审核规避词+敏感词skill
This commit is contained in:
1 parent
a9552b3d1a
commit
f05a11f0f3
14 files changed
+79
-29
No files matched your search
@@ -0,0 +1,50 @@
|
||||
---
|
||||
name: review-safe-words
|
||||
description: 个人小程序审核敏感词规避。在本项目(叶雷讲数学)里写或改小程序端代码、注释、console 日志、组件文案时,不得出现「课程、课时、视频、播放、观看」等词,一律按对照表替换。本项目内一切涉及小程序端的开发操作都适用。
|
||||
---
|
||||
|
||||
# 审核敏感词规避
|
||||
|
||||
个人主体小程序审核严:代码里(**包括注释、日志、组件内文案**)出现某些词,会被判定为在线教育 / 媒体类内容。本项目一律避开。
|
||||
|
||||
## 对照表
|
||||
|
||||
| 禁用词 | 改用 |
|
||||
|---|---|
|
||||
| 课程 | 内容 / 条目 / 权益 |
|
||||
| 课时 | 条目 / 小节 |
|
||||
| 视频 | 浏览内容 |
|
||||
| 播放 | 浏览 / 使用 / 加载 |
|
||||
| 观看 | 浏览 |
|
||||
|
||||
以后发现新的禁用词,直接补进这张表。
|
||||
|
||||
注意:「媒体」也别用——它和上面几个词一样敏感,不当作替代词。
|
||||
|
||||
## 适用范围
|
||||
|
||||
- 小程序端(`yelaymaths/`)**所有文件**:`.js` / `.wxml` / `.wxss` / `.json`
|
||||
- **包括注释和 `console.*` 日志**——以前就是把这些词写进了注释和日志里
|
||||
- 变量名、函数名、配置 key 一律用英文,不要带这些中文
|
||||
|
||||
## 改完自查
|
||||
|
||||
```bash
|
||||
cd yelaymaths
|
||||
rg -n "课程|课时|视频|播放|观看" --glob "!miniprogram_npm" --glob "!node_modules" .
|
||||
```
|
||||
|
||||
必须**无输出**才算干净。
|
||||
|
||||
## 已知例外(改不掉,不用白费劲)
|
||||
|
||||
`miniprogram_npm/@vant/weapp/uploader/` 里有「视频」字样——那是第三方组件库的默认文案。
|
||||
|
||||
- 它是【构建 npm】的产物、在 `.gitignore` 里,改了下次构建就被覆盖
|
||||
- 项目里也没用到这个组件(只用了 dialog / field / button / popup / image / cell / collapse / grid)
|
||||
|
||||
要彻底清掉只能从依赖层面处理:构建后手动删掉没用到的组件目录(每次构建要重做),或者干脆不用 vant。
|
||||
|
||||
## 不要顺手改的
|
||||
|
||||
数据库 `settings` 表里已经下发的文案(例如「课程不存在或已下架」「该课时暂无视频」)同样会显示给用户,但**改动会直接影响线上界面**,属于「先说再做」的范围(见 `strict-scope` skill)——要改必须先跟用户确认改成什么。
|
||||
@@ -278,7 +278,7 @@ DomHandler.prototype.onopentag = function(name, attrs) {
|
||||
attrs.source = [];
|
||||
if (attrs.src) attrs.source.push(attrs.src);
|
||||
if (!attrs.controls && !attrs.autoplay)
|
||||
console.warn('存在没有controls属性的' + name + '标签,可能导致无法播放', attrs);
|
||||
console.warn(name + ' 标签缺少 controls 属性,可能无法正常使用', attrs);
|
||||
this._bubbling();
|
||||
break;
|
||||
case 'source':
|
||||
@@ -322,4 +322,4 @@ DomHandler.prototype.onclosetag = function(name) {
|
||||
siblings.pop();
|
||||
}
|
||||
};
|
||||
module.exports = DomHandler;
|
||||
module.exports = DomHandler;
|
||||
@@ -53,7 +53,7 @@ Component({
|
||||
composed: true
|
||||
});
|
||||
},
|
||||
//内部方法:加载视频
|
||||
//内部方法:点击封面后加载真实内容
|
||||
_loadVideo(e) {
|
||||
this.data.controls[e.currentTarget.dataset.id] = {
|
||||
play: true,
|
||||
@@ -64,4 +64,4 @@ Component({
|
||||
})
|
||||
},
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -10,7 +10,7 @@
|
||||
<rich-text wx:else style="display:inline-block" nodes="{{[item]}}"></rich-text>
|
||||
</block>
|
||||
<text wx:elif="{{item.name=='br'}}">\n</text>
|
||||
<!--视频-->
|
||||
<!--浏览内容-->
|
||||
<block wx:elif="{{item.name=='video'}}">
|
||||
<view wx:if="{{item.attrs.id>'video3'&&!controls[item.attrs.id].play}}" class="video" style="{{item.attrs.style+(item.attrs.width?(';width:'+item.attrs.width):'')+(item.attrs.height?('height:'+item.attrs.height):'')}}" data-id="{{item.attrs.id}}" bindtap="_loadVideo">
|
||||
<view class="video-triangle" />
|
||||
@@ -31,4 +31,4 @@
|
||||
</navigator>
|
||||
<!--继续递归-->
|
||||
<trees wx:else id="node" class="{{item.name}}" style="{{item.attrs.style}}" nodes="{{item.children}}" controls="{{controls}}" />
|
||||
</block>
|
||||
</block>
|
||||
+3
-3
@@ -49,7 +49,7 @@ App({
|
||||
},
|
||||
|
||||
/**
|
||||
* 启动流程:配置再静默登录,最后拉已购课程。
|
||||
* 启动流程:配置再静默登录,最后拉已购内容。
|
||||
*
|
||||
* 每一步失败都不阻断启动:配置缺失时页面按空值渲染,登录失败时按未登录渲染。
|
||||
* 旧版本在页面 data 里同步读缓存、而缓存由异步写入,首次安装必然报错,这里不再重蹈。
|
||||
@@ -64,8 +64,8 @@ App({
|
||||
api
|
||||
.login()
|
||||
.then((res) => {
|
||||
// 静默登录只建立身份。用户从没主动登录过、或者已经退出,就不去拉已购课程,
|
||||
// 否则知识页会在「未登录」状态下又冒出课程列表。
|
||||
// 静默登录只建立身份。用户从没主动登录过、或者已经退出,就不去拉已购内容,
|
||||
// 否则知识页会在「未登录」状态下又冒出一份已购列表。
|
||||
if (!res || !res.user || res.user.isLogin !== 1) {
|
||||
store.setEntitlements([]);
|
||||
return null;
|
||||
|
||||
@@ -12,7 +12,7 @@ module.exports = {
|
||||
API_BASE_URL: 'https://yelaymaths-api.yeomai.site',
|
||||
|
||||
/**
|
||||
* 课程数据端(图片 / 视频)。
|
||||
* 静态资源端(图片、浏览内容)。
|
||||
* 已存库的正文 HTML 里的地址与此无关——那部分在数据迁移时按服务端的 STATIC_BASE_URL 改写。
|
||||
*/
|
||||
STATIC_BASE_URL: 'https://yelaymaths-data.yeomai.site',
|
||||
|
||||
@@ -87,11 +87,11 @@ Page({
|
||||
})
|
||||
.catch((err) => {
|
||||
this.setData({ playdata: [] });
|
||||
console.warn('[VideoDetails] 课时加载失败', err);
|
||||
console.warn('[VideoDetails] 条目加载失败', err);
|
||||
});
|
||||
},
|
||||
|
||||
/** 点课时:向后端换一次性播放地址,视频本身不直接暴露。 */
|
||||
/** 点条目:向后端换一次性地址,真实文件不直接暴露。 */
|
||||
onTapLesson(e) {
|
||||
const item = this.data.playdata[e.currentTarget.dataset.index];
|
||||
if (!item) return;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<!--pages/VideoDetails/VideoDetails.wxml-->
|
||||
|
||||
<!-- 已拥有:正常播放 -->
|
||||
<!-- 已拥有:正常浏览 -->
|
||||
<block wx:if="{{owned}}">
|
||||
<video hidden="{{HiddenVideoControl}}" class="videoplayer" src="{{VideoPlayerSrc}}" />
|
||||
<scroll-view class="scrollarea" scroll-y type="list" style="top:{{top}}rpx;">
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
// 职责是「确认订单 → 拉起微信支付 → 确认发货」。
|
||||
//
|
||||
// 两种进入方式:
|
||||
// - 带 ?code=xxx(从课程详情页进来):只显示这一门
|
||||
// - 不带参数:列出全部课程,一门一个购买按钮
|
||||
// - 带 ?code=xxx(从详情页进来):只显示这一条
|
||||
// - 不带参数:列出全部条目,一条一个购买按钮
|
||||
const api = require('../../utils/api');
|
||||
const format = require('../../utils/format');
|
||||
const store = require('../../utils/store');
|
||||
@@ -98,12 +98,12 @@ Page({
|
||||
})
|
||||
.catch((err) => {
|
||||
this.setData({ loading: false });
|
||||
// 课程被下架或课程号拼错,后端会返回错误,这里按同样的方式退出
|
||||
// 条目被下架或编号拼错,后端会返回错误,这里按同样的方式退出
|
||||
this.rejectOut((err && err.message) || store.cfg('course.tip.notFound'));
|
||||
});
|
||||
},
|
||||
|
||||
/** 不带课程号进来:列出全部课程,让用户自己挑。 */
|
||||
/** 不带编号进来:列出全部条目,让用户自己挑。 */
|
||||
loadList() {
|
||||
api
|
||||
.getCourses()
|
||||
@@ -124,7 +124,7 @@ Page({
|
||||
});
|
||||
},
|
||||
|
||||
/** 进错页面(没带课程、课程不存在、已经买过):提示一句然后退出去。 */
|
||||
/** 进错页面(没带编号、条目不存在、已经买过):提示一句然后退出去。 */
|
||||
rejectOut(message) {
|
||||
wx.showToast({ title: message, icon: 'none' });
|
||||
setTimeout(() => this.back(), 1500);
|
||||
@@ -141,7 +141,7 @@ Page({
|
||||
|
||||
/**
|
||||
* 购买:下单 → 拉起支付 → 轮询订单状态确认发货。
|
||||
* 课程号优先取按钮上的 data-code(列表模式),没有就用页面参数(单课程模式)。
|
||||
* 编号优先取按钮上的 data-code(列表模式),没有就用页面参数(单条模式)。
|
||||
*/
|
||||
buyNow(e) {
|
||||
const code =
|
||||
@@ -227,7 +227,7 @@ Page({
|
||||
if (order.status === 2) {
|
||||
this.setData({ buying: false, owned: true });
|
||||
wx.showToast({ title: store.cfg('course.tip.buySuccess'), icon: 'success', mask: true });
|
||||
// 单课程模式从详情页进来,买完退回去;列表模式留在原地刷新
|
||||
// 单条模式从详情页进来,买完退回去;列表模式留在原地刷新
|
||||
if (this.data.code) {
|
||||
setTimeout(() => this.back(), 1500);
|
||||
} else {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!--pages/buy/buy.wxml-->
|
||||
|
||||
<view class="buy-page">
|
||||
<!-- 带 ?code= 进来就只买这一门,否则列出全部课程、一门一个购买按钮。
|
||||
<!-- 带 ?code= 进来就只买这一条,否则列出全部条目、一条一个购买按钮。
|
||||
注意别在 wx:if 和 wx:else 之间插注释。 -->
|
||||
<view class="buy-single" wx:if="{{code}}">
|
||||
<text class="buy-title">{{title}}</text>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ── 单课程 ───────────────────────────────────────────── */
|
||||
/* ── 单条 ─────────────────────────────────────────────── */
|
||||
.buy-single {
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
@@ -31,7 +31,7 @@
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ── 课程列表 ─────────────────────────────────────────── */
|
||||
/* ── 列表 ─────────────────────────────────────────────── */
|
||||
.buy-list {
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
|
||||
@@ -24,7 +24,7 @@ Page({
|
||||
|
||||
onShow() {
|
||||
if (store.isLoggedIn()) this.refresh();
|
||||
// 未登录(含刚退出登录)不能留着一份别人的课程列表
|
||||
// 未登录(含刚退出登录)不能留着一份别人的已购列表
|
||||
else this.setData({ ownedCourses: [], hasCourse: false });
|
||||
},
|
||||
|
||||
@@ -39,7 +39,7 @@ Page({
|
||||
})
|
||||
.catch((err) => {
|
||||
if (err && err.code === api.ACCOUNT_DISABLED) {
|
||||
// 服务端不返回权益了,本地缓存也一并清掉,免得露出上一次的课程
|
||||
// 服务端不返回权益了,本地缓存也一并清掉,免得露出上一次的已购内容
|
||||
store.setEntitlements([]);
|
||||
this.setData({
|
||||
ownedCourses: [],
|
||||
@@ -50,7 +50,7 @@ Page({
|
||||
});
|
||||
return;
|
||||
}
|
||||
console.warn('[kecheng] 已购课程加载失败', err);
|
||||
console.warn('[kecheng] 已购内容加载失败', err);
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -195,7 +195,7 @@ const api = {
|
||||
getArticle: (id) => request({ url: '/v1/articles/' + id, auth: false }),
|
||||
getTips: () => request({ url: '/v1/tips', auth: false }),
|
||||
|
||||
// ── 课程 ────────────────────────────────────────────────────────────
|
||||
// ── 内容 ────────────────────────────────────────────────────────────
|
||||
getCourses: () => request({ url: '/v1/courses' }),
|
||||
getCourse: (code) => request({ url: '/v1/courses/' + code }),
|
||||
getLessons: (code) => request({ url: '/v1/courses/' + code + '/lessons' }),
|
||||
@@ -231,7 +231,7 @@ const api = {
|
||||
* 拉起虚拟支付。
|
||||
*
|
||||
* 支付成功只代表「钱付了」,权益由服务端收到发货推送后发放,
|
||||
* 因此这里不直接开通课程,而是让调用方轮询订单状态。
|
||||
* 因此这里不直接开通权益,而是让调用方轮询订单状态。
|
||||
*/
|
||||
function requestVirtualPayment(payData) {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
@@ -92,7 +92,7 @@ const store = {
|
||||
return value === undefined ? '' : value;
|
||||
},
|
||||
|
||||
// ── 已购课程 ─────────────────────────────────────────────────────────
|
||||
// ── 已购内容 ─────────────────────────────────────────────────────────
|
||||
getEntitlements() {
|
||||
if (memory.entitlements && memory.entitlements.length) return memory.entitlements;
|
||||
memory.entitlements = read(config.STORAGE.ENTITLEMENTS, []) || [];
|
||||
|
||||
Reference in new issue
Block a user