diff --git a/.agents/skills/review-safe-words/SKILL.md b/.agents/skills/review-safe-words/SKILL.md
new file mode 100644
index 0000000..db1ffcb
--- /dev/null
+++ b/.agents/skills/review-safe-words/SKILL.md
@@ -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)——要改必须先跟用户确认改成什么。
diff --git a/yelaymaths/Parser/DomHandler.js b/yelaymaths/Parser/DomHandler.js
index 24b9b25..39ba0d1 100644
--- a/yelaymaths/Parser/DomHandler.js
+++ b/yelaymaths/Parser/DomHandler.js
@@ -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;
\ No newline at end of file
+module.exports = DomHandler;
diff --git a/yelaymaths/Parser/trees/trees.js b/yelaymaths/Parser/trees/trees.js
index e38ff39..887c331 100644
--- a/yelaymaths/Parser/trees/trees.js
+++ b/yelaymaths/Parser/trees/trees.js
@@ -53,7 +53,7 @@ Component({
composed: true
});
},
- //内部方法:加载视频
+ //内部方法:点击封面后加载真实内容
_loadVideo(e) {
this.data.controls[e.currentTarget.dataset.id] = {
play: true,
@@ -64,4 +64,4 @@ Component({
})
},
}
-})
\ No newline at end of file
+})
diff --git a/yelaymaths/Parser/trees/trees.wxml b/yelaymaths/Parser/trees/trees.wxml
index c207e01..35db37c 100644
--- a/yelaymaths/Parser/trees/trees.wxml
+++ b/yelaymaths/Parser/trees/trees.wxml
@@ -10,7 +10,7 @@
\n
-
+
@@ -31,4 +31,4 @@
-
\ No newline at end of file
+
diff --git a/yelaymaths/app.js b/yelaymaths/app.js
index cc6170c..849035e 100644
--- a/yelaymaths/app.js
+++ b/yelaymaths/app.js
@@ -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;
diff --git a/yelaymaths/config/index.js b/yelaymaths/config/index.js
index b7ba382..f5e880c 100644
--- a/yelaymaths/config/index.js
+++ b/yelaymaths/config/index.js
@@ -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',
diff --git a/yelaymaths/pages/VideoDetails/VideoDetails.js b/yelaymaths/pages/VideoDetails/VideoDetails.js
index 58a0012..8c7c92b 100644
--- a/yelaymaths/pages/VideoDetails/VideoDetails.js
+++ b/yelaymaths/pages/VideoDetails/VideoDetails.js
@@ -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;
diff --git a/yelaymaths/pages/VideoDetails/VideoDetails.wxml b/yelaymaths/pages/VideoDetails/VideoDetails.wxml
index dfc8b24..2e2a472 100644
--- a/yelaymaths/pages/VideoDetails/VideoDetails.wxml
+++ b/yelaymaths/pages/VideoDetails/VideoDetails.wxml
@@ -1,6 +1,6 @@
-
+
diff --git a/yelaymaths/pages/buy/buy.js b/yelaymaths/pages/buy/buy.js
index 2f0e5d0..aa29db6 100644
--- a/yelaymaths/pages/buy/buy.js
+++ b/yelaymaths/pages/buy/buy.js
@@ -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 {
diff --git a/yelaymaths/pages/buy/buy.wxml b/yelaymaths/pages/buy/buy.wxml
index 6c994e8..5d2d124 100644
--- a/yelaymaths/pages/buy/buy.wxml
+++ b/yelaymaths/pages/buy/buy.wxml
@@ -1,7 +1,7 @@
-
{{title}}
diff --git a/yelaymaths/pages/buy/buy.wxss b/yelaymaths/pages/buy/buy.wxss
index 5060c78..84ac147 100644
--- a/yelaymaths/pages/buy/buy.wxss
+++ b/yelaymaths/pages/buy/buy.wxss
@@ -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;
diff --git a/yelaymaths/pages/kecheng/kecheng.js b/yelaymaths/pages/kecheng/kecheng.js
index a76c1ea..c990d3c 100644
--- a/yelaymaths/pages/kecheng/kecheng.js
+++ b/yelaymaths/pages/kecheng/kecheng.js
@@ -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);
});
},
diff --git a/yelaymaths/utils/api.js b/yelaymaths/utils/api.js
index 39c4066..7066883 100644
--- a/yelaymaths/utils/api.js
+++ b/yelaymaths/utils/api.js
@@ -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) => {
diff --git a/yelaymaths/utils/store.js b/yelaymaths/utils/store.js
index 76c5b51..cf1b5dd 100644
--- a/yelaymaths/utils/store.js
+++ b/yelaymaths/utils/store.js
@@ -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, []) || [];