From 42a1a434f77154746038c476ef70ca9be0b8e4e0 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期一, 19 一月 2026 18:02:46 +0800
Subject: [PATCH] fix: 完成资金管理,财务对账
---
src/views/collaborativeApproval/notificationManagement/meetIndex/index.vue | 363 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 363 insertions(+), 0 deletions(-)
diff --git a/src/views/collaborativeApproval/notificationManagement/meetIndex/index.vue b/src/views/collaborativeApproval/notificationManagement/meetIndex/index.vue
new file mode 100644
index 0000000..9b5325f
--- /dev/null
+++ b/src/views/collaborativeApproval/notificationManagement/meetIndex/index.vue
@@ -0,0 +1,363 @@
+<template>
+ <div>
+ <el-form :model="queryForm" label-width="80px" inline>
+ <el-form-item label="鏌ヨ鏃ユ湡">
+ <el-date-picker
+ v-model="queryForm.meetingDate"
+ type="date"
+ placeholder="璇烽�夋嫨鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ :clearable="false"
+ />
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary" @click="handleSearch">鏌ヨ</el-button>
+ <el-button @click="resetSearch">閲嶇疆</el-button>
+ </el-form-item>
+ </el-form>
+
+ <!-- 浼氳瀹や娇鐢ㄦ儏鍐� -->
+ <el-card class="table-container" :loading="loading">
+ <div class="time-table">
+ <!-- 琛ㄥご -->
+ <div class="table-header">
+ <div class="header-cell room-header">浼氳瀹�</div>
+ <div
+ v-for="timeSlot in timeSlots"
+ :key="timeSlot.value"
+ class="header-cell time-header"
+ >
+ {{ timeSlot.label }}
+ </div>
+ </div>
+
+ <!-- 琛ㄦ牸鍐呭 -->
+ <div class="table-body">
+ <div
+ v-for="room in roomUsage"
+ :key="room.id"
+ class="table-row"
+ >
+ <div class="cell room-cell">{{ room.name }}</div>
+ <div class="cells-container">
+ <template v-for="(cell, index) in generateMeetingCells(room)" :key="index">
+ <div
+ class="cell content-cell"
+ :class="[cell.type, `status-${cell.meeting?.status || '0'}`]"
+ :style="{ flex: cell.span-0.2 }"
+ @click="viewMeetingDetails(cell)"
+ >
+ <div v-if="cell.type === 'meeting'" class="meeting-content">
+ <div class="meeting-title">{{ cell.meeting.title }}</div>
+ <div class="meeting-time">{{ cell.startTime }}-{{ cell.endTime }}</div>
+ </div>
+ <div v-else class="free-content">
+ 绌洪棽
+ </div>
+ </div>
+ </template>
+ </div>
+ </div>
+ </div>
+ </div>
+ </el-card>
+
+ <!-- 浼氳璇︽儏瀵硅瘽妗� -->
+ <el-dialog
+ title="浼氳璇︽儏"
+ v-model="detailDialogVisible"
+ width="800px"
+ >
+ <div v-if="currentMeeting">
+ <el-descriptions :column="1" border>
+ <el-descriptions-item label="浼氳涓婚">{{ currentMeeting.title }}</el-descriptions-item>
+ <el-descriptions-item label="浼氳瀹�">{{ currentMeeting.room }}</el-descriptions-item>
+ <el-descriptions-item label="浼氳鏃堕棿">{{ currentMeeting.time }}</el-descriptions-item>
+ <el-descriptions-item label="涓绘寔浜�">{{ currentMeeting.host }}</el-descriptions-item>
+ <el-descriptions-item label="鍙備細浜烘暟">{{ currentMeeting.participants }}浜�</el-descriptions-item>
+ <el-descriptions-item label="浼氳璇存槑">{{ currentMeeting.description }}</el-descriptions-item>
+ </el-descriptions>
+ </div>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button @click="detailDialogVisible = false">鍏� 闂�</el-button>
+ </div>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+import {ref, reactive, onMounted} from 'vue'
+import {ElMessage} from 'element-plus'
+import {getMeetingUseList} from "@/api/collaborativeApproval/meeting.js"
+import dayjs from "dayjs";
+
+// 鏌ヨ琛ㄥ崟
+const queryForm = reactive({
+ meetingDate: dayjs().format('YYYY-MM-DD')
+})
+let loading = ref(false)
+// 鏃堕棿娈碉紙浠ュ崐灏忔椂涓洪棿闅旓級
+const timeSlots = ref([])
+
+// 浼氳瀹や娇鐢ㄦ儏鍐�
+const roomUsage = ref([])
+
+// 褰撳墠鏌ョ湅鐨勪細璁�
+const currentMeeting = ref(null)
+
+// 鏄惁鏄剧ず璇︽儏瀵硅瘽妗�
+const detailDialogVisible = ref(false)
+
+// 鍒濆鍖栨椂闂存Ы锛堜互鍗婂皬鏃朵负闂撮殧锛屼粠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 < 18) { // 鍒�17:30涓烘
+ slots.push({
+ label: `${hour.toString().padStart(2, '0')}:30`,
+ value: `${hour.toString().padStart(2, '0')}:30`
+ })
+ }
+ }
+ timeSlots.value = slots
+}
+
+// 鐢熸垚浼氳瀹ょ殑鏃堕棿鍗曞厓鏍�
+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
+ }
+ console.log('endIdx111', endIdx)
+ if (startIdx !== -1 && endIdx !== -1) {
+ // 鏍囪琚崰鐢ㄧ殑鏃堕棿娈�
+ for (let i = startIdx; i < endIdx; 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)
+ })
+ console.log('cells', cells)
+ return cells
+}
+
+// 鏌ョ湅浼氳璇︽儏
+const viewMeetingDetails = (cell) => {
+ if (cell && cell.type === 'meeting') {
+ currentMeeting.value = cell.meeting
+ detailDialogVisible.value = true
+ } else {
+ ElMessage.info('璇ユ椂闂存浼氳瀹ょ┖闂�')
+ }
+}
+
+// 鏌ヨ鎸夐挳鎿嶄綔
+const handleSearch = async () => {
+ loading.value = true
+ let resp = await getMeetingUseList({...queryForm})
+ roomUsage.value = resp.data
+ loading.value = false
+}
+
+// 閲嶇疆鎼滅储琛ㄥ崟
+const resetSearch = () => {
+ queryForm.date = dayjs().format('YYYY-MM-DD')
+}
+
+// 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
+onMounted(() => {
+ // 鍒濆鍖栨椂闂存Ы
+ initTimeSlots()
+
+ // 榛樿鏌ヨ浠婂ぉ鐨勬暟鎹�
+ const today = new Date()
+ queryForm.date = today.toISOString().split('T')[0]
+ handleSearch()
+})
+</script>
+
+<style scoped>
+.app-container {
+ padding: 20px;
+}
+
+.page-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 20px;
+}
+
+.page-header h2 {
+ margin: 0;
+ color: #303133;
+}
+
+.search-card {
+ margin-bottom: 20px;
+}
+
+.table-container {
+ padding: 0;
+}
+
+.time-table {
+ width: 100%;
+ border-collapse: collapse;
+}
+
+.table-header {
+ display: flex;
+ border: 1px solid;
+}
+
+.table-row {
+ display: flex;
+ border: 1px solid #ebeef5;
+ border-top: none;
+}
+
+.header-cell {
+ padding: 12px 5px;
+ text-align: center;
+ font-weight: bold;
+ border-right: 1px solid;
+ min-height: 20px;
+}
+
+.room-header {
+ width: 120px;
+}
+
+.time-header {
+ flex: 1;
+}
+
+.cell {
+ padding: 15px 5px;
+ text-align: center;
+ border-right: 1px solid;
+ min-height: 20px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ word-break: break-word;
+ line-height: 1.2;
+}
+
+.room-cell {
+ width: 120px;
+ font-weight: bold;
+}
+
+.cells-container {
+ flex: 1;
+ display: flex;
+}
+
+.content-cell {
+ min-height: 60px;
+ cursor: pointer;
+ transition: all 0.3s;
+}
+
+.content-cell:hover {
+ 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: #c7ddc8;
+ color: rgba(230, 162, 60, 0.29);
+}
+
+.meeting-content {
+ width: 100%;
+}
+
+.meeting-title {
+ font-weight: bold;
+ margin-bottom: 5px;
+}
+
+.meeting-time {
+ font-size: 12px;
+}
+
+.free-content {
+ color: #909399;
+}
+
+.dialog-footer {
+ display: flex;
+ justify-content: flex-end;
+ gap: 10px;
+}
+</style>
--
Gitblit v1.9.3