Browse Source

临时提交

master
王泽彦 8 months ago
parent
commit
7914b4e440
  1. 353
      Word合同模板系统任务规划.md
  2. BIN
      doc/副本(时间卡)体能课学员课程协议.docx
  3. 8
      mysql-mcp-config.json
  4. 133
      niucloud/TASK.md
  5. 30
      niucloud/app/api/controller/apiController/Personnel.php
  6. 16
      niucloud/app/service/admin/upgrade/UpgradeService.php
  7. 2
      niucloud/app/service/api/apiService/PersonCourseScheduleService.php
  8. 66
      niucloud/app/service/api/apiService/PersonnelService.php
  9. 6
      niucloud/app/service/core/addon/CoreAddonInstallService.php
  10. 12
      niucloud/app/service/core/addon/CoreDependService.php
  11. 106
      uniapp/PLANNING.md
  12. BIN
      uniapp/TASK.md
  13. 10
      uniapp/pages.json
  14. 8
      uniapp/pages/coach/my/due_soon.vue
  15. 1538
      uniapp/pages/common/profile/personal_info.vue
  16. 132
      各校区转化数据统计需求文档.md

353
Word合同模板系统任务规划.md

@ -0,0 +1,353 @@
# Word合同模板系统任务规划文档
## 项目概述
### 需求总结
基于现有的学校管理系统,开发一个完整的Word合同模板系统,实现:
1. **模板管理**:上传Word文档作为合同模板,解析占位符并配置数据源
2. **合同分发**:支持内部员工分发和业务用户购买课程签约两种方式
3. **数据收集**:在微信小程序上完成签订数据收集
4. **文档生成**:通过队列异步生成填充数据后的完整Word文档
### 技术栈
- **后端**:PHP ThinkPHP框架
- **前端管理**:Vue3 + Element Plus
- **小程序**:UniApp
- **数据库**:MySQL
- **文档处理**:phpoffice/phpword
- **队列**:基于现有的workerman队列系统
## 系统架构分析
### 现有架构基础
根据代码分析,系统已具备:
- 基础的合同管理模块(ContractSign模型)
- 文档数据源配置模块(DocumentDataSourceConfig模型)
- 文档生成记录模块(DocumentGenerateLog模型)
- 队列处理系统(workerman)
### 核心数据流
```
Word模板上传 → 占位符解析 → 数据源配置 → 合同分发 → 小程序数据收集 → 队列生成文档
```
## 数据库设计确认
### 核心表结构(需要确认)
#### 1. school_contract(合同模板表)
```sql
CREATE TABLE `school_contract` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '合同编号',
`contract_name` varchar(255) NOT NULL COMMENT '合同名称',
`contract_template` text NOT NULL COMMENT '合同模板文件路径',
`contract_status` varchar(50) NOT NULL COMMENT '合同状态',
`contract_type` varchar(50) NOT NULL COMMENT '合同类型',
`placeholder_config` text COMMENT '占位符配置JSON',
`remarks` text COMMENT '合同备注',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`deleted_at` int NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
);
```
#### 2. school_contract_sign(合同签署关系表)
```sql
CREATE TABLE `school_contract_sign` (
`id` int NOT NULL AUTO_INCREMENT,
`contract_id` int NOT NULL COMMENT '合同ID',
`personnel_id` int NOT NULL COMMENT '人员ID',
`type` tinyint NOT NULL DEFAULT '1' COMMENT '类型:1内部员工 2外部用户',
`status` varchar(50) NOT NULL DEFAULT 'pending' COMMENT '签署状态',
`sign_time` int DEFAULT NULL COMMENT '签署时间',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
`deleted_at` int NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
);
```
#### 3. school_document_data_source_config(数据源配置表)
```sql
CREATE TABLE `school_document_data_source_config` (
`id` int NOT NULL AUTO_INCREMENT,
`contract_id` int NOT NULL COMMENT '合同ID',
`placeholder` varchar(255) NOT NULL COMMENT '占位符',
`table_name` varchar(100) COMMENT '数据表名',
`field_name` varchar(100) COMMENT '字段名',
`field_type` varchar(50) COMMENT '字段类型',
`is_required` tinyint DEFAULT '0' COMMENT '是否必填',
`default_value` text COMMENT '默认值',
`created_at` timestamp DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
);
```
#### 4. school_document_generate_log(文档生成记录表)
```sql
CREATE TABLE `school_document_generate_log` (
`id` int NOT NULL AUTO_INCREMENT,
`user_type` int NOT NULL DEFAULT '0' COMMENT '人员类型1内部 2外部',
`template_id` int NOT NULL COMMENT '模板ID',
`user_id` int NOT NULL COMMENT '操作用户',
`fill_data` text COMMENT '填充数据JSON',
`generated_file` varchar(500) DEFAULT NULL COMMENT '生成文件路径',
`status` enum('pending','processing','completed','failed') DEFAULT 'pending',
`error_msg` text COMMENT '错误信息',
`created_at` int NOT NULL DEFAULT '0',
`completed_at` int DEFAULT '0',
PRIMARY KEY (`id`)
);
```
## 功能模块设计
### 1. 模板管理模块
**功能**:
- Word模板上传
- 占位符自动解析
- 数据源配置界面
- 模板预览
**涉及页面**:
- 模板列表页
- 模板上传页
- 占位符配置页
### 2. 合同分发模块
**功能**:
- 内部员工分发
- 外部用户分发(购买课程支付成功后触发)
- 分发记录管理
**涉及页面**:
- 合同分发管理页
- 分发记录列表页
### 3. 数据收集模块(小程序端)
**功能**:
- 合同信息展示
- 表单数据收集
- 电子签名
- 数据提交
**涉及页面**:
- 合同详情页
- 数据填写页
- 签名页
### 4. 文档生成模块
**功能**:
- 队列任务处理
- Word文档生成
- 文件存储管理
- 生成状态跟踪
## 关键问题确认
### 🔴 数据库相关问题
1. **表名前缀**:现有代码中有些表是`school_`前缀,有些不是,请确认统一的命名规范?
这个问题school_就是前缀,我文档中的表名称有些是去掉前缀的。所以你在记录表名的时候需要忽略掉 shcool 这个前缀
2. **表结构完整性**:上述表结构是否完整?是否有遗漏的字段?
具体的你可以再详细查看数据库中的表结构,并确认是否完整。
3. **人员表关联**:`personnel_id`关联的是哪个表?表结构是什么?
personnel_id来自两个表根据type和user_type来区分 1 是内部人员查询school_personnel表,2是外部人员查询school_customer_resources这个表
### 🔴 业务流程问题
1. **分发触发时机**
- 内部员工分发:是手动分发还是自动分发?
手动触发
- 外部用户分发:购买课程后如何自动触发合同分发?
在用户支付成功以后进行合同分发现在php 后端在支付成功后会触发student 的事件。目前这里面只会分发合同。
2. **签名流程**:电子签名是手写签名还是电子印章?签名数据如何存储?
签名是前端端进行手写签名,签名图片的 url 应该存在数据库中,生成签名前要将签名上传至服务器。
3. **数据收集范围**:除了占位符数据,还需要收集哪些额外信息?
占位符的数据的来源分两种类型,一种是从数据库中获取,另一种是用户填写。在管理后台的是可以对这个占位符
的字段进行配置,比如这个占位符的数据来源是数据库中获取从哪个表获取数据哪个字段数据
### 🔴 技术实现问题
1. **文件存储**:Word模板和生成的文档存储在哪里?本地还是云存储?
云存储(腾讯云)
2. **队列处理**:使用现有的workerman队列还是需要其他队列系统?
使用现有的workerman队列
3. **权限控制**:不同角色的权限如何划分?
暂时默认所有用户都可以操作,后续完善权限控制
### 🔴 小程序交互问题
1. **访问方式**:用户如何访问小程序合同页面?扫码还是链接?
两种情况都有。小程序端是有我的合同这个页面的。获取自己的合同列表点击查看合同详情进入合同详情页。根据状态
未签的就可以签署,已签的就是预览 word。
2. **身份验证**:如何确保用户身份的准确性?
只要用户登录才能签署合同,自己签署自己的合同。而且有自己的手写签名做备份。
3. **离线处理**:网络不好时如何处理数据收集?
离线时所有功能不可用提示用户网络有问题所有功能停用。
## 前后端任务分工
### 后端任务(PHP)
1. **模板管理API**
- 模板上传接口
- 占位符解析服务
- 数据源配置API
2. **合同分发API**
- 分发创建接口
- 分发记录查询API
3. **数据收集API**
- 合同信息获取API
- 数据提交接口
- 签名上传API
4. **文档生成服务**
- 队列任务处理
- Word文档生成
- 文件下载接口
### 前端管理界面任务(Vue3)
1. **模板管理页面**
- 模板列表组件
- 模板上传组件
- 占位符配置组件
2. **合同管理页面**
- 合同分发组件
- 分发记录组件
3. **生成记录页面**
- 生成状态监控
- 文件下载功能
### 小程序端任务(UniApp)
1. **合同展示页面**
- 合同信息展示
- 占位符数据收集表单
2. **签名功能页面**
- 手写签名组件
- 签名确认功能
3. **提交确认页面**
- 数据确认展示
- 最终提交功能
## 开发时间估算
### 第一阶段:基础架构(5天)
- 数据库表设计和创建
- 基础API框架搭建
- 前端页面框架搭建
### 第二阶段:模板管理(7天)
- Word解析功能开发
- 占位符配置功能
- 模板管理界面
### 第三阶段:合同分发(5天)
- 分发逻辑开发
- 分发管理界面
- 与业务系统集成
### 第四阶段:小程序端(8天)
- 数据收集页面
- 签名功能开发
- 数据提交逻辑
### 第五阶段:文档生成(6天)
- 队列处理开发
- Word生成功能
- 文件管理功能
### 第六阶段:测试优化(4天)
- 功能测试
- 性能优化
- Bug修复
**总计:35天**
## 补充问题确认
基于您的回答和代码分析,我发现还有几个关键问题需要确认:
### 🔴 支付成功事件集成问题
1. **现有支付流程**:我看到代码中支付成功后会触发`Student`事件,但在`Student.php`监听器中的`studentAdd`方法里,合同分发逻辑似乎不完整。您希望在哪个环节触发合同分发?
- 在`studentAdd`方法中直接添加合同分发逻辑?
- 还是创建新的事件监听器专门处理合同分发?
2. **合同分发条件**:外部用户购买课程后,是否所有课程都需要分发合同,还是只有特定课程?如何判断哪些课程需要分发合同?
### 🔴 数据库表结构问题
3. **表名前缀统一**:您确认使用`school_`前缀,但我需要确认以下表的完整表名:
- `school_contract`(合同模板表)
- `school_contract_sign`(合同签署关系表)
- `school_document_data_source_config`(数据源配置表)
- `school_document_generate_log`(文档生成记录表)
4. **现有表结构检查**:我需要查看现有数据库中是否已经存在这些表,以及它们的具体结构是否与我设计的一致。
### 🔴 小程序页面集成问题
5. **现有小程序结构**:您提到小程序有"我的合同"页面,这个页面是否已经存在?如果存在,我需要了解现有的页面结构和路由配置。
6. **用户身份关联**:小程序用户登录后,如何关联到`school_customer_resources`表中的用户?是通过`member_id`字段吗?
### 🔴 文件处理问题
7. **Word模板格式**:您提到测试文档是`doc/副本(时间卡)体能课学员课程协议.docx`,我需要确认:
- 模板中的占位符格式是什么?(如`{{学员姓名}}`、`{学员姓名}`还是其他格式?)
- 是否有现成的模板可以参考?
8. **腾讯云存储配置**:现有系统是否已经配置了腾讯云存储?我需要了解存储的配置信息以便集成。
## 建议的架构优化
### 1. 事件监听器优化
建议创建专门的合同分发事件监听器,而不是在现有的`Student`监听器中添加逻辑:
```php
// 新建 app/listener/contract/ContractDistributionListener.php
class ContractDistributionListener
{
public function handle(array $params)
{
// 处理合同分发逻辑
if ($params['event_type'] === 'course_purchase') {
$this->distributeCourseContract($params['data']);
}
}
}
```
### 2. 数据库设计优化
建议在`school_contract_sign`表中添加一些字段:
```sql
ALTER TABLE `school_contract_sign` ADD COLUMN `source_type` varchar(50) DEFAULT 'manual' COMMENT '分发来源:manual手动分发,auto_course自动课程分发';
ALTER TABLE `school_contract_sign` ADD COLUMN `source_id` int DEFAULT NULL COMMENT '来源ID(如课程ID、订单ID等)';
```
### 3. API接口设计建议
基于您的需求,我建议以下API结构:
**管理端API:**
- `/admin/contract/template` - 模板管理
- `/admin/contract/distribution` - 合同分发管理
- `/admin/contract/generate-log` - 生成记录管理
**小程序端API:**
- `/api/contract/my-contracts` - 我的合同列表
- `/api/contract/detail/{id}` - 合同详情
- `/api/contract/submit-data` - 提交填写数据
- `/api/contract/upload-signature` - 上传签名
## 下一步行动
请您确认上述补充问题后,我将:
1. 检查现有数据库表结构
2. 完善数据库设计方案
3. 制定详细的API接口文档
4. 创建具体的开发任务分配
5. 建立项目开发时间表
---
**注意**:这些补充问题的确认对于系统的正确实现非常重要,请务必详细回答。

