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