MS-IOHQJGHXZHQD\Administrator 1 месяц назад
Родитель
Сommit
e10b262fc4
78 измененных файлов с 7133 добавлено и 3264 удалено
  1. 23 9
      src/App.vue
  2. 1 0
      src/api/index.js
  3. 99 1
      src/api/order.js
  4. 68 0
      src/api/workbench.js
  5. 7 3
      src/components/cl-upload/cl-upload/cl-upload.vue
  6. 177 29
      src/pages.json
  7. 349 239
      src/pages/index/index.vue
  8. 106 156
      src/pages/join/applyJoin.vue
  9. 25 30
      src/pages/join/commitDocumentEdit.vue
  10. 2 3
      src/pages/join/idCardEdit.vue
  11. 2 2
      src/pages/join/introduceYourselfEdit.vue
  12. 3 3
      src/pages/join/lifePhotosEdit.vue
  13. 105 92
      src/pages/join/staff.vue
  14. 190 100
      src/pages/my/dynamic/add_dynamic.vue
  15. 132 26
      src/pages/my/dynamic/components/my_list.vue
  16. 94 43
      src/pages/my/dynamic/dynamicDetail.vue
  17. 32 54
      src/pages/my/dynamic/index.vue
  18. 253 0
      src/pages/order/businessFormal.vue
  19. 225 0
      src/pages/order/cancelOrder.vue
  20. 401 0
      src/pages/order/moneyDetail.vue
  21. 242 0
      src/pages/order/moneyRecord.vue
  22. 756 227
      src/pages/order/order.vue
  23. 799 1413
      src/pages/order/order_detail.vue
  24. 775 0
      src/pages/order/search.vue
  25. 1 1
      src/setting/myNew/forgetPassword.vue
  26. 1 1
      src/setting/myNew/useCodeLogin.vue
  27. BIN
      src/static/login/clockIcon.png
  28. BIN
      src/static/login/emptyIcon.png
  29. BIN
      src/static/workbench/arriveIcon.png
  30. BIN
      src/static/workbench/checkIcon.png
  31. BIN
      src/static/workbench/clockIcon.png
  32. BIN
      src/static/workbench/clockIcon2.png
  33. BIN
      src/static/workbench/clockIcon3.png
  34. BIN
      src/static/workbench/downIcon.png
  35. BIN
      src/static/workbench/editIcon.png
  36. BIN
      src/static/workbench/emptyIcon.png
  37. BIN
      src/static/workbench/emptyIcon1.png
  38. BIN
      src/static/workbench/eyeIcon.png
  39. BIN
      src/static/workbench/filterIcon.png
  40. BIN
      src/static/workbench/finishIcon.png
  41. BIN
      src/static/workbench/goedIcon.png
  42. BIN
      src/static/workbench/handIcon.png
  43. BIN
      src/static/workbench/licenceIcon.png
  44. BIN
      src/static/workbench/licenceIcon1.png
  45. BIN
      src/static/workbench/licenceIcon2.png
  46. BIN
      src/static/workbench/localIcon.png
  47. BIN
      src/static/workbench/localIcon3.png
  48. BIN
      src/static/workbench/locationIcon.png
  49. BIN
      src/static/workbench/moreIcon.png
  50. BIN
      src/static/workbench/noGoIcon.png
  51. BIN
      src/static/workbench/noSignIcon.png
  52. BIN
      src/static/workbench/orderIcon.png
  53. BIN
      src/static/workbench/peopleIcon1.png
  54. BIN
      src/static/workbench/phoneIcon.png
  55. BIN
      src/static/workbench/propleIcon.png
  56. BIN
      src/static/workbench/radio.png
  57. BIN
      src/static/workbench/redArrow.png
  58. BIN
      src/static/workbench/rightIcon.png
  59. BIN
      src/static/workbench/serviceingIcon.png
  60. BIN
      src/static/workbench/signIcon.png
  61. BIN
      src/static/workbench/timeLineIcon.png
  62. BIN
      src/static/workbench/upIcon.png
  63. BIN
      src/static/workbench/warringIcon.png
  64. 18 0
      src/uni_modules/yi-code/changelog.md
  65. 226 0
      src/uni_modules/yi-code/components/yi-code/yi-code.vue
  66. 83 0
      src/uni_modules/yi-code/package.json
  67. 102 0
      src/uni_modules/yi-code/readme.md
  68. 11 2
      src/utils/index.js
  69. 3 1
      src/utils/request.js
  70. 130 48
      src/workbench/contract/detail.vue
  71. 24 57
      src/workbench/contract/index.vue
  72. 25 7
      src/workbench/fare/index.vue
  73. 717 0
      src/workbench/onlineHours/index.vue
  74. 71 67
      src/workbench/rating/index.vue
  75. 2 28
      src/workbench/rating/mock.js
  76. 314 260
      src/workbench/skill/add.vue
  77. 190 182
      src/workbench/skill/edit.vue
  78. 349 180
      src/workbench/skill/index.vue

+ 23 - 9
src/App.vue

@@ -26,6 +26,7 @@ export default {
 			//if (!isWechat) return;//guo
 			let openid = uni.getStorageSync('wx_copenid')
 			const code = this.$utils.getQueryStr('code');
+			console.log(code,'6666')
 			if (openid) {
 				this.checkMerchantStatus()
 			} else {
@@ -33,16 +34,18 @@ export default {
 				// if (!code && isWechat) {
 				// 	let appid = 'wx9dc677bd41e82569'
 				// 	//https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx9dc677bd41e82569&redirect_uri=https://city.baoxianzhanggui.com/fragrance/wxcode/&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
-				// 	let ruri = encodeURIComponent('https://city.baoxianzhanggui.com/fragrance/');
+				// 	//let ruri = encodeURIComponent('https://city.baoxianzhanggui.com/fragrance/');
+				// 	let ruri = encodeURIComponent('https://city.baoxianzhanggui.com/fragrance/wxcode');
 				// 	const authUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${ruri}&response_type=code&scope=snsapi_base&state=123#wechat_redirect`
 				// 	window.location.href = authUrl
 				// }
 
 				let params = {
 					//code: this.$utils.('code') //guo
-					code: '031VMh000FD7zW1OwB200nJFjM1VMh0q'
+					code: '041Gaa100q6IDW1BH6100Wgpvv4Gaa1K'
 				}
 				getTechnicianToken(params).then(res => {
+					console.log(res,'77777')
 					if (res.data.code == 200) {
 						uni.setStorageSync('wx_copenid', res.data.data.copenid);
 						this.checkMerchantStatus()
@@ -56,36 +59,47 @@ export default {
 		//查询商户注册和入驻信息   auditStatus 审核状态:-1-申请入住,0-待入驻,1-待审核,2-审核通过,3-审核驳回"
 
 		async checkMerchantStatus() {
+			// let token = uni.getStorageSync('access-token'); // 假设token保存在本地缓存中
+			// if (!token) {
+			// 	uni.navigateTo({
+			// 		url: '/setting/myNew/phone'
+			// 	})
+			// 	return
+			// };
 			const openid = uni.getStorageSync('wx_copenid')
 			const merchantInfo = await this.$utils.checkMerchantStatus(openid)
 			if (!merchantInfo) return
-			//merchantInfo.merchant.auditStatus = 2  //guo
-			if (merchantInfo.merchant.auditStatus == -1) {//未注册
+			//merchantInfo.auditStatus = 3  //guo
+			//merchantInfo.fileGroups = []
+			uni.setStorageSync('auditStatus', merchantInfo.auditStatus)
+			uni.setStorageSync('serviceTag', merchantInfo.serviceTag)
+
+			if (merchantInfo.auditStatus == -1) {//未注册
 				uni.navigateTo({
 					url: '/pages/join/staff'
 				})
 				return
 
-			} else if (merchantInfo.merchant.auditStatus == 0 || merchantInfo.merchant.auditStatus == 1 || merchantInfo.merchant.auditStatus == 2 || merchantInfo.merchant.auditStatus == 3) {
-				if (merchantInfo.merchant.auditStatus == 0) { //待入驻
+			} else if (merchantInfo.auditStatus == 0 || merchantInfo.auditStatus == 1 || merchantInfo.auditStatus == 2 || merchantInfo.auditStatus == 3) {
+				if (merchantInfo.auditStatus == 0) { //待入驻
 					if (!this.$utils.checkLogin({ type: 'navigate' })) return;
 					uni.switchTab({
 						url: '/pages/index/index'
 					})
 					return
 				}
-				if (merchantInfo.merchantAuditFile.length) {//已有入驻信息
+				if (merchantInfo.fileGroups.length) {//已有入驻信息
 					if (!this.$utils.checkLogin({ type: 'navigate' })) return;
 					uni.switchTab({
 						url: '/pages/index/index?merchantInfo=' + encodeURIComponent(JSON.stringify(merchantInfo))
 					})
 
 				} else {//无入驻信息
-					if (merchantInfo.merchant.auditStatus == 1 || merchantInfo.merchant.auditStatus == 3) {
+					if (merchantInfo.auditStatus == 1 || merchantInfo.auditStatus == 3) {
 						uni.navigateTo({
 							url: '/pages/join/staff?merchantInfo=' + encodeURIComponent(JSON.stringify(merchantInfo))
 						})
-					} if (merchantInfo.merchant.auditStatus == 2) {
+					} if (merchantInfo.auditStatus == 2) {
 						uni.switchTab({
 							url: '/pages/index/index'
 						})

+ 1 - 0
src/api/index.js

@@ -611,6 +611,7 @@ export function getServiceCategoryList(dictType) {
 export function getTechnicianInfo(data) {
     return request({
         method: 'get',
+        //url:'/technician/technician/getTechnicianInfo',
         url:'/technician/technician/profile',
         data
     });

+ 99 - 1
src/api/order.js

@@ -79,4 +79,102 @@ export function getStaffServiceTime(data) {
         url: '/api/order/v1/wx/getTechnicianAvailability',
         data
     });
-}
+}
+//郭
+
+// 查询订单
+export function queryOrder(data) {
+    return request({
+        method: 'post',
+        url: '/merchant/order/queryByDate',
+        data
+    });
+}
+// 订单详情
+export function orderDetail(data) {
+    return request({
+        method: 'post',
+        url: '/merchant/order/detail',
+        data
+    });
+}
+// 立即接单
+export function acceptOrder(data) {
+    return request({
+        method: 'post',
+        url: '/merchant/order/accept',
+        data
+    });
+}
+// 拒绝订单
+export function rejectOrder(data) {
+    return request({
+        method: 'post',
+        url: '/merchant/order/reject',
+        data
+    });
+}
+// 取消订单
+export function cancelOrder(data) {
+    return request({
+        method: 'post',
+        url: '/merchant/order/cancelAfterReceive',
+        data
+    });
+}
+// 我已到
+export function arriveSign(data) {
+    return request({
+        method: 'post',
+        url: '/merchant/order/arriveSign',
+        data
+    });
+}
+// 开始服务
+export function startService(data) {
+    return request({
+        method: 'post',
+        url: '/merchant/order/startService',
+        data
+    });
+}
+// 服务完成
+export function finishService(data) {
+    return request({
+        method: 'post',
+        url: '/merchant/order/finishService',
+        data
+    });
+}
+// 一键报警
+export function alarmOrder(data) {
+    return request({
+        method: 'post',
+        url: '/merchant/order/alarm',
+        data
+    });
+}
+
+// 取消订单原因
+export function cancelOrderReason(type) {
+    return request({
+        method: 'get',
+        url: `/order/after/sale/dict/${type}/reason`,
+    });
+}
+///merchant/order/startGoOut 我已出发/签到
+export function startGoOut(data) {
+    return request({
+        method: 'post',
+        url: '/merchant/order/startGoOut',
+        data
+    });
+}
+// 获取客户手机号
+export function getCustomerPhone(data) {
+    return request({
+        method: 'post',
+        url: '/merchant/order/getCustomerPhone',
+        data
+    });
+}

+ 68 - 0
src/api/workbench.js

@@ -78,3 +78,71 @@ export function saveFareSetting(data) {
 		}
     });
 }
+// 查询未申请列表
+export function getNotApplyList(data) {
+    return request({
+        method: 'post',
+        url: '/technician/technician/getNotApplyList',
+        data,
+		header: {
+		    'Authorization': `tf:${uni.getStorageSync('access-token')}`
+		}
+    });
+}
+// 开通新服务
+export function applyForService(data) {
+    return request({
+        method: 'post',
+        url: '/technician/technician/applyForService',
+        data,
+		header: {
+		    'Authorization': `tf:${uni.getStorageSync('access-token')}`
+		}
+    });
+}
+// 更新商户项目
+export function updateMaProject(data) {
+    return request({
+        method: 'post',
+        url: '/technician/technician/updateMaProject',
+        data,
+		header: {
+		    'Authorization': `tf:${uni.getStorageSync('access-token')}`
+		}
+    });
+}
+// 重新申请开通
+export function updateApply(data) {
+    return request({
+        method: 'post',
+        url: '/technician/technician/updateApply',
+        data,
+		header: {
+		    'Authorization': `tf:${uni.getStorageSync('access-token')}`
+		}
+    });
+}
+
+// 查询待接单列表
+export function getWaitList(data) {
+    return request({
+        method: 'post',
+        url: '/technician/technician/wait/list',
+        data,
+		header: {
+		    'Authorization': `tf:${uni.getStorageSync('access-token')}`
+		}
+    });
+}
+
+// 查询我的评分列表
+export function getCommentList(data) {
+    return request({
+        method: 'post',
+        url: '/order/comment/merchant/my/page',
+        data,
+		header: {
+		    'Authorization': `tf:${uni.getStorageSync('access-token')}`
+		}
+    });
+}

+ 7 - 3
src/components/cl-upload/cl-upload/cl-upload.vue

@@ -621,11 +621,13 @@ export default {
 			if (updataType === 3) {
 
 				// 限制音频最大上传数量
-				const AUDIO_REGEXP = /\.(mp3|wav|ogg|m4a)/i
+				const AUDIO_REGEXP = /\.(mp3|wav|wma|m4a)/i
+				
 				const audioList = await that.FileList.filter(item => {
 					const fileUrl = item?.url ?? item
-					return AUDIO_REGEXP.test(fileUrl)
+					return AUDIO_REGEXP.test(fileExtension)
 				})
+				console.log(audioList,'that.audioList')
 
 				if (that.maxAudio > 0 && audioList.length >= that.maxAudio) {
 					that.$emit('onAudioMax', that.maxAudio, audioList.length)
@@ -702,6 +704,7 @@ export default {
 
 			input.onchange = function (e) {
 				const file = e.target.files[0];
+				console.log(file,'file')
 				if (!file) return;
 
 				// 限制音频上传尺寸
@@ -722,7 +725,8 @@ export default {
 					path: URL.createObjectURL(file),
 					name: file.name,
 					size: file.size,
-					duration: 0
+					duration: 0,
+					type: file.type
 				};
 
 				// 使用 Audio 对象获取音频时长

+ 177 - 29
src/pages.json

@@ -66,6 +66,78 @@
 				}
 			}
 		},
+		{
+			"path": "pages/order/search",
+			"style": {
+				"navigationBarTitleText": "搜索",
+				"navigationBarBackgroundColor": "#2cb8d4",
+				"navigationBarTextStyle": "white",
+				"app-plus": {
+					"softinputNavBar": "none",
+					"titleNView": false
+				}
+			}
+		},
+		{
+			"path": "pages/order/moneyRecord",
+			"style": {
+				"navigationBarTitleText": "钱款去向记录",
+				"navigationBarBackgroundColor": "#2cb8d4",
+				"navigationBarTextStyle": "white",
+				"app-plus": {
+					"softinputNavBar": "none",
+					"titleNView": false
+				}
+			}
+		},
+		{
+			"path": "pages/order/moneyDetail",
+			"style": {
+				"navigationBarTitleText": "钱款详情",
+				"navigationBarBackgroundColor": "#2cb8d4",
+				"navigationBarTextStyle": "white",
+				"app-plus": {
+					"softinputNavBar": "none",
+					"titleNView": false
+				}
+			}
+		},
+		{
+			"path": "pages/order/cancelOrder",
+			"style": {
+				"navigationBarTitleText": "取消订单",
+				"navigationBarBackgroundColor": "#2cb8d4",
+				"navigationBarTextStyle": "white",
+				"app-plus": {
+					"softinputNavBar": "none",
+					"titleNView": false
+				}
+			}
+		},
+		{
+			"path": "pages/order/cancelOrder",
+			"style": {
+				"navigationBarTitleText": "取消订单",
+				"navigationBarBackgroundColor": "#2cb8d4",
+				"navigationBarTextStyle": "white",
+				"app-plus": {
+					"softinputNavBar": "none",
+					"titleNView": false
+				}
+			}
+		},
+		{
+			"path": "pages/order/businessFormal",
+			"style": {
+				"navigationBarTitleText": "职业正装",
+				"navigationBarBackgroundColor": "#2cb8d4",
+				"navigationBarTextStyle": "white",
+				"app-plus": {
+					"softinputNavBar": "none",
+					"titleNView": false
+				}
+			}
+		},
 		{
 			"path": "pages/my/withdraw",
 			"style": {
@@ -460,8 +532,24 @@
 					"path": "rating/index",
 					"style": {
 						"navigationBarTitleText": "我的评分",
-						"navigationBarBackgroundColor": "#ffffff",
-						"navigationBarTextStyle": "black"
+						"navigationBarBackgroundColor": "#2cb8d4",
+						"navigationBarTextStyle": "white",
+						"app-plus": {
+							"softinputNavBar": "none",
+							"titleNView": false
+						}
+				
+					}
+				},{
+					"path": "onlineHours/index",
+					"style": {
+						"navigationBarTitleText": "在线时长",
+						"navigationBarBackgroundColor": "#2cb8d4",
+						"navigationBarTextStyle": "white",
+						"app-plus": {
+							"softinputNavBar": "none",
+							"titleNView": false
+						}
 					}
 				},
 				{
@@ -469,7 +557,11 @@
 					"style": {
 						"navigationBarTitleText": "银行卡",
 						"navigationBarBackgroundColor": "#2cb8d4",
-						"navigationBarTextStyle": "white"
+						"navigationBarTextStyle": "white",
+						"app-plus": {
+							"softinputNavBar": "none",
+							"titleNView": false
+						}
 					}
 				},
 				{
@@ -477,7 +569,11 @@
 					"style": {
 						"navigationBarTitleText": "添加银行卡",
 						"navigationBarBackgroundColor": "#2cb8d4",
-						"navigationBarTextStyle": "white"
+						"navigationBarTextStyle": "white",
+						"app-plus": {
+							"softinputNavBar": "none",
+							"titleNView": false
+						}
 					}
 				},
 				{
@@ -485,103 +581,155 @@
 					"style": {
 						"navigationBarTitleText": "银行卡详情",
 						"navigationBarBackgroundColor": "#2cb8d4",
-						"navigationBarTextStyle": "white"
+						"navigationBarTextStyle": "white",
+						"app-plus": {
+							"softinputNavBar": "none",
+							"titleNView": false
+						}
 					}
 				},
 				{
 					"path": "withdraw/apply",
 					"style": {
 						"navigationBarTitleText": "申请提现",
-						"navigationBarBackgroundColor": "#ffffff",
-						"navigationBarTextStyle": "black"
+						"navigationBarBackgroundColor": "#2cb8d4",
+						"navigationBarTextStyle": "white",
+						"app-plus": {
+							"softinputNavBar": "none",
+							"titleNView": false
+						}
 					}
 				},
 				{
 					"path": "withdraw/record",
 					"style": {
 						"navigationBarTitleText": "提现记录",
-						"navigationBarBackgroundColor": "#ffffff",
-						"navigationBarTextStyle": "black"
+						"navigationBarBackgroundColor": "#2cb8d4",
+						"navigationBarTextStyle": "white",
+						"app-plus": {
+							"softinputNavBar": "none",
+							"titleNView": false
+						}
 					}
 				},
 				{
 					"path": "withdraw/detail",
 					"style": {
 						"navigationBarTitleText": "提现详情",
-						"navigationBarBackgroundColor": "#ffffff",
-						"navigationBarTextStyle": "black"
+						"navigationBarBackgroundColor": "#2cb8d4",
+						"navigationBarTextStyle": "white",
+						"app-plus": {
+							"softinputNavBar": "none",
+							"titleNView": false
+						}
 					}
 				},
 				{
 					"path": "income/index",
 					"style": {
 						"navigationBarTitleText": "我的收入",
-						"navigationBarBackgroundColor": "#ffffff",
-						"navigationBarTextStyle": "black"
+						"navigationBarBackgroundColor": "#2cb8d4",
+						"navigationBarTextStyle": "white",
+						"app-plus": {
+							"softinputNavBar": "none",
+							"titleNView": false
+						}
 					}
 				},
 				{
 					"path": "skill/index",
 					"style": {
 						"navigationBarTitleText": "技能管理",
-						"navigationBarBackgroundColor": "#ffffff",
-						"navigationBarTextStyle": "black"
+						"navigationBarBackgroundColor": "#2cb8d4",
+						"navigationBarTextStyle": "white",
+						"app-plus": {
+							"softinputNavBar": "none",
+							"titleNView": false
+						}
 					}
 				},
 				{
 					"path": "skill/add",
 					"style": {
 						"navigationBarTitleText": "开通新服务",
-						"navigationBarBackgroundColor": "#ffffff",
-						"navigationBarTextStyle": "black"
+						"navigationBarBackgroundColor": "#2cb8d4",
+						"navigationBarTextStyle": "white",
+						"app-plus": {
+							"softinputNavBar": "none",
+							"titleNView": false
+						}
 					}
 				},
 				{
 					"path": "skill/edit",
 					"style": {
 						"navigationBarTitleText": "编辑项目",
-						"navigationBarBackgroundColor": "#ffffff",
-						"navigationBarTextStyle": "black"
+						"navigationBarBackgroundColor": "#2cb8d4",
+						"navigationBarTextStyle": "white",
+						"app-plus": {
+							"softinputNavBar": "none",
+							"titleNView": false
+						}
 					}
 				},
 				{
 					"path": "fare/index",
 					"style": {
 						"navigationBarTitleText": "免车费",
-						"navigationBarBackgroundColor": "#ffffff",
-						"navigationBarTextStyle": "black"
+						"navigationBarBackgroundColor": "#2cb8d4",
+						"navigationBarTextStyle": "white",
+						"app-plus": {
+							"softinputNavBar": "none",
+							"titleNView": false
+						}
 					}
 				},
 				{
 					"path": "contract/index",
 					"style": {
 						"navigationBarTitleText": "我的合同",
-						"navigationBarBackgroundColor": "#ffffff",
-						"navigationBarTextStyle": "black"
+						"navigationBarBackgroundColor": "#2cb8d4",
+						"navigationBarTextStyle": "white",
+						"app-plus": {
+							"softinputNavBar": "none",
+							"titleNView": false
+						}
 					}
 				},
 				{
 					"path": "contract/detail",
 					"style": {
 						"navigationBarTitleText": "合同查看",
-						"navigationBarBackgroundColor": "#ffffff",
-						"navigationBarTextStyle": "black"
+						"navigationBarBackgroundColor": "#2cb8d4",
+						"navigationBarTextStyle": "white",
+						"app-plus": {
+							"softinputNavBar": "none",
+							"titleNView": false
+						}
 					}
 				},
 				{
 					"path": "city/index",
 					"style": {
 						"navigationBarTitleText": "城市管理",
-						"navigationBarBackgroundColor": "#ffffff",
-						"navigationBarTextStyle": "black"
+						"navigationBarBackgroundColor": "#2cb8d4",
+						"navigationBarTextStyle": "white",
+						"app-plus": {
+							"softinputNavBar": "none",
+							"titleNView": false
+						}
 					}
 				},
 				{
 					"path": "city/apply",
 					"style": {
 						"navigationBarTitleText": "城市管理",
-						"navigationBarBackgroundColor": "#ffffff",
-						"navigationBarTextStyle": "black"
+						"navigationBarBackgroundColor": "#2cb8d4",
+						"navigationBarTextStyle": "white",
+						"app-plus": {
+							"softinputNavBar": "none",
+							"titleNView": false
+						}
 					}
 				}
 			]

Разница между файлами не показана из-за своего большого размера
+ 349 - 239
src/pages/index/index.vue


+ 106 - 156
src/pages/join/applyJoin.vue

@@ -15,12 +15,13 @@
                 <view style="height: 1rpx;background-color: #e5e5e5c2;width: 100%;"></view>
                 <view class="input-box">
 
-                    <u-input v-model="baseInfo.nickName" border="none" placeholder="昵称" class="input-item"
+                    <u-input v-model="baseInfo.nickName.value" border="none" placeholder="昵称" class="input-item"
                         placeholder-style="font-weight: 400;font-size: 30rpx;color: #C9CDD4;text-align: right;">
                         <template slot="prefix">
                             <view class="label">
                                 <text>昵称</text>
-                                <text v-if="baseInfo.teNickNameAuditStatus==0 || baseInfo.teNickNameAuditStatus==2" :class="baseInfo.teNickNameAuditStatus==0?'status1':'status2'">{{ baseInfo.teNickNameAuditStatus==0?'审核中':'审核驳回' }}</text>
+                                <text v-if="baseInfo.nickName.auditStatus == 0 || baseInfo.nickName.auditStatus == 2"
+                                    :class="baseInfo.nickName.auditStatus == 0 ? 'status1' : 'status2'">{{baseInfo.nickName.auditStatusText}}</text>
                             </view>
                         </template>
                     </u-input>
@@ -30,18 +31,20 @@
                     :rightText="baseInfo.name ? baseInfo.name : '昵称'" style="color: red!important;" /> -->
 
                 <uni-list-item title="入驻城市" :rightText="baseInfo.city" />
-                <uni-list-item showArrow title="简介" :class="{ 'hasText': baseInfo.introduceYourself }" clickable
-                    @click="introduceYourselfEdit(baseInfo.introduceYourself,baseInfo.teNickNameAuditStatus)"
-                    :rightText="baseInfo.introduceYourself ? baseInfo.introduceYourself : '简单的介绍您自己~'" >
+                <uni-list-item v-if="baseInfo.brief" showArrow title="简介" :class="{ 'hasText': baseInfo.brief }" clickable
+                    @click="introduceYourselfEdit(baseInfo.brief.value, baseInfo.brief.auditStatus)"
+                    :rightText="baseInfo.brief ? baseInfo.brief.value : '简单的介绍您自己~'">
                     <!-- 自定义 body -->
                     <template v-slot:body>
                         <view class="slot-box slot-text">
                             简介
-                            <view v-if="baseInfo.teNickNameAuditStatus==0 || baseInfo.teNickNameAuditStatus==2" :class="baseInfo.teNickNameAuditStatus==0?'status1':'status2'">{{ baseInfo.teNickNameAuditStatus==0?'审核中':'审核驳回' }}</view>
-                    
+                            <view v-if="baseInfo.brief.auditStatus == 0 || baseInfo.brief.auditStatus == 2"
+                                :class="baseInfo.brief.auditStatus == 0 ? 'status1' : 'status2'">{{
+                                    baseInfo.brief.auditStatusText }}</view>
+
                         </view>
                     </template>
-                           
+
                 </uni-list-item>
             </uni-list>
         </view>
@@ -62,9 +65,9 @@
                         <view class="slot-box slot-text">
                             形象照
                             <view
-                                :class="baseInfo.portraitPhotoList.some(item => item.auditStatus == 0) ? 'status1' : 'status2'"
-                                v-if="baseInfo.portraitPhotoList.every(item => item.auditStatus != 1)">{{
-                                    baseInfo.portraitPhotoList.some(item => item.auditStatus == 0) ? '审核中' : '审核驳回'}}
+                                :class="baseInfo.portraitPhotoListStatus == 0 ? 'status1' : 'status2'"
+                                v-if="baseInfo.portraitPhotoListStatus == 0 || baseInfo.portraitPhotoListStatus == 2">{{
+                                    baseInfo.portraitPhotoListStatus == 0 ? '审核中' : '审核驳回'}}
                             </view>
                         </view>
                     </template>
@@ -77,27 +80,27 @@
                 <uni-list-item showArrow title="生活照"
                     :rightText="baseInfo.cImgList.length > 0 ? baseInfo.cImgList.length + '项' : '去上传'"
                     :class="{ 'hasText': baseInfo.cImgList.length > 0 }" clickable
-                    @click="pictureUpLoad('cImgList', '生活照', 9)">
+                    @click="pictureUpLoad('cImgList', '生活照', 9,baseInfo.cImgListStatus)">
                     <template v-slot:body>
                         <view class="slot-box slot-text">
                             生活照
-                            <view :class="baseInfo.cImgList.some(item => item.auditStatus == 0) ? 'status1' : 'status2'"
-                                v-if="baseInfo.cImgList.every(item => item.auditStatus != 1)">{{
-                                    baseInfo.cImgList.some(item => item.auditStatus == 0) ? '审核中' : '审核驳回'}}</view>
+                            <view :class="baseInfo.cImgListStatus == 0 ? 'status1' : 'status2'"
+                                v-if="baseInfo.cImgListStatus == 0 || baseInfo.cImgListStatus == 2">{{
+                                    baseInfo.cImgListStatus == 0 ? '审核中' : '审核驳回'}}</view>
                         </view>
                     </template>
 
                 </uni-list-item>
                 <uni-list-item showArrow title="宣传视频" :class="{ 'hasText': baseInfo.promotionalVideo.length > 0 }"
                     :rightText="baseInfo.promotionalVideo.length > 0 ? baseInfo.promotionalVideo.length + '项' : '去上传'"
-                    clickable @click="pictureUpLoad('promotionalVideo', '宣传视频')">
+                    clickable @click="pictureUpLoad('promotionalVideo', '宣传视频',1,baseInfo.promotionalVideoStatus)">
                     <template v-slot:body>
                         <view class="slot-box slot-text">
                             宣传视频
                             <view
-                                :class="baseInfo.promotionalVideo.some(item => item.auditStatus == 0) ? 'status1' : 'status2'"
-                                v-if="baseInfo.promotionalVideo.every(item => item.auditStatus != 1)">{{
-                                    baseInfo.promotionalVideo.some(item => item.auditStatus == 0) ? '审核中' : '审核驳回'}}</view>
+                                :class="baseInfo.promotionalVideoStatus == 0 ? 'status1' : 'status2'"
+                                v-if="baseInfo.promotionalVideoStatus == 0 || baseInfo.promotionalVideoStatus == 2">{{
+                                    baseInfo.promotionalVideoStatus == 0 ? '审核中' : '审核驳回'}}</view>
                         </view>
                     </template>
 
@@ -105,13 +108,14 @@
 
                 <uni-list-item showArrow title="身份证"
                     :class="{ 'hasText': (baseInfo.idCard[0].length > 0 || baseInfo.idCard[1].length > 0 || baseInfo.idCard[2].length) > 0 }"
-                    :rightText="checkLength(baseInfo.idCard)" clickable @click="idCardEditFun('idCard')">
+                    :rightText="checkLength(baseInfo.idCard)" clickable @click="idCardEditFun('idCard',baseInfo.idCardStatus)">
                     <template v-slot:body>
                         <view class="slot-box slot-text">
                             身份证
-                            <view :class="(baseInfo.idCard || []).some(subArr => (subArr || []).some(item => item.auditStatus == 0)) ? 'status1' : 'status2'" 
-                            v-if="(baseInfo.idCard || []).every(subArr =>(subArr || []).every(item => item.auditStatus != 1))">
-                            {{(baseInfo.idCard || []).some(subArr =>(subArr || []).some(item => item.auditStatus == 0)) ? '审核中' : '审核驳回'}}</view>
+                            <view
+                                :class="baseInfo.idCardStatus == 0 ? 'status1' : 'status2'"
+                                v-if="baseInfo.idCardStatus == 0 || baseInfo.idCardStatus == 2">
+                                {{baseInfo.idCardStatus == 0  ? '审核中' : '审核驳回'}}</view>
                         </view>
                     </template>
 
@@ -120,14 +124,14 @@
 
                 <uni-list-item showArrow title="健康证" :class="{ 'hasText': baseInfo.healthCertificate.length > 0 }"
                     :rightText="baseInfo.healthCertificate.length > 0 ? baseInfo.healthCertificate.length + '项' : '去上传'"
-                    clickable @click="pictureUpLoad('healthCertificate', '健康证', 3)">
+                    clickable @click="pictureUpLoad('healthCertificate', '健康证', 9,baseInfo.healthCertificateStatus)">
                     <template v-slot:body>
                         <view class="slot-box slot-text">
                             健康证
                             <view
-                                :class="baseInfo.healthCertificate.some(item => item.auditStatus == 0) ? 'status1' : 'status2'"
-                                v-if="baseInfo.healthCertificate.every(item => item.auditStatus != 1)">{{
-                                    baseInfo.healthCertificate.some(item => item.auditStatus == 0) ? '审核中' : '审核驳回'}}
+                                :class="baseInfo.healthCertificateStatus == 0 ? 'status1' : 'status2'"
+                                v-if="baseInfo.healthCertificateStatus == 0 || baseInfo.healthCertificateStatus == 2">{{
+                                    baseInfo.healthCertificateStatus == 0 ? '审核中' : '审核驳回'}}
                             </view>
                         </view>
                     </template>
@@ -135,27 +139,27 @@
                 </uni-list-item>
                 <uni-list-item showArrow title="从业资格证" :class="{ 'hasText': baseInfo.certification.length > 0 }"
                     :rightText="baseInfo.certification.length > 0 ? baseInfo.certification.length + '项' : '去上传'"
-                    clickable @click="pictureUpLoad('certification', '从业资格证', 3)">
+                    clickable @click="pictureUpLoad('certification', '从业资格证', 3,baseInfo.certificationStatus)">
                     <template v-slot:body>
                         <view class="slot-box slot-text">
                             从业资格证
                             <view
-                                :class="baseInfo.certification.some(item => item.auditStatus == 0) ? 'status1' : 'status2'"
-                                v-if="baseInfo.certification.every(item => item.auditStatus != 1)">{{
-                                    baseInfo.certification.some(item => item.auditStatus == 0) ? '审核中' : '审核驳回'}}</view>
+                                :class="baseInfo.certificationStatus == 0 ? 'status1' : 'status2'"
+                                v-if="baseInfo.certificationStatus == 0 || baseInfo.certificationStatus == 2">{{ 
+                                    baseInfo.certificationStatus == 0 ? '审核中' : '审核驳回'}}</view>
                         </view>
                     </template>
 
                 </uni-list-item>
                 <uni-list-item showArrow title="无犯罪证明" :class="{ 'hasText': baseInfo.noCrime.length > 0 }"
                     :rightText="baseInfo.noCrime.length > 0 ? baseInfo.noCrime.length + '项' : '去上传'" clickable
-                    @click="pictureUpLoad('noCrime', '无犯罪证明', 9)">
+                    @click="pictureUpLoad('noCrime', '无犯罪证明', 9,baseInfo.noCrimeStatus)">
                     <template v-slot:body>
                         <view class="slot-box slot-text">
                             无犯罪证明
-                            <view :class="baseInfo.noCrime.some(item => item.auditStatus == 0) ? 'status1' : 'status2'"
-                                v-if="baseInfo.noCrime.every(item => item.auditStatus != 1)">{{
-                                    baseInfo.noCrime.some(item => item.auditStatus == 0) ? '审核中' : '审核驳回'}}</view>
+                            <view :class="baseInfo.noCrimeStatus == 0 ? 'status1' : 'status2'"
+                                v-if="baseInfo.noCrimeStatus == 0 || baseInfo.noCrimeStatus == 2">{{
+                                    baseInfo.noCrimeStatus == 0 ? '审核中' : '审核驳回'}}</view>
                         </view>
                     </template>
 
@@ -164,13 +168,14 @@
                 <uni-list-item showArrow title="承诺文件"
                     :class="{ 'hasText': (baseInfo.commitDocument[0].length > 0 || baseInfo.commitDocument[1].length > 0 || baseInfo.commitDocument[2].length) > 0 }"
                     :rightText="checkLength(baseInfo.commitDocument)" clickable
-                    @click="commitDocmentEditFun('commitDocument')">
+                    @click="commitDocmentEditFun('commitDocument',baseInfo.commitDocumentStatus)">
                     <template v-slot:body>
                         <view class="slot-box slot-text">
                             承诺文件
-                            <view :class="(baseInfo.commitDocument || []).some(subArr => (subArr || []).some(item => item.auditStatus == 0)) ? 'status1' : 'status2'" 
-                            v-if="(baseInfo.commitDocument || []).every(subArr =>(subArr || []).every(item => item.auditStatus != 1))">
-                            {{(baseInfo.commitDocument || []).some(subArr =>(subArr || []).some(item => item.auditStatus == 0)) ? '审核中' : '审核驳回'}}</view>
+                            <view
+                                :class="baseInfo.commitDocumentStatus == 0 ? 'status1' : 'status2'"
+                                v-if="baseInfo.commitDocumentStatus == 0 || baseInfo.commitDocumentStatus == 2">
+                                {{baseInfo.commitDocumentStatus == 0 ? '审核中' : '审核驳回'}}</view>
                         </view>
                     </template>
 
@@ -183,7 +188,7 @@
 
 
         <!-- 提交按钮 -->
-        <view class="submit-box">
+        <view class="submit-box" v-if="baseInfo.auditStatus != 1">
             <u-button @click="submitForm">提交</u-button>
         </view>
 
@@ -279,126 +284,68 @@ export default {
         async checkMerchantStatus() {
             const openid = uni.getStorageSync('wx_copenid')
             const merchantInfo = await this.$utils.checkMerchantStatus(openid)
+            console.log(merchantInfo)
+
 
             if (!merchantInfo) return
             this.ShopInfo = merchantInfo
-            this.baseInfo.id = this.ShopInfo.merchant.id
-            this.baseInfo.name = merchantInfo.merchant.teName
-            this.baseInfo.gender = merchantInfo.merchant.teSex == 0 ? '女' : '男'
-            this.baseInfo.phone = merchantInfo.merchant.tePhone
-            this.baseInfo.nickName = merchantInfo.merchant.teNickName
-            this.baseInfo.city = merchantInfo.merchant.provinceName + '/' + merchantInfo.merchant.cityName + ' ' + merchantInfo.merchant.operationCenterName
-            this.baseInfo.introduceYourself = merchantInfo.merchant.teBrief
-            console.log(this.baseInfo, 'baseInfo.commitDocument')
+            this.baseInfo.id = this.ShopInfo.merchantId
+            this.baseInfo.name = merchantInfo.name
+            this.baseInfo.gender = merchantInfo.teSex == 0 ? '女' : '男'
+            this.baseInfo.phone = merchantInfo.phone
+            this.baseInfo.nickName = merchantInfo.nickName
+            this.baseInfo.city = merchantInfo.provinceName + '/' + merchantInfo.cityName + ' ' + merchantInfo.operationCenterName
+            this.baseInfo.brief = merchantInfo.brief
             // 文件类型(1:形象照 2:生活照 3:宣传视频 4-身份证正面 5-身份证反面 6-手持身份证 
             // 7-健康证 8-从业资格证,9-无犯罪证明,10-承诺书,11-承诺录音,12-承诺录像,13-其他 )
-            merchantInfo.merchantAuditFile.map(m => {
+            merchantInfo.fileGroups.map(m => {
+                let key = 'portraitPhotoList'
                 if (m.fileType == 1) {
-                    this.baseInfo.portraitPhotoList = [{
-                        size: m.fileSize * 1024,
-                        contentType: m.contentType,
-                        url: m.fileUrl,
-                        status: 'success',
-                        auditStatus: m.auditStatus,
-                    }]
-                }
-                if (m.fileType == 2) {
-                    this.baseInfo.cImgList.push({
-                        size: m.fileSize * 1024,
-                        contentType: m.contentType,
-                        url: m.fileUrl,
-                        status: 'success',
-                        auditStatus: m.auditStatus,
-                    })
-                }
-                if (m.fileType == 3) {
-                    this.baseInfo.promotionalVideo = [{
-                        size: m.fileSize * 1024,
-                        type: m.contentType,
-                        url: m.fileUrl,
-                        status: 'success',
-                        auditStatus: m.auditStatus,
-                    }]
-                }
-                if (m.fileType == 4) {
-                    this.baseInfo.idCard[0] = [{
-                        size: m.fileSize * 1024,
-                        contentType: m.contentType,
-                        url: m.fileUrl,
-                        status: 'success',
-                        auditStatus: m.auditStatus,
-                    }]
-                }
-                if (m.fileType == 5) {
-                    this.baseInfo.idCard[1] = [{
-                        size: m.fileSize * 1024,
-                        contentType: m.contentType,
-                        url: m.fileUrl,
-                        status: 'success',
-                        auditStatus: m.auditStatus,
-                    }]
+                    key = 'portraitPhotoList'
+                } else if (m.fileType == 2) {
+                    key = 'cImgList'
+                } else if (m.fileType == 3) {
+                    key = 'promotionalVideo'
+                } else if (m.fileType == 4 || m.fileType == 5 || m.fileType == 6) {
+                    key = 'idCard'
+                } else if (m.fileType == 7) {
+                    key = 'healthCertificate'
+                } else if (m.fileType == 8) {
+                    key = 'certification'
+                } else if (m.fileType == 9) {
+                    key = 'noCrime'
+                } else if (m.fileType == 10 || m.fileType == 11 || m.fileType == 12) {
+                    key = 'commitDocument'
                 }
-                if (m.fileType == 6) {
-                    this.baseInfo.idCard[2] = [{
-                        size: m.fileSize * 1024,
-                        contentType: m.contentType,
-                        url: m.fileUrl,
+                this.baseInfo[key + 'Status'] = m.auditStatus
+                if (m.fileType == 4 || m.fileType == 5 || m.fileType == 6) {
+                    this.baseInfo[key][m.fileType == 4 ? '0' : m.fileType == 5 ? '1' : '2'] = m.officialFiles.map(item => ({
+                        size: item.fileSize * 1024,
+                        contentType: item.contentType,
+                        url: item.fileUrl,
                         status: 'success',
-                        auditStatus: m.auditStatus,
-                    }]
-                }
-                if (m.fileType == 7) {
-                    this.baseInfo.healthCertificate.push({
-                        size: m.fileSize * 1024,
-                        contentType: m.contentType,
-                        url: m.fileUrl,
+                        auditStatus: item.auditStatus,
+                    }))
+                } else if (m.fileType == 10 || m.fileType == 11 || m.fileType == 12) {
+                    this.baseInfo[key][m.fileType == 10 ? '0' : m.fileType == 11 ? '1' : '2'] = m.officialFiles.map(item => ({
+                        size: item.fileSize * 1024,
+                        contentType: item.contentType,
+                        url: item.fileUrl,
                         status: 'success',
-                        auditStatus: m.auditStatus,
-                    })
-                }
-                if (m.fileType == 8) {
-                    this.baseInfo.certification.push({
-                        size: m.fileSize * 1024,
-                        contentType: m.contentType,
-                        url: m.fileUrl,
-                        status: 'success',
-                        auditStatus: m.auditStatus,
-                    })
-                }
-                if (m.fileType == 9) {
-                    this.baseInfo.noCrime.push({
-                        size: m.fileSize * 1024,
-                        contentType: m.contentType,
-                        url: m.fileUrl,
-                        status: 'success',
-                        auditStatus: m.auditStatus,
-                    })
-                }
-                if (m.fileType == 10) {
-                    this.baseInfo.commitDocument[0] = [{
-                        size: m.fileSize * 1024,
-                        contentType: m.contentType,
-                        url: m.fileUrl,
+                        auditStatus: item.auditStatus,
+                    }))
+
+                } else {
+                    this.baseInfo[key] = m.officialFiles.map(item => ({
+                        size: item.fileSize * 1024,
+                        contentType: item.contentType,
+                        url: item.fileUrl,
                         status: 'success',
-                        auditStatus: m.auditStatus,
-                    }]
-                }
-                if (m.fileType == 11) {
-                    this.baseInfo.commitDocument[1] = [{
-                        size: m.fileSize * 1024,
-                        type: m.contentType,
-                        url: m.fileUrl,
-                        auditStatus: m.auditStatus,
-                    }]
-                }
-                if (m.fileType == 12) {
-                    this.baseInfo.commitDocument[2] = [{
-                        size: m.fileSize * 1024,
-                        type: m.contentType,
-                        url: m.fileUrl,
-                        auditStatus: m.auditStatus,
-                    }]
+                        auditStatus: item.auditStatus,
+                    }))
+
                 }
+
             })
 
             setTimeout(() => {
@@ -407,32 +354,35 @@ export default {
             }, 200);
 
         },
-        commitDocmentEditFun(value) {
+        commitDocmentEditFun(value,auditStatus) {
             let str = uni.$u.queryParams({
                 fieldName: value,
                 fieldVal: JSON.stringify(this.baseInfo[value]),
+                auditStatus: auditStatus,
             })
             uni.navigateTo({ url: `/pages/join/commitDocumentEdit${str}` })
         },
-        idCardEditFun(value) {
+        idCardEditFun(value,auditStatus) {
             let str = uni.$u.queryParams({
                 fieldName: value,
                 fieldVal: JSON.stringify(this.baseInfo[value]),
+                auditStatus: auditStatus,
             })
             uni.navigateTo({ url: `/pages/join/idCardEdit${str}` })
         },
-        pictureUpLoad(value, title, maxlength) {
+        pictureUpLoad(value, title, maxlength,auditStatus) {
             let str = uni.$u.queryParams({
                 fieldName: value,
                 fieldVal: JSON.stringify(this.baseInfo[value]),
                 title: title,
                 maxlength: maxlength,
+                auditStatus: auditStatus,
             })
             uni.navigateTo({ url: `/pages/join/lifePhotosEdit${str}` })
 
         },
         //简介
-        introduceYourselfEdit(introduceYourself,teNickNameAuditStatus) {
+        introduceYourselfEdit(introduceYourself, teNickNameAuditStatus) {
             uni.navigateTo({ url: '/pages/join/introduceYourselfEdit?introduceYourself=' + this.baseInfo.introduceYourself + '&teNickNameAuditStatus=' + teNickNameAuditStatus })
         },
         portraitPhotoFun() {
@@ -564,7 +514,7 @@ export default {
                         {
                             fileName: '宣传视频',
                             fileUrl: item.url,
-                            contentType: item.type,
+                            contentType: item.contentType,
                             fileSize: Number((item.size / 1024).toFixed(2)),
                         }
                     ]
@@ -679,7 +629,7 @@ export default {
                             {
                                 fileName: '承诺录音',
                                 fileUrl: this.baseInfo.commitDocument[1][0].url,
-                                contentType: this.baseInfo.commitDocument[1][0].type,
+                                contentType: this.baseInfo.commitDocument[1][0].contentType,
                                 fileSize: Number((this.baseInfo.commitDocument[1][0].size / 1024).toFixed(2)),
                             }
                         ]
@@ -689,7 +639,7 @@ export default {
                             {
                                 fileName: '承诺录像',
                                 fileUrl: this.baseInfo.commitDocument[2][0].url,
-                                contentType: this.baseInfo.commitDocument[2][0].type,
+                                contentType: this.baseInfo.commitDocument[2][0].contentType,
                                 fileSize: Number((this.baseInfo.commitDocument[2][0].size / 1024).toFixed(2)),
                             }
                         ]

+ 25 - 30
src/pages/join/commitDocumentEdit.vue

@@ -50,7 +50,7 @@
                         </view>
                         <audio :src="formData.audioUrl" class="audio-container" controls></audio>
                     </view>
-                    <clUpload v-else v-model="fileList1" :action="uploadApi" :headers="headers" :count="maxCount"
+                    <clUpload v-else :fileList="recording" :action="uploadApi" :headers="headers" :count="maxCount"
                         :listStyle="{
                             columnGap: '20rpx',
                             rowGap: '20rpx',
@@ -70,20 +70,6 @@
                     </clUpload>
                 </view>
 
-
-                <!-- <Upload :maxCount="1" @fileList="onUpload($event, 'recording')" :fileList="recording">
-                    <view class="upload-block" slot="content">
-                        <view class="icon-bg">
-                            <image src="/static/login/cameraIcon.png" mode="widthFix"
-                                style="width: 52rpx;height: 52rpx;">
-                            </image>
-                            <view style="font-weight: 400;font-size: 26rpx;color: #C9CDD4;margin-top: -13rpx;">上传</view>
-
-                        </view>
-
-                    </view>
-                </Upload> -->
-
             </view>
             <view class="content">
                 <view class="title">承诺录像</view>
@@ -101,7 +87,7 @@
 
                         <video ref="myVideo" :src="formData.videoUrl" class="video-container" controls></video>
                     </view>
-                    <clUpload v-else v-model="fileList" :action="uploadApi" :headers="headers" :count="maxCount"
+                    <clUpload v-else :fileList="videoRecording" :action="uploadApi" :headers="headers" :count="maxCount"
                         :listStyle="{
                             columnGap: '20rpx',
                             rowGap: '20rpx',
@@ -122,7 +108,7 @@
                 </view>
             </view>
 
-            <view class="footer-bar" v-if="auditStatus != 1">
+            <view class="footer-bar" v-if="auditStatus != 0">
                 <u-button :customStyle="{
                     padding: '24rpx 48rpx',
                     color: '#fff',
@@ -172,6 +158,7 @@ export default {
                 videoUrl: '',
                 videoCoverUrl: '',
                 imageUrls: [],
+                audioUrl:''
             },
             mediaType: 'all', // 默认为图片模式,上传第一个文件后确定类型
             uploadApi: baseUrl + '/common/upload', // 默认使用图片上传接口
@@ -188,20 +175,22 @@ export default {
     },
 
     onLoad(query) {
-        console.log(query)
+        console.log(query,'query')
         if (query.fieldName) this.fieldName = query.fieldName
         if (query.fieldVal) {
             let fieldVal = JSON.parse(query.fieldVal)
             this.commitment = fieldVal[0] ? fieldVal[0] : []
             this.recording = fieldVal[1] ? fieldVal[1] : []
+            if(this.recording.length){
+                this.formData.audioUrl = this.recording[0].url
+            }
             this.videoRecording = fieldVal[2] ? fieldVal[2] : []
             if (this.videoRecording.length > 0) {
                 this.formData.videoUrl = this.videoRecording[0].url
                 this.formData.videoCoverUrl = this.videoRecording[0].coverUrl
             }
-            let fileList = fieldVal.flat()
-            this.auditStatus = fileList.find(item => item.auditStatus == 0 || item.auditStatus == 2)?.auditStatus || 1
-
+            if (query.auditStatus) this.auditStatus = Number(query.auditStatus)       
+           
         }
     },
     onReady() {
@@ -233,14 +222,17 @@ export default {
                     this.formData.videoCoverUrl = baseUrl + reslut.coverUrl
                     this.videoRecording = [{
                         url: baseUrl + reslut.url,
-                        type: tempFile.tempFile.type,
+                        contentType: tempFile.tempFile.type,
                         size: tempFile.size,
                         coverUrl: baseUrl + reslut.coverUrl,
                     }]
                 } else if (isAudio) {
                     this.formData.audioUrl = baseUrl + reslut.url
-                    this.fileList1.push(baseUrl + reslut.url)
-
+                    this.recording = [{
+                        url: baseUrl + reslut.url,
+                        contentType: tempFile.type,
+                        size: tempFile.size,
+                    }]
                 } else {
                     this.fileList.push(baseUrl + reslut.url)
                 }
@@ -274,6 +266,7 @@ export default {
                     if (res.confirm) {
                         this.formData.videoUrl = ''
                         this.formData.videoCoverUrl = ''
+                        this.videoRecording = []
                         // 重置媒体类型
                         this.mediaType = 'all'
                     }
@@ -286,10 +279,12 @@ export default {
                 content: '是否要删除此音频',
                 success: res => {
                     if (res.confirm) {
+                        this.recording = []
                         this.formData.audioUrl = ''
-                        this.fileList1 = []
+                        this.$set(this.formData, 'audioUrl', '')
                         // 重置媒体类型
                         this.mediaType = 'all'
+                        console.log(this.formData,'this.formData')
                     }
                 },
             })
@@ -298,7 +293,6 @@ export default {
         // upload事件
         onUpload(e, t) {
             this[t] = e;
-            console.log(this[t])
         },
         goBack() {
             uni.navigateBack()
@@ -319,12 +313,13 @@ export default {
 </script>
 
 <style scoped lang="scss">
-.audio-container {
+::v-deep .audio-container {
     width: 100%;
-    .uni-audio-default{
-        min-width: none;
-    }
+    
 }
+::v-deep .uni-audio-default{
+        min-width: 340rpx!important;
+    }
 
 .commitDocument {
     height: 100vh;

+ 2 - 3
src/pages/join/idCardEdit.vue

@@ -132,7 +132,7 @@
                 </view>
             </Upload> -->
 
-            <view class="footer-bar" v-if="auditStatus != 1 ">
+            <view class="footer-bar" v-if="auditStatus != 0 ">
                 <u-button :customStyle="{
                     padding: '24rpx 48rpx',
                     color: '#fff',
@@ -171,9 +171,8 @@ export default {
             this.idCardFront = fieldVal[0] ? fieldVal[0] : []
             this.idCardBack = fieldVal[1] ? fieldVal[1]: []
             this.idCardHand = fieldVal[2] ? fieldVal[2] : []
-            let fileList=fieldVal.flat()
-            this.auditStatus = fileList.find(item => item.auditStatus == 0 || item.auditStatus == 2)?.auditStatus || 2
         }
+        if (query.auditStatus) this.auditStatus = Number(query.auditStatus)
         
     },
     onReady() {

+ 2 - 2
src/pages/join/introduceYourselfEdit.vue

@@ -22,7 +22,7 @@
             <u--textarea placeholderClass="textarea-placeholder" autoHeight v-model="value" placeholder="简单的介绍您自己~"
                 class="textareaDef"></u--textarea>
         </view>
-        <view class="footer-bar" v-if="auditStatus != 1 ">
+        <view class="footer-bar" v-if="auditStatus != 0 ">
             <u-button :customStyle="{
                 padding: '24rpx 48rpx',
                 color: '#fff',
@@ -50,7 +50,7 @@ export default {
     },
     onLoad(query) {
         console.log(query, 'query')
-        this.auditStatus = query.teNickNameAuditStatus?query.teNickNameAuditStatus:1
+        this.auditStatus = Number(query.auditStatus)
         this.value = (query.introduceYourself === undefined || query.introduceYourself === 'undefined') ? '' : decodeURIComponent(query.introduceYourself)
     },
     onShow() {

+ 3 - 3
src/pages/join/lifePhotosEdit.vue

@@ -70,7 +70,7 @@
             </view>
 
 
-            <view class="footer-bar" v-if="auditStatus != 1 ">
+            <view class="footer-bar" v-if="auditStatus != 0 ">
                 <u-button :customStyle="{
                     padding: '24rpx 48rpx',
                     color: '#fff',
@@ -129,10 +129,10 @@ export default {
                 // 找到第一个1/3就返回对应数值,找不到返回默认值0
 
             }
-            this.auditStatus = this.fileList.find(item => item.auditStatus == 0 || item.auditStatus == 2)?.auditStatus || 1
         }
-        console.log(this.fileList, this.auditStatus)
+        console.log(this.fileList)
         if (query.maxlength) this.maxlength = Number(query.maxlength)
+        if (query.auditStatus) this.auditStatus = Number(query.auditStatus)
         if (query.title) this.title = query.title
     },
     onReady() {

+ 105 - 92
src/pages/join/staff.vue

@@ -3,14 +3,13 @@
 		<view class="banner">
 			<image src="/static/login/banner.png" mode=""></image>
 		</view>
-		<view class="top" v-if="ShopInfo.merchant">
-			<view v-if="ShopInfo.merchant.auditStatus == 1 || ShopInfo.merchant.auditStatus == 3" class="checkBox"
-				:style="{
-					borderColor: ShopInfo.merchant.auditStatus == 3 ? '#F76560' : '#FF7D00',
-					color: ShopInfo.merchant.auditStatus === 3 ? '#F53F3F' : '#FF7D00',
-					background: ShopInfo.merchant.auditStatus === 3 ? '#FFF5F5' : '#FFF8EC'
-				}">
-				<view class="checkStatus">{{ShopInfo.merchant.auditStatus == 3 ? '审核驳回' : '审核中'}}</view>
+		<view class="top" v-if="ShopInfo">
+			<view v-if="ShopInfo.auditStatus == 1 || ShopInfo.auditStatus == 3" class="checkBox" :style="{
+				borderColor: ShopInfo.auditStatus == 3 ? '#F76560' : '#FF7D00',
+				color: ShopInfo.auditStatus === 3 ? '#F53F3F' : '#FF7D00',
+				background: ShopInfo.auditStatus === 3 ? '#FFF5F5' : '#FFF8EC'
+			}">
+				<view class="checkStatus">{{ ShopInfo.auditStatus == 3 ? '审核驳回' : '审核中' }}</view>
 				<view class="text">入驻审核中,审核结果将会在X-X个工作日通知您</view>
 			</view>
 			<view class="title">
@@ -22,8 +21,8 @@
 			</view>
 			<view class="content">
 				<view class="input-box">
-					<u-input :disabled="ShopInfo.merchant.auditStatus == 1 ? true : false" v-model="form.teName"
-						border="none" placeholder="输入真实姓名" class="input-item"
+					<u-input :disabled="ShopInfo.auditStatus == 1 ? true : false" v-model="form.teName" border="none"
+						placeholder="输入真实姓名" class="input-item"
 						placeholder-style="font-weight: 400;font-size: 30rpx;color: #C9CDD4;text-align: right;">
 						<template slot="prefix">
 							<view class="label">
@@ -34,10 +33,10 @@
 				</view>
 				<view class="input-box service">
 					<view class="label">性别</view>
-					<view class="valueText" v-if="ShopInfo.merchant.auditStatus == 1">{{ form.teSex == '1' ? '男' : '女'
+					<view class="valueText" v-if="ShopInfo.auditStatus == 1">{{ form.teSex == '1' ? '男' : '女'
 					}}
 					</view>
-					<u-radio-group v-if="ShopInfo.merchant.auditStatus != 1" v-model="form.teSex">
+					<u-radio-group v-if="ShopInfo.auditStatus != 1" v-model="form.teSex">
 						<u-radio activeColor="#333335" v-for="(item, index) in sex" :key="index" :name="item.value"
 							:label="item.label" :customStyle="{ margin: '0 12rpx' }" />
 					</u-radio-group>
@@ -45,8 +44,8 @@
 
 
 				<view class="input-box">
-					<u-input :disabled="ShopInfo.merchant.auditStatus == 1 ? true : false" v-model="form.tePhone"
-						border="none" maxlength='11' placeholder="请输入手机号" class="input-item"
+					<u-input :disabled="ShopInfo.auditStatus == 1 ? true : false" v-model="form.tePhone" border="none"
+						maxlength='11' placeholder="请输入手机号" class="input-item"
 						placeholder-style="font-weight: 400;font-size: 30rpx;color: #C9CDD4;text-align: right;">
 						<template slot="prefix">
 							<view class="label">
@@ -55,9 +54,9 @@
 						</template>
 					</u-input>
 				</view>
-				<view class="input-box" v-if="this.ShopInfo.merchant.auditStatus != 1">
-					<u-input :disabled="ShopInfo.merchant.auditStatus == -1 ? true : false" v-model="form.phoneMsg"
-						type="number" border="none" maxlength="6" placeholder="输入短信验证码"
+				<view class="input-box" v-if="this.ShopInfo.auditStatus != 1">
+					<u-input :disabled="ShopInfo.auditStatus == -1 ? true : false" v-model="form.phoneMsg" type="number"
+						border="none" maxlength="6" placeholder="输入短信验证码"
 						placeholder-style="font-weight: 400;font-size: 30rpx;color: #C9CDD4;text-align: right;margin-right: 42rpx;"
 						class="input-item code-input">
 						<template slot="prefix">
@@ -84,11 +83,11 @@
 
 				<view class="input-box">
 					<view class="label" style="width: 50%;">合作意向城市</view>
-					<view class="inp select" @click="ShopInfo.merchant.auditStatus == 1 ? show = false : show = true">
+					<view class="inp select" @click="ShopInfo.auditStatus == 1 ? show = false : show = true">
 						<view class="text" :style="{ color: form.partnerCities ? '#4E5969' : '#C9CDD4' }">{{
 							form.partnerCities || '选择城市' }}</view>
-						<img v-show="ShopInfo.merchant.auditStatus == 1 ? false : true"
-							src="/static/login/arrowIcon.png" alt="" />
+						<img v-show="ShopInfo.auditStatus == 1 ? false : true" src="/static/login/arrowIcon.png"
+							alt="" />
 					</view>
 
 					<u-popup :show="show" mode="bottom" border-radius="16rpx 16rpx 0 0"
@@ -104,10 +103,10 @@
 				</view>
 				<view class="input-box service">
 					<view class="label">开通服务</view>
-					<view class="valueText" v-if="ShopInfo.merchant.auditStatus == 1">{{
-						serveArr.find(item => item.dictValue == form.serviceTag).dictLabel}}</view>
-					<u-radio-group v-if="ShopInfo.merchant.auditStatus != 1" v-model="form.serviceTag"
-						:disabled="ShopInfo.merchant.auditStatus == 1 ? true : false">
+					<view class="valueText" v-if="serveArr && ShopInfo.auditStatus == 1">{{dictLabelFind(form.serviceTag)
+						}}</view>
+					<u-radio-group v-if="ShopInfo.auditStatus != 1" v-model="form.serviceTag"
+						:disabled="ShopInfo.auditStatus == 1 ? true : false">
 						<u-radio activeColor="#333335" v-for="(item, index) in serveArr" :key="index"
 							:name="item.dictValue" :label="item.dictLabel" :customStyle="{ fontSize: '20rpx' }" />
 					</u-radio-group>
@@ -117,7 +116,7 @@
 					<view class="name">形象照</view>
 
 					<view class="images">
-						<Upload :disabled="ShopInfo.merchant.auditStatus == 1 ? true : false" :maxCount="2"
+						<Upload :disabled="ShopInfo.auditStatus == 1 ? true : false" :maxCount="2"
 							:fileList="avatarList" @fileList="onUpload($event)" />
 					</view>
 					<view class="title">
@@ -140,7 +139,7 @@
 
 
 		</view>
-		<view class="submits" v-if="this.ShopInfo.merchant.auditStatus != 1">
+		<view class="submits" v-if="this.ShopInfo.auditStatus != 1">
 
 			<view class="btn" @click="submit">
 				提交
@@ -268,21 +267,21 @@ export default {
 			},
 			token: '',
 			uuid: '',
-			ShopInfo: { merchant: { auditStatus: 0 } },
+			ShopInfo: {},
 			cityColumns: [],
 			allCityList: [],
 			pickerKey: 1,
 		}
 	},
 	onLoad(options) {
-		
+
 		if (options.merchantInfo) {
 			this.ShopInfo = JSON.parse(options.merchantInfo)
 			this.initForm()
 
 		}
 	},
-	
+
 	onShow() {
 		this.getServiceCategoryList()
 		this.getCity()
@@ -294,30 +293,44 @@ export default {
 		// this.form.city = uni.getStorageSync('selectCity')
 	},
 	methods: {
+		//获取服务名称
+		dictLabelFind(value) {
+			return this.serveArr.find(item => item.dictValue == value)?.dictLabel || ''
+		},
 		//赋值
 		initForm() {
-			Object.keys(this.form).forEach(key => {
-				if (this.ShopInfo.merchant.hasOwnProperty(key)) {
-					this.form[key] = this.ShopInfo.merchant[key].toString()
-				}
-			})
+			console.log(this.ShopInfo, 'this.ShopInfo')
+			if(this.ShopInfo.avatar){
+				this.form.avatarList = this.ShopInfo.avatar.split(',').map(item => ({url: item.trim()}))
+			}
+			
+			this.form.teName = this.ShopInfo.name
+			this.form.tePhone = this.ShopInfo.phone
+			this.form.teSex = this.ShopInfo.sex
+			this.form.serviceTag = this.ShopInfo.serviceTag
+			this.form.provinceName = this.ShopInfo.provinceName
+			this.form.cityName = this.ShopInfo.cityName
+			this.form.operationCenterName = this.ShopInfo.operationCenterName
+			this.form.operationCenterId = this.ShopInfo.operationCenterId
+			this.form.provinceCode = this.ShopInfo.provinceCode
+			this.form.cityCode = this.ShopInfo.cityCode
 			setTimeout(() => {
 				const provinceIndex = this.allCityList.findIndex(p => p.name === this.form.provinceName)
 				if (provinceIndex == -1) return
-				const cityIndex = this.allCityList[provinceIndex].children.findIndex(c => c.name === this.ShopInfo.merchant.cityName)
+				const cityIndex = this.allCityList[provinceIndex].children.findIndex(c => c.name === this.form.cityName)
 				if (cityIndex == -1) return
-				const deptIndex = this.deptList.findIndex(c => c.name === this.ShopInfo.merchant.operationCenterName)
+				const deptIndex = this.deptList.findIndex(c => c.name === this.form.operationCenterName)
 				if (deptIndex == -1) return
 				this.defaultCityIndex = [provinceIndex, cityIndex, deptIndex]
-				this.form.partnerCities = this.ShopInfo.merchant.provinceName + '/' + this.ShopInfo.merchant.cityName + this.ShopInfo.merchant.operationCenterName
-
+				this.form.partnerCities = this.form.provinceName + '/' + this.form.cityName + this.form.operationCenterName
+				console.log(this.form,'666666' )
 			}, 300)
 
 		},
 		//获取城市
-		getCity() {
-			provinceCityTree().then(res => {
-				console.log(res, '获取城市')
+		async getCity() {
+			 await provinceCityTree().then(res => {
+				//console.log(res, '获取城市')
 				this.allCityList = res.data.data
 				const provinces = res.data.data.map(p => ({ name: p.name, code: p.code }))
 				const cities = this.getCitiesByProvince(this.form.provinceName || provinces[0]?.name || '').map(c => ({ name: c.name, code: c.code }))
@@ -424,20 +437,20 @@ export default {
 			const openid = uni.getStorageSync('wx_copenid')
 			const merchantInfo = await this.$utils.checkMerchantStatus(openid)
 			if (!merchantInfo) return
-			this.ShopInfo = merchantInfo.merchant
-			if (merchantInfo.merchant.auditStatus == -1) {//未注册
+			this.ShopInfo = merchantInfo
+			if (merchantInfo.auditStatus == -1) {//未注册
 				this.initForm()
 				return
 
-			} else if (merchantInfo.merchant.auditStatus == 0 || merchantInfo.merchant.auditStatus == 1 || merchantInfo.merchant.auditStatus == 2 || merchantInfo.merchant.auditStatus == 3) {
-				if (merchantInfo.merchant.auditStatus == 0) { //待入驻
+			} else if (merchantInfo.auditStatus == 0 || merchantInfo.auditStatus == 1 || merchantInfo.auditStatus == 2 || merchantInfo.auditStatus == 3) {
+				if (merchantInfo.auditStatus == 0) { //待入驻
 					if (!this.$utils.checkLogin({ type: 'navigate' })) return;
 					uni.switchTab({
 						url: '/pages/index/index'
 					})
 					return
 				}
-				if (merchantInfo.merchantAuditFile.length) {//已有入驻信息
+				if (merchantInfo.fileGroups.length) {//已有入驻信息
 					if (!this.$utils.checkLogin({ type: 'navigate' })) return;
 					uni.switchTab({
 						url: '/pages/index/index'
@@ -789,52 +802,52 @@ export default {
 }
 
 .captcha-box {
-  width: 622rpx;
-  background: #FFFFFF;
-  border-radius: 32rpx 32rpx 32rpx 32rpx;
-
-  .captcha-title {
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    font-weight: 500;
-    font-size: 32rpx;
-    color: #333333;
-    text-align: center;
-    padding: 32rpx 0;
-    border-bottom: 1rpx solid #E7E7E7;
-
-  }
-
-  .captcha-img {
-    //width: 100%;
-    width: 146rpx;
-    height: 60rpx;
-  }
-
-  .submitImgCode {
-    width: 526rpx;
-    height: 88rpx;
-    background: #333335;
-    border-radius: 60rpx 60rpx 60rpx 60rpx;
-    margin: 48rpx 0;
-
-    font-weight: 500;
-    font-size: 32rpx;
-    color: #FFFFFF;
-    text-align: center;
-  }
-
-  .text {
-    margin-top: 12rpx;
-    font-weight: 400;
-    font-size: 28rpx;
-    color: #86909C;
-    text-align: right;
-
-  }
-
-  .u-input {}
+	width: 622rpx;
+	background: #FFFFFF;
+	border-radius: 32rpx 32rpx 32rpx 32rpx;
+
+	.captcha-title {
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		font-weight: 500;
+		font-size: 32rpx;
+		color: #333333;
+		text-align: center;
+		padding: 32rpx 0;
+		border-bottom: 1rpx solid #E7E7E7;
+
+	}
+
+	.captcha-img {
+		//width: 100%;
+		width: 146rpx;
+		height: 60rpx;
+	}
+
+	.submitImgCode {
+		width: 526rpx;
+		height: 88rpx;
+		background: #333335;
+		border-radius: 60rpx 60rpx 60rpx 60rpx;
+		margin: 48rpx 0;
+
+		font-weight: 500;
+		font-size: 32rpx;
+		color: #FFFFFF;
+		text-align: center;
+	}
+
+	.text {
+		margin-top: 12rpx;
+		font-weight: 400;
+		font-size: 28rpx;
+		color: #86909C;
+		text-align: right;
+
+	}
+
+	.u-input {}
 }
 
 .join {

+ 190 - 100
src/pages/my/dynamic/add_dynamic.vue

@@ -2,17 +2,21 @@
   <view class="publish-container">
     <view class="content-body">
       <view class="text-area">
-        <u--textarea v-model="formData.title" placeholder="请输入标题..." maxLength="30" border="none"
+        <u--textarea class="textareaDef" v-model="formData.title" placeholder="请输入标题..." maxLength="30" border="none"
           height="20"></u--textarea>
         <view class="line"></view>
       </view>
       <view class="content-area">
-        <u--textarea v-model="formData.content" placeholder="记录美好生活时刻..." maxLength="500" border="none" height="150"
-          count></u--textarea>
+        <u--textarea class="textareaDef" v-model="formData.content" placeholder="
+此刻你想要分享" maxLength="500" border="none" height="150" count></u--textarea>
       </view>
-      <view class="media-area">
+      <view class="media-area" :style="{width: formData.videoUrl ? '340rpx' : '100%' }">
         <view v-if="formData.videoUrl">
-          <uni-icons class="icon iconfont icon-cuo" type="trash-filled" size="20" @tap="delectVideo"></uni-icons>
+          <view class="icon iconfont icon-cuo">
+            <image src="/static/login/close2.png" mode="" style="width: 32rpx;height: 32rpx;" @tap="delectVideo">
+            </image>
+          </view>
+
           <video ref="myVideo" :src="formData.videoUrl" class="video-container" controls></video>
         </view>
         <clUpload v-else v-model="fileList" :action="uploadApi" :headers="headers" :count="maxCount" :listStyle="{
@@ -21,21 +25,27 @@
           width: '130rpx',
           radius: '12rpx',
         }" :imageFormData="{
-          count: 9,
-          size: 2,
-        }" :videoFromData="{
-          count: 1,
-          size: 50,
-        }" :maxVideo="1" :fileType="mediaType" addImg="/static/discover/ic_upload.png"
-          deleteImg="/static/discover/ic_delete.png" @onSuccess="onSuccess" @onMediaTypeSelect="selectMediaType"
-          @onError="onCancel"></clUpload>
+                          count: 9,
+                          size: 2,
+                        }" :videoFromData="{
+                          count: 1,
+                          size: 50,
+                        }" :maxVideo="1" :fileType="mediaType" addImg="/static/login/cameraIcon.png"
+          deleteImg="/static/login/cameraIcon.png" @onSuccess="onSuccess" @onMediaTypeSelect="selectMediaType"
+          @onError="onCancel">
+
+
+        </clUpload>
       </view>
+
       <view class="tips">
         <text v-if="fileList.length === 0">支持上传图片(最多9张)或视频(1个)</text>
       </view>
     </view>
     <view class="location-cell">
+      <image src="/static/workbench/locationIcon.png" style="width: 32rpx;height: 32rpx;"></image>
       <u-cell-group :border="false">
+
         <u-cell title="地点" :value="formData.location || '请选择'" isLink :border="true" @click="selectLocation">
         </u-cell>
         <!-- <u-cell
@@ -49,10 +59,10 @@
       </u-cell-group>
     </view>
     <view class="footer-bar">
-      <u-button text="存为草稿" shape="circle" customStyle="height: 38px; font-size: 18px; margin-right: 20rpx;"
-        @click="submit('draft')"></u-button>
-      <u-button text="发布动态" color="linear-gradient(80deg,#02f6c1 0%,#07cdc4 100%)" shape="circle"
-        customStyle="height: 38px; font-size: 18px;" @click="submit('publish')"></u-button>
+      <u-button text="存为草稿" customStyle="width: 311rpx;height: 88rpx;background: rgba(51,51,53,0.05);
+border-radius: 60rpx 60rpx 60rpx 60rpx;" @click="submit('draft')"></u-button>
+      <u-button text="发布动态" color="linear-gradient(80deg,#02f6c1 0%,#07cdc4 100%)" shape="circle" customStyle="width: 311rpx;height: 88rpx;background: #333335;
+border-radius: 60rpx 60rpx 60rpx 60rpx;" @click="submit('publish')"></u-button>
     </view>
     <!-- 可见范围 -->
     <u-picker title="请选择" :show="showScopePicker" :columns="scopeList" confirmColor="#1ecbc3" @confirm="confirmScope"
@@ -84,14 +94,9 @@
           <text>简单描述《春秋笔法》在的应用场景</text>
         </view>
         <view class="popup-btn1">
-          <u-button text="继续编辑" shape="circle"
-            customStyle=" height: 68rpx; font-size: 28px; color: #1BD6CD; border-color: #1BD6CD;"
-            @click="goOnFun"></u-button>
-          <u-button text="重新写" shape="circle"
-            customStyle=" height: 68rpx;margin:30rpx 0; font-size: 28px; color: #1BD6CD; border-color: #1BD6CD;"
-            @click="popClose"></u-button>
-          <u-button text="删除草稿" color="linear-gradient( 90deg, #1AD7CE 0%, #21C9C1 100%)" shape="circle"
-            customStyle="height: 68rpx; font-size: 28px;" @click="deleteFun"></u-button>
+          <view class="btn" @click="goOnFun">继续编辑</view>
+          <view class="btn" @click="popClose">重新写</view>
+          <view class="btn" @click="deleteFun">删除草稿</view>
         </view>
       </view>
     </u-popup>
@@ -223,8 +228,10 @@ export default {
           reslut.url.endsWith('.mov') ||
           reslut.url.endsWith('.mkv') ||
           reslut.url.endsWith('.wmv')
-          console.log(isVideo,'isVideo')
+        console.log(isVideo, 'isVideo')
+           console.log(reslut, 'reslut')
         if (isVideo) {
+       
           this.formData.videoUrl = baseUrl + reslut.url
           this.formData.videoCoverUrl = baseUrl + reslut.coverUrl
         } else {
@@ -242,7 +249,7 @@ export default {
       } else if (type === 'video') {
         this.uploadApi = baseUrl + '/common/uploadVi'
         this.mediaType = 'video'
-      }else if (type === 'audio') {
+      } else if (type === 'audio') {
         this.uploadApi = baseUrl + '/common/uploadVi'
         this.mediaType = 'audio'
       }
@@ -333,9 +340,9 @@ export default {
         this.uploadApi = baseUrl + '/common/uploads'
         if (data.coverUrl.includes(',')) {
           this.fileList = data.coverUrl.split(',')
-          
-        }else{
-          this.fileList=[data.coverUrl]
+
+        } else {
+          this.fileList = [data.coverUrl]
         }
       } else if (data.mediaType === 2) {
         // 视频类型
@@ -365,10 +372,11 @@ export default {
         type == 'publish' &&
         (!this.formData.title ||
           !this.formData.content ||
-          !this.formData.location ||
-          (this.mediaType == 1 && this.fileList.length === 0) ||
-          (this.mediaType == 2 && !this.formData.videoUrl)
+          !this.formData.location 
         )//!this.formData.visibleRange
+      
+          // ||(this.mediaType == 1 && this.fileList.length === 0) ||
+         // (this.mediaType == 2 && !this.formData.videoUrl)
       ) {
         uni.showToast({ title: '请完善动态内容', icon: 'none' })
         return
@@ -395,7 +403,7 @@ export default {
         const postData = {
           ...this.formData,
           isDraft: type == 'draft' ? 1 : 0,
-          mediaType: this.formData.videoUrl ? 2 : 1,
+          mediaType: this.formData.videoUrl ? 2 : this.fileList.length > 0 ? 1 : 3,
           imageUrls: this.fileList,
         }
 
@@ -440,77 +448,147 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-.publish-container {
-  height: 100vh;
-  padding: 32rpx 32rpx 150rpx;
-  background: #f8f8f8;
-  box-sizing: border-box;
-  overflow: scroll;
-  font-family: PingFang SC, PingFang SC;
-
-  .content-body {
-    background: #fff;
-    padding: 32rpx;
-    border-radius: 20rpx;
-    margin-bottom: 24rpx;
-
-    .text-area {
-      font-weight: 500;
-      font-size: 32rpx;
-      color: #999999;
-
-      .line {
-        border-bottom: 1px solid #e5e5e5;
-        background: #cccccc;
-        border-radius: 4rpx;
-      }
+.media-area {
+  
+    margin: 20rpx 0 0 0;
+    justify-content: space-between;
+    position: relative;
+    .add-image{
+      border: 1px solid #f80000;
     }
 
-    .content-area {
-      ::v-deep .uni-textarea-wrapper {
-        font-size: 24rpx;
-      }
+    .icon-cuo {
+        background-color: #0000009c;
+        width: 40rpx;
+        height: 40rpx;
+        position: absolute;
+        right: 0;
+        top: 0;
+        z-index: 999;
+        border-bottom-left-radius: 12rpx;
+        border-top-right-radius: 12rpx;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        
     }
 
-    .media-area {
-      margin: 20rpx 0 20rpx;
-      justify-content: space-between;
-      position: relative;
 
-      .icon-cuo {
-        position: absolute;
-        left: 295upx;
-        top: 5upx;
-        color: #ffffff !important;
-        z-index: 999;
-        border-top-right-radius: 20upx;
-        border-bottom-left-radius: 20upx;
-      }
 
-      .video-container {
+    .video-container {
         width: 340upx;
         height: 240upx;
         border-radius: 12rpx;
-      }
     }
+}
+.text-area {
+  .textareaDef {
+    padding: 24rpx 0 !important;
+
+    .uni-textarea-placeholder {
+      font-weight: 400;
+      font-size: 28rpx;
+      color: #86909C !important;
+
+    }
+  }
+
+
+  .line {
+    border-bottom: 1px solid #e5e5e5;
+    background: #cccccc;
+    border-radius: 4rpx;
+  }
+}
+
+.content-area {
+  .textareaDef {
+    padding: 24rpx 0 !important;
+
+    .uni-textarea-placeholder {
+      font-weight: 400;
+      font-size: 28rpx;
+      color: #C9CDD4 !important;
+      margin-top: -40rpx;
+      text-align: left;
 
-    .tips {
-      font-size: 24rpx;
-      color: #999;
-      margin-bottom: 20rpx;
     }
   }
 
-  .location-cell {
+
+  ::v-deep .uni-textarea-wrapper {
+    font-size: 28rpx;
+    color: #1D2129;
+  }
+}
+
+::v-deep .location-cell {
+  border-top: 1px solid #E7E7E7;
+  height: 88rpx;
+  background: #fff;
+  border-radius: 20rpx;
+  padding: 12rpx 2rpx;
+  display: flex;
+  align-items: center;
+
+
+
+  .u-cell__body {
+    margin-left: 8rpx;
+    padding: 0 !important;
+  }
+
+  .u-cell__title-text {
+    font-weight: 400 !important;
+    font-size: 28rpx !important;
+    color: #1D2129 !important;
+
+  }
+
+  .u-cell__value {
+    font-weight: 400 !important;
+    font-size: 28rpx !important;
+    color: #1D2129 !important;
+  }
+
+  .u-icon__icon--info {
+    font-size: 28rpx !important;
+    color: #86909C !important;
+  }
+}
+
+.publish-container {
+  height: 100vh;
+  padding: 32rpx 32rpx 150rpx;
+  background: #fff;
+  box-sizing: border-box;
+  overflow: scroll;
+  font-family: PingFang SC, PingFang SC;
+
+  .content-body {
     background: #fff;
     border-radius: 20rpx;
-    padding: 12rpx 2rpx;
+    margin-bottom: 24rpx;
+
+    .tips {
+      margin-top: 8rpx;
+      margin-bottom: 24rpx;
+
+      font-weight: 400;
+      font-size: 24rpx;
+      color: #C9CDD4;
+    }
   }
 
+
+
   .footer-bar {
-    background: #f8f8f8;
-    box-shadow: none;
-    padding: 0 32rpx 20rpx;
+    width: 750rpx;
+    height: 136rpx;
+    background: #FFFFFF;
+    display: flex;
+    justify-content: center;
+    align-items: center;
   }
 }
 
@@ -531,6 +609,8 @@ export default {
   .cl-updata {
     .file-list .add-image {
       border: none;
+      background-color: #F7F8FA;
+      border-radius: 16rpx;
 
       ._image {
         width: 100%;
@@ -600,39 +680,49 @@ export default {
 
 .popup-content1 {
 
-  width: 630rpx;
+  width: 590rpx;
 
   //height: 380rpx;
   .popup-title {
     display: flex;
     justify-content: center;
     align-items: center;
-    font-weight: bold;
+    padding: 48rpx 48rpx 0rpx 48rpx;
+    width: 590rpx;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    font-weight: 500;
     font-size: 32rpx;
-    color: #000000;
-    height: 92rpx;
-    background: #e6f8f7;
-    border-radius: 24rpx 24rpx 0rpx 0rpx;
+    color: #1D2129;
   }
 
   .popup-desc {
-    height: 168rpx;
-    font-weight: 500;
+    margin-top: 20rpx;
+    padding: 0rpx 48rpx;
+    font-weight: 400;
     font-size: 28rpx;
-    color: #333333;
-    display: flex;
-    justify-content: center;
-    align-items: center;
+    color: #86909C;
+    text-align: left;
   }
 
   .popup-btn1 {
+    margin-top: 32rpx;
 
     //height: 120rpx;
     //padding: 24rpx 60rpx;
     //border-top: 2rpx solid #eeeeee;
-    ::v-deep .u-botton {
+    .btn {
+      border-top: 1rpx solid #E7E7E7;
       width: 100%;
-      height: 68rpx;
+      height: 90rpx;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+
+      font-weight: 400;
+      font-size: 30rpx;
+      color: #1D2129;
     }
   }
 }

+ 132 - 26
src/pages/my/dynamic/components/my_list.vue

@@ -3,23 +3,26 @@
     <view class="item" v-for="(item, index) in dataList" :key="index">
 
       <view class="item-content" @click.stop="goToDateil(item)">
-        <view style="display: flex;justify-content: space-between;">
-          <view>
+        <view style="display: flex;justify-content: space-between;align-items: center;">
+          <view style="display: flex;align-items: center;">
+            <view class="reserve-status" v-if="item.auditStatus == 0">草稿箱</view>
+            <view class="reserve-status1" v-if="item.auditStatus == 1">审核中</view>
+            <view class="reserve-status2" v-if="item.auditStatus == 3">审核驳回</view>
             <view class="title">{{ item.title }}</view>
 
           </view>
-          <view v-if="item.auditStatus == 2" class="diamond-count">
-            <text>已读{{ item.viewCount }}</text>
-          </view>
-          <view class="reserve-status" v-if="item.auditStatus == 1">审核中</view>
-          <view class="reserve-status" v-if="item.auditStatus == 3">审核驳回</view>
-
           <view class="moreClass" @click.stop="editFun(item)">
+            <image src="/static/workbench/moreIcon.png" style="width: 32rpx;height: 32rpx;" />
 
           </view>
         </view>
         <view class="service-info">
-          <text class="service-time">{{ item.publishTime }}发布</text>
+          <!--  //0-草稿 1-待审核 2-审核通过 3-审核拒绝 -->
+          <text v-if="item.publishTime" class="service-time">{{ item.publishTime }}发布</text>
+          <view v-if="item.auditStatus == 2" class="diamond-count">
+            <image src="/static/workbench/eyeIcon.png" style="width: 32rpx;height: 32rpx;" />
+            <text>已读{{ item.viewCount }}</text>
+          </view>
         </view>
         <view class="contentText">{{ item.content }}</view>
         <view class="item-image">
@@ -50,6 +53,24 @@
       </view>
     </u-popup>
 
+    <!-- 未入驻提示 -->
+    <u-popup :show="showModal1" mode="center" :round="16" :mask-close-able="false">
+      <view class="modal-wrap">
+        <!-- 标题居中 -->
+        <view class="title">{{ auditStatus == 0 ? '提示' : '入驻审核驳回' }}</view>
+        <!-- 正文 -->
+        <view class="content">
+          请提交入驻资料并由后台人员审核通过后,即可开通操作权限
+        </view>
+        <!-- 底部双按钮(必显示) -->
+        <view class="btn-box">
+          <view v-if="auditStatus == 3" class="btn">修改入驻信息</view>
+          <view v-if="auditStatus == 0" class="btn left" @click="cancel">我在想想</view>
+          <view v-if="auditStatus == 0" class="btn right" @click="goEnter">立即入驻</view>
+        </view>
+      </view>
+    </u-popup>
+
   </view>
 </template>
 
@@ -70,7 +91,9 @@ export default {
   },
   data() {
     return {
+      auditStatus: uni.getStorageSync('auditStatus'),
       showModal: false,
+      showModal1: false,
       sheetShow: false,
       actionList: [
         { name: '编辑' },
@@ -86,6 +109,18 @@ export default {
   },
   methods: {
     goToDateil(item) {
+      if (this.auditStatus == 0 || this.auditStatus == 3) {
+        this.showModal1 = true
+        return
+      }
+      if (this.auditStatus == 1) {
+        uni.showToast({
+          title: '入驻审核中,暂无操作权限',
+          icon: 'none'
+        })
+        return
+
+      }
       uni.navigateTo({
         url: `/pages/my/dynamic/dynamicDetail?momentId=${item.id}`,
       })
@@ -107,6 +142,17 @@ export default {
       })
 
     },
+    // 我在想想:关闭弹窗
+    cancel() {
+      this.showModal1 = false
+    },
+    // 立即入驻:跳转入驻页
+    goEnter() {
+      this.showModal1 = false
+      uni.navigateTo({
+        url: '/pages/join/applyJoin' // 替换你的入驻页面路径
+      })
+    },
     //取消
     cancel() {
       this.showModal = false
@@ -121,7 +167,7 @@ export default {
       if (item.name === '编辑') {
         if (this.currentAuditStatus == 1 || this.currentAuditStatus == 2) {
           uni.showToast({
-            title: this.currentAuditStatus == 1 ? '审核中':'已发布'+'的动态不支持编辑',
+            title: this.currentAuditStatus == 1 ? '审核中' : '已发布' + '的动态不支持编辑',
             icon: 'none'
           })
           return
@@ -147,6 +193,18 @@ export default {
 
     },
     editFun(item) {
+      if (this.auditStatus == 0 || this.auditStatus == 3) {
+        this.showModal1 = true
+        return
+      }
+      if (this.auditStatus == 1) {
+        uni.showToast({
+          title: '入驻审核中,暂无操作权限',
+          icon: 'none'
+        })
+        return
+
+      }
       this.currentObj = item
       this.currentAuditStatus = item.auditStatus
       this.sheetShow = true
@@ -161,6 +219,8 @@ export default {
 
 <style scoped lang="scss">
 .list-box {
+  padding: 32rpx;
+  background-color: #F7F8FA;
   //display: flex;
   flex-wrap: wrap;
   justify-content: space-between;
@@ -168,16 +228,20 @@ export default {
   font-family: PingFang SC, PingFang SC;
 
   .item {
-    //width: calc(50% - 14rpx);
-    margin-bottom: 28rpx;
+    border-radius: 16rpx 16rpx 16rpx 16rpx;
+    padding: 32rpx;
+
+    margin-bottom: 24rpx;
     box-sizing: border-box;
     background: #ffffff;
-    box-shadow: 0rpx 4rpx 12rpx 0rpx rgba(88, 209, 187, 0.1);
-    border-radius: 12rpx;
     overflow: hidden;
 
     .contentText {
+      margin: 20rpx 0;
+      font-family: PingFang SC, PingFang SC;
+      font-weight: 400;
       font-size: 28rpx;
+      color: #1D2129;
       overflow: hidden;
       display: -webkit-box;
       -webkit-line-clamp: 2;
@@ -186,8 +250,9 @@ export default {
     }
 
     .title {
-      font-size: 28rpx;
-      width: 520rpx;
+      width: 480rpx;
+      height: 32rpx;
+      line-height: 32rpx;
       //border: 1px solid red;
       white-space: nowrap;
       /* 禁止换行 单行 */
@@ -195,16 +260,23 @@ export default {
       /* 超出隐藏 */
       text-overflow: ellipsis;
       /* 末尾... */
+      font-weight: 500;
+      font-size: 30rpx;
+      color: #1D2129;
+      text-align: left;
+      margin-left: 8rpx;
     }
 
     .service-info {
+      margin-top: 8rpx;
       display: flex;
-      flex: 1;
 
       .service-time {
         display: block;
-        font-size: 24rpx;
-        color: #999999;
+        font-weight: 400;
+        font-size: 22rpx;
+        color: #86909C;
+        text-align: left;
       }
     }
 
@@ -221,6 +293,7 @@ export default {
         width: 100%;
         height: 100%;
         object-fit: cover;
+        border-radius: 8rpx 8rpx 8rpx 8rpx;
       }
     }
 
@@ -230,11 +303,40 @@ export default {
     }
 
     .reserve-status {
+      width: 84rpx;
+      height: 32rpx;
+      background: #86909C;
+      border-radius: 4rpx 4rpx 4rpx 4rpx;
+
+      font-weight: 400;
+      font-size: 20rpx;
+      color: #FFFFFF;
+      line-height: 32rpx;
+      text-align: center;
+    }
+
+    .reserve-status1 {
+
+      width: 84rpx;
+      height: 32rpx;
+      background: #FF7D00;
+      border-radius: 4rpx 4rpx 4rpx 4rpx;
+
+      font-weight: 400;
+      font-size: 20rpx;
+      color: #FFFFFF;
+      line-height: 32rpx;
+      text-align: center;
+    }
+
+    .reserve-status2 {
+
       font-size: 24rpx;
-      color: #f16336;
+      color: #03c8be;
     }
 
     .diamond-count {
+      margin-left: 48rpx;
       display: flex;
       align-items: center;
 
@@ -245,16 +347,20 @@ export default {
       }
 
       text {
-        font-size: 24rpx;
-        color: #999999;
+        font-weight: 400;
+        font-size: 22rpx;
+        color: #86909C;
+        line-height: 32rpx;
       }
     }
 
     .moreClass {
-      background-color: #03c8be;
-      height: 40rpx;
-      width: 40rpx;
-      border-radius: 50%;
+      height: 32rpx;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+
+
     }
 
 

+ 94 - 43
src/pages/my/dynamic/dynamicDetail.vue

@@ -4,14 +4,16 @@
     <scroll-view scroll-y class="scroll-wrap">
       <view class="page-content">
         <!-- 审核驳回区域 -->
-        <view class="reject-card" v-if="detail.auditStatus != 2">
+        <view class="reject-card" v-if="detail.auditStatus == 1 || detail.auditStatus == 3"
+          :style="{ background: detail.auditStatus == 3 ? '#FFF5F5' : '#FFF8EC' }">
           <view class="reject-head">
-            <u-icon name="close-circle" size="38" color="#999"></u-icon>
-            <text v-if="detail.auditStatus == 3" class="reject-title">审核驳回</text>
-            <text v-if="detail.auditStatus == 1" class="reject-title">审核中</text>
+            <image src="/static/workbench/warringIcon.png" style="width: 32rpx;height: 32rpx;" mode="widthFill" />
+
+            <text v-if="detail.auditStatus == 3" class="reject-title2">审核驳回</text>
+            <text v-if="detail.auditStatus == 1" class="reject-title1">审核中</text>
           </view>
-          <view class="reject-text">
-            审核结果将会在X-X个工作日通知您
+          <view :class="{ 'reject-text1': detail.auditStatus == 1, 'reject-text2': detail.auditStatus == 3 }">
+            审核结果将会在7个工作日通知您
           </view>
         </view>
 
@@ -25,7 +27,7 @@
           <text>{{ detail.technicianNickName || '--' }}</text>
           <text>{{ detail.publishTime || '--' }}</text>
           <text>{{ detail.viewCount || '--' }}已读</text>
-          <text>252点赞</text>
+          <!-- <text>252点赞</text> -->
         </view>
 
         <!-- 正文内容 -->
@@ -36,11 +38,11 @@
 
         <!-- 图片/视频占位 -->
         <view class="media-placeholder">
-          <view v-for="(item, index) in detail.mediaList" :key="index" style="border: 1rpx solid #eeeeee;">
-            <image v-if="item.mediaType == '1'" style=" width: 200rpx;" mode="widthFix" :src="item.mediaUrl"
-                        @error="imageError"></image>
-            <video v-if="item.mediaType == '2'" id="myVideo" :src="item.mediaUrl"
-              @error="videoErrorCallback" :danmu-list="danmuList" enable-danmu danmu-btn controls></video>
+          <view v-for="(item, index) in detail.mediaList" :key="index" :style="{ height: item.mediaType == '1' ? '214rpx' : '100%' }">
+            <image v-if="item.mediaType == '1'" class="media-item" mode="aspectFill" :src="item.mediaUrl"
+              @error="imageError"></image>
+            <video v-if="item.mediaType == '2'" class="myVideo" :src="item.mediaUrl" @error="videoErrorCallback"
+               enable-danmu danmu-btn controls></video>
           </view>
         </view>
       </view>
@@ -81,9 +83,11 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-.dynamic-detail{
-  
+.dynamic-detail {
+   background-color: #F7F8FA;
+   height: 100vh;
 }
+
 /* 滚动区域高度:扣除导航栏高度 */
 .scroll-wrap {
   height: calc(100vh - var(--u-navbar-height));
@@ -91,70 +95,117 @@ export default {
 
 /* 页面整体内边距 */
 .page-content {
-  margin: 0 32rpx;
-  padding: 24rpx;
-  background-color: #ffffff;
-  border-radius: 12rpx;
+  background-color: #fff;
 }
 
 /* 驳回卡片样式 */
 .reject-card {
-  border: 1rpx solid #eeeeee;
-  border-radius: 12rpx;
-  padding: 28rpx;
-  margin-bottom: 36rpx;
+  padding: 24rpx 32rpx;
 }
 
 .reject-head {
   display: flex;
   align-items: center;
-  gap: 18rpx;
+  gap: 8rpx;
   margin-bottom: 16rpx;
 }
 
-.reject-title {
+.reject-title1 {
+  font-weight: 500;
   font-size: 32rpx;
+  color: #FF7D00;
+}
+
+.reject-title2 {
   font-weight: 500;
-  color: #333333;
+  font-size: 32rpx;
+  color: #F53F3F;
 }
 
-.reject-text {
-  font-size: 28rpx;
-  color: #666666;
-  line-height: 1.6;
+.reject-text1 {
+  font-weight: 400;
+  font-size: 26rpx;
+  color: #FF7D00;
+}
+
+.reject-text2 {
+  font-weight: 400;
+  font-size: 26rpx;
+  color: #F53F3F;
 }
 
 /* 文章标题 */
 .article-title {
-  font-size: 34rpx;
   font-weight: 500;
-  line-height: 1.5;
-  color: #222;
-  margin-bottom: 22rpx;
+  font-size: 32rpx;
+  color: #1D2129;
+  padding: 32rpx 32rpx 0 32rpx;
 }
 
 /* 发布信息栏 */
 .info-bar {
   display: flex;
-  gap: 32rpx;
-  font-size: 26rpx;
-  color: #888888;
-  margin-bottom: 32rpx;
+  gap: 48rpx;
+  font-weight: 400;
+  font-size: 22rpx;
+  color: #86909C;
+  padding: 8rpx 32rpx 0 32rpx;
 }
 
 /* 正文 */
 .article-body {
-  font-size: 30rpx;
-  color: #333333;
-  line-height: 1.7;
-  margin-bottom: 42rpx;
+  font-weight: 400;
+  font-size: 28rpx;
+  color: #4E5969;
+  padding: 32rpx 32rpx 0 32rpx;
 }
 
 /* 媒体占位框 */
 .media-placeholder {
   display: flex;
   align-items: center;
-  font-size: 30rpx;
-  color: #666666;
+  flex-wrap: wrap;
+  padding: 32rpx;
+  gap: 24rpx;
+  .media-item {
+    width: 214rpx;
+    height: 214rpx;
+    border-radius: 8rpx;
+  }
+}
+.myVideo {
+  // width: 214rpx;
+  // height: 214rpx;
+  border-radius: 8rpx;
+}
+::v-deep .uni-video-danmu-button.uni-video-danmu-button-active{
+  display: none;
 }
+// ::v-deep .uni-video-control-button{
+//   padding:40rpx 0 0 5rpx!important;
+//   width: 15rpx;
+//   height: 15rpx;
+// }
+// ::v-deep .uni-video-bar.uni-video-bar-full{
+//   width: 214rpx;
+//   padding: 0;
+// }
+// ::v-deep .uni-video-bar-full{
+//   .uni-video-inner{
+//     display: none;
+//   }
+// }
+// ::v-deep .uni-video-bar{
+//   height: 30rpx;
+// }
+// ::v-deep .uni-video-danmu-button.uni-video-danmu-button-active{
+//   display: none;
+// }
+// ::v-deep .uni-video-current-time{
+//   font-size: 18rpx;
+//   margin-left: 10rpx;
+// }
+// ::v-deep .uni-video-duration{
+//   font-size: 18rpx;
+// }
 </style>

+ 32 - 54
src/pages/my/dynamic/index.vue

@@ -1,25 +1,24 @@
 <template>
   <view class="page-container">
-    <z-paging ref="paging" v-model="dynamicList" :paging-style="{
-      background: '#F7FFFF',
-    }" @query="queryList">
+    <z-paging ref="paging" v-model="dynamicList" @query="queryList">
 
-      <!-- 我的动态 -->
-      <my-dynamic-list :data-list="dynamicList" @refreshList="queryList"></my-dynamic-list>
+      <!-- 我的动态 @refreshList="queryList"-->
+      <my-dynamic-list :data-list="dynamicList"></my-dynamic-list>
 
 
       <template v-slot:empty>
-        <u-empty :text="!isLogin ? '您还没有登录' : '暂无相关动态~'" icon="/static/common/logo1.png">
-          <u-button size="small" text="去登录" color="linear-gradient(to right, #35c99d, #27aea7)"
+        <!-- !isLogin ? '您还没有登录' :  -->
+        <u-empty :text="'暂未发表任何动态'" icon="/static/workbench/emptyIcon.png">
+          <!-- <u-button size="small" text="去登录" color="linear-gradient(to right, #35c99d, #27aea7)"
             :customStyle="{ marginTop: '20rpx' }" v-if="!isLogin" @click="goLogin">
-          </u-button>
+          </u-button> -->
         </u-empty>
       </template>
     </z-paging>
 
     <!-- 发布动态 -->
-    <view v-if="isLogin && current === 0" class="add-btn" @click="goPublish">
-      <image src="/static/discover/subtract.png" mode="" />
+    <view v-if="isLogin" class="add-btn" @click="goPublish">
+      <image src="/static/workbench/editIcon.png" />
     </view>
 
 
@@ -74,11 +73,12 @@ export default {
     }
   },
   onLoad() {
-    this.isLogin = !!uni.getStorageSync('wx_copenid')
+    this.isLogin = !!uni.getStorageSync('access-token')
     console.log(this.isLogin, 'this.isLogin')
   },
   onShow() {
     this.queryList(1, 10)
+    this.checkMerchantStatus()
   },
   methods: {
     //查询商户状态  auditStatus 审核状态:-1-申请入住,0-待入驻,1-待审核,2-审核通过,3-审核驳回"
@@ -86,14 +86,20 @@ export default {
       const openid = uni.getStorageSync('wx_copenid')
       const merchantInfo = await this.$utils.checkMerchantStatus(openid)
       if (!merchantInfo) return
-      this.cJsId = merchantInfo.merchant.id; //用户id
+      this.cJsId = merchantInfo.id; //用户id
       /**
        * 服务标签(1:按摩推拿 2:陪玩)
        */
-      this.serviceTag = merchantInfo.merchant.serviceTag
-      uni.setStorageSync('serviceTag', normalizeStorageValue(merchantInfo.merchant.serviceTag))
-      uni.setStorageSync('userId', normalizeStorageValue(merchantInfo.merchant.id))
-      return merchantInfo.merchant.auditStatus//用户状态
+      // this.serviceTag = merchantInfo.merchant.serviceTag
+      // uni.setStorageSync('serviceTag', normalizeStorageValue(merchantInfo.merchant.serviceTag))
+      // uni.setStorageSync('userId', normalizeStorageValue(merchantInfo.merchant.id))
+      // return merchantInfo.merchant.auditStatus//用户状态
+
+
+      this.serviceTag = merchantInfo.serviceTag
+      uni.setStorageSync('serviceTag', merchantInfo.serviceTag)
+      uni.setStorageSync('userId', merchantInfo.id)
+      uni.setStorageSync('auditStatus', merchantInfo.auditStatus)
 
     },
     // 我在想想:关闭弹窗
@@ -112,8 +118,8 @@ export default {
         pageNum: pageNo,
         pageSize: pageSize,
       }
-      //this.current=0
-      const api = this.current == 0 ? myDynamicList : draftDynamicList
+      const api = myDynamicList
+      //0-草稿 1-待审核 2-审核通过 3-审核拒绝
       api(params).then(res => {
         if (
           res.data.code === 200 &&
@@ -121,43 +127,13 @@ export default {
           res.data.data.records.length > 0
         ) {
           let data = res.data.data.records
-          data.forEach(item => {
-            item.publishTime = item.publishTime
-              .replace('T', ' ')
-              .substring(0, 16)
-          })
           this.$refs.paging.complete(data)
+          //this.$refs.paging.complete([])
         } else {
           this.$refs.paging.complete([])
         }
       })
 
-      //  this. dynamicList= [
-      //   {title:'哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈lalallalaal哈',
-      //   auditStatus:2,
-      //   publishTime:'2023.12.25 18:25',
-      //   viewCount:'99999',
-      //   coverUrl:'/static/login/closeEye.png',
-      //   content:'偶滴啊发撒积分非机动撒JFK的拉萨偶滴啊发撒积分非机动撒JFK的拉萨佛海飞机滴哦撒娇放大 地方到南方粉底哦撒飞机殴打佛教道教佛海飞机滴哦撒娇放大 地方到南方粉底哦撒飞机殴打佛教道教佛'
-
-
-      //   },
-      //   {title:'444',
-      //   auditStatus:1,
-      //   publishTime:'88962333',
-      //   viewCount:'99999'
-
-
-      //   },
-      //   {title:'444',
-      //   auditStatus:1,
-      //   publishTime:'88962333',
-      //   viewCount:'99999'
-
-
-      //   },
-
-      // ]
 
     },
     onTabChange(index) {
@@ -174,7 +150,7 @@ export default {
       // })
     },
     async goPublish() {
-      this.auditStatus = await this.checkMerchantStatus()
+      this.auditStatus = uni.getStorageSync('auditStatus')
       if (this.auditStatus == 0 || this.auditStatus == 3) {
         this.showModal = true
         return
@@ -197,7 +173,7 @@ export default {
 
 <style scoped lang="scss">
 .page-container {
-  background-color: #f7ffff;
+  background-color: #F7F8FA ;
   font-family: PingFang SC, PingFang SC;
 
   .tab-box {
@@ -244,13 +220,15 @@ export default {
     display: flex;
     justify-content: center;
     align-items: center;
-    background-color: #fff;
+    width: 100rpx;
+    height: 100rpx;
+    background: #1D2129;
     border-radius: 50%;
     z-index: 99;
 
     image {
-      width: 80rpx;
-      height: 80rpx;
+      width: 48rpx;
+      height: 48rpx;
     }
   }
 }

+ 253 - 0
src/pages/order/businessFormal.vue

@@ -0,0 +1,253 @@
+<template>
+    <view class="lifePhotosEdit">
+
+        <view class="u-cell-group">
+            <!-- <Upload :maxCount="1" @fileList="onUpload($event, 'cImgList')" /> -->
+            <Upload :maxCount="maxCount" :width="76" :height="76" @fileList="onUpload"
+                :fileList="fileList">
+                <view class="upload-block" slot="content">
+
+                    <view class="icon-bg">
+                        <image src="/static/login/cameraIcon.png" mode="widthFix" style="width: 52rpx;height: 52rpx;">
+                        </image>
+                        <view style="font-weight: 400;font-size: 26rpx;color: #C9CDD4;margin-top: -13rpx;">上传</view>
+
+                    </view>
+
+                </view>
+            </Upload>
+            <view class="tagText">请上传到达服务场所后的职业正装大小不超过 2MB 格式为 jpg/png 格式图片</view>
+
+
+
+            <view class="footer-bar">
+                <u-button :customStyle="{
+                    padding: '24rpx 48rpx',
+                    color: '#fff',
+                    background: 'var(--theme-color-gradient)',
+                    width: '654rpx',
+                    height: '88rpx',
+                    background: '#333335',
+                    borderRadius: '60rpx 60rpx 60rpx 60rpx',
+                }" @click="onSubmit">确认</u-button>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script>
+import { startService } from '@/api/order.js'
+import clUpload from '@/components/cl-upload/cl-upload/cl-upload.vue'
+import Upload from '@/components/upload/index.vue';
+import { baseUrl } from '@/common/config.js'
+
+export default {
+    components: { Upload, clUpload },
+
+    data() {
+        return {
+            headers: {
+                Authorization: `tf: ${uni.getStorageSync('access-token')}`,
+            },
+            orderId: '',
+            fileList: [],
+            fieldName: '',
+            title: '',
+            mediaType: 'all', // 默认为图片模式,上传第一个文件后确定类型
+            uploadApi: baseUrl + '/common/upload', // 默认使用图片上传接口
+        }
+    },
+    computed: {
+        maxCount() {
+            return 9
+        },
+    },
+
+    onLoad(query) {
+        if (query.orderId) {
+            this.orderId = query.orderId
+        }
+
+    },
+    onReady() {
+
+    },
+    onShow() {
+    },
+    methods: {
+
+        // 处理媒体类型取消事件
+        onCancel() {
+            this.uploadApi = baseUrl + '/common/uploads'
+            this.mediaType = 'all'
+        },
+
+        // upload事件
+        onUpload(e) {
+            this.fileList = e
+        },
+        goBack() {
+            uni.navigateBack()
+        },
+        onSubmit() {
+            console.log(this.fileList, 'fileList')
+            if (this.fileList.length == 0) {
+                uni.showToast({ title: '请至少上传1张', icon: 'none' });
+                return
+            }
+            startService({
+                orderId: this.orderId,
+                imageUrls: this.fileList.map(item => item.url)
+            }).then(res => {
+                if (res.data.code === 200) {
+                    uni.showToast({ title: res.data.msg, icon: 'none' });
+                    setTimeout(() => {
+                        let str = uni.$u.queryParams({
+                            id:  this.orderId
+                        });
+                        uni.navigateTo({
+                            url: `/pages/order/order_detail${str}`
+                        });
+                    }, 1000);
+
+                }else{
+                    uni.showToast({ title: res.data.msg, icon: 'none' });
+                }
+            })
+        }
+
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.lifePhotosEdit {
+    height: 100vh;
+    background-color: #F7F8FA;
+
+    .tagText {
+        margin-top: 32rpx;
+        font-weight: 400;
+        font-size: 26rpx;
+        color: #86909C;
+    }
+
+    .checkBox {
+        padding: 30rpx 32rpx 24rpx 32rpx;
+        height: 134rpx;
+        border-radius: 8rpx 8rpx 8rpx 8rpx;
+
+        //color: #FF7D00;
+        .checkStatus {
+            font-weight: 500;
+            font-size: 30rpx;
+            text-align: left;
+            display: flex;
+            align-items: center;
+
+        }
+
+        .contactCustomer {
+            width: 144rpx;
+            height: 44rpx;
+            border-radius: 24rpx 24rpx 24rpx 24rpx;
+
+            font-weight: 400;
+            font-size: 26rpx;
+            text-align: center;
+
+        }
+
+        .text {
+            margin-top: 8rpx;
+            font-weight: 400;
+            font-size: 26rpx;
+            text-align: left;
+        }
+    }
+
+    ::v-deep .u-cell-group {
+        padding: 32rpx;
+        background-color: #fff;
+
+        .upload-block {
+            width: 160rpx;
+            height: 160rpx;
+            background-color: #F7F8FA;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            border-radius: 12rpx;
+        }
+
+        .u-upload__wrap {
+            display: flex;
+            flex-wrap: wrap;
+            justify-content: flex-start;
+            gap: 14rpx;
+        }
+
+        .u-upload__button {
+            margin: 0 !important;
+        }
+
+        .u-upload__wrap__preview {
+            margin: 0 !important;
+        }
+
+        .u-upload__success {
+            display: none;
+        }
+    }
+}
+
+::v-deep .u-upload__success {
+    display: none;
+}
+
+::v-deep .u-upload__wrap__preview__image {
+    border-radius: 12rpx !important;
+}
+
+::v-deep .u-upload__deletable {
+    border-top-right-radius: 12rpx;
+    border-bottom-left-radius: 12rpx;
+
+}
+
+::v-deep .u-upload__deletable__icon {
+    position: static !important;
+    -webkit-transform: scale(0.8) !important;
+
+}
+
+.media-area {
+    margin: 20rpx 0 20rpx;
+    justify-content: space-between;
+    position: relative;
+    width: 340upx;
+    height: 240upx;
+
+    .icon-cuo {
+        width: 40rpx;
+        height: 40rpx;
+        position: absolute;
+        right: 0;
+        top: 0;
+        color: #ffffff !important;
+        z-index: 999;
+        border-bottom-left-radius: 12rpx;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+    }
+
+
+
+    .video-container {
+        width: 340upx;
+        height: 240upx;
+        border-radius: 12rpx;
+    }
+}
+</style>

+ 225 - 0
src/pages/order/cancelOrder.vue

@@ -0,0 +1,225 @@
+<template>
+    <view class="page-container">
+
+        <view scroll-y class="content">
+            <!-- 取消原因选择 -->
+            <view class="cancel-section">
+                <text class="section-title">选择取消原因</text>
+
+                <view class="reason-item" v-for="(item, index) in reasonList" :key="index" @click="selectReason(index)">
+                    <view class="radio" :class="{ active: selectedIndex === index }">
+                        <image v-if="selectedIndex === index" src="/static/workbench/radio.png" mode="aspectFill" />
+                    </view>
+                    <text class="reason-text">{{ item }}</text>
+                </view>
+
+                <!-- 其它原因输入框 -->
+                <view v-if="selectedIndex === reasonList.length - 1" class="other-input">
+                    <textarea class="textarea" placeholder="请输入其他原因" v-model="otherReason"></textarea>
+                </view>
+            </view>
+        </view>
+
+        <!-- 底部按钮 -->
+        <view class="bottom-buttons">
+            <view class="btn btn-confirm" @click="confirmCancel">确认拒绝</view>
+        </view>
+    </view>
+</template>
+
+<script>
+import { cancelOrderReason, cancelOrder } from '@/api/order'
+import { onShow } from '@dcloudio/uni-app';
+export default {
+    data() {
+        return {
+            reasonList: [],
+            selectedIndex: -1,
+            otherReason: '',
+            orderId: '',
+            orderStatus: ''
+        }
+    },
+    onLoad(options) {
+       if(options.orderId) this.orderId = options.orderId
+       if(options.orderStatus) this.orderStatus = options.orderStatus
+    },
+    onShow() {
+        this.cancelOrderReason('3')
+    },
+    methods: {
+        cancelOrderReason(type) {
+            cancelOrderReason(type).then(res => {
+                if (res.data.code == 200) {
+                    this.reasonList = res.data.data || [];
+                }
+            })
+        },
+
+        selectReason(index) {
+            this.selectedIndex = index
+        },
+        confirmCancel() {
+            if (this.orderStatus==2) {
+                uni.showToast({
+                    title: '操作失败,请重试刷新当前页面',
+                    icon: 'none'
+                })
+            }
+
+            // 验证是否选择了原因
+            if (this.selectedIndex === -1) {
+                uni.showToast({
+                    title: '请选择取消原因',
+                    icon: 'none'
+                })
+                return
+            }
+
+            // 如果选择了"其它",验证是否填写了原因
+            if (this.selectedIndex === this.reasonList.length - 1 && !this.otherReason.trim()) {
+                uni.showToast({
+                    title: '请填写其他原因',
+                    icon: 'none'
+                })
+                return
+            }
+            let cancelReason = ''
+            if (this.selectedIndex === this.reasonList.length - 1) {
+                cancelReason = this.otherReason
+            } else {
+                cancelReason = this.reasonList[this.selectedIndex]
+            }
+
+            cancelOrder({
+                orderId: this.orderId,
+                cancelReason: cancelReason
+            }).then(res => {
+                if (res.data.code === 200) {
+                    uni.showToast({ title: res.data.msg, icon: 'none' });
+                    setTimeout(() => {
+                        uni.navigateBack({
+                            delta: 1
+                        })
+                    }, 1000)
+
+                } else {
+                    uni.showToast({
+                        title: res.data.msg || '取消失败',
+                        icon: 'none'
+                    })
+                }
+            })
+        }
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.page-container {
+    min-height: 100vh;
+    background: #F7F8FA;
+    width: 100%;
+}
+
+
+.content {
+    padding: 32rpx;
+    width: 100%;
+}
+
+.cancel-section {
+    background: #FFFFFF;
+    border-radius: 16rpx;
+    padding: 32rpx;
+    width: 100%;
+
+    .section-title {
+        font-weight: 500;
+        font-size: 36rpx;
+        color: #1D2129;
+        display: block;
+    }
+
+    .reason-item {
+        display: flex;
+        align-items: center;
+        margin-top: 32rpx;
+
+        .radio {
+            width: 36rpx;
+            height: 36rpx;
+            border-radius: 50%;
+            border: 1rpx solid #C0C4CC;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            margin-right: 24rpx;
+            flex-shrink: 0;
+
+
+            image {
+                width: 36rpx;
+                height: 36rpx;
+            }
+
+            &.active {
+                // border-color: #07C160;
+                // background: #07C160;
+            }
+        }
+
+        .reason-text {
+            font-weight: 400;
+            font-size: 28rpx;
+            color: #4E5969;
+        }
+    }
+
+    .other-input {
+        margin-top: 20rpx;
+
+        width: 100%;
+
+        .textarea {
+            height: 200rpx;
+            background: #F7F8FA;
+            border-radius: 8rpx 8rpx 8rpx 8rpx;
+            box-sizing: border-box;
+            font-weight: 400;
+            font-size: 28rpx;
+            color: #4E5969;
+            padding: 16rpx;
+        }
+    }
+}
+
+.bottom-buttons {
+    position: fixed;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    padding: 24rpx 48rpx;
+    background: #FFFFFF;
+    border-top: 1rpx solid #F0F0F0;
+
+    .btn {
+        width: 100%;
+        height: 88rpx;
+        border-radius: 44rpx;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        font-weight: 500;
+        font-size: 32rpx;
+
+        &.btn-confirm {
+            background: #333335;
+            font-weight: 500;
+            font-size: 32rpx;
+            color: #FFFFFF;
+            text-align: center;
+        }
+    }
+}
+</style>

+ 401 - 0
src/pages/order/moneyDetail.vue

@@ -0,0 +1,401 @@
+<template>
+  <view class="page-container">
+
+
+    <scroll-view scroll-y class="content">
+      <!-- 进度条 -->
+      <view class="progress-section">
+        <view class="progress-bar">
+          <view class="progress-step active">
+            <view class="step-dot">
+              <image src="/static/workbench/checkIcon.png" mode="aspectFill" style="width: 32rpx; height: 32rpx;" />
+            </view>
+            <text class="step-label">申请退款</text>
+          </view>
+          <view class="progress-line active"></view>
+          <view class="progress-step active">
+            <view class="step-dot">
+              <image src="/static/workbench/checkIcon.png" mode="aspectFill" style="width: 32rpx; height: 32rpx;" />
+            </view>
+            <text class="step-label">平台处理</text>
+          </view>
+          <view class="progress-line"></view>
+          <view class="progress-step">
+            <view class="step-dot" v-if="false">
+              <image src="/static/workbench/checkIcon.png" mode="aspectFill" style="width: 32rpx; height: 32rpx;" />
+
+            </view>
+            <text class="step-label">申请退款</text>
+          </view>
+        </view>
+      </view>
+
+      <!-- 退款状态 -->
+      <view class="status-section">
+        <view class="status-title">拒绝退款</view>
+        <view class="status-reason">拒绝原因拒绝原因拒绝原因拒绝原因拒绝原因拒绝原因拒绝原因拒绝原因拒绝原因拒绝原因拒绝原因拒绝原因拒绝原因拒绝原因拒绝原因拒绝原因</view>
+      </view>
+
+      <!-- 服务项目 -->
+      <view class="service-section">
+        <view class="service-item" v-for="(item, index) in serviceList" :key="index">
+          <image :src="item.image" mode="aspectFill" style="width: 96rpx; height: 96rpx;border:1px solid red" />
+          <view class="service-info">
+            <text class="service-name">{{ item.name }}</text>
+          </view>
+          <text class="service-price">
+            <text style="font-size: 20rpx;">¥</text>
+            {{ item.price }}</text>
+        </view>
+        <view class="info-row">
+          <text class="info-label">服务状态</text>
+          <text class="info-value">服务中</text>
+        </view>
+        <view class="info-row">
+          <text class="info-label">服务数量</text>
+          <text class="info-value">1</text>
+        </view>
+        <view class="info-row">
+          <text class="info-label">退款数量</text>
+          <text class="info-value">1</text>
+        </view>
+        <view class="info-row">
+          <text class="info-label">联系信息</text>
+          <text class="info-value">张先生,132 **** 5200</text>
+        </view>
+        <view class="info-row">
+          <text class="info-label">联系地址</text>
+          <text class="info-value">北京市朝阳区慧忠路8号奥运村附近亚奥观典大厦B座2506</text>
+        </view>
+        <view class="info-row">
+          <text class="info-label">退款原因</text>
+          <text class="info-value">原因原因原因原因</text>
+        </view>
+      </view>
+
+      <!-- 订单信息 -->
+      <view class="order-section">
+        <text class="section-title">订单信息</text>
+        <view class="order-info">
+          <view class="order-row">
+            <text class="order-label">订单编号</text>
+            <view class="order-value-wrapper">
+              <view class="order-value">5017036467099547354</view>
+              <view style="width: 0;height: 24rpx;border: 0.5rpx solid #86909C;margin: 0 8rpx;"></view>
+              <view class="copy-btn" @click="copyOrderNo">复制</view>
+            </view>
+          </view>
+          <view class="order-row">
+            <text class="order-label">下单时间</text>
+            <text class="order-value">2026.01.27 10:32:51</text>
+          </view>
+          <view class="order-row">
+            <text class="order-label">付款时间</text>
+            <text class="order-value">2026.01.27 10:32:51</text>
+          </view>
+          <view class="order-row">
+            <text class="order-label">完成时间</text>
+            <text class="order-value">2026.01.27 10:32:51</text>
+          </view>
+        </view>
+      </view>
+
+      <!-- 底部订单编号 -->
+      <view class="bottom-order-no">
+        <view class="order-row">
+          <text class="order-label">订单编号</text>
+          <view class="order-value-wrapper">
+            <view class="order-value">5017036467099547354</view>
+            <view class="arrow">
+              <image src="/static/workbench/right.png" mode="aspectFill" style="width: 22rpx; height: 22rpx;" />
+            </view>
+          </view>
+        </view>
+      </view>
+    </scroll-view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      serviceList: [
+        {
+          image: '/static/images/massage.png',
+          name: '中式按摩(60分钟)',
+          price: '493.4'
+        }
+      ],
+      orderNo: '5017036467099547354'
+    }
+  },
+  methods: {
+    goBack() {
+      uni.navigateBack()
+    },
+    copyOrderNo() {
+      uni.setClipboardData({
+        data: this.orderNo,
+        success: () => {
+          uni.showToast({
+            title: '复制成功',
+            icon: 'success'
+          })
+        }
+      })
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.page-container {
+  min-height: 100vh;
+  background: #F5F5F5;
+}
+
+
+.content {
+  height: calc(100vh - 88rpx);
+
+}
+
+.progress-section {
+  height: 212rpx;
+  background: linear-gradient(180deg, #FFEFE8 0%, #F7F8FA 100%);
+  padding: 32rpx 32rpx 0rpx 32rpx;
+}
+
+.progress-bar {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.progress-step {
+  display: flex;
+  align-items: center;
+
+  .step-dot {
+    width: 32rpx;
+    height: 32rpx;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin-right: 8rpx;
+  }
+
+  .step-label {
+
+    font-weight: 400;
+    font-size: 32rpx;
+    color: #86909C;
+  }
+
+  &.active {
+    .step-dot {}
+
+    .step-label {
+      font-weight: 500;
+      color: #1D2129;
+    }
+  }
+}
+
+.progress-line {
+  flex: 1;
+  width: 102rpx;
+  height: 0rpx;
+  border: 1rpx solid #86909C;
+  margin: 0 14rpx;
+
+  &.active {
+    border: 1rpx solid #1D2129;
+  }
+}
+
+.status-section {
+  background: #FFFFFF;
+  border-radius: 16rpx;
+  padding: 32rpx;
+  margin: 0 32rpx;
+  margin-top: -104rpx;
+
+  .status-title {
+    font-weight: 600;
+    font-size: 40rpx;
+    color: #1D2129;
+    text-align: center;
+  }
+
+  .status-reason {
+    margin-top: 8rpx;
+    font-weight: 400;
+    font-size: 26rpx;
+    color: #86909C;
+  }
+}
+
+.service-section {
+  background: #FFFFFF;
+  border-radius: 16rpx;
+  padding: 32rpx;
+  margin: 16rpx 32rpx 0 32rpx;
+
+  .service-item {
+    display: flex;
+
+    .service-image {
+      width: 100rpx;
+      height: 100rpx;
+      border-radius: 8rpx;
+    }
+
+    .service-info {
+      flex: 1;
+      margin-left: 24rpx;
+
+      .service-name {
+        font-weight: 500;
+        font-size: 30rpx;
+        color: #1D2129;
+      }
+    }
+
+    .service-price {
+      font-weight: 400;
+      font-size: 28rpx;
+      color: #1D2129;
+    }
+  }
+
+  .info-row {
+    display: flex;
+    justify-content: space-between;
+    align-items: flex-start;
+    margin-top: 24rpx;
+
+    &:last-child {
+      border-bottom: none;
+    }
+
+    .info-label {
+      font-weight: 400;
+      font-size: 28rpx;
+      color: #4E5969;
+    }
+
+    .info-value {
+      font-weight: 400;
+      font-size: 28rpx;
+      color: #1D2129;
+      text-align: right;
+      flex: 1;
+      margin-left: 20rpx;
+      word-break: break-all;
+      white-space: normal;
+      line-height: 1.5;
+    }
+  }
+}
+
+
+.order-section {
+  background: #FFFFFF;
+  border-radius: 16rpx;
+  padding: 32rpx;
+  margin: 16rpx 32rpx 0 32rpx;
+
+
+  .section-title {
+    font-weight: 500;
+    font-size: 32rpx;
+    color: #1D2129;
+    display: block;
+  }
+
+  .order-info {
+    .order-row {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-top: 24rpx;
+
+      .order-label {
+        font-weight: 400;
+        font-size: 28rpx;
+        color: #4E5969;
+        flex-shrink: 0;
+      }
+
+      .order-value-wrapper {
+        display: flex;
+        align-items: center;
+
+        .order-value {
+          font-weight: 400;
+          font-size: 28rpx;
+          color: #1D2129;
+        }
+
+        .copy-btn {
+          font-weight: 400;
+          font-size: 28rpx;
+          color: #19D29B;
+        }
+
+        .arrow {
+          font-weight: 400;
+          font-size: 28rpx;
+          color: #C0C4CC;
+        }
+      }
+
+      .order-value {
+        font-weight: 400;
+        font-size: 28rpx;
+        color: #1D2129;
+      }
+    }
+  }
+}
+
+.bottom-order-no {
+  background: #FFFFFF;
+  border-radius: 16rpx;
+  padding: 32rpx;
+  margin: 16rpx 32rpx 0 32rpx;
+
+  .order-row {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    .order-label {
+      font-weight: 400;
+      font-size: 28rpx;
+      color: #4E5969;
+    }
+
+    .order-value-wrapper {
+      display: flex;
+      align-items: center;
+
+      .order-value {
+        font-weight: 400;
+        font-size: 28rpx;
+        color: #1D2129;
+      }
+
+      .arrow {
+        font-weight: 400;
+        font-size: 28rpx;
+        color: #C0C4CC;
+        margin-right: -5rpx;
+        margin-left: 6rpx;
+      }
+    }
+  }
+}
+</style>

+ 242 - 0
src/pages/order/moneyRecord.vue

@@ -0,0 +1,242 @@
+<template>
+  <view class="page-container">
+
+    <view class="content">
+      <!-- 退款金额 -->
+      <view class="amount-section">
+        <text class="amount">¥128.00</text>
+        <text class="refund-type">原路退回</text>
+      </view>
+
+      <!-- 订单信息 -->
+      <view class="info-section">
+        <view class="info-item">
+          <view class="info-label">退款订单编号</view>
+          <view class="info-value">TK202502501212562300127</view>
+        </view>
+        <view class="info-item">
+          <view class="info-label">申请订单时间</view>
+          <view class="info-value">2025.12.23 16:00:45</view>
+        </view>
+        <view class="info-item">
+          <view class="info-label">申请时间</view>
+          <view class="info-value">2025.12.23 16:00:45</view>
+        </view>
+        <view class="info-item">
+          <view class="info-label">申请时间</view>
+          <view class="info-value">2025.12.23 16:00:45</view>
+        </view>
+      </view>
+
+      <!-- 操作时间线 -->
+      <view class="timeline-section">
+        <text class="section-title">操作时间</text>
+        <view class="timeline">
+          <view class="timeline-item" v-for="(item, index) in timelineData" :key="index">
+            <view class="timeline-dot">
+              <image src="/static/workbench/timeLineIcon.png" style="width: 30rpx;height: 30rpx;" mode="aspectFill" />
+
+            </view>
+            <view class="timeline-content">
+              <text class="timeline-title">{{ item.title }}</text>
+              <text class="timeline-time">{{ item.time }}</text>
+            </view>
+            <view v-if="index < timelineData.length - 1" class="timeline-line"></view>
+          </view>
+        </view>
+      </view>
+
+      <!-- 查看详情按钮 -->
+      <view class="btn-section">
+        <view class="btn-detail" @click="goDetail">查看退款详情</view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      timelineData: [
+        {
+          title: '申请退款',
+          time: '2025.12.23 16:00:45'
+        },
+        {
+          title: '平台审核',
+          time: '2025.02.02 12:22:00'
+        },
+        {
+          title: '同意退款',
+          time: '2025.02.02 12:22:00'
+        }
+      ]
+    }
+  },
+  methods: {
+    goBack() {
+      uni.navigateBack()
+    },
+    goDetail() {
+      // 跳转到退款详情页面
+      uni.navigateTo({
+				url: '/pages/order/moneyDetail'
+				//url: '/pages/order/moneyDetail?id=' + this.id
+			})
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.page-container {
+  min-height: 100vh;
+  background: #FFFFFF;
+}
+
+.content {}
+
+.amount-section {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding: 48rpx 0 64rpx 0;
+  background: #FFFFFF;
+
+  .amount {
+    font-weight: 600;
+    font-size: 60rpx;
+    color: #1D2129;
+    text-align: center;
+  }
+
+  .refund-type {
+    font-weight: 400;
+    font-size: 30rpx;
+    color: #1D2129;
+    text-align: center;
+  }
+}
+
+.info-section {
+  background: #FFFFFF;
+  padding: 0 32rpx;
+
+  .info-item {
+    padding-bottom: 32rpx;
+    display: flex;
+    align-items: center;
+
+    &:last-child {
+      border-bottom: none;
+    }
+
+    .info-label {
+      font-weight: 400;
+      font-size: 30rpx;
+      color: #86909C;
+      text-align: left;
+      width: 182rpx;
+    }
+
+    .info-value {
+      font-weight: 400;
+      font-size: 30rpx;
+      color: #1D2129;
+      margin-left: 32rpx;
+    }
+  }
+}
+
+.timeline-section {
+  background: #FFFFFF;
+  border-radius: 16rpx;
+  padding: 0 32rpx 80rpx 32rpx;
+  display: flex;
+
+  .section-title {
+    width: 182rpx;
+    font-weight: 400;
+    font-size: 30rpx;
+    color: #86909C;
+    text-align: left;
+  }
+
+  .timeline {
+    position: relative;
+    margin-left: 32rpx;
+    padding-left: 40rpx;
+  }
+
+  .timeline-item {
+    position: relative;
+    padding-bottom: 32rpx;
+
+    &:last-child {
+      padding-bottom: 0;
+    }
+
+    .timeline-dot {
+      position: absolute;
+      left: -40rpx;
+      top: 10rpx;
+      width: 30rpx;
+      height: 30rpx;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+
+      .dot-inner {
+        width: 16rpx;
+        height: 16rpx;
+        border-radius: 50%;
+        background: #FFFFFF;
+      }
+    }
+
+    .timeline-content {
+      display: flex;
+      flex-direction: column;
+
+      .timeline-title {
+        font-weight: 400;
+        font-size: 30rpx;
+        color: #1D2129;
+      }
+
+      .timeline-time {
+        font-weight: 400;
+        font-size: 22rpx;
+        color: #86909C;
+        margin-top: 16rpx;
+      }
+    }
+
+    .timeline-line {
+      position: absolute;
+      left: -28rpx;
+      top: 44rpx;
+      height: calc(100% - 40rpx);
+      border: 1rpx dashed #86909C;
+    }
+  }
+}
+
+.btn-section {
+  padding: 0 64rpx;
+
+  .btn-detail {
+    height: 88rpx;
+    line-height: 88rpx;
+    text-align: center;
+    background: #FFFFFF;
+    border-radius: 60rpx 60rpx 60rpx 60rpx;
+    border: 1rpx solid #333335;
+    font-weight: 500;
+    font-size: 32rpx;
+    color: #1D2129;
+    text-align: center;
+  }
+}
+</style>

Разница между файлами не показана из-за своего большого размера
+ 756 - 227
src/pages/order/order.vue


+ 799 - 1413
src/pages/order/order_detail.vue

@@ -1,1530 +1,916 @@
 <template>
-	<view class="details">
-		<view class="content">
-			<view class="order_status">
-				<view class="status_center">
-					<view class="status">
-						订单{{details.statusName}}
-						<text class="money">
-							¥<text>{{details.dTotalMoney}}</text>
-						</text>
-					</view>
-					<view class="time" v-if="details.nStatus == -3">
-						拒绝原因: {{details.reasonRefusal}}
-					</view>
-					<view class="time" v-else>
-						上门时间:{{details.reachTime}}
-					</view>
-					<view class="merchant">
-						服务商家:{{details.js.cNickName}}<br />
-						<text>商家电话:{{details.jsPhone}}</text>
-					</view>
-				</view>
+	<view class="order-detail-page">
+
+		<!-- 高风险区域提示 isHighRiskArea-->
+		<view v-if="orderDetail.isHighRiskArea" class="risk-tip">
+			<view style="width: 28rpx;margin-top: -5rpx;margin-right: 8rpx;">
+				<image src="/static/workbench/warringIcon.png" style="width: 28rpx;height: 28rpx;" mode="widthFill" />
 			</view>
-			<view class="orderinfo">
-				<view class="order_box">
-					<view class="title"><text></text> 服务项目</view>
-					<view class="project" v-for="(item,index) in details.cGoods" :key="index">
-						<view class="project_left">
-							<img :src="$globalData.publicUrl + item.cCover" alt="" />
-						</view>
-						<view class="project_right">
-							<text class="name">项目名称:{{item.cTitle}}</text>
-							<text class="price"> 项目单价:{{item.dPrice}}</text>
-							<view class="total">
-								数量:{{item.number}}
-								<span class="total_price">¥{{details.totalPrice}}</span>
-							</view>
-						</view>
-					</view>
+
+			<view class="risk-text">{{ orderDetail.fenceIntro }}</view>
+		</view>
+
+		<!-- 待接单状态卡片 -->
+		<view class="status-card">
+			<view class="status-title">
+				<image v-if="orderDetail.orderStatus == 5" src="/static/workbench/finishIcon.png"
+					style="width: 48rpx;height: 48rpx;margin-right: 8rpx;" mode="aspectFill" />
+				<image v-if="orderDetail.orderStatus == 4" src="/static/workbench/serviceingIcon.png"
+					style="width: 48rpx;height: 48rpx;margin-right: 8rpx;" mode="aspectFill" />
+				<view v-if="orderDetail.orderStatus == 3" style="display: flex;align-items: center;">
+					<image v-if="orderDetail.execStatus === 0" src="/static/workbench/noGoIcon.png"
+						style="width: 48rpx;height: 48rpx;margin-right: 8rpx;" mode="aspectFill" />
+					<image v-if="orderDetail.execStatus === 0" src="/static/workbench/noSignIcon.png"
+						style="width: 48rpx;height: 48rpx;margin-right: 8rpx;" mode="aspectFill" />
+					<image v-if="orderDetail.execStatus === 1" src="/static/workbench/goedIcon.png"
+						style="width: 48rpx;height: 48rpx;margin-right: 8rpx;" mode="aspectFill" />
+					<image v-if="orderDetail.execStatus === 2" src="/static/workbench/arriveIcon.png"
+						style="width: 48rpx;height: 48rpx;margin-right: 8rpx;" mode="aspectFill" />
+					<image v-if="orderDetail.execStatus === 2" src="/static/workbench/signIcon.png"
+						style="width: 48rpx;height: 48rpx;margin-right: 8rpx;" mode="aspectFill" />
+
 				</view>
+				<image v-if="orderDetail.orderStatus == 2" src="/static/workbench/orderIcon.png"
+					style="width: 48rpx;height: 48rpx;margin-right: 8rpx;" mode="aspectFill" />
+
 
-				<!-- <view v-for="(item,index) in details.cGoods" :key="index" class="items">
-					<view class="img">
-						<image :src="$globalData.publicUrl + item.cCover" mode=""></image>
+				<view class="status-text">
+					<view v-if="orderDetail.orderStatus == 2" style="color: #FF531C;">待接单</view>
+
+					<!-- 3:待服务  待出发\待签到\已出发\已到达\已签到 -->
+					<view v-if="orderDetail.orderStatus == 3">
+						<view v-if="orderDetail.execStatus === 0">待出发/待签到</view>
+						<view v-if="orderDetail.execStatus === 1">已出发</view>
+						<view v-if="orderDetail.execStatus === 2">已到达/已签到</view>
 					</view>
-					<view class="right">
-						<view class="">
-							项目名称:{{item.cTitle}}
-						</view>
-						<view class="">
-							项目单价:{{item.dPrice}}
-						</view>
-						<view class="">
-							数量:{{item.number}}
-						</view>
+					<view v-if="orderDetail.orderStatus == 4">服务中</view>
+					<view v-if="orderDetail.orderStatus == 5">已完成</view>
+					<view v-if="orderDetail.orderStatus == 9">
+						<view>售后</view>
+
 					</view>
 				</view>
-				<view class="conts">合计:{{details.totalPrice}}</view> -->
 			</view>
-			<!-- 			<view class="box1">
-				<view class="imgs">
-					<image src="/static/order/deimg.jpg" mode="widthFix" />
-				</view>
-				<view class="box1cont">
-					<view class="title">订单{{details.statusName}}</view>
-					<view class="moneytime" v-if="!details.reasonRefusal == ''">
-						拒绝原因: {{details.reasonRefusal}}
-					</view>
-					<view class="moneytime">
-						<view class="time">下单日期: {{dtCreateTime}}</view>
-						<view class="money">¥{{details.dTotalMoney}}</view>
+			<view class="count-down" v-if="orderDetail.orderStatus == 5">订单服务已完成,请联系客户给出好评</view>
+			<view v-else class="count-down">倒计时<span class="red-text">1小时59分</span></view>
+		</view>
+
+		<!-- 订单已退金额 -->
+		<view v-if="orderDetail.actualRefundAmount" class="refund-amount" @click="goMoneyRecord">
+			订单已退金额
+			<view class="refund-amount-text">
+				<view>¥{{ orderDetail.actualRefundAmount }}</view>
+				<image src="/static/workbench/rightIcon.png" style="width: 24rpx;height: 24rpx;" mode="aspectFill" />
+
+			</view>
+		</view>
+
+		<!-- 用户信息模块 -->
+		<view class="user-info">
+			<view class="row2">
+				<view style="display: flex;align-items: center;">
+					<image src="/static/workbench/peopleIcon1.png"
+						style="width: 32rpx;height: 32rpx;margin-right: 16rpx;" mode="aspectFill" />
+					<view>
+						{{ orderDetail.contactPersonName }} {{ orderDetail.contactPhoneNumber }}
 					</view>
+
 				</view>
-			</view> -->
-			<view class="orderinfo">
-				<view class="order_box order_detail">
-					<view class="title"><text></text> 订单信息</view>
-					<view class="cont"><text class="left_title">客户姓名:</text>
-						<text>{{details.cName}}</text>
-					</view>
-					<view class="cont">
-						<text class="left_title">客户电话:</text>
-						<text class="right_content" @click="dial(details.cPhone)">{{details.cPhone}}
-						</text>
-					</view>
-					<view class="cont"><text class="left_title">服务商家:</text> <text
-							class="right_content">{{details.js.cNickName}}</text></view>
-					<view class="cont" v-if="!dtCreateTime1 == ''"><text class="left_title">下单时间:</text>
-						<text>{{dtCreateTime1}}</text>
-					</view>
-					<view class="cont" v-if="!acceptanceTime == ''"><text class="left_title">接单时间:</text>
-						<text>{{acceptanceTime}}</text>
-					</view>
-					<view class="cont" v-if="!reachTime == ''"><text class="left_title">到达时间:</text> <text>{{reachTime}}</text>
-					</view>
-					<view class="cont" v-if="!startTime == ''"><text class="left_title">开始服务时间:</text> <text>{{startTime}}</text>
-					</view>
-					<view class="cont" v-if="!endTime == ''"><text class="left_title">完成订单时间:</text> <text>{{endTime}}</text>
-					</view>
-					<view class="cont"><text class="left_title">车费详情:</text> <text>{{details.fare || 0}}元</text></view>
-					<view class="cont"><text class="left_title">服务地址:</text> <text> {{details.address}}</text></view>
+				<view class="phone-icon">
+					<image src="/static/workbench/phoneIcon.png" style="width: 21.49rpx;height: 21.53rpx;"
+						mode="aspectFill" />
 				</view>
 			</view>
-<!-- 暂时注释,无用代码   xueyh-->
-<!--			<view class="sub_box">-->
-<!--				<view class="cancel">-->
-<!--					取消订单-->
-<!--				</view>-->
-<!--				&lt;!&ndash; 	<view class="edit_time">-->
-<!--					修改上门时间-->
-<!--				</view> &ndash;&gt;-->
-<!--			</view>-->
-			<view class="orderinfo" v-if="name == '商户订单'">
-				<view class="title">客户标签</view>
-				<view class="comment_box">
-					<view class="comment" v-for="(item,index) in userCommentList" :key="index">
-						{{item.text}}
-					</view>
+			<view class="row1" @click="goDetails(item.cId)">
+				<view style="display: flex;align-items: center;">
+					<image src="/static/workbench/clockIcon2.png"
+						style="width: 32rpx;height: 32rpx;margin-right: 16rpx;" mode="aspectFill" />
+					{{ orderDetail.appointmentTimeRange }}
 				</view>
+
 			</view>
 
-			<!-- <view style="height: 300rpx;"></view> -->
+
+			<view class="row3">
+				<image src="/static/workbench/localIcon3.png" style="width: 32rpx;height: 32rpx;margin-right: 16rpx;"
+					mode="aspectFill" />
+
+				{{ orderDetail.contactAddressInfo }}
+				<text class="cont">{{ orderDetail.distanceKm }}km</text>
+			</view>
 		</view>
-		<view v-if="name == '商户订单'">
-			<view class="btnbox" v-if="details.nStatus === 0">
-				<!-- <view @click="scheduling((details.cId))">了解客户</view> -->
-				<view @click="scheduling((details.cId))">接单</view>
-				<view @click="refuse((details.cId))">拒绝接单</view>
+
+		<!-- 服务项目卡片 -->
+		<view class="row4">
+			<view>
+				<image :src="orderDetail.projectCover" mode="aspectFill"
+					style="border: 1px solid red;width: 96rpx;height: 96rpx;border-radius: 8rpx;" />
 			</view>
-			<view class="btnbox" v-if="details.nStatus === 1">
-				<view @click="depart(details.cId,details.orderNo)">出发</view>
+			<view
+				style="display: flex;flex-direction: column;flex: 1;justify-content: space-between;margin-left: 24rpx;">
+				<view style="display: flex; justify-content: space-between;">
+					<view class="title">{{ orderDetail.projectName }}({{ orderDetail.projectDuration }}分钟)</view>
+					<view class="cont">
+						<view style="font-size: 20rpx;">¥</view>
+						{{ orderDetail.finalAmount }}
+					</view>
+				</view>
+				<view v-if="orderDetail.orderStatus == 9">
+					<view v-if="orderDetail.afterSalesServiceStatus == '退款中'" class="refundStatus1">退款中
+					</view>
+					<view class="refundStatus2">{{ orderDetail.afterSalesServiceStatus }}
+					</view>
+
+				</view>
+
 			</view>
-			<view class="btnbox" v-if="details.nStatus === 6">
-				<view @click="arriveOderLocation(details.cId,details.orderNo)">到达</view>
+
+		</view>
+
+		<!-- 费用明细 -->
+		<view class="price-card">
+			<view class="title">
+				<view>订单金额</view>
+				<view style="font-size: 32rpx;font-weight: bold;">¥{{ orderDetail.basePrice }}</view>
 			</view>
-			<view class="btnbox" v-if="details.nStatus === 2">
-				<view @click="enterService(details.cId,details.orderNo)">开始服务</view>
+			<view class="title">订单总金额 <view class="cont">¥{{ orderDetail.finalAmount }}</view>
 			</view>
-			<view class="btnbox" v-if="details.nStatus === 3">
-				<view @click="complete(details.cId,details.orderNo)">完成订单</view>
+			<view class="title" v-if="orderDetail.trafficFee">交通费 <view class="cont">¥{{ orderDetail.trafficFee }}
+				</view>
 			</view>
-			<view class="btnbox" v-if="details.nStatus === 4">
-				<view @click="appraise(details,details.cId,details.orderNo)">评价顾客</view>
+			<view class="title" v-if="orderDetail.couponPrice">优惠券 <view class="cont">¥{{ orderDetail.couponPrice }}
+				</view>
 			</view>
 		</view>
-		<view v-else>
-			<view class="btnbox" v-if="details.nStatus === -1">
-				<!-- <view @click="nowYuyue(details.cId,details.dTotalMoney)">支付订单</view> -->
+
+		<!-- 订单基础信息 -->
+		<view class="order-info-card">
+			<view class="info-title">订单信息</view>
+			<view class="info-row">
+				<text class="info-label">订单编号</text>
+				<view class="info-value">
+					<text>{{ orderDetail.orderNo }} </text>
+					<view style="width: 0;height: 24rpx;border: 0.5rpx solid #86909C;margin: 0 8rpx;"></view>
+					<u-icon name="复制" size="12" color="#18BE8D" @click="copyOrderNo"></u-icon>
+				</view>
 			</view>
-			<view class="btnbox" v-if="details.nStatus === -2">
-				<view @click="deleteOrder(details.cId)">删除订单</view>
+			<view class="info-row">
+				<text class="info-label">下单时间</text>
+				<text class="info-value">{{ orderDetail.createTime }}</text>
 			</view>
-			<view class="btnbox" v-if="details.nStatus === 4">
-				<view @click="commentOrder(details.orderNo,details.cJsId,details.cId,details.js.cNickName)">评价订单</view>
+			<view class="info-row">
+				<text class="info-label">付款时间</text>
+				<text class="info-value">{{ orderDetail.paidTime }}</text>
 			</view>
-			<view class="btnbox" v-if="details.nStatus === 3">
-				<view @click="bookNow(typelevel,details.cJsId)">升级</view>
-				<view @click="bookNow(typeTime,details.cJsId)">加钟</view>
+			<view class="info-row">
+				<text class="info-label">完成时间</text>
+				<text class="info-value">{{ orderDetail.completedTime }}</text>
 			</view>
 		</view>
-		<!-- 录音弹框 -->
-		<view class="recording" v-if="recordShow">
-			<view class="recording_content">
-				<view class="btn">
-					<view @click="cancle">取消</view>
-					<view @click="saveRecord">保存</view>
-				</view>
-				<view class="content">
-					<view class="time">{{recordTime}}</view>
-					<view class="Playparse" @click="pauseRecord" v-if="isRecording">
-						<image src="/static/identify/rec1.png" mode="" />
-					</view>
-					<view class="Playparse" @click="startRecord" v-else>
-						<image src="/static/identify/rec2.png" mode="" />
-					</view>
-				</view>
+
+		<!-- 底部占位,避开安全区 -->
+		<view class="footer-placeholder"></view>
+
+		<!-- 底部操作按钮栏 -->
+		<view class="bottom-btn-group" v-if="orderDetail.orderStatus != 5 && orderDetail.orderStatus != 9">
+			<!-- v-if="[0, 1, 2, 3, 6].includes(item.nStatus)" -->
+			<view class="pay" v-if="orderDetail.orderStatus == 2" @click.stop="rejectOrder(orderDetail)">拒接</view>
+			<view class="pay" v-if="[2, 3,].includes(orderDetail.orderStatus)"
+				@click.stop="contactCustomer(orderDetail)">
+				联系客户</view>
+			<view class="pay main" v-if="orderDetail.orderStatus == 2" @click.stop="acceptOrder(orderDetail)">立即接单
 			</view>
-		</view>
-		<!-- 加单弹框 -->
-		<view class="dialog" v-if="dialogShow && projects.length>0">
-			<view class="closebox" @click="closeDialog"></view>
-			<view class="dialog_content">
-				<view class="lists" v-for="(item,index) in projects" :key="index">
-					<view class="imgs">
-						<image :src="$globalData.publicUrl + item.cCover" mode="" />
-					</view>
-					<view class="right">
-						<view class="list_title">
-							<view class="title">{{item.cTitle}}</view>
-							<view class="time">{{item.nMinute}}分钟</view>
-						</view>
-						<view class="price">
-							<view class="money">¥{{item.dPrice}}</view>
-							<view class="counter">
-								<view @click="decrease(index)">-</view>
-								<text>{{ item.number }}</text>
-								<view @click="increase(index)">+</view>
-							</view>
-						</view>
-					</view>
-				</view>
+
+			<view class="pay" v-if="[4, 3,].includes(orderDetail.orderStatus)" @click.stop="cancelOrder(orderDetail)">
+				取消订单
 			</view>
-			<view class="now" @click="nowYuyue(details.orderNo,details.cJsId)" ><text>立即预约</text></view>
-		</view>
-		<view class="refuse_popup" v-if="isRefuse">
-			<view class="histroy">
-				<view class="title">
-					请输入拒绝接单原因
-				</view>
-				<view class="center">
-					<input type="text" maxlength="10" v-model="reasonRefusal" placeholder="请输入拒绝原因,最多10个" />
-				</view>
-				<view class="btn_box">
-					<view class="btn" @click="cancel">
-						取消
-					</view>
-					<view class="btn success" @click="refuseSubmit">
-						提交
-					</view>
-				</view>
+			<view class="pay main main1" v-if="orderDetail.orderStatus == 3 && orderDetail.execStatus == 0"
+				@click.stop="startGoOut(orderDetail)">我已出发/签到</view>
+			<view class="pay main" v-if="orderDetail.orderStatus == 3 && orderDetail.execStatus == 1"
+				@click.stop="arriveSign(orderDetail)">已到达</view>
+			<view class="pay main" v-if="orderDetail.orderStatus == 3 && orderDetail.execStatus == 2"
+				@click.stop="startService(orderDetail)">开始服务</view>
+
+			<view class="pay" v-if="orderDetail.orderStatus == 4" @click.stop="cancelOrder2(orderDetail)">提前结束</view>
+			<view class="pay main" v-if="orderDetail.orderStatus == 4" @click.stop="finishService(orderDetail)">服务完成
 			</view>
+
 		</view>
-		<view class="arrive" v-if="isArrive">
-			<view class="photo_box">
-				<view class="title">
-					到达地点
-				</view>
-				<view class="photo">
-					<view class="small_title">
-						请拍摄到达地点主要建筑物
-					</view>
-					<view class="upload_box">
-						<Upload
-							:maxCount="1"
-							@fileList="onUpload($event, 'arrivalPhoto')"
-						/>
-					</view>
+		<!-- 服务完成弹窗 -->
+		<u-popup :show="showModal2" mode="center" :round="16" :mask-close-able="false">
+			<view class="modal-wrap">
+				<!-- 标题居中 -->
+				<view class="title">提示</view>
+				<!-- 正文 -->
+				<view class="content">
+					距离服务时间还剩{{ diff }}分钟,确认提前结束订单吗?
 				</view>
-				<view class="btn_box">
-					<view class="cancel" @click="isArrive = false">
-						取 消
-					</view>
-					<view class="btn" @click="arrive">
-						提 交
-					</view>
+				<!-- 底部双按钮(必显示) -->
+				<view class="btn-box">
+					<view class="btn left" @click="showModal2 = false">我再想想</view>
+					<view class="btn right" @click="finishService1(orderDetail)">确认结束</view>
 				</view>
 			</view>
-		</view>
-		<view class="arrive" v-if="isSchedule">
-			<view class="photo_box">
-				<view class="title">
-					结束原因
+		</u-popup>
+		<!-- 线下签到弹窗 -->
+		<u-popup :show="showSignPopup" :closeOnClickOverlay="true" mode="center" :round="16"
+			@close="showSignPopup = false">
+			<view class="sign-wrap">
+				<view class="sign-title">输入用户手机后4位完成线下签到</view>
+				<view class="sign-input-wrap">
+					<Code ref="codeInput" :maxlength="4" :width="494" type="block" inputType="number"
+						@onChange="onPhoneInput" @onComplete="onSignComplete" />
 				</view>
-				<view class="photo">
-					<view class="small_title">
-						提前结束,请填写原因
-					</view>
-					<!-- <input type="text" placeholder="请输入提前结束原因" v-model="timeoutCause" /> -->
-					<view class="textarea">
-
-						<textarea placeholder="请输入提前结束原因" type="textarea" v-model="timeoutCause"
-							style="width: 100%;height: 100%;font-size: 26rpx;" id="" cols="30" rows="10"></textarea>
-					</view>
+				<view v-if="signError" class="sign-error">手机号验证错误,请重试</view>
 
-				</view>
-				<view class="btn_box">
-					<view class=" cancel" @click="isSchedule = false">
-						取 消
-					</view>
-					<view class="btn" @click="reasonSubmit">
-						提 交
-					</view>
-				</view>
 			</view>
-		</view>
+		</u-popup>
 	</view>
 </template>
 
 <script>
-	import {
-		getInfo,
-		alertOrder,
-		engineerDetails,
-		addOrder,
-		arriveOderLocation,
-		updateOrder,
-		project,
-		enterService,
-		depart,
-		userComment,
-		reach,
-		confirm
-	} from '@/api/index.js'
-	import {
-		delOrder,
-		takeOrder,
-		speedOrder,
-		refuseOrder,
-		confirmOrder,
-		orderDeatails,
-	} from '@/api/order.js';
-	import Upload from '@/components/upload/index.vue';
-	export default {
-		components: {
-			Upload
+//execStatus
+//'履约状态:0=待出发/待签到,1=已出发,2=已到达/已签到'
+import { orderDetail, acceptOrder, rejectOrder, cancelOrder, arriveSign, startService, finishService, startGoOut, getCustomerPhone } from '@/api/order.js'
+export default {
+	data() {
+		return {
+			showSignPopup: false,
+			phoneInputValue: '',
+			signError: '',
+			diff: 0,
+			id: '',
+			orderDetail: {},
+			showModal2: false,
+		};
+	},
+	onLoad(options) {
+		console.log(options.id)
+		this.id = options.id
+		this.getOrderDetail()
+	},
+	methods: {
+		// 订单详情
+		getOrderDetail() {
+			orderDetail({
+				orderId: this.id
+			}).then(res => {
+				console.log(res)
+				if (res.data.code === 200) {
+					this.orderDetail = res.data.data
+					// this.orderDetail.orderStatus = 9 //guo
+					// this.orderDetail.execStatus = 0
+				}
+			})
 		},
-		data() {
-			return {
-				cAddress: '',
-				id: '',
-				details: {
-          js: {
-            cNickName: ''
-          }
-        },
-				dtCreateTime: '',
-				dtCreateTime1: '',
-				acceptanceTime: '',
-				reachTime: '',
-				startTime: '',
-				endTime: '',
-				dTotalMoney: 0,
-				money: 0,
-				name: '',
-				orderShow: true,
-				// 录音
-				hours: 0, // 小时
-				minute: 0, // 分钟
-				second: 0, // 秒钟
-				recorderManager: null,
-				recordTime: '00:00:00',
-				isRecording: false,
-				isPaused: false,
-				audioFilePath: '',
-				timer: null,
-				recordShow: false,
-				// 加单
-				dialogShow: false,
-				projects: [],
-				soundFile: '',
-				ifOnceClick: true,
-				ordertype: null,
-				typelevel: 2, //升级
-				typeTime: 1, //加钟
-				isRefuse: false,
-				reasonRefusal: '', //拒单原因
-				refusecId: '',
-				userCommentList: [],
-				form: {},
-				isArrive: false,
-				isSchedule: false,
-				timeoutCause: ''
-			}
+		// 去钱款去向记录
+		goMoneyRecord() {
+			uni.navigateTo({
+				url: '/pages/order/moneyRecord?id=' + this.id
+			})
 		},
-		onLoad(options) {
-			this.id = options.cid
-			this.name = options.name
-			this.getDetails()
-			this.token = uni.getStorageSync('access-token'); // 假设token保存在本地缓存中
-
+		// 立即接单
+		acceptOrder(item) {
+			acceptOrder({
+				id: item.orderId
+			}).then(res => {
+				console.log(res)
+				if (res.data.code === 200) {
+					this.getOrderDetail()
+					uni.showToast({ title: res.data.msg, icon: 'none' });
+				}
+			})
 		},
-		methods: {
-			userComment(cOpenId) {
-				let data = {}
-				data.openId = cOpenId
-				userComment(data).then(res => {
-          if (res.data.code == 200){
-					  this.userCommentList = res.data.data.records
-          }
-				})
-			},
-			dial(cPhone) {
-				uni.makePhoneCall({
-					phoneNumber: cPhone //仅为示例
-				})
-			},
-			deleteOrder(cId) {
-				var that = this
-				var id = {
-					cId: e
-				}
-				uni.showModal({
-					title: '提示',
-					content: '确定删除订单吗?',
-					showCancel: true, // 是否显示取消按钮
-					success(res) {
-						if (res.confirm) {
-							delOrder(id).then(res => {
-								if (res.data.code == 200) {
-									// that.getList()
-									that.$router.go(0)
-									uni.showToast({
-										title: '删除订单成功!',
-										icon: 'none'
-									})
-									// setTimeout(() => {
-									// 	this.list = []
-									// 	this.getList()
-									// }, 100)
-								} else {
-									uni.showToast({
-										title: res.data.msg,
-										icon: 'none'
-									})
-								}
-							})
-						}
-					}
-				})
-			},
-			arriveOderLocation(cId, orderNo) {
-				console.log('+++++')
-				this.isArrive = true
-				this.form.cId = cId
-				this.form.orderNo = orderNo
-				let that = this
-				uni.getLocation({
-					type: 'wgs84',
-					isHighAccuracy: true,
-					accuracy: 'best',
-					success: (res) => {
-						that.form.arrivalLatitude = res.latitude
-						that.form.arrivalLongitude = res.longitude
-					},
-					fail: (res) => {}
-				});
-			},
-			// upload事件
-			onUpload(e, t) {
-				this.form[t] = e.map(item => item.url).join();
-			},
-			//提交到达拍照
-			arrive() {
-				if (!this.form.arrivalPhoto) {
-					uni.showToast({
-						title: '请上传到达照片',
-						icon: 'none'
-					})
-					return
-				} else {
-					reach(this.form).then(res => {
-						this.isArrive = false
-						if (res.data.code == 200) {
-							uni.showToast({
-								title: '已到达',
-								icon: 'none'
-							})
-							// this.getList()
-							this.$router.go(0)
-						} else {
-							uni.showToast({
-								title: res.data.msg,
-								icon: 'none'
-							})
-						}
-					})
-				}
-			},
-			scheduling(cId) {
-				var data = {
-					cId: cId
-				}
-				takeOrder(data).then(res => {
-					if (res.data.code == 200) {
-						uni.showToast({
-							title: '已接单',
-						})
-						this.$router.go()
-					} else {
-						uni.showToast({
-							title: res.data.msg,
-							icon: 'none'
-						})
-					}
-				})
-			},
-			//拒单
-			refuse(cId) {
-				this.isRefuse = true
-				this.refusecId = cId
-			},
-			refuseSubmit() {
-				var data = {
-					cId: this.refusecId,
-					reasonRefusal: this.reasonRefusal.trim()
-				}
-				if (data.reasonRefusal == '') {
-					uni.showToast({
-						title: '拒绝原因不能为空',
-					})
-					return
-				}
-				refuseOrder(data).then(res => {
-					if (res.data.code == 200) {
-						this.list = []
-						uni.showToast({
-							title: '已拒绝',
-						})
-						// this.getList()
-						this.isRefuse = false,
-							this.reasonRefusal = ''
-					} else {
-						uni.showToast({
-							title: res.data.msg,
-							icon: 'none'
-						})
-					}
-				})
-			},
-			cancel() {
-				this.isRefuse = false
-				this.reasonRefusal = ''
-			},
-			//出发
-			depart(cId, orderNo) {
-				let that = this
-				uni.getLocation({
-					type: 'wgs84',
-					isHighAccuracy: true,
-					accuracy: 'best',
-					success: (res) => {
-						let data = {
-							cId: cId,
-							departLatitude: res.latitude,
-							departLongitude: res.longitude
-						}
-						depart(data).then(res => {
-							if (res.data.code == 200) {
-								uni.showToast({
-									title: '已出发',
-								})
-								that.getList()
-							} else {
-								uni.showToast({
-									title: res.data.msg,
-								})
-								that.getList()
+		// 拒绝订单
+		rejectOrder(item) {
+			uni.showModal({
+				title: '确认拒绝',
+				content: '确定要拒绝该订单吗?',
+				success: (res) => {
+					if (res.confirm) {
+						rejectOrder({
+							id: item.orderId
+						}).then(res => {
+							console.log(res)
+							if (res.data.code === 200) {
+								this.getOrderDetail()
+								uni.showToast({ title: res.data.msg, icon: 'none' });
 							}
 						})
-					},
-					fail: (res) => {}
-				});
-			},
-			// complete(cId, orderNo) {
-			// 	var id = {
-			// 		cId: cId,
-			// 		orderNo: orderNo
-			// 	}
-			// 	let that  = this
-			// 	uni.showModal({
-			// 		title: '提示',
-			// 		content: '确认服务完成?',
-			// 		success: function(res) {
-			// 			if (res.confirm) {
-
-			// 				confirmOrder(id).then(res => {
-			// 					if (res.data.code == 200) {
-			// 						this.$router.go(0)
-			// 						// that.list =[]
-			// 						uni.showToast({
-			// 							title: '已完成',
-			// 						})
-			// 						uni.navigateTo({
-			// 							url: '/pages/my/js_order'
-			// 						})
-			// 						that.getList()
-			// 					} else {
-			// 						uni.showToast({
-			// 							title: res.data.msg,
-			// 						})
-			// 					}
-			// 				})
-
-			// 				// this.list = []
-			// 				// this.getList();
-
-			// 			}
-			// 		}
-			// 	});
-			// },
-			//完成订单
-			complete(cId, orderNo) {
-				console.log(this.details)
-				this.cId = cId
-				this.orderNo = orderNo
-				const now = new Date(+new Date() + 8 * 3600 * 1000);
-				const isoDateTime = now.toISOString(); // ISO 8601 格式
-				let nowtime = new Date(isoDateTime.slice(0, 19))
-				let starttime = new Date(this.details.startTime) //开始时间
-				let differenceInMs = nowtime - starttime //剩余时间
-				let differenceInMinutes = differenceInMs / (1000 * 60);
-				if (differenceInMinutes > this.details.cGoods[0].nMinute) {
-					var id = {
-						cId: cId,
-						orderNo: orderNo
 					}
-					let that = this
-					uni.showModal({
-						title: '提示',
-						content: '确认服务完成?',
-						success: function(res) {
-							if (res.confirm) {
-								confirmOrder(id).then(res => {
-									if (res.data.code == 200) {
-										// this.list =[]
-										uni.showToast({
-											title: '已完成',
-										})
-										// location.reload(true);
-										that.$router.go(0)
-										// this.getList()
-									} else {
-										uni.showToast({
-											title: res.data.msg,
-										})
-										// location.reload(true);
-										// that.$router.go(0)
-									}
-								})
-							}
-						}
-					});
-				} else {
-					this.isSchedule = true
 				}
-			},
-			//填写提前结束原因
-			reasonSubmit() {
-				let data = {}
-				data.cId = this.cId
-				data.orderNo = this.orderNo
-				data.timeoutCause = this.timeoutCause
-				if (data.timeoutCause == '') {
-					uni.showToast({
-						icon: 'none',
-						title: '请填写提前完成原因',
-					})
-					return
-				} else {
+			});
 
-					confirm(data).then(res => {
-						if (res.data.code == 200) {
-							uni.showToast({
-								title: '已完成',
-							})
-							location.reload(true);
-						} else {
-							uni.showToast({
-								title: res.data.msg,
-							})
-						}
-					})
-				}
-			},
-			enterService(cId, orderNo) {
-				var data = {
-					cId: cId
-				}
-				enterService(data).then(res => {
-					if (res.data.code == 200) {
-						// this.list = []
-						// this.getList()
-						this.getDetails()
-						uni.showToast({
-							title: '服务已开始',
-						})
-						this.$router.go(0)
-					} else {
-						uni.showToast({
-							title: res.data.msg,
-							icon: 'none'
-						})
-					}
-				})
-			},
-			//报警
-			alert(orderNo) {
-				var data = {
-					orderNo: orderNo
-				}
-				alertOrder(data).then(res => {
-					if (res.data.code == 200) {
-						uni.showToast({
-							title: '已报警!',
-						})
-						this.getDetails()
-					} else {
-						uni.showToast({
-							title: res.data.msg,
-							icon: 'none'
-						})
-					}
-				})
-			},
-			commentOrder(orderNo, cJsId, cId, cName) {
-				uni.navigateTo({
-					url: './comment?orderNo=' + orderNo + '&cJsId=' + cJsId + '&cId=' + cId + '&cName=' + cName
-				})
-			},
-			//获取订单详情
-			getDetails() {
-				var id = {
-					cId: this.id
+		},
+		// 联系客户
+		contactCustomer(item) {
+			getCustomerPhone({
+				orderId: item.orderId,
+			}).then(res => {
+				console.log(res)
+				if (res.data.code === 200) {
+					uni.showToast({ title: res.data.msg, icon: 'none' });
+				} else {
+					uni.showToast({ title: res.data.msg, icon: 'none' });
 				}
-				orderDeatails(id).then(res => {
-					var charToRemove = "T";
-					if (res.data.code == 200) {
-						this.details = res.data.data.records[0],
-							this.userComment(this.details.cOpenId)
-						this.dtCreateTime = res.data.data.records[0].dtCreateTime.slice(0, 10),
-							this.dtCreateTime1 = res.data.data.records[0].dtCreateTime.replace(charToRemove, ' '),
-
-							// let acceptancetime = res.data.data.records[0].dtCreateTime.slice(0, 10)
-							this.acceptanceTime = this.details.acceptanceTime ? this.details.acceptanceTime.replace(charToRemove, ' ') : ''
-
-							this.reachTime = this.details.reachTime ? this.details.reachTime.replace(charToRemove, ' ') : ''
-							this.startTime = this.details.startTime ? this.details.startTime.replace(charToRemove, ' ') : ''
-							this.endTime = this.details.endTime ? this.details.endTime.replace(charToRemove, ' ') : ''
-              if(this.details.cAddress){
-                this.cAddress = JSON.parse(this.details.cAddress).address + '(' + JSON.parse(this.details.cAddress).address + ')' + this.details.atlasAdd
-              }
-						var status = this.details.nStatus ? this.details.nStatus : 0
-						if (status == 2 || status == 3) {
-							// this.setData({
-							this.orderShow = true
-							// })
-						} else {
-							// this.setData({
-							this.orderShow = false
-							// })
-						}
-					}
-				})
-			},
-			bookNow(type, id) {
-				this.ordertype = type
-				this.projects = []
-				var id = {
-					id: id
+			}).catch(err => {
+				console.log(err)
+			})
+			//uni.showToast({ title: '联系客户', icon: 'none' });
+		},
+		// 取消订单
+		cancelOrder(item) {
+			uni.navigateTo({
+				url: '/pages/order/cancelOrder?orderId=' + item.orderId + '&orderStatus=' + item.orderStatus
+			})
+
+		},
+		// 我已出发/签到
+		startGoOut(item) {
+			startGoOut({
+				orderId: item.orderId,
+			}).then(res => {
+				console.log(res)
+				if (res.data.code === 200) {
+					this.$refs.paging.reload();
+					uni.showToast({ title: res.data.msg, icon: 'none' });
+				} else {
+					uni.showToast({ title: res.data.msg, icon: 'none' });
 				}
-				engineerDetails(id).then(res => {
-					res.data.data.projects.forEach(element => {
-						if ((this.details.dTotalMoney < element.dPrice) && type == 2) {
-							element.number = 0
-							this.projects.push(element)
-						}else if(type == 1){
-							element.number = 0
-							this.projects.push(element)
-						}
-					});
-					if(this.projects.length == 0){
-						uni.showToast({
-							icon:'none',
-							title:'暂无可升级订单'
-						})
-					}
-					// details:res.data.data,
-					// this.projects = res.data.data.projects,
-					console.log(this.projects)
-					this.dialogShow = true,
-						this.orderId = res.data.data.cId
-				})
-			},
-			//升级订单+1
-			increase(idx) {
-				this.projects[idx].number++;
-			},
-			decrease(idx) {
-				this.projects[idx].number--;
-			},
-			nowYuyue(orderNo, cJsId) {
-				var that = this
-				// if()
-				const allCountsZero = this.projects.every(item => item.number === 0);
-				if (allCountsZero) {
-					wx.showToast({
-						title: '请先选择项目!',
-						duration: 1000,
-						icon: 'none',
-					})
-					return
+			})
+		},
+		// 我已到
+		arriveSign() {
+			this.showSignPopup = true;
+			this.phoneInputValue = '';
+			this.signError = '';
+			// 清空验证码输入
+			this.$nextTick(() => {
+				if (this.$refs.codeInput) {
+					this.$refs.codeInput.clear();
+				}
+			});
+		},
+		// 监听输入(yi-code组件触发)
+		onPhoneInput(e) {
+			// 兼容不同调用方式
+			const value = e.detail ? e.detail.value : e;
+			// 过滤非数字字符
+			const filteredValue = String(value || '').replace(/[^0-9]/g, '');
+			this.phoneInputValue = filteredValue;
+			this.signError = '';
+		},
+		// 输入完成
+		onSignComplete(value) {
+			this.phoneInputValue = value;
+			arriveSign({
+				orderId: this.orderDetail.orderId,
+				phoneTail: this.phoneInputValue,//手机号后4位
+			}).then(res => {
+				console.log(res)
+				if (res.data.code === 200) {
+					this.showSignPopup = false;
+					this.$refs.paging.reload();
+					uni.showToast({ title: res.data.msg, icon: 'none' });
 				} else {
-					// console.log(this.data.projects,"project")
-					var list = []
-					this.projects.forEach(element => {
-						if (element.number > 0) {
-							element.sum = element.number * element.dPrice
-							list.push(element)
-						}
-					});
-					var total = 0
-					for (let i = 0; i < list.length; i++) {
-						total += list[i].sum;
-					}
-					var data = {
-						orderType: this.ordertype,
-						cJsId: cJsId,
-						cGoods: list,
-						cOpenId: uni.getStorageSync('wx_copenid'),
-						dTotalMoney: total,
-						parentNo: orderNo
-					}
-					speedOrder(data).then(res => {
-						if (res.data.code == 200) {
-							uni.navigateTo({
-								url: '../identify/pay_order?orderNo=' + res.data.data.orderNo,
-							})
-						} else {}
-					})
+					this.signError = res.data.msg;
+					uni.showToast({ title: res.data.msg, icon: 'none' });
+
 				}
-			},
-			closeDialog() {
-				this.dialogShow = false
-			},
-			appraise(details, cId, orderNo) {
+			})
+		},
+		// 开始服务
+		startService(item) {
+			if (item.projectType == 1) {
 				uni.navigateTo({
-					url: './comment?orderNo=' + orderNo + '&cJsId=' + details.cJsId + '&name=' + details.js.cName + '&cId=' +
-						details.cId + '&title=' + '商户' + '&cOpenId=' + details.cOpenId
+					url: '/pages/order/businessFormal?orderId=' + item.orderId
 				})
+				return
 			}
-		}
-	}
-</script>
 
-<style lang="scss" scoped>
-	.details {
-		position: relative;
-		height: 100vh;
-		overflow: hidden;
-		background: #F7FFFF;
-
-		.content {
-			height: 100vh;
-			overflow-y: scroll;
-
-			.order_status {
-				width: 100%;
-				height: 364rpx;
-				background: linear-gradient(90deg, #91F5F0 0%, #13E4DA 100%);
-				padding: 28rpx 32rpx 24rpx;
-				box-sizing: border-box;
-
-				.status_center {
-					width: 100%;
-					background: #E5FDFB;
-					box-shadow: 0px 4rpx 12rpx 0px rgba(88, 209, 187, 0.1);
-					border-radius: 16rpx;
-					border: 2rpx solid #BCE7E5;
-					padding: 24rpx;
-					box-sizing: border-box;
-
-					.status {
-						font-weight: 700;
-						font-size: 38rpx;
-						color: #2F3437;
-						line-height: 45rpx;
-						display: flex;
-						align-items: center;
-						justify-content: space-between;
-
-						.money {
-							font-weight: 400;
-							font-size: 28rpx;
-							color: #F53E54;
-							// line-height: 24rpx;
-							display: flex;
-							align-items: center;
-
-							text {
-								font-weight: 700;
-								font-size: 44rpx;
-								color: #F53E54;
-								// line-height: 24rpx;
-							}
-						}
-					}
-
-					.time {
-						width: 100%;
-						margin-top: 12rpx;
-						font-size: 30rpx;
-						color: #069E96;
-						line-height: 35rpx;
-						margin-bottom: 20rpx;
-					}
-
-					.merchant {
-						width: 100%;
-						height: 136rpx;
-						background: #FFFFFF;
-						box-shadow: 0px 4rpx 12rpx 0px rgba(88, 209, 187, 0.1);
-						border-radius: 16rpx;
-						padding: 20rpx;
-						box-sizing: border-box;
-						font-size: 28rpx;
-						color: #333333;
-
-						text {
-							display: inline-block;
-							margin-top: 16rpx;
-						}
-					}
-				}
+			//陪玩开始服务
+			startService({
+				orderId: item.orderId,
+				imageUrls: []
+			}).then(res => {
+				console.log(res)
+				if (res.data.code === 200) {
+					this.getOrderDetail()
+					uni.showToast({ title: res.data.msg, icon: 'none' });
+				}
+			})
+		},
+		// 服务完成
+		finishService(item) {
+
+			const diff = new Date(item.appointmentEndTime).getTime() - new Date().getTime();
+			this.diff = Math.floor(diff / (1000 * 60));
+			if (this.diff > 6) {
+				this.selectOrderDetail = item
+				this.showModal2 = true
+				return
 			}
+			this.finishService1(item)
 
-			.box1 {
-				display: flex;
-				align-items: center;
-				justify-content: space-between;
-				padding: 30rpx;
-				border-bottom: 20rpx solid #fcfcfc;
-
-				.imgs {
-					border-radius: 10rpx;
-					height: 180rpx;
-					overflow: hidden;
-
-					image {
-						width: 280rpx;
-						height: 180rpx;
-					}
-				}
-
-				.box1cont {
-					flex: 1;
-					padding-left: 30rpx;
-
-					.title {
-						font-size: 36rpx;
-						font-weight: bold;
-						display: flex;
-						align-items: center;
-					}
-
-					.moneytime {
-						display: flex;
-						justify-content: space-between;
-						padding-top: 40rpx;
-						color: #808080;
-
-						.money {
-							font-size: 32rpx;
-							color: #ff0000;
-							font-weight: bold;
-						}
-
-						.time {
-							// color: #333;
-							font-size: 26rpx;
-						}
+		},
+		// 确认提前结束订单
+		finishService1(item) {
+			finishService({
+				orderId: item.orderId,
+			}).then(res => {
+				if (res.data.code === 200) {
+					this.getOrderDetail()
+					uni.showToast({ title: res.data.msg, icon: 'none' });
+				}
+			})
+		},
+		// 提前结束
+		cancelOrder2(item) {
+			uni.showModal({
+				title: '提示',
+				content: '确定要提前结束该订单吗?',
+				success: (res) => {
+					if (res.confirm) {
+						this.finishService(item)
 					}
-
 				}
-			}
-
-			.orderinfo {
-				width: 100%;
-				margin-top: 28rpx;
-				padding: 0px 32rpx;
-				box-sizing: border-box;
-
-				.order_box {
-					width: 100%;
-					background: linear-gradient(35deg, #FFFFFF 0%, #E4FFFD 100%);
-					box-shadow: 0px 4rpx 12rpx 0px rgba(88, 209, 187, 0.1);
-					border-radius: 16rpx;
-					padding: 24rpx;
-					box-sizing: border-box;
-
-					.title {
-						font-size: 32rpx;
-						font-weight: bold;
-						color: #2F3437;
-						display: flex;
-						align-items: center;
-
-						text {
-							display: inline-block;
-							width: 6rpx;
-							height: 34rpx;
-							background-color: #20CBC2;
-							margin-right: 12rpx;
-						}
-					}
-
-					.project {
-						height: 160rpx;
-						margin-top: 24rpx;
-						display: flex;
-						align-items: center;
-
-						.project_left {
-							margin-right: 40rpx;
-
-							img {
-								width: 160rpx;
-								height: 160rpx;
-							}
-						}
-
-						.project_right {
-							flex: 1;
-							height: 100%;
-							display: flex;
-							flex-direction: column;
-							justify-content: space-between;
+			});
+		},
+		// 复制订单号
+		copyOrderNo() {
+			uni.setClipboardData({
+				data: '5017036467099547354',
+				success: () => {
+					uni.showToast({ title: '复制成功' });
+				}
+			});
+		},
 
-							text {
-								display: block;
-							}
+	}
+};
+</script>
 
-							.name {
-								font-weight: 700;
-								font-size: 28rpx;
-								color: #333333;
-								line-height: 33rpx;
-							}
+<style scoped lang="scss">
+// 线下签到弹窗
+.sign-wrap {
+	width: 650rpx;
+	background: #fff;
+	border-radius: 16rpx;
+	padding: 48rpx;
+
+	.sign-error {
+		font-weight: 400;
+		font-size: 26rpx;
+		color: #F53F3F;
+	}
 
-							.price {
-								font-size: 28rpx;
-								color: #666666;
-								line-height: 33rpx;
-								margin: 16rpx 0px;
-							}
 
-							.total {
-								width: 100%;
-								font-size: 28rpx;
-								color: #666666;
-								line-height: 33rpx;
-								display: flex;
-								justify-content: space-between;
-
-								.total_price {
-									display: inline-block;
-									font-weight: 700;
-									font-size: 32rpx;
-									color: #333333;
-									line-height: 38rpx;
-								}
-							}
-						}
-					}
-				}
 
-				.order_detail {
-					background: #fff;
-				}
+	.sign-title {
+		font-weight: 400;
+		font-size: 30rpx;
+		color: #1D2129;
+		text-align: left;
+		margin-bottom: 32rpx;
+	}
 
-				.orderA {
-					display: flex;
-					justify-content: space-around;
-					align-items: center;
-					padding-top: 30rpx;
+	.sign-input-wrap {
+		display: flex;
+		justify-content: center;
+	}
+}
+
+.user-info {
+	background: #fff;
+	margin: 16rpx 32rpx 0 32rpx;
+	border-radius: 16rpx;
+	padding: 32rpx;
+
+	.row1 {
+		margin-top: 16rpx;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		font-weight: 400;
+		font-size: 28rpx;
+		color: #4E5969;
+		text-align: left;
+
+
+		.status {
+			background: #FFF0ED;
+			border-radius: 4rpx 4rpx 4rpx 4rpx;
+
+			font-weight: 400;
+			font-size: 24rpx;
+			color: #FF531C;
+			line-height: 34rpx;
+			text-align: center;
+		}
 
-					view {
-						font-size: 32rpx;
+		.status1 {
+			background: #FFF7E7;
+			border-radius: 4rpx 4rpx 4rpx 4rpx;
 
-						image {
-							width: 80rpx;
-							height: 80rpx;
-							margin-right: 30rpx;
-						}
-					}
-				}
+			font-weight: 400;
+			font-size: 24rpx;
+			color: #FF7D00;
+			line-height: 34rpx;
 
+		}
 
+		.status2 {
+			background: #E8FFEA;
+			border-radius: 4rpx 4rpx 4rpx 4rpx;
 
-				.conts_price {
-					display: flex;
-					justify-content: space-between;
-				}
+			font-weight: 400;
+			font-size: 24rpx;
+			color: #00B42A;
+			line-height: 34rpx;
+			text-align: center;
+		}
 
-				.cont {
-					font-size: 28rpx;
-					line-height: 40rpx;
-					display: flex;
-					justify-content: space-between;
-					margin-top: 20rpx;
 
-					.left_title {
-						width: 170rpx;
-						font-size: 28rpx;
-					}
+		.status3 {
+			background: #F7F8FA;
+			border-radius: 4rpx 4rpx 4rpx 4rpx;
 
-					text {
-						// width: 498rpx;
-						// color: #dddbdb;
-						padding-left: 20rpx;
-						// font-size: 32rpx;
-					}
-				}
+			font-weight: 400;
+			font-size: 24rpx;
+			color: #4E5969;
+			line-height: 34rpx;
+			text-align: center;
+		}
 
-				.items {
-					border-bottom: 1px solid #f9f9f9;
-					padding: 20rpx 0;
-					display: flex;
-					justify-content: space-between;
-
-					.img {
-						width: 250rpx;
-						height: 200rpx;
-						border-radius: 20rpx;
-						overflow: hidden;
-
-						image {
-							width: 100%;
-							height: 100%;
-						}
-					}
+	}
 
-					.right {
-						height: 200rpx;
-						flex: 1;
-						padding-left: 50rpx;
-						display: flex;
-						flex-direction: column;
-						justify-content: space-between;
-					}
-				}
+	.row2 {
+		width: 100%;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
 
-				.conts {
-					font-size: 36rpx;
-					color: #ff0000;
-					font-weight: bold;
-					padding: 30rpx 0;
-					text-align: right;
-				}
+		font-weight: 400;
+		font-size: 28rpx;
+		color: #4E5969;
+		text-align: left;
 
-				.comment_box {
-					display: flex;
-					padding: 10rpx;
-					box-sizing: border-box;
-
-					.comment {
-						background-color: #ccc;
-						margin-right: 10px;
-						padding: 10rpx;
-						border-radius: 10rpx;
-						font-size: 30rpx;
-					}
-				}
-			}
+		.phone-icon {
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			width: 40rpx;
+			height: 40rpx;
+			border-radius: 40rpx 40rpx 40rpx 40rpx;
+			border: 1rpx solid #86909C;
 		}
 
-		.btnbox {
-			position: absolute;
-			bottom: 0;
-			left: 0;
-			width: 100%;
-			height: 120rpx;
-			background-color: #fff;
-			border-top: 1px solid #fdfdfd;
-			// padding-top: 20rpx;
+		.type {
+			margin-left: 16rpx;
 			display: flex;
-			justify-content: space-around;
 			align-items: center;
-
-			view {
-				display: flex;
-				justify-content: center;
-				align-items: center;
-				font-size: 30rpx;
-				background-color: #2ebdd9;
-				color: #fff;
-				// width: 47%;
-				height: 50%;
-				// margin:0 auto;
-				padding: 15rpx 30px;
-				border-radius: 50px;
-			}
 		}
+	}
 
-		.recording {
-			background-color: rgba(0, 0, 0, .5);
-			width: 100%;
-			height: 100%;
-			position: fixed;
-			top: 0;
-			left: 0;
-
-			.recording_content {
-				width: 100%;
-				height: 60%;
-				position: absolute;
-				bottom: 0;
-				background-color: #fff;
-
-				.btn {
-					display: flex;
-					justify-content: space-between;
-					padding: 20rpx 30rpx;
-				}
-
-				.time {
-					font-size: 70rpx;
-					font-weight: bold;
-					text-align: center;
-					padding: 200rpx 0;
-				}
-
-				.Playparse {
-					text-align: center;
-
-					image {
-						width: 80rpx;
-						height: 80rpx;
-					}
-				}
-			}
-
+	.row3 {
+		display: flex;
+		align-items: center;
+		margin-top: 16rpx;
+		font-weight: 400;
+		font-size: 28rpx;
+		color: #4E5969;
+		margin-bottom: 24rpx;
+
+		.cont {
+			margin-left: 40rpx;
+			font-weight: 500;
+			font-size: 28rpx;
+			color: #1D2129;
 		}
+	}
 
-		.dialog {
-			position: fixed;
-			top: 0;
-			left: 0;
-			width: 100%;
-			height: 100%;
-			background: rgba(0, 0, 0, .5);
-			z-index: 10;
-			transition: transform 0.3s ease-out;
-
-			.closebox {
-				height: calc(50vh - 60rpx);
-				width: 100%;
-			}
+}
 
-			.now {
-				position: absolute;
-				bottom: 0;
-				left: 0;
-				width: 100%;
-				text-align: center;
-				height: 100rpx;
-				background-color: #f7f8fa;
-				padding-top: 10rpx;
-
-				text {
-					display: inline-block;
-					height: 80rpx;
-					line-height: 80rpx;
-					width: 90%;
-					background-color: #2cb8d4;
-					color: #fff;
-					border-radius: 50rpx;
-				}
-			}
-
-			.dialog_content {
-				background-color: #fff;
-				position: absolute;
-				bottom: 0;
-				width: calc(100% - 60rpx);
-				height: 50vh;
-				overflow-y: scroll;
-				border-top-left-radius: 20rpx;
-				border-top-right-radius: 20rpx;
-				padding: 30rpx;
-				background-color: #f3f3f3;
-				padding-bottom: 100rpx;
-
-				.lists {
-					background-color: #fff;
-					margin-bottom: 20rpx;
-					display: flex;
-					justify-content: space-between;
-					padding: 20rpx 10rpx;
-					border-radius: 10rpx;
-
-					.imgs {
-						width: 240rpx;
-						height: 160rpx;
-						border-radius: 20rpx;
-						overflow: hidden;
-
-						image {
-							width: 100%;
-							height: 100%;
-						}
-					}
+.row4 {
+	background: #fff;
+	margin: 16rpx 32rpx 0 32rpx;
+	border-radius: 16rpx;
+	padding: 32rpx;
+	display: flex;
+	height: 160rpx;
 
-					.right {
-						flex: 1;
-						padding-left: 30rpx;
+	.title {
+		font-weight: 500;
+		font-size: 30rpx;
+		color: #1D2129;
+	}
 
-						.list_title {
-							display: flex;
-							justify-content: space-between;
-							align-items: center;
+	.cont {
+		display: flex;
+		align-items: baseline;
+		font-weight: 400;
+		font-size: 28rpx;
+		color: #1D2129;
+	}
+}
+
+.refundStatus1 {
+	margin-top: 16rpx;
+	width: 96rpx;
+	height: 36rpx;
+	background: #FFF2E5;
+	border-radius: 4rpx 4rpx 4rpx 4rpx;
+	border: 1rpx solid #FF7D00;
+
+	font-weight: 400;
+	font-size: 24rpx;
+	color: #FF7D00;
+	text-align: center;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+
+}
+
+.refundStatus2 {
+	width: 96rpx;
+	height: 36rpx;
+	background: #FFF2E5;
+	border-radius: 4rpx 4rpx 4rpx 4rpx;
+	border: 1rpx solid #F53F3F;
+
+	font-weight: 400;
+	font-size: 24rpx;
+	color: #F53F3F;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	text-align: center;
+
+}
+
+.order-detail-page {
+	background-color: #f5f5f5;
+	min-height: 100vh;
+}
+
+// 风险提示栏
+.risk-tip {
+	padding: 26rpx 32rpx;
+	background: #FFF8EC;
+	border-radius: 0rpx 0rpx 0rpx 0rpx;
+	display: flex;
+	align-items: flex-start;
+
+	.risk-text {
+		font-weight: 400;
+		font-size: 28rpx;
+		color: #FF7D00;
+	}
+}
+
+// 待接单状态卡片
+.status-card {
+	background: #fff;
+	margin: 16rpx 32rpx 0 32rpx;
+	border-radius: 16rpx;
+	padding: 32rpx;
+
+	.status-title {
+		display: flex;
+		align-items: center;
+
+		.status-text {
+			font-size: 40rpx;
+			font-weight: 600;
+			display: flex;
+			align-items: center;
+		}
+	}
 
-							.title {
-								font-size: 34rpx;
-								font-weight: bold;
-							}
+	.count-down {
+		margin-top: 16rpx;
+		font-weight: 400;
+		font-size: 28rpx;
+		color: #86909C;
 
-							.time {
-								font-size: 24rpx;
-							}
-						}
+		.red-text {
+			color: #F53F3F;
+			font-weight: 500;
+		}
+	}
+}
+
+// 订单已退金额
+.refund-amount {
+	background: #fff;
+	margin: 16rpx 32rpx 0 32rpx;
+	border-radius: 16rpx;
+	padding: 32rpx;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	font-weight: 400;
+	font-size: 28rpx;
+	color: #4E5969;
+
+	.refund-amount-text {
+		font-weight: bold;
+		font-size: 32rpx;
+		color: #1D2129;
+		line-height: 24rpx;
+		display: flex;
+		align-items: center;
+		justify-content: center;
 
-						.price {
-							padding-top: 50rpx;
-							display: flex;
-							justify-content: space-between;
+	}
+}
+
+// 用户信息卡片
+.user-info-card {
+	background: #fff;
+	margin: 0 20rpx;
+	border-radius: 12rpx;
+	padding: 24rpx;
+	display: flex;
+	flex-direction: column;
+	gap: 20rpx;
+
+	.user-row,
+	.time-row,
+	.address-row {
+		display: flex;
+		align-items: center;
+		gap: 12rpx;
+		font-size: 28rpx;
+		color: #333;
+	}
 
-							.money {
-								font-size: 42rpx;
-								color: #e61b1b;
-								font-weight: bold;
-							}
+	.address-text {
+		flex: 1;
+	}
 
-							.counter {
-								display: flex;
-
-								view {
-									width: 60rpx;
-									height: 60rpx;
-									line-height: 60rpx;
-									background-color: #f7f8fa;
-									text-align: center;
-									border-radius: 60rpx;
-									font-size: 50rpx;
-								}
-
-								text {
-									width: 100rpx;
-									text-align: center;
-									line-height: 60rpx;
-								}
-							}
-						}
-					}
-				}
-			}
+	.distance {
+		color: #666;
+	}
+}
+
+// 服务项目卡片
+.service-card {
+	background: #fff;
+	margin: 20rpx;
+	border-radius: 12rpx;
+	padding: 24rpx;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+
+	.service-left {
+		display: flex;
+		align-items: center;
+		gap: 20rpx;
+
+		.service-img {
+			width: 120rpx;
+			height: 120rpx;
+			border-radius: 8rpx;
 		}
 
-		.refuse_popup {
-			width: 100%;
-			height: 100%;
-			position: fixed;
-			top: 0;
-			left: 0;
-			background-color: rgba(0, 0, 0, 0.5);
+		.service-info {
 			display: flex;
-			justify-content: center;
-
-			.histroy {
-				width: 70%;
-				height: 160px;
-				margin-top: 500rpx;
-				background-color: #fff;
-				border-radius: 10px;
-				padding: 20px;
-				box-sizing: border-box;
-
-				.title {
-					width: 100%;
-					// padding: 10px ;
-					text-align: center;
-					box-sizing: border-box;
-					margin-bottom: 50rpx;
-				}
-
-				.center {
-					margin-bottom: 20px;
-
-					input {
-						display: block;
-						border-bottom: 1px solid #ccc;
-					}
-				}
+			flex-direction: column;
+			gap: 8rpx;
 
-				.btn_box {
-					width: 100%;
-					display: flex;
-					justify-content: space-around;
-
-					.btn {
-						width: 30%;
-						height: 30px;
-						background-color: #c8c9cc;
-						text-align: center;
-						line-height: 30px;
-						border-radius: 5px;
-					}
-
-					.success {
-						background: linear-gradient(to right, #35c99d, #27aea7);
-						color: #fff;
-					}
-				}
+			.service-name {
+				font-size: 30rpx;
+				font-weight: 500;
 			}
 		}
+	}
 
-		.arrive {
-			width: 100%;
-			height: 100%;
-			background-color: rgba(0, 0, 0, 0.5);
-			position: fixed;
-			top: 0;
-			display: flex;
-			justify-content: center;
-			align-items: center;
+	.service-price {
+		font-size: 32rpx;
+		color: #333;
+	}
+}
+
+// 费用明细
+.price-card {
+	background: #fff;
+	margin: 16rpx 32rpx 0 32rpx;
+	border-radius: 16rpx;
+	padding: 32rpx;
+
+
+	.title {
+		font-weight: 400;
+		font-size: 28rpx;
+		color: #4E5969;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		margin-bottom: 16rpx;
+	}
 
-			.photo_box {
-				width: 630rpx;
-				// height: 652rpx;
-				background-color: #fff;
-				// padding: 50rpx;
-				box-sizing: border-box;
-				display: flex;
-				flex-direction: column;
-				border-radius: 24rpx;
-				overflow: hidden;
-
-				.title {
-					width: 100%;
-					height: 92rpx;
-					background: #E6F8F7;
-					display: flex;
-					justify-content: center;
-					align-items: center;
-				}
+	.title:last-child {
+		margin-bottom: 0;
+	}
 
-				.photo {
-					width: 100%;
-					flex: 1;
-					overflow: hidden;
-					padding: 40rpx 32rpx;
-					box-sizing: border-box;
-
-					.small_title {
-						width: 100%;
-						font-size: 28rpx;
-						text-align: center;
-					}
+	.cont {
+		font-weight: 400;
+		font-size: 28rpx;
+		color: #FF4C12;
+	}
 
-					.textarea {
-						width: 566rpx;
-						height: 292rpx;
-						background: #F8F8F8;
-						border-radius: 16rpx;
-						padding: 20rpx 24rpx;
-						box-sizing: border-box;
-						margin-top: 32rpx;
-						font-size: 26rpx;
-					}
+}
 
-					.upload_box {
-						width: 100%;
-						display: flex;
-						justify-content: center;
-						align-items: center;
-						margin-top: 32rpx;
-						// margin-bottom: 40rpx;
-					}
-				}
+// 订单信息卡片
+.order-info-card {
+	background: #fff;
+	margin: 16rpx 32rpx 0 32rpx;
+	border-radius: 16rpx;
+	padding: 32rpx;
 
-				.btn_box {
-					width: 100%;
-					height: 116rpx;
-					background: #FFFFFF;
-					display: flex;
-					align-items: center;
-					justify-content: space-around;
-					border-top: 2rpx solid #EEEEEE;
-
-					.btn {
-						width: 225rpx;
-						height: 68rpx;
-						// height: 100%;
-						display: flex;
-						justify-content: center;
-						align-items: center;
-						background: linear-gradient(90deg, #1AD7CE 0%, #21C9C1 100%);
-						border-radius: 44rpx;
-						color: #fff;
-					}
+	.info-title {
+		font-weight: 500;
+		font-size: 32rpx;
+		color: #1D2129;
+	}
 
-					.cancel {
-						width: 225rpx;
-						height: 68rpx;
-						border-radius: 106rpx;
-						border: 2rpx solid #BBBBBB;
-						display: flex;
-						justify-content: center;
-						align-items: center;
-					}
-				}
-			}
+	.info-row {
+		display: flex;
+		justify-content: space-between;
+		font-size: 28rpx;
+		margin-top: 24rpx;
+
+		.info-label {
+			font-weight: 400;
+			font-size: 28rpx;
+			color: #4E5969;
 		}
 
-		.sub_box {
-			width: 100%;
-			height: 116rpx;
-			padding: 20rpx 40rpx;
-			box-sizing: border-box;
+		.info-value {
+			font-weight: 400;
+			font-size: 28rpx;
+			color: #1D2129;
 			display: flex;
 			align-items: center;
-			justify-content: center;
+		}
+	}
+}
+
+// 底部占位,防止按钮遮挡内容
+.footer-placeholder {
+	height: 160rpx;
+}
+
+// 底部按钮组
+.bottom-btn-group {
+	position: fixed;
+	bottom: 0;
+	left: 0;
+	right: 0;
+	background: #fff;
+	padding: 0 48rpx;
+	padding-bottom: calc(20rpx + var(--safe-area-inset-bottom));
+	display: flex;
+	justify-content: space-between;
+
+	// display: flex;
+	// align-items: center;
+	// justify-content: flex-end;
+
+	.pay {
+		margin-bottom: 24rpx;
+		margin-top: 24rpx;
+		// display: flex;
+		// align-items: center;
+		// justify-content: center;
+		width: 196.67rpx;
+		height: 88rpx;
+		line-height: 88rpx;
+		background: rgba(51, 51, 53, 0.05);
+		border-radius: 60rpx;
+		text-align: center;
+
+		font-weight: 400;
+		font-size: 32rpx;
+		color: #1D2129;
+	}
 
-			position: fixed;
-			bottom: 0;
-
-			.cancel {
-				width: 315rpx;
-				height: 76rpx;
-				border-radius: 106rpx;
-				border: 2rpx solid #BBBBBB;
-				font-size: 32rpx;
-				color: #999999;
-				display: flex;
-				align-items: center;
-				justify-content: center;
-			}
+	.alarm {
+		background-color: #F53F3F;
+		color: #FFFFFF;
+	}
+
+	.main {
+		background-color: #333335;
+		color: #FFFFFF;
+	}
+
+	.main1 {
+		width: 250rpx;
 
-			.edit_time {
-				width: 315rpx;
-				height: 76rpx;
-				border-radius: 106rpx;
-				border: 2rpx solid #00B8B0;
-				display: flex;
-				align-items: center;
-				justify-content: center;
-				color: #00B8B0;
-			}
-		}
 	}
+}
 </style>

+ 775 - 0
src/pages/order/search.vue

@@ -0,0 +1,775 @@
+<template>
+	<view class="page-container">
+		<webviewPoint ref="webviewRef" />
+
+		<z-paging ref="paging" v-model="dataList" @query="queryList">
+
+			<template #top>
+				<!-- 搜索框 -->
+				<view class="searchClass">
+					<u-search searchIcon="search" shape="round" placeholder="输入服务项目/客户手机号" searchIconColor="#A0A0A0"
+						v-model=searchProductName @search='goSearch' @custom='goSearch'></u-search>
+
+				</view>
+			</template>
+			<view class="list-box" v-if="dataList && dataList.length > 0">
+				<view class="item" v-for="(item, index) in dataList" :key="index" @click="goDetails(item.id)">
+					<!-- 订单信息 -->
+					<view style="border-bottom: 1px solid #E7E7E7;">
+						<view class="row1" @click="goDetails(item.cId)">
+							<view style="display: flex;align-items: center;">
+								<image src="/static/workbench/clockIcon3.png"
+									style="width: 32rpx;height: 32rpx;margin-right: 16rpx;" mode="aspectFill" />
+								{{ item.appointmentTimeRange }}
+							</view>
+							<view v-if="item.status == 2" class="status">待接单</view>
+
+							<!-- 3:待服务  待出发\待签到\已出发\已到达\已签到 -->
+							<view v-if="item.status == 3"
+								:class="(item.afterSalesServiceStatus === '待出发' || item.afterSalesServiceStatus === '待签到') ? 'status1' : 'status2'">
+								{{ item.afterSalesServiceStatus }}</view>
+							<view v-if="item.status == 4" class="status2">服务中</view>
+							<view v-if="item.status == 5" class="status3">已完成</view>
+
+						</view>
+						<view class="row2">
+							<image src="/static/workbench/propleIcon.png"
+								style="width: 32rpx;height: 32rpx;margin-right: 16rpx;" mode="aspectFill" />
+							<view>{{ item.contactPersonName }} {{ item.contactPhoneNumber }}
+							</view>
+							<view class="type">
+								<image v-if="item.customerTagCode == 0" src="/static/workbench/licenceIcon.png"
+									style="width: 108.5rpx;height: 40rpx;" mode="aspectFill" />
+								<image v-if="item.customerTagCode == 1" src="/static/workbench/licenceIcon1.png"
+									style="width: 108.5rpx;height: 40rpx;" mode="aspectFill" />
+								<image v-if="item.customerTagCode == 3" src="/static/workbench/licenceIcon2.png"
+									style="width: 92rpx;height: 40rpx;" mode="aspectFill" />
+
+							</view>
+						</view>
+
+						<view class="row3">
+							<image src="/static/workbench/localIcon.png"
+								style="width: 32rpx;height: 32rpx;margin-right: 16rpx;" mode="aspectFill" />
+
+							{{ item.contactAddressInfo }}
+							<text class="cont">{{ item.distanceKm }}km</text>
+						</view>
+					</view>
+
+					<!-- 服务项目信息 -->
+					<view class="row4">
+						<view>
+							<image :src="item.projectCover" mode="aspectFill"
+								style="border: 1px solid red;width: 96rpx;height: 96rpx;border-radius: 8rpx;" />
+						</view>
+						<view
+							style="display: flex;flex-direction: column;flex: 1;justify-content: space-between;margin-left: 24rpx;">
+							<view style="display: flex; justify-content: space-between;">
+								<view class="title">{{ item.projectName }}({{ item.projectPrice }}分钟)</view>
+								<view class="cont">
+									<view style="font-size: 20rpx;">¥</view>
+									{{ item.finalAmount }}
+								</view>
+							</view>
+							<view v-if="item.status == 9" class="refundStatus1">退款中</view>
+							<view v-if="item.status == 9" class="refundStatus2">已退款</view>
+
+						</view>
+
+					</view>
+					<!-- 订单金额 -->
+					<view class="price">
+						交通费
+						<view
+							style="font-weight: bold;font-size: 28rpx;display: flex;align-items: baseline;margin-right: 32rpx;">
+							<view style="font-size: 20rpx;">¥</view>
+							{{ item.trafficFee }}
+						</view>
+						实付
+						<view
+							style="font-weight: bold;font-size: 36rpx;color: #FF4C12;display: flex;align-items: baseline;">
+							<view style="font-size: 20rpx;">¥</view>
+							{{ item.finalAmount }}
+						</view>
+					</view>
+
+					<view class="btn">
+
+						<view class="button">
+							<!-- v-if="[0, 1, 2, 3, 6].includes(item.nStatus)" -->
+							<view class="pay" v-if="item.status == 2" @click="onCancleOrder(item)">拒接</view>
+							<view class="pay" v-if="[2, 3,].includes(item.status)" @click="onCancleOrder(item)">联系客户
+							</view>
+							<view class="pay main" v-if="item.status == 2" @click="onCancleOrder(item)">立即接单</view>
+
+							<view class="pay" v-if="[4, 3,].includes(item.status)" @click="onCancleOrder(item)">取消订单
+							</view>
+							<view class="pay main" v-if="item.status == 3" @click="onCancleOrder(item)">我已出发/签到</view>
+							<view class="pay main" v-if="item.status == 3" @click="onCancleOrder(item)">已到达</view>
+							<view class="pay main" v-if="item.status == 3" @click="onCancleOrder(item)">开始服务</view>
+
+							<view class="pay" v-if="item.status == 4" @click="onCancleOrder(item)">提前结束</view>
+							<view class="pay alarm" v-if="item.status == 4" @click="onCancleOrder(item)">一键报警</view>
+							<view class="pay main" v-if="item.status == 4" @click="onCancleOrder(item)">服务完成</view>
+						</view>
+					</view>
+				</view>
+			</view>
+
+			<template v-slot:empty>
+				<u-empty :text="!isLogin ? '您还没有登录' : '暂无相关订单'" icon="/static/workbench/emptyIcon1.png">
+					<u-button size="small" text="去登录" color="linear-gradient(to right, #35c99d, #27aea7)"
+						:customStyle="{ marginTop: '20rpx' }" v-if="!isLogin" @click="goLogin">
+					</u-button>
+				</u-empty>
+			</template>
+		</z-paging>
+
+	</view>
+</template>
+
+<script>
+//   // 订单状态(0:待付款,1:待派单,2:待接单,3:待服务 4:服务中 5:已完成 6:已取消
+//7:已关闭 8:拒绝接单 9:退款成功)
+import { queryOrder } from '@/api/order.js';
+import {
+	getIsLottery,
+} from '@/api/index.js';
+import {
+	delOrder,
+	cancleOrder,
+	cancleApply,
+	orderDeatails,
+} from '@/api/order.js';
+import webviewPoint from "@/components/webviewPoint.vue";
+import { onHide } from '@dcloudio/uni-app';
+export default {
+	components: { webviewPoint },
+	data() {
+		return {
+			searchProductName: '',
+			searchPhoneNumber: '',
+			startDate: '',
+			endDate: '',
+			dataList: [],
+			current: 0,
+			nStatus: '',
+			isLogin: false,
+			// 取消订单
+			cancelOrderPopup: {
+				show: false, // 弹窗显示状态
+				isOk: false, // 是否确认
+				successTip: '您的申请已提交,客服审核中,请注意接听客服电话:19936963696',
+				orderList: [],
+				orderInfo: null, // 当前要取消的订单信息
+				cId: '', // 订单ID
+				reason: '' // 用户输入的取消原因
+			},
+			selectDateKey: '',
+			dateValue: '',
+			datePickerShow: false,
+			feeOptions: [
+				{ label: '免车费', value: 'free' },
+				{ label: '不免车费', value: 'not_free' }
+			],
+			timeOptions: [
+				{ label: '今日', value: 'today' },
+				{ label: '近7天', value: '7days' },
+				{ label: '近30天', value: '30days' },
+				{ label: '近6个月', value: '6months' }
+			]
+		}
+	},
+	onLoad(query) {
+		this.isLogin = !!uni.getStorageSync('wx_copenid');
+	},
+	onShow() {
+		this.queryList(1, 10)
+	},
+	onHide() {
+		this.resetFilter()
+	},
+	methods: {
+		// 搜索订单
+		queryList(pageNo, pageSize) {
+			let params = {
+				current: pageNo,
+				size: pageSize,
+				status: null,
+				projectName: this.searchProductName,
+				contactPhoneNumber: this.searchPhoneNumber || '',
+
+			}
+			queryOrder(params).then(res => {
+				if (res.data.code === 200) {
+					if (!res.data.data) return
+					this.dataList = res.data.data.records;
+					// let data = res.data.data.records.forEach(item => {
+					// 	item.dtCreateTime = item.dtCreateTime.replace('T', ' ')
+					// });
+					this.$refs.paging.complete(this.dataList);
+
+				} else {
+					this.$refs.paging.complete([]);
+
+				}
+			});
+		},
+		// 跳转搜索订单
+		goSearch(e) {
+			const keyword = this.searchProductName.trim()
+			if (!keyword) return uni.showToast({ title: '请输入搜索内容', icon: 'none' })
+
+			// 手机号正则:1开头,第二位3-9,后面9位数字,总共11位
+			const phoneReg = /^1[3-9]\d*$/
+			let searchType = ''
+
+			if (phoneReg.test(keyword)) {
+				searchType = 'phone' // 手机号搜索
+				this.searchProductName = keyword 
+			} else {
+				searchType = 'name' // 项目名称搜索
+				this.searchProductName = keyword 
+			}
+			this.$refs.paging.reload();
+
+		},
+
+		// 格式化日期显示
+		formatter(type, value) {
+			if (type === 'year') {
+				return `${value}年`;
+			}
+			if (type === 'month') {
+				return `${value}月`;
+			}
+			if (type === 'day') {
+				return `${value}日`;
+			}
+			return value;
+		},
+		// 支付订单
+		onPayOrder(item) {
+			if (item.remainingTime <= 0) {
+				uni.showToast({
+					title: '订单已超时',
+					icon: 'none'
+				})
+			} else {
+				let str = uni.$u.queryParams({
+					page: 'order',
+					orderNo: item.orderNo
+				});
+				uni.navigateTo({
+					url: `/pages/identify/pay_order${str}`
+				})
+			}
+
+		},
+		// 取消退单申请
+		onCancleApply(item) {
+			uni.showModal({
+				title: '提示',
+				content: '确定取消退单申请吗?',
+				showCancel: true,
+				success: (res) => {
+					if (res.confirm) {
+						let params = {
+							cId: item.cId
+						}
+						cancleApply(params).then(res => {
+							if (res.data.code == 200) {
+								this.$refs.paging.reload();
+								uni.showToast({
+									title: '已取消',
+									icon: 'none'
+								})
+							} else {
+								uni.showToast({
+									title: res.data.msg,
+									icon: 'none'
+								})
+							}
+						})
+					}
+				}
+			})
+		},
+		// 取消订单
+		onCancleOrder(item) {
+			this.cancelOrderPopup.cId = item.cId
+			this.cancelOrderPopup.orderList = item.cGoods || []
+			this.cancelOrderPopup.show = true;
+		},
+		// 提交退单申请
+		onSubmitApply() {
+			if (this.cancelOrderPopup.reason === '') {
+				uni.showToast({
+					title: '请输入退单原因',
+					icon: 'none'
+				})
+				return
+			}
+			let params = {
+				cId: this.cancelOrderPopup.cId,
+				cancelReason: this.cancelOrderPopup.reason
+			}
+			cancleOrder(params).then(res => {
+				if (res.data.code == 200) {
+					this.cancelOrderPopup.isOk = true
+					this.$refs.paging.reload();
+				} else {
+					uni.showToast({
+						title: res.data.msg,
+						icon: 'none'
+					})
+				}
+			})
+		},
+
+		// 删除订单
+		onDelOrder(item) {
+			uni.showModal({
+				title: '提示',
+				content: '确定删除订单吗?',
+				showCancel: true, // 是否显示取消按钮
+				success: (res) => {
+					if (res.confirm) {
+						let params = {
+							cId: item.cId
+						}
+						delOrder(params).then(res => {
+							if (res.data.code == 200) {
+								this.$refs.paging.reload();
+								uni.showToast({
+									title: '删除订单成功!',
+									icon: 'none'
+								})
+							} else {
+								uni.showToast({
+									title: res.data.msg,
+									icon: 'none'
+								})
+							}
+						})
+					}
+				}
+			})
+		},
+
+		// 切换订单
+		onTabChange(code, index) {
+			this.current = index;
+			this.nStatus = code;
+			this.$refs.paging.reload();
+		},
+		// 跳转订单详情
+		goDetails(cid) {
+			let str = uni.$u.queryParams({
+				cid
+			});
+			uni.navigateTo({
+				url: `/pages/order/order_detail${str}`
+			});
+		},
+		goEvaluate(item) {
+			console.log(item)
+			let str = uni.$u.queryParams({
+				orderNo: item.orderNo,
+				cId: item.cId,
+				cJsId: item.cJsId,
+				cName: item.js.cName,
+				nickName: item.wxUser.nickName
+			});
+			uni.navigateTo({
+				url: `/pages/order/comment${str}`
+			});
+		},
+		goLogin() {
+			uni.navigateTo({
+				url: '/setting/myNew/phone',
+			})
+			// uni.navigateTo({
+			// 	url: '/pages/login/wxLogin'
+			// })
+		},
+	},
+}
+</script>
+
+<style scoped lang="scss">
+::v-deep .searchClass {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	padding: 12rpx 32rpx;
+
+	.u-search {
+		width: 622rpx;
+		height: 64rpx;
+		background: #FFFFFF;
+		border-radius: 66rpx 66rpx 66rpx 66rpx;
+		border: 1rpx solid #333335;
+
+		.u-search__content {
+			background: #FFFFFF !important;
+		}
+
+		.u-search__content__input {
+			background: #fff !important;
+			height: 30rpx !important;
+
+			.u-search__content__input--placeholder {
+				font-weight: 400 !important;
+				font-size: 26rpx !important;
+				color: #AAA !important;
+				height: 30rpx !important;
+			}
+		}
+
+
+		.u-search__action {
+			margin-right: 8rpx;
+			width: 104rpx;
+			height: 48rpx;
+			background: #333335;
+			border-radius: 32rpx 32rpx 32rpx 32rpx;
+
+			font-weight: 400;
+			font-size: 28rpx;
+			color: #FFFFFF;
+			line-height: 48rpx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+
+		}
+
+
+	}
+
+	.orderBox {
+		margin-left: 16rpx;
+		height: 68rpx;
+	}
+
+
+}
+
+::v-deep .zp-view-super {
+	background-color: #F7F8FA !important;
+}
+
+.page-container {
+	background: linear-gradient(180deg, #C1FFF8 0%, #B8FFF3 34%, #F5FFFF 100%);
+
+	.tab-box {
+		padding: 0 15rpx;
+		height: 80rpx;
+		display: flex;
+		justify-content: space-around;
+		align-items: center;
+		font-size: 30rpx;
+		z-index: 999;
+		background: radial-gradient(circle, #fcfdff, #fcfdff);
+
+		.item {
+			height: 100%;
+			font-weight: 400;
+			font-size: 28rpx;
+			color: #86909C;
+			display: flex;
+			align-items: center;
+
+		}
+
+		.active {
+			font-weight: 500;
+			font-size: 36rpx;
+			color: #1D2129;
+			text-align: center;
+			position: relative;
+			z-index: 99999 !important;
+
+			&::after {
+				content: '';
+				z-index: -1 !important;
+				position: absolute;
+				bottom: 18rpx;
+				left: 50%;
+				transform: translateX(-50%);
+
+				width: 100%;
+				height: 8rpx;
+				background: linear-gradient(263deg, #45FFD7 0%, #7FFFBD 100%);
+				border-radius: 2rpx 2rpx 2rpx 2rpx;
+			}
+		}
+	}
+
+	.list-box {
+		flex: 1;
+		padding: 32rpx;
+
+		.item {
+			width: 100%;
+			padding: 32rpx;
+			margin-bottom: 10rpx;
+			font-size: 28rpx;
+			margin-bottom: 28rpx;
+			box-sizing: border-box;
+			background: #FFFFFF;
+			border-radius: 16rpx 16rpx 16rpx 16rpx;
+
+			.row1 {
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				font-weight: 400;
+				font-size: 28rpx;
+				color: #4E5969;
+				text-align: left;
+
+				.status {
+					background: #FFF0ED;
+					border-radius: 4rpx 4rpx 4rpx 4rpx;
+
+					font-weight: 400;
+					font-size: 24rpx;
+					color: #FF531C;
+					line-height: 34rpx;
+					text-align: center;
+				}
+
+				.status1 {
+					background: #FFF7E7;
+					border-radius: 4rpx 4rpx 4rpx 4rpx;
+
+					font-weight: 400;
+					font-size: 24rpx;
+					color: #FF7D00;
+					line-height: 34rpx;
+
+				}
+
+				.status2 {
+					background: #E8FFEA;
+					border-radius: 4rpx 4rpx 4rpx 4rpx;
+
+					font-weight: 400;
+					font-size: 24rpx;
+					color: #00B42A;
+					line-height: 34rpx;
+					text-align: center;
+				}
+
+
+				.status3 {
+					background: #F7F8FA;
+					border-radius: 4rpx 4rpx 4rpx 4rpx;
+
+					font-weight: 400;
+					font-size: 24rpx;
+					color: #4E5969;
+					line-height: 34rpx;
+					text-align: center;
+				}
+
+			}
+
+			.row2 {
+				width: 100%;
+				display: flex;
+				align-items: center;
+				margin-top: 16rpx;
+				font-weight: 400;
+				font-size: 28rpx;
+				color: #4E5969;
+				text-align: left;
+
+				.type {
+					margin-left: 16rpx;
+					display: flex;
+					align-items: center;
+				}
+			}
+
+			.row3 {
+				display: flex;
+				align-items: center;
+				margin-top: 16rpx;
+				font-weight: 400;
+				font-size: 28rpx;
+				color: #4E5969;
+				margin-bottom: 24rpx;
+
+				.cont {
+					margin-left: 40rpx;
+					font-weight: 500;
+					font-size: 28rpx;
+					color: #1D2129;
+				}
+			}
+
+			.row4 {
+				display: flex;
+				margin: 24rpx 0 32rpx 0;
+
+				.title {
+					font-weight: 500;
+					font-size: 30rpx;
+					color: #1D2129;
+				}
+
+				.cont {
+					display: flex;
+					align-items: baseline;
+					font-weight: 400;
+					font-size: 28rpx;
+					color: #1D2129;
+				}
+			}
+
+			.refundStatus1 {
+				margin-top: 16rpx;
+				width: 96rpx;
+				height: 36rpx;
+				background: #FFF2E5;
+				border-radius: 4rpx 4rpx 4rpx 4rpx;
+				border: 1rpx solid #FF7D00;
+
+				font-weight: 400;
+				font-size: 24rpx;
+				color: #FF7D00;
+				text-align: center;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+
+			}
+
+			.refundStatus2 {
+				width: 96rpx;
+				height: 36rpx;
+				background: #FFF2E5;
+				border-radius: 4rpx 4rpx 4rpx 4rpx;
+				border: 1rpx solid #F53F3F;
+
+				font-weight: 400;
+				font-size: 24rpx;
+				color: #F53F3F;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				text-align: center;
+
+			}
+
+			.price {
+				display: flex;
+				align-items: center;
+				justify-content: flex-end;
+				font-weight: 400;
+				font-size: 24rpx;
+				color: #1D2129;
+				line-height: 24rpx;
+				text-align: right;
+			}
+
+			.cont {
+				color: rgb(162, 162, 162);
+				font-size: 26rpx;
+				line-height: 45rpx;
+			}
+
+			.btn {
+
+
+				.button {
+					display: flex;
+					align-items: center;
+					justify-content: flex-end;
+
+					.pay {
+						margin-left: 24rpx;
+						margin-top: 24rpx;
+						display: flex;
+						align-items: center;
+						justify-content: center;
+						width: 152rpx;
+						height: 64rpx;
+						background: rgba(51, 51, 53, 0.05);
+						border-radius: 32rpx 32rpx 32rpx 32rpx;
+
+						font-weight: 400;
+						font-size: 26rpx;
+						color: #1D2129;
+
+
+					}
+
+					.alarm {
+						background-color: #F53F3F;
+						color: #FFFFFF;
+					}
+
+					.main {
+						background-color: #333335;
+						font-weight: 500;
+						color: #FFFFFF;
+					}
+
+					.pay:last-child {
+						background-color: #333335;
+						font-weight: 500;
+						font-size: 26rpx;
+						color: #FFFFFF;
+						display: flex;
+						align-items: center;
+						justify-content: center;
+
+					}
+
+					.cancel {
+						width: 152rpx;
+						height: 48rpx;
+						border-radius: 98rpx;
+						border: 2rpx solid #BBBBBB;
+						padding: 5rpx 30rpx;
+					}
+				}
+			}
+		}
+	}
+
+	.popup-content {
+		width: 90vw;
+		padding: 100rpx 30rpx 30rpx;
+		box-sizing: border-box;
+
+		.table-header {
+			background-color: #FBFBFB;
+		}
+
+		.success-tip {
+			padding: 50rpx;
+			font-size: 32rpx;
+			text-align: center;
+			margin-bottom: 30rpx;
+		}
+
+		.reson {
+			margin: 30rpx;
+		}
+
+		.popup-btn {
+			padding: 0 80rpx;
+			display: flex;
+			justify-content: space-between;
+		}
+	}
+
+
+}
+</style>

+ 1 - 1
src/setting/myNew/forgetPassword.vue

@@ -52,7 +52,7 @@ export default {
       const openid = uni.getStorageSync('wx_copenid')
       const merchantInfo = await this.$utils.checkMerchantStatus(openid)
       if (!merchantInfo) return
-      this.phone = merchantInfo.merchant.tePhone
+      this.phone = merchantInfo.phone
 
     },
     validatePhone(phone) {

+ 1 - 1
src/setting/myNew/useCodeLogin.vue

@@ -127,7 +127,7 @@ export default {
             this.back()
           }else{
             uni.showToast({
-              title: res.data.message,
+              title: res.data.msg,
               icon: 'none'
             })
           }

BIN
src/static/login/clockIcon.png


BIN
src/static/login/emptyIcon.png


BIN
src/static/workbench/arriveIcon.png


BIN
src/static/workbench/checkIcon.png


BIN
src/static/workbench/clockIcon.png


BIN
src/static/workbench/clockIcon2.png


BIN
src/static/workbench/clockIcon3.png


BIN
src/static/workbench/downIcon.png


BIN
src/static/workbench/editIcon.png


BIN
src/static/workbench/emptyIcon.png


BIN
src/static/workbench/emptyIcon1.png


BIN
src/static/workbench/eyeIcon.png


BIN
src/static/workbench/filterIcon.png


BIN
src/static/workbench/finishIcon.png


BIN
src/static/workbench/goedIcon.png


BIN
src/static/workbench/handIcon.png


BIN
src/static/workbench/licenceIcon.png


BIN
src/static/workbench/licenceIcon1.png


BIN
src/static/workbench/licenceIcon2.png


BIN
src/static/workbench/localIcon.png


BIN
src/static/workbench/localIcon3.png


BIN
src/static/workbench/locationIcon.png


BIN
src/static/workbench/moreIcon.png


BIN
src/static/workbench/noGoIcon.png


BIN
src/static/workbench/noSignIcon.png


BIN
src/static/workbench/orderIcon.png


BIN
src/static/workbench/peopleIcon1.png


BIN
src/static/workbench/phoneIcon.png


BIN
src/static/workbench/propleIcon.png


BIN
src/static/workbench/radio.png


BIN
src/static/workbench/redArrow.png


BIN
src/static/workbench/rightIcon.png


BIN
src/static/workbench/serviceingIcon.png


BIN
src/static/workbench/signIcon.png


BIN
src/static/workbench/timeLineIcon.png


BIN
src/static/workbench/upIcon.png


BIN
src/static/workbench/warringIcon.png


+ 18 - 0
src/uni_modules/yi-code/changelog.md

@@ -0,0 +1,18 @@
+## 1.0.8(2024-10-05)
+修复vue2输入内容获取为空的BUG
+## 1.0.7(2024-09-02)
+修复部分情况下undefined BUG
+## 1.0.6(2024-08-01)
+增加ref方法 clear 清除输入内容
+## 1.0.5(2024-06-26)
+修复因text-align导致的input显示问题
+## 1.0.4(2024-06-26)
+更新隐藏input长度过短显示数字BUG
+## 1.0.3(2024-06-19)
+修复插件取消聚焦时的动画隐藏问题
+## 1.0.2(2024-05-15)
+支持自定义隐藏显示时的字符, 新增hide属性String,传入参数为隐藏显示的字符(一般使用 * 号)
+## 1.0.1(2024-03-23)
+修复在某些设备显示输入框数字的bug
+## 1.0.0(2024-03-23)
+首次更新三种样式验证框效果

+ 226 - 0
src/uni_modules/yi-code/components/yi-code/yi-code.vue

@@ -0,0 +1,226 @@
+<template>
+	<view class="yi-code">
+		<view class="yi-code-show">
+			<block v-for="i in numberArr">
+				<view :class="'yi-code-show-item' + ((codes.length === i && isFocus) ? ' yi-code-show-active' : '')"
+					:style="type !== 'block' ? (type === 'line' ? 'border-top: 0; border-left: 0; border-right: 0; border-radius: 0; border-width: 2px;' : 'border-style: dashed;') : ''">
+					{{ showVal(codes[i]) }}
+				</view>
+			</block>
+		</view>
+		<view class="yi-code-hide" :style="'width: ' + (width * 2) + 'rpx;left: -' + width + 'rpx;'">
+			<input ref="codeInput" v-model="value" :style="'width: ' + (width * 2) + 'rpx;'" :focus="focus"
+				@focus="onFocus" @blur="onBlur" :type="inputType" @input="onChange" :maxlength="maxlength" />
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	props: {
+		/**
+		 * @description 宽度 rpx
+		 */
+		width: {
+			type: Number,
+			default: 500,
+		},
+		/**
+		 * @description 是否自动聚焦
+		 */
+		focus: {
+			type: Boolean,
+			default: true,
+		},
+		/**
+		 * @description 隐藏字符(密码效果)
+		 */
+		hide: {
+			type: String,
+			default: '',
+		},
+		/**
+		 * @description 验证码长度
+		 */
+		maxlength: {
+			type: Number,
+			default: 6
+		},
+		/**
+		 * @description 样式类型 block 方框, dashed 虚线方框,line 线
+		 */
+		type: {
+			type: String,
+			default: 'block'
+		},
+		/**
+		 * @description text | number 
+		 */
+		inputType: {
+			type: String,
+			default: 'number'
+		},
+	},
+	created() {
+		let arr = [];
+		for (let i = 0; i < this.$props.maxlength; i++) {
+			arr.push(i);
+		}
+		this.numberArr = arr;
+	},
+	data() {
+		return {
+			numberArr: [], // 
+			codes: [],
+			value: '',
+			isFocus: false
+		}
+	},
+	mounted() {
+		// 组件挂载后自动聚焦
+		if (this.$props.focus) {
+			this.tryFocus();
+		}
+	},
+	methods: {
+		tryFocus(retryCount = 0) {
+			this.$nextTick(() => {
+				setTimeout(() => {
+					console.log('尝试聚焦,重试次数:', retryCount, 'ref:', this.$refs.codeInput);
+					// 方法1:尝试使用 ref 获取元素
+					if (this.$refs.codeInput) {
+						const inputEl = this.$refs.codeInput;
+						if (inputEl.focus) {
+							inputEl.focus();
+							console.log('验证码输入框聚焦成功(ref方式)');
+							return;
+						}
+						// 小程序中可能需要访问 $el
+						if (inputEl.$el && inputEl.$el.focus) {
+							inputEl.$el.focus();
+							console.log('验证码输入框聚焦成功(ref.$el方式)');
+							return;
+						}
+					}
+					// 方法2:尝试使用 uni.createSelectorQuery
+					uni.createSelectorQuery()
+						.in(this.$el)  // 限定搜索范围
+						.select('.yi-code-hide input')
+						.node()
+						.exec((res) => {
+							console.log('SelectorQuery result:', res);
+							if (res[0] && res[0].node) {
+								res[0].node.focus();
+								console.log('验证码输入框聚焦成功(SelectorQuery方式)');
+							} else if (retryCount < 5) {
+								this.tryFocus(retryCount + 1);
+							}
+						});
+				}, 200 + retryCount * 150);
+			});
+		},
+		clear() {
+			this.codes = []
+			this.value = ''
+		},
+		onFocus() {
+			this.isFocus = true
+		},
+		onBlur() {
+			this.isFocus = false
+		},
+		showVal(v) {
+			return v ? (this.hide || v) : '';
+		},
+		onChange(e) {
+			// 兼容不同平台的事件对象
+			let str = '';
+			if (e && e.detail && e.detail.value !== undefined) {
+				str = e.detail.value;
+			} else if (e && e.target && e.target.value !== undefined) {
+				str = e.target.value;
+			} else if (typeof e === 'string') {
+				str = e;
+			}
+			if (str) {
+				// 截断超过 maxlength 的部分
+				const maxLen = this.$props.maxlength;
+				str = String(str).slice(0, maxLen);
+				this.value = str;
+				this.codes = str.split('');
+				this.$emit('onChange', str);
+				if (this.codes.length === maxLen) {
+					this.$emit('onComplete', str);
+				}
+			} else {
+				this.codes = [];
+				this.$emit('onChange', '');
+			}
+		}
+	}
+}
+</script>
+
+<style lang="scss">
+.yi-code {
+	position: relative;
+	overflow: hidden;
+	text-align: unset;
+	width: 100%;
+
+	.yi-code-show {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		
+
+		.yi-code-show-item {
+			box-sizing: border-box;
+			width: 96rpx;
+			height: 96rpx;
+			background: #F7F8FA;
+			border-radius: 8rpx 8rpx 8rpx 8rpx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+		}
+
+		.yi-code-show-active {
+			width: 96rpx;
+			height: 96rpx;
+			background: #F7F8FA;
+			border-radius: 8rpx 8rpx 8rpx 8rpx;
+			border: 1rpx solid #19D29B;
+
+			// border-color: #ff5500;
+			// border-width: 2px;
+			//animation: myfirst 600ms infinite;
+
+			@keyframes myfirst {
+				0% {
+					opacity: 0.1
+				}
+
+				100% {
+					opacity: 1
+				}
+			}
+		}
+	}
+
+	.yi-code-hide {
+		position: absolute;
+		z-index: 99;
+		left: 0;
+		top: 0;
+		height: 96rpx;
+		opacity: 0;
+		text-align: unset;
+
+		input {
+			height: 96rpx;
+			text-align: unset;
+		}
+	}
+}
+</style>

+ 83 - 0
src/uni_modules/yi-code/package.json

@@ -0,0 +1,83 @@
+{
+  "id": "yi-code",
+  "displayName": "验证码输入框组件、密码框、支持多种样式",
+  "version": "1.0.8",
+  "description": "动效流畅的验证码输入框组件,收藏勿走丢,详情简介有扫码预览和更多模板库地址",
+  "keywords": [
+    "验证码",
+    "输入框"
+],
+  "repository": "",
+"engines": {
+  },
+  "dcloudext": {
+    "type": "component-vue",
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "插件不采集任何数据",
+      "permissions": "无"
+    },
+    "npmurl": ""
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "y"
+      },
+      "client": {
+        "Vue": {
+          "vue2": "y",
+          "vue3": "y"
+        },
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y",
+          "app-uvue": "u"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y",
+          "钉钉": "y",
+          "快手": "y",
+          "飞书": "y",
+          "京东": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        }
+      }
+    }
+  }
+}

+ 102 - 0
src/uni_modules/yi-code/readme.md

@@ -0,0 +1,102 @@
+### 线上预览
+![image](https://masteryi-localhost.oss-cn-hangzhou.aliyuncs.com/uni-app/yi-code-qrcode.png)
+
+[更多UNI-APP模板点击查看](https://www.masteryi.cn/uni-app)
+
+### 使用方法
+`<yi-code @onComplete="complete" @onChange="change"></yi-code>`
+
+### 参数
+
+| 属性            | 类型             | 说明                                | 默认值    |
+|---------------|----------------|-----------------------------------|--------|
+| width         | number         | 宽度 rpx                            | 500    |
+| maxlength     | number         | 验证码长度                             | 6      |
+| focus         | boolean        | 是否自动聚焦                            | true   |
+| type          | string      | 组件风格支持block方框, dashed 虚线方框,line 线 | block  |
+| inputType     | string    | 输入框类型 支持text、number               | number | 
+| hide     		| string    | 隐藏字符,传值则会使用该字符隐藏对应的验证码数字,类似于传 * 模拟密码遮盖效果  | null | 
+| @onComplete    | (code: string) |  输入长度===maxlength时的完成回调onComplete            |   null     |
+| @onChange      | (code: string) |  code值变更回调onChange                         |   null     |
+| clear      | ref function |  清除输入内容                      |        |
+
+### 示例代码
+```
+<template>
+	<view class="page">
+		<view class="card">
+			<view class="title">block</view>
+			<view><button @click="onClear" style="background: #ff5500; color: #fff;">清除内容</button></view>
+			<view class="body">
+				<yi-code ref="code" :width="600" @onComplete="complete" @onChange="change"></yi-code>
+			</view>
+		</view>
+		
+		<view class="card">
+			<view class="title">dashed</view>
+			<view class="body">
+				<yi-code :focus="false" :maxlength="5" type="dashed"></yi-code>
+			</view>
+		</view>
+		
+		<view class="card">
+			<view class="title">line</view>
+			<view class="body">
+				<yi-code :focus="false" :maxlength="4" type="line"></yi-code>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	// 注意测试案例的时候 focus只保持一个自动聚焦, 其他设置false,防止调试输入不了;
+	
+	export default {
+		data() {
+			return {
+			}
+		},
+		onLoad() {
+			
+		},
+		methods: {
+			onClear(){
+				this.$refs.code.clear()	
+			},
+			complete(code){
+				console.log(`complete:${code}`);
+			},
+			change(code){
+				console.log(`change:${code}`);
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.page {
+		display: flex;
+		flex-wrap: wrap;
+		.card{
+			width: 720rpx;
+			margin: 30rpx auto;
+			border: 1px solid #f0f0f0;
+			border-radius: 12rpx;
+			
+			.title{
+				font-size: 14px;
+				text-align: center;
+				line-height: 30px;
+				border-bottom: 1px solid #f0f0f0;
+			}
+			
+			.body{
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				height: 150rpx;
+			}
+		}
+	}
+</style>
+```

+ 11 - 2
src/utils/index.js

@@ -207,12 +207,21 @@ const otherUtil = {
 			if (!profileOpenid) return null;
 			const response = await getTechnicianInfo({ openid: profileOpenid });
 			if (response.data.code === 200) {
-				return adaptTechnicianProfile(response.data.data);
+				//return adaptTechnicianProfile(response.data.data);
+			return response.data.data;
+			}else{
+				uni.showToast({
+					title: response.data.msg,
+					icon: 'none'
+				})
 			}
 			// 接口非200返回null
 			return null;
 		} catch (err) {
-			console.log(err, 'err')
+			uni.showToast({
+				title: err.msg,
+				icon: 'none'
+			})
 			// 请求报错也返回null
 			return null;
 		}

+ 3 - 1
src/utils/request.js

@@ -17,8 +17,10 @@ export default (params) => {
 				if (res.statusCode === 200) {
                     // 401
                     if (res.data.code == 401) {
-						uni.clearStorage();
+						console.log(res.data,'401')
+						// uni.clearStorage();
 						// uni.removeStorageSync('access-token');
+						
                     }
 					resolve(res);
                 } else {

+ 130 - 48
src/workbench/contract/detail.vue

@@ -1,14 +1,32 @@
 <template>
 	<view class="detail-page">
-		<web-view v-if="fileType === 'pdf' && fileUrl" :src="fileUrl"></web-view>
+		<!-- 加载中状态 -->
+		<view v-if="loading" class="loading">
+			<view class="loading-icon"></view>
+			<text>加载中...</text>
+		</view>
+		
+		<!-- PDF 预览 -->
+		<view v-else-if="fileType === 'pdf' && fileUrl" class="pdf-wrapper">
+			<web-view 
+				:src="fileUrl"
+				class="web-view"
+				@load="onWebViewLoad"
+				@error="onWebViewError"
+			></web-view>
+		</view>
 
-		<scroll-view v-else-if="fileType === 'image' && fileUrl" scroll-y class="image-scroll">
+		<!-- 图片预览 -->
+		 
+		<scroll-view v-else-if="(fileType === 'png' || fileType === 'jpg' || fileType === 'jpeg') && fileUrl" scroll-y class="image-scroll">
 			<image class="contract-image" :src="fileUrl" mode="widthFix" @click="previewImage" />
 		</scroll-view>
 
-		<view class="empty" v-else>
-			<text class="empty-text">{{ fileUrl ? '暂不支持预览该合同文件' : '暂无合同文件' }}</text>
-			<view class="open-btn" v-if="fileUrl" @click="openFile">打开文件</view>
+		<!-- 空状态 -->
+		<view v-else class="empty">
+			<text class="empty-text">{{ !fileUrl ? '暂无合同文件' : '文件加载失败' }}</text>
+			<view v-if="fileUrl" class="empty-tip">请检查文件链接是否有效</view>
+			<view @click="goBack">返回</view>
 		</view>
 	</view>
 </template>
@@ -19,11 +37,27 @@ export default {
 		return {
 			fileType: '',
 			fileUrl: '',
+			loading: true,
+			webViewError: false,
 		}
 	},
 	onLoad(query) {
-		this.fileType = query.fileType || 'unknown'
-		this.fileUrl = decodeURIComponent(query.fileUrl || '')
+		console.log('detail page query:', query) // 调试日志
+		
+		this.fileType = query.fileType || 'pdf'
+		this.fileUrl = query.fileUrl ? decodeURIComponent(query.fileUrl) : ''
+		
+		// 验证 URL 是否有效
+		if (this.fileUrl && !this.isValidUrl(this.fileUrl)) {
+			console.error('无效的文件URL:', this.fileUrl)
+			this.fileUrl = ''
+		}
+		
+		// 延迟显示,避免闪烁
+		setTimeout(() => {
+			this.loading = false
+		}, 500)
+		
 		if (query.title) {
 			uni.setNavigationBarTitle({
 				title: decodeURIComponent(query.title),
@@ -31,6 +65,15 @@ export default {
 		}
 	},
 	methods: {
+		isValidUrl(string) {
+			try {
+				const url = new URL(string)
+				return url.protocol === 'http:' || url.protocol === 'https:'
+			} catch (_) {
+				return false
+			}
+		},
+		
 		previewImage() {
 			if (!this.fileUrl) return
 			uni.previewImage({
@@ -38,32 +81,22 @@ export default {
 				current: this.fileUrl,
 			})
 		},
-		openFile() {
-			if (!this.fileUrl) return
-
-			// #ifdef H5
-			if (typeof window !== 'undefined') {
-				window.open(this.fileUrl, '_blank')
-				return
-			}
-			// #endif
-
-			uni.downloadFile({
-				url: this.fileUrl,
-				success: res => {
-					if (res.statusCode === 200) {
-						uni.openDocument({
-							filePath: res.tempFilePath,
-							showMenu: true,
-						})
-					}
-				},
+		
+		onWebViewLoad() {
+			console.log('web-view 加载成功')
+		},
+		
+		onWebViewError(e) {
+			console.error('web-view 加载失败:', e)
+			this.webViewError = true
+			this.loading = false
+		},
+		
+		goBack() {
+			uni.navigateBack({
 				fail: () => {
-					uni.showToast({
-						title: '文件打开失败',
-						icon: 'none',
-					})
-				},
+					uni.switchTab({ url: '/pages/index/index' })
+				}
 			})
 		},
 	},
@@ -71,9 +104,55 @@ export default {
 </script>
 
 <style lang="scss" scoped>
+::v-deep #toolbar{
+	display: hidden!important;
+}
 .detail-page {
 	min-height: 100vh;
+	height: 100vh;
 	background: #f5f5f5;
+	position: relative;
+	overflow: hidden;
+}
+
+.loading {
+	position: fixed;
+	top: 50%;
+	left: 50%;
+	transform: translate(-50%, -50%);
+	text-align: center;
+	z-index: 100;
+	background: rgba(255,255,255,0.9);
+	padding: 40rpx 60rpx;
+	border-radius: 16rpx;
+}
+
+.loading-icon {
+	width: 60rpx;
+	height: 60rpx;
+	border: 4rpx solid #e0e0e0;
+	border-top-color: #07c160;
+	border-radius: 50%;
+	animation: spin 1s linear infinite;
+	margin: 0 auto 20rpx;
+}
+
+@keyframes spin {
+	to { transform: rotate(360deg); }
+}
+
+.pdf-wrapper {
+	width: 100%;
+	height: 100vh;
+	position: relative;
+}
+
+.web-view {
+	width: 100%;
+	height: 100%;
+	position: absolute;
+	top: 0;
+	left: 0;
 }
 
 .image-scroll {
@@ -86,28 +165,31 @@ export default {
 }
 
 .empty {
-	min-height: 100vh;
 	display: flex;
 	flex-direction: column;
 	align-items: center;
-	padding-top: 120rpx;
-	box-sizing: border-box;
+	justify-content: center;
+	min-height: 60vh;
+	padding: 120rpx 40rpx;
 }
 
 .empty-text {
-	font-size: 28rpx;
-	color: #999999;
-	line-height: 40rpx;
+	font-size: 32rpx;
+	color: #666;
+	margin-bottom: 16rpx;
+}
+
+.empty-tip {
+	font-size: 26rpx;
+	color: #999;
+	margin-bottom: 48rpx;
 }
 
-.open-btn {
-	margin-top: 32rpx;
-	height: 72rpx;
-	line-height: 72rpx;
-	padding: 0 40rpx;
-	border-radius: 36rpx;
-	background: #1d2129;
-	color: #ffffff;
-	font-size: 28rpx;
+.back-btn {
+	background: #07c160;
+	color: #fff;
+	padding: 24rpx 80rpx;
+	border-radius: 44rpx;
+	font-size: 30rpx;
 }
-</style>
+</style>

+ 24 - 57
src/workbench/contract/index.vue

@@ -55,67 +55,34 @@ export default {
 			return this.getBrowserStorageUserId() || uni.getStorageSync('userId')
 		},
 		loadList() {
-			const userId = this.getUserId()
-			if (!userId) {
-				this.contractList = []
-				this.errorText = '未获取到用户信息'
-				uni.showToast({
-					title: this.errorText,
-					icon: 'none',
-				})
-				return
-			}
-
-			this.loading = true
-			this.errorText = ''
-			getContractRecords({ userId })
-				.then(res => {
-					const body = res && res.data ? res.data : {}
-					if (body.code === 200) {
-						this.contractList = normalizeContractRecords(body.data)
-						this.errorText = ''
-						return
-					}
+			this.contractList = MOCK_CONTRACT_LIST
 
-					this.contractList = []
-					this.errorText = body.msg || '合同获取失败'
-					uni.showToast({
-						title: this.errorText,
-						icon: 'none',
-					})
-				})
-				.catch(() => {
-					this.contractList = []
-					this.errorText = '合同获取失败'
-					uni.showToast({
-						title: this.errorText,
-						icon: 'none',
-					})
-				})
-				.finally(() => {
-					this.loading = false
-				})
+			// 接口就绪后替换
+			getContractRecords({
+				userId: uni.getStorageSync('userId'),
+			}).then(res => {
+				console.log(res)
+				if (res.data.code == 200) {
+					this.contractList = res.data.data.file.map(item => ({
+						signerName: res.data.data.signerName,
+						signTime: res.data.data.signTime,
+						merchantId: res.data.data.merchantId,
+						contractName: item.contractName,
+						fileUrl: item.fileUrl,
+						id: item.id,
+					}))
+				}
+			})
 		},
 		viewContract(item) {
-			const fileUrl = resolveContractFileUrl(item.fileUrl, baseUrl)
-			if (!fileUrl) {
-				uni.showToast({
-					title: '暂无合同文件',
-					icon: 'none',
-				})
-				return
-			}
-
-			const query = [
-				`id=${encodeURIComponent(item.id)}`,
-				`title=${encodeURIComponent(item.contractName)}`,
-				`fileType=${encodeURIComponent(item.fileType)}`,
-				`fileUrl=${encodeURIComponent(fileUrl)}`,
-			].join('&')
-
-			uni.navigateTo({
-				url: `/workbench/contract/detail?${query}`,
+			const str = uni.$u.queryParams({
+				id: item.id,
+				title: item.contractName,
+				fileType: item.fileUrl.split('.').pop(),
+				fileUrl: encodeURIComponent(item.fileUrl),
 			})
+			
+			uni.navigateTo({ url: `/workbench/contract/detail${str}` })
 		},
 	},
 }

+ 25 - 7
src/workbench/fare/index.vue

@@ -121,11 +121,11 @@ const MOCK_OPENED_CATEGORIES = [
 	{ id: '1', name: '上门按摩' },
 	{ id: '3', name: '爬山' },
 ]
-import { saveFareSetting } from '@/api/workbench'
+import { saveFareSetting,getSkillList } from '@/api/workbench'
 export default {
 	data() {
 		return {
-			openedCategories: [...MOCK_OPENED_CATEGORIES],
+			openedCategories: [],
 			settingMode: 'unified',
 			unifiedForm: {
 				dayKm: '',
@@ -140,22 +140,40 @@ export default {
 		},
 	},
 	onLoad() {
-		this.initProjectForms()
-		if (this.openedCategories.length <= 1) {
+		this.getSkillList()
+		setTimeout(() => {
+			this.initProjectForms()
+			if (this.openedCategories.length <= 1) {
 			this.settingMode = 'unified'
 		}
+		}, 500)
+		
 	},
 	methods: {
+		getSkillList() {
+			let params = {
+				auditStatus: "1", //审核状态:0-待审核,1-审核通过,2-审核驳回
+				merchantId: uni.getStorageSync('merchantId'), //商户ID
+			}
+			getSkillList(params).then(res => {
+				if (res.data.code == 200) {
+					this.openedCategories = res.data.data || [];
+				}
+			})
+		},
 		initProjectForms() {
 			this.projectForms = this.openedCategories.map(cat => ({
-				categoryId: cat.id,
-				categoryName: cat.name,
+				categoryId: cat.projectId,
+				categoryName: cat.projectName,
 				dayKm: '',
 				nightKm: '',
 			}))
 		},
 		selectMode(mode) {
-			if (mode === 'byProject' && !this.canSwitchMode) return
+			if (mode === 'byProject' && !this.canSwitchMode) {
+				uni.showToast({ title: '请先开通服务分类', icon: 'none' })
+				return
+			}
 			this.settingMode = mode
 		},
 		onKmInput(scope, field, e, categoryId) {

+ 717 - 0
src/workbench/onlineHours/index.vue

@@ -0,0 +1,717 @@
+<template>
+    <view class="page-container">
+
+
+        <!-- 月份选择栏 -->
+        <view class="month-bar">
+            <view class="month-select" @click="showMonthPicker = true">
+                <text class="month-text">{{ currentYear }}年{{ currentMonth }}月</text>
+                <text class="month-arrow">▾</text>
+            </view>
+        </view>
+
+        <!-- 日历区域 -->
+        <view class="calendar-section">
+            <view class="calendar-header">
+                <text v-for="(day, index) in weekDays" :key="index" class="week-day">{{ day }}</text>
+            </view>
+            <view class="calendar-grid" :class="{ 'collapsed': !calendarExpanded }">
+                <view v-for="(day, index) in calendarDays" :key="index" class="calendar-item" :class="{
+                    'empty': !day.date,
+                    'current': day.isCurrent,
+                    'selected': day.isSelected,
+                    'has-record': day.hasRecord
+                }" @click="selectDate(day)">
+                    <text v-if="day.date" class="day-num">{{ day.date }}</text>
+                    <view v-if="day.hasRecord" class="record-dot"></view>
+                </view>
+            </view>
+            <!-- 展开/收起箭头 -->
+            <view class="calendar-toggle" @click="toggleCalendar">
+                <text class="toggle-arrow" :class="{ 'expanded': calendarExpanded }">▼</text>
+            </view>
+        </view>
+
+        <!-- 工时统计 -->
+        <view class="stats-section">
+            <view class="stats-bar">
+                <view class="stats-icon">
+                    <image class="icon-image" src="/static/login/clockIcon.png" mode="widthFix" />
+                </view>
+                <view class="stats-content">
+                    <text class="stats-label">工时统计:</text>
+                    <text class="stats-value">{{ formatHours(totalHours) }}</text>
+                    <text v-if="totalHours < 8" class="stats-warning">(不足8小时上线要求)</text>
+                </view>
+            </view>
+        </view>
+
+        <!-- 当日工时详情 -->
+        <view class="detail-section">
+            <view class="detail-header">
+                <text class="detail-title">工时:</text>
+                <text class="detail-value">{{ formatHours(selectedDayHours) }}</text>
+            </view>
+
+            <!-- 空状态 -->
+            <view v-if="!hasRecords" class="empty-state">
+                <view class="empty-icon">📦</view>
+                <text class="empty-text">暂无记录</text>
+            </view>
+
+            <!-- 记录列表 -->
+            <view v-else-if="selectedDayRecords.length === 0" class="empty-state">
+                <view class="empty-icon">📦</view>
+                <text class="empty-text">暂无记录</text>
+            </view>
+
+            <view v-else class="record-list">
+                <view v-for="(record, index) in selectedDayRecords" :key="index" class="record-item">
+                    <view class="record-time">
+                        <text class="time-start">{{ record.startTime }}</text>
+                        <text class="time-arrow">→</text>
+                        <text class="time-end">{{ record.endTime }}</text>
+                    </view>
+                    <view class="record-duration">
+                        <text class="duration-text">时长:{{ record.duration }}</text>
+                    </view>
+                </view>
+            </view>
+        </view>
+
+        <!-- 月份选择器弹窗 -->
+        <u-popup :show="showMonthPicker" mode="bottom" :safe-area-inset-bottom="true">
+            <view class="month-picker-container">
+                <u-datetime-picker confirmColor="#fff" title="选择月份" ref="datetimePicker" :show="showMonthPicker"
+                    v-model="value1" mode="year-month" @cancel="showMonthPicker = false" :formatter="formatter"
+                    @confirm="handleConfirm"></u-datetime-picker>
+            </view>
+        </u-popup>
+    </view>
+</template>
+
+<script>
+export default {
+    data() {
+        return {
+            value1: Number(new Date()),
+            currentYear: 2025,
+            currentMonth: 12,
+            selectedYear: 2025,
+            selectedMonth: 12,
+            selectedDate: null,
+            showMonthPicker: false,
+            weekDays: ['日', '一', '二', '三', '四', '五', '六'],
+            calendarDays: [],
+            workRecords: [], // 模拟数据
+            totalHours: 0,
+            selectedDayHours: 0,
+            selectedDayRecords: [],
+            calendarExpanded: false, // 新增:日历展开状态
+        }
+    },
+    computed: {
+        hasRecords() {
+            return this.workRecords.length > 0
+        },
+        monthList() {
+            const list = []
+            const now = new Date()
+            const currentYear = now.getFullYear()
+            const currentMonth = now.getMonth() + 1
+
+            // 生成最近3年的月份列表
+            for (let year = currentYear - 2; year <= currentYear; year++) {
+                for (let month = 1; month <= 12; month++) {
+                    if (year === currentYear && month > currentMonth) break
+                    list.push({ year, month })
+                }
+            }
+            return list.reverse()
+        }
+    },
+    onLoad() {
+        this.showMonthPicker = false
+        // 初始化当前年月
+        const now = new Date(this.value1)
+        this.currentYear = now.getFullYear()
+        this.currentMonth = now.getMonth() + 1
+        this.selectedYear = this.currentYear
+        this.selectedMonth = this.currentMonth
+        this.selectedDate = now.getDate()
+
+        this.generateCalendar()
+        this.calculateTotalHours()
+        this.loadSelectedDayRecords()
+    },
+    onReady() {
+    },
+    methods: {
+        goBack() {
+            uni.navigateBack()
+        },
+        formatter(type, value) {
+            if (type === 'year') {
+                return `${value}年`
+            }
+            if (type === 'month') {
+                return `${value}月`
+            }
+            return value
+        },
+        handleConfirm(e) {
+            this.showMonthPicker = false
+            // 关键:更新 currentYear 和 currentMonth,日历才会变化
+            const selectedDate = new Date(e.value)
+            this.currentYear = selectedDate.getFullYear()
+            this.currentMonth = selectedDate.getMonth() + 1
+            this.selectedYear = this.currentYear
+            this.selectedMonth = this.currentMonth
+            // 判断是否选中当前月份
+            const today = new Date()
+            if (this.currentYear === today.getFullYear() && this.currentMonth === today.getMonth() + 1) {
+                // 当前月份,选中今天
+                this.selectedDate = today.getDate()
+            } else {
+                // 其他月份,不选中任何日期
+                this.selectedDate = null
+            }
+
+            this.generateCalendar()
+            this.calculateTotalHours()
+            this.loadSelectedDayRecords()
+        },
+
+        generateCalendar() {
+            const year = this.currentYear
+            const month = this.currentMonth
+            const firstDay = new Date(year, month - 1, 1)
+            const lastDay = new Date(year, month, 0)
+            const daysInMonth = lastDay.getDate()
+            const startWeekDay = firstDay.getDay()
+
+            this.calendarDays = []
+
+            // 填充空白日期
+            for (let i = 0; i < startWeekDay; i++) {
+                this.calendarDays.push({ date: null, isCurrent: false, isSelected: false, hasRecord: false })
+            }
+
+            // 填充当月日期
+            const today = new Date()
+            for (let i = 1; i <= daysInMonth; i++) {
+                const dateStr = `${year}-${String(month).padStart(2, '0')}-${String(i).padStart(2, '0')}`
+                const hasRecord = this.workRecords.some(item => item.date === dateStr)
+                this.calendarDays.push({
+                    date: i,
+                    fullDate: dateStr,
+                    isCurrent: today.getFullYear() === year && today.getMonth() + 1 === month && today.getDate() === i,
+                    isSelected: this.selectedDate === i,
+                    hasRecord: hasRecord
+                })
+            }
+        },
+
+        selectDate(day) {
+            if (!day.date) return
+
+            this.selectedDate = day.date
+            this.calendarDays.forEach(d => {
+                d.isSelected = d.date === day.date
+            })
+
+            this.loadSelectedDayRecords()
+        },
+        toggleCalendar() {
+            this.calendarExpanded = !this.calendarExpanded
+        },
+
+        loadSelectedDayRecords() {
+            const dateStr = `${this.currentYear}-${String(this.currentMonth).padStart(2, '0')}-${String(this.selectedDate).padStart(2, '0')}`
+            const dayData = this.workRecords.find(item => item.date === dateStr)
+
+            if (dayData) {
+                this.selectedDayRecords = dayData.records
+                this.selectedDayHours = this.calculateHours(dayData.records)
+            } else {
+                this.selectedDayRecords = []
+                this.selectedDayHours = 0
+            }
+        },
+
+        calculateHours(records) {
+            let totalMinutes = 0
+            records.forEach(record => {
+                const match = record.duration.match(/(\d+)小时(\d+)分/)
+                if (match) {
+                    totalMinutes += parseInt(match[1]) * 60 + parseInt(match[2])
+                }
+            })
+            return totalMinutes / 60
+        },
+
+        calculateTotalHours() {
+            const monthRecords = this.workRecords.filter(item => {
+                return item.date.startsWith(`${this.currentYear}-${String(this.currentMonth).padStart(2, '0')}`)
+            })
+
+            let totalMinutes = 0
+            monthRecords.forEach(item => {
+                item.records.forEach(record => {
+                    const match = record.duration.match(/(\d+)小时(\d+)分/)
+                    if (match) {
+                        totalMinutes += parseInt(match[1]) * 60 + parseInt(match[2])
+                    }
+                })
+            })
+
+            this.totalHours = totalMinutes / 60
+        },
+
+        formatHours(hours) {
+            if (!hours || hours <= 0) return '--:--'
+            const h = Math.floor(hours)
+            const m = Math.round((hours - h) * 60)
+            return `${h}小时${m}分`
+        },
+
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+::v-deep .u-toolbar__title {
+    font-weight: 500;
+    font-size: 36rpx;
+    color: #1D2129;
+}
+
+::v-deep .u-picker__view__column__item {
+    font-weight: 400 !important;
+    font-size: 28rpx;
+    color: #1D2129
+}
+
+::v-deep .u-upload__success {
+    display: none;
+}
+
+::v-deep .u-picker {
+    bottom: 136rpx;
+    background-color: #ffffff;
+    position: relative;
+}
+
+::v-deep .u-toolbar__cancel__wrapper {
+    width: 30rpx;
+    height: 30rpx;
+    position: absolute;
+    right: 32rpx;
+    background-image: url('/static/login/closeIcon.png');
+    background-repeat: no-repeat;
+    background-size: 100% 100%;
+
+    .u-toolbar__wrapper__cancel {
+        width: 30rpx;
+        height: 30rpx;
+
+        span {
+            display: none;
+        }
+
+    }
+}
+
+/* 关键:穿透隐藏原生 toolbar,只留插槽内容 */
+.u-toolbar {
+    z-index: 9999 !important;
+    display: block !important;
+}
+
+::v-deep .u-toolbar__cancel__wrapper {
+    color: #666;
+}
+
+::v-deep .u-toolbar__confirm__wrapper {
+    position: fixed;
+    bottom: 0;
+    width: 100%;
+    padding: 24rpx 48rpx;
+
+    .u-toolbar__wrapper__confirm {
+        width: 654rpx;
+        height: 88rpx;
+        background: #333335;
+        border-radius: 60rpx 60rpx 60rpx 60rpx;
+
+        font-weight: 400;
+        font-size: 32rpx;
+        color: #FFFFFF;
+        text-align: center;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+    }
+}
+
+
+
+.page-container {
+    min-height: 100vh;
+    background-color: #f5f5f5;
+}
+
+.header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 60rpx 32rpx 24rpx;
+    background-color: #fff;
+}
+
+.header-left {
+    width: 60rpx;
+    height: 60rpx;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.back-icon {
+    font-size: 48rpx;
+    color: #333;
+}
+
+.header-title {
+    font-size: 34rpx;
+    font-weight: 600;
+    color: #1d2129;
+}
+
+.header-right {
+    width: 60rpx;
+}
+
+.month-bar {
+    background-color: #fff;
+    padding: 20rpx 32rpx;
+    border-bottom: 1rpx solid #f0f0f0;
+}
+
+.month-select {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.month-text {
+    font-size: 32rpx;
+    color: #1d2129;
+    font-weight: 500;
+}
+
+.month-arrow {
+    font-size: 20rpx;
+    color: #86909c;
+    margin-left: 8rpx;
+}
+
+.calendar-section {
+    background-color: #fff;
+    margin-top: 16rpx;
+    padding: 24rpx 32rpx;
+}
+
+.calendar-header {
+    display: flex;
+    margin-bottom: 20rpx;
+}
+
+.week-day {
+    flex: 1;
+    text-align: center;
+    font-size: 26rpx;
+    color: #86909c;
+}
+
+.calendar-grid {
+    display: flex;
+    flex-wrap: wrap;
+}
+
+/* 添加以下样式 */
+.calendar-grid.collapsed {
+    max-height: 160rpx;
+    /* 只显示两行 */
+    overflow: hidden;
+}
+
+.calendar-toggle {
+    text-align: center;
+    padding: 16rpx 0;
+}
+
+.toggle-arrow {
+    font-size: 20rpx;
+    color: #86909c;
+    transition: transform 0.3s;
+    display: inline-block;
+}
+
+.toggle-arrow.expanded {
+    transform: rotate(180deg);
+}
+
+.calendar-item {
+    width: calc(100% / 7);
+    height: 80rpx;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    position: relative;
+}
+
+.calendar-item.empty {
+    pointer-events: none;
+}
+
+.calendar-item.current .day-num {
+    background-color: #07c160;
+    color: #fff;
+    border-radius: 50%;
+    width: 56rpx;
+    height: 56rpx;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.calendar-item.selected .day-num {
+    border: 2rpx solid #07c160;
+    border-radius: 50%;
+    width: 52rpx;
+    height: 52rpx;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.day-num {
+    font-size: 28rpx;
+    color: #1d2129;
+}
+
+.record-dot {
+    width: 8rpx;
+    height: 8rpx;
+    background-color: #ff7d00;
+    border-radius: 50%;
+    position: absolute;
+    bottom: 8rpx;
+}
+
+.stats-section {
+    background-color: #fff;
+    margin-top: 16rpx;
+    padding: 20rpx 32rpx;
+}
+
+.stats-bar {
+    display: flex;
+    align-items: center;
+    padding: 16rpx 20rpx;
+    background-color: #fff8ec;
+    border-radius: 8rpx;
+}
+
+.stats-icon {
+    width: 48rpx;
+    height: 48rpx;
+    border-radius: 8rpx;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin-right: 16rpx;
+}
+
+.icon-text {
+    font-size: 24rpx;
+}
+
+.stats-content {
+    display: flex;
+    align-items: center;
+    flex-wrap: wrap;
+}
+
+.stats-label {
+    font-size: 28rpx;
+    color: #86909c;
+}
+
+.stats-value {
+    font-size: 28rpx;
+    color: #ff7d00;
+    font-weight: 500;
+}
+
+.stats-warning {
+    font-size: 24rpx;
+    color: #ff7d00;
+    margin-left: 8rpx;
+}
+
+.detail-section {
+    background-color: #fff;
+    margin-top: 16rpx;
+    padding: 24rpx 32rpx;
+    min-height: 300rpx;
+}
+
+.detail-header {
+    display: flex;
+    align-items: center;
+    margin-bottom: 24rpx;
+    padding-bottom: 20rpx;
+    border-bottom: 1rpx solid #f0f0f0;
+}
+
+.detail-title {
+    font-size: 28rpx;
+    color: #86909c;
+}
+
+.detail-value {
+    font-size: 32rpx;
+    color: #1d2129;
+    font-weight: 500;
+}
+
+.empty-state {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    padding: 80rpx 0;
+}
+
+.empty-icon {
+    font-size: 120rpx;
+    margin-bottom: 24rpx;
+}
+
+.empty-text {
+    font-size: 28rpx;
+    color: #86909c;
+}
+
+.record-list {
+    margin-top: 16rpx;
+}
+
+.record-item {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 20rpx 0;
+    border-bottom: 1rpx solid #f5f5f5;
+}
+
+.record-item:last-child {
+    border-bottom: none;
+}
+
+.record-time {
+    display: flex;
+    align-items: center;
+}
+
+.time-start,
+.time-end {
+    font-size: 28rpx;
+    color: #1d2129;
+}
+
+.time-arrow {
+    font-size: 24rpx;
+    color: #86909c;
+    margin: 0 16rpx;
+}
+
+.record-duration {
+    margin-left: 24rpx;
+}
+
+.duration-text {
+    font-size: 26rpx;
+    color: #86909c;
+}
+
+/* 月份选择器弹窗 */
+.month-picker-container {
+    background-color: #fff;
+    border-radius: 24rpx 24rpx 0 0;
+    padding-bottom: env(safe-area-inset-bottom);
+}
+
+.picker-header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 32rpx;
+    border-bottom: 1rpx solid #f0f0f0;
+}
+
+.picker-title {
+    font-size: 32rpx;
+    font-weight: 600;
+    color: #1d2129;
+}
+
+.picker-close {
+    font-size: 48rpx;
+    color: #86909c;
+    line-height: 1;
+}
+
+.month-scroll {
+    max-height: 600rpx;
+    padding: 16rpx 32rpx;
+}
+
+.month-item {
+    padding: 24rpx;
+    border-radius: 8rpx;
+    margin-bottom: 12rpx;
+}
+
+.month-item.active {
+    background-color: #f0f9ff;
+}
+
+.month-item-text {
+    font-size: 28rpx;
+    color: #1d2129;
+}
+
+.month-item.active .month-item-text {
+    color: #07c160;
+    font-weight: 500;
+}
+
+.picker-footer {
+    padding: 24rpx 32rpx;
+    border-top: 1rpx solid #f0f0f0;
+}
+
+.confirm-btn {
+    background-color: #333;
+    color: #fff;
+    text-align: center;
+    padding: 24rpx;
+    border-radius: 44rpx;
+    font-size: 32rpx;
+    font-weight: 500;
+}
+</style>

+ 71 - 67
src/workbench/rating/index.vue

@@ -4,54 +4,43 @@
 			<view class="rating-card" v-for="item in reviewList" :key="item.id">
 				<view class="card-header">
 					<view class="user-info">
-						<image
-							v-if="item.avatar"
-							class="avatar"
-							:src="item.avatar"
-							mode="aspectFill"
-						></image>
-						<view v-else class="avatar placeholder"></view>
-						<text class="nickname">{{ item.nickName }}</text>
+						<image v-if="item.userIcon" class="avatar" :src="item.userIcon" mode="aspectFill"></image>
+					</view>
+					<view style="flex: 1;display: flex;flex-direction: column;justify-content: space-between;">
+						<view style="display: flex;align-items: center;justify-content: space-between;">
+							<text class="nickname">{{ item.nickName }}666</text>
+							<text class="review-time">{{ item.commentTime }}</text>
+						</view>
+						<view class="star-row">
+							<u-rate :value="item.score" :count="5" :allowHalf="true" readonly size="23rpx" gutter="4"
+								activeColor="#F21144" inactiveColor="#e5e5e5"></u-rate>
+							<text class="score-text">{{ formatScore(item.score) }}分</text>
+						</view>
 					</view>
-					<text class="review-time">{{ item.reviewTime }}</text>
-				</view>
 
-				<view class="star-row">
-					<u-rate
-						:value="item.score"
-						:count="5"
-						:allowHalf="true"
-						readonly
-						size="18"
-						gutter="4"
-						activeColor="#FF4D4F"
-						inactiveColor="#e5e5e5"
-					></u-rate>
-					<text class="score-text">{{ formatScore(item.score) }}分</text>
 				</view>
 
+
+
 				<view class="content-wrap">
-					<text
-						class="review-content"
-						:class="{ collapsed: item.needExpand && !isExpanded(item.id), empty: !item.hasContent }"
-					>{{ item.displayContent }}</text>
-					<view
-						v-if="item.needExpand"
-						class="toggle"
-						@click="toggleExpand(item.id)"
-					>
-						<text class="toggle-text">{{ isExpanded(item.id) ? '收起' : '展开' }}</text>
-						<u-icon
-							:name="isExpanded(item.id) ? 'arrow-up' : 'arrow-down'"
-							color="#00C08B"
-							size="12"
-						></u-icon>
+					<text class="review-content" :class="{ collapsed: item.needExpand && !isExpanded(item.id) }">{{
+						item.text }}</text>
+					<view v-if="item.needExpand" class="toggle" @click="toggleExpand(item.id)">
+						<view class="toggle-text">
+							{{ isExpanded(item.id) ? '收起' : '展开' }}
+							<image v-if="isExpanded(item.id)" src="/static/workbench/upIcon.png" mode="aspectFill"
+								style="width: 32rpx;height: 32rpx;margin-top: 5rpx;" />
+
+							<image v-else src="/static/workbench/downIcon.png" mode="aspectFill"
+								style="width: 32rpx;height: 32rpx;margin-top: 5rpx;" />
+
+						</view>
 					</view>
 				</view>
 
 				<view class="service-tag">
 					<text class="tag-hash">#</text>
-					<text class="tag-text">{{ item.serviceName }}</text>
+					<text class="tag-text">{{ item.projectName }}</text>
 				</view>
 			</view>
 		</view>
@@ -60,7 +49,7 @@
 </template>
 
 <script>
-import { userComment } from '@/api/index'
+import { getCommentList } from '@/api/workbench.js'
 import {
 	MOCK_RATING_LIST,
 	normalizeRatingItem,
@@ -81,22 +70,19 @@ export default {
 	methods: {
 		formatScore,
 		loadList() {
-			const openId = uni.getStorageSync('wx_copenid')
-			userComment({ openId })
+			getCommentList({
+				pageNum: 1,
+				pageSize: 10,
+			})
 				.then(res => {
 					if (res.data.code == 200) {
-						const data = res.data.data
-						const raw = Array.isArray(data) ? data : data?.records || []
-						if (raw.length) {
-							this.reviewList = sortByTimeDesc(
-								raw.map((item, index) => normalizeRatingItem(item, index))
-							)
-							return
-						}
+						this.reviewList = res.data.data.records || []
+						this.reviewList.forEach((item, index) => {
+							item.needExpand = normalizeRatingItem(item, index)
+						})
+
 					}
-					this.useMock()
 				})
-				.catch(() => this.useMock())
 		},
 		useMock() {
 			this.reviewList = sortByTimeDesc(
@@ -137,20 +123,19 @@ export default {
 	display: flex;
 	align-items: center;
 	justify-content: space-between;
-	margin-bottom: 20rpx;
 }
 
 .user-info {
-	display: flex;
-	align-items: center;
-	flex: 1;
+	width: 68rpx;
+	height: 68rpx;
+
 	overflow: hidden;
 	margin-right: 16rpx;
 }
 
 .avatar {
-	width: 64rpx;
-	height: 64rpx;
+	width: 68rpx;
+	height: 68rpx;
 	border-radius: 50%;
 	flex-shrink: 0;
 	margin-right: 16rpx;
@@ -161,9 +146,9 @@ export default {
 }
 
 .nickname {
-	font-size: 28rpx;
-	color: #333;
 	font-weight: 500;
+	font-size: 28rpx;
+	color: #1D2129;
 	overflow: hidden;
 	text-overflow: ellipsis;
 	white-space: nowrap;
@@ -176,26 +161,31 @@ export default {
 }
 
 .star-row {
+	margin-top: 12rpx;
+	margin-left: -8rpx;
 	display: flex;
 	align-items: center;
-	margin-bottom: 16rpx;
 }
 
 .score-text {
-	font-size: 26rpx;
-	color: #ff4d4f;
-	margin-left: 12rpx;
+	font-weight: 600;
+	font-size: 24rpx;
+	color: #F21144;
+	line-height: 24rpx;
 }
 
 .content-wrap {
 	margin-bottom: 20rpx;
 	margin-left: 80rpx;
+
 }
 
 .review-content {
+	margin-top: 20rpx;
 	display: block;
+	font-weight: 400;
 	font-size: 28rpx;
-	color: #666;
+	color: #1D2129;
 	line-height: 1.6;
 	word-break: break-all;
 
@@ -218,11 +208,17 @@ export default {
 }
 
 .toggle-text {
-	font-size: 26rpx;
-	color: #00c08b;
+	display: flex;
+	align-items: center;
+	font-weight: 400;
+	font-size: 28rpx;
+	color: #19D29B;
+	line-height: 32rpx;
 	margin-right: 4rpx;
+
 }
 
+
 .service-tag {
 	display: flex;
 	align-items: center;
@@ -231,10 +227,18 @@ export default {
 }
 
 .tag-hash {
+	height: 28rpx;
+	width: 28rpx;
+	background: linear-gradient(263deg, #45FFD7 0%, #84FF94 100%);
 	font-size: 26rpx;
-	color: #00c08b;
+	font-weight: bold;
+	color: #1D2129;
 	margin-right: 4rpx;
 	flex-shrink: 0;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	margin-right: 8rpx;
 }
 
 .tag-text {

+ 2 - 28
src/workbench/rating/mock.js

@@ -97,35 +97,9 @@ export function formatScore(score) {
 }
 
 export function normalizeRatingItem(raw, index) {
+	//raw.text='fjkdspajfpodjhdjksjf健康的死来哦安抚飞机第四哦是打飞机范德萨发的撒回复第撒谎覅哦爱佛教的死哦阿富汗都随阿飞hi哦的撒就哦范德萨覅哦哦大家萨芬绝对是阿凡达开始啦积分卡十分接近迪斯拉夫降低哦按实际分开了就是打飞机i哦的撒覅大厦覅偶是大家覅哦大厦覅哦大厦i欧派发动机撒附近的死哦按附件'
 	const content = (raw.cContent || raw.content || raw.cText || raw.text || '').trim()
-	const score = Number(raw.nStar ?? raw.score ?? 0)
-	const createTime =
-		raw.createTime ||
-		raw.dtCreateTime ||
-		raw.dTime ||
-		raw.cTime ||
-		raw.dtTime ||
-		raw.commentTime ||
-		raw.completionTime ||
-		''
-	return {
-		id: raw.id || raw.cId || `api-${index}`,
-		serviceName:
-			raw.cServiceName ||
-			raw.serviceName ||
-			raw.cOrderTitle ||
-			raw.cProjectName ||
-			'服务项目',
-		score: Number.isFinite(score) ? score : 0,
-		content,
-		displayContent: content || EMPTY_REVIEW_TEXT,
-		hasContent: !!content,
-		avatar: raw.cAvatar || raw.avatar || raw.cHeadImg || '',
-		nickName: raw.cNickName || raw.cName || raw.userName || '用户',
-		createTime,
-		reviewTime: formatReviewTime(createTime),
-		needExpand: content.length > CONTENT_COLLAPSE_LEN,
-	}
+	return content.length > CONTENT_COLLAPSE_LEN
 }
 
 export function sortByTimeDesc(list) {

+ 314 - 260
src/workbench/skill/add.vue

@@ -11,8 +11,8 @@
 				}" itemStyle="padding: 0 28rpx; height: 88rpx; font-size: 28rpx;" @change="onSubTabChange"></u-tabs>
 		</view>
 		<!-- 可选服务列表 -->
-		<view class="service-list" v-if="filteredList.length">
-			<view class="service-item" v-for="item in filteredList" :key="item.id" @click="toggleSelect(item.id)">
+		<view class="service-list" v-if="serviceList.length">
+			<view class="service-item" v-for="item in serviceList" :key="item.id" @click="toggleSelect(item.id)">
 				<view class="cover">
 					<image v-if="item.cover" :src="item.cover" mode="aspectFill" />
 				</view>
@@ -36,11 +36,15 @@
 		<!-- 申请开通弹窗 -->
 		<view class="modal-mask" v-if="showApplyModal" @click="showApplyModal = false">
 			<view class="modal-box" @click.stop>
-				<view class="modal-title">申请开通</view>
-				<view class="apply-tip">已申请开通{{ selectedIds.length }}项服务</view>
-				<textarea class="apply-reason" v-model="applyReason" placeholder="请输入开通原因" maxlength="200" />
+				<view class="box">
+					<view class="modal-title">申请开通</view>
+					<view class="apply-tip">已申请开通{{ selectedIds.length }}项服务</view>
+					<textarea class="apply-reason" v-model="applyReason" placeholder="请输入开通原因" maxlength="200"
+						placeholder-style="font-weight: 400;font-size: 26rpx;color: #C9CDD4;" />
+				</view>
+
 				<view class="apply-btns">
-					<view class="btn ghost flex1" @click="showApplyModal = false">取消</view>
+					<view class="btn ghost flex1" @click="closeApplyModal">取消</view>
 					<view class="btn primary flex1" @click="submitApply">提交申请</view>
 				</view>
 			</view>
@@ -48,292 +52,342 @@
 	</view>
 </template>
 <script>
-	import {
-		MAIN_TYPES,
-		PLAYMATE_TABS,
-		MOCK_AVAILABLE_SKILLS,
-		formatAvailablePrice,
-	} from './mock.js'
-	export default {
-		data() {
-			return {
-				mainType: MAIN_TYPES.MASSAGE,
-				playmateTabs: PLAYMATE_TABS,
-				serviceList: [...MOCK_AVAILABLE_SKILLS],
-				activeSubTab: PLAYMATE_TABS[0].id,
-				selectedIds: [],
-				showApplyModal: false,
-				applyReason: '',
+import {
+	MAIN_TYPES,
+	PLAYMATE_TABS,
+	MOCK_AVAILABLE_SKILLS,
+	formatAvailablePrice,
+} from './mock.js'
+import { getNotApplyList,applyForService } from '@/api/workbench'
+export default {
+	data() {
+		return {
+			mainType: MAIN_TYPES.MASSAGE,
+			playmateTabs: PLAYMATE_TABS,
+			serviceList: [...MOCK_AVAILABLE_SKILLS],
+			activeSubTab: PLAYMATE_TABS[0].id,
+			selectedIds: [],
+			showApplyModal: false,
+			applyReason: '',
+		}
+	},
+	computed: {
+		isPlaymate() {
+			return this.mainType === MAIN_TYPES.PLAYMATE
+		},
+		isMassage() {
+			return this.mainType === MAIN_TYPES.MASSAGE
+		},
+		playmateTabList() {
+			return this.playmateTabs.map(item => ({
+				name: item.name
+			}))
+		},
+		activeSubTabIndex() {
+			return this.playmateTabs.findIndex(item => item.id === this.activeSubTab)
+		},
+		filteredList() {
+			if (this.isMassage) {
+				return this.serviceList.filter(item => item.mainType === MAIN_TYPES.MASSAGE)
 			}
+			return this.serviceList.filter(
+				item => item.mainType === MAIN_TYPES.PLAYMATE && item.categoryId === this.activeSubTab
+			)
 		},
-		computed: {
-			isPlaymate() {
-				return this.mainType === MAIN_TYPES.PLAYMATE
-			},
-			isMassage() {
-				return this.mainType === MAIN_TYPES.MASSAGE
-			},
-			playmateTabList() {
-				return this.playmateTabs.map(item => ({
-					name: item.name
-				}))
-			},
-			activeSubTabIndex() {
-				return this.playmateTabs.findIndex(item => item.id === this.activeSubTab)
-			},
-			filteredList() {
-				if (this.isMassage) {
-					return this.serviceList.filter(item => item.mainType === MAIN_TYPES.MASSAGE)
+	},
+	onLoad(query) {
+		this.getNotApplyListFun()
+		const type = query.type || query.mainType || MAIN_TYPES.MASSAGE
+		this.mainType = type === MAIN_TYPES.PLAYMATE ? MAIN_TYPES.PLAYMATE : MAIN_TYPES.MASSAGE
+		if (query.tab && this.isPlaymate) {
+			const matched = this.playmateTabs.find(item => item.id === query.tab)
+			if (matched) this.activeSubTab = matched.id
+		}
+	},
+	methods: {
+		getNotApplyListFun() {
+			getNotApplyList({
+				merchantId: uni.getStorageSync('merchantId'),
+				serviceTag: uni.getStorageSync('serviceTag'),
+			}).then(res => {
+				if (res.data.code == 200) {
+					this.serviceList = res.data.data || []
 				}
-				return this.serviceList.filter(
-					item => item.mainType === MAIN_TYPES.PLAYMATE && item.categoryId === this.activeSubTab
-				)
-			},
+			})
 		},
-		onLoad(query) {
-			const type = query.type || query.mainType || MAIN_TYPES.MASSAGE
-			this.mainType = type === MAIN_TYPES.PLAYMATE ? MAIN_TYPES.PLAYMATE : MAIN_TYPES.MASSAGE
-			if (query.tab && this.isPlaymate) {
-				const matched = this.playmateTabs.find(item => item.id === query.tab)
-				if (matched) this.activeSubTab = matched.id
+		formatAvailablePrice,
+		onSubTabChange(e) {
+			const index = typeof e === 'object' ? e.index : e
+			this.activeSubTab = this.playmateTabs[index]?.id || this.playmateTabs[0].id
+		},
+		toggleSelect(id) {
+			const idx = this.selectedIds.indexOf(id)
+			if (idx > -1) {
+				this.selectedIds.splice(idx, 1)
+			} else {
+				this.selectedIds.push(id)
 			}
 		},
-		methods: {
-			formatAvailablePrice,
-			onSubTabChange(e) {
-				const index = typeof e === 'object' ? e.index : e
-				this.activeSubTab = this.playmateTabs[index]?.id || this.playmateTabs[0].id
-			},
-			toggleSelect(id) {
-				const idx = this.selectedIds.indexOf(id)
-				if (idx > -1) {
-					this.selectedIds.splice(idx, 1)
-				} else {
-					this.selectedIds.push(id)
-				}
-			},
-			onApply() {
-				if (this.selectedIds.length === 0) {
+		onApply() {
+			if (this.selectedIds.length === 0) {
+				uni.showToast({
+					title: '请至少选择1条数据',
+					icon: 'none'
+				})
+				return
+			}
+			this.applyReason = ''
+			this.showApplyModal = true
+		},
+		closeApplyModal() {
+			this.showApplyModal = false
+			this.selectedIds = []
+		},
+		submitApply() {
+			if (!this.applyReason.trim()) {
+				uni.showToast({
+					title: '请输入开通原因',
+					icon: 'none'
+				})
+				return
+			}
+			let params = {
+				merchantId: uni.getStorageSync('merchantId'),
+				merchantPhone: uni.getStorageSync('phone'),
+				applyReason: this.applyReason,
+				projectIdList: this.selectedIds,
+			}
+			applyForService(params).then(res => {
+				if (res.data.code == 200) {
+					this.showApplyModal = false
+					this.selectedIds = []
 					uni.showToast({
-						title: '请至少选择1条数据',
+						title: res.data.msg || '申请成功',
 						icon: 'none'
 					})
-					return
-				}
-				this.applyReason = ''
-				this.showApplyModal = true
-			},
-			submitApply() {
-				if (!this.applyReason.trim()) {
+					setTimeout(() => uni.navigateBack(), 800)
+				}else{
 					uni.showToast({
-						title: '请输入开通原因',
+						title: res.data.msg || '申请失败',
 						icon: 'none'
 					})
-					return
 				}
-				this.showApplyModal = false
-				this.selectedIds = []
-				uni.showToast({
-					title: '已提交,待审核',
-					icon: 'none'
-				})
-				setTimeout(() => uni.navigateBack(), 1200)
-			},
+			})
 		},
-	}
+	},
+}
 </script>
 <style lang="scss" scoped>
-	.add-page {
-		min-height: 100vh;
-		background: #f5f5f5;
-		padding-bottom: calc(env(safe-area-inset-bottom) + 140rpx);
-		box-sizing: border-box;
-	}
-	.sub-tabs-wrap {
-		background: #fff;
-		border-bottom: 1rpx solid #f0f0f0;
-	}
-	.service-list {
-		padding: 24rpx;
-	}
-	.service-item {
-		display: flex;
-		align-items: center;
-		background: #fff;
-		border-radius: 16rpx;
-		padding: 24rpx;
-		margin-bottom: 20rpx;
-	}
-	.cover {
-		width: 120rpx;
-		height: 120rpx;
-		background: #eee;
-		border-radius: 12rpx;
-		flex-shrink: 0;
-		overflow: hidden;
-		image {
-			width: 100%;
-			height: 100%;
-		}
-	}
-	.info {
-		flex: 1;
-		margin: 0 20rpx;
-		overflow: hidden;
-		min-width: 0;
-	}
-	.title {
-		display: block;
-		font-size: 28rpx;
-		color: #333;
-		font-weight: 500;
-		line-height: 1.5;
-		overflow: hidden;
-		text-overflow: ellipsis;
-		display: -webkit-box;
-		-webkit-line-clamp: 2;
-		-webkit-box-orient: vertical;
-	}
-	.price {
-		display: block;
-		margin-top: 12rpx;
-		font-size: 28rpx;
-		color: #ff6b4a;
-		font-weight: 500;
-	}
+.add-page {
+	min-height: 100vh;
+	background: #f5f5f5;
+	padding-bottom: calc(env(safe-area-inset-bottom) + 140rpx);
+	box-sizing: border-box;
+}
 
-	.select-icon {
-		flex-shrink: 0;
-		width: 44rpx;
-		height: 44rpx;
-		display: flex;
-		align-items: center;
-		justify-content: center;
-	}
+.sub-tabs-wrap {
+	background: #fff;
+	border-bottom: 1rpx solid #f0f0f0;
+}
 
-	.checked-icon {
-		width: 44rpx;
-		height: 44rpx;
-	}
+.service-list {
+	padding: 24rpx;
+}
 
-	.unchecked-icon {
-		width: 40rpx;
-		height: 40rpx;
-		border: 2rpx solid #d9d9d9;
-		border-radius: 50%;
-		box-sizing: border-box;
-	}
+.service-item {
+	display: flex;
+	align-items: center;
+	background: #fff;
+	border-radius: 16rpx;
+	padding: 24rpx;
+	margin-bottom: 20rpx;
+}
 
-	.empty {
-		text-align: center;
-		padding: 120rpx 0;
-		font-size: 28rpx;
-		color: #999;
-	}
+.cover {
+	width: 120rpx;
+	height: 120rpx;
+	background: #eee;
+	border-radius: 12rpx;
+	flex-shrink: 0;
+	overflow: hidden;
 
-	.footer-bar {
-		position: fixed;
-		left: 0;
-		right: 0;
-		bottom: 0;
-		display: flex;
-		align-items: center;
-		justify-content: space-between;
-		padding: 20rpx 32rpx;
-		padding-bottom: calc(env(safe-area-inset-bottom) + 20rpx);
-		background: #fff;
-		border-top: 1rpx solid #eee;
-		z-index: 10;
+	image {
+		width: 100%;
+		height: 100%;
 	}
+}
 
-	.selected-count {
-		font-size: 28rpx;
-		color: #666;
-	}
+.info {
+	flex: 1;
+	margin: 0 20rpx;
+	overflow: hidden;
+	min-width: 0;
+}
 
-	.apply-btn {
-		min-width: 240rpx;
-		padding: 22rpx 48rpx;
-		background: #333;
-		color: #fff;
-		font-size: 28rpx;
-		border-radius: 44rpx;
-		text-align: center;
-		line-height: 1;
-	}
+.title {
+	display: block;
+	font-size: 28rpx;
+	color: #333;
+	font-weight: 500;
+	line-height: 1.5;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	display: -webkit-box;
+	-webkit-line-clamp: 2;
+	-webkit-box-orient: vertical;
+}
 
-	.modal-mask {
-		position: fixed;
-		left: 0;
-		top: 0;
-		right: 0;
-		bottom: 0;
-		background: rgba(0, 0, 0, 0.5);
-		z-index: 999;
-		display: flex;
-		align-items: center;
-		justify-content: center;
-		padding: 48rpx;
-		box-sizing: border-box;
-	}
+.price {
+	display: block;
+	margin-top: 12rpx;
+	font-size: 28rpx;
+	color: #ff6b4a;
+	font-weight: 500;
+}
 
-	.modal-box {
-		width: 100%;
-		max-width: 600rpx;
-		background: #fff;
-		border-radius: 16rpx;
-		padding-bottom: 32rpx;
-	}
+.select-icon {
+	flex-shrink: 0;
+	width: 44rpx;
+	height: 44rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
 
-	.modal-title {
-		font-size: 32rpx;
-		font-weight: 600;
-		text-align: center;
-		padding: 32rpx 32rpx 16rpx;
-	}
+.checked-icon {
+	width: 44rpx;
+	height: 44rpx;
+}
 
-	.apply-tip {
-		text-align: center;
-		font-size: 26rpx;
-		color: #666;
-		padding-bottom: 16rpx;
-	}
+.unchecked-icon {
+	width: 40rpx;
+	height: 40rpx;
+	border: 2rpx solid #d9d9d9;
+	border-radius: 50%;
+	box-sizing: border-box;
+}
 
-	.apply-reason {
-		display: block;
-		width: calc(100% - 64rpx);
-		margin: 0 32rpx 24rpx;
-		min-height: 200rpx;
-		padding: 20rpx;
-		border: 1rpx solid #ddd;
-		border-radius: 8rpx;
-		font-size: 26rpx;
-		box-sizing: border-box;
-	}
+.empty {
+	text-align: center;
+	padding: 120rpx 0;
+	font-size: 28rpx;
+	color: #999;
+}
 
-	.apply-btns {
-		display: flex;
-		gap: 16rpx;
-		padding: 0 32rpx;
-	}
+.footer-bar {
+	position: fixed;
+	left: 0;
+	right: 0;
+	bottom: 0;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	padding: 20rpx 32rpx;
+	padding-bottom: calc(env(safe-area-inset-bottom) + 20rpx);
+	background: #fff;
+	border-top: 1rpx solid #eee;
+	z-index: 10;
+}
 
-	.btn {
-		padding: 20rpx;
-		font-size: 28rpx;
-		border-radius: 8rpx;
-		text-align: center;
-		&.ghost {
-			border: 1rpx solid #ccc;
-			color: #666;
-		}
+.selected-count {
+	font-size: 28rpx;
+	color: #666;
+}
 
-		&.primary {
-			background: #333;
-			color: #fff;
-		}
+.apply-btn {
+	min-width: 240rpx;
+	padding: 22rpx 48rpx;
+	background: #333;
+	color: #fff;
+	font-size: 28rpx;
+	border-radius: 44rpx;
+	text-align: center;
+	line-height: 1;
+}
 
-		&.flex1 {
-			flex: 1;
-		}
+.modal-mask {
+	position: fixed;
+	left: 0;
+	top: 0;
+	right: 0;
+	bottom: 0;
+	background: rgba(0, 0, 0, 0.5);
+	z-index: 999;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	padding: 48rpx;
+	box-sizing: border-box;
+}
+
+.modal-box {
+	width: 100%;
+	max-width: 600rpx;
+	background: #fff;
+	border-radius: 16rpx;
+
+}
+
+.box {
+	padding: 32rpx 48rpx;
+}
+
+.modal-title {
+	font-size: 32rpx;
+	font-weight: 600;
+	text-align: center;
+}
+
+.apply-tip {
+	margin-top: 32rpx;
+	font-weight: 400;
+	font-size: 30rpx;
+	color: #1D2129;
+	text-align: left;
+}
+
+.apply-reason {
+	width: 100%;
+	height: 124rpx;
+	padding: 8rpx;
+	display: block;
+	background: #F7F8FA;
+	border-radius: 6rpx 6rpx 6rpx 6rpx;
+	box-sizing: border-box;
+	margin-top: 8rpx;
+
+	font-weight: 400;
+	font-size: 26rpx;
+	color: #4E5969;
+}
+
+.apply-btns {
+	display: flex;
+	border-top: 1rpx solid #E7E7E7;
+}
+
+.btn {
+	padding: 20rpx;
+	height: 90rpx;
+	font-size: 28rpx;
+	border-radius: 8rpx;
+	text-align: center;
+	font-weight: 400;
+	font-size: 30rpx;
+	color: #86909C;
+	text-align: center;
+
+
+
+	&.primary {
+		border-left: 1rpx solid #E7E7E7;
+		font-weight: 400;
+		font-size: 30rpx;
+		color: #1D2129;
+	}
+
+	&.flex1 {
+		flex: 1;
 	}
+}
 </style>

+ 190 - 182
src/workbench/skill/edit.vue

@@ -15,12 +15,12 @@
 			<view class="form-row">
 				<text class="label">服务分类</text>
 				<text class="value">{{ detail.categoryName }}</text>
-				<image class="chevron" src="@/static/workbench/right.png" mode=""></image>
+				<!-- <image class="chevron" src="@/static/workbench/right.png" mode=""></image> -->
 			</view>
 			<view class="form-row">
 				<text class="label">价格</text>
 				<text class="value">{{ platformPriceText }}</text>
-				<image class="chevron" src="@/static/workbench/right.png" mode=""></image>
+				<!-- <image class="chevron" src="@/static/workbench/right.png" mode=""></image> -->
 			</view>
 			<view class="form-row">
 				<text class="label">价格区间</text>
@@ -43,214 +43,222 @@
 	</view>
 </template>
 <script>
-	export default {
-		data() {
-			return {
-				detail: {
-					id: '',
-					title: '',
-					cover: '',
-					categoryName: '',
-					billingType: '',
-					platformPrice: '',
-					priceRangeMin: '',
-					priceRangeMax: '',
-				},
-				myPrice: '',
-			}
-		},
-		computed: {
-			platformPriceText() {
-				const price = Number(this.detail.platformPrice)
-				if (isNaN(price)) return '-'
-				return `¥ ${price.toFixed(2)}`
-			},
-			priceRangeText() {
-				const {
-					priceRangeMin,
-					priceRangeMax
-				} = this.detail
-				if (priceRangeMin != null && priceRangeMax != null) {
-					const max = Number(priceRangeMax).toFixed(2)
-					const min = Number(priceRangeMin).toFixed(2)
-					return `¥ ${max} 至 ${min}`
-				}
-				return '-'
+import { updateMaProject } from '@/api/workbench.js'
+export default {
+	data() {
+		return {
+			detail: {
+				id: '',
+				title: '',
+				cover: '',
+				categoryName: '',
+				billingType: '',
+				platformPrice: '',
+				priceRangeMin: '',
+				priceRangeMax: '',
 			},
+			myPrice: '',
+		}
+	},
+	computed: {
+		platformPriceText() {
+			const price = Number(this.detail.platformPrice)
+			if (isNaN(price)) return '-'
+			return `¥ ${price.toFixed(2)}`
 		},
-		onLoad(query) {
-			this.detail = {
-				id: query.id || '',
-				title: query.title || '中式推拿-培元疏通',
-				cover: query.cover || '',
-				categoryName: query.categoryName || '上门按摩',
-				billingType: query.billingType || '按分钟计费',
-				platformPrice: query.platformPrice || '368.00',
-				priceRangeMin: Number(query.priceRangeMin) || 288,
-				priceRangeMax: Number(query.priceRangeMax) || 368,
+		priceRangeText() {
+			const {
+				priceRangeMin,
+				priceRangeMax
+			} = this.detail
+			if (priceRangeMin != null && priceRangeMax != null) {
+				const max = Number(priceRangeMax).toFixed(2)
+				const min = Number(priceRangeMin).toFixed(2)
+				return `¥ ${max} 至 ${min}`
 			}
-			this.myPrice = query.myPrice || ''
+			return '-'
 		},
-		methods: {
-			validatePrice() {
-				const val = Number(this.myPrice)
-				if (isNaN(val)) return false
-				return val >= this.detail.priceRangeMin && val <= this.detail.priceRangeMax
-			},
-			onSubmit() {
-				if (!this.myPrice) {
-					uni.showToast({
-						title: '请输入售价',
-						icon: 'none'
-					})
-					return
-				}
-				if (!this.validatePrice()) {
-					uni.showToast({
-						title: `价格需在${this.detail.priceRangeMin}-${this.detail.priceRangeMax}之间`,
-						icon: 'none',
-					})
-					return
-				}
+	},
+	onLoad(query) {
+		this.detail = {
+			id: Number(query.id) || '',
+			title: query.title || '中式推拿-培元疏通',
+			cover: decodeURIComponent(query.cover) || '',
+			categoryName: query.categoryName || '上门按摩',
+			billingType: query.billingType || '按分钟计费',
+			platformPrice: query.platformPrice || '368.00',
+			priceRangeMin: Number(query.priceRangeMin) || 288,
+			priceRangeMax: Number(query.priceRangeMax) || 368,
+		}
+		this.myPrice = query.myPrice || ''
+	},
+	methods: {
+		validatePrice() {
+			const val = Number(this.myPrice)
+			if (isNaN(val)) return false
+			return val >= this.detail.priceRangeMin && val <= this.detail.priceRangeMax
+		},
+		onSubmit() {
+			if (!this.myPrice) {
 				uni.showToast({
-					title: '修改完成',
+					title: '请输入售价',
 					icon: 'none'
 				})
-				setTimeout(() => uni.navigateBack(), 1000)
-			},
+				return
+			}
+			if (!this.validatePrice()) {
+				uni.showToast({
+					title: `价格需在${this.detail.priceRangeMin}-${this.detail.priceRangeMax}之间`,
+					icon: 'none',
+				})
+				return
+			}
+			updateMaProject({
+				projectId: this.detail.id || '',
+				projectCurrentPrice: this.myPrice,
+			}).then(res => {
+				if (res.data.code == 200) {
+					uni.showToast({ title: res.data.msg || '修改完成', icon: 'none' })
+					setTimeout(() => uni.navigateBack(), 1000)
+				} else {
+					uni.showToast({ title: res.data.msg || '修改失败', icon: 'none' })
+				}
+			})
+			
 		},
-	}
+	},
+}
 </script>
 <style lang="scss" scoped>
-	.edit-page {
-		min-height: 100vh;
-		background: #f5f5f5;
-		padding-bottom: calc(env(safe-area-inset-bottom) + 140rpx);
-		box-sizing: border-box;
-	}
+.edit-page {
+	min-height: 100vh;
+	background: #f5f5f5;
+	padding-bottom: calc(env(safe-area-inset-bottom) + 140rpx);
+	box-sizing: border-box;
+}
 
-	.summary {
-		display: flex;
-		align-items: center;
-		background: #fff;
-		padding: 32rpx;
-		margin-bottom: 16rpx;
-	}
+.summary {
+	display: flex;
+	align-items: center;
+	background: #fff;
+	padding: 32rpx;
+	margin-bottom: 16rpx;
+}
 
-	.cover {
-		width: 120rpx;
-		height: 120rpx;
-		background: #eee;
-		border-radius: 12rpx;
-		flex-shrink: 0;
-		overflow: hidden;
+.cover {
+	width: 120rpx;
+	height: 120rpx;
+	background: #eee;
+	border-radius: 12rpx;
+	flex-shrink: 0;
+	overflow: hidden;
 
-		image {
-			width: 100%;
-			height: 100%;
-		}
+	image {
+		width: 100%;
+		height: 100%;
 	}
+}
 
-	.summary-info {
-		flex: 1;
-		margin-left: 24rpx;
-		min-width: 0;
-	}
+.summary-info {
+	flex: 1;
+	margin-left: 24rpx;
+	min-width: 0;
+}
 
-	.title {
-		display: block;
-		font-size: 30rpx;
-		color: #333;
-		font-weight: 500;
-		line-height: 1.5;
-		margin-bottom: 8rpx;
-	}
+.title {
+	display: block;
+	font-size: 30rpx;
+	color: #333;
+	font-weight: 500;
+	line-height: 1.5;
+	margin-bottom: 8rpx;
+}
 
-	.billing {
-		font-size: 24rpx;
-		color: #999;
-	}
+.billing {
+	font-size: 24rpx;
+	color: #999;
+}
 
-	.form-section {
-		background: #fff;
-	}
+.form-section {
+	background: #fff;
+}
 
-	.form-row {
-		display: flex;
-		align-items: center;
-		padding: 28rpx 32rpx;
-		border-bottom: 1rpx solid #f5f5f5;
+.form-row {
+	display: flex;
+	align-items: center;
+	padding: 28rpx 32rpx;
+	border-bottom: 1rpx solid #f5f5f5;
 
-		&.no-border {
-			border-bottom: none;
-			padding-bottom: 16rpx;
-		}
+	&.no-border {
+		border-bottom: none;
+		padding-bottom: 16rpx;
 	}
+}
 
-	.label {
-		width: 160rpx;
-		flex-shrink: 0;
-		font-size: 30rpx;
-		color: #333;
-	}
+.label {
+	width: 160rpx;
+	flex-shrink: 0;
+	font-size: 30rpx;
+	color: #333;
+}
 
-	.value {
-		flex: 1;
-		text-align: right;
-		font-size: 28rpx;
-		color: #333;
-	}
+.value {
+	flex: 1;
+	text-align: right;
+	font-size: 28rpx;
+	color: #333;
+}
 
-	.chevron {
-		width: 25rpx;
-		height: 25rpx;
-	}
+.chevron {
+	width: 25rpx;
+	height: 25rpx;
+}
 
-	.price-block {
-		border-top: 1rpx solid #f5f5f5;
-	}
+.price-block {
+	border-top: 1rpx solid #f5f5f5;
+}
 
-	.price-input {
-		flex: 1;
-		text-align: right;
-		font-size: 28rpx;
-		color: #333;
-		height: 44rpx;
-		line-height: 44rpx;
-	}
+.price-input {
+	flex: 1;
+	text-align: right;
+	font-size: 28rpx;
+	color: #333;
+	height: 44rpx;
+	line-height: 44rpx;
+}
 
-	.placeholder {
-		color: #ccc;
-		font-size: 28rpx;
-	}
+.placeholder {
+	color: #ccc;
+	font-size: 28rpx;
+}
 
-	.price-tip {
-		display: block;
-		padding: 0 32rpx 28rpx;
-		font-size: 24rpx;
-		color: #999;
-		line-height: 1.6;
-	}
+.price-tip {
+	display: block;
+	padding: 0 32rpx 28rpx;
+	font-size: 24rpx;
+	color: #999;
+	line-height: 1.6;
+}
 
-	.footer-bar {
-		position: fixed;
-		left: 0;
-		right: 0;
-		bottom: 0;
-		padding: 20rpx 32rpx;
-		padding-bottom: calc(env(safe-area-inset-bottom) + 20rpx);
-	}
+.footer-bar {
+	position: fixed;
+	left: 0;
+	right: 0;
+	bottom: 0;
+	padding: 20rpx 32rpx;
+	padding-bottom: calc(env(safe-area-inset-bottom) + 20rpx);
+}
 
-	.submit-btn {
-		margin: 0 auto;
-		width: 654rpx;
-		height: 88rpx;
-		line-height: 88rpx;
-		text-align: center;
-		font-weight: 500;
-		font-size: 32rpx;
-		color: #FFFFFF;
-		background: #333335;
-		border-radius: 60rpx 60rpx 60rpx 60rpx;
-	}
+.submit-btn {
+	margin: 0 auto;
+	width: 654rpx;
+	height: 88rpx;
+	line-height: 88rpx;
+	text-align: center;
+	font-weight: 500;
+	font-size: 32rpx;
+	color: #FFFFFF;
+	background: #333335;
+	border-radius: 60rpx 60rpx 60rpx 60rpx;
+}
 </style>

+ 349 - 180
src/workbench/skill/index.vue

@@ -2,32 +2,18 @@
 	<view class="skill-page">
 		<!-- 陪玩:分类 Tab -->
 		<scroll-view v-if="isPlaymate" scroll-x class="category-tabs" :show-scrollbar="false">
-			<view
-				v-for="tab in playmateTabs"
-				:key="tab.id"
-				class="category-tab"
-				:class="{ active: activeCategory === tab.id }"
-				@click="activeCategory = tab.id"
-			>
+			<view v-for="tab in playmateTabs" :key="tab.id" class="category-tab"
+				:class="{ active: activeCategory === tab.id }" @click="activeCategory = tab.id">
 				<text class="category-tab__text">{{ tab.name }}</text>
-				<image
-					v-if="activeCategory === tab.id"
-					class="category-tab__indicator"
-					src="/static/workbench/tabs.png"
-					mode="widthFix"
-				/>
+				<image v-if="activeCategory === tab.id" class="category-tab__indicator" src="/static/workbench/tabs.png"
+					mode="widthFix" />
 			</view>
 		</scroll-view>
 
 		<!-- 状态筛选 -->
 		<view class="status-tabs">
-			<view
-				v-for="tab in statusTabs"
-				:key="tab.key"
-				class="status-tab"
-				:class="{ active: activeStatus === tab.key }"
-				@click="onStatusChange(tab.key)"
-			>{{ tab.label }}</view>
+			<view v-for="tab in statusTabs" :key="tab.key" class="status-tab"
+				:class="{ active: activeStatus === tab.key }" @click="onStatusChange(tab.key)">{{ tab.label }}</view>
 		</view>
 
 		<!-- 技能列表 -->
@@ -41,25 +27,30 @@
 						<view class="info">
 							<view class="title-row">
 								<text class="title">{{ item.projectName }}</text>
-								<text class="sold" v-if="activeStatus === '1' && getSoldCount(item)">已售{{ getSoldCount(item) }}</text>
+								<text class="sold" v-if="activeStatus === '1' && getSoldCount(item)">已售{{
+									getSoldCount(item) }}</text>
 							</view>
-							<text class="price">{{ formatSkillPrice(item) }}</text>
-							<view
-								class="status-bar"
-								:class="{ 'status-bar--opened': activeStatus === '1' }"
-								v-if="statusBarText(item)"
-								@click="onStatusBarClick(item)"
-							>
-								<image
-									v-if="activeStatus === '1'"
-									class="status-icon"
-									src="/static/workbench/skillTime.png"
-									mode="aspectFit"
-								/>
+							<text class="price">
+								<text class="priceUnit">¥</text>
+								<text>{{ formatSkillPrice(item) }}</text>
+								<!-- 计量单位(0:分钟 1:小时 2:次) -->
+								<text class="priceUnit">/{{ item.unitType === 0 ? '分钟' : item.unitType === 1 ? '小时' :
+									'次' }}</text>
+							</text>
+							<view class="status-bar"
+								:class="{ 'status-bar--opened': activeStatus === '1', 'status-bar--rejected': activeStatus === '2' }"
+								v-if="statusBarText(item)" @click="onStatusBarClick(item)">
+								<image v-if="activeStatus === '1' || activeStatus === '0'" class="status-icon"
+									:src="activeStatus === '1' ? '/static/workbench/skillTime.png' : '/static/workbench/clockIcon.png'"
+									mode="aspectFit" />
 								<text class="status-text">{{ statusBarText(item) }}</text>
-								<text class="chevron" v-if="activeStatus === '2'">&gt;</text>
+								<view class="chevron" v-if="activeStatus === '2'">
+									<image src="/static/workbench/redArrow.png" mode="aspectFit"
+										style="width: 16rpx; height: 16rpx;" />
+								</view>
 							</view>
 						</view>
+
 					</view>
 				</view>
 
@@ -95,20 +86,20 @@
 			</view>
 		</view>
 
+
 		<!-- 申请开通弹窗 -->
-		<view class="modal-mask" v-if="showApplyModal" @click="closeApplyModal">
-			<view class="modal-box apply-box" @click.stop>
-				<view class="modal-title">申请开通</view>
-				<view class="apply-tip">已申请开通{{ applyItems.length }}项服务</view>
-				<textarea
-					class="apply-reason"
-					v-model="applyReason"
-					placeholder="请输入开通原因"
-					maxlength="200"
-				/>
+		<view class="modal-mask1" v-if="showApplyModal" @click="showApplyModal = false">
+			<view class="modal-box" @click.stop>
+				<view class="box">
+					<view class="modal-title">申请开通</view>
+					<view class="apply-tip">已申请开通{{ applyItems.length }}项服务</view>
+					<textarea class="apply-reason" v-model="applyReason" placeholder="请输入开通原因" maxlength="200"
+						placeholder-style="font-weight: 400;font-size: 26rpx;color: #C9CDD4;" />
+				</view>
+
 				<view class="apply-btns">
-					<view class="btn ghost flex1" @click="closeApplyModal">取消</view>
-					<view class="btn primary flex1" @click="submitApply">提交申请</view>
+					<view class="btn flex1" @click="closeApplyModal">取消</view>
+					<view class="btn submit flex1" @click="submitApply">提交申请</view>
 				</view>
 			</view>
 		</view>
@@ -117,7 +108,7 @@
 
 <script>
 import { PLAYMATE_TABS } from './mock.js'
-import { getSkillList } from '@/api/workbench.js'
+import { getSkillList, updateMaProject, updateApply } from '@/api/workbench.js'
 
 export default {
 	data() {
@@ -141,6 +132,7 @@ export default {
 			showApplyModal: false,
 			applyItems: [],
 			applyReason: '',
+			agginApplyProjectId: '',
 		}
 	},
 	computed: {
@@ -179,12 +171,13 @@ export default {
 			this.loading = true
 			const params = {
 				auditStatus: this.activeStatus,
-				userId: this.cJsId,
-				typeId: this.serviceTag,
+				merchantId: this.cJsId,
+				//typeId: this.serviceTag,
 			}
 			getSkillList(params).then(res => {
 				if (res.data.code == 200) {
-					this.skillList = Array.isArray(res.data.result) ? res.data.result : []
+					this.skillList = Array.isArray(res.data.data) ? res.data.data : []
+
 				} else {
 					this.skillList = []
 				}
@@ -200,7 +193,7 @@ export default {
 			return categoryId === String(tab.id) || categoryName === tab.name
 		},
 		getCover(item) {
-			const image = item.projectMasterImage || item.cover || item.projectImage || ''
+			const image = item.cover || item.projectImage || ''
 			if (!image) return ''
 			return image.startsWith('http') ? image : this.public + image
 		},
@@ -214,13 +207,13 @@ export default {
 		},
 		formatSkillPrice(item) {
 			const unit = item.cUnit || item.unit || '次'
-			const min = item.projectMinPrice ?? item.minPrice ?? item.projectLowPrice
-			const max = item.projectMaxPrice ?? item.maxPrice ?? item.projectHighPrice
+			const min = item.projectLowestPrice
+			const max = item.projectMaxPrice
 			if (min != null && max != null) {
-				return `¥${this.formatMoney(min)}-${this.formatMoney(max)}/${unit}`
+				return `${this.formatMoney(min)}-${this.formatMoney(max)}`
 			}
-			const price = item.projectCurrentPrice ?? item.price ?? min ?? max ?? 0
-			return `¥${this.formatMoney(price)}/${unit}`
+			const price = item.projectCurrentPrice
+			return `${this.formatMoney(price)}`
 		},
 		formatApplyDate(timeStr) {
 			if (!timeStr) return ''
@@ -230,11 +223,11 @@ export default {
 			return `${d.getFullYear()}年${d.getMonth() + 1}月${d.getDate()}日申请开通服务`
 		},
 		getRejectReason(item) {
-			return item.rejectReason || item.auditRemark || item.remark || item.auditReason || ''
+			return item.reason || ''
 		},
 		statusBarText(item) {
 			if (this.activeStatus === '1') {
-				const time = item.createTime || item.applyTime || item.openTime || item.auditTime
+				const time = item.applyTime || ''
 				return time ? this.formatApplyDate(time) : ''
 			}
 			if (this.activeStatus === '0') return '申请开通服务审核中'
@@ -254,35 +247,69 @@ export default {
 			const type = this.isPlaymate ? 'playmate' : 'massage'
 			uni.navigateTo({ url: `/workbench/skill/add?type=${type}` })
 		},
+		//编辑服务
 		goEdit(item) {
+			console.log(item)
+			if (item.auditStatus != 1) {
+				uni.showToast({ title: '服务未开通,不支持该操作', icon: 'none' })
+				return
+			}
 			const categoryName = this.isPlaymate
 				? item.subTypeName || item.categoryName || item.subCategoryName || ''
 				: ''
 			const str = uni.$u.queryParams({
-				id: item.id || item.projectId || '',
+				id: item.projectId || '',
 				title: item.projectName || '',
-				cover: this.getCover(item),
+				cover: encodeURIComponent(this.getCover(item)),
 				categoryName,
-				billingType: item.billingType || item.chargeType || (item.nMinute ? '按分钟计费' : ''),
-				platformPrice: item.projectPlatformPrice ?? item.platformPrice ?? item.projectCurrentPrice,
-				priceRangeMin: item.projectMinPrice ?? item.minPrice ?? item.projectLowPrice,
-				priceRangeMax: item.projectMaxPrice ?? item.maxPrice ?? item.projectHighPrice,
-				myPrice: item.projectCurrentPrice ?? item.price,
+				billingType: item.unitType === 0 ? '按分钟计费' : item.unitType === 1 ? '按小时计费' : '按次计费',
+				platformPrice: item.projectCurrentPrice,
+				priceRangeMin: item.projectLowestPrice,
+				priceRangeMax: item.projectMaxPrice,
+				myPrice: item.projectOriginalPrice,
 			})
+			console.log(this.getCover(item))
 			uni.navigateTo({ url: `/workbench/skill/edit${str}` })
 		},
+
+		//上下架服务
 		onOffShelf(item) {
-			uni.showToast({ title: '申请下架待对接', icon: 'none' })
+			if (item.auditStatus != 1) {
+				uni.showToast({ title: '服务未开通,不支持该操作', icon: 'none' })
+				return
+			}
+			if (this.filteredList.length == 1) {
+				uni.showToast({ title: '不支持该操作,请至少保留1项服务', icon: 'none' })
+				return
+			}
+			this.updateMaProjectFun({
+				projectId: item.projectId || '',
+				isPass: true,
+			})
+		},
+
+		//更新服务状态
+		updateMaProjectFun(params) {
+			updateMaProject(params).then(res => {
+				if (res.data.code == 200) {
+					uni.showToast({ title: res.data.msg || '更新成功', icon: 'none' })
+					this.getSkillList()
+				} else {
+					uni.showToast({ title: res.data.msg || '更新失败', icon: 'none' })
+				}
+			})
 		},
+		//删除服务
 		onDelete(item) {
 			uni.showModal({
 				title: '提示',
 				content: '确定删除该服务?',
 				success: res => {
 					if (res.confirm) {
-						const itemId = item.id || item.projectId
-						this.skillList = this.skillList.filter(s => (s.id || s.projectId) !== itemId)
-						uni.showToast({ title: '已删除', icon: 'none' })
+						this.updateMaProjectFun({
+							projectId: item.projectId || '',
+							isDelete: true,
+						})
 					}
 				},
 			})
@@ -302,10 +329,27 @@ export default {
 				uni.showToast({ title: '请输入开通原因', icon: 'none' })
 				return
 			}
-			this.closeApplyModal()
-			this.activeStatus = '0'
-			this.getSkillList()
-			uni.showToast({ title: '已提交,待审核', icon: 'none' })
+			updateApply({
+				projectId: this.applyItems[0].projectId || '',
+				applyReason: this.applyReason,
+			}).then(res => {
+				if (res.data.code == 200) {
+					this.showApplyModal = false
+					this.closeApplyModal()
+					this.activeStatus = '0'
+					this.getSkillList()
+					uni.showToast({
+						title: res.data.msg || '申请成功',
+						icon: 'none'
+					})
+				} else {
+					uni.showToast({
+						title: res.data.msg || '申请失败',
+						icon: 'none'
+					})
+				}
+			})
+
 		},
 	},
 }
@@ -314,6 +358,7 @@ export default {
 <style lang="scss" scoped>
 .skill-page {
 	min-height: 100vh;
+	width: 100%;
 	background: #f5f5f5;
 	padding-bottom: 160rpx;
 }
@@ -353,49 +398,56 @@ export default {
 .status-tabs {
 	display: flex;
 	align-items: center;
-	justify-content: space-around;
-	padding: 28rpx 32rpx;
+	justify-content: space-between;
+	padding: 20rpx 56rpx 18rpx 56rpx;
 	background: #fff;
 	border-bottom: 1rpx solid #eee;
-	margin-bottom: 16rpx;
+	margin-bottom: 20rpx;
 }
 
 .status-tab {
-	flex: 1;
-	text-align: center;
-	font-size: 28rpx;
-	color: #999;
-	line-height: 1.4;
+
+	font-weight: 400;
+	font-size: 30rpx;
+	color: #4E5969;
 
 	&.active {
-		color: #333;
 		font-weight: 600;
+		font-size: 32rpx;
+		color: #1D2129;
 	}
 }
 
 .skill-list {
-	padding: 0 24rpx;
+	width: 100%;
+	padding: 0 32rpx;
 }
 
 .skill-card {
+	width: 100%;
 	background: #fff;
 	border: 1rpx solid #eee;
 	border-radius: 12rpx;
-	margin-bottom: 20rpx;
+	margin-bottom: 24rpx;
 	overflow: hidden;
 }
 
 .card-body {
-	padding: 24rpx;
+	width: 100%;
+	padding: 32rpx;
+	box-sizing: border-box;
 }
 
 .card-main {
+	width: 100%;
 	display: flex;
+	gap: 24rpx;
+	justify-content: space-between;
 }
 
 .cover {
-	width: 120rpx;
-	height: 120rpx;
+	width: 140rpx;
+	height: 140rpx;
 	background: #eee;
 	border-radius: 8rpx;
 	flex-shrink: 0;
@@ -409,83 +461,110 @@ export default {
 
 .info {
 	flex: 1;
-	margin-left: 20rpx;
+	display: flex;
+	flex-direction: column;
 	overflow: hidden;
+	height: 140rpx;
 }
 
 .title-row {
 	display: flex;
 	justify-content: space-between;
-	align-items: flex-start;
 }
 
 .title {
-	font-size: 28rpx;
-	color: #333;
 	font-weight: 500;
-	flex: 1;
-	line-height: 1.4;
+	font-size: 30rpx;
+	color: #1D2129;
 }
 
 .sold {
-	font-size: 22rpx;
-	color: #e8a849;
-	background: #fff7ed;
-	padding: 4rpx 12rpx;
-	border-radius: 4rpx;
-	flex-shrink: 0;
-	margin-left: 12rpx;
+	width: 100rpx;
+	height: 36rpx;
+	background: #FFF4E7;
+	border-radius: 4rpx 4rpx 4rpx 4rpx;
+	padding: 8rpx 12rpx;
+	font-weight: 400;
+	font-size: 20rpx;
+	color: #FF8D2F;
+
+
+
 }
 
 .price {
-	display: block;
-	font-size: 28rpx;
-	color: #e54d42;
-	margin-top: 12rpx;
+	font-weight: Bold;
+	font-size: 36rpx;
+	color: #FF4C12;
+	margin: auto 0;
+	//margin-top: 16rpx;
+}
+
+.priceUnit {
+	font-weight: Regular;
+	font-size: 20rpx;
+	color: #FF4C12;
 }
 
 .status-bar {
-	display: inline-flex;
+	//margin-top: 8rpx;
+	line-height: 36rpx;
+	background: linear-gradient(90deg, #FFF6E6 0%, rgba(255, 246, 230, 0) 100%);
+	border-radius: 4rpx 4rpx 4rpx 4rpx;
+	padding: 0 16rpx;
+	display: flex;
 	align-items: center;
-	max-width: 100%;
-	margin-top: 12rpx;
-	padding: 8rpx 16rpx;
-	background: #f5f5f5;
-	border-radius: 8rpx;
+	overflow: hidden;
+
+	font-weight: 400;
+	font-size: 20rpx;
+	color: #FC8C0C;
 
 	&--opened {
-		background: #e8f9f7;
+		background: linear-gradient(90deg, #EAFFF0 0%, rgba(234, 255, 240, 0) 100%);
+
+		.status-text {
+			color: #00B42A;
+		}
+	}
+
+	&--rejected {
+		background: #FFF5F5;
+
 
 		.status-text {
-			color: #20CAC2;
+			flex: 1;
+			color: #F53F3F;
+			white-space: nowrap;
+			/* 禁止换行 单行 */
+			overflow: hidden;
+			/* 超出隐藏 */
+			text-overflow: ellipsis;
+			/* 末尾... */
 		}
 	}
 }
 
 .status-icon {
-	width: 28rpx;
-	height: 28rpx;
 	margin-right: 8rpx;
+	width: 20rpx;
+	height: 20rpx;
 	flex-shrink: 0;
 }
 
-.status-text {
-	flex: 1;
-	font-size: 24rpx;
-	color: #666;
-	line-height: 1.5;
-}
+
 
 .chevron {
-	color: #999;
-	font-size: 24rpx;
-	margin-left: 8rpx;
+	display: flex;
+	align-items: center;
 }
 
 .card-footer {
+	flex: 1;
 	display: flex;
-	align-items: stretch;
+	align-items: center;
 	border-top: 1rpx solid #eee;
+	height: 80rpx;
 }
 
 .footer-btn {
@@ -493,15 +572,17 @@ export default {
 	text-align: center;
 	padding: 24rpx 0;
 	font-size: 28rpx;
-	line-height: 1.4;
 
 	&--ghost {
-		color: #999;
+		font-weight: 500;
+		font-size: 28rpx;
+		color: #86909C;
 	}
 
 	&--primary {
-		color: #333;
 		font-weight: 500;
+		font-size: 28rpx;
+		color: #1D2129;
 	}
 }
 
@@ -580,67 +661,155 @@ export default {
 	justify-content: center;
 	padding: 48rpx;
 	box-sizing: border-box;
-}
 
-.modal-box {
-	width: 100%;
-	max-width: 600rpx;
-	background: #fff;
-	border-radius: 16rpx;
-	overflow: hidden;
-}
+	.modal-box {
+		width: 100%;
+		max-width: 600rpx;
+		background: #fff;
+		border-radius: 16rpx;
+		overflow: hidden;
+	}
 
-.modal-title {
-	font-size: 32rpx;
-	font-weight: 600;
-	color: #333;
-	text-align: center;
-	padding: 32rpx 32rpx 16rpx;
-}
+	.modal-title {
+		font-size: 32rpx;
+		font-weight: 600;
+		color: #333;
+		text-align: center;
+		padding: 32rpx;
+	}
 
-.modal-body {
-	padding: 16rpx 32rpx 32rpx;
-	font-size: 26rpx;
-	color: #666;
-	line-height: 1.7;
-	max-height: 400rpx;
-	overflow-y: auto;
-}
+	.modal-body {
+		font-weight: 400;
+		font-size: 30rpx;
+		color: #4E5969;
+		max-height: 400rpx;
+		overflow-y: auto;
+		padding: 0 48rpx 32rpx;
+	}
 
-.modal-footer {
-	text-align: center;
-	padding: 24rpx;
-	font-size: 30rpx;
-	color: #0879ff;
-	border-top: 1rpx solid #eee;
-}
+	.modal-footer {
+		text-align: center;
+		padding: 24rpx;
+		font-size: 30rpx;
+		color: #1D2129;
+		border-top: 1rpx solid #eee;
+	}
 
-.apply-box {
-	padding-bottom: 0;
-}
+	.apply-box {
+		padding-bottom: 0;
+	}
 
-.apply-tip {
-	text-align: center;
-	font-size: 26rpx;
-	color: #666;
-	padding: 0 32rpx 16rpx;
-}
+	.apply-tip {
+		text-align: center;
+		font-size: 26rpx;
+		color: #666;
+		padding: 0 32rpx 16rpx;
+	}
 
-.apply-reason {
-	display: block;
-	width: calc(100% - 64rpx);
-	margin: 0 32rpx 24rpx;
-	min-height: 200rpx;
-	padding: 20rpx;
-	border: 1rpx solid #ddd;
-	border-radius: 8rpx;
-	font-size: 26rpx;
-	box-sizing: border-box;
+	.apply-reason {
+		display: block;
+		width: calc(100% - 64rpx);
+		margin: 0 32rpx 24rpx;
+		min-height: 200rpx;
+		padding: 20rpx;
+		border: 1rpx solid #ddd;
+		border-radius: 8rpx;
+		font-size: 26rpx;
+		box-sizing: border-box;
+	}
+
+	.apply-btns {
+		display: flex;
+		gap: 16rpx;
+		padding: 0 32rpx 32rpx;
+	}
 }
 
-.apply-btns {
+
+
+.modal-mask1 {
+	position: fixed;
+	left: 0;
+	top: 0;
+	right: 0;
+	bottom: 0;
+	background: rgba(0, 0, 0, 0.5);
+	z-index: 999;
 	display: flex;
-	gap: 16rpx;
-	padding: 0 32rpx 32rpx;
+	align-items: center;
+	justify-content: center;
+	padding: 48rpx;
+	box-sizing: border-box;
+
+	.modal-box {
+		width: 100%;
+		max-width: 600rpx;
+		background: #fff;
+		border-radius: 16rpx;
+
+	}
+
+	.box {
+		padding: 32rpx 48rpx;
+	}
+
+	.modal-title {
+		font-size: 32rpx;
+		font-weight: 600;
+		text-align: center;
+	}
+
+	.apply-tip {
+		margin-top: 32rpx;
+		font-weight: 400;
+		font-size: 30rpx;
+		color: #1D2129;
+		text-align: left;
+	}
+
+	.apply-reason {
+		width: 100%;
+		height: 124rpx;
+		padding: 8rpx;
+		display: block;
+		background: #F7F8FA;
+		border-radius: 6rpx 6rpx 6rpx 6rpx;
+		box-sizing: border-box;
+		margin-top: 8rpx;
+
+		font-weight: 400;
+		font-size: 26rpx;
+		color: #4E5969;
+	}
+
+	.apply-btns {
+		display: flex;
+		border-top: 1rpx solid #E7E7E7;
+	}
+
+	.btn {
+		padding: 20rpx;
+		height: 90rpx;
+		font-size: 28rpx;
+		border-radius: 8rpx;
+		text-align: center;
+		font-weight: 400;
+		font-size: 30rpx;
+		color: #86909C;
+		text-align: center;
+
+
+
+		&.submit {
+			border-left: 1rpx solid #E7E7E7;
+			font-weight: 400;
+			font-size: 30rpx;
+			color: #1D2129;
+		}
+
+		&.flex1 {
+			flex: 1;
+		}
+	}
 }
 </style>

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