BIN
doc/副本(时间卡)体能课学员课程协议.docx

Binary file not shown.

8
mysql-mcp-config.json

@ -0,0 +1,8 @@
{
"host": "localhost",
"port": 23306,
"user": "niucloud",
"password": "niucloud123",
"database": "niucloud",
"ssl": false
}

133
niucloud/TASK.md

@ -0,0 +1,133 @@
# PHP后端开发任务记录
## 最新完成任务 ✅
**完整实现个人资料接口功能** (2025-07-29)
### 任务描述
根据前端 `uniapp/TASK.md` 中完成的个人资料页面,实现对应的后端API接口,支持员工个人资料的查看和编辑功能。
### 实现内容
#### 1. 扩展API接口功能
- **接口路径**:
- `GET /api/personnel/info` - 获取员工个人资料
- `POST /api/personnel/edit` - 更新员工个人资料
#### 2. 数据库表支持
- **基础信息表**: `school_personnel`
- 包含:姓名、性别、生日、电话、邮箱、微信号、学历、家庭住址、祖籍、个人简介、应急联系人电话、身份证正反面等
- **详细信息表**: `school_personnel_info`
- 包含:花名、门店、民族、年龄、司龄、转正时间、是否转正、政治面貌、毕业院校、专业、毕业时间、婚姻状况、银行卡号、开户行、备注等
#### 3. 技术实现
- **PersonnelService扩展**:
- 修改 `info` 方法:同时查询两个表,返回包含 `info` 对象的完整数据
- 修改 `edit` 方法:使用事务同时更新两个表的数据
- 添加PersonnelInfo模型引用
- **Personnel控制器优化**:
- 修改 `edit` 方法:支持接收完整的数据结构,包括 `info` 对象
- 添加字段存在性检查,避免undefined key错误
- 改进错误处理和返回消息
#### 4. 数据格式
**获取接口响应格式**:
```json
{
"code": 1,
"msg": "操作成功",
"data": {
"id": 7,
"name": "麒麟老师",
"head_img": "",
"gender": 1,
"phone": "19218917377",
"email": "258785420@qq.com",
"address": "北京市海淀区",
"native_place": "山东青岛",
"education": "硕士",
"profile": "资深市场经理...",
"emergency_contact_phone": "13900139000",
"info": {
"name": "麒麟",
"store": "海淀校区",
"ethnicity": "汉族",
"age": 31,
"politics": "党员",
"university": "清华大学",
"major": "工商管理",
"graduation_date": "2014-06-30",
"marital_status": "已婚",
"bank_card": "6222021234567890124",
"bank_name": "建设银行北京分行",
"remark": "优秀员工..."
}
}
}
```
**保存接口请求格式**:
```json
{
"name": "麒麟老师",
"gender": 1,
"phone": "19218917377",
"email": "258785420@qq.com",
"address": "北京市海淀区",
"native_place": "山东青岛",
"education": "硕士",
"profile": "资深市场经理...",
"emergency_contact_phone": "13900139000",
"info": {
"name": "麒麟",
"store": "海淀校区",
"ethnicity": "汉族",
"age": 31,
"politics": "党员",
"university": "清华大学",
"major": "工商管理"
}
}
```
#### 5. 测试验证
- ✅ **获取接口测试**: 使用curl验证数据正确返回,包含完整的基础信息和详细信息
- ✅ **保存接口测试**: 使用curl验证数据正确保存到两个表
- ✅ **更新接口测试**: 使用curl验证数据正确更新
- ✅ **数据库验证**: 直接查询数据库确认数据正确存储
- ✅ **事务处理**: 确保数据一致性,失败时正确回滚
#### 6. 业务逻辑
- **数据完整性**: 使用数据库事务确保两个表的数据同步更新
- **字段映射**: 正确处理基础信息和详细信息的字段分离
- **错误处理**: 完善的异常捕获和错误信息返回
- **权限控制**: 员工只能查看和编辑自己的个人资料
#### 7. 前端集成状态
- ✅ **数据回显**: 前端页面能够正确获取和显示所有字段数据
- ✅ **数据保存**: 前端页面能够正确保存所有字段数据
- ✅ **字段完整性**: 支持前端页面的所有功能需求
- ✅ **API兼容性**: 保持与前端调用方式的完全兼容
### 修改的文件
1. `niucloud/app/service/api/apiService/PersonnelService.php`
- 添加PersonnelInfo模型引用
- 扩展info方法支持详细信息查询
- 扩展edit方法支持两表联合更新
2. `niucloud/app/api/controller/apiController/Personnel.php`
- 优化edit方法支持完整数据结构
- 添加字段存在性检查
- 改进错误处理
### 技术特点
- **事务安全**: 使用数据库事务确保数据一致性
- **向后兼容**: 保持现有API接口的兼容性
- **错误处理**: 完善的异常处理和错误信息返回
- **数据验证**: 支持字段的存在性检查
- **模块化设计**: 清晰的数据层分离和业务逻辑封装
---
*最后更新:2025-07-29*
*状态:已完成并测试通过*

