From 7ab410022cbf32fd0eb1fe94456a13c95d4a3f89 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期四, 22 一月 2026 16:53:04 +0800
Subject: [PATCH] 客户拜访修改删除接口、规章制度页面

---
 src/pages/index.vue                                                  |   10 
 src/pages.json                                                       |   21 
 src/pages/managementMeetings/rulesRegulationsManagement/index.vue    |  451 ++++++++++
 src/api/cooperativeOffice/clientVisit.js                             |   16 
 src/api/managementMeetings/rulesRegulationsManagement.js             |   82 +
 src/components/Editor/index.vue                                      |    6 
 src/pages/managementMeetings/rulesRegulationsManagement/fileList.vue |  515 +++++++++++
 src/utils/requestApp.ts                                              |   39 
 src/pages/managementMeetings/rulesRegulationsManagement/detail.vue   |  455 ++++++++++
 package.json                                                         |    9 
 src/pages/cooperativeOffice/clientVisit/view.vue                     |  203 ++--
 src/pages/cooperativeOffice/clientVisit/detail.vue                   |  572 ++++++-----
 src/pages/cooperativeOffice/clientVisit/index.vue                    |  309 ++++--
 13 files changed, 2,183 insertions(+), 505 deletions(-)

diff --git a/package.json b/package.json
index bf8f26d..5e29c39 100644
--- a/package.json
+++ b/package.json
@@ -72,15 +72,18 @@
     "@jridgewell/sourcemap-codec": "^1.5.0",
     "@qiun/wx-ucharts": "2.5.0-20230101",
     "@uview-plus/types": "^3.2.5",
+    "@vueup/vue-quill": "^1.2.0",
+    "axios": "^1.13.2",
+    "axios-adapter-uniapp": "^0.1.4",
     "clipboard": "^2.0.11",
     "dayjs": "^1.11.13",
+    "file-saver": "^2.0.5",
     "mqtt": "4.1.0",
     "pinia": "2.2.2",
     "tslib": "^2.7.0",
     "uview-plus": "^3.4.62",
     "vue": "3.4.21",
-    "vue-i18n": "^9.14.2",
-    "@vueup/vue-quill": "^1.2.0"
+    "vue-i18n": "^9.14.2"
   },
   "devDependencies": {
     "@dcloudio/types": "^3.4.14",
@@ -97,4 +100,4 @@
     "vite": "5.4.10",
     "vue-tsc": "2.1.6"
   }
-}
\ No newline at end of file
+}
diff --git a/src/api/cooperativeOffice/clientVisit.js b/src/api/cooperativeOffice/clientVisit.js
index 64ba2a6..bd82c9c 100644
--- a/src/api/cooperativeOffice/clientVisit.js
+++ b/src/api/cooperativeOffice/clientVisit.js
@@ -9,6 +9,14 @@
         data: data
     })
 }
+// 瀹㈡埛鎷滆绛惧埌
+export function clientVisitUpdate(data) {
+    return request({
+        url: '/customerVisits/update',
+        method: 'post',
+        data: data
+    })
+}
 
 // 鑾峰彇鎷滆璁板綍鍒楄〃
 export function getVisitRecords(query) {
@@ -17,4 +25,12 @@
         method: 'get',
         params: query
     })
+}
+
+// 鍒犻櫎瀹㈡埛妗f
+export function delCustomer(ids) {
+    return request({
+        url: '/customerVisits/'+ids,
+        method: 'delete',
+    })
 }
