Просмотр исходного кода

Signed-off-by: 李妹妹 <1639016684@qq.com>

李妹妹 1 день назад
Родитель
Сommit
d18acc9b95
73 измененных файлов с 8123 добавлено и 2737 удалено
  1. 2 1
      .hbuilderx/launch.json
  2. 0 41
      api-js/airClassroom.js
  3. 0 22
      api-js/medicationSurvey.js
  4. 0 24
      api-js/points.js
  5. 0 27
      api-js/questionnaire.js
  6. 0 17
      api-js/serviceOrder.js
  7. 4 0
      api/account.js
  8. 60 0
      api/airClassroom.js
  9. 19 4
      api/bankCard.js
  10. 11 1
      api/certification.js
  11. 37 1
      api/common.js
  12. 12 5
      api/index.js
  13. 28 0
      api/login.js
  14. 26 0
      api/medicationSurvey.js
  15. 24 0
      api/onlineLecture.js
  16. 10 1
      api/password.js
  17. 34 0
      api/points.js
  18. 46 0
      api/questionnaire.js
  19. 10 0
      api/serviceAgreement.js
  20. 32 0
      api/serviceOrder.js
  21. 19 0
      api/statistics.js
  22. 1 1
      api/user.js
  23. 11 1
      api/withdraw.js
  24. 3 9
      common/request.js
  25. 2 2
      manifest.json
  26. 24 4
      pages.json
  27. 186 101
      pages/auth/login.vue
  28. 4 17
      pages/common/launch.vue
  29. 107 211
      pages/home/index.vue
  30. 17 9
      pages/task/index.vue
  31. 30 21
      pages/user/index.vue
  32. 47 14
      pages_echarts/statistics.vue
  33. 2 2
      pages_live/card.vue
  34. 38 87
      pages_live/lesson.vue
  35. 20 55
      pages_live/lessonDetail.vue
  36. 45 101
      pages_live/search.vue
  37. 7 1
      pages_task/activityDetail.vue
  38. 907 159
      pages_task/caseCollection.vue
  39. 395 72
      pages_task/completeTask.vue
  40. 962 0
      pages_task/formConfig.js
  41. 2 2
      pages_task/index.vue
  42. 981 0
      pages_task/json.json
  43. 196 134
      pages_task/longVideo.vue
  44. 163 279
      pages_task/medicationSurvey.vue
  45. 2 2
      pages_task/onlineLecture.vue
  46. 275 194
      pages_task/questionnaire.vue
  47. 877 158
      pages_task/questionnaireForm.vue
  48. 161 134
      pages_task/science.vue
  49. 801 0
      pages_task/shortVideo.vue
  50. 15 119
      pages_task/taskCompleteSuccess.vue
  51. 188 74
      pages_task/taskDetail.vue
  52. 80 71
      pages_user/addBankCard.vue
  53. 15 6
      pages_user/bankCard.vue
  54. 287 128
      pages_user/certification.vue
  55. 2 2
      pages_user/certificationExample.vue
  56. 7 1
      pages_user/certificationInfo.vue
  57. 88 49
      pages_user/editBankCard.vue
  58. 90 57
      pages_user/forgetPassword.vue
  59. 201 0
      pages_user/personInfo.vue
  60. 140 70
      pages_user/points.vue
  61. 3 3
      pages_user/practiceCertificateExample.vue
  62. 23 4
      pages_user/serviceAgreement.vue
  63. 7 1
      pages_user/serviceAgreementDetail.vue
  64. 123 51
      pages_user/serviceOrder.vue
  65. 155 54
      pages_user/serviceOrderDetail.vue
  66. 23 23
      pages_user/withdraw.vue
  67. 36 110
      pages_user/withdrawSuccess.vue
  68. BIN
      static/image/icon_article.png
  69. BIN
      static/image/icon_back_w.png
  70. BIN
      static/image/icon_task_longvideo.png
  71. BIN
      static/image/icon_task_shortvideo.png
  72. BIN
      static/image/img_blank_nodata.png
  73. BIN
      static/logo.jpg

+ 2 - 1
.hbuilderx/launch.json

@@ -16,7 +16,8 @@
             "type" : "uniCloud"
         },
         {
-            "playground" : "standard",
+            "customPlaygroundType" : "device",
+            "playground" : "custom",
             "type" : "uni-app:app-android"
         }
     ]

+ 0 - 41
api-js/airClassroom.js

@@ -1,41 +0,0 @@
-import Request from '../common/request.js';
-let request = new Request().http
-
-// 获取空中课堂任务列表
-export function getAirClassroomList(data) {
-	return request('/store/app/airClassroom/getList', data, 'GET');
-}
-
-// 获取任务详情
-export function getTaskDetail(data) {
-	return request('/store/app/airClassroom/getTaskDetail', data, 'GET');
-}
-
-// 提交任务
-export function submitTask(data) {
-	return request('/store/app/airClassroom/submitTask', data, 'POST', 'application/json;charset=UTF-8');
-}
-
-// 获取项目分组选项
-export function getGroupOptions() {
-	return request('/store/app/airClassroom/getGroupOptions', null, 'GET');
-}
-
-// 获取项目标签选项
-export function getTagOptions() {
-	return request('/store/app/airClassroom/getTagOptions', null, 'GET');
-}
-
-// 上传文件
-export function uploadFile(data) {
-	return request('/store/app/airClassroom/uploadFile', data, 'POST', 'application/json;charset=UTF-8');
-}
-
-
-
-
-
-
-
-
-

+ 0 - 22
api-js/medicationSurvey.js

@@ -1,22 +0,0 @@
-import Request from '../common/request.js';
-let request = new Request().http
-
-// 获取用药调研列表
-export function getMedicationSurveyList(data) {
-	return request('/store/app/medicationSurvey/getList', data, 'GET');
-}
-
-// 获取活动详情
-export function getActivityDetail(data) {
-	return request('/store/app/medicationSurvey/getActivityDetail', data, 'GET');
-}
-
-// 提交病例征集
-export function submitCaseCollection(data) {
-	return request('/store/app/medicationSurvey/submitCase', data, 'POST', 'application/json;charset=UTF-8');
-}
-
-// 获取病例列表
-export function getCaseList(data) {
-	return request('/store/app/medicationSurvey/getCaseList', data, 'GET');
-}

+ 0 - 24
api-js/points.js

@@ -1,24 +0,0 @@
-import Request from '../common/request.js';
-let request = new Request().http
-
-// 获取积分信息
-export function getPointsInfo() {
-	return request('/store/app/points/getInfo', null, 'GET');
-}
-
-// 获取积分列表
-export function getPointsList(data) {
-	return request('/store/app/points/getList', data, 'GET');
-}
-
-// 获取积分明细
-export function getPointsDetail(data) {
-	return request('/store/app/points/getDetail', data, 'GET');
-}
-
-// 获取积分汇总信息(包含余额和待入账)
-export function getPointsSummary() {
-	return request('/store/app/points/getSummary', null, 'GET');
-}
-
-

+ 0 - 27
api-js/questionnaire.js

@@ -1,27 +0,0 @@
-import Request from '../common/request.js';
-let request = new Request().http
-
-// 获取问卷调查列表
-export function getQuestionnaireList(data) {
-	return request('/store/app/questionnaire/getList', data, 'GET');
-}
-
-// 获取问卷调查详情
-export function getQuestionnaireDetail(data) {
-	return request('/store/app/questionnaire/getDetail', data, 'GET');
-}
-
-// 提交问卷调查
-export function submitQuestionnaire(data) {
-	return request('/store/app/questionnaire/submit', data, 'POST', 'application/json;charset=UTF-8');
-}
-
-
-
-
-
-
-
-
-
-

+ 0 - 17
api-js/serviceOrder.js

@@ -1,17 +0,0 @@
-import Request from '../common/request.js';
-let request = new Request().http
-
-// 获取服务单列表
-export function getServiceOrderList(data) {
-	return request('/store/app/serviceOrder/getList', data, 'GET');
-}
-
-// 获取服务单详情
-export function getServiceOrderDetail(data) {
-	return request('/store/app/serviceOrder/getDetail', data, 'GET');
-}
-
-// 确认服务单
-export function confirmServiceOrder(data) {
-	return request('/store/app/serviceOrder/confirm', data, 'POST', 'application/json;charset=UTF-8');
-}

+ 4 - 0
api-js/account.js → api/account.js

@@ -30,3 +30,7 @@ export function sendVerifyCode(data) {
 
 
 
+
+
+
+

+ 60 - 0
api/airClassroom.js

@@ -0,0 +1,60 @@
+import Request from '../common/request.js';
+let request = new Request().http
+
+// 获取空中课堂任务列表
+export function getAirClassroomList(data) {
+	return request('/app/task/getTaskList', data, 'GET');
+}
+
+// 获取任务详情
+export function getTaskDetail(data) {
+	return request('/app/task/getTaskInfo/'+ data, data, 'GET');
+}
+
+// 提交任务
+export function submitTask(data) {
+	return request('/app/task/completeTask', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 获取项目分组选项
+export function getGroupOptions(data) {
+	return request('/app/task/getProjectList', data, 'GET');
+}
+
+// 获取项目标签选项
+export function getTagOptions(data) {
+	return request('/app/common/getTaskTypeData', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 上传文件
+export function uploadFile(data) {
+	return request('/store/app/airClassroom/uploadFile', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 获取任务状态列表
+export function getTaskStatusList() {
+	return request('/store/app/airClassroom/getTaskStatusList', null, 'GET');
+}
+
+// 获取任务类型列表
+export function getTaskTypeList() {
+	return request('/app/common/getTaskTypeData', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 保存任务草稿
+export function saveTaskDraft(data) {
+	return request('/store/app/airClassroom/saveTaskDraft', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 19 - 4
api-js/bankCard.js → api/bankCard.js

@@ -2,8 +2,8 @@ import Request from '../common/request.js';
 let request = new Request().http
 
 // 获取银行卡信息
-export function getBankCardInfo() {
-	return request('/store/app/bankCard/getInfo', null, 'GET');
+export function getBankCardInfo(data) {
+	return request('/app/dockerInfo/getDockerBankInfo', data,'POST', 'application/json;charset=UTF-8');
 }
 
 // 获取银行卡详情
@@ -12,8 +12,8 @@ export function getBankCardDetail(data) {
 }
 
 // 添加银行卡
-export function addBankCard1(data) {
-	return request('/store/app/bankCard/add', data, 'POST', 'application/json;charset=UTF-8');
+export function addBankCard(data) {
+	return request('/app/dockerInfo/addDockerBankInfo', data, 'POST', 'application/json;charset=UTF-8');
 }
 
 // 更新银行卡
@@ -35,3 +35,18 @@ export function getBankList() {
 export function getBranchList(data) {
 	return request('/store/app/bankCard/getBranchList', data, 'GET');
 }
+
+// 获取银行卡列表
+export function getBankCardList() {
+	return request('/store/app/bankCard/getList', null, 'GET');
+}
+
+// 设置默认银行卡
+export function setDefaultBankCard(data) {
+	return request('/store/app/bankCard/setDefault', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 验证银行卡号
+export function validateBankCard(data) {
+	return request('/store/app/bankCard/validate', data, 'POST', 'application/json;charset=UTF-8');
+}

+ 11 - 1
api-js/certification.js → api/certification.js

@@ -3,7 +3,7 @@ let request = new Request().http
 
 // 提交认证
 export function submitCertification(data) {
-	return request('/store/app/certification/submit', data, 'POST', 'application/json;charset=UTF-8');
+	return request('/app/dockerInfo/launchSpeakerAuth', data, 'POST', 'application/json;charset=UTF-8');
 }
 
 // 获取认证信息
@@ -30,3 +30,13 @@ export function getTitleList() {
 export function getBankList() {
 	return request('/store/app/certification/getBankList', null, 'GET');
 }
+
+// 获取认证状态
+export function getCertificationStatus() {
+	return request('/store/app/certification/getStatus', null, 'GET');
+}
+
+// 上传认证图片
+export function uploadCertificationImage(data) {
+	return request('/store/app/certification/uploadImage', data, 'POST', 'application/json;charset=UTF-8');
+}

+ 37 - 1
api/common.js

@@ -32,4 +32,40 @@ let request = new Request().http
   	 return request('/store/app/common/getDictByKey',data,'GET');
  } 
  
- 
+ // 获取任务类型列表
+ export function getTaskTypeList(data) {
+ 	return request('/app/common/getTaskTypeData', data, 'POST', 'application/json;charset=UTF-8');
+ }
+//删除
+export function deleteFile(id) {
+ 	return request('/app/upload/' + id, null, 'DELETE');
+} 
+//批量删除
+export function deleteBatch(array) {
+ 	return request('/app/upload/batch', array, 'DELETE', 'application/json;charset=UTF-8');
+} 
+//秒传检查
+export function checkFast(data) {
+ 	return request('/app/upload/check-fast', data, 'GET');
+} 
+//上传完成回调
+export function complete(data) {
+	return request('/app/upload/complete', data, 'POST', 'application/json;charset=UTF-8');
+}
+//查询文件列表
+export function fileList(data) {
+ 	return request('/app/upload/list', data, 'GET');
+} 
+//获取COS临时密钥
+export function stsToken(data) {
+ 	return request('/app/upload/sts-token', data, 'GET');
+}
+//获取微信云开发access_token
+export function getAccessToken(data) {
+ 	return request('/app/upload/access-token', data, 'GET');
+}
+
+//获取policy 签名
+export function postPolicy(data) {
+ 	return request('/app/upload/post-policy', data, 'GET');
+}

+ 12 - 5
api/index.js

@@ -59,8 +59,15 @@ export function getCartCount() {
  export function getChineseMedicineById(data) {
  	 return request('/store/app/index/getChineseMedicineById',data,'GET');
  }
- 
- 
-
- 
- 
+ // 空中课堂
+ export function getClassroomList(data) {
+ 	return request('/app/index/getClassroomList', data, 'POST', 'application/json;charset=UTF-8');
+ }
+// 空中课堂详情
+ export function getClassroomDetail(data) {
+ 	return request('/app/index/getClassroomDetail/'+data, 'GET');
+ }
+ //轮播图
+ export function getIndexBannerList(data) {
+ 	 return request('/app/common/getIndexBannerList',data,'POST');
+ }

+ 28 - 0
api/login.js

@@ -0,0 +1,28 @@
+import Request from '../common/request.js';
+let request = new Request().http
+
+// 验证码登录
+export function loginByCode(data) {
+	return request('/app/dockerInfo/login', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 密码登录
+export function loginByPassword(data) {
+	return request('/app/dockerInfo/login', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 发送登录验证码
+export function sendLoginVerifyCode(data) {
+	return request('/app/dockerInfo/sendSmsCode', data, 'POST');
+}
+
+// 微信小程序登录
+export function loginByMiniApp(data) {
+	return request('/store/app/wx/loginByMiniApp', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 微信公众号登录
+export function loginByMp(data) {
+	return request('/store/app/wx/loginByMp', data, 'POST', 'application/json;charset=UTF-8');
+}
+

+ 26 - 0
api/medicationSurvey.js

@@ -0,0 +1,26 @@
+import Request from '../common/request.js';
+let request = new Request().http
+
+// 获取用药调研列表
+export function getMedicationSurveyList(data) {
+	return request('/app/drugResearch/getDrugResearchList',data, 'POST', 'application/json;charset=UTF-8');
+}
+// 提交病例征集
+export function submitCaseCollection(data) {
+	return request('/app/drugResearch/insertDrugResearch', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 获取病例详情
+export function getCaseDetail(data) {
+	return request('/app/drugResearch/getDrugResearchDetail', data, 'POST');
+}
+
+// 获取调研状态列表
+export function getSurveyStatusList() {
+	return request('/store/app/medicationSurvey/getStatusList', null, 'GET');
+}
+
+// 获取调研类型列表
+export function getSurveyTypeList() {
+	return request('/store/app/medicationSurvey/getTypeList', null, 'GET');
+}

+ 24 - 0
api-js/onlineLecture.js → api/onlineLecture.js

@@ -26,6 +26,30 @@ export function continueBroadcast(data) {
 	return request('/store/app/onlineLecture/continueBroadcast', data, 'POST', 'application/json;charset=UTF-8');
 }
 
+// 获取讲座详情
+export function getLectureDetail(data) {
+	return request('/store/app/onlineLecture/getDetail', data, 'GET');
+}
+
+// 结束直播
+export function endBroadcast(data) {
+	return request('/store/app/onlineLecture/endBroadcast', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 获取直播状态
+export function getBroadcastStatus(data) {
+	return request('/store/app/onlineLecture/getBroadcastStatus', data, 'GET');
+}
+
+// 获取讲座状态列表
+export function getLectureStatusList() {
+	return request('/store/app/onlineLecture/getStatusList', null, 'GET');
+}
+
+
+
+
+
 
 
 

+ 10 - 1
api-js/password.js → api/password.js

@@ -13,9 +13,18 @@ export function changePassword(data) {
 
 // 重置密码
 export function resetPassword(data) {
-	return request('/store/app/password/reset', data, 'POST', 'application/json;charset=UTF-8');
+	return request('/app/dockerInfo/resetPassword', data, 'POST', 'application/json;charset=UTF-8');
 }
 
+// 发送修改密码验证码
+export function sendPasswordVerifyCode(data) {
+	return request('/app/dockerInfo/sendSmsCode', data, 'POST');
+}
+
+
+
+
+
 
 
 

+ 34 - 0
api/points.js

@@ -0,0 +1,34 @@
+import Request from '../common/request.js';
+let request = new Request().http
+
+// 获取积分信息
+export function getPointsInfo(data) {
+	return request('/app/dockerInfo/getCreditInfo', data,  'POST', 'application/json;charset=UTF-8');
+}
+
+// 获取积分列表
+export function getPointsList(data) {
+	return request('/app/dockerInfo/getCreditHistoryData', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 获取积分明细
+export function getPointsDetail(data) {
+	return request('/store/app/points/getDetail', data, 'GET');
+}
+
+// 获取积分汇总信息(包含余额和待入账)
+export function getPointsSummary() {
+	return request('/store/app/points/getSummary', null, 'GET');
+}
+
+// 获取积分类型选项
+export function getPointsTypeOptions(data) {
+	return request('/app/common/getTaskTypeData',data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 获取积分收入/支出统计
+export function getPointsStatistics(data) {
+	return request('/store/app/points/getStatistics', data, 'GET');
+}
+
+

+ 46 - 0
api/questionnaire.js

@@ -0,0 +1,46 @@
+import Request from '../common/request.js';
+let request = new Request().http
+
+// 获取问卷调查列表
+export function getQuestionnaireList(data) {
+	return request('/app/drugResearch/getSurveyTaskList',  data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 获取问卷调查详情
+export function getQuestionnaireDetail(data) {
+	return request('/app/drugResearch/getSurveyTaskDetailById', data, 'POST');
+}
+
+// 提交问卷调查
+export function submitQuestionnaire(data) {
+	return request('/app/drugResearch/insertDrugResearch', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 获取问卷期号
+export function getPeriodData() {
+	return request('/app/drugResearch/getPeriodData', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 获取我的问卷列表
+export function getMyQuestionnaireList(data) {
+	return request('/store/app/questionnaire/getMyList', data, 'GET');
+}
+
+// 保存问卷草稿
+export function saveQuestionnaireDraft(data) {
+	return request('/store/app/questionnaire/saveDraft', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 10 - 0
api-js/serviceAgreement.js → api/serviceAgreement.js

@@ -10,3 +10,13 @@ export function getServiceAgreementList() {
 export function getServiceAgreementDetail(data) {
 	return request('/store/app/serviceAgreement/getDetail', data, 'GET');
 }
+
+// 同意服务协议
+export function agreeServiceAgreement(data) {
+	return request('/store/app/serviceAgreement/agree', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 获取协议类型列表
+export function getAgreementTypeList() {
+	return request('/store/app/serviceAgreement/getTypeList', null, 'GET');
+}

+ 32 - 0
api/serviceOrder.js

@@ -0,0 +1,32 @@
+import Request from '../common/request.js';
+let request = new Request().http
+
+// 获取服务单列表
+export function getServiceOrderList(data) {
+	return request('/app/serviceInfo/getServiceTicketList', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 获取服务单详情
+export function getServiceOrderDetail(data) {
+	return request('/app/serviceInfo/getServiceTask', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 确认服务单
+export function confirmServiceOrder(data) {
+	return request('/app/serviceInfo/confirmServiceTicket', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 获取服务单状态列表
+export function getServiceOrderStatusList() {
+	return request('/store/app/serviceOrder/getStatusList', null, 'GET');
+}
+
+// 申请服务单
+export function applyServiceOrder(data) {
+	return request('/store/app/serviceOrder/apply', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 取消服务单
+export function cancelServiceOrder(data) {
+	return request('/store/app/serviceOrder/cancel', data, 'POST', 'application/json;charset=UTF-8');
+}

+ 19 - 0
api-js/statistics.js → api/statistics.js

@@ -16,6 +16,25 @@ export function exportStatistics(data) {
 	return request('/store/app/statistics/export', data, 'GET');
 }
 
+// 获取统计数据汇总
+export function getStatisticsSummary(data) {
+	return request('/store/app/statistics/getSummary', data, 'GET');
+}
+
+// 获取任务类型统计
+export function getTaskTypeStatistics(data) {
+	return request('/store/app/statistics/getTaskTypeStatistics', data, 'GET');
+}
+
+// 获取任务状态统计
+export function getTaskStatusStatistics(data) {
+	return request('/store/app/statistics/getTaskStatusStatistics', data, 'GET');
+}
+
+
+
+
+
 
 
 

+ 1 - 1
api/user.js

@@ -8,7 +8,7 @@ let request = new Request().http
  	 return request('/store/app/wx/loginByMp',data,'POST','application/json;charset=UTF-8');
  }
  export function getUserInfo() {
- 	 return request('/store/app/user/getUserInfo',null,'GET');
+ 	 return request('/app/dockerInfo/getDockerInfo',null,'GET');
  }
  
  export function editUser(data) {

+ 11 - 1
api-js/withdraw.js → api/withdraw.js

@@ -3,7 +3,7 @@ let request = new Request().http
 
 // 提交提现申请
 export function submitWithdraw(data) {
-	return request('/store/app/withdraw/submit', data, 'POST', 'application/json;charset=UTF-8');
+	return request('/app/dockerInfo/launchCreditWithdraw', data, 'POST', 'application/json;charset=UTF-8');
 }
 
 // 获取提现信息(可提现金额等)
@@ -20,3 +20,13 @@ export function getWithdrawList(data) {
 export function getWithdrawDetail(data) {
 	return request('/store/app/withdraw/getDetail', data, 'GET');
 }
+
+// 取消提现申请
+export function cancelWithdraw(data) {
+	return request('/store/app/withdraw/cancel', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 获取提现状态列表
+export function getWithdrawStatusList() {
+	return request('/store/app/withdraw/getStatusList', null, 'GET');
+}

+ 3 - 9
common/request.js

@@ -4,17 +4,11 @@ export default class Request {
 		let that = this;
 		// let path = 'http://e767647f.natappfree.cc';
 		// let path = 'https://user.test.ylrztop.com/api'; //测试
-		let path = 'https://api.homemdt.net'; //正式
+		//let path = 'http://132.232.83.221:8113'; //正式
+		let path = 'https://doctor.his.ifeiyu100.com'; //正式
+		//let path='http://d8632984.natappfree.cc'
 		// let path = "https://api.qinggetai.com"
 	    // console.log(router,'router')
-		//用户模块
-		if(router.indexOf("/store/app") != -1 || router.indexOf("/app") != -1||  router.indexOf("/recharge-templates") != -1) {
-			path ='https://api.homemdt.net/user';
-		}
-		//企业
-		if(router.indexOf("/companyapp") != -1 ) {
-			path ='https://api.homemdt.net';
-		}
 		uni.setStorageSync('requestPath',path)
 		// uni.showLoading({
 		// 	title: '加载中'

+ 2 - 2
manifest.json

@@ -1,5 +1,5 @@
 {
-    "name" : "壹柒玖康养集团",
+    "name" : "研究型互联网医院",
     "appid" : "__UNI__DBD2079",
     "description" : "",
     "versionName" : "1.0.0",
@@ -50,7 +50,7 @@
     "quickapp" : {},
     /* 小程序特有相关 */
     "mp-weixin" : {
-        "appid" : "wxd56333375d59f1b8",
+        "appid" : "wxf2e7f8be5e31bf31",
         "lazyCodeLoading" : "requiredComponents",
         "setting" : {
             "urlCheck" : false,

+ 24 - 4
pages.json

@@ -97,10 +97,20 @@
 				    }
 				},
 				{
-				    "path" : "airClassroom",
+				    "path" : "longVideo",
 				    "style" :                                                                                    
 				    {
-				        "navigationBarTitleText": "空中课堂",
+				        "navigationBarTitleText": "长视频创作",
+						"app-plus": {
+							"titleNView": false
+						}
+				    }
+				},
+				{
+				    "path" : "shortVideo",
+				    "style" :                                                                                    
+				    {
+				        "navigationBarTitleText": "短视频创作",
 						"app-plus": {
 							"titleNView": false
 						}
@@ -111,6 +121,7 @@
 				    "style" :                                                                                    
 				    {
 				        "navigationBarTitleText": "任务详情",
+						"navigationStyle": "custom",
 						"app-plus": {
 							"titleNView": false
 						}
@@ -180,7 +191,7 @@
 				    "path" : "caseCollection",
 				    "style" :                                                                                    
 				    {
-				        "navigationBarTitleText": "病例征集",
+				        "navigationBarTitleText": "问卷调查",
 						"navigationStyle": "custom",
 						"app-plus": {
 							"titleNView": false
@@ -216,6 +227,15 @@
 		{
 			"root": "pages_user",
 			"pages": [
+				{
+					"path" : "personInfo",
+					"style" :                                                                                    
+					{
+						"navigationBarTitleText": "个人信息",
+						"enablePullDownRefresh": false
+					}
+					
+				},
 				{
 					"path" : "points",
 					"style" :                                                                                    
@@ -238,7 +258,7 @@
 					"path" : "withdrawSuccess",
 					"style" :                                                                                    
 					{
-						"navigationBarTitleText": "完成任务",
+						"navigationBarTitleText": "提现成功",
 						"enablePullDownRefresh": false
 					}
 					

+ 186 - 101
pages/auth/login.vue

@@ -1,17 +1,17 @@
 <template>
   <view class="container">
     <!-- #ifdef MP-WEIXIN -->
-	<image class="bg" src="@/static/image/bg_login.svg" mode="widthFix"></image>
+	<image class="bg" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/bg_login.png" mode="widthFix"></image>
     <view class="force-login-wrap">
 		<view :style="{height:menuButtonInfo.height,marginTop:menuButtonInfo.top}" class="backImg" >
-			<image @tap="goBack()" src="@/static/images/back.png"></image>
+			<image @tap="goBack()" src="@/static/image/back.png"></image>
 		</view>
 		<view class="top-title">
 			<view class="title-text">登录</view>
 			<view class="login-notice">仅限特定人群使用,登录后可体验更多功能</view>
 		</view>
       <view class="force-login__content">
-		  <image class="bg-type" :src="current==0?'/static/image/bg_tab_login.svg':'/static/image/bg_tab_login2.svg'" mode="widthFix"></image>
+		  <image class="bg-type" :src="current==0?'https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/bg_tab_login.png':'https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/bg_tab_login2.png'" mode="widthFix"></image>
 		<view class="logintype">
 			<view :class="current==0 ? 'logintype-item active':'logintype-item'" @click="changeType(0)">验证码登录</view>
 			<view :class="current==1 ? 'logintype-item active':'logintype-item'" @click="changeType(1)">密码登录</view>
@@ -32,7 +32,7 @@
 					v-if="current == 0"
 					class="input-field code-input" 
 					type="number" 
-					v-model="verifyCode" 
+					v-model="code" 
 					placeholder="请输入验证码" 
 					maxlength="6"
 				/>
@@ -69,7 +69,8 @@
 </template>
 
 <script>
-import { loginByMiniApp,getUserInfo,loginByMp } from '@/api/user'
+import { loginByMiniApp, getUserInfo, loginByMp } from '@/api/user'
+import { loginByCode, loginByPassword, sendLoginVerifyCode } from '@/api/login'
 export default {
 	data() {
 		return {
@@ -78,18 +79,25 @@ export default {
 			current:0, // 0-验证码登录 1-密码登录
 			menuButtonInfo:{},
 			phone:'', // 手机号
-			verifyCode:'', // 验证码
+			code:'', // 验证码
 			password:'', // 密码
 			codeText:'获取验证码', // 验证码按钮文字
 			countdown:0, // 倒计时
 			countdownTimer:null, // 倒计时定时器
-			showPassword:true // 是否显示密码
+			showPassword:true ,// 是否显示密码
+			companyUserId:null,
+			companyId:null
 		}
 	},
 	computed: {
 	},
 	onLoad(option) {
+		console.log(option)
 		this.getMenuButtonInfo()
+		if(option.scene){
+			this.companyUserId=option.scene.companyUserId
+			this.companyId==option.scene.companyId
+		}
 		// #ifdef MP-WEIXIN
 		uni.$on('refreshLogin', () => {
 			uni.navigateBack({
@@ -97,19 +105,7 @@ export default {
 			})
 		})
 		//选获取CODE,防止后请求的时候腾讯服务端未同步报错
-		this.getCode();
-		// #endif
-		
-		// #ifdef H5
-		if (this.checkWeixin()) {
-			this.getWxCode()
-		} else {
-			uni.showToast({
-				icon:'none',
-				title: "请在微信中打开",
-			});
-			//跳转到手机号密码登录
-		}
+		//this.getCode();
 		// #endif
 	 
 	},
@@ -147,7 +143,7 @@ export default {
 			if(index == 0) {
 				this.password = '';
 			} else {
-				this.verifyCode = '';
+				this.code = '';
 			}
 		},
 		// 返回主页
@@ -157,7 +153,7 @@ export default {
 			})
 		},
 		// 获取验证码
-		getVerifyCode() {
+		async getVerifyCode() {
 			if(this.countdown > 0) {
 				return;
 			}
@@ -175,30 +171,44 @@ export default {
 				});
 				return;
 			}
-			// TODO: 调用发送验证码API
-			// 这里需要对接真实的发送验证码接口
-			uni.showLoading({
-				title:"发送中..."
-			});
-			// 模拟发送验证码
-			setTimeout(() => {
+			try {
+				uni.showLoading({
+					title:"发送中..."
+				});
+				const res = await sendLoginVerifyCode({ phone: this.phone })
 				uni.hideLoading();
+				
+				if(res.code === 200) {
+					uni.showToast({
+						icon:'success',
+						title: "验证码已发送",
+					});
+					// 开始倒计时
+					this.countdown = 60;
+					this.codeText = this.countdown + '秒重新获取';
+					this.countdownTimer = setInterval(() => {
+						this.countdown--;
+						this.codeText = this.countdown + '秒重新获取';
+						if(this.countdown <= 0) {
+							clearInterval(this.countdownTimer);
+							this.countdownTimer = null;
+							this.codeText = '获取验证码';
+						}
+					}, 1000);
+				} else {
+					uni.showToast({
+						icon:'none',
+						title: res.msg || "发送验证码失败",
+					});
+				}
+			} catch (e) {
+				uni.hideLoading();
+				console.error('发送验证码失败', e);
 				uni.showToast({
-					icon:'success',
-					title: "验证码已发送",
+					icon:'none',
+					title: "发送验证码失败",
 				});
-				// 开始倒计时
-				this.countdown = 60;
-				this.countdownTimer = setInterval(() => {
-					this.countdown--;
-					this.codeText = this.countdown + '秒重新获取';
-					if(this.countdown <= 0) {
-						clearInterval(this.countdownTimer);
-						this.countdownTimer = null;
-						this.codeText = '获取验证码';
-					}
-				}, 1000);
-			}, 1000);
+			}
 		},
 		// 登录
 		handleLogin() {
@@ -209,77 +219,152 @@ export default {
 				});
 				return;
 			}
-			uni.navigateBack({
-				delta:1
-			})
-			// if(!this.phone) {
-			// 	uni.showToast({
-			// 		icon:'none',
-			// 		title: "请输入手机号",
-			// 	});
-			// 	return;
-			// }
-			// if(!/^1[3-9]\d{9}$/.test(this.phone)) {
-			// 	uni.showToast({
-			// 		icon:'none',
-			// 		title: "请输入正确的手机号",
-			// 	});
-			// 	return;
-			// }
+			if(!this.phone) {
+				uni.showToast({
+					icon:'none',
+					title: "请输入手机号",
+				});
+				return;
+			}
+			if(!/^1[3-9]\d{9}$/.test(this.phone)) {
+				uni.showToast({
+					icon:'none',
+					title: "请输入正确的手机号",
+				});
+				return;
+			}
 			
-			// if(this.current == 0) {
-			// 	// 验证码登录
-			// 	if(!this.verifyCode) {
-			// 		uni.showToast({
-			// 			icon:'none',
-			// 			title: "请输入验证码",
-			// 		});
-			// 		return;
-			// 	}
-			// 	// TODO: 调用验证码登录API
-			// 	this.loginByCode();
-			// } else {
-			// 	// 密码登录
-			// 	if(!this.password) {
-			// 		uni.showToast({
-			// 			icon:'none',
-			// 			title: "请输入密码",
-			// 		});
-			// 		return;
-			// 	}
-			// 	// TODO: 调用密码登录API
-			// 	this.loginByPassword();
-			// }
+			if(this.current == 0) {
+				// 验证码登录
+				if(!this.code) {
+					uni.showToast({
+						icon:'none',
+						title: "请输入验证码",
+					});
+					return;
+				}
+				this.loginByCode();
+			} else {
+				// 密码登录
+				if(!this.password) {
+					uni.showToast({
+						icon:'none',
+						title: "请输入密码",
+					});
+					return;
+				}
+				this.loginByPassword();
+			}
 		},
 		// 验证码登录
-		loginByCode() {
-			uni.showLoading({
-				title:"登录中..."
-			});
-			// TODO: 调用验证码登录接口
-			// 示例:loginByCode({ phone: this.phone, code: this.verifyCode })
-			setTimeout(() => {
+		async loginByCode() {
+			try {
+				uni.showLoading({
+					title:"登录中..."
+				});
+				const info={
+					phone: this.phone,
+					code: this.code,
+					loginType:2,
+				}
+				if(this.companyId && this.companyUserId){
+					info.companyId=this.companyId,
+					inof.companyUserId=this.companyUserId
+				}
+				const res = await loginByCode(info);
 				uni.hideLoading();
+				if(res.code === 200) {
+					// 保存token和用户信息
+					if(res.data.token) {
+						uni.setStorageSync('AppToken', res.data.token);
+					}
+					if(res.data.docker) {
+						uni.setStorageSync('userInfo', JSON.stringify(res.data.docker));
+					}
+					uni.showToast({
+						icon:'success',
+						title: "登录成功",
+					});
+					uni.$emit('refreshLogin');
+					var data= res.data.docker
+					setTimeout(() => {
+						if(data.status==0){
+							uni.navigateTo({
+								url: '/pages_user/certification'
+							})
+						}else{
+							uni.navigateBack({
+								delta: 1
+							});
+						}
+					}, 500);
+				} else {
+					uni.showToast({
+						icon:'none',
+						title: res.msg || "登录失败",
+					});
+				}
+			} catch (e) {
+				uni.hideLoading();
+				console.error('登录失败', e);
 				uni.showToast({
 					icon:'none',
-					title: "验证码登录接口待对接",
+					title: "登录失败",
 				});
-			}, 1000);
+			}
 		},
 		// 密码登录
-		loginByPassword() {
-			uni.showLoading({
-				title:"登录中..."
-			});
-			// TODO: 调用密码登录接口
-			// 示例:loginByPassword({ phone: this.phone, password: this.password })
-			setTimeout(() => {
+		async loginByPassword() {
+			try {
+				uni.showLoading({
+					title:"登录中..."
+				});
+				console.log('---------------')
+				const res = await loginByPassword({ 
+					phone: this.phone, 
+					password: this.password,
+					loginType:1
+				});
+				uni.hideLoading();
+				if(res.code === 200) {
+					// 保存token和用户信息
+					if(res.data.token) {
+						uni.setStorageSync('AppToken', res.data.token);
+					}
+					if(res.data.docker) {
+						uni.setStorageSync('userInfo', JSON.stringify(res.data.docker));
+					}
+					uni.showToast({
+						icon:'success',
+						title: "登录成功",
+					});
+					uni.$emit('refreshLogin');
+					var data= res.data.docker
+					setTimeout(() => {
+						if(data.status==0){
+							uni.navigateTo({
+								url: '/pages_user/certification'
+							})
+						}else{
+							uni.navigateBack({
+								delta: 1
+							});
+						}
+					}, 500);
+				} else {
+					uni.showToast({
+						icon:'none',
+						title: res.msg || "登录失败",
+					});
+				}
+			} catch (e) {
 				uni.hideLoading();
+				console.error('登录失败', e);
 				uni.showToast({
 					icon:'none',
-					title: "密码登录接口待对接",
+					title: "登录失败",
 				});
-			}, 1000);
+			}
 		},
 		checkWeixin(){
 			var ua = window.navigator.userAgent.toLowerCase();

+ 4 - 17
pages/common/launch.vue

@@ -1,8 +1,7 @@
 <template>
 	<view class="content">
-		[[]]
-		<view class="loadding" v-if="loadding==true">
-			<image src="https://user.test.ylrztop.com/images/logo.png"></image>
+		<view class="loadding" v-if="loadding">
+			<image src="@/static/logo.jpg"></image>
 			<text class="text">互联网医院</text>
 		</view>
 	</view>
@@ -19,20 +18,8 @@
 		methods: {
 			
 			getDicts:function(){
-				getDicts().then(
-					res => {
-						if(res.code==200){
-							console.log(res)
-							uni.setStorageSync('dicts',JSON.stringify(res));
-							
-						}else{
-							 
-						}
-						this.loadding=false;
-						this.navigatHandler();
-					},
-					rej => {}
-				);
+				this.loadding=false
+				this.navigatHandler();
 			},
 			navigatHandler: function() {
 				uni.reLaunch({

+ 107 - 211
pages/home/index.vue

@@ -1,7 +1,7 @@
 <template>
 	<view class="content">
 		<!-- 背景图片 -->
-		<image class="bg" src="@/static/image/top_bg.svg" mode="widthFix"></image>
+		<image class="bg" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/top_bg.png" mode="widthFix"></image>
 		<view>
 			<view class="top-inner">
 				<view class="fixed-top-box" :style="{ background: bgColor ,paddingBottom:top>0?'20rpx':''}">
@@ -13,11 +13,11 @@
 					</view> -->
 					<!-- 搜索框、购物车、客服 -->
 					<view class="func-cont" :style="{marginTop: menuButtonInfo.top}">
-						<view class="search-cont">
+						<view class="search-cont" @click="toSearch">
 							<image class="icon-search" src="@/static/image/icon_search.png" mode=""></image>
 							<input type="text" disabled value="" placeholder="请输入关键字或作者"
 								placeholder-style="font-size:28rpx;color:#BBBBBB;font-family: PingFang SC;" />
-							<view class="btn" @click="toSearch">搜索</view>
+							<view class="btn">搜索</view>
 						</view>
 						<!-- 购物车 -->
 						<!-- <uni-badge size="small" :text="cartCount" absolute="rightTop" type="error">
@@ -46,9 +46,8 @@
 				<view class="inner">
 					<swiper class="swiper" :indicator-dots="true" :circular="true" :autoplay="true" :interval="3000"
 						:duration="1000" indicator-color="rgba(255, 255, 255, 0.6)" indicator-active-color="#ffffff">
-						<swiper-item class="swiper-item" v-for="(item,index) in advList" :key="index"
-							@click="handleAdvClick(item)">
-							<image :src="item.imageUrl" mode=""></image>
+						<swiper-item class="swiper-item" v-for="(item,index) in advList" :key="index">
+							<image :src="item" mode="aspectFit"></image>
 						</swiper-item>
 					</swiper>
 				</view>
@@ -68,13 +67,13 @@
 				<u-tabs :list="articletabList"
 					:activeStyle="{width:'136rpx',height:'56rpx',lineHeight:'56rpx',textAlign:'center',fontWeight: '500',color: '#fff',background: 'linear-gradient( 90deg, #61A3FF 0%, #207DFF 100%)',borderRadius:'98rpx'}"
 					:inactiveStyle="{width:'136rpx',height:'56rpx',lineHeight:'56rpx',fontWeight: '400',color: '#666666',background:'#fff',borderRadius:'98rpx',textAlign:'center'}"
-					lineColor="#F7F8FA" @click="selectlivetab"></u-tabs>
+					lineColor="#F7F8FA" @click="selectarticletab"></u-tabs>
 			</view>
 			<scroll-view :scroll-x="true">
 				<view class="article-box">
 					<view class="article" @click="navTo('/pages_live/addForm')">
 						<view class="image-box">
-							<image class="bg" mode="aspectFill" src="@/static/image/bg_invitecard.svg"></image>
+							<image class="bg" mode="aspectFill" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/bg_invitecard.png"></image>
 							<view class="views">
 								<image mode="aspectFill" src="@/static/image/icon_goon.png"></image>
 								<view class="status">进行中</view>
@@ -98,7 +97,7 @@
 					</view>
 					<view class="article" @click="navTo('/pages_live/addForm')">
 						<view class="image-box">
-							<image class="bg" mode="aspectFill" src="@/static/image/bg_invitecard.svg"></image>
+							<image class="bg" mode="aspectFill" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/bg_invitecard.png"></image>
 							<view class="views">
 								<image mode="aspectFill" src="@/static/image/icon_tobestart.png"></image>
 								<view class="status">待开始</view>
@@ -122,7 +121,7 @@
 					</view>
 					<view class="article" @click="navTo('/pages_live/addForm')">
 						<view class="image-box">
-							<image class="bg" mode="aspectFill" src="@/static/image/bg_invitecard.svg"></image>
+							<image class="bg" mode="aspectFill" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/bg_invitecard.png"></image>
 							<view class="views">
 								<image mode="aspectFill" src="@/static/image/icon_goon.png"></image>
 								<view class="status">进行中</view>
@@ -165,78 +164,35 @@
 					lineColor="#F7F8FA" @click="selectlivetab"></u-tabs>
 			</view>
 			<scroll-view :scroll-x="true">
-				<view class="article-box">
-					<view class="article" @click="navTo('/pages_live/lessonDetail?articleId=87')">
+				<view class="article-box" v-if="classList.length>0">
+					<view class="article" v-for="(item,index) in classList" :key="index" @click="navTo('/pages_live/lessonDetail?groupId='+item.groupId)">
 						<view class="image-box">
-							<image class="bg" mode="aspectFill" src="@/static/image/bg_invitecard.svg"></image>
+							<image class="bg" mode="aspectFill" :src="item.coverUrl"></image>
 							<view class="zhibo">
 								<image mode="aspectFill" src="@/static/image/icon_video.png"></image>
 							</view>
 						</view>
 						<view class="article-title-box">
-							<view class="article-title one-t">王医生学术直播</view>
+							<view class="article-title one-t">{{item.title}}</view>
 							<view class="name-title one-t">
 								<image mode="aspectFill" src="@/static/image/icon_doctor.png"></image>
 								<view class="one-t">
-									王小明-副主任医师/副主任副主任
+									{{item.doctorName+'-'+item.jobTitle+'/'+item.department}}
 								</view>
 							</view>
 							<view class="position-title">
 								<image mode="aspectFill" src="@/static/image/icon_hospital.png"></image>
 								<view class="one-t">
-									北京人民医院
-								</view>
-							</view>
-						</view>
-					</view>
-					<view class="article" @click="navTo('/pages_live/lessonDetail?articleId=87')">
-						<view class="image-box">
-							<image class="bg" mode="aspectFill" src="@/static/image/bg_invitecard.svg"></image>
-							<view class="zhibo">
-								<image mode="aspectFill" src="@/static/image/icon_video.png"></image>
-							</view>
-						</view>
-						<view class="article-title-box">
-							<view class="article-title one-t">王医生学术直播</view>
-							<view class="name-title one-t">
-								<image mode="aspectFill" src="@/static/image/icon_doctor.png"></image>
-								<view class="one-t">
-									王小明-副主任医师/副主任副主任
-								</view>
-							</view>
-							<view class="position-title">
-								<image mode="aspectFill" src="@/static/image/icon_hospital.png"></image>
-								<view class="one-t">
-									北京人民医院
-								</view>
-							</view>
-						</view>
-					</view>
-					<view class="article" @click="navTo('/pages_live/lessonDetail?articleId=87')">
-						<view class="image-box">
-							<image class="bg" mode="aspectFill" src="@/static/image/bg_invitecard.svg"></image>
-							<view class="zhibo">
-								<image mode="aspectFill" src="@/static/image/icon_video.png"></image>
-							</view>
-						</view>
-						<view class="article-title-box">
-							<view class="article-title one-t">王医生学术直播</view>
-							<view class="name-title one-t">
-								<image mode="aspectFill" src="@/static/image/icon_doctor.png"></image>
-								<view class="one-t">
-									王小明-副主任医师/副主任副主任
-								</view>
-							</view>
-							<view class="position-title">
-								<image mode="aspectFill" src="@/static/image/icon_hospital.png"></image>
-								<view class="one-t">
-									北京人民医院
+									{{item.institution||'-'}}
 								</view>
 							</view>
 						</view>
 					</view>
 				</view>
-
+				<view class="empty-state y-bc" v-else>
+					<image class="w200 h200" src="@/static/image/img_blank_nodata.png" mode=""></image>
+					<text>暂无数据</text>
+				</view>
 			</scroll-view>
 		</view>
 	</view>
@@ -257,7 +213,9 @@
 		getTuiDoctor,
 		getTuiArticle,
 		getTuiDoctorOrder,
-		getCartCount
+		getCartCount,
+		getClassroomList,
+		getIndexBannerList
 	} from '@/api/index'
 	import {
 		getDoctorArticleList
@@ -266,7 +224,7 @@
 		getArticleList
 	} from '@/api/article.js'
 	import {
-		getStoreConfig
+		getStoreConfig,getTaskTypeList
 	} from '@/api/common'
 	import {
 		getUserInfo,
@@ -312,27 +270,19 @@
 				orderType: 0,
 				cateId: null,
 				articleList: [],
-				advList: [],
+				advList: [
+					// {id:1,imageUrl:'https://hos-1309931967.cos.ap-chongqing.myqcloud.com/fs/20240516/b091048293f142608f99eaf1b0b1510a.png'},
+					// {id:2,imageUrl:'https://hos-1309931967.cos.ap-chongqing.myqcloud.com/fs/20251126/7483a5b4346447ae878e6b1b9b02d201.jpg'},
+				],
 				doctorList: [],
 				articleCateList: [],
 				doctocArticles: [], //养生讲堂
 				articles: [], //养生干货
-				livetabList: [{
-						name: '推荐'
-					},
-					{
-						name: '内分泌'
-					},
-					{
-						name: '肾病'
-					},
-					{
-						name: '心血管'
-					},
-					{
-						name: '风湿免疫'
-					}
+				classList:[],
+				livetabList: [
+					
 				], //养生讲堂TAB
+				liveTab:'',
 				articletabList: [{
 						name: '推荐'
 					},
@@ -348,74 +298,13 @@
 				], //文章TAB
 				// 状态栏的高度
 				statusBarHeight: uni.getStorageSync('menuInfo').statusBarHeight,
-				// tabBg: tabBg, // tab切换背景
-				// 问诊案例类型
-				orderTypes: [{
-					name: '全部',
-					id: 0,
-				}, {
-					name: '图文',
-					id: 1,
-				}, {
-					name: '语音',
-					id: 2,
-				}],
-				// 限时消息是否显示
-				messageShow: true,
-				yangshengs: [{
-						id: "1",
-						title: "药膳食疗",
-						page: "/pages_index/index/medicatedFoodList",
-						icon: "https://fs-1319721001.cos.ap-chongqing.myqcloud.com/fs/20240229/3cfbd47911cf4753aa9497eac500728d.png"
-					},
-					{
-						id: "2",
-						title: "穴位保健",
-						page: "/pages_index/index/vesselList",
-						icon: "https://fs-1319721001.cos.ap-chongqing.myqcloud.com/fs/20240229/e93536a9dc1a4f8ca09545097b12fdea.png"
-					},
-					{
-						id: "3",
-						title: "特供中药",
-						page: "/pages_index/index/questionsList",
-						icon: "https://fs-1319721001.cos.ap-chongqing.myqcloud.com/fs/20240229/e896972bd56f4e358188af36f2c5af42.png"
-					},
-					{
-						id: "4",
-						title: "营养特医",
-						page: "/pages_index/index/diseaseList",
-						icon: "https://fs-1319721001.cos.ap-chongqing.myqcloud.com/fs/20240229/d6f1851cccae414b8baf2ba07782f91b.png"
-					},
-					{
-						id: "5",
-						title: "古方精方",
-						page: "/pages_index/index/chineseMedicineList",
-						icon: "https://fs-1319721001.cos.ap-chongqing.myqcloud.com/fs/20240229/ff43572d0d004285b5a3b0ef2663c471.png"
-					},
-					{
-						id: "6",
-						title: "健康案例",
-						page: "/pages_index/index/famousPrescribeList",
-						icon: "https://fs-1319721001.cos.ap-chongqing.myqcloud.com/fs/20240229/45db770e58c34963b0d2ba24a958b617.png"
-					},
-					{
-						id: "7",
-						title: "中西药房",
-						page: "/pages_index/index/doctorArticleList",
-						icon: "https://fs-1319721001.cos.ap-chongqing.myqcloud.com/fs/20240229/e793942797b24035b51f94d894bdfa0b.png"
-					},
-					{
-						id: "8",
-						title: "更多",
-						page: "",
-						icon: "/static/images/ysyd_more_icon.png"
-					}
-				],
+				
 			}
 			this.getStoreActivity();
 		},
 		onLoad(option) {
 			this.getMenuButtonInfo(); // 初始化获取胶囊信息
+			this.getIndexBannerList();
 			if (option.userCode != null) {
 				uni.setStorageSync('userCode', option.userCode);
 				if (this.utils.checkLoginState()) {
@@ -433,7 +322,7 @@
 					this.getUserInfo();
 				}
 			}
-			this.getStoreActivity()
+			//this.getStoreActivity()
 		},
 		// 暂停所有音频(一般用于页面切换时停止正在播放的音频)
 		onUnload() { //普通页面在 onUnload 生命周期中执行
@@ -453,7 +342,7 @@
 			return {
 				title: '互联网医院-您的专属健康解决方案',
 				path: `/pages/common/launch`,
-				imageUrl: 'https://user.test.ylrztop.com/images/logo.png' //分享图标,路径可以是本地文件路径、代码包文件路径或者网络图片路径.支持PNG及JPG。显示图片长宽比是 5:4
+				imageUrl: '/static/logo.jpg' //分享图标,路径可以是本地文件路径、代码包文件路径或者网络图片路径.支持PNG及JPG。显示图片长宽比是 5:4
 			}
 		},
 		onReachBottom() {
@@ -465,7 +354,7 @@
 			return {
 				title: '互联网医院-您的专属健康解决方案',
 				query: '', //页面参数
-				imageUrl: 'https://user.test.ylrztop.com/images/logo.png' //分享图标,路径可以是本地文件路径、代码包文件路径或者网络图片路径.支持PNG及JPG。显示图片长宽比是 5:4
+				imageUrl: '/static/logo.jpg' //分享图标,路径可以是本地文件路径、代码包文件路径或者网络图片路径.支持PNG及JPG。显示图片长宽比是 5:4
 			}
 		},
 		computed: {
@@ -476,23 +365,66 @@
 			},
 		},
 		onShow() {
-			this.getMenu();
-			this.getIndexData()
+			this.getClassroomList()
+			this.getTaskTypeList()
+			//this.getMenu();
+			//this.getIndexData()
 			//this.getTuiDoctorOrder();
 			// console.log(uni.getStorageSync('isLocation'))
 			// if(uni.getStorageSync('isLocation')==""){
 			// 	this.getLocation();
 			// }
-			if (this.utils.checkLoginState()) {
-				this.getCartCount();
-			}
-			this.getStoreConfig();
+			// if (this.utils.checkLoginState()) {
+			// 	this.getCartCount();
+			// }
+			// this.getStoreConfig();
 			//this.getTuiDoctor()
 			// this.getCanvas();
-			this.getDoctorArticleList();
-			this.getArticleList();
+			//this.getDoctorArticleList();
+			//this.getArticleList();
 		},
 		methods: {
+			getTaskTypeList() {
+				getTaskTypeList({dictType:'cloud_class_group'}).then(
+					res => {
+						if (res.code == 200) {
+							var res =res.data
+							this.livetabList = res.map(item => ({
+							    name: item.dictLabel,
+							    id: item.dictValue
+							  }));
+							// 在开头添加默认选项"全部"
+							this.livetabList.unshift({
+								name: '全部',
+								id: ''
+							});
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			getClassroomList() {
+				let data = {
+					groupId:this.liveTab,
+					pageNum:1,
+					pageSize:3
+				}
+				getClassroomList(data).then(res => {
+					if (res.code == 200) {
+						this.classList=res.data.rows
+					} else {
+						uni.showToast({
+							icon: 'none',
+							title: "请求失败",
+						});
+					}
+				});
+			},
 			getUserInfo() {
 				getUserInfo().then(
 					res => {
@@ -569,25 +501,6 @@
 				this.activityShow = false;
 				// uni.setStorageSync(this.activity.activityId,null);
 			},
-			getStoreActivity() {
-				let data = {}
-				getStoreActivity(data).then(res => {
-					this.activity = res.activity;
-					if (this.activity != null) {
-						// if(uni.getStorageSync(this.activity.activityId)!=null)
-						// {
-						// 	uni.setStorageSync(this.activity.activityId,1);
-						// 	this.activityShow=true;
-						// }
-						// else{
-						// 	this.activityShow=false;
-						// }
-						this.activityShow = true;
-					} else {
-						this.activityShow = false;
-					}
-				})
-			},
 			showActivity() {
 				this.activityShow = false;
 				uni.navigateTo({
@@ -626,7 +539,9 @@
 			},
 			//养生讲堂等直播tab
 			selectlivetab(item) {
-				// console.log('item', item);
+				this.liveTab=item.id
+				this.getClassroomList()
+				//console.log('item', item);
 			},
 			// 健康案例分享等文章tab
 			selectarticletab(item) {
@@ -673,24 +588,7 @@
 					}
 				});
 			},
-			getDepartmentList() {
-				this.depts = [];
-				getDepartmentList().then(res => {
-					if (res.code == 200) {
-						var allDept = {
-							departmentId: 0,
-							departmentName: "全部"
-						}
-						this.depts.push(allDept);
-						this.depts = this.depts.concat(res.data);
-					} else {
-						uni.showToast({
-							icon: 'none',
-							title: "请求失败",
-						});
-					}
-				});
-			},
+		
 			getTuiDoctor() {
 				let data = {
 					departmentId: this.deptId,
@@ -776,24 +674,16 @@
 					}
 				})
 			},
-			getIndexData() {
-				let data = {};
-				getIndexData(data).then(
+			getIndexBannerList() {
+				let data = {sysConfig:'sys.index.banner'};
+				getIndexBannerList(data).then(
 					res => {
 						if (res.code == 200) {
-							this.advList = res.data.advList;
-							this.articleCateList = res.data.articleCateList;
-							if (this.articleCateList != null && this.articleCateList.length > 0) {
-								this.cateId = this.articleCateList[0].cateId;
-								this.getTuiArticle()
-							}
-							this.tuiProductList = res.data.tuiProductList
-							this.newProductList = res.data.newProductList
-							this.hotProductList = res.data.hotProductList
+							this.advList = res.data;
 						} else {
 							uni.showToast({
 								icon: 'none',
-								title: "请求失败",
+								title: res.msg,
 							});
 						}
 					},
@@ -959,7 +849,12 @@
 		text-overflow: ellipsis;
 		white-space: nowrap;
 	}
-
+.empty-state {
+	padding:24rpx;
+	text-align: center;
+	font-size: 28rpx;
+	color: #999;
+}
 	.fixed-top-box {
 		width: 100%;
 		position: fixed;
@@ -2073,10 +1968,10 @@
 			// border-radius: 16rpx;
 
 			.title-box {
-				display: flex;
-				flex-direction: row;
-				align-items: center;
-				justify-content: space-between;
+				// display: flex;
+				// flex-direction: row;
+				// align-items: center;
+				// justify-content: space-between;
 
 				::v-deep.u-tabs__wrapper__nav__item {
 					padding-left: 0 !important;
@@ -2260,6 +2155,7 @@
 						}
 
 						.position-title {
+							width: 100%;
 							display: flex;
 							align-items: center;
 							font-family: PingFang SC, PingFang SC;

+ 17 - 9
pages/task/index.vue

@@ -1,12 +1,12 @@
 <template>
 	<view>
 		<view class="task-list">
-			<view class="item" v-for="(item,index) in tabs" :key="index" >
+			<view class="item" v-for="(item,index) in tabs" :key="index" @click="showDetail(item.url)">
 				<view class="left">
 					<image :src="item.icon" mode=""></image>
 					<view class="title-l">{{item.name}}</view>
 				</view>
-				<view class="right" @click="showDetail(item.url)">
+				<view class="right">
 					<view class="num" v-if="item.num!==0">{{item.num}}</view>
 					<image src="@/static/image/icon_more.png" mode=""></image>
 				</view>
@@ -29,11 +29,12 @@
 		data() {
 			return {
 				tabs:[
-					{name:'在线讲座',num:12,icon:'/static/image/icon_task_zxjz.png',url:'/pages_task/onlineLecture'},
-					{name:'空中课堂',num:3,icon:'/static/image/icon_task_kzkt.png',url:'/pages_task/airClassroom'},
-					{name:'用药调研',num:8,icon:'/static/image/icon_task_yydy.png',url:'/pages_task/medicationSurvey'},
+					{name:'在线讲座',num:0,icon:'/static/image/icon_task_zxjz.png',url:'/pages_task/onlineLecture'},
+					{name:'用药调研',num:0,icon:'/static/image/icon_task_yydy.png',url:'/pages_task/medicationSurvey'},
 					{name:'问卷调查',num:0,icon:'/static/image/icon_task_wjdc.png',url:'/pages_task/questionnaire'},
 					{name:'科普创作',num:0,icon:'/static/image/icon_task_kpcz.png',url:'/pages_task/science'},
+					{name:'长视频创作',num:0,icon:'/static/image/icon_task_longvideo.png',url:'/pages_task/longVideo'},
+					{name:'短视频创作',num:0,icon:'/static/image/icon_task_shortvideo.png',url:'/pages_task/shortVideo'},
 				],
 				typeOptions:[],
 				questionsType:0,
@@ -61,7 +62,7 @@
 			};
 		},
 		onShow() {
-			this.getDictByKey("sys_questions_type");
+			//this.getDictByKey("sys_questions_type");
 		},
 		methods:{
 			getDictByKey(key){
@@ -128,9 +129,16 @@
 			},
 			// 查看详情
 			showDetail(url) {
-				uni.navigateTo({
-					url: url
-				})
+				this.isLogin = uni.getStorageSync('AppToken')
+				if(this.isLogin){
+					uni.navigateTo({
+						url: url
+					})
+				}else{
+					uni.navigateTo({
+						url: '/pages/auth/login'
+					})	
+				}
 			}
 		}
 	}

+ 30 - 21
pages/user/index.vue

@@ -1,20 +1,20 @@
 <template>
 	<view>
 		<view class="top-cont">
-			<image class="bg" src="@/static/image/top_bg.svg" mode="widthFix"></image>
+			<image class="bg" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/top_bg.png" mode="widthFix"></image>
 			<view class="top-inner">			
 				<!-- 这里是状态栏 -->
 				<view class="status_bar" :style="{height: statusBarHeight}"></view>
 				<view class="user-info">
 					<view class="left">
 						<view class="head-img">
-							<image :src="user.avatar==null?'/static/image/my_heads_icon64.svg':user.avatar" mode="aspectFill"></image>
+							<image :src="user.avatar==null?'https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/my_heads_icon64.png':user.avatar" mode="aspectFill"></image>
 						</view>
 						<view class="name-phone">
 							<view class="x-f">
-								<view class="name" v-if="UserInfo">{{user.nickname}}</view>
+								<view class="name" v-if="isLogin">{{user.doctorName||'用户'}}</view>
 								<view class="name" v-else>请先登录</view>
-								<text>{{user.phone?utils.parsePhone(user.phone):'-'}}</text>
+								<text>{{user.mobile?utils.parsePhone(user.mobile):''}}</text>
 							</view>
 							
 							<!-- <view class="phone">
@@ -22,14 +22,14 @@
 							<text>{{user.phone?utils.parsePhone(user.phone):'-'}}</text>
 							</view> -->
 							
-							<view class="vip">
+							<view class="vip" v-if="user.status==1">
 								<image class="w24 h24" src="../../static/image/icon_v.png" mode=""></image>
 								已认证
 							</view>
 						</view>
 					</view>
 					<view class="right">
-						<view class="set" @click="navgetTo('/pages_user/user/personInfo')">
+						<view class="set" @click="navgetTo('/pages_user/personInfo')">
 							<image class="w48 h48" src="../../static/image/right_arrow_black_icon24.png" mode=""></image>
 						</view>
 						<!-- <uni-badge size="small" :text="msgNum" absolute="rightTop" type="error">
@@ -49,8 +49,8 @@
 						</uni-badge> -->
 					</view>
 				</view>
-				<view class="vipbox" @click="goVip">
-					<image src="@/static/image/img_renzheng.svg" mode="widthFix"></image>
+				<view v-if="user.status==0" class="vipbox" @click="goVip">
+					<image src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/img_renzheng.png" mode="widthFix"></image>
 				</view>
 				
 				<view class="content">
@@ -67,7 +67,7 @@
 						</view>
 					</view>
 					<!-- 退出登录按钮 -->
-					<view class="log-out" @click="logOut">退出登录</view>
+					<view  v-if="isLogin" class="log-out" @click="logOut">退出登录</view>
 				</view>
 			</view>
 			
@@ -104,6 +104,7 @@
 				statusBarHeight: uni.getStorageSync('menuInfo').statusBarHeight,
 				// 消息数量
 				msgNum: 0,
+				isLogin: false,
 			 isShow:true,
 				 UserInfo: uni.getStorageSync('AppToken')
 			};
@@ -113,12 +114,18 @@
 		},
 		onShow() {
 			console.log("onshow")
-			//this.getUserInfo();
-			//this.getOrderCount();
+			this.isLogin = uni.getStorageSync('AppToken')
+			if(this.isLogin){
+				this.getUserInfo();
+			}else{
+				uni.navigateTo({
+					url: '/pages/auth/login'
+				})	
+			}
 		},
 		onReachBottom() {
 			console.log("onReachBottom")
-			this.$refs.product.getGoodsProducts();
+			//this.$refs.product.getGoodsProducts();
 		},
 		methods: {
 			seeChange(){
@@ -158,9 +165,9 @@
 			 		confirmText:'确定',
 			 		success:res=>{
 			 			if(res.confirm){
-							uni.setStorageSync('CompanyUserToken',null);
-			 				uni.setStorageSync('AppToken',null);
-							uni.setStorageSync('userInfo',null);
+							//uni.setStorageSync('CompanyUserToken',null);
+			 				uni.removeStorageSync('AppToken',null);
+							uni.removeStorageSync('userInfo',null);
 							uni.$emit('refreshLogin');
 			 				uni.navigateTo({
 			 					url: '/pages/auth/login'
@@ -218,8 +225,8 @@
 				getUserInfo().then(
 					res => {
 						if(res.code==200){
-							if(res.user!=null){
-								this.user=res.user;
+							if(res.data!=null){
+								this.user=res.data;
 							}
 							else{
 								this.utils.loginOut();
@@ -237,13 +244,15 @@
 			},
 			// 跳转页面
 			navgetTo(url) {
-				this.utils.isLogin().then(res => {
-					if(res){
+					if(this.isLogin){
 						uni.navigateTo({
 							url: url+'?userId='+this.user.userId
 						})
-					}
-				})
+					}else{
+				uni.navigateTo({
+					url: '/pages/auth/login'
+				})	
+			}
 			},
 			// 查看订单
 			showOrder(status) {

+ 47 - 14
pages_echarts/statistics.vue

@@ -135,7 +135,12 @@
 </template>
 
 <script>
-// import { getStatisticsData } from '@/api-js/statistics'
+import { 
+	getStatisticsData, 
+	getStatisticsSummary, 
+	getTaskTypeStatistics, 
+	getTaskStatusStatistics 
+} from '@/api/statistics'
 export default {
 	data() {
 		return {
@@ -267,26 +272,54 @@ export default {
 			this.selectedTaskType = this.tempSelectedTaskType
 			this.selectedTaskStatus = this.tempSelectedTaskStatus
 			this.showFilter = false
-			//this.loadData()
+			this.loadData()
 		},
 		async loadData() {
 			try {
 				uni.showLoading({ title: '加载中...' })
-				const res = await getStatisticsData({
-					startDate: this.dateRange.startDate,
-					endDate: this.dateRange.endDate,
-					taskType: this.selectedTaskType,
-					taskStatus: this.selectedTaskStatus
-				})
+				// 并行加载统计数据、汇总数据、类型统计和状态统计
+				const [dataRes, summaryRes, typeRes, statusRes] = await Promise.all([
+					getStatisticsData({
+						startDate: this.dateRange.startDate,
+						endDate: this.dateRange.endDate,
+						taskType: this.selectedTaskType,
+						taskStatus: this.selectedTaskStatus
+					}),
+					getStatisticsSummary({
+						startDate: this.dateRange.startDate,
+						endDate: this.dateRange.endDate
+					}).catch(() => ({ code: 0 })),
+					getTaskTypeStatistics({
+						startDate: this.dateRange.startDate,
+						endDate: this.dateRange.endDate
+					}).catch(() => ({ code: 0 })),
+					getTaskStatusStatistics({
+						startDate: this.dateRange.startDate,
+						endDate: this.dateRange.endDate
+					}).catch(() => ({ code: 0 }))
+				])
 				uni.hideLoading()
-				if (res.code === 200 && res.data) {
+				
+				if (dataRes.code === 200 && dataRes.data) {
+					this.tableData = dataRes.data.list || []
+				} else {
+					this.tableData = []
+				}
+				
+				// 更新汇总数据
+				if (summaryRes.code === 200 && summaryRes.data) {
 					this.summaryData = {
-						taskCount: res.data.taskCount || 6,
-						totalPoints: res.data.totalPoints || 300
+						taskCount: summaryRes.data.taskCount || 0,
+						totalPoints: summaryRes.data.totalPoints || 0
 					}
-					this.tableData = res.data.list || this.getDefaultData()
-				} else {
-					this.tableData = this.getDefaultData()
+				}
+				
+				// 如果有类型统计和状态统计,可以用于图表展示
+				if (typeRes.code === 200 && typeRes.data) {
+					console.log('任务类型统计', typeRes.data)
+				}
+				if (statusRes.code === 200 && statusRes.data) {
+					console.log('任务状态统计', statusRes.data)
 				}
 			} catch (e) {
 				uni.hideLoading()

+ 2 - 2
pages_live/card.vue

@@ -2,7 +2,7 @@
 	<view class="content">
 		<view class="inner">
 			<view class="bg">
-				<image class="w622 h622" src="@/static/image/bg_invitecard.svg" mode=""></image>
+				<image class="w622 h622" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/bg_invitecard.png" mode=""></image>
 				<view class="infor">
 					<view class="title one-t">康复医学概论</view>
 					<view class="name-title">
@@ -43,7 +43,7 @@
 	export default {
 		data() {
 			return {
-			 bgImg: "/static/image/bg_invitecard.svg",
+			 bgImg: "https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/bg_invitecard.png",
 			      doctorIcon: "/static/image/icon_doctor_fill.png",
 			      qrCodeImg: "/static/image/icon_doctor_fill.png", // 替换为真实二维码
 			      wechatIcon: "/static/image/icon_share_wechat.png",

+ 38 - 87
pages_live/lesson.vue

@@ -10,16 +10,8 @@
 				</view>
 			</view>
 			<view class="keyword-list">
-				<!-- 关键字列表 -->
-				<!-- <scroll-view   scroll-x="true" >
-				<view class="inner">
-					<view v-for="(item,index) in cates" :key="index" :class="choseCateId == item.cateId?'item active':'item'" @click="choseCate(item)">
-						{{ item.cateName }}
-					</view>
-				</view>
-			</scroll-view> -->
 				<u-tabs :list="cates" :activeStyle="{fontWeight: '500',color: '#333333',fontSize: '32rpx',lineHeight:'88rpx'}"
-					:inactiveStyle="{color: '#999999',fontSize: '28rpx',lineHeight:'88rpx'}" @click="choseCate(item)"
+					:inactiveStyle="{color: '#999999',fontSize: '28rpx',lineHeight:'88rpx'}" @click="choseCate"
 					scrollable="false" lineColor="#388BFF"></u-tabs>
 			</view>
 		</view>
@@ -29,69 +21,23 @@
 			<view class="know-list">
 				<view class="item" v-for="(item,index) in dataList" :key="index" @click="showDetail(item)">
 					<view class="image-box">
-						<image class="bg" mode="aspectFill" :src="item.imageUrl"></image>
+						<image class="bg" mode="aspectFill" :src="item.coverUrl"></image>
 						<view class="zhibo">
 							<image mode="aspectFill" src="@/static/image/icon_video.png"></image>
 						</view>
 					</view>
 					<view class="article-title-box">
-						<view class="article-title one-t">王医生学术直播</view>
+						<view class="article-title one-t">{{item.title}}</view>
 						<view class="name-title ">
 							<image mode="aspectFill" src="@/static/image/icon_doctor.png"></image>
 							<view class="one-t">
-								王小明-副主任医师/副主任副主任
-							</view>
-						</view>
-						<view class="position-title">
-							<image mode="aspectFill" src="@/static/image/icon_hospital.png"></image>
-							<view class="one-t">
-								北京人民医院
-							</view>
-						</view>
-					</view>
-				</view>
-				<view class="item" v-for="(item,index) in dataList" :key="index" @click="showDetail(item)">
-					<view class="image-box">
-						<image class="bg" mode="aspectFill" :src="item.imageUrl"></image>
-						<view class="zhibo">
-							<image mode="aspectFill" src="@/static/image/icon_video.png"></image>
-						</view>
-					</view>
-					<view class="article-title-box">
-						<view class="article-title one-t">王医生学术直播</view>
-						<view class="name-title">
-							<image mode="aspectFill" src="@/static/image/icon_doctor.png"></image>
-							<view class="position-title">
-								<image mode="aspectFill" src="@/static/image/icon_hospital.png"></image>
-								<view class="one-t">
-									北京人民医院
-								</view>
-							</view>
-						</view>
-						<view class="position-title one-t">
-							<image mode="aspectFill" src="@/static/image/icon_hospital.png"></image>北京人民医院
-						</view>
-					</view>
-				</view>
-				<view class="item" v-for="(item,index) in dataList" :key="index" @click="showDetail(item)">
-					<view class="image-box">
-						<image class="bg" mode="aspectFill" :src="item.imageUrl"></image>
-						<view class="zhibo">
-							<image mode="aspectFill" src="@/static/image/icon_video.png"></image>
-						</view>
-					</view>
-					<view class="article-title-box">
-						<view class="article-title one-t">王医生学术直播</view>
-						<view class="name-title">
-							<image mode="aspectFill" src="@/static/image/icon_doctor.png"></image>
-							<view class="one-t">
-								王小明-副主任医师/副主任副主任
+								{{item.doctorName+'-'+item.jobTitle+'/'+item.department}}
 							</view>
 						</view>
 						<view class="position-title">
 							<image mode="aspectFill" src="@/static/image/icon_hospital.png"></image>
 							<view class="one-t">
-								北京人民医院
+								{{item.institution||'-'}}
 							</view>
 						</view>
 					</view>
@@ -104,9 +50,11 @@
 
 <script>
 	import {
-		getArticleCate,
-		getArticleList
-	} from '@/api/article'
+		getClassroomList
+	} from '@/api/index'
+	import {
+		getTaskTypeList
+	} from '@/api/common'
 	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
 	export default {
 		mixins: [MescrollMixin],
@@ -114,21 +62,20 @@
 			return {
 				top: '0px',
 				cates: [
-					{name: '全部',cateId:0},
-					{name:'内分泌',cateId:1},
-					{name:'肾病',cateId:2},
-					{name:'心血管',cateId:3},
-					{name:'风湿免疫',cateId:4},
-					{name:'风湿免疫',cateId:5},
+					// {name: '全部',cateId:0},
+					// {name:'内分泌',cateId:1},
+					// {name:'肾病',cateId:2},
+					// {name:'心血管',cateId:3},
+					// {name:'风湿免疫',cateId:4},
+					// {name:'风湿免疫',cateId:5},
 				],
-				choseCateId: 0,
+				choseCateId:'',
 				// 状态栏的高度
 				statusBarHeight: uni.getStorageSync('menuInfo').statusBarHeight,
 				searchValue: '',
 				mescroll: null,
 				// 上拉加载的配置
 				downOption: {
-
 				},
 				upOption: {
 					onScroll: true,
@@ -139,7 +86,7 @@
 					},
 					noMoreSize: 10, // 配置列表的总数量要大于等于5条才显示'-- END --'的提示
 					empty: {
-						icon: '/static/images/no_data.png',
+						icon: '/static/image/img_blank_nodata.png',
 						tip: '暂无数据'
 					},
 					textNoMore: '没有更多了~'
@@ -149,7 +96,7 @@
 			};
 		},
 		onShow() {
-			//this.getArticleCate();
+			this.getArticleCate();
 			var that = this;
 			setTimeout(function() {
 				let query = uni.createSelectorQuery().select(".top-content");
@@ -165,14 +112,17 @@
 			},
 			getArticleCate() {
 				var that = this;
-				let data = {};
-				getArticleCate(data).then(
+				getTaskTypeList({dictType:'cloud_class_group'}).then(
 					res => {
 						if (res.code == 200) {
-							this.cates = res.data.map(person => ({
-								name: person.cateName
+							this.cates = res.data.map(item => ({
+								name: item.dictLabel,
+								id: item.dictValue
 							}));
-
+							this.cates.unshift({
+								name: '全部',
+								id: ''
+							});
 						} else {
 							uni.showToast({
 								icon: 'none',
@@ -194,22 +144,22 @@
 				//联网加载数据
 				var that = this;
 				var data = {
-					keyword: this.searchValue,
-					cateId: this.choseCateId,
-					page: page.num,
+					keyWord:this.searchValue,
+					groupId:this.choseCateId,
+					pageNum: page.num,
 					pageSize: page.size
 				};
-				getArticleList(data).then(res => {
+				getClassroomList(data).then(res => {
 					if (res.code == 200) {
 						//设置列表数据
 						if (page.num == 1) {
-							that.dataList = res.data.list;
+							that.dataList = res.data.rows;
 
 						} else {
-							that.dataList = that.dataList.concat(res.data.list);
+							that.dataList = that.dataList.concat(res.data.rows);
 
 						}
-						that.mescroll.endBySize(res.data.list.length, res.data.total);
+						that.mescroll.endBySize(res.data.rows.length, res.data.total);
 
 					} else {
 						uni.showToast({
@@ -223,13 +173,13 @@
 			},
 			// 关键词选择
 			choseCate(item) {
-				this.choseCateId = item.cateId;
+				this.choseCateId = item.id;
 				this.mescroll.resetUpScroll()
 			},
 			// 查看详情
 			showDetail(item) {
 				uni.navigateTo({
-					url: '/pages_live/lessonDetail?articleId=87'
+					url: '/pages_live/lessonDetail?groupId='+item.groupId
 				})
 			}
 		}
@@ -355,7 +305,7 @@
 			flex-direction: column;
 			margin-bottom: 18rpx;
 			margin-right: 18rpx;
-			&:nth-child(2){
+			&:nth-child(2n){
 				margin-right:0;
 			}
             .image-box {
@@ -442,6 +392,7 @@
 				}
 			
 				.position-title {
+					width: 100%;
 					display: flex;
 					align-items: center;
 					font-family: PingFang SC, PingFang SC;

+ 20 - 55
pages_live/lessonDetail.vue

@@ -1,15 +1,15 @@
 <template>
 	<view class="content">
 		<view class="detail-cont">
-			<view class="title">全球肾脏新药研究生态驱动创新突破降蛋白瓶颈</view>
+			<view class="title">{{item.title||'-'}}</view>
 			<view class="info">
 				<view class="time">
-					<u-icon name="clock" color="#fff" size="14"></u-icon>2025-12-30</view>
+					<u-icon name="clock" color="#fff" size="14"></u-icon>{{item.createTime}}</view>
 				<view class="reads ">
-					<u-icon name="eye" color="#fff" size="14"></u-icon>10</view>
+					<u-icon name="eye" color="#fff" size="14"></u-icon>{{item.viewCount ||0}}</view>
 			</view>
 			<view class="video">
-				<video class="myVideo" id="myVideo" src="http://bjzmkytcpv.ylrzcloud.com/course/20251117/1763364883777.m3u8"
+				<video class="myVideo" id="myVideo" :src="item.videoUrl"
 				@error="videoErrorCallback"   controls ></video>
 			</view>
 			<!-- 正文 -->
@@ -21,58 +21,48 @@
 				<view class="text-box">本内容仅代表嘉宾观点,不代表本站立场。仅供医学药学专业人士查看,不构成实际治疗建议。</view>
 			</view>
 			<view class="actor x-f">
-				<image class="w88 h88" src="@/static/image/my_heads_icon64.svg" mode=""></image>
+				<image class="w88 h88" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/my_heads_icon64.png" mode=""></image>
 				<view class="infor y-start">
-					<view class="name">王小明 主任医师</view>
-					<view class="position">江南大学附属医院·肾内科</view>
+					<view class="name">{{item.doctorName+'-'+item.jobTitle}}</view>
+					<view class="position">{{item.institution||'-'}}·{{item.department||'-'}}</view>
 				</view>
 			</view>
 			<view class="full-text">
 				<view>
-					全球肾脏新药研究生态驱动创新突破降蛋白瓶颈,这里展示摘要。
+					{{item.summary||'-'}}
 				</view>
 			</view>
-			<view class="tag">#转载#肾病</view>
+			<!-- <view class="tag">#转载#肾病</view> -->
 		</view>
 	</view> 
 </template>
 
 <script>
-	// import {getAdvList} from '@/api/adv.js'
-	import {getDoctorArticleById} from '@/api/doctorArticle.js'
+	import {getClassroomDetail} from '@/api/index.js'
 	export default {
 		data() {
 			return {
 				advs:[],
 				advImgs:[],
 				src: '',
-				articleId:null,
+				groupId:null,
 				item:{},
+				type:''
 			};
 		},
 		onLoad(option) {
-			this.articleId=option.articleId;
-			 
+			this.groupId=option.groupId;
 		},
 		onShow() {
-			//this.getAdvList()
+			this.getClassroomDetail()
 			//this.getDoctorArticleById();
 		},
 		//发送给朋友
 		onShareAppMessage(res) {
 			return {
 				title: this.item.title,
-				path: '/pages_index/index/doctorArticleDetails?articleId='+this.articleId,
+				path: '/pages_live/lessonDetail?groupId='+this.groupId,
 			}
-			
-		},
-		//分享到朋友圈
-		onShareTimeline(res) {
-			return {
-				title: this.item.title,
-				query:'articleId='+this.articleId,//页面参数
-			}
-			
 		},
 		methods:{
 			handleAdvClick(index){
@@ -97,32 +87,6 @@
 				}
 				
 			},
-			getAdvList() {
-				//联网加载数据
-				var that = this;
-				var data = {
-					advType:10
-				};
-				getAdvList(data).then(res => {
-					if(res.code==200){
-						that.advImgs=[];
-						that.advs=[];
-						res.data.forEach(function(element) {
-							if(element.imageUrl!=null&&element.imageUrl!=""){
-								that.advs.push(element);
-								that.advImgs.push(element.imageUrl);
-							}
-						});
-						
-					}else{
-						uni.showToast({
-							icon:'none',
-							title: "请求失败",
-						});
-					}
-				});
-			},
-			 
 			videoErrorCallback: function(e) {
 				uni.showModal({
 					content: e.target.errMsg,
@@ -134,9 +98,8 @@
 					url: url
 				})
 			},
-			getDoctorArticleById(){
-				let data = {articleId:this.articleId};
-				getDoctorArticleById(data).then(
+			getClassroomDetail(){
+				getClassroomDetail(this.groupId).then(
 					res => {
 						if(res.code==200){
 							this.item=res.data;
@@ -221,12 +184,14 @@
 			line-height: 44rpx;
 		}
 	.tips{
-		width: calc(100% - 60rpx);
+		// width: calc(100% - 60rpx);
 		margin-bottom:184rpx;
 		display: flex;
 		align-items: center;
 		padding: 16rpx 24rpx;
 		margin-top: 40rpx;
+		margin-left: 24rpx;
+		margin-right: 24rpx;
 		background: rgba(255, 255, 255, 0.1);
 		border-radius: 18rpx 18rpx 18rpx 18rpx;
 		.text-box{

+ 45 - 101
pages_live/search.vue

@@ -3,40 +3,31 @@
 		<view class="top-content">
 			<view class="search-cont">
 				<view class="inner">
-					<image class="icon-search" src="../../static/images/search.png" mode=""></image>
+					<u-icon name="search" size="24" color="#C8C9CC"></u-icon>
 					<input type="text" v-model="searchValue" placeholder="请输入关键字或作者" confirm-type="search"
 						@confirm="doSearch"
 						placeholder-style="font-size:28rpx;color:#BBBBBB;font-family: PingFang SC;" />
 				</view>
 			</view>
 			<view class="keyword-list">
-				<!-- 关键字列表 -->
-				<!-- <scroll-view   scroll-x="true" > -->
 				<view class="inner">
 					<view v-for="(item,index) in cates" :key="index" :class="choseCateId == item.cateId?'item active':'item'" @click="choseCate(item)">
 						{{ item.cateName }}
 					</view>
 				</view>
-			<!-- </scroll-view> -->
-				<!-- <u-tabs :list="cates" :activeStyle="{fontWeight: '500',color: '#333333',fontSize: '32rpx',lineHeight:'88rpx'}"
-					:inactiveStyle="{color: '#999999',fontSize: '28rpx',lineHeight:'88rpx'}" @click="choseCate(item)"
-					scrollable="false" lineColor="#388BFF"></u-tabs> -->
 			</view>
 		</view>
 
-		<mescroll-body :top="top" ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback"
+		<mescroll-body top="190rpx" ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback"
 			:down="downOption" :up="upOption">
-			<view class="know-list">
-				<view class="item" v-for="(item,index) in dataList" :key="index" @click="showDetail(item)">
+			<view class="know-list" v-if='choseCateId==0'>
+				<view class="item">
 					<view class="image-box">
-						<image class="bg" mode="aspectFill" :src="item.imageUrl"></image>
-						<view v-if="choseCateId==0" class="views" >
+						<image class="bg" mode="aspectFill" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/bg_invitecard.png"></image>
+						<view class="views" >
 							<image mode="aspectFill" src="@/static/image/icon_goon.png"></image>
 							<view class="status">进行中</view>
 						</view>
-						<view v-else class="zhibo">
-							<image mode="aspectFill" src="@/static/image/icon_video.png"></image>
-						</view>
 					</view>
 					<view class="article-title-box">
 						<view class="article-title one-t">王医生学术直播</view>
@@ -54,77 +45,45 @@
 						</view>
 					</view>
 				</view>
+			</view>
+			<view class="know-list" v-else>
 				<view class="item" v-for="(item,index) in dataList" :key="index" @click="showDetail(item)">
 					<view class="image-box">
-						<image class="bg" mode="aspectFill" :src="item.imageUrl"></image>
-						<view v-if="choseCateId==0" class="views" >
-							<image mode="aspectFill" src="@/static/image/icon_goon.png"></image>
-							<view class="status">进行中</view>
-						</view>
-						<view v-else class="zhibo">
-							<image mode="aspectFill" src="@/static/image/icon_video.png"></image>
-						</view>
-					</view>
-					<view class="article-title-box">
-						<view class="article-title one-t">王医生学术直播</view>
-						<view class="name-title">
-							<image mode="aspectFill" src="@/static/image/icon_doctor.png"></image>
-							<view class="position-title">
-								<image mode="aspectFill" src="@/static/image/icon_hospital.png"></image>
-								<view class="one-t">
-									北京人民医院
-								</view>
-							</view>
-						</view>
-						<view class="position-title one-t">
-							<image mode="aspectFill" src="@/static/image/icon_hospital.png"></image>北京人民医院
-						</view>
-					</view>
-				</view>
-				<view class="item" v-for="(item,index) in dataList" :key="index" @click="showDetail(item)">
-					<view class="image-box">
-						<image class="bg" mode="aspectFill" :src="item.imageUrl"></image>
-						<view v-if="choseCateId==0" class="views" >
-							<image mode="aspectFill" src="@/static/image/icon_goon.png"></image>
-							<view class="status">进行中</view>
-						</view>
-						<view v-else class="zhibo">
+						<image class="bg" mode="aspectFill" :src="item.coverUrl"></image>
+						<view class="zhibo">
 							<image mode="aspectFill" src="@/static/image/icon_video.png"></image>
 						</view>
 					</view>
 					<view class="article-title-box">
-						<view class="article-title one-t">王医生学术直播</view>
-						<view class="name-title">
+						<view class="article-title one-t">{{item.title}}</view>
+						<view class="name-title ">
 							<image mode="aspectFill" src="@/static/image/icon_doctor.png"></image>
 							<view class="one-t">
-								王小明-副主任医师/副主任副主任
+								{{item.doctorName+'-'+item.jobTitle+'/'+item.department}}
 							</view>
 						</view>
 						<view class="position-title">
 							<image mode="aspectFill" src="@/static/image/icon_hospital.png"></image>
 							<view class="one-t">
-								北京人民医院
+								{{item.institution||'-'}}
 							</view>
 						</view>
 					</view>
 				</view>
 			</view>
 		</mescroll-body>
-
 	</view>
 </template>
 
 <script>
 	import {
-		getArticleCate,
-		getArticleList
-	} from '@/api/article'
+		getClassroomList
+	} from '@/api/index'
 	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
 	export default {
 		mixins: [MescrollMixin],
 		data() {
 			return {
-				top: '0px',
 				cates: [
 					{cateName: '在线讲座',cateId:0},
 					{cateName:'空中课堂',cateId:1},
@@ -147,50 +106,32 @@
 					},
 					noMoreSize: 10, // 配置列表的总数量要大于等于5条才显示'-- END --'的提示
 					empty: {
-						icon: '/static/images/no_data.png',
+						icon: '/static/image/img_blank_nodata.png',
 						tip: '暂无数据'
 					},
-					textNoMore: '已经到底了'
+					textNoMore: '没有更多了~'
 				},
 				// 列表数据
 				dataList: [],
 			};
 		},
+		onLoad() {
+			// var that = this;
+			// setTimeout(function() {
+			// 	let query = uni.createSelectorQuery().select(".top-content");
+			// 	query.boundingClientRect(function(data) { //data - 各种参数
+			// 		console.log(data.height) // 获取元素宽度
+			// 		that.top = data.height + "px";
+			// 	}).exec()
+			// }, 500);
+		},
 		onShow() {
 			//this.getArticleCate();
-			var that = this;
-			setTimeout(function() {
-				let query = uni.createSelectorQuery().select(".top-content");
-				query.boundingClientRect(function(data) { //data - 各种参数
-					console.log(data.height) // 获取元素宽度
-					that.top = data.height + "px";
-				}).exec()
-			}, 500);
 		},
 		methods: {
 			doSearch() {
 				this.mescroll.resetUpScroll()
 			},
-			getArticleCate() {
-				var that = this;
-				let data = {};
-				getArticleCate(data).then(
-					res => {
-						if (res.code == 200) {
-							this.cates = res.data.map(person => ({
-								name: person.cateName
-							}));
-
-						} else {
-							uni.showToast({
-								icon: 'none',
-								title: "请求失败",
-							});
-						}
-					},
-					rej => {}
-				);
-			},
 			mescrollInit(mescroll) {
 				this.mescroll = mescroll;
 			},
@@ -202,23 +143,22 @@
 				//联网加载数据
 				var that = this;
 				var data = {
-					keyword: this.searchValue,
-					cateId: this.choseCateId,
-					page: page.num,
+					keyWord:this.searchValue,
+					pageNum: page.num,
 					pageSize: page.size
 				};
-				getArticleList(data).then(res => {
+				getClassroomList(data).then(res => {
 					if (res.code == 200) {
 						//设置列表数据
 						if (page.num == 1) {
-							that.dataList = res.data.list;
-
+							that.dataList = res.data.rows;
+			
 						} else {
-							that.dataList = that.dataList.concat(res.data.list);
-
+							that.dataList = that.dataList.concat(res.data.rows);
+			
 						}
-						that.mescroll.endBySize(res.data.list.length, res.data.total);
-
+						that.mescroll.endBySize(res.data.rows.length, res.data.total);
+			
 					} else {
 						uni.showToast({
 							icon: 'none',
@@ -236,9 +176,13 @@
 			},
 			// 查看详情
 			showDetail(item) {
-				uni.navigateTo({
-					url: './detail?articleId=' + item.articleId
-				})
+				if(this.choseCateId==0){
+					url: '/pages_live/addForm'
+				}else{
+					uni.navigateTo({
+						url: '/pages_live/lessonDetail?groupId='+item.groupId
+					})
+				}
 			}
 		}
 	}
@@ -246,7 +190,7 @@
 
 <style lang="scss">
 	page {
-		background: #EFF3F7;
+		background: #F7F8FA;
 	}
 
 	.status_bar {

+ 7 - 1
pages_task/activityDetail.vue

@@ -46,7 +46,7 @@
 </template>
 
 <script>
-import { getActivityDetail } from '@/api-js/medicationSurvey'
+import { getActivityDetail } from '@/api/medicationSurvey'
 export default {
 	data() {
 		return {
@@ -297,3 +297,9 @@ export default {
 
 
 
+
+
+
+
+
+

Разница между файлами не показана из-за своего большого размера
+ 907 - 159
pages_task/caseCollection.vue


+ 395 - 72
pages_task/completeTask.vue

@@ -12,6 +12,7 @@
 				<view class="form-input-wrapper">
 					<textarea 
 						class="form-input" 
+						style="height: 100rpx;"
 						v-model="formData.title" 
 						placeholder="请输入标题"
 						maxlength="50"
@@ -74,25 +75,35 @@
 				</view>
 				<view class="form-tips">仅支持jpg/png文件,单个图片不超过2M</view>
 				<view class="upload-cover" @click="chooseCoverImage">
-					<image class="img" v-if="formData.coverImage" :src="formData.coverImage" mode="aspectFill"></image>
+					<image class="img" v-if="formData.coverImage" :src="formData.coverImage" mode=""></image>
 					<view v-else class="upload-placeholder">
 						<image class="w48 h48" src="@/static/image/icon_camera1.png" mode=""></image>
 					</view>
 				</view>
 			</view>
-			
+			<!-- 上传进度弹窗 -->
+			<view class="upload-modal" v-if="showUploadModal">
+				<view class="upload-modal-content">
+					<view class="upload-modal-title">文件上传中</view>
+					<view class="upload-progress-wrapper">
+						<progress :percent="percent" stroke-width="8" show-info activeColor="#4CAF50" border-radius="10"></progress>
+					</view>
+					<view class="upload-modal-tips">请勿关闭页面</view>
+				</view>
+			</view>
 			<!-- 上传附件 -->
 			<view class="form-section">
 				<view class="form-label">
 					<text class="required">*</text>
 					<text>上传附件</text>
 				</view>
-				<view class="form-tips">支持MP4等文件,单个文件不超过500M</view>
+				<view v-if="taskType==4" class="form-tips">支持PDF等文件,单个文件不超过2M</view>
+				<view v-else class="form-tips">支持MP4等文件,单个文件不超过500M</view>
 				<view class="attachment-list">
 					<view class="attachment-item" v-for="(item, index) in formData.attachments" :key="index">
-						<text class="attachment-icon">📎</text>
-						<view class="attachment-info">
-							<text class="attachment-name">{{ item.name }}</text>
+						<text class="attachment-icon"></text>
+						<view class="attachment-info" style="width: 90%;">
+							<text class="attachment-name one-t" style="width: 90%;">{{ item.name }}</text>
 							<text class="attachment-size">{{ item.size }}</text>
 						</view>
 						<text class="attachment-delete" @click="removeAttachment(index)">×</text>
@@ -124,8 +135,8 @@
 						:class="{ active: tempGroupId === item.id }"
 						v-for="(item, index) in groupOptions" 
 						:key="index"
-						@click="tempGroupId = item.id; tempGroupName = item.name">
-						{{ item.name }}
+						@click="tempGroupId = item.id; tempGroupName = item.projectName">
+						{{ item.projectName }}
 					</view>
 				</view>
 			</view>
@@ -141,11 +152,11 @@
 				</view>
 				<view class="picker-body">
 					<view class="picker-item" 
-						:class="{ active: tempTagId === item.id }"
+						:class="{ active: tempTagId === item.dictValue }"
 						v-for="(item, index) in tagOptions" 
 						:key="index"
-						@click="tempTagId = item.id; tempTagName = item.name">
-						{{ item.name }}
+						@click="tempTagId = item.dictValue; tempTagName = item.dictLabel">
+						{{ item.dictLabel }}
 					</view>
 				</view>
 			</view>
@@ -154,12 +165,16 @@
 </template>
 
 <script>
-import { submitTask, getGroupOptions, getTagOptions, uploadFile } from '@/api-js/airClassroom'
+import { submitTask, getGroupOptions, getTagOptions } from '@/api/airClassroom'
+import { deleteFile, deleteBatch, checkFast, complete,postPolicy} from '@/api/common.js'
 export default {
 	data() {
 		return {
+			percent: 0,
+			showUploadModal: false, // 控制上传进度弹窗显示
 			statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
 			taskId: '',
+			taskType:null,
 			isEdit: false,
 			showGroupPicker: false,
 			showTagPicker: false,
@@ -178,14 +193,14 @@ export default {
 				attachments: []
 			},
 			groupOptions: [
-				{ id: '1', name: '学术' },
-				{ id: '2', name: '临床' },
-				{ id: '3', name: '科研' }
+				// { id: '1', name: '学术' },
+				// { id: '2', name: '临床' },
+				// { id: '3', name: '科研' }
 			],
 			tagOptions: [
-				{ id: '1', name: '长视频' },
-				{ id: '2', name: '短视频' },
-				{ id: '3', name: '文章' }
+				// { id: '1', name: '长视频' },
+				// { id: '2', name: '短视频' },
+				// { id: '3', name: '文章' }
 			]
 		}
 	},
@@ -200,6 +215,7 @@ export default {
 	onLoad(options) {
 		if (options.id) {
 			this.taskId = options.id
+			this.taskType = options.taskType
 		}
 		if (options.edit === 'true') {
 			this.isEdit = true
@@ -232,54 +248,252 @@ export default {
 				count: 1,
 				sizeType: ['compressed'],
 				sourceType: ['album', 'camera'],
-				success: async (res) => {
-					try {
-						uni.showLoading({ title: '上传中...' })
-						const uploadRes = await uploadFile({
-							file: res.tempFilePaths[0],
-							type: 'cover'
-						})
-						uni.hideLoading()
-						if (uploadRes.code === 200 && uploadRes.data) {
-							this.formData.coverImage = uploadRes.data.url
+				success: (res) => {
+					uni.showLoading({ title: '上传中...' })
+					console.log('图片路径',res)
+					const filePath = res.tempFilePaths[0]
+					const requestPath = uni.getStorageSync('requestPath')
+					const uploadTask = uni.uploadFile({
+						url: `${requestPath}/app/common/uploadOSS`,
+						filePath: filePath,
+						name: 'file',
+						formData: {},
+						success: (uploadRes) => {
+							uni.hideLoading()
+							try {
+								const result = typeof uploadRes.data === 'string' ? JSON.parse(uploadRes.data) : uploadRes.data
+								if (result.code == 200) {
+									this.formData.coverImage = result.url
+									uni.showToast({ icon: 'success', title: '上传成功' })
+								} else {
+									uni.showToast({ icon: 'none', title: result.msg || '上传失败' })
+								}
+							} catch (e) {
+								uni.hideLoading()
+								console.error('解析上传结果失败', e)
+								uni.showToast({ icon: 'none', title: '上传失败' })
+							}
+						},
+						fail: (err) => {
+							// this.percent = 0;
+							console.error('上传失败', err)
+							uni.showToast({ icon: 'none', title: '上传失败' })
 						}
-					} catch (e) {
-						uni.hideLoading()
-						uni.showToast({ icon: 'none', title: '上传失败' })
-					}
+					})
 				}
 			})
 		},
-		chooseAttachment() {
-			uni.chooseFile({
-				count: 1,
-				type: 'file',
-				success: async (res) => {
-					const file = res.tempFiles[0]
-					if (file.size > 500 * 1024 * 1024) {
-						uni.showToast({ icon: 'none', title: '文件大小不能超过500M' })
-						return
-					}
-					try {
-						uni.showLoading({ title: '上传中...' })
-						const uploadRes = await uploadFile({
-							file: file.path,
-							type: 'attachment'
-						})
-						uni.hideLoading()
-						if (uploadRes.code === 200 && uploadRes.data) {
-							this.formData.attachments.push({
-								name: file.name,
-								size: this.formatFileSize(file.size),
-								url: uploadRes.data.url
-							})
-						}
-					} catch (e) {
-						uni.hideLoading()
-						uni.showToast({ icon: 'none', title: '上传失败' })
-					}
-				}
-			})
+		chooseAttachment(){
+			var vm = this;
+			
+			         // 对更多字符编码的 url encode 格式
+			         var camSafeUrlEncode = function (str) {
+			            return encodeURIComponent(str)
+			                    .replace(/!/g, '%21')
+			                    .replace(/'/g, '%27')
+			                    .replace(/\(/g, '%28')
+			                    .replace(/\)/g, '%29')
+			                    .replace(/\*/g, '%2A');
+			         };
+			         const requestPath = uni.getStorageSync('requestPath')
+			         // 获取上传路径、上传凭证
+			         var getUploadInfo = function (extName, callback) {
+			            // 传入文件后缀,让后端生成随机的 COS 对象路径,并返回上传域名、PostObject 接口要用的 policy 签名
+			            // 参考服务端示例:https://github.com/tencentyun/cos-demo/tree/main/server/post-policy
+			            uni.request({
+			               url: `${requestPath}/app/upload/post-policy?ext=` + extName,
+			               success: (res) => {
+			                 // 确认返回格式是否正确
+			                 //console.log(res);
+			                  callback && callback(null, res.data);
+			               },
+			               error(err) {
+			                  callback && callback(err);
+			               },
+			            });
+			         };
+			
+			         // 发起上传请求,上传使用 PostObject 接口,使用 policy 签名保护
+			         // 接口文档:https://cloud.tencent.com/document/product/436/14690#.E7.AD.BE.E5.90.8D.E4.BF.9D.E6.8A.A4
+			         var uploadFile = function (opt, callback) {
+						  console.log("上传参数", opt);
+			            // 构建表单数据(字段名必须使用带连字符的格式,符合腾讯云 PostObject 接口要求)
+			            var formData = {
+			               key: opt.data.key, // 文件路径(必须是 key,不是 cosKey)
+			               policy: opt.data.policy, // policy 的 base64 字符串
+			               success_action_status: '200',  // 成功状态码
+			               'q-sign-algorithm': opt.data.qsignAlgorithm,// 签名算法(必须是 q-sign-algorithm)
+			               'q-ak': opt.data.qak,
+			               'q-key-time': opt.data.qkeyTime, // 密钥有效时间(必须是 q-key-time)
+			               'q-signature': opt.data.qsignature // 签名(必须是 q-signature)
+			            };
+			            
+			            // 如果服务端用了临时密钥计算,需要传 x-cos-security-token
+			            if (opt.data.securityToken) {
+			               formData['x-cos-security-token'] = opt.data.securityToken;
+			            }
+			            
+			           
+			            console.log("上传URL", opt.data.url);
+			            console.log("文件路径", opt.filePath);
+			            
+			            // 显示上传进度弹窗
+			            vm.showUploadModal = true;
+			            vm.percent = 0;
+			            
+			            const uploadTask=uni.uploadFile({
+			               url: opt.data.url, // COS 上传域名
+			               filePath: opt.filePath, // 文件路径(不在 formData 中)
+			               name: 'file', // 文件字段名
+			               formData: formData, // 表单数据
+			               success: (res) => {
+			                  console.log("上传响应", res);
+			                  // 关闭上传进度弹窗
+			                  vm.showUploadModal = false;
+			                  vm.percent = 0;
+			                  
+			                  if (![200, 204].includes(res.statusCode)) {
+			                     console.error("上传失败,状态码:", res.statusCode, res);
+			                     return callback && callback(res);
+			                  }
+			                  // 构建文件访问 URL
+			                  var fileUrl = opt.data.url + '/' + camSafeUrlEncode(opt.data.key).replace(/%2F/g, '/');
+			                  console.log("上传成功,文件URL:", fileUrl);
+			                  callback && callback(null, fileUrl);
+			               },
+			               fail: (err) => {
+			                  console.error("上传失败", err);
+			                  // 关闭上传进度弹窗
+			                  vm.showUploadModal = false;
+			                  vm.percent = 0;
+			                  callback && callback(err);
+			               }
+			            });
+						uploadTask.onProgressUpdate(function(res) {
+							vm.percent = res.progress;
+						});
+			         };
+			
+			         // 根据 taskType 选择不同的文件类型
+			         // taskType = 4(科普文章):上传普通文档文件
+			         // taskType = 5 或 6:上传视频文件
+			         
+			         var taskType = vm.taskType;
+			         console.log('当前 taskType:', taskType);
+			         
+			         // taskType = 5 或 6,选择视频文件
+			         if (taskType == 5 || taskType == 6) {
+			            // 选择视频文件
+			            wx.chooseMessageFile({
+			               count: 3,
+						   type: 'video',
+			               success: (chooseRes) => {
+			                  console.log('选择视频', chooseRes);
+			                  var filePath = chooseRes.tempFiles[0].path;
+							  var size = chooseRes.tempFiles[0].size;
+							  var name = chooseRes.tempFiles[0].name;
+			                  var lastIndex = filePath.lastIndexOf('.');
+			                  var extName = lastIndex > -1 ? filePath.slice(lastIndex + 1) : '';
+			                  // 获取预上传用的域名、路径、凭证
+			                  getUploadInfo(extName, function (err, info) {
+			                     if (err) {
+			                        console.error('获取上传信息失败', err);
+			                        uni.showToast({ icon: 'none', title: '获取上传信息失败' });
+			                        return;
+			                     }
+			                     console.log("上传信息", info);
+			                     info.filePath = filePath;
+			                     // 上传文件
+			                     uploadFile(info, function (err, fileUrl) {
+			                        if (err) {
+			                           console.error('上传失败', err);
+			                           uni.showToast({ icon: 'none', title: '上传失败' });
+			                           return;
+			                        }
+			                        console.log('上传成功,文件URL:', fileUrl);
+			                        // 添加到附件列表
+			                        vm.formData.attachments.push({
+			                           name:name,
+			                           size: vm.formatFileSize(size || 0),
+			                           url: fileUrl
+			                        });
+			                        uni.showToast({ icon: 'success', title: '上传成功' });
+			                     });
+			                  });
+			               },
+			               fail: (err) => {
+			                  if (err.errMsg && !err.errMsg.includes('cancel')) {
+			                     console.error('选择视频失败', err);
+			                     uni.showToast({ icon: 'none', title: '选择视频失败' });
+			                  }
+			               }
+			            });
+			            return;
+			         }else{
+						 wx.chooseMessageFile({
+						    count: 1,
+						    type: 'file', // 选择文档文件(不包括视频和图片)
+						    success: (res) => {
+						       console.log('文档路径',res)
+						       const filePath = res.tempFiles[0].path
+							   const fileName = res.tempFiles[0].name
+							   const size = res.tempFiles[0].size;
+						       const requestPath = uni.getStorageSync('requestPath')
+						       
+						       // 显示上传进度弹窗
+						       vm.showUploadModal = true;
+						       vm.percent = 0;
+						       
+						       const uploadTask = uni.uploadFile({
+						       	url: `${requestPath}/app/common/uploadOSS`,
+						       	filePath: filePath,
+						       	name: 'file',
+						       	formData: {},
+						       	success: (uploadRes) => {
+						       		// 关闭上传进度弹窗
+						       		vm.showUploadModal = false;
+						       		vm.percent = 0;
+						       		
+						       		try {
+						       			const result = typeof uploadRes.data === 'string' ? JSON.parse(uploadRes.data) : uploadRes.data
+						       			if (result.code == 200) {
+						       				//this.formData.attachmentUrl = result.url
+											vm.formData.attachments.push({
+											   name:fileName,
+											   size: vm.formatFileSize(size || 0),
+											   url: result.url
+											});
+						       				uni.showToast({ icon: 'success', title: '上传成功' })
+						       			} else {
+						       				uni.showToast({ icon: 'none', title: result.msg || '上传失败' })
+						       			}
+						       		} catch (e) {
+						       			console.error('解析上传结果失败', e)
+						       			uni.showToast({ icon: 'none', title: '上传失败' })
+						       		}
+						       	},
+						       	fail: (err) => {
+						       		// 关闭上传进度弹窗
+						       		vm.showUploadModal = false;
+						       		vm.percent = 0;
+						       		console.error('上传失败', err)
+						       		uni.showToast({ icon: 'none', title: '上传失败' })
+						       	}
+						       })
+						       
+						       // 监听上传进度
+						       uploadTask.onProgressUpdate(function(res) {
+						       	vm.percent = res.progress;
+						       })
+						    },
+						    fail: (err) => {
+						       if (err.errMsg && !err.errMsg.includes('cancel')) {
+						          console.error('选择文档失败', err);
+						          uni.showToast({ icon: 'none', title: '选择文档失败' });
+						       }
+						    }
+						 });
+					 }
 		},
 		removeAttachment(index) {
 			this.formData.attachments.splice(index, 1)
@@ -289,11 +503,43 @@ export default {
 			if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + 'KB'
 			return (bytes / (1024 * 1024)).toFixed(2) + 'MB'
 		},
+		// 根据文件扩展名获取文件类型
+		getFileType(fileExt) {
+			const typeMap = {
+				// 视频
+				'mp4': 'video',
+				'avi': 'video',
+				'mov': 'video',
+				'wmv': 'video',
+				'flv': 'video',
+				'mkv': 'video',
+				// 音频
+				'mp3': 'audio',
+				'wav': 'audio',
+				'wma': 'audio',
+				// 图片
+				'jpg': 'image',
+				'jpeg': 'image',
+				'png': 'image',
+				'gif': 'image',
+				'bmp': 'image',
+				// 文档
+				'pdf': 'document',
+				'doc': 'document',
+				'docx': 'document',
+				'xls': 'document',
+				'xlsx': 'document',
+				'ppt': 'document',
+				'pptx': 'document',
+				'txt': 'document'
+			}
+			return typeMap[fileExt] || 'other'
+		},
 		async loadOptions() {
 			try {
 				const [groupRes, tagRes] = await Promise.all([
 					getGroupOptions(),
-					getTagOptions()
+					getTagOptions({dictType:'project_label'})
 				])
 				if (groupRes.code === 200 && groupRes.data) {
 					this.groupOptions = groupRes.data
@@ -325,17 +571,47 @@ export default {
 				uni.showToast({ icon: 'none', title: '请上传封面' })
 				return
 			}
-			if (this.formData.attachments.length === 0) {
-				uni.showToast({ icon: 'none', title: '请上传附件' })
-				return
-			}
+			// 附件可选,不再强制要求
+			// if (this.formData.attachments.length === 0) {
+			// 	uni.showToast({ icon: 'none', title: '请上传附件' })
+			// 	return
+			// }
 			
 			try {
 				uni.showLoading({ title: '提交中...' })
-				const res = await submitTask({
-					taskId: this.taskId,
-					...this.formData
-				})
+				
+				// 获取用户信息
+				const userInfo = JSON.parse(uni.getStorageSync('userInfo') || '{}')
+				const userId = userInfo.id || ''
+				
+				// 构建附件 URL(多个附件用逗号分隔,确保是字符串类型)
+				const attachmentUrl = this.formData.attachments && this.formData.attachments.length > 0
+					? this.formData.attachments.map(item => item.url).filter(url => url).join(',')
+					: '' // 如果没有附件,返回空字符串
+				
+				// 按照 API 要求的 JSON 结构构建提交数据
+				const submitData = {
+					attachmentUrl: attachmentUrl, // 附件 URL(多个用逗号分隔)
+					content: this.formData.summary || '', // 摘要/内容
+					coverImage: this.formData.coverImage, // 封面图片
+					projectId: parseInt(this.formData.groupId) || 0, // 项目分组 ID
+					tagIds: this.formData.tagId || '', // 标签 ID(字符串)
+					taskId: parseInt(this.taskId) || 0, // 任务 ID
+					title: this.formData.title, // 标题
+					userId: userId, // 用户 ID
+					taskType:this.taskType,
+					// 以下字段为可选,设置默认值
+					// deliveryName: '',
+					// deliveryNo: '',
+					// projectLink: '',
+					// remark: '',
+					// taskName: '',
+					// taskType:this.taskType,
+					// validViews: 0,
+					// viewCount: 0
+				}
+				
+				const res = await submitTask(submitData)
 				uni.hideLoading()
 				if (res.code === 200) {
 					uni.navigateTo({
@@ -346,6 +622,7 @@ export default {
 				}
 			} catch (e) {
 				uni.hideLoading()
+				console.error('提交失败', e)
 				uni.showToast({ icon: 'none', title: '提交失败' })
 			}
 		}
@@ -365,7 +642,6 @@ export default {
 	width: 100%;
 	background: #fff;
 }
-
 .header {
 	position: relative;
 	height: 88rpx;
@@ -653,6 +929,47 @@ export default {
 		}
 	}
 }
+
+// 上传进度弹窗样式
+.upload-modal {
+	position: fixed;
+	top: 0;
+	left: 0;
+	right: 0;
+	bottom: 0;
+	background: rgba(0, 0, 0, 0.6);
+	z-index: 9999;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	
+	.upload-modal-content {
+		width: 560rpx;
+		background: #fff;
+		border-radius: 24rpx;
+		padding: 48rpx 40rpx;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		
+		.upload-modal-title {
+			font-size: 32rpx;
+			font-weight: bold;
+			color: #333;
+			margin-bottom: 40rpx;
+		}
+		
+		.upload-progress-wrapper {
+			width: 100%;
+			margin-bottom: 32rpx;
+		}
+		
+		.upload-modal-tips {
+			font-size: 24rpx;
+			color: #999;
+		}
+	}
+}
 </style>
 
 
@@ -663,3 +980,9 @@ export default {
 
 
 
+
+
+
+
+
+

+ 962 - 0
pages_task/formConfig.js

@@ -0,0 +1,962 @@
+// 表单配置 - 从 JSON 文件转换而来
+export default {
+	"fields": [
+		{
+			"__config__": {
+				"changeTag": true,
+				"customConfig": {
+					"dbColumnLength": 255,
+					"dbColumnType": "VARCHAR",
+					"dbDefaultValue": "",
+					"dbNullable": true,
+					"exportConvert": true,
+					"exportFormatter": "none",
+					"exportLabel": "",
+					"exportOrder": 0,
+					"exportWidth": 20,
+					"fieldKey": "field101",
+					"isExport": true,
+					"isListShow": true,
+					"isMasked": false,
+					"isSearchable": false,
+					"listAlign": "left",
+					"listFixed": "",
+					"listFormatter": "none",
+					"listFormatterParam": "",
+					"listMinWidth": 100,
+					"listOrder": 0,
+					"listOverflow": "tooltip",
+					"listSortable": false,
+					"listWidth": 0,
+					"maskCustomRule": "",
+					"maskRule": "",
+					"searchDefaultValue": "",
+					"searchOrder": 0,
+					"searchPlaceholder": "",
+					"searchType": "LIKE",
+					"searchWidth": 200
+				},
+				"document": "https://element.eleme.cn/#/zh-CN/component/input",
+				"formId": 101,
+				"label": "单行文本",
+				"labelWidth": null,
+				"layout": "colFormItem",
+				"regList": [],
+				"renderKey": "1011769148485798",
+				"required": true,
+				"showLabel": true,
+				"span": 24,
+				"tag": "el-input",
+				"tagIcon": "input"
+			},
+			"__slot__": {
+				"append": "",
+				"prepend": ""
+			},
+			"__vModel__": "field101",
+			"clearable": true,
+			"disabled": false,
+			"maxlength": null,
+			"placeholder": "请输入单行文本",
+			"prefix-icon": "",
+			"readonly": false,
+			"show-word-limit": false,
+			"style": {
+				"width": "100%"
+			},
+			"suffix-icon": ""
+		},
+		{
+			"__config__": {
+				"changeTag": true,
+				"customConfig": {
+					"dbColumnLength": 255,
+					"dbColumnType": "VARCHAR",
+					"dbDefaultValue": "",
+					"dbNullable": true,
+					"exportConvert": true,
+					"exportFormatter": "none",
+					"exportLabel": "",
+					"exportOrder": 0,
+					"exportWidth": 20,
+					"fieldKey": "field103",
+					"isExport": true,
+					"isListShow": true,
+					"isMasked": false,
+					"isSearchable": false,
+					"listAlign": "left",
+					"listFixed": "",
+					"listFormatter": "none",
+					"listFormatterParam": "",
+					"listMinWidth": 100,
+					"listOrder": 0,
+					"listOverflow": "tooltip",
+					"listSortable": false,
+					"listWidth": 0,
+					"maskCustomRule": "",
+					"maskRule": "",
+					"searchDefaultValue": "",
+					"searchOrder": 0,
+					"searchPlaceholder": "",
+					"searchType": "LIKE",
+					"searchWidth": 200
+				},
+				"document": "https://element.eleme.cn/#/zh-CN/component/input",
+				"formId": 103,
+				"label": "密码",
+				"labelWidth": null,
+				"layout": "colFormItem",
+				"regList": [],
+				"renderKey": "1031769148487426",
+				"required": true,
+				"showLabel": true,
+				"span": 24,
+				"tag": "el-input",
+				"tagIcon": "password"
+			},
+			"__slot__": {
+				"append": "",
+				"prepend": ""
+			},
+			"__vModel__": "field103",
+			"clearable": true,
+			"disabled": false,
+			"maxlength": null,
+			"placeholder": "请输入密码",
+			"prefix-icon": "",
+			"readonly": false,
+			"show-password": true,
+			"show-word-limit": false,
+			"style": {
+				"width": "100%"
+			},
+			"suffix-icon": ""
+		},
+		{
+			"__config__": {
+				"changeTag": true,
+				"customConfig": {
+					"dbColumnLength": null,
+					"dbColumnType": "INT",
+					"dbDefaultValue": "",
+					"dbNullable": true,
+					"exportConvert": true,
+					"exportFormatter": "none",
+					"exportLabel": "",
+					"exportOrder": 0,
+					"exportWidth": 20,
+					"fieldKey": "field104",
+					"isExport": true,
+					"isListShow": true,
+					"isMasked": false,
+					"isSearchable": false,
+					"listAlign": "left",
+					"listFixed": "",
+					"listFormatter": "none",
+					"listFormatterParam": "",
+					"listMinWidth": 100,
+					"listOrder": 0,
+					"listOverflow": "tooltip",
+					"listSortable": false,
+					"listWidth": 0,
+					"maskCustomRule": "",
+					"maskRule": "",
+					"searchDefaultValue": "",
+					"searchOrder": 0,
+					"searchPlaceholder": "",
+					"searchType": "LIKE",
+					"searchWidth": 200
+				},
+				"document": "https://element.eleme.cn/#/zh-CN/component/input-number",
+				"formId": 104,
+				"label": "计数器",
+				"labelWidth": null,
+				"layout": "colFormItem",
+				"regList": [],
+				"renderKey": "1041769148488690",
+				"required": true,
+				"showLabel": true,
+				"span": 24,
+				"tag": "el-input-number",
+				"tagIcon": "number"
+			},
+			"__vModel__": "field104",
+			"controls-position": "",
+			"disabled": false,
+			"placeholder": "计数器",
+			"step": 1,
+			"step-strictly": false
+		},
+		{
+			"__config__": {
+				"changeTag": true,
+				"customConfig": {
+					"dbColumnLength": 255,
+					"dbColumnType": "VARCHAR",
+					"dbDefaultValue": "",
+					"dbNullable": true,
+					"exportConvert": true,
+					"exportFormatter": "none",
+					"exportLabel": "",
+					"exportOrder": 0,
+					"exportWidth": 20,
+					"fieldKey": "field105",
+					"isExport": true,
+					"isListShow": true,
+					"isMasked": false,
+					"isSearchable": false,
+					"listAlign": "left",
+					"listFixed": "",
+					"listFormatter": "none",
+					"listFormatterParam": "",
+					"listMinWidth": 100,
+					"listOrder": 0,
+					"listOverflow": "tooltip",
+					"listSortable": false,
+					"listWidth": 0,
+					"maskCustomRule": "",
+					"maskRule": "",
+					"searchDefaultValue": "",
+					"searchOrder": 0,
+					"searchPlaceholder": "",
+					"searchType": "LIKE",
+					"searchWidth": 200
+				},
+				"document": "https://element.eleme.cn/#/zh-CN/component/select",
+				"formId": 105,
+				"label": "下拉选择",
+				"labelWidth": null,
+				"layout": "colFormItem",
+				"regList": [],
+				"renderKey": "1051769148490140",
+				"required": true,
+				"showLabel": true,
+				"span": 24,
+				"tag": "el-select",
+				"tagIcon": "select"
+			},
+			"__slot__": {
+				"options": [
+					{
+						"label": "选项一",
+						"value": 1
+					},
+					{
+						"label": "选项二",
+						"value": 2
+					}
+				]
+			},
+			"__vModel__": "field105",
+			"clearable": true,
+			"disabled": false,
+			"filterable": false,
+			"multiple": false,
+			"placeholder": "请选择下拉选择",
+			"style": {
+				"width": "100%"
+			}
+		},
+		{
+			"__config__": {
+				"changeTag": true,
+				"customConfig": {
+					"dbColumnLength": 255,
+					"dbColumnType": "VARCHAR",
+					"dbDefaultValue": "",
+					"dbNullable": true,
+					"exportConvert": true,
+					"exportFormatter": "none",
+					"exportLabel": "",
+					"exportOrder": 0,
+					"exportWidth": 20,
+					"fieldKey": "field102",
+					"isExport": true,
+					"isListShow": true,
+					"isMasked": false,
+					"isSearchable": false,
+					"listAlign": "left",
+					"listFixed": "",
+					"listFormatter": "none",
+					"listFormatterParam": "",
+					"listMinWidth": 100,
+					"listOrder": 0,
+					"listOverflow": "tooltip",
+					"listSortable": false,
+					"listWidth": 0,
+					"maskCustomRule": "",
+					"maskRule": "",
+					"searchDefaultValue": "",
+					"searchOrder": 0,
+					"searchPlaceholder": "",
+					"searchType": "LIKE",
+					"searchWidth": 200
+				},
+				"document": "https://element.eleme.cn/#/zh-CN/component/input",
+				"formId": 102,
+				"label": "多行文本",
+				"labelWidth": null,
+				"layout": "colFormItem",
+				"regList": [],
+				"renderKey": "1021769148486625",
+				"required": true,
+				"showLabel": true,
+				"span": 24,
+				"tag": "el-input",
+				"tagIcon": "textarea"
+			},
+			"__vModel__": "field102",
+			"autosize": {
+				"maxRows": 4,
+				"minRows": 4
+			},
+			"disabled": false,
+			"maxlength": null,
+			"placeholder": "请输入多行文本",
+			"readonly": false,
+			"show-word-limit": false,
+			"style": {
+				"width": "100%"
+			},
+			"type": "textarea"
+		},
+		{
+			"__config__": {
+				"border": false,
+				"changeTag": true,
+				"customConfig": {
+					"dbColumnLength": 255,
+					"dbColumnType": "VARCHAR",
+					"dbDefaultValue": "",
+					"dbNullable": true,
+					"exportConvert": true,
+					"exportFormatter": "none",
+					"exportLabel": "",
+					"exportOrder": 0,
+					"exportWidth": 20,
+					"fieldKey": "field106",
+					"isExport": true,
+					"isListShow": true,
+					"isMasked": false,
+					"isSearchable": false,
+					"listAlign": "left",
+					"listFixed": "",
+					"listFormatter": "none",
+					"listFormatterParam": "",
+					"listMinWidth": 100,
+					"listOrder": 0,
+					"listOverflow": "tooltip",
+					"listSortable": false,
+					"listWidth": 0,
+					"maskCustomRule": "",
+					"maskRule": "",
+					"searchDefaultValue": "",
+					"searchOrder": 0,
+					"searchPlaceholder": "",
+					"searchType": "LIKE",
+					"searchWidth": 200
+				},
+				"document": "https://element.eleme.cn/#/zh-CN/component/radio",
+				"formId": 106,
+				"label": "单选框组",
+				"labelWidth": null,
+				"layout": "colFormItem",
+				"optionType": "default",
+				"regList": [],
+				"renderKey": "1061769148491043",
+				"required": true,
+				"showLabel": true,
+				"span": 24,
+				"tag": "el-radio-group",
+				"tagIcon": "radio"
+			},
+			"__slot__": {
+				"options": [
+					{
+						"label": "选项一",
+						"value": 1
+					},
+					{
+						"label": "选项二",
+						"value": 2
+					}
+				]
+			},
+			"__vModel__": "field106",
+			"disabled": false,
+			"size": "medium",
+			"style": {}
+		},
+		{
+			"__config__": {
+				"border": false,
+				"changeTag": true,
+				"customConfig": {
+					"dbColumnLength": 255,
+					"dbColumnType": "VARCHAR",
+					"dbDefaultValue": "",
+					"dbNullable": true,
+					"exportConvert": true,
+					"exportFormatter": "none",
+					"exportLabel": "",
+					"exportOrder": 0,
+					"exportWidth": 20,
+					"fieldKey": "field107",
+					"isExport": true,
+					"isListShow": true,
+					"isMasked": false,
+					"isSearchable": false,
+					"listAlign": "left",
+					"listFixed": "",
+					"listFormatter": "none",
+					"listFormatterParam": "",
+					"listMinWidth": 100,
+					"listOrder": 0,
+					"listOverflow": "tooltip",
+					"listSortable": false,
+					"listWidth": 0,
+					"maskCustomRule": "",
+					"maskRule": "",
+					"searchDefaultValue": "",
+					"searchOrder": 0,
+					"searchPlaceholder": "",
+					"searchType": "LIKE",
+					"searchWidth": 200
+				},
+				"defaultValue": [],
+				"document": "https://element.eleme.cn/#/zh-CN/component/checkbox",
+				"formId": 107,
+				"label": "多选框组",
+				"labelWidth": null,
+				"layout": "colFormItem",
+				"optionType": "default",
+				"regList": [],
+				"renderKey": "1071769148492223",
+				"required": true,
+				"showLabel": true,
+				"span": 24,
+				"tag": "el-checkbox-group",
+				"tagIcon": "checkbox"
+			},
+			"__slot__": {
+				"options": [
+					{
+						"label": "选项一",
+						"value": 1
+					},
+					{
+						"label": "选项二",
+						"value": 2
+					}
+				]
+			},
+			"__vModel__": "field107",
+			"disabled": false,
+			"size": "medium",
+			"style": {}
+		},
+		{
+			"__config__": {
+				"changeTag": true,
+				"customConfig": {
+					"dbColumnLength": 255,
+					"dbColumnType": "VARCHAR",
+					"dbDefaultValue": "",
+					"dbNullable": true,
+					"exportConvert": true,
+					"exportFormatter": "none",
+					"exportLabel": "",
+					"exportOrder": 0,
+					"exportWidth": 20,
+					"fieldKey": "field109",
+					"isExport": true,
+					"isListShow": true,
+					"isMasked": false,
+					"isSearchable": false,
+					"listAlign": "left",
+					"listFixed": "",
+					"listFormatter": "none",
+					"listFormatterParam": "",
+					"listMinWidth": 100,
+					"listOrder": 0,
+					"listOverflow": "tooltip",
+					"listSortable": false,
+					"listWidth": 0,
+					"maskCustomRule": "",
+					"maskRule": "",
+					"searchDefaultValue": "",
+					"searchOrder": 0,
+					"searchPlaceholder": "",
+					"searchType": "LIKE",
+					"searchWidth": 200
+				},
+				"defaultValue": null,
+				"document": "https://element.eleme.cn/#/zh-CN/component/time-picker",
+				"formId": 109,
+				"label": "时间选择",
+				"labelWidth": null,
+				"layout": "colFormItem",
+				"regList": [],
+				"renderKey": "1091769148494476",
+				"required": true,
+				"showLabel": true,
+				"span": 24,
+				"tag": "el-time-picker",
+				"tagIcon": "time"
+			},
+			"__vModel__": "field109",
+			"clearable": true,
+			"disabled": false,
+			"format": "HH:mm:ss",
+			"picker-options": {
+				"selectableRange": "00:00:00-23:59:59"
+			},
+			"placeholder": "请选择时间选择",
+			"style": {
+				"width": "100%"
+			},
+			"value-format": "HH:mm:ss"
+		},
+		{
+			"__config__": {
+				"changeTag": true,
+				"customConfig": {
+					"dbColumnLength": null,
+					"dbColumnType": "TINYINT",
+					"dbDefaultValue": "",
+					"dbNullable": true,
+					"exportConvert": true,
+					"exportFormatter": "none",
+					"exportLabel": "",
+					"exportOrder": 0,
+					"exportWidth": 20,
+					"fieldKey": "field108",
+					"isExport": true,
+					"isListShow": true,
+					"isMasked": false,
+					"isSearchable": false,
+					"listAlign": "left",
+					"listFixed": "",
+					"listFormatter": "none",
+					"listFormatterParam": "",
+					"listMinWidth": 100,
+					"listOrder": 0,
+					"listOverflow": "tooltip",
+					"listSortable": false,
+					"listWidth": 0,
+					"maskCustomRule": "",
+					"maskRule": "",
+					"searchDefaultValue": "",
+					"searchOrder": 0,
+					"searchPlaceholder": "",
+					"searchType": "LIKE",
+					"searchWidth": 200
+				},
+				"defaultValue": false,
+				"document": "https://element.eleme.cn/#/zh-CN/component/switch",
+				"formId": 108,
+				"label": "开关",
+				"labelWidth": null,
+				"layout": "colFormItem",
+				"regList": [],
+				"renderKey": "1081769148493243",
+				"required": true,
+				"showLabel": true,
+				"span": 24,
+				"tag": "el-switch",
+				"tagIcon": "switch"
+			},
+			"__vModel__": "field108",
+			"active-color": null,
+			"active-text": "",
+			"active-value": true,
+			"disabled": false,
+			"inactive-color": null,
+			"inactive-text": "",
+			"inactive-value": false,
+			"style": {}
+		},
+		{
+			"__config__": {
+				"changeTag": true,
+				"customConfig": {
+					"dbColumnLength": 255,
+					"dbColumnType": "VARCHAR",
+					"dbDefaultValue": "",
+					"dbNullable": true,
+					"exportConvert": true,
+					"exportFormatter": "none",
+					"exportLabel": "",
+					"exportOrder": 0,
+					"exportWidth": 20,
+					"fieldKey": "field110",
+					"isExport": true,
+					"isListShow": true,
+					"isMasked": false,
+					"isSearchable": false,
+					"listAlign": "left",
+					"listFixed": "",
+					"listFormatter": "none",
+					"listFormatterParam": "",
+					"listMinWidth": 100,
+					"listOrder": 0,
+					"listOverflow": "tooltip",
+					"listSortable": false,
+					"listWidth": 0,
+					"maskCustomRule": "",
+					"maskRule": "",
+					"searchDefaultValue": "",
+					"searchOrder": 0,
+					"searchPlaceholder": "",
+					"searchType": "LIKE",
+					"searchWidth": 200
+				},
+				"defaultValue": null,
+				"document": "https://element.eleme.cn/#/zh-CN/component/time-picker",
+				"formId": 110,
+				"label": "时间选择",
+				"labelWidth": null,
+				"layout": "colFormItem",
+				"regList": [],
+				"renderKey": "1101769148497460",
+				"required": true,
+				"showLabel": true,
+				"span": 24,
+				"tag": "el-time-picker",
+				"tagIcon": "time"
+			},
+			"__vModel__": "field110",
+			"clearable": true,
+			"disabled": false,
+			"format": "HH:mm:ss",
+			"picker-options": {
+				"selectableRange": "00:00:00-23:59:59"
+			},
+			"placeholder": "请选择时间选择",
+			"style": {
+				"width": "100%"
+			},
+			"value-format": "HH:mm:ss"
+		},
+		{
+			"__config__": {
+				"changeTag": true,
+				"customConfig": {
+					"dbColumnLength": 255,
+					"dbColumnType": "VARCHAR",
+					"dbDefaultValue": "",
+					"dbNullable": true,
+					"exportConvert": true,
+					"exportFormatter": "none",
+					"exportLabel": "",
+					"exportOrder": 0,
+					"exportWidth": 20,
+					"fieldKey": "field111",
+					"isExport": true,
+					"isListShow": true,
+					"isMasked": false,
+					"isSearchable": false,
+					"listAlign": "left",
+					"listFixed": "",
+					"listFormatter": "none",
+					"listFormatterParam": "",
+					"listMinWidth": 100,
+					"listOrder": 0,
+					"listOverflow": "tooltip",
+					"listSortable": false,
+					"listWidth": 0,
+					"maskCustomRule": "",
+					"maskRule": "",
+					"searchDefaultValue": "",
+					"searchOrder": 0,
+					"searchPlaceholder": "",
+					"searchType": "LIKE",
+					"searchWidth": 200
+				},
+				"defaultValue": [
+					"14:08:25",
+					"15:08:25"
+				],
+				"document": "https://element.eleme.cn/#/zh-CN/component/time-picker",
+				"formId": 111,
+				"label": "时间范围",
+				"labelWidth": null,
+				"layout": "colFormItem",
+				"regList": [],
+				"renderKey": "1111769148499332",
+				"required": true,
+				"showLabel": true,
+				"span": 24,
+				"tag": "el-time-picker",
+				"tagIcon": "time-range"
+			},
+			"__vModel__": "field111",
+			"clearable": true,
+			"disabled": false,
+			"end-placeholder": "结束时间",
+			"format": "HH:mm:ss",
+			"is-range": true,
+			"range-separator": "至",
+			"start-placeholder": "开始时间",
+			"style": {
+				"width": "100%"
+			},
+			"value-format": "HH:mm:ss"
+		},
+		{
+			"__config__": {
+				"changeTag": true,
+				"customConfig": {
+					"dbColumnLength": null,
+					"dbColumnType": "DATE",
+					"dbDefaultValue": "",
+					"dbNullable": true,
+					"exportConvert": true,
+					"exportFormatter": "none",
+					"exportLabel": "",
+					"exportOrder": 0,
+					"exportWidth": 20,
+					"fieldKey": "field112",
+					"isExport": true,
+					"isListShow": true,
+					"isMasked": false,
+					"isSearchable": false,
+					"listAlign": "left",
+					"listFixed": "",
+					"listFormatter": "none",
+					"listFormatterParam": "",
+					"listMinWidth": 100,
+					"listOrder": 0,
+					"listOverflow": "tooltip",
+					"listSortable": false,
+					"listWidth": 0,
+					"maskCustomRule": "",
+					"maskRule": "",
+					"searchDefaultValue": "",
+					"searchOrder": 0,
+					"searchPlaceholder": "",
+					"searchType": "LIKE",
+					"searchWidth": 200
+				},
+				"defaultValue": null,
+				"document": "https://element.eleme.cn/#/zh-CN/component/date-picker",
+				"formId": 112,
+				"label": "日期选择",
+				"labelWidth": null,
+				"layout": "colFormItem",
+				"regList": [],
+				"renderKey": "1121769148501493",
+				"required": true,
+				"showLabel": true,
+				"span": 24,
+				"tag": "el-date-picker",
+				"tagIcon": "date"
+			},
+			"__vModel__": "field112",
+			"clearable": true,
+			"disabled": false,
+			"format": "yyyy-MM-dd",
+			"placeholder": "请选择日期选择",
+			"readonly": false,
+			"style": {
+				"width": "100%"
+			},
+			"type": "date",
+			"value-format": "yyyy-MM-dd"
+		},
+		{
+			"__config__": {
+				"changeTag": true,
+				"customConfig": {
+					"dbColumnLength": null,
+					"dbColumnType": "DATE",
+					"dbDefaultValue": "",
+					"dbNullable": true,
+					"exportConvert": true,
+					"exportFormatter": "none",
+					"exportLabel": "",
+					"exportOrder": 0,
+					"exportWidth": 20,
+					"fieldKey": "field113",
+					"isExport": true,
+					"isListShow": true,
+					"isMasked": false,
+					"isSearchable": false,
+					"listAlign": "left",
+					"listFixed": "",
+					"listFormatter": "none",
+					"listFormatterParam": "",
+					"listMinWidth": 100,
+					"listOrder": 0,
+					"listOverflow": "tooltip",
+					"listSortable": false,
+					"listWidth": 0,
+					"maskCustomRule": "",
+					"maskRule": "",
+					"searchDefaultValue": "",
+					"searchOrder": 0,
+					"searchPlaceholder": "",
+					"searchType": "LIKE",
+					"searchWidth": 200
+				},
+				"defaultValue": null,
+				"document": "https://element.eleme.cn/#/zh-CN/component/date-picker",
+				"formId": 113,
+				"label": "日期范围",
+				"labelWidth": null,
+				"layout": "colFormItem",
+				"regList": [],
+				"renderKey": "1131769148503377",
+				"required": true,
+				"showLabel": true,
+				"span": 24,
+				"tag": "el-date-picker",
+				"tagIcon": "date-range"
+			},
+			"__vModel__": "field113",
+			"clearable": true,
+			"disabled": false,
+			"end-placeholder": "结束日期",
+			"format": "yyyy-MM-dd",
+			"range-separator": "至",
+			"readonly": false,
+			"start-placeholder": "开始日期",
+			"style": {
+				"width": "100%"
+			},
+			"type": "daterange",
+			"value-format": "yyyy-MM-dd"
+		},
+		{
+			"__config__": {
+				"changeTag": true,
+				"customConfig": {
+					"dbColumnLength": null,
+					"dbColumnType": "INT",
+					"dbDefaultValue": "",
+					"dbNullable": true,
+					"exportConvert": true,
+					"exportFormatter": "none",
+					"exportLabel": "",
+					"exportOrder": 0,
+					"exportWidth": 20,
+					"fieldKey": "field114",
+					"isExport": true,
+					"isListShow": true,
+					"isMasked": false,
+					"isSearchable": false,
+					"listAlign": "left",
+					"listFixed": "",
+					"listFormatter": "none",
+					"listFormatterParam": "",
+					"listMinWidth": 100,
+					"listOrder": 0,
+					"listOverflow": "tooltip",
+					"listSortable": false,
+					"listWidth": 0,
+					"maskCustomRule": "",
+					"maskRule": "",
+					"searchDefaultValue": "",
+					"searchOrder": 0,
+					"searchPlaceholder": "",
+					"searchType": "LIKE",
+					"searchWidth": 200
+				},
+				"defaultValue": 0,
+				"document": "https://element.eleme.cn/#/zh-CN/component/rate",
+				"formId": 114,
+				"label": "评分",
+				"labelWidth": null,
+				"layout": "colFormItem",
+				"regList": [],
+				"renderKey": "1141769148508876",
+				"required": true,
+				"showLabel": true,
+				"span": 24,
+				"tag": "el-rate",
+				"tagIcon": "rate"
+			},
+			"__vModel__": "field114",
+			"allow-half": false,
+			"disabled": false,
+			"max": 5,
+			"show-score": false,
+			"show-text": false,
+			"style": {}
+		},
+		{
+			"__config__": {
+				"buttonText": "点击上传",
+				"changeTag": true,
+				"customConfig": {
+					"dbColumnLength": null,
+					"dbColumnType": "TEXT",
+					"dbDefaultValue": "",
+					"dbNullable": true,
+					"exportConvert": true,
+					"exportFormatter": "none",
+					"exportLabel": "",
+					"exportOrder": 0,
+					"exportWidth": 20,
+					"fieldKey": "field115",
+					"isExport": true,
+					"isListShow": true,
+					"isMasked": false,
+					"isSearchable": false,
+					"listAlign": "left",
+					"listFixed": "",
+					"listFormatter": "none",
+					"listFormatterParam": "",
+					"listMinWidth": 100,
+					"listOrder": 0,
+					"listOverflow": "tooltip",
+					"listSortable": false,
+					"listWidth": 0,
+					"maskCustomRule": "",
+					"maskRule": "",
+					"searchDefaultValue": "",
+					"searchOrder": 0,
+					"searchPlaceholder": "",
+					"searchType": "LIKE",
+					"searchWidth": 200
+				},
+				"defaultValue": null,
+				"document": "https://element.eleme.cn/#/zh-CN/component/upload",
+				"fileSize": 2,
+				"formId": 115,
+				"label": "上传",
+				"labelWidth": null,
+				"layout": "colFormItem",
+				"regList": [],
+				"renderKey": "1151769148510443",
+				"required": true,
+				"showLabel": true,
+				"showTip": false,
+				"sizeUnit": "MB",
+				"span": 24,
+				"tag": "el-upload",
+				"tagIcon": "upload"
+			},
+			"__slot__": {
+				"list-type": true
+			},
+			"__vModel__": "field115",
+			"accept": "",
+			"action": "https://jsonplaceholder.typicode.com/posts/",
+			"auto-upload": true,
+			"disabled": false,
+			"list-type": "text",
+			"multiple": false,
+			"name": "file"
+		}
+	],
+	"formBtns": true,
+	"formModel": "formData",
+	"formRef": "elForm",
+	"formRules": "rules",
+	"gutter": 15,
+	"labelPosition": "right",
+	"labelWidth": 100,
+	"size": "medium",
+	"span": 24
+}

+ 2 - 2
pages_task/index.vue

@@ -43,7 +43,7 @@
 </template>
 
 <script>
-	import {getDictByKey} from '@/api/common.js'
+	//import {getDictByKey} from '@/api/common.js'
 	import {getQuestionsList} from '@/api/index.js'
 	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
 	import Server from '@/components/Server.vue'
@@ -80,7 +80,7 @@
 			};
 		},
 		onShow() {
-			this.getDictByKey("sys_questions_type");
+			//this.getDictByKey("sys_questions_type");
 		},
 		methods:{
 			getDictByKey(key){

+ 981 - 0
pages_task/json.json

@@ -0,0 +1,981 @@
+{
+    "fields": [
+        {
+            "__config__": {
+                "changeTag": true,
+                "customConfig": {
+                    "dbColumnLength": 255,
+                    "dbColumnType": "VARCHAR",
+                    "dbDefaultValue": "",
+                    "dbNullable": true,
+                    "exportConvert": true,
+                    "exportFormatter": "none",
+                    "exportLabel": "",
+                    "exportOrder": 0,
+                    "exportWidth": 20,
+                    "fieldKey": "field101",
+                    "isExport": true,
+                    "isListShow": true,
+                    "isMasked": false,
+                    "isSearchable": false,
+                    "listAlign": "left",
+                    "listFixed": "",
+                    "listFormatter": "none",
+                    "listFormatterParam": "",
+                    "listMinWidth": 100,
+                    "listOrder": 0,
+                    "listOverflow": "tooltip",
+                    "listSortable": false,
+                    "listWidth": 0,
+                    "maskCustomRule": "",
+                    "maskRule": "",
+                    "searchDefaultValue": "",
+                    "searchOrder": 0,
+                    "searchPlaceholder": "",
+                    "searchType": "LIKE",
+                    "searchWidth": 200
+                },
+                "document": "https://element.eleme.cn/#/zh-CN/component/input",
+                "formId": 101,
+                "label": "单行文本",
+                "labelWidth": null,
+                "layout": "colFormItem",
+                "regList": [
+                ],
+                "renderKey": "1011769148485798",
+                "required": true,
+                "showLabel": true,
+                "span": 24,
+                "tag": "el-input",
+                "tagIcon": "input"
+            },
+            "__slot__": {
+                "append": "",
+                "prepend": ""
+            },
+            "__vModel__": "field101",
+            "clearable": true,
+            "disabled": false,
+            "maxlength": null,
+            "placeholder": "请输入单行文本",
+            "prefix-icon": "",
+            "readonly": false,
+            "show-word-limit": false,
+            "style": {
+                "width": "100%"
+            },
+            "suffix-icon": ""
+        },
+        {
+            "__config__": {
+                "changeTag": true,
+                "customConfig": {
+                    "dbColumnLength": 255,
+                    "dbColumnType": "VARCHAR",
+                    "dbDefaultValue": "",
+                    "dbNullable": true,
+                    "exportConvert": true,
+                    "exportFormatter": "none",
+                    "exportLabel": "",
+                    "exportOrder": 0,
+                    "exportWidth": 20,
+                    "fieldKey": "field103",
+                    "isExport": true,
+                    "isListShow": true,
+                    "isMasked": false,
+                    "isSearchable": false,
+                    "listAlign": "left",
+                    "listFixed": "",
+                    "listFormatter": "none",
+                    "listFormatterParam": "",
+                    "listMinWidth": 100,
+                    "listOrder": 0,
+                    "listOverflow": "tooltip",
+                    "listSortable": false,
+                    "listWidth": 0,
+                    "maskCustomRule": "",
+                    "maskRule": "",
+                    "searchDefaultValue": "",
+                    "searchOrder": 0,
+                    "searchPlaceholder": "",
+                    "searchType": "LIKE",
+                    "searchWidth": 200
+                },
+                "document": "https://element.eleme.cn/#/zh-CN/component/input",
+                "formId": 103,
+                "label": "密码",
+                "labelWidth": null,
+                "layout": "colFormItem",
+                "regList": [
+                ],
+                "renderKey": "1031769148487426",
+                "required": true,
+                "showLabel": true,
+                "span": 24,
+                "tag": "el-input",
+                "tagIcon": "password"
+            },
+            "__slot__": {
+                "append": "",
+                "prepend": ""
+            },
+            "__vModel__": "field103",
+            "clearable": true,
+            "disabled": false,
+            "maxlength": null,
+            "placeholder": "请输入密码",
+            "prefix-icon": "",
+            "readonly": false,
+            "show-password": true,
+            "show-word-limit": false,
+            "style": {
+                "width": "100%"
+            },
+            "suffix-icon": ""
+        },
+        {
+            "__config__": {
+                "changeTag": true,
+                "customConfig": {
+                    "dbColumnLength": null,
+                    "dbColumnType": "INT",
+                    "dbDefaultValue": "",
+                    "dbNullable": true,
+                    "exportConvert": true,
+                    "exportFormatter": "none",
+                    "exportLabel": "",
+                    "exportOrder": 0,
+                    "exportWidth": 20,
+                    "fieldKey": "field104",
+                    "isExport": true,
+                    "isListShow": true,
+                    "isMasked": false,
+                    "isSearchable": false,
+                    "listAlign": "left",
+                    "listFixed": "",
+                    "listFormatter": "none",
+                    "listFormatterParam": "",
+                    "listMinWidth": 100,
+                    "listOrder": 0,
+                    "listOverflow": "tooltip",
+                    "listSortable": false,
+                    "listWidth": 0,
+                    "maskCustomRule": "",
+                    "maskRule": "",
+                    "searchDefaultValue": "",
+                    "searchOrder": 0,
+                    "searchPlaceholder": "",
+                    "searchType": "LIKE",
+                    "searchWidth": 200
+                },
+                "document": "https://element.eleme.cn/#/zh-CN/component/input-number",
+                "formId": 104,
+                "label": "计数器",
+                "labelWidth": null,
+                "layout": "colFormItem",
+                "regList": [
+                ],
+                "renderKey": "1041769148488690",
+                "required": true,
+                "showLabel": true,
+                "span": 24,
+                "tag": "el-input-number",
+                "tagIcon": "number"
+            },
+            "__vModel__": "field104",
+            "controls-position": "",
+            "disabled": false,
+            "placeholder": "计数器",
+            "step": 1,
+            "step-strictly": false
+        },
+        {
+            "__config__": {
+                "changeTag": true,
+                "customConfig": {
+                    "dbColumnLength": 255,
+                    "dbColumnType": "VARCHAR",
+                    "dbDefaultValue": "",
+                    "dbNullable": true,
+                    "exportConvert": true,
+                    "exportFormatter": "none",
+                    "exportLabel": "",
+                    "exportOrder": 0,
+                    "exportWidth": 20,
+                    "fieldKey": "field105",
+                    "isExport": true,
+                    "isListShow": true,
+                    "isMasked": false,
+                    "isSearchable": false,
+                    "listAlign": "left",
+                    "listFixed": "",
+                    "listFormatter": "none",
+                    "listFormatterParam": "",
+                    "listMinWidth": 100,
+                    "listOrder": 0,
+                    "listOverflow": "tooltip",
+                    "listSortable": false,
+                    "listWidth": 0,
+                    "maskCustomRule": "",
+                    "maskRule": "",
+                    "searchDefaultValue": "",
+                    "searchOrder": 0,
+                    "searchPlaceholder": "",
+                    "searchType": "LIKE",
+                    "searchWidth": 200
+                },
+                "document": "https://element.eleme.cn/#/zh-CN/component/select",
+                "formId": 105,
+                "label": "下拉选择",
+                "labelWidth": null,
+                "layout": "colFormItem",
+                "regList": [
+                ],
+                "renderKey": "1051769148490140",
+                "required": true,
+                "showLabel": true,
+                "span": 24,
+                "tag": "el-select",
+                "tagIcon": "select"
+            },
+            "__slot__": {
+                "options": [
+                    {
+                        "label": "选项一",
+                        "value": 1
+                    },
+                    {
+                        "label": "选项二",
+                        "value": 2
+                    }
+                ]
+            },
+            "__vModel__": "field105",
+            "clearable": true,
+            "disabled": false,
+            "filterable": false,
+            "multiple": false,
+            "placeholder": "请选择下拉选择",
+            "style": {
+                "width": "100%"
+            }
+        },
+        {
+            "__config__": {
+                "changeTag": true,
+                "customConfig": {
+                    "dbColumnLength": 255,
+                    "dbColumnType": "VARCHAR",
+                    "dbDefaultValue": "",
+                    "dbNullable": true,
+                    "exportConvert": true,
+                    "exportFormatter": "none",
+                    "exportLabel": "",
+                    "exportOrder": 0,
+                    "exportWidth": 20,
+                    "fieldKey": "field102",
+                    "isExport": true,
+                    "isListShow": true,
+                    "isMasked": false,
+                    "isSearchable": false,
+                    "listAlign": "left",
+                    "listFixed": "",
+                    "listFormatter": "none",
+                    "listFormatterParam": "",
+                    "listMinWidth": 100,
+                    "listOrder": 0,
+                    "listOverflow": "tooltip",
+                    "listSortable": false,
+                    "listWidth": 0,
+                    "maskCustomRule": "",
+                    "maskRule": "",
+                    "searchDefaultValue": "",
+                    "searchOrder": 0,
+                    "searchPlaceholder": "",
+                    "searchType": "LIKE",
+                    "searchWidth": 200
+                },
+                "document": "https://element.eleme.cn/#/zh-CN/component/input",
+                "formId": 102,
+                "label": "多行文本",
+                "labelWidth": null,
+                "layout": "colFormItem",
+                "regList": [
+                ],
+                "renderKey": "1021769148486625",
+                "required": true,
+                "showLabel": true,
+                "span": 24,
+                "tag": "el-input",
+                "tagIcon": "textarea"
+            },
+            "__vModel__": "field102",
+            "autosize": {
+                "maxRows": 4,
+                "minRows": 4
+            },
+            "disabled": false,
+            "maxlength": null,
+            "placeholder": "请输入多行文本",
+            "readonly": false,
+            "show-word-limit": false,
+            "style": {
+                "width": "100%"
+            },
+            "type": "textarea"
+        },
+        {
+            "__config__": {
+                "border": false,
+                "changeTag": true,
+                "customConfig": {
+                    "dbColumnLength": 255,
+                    "dbColumnType": "VARCHAR",
+                    "dbDefaultValue": "",
+                    "dbNullable": true,
+                    "exportConvert": true,
+                    "exportFormatter": "none",
+                    "exportLabel": "",
+                    "exportOrder": 0,
+                    "exportWidth": 20,
+                    "fieldKey": "field106",
+                    "isExport": true,
+                    "isListShow": true,
+                    "isMasked": false,
+                    "isSearchable": false,
+                    "listAlign": "left",
+                    "listFixed": "",
+                    "listFormatter": "none",
+                    "listFormatterParam": "",
+                    "listMinWidth": 100,
+                    "listOrder": 0,
+                    "listOverflow": "tooltip",
+                    "listSortable": false,
+                    "listWidth": 0,
+                    "maskCustomRule": "",
+                    "maskRule": "",
+                    "searchDefaultValue": "",
+                    "searchOrder": 0,
+                    "searchPlaceholder": "",
+                    "searchType": "LIKE",
+                    "searchWidth": 200
+                },
+                "document": "https://element.eleme.cn/#/zh-CN/component/radio",
+                "formId": 106,
+                "label": "单选框组",
+                "labelWidth": null,
+                "layout": "colFormItem",
+                "optionType": "default",
+                "regList": [
+                ],
+                "renderKey": "1061769148491043",
+                "required": true,
+                "showLabel": true,
+                "span": 24,
+                "tag": "el-radio-group",
+                "tagIcon": "radio"
+            },
+            "__slot__": {
+                "options": [
+                    {
+                        "label": "选项一",
+                        "value": 1
+                    },
+                    {
+                        "label": "选项二",
+                        "value": 2
+                    }
+                ]
+            },
+            "__vModel__": "field106",
+            "disabled": false,
+            "size": "medium",
+            "style": {
+            }
+        },
+        {
+            "__config__": {
+                "border": false,
+                "changeTag": true,
+                "customConfig": {
+                    "dbColumnLength": 255,
+                    "dbColumnType": "VARCHAR",
+                    "dbDefaultValue": "",
+                    "dbNullable": true,
+                    "exportConvert": true,
+                    "exportFormatter": "none",
+                    "exportLabel": "",
+                    "exportOrder": 0,
+                    "exportWidth": 20,
+                    "fieldKey": "field107",
+                    "isExport": true,
+                    "isListShow": true,
+                    "isMasked": false,
+                    "isSearchable": false,
+                    "listAlign": "left",
+                    "listFixed": "",
+                    "listFormatter": "none",
+                    "listFormatterParam": "",
+                    "listMinWidth": 100,
+                    "listOrder": 0,
+                    "listOverflow": "tooltip",
+                    "listSortable": false,
+                    "listWidth": 0,
+                    "maskCustomRule": "",
+                    "maskRule": "",
+                    "searchDefaultValue": "",
+                    "searchOrder": 0,
+                    "searchPlaceholder": "",
+                    "searchType": "LIKE",
+                    "searchWidth": 200
+                },
+                "defaultValue": [
+                ],
+                "document": "https://element.eleme.cn/#/zh-CN/component/checkbox",
+                "formId": 107,
+                "label": "多选框组",
+                "labelWidth": null,
+                "layout": "colFormItem",
+                "optionType": "default",
+                "regList": [
+                ],
+                "renderKey": "1071769148492223",
+                "required": true,
+                "showLabel": true,
+                "span": 24,
+                "tag": "el-checkbox-group",
+                "tagIcon": "checkbox"
+            },
+            "__slot__": {
+                "options": [
+                    {
+                        "label": "选项一",
+                        "value": 1
+                    },
+                    {
+                        "label": "选项二",
+                        "value": 2
+                    }
+                ]
+            },
+            "__vModel__": "field107",
+            "disabled": false,
+            "size": "medium",
+            "style": {
+            }
+        },
+        {
+            "__config__": {
+                "changeTag": true,
+                "customConfig": {
+                    "dbColumnLength": 255,
+                    "dbColumnType": "VARCHAR",
+                    "dbDefaultValue": "",
+                    "dbNullable": true,
+                    "exportConvert": true,
+                    "exportFormatter": "none",
+                    "exportLabel": "",
+                    "exportOrder": 0,
+                    "exportWidth": 20,
+                    "fieldKey": "field109",
+                    "isExport": true,
+                    "isListShow": true,
+                    "isMasked": false,
+                    "isSearchable": false,
+                    "listAlign": "left",
+                    "listFixed": "",
+                    "listFormatter": "none",
+                    "listFormatterParam": "",
+                    "listMinWidth": 100,
+                    "listOrder": 0,
+                    "listOverflow": "tooltip",
+                    "listSortable": false,
+                    "listWidth": 0,
+                    "maskCustomRule": "",
+                    "maskRule": "",
+                    "searchDefaultValue": "",
+                    "searchOrder": 0,
+                    "searchPlaceholder": "",
+                    "searchType": "LIKE",
+                    "searchWidth": 200
+                },
+                "defaultValue": null,
+                "document": "https://element.eleme.cn/#/zh-CN/component/time-picker",
+                "formId": 109,
+                "label": "时间选择",
+                "labelWidth": null,
+                "layout": "colFormItem",
+                "regList": [
+                ],
+                "renderKey": "1091769148494476",
+                "required": true,
+                "showLabel": true,
+                "span": 24,
+                "tag": "el-time-picker",
+                "tagIcon": "time"
+            },
+            "__vModel__": "field109",
+            "clearable": true,
+            "disabled": false,
+            "format": "HH:mm:ss",
+            "picker-options": {
+                "selectableRange": "00:00:00-23:59:59"
+            },
+            "placeholder": "请选择时间选择",
+            "style": {
+                "width": "100%"
+            },
+            "value-format": "HH:mm:ss"
+        },
+        {
+            "__config__": {
+                "changeTag": true,
+                "customConfig": {
+                    "dbColumnLength": null,
+                    "dbColumnType": "TINYINT",
+                    "dbDefaultValue": "",
+                    "dbNullable": true,
+                    "exportConvert": true,
+                    "exportFormatter": "none",
+                    "exportLabel": "",
+                    "exportOrder": 0,
+                    "exportWidth": 20,
+                    "fieldKey": "field108",
+                    "isExport": true,
+                    "isListShow": true,
+                    "isMasked": false,
+                    "isSearchable": false,
+                    "listAlign": "left",
+                    "listFixed": "",
+                    "listFormatter": "none",
+                    "listFormatterParam": "",
+                    "listMinWidth": 100,
+                    "listOrder": 0,
+                    "listOverflow": "tooltip",
+                    "listSortable": false,
+                    "listWidth": 0,
+                    "maskCustomRule": "",
+                    "maskRule": "",
+                    "searchDefaultValue": "",
+                    "searchOrder": 0,
+                    "searchPlaceholder": "",
+                    "searchType": "LIKE",
+                    "searchWidth": 200
+                },
+                "defaultValue": false,
+                "document": "https://element.eleme.cn/#/zh-CN/component/switch",
+                "formId": 108,
+                "label": "开关",
+                "labelWidth": null,
+                "layout": "colFormItem",
+                "regList": [
+                ],
+                "renderKey": "1081769148493243",
+                "required": true,
+                "showLabel": true,
+                "span": 24,
+                "tag": "el-switch",
+                "tagIcon": "switch"
+            },
+            "__vModel__": "field108",
+            "active-color": null,
+            "active-text": "",
+            "active-value": true,
+            "disabled": false,
+            "inactive-color": null,
+            "inactive-text": "",
+            "inactive-value": false,
+            "style": {
+            }
+        },
+        {
+            "__config__": {
+                "changeTag": true,
+                "customConfig": {
+                    "dbColumnLength": 255,
+                    "dbColumnType": "VARCHAR",
+                    "dbDefaultValue": "",
+                    "dbNullable": true,
+                    "exportConvert": true,
+                    "exportFormatter": "none",
+                    "exportLabel": "",
+                    "exportOrder": 0,
+                    "exportWidth": 20,
+                    "fieldKey": "field110",
+                    "isExport": true,
+                    "isListShow": true,
+                    "isMasked": false,
+                    "isSearchable": false,
+                    "listAlign": "left",
+                    "listFixed": "",
+                    "listFormatter": "none",
+                    "listFormatterParam": "",
+                    "listMinWidth": 100,
+                    "listOrder": 0,
+                    "listOverflow": "tooltip",
+                    "listSortable": false,
+                    "listWidth": 0,
+                    "maskCustomRule": "",
+                    "maskRule": "",
+                    "searchDefaultValue": "",
+                    "searchOrder": 0,
+                    "searchPlaceholder": "",
+                    "searchType": "LIKE",
+                    "searchWidth": 200
+                },
+                "defaultValue": null,
+                "document": "https://element.eleme.cn/#/zh-CN/component/time-picker",
+                "formId": 110,
+                "label": "时间选择",
+                "labelWidth": null,
+                "layout": "colFormItem",
+                "regList": [
+                ],
+                "renderKey": "1101769148497460",
+                "required": true,
+                "showLabel": true,
+                "span": 24,
+                "tag": "el-time-picker",
+                "tagIcon": "time"
+            },
+            "__vModel__": "field110",
+            "clearable": true,
+            "disabled": false,
+            "format": "HH:mm:ss",
+            "picker-options": {
+                "selectableRange": "00:00:00-23:59:59"
+            },
+            "placeholder": "请选择时间选择",
+            "style": {
+                "width": "100%"
+            },
+            "value-format": "HH:mm:ss"
+        },
+        {
+            "__config__": {
+                "changeTag": true,
+                "customConfig": {
+                    "dbColumnLength": 255,
+                    "dbColumnType": "VARCHAR",
+                    "dbDefaultValue": "",
+                    "dbNullable": true,
+                    "exportConvert": true,
+                    "exportFormatter": "none",
+                    "exportLabel": "",
+                    "exportOrder": 0,
+                    "exportWidth": 20,
+                    "fieldKey": "field111",
+                    "isExport": true,
+                    "isListShow": true,
+                    "isMasked": false,
+                    "isSearchable": false,
+                    "listAlign": "left",
+                    "listFixed": "",
+                    "listFormatter": "none",
+                    "listFormatterParam": "",
+                    "listMinWidth": 100,
+                    "listOrder": 0,
+                    "listOverflow": "tooltip",
+                    "listSortable": false,
+                    "listWidth": 0,
+                    "maskCustomRule": "",
+                    "maskRule": "",
+                    "searchDefaultValue": "",
+                    "searchOrder": 0,
+                    "searchPlaceholder": "",
+                    "searchType": "LIKE",
+                    "searchWidth": 200
+                },
+                "defaultValue": [
+                    "14:08:25",
+                    "15:08:25"
+                ],
+                "document": "https://element.eleme.cn/#/zh-CN/component/time-picker",
+                "formId": 111,
+                "label": "时间范围",
+                "labelWidth": null,
+                "layout": "colFormItem",
+                "regList": [
+                ],
+                "renderKey": "1111769148499332",
+                "required": true,
+                "showLabel": true,
+                "span": 24,
+                "tag": "el-time-picker",
+                "tagIcon": "time-range"
+            },
+            "__vModel__": "field111",
+            "clearable": true,
+            "disabled": false,
+            "end-placeholder": "结束时间",
+            "format": "HH:mm:ss",
+            "is-range": true,
+            "range-separator": "至",
+            "start-placeholder": "开始时间",
+            "style": {
+                "width": "100%"
+            },
+            "value-format": "HH:mm:ss"
+        },
+        {
+            "__config__": {
+                "changeTag": true,
+                "customConfig": {
+                    "dbColumnLength": null,
+                    "dbColumnType": "DATE",
+                    "dbDefaultValue": "",
+                    "dbNullable": true,
+                    "exportConvert": true,
+                    "exportFormatter": "none",
+                    "exportLabel": "",
+                    "exportOrder": 0,
+                    "exportWidth": 20,
+                    "fieldKey": "field112",
+                    "isExport": true,
+                    "isListShow": true,
+                    "isMasked": false,
+                    "isSearchable": false,
+                    "listAlign": "left",
+                    "listFixed": "",
+                    "listFormatter": "none",
+                    "listFormatterParam": "",
+                    "listMinWidth": 100,
+                    "listOrder": 0,
+                    "listOverflow": "tooltip",
+                    "listSortable": false,
+                    "listWidth": 0,
+                    "maskCustomRule": "",
+                    "maskRule": "",
+                    "searchDefaultValue": "",
+                    "searchOrder": 0,
+                    "searchPlaceholder": "",
+                    "searchType": "LIKE",
+                    "searchWidth": 200
+                },
+                "defaultValue": null,
+                "document": "https://element.eleme.cn/#/zh-CN/component/date-picker",
+                "formId": 112,
+                "label": "日期选择",
+                "labelWidth": null,
+                "layout": "colFormItem",
+                "regList": [
+                ],
+                "renderKey": "1121769148501493",
+                "required": true,
+                "showLabel": true,
+                "span": 24,
+                "tag": "el-date-picker",
+                "tagIcon": "date"
+            },
+            "__vModel__": "field112",
+            "clearable": true,
+            "disabled": false,
+            "format": "yyyy-MM-dd",
+            "placeholder": "请选择日期选择",
+            "readonly": false,
+            "style": {
+                "width": "100%"
+            },
+            "type": "date",
+            "value-format": "yyyy-MM-dd"
+        },
+        {
+            "__config__": {
+                "changeTag": true,
+                "customConfig": {
+                    "dbColumnLength": null,
+                    "dbColumnType": "DATE",
+                    "dbDefaultValue": "",
+                    "dbNullable": true,
+                    "exportConvert": true,
+                    "exportFormatter": "none",
+                    "exportLabel": "",
+                    "exportOrder": 0,
+                    "exportWidth": 20,
+                    "fieldKey": "field113",
+                    "isExport": true,
+                    "isListShow": true,
+                    "isMasked": false,
+                    "isSearchable": false,
+                    "listAlign": "left",
+                    "listFixed": "",
+                    "listFormatter": "none",
+                    "listFormatterParam": "",
+                    "listMinWidth": 100,
+                    "listOrder": 0,
+                    "listOverflow": "tooltip",
+                    "listSortable": false,
+                    "listWidth": 0,
+                    "maskCustomRule": "",
+                    "maskRule": "",
+                    "searchDefaultValue": "",
+                    "searchOrder": 0,
+                    "searchPlaceholder": "",
+                    "searchType": "LIKE",
+                    "searchWidth": 200
+                },
+                "defaultValue": null,
+                "document": "https://element.eleme.cn/#/zh-CN/component/date-picker",
+                "formId": 113,
+                "label": "日期范围",
+                "labelWidth": null,
+                "layout": "colFormItem",
+                "regList": [
+                ],
+                "renderKey": "1131769148503377",
+                "required": true,
+                "showLabel": true,
+                "span": 24,
+                "tag": "el-date-picker",
+                "tagIcon": "date-range"
+            },
+            "__vModel__": "field113",
+            "clearable": true,
+            "disabled": false,
+            "end-placeholder": "结束日期",
+            "format": "yyyy-MM-dd",
+            "range-separator": "至",
+            "readonly": false,
+            "start-placeholder": "开始日期",
+            "style": {
+                "width": "100%"
+            },
+            "type": "daterange",
+            "value-format": "yyyy-MM-dd"
+        },
+        {
+            "__config__": {
+                "changeTag": true,
+                "customConfig": {
+                    "dbColumnLength": null,
+                    "dbColumnType": "INT",
+                    "dbDefaultValue": "",
+                    "dbNullable": true,
+                    "exportConvert": true,
+                    "exportFormatter": "none",
+                    "exportLabel": "",
+                    "exportOrder": 0,
+                    "exportWidth": 20,
+                    "fieldKey": "field114",
+                    "isExport": true,
+                    "isListShow": true,
+                    "isMasked": false,
+                    "isSearchable": false,
+                    "listAlign": "left",
+                    "listFixed": "",
+                    "listFormatter": "none",
+                    "listFormatterParam": "",
+                    "listMinWidth": 100,
+                    "listOrder": 0,
+                    "listOverflow": "tooltip",
+                    "listSortable": false,
+                    "listWidth": 0,
+                    "maskCustomRule": "",
+                    "maskRule": "",
+                    "searchDefaultValue": "",
+                    "searchOrder": 0,
+                    "searchPlaceholder": "",
+                    "searchType": "LIKE",
+                    "searchWidth": 200
+                },
+                "defaultValue": 0,
+                "document": "https://element.eleme.cn/#/zh-CN/component/rate",
+                "formId": 114,
+                "label": "评分",
+                "labelWidth": null,
+                "layout": "colFormItem",
+                "regList": [
+                ],
+                "renderKey": "1141769148508876",
+                "required": true,
+                "showLabel": true,
+                "span": 24,
+                "tag": "el-rate",
+                "tagIcon": "rate"
+            },
+            "__vModel__": "field114",
+            "allow-half": false,
+            "disabled": false,
+            "max": 5,
+            "show-score": false,
+            "show-text": false,
+            "style": {
+            }
+        },
+        {
+            "__config__": {
+                "buttonText": "点击上传",
+                "changeTag": true,
+                "customConfig": {
+                    "dbColumnLength": null,
+                    "dbColumnType": "TEXT",
+                    "dbDefaultValue": "",
+                    "dbNullable": true,
+                    "exportConvert": true,
+                    "exportFormatter": "none",
+                    "exportLabel": "",
+                    "exportOrder": 0,
+                    "exportWidth": 20,
+                    "fieldKey": "field115",
+                    "isExport": true,
+                    "isListShow": true,
+                    "isMasked": false,
+                    "isSearchable": false,
+                    "listAlign": "left",
+                    "listFixed": "",
+                    "listFormatter": "none",
+                    "listFormatterParam": "",
+                    "listMinWidth": 100,
+                    "listOrder": 0,
+                    "listOverflow": "tooltip",
+                    "listSortable": false,
+                    "listWidth": 0,
+                    "maskCustomRule": "",
+                    "maskRule": "",
+                    "searchDefaultValue": "",
+                    "searchOrder": 0,
+                    "searchPlaceholder": "",
+                    "searchType": "LIKE",
+                    "searchWidth": 200
+                },
+                "defaultValue": null,
+                "document": "https://element.eleme.cn/#/zh-CN/component/upload",
+                "fileSize": 2,
+                "formId": 115,
+                "label": "上传",
+                "labelWidth": null,
+                "layout": "colFormItem",
+                "regList": [
+                ],
+                "renderKey": "1151769148510443",
+                "required": true,
+                "showLabel": true,
+                "showTip": false,
+                "sizeUnit": "MB",
+                "span": 24,
+                "tag": "el-upload",
+                "tagIcon": "upload"
+            },
+            "__slot__": {
+                "list-type": true
+            },
+            "__vModel__": "field115",
+            "accept": "",
+            "action": "https://jsonplaceholder.typicode.com/posts/",
+            "auto-upload": true,
+            "disabled": false,
+            "list-type": "text",
+            "multiple": false,
+            "name": "file"
+        }
+    ],
+    "formBtns": true,
+    "formModel": "formData",
+    "formRef": "elForm",
+    "formRules": "rules",
+    "gutter": 15,
+    "labelPosition": "right",
+    "labelWidth": 100,
+    "size": "medium",
+    "span": 24
+}

+ 196 - 134
pages_task/airClassroom.vue → pages_task/longVideo.vue

@@ -17,65 +17,75 @@
 				<image class="w32 h32" src="@/static/image/icon_select.png" mode=""></image>
 			</view>
 		</view>
+		
 		<!-- 任务列表 -->
 		<scroll-view class="content" scroll-y>
 			<view class="task-card" v-for="(item, index) in taskList" :key="index" @click="showDetail(item)">
 				<view class="card-header">
-					<view class="card-title">{{ item.title }}</view>
-					<view class="status-tag" :class="item.status">
-						{{ item.statusText }}
+					<view class="card-title">{{ item.taskName}}</view>
+					<view class="status-tag" :class="'tag'+item.finishAuditStatus">
+						{{ item.finishAuditStatus==0?'待审核':item.finishAuditStatus==1?'已通过':item.finishAuditStatus==2?'已驳回':'未完成'}}
 					</view>
 				</view>
+				<view style="padding: 24rpx;">
 				<view class="card-tags">
-				<view class="x-f">
-					<view class="tag-item video-tag" v-if="item.videoType">
-						<image class="w28 h28 mr10" src="@/static/image/icon_longvideo.png" mode=""></image>
-						<text>{{ item.videoType }}</text>
-						
-					</view>
-					<view class="tag-item category" v-if="item.category">
-						{{ item.category }}
+					<view class="x-f">
+						<view class="tag-item video-tag" v-if="item.taskType">
+							<!-- <image class="w28 h28 mr10" src="@/static/image/icon_longvideo.png" mode=""></image> -->
+							<image class="w28 h28 mr10" src="@/static/image/icon_article.png" mode=""></image>
+							<text>{{ item.taskType==4?'文章':taskData.taskType==5?'短视频':'长视频'}}</text>
+							
+						</view>
+						<view class="tag-item category">
+							学术
+						</view>
 					</view>
-				</view>
-				
+					
 					<view class="tag-item points-tag">
-						{{ item.points }}积分
+						{{ item.taskIntegral }}积分
 					</view>
 					<view class="tag-item">
-						{{ item.count }}个
+						{{ item.taskCount }}{{item.taskUnitName}}
 					</view>
 				</view>
 				
 				<view class="card-dates">
 					<view class="date-item">
-						<text>开始时间: {{ item.startTime }}</text>
+						<text>开始时间:{{ item.planStartTime }}</text>
 					</view>
 					<view class="date-item">
-						<text>结束时间: {{ item.endTime }}</text>
+						<text>结束时间:{{ item.planEndTime }}</text>
 					</view>
 				</view>
 				
 				<view class="card-warning" v-if="item.warning">
-					<text class="warning-icon">⚠</text>
+					<image class="w28 h28 mr8" src="@/static/image/icon_admonish.png" mode=""></image>
 					<text>{{ item.warning }}</text>
 				</view>
 				
-				<view class="card-rejection" v-if="item.rejectionReason">
-					<text class="rejection-icon">❌</text>
-					<text>驳回原因: {{ item.rejectionReason }}</text>
+				<view class="card-rejection" v-if="item.finishAuditStatus == 2">
+					<image class="w28 h28 mr8" src="@/static/image/icon_reject.png" mode=""></image>
+					<text>驳回原因: {{ item.finishAuditRemark}}</text>
 				</view>
 				
 				<view class="card-footer">
 					<view class="footer-date">{{ item.createTime }}</view>
 					<view class="footer-actions">
-						<view class="action-btn" v-if="item.status === 'pending'" @click="goComplete(item)">
+						<view class="action-btn" v-if="item.finishAuditStatus==3">
 							去完成
 						</view>
-						<view class="action-btn" v-if="item.status === 'rejected'" @click="goEdit(item)">
+						<view class="action-btn" v-if="item.finishAuditStatus == 2" @click="goEdit(item)">
 							编辑
 						</view>
 					</view>
 				</view>
+				</view>
+			</view>
+			
+			<view class="no-more" v-if="!hasMore && taskList.length > 0">没有更多了~</view>
+			<view class="empty-state y-bc" v-if="taskList.length === 0">
+				<image class="w300 h300" src="@/static/image/img_blank_nodata.png" mode=""></image>
+				<text>暂无数据</text>
 			</view>
 		</scroll-view>
 		
@@ -93,13 +103,13 @@
 				<view class="filter-group">
 					<view class="group-label">申请时间</view>
 					<view class="date-range-inputs">
-						<picker  style="flex:1" mode="date" :value="tempDateRange.startDate" @change="onStartDateChange">
+						<picker style="flex:1" mode="date" :value="tempDateRange.startDate" @change="onStartDateChange">
 							<view class="date-input" :class="{ placeholder: !tempDateRange.startDate }">
 								{{ tempDateRange.startDate || '开始时间' }}
 							</view>
 						</picker>
 						<text class="date-separator">-</text>
-						<picker  style="flex:1" mode="date" :value="tempDateRange.endDate" @change="onEndDateChange">
+						<picker style="flex:1" mode="date" :value="tempDateRange.endDate" @change="onEndDateChange">
 							<view class="date-input" :class="{ placeholder: !tempDateRange.endDate }">
 								{{ tempDateRange.endDate || '结束时间' }}
 							</view>
@@ -107,6 +117,21 @@
 					</view>
 				</view>
 				
+				<!-- 任务类型筛选 -->
+				<!-- <view class="filter-group">
+					<view class="group-label">任务类型</view>
+					<view class="filter-tags">
+						<view 
+							class="filter-tag" 
+							:class="{ active: tempSelectedTaskType === item.value }"
+							v-for="(item, index) in taskTypeOptions" 
+							:key="index"
+							@click="selectTaskType(item.value)">
+							{{ item.label }}
+						</view>
+					</view>
+				</view> -->
+				
 				<!-- 操作按钮 -->
 				<view class="filter-actions">
 					<view class="reset-btn" @click="resetFilters">重置</view>
@@ -118,12 +143,13 @@
 </template>
 
 <script>
-import { getAirClassroomList } from '@/api-js/airClassroom'
+import { getAirClassroomList ,getTaskDetail,submitTask} from '@/api/airClassroom'
+import { getTaskTypeList } from '@/api/common.js'
 export default {
 	data() {
 		return {
 			statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
-			currentTab: 'all',
+			currentTab:'',
 			showFilter: false,
 			dateRange: {
 				startDate: '',
@@ -133,28 +159,43 @@ export default {
 				startDate: '',
 				endDate: ''
 			},
+			selectedTaskType: 'article', // 默认选中科普文章
+			tempSelectedTaskType: 'article',
+			// taskTypeOptions: [
+			// 	{ label: '科普文章', value: 'article' },
+			// 	{ label: '科普短视频', value: 'shortVideo' },
+			// 	{ label: '科普长视频', value: 'longVideo' }
+			// ],
 			tabs: [
-				{ label: '全部', value: 'all' },
-				{ label: '未完成', value: 'pending' },
-				{ label: '待审核', value: 'reviewing' },
-				{ label: '已通过', value: 'approved' },
-				{ label: '已驳回', value: 'rejected' }
+				{ label: '全部', value:''},
+				{ label: '未完成', value: 3},
+				{ label: '待审核', value: 0},
+				{ label: '已通过', value: 1},
+				{ label: '已驳回', value: 2}
 			],
-			taskList: []
+			taskList: [],
+			pageNum: 1,
+			pageSize: 10,
+			hasMore: true,
+			loading: false
 		}
 	},
 	watch: {
 		showFilter(newVal) {
 			if (newVal) {
-				// 打开弹窗时,同步临时日期范围为当前日期范围
+				// 打开弹窗时,同步临时日期范围和任务类型为当前值
 				this.tempDateRange = {
 					startDate: this.dateRange.startDate,
 					endDate: this.dateRange.endDate
 				}
+				this.tempSelectedTaskType = this.selectedTaskType
 			}
 		}
 	},
 	onLoad() {
+		
+	},
+	onShow() {
 		this.loadData()
 	},
 	onReachBottom() {
@@ -166,16 +207,27 @@ export default {
 		},
 		switchTab(value) {
 			this.currentTab = value
+			this.pageNum = 1
+			this.hasMore = true
 			this.loadData()
 		},
 		closeFilter() {
-			// 关闭弹窗时,恢复临时日期范围为当前日期范围
+			// 关闭弹窗时,恢复临时日期范围和任务类型为当前值
 			this.tempDateRange = {
 				startDate: this.dateRange.startDate,
 				endDate: this.dateRange.endDate
 			}
+			this.tempSelectedTaskType = this.selectedTaskType
 			this.showFilter = false
 		},
+		selectTaskType(value) {
+			// 如果点击的是已选中的,则取消选择
+			if (this.tempSelectedTaskType === value) {
+				this.tempSelectedTaskType = ''
+			} else {
+				this.tempSelectedTaskType = value
+			}
+		},
 		onStartDateChange(e) {
 			this.tempDateRange.startDate = e.detail.value
 		},
@@ -187,6 +239,7 @@ export default {
 				startDate: '',
 				endDate: ''
 			}
+			this.tempSelectedTaskType = ''
 		},
 		confirmFilters() {
 			// 验证日期范围
@@ -203,7 +256,10 @@ export default {
 				startDate: this.tempDateRange.startDate,
 				endDate: this.tempDateRange.endDate
 			}
+			this.selectedTaskType = this.tempSelectedTaskType
 			this.showFilter = false
+			this.pageNum = 1
+			this.hasMore = true
 			this.loadData()
 		},
 		goComplete(item) {
@@ -224,99 +280,85 @@ export default {
 		},
 		async loadData() {
 			try {
+				this.pageNum = 1
+				this.hasMore = true
 				uni.showLoading({ title: '加载中...' })
-				const res = await getAirClassroomList({
-					status: this.currentTab,
-					startDate: this.dateRange.startDate,
-					endDate: this.dateRange.endDate,
-					page: 1,
-					pageSize: 20
-				})
+				// 构建请求参数
+				const params = {
+					beginTime: this.dateRange.startDate,
+					endTime: this.dateRange.endDate,
+					finishAuditStatus:this.currentTab,
+					taskType:6,
+					pageNum: 1,
+					pageSize: this.pageSize
+				}
+				const res = await getAirClassroomList(params)
 				uni.hideLoading()
-				if (res.code === 200 && res.data) {
-					this.taskList = res.data.list || this.getDefaultData()
+				if (res.code === 200) {
+					this.taskList = res.rows || []
+					// 判断是否还有更多数据
+					if (!res.rows || res.rows.length < this.pageSize) {
+						this.hasMore = false
+					}
 				} else {
-					this.taskList = this.getDefaultData()
+					uni.showToast({
+						icon: 'none',
+						title: res.msg
+					})
 				}
 			} catch (e) {
 				uni.hideLoading()
-				console.error('加载数据失败', e)
-				this.taskList = this.getDefaultData()
 			}
 		},
 		async loadMore() {
-			// 加载更多数据
-		},
-		getDefaultData() {
-			return [
-				{
-					id: 1,
-					title: '王小明医生空中任务',
-					videoType: '长视频',
-					category: '学术',
-					points: '10',
-					count: '1',
-					startTime: '2025-9-20 13:55',
-					endTime: '2025-9-20 13:55',
-					createTime: '2025-9-20 13:55',
-					status: 'pending',
-					statusText: '待完成'
-				},
-				{
-					id: 2,
-					title: '王小明医生空中任务',
-					videoType: '长视频',
-					category: '学术',
-					points: '10',
-					count: '1',
-					startTime: '2025-9-20 13:55',
-					endTime: '2025-9-20 13:55',
-					createTime: '2025-9-20 13:55',
-					status: 'pending',
-					statusText: '待完成',
-					warning: '有效观看不足5人'
-				},
-				{
-					id: 3,
-					title: '王小明医生空中任务',
-					videoType: '短视频',
-					category: '学术',
-					points: '10',
-					count: '1',
-					startTime: '2025-9-20 13:55',
-					endTime: '2025-9-20 13:55',
-					createTime: '2025-9-20 13:55',
-					status: 'reviewing',
-					statusText: '待审核'
-				},
-				{
-					id: 4,
-					title: '王小明医生空中任务',
-					videoType: '文章',
-					category: '学术',
-					points: '10',
-					count: '1',
-					startTime: '2025-9-20 13:55',
-					endTime: '2025-9-20 13:55',
-					createTime: '2025-9-20 13:55',
-					status: 'rejected',
-					statusText: '已驳回',
-					rejectionReason: '交付物无效,请重新编辑'
-				},
-				{
-					id: 5,
-					title: '王小明医生空中任务',
-					videoType: '长视频',
-					category: '学术',
-					points: '10',
-					count: '1',
-					startTime: '2025-9-20 13:55',
-					endTime: '2025-9-20 13:55',
-					createTime: '2025-9-20 13:55',
-					status: 'approved',
-					statusText: '已通过'
+			// 如果没有更多数据或正在加载,则不执行
+			if (!this.hasMore || this.loading) {
+				return
+			}
+			
+			try {
+				this.loading = true
+				const nextPage = this.pageNum + 1
+				// 构建请求参数
+				const params = {
+					beginTime: this.dateRange.startDate,
+					endTime: this.dateRange.endDate,
+					finishAuditStatus:this.currentTab,
+					taskType: 6,
+					pageNum: nextPage,
+					pageSize: this.pageSize
 				}
-			]
+				const res = await getAirClassroomList(params)
+				
+				if (res.code === 200) {
+					const newData = res.rows || []
+					if (newData.length > 0) {
+						// 追加新数据到列表
+						this.taskList = [...this.taskList, ...newData]
+						this.pageNum = nextPage
+						// 如果返回的数据量小于 pageSize,说明没有更多数据了
+						if (newData.length < this.pageSize) {
+							this.hasMore = false
+						}
+					} else {
+						// 没有新数据,说明已经加载完所有数据
+						this.hasMore = false
+					}
+				} else {
+					uni.showToast({
+						icon: 'none',
+						title: res.msg || '加载失败'
+					})
+				}
+			} catch (e) {
+				console.error('加载更多数据失败', e)
+				uni.showToast({
+					icon: 'none',
+					title: '加载失败'
+				})
+			} finally {
+				this.loading = false
+			}
 		}
 	}
 }
@@ -440,10 +482,22 @@ export default {
 	box-sizing: border-box;
 }
 
+.no-more {
+	text-align: center;
+	padding: 48rpx 0;
+	font-size: 24rpx;
+	color: #999;
+}
+.empty-state {
+	padding: 120rpx 24rpx;
+	text-align: center;
+	font-size: 28rpx;
+	color: #999;
+}
 .task-card {
 	background: #fff;
-	border-radius: 16rpx;
-	padding: 24rpx;
+	border-radius: 24rpx 24rpx 24rpx 24rpx;
+	border: 2rpx solid #E9F2FF;
 	margin-bottom: 24rpx;
 	
 	.card-header {
@@ -451,7 +505,9 @@ export default {
 		align-items: flex-start;
 		justify-content: space-between;
 		margin-bottom: 16rpx;
-		
+		padding: 24rpx;
+		background: linear-gradient( 90deg, #E8F1FF 0%, #FFFFFF 100%);
+		border-radius: 24rpx 24rpx 0rpx 0rpx;
 		.card-title {
 			flex: 1;
 			font-size: 32rpx;
@@ -464,24 +520,28 @@ export default {
 			border-radius: 20rpx;
 			font-size: 24rpx;
 			
-			&.pending {
-				background: #E3F2FD;
-				color: #2196F3;
-			}
-			
-			&.reviewing {
+			&.tag0 {
+				// 待审核
 				background: #FFF3E0;
 				color: #FF9800;
 			}
 			
-			&.approved {
+			&.tag1 {
+				// 已通过
 				background: #E8F5E9;
 				color: #4CAF50;
 			}
 			
-			&.rejected {
-				background: #FFEBEE;
-				color: #F44336;
+			&.tag2 {
+				// 已驳回
+				background: #FFF4F5;
+				color: #CF3546;
+			}
+			
+			&.tag3 {
+				// 未完成
+				background: #EBF5FF;
+				color: #388BFF;
 			}
 		}
 	}
@@ -495,14 +555,16 @@ export default {
 		
 		.tag-item {
 			padding: 8rpx 16rpx;
-			background: #f5f5f5;
+			// background: #f5f5f5;
 			border-radius: 8rpx;
 			font-size: 24rpx;
-			color: #666;
+			color: #999999;
+			border-radius: 8rpx 8rpx 8rpx 8rpx;
+			border: 2rpx solid #F5F5F5;
 			&.category{
 				border-radius: 0rpx 8rpx 8rpx 0rpx;
 			    border: 2rpx solid #F3D191;
-				background: #FFE9C7;
+				background: #FFFAF4;
 				color:#5D410F
 			}
 			&.video-tag {

+ 163 - 279
pages_task/medicationSurvey.vue

@@ -11,62 +11,58 @@
 			</view>
 		</view>
 		
-		<!-- 调研列表 -->
+		<!-- 问卷列表 -->
 		<scroll-view class="content" scroll-y>
-			<view class="survey-card" v-for="(item, index) in surveyList" :key="index" @click="goToDetail(item)">
-				<!-- 卡片头部背景 -->
-				<view class="card-header-bg" :style="{ backgroundImage: `url(${item.bannerImage})` }">
-					<view class="banner-content">
-						<!-- <view class="banner-title">{{ item.bannerTitle }}</view> -->
-						<view class="collection-time">
-							征集时间: {{ item.collectionStartTime }} 至 {{ item.collectionEndTime }}
-						</view>
-						<view class="banner-info" v-if="item.bannerInfo">{{ item.bannerInfo }}</view>
-					</view>
+			<view class="questionnaire-card" v-for="(item, index) in questionnaireList" :key="index">
+				<!-- 左侧缩略图 -->
+				<view class="card-thumbnail">
+					<image class="thumbnail-img" :src="item.coverImage" mode="aspectFill"></image>
 				</view>
 				
-				<!-- 卡片内容 -->
-				<view class="card-body">
-					
-					<view class="description">{{ item.description }}</view>
-					<view class="x-bc">
-						<view class="progress-section">
-							<view class="progress-bar">
-								<view class="progress-fill" :style="{ width: item.progressPercent + '%' }"></view>
-							</view>
-							<view class="progress-text">{{ item.completedCount }}/{{ item.totalCount }}</view>
-						</view>
-						<view class="card-action">
-							<view class="action-btn" :class="item.buttonClass" @click.stop="handleAction(item)">
-								{{ item.buttonText }}
-							</view>
+				<!-- 右侧内容 -->
+				<view class="card-content">
+					<view class="card-title">{{ item.title }}</view>
+					<view class="card-date">{{ item.startTime+'-'+ item.endTime}}</view>
+					<view class="card-status-section">
+						<view class="status-badge" :class="item.timeStatus">{{ item.timeStatus=='before'?'未完成':item.timeStatus=='during'?'进行中':'已结束'}}</view>
+						<view class="action-btn" v-if="currentTab == 'before'" @click="goToForm(item)">
+							填写问卷
 						</view>
 					</view>
-					
 				</view>
 			</view>
-			
-			<view class="no-more">没有更多了~</view>
+			<view class="no-more" v-if="!hasMore && questionnaireList.length > 0">没有更多了~</view>
+			<view class="empty-state y-bc" v-if="questionnaireList.length === 0">
+				<image class="w300 h300" src="@/static/image/img_blank_nodata.png" mode=""></image>
+				<text>暂无数据</text>
+			</view>
 		</scroll-view>
 	</view>
 </template>
 
 <script>
-import { getMedicationSurveyList } from '@/api-js/medicationSurvey'
+import { getMedicationSurveyList } from '@/api/medicationSurvey'
 export default {
 	data() {
 		return {
 			statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
-			currentTab: 'incomplete',
+			currentTab: 'before',
 			tabs: [
-				{ label: '未完成', value: 'incomplete' },
-				{ label: '未开始', value: 'notStarted' },
-				{ label: '已结束', value: 'ended' }
+				{ label: '未完成', value: 'before' },
+				{ label: '进行中', value: 'during' },
+				{ label: '已结束', value: 'after' }
 			],
-			surveyList: []
+			questionnaireList: [],
+			pageNum: 1,
+			pageSize: 10,
+			hasMore: true,
+			loading: false
 		}
 	},
 	onLoad() {
+		
+	},
+	onShow() {
 		this.loadData()
 	},
 	onReachBottom() {
@@ -78,157 +74,79 @@ export default {
 		},
 		switchTab(tab) {
 			this.currentTab = tab
+			this.pageNum = 1
+			this.hasMore = true
 			this.loadData()
 		},
-		goToDetail(item) {
+		goToForm(item) {
 			uni.navigateTo({
-				url: `/pages_task/activityDetail?id=${item.id}`
+				url: `/pages_task/caseCollection?id=${item.id}&title=${encodeURIComponent(item.title)}`
 			})
 		},
-		handleAction(item) {
-			if (item.status === 'notStarted') {
-				uni.showToast({
-					icon: 'none',
-					title: '活动未开始'
-				})
-			} else if (item.status === 'ended') {
-				uni.showToast({
-					icon: 'none',
-					title: '活动已结束'
-				})
-			} else {
-				// 跳转到填写问卷或上传病例页面
-				uni.navigateTo({
-					url: `/pages_task/caseCollection?activityId=${item.id}`
-				})
-			}
-		},
 		async loadData() {
 			try {
+				this.pageNum = 1
+				this.hasMore = true
 				uni.showLoading({ title: '加载中...' })
 				const res = await getMedicationSurveyList({
-					status: this.currentTab,
-					page: 1,
-					pageSize: 20
+					timeStatus: this.currentTab,
+					pageNum: 1,
+					pageSize: this.pageSize
 				})
 				uni.hideLoading()
-				if (res.code === 200 && res.data) {
-					this.surveyList = res.data.list || this.getDefaultData()
+				if (res.code === 200) {
+					this.questionnaireList = res.data.rows || []
+					// 判断是否还有更多数据
+					if (!res.data.rows || res.data.rows.length < this.pageSize) {
+						this.hasMore = false
+					}
 				} else {
-					this.surveyList = this.getDefaultData()
+					uni.showToast({
+						icon: 'none',
+						title: res.msg
+					})
+					this.hasMore = false
 				}
 			} catch (e) {
 				uni.hideLoading()
 				console.error('加载数据失败', e)
-				this.surveyList = this.getDefaultData()
+				this.hasMore = false
 			}
 		},
 		async loadMore() {
-			// 加载更多数据
-		},
-		getDefaultData() {
-			if (this.currentTab === 'notStarted') {
-				return [
-					{
-						id: 1,
-						bannerImage: 'https://hos-1309931967.cos.ap-chongqing.myqcloud.com/fs/20240516/b091048293f142608f99eaf1b0b1510a.png',
-						bannerTitle: '正规医院体检',
-						bannerSubtitle: '守护您的健康',
-						collectionStartTime: '2025-05-29 00:00',
-						collectionEndTime: '2025-05-29 00:00',
-						description: '全国14家医院抗菌药物合理用药调研',
-						completedCount: 0,
-						totalCount: 3,
-						progressPercent: 0,
-						status: 'notStarted',
-						buttonText: '未开始',
-						buttonClass: 'not-started'
-					},
-					{
-						id: 2,
-						bannerImage: 'https://hos-1309931967.cos.ap-chongqing.myqcloud.com/fs/20240516/b091048293f142608f99eaf1b0b1510a.png',
-						bannerTitle: '2025广东省医师协会眼科医师分会',
-						bannerSubtitle: '眼外伤与眼眶病学术会议',
-						bannerInfo: '·暨眼外伤诊疗新进展学习班·',
-						collectionStartTime: '2025-05-29 00:00',
-						collectionEndTime: '2025-05-29 00:00',
-						description: '全国14家医院抗菌药物合理用药调研',
-						completedCount: 0,
-						totalCount: 3,
-						progressPercent: 0,
-						status: 'notStarted',
-						buttonText: '未开始',
-						buttonClass: 'not-started'
-					}
-				]
-			} else if (this.currentTab === 'incomplete') {
-				return [
-					{
-						id: 3,
-						bannerImage: 'https://hos-1309931967.cos.ap-chongqing.myqcloud.com/fs/20240516/b091048293f142608f99eaf1b0b1510a.png',
-						bannerTitle: '正规医院体检',
-						bannerSubtitle: '守护您的健康',
-						collectionStartTime: '2025-05-29 00:00',
-						collectionEndTime: '2025-05-29 00:00',
-						description: '全国14家医院抗菌药物合理用药调研',
-						completedCount: 0,
-						totalCount: 3,
-						progressPercent: 0,
-						status: 'incomplete',
-						buttonText: '填写问卷',
-						buttonClass: 'fill-questionnaire'
-					},
-					{
-						id: 4,
-						bannerImage: 'https://hos-1309931967.cos.ap-chongqing.myqcloud.com/fs/20240516/b091048293f142608f99eaf1b0b1510a.png',
-						bannerTitle: '2025广东省医师协会眼科医师分会',
-						bannerSubtitle: '眼外伤与眼眶病学术会议',
-						bannerInfo: '·暨眼外伤诊疗新进展学习班·',
-						collectionStartTime: '2025-05-29 00:00',
-						collectionEndTime: '2025-05-29 00:00',
-						description: '全国14家医院抗菌药物合理用药调研',
-						completedCount: 1,
-						totalCount: 3,
-						progressPercent: 33,
-						status: 'incomplete',
-						buttonText: '填写问卷',
-						buttonClass: 'fill-questionnaire'
-					}
-				]
-			} else {
-				return [
-					{
-						id: 5,
-						bannerImage: 'https://hos-1309931967.cos.ap-chongqing.myqcloud.com/fs/20240516/b091048293f142608f99eaf1b0b1510a.png',
-						bannerTitle: '正规医院体检',
-						bannerSubtitle: '守护您的健康',
-						collectionStartTime: '2025-05-29 00:00',
-						collectionEndTime: '2025-05-29 00:00',
-						description: '全国14家医院抗菌药物合理用药调研',
-						completedCount: 0,
-						totalCount: 3,
-						progressPercent: 0,
-						status: 'ended',
-						buttonText: '活动已结束',
-						buttonClass: 'ended'
-					},
-					{
-						id: 6,
-						bannerImage: 'https://hos-1309931967.cos.ap-chongqing.myqcloud.com/fs/20240516/b091048293f142608f99eaf1b0b1510a.png',
-						bannerTitle: '2025广东省医师协会眼科医师分会',
-						bannerSubtitle: '眼外伤与眼眶病学术会议',
-						bannerInfo: '·暨眼外伤诊疗新进展学习班·',
-						collectionStartTime: '2025-05-29 00:00',
-						collectionEndTime: '2025-05-29 00:00',
-						description: '全国14家医院抗菌药物合理用药调研',
-						completedCount: 0,
-						totalCount: 3,
-						progressPercent: 0,
-						status: 'ended',
-						buttonText: '活动已结束',
-						buttonClass: 'ended'
+			if (!this.hasMore || this.loading) return
+			
+			try {
+				this.loading = true
+				const nextPage = this.pageNum + 1
+				const res = await getMedicationSurveyList({
+					timeStatus: this.currentTab,
+					pageNum: nextPage,
+					pageSize: this.pageSize
+				})
+				
+				if (res.code === 200) {
+					const newData = res.data.rows || []
+					if (newData.length > 0) {
+						// 追加新数据到列表
+						this.questionnaireList = [...this.questionnaireList, ...newData]
+						this.pageNum = nextPage
+						// 如果返回的数据量小于 pageSize,说明没有更多数据了
+						if (newData.length < this.pageSize) {
+							this.hasMore = false
+						}
+					} else {
+						// 没有新数据,说明已经加载完所有数据
+						this.hasMore = false
 					}
-				]
+				} else {
+					this.hasMore = false
+				}
+			} catch (e) {
+				console.error('加载更多数据失败', e)
+				this.hasMore = false
+			} finally {
+				this.loading = false
 			}
 		}
 	}
@@ -238,54 +156,52 @@ export default {
 <style lang="scss" scoped>
 .container {
 	min-height: 100vh;
-	background: #f5f5f5;
 	display: flex;
 	flex-direction: column;
 }
 
-.status-bar {
-	width: 100%;
-	background: #fff;
-}
-
-.header {
-	position: relative;
-	height: 88rpx;
+.navbar {
 	display: flex;
 	align-items: center;
-	justify-content: center;
+	justify-content: space-between;
+	padding: 20rpx 24rpx;
 	background: #fff;
 	border-bottom: 1rpx solid #f0f0f0;
 	
-	.back-btn {
-		position: absolute;
-		left: 24rpx;
-		width: 40rpx;
-		height: 40rpx;
+	.nav-left {
+		width: 60rpx;
 		
-		image {
-			width: 100%;
-			height: 100%;
+		.back-icon {
+			font-size: 36rpx;
+			color: #333;
+			font-weight: bold;
 		}
 	}
 	
-	.title {
+	.nav-title {
+		flex: 1;
+		text-align: center;
 		font-size: 36rpx;
 		font-weight: bold;
 		color: #333;
 	}
 	
-	.header-right {
-		position: absolute;
-		right: 24rpx;
+	.nav-right {
 		display: flex;
 		align-items: center;
-		gap: 16rpx;
+		gap: 24rpx;
+		width: 120rpx;
+		justify-content: flex-end;
 		
 		.more-icon {
 			font-size: 32rpx;
 			color: #333;
 		}
+		
+		.target-icon {
+			font-size: 32rpx;
+			color: #333;
+		}
 	}
 }
 
@@ -308,9 +224,8 @@ export default {
 		&.active {
 			font-family: PingFang SC, PingFang SC;
 			font-weight: 500;
-			font-size: 28rpx;
+			font-size: 32rpx;
 			color: #333333;
-			font-weight: bold;
 			
 			&::after {
 				content: '';
@@ -318,10 +233,9 @@ export default {
 				bottom: 0;
 				left: 50%;
 				transform: translateX(-50%);
-				right: 0;
 				width: 80rpx;
 				height: 6rpx;
-				border-radius: 3rpx 3rpx 3rpx 3rpx;
+				border-radius: 3rpx;
 				background: #388BFF;
 			}
 		}
@@ -331,114 +245,87 @@ export default {
 .content {
 	flex: 1;
 	padding: 24rpx;
-    box-sizing: border-box;
+	box-sizing: border-box;
 }
 
-.survey-card {
+.questionnaire-card {
+	display: flex;
 	background: #fff;
 	border-radius: 16rpx;
 	margin-bottom: 24rpx;
-	overflow: hidden;
+	padding: 24rpx;
 	
-	.card-header-bg {
-		position: relative;
-		height: 240rpx;
-		background: linear-gradient(135deg, #87CEEB 0%, #98D8C8 100%);
-		display: flex;
-		    align-items: flex-start;
-		    justify-content: flex-end;
-		    flex-direction: column;
-		padding: 24rpx;
+	.card-thumbnail {
+		width: 320rpx;
+		height: 180rpx;
+		border-radius: 16rpx 16rpx 16rpx 16rpx;
+		overflow: hidden;
+		margin-right: 24rpx;
+		flex-shrink: 0;
 		
-		.banner-content {
+		.thumbnail-img {
 			width: 100%;
-			text-align:left;
-			.collection-time {
-				font-family: PingFang SC, PingFang SC;
-				font-weight: 600;
-				font-size: 26rpx;
-				color: #FFFFFF;
-			}
-			
-			
-			.banner-info {
-				font-size: 24rpx;
-				color: #fff;
-				margin-bottom: 8rpx;
-			}
+			height: 100%;
 		}
 	}
 	
-	.card-body {
-		padding: 24rpx;
-		
-		
+	.card-content {
+		flex: 1;
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
 		
-		.description {
+		.card-title {
 			font-family: PingFang SC, PingFang SC;
 			font-weight: 500;
 			font-size: 28rpx;
 			color: #333333;
-			margin-bottom: 30rpx;
+			margin-bottom: 16rpx;
 		}
 		
-		.progress-section {
-			width: 60%;
+		.card-date {
+			font-family: PingFang SC, PingFang SC;
+			font-weight: 400;
+			font-size: 24rpx;
+			color: #999999;
+			margin-bottom: 16rpx;
+		}
+		
+		.card-status-section {
 			display: flex;
 			align-items: center;
 			justify-content: space-between;
-			gap: 16rpx;
 			
-			.progress-bar {
-				flex: 1;
-				height: 12rpx;
-				background: #f0f0f0;
-				border-radius: 4rpx;
-				overflow: hidden;
+			.status-badge {
+				padding: 8rpx 16rpx;
+				border-radius: 8rpx;
+				font-family: PingFang SC, PingFang SC;
+				font-weight: 400;
+				font-size: 24rpx;
+				&.before {
+					background: #FFF7E6;
+					color: #FF9500;
+				}
 				
-				.progress-fill {
-					height: 100%;
-					background: #388BFF;
-					border-radius: 4rpx;
-					transition: width 0.3s;
+				&.during {
+					background: #E6F4FF;
+					color: #388BFF;
+				}
+				
+				&.after {
+					background: #F6F6F6;
+					color: #999999;
 				}
 			}
 			
-			.progress-text {
-				font-size: 24rpx;
-				color: #388BFF;
-				min-width: 60rpx;
-			}
-		}
-		
-		.card-action {
-			display: flex;
-			justify-content: flex-end;
-			
 			.action-btn {
-				display: flex;
-				justify-content: center;
-				align-items: center;
-				padding: 12rpx 24rpx;
+				padding: 12rpx 32rpx;
 				background: #388BFF;
-				border-radius: 34rpx 34rpx 34rpx 34rpx;
+				border-radius: 34rpx;
 				font-family: PingFang SC, PingFang SC;
 				font-weight: 500;
 				font-size: 24rpx;
 				color: #FFFFFF;
-				&.fill-questionnaire {
-					background: #388BFF;
-				}
-				
-				&.not-started {
-					background: #EFEFEF;
-					color: #999999;
-				}
-				
-				&.ended {
-					background: #EFEFEF;
-					color: #999999;
-				}
 			}
 		}
 	}
@@ -450,13 +337,10 @@ export default {
 	font-size: 24rpx;
 	color: #999;
 }
-</style>
-
-
-
-
-
-
-
-
-
+.empty-state {
+	padding: 120rpx 24rpx;
+	text-align: center;
+	font-size: 28rpx;
+	color: #999;
+}
+</style>

+ 2 - 2
pages_task/onlineLecture.vue

@@ -52,7 +52,7 @@
 					</view>
 					<view class="card-points">{{ item.points }} 积分</view>
 					<view class="card-views" v-if="currentTab === 'completed'">
-						<text class="eye-icon">👁</text>
+						<text class="eye-icon"></text>
 						<text>{{ item.viewCount }}</text>
 					</view>
 					<view class="card-action">
@@ -113,7 +113,7 @@
 </template>
 
 <script>
-import { getOnlineLectureList, getBroadcastUrl, enterMiniProgram } from '@/api-js/onlineLecture'
+import { getOnlineLectureList, getBroadcastUrl, enterMiniProgram } from '@/api/onlineLecture'
 export default {
 	data() {
 		return {

+ 275 - 194
pages_task/questionnaire.vue

@@ -11,176 +11,214 @@
 			</view>
 		</view>
 		
-		<!-- 问卷列表 -->
+		<!-- 调研列表 -->
 		<scroll-view class="content" scroll-y>
-			<view class="questionnaire-card" v-for="(item, index) in questionnaireList" :key="index">
-				<!-- 左侧缩略图 -->
-				<view class="card-thumbnail">
-					<image class="thumbnail-img" :src="item.thumbnail" mode="aspectFill"></image>
+			<view class="survey-card" v-for="(item, index) in surveyList" :key="index" @click="handleAction(item)">
+				<!-- 卡片头部背景 -->
+				<view class="card-header-bg" :style="{ backgroundImage: `url(${item.coverImage})` }">
+					<view class="banner-content">
+						<!-- <view class="banner-title">{{ item.bannerTitle }}</view> -->
+						<view class="collection-time">
+							征集时间: {{ formatTime(item.periodStartTime) }} 至 {{ formatTime(item.periodEndTime) }}
+						</view>
+						<!-- <view class="banner-info" v-if="item.title">{{ item.title }}</view> -->
+					</view>
 				</view>
 				
-				<!-- 右侧内容 -->
-				<view class="card-content">
-					<view class="card-title">{{ item.title }}</view>
-					<view class="card-date">{{ item.dateRange }}</view>
-					<view class="card-status-section">
-						<view class="status-badge" :class="item.statusClass">{{ item.statusText }}</view>
-						<view class="action-btn" v-if="currentTab === 'incomplete'" @click.stop="goToForm(item)">
-							填写问卷
+				<!-- 卡片内容 -->
+				<view class="card-body">
+					
+					<view class="description">{{ item.title }}</view>
+					<view class="x-bc">
+						<view class="progress-section" v-if="item.periodDataDto && shouldShowProgress(item)">
+							<view class="progress-bar">
+								<view class="progress-fill" :style="{ width: getProgressWidth(item) }"></view>
+							</view>
+							<view class="progress-text">{{ getProgressText(item) }}</view>
+						</view>
+						<view class="card-action">
+							<view class="action-btn" v-if="currentTab == 'before'" :class="item.timeStatus" @click.stop="handleAction(item)">
+								填写问卷
+							</view>
+							<view class="action-btn" v-else :class="currentTab">
+								{{currentTab == 'during'?'进行中':'已结束'}}
+							</view>
 						</view>
 					</view>
+					
 				</view>
 			</view>
 			
-			<view class="no-more">没有更多了~</view>
+			<view class="no-more" v-if="!hasMore && surveyList.length > 0">没有更多了~</view>
+			<view class="empty-state y-bc" v-if="surveyList.length === 0">
+				<image class="w300 h300" src="@/static/image/img_blank_nodata.png" mode=""></image>
+				<text>暂无数据</text>
+			</view>
 		</scroll-view>
 	</view>
 </template>
 
 <script>
-import { getQuestionnaireList } from '@/api-js/questionnaire'
+import { 
+	getQuestionnaireList
+} from '@/api/questionnaire'
 export default {
 	data() {
 		return {
 			statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
-			currentTab: 'incomplete',
+			currentTab: 'before',
 			tabs: [
-				{ label: '未完成', value: 'incomplete' },
-				{ label: '未开始', value: 'notStarted' },
-				{ label: '已结束', value: 'ended' }
+				{ label: '未完成', value: 'before' },
+				{ label: '进行中', value: 'during' },
+				{ label: '已结束', value: 'after' }
 			],
-			questionnaireList: []
+			surveyList: [],
+			pageNum: 1,
+			pageSize: 10,
+			hasMore: true,
+			loading: false
 		}
 	},
 	onLoad() {
+	},
+	onShow() {
+		// 从表单页返回时刷新列表
 		this.loadData()
 	},
+	onReachBottom() {
+		this.loadMore()
+	},
 	methods: {
 		goBack() {
 			uni.navigateBack()
 		},
 		switchTab(tab) {
 			this.currentTab = tab
+			this.pageNum = 1
+			this.hasMore = true
 			this.loadData()
 		},
-		goToForm(item) {
+		goToDetail(item) {
 			uni.navigateTo({
-				url: `/pages_task/questionnaireForm?id=${item.id}&title=${encodeURIComponent(item.title)}`
+				url: `/pages_task/activityDetail?id=${item.id}`
 			})
 		},
+		handleAction(item) {
+			if (this.currentTab == 'after') {
+				uni.showToast({
+					icon: 'none',
+					title: '活动已结束'
+				})
+			} else {
+				// 跳转到填写问卷或上传病例页面
+				uni.navigateTo({
+					url: `/pages_task/questionnaireForm?id=${item.id}`
+				})
+			}
+		},
+		// 判断是否显示进度条
+		shouldShowProgress(item) {
+			if (!item.periodDataDto) return false
+			const { alreadyPeriodNum, totalPeriodNum } = item.periodDataDto
+			return totalPeriodNum != null && totalPeriodNum > 0
+		},
+		// 计算进度条宽度百分比
+		getProgressWidth(item) {
+			if (!item.periodDataDto) return '0%'
+			const { alreadyPeriodNum, totalPeriodNum } = item.periodDataDto
+			if (!totalPeriodNum || totalPeriodNum === 0) return '0%'
+			const percentage = Math.min(100, Math.max(0, (alreadyPeriodNum / totalPeriodNum) * 100))
+			return percentage.toFixed(2) + '%'
+		},
+		// 获取进度文本
+		getProgressText(item) {
+			if (!item.periodDataDto) return '0/0'
+			const { alreadyPeriodNum, totalPeriodNum } = item.periodDataDto
+			const already = alreadyPeriodNum != null ? alreadyPeriodNum : 0
+			const total = totalPeriodNum != null ? totalPeriodNum : 0
+			return `${already}/${total}`
+		},
+		// 格式化时间,去掉秒数
+		formatTime(timeStr) {
+			if (!timeStr) return '-'
+			// 如果时间格式包含秒数(如 "YYYY-MM-DD HH:mm:ss"),则去掉秒数部分
+			if (timeStr.length >= 19 && timeStr.indexOf(':') !== -1) {
+				// 匹配 "YYYY-MM-DD HH:mm:ss" 格式,去掉最后的 ":ss"
+				return timeStr.substring(0, 16)
+			}
+			return timeStr
+		},
 		async loadData() {
 			try {
+				this.pageNum = 1
+				this.hasMore = true
 				uni.showLoading({ title: '加载中...' })
 				const res = await getQuestionnaireList({
-					status: this.currentTab,
-					page: 1,
-					pageSize: 20
+					timeStatus: this.currentTab,
+					pageNum: 1,
+					pageSize: this.pageSize
 				})
 				uni.hideLoading()
-				if (res.code === 200 && res.data) {
-					this.questionnaireList = res.data.list || this.getDefaultData()
+				if (res.code === 200) {
+					this.surveyList = res.data.rows || []
+					// 判断是否还有更多数据
+					if (!res.data.rows || res.data.rows.length < this.pageSize) {
+						this.hasMore = false
+					}
 				} else {
-					this.questionnaireList = this.getDefaultData()
+					uni.showToast({
+						icon: 'none',
+						title: res.msg
+					})
 				}
 			} catch (e) {
 				uni.hideLoading()
 				console.error('加载数据失败', e)
-				this.questionnaireList = this.getDefaultData()
 			}
 		},
-		getDefaultData() {
-			const defaultThumbnail = 'https://hos-1309931967.cos.ap-chongqing.myqcloud.com/fs/20240516/b091048293f142608f99eaf1b0b1510a.png'
+		async loadMore() {
+			// 如果没有更多数据或正在加载,则不执行
+			if (!this.hasMore || this.loading) {
+				return
+			}
 			
-			if (this.currentTab === 'notStarted') {
-				return [
-					{
-						id: 1,
-						thumbnail: defaultThumbnail,
-						title: '康复医学调研',
-						dateRange: '2024-09-15~2025-09-30',
-						status: 'notStarted',
-						statusText: '待开始',
-						statusClass: 'status-pending'
-					},
-					{
-						id: 2,
-						thumbnail: defaultThumbnail,
-						title: '康复医学调研',
-						dateRange: '2024-09-15~2025-09-30',
-						status: 'notStarted',
-						statusText: '待开始',
-						statusClass: 'status-pending'
-					},
-					{
-						id: 3,
-						thumbnail: defaultThumbnail,
-						title: '糖尿病并发症调研',
-						dateRange: '2024-09-15~2025-09-30',
-						status: 'notStarted',
-						statusText: '待开始',
-						statusClass: 'status-pending'
-					}
-				]
-			} else if (this.currentTab === 'incomplete') {
-				return [
-					{
-						id: 4,
-						thumbnail: defaultThumbnail,
-						title: '康复医学调研',
-						dateRange: '2024-09-15~2025-09-30',
-						status: 'incomplete',
-						statusText: '待完成',
-						statusClass: 'status-incomplete'
-					},
-					{
-						id: 5,
-						thumbnail: defaultThumbnail,
-						title: '康复医学调研',
-						dateRange: '2024-09-15~2025-09-30',
-						status: 'incomplete',
-						statusText: '待完成',
-						statusClass: 'status-incomplete'
-					},
-					{
-						id: 6,
-						thumbnail: defaultThumbnail,
-						title: '糖尿病并发症调研',
-						dateRange: '2024-09-15~2025-09-30',
-						status: 'incomplete',
-						statusText: '待完成',
-						statusClass: 'status-incomplete'
-					}
-				]
-			} else {
-				return [
-					{
-						id: 7,
-						thumbnail: defaultThumbnail,
-						title: '康复医学调研',
-						dateRange: '2024-09-15~2025-09-30',
-						status: 'ended',
-						statusText: '已结束',
-						statusClass: 'status-ended'
-					},
-					{
-						id: 8,
-						thumbnail: defaultThumbnail,
-						title: '康复医学调研',
-						dateRange: '2024-09-15~2025-09-30',
-						status: 'ended',
-						statusText: '已结束',
-						statusClass: 'status-ended'
-					},
-					{
-						id: 9,
-						thumbnail: defaultThumbnail,
-						title: '糖尿病并发症调研',
-						dateRange: '2024-09-15~2025-09-30',
-						status: 'ended',
-						statusText: '已结束',
-						statusClass: 'status-ended'
+			try {
+				this.loading = true
+				const nextPage = this.pageNum + 1
+				const res = await getQuestionnaireList({
+					timeStatus: this.currentTab,
+					pageNum: nextPage,
+					pageSize: this.pageSize
+				})
+				
+				if (res.code === 200) {
+					const newData = res.data.rows || []
+					if (newData.length > 0) {
+						// 追加新数据到列表
+						this.surveyList = [...this.surveyList, ...newData]
+						this.pageNum = nextPage
+						// 如果返回的数据量小于 pageSize,说明没有更多数据了
+						if (newData.length < this.pageSize) {
+							this.hasMore = false
+						}
+					} else {
+						// 没有新数据,说明已经加载完所有数据
+						this.hasMore = false
 					}
-				]
+				} else {
+					uni.showToast({
+						icon: 'none',
+						title: res.msg || '加载失败'
+					})
+				}
+			} catch (e) {
+				console.error('加载更多数据失败', e)
+				uni.showToast({
+					icon: 'none',
+					title: '加载失败'
+				})
+			} finally {
+				this.loading = false
 			}
 		}
 	}
@@ -190,53 +228,53 @@ export default {
 <style lang="scss" scoped>
 .container {
 	min-height: 100vh;
-	background: #f5f5f5;
 	display: flex;
 	flex-direction: column;
 }
 
-.navbar {
+.status-bar {
+	width: 100%;
+	background: #fff;
+}
+
+.header {
+	position: relative;
+	height: 88rpx;
 	display: flex;
 	align-items: center;
-	justify-content: space-between;
-	padding: 20rpx 24rpx;
+	justify-content: center;
 	background: #fff;
 	border-bottom: 1rpx solid #f0f0f0;
 	
-	.nav-left {
-		width: 60rpx;
+	.back-btn {
+		position: absolute;
+		left: 24rpx;
+		width: 40rpx;
+		height: 40rpx;
 		
-		.back-icon {
-			font-size: 36rpx;
-			color: #333;
-			font-weight: bold;
+		image {
+			width: 100%;
+			height: 100%;
 		}
 	}
 	
-	.nav-title {
-		flex: 1;
-		text-align: center;
+	.title {
 		font-size: 36rpx;
 		font-weight: bold;
 		color: #333;
 	}
 	
-	.nav-right {
+	.header-right {
+		position: absolute;
+		right: 24rpx;
 		display: flex;
 		align-items: center;
-		gap: 24rpx;
-		width: 120rpx;
-		justify-content: flex-end;
+		gap: 16rpx;
 		
 		.more-icon {
 			font-size: 32rpx;
 			color: #333;
 		}
-		
-		.target-icon {
-			font-size: 32rpx;
-			color: #333;
-		}
 	}
 }
 
@@ -259,8 +297,9 @@ export default {
 		&.active {
 			font-family: PingFang SC, PingFang SC;
 			font-weight: 500;
-			font-size: 32rpx;
+			font-size: 28rpx;
 			color: #333333;
+			font-weight: bold;
 			
 			&::after {
 				content: '';
@@ -268,9 +307,10 @@ export default {
 				bottom: 0;
 				left: 50%;
 				transform: translateX(-50%);
+				right: 0;
 				width: 80rpx;
 				height: 6rpx;
-				border-radius: 3rpx;
+				border-radius: 3rpx 3rpx 3rpx 3rpx;
 				background: #388BFF;
 			}
 		}
@@ -280,88 +320,114 @@ export default {
 .content {
 	flex: 1;
 	padding: 24rpx;
-	box-sizing: border-box;
+    box-sizing: border-box;
 }
 
-.questionnaire-card {
-	display: flex;
+.survey-card {
 	background: #fff;
 	border-radius: 16rpx;
 	margin-bottom: 24rpx;
-	padding: 24rpx;
+	overflow: hidden;
 	
-	.card-thumbnail {
-		width: 320rpx;
-		height: 180rpx;
-		border-radius: 16rpx 16rpx 16rpx 16rpx;
-		overflow: hidden;
-		margin-right: 24rpx;
-		flex-shrink: 0;
+	.card-header-bg {
+		position: relative;
+		height: 240rpx;
+		background: linear-gradient(135deg, #87CEEB 0%, #98D8C8 100%);
+		display: flex;
+		    align-items: flex-start;
+		    justify-content: flex-end;
+		    flex-direction: column;
+		padding: 24rpx;
 		
-		.thumbnail-img {
+		.banner-content {
 			width: 100%;
-			height: 100%;
+			text-align:left;
+			.collection-time {
+				font-family: PingFang SC, PingFang SC;
+				font-weight: 600;
+				font-size: 26rpx;
+				color: #FFFFFF;
+			}
+			
+			
+			.banner-info {
+				font-size: 24rpx;
+				color: #fff;
+				margin-bottom: 8rpx;
+			}
 		}
 	}
 	
-	.card-content {
-		flex: 1;
-		display: flex;
-		flex-direction: column;
-		justify-content: space-between;
+	.card-body {
+		padding: 24rpx;
+		
 		
-		.card-title {
+		
+		.description {
 			font-family: PingFang SC, PingFang SC;
 			font-weight: 500;
 			font-size: 28rpx;
 			color: #333333;
-			margin-bottom: 16rpx;
-		}
-		
-		.card-date {
-			font-family: PingFang SC, PingFang SC;
-			font-weight: 400;
-			font-size: 24rpx;
-			color: #999999;
-			margin-bottom: 16rpx;
+			margin-bottom: 30rpx;
 		}
 		
-		.card-status-section {
+		.progress-section {
+			width: 60%;
 			display: flex;
 			align-items: center;
 			justify-content: space-between;
+			gap: 16rpx;
 			
-			.status-badge {
-				padding: 8rpx 16rpx;
-				border-radius: 8rpx;
-				font-family: PingFang SC, PingFang SC;
-				font-weight: 400;
-				font-size: 24rpx;
+			.progress-bar {
+				flex: 1;
+				height: 12rpx;
+				background: #f0f0f0;
+				border-radius: 4rpx;
+				overflow: hidden;
 				
-				&.status-pending {
-					background: #FFF7E6;
-					color: #FF9500;
-				}
-				
-				&.status-incomplete {
-					background: #E6F4FF;
-					color: #388BFF;
-				}
-				
-				&.status-ended {
-					background: #F5F5F5;
-					color: #999999;
+				.progress-fill {
+					height: 100%;
+					background: #388BFF;
+					border-radius: 4rpx;
+					transition: width 0.3s;
 				}
 			}
 			
+			.progress-text {
+				font-size: 24rpx;
+				color: #388BFF;
+				min-width: 60rpx;
+			}
+		}
+		
+		.card-action {
+			display: flex;
+			justify-content: flex-end;
+			
 			.action-btn {
-				padding: 12rpx 32rpx;
+				display: flex;
+				justify-content: center;
+				align-items: center;
+				padding: 12rpx 24rpx;
 				background: #388BFF;
-				border-radius: 34rpx;
+				border-radius: 34rpx 34rpx 34rpx 34rpx;
 				font-family: PingFang SC, PingFang SC;
 				font-weight: 500;
 				font-size: 24rpx;
 				color: #FFFFFF;
+				&.before {
+					background: #388BFF;
+				}
+				
+				&.during {
+					background: #EFEFEF;
+					color: #999999;
+				}
+				
+				&.after {
+					background: #EFEFEF;
+					color: #999999;
+				}
 			}
 		}
 	}
@@ -373,8 +439,23 @@ export default {
 	font-size: 24rpx;
 	color: #999;
 }
+.empty-state {
+	padding: 120rpx 24rpx;
+	text-align: center;
+	font-size: 28rpx;
+	color: #999;
+}
 </style>
 
 
 
 
+
+
+
+
+
+
+
+
+

Разница между файлами не показана из-за своего большого размера
+ 877 - 158
pages_task/questionnaireForm.vue


+ 161 - 134
pages_task/science.vue

@@ -22,61 +22,70 @@
 		<scroll-view class="content" scroll-y>
 			<view class="task-card" v-for="(item, index) in taskList" :key="index" @click="showDetail(item)">
 				<view class="card-header">
-					<view class="card-title">{{ item.title }}</view>
-					<view class="status-tag" :class="item.status">
-						{{ item.statusText }}
+					<view class="card-title">{{ item.taskName}}</view>
+					<view class="status-tag" :class="'tag'+item.finishAuditStatus">
+						{{ item.finishAuditStatus==0?'待审核':item.finishAuditStatus==1?'已通过':item.finishAuditStatus==2?'已驳回':'未完成'}}
 					</view>
 				</view>
+				<view style="padding: 24rpx;">
 				<view class="card-tags">
 					<view class="x-f">
-						<view class="tag-item video-tag" v-if="item.videoType">
-							<image class="w28 h28 mr10" src="@/static/image/icon_longvideo.png" mode=""></image>
-							<text>{{ item.videoType }}</text>
+						<view class="tag-item video-tag" v-if="item.taskType">
+							<!-- <image class="w28 h28 mr10" src="@/static/image/icon_longvideo.png" mode=""></image> -->
+							<image class="w28 h28 mr10" src="@/static/image/icon_article.png" mode=""></image>
+							<text>{{ item.taskType==4?'文章':taskData.taskType==5?'短视频':'长视频'}}</text>
 							
 						</view>
-						<view class="tag-item category" v-if="item.category">
-							{{ item.category }}
+						<view class="tag-item category">
+							学术
 						</view>
 					</view>
 					
 					<view class="tag-item points-tag">
-						{{ item.points }}积分
+						{{ item.taskIntegral }}积分
 					</view>
 					<view class="tag-item">
-						{{ item.count }}个
+						{{ item.taskCount }}{{item.taskUnitName}}
 					</view>
 				</view>
 				
 				<view class="card-dates">
 					<view class="date-item">
-						<text>开始时间: {{ item.startTime }}</text>
+						<text>开始时间:{{ item.planStartTime }}</text>
 					</view>
 					<view class="date-item">
-						<text>结束时间: {{ item.endTime }}</text>
+						<text>结束时间:{{ item.planEndTime }}</text>
 					</view>
 				</view>
 				
 				<view class="card-warning" v-if="item.warning">
-					<text class="warning-icon">⚠</text>
+					<image class="w28 h28 mr8" src="@/static/image/icon_admonish.png" mode=""></image>
 					<text>{{ item.warning }}</text>
 				</view>
 				
-				<view class="card-rejection" v-if="item.rejectionReason">
-					<text class="rejection-icon">❌</text>
-					<text>驳回原因: {{ item.rejectionReason }}</text>
+				<view class="card-rejection" v-if="item.finishAuditStatus == 2">
+					<image class="w28 h28 mr8" src="@/static/image/icon_reject.png" mode=""></image>
+					<text>驳回原因: {{ item.finishAuditRemark }}</text>
 				</view>
 				
 				<view class="card-footer">
 					<view class="footer-date">{{ item.createTime }}</view>
 					<view class="footer-actions">
-						<view class="action-btn" v-if="item.status === 'pending'" @click="goComplete(item)">
+						<view class="action-btn" v-if="item.finishAuditStatus==3">
 							去完成
 						</view>
-						<view class="action-btn" v-if="item.status === 'rejected'" @click="goEdit(item)">
+						<view class="action-btn" v-if="item.finishAuditStatus == 2" @click="goEdit(item)">
 							编辑
 						</view>
 					</view>
 				</view>
+				</view>
+			</view>
+			
+			<view class="no-more" v-if="!hasMore && taskList.length > 0">没有更多了~</view>
+			<view class="empty-state y-bc" v-if="taskList.length === 0">
+				<image class="w300 h300" src="@/static/image/img_blank_nodata.png" mode=""></image>
+				<text>暂无数据</text>
 			</view>
 		</scroll-view>
 		
@@ -109,7 +118,7 @@
 				</view>
 				
 				<!-- 任务类型筛选 -->
-				<view class="filter-group">
+				<!-- <view class="filter-group">
 					<view class="group-label">任务类型</view>
 					<view class="filter-tags">
 						<view 
@@ -121,7 +130,7 @@
 							{{ item.label }}
 						</view>
 					</view>
-				</view>
+				</view> -->
 				
 				<!-- 操作按钮 -->
 				<view class="filter-actions">
@@ -134,12 +143,13 @@
 </template>
 
 <script>
-import { getAirClassroomList } from '@/api-js/airClassroom'
+import { getAirClassroomList ,getTaskDetail,submitTask} from '@/api/airClassroom'
+import { getTaskTypeList } from '@/api/common.js'
 export default {
 	data() {
 		return {
 			statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
-			currentTab: 'all',
+			currentTab: '',
 			showFilter: false,
 			dateRange: {
 				startDate: '',
@@ -151,19 +161,23 @@ export default {
 			},
 			selectedTaskType: 'article', // 默认选中科普文章
 			tempSelectedTaskType: 'article',
-			taskTypeOptions: [
-				{ label: '科普文章', value: 'article' },
-				{ label: '科普短视频', value: 'shortVideo' },
-				{ label: '科普长视频', value: 'longVideo' }
-			],
+			// taskTypeOptions: [
+			// 	{ label: '科普文章', value: 'article' },
+			// 	{ label: '科普短视频', value: 'shortVideo' },
+			// 	{ label: '科普长视频', value: 'longVideo' }
+			// ],
 			tabs: [
-				{ label: '全部', value: 'all' },
-				{ label: '未完成', value: 'pending' },
-				{ label: '待审核', value: 'reviewing' },
-				{ label: '已通过', value: 'approved' },
-				{ label: '已驳回', value: 'rejected' }
+				{ label: '全部', value:''},
+				{ label: '未完成', value: 3},
+				{ label: '待审核', value: 0},
+				{ label: '已通过', value: 1},
+				{ label: '已驳回', value: 2}
 			],
-			taskList: []
+			taskList: [],
+			pageNum: 1,
+			pageSize: 10,
+			hasMore: true,
+			loading: false
 		}
 	},
 	watch: {
@@ -179,6 +193,9 @@ export default {
 		}
 	},
 	onLoad() {
+		
+	},
+	onShow() {
 		this.loadData()
 	},
 	onReachBottom() {
@@ -190,6 +207,8 @@ export default {
 		},
 		switchTab(value) {
 			this.currentTab = value
+			this.pageNum = 1
+			this.hasMore = true
 			this.loadData()
 		},
 		closeFilter() {
@@ -239,6 +258,8 @@ export default {
 			}
 			this.selectedTaskType = this.tempSelectedTaskType
 			this.showFilter = false
+			this.pageNum = 1
+			this.hasMore = true
 			this.loadData()
 		},
 		goComplete(item) {
@@ -259,100 +280,86 @@ export default {
 		},
 		async loadData() {
 			try {
+				this.pageNum = 1
+				this.hasMore = true
 				uni.showLoading({ title: '加载中...' })
-				const res = await getAirClassroomList({
-					status: this.currentTab,
-					startDate: this.dateRange.startDate,
-					endDate: this.dateRange.endDate,
-					taskType: this.selectedTaskType,
-					page: 1,
-					pageSize: 20
-				})
+				// 构建请求参数
+				const params = {
+					beginTime: this.dateRange.startDate,
+					endTime: this.dateRange.endDate,
+					finishAuditStatus:this.currentTab,
+					taskType:4,
+					pageNum: 1,
+					pageSize: this.pageSize
+				}
+				const res = await getAirClassroomList(params)
 				uni.hideLoading()
-				if (res.code === 200 && res.data) {
-					this.taskList = res.data.list || this.getDefaultData()
+				if (res.code === 200) {
+					this.taskList = res.rows || []
+					// 判断是否还有更多数据
+					if (!res.rows || res.rows.length < this.pageSize) {
+						this.hasMore = false
+					}
 				} else {
-					this.taskList = this.getDefaultData()
+					uni.showToast({
+						icon: 'none',
+						title: res.msg
+					})
 				}
 			} catch (e) {
 				uni.hideLoading()
-				console.error('加载数据失败', e)
-				this.taskList = this.getDefaultData()
 			}
 		},
 		async loadMore() {
-			// 加载更多数据
-		},
-		getDefaultData() {
-			return [
-				{
-					id: 1,
-					title: '王小明医生空中任务',
-					videoType: '长视频',
-					category: '学术',
-					points: '10',
-					count: '1',
-					startTime: '2025-9-20 13:55',
-					endTime: '2025-9-20 13:55',
-					createTime: '2025-9-20 13:55',
-					status: 'pending',
-					statusText: '待完成'
-				},
-				{
-					id: 2,
-					title: '王小明医生空中任务',
-					videoType: '长视频',
-					category: '学术',
-					points: '10',
-					count: '1',
-					startTime: '2025-9-20 13:55',
-					endTime: '2025-9-20 13:55',
-					createTime: '2025-9-20 13:55',
-					status: 'pending',
-					statusText: '待完成',
-					warning: '有效观看不足5人'
-				},
-				{
-					id: 3,
-					title: '王小明医生空中任务',
-					videoType: '短视频',
-					category: '学术',
-					points: '10',
-					count: '1',
-					startTime: '2025-9-20 13:55',
-					endTime: '2025-9-20 13:55',
-					createTime: '2025-9-20 13:55',
-					status: 'reviewing',
-					statusText: '待审核'
-				},
-				{
-					id: 4,
-					title: '王小明医生空中任务',
-					videoType: '文章',
-					category: '学术',
-					points: '10',
-					count: '1',
-					startTime: '2025-9-20 13:55',
-					endTime: '2025-9-20 13:55',
-					createTime: '2025-9-20 13:55',
-					status: 'rejected',
-					statusText: '已驳回',
-					rejectionReason: '交付物无效,请重新编辑'
-				},
-				{
-					id: 5,
-					title: '王小明医生空中任务',
-					videoType: '长视频',
-					category: '学术',
-					points: '10',
-					count: '1',
-					startTime: '2025-9-20 13:55',
-					endTime: '2025-9-20 13:55',
-					createTime: '2025-9-20 13:55',
-					status: 'approved',
-					statusText: '已通过'
+			// 如果没有更多数据或正在加载,则不执行
+			if (!this.hasMore || this.loading) {
+				return
+			}
+			
+			try {
+				this.loading = true
+				const nextPage = this.pageNum + 1
+				// 构建请求参数
+				const params = {
+					beginTime: this.dateRange.startDate,
+					endTime: this.dateRange.endDate,
+					finishAuditStatus:this.currentTab,
+					taskType: 4,
+					pageNum: nextPage,
+					pageSize: this.pageSize
 				}
-			]
+				
+				const res = await getAirClassroomList(params)
+				
+				if (res.code === 200) {
+					const newData = res.rows || []
+					if (newData.length > 0) {
+						// 追加新数据到列表
+						this.taskList = [...this.taskList, ...newData]
+						this.pageNum = nextPage
+						// 如果返回的数据量小于 pageSize,说明没有更多数据了
+						if (newData.length < this.pageSize) {
+							this.hasMore = false
+						}
+					} else {
+						// 没有新数据,说明已经加载完所有数据
+						this.hasMore = false
+					}
+				} else {
+					uni.showToast({
+						icon: 'none',
+						title: res.msg || '加载失败'
+					})
+				}
+			} catch (e) {
+				console.error('加载更多数据失败', e)
+				uni.showToast({
+					icon: 'none',
+					title: '加载失败'
+				})
+			} finally {
+				this.loading = false
+			}
 		}
 	}
 }
@@ -361,7 +368,6 @@ export default {
 <style lang="scss" scoped>
 .container {
 	min-height: 100vh;
-	background: #f5f5f5;
 	display: flex;
 	flex-direction: column;
 }
@@ -476,10 +482,22 @@ export default {
 	box-sizing: border-box;
 }
 
+.no-more {
+	text-align: center;
+	padding: 48rpx 0;
+	font-size: 24rpx;
+	color: #999;
+}
+.empty-state {
+	padding: 120rpx 24rpx;
+	text-align: center;
+	font-size: 28rpx;
+	color: #999;
+}
 .task-card {
 	background: #fff;
-	border-radius: 16rpx;
-	padding: 24rpx;
+	border-radius: 24rpx 24rpx 24rpx 24rpx;
+	border: 2rpx solid #E9F2FF;
 	margin-bottom: 24rpx;
 	
 	.card-header {
@@ -487,7 +505,9 @@ export default {
 		align-items: flex-start;
 		justify-content: space-between;
 		margin-bottom: 16rpx;
-		
+		padding: 24rpx;
+		background: linear-gradient( 90deg, #E8F1FF 0%, #FFFFFF 100%);
+		border-radius: 24rpx 24rpx 0rpx 0rpx;
 		.card-title {
 			flex: 1;
 			font-size: 32rpx;
@@ -500,24 +520,28 @@ export default {
 			border-radius: 20rpx;
 			font-size: 24rpx;
 			
-			&.pending {
-				background: #E3F2FD;
-				color: #2196F3;
-			}
-			
-			&.reviewing {
+			&.tag0 {
+				// 待审核
 				background: #FFF3E0;
 				color: #FF9800;
 			}
 			
-			&.approved {
+			&.tag1 {
+				// 已通过
 				background: #E8F5E9;
 				color: #4CAF50;
 			}
 			
-			&.rejected {
-				background: #FFEBEE;
-				color: #F44336;
+			&.tag2 {
+				// 已驳回
+				background: #FFF4F5;
+				color: #CF3546;
+			}
+			
+			&.tag3 {
+				// 未完成
+				background: #EBF5FF;
+				color: #388BFF;
 			}
 		}
 	}
@@ -531,14 +555,16 @@ export default {
 		
 		.tag-item {
 			padding: 8rpx 16rpx;
-			background: #f5f5f5;
+			// background: #f5f5f5;
 			border-radius: 8rpx;
 			font-size: 24rpx;
-			color: #666;
+			color: #999999;
+			border-radius: 8rpx 8rpx 8rpx 8rpx;
+			border: 2rpx solid #F5F5F5;
 			&.category{
 				border-radius: 0rpx 8rpx 8rpx 0rpx;
 			    border: 2rpx solid #F3D191;
-				background: #FFE9C7;
+				background: #FFFAF4;
 				color:#5D410F
 			}
 			&.video-tag {
@@ -769,5 +795,6 @@ export default {
 		}
 	}
 }
+
 </style>
 

+ 801 - 0
pages_task/shortVideo.vue

@@ -0,0 +1,801 @@
+<template>
+	<view class="container">
+		
+		<!-- 筛选标签栏 -->
+		<view class="filter-bar">
+			<view class="filter-tabs">
+				<view class="tab-item" 
+					:class="{ active: currentTab === item.value }" 
+					v-for="(item, index) in tabs" 
+					:key="index"
+					@click="switchTab(item.value)">
+					{{ item.label }}
+				</view>
+			</view>
+			<view class="filter-divider"></view>
+			<view class="filter-btn" @click="showFilter = true">
+				<image class="w32 h32" src="@/static/image/icon_select.png" mode=""></image>
+			</view>
+		</view>
+		
+		<!-- 任务列表 -->
+		<scroll-view class="content" scroll-y>
+			<view class="task-card" v-for="(item, index) in taskList" :key="index" @click="showDetail(item)">
+				<view class="card-header">
+					<view class="card-title">{{ item.taskName}}</view>
+					<view class="status-tag" :class="'tag'+item.finishAuditStatus">
+						{{ item.finishAuditStatus==0?'待审核':item.finishAuditStatus==1?'已通过':item.finishAuditStatus==2?'已驳回':'未完成'}}
+					</view>
+				</view>
+				<view style="padding: 24rpx;">
+				<view class="card-tags">
+					<view class="x-f">
+						<view class="tag-item video-tag" v-if="item.taskType">
+							<!-- <image class="w28 h28 mr10" src="@/static/image/icon_longvideo.png" mode=""></image> -->
+							<image class="w28 h28 mr10" src="@/static/image/icon_article.png" mode=""></image>
+							<text>{{ item.taskType==4?'文章':taskData.taskType==5?'短视频':'长视频'}}</text>
+							
+						</view>
+						<view class="tag-item category">
+							学术
+						</view>
+					</view>
+					
+					<view class="tag-item points-tag">
+						{{ item.taskIntegral }}积分
+					</view>
+					<view class="tag-item">
+						{{ item.taskCount }}{{item.taskUnitName}}
+					</view>
+				</view>
+				
+				<view class="card-dates">
+					<view class="date-item">
+						<text>开始时间:{{ item.planStartTime }}</text>
+					</view>
+					<view class="date-item">
+						<text>结束时间:{{ item.planEndTime }}</text>
+					</view>
+				</view>
+				
+				<view class="card-warning" v-if="item.warning">
+					<image class="w28 h28 mr8" src="@/static/image/icon_admonish.png" mode=""></image>
+					<text>{{ item.warning }}</text>
+				</view>
+				
+				<view class="card-rejection" v-if="item.finishAuditStatus == 2">
+					<image class="w28 h28 mr8" src="@/static/image/icon_reject.png" mode=""></image>
+					<text>驳回原因: {{ item.finishAuditRemark }}</text>
+				</view>
+				
+				<view class="card-footer">
+					<view class="footer-date">{{ item.createTime }}</view>
+					<view class="footer-actions">
+						<view class="action-btn" v-if="item.finishAuditStatus==3">
+							去完成
+						</view>
+						<view class="action-btn" v-if="item.finishAuditStatus == 2" @click="goEdit(item)">
+							编辑
+						</view>
+					</view>
+				</view>
+				</view>
+			</view>
+			
+			<view class="no-more" v-if="!hasMore && taskList.length > 0">没有更多了~</view>
+			<view class="empty-state y-bc" v-if="taskList.length === 0">
+				<image class="w300 h300" src="@/static/image/img_blank_nodata.png" mode=""></image>
+				<text>暂无数据</text>
+			</view>
+		</scroll-view>
+		
+		<!-- 筛选弹窗 -->
+		<view class="filter-popup" v-if="showFilter" @click="closeFilter">
+			<view class="filter-content" @click.stop>
+				<view class="filter-header">
+					<view class="filter-title">筛选</view>
+					<view class="filter-close-btn" @click="closeFilter">
+						<image class="w44 h44" src="@/static/image/icon_cross.png" mode=""></image>
+					</view>
+				</view>
+				
+				<!-- 申请时间筛选 -->
+				<view class="filter-group">
+					<view class="group-label">申请时间</view>
+					<view class="date-range-inputs">
+						<picker style="flex:1" mode="date" :value="tempDateRange.startDate" @change="onStartDateChange">
+							<view class="date-input" :class="{ placeholder: !tempDateRange.startDate }">
+								{{ tempDateRange.startDate || '开始时间' }}
+							</view>
+						</picker>
+						<text class="date-separator">-</text>
+						<picker style="flex:1" mode="date" :value="tempDateRange.endDate" @change="onEndDateChange">
+							<view class="date-input" :class="{ placeholder: !tempDateRange.endDate }">
+								{{ tempDateRange.endDate || '结束时间' }}
+							</view>
+						</picker>
+					</view>
+				</view>
+				
+				<!-- 任务类型筛选 -->
+				<!-- <view class="filter-group">
+					<view class="group-label">任务类型</view>
+					<view class="filter-tags">
+						<view 
+							class="filter-tag" 
+							:class="{ active: tempSelectedTaskType === item.value }"
+							v-for="(item, index) in taskTypeOptions" 
+							:key="index"
+							@click="selectTaskType(item.value)">
+							{{ item.label }}
+						</view>
+					</view>
+				</view> -->
+				
+				<!-- 操作按钮 -->
+				<view class="filter-actions">
+					<view class="reset-btn" @click="resetFilters">重置</view>
+					<view class="confirm-btn" @click="confirmFilters">确定</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+import { getAirClassroomList ,getTaskDetail,submitTask} from '@/api/airClassroom'
+import { getTaskTypeList } from '@/api/common.js'
+export default {
+	data() {
+		return {
+			statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
+			currentTab: '',
+			showFilter: false,
+			dateRange: {
+				startDate: '',
+				endDate: ''
+			},
+			tempDateRange: {
+				startDate: '',
+				endDate: ''
+			},
+			selectedTaskType: 'article', // 默认选中科普文章
+			tempSelectedTaskType: 'article',
+			// taskTypeOptions: [
+			// 	{ label: '科普文章', value: 'article' },
+			// 	{ label: '科普短视频', value: 'shortVideo' },
+			// 	{ label: '科普长视频', value: 'longVideo' }
+			// ],
+			tabs: [
+				{ label: '全部', value:''},
+				{ label: '未完成', value: 3},
+				{ label: '待审核', value: 0},
+				{ label: '已通过', value: 1},
+				{ label: '已驳回', value: 2}
+			],
+			taskList: [],
+			pageNum: 1,
+			pageSize: 10,
+			hasMore: true,
+			loading: false
+		}
+	},
+	watch: {
+		showFilter(newVal) {
+			if (newVal) {
+				// 打开弹窗时,同步临时日期范围和任务类型为当前值
+				this.tempDateRange = {
+					startDate: this.dateRange.startDate,
+					endDate: this.dateRange.endDate
+				}
+				this.tempSelectedTaskType = this.selectedTaskType
+			}
+		}
+	},
+	onLoad() {
+		
+	},
+	onShow() {
+		this.loadData()
+	},
+	onReachBottom() {
+		this.loadMore()
+	},
+	methods: {
+		goBack() {
+			uni.navigateBack()
+		},
+		switchTab(value) {
+			this.currentTab = value
+			this.pageNum = 1
+			this.hasMore = true
+			this.loadData()
+		},
+		closeFilter() {
+			// 关闭弹窗时,恢复临时日期范围和任务类型为当前值
+			this.tempDateRange = {
+				startDate: this.dateRange.startDate,
+				endDate: this.dateRange.endDate
+			}
+			this.tempSelectedTaskType = this.selectedTaskType
+			this.showFilter = false
+		},
+		selectTaskType(value) {
+			// 如果点击的是已选中的,则取消选择
+			if (this.tempSelectedTaskType === value) {
+				this.tempSelectedTaskType = ''
+			} else {
+				this.tempSelectedTaskType = value
+			}
+		},
+		onStartDateChange(e) {
+			this.tempDateRange.startDate = e.detail.value
+		},
+		onEndDateChange(e) {
+			this.tempDateRange.endDate = e.detail.value
+		},
+		resetFilters() {
+			this.tempDateRange = {
+				startDate: '',
+				endDate: ''
+			}
+			this.tempSelectedTaskType = ''
+		},
+		confirmFilters() {
+			// 验证日期范围
+			if (this.tempDateRange.startDate && this.tempDateRange.endDate) {
+				if (new Date(this.tempDateRange.startDate) > new Date(this.tempDateRange.endDate)) {
+					uni.showToast({
+						icon: 'none',
+						title: '开始时间不能大于结束时间'
+					})
+					return
+				}
+			}
+			this.dateRange = {
+				startDate: this.tempDateRange.startDate,
+				endDate: this.tempDateRange.endDate
+			}
+			this.selectedTaskType = this.tempSelectedTaskType
+			this.showFilter = false
+			this.pageNum = 1
+			this.hasMore = true
+			this.loadData()
+		},
+		goComplete(item) {
+			uni.navigateTo({
+				url: `/pages_task/completeTask?id=${item.id}`
+			})
+		},
+		goEdit(item) {
+			uni.navigateTo({
+				url: `/pages_task/completeTask?id=${item.id}&edit=true`
+			})
+		},
+		// 查看详情
+		showDetail(item) {
+			uni.navigateTo({
+				url: `/pages_task/taskDetail?id=${item.id}`
+			})
+		},
+		async loadData() {
+			try {
+				this.pageNum = 1
+				this.hasMore = true
+				uni.showLoading({ title: '加载中...' })
+				// 构建请求参数
+				const params = {
+					beginTime: this.dateRange.startDate,
+					endTime: this.dateRange.endDate,
+					finishAuditStatus:this.currentTab,
+					taskType:5,
+					pageNum: 1,
+					pageSize: this.pageSize
+				}
+				const res = await getAirClassroomList(params)
+				uni.hideLoading()
+				if (res.code === 200) {
+					this.taskList = res.rows || []
+					// 判断是否还有更多数据
+					if (!res.rows || res.rows.length < this.pageSize) {
+						this.hasMore = false
+					}
+				} else {
+					uni.showToast({
+						icon: 'none',
+						title: res.msg
+					})
+				}
+			} catch (e) {
+				uni.hideLoading()
+			}
+		},
+		async loadMore() {
+			// 如果没有更多数据或正在加载,则不执行
+			if (!this.hasMore || this.loading) {
+				return
+			}
+			
+			try {
+				this.loading = true
+				const nextPage = this.pageNum + 1
+				// 构建请求参数
+				const params = {
+					beginTime: this.dateRange.startDate,
+					endTime: this.dateRange.endDate,
+					finishAuditStatus:this.currentTab,
+					taskType: 5,
+					pageNum: nextPage,
+					pageSize: this.pageSize
+				}
+				
+				const res = await getAirClassroomList(params)
+				
+				if (res.code === 200) {
+					const newData = res.rows || []
+					if (newData.length > 0) {
+						// 追加新数据到列表
+						this.taskList = [...this.taskList, ...newData]
+						this.pageNum = nextPage
+						// 如果返回的数据量小于 pageSize,说明没有更多数据了
+						if (newData.length < this.pageSize) {
+							this.hasMore = false
+						}
+					} else {
+						// 没有新数据,说明已经加载完所有数据
+						this.hasMore = false
+					}
+				} else {
+					uni.showToast({
+						icon: 'none',
+						title: res.msg || '加载失败'
+					})
+				}
+			} catch (e) {
+				console.error('加载更多数据失败', e)
+				uni.showToast({
+					icon: 'none',
+					title: '加载失败'
+				})
+			} finally {
+				this.loading = false
+			}
+		}
+	}
+}
+</script>
+
+<style lang="scss" scoped>
+.container {
+	min-height: 100vh;
+	background: #f5f5f5;
+	display: flex;
+	flex-direction: column;
+}
+
+.status-bar {
+	width: 100%;
+	background: #fff;
+}
+
+.header {
+	position: relative;
+	height: 88rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	background: #fff;
+	border-bottom: 1rpx solid #f0f0f0;
+	
+	.back-btn {
+		position: absolute;
+		left: 24rpx;
+		width: 40rpx;
+		height: 40rpx;
+		
+		image {
+			width: 100%;
+			height: 100%;
+		}
+	}
+	
+	.title {
+		font-size: 36rpx;
+		font-weight: bold;
+		color: #333;
+	}
+	
+	.header-right {
+		position: absolute;
+		right: 24rpx;
+		display: flex;
+		align-items: center;
+		gap: 16rpx;
+		
+		.more-icon {
+			font-size: 32rpx;
+			color: #333;
+		}
+	}
+}
+
+.filter-bar {
+	display: flex;
+	align-items: center;
+	background: #fff;
+	padding: 0 24rpx;
+	border-bottom: 1rpx solid #f0f0f0;
+	
+	.filter-tabs {
+		flex: 1;
+		display: flex;
+		align-items: center;
+		gap: 48rpx;
+		overflow-x: auto;
+		
+		.tab-item {
+			padding: 24rpx 0;
+			font-size: 28rpx;
+			color: #969799;
+			white-space: nowrap;
+			position: relative;
+			
+			&.active {
+				font-weight: 500;
+				font-size: 28rpx;
+				color: #333333;
+				
+				&::after {
+					content: '';
+					position: absolute;
+					bottom: 0;
+					left: 50%;
+					transform: translateX(-50%);
+					width: 56rpx;
+					height: 6rpx;
+					background: #388BFF;
+					border-radius: 3rpx 3rpx 3rpx 3rpx;
+				}
+			}
+		}
+	}
+	
+	.filter-divider {
+		width: 1rpx;
+		height: 40rpx;
+		background: #e0e0e0;
+		margin: 0 16rpx;
+	}
+	
+	.filter-btn {
+		padding: 24rpx 0;
+		
+		.filter-icon {
+			font-size: 32rpx;
+			color: #333;
+		}
+	}
+}
+
+.content {
+	flex: 1;
+	padding: 24rpx;
+	box-sizing: border-box;
+}
+
+.no-more {
+	text-align: center;
+	padding: 48rpx 0;
+	font-size: 24rpx;
+	color: #999;
+}
+.empty-state {
+	padding: 120rpx 24rpx;
+	text-align: center;
+	font-size: 28rpx;
+	color: #999;
+}
+.task-card {
+	background: #fff;
+	border-radius: 24rpx 24rpx 24rpx 24rpx;
+	border: 2rpx solid #E9F2FF;
+	margin-bottom: 24rpx;
+	
+	.card-header {
+		display: flex;
+		align-items: flex-start;
+		justify-content: space-between;
+		margin-bottom: 16rpx;
+		padding: 24rpx;
+		background: linear-gradient( 90deg, #E8F1FF 0%, #FFFFFF 100%);
+		border-radius: 24rpx 24rpx 0rpx 0rpx;
+		
+		.card-title {
+			flex: 1;
+			font-size: 32rpx;
+			font-weight: bold;
+			color: #333;
+		}
+		
+		.status-tag {
+			padding: 8rpx 16rpx;
+			border-radius: 20rpx;
+			font-size: 24rpx;
+			
+			&.tag0 {
+				// 待审核
+				background: #FFF3E0;
+				color: #FF9800;
+			}
+			
+			&.tag1 {
+				// 已通过
+				background: #E8F5E9;
+				color: #4CAF50;
+			}
+			
+			&.tag2 {
+				// 已驳回
+				background: #FFF4F5;
+				color: #CF3546;
+			}
+			
+			&.tag3 {
+				// 未完成
+				background: #EBF5FF;
+				color: #388BFF;
+			}
+		}
+	}
+	
+	.card-tags {
+		display: flex;
+		align-items: center;
+		flex-wrap: wrap;
+		gap: 12rpx;
+		margin-bottom: 16rpx;
+		
+		.tag-item {
+			padding: 8rpx 16rpx;
+			// background: #f5f5f5;
+			border-radius: 8rpx;
+			font-size: 24rpx;
+			color: #999999;
+			border-radius: 8rpx 8rpx 8rpx 8rpx;
+			border: 2rpx solid #F5F5F5;
+			&.category{
+				border-radius: 0rpx 8rpx 8rpx 0rpx;
+			    border: 2rpx solid #F3D191;
+				background: #FFFAF4;
+				color:#5D410F
+			}
+			&.video-tag {
+				background: linear-gradient( 90deg, #FFE9C7 0%, #F3D091 100%);
+				border-radius:8rpx 0rpx 0rpx 8rpx;
+				border: 2rpx solid #F3D191;
+				font-family: PingFang SC, PingFang SC;
+				font-weight: 400;
+				font-size: 24rpx;
+				color: #5D410F;
+				display: flex;
+				align-items: center;
+				.tag-icon {
+					margin-right: 4rpx;
+				}
+			}
+			
+			&.points-tag {
+				border: 1rpx solid #388BFF;
+				color: #388BFF;
+				background: transparent;
+				
+			}
+		}
+	}
+	
+	.card-dates {
+		margin-bottom: 16rpx;
+		
+		.date-item {
+			font-size: 26rpx;
+			color: #999;
+			margin-bottom: 8rpx;
+		}
+	}
+	
+	.card-warning {
+		display: flex;
+		align-items: center;
+		gap: 8rpx;
+		padding: 12rpx;
+		background: #FFF3E0;
+		border-radius: 8rpx;
+		margin-bottom: 16rpx;
+		font-size: 26rpx;
+		color: #FF9800;
+		
+		.warning-icon {
+			font-size: 28rpx;
+		}
+	}
+	
+	.card-rejection {
+		display: flex;
+		align-items: center;
+		gap: 8rpx;
+		padding: 12rpx;
+		background: #FFEBEE;
+		border-radius: 8rpx;
+		margin-bottom: 16rpx;
+		font-size: 26rpx;
+		color: #F44336;
+		
+		.rejection-icon {
+			font-size: 28rpx;
+		}
+	}
+	
+	.card-footer {
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		padding-top: 16rpx;
+		border-top: 1rpx solid #f0f0f0;
+		
+		.footer-date {
+			font-size: 24rpx;
+			color: #999;
+		}
+		
+		.footer-actions {
+			.action-btn {
+				padding: 12rpx 32rpx;
+				background: #388BFF;
+				border-radius: 34rpx 34rpx 34rpx 34rpx;
+				font-size: 28rpx;
+				color: #fff;
+			}
+		}
+	}
+}
+
+.filter-popup {
+	position: fixed;
+	top: 0;
+	left: 0;
+	right: 0;
+	bottom: 0;
+	background: rgba(0, 0, 0, 0.5);
+	z-index: 999;
+	display: flex;
+	align-items: flex-end;
+}
+
+.filter-content {
+	width: 100%;
+	background: #fff;
+	border-radius: 24rpx 24rpx 0 0;
+	padding: 32rpx;
+	
+	.filter-header {
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		// padding: 32rpx 24rpx;
+		position: relative;
+		
+		.filter-title {
+			font-family: PingFang SC, PingFang SC;
+			font-weight: 500;
+			font-size: 32rpx;
+			color: #333333;
+		}
+		
+		.filter-close-btn {
+			position: absolute;
+			right: 24rpx;
+			top: 50%;
+			transform: translateY(-50%);
+			font-size: 48rpx;
+			color: #999;
+			width: 48rpx;
+			height: 48rpx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			line-height: 1;
+		}
+	}
+	
+	.filter-group {
+		margin-bottom: 32rpx;
+		
+		.group-label {
+			font-size: 28rpx;
+			font-weight: bold;
+			color: #333;
+			margin-bottom: 20rpx;
+		}
+		
+		.date-range-inputs {
+			display: flex;
+			align-items: center;
+			gap: 16rpx;
+			
+			.date-input {
+				flex: 1;
+				height: 80rpx;
+				line-height: 80rpx;
+				padding: 0 24rpx;
+				background: #f5f5f5;
+				border-radius: 8rpx;
+				font-size: 28rpx;
+				color: #333;
+				text-align: center;
+				
+				&.placeholder {
+					color: #999;
+				}
+			}
+			
+		.date-separator {
+			font-size: 28rpx;
+			color: #666;
+		}
+	}
+	
+	.filter-tags {
+		display: flex;
+		flex-wrap: wrap;
+		gap: 16rpx;
+		
+		.filter-tag {
+			padding: 14rpx 36rpx;
+			background: #F7F8FA;
+			border-radius: 70rpx 70rpx 70rpx 70rpx;
+			font-family: PingFang SC, PingFang SC;
+			font-weight: 400;
+			font-size: 28rpx;
+			color: #333333;
+			border: 1rpx solid transparent;
+			
+			&.active {
+				background: rgba(56,139,255,0.15);
+				color: #388BFF;
+				border-color: #388BFF;
+			}
+		}
+	}
+}
+	
+	.filter-actions {
+		display: flex;
+		gap: 24rpx;
+		margin-top: 40rpx;
+		padding-top: 24rpx;
+		border-top: 1rpx solid #f0f0f0;
+		
+		.reset-btn,
+		.confirm-btn {
+			flex: 1;
+			height: 88rpx;
+			line-height: 88rpx;
+			text-align: center;
+			border-radius: 200rpx 200rpx 200rpx 200rpx;
+			font-size: 30rpx;
+		}
+		
+		.reset-btn {
+			background: #fff;
+			color: #666;
+			border: 1rpx solid #e0e0e0;
+		}
+		
+		.confirm-btn {
+			background: #388BFF;
+			color: #fff;
+		}
+	}
+}
+</style>
+

+ 15 - 119
pages_task/taskCompleteSuccess.vue

@@ -1,33 +1,9 @@
 <template>
 	<view class="container">
 		<!-- 状态栏占位 -->
-		<view class="status-bar" :style="{height: statusBarHeight}"></view>
-		
-		<!-- 顶部导航栏 -->
-		<view class="header">
-			<view class="back-btn" @click="goBack">
-				<image src="@/static/image/back.png" mode="aspectFill"></image>
-			</view>
-			<view class="title">完成任务</view>
-			<view class="header-right">
-				<text class="more-icon">⋯</text>
-				<text class="more-icon">○</text>
-			</view>
-		</view>
-		
 		<view class="content">
 			<view class="success-content">
-				<view class="success-icon-wrapper">
-					<view class="success-icon">
-						<text class="checkmark">✓</text>
-					</view>
-					<view class="success-ring ring1"></view>
-					<view class="success-ring ring2"></view>
-					<view class="decoration dot1"></view>
-					<view class="decoration dot2"></view>
-					<view class="decoration plus"></view>
-					<view class="decoration dot3"></view>
-				</view>
+				<image class="w320" src="@/static/image/img_success.png" mode="widthFix"></image>
 				<view class="success-text">任务已完成</view>
 			</view>
 			
@@ -51,7 +27,7 @@ export default {
 		},
 		goBackToList() {
 			uni.navigateBack({
-				delta: 2
+				delta: 3
 			})
 		}
 	}
@@ -117,8 +93,8 @@ export default {
 	display: flex;
 	flex-direction: column;
 	align-items: center;
-	justify-content: center;
-	padding: 48rpx;
+	// justify-content: center;
+	padding-top: 190rpx;
 }
 
 .success-content {
@@ -127,99 +103,13 @@ export default {
 	align-items: center;
 	margin-bottom: 80rpx;
 	
-	.success-icon-wrapper {
-		position: relative;
-		width: 200rpx;
-		height: 200rpx;
-		margin-bottom: 48rpx;
-		
-		.success-icon {
-			position: absolute;
-			top: 50%;
-			left: 50%;
-			transform: translate(-50%, -50%);
-			width: 120rpx;
-			height: 120rpx;
-			background: #4CAF50;
-			border-radius: 50%;
-			display: flex;
-			align-items: center;
-			justify-content: center;
-			z-index: 3;
-			
-			.checkmark {
-				font-size: 80rpx;
-				color: #fff;
-				font-weight: bold;
-			}
-		}
-		
-		.success-ring {
-			position: absolute;
-			top: 50%;
-			left: 50%;
-			transform: translate(-50%, -50%);
-			border-radius: 50%;
-			border: 2rpx solid rgba(76, 175, 80, 0.3);
-			
-			&.ring1 {
-				width: 160rpx;
-				height: 160rpx;
-				z-index: 2;
-			}
-			
-			&.ring2 {
-				width: 200rpx;
-				height: 200rpx;
-				z-index: 1;
-			}
-		}
-		
-		.decoration {
-			position: absolute;
-			
-			&.dot1 {
-				top: 20rpx;
-				left: 20rpx;
-				width: 12rpx;
-				height: 12rpx;
-				background: rgba(76, 175, 80, 0.3);
-				border-radius: 50%;
-			}
-			
-			&.dot2 {
-				top: 30rpx;
-				right: 40rpx;
-				width: 8rpx;
-				height: 8rpx;
-				background: #FFC107;
-				border-radius: 50%;
-			}
-			
-			&.plus {
-				top: 10rpx;
-				right: 20rpx;
-				width: 16rpx;
-				height: 16rpx;
-				color: rgba(76, 175, 80, 0.3);
-				font-size: 16rpx;
-			}
-			
-			&.dot3 {
-				bottom: 30rpx;
-				right: 30rpx;
-				width: 8rpx;
-				height: 8rpx;
-				background: #FFC107;
-				border-radius: 50%;
-			}
-		}
-	}
-	
 	.success-text {
+		margin-top: 48rpx;
+		font-family: PingFang SC, PingFang SC;
+		font-weight: 500;
 		font-size: 36rpx;
-		font-weight: bold;
-		color: #333;
+		color: #333333;
+		line-height: 44rpx;
 	}
 }
 
@@ -246,3 +136,9 @@ export default {
 
 
 
+
+
+
+
+
+

+ 188 - 74
pages_task/taskDetail.vue

@@ -1,28 +1,45 @@
 <template>
 	<view class="container">
+      <!-- <image class="bg" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/bg_qestion.png" mode="widthFix"></image> -->
+		<view class="bg"></view>
+		<view class="fixed-top-box" :style="{background: bgColor }">
+			<view class="status_bar" :style="{height: statusBarHeight}"></view>
+			<view class="back-box" @click="goBack">
+				<image src="@/static/image/icon_back_w.png" mode=""></image>
+				<text class="title">任务详情</text>
+				<text></text>
+			</view>
+		</view>
 		<scroll-view class="content" scroll-y>
 			<!-- 任务卡片 -->
 			<view class="task-card">
 				<view class="card-header">
-					<view class="card-title">{{ taskData.title }}</view>
-					<view class="status-tag" :class="taskData.status">
-						{{ taskData.statusText }}
+					<view class="card-title">{{ taskData.taskName || '-'}}</view>
+					<view class="status-tag" :class="'tag'+taskData.finishAuditStatus">
+						{{ taskData.finishAuditStatus==0?'待审核':taskData.finishAuditStatus==1?'已通过':taskData.finishAuditStatus==2?'已驳回':'未完成'}}
 					</view>
 				</view>
 				
 				<view class="card-tags">
+					<view class="x-f">
 					<view class="tag-item video-tag">
-						<text class="tag-icon">▶</text>
-						<text>{{ taskData.videoType }}</text>
+						<image v-if="taskData.taskType==4" class="w28 h28 mr10" src="@/static/image/icon_article.png" mode=""></image>
+						<image v-else class="w28 h28 mr10" src="@/static/image/icon_longvideo.png" mode=""></image>
+						<text>{{ taskData.taskType==4?'文章':taskData.taskType==5?'短视频':'长视频'}}</text>
 					</view>
-					<view class="tag-item">{{ taskData.category }}</view>
-					<view class="tag-item points-tag">{{ taskData.points }}积分</view>
-					<view class="tag-item">{{ taskData.count }}个</view>
+					<view class="tag-item category">学术</view>
+					</view>
+					<view class="tag-item points-tag">{{ taskData.taskIntegral || 0}}积分</view>
+					<view class="tag-item">{{ taskData.taskUnit || 0 }}个</view>
 				</view>
 				
 				<view class="card-dates">
-					<view class="date-item">开始时间: {{ taskData.startTime }}</view>
-					<view class="date-item">结束时间: {{ taskData.endTime }}</view>
+					<view class="date-item">开始时间:{{ taskData.planStartTime || '-' }}</view>
+					<view class="date-item">结束时间:{{ taskData.planEndTime || '-'}}</view>
+				</view>
+				<view class="card-rejection" v-if="taskData.finishAuditStatus == 2">
+					<image class="w28 h28 mr8" src="@/static/image/icon_reject.png" mode=""></image>
+					<text>驳回原因: {{ taskData.finishAuditRemark }}</text>
 				</view>
 			</view>
 			
@@ -35,31 +52,31 @@
 				<view class="info-list">
 					<view class="info-item">
 						<text class="info-label">项目名称:</text>
-						<text class="info-value">{{ projectData.projectName }}</text>
+						<text class="info-value">{{ taskData.projectName||'-' }}</text>
 					</view>
 					<view class="info-item">
 						<text class="info-label">任务ID:</text>
-						<text class="info-value">{{ projectData.taskId }}</text>
+						<text class="info-value">{{ projectData.taskId ||'-'}}</text>
 					</view>
 					<view class="info-item">
 						<text class="info-label">交付物ID:</text>
-						<text class="info-value">{{ projectData.deliverableId }}</text>
+						<text class="info-value">{{ projectData.deliveryNo||'-' }}</text>
 					</view>
 					<view class="info-item">
 						<text class="info-label">观看人数:</text>
-						<text class="info-value">{{ projectData.viewers }}</text>
+						<text class="info-value">{{ projectData.viewCount||0 }}</text>
 					</view>
 					<view class="info-item">
 						<text class="info-label">有效观看:</text>
-						<text class="info-value">{{ projectData.validViews }}</text>
+						<text class="info-value">{{ projectData.validViews||0 }}</text>
 					</view>
 					<view class="info-item">
 						<text class="info-label">标题:</text>
-						<text class="info-value">{{ projectData.title }}</text>
+						<text class="info-value">{{ projectData.title || '-'}}</text>
 					</view>
 					<view class="info-item">
 						<text class="info-label">项目信息:</text>
-						<text class="info-value">{{ projectData.projectInfo || '-' }}</text>
+						<text class="info-value">{{ projectData.content || '-' }}</text>
 					</view>
 					<view class="info-item">
 						<text class="info-label">封面图:</text>
@@ -70,7 +87,7 @@
 					</view>
 					<view class="info-item">
 						<text class="info-label">情况说明:</text>
-						<text class="info-value">{{ projectData.description || '-' }}</text>
+						<text class="info-value">{{ projectData.remark || '-' }}</text>
 					</view>
 				</view>
 			</view>
@@ -84,7 +101,7 @@
 				<view class="info-list">
 					<view class="info-item">
 						<text class="info-label">申请人姓名:</text>
-						<text class="info-value">{{ applicantData.name }}</text>
+						<text class="info-value">{{ taskData.doctorName || '-' }}</text>
 					</view>
 				</view>
 			</view>
@@ -98,68 +115,60 @@
 				<view class="info-list">
 					<view class="info-item">
 						<text class="info-label">客户名称:</text>
-						<text class="info-value">{{ clientData.name }}</text>
+						<text class="info-value">{{ clientData.doctorName || '-'}}</text>
 					</view>
 					<view class="info-item">
 						<text class="info-label">客户ID:</text>
-						<text class="info-value">{{ clientData.clientId }}</text>
+						<text class="info-value">{{ clientData.doctorId || '-'}}</text>
 					</view>
 					<view class="info-item">
 						<text class="info-label">归属医院:</text>
-						<text class="info-value">{{ clientData.hospital }}</text>
+						<text class="info-value">{{ clientData.institution || '-'}}</text>
 					</view>
 					<view class="info-item">
 						<text class="info-label">归属科室:</text>
-						<text class="info-value">{{ clientData.department }}</text>
+						<text class="info-value">{{ clientData.department || '-' }}</text>
 					</view>
 				</view>
 			</view>
 		</scroll-view>
 		
 		<!-- 底部按钮 -->
-		<view class="bottom-btn" v-if="taskData.status === 'pending'" @click="goComplete">
-			去完成
+			<view class="submit-box" v-if="taskData.finishAuditStatus == 3||taskData.finishAuditStatus == 2">
+			<view class="submit-btn"  @click="goComplete">去完成</view>
 		</view>
 	</view>
 </template>
 
 <script>
-import { getTaskDetail } from '@/api-js/airClassroom'
+import { getTaskDetail } from '@/api/airClassroom'
 export default {
 	data() {
 		return {
+			top:0,
 			statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
 			taskId: '',
 			taskData: {
-				title: '王小明医生学术视频任务',
-				videoType: '长视频',
-				category: '学术',
-				points: '10',
-				count: '1',
-				startTime: '2025-9-20 13:55',
-				endTime: '2025-9-20 13:55',
-				status: 'pending',
-				statusText: '待完成'
 			},
 			projectData: {
-				projectName: '王小明医学术视频任务',
-				taskId: 'CRW234443000221',
-				deliverableId: 'JF123456',
-				viewers: '688',
-				validViews: '680',
-				title: '康复医学概论',
-				projectInfo: '-',
-				coverImage: '',
-				description: '-'
+				// projectName: '王小明医学术视频任务',
+				// taskId: 'CRW234443000221',
+				// deliverableId: 'JF123456',
+				// viewers: '688',
+				// validViews: '680',
+				// title: '康复医学概论',
+				// projectInfo: '-',
+				// coverImage: '',
+				// description: '-'
 			},
 			applicantData: {
-				name: '张菲菲'
+				// name: '张菲菲'
 			},
 			clientData: {
-				name: '王小明',
-				clientId: 'C00000001231445',
-				hospital: '江南大学附属医院',
-				department: '消化内科'
+				// name: '王小明',
+				// clientId: 'C00000001231445',
+				// hospital: '江南大学附属医院',
+				// department: '消化内科'
 			}
 		}
 	},
@@ -169,25 +178,36 @@ export default {
 			this.loadData()
 		}
 	},
+	onPageScroll(e) {
+		//console.log(e)
+		this.top = e.scrollTop;
+	},
+	computed: {
+		// 计算属性的 getter
+		bgColor: function() {
+			var top = this.top / 30;
+			return 'rgba(56, 139, 255,' + top + ')';
+		},
+	},
 	methods: {
 		goBack() {
 			uni.navigateBack()
 		},
 		goComplete() {
 			uni.navigateTo({
-				url: `/pages_task/completeTask?id=${this.taskId}`
+				url: `/pages_task/completeTask?id=${this.taskId}&taskType=${this.taskData.taskType}`
 			})
 		},
 		async loadData() {
 			try {
 				uni.showLoading({ title: '加载中...' })
-				const res = await getTaskDetail({ id: this.taskId })
+				const res = await getTaskDetail(this.taskId)
 				uni.hideLoading()
 				if (res.code === 200 && res.data) {
-					this.taskData = { ...this.taskData, ...res.data.task }
-					this.projectData = { ...this.projectData, ...res.data.project }
+					this.taskData = { ...this.taskData, ...res.data }
+					this.projectData = { ...this.projectData, ...res.data.taskDelivery }
 					this.applicantData = { ...this.applicantData, ...res.data.applicant }
-					this.clientData = { ...this.clientData, ...res.data.client }
+					this.clientData = { ...this.clientData, ...res.data.doctorVO }
 				}
 			} catch (e) {
 				uni.hideLoading()
@@ -205,12 +225,44 @@ export default {
 	display: flex;
 	flex-direction: column;
 }
-
 .status-bar {
 	width: 100%;
 	background: #fff;
 }
-
+.bg{
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 532rpx;
+	background: linear-gradient( 180deg, rgba(56,139,255,0.79) 0%, rgba(56,139,255,0) 100%);
+}
+.fixed-top-box{
+			width: 100%;
+			// background: linear-gradient(135deg, #66b2ef 0%, #0bb3f2 100%);
+			position: fixed;
+			top: 0;
+			left: 0;
+			z-index: 1000;
+			.back-box{
+				height: 88upx;
+				padding-left: 22upx;
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				padding: 0 24upx;
+				image{
+					width: 48rpx;
+					height: 48rpx;
+				}
+				.title{
+					font-family: PingFang SC, PingFang SC;
+					font-weight: 600;
+					font-size: 36rpx;
+					color: #fff;
+				}
+			}
+		}
 .header {
 	position: relative;
 	height: 88rpx;
@@ -253,8 +305,11 @@ export default {
 }
 
 .content {
+	margin-top:168rpx;
 	flex: 1;
 	padding: 24rpx;
+	box-sizing: border-box;
+	padding-bottom: 120rpx;
 }
 
 .task-card {
@@ -280,12 +335,30 @@ export default {
 			padding: 8rpx 16rpx;
 			border-radius: 20rpx;
 			font-size: 24rpx;
+			&.tag0 {
+				// 待审核
+				background: #FFF3E0;
+				color: #FF9800;
+			}
 			
-			&.pending {
-				background: #E3F2FD;
-				color: #2196F3;
+			&.tag1 {
+				// 已通过
+				background: #E8F5E9;
+				color: #4CAF50;
+			}
+			
+			&.tag2 {
+				// 已驳回
+				background: #FFF4F5;
+				color: #CF3546;
+			}
+			&.tag3 {
+				// 未完成
+				background: #EBF5FF;
+				color: #388BFF;
 			}
 		}
+		
 	}
 	
 	.card-tags {
@@ -297,15 +370,28 @@ export default {
 		
 		.tag-item {
 			padding: 8rpx 16rpx;
-			background: #f5f5f5;
+			// background: #f5f5f5;
 			border-radius: 8rpx;
 			font-size: 24rpx;
-			color: #666;
-			
+			color: #999999;
+			border-radius: 8rpx 8rpx 8rpx 8rpx;
+			border: 2rpx solid #F5F5F5;
+			&.category{
+				border-radius: 0rpx 8rpx 8rpx 0rpx;
+			    border: 2rpx solid #F3D191;
+				background: #FFFAF4;
+				color:#5D410F
+			}
 			&.video-tag {
-				background: #FFF3E0;
-				color: #FF9800;
-				
+				background: linear-gradient( 90deg, #FFE9C7 0%, #F3D091 100%);
+				border-radius:8rpx 0rpx 0rpx 8rpx;
+				border: 2rpx solid #F3D191;
+				font-family: PingFang SC, PingFang SC;
+				font-weight: 400;
+				font-size: 24rpx;
+				color: #5D410F;
+				display: flex;
+				align-items: center;
 				.tag-icon {
 					margin-right: 4rpx;
 				}
@@ -315,6 +401,7 @@ export default {
 				border: 1rpx solid #388BFF;
 				color: #388BFF;
 				background: transparent;
+				
 			}
 		}
 	}
@@ -326,6 +413,21 @@ export default {
 			margin-bottom: 8rpx;
 		}
 	}
+	.card-rejection {
+		display: flex;
+		align-items: center;
+		gap: 8rpx;
+		padding: 12rpx;
+		background: #FFEBEE;
+		border-radius: 8rpx;
+		margin-bottom: 16rpx;
+		font-size: 26rpx;
+		color: #F44336;
+		
+		.rejection-icon {
+			font-size: 28rpx;
+		}
+	}
 }
 
 .info-section {
@@ -392,20 +494,26 @@ export default {
 	}
 }
 
-.bottom-btn {
+.submit-box{
 	position: fixed;
 	bottom: 0;
 	left: 0;
 	right: 0;
-	height: 88rpx;
-	background: #388BFF;
-	display: flex;
-	align-items: center;
-	justify-content: center;
-	font-size: 32rpx;
-	color: #fff;
-	font-weight: 500;
+	background: #fff;
 	z-index: 100;
+	padding: 24rpx 32rpx;
+	.submit-btn {
+		height: 88rpx;
+		background: #388BFF;
+		border-radius: 200rpx 200rpx 200rpx 200rpx;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		font-size: 32rpx;
+		color: #fff;
+		font-weight: 500;
+		
+	}
 }
 </style>
 
@@ -417,3 +525,9 @@ export default {
 
 
 
+
+
+
+
+
+

+ 80 - 71
pages_user/addBankCard.vue

@@ -6,8 +6,8 @@
 				<view class="form-item">
 					<view class="form-label">开户行</view>
 					<picker mode="selector" :range="bankList" range-key="name" @change="onBankChange">
-						<view class="form-input picker-input" :class="{ placeholder: !formData.bank }">
-							{{ formData.bank || '请选择开户行' }}
+						<view class="form-input picker-input" :class="{ placeholder: !formData.bankName }">
+							{{ formData.bankName || '请选择开户行' }}
 							<image class="w36 h36" src="@/static/image/icon_my_more.png" mode=""></image>
 						</view>
 					</picker>
@@ -17,8 +17,8 @@
 				<view class="form-item">
 					<view class="form-label">支行</view>
 					<picker mode="selector" :range="branchList" range-key="name" @change="onBranchChange">
-						<view class="form-input picker-input" :class="{ placeholder: !formData.branch }">
-							{{ formData.branch || '请选择支行' }}
+						<view class="form-input picker-input" :class="{ placeholder: !formData.bankBranch }">
+							{{ formData.bankBranch || '请选择支行' }}
 							<image class="w36 h36" src="@/static/image/icon_my_more.png" mode=""></image>
 						</view>
 					</picker>
@@ -29,7 +29,7 @@
 					<view class="form-label">银行卡号</view>
 					<input 
 						class="form-input " 
-						v-model="formData.cardNumber" 
+						v-model="formData.bankCardNo" 
 						placeholder="请输入银行卡号"
 						type="number"
 						maxlength="19"
@@ -54,21 +54,30 @@
 </template>
 
 <script>
-import { addBankCard1, getBankList, getBranchList } from '@/api-js/bankCard'
+import { addBankCard, getBankList, getBranchList } from '@/api/bankCard'
 export default {
 	data() {
 		return {
 			formData: {
-				bank: '',
-				branch: '',
-				cardNumber: ''
+				"bankBranch": "",
+				  "bankCardNo": "",
+				  "bankName": ""
 			},
-			bankList: [],
-			branchList: []
+			bankList: [
+				{ name: '中国工商银行', id: 1 },
+				{ name: '中国建设银行', id: 2 },
+				{ name: '中国银行', id: 3 },
+				{ name: '中国农业银行', id: 4 }
+			],
+			branchList: [{ name: '北京支行', id: 1 },
+					{ name: '上海支行', id: 2 },
+					{ name: '广州支行', id: 3 },
+					{ name: '重庆支行', id: 4 }
+					]
 		}
 	},
 	onLoad() {
-		this.loadBankList()
+		//this.loadBankList()
 	},
 	methods: {
 		async loadBankList() {
@@ -117,80 +126,80 @@ export default {
 		},
 		onBankChange(e) {
 			const index = e.detail.value
-			this.formData.bank = this.bankList[index].name
-			this.formData.bankId = this.bankList[index].id
-			this.formData.branch = '' // 清空支行选择
-			if (this.formData.bankId) {
-				this.loadBranchList(this.formData.bankId)
-			}
+			this.formData.bankName = this.bankList[index].name
+			//this.formData.bankCardNo = this.bankList[index].id
+			this.formData.bankBranch = '' // 清空支行选择
+			// if (this.formData.bankCardNo) {
+			// 	this.loadBranchList(this.formData.bankCardNo)
+			// }
 		},
 		onBranchChange(e) {
 			const index = e.detail.value
-			this.formData.branch = this.branchList[index].name
-			this.formData.branchId = this.branchList[index].id
+			this.formData.bankBranch = this.branchList[index].name
+			//this.formData.bankCardNo = this.branchList[index].id
 		},
 		goBack() {
 			uni.navigateBack()
 		},
 		async handleSubmit() {
 			// 表单验证
-			// if (!this.formData.bank) {
-			// 	uni.showToast({
-			// 		icon: 'none',
-			// 		title: '请选择开户行'
-			// 	})
-			// 	return
-			// }
-			// if (!this.formData.branch) {
-			// 	uni.showToast({
-			// 		icon: 'none',
-			// 		title: '请选择支行'
-			// 	})
-			// 	return
-			// }
-			// if (!this.formData.cardNumber) {
-			// 	uni.showToast({
-			// 		icon: 'none',
-			// 		title: '请输入银行卡号'
-			// 	})
-			// 	return
-			// }
-			// // 银行卡号验证(简单验证)
-			// if (this.formData.cardNumber.length < 16) {
+			if (!this.formData.bankName) {
+				uni.showToast({
+					icon: 'none',
+					title: '请选择开户行'
+				})
+				return
+			}
+			if (!this.formData.bankBranch) {
+				uni.showToast({
+					icon: 'none',
+					title: '请选择支行'
+				})
+				return
+			}
+			if (!this.formData.bankCardNo) {
+				uni.showToast({
+					icon: 'none',
+					title: '请输入银行卡号'
+				})
+				return
+			}
+			// 银行卡号验证(简单验证)
+			// if (this.formData.bankCardNo.length < 16) {
 			// 	uni.showToast({
 			// 		icon: 'none',
 			// 		title: '请输入正确的银行卡号'
 			// 	})
 			// 	return
 			// }
-			uni.navigateTo({
-				url: '/pages_user/editBankCard'
-			})
-			// try {
-			// 	uni.showLoading({ title: '添加中...' })
-			// 	const res = await addBankCard1(this.formData)
-			// 	uni.hideLoading()
-			// 	if (res.code === 200) {
-			// 		uni.showToast({
-			// 			icon: 'success',
-			// 			title: '添加成功'
-			// 		})
-			// 		setTimeout(() => {
-			// 			uni.navigateBack()
-			// 		}, 1500)
-			// 	} else {
-			// 		uni.showToast({
-			// 			icon: 'none',
-			// 			title: res.msg || '添加失败'
-			// 		})
-			// 	}
-			// } catch (e) {
-			// 	uni.hideLoading()
-			// 	uni.showToast({
-			// 		icon: 'none',
-			// 		title: '添加失败'
-			// 	})
-			// }
+			// uni.navigateTo({
+			// 	url: '/pages_user/editBankCard'
+			// })
+			try {
+				uni.showLoading({ title: '添加中...' })
+				const res = await addBankCard(this.formData)
+				uni.hideLoading()
+				if (res.code === 200) {
+					uni.showToast({
+						icon: 'success',
+						title: '添加成功'
+					})
+					setTimeout(() => {
+						uni.navigateBack()
+					}, 1500)
+				} else {
+					uni.showToast({
+						icon: 'none',
+						title: res.msg || '添加失败'
+					})
+				}
+			} catch (e) {
+				uni.hideLoading()
+				uni.showToast({
+					icon: 'none',
+					title: '添加失败'
+				})
+			}
 		}
 	}
 }

+ 15 - 6
pages_user/bankCard.vue

@@ -3,16 +3,16 @@
 		<!-- 内容区域 -->
 		<scroll-view class="content" scroll-y>
 			<!-- 有银行卡状态 -->
-			<view v-if="bankCardData.id" class="card-section">
+			<view v-if="bankCardData.bankCardNo" class="card-section">
 				<view class="bank-card">
 					<view class="card-header">
 						<view class="bank-info">
 							<view class="bank-name">{{ bankCardData.bankName || '' }}</view>
-							<view class="card-type">{{ bankCardData.cardType || '储蓄卡' }}</view>
+							<view class="card-type">{{ bankCardData.bankBranch || '储蓄卡' }}</view>
 						</view>
 						<view class="edit-btn" @click="goEdit">编辑银行卡</view>
 					</view>
-					<view class="card-number">{{ formatCardNumber(bankCardData.cardNumber) }}</view>
+					<view class="card-number">{{ formatCardNumber(bankCardData.bankCardNo) }}</view>
 					<image class="w270 h320" src="@/static/image/bg_bankcard.png" mode=""></image>
 				</view>
 				
@@ -27,7 +27,7 @@
 			<!-- 空状态 -->
 			<view v-else class="empty-section">
 				<view class="empty-card-illustration">
-					<image class="w322 h198" src="@/static/image/img_nocard.svg" mode=""></image>
+					<image class="w322 h198" src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/img_nocard.png" mode=""></image>
 				</view>
 				<view class="empty-text">暂未添加银行卡</view>
 				<view class="add-btn" @click="goAdd">添加银行卡</view>
@@ -37,7 +37,7 @@
 </template>
 
 <script>
-import { getBankCardInfo } from '@/api-js/bankCard'
+import { getBankCardInfo } from '@/api/bankCard'
 export default {
 	data() {
 		return {
@@ -60,7 +60,10 @@ export default {
 				if (res.code === 200 && res.data) {
 					this.bankCardData = res.data
 				} else {
-					this.bankCardData = {id:1,bankName:'中国工商银行',cardNumber:'**** **** **** 8869'}
+					uni.showToast({
+						icon: 'none',
+						title: res.msg
+					})
 				}
 			} catch (e) {
 				uni.hideLoading()
@@ -327,3 +330,9 @@ export default {
 
 
 
+
+
+
+
+
+

+ 287 - 128
pages_user/certification.vue

@@ -21,7 +21,7 @@
 					</view>
 					<input 
 						class="form-input" 
-						v-model="formData.name" 
+						v-model="formData.doctorName" 
 						placeholder="请输入姓名"
 						placeholder-class="placeholder"
 					/>
@@ -34,7 +34,7 @@
 					</view>
 					<input 
 						class="form-input" 
-						v-model="formData.idNumber" 
+						v-model="formData.idCard" 
 						placeholder="请输入身份证号"
 						maxlength="18"
 						placeholder-class="placeholder"
@@ -46,12 +46,19 @@
 						<text class="required">*</text>
 						<text>账号身份</text>
 					</view>
-					<input 
-						class="form-input" 
-						v-model="formData.accountIdentity" 
-						placeholder="请输入账号身份"
-						placeholder-class="placeholder"
-					/>
+					<radio-group @change="onAccountIdentityChange" class="radio-group">
+						<label 
+							class="radio-item"
+							v-for="(option, index) in accountIdentityOptions"
+							:key="index">
+							<radio
+								:value="option.value"
+								:checked="formData.accountType == option.value"
+								color="#388BFF"
+							/>
+							<text class="radio-text">{{ option.label }}</text>
+						</label>
+					</radio-group>
 				</view>
 				
 				<view class="form-item">
@@ -59,12 +66,12 @@
 						<text class="required">*</text>
 						<text>机构</text>
 					</view>
-					<picker style="flex:1" mode="selector" :range="institutionList" range-key="name" @change="onInstitutionChange">
-						<view class="form-input picker-input" :class="{ placeholder: !formData.institution }">
-							{{ formData.institution || '请选择机构' }}
-							<image class="w36 h36" src="@/static/image/icon_my_more.png" mode=""></image>
-						</view>
-					</picker>
+					<input 
+						class="form-input" 
+						v-model="formData.institution" 
+						placeholder="请输入机构名称"
+						placeholder-class="placeholder"
+					/>
 				</view>
 				
 				<view class="form-item">
@@ -72,12 +79,12 @@
 						<text class="required">*</text>
 						<text>科室</text>
 					</view>
-					<picker style="flex:1" mode="selector" :range="departmentList" range-key="name" @change="onDepartmentChange">
-						<view class="form-input picker-input" :class="{ placeholder: !formData.department }">
-							{{ formData.department || '请选择科室' }}
-							<image class="w36 h36" src="@/static/image/icon_my_more.png" mode=""></image>
-						</view>
-					</picker>
+					<input 
+						class="form-input" 
+						v-model="formData.department" 
+						placeholder="请输入科室"
+						placeholder-class="placeholder"
+					/>
 				</view>
 				
 				<view class="form-item">
@@ -85,12 +92,12 @@
 						<text class="required">*</text>
 						<text>职称</text>
 					</view>
-					<picker style="flex:1" mode="selector" :range="titleList" range-key="name" @change="onTitleChange">
-						<view class="form-input picker-input" :class="{ placeholder: !formData.title }">
-							{{ formData.title || '请选择职称' }}
-							<image class="w36 h36" src="@/static/image/icon_my_more.png" mode=""></image>
-						</view>
-					</picker>
+					<input 
+						class="form-input" 
+						v-model="formData.jobTitle" 
+						placeholder="请输入职称"
+						placeholder-class="placeholder"
+					/>
 				</view>
 			</view>
 			
@@ -171,8 +178,8 @@
 						<text>开户行</text>
 					</view>
 					<picker style="flex:1" mode="selector" :range="bankList" range-key="name" @change="onBankChange">
-						<view class="form-input picker-input" :class="{ placeholder: !formData.bank }">
-							{{ formData.bank || '请选择开户行' }}
+						<view class="form-input picker-input x-bc" :class="{ placeholder: !formData.bankName}">
+							{{ formData.bankName|| '请选择开户行' }}
 							<image class="w36 h36" src="@/static/image/icon_my_more.png" mode=""></image>
 						</view>
 					</picker>
@@ -185,7 +192,7 @@
 					</view>
 					<input 
 						class="form-input" 
-						v-model="formData.branchName" 
+						v-model="formData.bankBranch" 
 						placeholder="请输入支行名称"
 					/>
 				</view>
@@ -197,7 +204,7 @@
 					</view>
 					<input 
 						class="form-input" 
-						v-model="formData.bankCardNumber" 
+						v-model="formData.bankCardNo" 
 						placeholder="请输入银行卡号"
 						type="number"
 					/>
@@ -229,111 +236,147 @@
 </template>
 
 <script>
-import { submitCertification, getCertificationInfo } from '@/api-js/certification'
+import { 
+	submitCertification, 
+	getCertificationInfo, 
+	getBankList,
+	getCertificationStatus 
+} from '@/api/certification'
+import { uploadOSS } from '@/api/common'
 export default {
 	data() {
 		return {
 			rejectionInfo: '', // 驳回意见
 			agreed: false,
+			certificationStatus: null, // 认证状态
 			formData: {
-				name: '',
-				idNumber: '',
-				accountIdentity: '',
-				institution: '',
-				department: '',
-				title: '',
-				practiceCertificate: [], // 医师职业证图片数组
-				titleCertificate: [], // 医师职称证/工牌图片数组
-				bank: '',
-				branchName: '',
-				bankCardNumber: ''
+				doctorName: '', // 讲者姓名
+				idCard: '', // 身份证号
+				accountIdentity: '', // 账号身份(用于转换为 accountType)
+				accountType: 1, // 账户身份: 1-医生, 2-药剂师
+				institution: '', // 机构名称
+				institutionId: '', // 机构ID(用于获取 companyId)
+				companyId: '', // 公司ID
+				companyName: '', // 公司名称
+				department: '', // 科室
+				jobTitle: '', // 职称
+				licenseImage: '', // 执业证图片URL(多个图片用逗号分隔)
+				titleCertImage: '', // 职称证/工牌图片URL(多个图片用逗号分隔)
+				bankName: '', // 开户银行
+				bankBranch: '', // 支行信息
+				bankCardNo: '', // 银行卡号
+				// 本地图片路径(用于上传)
+				practiceCertificate: [], // 医师职业证图片数组(本地路径)
+				titleCertificate: [] // 医师职称证/工牌图片数组(本地路径)
 			},
 			institutionList: [],
 			departmentList: [],
 			titleList: [],
-			bankList: []
+			bankList: [
+				{ name: '中国工商银行', id: 1 },
+				{ name: '中国建设银行', id: 2 },
+				{ name: '中国银行', id: 3 },
+				{ name: '中国农业银行', id: 4 }
+			],
+			selectedInstitution: null, // 选中的机构对象
+			selectedBank: null, // 选中的银行对象
+			accountIdentityOptions: [
+				{ label: '医生', value: 1 },
+				{ label: '药剂师', value: 2 }
+			]
 		}
 	},
 	onLoad(options) {
+		var user = JSON.parse(uni.getStorageSync('userInfo'))
+		this.formData.companyId=user.companyId
 		if (options.rejectionInfo) {
 			this.rejectionInfo = decodeURIComponent(options.rejectionInfo)
 		}
-		this.institutionList = [
-			{ name: '机构1', id: 1 },
-			{ name: '机构2', id: 2 }
-		]
-		this.departmentList = [
-			{ name: '内科', id: 1 },
-			{ name: '外科', id: 2 },
-			{ name: '儿科', id: 3 }
-		]
-		this.titleList = [
-			{ name: '主任医师', id: 1 },
-			{ name: '副主任医师', id: 2 },
-			{ name: '主治医师', id: 3 }
-		]
-		this.bankList = [
-			{ name: '中国工商银行', id: 1 },
-			{ name: '中国建设银行', id: 2 },
-			{ name: '中国银行', id: 3 }
-		]
 		//this.loadData()
 	},
 	methods: {
 		async loadData() {
 			try {
+				uni.showLoading({ title: '加载中...' })
+				// 并行加载所有数据
+				const [infoRes, statusRes, bankRes] = await Promise.all([
+					getCertificationInfo().catch(() => ({ code: 0 })),
+					getCertificationStatus().catch(() => ({ code: 0 })),
+					// getBankList().catch(() => ({ code: 0, data: [] }))
+				])
+				
 				// 加载认证信息(如果已提交过)
-				const res = await getCertificationInfo()
-				if (res.code === 200 && res.data) {
-					this.formData = { ...this.formData, ...res.data }
-					if (res.data.rejectionInfo) {
-						this.rejectionInfo = res.data.rejectionInfo
+				if (infoRes.code === 200 && infoRes.data) {
+					const data = infoRes.data
+					// 映射接口返回的字段到表单字段
+					this.formData = {
+						...this.formData,
+						doctorName: data.doctorName || data.name || '',
+						idCard: data.idCard || data.idNumber || '',
+						accountType: data.accountType || '',
+						accountIdentity: data.accountType === 1 ? '医生' : (data.accountType === 2 ? '药剂师' : ''),
+						institution: data.institution || '',
+						companyId: data.companyId || '',
+						companyName: data.companyName || '',
+						department: data.department || '',
+						jobTitle: data.jobTitle || data.title || '',
+						bankName: data.bankName || data.bank || '',
+						bankBranch: data.bankBranch || data.branchName || '',
+						bankCardNo: data.bankCardNo || data.bankCardNumber || '',
+					// 处理图片URL,转换为数组
+					licenseImage: data.licenseImage || '',
+					titleCertImage: data.titleCertImage || '',
+					practiceCertificate: data.licenseImage ? data.licenseImage.split(',').filter(Boolean) : [],
+					titleCertificate: data.titleCertImage ? data.titleCertImage.split(',').filter(Boolean) : []
+				}
+				// 设置账号身份
+				if (data.accountType) {
+					const selected = this.accountIdentityOptions.find(opt => opt.value === data.accountType)
+					if (selected) {
+						this.formData.accountIdentity = selected.label
+						this.formData.accountType = selected.value
 					}
 				}
-				// 加载选项数据
-				this.loadOptions()
+				// 如果有id(编辑时),保存id
+				if (data.id) {
+					this.formData.id = data.id
+				}
+				if (data.rejectionInfo) {
+					this.rejectionInfo = data.rejectionInfo
+				}
+			}
+				
+				// 加载认证状态
+				if (statusRes.code === 200 && statusRes.data) {
+					this.certificationStatus = statusRes.data
+				}
+				
+				// // 加载选项数据
+				// if (bankRes.code === 200 && bankRes.data) {
+				// 	this.bankList = bankRes.data
+				// } else {
+				// 	this.bankList = []
+				// }
+				
+				uni.hideLoading()
 			} catch (e) {
+				uni.hideLoading()
 				console.error('加载数据失败', e)
-				this.loadOptions()
 			}
 		},
-		loadOptions() {
-			// 这里应该从API获取选项数据
-			this.institutionList = [
-				{ name: '机构1', id: 1 },
-				{ name: '机构2', id: 2 }
-			]
-			this.departmentList = [
-				{ name: '内科', id: 1 },
-				{ name: '外科', id: 2 },
-				{ name: '儿科', id: 3 }
-			]
-			this.titleList = [
-				{ name: '主任医师', id: 1 },
-				{ name: '副主任医师', id: 2 },
-				{ name: '主治医师', id: 3 }
-			]
-			this.bankList = [
-				{ name: '中国工商银行', id: 1 },
-				{ name: '中国建设银行', id: 2 },
-				{ name: '中国银行', id: 3 }
-			]
-		},
-		onInstitutionChange(e) {
-			const index = e.detail.value
-			this.formData.institution = this.institutionList[index].name
-		},
-		onDepartmentChange(e) {
-			const index = e.detail.value
-			this.formData.department = this.departmentList[index].name
-		},
-		onTitleChange(e) {
-			const index = e.detail.value
-			this.formData.title = this.titleList[index].name
-		},
 		onBankChange(e) {
 			const index = e.detail.value
-			this.formData.bank = this.bankList[index].name
+			this.formData.bankName = this.bankList[index].name
+			//this.formData.bankCardNo = this.bankList[index].id
+			this.formData.bankBranch = '' // 清空支行选择
+		},
+		onAccountIdentityChange(e) {
+			const value = parseInt(e.detail.value)
+			const selected = this.accountIdentityOptions.find(opt => opt.value === value)
+			if (selected) {
+				this.formData.accountIdentity = selected.label
+				this.formData.accountType = selected.value
+			}
 		},
 		onAgreementChange(e) {
 			this.agreed = e.detail.value.includes('agree')
@@ -344,23 +387,91 @@ export default {
 				sizeType: ['compressed'],
 				sourceType: ['album', 'camera'],
 				success: (res) => {
-					this.formData.practiceCertificate = [...this.formData.practiceCertificate, ...res.tempFilePaths]
+					// 立即上传图片
+					uni.showLoading({ title: '上传中...' })
+					this.uploadImages(res.tempFilePaths, (urls) => {
+						uni.hideLoading()
+						// 保存上传后的URL
+						this.formData.practiceCertificate = [...this.formData.practiceCertificate, ...urls]
+						uni.showToast({ icon: 'success', title: '上传成功' })
+					}, (error) => {
+						uni.hideLoading()
+						uni.showToast({ icon: 'none', title: error || '上传失败' })
+					})
 				}
 			})
 		},
 		removePracticeImage(index) {
 			this.formData.practiceCertificate.splice(index, 1)
 		},
-		chooseTitleImage() {
+		async chooseTitleImage() {
 			uni.chooseImage({
 				count: 9 - this.formData.titleCertificate.length,
 				sizeType: ['compressed'],
 				sourceType: ['album', 'camera'],
 				success: (res) => {
-					this.formData.titleCertificate = [...this.formData.titleCertificate, ...res.tempFilePaths]
+					// 立即上传图片
+					uni.showLoading({ title: '上传中...' })
+					this.uploadImages(res.tempFilePaths, (urls) => {
+						uni.hideLoading()
+						// 保存上传后的URL
+						this.formData.titleCertificate = [...this.formData.titleCertificate, ...urls]
+						uni.showToast({ icon: 'success', title: '上传成功' })
+					}, (error) => {
+						uni.hideLoading()
+						uni.showToast({ icon: 'none', title: error || '上传失败' })
+					})
 				}
 			})
 		},
+		// 上传多张图片(不使用 Promise)
+		uploadImages(filePaths, successCallback, failCallback) {
+			const requestPath = uni.getStorageSync('requestPath') || 'http://t9794bec.natappfree.cc'
+			const urls = []
+			let completed = 0
+			let hasError = false
+			
+			if (filePaths.length === 0) {
+				successCallback([])
+				return
+			}
+			
+			filePaths.forEach((filePath, index) => {
+				uni.uploadFile({
+					url: `${requestPath}/app/common/uploadOSS`,
+					filePath: filePath,
+					name: 'file',
+					success: (uploadRes) => {
+						if (hasError) return
+						
+						try {
+							const result = typeof uploadRes.data === 'string' ? JSON.parse(uploadRes.data) : uploadRes.data
+							if (result.code == 200) {
+								urls[index] = result.url || result.data?.url || ''
+							} else {
+								hasError = true
+								failCallback(result.msg || '上传失败')
+								return
+							}
+						} catch (e) {
+							hasError = true
+							failCallback('解析上传结果失败')
+							return
+						}
+						
+						completed++
+						if (completed === filePaths.length) {
+							successCallback(urls.filter(Boolean))
+						}
+					},
+					fail: (err) => {
+						if (hasError) return
+						hasError = true
+						failCallback('上传失败')
+					}
+				})
+			})
+		},
 		removeTitleImage(index) {
 			this.formData.titleCertificate.splice(index, 1)
 		},
@@ -395,45 +506,45 @@ export default {
 		},
 		async handleSubmit() {
 			// 表单验证
-			if (!this.formData.name) {
+			if (!this.formData.doctorName && !this.formData.name) {
 				uni.showToast({
 					icon: 'none',
 					title: '请输入姓名'
 				})
 				return
 			}
-			if (!this.formData.idNumber) {
+			if (!this.formData.idCard && !this.formData.idNumber) {
 				uni.showToast({
 					icon: 'none',
 					title: '请输入身份证号'
 				})
 				return
 			}
-			if (!this.formData.accountIdentity) {
+			if (!this.formData.accountType) {
 				uni.showToast({
 					icon: 'none',
-					title: '请输入账号身份'
+					title: '请选择账号身份'
 				})
 				return
 			}
 			if (!this.formData.institution) {
 				uni.showToast({
 					icon: 'none',
-					title: '请选择机构'
+					title: '请输入机构名称'
 				})
 				return
 			}
 			if (!this.formData.department) {
 				uni.showToast({
 					icon: 'none',
-					title: '请选择科室'
+					title: '请输入科室'
 				})
 				return
 			}
-			if (!this.formData.title) {
+			if (!this.formData.jobTitle && !this.formData.title) {
 				uni.showToast({
 					icon: 'none',
-					title: '请选择职称'
+					title: '请输入职称'
 				})
 				return
 			}
@@ -453,21 +564,21 @@ export default {
 				})
 				return
 			}
-			if (!this.formData.bank) {
+			if (!this.formData.bankName && !this.formData.bank) {
 				uni.showToast({
 					icon: 'none',
 					title: '请选择开户行'
 				})
 				return
 			}
-			if (!this.formData.branchName) {
+			if (!this.formData.bankBranch && !this.formData.branchName) {
 				uni.showToast({
 					icon: 'none',
 					title: '请输入支行名称'
 				})
 				return
 			}
-			if (!this.formData.bankCardNumber) {
+			if (!this.formData.bankCardNo && !this.formData.bankCardNumber) {
 				uni.showToast({
 					icon: 'none',
 					title: '请输入银行卡号'
@@ -484,8 +595,36 @@ export default {
 			
 			try {
 				uni.showLoading({ title: '提交中...' })
-				const res = await submitCertification(this.formData)
+				
+				// 获取图片URL(选择时已上传,直接使用)
+				const licenseImageUrls = this.formData.practiceCertificate.filter(url => url && (url.startsWith('http://') || url.startsWith('https://')))
+				const titleCertImageUrls = this.formData.titleCertificate.filter(url => url && (url.startsWith('http://') || url.startsWith('https://')))
+				
+				// 构建提交数据,按照接口字段要求
+				const submitData = {
+					accountType: this.formData.accountType, // 账户身份: 1-医生, 2-药剂师
+					bankBranch: this.formData.bankBranch || this.formData.branchName, // 支行信息
+					bankCardNo: this.formData.bankCardNo || this.formData.bankCardNumber, // 银行卡号
+					bankName: this.formData.bankName || this.formData.bank, // 开户银行
+					companyId: this.formData.companyId || '', // 公司ID
+					companyName: this.formData.companyName || this.formData.institution, // 公司名称
+					department: this.formData.department, // 科室
+					doctorName: this.formData.doctorName || this.formData.name, // 讲者姓名
+					idCard: this.formData.idCard || this.formData.idNumber, // 身份证号
+					institution: this.formData.institution, // 机构名称
+					jobTitle: this.formData.jobTitle || this.formData.title, // 职称
+					licenseImage: licenseImageUrls.join(','), // 执业证图片URL(多个用逗号分隔)
+					titleCertImage: titleCertImageUrls.join(',') // 职称证/工牌图片URL(多个用逗号分隔)
+				}
+				
+				// 如果有id(编辑时),添加id字段
+				if (this.formData.id) {
+					submitData.id = this.formData.id
+				}
+				
+				const res = await submitCertification(submitData)
 				uni.hideLoading()
+				
 				if (res.code === 200) {
 					uni.showToast({
 						icon: 'success',
@@ -502,9 +641,10 @@ export default {
 				}
 			} catch (e) {
 				uni.hideLoading()
+				console.error('提交认证失败', e)
 				uni.showToast({
 					icon: 'none',
-					title: '提交失败'
+					title: e.message || '提交失败'
 				})
 			}
 		}
@@ -602,19 +742,38 @@ export default {
 			align-items: center;
 			font-size: 28rpx;
 			color: #333;
-			margin-bottom: 16rpx;
-			width: 150rpx;
+			// margin-bottom: 16rpx;
+			width: 160rpx;
 			.required {
 				color: #FF5030;
 				margin-right: 4rpx;
 			}
 		}
 		
-		.form-input {
-			// width: 100%;
-			flex:1;
-			height: 80rpx;
-			padding: 0 24rpx;
+	.form-input {
+		// width: 100%;
+		flex:1;
+		height: 80rpx;
+		font-size: 28rpx;
+	}
+	
+	.radio-group {
+		flex: 1;
+		display: flex;
+		align-items: center;
+		gap: 48rpx;
+		height: 80rpx;
+		.radio-item {
+			display: flex;
+			align-items: center;
+			gap: 8rpx;
+			
+			.radio-text {
+				font-size: 28rpx;
+				color: #333;
+			}
+		}
+			// padding: 0 24rpx;
 			font-size: 28rpx;
 			color: #333;
 			

+ 2 - 2
pages_user/certificationExample.vue

@@ -34,7 +34,7 @@
 					<view class="instruction-item">2.因各省市证件样式不统一,如有2页请拍摄完整</view>
 				</view>
 				<view class="example-image">
-					<image src="@/static/image/img_example4.svg" mode=""></image>
+					<image src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/img_example4.png" mode=""></image>
 					<!-- <view class="image-placeholder">示例图片:老版本职称证</view> -->
 					<!-- 请将示例图片放置在 @/static/image/example_old_certificate.png -->
 				</view>
@@ -51,7 +51,7 @@
 					<view class="instruction-item">2.包含执业证注册信息,主执业机构地点</view>
 				</view>
 				<view class="example-image">
-					<image src="@/static/image/img_example5.svg" mode=""></image>
+					<image src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/img_example5.png" mode=""></image>
 					<!-- <view class="image-placeholder">示例图片:新版本职称证</view> -->
 					<!-- 请将示例图片放置在 @/static/image/example_new_certificate.png -->
 				</view>

+ 7 - 1
pages_user/certificationInfo.vue

@@ -45,7 +45,7 @@
 </template>
 
 <script>
-import { getCertificationInfo } from '@/api-js/certification'
+import { getCertificationInfo } from '@/api/certification'
 export default {
 	data() {
 		return {
@@ -239,3 +239,9 @@ export default {
 
 
 
+
+
+
+
+
+

+ 88 - 49
pages_user/editBankCard.vue

@@ -6,8 +6,8 @@
 				<view class="form-item">
 					<view class="form-label">开户行</view>
 					<picker mode="selector" :range="bankList" range-key="name" @change="onBankChange">
-						<view class="form-input picker-input" :class="{ placeholder: !formData.bank }">
-							{{ formData.bank || '请选择开户行' }}
+						<view class="form-input picker-input" :class="{ placeholder: !formData.bankName }">
+							{{ formData.bankName || '请选择开户行' }}
 							<image class="w36 h36" src="@/static/image/icon_my_more.png" mode=""></image>
 						</view>
 					</picker>
@@ -17,8 +17,8 @@
 				<view class="form-item">
 					<view class="form-label">支行</view>
 					<picker mode="selector" :range="branchList" range-key="name" @change="onBranchChange">
-						<view class="form-input picker-input" :class="{ placeholder: !formData.branch }">
-							{{ formData.branch || '请选择支行' }}
+						<view class="form-input picker-input" :class="{ placeholder: !formData.bankBranch }">
+							{{ formData.bankBranch || '请选择支行' }}
 							<image class="w36 h36" src="@/static/image/icon_my_more.png" mode=""></image>
 						</view>
 					</picker>
@@ -29,7 +29,7 @@
 					<view class="form-label">银行卡号</view>
 					<input 
 						class="form-input" 
-						v-model="formData.cardNumber" 
+						v-model="formData.bankCardNo" 
 						placeholder="请输入银行卡号"
 						type="number"
 						maxlength="19"
@@ -49,48 +49,62 @@
 		<!-- 底部按钮 -->
 		<view class="bottom-bar">
 			<view class="save-btn" @click="handleSave">保存</view>
-			<view class="unbind-btn" @click="handleUnbind">解除绑定</view>
+			<!-- <view class="unbind-btn" @click="handleUnbind">解除绑定</view> -->
 		</view>
 	</view>
 </template>
 
 <script>
-import { updateBankCard, deleteBankCard, getBankCardDetail, getBankList, getBranchList } from '@/api-js/bankCard'
+import { addBankCard, deleteBankCard, getBankCardInfo, getBankList, getBranchList } from '@/api/bankCard'
 export default {
 	data() {
 		return {
 			cardId: '',
 			formData: {
-				bank: '',
-				branch: '',
-				cardNumber: ''
+				"bankBranch": "",
+				  "bankCardNo": "",
+				  "bankName": ""
 			},
-			bankList: [],
-			branchList: []
+			bankList: [
+				{ name: '中国工商银行', id: 1 },
+				{ name: '中国建设银行', id: 2 },
+				{ name: '中国银行', id: 3 },
+				{ name: '中国农业银行', id: 4 }
+			],
+			branchList: [{ name: '北京支行', id: 1 },
+					{ name: '上海支行', id: 2 },
+					{ name: '广州支行', id: 3 },
+					{ name: '重庆支行', id: 4 }
+					]
 		}
 	},
 	onLoad(options) {
-		if (options.id) {
-			this.cardId = options.id
-			this.loadBankCardDetail()
-		}
-		this.loadBankList()
+		// if (options.id) {
+		// 	this.cardId = options.id
+			
+		// }
+		this.loadBankCardDetail()
+		//this.loadBankList()
 	},
 	methods: {
 		async loadBankCardDetail() {
 			try {
 				uni.showLoading({ title: '加载中...' })
-				const res = await getBankCardDetail({ id: this.cardId })
+				const res = await getBankCardInfo({ id: this.cardId })
 				uni.hideLoading()
 				if (res.code === 200 && res.data) {
+					// 根据接口返回的数据结构映射字段
+					const data = res.data
 					this.formData = {
-						bank: res.data.bankName || '',
-						branch: res.data.branchName || '',
-						cardNumber: res.data.cardNumber || ''
-					}
-					if (res.data.bankId) {
-						this.loadBranchList(res.data.bankId)
+						...this.formData,
+						bankBranch: data.bankBranch,
+						  bankCardNo:  data.bankCardNo,
+						  bankName: data.bankName
 					}
+					// 加载支行列表(如果存在银行ID)
+					// if (this.formData.bankId) {
+					// 	this.loadBranchList(this.formData.bankId)
+					// }
 				}
 			} catch (e) {
 				uni.hideLoading()
@@ -141,59 +155,78 @@ export default {
 		},
 		onBankChange(e) {
 			const index = e.detail.value
-			this.formData.bank = this.bankList[index].name
-			this.formData.bankId = this.bankList[index].id
-			this.formData.branch = ''
-			if (this.formData.bankId) {
-				this.loadBranchList(this.formData.bankId)
-			}
+			this.formData.bankName = this.bankList[index].name
+			//this.formData.bankCardNo = this.bankList[index].id
+			this.formData.bankBranch = '' // 清空支行选择
+			// if (this.formData.bankCardNo) {
+			// 	this.loadBranchList(this.formData.bankCardNo)
+			// }
 		},
 		onBranchChange(e) {
 			const index = e.detail.value
-			this.formData.branch = this.branchList[index].name
-			this.formData.branchId = this.branchList[index].id
+			this.formData.bankBranch = this.branchList[index].name
+			//this.formData.bankCardNo = this.branchList[index].id
 		},
 		goBack() {
 			uni.navigateBack()
 		},
 		async handleSave() {
 			// 表单验证
-			if (!this.formData.bank) {
+			if (!this.formData.bankName) {
 				uni.showToast({
 					icon: 'none',
 					title: '请选择开户行'
 				})
 				return
 			}
-			if (!this.formData.branch) {
+			if (!this.formData.bankBranch) {
 				uni.showToast({
 					icon: 'none',
 					title: '请选择支行'
 				})
 				return
 			}
-			if (!this.formData.cardNumber) {
+			if (!this.formData.bankCardNo) {
 				uni.showToast({
 					icon: 'none',
 					title: '请输入银行卡号'
 				})
 				return
 			}
-			if (this.formData.cardNumber.length < 16) {
-				uni.showToast({
-					icon: 'none',
-					title: '请输入正确的银行卡号'
-				})
-				return
-			}
+			// if (this.formData.bankCardNo.length < 16) {
+			// 	uni.showToast({
+			// 		icon: 'none',
+			// 		title: '请输入正确的银行卡号'
+			// 	})
+			// 	return
+			// }
 			
 			try {
 				uni.showLoading({ title: '保存中...' })
-				const res = await updateBankCard({
-					id: this.cardId,
-					...this.formData
-				})
+				
+				// 构建提交数据,按照接口字段要求
+				const submitData = {
+					bankName: this.formData.bank || this.formData.bankName,
+					bankBranch: this.formData.branch || this.formData.bankBranch,
+					bankCardNo: this.formData.cardNumber || this.formData.bankCardNo
+				}
+				
+				// 如果有ID(编辑时),添加id字段
+				if (this.cardId || this.formData.id) {
+					submitData.id = this.cardId || this.formData.id
+				}
+				
+				// 如果有bankId和branchId,也一并提交
+				if (this.formData.bankId) {
+					submitData.bankId = this.formData.bankId
+				}
+				if (this.formData.branchId) {
+					submitData.branchId = this.formData.branchId
+				}
+				
+				const res = await addBankCard(submitData)
 				uni.hideLoading()
+				
 				if (res.code === 200) {
 					uni.showToast({
 						icon: 'success',
@@ -210,9 +243,10 @@ export default {
 				}
 			} catch (e) {
 				uni.hideLoading()
+				console.error('保存银行卡失败', e)
 				uni.showToast({
 					icon: 'none',
-					title: '保存失败'
+					title: e.message || '保存失败'
 				})
 			}
 		},
@@ -254,7 +288,6 @@ export default {
 	}
 }
 </script>
-
 <style lang="stylus">
 	.text-placeholder{
 	  color: #C8C9CC !important;
@@ -361,7 +394,7 @@ export default {
 
 // placeholder 样式(需要独立定义,不能嵌套)
 .placeholder {
-	color: #C8C9CC !important;
+	//color: #C8C9CC !important;
 	}
 	
 	.divider {
@@ -429,3 +462,9 @@ export default {
 
 
 
+
+
+
+
+
+

+ 90 - 57
pages_user/forgetPassword.vue

@@ -3,12 +3,12 @@
 		<view class="content">
 			<view class="info-item">
 				<text class="title">手机号码</text>
-				<input class="input-field code-input" type="text" :password="!phone" v-model="phone"
-					placeholder="请输入手机号码" />
+				<input class="input-field code-input" type="number" v-model="phone"
+					placeholder="请输入手机号码" maxlength="11" />
 			</view>
 			<view class="info-item">
 				<text class="title">验证码</text>
-				<input class="input-field code-input" type="number" v-model="verifyCode"
+				<input class="input-field code-input" type="number" v-model="code"
 					placeholder="请输入验证码" maxlength="6" />
 				<view  class="get-code-btn" @click="getVerifyCode">
 					{{ codeText }}
@@ -32,11 +32,15 @@
 </template>
 
 <script>
-	export default {
+import { resetPassword, sendPasswordVerifyCode } from '@/api/password'
+export default {
 		data() {
 			return {
-				phone:17873014571,
+				phone: '',
+				code: '',
 				codeText: '获取验证码', // 验证码按钮文字
+				countdown: 0, // 倒计时
+				countdownTimer: null, // 倒计时定时器
 				newPassword: '',
 				confirmPassword: '',
 				// 为每个密码框单独设置显示状态
@@ -45,10 +49,17 @@
 				showConfirmPassword: false
 			}
 		},
+		onUnload() {
+			// 清除倒计时
+			if(this.countdownTimer) {
+				clearInterval(this.countdownTimer);
+				this.countdownTimer = null;
+			}
+		},
 		onLoad() {},
 		methods: {
 			// 获取验证码
-			getVerifyCode() {
+			async getVerifyCode() {
 				if (this.countdown > 0) {
 					return;
 				}
@@ -66,30 +77,44 @@
 					});
 					return;
 				}
-				// TODO: 调用发送验证码API
-				// 这里需要对接真实的发送验证码接口
-				uni.showLoading({
-					title: "发送中..."
-				});
-				// 模拟发送验证码
-				setTimeout(() => {
+				try {
+					uni.showLoading({
+						title: "发送中..."
+					});
+					const res = await sendPasswordVerifyCode({ phone: this.phone });
+					uni.hideLoading();
+					
+					if (res.code === 200) {
+						uni.showToast({
+							icon: 'success',
+							title: "验证码已发送",
+						});
+						// 开始倒计时
+						this.countdown = 60;
+						this.codeText = this.countdown + '秒重新获取';
+						this.countdownTimer = setInterval(() => {
+							this.countdown--;
+							this.codeText = this.countdown + '秒重新获取';
+							if (this.countdown <= 0) {
+								clearInterval(this.countdownTimer);
+								this.countdownTimer = null;
+								this.codeText = '获取验证码';
+							}
+						}, 1000);
+					} else {
+						uni.showToast({
+							icon: 'none',
+							title: res.msg || "发送验证码失败",
+						});
+					}
+				} catch (e) {
 					uni.hideLoading();
+					console.error('发送验证码失败', e);
 					uni.showToast({
-						icon: 'success',
-						title: "验证码已发送",
+						icon: 'none',
+						title: "发送验证码失败",
 					});
-					// 开始倒计时
-					this.countdown = 60;
-					this.countdownTimer = setInterval(() => {
-						this.countdown--;
-						this.codeText = this.countdown + '秒重新获取';
-						if (this.countdown <= 0) {
-							clearInterval(this.countdownTimer);
-							this.countdownTimer = null;
-							this.codeText = '获取验证码';
-						}
-					}, 1000);
-				}, 1000);
+				}
 			},
 			// 分别控制每个密码框的显示/隐藏
 			toggleOldPassword() {
@@ -103,14 +128,27 @@
 			},
 			confirm() {
 				// 验证逻辑
-				if (!this.oldPassword) {
+				if (!this.phone) {
 					uni.showToast({
-						title: '请输入原密码',
+						title: '请输入手机号',
+						icon: 'none'
+					});
+					return;
+				}
+				if (!/^1[3-9]\d{9}$/.test(this.phone)) {
+					uni.showToast({
+						title: '请输入正确的手机号',
+						icon: 'none'
+					});
+					return;
+				}
+				if (!this.code) {
+					uni.showToast({
+						title: '请输入验证码',
 						icon: 'none'
 					});
 					return;
 				}
-
 				if (!this.newPassword) {
 					uni.showToast({
 						title: '请输入新密码',
@@ -129,45 +167,35 @@
 					return;
 				}
 
-				if (this.newPassword !== this.confirmPassword) {
-					uni.showToast({
-						title: '两次输入的新密码不一致',
-						icon: 'none'
-					});
-					return;
-				}
-
-				// 调用修改密码的API
-				this.changePassword();
+				// 调用重置密码的API
+				this.resetPassword();
 			},
 
-			// 修改密码的API调用
-			async changePassword() {
+			// 重置密码的API调用
+			async resetPassword() {
 				try {
 					uni.showLoading({
 						title: '修改中...'
 					});
 
-					// 这里添加实际的API调用
-					// const res = await uni.request({
-					// 	url: '/api/change-password',
-					// 	method: 'POST',
-					// 	data: {
-					// 		oldPassword: this.oldPassword,
-					// 		newPassword: this.newPassword
-					// 	}
-					// });
+					const res = await resetPassword({
+						phone: this.phone,
+						code: this.code,
+						newPassword: this.newPassword,
+						confirmPassword: this.newPassword,
+					});
 
-					// 模拟成功
-					setTimeout(() => {
-						uni.hideLoading();
+					uni.hideLoading();
+
+					if (res.code === 200) {
 						uni.showToast({
 							title: '密码修改成功',
 							icon: 'success'
 						});
 
 						// 清空表单
-						this.oldPassword = '';
+						this.phone = '';
+						this.code = '';
 						this.newPassword = '';
 						this.confirmPassword = '';
 
@@ -175,10 +203,15 @@
 						setTimeout(() => {
 							uni.navigateBack();
 						}, 1500);
-					}, 1000);
-
+					} else {
+						uni.showToast({
+							title: res.msg || '修改失败',
+							icon: 'none'
+						});
+					}
 				} catch (error) {
 					uni.hideLoading();
+					console.error('修改密码失败', error);
 					uni.showToast({
 						title: error.message || '修改失败',
 						icon: 'none'

+ 201 - 0
pages_user/personInfo.vue

@@ -0,0 +1,201 @@
+<template>
+		<view class="content">
+			<view class="info-item">
+				<view class="label">姓名</view>
+				<view class="right">
+					{{user.doctorName||'-'}}
+				</view>
+			</view>
+			<view class="info-item">
+			     <view class="label">账号身份</view>
+			     <view class="right">
+			       <template v-if="user.accountType">
+			         {{ user.accountType === '1' ? '医生' : user.accountType === '2' ? '药剂师' : '-' }}
+			       </template>
+			       <template v-else>-</template>
+			     </view>
+			   </view>
+			<view class="info-item">
+				<view class="label">是否认证</view>
+				<view class="right">{{user.status==1?'是':'否'}}</view>
+			</view>
+			<view class="info-item">
+				<view class="label">手机号</view>
+				<view class="right" v-if="user.mobile!=null">{{user.mobile}}</view>
+			</view>
+			    <view class="info-item">
+			      <view class="label">职称</view>
+			      <view class="right">{{ user.jobTitle || '-' }}</view>
+			    </view>
+			    <view class="info-item">
+			      <view class="label">科室</view>
+			      <view class="right">{{ user.department || '-' }}</view>
+			    </view>
+			    <view class="info-item">
+			      <view class="label">机构</view>
+			      <view class="right">{{ user.institution || '-' }}</view>
+			    </view>
+				<view class="info-item">
+				  <view class="label">公司名称</view>
+				  <view class="right">{{ user.companyName || '-' }}</view>
+				</view>
+			    <view class="info-item">
+			      <view class="label">开户银行</view>
+			      <view class="right">{{ user.bankName || '-' }}</view>
+			    </view>
+				<view class="info-item">
+				  <view class="label">银行卡号</view>
+				  <view class="right">{{ user.idCard ? formatBankCard(user.idCard) : '-' }}</view>
+				</view>
+				<view class="info-item">
+				  <view class="label">执业证</view>
+				  <view class="right">
+					  <image class="w300 h150" :src="user.licenseImage" mode="aspectFill"></image>
+				  </view>
+				</view>
+				<view class="info-item">
+				  <view class="label">职称证/工牌</view>
+				  <view class="right">
+					  <image class="w300 h150" :src="user.titleCertImage" mode="aspectFill"></image>
+				  </view>
+				</view>
+		</view>
+</template>
+
+<script>
+	import {getUserInfo,editUser} from '@/api/user'
+	export default {
+		data() {
+			return {
+				user: null 
+			}
+		},
+		onLoad() {
+			this.getUserInfo()
+		},
+		methods: {
+			 formatBankCard(cardNo) {
+			      if (!cardNo || cardNo.length < 8) return cardNo;
+			      const prefix = cardNo.substring(0, 4);
+			      const suffix = cardNo.substring(cardNo.length - 4);
+			      return `${prefix}****${suffix}`;
+			    },
+			bindblur(e) {
+				this.user.nickname = e.detail.value; // 获取微信昵称
+			},
+			bindinput(e){
+				this.user.nickname = e.detail.value; //这里要注意如果只用blur方法的话用户在输入玩昵称后直接点击保存按钮,会出现修改不成功的情况。
+			},
+			onChooseAvatar(e){
+				let {
+					avatarUrl
+				} = e.detail;
+				uni.uploadFile({
+					url: uni.getStorageSync('requestPath')+'/app/common/uploadOSS', //仅为示例,非真实的接口地址
+					filePath: avatarUrl,
+					name: 'file',
+					formData: {
+						'user': 'test'  // 上传附带参数
+					},
+					success: (uploadFileRes) => {
+						this.user.avatar =JSON.parse(uploadFileRes.data).url
+					}
+				});
+			},
+			getUserInfo(){
+				getUserInfo().then(
+					res => {
+						if(res.code==200){
+							this.user=res.data;
+						}else{
+							uni.showToast({
+								icon:'none',
+								title: "请求失败",
+							});
+						}
+					},
+					rej => {}
+				);
+			}
+			 
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.content{
+		// padding-top: 20rpx;
+	}
+	.info-item{
+		min-height: 104upx;
+		background: #FFFFFF;
+		padding: 0 30upx;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		border-bottom: 1px solid #F5F6FA;
+		&:last-child{
+			border-bottom: none;
+		}
+		.label{
+			font-size: 30upx;
+			font-family: PingFang SC;
+			font-weight: 400;
+			color: #0F1826;
+		}
+		.right{
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			position: relative;
+			.wx-head{
+				position: absolute;
+				width: 80upx;
+				height: 80upx;
+				opacity: 0;
+			}
+			.text{
+				font-size: 30upx;
+				font-family: PingFang SC;
+				font-weight: 400;
+				color: #0F1826;
+			}
+			.head{
+				border-radius: 50%;
+				width: 80upx;
+				height: 80upx;
+			}
+			.input{
+				text-align: right;
+				font-size: 30upx;
+				font-family: PingFang SC;
+				font-weight: 400;
+				color: #0F1826;
+			}
+			image{
+				padding: 20rpx 0;
+			}
+		}
+		 
+	}
+	.btn-box{
+		margin-top: 20rpx;
+		height: 120upx;
+		padding: 0 30upx;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		.sub-btn{
+			width: 100%;
+			height: 88upx;
+			line-height: 88upx;
+			text-align: center;
+			font-size: 30upx;
+			font-family: PingFang SC;
+			font-weight: bold;
+			color: #FFFFFF;
+			background: #0bb3f2;
+			border-radius: 44upx;
+		}
+	}
+</style>

+ 140 - 70
pages_user/points.vue

@@ -9,9 +9,9 @@
 				</view>
 				<view class="card-content">
 					<view class="card-label">积分账户</view>
-					<view class="card-balance">{{ pointsData.balance || '0.00' }}</view>
+					<view class="card-balance">{{ pointsData.creditNum || '0.00' }}</view>
 					<view class="x-bc">
-						<view class="card-pending">支出待入账: {{ pointsData.pendingExpense || '0.00' }}</view>
+						<view class="card-pending">支出待入账: {{ pointsData.waitCreditNum || '0.00' }}</view>
 						<view class="withdraw-btn x-c" @click="goWithdraw">去提现</view>
 					</view>
 					
@@ -28,15 +28,15 @@
 						</view>
 					</picker>
 					<view class="total-amount">
-						收入{{ summaryData.totalIncome || '0.00' }}
+						{{incomeType === 2?"收入":"支出"}}{{ summaryData.totalIncome || '0.00' }}
 					</view>
 				</view>
 				<view class="x-bc">
 					<view class="type-buttons">
-						<view class="type-btn" :class="{ active: incomeType === 'income' }" @click="switchType('income')">
+						<view class="type-btn" :class="{ active: incomeType === 2 }" @click="switchType(2)">
 							收入
 						</view>
-						<view class="type-btn" :class="{ active: incomeType === 'expense' }" @click="switchType('expense')">
+						<view class="type-btn" :class="{ active: incomeType === 1 }" @click="switchType(1)">
 							支出
 						</view>
 					</view>
@@ -49,13 +49,14 @@
 				<view class="transaction-list">
 					<view class="transaction-item" v-for="(item, index) in transactionList" :key="index">
 						<view class="item-left">
-							<view class="item-title">{{ item.title }}</view>
-							<view class="item-time">{{ item.dateTime }}</view>
+							<view class="item-title">{{ item.doctorName }}</view>
+							<view class="item-time">{{ item.createAt }}</view>
 						</view>
 						<view class="item-amount" :class="item.type">
-							{{ item.type === 'income' ? '+' : '-' }}{{ item.amount }}
+							{{ item.changeType === 2 ? '+' : '-' }}{{ item.changeMoney }}
 						</view>
 					</view>
+					<view class="no-more" v-if="!hasMore && transactionList.length > 0">没有更多了~</view>
 				</view>
 			</view>
 			
@@ -91,7 +92,7 @@
 </template>
 
 <script>
-import { getPointsList, getPointsInfo } from '@/api-js/points'
+import { getPointsList, getPointsInfo, getPointsTypeOptions, getPointsStatistics } from '@/api/points'
 export default {
 	data() {
 		return {
@@ -100,42 +101,42 @@ export default {
 			showTypePicker: false,
 			selectedDate: '2025-12',
 			tempDate: '2025-12',
-			incomeType: 'income', // income: 收入, expense: 支出
+			incomeType: 2, // income: 收入, expense: 支出
 			selectedType: '全部类型',
-			tempType: '全部类型',
+			tempType: '',
 			typeOptions: [
-				{ label: '全部类型', value: '全部类型' },
-				{ label: '医生坐诊', value: '医生坐诊' },
-				{ label: '科普讲座', value: '科普讲座' },
-				{ label: '学术研究', value: '学术研究' },
-				{ label: '科普文章', value: '科普文章' },
-				{ label: '科普短视频', value: '科普短视频' },
-				{ label: '科普长视频', value: '科普长视频' },
-				{ label: '空中课堂', value: '空中课堂' },
-				{ label: '用药调研', value: '用药调研' },
-				{ label: '问卷调研', value: '问卷调研' },
-				{ label: '社群咨询', value: '社群咨询' },
-				{ label: '健康问答', value: '健康问答' },
-				{ label: '受试者随访', value: '受试者随访' },
-				{ label: '受试者招募', value: '受试者招募' }
 			],
 			pointsData: {
-				balance: '320.00',
-				pendingExpense: '30.00'
 			},
 			summaryData: {
-				totalIncome: '600.00'
+				totalIncome: '0.00'
 			},
-			transactionList: []
+			transactionList: [],
+			pageNum: 1,
+			pageSize: 10,
+			hasMore: true,
+			loading: false
 		}
 	},
 	onLoad() {
+		this.loadTypeOptions()
+		this.initCurrentMonth()
+	},
+	onShow() {
 		this.loadData()
 	},
 	onReachBottom() {
 		this.loadMore()
 	},
 	methods: {
+		  // 核心:初始化当前月份
+		    initCurrentMonth() {
+		      const now = new Date();
+		      const year = now.getFullYear();
+		      const month = (now.getMonth() + 1).toString().padStart(2, "0");
+		      this.selectedDate = `${year}-${month}`;
+		      this.tempDate = `${year}-${month}`;
+		    },
 		goBack() {
 			uni.navigateBack()
 		},
@@ -146,79 +147,141 @@ export default {
 		},
 		onDateChange(e) {
 			this.selectedDate = e.detail.value
-			this.loadData()
+			this.pageNum = 1
+			this.hasMore = true
+			this.loadList()
 		},
-		// confirmDate() {
-		// 	this.selectedDate = this.tempDate
-		// 	this.showDatePicker = false
-		// 	this.loadData()
-		// },
 		closeTypePicker() {
 			this.showTypePicker = false
-			// 关闭时恢复临时选择
-			this.tempType = this.selectedType
 		},
 		resetType() {
-			this.tempType = '全部类型'
+			this.tempType = ''
 		},
 		confirmType() {
-			this.selectedType = this.tempType
+			// 根据 tempType 找到对应的选项
+			const selectedOption = this.typeOptions.find(item => item.value === this.tempType)
+			this.selectedType = selectedOption ? selectedOption.label : '全部类型'
+			if (!selectedOption) this.tempType = ''
 			this.showTypePicker = false
-			this.loadData()
+			this.pageNum = 1
+			this.hasMore = true
+			this.loadList()
 		},
 		switchType(type) {
 			this.incomeType = type
-			this.loadData()
+			this.pageNum = 1
+			this.hasMore = true
+			this.loadList()
 		},
 		openTypePicker() {
-			this.tempType = this.selectedType
+			// 根据 selectedType 找到对应的 value 设置给 tempType
+			const selectedOption = this.typeOptions.find(item => item.label === this.selectedType)
+			this.tempType = selectedOption ? selectedOption.value : ''
 			this.showTypePicker = true
 		},
 		async loadData() {
 			try {
+				this.pageNum = 1
+				this.hasMore = true
 				uni.showLoading({ title: '加载中...' })
-				const [infoRes, listRes] = await Promise.all([
-					getPointsInfo(),
-					getPointsList({
-						date: this.selectedDate,
-						type: this.incomeType,
-						category: this.selectedType === '全部类型' ? '' : this.selectedType,
-						page: 1,
-						pageSize: 20
-					})
+				
+				const [infoRes] = await Promise.all([
+					getPointsInfo({}),
+					this.loadList(true) // 不显示loading,因为外层已经显示了
 				])
 				uni.hideLoading()
 				
 				if (infoRes.code === 200 && infoRes.data) {
-					this.pointsData = {
-						balance: (infoRes.data.balance || 0).toFixed(2),
-						pendingExpense: (infoRes.data.pendingExpense || 0).toFixed(2)
-					}
+					this.pointsData = infoRes.data
+				}
+			} catch (e) {
+				uni.hideLoading()
+				console.error('加载数据失败', e)
+			}
+		},
+		async loadList(silent = false) {
+			try {
+				if (!silent) {
+					uni.showLoading({ title: '加载中...' })
+				}
+				
+				// 获取选中的类型值
+				const businessType = this.selectedType === '全部类型' ? '' : 
+					(this.typeOptions.find(item => item.label === this.selectedType)?.value || '')
+				
+				const listRes = await getPointsList({
+					pageNum: this.pageNum,
+					pageSize: this.pageSize,
+					changeType: this.incomeType,
+					...(businessType && { businessType })
+				})
+				
+				if (!silent) {
+					uni.hideLoading()
 				}
 				
 				if (listRes.code === 200 && listRes.data) {
-					this.transactionList = listRes.data.list || this.getDefaultData()
+					if (this.pageNum === 1) {
+						// 第一页,直接替换
+						this.transactionList = listRes.data.doctorBalanceLogs || []
+					} else {
+						// 后续页,追加数据
+						this.transactionList = [...this.transactionList, ...(listRes.data.doctorBalanceLogs || [])]
+					}
 					this.summaryData = {
-						totalIncome: (listRes.data.totalIncome || 0).toFixed(2)
+						totalIncome: (listRes.data.total || 0).toFixed(2)
+					}
+					// 判断是否还有更多数据
+					if (!listRes.data.doctorBalanceLogs || listRes.data.doctorBalanceLogs.length < this.pageSize) {
+						this.hasMore = false
 					}
 				} else {
-					this.transactionList = this.getDefaultData()
+					if (this.pageNum === 1) {
+						this.transactionList = []
+					}
+					this.hasMore = false
 				}
 			} catch (e) {
-				uni.hideLoading()
-				console.error('加载数据失败', e)
-				this.transactionList = this.getDefaultData()
+				if (!silent) {
+					uni.hideLoading()
+				}
+				console.error('加载列表失败', e)
+				if (this.pageNum === 1) {
+					this.transactionList = []
+				}
+				this.hasMore = false
 			}
 		},
-		async loadMore() {
-			// 加载更多数据
+		async loadTypeOptions() {
+			// 加载积分类型选项
+			try {
+				const res = await getPointsTypeOptions({dictType:"credit_flow_type"})
+				if (res.code === 200 && res.data && Array.isArray(res.data)) {
+					// 更新类型选项列表
+					this.typeOptions = [
+						{ label: '全部类型', value: '' },
+						...res.data.map(item => ({
+							label: item.dictLabel,
+							value: item.dictValue
+						}))
+					]
+				}
+			} catch (e) {
+				console.error('加载积分类型选项失败', e)
+			}
 		},
-		getDefaultData() {
-			// 默认数据,根据图片中的示例
-			return [
-				{ title: '医生座诊', dateTime: '2021-07-29 19:55', amount: '300', type: 'income' },
-				{ title: '科普讲座', dateTime: '2021-07-29 19:55', amount: '300', type: 'income' }
-			]
+		async loadMore() {
+			if (!this.hasMore || this.loading) return
+			
+			try {
+				this.loading = true
+				this.pageNum = this.pageNum + 1
+				await this.loadList(true) // 静默加载,不显示loading
+			} catch (e) {
+				console.error('加载更多数据失败', e)
+			} finally {
+				this.loading = false
+			}
 		}
 	}
 }
@@ -287,7 +350,7 @@ export default {
 	position: relative;
 	margin: 24rpx;
 	height: 280rpx;
-	background: linear-gradient(135deg, #FF9800 0%, #FFC107 100%);
+	background: linear-gradient( 81deg, #FFDF87 0%, #FFB042 100%);
 	border-radius: 24rpx;
 	padding: 48rpx 40rpx;
 	overflow: hidden;
@@ -418,6 +481,13 @@ export default {
 	// margin: 0 24rpx 24rpx;
 	border-radius: 16rpx;
 	padding: 24rpx;
+	
+	.no-more {
+		text-align: center;
+		padding: 48rpx 0;
+		font-size: 24rpx;
+		color: #999;
+	}
 }
 
 .transaction-item {

+ 3 - 3
pages_user/practiceCertificateExample.vue

@@ -36,12 +36,12 @@
 				</view>
 				<view class="example-images">
 					<view class="example-image-item">
-						<image src="@/static/image/img_example1.svg" mode=""></image>
+						<image src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/img_example1.png" mode=""></image>
 						<!-- <view class="image-placeholder">示例图片1:老版本执业证编码页</view> -->
 						<!-- 请将示例图片放置在 @/static/image/example_old_practice_1.png -->
 					</view>
 					<view class="example-image-item">
-						<image src="@/static/image/img_example2.svg" mode=""></image>
+						<image src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/img_example2.png" mode=""></image>
 						<!-- <view class="image-placeholder">示例图片2:老版本执业证注册信息页</view> -->
 						<!-- 请将示例图片放置在 @/static/image/example_old_practice_2.png -->
 					</view>
@@ -59,7 +59,7 @@
 					<view class="instruction-item">2.如有变更记录请继续补充上传。</view>
 				</view>
 				<view class="example-image">
-					<image src="@/static/image/img_example3.svg" mode=""></image>
+					<image src="https://ysrw-1395926010.cos.ap-chengdu.myqcloud.com/images/img_example3.png" mode=""></image>
 					<!-- <view class="image-placeholder">示例图片:新版本执业证</view> -->
 					<!-- 请将示例图片放置在 @/static/image/example_new_practice.png -->
 				</view>

+ 23 - 4
pages_user/serviceAgreement.vue

@@ -13,7 +13,7 @@
 </template>
 
 <script>
-import { getServiceAgreementList } from '@/api-js/serviceAgreement'
+import { getServiceAgreementList, getAgreementTypeList } from '@/api/serviceAgreement'
 export default {
 	data() {
 		return {
@@ -30,12 +30,27 @@ export default {
 	methods: {
 		async loadAgreementList() {
 			try {
-				const res = await getServiceAgreementList()
-				if (res.code === 200 && res.data) {
-					this.agreementList = res.data
+				uni.showLoading({ title: '加载中...' })
+				const [listRes, typeRes] = await Promise.all([
+					getServiceAgreementList(),
+					getAgreementTypeList().catch(() => ({ code: 0 }))
+				])
+				uni.hideLoading()
+				
+				if (listRes.code === 200 && listRes.data) {
+					this.agreementList = Array.isArray(listRes.data) ? listRes.data : []
+				} else {
+					this.agreementList = []
+				}
+				
+				// 如果有协议类型列表,可以用于筛选等功能
+				if (typeRes.code === 200 && typeRes.data) {
+					console.log('协议类型列表', typeRes.data)
 				}
 			} catch (e) {
+				uni.hideLoading()
 				console.error('加载服务协议列表失败', e)
+				this.agreementList = []
 			}
 		},
 		goBack() {
@@ -143,3 +158,7 @@ export default {
 
 
 
+
+
+
+

+ 7 - 1
pages_user/serviceAgreementDetail.vue

@@ -8,7 +8,7 @@
 </template>
 
 <script>
-import { getServiceAgreementDetail } from '@/api-js/serviceAgreement'
+import { getServiceAgreementDetail } from '@/api/serviceAgreement'
 export default {
 	data() {
 		return {
@@ -156,3 +156,9 @@ export default {
 
 
 
+
+
+
+
+
+

+ 123 - 51
pages_user/serviceOrder.vue

@@ -15,19 +15,19 @@
 		<!-- 内容区域 -->
 		<scroll-view class="content" scroll-y @scrolltolower="loadMore">
 			<view class="order-list">
-				<view class="month-group" v-for="(group, groupIndex) in groupedOrders" :key="groupIndex">
+				<view class="month-group" v-for="(group, groupIndex) in groupedOrders" :key="group.month">
 					<view class="month-header">
 						<!-- <view class="month-icon">○</view> -->
-						<text class="month-text">{{ group.month }}</text>
+						<text class="month-text">{{ formatMonth(group.month) }}</text>
 					</view>
 					<view class="order-items">
-						<view class="order-item" v-for="(item, index) in group.items" :key="index" @click="goToDetail(item)">
+						<view class="order-item" v-for="(item, index) in group.items" :key="getItemKey(item, index)" @click.stop="(e) => goToConfirm(item, e)">
 							<view class="order-content">
 								<view class="order-title">服务确认单</view>
 								<view class="order-time">{{ item.createTime }}</view>
 							</view>
 							<view class="order-action" v-if="activeTab === 'pending'">
-								<view class="confirm-btn" @click.stop="goToConfirm(item)">去确认</view>
+								<view class="confirm-btn">去确认</view>
 							</view>
 						</view>
 					</view>
@@ -35,7 +35,8 @@
 			</view>
 			
 			<!-- 空状态 -->
-			<view class="empty-state" v-if="groupedOrders.length === 0">
+			<view class="empty-state y-bc" v-if="groupedOrders.length === 0">
+				<image class="w300 h300" src="@/static/image/img_blank_nodata.png" mode=""></image>
 				<text>暂无数据</text>
 			</view>
 		</scroll-view>
@@ -43,81 +44,126 @@
 </template>
 
 <script>
-import { getServiceOrderList } from '@/api-js/serviceOrder'
+import { getServiceOrderList, getServiceOrderStatusList} from '@/api/serviceOrder'
 export default {
 	data() {
 		return {
 			activeTab: 'pending', // pending: 待确认, confirmed: 已确认
-			orderList: [],
+			orderData: {}, // 存储接口返回的按月份分组的数据 { "2026-01": [...], "2026-02": [...] }
 			page: 1,
-			pageSize: 20,
+			pageSize: 10,
 			hasMore: true
 		}
 	},
 	computed: {
-		// 按月份分组订单
+		// 将接口返回的月份分组数据转换为页面需要的格式
 		groupedOrders() {
-			const groups = {}
-			this.orderList.forEach(item => {
-				const month = item.createTime ? item.createTime.substring(0, 7) : '未知'
-				if (!groups[month]) {
-					groups[month] = {
+			const groups = []
+			// 根据当前 tab 确定 doctorConfirm 值
+			const doctorConfirm = this.activeTab === 'pending' ? 0 : 1
+			// 遍历接口返回的数据对象
+			Object.keys(this.orderData).forEach(month => {
+				const items = (this.orderData[month] || []).filter(item => {
+					// 根据 doctorConfirm 过滤数据
+					return item.doctorConfirm === doctorConfirm
+				})
+				if (items.length > 0) {
+					groups.push({
 						month: month,
-						items: []
-					}
+						items: items
+					})
 				}
-				groups[month].items.push(item)
 			})
-			// 转换为数组并按月份倒序排列
-			return Object.values(groups).sort((a, b) => {
+			// 按月份倒序排列(最新的月份在前)
+			return groups.sort((a, b) => {
 				return b.month.localeCompare(a.month)
 			})
 		}
 	},
 	onLoad() {
-		this.loadData()
+		// this.loadStatusList()
+		//this.loadData(true)
+	},
+	onShow() {
+		this.loadData(true)
 	},
 	methods: {
 		async loadData(refresh = false) {
 			if (refresh) {
 				this.page = 1
 				this.hasMore = true
+				this.orderData = {}
 			}
 			
 			if (!this.hasMore) return
 			
 			try {
 				uni.showLoading({ title: '加载中...' })
-				this.orderList = this.getDefaultData()
-				// const res = await getServiceOrderList({
-				// 	status: this.activeTab === 'pending' ? 0 : 1, // 0: 待确认, 1: 已确认
-				// 	page: this.page,
-				// 	pageSize: this.pageSize
-				// })
-				// uni.hideLoading()
+				// 根据当前 tab 设置 doctorConfirm 参数
+				const doctorConfirm = this.activeTab === 'pending' ? 0 : 1
+				const res = await getServiceOrderList({
+					doctorConfirm: doctorConfirm, // 0: 待确认, 1: 已确认
+					pageNum: this.page,
+					pageSize: this.pageSize
+				})
+				uni.hideLoading()
 				
-				// if (res.code === 200 && res.data) {
-				// 	const list = res.data.list || []
-				// 	if (refresh) {
-				// 		this.orderList = list
-				// 	} else {
-				// 		this.orderList = [...this.orderList, ...list]
-				// 	}
+				if (res.code === 200 && res.data) {
+					// 接口返回的数据结构:{ "2026-01": [...], "2026-02": [...] }
+					const monthData = res.data || {}
 					
-				// 	this.hasMore = list.length >= this.pageSize
-				// 	if (this.hasMore) {
-				// 		this.page++
-				// 	}
-				// } else {
-				// 	// 使用示例数据
-				// 	this.orderList = this.getDefaultData()
-				// }
+					if (refresh) {
+						// 刷新时直接替换
+						this.orderData = { ...monthData }
+					} else {
+						// 加载更多时合并数据
+						Object.keys(monthData).forEach(month => {
+							if (this.orderData[month]) {
+								// 如果该月份已存在,合并数组
+								this.orderData[month] = [...this.orderData[month], ...monthData[month]]
+							} else {
+								// 如果该月份不存在,直接添加
+								this.orderData[month] = [...monthData[month]]
+							}
+						})
+					}
+					
+					// 判断是否还有更多数据(根据返回的月份数量判断)
+					const monthCount = Object.keys(monthData).length
+					this.hasMore = monthCount > 0
+					if (this.hasMore) {
+						this.page++
+					}
+				} else {
+					// 如果接口失败,使用空对象
+					uni.showToast({
+						icon: 'none',
+						title: res.msg
+					})
+					if (refresh) {
+						this.orderData = {}
+					}
+				}
 			} catch (e) {
 				uni.hideLoading()
 				console.error('加载服务单列表失败', e)
-				this.orderList = this.getDefaultData()
+				if (refresh) {
+					this.orderData = {}
+				}
 			}
 		},
+		// async loadStatusList() {
+		// 	// 加载服务单状态列表(如果需要)
+		// 	try {
+		// 		const res = await getServiceOrderStatusList()
+		// 		if (res.code === 200 && res.data) {
+		// 			// 可以用于状态筛选等功能
+		// 			console.log('服务单状态列表', res.data)
+		// 		}
+		// 	} catch (e) {
+		// 		console.error('加载服务单状态列表失败', e)
+		// 	}
+		// },
 		getDefaultData() {
 			uni.hideLoading()
 			// 示例数据
@@ -165,13 +211,43 @@ export default {
 		},
 		goToDetail(item) {
 			uni.navigateTo({
-				url: `/pages_user/serviceOrderDetail?id=${item.id}&status=${item.status}`
+				url: `/pages_user/serviceOrderDetail?id=`+item.id+`&status=1`
 			})
 		},
-		goToConfirm(item) {
+		goToConfirm(item, e) {
+			// 阻止事件冒泡
+			if (e) {
+				e.stopPropagation()
+			}
+			if (!item) {
+				console.error('goToConfirm: item is undefined')
+				return
+			}
+			console.log('item', item)
+			const orderId = item.id
+			if (!orderId) {
+				uni.showToast({
+					icon: 'none',
+					title: '订单ID不存在'
+				})
+				return
+			}
 			uni.navigateTo({
-				url: `/pages_user/serviceOrderDetail?id=${item.id}&status=0`
+				url: `/pages_user/serviceOrderDetail?id=${orderId}&status=0`
 			})
+		},
+		// 格式化月份显示(可选:将 2026-01 格式化为 2026年01月)
+		formatMonth(month) {
+			if (!month) return '未知'
+			const parts = month.split('-')
+			if (parts.length === 2) {
+				return `${parts[0]}年${parts[1]}月`
+			}
+			return month
+		},
+		// 获取列表项的 key(用于 v-for)
+		getItemKey(item, index) {
+			return item.id || item.serviceTicketId || item.ticketId || `item_${index}`
 		}
 	}
 }
@@ -180,7 +256,6 @@ export default {
 <style lang="scss" scoped>
 .container {
 	min-height: 100vh;
-	background: #f5f5f5;
 	display: flex;
 	flex-direction: column;
 }
@@ -233,7 +308,7 @@ export default {
 .tabs {
 	display: flex;
 	background: #fff;
-	border-bottom: 1rpx solid #f0f0f0;
+	//border-bottom: 1rpx solid #f0f0f0;
 	
 	.tab-item {
 		flex: 1;
@@ -362,6 +437,3 @@ export default {
 
 
 
-
-
-

+ 155 - 54
pages_user/serviceOrderDetail.vue

@@ -6,7 +6,7 @@
 				<!-- 服务单标题和已确认标识 -->
 				<view class="order-header">
 					<view class="order-title-text">服务单</view>
-					<image class="w144 h144" v-if="orderDetail.status === 1" src="@/static/image/img_confirmed.png" mode=""></image>
+					<image class="w144 h144" v-if="serviceOrder.doctorConfirm === 1" src="@/static/image/img_confirmed.png" mode=""></image>
 				</view>
 				
 				<!-- 服务内容 -->
@@ -24,12 +24,12 @@
 							<view class="table-cell">总金额</view>
 						</view>
 						<view class="table-row" v-for="(item, index) in orderDetail.serviceItems" :key="index">
-							<view class="table-cell">{{ item.projectName }}</view>
-							<view class="table-cell">{{ item.singleAmount }}</view>
-							<view class="table-cell">{{ item.completeTime }}</view>
-							<view class="table-cell">{{ item.unit }}</view>
-							<view class="table-cell">{{ item.quantity }}</view>
-							<view class="table-cell">{{ item.totalAmount }}</view>
+							<view class="table-cell x-c">{{ item.projectName }}</view>
+							<view class="table-cell x-c">{{ item.taskIntegral}}</view>
+							<view class="table-cell x-c">{{ formatDate(item.planEndTime) }}</view>
+							<view class="table-cell x-c">{{ item.taskUnit}}</view>
+							<view class="table-cell x-c">{{ item.taskCount }}</view>
+							<view class="table-cell x-c">{{ totalAmount }}</view>
 						</view>
 					</view>
 				</view>
@@ -42,13 +42,13 @@
 					
 					<view class="payment-info">
 						<view class="payment-text">
-							我司将向您支付人民币[{{ orderDetail.totalAmount || '1534' }}]元(大写:{{ orderDetail.amountInWords || '壹仟伍佰叁拾肆元整' }})作为此次劳务报酬(该服务报酬为我司代扣代缴相关税款后的金额),款项将汇入如下账户:
+							我司将向您支付人民币[{{ totalAmount || 0 }}]元(大写:{{ convertToChineseAmount(totalAmount) || '-' }})作为此次劳务报酬(该服务报酬为我司代扣代缴相关税款后的金额),款项将汇入如下账户:
 						</view>
 						
 						<view class="account-info">
 							<view class="account-item">
 								<text class="account-label">姓名:</text>
-								<text class="account-value">{{ orderDetail.accountName || '王小明' }}</text>
+								<text class="account-value">{{ serviceOrder.initiatorName || '王小明' }}</text>
 							</view>
 							<view class="account-item">
 								<text class="account-label">开户行:</text>
@@ -56,7 +56,7 @@
 							</view>
 							<view class="account-item">
 								<text class="account-label">账号:</text>
-								<text class="account-value">{{ orderDetail.accountNumber || '6524012536580258' }}</text>
+								<text class="account-value">{{ orderDetail.bankCardNo || '6524012536580258' }}</text>
 							</view>
 						</view>
 					</view>
@@ -64,9 +64,9 @@
 			</view>
 			</scroll-view>
 			
-		<view class="confirm-box">
+		<view class="confirm-box" v-if="serviceOrder.doctorConfirm === 0">
 			<!-- 确认选项(仅待确认状态显示) -->
-			<view class="confirm-options" v-if="orderDetail.status === 0">
+			<view class="confirm-options">
 				<view class="option-item">
 					<checkbox-group @change="onOptionChange">
 						<label class="option-label">
@@ -95,11 +95,14 @@
 </template>
 
 <script>
-import { getServiceOrderDetail, confirmServiceOrder } from '@/api-js/serviceOrder'
+import { getServiceOrderDetail, confirmServiceOrder } from '@/api/serviceOrder'
+import utils from '@/utils/common.js'
 export default {
 	data() {
 		return {
-			orderId: '',
+			serviceOrderId:null,
+			serviceOrder:{},
+			totalAmount:0,
 			orderDetail: {
 				status: 0,
 				totalAmount: '1534',
@@ -113,15 +116,13 @@ export default {
 				promise: false,
 				lecture: false
 			},
-			
+			user:{},
+			utils: utils // 将 utils 挂载到 data 中,以便在模板中使用
 		}
 	},
 	onLoad(options) {
 		if (options.id) {
-			this.orderId = options.id
-		}
-		if (options.status) {
-			this.orderDetail.status = parseInt(options.status)
+			this.serviceOrderId = options.id
 		}
 		this.loadOrderDetail()
 	},
@@ -129,32 +130,26 @@ export default {
 		async loadOrderDetail() {
 			try {
 				uni.showLoading({ title: '加载中...' })
-				// const res = await getServiceOrderDetail({ id: this.orderId })
+				const res = await getServiceOrderDetail({ serviceOrderId: this.serviceOrderId })
 				uni.hideLoading()
 				
-				// if (res.code === 200 && res.data) {
-				// 	this.orderDetail = { ...this.orderDetail, ...res.data }
-				// } else {
-					// 使用示例数据
-					this.orderDetail.serviceItems = [
-						{ projectName: '病例征集', singleAmount: '111.00', completeTime: '2023年9月12日', unit: '个', quantity: 1, totalAmount: '111.00' },
-						{ projectName: '病例征集', singleAmount: '100.00', completeTime: '2023年9月12日', unit: '个', quantity: 1, totalAmount: '100.00' },
-						{ projectName: '病例征集', singleAmount: '100.00', completeTime: '2023年9月12日', unit: '个', quantity: 1, totalAmount: '100.00' },
-						{ projectName: '病例征集', singleAmount: '1200.00', completeTime: '2023年9月12日', unit: '个', quantity: 1, totalAmount: '1200.00' },
-						{ projectName: '病例征集', singleAmount: '23.00', completeTime: '2023年9月12日', unit: '个', quantity: 1, totalAmount: '23.00' }
-					]
-				// }
+				if (res.code === 200 && res.data) {
+					this.orderDetail = { ...this.orderDetail, ...res.data }
+					if (res.data.serviceOrderInfoVO) {
+						this.orderDetail.serviceItems = res.data.serviceOrderInfoVO.taskInfos
+						this.serviceOrder = res.data.serviceOrderInfoVO.serviceOrder
+						this.totalAmount = this.serviceOrder.totalAmount
+					}
+				} else {
+					uni.hideLoading();
+					uni.showToast({
+						icon:'none',
+						title: res.msg,
+					});
+				}
 			} catch (e) {
 				uni.hideLoading()
 				console.error('加载服务单详情失败', e)
-				// 使用示例数据
-				this.orderDetail.serviceItems = [
-					{ projectName: '病例征集', singleAmount: '111.00', completeTime: '2023年9月12日', unit: '个', quantity: 1, totalAmount: '111.00' },
-					{ projectName: '病例征集', singleAmount: '100.00', completeTime: '2023年9月12日', unit: '个', quantity: 1, totalAmount: '100.00' },
-					{ projectName: '病例征集', singleAmount: '100.00', completeTime: '2023年9月12日', unit: '个', quantity: 1, totalAmount: '100.00' },
-					{ projectName: '病例征集', singleAmount: '1200.00', completeTime: '2023年9月12日', unit: '个', quantity: 1, totalAmount: '1200.00' },
-					{ projectName: '病例征集', singleAmount: '23.00', completeTime: '2023年9月12日', unit: '个', quantity: 1, totalAmount: '23.00' }
-				]
 			}
 		},
 		onOptionChange(e) {
@@ -162,24 +157,134 @@ export default {
 			this.confirmOptions.promise = values.includes('promise')
 			this.confirmOptions.lecture = values.includes('lecture')
 		},
+		// 格式化日期字符串为年月日格式
+		formatDate(dateStr) {
+			if (!dateStr) return ''
+			// 处理 "2026-02-05" 格式的日期字符串
+			if (typeof dateStr === 'string' && dateStr.includes('-')) {
+				// 将 "2026-02-05" 转换为 Date 对象
+				const date = new Date(dateStr.replace(/-/g, '/'))
+				// 使用 utils.timeFormat 格式化
+				return utils.timeFormat(date.getTime(), 'yyyy年mm月dd日')
+			}
+			// 如果是时间戳,直接使用
+			return utils.timeFormat(dateStr, 'yyyy年mm月dd日')
+		},
+		// 将数字金额转换为中文大写
+		convertToChineseAmount(amount) {
+			if (!amount && amount !== 0) return ''
+			
+			// 转换为数字
+			const num = Number(amount)
+			if (isNaN(num) || num < 0) return ''
+			
+			// 中文数字
+			const chineseNums = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
+			// 单位
+			const units = ['', '拾', '佰', '仟']
+			const bigUnits = ['', '万', '亿']
+			
+			// 处理小数部分
+			const parts = num.toString().split('.')
+			const integerPart = Math.floor(num)
+			const decimalPart = parts[1] ? parts[1].substring(0, 2) : '' // 最多两位小数
+			
+			// 转换整数部分
+			let integerStr = integerPart.toString()
+			let result = ''
+			
+			if (integerPart === 0) {
+				result = '零'
+			} else {
+				// 每4位一组处理
+				const groups = []
+				while (integerStr.length > 0) {
+					groups.unshift(integerStr.slice(-4))
+					integerStr = integerStr.slice(0, -4)
+				}
+				
+				groups.forEach((group, groupIndex) => {
+					const groupNum = parseInt(group)
+					if (groupNum === 0) {
+						// 如果这一组是0,且不是最后一组,添加"零"
+						if (groupIndex < groups.length - 1) {
+							result += '零'
+						}
+						return
+					}
+					
+					let groupStr = ''
+					for (let i = 0; i < group.length; i++) {
+						const digit = parseInt(group[i])
+						const pos = group.length - 1 - i
+						
+						if (digit === 0) {
+							// 如果当前位是0,且下一位不是0,添加"零"
+							if (i < group.length - 1 && parseInt(group[i + 1]) !== 0) {
+								groupStr += '零'
+							}
+						} else {
+							groupStr += chineseNums[digit] + units[pos]
+						}
+					}
+					
+					result += groupStr
+					// 添加大单位(万、亿)
+					if (groupIndex < groups.length - 1) {
+						const bigUnitIndex = groups.length - 1 - groupIndex - 1
+						if (bigUnitIndex < bigUnits.length) {
+							result += bigUnits[bigUnitIndex]
+						}
+					}
+				})
+			}
+			
+			result += '元'
+			
+			// 处理小数部分
+			if (decimalPart) {
+				if (decimalPart.length === 1) {
+					const d1 = parseInt(decimalPart[0])
+					if (d1 !== 0) {
+						result += chineseNums[d1] + '角'
+					}
+				} else if (decimalPart.length === 2) {
+					const d1 = parseInt(decimalPart[0])
+					const d2 = parseInt(decimalPart[1])
+					if (d1 !== 0) {
+						result += chineseNums[d1] + '角'
+					}
+					if (d2 !== 0) {
+						result += chineseNums[d2] + '分'
+					}
+				}
+			} else {
+				result += '整'
+			}
+			
+			return result
+		},
 		goBack() {
 			uni.navigateBack()
 		},
 		async handleConfirm() {
-			if (!this.confirmOptions.promise) {
+			var user = JSON.parse(uni.getStorageSync('userInfo'))
+			// 验证至少选中一个选项(二选一)
+			if (!this.confirmOptions.promise && !this.confirmOptions.lecture) {
 				uni.showToast({
 					icon: 'none',
-					title: '请确认上述服务已真实发生'
+					title: '请至少选择一个确认选项'
 				})
 				return
 			}
 			
 			try {
 				uni.showLoading({ title: '确认中...' })
-				// const res = await confirmServiceOrder({
-				// 	id: this.orderId,
-				// 	confirmOptions: this.confirmOptions
-				// })
+				const res = await confirmServiceOrder({
+					serviceOrderId: this.serviceOrderId,
+					totalAmount:this.totalAmount,
+					userId:user.id
+				})
 				uni.hideLoading()
 				
 				if (res.code === 200) {
@@ -189,7 +294,7 @@ export default {
 					})
 					setTimeout(() => {
 						uni.navigateBack()
-					}, 1500)
+					}, 1000)
 				} else {
 					uni.showToast({
 						icon: 'none',
@@ -319,25 +424,21 @@ export default {
 		border: 1rpx solid #EBEDF0;
 		border-radius: 8rpx;
 		overflow: hidden;
-		overflow-x: auto;
+		width: 100%;
 		
 		.table-header,
 		.table-row {
 			display: flex;
-			min-width: 1000rpx;
+			width: 100%;
 			
 			.table-cell {
 				flex: 1;
-				min-width: 140rpx;
 				padding: 16rpx 8rpx;
 				font-size: 22rpx;
 				text-align: center;
 				border-right: 1rpx solid #EBEDF0;
 				word-break: break-all;
-				
-				&:first-child {
-					min-width: 200rpx;
-				}
+				box-sizing: border-box;
 				
 				&:last-child {
 					border-right: none;

+ 23 - 23
pages_user/withdraw.vue

@@ -22,7 +22,6 @@
 							class="amount-input" 
 							v-model="withdrawAmount" 
 							type="digit"
-							placeholder="0.00"
 							@input="onAmountInput"
 						/>
 					</view>
@@ -44,13 +43,14 @@
 </template>
 
 <script>
-import { submitWithdraw, getWithdrawInfo } from '@/api-js/withdraw'
-import { getBankCardInfo } from '@/api-js/bankCard'
+import { submitWithdraw, getWithdrawInfo } from '@/api/withdraw'
+import { getPointsInfo} from '@/api/points'
+import { getBankCardInfo } from '@/api/bankCard'
 export default {
 	data() {
 		return {
-			withdrawAmount: '320.00',
-			availableAmount: '320.00',
+			withdrawAmount: null,
+			availableAmount: '0.00',
 			bankCardInfo: {}
 		}
 	},
@@ -63,7 +63,7 @@ export default {
 				uni.showLoading({ title: '加载中...' })
 				const [bankRes, withdrawRes] = await Promise.all([
 					getBankCardInfo(),
-					getWithdrawInfo()
+					getPointsInfo()
 				])
 				uni.hideLoading()
 				
@@ -72,21 +72,16 @@ export default {
 				}
 				
 				if (withdrawRes.code === 200 && withdrawRes.data) {
-					this.availableAmount = (withdrawRes.data.availableAmount || 0).toFixed(2)
-					this.withdrawAmount = this.availableAmount
-				} else {
-					// 示例数据
-					this.availableAmount = '320.00'
-					this.withdrawAmount = '320.00'
-				}
-				
-				if (!this.bankCardInfo.id) {
-					// 示例数据
-					this.bankCardInfo = {
-						bankName: '中国工商银行',
-						cardNumber: '8869'
-					}
+					this.availableAmount = (withdrawRes.data.creditNum || 0).toFixed(2)
+					//this.withdrawAmount = this.availableAmount
 				}
+				// if (!this.bankCardInfo.id) {
+				// 	// 示例数据
+				// 	this.bankCardInfo = {
+				// 		bankName: '中国工商银行',
+				// 		cardNumber: '8869'
+				// 	}
+				// }
 			} catch (e) {
 				uni.hideLoading()
 				console.error('加载数据失败', e)
@@ -135,7 +130,7 @@ export default {
 		},
 		async handleSubmit() {
 			// 验证银行卡
-			if (!this.bankCardInfo.id) {
+			if (!this.bankCardInfo.bankCardNo) {
 				uni.showToast({
 					icon: 'none',
 					title: '请先添加银行卡'
@@ -168,8 +163,7 @@ export default {
 			try {
 				uni.showLoading({ title: '提交中...' })
 				const res = await submitWithdraw({
-					amount: this.withdrawAmount,
-					bankCardId: this.bankCardInfo.id
+					creditAmount: this.withdrawAmount
 				})
 				uni.hideLoading()
 				if (res.code === 200) {
@@ -387,3 +381,9 @@ export default {
 
 
 
+
+
+
+
+
+

+ 36 - 110
pages_user/withdrawSuccess.vue

@@ -4,17 +4,7 @@
 		<view class="content">
 			<!-- 成功图标 -->
 			<view class="success-icon-wrapper">
-				<view class="success-icon">
-					<view class="circle circle-outer"></view>
-					<view class="circle circle-middle"></view>
-					<view class="circle circle-inner">
-						<text class="checkmark">✓</text>
-					</view>
-					<view class="decoration decoration-1">○</view>
-					<view class="decoration decoration-2">·</view>
-					<view class="decoration decoration-3">+</view>
-					<view class="decoration decoration-4">·</view>
-				</view>
+				<image class="w320" src="@/static/image/img_success.png" mode="widthFix"></image>
 			</view>
 			
 			<!-- 成功文字 -->
@@ -22,11 +12,10 @@
 			
 			<!-- 提示文字 -->
 			<view class="success-tips">提现申请发起后,预计在3个工作日到账</view>
-		</view>
-		
-		<!-- 底部按钮 -->
-		<view class="bottom-bar">
-			<view class="home-btn" @click="goHome">返回首页</view>
+			<!-- 底部按钮 -->
+			<view class="bottom-bar">
+				<view class="home-btn" @click="goHome">返回首页</view>
+			</view>
 		</view>
 	</view>
 </template>
@@ -104,115 +93,46 @@ export default {
 	display: flex;
 	flex-direction: column;
 	align-items: center;
-	justify-content: center;
-	padding: 80rpx 24rpx;
+	//justify-content: center;
+	padding-top: 190rpx;
 }
 
 .success-icon-wrapper {
 	position: relative;
-	margin-bottom: 48rpx;
-	
-	.success-icon {
-		position: relative;
-		width: 240rpx;
-		height: 240rpx;
-		
-		.circle {
-			position: absolute;
-			left: 50%;
-			top: 50%;
-			transform: translate(-50%, -50%);
-			border-radius: 50%;
-			
-			&.circle-outer {
-				width: 240rpx;
-				height: 240rpx;
-				background: rgba(82, 196, 26, 0.1);
-			}
-			
-			&.circle-middle {
-				width: 180rpx;
-				height: 180rpx;
-				background: rgba(82, 196, 26, 0.3);
-			}
-			
-			&.circle-inner {
-				width: 120rpx;
-				height: 120rpx;
-				background: #52C41A;
-				display: flex;
-				align-items: center;
-				justify-content: center;
-				
-				.checkmark {
-					font-size: 72rpx;
-					color: #fff;
-					font-weight: bold;
-					line-height: 1;
-				}
-			}
-		}
-		
-		.decoration {
-			position: absolute;
-			color: #FFC107;
-			font-size: 32rpx;
-			
-			&.decoration-1 {
-				left: 20rpx;
-				top: 40rpx;
-				color: rgba(82, 196, 26, 0.4);
-			}
-			
-			&.decoration-2 {
-				left: 40rpx;
-				top: 20rpx;
-			}
-			
-			&.decoration-3 {
-				right: 40rpx;
-				top: 20rpx;
-				color: rgba(82, 196, 26, 0.4);
-			}
-			
-			&.decoration-4 {
-				right: 20rpx;
-				top: 60rpx;
-			}
-		}
-	}
+	margin-bottom: 40rpx;
 }
 
 .success-title {
-	font-size: 48rpx;
-	font-weight: bold;
-	color: #333;
-	margin-bottom: 32rpx;
+	font-family: PingFang SC, PingFang SC;
+	font-weight: 500;
+	font-size: 36rpx;
+	color: #333333;
+	line-height: 44rpx;
+	text-align: center;
+	margin-bottom: 14rpx;
 }
 
 .success-tips {
-	font-size: 26rpx;
-	color: #999;
-	text-align: center;
-	line-height: 1.8;
+	font-family: PingFang SC, PingFang SC;
+	font-weight: 400;
+	font-size: 24rpx;
+	color: #999999;
+	line-height: 40rpx;
 }
 
 .bottom-bar {
-	padding: 24rpx;
-	background: #fff;
-	border-top: 1rpx solid #f0f0f0;
-	
+	margin-top: 44rpx;
 	.home-btn {
-		width: 100%;
-		height: 88rpx;
+		width: 320rpx;
+		height: 80rpx;
 		background: #388BFF;
-		border-radius: 44rpx;
-		display: flex;
-		align-items: center;
-		justify-content: center;
-		font-size: 32rpx;
-		font-weight: bold;
-		color: #fff;
+		border-radius: 56rpx 56rpx 56rpx 56rpx;
+		font-family: PingFang SC, PingFang SC;
+		font-weight: 400;
+		font-size: 28rpx;
+		color: #FFFFFF;
+		line-height: 80rpx;
+		text-align: center;
 	}
 }
 </style>
@@ -223,3 +143,9 @@ export default {
 
 
 
+
+
+
+
+
+

BIN
static/image/icon_article.png


BIN
static/image/icon_back_w.png


BIN
static/image/icon_task_longvideo.png


BIN
static/image/icon_task_shortvideo.png


BIN
static/image/img_blank_nodata.png


BIN
static/logo.jpg


Некоторые файлы не были показаны из-за большого количества измененных файлов