30
niucloud/app/api/controller/apiController/Personnel.php

@ -47,23 +47,31 @@ class Personnel extends BaseApiService
//员工修改
public function edit(Request $request){
$params = $request->all();
$data = [
'head_img'=>$params['head_img'],//头像|绝对地址
'name'=>$params['name'],//姓名
'address'=>$params['address'],//住址
'gender'=>$params['gender'],//性别
'birthday'=>$params['birthday'],//生日
'email'=>$params['email'],//邮箱
'phone'=>$params['phone'],//手机号
'wx'=>$params['wx'],//微信号
];
// 构建基础数据,使用isset检查避免undefined key错误
$data = [];
// 基础信息字段
$baseFields = ['head_img', 'name', 'gender', 'birthday', 'phone', 'email', 'wx', 'address', 'native_place', 'education', 'profile', 'emergency_contact_phone', 'id_card_front', 'id_card_back'];
foreach ($baseFields as $field) {
if (isset($params[$field])) {
$data[$field] = $params[$field];
}
}
// 详细信息
if (isset($params['info']) && is_array($params['info'])) {
$data['info'] = $params['info'];
}
//获取员工信息
$where = [
'id'=>$this->member_id,
];
$res = (new PersonnelService())->edit($where,$data);
if(!$res['code']){
return fail('操作失败');
return fail($res['msg'] ?? '操作失败');
}
return success([]);
}

