Huanyi 2 долоо хоног өмнө
parent
commit
ec42666d1c

+ 15 - 3
.idea/workspace.xml

@@ -4,7 +4,9 @@
     <option name="autoReloadType" value="SELECTIVE" />
   </component>
   <component name="ChangeListManager">
-    <list default="true" id="e5f5f697-2bd4-4205-922a-fb106cdbbdf5" name="Changes" comment="修复BUG" />
+    <list default="true" id="e5f5f697-2bd4-4205-922a-fb106cdbbdf5" name="Changes" comment="整改完成">
+      <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
+    </list>
     <list id="6ae23f6a-53fe-4817-a1d7-106bcf184c18" name="New changelist" comment="不想提交的文件" />
     <option name="SHOW_DIALOG" value="false" />
     <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -91,6 +93,7 @@
       <workItem from="1774012995939" duration="18000" />
       <workItem from="1774229878524" duration="4279000" />
       <workItem from="1774277401659" duration="35000" />
+      <workItem from="1774345354357" duration="539000" />
     </task>
     <task id="LOCAL-00001" summary="1.完成app端履约者入驻相关功能开发&#10;2.完成app端履约者登录功能开发&#10;3.完成履约者个人中心功能开发">
       <option name="closed" value="true" />
@@ -188,7 +191,15 @@
       <option name="project" value="LOCAL" />
       <updated>1774277410829</updated>
     </task>
-    <option name="localTasksCounter" value="13" />
+    <task id="LOCAL-00013" summary="整改完成">
+      <option name="closed" value="true" />
+      <created>1774345369186</created>
+      <option name="number" value="00013" />
+      <option name="presentableId" value="LOCAL-00013" />
+      <option name="project" value="LOCAL" />
+      <updated>1774345369186</updated>
+    </task>
+    <option name="localTasksCounter" value="14" />
     <servers />
   </component>
   <component name="TypeScriptGeneratedFilesManager">
@@ -209,6 +220,7 @@
     <MESSAGE value="优化" />
     <MESSAGE value="修复bug" />
     <MESSAGE value="修复BUG" />
-    <option name="LAST_COMMIT_MESSAGE" value="修复BUG" />
+    <MESSAGE value="整改完成" />
+    <option name="LAST_COMMIT_MESSAGE" value="整改完成" />
   </component>
 </project>

+ 9 - 0
api/system/appSetting.js

@@ -0,0 +1,9 @@
+import request from '@/utils/request'
+
+// 获取应用设置
+export function getAppSetting(id) {
+  return request({
+    url: '/system/appSetting/' + id,
+    method: 'get'
+  })
+}

+ 9 - 0
api/system/customerServiceSetting.js

@@ -0,0 +1,9 @@
+import request from '@/utils/request'
+
+// 获取客服配置
+export function getCustomerServiceSetting(id) {
+  return request({
+    url: '/system/customerServiceSetting/' + id,
+    method: 'get'
+  })
+}

+ 2 - 2
manifest.json

@@ -2,8 +2,8 @@
     "name" : "履约者",
     "appid" : "__UNI__76F5C47",
     "description" : "履约者APP",
-    "versionName" : "0.1.2",
-    "versionCode" : 2,
+    "versionName" : "0.1.3",
+    "versionCode" : 3,
     "transformPx" : false,
     /* 5+App特有相关 */
     "app-plus" : {

+ 26 - 2
pages/login/logic.js

@@ -1,6 +1,7 @@
 import { loginByPassword, loginBySms } from '@/api/auth'
 import { sendSmsCode } from '@/api/resource/sms'
 import { getAgreement } from '@/api/system/agreement'
+import { getAppSetting } from '@/api/system/appSetting'
 import { setToken } from '@/utils/auth'
 import { startGpsTimer } from '@/utils/gps'
 
@@ -18,16 +19,39 @@ export default {
             showAgreementModal: false,
             agreementTitle: '',    // 协议标题
             agreementContent: '',  // 协议内容
-            loginLoading: false
+            loginLoading: false,
+            loginIconUrl: '/static/logo.png', // 登录图标
+            loginBackgroundUrl: '/static/header.png' // 登录背景
         }
     },
