{{ student.name }}
年龄:{{ student.age }}岁
+
+ 签到状态:
+ {{ getStatusText(student.status) }}
+
课程状态:{{ student.courseStatus }}
课程安排:等待位
@@ -555,6 +563,16 @@
// 学员点击处理
handleStudentClick(student, index) {
console.log('点击了学员:', student)
+ // 检查学员签到状态,只有状态为0(待上课)才能进行签到操作
+ if (student.status !== 0) {
+ uni.showToast({
+ title: `该学员已${this.getStatusText(student.status)},无法重复操作`,
+ icon: 'none',
+ duration: 2000
+ });
+ return;
+ }
+
// 检查是否是等待位学员
if (student.schedule_type === 2) {
// 等待位学员 - 询问是否转为正式课
@@ -854,6 +872,16 @@
return statusTextMap[status] || '未知状态';
},
+ // 获取签到状态样式类
+ getStatusClass(status) {
+ const statusClassMap = {
+ 0: 'status-pending', // 待上课
+ 1: 'status-completed', // 已上课
+ 2: 'status-leave' // 请假
+ };
+ return statusClassMap[status] || '';
+ },
+
// 根据课程状态代码获取状态文本
getStatusTextFromCode(statusCode) {
const statusTextMap = {
@@ -1137,6 +1165,44 @@
color: #ff3b30;
}
+ /* 签到状态相关样式 */
+ .attendance-status {
+ display: flex;
+ align-items: center;
+ margin: 8rpx 0;
+ font-size: 24rpx;
+ }
+
+ .status-label {
+ color: #666;
+ margin-right: 8rpx;
+ }
+
+ .status-text {
+ font-weight: 600;
+ padding: 4rpx 12rpx;
+ border-radius: 12rpx;
+ font-size: 22rpx;
+ }
+
+ .status-text.status-pending {
+ background: rgba(255, 149, 0, 0.1);
+ color: #ff9500;
+ border: 1rpx solid rgba(255, 149, 0, 0.2);
+ }
+
+ .status-text.status-completed {
+ background: rgba(41, 211, 180, 0.1);
+ color: #29d3b4;
+ border: 1rpx solid rgba(41, 211, 180, 0.2);
+ }
+
+ .status-text.status-leave {
+ background: rgba(255, 59, 48, 0.1);
+ color: #ff3b30;
+ border: 1rpx solid rgba(255, 59, 48, 0.2);
+ }
+
.status-absent {
color: #8e8e93;
}
diff --git a/uniapp/pages-market/clue/clue_info.vue b/uniapp/pages-market/clue/clue_info.vue
index f5803b24..6fc434a1 100644
--- a/uniapp/pages-market/clue/clue_info.vue
+++ b/uniapp/pages-market/clue/clue_info.vue
@@ -220,6 +220,7 @@
-
-
\ No newline at end of file
diff --git a/uniapp/pages/market/clue/class_arrangement.vue b/uniapp/pages/market/clue/class_arrangement.vue
deleted file mode 100644
index 42946130..00000000
--- a/uniapp/pages/market/clue/class_arrangement.vue
+++ /dev/null
@@ -1,623 +0,0 @@
-
-
-
-
-
- {{ item.week }}
- {{ item.day }}
-
-
-
-
-
- 查询
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 时间:{{ course.course_date || '未设置' }}
- 校区:{{ course.campus_name || '未设置' }}
- 教室:{{ course.venue ? course.venue.venue_name : '未设置' }}
- 课程:{{ course.course ? course.course.course_name : '未设置' }}
- 人数:{{ course.available_capacity || 0 }}
- 安排情况:{{ course.student ? course.student.length : 0 }}/{{course.max_students ? course.max_students : '不限'}}
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/uniapp/pages/market/clue/class_arrangement_detail.vue b/uniapp/pages/market/clue/class_arrangement_detail.vue
deleted file mode 100644
index 949d09cc..00000000
--- a/uniapp/pages/market/clue/class_arrangement_detail.vue
+++ /dev/null
@@ -1,1292 +0,0 @@
-
-
-
-
- 课程安排详情
-
- 日期:{{ schedule_info.course_date }}
- 课程名称:{{ schedule_info.course_name }}
- 课程时间:{{ schedule_info.time_slot }}
- 主教练:{{ schedule_info.coach_name || '待安排' }}
- 场地信息:{{ schedule_info.venue_name }}
-
-
-
-
-
- 正式学员
-
-
-
- 待续费
- {{ stu.name && stu.name.charAt(0) }}
-
- {{ stu.name }}
- 年龄:{{ stu.age || '未知' }}岁
- 课程状态:{{ stu.courseStatus }}
- 上课情况:{{ stu.course_progress.used }}/{{ stu.course_progress.total }}节
- 到期时间:{{ stu.student_course_info.end_date || '未设置' }}
-
-
-
-
-
-
- +
-
-
- 空位
- 点击添加学员
-
-
-
-
-
-
-
- 等待位
-
-
-
- {{ stu.name && stu.name.charAt(0) }}
-
- {{ stu.name }}
- 年龄:{{ stu.age || '未知' }}岁
- 课程状态:{{ stu.courseStatus }}
- 上课情况:{{ stu.course_progress.used }}/{{ stu.course_progress.total }}节 ({{ stu.course_progress.percentage }}%)
- 到期时间:{{ stu.expiryDate || '未设置' }}
-
-
-
-
-
-
- +
-
-
- 等待位
- 点击添加学员
-
-
-
-
-
-
-
-
-
-
-
-
-
- 客户选择
-
-
-
-
-
-
- {{ student.name ? student.name.charAt(0) : '?' }}
-
-
- {{ student.name }}
- 正式学员
-
- {{ student.phone }}
-
-
- ✓
-
-
-
-
-
-
-
- 选中学员
-
- {{ (presetStudent && presetStudent.name) ? presetStudent.name.charAt(0) : '?' }}
-
- {{ (presetStudent && presetStudent.name) || '未知学员' }}
- {{ (presetStudent && presetStudent.phone) || '未知手机号' }}
-
-
-
-
-
-
- 课程安排
-
-
-
-
-
-
-
-
- 备注
-
-
-
-
-
-
-
-
-
-
-
-
- 请假原因
-
-
-
-
- 取消
- 提交
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/uniapp/pages/market/clue/clue_info.less b/uniapp/pages/market/clue/clue_info.less
deleted file mode 100644
index ce333c24..00000000
--- a/uniapp/pages/market/clue/clue_info.less
+++ /dev/null
@@ -1,431 +0,0 @@
-// 客户详情页样式文件
-.assemble {
- background-color: #292929;
- min-height: 100vh;
-}
-
-.content {
- padding: 20rpx;
-}
-
-.tab-switcher-container {
- margin: 20rpx 0;
-}
-
-// 学生信息区域
-.student-section {
- margin-top: 20rpx;
-
- .section-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 20rpx;
-
- .section-title {
- font-size: 32rpx;
- font-weight: bold;
- color: #fff;
- }
-
- .add-student-btn {
- display: flex;
- align-items: center;
- background: #29d3b4;
- color: #fff;
- border-radius: 20rpx;
- padding: 12rpx 20rpx;
- font-size: 24rpx;
-
- .add-icon {
- margin-right: 8rpx;
- font-weight: bold;
- font-size: 20rpx;
- }
-
- &:active {
- background: #1ea08e;
- transform: scale(0.95);
- }
- }
- }
-
- .student-cards {
- width: 100%;
- min-height: 600rpx;
-
- .student-swiper {
- width: 100%;
- height: 560rpx;
-
- .student-swiper-content {
- display: flex;
- flex-direction: column;
- height: 580rpx;
- padding: 20rpx;
- box-sizing: border-box;
- background-color: #434544;
- border-radius: 16rpx;
- margin: 0 10rpx;
- color: #fff;
- }
- }
- }
-}
-
-.popup-footer {
- display: flex;
- padding: 30rpx 40rpx;
- padding-bottom: calc(30rpx + env(safe-area-inset-bottom));
- border-top: 1px solid #333;
- gap: 30rpx;
- flex-shrink: 0; /* 确保底部按钮区域不被压缩 */
- background: #1a1a1a; /* 确保背景色一致 */
-
- .popup-footer-btns {
- display: flex;
- justify-content: space-between;
-
- .footer-btn {
- flex: 1;
- height: 88rpx;
- display: flex;
- width: 45%;
- align-items: center;
- justify-content: center;
- border-radius: 12rpx;
- font-size: 32rpx;
- font-weight: 500;
-
- &.cancel-btn {
- background: #cccccc;
- }
-
- &.confirm-btn {
- background: linear-gradient(45deg, #29D3B4, #1DB584);
- color: #ffffff;
- }
- }
- }
-
-}
-
-// 课程、通话、体测记录等区域
-.course-section, .call-section, .fitness-section, .study-plan-section {
- background-color: #434544;
- border-radius: 16rpx;
- margin: 20rpx 0;
-
- .section-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 20rpx;
-
- .context-title {
- font-size: 28rpx;
- font-weight: bold;
- color: #fff;
- }
-
- .add-record-btn {
- display: flex;
- align-items: center;
- background: #29d3b4;
- color: #fff;
- border-radius: 20rpx;
- padding: 12rpx 20rpx;
- font-size: 24rpx;
-
- .add-icon {
- margin-right: 8rpx;
- font-weight: bold;
- }
-
- &:active {
- background: #1ea08e;
- transform: scale(0.95);
- }
- }
- }
-}
-
-// 操作按钮区域 - 独立于Swiper外部
-.student-section .action-buttons-section {
- display: flex;
- gap: 8rpx;
- margin-top: 15rpx;
- padding: 15rpx;
- flex-wrap: nowrap;
- height: 100rpx;
- box-sizing: border-box;
- overflow-x: auto;
- overflow-y: hidden;
- -webkit-overflow-scrolling: touch;
- background-color: #434544;
- border-radius: 16rpx;
- margin: 15rpx 0;
-
- &::-webkit-scrollbar {
- display: none;
- }
-
- .action-item {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- background: rgba(255, 255, 255, 0.05);
- border: 1px solid rgba(41, 211, 180, 0.3);
- border-radius: 8rpx;
- padding: 12rpx 8rpx;
- min-width: 90rpx;
- flex-shrink: 0;
- transition: all 0.3s ease;
-
- .action-icon {
- font-size: 24rpx;
- margin-bottom: 5rpx;
- line-height: 1;
- }
-
- .action-text {
- font-size: 18rpx;
- color: #fff;
- text-align: center;
- line-height: 1.2;
- word-break: break-all;
- }
-
- &:active {
- background: rgba(41, 211, 180, 0.2);
- border-color: #29d3b4;
- transform: scale(0.95);
-
- .action-text {
- color: #29d3b4;
- }
- }
- }
-}
-
-// 通用空状态样式
-.empty-state {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- padding: 60rpx 20rpx;
- min-height: 200rpx;
-
- .empty-icon {
- font-size: 60rpx;
- opacity: 0.6;
- margin-bottom: 20rpx;
- }
-
- .empty-text {
- color: #ccc;
- font-size: 28rpx;
- margin-bottom: 20rpx;
- }
-
- .empty-add-btn {
- background: #29d3b4;
- color: #fff;
- padding: 12rpx 24rpx;
- border-radius: 20rpx;
- font-size: 24rpx;
- transition: all 0.3s ease;
-
- &:active {
- background: #1ea08e;
- transform: scale(0.95);
- }
- }
-}
-
-// 备注弹窗样式
-.remark-dialog {
- width: 600rpx;
- padding: 30rpx;
- background: #fff;
- border-radius: 16rpx;
-
- textarea {
- width: 100%;
- height: 200rpx;
- padding: 20rpx;
- border: 2rpx solid #e9ecef;
- border-radius: 12rpx;
- font-size: 28rpx;
- color: #333;
- background-color: #fff;
- box-sizing: border-box;
- resize: none;
-
- &::placeholder {
- color: #999;
- }
-
- &:focus {
- border-color: #29d3b4;
- outline: none;
- box-shadow: 0 0 0 2rpx rgba(41, 211, 180, 0.1);
- }
- }
-
- .dialog-btns {
- display: flex;
- gap: 20rpx;
- margin-top: 30rpx;
-
- .btn {
- flex: 1;
- padding: 20rpx;
- border-radius: 8rpx;
- font-size: 28rpx;
- text-align: center;
-
- &.cancel {
- background: #f8f9fa;
- color: #666;
- border: 2rpx solid #e9ecef;
- }
-
- &.confirm {
- background: #29d3b4;
- color: #fff;
- }
- }
- }
-}
-
-// 二维码支付弹窗样式
-.qrcode-payment-modal {
- width: 600rpx;
- background: #fff;
- border-radius: 20rpx;
- overflow: hidden;
-
- .modal-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 40rpx 40rpx 20rpx;
- border-bottom: 1px solid #f0f0f0;
-
- .modal-title {
- font-size: 36rpx;
- font-weight: 600;
- color: #333;
- }
-
- .close-btn {
- width: 60rpx;
- height: 60rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- border-radius: 50%;
- background: #f5f5f5;
- color: #666;
- font-size: 32rpx;
-
- &:active {
- background: #e5e5e5;
- transform: scale(0.95);
- }
- }
- }
-
- .order-info {
- padding: 30rpx 40rpx;
-
- .info-row {
- display: flex;
- align-items: center;
- margin-bottom: 20rpx;
-
- .label {
- font-size: 28rpx;
- color: #666;
- margin-right: 20rpx;
- }
-
- .value {
- font-size: 28rpx;
- color: #333;
- flex: 1;
- }
-
- .amount {
- font-size: 32rpx;
- color: #ff4757;
- font-weight: 600;
- flex: 1;
- }
- }
- }
-
- .qrcode-container {
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 40rpx;
- background: #fafafa;
-
- .qrcode-image {
- width: 300rpx;
- height: 300rpx;
- border: 1px solid #e5e5e5;
- border-radius: 12rpx;
- background: #fff;
- margin-bottom: 20rpx;
- }
-
- .qrcode-tip {
- font-size: 24rpx;
- color: #666;
- text-align: center;
- line-height: 1.4;
- }
- }
-
- .modal-buttons {
- display: flex;
- padding: 30rpx 40rpx 40rpx;
- gap: 20rpx;
-
- .btn {
- flex: 1;
- height: 80rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- border-radius: 40rpx;
- font-size: 28rpx;
- font-weight: 500;
-
- &.secondary {
- background: #f5f5f5;
- color: #666;
-
- &:active {
- background: #e5e5e5;
- transform: scale(0.98);
- }
- }
-
- &.primary {
- background: #29d3b4;
- color: #fff;
-
- &:active {
- background: #1ea08e;
- transform: scale(0.98);
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/uniapp/pages/market/clue/clue_info.vue b/uniapp/pages/market/clue/clue_info.vue
deleted file mode 100644
index a800a7aa..00000000
--- a/uniapp/pages/market/clue/clue_info.vue
+++ /dev/null
@@ -1,1567 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ action.icon }}
-
- {{ action.text }}
-
-
-
-
-
- 👤
- 暂无学生信息
-
- 添加第一个学生
-
-
-
-
-
-
-
-
- 📚
- 暂无课程信息
-
-
-
-
-
-
- 📞
- 暂无通话记录
-
-
-
-
-
-
-
-
-
- 📊
- 暂无体测记录
-
-
-
-
-
-
-
- 📚
- 暂无学习计划
-
-
-
-
-
-
-
-
-
-
-
-
-
- 📊
- 暂无体测记录
- 点击下方"新增"按钮添加体测记录
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 订单号:
- {{ qrCodePaymentData.order.order_no }}
-
-
- 支付金额:
- ¥{{ qrCodePaymentData.order.total_amount }}
-
-
-
-
-
-
- 二维码加载中...
- 请使用微信扫码完成支付
-
-
-
-
- 取消支付
- 发送二维码给客户
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/uniapp/pages/market/clue/clue_table.vue b/uniapp/pages/market/clue/clue_table.vue
deleted file mode 100644
index 46f36e54..00000000
--- a/uniapp/pages/market/clue/clue_table.vue
+++ /dev/null
@@ -1,164 +0,0 @@
-
-
-
-
- {{ row.channel }}
- {{ expanded[rIdx] ? '▲' : '▼' }}
-
-
-
-
- {{ col.label }}
- ?
-
- {{ row[col.key] || '-' }}
-
-
-
- {{ expanded[rIdx] ? '收起' : '展开全部' }}
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/uniapp/pages/market/clue/edit_clues.vue b/uniapp/pages/market/clue/edit_clues.vue
deleted file mode 100644
index 725949d5..00000000
--- a/uniapp/pages/market/clue/edit_clues.vue
+++ /dev/null
@@ -1,1806 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- 基础信息
-
- 查看修改记录
-
-
-
-
-
-
-
- {{ formData.campus ? picker_config.campus.text : '点击选择' }}
-
-
-
-
-
-
-
- {{ formData.source ? picker_config.source.text : '点击选择' }}
-
-
-
-
-
-
-
- {{ formData.source_channel ? picker_config.source_channel.text : '点击选择' }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 男
-
-
-
-
-
- 女
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 是
-
-
-
-
-
- 否
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 六要素信息
-
- 查看修改记录
-
-
-
-
-
-
-
- {{ formData.purchasing_power ? picker_config.purchasing_power.text : '点击选择' }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ formData.cognitive_idea ? picker_config.cognitive_idea.text : '点击选择' }}
-
-
-
-
-
-
-
- {{ formData.optional_class_time ? formData.optional_class_time : '点击选择' }}
-
-
-
-
-
-
-
- {{ formData.promised_visit_time ? formData.promised_visit_time : '点击选择' }}
-
-
-
-
-
-
-
- {{ formData.distance ? picker_config.distance.text : '点击选择' }}
-
-
-
-
-
-
-
- {{ formData.decision_maker ? picker_config.decision_maker.text : '点击选择' }}
-
-
-
-
-
-
-
-
-
-
-
- 是
-
-
-
-
-
- 否
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 跟进与面咨
-
-
-
-
- {{ formData.first_visit_time ? formData.first_visit_time : '点击选择' }}
-
-
-
-
-
-
-
-
-
-
-
-
- {{ formData.second_visit_time ? formData.second_visit_time : '点击选择' }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 报名
-
-
-
-
-
- 未报名
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 请粘贴包含客户信息的文本,支持格式:
- 姓名:张三,电话:13800138000,校区:测试校区
-
-
-
-
- 取消
- 解析并填写
-
-
-
-
-
-
- 保存
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/uniapp/pages/market/clue/edit_clues_log.vue b/uniapp/pages/market/clue/edit_clues_log.vue
deleted file mode 100644
index 7340b68f..00000000
--- a/uniapp/pages/market/clue/edit_clues_log.vue
+++ /dev/null
@@ -1,365 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{v.modification_time}}
-
-
- 修改人:{{v.staff_id_name}} 修改了如下内容
-
-
-
-
-
- | 字段名称 |
- 原数据 |
- 新数据 |
-
-
-
-
-
-
- | {{ row.field_name_zh }} |
- {{ row.old_value }} |
- {{ row.new_value }} |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{v.modification_time}}
-
-
- 修改人:{{v.staff_id_name}} 修改了如下内容
-
-
-
-
-
- | 字段名称 |
- 原数据 |
- 新数据 |
-
-
-
-
-
-
- | {{ row.field_name_zh }} |
- {{ row.old_value }} |
- {{ row.new_value }} |
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/uniapp/pages/market/clue/index.vue b/uniapp/pages/market/clue/index.vue
deleted file mode 100644
index 3cf5b4df..00000000
--- a/uniapp/pages/market/clue/index.vue
+++ /dev/null
@@ -1,1749 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- 校区/用户名/手机号/时间范围
-
- 搜索
-
-
-
-
-
-
-
-
-
-
- {{ v.customerResource.name }}
- {{ v.customerResource.phone_number }}
-
-
- 所属校区:{{ v.customerResource.campus_name }}
-
-
- 来源:{{ v.customerResource.source }}
-
-
- 来源渠道:{{ v.customerResource.source_channel }}
-
-
-
-
-
- {{ v.customerResource.order_status || '未开单' }}
-
-
-
-
- 一访{{ v.customerResource.first_visit_status || '未到' }}
-
-
- 二访{{ v.customerResource.second_visit_status || '未到' }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 校区/用户名/手机号/时间范围
-
- 搜索
-
-
-
-
- 批量操作
- 取消
-
- ✓
- 全选
-
-
-
-
- 批量分配 ({{ selectedItems.length }})
-
-
-
-
-
-
-
-
-
-
- ✓
-
-
-
-
-
- {{v.customerResource.name}}
-
-
-
- 决策人:{{v.customerResource.name}} {{v.customerResource.decision_maker}}
-
-
- 分配给:{{v.shared_by_name}}
-
-
-
-
- 分配
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 筛选
-
-
-
-
-
- 校区筛选
-
-
-
-
-
-
-
-
-
- 时间筛选
-
-
-
-
-
-
-
-
- 姓名筛选
-
-
-
-
-
-
-
-
- 电话筛选
-
-
-
-
-
-
-
-
- 搜索
- 关闭
-
-
-
-
-
-
-
-
-
-
-
diff --git a/uniapp/pages/market/data/statistics.vue b/uniapp/pages/market/data/statistics.vue
deleted file mode 100644
index 4767e7b1..00000000
--- a/uniapp/pages/market/data/statistics.vue
+++ /dev/null
@@ -1,343 +0,0 @@
-
-
-
-
-
- 市场数据统计
-
-
-
-
-
- 统计时间:
-
- {{currentDate}}
-
-
-
-
-
-
- 市场人员资源量统计
-
-
-
-
- {{item.name}}
- {{item.weekCount}}
- {{item.monthCount}}
- {{item.yearCount}}
-
-
-
-
-
-
-
- {{currentMonth}}月 - 年度校区人员资源渠道量
-
-
-
-
- {{channel.name}}
-
- {{channel[school.id] || 0}}
-
- {{channel.total}}
-
-
-
-
-
-
-
- {{currentMonth}}月 - 年度市场人员资源渠道统计
-
-
-
-
- {{channel.name}}
-
- {{staff['channel'][channel.value] || 0}}
-
- {{channel.total}}
-
-
-
-
-
-
-
-
-
-
-
diff --git a/uniapp/pages/market/index/index.vue b/uniapp/pages/market/index/index.vue
deleted file mode 100644
index 0b355e81..00000000
--- a/uniapp/pages/market/index/index.vue
+++ /dev/null
@@ -1,427 +0,0 @@
-
-
-
-
-
-
-
- {{currentDate}}
-
-
-
-
-
-
-
- 本月提成
- ¥{{totalCommission}}
-
-
-
-
- 续费提成
-
-
-
-
- {{item.time}}
- {{item.expireCount}}
- {{item.renewCount}}
- {{item.renewRate}}%
- ¥{{item.commission}}
-
-
-
-
-
-
-
- 新招课包
-
-
-
-
- {{newPackageCount}}
- ¥{{newPackageCommission}}
- ¥{{newPackageTotal}}
-
-
-
-
-
-
-
- 私教课包
-
-
-
-
- {{privatePackageCount}}
- ¥{{privatePackageCommission}}
-
-
-
-
-
-
-
- 时间卡
-
-
-
-
- {{timeCardCount}}
- {{timeCardAmount}}
- ¥{{timeCardCommission}}
-
-
-
-
-
-
-
- 其他提成
-
-
-
-
- {{item.project}}
- ¥{{item.amount}}
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/uniapp/pages/market/my/campus_data.vue b/uniapp/pages/market/my/campus_data.vue
deleted file mode 100644
index bba0c6e3..00000000
--- a/uniapp/pages/market/my/campus_data.vue
+++ /dev/null
@@ -1,495 +0,0 @@
-
-
-
-
-
-
-
-
-
- 校区数据
-
-
-
-
-
-
-
- 选择校区:
-
- 请选择校区
-
-
-
-
-
-
-
-
-
-
-
- 部门数量
- --
-
-
-
-
-
-
-
-
- 员工总数
- --
-
-
-
-
-
-
-
-
- 客户总数
- --
-
-
-
-
-
-
-
-
- 校区业绩
- --
-
-
-
-
-
-
- 部门业绩对比
-
-
-
- 销售部
- ¥120000
-
-
-
-
- 80%
-
-
-
-
- 市场部
- ¥100000
-
-
-
-
- 67%
-
-
-
-
- 运营部
- ¥80000
-
-
-
-
- 53%
-
-
-
-
- 客服部
- ¥60000
-
-
-
-
- 40%
-
-
-
-
-
-
- 月度趋势
-
-
-
- 图表功能待开发
-
-
-
-
-
-
- 数据分析
-
-
-
-
-
- 校区对比
-
-
-
-
-
-
- 部门分析
-
-
-
-
-
-
- 趋势分析
-
-
-
-
-
-
- 详细报表
-
-
-
-
-
-
- 功能说明
-
- 这里将显示校区的各项数据统计,包括部门数量、员工总数、客户数量、校区业绩等。
- 具体功能待后续开发实现。
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/uniapp/pages/market/my/dept_data.vue b/uniapp/pages/market/my/dept_data.vue
deleted file mode 100644
index fdda74bc..00000000
--- a/uniapp/pages/market/my/dept_data.vue
+++ /dev/null
@@ -1,445 +0,0 @@
-
-
-
-
-
-
-
-
-
- 部门数据
-
-
-
-
-
-
-
- 选择部门:
-
- 请选择部门
-
-
-
-
-
-
-
-
-
-
-
- 部门人数
- --
-
-
-
-
-
-
-
-
- 总客户数
- --
-
-
-
-
-
-
-
-
- 部门业绩
- --
-
-
-
-
-
-
-
-
- 完成率
- --
-
-
-
-
-
-
- 部门排行榜
-
-
- 1
-
- 张三
- 业绩:¥50000
-
-
-
-
-
-
-
- 2
-
- 李四
- 业绩:¥45000
-
-
-
-
-
-
-
- 3
-
- 王五
- 业绩:¥40000
-
-
-
-
-
-
-
-
-
-
- 数据分析
-
-
-
-
-
- 业绩对比
-
-
-
-
-
-
- 人员分布
-
-
-
-
-
-
- 趋势分析
-
-
-
-
-
-
- 详细报表
-
-
-
-
-
-
- 功能说明
-
- 这里将显示部门的各项数据统计,包括部门人员、客户数量、销售业绩、排行榜等。
- 具体功能待后续开发实现。
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/uniapp/pages/market/my/index.vue b/uniapp/pages/market/my/index.vue
deleted file mode 100644
index b18d5915..00000000
--- a/uniapp/pages/market/my/index.vue
+++ /dev/null
@@ -1,523 +0,0 @@
-
-
-
-
-
- 我的
-
-
-
-
-
-
-
-
- {{userInfo.name}}
-
-
-
-
-
-
-
-
-
- 校区:
- {{v.campus_id_name || ''}}
-
-
-
- 部门:
- {{v.dept_name_str || ''}}
-
-
-
-
-
-
-
-
-
-
-
-
-
- 报销记录
-
-
-
-
-
-
- 我的考勤
-
-
-
-
-
-
- 课程安排
-
-
-
-
-
-
- 我的消息
-
-
-
-
-
-
- 我的合同
-
-
-
-
-
-
- 我的数据
-
-
-
-
-
-
- 部门数据
-
-
-
-
-
-
- 校区数据
-
-
-
-
-
-
- 设置
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/uniapp/pages/market/my/info.vue b/uniapp/pages/market/my/info.vue
deleted file mode 100644
index fefbe9c5..00000000
--- a/uniapp/pages/market/my/info.vue
+++ /dev/null
@@ -1,505 +0,0 @@
-
-
-
-
-
-
-
-
-
- 修改头像
-
-
-
-
-
-
- 姓名 *
-
-
-
-
-
-
-
-
- 账号
-
-
-
-
-
-
-
-
- 部门
-
-
-
- {{formData.department_name_str || '暂无'}}
-
-
-
-
-
- 等级
-
-
-
-
-
-
-
-
-
-
- 性别 *
-
-
-
-
-
-
-
-
-
- 生日 *
-
-
-
-
-
-
-
-
-
- 邮箱 *
-
-
-
-
-
-
-
-
- 手机 *
-
-
-
-
-
-
-
-
- 微信
-
-
-
-
-
-
-
- 提交
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/uniapp/pages/market/my/my_data.vue b/uniapp/pages/market/my/my_data.vue
deleted file mode 100644
index cefe0c5e..00000000
--- a/uniapp/pages/market/my/my_data.vue
+++ /dev/null
@@ -1,292 +0,0 @@
-
-
-
-
-
-
-
-
-
- 我的数据
-
-
-
-
-
-
-
-
-
-
-
-
- 总客户数
- --
-
-
-
-
-
-
-
-
- 已签客户
- --
-
-
-
-
-
-
-
-
- 销售业绩
- --
-
-
-
-
-
-
-
-
- 本月任务
- --
-
-
-
-
-
-
- 数据统计
-
-
-
-
-
- 客户统计
-
-
-
-
-
-
- 业绩统计
-
-
-
-
-
-
- 趋势分析
-
-
-
-
-
-
- 详细报表
-
-
-
-
-
-
- 功能说明
-
- 这里将显示您个人的各项数据统计,包括客户数量、销售业绩、任务完成情况等。
- 具体功能待后续开发实现。
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/uniapp/pages/market/my/set_up.vue b/uniapp/pages/market/my/set_up.vue
deleted file mode 100644
index 9e17258b..00000000
--- a/uniapp/pages/market/my/set_up.vue
+++ /dev/null
@@ -1,105 +0,0 @@
-
-
-
-
- 修改密码
- 用户协议
- 隐私策略
- 清空缓存
-
-
- 退出账号
-
-
-
-
-
-
-
diff --git a/uniapp/pages/market/my/signed_client_list.vue b/uniapp/pages/market/my/signed_client_list.vue
deleted file mode 100644
index d5525f1b..00000000
--- a/uniapp/pages/market/my/signed_client_list.vue
+++ /dev/null
@@ -1,275 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{v.name}}
- 课程截止时间:{{v.end_time}}
-
-
-
-
- {{v.have_study_time}}
- 已上课时
-
-
- {{v.end_study_time ? v.end_study_time:0}}
- 剩余课时
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/uniapp/pages/market/my/update_pass.vue b/uniapp/pages/market/my/update_pass.vue
deleted file mode 100644
index 7092c673..00000000
--- a/uniapp/pages/market/my/update_pass.vue
+++ /dev/null
@@ -1,225 +0,0 @@
-
-
-
-
- 1.验证旧密码
- 2.设置新密码
-
-
-
-
-
- 为保障您的账号安全,修改密码前请填写原密码
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 上一步
-
-
- 下一步
-
- 提交
-
-
-
-
- 忘记原密码
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/uniapp/pages/market/reimbursement/add.vue b/uniapp/pages/market/reimbursement/add.vue
deleted file mode 100644
index 6b330df9..00000000
--- a/uniapp/pages/market/reimbursement/add.vue
+++ /dev/null
@@ -1,272 +0,0 @@
-
-
-
-
-
-
- 报销金额
-
-
-
-
- 报销描述
-
-
-
-
- 发票/收据
-
-
-
- {{ getFileName(form.receipt_url) }}
-
-
-
-
-
-
- 提交
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/uniapp/pages/market/reimbursement/detail.vue b/uniapp/pages/market/reimbursement/detail.vue
deleted file mode 100644
index 62f14af5..00000000
--- a/uniapp/pages/market/reimbursement/detail.vue
+++ /dev/null
@@ -1,136 +0,0 @@
-
-
-
-
-
- 报销金额
- ¥{{ detail.amount }}
-
-
- 报销描述
- {{ detail.description }}
-
-
- 发票/收据
-
-
- {{ detail.receipt_url }}
- 无附件
-
-
-
- 状态
- {{ statusMap[detail.status] || detail.status }}
-
-
- 创建时间
- {{ detail.created_at }}
-
-
- 修改时间
- {{ detail.updated_at }}
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/uniapp/pages/market/reimbursement/list.vue b/uniapp/pages/market/reimbursement/list.vue
deleted file mode 100644
index f5eb4d60..00000000
--- a/uniapp/pages/market/reimbursement/list.vue
+++ /dev/null
@@ -1,144 +0,0 @@
-
-
-
- 暂无报销记录
-
-
- 金额:
- ¥{{ item.amount }}
-
-
- 描述:
- {{ item.description }}
-
-
- 发票/收据:
-
-
- 无附件
-
-
-
- 状态:
- {{ statusMap[item.status] || item.status }}
-
-
- 创建时间:
- {{ item.created_at }}
-
-
-
-
-
-
-
-
\ No newline at end of file
From 2324c324586831269673c4ee3413fde651e60f62 Mon Sep 17 00:00:00 2001
From: zeyan <258785420@qq.com>
Date: Wed, 29 Oct 2025 18:10:51 +0800
Subject: [PATCH 2/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20bug?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../apiController/StudentManager.php | 45 +-
niucloud/app/api/route/route.php | 1 +
.../service/api/apiService/StudentService.php | 27 +-
.../service/api/student/StudentService.php | 1 +
uniapp/api/apiRoute.js | 1614 +----------------
.../client-info-card/client-info-card.vue | 46 +-
uniapp/components/order-list-card/index.vue | 911 ++++++++--
.../order-list-card/qrcode-payment-dialog.vue | 207 +++
uniapp/components/schedule/ScheduleDetail.vue | 274 ++-
.../student-edit-popup.less | 49 +-
.../student-edit-popup/student-edit-popup.vue | 70 +-
.../student-info-card/student-info-card.vue | 24 +-
.../coach/schedule/schedule_table.vue | 62 +-
.../clue/class_arrangement_detail.vue | 1 +
uniapp/pages-market/clue/clue_info.vue | 718 +-------
uniapp/pages-market/clue/edit_clues.vue | 201 +-
16 files changed, 1588 insertions(+), 2663 deletions(-)
create mode 100644 uniapp/components/order-list-card/qrcode-payment-dialog.vue
diff --git a/niucloud/app/api/controller/apiController/StudentManager.php b/niucloud/app/api/controller/apiController/StudentManager.php
index fc983a89..7ddb4c67 100644
--- a/niucloud/app/api/controller/apiController/StudentManager.php
+++ b/niucloud/app/api/controller/apiController/StudentManager.php
@@ -147,4 +147,47 @@ class StudentManager extends BaseApiService
return fail('添加学员失败:' . $e->getMessage());
}
}
-}
\ No newline at end of file
+
+ /**
+ * 获取学员基本信息(员工端)
+ * @param int $id 学员ID
+ * @return \think\Response
+ */
+ public function info($id)
+ {
+ // 验证参数
+ if (empty($id) || !is_numeric($id)) {
+ return fail('学员ID无效');
+ }
+
+ try {
+ // 直接查询学员基本信息,不需要权限验证
+ $student = \think\facade\Db::table('school_student')
+ ->where('id', $id)
+ ->where('deleted_at', 0)
+ ->find();
+
+ if (!$student) {
+ return fail('学员信息不存在');
+ }
+
+ // 返回学员基本信息
+ $studentInfo = [
+ 'id' => $student['id'],
+ 'name' => $student['name'],
+ 'gender' => $student['gender'],
+ 'gender_text' => $student['gender'] == 1 ? '男' : '女',
+ 'birthday' => $student['birthday'],
+ 'campus_id' => $student['campus_id'] ?? null,
+ 'headimg' => $student['headimg'] ? get_image_url($student['headimg']) : '',
+ 'emergency_contact' => $student['emergency_contact'],
+ 'contact_phone' => $student['contact_phone']
+ ];
+
+ return success($studentInfo, '获取学员信息成功');
+
+ } catch (\Exception $e) {
+ return fail('获取学员信息失败:' . $e->getMessage());
+ }
+ }
+}
diff --git a/niucloud/app/api/route/route.php b/niucloud/app/api/route/route.php
index a546e51d..2efb4a03 100644
--- a/niucloud/app/api/route/route.php
+++ b/niucloud/app/api/route/route.php
@@ -277,6 +277,7 @@ Route::group(function () {
Route::post('student/edit', 'apiController.StudentManager/edit');
//销售端-学员-列表
Route::get('student/list', 'apiController.StudentManager/list');
+ Route::get('student/info/:id', 'apiController.StudentManager/info');
//教练端-学员-我的学员列表
Route::get('coach/students/my', 'apiController.CoachStudent/getMyStudents');
diff --git a/niucloud/app/service/api/apiService/StudentService.php b/niucloud/app/service/api/apiService/StudentService.php
index 8efa76a8..9a00827f 100644
--- a/niucloud/app/service/api/apiService/StudentService.php
+++ b/niucloud/app/service/api/apiService/StudentService.php
@@ -64,7 +64,7 @@ class StudentService extends BaseApiService
// 插入数据库
$id = Db::table('school_student')->insertGetId($insertData);
-
+
if ($id) {
$res['code'] = 1;
$res['msg'] = '添加成功';
@@ -115,7 +115,7 @@ class StudentService extends BaseApiService
if (!empty($data['name'])) {
$where[] = ['s.name', 'like', '%' . $data['name'] . '%'];
}
-
+
if (!empty($data['phone'])) {
$where[] = ['s.contact_phone', 'like', '%' . $data['phone'] . '%'];
}
@@ -146,8 +146,7 @@ class StudentService extends BaseApiService
// 查询该学员的课程安排记录,按日期排序获取一访和二访信息
$visitRecords = Db::table('school_person_course_schedule')
->where([
- ['person_id', '=', $student['id']],
- ['person_type', '=', 'student']
+ ['student_id', '=', $student['id']]
])
->order('course_date', 'asc')
->select()
@@ -197,27 +196,27 @@ class StudentService extends BaseApiService
// 如果指定了parent_resource_id,则查询该资源下的学生
if (!empty($data['parent_resource_id'])) {
$resourceId = $data['parent_resource_id'];
-
+
// 验证当前用户是否有权限访问该资源
$resource = Db::table('school_customer_resources')
->where('id', $resourceId)
->where('consultant', $userId)
->where('deleted_at', 0)
->find();
-
+
if (empty($resource)) {
// 用户无权限访问该资源
return [];
}
-
+
// 查询该资源关联的学生ID
$studentIds = Db::table('school_student_courses')
->where('resource_id', $resourceId)
->column('student_id');
-
+
return array_values(array_unique($studentIds));
}
-
+
// 如果没有指定资源ID,则查询当前用户(教练)负责的所有学生
return $this->getCoachStudentIds($userId, $data);
}
@@ -305,13 +304,13 @@ class StudentService extends BaseApiService
if (empty($token)) {
return 0;
}
-
+
// 去掉Bearer前缀
$token = str_replace('Bearer ', '', $token);
-
+
// 使用项目的TokenAuth类解析token,类型为personnel(员工端)
$tokenInfo = \core\util\TokenAuth::parseToken($token, 'personnel');
-
+
if (!empty($tokenInfo)) {
// 从jti中提取用户ID(格式:用户ID_类型)
$jti = $tokenInfo['jti'] ?? '';
@@ -322,7 +321,7 @@ class StudentService extends BaseApiService
}
}
}
-
+
return 0;
} catch (\Exception $e) {
return 0;
@@ -363,4 +362,4 @@ class StudentService extends BaseApiService
return $res;
}
-}
\ No newline at end of file
+}
diff --git a/niucloud/app/service/api/student/StudentService.php b/niucloud/app/service/api/student/StudentService.php
index 105a23a2..3b83f185 100644
--- a/niucloud/app/service/api/student/StudentService.php
+++ b/niucloud/app/service/api/student/StudentService.php
@@ -184,6 +184,7 @@ class StudentService extends BaseService
'contact_phone' => $student['contact_phone'],
'note' => $student['note'],
'headimg' => $student['headimg'] ? get_image_url($student['headimg']) : '',
+ 'campus_id' => $student['campus_id'] ?? null, // 添加校区ID
];
// 处理体测信息
diff --git a/uniapp/api/apiRoute.js b/uniapp/api/apiRoute.js
index 760c75e7..7b098c89 100644
--- a/uniapp/api/apiRoute.js
+++ b/uniapp/api/apiRoute.js
@@ -6,7 +6,6 @@ export default {
//统一登录接口
async unifiedLogin(data = {}) {
const response = await http.post('/login/unified', data)
- console.log('统一登录响应:', response)
return response
},
//教师/销售端详情
@@ -54,206 +53,6 @@ export default {
async resetPassword(data = {}) {
return await http.post('/common/resetPassword', data)
},
-
- // 课程安排列表 - Mock版本
- async getCourseScheduleListMock(data = {}) {
- // 延迟模拟网络请求
- await new Promise(resolve => setTimeout(resolve, 500))
-
- // 模拟课程数据
- const mockCourses = [
- {
- id: 101,
- date: '2025-07-14', // 周一
- time: '09:00',
- courseName: '少儿形体课',
- students: '已报名8人',
- teacher: '张教练',
- teacher_id: 1,
- status: '未点名',
- type: 'normal', // 普通课程
- venue: '舞蹈室A',
- venue_id: 1,
- class_id: 1,
- duration: 1,
- },
- {
- id: 102,
- date: '2025-07-14', // 周一
- time: '14:00',
- courseName: '成人瑜伽',
- students: '已报名12人',
- teacher: '李教练',
- teacher_id: 2,
- status: '已点名',
- type: 'normal', // 普通课程
- venue: '瑜伽B',
- venue_id: 2,
- class_id: 2,
- duration: 1,
- },
- {
- id: 103,
- date: '2025-07-15', // 周二
- time: '10:00',
- courseName: '私教训练',
- students: '已报名1人',
- teacher: '王教练',
- teacher_id: 3,
- status: '未点名',
- type: 'private', // 私教课程
- venue: '健身C',
- venue_id: 3,
- class_id: 3,
- duration: 1,
- },
- {
- id: 104,
- date: '2025-07-15', // 周二
- time: '16:00',
- courseName: '儿童游泳',
- students: '已报名6人',
- teacher: '刘教练',
- teacher_id: 4,
- status: '未点名',
- type: 'normal', // 普通课程
- venue: '泳池D',
- venue_id: 4,
- class_id: 4,
- duration: 1,
- },
- {
- id: 105,
- date: '2025-07-17', // 周四
- time: '14:00',
- courseName: '暑季特训营',
- students: '已报名15人',
- teacher: '赵教练',
- teacher_id: 5,
- status: '未点名',
- type: 'activity', // 活动课程
- venue: '综合场馆E',
- venue_id: 5,
- class_id: 5,
- duration: 2, // 持续2小时
- },
- ]
-
- // 根据筛选条件过滤课程
- let filteredCourses = [...mockCourses]
-
- // 日期范围筛选
- if (data.start_date && data.end_date) {
- filteredCourses = filteredCourses.filter(course => {
- return course.date >= data.start_date && course.date <= data.end_date
- })
- }
-
- // 教练筛选
- if (data.coach_id) {
- const coachIds = Array.isArray(data.coach_id) ? data.coach_id : [data.coach_id]
- filteredCourses = filteredCourses.filter(course => {
- return coachIds.includes(course.teacher_id)
- })
- }
-
- // 场地筛选
- if (data.venue_id) {
- const venueIds = Array.isArray(data.venue_id) ? data.venue_id : [data.venue_id]
- filteredCourses = filteredCourses.filter(course => {
- return venueIds.includes(course.venue_id)
- })
- }
-
- // 班级筛选
- if (data.class_id) {
- const classIds = Array.isArray(data.class_id) ? data.class_id : [data.class_id]
- filteredCourses = filteredCourses.filter(course => {
- return classIds.includes(course.class_id)
- })
- }
-
- // 时间段筛选
- if (data.time_range) {
- switch (data.time_range) {
- case 'morning': // 上午
- filteredCourses = filteredCourses.filter(course => {
- const hour = parseInt(course.time.split(':')[0])
- return hour >= 8 && hour < 12
- })
- break
- case 'afternoon': // 下午
- filteredCourses = filteredCourses.filter(course => {
- const hour = parseInt(course.time.split(':')[0])
- return hour >= 12 && hour < 18
- })
- break
- case 'evening': // 晚上
- filteredCourses = filteredCourses.filter(course => {
- const hour = parseInt(course.time.split(':')[0])
- return hour >= 18 && hour < 22
- })
- break
- }
- }
-
- // 处理结果格式
- const result = {
- list: filteredCourses.map(course => ({
- id: course.id,
- course_date: course.date,
- time_info: {
- start_time: course.time,
- end_time: this.calculateEndTime(course.time, course.duration),
- duration: course.duration * 60,
- },
- course_name: course.courseName,
- enrolled_count: parseInt(course.students.match(/\d+/)[0]) || 0,
- coach_name: course.teacher,
- teacher_id: course.teacher_id,
- status_text: course.status,
- course_type: course.type,
- venue_name: course.venue,
- venue_id: course.venue_id,
- campus_name: this.getCampusName(course.venue_id),
- class_id: course.class_id,
- available_capacity: course.type === 'private' ? 1 : (course.type === 'activity' ? 30 : 15),
- time_slot: `${course.time}-${this.calculateEndTime(course.time, course.duration)}`,
- })),
- total: filteredCourses.length,
- }
-
- return {
- code: 1,
- data: result,
- msg: 'SUCCESS',
- }
- },
-
- // 计算结束时间
- calculateEndTime(startTime, duration) {
- const [hours, minutes] = startTime.split(':').map(Number)
- let endHours = hours + duration
- let endMinutes = minutes
-
- if (endHours >= 24) {
- endHours -= 24
- }
-
- return `${endHours.toString().padStart(2, '0')}:${endMinutes.toString().padStart(2, '0')}`
- },
-
- // 根据场地ID获取校区名称
- getCampusName(venueId) {
- const campusMap = {
- 1: '总部校区',
- 2: '南山校区',
- 3: '福田校区',
- 4: '罗湖校区',
- 5: '宝安校区',
- }
- return campusMap[venueId] || '总部校区'
- },
//公共端-获取全部员工列表
async common_getPersonnelAll(data = {}) {
return await http.get('/personnel/getPersonnelAll', data)
@@ -546,7 +345,6 @@ export default {
//学生登陆接口
async xy_login(data = {}) {
const response = await http.post('/customerResourcesAuth/login', data)
- console.log('学生登录响应:', response)
return response
},
//学生详情
@@ -730,370 +528,101 @@ export default {
//↓↓↓↓↓↓↓↓↓↓↓↓-----课程预约相关接口-----↓↓↓↓↓↓↓↓↓↓↓↓
// 获取可预约课程列表
async getAvailableCourses(data = {}) {
- try {
- // 过滤掉undefined、null、空字符串的参数
- const params = {}
- if (data.date !== undefined && data.date !== null && data.date !== '') {
- params.date = data.date
- }
- if (data.start_date !== undefined && data.start_date !== null && data.start_date !== '') {
- params.start_date = data.start_date
- }
- if (data.end_date !== undefined && data.end_date !== null && data.end_date !== '') {
- params.end_date = data.end_date
- }
- if (data.coach_id !== undefined && data.coach_id !== null && data.coach_id !== '') {
- params.coach_id = data.coach_id
- }
- if (data.venue_id !== undefined && data.venue_id !== null && data.venue_id !== '') {
- params.venue_id = data.venue_id
- }
- if (data.course_type !== undefined && data.course_type !== null && data.course_type !== '') {
- params.course_type = data.course_type
- }
-
- const response = await http.get('/course-booking/available/' + data.student_id, params)
-
- // 检查响应状态,如果失败则降级到Mock数据
- if (response.code !== 1) {
- console.warn('API返回错误,降级到Mock数据:', response.msg)
- return await this.getAvailableCoursesMock(data)
- }
-
- return response
- } catch (error) {
- console.error('获取可预约课程错误:', error)
- // 返回模拟数据作为后备
- return await this.getAvailableCoursesMock(data)
+ // 过滤掉undefined、null、空字符串的参数
+ const params = {}
+ if (data.date !== undefined && data.date !== null && data.date !== '') {
+ params.date = data.date
}
+ if (data.start_date !== undefined && data.start_date !== null && data.start_date !== '') {
+ params.start_date = data.start_date
+ }
+ if (data.end_date !== undefined && data.end_date !== null && data.end_date !== '') {
+ params.end_date = data.end_date
+ }
+ if (data.coach_id !== undefined && data.coach_id !== null && data.coach_id !== '') {
+ params.coach_id = data.coach_id
+ }
+ if (data.venue_id !== undefined && data.venue_id !== null && data.venue_id !== '') {
+ params.venue_id = data.venue_id
+ }
+ if (data.course_type !== undefined && data.course_type !== null && data.course_type !== '') {
+ params.course_type = data.course_type
+ }
+
+ return await http.get('/course-booking/available/' + data.student_id, params)
},
// 创建课程预约
async createBooking(data = {}) {
- try {
- const response = await http.post('/course-booking/create', data)
-
- // 检查响应状态,如果失败则返回模拟成功响应
- if (response.code !== 1) {
- console.warn('创建预约API返回错误,返回模拟成功响应:', response.msg)
- return {
- code: 1,
- msg: '预约成功(模拟)',
- data: { booking_id: Date.now() },
- }
- }
-
- return response
- } catch (error) {
- console.error('创建预约错误:', error)
- // 模拟成功响应
- return {
- code: 1,
- msg: '预约成功(模拟)',
- data: { booking_id: Date.now() },
- }
- }
+ return await http.post('/course-booking/create', data)
},
// 获取我的预约列表
async getMyBookingList(data = {}) {
- try {
- // 过滤掉undefined值,避免传递"undefined"字符串
- const params = {}
- if (data.status !== undefined && data.status !== null && data.status !== '') {
- params.status = data.status
- }
- if (data.start_date !== undefined && data.start_date !== null && data.start_date !== '') {
- params.start_date = data.start_date
- }
- if (data.end_date !== undefined && data.end_date !== null && data.end_date !== '') {
- params.end_date = data.end_date
- }
-
- const response = await http.get('/course-booking/my-list/' + data.student_id, params)
-
- // 检查响应状态,如果失败则降级到Mock数据
- if (response.code !== 1) {
- console.warn('获取预约列表API返回错误,降级到Mock数据:', response.msg)
- return await this.getMyBookingListMock(data)
- }
-
- return response
- } catch (error) {
- console.error('获取预约列表错误:', error)
- // 返回模拟数据作为后备
- return await this.getMyBookingListMock(data)
+ // 过滤掉undefined值,避免传递"undefined"字符串
+ const params = {}
+ if (data.status !== undefined && data.status !== null && data.status !== '') {
+ params.status = data.status
+ }
+ if (data.start_date !== undefined && data.start_date !== null && data.start_date !== '') {
+ params.start_date = data.start_date
}
+ if (data.end_date !== undefined && data.end_date !== null && data.end_date !== '') {
+ params.end_date = data.end_date
+ }
+
+ return await http.get('/course-booking/my-list/' + data.student_id, params)
},
// 取消预约
async cancelBooking(data = {}) {
- try {
- const response = await http.post('/course-booking/cancel', data)
-
- // 检查响应状态,如果失败则返回模拟成功响应
- if (response.code !== 1) {
- console.warn('取消预约API返回错误,返回模拟成功响应:', response.msg)
- return {
- code: 1,
- msg: '取消成功(模拟)',
- }
- }
-
- return response
- } catch (error) {
- console.error('取消预约错误:', error)
- // 模拟成功响应
- return {
- code: 1,
- msg: '取消成功(模拟)',
- }
- }
+ return await http.post('/course-booking/cancel', data)
},
// 获取学员汇总信息
async getStudentSummary(student_id) {
- try {
- return await http.get(`/student/summary/${student_id}`)
- } catch (error) {
- console.error('获取学员汇总信息错误:', error)
- // 返回模拟数据
- return {
- code: 1,
- data: {
- student_id: student_id,
- name: '学员姓名',
- booking_qualification: {
- can_book: false,
- remaining_courses: 0,
- reason: '接口调用失败',
- },
- },
- }
- }
- },
-
- // 模拟可预约课程数据
- async getAvailableCoursesMock(data = {}) {
- await new Promise(resolve => setTimeout(resolve, 500))
-
- const mockCourses = [
- {
- id: 1,
- course_date: data.date || '2025-08-01',
- start_time: '09:00',
- end_time: '10:00',
- duration: 60,
- course_name: '基础体能训练',
- course_type: '基础体能训练',
- coach_name: '张教练',
- venue_name: '训练馆A',
- booking_status: 'available',
- max_students: 8,
- current_students: 3,
- },
- {
- id: 2,
- course_date: data.date || '2025-08-01',
- start_time: '10:30',
- end_time: '11:30',
- duration: 60,
- course_name: '少儿体适能',
- course_type: '少儿体适能',
- coach_name: '李教练',
- venue_name: '训练馆B',
- booking_status: 'available',
- max_students: 6,
- current_students: 2,
- },
- {
- id: 3,
- course_date: data.date || '2025-08-01',
- start_time: '14:00',
- end_time: '15:00',
- duration: 60,
- course_name: '专项训练',
- course_type: '专项训练',
- coach_name: '王教练',
- venue_name: '训练馆A',
- booking_status: 'full',
- max_students: 4,
- current_students: 4,
- },
- ]
-
- return {
- code: 1,
- data: {
- list: mockCourses,
- total: mockCourses.length,
- },
- msg: 'SUCCESS',
- }
- },
-
- // 模拟我的预约列表数据
- async getMyBookingListMock(data = {}) {
- await new Promise(resolve => setTimeout(resolve, 300))
-
- const mockBookings = [
- {
- id: 1,
- booking_date: this.formatDateString(new Date(Date.now() + 24 * 60 * 60 * 1000)),
- start_time: '16:00',
- end_time: '17:00',
- coach_name: '张教练',
- course_type: '基础体能训练',
- venue_name: '训练馆A',
- status: 0,
- status_text: '待上课',
- },
- ]
-
- return {
- code: 1,
- data: {
- list: mockBookings,
- total: mockBookings.length,
- },
- msg: 'SUCCESS',
- }
+ return await http.get(`/student/summary/${student_id}`)
},
//↓↓↓↓↓↓↓↓↓↓↓↓-----课程安排相关接口-----↓↓↓↓↓↓↓↓↓↓↓↓
// 获取课程安排列表(支持学员和教练端)
async getCourseScheduleList(data = {}) {
- try {
- let response
-
- // 如果有student_id参数,说明是学员端调用,使用学员端API
- if (data.student_id) {
- response = await http.get('/course-schedule/list/' + data.student_id, {
- date: data.date,
- status: data.status,
- start_date: data.start_date,
- end_date: data.end_date,
- })
- } else {
- // 否则是教练端调用,使用教练端API
- response = await http.get('/courseSchedule/list', {
- start_date: data.start_date,
- end_date: data.end_date,
- coach_id: data.coach_id,
- venue_id: data.venue_id,
- class_id: data.class_id,
- time_range: data.time_range,
- view_type: data.view_type,
- page: data.page || 1,
- limit: data.limit || 9999,
- })
- }
-
- return response
- } catch (error) {
- console.error('获取课程安排列表错误:', error)
- uni.showModal({
- title: '获取课程安排列表错误',
- content: JSON.stringify(error),
- showCancel: false,
+ let response
+
+ // 如果有student_id参数,说明是学员端调用,使用学员端API
+ if (data.student_id) {
+ response = await http.get('/course-schedule/list/' + data.student_id, {
+ date: data.date,
+ status: data.status,
+ start_date: data.start_date,
+ end_date: data.end_date,
+ })
+ } else {
+ // 否则是教练端调用,使用教练端API
+ response = await http.get('/courseSchedule/list', {
+ start_date: data.start_date,
+ end_date: data.end_date,
+ coach_id: data.coach_id,
+ venue_id: data.venue_id,
+ class_id: data.class_id,
+ time_range: data.time_range,
+ view_type: data.view_type,
+ page: data.page || 1,
+ limit: data.limit || 9999,
})
}
- },
+ return response
+ },
// 申请课程请假
async requestCourseLeave(data = {}) {
- try {
- const response = await http.post('/course-schedule/leave', data)
- return response
- } catch (error) {
- console.error('申请课程请假错误:', error)
- // 模拟请假申请成功
- return {
- code: 1,
- msg: '请假申请已提交',
- }
- }
+ return await http.post('/course-schedule/leave', data)
},
+
// 获取课程安排详情(用于课程调整页面)
async getCourseScheduleInfo(data = {}) {
- try {
- // 使用真实的API接口获取课程安排详情 - 调整页面专用接口
- const result = await http.get('/courseSchedule/info', data)
- console.log('获取课程安排详情:', result)
- return result
- } catch (error) {
- console.error('获取课程安排详情失败:', error)
- // 如果接口调用失败,降级到Mock数据
- return this.getCourseScheduleInfoMock(data)
- }
- },
-
- // 模拟课程安排详情数据
- async getCourseScheduleInfoMock(data = {}) {
- // 模拟数据加载延迟
- await new Promise(resolve => setTimeout(resolve, 500))
-
- // 使用默认学生数据
- const defaultStudents = [
- {
- id: 1,
- name: '张三',
- avatar: '/static/icon-img/avatar.png',
- status: 0,
- status_text: '未点名',
- statusClass: 'status-pending',
- },
- {
- id: 2,
- name: '李四',
- avatar: '/static/icon-img/avatar.png',
- status: 1,
- status_text: '已点名',
- statusClass: 'status-present',
- },
- {
- id: 3,
- name: '王五',
- avatar: '/static/icon-img/avatar.png',
- status: 2,
- status_text: '请假',
- statusClass: 'status-leave',
- },
- ]
-
- // 课程安排模拟数据
- const mockScheduleInfo = {
- id: parseInt(data.schedule_id),
- course_name: '大课7+1类型',
- course_date: '2025-07-25',
- time_slot: '09:00-10:00',
- venue_name: '时间范围教室',
- campus_name: '测试校区',
- coach_name: '老六',
- status: 'pending',
- status_text: '即将开始',
- class_info: {
- id: 1,
- class_name: '少儿形体班',
- },
- course_duration: 60,
- students: defaultStudents,
- course_info: {
- total_hours: 20,
- use_total_hours: 8,
- gift_hours: 2,
- use_gift_hours: 1,
- start_date: '2025-06-01',
- end_date: '2025-12-31',
- },
- }
-
- return {
- code: 1,
- data: mockScheduleInfo,
- msg: 'SUCCESS',
- }
+ return await http.get('/courseSchedule/info', data)
},
// 创建课程安排
async createCourseSchedule(data = {}) {
@@ -1127,77 +656,21 @@ export default {
},
// 检查教练时间冲突
async checkCoachConflict(data = {}) {
- // 未登录或测试模式使用模拟数据
- if (!uni.getStorageSync('token')) {
- return this.checkCoachConflictMock(data)
- }
return await http.get('/courseSchedule/checkCoachConflict', data)
},
- // 模拟教练时间冲突检查
- async checkCoachConflictMock(data = {}) {
- // 模拟数据加载延迟
- await new Promise(resolve => setTimeout(resolve, 300))
-
- // 模拟冲突检查逻辑
- const { coach_id, date, time_slot } = data
-
- // 日期匹配 2025-07-14 或 2025-07-15
- const conflictDates = ['2025-07-14', '2025-07-15']
-
- // 特定教练和时间段的冲突场景
- const hasConflict = (
- // 张教练在特定日期的时间冲突
- (coach_id == 1 && conflictDates.includes(date) && time_slot === '09:00-10:00') ||
- // 李教练在特定日期的时间冲突
- (coach_id == 2 && conflictDates.includes(date) && time_slot === '14:00-15:00') ||
- // 随机生成一些冲突情况进行测试
- (Math.random() < 0.2 && coach_id && date && time_slot)
- )
-
- return {
- code: 1,
- data: {
- has_conflict: hasConflict,
- conflict_schedules: hasConflict ? [
- {
- id: Math.floor(Math.random() * 1000),
- course_name: hasConflict ? '冲突课程' : '',
- time_slot: time_slot,
- venue_name: '测试场地',
- },
- ] : [],
- },
- msg: 'SUCCESS',
- }
- },
// 获取课程安排统计
async getCourseScheduleStatistics(data = {}) {
- try {
- // 如果有student_id参数,使用学员个人统计接口
- if (data.student_id) {
- const response = await http.get('/course-schedule/statistics/' + data.student_id, {
- start_date: data.start_date,
- end_date: data.end_date,
- })
- return response
- } else {
- // 否则使用全局统计接口
- return await http.get('/course-schedule/courseSchedule/statistics', data)
- }
- } catch (error) {
- console.error('获取课程统计失败:', error)
- // 返回默认统计数据
- return {
- code: 1,
- data: {
- total_courses: 0,
- completed_courses: 0,
- scheduled_courses: 0,
- cancelled_courses: 0,
- },
- msg: '获取统计数据成功',
- }
+ // 如果有student_id参数,使用学员个人统计接口
+ if (data.student_id) {
+ const response = await http.get('/course-schedule/statistics/' + data.student_id, {
+ start_date: data.start_date,
+ end_date: data.end_date,
+ })
+ return response
+ } else {
+ // 否则使用全局统计接口
+ return await http.get('/course-schedule/courseSchedule/statistics', data)
}
},
// 获取筛选选项
@@ -1280,378 +753,54 @@ export default {
// 移除学员(统一接口)
async removeStudent(data = {}) {
- try {
- const response = await http.post('/course/removeStudentFromSchedule', data)
- return response
- } catch (error) {
- console.error('移除学员失败:', error)
- // 返回模拟成功响应
- return {
- code: 1,
- msg: '移除学员成功(模拟)',
- data: {}
- }
- }
+ return await http.post('/course/removeStudentFromSchedule', data)
},
// 恢复学员(统一接口)
async restoreStudent(data = {}) {
- try {
- const response = await http.post('/course/restoreStudent', data)
- return response
- } catch (error) {
- console.error('恢复学员失败:', error)
- // 返回模拟成功响应
- return {
- code: 1,
- msg: '恢复学员成功(模拟)',
- data: {}
- }
- }
+ return await http.post('/course/restoreStudent', data)
},
//↓↓↓↓↓↓↓↓↓↓↓↓-----统一课程安排详情管理接口(与admin端保持一致)-----↓↓↓↓↓↓↓↓↓↓↓↓
// 获取课程安排详情(新统一接口 - 对接admin端)
async getCourseArrangementDetail(data = {}) {
- try {
- const response = await http.get('/course/scheduleDetail', data)
- return response
- } catch (error) {
- console.error('获取课程安排详情失败:', error)
- // 降级到 Mock 数据
- return await this.getCourseArrangementDetailMock(data)
- }
+ return await http.get('/course/scheduleDetail', data)
},
// 搜索学员(新统一接口 - 对接admin端)
async searchStudentsForArrangement(data = {}) {
- try {
- const response = await http.get('/course/searchStudents', data)
- return response
- } catch (error) {
- console.error('搜索学员失败:', error)
- // 降级到 Mock 数据
- return await this.searchStudentsForArrangementMock(data)
- }
+ return await http.get('/course/searchStudents', data)
},
// 添加学员到课程安排(新统一接口 - 对接admin端)
async addStudentToArrangement(data = {}) {
- try {
- const response = await http.post('/course/addStudentToSchedule', data)
- return response
- } catch (error) {
- console.error('添加学员失败:', error)
- // 返回模拟成功响应
- return {
- code: 1,
- msg: '添加学员成功(模拟)',
- data: { id: Date.now() }
- }
- }
+ return await http.post('/course/addStudentToSchedule', data)
},
// 移除学员(新统一接口 - 对接admin端)
async removeStudentFromArrangement(data = {}) {
- try {
- const response = await http.post('/course/removeStudentFromSchedule', data)
- return response
- } catch (error) {
- console.error('移除学员失败:', error)
- // 返回模拟成功响应
- return {
- code: 1,
- msg: '移除学员成功(模拟)',
- data: {}
- }
- }
+ return await http.post('/course/removeStudentFromSchedule', data)
},
// 升级学员(新统一接口 - 对接admin端)
async upgradeStudentInArrangement(data = {}) {
- try {
- const response = await http.post('/course/upgradeStudent', data)
- return response
- } catch (error) {
- console.error('升级学员失败:', error)
- // 返回模拟成功响应
- return {
- code: 1,
- msg: '升级学员成功(模拟)',
- data: {}
- }
- }
+ return await http.post('/course/upgradeStudent', data)
},
// 更新学员状态(新统一接口 - 对接admin端)
async updateStudentStatusInArrangement(data = {}) {
- try {
- const response = await http.post('/courseSchedule/updateStudentStatus', data)
- return response
- } catch (error) {
- console.error('更新学员状态失败:', error)
- // 返回模拟成功响应
- return {
- code: 1,
- msg: '更新状态成功(模拟)',
- data: {}
- }
- }
+ return await http.post('/courseSchedule/updateStudentStatus', data)
},
// 删除学员所有未来课程安排
async deleteStudentFutureSchedules(data = {}) {
- try {
- const response = await http.post('/courseSchedule/deleteStudentFutureSchedules', data)
- return response
- } catch (error) {
- console.error('删除学员未来课程安排失败:', error)
- // 返回模拟成功响应
- return {
- code: 1,
- msg: '删除成功(模拟)',
- data: { deleted_count: 0 }
- }
- }
+ return await http.post('/courseSchedule/deleteStudentFutureSchedules', data)
},
// 恢复学员(新统一接口 - 对接admin端)
async restoreStudentInArrangement(data = {}) {
- try {
- const response = await http.post('/course/restoreStudent', data)
- return response
- } catch (error) {
- console.error('恢复学员失败:', error)
- // 返回模拟成功响应
- return {
- code: 1,
- msg: '恢复学员成功(模拟)',
- data: {}
- }
- }
- },
-
- //↓↓↓↓↓↓↓↓↓↓↓↓-----新统一课程安排Mock数据(与admin端保持一致)-----↓↓↓↓↓↓↓↓↓↓↓↓
-
- // 模拟课程安排详情数据(对应admin端格式)
- async getCourseArrangementDetailMock(data = {}) {
- await new Promise(resolve => setTimeout(resolve, 500))
-
- const mockStudents = [
- {
- id: 1,
- person_id: 1,
- student_id: 1,
- name: '张小明',
- phone: '13800138001',
- age: 8,
- person_type: 'student',
- person_type_text: '正式学员',
- schedule_type: 1,
- status: 0,
- course_progress: {
- used: 5,
- total: 20,
- percentage: 25
- }
- },
- {
- id: 2,
- person_id: 2,
- resources_id: 2,
- name: '李小红',
- phone: '13800138002',
- age: 7,
- person_type: 'customer_resource',
- person_type_text: '潜在客户',
- schedule_type: 2,
- status: 0,
- course_progress: {
- used: 0,
- total: 1,
- percentage: 0
- }
- }
- ]
-
- return {
- code: 1,
- data: {
- schedule_info: {
- id: parseInt(data.schedule_id) || 1,
- course_name: '少儿体适能课程',
- course_date: '2025-08-16',
- time_slot: '09:00-10:00',
- venue_name: '训练馆A',
- campus_name: '总部校区',
- coach_name: '张教练',
- status: 'upcoming',
- status_text: '即将开始'
- },
- formal_students: mockStudents.filter(s => s.schedule_type === 1),
- waiting_students: mockStudents.filter(s => s.schedule_type === 2),
- formal_empty_seats: [2, 3, 4, 5],
- waiting_empty_seats: [2, 3]
- },
- msg: 'SUCCESS'
- }
- },
-
- // 模拟搜索学员数据(对应admin端格式)
- async searchStudentsForArrangementMock(data = {}) {
- await new Promise(resolve => setTimeout(resolve, 300))
-
- const mockResults = [
- {
- id: 101,
- person_id: 101,
- student_id: 101,
- name: '王小华',
- phone: '13800138101',
- age: 9,
- person_type: 'student',
- person_type_text: '正式学员'
- },
- {
- id: 102,
- person_id: 102,
- resources_id: 102,
- name: '赵小美',
- phone: '13800138102',
- age: 6,
- person_type: 'customer_resource',
- person_type_text: '潜在客户'
- }
- ]
-
- // 根据关键词过滤
- let filteredResults = mockResults
- if (data.keyword) {
- filteredResults = mockResults.filter(student =>
- student.name.includes(data.keyword) || student.phone.includes(data.keyword)
- )
- }
-
- return {
- code: 1,
- data: {
- list: filteredResults,
- total: filteredResults.length
- },
- msg: 'SUCCESS'
- }
- },
-
- //↓↓↓↓↓↓↓↓↓↓↓↓-----统一课程安排Mock数据-----↓↓↓↓↓↓↓↓↓↓↓↓
-
- // 模拟课程安排详情数据
- async getScheduleDetailMock(data = {}) {
- await new Promise(resolve => setTimeout(resolve, 500))
-
- const mockStudents = [
- {
- id: 1,
- person_id: 1,
- student_id: 1,
- name: '张小明',
- phone: '13800138001',
- age: 8,
- person_type: 'student',
- person_type_text: '正式学员',
- schedule_type: 1,
- status: 0,
- course_progress: {
- used: 5,
- total: 20,
- percentage: 25
- }
- },
- {
- id: 2,
- person_id: 2,
- resources_id: 2,
- name: '李小红',
- phone: '13800138002',
- age: 7,
- person_type: 'customer_resource',
- person_type_text: '潜在客户',
- schedule_type: 2,
- status: 0,
- course_progress: {
- used: 0,
- total: 1,
- percentage: 0
- }
- }
- ]
-
- return {
- code: 1,
- data: {
- schedule_info: {
- id: parseInt(data.schedule_id) || 1,
- course_name: '少儿体适能课程',
- course_date: '2025-08-16',
- time_slot: '09:00-10:00',
- venue_name: '训练馆A',
- campus_name: '总部校区',
- coach_name: '张教练',
- status: 'upcoming',
- status_text: '即将开始'
- },
- formal_students: mockStudents.filter(s => s.schedule_type === 1),
- waiting_students: mockStudents.filter(s => s.schedule_type === 2),
- formal_empty_seats: [2, 3, 4, 5],
- waiting_empty_seats: [2, 3]
- },
- msg: 'SUCCESS'
- }
- },
-
- // 模拟搜索学员数据
- async searchStudentsMock(data = {}) {
- await new Promise(resolve => setTimeout(resolve, 300))
-
- const mockResults = [
- {
- id: 101,
- person_id: 101,
- student_id: 101,
- name: '王小华',
- phone: '13800138101',
- age: 9,
- person_type: 'student',
- person_type_text: '正式学员'
- },
- {
- id: 102,
- person_id: 102,
- resources_id: 102,
- name: '赵小美',
- phone: '13800138102',
- age: 6,
- person_type: 'customer_resource',
- person_type_text: '潜在客户'
- }
- ]
-
- // 根据关键词过滤
- let filteredResults = mockResults
- if (data.keyword) {
- filteredResults = mockResults.filter(student =>
- student.name.includes(data.keyword) || student.phone.includes(data.keyword)
- )
- }
-
- return {
- code: 1,
- data: {
- list: filteredResults,
- total: filteredResults.length
- },
- msg: 'SUCCESS'
- }
+ return await http.post('/course/restoreStudent', data)
},
//↓↓↓↓↓↓↓↓↓↓↓↓-----学员出勤管理相关接口-----↓↓↓↓↓↓↓↓↓↓↓↓
@@ -1768,12 +917,9 @@ export default {
return await http.get('/student/mychild')
},
- // 获取学员基本信息
+ // 获取学员基本信息(员工端)
async getStudentBasicInfo(data = {}) {
- const params = {
- student_id: data.student_id,
- }
- return await http.get('/student/student-info', params)
+ return await http.get(`/student/info/${data.student_id}`)
},
//↓↓↓↓↓↓↓↓↓↓↓↓-----员工端合同管理相关接口-----↓↓↓↓↓↓↓↓↓↓↓↓
@@ -1820,7 +966,7 @@ export default {
async getContractByOrder(data = {}) {
return await http.get('/contract/getByOrder', {
order_id: data.order_id,
- student_id: data.student_id
+ student_id: data.student_id,
})
},
@@ -1828,8 +974,7 @@ export default {
// 获取知识文章列表
async getKnowledgeList(data = {}) {
- try {
- const params = {
+ const params = {
category: data.category,
page: data.page || 1,
limit: data.limit || 10,
@@ -1837,110 +982,35 @@ export default {
}
const response = await http.get(`/knowledge-test/list/${data.student_id}`, params)
return response
- } catch (error) {
- console.error('获取知识文章列表错误:', error)
- // 返回模拟数据作为后备
- return await this.getKnowledgeListMock(data)
- }
},
// 获取知识分类列表
async getKnowledgeCategories(data = {}) {
- try {
- const response = await http.get('/knowledge-test/categories')
- return response
- } catch (error) {
- console.error('获取知识分类错误:', error)
- // 返回模拟数据作为后备
- return await this.getKnowledgeCategoriesMock()
- }
- },
-
- // 获取推荐文章
- async getRecommendArticles(data = {}) {
- try {
- const params = {
- limit: data.limit || 5,
- }
- const response = await http.get(`/knowledge-test/recommend/${data.student_id}`, params)
+ const response = await http.get('/knowledge-test/categories')
return response
- } catch (error) {
- console.error('获取推荐文章错误:', error)
- // 返回模拟数据作为后备
- return await this.getRecommendArticlesMock(data)
- }
},
// 获取文章详情
async getKnowledgeDetail(data = {}) {
- try {
- const params = {
+ const params = {
student_id: data.student_id,
}
const response = await http.get(`/knowledge-test/detail/${data.id}`, params)
return response
- } catch (error) {
- console.error('获取文章详情错误:', error)
- // 返回模拟数据作为后备
- return await this.getKnowledgeDetailMock(data)
- }
},
// 标记文章已读
async markArticleRead(data = {}) {
- try {
- const response = await http.post('/knowledge-test/mark-read', {
+ const response = await http.post('/knowledge-test/mark-read', {
article_id: data.article_id,
student_id: data.student_id,
})
return response
- } catch (error) {
- console.error('标记文章已读错误:', error)
- // 返回模拟成功响应
- return {
- code: 1,
- msg: '标记已读成功',
- data: { message: '标记已读成功' },
- }
- }
- },
-
- // 收藏/取消收藏文章
- async toggleArticleFavorite(data = {}) {
- try {
- const response = await http.post('/knowledge-test/toggle-favorite', {
- article_id: data.article_id,
- student_id: data.student_id,
- action: data.action,
- })
- return response
- } catch (error) {
- console.error('收藏操作错误:', error)
- // 返回模拟成功响应
- return {
- code: 1,
- msg: data.action === 'add' ? '收藏成功' : '取消收藏成功',
- data: { is_favorite: data.action === 'add' },
- }
- }
- },
-
- // 获取知识库统计
- async getKnowledgeStats(data = {}) {
- try {
- const response = await http.get(`/knowledge-test/stats/${data.student_id}`)
- return response
- } catch (error) {
- console.error('获取知识库统计错误:', error)
- // 返回模拟数据作为后备
- return await this.getKnowledgeStatsMock(data)
- }
},
// 搜索知识文章
async searchKnowledgeArticles(data = {}) {
- try {
- const params = {
+ const params = {
keyword: data.keyword,
category: data.category,
page: data.page || 1,
@@ -1948,225 +1018,20 @@ export default {
}
const response = await http.get(`/knowledge-test/search/${data.student_id}`, params)
return response
- } catch (error) {
- console.error('搜索知识文章错误:', error)
- // 返回模拟数据作为后备
- return await this.searchKnowledgeArticlesMock(data)
- }
},
- //↓↓↓↓↓↓↓↓↓↓↓↓-----知识库Mock数据-----↓↓↓↓↓↓↓↓↓↓↓↓
-
- // 模拟知识文章列表数据
- async getKnowledgeListMock(data = {}) {
- await new Promise(resolve => setTimeout(resolve, 500))
-
- const mockArticles = [
- {
- id: 1,
- title: '少儿体适能训练基础知识',
- image: '/static/knowledge/article1.jpg',
- content: '体适能是指人体所具备的有充足的精力从事日常工作而不易疲劳,同时有余力享受休闲活动的乐趣,能够应付突发状况的身体适应能力。',
- table_type: '2',
- category_name: '跳绳教案库',
- type: 1,
- url: '',
- status: 1,
- create_time: 1627804800,
- update_time: 1627804800,
- user_permission: '',
- is_read: false,
- is_favorite: false,
- },
- {
- id: 2,
- title: '儿童运动安全防护指南',
- image: '/static/knowledge/article2.jpg',
- content: '儿童参与运动时的安全防护措施是确保运动效果和避免运动伤害的重要保障。本文详细介绍了各种运动项目的安全注意事项。',
- table_type: '7',
- category_name: '少儿安防教案库',
- type: 1,
- url: '',
- status: 1,
- create_time: 1627804700,
- update_time: 1627804700,
- user_permission: '',
- is_read: true,
- is_favorite: true,
- },
- {
- id: 3,
- title: '篮球基础技巧训练方法',
- image: '/static/knowledge/article3.jpg',
- content: '篮球作为一项受欢迎的运动项目,需要掌握正确的基础技巧。本教案介绍了运球、投篮、传球等基本技能的训练方法。',
- table_type: '4',
- category_name: '篮球教案库',
- type: 1,
- url: '',
- status: 1,
- create_time: 1627804600,
- update_time: 1627804600,
- user_permission: '',
- is_read: false,
- is_favorite: false,
- },
- ]
-
- // 根据分类筛选
- let filteredArticles = mockArticles
- if (data.category) {
- filteredArticles = mockArticles.filter(article => article.table_type === data.category)
- }
- // 根据关键词搜索
- if (data.keyword) {
- filteredArticles = filteredArticles.filter(article =>
- article.title.includes(data.keyword) || article.content.includes(data.keyword),
- )
- }
-
- return {
- code: 1,
- data: {
- list: filteredArticles,
- current_page: data.page || 1,
- last_page: 1,
- total: filteredArticles.length,
- per_page: data.limit || 10,
- },
- msg: '获取知识文章列表成功',
- }
- },
- // 模拟知识分类数据
- async getKnowledgeCategoriesMock() {
- await new Promise(resolve => setTimeout(resolve, 300))
-
- return {
- code: 1,
- data: [
- { value: '1', text: '课程教学大纲', icon: '📖', count: 8 },
- { value: '2', text: '跳绳教案库', icon: '🏃', count: 15 },
- { value: '3', text: '增高教案库', icon: '📏', count: 6 },
- { value: '4', text: '篮球教案库', icon: '🏀', count: 12 },
- { value: '5', text: '强化教案库', icon: '💪', count: 9 },
- { value: '6', text: '空中忍者教案库', icon: '🥷', count: 7 },
- { value: '7', text: '少儿安防教案库', icon: '🛡️', count: 5 },
- { value: '8', text: '体能教案库', icon: '🏋️', count: 11 },
- ],
- msg: '获取知识分类成功',
- }
- },
- // 模拟推荐文章数据
- async getRecommendArticlesMock(data = {}) {
- await new Promise(resolve => setTimeout(resolve, 400))
-
- const mockRecommendArticles = [
- {
- id: 1,
- title: '少儿体适能训练基础知识',
- image: '/static/knowledge/article1.jpg',
- summary: '体适能是指人体所具备的有充足的精力从事日常工作而不易疲劳,同时有余力享受休闲活动的乐趣...',
- category_name: '跳绳教案库',
- create_time: 1627804800,
- read_count: 156,
- },
- {
- id: 2,
- title: '儿童运动安全防护指南',
- image: '/static/knowledge/article2.jpg',
- summary: '儿童参与运动时的安全防护措施是确保运动效果和避免运动伤害的重要保障...',
- category_name: '少儿安防教案库',
- create_time: 1627804700,
- read_count: 89,
- },
- ]
-
- return {
- code: 1,
- data: mockRecommendArticles.slice(0, data.limit || 5),
- msg: '获取推荐文章成功',
- }
- },
- // 模拟文章详情数据
- async getKnowledgeDetailMock(data = {}) {
- await new Promise(resolve => setTimeout(resolve, 600))
-
- return {
- code: 1,
- data: {
- id: data.id,
- title: '少儿体适能训练基础知识',
- image: '/static/knowledge/article1.jpg',
- content: `
- 什么是体适能?
- 体适能是指人体所具备的有充足的精力从事日常工作而不易疲劳,同时有余力享受休闲活动的乐趣,能够应付突发状况的身体适应能力。
-
- 少儿体适能的重要性
- 1. 促进身体发育:通过科学的运动训练,可以促进儿童骨骼、肌肉的健康发育。
- 2. 提高运动能力:培养儿童的协调性、平衡性、柔韧性等基本运动能力。
- 3. 增强体质:提高儿童的心肺功能,增强免疫力。
-
- 训练原则
- • 循序渐进:从简单到复杂,从易到难
- • 因材施教:根据儿童的年龄特点和个体差异制定训练计划
- • 寓教于乐:将训练内容游戏化,提高儿童参与的积极性
- `,
- table_type: '2',
- category_name: '跳绳教案库',
- type: 1,
- url: '',
- status: 1,
- create_time: 1627804800,
- update_time: 1627804800,
- user_permission: '',
- exam_papers_id: 0,
- is_read: false,
- is_favorite: false,
- },
- msg: '获取文章详情成功',
- }
- },
- // 模拟知识库统计数据
- async getKnowledgeStatsMock(data = {}) {
- await new Promise(resolve => setTimeout(resolve, 300))
-
- return {
- code: 1,
- data: {
- total_articles: 45,
- favorites: 8,
- read_articles: 23,
- categories_count: {
- '1': 8,
- '2': 15,
- '3': 6,
- '4': 12,
- '5': 9,
- '6': 7,
- '7': 5,
- '8': 11,
- },
- },
- msg: '获取知识库统计成功',
- }
- },
- // 模拟搜索知识文章数据
- async searchKnowledgeArticlesMock(data = {}) {
- // 复用知识文章列表的Mock数据,根据关键词进行筛选
- return await this.getKnowledgeListMock(data)
- },
//↓↓↓↓↓↓↓↓↓↓↓↓-----学员端消息管理相关接口-----↓↓↓↓↓↓↓↓↓↓↓↓
// 获取学员消息列表
async getStudentMessageList(data = {}) {
- try {
- const params = {
+ const params = {
message_type: data.message_type,
page: data.page || 1,
limit: data.limit || 10,
@@ -2175,83 +1040,29 @@ export default {
}
const response = await http.get(`/message/list/${data.student_id}`, params)
return response
- } catch (error) {
- console.error('获取学员消息列表错误:', error)
- // 返回模拟数据作为后备
- return await this.getStudentMessageListMock(data)
- }
},
// 获取消息详情
async getStudentMessageDetail(data = {}) {
- try {
- const params = {
+ const params = {
student_id: data.student_id,
}
const response = await http.get(`/message/detail/${data.message_id}`, params)
return response
- } catch (error) {
- console.error('获取消息详情错误:', error)
- // 返回模拟数据作为后备
- return await this.getStudentMessageDetailMock(data)
- }
},
// 标记消息已读
async markStudentMessageRead(data = {}) {
- try {
- const response = await http.post('/message/mark-read', {
+ const response = await http.post('/message/mark-read', {
message_id: data.message_id,
student_id: data.student_id,
})
return response
- } catch (error) {
- console.error('标记消息已读错误:', error)
- // 返回模拟成功响应
- return {
- code: 1,
- msg: '标记已读成功',
- data: { message: '标记已读成功' },
- }
- }
- },
-
- // 批量标记消息已读
- async markStudentMessageBatchRead(data = {}) {
- try {
- const response = await http.post('/message/mark-batch-read', {
- student_id: data.student_id,
- message_ids: data.message_ids,
- message_type: data.message_type,
- })
- return response
- } catch (error) {
- console.error('批量标记已读错误:', error)
- // 返回模拟成功响应
- return {
- code: 1,
- msg: '批量标记成功',
- data: { message: '批量标记成功', updated_count: data.message_ids?.length || 0 },
- }
- }
- },
-
- // 获取学员消息统计
- async getStudentMessageStats(data = {}) {
- try {
- const response = await http.get(`/message/stats/${data.student_id}`)
- return response
- } catch (error) {
- console.error('获取消息统计错误:', error)
- // 返回模拟数据作为后备
- return await this.getStudentMessageStatsMock(data)
- }
},
// 获取对话中的所有消息
async getConversationMessages(data = {}) {
- try {
- const params = {
+ const params = {
student_id: data.student_id,
from_type: data.from_type,
from_id: data.from_id,
@@ -2260,245 +1071,10 @@ export default {
}
const response = await http.get('/message/conversation', params)
return response
- } catch (error) {
- console.error('获取对话消息错误:', error)
- // 返回空对话作为后备
- return {
- code: 1,
- data: {
- list: [],
- current_page: 1,
- last_page: 1,
- total: 0,
- per_page: 20,
- has_more: false,
- },
- msg: 'SUCCESS',
- }
- }
- },
-
- // 学员回复消息
- async replyMessage(data = {}) {
- try {
- const response = await http.post('/message/reply', {
- student_id: data.student_id,
- to_type: data.to_type,
- to_id: data.to_id,
- content: data.content,
- message_type: data.message_type || 'text',
- title: data.title || '',
- })
- return response
- } catch (error) {
- console.error('回复消息错误:', error)
- // 返回模拟成功响应
- return {
- code: 1,
- msg: '回复发送成功',
- data: {
- message: '回复发送成功',
- data: {
- id: Date.now(),
- content: data.content,
- created_at: new Date().toISOString().replace('T', ' ').slice(0, 19),
- create_time: Math.floor(Date.now() / 1000),
- from_name: '我',
- is_sent_by_student: true,
- },
- },
- }
- }
- },
-
- // 搜索学员消息
- async searchStudentMessages(data = {}) {
- try {
- const params = {
- keyword: data.keyword,
- message_type: data.message_type,
- page: data.page || 1,
- limit: data.limit || 10,
- }
- const response = await http.get(`/message/search/${data.student_id}`, params)
- return response
- } catch (error) {
- console.error('搜索消息错误:', error)
- // 返回模拟数据作为后备
- return await this.searchStudentMessagesMock(data)
- }
},
- //↓↓↓↓↓↓↓↓↓↓↓↓-----学员端消息管理Mock数据-----↓↓↓↓↓↓↓↓↓↓↓↓
-
- // 模拟学员消息列表数据
- async getStudentMessageListMock(data = {}) {
- await new Promise(resolve => setTimeout(resolve, 500))
-
- const mockMessages = [
- {
- id: 1,
- from_type: 'system',
- from_id: 0,
- message_type: 'system',
- title: '欢迎使用学员端',
- content: '欢迎使用学员端,您可以在这里查看课程安排、作业任务等信息。',
- business_id: null,
- business_type: '',
- is_read: 0,
- read_time: null,
- create_time: Math.floor(Date.now() / 1000) - 3600,
- type_text: '系统消息',
- from_name: '系统',
- summary: '欢迎使用学员端,您可以在这里查看课程安排、作业任务等信息。',
- },
- {
- id: 2,
- from_type: 'personnel',
- from_id: 1,
- message_type: 'homework',
- title: '新作业任务',
- content: '您有一项新的作业任务:完成本周的体能训练计划,请按时提交。',
- business_id: 1,
- business_type: 'homework',
- is_read: 0,
- read_time: null,
- create_time: Math.floor(Date.now() / 1000) - 1800,
- type_text: '作业任务',
- from_name: '教务老师',
- summary: '您有一项新的作业任务:完成本周的体能训练计划,请按时提交。',
- },
- {
- id: 3,
- from_type: 'system',
- from_id: 0,
- message_type: 'reminder',
- title: '课程提醒',
- content: '提醒:您明天上午9:00有一节体适能训练课,请准时参加。',
- business_id: 1,
- business_type: 'course',
- is_read: 1,
- read_time: new Date(Date.now() - 900 * 1000).toISOString(),
- create_time: Math.floor(Date.now() / 1000) - 7200,
- type_text: '课程提醒',
- from_name: '系统',
- summary: '提醒:您明天上午9:00有一节体适能训练课,请准时参加。',
- },
- {
- id: 4,
- from_type: 'personnel',
- from_id: 2,
- message_type: 'notification',
- title: '重要通知',
- content: '本周六将举行家长开放日活动,欢迎家长朋友们前来参观指导。',
- business_id: null,
- business_type: '',
- is_read: 0,
- read_time: null,
- create_time: Math.floor(Date.now() / 1000) - 86400,
- type_text: '通知公告',
- from_name: '教务老师',
- summary: '本周六将举行家长开放日活动,欢迎家长朋友们前来参观指导。',
- },
- {
- id: 5,
- from_type: 'system',
- from_id: 0,
- message_type: 'feedback',
- title: '课程评价邀请',
- content: '您上次参加的体适能训练课已结束,请对本次课程进行评价。',
- business_id: 2,
- business_type: 'course',
- is_read: 1,
- read_time: new Date(Date.now() - 3600 * 1000).toISOString(),
- create_time: Math.floor(Date.now() / 1000) - 172800,
- type_text: '反馈评价',
- from_name: '系统',
- summary: '您上次参加的体适能训练课已结束,请对本次课程进行评价。',
- },
- ]
-
- // 根据消息类型筛选
- let filteredMessages = mockMessages
- if (data.message_type && data.message_type !== 'all') {
- filteredMessages = mockMessages.filter(msg => msg.message_type === data.message_type)
- }
- // 根据已读状态筛选
- if (data.is_read !== '' && data.is_read !== undefined) {
- filteredMessages = filteredMessages.filter(msg => msg.is_read == data.is_read)
- }
- // 根据关键词搜索
- if (data.keyword) {
- filteredMessages = filteredMessages.filter(msg =>
- msg.title.includes(data.keyword) || msg.content.includes(data.keyword),
- )
- }
- return {
- code: 1,
- data: {
- list: filteredMessages,
- current_page: data.page || 1,
- last_page: 1,
- total: filteredMessages.length,
- per_page: data.limit || 10,
- has_more: false,
- },
- msg: '获取消息列表成功',
- }
- },
-
- // 模拟消息详情数据
- async getStudentMessageDetailMock(data = {}) {
- await new Promise(resolve => setTimeout(resolve, 300))
-
- return {
- code: 1,
- data: {
- id: data.message_id,
- from_type: 'system',
- from_id: 0,
- message_type: 'system',
- title: '欢迎使用学员端',
- content: '欢迎使用学员端,您可以在这里查看课程安排、作业任务等信息。如有任何问题,请随时联系我们的客服团队。',
- business_id: null,
- business_type: '',
- is_read: 0,
- read_time: null,
- create_time: Math.floor(Date.now() / 1000) - 3600,
- type_text: '系统消息',
- from_name: '系统',
- },
- msg: '获取消息详情成功',
- }
- },
- // 模拟消息统计数据
- async getStudentMessageStatsMock(data = {}) {
- await new Promise(resolve => setTimeout(resolve, 300))
-
- return {
- code: 1,
- data: {
- total_messages: 12,
- unread_messages: 5,
- read_messages: 7,
- type_counts: {
- 'system': 3,
- 'notification': 2,
- 'homework': 3,
- 'feedback': 2,
- 'reminder': 2,
- },
- },
- msg: '获取消息统计成功',
- }
- },
- // 模拟搜索消息数据
- async searchStudentMessagesMock(data = {}) {
- // 复用消息列表的Mock数据,根据关键词进行筛选
- return await this.getStudentMessageListMock(data)
- },
}
diff --git a/uniapp/components/client-info-card/client-info-card.vue b/uniapp/components/client-info-card/client-info-card.vue
index 5c5fe555..cf0356b1 100644
--- a/uniapp/components/client-info-card/client-info-card.vue
+++ b/uniapp/components/client-info-card/client-info-card.vue
@@ -22,7 +22,7 @@