\ No newline at end of file
diff --git a/src/api/managementMeetings/rulesRegulationsManagement.js b/src/api/managementMeetings/rulesRegulationsManagement.js
new file mode 100644
index 0000000..b5cd48c
--- /dev/null
+++ b/src/api/managementMeetings/rulesRegulationsManagement.js
@@ -0,0 +1,82 @@
+import request from '@/utils/request';
+
+// 鏌ヨ瑙勭珷鍒跺害鍒楄〃
+export function listRuleManagement(page,query) {
+  return request({
+    url: "/rulesRegulationsManagement/getList",
+    method: "get",
+    params: {
+      ...page,
+      ...query},
+  });
+}
+// 鏌ヨ闃呰鐘舵�佸垪琛�
+export function getReadingStatusList(page,query) {
+  return request({
+    url: "/rulesRegulationsManagement/getReadingStatusList",
+    method: "get",
+    params: {
+      ...page,
+      ...query},
+  });
+}
+
+// 鏍规嵁瑙勫垯id鏌ヨ闃呰鐘舵�佸垪琛�
+export function getReadingStatusByRuleId(id) {
+  return request({
+    url: "/rulesRegulationsManagement/getReadingStatusByRuleId/"+id,
+    method: "get"
+  });
+}
+// 淇敼瑙勭珷鍒跺害
+export function updateRuleManagement(data) {
+  return request({
+    url: "/rulesRegulationsManagement/update",
+    method: "post",
+    data: data,
+  });
+}
+// 鏂板瑙勭珷鍒跺害
+export function addRuleManagement(data) {
+  return request({
+    url: "/rulesRegulationsManagement/add",
+    method: "post",
+    data: data,
+  });
+}
+
+// 闄勪欢鍒楄〃
+export function listRuleFiles(query) {
+  return request({
+    url: "/rulesRegulationsManagementFile/listPage",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鏂板闄勪欢
+export function addRuleFile(data) {
+  return request({
+    url: "/rulesRegulationsManagementFile/add",
+    method: "post",
+    data,
+  });
+}
+
+// 鍒犻櫎闄勪欢锛堟敮鎸佷紶閫� id 鏁扮粍锛�
+export function delRuleFile(ids) {
+  return request({
+    url: "/rulesRegulationsManagementFile/del",
+    method: "delete",
+    data: ids,
+  });
+}
+// 涓婁紶闄勪欢
+export function upload(query) {
+  return request({
+    url: "/file/upload",
+    method: "post",
+    data: query,
+    responseType: "blob",
+  });
+}
\ No newline at end of file
diff --git a/src/components/Editor/index.vue b/src/components/Editor/index.vue
index 8b95790..952c1d8 100644
--- a/src/components/Editor/index.vue
+++ b/src/components/Editor/index.vue
@@ -1,18 +1,18 @@
 <template>
   <view class="editor-container">
     <div class="editor">
-      <QuillEditor v-model:content="content"
+      <!-- <QuillEditor v-model:content="content"
                    contentType="html"
                    @textChange="(e) => emit('update:modelValue', content)"
                    :options="options"
-                   :style="styles" />
+                   :style="styles" /> -->
     </div>
   </view>
 </template>
 
 <script setup>
   import { ref, computed, watch } from "vue";
-  import { QuillEditor } from "@vueup/vue-quill";
+  // import { QuillEditor } from "@vueup/vue-quill";
   import "@vueup/vue-quill/dist/vue-quill.snow.css";
   import { getToken } from "@/utils/auth";
 
diff --git a/src/pages.json b/src/pages.json
index 561ed11..0cbf52b 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -394,6 +394,27 @@
       }
     },
     {
+      "path": "pages/managementMeetings/rulesRegulationsManagement/index",
+      "style": {
+        "navigationBarTitleText": "瑙勭珷鍒跺害绠$悊",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/managementMeetings/rulesRegulationsManagement/detail",
+      "style": {
+        "navigationBarTitleText": "瑙勭珷鍒跺害璇︽儏",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/managementMeetings/rulesRegulationsManagement/fileList",
+      "style": {
+        "navigationBarTitleText": "瑙勭珷鍒跺害鏂囦欢绠$悊",
+        "navigationStyle": "custom"
+      }
+    },
+    {
       "path": "pages/managementMeetings/knowledgeBase/detail",
       "style": {
         "navigationBarTitleText": "鐭ヨ瘑搴撹鎯�",
diff --git a/src/pages/cooperativeOffice/clientVisit/detail.vue b/src/pages/cooperativeOffice/clientVisit/detail.vue
index 9c0460e..9c3ce0d 100644
--- a/src/pages/cooperativeOffice/clientVisit/detail.vue
+++ b/src/pages/cooperativeOffice/clientVisit/detail.vue
@@ -1,324 +1,360 @@
 <template>
   <view class="client-visit-detail">
-    <PageHeader title="瀹㈡埛鎷滆璇︽儏" @back="goBack" />
-    
-    <u-form @submit="handleSignIn" ref="formRef" label-width="90">
+    <PageHeader title="瀹㈡埛鎷滆璇︽儏"
+                @back="goBack" />
+    <u-form @submit="handleSignIn"
+            ref="formRef"
+            label-width="90">
       <!-- 瀹㈡埛淇℃伅 -->
       <u-cell-group title="瀹㈡埛淇℃伅">
-        <u-form-item label="瀹㈡埛鍚嶇О" prop="customerName" required border-bottom>
-          <u-input
-            v-model="form.customerName"
-            placeholder="璇疯緭鍏ュ鎴峰悕绉�"
-          />
+        <u-form-item label="瀹㈡埛鍚嶇О"
+                     prop="customerName"
+                     required
+                     border-bottom>
+          <u-input v-model="form.customerName"
+                   placeholder="璇疯緭鍏ュ鎴峰悕绉�" />
         </u-form-item>
-        <u-form-item label="鑱旂郴浜�" prop="contact" border-bottom>
-          <u-input
-            v-model="form.contact"
-            placeholder="璇疯緭鍏ヨ仈绯讳汉"
-          />
+        <u-form-item label="鑱旂郴浜�"
+                     prop="contact"
+                     border-bottom>
+          <u-input v-model="form.contact"
+                   placeholder="璇疯緭鍏ヨ仈绯讳汉" />
         </u-form-item>
-        <u-form-item label="鑱旂郴鐢佃瘽" prop="contactPhone" border-bottom>
-          <u-input
-            v-model="form.contactPhone"
-            placeholder="璇疯緭鍏ヨ仈绯荤數璇�"
-          />
+        <u-form-item label="鑱旂郴鐢佃瘽"
+                     prop="contactPhone"
+                     border-bottom>
+          <u-input v-model="form.contactPhone"
+                   placeholder="璇疯緭鍏ヨ仈绯荤數璇�" />
         </u-form-item>
       </u-cell-group>
-
       <!-- 鎷滆淇℃伅 -->
       <u-cell-group title="鎷滆淇℃伅">
-        <u-form-item label="鎷滆鐩殑" prop="purposeVisit" required border-bottom>
-          <u-input
-            v-model="form.purposeVisit"
-            placeholder="璇疯緭鍏ユ嫓璁跨洰鐨�"
-          />
+        <u-form-item label="鎷滆鐩殑"
+                     prop="purposeVisit"
+                     required
+                     border-bottom>
+          <u-input v-model="form.purposeVisit"
+                   placeholder="璇疯緭鍏ユ嫓璁跨洰鐨�" />
         </u-form-item>
-        <u-form-item label="鎷滆鏃堕棿" prop="purposeDate" required border-bottom>
-          <u-input
-            v-model="form.purposeDate"
-            placeholder="璇烽�夋嫨鎷滆鏃堕棿"
-            @click="showTimePicker"
-          />
+        <u-form-item label="鎷滆鏃堕棿"
+                     prop="purposeDate"
+                     required
+                     border-bottom>
+          <u-input v-model="form.purposeDate"
+                   placeholder="璇烽�夋嫨鎷滆鏃堕棿"
+                   @click="showTimePicker" />
           <template #right>
-					<up-icon
-						name="arrow-right"
-						@click="showTimePicker"
-					></up-icon>
-				</template>
+            <up-icon name="arrow-right"
+                     @click="showTimePicker"></up-icon>
+          </template>
         </u-form-item>
-        <u-form-item label="鎷滆鍦扮偣" prop="visitAddress" required border-bottom>
-          <u-input
-            v-model="form.visitAddress"
-            placeholder="璇疯緭鍏ユ嫓璁垮湴鐐�"
-          >
+        <u-form-item label="鎷滆鍦扮偣"
+                     prop="visitAddress"
+                     required
+                     border-bottom>
+          <u-input v-model="form.visitAddress"
+                   placeholder="璇疯緭鍏ユ嫓璁垮湴鐐�">
             <template #suffix>
-              <u-icon name="map" @click="getCurrentLocation" class="location-icon" />
+              <u-icon name="map"
+                      @click="getCurrentLocation"
+                      class="location-icon" />
             </template>
           </u-input>
         </u-form-item>
       </u-cell-group>
-
       <!-- 澶囨敞淇℃伅 -->
       <u-cell-group title="澶囨敞淇℃伅">
-        <u-form-item label="澶囨敞" prop="remark" border-bottom>
-          <u-textarea
-            v-model="form.remark"
-            placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
-            :maxlength="200"
-            count
-            :autoHeight="true"
-          />
+        <u-form-item label="澶囨敞"
+                     prop="remark"
+                     border-bottom>
+          <u-textarea v-model="form.remark"
+                      placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
+                      :maxlength="200"
+                      count
+                      :autoHeight="true" />
         </u-form-item>
       </u-cell-group>
-
       <!-- 鎻愪氦鎸夐挳 -->
       <view class="footer-btns">
-        <u-button class="cancel-btn" @click="goBack">鍙栨秷</u-button>
-        <u-button class="sign-btn" type="primary" @click="handleSignIn" :loading="loading">绛惧埌</u-button>
+        <u-button class="cancel-btn"
+                  @click="goBack">鍙栨秷</u-button>
+        <u-button class="sign-btn"
+                  type="primary"
+                  @click="handleSignIn"
+                  :loading="loading">绛惧埌</u-button>
       </view>
     </u-form>
-
     <!-- 鏃堕棿閫夋嫨鍣� -->
-    <up-datetime-picker
-					:show="showTime"
-					v-model="currentTime"
-					@confirm="onTimeConfirm"
-					@cancel="showTime = false"
-					mode="datetime"
-				/>
+    <up-datetime-picker :show="showTime"
+                        v-model="currentTime"
+                        @confirm="onTimeConfirm"
+                        @cancel="showTime = false"
+                        mode="datetime" />
   </view>
 </template>
 
 <script setup>
-// 鏇挎崲 toast 鏂规硶
-defineOptions({name: 'client-visit-detail'})
-const showToast = (message) => {
-  uni.showToast({
-    title: message,
-    icon: 'none'
-  })
-}
+  // 鏇挎崲 toast 鏂规硶
+  defineOptions({ name: "client-visit-detail" });
+  const showToast = message => {
+    uni.showToast({
+      title: message,
+      icon: "none",
+    });
+  };
 
-import { ref, onMounted } from 'vue'
-import PageHeader from '@/components/PageHeader.vue'
-import { clientVisitSignIn } from '@/api/cooperativeOffice/clientVisit'
-import useUserStore from "@/store/modules/user"
-import dayjs from "dayjs"
+  import { ref, onMounted } from "vue";
+  import PageHeader from "@/components/PageHeader.vue";
+  import {
+    clientVisitSignIn,
+    clientVisitUpdate,
+  } from "@/api/cooperativeOffice/clientVisit";
+  import useUserStore from "@/store/modules/user";
+  import dayjs from "dayjs";
+  import { onLoad } from "@dcloudio/uni-app";
 
-const userStore = useUserStore()
+  const userStore = useUserStore();
 
-// 琛ㄥ崟鏁版嵁
-const form = ref({
-  customerName: '',
-  contact: '',
-  contactPhone: '',
-  visitingPeople: '',
-  purposeVisit: '',
-  purposeDate: '',
-  visitAddress: '',
-  latitude: '',
-  longitude: '',
-  locationAddress: '',
-  remark: ''
-})
+  // 琛ㄥ崟鏁版嵁
+  const form = ref({
+    customerName: "",
+    contact: "",
+    contactPhone: "",
+    visitingPeople: "",
+    purposeVisit: "",
+    purposeDate: "",
+    visitAddress: "",
+    latitude: "",
+    longitude: "",
+    locationAddress: "",
+    remark: "",
+  });
 
-// 椤甸潰鐘舵��
-const loading = ref(false)
-const formRef = ref(null)
+  // 椤甸潰鐘舵��
+  const loading = ref(false);
+  const formRef = ref(null);
 
-// 鏃堕棿鐩稿叧
-const currentTime = ref(Date.now())
-const showTime = ref(false)
+  // 鏃堕棿鐩稿叧
+  const currentTime = ref(Date.now());
+  const showTime = ref(false);
 
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
-  // 杩斿洖鏃舵竻闄ゆ湰鍦板瓨鍌ㄧ殑ID
-  uni.removeStorageSync('clientVisit')
-  uni.navigateBack()
-}
+  // 杩斿洖涓婁竴椤�
+  const goBack = () => {
+    // 杩斿洖鏃舵竻闄ゆ湰鍦板瓨鍌ㄧ殑ID
+    uni.removeStorageSync("clientVisit");
+    uni.navigateBack();
+  };
 
-// 鏄剧ず鏃堕棿閫夋嫨鍣�
-const showTimePicker = () => {
-  showTime.value = true
-}
+  // 鏄剧ず鏃堕棿閫夋嫨鍣�
+  const showTimePicker = () => {
+    showTime.value = true;
+  };
 
-// 纭鏃堕棿閫夋嫨
-const onTimeConfirm = (e) => {
-  console.log(e)
-  form.value.purposeDate = dayjs(e.value).format('YYYY-MM-DD HH:mm:ss')
-	currentTime.value = e.value
-	showTime.value = false;
-}
+  // 纭鏃堕棿閫夋嫨
+  const onTimeConfirm = e => {
+    console.log(e);
+    form.value.purposeDate = dayjs(e.value).format("YYYY-MM-DD HH:mm:ss");
+    currentTime.value = e.value;
+    showTime.value = false;
+  };
 
-// 鑾峰彇褰撳墠浣嶇疆
-const getCurrentLocation = () => {
-  uni.showLoading({ title: '鑾峰彇浣嶇疆涓�...' })
-  
-  uni.getLocation({
-    type: 'gcj02',
-    success: (res) => {
-      form.value.latitude = res.latitude
-      form.value.longitude = res.longitude
-      
-      // 浣跨敤閫嗗湴鐞嗙紪鐮佽幏鍙栧湴鍧�淇℃伅
-      uni.request({
-        url: `https://restapi.amap.com/v3/geocode/regeo?key=c120a5dc69a9f61839f7763e6057005f&location=${res.longitude},${res.latitude}&radius=1000&extensions=all`,
-        success: (geoRes) => {
-          uni.hideLoading()
-          if (geoRes.data.status === '1' && geoRes.data.regeocode) {
-            const regeocode = geoRes.data.regeocode
-            const address = regeocode.formatted_address
-            
-            // 浼樺厛鏄剧ず璇︾粏鍦板潃
-            if (address) {
-              form.value.visitAddress = address
-              showToast('浣嶇疆鑾峰彇鎴愬姛')
+  // 鑾峰彇褰撳墠浣嶇疆
+  const getCurrentLocation = () => {
+    uni.showLoading({ title: "鑾峰彇浣嶇疆涓�..." });
+
+    uni.getLocation({
+      type: "gcj02",
+      success: res => {
+        form.value.latitude = res.latitude;
+        form.value.longitude = res.longitude;
+
+        // 浣跨敤閫嗗湴鐞嗙紪鐮佽幏鍙栧湴鍧�淇℃伅
+        uni.request({
+          url: `https://restapi.amap.com/v3/geocode/regeo?key=c120a5dc69a9f61839f7763e6057005f&location=${res.longitude},${res.latitude}&radius=1000&extensions=all`,
+          success: geoRes => {
+            uni.hideLoading();
+            if (geoRes.data.status === "1" && geoRes.data.regeocode) {
+              const regeocode = geoRes.data.regeocode;
+              const address = regeocode.formatted_address;
+
+              // 浼樺厛鏄剧ず璇︾粏鍦板潃
+              if (address) {
+                form.value.visitAddress = address;
+                showToast("浣嶇疆鑾峰彇鎴愬姛");
+              } else {
+                // 濡傛灉娌℃湁璇︾粏鍦板潃锛屽皾璇曠粍鍚堝湴鍧�淇℃伅
+                const addressComponent = regeocode.addressComponent;
+                const combinedAddress = `${addressComponent.province}${addressComponent.city}${addressComponent.district}${addressComponent.township}`;
+                form.value.visitAddress = combinedAddress;
+                showToast("浣嶇疆鑾峰彇鎴愬姛");
+              }
             } else {
-              // 濡傛灉娌℃湁璇︾粏鍦板潃锛屽皾璇曠粍鍚堝湴鍧�淇℃伅
-              const addressComponent = regeocode.addressComponent
-              const combinedAddress = `${addressComponent.province}${addressComponent.city}${addressComponent.district}${addressComponent.township}`
-              form.value.visitAddress = combinedAddress
-              showToast('浣嶇疆鑾峰彇鎴愬姛')
+              // API璋冪敤鎴愬姛浣嗘病鏈夎繑鍥炲湴鍧�淇℃伅
+              const fallbackAddress = `浣嶇疆: ${res.latitude.toFixed(
+                4
+              )}, ${res.longitude.toFixed(4)}`;
+              form.value.visitAddress = fallbackAddress;
+              showToast("鑾峰彇鍒颁綅缃紝浣嗗湴鍧�瑙f瀽澶辫触");
             }
-          } else {
-            // API璋冪敤鎴愬姛浣嗘病鏈夎繑鍥炲湴鍧�淇℃伅
-            const fallbackAddress = `浣嶇疆: ${res.latitude.toFixed(4)}, ${res.longitude.toFixed(4)}`
-            form.value.visitAddress = fallbackAddress
-            showToast('鑾峰彇鍒颁綅缃紝浣嗗湴鍧�瑙f瀽澶辫触')
-          }
-        },
-        fail: (err) => {
-          uni.hideLoading()
-          console.error('閫嗗湴鐞嗙紪鐮佸け璐�:', err)
-          
-          // 閫嗗湴鐞嗙紪鐮佸け璐ユ椂锛屾樉绀虹畝鍖栫殑浣嶇疆淇℃伅
-          const fallbackAddress = `浣嶇疆: ${res.latitude.toFixed(4)}, ${res.longitude.toFixed(4)}`
-          form.value.visitAddress = fallbackAddress
-          showToast('浣嶇疆鑾峰彇鎴愬姛锛屼絾鍦板潃瑙f瀽澶辫触')
+          },
+          fail: err => {
+            uni.hideLoading();
+            console.error("閫嗗湴鐞嗙紪鐮佸け璐�:", err);
+
+            // 閫嗗湴鐞嗙紪鐮佸け璐ユ椂锛屾樉绀虹畝鍖栫殑浣嶇疆淇℃伅
+            const fallbackAddress = `浣嶇疆: ${res.latitude.toFixed(
+              4
+            )}, ${res.longitude.toFixed(4)}`;
+            form.value.visitAddress = fallbackAddress;
+            showToast("浣嶇疆鑾峰彇鎴愬姛锛屼絾鍦板潃瑙f瀽澶辫触");
+          },
+        });
+      },
+      fail: err => {
+        uni.hideLoading();
+        showToast("鑾峰彇浣嶇疆澶辫触锛岃妫�鏌ュ畾浣嶆潈闄�");
+        console.error("鑾峰彇浣嶇疆澶辫触:", err);
+
+        // 澶辫触鏃舵樉绀洪敊璇俊鎭�
+        form.value.visitAddress = "浣嶇疆鑾峰彇澶辫触";
+      },
+    });
+  };
+
+  // 鎻愪氦绛惧埌
+  const handleSignIn = async () => {
+    if (!form.value.customerName) {
+      showToast("璇疯緭鍏ュ鎴峰悕绉�");
+      return;
+    }
+
+    if (!form.value.purposeVisit) {
+      showToast("璇疯緭鍏ユ嫓璁跨洰鐨�");
+      return;
+    }
+
+    if (!form.value.purposeDate) {
+      showToast("璇烽�夋嫨鎷滆鏃堕棿");
+      return;
+    }
+    if (!form.value.visitAddress) {
+      showToast("璇疯幏鍙栧綋鍓嶄綅缃�");
+      return;
+    }
+
+    try {
+      loading.value = true;
+
+      // 浣跨敤瀹夊叏娴呮嫹璐濓紝閬垮厤瀵硅薄灞曞紑鍦ㄦ煇浜涜繍琛屾椂鎶涢敊
+      const source =
+        form.value && typeof form.value === "object" ? form.value : {};
+      const submitData = {};
+      Object.keys(source).forEach(k => {
+        submitData[k] = source[k];
+      });
+      console.log("submitData", submitData);
+      if (isEdit.value) {
+        const { code } = await clientVisitUpdate(submitData);
+        if (code === 200) {
+          showToast("淇敼鎴愬姛");
+          setTimeout(() => {
+            goBack();
+          }, 500);
+        } else {
+          loading.value = false;
+          showToast("绛惧埌澶辫触锛岃閲嶈瘯");
         }
-      })
-    },
-    fail: (err) => {
-      uni.hideLoading()
-      showToast('鑾峰彇浣嶇疆澶辫触锛岃妫�鏌ュ畾浣嶆潈闄�')
-      console.error('鑾峰彇浣嶇疆澶辫触:', err)
-      
-      // 澶辫触鏃舵樉绀洪敊璇俊鎭�
-      form.value.visitAddress = '浣嶇疆鑾峰彇澶辫触'
+      } else {
+        const { code } = await clientVisitSignUp(submitData);
+        if (code === 200) {
+          showToast("绛惧埌鎴愬姛");
+          setTimeout(() => {
+            goBack();
+          }, 500);
+        } else {
+          loading.value = false;
+          showToast("绛惧埌澶辫触锛岃閲嶈瘯");
+        }
+      }
+    } catch (e) {
+      loading.value = false;
+      console.error("绛惧埌澶辫触:", e);
     }
-  })
-}
-
-// 鎻愪氦绛惧埌
-const handleSignIn = async () => {
-  if (!form.value.customerName) {
-    showToast('璇疯緭鍏ュ鎴峰悕绉�')
-    return
-  }
-  
-  if (!form.value.purposeVisit) {
-    showToast('璇疯緭鍏ユ嫓璁跨洰鐨�')
-    return
-  }
-  
-  if (!form.value.purposeDate) {
-    showToast('璇烽�夋嫨鎷滆鏃堕棿')
-    return
-  }
-  if (!form.value.visitAddress) {
-    showToast('璇疯幏鍙栧綋鍓嶄綅缃�')
-    return
-  }
-  
-  try {
-    loading.value = true
-
-    // 浣跨敤瀹夊叏娴呮嫹璐濓紝閬垮厤瀵硅薄灞曞紑鍦ㄦ煇浜涜繍琛屾椂鎶涢敊
-    const source = (form.value && typeof form.value === 'object') ? form.value : {}
-    const submitData = {}
-    Object.keys(source).forEach((k) => {
-      submitData[k] = source[k]
-    })
-		console.log('submitData', submitData)
-  
-    const { code } = await clientVisitSignIn(submitData)
-    
-    if (code === 200) {
-      showToast('绛惧埌鎴愬姛')
-      setTimeout(() => {
-				goBack()
-      }, 500)
+  };
+  const isEdit = ref(false);
+  onLoad(() => {
+    // 缂栬緫鎷滆鏃讹紝浠庢湰鍦板瓨鍌ㄨ幏鍙栨嫓璁胯褰�
+    const visit = uni.getStorageSync("clientVisit");
+    if (visit) {
+      form.value = visit;
+      isEdit.value = true;
+      console.log("form.value", form.value);
     } else {
-      loading.value = false
-      showToast('绛惧埌澶辫触锛岃閲嶈瘯')
+      isEdit.value = false;
     }
-  } catch (e) {
-    loading.value = false
-    console.error('绛惧埌澶辫触:', e)
-  }
-}
+  });
 
-// 鍒濆鍖栭〉闈㈡暟鎹�
-const initPageData = () => {
-  // 璁剧疆榛樿鎷滆鏃堕棿涓哄綋鍓嶆椂闂�
-  form.value.purposeDate = dayjs().format('YYYY-MM-DD HH:mm:ss')
-  currentTime.value = Date.now()
-  
-  // 璁剧疆鎷滆浜轰负褰撳墠鐧诲綍鐢ㄦ埛鐨勬樀绉�
-  form.value.visitingPeople = userStore.nickName || ''
-}
+  // 鍒濆鍖栭〉闈㈡暟鎹�
+  const initPageData = () => {
+    // 璁剧疆榛樿鎷滆鏃堕棿涓哄綋鍓嶆椂闂�
+    form.value.purposeDate = dayjs().format("YYYY-MM-DD HH:mm:ss");
+    currentTime.value = Date.now();
 
-onMounted(() => {
-  initPageData()
-})
+    // 璁剧疆鎷滆浜轰负褰撳墠鐧诲綍鐢ㄦ埛鐨勬樀绉�
+    form.value.visitingPeople = userStore.nickName || "";
+  };
+
+  onMounted(() => {
+    initPageData();
+  });
 </script>
 
 <style scoped lang="scss">
-@import '@/static/scss/form-common.scss';
-.client-visit {
-  min-height: 100vh;
-  background: #f8f9fa;
-  padding-bottom: 5rem;
-}
+  @import "@/static/scss/form-common.scss";
+  .client-visit {
+    min-height: 100vh;
+    background: #f8f9fa;
+    padding-bottom: 5rem;
+  }
 
-.footer-btns {
-  position: fixed;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  background: #fff;
-  display: flex;
-  justify-content: space-around;
-  align-items: center;
-  padding: 0.75rem 0;
-  box-shadow: 0 -0.125rem 0.5rem rgba(0,0,0,0.05);
-  z-index: 1000;
-}
+  .footer-btns {
+    position: fixed;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background: #fff;
+    display: flex;
+    justify-content: space-around;
+    align-items: center;
+    padding: 0.75rem 0;
+    box-shadow: 0 -0.125rem 0.5rem rgba(0, 0, 0, 0.05);
+    z-index: 1000;
+  }
 
-.cancel-btn {
-  font-weight: 400;
-  font-size: 1rem;
-  color: #666;
-  background: #f5f5f5;
-  border: 1px solid #ddd;
-  width: 45%;
-  height: 2.5rem;
-  border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
-}
+  .cancel-btn {
+    font-weight: 400;
+    font-size: 1rem;
+    color: #666;
+    background: #f5f5f5;
+    border: 1px solid #ddd;
+    width: 45%;
+    height: 2.5rem;
+    border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+  }
 
-.sign-btn {
-  font-weight: 500;
-  font-size: 1rem;
-  color: #fff;
-  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-  border: none;
-  width: 45%;
-  height: 2.5rem;
-  border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
-}
+  .sign-btn {
+    font-weight: 500;
+    font-size: 1rem;
+    color: #fff;
+    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+    border: none;
+    width: 45%;
+    height: 2.5rem;
+    border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+  }
 
-.location-icon {
-  color: #1989fa;
-  font-size: 1.2rem;
-}
+  .location-icon {
+    color: #1989fa;
+    font-size: 1.2rem;
+  }
 </style>
\ No newline at end of file
diff --git a/src/pages/cooperativeOffice/clientVisit/index.vue b/src/pages/cooperativeOffice/clientVisit/index.vue
index 6ff2467..7501efa 100644
--- a/src/pages/cooperativeOffice/clientVisit/index.vue
+++ b/src/pages/cooperativeOffice/clientVisit/index.vue
@@ -1,40 +1,43 @@
 <template>
   <view class="sales-accoun">
     <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
-    <PageHeader title="瀹㈡埛鎷滆" @back="goBack" />
-    
+    <PageHeader title="瀹㈡埛鎷滆"
+                @back="goBack" />
     <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
     <view class="search-section">
       <view class="search-bar">
         <view class="search-input">
-          <up-input
-            class="search-text"
-            placeholder="璇疯緭鍏ュ鎴峰悕绉�"
-            v-model="customerName"
-            @blur="getList"
-            clearable
-          />
+          <up-input class="search-text"
+                    placeholder="璇疯緭鍏ュ鎴峰悕绉�"
+                    v-model="customerName"
+                    @blur="getList"
+                    clearable />
         </view>
-        <view class="filter-button" @click="getList">
-          <u-icon name="search" size="24" color="#999"></u-icon>
+        <view class="filter-button"
+              @click="getList">
+          <u-icon name="search"
+                  size="24"
+                  color="#999"></u-icon>
         </view>
       </view>
     </view>
-    
     <!-- 鎷滆璁板綍鍒楄〃 -->
-    <view class="ledger-list" v-if="visitList.length > 0">
-      <view v-for="(item, index) in visitList" :key="index">
+    <view class="ledger-list"
+          v-if="visitList.length > 0">
+      <view v-for="(item, index) in visitList"
+            :key="index">
         <view class="ledger-item">
           <view class="item-header">
             <view class="item-left">
               <view class="document-icon">
-                <up-icon name="file-text" size="16" color="#ffffff"></up-icon>
+                <up-icon name="file-text"
+                         size="16"
+                         color="#ffffff"></up-icon>
               </view>
               <text class="item-id">瀹㈡埛锛歿{ item.customerName }}</text>
             </view>
           </view>
           <up-divider></up-divider>
-          
           <view class="item-details">
             <view class="detail-row">
               <text class="detail-label">鑱旂郴浜�</text>
@@ -60,155 +63,203 @@
               <text class="detail-label">鎷滆浜�</text>
               <text class="detail-value">{{ item.visitingPeople || '-' }}</text>
             </view>
-            <view class="detail-row" v-if="item.remark">
+            <view class="detail-row"
+                  v-if="item.remark">
               <text class="detail-label">澶囨敞</text>
               <text class="detail-value">{{ item.remark }}</text>
             </view>
           </view>
-          
           <!-- 鎸夐挳鍖哄煙 -->
           <view class="action-buttons">
-            <u-button
-              type="primary"
-              size="small"
-              class="action-btn"
-              @click="viewDetail(item)"
-            >
+            <u-button type="info"
+                      size="small"
+                      class="action-btn"
+                      @click="viewDetail(item)">
               鏌ョ湅璇︽儏
+            </u-button>
+            <u-button type="primary"
+                      size="small"
+                      class="action-btn"
+                      @click="editVisit(item)">
+              缂栬緫
+            </u-button>
+            <u-button type="error"
+                      size="small"
+                      class="action-btn"
+                      @click="deleteVisit(item)">
+              鍒犻櫎
             </u-button>
           </view>
         </view>
       </view>
     </view>
-    
-    <view v-else class="no-data">
+    <view v-else
+          class="no-data">
       <text>鏆傛棤鎷滆璁板綍</text>
     </view>
-    
     <!-- 娴姩鏂板鎸夐挳 -->
-    <view class="fab-button" @click="addVisit">
-      <up-icon name="plus" size="24" color="#ffffff"></up-icon>
+    <view class="fab-button"
+          @click="addVisit">
+      <up-icon name="plus"
+               size="24"
+               color="#ffffff"></up-icon>
     </view>
   </view>
 </template>
 
 <script setup>
-import { ref, onMounted } from 'vue'
-import { onShow } from '@dcloudio/uni-app'
-import PageHeader from '@/components/PageHeader.vue'
-import { getVisitRecords } from '@/api/cooperativeOffice/clientVisit'
-import useUserStore from "@/store/modules/user"
-// 鏇挎崲 toast 鏂规硶
-defineOptions({name: 'client-visit-index'})
-const showToast = (message) => {
-  uni.showToast({
-    title: message,
-    icon: 'none'
-  })
-}
+  import { ref, onMounted } from "vue";
+  import { onShow } from "@dcloudio/uni-app";
+  import PageHeader from "@/components/PageHeader.vue";
+  import {
+    getVisitRecords,
+    delCustomer,
+  } from "@/api/cooperativeOffice/clientVisit";
+  import useUserStore from "@/store/modules/user";
+  // 鏇挎崲 toast 鏂规硶
+  defineOptions({ name: "client-visit-index" });
+  const showToast = message => {
+    uni.showToast({
+      title: message,
+      icon: "none",
+    });
+  };
 
-import dayjs from "dayjs"
+  import dayjs from "dayjs";
 
-const userStore = useUserStore()
+  const userStore = useUserStore();
 
-// 鎼滅储鍏抽敭璇�
-const customerName = ref('')
+  // 鎼滅储鍏抽敭璇�
+  const customerName = ref("");
 
-// 鎷滆璁板綍鏁版嵁
-const visitList = ref([])
+  // 鎷滆璁板綍鏁版嵁
+  const visitList = ref([]);
 
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
-  uni.navigateBack()
-}
+  // 杩斿洖涓婁竴椤�
+  const goBack = () => {
+    uni.navigateBack();
+  };
 
-// 鏌ヨ鍒楄〃
-const getList = () => {
-  showLoadingToast('鍔犺浇涓�...')
-  const params = {
-    current: -1,
-    size: -1,
-    customerName: customerName.value,
-  }
-  getVisitRecords(params)
-    .then((res) => {
-      visitList.value = res.records || res.data?.records || []
-      closeToast()
-    })
-    .catch(() => {
-      closeToast()
-      showToast('鑾峰彇鏁版嵁澶辫触')
-    })
-}
+  // 鏌ヨ鍒楄〃
+  const getList = () => {
+    showLoadingToast("鍔犺浇涓�...");
+    const params = {
+      current: -1,
+      size: -1,
+      customerName: customerName.value,
+    };
+    getVisitRecords(params)
+      .then(res => {
+        visitList.value = res.records || res.data?.records || [];
+        closeToast();
+      })
+      .catch(() => {
+        closeToast();
+        showToast("鑾峰彇鏁版嵁澶辫触");
+      });
+  };
 
-// 鏄剧ず鍔犺浇鎻愮ず
-const showLoadingToast = (message) => {
-  uni.showLoading({
-    title: message,
-    mask: true
+  // 鏄剧ず鍔犺浇鎻愮ず
+  const showLoadingToast = message => {
+    uni.showLoading({
+      title: message,
+      mask: true,
+    });
+  };
+
+  // 鍏抽棴鎻愮ず
+  const closeToast = () => {
+    uni.hideLoading();
+  };
+
+  // 鏂板鎷滆 - 璺宠浆鍒扮櫥璁伴〉闈�
+  const addVisit = () => {
+    uni.navigateTo({
+      url: "/pages/cooperativeOffice/clientVisit/detail",
+    });
+  };
+  // 缂栬緫鎷滆 - 璺宠浆鍒扮櫥璁伴〉闈�
+  const editVisit = item => {
+    uni.setStorageSync("clientVisit", item);
+    // 缂栬緫鎷滆璺宠浆鍒扮櫥璁伴〉闈�
+    uni.navigateTo({
+      url: "/pages/cooperativeOffice/clientVisit/detail",
+    });
+  };
+  // 鍒犻櫎鎷滆
+  const deleteVisit = item => {
+    uni.showModal({
+      title: "鍒犻櫎纭",
+      content: `纭畾瑕佸垹闄よ鎷滆璁板綍鍚楋紵`,
+      success: res => {
+        if (res.confirm) {
+          deleteClientVisit(item.id);
+        }
+      },
+    });
+  };
+  // 鍒犻櫎鎷滆璁板綍
+  const deleteClientVisit = id => {
+    showLoadingToast("鍒犻櫎涓�...");
+    delCustomer(id)
+      .then(() => {
+        closeToast();
+        showToast("鍒犻櫎鎴愬姛");
+        getList();
+      })
+      .catch(() => {
+        closeToast();
+        showToast("鍒犻櫎澶辫触");
+      });
+  };
+  // 鏌ョ湅璇︽儏
+  const viewDetail = item => {
+    uni.setStorageSync("clientVisit", item);
+    // 鏌ョ湅璇︽儏璺宠浆鍒板彧璇诲睍绀洪〉闈�
+    uni.navigateTo({
+      url: "/pages/cooperativeOffice/clientVisit/view",
+    });
+  };
+
+  onMounted(() => {
+    getList();
   });
-};
 
-// 鍏抽棴鎻愮ず
-const closeToast = () => {
-  uni.hideLoading();
-};
-
-// 鏂板鎷滆 - 璺宠浆鍒扮櫥璁伴〉闈�
-const addVisit = () => {
-  uni.navigateTo({
-    url: '/pages/cooperativeOffice/clientVisit/detail'
-  })
-}
-
-// 鏌ョ湅璇︽儏
-const viewDetail = (item) => {
-  uni.setStorageSync('clientVisit', item)
-  // 鏌ョ湅璇︽儏璺宠浆鍒板彧璇诲睍绀洪〉闈�
-  uni.navigateTo({
-    url: '/pages/cooperativeOffice/clientVisit/view'
-  })
-}
-
-onMounted(() => {
-  getList()
-})
-
-onShow(() => {
-  getList()
-})
+  onShow(() => {
+    getList();
+  });
 </script>
 
 <style scoped lang="scss">
-@import "../../../styles/sales-common.scss";
+  @import "../../../styles/sales-common.scss";
 
-// 椤甸潰鐗瑰畾鐨勬牱寮忚鐩�
-.sales-accoun {
-  min-height: 100vh;
-  background: #f8f9fa;
-  position: relative;
-  padding-bottom: 80px;
-}
+  // 椤甸潰鐗瑰畾鐨勬牱寮忚鐩�
+  .sales-accoun {
+    min-height: 100vh;
+    background: #f8f9fa;
+    position: relative;
+    padding-bottom: 80px;
+  }
 
-// 鐗瑰畾鐨勫浘鏍囨牱寮�
-.document-icon {
-  background: #667eea; // 淇濇寔椤甸潰鐗规湁鐨勮儗鏅壊
-}
+  // 鐗瑰畾鐨勫浘鏍囨牱寮�
+  .document-icon {
+    background: #667eea; // 淇濇寔椤甸潰鐗规湁鐨勮儗鏅壊
+  }
 
-// 鐗规湁鏍峰紡
-.visit-status {
-  display: flex;
-  align-items: center;
-}
+  // 鐗规湁鏍峰紡
+  .visit-status {
+    display: flex;
+    align-items: center;
+  }
 
-.detail-value {
-  word-break: break-all; // 淇濈暀椤甸潰鐗规湁鐨勬枃鏈崲琛屾牱寮�
-}
+  .detail-value {
+    word-break: break-all; // 淇濈暀椤甸潰鐗规湁鐨勬枃鏈崲琛屾牱寮�
+  }
 
-// 鐗瑰畾鐨勬诞鍔ㄦ寜閽牱寮�
-.fab-button {
-  background: #667eea; // 淇濇寔椤甸潰鐗规湁鐨勮儗鏅壊
-  box-shadow: 0 4px 16px rgba(102, 126, 234, 0.3); // 淇濇寔椤甸潰鐗规湁鐨勯槾褰辨晥鏋�
-}
+  // 鐗瑰畾鐨勬诞鍔ㄦ寜閽牱寮�
+  .fab-button {
+    background: #667eea; // 淇濇寔椤甸潰鐗规湁鐨勮儗鏅壊
+    box-shadow: 0 4px 16px rgba(102, 126, 234, 0.3); // 淇濇寔椤甸潰鐗规湁鐨勯槾褰辨晥鏋�
+  }
 </style>
 
diff --git a/src/pages/cooperativeOffice/clientVisit/view.vue b/src/pages/cooperativeOffice/clientVisit/view.vue
index f56ddb2..18d1d98 100644
--- a/src/pages/cooperativeOffice/clientVisit/view.vue
+++ b/src/pages/cooperativeOffice/clientVisit/view.vue
@@ -1,7 +1,7 @@
 <template>
   <view class="client-visit-detail">
-    <PageHeader title="瀹㈡埛鎷滆璇︽儏" @back="goBack" />
-    
+    <PageHeader title="瀹㈡埛鎷滆璇︽儏"
+                @back="goBack" />
     <!-- 鍐呭瀹瑰櫒 -->
     <view class="content-container">
       <!-- 瀹㈡埛淇℃伅 -->
@@ -20,7 +20,6 @@
           <text class="info-value">{{ form.contactPhone || '-' }}</text>
         </view>
       </view>
-
       <!-- 鎷滆淇℃伅 -->
       <view class="section">
         <view class="section-title">鎷滆淇℃伅</view>
@@ -40,12 +39,12 @@
           <text class="info-label">鎷滆浜�</text>
           <text class="info-value">{{ form.visitingPeople || '-' }}</text>
         </view>
-        <view class="info-item" v-if="form.latitude && form.longitude">
+        <view class="info-item"
+              v-if="form.latitude && form.longitude">
           <text class="info-label">缁忕含搴�</text>
           <text class="info-value">{{ form.latitude }}, {{ form.longitude }}</text>
         </view>
       </view>
-
       <!-- 澶囨敞淇℃伅 -->
       <view class="section">
         <view class="section-title">澶囨敞淇℃伅</view>
@@ -59,120 +58,120 @@
 </template>
 
 <script setup>
-// 鏇挎崲 toast 鏂规硶
-const showToast = (message) => {
-  uni.showToast({
-    title: message,
-    icon: 'none'
-  })
-}
+  // 鏇挎崲 toast 鏂规硶
+  const showToast = message => {
+    uni.showToast({
+      title: message,
+      icon: "none",
+    });
+  };
 
-import { ref, onMounted } from 'vue'
-import PageHeader from '@/components/PageHeader.vue'
-import useUserStore from "@/store/modules/user"
+  import { ref, onMounted } from "vue";
+  import PageHeader from "@/components/PageHeader.vue";
+  import useUserStore from "@/store/modules/user";
 
-const userStore = useUserStore()
+  const userStore = useUserStore();
 
-// 琛ㄥ崟鏁版嵁
-const form = ref({
-  customerName: '',
-  contact: '',
-  contactPhone: '',
-  visitingPeople: '',
-  purposeVisit: '',
-  purposeDate: '',
-  visitAddress: '',
-  latitude: '',
-  longitude: '',
-  locationAddress: '',
-  remark: ''
-})
+  // 琛ㄥ崟鏁版嵁
+  const form = ref({
+    customerName: "",
+    contact: "",
+    contactPhone: "",
+    visitingPeople: "",
+    purposeVisit: "",
+    purposeDate: "",
+    visitAddress: "",
+    latitude: "",
+    longitude: "",
+    locationAddress: "",
+    remark: "",
+  });
 
-// 杩斿洖涓婁竴椤�
-const goBack = () => {
-  // 杩斿洖鏃舵竻闄ゆ湰鍦板瓨鍌ㄧ殑ID
-  uni.removeStorageSync('clientVisit')
-  uni.navigateBack()
-}
+  // 杩斿洖涓婁竴椤�
+  const goBack = () => {
+    // 杩斿洖鏃舵竻闄ゆ湰鍦板瓨鍌ㄧ殑ID
+    uni.removeStorageSync("clientVisit");
+    uni.navigateBack();
+  };
 
-// 鍒濆鍖栭〉闈㈡暟鎹�
-const initPageData = () => {
-  // 浠庢湰鍦板瓨鍌ㄨ幏鍙栨嫓璁胯褰曡鎯�
-  const row = uni.getStorageSync('clientVisit')
-  if (row) {
-    form.value = { ...row }
-  } else {
-    showToast('鏆傛棤鎷滆璁板綍鏁版嵁')
-  }
-}
+  // 鍒濆鍖栭〉闈㈡暟鎹�
+  const initPageData = () => {
+    // 浠庢湰鍦板瓨鍌ㄨ幏鍙栨嫓璁胯褰曡鎯�
+    const row = uni.getStorageSync("clientVisit");
+    if (row) {
+      form.value = { ...row };
+    } else {
+      showToast("鏆傛棤鎷滆璁板綍鏁版嵁");
+    }
+  };
 
-onMounted(() => {
-  initPageData()
-})
+  onMounted(() => {
+    initPageData();
+  });
 </script>
 
 <style scoped lang="scss">
-@import '@/static/scss/form-common.scss';
+  @import "@/static/scss/form-common.scss";
 
-.client-visit-detail {
-  min-height: 100vh;
-  background-color: #f8f9fa;
-}
+  .client-visit-detail {
+    min-height: 100vh;
+    background-color: #f8f9fa;
+  }
 
-.content-container {
-  padding: 16px;
-}
+  .content-container {
+    padding: 16px;
+  }
 
-.section {
-  background-color: #ffffff;
-  border-radius: 12px;
-  margin-bottom: 16px;
-  overflow: hidden;
-  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
-}
+  .section {
+    background-color: #ffffff;
+    border-radius: 12px;
+    margin-bottom: 16px;
+    overflow: hidden;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+  }
 
-.section-title {
-  font-size: 16px;
-  font-weight: 600;
-  color: #333333;
-  padding: 16px 16px 12px;
-  border-bottom: 1px solid #f0f0f0;
-}
+  .section-title {
+    font-size: 16px;
+    font-weight: 600;
+    color: #333333;
+    padding: 16px 16px 12px;
+    border-bottom: 1px solid #f0f0f0;
+  }
 
-.info-item {
-  display: flex;
-  padding: 14px 16px;
-  border-bottom: 1px solid #f8f8f8;
-  align-items: flex-start;
-}
+  .info-item {
+    display: flex;
+    padding: 14px 16px;
+    border-bottom: 1px solid #f8f8f8;
+    align-items: flex-start;
+  }
 
-.info-item:last-child {
-  border-bottom: none;
-}
+  .info-item:last-child {
+    border-bottom: none;
+  }
 
-.info-label {
-  font-size: 14px;
-  color: #666666;
-  min-width: 80px;
-  flex-shrink: 0;
-  line-height: 22px;
-}
+  .info-label {
+    font-size: 14px;
+    color: #666666;
+    min-width: 80px;
+    flex-shrink: 0;
+    line-height: 22px;
+  }
 
-.info-value {
-  font-size: 14px;
-  color: #333333;
-  flex: 1;
-  line-height: 22px;
-  text-align: right;
-}
+  .info-value {
+    font-size: 14px;
+    color: #333333;
+    flex: 1;
+    line-height: 22px;
+    text-align: right;
+  }
 
-.multi-line {
-  text-align: left;
-  word-break: break-all;
-  line-height: 1.6;
-}
+  .multi-line {
+    text-align: left;
+    word-break: break-all;
+    line-height: 1.6;
+  }
 
-.remark-item {
-  padding-bottom: 16px;
-}
+  .remark-item {
+    padding-bottom: 16px;
+  }
 </style>
\ No newline at end of file
diff --git a/src/pages/index.vue b/src/pages/index.vue
index ef281c5..04c6c96 100644
--- a/src/pages/index.vue
+++ b/src/pages/index.vue
@@ -346,6 +346,10 @@
       icon: "/static/images/icon/qingjiaguanli@2x.png",
       label: "鐢ㄥ嵃绠$悊",
     },
+    {
+      icon: "/static/images/icon/qingjiaguanli@2x.png",
+      label: "瑙勭珷鍒跺害",
+    },
     // {
     //   icon: "/static/images/icon/xietongshenpi@2x.png",
     //   label: "鍗忓悓瀹℃壒",
@@ -574,6 +578,12 @@
           url: "/pages/managementMeetings/sealManagement/index",
         });
         break;
+      case "瑙勭珷鍒跺害":
+        uni.navigateTo({
+          url: "/pages/managementMeetings/rulesRegulationsManagement/index",
+        });
+        break;
+
       case "鍗忓悓瀹℃壒":
         uni.navigateTo({
           url: "/pages/cooperativeOffice/collaborativeApproval/index",
diff --git a/src/pages/managementMeetings/rulesRegulationsManagement/detail.vue b/src/pages/managementMeetings/rulesRegulationsManagement/detail.vue
new file mode 100644
index 0000000..363d665
--- /dev/null
+++ b/src/pages/managementMeetings/rulesRegulationsManagement/detail.vue
@@ -0,0 +1,455 @@
+<template>
+  <view class="client-visit-detail">
+    <PageHeader :title="detailType === 1 ? '鍙戝竷鍒跺害' : '鍒跺害璇︽儏'"
+                @back="goBack" />
+    <u-form ref="formRef"
+            label-width="90">
+      <!-- 瀹㈡埛淇℃伅 -->
+      <!-- <u-cell-group title="鐭ヨ瘑淇℃伅"> -->
+      <u-form-item label="鍒跺害缂栧彿"
+                   prop="regulationNum"
+                   required
+                   border-bottom>
+        <u-input v-model="form.regulationNum"
+                 :readonly="readonly"
+                 placeholder="璇疯緭鍏ュ埗搴︾紪鍙�" />
+      </u-form-item>
+      <u-form-item label="鍒跺害鏍囬"
+                   prop="title"
+                   required
+                   border-bottom>
+        <u-input v-model="form.title"
+                 :readonly="readonly"
+                 placeholder="璇疯緭鍏ュ埗搴︽爣棰�" />
+      </u-form-item>
+      <u-form-item label="鍒跺害鍒嗙被"
+                   prop="type"
+                   required
+                   border-bottom>
+        <u-input v-model="equipmentname"
+                 readonly
+                 placeholder="璇烽�夋嫨鍒跺害鍒嗙被"
+                 @click="showEquipmentSheet = true" />
+        <template v-if="!readonly"
+                  #right>
+          <up-icon name="arrow-right"
+                   @click="openEquipmentSheet"></up-icon>
+        </template>
+      </u-form-item>
+      <u-form-item label="鍒跺害鍐呭"
+                   prop="scenario"
+                   required
+                   border-bottom>
+        <u-textarea v-model="form.content"
+                    type="textarea"
+                    rows="4"
+                    :disabled="readonly"
+                    placeholder="璇疯緭鍏ュ埗搴﹀唴瀹�" />
+      </u-form-item>
+      <u-form-item label="鍒跺害鐗堟湰"
+                   prop="title"
+                   border-bottom>
+        <u-input v-model="form.version"
+                 :readonly="readonly"
+                 placeholder="璇疯緭鍏ュ埗搴︾増鏈�" />
+      </u-form-item>
+      <u-form-item label="鐢熸晥鏃堕棿"
+                   prop="status"
+                   required
+                   border-bottom>
+        <u-input v-model="form.effectiveTime"
+                 readonly
+                 placeholder="璇烽�夋嫨鐢熸晥鏃堕棿"
+                 @click="showEffectiveTimeSheet = true" />
+        <template v-if="!readonly"
+                  #right>
+          <up-icon name="arrow-right"
+                   @click="showEffectiveTimeSheet = true"></up-icon>
+        </template>
+      </u-form-item>
+      <u-form-item label="閫傜敤鑼冨洿"
+                   required
+                   prop="remark"
+                   border-bottom>
+        <up-checkbox-group v-model="form.scope"
+                           :disabled="readonly"
+                           placement="column"
+                           @change="checkboxChange">
+          <up-checkbox :customStyle="{marginBottom: '8px'}"
+                       v-for="(item, index) in checkboxList1"
+                       :key="index"
+                       :label="item.name"
+                       :name="item.value">
+          </up-checkbox>
+        </up-checkbox-group>
+      </u-form-item>
+      <u-form-item label="闇�瑕佺‘璁�"
+                   prop="solution"
+                   border-bottom>
+        <up-switch :disabled="readonly"
+                   v-model="form.requireConfirm"></up-switch>
+      </u-form-item>
+      <!-- </u-cell-group> -->
+      <!-- 鎻愪氦鎸夐挳 -->
+      <view v-if="!readonly"
+            class="footer-btns">
+        <u-button class="cancel-btn"
+                  @click="goBack">鍙栨秷</u-button>
+        <u-button class="sign-btn"
+                  type="primary"
+                  @click="handleSubmit"
+                  :loading="loading">淇濆瓨</u-button>
+      </view>
+    </u-form>
+    <!-- 璁惧閰嶇疆閫夋嫨鍣� -->
+    <up-action-sheet :show="showEquipmentSheet"
+                     :actions="equipmentOptions"
+                     @select="handleEquipmentChange"
+                     @close="showEquipmentSheet = false" />
+    <!-- 鐘舵�侀�夋嫨鍣� -->
+    <up-action-sheet :show="showStatusSheet"
+                     :actions="statusOptions"
+                     @select="onStatusSelect"
+                     @close="showStatusSheet = false" />
+    <up-datetime-picker :show="showEffectiveTimeSheet"
+                        @confirm="handleEffectiveTimeConfirm"
+                        @cancel="showEffectiveTimeSheet = false"
+                        v-model="effectiveTime"
+                        mode="datetime"></up-datetime-picker>
+  </view>
+</template>
+
+<script setup>
+  // 鏇挎崲 toast 鏂规硶
+  defineOptions({ name: "meeting-settings-detail" });
+  const showToast = message => {
+    uni.showToast({
+      title: message,
+      icon: "none",
+    });
+  };
+
+  import { ref, onMounted, computed } from "vue";
+  import PageHeader from "@/components/PageHeader.vue";
+  import useUserStore from "@/store/modules/user";
+  import { onLoad } from "@dcloudio/uni-app";
+  import {
+    addRuleManagement,
+    updateRuleManagement,
+  } from "@/api/managementMeetings/rulesRegulationsManagement";
+  import dayjs from "dayjs";
+  const userStore = useUserStore();
+  const showEffectiveTimeSheet = ref(false);
+  const effectiveTime = ref(new Date());
+  // 琛ㄥ崟鏁版嵁
+  const form = ref({
+    id: "",
+    regulationNum: "",
+    title: "",
+    category: "",
+    content: "",
+    version: "",
+    status: "active",
+    readCount: 0,
+    effectiveTime: "",
+    scope: [],
+    requireConfirm: false,
+  });
+  const checkboxList1 = ref([
+    { name: "鍏ㄤ綋鍛樺伐", value: "all" },
+    { name: "绠$悊灞�", value: "manager" },
+    { name: "浜轰簨閮ㄩ棬", value: "hr" },
+    { name: "璐㈠姟閮ㄩ棬", value: "finance" },
+    { name: "鎶�鏈儴闂�", value: "tech" },
+  ]);
+  const equipmentOptions = ref([
+    { value: "hr", name: "浜轰簨鍒跺害" },
+    { value: "finance", name: "璐㈠姟鍒跺害" },
+    { value: "safety", name: "瀹夊叏鍒跺害" },
+    { value: "tech", name: "鎶�鏈埗搴�" },
+  ]);
+  const statusOptions = ref([
+    { value: "high", name: "鏄捐憲鎻愬崌" },
+    { value: "medium", name: "涓�鑸彁鍗�" },
+    { value: "low", name: "杞诲井鎻愬崌" },
+  ]);
+  //// 椤甸潰鐘舵��
+  const loading = ref(false);
+  const formRef = ref(null);
+  const showEquipmentSheet = ref(false);
+  const showStatusSheet = ref(false);
+  const openEquipmentSheet = () => {
+    showEquipmentSheet.value = true;
+  };
+  // 杩斿洖涓婁竴椤�
+  const goBack = () => {
+    uni.navigateBack();
+  };
+  const statusname = ref("");
+  // 鐘舵�侀�夋嫨
+  const onStatusSelect = action => {
+    form.value.efficiency = action.value;
+    statusname.value = action.name;
+    showStatusSheet.value = false;
+  };
+  const equipmentname = ref("");
+  const handleEffectiveTimeConfirm = () => {
+    form.value.effectiveTime = dayjs(effectiveTime.value).format(
+      "YYYY-MM-DD HH:mm:ss"
+    );
+    showEffectiveTimeSheet.value = false;
+  };
+  // 鍒跺害鍒嗙被閫夋嫨
+  const handleEquipmentChange = val => {
+    form.value.category = val.value;
+    equipmentname.value = val.name;
+    showEquipmentSheet.value = false;
+  };
+  // 鎻愪氦琛ㄥ崟
+  const handleSubmit = async () => {
+    if (!form.value.regulationNum) {
+      showToast("璇疯緭鍏ュ埗搴︾紪鍙�");
+      return;
+    }
+
+    if (!form.value.title) {
+      showToast("璇疯緭鍏ュ埗搴︽爣棰�");
+      return;
+    }
+
+    if (!form.value.category) {
+      showToast("璇烽�夋嫨鍒跺害鍒嗙被");
+      return;
+    }
+    if (!form.value.content) {
+      showToast("璇疯緭鍏ュ埗搴﹀唴瀹�");
+      return;
+    }
+    if (!form.value.effectiveTime) {
+      showToast("璇烽�夋嫨鐢熸晥鏃堕棿");
+      return;
+    }
+    if (!form.value.scope.length) {
+      showToast("璇烽�夋嫨鐢熸晥鑼冨洿");
+      return;
+    }
+    try {
+      loading.value = true;
+      if (detailType.value === 1) {
+        addRuleManagement(form.value).then(res => {
+          if (res.code !== 200) {
+            showToast("淇濆瓨澶辫触锛岃閲嶈瘯");
+            return;
+          }
+          loading.value = false;
+          showToast("淇濆瓨鎴愬姛");
+          setTimeout(() => {
+            goBack();
+          }, 500);
+        });
+      } else if (detailType.value === 2) {
+        updateRuleManagement(form.value).then(res => {
+          if (res.code !== 200) {
+            showToast("淇濆瓨澶辫触锛岃閲嶈瘯");
+            return;
+          }
+          loading.value = false;
+          showToast("淇濆瓨鎴愬姛");
+          setTimeout(() => {
+            goBack();
+          }, 500);
+        });
+      }
+    } catch (e) {
+      loading.value = false;
+      console.error("淇濆瓨澶辫触:", e);
+      showToast("淇濆瓨澶辫触锛岃閲嶈瘯");
+    }
+  };
+
+  // 鍒濆鍖栭〉闈㈡暟鎹�
+  const initPageData = () => {
+    // 浠庢湰鍦板瓨鍌ㄤ腑鑾峰彇浼氳 room 鏁版嵁
+    const meetingRoom = uni.getStorageSync("meetingRoom");
+    if (meetingRoom) {
+      form.value = JSON.parse(JSON.stringify(meetingRoom));
+      if (meetingRoom.equipment) {
+        if (Array.isArray(meetingRoom.equipment)) {
+          form.value.equipment = meetingRoom.equipment;
+        } else {
+          form.value.equipment = meetingRoom.equipment.split(",");
+        }
+      }
+      statusname.value = meetingRoom.status === 1 ? "鍚敤" : "绂佺敤";
+
+      // 娓呴櫎鏈湴瀛樺偍涓殑鏁版嵁锛岄伩鍏嶄笅娆℃墦寮�鏃朵粛鐒舵樉绀�
+      uni.removeStorageSync("meetingRoom");
+    }
+  };
+  const readonly = ref(false);
+  const detailType = ref(1);
+  const knowledgeId = ref("");
+
+  onLoad(options => {
+    detailType.value = Number(options.detailType);
+    knowledgeId.value = options.id || "";
+
+    // 鏌ョ湅妯″紡璁剧疆鍙
+    if (detailType.value === 3) {
+      readonly.value = true;
+    }
+  });
+  // 閲嶇疆琛ㄥ崟
+  const resetForm = () => {
+    form.value = {
+      id: "",
+      regulationNum: "",
+      title: "",
+      category: "",
+      content: "",
+      version: "",
+      status: "active",
+      readCount: 0,
+      effectiveTime: "",
+      scope: [],
+      requireConfirm: false,
+    };
+    equipmentname.value = "";
+    statusname.value = "";
+  };
+  onMounted(() => {
+    console.log(effectiveTime.value, "鐢熸晥鏃堕棿");
+
+    // 浠庢湰鍦板瓨鍌ㄤ腑鑾峰彇鐭ヨ瘑鏁版嵁
+    const rulesRegulations = uni.getStorageSync("rulesRegulations");
+    initPageData();
+    if (rulesRegulations) {
+      form.value = JSON.parse(JSON.stringify(rulesRegulations));
+    }
+
+    if (detailType.value === 1) {
+      resetForm();
+    }
+
+    if (detailType.value != 1) {
+      equipmentname.value =
+        equipmentOptions.value.find(item => item.value == form.value.category)
+          ?.name || "";
+    }
+  });
+</script>
+
+<style scoped lang="scss">
+  @import "@/static/scss/form-common.scss";
+  .client-visit {
+    min-height: 100vh;
+    background: #f8f9fa;
+    padding-bottom: 5rem;
+  }
+
+  .footer-btns {
+    position: fixed;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background: #fff;
+    display: flex;
+    justify-content: space-around;
+    align-items: center;
+    padding: 0.75rem 0;
+    box-shadow: 0 -0.125rem 0.5rem rgba(0, 0, 0, 0.05);
+    z-index: 1000;
+  }
+
+  .cancel-btn {
+    font-weight: 400;
+    font-size: 1rem;
+    color: #666;
+    background: #f5f5f5;
+    border: 1px solid #ddd;
+    width: 45%;
+    height: 2.5rem;
+    border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+  }
+
+  .sign-btn {
+    font-weight: 500;
+    font-size: 1rem;
+    color: #fff;
+    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+    border: none;
+    width: 45%;
+    height: 2.5rem;
+    border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+  }
+
+  .location-icon {
+    color: #1989fa;
+    font-size: 1.2rem;
+  }
+
+  .selector-container {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    width: 100%;
+    height: 100%;
+  }
+
+  .selector-text {
+    font-size: 14px;
+    color: #333;
+  }
+
+  .popup-content {
+    padding: 20rpx;
+  }
+
+  .popup-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 20rpx;
+  }
+
+  .popup-title {
+    font-size: 16px;
+    font-weight: bold;
+    color: #333;
+  }
+
+  .close-icon {
+    font-size: 20px;
+    color: #999;
+  }
+
+  .popup-body {
+    max-height: 60vh;
+    overflow-y: auto;
+    margin-bottom: 20rpx;
+  }
+
+  .checkbox-item {
+    margin-bottom: 15rpx;
+    font-size: 14px;
+  }
+
+  .popup-footer {
+    display: flex;
+    justify-content: space-between;
+    gap: 15rpx;
+  }
+
+  .cancel-btn-popup {
+    flex: 1;
+    border-radius: 8rpx;
+  }
+
+  .confirm-btn-popup {
+    flex: 1;
+    border-radius: 8rpx;
+  }
+  .checkbox-item {
+    margin-top: 40rpx;
+  }
+</style>
\ No newline at end of file
diff --git a/src/pages/managementMeetings/rulesRegulationsManagement/fileList.vue b/src/pages/managementMeetings/rulesRegulationsManagement/fileList.vue
new file mode 100644
index 0000000..c31e39b
--- /dev/null
+++ b/src/pages/managementMeetings/rulesRegulationsManagement/fileList.vue
@@ -0,0 +1,515 @@
+<template>
+  <view class="file-list-page">
+    <!-- 椤甸潰澶撮儴 -->
+    <PageHeader title="闄勪欢绠$悊"
+                @back="goBack" />
+    <!-- 闄勪欢鍒楄〃 -->
+    <view class="file-list-container">
+      <view v-if="fileList.length > 0"
+            class="file-list">
+        <view v-for="(file, index) in fileList"
+              :key="file.id || index"
+              class="file-item">
+          <!-- 鏂囦欢鍥炬爣 -->
+          <!-- <view class="file-icon"
+                :class="getFileIconClass(file.fileType)">
+            <up-icon :name="getFileIcon(file.fileType)"
+                     size="24"
+                     color="#ffffff" />
+          </view> -->
+          <!-- 鏂囦欢淇℃伅 -->
+          <view class="file-info">
+            <text class="file-name">{{ file.name }}</text>
+            <!-- <text class="file-meta">{{ formatFileSize(file.fileSize) }} 路 {{ file.uploadTime || file.createTime }}</text> -->
+          </view>
+          <!-- 鎿嶄綔鎸夐挳 -->
+          <view class="file-actions">
+            <!-- <u-button size="small"
+                      type="primary"
+                      plain
+                      @click="previewFile(file)">棰勮</u-button> -->
+            <u-button size="small"
+                      type="info"
+                      plain
+                      @click="downloadFile(file)">涓嬭浇</u-button>
+            <u-button size="small"
+                      type="error"
+                      plain
+                      @click="confirmDelete(file, index)">鍒犻櫎</u-button>
+          </view>
+        </view>
+      </view>
+      <!-- 绌虹姸鎬� -->
+      <view v-else
+            class="empty-state">
+        <up-icon name="document"
+                 size="64"
+                 color="#c0c4cc" />
+        <text class="empty-text">鏆傛棤闄勪欢</text>
+      </view>
+    </view>
+    <a rel="nofollow"
+       id="downloadLink"
+       href="#"
+       style="display:none;">涓嬭浇鏂囨湰鏂囦欢</a>
+    <!-- 涓婁紶鎸夐挳 -->
+    <view class="upload-button"
+          @click="chooseFile">
+      <up-icon name="plus"
+               size="24"
+               color="#ffffff" />
+      <text class="upload-text">涓婁紶闄勪欢</text>
+    </view>
+  </view>
+</template>
+
+<script setup>
+  import { ref, onMounted } from "vue";
+  import PageHeader from "@/components/PageHeader.vue";
+  import config from "@/config";
+  import { getToken } from "@/utils/auth";
+  import axios from "axios";
+  import requestApp from "@/utils/requestApp";
+  // import { saveAs } from "file-saver";
+  import {
+    listRuleFiles,
+    addRuleFile,
+    delRuleFile,
+    upload,
+  } from "@/api/managementMeetings/rulesRegulationsManagement";
+  import { blobValidate } from "@/utils/ruoyi";
+
+  // 闄勪欢鍒楄〃
+  const fileList = ref([]);
+
+  // 杩斿洖涓婁竴椤�
+  const goBack = () => {
+    uni.navigateBack();
+  };
+  // const request = axios.create({
+  //   baseURL: "URL.com",
+  //   adapter: axiosAdapterUniapp,
+  // });
+  // 鑾峰彇鏂囦欢鍥炬爣
+  const getFileIcon = fileType => {
+    const iconMap = {
+      doc: "document",
+      docx: "document",
+      xls: "grid",
+      xlsx: "grid",
+      pdf: "document",
+      ppt: "copy",
+      pptx: "copy",
+      txt: "document",
+      jpg: "image",
+      jpeg: "image",
+      png: "image",
+      gif: "image",
+      zip: "folder",
+      rar: "folder",
+    };
+    return iconMap[fileType.toLowerCase()] || "document";
+  };
+
+  // 鑾峰彇鏂囦欢鍥炬爣鏍峰紡绫�
+  const getFileIconClass = fileType => {
+    const colorMap = {
+      doc: "blue",
+      docx: "blue",
+      xls: "green",
+      xlsx: "green",
+      pdf: "red",
+      ppt: "orange",
+      pptx: "orange",
+      txt: "gray",
+      jpg: "purple",
+      jpeg: "purple",
+      png: "purple",
+      gif: "purple",
+      zip: "yellow",
+      rar: "yellow",
+    };
+    return colorMap[fileType.toLowerCase()] || "gray";
+  };
+
+  // 鏍煎紡鍖栨枃浠跺ぇ灏�
+  const formatFileSize = bytes => {
+    if (bytes === 0) return "0 B";
+    const k = 1024;
+    const sizes = ["B", "KB", "MB", "GB"];
+    const i = Math.floor(Math.log(bytes) / Math.log(k));
+    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
+  };
+
+  // 閫夋嫨鏂囦欢
+  const chooseFile = () => {
+    // uni.chooseImage({
+    //   count: 9,
+    //   sizeType: ["original", "compressed"],
+    //   sourceType: ["album", "camera"],
+    //   success: res => {
+    //     uploadFiles(res.tempFiles);
+    //   },
+    //   fail: err => {
+    //     console.error("閫夋嫨鍥剧墖澶辫触:", err);
+    //     showToast("閫夋嫨鏂囦欢澶辫触");
+    //   },
+    // });
+    // uni.chooseFile({
+    //   count: 9,
+    //   extension: [
+    //     ".doc",
+    //     ".docx",
+    //     ".xls",
+    //     ".xlsx",
+    //     ".pdf",
+    //     ".ppt",
+    //     ".pptx",
+    //     ".txt",
+    //     ".jpg",
+    //     ".jpeg",
+    //     ".png",
+    //     ".gif",
+    //     ".zip",
+    //     ".rar",
+    //   ],
+    //   success: res => {
+    //     uploadFiles(res.tempFiles);
+    //   },
+    //   fail: err => {
+    //     showToast("閫夋嫨鏂囦欢澶辫触");
+    //   },
+    // });
+  };
+
+  // 涓婁紶鏂囦欢
+  const uploadFiles = tempFiles => {
+    tempFiles.forEach((tempFile, index) => {
+      // 鏄剧ず涓婁紶涓彁绀�
+      uni.showLoading({
+        title: "涓婁紶涓�...",
+        mask: true,
+      });
+      console.log(tempFile, "涓婁紶鏂囦欢");
+      // 1. 鐩存帴浣跨敤 uni.uploadFile 涓婁紶鏂囦欢
+      uni.uploadFile({
+        url: config.baseUrl + "/file/upload",
+        filePath: tempFile.path,
+        name: "file",
+        header: {
+          Authorization: "Bearer " + getToken(),
+        },
+        success: uploadRes => {
+          uni.hideLoading();
+          try {
+            const res = JSON.parse(uploadRes.data);
+            if (res.code === 200) {
+              // 2. 鎻愬彇鏂囦欢淇℃伅
+              const fileName = tempFile.name;
+              const fileType = fileName.split(".").pop();
+              // 3. 鏋勯�犱繚瀛樻枃浠朵俊鎭殑鍙傛暟
+              const saveData = {
+                name: fileName,
+                rulesRegulationsManagementId: rulesRegulationsManagementId.value,
+                url: res.data.tempPath || "",
+              };
+              console.log(saveData, "淇濆瓨鏂囦欢淇℃伅鍙傛暟");
+              // 4. 璋冪敤 addRuleFile 鎺ュ彛淇濆瓨鏂囦欢淇℃伅
+              addRuleFile(saveData)
+                .then(addRes => {
+                  if (addRes.code === 200) {
+                    // 5. 娣诲姞鍒版枃浠跺垪琛�
+                    const newFile = {
+                      ...addRes.data,
+                      uploadTime: new Date().toLocaleString(),
+                    };
+                    // fileList.value.push(newFile);
+                    getFileList();
+                    showToast("涓婁紶鎴愬姛");
+                  } else {
+                    showToast("淇濆瓨鏂囦欢淇℃伅澶辫触");
+                  }
+                })
+                .catch(err => {
+                  console.error("淇濆瓨鏂囦欢淇℃伅澶辫触:", err);
+                  showToast("淇濆瓨鏂囦欢淇℃伅澶辫触");
+                });
+            } else {
+              showToast("鏂囦欢涓婁紶澶辫触");
+            }
+          } catch (e) {
+            console.error("瑙f瀽涓婁紶缁撴灉澶辫触:", e);
+            showToast("涓婁紶澶辫触");
+          }
+        },
+        fail: err => {
+          uni.hideLoading();
+          console.error("涓婁紶澶辫触:", err);
+          showToast("涓婁紶澶辫触");
+        },
+      });
+    });
+  };
+
+  // 涓嬭浇鏂囦欢
+  const downloadFile = file => {
+    var url =
+      config.baseUrl +
+      "/common/download?fileName=" +
+      encodeURIComponent(file.url) +
+      "&delete=true";
+    console.log(url, "url");
+
+    uni
+      .downloadFile({
+        url: url,
+        responseType: "blob",
+        header: { Authorization: "Bearer " + getToken() },
+      })
+      .then(res => {
+        console.log(res, "res");
+        const isBlob = blobValidate(res.data);
+        console.log(isBlob, "isBlob");
+        if (isBlob) {
+          const blob = new Blob([res.data], { type: "text/plain" });
+          const url = URL.createObjectURL(blob);
+          const downloadLink = document.getElementById("downloadLink");
+          downloadLink.href = url;
+          downloadLink.download = file.name;
+          downloadLink.click();
+          // downloadLink.style.display = "block";
+          showToast("涓嬭浇鎴愬姛");
+        } else {
+          showToast("涓嬭浇澶辫触");
+        }
+      })
+      .catch(err => {
+        console.error("涓嬭浇澶辫触:", err);
+        showToast("涓嬭浇澶辫触");
+      });
+  };
+
+  // 纭鍒犻櫎
+  const confirmDelete = (file, index) => {
+    uni.showModal({
+      title: "鍒犻櫎纭",
+      content: `纭畾瑕佸垹闄ら檮浠� "${file.name}" 鍚楋紵`,
+      success: res => {
+        if (res.confirm) {
+          deleteFile(file.id, index);
+        }
+      },
+    });
+  };
+
+  // 鍒犻櫎鏂囦欢
+  const deleteFile = (fileId, index) => {
+    uni.showLoading({
+      title: "鍒犻櫎涓�...",
+      mask: true,
+    });
+
+    delRuleFile([fileId])
+      .then(res => {
+        uni.hideLoading();
+        if (res.code === 200) {
+          // fileList.value.splice(index, 1);
+          getFileList();
+          showToast("鍒犻櫎鎴愬姛");
+        } else {
+          showToast("鍒犻櫎澶辫触");
+        }
+      })
+      .catch(err => {
+        uni.hideLoading();
+        showToast("鍒犻櫎澶辫触");
+      });
+  };
+
+  // 鏄剧ず鎻愮ず
+  const showToast = message => {
+    uni.showToast({
+      title: message,
+      icon: "none",
+    });
+  };
+  const rulesRegulationsManagementId = ref("");
+  // 椤甸潰鍔犺浇鏃�
+  onMounted(() => {
+    // 浠� API 鑾峰彇闄勪欢鍒楄〃
+    getFileList();
+    // 浠庢湰鍦板瓨鍌ㄨ幏鍙� rulesRegulationsManagementId
+    rulesRegulationsManagementId.value = uni.getStorageSync(
+      "rulesRegulationsManagement"
+    );
+  });
+
+  // 鑾峰彇闄勪欢鍒楄〃
+  const getFileList = () => {
+    uni.showLoading({
+      title: "鍔犺浇涓�...",
+      mask: true,
+    });
+
+    listRuleFiles()
+      .then(res => {
+        uni.hideLoading();
+        if (res.code === 200) {
+          fileList.value = res.data.records || [];
+        } else {
+          showToast("鑾峰彇闄勪欢鍒楄〃澶辫触");
+        }
+      })
+      .catch(err => {
+        uni.hideLoading();
+        showToast("鑾峰彇闄勪欢鍒楄〃澶辫触");
+      });
+  };
+</script>
+
+<style scoped lang="scss">
+  @import "../../../styles/sales-common.scss";
+
+  .file-list-page {
+    min-height: 100vh;
+    background: #f8f9fa;
+    padding-bottom: 100rpx;
+  }
+
+  .file-list-container {
+    padding: 20rpx;
+  }
+
+  .file-list {
+    background: #ffffff;
+    border-radius: 8rpx;
+    overflow: hidden;
+    box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
+  }
+
+  .file-item {
+    display: flex;
+    align-items: center;
+    padding: 20rpx;
+    border-bottom: 1rpx solid #f0f0f0;
+
+    &:last-child {
+      border-bottom: none;
+    }
+  }
+
+  .file-icon {
+    width: 56rpx;
+    height: 56rpx;
+    border-radius: 8rpx;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    margin-right: 20rpx;
+
+    &.blue {
+      background: #409eff;
+    }
+
+    &.green {
+      background: #67c23a;
+    }
+
+    &.red {
+      background: #f56c6c;
+    }
+
+    &.orange {
+      background: #e6a23c;
+    }
+
+    &.gray {
+      background: #909399;
+    }
+
+    &.purple {
+      background: #909399;
+    }
+
+    &.yellow {
+      background: #e6a23c;
+    }
+  }
+
+  .file-info {
+    flex: 1;
+    min-width: 0;
+  }
+
+  .file-name {
+    display: block;
+    font-size: 16px;
+    color: #303133;
+    margin-bottom: 8rpx;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+
+  .file-meta {
+    display: block;
+    font-size: 12px;
+    color: #909399;
+  }
+
+  .file-actions {
+    display: flex;
+    gap: 12rpx;
+  }
+
+  .empty-state {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    padding: 100rpx 0;
+    background: #ffffff;
+    border-radius: 8rpx;
+    box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
+  }
+
+  .empty-text {
+    font-size: 14px;
+    color: #909399;
+    margin-top: 20rpx;
+  }
+
+  .upload-button {
+    position: fixed;
+    bottom: 40rpx;
+    right: 40rpx;
+    width: 80rpx;
+    height: 80rpx;
+    border-radius: 50%;
+    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    box-shadow: 0 4rpx 16rpx rgba(102, 126, 234, 0.4);
+    z-index: 1000;
+  }
+
+  .upload-text {
+    font-size: 10px;
+    color: #ffffff;
+    margin-top: 4rpx;
+  }
+
+  .upload-progress {
+    padding: 40rpx 0;
+  }
+
+  .upload-progress-text {
+    display: block;
+    text-align: center;
+    margin-top: 20rpx;
+    font-size: 14px;
+    color: #606266;
+  }
+</style>
\ No newline at end of file
diff --git a/src/pages/managementMeetings/rulesRegulationsManagement/index.vue b/src/pages/managementMeetings/rulesRegulationsManagement/index.vue
new file mode 100644
index 0000000..40c942f
--- /dev/null
+++ b/src/pages/managementMeetings/rulesRegulationsManagement/index.vue
@@ -0,0 +1,451 @@
+<template>
+  <view class="sales-accoun">
+    <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+    <PageHeader title="瑙勭珷鍒跺害绠$悊"
+                @back="goBack" />
+    <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
+    <view class="search-section">
+      <view class="search-bar">
+        <view class="search-input">
+          <up-input class="search-text"
+                    placeholder="璇疯緭鍏ュ埗搴︽爣棰�"
+                    v-model="name"
+                    @blur="getList"
+                    clearable />
+        </view>
+        <view class="filter-button"
+              @click="getList">
+          <u-icon name="search"
+                  size="24"
+                  color="#999"></u-icon>
+        </view>
+      </view>
+    </view>
+    <!-- 鎷滆璁板綍鍒楄〃 -->
+    <view class="ledger-list"
+          v-if="visitList.length > 0">
+      <view v-for="(item, index) in visitList"
+            :key="index">
+        <view class="ledger-item">
+          <view class="item-header">
+            <view class="item-left">
+              <view class="document-icon">
+                <up-icon name="file-text"
+                         size="16"
+                         color="#ffffff"></up-icon>
+              </view>
+              <text class="item-id">鍒跺害鏍囬锛歿{ item.title || '-' }}</text>
+            </view>
+          </view>
+          <up-divider></up-divider>
+          <view class="item-details">
+            <view class="detail-row">
+              <text class="detail-label">鍒跺害缂栧彿</text>
+              <text class="detail-value">{{ item.regulationNum || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">鍒嗙被</text>
+              <u-tag size="mini">{{ formatReceiptType(item.category) }}</u-tag>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">鐗堟湰</text>
+              <text class="detail-value">{{ item.version || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">鍙戝竷浜�</text>
+              <text class="detail-value">{{ item.createUserName || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">鍙戝竷鏃堕棿</text>
+              <text class="detail-value">{{ item.createTime || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">鐘舵��</text>
+              <u-tag size="mini"
+                     :type="item.status === 'active' ? 'success' : 'info'">
+                {{ item.status === "active" ? '鐢熸晥涓�' : '宸插簾姝�' }}
+              </u-tag>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">宸茶浜烘暟</text>
+              <text class="detail-value">{{ item.readCount || '-' }}</text>
+            </view>
+            <u-collapse border="false"
+                        accordion
+                        @open="(value) => handleOpen(value, index)">
+              <u-collapse-item title="鐗堟湰鍘嗗彶"
+                               border="false"
+                               :name="item.category">
+                <view class="table-container">
+                  <u-table2 :data="item.tableData1"
+                            :columns="columns"
+                            stripe
+                            border />
+                </view>
+              </u-collapse-item>
+              <!-- <u-collapse-item title="闃呰鐘舵��"
+                               border="false"
+                               :name="item.id">
+                <view class="table-container">
+                  <u-table2 :data="item.tableData2"
+                            :columns="columns2"
+                            stripe
+                            border />
+                </view>
+              </u-collapse-item> -->
+            </u-collapse>
+          </view>
+          <!-- 鎸夐挳鍖哄煙 -->
+          <view class="action-buttons">
+            <u-button type="info"
+                      size="small"
+                      class="action-btn"
+                      @click="viewDetail(item,3)">
+              鏌ョ湅
+            </u-button>
+            <u-button type="error"
+                      size="small"
+                      class="action-btn"
+                      @click="handleAbrogate(item)">
+              搴熷純
+            </u-button>
+            <u-button type="primary"
+                      size="small"
+                      class="action-btn"
+                      @click="viewDetail(item,2)">
+              缂栬緫
+            </u-button>
+            <u-button type="primary"
+                      size="small"
+                      class="action-btn"
+                      @click="fileList(item)">
+              闄勪欢
+            </u-button>
+          </view>
+        </view>
+      </view>
+    </view>
+    <view v-else
+          class="no-data">
+      <text>鏆傛棤浼氳瀹よ褰�</text>
+    </view>
+    <!-- 娴姩鏂板鎸夐挳 -->
+    <view class="fab-button"
+          @click="addVisit">
+      <up-icon name="plus"
+               size="24"
+               color="#ffffff"></up-icon>
+    </view>
+  </view>
+</template>
+
+<script setup>
+  import { ref, onMounted, computed } from "vue";
+  import { onShow } from "@dcloudio/uni-app";
+  import { useDict } from "@/utils/dict";
+  import PageHeader from "@/components/PageHeader.vue";
+  import {
+    listRuleManagement,
+    getReadingStatusList,
+    getReadingStatusByRuleId,
+    updateRuleManagement,
+    // delKnowledgeBase,
+  } from "@/api/managementMeetings/rulesRegulationsManagement";
+  import useUserStore from "@/store/modules/user";
+  // 鏇挎崲 toast 鏂规硶
+  defineOptions({ name: "client-visit-index" });
+  const showToast = message => {
+    uni.showToast({
+      title: message,
+      icon: "none",
+    });
+  };
+
+  import dayjs from "dayjs";
+
+  const userStore = useUserStore();
+  // 搴熷純瑙勭珷鍒跺害
+  const handleAbrogate = item => {
+    uni.showModal({
+      title: "搴熷純纭",
+      content: `纭畾瑕佸簾寮冭瑙勭珷鍒跺害鍚楋紵`,
+      success: res => {
+        if (res.confirm) {
+          item.status = "repealed";
+          updateRuleManagement(item).then(() => {
+            showToast("搴熷純鎴愬姛");
+            getList();
+          });
+        }
+      },
+    });
+  };
+  // 闄勪欢鍒楄〃
+  const fileList = item => {
+    console.log(item.id, "item");
+    uni.setStorageSync("rulesRegulationsManagement", item.id);
+    // // 闄勪欢鍒楄〃璺宠浆鍒拌鎯呴〉闈�
+    uni.navigateTo({
+      url: "/pages/managementMeetings/rulesRegulationsManagement/fileList",
+    });
+  };
+  const columns = ref([
+    { title: "鐗堟湰鍙�", key: "version", width: 100 },
+    { title: "鏇存柊鏃堕棿", key: "updateTime", width: 200 },
+    { title: "鏇存柊浜�", key: "createUserName", width: 150 },
+    { title: "鍙樻洿璇存槑", key: "status", width: 100 },
+  ]);
+  const columns2 = ref([
+    { title: "鍛樺伐濮撳悕", key: "employee", width: 150 },
+    { title: "鎵�灞為儴闂�", key: "department", width: 150 },
+    { title: "闃呰鏃堕棿", key: "createTime", width: 200 },
+    { title: "纭鏃堕棿", key: "confirmTime", width: 200 },
+    { title: "鐘舵��", key: "status", width: 100 },
+  ]);
+  // 鎼滅储鍏抽敭璇�
+  const name = ref("");
+
+  // 鎷滆璁板綍鏁版嵁
+  const visitList = ref([]);
+
+  // 杩斿洖涓婁竴椤�
+  const goBack = () => {
+    uni.navigateBack();
+  };
+  const { knowledge_type } = useDict("knowledge_type");
+  // 鏍煎紡鍖栧洖娆炬柟寮�
+  const formatReceiptType = params => {
+    if (params == "hr") {
+      return "浜轰簨鍒跺害";
+    } else if (params == "finance") {
+      return "璐㈠姟鍒跺害";
+    } else if (params == "safety") {
+      return "瀹夊叏鍒跺害";
+    } else if (params == "tech") {
+      return "鎶�鏈埗搴�";
+    } else {
+      return "鏈煡";
+    }
+  };
+  const getTagClass = type => {
+    if (type == "high") {
+      return "success";
+    } else if (type == "medium") {
+      return "warning";
+    } else if (type == "low") {
+      return "info";
+    } else {
+      return "info";
+    }
+  };
+  const knowledgeTypeOptions = computed(() => knowledge_type?.value || []);
+  // 鑾峰彇鐭ヨ瘑绫诲瀷鏍囩
+  const getKnowledgeTypeLabel = val => {
+    console.log(knowledgeTypeOptions, "knowledgeTypeOptions");
+    const item = knowledgeTypeOptions.value.find(
+      i => String(i.value) === String(val)
+    );
+    return item ? item.label : val;
+  };
+  const handleOpen = (value, index) => {
+    if (
+      value == "hr" ||
+      value == "finance" ||
+      value == "safety" ||
+      value == "tech"
+    ) {
+      // 鍘嗗彶鐗堟湰
+      const params = {
+        current: -1,
+        size: -1,
+        category: value,
+      };
+      listRuleManagement(params)
+        .then(res => {
+          visitList.value[index].tableData1 = res.data.records;
+          visitList.value[index].tableData1.forEach(item => {
+            item.status = item.status == "active" ? "鐢熸晥涓�" : "宸插簾姝�";
+          });
+        })
+        .catch(() => {
+          closeToast();
+          showToast("鑾峰彇鏁版嵁澶辫触");
+        });
+    } else {
+      // 闃呰鐘舵��
+      getReadingStatusByRuleId(value)
+        .then(res => {
+          visitList.value[index].tableData2 = res.data;
+          visitList.value[index].tableData2.forEach(item => {
+            item.status = item.status == "confirmed" ? "宸茬‘璁�" : "鏈‘璁�";
+          });
+        })
+        .catch(() => {
+          closeToast();
+          showToast("鑾峰彇鏁版嵁澶辫触");
+        });
+    }
+  };
+  // 鏌ヨ鍒楄〃
+  const getList = () => {
+    showLoadingToast("鍔犺浇涓�...");
+    const params = {
+      current: -1,
+      size: -1,
+      title: name.value,
+    };
+    listRuleManagement(params)
+      .then(res => {
+        visitList.value = res.data.records;
+        closeToast();
+      })
+      .catch(() => {
+        closeToast();
+        showToast("鑾峰彇鏁版嵁澶辫触");
+      });
+  };
+
+  // 鏄剧ず鍔犺浇鎻愮ず
+  const showLoadingToast = message => {
+    uni.showLoading({
+      title: message,
+      mask: true,
+    });
+  };
+
+  // 鍏抽棴鎻愮ず
+  const closeToast = () => {
+    uni.hideLoading();
+  };
+
+  // 鏂板鎷滆 - 璺宠浆鍒扮櫥璁伴〉闈�
+  const addVisit = () => {
+    uni.navigateTo({
+      url: "/pages/managementMeetings/rulesRegulationsManagement/detail?detailType=1",
+    });
+  };
+
+  // 缂栬緫
+  const viewDetail = (item, detailType) => {
+    uni.setStorageSync("rulesRegulations", item);
+    uni.navigateTo({
+      url:
+        "/pages/managementMeetings/rulesRegulationsManagement/detail?detailType=" +
+        detailType +
+        "&id=" +
+        item.id,
+    });
+  };
+
+  // 鍒犻櫎纭
+  const confirmDelete = item => {
+    uni.showModal({
+      title: "鍒犻櫎纭",
+      content: `纭畾瑕佸垹闄ょ煡璇� "${item.title}" 鍚楋紵`,
+      success: res => {
+        if (res.confirm) {
+          deleteKnowledge(item.id);
+        }
+      },
+    });
+  };
+
+  // 鎵ц鍒犻櫎
+  const deleteKnowledge = id => {
+    showLoadingToast("鍒犻櫎涓�...");
+    delKnowledgeBase([id])
+      .then(res => {
+        closeToast();
+        if (res.code === 200) {
+          showToast("鍒犻櫎鎴愬姛");
+          getList(); // 閲嶆柊鑾峰彇鍒楄〃
+        } else {
+          showToast("鍒犻櫎澶辫触");
+        }
+      })
+      .catch(() => {
+        closeToast();
+        showToast("鍒犻櫎澶辫触");
+      });
+  };
+
+  onMounted(() => {
+    getList();
+  });
+
+  onShow(() => {
+    getList();
+  });
+</script>
+
+<style scoped lang="scss">
+  @import "../../../styles/sales-common.scss";
+
+  // 椤甸潰鐗瑰畾鐨勬牱寮忚鐩�
+  .sales-accoun {
+    min-height: 100vh;
+    background: #f8f9fa;
+    position: relative;
+    padding-bottom: 80px;
+  }
+
+  // 鐗瑰畾鐨勫浘鏍囨牱寮�
+  .document-icon {
+    background: #667eea; // 淇濇寔椤甸潰鐗规湁鐨勮儗鏅壊
+  }
+
+  // 鐗规湁鏍峰紡
+  .visit-status {
+    display: flex;
+    align-items: center;
+  }
+
+  .detail-value {
+    word-break: break-all; // 淇濈暀椤甸潰鐗规湁鐨勬枃鏈崲琛屾牱寮�
+    color: #333; // 淇濇寔椤甸潰鐗规湁鐨勬枃鏈鑹�
+  }
+
+  // 鐘舵�佹牱寮�
+  .status-enabled {
+    color: #28a745; // 淇濇寔椤甸潰鐗规湁鐨勬垚鍔熼鑹�
+  }
+
+  .status-disabled {
+    color: #dc3545; // 淇濇寔椤甸潰鐗规湁鐨勯敊璇鑹�
+  }
+
+  // 鐗瑰畾鐨勬诞鍔ㄦ寜閽牱寮�
+  .fab-button {
+    background: #667eea; // 淇濇寔椤甸潰鐗规湁鐨勮儗鏅壊
+    box-shadow: 0 4px 16px rgba(102, 126, 234, 0.3); // 淇濇寔椤甸潰鐗规湁鐨勯槾褰辨晥鏋�
+  }
+
+  // 琛ㄦ牸瀹瑰櫒锛屽疄鐜版í鍚戞粴鍔�
+  .table-container {
+    overflow-x: auto;
+    margin: 0 -20rpx;
+    padding: 0 20rpx;
+  }
+
+  .table-container::-webkit-scrollbar {
+    height: 6rpx;
+  }
+
+  .table-container::-webkit-scrollbar-track {
+    background: #f1f1f1;
+    border-radius: 3rpx;
+  }
+
+  .table-container::-webkit-scrollbar-thumb {
+    background: #c1c1c1;
+    border-radius: 3rpx;
+  }
+
+  .table-container::-webkit-scrollbar-thumb:hover {
+    background: #a8a8a8;
+  }
+  // .u-table2 {
+  //   width: 500px;
+  // }
+</style>
+
diff --git a/src/utils/requestApp.ts b/src/utils/requestApp.ts
new file mode 100644
index 0000000..9f8ef84
--- /dev/null
+++ b/src/utils/requestApp.ts
@@ -0,0 +1,39 @@
+import axios from 'axios';
+import adapter from 'axios-adapter-uniapp';
+import config from '@/config';
+
+const service = axios.create({
+  baseURL: config.baseUrl, // 鏇挎崲涓哄疄闄呭悗绔湴鍧�
+  timeout: 10000,
+  adapter: adapter // 鏍稿績閫傞厤鍣ㄩ厤缃�
+});
+
+// 璇锋眰鎷︽埅鍣�
+service.interceptors.request.use(
+  config => {
+    const token = uni.getStorageSync('token');
+    if (token) {
+      config.headers.Authorization = `Bearer ${token}`;
+    }
+    return config;
+  },
+  error => Promise.reject(error)
+);
+
+// 鍝嶅簲鎷︽埅鍣�
+service.interceptors.response.use(
+  response => {
+    const res = response.data;
+    if (res.code !== 200) {
+      uni.showToast({ title: res.message, icon: 'none' });
+      return Promise.reject(res);
+    }
+    return res;
+  },
+  error => {
+    uni.showToast({ title: '缃戠粶閿欒', icon: 'none' });
+    return Promise.reject(error);
+  }
+);
+
+export default service;
\ No newline at end of file

--
Gitblit v1.9.3