-    onLoad() {
+    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) {
+                console.error('获取应用配置失败:', err);
+            }
+        },
         /**
          * 显示协议弹窗
          * @param {Number} id 协议ID (1: 用户服务协议, 2: 隐私政策)

+ 2 - 2
pages/login/login.vue

@@ -2,14 +2,14 @@
   <view class="container">
     <!-- 顶部 Banner 区域 -->
     <view class="banner-area">
-      <image class="banner-img" src="/static/header.png" mode="widthFix"></image>
+      <image class="banner-img" :src="loginBackgroundUrl" mode="widthFix"></image>
     </view>
 
     <!-- 白色内容卡片 -->
     <view class="content-card">
       <!-- 悬浮 Logo -->
       <view class="logo-wrapper">
-        <image class="logo-img" src="/static/logo.png" mode="widthFix"></image>
+        <image class="logo-img" :src="loginIconUrl" mode="widthFix"></image>
       </view>
 
       <!-- 登录 Tab 切换 -->

+ 9 - 6
pages/mine/index.vue

@@ -108,11 +108,11 @@
                 <text class="menu-text">我的奖惩</text>
                 <image class="arrow-icon" src="/static/icons/chevron_right.svg"></image>
             </view>
-            <!-- <view class="menu-item" @click="openServicePopup">
+            <view class="menu-item" @click="openServicePopup">
                 <image class="menu-icon" src="/static/icons/headset_linear.svg"></image>
                 <text class="menu-text">联系客服</text>
                 <image class="arrow-icon" src="/static/icons/chevron_right.svg"></image>
-            </view> -->
+            </view>
         </view>
 
         <!-- 退出登录 -->
@@ -132,7 +132,7 @@
 
                 <view class="qr-section">
                     <text class="qr-title">客服二维码</text>
-                    <image class="qr-img" src="/static/logo.png" @click="previewQRCode"></image>
+                    <image class="qr-img" :src="customerSetting.qrCodeUrl || '/static/logo.png'" @click="previewQRCode"></image>
                     <text class="qr-desc">点击查看大图</text>
                 </view>
 
@@ -141,16 +141,19 @@
                         <image class="service-row-icon" src="/static/icons/headset_green.svg"></image>
                         <view class="service-info">
                             <text class="service-name">在线客服</text>
-                            <text class="service-desc">企业微信专属客服在线解答</text>
+                            <text class="service-desc">{{ customerSetting.wechatAccount || '企业微信专属客服在线解答' }}</text>
+                        </view>
+                        <view class="call-btn" @click="openOnlineService">
+                            <image class="phone-icon-small" src="/static/icons/headset_green.svg"></image>
+                            <text>企业微信</text>
                         </view>
-                        <image class="arrow-icon-small" src="/static/icons/chevron_right.svg"></image>
                     </view>
 
                     <view class="service-row">
                         <image class="service-row-icon" src="/static/icons/phone_orange.svg"></image>
                         <view class="service-info">
                             <text class="service-name">客服电话</text>
-                            <text class="service-desc">400-123-4567</text>
+                            <text class="service-desc">{{ customerSetting.phoneNumber || '暂无电话' }}</text>
                         </view>
                         <view class="call-btn" @click="callServicePhone">
                             <image class="phone-icon-small" src="/static/icons/phone_green.svg"></image>

+ 47 - 8
pages/mine/logic.js

@@ -1,6 +1,7 @@
 import { logout as logoutApi } from '@/api/auth'
 import { getMyProfile } from '@/api/fulfiller/fulfiller'
 import { listAllLevelConfigs } from '@/api/fulfiller/levelConfig'
+import { getCustomerServiceSetting } from '@/api/system/customerServiceSetting'
 import { clearAuth, isLoggedIn } from '@/utils/auth'
 import customTabbar from '@/components/custom-tabbar/index.vue'
 
@@ -14,7 +15,15 @@ export default {
             showLogoutPopup: false,
             profile: null,
             profileLoading: false,
-            levelConfigs: [] // 等级配置列表
+            levelConfigs: [], // 等级配置列表
+            customerSetting: {
+                wechatAccount: '',
+                phoneNumber: '400-123-4567',
+                qrCodeUrl: '/static/logo.png',
+                enterpriseWechatLink: '',
+                startServiceTime: '',
+                endServiceTime: ''
+            }
         }
     },
     computed: {
@@ -30,6 +39,7 @@ export default {
         if (isLoggedIn()) {
             this.loadProfile()
             this.loadLevelConfigs()
+            this.fetchCustomerServiceSetting()
         }
     },
     methods: {
@@ -53,6 +63,16 @@ export default {
                 console.error('加载等级配置失败:', err)
             }
         },
+        async fetchCustomerServiceSetting() {
+            try {
+                const res = await getCustomerServiceSetting(1)
+                if (res.code === 200 && res.data) {
+                    this.customerSetting = { ...this.customerSetting, ...res.data }
+                }
+            } catch (err) {
+                console.error('获取客服配置失败:', err)
+            }
+        },
         navToSettings() {
             uni.navigateTo({
                 url: '/pages/mine/settings/index'
@@ -100,20 +120,39 @@ export default {
             this.showServicePopup = false;
         },
         previewQRCode() {
+            if (!this.customerSetting.qrCodeUrl) return;
             uni.previewImage({
-                urls: ['/static/logo.png']
+                urls: [this.customerSetting.qrCodeUrl]
             });
         },
         openOnlineService() {
-            // 模拟跳转企业微信客服
-            uni.showToast({
-                title: '正在跳转企业微信客服...',
-                icon: 'none'
-            });
+            // 如果有企业微信链接,则打开
+            if (this.customerSetting.enterpriseWechatLink) {
+                // #ifdef H5
+                window.location.href = this.customerSetting.enterpriseWechatLink;
+                // #endif
+                // #ifndef H5
+                uni.setClipboardData({
+                    data: this.customerSetting.wechatAccount || this.customerSetting.enterpriseWechatLink,
+                    success: () => {
+                        uni.showToast({ title: '链接已复制,请在浏览器或微信打开', icon: 'none' });
+                    }
+                });
+                // #endif
+            } else {
+                uni.showToast({
+                    title: '在线客服暂未配置',
+                    icon: 'none'
+                });
+            }
         },
         callServicePhone() {
+            if (!this.customerSetting.phoneNumber) {
+                uni.showToast({ title: '暂无联系电话', icon: 'none' });
+                return;
+            }
             uni.makePhoneCall({
-                phoneNumber: '400-123-4567'
+                phoneNumber: this.customerSetting.phoneNumber
             });
         },
         logout() {

BIN
unpackage/cache/apk/__UNI__76F5C47_cm.apk


+ 1 - 1
unpackage/cache/apk/apkurl

@@ -1 +1 @@
-https://app.liuyingyong.cn/build/download/4a05bfe0-2747-11f1-8c1e-3d7a3a479d7d
+https://app.liuyingyong.cn/build/download/e9e3d270-2818-11f1-b508-27f624244336

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
unpackage/cache/apk/cmManifestCache.json


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 1 - 1
unpackage/cache/wgt/__UNI__76F5C47/app-config-service.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
unpackage/cache/wgt/__UNI__76F5C47/app-service.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
unpackage/cache/wgt/__UNI__76F5C47/manifest.json


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 1 - 1
unpackage/dist/build/app-plus/app-config-service.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
unpackage/dist/build/app-plus/app-service.js


+ 3 - 3
unpackage/dist/build/app-plus/manifest.json

@@ -7,8 +7,8 @@
   "id": "__UNI__76F5C47",
   "name": "履约者",
   "version": {
-    "name": "0.1.2",
-    "code": 2
+    "name": "0.1.3",
+    "code": 3
   },
   "description": "履约者APP",
   "developer": {
@@ -127,7 +127,7 @@
     "uni-app": {
       "control": "uni-v3",
       "vueVersion": "3",
-      "compilerVersion": "5.04",
+      "compilerVersion": "5.05",
       "nvueCompiler": "uni-app",
       "renderer": "auto",
       "nvue": {

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 1 - 1
unpackage/dist/dev/app-plus/app-config-service.js


+ 188 - 77
unpackage/dist/dev/app-plus/app-service.js

@@ -302,6 +302,12 @@ if (uni.restoreGlobal) {
       method: "get"
     });
   }
+  function getAppSetting(id) {
+    return request({
+      url: "/system/appSetting/" + id,
+      method: "get"
+    });
+  }
   const logic$9 = {
     data() {
       return {
@@ -319,15 +325,38 @@ if (uni.restoreGlobal) {
         // 协议标题
         agreementContent: "",
         // 协议内容
-        loginLoading: false
+        loginLoading: false,
+        loginIconUrl: "/static/logo.png",
+        // 登录图标
+        loginBackgroundUrl: "/static/header.png"
+        // 登录背景
       };
     },
-    onLoad() {
+    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: 隐私政策)
@@ -344,7 +373,7 @@ if (uni.restoreGlobal) {
             uni.showToast({ title: res.msg || "获取协议失败", icon: "none" });
           }
         } catch (err) {
-          formatAppLog("error", "at pages/login/logic.js:47", "获取协议详情失败:", err);
+          formatAppLog("error", "at pages/login/logic.js:71", "获取协议详情失败:", err);
         } finally {
           uni.hideLoading();
         }
@@ -376,7 +405,7 @@ if (uni.restoreGlobal) {
                               uni.showToast({ title: '验证码已发送', icon: 'none' });
                           }
                       } catch (err) {
-                          __f__('error','at pages/login/logic.js:79','发送验证码失败:', err);
+                          __f__('error','at pages/login/logic.js:103','发送验证码失败:', err);
                       }
                   }, */
       async handleLogin() {
@@ -415,7 +444,7 @@ if (uni.restoreGlobal) {
             });
           }, 1e3);
         } catch (err) {
-          formatAppLog("error", "at pages/login/logic.js:144", "登录失败:", err);
+          formatAppLog("error", "at pages/login/logic.js:168", "登录失败:", err);
         } finally {
           this.loginLoading = false;
           uni.hideLoading();
@@ -504,8 +533,6 @@ if (uni.restoreGlobal) {
     )) : 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 _imports_0$3 = "/static/header.png";
