| 1 |
- {"version":3,"sources":["E:/tool/HBuilderX.5.02.2026030616-alpha/HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/uni-console/src/runtime/app/socket.ts","App.uvue","utils/request.uts","E:/tool/HBuilderX.5.02.2026030616-alpha/HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/uni-console/src/runtime/utils.ts","utils/api/location.uts","pages/myEdit/setting.uvue","pages/login/login.uvue","pages/order/order.uvue","E:/tool/HBuilderX.5.02.2026030616-alpha/HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/uni-console/src/runtime/app/index.ts","main.uts","components/u-floating/u-floating.vue","static/imagesInfo/bg-color.png.uts","static/imagesInfo/bg-color.png.ts","static/imagesInfo/bg-icon.png.uts","static/imagesInfo/bg-icon.png.ts","utils/api/masterInfoApi.uts","utils/api/order.uts","utils/api/workbenches.uts","pages/homepage/console.uvue","pages/myEdit/my.uvue","utils/api/account.uts","pages/account/account.uvue","pages/homepage/setOrderTime.uvue","utils/api/login.uts","pages/login/merchantRecuitment.uvue","pages/order/orderStatisics.uvue","pages/order/appraise.uvue","utils/api/tool.uts","pages/order/orderDetail.uvue"],"sourcesContent":["/// <reference types=\"@dcloudio/uni-app-x/types/uni/global\" />\n\nimport { currentPageCaptureScreenshot } from '../utils'\n\n// 之所以又写了一份,是因为外层的socket,connectSocket的时候必须传入multiple:true\n// 但是android又不能传入,目前代码里又不能写条件编译之类的。\nexport function initRuntimeSocket(\n hosts: string,\n port: string,\n id: string\n): Promise<SocketTask | null> {\n if (hosts == '' || port == '' || id == '') return Promise.resolve(null)\n return hosts\n .split(',')\n .reduce<Promise<SocketTask | null>>(\n (\n promise: Promise<SocketTask | null>,\n host: string\n ): Promise<SocketTask | null> => {\n return promise.then((socket): Promise<SocketTask | null> => {\n if (socket != null) return Promise.resolve(socket)\n return tryConnectSocket(host, port, id)\n })\n },\n Promise.resolve(null)\n )\n}\n\nconst SOCKET_TIMEOUT = 500\nfunction tryConnectSocket(\n host: string,\n port: string,\n id: string\n): Promise<SocketTask | null> {\n return new Promise((resolve, reject) => {\n const socket = uni.connectSocket({\n url: `ws://${host}:${port}/${id}`,\n fail() {\n resolve(null)\n },\n })\n const timer = setTimeout(() => {\n // @ts-expect-error\n socket.close({\n code: 1006,\n reason: 'connect timeout',\n } as CloseSocketOptions)\n resolve(null)\n }, SOCKET_TIMEOUT)\n\n socket.onOpen((e) => {\n clearTimeout(timer)\n resolve(socket)\n })\n socket.onClose((e) => {\n clearTimeout(timer)\n resolve(null)\n })\n socket.onError((e) => {\n clearTimeout(timer)\n resolve(null)\n })\n // 接收 hx 消息,处理截屏请求\n socket.onMessage((result) => {\n if (typeof result['data'] == 'string') {\n // @ts-expect-error\n const message = JSON.parse<UTSJSONObject>(result['data'] as string)!\n if ((message['type'] as string) == 'screencap') {\n const id = message['id'] as string\n currentPageCaptureScreenshot(\n message['fullPage'] as boolean,\n (base64: string, error: string) => {\n // @ts-expect-error\n socket.send({\n data: JSON.stringify({\n id,\n base64,\n error,\n }),\n } as SendSocketMessageOptions)\n }\n )\n }\n }\n resolve(null)\n })\n })\n}\n","<script lang=\"uts\">\r\n\r\n\tlet firstBackTime = 0\r\n\r\n\texport default {\r\n\t\tonLaunch() {\r\n\t\t\tconsole.log('App Launch')\r\n\t\t\t// 1. 从本地缓存读取 token(或用户信息)\r\n\t\t\tconst token = uni.getStorageSync('token');\r\n\t\t\tconsole.log(token, 'token');\r\n\r\n\t\t\t// 2. 判断登录态\r\n\t\t\tif (token === '' || token === null || token === 'undefined') {\r\n\t\t\t\t// 未登录:跳转到默认登录页\r\n\t\t\t\tuni.reLaunch({ url: '/pages/login/login' })\r\n\t\t\t} else {\r\n\t\t\t\t// 已登录:正常进入首页\r\n\t\t\t\tuni.switchTab({ url: '/pages/homepage/console' })\r\n\t\t\t}\r\n\t\t},\r\n\t\tonShow() {\r\n\t\t\tconsole.log('App Show')\r\n\t\t},\r\n\t\tonHide() {\r\n\t\t\tconsole.log('App Hide')\r\n\t\t},\r\n\r\n\t\tonLastPageBackPress() {\r\n\t\t\tconsole.log('App LastPageBackPress')\r\n\t\t\tif (firstBackTime == 0) {\r\n\t\t\t\tuni.showToast({\r\n\t\t\t\t\ttitle: '再按一次退出应用',\r\n\t\t\t\t\tposition: 'bottom',\r\n\t\t\t\t})\r\n\t\t\t\tfirstBackTime = Date.now()\r\n\t\t\t\tsetTimeout(() => {\r\n\t\t\t\t\tfirstBackTime = 0\r\n\t\t\t\t}, 2000)\r\n\t\t\t} else if (Date.now() - firstBackTime < 2000) {\r\n\t\t\t\tfirstBackTime = Date.now()\r\n\t\t\t\tuni.exit()\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\tonExit() {\r\n\t\t\tconsole.log('App Exit')\r\n\t\t},\r\n\t}\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n\t/*每个页面公共css */\r\n\t.uni-row {\r\n\t\tflex-direction: row;\r\n\t}\r\n\r\n\t.uni-column {\r\n\t\tflex-direction: column;\r\n\t}\r\n</style>","// uni-app x UTS 标准请求封装 | APP 直接访问,WEB 需代理跨域\r\n// 修复:URL 格式错误、Header 类型错误、平台判断错误\r\n\r\n// 定义请求配置类型\r\nexport type RequestOptions = {\r\n\turl : string\r\n\tmethod ?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'\r\n\tparams ?: any | null\r\n\tdata ?: any | null\r\n\tshowLoading ?: boolean\r\n\tloadingMsg ?: string\r\n}\r\n\r\n// 平台判断工具(运行期判断,兼容所有平台)\r\nclass PlatformUtil {\r\n\t// 获取平台信息(使用 uniPlatform,uni-app x 推荐方式)\r\n\tstatic getPlatform() : string {\r\n\t\ttry {\r\n\t\t\tconst appBaseInfo = uni.getAppBaseInfo()\r\n\t\t\tif (appBaseInfo.uniPlatform != null && appBaseInfo.uniPlatform.length > 0) {\r\n\t\t\t\treturn appBaseInfo.uniPlatform\r\n\t\t\t}\r\n\t\t\t// 降级方案:尝试 getSystemInfoSync\r\n\t\t\tconst systemInfo = uni.getSystemInfoSync()\r\n\t\t\tif (systemInfo.platform != null && systemInfo.platform.length > 0) {\r\n\t\t\t\treturn systemInfo.platform\r\n\t\t\t}\r\n\t\t\treturn ''\r\n\t\t} catch (e) {\r\n\t\t\treturn ''\r\n\t\t}\r\n\t}\r\n\r\n\t// 是否为 App 端(Android 或 iOS)\r\n\tstatic isApp() : boolean {\r\n\t\tconst platform = this.getPlatform()\r\n\t\treturn platform === 'app' || platform === 'android' || platform === 'ios'\r\n\t}\r\n\r\n\t// 是否为 Web 端(H5)\r\n\tstatic isH5() : boolean {\r\n\t\tconst platform = this.getPlatform()\r\n\t\treturn platform === 'web'\r\n\t}\r\n\r\n\t// 是否为微信小程序\r\n\tstatic isMpWeixin() : boolean {\r\n\t\tconst platform = this.getPlatform()\r\n\t\treturn platform === 'mp-weixin'\r\n\t}\r\n\r\n\t// 是否为小程序(通用)\r\n\tstatic isMiniProgram() : boolean {\r\n\t\tconst platform = this.getPlatform()\r\n\t\treturn platform.startsWith('mp-')\r\n\t}\r\n}\r\n\r\nfunction toUTSJSONObject(input : any | null) : any | null {\r\n\tif (input == null) return null\r\n\tif (typeof input !== 'object') return null\r\n\r\n\ttry {\r\n\t\t// 通过 JSON 归一化为普通对象,避免 UTS 中遍历/动态索引的兼容问题\r\n\t\treturn JSON.parse(JSON.stringify(input)) as UTSJSONObject\r\n\t} catch (e) {\r\n\t\treturn null\r\n\t}\r\n}\r\n\r\n// 核心请求方法,APP 端直接访问,WEB 端自动代理前缀\r\nexport function request(options : RequestOptions | null) : Promise<any> {\r\n\treturn new Promise<any>((resolve, reject) => {\r\n\t\tif (options == null) {\r\n\t\t\treject(new Error('请求参数不能为空'))\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\t// 1. 处理URL\r\n\t\tlet url = options.url\r\n\t\tif (typeof url !== 'string' || url.length === 0) {\r\n\t\t\treject(new Error('请求地址不能为空'))\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\t// 2. 根据平台处理 URL\r\n\t\tif (PlatformUtil.isH5()) {\r\n\t\t\tconst proxyPrefix = '/dev'\r\n\t\t\tconst isProxy = typeof url === 'string' && url.length >= proxyPrefix.length && url.substring(0, proxyPrefix.length) === proxyPrefix\r\n\t\t\tconst isHttp = typeof url === 'string' && (url.indexOf('http') === 0)\r\n\t\t\tif (!isProxy && !isHttp) {\r\n\t\t\t\tconst isSlash = typeof url === 'string' && url.indexOf('/') === 0\r\n\t\t\t\tif (!isSlash) {\r\n\t\t\t\t\turl = '/' + url\r\n\t\t\t\t}\r\n\t\t\t\turl = proxyPrefix + url\r\n\r\n\t\t\t}\r\n\t\t} else if (PlatformUtil.isApp()) {\r\n\t\t\tconst isHttpUrl =\r\n\t\t\t\t(typeof url === 'string' && url.indexOf('http://') === 0) ||\r\n\t\t\t\t(typeof url === 'string' && url.indexOf('https://') === 0)\r\n\t\t\tif (!isHttpUrl) {\r\n\t\t\t\treject(new Error('App 端请求地址必须是完整的 http:// 或 https:// URL,当前:' + url))\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// 3. 处理请求方法(保持字面量,避免 toUpperCase 造成类型丢失)\r\n\t\tconst method = (options.method ?? 'GET') as string\r\n\r\n\t\t// 4. 最终 URL\r\n\t\tconst finalUrl = url\r\n\r\n\t\t// 5. 构建请求头\r\n\t\t// if (PlatformUtil.isH5()) {\r\n\t\t// \tconst header = mapToUTSJSONObject(headerMap);\r\n\t\t// } else if (PlatformUtil.isApp()) { \r\n\t\t// \tconst header = UTSJSONObject(); \r\n\t\t// \theader['Content-Type'] = 'application/json'\r\n\t\t// \t}\r\n\t\t// 获取 token\r\n\t\t// const token = uni.getStorageSync('token') as string\r\n\t\t// if (typeof token === 'string' && token.length > 0) {\r\n\t\t// \theader['Authorization'] = 'Bearer ' + token\r\n\t\t// }\r\n\t\t// const headerMap = new Map<string, string>()\r\n\t\t// \theaderMap.set('Content-Type', 'application/json')\r\n\t\tconst token = uni.getStorageSync('token') as string | null\r\n\t\t// \tif (token.length > 0) headerMap.set('Authorization', 'Bearer ' + token)\r\n\t\t// \tconst tenantId = uni.getStorageSync('tenantId') as string | null\r\n\t\t// \theaderMap.set('tenant-id', tenantId ?? 'default')\r\n\t\t// \theaderMap.set('terminal', uni.getSystemInfoSync().platform)\r\n\t\t// \tconst header = mapToUTSJSONObject(headerMap)\r\n\t\t// 获取 tenantId\r\n\t\tconst tenantIdOrigin = uni.getStorageSync('tenantId')\r\n\t\tlet tenantValue = 'default'\r\n\t\tif (typeof tenantIdOrigin === 'string') {\r\n\t\t\tif (tenantIdOrigin != null && (tenantIdOrigin as string).length > 0) {\r\n\t\t\t\ttenantValue = tenantIdOrigin as string\r\n\t\t\t}\r\n\t\t}\r\n\t\t// \theader['tenant-id'] = tenantValue\r\n\r\n\t\t// \t// 获取平台信息\r\n\t\t// \ttry {\r\n\t\t// \t\tconst systemInfo = uni.getSystemInfoSync()\r\n\t\t// \t\tif (typeof systemInfo.platform === 'string' && systemInfo.platform.length > 0) {\r\n\t\t// \t\t\theader['terminal'] = systemInfo.platform\r\n\t\t// \t\t} else {\r\n\t\t// \t\t\theader['terminal'] = 'unknown'\r\n\t\t// \t\t}\r\n\t\t// \t} catch (e) {\r\n\t\t// \t\theader['terminal'] = 'unknown'\r\n\t\t// \t}\r\n\t\tconst header = {\r\n\t\t\t'tenant-id': tenantValue ?? 'default',\r\n\t\t\t'terminal': uni.getSystemInfoSync().platform,\r\n\t\t\t'Content-Type': 'application/json',\r\n\t\t\t'Authorization': token != null ? `Bearer ${token}` : '' // 添加 token\r\n\t\t} as UTSJSONObject\r\n\r\n\t\t// 6. 处理请求数据(UTS 下 uni.request 期望 Map<String, Any>?)\r\n\t\t// GET 参数通过 data 传递,由框架负责拼接到 query,避免手动遍历拼接导致的 UTS 编译问题\r\n\t\tconst requestData = method === 'GET' ? toUTSJSONObject(options.params) : toUTSJSONObject(options.data)\r\n\r\n\t\t// 7. 处理加载提示\r\n\t\tconst showLoading = typeof options.showLoading === 'boolean' ? options.showLoading : true\r\n\t\tconst loadingMsg = typeof options.loadingMsg === 'string' ? options.loadingMsg : '加载中'\r\n\r\n\t\tif (showLoading) {\r\n\t\t\tuni.showLoading({ title: loadingMsg, mask: true })\r\n\t\t}\r\n\r\n\t\t// 8. 发起请求\r\n\t\tuni.request({\r\n\t\t\turl: finalUrl,\r\n\t\t\tmethod: method,\r\n\t\t\tdata: requestData,\r\n\t\t\theader: header,\r\n\t\t\ttimeout: 30000,\r\n\t\t\tdataType: 'json',\r\n\t\t\tresponseType: 'text',\r\n\t\t\tsuccess: (res) => {\r\n\t\t\t\tuni.hideLoading()\r\n\t\t\t\tif (res.statusCode >= 200 && res.statusCode < 300) {\r\n\t\t\t\t\tresolve(res.data ?? {})\r\n\t\t\t\t} else {\r\n\t\t\t\t\treject(new Error(`请求失败:HTTP ${res.statusCode}`))\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tfail: (err) => {\r\n\t\t\t\tuni.hideLoading()\r\n\t\t\t\t__f__('error','at utils/request.uts:194','Request failed:', err)\r\n\r\n\t\t\t\t// 详细错误日志\r\n\t\t\t\t__f__('error','at utils/request.uts:197','Error code:', err.errCode)\r\n\t\t\t\t__f__('error','at utils/request.uts:198','Error message:', err.errMsg)\r\n\t\t\t\t__f__('error','at utils/request.uts:199','Error subject:', err.errSubject)\r\n\r\n\t\t\t\t// 根据错误码给出具体错误信息 [15]\r\n\t\t\t\tlet errorMsg = '网络异常,请重试'\r\n\t\t\t\tif (err.errCode === 600009) {\r\n\t\t\t\t\terrorMsg = 'URL 格式不合法,请检查请求地址是否正确(App端必须使用完整URL)'\r\n\t\t\t\t} else if (err.errCode === 600003) {\r\n\t\t\t\t\terrorMsg = '网络中断,请检查网络连接'\r\n\t\t\t\t} else if (err.errCode === 600008) {\r\n\t\t\t\t\terrorMsg = '请求数据格式错误'\r\n\t\t\t\t} else if (err.errCode === 600001) {\r\n\t\t\t\t\terrorMsg = '请求超时,请检查网络状况'\r\n\t\t\t\t} else if (typeof err.errMsg === 'string' && err.errMsg.length > 0) {\r\n\t\t\t\t\terrorMsg = err.errMsg\r\n\t\t\t\t}\r\n\r\n\t\t\t\treject(new Error(errorMsg))\r\n\t\t\t}\r\n\t\t})\r\n\t})\r\n}","export type SendFn = ((msg: string) => void) | null\n\nexport type currentPageCaptureScreenshotCallBack = (\n base64: string,\n error: string\n) => void\n\nexport function currentPageCaptureScreenshot(\n fullPage: boolean,\n callback: currentPageCaptureScreenshotCallBack\n) {\n const pages = getCurrentPages() as UniPage[]\n const currentPage = pages[pages.length - 1]\n currentPage.vm?.$viewToTempFilePath({\n wholeContent: fullPage,\n overwrite: true,\n success: (res) => {\n const fileManager = uni.getFileSystemManager()\n // @ts-expect-error\n fileManager.readFile({\n encoding: 'base64',\n filePath: res.tempFilePath,\n success(readFileRes) {\n callback(readFileRes.data as string, '')\n },\n fail(err) {\n callback('', `captureScreenshot fail: ${JSON.stringify(err)}`)\n },\n } as ReadFileOptions)\n },\n fail: (err) => {\n callback('', `captureScreenshot fail: ${JSON.stringify(err)}`)\n },\n })\n}\n","type QQMapApi = {\n\tIP_LOCATION: string\n\tGEOCODER: string\n\tDISTANCE: string\n\tSCAN_QR_CODE: string\n}\n\ntype QQMapConfig = {\n\tKEY: string\n\tAPI: QQMapApi\n}\n\ntype LocationPoint = {\n\tlongitude: number\n\tlatitude: number\n}\n\ntype LocationResult = {\n\tcode: number\n\tdata?: UTSJSONObject\n\tmessage: string\n\tresult?: any\n}\n\nconst QQ_MAP: QQMapConfig = {\n\tKEY: 'SIFBZ-2UJEZ-FZIXF-TAVLV-6GWVK-ZEBZX',\n\tAPI: {\n\t\tIP_LOCATION: 'https://apis.map.qq.com/ws/location/v1/ip',\n\t\tGEOCODER: 'https://apis.map.qq.com/ws/geocoder/v1/',\n\t\tDISTANCE: 'https://apis.map.qq.com/ws/distance/v1/',\n\t\tSCAN_QR_CODE: 'https://apis.map.qq.com/ws/barcode/v1/scan',\n\t}\n}\n\nconst showLocationSettingModal = () : void => {\n\tuni.showModal({\n\t\ttitle: '提示',\n\t\tcontent: '请先开启定位权限后重试',\n\t\tshowCancel: false,\n\t\tconfirmText: '我知道了',\n\t})\n}\n\nconst buildLocationData = (point: LocationPoint, num: number) : UTSJSONObject => {\n\treturn {\n\t\tlocation: {\n\t\t\tlongitude: point.longitude,\n\t\t\tlatitude: point.latitude,\n\t\t},\n\t\tnum: num,\n\t} as UTSJSONObject\n}\n\n/**\n * 扫描二维码\n */\nexport const scanQRCode = async () : Promise<any> => {\n\treturn new Promise<any>((resolve: (value: any) => void, reject: (reason?: any) => void) => {\n\t\tuni.scanCode({\n\t\t\tscanType: ['qrCode', 'barCode'],\n\t\t\tsuccess: (res) => {\n\t\t\t\tresolve((res.result as string | null) ?? '')\n\t\t\t},\n\t\t\tfail: (err) => {\n\t\t\t\treject(err)\n\t\t\t}\n\t\t})\n\t})\n}\n\n/**\n * 请求位置授权\n */\nexport const requestLocationAuth = async () : Promise<void> => {\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n}\n\n/**\n * 发起定位相关请求\n */\nexport const requestJsonp = async (url: string, params: UTSJSONObject | null) : Promise<any> => {\n\ttry {\n\t\tconst requestParams = params ?? ({} as UTSJSONObject)\n\t\treturn await new Promise<any>((resolve: (value: any) => void, reject: (reason?: any) => void) => {\n\t\t\tuni.request({\n\t\t\t\turl: url,\n\t\t\t\tmethod: 'GET',\n\t\t\t\tdata: requestParams,\n\t\t\t\tsuccess: (res) => {\n\t\t\t\t\tconst response = res.data as UTSJSONObject | null\n\t\t\t\t\tif (response == null) {\n\t\t\t\t\t\treject(new Error('定位服务响应为空'))\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tconst status = (response['status'] as number | null) ?? 0\n\t\t\t\t\tif (status === 0) {\n\t\t\t\t\t\tresolve(response['result'] ?? response)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\treject(response)\n\t\t\t\t},\n\t\t\t\tfail: (err) => {\n\t\t\t\t\treject(err)\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t} catch (error) {\n\t\t__f__('error','at utils/api/location.uts:126','定位请求错误:', error)\n\t\treturn null\n\t}\n}\n\n/**\n * 通过城市名字搜索\n */\nexport const getCityNameInfo = async (cityName: string = '') : Promise<UTSJSONObject | null> => {\n\ttry {\n\t\tconst params = {\n\t\t\taddress: cityName,\n\t\t\tkey: QQ_MAP.KEY,\n\t\t} as UTSJSONObject\n\t\tconst res = await requestJsonp(QQ_MAP.API.GEOCODER, params) as UTSJSONObject | null\n\t\tif (res == null) {\n\t\t\treturn null\n\t\t}\n\t\treturn {\n\t\t\tarea_code: ((res['ad_info'] as UTSJSONObject | null)?.['adcode'] as string | null) ?? '',\n\t\t\tcity: ((res['address_components'] as UTSJSONObject | null)?.['city'] as string | null) ?? '',\n\t\t\tlatitude: ((res['location'] as UTSJSONObject | null)?.['lat'] as number | null) ?? 0,\n\t\t\tlongitude: ((res['location'] as UTSJSONObject | null)?.['lng'] as number | null) ?? 0,\n\t\t} as UTSJSONObject\n\t} catch (error) {\n\t\t__f__('error','at utils/api/location.uts:151','城市定位请求错误:', error)\n\t\treturn null\n\t}\n}\n\n/**\n * 初始化微信配置\n */\nexport const initWxConfig = async () : Promise<UTSJSONObject> => {\n\treturn Promise.resolve({\n\t\tcode: 200,\n\t\tmessage: '当前平台无需微信初始化',\n\t} as UTSJSONObject)\n}\n\n/**\n * 获取当前位置信息\n */\nexport const getCurrentLocation = async () : Promise<LocationResult> => {\n\treturn new Promise<LocationResult>((resolve: (value: LocationResult) => void, reject: (reason?: any) => void) => {\n\t\tlet hasResolved = false\n\t\tconst fallbackToIpLocation = async () : Promise<void> => {\n\t\t\tif (hasResolved) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst locationData = await requestJsonp(QQ_MAP.API.IP_LOCATION, {\n\t\t\t\t\tkey: QQ_MAP.KEY,\n\t\t\t\t} as UTSJSONObject) as UTSJSONObject | null\n\t\t\t\tconst location = locationData?.['location'] as UTSJSONObject | null\n\t\t\t\tif (location != null) {\n\t\t\t\t\thasResolved = true\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tcode: 200,\n\t\t\t\t\t\tdata: buildLocationData({\n\t\t\t\t\t\t\tlongitude: (location['lng'] as number | null) ?? 0,\n\t\t\t\t\t\t\tlatitude: (location['lat'] as number | null) ?? 0,\n\t\t\t\t\t\t}, 1),\n\t\t\t\t\t\tmessage: '获取IP定位成功',\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\treject({ code: 202, message: '获取位置失败' } as UTSJSONObject)\n\t\t\t} catch (e) {\n\t\t\t\treject({ code: 202, message: 'IP定位异常' } as UTSJSONObject)\n\t\t\t}\n\t\t}\n\t\tconst timeoutInfo = setTimeout(() => {\n\t\t\tfallbackToIpLocation()\n\t\t}, 3000)\n\n\t\tuni.getLocation({\n\t\t\ttype: 'gcj02',\n\t\t\tsuccess: (res) => {\n\t\t\t\tif (hasResolved) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\thasResolved = true\n\t\t\t\tclearTimeout(timeoutInfo)\n\t\t\t\tconst point: LocationPoint = {\n\t\t\t\t\tlongitude: res.longitude,\n\t\t\t\t\tlatitude: res.latitude,\n\t\t\t\t}\n\t\t\t\tuni.setStorageSync('locationInfo', point)\n\t\t\t\tresolve({\n\t\t\t\t\tcode: 200,\n\t\t\t\t\tdata: buildLocationData(point, 2),\n\t\t\t\t\tmessage: '获取位置成功',\n\t\t\t\t})\n\t\t\t},\n\t\t\tfail: () => {\n\t\t\t\tclearTimeout(timeoutInfo)\n\t\t\t\tshowLocationSettingModal()\n\t\t\t\treject({\n\t\t\t\t\tcode: 202,\n\t\t\t\t\tmessage: '获取位置失败',\n\t\t\t\t} as UTSJSONObject)\n\t\t\t},\n\t\t})\n\t})\n}\n\n/**\n * 解析地理位置信息\n */\nexport const parseLocation = async (location: UTSJSONObject) : Promise<LocationResult> => {\n\ttry {\n\t\tconst latitude = (location['latitude'] as number | null) ?? 0\n\t\tconst longitude = (location['longitude'] as number | null) ?? 0\n\t\tconst geoLocation = await requestJsonp(QQ_MAP.API.GEOCODER, {\n\t\t\tkey: QQ_MAP.KEY,\n\t\t\tlocation: `${latitude},${longitude}`,\n\t\t} as UTSJSONObject)\n\t\tuni.setStorageSync('userAddress', geoLocation)\n\t\treturn {\n\t\t\tcode: 200,\n\t\t\tdata: {\n\t\t\t\tgeoLocation: geoLocation,\n\t\t\t} as UTSJSONObject,\n\t\t\tmessage: '解析地址成功',\n\t\t}\n\t} catch (error) {\n\t\treturn {\n\t\t\tcode: 500,\n\t\t\tmessage: '解析地址失败',\n\t\t}\n\t}\n}\n\n/**\n * 计算两点间距离\n */\nexport const calculateDistance = async (startPoint: UTSJSONObject, endPoint: UTSJSONObject) : Promise<LocationResult> => {\n\ttry {\n\t\tconst startLatitude = (startPoint['latitude'] as number | null) ?? 0\n\t\tconst startLongitude = (startPoint['longitude'] as number | null) ?? 0\n\t\tconst endLatitude = (endPoint['latitude'] as number | null) ?? 0\n\t\tconst endLongitude = (endPoint['longitude'] as number | null) ?? 0\n\t\tconst result = await requestJsonp(QQ_MAP.API.DISTANCE, {\n\t\t\tfrom: `${startLatitude},${startLongitude}`,\n\t\t\tto: `${endLatitude},${endLongitude}`,\n\t\t\tkey: QQ_MAP.KEY,\n\t\t\tmode: 'driving',\n\t\t} as UTSJSONObject) as UTSJSONObject | null\n\n\t\tconst elements = result?.['elements'] as UTSArray<UTSJSONObject> | null\n\t\tif (elements != null && elements.length > 0) {\n\t\t\tconst firstElement = elements[0]\n\t\t\treturn {\n\t\t\t\tcode: 200,\n\t\t\t\tdata: {\n\t\t\t\t\tdistance: (firstElement['distance'] as number | null) ?? 0,\n\t\t\t\t} as UTSJSONObject,\n\t\t\t\tresult: result,\n\t\t\t\tmessage: '计算距离成功',\n\t\t\t}\n\t\t}\n\t\tthrow new Error('无效的距离数据')\n\t} catch (error) {\n\t\treturn {\n\t\t\tcode: 202,\n\t\t\tmessage: '计算距离失败',\n\t\t}\n\t}\n}\n\n/**\n * 格式化数字为千分位\n */\nexport const formatThousands = (number: number = 0) : string => {\n\treturn number.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',')\n}\n\n/**\n * 手机号码脱敏处理\n */\nexport const maskPhoneNumber = (phone: string = '') : string => {\n\treturn phone.length > 0 ? phone.replace(/(\\d{3})\\d{6}(\\d{2})/, '$1******$2') : ''\n}\n\n/**\n * 拨打电话\n */\nexport const makePhoneCall = (phoneNumber: string) : Promise<any> => {\n\tconst phone = phoneNumber.length > 0 ? phoneNumber : '19806196313'\n\treturn new Promise<any>((resolve: (value: any) => void, reject: (reason?: any) => void) => {\n\t\tuni.makePhoneCall({\n\t\t\tphoneNumber: phone,\n\t\t\tsuccess: () => {\n\t\t\t\tresolve({\n\t\t\t\t\tcode: 200,\n\t\t\t\t\tmessage: '拨号成功',\n\t\t\t\t})\n\t\t\t},\n\t\t\tfail: (err) => {\n\t\t\t\treject({\n\t\t\t\t\tcode: 500,\n\t\t\t\t\tmessage: '拨号失败',\n\t\t\t\t\terror: err,\n\t\t\t\t})\n\t\t\t},\n\t\t})\n\t})\n}\n","<template>\r\n <view class=\"setting-page\">\r\n <view class=\"setting-list\">\r\n <view class=\"setting-item\" @click=\"goToAccountSecurity\">\r\n <text class=\"item-text\">\r\n 账号安全\r\n </text>\r\n <u-icon name=\"arrow-right\" size=\"18\" color=\"#999\" />\r\n </view>\r\n <view class=\"setting-item\" @click=\"goToFeedback\">\r\n <text class=\"item-text\">\r\n 意见反馈\r\n </text>\r\n <u-icon name=\"arrow-right\" size=\"18\" color=\"#999\" />\r\n </view>\r\n <view class=\"setting-item\" @click=\"goToAbout\">\r\n <text class=\"item-text\">\r\n 关于我们\r\n </text>\r\n <u-icon name=\"arrow-right\" size=\"18\" color=\"#999\" />\r\n </view>\r\n </view>\r\n <view class=\"logout-section\">\r\n <button class=\"logout-btn\" @click=\"doLogout\">\r\n 退出登录\r\n </button>\r\n </view>\r\n </view>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n const goToAccountSecurity = () => {\r\n uni.navigateTo({\r\n url: '/pages/myEdit/account-security'\r\n })\r\n }\r\n const goToFeedback = () => {\r\n uni.navigateTo({\r\n url: '/pages/myEdit/feedback'\r\n })\r\n }\r\n const goToAbout = () => {\r\n uni.navigateTo({\r\n url: '/pages/myEdit/about'\r\n })\r\n }\r\n const doLogout = () => {\r\n // 清除本地 token 或其他信息\r\n uni.removeStorageSync('token');\r\n uni.showToast({ title: '已退出登录', icon: 'success' });\r\n setTimeout(() => {\r\n uni.reLaunch({\r\n url: '/pages/login/login'\r\n })\r\n }, 500)\r\n }\r\n</script>\r\n\r\n<style>\r\n .setting-page {\r\n\r\n background: #f7f8fa;\r\n padding-top: 20rpx;\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: space-between;\r\n }\r\n .setting-list {\r\n background: #fff;\r\n border-radius: 20rpx;\r\n margin: 24rpx 24rpx 0 24rpx;\r\n box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.03);\r\n overflow: hidden;\r\n }\r\n .setting-item {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 32rpx 24rpx;\r\n border-bottom: 1rpx solid #f1f1f1;\r\n font-size: 30rpx;\r\n color: #222;\r\n background: #fff;\r\n }\r\n .setting-item:last-child {\r\n border-bottom: none;\r\n }\r\n .item-text {\r\n }\r\n .logout-section {\r\n margin-top: auto;\r\n margin-bottom: 60rpx;\r\n padding: 0 24rpx;\r\n }\r\n .logout-btn {\r\n width: 100%;\r\n color: #000;\r\n border-radius: 40rpx;\r\n font-size: 32rpx;\r\n padding: 26rpx 0;\r\n border: none;\r\n box-shadow: 0 4rpx 10rpx rgba(186, 171, 171, 0.1);\r\n font-weight: bold;\r\n border: 1rpx solid #000;\r\n }\r\n</style>\r\n","<template>\r\n\t<view class=\"page-container\">\r\n\t\t<view class=\"close-btn\" @click=\"goBack\">\r\n\t\t</view>\r\n\r\n\t\t<view class=\"header-section\">\r\n\t\t\t<text class=\"hello-text\">\r\n\t\t\t\tHello!\r\n\t\t\t</text>\r\n\t\t\t<text class=\"welcome-text\">\r\n\t\t\t\t欢迎来到小丁到家\r\n\t\t\t</text>\r\n\t\t\t<image src=\"/static/logo-massage.png\" class=\"logo-img\" mode=\"aspectFit\">\r\n\t\t\t</image>\r\n\t\t</view>\r\n\r\n\t\t<view class=\"form-section\">\r\n\t\t\t<view class=\"input-box\">\r\n\t\t\t\t<input class=\"input-field\" type=\"number\" placeholder=\"请输入手机号码\" v-model=\"mobile\" maxlength=\"11\" />\r\n\t\t\t</view>\r\n\r\n\t\t\t<view class=\"input-box row-between\">\r\n\t\t\t\t<input class=\"input-field\" type=\"number\" placeholder=\"请输入验证码\" v-model=\"mobileCode\" maxlength=\"6\" />\r\n\t\t\t\t<text class=\"code-btn\" :class=\"{ disabled: !canSend }\" @click=\"sendCode\">\r\n\t\t\t\t\t{{ codeText }}\r\n\t\t\t\t</text>\r\n\t\t\t</view>\r\n\r\n\t\t\t<view class=\"login-btn\" :class=\"{ disabled: !canLogin }\" @click=\"doLogin\">\r\n\t\t\t\t登录\r\n\t\t\t</view>\r\n\r\n\t\t\t<view class=\"agree-row row-start\">\r\n\t\t\t\t<radio :value=\"isAgree\" color=\"#FFCC33\" style=\"transform: scale(0.7);\" class=\"radio r\" />\r\n\t\t\t\t<view class=\"agree-content\">\r\n\t\t\t\t\t<text class=\"agree-text\" @click=\"showModal=true\">\r\n\t\t\t\t\t\t我已阅读并同意\r\n\t\t\t\t\t\t<text class=\"link-text\">\r\n\t\t\t\t\t\t\t《用户协议》\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t<text class=\"link-text\">\r\n\t\t\t\t\t\t\t《隐私政策》\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t<text class=\"link-text\">\r\n\t\t\t\t\t\t\t《上门按摩服务行业平台公约》\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t,未注册的手机号将自动创建小丁到家账号\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t</view>\r\n\t\t</view>\r\n\r\n\t\t<view class=\"footer-section\">\r\n\t\t\t<view class=\"divider-row row-center\">\r\n\t\t\t\t<view class=\"line\">\r\n\t\t\t\t</view>\r\n\t\t\t\t<text class=\"divider-text\">\r\n\t\t\t\t\t其他登录方式\r\n\t\t\t\t</text>\r\n\t\t\t\t<view class=\"line\">\r\n\t\t\t\t</view>\r\n\t\t\t</view>\r\n\t\t\t<view class=\"methods-row row-center\">\r\n\t\t\t\t<view class=\"method-item column-center\" @click=\"customLoginIn()\">\r\n\t\t\t\t\t<view class=\"icon-box blue-bg\">\r\n\t\t\t\t\t\t<u-icon name=\"phone\" :size=\"24\" />\r\n\t\t\t\t\t</view>\r\n\t\t\t\t\t<text class=\"method-name\">\r\n\t\t\t\t\t\t一键登录\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t\t<view class=\"method-item column-center\" @click=\"wechatLogin\">\n\t\t\t\t\t<view class=\"icon-box green-bg\">\n\t\t\t\t\t\t<text class=\"wechat-mark\">微</text>\n\t\t\t\t\t</view>\n\t\t\t\t\t<text class=\"method-name\">\n\t\t\t\t\t\t微信登录\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t</view>\r\n\t\t</view>\r\n\r\n\t\t<view v-if=\"showModal\" class=\"modal-mask\" @click=\"showModal=false\">\r\n\t\t\t<view class=\"modal-box\" @click.stop>\r\n\t\t\t\t<text class=\"modal-title\">\r\n\t\t\t\t\t服务协议及隐私政策\r\n\t\t\t\t</text>\r\n\r\n\t\t\t\t<scroll-view scroll-y class=\"modal-scroll\">\r\n\t\t\t\t\t<text class=\"modal-welcome\">\r\n\t\t\t\t\t\t欢迎您使用小丁到家!\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text class=\"modal-desc\">\r\n\t\t\t\t\t\t请你务必审慎阅读、并充分理解\r\n\t\t\t\t\t\t<text class=\"modal-link\">\r\n\t\t\t\t\t\t\t《用户协议》\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t和\r\n\t\t\t\t\t\t<text class=\"modal-link\">\r\n\t\t\t\t\t\t\t《隐私政策》\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t,协议内容包括但不限于:\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text class=\"modal-list\">\r\n\t\t\t\t\t\t1、在您使用软件及服务的过程中,向您提供相关基本功能,我们将根据合法、正当、必要的原则,收集或使用必要的个人信息;\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text class=\"modal-list\">\r\n\t\t\t\t\t\t2、基于您的授权,我们可能会获取您的地理位置、相册、相机等相关软件权限;\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text class=\"modal-list\">\r\n\t\t\t\t\t\t3、我们会采取符合标准的技术措施和数据安全措施来保护您的个人信息安全;\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text class=\"modal-list\">\r\n\t\t\t\t\t\t4、您可以查询,更正,管理您的个人信息,我们也提供账户注销的渠道;\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text class=\"modal-footer\">\r\n\t\t\t\t\t\t如您同意以上协议内容,请点击“同意”开始使用我们的产品和服务,我们依法尽全力保护您的个人信息。\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</scroll-view>\r\n\r\n\t\t\t\t<view class=\"modal-btns row-between\">\r\n\t\t\t\t\t<text class=\"modal-btn reject\" @click=\"rejectAgreement\">\r\n\t\t\t\t\t\t拒绝并退出\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text class=\"modal-btn agree\" @click=\"agreeAgreement\">\r\n\t\t\t\t\t\t同意\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t</view>\r\n\t\t</view>\r\n\t</view>\r\n</template>\r\n\r\n<script setup lang=\"uts\">\r\n\timport { ref, computed } from 'vue';\r\n\r\n\timport { fetchSendcode, fetchLogin } from '@/utils/api/login.uts'\r\n\tconst slogan = ref('');\r\n\tconst privacyName = ref('');\r\n\tconst privacyUrl = ref('');\r\n\tconst mobile = ref('');\r\n\tconst phone = ref<string>('');\r\n\tconst mobileCode = ref<string>('');\r\n\tconst isAgree = ref<boolean>(false);\r\n\tconst showModal = ref<boolean>(false);\r\n\tconst countdown = ref<number>(0);\r\n\tconst uniVerifyManager = ref(null as UniVerifyManager | null);\r\n\tconst isAppEnv = process.env.UNI_PLATFORM === 'app'\r\n\t// 定义定时器变量\r\n\tlet timer : number | null = null;\r\n\r\n\tconst canSend = computed(() => mobile.value.length === 11 && countdown.value === 0);\r\n\tconst canLogin = computed(() => phone.value.length === 11 && mobileCode.value.length === 6 && isAgree.value);\r\n\tconst codeText = computed(() => countdown.value > 0 ? `${countdown.value}s 后重试` : '获取验证码');\r\n\r\n\tconst goBack = () => uni.navigateBack();\r\n\t// const oneKeyNav = () => uni.navigateTo({ url: '/pages/login/login-one-key' });\r\n\tconst wechatLogin = () => uni.showToast({ title: '微信登录开发中', icon: 'none' });\r\n\r\n\tconst sendCode = async () => {\r\n\t\tif (!canSend.value) return;\r\n\t\tconsole.log(mobile.value, 'mobile')\r\n\t\ttry {\r\n\t\t\tconst res = await fetchSendcode({ mobile: mobile.value });\r\n\t\t\tconst currentTimer = timer;\r\n\t\t\tif (currentTimer !== null) {\r\n\t\t\t\tclearInterval(currentTimer);\r\n\t\t\t}\r\n\t\t\ttimer = null;\r\n\r\n\t\t\tcountdown.value = 60;\r\n\t\t\tuni.showToast({ title: '验证码已发送', icon: 'success' });\r\n\r\n\t\t\ttimer = setInterval(() => {\r\n\t\t\t\tcountdown.value--;\r\n\t\t\t\tif (countdown.value <= 0) {\r\n\t\t\t\t\tconst t = timer;\r\n\t\t\t\t\tif (t !== null) {\r\n\t\t\t\t\t\tclearInterval(t);\r\n\t\t\t\t\t}\r\n\t\t\t\t\ttimer = null;\r\n\t\t\t\t\tcountdown.value = 0;\r\n\t\t\t\t}\r\n\t\t\t}, 1000);\r\r\n\t\t} catch (err : any) {\r\n\t\t\tconsole.error('获取客户评价接口异常', err)\r\n\t\t}\r\n\t};\r\n\r\n\tconst onAgreeChange = (e : any) => {\r\n\t\t// UTS 中 any 类型必须 as 成具体类型再访问属性\r\n\t\tconst evt = e as UTSJSONObject;\r\n\t\tconsole.log(evt, 'evt')\r\n\t\tif (evt != null) {\r\n\t\t\tconst detail = evt[\"detail\"] as UTSJSONObject | null;\r\n\t\t\tif (detail != null) {\r\n\t\t\t\tconst value = detail[\"value\"] as boolean | null;\r\n\t\t\t\tisAgree.value = (value != null) && value;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\t\tisAgree.value = false;\r\n\t};\r\n\r\n\tconst doLogin = async () => {\r\n\t\t// if (!canLogin.value) {\r\n\t\t// \tconsole.log(isAgree.value)\r\n\t\t// \tuni.showToast({ title: isAgree.value ? '请填写完整信息' : '请先同意协议', icon: 'none' });\r\n\t\t// \treturn;\r\n\t\t// }\r\n\t\tuni.showLoading({ title: '登录中...' });\r\n\t\tconst res = await fetchLogin({ mobile: mobile.value, code: mobileCode.value });\r\n\t\tconsole.log(res, 'res');\r\n\r\n\t\tconst code = (res as UTSJSONObject)[\"code\"] as number | null;\r\n\t\tconst message = (res as UTSJSONObject)[\"message\"] as string ?? '';\r\n\t\tconst data = (res as UTSJSONObject)[\"data\"] as UTSJSONObject | null;\r\n\r\n\r\n\t\tif (code == 200 && data != null) {\r\n\t\t\tconst token = data[\"token\"] as string | null;\r\n\t\t\tif (token != null && token.length > 0) {\r\n\t\t\t\tuni.setStorageSync('token', token);\r\n\t\t\t\tuni.hideLoading();\r\n\t\t\t\tuni.showToast({ title: '登录成功', icon: 'success' });\r\n\t\t\t\tsetTimeout(() => {\r\n\t\t\t\t\tuni.reLaunch({\r\n\t\t\t\t\t\turl: '/pages/homepage/console'\r\n\t\t\t\t\t});\r\n\t\t\t\t}, 500);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tuni.hideLoading();\r\n\t\t\t// const toastMsg = (message ?? '') as string;\r\n\t\t\tuni.showToast({ title: message, icon: 'none' });\r\n\t\t}\r\n\r\n\t\t// setTimeout(() => {\r\n\t\t// \tuni.hideLoading();\r\n\t\t// \tuni.showToast({ title: '登录成功', icon: 'success' });\r\n\t\t// }, 1500);\r\n\t};\r\n\r\n\tconst rejectAgreement = () => {\r\n\t\tshowModal.value = false;\r\n\t\tuni.showToast({ title: '您拒绝了协议', icon: 'none' });\r\n\t};\r\n\r\n\tconst agreeAgreement = () => {\r\n\t\tshowModal.value = false;\r\n\t\tisAgree.value = true;\r\n\t\tuni.showToast({ title: '已同意协议', icon: 'success' });\r\n\t};\r\n\r\n\t// 解析一键登录错误信息,提取 errorDesc\r\n\tconst getErrorMessage = (err : any) : string => {\r\n\t\tconst str = JSON.stringify(err)\r\n\r\n\t\t// 根据错误码和关键词判断(按优先级排序)\r\n\t\tif (str.includes('410021') || str.includes('数据网络未开启')) {\r\n\t\t\treturn '请开启移动数据网络'\r\n\t\t}\r\n\t\tif (str.includes('-20202') || str.includes('蜂窝网络')) {\r\n\t\t\treturn '请开启蜂窝网络'\r\n\t\t}\r\n\t\tif (str.includes('无SIM卡') || str.includes('SIM卡不存在')) {\r\n\t\t\treturn '请插入SIM卡'\r\n\t\t}\r\n\t\tif (str.includes('超时') || str.includes('timeout')) {\r\n\t\t\treturn '网络连接超时,请稍后重试'\r\n\t\t}\r\n\t\tif (str.includes('30005')) {\r\n\t\t\treturn '预登录失败,请检查网络设置'\r\n\t\t}\r\n\r\n\t\t// 提取具体错误信息作为备选\r\n\t\tlet match = str.match(/\"resultMsg\":\"([^\"]+)\"/)\r\n\t\tif (match == null) {\r\n\t\t\tmatch = str.match(/\"errorDesc\":\"([^\"]+)\"/)\r\n\t\t}\r\n\t\tif (match == null) {\r\n\t\t\tmatch = str.match(/\"errMsg\":\"([^\"]+)\"/)\r\n\t\t}\r\n\r\n\t\tif (match != null && match.length > 1) {\r\n\t\t\tconst msg = match[1]\r\n\t\t\tif (msg != null) {\r\n\t\t\t\treturn msg\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn '登录失败,请检查网络'\r\n\t}\r\n\r\n\tconst preLogin = (callback : (() => void)) => {\r\n\t\tuniVerifyManager.value?.preLogin({\r\n\t\t\tsuccess: (res) => {\r\n\t\t\t\tphone.value = res.number;\r\n\t\t\t\tslogan.value = res.slogan;\r\n\t\t\t\tprivacyName.value = res.privacyName;\r\n\t\t\t\tprivacyUrl.value = res.privacyUrl;\r\n\t\t\t\tcallback();\r\n\t\t\t},\r\n\t\t\tfail: (err) => {\r\n\t\t\t\tconst hasCauseMessage = (err.cause?.cause?.message ?? '').length > 0\r\n\t\t\t\tconsole.log(JSON.parse(err.cause?.cause?.message as string))\r\n\t\t\t\tconst msgObj = JSON.parse(err.cause?.cause?.message as string) as UTSJSONObject\r\n\t\t\t\tif (hasCauseMessage) {\r\n\t\t\t\t\tuni.showModal({\r\n\t\t\t\t\t\ttitle: msgObj.getString('resultMsg'),\r\n\t\t\t\t\t\tcontent: getErrorMessage(err),\r\n\t\t\t\t\t\tshowCancel: false\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\tconst pushCustomPage = () => {\r\n\t\tconst url = '/pages/login/verifyManager?phone=' + phone.value + '&slogan=' + slogan.value + '&name=' + privacyName.value + '&link=' + privacyUrl.value;\r\n\t\tuni.openDialogPage({\r\n\t\t\turl: url,\r\n\t\t\tanimationType: 'slide-in-bottom',\r\n\t\t\tsuccess(res) {\r\n\t\t\t\tconsole.log(\"成功打开自定义登录页面\");\r\n\t\t\t},\r\n\t\t\tfail(err) {\r\n\t\t\t\tconsole.log(err);\r\n\t\t\t}\r\n\t\t})\r\n\t}\r\n\r\n\tconst customLoginIn = () => {\r\n\t\tif ('production' === process.env.NODE_ENV && '__UNI__HelloUniAppX' === uni.getAppBaseInfo().appId) {\r\n\t\t\tuni.showModal({\r\n\t\t\t\ttitle: '提示',\r\n\t\t\t\tcontent: '一键登录为收费功能,当前环境暂不支持。请在HBuilderX中新建Hello uni-app x项目真机运行体验!',\r\n\t\t\t\tshowCancel: false\r\n\t\t\t})\r\n\t\t\treturn\r\n\t\t}\r\n\t\tconst isPreLoginValid = uniVerifyManager.value?.isPreLoginValid() ?? false;\r\n\t\tif (isPreLoginValid) {\r\n\t\t\tpushCustomPage();\r\n\t\t} else {\r\n\t\t\tpreLogin(() => {\r\n\t\t\t\tpushCustomPage();\r\n\t\t\t})\r\n\t\t}\r\n\t}\r\n\r\n\r\n\r\n\tonLoad(() => {\r\n\t\tif (isAppEnv) {\r\n\t\t\tuniVerifyManager.value = uni.getUniVerifyManager();\r\n\r\n\t\t}\r\n\t\t// 预登录\r\n\t\tpreLogin(() => { });\r\n\t})\r\n</script>\r\n\r\n<style>\r\n\t.page-container {\r\n\t\t/* background: linear-gradient(180deg, #e0f7fa 0%, #fff8e1 100%); */\r\n\t\theight: 100%;\r\n\t\tpadding: 40rpx 30rpx;\r\n\t\tbox-sizing: border-box;\r\n\t}\r\n\r\n\t.close-btn {\r\n\t\tposition: absolute;\r\n\t\ttop: 40rpx;\r\n\t\tright: 30rpx;\r\n\t\tz-index: 10;\r\n\t}\r\n\r\n\t.header-section {\r\n\t\talign-items: center;\r\n\t\tmargin-bottom: 60rpx;\r\n\t}\r\n\r\n\t.hello-text {\r\n\t\tfont-size: 48rpx;\r\n\t\tfont-weight: bold;\r\n\t\tcolor: #333;\r\n\t\tmargin-bottom: 10rpx;\r\n\t}\r\n\r\n\t.welcome-text {\r\n\t\tfont-size: 32rpx;\r\n\t\tcolor: #666;\r\n\t\tmargin-bottom: 30rpx;\r\n\t}\r\n\r\n\t.logo-img {\r\n\t\twidth: 300rpx;\r\n\t\theight: 300rpx;\r\n\t\tborder-radius: 150rpx;\r\n\t\tbackground-color: rgba(255, 255, 255, 0.3);\r\n\t}\r\n\r\n\t.form-section {\n\t\tmargin-bottom: 60rpx;\n\t}\n\r\n\t.input-box {\r\n\t\tbackground-color: #ffffff;\r\n\t\tborder-radius: 30rpx;\r\n\t\tpadding: 20rpx 30rpx;\r\n\t\tmargin-bottom: 30rpx;\r\n\t\tbox-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);\r\n\t}\r\n\r\n\t.input-field {\r\n\t\tflex: 1;\r\n\t\tfont-size: 28rpx;\r\n\t\tcolor: #333;\r\n\t}\r\n\r\n\t.code-btn {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #ffc107;\r\n\t\tfont-weight: bold;\r\n\t\twhite-space: nowrap;\r\n\t}\r\n\r\n\t.code-btn.disabled {\r\n\t\tcolor: #ccc;\r\n\t}\r\n\r\n\t.login-btn {\r\n\t\t/* background: linear-gradient(90deg, #ffc107, #ffca2c); */\r\n\t\tcolor: #ffffff;\r\n\t\tfont-size: 32rpx;\r\n\t\tfont-weight: bold;\r\n\t\ttext-align: center;\r\n\t\tpadding: 24rpx 0;\r\n\t\tborder-radius: 30rpx;\r\n\t\tmargin-bottom: 30rpx;\r\n\t\tbox-shadow: 0 4rpx 12rpx rgba(255, 193, 7, 0.3);\r\n\t}\r\n\r\n\t.login-btn.disabled {\r\n\t\tbackground: #ddd;\r\n\t\tcolor: #999;\r\n\t\tbox-shadow: none;\r\n\t}\r\n\r\n\t.agree-row {\r\n\t\talign-items: flex-start;\r\n\t}\r\n\r\n\t.agree-content {\r\n\t\tflex: 1;\r\n\t\tmargin-left: 10rpx;\r\n\t}\r\n\r\n\t.agree-text {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #999;\r\n\t\tline-height: 1.6;\r\n\t}\r\n\r\n\t.link-text {\r\n\t\tcolor: #ffe205;\r\n\t\tborder-bottom: 1rpx solid #ffff7f;\r\n\t}\r\n\r\n\t.footer-section {\r\n\t\tmargin-top: auto;\r\n\t}\r\n\r\n\t.divider-row {\r\n\t\tmargin-bottom: 40rpx;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.line {\r\n\t\tflex: 1;\r\n\t\theight: 1rpx;\r\n\t\tbackground-color: #ddd;\r\n\t}\r\n\r\n\t.divider-text {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #999;\r\n\t\tmargin: 0 20rpx;\r\n\t}\r\n\r\n\t.methods-row {\r\n\t\tjustify-content: center;\r\n\t\tmargin-bottom: 40rpx;\r\n\t}\r\n\r\n\t.method-item {\r\n\t\tmargin-right: 60rpx;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.method-item:last-child {\r\n\t\tmargin-right: 0;\r\n\t}\r\n\r\n\t.icon-box {\n\t\twidth: 80rpx;\n\t\theight: 80rpx;\n\t\tborder-radius: 40rpx;\n\t\tflex-direction: row;\n\t\tjustify-content: center;\n\t\talign-items: center;\n\t\tmargin-bottom: 15rpx;\n\t}\n\n\t.wechat-mark {\n\t\tfont-size: 34rpx;\n\t\tcolor: #ffffff;\n\t\tfont-weight: 700;\n\t}\n\r\n\t/* \t.blue-bg {\r\n\t\tbackground: linear-gradient(135deg, #4a90e2, #67b26f);\r\n\t}\r\n\r\n\t.green-bg {\r\n\t\tbackground: linear-gradient(135deg, #00b894, #00cec9);\r\n\t} */\r\n\r\n\t.method-name {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #666;\r\n\t}\r\n\r\n\t.modal-mask {\r\n\t\tposition: fixed;\r\n\t\ttop: 0;\r\n\t\tleft: 0;\r\n\t\tright: 0;\r\n\t\tbottom: 0;\r\n\t\tbackground-color: rgba(0, 0, 0, 0.5);\r\n\t\tjustify-content: center;\r\n\t\talign-items: center;\r\n\t\tz-index: 100;\r\n\t}\r\n\r\n\t.modal-box {\r\n\t\tbackground-color: #ffffff;\r\n\t\tborder-radius: 20rpx;\r\n\t\tpadding: 40rpx 30rpx;\r\n\t\twidth: 600rpx;\r\n\t\tmax-height: 800rpx;\r\n\t\tflex-direction: column;\r\n\t}\r\n\r\n\t.modal-title {\r\n\t\tfont-size: 36rpx;\r\n\t\tfont-weight: bold;\r\n\t\tcolor: #333;\r\n\t\ttext-align: center;\r\n\t\tmargin-bottom: 20rpx;\r\n\t}\r\n\r\n\t.modal-scroll {\r\n\t\tflex: 1;\r\n\t\tmargin-bottom: 20rpx;\r\n\t}\r\n\r\n\t.modal-welcome {\r\n\t\tfont-size: 28rpx;\r\n\t\tcolor: #333;\r\n\t\tmargin-bottom: 15rpx;\r\n\t}\r\n\r\n\t.modal-desc {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #666;\r\n\t\tline-height: 1.6;\r\n\t\tmargin-bottom: 15rpx;\r\n\t}\r\n\r\n\t.modal-link {\r\n\t\tcolor: #00b894;\r\n\t\tborder-bottom: 1rpx solid #00b894;\r\n\t}\r\n\r\n\t.modal-list {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #666;\r\n\t\tline-height: 1.6;\r\n\t\tmargin-bottom: 10rpx;\r\n\t}\r\n\r\n\t.modal-footer {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #666;\r\n\t\tline-height: 1.6;\r\n\t\tmargin-bottom: 10rpx;\r\n\t}\r\n\r\n\t.modal-btns {\r\n\t\tborder-top: 1rpx solid #eee;\r\n\t\tpadding-top: 20rpx;\r\n\t}\r\n\r\n\t.modal-btn {\r\n\t\tflex: 1;\r\n\t\ttext-align: center;\r\n\t\tfont-size: 28rpx;\r\n\t\tfont-weight: bold;\r\n\t\tpadding: 15rpx 0;\r\n\t}\r\n\r\n\t.modal-btn.reject {\r\n\t\tcolor: #999;\r\n\t\tmargin-right: 20rpx;\r\n\t}\r\n\r\n\t.modal-btn.agree {\r\n\t\tcolor: #00b894;\r\n\t}\r\n\r\n\t.row-between {\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: space-between;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.row-start {\r\n\t\tflex-direction: row;\r\n\t\talign-items: flex-start;\r\n\t}\r\n\r\n\t.row-center {\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: center;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.column-center {\r\n\t\tflex-direction: column;\r\n\t\tjustify-content: center;\r\n\t\talign-items: center;\r\n\t}\r\n</style>\n","<template>\r\n\t<view class=\"page-container\">\r\n\r\n\t\t<!-- 1. 顶部标签栏 (Scroll View) -->\r\n\t\t<scroll-view direction=\"horizontal\" class=\"tab-scroll\" show-scrollbar=\"false\" :enable-flex=\"true\">\r\n\t\t\t<view class=\"tab-wrapper\">\r\n\t\t\t\t<view v-for=\"(tab, index) in tabs\" :key=\"tab?.['index']\" :class=\"['tab-item', currentTab == tab?.['value']\r\n\t\t\t\t\t? 'active' : '' ]\" @click=\"handleTabClick((tab?.['value']) as number)\">\r\n\t\t\t\t\t<text>\r\n\t\t\t\t\t\t{{ tab?.[\"label\"] }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<!-- 激活下的黄色短线 -->\r\n\t\t\t\t\t<view v-if=\"currentTab == tab?.[' value']\" class=\"tab-indicator\">\r\n\t\t\t\t\t</view>\r\n\t\t\t\t</view>\r\n\t\t\t</view>\r\n\t\t</scroll-view>\r\n\r\n\t\t<!-- 2. 订单列表 -->\r\n\t\t<scroll-view style=\"flex:1\" v-if=\"orderList.length > 0\" direction=\"vertical\" @scrolltolower=\"loadMore\">\r\n\t\t\t<view class=\"order-list\">\r\n\t\t\t\t<view v-for=\"(item, index) in orderList\" :key=\"item.id\" class=\"order-card\">\r\n\r\n\t\t\t\t\t<!-- Card Header: 时间 & 状态 -->\r\n\t\t\t\t\t<view class=\"card-header\">\r\n\t\t\t\t\t\t<text class=\"time-text\">\r\n\t\t\t\t\t\t\t预约时间:{{ item.service_time }}\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t<text class=\"status-badge paid\">\r\n\t\t\t\t\t\t\t{{ item.state_text }}\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t<!-- Card Body: 服务信息 (左图右文) -->\r\n\t\t\t\t\t<view class=\"service-section\" @click=\"orderDetail(item.id as number)\">\r\n\t\t\t\t\t\t<image\r\n\t\t\t\t\t\t\t:src=\"(((((item.project as UTSJSONObject).cover_urls ) as UTSArray<UTSJSONObject>)[0]) as UTSJSONObject).medium_url\"\r\n\t\t\t\t\t\t\tclass=\" service-image\" mode=\"aspectFill\" />\r\n\t\t\t\t\t\t<view class=\"service-details\">\r\n\t\t\t\t\t\t\t<view class=\"service-title-row\">\r\n\t\t\t\t\t\t\t\t<text class=\"service-name\">\r\n\t\t\t\t\t\t\t\t\t{{ (item.project as UTSJSONObject)?.title }}\r\n\t\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t\t<view class=\"contact-info-row\">\r\n\t\t\t\t\t\t\t\t<text class=\"contact-info\">\r\n\t\t\t\t\t\t\t\t\t联系人:{{ item.user_nickname }}\r\n\t\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t\t<text class=\"tag-pill green\" v-if=\"item.source === 1\">\r\n\t\t\t\t\t\t\t\t\t新客\r\n\t\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t<text class=\"service-price\">\r\n\t\t\t\t\t\t\t¥{{ item.project_amount }}\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t\t<!-- Card Address: 地址 & 距离 -->\r\n\t\t\t\t\t<view class=\"address-section\">\r\n\t\t\t\t\t\t<u-icon name=\"location\" :size=\"18\" />\r\n\t\t\t\t\t\t<text class=\"address-content\">\r\n\t\t\t\t\t\t\t{{( item.address as UTSJSONObject)?.[\"address\"] }}\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t<text class=\"distance-text\">\r\n\t\t\t\t\t\t\t{{ item.distance }}km\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t<!-- Card Income: 预估收入 -->\r\n\t\t\t\t\t<view class=\"income-section\">\r\n\t\t\t\t\t\t<text class=\"income-label\">\r\n\t\t\t\t\t\t\t预估收入\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t<view class=\"income-value-group\">\r\n\t\t\t\t\t\t\t<text class=\"income-main\">\r\n\t\t\t\t\t\t\t\t¥{{ item.commission_amount }}\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t<text class=\"income-sub\">\r\n\t\t\t\t\t\t\t\t(含路费)\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t<!-- Card Actions: 按钮组 -->\r\n\t\t\t\t\t<view class=\"action-section\" v-if=\"currentTab==1\">\r\n\t\t\t\t\t\t<view class=\"btn btn-nav\"\r\n\t\t\t\t\t\t\t@click.stop=\"onNavigate((item.address as UTSJSONObject)?.address as String) \">\r\n\t\t\t\t\t\t\t<u-icon name=\"navigation\" :size=\"18\" />\r\n\t\t\t\t\t\t\t<text style=\"font-size:28rpx\">\r\n\t\t\t\t\t\t\t\t地址导航\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t<view style=\"flex-direction:row\">\r\n\t\t\t\t\t\t\t<button class=\"btn btn-transfer\" @click=\"onTransfer(item.id as number)\">\r\n\t\t\t\t\t\t\t\t我要转单\r\n\t\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t\t<button class=\"btn btn-confirm\" @click=\"onConfirm(item.id as number)\">\r\n\t\t\t\t\t\t\t\t确认接单\r\n\t\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t\t<view class=\"action-section\" v-else=\"currentTab==2\">\r\n\t\t\t\t\t\t<view class=\"btn btn-nav\"\r\n\t\t\t\t\t\t\t@click.stop=\"onNavigate((item.address as UTSJSONObject)?.address as String) \">\r\n\t\t\t\t\t\t\t<u-icon name=\"navigation\" :size=\"18\" />\r\n\t\t\t\t\t\t\t<text style=\"font-size:28rpx\">\r\n\t\t\t\t\t\t\t\t地址导航\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t<view style=\"flex-direction:row\">\r\n\t\t\t\t\t\t\t<button class=\"btn btn-transfer\" @click=\"onTransfer(item.id as number)\">\r\n\t\t\t\t\t\t\t\t我要转单\r\n\t\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t\t<button class=\"btn btn-confirm\" @click=\"onConfirm(item.id as number)\">\r\n\t\t\t\t\t\t\t\t确认接单\r\n\t\t\t\t\t\t\t</button>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t</view>\r\n\r\n\t\t\t</view>\r\n\r\n\t\t\t<!-- 加载状态 -->\r\n\t\t\t<view v-if=\"loading\" class=\"loading\">\r\n\t\t\t\t<loading style=\"border-width: 6rpx; border-color:#FFDA59\" />\r\n\t\t\t</view>\r\n\t\t\t<view v-if=\"!hasMore && orderList.length > 0\" class=\"no-more\">\r\n\t\t\t\t<text style=\"font-size: 28rpx;\r\n\t\t\t\tcolor: #999999;\r\n\t\t\t\ttext-align: center;\">\r\n\t\t\t\t\t没有更多数据了...\r\n\t\t\t\t</text>\r\n\t\t\t</view>\r\n\r\n\r\n\t\t</scroll-view>\r\n\t\t<!-- 空状态 -->\r\n\t\t<view v-else class=\"ss-flex-2\" style=\"align-items: center;margin-top: 200rpx;\">\r\n\r\n\t\t\t<image src=\"/static/other/order-k.png\" class=\"wh\">\r\n\t\t\t</image>\r\n\t\t\t<text style=\"font-size: 30rpx;color: #999999;letter-spacing: 2rpx;text-align: center;font-weight: 600;\">\r\n\t\t\t\t暂无订单</text>\r\n\r\n\t\t</view>\r\n\t</view>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n\timport { ref } from 'vue';\r\n\timport { getOrderList, transferOrder, acceptOrder } from '@/utils/api/order';\r\n\r\n\t// --- 数据 ---\r\n\tconst tabs = ref([\r\n\t\t{\r\n\t\t\tlabel: '新订单',\r\n\t\t\tvalue: 1\r\n\t\t},\r\n\t\t{\r\n\t\t\tlabel: '进行中',\r\n\t\t\tvalue: 2\r\n\t\t},\r\n\t\t{\r\n\t\t\tlabel: '取消/售后',\r\n\t\t\tvalue: 5\r\n\t\t},\r\n\t\t{\r\n\t\t\tlabel: '已完成',\r\n\t\t\tvalue: 3\r\n\t\t},\r\n\t\t{\r\n\t\t\tlabel: '全部',\r\n\t\t\tvalue: 0\r\n\t\t},\r\n\t])\r\n\tconst currentTab = ref(1);\r\n\r\n\ttype OrderTag = {\r\n\t\ttext : string;\r\n\t\ttype : 'orange' | 'green' | 'red';\r\n\t}\r\n\r\n\r\n\r\n\tconst orderList = ref<UTSJSONObject[]>([]);\r\n\tconst pageNo = ref(1);\r\n\tconst pageSize = ref(5);\r\n\tconst hasMore = ref(true);\r\n\tconst loading = ref(false);\r\n\r\n\t// --- 方法 ---\r\n\r\n\t// helper used in template to give v-for a typed array source\r\n\t// function tagList(order : OrderItem) : OrderTag[] {\r\n\t// \treturn order.tags;\r\n\t// }\r\n\r\n\t//计算预估收入\r\n\tconst estimateManey = (item) => {\r\n\t\t// 技师等级和星级\r\n\t\tconst coach_level = Number(coachInfo.value?.coach_level) ?? 1; // 加钟等级\r\n\t\tconst star_level = Number(coachInfo.value?.star_level) ?? 3; // 星星等级\r\n\t\tlet project_amount = (Number(item?.project_amount) ?? 0) * (item?.num - 0 ?? 1); // 项目金额\r\n\t\tconst traffic_amount = Number(item?.traffic_amount) ?? 0; // 路费\r\n\t\t// 星级系数表(1-5星)\r\n\t\tconst starArr = [0,\r\n\t\t\t0.45,\r\n\t\t\t0.48,\r\n\t\t\t0.5,\r\n\t\t\t0.55,\r\n\t\t\t0.58];\r\n\r\n\t\tlet maneyInfo = 0;\r\n\t\t//是否是vip订单\r\n\t\tconst isVip = item.user?.member_type && item.user?.member_type - 0 > 0 ? true : false;\r\n\t\tif (!isVip) {\r\n\t\t\tif (item.click_farming) {\r\n\t\t\t\t// 刷单\r\n\t\t\t\tmaneyInfo = project_amount * 0.7;\r\n\t\t\t} else if (item?.type === 1) {\r\n\t\t\t\t// 首钟\r\n\t\t\t\tconst starRate = starArr[star_level] ?? 0.5;\r\n\t\t\t\tmaneyInfo = project_amount * starRate + traffic_amount;\r\n\t\t\t} else if (item?.type === 3) {\r\n\t\t\t\t// 加钟\r\n\t\t\t\tmaneyInfo = project_amount * (0.5 + coach_level / 10);\r\n\t\t\t} else {\r\n\t\t\t\tmaneyInfo = 0;\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tif (item.click_farming) {\r\n\t\t\t\t// 刷单\r\n\t\t\t\tmaneyInfo = project_amount * 0.5;\r\n\t\t\t} else if (item?.type === 1) {\r\n\t\t\t\t// 首钟\r\n\t\t\t\tmaneyInfo = project_amount * 0.5 + traffic_amount;\r\n\t\t\t} else if (item?.type === 3) {\r\n\t\t\t\t// 加钟\r\n\t\t\t\tmaneyInfo = project_amount * 0.7;\r\n\t\t\t} else {\r\n\t\t\t\tmaneyInfo = 0;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// 保留两位小数\r\n\t\treturn maneyInfo.toFixed(2);\r\n\t};\r\n\r\n\r\n\t// 加载订单列表\r\n\tconst httpGetOrderList = async (isLoadMore : boolean) => {\r\n\t\tif (!hasMore.value || loading.value) return;\r\n\r\n\t\tloading.value = true;\r\n\t\ttry {\r\n\t\t\tconst response = await getOrderList({\r\n\t\t\t\ttype: currentTab.value,\r\n\t\t\t\tpage: pageNo.value,\r\n\t\t\t\tper_page: pageSize.value\r\n\t\t\t}) as UTSJSONObject;\r\n\t\t\tconst code = response[\"code\"] as number;\r\n\t\t\tif (code !== 200) return;\r\n\r\n\t\t\tconst items = (response.data as UTSJSONObject)[\"items\"] as UTSArray<UTSJSONObject>;\r\n\t\t\tif (isLoadMore) {\r\n\t\t\t\torderList.value.push(...items);\r\n\t\t\t} else {\r\n\t\t\t\torderList.value = items;\r\n\t\t\t}\r\n\r\n\t\t\t// 判断是否还有更多数据\r\n\t\t\tif (items.length < pageSize.value) {\r\n\t\t\t\thasMore.value = false;\r\n\t\t\t} else {\r\n\t\t\t\tpageNo.value++;\r\n\t\t\t}\r\n\t\t} catch (err : any) {\r\n\t\t\tconsole.error('获取订单列表接口异常', err);\r\n\t\t} finally {\r\n\t\t\tloading.value = false;\r\n\t\t}\r\n\t};\r\n\t// 处理tab点击事件\r\n\tconst handleTabClick = (index : number) => {\r\n\t\tcurrentTab.value = index;\r\n\t\t// 切换标签时重置分页状态\r\n\t\tpageNo.value = 1;\r\n\t\thasMore.value = true;\r\n\t\torderList.value = [];\r\n\t\thttpGetOrderList(false);\r\n\t};\r\n\t// 滚动到底部加载更多\r\n\tconst loadMore = () => {\r\n\t\thttpGetOrderList(true);\r\n\t};\r\n\r\n\t// 客户接单接口\r\n\tconst onConfirmOrder = async (orderId : number) => {\r\n\t\t// uni.showLoading({ title: '处理中...' });\r\n\t\ttry {\r\n\r\n\t\t\tconst res = await acceptOrder({\r\n\t\t\t\torder_id: orderId\r\n\t\t\t}) as UTSJSONObject;\r\n\t\t\t// const code = response[\"code\"] as number\r\n\t\t\tuni.hideLoading();\r\n\t\t\tif (res?.code === 200) {\r\n\t\t\t\tuni.showToast({ title: '接单成功', icon: 'success' });\r\n\t\t\t\t// 可选: 自动刷新订单列表或做其他操作\r\n\t\t\t\tawait httpGetOrderList(false);\r\n\t\t\t} else {\r\n\t\t\t\tuni.showToast({\r\n\t\t\t\t\ttitle: (res?.msg) as String ?? '接单失败',\r\n\t\t\t\t\ticon: 'none'\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t} catch (err) {\r\n\t\t\tuni.hideLoading();\r\n\t\t\tconsole.error('接单异常', err);\r\n\t\t\tuni.showToast({\r\n\t\t\t\ttitle: '接单失败,请重试',\r\n\t\t\t\ticon: 'none'\r\n\t\t\t});\r\n\t\t}\r\n\t};\r\n\tconst onConfirm = (orderId : number) => {\r\n\t\tuni.showModal({\r\n\t\t\ttitle: '接单确认',\r\n\t\t\tcontent: '确定要接受该订单吗?',\r\n\t\t\tsuccess: (res) => { onConfirmOrder(orderId) }\r\n\t\t});\r\n\t};\r\n\t// 商户转单\r\n\tconst httptransferOrder = async (orderId : number,) => {\r\n\t\ttry {\r\n\t\t\tconst res = await transferOrder({\r\n\t\t\t\torder_id: orderId,\r\n\t\t\t}) as UTSJSONObject;\r\n\t\t\tif (res?.code === 200) {\r\n\t\t\t\tuni.showToast({ title: '转单成功', icon: 'success' });\r\n\t\t\t\tawait httpGetOrderList(false);\r\n\t\t\t} else {\r\n\t\t\t\tuni.showToast({\r\n\t\t\t\t\ttitle: (res?.msg) as String ?? '转单失败',\r\n\t\t\t\t\ticon: 'none'\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t} catch (err) {\r\n\t\t\tconsole.error('转单异常', err);\r\n\t\t\tuni.showToast({\r\n\t\t\t\ttitle: '转单失败,请重试',\r\n\t\t\t\ticon: 'none'\r\n\t\t\t});\r\n\t\t}\r\n\t};\r\n\tconst onTransfer = (id : number) => {\r\n\t\tuni.showModal({\r\n\t\t\ttitle: '转单确认',\r\n\t\t\tcontent: '确定将此订单转给其他技师吗?',\r\n\t\t\tsuccess: (res) => {\r\n\t\t\t\thttptransferOrder(id);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t};\r\n\tconst orderDetail = (orderId : number) => {\r\n\t\tuni.navigateTo({\r\n\t\t\turl: `/pages/order/orderDetail?orderId=${orderId}`\r\n\t\t});\r\n\t};\r\n\tconst onNavigate = (addr : string) => {\r\n\t\tuni.showToast({ title: '启动导航', icon: 'none' });\r\n\t\tuni.navigateTo({\r\n\t\t\turl: '/pages/map/map'\r\n\t\t});\r\n\t};\r\n\r\n\tonLoad(() => {\r\n\t\t// httpGetOrderList();\r\n\t})\r\n\tonReady(() => {\r\n\t\thttpGetOrderList(false);\r\n\t})\r\n</script>\r\n\r\n<style scoped>\r\n\t.page-container {\r\n\t\tbackground-color: #f5f6f8;\r\n\t\tbox-sizing: border-box;\r\n\t\theight: 100%;\r\n\t}\r\n\r\n\t.tab-scroll {\r\n\t\tbackground-color: #ffffff;\r\n\t\theight: 88rpx;\r\n\t\twidth: 100%;\r\n\t}\r\n\r\n\t.tab-wrapper {\r\n\t\tflex-direction: row;\r\n\t\talign-items: center;\r\n\t\theight: 88rpx;\r\n\t\tpadding: 0 20rpx;\r\n\t}\r\n\r\n\t.tab-item {\r\n\t\tposition: relative;\r\n\t\tpadding: 0 30rpx;\r\n\t\theight: 88rpx;\r\n\t\talign-items: center;\r\n\t\tjustify-content: center;\r\n\t\tfont-size: 30rpx;\r\n\t\tcolor: #666666;\r\n\t\tflex-shrink: 0\r\n\t}\r\n\r\n\t.tab-item.active {\r\n\t\tcolor: #333333;\r\n\t\tfont-weight: bold;\r\n\t}\r\n\r\n\t.tab-indicator {\r\n\t\tposition: absolute;\r\n\t\tbottom: 16rpx;\r\n\t\tleft: 0;\r\n\t\tright: 0;\r\n\t\tmargin: 0 auto;\r\n\t\twidth: 40rpx;\r\n\t\theight: 6rpx;\r\n\t\tbackground-color: #ffc107;\r\n\t\tborder-radius: 3rpx;\r\n\t}\r\n\r\n\t.order-list {\r\n\t\tpadding: 20rpx;\r\n\t}\r\n\r\n\t.order-card {\r\n\t\tbackground-color: #ffffff;\r\n\t\tborder-radius: 16rpx;\r\n\t\tpadding: 30rpx;\r\n\t\tmargin-bottom: 20rpx;\r\n\t}\r\n\r\n\t.card-header {\r\n\t\tjustify-content: space-between;\r\n\t\talign-items: center;\r\n\t\tflex-direction: row;\r\n\t}\r\n\r\n\t.time-text {\r\n\t\tfont-size: 28rpx;\r\n\t\tcolor: #333333;\r\n\t\tfont-weight: 400;\r\n\t}\r\n\r\n\t.status-badge {\r\n\t\tfont-size: 24rpx;\r\n\t\tpadding: 6rpx 16rpx;\r\n\t\tborder-radius: 20rpx;\r\n\t}\r\n\r\n\t.status-badge.paid {\r\n\t\tbackground-color: #fff7e6;\r\n\t\tcolor: #ff9900;\r\n\t}\r\n\r\n\t.service-section {\r\n\t\tflex-direction: row;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.service-image {\r\n\t\twidth: 110rpx;\r\n\t\theight: 110rpx;\r\n\t\tborder-radius: 12rpx;\r\n\t\tbackground-color: #f0f0f0;\r\n\t\tflex-shrink: 0;\r\n\t}\r\n\r\n\t.service-details {\r\n\t\tflex: 1;\r\n\t\tjustify-content: space-between;\r\n\t}\r\n\r\n\t.service-title-row {\r\n\t\tflex-direction: row;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.service-name {\r\n\t\tfont-size: 32rpx;\r\n\t\tfont-weight: bold;\r\n\t\tcolor: #333333;\r\n\t}\r\n\r\n\t.service-price {\r\n\t\tfont-size: 34rpx;\r\n\t\tfont-weight: bold;\r\n\t\tcolor: #333333;\r\n\t}\r\n\r\n\t.tags-container {\r\n\t\tflex-direction: row;\r\n\t\tflex-wrap: wrap;\r\n\t}\r\n\r\n\t.tag-pill {\r\n\t\tfont-size: 22rpx;\r\n\t\tpadding: 4rpx 12rpx;\r\n\t\tborder-radius: 20rpx;\r\n\t\tborder-width: 1rpx;\r\n\t\tborder-style: solid;\r\n\t\tline-height: 1.2;\r\n\t\tmargin-right: 10rpx;\r\n\t}\r\n\r\n\t.tag-pill.orange {\r\n\t\tcolor: #ff9900;\r\n\t\tborder-color: #ff9900;\r\n\t\tbackground-color: #fffaf0;\r\n\t}\r\n\r\n\t.tag-pill.green {\r\n\t\tcolor: #52c41a;\r\n\t\tborder-color: #52c41a;\r\n\t\tbackground-color: #f6ffed;\r\n\t}\r\n\r\n\t.tag-pill.red {\r\n\t\tcolor: #ff4d4f;\r\n\t\tborder-color: #ff4d4f;\r\n\t\tbackground-color: #fff1f0;\r\n\t}\r\n\r\n\t.contact-info-row {\r\n\t\tflex-direction: row;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.contact-info {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #999999;\r\n\t\tmargin-left: 10rpx;\r\n\t}\r\n\r\n\t.address-section {\r\n\t\tflex-direction: row;\r\n\t\talign-items: flex-start;\r\n\t\tpadding-bottom: 20rpx;\r\n\t\tborder-bottom-width: 1rpx;\r\n\t\tborder-bottom-color: #f5f5f5;\r\n\t\tborder-bottom-style: solid;\r\n\t}\r\n\r\n\t.address-content {\r\n\t\tflex: 1;\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #666666;\r\n\t\tline-height: 1.4;\r\n\t}\r\n\r\n\t.distance-text {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #999999;\r\n\t\twhite-space: nowrap;\r\n\t\tmargin-left: 10rpx;\r\n\t}\r\n\r\n\t.income-section {\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: space-between;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.income-label {\r\n\t\tfont-size: 28rpx;\r\n\t\tcolor: #666666;\r\n\t}\r\n\r\n\t.income-value-group {\r\n\t\tflex-direction: row;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.income-main {\r\n\t\tfont-size: 36rpx;\r\n\t\tfont-weight: bold;\r\n\t\tcolor: #ff4d4f;\r\n\t}\r\n\r\n\t.income-sub {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #999999;\r\n\t}\r\n\r\n\t.action-section {\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: space-between;\r\n\t}\r\n\r\n\t.btn {\r\n\t\theight: 72rpx;\r\n\t\tborder-radius: 36rpx;\r\n\t\twidth: 170rpx;\r\n\t\tpadding: 0 10rpx;\r\n\t}\r\n\r\n\t.btn-nav {\r\n\t\tbackground-color: #FFFBEF;\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: center;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.btn-transfer {\r\n\t\tbackground-color: #ffffff;\r\n\t\tcolor: #ff9900;\r\n\t\tfont-size: 28rpx;\r\n\t}\r\n\r\n\t.btn-confirm {\r\n\t\tbackground-color: #ffc107;\r\n\t\tcolor: #333333;\r\n\t\tfont-size: 28rpx;\r\n\t\tmargin-left: 20rpx\r\n\t}\r\n\r\n\t.loading {\r\n\t\ttext-align: center;\r\n\t\tjustify-content: center;\r\n\t\talign-items: center;\r\n\t}\r\n</style>","import { initRuntimeSocket } from './socket'\n\nexport function initRuntimeSocketService(): Promise<boolean> {\n const hosts: string = process.env.UNI_SOCKET_HOSTS\n const port: string = process.env.UNI_SOCKET_PORT\n const id: string = process.env.UNI_SOCKET_ID\n if (hosts == '' || port == '' || id == '') return Promise.resolve(false)\n let socketTask: SocketTask | null = null\n return Promise.resolve()\n .then((): Promise<boolean> => {\n return initRuntimeSocket(hosts, port, id).then((socket): boolean => {\n if (socket == null) {\n return false\n }\n socketTask = socket\n return true\n })\n })\n .catch((): boolean => {\n return false\n })\n}\n\ninitRuntimeSocketService()\n","import 'E:/tool/HBuilderX.5.02.2026030616-alpha/HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/uni-console/src/runtime/app/index.ts';import App from './App.uvue'\r\nimport { createSSRApp } from 'vue'\r\nexport function createApp() {\r\n\tconst app = createSSRApp(App)\r\n\treturn {\r\n\t\tapp\r\n\t}\r\n}\nexport function main(app: IApp) {\n definePageRoutes();\n defineAppConfig();\n (createApp()['app'] as VueApp).mount(app, GenUniApp());\n}\n\nexport class UniAppConfig extends io.dcloud.uniapp.appframe.AppConfig {\n override name: string = \"小丁到家\"\n override appid: string = \"__UNI__9F955ED\"\n override versionName: string = \"1.0.0\"\n override versionCode: string = \"100\"\n override uniCompilerVersion: string = \"5.04\"\n \n constructor() { super() }\n}\n\nimport GenPagesHomepageConsoleClass from './pages/homepage/console.uvue'\nimport GenPagesMyEditMyClass from './pages/myEdit/my.uvue'\nimport GenPagesOrderOrderClass from './pages/order/order.uvue'\nimport GenPagesAccountAccountClass from './pages/account/account.uvue'\nimport GenPagesHomepageSetOrderTimeClass from './pages/homepage/setOrderTime.uvue'\nimport GenPagesLoginLoginClass from './pages/login/login.uvue'\nimport GenPagesHomepageServiceProjectClass from './pages/homepage/serviceProject.uvue'\nimport GenPagesMyEditMyEditClass from './pages/myEdit/myEdit.uvue'\nimport GenPagesLoginVerifyManagerClass from './pages/login/verifyManager.uvue'\nimport GenPagesLoginFullWebviewPageClass from './pages/login/full-webview-page.uvue'\nimport GenPagesLoginMerchantRecuitmentClass from './pages/login/merchantRecuitment.uvue'\nimport GenPagesMyEditSettingClass from './pages/myEdit/setting.uvue'\nimport GenPagesOrderOrderStatisicsClass from './pages/order/orderStatisics.uvue'\nimport GenPagesOrderAppraiseClass from './pages/order/appraise.uvue'\nimport GenPagesLoginCheckMiddleClass from './pages/login/checkMiddle.uvue'\nimport GenPagesOrderOrderDetailClass from './pages/order/orderDetail.uvue'\nimport GenPagesAccountAccountListClass from './pages/account/accountList.uvue'\nimport GenPagesMapMapClass from './pages/map/map.uvue'\nimport GenPagesMyEditTerminateClass from './pages/myEdit/terminate.uvue'\nimport GenPagesMyEditLogoutClass from './pages/myEdit/logout.uvue'\nimport GenPagesMyEditChangePhoneClass from './pages/myEdit/changePhone.uvue'\nimport GenPagesMyEditSignClass from './pages/myEdit/sign.uvue'\nfunction definePageRoutes() {\n__uniRoutes.push({ path: \"pages/homepage/console\", component: GenPagesHomepageConsoleClass, meta: { isQuit: true } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"控制台\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/myEdit/my\", component: GenPagesMyEditMyClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"我的\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/order/order\", component: GenPagesOrderOrderClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"订单\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/account/account\", component: GenPagesAccountAccountClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"账户\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/homepage/setOrderTime\", component: GenPagesHomepageSetOrderTimeClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"接单时间\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/login/login\", component: GenPagesLoginLoginClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/homepage/serviceProject\", component: GenPagesHomepageServiceProjectClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"服务项目\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/myEdit/myEdit\", component: GenPagesMyEditMyEditClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"个人信息\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/login/verifyManager\", component: GenPagesLoginVerifyManagerClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/login/full-webview-page\", component: GenPagesLoginFullWebviewPageClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/login/merchantRecuitment\", component: GenPagesLoginMerchantRecuitmentClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"商户招募\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/myEdit/setting\", component: GenPagesMyEditSettingClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"设置\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/order/orderStatisics\", component: GenPagesOrderOrderStatisicsClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"数据统计\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/order/appraise\", component: GenPagesOrderAppraiseClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"客户评价\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/login/checkMiddle\", component: GenPagesLoginCheckMiddleClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"商户招募\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/order/orderDetail\", component: GenPagesOrderOrderDetailClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"查看订单\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/account/accountList\", component: GenPagesAccountAccountListClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"全部账单\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/map/map\", component: GenPagesMapMapClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/myEdit/terminate\", component: GenPagesMyEditTerminateClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"解约\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/myEdit/logout\", component: GenPagesMyEditLogoutClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"退出登录\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/myEdit/changePhone\", component: GenPagesMyEditChangePhoneClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"修改手机号\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/myEdit/sign\", component: GenPagesMyEditSignClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"签约\"]]) } as UniPageRoute)\n}\nconst __uniTabBar: Map<string, any | null> | null = _uM([[\"selectedColor\",\"#000000\"],[\"backgroundColor\",\"#ffffff\"],[\"list\",[_uM([[\"pagePath\",\"pages/homepage/console\"],[\"iconPath\",\"static/iconInfo/noactive/homepage.png\"],[\"selectedIconPath\",\"static/iconInfo/active/homepage.png\"],[\"text\",\"控制台\"]]),_uM([[\"pagePath\",\"pages/order/order\"],[\"iconPath\",\"static/iconInfo/noactive/order.png\"],[\"selectedIconPath\",\"static/iconInfo/active/order.png\"],[\"text\",\"订单\"]]),_uM([[\"pagePath\",\"pages/account/account\"],[\"iconPath\",\"static/iconInfo/noactive/account.png\"],[\"selectedIconPath\",\"static/iconInfo/active/account.png\"],[\"text\",\"账户\"]]),_uM([[\"pagePath\",\"pages/myEdit/my\"],[\"iconPath\",\"static/iconInfo/noactive/myhome.png\"],[\"selectedIconPath\",\"static/iconInfo/active/myhome.png\"],[\"text\",\"我的\"]])]]])\nconst __uniLaunchPage: Map<string, any | null> = _uM([[\"url\",\"pages/homepage/console\"],[\"style\",_uM([[\"navigationBarTitleText\",\"控制台\"]])]])\nfunction defineAppConfig(){\n __uniConfig.entryPagePath = '/pages/homepage/console'\n __uniConfig.globalStyle = _uM([[\"navigationBarTextStyle\",\"black\"],[\"navigationBarTitleText\",\"小丁到家--上门按摩\"],[\"navigationBarBackgroundColor\",\"#F8F8F8\"],[\"backgroundColor\",\"#F8F8F8\"]])\n __uniConfig.getTabBarConfig = ():Map<string, any> | null => _uM([[\"selectedColor\",\"#000000\"],[\"backgroundColor\",\"#ffffff\"],[\"list\",[_uM([[\"pagePath\",\"pages/homepage/console\"],[\"iconPath\",\"static/iconInfo/noactive/homepage.png\"],[\"selectedIconPath\",\"static/iconInfo/active/homepage.png\"],[\"text\",\"控制台\"]]),_uM([[\"pagePath\",\"pages/order/order\"],[\"iconPath\",\"static/iconInfo/noactive/order.png\"],[\"selectedIconPath\",\"static/iconInfo/active/order.png\"],[\"text\",\"订单\"]]),_uM([[\"pagePath\",\"pages/account/account\"],[\"iconPath\",\"static/iconInfo/noactive/account.png\"],[\"selectedIconPath\",\"static/iconInfo/active/account.png\"],[\"text\",\"账户\"]]),_uM([[\"pagePath\",\"pages/myEdit/my\"],[\"iconPath\",\"static/iconInfo/noactive/myhome.png\"],[\"selectedIconPath\",\"static/iconInfo/active/myhome.png\"],[\"text\",\"我的\"]])]]])\n __uniConfig.tabBar = __uniConfig.getTabBarConfig()\n __uniConfig.conditionUrl = ''\n __uniConfig.uniIdRouter = _uM()\n \n __uniConfig.ready = true\n}\n","<template>\r\n\t<view class=\"floating-button\" :style=\"{ top: top + 'px', left: left + 'px' }\" @touchstart=\"onTouchStart\"\r\n\t\t@touchmove=\"onTouchMove\" @touchend=\"onTouchEnd\">\r\n\t\t<text class=\"textIcon icon-jingwuicon_svg-\" style=\"font-size: 60rpx;color: #FF4D4D;\"></text>\r\n\t</view>\r\n</template>\r\n\r\n<script lang=\"uts\">\r\n\ttype TouchItem = {\r\n\t\tclientX : number\r\n\t\tclientY : number\r\n\t}\r\n\ttype TouchEvent = {\r\n\t\ttouches : Array<TouchItem>\r\n\t}\r\n\texport default {\r\n\t\tname: 'FloatingButton',\r\n\t\tdata() {\r\n\t\t\treturn {\r\n\t\t\t\ttop: 430,\r\n\t\t\t\tleft: 20,\r\n\t\t\t\tstartX: 0,\r\n\t\t\t\tstartY: 0,\r\n\t\t\t\tdragging: false\r\n\t\t\t};\r\n\t\t},\r\n\t\tmethods: {\r\n\t\t\tonTouchStart(event : TouchEvent) {\r\n\t\t\t\tthis.startX = event.touches[0].clientX\r\n\t\t\t\tthis.startY = event.touches[0].clientY\r\n\t\t\t\tthis.dragging = true\r\n\t\t\t},\r\n\t\t\tonTouchMove(event : TouchEvent) {\r\n\t\t\t\tif (this.dragging) {\r\n\t\t\t\t\tconst deltaX = event.touches[0].clientX - this.startX\r\n\t\t\t\t\tconst deltaY = event.touches[0].clientY - this.startY\r\n\t\t\t\t\tthis.startX = event.touches[0].clientX\r\n\t\t\t\t\tthis.startY = event.touches[0].clientY\r\n\t\t\t\t\tthis.top += deltaY\r\n\t\t\t\t\tthis.left += deltaX\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tonTouchEnd() {\r\n\t\t\t\tthis.dragging = false\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n</script>\r\n\r\n<style scoped>\r\n\t.floating-button {\r\n\t\tposition: fixed;\r\n\t\tz-index: 9999;\r\n\t\tbackground-color: #fff;\r\n\t\tpadding: 20rpx; /* converted from 10px */\r\n\t\t/* use explicit half of width to create perfect circle in rpx */\r\n\t\tborder-radius: 35rpx;\r\n\t\twidth: 70rpx;\r\n\t\theight: 70rpx;\r\n\t\tdisplay: flex;\r\n\t\tjustify-content: center;\r\n\t\talign-items: center;\r\n\t\tbox-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.3);\r\n\t}\r\n</style>","export default \"/static/imagesInfo/bg-color.png\";\n//# sourceMappingURL=bg-color.png.uts.map","export default \"/static/imagesInfo/bg-color.png\"","export default \"/static/imagesInfo/bg-icon.png\";\n//# sourceMappingURL=bg-icon.png.uts.map","export default \"/static/imagesInfo/bg-icon.png\"","import { request } from '../request.uts'\r\n// 基础 URL 配置\r\n\r\nconst BASE_URL = 'https://dev.xiaodingyun.cn'\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n// 获取技师详情信息\r\nexport function getCoachDetaile() : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/client/v3/user/checkCoachReview`,\r\n\t\tmethod: \"GET\"\r\n\t})\r\n}\r\n\r\n// 申请成为技师base-info\r\nexport function fetchBaseInfo(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/client/v3/coach/account/base-info`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata: data\r\n\t})\r\n}\r\n\r\n/**\r\n * 提交实名认证信息\r\n * @param {Object} data - 实名认证信息\r\n * @param {string} data.name - 真实姓名\r\n * @param {string} data.idCard - 身份证号码\r\n * @param {string} data.idCardFrontUrl - 身份证正面照片URL\r\n * @param {string} data.idCardBackUrl - 身份证背面照片URL\r\n * @returns {Promise<any>} 提交结果\r\n */\r\nexport function submitRealName(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/account/real-name`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata: data\r\n\t})\r\n}\r\n\r\n// 修改商户基本信息\r\nexport function editRealName(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/account/update-basic-info`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata: data\r\n\t})\r\n}\r\n\r\n\r\n/**\r\n * 提交技师资质认证信息\r\n * @param {Object} data - 资质认证信息\r\n * @param {string} data.certificateUrl - 资格证书照片URL\r\n * @param {string} data.certificateNo - 资格证书编号\r\n * @param {string} data.mobile - 手机号\r\n * @returns {Promise<any>} 提交结果\r\n */\r\nexport function submitQualification(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/account/qualification`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata: data\r\n\t})\r\n}\r\n\r\n// 获取标签列表\r\nexport function getCoachFlagList() : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/account/coach-tag`,\r\n\t\tmethod: \"GET\"\r\n\t})\r\n}\r\n\r\n// 更新接单位置\r\nexport function updateLocation(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/account/location`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata: data\r\n\t})\r\n}\r\n\r\n/**\r\n * 获取技师二维码\r\n * @returns {Promise<{qrcode: string}>} 技师二维码信息\r\n */\r\nexport function getCoachQrcode() : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/account/qrcode`,\r\n\t\tmethod: \"GET\"\r\n\t})\r\n}\r\n\r\n\r\n\r\n// 一键报警\r\nexport function orderAlarm() : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/orders/alerts`,\r\n\t\tmethod: \"GET\"\r\n\t})\r\n}\r\n\r\n// 获取当前区域配置\r\nexport function getAreaConfig(params : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/wallet/withdraw-fee-rate`,\r\n\t\tmethod: \"GET\",\r\n\t\tparams: params\r\n\t})\r\n}\r\n\r\n\r\n\r\n// 消息通知\r\nexport function getNotice(params : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/inform/inform`,\r\n\t\tmethod: \"GET\",\r\n\t\tparams: params\r\n\t})\r\n}","import { request } from '../request.uts'\r\n// 基础 URL 配置\r\n\r\nconst BASE_URL = 'https://dev.xiaodingyun.cn'\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n/**\r\n * 获取商户评论列表\r\n */\r\nexport function transRecords(data : UTSJSONObject) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/wallet/trans-records/${data?.id ?? ''}`,\r\n\t\tmethod: \"GET\"\r\n\t})\r\n}\r\n\r\n/**\r\n * 获取商户评论列表\r\n */\r\nexport function getCommentList(data : UTSJSONObject) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/ordercomments/${data?.id ?? ''}`,\r\n\t\tmethod: \"GET\"\r\n\t})\r\n}\r\n\r\n/**\r\n * 获取商户评论统计数据\r\n */\r\nexport function getCommentData(data : UTSJSONObject) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/ordercomments/statistics/${data?.id ?? ''}`,\r\n\t\tmethod: \"GET\"\r\n\t})\r\n}\r\n// 开通/关闭项目并设置路费\r\nexport function toggleProject(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/projects/open`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata: data\r\n\t})\r\n}\r\n\r\n// 获取订单列表\r\nexport function getOrderList(params : UTSJSONObject) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/orders`,\r\n\t\tmethod: \"GET\",\r\n\t\tparams\r\n\t})\r\n}\r\n\r\n// 商户订单详情\r\nexport function getOrderDetaile(data : UTSJSONObject) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/orders/detail/${data?.id ?? ''}`,\r\n\t\tmethod: \"GET\",\r\n\t\tparams: data\r\n\t})\r\n}\r\n\r\n/**\r\n * 商户开始服务\r\n * @param {Object} data - 服务相关数据\r\n * @param {string|number} data.order_id - 订单ID\r\n * @param {string} [data.start_time] - 服务开始时间\r\n * @param {string} [data.service_notes] - 服务备注\r\n * @returns {Promise<Object>} 开始服务结果\r\n */\r\nexport function startService(data : any = {}) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/orders/start-service`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata\r\n\t})\r\n}\r\n\r\n/**\r\n * 商户接单\r\n * @param {string|number} orderId - 订单ID\r\n * @returns {Promise<Object>} 接单结果\r\n */\r\nexport function acceptOrder(data : UTSJSONObject) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/orders/accept/${data.order_id}`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata\r\n\t})\r\n}\r\n\r\n/**\r\n * 商户出发\r\n * @param {string|number} orderId - 订单ID\r\n * @param {Object} data - 出发相关数据\r\n * @param {string} [data.estimated_arrival_time] - 预计到达时间(分钟)\r\n * @param {Object} [data.current_location] - 当前位置信息\r\n * @param {number} [data.current_location.latitude] - 纬度\r\n * @param {number} [data.current_location.longitude] - 经度\r\n * @returns {Promise<Object>} 确认出发结果\r\n */\r\nexport function departOrder(orderId : any, data : any = {}) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/orders/depart/${orderId}`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata\r\n\t})\r\n}\r\n\r\n/**\r\n * 商户到达\r\n * @param {string|number} orderId - 订单ID\r\n * @param {Object} data - 到达相关数据\r\n * @param {Object} [data.arrival_location] - 到达位置信息\r\n * @param {number} [data.arrival_location.latitude] - 纬度\r\n * @param {number} [data.arrival_location.longitude] - 经度\r\n * @param {string} [data.arrival_time] - 到达时间\r\n * @returns {Promise<Object>} 确认到达结果\r\n */\r\nexport function arriveOrder(orderId : any, data : any = {}) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/orders/arrive/${orderId}`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata\r\n\t})\r\n}\r\n\r\n/**\r\n * 商户撤离\r\n * @param {string|number} orderId - 订单ID\r\n * @param {Object} data - 撤离相关数据\r\n * @param {string} [data.leave_time] - 撤离时间\r\n * @param {Object} [data.leave_location] - 撤离位置信息\r\n * @param {number} [data.leave_location.latitude] - 纬度\r\n * @param {number} [data.leave_location.longitude] - 经度\r\n * @param {string} [data.service_notes] - 服务备注\r\n * @returns {Promise<Object>} 确认撤离结果\r\n */\r\nexport function leaveOrder(orderId : any, data : any = {}) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/orders/${orderId}/leave`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata\r\n\t})\r\n}\r\n\r\n// 商户转单\r\nexport function transferOrder(orderId : any, data : any = {}) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/orders/${orderId}/transfer`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata\r\n\t})\r\n}\r\n\r\n// 获取商户订单详情\r\nexport function getOrderDetailById(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/orders/detail/${data?.id ?? ''}`,\r\n\t\tmethod: \"GET\"\r\n\t})\r\n}\r\n\r\n// 用户评价标签\r\nexport function getCommentTag(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/orders/comment_tag/${data?.id ?? ''}`,\r\n\t\tmethod: \"GET\"\r\n\t})\r\n}\r\n\r\n// 订单简单版详情\r\nexport function getSimpleOrderDetaile(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/orders/comment_detail/${data?.id ?? ''}`,\r\n\t\tmethod: \"GET\"\r\n\t})\r\n}\r\n\r\n// 用户评价\r\nexport function rate(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/orders/rate`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata\r\n\t})\r\n}\r\n\r\n// 对ta的印象\r\nexport function getQuestion(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/orders/commentStatistics/${data?.id ?? data ?? ''}`,\r\n\t\tmethod: \"GET\"\r\n\t})\r\n}","// 导入请求\r\nimport { request } from '../request.uts'\r\n// 基础 URL 配置\r\n\r\nconst BASE_URL = 'https://dev.xiaodingyun.cn'\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n //获取技师统计数据\r\nexport function getAllData(params : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/orders/statistics`,\r\n\t\tmethod: \"GET\",\r\n\t\tparams: params\r\n\t})\r\n}\r\n //修改技师工作状态\r\nexport function editCoachWorkState(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/account/work-status`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata: data\r\n\t})\r\n}\r\n// 获取技师工作状态\r\nexport function getCoachWorkState() : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/account/work-status`,\r\n\t\tmethod: \"GET\"\r\n\t})\r\n}\r\n\r\n// 获取技师工作时间设置\r\nexport function getWorkTimeSetting() : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/account/schedule`,\r\n\t\tmethod: \"GET\"\r\n\t})\r\n}\r\n\r\n\r\n //修改技师工作时间设置\r\nexport function editWorkTimeSetting(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/account/schedule`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata: data\r\n\t})\r\n}\r\n// 获取技师服务项目\r\nexport function getCoachItems() : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/project`,\r\n\t\tmethod: \"GET\"\r\n\t})\r\n}\r\n// 获取可开通项目列表\r\nexport function getAvailableProjects() : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/projects/available`,\r\n\t\tmethod: \"GET\"\r\n\t})\r\n}\r\n // 开通/关闭项目并设置路费\r\nexport function toggleProject(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/projects/open`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata: data\r\n\t})\r\n}\r\n\r\n// 获取技师本月数据\r\nexport function getMonthData() : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/orders/statistics_month`,\r\n\t\tmethod: \"GET\"\r\n\t})\r\n}","<template>\r\n\r\n\t<scroll-view style=\"flex:1\">\r\n\r\n\t\t<view class=\"container\">\r\n\t\t\t<!-- 背景图改为absolute,避免fixed在scroll-view内的问题 -->\r\n\t\t\t<image class=\"bg-image\" src=\"@/static/imagesInfo/bg-color.png\" mode=\"aspectFill\" />\r\n\r\n\t\t\t<scroll-view style=\"flex: 1\" scroll-y>\r\n\t\t\t\t<view class=\"page\">\r\n\t\t\t\t\t<!-- 城市信息 -->\r\n\t\t\t\t\t<view class=\"city-info\">\r\n\t\t\t\t\t\t<text class=\"city-text-box\">当前城市:{{ state.cityInfo }}</text>\r\n\t\t\t\t\t\t<u-icon name=\"notification\" :size=\"24\" />\r\n\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t<!-- 用户卡片 -->\r\n\t\t\t\t\t<view class=\"user-card\">\r\n\t\t\t\t\t\t<image class=\"user-bg\" src=\"@/static/imagesInfo/bg-icon.png\" mode=\"scaleToFill\" />\r\n\r\n\t\t\t\t\t\t<view class=\"user-content\" style=\"padding: 20rpx;\">\r\n\t\t\t\t\t\t\t<!-- 左侧信息 -->\r\n\t\t\t\t\t\t\t<view class=\"user-left\">\r\n\t\t\t\t\t\t\t\t<view class=\"user-row\">\r\n\t\t\t\t\t\t\t\t\t<text class=\"user-name\">{{ coachInfo.nickname }}</text>\r\n\t\t\t\t\t\t\t\t\t<view class=\"tags\">\r\n\t\t\t\t\t\t\t\t\t\t<text class=\"tag-new\">新人实习</text>\r\n\t\t\t\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t\t\t\t<u-icon name=\"edit\" :size=\"18\" @click=\"jumpMasterInfo\" />\r\n\t\t\t\t\t\t\t\t\t<text class=\"tag\">编辑</text>\r\n\t\t\t\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t\t\t\t<view class=\"user-row\">\r\n\t\t\t\t\t\t\t\t\t<u-icon name=\"customer-interests\" :size=\"18\" />\r\n\t\t\t\t\t\t\t\t\t<text class=\"user-role\">{{ coachInfo.role_name }}</text>\r\n\t\t\t\t\t\t\t\t\t<u-icon name=\"store\" :size=\"18\" />\r\n\t\t\t\t\t\t\t\t\t<text class=\"user-shop\">{{ coachInfo.shop_name }}</text>\r\n\t\t\t\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t\t\t\t<view class=\"online-switch\">\r\n\t\t\t\t\t\t\t\t\t<u-switch :checked=\"state.isOnline\" @change=\"toggleOnline\" />\r\n\t\t\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t\t\t<!-- 右侧头像 -->\r\n\t\t\t\t\t\t\t<view class=\"user-right\" @click=\"jumpMasterInfo\">\r\n\t\t\t\t\t\t\t\t<text class=\"time-text\">入驻时间</text>\r\n\t\t\t\t\t\t\t\t<text class=\"time-text\" style=\"margin-top: 5rpx;\">{{ displayCreatedAt }}</text>\r\n\t\t\t\t\t\t\t\t<image class=\"avatar-img\" :src=\"coachInfo.avatar\" mode=\"aspectFit\" />\r\n\t\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t\t<!-- 定位栏 -->\r\n\t\t\t\t\t\t<view class=\"location-bar\">\r\n\t\t\t\t\t\t\t<u-icon name=\"navigation\" :size=\"18\" />\r\n\t\t\t\t\t\t\t<text class=\"location-text\">当前定位:{{ userLocation }}</text>\r\n\t\t\t\t\t\t\t<text class=\"location-btn\" @click=\"updateLocation\">手动更新</text>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t<!-- 本月数据 -->\r\n\t\t\t\t\t<view class=\"stats-row\">\r\n\t\t\t\t\t\t<view class=\"stat-item\" v-for=\"(item, index) in monthStats\" :key=\"index\">\r\n\t\t\t\t\t\t\t<!-- {{item?.[\"label\"]}} -->\r\n\t\t\t\t\t\t\t<text class=\"stat-label\">{{ item?.[\"label\"] }}</text>\r\n\t\t\t\t\t\t\t<text class=\"stat-value\">{{ item?.[\"value\"]}}</text>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t<!-- 功能按钮 -->\r\n\t\t\t\t\t<view class=\"func-grid\">\r\n\t\t\t\t\t\t<view class=\"func-item\" v-for=\"(item, index) in funcList\" :key=\"index\"\r\n\t\t\t\t\t\t\t@click=\"jumpSetProject(item.label)\">\r\n\t\t\t\t\t\t\t<image class=\"func-icon\" :src=\"item.iconUrl\" mode=\"aspectFit\" />\r\n\t\t\t\t\t\t\t<text class=\"func-label\">{{ item.label }}</text>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t<!-- 数据统计 -->\r\n\t\t\t\t\t<view class=\"data-section\">\r\n\t\t\t\t\t\t<view class=\"section-header\">\r\n\t\t\t\t\t\t\t<text class=\"section-title\">数据统计</text>\r\n\t\t\t\t\t\t\t<text class=\"section-more\" @click=\"jumpStatisics\">查看全部 ></text>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t<view class=\"data-grid\">\r\n\t\t\t\t\t\t\t<view class=\"data-item\" v-for=\"(item, index) in coachData\" :key=\"index\">\r\n\t\t\t\t\t\t\t\t<text class=\"data-value\">{{ item?.[\"value\"] }}</text>\r\n\t\t\t\t\t\t\t\t<text class=\"data-label\">{{ item?.[\"label\"] }}</text>\r\n\t\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t<!-- 客户评价 -->\r\n\t\t\t\t\t<view class=\"eval-section\">\r\n\t\t\t\t\t\t<view class=\"section-header\">\r\n\t\t\t\t\t\t\t<text class=\"section-title\">客户评价</text>\r\n\t\t\t\t\t\t\t<text class=\"section-more\" @click=\"jumpAppraise\">查看全部 ></text>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t<scroll-view class=\"eval-tags\" scroll-x>\r\n\t\t\t\t\t\t\t<text class=\"eval-tag\" v-for=\"(tag, index) in evalTags\" :key=\"index\">\r\n\t\t\t\t\t\t\t\t{{ tag?.[\"text\"] }} {{ (tag?.[\"count\"])as number > 0 ? tag?.[\"count\"] : '' }}\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t</scroll-view>\r\n\t\t\t\t\t\t<view class=\"eval-item\" v-for=\"(item, index) in evalList\" :key=\"index\">\r\n\t\t\t\t\t\t\t<image class=\"eval-avatar\" :src='(item[\"user_info\"] as UTSJSONObject)?.[\"avatar\"] as string'\r\n\t\t\t\t\t\t\t\tmode=\"aspectFill\" />\r\n\t\t\t\t\t\t\t<view class=\"eval-content\">\r\n\t\t\t\t\t\t\t\t<view class=\"eval-top\">\r\n\t\t\t\t\t\t\t\t\t<text\r\n\t\t\t\t\t\t\t\t\t\tclass=\"eval-name\">{{(item['user_info'] as UTSJSONObject)?.['nickname'] as string}}</text>\r\n\t\t\t\t\t\t\t\t\t<text class=\"eval-date\">{{item?.[\"created_at\"] as string}}</text>\r\n\t\t\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t\t\t<view class=\"eval-stars\">\r\n\t\t\t\t\t\t\t\t\t<text>⭐⭐⭐⭐⭐</text>\r\n\t\t\t\t\t\t\t\t\t<text class=\"eval-service\">{{item?.[\"project_name\"]}}</text>\r\n\t\t\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t\t\t<view style=\"flex-direction: row;\">\r\n\t\t\t\t\t\t\t\t\t<text class=\"eval-comment\" v-for='(tag, index) in (item?.[\"tags_list\"]) as string[]'\r\n\t\t\t\t\t\t\t\t\t\t:key=\"index\">\r\n\t\t\t\t\t\t\t\t\t\t{{tag}}\r\n\t\t\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t<!-- 底部留白,避免悬浮球遮挡 -->\r\n\t\t\t\t\t<!-- <view style=\"height: 100rpx;\"></view> -->\r\n\t\t\t\t</view>\r\n\t\t\t</scroll-view>\r\n\r\n\t\t\t<!-- 悬浮球移到scroll-view外 -->\r\n\t\t\t<u-floating @click=\"callPolice\" />\r\n\t\t</view>\r\n\r\n\t</scroll-view>\r\n\r\n</template>\r\n\r\n<script setup lang=\"uts\">\r\n\timport { ref, computed, reactive, } from 'vue'\r\n\timport { getCoachDetaile } from '@/utils/api/masterInfoApi'\r\n\timport { getCommentList } from '@/utils/api/order'\r\n\timport { getMonthData, getAllData, getCoachWorkState, editCoachWorkState, editWorkTimeSetting } from '@/utils/api/workbenches'\r\n\t// ==================== 类型定义 ====================\r\n\ttype CoachInfo = {\r\n\t\tnickname : string\r\n\t\trole_name : string\r\n\t\tshop_name : string\r\n\t\tcreated_at : string\r\n\t\tavatar : string\r\n\t\tcoach : string\r\n\t}\r\n\r\n\ttype State = {\r\n\t\tisOnline : boolean\r\n\t\tcityInfo : string\r\n\t}\r\n\r\n\ttype FuncItem = {\r\n\t\tlabel : string\r\n\t\ticonUrl : string\r\n\t}\r\n\r\n\ttype EvalTag = {\r\n\t\ttext : string\r\n\t\tcount : number\r\n\t}\r\n\ttype StatItem = {\r\n\t\tlabel : string,\r\n\t\tvalue : string | number\r\n\t}\r\n\ttype UserInfo = {\r\n\t\tnickname ?: string\r\n\t\tavatar ?: string\r\n\t}\r\n\r\n\ttype EvalItem = {\r\n\t\tuser_info ?: UserInfo\r\n\t\tcreated_at ?: string\r\n\r\n\t\tproject_name ?: string\r\n\t\ttags_list ?: string[]\r\n\t}\r\n\t// ==================== 响应式数据(全部使用reactive/ref,避免shallowRef)====================\r\n\r\n\tconst state = ref<State>({\r\n\t\tisOnline: true,\r\n\t\tcityInfo: '定位中...'\r\n\t})\r\n\r\n\r\n\tconst coachInfo = reactive<CoachInfo>({\r\n\t\tnickname: '',\r\n\t\trole_name: '小丁理疗师',\r\n\t\tshop_name: '未绑定门店',\r\n\t\tcreated_at: '',\r\n\t\tavatar: '/static/testInfo/boy-nickname.png',\r\n\t\tcoach: ''\r\n\t})\r\n\r\n\tconst userLocation = ref<string>('')\r\n\r\n\tconst displayCreatedAt = computed(() : string => {\r\n\t\tconst date = coachInfo.created_at\r\n\t\tif (date == null || date.length == 0) {\r\n\t\t\treturn '--'\r\n\t\t}\r\n\t\treturn date\r\n\t})\r\n\r\n\t// ==================== 静态数据 ====================\r\n\tconst monthStats = ref<UTSArray<UTSJSONObject>>([\r\n\t\t{ label: '本月收益(元)', value: '2234.88' },\r\n\t\t{ label: '本月接单量(单)', value: '2234.88' },\r\n\t\t{ label: '本月退单率', value: '30%' }\r\n\t])\r\n\r\n\tconst funcList : FuncItem[] = [\r\n\t\t{ iconUrl: '/static/imagesInfo/cx-shop.png', label: '接单时间' },\r\n\t\t{ iconUrl: '/static/imagesInfo/item-icon.png', label: '服务项目' },\r\n\t\t{ iconUrl: '/static/imagesInfo/jied-time.png', label: '重选店铺' },\r\n\t\t{ iconUrl: '/static/imagesInfo/gengxin-wz.png', label: '位置更新' }\r\n\t]\r\n\r\n\tconst coachData = ref<UTSArray<UTSJSONObject>>([\r\n\t\t{ value: '456', label: '接单量' },\r\n\t\t{ value: '10%', label: '加钟率' },\r\n\t\t{ value: '70%', label: '好评率' },\r\n\t\t{ value: '3%', label: '复购率' },\r\n\t\t{ value: '19%', label: '退单率' }\r\n\t])\r\n\r\n\tconst evalTags = ref<UTSArray<UTSJSONObject>>([\r\n\t\t{ text: '不良引导', count: 0 },\r\n\t\t{ text: '手法不好', count: 101 },\r\n\t\t{ text: '性格温柔', count: 198 },\r\n\t\t{ text: '服务到位', count: 10 }\r\n\t])\r\n\tconst evalList = ref<UTSJSONObject[]>([])\r\n\t// ==================== 方法 ====================\r\n\r\n\r\n\tconst toggleOnline = async () => {\r\n\t\tstate.value.isOnline = !state.value.isOnline\r\n\t\tconsole.log('Status changed:', state.value.isOnline)\r\n\t\tconst status = state.value.isOnline ? 2 : 1\r\n\t\ttry {\r\n\t\t\tconst response = await editCoachWorkState({ status: status }) as UTSJSONObject\r\n\t\t\tconsole.log('Set work state result:', response)\r\n\t\t\tconst code = response[\"code\"] as number\r\n\t\t\tconst message = response[\"message\"] as string\r\n\t\t\tif (code !== 200) {\r\n\t\t\t\tuni.showToast({ title: message, icon: 'none' })\r\n\t\t\t\treturn false\r\n\t\t\t}\r\n\t\t\tuni.showToast({ title: '状态切换成功', icon: 'success' })\r\n\t\t\treturn true\r\n\t\t} catch (err : any) {\r\n\t\t\tconsole.error('设置技师工作状态失败:', err)\r\n\t\t\tuni.showToast({ title: '网络错误', icon: 'none' })\r\n\t\t\treturn false\r\n\t\t}\r\n\t}\r\n\tconst httpGetMonthData = async () => {\r\n\t\ttry {\r\n\t\t\tconst response = await getMonthData() as UTSJSONObject\r\n\t\t\tconsole.log('Month data:', response)\r\n\t\t\tconst code = response[\"code\"] as number\r\n\t\t\tconst dataObj = response[\"data\"] as UTSJSONObject | null\r\n\t\t\tif (code != 200 || dataObj == null) {\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t\tmonthStats.value = [\r\n\t\t\t\t{ label: '本月收益(元)', value: dataObj[\"commission_amount\"] ?? 0 },\r\n\t\t\t\t{ label: '本月接单量(单)', value: dataObj[\"total_count\"] ?? 0 },\r\n\t\t\t\t{\r\n\t\t\t\t\tlabel: '本月退单率',\r\n\t\t\t\t\tvalue: dataObj[\"refund_rate\"] != ''\r\n\t\t\t\t\t\t? ((dataObj[\"refund_rate\"] as number) * 100).toFixed(0) + '%'\r\n\t\t\t\t\t\t: '0%'\r\n\t\t\t\t}\r\n\t\t\t]\r\n\t\t\tconsole.log(monthStats.value, 'monthStats.value')\r\n\t\t} catch (err : any) {\r\n\t\t\tconsole.error('获取技师本月数据失败:', err)\r\n\t\t}\r\n\t}\r\n\r\n\tconst httpGetAllData = async () => {\r\n\t\ttry {\r\n\t\t\tconst response = await getAllData({}) as UTSJSONObject\r\n\t\t\tconsole.log('All stats:', response)\r\n\t\t\tconst code = response[\"code\"] as number\r\n\t\t\tconst dataObj = response[\"data\"] as UTSJSONObject | null\r\n\t\t\tif (code != 200 || dataObj == null) {\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t\t// coachData.value = [\r\n\t\t\t// \t{\r\n\t\t\t// \t\tvalue: dataObj[\"receiving\"] ?? 0,\r\n\t\t\t// \t\tlabel: '接单量'\r\n\t\t\t// \t},\r\n\t\t\t// \t{\r\n\t\t\t// \t\tvalue: ((dataObj[\"additional\"] as UTSJSONObject)?.[\"rate\"] ?? 0) * 100 + '%',\r\n\t\t\t// \t\tlabel: '加钟率'\r\n\t\t\t// \t},\r\n\t\t\t// \t{\r\n\t\t\t// \t\tvalue: ((dataObj[\"comment\"] as UTSJSONObject)?.[\"goodrate\"] ?? 0) * 100 + '%',\r\n\t\t\t// \t\tlabel: '好评率'\r\n\t\t\t// \t},\r\n\t\t\t// \t{\r\n\t\t\t// \t\tvalue: ((dataObj[\"renewal\"] as UTSJSONObject)?.[\"rate\"] ?? 0) * 100 + '%',\r\n\t\t\t// \t\tlabel: '复购率'\r\n\t\t\t// \t},\r\n\t\t\t// \t{\r\n\t\t\t// \t\tvalue: ((dataObj[\"refund\"] as UTSJSONObject)?.[\"rate\"] ?? 0) * 100 + '%',\r\n\t\t\t// \t\tlabel: '退单率'\r\n\t\t\t// \t}\r\n\t\t\t// ]\r\n\t\t} catch (err : any) {\r\n\t\t\tconsole.error('获取技师统计数据失败:', err)\r\n\t\t}\r\n\t}\r\n\r\n\tconst httpGetCoachWorkState = async () => {\r\n\t\ttry {\r\n\t\t\tconst response = await getCoachWorkState() as UTSJSONObject\r\n\t\t\tconst code = response[\"code\"] as number\r\n\t\t\tconst dataObj = response[\"data\"] as UTSJSONObject | null\r\n\t\t\tif (code != 200 || dataObj == null) {\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t\t// 根据接口返回值修改技师工作状态\r\n\t\t\t// 通常work_status字段:1为在线,2为离线等\r\n\t\t\tstate.value.isOnline = (dataObj[\"work_status\"] as number) === 1\r\n\r\n\t\t} catch (err : any) {\r\n\t\t\tconsole.error('获取技师工作状态失败:', err)\r\n\t\t}\r\n\t}\r\n\t// 获取客户评价接口\r\n\tconst httpGetEvaluations = async () => {\r\n\t\ttry {\r\n\t\t\tconst response = await getCommentList({\r\n\t\t\t\tpage: 1,\r\n\t\t\t\tper_page: 5\r\n\t\t\t}) as UTSJSONObject\r\n\t\t\tconst code = response[\"code\"] as number\r\n\t\t\tconst data = response[\"data\"] as UTSJSONObject\r\n\t\t\tif (code !== 200) return\r\n\r\n\t\t\tevalTags.value = data?.tags_list as UTSArray<UTSJSONObject>;\r\n\t\t\tevalList.value = data?.items as UTSArray<UTSJSONObject>;\r\n\t\t} catch (err : any) {\r\n\t\t\tconsole.error('获取客户评价接口异常', err)\r\n\t\t}\r\n\t}\r\n\r\n\tconst httpGetCoachDetail = async () => {\r\n\t\tconst response = await getCoachDetaile() as UTSJSONObject\r\n\t\t// console.log('Coach detail:', response)\r\n\t\tconst code = response[\"code\"] as number\r\n\t\tconst dataObj = response[\"data\"] as UTSJSONObject | null\r\n\t\tif (code != 200 || dataObj == null) {\r\n\t\t\treturn\r\n\t\t}\r\n\r\n\t\tconst coach = dataObj[\"coach\"] as UTSJSONObject | null\r\n\t\tconst coachValue = (coach?.[\"info_records\"] as UTSArray<UTSJSONObject>)[0] as UTSJSONObject | null\r\n\t\t// console.log(coachValue, 'coachValue')\r\n\t\t// console.log(coachValue?.state_text, 'value');\r\n\t\tif (coach == null) {\r\n\t\t\tuni.navigateTo({\r\n\t\t\t\turl: '/pages/login/merchantRecuitment'\r\n\t\t\t})\r\n\t\t\treturn\r\n\t\t}\r\n\t\telse if (coachValue?.state_text == '审核中' || coachValue?.state_text == '审核拒绝') {\r\n\t\t\tuni.navigateTo({\r\n\t\t\t\turl: `/pages/login/checkMiddle?stateNum=${coachValue?.state_text == '审核拒绝' ? 3 : 1}&remark=${coachValue?.audit_remark}`\r\n\t\t\t})\r\n\r\n\t\t}\r\n\t\tcoachInfo.nickname = dataObj[\"nickname\"] as string\r\n\t\tconst spaceIndex = (dataObj[\"created_at\"] as string).lastIndexOf(\" \")\r\n\t\tcoachInfo.created_at = (dataObj[\"created_at\"] as string).substring(0, spaceIndex)\r\n\t\t// coachInfo.created_at = dataObj[\"created_at\"] as string\r\n\t\tcoachInfo.avatar = dataObj[\"avatar\"] as string\r\n\t\tstate.value.isOnline = coach?.[\"work_status\"] == 1 ? true : false as boolean\r\n\t\tconsole.log(coach[\"work_status\"], state.value.isOnline, 'work_status')\r\n\t\thttpGetMonthData();\r\n\t\thttpGetAllData();\r\n\t\thttpGetCoachWorkState();\r\n\t\thttpGetEvaluations();\r\n\t}\r\n\r\n\r\n\tconst updateLocation = async () => {\r\n\t\t// try {\r\n\t\t// \tconst location = await new Promise<UniApp.GetLocationSuccess>((resolve, reject) => {\r\n\t\t// \t\tuni.getLocation({\r\n\t\t// \t\t\ttype: 'gcj02',\r\n\t\t// \t\t\tsuccess: resolve,\r\n\t\t// \t\t\tfail: reject\r\n\t\t// \t\t})\r\n\t\t// \t})\r\n\r\n\t\t// \tconsole.log('Location:', location)\r\n\t\t// \t// 简化处理,实际需要逆地理编码\r\n\t\t// \tuserLocation.value = `${location.latitude.toFixed(2)}, ${location.longitude.toFixed(2)}`\r\n\r\n\t\t// } catch (e) {\r\n\t\t// \tconsole.error('定位错误:', e)\r\n\t\t// \tuni.showToast({ title: '定位失败', icon: 'none' })\r\n\t\t// \tuserLocation.value = '定位失败'\r\n\t\t// }\r\n\t}\r\n\r\n\tconst jumpMasterInfo = () => {\r\n\t\tuni.navigateTo({\r\n\t\t\turl: '/pages/myEdit/myEdit'\r\n\t\t});\r\n\r\n\r\n\t}\r\n\r\n\tconst jumpSetProject = (label : string) => {\r\n\t\tconsole.log('Navigate to:', label)\r\n\t\tswitch (label) {\r\n\t\t\tcase '接单时间':\r\n\t\t\t\tuni.navigateTo({ url: '/pages/homepage/setOrderTime' })\r\n\t\t\t\tbreak\r\n\t\t\tcase '服务项目':\r\n\t\t\t\tuni.navigateTo({ url: '/pages/homepage/serviceProject' })\r\n\t\t\t\tbreak\r\n\t\t}\r\n\t}\r\n\r\n\tconst callPolice = () => {\r\n\t\tconsole.log('Emergency call triggered')\r\n\t}\r\n\tconst jumpStatisics = () => {\r\n\t\tuni.navigateTo({ url: '/pages/order/orderStatisics' })\r\n\t}\r\n\tconst jumpAppraise = () => {\r\n\t\tuni.navigateTo({ url: '/pages/order/appraise' })\r\n\t}\r\n\tonLoad(() => {\r\n\t\t// httpGetCoachDetail()\r\n\t})\r\n\r\n\tonReady(() => {\r\n\t\thttpGetCoachDetail();\r\n\t})\r\n</script>\r\n\r\n<style>\r\n\t.container {\r\n\r\n\t\tposition: relative;\r\n\t}\r\n\r\n\t/* 修复9:背景图改为absolute,避免fixed在scroll-view内的问题 */\r\n\t.bg-image {\r\n\t\tposition: absolute;\r\n\t\ttop: 0;\r\n\t\tleft: 0;\r\n\t\twidth: 750rpx;\r\n\t\theight: 900rpx;\r\n\t\tz-index: 0;\r\n\t}\r\n\r\n\t.page {\r\n\t\tpadding: 20rpx;\r\n\t\tposition: relative;\r\n\t\tz-index: 1;\r\n\t}\r\n\r\n\t.city-info {\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: space-between;\r\n\t\talign-items: center;\r\n\t\tmargin-bottom: 16rpx;\r\n\t}\r\n\r\n\t.city-text-box {\r\n\t\tfont-size: 28rpx;\r\n\t\tcolor: #333;\r\n\t}\r\n\r\n\t/* 用户卡片 */\r\n\t.user-card {\r\n\t\tborder-radius: 16rpx;\r\n\t\tmargin-bottom: 32rpx;\r\n\t\tbox-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);\r\n\t\tposition: relative;\r\n\t\toverflow: hidden;\r\n\t\tbackground-color: #fff;\r\n\t}\r\n\r\n\t.user-bg {\r\n\t\tposition: absolute;\r\n\t\ttop: 0;\r\n\t\tleft: 0;\r\n\t\twidth: 100%;\r\n\t\theight: 100%;\r\n\t\tz-index: 0;\r\n\t}\r\n\r\n\t.user-content {\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: space-between;\r\n\t\tposition: relative;\r\n\t\tz-index: 1;\r\n\t}\r\n\r\n\t.user-left {\r\n\t\tflex: 1;\r\n\t\tflex-direction: column;\r\n\t}\r\n\r\n\t.user-row {\r\n\t\tflex-direction: row;\r\n\t\talign-items: center;\r\n\t\tmargin-bottom: 16rpx;\r\n\t}\r\n\r\n\t.user-name {\r\n\t\tfont-size: 40rpx;\r\n\t\tfont-weight: bold;\r\n\t\tcolor: #333;\r\n\t}\r\n\r\n\t.tags {\r\n\t\tflex-direction: row;\r\n\t\tmargin-left: 16rpx;\r\n\t}\r\n\r\n\t.tag-new {\r\n\t\tbackground: linear-gradient(180deg, rgba(207, 221, 62, 0.69) 0%, rgba(162, 184, 29, 1) 100%);\r\n\t\tcolor: #fff;\r\n\t\tborder-radius: 24rpx;\r\n\t\tfont-size: 24rpx;\r\n\t\tpadding: 6rpx 16rpx;\r\n\t}\r\n\r\n\t.tag {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #666;\r\n\t\tmargin-left: 8rpx;\r\n\t}\r\n\r\n\t.user-role,\r\n\t.user-shop {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #999;\r\n\t\tmargin-left: 8rpx;\r\n\t\tmargin-right: 24rpx;\r\n\t}\r\n\r\n\t.online-switch {\r\n\t\tmargin-top: 24rpx;\r\n\t}\r\n\r\n\t.user-right {\r\n\t\twidth: 210rpx;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.time-text {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #fff;\r\n\t\ttext-align: center;\r\n\t\tmargin-bottom: 10rpx;\r\n\t}\r\n\r\n\t.avatar-img {\r\n\t\twidth: 138rpx;\r\n\t\theight: 138rpx;\r\n\t\tborder-radius: 69rpx;\r\n\t\tborder: 4rpx solid #fff;\r\n\t}\r\n\r\n\t.location-bar {\r\n\t\tflex-direction: row;\r\n\t\talign-items: center;\r\n\t\tbackground: linear-gradient(to right, rgba(255, 249, 225, 1), rgba(255, 241, 191, 1));\r\n\t\tpadding: 16rpx 20rpx;\r\n\t\tborder-radius: 18rpx;\r\n\t\tmargin: 20rpx;\r\n\t\tposition: relative;\r\n\t\tz-index: 1;\r\n\t\tmargin-top: 32rpx;\r\n\t}\r\n\r\n\t.location-text {\r\n\t\tflex: 1;\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #333;\r\n\t\tmargin-left: 8rpx;\r\n\t}\r\n\r\n\t.location-btn {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #333;\r\n\t\tborder: 2rpx solid #333;\r\n\t\tpadding: 8rpx 16rpx;\r\n\t\tborder-radius: 16rpx;\r\n\t}\r\n\r\n\t/* 本月数据 */\r\n\t.stats-row {\r\n\t\tflex-direction: row;\r\n\t\tbackground-color: #fff;\r\n\t\tmargin-bottom: 32rpx;\r\n\t\tborder-radius: 24rpx;\r\n\t\tpadding: 32rpx 0;\r\n\t\tbox-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);\r\n\t}\r\n\r\n\t.stat-item {\r\n\t\tflex: 1;\r\n\t\talign-items: center;\r\n\t\tborder-right-width: 2rpx;\r\n\t\tborder-right-color: #eee;\r\n\t\tborder-right-style: solid;\r\n\t}\r\n\r\n\t.stat-item:last-child {\r\n\t\tborder-right-width: 0;\r\n\t}\r\n\r\n\t.stat-label {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #999;\r\n\t\tmargin-bottom: 12rpx;\r\n\t}\r\n\r\n\t.stat-value {\r\n\t\tfont-size: 36rpx;\r\n\t\tfont-weight: bold;\r\n\t\tcolor: #333;\r\n\t}\r\n\r\n\t/* 功能网格 */\r\n\t.func-grid {\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: space-around;\r\n\t\tbackground-color: #fff;\r\n\t\tmargin-bottom: 32rpx;\r\n\t\tborder-radius: 24rpx;\r\n\t\tpadding: 32rpx 0;\r\n\t\tbox-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);\r\n\t}\r\n\r\n\t.func-item {\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.func-icon {\r\n\t\twidth: 92rpx;\r\n\t\theight: 92rpx;\r\n\t}\r\n\r\n\t.func-label {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #666;\r\n\t\tmargin-top: 16rpx;\r\n\t}\r\n\r\n\t/* 数据统计 */\r\n\t.data-section,\r\n\t.eval-section {\r\n\t\tbackground-color: #fff;\r\n\t\tmargin-bottom: 32rpx;\r\n\t\tborder-radius: 24rpx;\r\n\t\tpadding: 32rpx;\r\n\t\tbox-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);\r\n\t}\r\n\r\n\t.section-header {\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: space-between;\r\n\t\talign-items: center;\r\n\t\tmargin-bottom: 24rpx;\r\n\t}\r\n\r\n\t.section-title {\r\n\t\tfont-size: 32rpx;\r\n\t\tfont-weight: bold;\r\n\t\tcolor: #333;\r\n\t}\r\n\r\n\t.section-more {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #999;\r\n\t}\r\n\r\n\t.data-grid {\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: space-between;\r\n\t}\r\n\r\n\t.data-item {\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.data-value {\r\n\t\tfont-size: 32rpx;\r\n\t\tfont-weight: bold;\r\n\t\tcolor: #333;\r\n\t\tmargin-bottom: 8rpx;\r\n\t}\r\n\r\n\t.data-label {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #999;\r\n\t}\r\n\r\n\t/* 评价 */\r\n\t.eval-tags {\r\n\t\tflex-direction: row;\r\n\t\tmargin-bottom: 24rpx;\r\n\t}\r\n\r\n\t.eval-tag {\r\n\t\tfont-size: 24rpx;\r\n\t\tpadding: 8rpx 20rpx;\r\n\t\tbackground-color: #f5f5f5;\r\n\t\tborder-radius: 24rpx;\r\n\t\tmargin-right: 16rpx;\r\n\t\tcolor: #666;\r\n\t}\r\n\r\n\t.eval-item {\r\n\t\tflex-direction: row;\r\n\t}\r\n\r\n\t.eval-avatar {\r\n\t\twidth: 80rpx;\r\n\t\theight: 80rpx;\r\n\t\tborder-radius: 40rpx;\r\n\t\tmargin-right: 20rpx;\r\n\t}\r\n\r\n\t.eval-content {\r\n\t\tflex: 1;\r\n\t\tflex-direction: column;\r\n\t}\r\n\r\n\t.eval-top {\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: space-between;\r\n\t\tmargin-bottom: 8rpx;\r\n\t}\r\n\r\n\t.eval-name {\r\n\t\tfont-size: 28rpx;\r\n\t\tcolor: #333;\r\n\t}\r\n\r\n\t.eval-date {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #999;\r\n\t}\r\n\r\n\t.eval-stars {\r\n\t\tflex-direction: row;\r\n\t\talign-items: center;\r\n\t\tmargin-bottom: 8rpx;\r\n\t}\r\n\r\n\t.eval-service {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #999;\r\n\t\tmargin-left: 16rpx;\r\n\t}\r\n\r\n\t.eval-comment {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #333;\r\n\t\tmargin-right: 10rpx;\r\n\t}\r\n</style>","<template>\r\n\t<view class=\"page-container\">\r\n\r\n\t\t<!-- 1. 用户信息头部 -->\r\n\t\t<view class=\"user-header\">\r\n\t\t\t<view class=\"user-info\">\r\n\t\t\t\t<image class=\"avatar\" :src=\"coachInfo['avatar']\" mode=\"aspectFill\" />\r\n\t\t\t\t<text class=\"username\">\r\n\t\t\t\t\t{{ coachInfo['name'] }}\r\n\t\t\t\t</text>\r\n\t\t\t\t<image @click=\"jumpStarRating()\" :src=\"'/static/testInfo/xx-x' + coachInfo?.star_leavl + '.png'\"\r\n\t\t\t\t\tstyle=\"width: 108rpx;height:40rpx;margin-left: 12rpx;\" mode=\"aspectFit\">\r\n\t\t\t\t</image>\r\n\t\t\t</view>\r\n\t\t\t<view class=\"header-actions\">\r\n\t\t\t\t<view class=\"action-item\" @click=\"contactService\">\r\n\t\t\t\t\t<view class=\"icon-circle\">\r\n\t\t\t\t\t\t<u-icon name=\"customerService\" size=\"30\" color=\"#666\" />\r\n\t\t\t\t\t</view>\r\n\t\t\t\t\t<text>\r\n\t\t\t\t\t\t客服\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t\t<view class=\"action-item\" style=\"margin-left: 20rpx;\" @click=\"openSettings\">\r\n\t\t\t\t\t<view class=\"icon-circle\">\r\n\t\t\t\t\t\t<u-icon name=\"setting\" size=\"22\" color=\"#666\" />\r\n\t\t\t\t\t</view>\r\n\t\t\t\t\t<text>\r\n\t\t\t\t\t\t设置\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t</view>\r\n\t\t</view>\r\n\r\n\r\n\t\t<!-- 2. 等级卡片 -->\r\n\t\t<view class=\"level-card\">\r\n\t\t\t<image src=\"/static/testInfo/l-bg.png\" class=\"level-bg\" mode=\"widthFix\">\r\n\t\t\t</image>\r\n\t\t\t<view class=\"level-content\">\r\n\t\t\t\t<view class=\"level-main\" style=\"width: 60%;\">\r\n\t\t\t\t\t<text class=\"level-title\">\r\n\t\t\t\t\t\tV{{ coachInfo['level'] }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text style=\"margin: 0 20rpx;\">\r\n\t\t\t\t\t\t|\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text class=\"level-sub\">\r\n\t\t\t\t\t\t成长值 {{ coachInfo['growthValue'] }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t\t<text class=\"progress-text\">\r\n\t\t\t\t\t还差{{ coachInfo['nextLevelGap'] }}成长值可升至V{{ coachInfo['nextLevel'] }}\r\n\t\t\t\t</text>\r\n\t\t\t\t<view class=\"level-progress-box\">\r\n\t\t\t\t\t<view class=\"level-progress\">\r\n\r\n\t\t\t\t\t\t<view class=\"progress-bar\">\r\n\t\t\t\t\t\t\t<!-- \t<view class=\"progress-fill\" :style=\"{ width: progressWidth }\">\r\n\t\t\t\t\t\t\t</view> -->\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t<view class=\"progress-labels\">\r\n\t\t\t\t\t\t\t<text>\r\n\t\t\t\t\t\t\t\tV1\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t<text>\r\n\t\t\t\t\t\t\t\tV2\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t\t<view class=\"level-badge\" @click=\"viewLevelDetail\">\r\n\t\t\t\t\t\t<text>\r\n\t\t\t\t\t\t\t我的等级\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t</view>\r\n\t\t\t</view>\r\n\r\n\r\n\t\t\t<!-- 3. 我的档案 -->\r\n\t\t\t<view class=\"bs-box\">\r\n\t\t\t\t<view class=\"title-bg-box\">\r\n\t\t\t\t\t<text class=\"texnj-box\">\r\n\t\t\t\t\t\t我的档案\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t\t<view class=\"level-main\">\r\n\t\t\t\t\t<view class=\"action-item\" @click=\"jumpQy\">\r\n\t\t\t\t\t\t<image src=\"/static/myImages/my-qy.png\" style=\"width: 60rpx;height:60rpx;\" mode=\"aspectFit\">\r\n\t\t\t\t\t\t</image>\r\n\t\t\t\t\t\t<text class=\"dib-text\">\r\n\t\t\t\t\t\t\t签约\r\n\t\t\t\t\t\t</text>\r\n\r\n\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t<view class=\"action-item\" style=\"margin-left: 25rpx;\" @click=\"jumpJiey\">\r\n\t\t\t\t\t\t<image src=\"/static/myImages/my-jiey.png\" style=\"width: 60rpx;height:60rpx;\" mode=\"aspectFit\">\r\n\t\t\t\t\t\t</image>\r\n\t\t\t\t\t\t<text class=\"dib-text\">\r\n\t\t\t\t\t\t\t解约\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t\t<view class=\"action-item\" @click=\"jumpQd\">\r\n\t\t\t\t\t\t<image src=\"/static/myImages/my-qd.png\" style=\"width: 60rpx;height:60rpx;\" mode=\"aspectFit\">\r\n\t\t\t\t\t\t</image>\r\n\t\t\t\t\t\t<text class=\"dib-text\">\r\n\t\t\t\t\t\t\t店铺签到\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t\t<view class=\"action-item\" @click=\"jumpGoum\">\r\n\t\t\t\t\t\t<image src=\"/static/myImages/my-goum.png\" style=\"width: 60rpx;height:60rpx;\" mode=\"aspectFit\">\r\n\t\t\t\t\t\t</image>\r\n\t\t\t\t\t\t<text class=\"dib-text\">\r\n\t\t\t\t\t\t\t购买物料\r\n\t\t\t\t\t\t</text>\r\n\r\n\t\t\t\t\t</view>\r\n\t\t\t\t</view>\r\n\t\t\t\t<view class=\"title-bg-box\">\r\n\t\t\t\t\t<view class=\"texnj-box\">\r\n\t\t\t\t\t\t我的工具\r\n\t\t\t\t\t</view>\r\n\t\t\t\t</view>\r\n\t\t\t\t<view class=\"level-main\" style=\"justify-content: space-between; padding: 0 15rpx;\">\r\n\t\t\t\t\t<view class=\"action-item\" @click=\"jumpXuexi\">\r\n\t\t\t\t\t\t<image src=\"/static/myImages/my-xux.png\" style=\"width: 60rpx;height:60rpx;\" mode=\"aspectFit\">\r\n\t\t\t\t\t\t</image>\r\n\t\t\t\t\t\t<text class=\"dib-text\">\r\n\t\t\t\t\t\t\t学习园地\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t\t<view class=\"action-item\">\r\n\t\t\t\t\t\t<image src=\"/static/myImages/my-wt.png\" style=\"width: 60rpx;height:60rpx;\" mode=\"aspectFit\">\r\n\t\t\t\t\t\t</image>\r\n\t\t\t\t\t\t<text class=\"dib-text\">\r\n\t\t\t\t\t\t\t申诉\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t\t<view class=\"action-item\">\r\n\t\t\t\t\t\t<image src=\"/static/myImages/my-yhj.png\" style=\"width: 60rpx;height:60rpx;\" mode=\"aspectFit\">\r\n\t\t\t\t\t\t</image>\r\n\t\t\t\t\t\t<text class=\"dib-text\">\r\n\t\t\t\t\t\t\t定制优惠\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t\t<view class=\"action-item\">\r\n\t\t\t\t\t\t<image src=\"/static/myImages/vipIcon.png\" style=\"width: 70rpx;height:70rpx;\" mode=\"aspectFit\">\r\n\t\t\t\t\t\t</image>\r\n\t\t\t\t\t\t<text class=\"dib-text\">\r\n\t\t\t\t\t\t\tVIP俱乐部\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t</view>\r\n\t\t\t\t<view class=\"level-progress-box\">\r\n\t\t\t\t\t<view class=\"lef-bg-box\" @click=\"jumpLaxin\">\r\n\t\t\t\t\t\t<image src=\"/static/myImages/my-lax.png\" class=\"my-lax\" mode=\"widthFix\">\r\n\t\t\t\t\t\t</image>\r\n\t\t\t\t\t\t<view class=\"conm-box\">\r\n\t\t\t\t\t\t\t<text class=\"max-box\">\r\n\t\t\t\t\t\t\t\t邀请好友赚钱\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t<text class=\"min-box\">\r\n\t\t\t\t\t\t\t\t单次最高可奖200元\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t\t<view class=\"lef-bg-box\" @click=\"jumpMyTeam\">\r\n\t\t\t\t\t\t<image src=\"/static/myImages/my-td.png\" class=\"my-lax\" mode=\"widthFix\">\r\n\t\t\t\t\t\t</image>\r\n\t\t\t\t\t\t<view class=\"conm-box\">\r\n\t\t\t\t\t\t\t<text class=\"max-box\">\r\n\t\t\t\t\t\t\t\t我的团队\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t<text class=\"min-box\">\r\n\t\t\t\t\t\t\t\t团队成员数:100人\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t</view>\r\n\r\n\t\t\t\t<image class=\"hhr-image\" src=\"/static/yaoqInfo/hhr-image.png\" mode=\"widthFix\">\r\n\t\t\t\t</image>\r\n\r\n\t\t\t</view>\r\n\t\t</view>\r\n\t</view>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n\timport { ref, reactive } from 'vue';\r\n\timport { getCoachDetaile } from '@/utils/api/masterInfoApi'\r\n\t// --- 用户信息 ---\r\n\tconst coachInfo = reactive<UTSJSONObject>({\r\n\t\tname: '刘大锤',\r\n\t\tavatar: '/static/testInfo/boy-nickname.png', // 替换为实际头像\r\n\t\tlevel: 30,\r\n\t\tgrowthValue: 50,\r\n\t\tstar_leavl: 3,\r\n\t\tstar_score: 3.0,\r\n\t\tnextLevel: 2,\r\n\t\tnextLevelGap: 15,\r\n\t\tprogressPercent: 75 // (50 / (50+15)) * 100 ≈ 75%\r\n\t});\r\n\r\n\t// computed helpers to satisfy UTS inference rules\r\n\t// convert percent to a fixed rpx width (assuming 750rpx full width)\r\n\t// const progressWidth = computed(() => `${coachInfo.progressPercent * 7.5}rpx`);\r\n\r\n\t// --- 工具列表 ---\r\n\r\n\ttype ToolItem = {\r\n\t\tname : string;\r\n\t\ticon : string;\r\n\t\tcolor : string;\r\n\t};\r\n\r\n\t// avoid generic parameter on ref which earlier triggered an \"interface does not\r\n\t// have constructors\" error; cast the initial value instead.\r\n\tconst tools = ref([\r\n\t\t{ name: '学习园地', icon: 'book', color: '#ff9900' },\r\n\t\t{ name: '问题反馈', icon: 'chat', color: '#52c41a' },\r\n\t\t{ name: '定制优惠', icon: 'wallet', color: '#1890ff' },\r\n\t\t{ name: 'VIP俱乐部', icon: 'vip', color: '#faad14' }\r\n\t] as ToolItem[]);\r\n\r\n\t// --- 方法 ---\r\n\tconst httpGetCoachDetail = async () => {\r\n\t\tconst response = await getCoachDetaile() as UTSJSONObject\r\n\t\tconst code = response[\"code\"] as number\r\n\t\tconst dataObj = response[\"data\"] as UTSJSONObject | null\r\n\t\tif (code != 200 || dataObj == null) {\r\n\t\t\treturn\r\n\t\t}\r\n\t\tcoachInfo.name = dataObj[\"nickname\"] as string\r\n\t\tcoachInfo.avatar = dataObj[\"avatar\"] as string\r\n\t\tcoachInfo.level = dataObj[\"level\"] as number\r\n\t\tcoachInfo.growthValue = dataObj[\"growthValue\"] as number\r\n\t\tcoachInfo.nextLevel = dataObj[\"nextLevel\"] as number\r\n\t\tcoachInfo.nextLevelGap = dataObj[\"nextLevelGap\"] as number\r\n\t\tcoachInfo.progressPercent = dataObj[\"progressPercent\"] as number\r\n\t\tcoachInfo.star_leavl = dataObj[\"star_leavl\"] as number\r\n\t\tcoachInfo.star_score = dataObj[\"star_score\"] as number\r\n\r\n\t}\r\n\r\n\tconst contactService = () => {\r\n\t\tuni.showToast({ title: '联系客服', icon: 'none' });\r\n\t};\r\n\r\n\tconst openSettings = () => {\r\n\t\tuni.navigateTo({\r\n\t\t\turl: '/pages/myEdit/setting'\r\n\t\t});\r\n\t};\r\n\r\n\tconst viewLevelDetail = () => {\r\n\t\tuni.showToast({ title: '查看等级详情', icon: 'none' });\r\n\t};\r\n\r\n\tconst handleToolClick = (tool : ToolItem) => {\r\n\t\tuni.showToast({ title: `点击${tool.name}`, icon: 'none' });\r\n\t};\r\n\t// --- 跳转 ---\r\n\tconst jumpQy = () => {\r\n\t\tuni.navigateTo({\r\n\t\t\turl: '/pages/myEdit/sign'\r\n\t\t});\r\n\t};\r\n\tconst jumpJiey = () => {\r\n\t\tuni.navigateTo({\r\n\t\t\turl: '/pages/myEdit/terminate'\r\n\t\t});\r\n\t};\r\n\tconst jumpQd = () => {\r\n\t\tuni.navigateTo({\r\n\t\t\turl: '/pages/myEdit/signIn'\r\n\t\t});\r\n\t};\r\n\tconst jumpGoum = () => {\r\n\t\tuni.navigateTo({\r\n\t\t\turl: '/pages/myEdit/shoppingRecord'\r\n\t\t});\r\n\t};\r\n\tconst jumpLaxin = () => {\r\n\t\tuni.navigateTo({\r\n\t\t\turl: '/pages/myEdit/inviteRecord'\r\n\t\t});\r\n\t};\r\n\t//跳转到我的团队\r\n\tconst jumpMyTeam = () => {\r\n\t\tuni.navigateTo({\r\n\t\t\turl: '/pages/myEdit/team'\r\n\t\t});\r\n\t};\r\n\tconst jumpYhj = () => {\r\n\t\tuni.navigateTo({\r\n\t\t\turl: '/pages/myEdit/setting'\r\n\t\t});\r\n\t};\r\n\t//跳转到城市合伙人\r\n\tconst jumpPartner = async () => {\r\n\t\tuni.navigateTo({\r\n\t\t\turl: '/pages/masterProject/inviteInfo/partner/index'\r\n\t\t})\r\n\t}\r\n\r\n\t//跳转到用户开通VIP\r\n\tconst goToOpenVip = async () => {\r\n\t\tuni.navigateTo({\r\n\t\t\turl: '/pages/masterProject/masterInfo/vipMember/index'\r\n\t\t})\r\n\t}\r\n\t//跳转到问题反馈\r\n\tconst goToMyCourse = async () => {\r\n\t\tuni.navigateTo({\r\n\t\t\turl: '/pages/masterProject/masterInfo/problemFeedback/index'\r\n\t\t})\r\n\t}\r\n\t//跳转到个人信息\r\n\tconst jumpMasterInfo = async () => {\r\n\t\tuni.navigateTo({\r\n\t\t\turl: '/pages/masterProject/masterInfo/index'\r\n\t\t})\r\n\t}\r\n\t//跳转到我的星级\r\n\tconst jumpStarRating = async () => {\r\n\t\tuni.navigateTo({\r\n\t\t\turl: '/pages/masterProject/masterInfo/starRating/index?star_score'\r\n\t\t})\r\n\t}\r\n\t//跳转到学习园地\r\n\tconst jumpXuexi = () => {\r\n\t\tuni.navigateTo({\r\n\t\t\turl: '/pages/masterProject/inviteInfo/learningCorner/index'\r\n\t\t})\r\n\t}\r\n\tconst inviteFriends = () => {\r\n\t\tuni.showModal({\r\n\t\t\ttitle: '邀请好友',\r\n\t\t\tcontent: '分享链接邀请好友加入,单次最高可获奖励200元!',\r\n\t\t\tsuccess: (res) => {\r\n\t\t\t\tif (res.confirm) {\r\n\t\t\t\t\tuni.showToast({ title: '已生成邀请链接', icon: 'success' });\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\t};\r\n\r\n\tconst viewTeam = () => {\r\n\t\tuni.showToast({ title: '查看团队成员', icon: 'none' });\r\n\t};\r\n\r\n\tconst joinPartner = () => {\r\n\t\tuni.showModal({\r\n\t\t\ttitle: '城市合伙人',\r\n\t\t\tcontent: '全新盈利模式助你创业,立即申请成为城市合伙人!',\r\n\t\t\tsuccess: (res) => {\r\n\t\t\t\tif (res.confirm) {\r\n\t\t\t\t\tuni.showToast({ title: '申请已提交', icon: 'success' });\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\t};\r\n\tonLoad(() => {\r\n\t\thttpGetCoachDetail()\r\n\t})\r\n</script>\r\n\r\n<style scoped>\r\n\t/*\r\n\tUniApp X 默认 page 是 flex-direction: column\r\n\t所以 .page-container 会自动垂直排列子元素\r\n\t*/\r\n\r\n\t.page-container {\r\n\t\tbackground-color: rgba(246, 246, 244, 0.5);\r\n\t}\r\n\r\n\t/* --- 用户头部 --- */\r\n\t.user-header {\r\n\t\tdisplay: flex;\r\n\t\tflex-direction: row;\r\n\t\talign-items: center;\r\n\t\tpadding: 30rpx;\r\n\t\tjustify-content: space-between;\r\n\t}\r\n\r\n\t.avatar {\r\n\t\twidth: 124rpx;\r\n\t\theight: 124rpx;\r\n\t\tborder-radius: 62rpx;\r\n\t\tborder: 2rpx solid #fff;\r\n\t}\r\n\r\n\t.user-info {\r\n\t\tflex-direction: row;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.username {\r\n\t\tfont-size: 32rpx;\r\n\t\tfont-weight: bold;\r\n\t\tcolor: #333;\r\n\t\tmargin: 0 10rpx;\r\n\t}\r\n\r\n\t.badge-row {\r\n\t\tdisplay: flex;\r\n\t\tflex-direction: row;\r\n\t}\r\n\r\n\t.badge {\r\n\t\tfont-size: 22rpx;\r\n\t\tpadding: 4rpx 12rpx;\r\n\t\tborder-radius: 20rpx;\r\n\t\tfont-weight: bold;\r\n\t}\r\n\r\n\t.badge.vip {\r\n\t\tcolor: #ffffff;\r\n\t}\r\n\r\n\t.header-actions {\r\n\t\tdisplay: flex;\r\n\t\tflex-direction: row;\r\n\t}\r\n\r\n\t.action-item {\r\n\t\tdisplay: flex;\r\n\t\talign-items: center;\r\n\r\n\t}\r\n\r\n\t.icon-circle {\r\n\t\twidth: 80rpx;\r\n\t\theight: 80rpx;\r\n\t\tborder-radius: 40rpx;\r\n\t\tbackground-color: #ffffff;\r\n\t\tbox-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);\r\n\t\tdisplay: flex;\r\n\t\talign-items: center;\r\n\t\tjustify-content: center;\r\n\t\tmargin-bottom: 8rpx;\r\n\t}\r\n\r\n\r\n\t/* --- 等级卡片 --- */\r\n\t.level-card {\r\n\t\t/* padding:0 40rpx; */\r\n\t\tposition: relative;\r\n\t\tflex-direction: column;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.level-bg {\r\n\t\tposition: absolute;\r\n\t\twidth: 90%;\r\n\t\tz-index: 1;\r\n\t}\r\n\r\n\t.level-content {\r\n\t\tposition: absolute;\r\n\t\tz-index: 2;\r\n\t\tpadding: 20rpx;\r\n\t\twidth: 90%;\r\n\t}\r\n\r\n\t.level-main {\r\n\t\tdisplay: flex;\r\n\t\tflex-direction: row;\r\n\t\talign-items: center;\r\n\t\tjustify-content: space-around;\r\n\t}\r\n\r\n\t.level-title {\r\n\t\tfont-size: 86rpx;\r\n\t\tcolor: #485575;\r\n\t}\r\n\r\n\t.level-sub {\r\n\t\tfont-size: 36rpx;\r\n\t\tcolor: #424C6C;\r\n\t}\r\n\r\n\t.level-progress-box {\r\n\t\tdisplay: flex;\r\n\t\tflex-direction: row;\r\n\t\talign-items: flex-start;\r\n\t\tjustify-content: space-between;\r\n\t}\r\n\r\n\t.level-progress {\r\n\t\tmargin-bottom: 20rpx;\r\n\t\twidth: 70%;\r\n\t}\r\n\r\n\t.progress-text {\r\n\t\tfont-size: 28rpx;\r\n\t\topacity: 0.8;\r\n\t\tmargin-bottom: 10rpx;\r\n\t}\r\n\r\n\t.progress-bar {\r\n\r\n\t\theight: 12rpx;\r\n\t\tbackground: rgba(255, 255, 255, 0.3);\r\n\t\tborder-radius: 6rpx;\r\n\t\toverflow: hidden;\r\n\t\tmargin-top: 8rpx;\r\n\t}\r\n\r\n\t.progress-fill {\r\n\t\t/* 使用与父容器相同的固定高度 */\r\n\t\theight: 12rpx;\r\n\t\tbackground: #ffffff;\r\n\t\tborder-radius: 6rpx;\r\n\t\ttransition: width 0.3s ease;\r\n\t}\r\n\r\n\t.progress-labels {\r\n\t\tdisplay: flex;\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: space-between;\r\n\t\tfont-size: 22rpx;\r\n\t\topacity: 0.7;\r\n\t}\r\n\r\n\t.level-badge {\r\n\t\tbackground-color: #E9EEF7;\r\n\t\tborder-radius: 14px;\r\n\t\tpadding: 8rpx 16rpx;\r\n\t}\r\n\r\n\t/* --- 章节标题 --- */\r\n\t.bs-box {\r\n\t\tbackground-color: #ffffff;\r\n\t\tborder-radius: 36rpx;\r\n\t\tpadding: 30rpx;\r\n\t\twidth: 100%;\r\n\t\tmargin-top: 30%;\r\n\t}\r\n\r\n\t.title-bg-box {\r\n\t\tdisplay: flex;\r\n\t\talign-items: flex-start;\r\n\t\tmargin: 35rpx 0;\r\n\t}\r\n\r\n\t.texnj-box {\r\n\t\tfont-size: 30rpx;\r\n\t\tfont-weight: 500;\r\n\t\tbackground: linear-gradient(to right, #ffd95aff, #FFFFFF);\r\n\t\tborder-radius: 24rpx;\r\n\t\tpadding: 4rpx 10rpx;\r\n\t\tbackground-size: 50% 100%;\r\n\t\tbackground-repeat: no-repeat;\r\n\t\tbackground-position: 0 50%;\r\n\t}\r\n\r\n\t.lef-bg-box {\r\n\t\twidth: 49%;\r\n\t\tposition: relative;\r\n\t\tmargin: 20rpx 0;\r\n\t}\r\n\r\n\t.my-lax {\r\n\t\twidth: 100%;\r\n\t\t/* position: absolute; */\r\n\r\n\t}\r\n\r\n\t.min-box {\r\n\t\tfont-size: 30rpx;\r\n\t\tcolor: #a8a8a8ff;\r\n\t}\r\n\r\n\t.max-box {\r\n\t\tfont-size: 32rpx;\r\n\t\tcolor: #000000ff;\r\n\t\tfont-weight: bold;\r\n\t}\r\n\r\n\t.conm-box {\r\n\t\tposition: absolute;\r\n\t\tpadding: 28rpx;\r\n\r\n\t}\r\n\r\n\t.hhr-image {\r\n\t\twidth: 100%;\r\n\t}\r\n</style>","import { request } from '../request.uts'\r\n\r\n// 与技师相关的V3接口 | UTS 规范版\r\n// 获取技师钱包信息\r\nexport function getCoachWallteInfo() : Promise<any> {\r\n\treturn request({\r\n\t\turl: \"/api/coach/v3/wallet\",\r\n\t\tmethod: \"GET\"\r\n\t})\r\n}\r\n\r\n// 获取本月账单\r\nexport function getCoachTransRecords(params : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: \"/api/coach/v3/wallet/trans-records\",\r\n\t\tmethod: \"GET\",\r\n\t\tparams: params\r\n\t})\r\n}\r\n\r\n// 路费转出\r\nexport function saveTransInfo(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: \"/api/coach/v3/wallet/travel-withdraw\",\r\n\t\tmethod: \"POST\",\r\n\t\tdata: data\r\n\t})\r\n}\r\n\r\n// 申请提现\r\nexport function createWithdraw(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: \"/api/coach/v3/wallet/withdraw\",\r\n\t\tmethod: \"POST\",\r\n\t\tdata: data\r\n\t})\r\n}\r\n\r\n// 提现记录列表\r\nexport function recordsList(params : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: \"/api/coach/v3/wallet/withdraw-records\",\r\n\t\tmethod: \"GET\",\r\n\t\tparams: params\r\n\t})\r\n}\r\n\r\n// 技师确认收款\r\nexport function withdrawalCoachInfo(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: \"/api/coach/v3/wallet/confirm-withdraw\",\r\n\t\tmethod: \"POST\",\r\n\t\tdata: data\r\n\t})\r\n}\r\n\r\n// 获取本月邀请的技师/用户佣金账单明细\r\nexport function getCoachYjRecords(params : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: \"/api/coach/v3/team/team-records\",\r\n\t\tmethod: \"GET\",\r\n\t\tparams: params\r\n\t})\r\n}\r\n// 技师缴纳保证金充值\r\nexport function deposit(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: \"/api/coach/v3/pledge/recharge\",\r\n\t\tmethod: \"POST\",\r\n\t\tdata: data\r\n\t})\r\n}\r\n\r\n// 技师保证金账单明细\r\nexport function getDepositBill(params : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: \"/api/coach/v3/pledge/getAssure\",\r\n\t\tmethod: \"GET\",\r\n\t\tparams: params\r\n\t})\r\n}","<template>\r\n\t<view class=\"page-container\">\r\n\r\n\t\t<!-- 1. 资产卡片区域 -->\r\n\t\t<view class=\"income-section \">\r\n\t\t\t<view class=\"asset-card\">\r\n\t\t\t\t<!-- 总资产 -->\r\n\t\t\t\t<view class=\"total-asset-section row-between\">\r\n\t\t\t\t\t<view>\r\n\t\t\t\t\t\t<view class=\"row-start\">\r\n\t\t\t\t\t\t\t<text class=\"label\">\r\n\t\t\t\t\t\t\t\t我的资产(元)\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t<u-icon v-if=\"isShowAmount\" name=\"view\" :size=\"20\" @click=\"toggleShowAmount\" />\r\n\t\t\t\t\t\t\t<u-icon v-else name=\"view_off\" :size=\"20\" @click=\"toggleShowAmount\" />\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t<text class=\"amount\" style=\"margin-top: 20rpx;\">\r\n\t\t\t\t\t\t\t{{ isShowAmount ? totalAsset : '***' }}\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t\t<view class=\"refresh-btn row-center\" @click=\"refreshData\">\r\n\t\t\t\t\t\t<u-icon name=\"sync\" :size=\"18\" />\r\n\r\n\t\t\t\t\t\t<text>\r\n\t\t\t\t\t\t\t刷新\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t</view>\r\n\t\t\t</view>\r\n\t\t\t<!-- 累计收益 & 打车费 -->\r\n\r\n\t\t\t<image class=\"bg-image\" src=\"/static/imagesInfo/zh-bg.png\">\r\n\t\t\t</image>\r\n\t\t\t<view class=\"detail-container row-start \">\r\n\t\t\t\t<!-- 左侧:累计收益 -->\r\n\t\t\t\t<view class=\"income-item column \">\r\n\t\t\t\t\t<view class=\"income-header-content\">\r\n\t\t\t\t\t\t<view class=\"row-start\" style=\"margin-top: 30rpx;\">\r\n\t\t\t\t\t\t\t<text class=\"income-label\">\r\n\t\t\t\t\t\t\t\t累计收益(元)\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t<u-icon name=\"hollowquery\" :size=\"16\" color=\"#999\" @click=\"openIncomePopup\" />\r\n\t\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t\t<view class=\"income-main row-between\">\r\n\t\t\t\t\t\t\t<text class=\"income-value\">\r\n\t\t\t\t\t\t\t\t{{ cumulativeIncome }}\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t<view class=\"withdraw-btn\" @click=\"handleWithdraw('income')\">\r\n\t\t\t\t\t\t\t\t提现\r\n\t\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t\t<view class=\"income-detail row-start\">\r\n\t\t\t\t\t\t<image class=\"jine-bg\" src=\"/static/imagesInfo/jine-bg.png\" mode=\"widthFix\">\r\n\t\t\t\t\t\t</image>\r\n\t\t\t\t\t\t<view class=\"detail-item column-center\">\r\n\t\t\t\t\t\t\t<text class=\"detail-label\">\r\n\t\t\t\t\t\t\t\t冻结(元)\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t<text class=\"detail-value\">\r\n\t\t\t\t\t\t\t\t{{ frozenIncome }}\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t<view class=\"divider\">\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t<view class=\"detail-item column-center\">\r\n\t\t\t\t\t\t\t<text class=\"detail-label\">\r\n\t\t\t\t\t\t\t\t可提现(元)\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t<text class=\"detail-value\">\r\n\t\t\t\t\t\t\t\t{{ availableIncome }}\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t</view>\r\n\r\n\t\t\t\t<!-- 右侧:打车费 -->\r\n\t\t\t\t<view class=\"income-item column \" style=\"padding-left: 20rpx;\">\r\n\r\n\t\t\t\t\t<view class=\" row-start\" style=\"margin-top: 30rpx;\">\r\n\t\t\t\t\t\t<text class=\"income-label\">\r\n\t\t\t\t\t\t\t打车费(元)\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t<u-icon name=\"hollowquery\" :size=\"16\" color=\"#999\" @click=\"openTaxiPopup\" />\r\n\t\t\t\t\t</view>\r\n\t\t\t\t\t<view class=\"income-main row-between\">\r\n\t\t\t\t\t\t<text class=\"income-value\">\r\n\t\t\t\t\t\t\t{{ taxiFee }}\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t<view class=\"transfer-btn\" @click=\"handleTransfer('taxi')\">\r\n\t\t\t\t\t\t\t转出\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t<view class=\"income-detail row-start\">\r\n\t\t\t\t\t\t<image class=\"jine-bg\" src=\"/static/imagesInfo/jine-bg.png\" mode=\"widthFix\">\r\n\t\t\t\t\t\t</image>\r\n\t\t\t\t\t\t<view class=\"detail-item column-center\">\r\n\t\t\t\t\t\t\t<text class=\"detail-label\">\r\n\t\t\t\t\t\t\t\t冻结(元)\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t<text class=\"detail-value\">\r\n\t\t\t\t\t\t\t\t{{ frozenTaxi }}\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t<view class=\"divider\">\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t<view class=\"detail-item column-center\">\r\n\t\t\t\t\t\t\t<text class=\"detail-label\">\r\n\t\t\t\t\t\t\t\t可使用(元)\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t<text class=\"detail-value\">\r\n\t\t\t\t\t\t\t\t{{ availableTaxi }}\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t</view>\r\n\t\t\t</view>\r\n\t\t\t<view class=\"record-entry row-between\" @click=\"viewWithdrawRecords\">\r\n\t\t\t\t<text>\r\n\t\t\t\t\t提现记录\r\n\t\t\t\t</text>\r\n\t\t\t\t<text>\r\n\t\t\t\t\t>\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\r\n\t\t\t</view>\r\n\r\n\t\t\t<!-- 提现记录入口 -->\r\n\r\n\r\n\t\t\t<!-- 2. 本月账单标题 -->\r\n\t\t\t<view class=\"bill-header row-between\">\r\n\t\t\t\t<text class=\"bill-title\">\r\n\t\t\t\t\t本月账单\r\n\t\t\t\t</text>\r\n\t\t\t\t<text class=\"view-all\" @click=\"viewAllBills\">\r\n\t\t\t\t\t查看全部\r\n\t\t\t\t</text>\r\n\t\t\t</view>\r\n\r\n\t\t\t<!-- 3. 账单列表 -->\r\n\t\t\t<view class=\"bill-list column\">\r\n\t\t\t\t<view v-for=\"(bill, idx) in bills\" :key=\"idx\" class=\"bill-card column\">\r\n\r\n\t\t\t\t\t<!-- 订单号行 -->\r\n\t\t\t\t\t<view class=\"order-id-row row-between\">\r\n\t\t\t\t\t\t<text class=\"split-type\">\r\n\t\t\t\t\t\t\t订单号:{{ bill.orderId }}\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t<text>\r\n\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t\t<!-- 项目与金额 -->\r\n\t\t\t\t\t\t<view class=\"project-amount-row row-between\">\r\n\t\t\t\t\t\t\t<text class=\"project-name\">\r\n\t\t\t\t\t\t\t\t{{ bill.projectName }}\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t<text :class=\"['amount', bill.amount > 0 ? 'positive' : 'negative']\">\r\n\t\t\t\t\t\t\t\t{{ bill.amount > 0 ? '+' : '' }}{{ Math.abs(bill.amount).toFixed(2) }}\r\n\t\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t\t\t<!-- 分成说明 -->\r\n\t\t\t\t\t\t\t<view class=\"split-info row-between\">\r\n\t\t\t\t\t\t\t\t<text class=\"split-type\">\r\n\t\t\t\t\t\t\t\t\t{{ bill.splitType }}\r\n\t\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t\t<text class=\"split-type\">\r\n\t\t\t\t\t\t\t\t\t{{ bill.splitDetail }}\r\n\t\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t\t\t<!-- 记录时间 -->\r\n\t\t\t\t\t\t\t<view class=\"time-row row-between\">\r\n\t\t\t\t\t\t\t\t<text class=\"split-type\">\r\n\t\t\t\t\t\t\t\t\t记录时间\r\n\t\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t\t<text class=\"split-type\">\r\n\t\t\t\t\t\t\t\t\t{{ bill.recordTime }}\r\n\t\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t</view>\r\n\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t</view>\r\n\r\n\t\t\t\t</view>\r\n\r\n</template>\r\n\r\n<script setup lang=\"uts\">\r\n\timport { ref } from 'vue';\r\n\timport { getCoachWallteInfo, getCoachTransRecords } from '@/utils/api/account'\r\n\t// --- 数据定义 ---\r\n\tconst totalAsset = ref('0');\r\n\tconst cumulativeIncome = ref('0');\r\n\tconst frozenIncome = ref('0');\r\n\tconst availableIncome = ref('0');\r\n\tconst taxiFee = ref('0');\r\n\tconst frozenTaxi = ref('0');\r\n\tconst availableTaxi = ref('0');\r\n\r\n\tconst isShowAmount = ref(true);\r\n\r\n\ttype BillItem = {\r\n\t\torderId : string;\r\n\t\tprojectName : string;\r\n\t\tamount : number;\r\n\t\tsplitType : string;\r\n\t\tsplitDetail : string;\r\n\t\trecordTime : string;\r\n\t};\r\n\r\n\tconst bills = ref([\r\n\t\t\t{\r\n\t\t\t\torderId: '202506091311123009874638',\r\n\t\t\t\tprojectName: '中式推拿',\r\n\t\t\t\tamount: 170.00,\r\n\t\t\t\tsplitType: '首单分成',\r\n\t\t\t\tsplitDetail: '基本套餐车费收入 x90%=20\\n项目套餐收入 x50%=150',\r\n\t\t\t\trecordTime: '2025-06-09 13:58'\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\torderId: '202506091311123009874638',\r\n\t\t\t\tprojectName: '中式推拿',\r\n\t\t\t\tamount: 150.00,\r\n\t\t\t\tsplitType: '加钟分成',\r\n\t\t\t\tsplitDetail: '项目套餐收入 x71%+(70%+等级v1)=150',\r\n\t\t\t\trecordTime: '2025-06-09 13:58'\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\torderId: '202506091311123009874638',\r\n\t\t\t\tprojectName: '中式推拿订单退款',\r\n\t\t\t\tamount: -150.00,\r\n\t\t\t\tsplitType: '首单分成',\r\n\t\t\t\tsplitDetail: '基本套餐车费收入 x90%=20\\n项目套餐收入 x50%=150',\r\n\t\t\t\trecordTime: '2025-06-09 13:58'\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\torderId: '',\r\n\t\t\t\tprojectName: '打车费转出',\r\n\t\t\t\tamount: -50.00,\r\n\t\t\t\tsplitType: '分成',\r\n\t\t\t\tsplitDetail: '打车费转出刘大锤账户:45.00元\\n费率:0.1 手续费:5.00元',\r\n\t\t\t\trecordTime: '2025-06-09 13:58'\r\n\t\t\t}\r\n\t\t] as BillItem[]); // 如果自动推断不准,可以在末尾加 'as BillItem[]' 进行断言\r\n\r\n\t// --- 方法定义 ---\r\n\tconst walletInfo = ref<UTSJSONObject | null>(null)\r\n\r\n\tconst httpGetWalletInfo = async () => {\r\n\t\ttry {\r\n\t\t\tconst res = await getCoachWallteInfo() as UTSJSONObject;\r\n\t\t\tconst code = res[\"code\"] as number;\r\n\t\t\tconst data = res[\"data\"] as UTSJSONObject;\r\n\t\t\tif (code === 200) {\r\n\t\t\t\twalletInfo.value = data;\r\n\t\t\t\t// 赋值到页面变量\r\n\t\t\t\ttotalAsset.value = data.total_balance as string ;\r\n\t\t\t\tcumulativeIncome.value = data.total_income as string ;\r\n\t\t\t\tfrozenIncome.value = data.frozen_amount as string ;\r\n\t\t\t\tavailableIncome.value = data.available_balance as string;\r\n\t\t\t\ttaxiFee.value = data.travel_balance as string ;\r\n\t\t\t\tfrozenTaxi.value = data.travel_frozen_balance as string ;\r\n\t\t\t\tavailableTaxi.value = (parseFloat(data.travel_balance as string ) - parseFloat(data.travel_frozen_balance as string )).toFixed(2);\r\n\t\t\t} else {\r\n\t\t\t\tuni.showToast({\r\n\t\t\t\t\t\ttitle: '获取钱包信息失败',\r\n\t\t\t\t\t\ticon: 'none'\r\n\t\t\t\t\t});\r\n\t\t\t}\r\n\t\t} catch (err : any) {\r\n\t\t\tconsole.error('获取技师钱包信息异常', err);\r\n\t\t\tuni.showToast({\r\n\t\t\t\t\ttitle: '请求失败',\r\n\t\t\t\t\ticon: 'none'\r\n\t\t\t\t});\r\n\t\t}\r\n\t};\r\n\t// 获取本月账单接口\r\n\tconst billRecords = ref<any[]>([]);\r\n\r\n\tconst httpGetBillRecords = async (params: UTSJSONObject) => {\r\n\t\ttry {\r\n\t\t\tconst res = await getCoachTransRecords(params) as UTSJSONObject;\r\n\t\t\tconst code = res[\"code\"] as number;\r\n\t\t\tconst data = res[\"data\"] as any[];\r\n\t\t\tif (code == 200) {\r\n\t\t\t\tbillRecords.value = data;\r\n\t\t\t} else {\r\n\t\t\t\tuni.showToast({\r\n\t\t\t\t\t\ttitle: '获取本月账单失败',\r\n\t\t\t\t\t\ticon: 'none'\r\n\t\t\t\t\t});\r\n\t\t\t}\r\n\t\t} catch (err : any) {\r\n\t\t\tconsole.error('获取本月账单异常', err);\r\n\t\t\tuni.showToast({\r\n\t\t\t\t\ttitle: '请求失败,请稍后重试',\r\n\t\t\t\t\ticon: 'none'\r\n\t\t\t\t});\r\n\t\t}\r\n\t};\r\n\tconst refreshData = () => {\r\n\t\tuni.showLoading({ title: '刷新中...' });\r\n\t\tsetTimeout(() => {\r\n\t\t\t\tuni.hideLoading();\r\n\t\t\t\tuni.showToast({ title: '刷新成功', icon: 'success' });\r\n\t\t\t\thttpGetWalletInfo();\r\n\t\t\t\thttpGetBillRecords({});\r\n\t\t\t}, 800);\r\n\t};\r\n\r\n\tconst handleWithdraw = (type : string) => {\r\n\t\tconst amount = type === 'income' ? availableIncome.value : '0';\r\n\t\tuni.showModal({\r\n\t\t\t\ttitle: '提现确认',\r\n\t\t\t\tcontent: `确定要提现 ${amount} 元吗?`,\r\n\t\t\t\tsuccess: (res) => {\r\n\t\t\t\t\tif (res.confirm) {\r\n\t\t\t\t\t\tuni.navigateTo({\r\n\t\t\t\t\t\t\t\turl: '/pages/account/withdraw'\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t};\r\n\r\n\tconst handleTransfer = (type : string) => {\r\n\t\tuni.navigateTo({\r\n\t\t\t\turl: '/pages/account/transfer'\r\n\t\t\t});\r\n\t};\r\n\r\n\tconst viewWithdrawRecords = () => {\r\n\t\tuni.showToast({ title: '查看提现记录', icon: 'none' });\r\n\t};\r\n\r\n\tconst viewAllBills = () => {\r\n\t\tuni.navigateTo({\r\n\t\t\t\turl: '/pages/account/bill-list'\r\n\t\t\t});\r\n\t};\r\n\r\n\r\n\tconst toggleShowAmount = () => {\r\n\t\tconsole.log('toggleShowAmount', isShowAmount.value);\r\n\t\tisShowAmount.value = !isShowAmount.value;\r\n\t};\r\n\r\n\tconst openIncomePopup = () => {\r\n\t\tuni.showModal({\r\n\t\t\t\ttitle: '我的收益',\r\n\t\t\t\tcontent: '我的收益包含订单分成、加钟收益+佣金收益+红包收益+车费收益。\\n\\n特殊说明:\\n1、红包收益是商户拉新用户时平台直接奖励的,直接进入可提现余额,无冻结情况。\\n2、未到账、提现中等金额属于冻结余额。',\r\n\t\t\t\tshowCancel: false,\r\n\t\t\t\tconfirmText: '我知道了'\r\n\t\t\t});\r\n\t};\r\n\r\n\tconst openTaxiPopup = () => {\r\n\t\tuni.showModal({\r\n\t\t\t\ttitle: '车费说明',\r\n\t\t\t\tcontent: '1、车费主要是用户在小叮当下支付的打车费(不包含公交车费)将会进入商户的打车收益中。\\n\\n2、打车费可以转到我的收益里提现,提现平台将收取10%的手续费。\\n\\n3、车费收入为100%商户个人收入,长期以来一直是平台代商户缴纳该部分的个人经营所得税,技师提现打车费余额,平台将会代收10%的税费扣款。\\n\\n4、当商户长时间不接单时,打车费余额存在负数时,将优先将技师的提现余额进行抵扣,达到冲正效果。\\n\\n5、单程车费不超过500元,超出部分需要技师个人承担车费。',\r\n\t\t\t\tshowCancel: false,\r\n\t\t\t\tconfirmText: '我知道了'\r\n\t\t\t});\r\n\t};\r\n\r\n\tonLoad(() => {\r\n\t\t\thttpGetWalletInfo();\r\n\t\t\thttpGetBillRecords({});\r\n\t\t});\r\n\r\n</script>\r\n\r\n<style>\r\n\t/*\r\n\t⚠️ UniApp X 样式规范:\r\n\t1. 不写 display: flex (view 默认就是)\r\n\t2. 不写 display: block/inline-block\r\n\t3. 布局靠 flex-direction (默认 column, 需 row 时手动改)\r\n\t4. 不写 border-radius: 50% (用具体数值)\r\n\t5. 只用类名选择器\r\n\t*/\r\n\r\n\t/* --- 辅助布局类 (核心) --- */\r\n\t.row-between {\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: space-between;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.row-start {\r\n\t\tflex-direction: row;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.row-center {\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: center;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.column {\r\n\t\tflex-direction: column;\r\n\t}\r\n\r\n\t.column-center {\r\n\t\tflex-direction: column;\r\n\t\tjustify-content: center;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t/* --- 页面容器 --- */\r\n\t.page-container {\r\n\t\tbackground-color: rgba(246, 246, 244, 0.5);\r\n\t\tpadding-bottom: 40rpx;\r\n\t\tpadding: 20rpx;\r\n\t}\r\n\r\n\t/* --- 资产卡片 --- */\r\n\t.asset-card {\r\n\t\t/* background: linear-gradient(to right, rgba(255, 249, 225, 1), rgba(255, 241, 191, 1));\r\n\t\tmargin: 20rpx;\r\n\t\tborder-radius: 16rpx;\r\n\t\tpadding: 30rpx;\r\n\t\tbox-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);\r\n\t\t*/\r\n\t\tpadding: 0 20rpx;\r\n\t}\r\n\r\n\t.total-asset-section {\r\n\t\tbackground: linear-gradient(to bottom, rgba(253, 252, 246, 1) ,rgba(254, 249, 234, 1));\r\n\t\tpadding: 30rpx 20rpx 20rpx;\r\n\t\tborder-radius: 16rpx 16rpx 0 0;\r\n\t\tbox-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);\r\n\t} rgba(254, 249, 234, 1)\r\n\r\n\t.label {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #666;\r\n\t}\r\n\r\n\r\n\t.amount {\r\n\t\tfont-size: 48rpx;\r\n\t\tfont-weight: bold;\r\n\t\tcolor: #333;\r\n\t}\r\n\r\n\t.refresh-btn {\r\n\t\tpadding: 10rpx 20rpx;\r\n\t\tborder-radius: 30rpx;\r\n\t\tborder: 1rpx solid #ddd;\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #333;\r\n\t}\r\n\r\n\t/* 收益分区 */\r\n\t.income-section {\r\n\t\t/* gap: 30rpx; */\r\n\t\tmargin-bottom: 20rpx;\r\n\t\tposition: relative;\r\n\t}\r\n\r\n\t.bg-image {\r\n\t\twidth: 100%;\r\n\t\theight: 400rpx;\r\n\t\tposition: absolute;\r\n\t\ttop: 28%;\r\n\t\tleft: 0;\r\n\t}\r\n\t.detail-container{\r\n\t\tpadding:0 20rpx 20rpx;\r\n\t}\r\n\t.income-item {\r\n\t\tflex: 1;\r\n\t\t/* gap: 15rpx; */\r\n\t}\r\n\r\n\r\n\t.income-label {\r\n\t\tfont-size: 26rpx;\r\n\t}\r\n\r\n\t.income-main {\r\n\t\tmargin-top:20rpx;\r\n\t}\r\n\r\n\t.income-value {\r\n\t\tfont-size: 40rpx;\r\n\t\tfont-weight: bold;\r\n\t\tcolor: #333;\r\n\t}\r\n\r\n\t.withdraw-btn,\r\n\t.transfer-btn {\r\n\t\tfont-size: 28rpx;\r\n\t\tpadding: 6rpx 22rpx;\r\n\t\tborder-radius: 26rpx;\r\n\t\tbackground: #FFFCEE;\r\n\t\tborder: 1rpx solid;\r\n\t}\r\n\r\n\t.withdraw-btn {\r\n\t\tcolor: #111111ff;\r\n\t\tborder-color: #fff;\r\n\t}\r\n\r\n\t.jine-bg {\r\n\t\twidth: 320rpx;\r\n\t\theight: 100%;\r\n\t\tposition: absolute;\r\n\t\ttop: 0;\r\n\t\tleft: 0;\r\n\r\n\t}\r\n\t.transfer-btn {\r\n\t\tcolor: #101010ff;\r\n\t\tborder-color: #fff;\r\n\t}\r\n\r\n\t/* 明细部分 */\r\n\t.income-detail {\r\n\t\tpadding: 20rpx;\r\n\t\tposition: relative;\r\n\t\tmargin-top: 10rpx;\r\n\t\tjustify-content: space-between;\r\n\t}\r\n\r\n\t.income-header-content {\r\n\r\n\t\tpadding: 0 20rpx 0 10rpx;\r\n\t\tborder-right-width: 2rpx;\r\n\t\tborder-right-color: #979797;\r\n\t\tborder-right-style: solid;\r\n\t}\r\n\r\n\t.detail-label {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #666;\r\n\t}\r\n\r\n\t.detail-value {\r\n\t\t/* font-size: 28rpx; */\r\n\t\tfont-weight: bold;\r\n\t}\r\n\r\n\r\n\t.divider {\r\n\t\twidth: 1rpx;\r\n\t\tbackground: #ddd;\r\n\t\tmargin: 0 10rpx;\r\n\t}\r\n\r\n\t/* 提现记录入口 */\r\n\t.record-entry {\r\n\t\tpadding: 20rpx 30rpx 30rpx ;\r\n\t\tfont-size: 28rpx;\r\n\t\tcolor: #333;\r\n\t\t/* background: #fff; */\r\n\t}\r\n\r\n\t/* --- 账单标题 --- */\r\n\t.bill-header {\r\n\t\tpadding: 0 30rpx;\r\n\t\t/* margin-top: 20rpx; */\r\n\t}\r\n\r\n\r\n\t.view-all {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #666;\r\n\t}\r\n\r\n\t/* --- 账单列表 --- */\r\n\t.bill-list {\r\n\t\tpadding: 0 20rpx;\r\n\t\t/* gap: 20rpx; */\r\n\t}\r\n\r\n\t.bill-card {\r\n\t\tbackground: #ffffff;\r\n\t\tborder-radius: 20rpx;\r\n\t\tpadding: 30rpx;\r\n\t\tbox-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);\r\n\t\tmargin-top: 20rpx;\r\n\t}\r\n\r\n\t.order-id-row {\r\n\t\tfont-size: 26rpx;\r\n\t\tpadding: 10rpx 0 20rpx 0;\r\n\t\tborder-bottom: 1rpx solid #eee;\r\n\t}\r\n\r\n\t.project-amount-row {\r\n\t\tmargin-top: 20rpx;\r\n\t}\r\n\r\n\t.project-name {\r\n\t\tfont-size: 30rpx;\r\n\t}\r\n\r\n\t.amount.positive {\r\n\t\tcolor: #ff4d4f;\r\n\t\tfont-size: 32rpx;\r\n\t}\r\n\r\n\t.amount.negative {\r\n\t\tcolor: #333;\r\n\t\tfont-size: 32rpx;\r\n\t}\r\n\r\n\t.split-info {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #999;\r\n\t\tline-height: 1.4;\r\n\t}\r\n\r\n\t.split-type {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #999;\r\n\t}\r\n\r\n\t.time-row {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #999;\r\n\t}\r\n</style>","<template>\n\n\t<scroll-view class=\"page-scroll\">\n\n\t\t<view class=\"page\">\n\t\t\t<view class=\"hero-card\">\n\t\t\t\t<text class=\"hero-title\">接单时间设置</text>\n\t\t\t\t<text class=\"hero-desc\">按半小时粒度安排可接单时间,黄色卡片表示当前已开启。</text>\n\t\t\t</view>\n\t\t\t<view class=\"toolbar\">\n\t\t\t\t<view class=\"toolbar-button\" @click=\"toggleAllTime\">\n\t\t\t\t\t<text class=\"toolbar-button-text\">{{ allSelected ? '取消全选' : '全部可接单' }}</text>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"toolbar-meta\">\n\t\t\t\t\t<text class=\"toolbar-meta-text\">已选 {{ timeItems.filter((item : TimeItem) : boolean => item.selected).length }} 段</text>\n\t\t\t\t</view>\n\t\t\t</view>\n\n\t\t\t<view class=\"grid\">\n\t\t\t\t<view v-for=\"item in timeItems\" :key=\"item.startTime\" class=\"time-card\" :class=\"item.selected ? 'time-card-active' : 'time-card-idle'\" @click=\"toggleTimeItem(item.startTime)\">\n\t\t\t\t\t<text class=\"time-card-time\" :class=\"item.selected ? 'time-card-time-active' : 'time-card-time-idle'\">{{ item.startTime }}</text>\n\t\t\t\t\t<text class=\"time-card-state\" :class=\"item.selected ? 'time-card-time-active' : 'time-card-time-idle'\">{{ item.selected ? '可接单' : '休息' }}</text>\n\t\t\t\t</view>\n\t\t\t</view>\n\n\t\t\t<view class=\"footer-button\" @click=\"saveTimeSetting\">\n\t\t\t\t<text class=\"footer-button-text\">保存设置</text>\n\t\t\t</view>\n\t\t</view>\n\n\t</scroll-view>\n\n</template>\n\n<script setup lang=\"uts\">\n\timport { computed, ref } from 'vue'\n\timport { getWorkTimeSetting, editWorkTimeSetting } from '@/utils/api/workbenches.uts'\n\n\ttype TimeItem = {\n\t\tstartTime: string\n\t\tendTime: string\n\t\tselected: boolean\n\t}\n\n\tconst timeItems = ref<TimeItem[]>([])\n\n\tconst buildTimeItems = () : TimeItem[] => {\n\t\tconst result : TimeItem[] = []\n\t\tfor (let i = 0; i < 48; i++) {\n\t\t\tconst startHour = Math.floor(i / 2)\n\t\t\tconst startMinute = i % 2 == 0 ? '00' : '30'\n\t\t\tlet endHour = Math.floor((i + 1) / 2)\n\t\t\tlet endMinute = (i + 1) % 2 == 0 ? '00' : '30'\n\t\t\tif (endHour >= 24) {\n\t\t\t\tendHour = 24\n\t\t\t\tendMinute = '00'\n\t\t\t}\n\t\t\tconst startTime = `${startHour < 10 ? '0' : ''}${startHour}:${startMinute}`\n\t\t\tconst endTime = `${endHour < 10 ? '0' : ''}${endHour}:${endMinute}`\n\t\t\tresult.push({\n\t\t\t\tstartTime: startTime,\n\t\t\t\tendTime: endTime,\n\t\t\t\tselected: false,\n\t\t\t})\n\t\t}\n\t\treturn result\n\t}\n\n\ttimeItems.value = buildTimeItems()\n\n\tconst allSelected = computed(() : boolean => {\n\t\treturn timeItems.value.length > 0 && timeItems.value.every((item : TimeItem) : boolean => item.selected)\n\t})\n\n\tconst toggleTimeItem = (startTime : string) : void => {\n\t\tfor (let i = 0; i < timeItems.value.length; i++) {\n\t\t\tconst item = timeItems.value[i]\n\t\t\tif (item.startTime == startTime) {\n\t\t\t\titem.selected = !item.selected\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tconst toggleAllTime = () : void => {\n\t\tconst nextSelected = !allSelected.value\n\t\tfor (let i = 0; i < timeItems.value.length; i++) {\n\t\t\ttimeItems.value[i].selected = nextSelected\n\t\t}\n\t}\n\n\tconst applyServerRanges = (ranges : UTSArray<UTSJSONObject> | null) : void => {\n\t\tconst freshItems = buildTimeItems()\n\t\tif (ranges != null) {\n\t\t\tfor (let i = 0; i < freshItems.length; i++) {\n\t\t\t\tconst item = freshItems[i]\n\t\t\t\tfor (let j = 0; j < ranges.length; j++) {\n\t\t\t\t\tconst range = ranges[j]\n\t\t\t\t\tconst startTime = (range['start_time'] as string | null) ?? ''\n\t\t\t\t\tconst endTime = (range['end_time'] as string | null) ?? ''\n\t\t\t\t\tif (item.startTime == startTime && item.endTime == endTime) {\n\t\t\t\t\t\titem.selected = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\ttimeItems.value = freshItems\n\t}\n\n\tconst loadTimeSetting = async () : Promise<void> => {\n\t\ttry {\n\t\t\tconst response = await getWorkTimeSetting() as UTSJSONObject\n\t\t\tconst code = (response['code'] as number | null) ?? -1\n\t\t\tif (code != 0 && code != 200) {\n\t\t\t\tapplyServerRanges(null)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst data = (response['data'] as UTSJSONObject | null)\n\t\t\tconst ranges = (data?.['time_ranges'] as UTSArray<UTSJSONObject> | null)\n\t\t\tapplyServerRanges(ranges)\n\t\t} catch (error) {\n\t\t\tapplyServerRanges(null)\n\t\t}\n\t}\n\n\tconst saveTimeSetting = async () : Promise<void> => {\n\t\tconst selectedRanges : UTSArray<UTSJSONObject> = []\n\t\tfor (let i = 0; i < timeItems.value.length; i++) {\n\t\t\tconst item = timeItems.value[i]\n\t\t\tif (item.selected) {\n\t\t\t\tselectedRanges.push({\n\t\t\t\t\tstart_time: item.startTime,\n\t\t\t\t\tend_time: item.endTime,\n\t\t\t\t} as UTSJSONObject)\n\t\t\t}\n\t\t}\n\t\tif (selectedRanges.length == 0) {\n\t\t\tuni.showToast({ title: '请至少选择一个时间段', icon: 'none' })\n\t\t\treturn\n\t\t}\n\t\ttry {\n\t\t\tconst response = await editWorkTimeSetting({\n\t\t\t\ttime_ranges: selectedRanges,\n\t\t\t} as UTSJSONObject) as UTSJSONObject\n\t\t\tconst code = (response['code'] as number | null) ?? -1\n\t\t\tuni.showToast({\n\t\t\t\ttitle: code == 0 || code == 200 ? '保存成功' : '保存失败',\n\t\t\t\ticon: 'none',\n\t\t\t})\n\t\t} catch (error) {\n\t\t\tuni.showToast({ title: '保存失败,请重试', icon: 'none' })\n\t\t}\n\t}\n\n\tonLoad(() => {\n\t\tloadTimeSetting()\n\t})\n</script>\n\n<style>\n\t.page-scroll {\n\t\tflex: 1;\n\t}\n\t.page {\n\t\tmin-height: 1000rpx;\n\t\tpadding: 24rpx;\n\t\tbox-sizing: border-box;\n\t\tbackground-color: #fff8e8;\n\t\tflex-direction: column;\n\t}\n\t.hero-card {\n\t\tpadding: 28rpx;\n\t\tborder-radius: 28rpx;\n\t\tbackground-color: #ffe68a;\n\t\tflex-direction: column;\n\t}\n\t.hero-title {\n\t\tfont-size: 38rpx;\n\t\tfont-weight: 700;\n\t\tcolor: #3d3528;\n\t}\n\t.hero-desc {\n\t\tmargin-top: 10rpx;\n\t\tfont-size: 24rpx;\n\t\tline-height: 34rpx;\n\t\tcolor: #6f6047;\n\t}\n\t.toolbar {\n\t\tmargin-top: 20rpx;\n\t\tflex-direction: row;\n\t\talign-items: center;\n\t\tjustify-content: space-between;\n\t\tmargin-bottom: 24rpx;\n\t}\n\t.toolbar-button {\n\t\tpadding: 18rpx 28rpx;\n\t\tborder-radius: 18rpx;\n\t\tbackground-color: #ffdb5a;\n\t\tflex-direction: row;\n\t\tjustify-content: center;\n\t\talign-items: center;\n\t}\n\t.toolbar-meta {\n\t\tpadding-left: 20rpx;\n\t\tpadding-right: 20rpx;\n\t\theight: 64rpx;\n\t\tborder-radius: 18rpx;\n\t\tbackground-color: #ffffff;\n\t\tflex-direction: row;\n\t\tjustify-content: center;\n\t\talign-items: center;\n\t}\n\t.toolbar-meta-text {\n\t\tfont-size: 24rpx;\n\t\tcolor: #7d7261;\n\t}\n\t.toolbar-button-text {\n\t\tfont-size: 28rpx;\n\t\tfont-weight: 700;\n\t\tcolor: #3d3528;\n\t}\n\t.grid {\n\t\tflex-direction: row;\n\t\tflex-wrap: wrap;\n\t\tjustify-content: space-between;\n\t}\n\t.time-card {\n\t\twidth: 158rpx;\n\t\theight: 104rpx;\n\t\tmargin-bottom: 18rpx;\n\t\tborder-radius: 18rpx;\n\t\tbox-sizing: border-box;\n\t\tflex-direction: column;\n\t\tjustify-content: center;\n\t\talign-items: center;\n\t}\n\t.time-card-active {\n\t\tbackground-color: #fff6d8;\n\t\tborder-width: 2rpx;\n\t\tborder-style: solid;\n\t\tborder-color: #ffdb5a;\n\t}\n\t.time-card-idle {\n\t\tbackground-color: #f1f1f1;\n\t}\n\t.time-card-time {\n\t\tfont-size: 28rpx;\n\t}\n\t.time-card-state {\n\t\tmargin-top: 8rpx;\n\t\tfont-size: 24rpx;\n\t}\n\t.time-card-time-active {\n\t\tcolor: #3d3528;\n\t}\n\t.time-card-time-idle {\n\t\tcolor: #9c988f;\n\t}\n\t.footer-button {\n\t\tmargin-top: 20rpx;\n\t\theight: 96rpx;\n\t\tborder-radius: 24rpx;\n\t\tbackground-color: #ffd84d;\n\t\tflex-direction: row;\n\t\tjustify-content: center;\n\t\talign-items: center;\n\t}\n\t.footer-button-text {\n\t\tfont-size: 32rpx;\n\t\tfont-weight: 700;\n\t\tcolor: #3d3528;\n\t}\n</style>\n","import { request } from '../request.uts'\r\n\r\n// 基础 URL 配置\r\n\r\nconst BASE_URL = 'https://dev.xiaodingyun.cn'\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n// 验证码登录\r\nexport function fetchLogin(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coachapp/account/login`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata: data\r\n\t})\r\n}\r\n\r\n// 发送验证码\r\nexport function fetchSendcode(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coachapp/account/sendcode`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata: data\r\n\t})\r\n}","<template>\n\n\t<scroll-view class=\"page-scroll\">\n\n\t\t<view class=\"page\">\n\t\t\t<image class=\"page-bg\" src=\"/static/other/shzm-bg.png\" mode=\"widthFix\"></image>\n\t\t\t<image class=\"page-banner\" src=\"/static/other/shzm-jrwm.png\" mode=\"widthFix\"></image>\n\t\t\t<view class=\"hero-card\">\n\t\t\t\t<text class=\"hero-title\">商户招募</text>\n\t\t\t\t<text class=\"hero-desc\">请填写基础信息,提交后等待平台审核。</text>\n\t\t\t</view>\n\n\t\t\t<view class=\"form-card\">\n\t\t\t\t<view class=\"field-block\">\n\t\t\t\t\t<text class=\"field-label\">邀请人专属码</text>\n\t\t\t\t\t<input v-model=\"form.inviteCode\" class=\"field-input\" placeholder=\"选填\" />\n\t\t\t\t</view>\n\t\t\t\t<view class=\"field-block\">\n\t\t\t\t\t<text class=\"field-label\">真实姓名</text>\n\t\t\t\t\t<input v-model=\"form.realName\" class=\"field-input\" placeholder=\"请输入本人姓名\" />\n\t\t\t\t</view>\n\t\t\t\t<view class=\"field-block\">\n\t\t\t\t\t<text class=\"field-label\">工作艺名</text>\n\t\t\t\t\t<input v-model=\"form.nickname\" class=\"field-input\" placeholder=\"选填,四字以内\" :maxlength=\"4\" />\n\t\t\t\t</view>\n\t\t\t\t<view class=\"field-block\">\n\t\t\t\t\t<text class=\"field-label\">性别</text>\n\t\t\t\t\t<view class=\"gender-row\">\n\t\t\t\t\t\t<view class=\"gender-chip\" :class=\"form.gender == 0 ? 'gender-chip-active' : 'gender-chip-idle'\" @click=\"setGender(0)\">\n\t\t\t\t\t\t\t<text class=\"gender-chip-text\">男</text>\n\t\t\t\t\t\t</view>\n\t\t\t\t\t\t<view class=\"gender-chip\" :class=\"form.gender == 1 ? 'gender-chip-active' : 'gender-chip-idle'\" @click=\"setGender(1)\">\n\t\t\t\t\t\t\t<text class=\"gender-chip-text\">女</text>\n\t\t\t\t\t\t</view>\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"field-block\">\n\t\t\t\t\t<text class=\"field-label\">手机号</text>\n\t\t\t\t\t<input v-model=\"form.mobile\" class=\"field-input\" type=\"number\" :maxlength=\"11\" placeholder=\"请输入手机号\" />\n\t\t\t\t</view>\n\t\t\t\t<view class=\"field-block\">\n\t\t\t\t\t<text class=\"field-label\">验证码</text>\n\t\t\t\t\t<view class=\"code-row\">\n\t\t\t\t\t\t<input v-model=\"form.code\" class=\"field-input code-input\" type=\"number\" :maxlength=\"6\" placeholder=\"请输入验证码\" />\n\t\t\t\t\t\t<view class=\"code-button\" :class=\"canSendCode ? 'code-button-active' : 'code-button-disabled'\" @click=\"sendCode\">\n\t\t\t\t\t\t\t<text class=\"code-button-text\">{{ codeButtonText }}</text>\n\t\t\t\t\t\t</view>\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"field-block\">\n\t\t\t\t\t<text class=\"field-label\">年龄</text>\n\t\t\t\t\t<input v-model=\"form.age\" class=\"field-input\" type=\"number\" :maxlength=\"2\" placeholder=\"18 岁以上\" />\n\t\t\t\t</view>\n\t\t\t\t<view class=\"field-block\">\n\t\t\t\t\t<text class=\"field-label\">合作城市</text>\n\t\t\t\t\t<input v-model=\"form.intentionCity\" class=\"field-input\" placeholder=\"请输入意向合作城市\" />\n\t\t\t\t</view>\n\t\t\t</view>\n\n\t\t\t<view class=\"submit-button\" @click=\"submitForm\">\n\t\t\t\t<text class=\"submit-button-text\">提交审核</text>\n\t\t\t</view>\n\t\t</view>\n\n\t</scroll-view>\n\n</template>\n\n<script setup lang=\"uts\">\n\timport { computed, reactive, ref } from 'vue'\n\timport { onUnload } from '@dcloudio/uni-app'\n\timport { fetchSendcode } from '@/utils/api/login.uts'\n\timport { submitQualification } from '@/utils/api/masterInfoApi.uts'\n\n\ttype FormState = {\n\t\tinviteCode: string\n\t\trealName: string\n\t\tnickname: string\n\t\tgender: number\n\t\tmobile: string\n\t\tcode: string\n\t\tage: string\n\t\tintentionCity: string\n\t}\n\n\tconst form = reactive<FormState>({\n\t\tinviteCode: '',\n\t\trealName: '',\n\t\tnickname: '',\n\t\tgender: 0,\n\t\tmobile: '',\n\t\tcode: '',\n\t\tage: '',\n\t\tintentionCity: '',\n\t})\n\n\tconst countdown = ref<number>(0)\n\tlet timerId : number | null = null\n\n\tconst canSendCode = computed(() : boolean => {\n\t\treturn form.mobile.length == 11 && countdown.value == 0\n\t})\n\n\tconst codeButtonText = computed(() : string => {\n\t\treturn countdown.value > 0 ? `${countdown.value}s后重试` : '获取验证码'\n\t})\n\n\tconst setGender = (gender : number) : void => {\n\t\tform.gender = gender\n\t}\n\n\tconst stopTimer = () : void => {\n\t\tconst currentTimer = timerId\n\t\tif (currentTimer != null) {\n\t\t\tclearInterval(currentTimer)\n\t\t\ttimerId = null\n\t\t}\n\t}\n\n\tconst sendCode = async () : Promise<void> => {\n\t\tif (!canSendCode.value) {\n\t\t\treturn\n\t\t}\n\t\ttry {\n\t\t\tawait fetchSendcode({ mobile: form.mobile } as UTSJSONObject)\n\t\t\tcountdown.value = 60\n\t\t\tstopTimer()\n\t\t\ttimerId = setInterval(() => {\n\t\t\t\tif (countdown.value > 0) {\n\t\t\t\t\tcountdown.value = countdown.value - 1\n\t\t\t\t}\n\t\t\t\tif (countdown.value <= 0) {\n\t\t\t\t\tstopTimer()\n\t\t\t\t}\n\t\t\t}, 1000)\n\t\t\tuni.showToast({ title: '验证码已发送', icon: 'none' })\n\t\t} catch (error) {\n\t\t\tuni.showToast({ title: '验证码发送失败', icon: 'none' })\n\t\t}\n\t}\n\n\tconst submitForm = async () : Promise<void> => {\n\t\tif (form.realName.length == 0 || form.mobile.length == 0 || form.code.length == 0 || form.age.length == 0 || form.intentionCity.length == 0) {\n\t\t\tuni.showToast({ title: '请完整填写必要信息', icon: 'none' })\n\t\t\treturn\n\t\t}\n\t\ttry {\n\t\t\tconst payload = {\n\t\t\t\tinvite_code: form.inviteCode,\n\t\t\t\treal_name: form.realName,\n\t\t\t\tnickname: form.nickname,\n\t\t\t\tgender: `${form.gender}`,\n\t\t\t\tmobile: form.mobile,\n\t\t\t\tcode: form.code,\n\t\t\t\tage: parseInt(form.age),\n\t\t\t\tintention_city: form.intentionCity,\n\t\t\t} as UTSJSONObject\n\t\t\tconst response = await submitQualification(payload) as UTSJSONObject\n\t\t\tconst code = (response['code'] as number | null) ?? -1\n\t\t\tuni.showToast({ title: code == 0 || code == 200 ? '提交成功' : '提交失败', icon: 'none' })\n\t\t} catch (error) {\n\t\t\tuni.showToast({ title: '提交失败,请重试', icon: 'none' })\n\t\t}\n\t}\n\n\tonUnload(() => {\n\t\tstopTimer()\n\t})\n</script>\n\n<style>\n\t.page-scroll {\n\t\tflex: 1;\n\t}\n\t.page {\n\t\tposition: relative;\n\t\tmin-height: 1000rpx;\n\t\tpadding: 24rpx;\n\t\tbox-sizing: border-box;\n\t\tbackground-color: #fef9cf;\n\t\tflex-direction: column;\n\t}\n\t.page-bg {\n\t\tposition: absolute;\n\t\ttop: 0;\n\t\tleft: 0;\n\t\twidth: 100%;\n\t}\n\t.page-banner {\n\t\tposition: absolute;\n\t\ttop: 110rpx;\n\t\tleft: 88rpx;\n\t\twidth: 312rpx;\n\t\theight: 122rpx;\n\t}\n\t.hero-card {\n\t\tmargin-top: 300rpx;\n\t\tpadding: 28rpx;\n\t\tborder-radius: 24rpx;\n\t\tbackground-color: rgba(255, 255, 255, 0.84);\n\t\tflex-direction: column;\n\t}\n\t.hero-title {\n\t\tfont-size: 38rpx;\n\t\tfont-weight: 700;\n\t\tcolor: #372f21;\n\t}\n\t.hero-desc {\n\t\tmargin-top: 12rpx;\n\t\tfont-size: 24rpx;\n\t\tcolor: #5c513e;\n\t}\n\t.form-card {\n\t\tmargin-top: 20rpx;\n\t\tpadding: 24rpx;\n\t\tborder-radius: 24rpx;\n\t\tbackground-color: rgba(255,255,255,0.88);\n\t\tflex-direction: column;\n\t}\n\t.field-block {\n\t\tmargin-bottom: 18rpx;\n\t\tflex-direction: column;\n\t}\n\t.field-label {\n\t\tfont-size: 26rpx;\n\t\tcolor: #3a3330;\n\t}\n\t.field-input {\n\t\tmargin-top: 10rpx;\n\t\theight: 88rpx;\n\t\tpadding-left: 20rpx;\n\t\tpadding-right: 20rpx;\n\t\tborder-radius: 18rpx;\n\t\tbackground-color: #fffdd7;\n\t\tfont-size: 28rpx;\n\t\tbox-sizing: border-box;\n\t}\n\t.gender-row {\n\t\tmargin-top: 10rpx;\n\t\tflex-direction: row;\n\t}\n\t.gender-chip {\n\t\tpadding: 16rpx 28rpx;\n\t\tmargin-right: 16rpx;\n\t\tborder-radius: 999rpx;\n\t\tflex-direction: row;\n\t\tjustify-content: center;\n\t\talign-items: center;\n\t}\n\t.gender-chip-active {\n\t\tbackground-color: #ffdb5a;\n\t}\n\t.gender-chip-idle {\n\t\tbackground-color: #fffdd7;\n\t}\n\t.gender-chip-text {\n\t\tfont-size: 26rpx;\n\t\tcolor: #3a3330;\n\t}\n\t.code-row {\n\t\tmargin-top: 10rpx;\n\t\tflex-direction: row;\n\t\talign-items: center;\n\t}\n\t.code-input {\n\t\tflex: 1;\n\t}\n\t.code-button {\n\t\tmargin-left: 16rpx;\n\t\tpadding-left: 20rpx;\n\t\tpadding-right: 20rpx;\n\t\theight: 88rpx;\n\t\tborder-radius: 18rpx;\n\t\tflex-direction: row;\n\t\tjustify-content: center;\n\t\talign-items: center;\n\t}\n\t.code-button-active {\n\t\tbackground-color: #ffdb5a;\n\t}\n\t.code-button-disabled {\n\t\tbackground-color: #e3e3e3;\n\t}\n\t.code-button-text {\n\t\tfont-size: 24rpx;\n\t\tcolor: #3a3330;\n\t}\n\t.submit-button {\n\t\tmargin-top: 20rpx;\n\t\theight: 96rpx;\n\t\tborder-radius: 24rpx;\n\t\tbackground-color: #ffdb5a;\n\t\tflex-direction: row;\n\t\tjustify-content: center;\n\t\talign-items: center;\n\t}\n\t.submit-button-text {\n\t\tfont-size: 32rpx;\n\t\tfont-weight: 700;\n\t\tcolor: #3a3330;\n\t}\n</style>\n","<template>\n\n\t<scroll-view class=\"page-scroll\">\n\n\t\t<view class=\"page\">\n\t\t\t<view class=\"summary-card\">\n\t\t\t\t<text class=\"summary-title\">数据总览</text>\n\t\t\t\t<text class=\"summary-subtitle\">按当前统计口径展示技师经营数据</text>\n\t\t\t</view>\n\t\t\t<view class=\"summary-strip\">\n\t\t\t\t<view class=\"summary-strip-item\">\n\t\t\t\t\t<text class=\"summary-strip-value\">{{ stats.registerDays.count }}</text>\n\t\t\t\t\t<text class=\"summary-strip-label\">入驻天数</text>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"summary-strip-item\">\n\t\t\t\t\t<text class=\"summary-strip-value\">{{ stats.additional.count }}</text>\n\t\t\t\t\t<text class=\"summary-strip-label\">7日在线</text>\n\t\t\t\t</view>\n\t\t\t</view>\n\n\t\t\t<view v-for=\"item in statCards\" :key=\"item.key\" class=\"stat-card\">\n\t\t\t\t<view class=\"stat-row\">\n\t\t\t\t\t<text class=\"stat-label\">{{ item.title }}</text>\n\t\t\t\t\t<text class=\"stat-rate\">{{ item.rateText }}</text>\n\t\t\t\t</view>\n\t\t\t\t<view class=\"stat-row stat-row-gap\">\n\t\t\t\t\t<view class=\"stat-column\">\n\t\t\t\t\t\t<text class=\"stat-value\">{{ item.countText }}</text>\n\t\t\t\t\t\t<text class=\"stat-caption\">数量</text>\n\t\t\t\t\t</view>\n\t\t\t\t\t<view class=\"stat-column\">\n\t\t\t\t\t\t<text class=\"stat-value\">{{ item.amountText }}</text>\n\t\t\t\t\t\t<text class=\"stat-caption\">金额</text>\n\t\t\t\t\t</view>\n\t\t\t\t</view>\n\t\t\t</view>\n\t\t</view>\n\n\t</scroll-view>\n\n</template>\n\n<script setup lang=\"uts\">\n\timport { computed, reactive } from 'vue'\n\timport { getAllData } from '@/utils/api/workbenches.uts'\n\n\ttype StatInfo = {\n\t\tcount: number\n\t\tamount: number\n\t\trate: number\n\t}\n\n\ttype StatsState = {\n\t\tadditional: StatInfo\n\t\tregisterDays: StatInfo\n\t\tdeal: StatInfo\n\t\treceiving: StatInfo\n\t\trefund: StatInfo\n\t\trenewal: StatInfo\n\t\tcomment: StatInfo\n\t}\n\n\ttype StatCard = {\n\t\tkey: string\n\t\ttitle: string\n\t\trateText: string\n\t\tcountText: string\n\t\tamountText: string\n\t}\n\n\tconst createStat = () : StatInfo => {\n\t\treturn { count: 0, amount: 0, rate: 0 }\n\t}\n\n\tconst stats = reactive<StatsState>({\n\t\tadditional: createStat(),\n\t\tregisterDays: createStat(),\n\t\tdeal: createStat(),\n\t\treceiving: createStat(),\n\t\trefund: createStat(),\n\t\trenewal: createStat(),\n\t\tcomment: createStat(),\n\t})\n\n\tconst applyStat = (target : StatInfo, source : UTSJSONObject | null) : void => {\n\t\tif (source == null) {\n\t\t\ttarget.count = 0\n\t\t\ttarget.amount = 0\n\t\t\ttarget.rate = 0\n\t\t\treturn\n\t\t}\n\t\ttarget.count = (source['count'] as number | null) ?? 0\n\t\ttarget.amount = (source['amount'] as number | null) ?? 0\n\t\ttarget.rate = (source['rate'] as number | null) ?? 0\n\t}\n\n\tconst statCards = computed(() : StatCard[] => {\n\t\treturn [\n\t\t\t{ key: 'receiving', title: '接单数据', rateText: `${stats.receiving.rate}%`, countText: `${stats.receiving.count}`, amountText: `${stats.receiving.amount}` },\n\t\t\t{ key: 'deal', title: '成交数据', rateText: `${stats.deal.rate}%`, countText: `${stats.deal.count}`, amountText: `${stats.deal.amount}` },\n\t\t\t{ key: 'renewal', title: '加钟数据', rateText: `${stats.renewal.rate}%`, countText: `${stats.renewal.count}`, amountText: `${stats.renewal.amount}` },\n\t\t\t{ key: 'refund', title: '退单数据', rateText: `${stats.refund.rate}%`, countText: `${stats.refund.count}`, amountText: `${stats.refund.amount}` },\n\t\t\t{ key: 'comment', title: '评价数据', rateText: `${stats.comment.rate}%`, countText: `${stats.comment.count}`, amountText: `${stats.comment.amount}` },\n\t\t]\n\t})\n\n\tconst loadStats = async () : Promise<void> => {\n\t\ttry {\n\t\t\tconst response = await getAllData({} as UTSJSONObject) as UTSJSONObject\n\t\t\tconst code = (response['code'] as number | null) ?? -1\n\t\t\tif (code != 0 && code != 200) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst data = response['data'] as UTSJSONObject | null\n\t\t\tapplyStat(stats.additional, data?.['additional'] as UTSJSONObject | null)\n\t\t\tapplyStat(stats.registerDays, data?.['registerDays'] as UTSJSONObject | null)\n\t\t\tapplyStat(stats.deal, data?.['deal'] as UTSJSONObject | null)\n\t\t\tapplyStat(stats.receiving, data?.['receiving'] as UTSJSONObject | null)\n\t\t\tapplyStat(stats.refund, data?.['refund'] as UTSJSONObject | null)\n\t\t\tapplyStat(stats.renewal, data?.['renewal'] as UTSJSONObject | null)\n\t\t\tapplyStat(stats.comment, data?.['comment'] as UTSJSONObject | null)\n\t\t} catch (error) {\n\t\t\tuni.showToast({ title: '数据加载失败', icon: 'none' })\n\t\t}\n\t}\n\n\tonLoad(() => {\n\t\tloadStats()\n\t})\n</script>\n\n<style>\n\t.page-scroll {\n\t\tflex: 1;\n\t}\n\t.page {\n\t\tmin-height: 1000rpx;\n\t\tpadding: 24rpx;\n\t\tbox-sizing: border-box;\n\t\tbackground-color: #f7f2e7;\n\t\tflex-direction: column;\n\t}\n\t.summary-card {\n\t\tpadding: 28rpx;\n\t\tborder-radius: 24rpx;\n\t\tbackground-color: #ffe48a;\n\t\tflex-direction: column;\n\t}\n\t.summary-title {\n\t\tfont-size: 36rpx;\n\t\tfont-weight: 700;\n\t\tcolor: #2e281f;\n\t}\n\t.summary-subtitle {\n\t\tmargin-top: 12rpx;\n\t\tfont-size: 24rpx;\n\t\tcolor: #5f533c;\n\t}\n\t.summary-strip {\n\t\tmargin-top: 18rpx;\n\t\tflex-direction: row;\n\t\tjustify-content: space-between;\n\t}\n\t.summary-strip-item {\n\t\twidth: 48%;\n\t\tpadding: 24rpx;\n\t\tborder-radius: 22rpx;\n\t\tbackground-color: #ffffff;\n\t\tflex-direction: column;\n\t}\n\t.summary-strip-value {\n\t\tfont-size: 36rpx;\n\t\tfont-weight: 700;\n\t\tcolor: #2e281f;\n\t}\n\t.summary-strip-label {\n\t\tmargin-top: 8rpx;\n\t\tfont-size: 22rpx;\n\t\tcolor: #8b8376;\n\t}\n\t.stat-card {\n\t\tmargin-top: 20rpx;\n\t\tpadding: 28rpx;\n\t\tborder-radius: 24rpx;\n\t\tbackground-color: #ffffff;\n\t\tflex-direction: column;\n\t}\n\t.stat-row {\n\t\tflex-direction: row;\n\t\tjustify-content: space-between;\n\t\talign-items: center;\n\t}\n\t.stat-row-gap {\n\t\tmargin-top: 18rpx;\n\t}\n\t.stat-label {\n\t\tfont-size: 30rpx;\n\t\tfont-weight: 700;\n\t\tcolor: #2e281f;\n\t}\n\t.stat-rate {\n\t\tfont-size: 26rpx;\n\t\tcolor: #d76b31;\n\t}\n\t.stat-column {\n\t\twidth: 46%;\n\t\tpadding: 20rpx;\n\t\tborder-radius: 18rpx;\n\t\tbackground-color: #faf7f1;\n\t\tflex-direction: column;\n\t}\n\t.stat-value {\n\t\tfont-size: 34rpx;\n\t\tfont-weight: 700;\n\t\tcolor: #2e281f;\n\t}\n\t.stat-caption {\n\t\tmargin-top: 8rpx;\n\t\tfont-size: 22rpx;\n\t\tcolor: #8b8376;\n\t}\n</style>\n","<template>\n\n\t<scroll-view class=\"page-scroll\">\n\n\t\t<view class=\"page\">\n\t\t\t<view class=\"header-card\">\n\t\t\t\t<text class=\"header-score\">5.0</text>\n\t\t\t\t<text class=\"header-text\">客户评价</text>\n\t\t\t\t<text class=\"header-subtext\">高于 98% 的同类服务者</text>\n\t\t\t</view>\n\n\t\t\t<view class=\"tag-section\">\n\t\t\t\t<view v-for=\"item in tagList\" :key=\"item.text\" class=\"tag-item\">\n\t\t\t\t\t<text class=\"tag-text\">{{ item.text }}</text>\n\t\t\t\t\t<text class=\"tag-count\">{{ item.countText }}</text>\n\t\t\t\t</view>\n\t\t\t</view>\n\n\t\t\t<view v-for=\"item in commentList\" :key=\"item.id\" class=\"comment-card\">\n\t\t\t\t<view class=\"comment-row\">\n\t\t\t\t\t<text class=\"comment-user\">{{ item.userName }}</text>\n\t\t\t\t\t<text class=\"comment-time\">{{ item.createdAt }}</text>\n\t\t\t\t</view>\n\t\t\t\t<text class=\"comment-project\">{{ item.projectName }}</text>\n\t\t\t\t<text class=\"comment-content\">{{ item.content }}</text>\n\t\t\t</view>\n\t\t</view>\n\n\t</scroll-view>\n\n</template>\n\n<script setup lang=\"uts\">\n\timport { ref } from 'vue'\n\timport { getCommentList } from '@/utils/api/order.uts'\n\n\ttype TagItem = {\n\t\ttext: string\n\t\tcountText: string\n\t}\n\n\ttype CommentItem = {\n\t\tid: string\n\t\tuserName: string\n\t\tcreatedAt: string\n\t\tprojectName: string\n\t\tcontent: string\n\t}\n\n\tconst tagList = ref<TagItem[]>([])\n\tconst commentList = ref<CommentItem[]>([])\n\n\tconst loadComments = async () : Promise<void> => {\n\t\ttry {\n\t\t\tconst response = await getCommentList({} as UTSJSONObject) as UTSJSONObject\n\t\t\tconst code = (response['code'] as number | null) ?? -1\n\t\t\tif (code != 0 && code != 200) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tconst data = response['data'] as UTSJSONObject | null\n\t\t\tconst tags = (data?.['tags_list'] as UTSArray<UTSJSONObject> | null)\n\t\t\tconst items = (data?.['items'] as UTSArray<UTSJSONObject> | null)\n\t\t\tconst nextTags : TagItem[] = []\n\t\t\tif (tags != null) {\n\t\t\t\tfor (let i = 0; i < tags.length; i++) {\n\t\t\t\t\tconst tag = tags[i]\n\t\t\t\t\tnextTags.push({\n\t\t\t\t\t\ttext: (tag['text'] as string | null) ?? '标签',\n\t\t\t\t\t\tcountText: `${(tag['count'] as number | null) ?? 0}`,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\ttagList.value = nextTags\n\n\t\t\tconst nextComments : CommentItem[] = []\n\t\t\tif (items != null) {\n\t\t\t\tfor (let i = 0; i < items.length; i++) {\n\t\t\t\t\tconst item = items[i]\n\t\t\t\t\tconst userInfo = item['user_info'] as UTSJSONObject | null\n\t\t\t\t\tnextComments.push({\n\t\t\t\t\t\tid: `${i}`,\n\t\t\t\t\t\tuserName: (userInfo?.['nickname'] as string | null) ?? '匿名用户',\n\t\t\t\t\t\tcreatedAt: (item['created_at'] as string | null) ?? '',\n\t\t\t\t\t\tprojectName: (item['project_name'] as string | null) ?? '服务项目',\n\t\t\t\t\t\tcontent: (item['content'] as string | null) ?? '暂无评价内容',\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\tcommentList.value = nextComments\n\t\t} catch (error) {\n\t\t\tuni.showToast({ title: '评价加载失败', icon: 'none' })\n\t\t}\n\t}\n\n\tonLoad(() => {\n\t\tloadComments()\n\t})\n</script>\n\n<style>\n\t.page-scroll {\n\t\tflex: 1;\n\t}\n\t.page {\n\t\tmin-height: 1000rpx;\n\t\tpadding: 24rpx;\n\t\tbox-sizing: border-box;\n\t\tbackground-color: #f5f3ef;\n\t\tflex-direction: column;\n\t}\n\t.header-card {\n\t\tpadding: 28rpx;\n\t\tborder-radius: 24rpx;\n\t\tbackground-color: #fff09a;\n\t\tflex-direction: column;\n\t}\n\t.header-score {\n\t\tfont-size: 56rpx;\n\t\tfont-weight: 700;\n\t\tcolor: #2f2a22;\n\t}\n\t.header-text {\n\t\tmargin-top: 10rpx;\n\t\tfont-size: 28rpx;\n\t\tcolor: #5e5648;\n\t}\n\t.header-subtext {\n\t\tmargin-top: 6rpx;\n\t\tfont-size: 22rpx;\n\t\tcolor: #7e7564;\n\t}\n\t.tag-section {\n\t\tmargin-top: 20rpx;\n\t\tflex-direction: row;\n\t\tflex-wrap: wrap;\n\t}\n\t.tag-item {\n\t\tpadding: 12rpx 18rpx;\n\t\tmargin-right: 12rpx;\n\t\tmargin-bottom: 12rpx;\n\t\tborder-radius: 999rpx;\n\t\tbackground-color: #ffffff;\n\t\tflex-direction: row;\n\t\talign-items: center;\n\t}\n\t.tag-text {\n\t\tfont-size: 24rpx;\n\t\tcolor: #4d473c;\n\t}\n\t.tag-count {\n\t\tmargin-left: 8rpx;\n\t\tfont-size: 24rpx;\n\t\tcolor: #999999;\n\t}\n\t.comment-card {\n\t\tmargin-top: 16rpx;\n\t\tpadding: 24rpx;\n\t\tborder-radius: 20rpx;\n\t\tbackground-color: #ffffff;\n\t\tflex-direction: column;\n\t\tborder-width: 1px;\n\t\tborder-style: solid;\n\t\tborder-color: #efebe4;\n\t}\n\t.comment-row {\n\t\tflex-direction: row;\n\t\tjustify-content: space-between;\n\t\talign-items: center;\n\t}\n\t.comment-user {\n\t\tfont-size: 28rpx;\n\t\tfont-weight: 700;\n\t\tcolor: #2f2a22;\n\t}\n\t.comment-time {\n\t\tfont-size: 22rpx;\n\t\tcolor: #9a9a9a;\n\t}\n\t.comment-project {\n\t\tmargin-top: 10rpx;\n\t\tfont-size: 24rpx;\n\t\tcolor: #db6d3a;\n\t}\n\t.comment-content {\n\t\tmargin-top: 12rpx;\n\t\tfont-size: 26rpx;\n\t\tline-height: 38rpx;\n\t\tcolor: #555555;\n\t}\n</style>\n","// 导入请求\r\nimport { request } from '../request.uts'\r\n// 基础 URL 配置\r\n\r\nconst BASE_URL = 'https://dev.xiaodingyun.cn'\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nexport function getAllData(params : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/orders/statistics`,\r\n\t\tmethod: \"GET\",\r\n\t\tparams: params\r\n\t})\r\n}\r\nexport function editCoachWorkState(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/account/work-status`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata: data\r\n\t})\r\n}\r\nexport function editWorkTimeSetting(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/account/schedule`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata: data\r\n\t})\r\n}\r\nexport function toggleProject(data : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: `${BASE_URL}/api/coach/v3/projects/open`,\r\n\t\tmethod: \"POST\",\r\n\t\tdata: data\r\n\t})\r\n}\r\nimport { makePhoneCall } from \"./location\";\r\n/**\r\n * 拨打电话\r\n * @param {string} phoneNumber - 电话号码\r\n */\r\nexport const navigateToMobile = (phoneNumber : String) => {\r\n\tmakePhoneCall(phoneNumber ?? '4000678313');\r\n};\r\n\r\n/**\r\n * @description 防抖函数\r\n * @param {Function} fn - 需要防抖的函数\r\n * @param {number} delay - 延迟时间,默认1000ms\r\n * @returns {Function} - 防抖后的函数\r\n */\r\nexport const debounce = (fn : Function, delay : number = 2000) : Function => {\r\n\tlet timer : number | null = null\r\n\treturn function (...args : any[]) {\r\n\t\tif (timer) clearTimeout(timer)\r\n\t\ttimer = setTimeout(() => {\r\n\t\t\tfn.apply(this, args)\r\n\t\t}, delay)\r\n\t}\r\n}\r\n\r\n/**\r\n * @description 节流函数\r\n * @param {Function} fn - 需要节流的函数\r\n * @param {number} delay - 延迟时间,默认1000ms\r\n * @returns {Function} - 节流后的函数\r\n */\r\nexport const throttle = (fn : Function, delay : number = 300) : Function => {\r\n\tlet timer : number | null = null\r\n\tlet start : number = Date.now()\r\n\treturn function (...args : any[]) {\r\n\t\tconst current : number = Date.now()\r\n\t\tconst remaining : number = delay - (current - start)\r\n\t\tclearTimeout(timer!)\r\n\t\tif (remaining <= 0) {\r\n\t\t\tfn.apply(this, args)\r\n\t\t\tstart = Date.now()\r\n\t\t} else {\r\n\t\t\ttimer = setTimeout(() => {\r\n\t\t\t\tfn.apply(this, args)\r\n\t\t\t\tstart = Date.now()\r\n\t\t\t}, remaining)\r\n\t\t}\r\n\t}\r\n}\r\n\r\n// 缓存相关工具函数\r\nexport const cacheTools = {\r\n\t// 获取缓存\r\n\tget(key : string) : any | null { // 显式声明参数类型和返回类型\r\n\t\ttry {\r\n\t\t\tconst data = uni.getStorageSync(key) as UTSJSONObject | null // 类型断言\r\n\r\n\t\t\tif (data == null) return null\r\n\r\n\t\t\t// 检查缓存是否过期(5分钟)\r\n\t\t\tconst timestamp = data['timestamp'] as number // 通过索引访问并断言类型\r\n\t\t\tif (Date.now() - timestamp > 5 * 60 * 1000) {\r\n\t\t\t\tuni.removeStorageSync(key)\r\n\t\t\t\treturn null\r\n\t\t\t}\r\n\t\t\treturn data\r\n\t\t} catch (e) {\r\n\t\t\treturn null\r\n\t\t}\r\n\t},\r\n\r\n\t// 设置缓存\r\n\tset(key : string, value : any) : void { // 显式声明参数类型\r\n\t\ttry {\r\n\t\t\tuni.setStorageSync(key, {\r\n\t\t\t\tdata: value,\r\n\t\t\t\ttimestamp: Date.now()\r\n\t\t\t})\r\n\t\t} catch (e) {\r\n\t\t\t__f__('error','at utils/api/tool.uts:131','缓存设置失败', e)\r\n\t\t}\r\n\t}\r\n}\r\n\r\n// 网络状态检测\r\nexport const checkNetwork = () => {\r\n\treturn new Promise((resolve) => {\r\n\t\tuni.getNetworkType({\r\n\t\t\tsuccess: (res) => {\r\n\t\t\t\tresolve(res.networkType !== \"none\");\r\n\t\t\t},\r\n\t\t\tfail: () => {\r\n\t\t\t\tresolve(false);\r\n\t\t\t},\r\n\t\t});\r\n\t});\r\n};\r\n\r\n/**\r\n * 格式化日期\r\n * @param {Date} date - 要格式化的日期对象\r\n * @param {string} fmt - 格式化模板,如 'YYYY-MM-DD HH:mm:ss'\r\n * @returns {string} 格式化后的日期字符串\r\n */\r\nexport const formatDate = (date : any, fmt : string) : string => {\r\n\tif (!date) return \"\";\r\n\tif (typeof date === \"string\") {\r\n\t\tdate = new Date(date.replace(/-/g, \"/\"));\r\n\t}\r\n\tif (typeof date === \"number\") {\r\n\t\tdate = new Date(date);\r\n\t}\r\n\r\n\tconst o = {\r\n\t\t\"M+\": date.getMonth() + 1,\r\n\t\t\"D+\": date.getDate(),\r\n\t\t\"H+\": date.getHours(),\r\n\t\t\"m+\": date.getMinutes(),\r\n\t\t\"s+\": date.getSeconds(),\r\n\t\t\"q+\": Math.floor((date.getMonth() + 3) / 3),\r\n\t\tS: date.getMilliseconds(),\r\n\t};\r\n\r\n\tif (/(Y+)/.test(fmt)) {\r\n\t\tfmt = fmt.replace(\r\n\t\t\tRegExp.$1,\r\n\t\t\t(date.getFullYear() + \"\").substr(4 - RegExp.$1.length)\r\n\t\t);\r\n\t}\r\n\r\n\tfor (let k in o) {\r\n\t\tif (new RegExp(\"(\" + k + \")\").test(fmt)) {\r\n\t\t\tfmt = fmt.replace(\r\n\t\t\t\tRegExp.$1,\r\n\t\t\t\tRegExp.$1.length === 1 ? o[k] : (\"00\" + o[k]).substr((\"\" + o[k]).length)\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\treturn fmt;\r\n};\r\n\r\n//最新上传图片2025-02-17\r\nexport async function newUploadImage(\r\n\tbucket : string = \"photo-images\",\r\n\tmodule : string = \"real-photo\"\r\n) : Promise<any> {\r\n\treturn new Promise((resolve, reject) => {\r\n\t\tuni.chooseImage({\r\n\t\t\tcount: 1,\r\n\t\t\tsuccess: (res) => {\r\n\t\t\t\tconst tempFilePaths = res.tempFilePaths\r\n\t\t\t\tuni.showLoading({\r\n\t\t\t\t\ttitle: \"上传中...\",\r\n\t\t\t\t\tmask: true,\r\n\t\t\t\t})\r\n\t\t\t\tuni.uploadFile({\r\n\t\t\t\t\turl: \"https://dev.xiaodingyun.cn/api/upload\",\r\n\t\t\t\t\tfilePath: tempFilePaths[0],\r\n\t\t\t\t\tname: \"file\",\r\n\t\t\t\t\tformData: {\r\n\t\t\t\t\t\tbucket: bucket,\r\n\t\t\t\t\t\tmodule: module,\r\n\t\t\t\t\t},\r\n\t\t\t\t\tsuccess: (uploadFileRes) => {\r\n\t\t\t\t\t\tlet data = JSON.parse(uploadFileRes.data) as UTSJSONObject\r\n\t\t\t\t\t\tif (data['code'] as number == 200) {\r\n\t\t\t\t\t\t\tresolve({ code: 200, data: data['data'], message: \"上传成功\" })\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\treject({ code: 202, data: {}, message: \"上传失败\" })\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t},\r\n\t\t\t\t\tfail: (err) => {\r\n\t\t\t\t\t\treject({ code: 202, data: {}, message: \"上传失败\" })\r\n\t\t\t\t\t},\r\n\t\t\t\t\tcomplete: () => {\r\n\t\t\t\t\t\tuni.hideLoading()\r\n\t\t\t\t\t},\r\n\t\t\t\t})\r\n\t\t\t},\r\n\t\t\tfail: (err) => {\r\n\t\t\t\treject({ code: 202, data: {}, message: \"上传失败\" })\r\n\t\t\t},\r\n\t\t})\r\n\t})\r\n}\r\n//汇付天下\r\nexport const huifuUpload = async () => {\r\n\t//获取token\r\n\tconst token = await uni.getStorageSync(\"token\");\r\n\treturn new Promise((resolve, reject) => {\r\n\t\tuni.chooseImage({\r\n\t\t\tcount: 1,\r\n\t\t\tfileType: \"image\",\r\n\t\t\tsuccess: (res) => {\r\n\t\t\t\tconst tempFilePaths = res.tempFilePaths;\r\n\t\t\t\tuni.showLoading({\r\n\t\t\t\t\ttitle: \"上传中...\",\r\n\t\t\t\t\tmask: true,\r\n\t\t\t\t});\r\n\t\t\t\tuni.uploadFile({\r\n\t\t\t\t\turl: \"https://dev.xiaodingyun.cn/api/coach/v3/wallet/BsUpload\",\r\n\t\t\t\t\tfilePath: tempFilePaths[0],\r\n\t\t\t\t\tname: \"file\",\r\n\t\t\t\t\theader: {\r\n\t\t\t\t\t\tAuthorization: \"Bearer \" + token,\r\n\t\t\t\t\t},\r\n\t\t\t\t\tsuccess: (uploadFileRes) => {\r\n\t\t\t\t\t\tlet data = JSON.parse(uploadFileRes.data);\r\n\t\t\t\t\t\tif (data.code == 200) {\r\n\t\t\t\t\t\t\tresolve({ code: 200, data: data.data, message: \"上传成功\" });\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\treject({ code: 202, data: {}, message: \"上传失败\" });\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t},\r\n\t\t\t\t\tfail: (err) => {\r\n\t\t\t\t\t\treject({ code: 202, data: {}, message: \"上传失败\" });\r\n\t\t\t\t\t},\r\n\t\t\t\t\tcomplete: () => {\r\n\t\t\t\t\t\tuni.hideLoading();\r\n\t\t\t\t\t},\r\n\t\t\t\t});\r\n\t\t\t},\r\n\t\t\tfail: (err) => {\r\n\t\t\t\treject({ code: 202, data: {}, message: \"上传失败\" });\r\n\t\t\t},\r\n\t\t});\r\n\t});\r\n};","<template>\r\n\r\n\t<scroll-view class=\"page-scroll\">\r\n\r\n\t\t<view class=\"page\">\r\n\t\t\t<view class=\"header-card\">\r\n\t\t\t\t<view class=\"header-status\">\r\n\t\t\t\t\t<u-icon name=\"customerservice\" :size=\"24\" />\r\n\t\t\t\t\t<text class=\"header-status-text\">\r\n\t\t\t\t\t\t{{ detail.stateText }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t</view>\r\n\r\n\t\t\t<view class=\"section-card\">\r\n\t\t\t\t<view class=\"address-section\">\r\n\t\t\t\t\t<text class=\"address-label\">\r\n\t\t\t\t\t\t服务地址\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text class=\"address-text\">\r\n\t\t\t\t\t\t{{ detail.address }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text class=\"phone-text\">\r\n\t\t\t\t\t\t{{ detail.customerPhone }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t\t<view class=\"time-section\">\r\n\t\t\t\t\t<text class=\"time-label\">\r\n\t\t\t\t\t\t预约服务时间\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text class=\"time-value\">\r\n\t\t\t\t\t\t{{ detail.serviceTime }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t</view>\r\n\r\n\t\t\t<view class=\"section-card\">\r\n\t\t\t\t<view class=\"project-section\">\r\n\t\t\t\t\t<image class=\"project-image\"\r\n\t\t\t\t\t:src=\"detail.projectImage\"\r\n\t\t\t\t\tmode=\"aspectFill\">\r\n\t\t\t\t\t</image>\r\n\t\t\t\t\t<view class=\"project-info\">\r\n\t\t\t\t\t\t<text class=\"project-title\">\r\n\t\t\t\t\t\t\t{{ detail.projectTitle }}\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t<text class=\"project-duration\">\r\n\t\t\t\t\t\t\t服务时长: {{ detail.durationText }}\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t\t<text class=\"project-price\">\r\n\t\t\t\t\t\t{{ detail.projectAmount }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t</view>\r\n\r\n\t\t\t<view class=\"section-card\">\r\n\t\t\t\t<text class=\"section-title\">\r\n\t\t\t\t\t预估收入\r\n\t\t\t\t</text>\r\n\t\t\t\t<view class=\"income-row\">\r\n\t\t\t\t\t<text class=\"income-label\">\r\n\t\t\t\t\t\t项目分成\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text class=\"income-value\">\r\n\t\t\t\t\t\t{{ detail.projectShare }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t\t<view class=\"income-row\">\r\n\t\t\t\t\t<text class=\"income-label\">\r\n\t\t\t\t\t\t路费\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text class=\"income-value\">\r\n\t\t\t\t\t\t{{ detail.roadFee }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t\t<view class=\"income-total\">\r\n\t\t\t\t\t<text class=\"income-total-label\">\r\n\t\t\t\t\t\t总收入\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text class=\"income-total-value\">\r\n\t\t\t\t\t\t{{ detail.totalIncome }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t</view>\r\n\r\n\t\t\t<view class=\"section-card\">\r\n\t\t\t\t<view class=\"order-info-row\">\r\n\t\t\t\t\t<text class=\"order-info-label\">\r\n\t\t\t\t\t\t订单编号\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<view class=\"order-info-value\">\r\n\t\t\t\t\t\t<text>\r\n\t\t\t\t\t\t\t{{ detail.orderNo }}\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t<text class=\"copy-button\" @click=\"copyOrderNo\">\r\n\t\t\t\t\t\t\t复制\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t</view>\r\n\t\t\t\t<view class=\"order-info-row\">\r\n\t\t\t\t\t<text class=\"order-info-label\">\r\n\t\t\t\t\t\t下单时间\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text class=\"order-info-value\">\r\n\t\t\t\t\t\t{{ detail.createdAt }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t\t<view class=\"order-info-row\">\r\n\t\t\t\t\t<text class=\"order-info-label\">\r\n\t\t\t\t\t\t支付金额\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text class=\"order-info-value\">\r\n\t\t\t\t\t\t{{ detail.payAmount }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t\t<view class=\"order-info-row\">\r\n\t\t\t\t\t<text class=\"order-info-label\">\r\n\t\t\t\t\t\t出行车费\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text class=\"order-info-value\">\r\n\t\t\t\t\t\t{{ detail.deliveryFee }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t\t<view class=\"order-info-row\">\r\n\t\t\t\t\t<text class=\"order-info-label\">\r\n\t\t\t\t\t\t支付时间\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text class=\"order-info-value\">\r\n\t\t\t\t\t\t{{ detail.paymentTime }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t\t<view class=\"order-info-row\">\r\n\t\t\t\t\t<text class=\"order-info-label\">\r\n\t\t\t\t\t\t备注\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text class=\"order-info-value\">\r\n\t\t\t\t\t\t{{ detail.remark }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t</view>\r\n\r\n\t\t\t<view class=\"section-card\">\r\n\t\t\t\t<view v-for=\"(item, index) in detail.statusList\" :key=\"index\"\r\n\t\t\t\t:class=\"['progress-item', item.active ? 'active' : '']\">\r\n\t\t\t\t\t<view class=\"progress-dot\">\r\n\t\t\t\t\t</view>\r\n\t\t\t\t\t<view v-if=\"index < detail.statusList.length - 1\"\r\n\t\t\t\t\t:class=\"['progress-line', item.active ? 'active' : '']\">\r\n\t\t\t\t\t</view>\r\n\t\t\t\t\t<view class=\"progress-content\">\r\n\t\t\t\t\t\t<text :class=\"['progress-text', item.active ? 'active' : '']\">\r\n\t\t\t\t\t\t\t{{ item.status }}\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t<text class=\"progress-time\">\r\n\t\t\t\t\t\t\t{{ item.time }}\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t</view>\r\n\t\t\t</view>\r\n\r\n\t\t\t<view class=\"button-row\">\r\n\t\t\t\t<view v-if=\"showSecondaryButton\" class=\"secondary-button\"\r\n\t\t\t\t@click=\"detail.state == 2 ? handleTransfer : callCustomer\">\r\n\t\t\t\t\t<u-icon name=\"customerservice\" :size=\"24\" />\r\n\t\t\t\t\t<text class=\"secondary-button-text\">\r\n\t\t\t\t\t\t{{ secondaryActionText }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t\t<view v-if=\"showPrimaryButton\" :class=\"['primary-button', { 'full-width': !showSecondaryButton }]\"\r\n\t\t\t\t@click=\"detail.state == 8 || detail.state == 9 ? contactService : handleAction\">\r\n\t\t\t\t\t<text class=\"primary-button-text\">\r\n\t\t\t\t\t\t{{ actionText }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t</view>\r\n\t\t</view>\r\n\r\n\t</scroll-view>\r\n\r\n</template>\r\n\r\n<script setup lang=\"uts\">\r\n\timport { computed, reactive } from 'vue'\r\n\timport { getCurrentLocation } from '@/utils/api/location.uts'\r\n\timport { navigateToMobile } from '@/utils/api/tool.uts'\r\n\timport { getOrderDetaile, acceptOrder, departOrder, arriveOrder, leaveOrder, transferOrder } from '@/utils/api/order.uts'\r\n\r\n\ttype StatusItem = {\r\n\t\tstatus : string\r\n\t\ttime : string\r\n\t\tactive : boolean\r\n\t}\r\n\r\n\ttype DetailState = {\r\n\t\torderId : string\r\n\t\torderNo : string\r\n\t\tstate : number\r\n\t\tstateText : string\r\n\t\taddress : string\r\n\t\tcustomer : string\r\n\t\tcustomerPhone : string\r\n\t\tserviceTime : string\r\n\t\tprojectTitle : string\r\n\t\tprojectImage : string\r\n\t\tdurationText : string\r\n\t\tprojectAmount : string\r\n\t\tdeliveryFee : string\r\n\t\tpayAmount : string\r\n\t\tcreatedAt : string\r\n\t\tpaymentTime : string\r\n\t\tremark : string\r\n\t\tprojectShare : string\r\n\t\troadFee : string\r\n\t\ttotalIncome : string\r\n\t\tstatusList : Array<StatusItem>\r\n\t}\r\n\r\n\tconst detail = reactive<DetailState>({\r\n\t\t\torderId: '',\r\n\t\t\torderNo: '',\r\n\t\t\tstate: 0,\r\n\t\t\tstateText: '订单详情',\r\n\t\t\taddress: '',\r\n\t\t\tcustomer: '',\r\n\t\t\tcustomerPhone: '',\r\n\t\t\tserviceTime: '',\r\n\t\t\tprojectTitle: '',\r\n\t\t\tprojectImage: '',\r\n\t\t\tdurationText: '',\r\n\t\t\tprojectAmount: '0',\r\n\t\t\tdeliveryFee: '0',\r\n\t\t\tpayAmount: '0',\r\n\t\t\tcreatedAt: '',\r\n\t\t\tpaymentTime: '',\r\n\t\t\tremark: '',\r\n\t\t\tprojectShare: '0',\r\n\t\t\troadFee: '0',\r\n\t\t\ttotalIncome: '0',\r\n\t\t\tstatusList: [\r\n\t\t\t\t{ status: '已接单', time: '', active: false },\r\n\t\t\t\t{ status: '已出发', time: '', active: false },\r\n\t\t\t\t{ status: '到达', time: '', active: false },\r\n\t\t\t\t{ status: '开始服务', time: '', active: false },\r\n\t\t\t{ status: '服务完成', time: '', active: false }]\r\n\t\t})\r\n\r\n\tconst actionText = computed(() : string => {\r\n\t\t\tif (detail.state == 2) { // 已支付\r\n\t\t\t\treturn '确认接单'\r\n\t\t\t}\r\n\t\t\tif (detail.state == 4) { // 已接单\r\n\t\t\t\treturn '已出发'\r\n\t\t\t}\r\n\t\t\tif (detail.state == 8 || detail.state == 9) { // 已退款或已取消\r\n\t\t\t\treturn '联系客服'\r\n\t\t\t}\r\n\t\t\tif (detail.state == 5) {\r\n\t\t\t\treturn '确认到达'\r\n\t\t\t}\r\n\t\t\tif (detail.state == 10) {\r\n\t\t\t\treturn '确认撤离'\r\n\t\t\t}\r\n\t\t\treturn '刷新详情'\r\n\t\t})\r\n\r\n\tconst secondaryActionText = computed(() : string => {\r\n\t\t\tif (detail.state == 2) { // 已支付\r\n\t\t\t\treturn '我要转单'\r\n\t\t\t}\r\n\t\t\tif (detail.state == 4) { // 已接单\r\n\t\t\t\treturn '拨打电话'\r\n\t\t\t}\r\n\t\t\tif (detail.state == 8 || detail.state == 9) { // 已退款或已取消\r\n\t\t\t\treturn ''\r\n\t\t\t}\r\n\t\t\treturn '拨打电话'\r\n\t\t})\r\n\r\n\tconst showSecondaryButton = computed(() : boolean => {\r\n\t\t\treturn detail.state == 2 || detail.state == 4\r\n\t\t})\r\n\r\n\tconst showPrimaryButton = computed(() : boolean => {\r\n\t\t\treturn detail.state == 2 || detail.state == 4 || detail.state == 8 || detail.state == 9\r\n\t\t})\r\n\r\n\tconst toNumber = (value : any | null) : number => {\r\n\t\tconst numberValue = value as number | null\r\n\t\tif (numberValue != null) {\r\n\t\t\treturn numberValue\r\n\t\t}\r\n\t\tconst stringValue = value as string | null\r\n\t\tif (stringValue != null && stringValue.length > 0) {\r\n\t\t\treturn parseFloat(stringValue)\r\n\t\t}\r\n\t\treturn 0\r\n\t}\r\n\r\n\tconst getLocationPayload = async () : Promise<UTSJSONObject | null> => {\r\n\t\tconst response = await getCurrentLocation()\r\n\t\tconst data = response['data'] as UTSJSONObject | null\r\n\t\tconst location = data?.['location'] as UTSJSONObject | null\r\n\t\tif (location == null) {\r\n\t\t\treturn null\r\n\t\t}\r\n\t\treturn {\r\n\t\t\tlatitude: (location['latitude'] as number | null) ?? 0,\r\n\t\t\tlongitude: (location['longitude'] as number | null) ?? 0,\r\n\t\t} as UTSJSONObject\r\n\t}\r\n\r\n\tconst getActiveStatusIndex = (state : number) : number => {\r\n\t\tswitch (state) {\r\n\t\t\tcase 2: // 待接单\r\n\t\t\treturn 0\r\n\t\t\tcase 4: // 已接单\r\n\t\t\treturn 1\r\n\t\t\tcase 5: // 已出发\r\n\t\t\treturn 2\r\n\t\t\tcase 6: // 已到达\r\n\t\t\treturn 3\r\n\t\t\tcase 7: // 服务中\r\n\t\t\tcase 8: // 服务完成\r\n\t\t\treturn 4\r\n\t\t\tdefault:\r\n\t\t\treturn 0\r\n\t\t}\r\n\t}\r\n\r\n\tconst applyDetail = (data : UTSJSONObject) : void => {\r\n\t\tconst address = data['address'] as UTSJSONObject | null\r\n\t\tconst project = data['project'] as UTSJSONObject | null\r\n\t\tconst state = (data['state'] as number | null) ?? 0\r\n\t\tconst num = (data['num'] as number | null) ?? 1\r\n\t\tdetail.orderNo = (data['order_no'] as string | null) ?? ''\r\n\t\tdetail.state = state\r\n\t\tdetail.stateText = (data['state_text'] as string | null) ?? '已支付'\r\n\r\n\t\t// 拼接完整地址\r\n\t\tconst province = (address?.['province'] as string | null) ?? ''\r\n\t\tconst city = (address?.['city'] as string | null) ?? ''\r\n\t\tconst district = (address?.['district'] as string | null) ?? ''\r\n\t\tconst detailAddr = (address?.['detail'] as string | null) ?? ''\r\n\t\tdetail.address = `${province}${city}${district}${detailAddr}`\r\n\r\n\t\tconst customerName = (address?.['name'] as string | null) ?? ''\r\n\t\tconst customerPhone = (address?.['phone'] as string | null) ?? ''\r\n\t\tdetail.customer = `${customerName} ${customerPhone}`\r\n\t\tdetail.customerPhone = customerPhone\r\n\t\tdetail.serviceTime = (data['service_time'] as string | null) ?? ''\r\n\t\tdetail.projectTitle = (project?.['title'] as string | null) ?? '服务项目'\r\n\r\n\t\t// 获取项目图片\r\n\t\tconst coverUrls = project?.['cover_urls'] as Array<UTSJSONObject> | null\r\n\t\tif (coverUrls != null && coverUrls.length > 0) {\r\n\t\t\tdetail.projectImage = (coverUrls[0]['medium_url'] as string | null) ?? ''\r\n\t\t} else {\r\n\t\t\tdetail.projectImage = ''\r\n\t\t}\r\n\r\n\t\tconst duration = (project?.['duration'] as number | null) ?? 0\r\n\t\tdetail.durationText = `${duration * num}分钟`\r\n\t\tdetail.projectAmount = `¥${toNumber(data['project_amount']).toFixed(2)}`\r\n\t\tdetail.deliveryFee = `¥${toNumber(data['delivery_fee']).toFixed(2)}`\r\n\t\tdetail.payAmount = `¥${(toNumber(data['pay_amount']) + toNumber(data['balance_amount'])).toFixed(2)}`\r\n\t\tdetail.createdAt = (data['created_at'] as string | null) ?? ''\r\n\t\tdetail.paymentTime = (data['payment_time'] as string | null) ?? ''\r\n\t\tdetail.remark = (data['remark'] as string | null) ?? '无'\r\n\r\n\t\t// 预估收入相关字段(根据接口数据计算)\r\n\t\tconst commissionAmount = toNumber(data['commission_amount'])\r\n\t\tconst deliveryFee = toNumber(data['delivery_fee'])\r\n\t\tdetail.projectShare = `¥${commissionAmount.toFixed(2)}`\r\n\t\tdetail.roadFee = `¥${deliveryFee.toFixed(2)}`\r\n\t\tdetail.totalIncome = `¥${(commissionAmount + deliveryFee).toFixed(2)}`\r\n\r\n\t\t// 更新状态列表\r\n\t\tconst statusList = data['status_list'] as Array<UTSJSONObject> | null\r\n\t\tif (statusList != null && statusList.length > 0) {\r\n\t\t\tfor (let i = 0; i < statusList.length; i++) {\r\n\t\t\t\tconst item = statusList[i]\r\n\t\t\t\tif (i < detail.statusList.length) {\r\n\t\t\t\t\tdetail.statusList[i].status = (item['status'] as string | null) ?? detail.statusList[i].status\r\n\t\t\t\t\tdetail.statusList[i].time = (item['time'] as string | null) ?? ''\r\n\t\t\t\t\tdetail.statusList[i].active = (item['active'] as boolean | null) ?? false\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\t// 根据订单状态设置默认激活状态\r\n\t\t\tfor (let i = 0; i < detail.statusList.length; i++) {\r\n\t\t\t\tdetail.statusList[i].active = i < getActiveStatusIndex(state)\r\n\t\t\t\tdetail.statusList[i].time = detail.createdAt\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tconst loadDetail = async () : Promise<void> => {\r\n\t\tif (detail.orderId.length == 0) {\r\n\t\t\treturn\r\n\t\t}\r\n\t\ttry {\r\n\t\t\tconst response = await getOrderDetaile({ id: detail.orderId } as UTSJSONObject) as UTSJSONObject\r\n\t\t\tconst code = (response['code'] as number | null) ?? -1\r\n\t\t\tif (code != 0 && code != 200) {\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t\tconst data = response['data'] as UTSJSONObject | null\r\n\t\t\tif (data != null) {\r\n\t\t\t\tapplyDetail(data)\r\n\t\t\t}\r\n\t\t} catch (error) {\r\n\t\t\tuni.showToast({ title: '订单加载失败', icon: 'none' })\r\n\t\t}\r\n\t}\r\n\r\n\tconst callCustomer = () : void => {\r\n\t\tif (detail.customerPhone.length == 0) {\r\n\t\t\tuni.showToast({ title: '暂无客户电话', icon: 'none' })\r\n\t\t\treturn\r\n\t\t}\r\n\t\tnavigateToMobile(detail.customerPhone)\r\n\t}\r\n\r\n\tconst copyOrderNo = () : void => {\r\n\t\tif (detail.orderNo.length == 0) {\r\n\t\t\treturn\r\n\t\t}\r\n\t\tuni.setClipboardData({\r\n\t\t\t\tdata: detail.orderNo,\r\n\t\t\t\tsuccess: function () {\r\n\t\t\t\t\tuni.showToast({ title: '复制成功', icon: 'success' })\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t}\r\n\t// 商户转单\r\n\tconst httptransferOrder = async (orderId : number,) => {\r\n\t\ttry {\r\n\t\t\tconst res = await transferOrder({\r\n\t\t\t\t\torder_id: orderId,\r\n\t\t\t\t}) as UTSJSONObject;\r\n\t\t\tif (res?.code === 200) {\r\n\t\t\t\tuni.showToast({ title: '转单成功', icon: 'success' });\r\n\t\t\t\t// await httpGetOrderList();\r\n\t\t\t} else {\r\n\t\t\t\tuni.showToast({\r\n\t\t\t\t\t\ttitle: (res?.msg) as String ?? '转单失败',\r\n\t\t\t\t\t\ticon: 'none'\r\n\t\t\t\t\t});\r\n\t\t\t}\r\n\t\t} catch (err) {\r\n\t\t\tconsole.error('转单异常', err);\r\n\t\t\tuni.showToast({\r\n\t\t\t\t\ttitle: '转单失败,请重试',\r\n\t\t\t\t\ticon: 'none'\r\n\t\t\t\t});\r\n\t\t}\r\n\t};\r\n\tconst handleTransfer = () : void => {\r\n\t\t// 转单逻辑\r\n\t\tuni.showModal({\r\n\t\t\t\ttitle: '转单确认',\r\n\t\t\t\tcontent: '确定要将此订单转单吗?',\r\n\t\t\t\tconfirmText: '确定',\r\n\t\t\t\tcancelText: '取消',\r\n\t\t\t\tsuccess: function (res) {\r\n\t\t\t\t\tif (res.confirm) {\r\n\t\t\t\t\t\t// 调用转单接口\r\n\t\t\t\t\t\thttptransferOrder(toNumber(detail.orderId))\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t}\r\n\r\n\tconst contactService = () : void => {\r\n\t\t// 联系客服逻辑\r\n\t\tuni.showModal({\r\n\t\t\t\ttitle: '联系客服',\r\n\t\t\t\tcontent: '客服电话:400-123-4567',\r\n\t\t\t\tconfirmText: '拨打电话',\r\n\t\t\t\tcancelText: '取消',\r\n\t\t\t\tsuccess: function (res) {\r\n\t\t\t\t\tif (res.confirm) {\r\n\t\t\t\t\t\t// 拨打电话\r\n\t\t\t\t\t\tnavigateToMobile('4001234567')\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t}\r\n\r\n\tconst handleAction = async () : Promise<void> => {\r\n\t\tif (detail.orderId.length == 0) {\r\n\t\t\treturn\r\n\t\t}\r\n\t\tif (detail.state != 2 && detail.state != 4 && detail.state != 5 && detail.state != 10) {\r\n\t\t\tloadDetail()\r\n\t\t\treturn\r\n\t\t}\r\n\t\tconst locationPayload = await getLocationPayload()\r\n\t\tif (locationPayload == null) {\r\n\t\t\tuni.showToast({ title: '定位失败,请重试', icon: 'none' })\r\n\t\t\treturn\r\n\t\t}\r\n\t\ttry {\r\n\t\t\tif (detail.state == 2) {\r\n\t\t\t\tawait acceptOrder({\r\n\t\t\t\t\t\torder_id: detail.orderId,\r\n\t\t\t\t\t\tlatitude: locationPayload['latitude'],\r\n\t\t\t\t\t\tlongitude: locationPayload['longitude']\r\n\t\t\t\t\t} as UTSJSONObject)\r\n\t\t\t} else if (detail.state == 4) {\r\n\t\t\t\tawait departOrder(detail.orderId, locationPayload)\r\n\t\t\t} else if (detail.state == 5) {\r\n\t\t\t\tawait arriveOrder(detail.orderId, locationPayload)\r\n\t\t\t} else if (detail.state == 10) {\r\n\t\t\t\tawait leaveOrder(detail.orderId, locationPayload)\r\n\t\t\t}\r\n\t\t\tuni.showToast({ title: '操作成功', icon: 'none' })\r\n\t\t\tloadDetail()\r\n\t\t} catch (error) {\r\n\t\t\tuni.showToast({ title: '操作失败', icon: 'none' })\r\n\t\t}\r\n\t}\r\n\r\n\tonLoad((option : UTSJSONObject) => {\r\n\t\t\tdetail.orderId = (option['orderId'] as string | null) ?? ''\r\n\t\t\tloadDetail()\r\n\t\t})\r\n</script>\r\n\r\n<style>\r\n\t.page-scroll {\r\n\t\tflex: 1;\r\n\t}\r\n\r\n\t.page {\r\n\t\tmin-height: 1000rpx;\r\n\t\tpadding: 0;\r\n\t\tbox-sizing: border-box;\r\n\t\tbackground-color: #f5f5f5;\r\n\t\tflex-direction: column;\r\n\t}\r\n\r\n\t.header-card {\r\n\t\tpadding: 36rpx;\r\n\t\tbackground-color: #ffdb5a;\r\n\t\tflex-direction: column;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.header-status {\r\n\t\tflex-direction: row;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.header-status-icon {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #3a3330;\r\n\t\tmargin-right: 8rpx;\r\n\t}\r\n\r\n\t.header-status-text {\r\n\t\tfont-size: 32rpx;\r\n\t\tfont-weight: 700;\r\n\t\tcolor: #3a3330;\r\n\t}\r\n\r\n\t.section-card {\r\n\t\tmargin-top: 12rpx;\r\n\t\tpadding: 24rpx;\r\n\t\tbackground-color: #ffffff;\r\n\t\tflex-direction: column;\r\n\t}\r\n\r\n\t.address-section {\r\n\t\tmargin-bottom: 20rpx;\r\n\t}\r\n\r\n\t.address-label {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #ff9500;\r\n\t\tmargin-bottom: 8rpx;\r\n\t}\r\n\r\n\t.address-text {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #333333;\r\n\t\tline-height: 36rpx;\r\n\t}\r\n\r\n\t.phone-text {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #333333;\r\n\t\tmargin-top: 8rpx;\r\n\t}\r\n\r\n\t.time-section {\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: space-between;\r\n\t\talign-items: center;\r\n\t\tpadding-top: 16rpx;\r\n\t\tborder-top: 1rpx solid #f0f0f0;\r\n\t}\r\n\r\n\t.time-label {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #666666;\r\n\t}\r\n\r\n\t.time-value {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #333333;\r\n\t}\r\n\r\n\t.project-section {\r\n\t\tflex-direction: row;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.project-image {\r\n\t\twidth: 120rpx;\r\n\t\theight: 120rpx;\r\n\t\tborder-radius: 12rpx;\r\n\t\tmargin-right: 16rpx;\r\n\t}\r\n\r\n\t.project-info {\r\n\t\tflex: 1;\r\n\t}\r\n\r\n\t.project-title {\r\n\t\tfont-size: 28rpx;\r\n\t\tfont-weight: 600;\r\n\t\tcolor: #333333;\r\n\t\tmargin-bottom: 8rpx;\r\n\t}\r\n\r\n\t.project-duration {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #999999;\r\n\t}\r\n\r\n\t.project-price {\r\n\t\tfont-size: 32rpx;\r\n\t\tfont-weight: 700;\r\n\t\tcolor: #ff3b30;\r\n\t}\r\n\r\n\t.section-title {\r\n\t\tfont-size: 28rpx;\r\n\t\tfont-weight: 600;\r\n\t\tcolor: #333333;\r\n\t\tmargin-bottom: 16rpx;\r\n\t}\r\n\r\n\t.income-row {\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: space-between;\r\n\t\tmargin-bottom: 12rpx;\r\n\t}\r\n\r\n\t.income-label {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #666666;\r\n\t}\r\n\r\n\t.income-value {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #333333;\r\n\t}\r\n\r\n\t.income-total {\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: space-between;\r\n\t\tmargin-top: 16rpx;\r\n\t\tpadding-top: 16rpx;\r\n\t\tborder-top: 1rpx solid #f0f0f0;\r\n\t}\r\n\r\n\t.income-total-label {\r\n\t\tfont-size: 26rpx;\r\n\t\tfont-weight: 600;\r\n\t\tcolor: #333333;\r\n\t}\r\n\r\n\t.income-total-value {\r\n\t\tfont-size: 30rpx;\r\n\t\tfont-weight: 700;\r\n\t\tcolor: #ff3b30;\r\n\t}\r\n\r\n\t.order-info-row {\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: space-between;\r\n\t\tmargin-bottom: 16rpx;\r\n\t}\r\n\r\n\t.order-info-label {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #666666;\r\n\t}\r\n\r\n\t.order-info-value {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #333333;\r\n\t\tflex-direction: row;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.copy-button {\r\n\t\tmargin-left: 16rpx;\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #007aff;\r\n\t\tpadding: 4rpx 12rpx;\r\n\t\tborder: 1rpx solid #e0e0e0;\r\n\t\tborder-radius: 16rpx;\r\n\t}\r\n\r\n\t.progress-item {\r\n\t\tflex-direction: row;\r\n\t\tposition: relative;\r\n\t\tpadding-bottom: 32rpx;\r\n\t}\r\n\r\n\t.progress-item:last-child {\r\n\t\tpadding-bottom: 0;\r\n\t}\r\n\r\n\t.progress-dot {\r\n\t\twidth: 20rpx;\r\n\t\theight: 20rpx;\r\n\t\tborder-radius: 50%;\r\n\t\tbackground-color: #e0e0e0;\r\n\t\tmargin-right: 16rpx;\r\n\t\tposition: relative;\r\n\t\tz-index: 2;\r\n\t}\r\n\r\n\t.progress-line {\r\n\t\tposition: absolute;\r\n\t\tleft: 9rpx;\r\n\t\ttop: 20rpx;\r\n\t\twidth: 2rpx;\r\n\t\theight: 64rpx;\r\n\t\tbackground-color: #e0e0e0;\r\n\t\tz-index: 1;\r\n\t}\r\n\r\n\t.progress-item.active .progress-dot {\r\n\t\tbackground-color: #ff9500;\r\n\t}\r\n\r\n\t.progress-item.active .progress-line {\r\n\t\tbackground-color: #ff9500;\r\n\t}\r\n\r\n\t.progress-content {\r\n\t\tflex: 1;\r\n\t}\r\n\r\n\t.progress-text {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #999999;\r\n\t\tmargin-bottom: 4rpx;\r\n\t}\r\n\r\n\t.progress-text.active {\r\n\t\tcolor: #333333;\r\n\t\tfont-weight: 600;\r\n\t}\r\n\r\n\t.progress-time {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #999999;\r\n\t}\r\n\r\n\t.button-row {\r\n\t\tmargin-top: 32rpx;\r\n\t\tmargin-bottom: 32rpx;\r\n\t\tpadding: 0 24rpx;\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: space-between;\r\n\t}\r\n\r\n\t.secondary-button {\r\n\t\twidth: 48%;\r\n\t\theight: 88rpx;\r\n\t\tborder-radius: 44rpx;\r\n\t\tborder-width: 2rpx;\r\n\t\tborder-style: solid;\r\n\t\tborder-color: #ffdb5a;\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: center;\r\n\t\talign-items: center;\r\n\t\tbackground-color: #ffffff;\r\n\t}\r\n\r\n\t.secondary-button-text {\r\n\t\tfont-size: 28rpx;\r\n\t\tcolor: #3a3330;\r\n\t}\r\n\r\n\t.primary-button {\r\n\t\twidth: 48%;\r\n\t\theight: 88rpx;\r\n\t\tborder-radius: 44rpx;\r\n\t\tbackground-color: #ffdb5a;\r\n\t\tflex-direction: row;\r\n\t\tjustify-content: center;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.primary-button-text {\r\n\t\tfont-size: 28rpx;\r\n\t\tfont-weight: 700;\r\n\t\tcolor: #3a3330;\r\n\t}\r\n\r\n\t.primary-button.full-width {\r\n\t\twidth: 100%;\r\n\t}\r\n</style>"],"names":[],"mappings":"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"}
|