From 00b5cbce9f587931c7dc5455df707b0acc753e69 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期五, 16 一月 2026 15:48:17 +0800
Subject: [PATCH] 会议设置,会议申请,会议列表

---
 src/pages/index.vue                                         |   27 
 src/pages/managementMeetings/meetApplication/index.vue      |  497 +++++++++++
 src/pages.json                                              |   25 
 src/pages/managementMeetings/meetingSettings/index.vue      |  244 +++++
 src/pages/cooperativeOffice/collaborativeApproval/index.vue |  668 +++++++-------
 src/api/managementMeetings/meetingSettings.js               |   24 
 src/pages/managementMeetings/meetingSettings/detail.vue     |  344 ++++++++
 src/pages/managementMeetings/meetingSettings/view.vue       |  178 ++++
 src/api/managementMeetings/meeting.js                       |   26 
 src/pages/managementMeetings/meetingList/index.vue          |  529 ++++++++++++
 10 files changed, 2,234 insertions(+), 328 deletions(-)

diff --git a/src/api/managementMeetings/meeting.js b/src/api/managementMeetings/meeting.js
new file mode 100644
index 0000000..1f730a2
--- /dev/null
+++ b/src/api/managementMeetings/meeting.js
@@ -0,0 +1,26 @@
+import request from '@/utils/request';
+
+// 鑾峰彇浼氳浣跨敤鍒楄〃
+export function getMeetingUseList(data){
+    return request({
+        url: "/meeting/meetingUseList",
+        method: "post",
+        data: data,
+    });
+}
+
+// 淇濆瓨浼氳鐢宠
+export function saveMeetingApplication(data){
+    return request({
+        url: "/meeting/saveMeetingApplication",
+        method: "post",
+        data: data,
+    });
+}
+
+export function getRoomEnum() {
+    return request({
+        url: "/meeting/roomEnum",
+        method: "get",
+    });
+}
\ No newline at end of file
diff --git a/src/api/managementMeetings/meetingSettings.js b/src/api/managementMeetings/meetingSettings.js
new file mode 100644
index 0000000..0205270
--- /dev/null
+++ b/src/api/managementMeetings/meetingSettings.js
@@ -0,0 +1,24 @@
+// 浼氳绠$悊
+import request from "@/utils/request";
+
+export function getMeetingRoomList(data) {
+    return request({
+        url: "/meeting/roomList",
+        method: "post",
+        data: data,
+    });
+}
+
+export function saveRoom(data) {
+    return request({
+        url: "/meeting/saveRoom",
+        method: "post",
+        data: data,
+    });
+}
+export function delRoom(id) {
+    return request({
+        url: "/meeting/delRoom/"+id,
+        method: "delete",
+    });
+}
\ No newline at end of file
diff --git a/src/pages.json b/src/pages.json
index 2375606..d384630 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -296,9 +296,30 @@
       }
     },
     {
-      "path": "pages/cooperativeOffice/collaborativeApproval/index",
+      "path": "pages/managementMeetings/meetingSettings/index",
       "style": {
-        "navigationBarTitleText": "瀹℃壒绠$悊",
+        "navigationBarTitleText": "浼氳璁剧疆",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/managementMeetings/meetingSettings/detail",
+      "style": {
+        "navigationBarTitleText": "浼氳瀹よ鎯�",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/managementMeetings/meetingList/index",
+      "style": {
+        "navigationBarTitleText": "浼氳鍒楄〃",
+        "navigationStyle": "custom"
+      }
+    },
+    {
+      "path": "pages/managementMeetings/meetApplication/index",
+      "style": {
+        "navigationBarTitleText": "浼氳鐢宠",
         "navigationStyle": "custom"
       }
     },
diff --git a/src/pages/cooperativeOffice/collaborativeApproval/index.vue b/src/pages/cooperativeOffice/collaborativeApproval/index.vue
index f72d200..9f42801 100644
--- a/src/pages/cooperativeOffice/collaborativeApproval/index.vue
+++ b/src/pages/cooperativeOffice/collaborativeApproval/index.vue
@@ -1,351 +1,367 @@
 // 瀹℃壒绠$悊涓婚〉闈�
 <template>
-	<view class="sales-account">
-		<!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
-		<PageHeader title="瀹℃壒绠$悊" @back="goBack" />
-
-		<!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
-		<view class="search-section">
-			<view class="search-bar">
-				<view class="search-input">
-					<up-input
-						class="search-text"
-						placeholder="璇疯緭鍏ユ祦绋嬬紪鍙�"
-						v-model="searchForm.approveId"
-						clearable
-					/>
-				</view>
-				<view class="search-button" @click="getList">
-					<up-icon name="search" size="24" color="#999"></up-icon>
-				</view>
-			</view>
-		</view>
-
-		<!-- 瀹℃壒鍒楄〃 -->
-		<view class="ledger-list" v-if="ledgerList.length > 0">
-			<view v-for="(item, index) in ledgerList" :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.approveId }}</text>
-						</view>
-						<view class="item-tag">
-							<u-tag :type="getTagClass(item.approveStatus)">{{ formatReceiptType(item.approveStatus) }}</u-tag>
-						</view>
-					</view>
-					<up-divider></up-divider>
-
-					<view class="item-details">
-						<view class="detail-row">
-							<text class="detail-label">鐢宠浜�</text>
-							<text class="detail-value">{{ item.approveUserName }}</text>
-						</view>
-						<view class="detail-row">
-							<text class="detail-label">鐢宠閮ㄩ棬</text>
-							<text class="detail-value">{{ item.approveDeptName }}</text>
-						</view>
-						<view class="detail-row-approveReason">
-							<text class="detail-label">瀹℃壒浜嬬敱</text>
-							<text class="detail-value highlightBlue">{{ item.approveReason }}</text>
-						</view>
-						<view class="detail-row">
-							<text class="detail-label">鐢宠鏃ユ湡</text>
-							<text class="detail-value">{{ item.approveTime }}</text>
-						</view>
-						
-						<!-- approveType=2 璇峰亣鐩稿叧瀛楁 -->
-						<template v-if="item.approveType === 2">
-							<view class="detail-row">
-								<text class="detail-label">璇峰亣寮�濮嬫椂闂�</text>
-								<text class="detail-value">{{ item.startDate || '-' }}</text>
-							</view>
-							<view class="detail-row">
-								<text class="detail-label">璇峰亣缁撴潫鏃堕棿</text>
-								<text class="detail-value">{{ item.endDate || '-' }}</text>
-							</view>
-						</template>
-						
-						<!-- approveType=3 鍑哄樊鐩稿叧瀛楁 -->
-						<view v-if="item.approveType === 3" class="detail-row">
-							<text class="detail-label">鍑哄樊鍦扮偣</text>
-							<text class="detail-value">{{ item.location || '-' }}</text>
-						</view>
-						
-						<!-- approveType=4 鎶ラ攢鐩稿叧瀛楁 -->
-						<view v-if="item.approveType === 4" class="detail-row">
-							<text class="detail-label">鎶ラ攢閲戦</text>
-							<text class="detail-value highlightYellow">{{ item.price ? `楼${item.price}` : '-' }}</text>
-						</view>
-						
-						<view class="detail-row">
-							<text class="detail-label">缁撴潫鏃ユ湡</text>
-							<text class="detail-value">{{ item.approveOverTime }}</text>
-						</view>
-						<up-divider></up-divider>
-						<view class="detail-info">
-							<view class="detail-row-user">
-								<text class="detail-label">褰撳墠瀹℃壒浜�</text>
-								<view class="detail-value approver-value">
-									<view class="approver-chip">
-										<text class="approver-name">{{ item.approveUserCurrentName || '鏈垎閰�' }}</text>
-									</view>
-								</view>
-							</view>
-							<view class="detail-row">
-								<view class="actions">
-									<u-button
-										type="primary"
-										size="small"
-										class="action-btn edit"
-										:disabled="item.approveStatus == 2 || item.approveStatus == 1 || item.approveStatus == 4"
-										@click="handleItemClick(item)"
-									>
-											缂栬緫
-									</u-button>
-									<u-button
-										type="success"
-										size="small"
-										class="action-btn approve"
-										:disabled="item.approveUserCurrentId == null || item.approveStatus == 2 || item.approveStatus == 3 || item.approveStatus == 4 || item.approveUserCurrentId !== userStore.id"
-										@click="approve(item)"
-									>
-											瀹℃牳
-									</u-button>
-								</view>
-							</view>
-						</view>
-					</view>
-				</view>
-			</view>
-		</view>
-		<view v-else class="no-data">
-			<text>鏆傛棤瀹℃壒鏁版嵁</text>
-		</view>
-		<!-- 娴姩鎿嶄綔鎸夐挳 -->
-		<view class="fab-button" @click="handleAdd">
-			<up-icon name="plus" size="24" color="#ffffff"></up-icon>
-		</view>
-	</view>
+  <view class="sales-account">
+    <!-- 浣跨敤閫氱敤椤甸潰澶撮儴缁勪欢 -->
+    <PageHeader :title="pageTitle"
+                @back="goBack" />
+    <!-- 鎼滅储鍜岀瓫閫夊尯鍩� -->
+    <view class="search-section">
+      <view class="search-bar">
+        <view class="search-input">
+          <up-input class="search-text"
+                    placeholder="璇疯緭鍏ユ祦绋嬬紪鍙�"
+                    v-model="searchForm.approveId"
+                    clearable />
+        </view>
+        <view class="search-button"
+              @click="getList">
+          <up-icon name="search"
+                   size="24"
+                   color="#999"></up-icon>
+        </view>
+      </view>
+    </view>
+    <!-- 瀹℃壒鍒楄〃 -->
+    <view class="ledger-list"
+          v-if="ledgerList.length > 0">
+      <view v-for="(item, index) in ledgerList"
+            :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.approveId }}</text>
+            </view>
+            <view class="item-tag">
+              <u-tag :type="getTagClass(item.approveStatus)">{{ formatReceiptType(item.approveStatus) }}</u-tag>
+            </view>
+          </view>
+          <up-divider></up-divider>
+          <view class="item-details">
+            <view class="detail-row">
+              <text class="detail-label">鐢宠浜�</text>
+              <text class="detail-value">{{ item.approveUserName }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">鐢宠閮ㄩ棬</text>
+              <text class="detail-value">{{ item.approveDeptName }}</text>
+            </view>
+            <view class="detail-row-approveReason">
+              <text class="detail-label">瀹℃壒浜嬬敱</text>
+              <text class="detail-value highlightBlue">{{ item.approveReason }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">鐢宠鏃ユ湡</text>
+              <text class="detail-value">{{ item.approveTime }}</text>
+            </view>
+            <!-- approveType=2 璇峰亣鐩稿叧瀛楁 -->
+            <template v-if="item.approveType === 2">
+              <view class="detail-row">
+                <text class="detail-label">璇峰亣寮�濮嬫椂闂�</text>
+                <text class="detail-value">{{ item.startDate || '-' }}</text>
+              </view>
+              <view class="detail-row">
+                <text class="detail-label">璇峰亣缁撴潫鏃堕棿</text>
+                <text class="detail-value">{{ item.endDate || '-' }}</text>
+              </view>
+            </template>
+            <!-- approveType=3 鍑哄樊鐩稿叧瀛楁 -->
+            <view v-if="item.approveType === 3"
+                  class="detail-row">
+              <text class="detail-label">鍑哄樊鍦扮偣</text>
+              <text class="detail-value">{{ item.location || '-' }}</text>
+            </view>
+            <!-- approveType=4 鎶ラ攢鐩稿叧瀛楁 -->
+            <view v-if="item.approveType === 4"
+                  class="detail-row">
+              <text class="detail-label">鎶ラ攢閲戦</text>
+              <text class="detail-value highlightYellow">{{ item.price ? `楼${item.price}` : '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">缁撴潫鏃ユ湡</text>
+              <text class="detail-value">{{ item.approveOverTime }}</text>
+            </view>
+            <up-divider></up-divider>
+            <view class="detail-info">
+              <view class="detail-row-user">
+                <text class="detail-label">褰撳墠瀹℃壒浜�</text>
+                <view class="detail-value approver-value">
+                  <view class="approver-chip">
+                    <text class="approver-name">{{ item.approveUserCurrentName || '鏈垎閰�' }}</text>
+                  </view>
+                </view>
+              </view>
+              <view class="detail-row">
+                <view class="actions">
+                  <u-button type="primary"
+                            size="small"
+                            class="action-btn edit"
+                            :disabled="item.approveStatus == 2 || item.approveStatus == 1 || item.approveStatus == 4"
+                            @click="handleItemClick(item)">
+                    缂栬緫
+                  </u-button>
+                  <u-button type="success"
+                            size="small"
+                            class="action-btn approve"
+                            :disabled="item.approveUserCurrentId == null || item.approveStatus == 2 || item.approveStatus == 3 || item.approveStatus == 4 || item.approveUserCurrentId !== userStore.id"
+                            @click="approve(item)">
+                    瀹℃牳
+                  </u-button>
+                </view>
+              </view>
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+    <view v-else
+          class="no-data">
+      <text>鏆傛棤瀹℃壒鏁版嵁</text>
+    </view>
+    <!-- 娴姩鎿嶄綔鎸夐挳 -->
+    <view class="fab-button"
+          @click="handleAdd">
+      <up-icon name="plus"
+               size="24"
+               color="#ffffff"></up-icon>
+    </view>
+  </view>
 </template>
 
 <script setup>
-	import {
-		ref,
-		toRefs,
-		reactive
-	} from "vue";
-	import PageHeader from "@/components/PageHeader.vue";
-	import {approveProcessListPage} from "@/api/collaborativeApproval/approvalProcess";
-	import {onShow} from "@dcloudio/uni-app";
-	import useUserStore from "@/store/modules/user";
-	
-	// 鎺ユ敹鐖剁粍浠朵紶閫掔殑 approveType 鍙傛暟
-	const props = defineProps({
-		approveType: {
-			type: Number,
-			default: 0
-		}
-	});
-	
-	const userStore = useUserStore()
-	// 鏁版嵁
-	const ledgerList = ref([]);
-	const data = reactive({
-		searchForm: {
-			approveId: "",
-		},
-	});
-	const { searchForm } = toRefs(data);
+  import { ref, toRefs, reactive } from "vue";
+  import PageHeader from "@/components/PageHeader.vue";
+  import { approveProcessListPage } from "@/api/collaborativeApproval/approvalProcess";
+  import { onShow } from "@dcloudio/uni-app";
+  import useUserStore from "@/store/modules/user";
 
-	// 杩斿洖涓婁竴椤�
-	const goBack = () => {
-		uni.navigateBack();
-	};
-	// 鏌ヨ鍒楄〃
-	const getList = () => {
-		showLoadingToast('鍔犺浇涓�...')
-		const page = {
-			current: -1,
-			size: -1,
-		};
-		approveProcessListPage({
-				...page,approveType: props.approveType,...searchForm.value
-			})
-			.then((res) => {
-				ledgerList.value = res.data.records;
-				closeToast()
-			})
-			.catch(() => {
-				closeToast()
-			});
-	};
-	// 鏄剧ず鍔犺浇鎻愮ず
-	const showLoadingToast = (message) => {
-		uni.showLoading({
-			title: message,
-			mask: true
-		});
-	};
+  // 鎺ユ敹鐖剁粍浠朵紶閫掔殑 approveType 鍙傛暟
+  const props = defineProps({
+    approveType: {
+      type: Number,
+      default: 0,
+    },
+  });
 
-	// 鍏抽棴鎻愮ず
-	const closeToast = () => {
-		uni.hideLoading();
-	};
+  // 鏄犲皠 approveType 鍒板搴旂殑椤甸潰鏍囬
+  const getPageTitle = type => {
+    const titleMap = {
+      1: "鍏嚭绠$悊",
+      2: "璇峰亣绠$悊",
+      3: "鍑哄樊绠$悊",
+      4: "鎶ラ攢绠$悊",
+      5: "閲囪喘绠$悊",
+      6: "鎶ヤ环绠$悊",
+      7: "鍑哄簱绠$悊",
+    };
+    return titleMap[type] || "瀹℃壒绠$悊";
+  };
 
-	// 鏄剧ず绛涢�夐�夐」
-	const showFilterOptions = () => {
-		uni.showActionSheet({
-			itemList: ["鎸夋棩鏈熺瓫閫�", "鎸夌姸鎬佺瓫閫�", "鎸夐噾棰濈瓫閫�"],
-			success: (res) => {
-				console.log("閫夋嫨浜嗙瓫閫夐�夐」:", res.tapIndex);
-			},
-		});
-	};
-	// 鏍煎紡鍖栧洖娆炬柟寮�
-	const formatReceiptType = (params) => {
-		if (params == 0) {
-			return "寰呭鏍�";
-		} else if (params == 1) {
-			return "瀹℃牳涓�";
-		} else if (params == 2) {
-			return "瀹℃牳瀹屾垚";
-		} else if (params == 4) {
-			return "宸查噸鏂版彁浜�";
-		} else {
-			return '涓嶉�氳繃';
-		}
-	};
-	// 鑾峰彇鏍囩鏍峰紡绫�
-	const getTagClass = (type) => {
-		if (type == 0) {
-			return "warning";
-		} else if (type == 1) {
-			return "primary";
-		} else if (type == 2) {
-			return "success";
-		} else if (type == 4) {
-			return "primary";
-		} else {
-			return "error";
-		}
-	};
+  const pageTitle = getPageTitle(props.approveType);
 
-	// 鐐瑰嚮鍒楄〃椤�
-	const handleItemClick = (item) => {
-		// 浣跨敤鏈湴瀛樺偍浼犻�掓暟鎹�
-		uni.setStorageSync('invoiceLedgerEditRow', JSON.stringify(item));
-		uni.setStorageSync('operationType', 'edit');
-		uni.setStorageSync('approveId', item.approveId);
-		uni.setStorageSync('approveType', props.approveType);
-		uni.navigateTo({
-			url: "/pages/cooperativeOffice/collaborativeApproval/detail",
-		});
-	};
+  const userStore = useUserStore();
+  // 鏁版嵁
+  const ledgerList = ref([]);
+  const data = reactive({
+    searchForm: {
+      approveId: "",
+    },
+  });
+  const { searchForm } = toRefs(data);
 
-	// 娣诲姞鏂拌褰�
-	const handleAdd = () => {
-		uni.setStorageSync('operationType', 'add');
-		uni.setStorageSync('approveType', props.approveType);
-		uni.navigateTo({
-			url: `/pages/cooperativeOffice/collaborativeApproval/detail?approveType=${props.approveType}`,
-		});
-	};
-	// 鐐瑰嚮瀹℃牳
-	const approve = (item) => {
-		uni.setStorageSync('approveId', item.approveId);
-		uni.setStorageSync('approveType', props.approveType);
-		uni.navigateTo({
-			url: "/pages/cooperativeOffice/collaborativeApproval/approve?approveType=" + props.approveType
-		})
-	}
+  // 杩斿洖涓婁竴椤�
+  const goBack = () => {
+    uni.navigateBack();
+  };
+  // 鏌ヨ鍒楄〃
+  const getList = () => {
+    showLoadingToast("鍔犺浇涓�...");
+    const page = {
+      current: -1,
+      size: -1,
+    };
+    approveProcessListPage({
+      ...page,
+      approveType: props.approveType,
+      ...searchForm.value,
+    })
+      .then(res => {
+        ledgerList.value = res.data.records;
+        closeToast();
+      })
+      .catch(() => {
+        closeToast();
+      });
+  };
+  // 鏄剧ず鍔犺浇鎻愮ず
+  const showLoadingToast = message => {
+    uni.showLoading({
+      title: message,
+      mask: true,
+    });
+  };
 
-	onShow(() => {
-		// 椤甸潰鍔犺浇瀹屾垚鍚庣殑鍒濆鍖栭�昏緫
-		getList();
-	});
+  // 鍏抽棴鎻愮ず
+  const closeToast = () => {
+    uni.hideLoading();
+  };
+
+  // 鏄剧ず绛涢�夐�夐」
+  const showFilterOptions = () => {
+    uni.showActionSheet({
+      itemList: ["鎸夋棩鏈熺瓫閫�", "鎸夌姸鎬佺瓫閫�", "鎸夐噾棰濈瓫閫�"],
+      success: res => {
+        console.log("閫夋嫨浜嗙瓫閫夐�夐」:", res.tapIndex);
+      },
+    });
+  };
+  // 鏍煎紡鍖栧洖娆炬柟寮�
+  const formatReceiptType = params => {
+    if (params == 0) {
+      return "寰呭鏍�";
+    } else if (params == 1) {
+      return "瀹℃牳涓�";
+    } else if (params == 2) {
+      return "瀹℃牳瀹屾垚";
+    } else if (params == 4) {
+      return "宸查噸鏂版彁浜�";
+    } else {
+      return "涓嶉�氳繃";
+    }
+  };
+  // 鑾峰彇鏍囩鏍峰紡绫�
+  const getTagClass = type => {
+    if (type == 0) {
+      return "warning";
+    } else if (type == 1) {
+      return "primary";
+    } else if (type == 2) {
+      return "success";
+    } else if (type == 4) {
+      return "primary";
+    } else {
+      return "error";
+    }
+  };
+
+  // 鐐瑰嚮鍒楄〃椤�
+  const handleItemClick = item => {
+    // 浣跨敤鏈湴瀛樺偍浼犻�掓暟鎹�
+    uni.setStorageSync("invoiceLedgerEditRow", JSON.stringify(item));
+    uni.setStorageSync("operationType", "edit");
+    uni.setStorageSync("approveId", item.approveId);
+    uni.setStorageSync("approveType", props.approveType);
+    uni.navigateTo({
+      url: "/pages/cooperativeOffice/collaborativeApproval/detail",
+    });
+  };
+
+  // 娣诲姞鏂拌褰�
+  const handleAdd = () => {
+    uni.setStorageSync("operationType", "add");
+    uni.setStorageSync("approveType", props.approveType);
+    uni.navigateTo({
+      url: `/pages/cooperativeOffice/collaborativeApproval/detail?approveType=${props.approveType}`,
+    });
+  };
+  // 鐐瑰嚮瀹℃牳
+  const approve = item => {
+    uni.setStorageSync("approveId", item.approveId);
+    uni.setStorageSync("approveType", props.approveType);
+    uni.navigateTo({
+      url:
+        "/pages/cooperativeOffice/collaborativeApproval/approve?approveType=" +
+        props.approveType,
+    });
+  };
+
+  onShow(() => {
+    // 椤甸潰鍔犺浇瀹屾垚鍚庣殑鍒濆鍖栭�昏緫
+    getList();
+  });
 </script>
 
 <style scoped lang="scss">
-	@import "../../../styles/sales-common.scss";
+  @import "../../../styles/sales-common.scss";
 
-	.u-divider {
-		margin: 0 !important;
-	}
+  .u-divider {
+    margin: 0 !important;
+  }
 
-	// 鏂囨。鍥炬爣鏍峰紡 - 瑕嗙洊鍏叡鏍峰紡涓殑鑳屾櫙鑹�
-	.document-icon {
-		background: #ed8d05;
-	}
+  // 鏂囨。鍥炬爣鏍峰紡 - 瑕嗙洊鍏叡鏍峰紡涓殑鑳屾櫙鑹�
+  .document-icon {
+    background: #ed8d05;
+  }
 
-	// 娴姩鎸夐挳鏍峰紡 - 瑕嗙洊鍏叡鏍峰紡涓殑鑳屾櫙鑹�
-	.fab-button {
-		background: #ed8d05;
-	}
+  // 娴姩鎸夐挳鏍峰紡 - 瑕嗙洊鍏叡鏍峰紡涓殑鑳屾櫙鑹�
+  .fab-button {
+    background: #ed8d05;
+  }
 
-	// 鐗规湁鏍峰紡
-	.detail-row-user {
-		display: flex;
-		align-items: center;
-		justify-content: space-between;
-	}
-	
-	.detail-row-approveReason {
-		display: flex;
-		align-items: center;
-		justify-content: space-between;
-		margin-bottom: 8px;
-	}
+  // 鐗规湁鏍峰紡
+  .detail-row-user {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+  }
 
-	.detail-value.highlightBlue {
-		color: #2979ff;
-		font-weight: 500;
-	}
+  .detail-row-approveReason {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin-bottom: 8px;
+  }
 
-	.detail-value.highlightYellow {
-		color: #ed8d05;
-		font-weight: 500;
-	}
+  .detail-value.highlightBlue {
+    color: #2979ff;
+    font-weight: 500;
+  }
 
-	.approver-value {
-		display: flex;
-		justify-content: flex-end;
-	}
-	
-	.approver-chip {
-		display: inline-flex;
-		align-items: center;
-		gap: 6px;
-		background: #f0f6ff;
-		color: #2b7cff;
-		border: 1px solid #e0efff;
-		border-radius: 999px;
-		padding: 4px 10px;
-		max-width: 100%;
-	}
-	
-	.approver-name {
-		font-size: 12px;
-		color: #2b7cff;
-		overflow: hidden;
-		text-overflow: ellipsis;
-		white-space: nowrap;
-	}
+  .detail-value.highlightYellow {
+    color: #ed8d05;
+    font-weight: 500;
+  }
 
-	.actions {
-		display: flex;
-		gap: 10px;
-		align-items: center;
-		justify-content: flex-end;
-	}
+  .approver-value {
+    display: flex;
+    justify-content: flex-end;
+  }
 
-	.action-btn {
-		border-radius: 16px;
-		height: 28px;
-		line-height: 28px;
-		padding: 0 12px;
-	}
+  .approver-chip {
+    display: inline-flex;
+    align-items: center;
+    gap: 6px;
+    background: #f0f6ff;
+    color: #2b7cff;
+    border: 1px solid #e0efff;
+    border-radius: 999px;
+    padding: 4px 10px;
+    max-width: 100%;
+  }
 
+  .approver-name {
+    font-size: 12px;
+    color: #2b7cff;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+
+  .actions {
+    display: flex;
+    gap: 10px;
+    align-items: center;
+    justify-content: flex-end;
+  }
+
+  .action-btn {
+    border-radius: 16px;
+    height: 28px;
+    line-height: 28px;
+    padding: 0 12px;
+  }
 </style>
\ No newline at end of file
diff --git a/src/pages/index.vue b/src/pages/index.vue
index 5f0b494..8abfb9e 100644
--- a/src/pages/index.vue
+++ b/src/pages/index.vue
@@ -303,6 +303,18 @@
       label: "鍑哄簱绠$悊",
     },
     {
+      icon: "/static/images/icon/qingjiaguanli@2x.png",
+      label: "浼氳璁剧疆",
+    },
+    {
+      icon: "/static/images/icon/qingjiaguanli@2x.png",
+      label: "浼氳鍒楄〃",
+    },
+    {
+      icon: "/static/images/icon/qingjiaguanli@2x.png",
+      label: "浼氳鐢宠",
+    },
+    {
       icon: "/static/images/icon/xietongshenpi@2x.png",
       label: "鍗忓悓瀹℃壒",
     },
@@ -495,6 +507,21 @@
           url: "/pages/cooperativeOffice/collaborativeApproval/index7",
         });
         break;
+      case "浼氳璁剧疆":
+        uni.navigateTo({
+          url: "/pages/managementMeetings/meetingSettings/index",
+        });
+        break;
+      case "浼氳鍒楄〃":
+        uni.navigateTo({
+          url: "/pages/managementMeetings/meetingList/index",
+        });
+        break;
+      case "浼氳鐢宠":
+        uni.navigateTo({
+          url: "/pages/managementMeetings/meetApplication/index",
+        });
+        break;
       case "鍗忓悓瀹℃壒":
         uni.navigateTo({
           url: "/pages/cooperativeOffice/collaborativeApproval/index",
diff --git a/src/pages/managementMeetings/meetApplication/index.vue b/src/pages/managementMeetings/meetApplication/index.vue
new file mode 100644
index 0000000..ac7eb16
--- /dev/null
+++ b/src/pages/managementMeetings/meetApplication/index.vue
@@ -0,0 +1,497 @@
+<template>
+  <view style="background-color: #fff;"
+        class="client-visit-detail">
+    <PageHeader title="浼氳鐢宠"
+                @back="goBack" />
+    <view>
+      <view v-for="item in applicationTypes"
+            :key="item.value"
+            class="application-type-item"
+            :class="{ active: meetingForm.applicationType === item.value }"
+            @click="selectApplicationType(item)">
+        <view class="application-type-info">
+          <view class="application-type-name">{{ item.name }}</view>
+          <view class="application-type-desc">{{ item.desc }}</view>
+        </view>
+      </view>
+    </view>
+    <u-form ref="formRef"
+            label-width="90">
+      <!-- 瀹㈡埛淇℃伅 -->
+      <u-cell-group title="浼氳鐢宠">
+        <u-form-item label="浼氳涓婚"
+                     prop="title"
+                     required
+                     border-bottom>
+          <u-input v-model="meetingForm.title"
+                   placeholder="璇疯緭鍏ヤ細璁富棰�" />
+        </u-form-item>
+        <u-form-item label="浼氳瀹�"
+                     prop="roomId"
+                     required
+                     border-bottom>
+          <u-input v-model="meetingForm.roomName"
+                   placeholder="璇烽�夋嫨浼氳瀹�"
+                   readonly
+                   @click="showRoomPicker = true" />
+          <template #right>
+            <up-icon name="arrow-right"
+                     @click="showRoomPicker = true"></up-icon>
+          </template>
+        </u-form-item>
+        <u-form-item label="涓绘寔浜�"
+                     prop="host"
+                     required
+                     border-bottom>
+          <u-input v-model="meetingForm.host"
+                   placeholder="璇疯緭鍏ヤ富鎸佷汉濮撳悕" />
+        </u-form-item>
+        <u-form-item label="浼氳鏃ユ湡"
+                     prop="meetingDate"
+                     required
+                     border-bottom>
+          <u-input v-model="meetingForm.meetingDate"
+                   placeholder="璇烽�夋嫨浼氳鏃ユ湡"
+                   readonly
+                   @click="showDatePicker = true" />
+          <template #right>
+            <up-icon name="calendar"
+                     @click="showDatePicker = true"></up-icon>
+          </template>
+        </u-form-item>
+        <u-form-item label="寮�濮嬫椂闂�"
+                     prop="startTime"
+                     required
+                     border-bottom>
+          <u-input v-model="meetingForm.startTime"
+                   placeholder="璇烽�夋嫨寮�濮嬫椂闂�"
+                   readonly
+                   @click="showStartTimePicker = true" />
+          <template #right>
+            <up-icon name="clock"
+                     @click="showStartTimePicker = true"></up-icon>
+          </template>
+        </u-form-item>
+        <u-form-item label="缁撴潫鏃堕棿"
+                     prop="endTime"
+                     required
+                     border-bottom>
+          <u-input v-model="meetingForm.endTime"
+                   placeholder="璇烽�夋嫨缁撴潫鏃堕棿"
+                   readonly
+                   @click="showEndTimePicker = true" />
+          <template #right>
+            <up-icon name="clock"
+                     @click="showEndTimePicker = true"></up-icon>
+          </template>
+        </u-form-item>
+        <u-form-item label="鍙備細浜哄憳"
+                     prop="participants"
+                     required
+                     border-bottom>
+          <u-input v-model="meetingForm.participantsNames"
+                   placeholder="璇烽�夋嫨鍙備細浜哄憳"
+                   readonly
+                   @click="showEquipmentSheet = true" />
+          <template #right>
+            <up-icon name="arrow-right"
+                     @click="openParticipantPicker"></up-icon>
+          </template>
+        </u-form-item>
+        <u-form-item label="浼氳璇存槑"
+                     prop="description"
+                     border-bottom>
+          <u-input v-model="meetingForm.description"
+                   placeholder="璇疯緭鍏ヤ細璁鏄�" />
+        </u-form-item>
+      </u-cell-group>
+      <!-- 鎻愪氦鎸夐挳 -->
+    </u-form>
+    <view class="footer-btns">
+      <u-button class="cancel-btn"
+                @click="resetForm">閲嶇疆</u-button>
+      <u-button class="save-btn"
+                @click="handleSubmit">淇濆瓨</u-button>
+    </view>
+    <!-- 鏃ユ湡閫夋嫨鍣� -->
+    <up-datetime-picker v-model="meetingForm.meetingDate"
+                        mode="date"
+                        :show="showDatePicker"
+                        @confirm="onDateSelect"
+                        @cancel="showDatePicker = false"
+                        format="YYYY-MM-DD"
+                        value-format="YYYY-MM-DD"
+                        :min-date="minDate" />
+    <!-- 寮�濮嬫椂闂撮�夋嫨鍣� -->
+    <up-action-sheet :show="showStartTimePicker"
+                     :actions="timeOptions"
+                     @select="onStartTimeSelect"
+                     @close="showStartTimePicker = false" />
+    <!-- 缁撴潫鏃堕棿閫夋嫨鍣� -->
+    <up-action-sheet :show="showEndTimePicker"
+                     :actions="timeOptions"
+                     @select="onEndTimeSelect"
+                     @close="showEndTimePicker = false" />
+    <!-- 浼氳瀹ら�夋嫨鍣� -->
+    <up-action-sheet :show="showRoomPicker"
+                     :actions="meetingRooms"
+                     @select="onRoomSelect"
+                     @close="showRoomPicker = false" />
+    <u-popup :show="showEquipmentSheet"
+             mode="bottom"
+             @close="showEquipmentSheet = false"
+             height="200px">
+      <view class="popup-content">
+        <view class="popup-body">
+          <u-checkbox-group v-model="meetingForm.participants"
+                            @change="handleParticipantChange"
+                            icon-placement="right"
+                            placement="row">
+            <view style="width:100%;padding:10px;margin-top:20px;">
+              <u-checkbox v-for="option in employees"
+                          :key="option.id"
+                          :name="option.id"
+                          :label="`${option.staffName} (${option.postJob})`"
+                          class="checkbox-item"></u-checkbox>
+            </view>
+          </u-checkbox-group>
+        </view>
+      </view>
+    </u-popup>
+  </view>
+</template>
+
+<script setup>
+  // 鏇挎崲 toast 鏂规硶
+  defineOptions({ name: "meeting-settings-detail" });
+  const showToast = message => {
+    uni.showToast({
+      title: message,
+      icon: "none",
+    });
+  };
+
+  import { ref, reactive, onMounted, computed } from "vue";
+  import PageHeader from "@/components/PageHeader.vue";
+  import useUserStore from "@/store/modules/user";
+  import {
+    saveMeetingApplication,
+    getRoomEnum,
+  } from "@/api/managementMeetings/meeting";
+  import { getStaffOnJob } from "@/api/personnelManagement/onboarding";
+  import dayjs from "dayjs";
+
+  const userStore = useUserStore();
+
+  // 琛ㄥ崟鏁版嵁
+  const meetingForm = reactive({
+    title: "",
+    type: "",
+    roomId: "",
+    roomName: "",
+    host: "",
+    meetingDate: "",
+    startTime: "",
+    endTime: "",
+    participants: [],
+    description: "",
+    participantsNames: [],
+    applicationType: "department",
+  });
+  // 鐢宠绫诲瀷閫夐」
+  const applicationTypes = ref([
+    {
+      value: "approval",
+      name: "瀹℃壒娴佺▼浼氳",
+      desc: "闇�瑕佺粡杩囧绾у鎵圭殑浼氳鐢宠",
+      // icon: Document,
+    },
+    {
+      value: "department",
+      name: "閮ㄩ棬绾т細璁�",
+      desc: "閮ㄩ棬鍐呴儴浼氳鐢宠娴佺▼",
+      // icon: Promotion,
+    },
+    {
+      value: "notification",
+      name: "浼氳閫氱煡",
+      desc: "鏃犻渶瀹℃壒鐩存帴鍙戝竷鐨勪細璁�氱煡",
+      // icon: Bell,
+    },
+  ]);
+  // 椤甸潰鐘舵��
+  const loading = ref(false);
+  const formRef = ref(null);
+  const showDatePicker = ref(false);
+  const showStartTimePicker = ref(false);
+  const showEndTimePicker = ref(false);
+  const showRoomPicker = ref(false);
+
+  // 鏈�灏忔棩鏈燂紙浠婂ぉ锛�
+  const minDate = computed(() => {
+    return dayjs().format("YYYY-MM-DD");
+  });
+
+  // 閫夋嫨鐢宠绫诲瀷
+  const selectApplicationType = item => {
+    meetingForm.applicationType = item.value;
+  };
+
+  // 杩斿洖涓婁竴椤�
+  const goBack = () => {
+    uni.navigateBack();
+  };
+  const showEquipmentSheet = ref(false);
+  const openParticipantPicker = () => {
+    showEquipmentSheet.value = true;
+  };
+
+  // 閲嶇疆琛ㄥ崟
+  const resetForm = () => {
+    meetingForm.title = "";
+    meetingForm.type = "";
+    meetingForm.roomId = "";
+    meetingForm.roomName = "";
+    meetingForm.host = "";
+    meetingForm.meetingDate = "";
+    meetingForm.startTime = "";
+    meetingForm.endTime = "";
+    meetingForm.participants = [];
+    meetingForm.participantsNames = [];
+    meetingForm.description = "";
+    meetingForm.applicationType = "department";
+  };
+  const handleParticipantChange = val => {
+    console.log("val", val);
+
+    meetingForm.participants = val;
+    meetingForm.participantsNames = employees.value
+      .filter(employee => val.includes(employee.id))
+      .map(employee => employee.staffName);
+  };
+  // 鎻愪氦琛ㄥ崟
+  const handleSubmit = async () => {
+    console.log("meetingForm", meetingForm);
+    if (!meetingForm.title) {
+      showToast("璇疯緭鍏ヤ細璁富棰�");
+      return;
+    }
+
+    if (!meetingForm.roomId) {
+      showToast("璇烽�夋嫨浼氳瀹�");
+      return;
+    }
+
+    if (!meetingForm.host) {
+      showToast("璇疯緭鍏ヤ富鎸佷汉");
+      return;
+    }
+
+    if (!meetingForm.meetingDate) {
+      showToast("璇烽�夋嫨浼氳鏃ユ湡");
+      return;
+    }
+
+    if (!meetingForm.startTime) {
+      showToast("璇烽�夋嫨寮�濮嬫椂闂�");
+      return;
+    }
+
+    if (!meetingForm.endTime) {
+      showToast("璇烽�夋嫨缁撴潫鏃堕棿");
+      return;
+    }
+
+    if (!meetingForm.participants) {
+      showToast("璇烽�夋嫨鍙備細浜哄憳");
+      return;
+    }
+
+    // 楠岃瘉寮�濮嬫椂闂村繀椤诲皬浜庣粨鏉熸椂闂�
+    if (meetingForm.startTime >= meetingForm.endTime) {
+      showToast("寮�濮嬫椂闂村繀椤诲皬浜庣粨鏉熸椂闂�");
+      return;
+    }
+
+    try {
+      loading.value = true;
+
+      let formData = { ...meetingForm };
+      formData.startTime = `${meetingForm.meetingDate} ${meetingForm.startTime}:00`;
+      formData.endTime = `${meetingForm.meetingDate} ${meetingForm.endTime}:00`;
+      formData.participants = JSON.stringify(meetingForm.participants);
+
+      console.log(formData);
+
+      // 璋冪敤瀹為檯鐨凙PI
+      const res = await saveMeetingApplication(formData);
+
+      if (res.code === 200) {
+        showToast("淇濆瓨鎴愬姛");
+        setTimeout(() => {
+          goBack();
+        }, 500);
+      } else {
+        showToast(res.message || "淇濆瓨澶辫触锛岃閲嶈瘯");
+      }
+    } catch (e) {
+      console.error("淇濆瓨澶辫触:", e);
+      showToast("淇濆瓨澶辫触锛岃閲嶈瘯");
+    } finally {
+      loading.value = false;
+    }
+  };
+  // 鏃ユ湡閫夋嫨鍣ㄧ‘璁ゅ洖璋�
+  const onDateSelect = action => {
+    console.log(action.value);
+
+    if (action.value) {
+      meetingForm.meetingDate = dayjs(action.value).format("YYYY-MM-DD");
+    } else {
+      meetingForm.meetingDate = dayjs().format("YYYY-MM-DD");
+    }
+
+    showDatePicker.value = false;
+  };
+  const onStartTimeSelect = action => {
+    meetingForm.startTime = action.value;
+    showStartTimePicker.value = false;
+  };
+  const onEndTimeSelect = action => {
+    meetingForm.endTime = action.value;
+    showEndTimePicker.value = false;
+  };
+
+  // 浼氳瀹ら�夋嫨鍥炶皟
+  const onRoomSelect = action => {
+    meetingForm.roomId = action.id;
+    meetingForm.roomName = action.name;
+    showRoomPicker.value = false;
+  };
+  // 鏃堕棿閫夐」锛堜互鍗婂皬鏃朵负闂撮殧锛�
+  const timeOptions = ref([]);
+
+  // 鍒濆鍖栨椂闂撮�夐」
+  const initTimeOptions = () => {
+    const options = [];
+    for (let hour = 8; hour <= 18; hour++) {
+      // 姣忎釜灏忔椂娣诲姞涓や釜閫夐」锛氭暣鐐瑰拰鍗婄偣
+      options.push({
+        value: `${hour.toString().padStart(2, "0")}:00`,
+        name: `${hour.toString().padStart(2, "0")}:00`,
+      });
+
+      if (hour < 18) {
+        // 18:00涔嬪悗娌℃湁鍗婄偣閫夐」
+        options.push({
+          value: `${hour.toString().padStart(2, "0")}:30`,
+          name: `${hour.toString().padStart(2, "0")}:30`,
+        });
+      }
+    }
+    timeOptions.value = options;
+  };
+  // 浼氳瀹ゅ垪琛�
+  const employees = ref([]);
+  const meetingRooms = ref([]);
+  const getMeetingRooms = async () => {
+    try {
+      const res = await getRoomEnum();
+      if (res.code === 200) {
+        meetingRooms.value = res.data || [];
+      } else {
+        showToast(res.message || "鑾峰彇浼氳瀹ゅ垪琛ㄥけ璐�");
+      }
+    } catch (e) {
+      console.error("鑾峰彇浼氳瀹ゅ垪琛ㄥけ璐�:", e);
+      showToast("鑾峰彇浼氳瀹ゅ垪琛ㄥけ璐ワ紝璇烽噸璇�");
+    }
+  };
+
+  onMounted(() => {
+    initPageData();
+    initTimeOptions();
+    getMeetingRooms();
+    getStaffOnJob().then(res => {
+      employees.value = res.data.sort((a, b) =>
+        a.postJob.localeCompare(b.postJob)
+      );
+    });
+  });
+
+  const initPageData = () => {
+    // 鍒濆鍖栨暟鎹�
+  };
+</script>
+
+<style scoped lang="scss">
+  @import "@/static/scss/form-common.scss";
+
+  .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: #ffffff;
+    width: 6.375rem;
+    background: #c7c9cc;
+    box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
+    border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+  }
+
+  .save-btn {
+    font-weight: 400;
+    font-size: 1rem;
+    color: #ffffff;
+    width: 14rem;
+    background: linear-gradient(140deg, #00baff 0%, #006cfb 100%);
+    box-shadow: 0 0.25rem 0.625rem 0 rgba(3, 88, 185, 0.2);
+    border-radius: 2.5rem 2.5rem 2.5rem 2.5rem;
+  }
+  .application-type-item {
+    width: 94%;
+    margin-left: 3%;
+    // height: 120rpx;
+    background-color: #f1f1f1;
+    border-radius: 10rpx;
+    margin-top: 20rpx;
+    padding: 20rpx;
+    box-shadow: 0 2rpx 12rpx 0 rgba(246, 244, 244, 0.1);
+    transition: box-shadow 0.3s ease;
+  }
+  .application-type-item.active {
+    box-shadow: 0 4rpx 16rpx 0 rgba(0, 0, 0, 0.15);
+    background-color: #fff;
+    border: 1rpx solid #0078a3;
+  }
+
+  .application-type-name {
+    font-weight: 400;
+    font-size: 1rem;
+    color: #000000;
+  }
+  .application-type-item.active .application-type-name {
+    color: #0078a3;
+  }
+  .application-type-desc {
+    font-weight: 400;
+    font-size: 0.875rem;
+    margin-top: 0.5rem;
+    color: #757575;
+  }
+  .application-type-item.active .application-type-desc {
+    color: #0078a3;
+  }
+</style>
\ No newline at end of file
diff --git a/src/pages/managementMeetings/meetingList/index.vue b/src/pages/managementMeetings/meetingList/index.vue
new file mode 100644
index 0000000..8203f38
--- /dev/null
+++ b/src/pages/managementMeetings/meetingList/index.vue
@@ -0,0 +1,529 @@
+<template>
+  <view class="meeting-list">
+    <PageHeader title="浼氳鍒楄〃"
+                @back="goBack" />
+    <!-- 鏌ヨ琛ㄥ崟 -->
+    <view class="search-section">
+      <view class="search-bar">
+        <view class="search-input">
+          <up-input class="search-text"
+                    placeholder="鏌ヨ鏃ユ湡"
+                    @click.stop="showDatePicker"
+                    v-model="queryForm.meetingDate"
+                    clearable />
+        </view>
+        <view class="filter-button"
+              @click="clearDate">
+          <u-icon name="close-circle-fill"
+                  size="24"
+                  color="#999"></u-icon>
+        </view>
+      </view>
+    </view>
+    <!-- 鏃ユ湡閫夋嫨鍣� -->
+    <up-datetime-picker v-model="datePickerValue"
+                        mode="date"
+                        :show="showDatePickerDialog"
+                        @confirm="handleDateConfirm"
+                        @cancel="showDatePickerDialog = false"
+                        format="YYYY-MM-DD"
+                        value-format="YYYY-MM-DD" />
+    <!-- 浼氳瀹や娇鐢ㄦ儏鍐� -->
+    <view class="table-container">
+      <scroll-view scroll-x="true"
+                   style="width: 100%;">
+        <view class="time-table">
+          <!-- 琛ㄥご -->
+          <view class="table-header">
+            <view class="header-cell room-header">浼氳瀹�</view>
+            <view v-for="timeSlot in timeSlots"
+                  :key="timeSlot.value"
+                  class="header-cell time-header">
+              {{ timeSlot.label }}
+            </view>
+          </view>
+          <!-- 琛ㄦ牸鍐呭 -->
+          <view class="table-body">
+            <view v-for="room in roomUsage"
+                  :key="room.id"
+                  class="table-row">
+              <view class="cell room-cell">{{ room.name }}</view>
+              <view class="cells-container">
+                <template v-for="(cell, index) in generateMeetingCells(room)"
+                          :key="index">
+                  <view class="cell content-cell"
+                        :class="[cell.type, `status-${cell.meeting?.status || '0'}`]"
+                        :style="{ width: `${cell.span * 120}rpx` }"
+                        @click="viewMeetingDetails(cell)">
+                    <view v-if="cell.type === 'meeting'"
+                          class="meeting-content">
+                      <view class="meeting-title">{{ cell.meeting.title }}</view>
+                      <view class="meeting-time">{{ cell.startTime }}-{{ cell.endTime }}</view>
+                    </view>
+                    <view v-else
+                          class="free-content">
+                      绌洪棽
+                    </view>
+                  </view>
+                </template>
+              </view>
+            </view>
+          </view>
+        </view>
+      </scroll-view>
+    </view>
+    <!-- 浼氳璇︽儏瀵硅瘽妗� -->
+    <u-popup :show="detailDialogVisible"
+             mode="center"
+             customStyle="width: 80%;"
+             :round="10">
+      <view class="dialog-content">
+        <view class="dialog-header">
+          <text class="dialog-title">浼氳璇︽儏</text>
+          <up-icon name="close"
+                   @click="detailDialogVisible = false"
+                   class="close-icon"></up-icon>
+        </view>
+        <view v-if="currentMeeting"
+              class="dialog-body">
+          <view class="detail-item">
+            <text class="detail-label">浼氳涓婚</text>
+            <text class="detail-value">{{ currentMeeting.title }}</text>
+          </view>
+          <view class="detail-item">
+            <text class="detail-label">浼氳瀹�</text>
+            <text class="detail-value">{{ currentMeeting.room }}</text>
+          </view>
+          <view class="detail-item">
+            <text class="detail-label">浼氳鏃堕棿</text>
+            <text class="detail-value">{{ currentMeeting.time }}</text>
+          </view>
+          <view class="detail-item">
+            <text class="detail-label">涓绘寔浜�</text>
+            <text class="detail-value">{{ currentMeeting.host }}</text>
+          </view>
+          <view class="detail-item">
+            <text class="detail-label">鍙備細浜烘暟</text>
+            <text class="detail-value">{{ currentMeeting.participants }}浜�</text>
+          </view>
+          <view class="detail-item">
+            <text class="detail-label">浼氳璇存槑</text>
+            <text class="detail-value">{{ currentMeeting.description }}</text>
+          </view>
+        </view>
+        <view class="dialog-footer">
+          <u-button @click="detailDialogVisible = false">鍏抽棴</u-button>
+        </view>
+      </view>
+    </u-popup>
+  </view>
+</template>
+
+<script setup>
+  import { ref, reactive, onMounted } from "vue";
+  import PageHeader from "@/components/PageHeader.vue";
+  import { getMeetingUseList } from "@/api/managementMeetings/meeting.js";
+  import dayjs from "dayjs";
+
+  // 鏌ヨ琛ㄥ崟
+  const queryForm = reactive({
+    meetingDate: dayjs().format("YYYY-MM-DD"),
+  });
+
+  const loading = ref(false);
+  const timeSlots = ref([]);
+  const roomUsage = ref([]);
+  const currentMeeting = ref(null);
+  const detailDialogVisible = ref(false);
+  const showDatePickerDialog = ref(false);
+  const datePickerValue = ref(Date.now());
+
+  // 杩斿洖涓婁竴椤�
+  const goBack = () => {
+    uni.navigateBack();
+  };
+
+  // 娓呯┖鏃ユ湡
+  const clearDate = () => {
+    datePickerValue.value = Date.now();
+    queryForm.meetingDate = dayjs().format("YYYY-MM-DD");
+    getList();
+  };
+
+  // 鏄剧ず鏃ユ湡閫夋嫨鍣�
+  const showDatePicker = () => {
+    if (queryForm.meetingDate) {
+      datePickerValue.value = new Date(queryForm.meetingDate).getTime();
+    } else {
+      datePickerValue.value = Date.now();
+    }
+    console.log(datePickerValue.value, "datePickerValue.value");
+    showDatePickerDialog.value = true;
+  };
+
+  // 澶勭悊鏃ユ湡閫夋嫨纭
+  const handleDateConfirm = value => {
+    // dayjs().format("YYYY-MM-DD")
+    console.log(value, "value");
+
+    queryForm.meetingDate = dayjs(value.value).format("YYYY-MM-DD");
+    showDatePickerDialog.value = false;
+    getList();
+  };
+
+  // 鑾峰彇鍒楄〃鏁版嵁
+  const getList = () => {
+    handleSearch();
+  };
+
+  // 鍒濆鍖栨椂闂存Ы锛堜互鍗婂皬鏃朵负闂撮殧锛屼粠8:00鍒�18:00锛�
+  const initTimeSlots = () => {
+    const slots = [];
+    for (let hour = 8; hour < 18; hour++) {
+      // 姣忎釜灏忔椂娣诲姞涓や釜鏃堕棿娈碉細鏁寸偣鍜屽崐鐐�
+      slots.push({
+        label: `${hour.toString().padStart(2, "0")}:00`,
+        value: `${hour.toString().padStart(2, "0")}:00`,
+      });
+
+      if (hour < 17) {
+        // 鍒�17:30涓烘
+        slots.push({
+          label: `${hour.toString().padStart(2, "0")}:30`,
+          value: `${hour.toString().padStart(2, "0")}:30`,
+        });
+      }
+    }
+    timeSlots.value = slots;
+    console.log(timeSlots.value, "timeSlots.value");
+  };
+
+  // 鐢熸垚浼氳瀹ょ殑鏃堕棿鍗曞厓鏍�
+  const generateMeetingCells = room => {
+    const cells = [];
+    const meetings = room.meetings || [];
+    const occupiedSlots = new Set();
+
+    // 澶勭悊姣忎釜浼氳
+    for (const meeting of meetings) {
+      const startIdx = timeSlots.value.findIndex(
+        slot => slot.value === meeting.startTime
+      );
+      let endIdx = timeSlots.value.findIndex(
+        slot => slot.value === meeting.endTime
+      );
+      if (endIdx === -1) {
+        endIdx = timeSlots.value.length;
+      }
+
+      if (startIdx !== -1) {
+        // 鏍囪琚崰鐢ㄧ殑鏃堕棿娈�
+        for (let i = startIdx; i < endIdx; i++) {
+          if (timeSlots.value[i]) {
+            occupiedSlots.add(timeSlots.value[i].value);
+          }
+        }
+
+        // 鍒涘缓浼氳鍗曞厓鏍�
+        cells.push({
+          type: "meeting",
+          meeting: meeting,
+          span: endIdx - startIdx,
+          startTime: meeting.startTime,
+          endTime: meeting.endTime,
+        });
+      }
+    }
+
+    // 澶勭悊绌洪棽鏃堕棿娈�
+    for (let i = 0; i < timeSlots.value.length; i++) {
+      const slot = timeSlots.value[i];
+      if (!occupiedSlots.has(slot.value)) {
+        // 鏌ユ壘杩炵画鐨勭┖闂叉椂闂存
+        let span = 1;
+        while (
+          i + span < timeSlots.value.length &&
+          !occupiedSlots.has(timeSlots.value[i + span].value)
+        ) {
+          occupiedSlots.add(timeSlots.value[i + span].value);
+          span++;
+        }
+
+        cells.push({
+          type: "free",
+          span: span,
+          time: slot.value,
+        });
+      }
+    }
+
+    // 鎸夋椂闂存帓搴�
+    cells.sort((a, b) => {
+      const timeA = a.startTime || a.time;
+      const timeB = b.startTime || b.time;
+      return (
+        timeSlots.value.findIndex(s => s.value === timeA) -
+        timeSlots.value.findIndex(s => s.value === timeB)
+      );
+    });
+
+    return cells;
+  };
+
+  // 鏌ョ湅浼氳璇︽儏
+  const viewMeetingDetails = cell => {
+    console.log(cell, "cell");
+
+    if (cell && cell.type === "meeting") {
+      currentMeeting.value = cell.meeting;
+      detailDialogVisible.value = true;
+    } else {
+      uni.showToast({
+        title: "璇ユ椂闂存浼氳瀹ょ┖闂�",
+        icon: "info",
+      });
+    }
+  };
+
+  // 鏌ヨ鎸夐挳鎿嶄綔
+  const handleSearch = async () => {
+    loading.value = true;
+    try {
+      const resp = await getMeetingUseList({ ...queryForm });
+      roomUsage.value = resp.data;
+    } catch (error) {
+      uni.showToast({
+        title: "鑾峰彇鏁版嵁澶辫触",
+        icon: "error",
+      });
+    } finally {
+      loading.value = false;
+    }
+  };
+
+  // 閲嶇疆鎼滅储琛ㄥ崟
+  const resetSearch = () => {
+    queryForm.meetingDate = dayjs().format("YYYY-MM-DD");
+  };
+
+  // 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
+  onMounted(() => {
+    // 鍒濆鍖栨椂闂存Ы
+    initTimeSlots();
+
+    // 榛樿鏌ヨ浠婂ぉ鐨勬暟鎹�
+    handleSearch();
+  });
+</script>
+
+<style scoped lang="scss">
+  @import "../../../styles/sales-common.scss";
+  .meeting-list {
+    min-height: 100vh;
+    background: #f8f9fa;
+    padding: 16rpx;
+  }
+
+  .search-section {
+    background: #fff;
+    padding: 16rpx;
+    border-radius: 8rpx;
+    margin-bottom: 16rpx;
+    box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
+  }
+
+  .search-bar {
+    display: flex;
+    align-items: center;
+    gap: 12rpx;
+  }
+
+  .search-input {
+    flex: 1;
+  }
+
+  .filter-button {
+    padding: 12rpx 16rpx;
+    background: #f5f7fa;
+    border-radius: 4rpx;
+  }
+
+  .form-buttons {
+    display: flex;
+    gap: 12rpx;
+    margin-top: 16rpx;
+    justify-content: center;
+  }
+
+  .table-container {
+    margin-top: 16rpx;
+    overflow-x: auto;
+  }
+
+  .time-table {
+    width: 100%;
+  }
+
+  .table-header {
+    display: flex;
+    border: 1rpx solid #e4e7ed;
+    background: #f5f7fa;
+  }
+
+  .header-cell {
+    padding: 12rpx 8rpx;
+    text-align: center;
+    font-weight: bold;
+    border-right: 1rpx solid #e4e7ed;
+  }
+
+  .room-header {
+    width: 120rpx;
+    flex-shrink: 0;
+  }
+
+  .time-header {
+    width: 120rpx;
+    flex-shrink: 0;
+  }
+
+  .table-body {
+    border: 1rpx solid #e4e7ed;
+    border-top: none;
+  }
+
+  .table-row {
+    display: flex;
+    border-top: 1rpx solid #e4e7ed;
+  }
+
+  .table-row:first-child {
+    border-top: none;
+  }
+
+  .cell {
+    padding: 16rpx 8rpx;
+    text-align: center;
+    border-right: 1rpx solid #e4e7ed;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    word-break: break-word;
+    line-height: 1.2;
+  }
+
+  .room-cell {
+    width: 120rpx;
+    font-weight: bold;
+    flex-shrink: 0;
+    background: #f9fafc;
+  }
+
+  .cells-container {
+    display: flex;
+  }
+
+  .content-cell {
+    min-height: 120rpx;
+    cursor: pointer;
+    transition: all 0.3s;
+    flex-direction: column;
+    justify-content: center;
+  }
+
+  .content-cell:active {
+    opacity: 0.8;
+  }
+
+  .free {
+    color: #f56c6c;
+  }
+
+  .meeting {
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+  }
+
+  .status-1 {
+    background-color: #fef0f0;
+    color: #d14646;
+  }
+
+  .status-0 {
+    background-color: #ecf5ff;
+    color: #409eff;
+  }
+
+  .meeting-content {
+    width: 100%;
+  }
+
+  .meeting-title {
+    font-weight: bold;
+    margin-bottom: 8rpx;
+    font-size: 24rpx;
+  }
+
+  .meeting-time {
+    font-size: 20rpx;
+    opacity: 0.8;
+  }
+
+  .free-content {
+    color: #909399;
+  }
+
+  /* 瀵硅瘽妗嗘牱寮� */
+  .dialog-content {
+    padding: 24rpx;
+  }
+
+  .dialog-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 24rpx;
+    padding-bottom: 16rpx;
+    border-bottom: 1rpx solid #e4e7ed;
+  }
+
+  .dialog-title {
+    font-size: 32rpx;
+    font-weight: bold;
+    color: #303133;
+  }
+
+  .close-icon {
+    font-size: 32rpx;
+    color: #909399;
+  }
+
+  .dialog-body {
+    margin-bottom: 24rpx;
+  }
+
+  .detail-item {
+    display: flex;
+    margin-bottom: 16rpx;
+    padding: 8rpx 0;
+    border-bottom: 1rpx solid #f0f0f0;
+  }
+
+  .detail-label {
+    width: 140rpx;
+    font-weight: bold;
+    color: #606266;
+  }
+
+  .detail-value {
+    flex: 1;
+    color: #303133;
+  }
+
+  .dialog-footer {
+    display: flex;
+    justify-content: center;
+    margin-top: 16rpx;
+  }
+</style>
\ No newline at end of file
diff --git a/src/pages/managementMeetings/meetingSettings/detail.vue b/src/pages/managementMeetings/meetingSettings/detail.vue
new file mode 100644
index 0000000..8e83099
--- /dev/null
+++ b/src/pages/managementMeetings/meetingSettings/detail.vue
@@ -0,0 +1,344 @@
+<template>
+  <view class="client-visit-detail">
+    <PageHeader title="浼氳瀹よ鎯�"
+                @back="goBack" />
+    <u-form ref="formRef"
+            label-width="90">
+      <!-- 瀹㈡埛淇℃伅 -->
+      <u-cell-group title="浼氳瀹や俊鎭�">
+        <u-form-item label="浼氳瀹ゅ悕绉�"
+                     prop="name"
+                     required
+                     border-bottom>
+          <u-input v-model="form.name"
+                   placeholder="璇疯緭鍏ヤ細璁鍚嶇О" />
+        </u-form-item>
+        <u-form-item label="浣嶇疆"
+                     required
+                     prop="location"
+                     border-bottom>
+          <u-input v-model="form.location"
+                   placeholder="璇疯緭鍏ヤ綅缃�" />
+        </u-form-item>
+        <u-form-item label="瀹圭撼浜烘暟"
+                     required
+                     prop="capacity"
+                     border-bottom>
+          <u-input v-model="form.capacity"
+                   placeholder="璇疯緭鍏ュ绾充汉鏁�" />
+        </u-form-item>
+        <u-form-item label="璁惧閰嶇疆"
+                     prop="equipment"
+                     border-bottom>
+          <u-input v-model="form.equipment"
+                   readonly
+                   placeholder="璇烽�夋嫨璁惧閰嶇疆"
+                   @click="showEquipmentSheet = true" />
+          <template #right>
+            <up-icon name="arrow-right"
+                     @click="openEquipmentSheet"></up-icon>
+          </template>
+        </u-form-item>
+        <u-form-item label="鐘舵��"
+                     prop="status"
+                     border-bottom>
+          <u-input v-model="statusname"
+                   readonly
+                   placeholder="璇烽�夋嫨鐘舵��"
+                   @click="showStatusSheet = true" />
+          <template #right>
+            <up-icon name="arrow-right"
+                     @click="showStatusSheet = true"></up-icon>
+          </template>
+        </u-form-item>
+        <u-form-item label="澶囨敞"
+                     prop="remark"
+                     border-bottom>
+          <u-input v-model="form.remark"
+                   placeholder="璇疯緭鍏ュ娉�" />
+        </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="handleSubmit"
+                  :loading="loading">淇濆瓨</u-button>
+      </view>
+    </u-form>
+    <!-- 璁惧閰嶇疆閫夋嫨鍣� -->
+    <u-popup :show="showEquipmentSheet"
+             mode="bottom"
+             @close="showEquipmentSheet = false"
+             height="200px">
+      <view class="popup-content">
+        <view class="popup-body">
+          <u-checkbox-group v-model="form.equipment"
+                            @change="handleEquipmentChange"
+                            icon-placement="right"
+                            placement="row">
+            <view style="width:100%;padding:10px;margin-top:20px;">
+              <u-checkbox v-for="option in equipmentOptions"
+                          :key="option.value"
+                          :name="option.value"
+                          :label="option.name"
+                          class="checkbox-item"></u-checkbox>
+            </view>
+          </u-checkbox-group>
+        </view>
+      </view>
+    </u-popup>
+    <!-- 鐘舵�侀�夋嫨鍣� -->
+    <up-action-sheet :show="showStatusSheet"
+                     :actions="statusOptions"
+                     @select="onStatusSelect"
+                     @close="showStatusSheet = false" />
+  </view>
+</template>
+
+<script setup>
+  // 鏇挎崲 toast 鏂规硶
+  defineOptions({ name: "meeting-settings-detail" });
+  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 { saveRoom } from "@/api/managementMeetings/meetingSettings";
+
+  const userStore = useUserStore();
+
+  // 琛ㄥ崟鏁版嵁
+  const form = ref({
+    name: "",
+    location: "",
+    capacity: "",
+    equipment: [],
+    status: "",
+    remark: "",
+  });
+  const equipmentOptions = ref([
+    { value: "鎶曞奖浠�", name: "鎶曞奖浠�" },
+    { value: "鐢佃", name: "鐢佃" },
+    { value: "闊冲搷", name: "闊冲搷" },
+    { value: "鐢佃瘽", name: "鐢佃瘽" },
+    { value: "瑙嗛浼氳绯荤粺", name: "瑙嗛浼氳绯荤粺" },
+    { value: "鐧芥澘", name: "鐧芥澘" },
+    { value: "鍐欏瓧鏉�", name: "鍐欏瓧鏉�" },
+    { value: "鏃犵嚎缃戠粶", name: "鏃犵嚎缃戠粶" },
+  ]);
+  const statusOptions = ref([
+    { value: "1", name: "鍚敤" },
+    { value: "0", 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.status = action.value;
+    statusname.value = action.name;
+    showStatusSheet.value = false;
+  };
+  // 璁惧閰嶇疆閫夋嫨
+  const handleEquipmentChange = val => {
+    form.value.equipment = val;
+    console.log("form.value.equipment", form.value.equipment);
+  };
+  // 鎻愪氦琛ㄥ崟
+  const handleSubmit = async () => {
+    if (!form.value.name) {
+      showToast("璇疯緭鍏ヤ細璁鍚嶇О");
+      return;
+    }
+
+    if (!form.value.location) {
+      showToast("璇疯緭鍏ヤ綅缃�");
+      return;
+    }
+
+    if (!form.value.capacity) {
+      showToast("璇疯緭鍏ュ绾充汉鏁�");
+      return;
+    }
+    try {
+      loading.value = true;
+      form.value.equipment = form.value.equipment.join(",");
+      form.value.status = Number(form.value.status);
+      form.value.capacity = Number(form.value.capacity);
+      // 浣跨敤瀹夊叏娴呮嫹璐濓紝閬垮厤瀵硅薄灞曞紑鍦ㄦ煇浜涜繍琛屾椂鎶涢敊
+      console.log("form.value", form.value);
+      saveRoom(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");
+    }
+  };
+
+  onMounted(() => {
+    initPageData();
+  });
+</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/meetingSettings/index.vue b/src/pages/managementMeetings/meetingSettings/index.vue
new file mode 100644
index 0000000..f55c0d7
--- /dev/null
+++ b/src/pages/managementMeetings/meetingSettings/index.vue
@@ -0,0 +1,244 @@
+<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.name || '-' }}</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.name || '-' }}</text>
+            </view> -->
+            <view class="detail-row">
+              <text class="detail-label">浣嶇疆</text>
+              <text class="detail-value">{{ item.location || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">瀹圭撼浜烘暟</text>
+              <text class="detail-value">{{ item.capacity || '-' }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">璁惧閰嶇疆</text>
+              <text class="detail-value">{{ item.equipment }}</text>
+            </view>
+            <view class="detail-row">
+              <text class="detail-label">鐘舵��</text>
+              <text class="detail-value"
+                    :class="{'status-enabled': item.status == 1, 'status-disabled': item.status == 0}">{{ item.status == 1 ? '鍚敤' : '绂佺敤' }}</text>
+            </view>
+          </view>
+          <!-- 鎸夐挳鍖哄煙 -->
+          <view class="action-buttons">
+            <u-button type="primary"
+                      size="small"
+                      class="action-btn"
+                      @click="viewDetail(item)">
+              缂栬緫
+            </u-button>
+            <u-button type="error"
+                      size="small"
+                      class="action-btn"
+                      @click="confirmDelete(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 } from "vue";
+  import { onShow } from "@dcloudio/uni-app";
+  import PageHeader from "@/components/PageHeader.vue";
+  import {
+    getMeetingRoomList,
+    delRoom,
+  } from "@/api/managementMeetings/meetingSettings";
+  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 name = ref("");
+
+  // 鎷滆璁板綍鏁版嵁
+  const visitList = ref([]);
+
+  // 杩斿洖涓婁竴椤�
+  const goBack = () => {
+    uni.navigateBack();
+  };
+  const confirmDelete = item => {
+    uni.showModal({
+      title: "纭鍒犻櫎",
+      content: `鏄惁纭鍒犻櫎浼氳瀹� ${item.name}锛焋,
+      success: res => {
+        if (res.confirm) {
+          delRoom(item.id)
+            .then(() => {
+              showToast("鍒犻櫎鎴愬姛");
+              getList();
+            })
+            .catch(() => {
+              showToast("鍒犻櫎澶辫触");
+            });
+        }
+      },
+    });
+  };
+  // 鏌ヨ鍒楄〃
+  const getList = () => {
+    showLoadingToast("鍔犺浇涓�...");
+    const params = {
+      current: -1,
+      size: -1,
+      name: name.value,
+    };
+    getMeetingRoomList(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/meetingSettings/detail",
+    });
+  };
+
+  // 缂栬緫
+  const viewDetail = item => {
+    uni.setStorageSync("meetingRoom", item);
+    uni.navigateTo({
+      url: "/pages/managementMeetings/meetingSettings/detail",
+    });
+  };
+
+  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); // 淇濇寔椤甸潰鐗规湁鐨勯槾褰辨晥鏋�
+  }
+</style>
+
diff --git a/src/pages/managementMeetings/meetingSettings/view.vue b/src/pages/managementMeetings/meetingSettings/view.vue
new file mode 100644
index 0000000..f56ddb2
--- /dev/null
+++ b/src/pages/managementMeetings/meetingSettings/view.vue
@@ -0,0 +1,178 @@
+<template>
+  <view class="client-visit-detail">
+    <PageHeader title="瀹㈡埛鎷滆璇︽儏" @back="goBack" />
+    
+    <!-- 鍐呭瀹瑰櫒 -->
+    <view class="content-container">
+      <!-- 瀹㈡埛淇℃伅 -->
+      <view class="section">
+        <view class="section-title">瀹㈡埛淇℃伅</view>
+        <view class="info-item">
+          <text class="info-label">瀹㈡埛鍚嶇О</text>
+          <text class="info-value">{{ form.customerName || '-' }}</text>
+        </view>
+        <view class="info-item">
+          <text class="info-label">鑱旂郴浜�</text>
+          <text class="info-value">{{ form.contact || '-' }}</text>
+        </view>
+        <view class="info-item">
+          <text class="info-label">鑱旂郴鐢佃瘽</text>
+          <text class="info-value">{{ form.contactPhone || '-' }}</text>
+        </view>
+      </view>
+
+      <!-- 鎷滆淇℃伅 -->
+      <view class="section">
+        <view class="section-title">鎷滆淇℃伅</view>
+        <view class="info-item">
+          <text class="info-label">鎷滆鐩殑</text>
+          <text class="info-value">{{ form.purposeVisit || '-' }}</text>
+        </view>
+        <view class="info-item">
+          <text class="info-label">鎷滆鏃堕棿</text>
+          <text class="info-value">{{ form.purposeDate || '-' }}</text>
+        </view>
+        <view class="info-item">
+          <text class="info-label">鎷滆鍦扮偣</text>
+          <text class="info-value multi-line">{{ form.visitAddress || '-' }}</text>
+        </view>
+        <view class="info-item">
+          <text class="info-label">鎷滆浜�</text>
+          <text class="info-value">{{ form.visitingPeople || '-' }}</text>
+        </view>
+        <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>
+        <view class="info-item remark-item">
+          <text class="info-label">澶囨敞</text>
+          <text class="info-value multi-line">{{ form.remark }}</text>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script setup>
+// 鏇挎崲 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"
+
+const userStore = useUserStore()
+
+// 琛ㄥ崟鏁版嵁
+const form = ref({
+  customerName: '',
+  contact: '',
+  contactPhone: '',
+  visitingPeople: '',
+  purposeVisit: '',
+  purposeDate: '',
+  visitAddress: '',
+  latitude: '',
+  longitude: '',
+  locationAddress: '',
+  remark: ''
+})
+
+// 杩斿洖涓婁竴椤�
+const goBack = () => {
+  // 杩斿洖鏃舵竻闄ゆ湰鍦板瓨鍌ㄧ殑ID
+  uni.removeStorageSync('clientVisit')
+  uni.navigateBack()
+}
+
+// 鍒濆鍖栭〉闈㈡暟鎹�
+const initPageData = () => {
+  // 浠庢湰鍦板瓨鍌ㄨ幏鍙栨嫓璁胯褰曡鎯�
+  const row = uni.getStorageSync('clientVisit')
+  if (row) {
+    form.value = { ...row }
+  } else {
+    showToast('鏆傛棤鎷滆璁板綍鏁版嵁')
+  }
+}
+
+onMounted(() => {
+  initPageData()
+})
+</script>
+
+<style scoped lang="scss">
+@import '@/static/scss/form-common.scss';
+
+.client-visit-detail {
+  min-height: 100vh;
+  background-color: #f8f9fa;
+}
+
+.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-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:last-child {
+  border-bottom: none;
+}
+
+.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;
+}
+
+.multi-line {
+  text-align: left;
+  word-break: break-all;
+  line-height: 1.6;
+}
+
+.remark-item {
+  padding-bottom: 16px;
+}
+</style>
\ No newline at end of file

--
Gitblit v1.9.3