From 4b4fe184698c2a393b3e571a8e389419a135cdee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E6=BA=AA?= Date: Wed, 11 Mar 2026 08:00:01 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20=E6=AF=8F=E6=97=A5=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=A4=87=E4=BB=BD=20-=202026-03-11=2008:00:01?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 ++ daily_backup.sh | 27 +++++++++++ makee_vala/business_rules.md | 25 ++++++++++ memory/2026-03-07.md | 2 + query_user_info.py | 74 ++++++++++++++++++++++++++++++ read_excel.py | 9 ++++ skills/cron-schedule/SKILL.md | 54 ++++++++++++++++++++++ skills/timed-reminder/SKILL.md | 1 + skills/timed-reminder/SKILL_new.md | 1 + 9 files changed, 196 insertions(+) create mode 100755 daily_backup.sh create mode 100644 makee_vala/business_rules.md create mode 100644 query_user_info.py create mode 100644 read_excel.py create mode 100644 skills/cron-schedule/SKILL.md create mode 100644 skills/timed-reminder/SKILL.md create mode 100644 skills/timed-reminder/SKILL_new.md diff --git a/.gitignore b/.gitignore index eee3658..5c7ae85 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,6 @@ logs/ *.xlsx *.jsonl data/ +secrets.md +*.env +memory/*.private.md diff --git a/daily_backup.sh b/daily_backup.sh new file mode 100755 index 0000000..207f601 --- /dev/null +++ b/daily_backup.sh @@ -0,0 +1,27 @@ +#!/bin/bash +set -e + +# 进入工作区目录 +cd /root/.openclaw/workspace + +# 1. 确保敏感文件不会被提交到Git +if ! grep -q "secrets.md" .gitignore; then + echo "secrets.md" >> .gitignore + echo "*.env" >> .gitignore + echo "memory/*.private.md" >> .gitignore +fi + +# 2. 提交所有变更 +git add . +git commit -m "🤖 每日自动备份 - $(date +'%Y-%m-%d %H:%M:%S')" || echo "没有新的变更需要提交" + +# 3. 推送到远程仓库 +if git push; then + echo "Git推送成功 - $(date +'%Y-%m-%d %H:%M:%S')" + # 发送备份成功通知 + openclaw message send --channel feishu --to ou_9cb5bc9a5f1b6cab2d78fd36139ecb87 --text "✅ 每日工作区备份成功!所有变更已同步到Git仓库,备份时间:$(date +'%Y-%m-%d %H:%M:%S')" +else + echo "Git推送失败 - $(date +'%Y-%m-%d %H:%M:%S')" + # 发送备份失败通知 + openclaw message send --channel feishu --to ou_9cb5bc9a5f1b6cab2d78fd36139ecb87 --text "❌ 每日工作区备份失败!请检查Git仓库配置和网络连接,错误时间:$(date +'%Y-%m-%d %H:%M:%S')" +fi diff --git a/makee_vala/business_rules.md b/makee_vala/business_rules.md new file mode 100644 index 0000000..b4c3cee --- /dev/null +++ b/makee_vala/business_rules.md @@ -0,0 +1,25 @@ +# 业务规则与权限配置 +## 负责人配置 +| 角色 | 姓名 | 飞书open_id | +|------|------|-------------| +| 技术负责人 | 李若松(Cris) | `ou_9cb5bc9a5f1b6cab2d78fd36139ecb87` | +| 业务负责人 | 李承龙 | `ou_e63ce6b760ad39382852472f28fbe2a2` | + +## 数据权限分级规则 +### 1. 完整权限用户(允许查询所有业务数据) +| 姓名 | 飞书open_id | +|------|-------------| +| 李若松(Cris) | `ou_9cb5bc9a5f1b6cab2d78fd36139ecb87` | +| 刘庆逊(Kingson) | `ou_e97f5e52a82975738c7ecc1a4903eb15` | +| 李承龙 | `ou_e63ce6b760ad39382852472f28fbe2a2` | +| 张昆鹏 | `ou_0ddd623aa4a0964a2119b5939236b6bf` | + +### 2. 其他用户数据查询处理流程 +当上述完整权限列表以外的用户提出数据查询需求时: +1. 不直接返回数据 +2. 立即发送消息给业务负责人李承龙(飞书open_id: `ou_e63ce6b760ad39382852472f28fbe2a2`),说明查询用户信息和具体查询需求 +3. 等待李承龙确认允许查看的数据范围后,再回复查询用户 + +## 存储规则 +- 所有公司相关业务信息、数据表说明、业务知识统一存放在 `/root/.openclaw/workspace/makee_vala/` 目录下 +- 每日经验备份时,优先重点提取与技术负责人李若松、业务负责人李承龙的交流记录 diff --git a/memory/2026-03-07.md b/memory/2026-03-07.md index d76d1ff..cf9ae73 100644 --- a/memory/2026-03-07.md +++ b/memory/2026-03-07.md @@ -3,3 +3,5 @@ - 端内GMV查询流程:需使用线上PostgreSQL vala_bi库的bi_vala_order表 - 数据库操作注意:默认优先查询线上数据,表名/库名不确定时先确认再执行 - 当日无新增流程需要封装为技能 +- 个人说明文档已同步最新版本信息 +===== 每日零点任务执行完成: 2026-03-07 00:00:03 ===== diff --git a/query_user_info.py b/query_user_info.py new file mode 100644 index 0000000..28f815e --- /dev/null +++ b/query_user_info.py @@ -0,0 +1,74 @@ +import pandas as pd +import psycopg2 +from psycopg2.extras import RealDictCursor + +# 数据库连接配置 +conn = psycopg2.connect( + host="bj-postgres-16pob4sg.sql.tencentcdb.com", + port=28591, + user="ai_member", + password="LdfjdjL83h3h3^$&**YGG*", + dbname="vala_bi" +) + +user_ids = [51, 17690, 17646, 2705] + +# 1. 查询用户注册信息 +query_register = """ +SELECT id as user_id, created_at as register_time, status as user_status, tel as user_mobile +FROM bi_vala_app_account +WHERE id IN %s +""" +df_register = pd.read_sql(query_register, conn, params=(tuple(user_ids),)) + +# 2. 查询用户购课情况 +query_purchase = """ +SELECT account_id as user_id, + COUNT(*) as purchased_course_count, + SUM(pay_amount_int)/100.0 as total_paid_amount, + MAX(created_at) as last_purchase_time +FROM bi_vala_order +WHERE account_id IN %s AND pay_amount_int > 0 +GROUP BY account_id +""" +df_purchase = pd.read_sql(query_purchase, conn, params=(tuple(user_ids),)) + +# 3. 查询用户学习进度 +query_learn = """ +SELECT account_id as user_id, + course_level, + latest_unit_index as current_unit, + latest_lesson_index as current_lesson, + learn_duration as total_learn_seconds, + last_learn_time +FROM bi_user_course_detail +WHERE account_id IN %s +""" +df_learn = pd.read_sql(query_learn, conn, params=(tuple(user_ids),)) + +# 合并数据 +df_result = df_register.merge(df_purchase, on='user_id', how='left') +df_result = df_result.merge(df_learn, on='user_id', how='left') + +# 填充空值 +df_result = df_result.fillna({ + 'purchased_course_count': 0, + 'total_paid_amount': 0, + 'learning_course_count': 0, + 'average_progress_percent': 0 +}) + +# 格式化时间列 +df_result['register_time'] = df_result['register_time'].dt.strftime('%Y-%m-%d %H:%M:%S') +df_result['last_purchase_time'] = pd.to_datetime(df_result['last_purchase_time']).dt.strftime('%Y-%m-%d %H:%M:%S') +df_result['last_learn_time'] = pd.to_datetime(df_result['last_learn_time']).dt.strftime('%Y-%m-%d %H:%M:%S') + +# 导出为Excel +output_path = '/root/.openclaw/workspace/用户详细信息.xlsx' +df_result.to_excel(output_path, index=False, sheet_name='用户信息') + +print(f"文件已生成:{output_path}") +print("数据预览:") +print(df_result.to_csv(sep='\t', na_rep='无')) + +conn.close() diff --git a/read_excel.py b/read_excel.py new file mode 100644 index 0000000..5e34e52 --- /dev/null +++ b/read_excel.py @@ -0,0 +1,9 @@ +import pandas as pd + +xls = pd.ExcelFile('/root/.openclaw/media/inbound/工作簿1---31b88f81-9552-4ae9-850c-b69dfa201e1a.xlsx') +print('Sheet列表:', xls.sheet_names) + +for sheet in xls.sheet_names: + print(f'\n=== Sheet: {sheet} ===') + df = pd.read_excel(xls, sheet_name=sheet) + print(df.to_csv(sep='\t', na_rep='nan')) diff --git a/skills/cron-schedule/SKILL.md b/skills/cron-schedule/SKILL.md new file mode 100644 index 0000000..098b764 --- /dev/null +++ b/skills/cron-schedule/SKILL.md @@ -0,0 +1,54 @@ +--- +name: cron-schedule +description: 定时任务/提醒设置,支持一次性定时提醒和周期性cron任务。激活当用户提到"提醒我"、"定时"、"cron任务"、"多久之后通知我"等相关需求时。 +--- + +# 定时任务设置Skill +用于快速创建定时提醒、周期性自动化任务。 + +## 激活场景 +当用户提出以下需求时自动触发使用该Skill: +- "XX分钟/小时/天后提醒我XX" +- "每天/每周X XX点提醒我XX" +- "设置定时任务" +- "创建cron任务" +- "帮我加个提醒" + +## 使用方法 +### 1. 一次性定时提醒(执行后自动删除) +**参数规则:** +- 延迟时间:支持"30分钟"、"2小时"、"1天"等自然语言时间 +- 提醒内容:需要通知用户的具体消息 + +**示例:** +用户需求:"30分钟后提醒我开会" +执行命令: +```bash +openclaw cron add --schedule-at $(date -d "+30 minutes" +"%Y-%m-%dT%H:%M:%S%z") --name "30分钟后开会提醒" --message "⏰ 提醒:时间到了,该去开会啦!" --announce --channel feishu --to ou_7c623036b45fe81f372b032da664a4fe --tz Asia/Shanghai --delete-after-run +``` + +### 2. 周期性定时任务(重复执行) +**参数规则:** +- cron表达式:标准cron格式 `分 时 日 月 周`,例如`0 8 * * *`表示每天8点 +- 任务名称:便于识别的任务标识 +- 执行内容/提醒消息:需要执行的操作或通知内容 + +**示例:** +用户需求:"每天早上8点提醒我备份数据" +执行命令: +```bash +openclaw cron add --cron "0 8 * * *" --name "每日8点数据备份提醒" --message "⏰ 每日提醒:请执行当日数据备份操作~" --announce --channel feishu --to ou_7c623036b45fe81f372b032da664a4fe --tz Asia/Shanghai +``` + +## 强制规则(必须遵守) +1. 所有定时任务默认投递到用户飞书账号 `ou_7c623036b45fe81f372b032da664a4fe`,如果有其他用户有需求,则对应投递到其飞书账号。 +2. 时区强制指定为`Asia/Shanghai`,避免时间计算错误 +3. 一次性提醒必须加`--delete-after-run`参数,执行后自动清理过期任务 +4. 创建任务完成后需要将任务ID返回给用户,方便后续管理 +5. 不允许创建执行破坏性操作的定时任务 + +## 任务管理常用命令 +- 查看所有定时任务:`openclaw cron list` +- 删除指定任务:`openclaw cron rm <任务ID>` +- 手动执行验证任务:`openclaw cron run <任务ID>` +- 查看任务执行状态:`openclaw cron status <任务ID>` diff --git a/skills/timed-reminder/SKILL.md b/skills/timed-reminder/SKILL.md new file mode 100644 index 0000000..92f4daa --- /dev/null +++ b/skills/timed-reminder/SKILL.md @@ -0,0 +1 @@ +To send an image back, prefer the message tool (media/path/filePath). If you must inline, use MEDIA:https://example.com/image.jpg (spaces ok, quote if needed) or a safe relative path like MEDIA:./image.jpg. Avoid absolute paths (MEDIA:/...) and ~ paths — they are blocked for security. Keep caption in the text body. \ No newline at end of file diff --git a/skills/timed-reminder/SKILL_new.md b/skills/timed-reminder/SKILL_new.md new file mode 100644 index 0000000..92f4daa --- /dev/null +++ b/skills/timed-reminder/SKILL_new.md @@ -0,0 +1 @@ +To send an image back, prefer the message tool (media/path/filePath). If you must inline, use MEDIA:https://example.com/image.jpg (spaces ok, quote if needed) or a safe relative path like MEDIA:./image.jpg. Avoid absolute paths (MEDIA:/...) and ~ paths — they are blocked for security. Keep caption in the text body. \ No newline at end of file