index.kt.map 112 KB

1
  1. {"version":3,"sources":["E:/install/HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/uni-console/src/runtime/app/socket.ts","App.uvue","utils/request.uts","pages/index/order.uvue","E:/install/HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/uni-console/src/runtime/app/index.ts","common/icon-map.uts","common/icon-map.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","pages/index/console.uvue","pages/index/my.uvue","pages/index/account.uvue","utils/api/workbenches.uts","pages/console/setOrderTime.uvue","pages/console/serviceProject.uvue"],"sourcesContent":["/// <reference types=\"@dcloudio/uni-app-x/types/uni/global\" />\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 })\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},\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>\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>","// request.uts - 无警告 最终版\r\nexport class RequestOptions {\r\n\turl : string = ''\r\n\tmethod : string = 'GET'\r\n\tparams : UTSJSONObject | null = null\r\n\tdata : UTSJSONObject | null = null\r\n\tshowLoading : boolean = true\r\n\tloadingMsg : string = '加载中'\r\n\tshowError : boolean = true\r\n}\r\n\r\n// 修复:any → any | null 声明可空,消除null判断警告\r\nfunction toUTSJSONObject(obj : any | null) : UTSJSONObject | null {\r\n\tif (obj == null) return null\r\n\tif (obj instanceof UTSJSONObject) return obj\r\n\r\n\tconst result = new UTSJSONObject()\r\n\tconst keys = UTSJSONObject.keys(obj as UTSJSONObject)\r\n\tfor (let i = 0; i < keys.length; i++) {\r\n\t\tconst key = keys[i]\r\n\t\tconst val = (obj as UTSJSONObject).get(key)\r\n\t\tif (val != null) {\r\n\t\t\tresult.set(key, val)\r\n\t\t}\r\n\t}\r\n\treturn result\r\n}\r\n\r\n// Map 转 UTSJSONObject\r\nfunction mapToUTSJSONObject(map : Map<string, string>) : UTSJSONObject {\r\n\tconst obj = new UTSJSONObject()\r\n\tmap.forEach((value : string, key : string) => {\r\n\t\tobj.set(key, value)\r\n\t})\r\n\treturn obj\r\n}\r\n// 修复:any → any | null\r\nfunction buildQueryString(params : any | null) : string {\r\n\tif (params == null) return ''\r\n\tconst obj = toUTSJSONObject(params)\r\n\tif (obj == null) return ''\r\n\r\n\tconst keys = UTSJSONObject.keys(obj)\r\n\tlet query = ''\r\n\tfor (let i = 0; i < keys.length; i++) {\r\n\t\tconst key = keys[i]\r\n\t\tconst val = obj.get(key)\r\n\t\tif (val != null) {\r\n\t\t\tif (query.length > 0) query += '&'\r\n\t\t\tquery += key + '=' + encodeURIComponent(val.toString())\r\n\t\t}\r\n\t}\r\n\treturn query\r\n}\r\n\r\nexport function request(options : any | 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\tconst opts = toUTSJSONObject(options)\r\n\t\tif (opts == null) {\r\n\t\t\treject(new Error('请求参数格式错误'))\r\n\t\t\treturn\r\n\t\t}\r\n\t\tconst baseURL = '/'\r\n\t\tconst url = opts.getString('url') ?? ''\r\n\t\tconst method = opts.getString('method') ?? 'GET'\r\n\t\tconst params = opts.get('params')\r\n\t\tconst data = opts.get('data')\r\n\t\tconst showLoading = opts.getBoolean('showLoading') ?? true\r\n\t\tconst loadingMsg = opts.getString('loadingMsg') ?? '加载中'\r\n\r\n\t\t// 拼接基础地址 + 接口地址\r\n\t\tlet finalUrl = baseURL + url.replace(/^\\//, '')\r\n\t\tconst upperMethod = method.toUpperCase()\r\n\r\n\t\t// GET 参数拼接\r\n\t\tif (upperMethod === 'GET' && params != null) {\r\n\t\t\tconst query = buildQueryString(params)\r\n\t\t\tif (query.length > 0) finalUrl += '?' + query\r\n\t\t}\r\n\r\n\r\n\r\n\t\tconst headerMap = new Map<string, string>()\r\n\t\theaderMap.set('Content-Type', 'application/json')\r\n\t\tconst token = uni.getStorageSync('token') as string\r\n\t\tif (token.length > 0) headerMap.set('Authorization', 'Bearer ' + token)\r\n\t\tconst tenantId = uni.getStorageSync('tenantId') as string | null\r\n\t\theaderMap.set('tenant-id', tenantId ?? 'default')\r\n\t\theaderMap.set('terminal', uni.getSystemInfoSync().platform)\r\n\t\tconst header = mapToUTSJSONObject(headerMap)\r\n\r\n\t\tlet requestData : string | null = null\r\n\t\tif (upperMethod !== 'GET' && data != null) {\r\n\t\t\trequestData = JSON.stringify(data)\r\n\t\t}\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\tuni.request({\r\n\t\t\turl: finalUrl,\r\n\t\t\tmethod: upperMethod,\r\n\t\t\tdata: requestData,\r\n\t\t\theader: header,\r\n\t\t\ttimeout: 15000,\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 as any ?? {})\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\treject(new Error('网络错误:' + err.errMsg))\r\n\t\t\t}\r\n\t\t})\r\n\t})\r\n}","<template>\r\n <view class=\"page-container\">\r\n\r\n <!-- 1. 顶部标签栏 (Scroll View) -->\r\n <scroll-view scroll-x class=\"tab-scroll\" show-scrollbar=\"false\" :enable-flex=\"true\">\r\n <view class=\"tab-wrapper\">\r\n <view v-for=\"(tab, index) in tabs\" :key=\"index\"\r\n :class=\"['tab-item', currentTab === index ? 'active' : '']\" @click=\"currentTab = index\">\r\n <text>\r\n {{ tab }}\r\n </text>\r\n <!-- 激活下的黄色短线 -->\r\n <view v-if=\"currentTab === index\" class=\"tab-indicator\">\r\n </view>\r\n </view>\r\n </view>\r\n </scroll-view>\r\n\r\n <!-- 2. 订单列表 -->\r\n <view class=\"order-list\">\r\n <view v-for=\"(order, idx) in orders\" :key=\"order['id']\" class=\"order-card\">\r\n\r\n <!-- Card Header: 时间 & 状态 -->\r\n <view class=\"card-header\">\r\n <text class=\"time-text\">\r\n 预约时间:{{ order['time'] }}\r\n </text>\r\n <text class=\"status-badge paid\">\r\n 已支付\r\n </text>\r\n </view>\r\n\r\n <!-- Card Body: 服务信息 (左图右文) -->\r\n <view class=\"service-section\">\r\n <image :src=\"order['image']\" class=\"service-image\" mode=\"aspectFill\" />\r\n <view class=\"service-details\">\r\n <view class=\"service-title-row\">\r\n <text class=\"service-name\">\r\n {{ order['serviceName'] }}\r\n </text>\r\n <text v-for=\"(tag, tIdx) in tagList(order)\" :key=\"tIdx\" :class=\"['tag-pill', tag.type]\">\r\n {{ tag.text }}\r\n </text>\r\n\r\n </view>\r\n <view class=\"contact-info-row\">\r\n <text class=\"contact-info\">\r\n 联系人:{{ order['contact'] }}\r\n </text>\r\n\r\n <text class=\"tag-pill green \">\r\n 新客\r\n </text>\r\n\r\n </view>\r\n </view>\r\n <text class=\"service-price\">\r\n ¥{{ order.price }}\r\n </text>\r\n </view>\r\n <!-- Card Address: 地址 & 距离 -->\r\n <view class=\"address-section\">\r\n <u-icon type=\"location\" size=\"16\" color=\"#999999\">\r\n </u-icon>\r\n <text class=\"address-content\">\r\n {{ order.address }}\r\n </text>\r\n <text class=\"distance-text\">\r\n {{ order.distance }}km\r\n </text>\r\n </view>\r\n\r\n <!-- Card Income: 预估收入 -->\r\n <view class=\"income-section\">\r\n <text class=\"income-label\">\r\n 预估收入\r\n </text>\r\n <view class=\"income-value-group\">\r\n <text class=\"income-main\">\r\n ¥{{ order.income }}\r\n </text>\r\n <text class=\"income-sub\">\r\n (含路费)\r\n </text>\r\n </view>\r\n </view>\r\n\r\n <!-- Card Actions: 按钮组 -->\r\n <view class=\"action-section\">\r\n <view class=\"btn btn-nav\" @click=\"onNavigate(order.address)\">\r\n <u-icon type=\"navigation\" size=\"14\" color=\"#333333\">\r\n </u-icon>\r\n <text>\r\n 地址导航\r\n </text>\r\n </view>\r\n <text class=\"btn btn-transfer\" @click=\"onTransfer(order.id)\">\r\n 我要转单\r\n </text>\r\n <text class=\"btn btn-confirm\" @click=\"onConfirm(order.id)\">\r\n 确认接单\r\n </text>\r\n </view>\r\n </view>\r\n </view>\r\n </view>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n import { ref } from 'vue';\r\n\r\n // --- 数据 ---\r\n const tabs = ['新订单',\r\n '进行中',\r\n '取消/售后',\r\n '已完成',\r\n '全部'];\r\n const currentTab = ref(0);\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\ttype OrderItem = {\r\n\t\tid : number;\r\n\t\ttime : string;\r\n\t\tserviceName : string;\r\n\t\ttags : OrderTag[];\r\n\t\tcontact : string;\r\n\t\tprice : string;\r\n\t\taddress : string;\r\n\t\tdistance : string;\r\n\t\tincome : string;\r\n\t\timage : string;\r\n\t};\r\n\r\n // orders data – no need for reactivity, use a plain typed array\r\n const orders : OrderItem[] = [\r\n {\r\n id: 1,\r\n time: '2025-06-18 4:00',\r\n serviceName: '润养SPA',\r\n tags: [\r\n { text: '上门', type: 'orange' } as OrderTag,\r\n { text: '首单', type: 'orange' } as OrderTag,\r\n ],\r\n contact: '刘',\r\n price: '286.6',\r\n address: '烟台 芝罘区楚风一街楚凤花园(烟台吾悦)广场附近',\r\n distance: '2.24',\r\n income: '186.6',\r\n image: '/static/testInfo/demo.png'\r\n },\r\n {\r\n id: 2,\r\n time: '2025-06-18 8:00',\r\n serviceName: '润养SPA',\r\n tags: [\r\n { text: '加钟', type: 'red' } as OrderTag\r\n ],\r\n contact: '刘',\r\n price: '286.6',\r\n address: '烟台 芝罘区楚风一街楚凤花园(烟台吾悦)广场附近',\r\n distance: '2.24',\r\n income: '186.6',\r\n image: '/static/testInfo/demo.png'\r\n }\r\n ] as OrderItem[];\r\n\r\n // --- 方法 ---\r\n const onNavigate = (addr : string) => {\r\n uni.showToast({ title: '启动导航', icon: 'none' });\r\n };\r\n\r\n // helper used in template to give v-for a typed array source\r\n function tagList(order: OrderItem): OrderTag[] {\r\n return order.tags;\r\n }\r\n\r\n const onTransfer = (id : number) => {\r\n uni.showModal({\r\n title: '转单确认',\r\n content: '确定将此订单转给其他技师吗?',\r\n success: (res) => {\r\n if (res.confirm) uni.showToast({ title: '转单成功', icon: 'success' });\r\n }\r\n });\r\n };\r\n\r\n const onConfirm = (id : number) => {\r\n uni.showLoading({ title: '处理中...' });\r\n setTimeout(() => {\r\n uni.hideLoading();\r\n uni.showToast({ title: '接单成功', icon: 'success' });\r\n }, 600);\r\n };\r\n</script>\r\n\r\n<style scoped>\r\n .page-container {\r\n background-color: #f5f6f8;\r\n /* min-height: 100vh; unsupported by uvue, replace with fixed value or remove */\r\n min-height: 1000rpx;\r\n /* width: 100%; */ /* 默认块级元素已撑满父容器 */\r\n /* 确保内部元素不溢出 */\r\n box-sizing: border-box;\r\n }\r\n\r\n /* --- Tab 区域 --- */\r\n .tab-scroll {\r\n /* width: 100%; */ /* 不使用百分比 */\r\n background-color: #ffffff;\r\n /* 固定高度或自适应 */\r\n height: 88rpx;\r\n }\r\n\r\n .tab-wrapper {\r\n display: flex;\r\n /* 内部横向排列 */\r\n flex-direction: row;\r\n align-items: center;\r\n /* 直接使用固定高度匹配 .tab-scroll */\r\n height: 88rpx;\r\n padding: 0 20rpx;\r\n white-space: nowrap;\r\n }\r\n\r\n .tab-item {\r\n position: relative;\r\n padding: 0 30rpx;\r\n /* 高度与容器一致,避免百分比 */\r\n height: 88rpx;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n font-size: 30rpx;\r\n color: #666666;\r\n }\r\n\r\n .tab-item.active {\r\n color: #333333;\r\n font-weight: bold;\r\n }\r\n\r\n .tab-indicator {\r\n position: absolute;\r\n bottom: 16rpx;\r\n left: 0;\r\n right: 0;\r\n margin: 0 auto;\r\n width: 40rpx;\r\n height: 6rpx;\r\n background-color: #ffc107;\r\n border-radius: 3rpx;\r\n }\r\n\r\n /* --- 列表区域 --- */\r\n .order-list {\r\n padding: 20rpx;\r\n /* 垂直排列卡片 */\r\n display: flex;\r\n flex-direction: column;\r\n /* gap: 20rpx; */\r\n }\r\n\r\n .order-card {\r\n background-color: #ffffff;\r\n border-radius: 16rpx;\r\n padding: 30rpx;\r\n /* 卡片内部也是垂直流 */\r\n display: flex;\r\n flex-direction: column;\r\n /* gap: 20rpx; */\r\n }\r\n\r\n /* 1. 头部 */\r\n .card-header {\r\n display: flex;\r\n flex-direction: row;\r\n /* 左右布局 */\r\n justify-content: space-between;\r\n align-items: center;\r\n }\r\n\r\n .time-text {\r\n font-size: 28rpx;\r\n color: #333333;\r\n font-weight: 400;\r\n /* use supported weight */\r\n }\r\n\r\n .status-badge {\r\n font-size: 24rpx;\r\n padding: 6rpx 16rpx;\r\n border-radius: 20rpx;\r\n }\r\n\r\n .status-badge.paid {\r\n background-color: #fff7e6;\r\n color: #ff9900;\r\n }\r\n\r\n /* 2. 服务信息 (左图右文) */\r\n .service-section {\r\n display: flex;\r\n flex-direction: row;\r\n /* 关键:横向排列图和文 */\r\n align-items: flex-start;\r\n /* gap: 20rpx; */\r\n }\r\n\r\n .service-image {\r\n width: 110rpx;\r\n height: 110rpx;\r\n border-radius: 12rpx;\r\n background-color: #f0f0f0;\r\n flex-shrink: 0;\r\n /* 防止图片被压缩 */\r\n }\r\n\r\n .service-details {\r\n flex: 1;\r\n display: flex;\r\n /* flex-direction: column; */\r\n /* 文字内部垂直排列 */\r\n justify-content: space-between;\r\n /* height: 110rpx; */\r\n\r\n }\r\n\r\n .service-title-row {\r\n display: flex;\r\n flex-direction: row;\r\n /* justify-content: space-between; */\r\n align-items: center;\r\n }\r\n\r\n .service-name {\r\n font-size: 32rpx;\r\n font-weight: bold;\r\n color: #333333;\r\n }\r\n\r\n .service-price {\r\n font-size: 34rpx;\r\n font-weight: bold;\r\n color: #333333;\r\n }\r\n\r\n .tags-container {\r\n display: flex;\r\n flex-direction: row;\r\n /* gap: 12rpx; */\r\n flex-wrap: wrap;\r\n }\r\n\r\n .tag-pill {\r\n font-size: 22rpx;\r\n padding: 4rpx 12rpx;\r\n border-radius: 20rpx;\r\n border-width: 1rpx;\r\n border-style: solid;\r\n line-height: 1.2;\r\n }\r\n\r\n .tag-pill.orange {\r\n color: #ff9900;\r\n border-color: #ff9900;\r\n background-color: #fffaf0;\r\n }\r\n\r\n .tag-pill.green {\r\n color: #52c41a;\r\n border-color: #52c41a;\r\n background-color: #f6ffed;\r\n }\r\n\r\n .tag-pill.red {\r\n color: #ff4d4f;\r\n border-color: #ff4d4f;\r\n background-color: #fff1f0;\r\n }\r\n\r\n .contact-info-row {\r\n display: flex;\r\n flex-direction: row;\r\n align-items: center;\r\n /* gap: 20rpx; */\r\n }\r\n\r\n .contact-info {\r\n font-size: 26rpx;\r\n color: #999999;\r\n }\r\n\r\n /* 3. 地址栏 */\r\n .address-section {\r\n display: flex;\r\n flex-direction: row;\r\n align-items: flex-start;\r\n padding-bottom: 20rpx;\r\n border-bottom-width: 1rpx;\r\n border-bottom-color: #f5f5f5;\r\n border-bottom-style: solid;\r\n /* gap: 10rpx; */\r\n }\r\n\r\n .address-content {\r\n flex: 1;\r\n font-size: 26rpx;\r\n color: #666666;\r\n line-height: 1.4;\r\n /* multi-line ellipsis removed; not supported by uvue */\r\n /* display: -webkit-box;\r\n -webkit-line-clamp: 2;\r\n -webkit-box-orient: vertical;\r\n overflow: hidden;\r\n */\r\n }\r\n\r\n .distance-text {\r\n font-size: 24rpx;\r\n color: #999999;\r\n white-space: nowrap;\r\n margin-left: 10rpx;\r\n }\r\n\r\n /* 4. 收入栏 */\r\n .income-section {\r\n display: flex;\r\n flex-direction: row;\r\n justify-content: space-between;\r\n align-items: center;\r\n }\r\n\r\n .income-label {\r\n font-size: 28rpx;\r\n color: #666666;\r\n }\r\n\r\n .income-value-group {\r\n display: flex;\r\n flex-direction: row;\r\n align-items: center;\r\n /* baseline not supported */\r\n /* */\r\n }\r\n\r\n .income-main {\r\n font-size: 36rpx;\r\n font-weight: bold;\r\n color: #ff4d4f;\r\n }\r\n\r\n .income-sub {\r\n font-size: 24rpx;\r\n color: #999999;\r\n }\r\n\r\n /* 5. 按钮组 */\r\n .action-section {\r\n display: flex;\r\n flex-direction: row;\r\n justify-content: space-between;\r\n /* gap: 20rpx; */\r\n }\r\n\r\n .btn {\r\n flex: 1;\r\n height: 72rpx;\r\n border-radius: 36rpx;\r\n font-size: 28rpx;\r\n font-weight: 400;\r\n display: flex;\r\n flex-direction: row;\r\n /* 按钮内图标和文字横向 */\r\n justify-content: center;\r\n align-items: center;\r\n /* */\r\n }\r\n\r\n .btn-nav {\r\n background-color: #f5f5f5;\r\n color: #333333;\r\n }\r\n\r\n .btn-transfer {\r\n background-color: #ffffff;\r\n color: #ff9900;\r\n border-width: 1rpx;\r\n border-color: #ff9900;\r\n border-style: solid;\r\n }\r\n\r\n .btn-confirm {\r\n background-color: #ffc107;\r\n color: #333333;\r\n border-width: 1rpx;\r\n border-color: #ffc107;\r\n border-style: solid;\r\n }\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 __registerWebViewUniConsole(\n (): string => {\n return process.env.UNI_CONSOLE_WEBVIEW_EVAL_JS_CODE\n },\n (data: string) => {\n socketTask?.send({\n data,\n } as SendSocketMessageOptions)\n }\n )\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","// 由脚本自动生成,请勿手动修改\nexport const iconMap = {\n \"alipay\": \"/static/icons/alipay.svg\",\n \"arrow_down\": \"/static/icons/arrow_down.svg\",\n \"arrow_left\": \"/static/icons/arrow_left.svg\",\n \"arrow_right\": \"/static/icons/arrow_right.svg\",\n \"arrow_up\": \"/static/icons/arrow_up.svg\",\n \"calculator\": \"/static/icons/calculator.svg\",\n \"cart\": \"/static/icons/cart.svg\",\n \"cart_empty\": \"/static/icons/cart_empty.svg\",\n \"caution\": \"/static/icons/caution.svg\",\n \"caution_filled\": \"/static/icons/caution_filled.svg\",\n \"check\": \"/static/icons/check.svg\",\n \"check_filled\": \"/static/icons/check_filled.svg\",\n \"close\": \"/static/icons/close.svg\",\n \"close_filled\": \"/static/icons/close_filled.svg\",\n \"copy\": \"/static/icons/copy.svg\",\n \"customer-interests\": \"/static/icons/customer-interests.svg\",\n \"customer_service\": \"/static/icons/customer_service.svg\",\n \"discount\": \"/static/icons/discount.svg\",\n \"download\": \"/static/icons/download.svg\",\n \"down_to_bottom\": \"/static/icons/down_to_bottom.svg\",\n \"edit\": \"/static/icons/edit.svg\",\n \"email\": \"/static/icons/email.svg\",\n \"ET\": \"/static/icons/ET.svg\",\n \"filter\": \"/static/icons/filter.svg\",\n \"flow\": \"/static/icons/flow.svg\",\n \"forbidden\": \"/static/icons/forbidden.svg\",\n \"forbidden_filled\": \"/static/icons/forbidden_filled.svg\",\n \"help\": \"/static/icons/help.svg\",\n \"help_filled\": \"/static/icons/help_filled.svg\",\n \"image\": \"/static/icons/image.svg\",\n \"info\": \"/static/icons/info.svg\",\n \"info_filled\": \"/static/icons/info_filled.svg\",\n \"international\": \"/static/icons/international.svg\",\n \"like\": \"/static/icons/like.svg\",\n \"like_filled\": \"/static/icons/like_filled.svg\",\n \"link\": \"/static/icons/link.svg\",\n \"list\": \"/static/icons/list.svg\",\n \"lock\": \"/static/icons/lock.svg\",\n \"message\": \"/static/icons/message.svg\",\n \"message_unread\": \"/static/icons/message_unread.svg\",\n \"navigation\": \"/static/icons/navigation.svg\",\n \"notification\": \"/static/icons/notification.svg\",\n \"notification_off\": \"/static/icons/notification_off.svg\",\n \"order_unread\": \"/static/icons/order_unread.svg\",\n \"page_first\": \"/static/icons/page_first.svg\",\n \"page_last\": \"/static/icons/page_last.svg\",\n \"page_turning_left\": \"/static/icons/page_turning_left.svg\",\n \"page_turning_right\": \"/static/icons/page_turning_right.svg\",\n \"partner\": \"/static/icons/partner.svg\",\n \"phonecall\": \"/static/icons/phonecall.svg\",\n \"phonecall_off\": \"/static/icons/phonecall_off.svg\",\n \"play\": \"/static/icons/play.svg\",\n \"record\": \"/static/icons/record.svg\",\n \"refresh\": \"/static/icons/refresh.svg\",\n \"region\": \"/static/icons/region.svg\",\n \"search\": \"/static/icons/search.svg\",\n \"setting\": \"/static/icons/setting.svg\",\n \"share\": \"/static/icons/share.svg\",\n \"show_less\": \"/static/icons/show_less.svg\",\n \"show_more\": \"/static/icons/show_more.svg\",\n \"social_wechat\": \"/static/icons/social_wechat.svg\",\n \"star\": \"/static/icons/star.svg\",\n \"star_filled\": \"/static/icons/star_filled.svg\",\n \"store\": \"/static/icons/store.svg\",\n \"sub_account\": \"/static/icons/sub_account.svg\",\n \"time\": \"/static/icons/time.svg\",\n \"unlock\": \"/static/icons/unlock.svg\",\n \"upload\": \"/static/icons/upload.svg\",\n \"up_to_top\": \"/static/icons/up_to_top.svg\",\n \"user\": \"/static/icons/user.svg\",\n \"view\": \"/static/icons/view.svg\",\n \"view_off\": \"/static/icons/view_off.svg\"\n} as UTSJSONObject;\n//# sourceMappingURL=icon-map.uts.map","\n// 由脚本自动生成,请勿手动修改\nexport const iconMap = {\n \"alipay\": \"/static/icons/alipay.svg\",\n \"arrow_down\": \"/static/icons/arrow_down.svg\",\n \"arrow_left\": \"/static/icons/arrow_left.svg\",\n \"arrow_right\": \"/static/icons/arrow_right.svg\",\n \"arrow_up\": \"/static/icons/arrow_up.svg\",\n \"calculator\": \"/static/icons/calculator.svg\",\n \"cart\": \"/static/icons/cart.svg\",\n \"cart_empty\": \"/static/icons/cart_empty.svg\",\n \"caution\": \"/static/icons/caution.svg\",\n \"caution_filled\": \"/static/icons/caution_filled.svg\",\n \"check\": \"/static/icons/check.svg\",\n \"check_filled\": \"/static/icons/check_filled.svg\",\n \"close\": \"/static/icons/close.svg\",\n \"close_filled\": \"/static/icons/close_filled.svg\",\n \"copy\": \"/static/icons/copy.svg\",\n \"customer-interests\": \"/static/icons/customer-interests.svg\",\n \"customer_service\": \"/static/icons/customer_service.svg\",\n \"discount\": \"/static/icons/discount.svg\",\n \"download\": \"/static/icons/download.svg\",\n \"down_to_bottom\": \"/static/icons/down_to_bottom.svg\",\n \"edit\": \"/static/icons/edit.svg\",\n \"email\": \"/static/icons/email.svg\",\n \"ET\": \"/static/icons/ET.svg\",\n \"filter\": \"/static/icons/filter.svg\",\n \"flow\": \"/static/icons/flow.svg\",\n \"forbidden\": \"/static/icons/forbidden.svg\",\n \"forbidden_filled\": \"/static/icons/forbidden_filled.svg\",\n \"help\": \"/static/icons/help.svg\",\n \"help_filled\": \"/static/icons/help_filled.svg\",\n \"image\": \"/static/icons/image.svg\",\n \"info\": \"/static/icons/info.svg\",\n \"info_filled\": \"/static/icons/info_filled.svg\",\n \"international\": \"/static/icons/international.svg\",\n \"like\": \"/static/icons/like.svg\",\n \"like_filled\": \"/static/icons/like_filled.svg\",\n \"link\": \"/static/icons/link.svg\",\n \"list\": \"/static/icons/list.svg\",\n \"lock\": \"/static/icons/lock.svg\",\n \"message\": \"/static/icons/message.svg\",\n \"message_unread\": \"/static/icons/message_unread.svg\",\n \"navigation\": \"/static/icons/navigation.svg\",\n \"notification\": \"/static/icons/notification.svg\",\n \"notification_off\": \"/static/icons/notification_off.svg\",\n \"order_unread\": \"/static/icons/order_unread.svg\",\n \"page_first\": \"/static/icons/page_first.svg\",\n \"page_last\": \"/static/icons/page_last.svg\",\n \"page_turning_left\": \"/static/icons/page_turning_left.svg\",\n \"page_turning_right\": \"/static/icons/page_turning_right.svg\",\n \"partner\": \"/static/icons/partner.svg\",\n \"phonecall\": \"/static/icons/phonecall.svg\",\n \"phonecall_off\": \"/static/icons/phonecall_off.svg\",\n \"play\": \"/static/icons/play.svg\",\n \"record\": \"/static/icons/record.svg\",\n \"refresh\": \"/static/icons/refresh.svg\",\n \"region\": \"/static/icons/region.svg\",\n \"search\": \"/static/icons/search.svg\",\n \"setting\": \"/static/icons/setting.svg\",\n \"share\": \"/static/icons/share.svg\",\n \"show_less\": \"/static/icons/show_less.svg\",\n \"show_more\": \"/static/icons/show_more.svg\",\n \"social_wechat\": \"/static/icons/social_wechat.svg\",\n \"star\": \"/static/icons/star.svg\",\n \"star_filled\": \"/static/icons/star_filled.svg\",\n \"store\": \"/static/icons/store.svg\",\n \"sub_account\": \"/static/icons/sub_account.svg\",\n \"time\": \"/static/icons/time.svg\",\n \"unlock\": \"/static/icons/unlock.svg\",\n \"upload\": \"/static/icons/upload.svg\",\n \"up_to_top\": \"/static/icons/up_to_top.svg\",\n \"user\": \"/static/icons/user.svg\",\n \"view\": \"/static/icons/view.svg\",\n \"view_off\": \"/static/icons/view_off.svg\"\n};\n","import 'E:/install/HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/uni-console/src/runtime/app/index.ts';import App from './App.uvue'\r\n\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 = \"4.87\"\n \n constructor() { super() }\n}\n\nimport GenPagesIndexConsoleClass from './pages/index/console.uvue'\nimport GenPagesIndexMyClass from './pages/index/my.uvue'\nimport GenPagesIndexOrderClass from './pages/index/order.uvue'\nimport GenPagesIndexAccountClass from './pages/index/account.uvue'\nimport GenPagesConsoleSetOrderTimeClass from './pages/console/setOrderTime.uvue'\nimport GenPagesLoginLoginClass from './pages/login/login.uvue'\nimport GenPagesConsoleServiceProjectClass from './pages/console/serviceProject.uvue'\nimport GenPagesMyEditMyEditClass from './pages/myEdit/myEdit.uvue'\nfunction definePageRoutes() {\n__uniRoutes.push({ path: \"pages/index/console\", component: GenPagesIndexConsoleClass, meta: { isQuit: true } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"控制台\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/index/my\", component: GenPagesIndexMyClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"我的\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/index/order\", component: GenPagesIndexOrderClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"订单\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/index/account\", component: GenPagesIndexAccountClass, meta: { isQuit: false } as UniPageMeta, style: _uM([[\"navigationBarTitleText\",\"账户\"]]) } as UniPageRoute)\n__uniRoutes.push({ path: \"pages/console/setOrderTime\", component: GenPagesConsoleSetOrderTimeClass, 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/console/serviceProject\", component: GenPagesConsoleServiceProjectClass, 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}\nconst __uniTabBar: Map<string, any | null> | null = _uM([[\"selectedColor\",\"#000000\"],[\"backgroundColor\",\"#ffffff\"],[\"list\",[_uM([[\"pagePath\",\"pages/index/console\"],[\"iconPath\",\"static/iconInfo/noactive/homepage.png\"],[\"selectedIconPath\",\"static/iconInfo/active/homepage.png\"],[\"text\",\"控制台\"]]),_uM([[\"pagePath\",\"pages/index/order\"],[\"iconPath\",\"static/iconInfo/noactive/order.png\"],[\"selectedIconPath\",\"static/iconInfo/active/order.png\"],[\"text\",\"订单\"]]),_uM([[\"pagePath\",\"pages/index/account\"],[\"iconPath\",\"static/iconInfo/noactive/account.png\"],[\"selectedIconPath\",\"static/iconInfo/active/account.png\"],[\"text\",\"账户\"]]),_uM([[\"pagePath\",\"pages/index/my\"],[\"iconPath\",\"static/iconInfo/noactive/myhome.png\"],[\"selectedIconPath\",\"static/iconInfo/active/myhome.png\"],[\"text\",\"我的\"]])]]])\nconst __uniLaunchPage: Map<string, any | null> = _uM([[\"url\",\"pages/index/console\"],[\"style\",_uM([[\"navigationBarTitleText\",\"控制台\"]])]])\nfunction defineAppConfig(){\n __uniConfig.entryPagePath = '/pages/index/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/index/console\"],[\"iconPath\",\"static/iconInfo/noactive/homepage.png\"],[\"selectedIconPath\",\"static/iconInfo/active/homepage.png\"],[\"text\",\"控制台\"]]),_uM([[\"pagePath\",\"pages/index/order\"],[\"iconPath\",\"static/iconInfo/noactive/order.png\"],[\"selectedIconPath\",\"static/iconInfo/active/order.png\"],[\"text\",\"订单\"]]),_uM([[\"pagePath\",\"pages/index/account\"],[\"iconPath\",\"static/iconInfo/noactive/account.png\"],[\"selectedIconPath\",\"static/iconInfo/active/account.png\"],[\"text\",\"账户\"]]),_uM([[\"pagePath\",\"pages/index/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\"","<template>\r\n\t<scroll-view style=\"flex:1\">\r\n\r\n\t\t<view class=\"page\">\r\n\t\t\t<image class=\"upContent\" src=\"@/static/imagesInfo/bg-color.png\" mode=\"aspectFill\">\r\n\t\t\t</image>\r\n\r\n\t\t\t<view class=\"city-info\">\r\n\t\t\t\t<view>\r\n\t\t\t\t\t<text class=\"city-text-box\">\r\n\t\t\t\t\t\t当前城市:{{ cityInfo }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t\t<u-icon name=\"notification\" :size=\"24\" />\r\n\t\t\t</view>\r\n\t\t\t<!-- 用户卡片 -->\r\n\t\t\t<view class=\"user-card \">\r\n\t\t\t\t<image class=\"user-bg\" src=\"@/static/imagesInfo/bg-icon.png\" mode=\"scaleToFill\">\r\n\t\t\t\t</image>\r\n\t\t\t\t<view class=\"user-info\" style=\"padding: 20rpx;\">\r\n\t\t\t\t\t<view class=\"user-left\">\r\n\t\t\t\t\t\t<view class=\"user-info\">\r\n\t\t\t\t\t\t\t<text class=\"user-name\">\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<view class=\"tags\">\r\n\t\t\t\t\t\t\t\t<text class=\"tag-new\">\r\n\t\t\t\t\t\t\t\t\t新人实习\r\n\t\t\t\t\t\t\t\t</text>\r\n\r\n\t\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t\t<u-icon name=\"edit\" :size=\"18\" @click=\"jumpMasterInfo\" />\r\n\t\t\t\t\t\t\t<text class=\"tag\">\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 class=\"user-info\">\r\n\t\t\t\t\t\t\t<u-icon name=\"customer-interests\" :size=\"18\" />\r\n\t\t\t\t\t\t\t<text class=\"user-role\">\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=\"store\" :size=\"18\" />\r\n\t\t\t\t\t\t\t<text class=\"user-shop\">\r\n\t\t\t\t\t\t\t\t佳人有约\r\n\t\t\t\t\t\t\t</text>\r\n\r\n\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t<view class=\"online-switch\">\r\n\t\t\t\t\t\t\t<u-switch :checked=\"isOnline\" @change=\"toggleOnline\" />\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=\"user-right\" @click=\"jumpMasterInfo\">\r\n\t\t\t\t\t\t<text class=\"text-time-box\">\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=\"text-time-box\" style=\"margin-top: 5rpx;\">2026.03.01{{\r\n\t\t\t\t\t\t\tcoachInfo?.created_at.split(' ')[0] }}\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t<image v-if=\"coachInfo!=null && coachInfo.avatar_url!=null\"\r\n\t\t\t\t\t\t:src=\"coachInfo!.avatar_url!.url\"\r\n\t\t\t\t\t\tstyle=\"width: 138rpx;height:138rpx;border-radius: 69rpx;margin-top: 15rpx;\"\r\n\t\t\t\t\t\tmode=\"aspectFit\">\r\n\t\t\t\t\t\t</image>\r\n\t\t\t\t\t\t<image v-else src=\"/static/testInfo/boy-nickname.png\"\r\n\t\t\t\t\t\tstyle=\"width: 138rpx;height:138rpx;border-radius: 69rpx;margin-top: 15rpx;\"\r\n\t\t\t\t\t\tmode=\"aspectFit\">\r\n\t\t\t\t\t\t</image>\r\n\t\t\t\t\t</view>\r\n\t\t\t\t</view>\r\n\r\n\t\t\t\t<view class=\"location-bar user-info\">\r\n\t\t\t\t\t<u-icon name=\"navigation\" :size=\"18\" />\r\n\t\t\t\t\t<text class=\"location-text\">\r\n\t\t\t\t\t\t当前定位:烟台市楚凤一街1号楚凤花园\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text class=\"location-btn\">\r\n\t\t\t\t\t\t手动更新\r\n\t\t\t\t\t</text>\r\n\r\n\t\t\t\t</view>\r\n\r\n\t\t\t</view>\r\n\t\t\t<!-- 本月数据 -->\r\n\t\t\t<view class=\"stats-row\">\r\n\t\t\t\t<view class=\"stat-item\">\r\n\t\t\t\t\t<text class=\"stat-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=\"stat-value\">\r\n\t\t\t\t\t\t2234.88\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t\t<view class=\"stat-divider\">\r\n\t\t\t\t</view>\r\n\t\t\t\t<view class=\"stat-item\">\r\n\t\t\t\t\t<text class=\"stat-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=\"stat-value\">\r\n\t\t\t\t\t\t2234.88\r\n\t\t\t\t\t</text>\r\n\t\t\t\t</view>\r\n\t\t\t\t<view class=\"stat-divider\">\r\n\t\t\t\t</view>\r\n\t\t\t\t<view class=\"stat-item\">\r\n\t\t\t\t\t<text class=\"stat-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=\"stat-value\">\r\n\t\t\t\t\t\t30%\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<!-- 功能按钮 -->\r\n\t\t\t<view class=\"func-grid\">\r\n\t\t\t\t<view class=\"func-item\" v-for=\"(item, i) in funcList\" :key=\"i\">\r\n\t\t\t\t\t<view @click.stop=\"jumpSetProject(item.label as string)\">\r\n\t\t\t\t\t\t<image style=\" width: 92rpx;height: 92rpx;\" :src=\"item.iconUrl\" mode=\"aspectFit\">\r\n\t\t\t\t\t\t</image>\r\n\t\t\t\t\t\t<text class=\"func-label\">\r\n\t\t\t\t\t\t\t{{ item.label }}\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</view>\r\n\t\t\t</view>\r\n\r\n\t\t\t<!-- 数据统计 -->\r\n\t\t\t<view class=\"data-section\">\r\n\t\t\t\t<view class=\"section-header\">\r\n\t\t\t\t\t<text class=\"section-title\">\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=\"section-more\">\r\n\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=\"data-grid\">\r\n\t\t\t\t\t\t<view class=\"data-item\" v-for=\"(item, i) in dataStats\" :key=\"i\">\r\n\t\t\t\t\t\t\t<text class=\"data-value\">\r\n\t\t\t\t\t\t\t\t{{ item.value }}\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t<text class=\"data-label\">\r\n\t\t\t\t\t\t\t\t{{ item.label }}\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=\"eval-section\">\r\n\t\t\t\t\t<view class=\"section-header\">\r\n\t\t\t\t\t\t<text class=\"section-title\">\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=\"section-more\">\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\t\t\t\t\t\t<view class=\"eval-tags\">\r\n\t\t\t\t\t\t\t<text class=\"eval-tag\" v-for=\"(tag, i) in evalTags\" :key=\"i\">\r\n\t\t\t\t\t\t\t\t{{ tag.text }} {{ tag.count > 0 ? tag.count : '' }}\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=\"eval-item\">\r\n\t\t\t\t\t\t\t\t<image class=\"eval-avatar\" src=\"/static/testInfo/boy-nickname.png\" mode=\"aspectFill\" />\r\n\t\t\t\t\t\t\t\t<view class=\"eval-content\">\r\n\t\t\t\t\t\t\t\t\t<view class=\"eval-top\">\r\n\t\t\t\t\t\t\t\t\t\t<text class=\"eval-name\">\r\n\t\t\t\t\t\t\t\t\t\t\t匿名评价\r\n\t\t\t\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t\t\t\t<text class=\"eval-date\">\r\n\t\t\t\t\t\t\t\t\t\t\t2025-04-24\r\n\t\t\t\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t\t\t\t<view class=\"eval-stars\">\r\n\t\t\t\t\t\t\t\t\t\t<text>\r\n\t\t\t\t\t\t\t\t\t\t\t⭐⭐⭐⭐☆\r\n\t\t\t\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t\t\t\t<view class=\"stat-divider\">\r\n\t\t\t\t\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t\t\t\t\t<text class=\"eval-service\">\r\n\t\t\t\t\t\t\t\t\t\t\t泰式松骨\r\n\t\t\t\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t\t\t</view>\r\n\t\t\t\t\t\t\t\t\t<text class=\"eval-comment\">\r\n\t\t\t\t\t\t\t\t\t\t服务到位\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\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<!-- 做一个悬浮球 -->\r\n\t\t\t\t\t\t<u-floating @dblclick=\"callPolice\" />\r\n\t\t\t\t\t</view>\r\n\t\t\t\t</scroll-view>\r\n</template>\r\n\r\n<script setup>\r\n\timport { ref, computed } from 'vue';\r\n\t// import { colors } from '@/common/theme';\r\n\r\n\t// 状态\r\n\tconst isOnline = ref(true);\r\n\tconst cityInfo = ref('')\r\n\t// 头像url类型\r\n\ttype AvatarUrl = {\r\n\t\turl : string\r\n\t}\r\n\r\n\t// 技师信息(空对象,字段可为null)\r\n\ttype CoachInfo = {\r\n\t\tcreated_at : string | null\r\n\t\tavatar_url : AvatarUrl | null\r\n\t}\r\n\ttype FuncItem = {\r\n\t\tlabel : string | undefined;\r\n\t\ticonUrl : string;\r\n\t// 补充其他可能的字段(如id、desc等)\r\n\t}\r\n\tconst coachInfo = ref<CoachInfo | null>(null);\r\n\r\n\t// 切换上线状态\r\n\tconst toggleOnline = () => {\r\n\t\tisOnline.value = !isOnline.value;\r\n\t\t// 这里可以调用 API 更新状态\r\n\t\tconsole.log('Status changed:', isOnline.value);\r\n\t};\r\n\r\n\t// 功能列表\r\n\tconst funcList = [\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\t// 跳转到技师详情\r\n\tconst jumpMasterInfo = () => {\r\n\t\tuni.navigateTo({\r\n\t\t\t\turl: '/pages/myEdit/myEdit'\r\n\t\t\t});\r\n\r\n\t};\r\n\r\n\t// 功能按钮点击处理\r\n\tconst jumpSetProject = (label : string) => {\r\n\t\tconsole.log(label, 'jumpSetProject invoked');\r\n\t\tswitch (label) {\r\n\t\t\tcase '接单时间':\r\n\t\t\tuni.navigateTo({\r\n\t\t\t\t\turl: '/pages/console/setOrderTime'\r\n\t\t\t\t});\r\n\t\t\tbreak;\r\n\t\t\tcase '服务项目':\r\n\t\t\tuni.navigateTo({\r\n\t\t\t\t\turl: '/pages/console/serviceProject'\r\n\t\t\t\t});\r\n\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\tbreak;\r\n\t\t}\r\n\r\n\r\n\r\n\t};\r\n\r\n\t// 悬浮球双击处理\r\n\tconst callPolice = () => {\r\n\t\tconsole.log('callPolice triggered');\r\n\t\t// 可在此触发紧急呼叫等操作\r\n\t};\r\n\r\n\t// 统计数据\r\n\tconst dataStats = [\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\t// 评价标签数据\r\n\t// 使用类型别名避免 UTS 对内联对象字面量的限制\r\n\ttype EvalTag = { text : string; count : number };\r\n\tconst evalTags : EvalTag[] = [\r\n\t\t{ text: '不良引导', count: 0 },\r\n\t{ text: '手法不好', count: 101 },\r\n\t{ text: '性格温柔', count: 198 },\r\n\t{ text: '服务到位', count: 10 }\r\n\t];\r\n</script>\r\n\r\n<style>\r\n\t.page {\r\n\t\t/* width: 100%;\r\n\t\tcommented out because percentage unsupported\r\n\t\t*/\r\n\t\tpadding: 20rpx;\r\n\t}\r\n\r\n\t.upContent {\r\n\t\theight: 900rpx;\r\n\t\twidth: 750rpx;\r\n\t\tposition: fixed;\r\n\t\ttop: 0;\r\n\t\tleft: 0;\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}\r\n\r\n\t.city-text-box {\r\n\t\tfont-size: 28rpx;\r\n\t}\r\n\r\n\t/* 用户卡片 */\r\n\t.user-card {\r\n\t\tborder-radius: 16rpx;\r\n\t\t/* padding: 20rpx; */\r\n\t\t/* margin-top: 16rpx; */\r\n\t\tmargin-bottom: 32rpx;\r\n\t\tbox-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);\r\n\t\t/* border: 1rpx solid #f5f5f5; */\r\n\t\tposition: relative;\r\n\t}\r\n\r\n\t.user-bg {\r\n\t\tposition: absolute;\r\n\t\twidth: 100%;\r\n\t\theight: 100%;\r\n\t}\r\n\r\n\t.user-info {\r\n\t\t/* display: flex; */\r\n\t\tflex-direction: row;\r\n\t\talign-items: center;\r\n\t\tmargin-bottom: 16rpx;\r\n\t\tjustify-content: space-between;\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: #333333;\r\n\t\t/* margin-bottom: 16rpx; */\r\n\t}\r\n\r\n\r\n\t.tag {\r\n\t\tfont-size: 24rpx;\r\n\t}\r\n\r\n\t.tag-new {\r\n\t\t/* 绿色透明度渐变 */\r\n\t\tbackground: linear-gradient(180deg, rgba(207, 221, 62, 0.69) 0%, rgba(162, 184, 29, 1) 100%);\r\n\t\tcolor: #FFFFFF;\r\n\t\tborder-radius: 24rpx;\r\n\t\tmargin: 0 16rpx;\r\n\t\tfont-size: 28rpx;\r\n\t\tpadding: 6rpx 12rpx;\r\n\t}\r\n\r\n\t.tag-edit {\r\n\t\tcolor: #999999;\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: #999999;\r\n\t\tmargin-right: 32rpx;\r\n\t}\r\n\r\n\t.online-switch {\r\n\t\tmargin-top: 24rpx;\r\n\t}\r\n\r\n\t.online-text {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #333333;\r\n\t\tmargin-right: 16rpx;\r\n\t}\r\n\r\n\t.user-right {\r\n\t\talign-items: center;\r\n\t\twidth: 180rpx;\r\n\t\theight: 245rpx;\r\n\t\tz-index: 1;\r\n\t\tmargin-right: 14rpx;\r\n\t}\r\n\r\n\t.text-time-box {\r\n\t\tmargin-top: 10rpx;\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #fff;\r\n\t\tletter-spacing: 1rpx;\r\n\t\ttext-align: center;\r\n\t}\r\n\r\n\t.join-time {\r\n\t\ttext-align: center;\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #FFFFFF;\r\n\t\tbackground-color: rgba(0, 0, 0, 0.6);\r\n\t\tpadding: 8rpx 16rpx;\r\n\t\tborder-radius: 8rpx;\r\n\t\tmargin-bottom: 16rpx;\r\n\t}\r\n\r\n\t.avatar {\r\n\t\twidth: 120rpx;\r\n\t\theight: 120rpx;\r\n\t\tborder-radius: 60rpx;\r\n\t\t/* half of width/height */\r\n\t\tborder: 4rpx solid #FFFFFF;\r\n\t}\r\n\r\n\t.location-bar {\r\n\t\tdisplay: flex;\r\n\t\talign-items: center;\r\n\t\tbackground-image: linear-gradient(to right, #FFF9E1 0%, #FFF1BF 100%);\r\n\t\tpadding: 10rpx 20rpx;\r\n\t\tborder-radius: 18rpx;\r\n\t\tmargin-top: 30rpx;\r\n\t\tfont-size: 24rpx;\r\n\t\tjustify-content: space-between;\r\n\t}\r\n\r\n\t.location-icon {\r\n\t\tfont-size: 28rpx;\r\n\t\tmargin-right: 16rpx;\r\n\t}\r\n\r\n\t.location-text {\r\n\t\t/* flex: 1; */\r\n\t\tfont-size: 26rpx;\r\n\t\t/* color: #333333; */\r\n\t}\r\n\r\n\t.location-btn {\r\n\t\tfont-size: 26rpx;\r\n\t\tborder: 2rpx solid #0a0a0a;\r\n\t\tpadding: 8rpx 8rpx;\r\n\t\tborder-radius: 16rpx;\r\n\r\n\t}\r\n\r\n\t/* 本月数据 */\r\n\t.stats-row {\r\n\t\tdisplay: flex;\r\n\t\tflex-direction: row;\r\n\t\t/* width: 100%; removed percentage, flex children will stretch */\r\n\t\ttext-align: center;\r\n\t\tbackground-color: #FFFFFF;\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.05);\r\n\t\t/* border: 1rpx solid #e9e9e9; */\r\n\t}\r\n\r\n\t.stat-item {\r\n\t\tflex: 1;\r\n\t\ttext-align: center;\r\n\t}\r\n\r\n\t.stat-label {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #999999;\r\n\t\t/* display: block not supported; default inline behavior is fine */\r\n\t\tmargin-bottom: 24rpx;\r\n\t\ttext-align: center;\r\n\t}\r\n\r\n\t.stat-value {\r\n\t\tfont-size: 40rpx;\r\n\t\tfont-weight: bold;\r\n\t\tcolor: #333333;\r\n\t\ttext-align: center;\r\n\t}\r\n\r\n\t.stat-divider {\r\n\t\twidth: 2rpx;\r\n\t\tbackground-color: #EEEEEE;\r\n\t\tmargin: 0 16rpx;\r\n\t}\r\n\r\n\t/* 功能网格 */\r\n\t.func-grid {\r\n\t\tdisplay: flex;\r\n\t\tjustify-content: space-around;\r\n\t\tbackground-color: #FFFFFF;\r\n\t\tmargin-bottom: 32rpx;\r\n\t\tborder-radius: 24rpx;\r\n\t\tpadding: 32rpx 0;\r\n\t\tflex-direction: row;\r\n\t\tbox-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.1);\r\n\t\tborder: 1rpx solid #f9f9f9;\r\n\t}\r\n\r\n\t.func-item {\r\n\t\tdisplay: flex;\r\n\t\tflex-direction: column;\r\n\t\talign-items: center;\r\n\t}\r\n\r\n\t.func-label {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #666666;\r\n\t\tmargin-top: 16rpx;\r\n\t}\r\n\r\n\t/* 数据统计 */\r\n\t.data-section {\r\n\t\tbackground-color: #FFFFFF;\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\tborder: 1rpx solid #f9f9f9;\r\n\t}\r\n\r\n\t.section-header {\r\n\t\t/* display: flex; */\r\n\t\tjustify-content: space-between;\r\n\t\talign-items: center;\r\n\t\tmargin-bottom: 32rpx;\r\n\t\tflex-direction: row;\r\n\t}\r\n\r\n\t.section-title {\r\n\t\tfont-size: 32rpx;\r\n\t\tfont-weight: 400;\r\n\t\tcolor: #333333;\r\n\t}\r\n\r\n\t.section-more {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #999999;\r\n\t}\r\n\r\n\t.data-grid {\r\n\t\t/* display: flex; */\r\n\t\tjustify-content: space-between;\r\n\t\tflex-direction: row;\r\n\t}\r\n\r\n\t.data-item {\r\n\t\ttext-align: center;\r\n\t}\r\n\r\n\t.data-value {\r\n\t\tfont-size: 36rpx;\r\n\t\tfont-weight: bold;\r\n\t\tcolor: #333333;\r\n\t\t/* display property not needed */\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: #999999;\r\n\t}\r\n\r\n\t/* 客户评价 */\r\n\t.eval-section {\r\n\t\tbackground-color: #FFFFFF;\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\tborder: 1rpx solid #f9f9f9;\r\n\t}\r\n\r\n\t.eval-tags {\r\n\t\tdisplay: flex;\r\n\t\t/* flex-wrap: wrap; */\r\n\t\tflex-direction: row;\r\n\t\t/* gap: 16rpx; */\r\n\t\tmargin-bottom: 32rpx;\r\n\t}\r\n\r\n\t.eval-tag {\r\n\t\tfont-size: 24rpx;\r\n\t\tpadding: 8rpx 24rpx;\r\n\t\tbackground-color: #F5F5F5;\r\n\t\tborder-radius: 24rpx;\r\n\t\t/* color: #666666; */\r\n\t}\r\n\r\n\t.eval-item {\r\n\t\t/* display: flex; */\r\n\t\t/* gap: 24rpx; */\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}\r\n\r\n\t.eval-content {\r\n\t\tflex: 1;\r\n\t}\r\n\r\n\t.eval-top {\r\n\t\t/* display: flex; */\r\n\t\tjustify-content: space-between;\r\n\t\tmargin-bottom: 8rpx;\r\n\t\tflex-direction: row;\r\n\t}\r\n\r\n\t.eval-name {\r\n\t\t/* font-size: 28rpx; */\r\n\t\tfont-weight: 400;\r\n\t\tcolor: #333333;\r\n\t}\r\n\r\n\t.eval-date {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #999999;\r\n\t}\r\n\r\n\t.eval-stars {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #FFD740;\r\n\t\tmargin-bottom: 8rpx;\r\n\t\tflex-direction: row;\r\n\t}\r\n\r\n\t.eval-service {\r\n\t\tcolor: #999999;\r\n\t\tmargin-left: 16rpx;\r\n\t\tfont-size: 28rpx;\r\n\r\n\t}\r\n\r\n\t.eval-comment {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #333333;\r\n\t}\r\n</style>","<template>\r\n <view class=\"page-container\">\r\n\r\n <!-- 1. 用户信息头部 -->\r\n <view class=\"user-header\">\r\n <image :src=\"userInfo['avatar']\" class=\"avatar\" mode=\"aspectFill\" />\r\n <view class=\"user-info\">\r\n <text class=\"username\">\r\n {{ userInfo['name'] }}\r\n </text>\r\n <view class=\"badge-row\">\r\n <text class=\"badge vip\">\r\n 王牌\r\n </text>\r\n </view>\r\n </view>\r\n <view class=\"header-actions\">\r\n <view class=\"action-item\" @click=\"contactService\">\r\n <u-icon type=\"customer-service\" size=\"24\" color=\"#666\">\r\n </u-icon>\r\n <text>\r\n 客服\r\n </text>\r\n </view>\r\n <view class=\"action-item\" @click=\"openSettings\">\r\n <u-icon type=\"gear\" size=\"24\" color=\"#666\">\r\n </u-icon>\r\n <text>\r\n 设置\r\n </text>\r\n </view>\r\n </view>\r\n </view>\r\n\r\n <!-- 2. 等级卡片 -->\r\n <view class=\"level-card\">\r\n <view class=\"level-main\">\r\n <text class=\"level-title\">\r\n V{{ userInfo['level'] }}\r\n </text>\r\n <text class=\"level-sub\">\r\n 成长值 {{ userInfo['growthValue'] }}\r\n </text>\r\n </view>\r\n <view class=\"level-progress\">\r\n <text class=\"progress-text\">\r\n 还差{{ userInfo['nextLevelGap'] }}成长值可升至V{{ userInfo['nextLevel'] }}\r\n </text>\r\n <view class=\"progress-bar\">\r\n <view class=\"progress-fill\" :style=\"{ width: progressWidth }\">\r\n </view>\r\n </view>\r\n <view class=\"progress-labels\">\r\n <text>\r\n V1\r\n </text>\r\n <text>\r\n V2\r\n </text>\r\n </view>\r\n </view>\r\n <view class=\"level-badge\" @click=\"viewLevelDetail\">\r\n <u-icon type=\"vip\" size=\"40\" color=\"#ffffff\">\r\n </u-icon>\r\n <text>\r\n 我的等级\r\n </text>\r\n </view>\r\n </view>\r\n\r\n <!-- 3. 我的档案 -->\r\n <view class=\"section-title\">\r\n 我的档案\r\n </view>\r\n <view class=\"profile-stats\">\r\n <view class=\"stat-item\">\r\n <text class=\"stat-value\">\r\n 60\r\n </text>\r\n <text class=\"stat-label\">\r\n 签约\r\n </text>\r\n </view>\r\n <view class=\"stat-item\">\r\n <text class=\"stat-value\">\r\n 21\r\n </text>\r\n <text class=\"stat-label\">\r\n 解约\r\n </text>\r\n </view>\r\n <view class=\"stat-item\">\r\n <u-icon type=\"location\" size=\"24\" color=\"#666\">\r\n </u-icon>\r\n <text class=\"stat-label\">\r\n 异地签到\r\n </text>\r\n </view>\r\n <view class=\"stat-item\">\r\n <u-icon type=\"cart\" size=\"24\" color=\"#666\">\r\n </u-icon>\r\n <text class=\"stat-label\">\r\n 购买物料\r\n </text>\r\n </view>\r\n </view>\r\n\r\n <!-- 4. 我的工具 -->\r\n <view class=\"section-title\">\r\n 我的工具\r\n </view>\r\n <view class=\"tools-grid\">\r\n <view class=\"tool-item\" v-for=\"(tool, idx) in tools\" :key=\"idx\" @click=\"handleToolClick(tool)\">\r\n <u-icon :type=\"tool.icon\" size=\"32\" :color=\"tool.color\">\r\n </u-icon>\r\n <text class=\"tool-name\">\r\n {{ tool.name }}\r\n </text>\r\n </view>\r\n </view>\r\n\r\n <!-- 5. 推广卡片 -->\r\n <view class=\"promo-cards\">\r\n <!-- 邀请好友 -->\r\n <view class=\"promo-card invite\" @click=\"inviteFriends\">\r\n <view class=\"promo-content\">\r\n <text class=\"promo-title\">\r\n 邀请好友赚钱\r\n </text>\r\n <text class=\"promo-subtitle\">\r\n 单次最高可奖200元\r\n </text>\r\n </view>\r\n <u-icon type=\"gift\" size=\"40\" color=\"#ffd700\">\r\n </u-icon>\r\n </view>\r\n\r\n <!-- 我的团队 -->\r\n <view class=\"promo-card team\" @click=\"viewTeam\">\r\n <view class=\"promo-content\">\r\n <text class=\"promo-title\">\r\n 我的团队\r\n </text>\r\n <text class=\"promo-subtitle\">\r\n 团队成员100人\r\n </text>\r\n </view>\r\n <u-icon type=\"person\" size=\"40\" color=\"#4a90e2\">\r\n </u-icon>\r\n </view>\r\n </view>\r\n\r\n <!-- 6. 城市合伙人 banner -->\r\n <view class=\"partner-banner\" @click=\"joinPartner\">\r\n <view class=\"partner-content\">\r\n <text class=\"partner-title\">\r\n 寻找城市合伙人\r\n </text>\r\n <text class=\"partner-subtitle\">\r\n 全新盈利模式助你创业\r\n </text>\r\n </view>\r\n <view class=\"partner-icon\">\r\n <u-icon type=\"person\" size=\"50\" color=\"#ffffff\">\r\n </u-icon>\r\n <u-icon type=\"person\" size=\"30\" color=\"#ffffff\" style=\"margin-left: -20rpx;\">\r\n </u-icon>\r\n </view>\r\n </view>\r\n\r\n </view>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\n import { ref, reactive } from 'vue';\r\n\r\n // --- 用户信息 ---\r\n\r\n\ttype UserInfo = {\r\n\t\tname : string;\r\n\t\tavatar : string;\r\n\t\tlevel : number;\r\n\t\tgrowthValue : number;\r\n\t\tnextLevel : number;\r\n\t\tnextLevelGap : number;\r\n\t\tprogressPercent : number;\r\n\t}\r\n const userInfo = reactive<UserInfo>({\r\n name: '刘大锤',\r\n avatar: 'https://via.placeholder.com/100x100/4a90e2/ffffff?text=LD', // 替换为实际头像\r\n level: 30,\r\n growthValue: 50,\r\n nextLevel: 2,\r\n nextLevelGap: 15,\r\n progressPercent: 75 // (50 / (50+15)) * 100 ≈ 75%\r\n });\r\n\r\n // computed helpers to satisfy UTS inference rules\r\n // convert percent to a fixed rpx width (assuming 750rpx full width)\r\n const progressWidth = computed(() => `${userInfo.progressPercent * 7.5}rpx`);\r\n\r\n // --- 工具列表 ---\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 // avoid generic parameter on ref which earlier triggered an \"interface does not\r\n // have constructors\" error; cast the initial value instead.\r\n const tools = ref([\r\n { name: '学习园地', icon: 'book', color: '#ff9900' },\r\n { name: '问题反馈', icon: 'chat', color: '#52c41a' },\r\n { name: '定制优惠', icon: 'wallet', color: '#1890ff' },\r\n { name: 'VIP俱乐部', icon: 'vip', color: '#faad14' }\r\n ] as ToolItem[]);\r\n\r\n // --- 方法 ---\r\n const contactService = () => {\r\n uni.showToast({ title: '联系客服', icon: 'none' });\r\n };\r\n\r\n const openSettings = () => {\r\n uni.showToast({ title: '打开设置', icon: 'none' });\r\n };\r\n\r\n const viewLevelDetail = () => {\r\n uni.showToast({ title: '查看等级详情', icon: 'none' });\r\n };\r\n\r\n const handleToolClick = (tool : ToolItem) => {\r\n uni.showToast({ title: `点击${tool.name}`, icon: 'none' });\r\n };\r\n\r\n const inviteFriends = () => {\r\n uni.showModal({\r\n title: '邀请好友',\r\n content: '分享链接邀请好友加入,单次最高可获奖励200元!',\r\n success: (res) => {\r\n if (res.confirm) {\r\n uni.showToast({ title: '已生成邀请链接', icon: 'success' });\r\n }\r\n }\r\n });\r\n };\r\n\r\n const viewTeam = () => {\r\n uni.showToast({ title: '查看团队成员', icon: 'none' });\r\n };\r\n\r\n const joinPartner = () => {\r\n uni.showModal({\r\n title: '城市合伙人',\r\n content: '全新盈利模式助你创业,立即申请成为城市合伙人!',\r\n success: (res) => {\r\n if (res.confirm) {\r\n uni.showToast({ title: '申请已提交', icon: 'success' });\r\n }\r\n }\r\n });\r\n };\r\n</script>\r\n\r\n<style scoped>\r\n /*\r\n UniApp X 默认 page 是 flex-direction: column\r\n 所以 .page-container 会自动垂直排列子元素\r\n */\r\n\r\n .page-container {\r\n background-color: #f5f6f8;\r\n /* min-height: 100vh unsupported */\r\n min-height: 1000rpx;\r\n /* width: 100%; default block behavior */\r\n box-sizing: border-box;\r\n padding: 20rpx;\r\n /* gap: 20rpx; */\r\n /* 各模块间间距 */\r\n }\r\n\r\n /* --- 用户头部 --- */\r\n .user-header {\r\n display: flex;\r\n flex-direction: row;\r\n align-items: center;\r\n /* gap: 20rpx; */\r\n padding: 20rpx;\r\n background: #ffffff;\r\n border-radius: 16rpx;\r\n box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);\r\n }\r\n\r\n .avatar {\r\n width: 100rpx;\r\n height: 100rpx;\r\n border-radius: 50rpx;\r\n border: 2rpx solid #eee;\r\n }\r\n\r\n .user-info {\r\n flex: 1;\r\n display: flex;\r\n flex-direction: column;\r\n /* */\r\n }\r\n\r\n .username {\r\n font-size: 32rpx;\r\n font-weight: bold;\r\n color: #333;\r\n }\r\n\r\n .badge-row {\r\n display: flex;\r\n flex-direction: row;\r\n /* gap: 10rpx; */\r\n }\r\n\r\n .badge {\r\n font-size: 22rpx;\r\n padding: 4rpx 12rpx;\r\n border-radius: 20rpx;\r\n font-weight: bold;\r\n }\r\n\r\n .badge.vip {\r\n background: linear-gradient(90deg, #4a90e2, #67b26f);\r\n color: #ffffff;\r\n }\r\n\r\n .header-actions {\r\n display: flex;\r\n flex-direction: row;\r\n /* gap: 30rpx; */\r\n }\r\n\r\n .action-item {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n /* gap: 4rpx; unsupported */\r\n font-size: 22rpx;\r\n color: #666;\r\n }\r\n\r\n /* --- 等级卡片 --- */\r\n .level-card {\r\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\r\n border-radius: 16rpx;\r\n padding: 30rpx;\r\n color: #ffffff;\r\n position: relative;\r\n overflow: hidden;\r\n }\r\n\r\n .level-main {\r\n display: flex;\r\n flex-direction: row;\r\n align-items: flex-start;\r\n /* baseline unsupported */\r\n /* gap: 15rpx; not supported by uvue */\r\n margin-bottom: 20rpx;\r\n }\r\n\r\n .level-title {\r\n font-size: 48rpx;\r\n font-weight: bold;\r\n }\r\n\r\n .level-sub {\r\n font-size: 28rpx;\r\n opacity: 0.9;\r\n }\r\n\r\n .level-progress {\r\n margin-bottom: 20rpx;\r\n }\r\n\r\n .progress-text {\r\n font-size: 24rpx;\r\n opacity: 0.8;\r\n margin-bottom: 10rpx;\r\n /* display:block removed; inline text is fine */\r\n }\r\n\r\n .progress-bar {\r\n /* width: 100%; */\r\n /* 全宽默认,无需指定百分比 */\r\n height: 12rpx;\r\n background: rgba(255, 255, 255, 0.3);\r\n border-radius: 6rpx;\r\n overflow: hidden;\r\n margin-bottom: 8rpx;\r\n }\r\n\r\n .progress-fill {\r\n /* 使用与父容器相同的固定高度 */\r\n height: 12rpx;\r\n background: #ffffff;\r\n border-radius: 6rpx;\r\n transition: width 0.3s ease;\r\n }\r\n\r\n .progress-labels {\r\n display: flex;\r\n flex-direction: row;\r\n justify-content: space-between;\r\n font-size: 22rpx;\r\n opacity: 0.7;\r\n }\r\n\r\n .level-badge {\r\n position: absolute;\r\n top: 20rpx;\r\n right: 20rpx;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n /* */\r\n font-size: 24rpx;\r\n opacity: 0.9;\r\n }\r\n\r\n /* --- 章节标题 --- */\r\n .section-title {\r\n font-size: 30rpx;\r\n font-weight: bold;\r\n color: #333;\r\n margin-top: 10rpx;\r\n margin-bottom: 15rpx;\r\n padding-left: 10rpx;\r\n border-left: 4rpx solid #4a90e2;\r\n }\r\n\r\n /* --- 档案统计 --- */\r\n .profile-stats {\r\n display: flex;\r\n flex-direction: row;\r\n justify-content: space-around;\r\n background: #ffffff;\r\n border-radius: 16rpx;\r\n padding: 30rpx 20rpx;\r\n box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);\r\n }\r\n\r\n .stat-item {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n\r\n }\r\n\r\n .stat-value {\r\n font-size: 32rpx;\r\n font-weight: bold;\r\n color: #333;\r\n }\r\n\r\n .stat-label {\r\n font-size: 24rpx;\r\n color: #666;\r\n }\r\n\r\n /* --- 工具网格 --- */\r\n .tools-grid {\r\n display: flex;\r\n flex-direction: row;\r\n flex-wrap: wrap;\r\n /* gap: 20rpx; */\r\n background: #ffffff;\r\n border-radius: 16rpx;\r\n padding: 30rpx;\r\n box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);\r\n }\r\n\r\n .tool-item {\r\n /* width: calc(25% - 15rpx); not supported */\r\n width: 168rpx;\r\n /* approximate quarter width */\r\n /* 4列,减去gap */\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n /* gap: 10rpx; */\r\n padding: 20rpx 0;\r\n }\r\n\r\n .tool-name {\r\n font-size: 24rpx;\r\n color: #666;\r\n text-align: center;\r\n }\r\n\r\n /* --- 推广卡片 --- */\r\n .promo-cards {\r\n display: flex;\r\n flex-direction: row;\r\n /* gap: 20rpx; */\r\n }\r\n\r\n .promo-card {\r\n flex: 1;\r\n border-radius: 16rpx;\r\n padding: 25rpx;\r\n display: flex;\r\n flex-direction: row;\r\n justify-content: space-between;\r\n align-items: center;\r\n box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);\r\n }\r\n\r\n .promo-card.invite {\r\n background: linear-gradient(135deg, #fff9e6 0%, #ffeaa7 100%);\r\n }\r\n\r\n .promo-card.team {\r\n background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);\r\n }\r\n\r\n .promo-content {\r\n display: flex;\r\n flex-direction: column;\r\n /* */\r\n }\r\n\r\n .promo-title {\r\n font-size: 28rpx;\r\n font-weight: bold;\r\n color: #333;\r\n }\r\n\r\n .promo-subtitle {\r\n font-size: 24rpx;\r\n color: #666;\r\n }\r\n\r\n /* --- 合伙人 Banner --- */\r\n .partner-banner {\r\n background: linear-gradient(135deg, #ff9a9e 0%, #fad0c4 100%);\r\n border-radius: 16rpx;\r\n padding: 30rpx;\r\n display: flex;\r\n flex-direction: row;\r\n justify-content: space-between;\r\n align-items: center;\r\n color: #ffffff;\r\n box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);\r\n }\r\n\r\n .partner-content {\r\n display: flex;\r\n flex-direction: column;\r\n /* gap: 10rpx; */\r\n }\r\n\r\n .partner-title {\r\n font-size: 32rpx;\r\n font-weight: bold;\r\n }\r\n\r\n .partner-subtitle {\r\n font-size: 26rpx;\r\n opacity: 0.9;\r\n }\r\n\r\n .partner-icon {\r\n display: flex;\r\n flex-direction: row;\r\n align-items: center;\r\n }\r\n</style>","<template>\r\n\t<view class=\"page-container\">\r\n\r\n\t\t<!-- 1. 资产卡片区域 -->\r\n\t\t<view class=\"asset-card\">\r\n\t\t\t<!-- 总资产 -->\r\n\t\t\t<view class=\"total-asset-section row-between\">\r\n\t\t\t\t<text class=\"label\">\r\n\t\t\t\t\t我的资产(元)\r\n\t\t\t\t</text>\r\n\t\t\t\t<view class=\"amount-row row-start\">\r\n\t\t\t\t\t<!-- 修复:确保 totalAsset 已定义 -->\r\n\t\t\t\t\t<text class=\"amount\">\r\n\t\t\t\t\t\t{{ totalAsset }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<u-icon type=\"eye\" size=\"20\" color=\"#333\">\r\n\t\t\t\t\t</u-icon>\r\n\t\t\t\t</view>\r\n\t\t\t\t<!-- 修复:确保 refreshData 已定义 -->\r\n\t\t\t\t<view class=\"refresh-btn row-center\" @click=\"refreshData\">\r\n\t\t\t\t\t<u-icon type=\"refresh\" size=\"18\" color=\"#333\">\r\n\t\t\t\t\t</u-icon>\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\r\n\t\t\t<!-- 累计收益 & 打车费 -->\r\n\t\t\t<view class=\"income-section 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 row-start\">\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 type=\"help\" size=\"16\" color=\"#999\">\r\n\t\t\t\t\t\t</u-icon>\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<!-- 修复:确保 cumulativeIncome 已定义 -->\r\n\t\t\t\t\t\t<text class=\"income-value\">\r\n\t\t\t\t\t\t\t{{ cumulativeIncome }}\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t<!-- 修复:确保 handleWithdraw 已定义 -->\r\n\t\t\t\t\t\t<view class=\"withdraw-btn\" @click=\"handleWithdraw('income')\">\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\t\t\t\t\t<view class=\"income-detail row-start\">\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<!-- 修复:确保 frozenIncome 已定义 -->\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 highlight\">\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\">\r\n\t\t\t\t\t<view class=\"income-header row-start\">\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 type=\"help\" size=\"16\" color=\"#999\">\r\n\t\t\t\t\t\t</u-icon>\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\t\t\t\t\t<view class=\"income-detail row-start\">\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 highlight\">\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\r\n\t\t\t<!-- 提现记录入口 -->\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<u-icon type=\"arrowright\" size=\"16\" color=\"#999\">\r\n\t\t\t\t</u-icon>\r\n\t\t\t</view>\r\n\t\t</view>\r\n\r\n\t\t<!-- 2. 本月账单标题 -->\r\n\t\t<view class=\"bill-header row-between\">\r\n\t\t\t<text class=\"bill-title\">\r\n\t\t\t\t本月账单\r\n\t\t\t</text>\r\n\t\t\t<text class=\"view-all\" @click=\"viewAllBills\">\r\n\t\t\t\t查看全部\r\n\t\t\t</text>\r\n\t\t</view>\r\n\r\n\t\t<!-- 3. 账单列表 -->\r\n\t\t<view class=\"bill-list column\">\r\n\t\t\t<view v-for=\"(bill, idx) in bills\" :key=\"idx\" class=\"bill-card column\">\r\n\r\n\t\t\t\t<!-- 订单号行 -->\r\n\t\t\t\t<view class=\"order-id-row row-between\">\r\n\t\t\t\t\t<text class=\"order-id\">\r\n\t\t\t\t\t\t订单号:{{ bill.orderId }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<u-icon type=\"arrowright\" size=\"16\" color=\"#999\">\r\n\t\t\t\t\t</u-icon>\r\n\t\t\t\t</view>\r\n\r\n\t\t\t\t<!-- 项目与金额 -->\r\n\t\t\t\t<view class=\"project-amount-row row-between\">\r\n\t\t\t\t\t<text class=\"project-name\">\r\n\t\t\t\t\t\t{{ bill.projectName }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text :class=\"['amount', bill.amount > 0 ? 'positive' : 'negative']\">\r\n\t\t\t\t\t\t{{ bill.amount > 0 ? '+' : '' }}{{ Math.abs(bill.amount).toFixed(2) }}\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<!-- 分成说明 -->\r\n\t\t\t\t\t<view class=\"split-info column\">\r\n\t\t\t\t\t\t<text class=\"split-type\">\r\n\t\t\t\t\t\t\t{{ bill.splitType }}\r\n\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t<text class=\"split-detail\">\r\n\t\t\t\t\t\t\t{{ bill.splitDetail }}\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<!-- 记录时间 -->\r\n\t\t\t\t\t<view class=\"time-row row-between\">\r\n\t\t\t\t\t\t<text class=\"time-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<text class=\"time-value\">\r\n\t\t\t\t\t\t\t{{ bill.recordTime }}\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</view>\r\n\t\t\t</view>\r\n\r\n\t\t</view>\r\n</template>\r\n\r\n<script setup lang=\"uts\">\r\n\timport { ref } from 'vue';\r\n\r\n\t// --- 数据定义 ---\r\n\tconst totalAsset = ref('1978.2');\r\n\tconst cumulativeIncome = ref('1889');\r\n\tconst frozenIncome = ref('1000');\r\n\tconst availableIncome = ref('889');\r\n\tconst taxiFee = ref('89.2');\r\n\tconst frozenTaxi = ref('50');\r\n\tconst availableTaxi = ref('49.2');\r\n\r\n\t// ✅ 修复点 1: 定义类型 (可以用 interface 或 type)\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\t// ✅ 修复点 2: 初始化时不写泛型 <BillItem[]>,让 TS 自动推断\r\n\t// 或者写成: const bills = ref<BillItem[]>([]); 然后单独 push,但直接推断最方便\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 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\ttotalAsset.value = (parseFloat(totalAsset.value) + 0.1).toFixed(1);\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.showToast({ title: '提现申请已提交', icon: 'success' });\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.showModal({\r\n\t\t\t\ttitle: '转出确认',\r\n\t\t\t\tcontent: '确定要将打车费转出到其他账户吗?',\r\n\t\t\t\tsuccess: (res) => {\r\n\t\t\t\t\tif (res.confirm) {\r\n\t\t\t\t\t\tuni.showToast({ title: '转出成功', icon: 'success' });\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 viewWithdrawRecords = () => {\r\n\t\tuni.showToast({ title: '查看提现记录', icon: 'none' });\r\n\t};\r\n\r\n\tconst viewAllBills = () => {\r\n\t\tuni.showToast({ title: '查看全部账单', icon: 'none' });\r\n\t};\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\t/* gap: 10rpx; */\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: #f5f6f8;\r\n\t\t/* min-height: 100vh; */\r\n\t\tpadding-bottom: 40rpx;\r\n\t}\r\n\r\n\t/* --- 资产卡片 --- */\r\n\t.asset-card {\r\n\t\tbackground: linear-gradient(180deg, #fff9e6 0%, #ffeaa7 100%);\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}\r\n\r\n\t.total-asset-section {\r\n\t\tmargin-bottom: 30rpx;\r\n\t}\r\n\r\n\t.label {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #666;\r\n\t}\r\n\r\n\t.amount-row {\r\n\t\t/* gap: 10rpx; */\r\n\t}\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\tbackground: #ffffff;\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}\r\n\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: 24rpx;\r\n\t\tcolor: #666;\r\n\t}\r\n\r\n\t.income-main {\r\n\t\t/* 继承 row-between */\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: 24rpx;\r\n\t\tpadding: 8rpx 20rpx;\r\n\t\tborder-radius: 20rpx;\r\n\t\tbackground: #ffffff;\r\n\t\tborder: 1rpx solid;\r\n\t}\r\n\r\n\t.withdraw-btn {\r\n\t\tcolor: #ff9900;\r\n\t\tborder-color: #ff9900;\r\n\t}\r\n\r\n\t.transfer-btn {\r\n\t\tcolor: #52c41a;\r\n\t\tborder-color: #52c41a;\r\n\t}\r\n\r\n\t/* 明细部分 */\r\n\t.income-detail {\r\n\t\tbackground: rgba(255, 255, 255, 0.6);\r\n\t\tborder-radius: 12rpx;\r\n\t\tpadding: 15rpx;\r\n\t\t/* gap: 20rpx; */\r\n\t}\r\n\r\n\t.detail-item {\r\n\t\tflex: 1;\r\n\t\t/* gap: 4rpx; */\r\n\t}\r\n\r\n\t.detail-label {\r\n\t\tfont-size: 22rpx;\r\n\t\tcolor: #999;\r\n\t}\r\n\r\n\t.detail-value {\r\n\t\tfont-size: 28rpx;\r\n\t\tfont-weight: bold;\r\n\t\tcolor: #333;\r\n\t}\r\n\r\n\t.detail-value.highlight {\r\n\t\tcolor: #ff9900;\r\n\t}\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 0;\r\n\t\tborder-top: 1rpx solid rgba(0, 0, 0, 0.05);\r\n\t\tfont-size: 28rpx;\r\n\t\tcolor: #333;\r\n\t}\r\n\r\n\t/* --- 账单标题 --- */\r\n\t.bill-header {\r\n\t\tpadding: 20rpx 30rpx;\r\n\t\tmargin-top: 20rpx;\r\n\t}\r\n\r\n\t.bill-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.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: 16rpx;\r\n\t\tpadding: 30rpx;\r\n\t\tbox-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);\r\n\t\t/* gap: 15rpx; */\r\n\t}\r\n\r\n\t.order-id-row {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #666;\r\n\t}\r\n\r\n\t.project-amount-row {\r\n\t\t/* 继承 row-between */\r\n\t}\r\n\r\n\t.project-name {\r\n\t\tfont-size: 30rpx;\r\n\t\tfont-weight: bold;\r\n\t\tcolor: #333;\r\n\t}\r\n\r\n\t.amount.positive {\r\n\t\tcolor: #ff4d4f;\r\n\t\tfont-size: 32rpx;\r\n\t\tfont-weight: bold;\r\n\t}\r\n\r\n\t.amount.negative {\r\n\t\tcolor: #333;\r\n\t\tfont-size: 32rpx;\r\n\t\tfont-weight: bold;\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-weight: 400;\r\n\t\tcolor: #666;\r\n\t}\r\n\r\n\t.time-row {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #999;\r\n\t}\r\n</style>","// 导入请求\r\nimport { request } from '../request.uts'\r\n\r\nexport function getAllData(params : any) : Promise<any> {\r\n\treturn request({\r\n\t\turl: \"/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: \"/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: \"/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: \"/api/coach/v3/projects/open\",\r\n\t\tmethod: \"POST\",\r\n\t\tdata: data\r\n\t})\r\n}","<!-- pages/setOrderTime/setOrderTime.uvue -->\r\n<template>\r\n\t<view class=\"container\">\r\n\r\n\t\t<!-- 头部:全部可接单 -->\r\n\t\t<view class=\"header-box\" @click=\"allTime\">\r\n\t\t\t<text class=\"header-text\">\r\n\t\t\t\t{{ allIndex == 2 ? '取消全选' : '全部可接单' }}\r\n\t\t\t</text>\r\n\t\t</view>\r\n\r\n\t\t<!-- 滚动列表区域 -->\r\n\t\t<!-- uni-app x 中 scroll-view 需要明确高度或使用 flex 填充 -->\r\n\t\t<scroll-view class=\"time-list\" scroll-y=\"true\">\r\n\t\t\t<view class=\"time-grid\">\r\n\t\t\t\t<view v-for=\"item in timeArr\" :key=\"item.start_time\"\r\n\t\t\t\t\t:class=\"item.isSelect ? 'time-card selected' : 'time-card normal'\" @click.stop=\"chooseTime(item)\">\r\n\t\t\t\t\t<text :class=\"item.isSelect ? 'time-text selected' : 'time-text normal'\">\r\n\t\t\t\t\t\t{{ item.start_time }}\r\n\t\t\t\t\t</text>\r\n\t\t\t\t\t<text :class=\"item.isSelect ? 'time-sub selected' : 'time-sub normal'\">\r\n\t\t\t\t\t\t{{ item.isSelect ? '可接单' : '休息' }}\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</scroll-view>\r\n\t\t<!-- 底部保存按钮 -->\r\n\t\t<view class=\"footer-box\" @click=\"handleSave\">\r\n\t\t\t<text class=\"footer-text\">\r\n\t\t\t\t保存设置\r\n\t\t\t</text>\r\n\t\t</view>\r\n\t</view>\r\n</template>\r\n\r\n<script lang=\"uts\" setup>\r\n\timport { ref } from 'vue';\r\n\timport { editWorkTimeSetting } from '@/utils/api/workbenches.uts'\r\n\r\n\t// 状态定义\r\n\tconst allIndex = ref<1 | 2>(1); // 1: 普通模式, 2: 全选模式\r\n\r\n\t// 1. 定义时间项类型(必须最先定义)\r\n\ttype TimeItem = {\r\n\t\tstart_time : string;\r\n\t\tend_time : string;\r\n\t\tisSelect : boolean;\r\n\t}\r\n\r\n\t// 2. 定义响应式数组\r\n\tconst timeArr = ref<TimeItem[]>([]);\r\n\r\n\t// 3. 先定义初始化函数\r\n\tfunction initTimeArr() {\r\n\t\tconst arr : TimeItem[] = [];\r\n\t\tfor (let i = 0; i < 48; i++) {\r\n\t\t\tconst startHour = Math.floor(i / 2);\r\n\t\t\tconst startMin = i % 2 === 0 ? '00' : '30';\r\n\r\n\t\t\tlet endHour = Math.floor((i + 1) / 2);\r\n\t\t\tlet endMin = (i + 1) % 2 === 0 ? '00' : '30';\r\n\r\n\t\t\t// 处理23:30 -> 24:00\r\n\t\t\tif (endHour >= 24) {\r\n\t\t\t\tendHour = 24;\r\n\t\t\t\tendMin = '00';\r\n\t\t\t}\r\n\r\n\t\t\tarr.push({\r\n\t\t\t\tstart_time: `${startHour < 10 ? '0' : ''}${startHour}:${startMin}`,\r\n\t\t\t\tend_time: `${endHour < 10 ? '0' : ''}${endHour}:${endMin}`,\r\n\t\t\t\tisSelect: false\r\n\t\t\t});\r\n\t\t}\r\n\t\ttimeArr.value = arr;\r\n\t}\r\n\r\n\t// 4. 定义点击函数\r\n\tfunction chooseTime(item : TimeItem) {\r\n\t\titem.isSelect = !item.isSelect;\r\n\t\tconsole.log('选中时间:', item.start_time, item.isSelect);\r\n\t}\r\n\r\n\t// 5. 最后调用函数(UTS 核心:先定义,后调用)\r\n\tinitTimeArr();\r\n\r\n\t// onShow(() => {\r\n\t// \tallIndex.value = 1;\r\n\t// \t// getCoachTime();\r\n\t// \t// adjustSafeArea();\r\n\t// });\r\n\r\n\r\n\t// // 获取技师时间设置\r\n\t// const getCoachTime = async () => {\r\n\t// \t// 重置状态\r\n\t// \ttimeArr.value.forEach(item => item.isSelect = false);\r\n\t// \tallIndex.value = 1;\r\n\r\n\t// \ttry {\r\n\t// \t\tconst res = await workbenchesInfoApi.getWorkTimeSetting();\r\n\t// \t\tconst timeRanges = res.data?.time_ranges || [];\r\n\r\n\t// \t\t// 判断是否全部可接单\r\n\t// \t\tif (timeRanges.length === 1 && timeRanges[0].start_time === '00:00' && timeRanges[0].end_time === '24:00') {\r\n\t// \t\t\tallTime();\r\n\t// \t\t\treturn;\r\n\t// \t\t}\r\n\r\n\t// \t\t// 匹配时间段\r\n\t// \t\ttimeArr.value.forEach(item => {\r\n\t// \t\t\tconst itemTime = item.start_time;\r\n\t// \t\t\tfor (const range of timeRanges) {\r\n\t// \t\t\t\t// 比较逻辑:start <= item < end\r\n\t// \t\t\t\tif (compareTime(itemTime, range.start_time) >= 0 &&\r\n\t// \t\t\t\t\tcompareTime(itemTime, range.end_time) < 0\r\n\t// \t\t\t\t) {\r\n\t// \t\t\t\t\titem.isSelect = true;\r\n\t// \t\t\t\t\tbreak;\r\n\t// \t\t\t\t}\r\n\t// \t\t\t}\r\n\t// \t\t});\r\n\t// \t} catch (error) {\r\n\t// \t\tconsole.error('获取时间设置失败', error);\r\n\t// \t\tuni.showToast({ title: '加载失败', icon: 'none' });\r\n\t// \t}\r\n\t// };\r\n\r\n\t// 时间比较工具函数\r\n\t// function compareTime(t1, t2) {\r\n\t// \tif (!t1 || !t2) return 0;\r\n\t// \tconst [h1, m1] = t1.split(':').map(Number);\r\n\t// \tconst [h2, m2] = t2.split(':').map(Number);\r\n\r\n\t// \tif (h1 !== h2) return h1 > h2 ? 1 : -1;\r\n\t// \tif (m1 !== m2) return m1 > m2 ? 1 : -1;\r\n\t// \treturn 0;\r\n\t// }\r\n\r\n\t// 点击单个时间\r\n\r\n\r\n\r\n\t// 全部可接单/取消全选\r\n\tconst allTime = () => {\r\n\t\tif (allIndex.value === 2) {\r\n\t\t\t// 当前是全选状态,点击则取消全选\r\n\t\t\tfor (let i = 0; i < timeArr.value.length; i++) {\r\n\t\t\t\ttimeArr.value[i].isSelect = false;\r\n\t\t\t}\r\n\t\t\tallIndex.value = 1;\r\n\t\t} else {\r\n\t\t\t// 当前是普通状态,点击则全选\r\n\t\t\tfor (let i = 0; i < timeArr.value.length; i++) {\r\n\t\t\t\ttimeArr.value[i].isSelect = true;\r\n\t\t\t}\r\n\t\t\tallIndex.value = 2;\r\n\t\t}\r\n\t};\r\n\tconst handleSave = async () => {\r\n\t\t// console.log(timeArr.value, 'timeArr')\r\n\t\t// 1. 声明选中时间数组(类型固定)\r\n\t\tconst kjTime : TimeItem[] = []\r\n\t\t// 2. 遍历获取选中的时间段\r\n\t\tfor (let i = 0; i < timeArr.value.length; i++) {\r\n\t\t\tconst item : TimeItem = timeArr.value[i]\r\n\t\t\tif (item.isSelect) {\r\n\t\t\t\tkjTime.push(item)\r\n\t\t\t}\r\n\t\t}\r\n\t\t// 3. 校验:未选择时间段\r\n\t\tif (kjTime.length === 0) {\r\n\t\t\tuni.showToast({\r\n\t\t\t\ttitle: '请至少选择一个可接单时间段',\r\n\t\t\t\ticon: 'none',\r\n\t\t\t\tduration: 2000\r\n\t\t\t})\r\n\t\t\treturn\r\n\t\t}\r\n\t\ttry {\r\n\r\n\t\t\tconst scheduleData = {\r\n\t\t\t\t// time_ranges: kjTime.filter((range : TimeItem) => range.isSelect).map((range : TimeItem) => ({\r\n\t\t\t\t// \t\t\tstart_time: range.start_time,\r\n\t\t\t\t// \t\t\tend_time: range.end_time\r\n\t\t\t\t// \t\t}))\r\n\t\t\t\ttime_ranges: [{ start_time: \"04:00\", end_time: \"04:30\" }, { start_time: \"04:30\", end_time: \"05:00\" }]\r\n\r\n\t\t\t}\r\n\t\t\tconsole.log(scheduleData, 'scheduleData');\r\n\r\n\t\t\t// 调用接口保存\r\n\t\t\tconst res = await editWorkTimeSetting(scheduleData)\r\n\t\t\tconsole.log(res);\r\n\t\t\t// if ((res.code as number) === 200) {\r\n\t\t\t// \tuni.showToast({\r\n\t\t\t// \t\ttitle: '保存成功',\r\n\t\t\t// \t\ticon: 'success',\r\n\t\t\t// \t\tduration: 2000\r\n\t\t\t// \t})\r\n\t\t\t// \tuni.reLaunch({\r\n\t\t\t// \t\turl: '/pages/index/console'\r\n\t\t\t// \t})\r\n\t\t\t// }\r\n\t\t} catch (error) {\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\tconsole.error('保存报错:', error)\r\n\t\t}\r\n\t}\r\n</script>\r\n\r\n<style lang=\"scss\">\r\n\t/* 根容器:使用 Flex 布局填满屏幕 */\r\n\t.container {\r\n\t\tdisplay: flex;\r\n\t\tflex-direction: column;\r\n\t\twidth: 100%;\r\n\t\theight: 100%;\r\n\t\t/* 或 100% */\r\n\t\tbackground-color: #FFFFFF;\r\n\t\tbox-sizing: border-box;\r\n\t\tpadding-bottom: env(safe-area-inset-bottom);\r\n\t\t/* 适配全面屏底部 */\r\n\t}\r\n\r\n\t/* 顶部占位 */\r\n\t.top-safe-area {\r\n\t\twidth: 100%;\r\n\t\theight: 20rpx;\r\n\t\t/* 根据需要调整 */\r\n\t\tflex-shrink: 0;\r\n\t}\r\n\r\n\t/* 头部盒子 */\r\n\t.header-box {\r\n\t\twidth: 184rpx;\r\n\t\theight: 66rpx;\r\n\t\tborder-radius: 16rpx;\r\n\t\tbackground-color: #FFDA59;\r\n\t\tdisplay: flex;\r\n\t\talign-items: center;\r\n\t\tjustify-content: center;\r\n\t\tmargin: 20rpx 0 20rpx 32rpx;\r\n\t\tflex-shrink: 0;\r\n\r\n\t\t.header-text {\r\n\t\t\tcolor: #3D444E;\r\n\t\t\tfont-size: 28rpx;\r\n\t\t\tfont-weight: 700;\r\n\t\t\tletter-spacing: 3rpx;\r\n\t\t}\r\n\t}\r\n\r\n\t/* 滚动列表区域:flex: 1 占据剩余空间 */\r\n\t.time-list {\r\n\t\tflex: 1;\r\n\t\twidth: 100%;\r\n\t\tpadding-bottom: 20rpx;\r\n\t}\r\n\r\n\t/* 网格布局容器 */\r\n\t.time-grid {\r\n\t\twidth: 100%;\r\n\t\tpadding: 0 20rpx 20rpx;\r\n\t\t/* 底部 padding 防止被按钮遮挡 */\r\n\t\tbox-sizing: border-box;\r\n\t\tflex-wrap: wrap;\r\n\t\tjustify-content: space-between;\r\n\t\tflex-direction: row;\r\n\t}\r\n\r\n\t/* 时间卡片通用样式 */\r\n\t.time-card {\r\n\t\twidth: 158rpx;\r\n\t\theight: 90rpx;\r\n\t\tborder-radius: 16rpx;\r\n\t\tmargin-bottom: 22rpx;\r\n\t\talign-items: center;\r\n\t\tjustify-content: center;\r\n\t\tbox-sizing: border-box;\r\n\t\tborder-width: 2rpx;\r\n\t\tborder-style: solid;\r\n\r\n\t\t/* 选中状态 */\r\n\t\t&.selected {\r\n\t\t\tbackground-color: #FFFBEF;\r\n\t\t\tborder-color: #FFDB5F;\r\n\r\n\t\t\t.time-text,\r\n\t\t\t.time-sub {\r\n\t\t\t\tcolor: #3A3330;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/* 未选中状态 */\r\n\t\t&.normal {\r\n\t\t\tbackground-color: #F3F3F3;\r\n\t\t\tborder-color: transparent;\r\n\r\n\t\t\t.time-text,\r\n\t\t\t.time-sub {\r\n\t\t\t\tcolor: #9B9B9B;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/* 时间文字 */\r\n\t.time-text {\r\n\t\tfont-size: 28rpx;\r\n\t\tfont-weight: 400;\r\n\t\tmargin-bottom: 4rpx;\r\n\t\ttext-align: center;\r\n\t}\r\n\r\n\t/* 状态文字 */\r\n\t.time-sub {\r\n\t\tfont-size: 26rpx;\r\n\t\tfont-weight: 400;\r\n\t\tletter-spacing: 2rpx;\r\n\t\ttext-align: center;\r\n\t}\r\n\r\n\t/* 底部保存按钮 */\r\n\t.footer-box {\r\n\r\n\t\t/* bottom: 40rpx; */\r\n\t\t/* 距离底部距离 */\r\n\r\n\t\ttransform: translateX(-50%);\r\n\t\tleft: 50%;\r\n\t\twidth: 78%;\r\n\t\theight: 100rpx;\r\n\t\tbackground-color: #FFDA59;\r\n\t\tborder-radius: 24rpx;\r\n\t\tdisplay: flex;\r\n\t\talign-items: center;\r\n\t\tjustify-content: center;\r\n\t\tbox-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);\r\n\r\n\t\t.footer-text {\r\n\t\t\tcolor: #3A3330;\r\n\t\t\tfont-size: 34rpx;\r\n\t\t\tfont-weight: 700;\r\n\t\t\tletter-spacing: 3rpx;\r\n\t\t}\r\n\t}\r\n</style>","<template>\r\n\t<view class=\"page-container\">\r\n\t\t<scroll-view style=\"flex:1\">\r\n\r\n\t\t\t<!-- 服务列表容器 -->\r\n\t\t\t<view class=\"service-list\" v-for=\"service in servicesList\" :key=\"service.id\">\r\n\t\t\t\t<!-- 中式推拿项(带路费设置) -->\r\n\t\t\t\t<view class=\"service-item\">\r\n\t\t\t\t\t<!-- 左侧图片+信息区(核心:显式设置flex-direction: row) -->\r\n\t\t\t\t\t<view class=\"item-left\" style=\"flex-direction: row;\">\r\n\t\t\t\t\t\t<image class=\"service-img\" :src=\"service.img\" mode=\"aspectFill\">\r\n\t\t\t\t\t\t</image>\r\n\t\t\t\t\t\t<view class=\"service-info\">\r\n\t\t\t\t\t\t\t<text class=\"service-title\">\r\n\t\t\t\t\t\t\t\t{{ service.title }}\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t<text class=\"service-desc\">\r\n\t\t\t\t\t\t\t\t{{ service.desc }}\r\n\t\t\t\t\t\t\t</text>\r\n\t\t\t\t\t\t\t<text class=\"service-price\">\r\n\t\t\t\t\t\t\t\t¥{{ service.price }}\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<!-- 右侧开关 -->\r\n\t\t\t\t\t<switch class=\"service-switch\" :checked=\"service.hasFare\" color=\"#FFCC00\">\r\n\t\t\t\t\t</switch>\r\n\r\n\t\t\t\t\t<!-- 路费设置(仅中式推拿展示) -->\r\n\t\t\t\t\t<view class=\"fare-setting\" style=\"flex-direction: row;\">\r\n\t\t\t\t\t\t<text class=\"fare-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=\"fare-options\" style=\"flex-direction: row;\">\r\n\t\t\t\t\t\t\t<button class=\"fare-btn\">\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=\"fare-btn\">\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=\"fare-btn active\">\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\r\n\t\t\t</view>\r\n\t\t</scroll-view>\r\n\t\t<!-- 底部保存按钮 -->\r\n\t\t<view class=\"footer-box\" @click=\"handleSave\">\r\n\t\t\t<text class=\"footer-text\">\r\n\t\t\t\t保存设置\r\n\t\t\t</text>\r\n\t\t</view>\r\n\t</view>\r\n</template>\r\n\r\n<script setup lang=\"uts\">\r\n\timport { ref } from 'vue';\r\n\timport { editWorkTimeSetting } from '@/utils/api/workbenches.uts'\r\n\r\n\ttype ServiceItem = {\r\n\t\tid : number\r\n\t\ttitle : string\r\n\t\tdesc : string\r\n\t\tprice : number\r\n\t\timg : string\r\n\t\thasFare : boolean\r\n\t}\r\n\r\n\tconst fareType = ref<string>('roundtrip');\r\n\tconst servicesList = ref<ServiceItem[]>([\r\n\t\t{\r\n\t\t\tid: 1,\r\n\t\t\ttitle: '中式推拿',\r\n\t\t\tdesc: '服务时长:60分钟',\r\n\t\t\tprice: 199,\r\n\t\t\timg: '/static/imagesInfo/anmo.png',\r\n\t\t\thasFare: true\r\n\t\t},\r\n\t\t{\r\n\t\t\tid: 2,\r\n\t\t\ttitle: '足疗按摩',\r\n\t\t\tdesc: '服务时长:45分钟',\r\n\t\t\tprice: 149,\r\n\t\t\timg: '/static/imagesInfo/anmo.png',\r\n\t\t\thasFare: false\r\n\t\t},\r\n\t\t{\r\n\t\t\tid: 3,\r\n\t\t\ttitle: '肩颈按摩',\r\n\t\t\tdesc: '服务时长:30分钟',\r\n\t\t\tprice: 99,\r\n\t\t\timg: '/static/imagesInfo/anmo.png',\r\n\t\t\thasFare: false\r\n\t\t}\r\n\t])\r\n\tconst handleSave = async () => {\r\n\t\t// console.log(timeArr.value, 'timeArr')\r\n\t\t// // 1. 声明选中时间数组(类型固定)\r\n\t\t// const kjTime : TimeItem[] = []\r\n\t\t// // 2. 遍历获取选中的时间段\r\n\t\t// for (let i = 0; i < timeArr.value.length; i++) {\r\n\t\t// \tconst item : TimeItem = timeArr.value[i]\r\n\t\t// \tif (item.isSelect) {\r\n\t\t// \t\tkjTime.push(item)\r\n\t\t// \t}\r\n\t\t// }\r\n\t\t// // 3. 校验:未选择时间段\r\n\t\t// if (kjTime.length === 0) {\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\tduration: 2000\r\n\t\t// \t\t})\r\n\t\t// \treturn\r\n\t\t// }\r\n\t\ttry {\r\n\r\n\t\t\t// const scheduleData = {\r\n\t\t\t// \ttime_ranges: kjTime.filter((range : TimeItem) => range.isSelect).map((range : TimeItem) => ({\r\n\t\t\t// \t\tstart_time: range.start_time,\r\n\t\t\t// \t\tend_time: range.end_time\r\n\t\t\t// \t}))\r\n\t\t\t// }\r\n\t\t\t// 调用接口保存\r\n\t\t\tconst res = await editWorkTimeSetting({})\r\n\t\t\tconsole.log(res);\r\n\t\t\t// if ((res.code as number) === 200) {\r\n\t\t\t// \tuni.showToast({\r\n\t\t\t// \t\ttitle: '保存成功',\r\n\t\t\t// \t\ticon: 'success',\r\n\t\t\t// \t\tduration: 2000\r\n\t\t\t// \t})\r\n\t\t\t// \tuni.reLaunch({\r\n\t\t\t// \t\turl: '/pages/index/console'\r\n\t\t\t// \t})\r\n\t\t\t// }\r\n\t\t} catch (error) {\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\tconsole.error('保存报错:', error)\r\n\t\t}\r\n\t}\r\n</script>\r\n\r\n<style>\r\n\t/* 页面根容器:利用默认flex + column,全屏适配 + 基础背景 */\r\n\t.page-container {\r\n\t\tmin-height: 100%;\r\n\t\theight: 100%;\r\n\t\tbackground-color: #f5f5f5;\r\n\t\tpadding-bottom: 40rpx;\r\n\t\t/* 给保存按钮留间距 */\r\n\t}\r\n\r\n\t/* 顶部导航栏:显式设置flex-direction: row,保证横向排版 */\r\n\t.nav-bar {\r\n\t\tdisplay: flex;\r\n\t\tflex-direction: row;\r\n\t\talign-items: center;\r\n\t\tjustify-content: space-between;\r\n\t\tpadding: 20rpx 20rpx;\r\n\t\tbackground-color: #fff;\r\n\t\tborder-bottom: 1px solid #eee;\r\n\t}\r\n\r\n\t/* 关闭图标 */\r\n\t.close-icon {\r\n\t\twidth: 40rpx;\r\n\t\theight: 40rpx;\r\n\t}\r\n\r\n\t/* 导航标题 */\r\n\t.nav-title {\r\n\t\tfont-size: 36rpx;\r\n\t\tfont-weight: 700;\r\n\t\t/* 替换600,兼容uni app x */\r\n\t\tcolor: #333;\r\n\t}\r\n\r\n\t/* 占位空盒 */\r\n\t.empty-box {\r\n\t\twidth: 40rpx;\r\n\t\theight: 40rpx;\r\n\t}\r\n\r\n\t/* 服务列表容器:纵向排列,替代gap用margin */\r\n\t.service-list {\r\n\t\tdisplay: flex;\r\n\t\tflex-direction: column;\r\n\t\tpadding: 20rpx;\r\n\t}\r\n\r\n\t/* 服务项间距:替代gap:15rpx */\r\n\t.service-item {\r\n\t\tmargin-bottom: 15rpx;\r\n\t\tbackground-color: #fff;\r\n\t\tborder-radius: 12rpx;\r\n\t\tpadding: 20rpx;\r\n\t\tdisplay: flex;\r\n\t\tflex-direction: row;\r\n\t\t/* 核心:显式设置横向排版 */\r\n\t\talign-items: center;\r\n\t\tjustify-content: space-between;\r\n\t\tflex-wrap: wrap;\r\n\t\t/* 小屏幕路费设置换行 */\r\n\t}\r\n\r\n\t/* 最后一个服务项去掉底部间距 */\r\n\t.service-list .service-item:last-child {\r\n\t\tmargin-bottom: 0;\r\n\t}\r\n\r\n\t/* 左侧图片+信息区:横向排版 */\r\n\t.item-left {\r\n\t\tdisplay: flex;\r\n\t\talign-items: center;\r\n\t\tflex: 1;\r\n\t}\r\n\r\n\t/* 服务图片 */\r\n\t.service-img {\r\n\t\twidth: 120rpx;\r\n\t\theight: 120rpx;\r\n\t\tborder-radius: 8rpx;\r\n\t\tmargin-right: 20rpx;\r\n\t\t/* 替代gap:20rpx */\r\n\t}\r\n\r\n\t/* 服务信息区:纵向排列 */\r\n\t.service-info {\r\n\t\tdisplay: flex;\r\n\t\tflex-direction: column;\r\n\t}\r\n\r\n\t/* 服务描述/价格:顶部间距,替代gap:8rpx */\r\n\t.service-desc {\r\n\t\tmargin-top: 8rpx;\r\n\t}\r\n\r\n\t.service-price {\r\n\t\tmargin-top: 8rpx;\r\n\t}\r\n\r\n\t/* 服务标题:替换font-weight:600为700 */\r\n\t.service-title {\r\n\t\tfont-size: 32rpx;\r\n\t\tfont-weight: 700;\r\n\t\tcolor: #333;\r\n\t}\r\n\r\n\t/* 服务描述:替换font-weight:500为400 */\r\n\t.service-desc {\r\n\t\tfont-size: 24rpx;\r\n\t\tcolor: #666;\r\n\t\tfont-weight: 400;\r\n\t}\r\n\r\n\t/* 服务价格:替换font-weight:500为400 */\r\n\t.service-price {\r\n\t\tfont-size: 28rpx;\r\n\t\tcolor: #ff6700;\r\n\t\tfont-weight: 400;\r\n\t}\r\n\r\n\t/* 开关样式 */\r\n\t.service-switch {\r\n\t\ttransform: scale(0.9);\r\n\t}\r\n\r\n\t/* 路费设置区域:横向排版 */\r\n\t.fare-setting {\r\n\t\tdisplay: flex;\r\n\t\talign-items: center;\r\n\t\twidth: 100%;\r\n\t\tmargin-top: 15rpx;\r\n\t\tpadding-top: 15rpx;\r\n\t\tborder-top: 1px solid #eee;\r\n\t}\r\n\r\n\t/* 路费标签 */\r\n\t.fare-label {\r\n\t\tfont-size: 26rpx;\r\n\t\tcolor: #666;\r\n\t\twhite-space: nowrap;\r\n\t\tmargin-right: 20rpx;\r\n\t\t/* 替代gap:20rpx */\r\n\t}\r\n\r\n\t/* 路费选项容器:横向排版 */\r\n\t.fare-options {\r\n\t\tdisplay: flex;\r\n\t\tflex: 1;\r\n\t}\r\n\r\n\t/* 路费按钮:替代gap:10rpx用margin-left */\r\n\t.fare-btn {\r\n\t\tflex: 1;\r\n\t\theight: 60rpx;\r\n\t\tline-height: 60rpx;\r\n\t\ttext-align: center;\r\n\t\tfont-size: 24rpx;\r\n\t\tborder-radius: 8rpx;\r\n\t\tborder: 1px solid #ddd;\r\n\t\tbackground-color: #fff;\r\n\t}\r\n\r\n\t/* 路费按钮:非首个按钮左侧间距 */\r\n\t.fare-btn:not(:first-child) {\r\n\t\tmargin-left: 10rpx;\r\n\t}\r\n\r\n\t/* 选中状态样式 */\r\n\t.fare-btn.active {\r\n\t\tbackground-color: #FFCC00;\r\n\t\tcolor: #fff;\r\n\t\tborder-color: #FFCC00;\r\n\t}\r\n\r\n\t/* 底部保存按钮 */\r\n\t.footer-box {\r\n\r\n\t\t/* bottom: 40rpx; */\r\n\t\t/* 距离底部距离 */\r\n\r\n\t\ttransform: translateX(-50%);\r\n\t\tleft: 50%;\r\n\t\twidth: 78%;\r\n\t\theight: 100rpx;\r\n\t\tbackground-color: #FFDA59;\r\n\t\tborder-radius: 24rpx;\r\n\t\tdisplay: flex;\r\n\t\talign-items: center;\r\n\t\tjustify-content: center;\r\n\t\tbox-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);\r\n\r\n\t\t.footer-text {\r\n\t\t\tcolor: #3A3330;\r\n\t\t\tfont-size: 34rpx;\r\n\t\t\tfont-weight: 700;\r\n\t\t\tletter-spacing: 3rpx;\r\n\t\t}\r\n\t}\r\n</style>"],"names":[],"mappings":"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"}