16
niucloud/app/service/admin/upgrade/UpgradeService.php

@ -317,14 +317,14 @@ class UpgradeService extends BaseAdminService
if ($addon == AddonDict::FRAMEWORK_KEY) {
$composer = '/niucloud/composer.json';
$admin_package = '/admin/package.json';
$web_package = '/web/package.json';
$uniapp_package = '/uni-app/package.json';
$admin_package = '/admin/mysql-mcp-config.json';
$web_package = '/web/mysql-mcp-config.json';
$uniapp_package = '/uni-app/mysql-mcp-config.json';
} else {
$composer = "/niucloud/addon/{$addon}/package/composer.json";
$admin_package = "/niucloud/addon/{$addon}/package/admin-package.json";
$web_package = "/niucloud/addon/{$addon}/package/web-package.json";
$uniapp_package = "/niucloud/addon/{$addon}/package/uni-app-package.json";
$admin_package = "/niucloud/addon/{$addon}/package/admin-mysql-mcp-config.json";
$web_package = "/niucloud/addon/{$addon}/package/web-mysql-mcp-config.json";
$uniapp_package = "/niucloud/addon/{$addon}/package/uni-app-mysql-mcp-config.json";
}
if (in_array($composer, $change_files)) {
@ -392,7 +392,7 @@ class UpgradeService extends BaseAdminService
$this->compileLocale($this->root_path . 'uni-app' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR, $addon);
// 合并插件依赖
$addon_uniapp_package = str_replace('/', DIRECTORY_SEPARATOR, project_path() . "niucloud/addon/{$addon}/package/uni-app-package.json");
$addon_uniapp_package = str_replace('/', DIRECTORY_SEPARATOR, project_path() . "niucloud/addon/{$addon}/package/uni-app-mysql-mcp-config.json");
if (file_exists($addon_uniapp_package)) {
$original = $depend_service->getNpmContent('uni-app');
@ -402,7 +402,7 @@ class UpgradeService extends BaseAdminService
$original[$name] = isset($original[$name]) && is_array($original[$name]) ? array_merge($original[$name], $new[$name]) : $new[$name];
}
$uniapp_package = $this->root_path . 'uni-app' . DIRECTORY_SEPARATOR . 'package.json';
$uniapp_package = $this->root_path . 'uni-app' . DIRECTORY_SEPARATOR . 'mysql-mcp-config.json';
$depend_service->writeArrayToJsonFile($original, $uniapp_package);
}
}