-  const _imports_1$8 = "/static/logo.png";
   const _sfc_main$D = {
     ...logic$9,
     components: {
@@ -518,17 +545,17 @@ if (uni.restoreGlobal) {
       vue.createElementVNode("view", { class: "banner-area" }, [
         vue.createElementVNode("image", {
           class: "banner-img",
-          src: _imports_0$3,
+          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: _imports_1$8,
+            src: _ctx.loginIconUrl,
             mode: "widthFix"
-          })
+          }, null, 8, ["src"])
         ]),
         vue.createElementVNode("view", { class: "tabs" }, [
           vue.createElementVNode("view", { class: "tab-item active" }, [
@@ -4304,27 +4331,37 @@ if (uni.restoreGlobal) {
         if (type === "merchant") {
           phoneNum = "18900008451";
         } else if (type === "customer") {
-          phoneNum = (targetItem == null ? void 0 : targetItem.customerPhone) || "13800000001";
+          phoneNum = targetItem == null ? void 0 : targetItem.customerPhone;
         }
-        if (phoneNum) {
-          uni.showModal({
-            title: "拨号提示",
-            content: `是否呼叫号码: ${phoneNum}?`,
-            confirmText: "呼叫",
-            success: (res) => {
-              if (res.confirm) {
-                uni.makePhoneCall({
-                  phoneNumber: phoneNum,
-                  fail: (err) => {
-                    formatAppLog("error", "at pages/orders/logic.js:278", "拨号失败:", err);
-                    uni.showToast({ title: "无法唤起拨号盘", icon: "none" });
-                  }
-                });
-              }
-            }
-          });
+        if (!phoneNum) {
+          uni.showToast({ title: "未找到电话号码", icon: "none" });
+          this.activeCallItem = null;
+          return;
         }
-        this.activeCallItem = null;
+        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 || "") });
@@ -4467,7 +4504,7 @@ if (uni.restoreGlobal) {
                   this.loadOrders();
                 }, 1500);
               } catch (err) {
-                formatAppLog("error", "at pages/orders/logic.js:423", "取消订单失败:", err);
+                formatAppLog("error", "at pages/orders/logic.js:482", "取消订单失败:", err);
                 uni.showToast({ title: "取消失败", icon: "none" });
               } finally {
                 uni.hideLoading();
@@ -5995,10 +6032,10 @@ if (uni.restoreGlobal) {
     }
   };
   const _imports_12 = "/static/icons/phone_orange.svg";
-  const _imports_1$7 = "/static/icons/clock.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$6 = "/static/icons/camera_grey.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";
@@ -6179,7 +6216,7 @@ if (uni.restoreGlobal) {
               vue.createElementVNode("view", { class: "si-row time-row" }, [
                 vue.createElementVNode("image", {
                   class: "si-icon outline",
-                  src: _imports_1$7
+                  src: _imports_1$8
                 }),
                 vue.createElementVNode("view", { class: "si-content" }, [
                   vue.createElementVNode("text", { class: "si-label" }, "服务时间"),
@@ -6338,7 +6375,7 @@ if (uni.restoreGlobal) {
               }, [
                 vue.createElementVNode("image", {
                   class: "upload-icon-large",
-                  src: _imports_1$6
+                  src: _imports_1$7
                 }),
                 vue.createElementVNode("text", { class: "upload-text-large" }, "上传图或视频")
               ])
@@ -6369,7 +6406,7 @@ if (uni.restoreGlobal) {
               vue.createElementVNode("view", { class: "bi-row" }, [
                 vue.createElementVNode("image", {
                   class: "si-icon outline",
-                  src: _imports_1$7
+                  src: _imports_1$8
                 }),
                 vue.createElementVNode("view", { class: "bi-content" }, [
                   vue.createElementVNode("text", { class: "bi-label" }, "下单时间"),
@@ -6824,7 +6861,7 @@ if (uni.restoreGlobal) {
                   }, [
                     vue.createElementVNode("image", {
                       class: "um-add-icon",
-                      src: _imports_1$6
+                      src: _imports_1$7
                     }),
                     vue.createElementVNode("text", { class: "um-add-text" }, "拍摄/上传")
                   ])) : vue.createCommentVNode("v-if", true)
@@ -7348,7 +7385,7 @@ if (uni.restoreGlobal) {
             }, [
               vue.createElementVNode("image", {
                 class: "ano-add-icon",
-                src: _imports_1$6
+                src: _imports_1$7
               }),
               vue.createElementVNode("text", { class: "ano-add-text" }, "上传")
             ])) : vue.createCommentVNode("v-if", true)
@@ -8531,6 +8568,12 @@ if (uni.restoreGlobal) {
       method: "GET"
     });
   }
+  function getCustomerServiceSetting(id) {
+    return request({
+      url: "/system/customerServiceSetting/" + id,
+      method: "get"
+    });
+  }
   const logic = {
     components: {
       customTabbar
@@ -8541,8 +8584,16 @@ if (uni.restoreGlobal) {
         showLogoutPopup: false,
         profile: null,
         profileLoading: false,
-        levelConfigs: []
+        levelConfigs: [],
         // 等级配置列表
+        customerSetting: {
+          wechatAccount: "",
+          phoneNumber: "400-123-4567",
+          qrCodeUrl: "/static/logo.png",
+          enterpriseWechatLink: "",
+          startServiceTime: "",
+          endServiceTime: ""
+        }
       };
     },
     computed: {
@@ -8559,6 +8610,7 @@ if (uni.restoreGlobal) {
       if (isLoggedIn()) {
         this.loadProfile();
         this.loadLevelConfigs();
+        this.fetchCustomerServiceSetting();
       }
     },
     methods: {
@@ -8570,7 +8622,7 @@ if (uni.restoreGlobal) {
           const res = await getMyProfile();
           this.profile = res.data || null;
         } catch (err) {
-          formatAppLog("error", "at pages/mine/logic.js:43", "获取个人信息失败:", err);
+          formatAppLog("error", "at pages/mine/logic.js:53", "获取个人信息失败:", err);
         } finally {
           this.profileLoading = false;
         }
@@ -8580,7 +8632,17 @@ if (uni.restoreGlobal) {
           const res = await listAllLevelConfigs();
           this.levelConfigs = res.data || [];
         } catch (err) {
-          formatAppLog("error", "at pages/mine/logic.js:53", "加载等级配置失败:", 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() {
@@ -8630,19 +8692,34 @@ if (uni.restoreGlobal) {
         this.showServicePopup = false;
       },
       previewQRCode() {
+        if (!this.customerSetting.qrCodeUrl)
+          return;
         uni.previewImage({
-          urls: ["/static/logo.png"]
+          urls: [this.customerSetting.qrCodeUrl]
         });
       },
       openOnlineService() {
-        uni.showToast({
-          title: "正在跳转企业微信客服...",
-          icon: "none"
-        });
+        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: "400-123-4567"
+          phoneNumber: this.customerSetting.phoneNumber
         });
       },
       logout() {
@@ -8665,15 +8742,16 @@ if (uni.restoreGlobal) {
     }
   };
   const _imports_0$1 = "/static/icons/motorbike.svg";
-  const _imports_1$5 = "/static/icons/location.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$4 = "/static/icons/crown.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/close_gray.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 = {
@@ -8736,7 +8814,7 @@ if (uni.restoreGlobal) {
                 vue.createElementVNode("view", { class: "detail-row" }, [
                   vue.createElementVNode("image", {
                     class: "small-icon",
-                    src: _imports_1$5
+                    src: _imports_1$6
                   }),
                   vue.createElementVNode(
                     "text",
@@ -8774,7 +8852,7 @@ if (uni.restoreGlobal) {
               vue.createElementVNode("view", { class: "vip-left" }, [
                 vue.createElementVNode("image", {
                   class: "vip-icon",
-                  src: _imports_1$4
+                  src: _imports_1$5
                 }),
                 vue.createElementVNode("view", { class: "vip-text" }, [
                   vue.createElementVNode(
@@ -8889,43 +8967,57 @@ if (uni.restoreGlobal) {
                 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[7] || (_cache[7] = (...args) => _ctx.logout && _ctx.logout(...args))
+            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[13] || (_cache[13] = (...args) => _ctx.closeServicePopup && _ctx.closeServicePopup(...args))
+            onClick: _cache[15] || (_cache[15] = (...args) => _ctx.closeServicePopup && _ctx.closeServicePopup(...args))
           }, [
             vue.createElementVNode("view", {
               class: "service-popup",
-              onClick: _cache[12] || (_cache[12] = vue.withModifiers(() => {
+              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_9,
-                  onClick: _cache[8] || (_cache[8] = (...args) => _ctx.closeServicePopup && _ctx.closeServicePopup(...args))
+                  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: _imports_1$8,
-                  onClick: _cache[9] || (_cache[9] = (...args) => _ctx.previewQRCode && _ctx.previewQRCode(...args))
-                }),
+                  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[10] || (_cache[10] = (...args) => _ctx.openOnlineService && _ctx.openOnlineService(...args))
+                  onClick: _cache[12] || (_cache[12] = (...args) => _ctx.openOnlineService && _ctx.openOnlineService(...args))
                 }, [
                   vue.createElementVNode("image", {
                     class: "service-row-icon",
@@ -8933,12 +9025,24 @@ if (uni.restoreGlobal) {
                   }),
                   vue.createElementVNode("view", { class: "service-info" }, [
                     vue.createElementVNode("text", { class: "service-name" }, "在线客服"),
-                    vue.createElementVNode("text", { class: "service-desc" }, "企业微信专属客服在线解答")
+                    vue.createElementVNode(
+                      "text",
+                      { class: "service-desc" },
+                      vue.toDisplayString(_ctx.customerSetting.wechatAccount || "企业微信专属客服在线解答"),
+                      1
+                      /* TEXT */
+                    )
                   ]),
-                  vue.createElementVNode("image", {
-                    class: "arrow-icon-small",
-                    src: _imports_3
-                  })
+                  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", {
@@ -8947,11 +9051,17 @@ if (uni.restoreGlobal) {
                   }),
                   vue.createElementVNode("view", { class: "service-info" }, [
                     vue.createElementVNode("text", { class: "service-name" }, "客服电话"),
-                    vue.createElementVNode("text", { class: "service-desc" }, "400-123-4567")
+                    vue.createElementVNode(
+                      "text",
+                      { class: "service-desc" },
+                      vue.toDisplayString(_ctx.customerSetting.phoneNumber || "暂无电话"),
+                      1
+                      /* TEXT */
+                    )
                   ]),
                   vue.createElementVNode("view", {
                     class: "call-btn",
-                    onClick: _cache[11] || (_cache[11] = (...args) => _ctx.callServicePhone && _ctx.callServicePhone(...args))
+                    onClick: _cache[13] || (_cache[13] = (...args) => _ctx.callServicePhone && _ctx.callServicePhone(...args))
                   }, [
                     vue.createElementVNode("image", {
                       class: "phone-icon-small",
@@ -8967,14 +9077,14 @@ if (uni.restoreGlobal) {
             "view",
             {
               class: vue.normalizeClass(["logout-popup-mask", { "show": _ctx.showLogoutPopup }]),
-              onClick: _cache[17] || (_cache[17] = (...args) => _ctx.cancelLogout && _ctx.cancelLogout(...args)),
-              onTouchmove: _cache[18] || (_cache[18] = vue.withModifiers(() => {
+              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[16] || (_cache[16] = vue.withModifiers(() => {
+                onClick: _cache[18] || (_cache[18] = vue.withModifiers(() => {
                 }, ["stop"]))
               }, [
                 vue.createElementVNode("text", { class: "popup-title" }, "退出登录"),
@@ -8982,11 +9092,11 @@ if (uni.restoreGlobal) {
                 vue.createElementVNode("view", { class: "popup-actions" }, [
                   vue.createElementVNode("view", {
                     class: "popup-btn cancel",
-                    onClick: _cache[14] || (_cache[14] = (...args) => _ctx.cancelLogout && _ctx.cancelLogout(...args))
+                    onClick: _cache[16] || (_cache[16] = (...args) => _ctx.cancelLogout && _ctx.cancelLogout(...args))
                   }, "取消"),
                   vue.createElementVNode("view", {
                     class: "popup-btn confirm",
-                    onClick: _cache[15] || (_cache[15] = (...args) => _ctx.confirmLogout && _ctx.confirmLogout(...args))
+                    onClick: _cache[17] || (_cache[17] = (...args) => _ctx.confirmLogout && _ctx.confirmLogout(...args))
                   }, "确定")
                 ])
               ])
@@ -10295,7 +10405,7 @@ if (uni.restoreGlobal) {
     ]);
   }
   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$3 = "/static/icons/shield.svg";
+  const _imports_1$4 = "/static/icons/shield.svg";
   const _sfc_main$h = {
     data() {
       return {
@@ -10352,7 +10462,7 @@ if (uni.restoreGlobal) {
         $data.hasShieldIcon ? (vue.openBlock(), vue.createElementBlock("image", {
           key: 0,
           class: "shield-icon",
-          src: _imports_1$3
+          src: _imports_1$4
         })) : vue.createCommentVNode("v-if", true),
         vue.createElementVNode("text", null, "信息已加密,仅用于收入发放")
       ])
@@ -10965,6 +11075,7 @@ if (uni.restoreGlobal) {
     ]);
   }
   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 {
@@ -11015,7 +11126,7 @@ if (uni.restoreGlobal) {
       vue.createElementVNode("view", { class: "logo-area" }, [
         vue.createElementVNode("image", {
           class: "app-logo",
-          src: _imports_1$8,
+          src: _imports_1$3,
           mode: "aspectFit"
         }),
         vue.createElementVNode("text", { class: "app-name" }, "履约者"),
@@ -11800,7 +11911,7 @@ if (uni.restoreGlobal) {
                       ),
                       vue.createElementVNode("image", {
                         class: "crown-overlay",
-                        src: _imports_1$4,
+                        src: _imports_1$5,
                         mode: "aspectFit"
                       })
                     ])

+ 7 - 5
unpackage/dist/dev/app-plus/manifest.json

@@ -7,8 +7,8 @@
   "id": "__UNI__76F5C47",
   "name": "履约者",
   "version": {
-    "name": "0.1.0",
-    "code": 1
+    "name": "0.1.2",
+    "code": 2
   },
   "description": "履约者APP",
   "developer": {
@@ -19,7 +19,6 @@
   "permissions": {
     "Camera": {},
     "VideoPlayer": {},
-    "Contacts": {},
     "UniNView": {
       "description": "UniNView原生渲染"
     }
@@ -92,7 +91,10 @@
           "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
           "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
           "<uses-feature android:name=\"android.hardware.camera\"/>",
-          "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+          "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
+          "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\" />",
+          "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\" />",
+          "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>"
         ]
       },
       "apple": {
@@ -125,7 +127,7 @@
     "uni-app": {
       "control": "uni-v3",
       "vueVersion": "3",
-      "compilerVersion": "5.04",
+      "compilerVersion": "5.05",
       "nvueCompiler": "uni-app",
       "renderer": "auto",
       "nvue": {

BIN
unpackage/release/apk/__UNI__76F5C47__20260324142623.apk → unpackage/release/apk/__UNI__76F5C47__20260325150449.apk


Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно