if (typeof Promise !== "undefined" && !Promise.prototype.finally) { Promise.prototype.finally = function(callback) { const promise = this.constructor; return this.then( (value) => promise.resolve(callback()).then(() => value), (reason) => promise.resolve(callback()).then(() => { throw reason; }) ); }; } ; if (typeof uni !== "undefined" && uni && uni.requireGlobal) { const global = uni.requireGlobal(); ArrayBuffer = global.ArrayBuffer; Int8Array = global.Int8Array; Uint8Array = global.Uint8Array; Uint8ClampedArray = global.Uint8ClampedArray; Int16Array = global.Int16Array; Uint16Array = global.Uint16Array; Int32Array = global.Int32Array; Uint32Array = global.Uint32Array; Float32Array = global.Float32Array; Float64Array = global.Float64Array; BigInt64Array = global.BigInt64Array; BigUint64Array = global.BigUint64Array; } ; if (uni.restoreGlobal) { uni.restoreGlobal(Vue, weex, plus, setTimeout, clearTimeout, setInterval, clearInterval); } (function(vue) { "use strict"; function formatAppLog(type, filename, ...args) { if (uni.__log__) { uni.__log__(type, filename, ...args); } else { console[type].apply(console, [...args, filename]); } } const BASE_URL = "http://192.168.1.118:8080"; const CLIENT_ID = "fe63fea7be31b0200b496d08bc6b517d"; const PLATFORM_CODE = "FlfAppPlatformCodeX9kR7mT3wQ5vZ8nB1jY6pD4sL0hC2gA"; function uploadGps(data) { return request({ url: "/fulfiller/fulfiller/gps", method: "POST", data }); } function getMyProfile() { return request({ url: "/fulfiller/fulfiller/my", method: "GET" }); } function updateAvatar(avatar) { return request({ url: "/fulfiller/fulfiller/my/avatar", method: "PUT", data: { avatar } }); } function updateName(name) { return request({ url: "/fulfiller/fulfiller/my/name", method: "PUT", data: { name } }); } function updateStatus(status) { return request({ url: "/fulfiller/fulfiller/my/status", method: "PUT", data: { status } }); } function updateCity(data) { return request({ url: "/fulfiller/fulfiller/my/city", method: "PUT", data }); } function getAuthInfo() { return request({ url: "/fulfiller/fulfiller/my/auth", method: "GET" }); } function updatePhone(phone, code) { return request({ url: "/fulfiller/fulfiller/my/phone", method: "PUT", data: { phone, code } }); } function updatePassword(oldPassword, newPassword) { return request({ url: "/fulfiller/fulfiller/my/password", method: "PUT", data: { oldPassword, newPassword } }); } function deleteAccount() { return request({ url: "/fulfiller/fulfiller/my/account", method: "DELETE" }); } function updateAuthInfo(data) { return request({ url: "/fulfiller/fulfiller/my/auth", method: "POST", data }); } let gpsTimer = null; function reportGps(manual = false) { return new Promise((resolve, reject) => { uni.getLocation({ type: "wgs84", success: function(res) { const data = { longitude: res.longitude, latitude: res.latitude }; uploadGps(data).then(() => { formatAppLog("log", "at utils/gps.js:21", "GPS定位上传成功", data); resolve(res); }).catch((err) => { formatAppLog("error", "at utils/gps.js:24", "GPS定位上传失败", err); reject(err); }); }, fail: function(err) { formatAppLog("error", "at utils/gps.js:29", "获取GPS定位失败", err); if (manual) { checkAndRequestPermission(reject); } else { reject(err); } } }); }); } function checkAndRequestPermission(reject) { uni.getSetting({ success(res) { if (!res.authSetting["scope.userLocation"]) { uni.showModal({ title: "定位未授权", content: "请开启定位权限,以便为您推荐附近的订单并记录服务轨迹", confirmText: "去设置", success: (modalRes) => { if (modalRes.confirm) { uni.openSetting({ success: (settingRes) => { if (settingRes.authSetting["scope.userLocation"]) { reportGps(true); } } }); } else { if (reject) reject(new Error("User denied location permission")); } } }); } else { uni.showToast({ title: "获取定位失败,请检查手机GPS是否开启", icon: "none" }); if (reject) reject(new Error("Location failed even with permission")); } } }); } function startGpsTimer() { const isEnabled = uni.getStorageSync("GPS_REPORT_ENABLED"); if (isEnabled === false) { stopGpsTimer(); return; } stopGpsTimer(); reportGps(); gpsTimer = setInterval(() => { reportGps(); }, 12e5); } function stopGpsTimer() { if (gpsTimer) { clearInterval(gpsTimer); gpsTimer = null; } } const TOKEN_KEY = "fulfiller_token"; const USER_INFO_KEY = "fulfiller_user_info"; function getToken() { return uni.getStorageSync(TOKEN_KEY) || ""; } function setToken(token) { uni.setStorageSync(TOKEN_KEY, token); } function removeToken() { uni.removeStorageSync(TOKEN_KEY); } function isLoggedIn() { return !!getToken(); } function removeUserInfo() { uni.removeStorageSync(USER_INFO_KEY); } function clearAuth() { removeToken(); removeUserInfo(); stopGpsTimer(); } function request(options = {}) { const { url, method = "GET", data, header = {}, needToken = true } = options; const headers = { "Content-Type": "application/json;charset=utf-8", "clientid": CLIENT_ID, "X-Platform-Code": PLATFORM_CODE, ...header }; if (needToken) { const token = getToken(); if (token) { headers["Authorization"] = "Bearer " + token; } } return new Promise((resolve, reject) => { uni.request({ url: BASE_URL + url, method: method.toUpperCase(), data, header: headers, timeout: 6e5, success: (res) => { formatAppLog("log", "at utils/request.js:51", res); const statusCode = res.statusCode; const code = res.data.code; const msg = res.data.msg; res.data.data; if (statusCode !== 200) { const errorMsg = msg || `请求失败(${statusCode})`; uni.showToast({ title: errorMsg, icon: "none" }); return reject(new Error(errorMsg)); } if (code === 401) { clearAuth(); uni.showToast({ title: "登录已过期,请重新登录", icon: "none" }); setTimeout(() => { uni.reLaunch({ url: "/pages/login/login" }); }, 1500); return reject(new Error("未授权")); } if (code !== void 0 && code !== 200) { const errorMsg = msg || "操作失败"; uni.showToast({ title: errorMsg, icon: "none" }); return reject(new Error(errorMsg)); } resolve(res.data); }, fail: (err) => { uni.showToast({ title: "网络异常,请稍后重试", icon: "none" }); reject(err); } }); }); } function loginByPassword(username, password) { return request({ url: "/auth/login", method: "POST", needToken: false, data: { userSource: 1, username, password, clientId: CLIENT_ID, grantType: "password", source: 1 } }); } function logout() { return request({ url: "/auth/logout", method: "POST" }); } function getAgreement(id) { return request({ url: "/system/agreement/" + id, method: "get" }); } function getAppSetting(id) { return request({ url: "/system/appSetting/" + id, method: "get" }); } const logic$9 = { data() { return { currentTab: 1, // 0: 免密, 1: 密码 mobile: "", code: "", password: "", showPassword: false, isAgreed: false, countDown: 0, timer: null, showAgreementModal: false, agreementTitle: "", // 协议标题 agreementContent: "", // 协议内容 loginLoading: false, loginIconUrl: "/static/logo.png", // 登录图标 loginBackgroundUrl: "/static/header.png" // 登录背景 }; }, async onLoad() { uni.removeStorageSync("recruit_form_data"); uni.removeStorageSync("recruit_auth_data"); uni.removeStorageSync("recruit_qual_data"); await this.fetchAppSetting(); }, methods: { /** * 获取应用配置 */ async fetchAppSetting() { try { const res = await getAppSetting(1); if (res.code === 200 && res.data) { if (res.data.loginIconUrl) { this.loginIconUrl = res.data.loginIconUrl; } if (res.data.loginBackgroundUrl) { this.loginBackgroundUrl = res.data.loginBackgroundUrl; } } } catch (err) { formatAppLog("error", "at pages/login/logic.js:52", "获取应用配置失败:", err); } }, /** * 显示协议弹窗 * @param {Number} id 协议ID (1: 用户服务协议, 2: 隐私政策) */ async showAgreement(id) { try { uni.showLoading({ title: "加载中..." }); const res = await getAgreement(id); if (res.code === 200 && res.data) { this.agreementTitle = res.data.title; this.agreementContent = res.data.content; this.showAgreementModal = true; } else { uni.showToast({ title: res.msg || "获取协议失败", icon: "none" }); } } catch (err) { formatAppLog("error", "at pages/login/logic.js:71", "获取协议详情失败:", err); } finally { uni.hideLoading(); } }, /* async getVerifyCode() { if (this.currentTab === 1) return; if (this.countDown > 0) return; if (!this.mobile || this.mobile.length !== 11) { uni.showToast({ title: '请输入正确的手机号', icon: 'none' }); return; } try { const res = await sendSmsCode(this.mobile); // 发送成功,启动倒计时 this.countDown = 60; this.timer = setInterval(() => { this.countDown--; if (this.countDown <= 0) { clearInterval(this.timer); } }, 1000); // TODO 【生产环境必须删除】开发模式下后端会返回验证码,自动填入方便测试 const devCode = res.data; if (devCode) { this.code = devCode; uni.showToast({ title: '验证码: ' + devCode, icon: 'none', duration: 3000 }); } else { uni.showToast({ title: '验证码已发送', icon: 'none' }); } } catch (err) { __f__('error','at pages/login/logic.js:103','发送验证码失败:', err); } }, */ async handleLogin() { var _a; if (!this.isAgreed) { uni.showToast({ title: "请先同意用户协议", icon: "none" }); return; } if (!this.mobile) { uni.showToast({ title: "请输入手机号", icon: "none" }); return; } if (!this.password) { uni.showToast({ title: "请输入密码", icon: "none" }); return; } if (this.loginLoading) return; this.loginLoading = true; uni.showLoading({ title: "登录中...", mask: true }); try { let res; res = await loginByPassword(this.mobile, this.password); const token = ((_a = res.data) == null ? void 0 : _a.access_token) || res.access_token; if (token) { setToken(token); } startGpsTimer(); uni.showToast({ title: "登录成功", icon: "success" }); setTimeout(() => { uni.switchTab({ url: "/pages/home/index" }); }, 1e3); } catch (err) { formatAppLog("error", "at pages/login/logic.js:168", "登录失败:", err); } finally { this.loginLoading = false; uni.hideLoading(); } }, goToRecruit() { uni.navigateTo({ url: "/pages/recruit/landing" }); }, goToForgotPwd() { uni.navigateTo({ url: "/pages/login/reset-pwd-verify" }); } } }; const _export_sfc = (sfc, props) => { const target = sfc.__vccOpts || sfc; for (const [key, val] of props) { target[key] = val; } return target; }; const _sfc_main$E = { name: "Agreement", props: { visible: { type: Boolean, default: false }, title: { type: String, default: "" }, content: { type: String, default: "" } }, methods: { /** * 关闭弹窗 */ handleClose() { this.$emit("close"); } } }; function _sfc_render$D(_ctx, _cache, $props, $setup, $data, $options) { return $props.visible ? (vue.openBlock(), vue.createElementBlock( "view", { key: 0, class: "agreement-mask", onTouchmove: _cache[1] || (_cache[1] = vue.withModifiers(() => { }, ["stop", "prevent"])) }, [ vue.createElementVNode("view", { class: "agreement-container" }, [ vue.createElementVNode("view", { class: "agreement-header" }, [ vue.createElementVNode( "text", { class: "agreement-title" }, vue.toDisplayString($props.title || "协议详情"), 1 /* TEXT */ ) ]), vue.createElementVNode("scroll-view", { "scroll-y": "", class: "agreement-body" }, [ vue.createElementVNode("rich-text", { nodes: $props.content }, null, 8, ["nodes"]) ]), vue.createElementVNode("view", { class: "agreement-footer" }, [ vue.createElementVNode("button", { class: "confirm-btn", onClick: _cache[0] || (_cache[0] = (...args) => $options.handleClose && $options.handleClose(...args)) }, "确 定") ]) ]) ], 32 /* NEED_HYDRATION */ )) : vue.createCommentVNode("v-if", true); } const Agreement = /* @__PURE__ */ _export_sfc(_sfc_main$E, [["render", _sfc_render$D], ["__scopeId", "data-v-c8509778"], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/components/agreement/index.vue"]]); const _sfc_main$D = { ...logic$9, components: { Agreement } }; function _sfc_render$C(_ctx, _cache, $props, $setup, $data, $options) { const _component_agreement = vue.resolveComponent("agreement"); return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "banner-area" }, [ vue.createElementVNode("image", { class: "banner-img", src: _ctx.loginBackgroundUrl, mode: "widthFix" }, null, 8, ["src"]) ]), vue.createElementVNode("view", { class: "content-card" }, [ vue.createElementVNode("view", { class: "logo-wrapper" }, [ vue.createElementVNode("image", { class: "logo-img", src: _ctx.loginIconUrl, mode: "widthFix" }, null, 8, ["src"]) ]), vue.createElementVNode("view", { class: "tabs" }, [ vue.createElementVNode("view", { class: "tab-item active" }, [ vue.createElementVNode("text", { class: "tab-text" }, "密码登录"), vue.createElementVNode("view", { class: "tab-indicator" }) ]) ]), vue.createElementVNode("view", { class: "form-area" }, [ vue.createElementVNode("view", { class: "input-group" }, [ vue.createElementVNode("view", { class: "area-code" }, [ vue.createElementVNode("text", null, "+86"), vue.createElementVNode("text", { class: "arrow" }, "﹀") ]), vue.withDirectives(vue.createElementVNode( "input", { class: "input", type: "number", placeholder: "手机号", "placeholder-style": "color: #ccc", "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.mobile = $event), maxlength: "11" }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, _ctx.mobile] ]) ]), vue.createElementVNode("view", { class: "input-group" }, [ vue.withDirectives(vue.createElementVNode("input", { class: "input", password: !_ctx.showPassword, type: "text", placeholder: "请输入密码", "placeholder-style": "color: #ccc", "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => _ctx.password = $event) }, null, 8, ["password"]), [ [vue.vModelText, _ctx.password] ]), vue.createElementVNode("view", { class: "eye-icon", onClick: _cache[2] || (_cache[2] = ($event) => _ctx.showPassword = !_ctx.showPassword) }, [ _ctx.showPassword ? (vue.openBlock(), vue.createElementBlock("svg", { key: 0, class: "svg-icon", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, [ vue.createElementVNode("path", { d: "M12 4.5C7 4.5 2.73 7.61 1 12C2.73 16.39 7 19.5 12 19.5C17 19.5 21.27 16.39 23 12C21.27 7.61 17 4.5 12 4.5ZM12 17C9.24 17 7 14.76 7 12C7 9.24 9.24 7 12 7C14.76 7 17 9.24 17 12C17 14.76 14.76 17 12 17ZM12 9C10.34 9 9 10.34 9 12C9 13.66 10.34 15 12 15C13.66 15 15 13.66 15 12C15 10.34 13.66 9 12 9Z", fill: "#CCCCCC" }) ])) : (vue.openBlock(), vue.createElementBlock("svg", { key: 1, class: "svg-icon", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, [ vue.createElementVNode("path", { d: "M12 7C7 7 2.73 10.11 1 14.5", stroke: "#CCCCCC", "stroke-width": "2", "stroke-linecap": "round" }), vue.createElementVNode("path", { d: "M23 14.5C21.27 10.11 17 7 12 7", stroke: "#CCCCCC", "stroke-width": "2", "stroke-linecap": "round" }), vue.createElementVNode("path", { d: "M12 7V4", stroke: "#CCCCCC", "stroke-width": "2", "stroke-linecap": "round" }), vue.createElementVNode("path", { d: "M16 8L18 5", stroke: "#CCCCCC", "stroke-width": "2", "stroke-linecap": "round" }), vue.createElementVNode("path", { d: "M8 8L6 5", stroke: "#CCCCCC", "stroke-width": "2", "stroke-linecap": "round" }), vue.createElementVNode("path", { d: "M20 10L22 8", stroke: "#CCCCCC", "stroke-width": "2", "stroke-linecap": "round" }), vue.createElementVNode("path", { d: "M4 10L2 8", stroke: "#CCCCCC", "stroke-width": "2", "stroke-linecap": "round" }) ])) ]) ]), vue.createElementVNode("button", { class: "login-btn", onClick: _cache[3] || (_cache[3] = (...args) => _ctx.handleLogin && _ctx.handleLogin(...args)) }, "登 录"), vue.createElementVNode("view", { class: "agreement" }, [ vue.createElementVNode( "view", { class: vue.normalizeClass(["checkbox", { checked: _ctx.isAgreed }]), onClick: _cache[4] || (_cache[4] = ($event) => _ctx.isAgreed = !_ctx.isAgreed) }, [ _ctx.isAgreed ? (vue.openBlock(), vue.createElementBlock("text", { key: 0, class: "check-mark" }, "✓")) : vue.createCommentVNode("v-if", true) ], 2 /* CLASS */ ), vue.createElementVNode("text", { class: "agree-text" }, [ vue.createTextVNode(" 我已经阅读并同意 "), vue.createElementVNode("text", { class: "link", onClick: _cache[5] || (_cache[5] = vue.withModifiers(($event) => _ctx.showAgreement(1), ["stop"])) }, "《用户服务协议》"), vue.createTextVNode(" 和 "), vue.createElementVNode("text", { class: "link", onClick: _cache[6] || (_cache[6] = vue.withModifiers(($event) => _ctx.showAgreement(2), ["stop"])) }, "《隐私政策》") ]) ]) ]), vue.createElementVNode("view", { class: "footer-recruit", onClick: _cache[7] || (_cache[7] = (...args) => _ctx.goToRecruit && _ctx.goToRecruit(...args)) }, [ vue.createElementVNode("view", { class: "recruit-badge" }, [ (vue.openBlock(), vue.createElementBlock("svg", { class: "svg-icon flag-icon", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", style: { "width": "30rpx", "height": "30rpx" } }, [ vue.createElementVNode("path", { d: "M4 14V4H18L17 9L18 14H4Z", stroke: "#FF5722", "stroke-width": "2", "stroke-linejoin": "round" }), vue.createElementVNode("path", { d: "M4 22V14", stroke: "#FF5722", "stroke-width": "2", "stroke-linecap": "round" }) ])), vue.createElementVNode("text", null, " 宠宝履约者招募") ]) ]), vue.createVNode(_component_agreement, { visible: _ctx.showAgreementModal, title: _ctx.agreementTitle, content: _ctx.agreementContent, onClose: _cache[8] || (_cache[8] = ($event) => _ctx.showAgreementModal = false) }, null, 8, ["visible", "title", "content"]) ]) ]); } const PagesLoginLogin = /* @__PURE__ */ _export_sfc(_sfc_main$D, [["render", _sfc_render$C], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/login/login.vue"]]); const logic$8 = { data() { return { statusBarHeight: 20 // 默认状态栏高度 }; }, onLoad() { const sysInfo = uni.getSystemInfoSync(); this.statusBarHeight = sysInfo.statusBarHeight || 20; }, methods: { goBack() { const pages = getCurrentPages(); if (pages.length > 1) { uni.navigateBack(); } else { uni.reLaunch({ url: "/pages/login/login" }); } }, goToForm() { uni.navigateTo({ url: "/pages/recruit/form" }); } } }; const _sfc_main$C = logic$8; function _sfc_render$B(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode( "view", { style: vue.normalizeStyle({ height: _ctx.statusBarHeight + "px" }) }, null, 4 /* STYLE */ ), vue.createElementVNode("view", { class: "nav-bar" }, [ vue.createElementVNode("view", { class: "back-icon", onClick: _cache[0] || (_cache[0] = (...args) => _ctx.goBack && _ctx.goBack(...args)) }, "‹") ]), vue.createElementVNode("view", { class: "header-area" }, [ vue.createElementVNode("text", { class: "main-title" }, "加入宠宝履约者"), vue.createElementVNode("text", { class: "sub-title" }, "月薪最高可达1.5万元") ]), vue.createElementVNode("view", { class: "content-card" }, [ vue.createElementVNode("view", { class: "benefit-item" }, [ vue.createElementVNode("view", { class: "icon-circle icon-money" }, [ vue.createElementVNode("text", { class: "icon-text" }, "¥") ]), vue.createElementVNode("view", { class: "info" }, [ vue.createElementVNode("text", { class: "item-title" }, "1、收入可观"), vue.createElementVNode("text", { class: "item-desc" }, "小默配送为您提供一种全新的赚钱选择,利用空闲时间,获得更多收入。") ]) ]), vue.createElementVNode("view", { class: "benefit-item" }, [ vue.createElementVNode("view", { class: "icon-circle icon-loc" }, [ vue.createElementVNode("text", { class: "icon-text" }, "📍") ]), vue.createElementVNode("view", { class: "info" }, [ vue.createElementVNode("text", { class: "item-title" }, "2、地点灵活"), vue.createElementVNode("text", { class: "item-desc" }, "小默配送覆盖国内各城市与港澳台等地,您可随时就近使用。") ]) ]), vue.createElementVNode("view", { class: "benefit-item" }, [ vue.createElementVNode("view", { class: "icon-circle icon-clock" }, [ vue.createElementVNode("text", { class: "icon-text" }, "🕒") ]), vue.createElementVNode("view", { class: "info" }, [ vue.createElementVNode("text", { class: "item-title" }, "3、时间自由"), vue.createElementVNode("text", { class: "item-desc" }, "不必再受繁琐事务约束,加入小默配送,自由分配个人时间,为自己工作。") ]) ]) ]), vue.createElementVNode("view", { class: "footer-area" }, [ vue.createElementVNode("button", { class: "join-btn", onClick: _cache[1] || (_cache[1] = (...args) => _ctx.goToForm && _ctx.goToForm(...args)) }, "我要加入"), vue.createElementVNode("view", { class: "faq" }, [ vue.createElementVNode("text", { class: "help-icon" }, "?"), vue.createTextVNode(" 常见问题 ") ]) ]) ]); } const PagesRecruitLanding = /* @__PURE__ */ _export_sfc(_sfc_main$C, [["render", _sfc_render$B], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/recruit/landing.vue"]]); function getAreaStationList() { return request({ url: "/system/areaStation/list", method: "GET" }); } function listAllService() { return request({ url: "/service/list/listAll", method: "GET" }); } const logic$7 = { data() { return { formData: { mobile: "", code: "", name: "", gender: 1, // 1男 2女 birthday: "", password: "", serviceType: [], station: "", stationId: null, areaPath: "" // 用于回显“区域+站点”名称 }, showPwd: false, isAgreed: false, serviceTypes: [], // 验证码倒计时 countDown: 0, timer: null, // 日期选择器相关 showPicker: false, years: [], months: [], days: [], pickerValue: [0, 0, 0], tempYear: 0, tempMonth: 0, tempDay: 0, // 站点选择器(级联版) showStationPickerCascader: false, selectStep: 0, selectedPathway: [], currentList: [], fullStationData: [], // 全量数据 selectedStationId: null, // 协议弹窗 showPrivacy: false, agreementTitle: "", // 协议标题 agreementContent: "", // 协议内容 currentAgreementId: "" // 当前协议ID }; }, onLoad() { this.initDateData(); this.loadServiceTypes(); this.loadAreaStationData(); this.restoreFormData(); }, beforeDestroy() { if (this.timer) clearInterval(this.timer); }, methods: { async loadAreaStationData() { try { const res = await getAreaStationList(); this.fullStationData = res.data || []; } catch (err) { formatAppLog("error", "at pages/recruit/logic.js:73", "加载站点列表失败:", err); } }, restoreFormData() { try { const saved = uni.getStorageSync("recruit_form_data"); if (saved) { const d = JSON.parse(saved); Object.assign(this.formData, d); if (d._selectedPathway) { this.selectedPathway = d._selectedPathway; this.selectStep = this.selectedPathway.length; } if (this.selectedPathway.length > 0) { const last = this.selectedPathway[this.selectedPathway.length - 1]; if (last) this.loadStations(last.id); } } } catch (e) { formatAppLog("error", "at pages/recruit/logic.js:95", "恢复表单数据失败", e); } }, initDateData() { const now = /* @__PURE__ */ new Date(); const currentYear = now.getFullYear(); for (let i = 1980; i <= currentYear + 5; i++) { this.years.push(i); } for (let i = 1; i <= 12; i++) { this.months.push(i); } for (let i = 1; i <= 31; i++) { this.days.push(i); } }, // 打开选择器 openPicker() { const dateStr = this.formData.birthday || "2000-01-01"; const [y, m, d] = dateStr.split("-").map(Number); const yIndex = this.years.indexOf(y); const mIndex = this.months.indexOf(m); const dIndex = this.days.indexOf(d); this.pickerValue = [ yIndex > -1 ? yIndex : 0, mIndex > -1 ? mIndex : 0, dIndex > -1 ? dIndex : 0 ]; this.tempYear = this.years[this.pickerValue[0]]; this.tempMonth = this.months[this.pickerValue[1]]; this.tempDay = this.days[this.pickerValue[2]]; this.showPicker = true; }, closePicker() { this.showPicker = false; }, onPickerChange(e) { const val = e.detail.value; this.tempYear = this.years[val[0]]; this.tempMonth = this.months[val[1]]; this.tempDay = this.days[val[2]]; }, confirmPicker() { const mStr = this.tempMonth < 10 ? "0" + this.tempMonth : this.tempMonth; const dStr = this.tempDay < 10 ? "0" + this.tempDay : this.tempDay; this.formData.birthday = `${this.tempYear}-${mStr}-${dStr}`; this.closePicker(); }, async loadServiceTypes() { try { const res = await listAllService(); this.serviceTypes = (res.data || []).map((item) => ({ id: item.id, name: item.name })); } catch (err) { formatAppLog("error", "at pages/recruit/logic.js:167", "加载服务类型失败:", err); this.serviceTypes = []; } }, toggleService(item) { const idx = this.formData.serviceType.indexOf(item.id); if (idx > -1) { this.formData.serviceType.splice(idx, 1); } else { this.formData.serviceType.push(item.id); } }, // 验证码 /* async getVerifyCode() { if (this.countDown > 0) return; if (!this.formData.mobile || this.formData.mobile.length !== 11) { uni.showToast({ title: '请输入正确的手机号', icon: 'none' }); return; } try { const res = await sendSmsCode(this.formData.mobile); this.countDown = 60; this.timer = setInterval(() => { this.countDown--; if (this.countDown <= 0) clearInterval(this.timer); }, 1000); // TODO 【生产环境必须删除】开发模式自动填入验证码 const devCode = res.data; if (devCode) { this.formData.code = devCode; uni.showToast({ title: '验证码: ' + devCode, icon: 'none', duration: 3000 }); } else { uni.showToast({ title: '验证码已发送', icon: 'none' }); } } catch (err) { __f__('error','at pages/recruit/logic.js:204','发送验证码失败:', err); } }, */ // 站点级联选择逻辑 (从全量本地数据中根据 parentId 过滤) async openStationPickerCascader() { this.showStationPickerCascader = true; if (this.selectedPathway.length === 0) { await this.resetStationPicker(); } }, async resetStationPicker() { this.selectStep = 0; this.selectedPathway = []; this.filterLocalChildren(0); }, closeStationPickerCascader() { this.showStationPickerCascader = false; }, filterLocalChildren(parentId) { this.currentList = this.fullStationData.filter((item) => item.parentId == parentId); }, async selectStationItem(item) { this.selectedPathway[this.selectStep] = item; const sons = this.fullStationData.filter((i) => i.parentId == item.id); if (sons.length > 0) { this.selectStep++; this.selectedPathway = this.selectedPathway.slice(0, this.selectStep); this.currentList = sons; } else { this.confirmStation(); } }, async jumpToStep(step) { this.selectStep = step; if (step === 0) { this.filterLocalChildren(0); } else { const parent = this.selectedPathway[step - 1]; if (parent) { this.filterLocalChildren(parent.id); } } }, confirmStation() { const path = this.selectedPathway.map((i) => i.name); const stationName = path[path.length - 1]; const areaName = path.slice(0, -1).join(" "); this.formData.station = stationName; this.formData.stationId = this.selectedPathway[this.selectedPathway.length - 1].id; this.formData.areaPath = areaName; this.closeStationPickerCascader(); }, // --- 废弃的功能逻辑 (已被站点选择合并或移除) --- /* async loadStations(parentId) { ... } */ /* openStationPicker() { ... } */ /* selectStation(item) { ... } */ /* async openCityPicker() { ... } */ /* loadAreaChildren(parentId) { ... } */ /* async selectCityItem(item) { ... } */ /* confirmCity() { ... } */ async openPrivacy() { try { uni.showLoading({ title: "加载中..." }); const res = await getAgreement(3); if (res.code === 200 && res.data) { this.agreementTitle = res.data.title; this.agreementContent = res.data.content; this.showPrivacy = true; } else { uni.showToast({ title: res.msg || "获取协议失败", icon: "none" }); } } catch (err) { formatAppLog("error", "at pages/recruit/logic.js:287", "获取协议详情失败:", err); } finally { uni.hideLoading(); } }, goToAuth() { if (!this.isAgreed) { uni.showToast({ title: "请勾选协议", icon: "none" }); return; } if (!this.formData.mobile || this.formData.mobile.length !== 11) { uni.showToast({ title: "请输入正确的手机号", icon: "none" }); return; } if (!this.formData.name) { uni.showToast({ title: "请输入姓名", icon: "none" }); return; } if (this.formData.serviceType.length === 0) { uni.showToast({ title: "请选择服务类型", icon: "none" }); return; } if (!this.formData.stationId) { uni.showToast({ title: "请选择所属站点", icon: "none" }); return; } uni.setStorageSync("recruit_form_data", JSON.stringify({ ...this.formData, _selectedPathway: this.selectedPathway // 私有存储,仅用于回显 })); const selectedServices = this.serviceTypes.filter((s) => this.formData.serviceType.includes(s.id)); const services = JSON.stringify(selectedServices); uni.navigateTo({ url: `/pages/recruit/auth?services=${encodeURIComponent(services)}` }); } } }; const _sfc_main$B = { ...logic$7, components: { Agreement } }; function _sfc_render$A(_ctx, _cache, $props, $setup, $data, $options) { const _component_agreement = vue.resolveComponent("agreement"); return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "card" }, [ vue.createElementVNode("view", { class: "form-item" }, [ vue.createElementVNode("text", { class: "label" }, "手机号"), vue.createElementVNode("view", { class: "input-box" }, [ vue.createElementVNode("view", { class: "prefix-area" }, [ vue.createElementVNode("text", { class: "prefix" }, "+86"), vue.createElementVNode("text", { class: "arrow-down" }, "﹀") ]), vue.withDirectives(vue.createElementVNode( "input", { class: "input", type: "number", "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.formData.mobile = $event) }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, _ctx.formData.mobile] ]) ]) ]), vue.createElementVNode("view", { class: "form-item" }, [ vue.createElementVNode("text", { class: "label" }, "姓名"), vue.createElementVNode("view", { class: "input-box" }, [ vue.withDirectives(vue.createElementVNode( "input", { class: "input", type: "text", "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => _ctx.formData.name = $event) }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, _ctx.formData.name] ]) ]) ]), vue.createElementVNode("view", { class: "form-item" }, [ vue.createElementVNode("text", { class: "label" }, "性别"), vue.createElementVNode("view", { class: "gender-group" }, [ vue.createElementVNode("view", { class: "radio-item", onClick: _cache[2] || (_cache[2] = ($event) => _ctx.formData.gender = 1) }, [ vue.createElementVNode( "text", { class: vue.normalizeClass(["radio-icon", { active: _ctx.formData.gender === 1 }]) }, vue.toDisplayString(_ctx.formData.gender === 1 ? "♂" : "○"), 3 /* TEXT, CLASS */ ), vue.createElementVNode( "text", { class: vue.normalizeClass(["radio-label", { active: _ctx.formData.gender === 1 }]) }, " 男", 2 /* CLASS */ ) ]), vue.createElementVNode("view", { class: "radio-item", onClick: _cache[3] || (_cache[3] = ($event) => _ctx.formData.gender = 2) }, [ vue.createElementVNode( "text", { class: vue.normalizeClass(["radio-icon", { active: _ctx.formData.gender === 2 }]) }, vue.toDisplayString(_ctx.formData.gender === 2 ? "♀" : "○"), 3 /* TEXT, CLASS */ ), vue.createElementVNode( "text", { class: vue.normalizeClass(["radio-label", { active: _ctx.formData.gender === 2 }]) }, " 女", 2 /* CLASS */ ) ]) ]) ]), vue.createElementVNode("view", { class: "form-item" }, [ vue.createElementVNode("text", { class: "label" }, "生日"), vue.createElementVNode("view", { class: "input-box", onClick: _cache[4] || (_cache[4] = (...args) => _ctx.openPicker && _ctx.openPicker(...args)) }, [ vue.createElementVNode( "text", null, vue.toDisplayString(_ctx.formData.birthday || "请选择生日"), 1 /* TEXT */ ), (vue.openBlock(), vue.createElementBlock("svg", { class: "arrow-right", style: { "width": "24rpx", "height": "24rpx", "margin-left": "auto" }, viewBox: "0 0 1024 1024", version: "1.1", xmlns: "http://www.w3.org/2000/svg" }, [ vue.createElementVNode("path", { d: "M340.864 149.312a30.592 30.592 0 0 0 0 42.752L652.736 512 340.864 831.872a30.592 30.592 0 0 0 0 42.752 29.12 29.12 0 0 0 41.728 0L714.24 534.336a32 32 0 0 0 0-45.056L382.592 149.312a29.12 29.12 0 0 0-41.728 0z", fill: "#CCCCCC" }) ])) ]) ]), vue.createElementVNode("view", { class: "form-item" }, [ vue.createElementVNode("text", { class: "label" }, "密码"), vue.createElementVNode("view", { class: "input-box" }, [ vue.withDirectives(vue.createElementVNode("input", { class: "input", password: !_ctx.showPwd, "onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => _ctx.formData.password = $event), placeholder: "设置登录密码" }, null, 8, ["password"]), [ [vue.vModelText, _ctx.formData.password] ]), vue.createElementVNode("view", { class: "monkey-icon", onClick: _cache[6] || (_cache[6] = ($event) => _ctx.showPwd = !_ctx.showPwd) }, [ _ctx.showPwd ? (vue.openBlock(), vue.createElementBlock("svg", { key: 0, class: "svg-icon", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, [ vue.createElementVNode("path", { d: "M12 4.5C7 4.5 2.73 7.61 1 12C2.73 16.39 7 19.5 12 19.5C17 19.5 21.27 16.39 23 12C21.27 7.61 17 4.5 12 4.5ZM12 17C9.24 17 7 14.76 7 12C7 9.24 9.24 7 12 7C14.76 7 17 9.24 17 12C17 14.76 14.76 17 12 17ZM12 9C10.34 9 9 10.34 9 12C9 13.66 10.34 15 12 15C13.66 15 15 13.66 15 12C15 10.34 13.66 9 12 9Z", fill: "#CCCCCC" }) ])) : (vue.openBlock(), vue.createElementBlock("svg", { key: 1, class: "svg-icon", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, [ vue.createElementVNode("path", { d: "M12 7C7 7 2.73 10.11 1 14.5", stroke: "#CCCCCC", "stroke-width": "2", "stroke-linecap": "round" }), vue.createElementVNode("path", { d: "M23 14.5C21.27 10.11 17 7 12 7", stroke: "#CCCCCC", "stroke-width": "2", "stroke-linecap": "round" }), vue.createElementVNode("path", { d: "M12 7V4", stroke: "#CCCCCC", "stroke-width": "2", "stroke-linecap": "round" }), vue.createElementVNode("path", { d: "M16 8L18 5", stroke: "#CCCCCC", "stroke-width": "2", "stroke-linecap": "round" }), vue.createElementVNode("path", { d: "M8 8L6 5", stroke: "#CCCCCC", "stroke-width": "2", "stroke-linecap": "round" }), vue.createElementVNode("path", { d: "M20 10L22 8", stroke: "#CCCCCC", "stroke-width": "2", "stroke-linecap": "round" }), vue.createElementVNode("path", { d: "M4 10L2 8", stroke: "#CCCCCC", "stroke-width": "2", "stroke-linecap": "round" }) ])) ]) ]) ]) ]), vue.createElementVNode("view", { class: "card" }, [ vue.createElementVNode("view", { class: "section-title" }, "服务类型"), vue.createElementVNode("view", { class: "service-types" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.serviceTypes, (item, index) => { return vue.openBlock(), vue.createElementBlock("view", { class: vue.normalizeClass(["type-btn", { selected: _ctx.formData.serviceType.includes(item.id) }]), key: item.id, onClick: ($event) => _ctx.toggleService(item) }, vue.toDisplayString(item.name), 11, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )) ]), vue.createElementVNode("view", { class: "form-item" }, [ vue.createElementVNode("text", { class: "label" }, "所属站点"), vue.createElementVNode("view", { class: "input-box", onClick: _cache[7] || (_cache[7] = (...args) => _ctx.openStationPickerCascader && _ctx.openStationPickerCascader(...args)) }, [ _ctx.formData.station ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "station-display" }, [ _ctx.formData.areaPath ? (vue.openBlock(), vue.createElementBlock( "text", { key: 0, class: "area-tag" }, vue.toDisplayString(_ctx.formData.areaPath), 1 /* TEXT */ )) : vue.createCommentVNode("v-if", true), vue.createElementVNode( "text", { class: "station-name" }, vue.toDisplayString(_ctx.formData.station), 1 /* TEXT */ ) ])) : (vue.openBlock(), vue.createElementBlock("text", { key: 1, style: { "color": "#ccc" } }, "请选择所属站点")), (vue.openBlock(), vue.createElementBlock("svg", { class: "arrow-right", style: { "width": "24rpx", "height": "24rpx", "margin-left": "auto" }, viewBox: "0 0 1024 1024", version: "1.1", xmlns: "http://www.w3.org/2000/svg" }, [ vue.createElementVNode("path", { d: "M340.864 149.312a30.592 30.592 0 0 0 0 42.752L652.736 512 340.864 831.872a30.592 30.592 0 0 0 0 42.752 29.12 29.12 0 0 0 41.728 0L714.24 534.336a32 32 0 0 0 0-45.056L382.592 149.312a29.12 29.12 0 0 0-41.728 0z", fill: "#CCCCCC" }) ])) ]) ]) ]), vue.createElementVNode( "view", { class: vue.normalizeClass(["picker-mask", { show: _ctx.showStationPickerCascader }]), onClick: _cache[11] || (_cache[11] = (...args) => _ctx.closeStationPickerCascader && _ctx.closeStationPickerCascader(...args)) }, [ vue.createElementVNode("view", { class: "picker-content", onClick: _cache[10] || (_cache[10] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("view", { class: "picker-header" }, [ vue.createElementVNode("text", { class: "picker-btn-cancel", onClick: _cache[8] || (_cache[8] = (...args) => _ctx.closeStationPickerCascader && _ctx.closeStationPickerCascader(...args)) }, "取消"), vue.createElementVNode("text", { class: "picker-title" }, "请选择所属站点"), vue.createElementVNode("text", { class: "picker-btn-confirm", onClick: _cache[9] || (_cache[9] = (...args) => _ctx.closeStationPickerCascader && _ctx.closeStationPickerCascader(...args)) }, "关闭") ]), vue.createElementVNode("view", { class: "picker-body" }, [ vue.createElementVNode("view", { class: "timeline-area" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.selectedPathway, (item, index) => { return vue.openBlock(), vue.createElementBlock("view", { class: "timeline-item", key: index, onClick: ($event) => _ctx.jumpToStep(index) }, [ vue.createElementVNode("view", { class: "timeline-dot" }), vue.createElementVNode( "text", null, vue.toDisplayString(item.name), 1 /* TEXT */ ) ], 8, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )), _ctx.selectStep === _ctx.selectedPathway.length ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "timeline-item active" }, [ vue.createElementVNode("view", { class: "timeline-dot" }), vue.createElementVNode("text", null, "请选择") ])) : vue.createCommentVNode("v-if", true) ]), vue.createElementVNode("scroll-view", { "scroll-y": "", class: "list-area" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.currentList, (item, index) => { return vue.openBlock(), vue.createElementBlock("view", { class: "list-item", key: item.id, onClick: ($event) => _ctx.selectStationItem(item) }, vue.toDisplayString(item.name), 9, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )), _ctx.currentList.length === 0 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, style: { "padding": "20rpx", "color": "#999" } }, " 无数据 ")) : vue.createCommentVNode("v-if", true) ]) ]) ]) ], 2 /* CLASS */ ), vue.createElementVNode("view", { class: "footer-actions" }, [ vue.createElementVNode("view", { class: "agreement-row" }, [ vue.createElementVNode( "view", { class: vue.normalizeClass(["checkbox", { checked: _ctx.isAgreed }]), onClick: _cache[12] || (_cache[12] = ($event) => _ctx.isAgreed = !_ctx.isAgreed) }, [ _ctx.isAgreed ? (vue.openBlock(), vue.createElementBlock("text", { key: 0, class: "check-mark" }, "✓")) : vue.createCommentVNode("v-if", true) ], 2 /* CLASS */ ), vue.createElementVNode("text", { class: "agree-text" }, [ vue.createTextVNode("我已阅读并同意 "), vue.createElementVNode("text", { style: { "color": "#2979ff" }, onClick: _cache[13] || (_cache[13] = vue.withModifiers((...args) => _ctx.openPrivacy && _ctx.openPrivacy(...args), ["stop"])) }, "《宠宝履约者说明》") ]) ]), vue.createElementVNode("view", { class: "footer-btn-area" }, [ vue.createElementVNode("button", { class: "submit-btn", onClick: _cache[14] || (_cache[14] = (...args) => _ctx.goToAuth && _ctx.goToAuth(...args)) }, "下一步,实名认证") ]) ]), vue.createElementVNode( "view", { class: vue.normalizeClass(["picker-mask", { show: _ctx.showPicker }]), onClick: _cache[19] || (_cache[19] = (...args) => _ctx.closePicker && _ctx.closePicker(...args)) }, [ vue.createElementVNode("view", { class: "picker-content", onClick: _cache[18] || (_cache[18] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("view", { class: "picker-header" }, [ vue.createElementVNode("text", { class: "picker-btn-cancel", onClick: _cache[15] || (_cache[15] = (...args) => _ctx.closePicker && _ctx.closePicker(...args)) }, "取消"), vue.createElementVNode("text", { class: "picker-title" }, "选择出生日期"), vue.createElementVNode("text", { class: "picker-btn-confirm", onClick: _cache[16] || (_cache[16] = (...args) => _ctx.confirmPicker && _ctx.confirmPicker(...args)) }, "确定") ]), vue.createElementVNode("picker-view", { class: "picker-view", "indicator-style": "height: 50px;", value: _ctx.pickerValue, onChange: _cache[17] || (_cache[17] = (...args) => _ctx.onPickerChange && _ctx.onPickerChange(...args)) }, [ vue.createElementVNode("picker-view-column", null, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.years, (item, index) => { return vue.openBlock(), vue.createElementBlock( "view", { class: "picker-item", key: index }, vue.toDisplayString(item) + "年", 1 /* TEXT */ ); }), 128 /* KEYED_FRAGMENT */ )) ]), vue.createElementVNode("picker-view-column", null, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.months, (item, index) => { return vue.openBlock(), vue.createElementBlock( "view", { class: "picker-item", key: index }, vue.toDisplayString(item) + "月", 1 /* TEXT */ ); }), 128 /* KEYED_FRAGMENT */ )) ]), vue.createElementVNode("picker-view-column", null, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.days, (item, index) => { return vue.openBlock(), vue.createElementBlock( "view", { class: "picker-item", key: index }, vue.toDisplayString(item) + "日", 1 /* TEXT */ ); }), 128 /* KEYED_FRAGMENT */ )) ]) ], 40, ["value"]) ]) ], 2 /* CLASS */ ), vue.createVNode(_component_agreement, { visible: _ctx.showPrivacy, title: _ctx.agreementTitle, content: _ctx.agreementContent, onClose: _cache[20] || (_cache[20] = ($event) => _ctx.showPrivacy = false) }, null, 8, ["visible", "title", "content"]) ]); } const PagesRecruitForm = /* @__PURE__ */ _export_sfc(_sfc_main$B, [["render", _sfc_render$A], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/recruit/form.vue"]]); function submitAudit(data) { return request({ url: "/fulfiller/app/audit/submit", method: "POST", needToken: false, data }); } function getServiceTypes() { return request({ url: "/fulfiller/app/service/list", method: "GET", needToken: false }); } function uploadFile(filePath) { return new Promise((resolve, reject) => { const token = uni.getStorageSync("fulfiller_token"); uni.uploadFile({ url: BASE_URL + "/fulfiller/app/upload", filePath, name: "file", timeout: 6e5, header: { "clientid": CLIENT_ID, "X-Platform-Code": PLATFORM_CODE, "Authorization": token ? `Bearer ${token}` : "" }, success: (res) => { try { const data = JSON.parse(res.data); if (data.code === 200) { resolve(data); } else { uni.showToast({ title: data.msg || "上传失败", icon: "none" }); reject(data); } } catch (e) { reject(e); } }, fail: (err) => { uni.showToast({ title: "上传失败", icon: "none" }); reject(err); } }); }); } const logic$6 = { data() { return { formData: { idType: "居民身份证", name: "", idNumber: "", expiryDate: "" }, idCardFront: "", // 身份证正面本地预览路径 idCardBack: "", // 身份证反面本地预览路径 idCardFrontOssId: "", // 身份证正面 OSS ID idCardBackOssId: "", // 身份证反面 OSS ID showPicker: false, pickerValue: [0, 0, 0], // YYYY-MM-DD years: [], months: [], days: [], tempYear: 0, tempMonth: 0, tempDay: 0, serviceType: [], // 接收上一页的服务类型 isChoosingImage: false // 标志位:是否正在选择图片中,防止 onShow 重置数据 }; }, onLoad(options) { if (options.services) { try { this.serviceType = JSON.parse(decodeURIComponent(options.services)); } catch (e) { formatAppLog("error", "at pages/recruit/auth_logic.js:33", "Parse services failed", e); } } this.initDateData(); this.restoreAuthData(); }, onShow() { if (this.isChoosingImage) { this.isChoosingImage = false; } }, methods: { // --- 日期选择器逻辑 --- initDateData() { const date = /* @__PURE__ */ new Date(); const year = date.getFullYear(); for (let i = year; i <= year + 50; i++) { this.years.push(i); } for (let i = 1; i <= 12; i++) { this.months.push(i); } for (let i = 1; i <= 31; i++) { this.days.push(i); } }, openPicker() { const date = /* @__PURE__ */ new Date(); const dateStr = this.formData.expiryDate || `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`; const [y, m, d] = dateStr.split("-").map(Number); let yIndex = this.years.indexOf(y); let mIndex = this.months.indexOf(m); let dIndex = this.days.indexOf(d); this.pickerValue = [ yIndex > -1 ? yIndex : 0, mIndex > -1 ? mIndex : 0, dIndex > -1 ? dIndex : 0 ]; this.tempYear = this.years[this.pickerValue[0]]; this.tempMonth = this.months[this.pickerValue[1]]; this.tempDay = this.days[this.pickerValue[2]]; this.showPicker = true; }, closePicker() { this.showPicker = false; }, onPickerChange(e) { const val = e.detail.value; this.tempYear = this.years[val[0]]; this.tempMonth = this.months[val[1]]; this.tempDay = this.days[val[2]]; }, confirmPicker() { const mStr = this.tempMonth < 10 ? "0" + this.tempMonth : this.tempMonth; const dStr = this.tempDay < 10 ? "0" + this.tempDay : this.tempDay; this.formData.expiryDate = `${this.tempYear}-${mStr}-${dStr}`; this.closePicker(); }, // --- 数据持久化(防止返回上一级丢失) --- restoreAuthData() { try { const saved = uni.getStorageSync("recruit_auth_data"); if (saved) { const d = JSON.parse(saved); this.formData.name = d.name || ""; this.formData.idNumber = d.idNumber || ""; this.formData.expiryDate = d.expiryDate || ""; this.idCardFront = d.idCardFront || ""; this.idCardBack = d.idCardBack || ""; this.idCardFrontOssId = d.idCardFrontOssId || ""; this.idCardBackOssId = d.idCardBackOssId || ""; } } catch (e) { formatAppLog("error", "at pages/recruit/auth_logic.js:113", "恢复认证数据失败", e); } }, saveAuthData() { try { uni.setStorageSync("recruit_auth_data", JSON.stringify({ name: this.formData.name, idNumber: this.formData.idNumber, expiryDate: this.formData.expiryDate, idCardFront: this.idCardFront, idCardBack: this.idCardBack, idCardFrontOssId: this.idCardFrontOssId, idCardBackOssId: this.idCardBackOssId })); } catch (e) { formatAppLog("error", "at pages/recruit/auth_logic.js:128", "保存认证数据失败", e); } }, // --- 重置表单数据 --- resetFormData() { this.formData.name = ""; this.formData.idNumber = ""; this.formData.expiryDate = ""; this.idCardFront = ""; this.idCardBack = ""; this.idCardFrontOssId = ""; this.idCardBackOssId = ""; try { uni.removeStorageSync("recruit_auth_data"); } catch (e) { formatAppLog("error", "at pages/recruit/auth_logic.js:145", "清除缓存失败", e); } }, // --- 图片上传(选择后自动上传到OSS) --- chooseImage(side) { this.isChoosingImage = true; uni.chooseImage({ count: 1, sizeType: ["compressed"], sourceType: ["album", "camera"], success: async (res) => { const tempPath = res.tempFilePaths[0]; if (side === "front") { this.idCardFront = tempPath; } else { this.idCardBack = tempPath; } try { uni.showLoading({ title: "上传中..." }); const uploadRes = await uploadFile(tempPath); if (side === "front") { this.idCardFrontOssId = uploadRes.data.ossId; } else { this.idCardBackOssId = uploadRes.data.ossId; } uni.hideLoading(); this.saveAuthData(); } catch (err) { uni.hideLoading(); formatAppLog("error", "at pages/recruit/auth_logic.js:176", "上传身份证图片失败:", err); } } }); }, // --- 提交 --- goToQualifications() { this.saveAuthData(); try { const stored = uni.getStorageSync("recruit_form_data"); if (stored) { const data = JSON.parse(stored); data.realName = this.formData.name; data.idNumber = this.formData.idNumber; data.expiryDate = this.formData.expiryDate; data.idCardFrontOssId = this.idCardFrontOssId; data.idCardBackOssId = this.idCardBackOssId; uni.setStorageSync("recruit_form_data", JSON.stringify(data)); } } catch (e) { formatAppLog("error", "at pages/recruit/auth_logic.js:213", "保存认证数据失败", e); } const services = JSON.stringify(this.serviceType); uni.navigateTo({ url: `/pages/recruit/qualifications?services=${encodeURIComponent(services)}` }); } } }; const _sfc_main$A = logic$6; function _sfc_render$z(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "auth-container" }, [ vue.createElementVNode("view", { class: "top-tip" }, "请确保身份信息的准确,以免影响后续履约费用结算。"), vue.createElementVNode("view", { class: "form-card" }, [ vue.createElementVNode("view", { class: "form-item" }, [ vue.createElementVNode("text", { class: "label" }, "证件类型"), vue.createElementVNode("view", { class: "read-only-text" }, "居民身份证") ]), vue.createElementVNode("view", { class: "form-item" }, [ vue.createElementVNode("text", { class: "label" }, "真实姓名"), vue.createElementVNode("view", { class: "gray-input-box" }, [ vue.withDirectives(vue.createElementVNode( "input", { class: "input-area", type: "text", "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.formData.name = $event), placeholder: "证件姓名", "placeholder-class": "input-placeholder" }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, _ctx.formData.name] ]) ]) ]), vue.createElementVNode("view", { class: "form-item" }, [ vue.createElementVNode("text", { class: "label" }, "证件号码"), vue.createElementVNode("view", { class: "gray-input-box" }, [ vue.withDirectives(vue.createElementVNode( "input", { class: "input-area", type: "idcard", "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => _ctx.formData.idNumber = $event), placeholder: "身份证号", "placeholder-class": "input-placeholder" }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, _ctx.formData.idNumber] ]) ]) ]), vue.createElementVNode("view", { class: "form-item" }, [ vue.createElementVNode("text", { class: "label" }, "有效日期"), vue.createElementVNode("view", { class: "gray-input-box", onClick: _cache[2] || (_cache[2] = (...args) => _ctx.openPicker && _ctx.openPicker(...args)) }, [ vue.createElementVNode( "text", { class: vue.normalizeClass(["input-area", { "input-placeholder": !_ctx.formData.expiryDate }]) }, vue.toDisplayString(_ctx.formData.expiryDate || "选择有效结束期限"), 3 /* TEXT, CLASS */ ), (vue.openBlock(), vue.createElementBlock("svg", { class: "arrow-right", viewBox: "0 0 1024 1024", version: "1.1", xmlns: "http://www.w3.org/2000/svg" }, [ vue.createElementVNode("path", { d: "M340.864 149.312a30.592 30.592 0 0 0 0 42.752L652.736 512 340.864 831.872a30.592 30.592 0 0 0 0 42.752 29.12 29.12 0 0 0 41.728 0L714.24 534.336a32 32 0 0 0 0-45.056L382.592 149.312a29.12 29.12 0 0 0-41.728 0z", fill: "#CCCCCC" }) ])) ]) ]) ]), vue.createElementVNode("view", { class: "upload-card" }, [ vue.createElementVNode("view", { class: "upload-box", onClick: _cache[3] || (_cache[3] = ($event) => _ctx.chooseImage("front")) }, [ _ctx.idCardFront ? (vue.openBlock(), vue.createElementBlock("image", { key: 0, src: _ctx.idCardFront, class: "preview-img", mode: "aspectFill" }, null, 8, ["src"])) : (vue.openBlock(), vue.createElementBlock( vue.Fragment, { key: 1 }, [ (vue.openBlock(), vue.createElementBlock("svg", { class: "camera-icon", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, [ vue.createElementVNode("path", { d: "M12 12C14.7614 12 17 9.76142 17 7C17 4.23858 14.7614 2 12 2C9.23858 2 7 4.23858 7 7C7 9.76142 9.23858 12 12 12Z", fill: "#E0E0E0" }), vue.createElementVNode("circle", { cx: "12", cy: "12", r: "3", stroke: "#CCCCCC", "stroke-width": "2" }), vue.createElementVNode("path", { d: "M20 6H17.82L16.4 4.47C15.96 4 15.34 3.73 14.68 3.73H9.32C8.66 3.73 8.04 4 7.6 4.47L6.18 6H4C2.9 6 2 6.9 2 8V18C2 19.1 2.9 20 4 20H20C21.1 20 22 19.1 22 18V8C22 6.9 21.1 6 20 6ZM12 17C9.24 17 7 14.76 7 12C7 9.24 9.24 7 12 7C14.76 7 17 9.24 17 12C17 14.76 14.76 17 12 17Z", fill: "#CCCCCC" }) ])), vue.createElementVNode("text", { class: "upload-text" }, "点击上传") ], 64 /* STABLE_FRAGMENT */ )) ]), vue.createElementVNode("text", { class: "card-label" }, "证件带照片面") ]), vue.createElementVNode("view", { class: "upload-card" }, [ vue.createElementVNode("view", { class: "upload-box", onClick: _cache[4] || (_cache[4] = ($event) => _ctx.chooseImage("back")) }, [ _ctx.idCardBack ? (vue.openBlock(), vue.createElementBlock("image", { key: 0, src: _ctx.idCardBack, class: "preview-img", mode: "aspectFill" }, null, 8, ["src"])) : (vue.openBlock(), vue.createElementBlock( vue.Fragment, { key: 1 }, [ (vue.openBlock(), vue.createElementBlock("svg", { class: "camera-icon", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, [ vue.createElementVNode("path", { d: "M20 6H17.82L16.4 4.47C15.96 4 15.34 3.73 14.68 3.73H9.32C8.66 3.73 8.04 4 7.6 4.47L6.18 6H4C2.9 6 2 6.9 2 8V18C2 19.1 2.9 20 4 20H20C21.1 20 22 19.1 22 18V8C22 6.9 21.1 6 20 6ZM12 17C9.24 17 7 14.76 7 12C7 9.24 9.24 7 12 7C14.76 7 17 9.24 17 12C17 14.76 14.76 17 12 17Z", fill: "#CCCCCC" }) ])), vue.createElementVNode("text", { class: "upload-text" }, "点击上传") ], 64 /* STABLE_FRAGMENT */ )) ]), vue.createElementVNode("text", { class: "card-label" }, "证件国徽面") ]), vue.createElementVNode("view", { class: "footer-btn-area" }, [ vue.createElementVNode("button", { class: "next-btn", onClick: _cache[5] || (_cache[5] = (...args) => _ctx.goToQualifications && _ctx.goToQualifications(...args)) }, "下一步,完善资质") ]), vue.createElementVNode( "view", { class: vue.normalizeClass(["picker-mask", { show: _ctx.showPicker }]), onClick: _cache[10] || (_cache[10] = (...args) => _ctx.closePicker && _ctx.closePicker(...args)) }, [ vue.createElementVNode("view", { class: "picker-content", onClick: _cache[9] || (_cache[9] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("view", { class: "picker-header" }, [ vue.createElementVNode("text", { class: "picker-btn-cancel", onClick: _cache[6] || (_cache[6] = (...args) => _ctx.closePicker && _ctx.closePicker(...args)) }, "取消"), vue.createElementVNode("text", { class: "picker-title" }, "选择有效结束期限"), vue.createElementVNode("text", { class: "picker-btn-confirm", onClick: _cache[7] || (_cache[7] = (...args) => _ctx.confirmPicker && _ctx.confirmPicker(...args)) }, "确定") ]), vue.createElementVNode("picker-view", { class: "picker-view", "indicator-style": "height: 50px;", value: _ctx.pickerValue, onChange: _cache[8] || (_cache[8] = (...args) => _ctx.onPickerChange && _ctx.onPickerChange(...args)) }, [ vue.createElementVNode("picker-view-column", null, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.years, (item, index) => { return vue.openBlock(), vue.createElementBlock( "view", { class: "picker-item", key: index }, vue.toDisplayString(item) + "年", 1 /* TEXT */ ); }), 128 /* KEYED_FRAGMENT */ )) ]), vue.createElementVNode("picker-view-column", null, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.months, (item, index) => { return vue.openBlock(), vue.createElementBlock( "view", { class: "picker-item", key: index }, vue.toDisplayString(item) + "月", 1 /* TEXT */ ); }), 128 /* KEYED_FRAGMENT */ )) ]), vue.createElementVNode("picker-view-column", null, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.days, (item, index) => { return vue.openBlock(), vue.createElementBlock( "view", { class: "picker-item", key: index }, vue.toDisplayString(item) + "日", 1 /* TEXT */ ); }), 128 /* KEYED_FRAGMENT */ )) ]) ], 40, ["value"]) ]) ], 2 /* CLASS */ ) ]); } const PagesRecruitAuth = /* @__PURE__ */ _export_sfc(_sfc_main$A, [["render", _sfc_render$z], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/recruit/auth.vue"]]); const logic$5 = { data() { return { serviceTypes: [], // 从上一页传递过来的服务类型列表 qualifications: {}, // 存储本地预览路径 { '宠物接送': ['path1', ...], ... } qualOssIds: {} // 存储OSS ID { '宠物接送': ['id1', ...], ... } }; }, onLoad(options) { if (options.services) { try { this.serviceTypes = JSON.parse(decodeURIComponent(options.services)); this.serviceTypes.forEach((item) => { this.qualifications[item.name] = this.qualifications[item.name] || []; this.qualOssIds[item.name] = this.qualOssIds[item.name] || []; }); } catch (e) { formatAppLog("error", "at pages/recruit/qualifications_logic.js:21", "Parse services failed", e); } } this.restoreQualData(); }, methods: { saveQualData() { try { uni.setStorageSync("recruit_qual_data", JSON.stringify({ qualifications: this.qualifications, qualOssIds: this.qualOssIds })); } catch (e) { formatAppLog("error", "at pages/recruit/qualifications_logic.js:35", "保存资质数据失败", e); } }, restoreQualData() { try { const saved = uni.getStorageSync("recruit_qual_data"); if (saved) { const d = JSON.parse(saved); this.qualifications = d.qualifications || {}; this.qualOssIds = d.qualOssIds || {}; this.$forceUpdate(); } } catch (e) { formatAppLog("error", "at pages/recruit/qualifications_logic.js:48", "恢复资质数据失败", e); } }, chooseImage(serviceName) { uni.chooseImage({ count: 9, sizeType: ["compressed"], sourceType: ["album", "camera"], success: async (res) => { if (!this.qualifications[serviceName]) { this.qualifications[serviceName] = []; this.qualOssIds[serviceName] = []; } for (const tempPath of res.tempFilePaths) { this.qualifications[serviceName].push(tempPath); this.$forceUpdate(); try { const uploadRes = await uploadFile(tempPath); this.qualOssIds[serviceName].push(uploadRes.data.ossId); this.saveQualData(); } catch (err) { formatAppLog("error", "at pages/recruit/qualifications_logic.js:70", "上传资质图片失败:", err); } } } }); }, deleteImage(serviceName, index) { this.qualifications[serviceName].splice(index, 1); if (this.qualOssIds[serviceName]) { this.qualOssIds[serviceName].splice(index, 1); } this.saveQualData(); this.$forceUpdate(); }, goBackToForm() { const pages = getCurrentPages(); if (pages.length > 2) { uni.navigateBack({ delta: 2 }); } else { uni.reLaunch({ url: "/pages/recruit/form" }); } }, async submit() { let recruitData = {}; try { const stored = uni.getStorageSync("recruit_form_data"); if (stored) { recruitData = JSON.parse(stored); } } catch (e) { formatAppLog("error", "at pages/recruit/qualifications_logic.js:107", "读取招募表单数据失败", e); } const allQualOssIds = []; Object.values(this.qualOssIds).forEach((ids) => { allQualOssIds.push(...ids); }); const auditData = { name: recruitData.name || "", phone: recruitData.mobile || "", password: recruitData.password || "", gender: recruitData.gender === 1 ? "0" : "1", birthday: recruitData.birthday || "", serviceTypes: (recruitData.serviceType || []).join(","), // 逗号分隔的服务类型ID city: recruitData.areaPath || "", stationId: recruitData.stationId || null, realName: recruitData.realName || "", idCard: recruitData.idNumber || "", idValidDate: recruitData.expiryDate || "", idCardFront: recruitData.idCardFrontOssId || null, idCardBack: recruitData.idCardBackOssId || null, qualifications: allQualOssIds.join(",") // 逗号分隔的资质图片OSS ID }; uni.showLoading({ title: "提交中..." }); try { await submitAudit(auditData); uni.hideLoading(); const s = encodeURIComponent(recruitData.station || ""); const n = encodeURIComponent(recruitData.name || ""); const p = recruitData.mobile || ""; uni.removeStorageSync("recruit_form_data"); uni.removeStorageSync("recruit_auth_data"); uni.removeStorageSync("recruit_qual_data"); uni.reLaunch({ url: `/pages/recruit/success?station=${s}&name=${n}&phone=${p}` }); } catch (err) { uni.hideLoading(); formatAppLog("error", "at pages/recruit/qualifications_logic.js:153", "提交申请失败:", err); } } } }; const _sfc_main$z = logic$5; function _sfc_render$y(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "qual-container" }, [ vue.createElementVNode("view", { class: "top-tip" }, "根据国家政策要求,请尽快完成实名认证与健康认证,否则无法开展配送业务。我们承诺将严格保管好您的个人信息。"), _ctx.serviceTypes.length === 0 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "empty-state" }, [ vue.createElementVNode("text", { class: "empty-tip" }, "请返回第一步选择服务类型"), vue.createElementVNode("button", { class: "back-btn", onClick: _cache[0] || (_cache[0] = (...args) => _ctx.goBackToForm && _ctx.goBackToForm(...args)) }, "返回选择") ])) : vue.createCommentVNode("v-if", true), (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.serviceTypes, (item, index) => { return vue.openBlock(), vue.createElementBlock("view", { class: "qual-card", key: item.id }, [ vue.createElementVNode( "view", { class: "card-title" }, vue.toDisplayString(item.name) + "服务资质", 1 /* TEXT */ ), vue.createElementVNode("view", { class: "upload-wrapper" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.qualifications[item.name], (img, imgIndex) => { return vue.openBlock(), vue.createElementBlock("view", { class: "img-item", key: imgIndex }, [ vue.createElementVNode("image", { src: img, class: "preview-img", mode: "aspectFill", onClick: ($event) => _ctx.previewImage(item.name, imgIndex) }, null, 8, ["src", "onClick"]), vue.createElementVNode("view", { class: "delete-btn", onClick: vue.withModifiers(($event) => _ctx.deleteImage(item.name, imgIndex), ["stop"]) }, "×", 8, ["onClick"]) ]); }), 128 /* KEYED_FRAGMENT */ )), vue.createElementVNode("view", { class: "upload-box", onClick: ($event) => _ctx.chooseImage(item.name) }, [ vue.createElementVNode("text", { class: "plus-icon" }, "+"), vue.createElementVNode("text", { class: "upload-text" }, "上传") ], 8, ["onClick"]) ]) ]); }), 128 /* KEYED_FRAGMENT */ )), vue.createElementVNode("view", { class: "footer-actions" }, [ vue.createElementVNode("button", { class: "submit-btn", onClick: _cache[1] || (_cache[1] = (...args) => _ctx.submit && _ctx.submit(...args)) }, "立即提交") ]) ]); } const PagesRecruitQualifications = /* @__PURE__ */ _export_sfc(_sfc_main$z, [["render", _sfc_render$y], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/recruit/qualifications.vue"]]); const logic$4 = { data() { return { station: "", name: "", phone: "" }; }, onLoad(options) { if (options.station) { this.station = decodeURIComponent(options.station); } if (options.name) { this.name = decodeURIComponent(options.name); } if (options.phone) { this.phone = options.phone; } }, methods: { goHome() { uni.reLaunch({ url: "/pages/login/login" }); } } }; const _sfc_main$y = logic$4; function _sfc_render$x(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "success-container" }, [ vue.createElementVNode("view", { class: "icon-area" }, [ (vue.openBlock(), vue.createElementBlock("svg", { class: "success-icon", viewBox: "0 0 1024 1024", version: "1.1", xmlns: "http://www.w3.org/2000/svg" }, [ vue.createElementVNode("path", { d: "M512 0C229.23 0 0 229.23 0 512s229.23 512 512 512 512-229.23 512-512S794.77 0 512 0z m0 960C264.58 960 64 759.42 64 512S264.58 64 512 64s448 200.58 448 448-200.58 448-448 448z", fill: "#64D01D" }), vue.createElementVNode("path", { d: "M743.08 335.78c-12.23-12.24-32.07-12.24-44.3 0L426.6 607.96 325.22 506.58c-12.24-12.24-32.07-12.24-44.3 0-12.24 12.24-12.24 32.07 0 44.3l124.58 124.58c6.12 6.12 14.14 9.17 22.15 9.17s16.03-3.05 22.15-9.17L743.08 380.08c12.24-12.24 12.24-32.07 0-44.3z", fill: "#64D01D" }) ])), vue.createElementVNode("text", { class: "main-title" }, "提交成功") ]), vue.createElementVNode("text", { class: "sub-tip" }, "请保持手机畅通,等待平台工作人员与您联系"), vue.createElementVNode("view", { class: "info-card" }, [ vue.createElementVNode("view", { class: "info-item" }, [ vue.createElementVNode("text", { class: "label" }, "服务站点:"), vue.createElementVNode( "text", { class: "value" }, vue.toDisplayString(_ctx.station), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "info-item" }, [ vue.createElementVNode("text", { class: "label" }, "报 名 人 :"), vue.createElementVNode( "text", { class: "value" }, vue.toDisplayString(_ctx.name), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "info-item" }, [ vue.createElementVNode("text", { class: "label" }, "联系手机:"), vue.createElementVNode( "text", { class: "value" }, vue.toDisplayString(_ctx.phone), 1 /* TEXT */ ) ]) ]), vue.createElementVNode("view", { class: "footer-btn", onClick: _cache[0] || (_cache[0] = (...args) => _ctx.goHome && _ctx.goHome(...args)) }, "我知道了") ]); } const PagesRecruitSuccess = /* @__PURE__ */ _export_sfc(_sfc_main$y, [["render", _sfc_render$x], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/recruit/success.vue"]]); const _sfc_main$x = { data() { return { mobile: "", code: "", countDown: 0, timer: null }; }, computed: { mobileMask() { if (!this.mobile) return ""; return this.mobile.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2"); } }, onLoad(options) { if (options.mobile) { this.mobile = options.mobile; } else { this.mobile = "13412346783"; } }, methods: { getVerifyCode() { if (this.countDown > 0) return; this.countDown = 60; this.timer = setInterval(() => { this.countDown--; if (this.countDown <= 0) { clearInterval(this.timer); } }, 1e3); uni.showToast({ title: "验证码已发送", icon: "none" }); }, nextStep() { if (!this.code) { uni.showToast({ title: "请输入验证码", icon: "none" }); return; } uni.navigateTo({ url: "/pages/login/reset-pwd-set" }); } } }; function _sfc_render$w(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "reset-container" }, [ vue.createElementVNode("view", { class: "content" }, [ vue.createElementVNode( "view", { class: "tip-text" }, "请输入 +86 " + vue.toDisplayString($options.mobileMask) + " 收到的短信验证码,进行验证~", 1 /* TEXT */ ), vue.createElementVNode("view", { class: "input-group" }, [ vue.createElementVNode("text", { class: "label" }, "验证码"), vue.createElementVNode("view", { class: "input-wrapper" }, [ vue.withDirectives(vue.createElementVNode( "input", { class: "code-input", type: "number", maxlength: "6", "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $data.code = $event) }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, $data.code] ]), vue.createElementVNode("view", { class: "get-code-btn", onClick: _cache[1] || (_cache[1] = (...args) => $options.getVerifyCode && $options.getVerifyCode(...args)) }, [ vue.createElementVNode( "text", { class: "btn-text" }, vue.toDisplayString($data.countDown > 0 ? `${$data.countDown}s` : "获取验证码"), 1 /* TEXT */ ) ]) ]) ]), vue.createElementVNode("button", { class: "next-btn", onClick: _cache[2] || (_cache[2] = (...args) => $options.nextStep && $options.nextStep(...args)) }, "下一步") ]) ]); } const PagesLoginResetPwdVerify = /* @__PURE__ */ _export_sfc(_sfc_main$x, [["render", _sfc_render$w], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/login/reset-pwd-verify.vue"]]); const _sfc_main$w = { data() { return { pwd1: "", pwd2: "" }; }, methods: { confirmReset() { if (!this.pwd1 || !this.pwd2) { uni.showToast({ title: "请输入密码", icon: "none" }); return; } if (this.pwd1 !== this.pwd2) { uni.showToast({ title: "两次密码不一致", icon: "none" }); return; } uni.showToast({ title: "重置成功", icon: "success" }); setTimeout(() => { uni.navigateBack({ delta: 2 // 返回到登录页 }); }, 1500); } } }; function _sfc_render$v(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "reset-container" }, [ vue.createElementVNode("view", { class: "content" }, [ vue.createElementVNode("view", { class: "tip-text" }, "请输入新密码,并重新登录验证"), vue.createElementVNode("view", { class: "input-form" }, [ vue.createElementVNode("view", { class: "input-row" }, [ vue.withDirectives(vue.createElementVNode( "input", { class: "pwd-input", type: "text", password: "", placeholder: "限12-20位字母和数字组合", "placeholder-style": "color:#ccc", "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => $data.pwd1 = $event) }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, $data.pwd1] ]) ]), vue.createElementVNode("view", { class: "divider" }), vue.createElementVNode("view", { class: "input-row" }, [ vue.withDirectives(vue.createElementVNode( "input", { class: "pwd-input", type: "text", password: "", placeholder: "限12-20位字母和数字组合", "placeholder-style": "color:#ccc", "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => $data.pwd2 = $event) }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, $data.pwd2] ]) ]), vue.createElementVNode("view", { class: "divider" }) ]), vue.createElementVNode("button", { class: "confirm-btn", onClick: _cache[2] || (_cache[2] = (...args) => $options.confirmReset && $options.confirmReset(...args)) }, "确定") ]) ]); } const PagesLoginResetPwdSet = /* @__PURE__ */ _export_sfc(_sfc_main$w, [["render", _sfc_render$v], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/login/reset-pwd-set.vue"]]); function cancelOrderApi(data) { return request({ url: "/order/subOrder/cancel", method: "PUT", data }); } function rejectOrderApi(data) { return request({ url: "/order/subOrder/reject", method: "PUT", data }); } function getPendingOrders(params) { return request({ url: "/order/subOrder/listPendingAccept", method: "GET", data: params }); } function acceptOrder(orderId) { return request({ url: "/order/subOrder/accept", method: "PUT", data: { orderId } }); } function getOrderCount() { return request({ url: "/order/subOrder/count", method: "GET" }); } function getStatisticOrders(params) { return request({ url: "/order/subOrder/listOnStatistic", method: "GET", data: params }); } function getMyOrders(params) { return request({ url: "/order/subOrder/listOnMyOrder", method: "GET", data: params }); } function getOrderInfo(id) { return request({ url: `/order/subOrder/getInfo?id=${id}`, method: "GET" }); } function clockIn(data) { return request({ url: "/order/subOrder/clockIn", method: "PUT", data }); } function submitNursingSummary(data) { return request({ url: "/order/subOrder/nursingSummary", method: "PUT", data }); } const _sfc_main$v = { __name: "index", props: { currentPath: { type: String, required: true } }, setup(__props, { expose: __expose }) { __expose(); const props = __props; const list = vue.ref([ { pagePath: "pages/home/index", text: "任务中心", iconPath: "/static/tabbar/home.svg", selectedIconPath: "/static/tabbar/home-active.svg" }, { pagePath: "pages/orders/index", text: "我的订单", iconPath: "/static/tabbar/order.svg", selectedIconPath: "/static/tabbar/order-active.svg" }, { pagePath: "pages/mine/index", text: "我的", iconPath: "/static/tabbar/mine.svg", selectedIconPath: "/static/tabbar/mine-active.svg" } ]); const switchTab = (path) => { if (props.currentPath === path) return; uni.switchTab({ url: "/" + path }); }; const __returned__ = { props, list, switchTab, ref: vue.ref }; Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true }); return __returned__; } }; function _sfc_render$u(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "custom-tabbar" }, [ vue.createElementVNode("view", { class: "tabbar-border" }), vue.createElementVNode("view", { class: "tabbar-list" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($setup.list, (item, index) => { return vue.openBlock(), vue.createElementBlock("view", { class: "tabbar-item", key: index, onClick: ($event) => $setup.switchTab(item.pagePath) }, [ vue.createElementVNode("image", { class: "tabbar-icon", src: $props.currentPath === item.pagePath ? item.selectedIconPath : item.iconPath }, null, 8, ["src"]), vue.createElementVNode( "view", { class: vue.normalizeClass(["tabbar-text", { "tabbar-text-active": $props.currentPath === item.pagePath }]) }, vue.toDisplayString(item.text), 3 /* TEXT, CLASS */ ) ], 8, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )) ]) ]); } const customTabbar = /* @__PURE__ */ _export_sfc(_sfc_main$v, [["render", _sfc_render$u], ["__scopeId", "data-v-52454e90"], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/components/custom-tabbar/index.vue"]]); const logic$3 = { components: { customTabbar }, data() { return { taskList: [], currentFilter: "default", // default, distance, time filterCondition: "筛选条件", sortDistance: "asc", // asc, desc sortTime: "asc", scrollTop: 0, // Track scroll position isFilterShow: false, tempFilter: { service: null, distance: "全部", amount: "全部" }, activeFilter: { service: null, distance: "全部", amount: "全部" }, workStatus: "resting", // resting | busy | disabled showConfirmModal: false, showPetModal: false, currentPetInfo: {}, showRejectModal: false, rejectReason: "", currentOrder: null, showAcceptConfirmModal: false, showNavModal: false, navTargetItem: null, navTargetPointType: "", profile: null, profileLoading: false, serviceList: [], orderStats: { total: 0, reject: 0, completed: 0, price: 0 } }; }, onPageScroll(e) { this.scrollTop = e.scrollTop; }, async onLoad() { this.checkWorkStatus(); await this.loadServiceList(); this.loadTaskList(); reportGps(true).catch((e) => formatAppLog("log", "at pages/home/logic.js:64", "Init GPS check skipped", e)); }, onShow() { uni.hideTabBar(); this.checkWorkStatus(); if (isLoggedIn()) { this.loadProfile(); this.loadOrderStats(); this.loadTaskList(); this.loadServiceList(); } }, async onPullDownRefresh() { this.checkWorkStatus(); try { await this.loadServiceList(); const tasks = [ this.loadTaskList() ]; if (isLoggedIn()) { tasks.push(this.loadProfile()); tasks.push(this.loadOrderStats()); } await Promise.all(tasks); } catch (err) { formatAppLog("error", "at pages/home/logic.js:94", "刷新异常:", err); } finally { uni.stopPullDownRefresh(); uni.showToast({ title: "刷新成功", icon: "success" }); } }, methods: { async loadProfile() { if (this.profileLoading) return; this.profileLoading = true; try { const res = await getMyProfile(); const data = res.data || null; if (data) { if (data.status) { this.workStatus = data.status; uni.setStorageSync("workStatus", data.status); } if (data.stationId) { try { const stationRes = await getAreaStationList(); const list = stationRes.data || []; const currentStation = list.find((i) => i.id === data.stationId); if (currentStation) { let node = currentStation; while (node && node.parentId !== 0) { let parent = list.find((i) => i.id === node.parentId); if (parent) { node = parent; } else { break; } } data.cityName = node.name; } } catch (e) { formatAppLog("error", "at pages/home/logic.js:136", "溯源城市失败:", e); } } } this.profile = data; } catch (err) { formatAppLog("error", "at pages/home/logic.js:143", "获取个人信息失败:", err); } finally { this.profileLoading = false; } }, async loadServiceList() { try { const res = await listAllService(); this.serviceList = res.data || []; } catch (err) { formatAppLog("error", "at pages/home/logic.js:153", "获取服务类型失败:", err); } }, async loadOrderStats() { try { const res = await getOrderCount(); this.orderStats = res.data || { total: 0, reject: 0, completed: 0, price: 0 }; } catch (err) { formatAppLog("error", "at pages/home/logic.js:161", "获取订单统计失败:", err); } }, checkWorkStatus() { const status = uni.getStorageSync("workStatus"); if (status) { this.workStatus = status; } else { this.workStatus = "resting"; uni.setStorageSync("workStatus", "resting"); } }, toggleFilter() { if (this.workStatus === "resting") return; this.isFilterShow = !this.isFilterShow; }, goToWorkStatus() { uni.navigateTo({ url: "/pages/home/work-status" }); }, async handleManualLocation() { try { uni.showLoading({ title: "定位获取中...", mask: true }); await reportGps(true); uni.showToast({ title: "位置已更新", icon: "success" }); } catch (e) { formatAppLog("error", "at pages/home/logic.js:189", "Manual location failed", e); } finally { uni.hideLoading(); } }, startWork() { this.showConfirmModal = true; }, confirmStartWork() { this.workStatus = "busy"; uni.setStorageSync("workStatus", "busy"); this.loadTaskList(); this.showConfirmModal = false; uni.showToast({ title: "已开始接单", icon: "success" }); }, closeConfirmModal() { this.showConfirmModal = false; }, showPetProfile(item) { this.currentPetInfo = item; this.showPetModal = true; }, closePetProfile() { this.showPetModal = false; }, openRejectModal(item) { this.currentOrder = item; this.rejectReason = ""; this.showRejectModal = true; }, closeRejectModal() { this.showRejectModal = false; this.currentOrder = null; }, async confirmReject() { var _a; if (!this.rejectReason.trim()) { uni.showToast({ title: "请输入拒绝理由", icon: "none" }); return; } if (!((_a = this.currentOrder) == null ? void 0 : _a.id)) return; try { uni.showLoading({ title: "提交中...", mask: true }); await rejectOrderApi({ orderId: this.currentOrder.id, rejectReason: this.rejectReason }); uni.showToast({ title: "已拒绝接单", icon: "success" }); this.showRejectModal = false; this.currentOrder = null; this.loadTaskList(); this.loadOrderStats(); } catch (err) { formatAppLog("error", "at pages/home/logic.js:241", "拒绝接单失败:", err); uni.showToast({ title: "操作失败", icon: "none" }); } finally { uni.hideLoading(); } }, openAcceptModal(item) { this.currentOrder = item; this.showAcceptConfirmModal = true; }, closeAcceptModal() { this.showAcceptConfirmModal = false; this.currentOrder = null; }, async confirmAccept() { var _a; if (!((_a = this.currentOrder) == null ? void 0 : _a.id)) return; try { await acceptOrder(this.currentOrder.id); uni.showToast({ title: "接单成功", icon: "success" }); this.showAcceptConfirmModal = false; this.currentOrder = null; this.loadTaskList(); this.loadProfile(); this.loadOrderStats(); } catch (err) { formatAppLog("error", "at pages/home/logic.js:266", "接单失败:", err); uni.showToast({ title: "接单失败", icon: "none" }); } }, openNavigation(item, pointType) { this.navTargetItem = item; this.navTargetPointType = pointType; this.showNavModal = true; }, closeNavModal() { this.showNavModal = false; }, chooseMap(mapType) { let item = this.navTargetItem; let pointType = this.navTargetPointType; let name = pointType === "start" ? item.fromAddress || "起点" : item.toAddress || "终点"; let address = pointType === "start" ? item.fromAddress || "起点地址" : item.toAddress || "终点地址"; let latitude = pointType === "start" ? Number(item.fromLat) : Number(item.toLat); let longitude = pointType === "start" ? Number(item.fromLng) : Number(item.toLng); this.showNavModal = false; const navigateTo = (lat, lng, addrName, addrDesc) => { uni.openLocation({ latitude: lat, longitude: lng, name: addrName, address: addrDesc || "无法获取详细地址", success: function() { formatAppLog("log", "at pages/home/logic.js:297", "打开导航成功: " + mapType); }, fail: function(err) { formatAppLog("error", "at pages/home/logic.js:300", "打开导航失败:", err); uni.showToast({ title: "打开地图失败", icon: "none" }); } }); }; if (latitude && longitude && !isNaN(latitude) && !isNaN(longitude)) { navigateTo(latitude, longitude, name, address); } else { uni.showLoading({ title: "获取当前位置...", mask: true }); uni.getLocation({ type: "gcj02", success: (res) => { uni.hideLoading(); navigateTo(res.latitude, res.longitude, name, address); }, fail: (err) => { uni.hideLoading(); formatAppLog("error", "at pages/home/logic.js:321", "获取地理位置失败:", err); uni.showToast({ title: "无法获取当前位置信息", icon: "none" }); } }); } }, selectService(type) { this.tempFilter.service = type; }, selectDistance(type) { this.tempFilter.distance = type; }, selectAmount(type) { this.tempFilter.amount = type; }, resetFilter() { this.tempFilter = { service: null, distance: "全部", amount: "全部" }; }, confirmFilter() { this.activeFilter = { ...this.tempFilter }; this.isFilterShow = false; this.loadTaskList(); }, closeFilter() { this.isFilterShow = false; }, goToDetail(item) { formatAppLog("log", "at pages/home/logic.js:352", "Go to detail", item); }, async loadTaskList() { try { const params = { service: this.activeFilter.service, minPrice: this.getMinPrice(), maxPrice: this.getMaxPrice(), pageNum: 1, pageSize: 20 }; const res = await getPendingOrders(params); this.taskList = (res.rows || []).map((item) => this.transformOrder(item)); } catch (err) { formatAppLog("error", "at pages/home/logic.js:366", "获取订单列表失败:", err); uni.showToast({ title: "加载失败", icon: "none" }); this.taskList = []; } }, getMinPrice() { const amount = this.activeFilter.amount; if (amount === "100以下") return 0; if (amount === "100-200") return 1e4; if (amount === "200-500") return 2e4; if (amount === "500以上") return 5e4; return void 0; }, getMaxPrice() { const amount = this.activeFilter.amount; if (amount === "100以下") return 1e4; if (amount === "100-200") return 2e4; if (amount === "200-500") return 5e4; return void 0; }, transformOrder(item) { const service = this.serviceList.find((s) => s.id === item.service); const serviceText = (service == null ? void 0 : service.name) || "未知"; const serviceIcon = (service == null ? void 0 : service.iconUrl) || ""; const mode = (service == null ? void 0 : service.mode) || 0; const isRoundTrip = mode === 1; return { id: item.id, type: isRoundTrip ? 1 : item.service, typeText: serviceText, typeIcon: serviceIcon, price: (item.price / 100).toFixed(2), timeLabel: "服务时间", time: item.serviceTime, petAvatar: item.petAvatar || "/static/dog.png", petAvatarUrl: item.petAvatarUrl || "", petName: item.petName, petBreed: item.breed, petGender: "M", petAge: "", petWeight: "", petPersonality: "", petHobby: "", petRemark: "", petTags: [], petLogs: [], startLocation: item.fromAddress || "暂无起点", startAddress: item.fromAddress || "", fromAddress: item.fromAddress || "", fromLat: item.fromLat, fromLng: item.fromLng, startDistance: "0km", endLocation: (item.customerName || item.contact || "") + " " + (item.customerPhone || ""), endAddress: item.toAddress || "", toAddress: item.toAddress || "", toLat: item.toLat, toLng: item.toLng, endDistance: "0km", serviceContent: "", remark: item.remark || "" }; }, setFilter(type) { this.currentFilter = type; if (type === "distance") { this.sortDistance = this.sortDistance === "asc" ? "desc" : "asc"; uni.showToast({ title: `按距离${this.sortDistance === "asc" ? "升序" : "降序"}`, icon: "none" }); } else if (type === "time") { this.sortTime = this.sortTime === "asc" ? "desc" : "asc"; uni.showToast({ title: `按时间${this.sortTime === "asc" ? "升序" : "降序"}`, icon: "none" }); } }, showFilterDropdown() { this.toggleFilter(); } } }; const _imports_3$2 = "/static/icons/nav_arrow.svg"; const _sfc_main$u = { ...logic$3 }; function _sfc_render$t(_ctx, _cache, $props, $setup, $data, $options) { var _a, _b, _c; const _component_custom_tabbar = vue.resolveComponent("custom-tabbar"); return vue.openBlock(), vue.createElementBlock( vue.Fragment, null, [ vue.createElementVNode("view", { class: "container" }, [ vue.createElementVNode( "view", { class: "custom-nav-bar", style: vue.normalizeStyle({ backgroundColor: _ctx.scrollTop > 20 ? "#fff" : "transparent" }) }, [ vue.createElementVNode("text", { class: "nav-title" }, "任务中心") ], 4 /* STYLE */ ), vue.createElementVNode("view", { class: "nav-bg" }, [ vue.createElementVNode("view", { class: "bg-circle-left" }), vue.createElementVNode("view", { class: "bg-circle-right" }) ]), vue.createElementVNode("view", { class: "header-section" }, [ vue.createElementVNode("view", { class: "user-info" }, [ vue.createElementVNode("image", { class: "avatar", src: ((_a = _ctx.profile) == null ? void 0 : _a.avatarUrl) || "/static/touxiang.png", mode: "aspectFill" }, null, 8, ["src"]), vue.createElementVNode("view", { class: "info-content" }, [ vue.createElementVNode("view", { class: "top-row" }, [ vue.createElementVNode( "text", { class: "name" }, vue.toDisplayString(((_b = _ctx.profile) == null ? void 0 : _b.name) || "未登录"), 1 /* TEXT */ ), vue.createElementVNode( "view", { class: vue.normalizeClass(["status-pill", { "resting": _ctx.workStatus !== "busy" }]), onClick: _cache[0] || (_cache[0] = (...args) => _ctx.goToWorkStatus && _ctx.goToWorkStatus(...args)) }, [ vue.createElementVNode( "view", { class: vue.normalizeClass(["status-dot-bg", { "busy": _ctx.workStatus === "busy", "disabled": _ctx.workStatus === "disabled" }]) }, [ _ctx.workStatus === "busy" ? (vue.openBlock(), vue.createElementBlock("text", { key: 0, class: "check-mark" }, "✔")) : (vue.openBlock(), vue.createElementBlock("text", { key: 1, class: "check-mark", style: { "font-size": "16rpx", "line-height": "20rpx" } }, "✕")) ], 2 /* CLASS */ ), vue.createElementVNode( "text", { class: "status-text" }, vue.toDisplayString(_ctx.workStatus === "busy" ? "接单中" : _ctx.workStatus === "resting" ? "正在休息" : "已禁用"), 1 /* TEXT */ ), vue.createElementVNode("text", { class: "arrow-down" }, "▼") ], 2 /* CLASS */ ) ]), vue.createElementVNode("view", { class: "bottom-row", onClick: _cache[1] || (_cache[1] = (...args) => _ctx.handleManualLocation && _ctx.handleManualLocation(...args)) }, [ vue.createElementVNode( "text", { class: "city-label" }, "接单城市:" + vue.toDisplayString(((_c = _ctx.profile) == null ? void 0 : _c.cityName) || "暂无"), 1 /* TEXT */ ), vue.createElementVNode("text", { class: "city-arrow" }, ">") ]) ]) ]), vue.createElementVNode("view", { class: "stats-card" }, [ vue.createElementVNode("view", { class: "stat-item" }, [ vue.createElementVNode( "text", { class: "num" }, vue.toDisplayString(_ctx.orderStats.total), 1 /* TEXT */ ), vue.createElementVNode("text", { class: "label" }, "全部订单") ]), vue.createElementVNode("view", { class: "divider" }), vue.createElementVNode("view", { class: "stat-item" }, [ vue.createElementVNode( "text", { class: "num" }, vue.toDisplayString(_ctx.orderStats.reject), 1 /* TEXT */ ), vue.createElementVNode("text", { class: "label" }, "拒接订单") ]), vue.createElementVNode("view", { class: "divider" }), vue.createElementVNode("view", { class: "stat-item" }, [ vue.createElementVNode( "text", { class: "num" }, vue.toDisplayString(_ctx.orderStats.completed), 1 /* TEXT */ ), vue.createElementVNode("text", { class: "label" }, "完成订单") ]), vue.createElementVNode("view", { class: "divider" }), vue.createElementVNode("view", { class: "stat-item" }, [ vue.createElementVNode( "text", { class: "num" }, vue.toDisplayString((_ctx.orderStats.price / 100).toFixed(2)), 1 /* TEXT */ ), vue.createElementVNode("text", { class: "label" }, "服务总得") ]) ]) ]), vue.createElementVNode("view", { class: "task-header" }, [ vue.createElementVNode( "view", { class: "header-inner", style: vue.normalizeStyle({ backgroundColor: _ctx.scrollTop > 300 || _ctx.isFilterShow ? "#fff" : "transparent" }) }, [ vue.createElementVNode("view", { class: "left-title" }, [ vue.createElementVNode("view", { class: "orange-bar" }), vue.createElementVNode("text", { class: "title" }, "任务大厅"), vue.createElementVNode( "text", { class: "count" }, "- (" + vue.toDisplayString(_ctx.taskList.length) + "单)", 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "filter-options" }, [ vue.createElementVNode("view", { class: "dropdown", onClick: _cache[2] || (_cache[2] = (...args) => _ctx.showFilterDropdown && _ctx.showFilterDropdown(...args)) }, [ vue.createElementVNode("text", null, "筛选条件"), vue.createElementVNode("text", { class: "arrow-down" }, "﹀") ]) ]) ], 4 /* STYLE */ ), _ctx.isFilterShow ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "filter-mask", onClick: _cache[3] || (_cache[3] = (...args) => _ctx.closeFilter && _ctx.closeFilter(...args)) })) : vue.createCommentVNode("v-if", true), vue.createElementVNode( "view", { class: vue.normalizeClass(["filter-panel", { show: _ctx.isFilterShow }]) }, [ vue.createElementVNode("view", { class: "filter-section" }, [ vue.createElementVNode("text", { class: "section-title" }, "服务类型"), vue.createElementVNode("view", { class: "options-grid" }, [ vue.createElementVNode( "view", { class: vue.normalizeClass(["option-btn", { active: _ctx.tempFilter.service === null }]), onClick: _cache[4] || (_cache[4] = ($event) => _ctx.selectService(null)) }, "全部", 2 /* CLASS */ ), (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.serviceList, (item) => { return vue.openBlock(), vue.createElementBlock("view", { class: vue.normalizeClass(["option-btn", { active: _ctx.tempFilter.service === item.id }]), key: item.id, onClick: ($event) => _ctx.selectService(item.id) }, vue.toDisplayString(item.name), 11, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )) ]) ]), vue.createElementVNode("view", { class: "filter-section" }, [ vue.createElementVNode("text", { class: "section-title" }, "金额"), vue.createElementVNode("view", { class: "options-grid" }, [ vue.createElementVNode( "view", { class: vue.normalizeClass(["option-btn", { active: _ctx.tempFilter.amount === "全部" }]), onClick: _cache[5] || (_cache[5] = ($event) => _ctx.selectAmount("全部")) }, "全部", 2 /* CLASS */ ), vue.createElementVNode( "view", { class: vue.normalizeClass(["option-btn", { active: _ctx.tempFilter.amount === "100以下" }]), onClick: _cache[6] || (_cache[6] = ($event) => _ctx.selectAmount("100以下")) }, "100以下", 2 /* CLASS */ ), vue.createElementVNode( "view", { class: vue.normalizeClass(["option-btn", { active: _ctx.tempFilter.amount === "100-200" }]), onClick: _cache[7] || (_cache[7] = ($event) => _ctx.selectAmount("100-200")) }, "100-200", 2 /* CLASS */ ), vue.createElementVNode( "view", { class: vue.normalizeClass(["option-btn", { active: _ctx.tempFilter.amount === "200-500" }]), onClick: _cache[8] || (_cache[8] = ($event) => _ctx.selectAmount("200-500")) }, "200-500", 2 /* CLASS */ ), vue.createElementVNode( "view", { class: vue.normalizeClass(["option-btn", { active: _ctx.tempFilter.amount === "500以上" }]), onClick: _cache[9] || (_cache[9] = ($event) => _ctx.selectAmount("500以上")) }, "500以上", 2 /* CLASS */ ) ]) ]), vue.createElementVNode("view", { class: "filter-actions" }, [ vue.createElementVNode("button", { class: "action-btn reset", onClick: _cache[10] || (_cache[10] = (...args) => _ctx.resetFilter && _ctx.resetFilter(...args)) }, "重置"), vue.createElementVNode("button", { class: "action-btn confirm", onClick: _cache[11] || (_cache[11] = (...args) => _ctx.confirmFilter && _ctx.confirmFilter(...args)) }, "确认") ]) ], 2 /* CLASS */ ) ]), vue.createElementVNode("view", { class: "task-list-container" }, [ vue.createElementVNode("view", { class: "task-list" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.taskList, (item) => { return vue.openBlock(), vue.createElementBlock("view", { class: "task-card", key: item.id, onClick: ($event) => _ctx.goToDetail(item) }, [ vue.createElementVNode("view", { class: "card-header" }, [ vue.createElementVNode("view", { class: "type-badge" }, [ vue.createElementVNode("image", { class: "type-icon", src: item.typeIcon }, null, 8, ["src"]), vue.createElementVNode( "text", { class: "type-text" }, vue.toDisplayString(item.typeText), 1 /* TEXT */ ) ]), vue.createElementVNode( "text", { class: "price" }, "¥" + vue.toDisplayString(item.price), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "card-body" }, [ vue.createElementVNode("view", { class: "time-row" }, [ vue.createElementVNode( "text", { class: "label" }, vue.toDisplayString(item.timeLabel) + ":", 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "value" }, vue.toDisplayString(item.time), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "pet-card" }, [ vue.createElementVNode("image", { class: "pet-avatar", src: item.petAvatarUrl || item.petAvatar, mode: "aspectFill" }, null, 8, ["src"]), vue.createElementVNode("view", { class: "pet-info" }, [ vue.createElementVNode( "text", { class: "pet-name" }, vue.toDisplayString(item.petName), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "pet-breed" }, "品种: " + vue.toDisplayString(item.petBreed), 1 /* TEXT */ ) ]) ]), vue.createElementVNode("view", { class: "route-info" }, [ item.type === 1 ? (vue.openBlock(), vue.createElementBlock( vue.Fragment, { key: 0 }, [ vue.createElementVNode("view", { class: "route-item", onClick: vue.withModifiers(($event) => _ctx.openNavigation(item, "start"), ["stop"]) }, [ vue.createElementVNode("view", { class: "icon-circle start" }, "起"), vue.createElementVNode("view", { class: "route-line-vertical" }), vue.createElementVNode("view", { class: "address-box" }, [ vue.createElementVNode( "text", { class: "addr-title" }, vue.toDisplayString(item.startLocation), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "addr-desc" }, vue.toDisplayString(item.startAddress), 1 /* TEXT */ ) ]), vue.createElementVNode("image", { class: "nav-arrow", src: _imports_3$2, style: { "flex-shrink": "0", "align-self": "center" } }) ], 8, ["onClick"]), vue.createElementVNode("view", { class: "route-item", onClick: vue.withModifiers(($event) => _ctx.openNavigation(item, "end"), ["stop"]) }, [ vue.createElementVNode("view", { class: "icon-circle end" }, "终"), vue.createElementVNode("view", { class: "address-box" }, [ vue.createElementVNode( "text", { class: "addr-title" }, vue.toDisplayString(item.endLocation), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "addr-desc" }, vue.toDisplayString(item.endAddress), 1 /* TEXT */ ) ]), vue.createElementVNode("image", { class: "nav-arrow", src: _imports_3$2, style: { "flex-shrink": "0", "align-self": "center" } }) ], 8, ["onClick"]) ], 64 /* STABLE_FRAGMENT */ )) : (vue.openBlock(), vue.createElementBlock( vue.Fragment, { key: 1 }, [ vue.createElementVNode("view", { class: "route-item", onClick: vue.withModifiers(($event) => _ctx.openNavigation(item, "end"), ["stop"]) }, [ vue.createElementVNode("view", { class: "icon-circle service" }, "服"), vue.createElementVNode("view", { class: "address-box" }, [ vue.createElementVNode( "text", { class: "addr-title" }, vue.toDisplayString(item.endLocation), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "addr-desc" }, vue.toDisplayString(item.endAddress), 1 /* TEXT */ ) ]), vue.createElementVNode("image", { class: "nav-arrow", src: _imports_3$2, style: { "flex-shrink": "0", "align-self": "center" } }) ], 8, ["onClick"]), item.serviceContent ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "service-content" }, [ vue.createElementVNode("text", { class: "content-label" }, "服务内容:"), vue.createElementVNode( "text", null, vue.toDisplayString(item.serviceContent), 1 /* TEXT */ ) ])) : vue.createCommentVNode("v-if", true) ], 64 /* STABLE_FRAGMENT */ )) ]), item.remark ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "remark-box" }, [ vue.createElementVNode( "text", null, "备注:" + vue.toDisplayString(item.remark), 1 /* TEXT */ ) ])) : vue.createCommentVNode("v-if", true) ]), vue.createElementVNode("view", { class: "action-btns" }, [ vue.createElementVNode("button", { class: "btn reject", onClick: vue.withModifiers(($event) => _ctx.openRejectModal(item), ["stop"]) }, "拒绝", 8, ["onClick"]), vue.createElementVNode("button", { class: "btn accept", onClick: vue.withModifiers(($event) => _ctx.openAcceptModal(item), ["stop"]) }, "接单", 8, ["onClick"]) ]) ], 8, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )), vue.createElementVNode("view", { style: { "height": "120rpx" } }) ]) ]), _ctx.showConfirmModal ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "modal-mask" }, [ vue.createElementVNode("view", { class: "custom-modal" }, [ vue.createElementVNode("text", { class: "modal-title" }, "提示"), vue.createElementVNode("text", { class: "modal-content" }, "是否确定结束休息,开始接单?"), vue.createElementVNode("view", { class: "modal-btns" }, [ vue.createElementVNode("button", { class: "modal-btn cancel", onClick: _cache[12] || (_cache[12] = (...args) => _ctx.closeConfirmModal && _ctx.closeConfirmModal(...args)) }, "取消"), vue.createElementVNode("button", { class: "modal-btn confirm", onClick: _cache[13] || (_cache[13] = (...args) => _ctx.confirmStartWork && _ctx.confirmStartWork(...args)) }, "确定") ]) ]) ])) : vue.createCommentVNode("v-if", true), _ctx.showPetModal ? (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "pet-modal-mask", onClick: _cache[17] || (_cache[17] = (...args) => _ctx.closePetProfile && _ctx.closePetProfile(...args)) }, [ vue.createElementVNode("view", { class: "pet-modal-content", onClick: _cache[16] || (_cache[16] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("view", { class: "pet-modal-header" }, [ vue.createElementVNode("text", { class: "pet-modal-title" }, "宠物档案"), vue.createElementVNode("view", { class: "close-icon-btn", onClick: _cache[14] || (_cache[14] = (...args) => _ctx.closePetProfile && _ctx.closePetProfile(...args)) }, "×") ]), vue.createElementVNode("scroll-view", { "scroll-y": "", class: "pet-modal-scroll" }, [ vue.createElementVNode("view", { class: "pet-base-info" }, [ vue.createElementVNode("image", { class: "pm-avatar", src: _ctx.currentPetInfo.petAvatar, mode: "aspectFill" }, null, 8, ["src"]), vue.createElementVNode("view", { class: "pm-info-text" }, [ vue.createElementVNode("view", { class: "pm-name-row" }, [ vue.createElementVNode( "text", { class: "pm-name" }, vue.toDisplayString(_ctx.currentPetInfo.petName), 1 /* TEXT */ ), _ctx.currentPetInfo.petGender === "M" ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "pm-gender" }, [ vue.createElementVNode("text", { class: "gender-icon" }, "♂"), vue.createElementVNode("text", null, "公") ])) : _ctx.currentPetInfo.petGender === "F" ? (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "pm-gender female" }, [ vue.createElementVNode("text", { class: "gender-icon" }, "♀"), vue.createElementVNode("text", null, "母") ])) : vue.createCommentVNode("v-if", true) ]), vue.createElementVNode( "text", { class: "pm-breed" }, "品种:" + vue.toDisplayString(_ctx.currentPetInfo.petBreed), 1 /* TEXT */ ) ]) ]), vue.createElementVNode("view", { class: "pm-detail-grid" }, [ vue.createElementVNode("view", { class: "pm-grid-item half" }, [ vue.createElementVNode("text", { class: "pm-label" }, "年龄"), vue.createElementVNode( "text", { class: "pm-val" }, vue.toDisplayString(_ctx.currentPetInfo.petAge || "未知"), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "pm-grid-item half" }, [ vue.createElementVNode("text", { class: "pm-label" }, "体重"), vue.createElementVNode( "text", { class: "pm-val" }, vue.toDisplayString(_ctx.currentPetInfo.petWeight || "未知"), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "pm-grid-item full" }, [ vue.createElementVNode("text", { class: "pm-label" }, "性格"), vue.createElementVNode( "text", { class: "pm-val" }, vue.toDisplayString(_ctx.currentPetInfo.petPersonality || "无"), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "pm-grid-item full" }, [ vue.createElementVNode("text", { class: "pm-label" }, "爱好"), vue.createElementVNode( "text", { class: "pm-val" }, vue.toDisplayString(_ctx.currentPetInfo.petHobby || "无"), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "pm-grid-item full" }, [ vue.createElementVNode("text", { class: "pm-label" }, "备注"), vue.createElementVNode( "text", { class: "pm-val" }, vue.toDisplayString(_ctx.currentPetInfo.petRemark || "无特殊过敏史"), 1 /* TEXT */ ) ]) ]), _ctx.currentPetInfo.petTags && _ctx.currentPetInfo.petTags.length > 0 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "pm-tags" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.currentPetInfo.petTags, (tag, index) => { return vue.openBlock(), vue.createElementBlock( "view", { class: "pm-tag", key: index }, vue.toDisplayString(tag), 1 /* TEXT */ ); }), 128 /* KEYED_FRAGMENT */ )) ])) : vue.createCommentVNode("v-if", true), vue.createElementVNode("view", { class: "pm-section-title" }, [ vue.createElementVNode("view", { class: "orange-bar" }), vue.createElementVNode("text", null, "备注日志") ]), vue.createElementVNode("view", { class: "pm-log-list" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.currentPetInfo.petLogs, (log, lIndex) => { return vue.openBlock(), vue.createElementBlock("view", { class: "pm-log-item", key: lIndex }, [ vue.createElementVNode( "text", { class: "pm-log-date" }, vue.toDisplayString(log.date), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "pm-log-text" }, vue.toDisplayString(log.content), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "pm-log-recorder" }, vue.toDisplayString(log.recorder === "系统记录" ? "" : "记录人: ") + vue.toDisplayString(log.recorder), 1 /* TEXT */ ) ]); }), 128 /* KEYED_FRAGMENT */ )) ]), vue.createElementVNode("view", { style: { "height": "40rpx" } }), vue.createElementVNode("button", { class: "pm-bottom-close", onClick: _cache[15] || (_cache[15] = (...args) => _ctx.closePetProfile && _ctx.closePetProfile(...args)) }, "关闭"), vue.createElementVNode("view", { style: { "height": "20rpx" } }) ]) ]) ])) : vue.createCommentVNode("v-if", true) ]), _ctx.showRejectModal ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "modal-mask" }, [ vue.createElementVNode("view", { class: "custom-modal" }, [ vue.createElementVNode("text", { class: "modal-title" }, "拒绝接单"), vue.withDirectives(vue.createElementVNode( "textarea", { class: "reject-textarea", "onUpdate:modelValue": _cache[18] || (_cache[18] = ($event) => _ctx.rejectReason = $event), placeholder: "请输入拒绝理由(必填)", maxlength: "100" }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, _ctx.rejectReason] ]), vue.createElementVNode("view", { class: "modal-btns mt-30" }, [ vue.createElementVNode("button", { class: "modal-btn cancel", onClick: _cache[19] || (_cache[19] = (...args) => _ctx.closeRejectModal && _ctx.closeRejectModal(...args)) }, "取消"), vue.createElementVNode("button", { class: "modal-btn confirm", onClick: _cache[20] || (_cache[20] = (...args) => _ctx.confirmReject && _ctx.confirmReject(...args)) }, "提交") ]) ]) ])) : vue.createCommentVNode("v-if", true), _ctx.showAcceptConfirmModal ? (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "modal-mask" }, [ vue.createElementVNode("view", { class: "custom-modal" }, [ vue.createElementVNode("text", { class: "modal-title" }, "接单确认"), vue.createElementVNode("view", { class: "modal-content-box" }, [ vue.createElementVNode("text", { class: "modal-content-main" }, "请确认是否接收此订单?"), vue.createElementVNode("text", { class: "modal-content-sub" }, "接单后请尽快通过电话联系用户") ]), vue.createElementVNode("view", { class: "modal-btns mt-30" }, [ vue.createElementVNode("button", { class: "modal-btn cancel", onClick: _cache[21] || (_cache[21] = (...args) => _ctx.closeAcceptModal && _ctx.closeAcceptModal(...args)) }, "再想想"), vue.createElementVNode("button", { class: "modal-btn confirm", onClick: _cache[22] || (_cache[22] = (...args) => _ctx.confirmAccept && _ctx.confirmAccept(...args)) }, "确认接单") ]) ]) ])) : vue.createCommentVNode("v-if", true), _ctx.showNavModal ? (vue.openBlock(), vue.createElementBlock("view", { key: 2, class: "nav-modal-mask", onClick: _cache[28] || (_cache[28] = (...args) => _ctx.closeNavModal && _ctx.closeNavModal(...args)) }, [ vue.createElementVNode("view", { class: "nav-action-sheet", onClick: _cache[27] || (_cache[27] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("view", { class: "nav-sheet-title" }, "选择地图进行导航"), vue.createElementVNode("view", { class: "nav-sheet-item", onClick: _cache[23] || (_cache[23] = ($event) => _ctx.chooseMap("高德")) }, "高德地图"), vue.createElementVNode("view", { class: "nav-sheet-item", onClick: _cache[24] || (_cache[24] = ($event) => _ctx.chooseMap("腾讯")) }, "腾讯地图"), vue.createElementVNode("view", { class: "nav-sheet-item", onClick: _cache[25] || (_cache[25] = ($event) => _ctx.chooseMap("百度")) }, "百度地图"), vue.createElementVNode("view", { class: "nav-sheet-gap" }), vue.createElementVNode("view", { class: "nav-sheet-item cancel", onClick: _cache[26] || (_cache[26] = (...args) => _ctx.closeNavModal && _ctx.closeNavModal(...args)) }, "取消") ]) ])) : vue.createCommentVNode("v-if", true), vue.createVNode(_component_custom_tabbar, { currentPath: "pages/home/index" }) ], 64 /* STABLE_FRAGMENT */ ); } const PagesHomeIndex = /* @__PURE__ */ _export_sfc(_sfc_main$u, [["render", _sfc_render$t], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/home/index.vue"]]); const _sfc_main$t = { data() { return { status: "resting", // resting | busy | disabled loading: false }; }, onShow() { const savedStatus = uni.getStorageSync("workStatus"); if (savedStatus) { this.status = savedStatus; } this.fetchLatestProfile(); }, methods: { async fetchLatestProfile() { try { const res = await getMyProfile(); if (res.data && res.data.status) { this.status = res.data.status; uni.setStorageSync("workStatus", this.status); } } catch (err) { formatAppLog("error", "at pages/home/work-status.vue:64", "获取状态失败:", err); } }, async toggleStatus() { if (this.loading) return; const targetStatus = this.status === "busy" ? "resting" : "busy"; const actionText = targetStatus === "busy" ? "恢复接单" : "停止接单"; try { uni.showLoading({ title: "处理中...", mask: true }); this.loading = true; await updateStatus(targetStatus); await this.fetchLatestProfile(); uni.hideLoading(); uni.showToast({ title: actionText + "成功", icon: "success" }); } catch (err) { uni.hideLoading(); formatAppLog("error", "at pages/home/work-status.vue:88", "切换状态失败:", err); uni.showToast({ title: "操作失败,请重试", icon: "none" }); } finally { this.loading = false; } } } }; function _sfc_render$s(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "signboard-container" }, [ vue.createElementVNode("view", { class: "rope" }), vue.createElementVNode("view", { class: "nail" }), vue.createElementVNode( "view", { class: vue.normalizeClass(["board", { "resting": $data.status !== "busy" }]) }, [ vue.createElementVNode("view", { class: "screw top-left" }), vue.createElementVNode("view", { class: "screw top-right" }), vue.createElementVNode("view", { class: "screw bottom-left" }), vue.createElementVNode("view", { class: "screw bottom-right" }), vue.createElementVNode("view", { class: "board-inner" }, [ vue.createElementVNode( "text", { class: "status-text" }, vue.toDisplayString($data.status === "busy" ? "接单中" : "休息中"), 1 /* TEXT */ ) ]) ], 2 /* CLASS */ ) ]), vue.createElementVNode("view", { class: "status-desc" }, [ vue.createElementVNode( "text", null, vue.toDisplayString($data.status === "busy" ? "当前处于工作接单中,正常接收新订单" : "当前处于休息状态,暂停接收新订单"), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "action-area" }, [ vue.createElementVNode( "button", { class: vue.normalizeClass(["action-btn", { "stop": $data.status === "busy", "start": $data.status !== "busy" }]), onClick: _cache[0] || (_cache[0] = (...args) => $options.toggleStatus && $options.toggleStatus(...args)) }, vue.toDisplayString($data.status === "busy" ? "停止接单" : "开始接单"), 3 /* TEXT, CLASS */ ), vue.createElementVNode("view", { class: "tips" }, [ $data.status === "busy" ? (vue.openBlock(), vue.createElementBlock("text", { key: 0 }, "当您希望长时间不再接收订单时,请点击上方按钮停止接单,开启后需手动恢复。")) : (vue.openBlock(), vue.createElementBlock("text", { key: 1 }, "点击上方按钮恢复接单,开始接收新的任务推送。")) ]) ]) ]); } const PagesHomeWorkStatus = /* @__PURE__ */ _export_sfc(_sfc_main$t, [["render", _sfc_render$s], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/home/work-status.vue"]]); const logic$2 = { components: { customTabbar }, data() { return { currentTab: 0, tabs: ["待接送/服务", "配送/服务中", "已完成", "已取消"], typeFilterOptions: ["全部类型"], currentTypeFilterIdx: 0, activeDropdown: 0, hasTimeFilter: false, currentMonth: "2026年2月", weekDays: ["日", "一", "二", "三", "四", "五", "六"], calendarDays: [], selectedDateRange: [], allOrderList: [], serviceList: [], searchContent: "", startServiceTime: "", endServiceTime: "", showPetModal: false, currentPetInfo: {}, showNavModal: false, navTargetItem: null, navTargetPointType: "", activeCallItem: null, showRemarkInput: false, remarkText: "" }; }, created() { this.initCalendar(); }, async onLoad() { await this.loadServiceList(); await this.loadOrders(); reportGps(true).catch((e) => formatAppLog("log", "at pages/orders/logic.js:44", "Init GPS check skipped", e)); }, onShow() { uni.hideTabBar(); this.loadOrders(); }, async onPullDownRefresh() { try { await this.loadServiceList(); await this.loadOrders(); } finally { uni.stopPullDownRefresh(); } }, watch: { currentTab() { this.loadOrders(); }, currentTypeFilterIdx() { this.loadOrders(); }, searchContent() { this.loadOrders(); } }, computed: { orderList() { return this.allOrderList; } }, methods: { async loadServiceList() { try { const res = await listAllService(); this.serviceList = res.data || []; this.typeFilterOptions = ["全部类型", ...this.serviceList.map((s) => s.name)]; } catch (err) { formatAppLog("error", "at pages/orders/logic.js:84", "获取服务类型失败:", err); } }, async loadOrders() { var _a; try { const statusMap = { 0: 2, 1: 3, 2: 4, 3: 5 }; const serviceId = this.currentTypeFilterIdx > 0 ? (_a = this.serviceList[this.currentTypeFilterIdx - 1]) == null ? void 0 : _a.id : void 0; const params = { status: statusMap[this.currentTab], content: this.searchContent || void 0, service: serviceId, startServiceTime: this.startServiceTime || void 0, endServiceTime: this.endServiceTime || void 0 }; formatAppLog("log", "at pages/orders/logic.js:98", "订单列表请求参数:", params); const res = await getMyOrders(params); formatAppLog("log", "at pages/orders/logic.js:100", "订单列表响应:", res); const orders = res.rows || []; formatAppLog("log", "at pages/orders/logic.js:102", "订单数量:", orders.length); this.allOrderList = orders.map((order) => this.transformOrder(order, this.currentTab)); } catch (err) { formatAppLog("error", "at pages/orders/logic.js:105", "获取订单列表失败:", err); this.allOrderList = []; } }, transformOrder(order, tabIndex) { const service = this.serviceList.find((s) => s.id === order.service); const serviceText = (service == null ? void 0 : service.name) || "未知"; const serviceIcon = (service == null ? void 0 : service.iconUrl) || ""; const mode = (service == null ? void 0 : service.mode) || 0; const isRoundTrip = mode === 1; let statusText = "接单"; if (tabIndex === 0) { statusText = "接单"; } else if (tabIndex === 1) { statusText = isRoundTrip ? "出发" : "开始"; } else if (tabIndex === 2) { statusText = "已完成"; } else if (tabIndex === 3) { statusText = "已拒绝"; } return { id: order.id, status: order.status, // 保存原始 status 用于判断权限 type: isRoundTrip ? 1 : 2, typeText: serviceText, typeIcon: serviceIcon, statusText, price: (order.price / 100).toFixed(2), timeLabel: "服务时间", time: order.serviceTime || "", petAvatar: order.petAvatar || "/static/dog.png", petAvatarUrl: order.petAvatarUrl || "", petName: order.petName || "", petBreed: order.breed || "", startLocation: order.fromAddress || "暂无起点", startAddress: order.fromAddress || "", fromAddress: order.fromAddress || "", fromLat: order.fromLat, fromLng: order.fromLng, startDistance: "0km", endLocation: (order.customerName || "") + " " + (order.customerPhone || ""), endAddress: order.toAddress || "", toAddress: order.toAddress || "", toLat: order.toLat, toLng: order.toLng, customerPhone: order.customerPhone || "", endDistance: "0km", serviceContent: order.remark || "", remark: order.remark || "" }; }, getDisplayStatus(item) { if (item.statusText === "已完成") return "已完成"; if (item.statusText === "已拒绝") return "已拒绝"; if (item.statusText === "接单") { return item.type === 1 ? "待接送" : "待服务"; } return item.type === 1 ? "配送中" : "服务中"; }, getStatusClass(item) { let display = this.getDisplayStatus(item); if (display === "已完成") return "finish"; if (display === "已拒绝") return "reject"; if (display === "配送中" || display === "服务中") return "processing"; return "highlight"; }, goToDetail(item) { uni.navigateTo({ url: `/pages/orders/detail?id=${item.id}` }); }, showPetProfile(item) { this.currentPetInfo = { ...item, petGender: "M", petAge: "2岁", petWeight: "15kg", petPersonality: "活泼亲人,精力旺盛", petHobby: "喜欢追飞盘,爱吃肉干", petRemark: "肠胃较弱,不能乱喂零食;出门易爆冲,请拉紧牵引绳。", petTags: ["拉响警报", "不能吃鸡肉", "精力旺盛"], petLogs: [ { date: "2026-02-09 14:00", content: "今天遛弯拉了两次粑粑,精神状态很好。", recorder: "王阿姨" }, { date: "2026-02-08 10:30", content: "有些挑食,剩了小半碗狗粮。", recorder: "李师傅" }, { date: "2026-02-05 09:00", content: "建档。", recorder: "系统记录" } ] }; this.showPetModal = true; }, closePetProfile() { this.showPetModal = false; }, openNavigation(item, pointType) { this.navTargetItem = item; this.navTargetPointType = pointType; this.showNavModal = true; }, closeNavModal() { this.showNavModal = false; }, chooseMap(mapType) { let item = this.navTargetItem; let pointType = this.navTargetPointType; let name = pointType === "start" ? item.fromAddress || "起点" : item.toAddress || "终点"; let address = pointType === "start" ? item.fromAddress || "起点地址" : item.toAddress || "终点地址"; let latitude = pointType === "start" ? Number(item.fromLat) : Number(item.toLat); let longitude = pointType === "start" ? Number(item.fromLng) : Number(item.toLng); this.showNavModal = false; const navigateTo = (lat, lng, addrName, addrDesc) => { uni.openLocation({ latitude: lat, longitude: lng, name: addrName, address: addrDesc || "无法获取详细地址", success: function() { formatAppLog("log", "at pages/orders/logic.js:224", "打开导航成功: " + mapType); }, fail: function(err) { formatAppLog("error", "at pages/orders/logic.js:227", "打开导航失败:", err); uni.showToast({ title: "打开地图失败", icon: "none" }); } }); }; if (latitude && longitude && !isNaN(latitude) && !isNaN(longitude)) { navigateTo(latitude, longitude, name, address); } else { uni.showLoading({ title: "获取当前位置...", mask: true }); reportGps(true).then((res) => { uni.hideLoading(); navigateTo(res.latitude, res.longitude, name, address); }).catch((err) => { uni.hideLoading(); formatAppLog("error", "at pages/orders/logic.js:245", "获取地理位置失败:", err); }); } }, toggleCallMenu(item) { if (this.activeCallItem === item) { this.activeCallItem = null; } else { this.activeCallItem = item; } }, closeCallMenu() { this.activeCallItem = null; }, doCall(type, item) { let phoneNum = ""; const targetItem = item || this.activeCallItem; if (type === "merchant") { phoneNum = "18900008451"; } else if (type === "customer") { phoneNum = targetItem == null ? void 0 : targetItem.customerPhone; } if (!phoneNum) { uni.showToast({ title: "未找到电话号码", icon: "none" }); this.activeCallItem = null; return; } phoneNum = phoneNum.replace(/[^\d]/g, ""); if (phoneNum.length < 3) { uni.showToast({ title: "电话号码格式错误", icon: "none" }); this.activeCallItem = null; return; } formatAppLog("log", "at pages/orders/logic.js:288", "正在发起直接呼叫:", phoneNum); uni.makePhoneCall({ phoneNumber: phoneNum, success: () => { formatAppLog("log", "at pages/orders/logic.js:296", "成功唤起系统拨号盘"); }, fail: (err) => { formatAppLog("error", "at pages/orders/logic.js:299", "拨号失败:", err); let msg = "拨号失败"; if (err.message && err.message.includes("permission")) { msg = '请在手机设置中允许"电话"权限'; } uni.showToast({ title: msg, icon: "none", duration: 3e3 }); }, complete: () => { this.activeCallItem = null; } }); }, reportAbnormal(item) { uni.navigateTo({ url: "/pages/orders/anomaly?orderId=" + (item.id || "") }); }, toggleDropdown(idx) { if (this.activeDropdown === idx) { this.activeDropdown = 0; } else { this.activeDropdown = idx; } }, closeDropdown() { this.activeDropdown = 0; }, selectType(index) { this.currentTypeFilterIdx = index; this.closeDropdown(); }, initCalendar() { let days = []; for (let i = 1; i <= 28; i++) { days.push(i); } this.calendarDays = days; this.selectedDateRange = [2, 4]; }, prevMonth() { uni.showToast({ title: "上个月", icon: "none" }); }, nextMonth() { uni.showToast({ title: "下个月", icon: "none" }); }, selectDateItem(day) { if (this.selectedDateRange.length === 2) { this.selectedDateRange = [day]; } else if (this.selectedDateRange.length === 1) { let start = this.selectedDateRange[0]; if (day > start) { this.selectedDateRange = [start, day]; } else if (day < start) { this.selectedDateRange = [day, start]; } else { this.selectedDateRange = []; } } else { this.selectedDateRange = [day]; } }, getDateClass(day) { if (this.selectedDateRange.length === 0) return ""; if (this.selectedDateRange.length === 1) { return day === this.selectedDateRange[0] ? "is-start" : ""; } let start = this.selectedDateRange[0]; let end = this.selectedDateRange[1]; if (day === start) return "is-start"; if (day === end) return "is-end"; if (day > start && day < end) return "is-between"; return ""; }, resetTimeFilter() { this.hasTimeFilter = false; this.selectedDateRange = []; this.startServiceTime = ""; this.endServiceTime = ""; this.closeDropdown(); this.loadOrders(); }, confirmTimeFilter() { if (this.selectedDateRange.length === 0) { uni.showToast({ title: "请先选择日期", icon: "none" }); return; } const year = this.currentMonth.replace(/[^0-9]/g, "").substring(0, 4); const month = this.currentMonth.replace(/[^0-9]/g, "").substring(4); const pad = (n) => String(n).padStart(2, "0"); if (this.selectedDateRange.length === 2) { this.startServiceTime = `${year}-${pad(month)}-${pad(this.selectedDateRange[0])} 00:00:00`; this.endServiceTime = `${year}-${pad(month)}-${pad(this.selectedDateRange[1])} 23:59:59`; } else { this.startServiceTime = `${year}-${pad(month)}-${pad(this.selectedDateRange[0])} 00:00:00`; this.endServiceTime = `${year}-${pad(month)}-${pad(this.selectedDateRange[0])} 23:59:59`; } this.hasTimeFilter = true; this.closeDropdown(); this.loadOrders(); }, getMainActionText(item) { return "查看详情"; }, mainAction(item) { uni.navigateTo({ url: `/pages/orders/detail?id=${item.id}` }); }, openRemarkInput() { this.remarkText = ""; this.showRemarkInput = true; }, closeRemarkInput() { this.showRemarkInput = false; this.remarkText = ""; }, submitRemark() { const text = this.remarkText.trim(); if (!text) { uni.showToast({ title: "备注内容不能为空", icon: "none" }); return; } const now = /* @__PURE__ */ new Date(); const dateStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")} ${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}`; if (!this.currentPetInfo.petLogs) { this.$set(this.currentPetInfo, "petLogs", []); } this.currentPetInfo.petLogs.unshift({ date: dateStr, content: text, recorder: "我" }); uni.showToast({ title: "备注已添加", icon: "success" }); this.closeRemarkInput(); }, /** * 取消订单处理逻辑 * @param {Object} item - 订单项 */ handleCancelOrder(item) { uni.showModal({ title: "提示", content: "确认是否取消这个订单?", success: async (res) => { if (res.confirm) { try { uni.showLoading({ title: "取消中...", mask: true }); await cancelOrderApi({ orderId: item.id }); uni.showToast({ title: "订单已取消", icon: "success" }); setTimeout(() => { this.loadOrders(); }, 1500); } catch (err) { formatAppLog("error", "at pages/orders/logic.js:482", "取消订单失败:", err); uni.showToast({ title: "取消失败", icon: "none" }); } finally { uni.hideLoading(); } } } }); } } }; const _sfc_main$s = { ...logic$2 }; function _sfc_render$r(_ctx, _cache, $props, $setup, $data, $options) { const _component_custom_tabbar = vue.resolveComponent("custom-tabbar"); return vue.openBlock(), vue.createElementBlock( vue.Fragment, null, [ vue.createElementVNode("view", { class: "container" }, [ vue.createElementVNode("view", { class: "sticky-header" }, [ vue.createElementVNode("view", { class: "status-tabs" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.tabs, (tab, index) => { return vue.openBlock(), vue.createElementBlock("view", { class: vue.normalizeClass(["tab-item", { active: _ctx.currentTab === index }]), key: index, onClick: ($event) => _ctx.currentTab = index }, [ vue.createElementVNode( "text", null, vue.toDisplayString(tab), 1 /* TEXT */ ), _ctx.currentTab === index ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "indicator" })) : vue.createCommentVNode("v-if", true) ], 10, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )) ]), vue.createElementVNode("view", { class: "search-bar" }, [ vue.createElementVNode("view", { class: "search-input-box" }, [ vue.withDirectives(vue.createElementVNode( "input", { class: "search-input", "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.searchContent = $event), placeholder: "搜索地址/电话/姓名", "placeholder-class": "ph-style" }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, _ctx.searchContent] ]) ]) ]), vue.createElementVNode("view", { class: "filter-wrapper" }, [ vue.createElementVNode("view", { class: "filter-bar" }, [ vue.createElementVNode( "view", { class: vue.normalizeClass(["filter-item", { "active": _ctx.activeDropdown === 1 }]), onClick: _cache[1] || (_cache[1] = ($event) => _ctx.toggleDropdown(1)) }, [ vue.createElementVNode( "text", { class: vue.normalizeClass({ "active-text": _ctx.activeDropdown === 1 || _ctx.currentTypeFilterIdx > 0 }) }, vue.toDisplayString(_ctx.currentTypeFilterIdx > 0 ? _ctx.typeFilterOptions[_ctx.currentTypeFilterIdx] : "全部类型"), 3 /* TEXT, CLASS */ ), vue.createElementVNode( "view", { class: vue.normalizeClass(["triangle", _ctx.activeDropdown === 1 ? "up" : "down"]) }, null, 2 /* CLASS */ ) ], 2 /* CLASS */ ), vue.createElementVNode( "view", { class: vue.normalizeClass(["filter-item", { "active": _ctx.activeDropdown === 2 }]), onClick: _cache[2] || (_cache[2] = ($event) => _ctx.toggleDropdown(2)) }, [ vue.createElementVNode( "text", { class: vue.normalizeClass({ "active-text": _ctx.activeDropdown === 2 || _ctx.hasTimeFilter }) }, "服务时间", 2 /* CLASS */ ), vue.createElementVNode( "view", { class: vue.normalizeClass(["triangle", _ctx.activeDropdown === 2 ? "up" : "down"]) }, null, 2 /* CLASS */ ) ], 2 /* CLASS */ ) ]), _ctx.activeDropdown !== 0 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "dropdown-mask", onClick: _cache[3] || (_cache[3] = (...args) => _ctx.closeDropdown && _ctx.closeDropdown(...args)) })) : vue.createCommentVNode("v-if", true), _ctx.activeDropdown === 1 ? (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "dropdown-panel" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.typeFilterOptions, (item, index) => { return vue.openBlock(), vue.createElementBlock("view", { class: vue.normalizeClass(["type-option", { "selected": _ctx.currentTypeFilterIdx === index }]), key: index, onClick: ($event) => _ctx.selectType(index) }, [ vue.createElementVNode( "text", null, vue.toDisplayString(item), 1 /* TEXT */ ) ], 10, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )) ])) : vue.createCommentVNode("v-if", true), _ctx.activeDropdown === 2 ? (vue.openBlock(), vue.createElementBlock("view", { key: 2, class: "dropdown-panel calendar-panel" }, [ vue.createElementVNode("view", { class: "custom-calendar-container" }, [ vue.createElementVNode("view", { class: "cal-header" }, [ vue.createElementVNode("text", { class: "cal-nav-btn", onClick: _cache[4] || (_cache[4] = (...args) => _ctx.prevMonth && _ctx.prevMonth(...args)) }, "‹"), vue.createElementVNode( "text", { class: "cal-title" }, vue.toDisplayString(_ctx.currentMonth), 1 /* TEXT */ ), vue.createElementVNode("text", { class: "cal-nav-btn", onClick: _cache[5] || (_cache[5] = (...args) => _ctx.nextMonth && _ctx.nextMonth(...args)) }, "›") ]), vue.createElementVNode("view", { class: "cal-weekdays" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.weekDays, (wk, idx) => { return vue.openBlock(), vue.createElementBlock( "text", { key: idx, class: "wk-item" }, vue.toDisplayString(wk), 1 /* TEXT */ ); }), 128 /* KEYED_FRAGMENT */ )) ]), vue.createElementVNode("view", { class: "cal-body" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.calendarDays, (day, idx) => { return vue.openBlock(), vue.createElementBlock("view", { key: idx, class: vue.normalizeClass(["cal-day-box", _ctx.getDateClass(day)]), onClick: ($event) => _ctx.selectDateItem(day) }, [ vue.createElementVNode( "view", { class: "cal-day-text" }, vue.toDisplayString(day), 1 /* TEXT */ ) ], 10, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )) ]) ]), vue.createElementVNode("view", { class: "calendar-actions" }, [ vue.createElementVNode("button", { class: "cal-btn reset", onClick: _cache[6] || (_cache[6] = (...args) => _ctx.resetTimeFilter && _ctx.resetTimeFilter(...args)) }, "重置"), vue.createElementVNode("button", { class: "cal-btn confirm", onClick: _cache[7] || (_cache[7] = (...args) => _ctx.confirmTimeFilter && _ctx.confirmTimeFilter(...args)) }, "确定") ]) ])) : vue.createCommentVNode("v-if", true) ]) ]), vue.createElementVNode("view", { class: "order-list" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.orderList, (item, index) => { return vue.openBlock(), vue.createElementBlock("view", { class: "order-card", key: index, onClick: ($event) => _ctx.goToDetail(item) }, [ vue.createElementVNode("view", { class: "card-header" }, [ vue.createElementVNode("view", { class: "type-badge" }, [ vue.createElementVNode("image", { class: "type-icon", src: item.typeIcon }, null, 8, ["src"]), vue.createElementVNode( "text", { class: "type-text" }, vue.toDisplayString(item.typeText), 1 /* TEXT */ ) ]), vue.createElementVNode( "text", { class: vue.normalizeClass(["status-badge", _ctx.getStatusClass(item)]) }, vue.toDisplayString(_ctx.getDisplayStatus(item)), 3 /* TEXT, CLASS */ ) ]), vue.createElementVNode("view", { class: "card-body" }, [ vue.createElementVNode("view", { class: "time-row" }, [ vue.createElementVNode("view", { class: "time-col" }, [ vue.createElementVNode( "text", { class: "label" }, vue.toDisplayString(item.timeLabel) + ":", 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "value" }, vue.toDisplayString(item.time), 1 /* TEXT */ ) ]), vue.createElementVNode( "text", { class: "price" }, "¥" + vue.toDisplayString(item.price), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "pet-card" }, [ vue.createElementVNode("image", { class: "pet-avatar", src: item.petAvatarUrl || item.petAvatar, mode: "aspectFill" }, null, 8, ["src"]), vue.createElementVNode("view", { class: "pet-info" }, [ vue.createElementVNode( "text", { class: "pet-name" }, vue.toDisplayString(item.petName), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "pet-breed" }, "品种: " + vue.toDisplayString(item.petBreed), 1 /* TEXT */ ) ]) ]), vue.createElementVNode("view", { class: "route-info" }, [ item.type === 1 ? (vue.openBlock(), vue.createElementBlock( vue.Fragment, { key: 0 }, [ vue.createElementVNode("view", { class: "route-item", onClick: vue.withModifiers(($event) => _ctx.openNavigation(item, "start"), ["stop"]) }, [ vue.createElementVNode("view", { class: "icon-circle start" }, "起"), vue.createElementVNode("view", { class: "route-line-vertical" }), vue.createElementVNode("view", { class: "address-box" }, [ vue.createElementVNode( "text", { class: "addr-title" }, vue.toDisplayString(item.startLocation), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "addr-desc" }, vue.toDisplayString(item.startAddress), 1 /* TEXT */ ) ]), vue.createElementVNode("image", { class: "nav-arrow", src: _imports_3$2, style: { "flex-shrink": "0", "align-self": "center" } }) ], 8, ["onClick"]), vue.createElementVNode("view", { class: "route-item", onClick: vue.withModifiers(($event) => _ctx.openNavigation(item, "end"), ["stop"]) }, [ vue.createElementVNode("view", { class: "icon-circle end" }, "终"), vue.createElementVNode("view", { class: "address-box" }, [ vue.createElementVNode( "text", { class: "addr-title" }, vue.toDisplayString(item.endLocation), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "addr-desc" }, vue.toDisplayString(item.endAddress), 1 /* TEXT */ ) ]), vue.createElementVNode("image", { class: "nav-arrow", src: _imports_3$2, style: { "flex-shrink": "0", "align-self": "center" } }) ], 8, ["onClick"]) ], 64 /* STABLE_FRAGMENT */ )) : (vue.openBlock(), vue.createElementBlock( vue.Fragment, { key: 1 }, [ vue.createElementVNode("view", { class: "route-item", onClick: vue.withModifiers(($event) => _ctx.openNavigation(item, "end"), ["stop"]) }, [ vue.createElementVNode("view", { class: "icon-circle service" }, "服"), vue.createElementVNode("view", { class: "address-box" }, [ vue.createElementVNode( "text", { class: "addr-title" }, vue.toDisplayString(item.endLocation), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "addr-desc" }, vue.toDisplayString(item.endAddress), 1 /* TEXT */ ) ]), vue.createElementVNode("image", { class: "nav-arrow", src: _imports_3$2, style: { "flex-shrink": "0", "align-self": "center" } }) ], 8, ["onClick"]), item.serviceContent ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "service-content" }, [ vue.createElementVNode("text", { class: "content-label" }, "服务内容:"), vue.createElementVNode( "text", null, vue.toDisplayString(item.serviceContent), 1 /* TEXT */ ) ])) : vue.createCommentVNode("v-if", true) ], 64 /* STABLE_FRAGMENT */ )) ]), item.remark ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "remark-box" }, [ vue.createElementVNode( "text", null, "备注:" + vue.toDisplayString(item.remark), 1 /* TEXT */ ) ])) : vue.createCommentVNode("v-if", true) ]), ["接单", "到达", "出发", "开始", "送达", "结束"].includes(item.statusText) ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "action-btns" }, [ vue.createElementVNode("view", { class: "action-left" }, [ vue.createElementVNode("button", { class: "btn normal", onClick: vue.withModifiers(($event) => _ctx.doCall("customer", item), ["stop"]) }, "拨号", 8, ["onClick"]) ]), vue.createElementVNode("view", { class: "action-right" }, [ item.status === 2 ? (vue.openBlock(), vue.createElementBlock("button", { key: 0, class: "btn normal danger", onClick: vue.withModifiers(($event) => _ctx.handleCancelOrder(item), ["stop"]) }, "取消", 8, ["onClick"])) : vue.createCommentVNode("v-if", true), vue.createElementVNode("button", { class: "btn normal", onClick: vue.withModifiers(($event) => _ctx.reportAbnormal(item), ["stop"]) }, "异常上报", 8, ["onClick"]), vue.createElementVNode("button", { class: "btn primary", onClick: vue.withModifiers(($event) => _ctx.mainAction(item), ["stop"]) }, "打卡", 8, ["onClick"]) ]) ])) : vue.createCommentVNode("v-if", true) ], 8, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )), vue.createElementVNode("view", { class: "loading-text" }, "已加载完"), vue.createElementVNode("view", { style: { "height": "160rpx" } }) ]), _ctx.activeCallItem ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "call-mask", onClick: _cache[8] || (_cache[8] = (...args) => _ctx.closeCallMenu && _ctx.closeCallMenu(...args)) })) : vue.createCommentVNode("v-if", true) ]), _ctx.showPetModal ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "pet-modal-mask", onClick: _cache[12] || (_cache[12] = (...args) => _ctx.closePetProfile && _ctx.closePetProfile(...args)) }, [ vue.createElementVNode("view", { class: "pet-modal-content", onClick: _cache[11] || (_cache[11] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("view", { class: "pet-modal-header" }, [ vue.createElementVNode("text", { class: "pet-modal-title" }, "宠物档案"), vue.createElementVNode("view", { class: "pm-header-actions" }, [ vue.createElementVNode("view", { class: "pm-remark-btn", onClick: _cache[9] || (_cache[9] = (...args) => _ctx.openRemarkInput && _ctx.openRemarkInput(...args)) }, "备注"), vue.createElementVNode("view", { class: "close-icon-btn", onClick: _cache[10] || (_cache[10] = (...args) => _ctx.closePetProfile && _ctx.closePetProfile(...args)) }, "×") ]) ]), vue.createElementVNode("scroll-view", { "scroll-y": "", class: "pet-modal-scroll" }, [ vue.createElementVNode("view", { class: "pet-base-info" }, [ vue.createElementVNode("image", { class: "pm-avatar", src: _ctx.currentPetInfo.petAvatar, mode: "aspectFill" }, null, 8, ["src"]), vue.createElementVNode("view", { class: "pm-info-text" }, [ vue.createElementVNode("view", { class: "pm-name-row" }, [ vue.createElementVNode( "text", { class: "pm-name" }, vue.toDisplayString(_ctx.currentPetInfo.petName), 1 /* TEXT */ ), _ctx.currentPetInfo.petGender === "M" ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "pm-gender" }, [ vue.createElementVNode("text", { class: "gender-icon" }, "♂"), vue.createElementVNode("text", null, "公") ])) : _ctx.currentPetInfo.petGender === "F" ? (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "pm-gender female" }, [ vue.createElementVNode("text", { class: "gender-icon" }, "♀"), vue.createElementVNode("text", null, "母") ])) : vue.createCommentVNode("v-if", true) ]), vue.createElementVNode( "text", { class: "pm-breed" }, "品种:" + vue.toDisplayString(_ctx.currentPetInfo.petBreed), 1 /* TEXT */ ) ]) ]), vue.createElementVNode("view", { class: "pm-detail-grid" }, [ vue.createElementVNode("view", { class: "pm-grid-item half" }, [ vue.createElementVNode("text", { class: "pm-label" }, "年龄"), vue.createElementVNode( "text", { class: "pm-val" }, vue.toDisplayString(_ctx.currentPetInfo.petAge || "未知"), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "pm-grid-item half" }, [ vue.createElementVNode("text", { class: "pm-label" }, "体重"), vue.createElementVNode( "text", { class: "pm-val" }, vue.toDisplayString(_ctx.currentPetInfo.petWeight || "未知"), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "pm-grid-item full" }, [ vue.createElementVNode("text", { class: "pm-label" }, "性格"), vue.createElementVNode( "text", { class: "pm-val" }, vue.toDisplayString(_ctx.currentPetInfo.petPersonality || "无"), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "pm-grid-item full" }, [ vue.createElementVNode("text", { class: "pm-label" }, "爱好"), vue.createElementVNode( "text", { class: "pm-val" }, vue.toDisplayString(_ctx.currentPetInfo.petHobby || "无"), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "pm-grid-item full" }, [ vue.createElementVNode("text", { class: "pm-label" }, "备注"), vue.createElementVNode( "text", { class: "pm-val" }, vue.toDisplayString(_ctx.currentPetInfo.petRemark || "无特殊过敏史"), 1 /* TEXT */ ) ]) ]), _ctx.currentPetInfo.petTags && _ctx.currentPetInfo.petTags.length > 0 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "pm-tags" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.currentPetInfo.petTags, (tag, index) => { return vue.openBlock(), vue.createElementBlock( "view", { class: "pm-tag", key: index }, vue.toDisplayString(tag), 1 /* TEXT */ ); }), 128 /* KEYED_FRAGMENT */ )) ])) : vue.createCommentVNode("v-if", true), vue.createElementVNode("view", { class: "pm-section-title" }, [ vue.createElementVNode("view", { class: "orange-bar" }), vue.createElementVNode("text", null, "备注日志") ]), vue.createElementVNode("view", { class: "pm-log-list" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.currentPetInfo.petLogs, (log, lIndex) => { return vue.openBlock(), vue.createElementBlock("view", { class: "pm-log-item", key: lIndex }, [ vue.createElementVNode( "text", { class: "pm-log-date" }, vue.toDisplayString(log.date), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "pm-log-text" }, vue.toDisplayString(log.content), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "pm-log-recorder" }, vue.toDisplayString(log.recorder === "系统记录" ? "" : "记录人: ") + vue.toDisplayString(log.recorder), 1 /* TEXT */ ) ]); }), 128 /* KEYED_FRAGMENT */ )) ]), vue.createElementVNode("view", { style: { "height": "30rpx" } }) ]) ]) ])) : vue.createCommentVNode("v-if", true), _ctx.showRemarkInput ? (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "remark-mask", onClick: _cache[17] || (_cache[17] = (...args) => _ctx.closeRemarkInput && _ctx.closeRemarkInput(...args)) }, [ vue.createElementVNode("view", { class: "remark-sheet", onClick: _cache[16] || (_cache[16] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("view", { class: "remark-sheet-header" }, [ vue.createElementVNode("text", { class: "remark-sheet-title" }, "添加备注"), vue.createElementVNode("view", { class: "close-icon-btn", onClick: _cache[13] || (_cache[13] = (...args) => _ctx.closeRemarkInput && _ctx.closeRemarkInput(...args)) }, "×") ]), vue.withDirectives(vue.createElementVNode( "textarea", { class: "remark-textarea", "onUpdate:modelValue": _cache[14] || (_cache[14] = ($event) => _ctx.remarkText = $event), placeholder: "请输入备注内容...", maxlength: "500", "auto-height": "" }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, _ctx.remarkText] ]), vue.createElementVNode("view", { class: "remark-submit-btn", onClick: _cache[15] || (_cache[15] = (...args) => _ctx.submitRemark && _ctx.submitRemark(...args)) }, "提交备注") ]) ])) : vue.createCommentVNode("v-if", true), _ctx.showNavModal ? (vue.openBlock(), vue.createElementBlock("view", { key: 2, class: "nav-modal-mask", onClick: _cache[23] || (_cache[23] = (...args) => _ctx.closeNavModal && _ctx.closeNavModal(...args)) }, [ vue.createElementVNode("view", { class: "nav-action-sheet", onClick: _cache[22] || (_cache[22] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("view", { class: "nav-sheet-title" }, "选择地图进行导航"), vue.createElementVNode("view", { class: "nav-sheet-item", onClick: _cache[18] || (_cache[18] = ($event) => _ctx.chooseMap("高德")) }, "高德地图"), vue.createElementVNode("view", { class: "nav-sheet-item", onClick: _cache[19] || (_cache[19] = ($event) => _ctx.chooseMap("腾讯")) }, "腾讯地图"), vue.createElementVNode("view", { class: "nav-sheet-item", onClick: _cache[20] || (_cache[20] = ($event) => _ctx.chooseMap("百度")) }, "百度地图"), vue.createElementVNode("view", { class: "nav-sheet-gap" }), vue.createElementVNode("view", { class: "nav-sheet-item cancel", onClick: _cache[21] || (_cache[21] = (...args) => _ctx.closeNavModal && _ctx.closeNavModal(...args)) }, "取消") ]) ])) : vue.createCommentVNode("v-if", true), vue.createVNode(_component_custom_tabbar, { currentPath: "pages/orders/index" }) ], 64 /* STABLE_FRAGMENT */ ); } const PagesOrdersIndex = /* @__PURE__ */ _export_sfc(_sfc_main$s, [["render", _sfc_render$r], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/orders/index.vue"]]); function getOrderStats() { return request({ url: "/order/subOrderLog/count", method: "GET" }); } function getOrderLogs(orderId) { return request({ url: `/order/subOrderLog/list?orderId=${orderId}`, method: "GET" }); } function uploadAnamaly(data) { return request({ url: "/fulfiller/anamaly/upload", method: "POST", data }); } function getAnomalyList(orderId) { return request({ url: `/fulfiller/anamaly/listOnOrder?orderId=${orderId}`, method: "GET" }); } function getDictDataByType(dictType) { return request({ url: `/system/dict/data/type/${dictType}`, method: "GET" }); } function getPetDetail(id) { return request({ url: `/archieves/pet/${id}`, method: "GET" }); } function submitPetRemark(data) { return request({ url: "/archieves/pet/remark", method: "POST", data }); } function listChangeLog(params) { return request({ url: "/archieves/changeLog/listAll", method: "GET", data: params }); } const logic$1 = { data() { return { orderId: null, pageLoading: true, // 页面数据加载中 orderType: 1, orderStatus: 2, serviceId: null, // 当前订单的服务类型ID serviceMode: null, // 当前订单的服务模式 (0: 喂遛/洗护, 1: 接送) petId: null, // 当前订单关联的宠物ID petDetail: null, // 宠物档案详情 // 从后端 clockInRemark 解析出的打卡步骤列表 // 格式: [{step:1, title:'到达打卡', remark:'照片视频二选一即可'}, ...] clockInSteps: [], // 当前应执行的打卡信息(从 clockInSteps 中取出) currentClockIn: null, currentStep: 0, orderDetail: { type: 1, price: "0.00", timeLabel: "服务时间", time: "", petAvatar: "/static/dog.png", petName: "", petBreed: "", serviceTag: "", startLocation: "", startAddress: "", endAddress: "", customerPhone: "", serviceContent: "", remark: "", orderNo: "", createTime: "", serviceName: "", // 服务类型名称 progressLogs: [], nursingSummary: "" // 宠护小结 }, serviceList: [], showPetModal: false, currentPetInfo: {}, showNavModal: false, navTargetPointType: "", showUploadModal: false, modalMediaList: [], modalRemark: "", showSumModal: false, sumContent: "", sumDate: "", sumSigner: "未知", showPetRemarkInput: false, petRemarkText: "", showAnomalyModal: false, anomalyList: [], anomalyTypeDict: [], // 媒体预览相关 videoPlayerShow: false, videoPlayerUrl: "" }; }, computed: { // 从 clockInSteps 中提取 title 数组作为打卡步骤名(内部逻辑用) steps() { if (this.clockInSteps.length > 0) { return this.clockInSteps.map((s) => s.title); } return this.orderType === 1 ? ["到达打卡", "确认出发", "送达打卡"] : ["到达打卡", "开始服务", "服务结束"]; }, // 顶部进度条展示用:已接单 -> 各打卡步骤 -> 订单完成 progressSteps() { return ["已接单", ...this.steps, "订单完成"]; }, // 进度条当前激活索引(= currentStep + 1,因为首位是"已接单") progressIndex() { return this.currentStep + 1; }, displayStatusText() { if (this.currentStep >= this.steps.length) return "已完成"; if (this.currentStep > 0) { return this.orderType === 1 ? "配送中" : "服务中"; } return this.orderType === 1 ? "待接送" : "待服务"; }, currentStatusText() { return this.currentStep >= this.steps.length ? "已完成" : this.steps[this.currentStep]; }, // 按钮文本:使用 clockInSteps 中对应步骤的 title currentTaskTitle() { if (this.currentStep >= this.steps.length) return "订单已完成"; if (this.currentClockIn) { return this.currentClockIn.title; } return this.steps[this.currentStep] || "打卡"; }, // 任务描述小字:使用 clockInSteps 中对应步骤的 remark currentTaskDesc() { if (this.currentStep >= this.steps.length) return "感谢您的服务,请注意休息"; if (this.currentClockIn && this.currentClockIn.remark) { return this.currentClockIn.remark; } return "请按要求提交照片或视频及备注"; } }, async onLoad(options) { if (options.id) { this.orderId = options.id; } this.pageLoading = true; reportGps(true).catch((e) => formatAppLog("log", "at pages/orders/detail-logic.js:140", "Init GPS check skipped", e)); try { await this.loadAnomalyTypeDict(); await this.loadServiceList(); await this.loadOrderDetail(); } finally { this.pageLoading = false; } }, methods: { async loadServiceList() { try { const res = await listAllService(); this.serviceList = res.data || []; } catch (err) { formatAppLog("error", "at pages/orders/detail-logic.js:159", "获取服务类型失败:", err); } }, /** * 根据服务类型ID获取服务详情,解析 clockInRemark 为打卡步骤 */ /** * 基于已加载的 serviceList 进行前端匹配,解析 clockInRemark 为打卡步骤 */ loadServiceDetail(serviceId) { formatAppLog("log", "at pages/orders/detail-logic.js:169", "前端匹配服务详情, ID:", serviceId); const serviceInfo = (this.serviceList || []).find((s) => s.id === serviceId); formatAppLog("log", "at pages/orders/detail-logic.js:171", "匹配到的服务信息:", serviceInfo); if (serviceInfo) { this.serviceMode = serviceInfo.mode; this.orderDetail.serviceName = serviceInfo.name; formatAppLog("log", "at pages/orders/detail-logic.js:175", "当前服务模式(mode):", this.serviceMode); if (serviceInfo.clockInRemark) { try { const parsed = JSON.parse(serviceInfo.clockInRemark); if (Array.isArray(parsed) && parsed.length > 0) { this.clockInSteps = parsed; formatAppLog("log", "at pages/orders/detail-logic.js:181", "解析打卡步骤:", this.clockInSteps); } } catch (parseErr) { formatAppLog("error", "at pages/orders/detail-logic.js:184", "解析 clockInRemark 失败:", parseErr); } } } }, async loadOrderDetail() { if (!this.orderId) { formatAppLog("log", "at pages/orders/detail-logic.js:191", "订单ID缺失"); uni.showToast({ title: "订单ID缺失", icon: "none" }); return; } try { formatAppLog("log", "at pages/orders/detail-logic.js:196", "请求订单详情,ID:", this.orderId); const res = await getOrderInfo(this.orderId); formatAppLog("log", "at pages/orders/detail-logic.js:198", "订单详情响应:", res); const order = res.data; if (!order) { formatAppLog("log", "at pages/orders/detail-logic.js:201", "订单数据为空"); uni.showToast({ title: "订单不存在", icon: "none" }); return; } formatAppLog("log", "at pages/orders/detail-logic.js:205", "订单数据:", order); this.serviceId = order.service; this.petId = order.usrPet || null; this.transformOrderData(order); formatAppLog("log", "at pages/orders/detail-logic.js:209", "解析出的 serviceId:", this.serviceId); if (this.serviceId) { this.loadServiceDetail(this.serviceId); } else { formatAppLog("warn", "at pages/orders/detail-logic.js:215", "订单中未找到 service 字段,无法加载服务步骤"); } if (this.petId) { await this.loadPetDetail(this.petId); } await this.loadOrderLogs(); } catch (err) { formatAppLog("error", "at pages/orders/detail-logic.js:226", "获取订单详情失败:", err); uni.showToast({ title: "加载失败", icon: "none" }); } }, async loadOrderLogs() { try { const res = await getOrderLogs(this.orderId); const logs = res.data || []; formatAppLog("log", "at pages/orders/detail-logic.js:234", "订单日志:", logs); const progressLogs = logs.filter((log) => log.logType === 1); this.orderDetail.progressLogs = progressLogs.map((log) => ({ status: log.title || "", time: log.createTime || "", medias: log.photoUrls || [], remark: log.content || "" })); const validLogs = logs.filter((log) => log.logType === 1 && log.step !== void 0 && log.step !== null).sort((a, b) => new Date(b.createTime).getTime() - new Date(a.createTime).getTime()); if (validLogs.length > 0) { const latestLog = validLogs[0]; const latestStep = latestLog.step; formatAppLog("log", "at pages/orders/detail-logic.js:253", "最新打卡日志 step:", latestStep); const stepIndex = this.clockInSteps.findIndex((s) => s.step === latestStep); if (stepIndex >= 0) { this.currentStep = stepIndex + 1; } else { this.currentStep = Number(latestStep); } } else { this.currentStep = 0; } this.updateCurrentClockIn(); formatAppLog("log", "at pages/orders/detail-logic.js:269", "根据最新日志推算的当前步骤:", this.currentStep, "当前打卡信息:", this.currentClockIn); } catch (err) { formatAppLog("error", "at pages/orders/detail-logic.js:271", "获取订单日志失败:", err); } }, /** * 根据 currentStep 更新当前打卡信息 */ updateCurrentClockIn() { if (this.currentStep < this.clockInSteps.length) { this.currentClockIn = this.clockInSteps[this.currentStep]; } else { this.currentClockIn = null; } }, transformOrderData(order) { const mode = order.mode || 0; const isRoundTrip = mode === 1; this.orderType = isRoundTrip ? 1 : 2; this.orderStatus = order.status || 2; this.orderDetail = { type: this.orderType, price: (order.price / 100).toFixed(2), timeLabel: isRoundTrip ? "取货时间" : "服务时间", time: order.serviceTime || "", petAvatar: "/static/dog.png", petName: order.petName || order.contact || "", petBreed: order.breed || "", serviceTag: order.groupPurchasePackageName || "", startLocation: order.fromAddress || "暂无起点", startAddress: order.fromAddress || "", fromAddress: order.fromAddress || "", fromLat: order.fromLat, fromLng: order.fromLng, endLocation: (order.contact || "") + " " + (order.contactPhoneNumber || ""), endAddress: order.toAddress || "", toAddress: order.toAddress || "", toLat: order.toLat, toLng: order.toLng, customerPhone: order.contactPhoneNumber || "", ownerName: order.contact || "", // 宠主姓名(默认使用客户姓名) serviceContent: "", remark: "", orderNo: order.code || "T" + order.id, createTime: order.serviceTime || "", nursingSummary: order.nursingSummary || "", fulfillerName: order.fulfillerName || "", // 履约者/护宠师姓名 progressLogs: [ { status: "您已接单", time: order.serviceTime || "" } ] }; if (this.orderDetail.fulfillerName) { this.sumSigner = this.orderDetail.fulfillerName; } }, /** * 根据宠物ID获取宠物档案详情 */ async loadPetDetail(petId) { try { const res = await getPetDetail(petId); const pet = res.data; if (pet) { this.petDetail = pet; this.orderDetail.petAvatar = pet.avatarUrl || "/static/dog.png"; this.orderDetail.petName = pet.name || this.orderDetail.petName; this.orderDetail.petBreed = pet.breed || this.orderDetail.petBreed; this.orderDetail.ownerName = pet.ownerName || this.orderDetail.ownerName; formatAppLog("log", "at pages/orders/detail-logic.js:342", "宠物档案:", pet); } } catch (err) { formatAppLog("error", "at pages/orders/detail-logic.js:345", "获取宠物档案失败:", err); } }, /** * 加载异常记录列表 */ async loadAnomalyList() { if (!this.orderId) return; try { const res = await getAnomalyList(this.orderId); const list = res.data || []; this.anomalyList = list.map((item) => { const dict = this.anomalyTypeDict.find((d) => d.value === item.type); return { ...item, typeLabel: dict ? dict.label : item.type, // 确保有图片数组供展示,如果后端没返 photoUrls,尝试兼容 photoUrls: item.photoUrls || [] }; }); } catch (err) { formatAppLog("error", "at pages/orders/detail-logic.js:368", "获取异常列表失败:", err); } }, async loadAnomalyTypeDict() { try { const res = await getDictDataByType("flf_anamaly_type"); this.anomalyTypeDict = res.data.map((item) => ({ label: item.dictLabel, value: item.dictValue })); } catch (err) { formatAppLog("error", "at pages/orders/detail-logic.js:379", "获取异常字典失败:", err); } }, openAnomalyModal() { this.showAnomalyModal = true; this.loadAnomalyList(); }, closeAnomalyModal() { this.showAnomalyModal = false; }, getAnomalyStatusLabel(status) { const map = { 0: "待审核", 1: "已通过", 2: "已驳回" }; return map[status] || "未知"; }, updateStepByStatus() { if (this.orderStatus === 2) { this.currentStep = 0; } else if (this.orderStatus === 3) { this.currentStep = 1; } else if (this.orderStatus === 4) { this.currentStep = this.steps.length - 1; } else { this.currentStep = 0; } }, showPetProfile() { const pet = this.petDetail; if (pet) { this.currentPetInfo = { petAvatar: pet.avatarUrl || "/static/dog.png", petName: pet.name || "", petBreed: pet.breed || "", petGender: pet.gender === 1 ? "M" : pet.gender === 2 ? "F" : "", petAge: pet.age ? pet.age + "岁" : "未知", petWeight: pet.weight ? pet.weight + "kg" : "未知", petPersonality: pet.personality || pet.cutePersonality || "无", petHobby: "", petRemark: pet.remark || "无", petTags: (pet.tags || []).map((t) => t.name), petLogs: [], // 额外信息 petSize: pet.size || "", petIsSterilized: pet.isSterilized, petHealthStatus: pet.healthStatus || "", petAllergies: pet.allergies || "", petMedicalHistory: pet.medicalHistory || "", petVaccineStatus: pet.vaccineStatus || "", ownerName: pet.ownerName || "", ownerPhone: pet.ownerPhone || "" }; this.loadPetChangeLogs(pet.id); } else { this.currentPetInfo = { ...this.orderDetail, petGender: "", petAge: "未知", petWeight: "未知", petPersonality: "无", petHobby: "", petRemark: "无", petTags: [], petLogs: [] }; } this.showPetModal = true; }, async loadPetChangeLogs(petId) { if (!petId) return; try { const res = await listChangeLog({ targetId: petId, targetType: "pet" }); const logs = res.data || []; this.currentPetInfo.petLogs = logs.map((item) => ({ date: item.createTime || "", content: item.content || "", recorder: item.operatorName || "未知" })); } catch (err) { formatAppLog("error", "at pages/orders/detail-logic.js:466", "获取宠物备注列表失败:", err); } }, closePetProfile() { this.showPetModal = false; }, openPetRemarkInput() { this.petRemarkText = ""; this.showPetRemarkInput = true; }, closePetRemarkInput() { this.showPetRemarkInput = false; }, async submitPetRemark() { if (!this.petRemarkText.trim()) { uni.showToast({ title: "备注内容不能为空", icon: "none" }); return; } if (!this.petId) { uni.showToast({ title: "宠物信息缺失", icon: "none" }); return; } uni.showLoading({ title: "提交中...", mask: true }); try { await submitPetRemark({ petId: this.petId, content: this.petRemarkText }); uni.hideLoading(); uni.showToast({ title: "备注已添加", icon: "success" }); this.closePetRemarkInput(); this.loadPetChangeLogs(this.petId); } catch (err) { uni.hideLoading(); formatAppLog("error", "at pages/orders/detail-logic.js:504", "提交宠物备注失败:", err); } }, goToAnomaly() { uni.navigateTo({ url: "/pages/orders/anomaly?orderId=" + (this.orderId || "") }); }, /** * 拨打电话 (带授权引导) */ callPhone() { const phoneNum = this.orderDetail.customerPhone || "18900008451"; if (!phoneNum) { uni.showToast({ title: "手机号不存在", icon: "none" }); return; } uni.showModal({ title: "拨号提示", content: `系统将为您拨打手机号: ${phoneNum},请授予拨号权限以正常通话。`, confirmText: "呼叫", cancelText: "取消", success: (res) => { if (res.confirm) { uni.makePhoneCall({ phoneNumber: phoneNum, fail: (err) => { formatAppLog("error", "at pages/orders/detail-logic.js:533", "拨号失败:", err); uni.showToast({ title: "无法唤起拨号盘,请检查权限设置", icon: "none" }); } }); } } }); }, openNavigation(type) { this.navTargetPointType = type; this.showNavModal = true; }, closeNavModal() { this.showNavModal = false; }, chooseMap(mapType) { let pointType = this.navTargetPointType; let name = pointType === "start" ? this.orderDetail.fromAddress || "起点" : this.orderDetail.toAddress || "终点"; let address = pointType === "start" ? this.orderDetail.fromAddress || "起点地址" : this.orderDetail.toAddress || "终点地址"; let latitude = pointType === "start" ? Number(this.orderDetail.fromLat) : Number(this.orderDetail.toLat); let longitude = pointType === "start" ? Number(this.orderDetail.fromLng) : Number(this.orderDetail.toLng); this.showNavModal = false; const navigateTo = (lat, lng, addrName, addrDesc) => { uni.openLocation({ latitude: lat, longitude: lng, name: addrName, address: addrDesc || "无法获取详细地址", success: function() { formatAppLog("log", "at pages/orders/detail-logic.js:567", "打开导航成功: " + mapType); }, fail: function(err) { formatAppLog("error", "at pages/orders/detail-logic.js:570", "打开导航失败:", err); uni.showToast({ title: "打开地图失败", icon: "none" }); } }); }; if (latitude && longitude && !isNaN(latitude) && !isNaN(longitude)) { navigateTo(latitude, longitude, name, address); } else { uni.showLoading({ title: "获取当前位置...", mask: true }); reportGps(true).then((res) => { uni.hideLoading(); navigateTo(res.latitude, res.longitude, name, address); }).catch((err) => { uni.hideLoading(); formatAppLog("error", "at pages/orders/detail-logic.js:588", "获取地理位置失败:", err); }); } }, openUploadModal() { this.modalMediaList = []; this.modalRemark = ""; this.showUploadModal = true; }, closeUploadModal() { this.showUploadModal = false; }, handleConfirmUpload() { formatAppLog("log", "at pages/orders/detail-logic.js:602", "handleConfirmUpload被调用"); this.confirmUploadModal(); }, async chooseModalMedia() { formatAppLog("log", "at pages/orders/detail-logic.js:606", "chooseModalMedia被调用"); uni.chooseMedia({ count: 5 - this.modalMediaList.length, mediaType: ["image", "video"], sourceType: ["album", "camera"], success: async (res) => { formatAppLog("log", "at pages/orders/detail-logic.js:613", "选择媒体文件成功:", res.tempFiles); uni.showLoading({ title: "上传中...", mask: true }); try { for (const file of res.tempFiles) { const filePath = file.tempFilePath; const fileType = file.fileType; formatAppLog("log", "at pages/orders/detail-logic.js:619", "开始上传文件:", filePath, "类型:", fileType); const uploadRes = await uploadFile(filePath); formatAppLog("log", "at pages/orders/detail-logic.js:622", "服务器响应:", uploadRes); if (uploadRes.code === 200) { this.modalMediaList.push({ url: uploadRes.data.url, ossId: uploadRes.data.ossId, localPath: filePath, mediaType: fileType, thumb: file.thumbTempFilePath // 视频缩略图(如果有) }); formatAppLog("log", "at pages/orders/detail-logic.js:632", "媒体文件添加成功"); } } uni.hideLoading(); uni.showToast({ title: "上传成功", icon: "success" }); } catch (err) { uni.hideLoading(); formatAppLog("error", "at pages/orders/detail-logic.js:639", "上传失败详情:", err); uni.showToast({ title: "上传失败", icon: "none" }); } }, fail: (err) => { formatAppLog("error", "at pages/orders/detail-logic.js:644", "选择媒体文件失败:", err); } }); }, removeModalMedia(index) { this.modalMediaList.splice(index, 1); }, getCurrentTime() { const now = /* @__PURE__ */ new Date(); const y = now.getFullYear(); const m = String(now.getMonth() + 1).padStart(2, "0"); const d = String(now.getDate()).padStart(2, "0"); const h = String(now.getHours()).padStart(2, "0"); const min = String(now.getMinutes()).padStart(2, "0"); return `${y}/${m}/${d} ${h}:${min}`; }, async confirmUploadModal() { formatAppLog("log", "at pages/orders/detail-logic.js:662", "confirmUploadModal被调用,文件数量:", this.modalMediaList.length); if (this.modalMediaList.length === 0) { uni.showToast({ title: "请上传至少一张图片或视频", icon: "none" }); return; } try { uni.showLoading({ title: "提交中..." }); const uploadedMedias = this.modalMediaList.map((item) => item.url); const ossIds = this.modalMediaList.map((item) => item.ossId); formatAppLog("log", "at pages/orders/detail-logic.js:673", "准备打卡,ossIds:", ossIds); const clockInType = this.currentClockIn ? this.currentClockIn.step : this.currentStep + 1; const clockInData = { orderId: this.orderId, photos: ossIds, content: this.modalRemark || "", step: clockInType, title: this.currentTaskTitle, startFlag: Number(clockInType) === 1, endFlag: Number(this.currentStep) === this.steps.length - 1 }; formatAppLog("log", "at pages/orders/detail-logic.js:688", "打卡数据:", clockInData); await clockIn(clockInData); uni.hideLoading(); this.closeUploadModal(); uni.showToast({ title: "打卡成功", icon: "success" }); await this.loadOrderDetail(); } catch (err) { uni.hideLoading(); formatAppLog("error", "at pages/orders/detail-logic.js:698", "打卡失败:", err); uni.showToast({ title: "打卡失败,请重试", icon: "none" }); } }, copyOrderNo() { uni.setClipboardData({ data: this.orderDetail.orderNo, success: () => { uni.showToast({ title: "复制成功", icon: "none" }); } }); }, openSumModal() { let displayDate = ""; if (this.orderDetail.time) { displayDate = this.orderDetail.time.split(" ")[0].replace(/-/g, "/"); } else { const now = /* @__PURE__ */ new Date(); const y = now.getFullYear(); const m = String(now.getMonth() + 1).padStart(2, "0"); const d = String(now.getDate()).padStart(2, "0"); displayDate = `${y}/${m}/${d}`; } this.sumDate = displayDate; if (this.orderDetail.nursingSummary) { this.sumContent = this.orderDetail.nursingSummary; } else if (!this.sumContent) { this.sumContent = "1. 精神/身体状态:\n2. 进食/饮水:\n3. 排泤情况:\n4. 卫生情况:\n5. 互动情况:\n6. 特殊情况/备注:"; } this.showSumModal = true; }, closeSumModal() { this.showSumModal = false; }, async submitSumModal() { if (!this.sumContent.trim()) { uni.showToast({ title: "请填写服务内容", icon: "none" }); return; } uni.showLoading({ title: "提交中...", mask: true }); try { const res = await submitNursingSummary({ orderId: this.orderId, content: this.sumContent }); uni.hideLoading(); if (res.code === 200) { uni.showToast({ title: "小结已提交", icon: "success" }); this.closeSumModal(); await this.loadOrderDetail(); } else { uni.showToast({ title: res.msg || "提交失败", icon: "none" }); } } catch (err) { uni.hideLoading(); formatAppLog("error", "at pages/orders/detail-logic.js:766", "提交宠护小结失败:", err); uni.showToast({ title: "提交失败,请重试", icon: "none" }); } }, /** * 检查是否为视频 */ isVideo(url) { if (!url) return false; const videoExts = [".mp4", ".mov", ".m4v", ".3gp", ".avi", ".wmv"]; const lowerUrl = url.toLowerCase(); return videoExts.some((ext) => lowerUrl.includes(ext)); }, /** * 获取视频封面图 (第一帧) * 兼容阿里云、腾讯云等主流 OSS */ getVideoPoster(url) { if (!this.isVideo(url)) return url; if (url.includes("?x-oss-process") || url.includes("?ci-process") || url.includes("?vframe")) { return url; } const aliyun = `?x-oss-process=video/snapshot,t_1,f_jpg,w_300,m_fast`; const tencent = `?ci-process=snapshot&time=1`; if (url.includes("myqcloud.com")) { return url + tencent; } return url + aliyun; }, /** * 统一预览媒体 */ previewMedia(medias, currentIdx) { const url = medias[currentIdx]; if (this.isVideo(url)) { this.videoPlayerUrl = url; this.videoPlayerShow = true; } else { const imageUrls = medias.filter((m) => !this.isVideo(m)); const currentImgUrl = url; const newIdx = imageUrls.indexOf(currentImgUrl); uni.previewImage({ current: newIdx >= 0 ? newIdx : 0, urls: imageUrls }); } }, closeVideoPlayer() { this.videoPlayerShow = false; this.videoPlayerUrl = ""; } } }; const _imports_12 = "/static/icons/phone_orange.svg"; const _imports_1$8 = "/static/icons/clock.svg"; const _imports_0$2 = "/static/icons/right_arrow_orange.svg"; const _imports_4$1 = "/static/icons/file.svg"; const _imports_1$7 = "/static/icons/camera_grey.svg"; const _imports_6$1 = "/static/icons/order_no.svg"; const _imports_7 = "/static/icons/play_circle.svg"; const _imports_8$1 = "/static/empty-rest.png"; const _sfc_main$r = { ...logic$1 }; function _sfc_render$q(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "detail-container" }, [ _ctx.pageLoading ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "loading-container" }, [ vue.createElementVNode("view", { class: "skeleton-header" }, [ vue.createElementVNode("view", { class: "skeleton-line skeleton-ani", style: { "width": "30%", "height": "36rpx" } }), vue.createElementVNode("view", { class: "skeleton-line skeleton-ani", style: { "width": "20%", "height": "36rpx" } }) ]), vue.createElementVNode("view", { class: "skeleton-progress" }, [ (vue.openBlock(), vue.createElementBlock( vue.Fragment, null, vue.renderList(4, (i) => { return vue.createElementVNode("view", { class: "skeleton-circle skeleton-ani", key: i }); }), 64 /* STABLE_FRAGMENT */ )) ]), (vue.openBlock(), vue.createElementBlock( vue.Fragment, null, vue.renderList(3, (j) => { return vue.createElementVNode("view", { class: "skeleton-card", key: "c" + j }, [ vue.createElementVNode("view", { class: "skeleton-line skeleton-ani", style: { "width": "60%", "height": "28rpx", "margin-bottom": "20rpx" } }), vue.createElementVNode("view", { class: "skeleton-line skeleton-ani", style: { "width": "90%", "height": "24rpx", "margin-bottom": "14rpx" } }), vue.createElementVNode("view", { class: "skeleton-line skeleton-ani", style: { "width": "75%", "height": "24rpx" } }) ]); }), 64 /* STABLE_FRAGMENT */ )) ])) : (vue.openBlock(), vue.createElementBlock( vue.Fragment, { key: 1 }, [ vue.createElementVNode("view", { class: "detail-header" }, [ vue.createElementVNode("view", { class: "status-row" }, [ vue.createElementVNode( "text", { class: "status-title" }, vue.toDisplayString(_ctx.displayStatusText), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "status-price" }, "¥" + vue.toDisplayString(_ctx.orderDetail.price), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "progress-bar" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.progressSteps, (step, index) => { return vue.openBlock(), vue.createElementBlock( "view", { class: vue.normalizeClass(["step-item", { "active": index === _ctx.progressIndex, "done": index < _ctx.progressIndex }]), key: index }, [ vue.createElementVNode("view", { class: "step-circle-wrapper" }, [ index !== 0 ? (vue.openBlock(), vue.createElementBlock( "view", { key: 0, class: vue.normalizeClass(["step-line", { "active-line": index <= _ctx.progressIndex }]) }, null, 2 /* CLASS */ )) : vue.createCommentVNode("v-if", true), vue.createElementVNode( "view", { class: "step-circle" }, vue.toDisplayString(index + 1), 1 /* TEXT */ ) ]), vue.createElementVNode( "text", { class: "step-text" }, vue.toDisplayString(step), 1 /* TEXT */ ) ], 2 /* CLASS */ ); }), 128 /* KEYED_FRAGMENT */ )) ]) ]), vue.createElementVNode("scroll-view", { "scroll-y": "", class: "detail-content" }, [ vue.createElementVNode("view", { class: "white-card pet-bar" }, [ vue.createElementVNode("image", { class: "pb-avatar", src: _ctx.orderDetail.petAvatar, mode: "aspectFill" }, null, 8, ["src"]), vue.createElementVNode("view", { class: "pb-info" }, [ vue.createElementVNode("view", { class: "pb-name-row" }, [ vue.createElementVNode( "text", { class: "pb-name" }, vue.toDisplayString(_ctx.orderDetail.petName), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "pb-tags" }, [ vue.createElementVNode( "text", { class: "pb-tag" }, vue.toDisplayString(_ctx.orderDetail.serviceName), 1 /* TEXT */ ) ]) ]), vue.createElementVNode("view", { class: "pb-actions" }, [ vue.createElementVNode("view", { class: "pb-btn profile-btn", onClick: _cache[0] || (_cache[0] = (...args) => _ctx.showPetProfile && _ctx.showPetProfile(...args)) }, "宠物档案"), vue.createElementVNode("view", { class: "pb-btn phone-btn", onClick: _cache[1] || (_cache[1] = (...args) => _ctx.callPhone && _ctx.callPhone(...args)) }, [ vue.createElementVNode("image", { class: "phone-icon", src: _imports_12 }) ]) ]) ]), vue.createElementVNode("view", { class: "white-card service-info-card" }, [ vue.createElementVNode("view", { class: "si-row time-row" }, [ vue.createElementVNode("image", { class: "si-icon outline", src: _imports_1$8 }), vue.createElementVNode("view", { class: "si-content" }, [ vue.createElementVNode("text", { class: "si-label" }, "服务时间"), vue.createElementVNode( "text", { class: "si-val" }, vue.toDisplayString(_ctx.orderDetail.time), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "si-action record-btn", onClick: _cache[2] || (_cache[2] = vue.withModifiers((...args) => _ctx.openAnomalyModal && _ctx.openAnomalyModal(...args), ["stop"])) }, [ vue.createElementVNode("text", null, "异常记录"), vue.createElementVNode("image", { class: "record-arrow", src: _imports_0$2 }) ]) ]), _ctx.orderDetail.type === 1 ? (vue.openBlock(), vue.createElementBlock( vue.Fragment, { key: 0 }, [ vue.createElementVNode("view", { class: "si-row addr-row start-addr" }, [ vue.createElementVNode("view", { class: "icon-circle start" }, "起"), vue.createElementVNode("view", { class: "route-line-vertical" }), vue.createElementVNode("view", { class: "si-content" }, [ vue.createElementVNode( "text", { class: "si-addr-title" }, vue.toDisplayString(_ctx.orderDetail.startLocation), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "si-addr-desc" }, vue.toDisplayString(_ctx.orderDetail.startAddress), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "nav-btn-circle", onClick: _cache[3] || (_cache[3] = ($event) => _ctx.openNavigation("start")) }, [ vue.createElementVNode("image", { class: "nav-arrow", src: _imports_3$2 }) ]) ]), vue.createElementVNode("view", { class: "si-row addr-row end-addr" }, [ vue.createElementVNode("view", { class: "icon-circle end" }, "终"), vue.createElementVNode("view", { class: "si-content" }, [ vue.createElementVNode( "text", { class: "si-addr-title" }, vue.toDisplayString(_ctx.orderDetail.endLocation), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "si-addr-desc" }, vue.toDisplayString(_ctx.orderDetail.endAddress), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "nav-btn-circle", onClick: _cache[4] || (_cache[4] = ($event) => _ctx.openNavigation("end")) }, [ vue.createElementVNode("image", { class: "nav-arrow", src: _imports_3$2 }) ]) ]) ], 64 /* STABLE_FRAGMENT */ )) : (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "si-row addr-row end-addr" }, [ vue.createElementVNode("view", { class: "icon-circle service" }, "服"), vue.createElementVNode("view", { class: "si-content" }, [ vue.createElementVNode( "text", { class: "si-addr-title" }, vue.toDisplayString(_ctx.orderDetail.endLocation), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "si-addr-desc" }, vue.toDisplayString(_ctx.orderDetail.endAddress), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "nav-btn-circle", onClick: _cache[5] || (_cache[5] = ($event) => _ctx.openNavigation("end")) }, [ vue.createElementVNode("image", { class: "nav-arrow", src: _imports_3$2 }) ]) ])), vue.createElementVNode("view", { class: "si-row" }, [ vue.createElementVNode("image", { class: "si-icon outline custom-icon-file", src: _imports_4$1 }), vue.createElementVNode("view", { class: "si-content" }, [ vue.createElementVNode("text", { class: "si-label" }, "备注"), vue.createElementVNode( "text", { class: "si-val" }, vue.toDisplayString(_ctx.orderDetail.remark || "无"), 1 /* TEXT */ ) ]) ]) ]), _ctx.currentStep < _ctx.steps.length ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "white-card task-card" }, [ vue.createElementVNode( "text", { class: "tc-title" }, "当前任务:" + vue.toDisplayString(_ctx.currentTaskTitle), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "tc-desc" }, vue.toDisplayString(_ctx.currentTaskDesc), 1 /* TEXT */ ), vue.createElementVNode("view", { class: "full-media-add", onClick: _cache[6] || (_cache[6] = (...args) => _ctx.openUploadModal && _ctx.openUploadModal(...args)) }, [ vue.createElementVNode("image", { class: "upload-icon-large", src: _imports_1$7 }), vue.createElementVNode("text", { class: "upload-text-large" }, "上传图或视频") ]) ])) : vue.createCommentVNode("v-if", true), vue.createElementVNode("view", { class: "white-card base-info-card" }, [ vue.createElementVNode("view", { class: "bi-row" }, [ vue.createElementVNode("image", { class: "si-icon outline", src: _imports_6$1 }), vue.createElementVNode("view", { class: "bi-content" }, [ vue.createElementVNode("text", { class: "bi-label" }, "订单编号"), vue.createElementVNode("view", { class: "bi-val-row" }, [ vue.createElementVNode( "text", { class: "bi-val" }, vue.toDisplayString(_ctx.orderDetail.orderNo), 1 /* TEXT */ ), vue.createElementVNode("text", { class: "bi-copy", onClick: _cache[7] || (_cache[7] = (...args) => _ctx.copyOrderNo && _ctx.copyOrderNo(...args)) }, "复制") ]) ]) ]), vue.createElementVNode("view", { class: "bi-row" }, [ vue.createElementVNode("image", { class: "si-icon outline", src: _imports_1$8 }), vue.createElementVNode("view", { class: "bi-content" }, [ vue.createElementVNode("text", { class: "bi-label" }, "下单时间"), vue.createElementVNode( "text", { class: "bi-val" }, vue.toDisplayString(_ctx.orderDetail.createTime), 1 /* TEXT */ ) ]) ]) ]), vue.createElementVNode("view", { class: "white-card timeline-card" }, [ vue.createElementVNode("view", { class: "tl-title-row" }, [ vue.createElementVNode("view", { class: "orange-bar" }), vue.createElementVNode("text", { class: "tl-title" }, "订单进度") ]), vue.createElementVNode("view", { class: "tl-list" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.orderDetail.progressLogs, (log, idx) => { return vue.openBlock(), vue.createElementBlock("view", { class: "tl-item", key: idx }, [ vue.createElementVNode("view", { class: "tl-marker active" }, [ vue.createElementVNode("view", { class: "tl-dot-inner" }) ]), vue.createElementVNode("view", { class: "tl-content-row" }, [ vue.createElementVNode("view", { class: "tl-header" }, [ vue.createElementVNode( "text", { class: "tl-status" }, vue.toDisplayString(log.status), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "tl-time" }, vue.toDisplayString(log.time), 1 /* TEXT */ ) ]), log.medias && log.medias.length > 0 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "tl-medias" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(log.medias, (media, midx) => { return vue.openBlock(), vue.createElementBlock("view", { class: "tl-media-item", key: midx, onClick: ($event) => _ctx.previewMedia(log.medias, midx) }, [ !_ctx.isVideo(media) ? (vue.openBlock(), vue.createElementBlock("image", { key: 0, class: "tl-img", src: media, mode: "aspectFill" }, null, 8, ["src"])) : (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "tl-video-placeholder" }, [ vue.createElementVNode("view", { class: "tl-play-icon" }), vue.createElementVNode("text", { class: "tl-video-label" }, "视频") ])) ], 8, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )) ])) : vue.createCommentVNode("v-if", true), log.remark ? (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "tl-remark" }, [ vue.createElementVNode( "text", null, vue.toDisplayString(log.remark), 1 /* TEXT */ ) ])) : vue.createCommentVNode("v-if", true) ]) ]); }), 128 /* KEYED_FRAGMENT */ )) ]) ]), vue.createElementVNode("view", { style: { "height": "140rpx" } }) ]), vue.createElementVNode("view", { class: "bottom-action-bar" }, [ vue.createElementVNode("view", { class: "action-left" }, [ vue.createElementVNode("button", { class: "action-btn outline grey-outline", onClick: _cache[8] || (_cache[8] = (...args) => _ctx.goToAnomaly && _ctx.goToAnomaly(...args)) }, "异常上报"), _ctx.serviceMode === 0 ? (vue.openBlock(), vue.createElementBlock("button", { key: 0, class: "action-btn outline orange-outline", onClick: _cache[9] || (_cache[9] = (...args) => _ctx.openSumModal && _ctx.openSumModal(...args)) }, "宠护小结")) : vue.createCommentVNode("v-if", true) ]), vue.createElementVNode("view", { class: "action-right" }, [ _ctx.currentStep < _ctx.steps.length ? (vue.openBlock(), vue.createElementBlock( "button", { key: 0, class: "action-btn primary", onClick: _cache[10] || (_cache[10] = (...args) => _ctx.openUploadModal && _ctx.openUploadModal(...args)) }, vue.toDisplayString(_ctx.currentTaskTitle), 1 /* TEXT */ )) : (vue.openBlock(), vue.createElementBlock("button", { key: 1, class: "action-btn primary grey-bg" }, "已完成")) ]) ]), _ctx.showPetModal ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "pet-modal-mask", onClick: _cache[14] || (_cache[14] = (...args) => _ctx.closePetProfile && _ctx.closePetProfile(...args)) }, [ vue.createElementVNode("view", { class: "pet-modal-content", onClick: _cache[13] || (_cache[13] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("view", { class: "pet-modal-header" }, [ vue.createElementVNode("text", { class: "pet-modal-title" }, "宠物档案"), vue.createElementVNode("view", { style: { "flex": "1" } }), vue.createElementVNode("view", { class: "pm-remark-btn", onClick: _cache[11] || (_cache[11] = (...args) => _ctx.openPetRemarkInput && _ctx.openPetRemarkInput(...args)) }, "备注"), vue.createElementVNode("view", { class: "close-icon-btn", onClick: _cache[12] || (_cache[12] = (...args) => _ctx.closePetProfile && _ctx.closePetProfile(...args)) }, "×") ]), vue.createElementVNode("scroll-view", { "scroll-y": "", class: "pet-modal-scroll" }, [ vue.createElementVNode("view", { class: "pet-base-info" }, [ vue.createElementVNode("image", { class: "pm-avatar", src: _ctx.currentPetInfo.petAvatar, mode: "aspectFill" }, null, 8, ["src"]), vue.createElementVNode("view", { class: "pm-info-text" }, [ vue.createElementVNode("view", { class: "pm-name-row" }, [ vue.createElementVNode( "text", { class: "pm-name" }, vue.toDisplayString(_ctx.currentPetInfo.petName), 1 /* TEXT */ ), _ctx.currentPetInfo.petGender === "M" ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "pm-gender" }, [ vue.createElementVNode("text", { class: "gender-icon" }, "♂"), vue.createElementVNode("text", null, "公") ])) : _ctx.currentPetInfo.petGender === "F" ? (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "pm-gender female" }, [ vue.createElementVNode("text", { class: "gender-icon" }, "♀"), vue.createElementVNode("text", null, "母") ])) : vue.createCommentVNode("v-if", true) ]), vue.createElementVNode( "text", { class: "pm-breed" }, "品种:" + vue.toDisplayString(_ctx.currentPetInfo.petBreed), 1 /* TEXT */ ) ]) ]), vue.createElementVNode("view", { class: "pm-detail-grid" }, [ vue.createElementVNode("view", { class: "pm-grid-item half" }, [ vue.createElementVNode("text", { class: "pm-label" }, "年龄"), vue.createElementVNode( "text", { class: "pm-val" }, vue.toDisplayString(_ctx.currentPetInfo.petAge || "未知"), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "pm-grid-item half" }, [ vue.createElementVNode("text", { class: "pm-label" }, "体重"), vue.createElementVNode( "text", { class: "pm-val" }, vue.toDisplayString(_ctx.currentPetInfo.petWeight || "未知"), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "pm-grid-item full" }, [ vue.createElementVNode("text", { class: "pm-label" }, "性格"), vue.createElementVNode( "text", { class: "pm-val" }, vue.toDisplayString(_ctx.currentPetInfo.petPersonality || "无"), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "pm-grid-item full" }, [ vue.createElementVNode("text", { class: "pm-label" }, "爱好"), vue.createElementVNode( "text", { class: "pm-val" }, vue.toDisplayString(_ctx.currentPetInfo.petHobby || "无"), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "pm-grid-item full" }, [ vue.createElementVNode("text", { class: "pm-label" }, "备注"), vue.createElementVNode( "text", { class: "pm-val" }, vue.toDisplayString(_ctx.currentPetInfo.petRemark || "无特殊过敏史"), 1 /* TEXT */ ) ]) ]), _ctx.currentPetInfo.petTags && _ctx.currentPetInfo.petTags.length > 0 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "pm-tags-row" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.currentPetInfo.petTags, (tag, ti) => { return vue.openBlock(), vue.createElementBlock("view", { class: "pm-tag-chip", key: ti }, [ vue.createElementVNode( "text", { class: "pm-tag-chip-text" }, vue.toDisplayString(tag), 1 /* TEXT */ ) ]); }), 128 /* KEYED_FRAGMENT */ )) ])) : vue.createCommentVNode("v-if", true), vue.createElementVNode("view", { class: "pm-log-section" }, [ vue.createElementVNode("view", { class: "pm-log-header" }, [ vue.createElementVNode("view", { style: { "width": "6rpx", "height": "28rpx", "background": "#FF9800", "border-radius": "3rpx", "margin-right": "12rpx" } }), vue.createElementVNode("text", { class: "pm-log-section-title" }, "备注日志") ]), (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.currentPetInfo.petLogs, (log, lIndex) => { return vue.openBlock(), vue.createElementBlock("view", { class: "pm-log-item", key: lIndex }, [ vue.createElementVNode( "text", { class: "pm-log-date" }, vue.toDisplayString(log.date), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "pm-log-text" }, vue.toDisplayString(log.content), 1 /* TEXT */ ), log.recorder !== "系统记录" ? (vue.openBlock(), vue.createElementBlock( "text", { key: 0, class: "pm-log-recorder" }, "记录人:" + vue.toDisplayString(log.recorder), 1 /* TEXT */ )) : (vue.openBlock(), vue.createElementBlock("text", { key: 1, class: "pm-log-recorder system" }, "系统记录")) ]); }), 128 /* KEYED_FRAGMENT */ )) ]), vue.createElementVNode("view", { style: { "height": "30rpx" } }) ]) ]) ])) : vue.createCommentVNode("v-if", true), _ctx.showPetRemarkInput ? (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "upload-modal-mask", onClick: _cache[18] || (_cache[18] = (...args) => _ctx.closePetRemarkInput && _ctx.closePetRemarkInput(...args)) }, [ vue.createElementVNode("view", { class: "upload-modal-content", onClick: _cache[17] || (_cache[17] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("view", { class: "um-header" }, [ vue.createElementVNode("text", { class: "um-title" }, "添加备注") ]), vue.createElementVNode("view", { class: "um-body" }, [ vue.withDirectives(vue.createElementVNode( "textarea", { class: "um-textarea", "onUpdate:modelValue": _cache[15] || (_cache[15] = ($event) => _ctx.petRemarkText = $event), "auto-height": "", placeholder: "请输入宠物备注内容...", "placeholder-style": "color:#ccc; font-size:26rpx;" }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, _ctx.petRemarkText] ]) ]), vue.createElementVNode("view", { class: "um-footer" }, [ vue.createElementVNode("button", { class: "um-submit-btn active", onClick: _cache[16] || (_cache[16] = (...args) => _ctx.submitPetRemark && _ctx.submitPetRemark(...args)) }, "确认提交") ]) ]) ])) : vue.createCommentVNode("v-if", true), _ctx.showNavModal ? (vue.openBlock(), vue.createElementBlock("view", { key: 2, class: "nav-modal-mask", onClick: _cache[24] || (_cache[24] = (...args) => _ctx.closeNavModal && _ctx.closeNavModal(...args)) }, [ vue.createElementVNode("view", { class: "nav-action-sheet", onClick: _cache[23] || (_cache[23] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("view", { class: "nav-sheet-title" }, "选择地图进行导航"), vue.createElementVNode("view", { class: "nav-sheet-item", onClick: _cache[19] || (_cache[19] = ($event) => _ctx.chooseMap("高德")) }, "高德地图"), vue.createElementVNode("view", { class: "nav-sheet-item", onClick: _cache[20] || (_cache[20] = ($event) => _ctx.chooseMap("腾讯")) }, "腾讯地图"), vue.createElementVNode("view", { class: "nav-sheet-item", onClick: _cache[21] || (_cache[21] = ($event) => _ctx.chooseMap("百度")) }, "百度地图"), vue.createElementVNode("view", { class: "nav-sheet-gap" }), vue.createElementVNode("view", { class: "nav-sheet-item cancel", onClick: _cache[22] || (_cache[22] = (...args) => _ctx.closeNavModal && _ctx.closeNavModal(...args)) }, "取消") ]) ])) : vue.createCommentVNode("v-if", true), _ctx.showUploadModal ? (vue.openBlock(), vue.createElementBlock("view", { key: 3, class: "upload-modal-mask", onClick: _cache[29] || (_cache[29] = (...args) => _ctx.closeUploadModal && _ctx.closeUploadModal(...args)) }, [ vue.createElementVNode("view", { class: "upload-modal-content", onClick: _cache[28] || (_cache[28] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("view", { class: "um-header" }, [ vue.createElementVNode( "text", { class: "um-title" }, "上传图或视频 (" + vue.toDisplayString(_ctx.modalMediaList.length) + "/5)", 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "um-remark-hint" }, vue.toDisplayString(_ctx.currentTaskDesc), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "um-body" }, [ vue.createElementVNode("view", { class: "um-grid" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.modalMediaList, (img, idx) => { return vue.openBlock(), vue.createElementBlock("view", { class: "um-item", key: idx }, [ vue.createElementVNode("image", { class: "um-preview", src: img.thumb || img.url || img.localPath || img, mode: "aspectFill" }, null, 8, ["src"]), img.mediaType === "video" ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "um-video-badge" }, [ vue.createElementVNode("image", { class: "play-icon-small", src: _imports_7 }) ])) : vue.createCommentVNode("v-if", true), vue.createElementVNode("view", { class: "um-del", onClick: ($event) => _ctx.removeModalMedia(idx) }, "×", 8, ["onClick"]) ]); }), 128 /* KEYED_FRAGMENT */ )), _ctx.modalMediaList.length < 5 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "um-add", onClick: _cache[25] || (_cache[25] = (...args) => _ctx.chooseModalMedia && _ctx.chooseModalMedia(...args)) }, [ vue.createElementVNode("image", { class: "um-add-icon", src: _imports_1$7 }), vue.createElementVNode("text", { class: "um-add-text" }, "拍摄/上传") ])) : vue.createCommentVNode("v-if", true) ]), vue.withDirectives(vue.createElementVNode( "textarea", { class: "um-textarea", "onUpdate:modelValue": _cache[26] || (_cache[26] = ($event) => _ctx.modalRemark = $event), placeholder: "在此输入备注信息...", "placeholder-style": "color:#ccc; font-size:26rpx;" }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, _ctx.modalRemark] ]) ]), vue.createElementVNode("view", { class: "um-footer" }, [ vue.createElementVNode( "view", { class: vue.normalizeClass(["um-submit-btn", { "active": _ctx.modalMediaList.length > 0 }]), onClick: _cache[27] || (_cache[27] = (...args) => _ctx.handleConfirmUpload && _ctx.handleConfirmUpload(...args)) }, " 确认提交", 2 /* CLASS */ ) ]) ]) ])) : vue.createCommentVNode("v-if", true), _ctx.showSumModal ? (vue.openBlock(), vue.createElementBlock("view", { key: 4, class: "sum-modal-mask", onClick: _cache[33] || (_cache[33] = (...args) => _ctx.closeSumModal && _ctx.closeSumModal(...args)) }, [ vue.createElementVNode("view", { class: "sum-modal-card", onClick: _cache[32] || (_cache[32] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("scroll-view", { "scroll-y": "", class: "sum-modal-scroll" }, [ vue.createElementVNode("view", { class: "sum-modal-inner" }, [ vue.createElementVNode("text", { class: "sum-modal-title" }, "宠物护理工作小结"), vue.createElementVNode("view", { class: "sum-meta-row" }, [ vue.createElementVNode("text", { class: "sum-meta-label" }, "日期:"), vue.createElementVNode( "text", { class: "sum-meta-val" }, vue.toDisplayString(_ctx.sumDate), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "sum-meta-row" }, [ vue.createElementVNode("text", { class: "sum-meta-label" }, "客户住址:"), vue.createElementVNode( "text", { class: "sum-meta-val" }, vue.toDisplayString(_ctx.orderDetail.endAddress), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "sum-meta-row" }, [ vue.createElementVNode("text", { class: "sum-meta-label" }, "宠主姓名:"), vue.createElementVNode( "text", { class: "sum-meta-val" }, vue.toDisplayString(_ctx.orderDetail.ownerName || "未知"), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "sum-section-title" }, "宠物信息"), vue.createElementVNode("view", { class: "sum-pet-card" }, [ vue.createElementVNode("image", { class: "sum-pet-avatar", src: _ctx.orderDetail.petAvatar, mode: "aspectFill" }, null, 8, ["src"]), vue.createElementVNode("view", { class: "sum-pet-info" }, [ vue.createElementVNode("view", { class: "sum-pet-name-row" }, [ vue.createElementVNode( "text", { class: "sum-pet-name" }, vue.toDisplayString(_ctx.orderDetail.petName || "未知"), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "sum-pet-breed" }, "品种: " + vue.toDisplayString(_ctx.orderDetail.petBreed || "未知"), 1 /* TEXT */ ) ]), vue.createElementVNode( "text", { class: "sum-pet-remark" }, vue.toDisplayString(_ctx.orderDetail.petNotes || "暂无备注"), 1 /* TEXT */ ) ]) ]), vue.createElementVNode("view", { class: "sum-section-title" }, "服务内容记录"), vue.withDirectives(vue.createElementVNode( "textarea", { class: "sum-textarea", "onUpdate:modelValue": _cache[30] || (_cache[30] = ($event) => _ctx.sumContent = $event), "auto-height": "", placeholder: "请填写服务内容...", "placeholder-style": "color:#ccc" }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, _ctx.sumContent] ]), vue.createElementVNode("view", { class: "sum-sign-row" }, [ vue.createElementVNode("text", { class: "sum-sign-label" }, "护宠师签名:"), vue.createElementVNode( "text", { class: "sum-sign-val" }, vue.toDisplayString(_ctx.sumSigner), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { style: { "height": "20rpx" } }) ]) ]), vue.createElementVNode("view", { class: "sum-footer" }, [ vue.createElementVNode("button", { class: "sum-submit-btn", onClick: _cache[31] || (_cache[31] = (...args) => _ctx.submitSumModal && _ctx.submitSumModal(...args)) }, "提交小结") ]) ]) ])) : vue.createCommentVNode("v-if", true), _ctx.showAnomalyModal ? (vue.openBlock(), vue.createElementBlock("view", { key: 5, class: "modal-mask", onClick: _cache[36] || (_cache[36] = (...args) => _ctx.closeAnomalyModal && _ctx.closeAnomalyModal(...args)) }, [ vue.createElementVNode("view", { class: "anomaly-modal-content", onClick: _cache[35] || (_cache[35] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("view", { class: "am-header" }, [ vue.createElementVNode("text", { class: "am-title" }, "历史异常记录"), vue.createElementVNode("view", { class: "close-icon-btn", onClick: _cache[34] || (_cache[34] = (...args) => _ctx.closeAnomalyModal && _ctx.closeAnomalyModal(...args)) }, "×") ]), vue.createElementVNode("scroll-view", { "scroll-y": "", class: "am-scroll-list" }, [ _ctx.anomalyList.length === 0 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "empty-list" }, [ vue.createElementVNode("image", { class: "empty-icon", src: _imports_8$1, mode: "aspectFit" }), vue.createElementVNode("text", { class: "empty-text" }, "暂无异常记录") ])) : vue.createCommentVNode("v-if", true), (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.anomalyList, (item, index) => { return vue.openBlock(), vue.createElementBlock("view", { class: "am-item", key: index }, [ vue.createElementVNode("view", { class: "am-item-header" }, [ vue.createElementVNode( "text", { class: "am-item-type" }, vue.toDisplayString(item.typeLabel), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: vue.normalizeClass(["am-item-status", "status-" + item.status]) }, vue.toDisplayString(_ctx.getAnomalyStatusLabel(item.status)), 3 /* TEXT, CLASS */ ) ]), vue.createElementVNode( "text", { class: "am-item-content" }, vue.toDisplayString(item.content), 1 /* TEXT */ ), item.photos && item.photos.length > 0 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "am-item-photos" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(item.photoUrls, (photoUrl, pIdx) => { return vue.openBlock(), vue.createElementBlock("view", { class: "am-photo-item", key: pIdx, onClick: ($event) => _ctx.previewMedia(item.photoUrls, pIdx) }, [ !_ctx.isVideo(photoUrl) ? (vue.openBlock(), vue.createElementBlock("image", { key: 0, class: "am-photo", src: photoUrl, mode: "aspectFill" }, null, 8, ["src"])) : (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "tl-video-placeholder miniaturized" }, [ vue.createElementVNode("view", { class: "tl-play-icon small" }), vue.createElementVNode("text", { class: "tl-video-label small" }, "视频") ])) ], 8, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )) ])) : vue.createCommentVNode("v-if", true), item.status !== 0 ? (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "am-audit-box" }, [ vue.createElementVNode("view", { class: "am-audit-header" }, [ vue.createElementVNode( "text", { class: "am-audit-label" }, vue.toDisplayString(item.status === 1 ? "审核通过" : "驳回理由"), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "am-audit-time" }, vue.toDisplayString(item.auditTime), 1 /* TEXT */ ) ]), vue.createElementVNode( "text", { class: "am-audit-remark" }, vue.toDisplayString(item.auditRemark || "无"), 1 /* TEXT */ ) ])) : vue.createCommentVNode("v-if", true) ]); }), 128 /* KEYED_FRAGMENT */ )) ]) ]) ])) : vue.createCommentVNode("v-if", true), _ctx.videoPlayerShow ? (vue.openBlock(), vue.createElementBlock("view", { key: 6, class: "video-player-mask", onClick: _cache[39] || (_cache[39] = (...args) => _ctx.closeVideoPlayer && _ctx.closeVideoPlayer(...args)) }, [ vue.createElementVNode("view", { class: "video-player-content", onClick: _cache[38] || (_cache[38] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("video", { class: "v-player", src: _ctx.videoPlayerUrl, autoplay: "", controls: "" }, null, 8, ["src"]), vue.createElementVNode("view", { class: "v-close", onClick: _cache[37] || (_cache[37] = (...args) => _ctx.closeVideoPlayer && _ctx.closeVideoPlayer(...args)) }, "×") ]) ])) : vue.createCommentVNode("v-if", true) ], 64 /* STABLE_FRAGMENT */ )) ]); } const PagesOrdersDetail = /* @__PURE__ */ _export_sfc(_sfc_main$r, [["render", _sfc_render$q], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/orders/detail.vue"]]); const _sfc_main$q = { data() { return { orderId: "", // 已选异常类型(dictValue) selectedTypeValue: "", // 已选异常类型标签(dictLabel,用于显示) selectedTypeLabel: "", // 异常描述 anomalyDesc: "", // 照片列表(含 url 和 ossId) photoList: [], // 是否显示类型选择器 showTypeSheet: false, // 异常类型字典列表(从后端获取) anomalyTypes: [] }; }, onLoad(options) { if (options.orderId) { this.orderId = options.orderId; } this.loadAnomalyTypes(); }, computed: { // 当前选中的类型显示文本 selectedType() { return this.selectedTypeLabel || ""; } }, methods: { /** * 加载异常类型字典数据 */ async loadAnomalyTypes() { try { const res = await getDictDataByType("flf_anamaly_type"); if (res.data && Array.isArray(res.data)) { this.anomalyTypes = res.data.map((item) => ({ label: item.dictLabel, value: item.dictValue, dictCode: item.dictCode })); formatAppLog("log", "at pages/orders/anomaly.vue:137", "异常类型字典:", this.anomalyTypes); } } catch (err) { formatAppLog("error", "at pages/orders/anomaly.vue:140", "获取异常类型字典失败:", err); } }, // 打开类型选择器 openTypeSheet() { this.showTypeSheet = true; }, // 关闭类型选择器 closeTypeSheet() { this.showTypeSheet = false; }, // 选择异常类型 selectType(type) { this.selectedTypeValue = type.value; this.selectedTypeLabel = type.label; this.closeTypeSheet(); }, // 选择照片并上传 choosePhoto() { uni.chooseImage({ count: 5 - this.photoList.length, sizeType: ["compressed"], sourceType: ["album", "camera"], success: async (res) => { uni.showLoading({ title: "上传中..." }); try { for (const filePath of res.tempFilePaths) { const uploadRes = await uploadFile(filePath); if (uploadRes.code === 200) { this.photoList.push({ url: uploadRes.data.url, ossId: uploadRes.data.ossId, localPath: filePath }); } } uni.hideLoading(); } catch (err) { uni.hideLoading(); formatAppLog("error", "at pages/orders/anomaly.vue:179", "上传失败:", err); uni.showToast({ title: "上传失败", icon: "none" }); } } }); }, // 删除照片 removePhoto(idx) { this.photoList.splice(idx, 1); }, // 提交上报 async submitAnomaly() { if (!this.selectedTypeValue) { uni.showToast({ title: "请选择异常类型", icon: "none" }); return; } if (this.photoList.length === 0) { uni.showToast({ title: "请上传现场照片", icon: "none" }); return; } const data = { orderId: this.orderId, type: this.selectedTypeValue, content: this.anomalyDesc, photos: this.photoList.map((p) => p.ossId) }; try { uni.showLoading({ title: "提交中..." }); await uploadAnamaly(data); uni.hideLoading(); uni.showToast({ title: "上报成功", icon: "success" }); setTimeout(() => { uni.navigateBack(); }, 1500); } catch (err) { uni.hideLoading(); formatAppLog("error", "at pages/orders/anomaly.vue:215", "异常上报失败:", err); uni.showToast({ title: "提交失败,请重试", icon: "none" }); } } } }; function _sfc_render$p(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "anomaly-container" }, [ vue.createElementVNode("scroll-view", { "scroll-y": "", class: "anomaly-scroll" }, [ vue.createElementVNode("view", { class: "ano-card" }, [ vue.createElementVNode("view", { class: "ano-section-title" }, [ vue.createElementVNode("view", { class: "ano-title-bar" }), vue.createElementVNode("text", { class: "ano-title-text" }, "异常类型") ]), vue.createElementVNode("view", { class: "ano-type-row", onClick: _cache[0] || (_cache[0] = (...args) => $options.openTypeSheet && $options.openTypeSheet(...args)) }, [ vue.createElementVNode( "text", { class: vue.normalizeClass(["ano-type-val", { "placeholder": !$options.selectedType }]) }, vue.toDisplayString($options.selectedType || "请选择异常类型"), 3 /* TEXT, CLASS */ ), vue.createElementVNode("image", { class: "ano-right-arrow", src: _imports_0$2 }) ]) ]), vue.createElementVNode("view", { class: "ano-card" }, [ vue.createElementVNode("view", { class: "ano-section-title" }, [ vue.createElementVNode("view", { class: "ano-title-bar" }), vue.createElementVNode("text", { class: "ano-title-text" }, "异常描述") ]), vue.withDirectives(vue.createElementVNode( "textarea", { class: "ano-textarea", "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => $data.anomalyDesc = $event), placeholder: "请详细描述现场异常情况...", "placeholder-style": "color:#ccc; font-size:28rpx;", maxlength: "500" }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, $data.anomalyDesc] ]) ]), vue.createElementVNode("view", { class: "ano-card" }, [ vue.createElementVNode("view", { class: "ano-section-title" }, [ vue.createElementVNode("view", { class: "ano-title-bar" }), vue.createElementVNode("text", { class: "ano-title-text" }, "现场照片 (必填,最多5张)") ]), vue.createElementVNode("view", { class: "ano-photo-grid" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($data.photoList, (img, idx) => { return vue.openBlock(), vue.createElementBlock("view", { class: "ano-photo-item", key: idx }, [ vue.createElementVNode("image", { class: "ano-photo-preview", src: img.url || img.localPath || img, mode: "aspectFill" }, null, 8, ["src"]), vue.createElementVNode("view", { class: "ano-photo-del", onClick: ($event) => $options.removePhoto(idx) }, "×", 8, ["onClick"]) ]); }), 128 /* KEYED_FRAGMENT */ )), $data.photoList.length < 5 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "ano-photo-add", onClick: _cache[2] || (_cache[2] = (...args) => $options.choosePhoto && $options.choosePhoto(...args)) }, [ vue.createElementVNode("image", { class: "ano-add-icon", src: _imports_1$7 }), vue.createElementVNode("text", { class: "ano-add-text" }, "上传") ])) : vue.createCommentVNode("v-if", true) ]) ]), vue.createElementVNode("view", { style: { "height": "160rpx" } }) ]), vue.createElementVNode("view", { class: "ano-footer" }, [ vue.createElementVNode("button", { class: "ano-submit-btn", onClick: _cache[3] || (_cache[3] = (...args) => $options.submitAnomaly && $options.submitAnomaly(...args)) }, "提交上报") ]), $data.showTypeSheet ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "ano-sheet-mask", onClick: _cache[6] || (_cache[6] = (...args) => $options.closeTypeSheet && $options.closeTypeSheet(...args)) }, [ vue.createElementVNode("view", { class: "ano-sheet", onClick: _cache[5] || (_cache[5] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("text", { class: "ano-sheet-title" }, "选择异常类型"), vue.createElementVNode("scroll-view", { "scroll-y": "", class: "ano-sheet-list" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($data.anomalyTypes, (type, idx) => { return vue.openBlock(), vue.createElementBlock("view", { class: "ano-sheet-item", key: idx, onClick: ($event) => $options.selectType(type) }, [ vue.createElementVNode( "text", { class: vue.normalizeClass(["ano-sheet-item-text", { "selected": $data.selectedTypeValue === type.value }]) }, vue.toDisplayString(type.label), 3 /* TEXT, CLASS */ ), $data.selectedTypeValue === type.value ? (vue.openBlock(), vue.createElementBlock("image", { key: 0, class: "ano-check-icon", src: _imports_0$2 })) : vue.createCommentVNode("v-if", true) ], 8, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )) ]), vue.createElementVNode("view", { class: "ano-sheet-cancel", onClick: _cache[4] || (_cache[4] = (...args) => $options.closeTypeSheet && $options.closeTypeSheet(...args)) }, "取消") ]) ])) : vue.createCommentVNode("v-if", true) ]); } const PagesOrdersAnomaly = /* @__PURE__ */ _export_sfc(_sfc_main$q, [["render", _sfc_render$p], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/orders/anomaly.vue"]]); const _sfc_main$p = { data() { return { tabs: ["全部", "已完成", "已拒绝"], activeTab: 0, stats: { total: 0, reject: 0, reward: 0, punish: 0 }, orders: [], serviceList: [], pageNum: 1, pageSize: 10, total: 0, loading: false }; }, computed: { filteredOrders() { return this.orders; } }, async onLoad() { await this.loadServiceList(); this.fetchStats(); this.fetchOrders(true); }, methods: { async loadServiceList() { try { const res = await listAllService(); this.serviceList = res.data || []; } catch (err) { formatAppLog("error", "at pages/mine/order-stats.vue:161", "获取服务类型失败:", err); } }, async fetchStats() { try { const res = await getOrderStats(); if (res.code === 200 && res.data) { this.stats = { ...this.stats, ...res.data }; } } catch (err) { formatAppLog("error", "at pages/mine/order-stats.vue:174", "获取统计值失败:", err); } }, async fetchOrders(reset = false) { if (reset) { this.pageNum = 1; this.orders = []; } if (this.loading) return; if (!reset && this.orders.length >= this.total && this.total !== 0) return; this.loading = true; try { const statusMap = { 0: void 0, 1: 4, 2: 5 }; const params = { status: statusMap[this.activeTab], pageNum: this.pageNum, pageSize: this.pageSize }; const res = await getStatisticOrders(params); if (res.code === 200) { this.total = res.total || 0; const rows = res.rows || []; const mapped = rows.map((item) => this.transformOrder(item)); this.orders = this.orders.concat(mapped); this.pageNum++; } } catch (err) { formatAppLog("error", "at pages/mine/order-stats.vue:202", "获取订单列表失败:", err); } finally { this.loading = false; } }, transformOrder(order) { const service = this.serviceList.find((s) => s.id === order.service); const mode = (service == null ? void 0 : service.mode) || 0; const isRoundTrip = mode === 1; const statusMap = { 0: { label: "待派单", color: "#f56c6c" }, 1: { label: "待接单", color: "#e6a23c" }, 2: { label: "待服务", color: "#49a3ff" }, 3: { label: "服务中", color: "#49a3ff" }, 4: { label: "已完成", color: "#67c23a" }, 5: { label: "已取消", color: "#909399" } }; const statusInfo = statusMap[order.status] || { label: "未知", color: "#999" }; return { id: order.id, orderType: isRoundTrip ? 1 : 2, typeName: (service == null ? void 0 : service.name) || "未知", typeIcon: (service == null ? void 0 : service.iconUrl) || "", statusLabel: statusInfo.label, statusColor: statusInfo.color, finishTime: order.serviceTime || "", serviceTime: order.serviceTime || "", petName: order.petName || "未知", petBreed: order.breed || "未知", petAvatar: order.petAvatarUrl || "/static/dog.png", price: (order.price / 100).toFixed(2), startName: order.fromAddress || "", startAddr: order.fromAddress || "", endName: (order.customerName || "") + " " + (order.customerPhone || ""), endAddr: order.toAddress || "", serviceNote: order.remark || "" }; }, switchTab(idx) { this.activeTab = idx; this.fetchOrders(true); }, onReachBottom() { this.fetchOrders(); }, navBack() { uni.navigateBack(); } } }; function _sfc_render$o(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "stats-banner" }, [ vue.createElementVNode("view", { class: "banner-item" }, [ vue.createElementVNode( "text", { class: "banner-num" }, vue.toDisplayString($data.stats.total), 1 /* TEXT */ ), vue.createElementVNode("text", { class: "banner-label" }, "累计接单") ]), vue.createElementVNode("view", { class: "banner-item" }, [ vue.createElementVNode( "text", { class: "banner-num" }, vue.toDisplayString($data.stats.reject), 1 /* TEXT */ ), vue.createElementVNode("text", { class: "banner-label" }, "累计拒单") ]), vue.createElementVNode("view", { class: "banner-item" }, [ vue.createElementVNode( "text", { class: "banner-num" }, vue.toDisplayString($data.stats.reward), 1 /* TEXT */ ), vue.createElementVNode("text", { class: "banner-label" }, "奖励单量") ]), vue.createElementVNode("view", { class: "banner-item" }, [ vue.createElementVNode( "text", { class: "banner-num" }, vue.toDisplayString($data.stats.punish), 1 /* TEXT */ ), vue.createElementVNode("text", { class: "banner-label" }, "惩罚单量") ]) ]), vue.createElementVNode("view", { class: "tab-bar" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($data.tabs, (tab, idx) => { return vue.openBlock(), vue.createElementBlock("view", { class: vue.normalizeClass(["tab-item", { active: $data.activeTab === idx }]), key: idx, onClick: ($event) => $options.switchTab(idx) }, [ vue.createElementVNode( "text", null, vue.toDisplayString(tab), 1 /* TEXT */ ), $data.activeTab === idx ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "tab-line" })) : vue.createCommentVNode("v-if", true) ], 10, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )) ]), vue.createElementVNode( "scroll-view", { "scroll-y": "", class: "order-scroll", onScrolltolower: _cache[0] || (_cache[0] = (...args) => $options.onReachBottom && $options.onReachBottom(...args)) }, [ vue.createElementVNode("view", { style: { "height": "16rpx" } }), (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($options.filteredOrders, (order, idx) => { return vue.openBlock(), vue.createElementBlock("view", { class: "order-card", key: idx }, [ vue.createElementVNode("view", { class: "card-header" }, [ vue.createElementVNode("view", { class: "type-badge" }, [ vue.createElementVNode("image", { class: "type-icon", src: order.typeIcon }, null, 8, ["src"]), vue.createElementVNode( "text", { class: "type-text" }, vue.toDisplayString(order.typeName), 1 /* TEXT */ ) ]), vue.createElementVNode( "text", { class: "status-text", style: vue.normalizeStyle({ color: order.statusColor }) }, vue.toDisplayString(order.statusLabel), 5 /* TEXT, STYLE */ ) ]), vue.createElementVNode( "text", { class: "service-time" }, "服务时间:" + vue.toDisplayString(order.serviceTime), 1 /* TEXT */ ), vue.createElementVNode("view", { class: "pet-card" }, [ vue.createElementVNode("image", { class: "pet-avatar", src: order.petAvatar, mode: "aspectFill" }, null, 8, ["src"]), vue.createElementVNode("view", { class: "pet-info" }, [ vue.createElementVNode( "text", { class: "pet-name" }, vue.toDisplayString(order.petName), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "pet-breed" }, "品种: " + vue.toDisplayString(order.petBreed), 1 /* TEXT */ ) ]), vue.createElementVNode( "text", { class: "pet-price" }, "¥" + vue.toDisplayString(order.price), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "route-info" }, [ order.orderType === 1 ? (vue.openBlock(), vue.createElementBlock( vue.Fragment, { key: 0 }, [ vue.createElementVNode("view", { class: "route-item" }, [ vue.createElementVNode("view", { class: "icon-circle pickup" }, "取"), vue.createElementVNode("view", { class: "route-connector" }), vue.createElementVNode("view", { class: "address-box" }, [ vue.createElementVNode( "text", { class: "addr-title" }, vue.toDisplayString(order.startName), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "addr-desc" }, vue.toDisplayString(order.startAddr), 1 /* TEXT */ ) ]) ]), vue.createElementVNode("view", { class: "route-item" }, [ vue.createElementVNode("view", { class: "icon-circle deliver" }, "送"), vue.createElementVNode("view", { class: "address-box" }, [ vue.createElementVNode( "text", { class: "addr-title" }, vue.toDisplayString(order.endName), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "addr-desc" }, vue.toDisplayString(order.endAddr), 1 /* TEXT */ ) ]) ]) ], 64 /* STABLE_FRAGMENT */ )) : (vue.openBlock(), vue.createElementBlock( vue.Fragment, { key: 1 }, [ vue.createElementVNode("view", { class: "route-item" }, [ vue.createElementVNode("view", { class: "icon-circle service" }, "服"), vue.createElementVNode("view", { class: "address-box" }, [ vue.createElementVNode( "text", { class: "addr-title" }, vue.toDisplayString(order.endName), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "addr-desc" }, vue.toDisplayString(order.endAddr), 1 /* TEXT */ ) ]) ]), order.serviceNote ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "service-note-row" }, [ vue.createElementVNode( "text", { class: "service-note-text" }, "服务内容:" + vue.toDisplayString(order.serviceNote), 1 /* TEXT */ ) ])) : vue.createCommentVNode("v-if", true) ], 64 /* STABLE_FRAGMENT */ )) ]) ]); }), 128 /* KEYED_FRAGMENT */ )), $options.filteredOrders.length === 0 && !$data.loading ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "empty-state" }, [ vue.createElementVNode("text", { class: "empty-text" }, "暂无相关订单") ])) : vue.createCommentVNode("v-if", true), $data.loading ? (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "loading-more" }, [ vue.createElementVNode("text", null, "加载中...") ])) : vue.createCommentVNode("v-if", true), vue.createElementVNode("view", { style: { "height": "40rpx" } }) ], 32 /* NEED_HYDRATION */ ) ]); } const PagesMineOrderStats = /* @__PURE__ */ _export_sfc(_sfc_main$p, [["render", _sfc_render$o], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/order-stats.vue"]]); function getBalanceOnApp() { return request({ url: "/fulfiller/log/balanceOnApp", method: "GET" }); } function pageBalanceOnApp(data) { return request({ url: "/fulfiller/log/pageBalanceOnApp", method: "GET", data }); } function listBalanceOnApp(data) { return request({ url: "/fulfiller/log/listBalanceOnApp", method: "GET", data }); } function pointsOnApp() { return request({ url: "/fulfiller/log/pointsOnApp", method: "GET" }); } function pagePointsOnApp(data) { return request({ url: "/fulfiller/log/pagePointsOnApp", method: "GET", data }); } function listPointsOnApp(data) { return request({ url: "/fulfiller/log/listPointsOnApp", method: "GET", data }); } function countOnAppReward(data) { return request({ url: "/fulfiller/log/countOnAppReward", method: "GET", data }); } function listOnAppReward(data) { return request({ url: "/fulfiller/log/listOnAppReward", method: "GET", data }); } const FlfBalanceBizType = { admin_reward: "后台奖励", admin_punish: "后台惩罚", admin_adjust: "后台调整", order_reward: "订单奖励", order_punish: "订单惩罚", order_finish: "订单完成", salary: "工资发放", withdraw: "提现" }; const FlfPointsBizType = { admin_reward: "后台奖励", admin_punish: "后台惩罚", admin_adjust: "后台调整", order_reward: "订单奖励", order_punish: "订单惩罚", order_finish: "订单完成" }; const FlfRewardBizType = { admin_reward: "后台奖励", admin_punish: "后台惩罚", order_reward: "订单奖励", order_punish: "订单惩罚", order_finish: "订单完成" }; const FlfActionType = { add: "收入", reduce: "支出" }; const fulfillerEnum = { FlfBalanceBizType, FlfPointsBizType, FlfRewardBizType, FlfActionType }; const bizTypeMap$5 = fulfillerEnum.FlfRewardBizType; const _sfc_main$o = { data() { const now = /* @__PURE__ */ new Date(); return { tabs: ["全部", "奖励", "惩罚"], activeTab: 0, selectedYear: now.getFullYear(), selectedMonth: now.getFullYear() === 2026 && now.getMonth() < 2 ? 3 : now.getMonth() + 1, // 默认当前月,处理一下测试数据时间 // 统计数据 stats: { rewardCount: 0, punishCount: 0, rewardBalance: 0, punishBalance: 0 }, // 月份选择器状态 showMonthPicker: false, pickerYear: 2026, pickerMonth: 3, years: [2024, 2025, 2026], months: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], yearScrollTop: 0, monthScrollTop: 0, // 奖惩记录列表 records: [] }; }, computed: { filteredList() { if (this.activeTab === 0) return this.records; const targetType = this.activeTab === 1 ? "reward" : "penalty"; return this.records.filter((r) => r.type === targetType); } }, onShow() { if (this.selectedYear === 2026 && this.selectedMonth === 2) ; this.fetchData(); }, methods: { async fetchData() { const params = { year: this.selectedYear, month: this.selectedMonth }; this.fetchStats(params); this.fetchList(params); }, async fetchStats(params) { try { const res = await countOnAppReward(params); if (res.code === 200) { this.stats = res.data || { rewardCount: 0, punishCount: 0, rewardBalance: 0, punishBalance: 0 }; } } catch (err) { formatAppLog("error", "at pages/mine/rewards.vue:196", "获取奖惩统计失败:", err); } }, async fetchList(params) { try { const res = await listOnAppReward(params); if (res.code === 200) { const list = res.data || []; this.records = list.map((item) => { const isAdd = item.type === "add"; const amountVal = Math.abs(item.amount) / 100; let dateStr = ""; if (item.createTime) { const datePart = item.createTime.split(" ")[0]; const parts = datePart.split("-"); if (parts.length >= 3) { dateStr = `${parts[1]}-${parts[2]}`; } } return { ...item, date: dateStr, title: bizTypeMap$5[item.bizType] || item.bizType || "其他", desc: item.reason || "", amount: isAdd ? amountVal : -amountVal, type: isAdd ? "reward" : "penalty", status: isAdd ? "已入账" : "已扣款", // 简化处理状态 statusClass: isAdd ? "credited" : "deducted" }; }); } } catch (err) { formatAppLog("error", "at pages/mine/rewards.vue:231", "获取奖惩列表失败:", err); } }, switchTab(idx) { this.activeTab = idx; }, openMonthPicker() { this.pickerYear = this.selectedYear; this.pickerMonth = this.selectedMonth; this.showMonthPicker = true; }, closeMonthPicker() { this.showMonthPicker = false; }, confirmMonthPicker() { this.selectedYear = this.pickerYear; this.selectedMonth = this.pickerMonth; this.closeMonthPicker(); this.fetchData(); }, goToAll() { uni.navigateTo({ url: "/pages/mine/rewards-all" }); } } }; function _sfc_render$n(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "top-banner" }, [ vue.createElementVNode("view", { class: "month-btn", onClick: _cache[0] || (_cache[0] = (...args) => $options.openMonthPicker && $options.openMonthPicker(...args)) }, [ vue.createElementVNode( "text", { class: "month-text" }, vue.toDisplayString($data.selectedYear) + "年" + vue.toDisplayString($data.selectedMonth) + "月 ▾", 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "stats-grid" }, [ vue.createElementVNode("view", { class: "stats-cell" }, [ vue.createElementVNode("text", { class: "stats-label" }, "奖励订单"), vue.createElementVNode("text", { class: "stats-num" }, [ vue.createTextVNode( vue.toDisplayString($data.stats.rewardCount), 1 /* TEXT */ ), vue.createElementVNode("text", { class: "stats-unit" }, "单") ]), vue.createElementVNode("view", { class: "stats-divider" }), vue.createElementVNode("text", { class: "stats-sub" }, "月度统计") ]), vue.createElementVNode("view", { class: "stats-cell" }, [ vue.createElementVNode("text", { class: "stats-label" }, "惩罚订单"), vue.createElementVNode("text", { class: "stats-num" }, [ vue.createTextVNode( vue.toDisplayString($data.stats.punishCount), 1 /* TEXT */ ), vue.createElementVNode("text", { class: "stats-unit" }, "单") ]), vue.createElementVNode("view", { class: "stats-divider" }), vue.createElementVNode("text", { class: "stats-sub" }, "月度统计") ]), vue.createElementVNode("view", { class: "stats-cell" }, [ vue.createElementVNode("text", { class: "stats-label" }, "奖励金额"), vue.createElementVNode( "text", { class: "stats-num reward-num" }, vue.toDisplayString(($data.stats.rewardBalance / 100).toFixed(2)), 1 /* TEXT */ ), vue.createElementVNode("view", { class: "stats-divider" }), vue.createElementVNode("text", { class: "stats-sub" }, "月度统计") ]), vue.createElementVNode("view", { class: "stats-cell" }, [ vue.createElementVNode("text", { class: "stats-label" }, "惩罚金额"), vue.createElementVNode( "text", { class: "stats-num penalty-num" }, vue.toDisplayString(($data.stats.punishBalance / 100).toFixed(2)), 1 /* TEXT */ ), vue.createElementVNode("view", { class: "stats-divider" }), vue.createElementVNode("text", { class: "stats-sub" }, "月度统计") ]) ]) ]), vue.createElementVNode("view", { class: "list-header" }, [ vue.createElementVNode("view", { class: "tab-bar" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($data.tabs, (tab, idx) => { return vue.openBlock(), vue.createElementBlock("view", { class: vue.normalizeClass(["tab-item", { active: $data.activeTab === idx }]), key: idx, onClick: ($event) => $options.switchTab(idx) }, [ vue.createElementVNode( "text", null, vue.toDisplayString(tab), 1 /* TEXT */ ), $data.activeTab === idx ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "tab-line" })) : vue.createCommentVNode("v-if", true) ], 10, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )) ]), vue.createElementVNode("view", { class: "view-all-btn", onClick: _cache[1] || (_cache[1] = (...args) => $options.goToAll && $options.goToAll(...args)) }, [ vue.createElementVNode("text", { class: "view-all-text" }, "查看全部 ›") ]) ]), vue.createElementVNode("view", { class: "record-list" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($options.filteredList, (item, idx) => { return vue.openBlock(), vue.createElementBlock("view", { class: "record-item", key: idx }, [ vue.createElementVNode( "view", { class: vue.normalizeClass(["ri-icon", item.amount > 0 ? "ri-reward" : "ri-penalty"]) }, [ vue.createElementVNode("text", { class: "ri-icon-text" }, "¥") ], 2 /* CLASS */ ), vue.createElementVNode("view", { class: "ri-content" }, [ vue.createElementVNode("view", { class: "ri-title-row" }, [ vue.createElementVNode( "text", { class: "ri-date" }, vue.toDisplayString(item.date), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "ri-title" }, vue.toDisplayString(item.title), 1 /* TEXT */ ) ]), vue.createElementVNode( "text", { class: "ri-desc" }, vue.toDisplayString(item.desc), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "ri-right" }, [ vue.createElementVNode( "text", { class: vue.normalizeClass(["ri-amount", item.amount > 0 ? "positive" : "negative"]) }, vue.toDisplayString(item.amount > 0 ? "+" : "") + vue.toDisplayString(item.amount.toFixed(2)), 3 /* TEXT, CLASS */ ), vue.createElementVNode( "text", { class: vue.normalizeClass(["ri-status", item.statusClass]) }, vue.toDisplayString(item.status), 3 /* TEXT, CLASS */ ) ]) ]); }), 128 /* KEYED_FRAGMENT */ )), vue.createElementVNode("text", { class: "more-hint" }, "更多记录请点击上方的查看全部") ]), $data.showMonthPicker ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "picker-mask", onClick: _cache[7] || (_cache[7] = (...args) => $options.closeMonthPicker && $options.closeMonthPicker(...args)) }, [ vue.createElementVNode("view", { class: "picker-sheet", onClick: _cache[6] || (_cache[6] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("view", { class: "picker-header" }, [ vue.createElementVNode("text", { class: "picker-cancel", onClick: _cache[2] || (_cache[2] = (...args) => $options.closeMonthPicker && $options.closeMonthPicker(...args)) }, "取消"), vue.createElementVNode("text", { class: "picker-title" }, "选择时间"), vue.createElementVNode("text", { class: "picker-confirm", onClick: _cache[3] || (_cache[3] = (...args) => $options.confirmMonthPicker && $options.confirmMonthPicker(...args)) }, "确定") ]), vue.createElementVNode("view", { class: "picker-body" }, [ vue.createElementVNode("scroll-view", { "scroll-y": "", class: "picker-column", "scroll-top": $data.yearScrollTop, onScroll: _cache[4] || (_cache[4] = (...args) => _ctx.onYearScroll && _ctx.onYearScroll(...args)) }, [ vue.createElementVNode("view", { style: { "height": "80rpx" } }), (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($data.years, (year) => { return vue.openBlock(), vue.createElementBlock("view", { class: vue.normalizeClass(["picker-col-item", { "picker-selected": $data.pickerYear === year }]), key: year, onClick: ($event) => $data.pickerYear = year }, vue.toDisplayString(year) + "年", 11, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )), vue.createElementVNode("view", { style: { "height": "80rpx" } }) ], 40, ["scroll-top"]), vue.createElementVNode("view", { class: "picker-highlight" }), vue.createElementVNode("scroll-view", { "scroll-y": "", class: "picker-column", "scroll-top": $data.monthScrollTop, onScroll: _cache[5] || (_cache[5] = (...args) => _ctx.onMonthScroll && _ctx.onMonthScroll(...args)) }, [ vue.createElementVNode("view", { style: { "height": "80rpx" } }), (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($data.months, (month) => { return vue.openBlock(), vue.createElementBlock("view", { class: vue.normalizeClass(["picker-col-item", { "picker-selected": $data.pickerMonth === month }]), key: month, onClick: ($event) => $data.pickerMonth = month }, vue.toDisplayString(month) + "月", 11, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )), vue.createElementVNode("view", { style: { "height": "80rpx" } }) ], 40, ["scroll-top"]) ]) ]) ])) : vue.createCommentVNode("v-if", true) ]); } const PagesMineRewards = /* @__PURE__ */ _export_sfc(_sfc_main$o, [["render", _sfc_render$n], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/rewards.vue"]]); const bizTypeMap$4 = fulfillerEnum.FlfRewardBizType; const _sfc_main$n = { data() { const now = /* @__PURE__ */ new Date(); return { tabs: ["全部", "奖励", "惩罚"], activeTab: 0, selectedYear: now.getFullYear(), selectedMonth: now.getMonth() + 1, // 原始分组数据 allGroups: [], loading: false }; }, computed: { currentPickerDate() { return `${this.selectedYear}-${String(this.selectedMonth).padStart(2, "0")}`; }, filteredGroups() { if (this.activeTab === 0) return this.allGroups; const typeKey = this.activeTab === 1 ? "reward" : "penalty"; return this.allGroups.map((g) => ({ ...g, items: g.items.filter((i) => i.type === typeKey) })).filter((g) => g.items.length > 0); } }, onShow() { this.fetchMonthData(); }, methods: { async fetchMonthData() { if (this.loading) return; this.loading = true; try { const params = { year: this.selectedYear, month: this.selectedMonth }; const res = await listOnAppReward(params); const data = res.data || []; if (data.length === 0) { this.allGroups = []; return; } let credited = 0; const items = data.map((item) => { const isAdd = item.type === "add"; const amountVal = Math.abs(item.amount) / 100; if (isAdd) credited += amountVal; let dateStr = ""; if (item.createTime) { const datePart = item.createTime.split(" ")[0]; const parts = datePart.split("-"); if (parts.length >= 3) { dateStr = `${parts[1]}-${parts[2]}`; } } return { ...item, date: dateStr, title: bizTypeMap$4[item.bizType] || item.bizType || "其他", desc: item.reason || "", amount: isAdd ? amountVal : -amountVal, type: isAdd ? "reward" : "penalty", status: isAdd ? "已入账" : "已扣款", statusClass: isAdd ? "credited" : "deducted" }; }); this.allGroups = [{ month: this.selectedMonth, year: this.selectedYear, credited, pending: 0, items }]; } catch (err) { formatAppLog("error", "at pages/mine/rewards-all.vue:151", "获取奖惩明细失败:", err); } finally { this.loading = false; } }, onDateChange(e) { const val = e.detail.value; const parts = val.split("-"); this.selectedYear = parseInt(parts[0]); this.selectedMonth = parseInt(parts[1]); this.fetchMonthData(); }, switchTab(idx) { this.activeTab = idx; } } }; function _sfc_render$m(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "filter-header" }, [ vue.createElementVNode("view", { class: "tab-bar" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($data.tabs, (tab, idx) => { return vue.openBlock(), vue.createElementBlock("view", { class: vue.normalizeClass(["tab-item", { active: $data.activeTab === idx }]), key: idx, onClick: ($event) => $options.switchTab(idx) }, [ vue.createElementVNode( "text", null, vue.toDisplayString(tab), 1 /* TEXT */ ), $data.activeTab === idx ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "tab-line" })) : vue.createCommentVNode("v-if", true) ], 10, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )) ]), vue.createElementVNode("view", { class: "date-filter" }, [ vue.createElementVNode("picker", { mode: "date", fields: "month", value: $options.currentPickerDate, onChange: _cache[0] || (_cache[0] = (...args) => $options.onDateChange && $options.onDateChange(...args)) }, [ vue.createElementVNode("view", { class: "picker-trigger" }, [ vue.createElementVNode( "text", null, vue.toDisplayString($data.selectedYear) + "年" + vue.toDisplayString(String($data.selectedMonth).padStart(2, "0")) + "月", 1 /* TEXT */ ), vue.createElementVNode("text", { class: "arrow-icon" }, "▼") ]) ], 40, ["value"]) ]) ]), vue.createElementVNode("scroll-view", { "scroll-y": "", class: "main-scroll" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($options.filteredGroups, (group, gIdx) => { return vue.openBlock(), vue.createElementBlock("view", { key: gIdx, class: "month-group" }, [ vue.createElementVNode("view", { class: "month-header" }, [ vue.createElementVNode( "text", { class: "month-title" }, vue.toDisplayString(group.month) + "月", 1 /* TEXT */ ), vue.createElementVNode("view", { class: "month-summary" }, [ vue.createElementVNode( "text", { class: "month-sum-text" }, "已入账¥" + vue.toDisplayString(group.credited.toFixed(2)), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "month-sum-text" }, " 待入账¥" + vue.toDisplayString(group.pending.toFixed(2)), 1 /* TEXT */ ) ]) ]), (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(group.items, (item, rIdx) => { return vue.openBlock(), vue.createElementBlock("view", { class: "record-item", key: rIdx }, [ vue.createElementVNode( "view", { class: vue.normalizeClass(["ri-icon", item.amount > 0 ? "ri-reward" : "ri-penalty"]) }, [ vue.createElementVNode("text", { class: "ri-icon-text" }, "¥") ], 2 /* CLASS */ ), vue.createElementVNode("view", { class: "ri-content" }, [ vue.createElementVNode("view", { class: "ri-title-row" }, [ vue.createElementVNode( "text", { class: "ri-date" }, vue.toDisplayString(item.date), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "ri-title" }, vue.toDisplayString(item.title), 1 /* TEXT */ ) ]), vue.createElementVNode( "text", { class: "ri-desc" }, vue.toDisplayString(item.desc), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "ri-right" }, [ vue.createElementVNode( "text", { class: vue.normalizeClass(["ri-amount", item.amount > 0 ? "positive" : "negative"]) }, vue.toDisplayString(item.amount > 0 ? "+" : "") + vue.toDisplayString(item.amount.toFixed(2)), 3 /* TEXT, CLASS */ ), vue.createElementVNode( "text", { class: vue.normalizeClass(["ri-status", item.statusClass]) }, vue.toDisplayString(item.status), 3 /* TEXT, CLASS */ ) ]) ]); }), 128 /* KEYED_FRAGMENT */ )) ]); }), 128 /* KEYED_FRAGMENT */ )), vue.createElementVNode("view", { style: { "height": "40rpx" } }) ]) ]); } const PagesMineRewardsAll = /* @__PURE__ */ _export_sfc(_sfc_main$n, [["render", _sfc_render$m], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/rewards-all.vue"]]); function listAllLevelConfigs() { return request({ url: "/fulfiller/levelConfig/listAll", method: "GET" }); } function getCustomerServiceSetting(id) { return request({ url: "/system/customerServiceSetting/" + id, method: "get" }); } const logic = { components: { customTabbar }, data() { return { showServicePopup: false, showLogoutPopup: false, profile: null, profileLoading: false, levelConfigs: [], // 等级配置列表 customerSetting: { wechatAccount: "", phoneNumber: "400-123-4567", qrCodeUrl: "/static/logo.png", enterpriseWechatLink: "", startServiceTime: "", endServiceTime: "" } }; }, computed: { // 根据 profile.level 匹配对应的等级名称 displayLevelName() { if (!this.profile || !this.levelConfigs.length) return "普通履约者"; const config = this.levelConfigs.find((c) => c.lvNo === this.profile.level); return config ? config.name : this.profile.levelName || "普通履约者"; } }, onShow() { uni.hideTabBar(); if (isLoggedIn()) { this.loadProfile(); this.loadLevelConfigs(); this.fetchCustomerServiceSetting(); } }, methods: { async loadProfile() { if (this.profileLoading) return; this.profileLoading = true; try { const res = await getMyProfile(); this.profile = res.data || null; } catch (err) { formatAppLog("error", "at pages/mine/logic.js:53", "获取个人信息失败:", err); } finally { this.profileLoading = false; } }, async loadLevelConfigs() { try { const res = await listAllLevelConfigs(); this.levelConfigs = res.data || []; } catch (err) { formatAppLog("error", "at pages/mine/logic.js:63", "加载等级配置失败:", err); } }, async fetchCustomerServiceSetting() { try { const res = await getCustomerServiceSetting(1); if (res.code === 200 && res.data) { this.customerSetting = { ...this.customerSetting, ...res.data }; } } catch (err) { formatAppLog("error", "at pages/mine/logic.js:73", "获取客服配置失败:", err); } }, navToSettings() { uni.navigateTo({ url: "/pages/mine/settings/index" }); }, navToProfile() { uni.navigateTo({ url: "/pages/mine/settings/profile/index" }); }, navToLevel() { uni.navigateTo({ url: "/pages/mine/level/index" }); }, navToNotification() { uni.navigateTo({ url: "/pages/mine/message/index" }); }, navToWallet() { uni.navigateTo({ url: "/pages/mine/wallet/index" }); }, navToPoints() { uni.navigateTo({ url: "/pages/mine/points/index" }); }, navToOrderStats() { uni.navigateTo({ url: "/pages/mine/order-stats" }); }, navToRewards() { uni.navigateTo({ url: "/pages/mine/rewards" }); }, openServicePopup() { this.showServicePopup = true; }, closeServicePopup() { this.showServicePopup = false; }, previewQRCode() { if (!this.customerSetting.qrCodeUrl) return; uni.previewImage({ urls: [this.customerSetting.qrCodeUrl] }); }, openOnlineService() { if (this.customerSetting.enterpriseWechatLink) { uni.setClipboardData({ data: this.customerSetting.wechatAccount || this.customerSetting.enterpriseWechatLink, success: () => { uni.showToast({ title: "链接已复制,请在浏览器或微信打开", icon: "none" }); } }); } else { uni.showToast({ title: "在线客服暂未配置", icon: "none" }); } }, callServicePhone() { if (!this.customerSetting.phoneNumber) { uni.showToast({ title: "暂无联系电话", icon: "none" }); return; } uni.makePhoneCall({ phoneNumber: this.customerSetting.phoneNumber }); }, logout() { this.showLogoutPopup = true; }, cancelLogout() { this.showLogoutPopup = false; }, async confirmLogout() { this.showLogoutPopup = false; try { await logout(); } catch (e) { } clearAuth(); uni.reLaunch({ url: "/pages/login/login" }); } } }; const _imports_0$1 = "/static/icons/motorbike.svg"; const _imports_1$6 = "/static/icons/location.svg"; const _imports_0 = "/static/icons/chevron_right_dark.svg"; const _imports_3$1 = "/static/icons/calendar.svg"; const _imports_4 = "/static/icons/settings.svg"; const _imports_1$5 = "/static/icons/crown.svg"; const _imports_6 = "/static/icons/chevron_right_gold.svg"; const _imports_3 = "/static/icons/chevron_right.svg"; const _imports_8 = "/static/icons/money_linear.svg"; const _imports_9 = "/static/icons/headset_linear.svg"; const _imports_10 = "/static/icons/close_gray.svg"; const _imports_11 = "/static/icons/headset_green.svg"; const _imports_13 = "/static/icons/phone_green.svg"; const _sfc_main$m = { ...logic }; function _sfc_render$l(_ctx, _cache, $props, $setup, $data, $options) { var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l; const _component_custom_tabbar = vue.resolveComponent("custom-tabbar"); return vue.openBlock(), vue.createElementBlock( vue.Fragment, null, [ vue.createElementVNode("view", { class: "container" }, [ vue.createElementVNode("view", { class: "nav-bg" }, [ vue.createElementVNode("view", { class: "bg-circle-1" }), vue.createElementVNode("view", { class: "bg-circle-2" }) ]), vue.createElementVNode("view", { class: "header-section" }, [ vue.createElementVNode("view", { class: "title-bar" }, "个人中心"), vue.createElementVNode("view", { class: "user-card", onClick: _cache[1] || (_cache[1] = (...args) => _ctx.navToProfile && _ctx.navToProfile(...args)) }, [ vue.createElementVNode("image", { class: "avatar", src: ((_a = _ctx.profile) == null ? void 0 : _a.avatarUrl) || "/static/touxiang.png", mode: "aspectFill" }, null, 8, ["src"]), vue.createElementVNode("view", { class: "info-content" }, [ vue.createElementVNode("view", { class: "name-row" }, [ vue.createElementVNode( "text", { class: "name" }, vue.toDisplayString(((_b = _ctx.profile) == null ? void 0 : _b.name) || "未登录"), 1 /* TEXT */ ), vue.createElementVNode("view", { class: "tags" }, [ ((_c = _ctx.profile) == null ? void 0 : _c.status) === "0" ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "tag green" }, "接单中")) : ((_d = _ctx.profile) == null ? void 0 : _d.status) === "1" ? (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "tag green" }, "休息中")) : ((_e = _ctx.profile) == null ? void 0 : _e.status) === "2" ? (vue.openBlock(), vue.createElementBlock("view", { key: 2, class: "tag", style: { "background": "#eee", "color": "#999" } }, "已禁用")) : vue.createCommentVNode("v-if", true), ((_f = _ctx.profile) == null ? void 0 : _f.workType) === "full_time" ? (vue.openBlock(), vue.createElementBlock("view", { key: 3, class: "tag blue" }, "全职")) : vue.createCommentVNode("v-if", true), vue.createElementVNode("image", { class: "bike-icon", src: _imports_0$1 }) ]) ]), vue.createElementVNode("view", { class: "detail-row" }, [ vue.createElementVNode("image", { class: "small-icon", src: _imports_1$6 }), vue.createElementVNode( "text", null, vue.toDisplayString(((_g = _ctx.profile) == null ? void 0 : _g.stationName) || ((_h = _ctx.profile) == null ? void 0 : _h.cityName) || "暂无站点"), 1 /* TEXT */ ), vue.createElementVNode("image", { class: "arrow-icon-small", src: _imports_0 }) ]), vue.createElementVNode("view", { class: "detail-row" }, [ vue.createElementVNode("image", { class: "small-icon", src: _imports_3$1 }), vue.createElementVNode( "text", null, "已注册" + vue.toDisplayString(((_i = _ctx.profile) == null ? void 0 : _i.registerDays) || 0) + "天", 1 /* TEXT */ ) ]) ]), vue.createElementVNode("image", { class: "settings-icon", src: _imports_4, onClick: _cache[0] || (_cache[0] = vue.withModifiers((...args) => _ctx.navToSettings && _ctx.navToSettings(...args), ["stop"])) }) ]), vue.createElementVNode("view", { class: "vip-card" }, [ vue.createElementVNode("view", { class: "vip-left" }, [ vue.createElementVNode("image", { class: "vip-icon", src: _imports_1$5 }), vue.createElementVNode("view", { class: "vip-text" }, [ vue.createElementVNode( "text", { class: "vip-title" }, vue.toDisplayString(_ctx.displayLevelName), 1 /* TEXT */ ), vue.createElementVNode("text", { class: "vip-desc" }, "完成更多订单即可升级") ]) ]), vue.createElementVNode("view", { class: "vip-btn", onClick: _cache[2] || (_cache[2] = (...args) => _ctx.navToLevel && _ctx.navToLevel(...args)) }, [ vue.createElementVNode("text", null, "查看权益"), vue.createElementVNode("image", { class: "arrow-icon-small", src: _imports_6 }) ]) ]) ]), vue.createElementVNode("view", { class: "stats-panel" }, [ vue.createElementVNode("view", { class: "stat-item", onClick: _cache[3] || (_cache[3] = (...args) => _ctx.navToWallet && _ctx.navToWallet(...args)) }, [ vue.createElementVNode("view", { class: "stat-header" }, [ vue.createElementVNode("view", { class: "red-bar" }), vue.createElementVNode("text", { class: "label" }, "我的钱包"), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]), vue.createElementVNode("view", { class: "stat-value" }, [ vue.createElementVNode( "text", { class: "num" }, vue.toDisplayString(((_j = _ctx.profile) == null ? void 0 : _j.balance) ? (_ctx.profile.balance / 100).toFixed(2) : "0.00"), 1 /* TEXT */ ), vue.createElementVNode("text", { class: "unit" }, "元") ]), vue.createElementVNode("text", { class: "sub-text" }, "账户余额") ]), vue.createElementVNode("view", { class: "divider" }), vue.createElementVNode("view", { class: "stat-item", onClick: _cache[4] || (_cache[4] = (...args) => _ctx.navToOrderStats && _ctx.navToOrderStats(...args)) }, [ vue.createElementVNode("view", { class: "stat-header" }, [ vue.createElementVNode("view", { class: "green-bar" }), vue.createElementVNode("text", { class: "label" }, "订单统计"), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]), vue.createElementVNode("view", { class: "stat-value" }, [ vue.createElementVNode( "text", { class: "num" }, vue.toDisplayString(((_k = _ctx.profile) == null ? void 0 : _k.orderCount) || 0), 1 /* TEXT */ ), vue.createElementVNode("text", { class: "unit" }, "单") ]), vue.createElementVNode("text", { class: "sub-text" }, "累计服务单量") ]), vue.createElementVNode("view", { class: "divider" }), vue.createElementVNode("view", { class: "stat-item", onClick: _cache[5] || (_cache[5] = (...args) => _ctx.navToPoints && _ctx.navToPoints(...args)) }, [ vue.createElementVNode("view", { class: "stat-header" }, [ vue.createElementVNode("view", { class: "orange-bar" }), vue.createElementVNode("text", { class: "label" }, "我的积分"), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]), vue.createElementVNode("view", { class: "stat-value" }, [ vue.createElementVNode( "text", { class: "num" }, vue.toDisplayString(((_l = _ctx.profile) == null ? void 0 : _l.points) || 0), 1 /* TEXT */ ), vue.createElementVNode("text", { class: "unit" }, "分") ]), vue.createElementVNode("text", { class: "sub-text" }, "可兑换权益") ]) ]), vue.createElementVNode("view", { class: "menu-list" }, [ vue.createElementVNode("view", { class: "menu-item", onClick: _cache[6] || (_cache[6] = (...args) => _ctx.navToRewards && _ctx.navToRewards(...args)) }, [ vue.createElementVNode("image", { class: "menu-icon", src: _imports_8 }), vue.createElementVNode("text", { class: "menu-text" }, "我的奖惩"), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]), vue.createElementVNode("view", { class: "menu-item", onClick: _cache[7] || (_cache[7] = (...args) => _ctx.openServicePopup && _ctx.openServicePopup(...args)) }, [ vue.createElementVNode("image", { class: "menu-icon", src: _imports_9 }), vue.createElementVNode("text", { class: "menu-text" }, "联系客服"), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]) ]), vue.createElementVNode("view", { class: "logout-btn", onClick: _cache[8] || (_cache[8] = (...args) => _ctx.logout && _ctx.logout(...args)) }, "退出登录"), _ctx.showServicePopup ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "service-popup-mask", onClick: _cache[15] || (_cache[15] = (...args) => _ctx.closeServicePopup && _ctx.closeServicePopup(...args)) }, [ vue.createElementVNode("view", { class: "service-popup", onClick: _cache[14] || (_cache[14] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("view", { class: "service-header" }, [ vue.createElementVNode("text", { class: "service-title" }, "联系客服"), vue.createElementVNode("image", { class: "close-icon", src: _imports_10, onClick: _cache[9] || (_cache[9] = (...args) => _ctx.closeServicePopup && _ctx.closeServicePopup(...args)) }) ]), vue.createElementVNode("view", { class: "qr-section" }, [ vue.createElementVNode("text", { class: "qr-title" }, "客服二维码"), vue.createElementVNode("image", { class: "qr-img", src: _ctx.customerSetting.qrCodeUrl || "/static/logo.png", onClick: _cache[10] || (_cache[10] = (...args) => _ctx.previewQRCode && _ctx.previewQRCode(...args)) }, null, 8, ["src"]), vue.createElementVNode("text", { class: "qr-desc" }, "点击查看大图") ]), vue.createElementVNode("view", { class: "service-list" }, [ vue.createElementVNode("view", { class: "service-row", onClick: _cache[12] || (_cache[12] = (...args) => _ctx.openOnlineService && _ctx.openOnlineService(...args)) }, [ vue.createElementVNode("image", { class: "service-row-icon", src: _imports_11 }), vue.createElementVNode("view", { class: "service-info" }, [ vue.createElementVNode("text", { class: "service-name" }, "在线客服"), vue.createElementVNode( "text", { class: "service-desc" }, vue.toDisplayString(_ctx.customerSetting.wechatAccount || "企业微信专属客服在线解答"), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "call-btn", onClick: _cache[11] || (_cache[11] = (...args) => _ctx.openOnlineService && _ctx.openOnlineService(...args)) }, [ vue.createElementVNode("image", { class: "phone-icon-small", src: _imports_11 }), vue.createElementVNode("text", null, "企业微信") ]) ]), vue.createElementVNode("view", { class: "service-row" }, [ vue.createElementVNode("image", { class: "service-row-icon", src: _imports_12 }), vue.createElementVNode("view", { class: "service-info" }, [ vue.createElementVNode("text", { class: "service-name" }, "客服电话"), vue.createElementVNode( "text", { class: "service-desc" }, vue.toDisplayString(_ctx.customerSetting.phoneNumber || "暂无电话"), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "call-btn", onClick: _cache[13] || (_cache[13] = (...args) => _ctx.callServicePhone && _ctx.callServicePhone(...args)) }, [ vue.createElementVNode("image", { class: "phone-icon-small", src: _imports_13 }), vue.createElementVNode("text", null, "拨打") ]) ]) ]) ]) ])) : vue.createCommentVNode("v-if", true), vue.createElementVNode( "view", { class: vue.normalizeClass(["logout-popup-mask", { "show": _ctx.showLogoutPopup }]), onClick: _cache[19] || (_cache[19] = (...args) => _ctx.cancelLogout && _ctx.cancelLogout(...args)), onTouchmove: _cache[20] || (_cache[20] = vue.withModifiers(() => { }, ["stop", "prevent"])) }, [ vue.createElementVNode("view", { class: "popup-modal", onClick: _cache[18] || (_cache[18] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("text", { class: "popup-title" }, "退出登录"), vue.createElementVNode("text", { class: "popup-desc" }, "确定要退出当前账号吗?\\n退出后需要重新登录才能使用完整功能。"), vue.createElementVNode("view", { class: "popup-actions" }, [ vue.createElementVNode("view", { class: "popup-btn cancel", onClick: _cache[16] || (_cache[16] = (...args) => _ctx.cancelLogout && _ctx.cancelLogout(...args)) }, "取消"), vue.createElementVNode("view", { class: "popup-btn confirm", onClick: _cache[17] || (_cache[17] = (...args) => _ctx.confirmLogout && _ctx.confirmLogout(...args)) }, "确定") ]) ]) ], 34 /* CLASS, NEED_HYDRATION */ ) ]), vue.createVNode(_component_custom_tabbar, { currentPath: "pages/mine/index" }) ], 64 /* STABLE_FRAGMENT */ ); } const PagesMineIndex = /* @__PURE__ */ _export_sfc(_sfc_main$m, [["render", _sfc_render$l], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/index.vue"]]); const _sfc_main$l = { data() { return { version: "2.0.6", cacheSize: "0B", // 明确默认状态为开启:获取不到缓存即为 true,以此确保默认值为开启。 isGpsEnabled: uni.getStorageSync("GPS_REPORT_ENABLED") !== false }; }, onLoad() { this.getAppVersion(); this.getCacheSize(); }, methods: { navBack() { uni.navigateBack({ delta: 1 }); }, navTo(type) { let url = ""; switch (type) { case "profile": url = "/pages/mine/settings/profile/index"; break; case "auth": url = "/pages/mine/settings/auth/index"; break; case "bank": url = "/pages/mine/settings/bank/index"; break; case "security": url = "/pages/mine/settings/security/index"; break; case "push": url = "/pages/mine/settings/notification/index"; break; case "about": url = "/pages/mine/settings/about/index"; break; default: formatAppLog("log", "at pages/mine/settings/index.vue:114", "Navigate to:", type); return; } uni.navigateTo({ url }); }, clearCache() { uni.showModal({ title: "清理缓存", content: "确定要清理应用缓存吗?", success: (res) => { if (res.confirm) { try { const token = uni.getStorageSync("Authorization_token"); const gpsToggle = uni.getStorageSync("GPS_REPORT_ENABLED"); uni.clearStorageSync(); if (token) uni.setStorageSync("Authorization_token", token); uni.setStorageSync("GPS_REPORT_ENABLED", gpsToggle); uni.showToast({ title: "清理完成", icon: "success" }); this.getCacheSize(); } catch (err) { formatAppLog("error", "at pages/mine/settings/index.vue:140", "清理缓存失败:", err); } } } }); }, getCacheSize() { try { const res = uni.getStorageInfoSync(); const kb = res.currentSize; if (kb < 1024) { this.cacheSize = kb + "KB"; } else { this.cacheSize = (kb / 1024).toFixed(2) + "MB"; } } catch (err) { this.cacheSize = "0B"; } }, getAppVersion() { plus.runtime.getProperty(plus.runtime.appid, (widgetInfo) => { this.version = widgetInfo.version || "2.0.6"; }); }, onGpsSwitchChange(e) { const val = e.detail.value; this.isGpsEnabled = val; uni.setStorageSync("GPS_REPORT_ENABLED", val); if (val) { startGpsTimer(); } else { stopGpsTimer(); } } } }; function _sfc_render$k(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "custom-header" }, [ vue.createElementVNode("view", { class: "header-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0, style: { "transform": "rotate(180deg)" } }) ]), vue.createElementVNode("text", { class: "header-title" }, "设置"), vue.createElementVNode("view", { class: "header-right" }) ]), vue.createElementVNode("view", { class: "header-placeholder" }), vue.createElementVNode("view", { class: "group-card" }, [ vue.createElementVNode("view", { class: "list-item", onClick: _cache[1] || (_cache[1] = ($event) => $options.navTo("profile")) }, [ vue.createElementVNode("text", { class: "item-title" }, "个人资料"), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]), vue.createElementVNode("view", { class: "list-item", onClick: _cache[2] || (_cache[2] = ($event) => $options.navTo("auth")) }, [ vue.createElementVNode("text", { class: "item-title" }, "认证信息"), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]), vue.createElementVNode("view", { class: "list-item no-border", onClick: _cache[3] || (_cache[3] = ($event) => $options.navTo("security")) }, [ vue.createElementVNode("text", { class: "item-title" }, "账号与安全"), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]) ]), vue.createElementVNode("view", { class: "group-card" }, [ vue.createElementVNode("view", { class: "list-item" }, [ vue.createElementVNode("view", { class: "item-row-left" }, [ vue.createElementVNode("text", { class: "item-title" }, "位置上报"), vue.createElementVNode("text", { class: "item-subtitle" }, "每隔20分钟自动上报位置") ]), vue.createElementVNode("switch", { checked: $data.isGpsEnabled, color: "#FF5722", style: { "transform": "scale(0.8)" }, onChange: _cache[4] || (_cache[4] = (...args) => $options.onGpsSwitchChange && $options.onGpsSwitchChange(...args)) }, null, 40, ["checked"]) ]), vue.createElementVNode("view", { class: "list-item", onClick: _cache[5] || (_cache[5] = (...args) => $options.clearCache && $options.clearCache(...args)) }, [ vue.createElementVNode("text", { class: "item-title" }, "清理缓存"), vue.createElementVNode("view", { class: "item-right" }, [ vue.createElementVNode( "text", { class: "item-value" }, vue.toDisplayString($data.cacheSize), 1 /* TEXT */ ), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]) ]), vue.createElementVNode("view", { class: "list-item no-border", onClick: _cache[6] || (_cache[6] = ($event) => $options.navTo("about")) }, [ vue.createElementVNode("text", { class: "item-title" }, "关于我们"), vue.createElementVNode("view", { class: "item-right" }, [ vue.createElementVNode( "text", { class: "item-value" }, "v" + vue.toDisplayString($data.version), 1 /* TEXT */ ), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]) ]) ]) ]); } const PagesMineSettingsIndex = /* @__PURE__ */ _export_sfc(_sfc_main$l, [["render", _sfc_render$k], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/settings/index.vue"]]); const _sfc_main$k = { data() { return { userInfo: { name: "", workType: "", workStatus: "", city: "", avatar: "/static/touxiang.png", stationName: "", stationFullName: "" }, isStatusPickerShow: false, isCityPickerShow: false, // 城市站点级联选择器 selectStep: 0, selectedPathway: [], currentCityList: [], selectedCityId: null, fullTree: [] // 树形结构数据 }; }, onLoad() { this.loadUserInfo(); uni.$on("updateName", (newName) => { this.userInfo.name = newName; }); }, onUnload() { uni.$off("updateName"); }, methods: { // 加载用户信息 @author steelwei async loadUserInfo() { uni.showLoading({ title: "加载中..." }); try { const res = await getMyProfile(); if (res.code === 200) { const data = res.data; this.userInfo = { name: data.realName || data.name, workType: data.workType === "full_time" ? "全职" : "兼职", workStatus: this.formatStatus(data.status), city: data.cityName || "", avatar: data.avatarUrl || "/static/touxiang.png", stationName: data.stationName || "", stationFullName: "加载中..." }; if (data.stationId) { if (this.fullTree.length === 0) { await this.loadAreaStationTree(); } this.userInfo.stationFullName = this.findStationFullName(data.stationId, this.fullTree) || data.stationName || "未分配站点"; } else { this.userInfo.stationFullName = "未分配站点"; } } else { uni.showToast({ title: res.msg || "加载失败", icon: "none" }); } } catch (error) { formatAppLog("error", "at pages/mine/settings/profile/index.vue:182", "加载用户信息失败:", error); uni.showToast({ title: "网络错误", icon: "none" }); } finally { uni.hideLoading(); } }, // 格式化状态 @author steelwei formatStatus(status) { const statusMap = { "busy": "接单中", "resting": "休息中", "disabled": "已禁用" }; return statusMap[status] || status; }, // 查找站点完整路径 (城市/区域/站点) @author steelwei findStationFullName(stationId, tree) { if (!stationId || !tree || tree.length === 0) return ""; let path = []; const dfs = (nodes, targetId, currentPath) => { for (let node of nodes) { if (node.id === targetId) { path = [...currentPath, node.name]; return true; } if (node.children && node.children.length > 0) { if (dfs(node.children, targetId, [...currentPath, node.name])) { return true; } } } return false; }; dfs(tree, stationId, []); return path.join("/"); }, navBack() { uni.navigateBack({ delta: 1 }); }, // 修改头像 @author steelwei changeAvatar() { uni.chooseImage({ count: 1, success: async (res) => { const tempFilePath = res.tempFilePaths[0]; uni.showLoading({ title: "上传中..." }); try { const uploadRes = await uploadFile(tempFilePath); if (uploadRes.code === 200) { const { url, ossId } = uploadRes.data; const result = await updateAvatar(ossId); if (result.code === 200) { this.userInfo.avatar = url; uni.showToast({ title: "修改成功", icon: "success" }); } else { uni.showToast({ title: result.msg || "修改失败", icon: "none" }); } } } catch (error) { formatAppLog("error", "at pages/mine/settings/profile/index.vue:251", "修改头像失败:", error); uni.showToast({ title: "上传失败", icon: "none" }); } finally { uni.hideLoading(); } } }); }, editName() { uni.navigateTo({ url: `/pages/mine/settings/profile/edit-name?name=${this.userInfo.name}` }); }, showStatusPicker() { this.isStatusPickerShow = true; }, closeStatusPicker() { this.isStatusPickerShow = false; }, // 选择状态 @author steelwei async selectStatus(statusText) { const statusMap = { "接单中": "busy", "休息中": "resting" }; const status = statusMap[statusText]; try { const res = await updateStatus(status); if (res.code === 200) { this.userInfo.workStatus = statusText; uni.showToast({ title: "状态已更新", icon: "success" }); } else { uni.showToast({ title: res.msg || "修改失败", icon: "none" }); } } catch (error) { formatAppLog("error", "at pages/mine/settings/profile/index.vue:291", "修改状态失败:", error); uni.showToast({ title: "网络错误", icon: "none" }); } finally { this.closeStatusPicker(); } }, // 城市和站点级联选择器 @author steelwei async showCityPicker() { this.isCityPickerShow = true; if (this.fullTree.length === 0) { await this.loadAreaStationTree(); } if (this.selectedPathway.length === 0) { this.resetCityPicker(); } }, async loadAreaStationTree() { try { uni.showLoading({ title: "加载中..." }); const res = await getAreaStationList(); const list = res.data || []; let map = {}; let roots = []; list.forEach((node) => { map[node.id] = { ...node, children: [] }; }); list.forEach((node) => { if (node.parentId === 0 || !map[node.parentId]) { roots.push(map[node.id]); } else { map[node.parentId].children.push(map[node.id]); } }); this.fullTree = roots; } catch (err) { formatAppLog("error", "at pages/mine/settings/profile/index.vue:328", "加载站点数据失败:", err); this.fullTree = []; } finally { uni.hideLoading(); } }, resetCityPicker() { this.selectStep = 0; this.selectedPathway = []; this.currentCityList = this.fullTree; }, closeCityPicker() { this.isCityPickerShow = false; }, selectCityItem(item) { this.selectedPathway[this.selectStep] = item; if (item.children && item.children.length > 0) { this.selectStep++; this.selectedPathway = this.selectedPathway.slice(0, this.selectStep); this.currentCityList = item.children; } else { this.selectedCityId = item.id; this.confirmCity(); } }, jumpToStep(step) { this.selectStep = step; if (step === 0) { this.currentCityList = this.fullTree; } else { const parent = this.selectedPathway[step - 1]; this.currentCityList = parent ? parent.children : []; } }, // 确认城市与站点选择 @author steelwei async confirmCity() { if (this.selectedPathway.length === 0) { uni.showToast({ title: "请选择站点", icon: "none" }); return; } let stationNode = this.selectedPathway[this.selectedPathway.length - 1]; const fullName = this.selectedPathway.map((i) => i.name).join("/"); const reqData = { stationId: stationNode.id }; try { const res = await updateCity(reqData); if (res.code === 200) { this.userInfo.stationFullName = fullName; uni.showToast({ title: "修改成功", icon: "success" }); this.closeCityPicker(); this.selectedPathway = []; } else { uni.showToast({ title: res.msg || "修改失败", icon: "none" }); } } catch (error) { formatAppLog("error", "at pages/mine/settings/profile/index.vue:393", "修改失败:", error); uni.showToast({ title: "网络错误", icon: "none" }); } } } }; function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "custom-header" }, [ vue.createElementVNode("view", { class: "header-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0, style: { "transform": "rotate(180deg)" } }) ]), vue.createElementVNode("text", { class: "header-title" }, "个人资料"), vue.createElementVNode("view", { class: "header-right" }) ]), vue.createElementVNode("view", { class: "header-placeholder" }), vue.createElementVNode("view", { class: "group-card" }, [ vue.createElementVNode("view", { class: "list-item", onClick: _cache[1] || (_cache[1] = (...args) => $options.changeAvatar && $options.changeAvatar(...args)) }, [ vue.createElementVNode("text", { class: "item-title" }, "头像"), vue.createElementVNode("view", { class: "item-right" }, [ vue.createElementVNode("image", { class: "user-avatar", src: $data.userInfo.avatar, mode: "aspectFill" }, null, 8, ["src"]), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]) ]), vue.createElementVNode("view", { class: "list-item", onClick: _cache[2] || (_cache[2] = (...args) => $options.editName && $options.editName(...args)) }, [ vue.createElementVNode("text", { class: "item-title" }, "真实姓名"), vue.createElementVNode("view", { class: "item-right" }, [ vue.createElementVNode( "text", { class: "item-value" }, vue.toDisplayString($data.userInfo.name), 1 /* TEXT */ ), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]) ]) ]), vue.createElementVNode("view", { class: "group-card" }, [ vue.createElementVNode("view", { class: "list-item", onClick: _cache[3] || (_cache[3] = (...args) => $options.showStatusPicker && $options.showStatusPicker(...args)) }, [ vue.createElementVNode("text", { class: "item-title" }, "工作状态"), vue.createElementVNode("view", { class: "item-right" }, [ vue.createElementVNode( "text", { class: "item-value-black" }, vue.toDisplayString($data.userInfo.workStatus), 1 /* TEXT */ ), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]) ]) ]), vue.createElementVNode("view", { class: "group-card" }, [ vue.createElementVNode("view", { class: "list-item no-border", onClick: _cache[4] || (_cache[4] = (...args) => $options.showCityPicker && $options.showCityPicker(...args)) }, [ vue.createElementVNode("text", { class: "item-title" }, "所属站点"), vue.createElementVNode("view", { class: "item-right" }, [ vue.createElementVNode( "text", { class: "item-value" }, vue.toDisplayString($data.userInfo.stationFullName || "未分配站点"), 1 /* TEXT */ ), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]) ]) ]), $data.isStatusPickerShow ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "popup-mask", onClick: _cache[9] || (_cache[9] = (...args) => $options.closeStatusPicker && $options.closeStatusPicker(...args)) }, [ vue.createElementVNode("view", { class: "popup-content", onClick: _cache[8] || (_cache[8] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("view", { class: "popup-title" }, "选择工作状态"), vue.createElementVNode("view", { class: "popup-item", onClick: _cache[5] || (_cache[5] = ($event) => $options.selectStatus("接单中")) }, "接单中"), vue.createElementVNode("view", { class: "popup-item", onClick: _cache[6] || (_cache[6] = ($event) => $options.selectStatus("休息中")) }, "休息中"), vue.createElementVNode("view", { class: "popup-cancel", onClick: _cache[7] || (_cache[7] = (...args) => $options.closeStatusPicker && $options.closeStatusPicker(...args)) }, "取消") ]) ])) : vue.createCommentVNode("v-if", true), $data.isCityPickerShow ? (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "popup-mask", onClick: _cache[13] || (_cache[13] = (...args) => $options.closeCityPicker && $options.closeCityPicker(...args)) }, [ vue.createElementVNode("view", { class: "popup-content", onClick: _cache[12] || (_cache[12] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("view", { class: "popup-header-row" }, [ vue.createElementVNode("text", { class: "popup-btn-cancel", onClick: _cache[10] || (_cache[10] = (...args) => $options.closeCityPicker && $options.closeCityPicker(...args)) }, "取消"), vue.createElementVNode("text", { class: "popup-title-text" }, "请选择工作城市和站点"), vue.createElementVNode("text", { class: "popup-btn-confirm", onClick: _cache[11] || (_cache[11] = (...args) => $options.confirmCity && $options.confirmCity(...args)) }, "确定") ]), vue.createElementVNode("view", { class: "picker-body" }, [ vue.createElementVNode("view", { class: "timeline-area" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($data.selectedPathway, (item, index) => { return vue.openBlock(), vue.createElementBlock("view", { class: "timeline-item", key: index, onClick: ($event) => $options.jumpToStep(index) }, [ vue.createElementVNode("view", { class: "timeline-dot" }), vue.createElementVNode( "text", null, vue.toDisplayString(item.name), 1 /* TEXT */ ) ], 8, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )), $data.selectStep === $data.selectedPathway.length ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "timeline-item active" }, [ vue.createElementVNode("view", { class: "timeline-dot" }), vue.createElementVNode("text", null, "请选择") ])) : vue.createCommentVNode("v-if", true) ]), vue.createElementVNode("scroll-view", { "scroll-y": "", class: "list-area" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($data.currentCityList, (item) => { return vue.openBlock(), vue.createElementBlock("view", { class: "list-item", key: item.id, onClick: ($event) => $options.selectCityItem(item) }, vue.toDisplayString(item.name), 9, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )), $data.currentCityList.length === 0 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, style: { "padding": "20rpx", "color": "#999" } }, " 无数据 ")) : vue.createCommentVNode("v-if", true) ]) ]) ]) ])) : vue.createCommentVNode("v-if", true) ]); } const PagesMineSettingsProfileIndex = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["render", _sfc_render$j], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/settings/profile/index.vue"]]); const _sfc_main$j = { data() { return { authInfo: { realName: "", idCard: "", idCardFront: "", idCardBack: "", serviceTypes: [], authId: false, authQual: false, pendingAudit: false, qualImages: [] } }; }, onLoad() { this.loadAuthInfo(); }, methods: { navBack() { uni.navigateBack({ delta: 1 }); }, async loadAuthInfo() { try { const res = await getAuthInfo(); if (res.code === 200 && res.data) { this.authInfo = { realName: res.data.realName || "", idCard: res.data.idCard || "", idCardFront: res.data.idCardFrontUrl || "", idCardBack: res.data.idCardBackUrl || "", serviceTypes: res.data.serviceTypeList || [], authId: res.data.authId || false, authQual: res.data.authQual || false, pendingAudit: res.data.pendingAudit || false, qualImages: res.data.qualImageUrls ? res.data.qualImageUrls.split(",").filter(Boolean) : [] }; } } catch (e) { formatAppLog("error", "at pages/mine/settings/auth/index.vue:133", "加载认证信息失败", e); uni.showToast({ title: "加载失败", icon: "none" }); } }, maskIdCard(idCard) { if (!idCard || idCard.length < 8) return idCard; return idCard.substring(0, 4) + "**********" + idCard.substring(idCard.length - 4); }, editAuth() { uni.showModal({ title: "提示", content: "修改认证信息需要重新审核,审核期间无法接单,确定要继续吗?", success: (res) => { if (res.confirm) { uni.navigateTo({ url: "/pages/mine/settings/auth/edit" }); } } }); } } }; function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "custom-header" }, [ vue.createElementVNode("view", { class: "header-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0, style: { "transform": "rotate(180deg)" } }) ]), vue.createElementVNode("text", { class: "header-title" }, "认证信息"), vue.createElementVNode("view", { class: "header-right" }) ]), vue.createElementVNode("view", { class: "header-placeholder" }), vue.createElementVNode("view", { class: "card" }, [ vue.createElementVNode("view", { class: "section-header" }, [ vue.createElementVNode("view", { class: "orange-bar" }), vue.createElementVNode("text", { class: "section-title" }, "身份认证"), $data.authInfo.pendingAudit ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "tag-orange" }, "认证中")) : $data.authInfo.authId ? (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "tag-green" }, "已认证")) : (vue.openBlock(), vue.createElementBlock("view", { key: 2, class: "tag-gray" }, "未认证")) ]), vue.createElementVNode("view", { class: "info-row" }, [ vue.createElementVNode("text", { class: "label" }, "真实姓名"), vue.createElementVNode( "text", { class: "value" }, vue.toDisplayString($data.authInfo.realName || "未设置"), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "info-row" }, [ vue.createElementVNode("text", { class: "label" }, "证件号码"), vue.createElementVNode( "text", { class: "value" }, vue.toDisplayString($options.maskIdCard($data.authInfo.idCard) || "未设置"), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "id-card-row" }, [ $data.authInfo.idCardFront ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "id-card-box green-bg" }, [ vue.createElementVNode("image", { class: "id-card-img", src: $data.authInfo.idCardFront, mode: "aspectFill" }, null, 8, ["src"]), vue.createElementVNode("view", { class: "corner-tag" }, "人像面") ])) : (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "id-card-box green-bg" }, [ vue.createElementVNode("text", { class: "id-text" }, "ID Front"), vue.createElementVNode("view", { class: "corner-tag" }, "人像面") ])), $data.authInfo.idCardBack ? (vue.openBlock(), vue.createElementBlock("view", { key: 2, class: "id-card-box green-bg" }, [ vue.createElementVNode("image", { class: "id-card-img", src: $data.authInfo.idCardBack, mode: "aspectFill" }, null, 8, ["src"]), vue.createElementVNode("view", { class: "corner-tag" }, "国徽面") ])) : (vue.openBlock(), vue.createElementBlock("view", { key: 3, class: "id-card-box green-bg" }, [ vue.createElementVNode("text", { class: "id-text" }, "ID Back"), vue.createElementVNode("view", { class: "corner-tag" }, "国徽面") ])) ]) ]), vue.createElementVNode("view", { class: "card" }, [ vue.createElementVNode("view", { class: "section-header" }, [ vue.createElementVNode("view", { class: "orange-bar" }), vue.createElementVNode("text", { class: "section-title" }, "服务类型") ]), vue.createElementVNode("view", { class: "tags-row" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($data.authInfo.serviceTypes, (type, index) => { return vue.openBlock(), vue.createElementBlock( "view", { class: "service-tag", key: index }, vue.toDisplayString(type), 1 /* TEXT */ ); }), 128 /* KEYED_FRAGMENT */ )), $data.authInfo.serviceTypes.length === 0 ? (vue.openBlock(), vue.createElementBlock("text", { key: 0, class: "empty-text" }, "暂无服务类型")) : vue.createCommentVNode("v-if", true) ]) ]), vue.createElementVNode("view", { class: "card" }, [ vue.createElementVNode("view", { class: "section-header" }, [ vue.createElementVNode("view", { class: "orange-bar" }), vue.createElementVNode("text", { class: "section-title" }, "资质证书") ]), vue.createElementVNode( "text", { class: "sub-title" }, vue.toDisplayString($data.authInfo.authQual ? "已认证" : "未认证"), 1 /* TEXT */ ), vue.createElementVNode("view", { class: "cert-row" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($data.authInfo.qualImages, (img, index) => { return vue.openBlock(), vue.createElementBlock("view", { class: "cert-box yellow-bg", key: index }, [ vue.createElementVNode("image", { class: "cert-img", src: img, mode: "aspectFill" }, null, 8, ["src"]) ]); }), 128 /* KEYED_FRAGMENT */ )), $data.authInfo.qualImages.length === 0 ? (vue.openBlock(), vue.createElementBlock("text", { key: 0, class: "empty-text" }, "暂无资质证书")) : vue.createCommentVNode("v-if", true) ]) ]), vue.createElementVNode("view", { class: "bottom-btn-area" }, [ $data.authInfo.pendingAudit ? (vue.openBlock(), vue.createElementBlock("button", { key: 0, class: "action-btn disabled", disabled: "" }, "认证审核中...")) : (vue.openBlock(), vue.createElementBlock("button", { key: 1, class: "action-btn", onClick: _cache[1] || (_cache[1] = (...args) => $options.editAuth && $options.editAuth(...args)) }, "修改认证信息")), $data.authInfo.pendingAudit ? (vue.openBlock(), vue.createElementBlock("text", { key: 2, class: "tips" }, "认证信息正在审核中,请耐心等待")) : (vue.openBlock(), vue.createElementBlock("text", { key: 3, class: "tips" }, "修改认证信息需要重新审核,审核期间无法接单")) ]) ]); } const PagesMineSettingsAuthIndex = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$i], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/settings/auth/index.vue"]]); const _sfc_main$i = { data() { return { idCardFront: "", idCardBack: "", idCardFrontOssId: "", idCardBackOssId: "", serviceOptions: [], selectedServices: [], qualifications: {}, qualOssIds: {} }; }, async onLoad() { await this.loadServiceOptions(); this.loadAuthInfo(); }, methods: { async loadServiceOptions() { try { const res = await getServiceTypes(); this.serviceOptions = (res.data || []).map((item) => ({ id: String(item.id), name: item.name })); } catch (e) { formatAppLog("error", "at pages/mine/settings/auth/edit.vue:135", "加载服务类型失败", e); } }, async loadAuthInfo() { try { uni.showLoading({ title: "加载中..." }); const res = await getAuthInfo(); if (res.code === 200 && res.data) { this.idCardFront = res.data.idCardFrontUrl || ""; this.idCardBack = res.data.idCardBackUrl || ""; this.idCardFrontOssId = res.data.idCardFront || ""; this.idCardBackOssId = res.data.idCardBack || ""; let serviceIds = []; if (res.data.serviceTypes) { serviceIds = [...new Set( String(res.data.serviceTypes).replace(/[\[\]"']/g, "").split(",").map((s) => s.trim()).filter((id) => id && id !== "0" && id !== "null" && id !== "undefined") )]; } this.selectedServices = serviceIds; const qualUrlList = res.data.qualImageUrls ? res.data.qualImageUrls.split(",").filter(Boolean) : []; const qualOssIdList = res.data.qualImages ? res.data.qualImages.replace(/[\[\]"]/g, "").split(",").map((s) => s.trim()).filter(Boolean) : []; const validNames = serviceIds.map((sid) => this.getServiceName(sid)).filter(Boolean); validNames.forEach((name, idx) => { const start = Math.floor(idx * qualUrlList.length / validNames.length); const end = Math.floor((idx + 1) * qualUrlList.length / validNames.length); this.$set(this.qualifications, name, qualUrlList.slice(start, end)); this.$set(this.qualOssIds, name, qualOssIdList.slice(start, end)); }); } uni.hideLoading(); } catch (e) { uni.hideLoading(); formatAppLog("error", "at pages/mine/settings/auth/edit.vue:177", "加载认证信息失败", e); uni.showToast({ title: "加载失败", icon: "none" }); } }, navBack() { uni.navigateBack({ delta: 1 }); }, chooseImage(side) { uni.chooseImage({ count: 1, sizeType: ["compressed"], sourceType: ["album", "camera"], success: async (res) => { const tempPath = res.tempFilePaths[0]; if (side === "front") { this.idCardFront = tempPath; } else { this.idCardBack = tempPath; } try { uni.showLoading({ title: "上传中..." }); const uploadRes = await uploadFile(tempPath); if (side === "front") { this.idCardFrontOssId = uploadRes.data.ossId; } else { this.idCardBackOssId = uploadRes.data.ossId; } uni.hideLoading(); uni.showToast({ title: "上传成功", icon: "success" }); } catch (err) { uni.hideLoading(); formatAppLog("error", "at pages/mine/settings/auth/edit.vue:209", "上传身份证图片失败:", err); uni.showToast({ title: "上传失败", icon: "none" }); } } }); }, deleteImage(side) { if (side === "front") { this.idCardFront = ""; this.idCardFrontOssId = ""; } else { this.idCardBack = ""; this.idCardBackOssId = ""; } }, getServiceName(serviceId) { const found = this.serviceOptions.find((s) => String(s.id) === String(serviceId)); return found ? found.name : ""; }, toggleService(service) { const index = this.selectedServices.indexOf(service.id); if (index > -1) { this.selectedServices.splice(index, 1); this.$delete(this.qualifications, service.name); this.$delete(this.qualOssIds, service.name); } else { this.selectedServices.push(service.id); this.$set(this.qualifications, service.name, []); this.$set(this.qualOssIds, service.name, []); } this.$forceUpdate(); }, chooseQualImage(service) { uni.chooseImage({ count: 9, sizeType: ["compressed"], sourceType: ["album", "camera"], success: async (res) => { if (!this.qualifications[service]) { this.qualifications[service] = []; this.qualOssIds[service] = []; } for (const tempPath of res.tempFilePaths) { this.qualifications[service].push(tempPath); this.$forceUpdate(); try { uni.showLoading({ title: "上传中..." }); const uploadRes = await uploadFile(tempPath); this.qualOssIds[service].push(uploadRes.data.ossId); uni.hideLoading(); } catch (err) { uni.hideLoading(); formatAppLog("error", "at pages/mine/settings/auth/edit.vue:263", "上传资质图片失败:", err); } } } }); }, deleteQualImage(service, index) { this.qualifications[service].splice(index, 1); if (this.qualOssIds[service]) { this.qualOssIds[service].splice(index, 1); } this.$forceUpdate(); }, previewImage(service, index) { uni.previewImage({ urls: this.qualifications[service], current: index }); }, async submitAuth() { if (!this.idCardFront || !this.idCardBack) { uni.showToast({ title: "请上传身份证正反面", icon: "none" }); return; } if (this.selectedServices.length === 0) { uni.showToast({ title: "请选择服务类型", icon: "none" }); return; } for (const serviceId of this.selectedServices) { const name = this.getServiceName(serviceId); if (!this.qualifications[name] || this.qualifications[name].length === 0) { uni.showToast({ title: `请上传${name}资质`, icon: "none" }); return; } } uni.showModal({ title: "提示", content: "修改认证信息需要重新审核,审核期间无法接单,确定要继续吗?", success: (res) => { if (res.confirm) { this.doSubmit(); } } }); }, async doSubmit() { const allQualOssIds = []; Object.values(this.qualOssIds).forEach((ids) => { allQualOssIds.push(...ids); }); const submitData = { idCardFront: this.idCardFrontOssId, idCardBack: this.idCardBackOssId, serviceTypes: this.selectedServices.join(","), // 逗号分隔的服务类型ID qualifications: allQualOssIds.join(",") // 逗号分隔的资质图片OSS ID }; try { uni.showLoading({ title: "提交中..." }); await updateAuthInfo(submitData); uni.hideLoading(); uni.showToast({ title: "提交成功,等待审核", icon: "success", duration: 1500 }); setTimeout(() => { uni.navigateBack({ delta: 1 }); }, 1500); } catch (err) { uni.hideLoading(); formatAppLog("error", "at pages/mine/settings/auth/edit.vue:334", "提交失败:", err); uni.showToast({ title: "提交失败", icon: "none" }); } } } }; function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "edit-auth-container" }, [ vue.createElementVNode("view", { class: "custom-header" }, [ vue.createElementVNode("view", { class: "header-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0, style: { "transform": "rotate(180deg)" } }) ]), vue.createElementVNode("text", { class: "header-title" }, "修改认证信息"), vue.createElementVNode("view", { class: "header-right" }) ]), vue.createElementVNode("view", { class: "header-placeholder" }), vue.createElementVNode("view", { class: "warning-tip" }, [ vue.createElementVNode("text", { class: "warning-icon" }, "⚠"), vue.createElementVNode("text", { class: "warning-text" }, "若修改认证信息,将在审核通过后生效") ]), vue.createElementVNode("view", { class: "section-card" }, [ vue.createElementVNode("view", { class: "section-title" }, "身份认证"), vue.createElementVNode("text", { class: "section-subtitle" }, "点击图片修改"), vue.createElementVNode("view", { class: "id-card-row" }, [ vue.createElementVNode("view", { class: "id-card-upload", onClick: _cache[2] || (_cache[2] = ($event) => $options.chooseImage("front")) }, [ $data.idCardFront ? (vue.openBlock(), vue.createElementBlock("image", { key: 0, src: $data.idCardFront, class: "id-card-img", mode: "aspectFill" }, null, 8, ["src"])) : (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "id-card-placeholder" }, [ vue.createElementVNode("text", { class: "placeholder-text" }, "ID Front") ])), $data.idCardFront ? (vue.openBlock(), vue.createElementBlock("view", { key: 2, class: "delete-btn", onClick: _cache[1] || (_cache[1] = vue.withModifiers(($event) => $options.deleteImage("front"), ["stop"])) }, "×")) : vue.createCommentVNode("v-if", true), vue.createElementVNode("view", { class: "corner-tag" }, "人像面") ]), vue.createElementVNode("view", { class: "id-card-upload", onClick: _cache[4] || (_cache[4] = ($event) => $options.chooseImage("back")) }, [ $data.idCardBack ? (vue.openBlock(), vue.createElementBlock("image", { key: 0, src: $data.idCardBack, class: "id-card-img", mode: "aspectFill" }, null, 8, ["src"])) : (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "id-card-placeholder" }, [ vue.createElementVNode("text", { class: "placeholder-text" }, "ID Back") ])), $data.idCardBack ? (vue.openBlock(), vue.createElementBlock("view", { key: 2, class: "delete-btn", onClick: _cache[3] || (_cache[3] = vue.withModifiers(($event) => $options.deleteImage("back"), ["stop"])) }, "×")) : vue.createCommentVNode("v-if", true), vue.createElementVNode("view", { class: "corner-tag" }, "国徽面") ]) ]) ]), vue.createElementVNode("view", { class: "section-card" }, [ vue.createElementVNode("view", { class: "section-title" }, "服务类型"), vue.createElementVNode("text", { class: "section-subtitle" }, "可多选"), vue.createElementVNode("view", { class: "service-list" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($data.serviceOptions, (service, index) => { return vue.openBlock(), vue.createElementBlock("view", { class: "service-item", key: service.id, onClick: ($event) => $options.toggleService(service) }, [ vue.createElementVNode( "text", { class: "service-name" }, vue.toDisplayString(service.name), 1 /* TEXT */ ), vue.createElementVNode( "view", { class: vue.normalizeClass(["check-icon", { active: $data.selectedServices.map(String).includes(String(service.id)) }]) }, [ $data.selectedServices.map(String).includes(String(service.id)) ? (vue.openBlock(), vue.createElementBlock("text", { key: 0 }, "✓")) : vue.createCommentVNode("v-if", true) ], 2 /* CLASS */ ) ], 8, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )) ]) ]), vue.createElementVNode("view", { class: "section-card" }, [ vue.createElementVNode("view", { class: "section-title" }, "资质证书"), vue.createElementVNode("text", { class: "section-subtitle" }, "请上传对应服务的资质"), (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($data.selectedServices, (serviceId, index) => { return vue.openBlock(), vue.createElementBlock("view", { key: serviceId, class: "qual-section" }, [ vue.createElementVNode( "text", { class: "qual-title" }, vue.toDisplayString($options.getServiceName(serviceId)) + "资质", 1 /* TEXT */ ), vue.createElementVNode("view", { class: "qual-upload-row" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($data.qualifications[$options.getServiceName(serviceId)], (img, imgIndex) => { return vue.openBlock(), vue.createElementBlock("view", { class: "qual-item", key: imgIndex, onClick: ($event) => $options.previewImage($options.getServiceName(serviceId), imgIndex) }, [ vue.createElementVNode("image", { src: img, class: "qual-img", mode: "aspectFill" }, null, 8, ["src"]), vue.createElementVNode("view", { class: "delete-btn", onClick: vue.withModifiers(($event) => $options.deleteQualImage($options.getServiceName(serviceId), imgIndex), ["stop"]) }, "×", 8, ["onClick"]) ], 8, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )), vue.createElementVNode("view", { class: "qual-upload-btn", onClick: ($event) => $options.chooseQualImage($options.getServiceName(serviceId)) }, [ vue.createElementVNode("text", { class: "plus-icon" }, "+") ], 8, ["onClick"]) ]) ]); }), 128 /* KEYED_FRAGMENT */ )), $data.selectedServices.length === 0 ? (vue.openBlock(), vue.createElementBlock("text", { key: 0, class: "empty-hint" }, "请先选择服务类型")) : vue.createCommentVNode("v-if", true) ]), vue.createElementVNode("view", { class: "bottom-btn-area" }, [ vue.createElementVNode("button", { class: "submit-btn", onClick: _cache[5] || (_cache[5] = (...args) => $options.submitAuth && $options.submitAuth(...args)) }, "提交审核") ]) ]); } const PagesMineSettingsAuthEdit = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$h], ["__scopeId", "data-v-10d0f207"], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/settings/auth/edit.vue"]]); const _imports_1$4 = "/static/icons/shield.svg"; const _sfc_main$h = { data() { return { hasShieldIcon: false // 如果没有盾牌图标资源,暂时隐藏或用文字代替 }; }, methods: { navBack() { uni.navigateBack({ delta: 1 }); }, editBank() { uni.showToast({ title: "跳转修改银行卡页", icon: "none" }); } } }; function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "custom-header" }, [ vue.createElementVNode("view", { class: "header-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0, style: { "transform": "rotate(180deg)" } }) ]), vue.createElementVNode("text", { class: "header-title" }, "银行卡信息"), vue.createElementVNode("view", { class: "header-right" }) ]), vue.createElementVNode("view", { class: "header-placeholder" }), vue.createElementVNode("view", { class: "bank-card" }, [ vue.createElementVNode("view", { class: "card-top" }, [ vue.createElementVNode("view", { class: "bank-info" }, [ vue.createElementVNode("view", { class: "bank-icon-circle" }, [ vue.createElementVNode("text", { class: "bank-icon-text" }, "招") ]), vue.createElementVNode("text", { class: "bank-name" }, "招商银行") ]), vue.createElementVNode("view", { class: "card-type" }, "储蓄卡") ]), vue.createElementVNode("view", { class: "card-number" }, "622588******1234"), vue.createElementVNode("view", { class: "card-bg-circle" }) ]), vue.createElementVNode("button", { class: "action-btn", onClick: _cache[1] || (_cache[1] = (...args) => $options.editBank && $options.editBank(...args)) }, "修改银行卡信息"), vue.createElementVNode("view", { class: "security-tip" }, [ $data.hasShieldIcon ? (vue.openBlock(), vue.createElementBlock("image", { key: 0, class: "shield-icon", src: _imports_1$4 })) : vue.createCommentVNode("v-if", true), vue.createElementVNode("text", null, "信息已加密,仅用于收入发放") ]) ]); } const PagesMineSettingsBankIndex = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$g], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/settings/bank/index.vue"]]); const _sfc_main$g = { data() { return { phone: "", hasPassword: false }; }, onLoad() { this.loadProfile(); }, methods: { navBack() { uni.navigateBack({ delta: 1 }); }, async loadProfile() { try { const res = await getMyProfile(); if (res.code === 200 && res.data) { this.phone = res.data.phone || ""; this.hasPassword = !!res.data.hasPassword; } } catch (e) { formatAppLog("error", "at pages/mine/settings/security/index.vue:68", "加载个人信息失败", e); } }, maskPhone(phone) { if (!phone || phone.length < 11) return phone; return phone.substring(0, 3) + "****" + phone.substring(7); }, changeMobile() { uni.navigateTo({ url: "/pages/mine/settings/security/change-phone" }); }, changePassword() { uni.navigateTo({ url: "/pages/mine/settings/security/change-password" }); }, async deleteAccount() { uni.showModal({ title: "警示", content: "注销账号后将无法恢复,确定要继续吗?", success: async (res) => { if (res.confirm) { try { const result = await deleteAccount(); if (result.code === 200) { uni.showToast({ title: "账号已注销", icon: "success" }); setTimeout(() => { uni.reLaunch({ url: "/pages/login/login" }); }, 1500); } else { uni.showToast({ title: result.msg || "注销失败", icon: "none" }); } } catch (e) { formatAppLog("error", "at pages/mine/settings/security/index.vue:102", "注销账号失败", e); uni.showToast({ title: "注销失败", icon: "none" }); } } } }); } } }; function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "custom-header" }, [ vue.createElementVNode("view", { class: "header-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0, style: { "transform": "rotate(180deg)" } }) ]), vue.createElementVNode("text", { class: "header-title" }, "账号与安全"), vue.createElementVNode("view", { class: "header-right" }) ]), vue.createElementVNode("view", { class: "header-placeholder" }), vue.createElementVNode("view", { class: "section-title-security" }, "安全设置"), vue.createElementVNode("view", { class: "group-card" }, [ vue.createElementVNode("view", { class: "list-item", onClick: _cache[1] || (_cache[1] = (...args) => $options.changeMobile && $options.changeMobile(...args)) }, [ vue.createElementVNode("text", { class: "item-title" }, "手机号"), vue.createElementVNode("view", { class: "item-right" }, [ vue.createElementVNode( "text", { class: "item-value" }, vue.toDisplayString($options.maskPhone($data.phone) || "未设置"), 1 /* TEXT */ ), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]) ]), vue.createElementVNode("view", { class: "list-item", onClick: _cache[2] || (_cache[2] = (...args) => $options.changePassword && $options.changePassword(...args)) }, [ vue.createElementVNode("text", { class: "item-title" }, "登录密码"), vue.createElementVNode("view", { class: "item-right" }, [ vue.createElementVNode( "text", { class: "item-value" }, vue.toDisplayString($data.hasPassword ? "已设置" : "未设置"), 1 /* TEXT */ ), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]) ]) ]), vue.createElementVNode("view", { class: "section-title-security" }, "高级设置"), vue.createElementVNode("view", { class: "group-card" }, [ vue.createElementVNode("view", { class: "list-item no-border", onClick: _cache[3] || (_cache[3] = (...args) => $options.deleteAccount && $options.deleteAccount(...args)) }, [ vue.createElementVNode("text", { class: "item-title" }, "注销账号"), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]) ]) ]); } const PagesMineSettingsSecurityIndex = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$f], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/settings/security/index.vue"]]); const _sfc_main$f = { data() { return { name: "" }; }, onLoad(options) { if (options.name) { this.name = decodeURIComponent(options.name); } }, methods: { navBack() { uni.navigateBack({ delta: 1 }); }, // 提交修改 @author steelwei async submitChange() { if (!this.name || !this.name.trim()) { uni.showToast({ title: "请输入姓名", icon: "none" }); return; } if (this.name.trim().length < 2) { uni.showToast({ title: "姓名至少2个字符", icon: "none" }); return; } uni.showLoading({ title: "提交中..." }); try { const res = await updateName(this.name.trim()); if (res.code === 200) { uni.showToast({ title: "修改成功", icon: "success", duration: 2e3 }); uni.$emit("updateName", this.name.trim()); setTimeout(() => { uni.navigateBack({ delta: 1 }); }, 2e3); } else { uni.showToast({ title: res.msg || "修改失败", icon: "none" }); } } catch (error) { formatAppLog("error", "at pages/mine/settings/profile/edit-name.vue:94", "修改姓名失败:", error); uni.showToast({ title: "网络错误", icon: "none" }); } finally { uni.hideLoading(); } } } }; function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "custom-header" }, [ vue.createElementVNode("view", { class: "header-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0, style: { "transform": "rotate(180deg)" } }) ]), vue.createElementVNode("text", { class: "header-title" }, "修改姓名"), vue.createElementVNode("view", { class: "header-right" }) ]), vue.createElementVNode("view", { class: "header-placeholder" }), vue.createElementVNode("view", { class: "form-card" }, [ vue.createElementVNode("view", { class: "form-item no-border" }, [ vue.createElementVNode("text", { class: "form-label" }, "真实姓名"), vue.withDirectives(vue.createElementVNode( "input", { class: "form-input", type: "text", "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => $data.name = $event), placeholder: "请输入真实姓名", "placeholder-class": "placeholder", maxlength: "20" }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, $data.name] ]) ]) ]), vue.createElementVNode("view", { class: "btn-area" }, [ vue.createElementVNode("button", { class: "submit-btn", onClick: _cache[2] || (_cache[2] = (...args) => $options.submitChange && $options.submitChange(...args)) }, "确认修改") ]), vue.createElementVNode("view", { class: "tips" }, [ vue.createElementVNode("text", { class: "tips-text" }, "• 请输入您的真实姓名"), vue.createElementVNode("text", { class: "tips-text" }, "• 姓名将用于实名认证和订单服务") ]) ]); } const PagesMineSettingsProfileEditName = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["render", _sfc_render$e], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/settings/profile/edit-name.vue"]]); const _sfc_main$e = { data() { return { oldPassword: "", newPassword: "", confirmPassword: "" }; }, methods: { navBack() { uni.navigateBack({ delta: 1 }); }, // 提交修改 @author steelwei async submitChange() { if (!this.oldPassword) { uni.showToast({ title: "请输入旧密码", icon: "none" }); return; } if (!this.newPassword) { uni.showToast({ title: "请输入新密码", icon: "none" }); return; } if (this.newPassword.length < 6 || this.newPassword.length > 20) { uni.showToast({ title: "密码长度为6-20位", icon: "none" }); return; } if (this.newPassword !== this.confirmPassword) { uni.showToast({ title: "两次密码输入不一致", icon: "none" }); return; } uni.showLoading({ title: "提交中..." }); try { const res = await updatePassword(this.oldPassword, this.newPassword); if (res.code === 200) { uni.showToast({ title: "修改成功", icon: "success", duration: 2e3 }); setTimeout(() => { uni.navigateBack({ delta: 1 }); }, 2e3); } else { uni.showToast({ title: res.msg || "修改失败", icon: "none" }); } } catch (error) { formatAppLog("error", "at pages/mine/settings/security/change-password.vue:109", "修改密码失败:", error); uni.showToast({ title: "网络错误", icon: "none" }); } finally { uni.hideLoading(); } } } }; function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "custom-header" }, [ vue.createElementVNode("view", { class: "header-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0, style: { "transform": "rotate(180deg)" } }) ]), vue.createElementVNode("text", { class: "header-title" }, "修改密码"), vue.createElementVNode("view", { class: "header-right" }) ]), vue.createElementVNode("view", { class: "header-placeholder" }), vue.createElementVNode("view", { class: "form-card" }, [ vue.createElementVNode("view", { class: "form-item" }, [ vue.createElementVNode("text", { class: "form-label" }, "旧密码"), vue.withDirectives(vue.createElementVNode( "input", { class: "form-input", type: "password", "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => $data.oldPassword = $event), placeholder: "请输入旧密码", "placeholder-class": "placeholder" }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, $data.oldPassword] ]) ]), vue.createElementVNode("view", { class: "form-item" }, [ vue.createElementVNode("text", { class: "form-label" }, "新密码"), vue.withDirectives(vue.createElementVNode( "input", { class: "form-input", type: "password", "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => $data.newPassword = $event), placeholder: "请输入新密码(6-20位)", "placeholder-class": "placeholder" }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, $data.newPassword] ]) ]), vue.createElementVNode("view", { class: "form-item no-border" }, [ vue.createElementVNode("text", { class: "form-label" }, "确认密码"), vue.withDirectives(vue.createElementVNode( "input", { class: "form-input", type: "password", "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => $data.confirmPassword = $event), placeholder: "请再次输入新密码", "placeholder-class": "placeholder" }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, $data.confirmPassword] ]) ]) ]), vue.createElementVNode("view", { class: "btn-area" }, [ vue.createElementVNode("button", { class: "submit-btn", onClick: _cache[4] || (_cache[4] = (...args) => $options.submitChange && $options.submitChange(...args)) }, "确认修改") ]) ]); } const PagesMineSettingsSecurityChangePassword = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$d], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/settings/security/change-password.vue"]]); const _sfc_main$d = { data() { return { phone: "", code: "", countdown: 0, timer: null }; }, onUnload() { if (this.timer) { clearInterval(this.timer); } }, methods: { navBack() { uni.navigateBack({ delta: 1 }); }, // 发送验证码 @author steelwei sendCode() { if (!this.phone) { uni.showToast({ title: "请输入手机号", icon: "none" }); return; } if (!/^1[3-9]\d{9}$/.test(this.phone)) { uni.showToast({ title: "手机号格式不正确", icon: "none" }); return; } uni.showToast({ title: "验证码已发送", icon: "success" }); this.countdown = 60; this.timer = setInterval(() => { this.countdown--; if (this.countdown <= 0) { clearInterval(this.timer); } }, 1e3); }, // 提交修改 @author steelwei async submitChange() { if (!this.phone) { uni.showToast({ title: "请输入手机号", icon: "none" }); return; } if (!/^1[3-9]\d{9}$/.test(this.phone)) { uni.showToast({ title: "手机号格式不正确", icon: "none" }); return; } if (!this.code) { uni.showToast({ title: "请输入验证码", icon: "none" }); return; } uni.showLoading({ title: "提交中..." }); try { const res = await updatePhone(this.phone, this.code); if (res.code === 200) { uni.showToast({ title: "修改成功", icon: "success", duration: 2e3 }); setTimeout(() => { uni.navigateBack({ delta: 1 }); }, 2e3); } else { uni.showToast({ title: res.msg || "修改失败", icon: "none" }); } } catch (error) { formatAppLog("error", "at pages/mine/settings/security/change-phone.vue:139", "修改手机号失败:", error); uni.showToast({ title: "网络错误", icon: "none" }); } finally { uni.hideLoading(); } } } }; function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "custom-header" }, [ vue.createElementVNode("view", { class: "header-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0, style: { "transform": "rotate(180deg)" } }) ]), vue.createElementVNode("text", { class: "header-title" }, "修改手机号"), vue.createElementVNode("view", { class: "header-right" }) ]), vue.createElementVNode("view", { class: "header-placeholder" }), vue.createElementVNode("view", { class: "form-card" }, [ vue.createElementVNode("view", { class: "form-item" }, [ vue.createElementVNode("text", { class: "form-label" }, "新手机号"), vue.withDirectives(vue.createElementVNode( "input", { class: "form-input", type: "number", "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => $data.phone = $event), placeholder: "请输入新手机号", "placeholder-class": "placeholder", maxlength: "11" }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, $data.phone] ]) ]), vue.createElementVNode("view", { class: "form-item no-border" }, [ vue.createElementVNode("text", { class: "form-label" }, "验证码"), vue.withDirectives(vue.createElementVNode( "input", { class: "form-input", type: "number", "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => $data.code = $event), placeholder: "请输入验证码", "placeholder-class": "placeholder", maxlength: "6" }, null, 512 /* NEED_PATCH */ ), [ [vue.vModelText, $data.code] ]), vue.createElementVNode("button", { class: "code-btn", disabled: $data.countdown > 0, onClick: _cache[3] || (_cache[3] = (...args) => $options.sendCode && $options.sendCode(...args)) }, vue.toDisplayString($data.countdown > 0 ? `${$data.countdown}s` : "获取验证码"), 9, ["disabled"]) ]) ]), vue.createElementVNode("view", { class: "btn-area" }, [ vue.createElementVNode("button", { class: "submit-btn", onClick: _cache[4] || (_cache[4] = (...args) => $options.submitChange && $options.submitChange(...args)) }, "确认修改") ]), vue.createElementVNode("view", { class: "tips" }, [ vue.createElementVNode("text", { class: "tips-text" }, "• 修改手机号后,新手机号将作为登录账号"), vue.createElementVNode("text", { class: "tips-text" }, "• 请确保新手机号可以正常接收短信") ]) ]); } const PagesMineSettingsSecurityChangePhone = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$c], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/settings/security/change-phone.vue"]]); const _sfc_main$c = { data() { return {}; }, methods: { navBack() { uni.navigateBack({ delta: 1 }); }, switchChange(type, e) { formatAppLog("log", "at pages/mine/settings/notification/index.vue:41", "switch change", type, e.detail.value); } } }; function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "custom-header" }, [ vue.createElementVNode("view", { class: "header-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0, style: { "transform": "rotate(180deg)" } }) ]), vue.createElementVNode("text", { class: "header-title" }, "推送通知设置"), vue.createElementVNode("view", { class: "header-right" }) ]), vue.createElementVNode("view", { class: "header-placeholder" }), vue.createElementVNode("view", { class: "group-card" }, [ vue.createElementVNode("view", { class: "list-item" }, [ vue.createElementVNode("text", { class: "item-title" }, "系统消息通知"), vue.createElementVNode( "switch", { checked: "", color: "#FF5722", style: { "transform": "scale(0.8)" }, onChange: _cache[1] || (_cache[1] = ($event) => $options.switchChange("system", $event)) }, null, 32 /* NEED_HYDRATION */ ) ]), vue.createElementVNode("view", { class: "list-item no-border" }, [ vue.createElementVNode("text", { class: "item-title" }, "订单消息通知"), vue.createElementVNode( "switch", { checked: "", color: "#FF5722", style: { "transform": "scale(0.8)" }, onChange: _cache[2] || (_cache[2] = ($event) => $options.switchChange("order", $event)) }, null, 32 /* NEED_HYDRATION */ ) ]) ]), vue.createElementVNode("text", { class: "tips-text" }, "关闭通知后将收不到消息通知推送") ]); } const PagesMineSettingsNotificationIndex = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$b], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/settings/notification/index.vue"]]); const _imports_1$3 = "/static/logo.png"; const _sfc_main$b = { data() { return { version: "2.0.6" }; }, onLoad() { this.getAppVersion(); }, methods: { navBack() { uni.navigateBack({ delta: 1 }); }, goToDetail(id) { uni.navigateTo({ url: `/pages/mine/settings/about/agreement-detail?id=${id}` }); }, checkUpdate() { uni.showToast({ title: "已是最新版本", icon: "none" }); }, getAppVersion() { plus.runtime.getProperty(plus.runtime.appid, (widgetInfo) => { this.version = widgetInfo.version || "2.0.6"; }); } } }; function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "custom-header" }, [ vue.createElementVNode("view", { class: "header-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0, style: { "transform": "rotate(180deg)" } }) ]), vue.createElementVNode("text", { class: "header-title" }, "关于我们"), vue.createElementVNode("view", { class: "header-right" }) ]), vue.createElementVNode("view", { class: "header-placeholder" }), vue.createElementVNode("view", { class: "logo-area" }, [ vue.createElementVNode("image", { class: "app-logo", src: _imports_1$3, mode: "aspectFit" }), vue.createElementVNode("text", { class: "app-name" }, "履约者"), vue.createElementVNode( "text", { class: "app-version" }, "Version " + vue.toDisplayString($data.version), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "group-card" }, [ vue.createElementVNode("view", { class: "list-item", onClick: _cache[1] || (_cache[1] = ($event) => $options.goToDetail(1)) }, [ vue.createElementVNode("text", { class: "item-title" }, "服务协议"), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]), vue.createElementVNode("view", { class: "list-item", onClick: _cache[2] || (_cache[2] = ($event) => $options.goToDetail(2)) }, [ vue.createElementVNode("text", { class: "item-title" }, "隐私政策"), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]) ]) ]); } const PagesMineSettingsAboutIndex = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["render", _sfc_render$a], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/settings/about/index.vue"]]); const _imports_1$2 = "/static/icons/wallet_white.svg"; const _imports_2$2 = "/static/icons/arrow_right_gray.svg"; const bizTypeMap$3 = fulfillerEnum.FlfBalanceBizType; const _sfc_main$a = { data() { return { balance: "0.00", pendingBalance: "0.00", currentTab: 0, list: [], pageNum: 1, pageSize: 10, total: 0, loading: false }; }, computed: { displayList() { if (this.currentTab === 0) return this.list; if (this.currentTab === 1) return this.list.filter((item) => item.type === "income"); if (this.currentTab === 2) return this.list.filter((item) => item.type === "expense"); return []; } }, onShow() { this.fetchData(); this.fetchList(true); }, onReachBottom() { this.fetchList(); }, methods: { async fetchData() { try { const res = await getBalanceOnApp(); if (res.code === 200 && res.data) { this.balance = (res.data.balance / 100).toFixed(2); this.pendingBalance = (res.data.pendingBalance / 100).toFixed(2); } } catch (error) { formatAppLog("error", "at pages/mine/wallet/index.vue:135", "获取余额数据失败", error); } }, async fetchList(reset = false) { if (reset) { this.pageNum = 1; this.list = []; this.total = 0; } if (this.loading) return; if (!reset && this.list.length >= this.total && this.total !== 0) return; this.loading = true; try { const res = await pageBalanceOnApp({ pageNum: this.pageNum, pageSize: this.pageSize }); if (res.code === 200) { this.total = res.total || 0; const rows = res.rows || []; const mappedRows = rows.map((item) => { const isAdd = item.type === "add"; const uiType = isAdd ? "income" : "expense"; const title = bizTypeMap$3[item.bizType] || item.bizType || "其他"; let amountStr = (Math.abs(item.amount) / 100).toFixed(2); if (!isAdd) { amountStr = "-" + amountStr; } return { ...item, title, desc: item.reason || "", time: item.createTime || "", amount: amountStr, type: uiType, // 'income' or 'expense' for template class tag: title }; }); this.list = this.list.concat(mappedRows); this.pageNum++; } } catch (error) { formatAppLog("error", "at pages/mine/wallet/index.vue:182", "获取列表数据失败", error); } finally { this.loading = false; } }, navBack() { uni.navigateBack(); }, navToBill() { uni.navigateTo({ url: "/pages/mine/wallet/bill" }); }, switchTab(index) { this.currentTab = index; } } }; function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "nav-bar" }, [ vue.createElementVNode("view", { class: "nav-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0 }) ]), vue.createElementVNode("text", { class: "nav-title" }, "我的钱包"), vue.createElementVNode("view", { class: "nav-right" }) ]), vue.createElementVNode("view", { class: "wallet-card" }, [ vue.createElementVNode("view", { class: "bg-circle big" }), vue.createElementVNode("view", { class: "bg-circle small" }), vue.createElementVNode("view", { class: "card-content" }, [ vue.createElementVNode("view", { class: "card-top" }, [ vue.createElementVNode("view", { class: "app-info" }, [ vue.createElementVNode("image", { class: "app-logo", src: _imports_1$2, mode: "aspectFit" }), vue.createElementVNode("text", { class: "app-name" }, "履约者APP") ]), vue.createElementVNode("view", { class: "bill-btn", onClick: _cache[1] || (_cache[1] = (...args) => $options.navToBill && $options.navToBill(...args)) }, [ vue.createElementVNode("text", null, "账单") ]) ]), vue.createElementVNode("view", { class: "balance-container" }, [ vue.createElementVNode("view", { class: "balance-main" }, [ vue.createElementVNode("text", { class: "balance-label" }, "账户余额 (元)"), vue.createElementVNode( "text", { class: "balance-num" }, vue.toDisplayString($data.balance), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "balance-pending" }, [ vue.createElementVNode("text", { class: "pending-label" }, "待入账 (元)"), vue.createElementVNode( "text", { class: "pending-num" }, vue.toDisplayString($data.pendingBalance), 1 /* TEXT */ ) ]) ]) ]) ]), vue.createElementVNode("view", { class: "record-container" }, [ vue.createElementVNode("view", { class: "record-header" }, [ vue.createElementVNode("text", { class: "header-title" }, "最近账户余额变动记录"), vue.createElementVNode("view", { class: "header-more", onClick: _cache[2] || (_cache[2] = (...args) => $options.navToBill && $options.navToBill(...args)) }, [ vue.createElementVNode("text", null, "查看全部"), vue.createElementVNode("image", { class: "more-icon", src: _imports_2$2 }) ]) ]), vue.createElementVNode("view", { class: "tabs-row" }, [ vue.createElementVNode( "view", { class: vue.normalizeClass(["tab-item", { active: $data.currentTab === 0 }]), onClick: _cache[3] || (_cache[3] = ($event) => $options.switchTab(0)) }, [ vue.createElementVNode("text", null, "全部"), $data.currentTab === 0 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "tab-line" })) : vue.createCommentVNode("v-if", true) ], 2 /* CLASS */ ), vue.createElementVNode( "view", { class: vue.normalizeClass(["tab-item", { active: $data.currentTab === 1 }]), onClick: _cache[4] || (_cache[4] = ($event) => $options.switchTab(1)) }, [ vue.createElementVNode("text", null, "收入"), $data.currentTab === 1 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "tab-line" })) : vue.createCommentVNode("v-if", true) ], 2 /* CLASS */ ), vue.createElementVNode( "view", { class: vue.normalizeClass(["tab-item", { active: $data.currentTab === 2 }]), onClick: _cache[5] || (_cache[5] = ($event) => $options.switchTab(2)) }, [ vue.createElementVNode("text", null, "支出"), $data.currentTab === 2 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "tab-line" })) : vue.createCommentVNode("v-if", true) ], 2 /* CLASS */ ) ]), vue.createElementVNode("view", { class: "record-list" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($options.displayList, (item, index) => { return vue.openBlock(), vue.createElementBlock("view", { class: "list-item", key: index }, [ vue.createElementVNode("view", { class: "item-left" }, [ vue.createElementVNode( "text", { class: "item-title" }, vue.toDisplayString(item.title), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "item-desc" }, vue.toDisplayString(item.desc), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "item-time" }, vue.toDisplayString(item.time), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "item-right" }, [ vue.createElementVNode( "text", { class: vue.normalizeClass(["item-amount", { income: item.type === "income", expense: item.type === "expense" }]) }, vue.toDisplayString(item.type === "income" ? "+" : "") + vue.toDisplayString(item.amount), 3 /* TEXT, CLASS */ ), vue.createElementVNode("view", { class: "item-tag" }, [ vue.createElementVNode( "text", null, vue.toDisplayString(item.tag), 1 /* TEXT */ ) ]) ]) ]); }), 128 /* KEYED_FRAGMENT */ )) ]) ]) ]); } const PagesMineWalletIndex = /* @__PURE__ */ _export_sfc(_sfc_main$a, [["render", _sfc_render$9], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/wallet/index.vue"]]); const bizTypeMap$2 = fulfillerEnum.FlfBalanceBizType; const _sfc_main$9 = { data() { const d = /* @__PURE__ */ new Date(); return { currentTab: 0, year: d.getFullYear(), month: d.getMonth() + 1, groups: [] }; }, computed: { currentDate() { return `${this.year}-${String(this.month).padStart(2, "0")}`; }, displayGroups() { if (this.currentTab === 0) return this.groups; return this.groups.map((group) => { const filteredItems = group.items.filter((item) => { const type = this.currentTab === 1 ? "income" : "expense"; return item.type === type; }); return { ...group, items: filteredItems }; }).filter((group) => group.items.length > 0); } }, onShow() { this.fetchData(); }, methods: { async fetchData() { try { const res = await listBalanceOnApp({ year: this.year, month: this.month }); if (res.code === 200) { const list = res.data || []; let incomeTotal = 0; let expenseTotal = 0; const items = list.map((item) => { const isAdd = item.type === "add"; const uiType = isAdd ? "income" : "expense"; const title = bizTypeMap$2[item.bizType] || item.bizType || "其他"; let amountVal = Math.abs(item.amount) / 100; if (isAdd) { incomeTotal += amountVal; } else { expenseTotal += amountVal; } let amountStr = amountVal.toFixed(2); if (!isAdd) amountStr = "-" + amountStr; let timeStr = item.createTime || ""; if (timeStr.length >= 16) { timeStr = timeStr.substring(5, 16); } return { ...item, title, desc: item.reason || "", time: timeStr, amount: amountStr, type: uiType, tag: title }; }); this.groups = [ { month: `${this.month}月 ${this.year}`, income: incomeTotal.toFixed(2), expense: expenseTotal.toFixed(2), items } ]; } } catch (error) { formatAppLog("error", "at pages/mine/wallet/bill.vue:175", "获取账单记录失败", error); } }, onDateChange(e) { const val = e.detail.value; const [y, m] = val.split("-"); this.year = parseInt(y, 10); this.month = parseInt(m, 10); this.fetchData(); }, navBack() { uni.navigateBack(); }, switchTab(index) { this.currentTab = index; } } }; function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "nav-bar" }, [ vue.createElementVNode("view", { class: "nav-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0 }) ]), vue.createElementVNode("text", { class: "nav-title" }, "账单明细"), vue.createElementVNode("view", { class: "nav-right" }) ]), vue.createElementVNode("view", { class: "content-area" }, [ vue.createElementVNode("view", { class: "filter-area" }, [ vue.createElementVNode("view", { class: "tabs-row" }, [ vue.createElementVNode( "view", { class: vue.normalizeClass(["tab-item", { active: $data.currentTab === 0 }]), onClick: _cache[1] || (_cache[1] = ($event) => $options.switchTab(0)) }, [ vue.createElementVNode("text", null, "全部"), $data.currentTab === 0 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "tab-line" })) : vue.createCommentVNode("v-if", true) ], 2 /* CLASS */ ), vue.createElementVNode( "view", { class: vue.normalizeClass(["tab-item", { active: $data.currentTab === 1 }]), onClick: _cache[2] || (_cache[2] = ($event) => $options.switchTab(1)) }, [ vue.createElementVNode("text", null, "收入"), $data.currentTab === 1 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "tab-line" })) : vue.createCommentVNode("v-if", true) ], 2 /* CLASS */ ), vue.createElementVNode( "view", { class: vue.normalizeClass(["tab-item", { active: $data.currentTab === 2 }]), onClick: _cache[3] || (_cache[3] = ($event) => $options.switchTab(2)) }, [ vue.createElementVNode("text", null, "支出"), $data.currentTab === 2 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "tab-line" })) : vue.createCommentVNode("v-if", true) ], 2 /* CLASS */ ) ]), vue.createElementVNode("view", { class: "date-picker-wrap" }, [ vue.createElementVNode("picker", { mode: "date", fields: "month", value: $options.currentDate, onChange: _cache[4] || (_cache[4] = (...args) => $options.onDateChange && $options.onDateChange(...args)) }, [ vue.createElementVNode("view", { class: "date-picker" }, [ vue.createElementVNode( "text", { class: "date-text" }, vue.toDisplayString($data.year) + "年" + vue.toDisplayString(`${$data.month}`.padStart(2, "0")) + "月", 1 /* TEXT */ ), vue.createElementVNode("text", { class: "arrow-down" }, "﹀") ]) ], 40, ["value"]) ]) ]), vue.createElementVNode("scroll-view", { "scroll-y": "", class: "bill-list" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($options.displayGroups, (group, gIndex) => { return vue.openBlock(), vue.createElementBlock("view", { key: gIndex, class: "month-group" }, [ vue.createElementVNode("view", { class: "group-header" }, [ vue.createElementVNode( "text", { class: "month-title" }, vue.toDisplayString(group.month), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "month-summary" }, "收入 ¥" + vue.toDisplayString(group.income) + " 支出 ¥" + vue.toDisplayString(group.expense), 1 /* TEXT */ ) ]), (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(group.items, (item, index) => { return vue.openBlock(), vue.createElementBlock("view", { class: "list-item", key: index }, [ vue.createElementVNode( "view", { class: vue.normalizeClass(["item-icon-box", item.type]) }, [ vue.createElementVNode( "text", { class: "item-icon-symbol" }, vue.toDisplayString(item.type === "income" ? "+" : "-"), 1 /* TEXT */ ) ], 2 /* CLASS */ ), vue.createElementVNode("view", { class: "item-center" }, [ vue.createElementVNode( "text", { class: "item-title" }, vue.toDisplayString(item.title), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "item-desc" }, vue.toDisplayString(item.time) + " " + vue.toDisplayString(item.desc), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "item-right" }, [ vue.createElementVNode( "text", { class: vue.normalizeClass(["item-amount", { income: item.type === "income", expense: item.type === "expense" }]) }, vue.toDisplayString(item.type === "income" ? "+" : "") + vue.toDisplayString(item.amount), 3 /* TEXT, CLASS */ ), vue.createElementVNode("view", { class: "item-tag" }, [ vue.createElementVNode( "text", null, vue.toDisplayString(item.tag), 1 /* TEXT */ ) ]) ]) ]); }), 128 /* KEYED_FRAGMENT */ )) ]); }), 128 /* KEYED_FRAGMENT */ )), vue.createElementVNode("view", { class: "list-padding-bottom" }) ]) ]) ]); } const PagesMineWalletBill = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["render", _sfc_render$8], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/wallet/bill.vue"]]); function listAllLevelRights() { return request({ url: "/fulfiller/levelRights/listAll", method: "GET" }); } const _sfc_main$8 = { data() { return { currentIndex: 0, profile: null, levels: [], // 从后端获取的等级配置 rightsList: [], // 从后端获取的所有权益列表 isPopupShow: false, currentBenefit: null, pageLoading: true }; }, computed: { currentLevel() { return this.processedLevels[this.currentIndex]; }, // 合并等级与对应的权益详细信息 processedLevels() { if (!this.levels.length) return []; return this.levels.map((lvl) => { const benefits = (lvl.rights || []).map((rightId) => { return this.rightsList.find((r) => r.id === rightId); }).filter(Boolean); return { ...lvl, isCurrent: this.profile && this.profile.level === lvl.lvNo, benefits }; }).sort((a, b) => a.lvNo - b.lvNo); } }, async onLoad() { await this.initData(); }, methods: { async initData() { this.pageLoading = true; uni.showLoading({ title: "加载中..." }); try { const [profileRes, levelsRes, rightsRes] = await Promise.all([ getMyProfile(), listAllLevelConfigs(), listAllLevelRights() ]); this.profile = profileRes.data; this.levels = levelsRes.data || []; this.rightsList = rightsRes.data || []; if (this.profile) { const idx = this.processedLevels.findIndex((lvl) => lvl.lvNo === this.profile.level); if (idx !== -1) { this.currentIndex = idx; } } } catch (err) { formatAppLog("error", "at pages/mine/level/index.vue:157", "初始化等级页面失败:", err); uni.showToast({ title: "数据加载失败", icon: "none" }); } finally { this.pageLoading = false; uni.hideLoading(); } }, navBack() { uni.navigateBack(); }, swiperChange(e) { this.currentIndex = e.detail.current; }, changeLevel(index) { this.currentIndex = index; }, showBenefitDetail(benefit) { this.currentBenefit = benefit; this.isPopupShow = true; }, closePopup() { this.isPopupShow = false; } } }; function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "custom-header" }, [ vue.createElementVNode("view", { class: "header-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0, style: { "transform": "rotate(180deg)" } }) ]), vue.createElementVNode("text", { class: "header-title" }, "履约者等级权益"), vue.createElementVNode("view", { class: "header-right" }) ]), vue.createElementVNode("view", { class: "header-placeholder" }), !$data.pageLoading ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "swiper-container" }, [ vue.createElementVNode("swiper", { class: "level-swiper", "previous-margin": "80rpx", "next-margin": "80rpx", current: $data.currentIndex, onChange: _cache[1] || (_cache[1] = (...args) => $options.swiperChange && $options.swiperChange(...args)) }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($options.processedLevels, (level, index) => { return vue.openBlock(), vue.createElementBlock("swiper-item", { key: index, onClick: ($event) => $options.changeLevel(index) }, [ vue.createElementVNode( "view", { class: "level-card", style: vue.normalizeStyle({ transform: $data.currentIndex === index ? "scale(1)" : "scale(0.9)", backgroundImage: "url(" + level.backgroundUrl + ")", backgroundSize: "cover", backgroundPosition: "center" }) }, [ vue.createElementVNode("view", { class: "card-content" }, [ vue.createElementVNode("view", { class: "card-header" }, [ vue.createElementVNode( "view", { class: "level-badge" }, "L" + vue.toDisplayString(index + 1), 1 /* TEXT */ ), level.isCurrent ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "current-badge" }, "当前等级")) : vue.createCommentVNode("v-if", true) ]), vue.createElementVNode( "text", { class: "level-name" }, vue.toDisplayString(level.name), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "level-score" }, "所需积分: " + vue.toDisplayString(level.upgradePoints || 0), 1 /* TEXT */ ), vue.createElementVNode("image", { class: "crown-overlay", src: _imports_1$5, mode: "aspectFit" }) ]) ], 4 /* STYLE */ ) ], 8, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )) ], 40, ["current"]), vue.createElementVNode("view", { class: "swiper-dots" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($options.processedLevels, (item, index) => { return vue.openBlock(), vue.createElementBlock( "view", { class: vue.normalizeClass(["dot", { active: $data.currentIndex === index }]), key: index }, null, 2 /* CLASS */ ); }), 128 /* KEYED_FRAGMENT */ )) ]) ])) : vue.createCommentVNode("v-if", true), !$data.pageLoading && $options.currentLevel ? (vue.openBlock(), vue.createElementBlock("view", { key: 1, class: "benefits-title-row" }, [ vue.createElementVNode("text", { class: "benefits-title" }, "专属权益"), vue.createElementVNode( "text", { class: "benefits-count" }, "(" + vue.toDisplayString($options.currentLevel.benefits ? $options.currentLevel.benefits.length : 0) + ")", 1 /* TEXT */ ) ])) : vue.createCommentVNode("v-if", true), !$data.pageLoading && $options.currentLevel ? (vue.openBlock(), vue.createElementBlock("view", { key: 2, class: "benefits-grid" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($options.currentLevel.benefits, (benefit, index) => { return vue.openBlock(), vue.createElementBlock("view", { class: "benefit-item", key: index, onClick: ($event) => $options.showBenefitDetail(benefit) }, [ vue.createElementVNode("view", { class: "benefit-icon-wrapper" }, [ benefit.iconUrl ? (vue.openBlock(), vue.createElementBlock("image", { key: 0, class: "benefit-icon", src: benefit.iconUrl, mode: "aspectFit" }, null, 8, ["src"])) : (vue.openBlock(), vue.createElementBlock( "view", { key: 1, class: "benefit-icon-placeholder" }, vue.toDisplayString(benefit.name[0]), 1 /* TEXT */ )) ]), vue.createElementVNode( "text", { class: "benefit-name" }, vue.toDisplayString(benefit.name), 1 /* TEXT */ ) ], 8, ["onClick"]); }), 128 /* KEYED_FRAGMENT */ )), !$options.currentLevel.benefits || $options.currentLevel.benefits.length === 0 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "empty-benefits" }, [ vue.createElementVNode("text", null, "该等级暂无特殊权益") ])) : vue.createCommentVNode("v-if", true) ])) : vue.createCommentVNode("v-if", true), vue.createElementVNode( "view", { class: vue.normalizeClass(["popup-mask", { "show": $data.isPopupShow }]), onClick: _cache[4] || (_cache[4] = (...args) => $options.closePopup && $options.closePopup(...args)), onTouchmove: _cache[5] || (_cache[5] = vue.withModifiers(() => { }, ["stop", "prevent"])) }, [ vue.createElementVNode("view", { class: "popup-modal", onClick: _cache[3] || (_cache[3] = vue.withModifiers(() => { }, ["stop"])) }, [ vue.createElementVNode("view", { class: "popup-icon-wrapper" }, [ $data.currentBenefit && $data.currentBenefit.iconUrl ? (vue.openBlock(), vue.createElementBlock("image", { key: 0, class: "benefit-icon-large", src: $data.currentBenefit.iconUrl, mode: "aspectFit" }, null, 8, ["src"])) : (vue.openBlock(), vue.createElementBlock( "view", { key: 1, class: "benefit-icon-placeholder-large" }, vue.toDisplayString($data.currentBenefit ? $data.currentBenefit.name[0] : ""), 1 /* TEXT */ )) ]), vue.createElementVNode( "text", { class: "popup-title" }, vue.toDisplayString($data.currentBenefit ? $data.currentBenefit.name : ""), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "popup-desc" }, vue.toDisplayString($data.currentBenefit ? $data.currentBenefit.statement : ""), 1 /* TEXT */ ), vue.createElementVNode("button", { class: "popup-btn", onClick: _cache[2] || (_cache[2] = (...args) => $options.closePopup && $options.closePopup(...args)) }, "我知道了") ]) ], 34 /* CLASS, NEED_HYDRATION */ ) ]); } const PagesMineLevelIndex = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$7], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/level/index.vue"]]); const _imports_1$1 = "/static/icons/icon_order_msg.svg"; const _imports_2$1 = "/static/icons/icon_system_msg.svg"; const _sfc_main$7 = { data() { return {}; }, methods: { navBack() { uni.navigateBack(); }, navToOrderMsg() { uni.navigateTo({ url: "/pages/mine/message/order" }); }, navToSystemMsg() { uni.navigateTo({ url: "/pages/mine/message/system" }); } } }; function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "nav-bar" }, [ vue.createElementVNode("view", { class: "nav-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0, style: { "transform": "rotate(180deg)" } }) ]), vue.createElementVNode("text", { class: "nav-title" }, "消息中心"), vue.createElementVNode("view", { class: "nav-right" }, [ vue.createElementVNode("view", { class: "more-dots" }, [ vue.createElementVNode("view", { class: "dot" }), vue.createElementVNode("view", { class: "dot" }), vue.createElementVNode("view", { class: "dot" }) ]) ]) ]), vue.createElementVNode("view", { class: "nav-placeholder" }), vue.createElementVNode("view", { class: "message-list" }, [ vue.createElementVNode("view", { class: "message-item", onClick: _cache[1] || (_cache[1] = (...args) => $options.navToOrderMsg && $options.navToOrderMsg(...args)) }, [ vue.createElementVNode("view", { class: "icon-wrapper" }, [ vue.createElementVNode("image", { class: "msg-icon", src: _imports_1$1 }), vue.createElementVNode("view", { class: "red-dot-badge" }) ]), vue.createElementVNode("view", { class: "content-wrapper" }, [ vue.createElementVNode("view", { class: "top-row" }, [ vue.createElementVNode("text", { class: "msg-title" }, "订单消息"), vue.createElementVNode("text", { class: "msg-time" }, "5分钟前") ]), vue.createElementVNode("text", { class: "msg-preview" }, "你收到一个站长手动派单的新订单") ]) ]), vue.createElementVNode("view", { class: "message-item", onClick: _cache[2] || (_cache[2] = (...args) => $options.navToSystemMsg && $options.navToSystemMsg(...args)) }, [ vue.createElementVNode("view", { class: "icon-wrapper" }, [ vue.createElementVNode("image", { class: "msg-icon", src: _imports_2$1 }) ]), vue.createElementVNode("view", { class: "content-wrapper" }, [ vue.createElementVNode("view", { class: "top-row" }, [ vue.createElementVNode("text", { class: "msg-title" }, "系统消息"), vue.createElementVNode("text", { class: "msg-time" }, "7天前") ]), vue.createElementVNode("text", { class: "msg-preview" }, "你的健康证明认证审核已通过。") ]) ]) ]) ]); } const PagesMineMessageIndex = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["render", _sfc_render$6], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/message/index.vue"]]); const _sfc_main$6 = { methods: { navBack() { uni.navigateBack(); } } }; function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "nav-bar" }, [ vue.createElementVNode("view", { class: "nav-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0, style: { "transform": "rotate(180deg)" } }) ]), vue.createElementVNode("text", { class: "nav-title" }, "订单消息"), vue.createElementVNode("view", { class: "nav-right" }) ]), vue.createElementVNode("view", { class: "nav-placeholder" }), vue.createElementVNode("view", { class: "msg-group" }, [ vue.createElementVNode("view", { class: "date-label" }, "2099-12-28"), vue.createElementVNode("view", { class: "msg-card" }, [ vue.createElementVNode("view", { class: "card-header" }, [ vue.createElementVNode("text", { class: "card-title" }, "站长手动派单"), vue.createElementVNode("view", { class: "red-dot" }) ]), vue.createElementVNode("view", { class: "card-body" }, [ vue.createElementVNode("text", { class: "msg-text" }, "你收到一个新订单,请及时查看并接单。") ]), vue.createElementVNode("view", { class: "card-footer" }, [ vue.createElementVNode("text", { class: "order-id" }, "订单: 2099091503521"), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]) ]), vue.createElementVNode("view", { class: "msg-card" }, [ vue.createElementVNode("view", { class: "card-header" }, [ vue.createElementVNode("text", { class: "card-title" }, "系统自动派单") ]), vue.createElementVNode("view", { class: "card-body" }, [ vue.createElementVNode("text", { class: "msg-text" }, "你收到一个新订单,请及时查看并接单。") ]), vue.createElementVNode("view", { class: "card-footer" }, [ vue.createElementVNode("text", { class: "order-id" }, "订单: 2099091503523"), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]) ]) ]), vue.createElementVNode("view", { class: "msg-group" }, [ vue.createElementVNode("view", { class: "date-label" }, "2099-12-27"), vue.createElementVNode("view", { class: "msg-card" }, [ vue.createElementVNode("view", { class: "card-header" }, [ vue.createElementVNode("text", { class: "card-title" }, "系统取消派单") ]), vue.createElementVNode("view", { class: "card-body" }, [ vue.createElementVNode("text", { class: "msg-text" }, "订单由于超时未接单已被系统取消。") ]), vue.createElementVNode("view", { class: "card-footer" }, [ vue.createElementVNode("text", { class: "order-id" }, "订单: 2099091503111"), vue.createElementVNode("image", { class: "arrow-icon", src: _imports_3 }) ]) ]) ]) ]); } const PagesMineMessageOrder = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["render", _sfc_render$5], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/message/order.vue"]]); const _sfc_main$5 = { methods: { navBack() { uni.navigateBack(); }, navToDetail() { uni.navigateTo({ url: "/pages/mine/message/detail" }); } } }; function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "nav-bar" }, [ vue.createElementVNode("view", { class: "nav-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0, style: { "transform": "rotate(180deg)" } }) ]), vue.createElementVNode("text", { class: "nav-title" }, "系统消息"), vue.createElementVNode("view", { class: "nav-right" }) ]), vue.createElementVNode("view", { class: "nav-placeholder" }), vue.createElementVNode("view", { class: "sys-msg-list" }, [ vue.createElementVNode("view", { class: "date-label" }, "2023-11-01"), vue.createElementVNode("view", { class: "sys-card", onClick: _cache[1] || (_cache[1] = (...args) => $options.navToDetail && $options.navToDetail(...args)) }, [ vue.createElementVNode("view", { class: "sys-header" }, [ vue.createElementVNode("text", { class: "sys-title" }, "账号审核通过"), vue.createElementVNode("view", { class: "red-dot" }) ]), vue.createElementVNode("view", { class: "sys-content" }, [ vue.createElementVNode("text", { class: "sys-text" }, "恭喜,您的健康证已通过审核,现在可以开始接单了。") ]), vue.createElementVNode("view", { class: "sys-footer" }, [ vue.createElementVNode("text", { class: "sys-time" }, "10:00"), vue.createElementVNode("view", { class: "check-more" }, [ vue.createElementVNode("text", null, "查看详情"), vue.createElementVNode("image", { class: "arrow-icon-small", src: _imports_3 }) ]) ]) ]), vue.createElementVNode("view", { class: "sys-card" }, [ vue.createElementVNode("view", { class: "sys-header" }, [ vue.createElementVNode("text", { class: "sys-title" }, "活动奖励到账") ]), vue.createElementVNode("view", { class: "sys-content" }, [ vue.createElementVNode("text", { class: "sys-text" }, "您参与的“新手启航”活动奖励金 ¥50 已发放到您的账户。") ]), vue.createElementVNode("view", { class: "sys-footer" }, [ vue.createElementVNode("text", { class: "sys-time" }, "09:15"), vue.createElementVNode("view", { class: "check-more" }, [ vue.createElementVNode("text", null, "查看详情"), vue.createElementVNode("image", { class: "arrow-icon-small", src: _imports_3 }) ]) ]) ]), vue.createElementVNode("view", { class: "date-label" }, "2023-10-30"), vue.createElementVNode("view", { class: "sys-card" }, [ vue.createElementVNode("view", { class: "sys-header" }, [ vue.createElementVNode("text", { class: "sys-title" }, "系统维护通知") ]), vue.createElementVNode("view", { class: "sys-content" }, [ vue.createElementVNode("text", { class: "sys-text" }, "平台将于 11月5日 凌晨 02:00-04:00 进行系统维护,届时将无法接单。") ]), vue.createElementVNode("view", { class: "sys-footer" }, [ vue.createElementVNode("text", { class: "sys-time" }, "18:30"), vue.createElementVNode("view", { class: "check-more" }, [ vue.createElementVNode("text", null, "查看详情"), vue.createElementVNode("image", { class: "arrow-icon-small", src: _imports_3 }) ]) ]) ]) ]) ]); } const PagesMineMessageSystem = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$4], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/message/system.vue"]]); const _sfc_main$4 = { methods: { navBack() { uni.navigateBack(); } } }; function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "nav-bar" }, [ vue.createElementVNode("view", { class: "nav-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0, style: { "transform": "rotate(180deg)" } }) ]), vue.createElementVNode("text", { class: "nav-title" }, "消息详情"), vue.createElementVNode("view", { class: "nav-right" }) ]), vue.createElementVNode("view", { class: "nav-placeholder" }), vue.createElementVNode("view", { class: "detail-content" }, [ vue.createElementVNode("text", { class: "detail-title" }, "账号审核通过"), vue.createElementVNode("text", { class: "detail-time" }, "2023-11-01 10:00"), vue.createElementVNode("view", { class: "detail-body" }, [ vue.createElementVNode("text", null, "尊敬的用户,您的健康认证资料已通过平台审核。作为履约者,您现在可以正常接收并处理订单。请确保您熟读平台规则,遵守交通法规,安全配送。祝您工作愉快!") ]), vue.createElementVNode("view", { class: "detail-footer" }, [ vue.createElementVNode("view", { class: "divider" }), vue.createElementVNode("text", { class: "footer-text" }, "如有疑问,请咨询在线客服。") ]) ]) ]); } const PagesMineMessageDetail = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$3], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/message/detail.vue"]]); const _imports_1 = "/static/icons/diamond_white.svg"; const _imports_2 = "/static/icons/star_decor.svg"; const bizTypeMap$1 = fulfillerEnum.FlfPointsBizType; const _sfc_main$3 = { data() { return { points: 0, currentTab: 0, list: [], pageNum: 1, pageSize: 10, total: 0, loading: false }; }, computed: { displayList() { if (this.currentTab === 0) return this.list; const type = this.currentTab === 1 ? "income" : "expense"; return this.list.filter((item) => item.type === type); } }, onShow() { this.fetchPoints(); this.fetchList(true); }, onReachBottom() { this.fetchList(); }, methods: { async fetchPoints() { try { const res = await pointsOnApp(); if (res.code === 200) { this.points = res.data || 0; } } catch (error) { formatAppLog("error", "at pages/mine/points/index.vue:120", "获取当前积分失败", error); } }, async fetchList(reset = false) { if (reset) { this.pageNum = 1; this.list = []; this.total = 0; } if (this.loading) return; if (!reset && this.list.length >= this.total && this.total !== 0) return; this.loading = true; try { const res = await pagePointsOnApp({ pageNum: this.pageNum, pageSize: this.pageSize }); if (res.code === 200) { this.total = res.total || 0; const rows = res.rows || []; const mappedRows = rows.map((item) => { const isAdd = item.type === "add"; const uiType = isAdd ? "income" : "expense"; const title = bizTypeMap$1[item.bizType] || item.bizType || "其他"; let amountStr = Math.abs(item.amount); if (!isAdd) { amountStr = "-" + amountStr; } return { ...item, title, desc: item.reason || "", time: item.createTime || "", amount: amountStr, type: uiType, tag: title }; }); this.list = this.list.concat(mappedRows); this.pageNum++; } } catch (error) { formatAppLog("error", "at pages/mine/points/index.vue:163", "获取积分明细失败", error); } finally { this.loading = false; } }, navBack() { uni.navigateBack(); }, navToDetail() { uni.navigateTo({ url: "/pages/mine/points/detail" }); }, navToEquity() { }, switchTab(index) { this.currentTab = index; } } }; function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "nav-bar" }, [ vue.createElementVNode("view", { class: "nav-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0 }) ]), vue.createElementVNode("text", { class: "nav-title" }, "我的积分"), vue.createElementVNode("view", { class: "nav-right" }) ]), vue.createElementVNode("view", { class: "points-card" }, [ vue.createElementVNode("view", { class: "card-header" }, [ vue.createElementVNode("view", { class: "equity-btn", onClick: _cache[1] || (_cache[1] = (...args) => $options.navToEquity && $options.navToEquity(...args)) }, [ vue.createElementVNode("image", { class: "equity-icon", src: _imports_1 }), vue.createElementVNode("text", null, "积分权益") ]), vue.createElementVNode("view", { class: "detail-link", onClick: _cache[2] || (_cache[2] = (...args) => $options.navToDetail && $options.navToDetail(...args)) }, [ vue.createElementVNode("text", null, "明细") ]) ]), vue.createElementVNode("view", { class: "card-body" }, [ vue.createElementVNode("text", { class: "label" }, "当前积分"), vue.createElementVNode( "text", { class: "value" }, vue.toDisplayString($data.points), 1 /* TEXT */ ) ]), vue.createElementVNode("image", { class: "bg-decor", src: _imports_2, mode: "aspectFit" }) ]), vue.createElementVNode("view", { class: "record-container" }, [ vue.createElementVNode("view", { class: "record-header" }, [ vue.createElementVNode("text", { class: "header-title" }, "最近积分变动"), vue.createElementVNode("view", { class: "header-more", onClick: _cache[3] || (_cache[3] = (...args) => $options.navToDetail && $options.navToDetail(...args)) }, [ vue.createElementVNode("text", null, "查看全部"), vue.createElementVNode("image", { class: "more-icon", src: _imports_3 }) ]) ]), vue.createElementVNode("view", { class: "tabs-row" }, [ vue.createElementVNode( "view", { class: vue.normalizeClass(["tab-item", { active: $data.currentTab === 0 }]), onClick: _cache[4] || (_cache[4] = ($event) => $options.switchTab(0)) }, [ vue.createElementVNode("text", null, "全部"), $data.currentTab === 0 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "tab-line" })) : vue.createCommentVNode("v-if", true) ], 2 /* CLASS */ ), vue.createElementVNode( "view", { class: vue.normalizeClass(["tab-item", { active: $data.currentTab === 1 }]), onClick: _cache[5] || (_cache[5] = ($event) => $options.switchTab(1)) }, [ vue.createElementVNode("text", null, "获取"), $data.currentTab === 1 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "tab-line" })) : vue.createCommentVNode("v-if", true) ], 2 /* CLASS */ ), vue.createElementVNode( "view", { class: vue.normalizeClass(["tab-item", { active: $data.currentTab === 2 }]), onClick: _cache[6] || (_cache[6] = ($event) => $options.switchTab(2)) }, [ vue.createElementVNode("text", null, "扣减"), $data.currentTab === 2 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "tab-line" })) : vue.createCommentVNode("v-if", true) ], 2 /* CLASS */ ) ]), vue.createElementVNode("view", { class: "record-list" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($options.displayList, (item, index) => { return vue.openBlock(), vue.createElementBlock("view", { class: "list-item", key: index }, [ vue.createElementVNode("view", { class: "item-left" }, [ vue.createElementVNode( "text", { class: "item-title" }, vue.toDisplayString(item.title), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "item-desc" }, vue.toDisplayString(item.desc), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "item-time" }, vue.toDisplayString(item.time), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "item-right" }, [ vue.createElementVNode( "text", { class: vue.normalizeClass(["item-amount", { income: item.type === "income", expense: item.type === "expense" }]) }, vue.toDisplayString(item.type === "income" ? "+" : "") + vue.toDisplayString(item.amount), 3 /* TEXT, CLASS */ ), vue.createElementVNode("view", { class: "item-tag" }, [ vue.createElementVNode( "text", null, vue.toDisplayString(item.tag), 1 /* TEXT */ ) ]) ]) ]); }), 128 /* KEYED_FRAGMENT */ )) ]) ]) ]); } const PagesMinePointsIndex = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$2], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/points/index.vue"]]); const bizTypeMap = fulfillerEnum.FlfPointsBizType; const _sfc_main$2 = { data() { const d = /* @__PURE__ */ new Date(); return { currentTab: 0, year: d.getFullYear(), month: d.getMonth() + 1, groups: [] }; }, computed: { currentDate() { return `${this.year}-${String(this.month).padStart(2, "0")}`; }, displayGroups() { if (this.currentTab === 0) return this.groups; return this.groups.map((group) => { const filteredItems = group.items.filter((item) => { const type = this.currentTab === 1 ? "income" : "expense"; return item.type === type; }); return { ...group, items: filteredItems }; }).filter((group) => group.items.length > 0); } }, onShow() { this.fetchData(); }, methods: { async fetchData() { try { const res = await listPointsOnApp({ year: this.year, month: this.month }); if (res.code === 200) { const list = res.data || []; let incomeTotal = 0; let expenseTotal = 0; const items = list.map((item) => { const isAdd = item.type === "add"; const uiType = isAdd ? "income" : "expense"; const title = bizTypeMap[item.bizType] || item.bizType || "其他"; let amountVal = Math.abs(item.amount); if (isAdd) { incomeTotal += amountVal; } else { expenseTotal += amountVal; } let amountStr = String(amountVal); if (!isAdd) amountStr = "-" + amountStr; let timeStr = item.createTime || ""; if (timeStr.length >= 16) { timeStr = timeStr.substring(5, 16); } return { ...item, title, desc: item.reason || "", time: timeStr, amount: amountStr, type: uiType, tag: title }; }); this.groups = [ { month: `${this.month}月 ${this.year}`, income: String(incomeTotal), expense: String(expenseTotal), items } ]; } } catch (error) { formatAppLog("error", "at pages/mine/points/detail.vue:174", "获取积分明细记录失败", error); } }, onDateChange(e) { const val = e.detail.value; const [y, m] = val.split("-"); this.year = parseInt(y, 10); this.month = parseInt(m, 10); this.fetchData(); }, navBack() { uni.navigateBack(); }, switchTab(index) { this.currentTab = index; } } }; function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "nav-bar" }, [ vue.createElementVNode("view", { class: "nav-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0 }) ]), vue.createElementVNode("text", { class: "nav-title" }, "积分明细"), vue.createElementVNode("view", { class: "nav-right" }) ]), vue.createElementVNode("view", { class: "content-area" }, [ vue.createElementVNode("view", { class: "filter-area" }, [ vue.createElementVNode("view", { class: "tabs-row" }, [ vue.createElementVNode( "view", { class: vue.normalizeClass(["tab-item", { active: $data.currentTab === 0 }]), onClick: _cache[1] || (_cache[1] = ($event) => $options.switchTab(0)) }, [ vue.createElementVNode("text", null, "全部"), $data.currentTab === 0 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "tab-line" })) : vue.createCommentVNode("v-if", true) ], 2 /* CLASS */ ), vue.createElementVNode( "view", { class: vue.normalizeClass(["tab-item", { active: $data.currentTab === 1 }]), onClick: _cache[2] || (_cache[2] = ($event) => $options.switchTab(1)) }, [ vue.createElementVNode("text", null, "获取"), $data.currentTab === 1 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "tab-line" })) : vue.createCommentVNode("v-if", true) ], 2 /* CLASS */ ), vue.createElementVNode( "view", { class: vue.normalizeClass(["tab-item", { active: $data.currentTab === 2 }]), onClick: _cache[3] || (_cache[3] = ($event) => $options.switchTab(2)) }, [ vue.createElementVNode("text", null, "扣减"), $data.currentTab === 2 ? (vue.openBlock(), vue.createElementBlock("view", { key: 0, class: "tab-line" })) : vue.createCommentVNode("v-if", true) ], 2 /* CLASS */ ) ]), vue.createElementVNode("view", { class: "date-picker-wrap" }, [ vue.createElementVNode("picker", { mode: "date", fields: "month", value: $options.currentDate, onChange: _cache[4] || (_cache[4] = (...args) => $options.onDateChange && $options.onDateChange(...args)) }, [ vue.createElementVNode("view", { class: "date-picker" }, [ vue.createElementVNode( "text", { class: "date-text" }, vue.toDisplayString($data.year) + "年" + vue.toDisplayString(`${$data.month}`.padStart(2, "0")) + "月", 1 /* TEXT */ ), vue.createElementVNode("text", { class: "arrow-down" }, "﹀") ]) ], 40, ["value"]) ]) ]), vue.createElementVNode("scroll-view", { "scroll-y": "", class: "bill-list" }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList($options.displayGroups, (group, gIndex) => { return vue.openBlock(), vue.createElementBlock("view", { key: gIndex, class: "month-group" }, [ vue.createElementVNode("view", { class: "group-header" }, [ vue.createElementVNode( "text", { class: "month-title" }, vue.toDisplayString(group.month), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "month-summary" }, "获取 " + vue.toDisplayString(group.income) + " 扣减 " + vue.toDisplayString(group.expense), 1 /* TEXT */ ) ]), (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(group.items, (item, index) => { return vue.openBlock(), vue.createElementBlock("view", { class: "list-item", key: index }, [ vue.createElementVNode( "view", { class: vue.normalizeClass(["item-icon-box", item.type]) }, [ vue.createElementVNode( "text", { class: "item-icon-symbol" }, vue.toDisplayString(item.type === "income" ? "+" : "-"), 1 /* TEXT */ ) ], 2 /* CLASS */ ), vue.createElementVNode("view", { class: "item-center" }, [ vue.createElementVNode( "text", { class: "item-title" }, vue.toDisplayString(item.title), 1 /* TEXT */ ), vue.createElementVNode( "text", { class: "item-desc" }, vue.toDisplayString(item.time) + " " + vue.toDisplayString(item.desc), 1 /* TEXT */ ) ]), vue.createElementVNode("view", { class: "item-right" }, [ vue.createElementVNode( "text", { class: vue.normalizeClass(["item-amount", { income: item.type === "income", expense: item.type === "expense" }]) }, vue.toDisplayString(item.type === "income" ? "+" : "") + vue.toDisplayString(item.amount), 3 /* TEXT, CLASS */ ), vue.createElementVNode("view", { class: "item-tag" }, [ vue.createElementVNode( "text", null, vue.toDisplayString(item.tag), 1 /* TEXT */ ) ]) ]) ]); }), 128 /* KEYED_FRAGMENT */ )) ]); }), 128 /* KEYED_FRAGMENT */ )), vue.createElementVNode("view", { class: "list-padding-bottom" }) ]) ]) ]); } const PagesMinePointsDetail = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$1], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/points/detail.vue"]]); const _sfc_main$1 = { data() { return { id: null, title: "", content: "", loading: false }; }, onLoad(options) { if (options.id) { this.id = options.id; this.loadDetail(); } }, methods: { async loadDetail() { if (!this.id) return; uni.showLoading({ title: "加载中..." }); try { const res = await getAgreement(this.id); if (res.code === 200 && res.data) { this.title = res.data.title; this.content = res.data.content; uni.setNavigationBarTitle({ title: this.title }); } else { uni.showToast({ title: res.msg || "获取失败", icon: "none" }); } } catch (err) { formatAppLog("error", "at pages/mine/settings/about/agreement-detail.vue:56", "获取协议详情失败:", err); uni.showToast({ title: "网络错误", icon: "none" }); } finally { uni.hideLoading(); } }, navBack() { uni.navigateBack({ delta: 1 }); } } }; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("view", { class: "container" }, [ vue.createElementVNode("view", { class: "custom-header" }, [ vue.createElementVNode("view", { class: "header-left", onClick: _cache[0] || (_cache[0] = (...args) => $options.navBack && $options.navBack(...args)) }, [ vue.createElementVNode("image", { class: "back-icon", src: _imports_0, style: { "transform": "rotate(180deg)" } }) ]), vue.createElementVNode( "text", { class: "header-title" }, vue.toDisplayString($data.title || "协议详情"), 1 /* TEXT */ ), vue.createElementVNode("view", { class: "header-right" }) ]), vue.createElementVNode("view", { class: "header-placeholder" }), vue.createElementVNode("scroll-view", { "scroll-y": "", class: "content-scroll" }, [ vue.createElementVNode("view", { class: "content-card" }, [ vue.createElementVNode("rich-text", { nodes: $data.content, class: "rich-text" }, null, 8, ["nodes"]) ]), vue.createElementVNode("view", { class: "safe-area-inset-bottom" }) ]) ]); } const PagesMineSettingsAboutAgreementDetail = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render], ["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/pages/mine/settings/about/agreement-detail.vue"]]); __definePage("pages/login/login", PagesLoginLogin); __definePage("pages/recruit/landing", PagesRecruitLanding); __definePage("pages/recruit/form", PagesRecruitForm); __definePage("pages/recruit/auth", PagesRecruitAuth); __definePage("pages/recruit/qualifications", PagesRecruitQualifications); __definePage("pages/recruit/success", PagesRecruitSuccess); __definePage("pages/login/reset-pwd-verify", PagesLoginResetPwdVerify); __definePage("pages/login/reset-pwd-set", PagesLoginResetPwdSet); __definePage("pages/home/index", PagesHomeIndex); __definePage("pages/home/work-status", PagesHomeWorkStatus); __definePage("pages/orders/index", PagesOrdersIndex); __definePage("pages/orders/detail", PagesOrdersDetail); __definePage("pages/orders/anomaly", PagesOrdersAnomaly); __definePage("pages/mine/order-stats", PagesMineOrderStats); __definePage("pages/mine/rewards", PagesMineRewards); __definePage("pages/mine/rewards-all", PagesMineRewardsAll); __definePage("pages/mine/index", PagesMineIndex); __definePage("pages/mine/settings/index", PagesMineSettingsIndex); __definePage("pages/mine/settings/profile/index", PagesMineSettingsProfileIndex); __definePage("pages/mine/settings/auth/index", PagesMineSettingsAuthIndex); __definePage("pages/mine/settings/auth/edit", PagesMineSettingsAuthEdit); __definePage("pages/mine/settings/bank/index", PagesMineSettingsBankIndex); __definePage("pages/mine/settings/security/index", PagesMineSettingsSecurityIndex); __definePage("pages/mine/settings/profile/edit-name", PagesMineSettingsProfileEditName); __definePage("pages/mine/settings/security/change-password", PagesMineSettingsSecurityChangePassword); __definePage("pages/mine/settings/security/change-phone", PagesMineSettingsSecurityChangePhone); __definePage("pages/mine/settings/notification/index", PagesMineSettingsNotificationIndex); __definePage("pages/mine/settings/about/index", PagesMineSettingsAboutIndex); __definePage("pages/mine/wallet/index", PagesMineWalletIndex); __definePage("pages/mine/wallet/bill", PagesMineWalletBill); __definePage("pages/mine/level/index", PagesMineLevelIndex); __definePage("pages/mine/message/index", PagesMineMessageIndex); __definePage("pages/mine/message/order", PagesMineMessageOrder); __definePage("pages/mine/message/system", PagesMineMessageSystem); __definePage("pages/mine/message/detail", PagesMineMessageDetail); __definePage("pages/mine/points/index", PagesMinePointsIndex); __definePage("pages/mine/points/detail", PagesMinePointsDetail); __definePage("pages/mine/settings/about/agreement-detail", PagesMineSettingsAboutAgreementDetail); const _sfc_main = { onLaunch: function() { formatAppLog("log", "at App.vue:7", "App Launch"); uni.removeStorageSync("recruit_form_data"); uni.removeStorageSync("recruit_auth_data"); uni.removeStorageSync("recruit_qual_data"); if (isLoggedIn()) { startGpsTimer(); uni.switchTab({ url: "/pages/home/index" }); } }, onShow: function() { formatAppLog("log", "at App.vue:22", "App Show"); }, onHide: function() { formatAppLog("log", "at App.vue:25", "App Hide"); } }; const App = /* @__PURE__ */ _export_sfc(_sfc_main, [["__file", "E:/CodeProjects/Cursor/pet-system-fulfiller-app/App.vue"]]); function createApp() { const app = vue.createVueApp(App); return { app }; } const { app: __app__, Vuex: __Vuex__, Pinia: __Pinia__ } = createApp(); uni.Vuex = __Vuex__; uni.Pinia = __Pinia__; __app__.provide("__globalStyles", __uniConfig.styles); __app__._component.mpType = "app"; __app__._component.render = () => { }; __app__.mount("#app"); })(Vue);