2
niucloud/app/service/api/apiService/PersonCourseScheduleService.php

@ -361,7 +361,7 @@ class PersonCourseScheduleService extends BaseApiService
public function getStudentCourseInfo(array $where)
{
$res = [
'code' => 0,
'code' => 1,
'msg' => '暂无课程信息',
'data' => []
];

66
niucloud/app/service/api/apiService/PersonnelService.php

@ -15,6 +15,7 @@ use app\model\campus_person_role\CampusPersonRole;
use app\model\departments\Departments;
use app\model\member\Member;
use app\model\personnel\Personnel;
use app\model\personnel\PersonnelInfo;
use app\model\reimbursement\Reimbursement;
use app\model\sys\SysRole;
use app\model\sys\SysUser;
@ -129,6 +130,10 @@ class PersonnelService extends BaseApiService
$data['department_name_str'] = $department_name_str;
$data['cameus_dept_arr'] = $cameus_dept_arr;//校区+部门的组合
// 获取员工详细信息
$personnelInfo = (new PersonnelInfo())->where(['person_id' => $where['id']])->findOrEmpty()->toArray();
$data['info'] = $personnelInfo;
$res['code'] = 1;
$res['msg'] = '操作成功';
$res['data'] = $data;
@ -146,8 +151,6 @@ class PersonnelService extends BaseApiService
//员工信息-修改
public function edit(array $where, array $data)
{
$data['update_time'] = date('Y-m-d H:i:s');
if (!$where) {
return [
'code' => 0,
@ -155,25 +158,68 @@ class PersonnelService extends BaseApiService
];
}
try {
// 开启事务
\think\facade\Db::startTrans();
// 分离基础信息和详细信息
$personnelData = [];
$infoData = [];
// 基础信息字段
$baseFields = ['head_img', 'name', 'gender', 'birthday', 'phone', 'email', 'wx', 'address', 'native_place', 'education', 'profile', 'emergency_contact_phone', 'id_card_front', 'id_card_back'];
foreach ($baseFields as $field) {
if (isset($data[$field])) {
$personnelData[$field] = $data[$field];
}
}
// 添加更新时间
$personnelData['update_time'] = date('Y-m-d H:i:s');
// 更新基础信息
$model = $this->model;
if (!empty($where['id'])) {
$model = $model->where('id', $where['id']);
}
$res = $model->update($data);//员工信息
$updateResult = $model->update($personnelData);
if ($res) {
$res = [
// 处理详细信息
if (isset($data['info']) && is_array($data['info'])) {
$infoData = $data['info'];
$infoData['updated_at'] = date('Y-m-d H:i:s');
// 检查是否已存在详细信息记录
$existingInfo = (new PersonnelInfo())->where(['person_id' => $where['id']])->findOrEmpty();
if ($existingInfo->isEmpty()) {
// 创建新记录
$infoData['person_id'] = $where['id'];
$infoData['created_at'] = date('Y-m-d H:i:s');
(new PersonnelInfo())->insert($infoData);
} else {
// 更新现有记录
(new PersonnelInfo())->where(['person_id' => $where['id']])->update($infoData);
}
}
// 提交事务
\think\facade\Db::commit();
return [
'code' => 1,
'msg' => '操作成功'
];
} else {
$res = [
} catch (\Exception $e) {
// 回滚事务
\think\facade\Db::rollback();
return [
'code' => 0,
'msg' => '操作失败'
'msg' => '操作失败' . $e->getMessage()
];
}
return $res;
}
//员工信息-获取全部用户

6
niucloud/app/service/core/addon/CoreAddonInstallService.php

@ -220,10 +220,10 @@ class CoreAddonInstallService extends CoreAddonBaseService
}, $package_file);
$tips = [get_lang('dict_addon.install_after_update')];
if (in_array('admin-package.json', $package_file)) $tips[] = get_lang('dict_addon.install_after_admin_update');
if (in_array('admin-mysql-mcp-config.json', $package_file)) $tips[] = get_lang('dict_addon.install_after_admin_update');
if (in_array('composer.json', $package_file)) $tips[] = get_lang('dict_addon.install_after_composer_update');
if (in_array('uni-app-package.json', $package_file)) $tips[] = get_lang('dict_addon.install_after_wap_update');
if (in_array('web-package.json', $package_file)) $tips[] = get_lang('dict_addon.install_after_web_update');
if (in_array('uni-app-mysql-mcp-config.json', $package_file)) $tips[] = get_lang('dict_addon.install_after_wap_update');
if (in_array('web-mysql-mcp-config.json', $package_file)) $tips[] = get_lang('dict_addon.install_after_web_update');
return $tips;
}
return true;

12
niucloud/app/service/core/addon/CoreDependService.php

@ -25,9 +25,9 @@ class CoreDependService extends CoreAddonBaseService
{
parent::__construct();
$this->server_composer_file = $this->root_path . 'niucloud' . DIRECTORY_SEPARATOR . 'composer.json';
$this->admin_npm_file = $this->root_path . 'admin' . DIRECTORY_SEPARATOR . 'package.json';
$this->web_npm_file = $this->root_path . 'web' . DIRECTORY_SEPARATOR . 'package.json';
$this->wap_npm_file = $this->root_path . 'uni-app' . DIRECTORY_SEPARATOR . 'package.json';
$this->admin_npm_file = $this->root_path . 'admin' . DIRECTORY_SEPARATOR . 'mysql-mcp-config.json';
$this->web_npm_file = $this->root_path . 'web' . DIRECTORY_SEPARATOR . 'mysql-mcp-config.json';
$this->wap_npm_file = $this->root_path . 'uni-app' . DIRECTORY_SEPARATOR . 'mysql-mcp-config.json';
}
/**
@ -141,11 +141,11 @@ class CoreDependService extends CoreAddonBaseService
public function getAddonNpmContent(string $addon, string $type)
{
if ($type == 'admin') {
$file_path = $this->geAddonPackagePath($addon) . 'admin-package.json';
$file_path = $this->geAddonPackagePath($addon) . 'admin-mysql-mcp-config.json';
} elseif ($type == 'web') {
$file_path = $this->geAddonPackagePath($addon) . 'web-package.json';
$file_path = $this->geAddonPackagePath($addon) . 'web-mysql-mcp-config.json';
} else {
$file_path = $this->geAddonPackagePath($addon) . 'uni-app-package.json';
$file_path = $this->geAddonPackagePath($addon) . 'uni-app-mysql-mcp-config.json';
}
return $this->jsonFileToArray($file_path);
}

106
uniapp/PLANNING.md

@ -1,92 +1,14 @@
✅ 已完成:uniapp/components/service-list-card/index.vue数据问题
- 前端:已添加完整的Mock数据支持,组件可正常显示测试数据
- 后端:PHP后端工程师已成功补充测试数据到数据库
- API测试:接口 `/xy/service/list?student_id=1` 已验证返回完整数据
- 最终状态:前端组件可以正常获取和显示真实的服务列表数据
API返回数据包含:
- 3种不同类型的服务(体测服务、测试服务、1V1+情感沟通)
- 每个服务包含完整的日志记录、评分、反馈信息
- 服务状态、教练信息、时间等完整字段
- 数据结构完全符合前端组件期望格式
✅ 已完成:uniapp/components/service-list-card/index.vue弹窗无法关闭问题
- 问题原因:事件绑定和微信小程序兼容性问题
- 修复内容:添加了事件防冒泡处理,优化微信小程序环境下的事件响应
- 解决方案:增强了响应式更新机制,添加了调试功能
- 验证状态:已修复弹窗关闭功能,支持微信小程序环境
✅ 已处理:components/course-info-card/index.vue页面的接口需求分析
- 已完成接口需求分析,包含完整的数据结构和字段定义
- 已将详细的接口规格写入 niucloud/PLANNING.md 中
- 等待PHP后端工程师按照规格开发接口
- 开发完成后需要进行联调测试
✅ 已修复:课程安排、订单列表、服务列表按钮点击无法打开弹窗问题
- 问题原因:事件冒泡导致按钮点击事件冒泡到遮罩层,立即触发关闭逻辑
- 修复方案:为所有触发弹窗的按钮添加 `.stop` 事件修饰符阻止冒泡
- 涉及组件:主页面、OrderListCard、ServiceListCard等所有弹窗相关按钮
- 验证状态:弹窗打开和关闭功能均正常,微信小程序环境兼容
✅ 已修复:pages/market/clue/clue_info.vue页面所有点击事件失灵问题
- 问题原因:底部弹窗组件的遮罩层一直存在并覆盖整个视口,拦截所有页面点击
- 核心问题:遮罩层即使弹窗隐藏时仍然监听点击事件,导致所有操作被误判为遮罩点击
- 修复方案:
- 为BottomPopup组件添加 `v-if="visible"` 条件渲染
- 关键元素添加 `@click.stop` 阻止事件冒泡
- 优化弹窗关闭时的数据重置逻辑
- 影响范围:修复了页面上所有按钮、标签切换、操作项的点击响应
- 验证状态:页面交互功能完全恢复正常,微信小程序环境兼容
📋 体测记录PDF附件预览功能需求
**背景**:体测记录弹窗需要支持PDF附件预览功能,允许用户查看体测报告
**需求描述**:
1. 体测记录数据中需要包含 `pdf_files` 字段,包含附件信息
2. 需要提供PDF文件预览接口,支持在线预览或下载
3. 前端需要实现PDF预览功能,兼容微信小程序环境
**接口需求**:
1. 获取体测记录接口需要返回PDF附件信息
2. 新增PDF文件预览/下载接口
- 接口路径:`/api/fitness/record/pdf/preview`
- 请求方式:GET
- 请求参数:
```json
{
"file_id": "文件ID",
"record_id": "体测记录ID"
}
```
- 响应数据:
```json
{
"code": 1,
"msg": "success",
"data": {
"file_url": "PDF文件访问URL",
"file_name": "文件名称",
"file_size": 1024000,
"preview_url": "在线预览URL(可选)",
"download_url": "下载URL"
}
}
```
**数据结构扩展**:
体测记录数据中的 `pdf_files` 字段结构:
```json
{
"pdf_files": [
{
"id": "文件ID",
"name": "体测报告.pdf",
"size": 1024000,
"upload_time": "2024-01-15 10:30:00",
"file_path": "/uploads/fitness/2024/01/xxx.pdf"
}
]
}
```
**前端实现**:
- 在 FitnessRecordCard 组件中实现PDF预览按钮
- 支持微信小程序环境下的PDF预览
- 提供下载功能作为备选方案
阅读PRPs/Word模板解析填充功能开发计划.md
pages/parent/contracts/index这个页面的主题样式和其他页面不符需要修改一下,
然后这个页面的接口请求也有一些问题,我目前没有在浏览器控制台看到任何请求但是提示了一个
缺少孩子id参数的提示。我需要你把这个页面的渲染和操作都一并完成,我来讲解一下这个功能的一些需求。
我的数据库里有school_contract_sign as a这个表记录的是合同和人员的关系。
当前登录的人员如果是员工则获取type=1并且personnel_id=1的所有数据分页展示,
这个表要关联school_contract as b表通过a.contract_id=b.id。
然后获取school_contract中的所有字段这里你可以使用thinkphp的模型关联。
然后详情页是需要额外查询school_document_data_source_config和school_document_generate_log这两个表。
如果school_document_generate_log有值则打开弹窗获取school_document_data_source_config中table_name和field_name是 0 的
内容然后根据field_type来渲染输入控件接收用户输入,然后更新school_document_generate_log中的fill_data字段。
然后这个弹窗控件里还有一个签名的字段需要跳转到/pages/common/contract/contract_sign这个页面
进行签名然后将图片地址也添加到fill_data字段一并更新。
测试的 word 文档文件是:doc/副本(时间卡)体能课学员课程协议.docx

BIN
uniapp/TASK.md

Binary file not shown.

10
uniapp/pages.json

@ -601,6 +601,16 @@
"navigationBarTextStyle": "white"
}
}
,
{
"path": "pages/common/profile/personal_info",
"style": {
"navigationBarTitleText": "个人资料",
"navigationStyle": "custom",
"navigationBarBackgroundColor": "#181A20",
"navigationBarTextStyle": "white"
}
}
],
"globalStyle": {

8
uniapp/pages/coach/my/due_soon.vue

@ -1,10 +1,6 @@
<!--即将到期-->
<template>
<view class="main_box">
<!--自定义导航栏-->
<!-- <view class="navbar_section">-->
<!-- <view class="title">班级详情</view>-->
<!-- </view>-->
<view class="main_section">
<!-- 班级成员列表-->
@ -69,10 +65,6 @@
this.getStudentList();
},
methods: {
//tab
tabChange(tabType) {
this.tabType = tabType
},
async getStudentList() {
// API
const res = await memberApi.jlGetStudentList({

1538
uniapp/pages/common/profile/personal_info.vue

File diff suppressed because it is too large

132
各校区转化数据统计需求文档.md

@ -1,132 +0,0 @@
# 各校区月&年转化汇总表数据统计需求文档
## 1. 项目背景
基于智慧教务系统,需要建立完善的数据统计分析功能,为各校区运营决策提供数据支撑。
## 2. 业务目标
- 实现各校区数据的统一汇总和对比分析
- 提供月度、年度的转化率趋势分析
- 为校区运营优化提供数据依据
## 3. 功能需求
### 3.1 数据统计维度
#### 3.1.1 校区维度
- **数据范围**:所有已开设校区
- **统计指标**
- 学员总数
- 新增学员数
- 流失学员数
- 收入金额
- 转化率
#### 3.1.2 时间维度
- **月度统计**:按自然月统计各项指标
- **年度统计**:按自然年统计各项指标
- **对比分析**:同比、环比增长率
#### 3.1.3 课程维度
- **课程类型**:体能课、篮球课、私教课等
- **统计指标**
- 各课程类型学员数
- 各课程类型收入
- 课程转化率
### 3.2 转化率计算规则
#### 3.2.1 试听转化率
```
试听转化率 = (试听后报名学员数 / 试听学员总数) × 100%
```
#### 3.2.2 续费转化率
```
续费转化率 = (续费学员数 / 到期学员总数) × 100%
```
#### 3.2.3 整体转化率
```
整体转化率 = (正式学员数 / 潜在客户总数) × 100%
```
### 3.3 报表功能需求
#### 3.3.1 数据展示
- **表格形式**:支持Excel导出
- **图表形式**:柱状图、折线图、饼图
- **数据筛选**:按校区、时间、课程类型筛选
#### 3.3.2 数据权限
- **超级管理员**:查看所有校区数据
- **校区管理员**:仅查看本校区数据
- **教练**:查看相关课程数据
## 4. 技术实现方案
### 4.1 数据源
- **学员信息表**:基础学员数据
- **课程安排表**:课程相关数据
- **收费记录表**:财务数据
- **考勤记录表**:出勤数据
### 4.2 技术架构
- **后端**:PHP (ThinkPHP框架)
- **前端**:Vue.js + Element UI
- **移动端**:uni-app
- **图表库**:uCharts/ECharts
### 4.3 数据处理流程
1. **数据采集**:从各业务表采集原始数据
2. **数据清洗**:处理异常数据和重复数据
3. **数据计算**:按统计规则计算各项指标
4. **数据存储**:存储到统计结果表
5. **数据展示**:通过API提供给前端展示
## 5. 界面设计要求
### 5.1 PC端管理后台
- **统计概览页**:关键指标卡片展示
- **详细报表页**:可筛选的数据表格
- **图表分析页**:多维度图表展示
### 5.2 移动端
- **数据看板**:关键指标移动端展示
- **简化报表**:适配移动端的数据表格
## 6. 数据安全要求
- **数据加密**:敏感数据加密存储
- **访问控制**:基于角色的权限控制
- **操作日志**:记录数据查看和导出日志
## 7. 性能要求
- **响应时间**:页面加载时间 < 3秒
- **并发支持**:支持100个用户同时访问
- **数据更新**:支持实时或定时更新
## 8. 验收标准
- [ ] 数据统计准确性验证
- [ ] 各维度筛选功能正常
- [ ] 图表展示效果符合要求
- [ ] 权限控制功能正常
- [ ] 导出功能正常
- [ ] 移动端适配正常
## 9. 风险评估
- **数据一致性风险**:需要确保统计数据与业务数据一致
- **性能风险**:大数据量统计可能影响系统性能
- **权限风险**:需要严格控制数据访问权限
## 10. 后续优化建议
- **数据挖掘**:基于历史数据进行趋势预测
- **智能分析**:提供数据异常预警功能
- **自动化报告**:定期自动生成运营报告
---
**注意**:本需求文档基于项目结构分析生成,具体的数据字段和计算规则需要根据实际Excel表格内容进行调整。
**下一步行动**:
1. 请提供Excel表格的具体内容截图或数据样例
2. 确认具体的业务规则和计算公式
3. 明确优先级和开发时间节点
Loading…
Cancel
Save