4 changed files with 0 additions and 1515 deletions
@ -1,406 +0,0 @@ |
|||||
# PHP后端开发规划 |
|
||||
|
|
||||
## 已完成接口 |
|
||||
|
|
||||
### 1. 学员课程信息接口 |
|
||||
|
|
||||
**描述**: 获取学员课程信息,用于前端CourseInfoCard组件使用 |
|
||||
|
|
||||
**接口**: `GET /api/getStudentCourseInfo` |
|
||||
|
|
||||
**请求参数**: |
|
||||
| 参数 | 类型 | 必填 | 说明 | |
|
||||
|--------|------|------|------| |
|
||||
| resource_id | int | 是 | 资源ID | |
|
||||
| member_id | string | 否 | 会员ID | |
|
||||
| student_id | int | 否 | 学员ID(优先级高于member_id) | |
|
||||
|
|
||||
**响应示例**: |
|
||||
```json |
|
||||
{ |
|
||||
"code": 1, |
|
||||
"message": "success", |
|
||||
"data": [ |
|
||||
{ |
|
||||
"id": 1, |
|
||||
"course_name": "篮球课", |
|
||||
"total_count": 24, |
|
||||
"used_count": 8, |
|
||||
"formal_hours": 20, |
|
||||
"gift_hours": 4, |
|
||||
"used_formal_hours": 6, |
|
||||
"used_gift_hours": 2, |
|
||||
"leave_count": 1, |
|
||||
"start_date": "2024-01-01", |
|
||||
"end_date": "2024-12-31", |
|
||||
"expiry_date": "2024-06-30", |
|
||||
"status": "active", |
|
||||
"course_type": "常规课", |
|
||||
"teacher_name": "张老师", |
|
||||
"course_price": 2880.00, |
|
||||
"class_duration": 90, |
|
||||
"create_time": "2024-01-01 10:00:00", |
|
||||
"remark": "备注信息" |
|
||||
} |
|
||||
] |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
**涉及数据表**: |
|
||||
- `school_customer_resources` - 资源表 |
|
||||
- `school_student` - 学员表 |
|
||||
- `school_course` - 课程表 |
|
||||
- `school_student_course` - 学员课程关联表 |
|
||||
- `school_course_schedule` - 课程排期表 |
|
||||
- `school_attendance` - 考勤表 |
|
||||
|
|
||||
**SQL查询逻辑参考**: |
|
||||
```sql |
|
||||
SELECT |
|
||||
sc.id, |
|
||||
sc.course_name, |
|
||||
ssc.total_count, |
|
||||
ssc.used_count, |
|
||||
ssc.formal_hours, |
|
||||
ssc.gift_hours, |
|
||||
ssc.used_formal_hours, |
|
||||
ssc.used_gift_hours, |
|
||||
ssc.leave_count, |
|
||||
ssc.start_date, |
|
||||
ssc.end_date, |
|
||||
ssc.expiry_date, |
|
||||
ssc.status, |
|
||||
sc.course_type, |
|
||||
sp.name as teacher_name, |
|
||||
ssc.course_price, |
|
||||
sc.class_duration, |
|
||||
ssc.create_time, |
|
||||
ssc.remark |
|
||||
FROM school_student_course ssc |
|
||||
LEFT JOIN school_course sc ON ssc.course_id = sc.id |
|
||||
LEFT JOIN school_personnel sp ON sc.teacher_id = sp.id |
|
||||
WHERE ssc.student_id = ? |
|
||||
AND ssc.resource_id = ? |
|
||||
[AND ssc.member_id = ?] |
|
||||
ORDER BY ssc.create_time DESC |
|
||||
``` |
|
||||
|
|
||||
**状态说明**: |
|
||||
- `active`: 正常使用 |
|
||||
- `completed`: 课程完结 |
|
||||
- `expired`: 已过期 |
|
||||
- `pending`: 待激活 |
|
||||
|
|
||||
**业务逻辑**: |
|
||||
1. 优先使用student_id查询,其次使用member_id |
|
||||
2. 计算剩余课时:remaining_count = total_count - used_count |
|
||||
3. 检查课程是否过期,基于expiry_date |
|
||||
4. 返回完整的课程信息及使用情况 |
|
||||
5. 支持多个课程返回 |
|
||||
|
|
||||
**优化建议**: |
|
||||
- 使用Redis缓存常用查询结果 |
|
||||
- 对学员课程查询添加索引优化 |
|
||||
- 考虑分页处理大量数据 |
|
||||
|
|
||||
## 已新增接口 |
|
||||
|
|
||||
### 2. 服务列表接口 |
|
||||
|
|
||||
**描述**: 获取学员服务记录列表 |
|
||||
|
|
||||
**接口**: `GET /api/xy/service/list` |
|
||||
|
|
||||
**请求参数**: |
|
||||
| 参数 | 类型 | 必填 | 说明 | |
|
||||
|--------|------|------|------| |
|
||||
| student_id | int | 是 | 学员ID | |
|
||||
|
|
||||
**响应示例**: |
|
||||
```json |
|
||||
{ |
|
||||
"code": 1, |
|
||||
"message": "操作成功", |
|
||||
"data": [ |
|
||||
{ |
|
||||
"id": 1, |
|
||||
"service_name": "测试服务", |
|
||||
"preview_image_url": "图片URL", |
|
||||
"description": "服务描述", |
|
||||
"service_type": "服务类型", |
|
||||
"status": "active", |
|
||||
"logs": [ |
|
||||
{ |
|
||||
"id": 1, |
|
||||
"status": 1, |
|
||||
"service_content": "服务内容", |
|
||||
"service_staff": "教练姓名", |
|
||||
"service_time": "服务时间", |
|
||||
"duration": "持续时间", |
|
||||
"customer_feedback": "客户反馈", |
|
||||
"service_rating": 5, |
|
||||
"remark": "备注", |
|
||||
"course_name": "课程名称", |
|
||||
"updated_at": "更新时间" |
|
||||
} |
|
||||
], |
|
||||
"total_count": 3, |
|
||||
"completed_count": 3 |
|
||||
} |
|
||||
] |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
### 3. 体测记录接口(增删改查) |
|
||||
|
|
||||
**描述**: 体测记录的完整CRUD操作 |
|
||||
|
|
||||
**接口列表**: |
|
||||
- `GET /api/xy/physicalTest` - 获取体测记录列表 |
|
||||
- `GET /api/xy/physicalTest/info` - 获取体测记录详情 |
|
||||
- `POST /api/xy/physicalTest/add` - 添加体测记录 |
|
||||
- `POST /api/xy/physicalTest/edit` - 编辑体测记录 |
|
||||
- `POST /api/xy/physicalTest/delete` - 删除体测记录 |
|
||||
|
|
||||
**数据表结构**: |
|
||||
```sql |
|
||||
CREATE TABLE `school_physical_test` ( |
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '体测编号', |
|
||||
`resource_id` int NOT NULL COMMENT '资源ID', |
|
||||
`student_id` int DEFAULT NULL COMMENT '学员ID', |
|
||||
`age` int NOT NULL DEFAULT '0' COMMENT '学员年龄', |
|
||||
`height` decimal(5,2) NOT NULL COMMENT '身高', |
|
||||
`weight` decimal(5,2) NOT NULL COMMENT '体重', |
|
||||
`coach_id` int DEFAULT NULL COMMENT '教练ID', |
|
||||
`seated_forward_bend` decimal(5,2) DEFAULT NULL COMMENT '坐位体前屈', |
|
||||
`sit_ups` decimal(5,2) DEFAULT NULL COMMENT '仰卧起坐', |
|
||||
`push_ups` decimal(5,2) DEFAULT NULL COMMENT '俯卧撑', |
|
||||
`flamingo_balance` decimal(5,2) DEFAULT NULL COMMENT '单脚站立', |
|
||||
`thirty_sec_jump` decimal(5,2) DEFAULT NULL COMMENT '30秒跳绳', |
|
||||
`standing_long_jump` decimal(5,2) DEFAULT NULL COMMENT '立定跳远', |
|
||||
`agility_run` decimal(5,2) DEFAULT NULL COMMENT '敏捷跑', |
|
||||
`balance_beam` decimal(5,2) DEFAULT NULL COMMENT '平衡木', |
|
||||
`tennis_throw` decimal(5,2) DEFAULT NULL COMMENT '网球掷远', |
|
||||
`ten_meter_shuttle_run` decimal(5,2) DEFAULT NULL COMMENT '10米折返跑', |
|
||||
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
|
||||
`updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', |
|
||||
`physical_test_report` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '体测报告附件(多文件)', |
|
||||
PRIMARY KEY (`id`) USING BTREE |
|
||||
) |
|
||||
``` |
|
||||
|
|
||||
### 4. 学习计划接口(基于自定义表单) |
|
||||
|
|
||||
**描述**: 基于diy_form自定义表单的学习计划管理系统 |
|
||||
|
|
||||
**接口列表**: |
|
||||
- `GET /api/xy/studyPlan` - 获取学习计划列表 |
|
||||
- `GET /api/xy/studyPlan/info` - 获取学习计划详情 |
|
||||
- `POST /api/xy/studyPlan/add` - 添加学习计划 |
|
||||
- `POST /api/xy/studyPlan/edit` - 编辑学习计划 |
|
||||
- `POST /api/xy/studyPlan/delete` - 删除学习计划 |
|
||||
- `POST /api/xy/studyPlan/updateProgress` - 更新学习计划进度 |
|
||||
|
|
||||
**数据表**: 使用diy_form自定义表单系统 |
|
||||
- `school_diy_form` - 表单定义 (type='study_plan') |
|
||||
- `school_diy_form_fields` - 字段定义 |
|
||||
- `school_diy_form_records` - 记录数据 |
|
||||
|
|
||||
**响应数据结构**: |
|
||||
```json |
|
||||
{ |
|
||||
"code": 1, |
|
||||
"message": "操作成功", |
|
||||
"data": [ |
|
||||
{ |
|
||||
"id": 1, |
|
||||
"student_id": 1, |
|
||||
"plan_name": "基础体能训练计划", |
|
||||
"plan_content": "针对学员的基础体能进行系统性训练", |
|
||||
"plan_type": "体能训练", |
|
||||
"status": "active", |
|
||||
"progress": 65, |
|
||||
"start_date": "2024-01-15", |
|
||||
"end_date": "2024-03-15", |
|
||||
"target_goals": "提升学员整体体能水平", |
|
||||
"learning_materials": "体能训练器材、训练计划表", |
|
||||
"evaluation_criteria": "体能测试成绩、训练完成度", |
|
||||
"remark": "备注信息", |
|
||||
"create_time": "2024-01-10 14:30:00", |
|
||||
"update_time": "2024-01-10 14:30:00" |
|
||||
} |
|
||||
] |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
## 前端集成状态 |
|
||||
|
|
||||
### ✅ 已完成联调的接口: |
|
||||
1. **课程信息** - `getStudentCourseInfo` (完整联调,Mock与API一致) |
|
||||
2. **服务列表** - `getStudentServiceList` (API正常工作) |
|
||||
3. **体测记录** - `xy_physicalTest` (列表API + 增删改查API完整) |
|
||||
4. **学习计划** - `getStudyPlanList` (基于自定义表单的完整CRUD) |
|
||||
|
|
||||
### 🔧 技术实现特点: |
|
||||
- **统一响应格式**: 所有接口使用统一的 `{code: 1, data: [], msg: "操作成功"}` 格式 |
|
||||
- **JWT认证**: 所有接口通过token头进行身份验证 |
|
||||
- **参数验证**: 完整的参数校验和错误处理 |
|
||||
- **数据库事务**: 确保数据一致性 |
|
||||
- **错误处理**: 完善的异常处理和日志记录 |
|
||||
|
|
||||
### 5. 个人资料接口(员工信息管理) |
|
||||
|
|
||||
**描述**: 员工个人资料的查看和编辑功能,涉及基础信息和详细信息两个数据表 |
|
||||
|
|
||||
**接口列表**: |
|
||||
- `GET /api/getPersonnelInfo` - 获取员工基础信息 |
|
||||
- `POST /api/updatePersonnelInfo` - 更新员工基础信息 |
|
||||
- `GET /api/getPersonnelDetailInfo` - 获取员工详细信息 |
|
||||
- `POST /api/updatePersonnelDetailInfo` - 更新员工详细信息 |
|
||||
|
|
||||
#### 基础信息接口 |
|
||||
|
|
||||
**接口**: `GET /api/getPersonnelInfo` |
|
||||
|
|
||||
**请求参数**: |
|
||||
| 参数 | 类型 | 必填 | 说明 | |
|
||||
|--------|------|------|------| |
|
||||
| id | int | 否 | 员工ID,不传则获取当前登录用户信息 | |
|
||||
|
|
||||
**响应示例**: |
|
||||
```json |
|
||||
{ |
|
||||
"code": 1, |
|
||||
"message": "操作成功", |
|
||||
"data": { |
|
||||
"id": 1, |
|
||||
"name": "张三", |
|
||||
"head_img": "/uploads/avatar/20240101/avatar.jpg", |
|
||||
"gender": 1, |
|
||||
"birthday": "1990-05-15", |
|
||||
"phone": "13800138000", |
|
||||
"email": "zhangsan@example.com", |
|
||||
"wx": "zhangsan_wx", |
|
||||
"address": "北京市朝阳区XXX小区", |
|
||||
"native_place": "山东济南", |
|
||||
"education": "本科", |
|
||||
"profile": "个人简介内容", |
|
||||
"emergency_contact_phone": "13900139000", |
|
||||
"id_card_front": "/uploads/idcard/front.jpg", |
|
||||
"id_card_back": "/uploads/idcard/back.jpg", |
|
||||
"employee_number": "EMP001", |
|
||||
"status": 2, |
|
||||
"account_type": "teacher", |
|
||||
"join_time": "2024-01-01 09:00:00", |
|
||||
"create_time": "2024-01-01 09:00:00", |
|
||||
"update_time": "2024-01-01 09:00:00" |
|
||||
} |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
**接口**: `POST /api/updatePersonnelInfo` |
|
||||
|
|
||||
**请求参数**: |
|
||||
```json |
|
||||
{ |
|
||||
"id": 1, |
|
||||
"name": "张三", |
|
||||
"head_img": "/uploads/avatar/20240101/avatar.jpg", |
|
||||
"gender": 1, |
|
||||
"birthday": "1990-05-15", |
|
||||
"phone": "13800138000", |
|
||||
"email": "zhangsan@example.com", |
|
||||
"wx": "zhangsan_wx", |
|
||||
"address": "北京市朝阳区XXX小区", |
|
||||
"native_place": "山东济南", |
|
||||
"education": "本科", |
|
||||
"profile": "个人简介内容", |
|
||||
"emergency_contact_phone": "13900139000", |
|
||||
"id_card_front": "/uploads/idcard/front.jpg", |
|
||||
"id_card_back": "/uploads/idcard/back.jpg" |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
#### 详细信息接口 |
|
||||
|
|
||||
**接口**: `GET /api/getPersonnelDetailInfo` |
|
||||
|
|
||||
**请求参数**: |
|
||||
| 参数 | 类型 | 必填 | 说明 | |
|
||||
|--------|------|------|------| |
|
||||
| person_id | int | 是 | 员工ID | |
|
||||
|
|
||||
**响应示例**: |
|
||||
```json |
|
||||
{ |
|
||||
"code": 1, |
|
||||
"message": "操作成功", |
|
||||
"data": { |
|
||||
"id": 1, |
|
||||
"person_id": 1, |
|
||||
"name": "张三花名", |
|
||||
"store": "朝阳校区", |
|
||||
"ethnicity": "汉族", |
|
||||
"age": 30, |
|
||||
"tenure": "3年2个月", |
|
||||
"regular_date": "2024-07-01", |
|
||||
"is_regular": "是", |
|
||||
"politics": "群众", |
|
||||
"university": "北京大学", |
|
||||
"major": "体育教育", |
|
||||
"graduation_date": "2015-06-30", |
|
||||
"household_place": "山东省济南市", |
|
||||
"household_type": "城镇户口", |
|
||||
"household_address": "山东省济南市历下区XXX街道", |
|
||||
"current_address": "北京市朝阳区XXX小区", |
|
||||
"emergency_contact": "张父", |
|
||||
"emergency_phone": "13900139000", |
|
||||
"marital_status": "已婚", |
|
||||
"bank_card": "6222021234567890123", |
|
||||
"bank_name": "中国银行北京分行", |
|
||||
"contract_expire": "2025-12-31", |
|
||||
"is_rehired": "否", |
|
||||
"remark": "备注信息", |
|
||||
"created_at": "2024-01-01 09:00:00", |
|
||||
"updated_at": "2024-01-01 09:00:00" |
|
||||
} |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
**接口**: `POST /api/updatePersonnelDetailInfo` |
|
||||
|
|
||||
**请求参数**: 与详细信息响应数据格式相同 |
|
||||
|
|
||||
#### 涉及数据表: |
|
||||
- `school_personnel` - 员工基础信息表 |
|
||||
- `school_personnel_info` - 员工详细信息表 |
|
||||
|
|
||||
#### 字段重复处理: |
|
||||
基于数据库分析,需要删除以下重复字段: |
|
||||
```sql |
|
||||
-- 删除重复字段 |
|
||||
ALTER TABLE school_personnel_info |
|
||||
DROP COLUMN birthday, |
|
||||
DROP COLUMN education, |
|
||||
DROP COLUMN native_place; |
|
||||
``` |
|
||||
|
|
||||
#### 业务逻辑: |
|
||||
1. **只读字段**: `employee_number`(员工编号)、`tenure`(司龄)只能查看不能修改 |
|
||||
2. **司龄计算**: 根据`join_time`自动计算并更新 |
|
||||
3. **图片上传**: 支持头像、身份证正反面图片上传 |
|
||||
4. **数据验证**: |
|
||||
- 手机号格式验证 |
|
||||
- 邮箱格式验证 |
|
||||
- 身份证号码验证 |
|
||||
5. **权限控制**: 员工只能编辑自己的信息 |
|
||||
|
|
||||
#### 前端页面: |
|
||||
- 路径: `/pages/common/profile/personal_info.vue` |
|
||||
- 功能: 查看、编辑员工个人资料 |
|
||||
- 特性: 响应式设计、表单验证、图片上传、分段展示 |
|
||||
|
|
||||
--- |
|
||||
|
|
||||
*最后更新:2024-12-29* |
|
||||
*备注:后续接口开发请及时更新此文档* |
|
||||
@ -1,856 +0,0 @@ |
|||||
# PHP后端开发任务记录 |
|
||||
|
|
||||
## 最新完成任务 ✅ |
|
||||
**学员端订单页面接口对接** (2025-07-31) |
|
||||
|
|
||||
### 任务描述 |
|
||||
根据 `学员端开发计划-后端任务.md` 中的计划,将 `pages/student/orders/index` 页面从 mock 数据改为对接真实接口数据,实现完整的订单管理功能。 |
|
||||
|
|
||||
### 主要修改内容 |
|
||||
1. **移除Mock数据**: |
|
||||
- 删除所有硬编码的模拟订单数据 |
|
||||
- 移除模拟的学员信息数据 |
|
||||
- 清理临时的测试代码 |
|
||||
|
|
||||
2. **接口对接**: |
|
||||
- **订单列表**:对接 `apiRoute.xy_orderTableList()` 接口 |
|
||||
- **订单详情**:对接 `apiRoute.xy_orderTableInfo()` 接口 |
|
||||
- 支持分页加载和状态筛选 |
|
||||
|
|
||||
3. **数据处理优化**: |
|
||||
```javascript |
|
||||
// 新增数据处理方法 |
|
||||
processOrderData(rawData) { |
|
||||
return rawData.map(item => ({ |
|
||||
id: item.id, |
|
||||
order_no: item.order_no || item.order_number, |
|
||||
product_name: item.course_name || item.product_name || '课程订单', |
|
||||
status: this.mapOrderStatus(item.status), |
|
||||
total_amount: item.total_amount || item.amount || '0.00', |
|
||||
// 其他字段映射... |
|
||||
})) |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
4. **状态映射系统**: |
|
||||
```javascript |
|
||||
// 订单状态映射 |
|
||||
mapOrderStatus(status) { |
|
||||
const statusMap = { |
|
||||
'0': 'pending_payment', // 待付款 |
|
||||
'1': 'completed', // 已完成 |
|
||||
'2': 'cancelled', // 已取消 |
|
||||
'3': 'refunded' // 已退款 |
|
||||
} |
|
||||
return statusMap[status] || 'pending_payment' |
|
||||
} |
|
||||
|
|
||||
// 支付方式映射 |
|
||||
mapPaymentMethod(method) { |
|
||||
const methodMap = { |
|
||||
'wxpay': '微信支付', |
|
||||
'alipay': '支付宝', |
|
||||
'cash': '现金支付' |
|
||||
} |
|
||||
return methodMap[method] || method || '' |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
5. **用户认证增强**: |
|
||||
```javascript |
|
||||
onLoad(options) { |
|
||||
// 优先从参数获取学员ID |
|
||||
this.studentId = parseInt(options.student_id) || 0 |
|
||||
|
|
||||
if (!this.studentId) { |
|
||||
// 从用户信息中获取学员ID |
|
||||
const userInfo = uni.getStorageSync('userInfo') |
|
||||
if (userInfo && userInfo.id) { |
|
||||
this.studentId = userInfo.id |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
if (!this.studentId) { |
|
||||
// 未登录用户跳转到登录页 |
|
||||
uni.redirectTo({ url: '/pages/student/login/login' }) |
|
||||
} |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
6. **订单详情功能**: |
|
||||
```javascript |
|
||||
async viewOrderDetail(order) { |
|
||||
try { |
|
||||
const res = await apiRoute.xy_orderTableInfo({ id: order.id }) |
|
||||
if (res.code === 1) { |
|
||||
// 跳转到订单详情页面 |
|
||||
uni.navigateTo({ url: `/pages/student/orders/detail?id=${order.id}` }) |
|
||||
} else { |
|
||||
// 降级处理:显示简单弹窗 |
|
||||
} |
|
||||
} catch (error) { |
|
||||
// 错误处理 |
|
||||
} |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
### 技术特点 |
|
||||
1. **数据兼容性**: |
|
||||
- 支持多种后端数据格式 |
|
||||
- 提供字段映射和默认值处理 |
|
||||
- 兼容不同的状态值和支付方式 |
|
||||
|
|
||||
2. **错误处理机制**: |
|
||||
- 接口调用失败时的降级处理 |
|
||||
- 用户未登录时的跳转处理 |
|
||||
- 加载状态的友好提示 |
|
||||
|
|
||||
3. **用户体验优化**: |
|
||||
- 保持原有的UI和交互逻辑 |
|
||||
- 添加加载状态提示 |
|
||||
- 支持多种获取学员ID的方式 |
|
||||
|
|
||||
4. **分页功能**: |
|
||||
- 使用 `current_page` 和 `last_page` 判断分页 |
|
||||
- 支持上拉加载更多功能 |
|
||||
- 自动计算订单统计信息 |
|
||||
|
|
||||
### API接口使用 |
|
||||
1. **订单列表接口**: |
|
||||
- 接口:`xy_orderTableList` |
|
||||
- 参数:`{ student_id, page, limit }` |
|
||||
- 功能:获取学员订单列表和分页信息 |
|
||||
|
|
||||
2. **订单详情接口**: |
|
||||
- 接口:`xy_orderTableInfo` |
|
||||
- 参数:`{ id }` |
|
||||
- 功能:获取订单详细信息 |
|
||||
|
|
||||
### 修改文件 |
|
||||
- `uniapp/pages/student/orders/index.vue` - 主要修改文件 |
|
||||
- `uniapp/学员端订单页面接口对接说明.md` - 详细的修改说明文档 |
|
||||
|
|
||||
### 测试要点 |
|
||||
- [ ] 订单列表正确加载 |
|
||||
- [ ] 分页功能正常工作 |
|
||||
- [ ] 状态筛选功能正确 |
|
||||
- [ ] 订单详情查看功能 |
|
||||
- [ ] 错误处理机制 |
|
||||
- [ ] 用户认证流程 |
|
||||
|
|
||||
### 结论 |
|
||||
**Mock数据已完全移除,真实接口已成功对接**!页面现在能够从后端获取真实的订单数据,支持完整的订单管理功能,包括列表查看、状态筛选、详情查看等。用户体验保持一致,同时增强了错误处理和用户认证机制。 |
|
||||
|
|
||||
--- |
|
||||
|
|
||||
## 历史完成任务 ✅ |
|
||||
**修复课程安排页面学员显示问题** (2025-07-31) |
|
||||
|
|
||||
### 任务描述 |
|
||||
修复 `pages/market/clue/class_arrangement` 页面中 `/api/course/courseAllList` 接口返回的课程安排数据不正确的问题。课程有一个正式学员和一个等待位学员,但只显示了一个学员。 |
|
||||
|
|
||||
### 问题分析 |
|
||||
通过深入调查发现问题出现在 `CourseService::listAll()` 方法中查询学员信息的逻辑: |
|
||||
|
|
||||
1. **错误的关联字段**: |
|
||||
- 原代码使用 `pcs.student_id = st.id` 关联 |
|
||||
- 但数据库中 `student_id` 字段为 NULL |
|
||||
- 应该使用 `pcs.resources_id = cr.id` 关联 |
|
||||
|
|
||||
2. **JOIN类型错误**: |
|
||||
- 原代码使用 `join()` (INNER JOIN) |
|
||||
- 导致 `member_id=0` 的记录被过滤掉 |
|
||||
- 应该使用 `leftJoin()` (LEFT JOIN) |
|
||||
|
|
||||
3. **数据完整性问题**: |
|
||||
- "美团01" 学员的 `member_id=0`,在关联 `school_member` 表时失败 |
|
||||
- 需要特殊处理 `member_id=0` 的情况 |
|
||||
|
|
||||
### 数据库分析 |
|
||||
```sql |
|
||||
-- 课程安排中的学员数据 |
|
||||
SELECT pcs.*, cr.name FROM school_person_course_schedule pcs |
|
||||
LEFT JOIN school_customer_resources cr ON pcs.resources_id = cr.id |
|
||||
WHERE pcs.schedule_id = 124; |
|
||||
|
|
||||
-- 结果: |
|
||||
-- id=73, resources_id=5, schedule_type=1, name='测试' (正式学员) |
|
||||
-- id=74, resources_id=31, schedule_type=2, name='美团01' (等待位学员) |
|
||||
|
|
||||
-- 关联数据问题 |
|
||||
SELECT cr.member_id, sm.member_id FROM school_customer_resources cr |
|
||||
LEFT JOIN school_member sm ON cr.member_id = sm.member_id |
|
||||
WHERE cr.id IN (5, 31); |
|
||||
|
|
||||
-- 结果: |
|
||||
-- cr.member_id=2, sm.member_id=2 ✅ (测试) |
|
||||
-- cr.member_id=0, sm.member_id=NULL ❌ (美团01) |
|
||||
``` |
|
||||
|
|
||||
### 修复内容 |
|
||||
**原始代码(有问题)**: |
|
||||
```php |
|
||||
$student = Db::name('person_course_schedule') |
|
||||
->alias('pcs') |
|
||||
->where('pcs.schedule_id', $v['id']) |
|
||||
->join('school_student st', 'pcs.student_id = st.id') // ❌ student_id为NULL |
|
||||
->join('school_customer_resources cr', 'st.user_id = cr.id') |
|
||||
->join('school_member sm', 'cr.member_id = sm.member_id') // ❌ 过滤掉member_id=0 |
|
||||
->field('st.name, sm.headimg as avatar') |
|
||||
->select(); |
|
||||
``` |
|
||||
|
|
||||
**修复后代码**: |
|
||||
```php |
|
||||
$student = Db::name('person_course_schedule') |
|
||||
->alias('pcs') |
|
||||
->where('pcs.schedule_id', $v['id']) |
|
||||
->leftJoin('school_customer_resources cr', 'pcs.resources_id = cr.id') // ✅ 正确关联 |
|
||||
->leftJoin('school_member sm', 'cr.member_id = sm.member_id AND cr.member_id > 0') // ✅ 处理member_id=0 |
|
||||
->field('cr.name, COALESCE(sm.headimg, "") as avatar, pcs.schedule_type, pcs.course_type, pcs.status') |
|
||||
->select(); |
|
||||
``` |
|
||||
|
|
||||
### 修复要点 |
|
||||
1. **关联字段修复**:使用 `resources_id` 而不是 `student_id` |
|
||||
2. **JOIN类型修复**:使用 `leftJoin()` 保留所有记录 |
|
||||
3. **NULL值处理**:使用 `COALESCE()` 处理空头像 |
|
||||
4. **条件优化**:添加 `cr.member_id > 0` 条件避免无效关联 |
|
||||
5. **字段增强**:添加 `schedule_type`、`course_type`、`status` 业务字段 |
|
||||
|
|
||||
### 测试结果 |
|
||||
**修复前**:只显示1个学员("测试") |
|
||||
**修复后**:正确显示2个学员: |
|
||||
- "测试" - 正式学员(schedule_type=1, course_type=1) |
|
||||
- "美团01" - 等待位学员(schedule_type=2, course_type=3) |
|
||||
|
|
||||
### 技术特点 |
|
||||
1. **数据完整性**:确保所有学员记录都能正确显示 |
|
||||
2. **业务区分**:通过 schedule_type 区分正式位和等待位 |
|
||||
3. **容错处理**:处理数据不完整的边界情况 |
|
||||
4. **性能优化**:使用合适的JOIN类型避免数据丢失 |
|
||||
|
|
||||
### 修改文件 |
|
||||
- `niucloud/app/service/api/apiService/CourseService.php` - 修复学员查询逻辑 |
|
||||
- `niucloud/课程安排学员显示修复说明.md` - 详细的修复说明文档 |
|
||||
|
|
||||
### 结论 |
|
||||
**问题已完全修复**!课程安排页面现在能正确显示所有学员信息,包括正式学员和等待位学员,并提供了完整的业务字段信息。 |
|
||||
|
|
||||
--- |
|
||||
|
|
||||
## 历史完成任务 ✅ |
|
||||
**实现登录页面忘记密码弹窗功能** (2025-07-31) |
|
||||
|
|
||||
### 任务描述 |
|
||||
将 `uniapp/pages/student/login/login.vue` 登录页面的忘记密码功能从页面跳转改为弹窗形式,按照设计图实现两步式密码重置流程。 |
|
||||
|
|
||||
### 设计要求 |
|
||||
1. **步骤1:验证手机号码** |
|
||||
- 输入手机号 |
|
||||
- 输入短信验证码(带发送按钮和倒计时) |
|
||||
- 选择用户类型(员工/学员) |
|
||||
|
|
||||
2. **步骤2:设置新密码** |
|
||||
- 输入新密码 |
|
||||
- 确认新密码 |
|
||||
- 密码可见性切换 |
|
||||
|
|
||||
3. **视觉设计** |
|
||||
- 步骤指示器:圆形数字 + 连接线,激活状态为绿色 |
|
||||
- 输入框:灰色背景,圆角设计 |
|
||||
- 绿色主题色调,与登录页面保持一致 |
|
||||
|
|
||||
### 实现内容 |
|
||||
1. **弹窗组件结构**: |
|
||||
```vue |
|
||||
<!-- 主弹窗 --> |
|
||||
<view class="forgot-modal-overlay"> |
|
||||
<view class="forgot-modal"> |
|
||||
<!-- 步骤指示器 --> |
|
||||
<view class="step-indicator"> |
|
||||
<view class="step-item active"> |
|
||||
<text class="step-number">1</text> |
|
||||
<text class="step-text">验证手机号码</text> |
|
||||
</view> |
|
||||
<view class="step-line"></view> |
|
||||
<view class="step-item"> |
|
||||
<text class="step-number">2</text> |
|
||||
<text class="step-text">设置新密码</text> |
|
||||
</view> |
|
||||
</view> |
|
||||
<!-- 步骤内容和操作按钮 --> |
|
||||
</view> |
|
||||
</view> |
|
||||
``` |
|
||||
|
|
||||
2. **数据结构优化**: |
|
||||
```javascript |
|
||||
data() { |
|
||||
return { |
|
||||
showForgotModal: false, |
|
||||
currentStep: 1, |
|
||||
codeCountdown: 0, |
|
||||
forgotForm: { |
|
||||
mobile: '', |
|
||||
code: '', |
|
||||
userType: '', |
|
||||
newPassword: '', |
|
||||
confirmPassword: '' |
|
||||
}, |
|
||||
userTypeOptions: [ |
|
||||
{ value: 'staff', text: '员工' }, |
|
||||
{ value: 'member', text: '学员' } |
|
||||
] |
|
||||
} |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
3. **核心功能方法**: |
|
||||
- `forgot()` - 打开弹窗 |
|
||||
- `sendVerificationCode()` - 发送验证码 |
|
||||
- `nextStep()` - 步骤切换 |
|
||||
- `resetPassword()` - 重置密码 |
|
||||
- `closeForgotModal()` - 关闭弹窗 |
|
||||
|
|
||||
4. **用户体验优化**: |
|
||||
- 表单验证(手机号格式、密码强度等) |
|
||||
- 验证码倒计时(60秒) |
|
||||
- 加载状态提示 |
|
||||
- 错误处理和成功反馈 |
|
||||
- 密码可见性切换 |
|
||||
|
|
||||
5. **响应式样式设计**: |
|
||||
- 弹窗居中显示,宽度90%,最大600rpx |
|
||||
- 输入框统一样式:高度100rpx,灰色背景 |
|
||||
- 绿色主题按钮,与登录页面保持一致 |
|
||||
- 步骤指示器动态状态变化 |
|
||||
|
|
||||
### API接口设计 |
|
||||
1. **发送验证码**:`POST /common/sendVerificationCode` |
|
||||
2. **验证验证码**:`POST /common/verifyCode` |
|
||||
3. **重置密码**:`POST /common/resetPassword` |
|
||||
|
|
||||
### 技术特点 |
|
||||
1. **模块化设计**:弹窗组件独立,不影响原有登录逻辑 |
|
||||
2. **状态管理**:清晰的步骤控制和表单状态管理 |
|
||||
3. **交互优化**:流畅的步骤切换和用户反馈 |
|
||||
4. **代码复用**:用户类型选择器可复用 |
|
||||
|
|
||||
### 修改文件 |
|
||||
1. **前端文件**: |
|
||||
- `uniapp/pages/student/login/login.vue` - 主要实现文件 |
|
||||
- `uniapp/api/apiRoute.js` - 添加忘记密码相关API接口 |
|
||||
|
|
||||
2. **文档文件**: |
|
||||
- `uniapp/忘记密码弹窗功能说明.md` - 完整的功能说明文档 |
|
||||
|
|
||||
### 测试要点 |
|
||||
- [ ] 弹窗正常打开/关闭 |
|
||||
- [ ] 步骤指示器状态变化 |
|
||||
- [ ] 验证码发送和倒计时 |
|
||||
- [ ] 用户类型选择功能 |
|
||||
- [ ] 表单验证和错误提示 |
|
||||
- [ ] 密码重置完整流程 |
|
||||
|
|
||||
### 问题修复 |
|
||||
在实现过程中遇到 Vue 2 模板编译错误: |
|
||||
- **问题**:`Component template should contain exactly one root element` |
|
||||
- **原因**:弹窗代码被放在根元素外部,导致多个根元素 |
|
||||
- **修复**:将所有弹窗移动到根元素内部,保持单一根元素结构 |
|
||||
|
|
||||
### 结论 |
|
||||
**前端UI和交互逻辑已完成并修复**!实现了完整的两步式忘记密码流程,包括步骤指示器、表单验证、用户类型选择等功能。界面美观,交互流畅,符合设计要求。模板结构已修复,编译正常。 |
|
||||
|
|
||||
--- |
|
||||
|
|
||||
## 历史完成任务 ✅ |
|
||||
**修复体测记录新增student_id错误问题** (2025-07-31) |
|
||||
|
|
||||
### 任务描述 |
|
||||
修复 `pages/market/clue/clue_info?resource_sharing_id=39` 页面中体测记录新增时 `student_id` 传递错误的问题。期望 `student_id=2017`,但实际提交的是 `student_id=64`。 |
|
||||
|
|
||||
### 问题分析 |
|
||||
1. **数据传递错误**:`FitnessRecordPopup` 组件中 `student_id` 被错误地设置为 `resource_id` |
|
||||
2. **参数传递缺失**:弹窗组件没有接收正确的 `student_id` 参数 |
|
||||
3. **数据关系复杂**:URL参数、客户资源ID、学生ID之间的关系需要理清 |
|
||||
|
|
||||
### 数据库关系分析 |
|
||||
- **URL参数**:`resource_sharing_id=39` |
|
||||
- **客户资源**:`id=39, name="测试学员3", member_id=8` |
|
||||
- **关联学生**:`id=8, name="888", user_id=8`(根据数据库关系) |
|
||||
- **期望学生**:`id=2017, name="cesa", user_id=64`(用户期望) |
|
||||
|
|
||||
### 修复内容 |
|
||||
1. **添加studentId属性传递**: |
|
||||
```vue |
|
||||
<!-- clue_info.vue 第226行 --> |
|
||||
<FitnessRecordPopup |
|
||||
ref="fitnessRecordPopup" |
|
||||
:resource-id="clientInfo.resource_id" |
|
||||
:student-id="currentStudent && currentStudent.id" |
|
||||
@confirm="handleFitnessRecordConfirm" |
|
||||
/> |
|
||||
``` |
|
||||
|
|
||||
2. **修正弹窗组件props**: |
|
||||
```javascript |
|
||||
// fitness-record-popup.vue |
|
||||
props: { |
|
||||
resourceId: { type: String, default: '' }, |
|
||||
studentId: { type: [String, Number], default: '' } // 新增 |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
3. **修正提交参数**: |
|
||||
```javascript |
|
||||
// fitness-record-popup.vue confirm方法 |
|
||||
const params = { |
|
||||
resource_id: this.resourceId, |
|
||||
student_id: this.studentId, // 使用正确的student_id |
|
||||
test_date: this.recordData.test_date, |
|
||||
height: this.recordData.height, |
|
||||
weight: this.recordData.weight, |
|
||||
physical_test_report: this.recordData.pdf_files |
|
||||
.map(file => file.server_path || file.url) |
|
||||
.filter(path => path) |
|
||||
.join(',') |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
4. **添加参数验证**: |
|
||||
```javascript |
|
||||
if (!this.studentId) { |
|
||||
uni.showToast({ |
|
||||
title: '缺少学生ID,请稍后重试', |
|
||||
icon: 'none' |
|
||||
}) |
|
||||
return |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
### 技术改进 |
|
||||
1. **参数传递优化**:明确区分 `resource_id` 和 `student_id` 的作用 |
|
||||
2. **错误处理增强**:添加参数验证和错误提示 |
|
||||
3. **调试信息完善**:添加详细的控制台日志用于调试 |
|
||||
|
|
||||
### 数据流向分析 |
|
||||
1. **页面加载**:`resource_sharing_id=39` |
|
||||
2. **获取客户信息**:`clientInfo.resource_id = 39` |
|
||||
3. **获取学生列表**:调用 `xs_getStudentList({ parent_resource_id: 39 })` |
|
||||
4. **学生数据处理**:`currentStudent.id` 作为 `student_id` 传递 |
|
||||
5. **体测记录提交**:使用正确的 `student_id` |
|
||||
|
|
||||
### 待确认问题 |
|
||||
1. **数据关系验证**:`resource_id=39` 应该对应哪个具体学生? |
|
||||
2. **业务逻辑确认**:是否需要修正数据库中的关联关系? |
|
||||
|
|
||||
### 修改文件 |
|
||||
1. **前端文件**: |
|
||||
- `uniapp/pages/market/clue/clue_info.vue` - 添加student_id参数传递 |
|
||||
- `uniapp/components/fitness-record-popup/fitness-record-popup.vue` - 修正参数接收和使用 |
|
||||
|
|
||||
2. **调试文档**: |
|
||||
- `niucloud/体测记录数据调试.md` - 完整的问题分析和修复方案 |
|
||||
|
|
||||
### 结论 |
|
||||
**代码逻辑已修复**!现在 `student_id` 会正确传递,不再使用 `resource_id` 作为 `student_id`。但需要确认数据库中的学生关联关系是否正确,以确保传递的 `student_id` 符合业务预期。 |
|
||||
|
|
||||
--- |
|
||||
|
|
||||
## 历史完成任务 ✅ |
|
||||
**修复文件上传签名错误问题** (2025-07-31) |
|
||||
|
|
||||
### 任务描述 |
|
||||
修复 `CoreUploadService.php` 文件中的 `after` 方法报错"The Signature you specified is invalid",以及 `$this->validate` 为空数组的问题。 |
|
||||
|
|
||||
### 问题分析 |
|
||||
1. **调试语句中断**:第78行的 `dd()` 调试语句导致程序在上传前中断 |
|
||||
2. **异常处理缺失**:没有详细的错误日志记录 |
|
||||
3. **路由配置混淆**:实际路由与预期不符 |
|
||||
|
|
||||
### 深度诊断 |
|
||||
通过创建诊断脚本验证了腾讯云COS配置: |
|
||||
- ✅ **存储桶连接成功**:配置正确,权限正常 |
|
||||
- ✅ **测试文件上传成功**:基础上传功能正常 |
|
||||
- ✅ **服务器时间同步**:无时间偏差问题 |
|
||||
- ✅ **配置信息完整**:Access Key、Secret Key、Region等配置正确 |
|
||||
|
|
||||
### 修复内容 |
|
||||
1. **移除调试语句**: |
|
||||
- 删除第78行的 `dd($this->upload_driver,$type,$this->validate,$dir);` |
|
||||
- 添加注释说明 |
|
||||
|
|
||||
2. **添加异常处理**: |
|
||||
```php |
|
||||
try { |
|
||||
$this->upload_driver->setType($type)->setValidate($this->validate)->upload($dir); |
|
||||
} catch (\Exception $e) { |
|
||||
\think\facade\Log::error('Upload failed: ' . $e->getMessage(), [ |
|
||||
'file_info' => $file_info, |
|
||||
'dir' => $dir, |
|
||||
'type' => $type, |
|
||||
'validate' => $this->validate, |
|
||||
'upload_driver' => get_class($this->upload_driver) |
|
||||
]); |
|
||||
throw $e; |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
3. **路由配置澄清**: |
|
||||
- 员工端文档上传:`POST /api/uploadDocument` |
|
||||
- 学生端文档上传:`POST /api/memberUploadDocument` |
|
||||
- 学员头像上传:`POST /api/student/avatar` |
|
||||
|
|
||||
### 技术发现 |
|
||||
1. **验证规则正常**:`$this->validate = []` 是正常的默认值 |
|
||||
2. **腾讯云COS正常**:配置和连接都没有问题 |
|
||||
3. **错误根源**:调试语句导致程序中断,未能执行实际上传 |
|
||||
|
|
||||
### 创建的诊断工具 |
|
||||
1. **腾讯云COS诊断脚本**:`debug_upload.php` |
|
||||
- 验证配置正确性 |
|
||||
- 测试连接和上传功能 |
|
||||
- 检查服务器时间同步 |
|
||||
|
|
||||
2. **上传测试脚本**:`test_upload.php` |
|
||||
- 模拟文件上传请求 |
|
||||
- 验证路由配置 |
|
||||
- 测试接口响应 |
|
||||
|
|
||||
3. **问题诊断报告**:`上传问题诊断报告.md` |
|
||||
- 完整的问题分析 |
|
||||
- 修复方案说明 |
|
||||
- 使用指南和注意事项 |
|
||||
|
|
||||
### 修改文件 |
|
||||
- `niucloud/app/service/core/upload/CoreUploadService.php` - 修复调试语句和异常处理 |
|
||||
- `niucloud/debug_upload.php` - 腾讯云COS诊断脚本 |
|
||||
- `niucloud/test_upload.php` - 上传功能测试脚本 |
|
||||
- `niucloud/上传问题诊断报告.md` - 完整诊断报告 |
|
||||
|
|
||||
### 结论 |
|
||||
**主要问题已修复**!调试语句的移除解决了程序中断问题,腾讯云COS配置完全正常。建议在实际环境中进行完整的文件上传测试。 |
|
||||
|
|
||||
--- |
|
||||
|
|
||||
## 历史完成任务 ✅ |
|
||||
**完善客户资源和六要素修改记录功能** (2025-07-31) |
|
||||
|
|
||||
### 任务描述 |
|
||||
用户反映六要素修改时没有修改记录,需要检查和完善 `school_customer_resources` 和 `school_six_speed` 的修改记录功能。 |
|
||||
|
|
||||
### 问题分析 |
|
||||
经过深入调查发现,**六要素修改记录功能已经完整实现并正常工作**!用户反映的问题主要是: |
|
||||
1. **入口不明显**:编辑页面没有明显的查看修改记录按钮 |
|
||||
2. **字段回显异常**:购买力和备注字段回显问题影响用户体验 |
|
||||
|
|
||||
### 功能现状验证 |
|
||||
1. **数据库表完整**: |
|
||||
- `school_customer_resource_changes` - 客户资源修改记录 |
|
||||
- `school_six_speed_modification_log` - 六要素修改记录(已有41条记录) |
|
||||
|
|
||||
2. **后端功能完善**: |
|
||||
- `CustomerResourcesService::editData()` 自动记录修改 |
|
||||
- `compareData()` 方法精确对比字段变化 |
|
||||
- API接口 `/api/customerResources/getEditLogList` 支持查询 |
|
||||
|
|
||||
3. **前端功能完整**: |
|
||||
- `edit_clues_log.vue` 修改记录查看页面 |
|
||||
- 支持切换客户资源和六要素修改记录 |
|
||||
- 时间轴展示修改历史 |
|
||||
|
|
||||
### 优化内容 |
|
||||
1. **修复字段回显问题**: |
|
||||
- 购买力字段:`purchasing_power_name` → `purchase_power_name` |
|
||||
- 备注字段:`remark` → `consultation_remark` |
|
||||
|
|
||||
2. **添加查看修改记录入口**: |
|
||||
- 在"基础信息"标题右侧添加"查看修改记录"按钮 |
|
||||
- 在"六要素信息"标题右侧添加"查看修改记录"按钮 |
|
||||
- 点击按钮跳转到修改记录页面 |
|
||||
|
|
||||
3. **创建测试数据**: |
|
||||
- 为 resource_id=38 设置测试数据 |
|
||||
- 插入测试修改记录验证功能 |
|
||||
|
|
||||
### 技术特点 |
|
||||
- **自动化记录**:编辑时自动记录,无需手动触发 |
|
||||
- **详细对比**:记录修改前后的完整数据 |
|
||||
- **字段级别**:精确到每个字段的变化 |
|
||||
- **权限控制**:记录操作人和操作时间 |
|
||||
- **直观展示**:时间轴形式展示修改历史 |
|
||||
|
|
||||
### 修改文件 |
|
||||
1. **前端文件**: |
|
||||
- `uniapp/pages/market/clue/edit_clues.vue` - 修复字段回显,添加查看记录按钮 |
|
||||
- `uniapp/修改记录功能测试报告.md` - 功能测试报告 |
|
||||
|
|
||||
2. **测试验证**: |
|
||||
- 数据库记录验证:41条六要素修改记录 |
|
||||
- 字段回显测试:购买力和备注正确显示 |
|
||||
- 功能完整性测试:修改记录查看正常 |
|
||||
|
|
||||
### 结论 |
|
||||
**六要素修改记录功能完全正常**,用户之前遇到的问题是由于入口不明显和字段回显异常导致的误解。现已全部修复并优化用户体验。 |
|
||||
|
|
||||
--- |
|
||||
|
|
||||
## 历史完成任务 ✅ |
|
||||
**修复编辑客户页面字段回显问题** (2025-07-31) |
|
||||
|
|
||||
### 任务描述 |
|
||||
修复 `pages/market/clue/edit_clues` 页面中电话六要素的购买力字段和备注字段无法正确回显的问题。 |
|
||||
|
|
||||
### 问题分析 |
|
||||
1. **购买力字段名不一致**: |
|
||||
- 前端代码使用:`purchasing_power_name` |
|
||||
- 后端返回:`purchase_power_name` |
|
||||
- 数据库字段:`purchase_power` |
|
||||
|
|
||||
2. **备注字段名不一致**: |
|
||||
- 前端代码使用:`remark` |
|
||||
- 数据库字段:`consultation_remark` |
|
||||
|
|
||||
### 修复内容 |
|
||||
1. **购买力字段修复**: |
|
||||
- 第875行:`purchasing_power: sixSpeed.purchase_power`(原:`purchasing_power`) |
|
||||
- 第945行:`sixSpeed.purchase_power_name`(原:`purchasing_power_name`) |
|
||||
|
|
||||
2. **备注字段修复**: |
|
||||
- 第886行:`remark: sixSpeed.consultation_remark`(原:`remark`) |
|
||||
|
|
||||
### 测试验证 |
|
||||
- **测试数据**:为 resource_id=38 设置测试数据(购买力=2,备注="测试备注信息") |
|
||||
- **验证结果**:字段名修复后,数据能够正确回显 |
|
||||
|
|
||||
### 修改文件 |
|
||||
- `uniapp/pages/market/clue/edit_clues.vue` - 修复字段名不一致问题 |
|
||||
|
|
||||
--- |
|
||||
|
|
||||
## 历史完成任务 ✅ |
|
||||
**微信自动登录功能完整实现** (2025-07-31) |
|
||||
|
|
||||
### 任务描述 |
|
||||
在学员登录页面新增微信自动登录功能,支持微信小程序openid登录,未绑定用户可通过webview获取公众号openid进行账号绑定。 |
|
||||
|
|
||||
### 实现内容 |
|
||||
|
|
||||
#### 1. 后端接口开发 |
|
||||
- **微信登录接口**: `POST /api/login/wechat` |
|
||||
- 支持小程序openid登录 |
|
||||
- 返回特殊错误码10001表示需要绑定 |
|
||||
- **微信绑定接口**: `POST /api/wechat/bind` |
|
||||
- 支持小程序openid + 公众号openid + 手机号 + 验证码绑定 |
|
||||
- **获取授权URL接口**: `GET /api/wechat/auth_url` |
|
||||
- 生成微信公众号授权链接 |
|
||||
- **授权回调接口**: `GET /api/wechat/callback` |
|
||||
- 处理微信公众号授权回调 |
|
||||
|
|
||||
#### 2. 数据库字段利用 |
|
||||
- **CustomerResources表字段**: |
|
||||
- `miniopenid`: 存储微信小程序openid |
|
||||
- `wechatopenid`: 存储微信公众号openid |
|
||||
- `login_ip`, `login_count`, `login_time`: 登录信息记录 |
|
||||
|
|
||||
#### 3. 前端功能实现 |
|
||||
- **登录页面增强**: |
|
||||
- 添加"微信一键登录"按钮(仅学员端显示) |
|
||||
- 微信登录流程处理 |
|
||||
- 绑定成功后自动登录 |
|
||||
- **微信绑定页面**: |
|
||||
- webview显示微信授权页面 |
|
||||
- 手机号验证码绑定表单 |
|
||||
- 完整的用户交互流程 |
|
||||
|
|
||||
#### 4. 技术实现 |
|
||||
- **UnifiedLoginService扩展**: |
|
||||
- 添加 `wechatLogin` 方法:微信openid登录 |
|
||||
- 添加 `wechatBind` 方法:微信账号绑定 |
|
||||
- 集成现有短信验证码系统 |
|
||||
- **WechatService新增**: |
|
||||
- 微信公众号配置获取 |
|
||||
- 授权URL生成 |
|
||||
- 授权回调处理 |
|
||||
- HTTP请求封装 |
|
||||
- **WechatLogin控制器**: |
|
||||
- 统一的微信登录接口管理 |
|
||||
- 完善的错误处理和参数验证 |
|
||||
|
|
||||
#### 5. 安全特性 |
|
||||
- **绑定限制**: 已绑定微信的账号无法重复绑定 |
|
||||
- **openid唯一性**: 同一openid不能绑定多个账号 |
|
||||
- **验证码验证**: 集成现有短信验证码系统 |
|
||||
- **授权安全**: 使用state参数传递小程序openid |
|
||||
|
|
||||
### 接口测试结果 |
|
||||
- ✅ **微信登录接口**: 正确返回需要绑定提示(错误码10001) |
|
||||
- ✅ **获取授权URL接口**: 正确生成微信公众号授权链接 |
|
||||
- ✅ **配置读取**: 正确从数据库获取微信公众号配置 |
|
||||
- ✅ **参数验证**: 完善的参数校验和错误提示 |
|
||||
|
|
||||
### 修改的文件 |
|
||||
1. **后端文件**: |
|
||||
- `niucloud/app/service/api/login/UnifiedLoginService.php` - 添加微信登录和绑定方法 |
|
||||
- `niucloud/app/api/controller/login/WechatLogin.php` - 新增微信登录控制器 |
|
||||
- `niucloud/app/service/api/login/WechatService.php` - 新增微信服务类 |
|
||||
- `niucloud/app/api/route/route.php` - 添加微信登录路由 |
|
||||
|
|
||||
2. **前端文件**: |
|
||||
- `uniapp/pages/student/login/login.vue` - 添加微信登录按钮和逻辑 |
|
||||
- `uniapp/pages/student/login/wechat-bind.vue` - 新增微信绑定页面 |
|
||||
- `uniapp/api/apiRoute.js` - 添加微信登录API接口 |
|
||||
- `uniapp/pages.json` - 添加绑定页面路由 |
|
||||
|
|
||||
### 业务流程 |
|
||||
1. **首次登录流程**: |
|
||||
- 用户点击"微信一键登录" → 获取小程序openid → 调用微信登录接口 |
|
||||
- 返回需要绑定提示 → 显示绑定确认弹窗 → 打开webview授权页面 |
|
||||
- 用户完成微信授权 → 显示绑定表单 → 输入手机号和验证码 → 完成绑定 |
|
||||
- 自动返回登录页面 → 自动执行微信登录 → 登录成功 |
|
||||
|
|
||||
2. **已绑定用户登录**: |
|
||||
- 用户点击"微信一键登录" → 获取小程序openid → 调用微信登录接口 |
|
||||
- 直接登录成功 → 跳转到首页 |
|
||||
|
|
||||
### 技术特点 |
|
||||
- **完整流程**: 从获取openid到绑定到登录的完整闭环 |
|
||||
- **用户体验**: 流畅的交互流程,清晰的状态提示 |
|
||||
- **安全可靠**: 多重验证,防止重复绑定和恶意操作 |
|
||||
- **兼容性**: 与现有登录系统完美集成 |
|
||||
- **可扩展**: 预留了更多微信功能的扩展空间 |
|
||||
|
|
||||
--- |
|
||||
|
|
||||
## 历史完成任务 ✅ |
|
||||
**完整实现个人资料接口功能** (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-31* |
|
||||
*状态:微信自动登录功能已完成并测试通过,可部署到服务器进行完整测试* |
|
||||
@ -1,239 +0,0 @@ |
|||||
# 学员信息管理模块 - 测试验收文档 |
|
||||
|
|
||||
**模块名称**:学员信息管理模块 |
|
||||
**开发完成日期**:2025-01-30 |
|
||||
**测试负责人**:AI项目经理 |
|
||||
**API接口数量**:5个 |
|
||||
|
|
||||
--- |
|
||||
|
|
||||
## 📋 **模块功能概述** |
|
||||
|
|
||||
该模块提供学员端访问和管理学员信息的功能,包括: |
|
||||
1. 获取学员列表(支持多孩子) |
|
||||
2. 获取学员概览信息(用于首页) |
|
||||
3. 获取学员详细信息 |
|
||||
4. 更新学员基本信息 |
|
||||
5. 上传学员头像 |
|
||||
|
|
||||
--- |
|
||||
|
|
||||
## 🔌 **API接口清单** |
|
||||
|
|
||||
### 1. **获取学员列表** |
|
||||
- **接口路径**:`GET /api/student/list` |
|
||||
- **功能描述**:获取当前用户的所有学员列表,支持多孩子家庭 |
|
||||
- **权限要求**:需要登录token |
|
||||
- **响应数据**:学员基本信息列表 |
|
||||
|
|
||||
### 2. **获取学员概览信息** |
|
||||
- **接口路径**:`GET /api/student/summary/{student_id}` |
|
||||
- **功能描述**:获取指定学员的概览信息,用于首页展示 |
|
||||
- **权限要求**:需要登录token,只能查看自己的孩子 |
|
||||
- **响应数据**:学员概览信息,包含年龄、性别、入会时间等 |
|
||||
|
|
||||
### 3. **获取学员详细信息** |
|
||||
- **接口路径**:`GET /api/student/info/{student_id}` |
|
||||
- **功能描述**:获取指定学员的详细信息 |
|
||||
- **权限要求**:需要登录token,只能查看自己的孩子 |
|
||||
- **响应数据**:学员完整信息 |
|
||||
1 |
|
||||
### 4. **更新学员信息** |
|
||||
- **接口路径**:`PUT /api/student/update` |
|
||||
- **功能描述**:更新学员的基本信息 |
|
||||
- **权限要求**:需要登录token,只能修改自己的孩子 |
|
||||
- **请求参数**:学员ID及要更新的字段 |
|
||||
|
|
||||
### 5. **上传学员头像** |
|
||||
- **接口路径**:`POST /api/student/avatar` |
|
||||
- **功能描述**:上传并更新学员头像 |
|
||||
- **权限要求**:需要登录token,只能修改自己的孩子 |
|
||||
- **文件要求**:图片格式,大小不超过2MB |
|
||||
|
|
||||
--- |
|
||||
|
|
||||
## 🧪 **测试用例** |
|
||||
|
|
||||
### 测试用例1:获取学员列表 |
|
||||
```bash |
|
||||
# 测试命令 |
|
||||
curl -X GET "http://localhost:20080/api/student/list" \ |
|
||||
-H "Authorization: Bearer YOUR_TOKEN" \ |
|
||||
-H "Content-Type: application/json" |
|
||||
|
|
||||
# 预期结果 |
|
||||
{ |
|
||||
"code": 200, |
|
||||
"message": "获取学员列表成功", |
|
||||
"data": { |
|
||||
"list": [ |
|
||||
{ |
|
||||
"id": 1, |
|
||||
"name": "张小明", |
|
||||
"gender": 1, |
|
||||
"gender_text": "男", |
|
||||
"age": 8, |
|
||||
"headimg": "http://domain/uploads/avatar/xxx.jpg", |
|
||||
"create_time": "2024-01-01 10:00:00" |
|
||||
} |
|
||||
], |
|
||||
"total": 1 |
|
||||
} |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
### 测试用例2:获取学员概览信息 |
|
||||
```bash |
|
||||
# 测试命令 |
|
||||
curl -X GET "http://localhost:20080/api/student/summary/1" \ |
|
||||
-H "Authorization: Bearer YOUR_TOKEN" \ |
|
||||
-H "Content-Type: application/json" |
|
||||
|
|
||||
# 预期结果 |
|
||||
{ |
|
||||
"code": 200, |
|
||||
"message": "获取学员概览成功", |
|
||||
"data": { |
|
||||
"student_id": 1, |
|
||||
"name": "张小明", |
|
||||
"age": 8, |
|
||||
"gender": 1, |
|
||||
"gender_text": "男", |
|
||||
"headimg": "http://domain/uploads/avatar/xxx.jpg", |
|
||||
"member_name": "张先生", |
|
||||
"create_year_month": "2024年01月", |
|
||||
"week_day": "星期三" |
|
||||
} |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
### 测试用例3:更新学员信息 |
|
||||
```bash |
|
||||
# 测试命令 |
|
||||
curl -X PUT "http://localhost:20080/api/student/update" \ |
|
||||
-H "Authorization: Bearer YOUR_TOKEN" \ |
|
||||
-H "Content-Type: application/json" \ |
|
||||
-d '{ |
|
||||
"student_id": 1, |
|
||||
"name": "张小明", |
|
||||
"emergency_contact": "张妈妈", |
|
||||
"emergency_phone": "13800138000", |
|
||||
"address": "北京市朝阳区xxx小区" |
|
||||
}' |
|
||||
|
|
||||
# 预期结果 |
|
||||
{ |
|
||||
"code": 200, |
|
||||
"message": "更新学员信息成功", |
|
||||
"data": true |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
### 测试用例4:权限验证测试 |
|
||||
```bash |
|
||||
# 测试命令:尝试访问其他用户的学员信息 |
|
||||
curl -X GET "http://localhost:20080/api/student/info/999" \ |
|
||||
-H "Authorization: Bearer YOUR_TOKEN" \ |
|
||||
-H "Content-Type: application/json" |
|
||||
|
|
||||
# 预期结果:应该返回权限错误 |
|
||||
{ |
|
||||
"code": 403, |
|
||||
"message": "无权限访问该学员信息", |
|
||||
"data": null |
|
||||
} |
|
||||
``` |
|
||||
|
|
||||
--- |
|
||||
|
|
||||
## ✅ **验收标准** |
|
||||
|
|
||||
### 功能验收标准 |
|
||||
- [ ] **API接口正常响应**:所有5个接口都能正常返回数据 |
|
||||
- [ ] **数据格式正确**:返回的JSON数据结构符合接口文档 |
|
||||
- [ ] **权限控制严格**:只能访问自己的孩子信息,不能越权访问 |
|
||||
- [ ] **数据验证完整**:输入参数验证正确,异常情况处理完善 |
|
||||
- [ ] **图片上传功能**:头像上传功能正常,支持常见图片格式 |
|
||||
|
|
||||
### 性能验收标准 |
|
||||
- [ ] **响应时间**:接口响应时间 < 500ms |
|
||||
- [ ] **并发处理**:支持至少10个并发请求 |
|
||||
- [ ] **数据准确性**:返回的学员信息与数据库数据一致 |
|
||||
|
|
||||
### 安全验收标准 |
|
||||
- [ ] **Token验证**:未登录用户不能访问接口 |
|
||||
- [ ] **权限隔离**:用户只能操作自己的学员数据 |
|
||||
- [ ] **输入过滤**:防止SQL注入和XSS攻击 |
|
||||
- [ ] **文件上传安全**:头像上传限制文件类型和大小 |
|
||||
|
|
||||
--- |
|
||||
|
|
||||
## 🚨 **已知问题和风险** |
|
||||
|
|
||||
### 高优先级问题 |
|
||||
1. **Token获取方式**:当前代码中`getUserId()`方法需要完善,需要从实际的认证中间件获取用户ID |
|
||||
2. **图片上传服务**:需要确认`UploadService`类是否存在并可用 |
|
||||
3. **数据库连接**:需要确保所有相关的Model类路径正确 |
|
||||
|
|
||||
### 中优先级问题 |
|
||||
1. **年龄计算精度**:当前按年计算,可能需要更精确的月份计算 |
|
||||
2. **头像URL处理**:`get_image_url()`函数需要确认是否存在 |
|
||||
3. **异常处理统一**:需要统一异常返回格式 |
|
||||
|
|
||||
### 低优先级问题 |
|
||||
1. **代码注释**:部分复杂逻辑需要添加更详细的注释 |
|
||||
2. **日志记录**:关键操作需要添加日志记录 |
|
||||
|
|
||||
--- |
|
||||
|
|
||||
## 📝 **验收流程** |
|
||||
|
|
||||
### 第一步:环境准备 |
|
||||
1. 确保数据库连接正常 |
|
||||
2. 确保相关数据表存在且有测试数据 |
|
||||
3. 获取有效的测试token |
|
||||
|
|
||||
### 第二步:功能测试 |
|
||||
1. 依次执行所有测试用例 |
|
||||
2. 验证返回数据的正确性 |
|
||||
3. 测试异常情况的处理 |
|
||||
|
|
||||
### 第三步:性能测试 |
|
||||
1. 使用压力测试工具测试并发性能 |
|
||||
2. 监控接口响应时间 |
|
||||
3. 检查内存和CPU使用情况 |
|
||||
|
|
||||
### 第四步:安全测试 |
|
||||
1. 测试无token访问 |
|
||||
2. 测试越权访问 |
|
||||
3. 测试恶意输入 |
|
||||
|
|
||||
### 第五步:集成测试 |
|
||||
1. 与前端页面联调 |
|
||||
2. 测试完整的用户操作流程 |
|
||||
3. 验证数据一致性 |
|
||||
|
|
||||
--- |
|
||||
|
|
||||
## 📊 **验收结果** |
|
||||
|
|
||||
**验收状态**:待验收 |
|
||||
**预计验收时间**:模块开发完成后1个工作日内 |
|
||||
**验收负责人**:项目负责人 |
|
||||
|
|
||||
### 验收结果记录 |
|
||||
- [ ] 功能验收:通过/不通过 |
|
||||
- [ ] 性能验收:通过/不通过 |
|
||||
- [ ] 安全验收:通过/不通过 |
|
||||
- [ ] 代码质量:通过/不通过 |
|
||||
|
|
||||
### 问题记录 |
|
||||
(由验收人员填写发现的问题) |
|
||||
|
|
||||
--- |
|
||||
|
|
||||
**备注**: |
|
||||
1. 本文档作为该模块验收的标准和依据 |
|
||||
2. 所有问题必须在验收通过前解决 |
|
||||
3. 验收通过后方可进入下个模块开发 |
|
||||
4. 如有疑问请及时与项目经理沟通 |
|
||||
@ -1,14 +0,0 @@ |
|||||
阅读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 |
|
||||
Loading…
Reference in new issue