This commit is contained in:
Leo_Ding 2025-07-28 09:54:10 +08:00
parent 984194ff7e
commit 0f7a7d4770
6 changed files with 709 additions and 462 deletions

170
components/instruction.vue Normal file
View File

@ -0,0 +1,170 @@
<template>
<!-- pages/meeting-room/guide.wxml -->
<!-- pages/meeting-room/notice.wxml -->
<view class="notice-container">
<view class="notice-title" style="font-size: 16px;font-weight: bold;text-align: center;margin-bottom: 10px;">
近山社区城市青年会客厅使用说明</view>
<view class="notice-section-title">城市青年会客厅</view><br>
<view class="notice-content">
为了能进一步创新社区服务模式更好地利用社区公共资源为民服务为企解忧为共建强基2025年起近山社区将社区党群服务中心二楼"共享空间"升级为社区"城市青年会客厅"以下简称"会客厅"用途使用会客厅位于紫琅人才公寓33号楼二楼面积为368.3功能布局为文化展示区妇女儿童之家党建会议室中心会客厅共享会议室自习室
</view><br>
<view class="notice-section-title">使用须知</view><br>
<view class="notice-content">
第一条会客厅仍实行园区共享机制即会客厅除了平时用于社区日常的功能使用需要之外根据驻辖区单位业主以及社区共建单位的申请需求还可以作为社区共享资源场地免费使用主要用于召开园区单位会议接待来宾培训活动以及举办其他合法活动会客厅由近山社区统一管理负责使用登记与调度设备维护等相关内容
</view><br>
<view class="notice-content">
第二条会客厅实行提前预约制度申请使用会客厅时需填写近山社区城市青年会客厅使用申请表说明申请用途和目的等相关情况如有需要社区协助办理的事项需提前注明以便根据情况做好相关协调安排为避免使用时间段冲突要求各申请人/单位至少提前1天预约重要活动需提前一周预约特殊情况下需要紧急申请使用的应及时向社区提出申请并在使用后进行补办相关手续
</view><br>
<view class="notice-content">
第三条申请单位在使用期间应严格遵守国家法律法规并有完善的安全应急预案严禁使用会客厅开展任何违反法律法规违背社会公序良俗的活动产生的社会负面影响及法律责任由申请使用方负责因申请使用方的安全应急预案不严谨不完善以及现场活动组织不严密等问题造成的安全事故责任由申请使用方负责出现以上问题的取消该预约单位借用人后续使用会客厅的权利并列入社区征信名单
</view><br>
<view class="notice-section-title">注意事项</view><br>
<view class="notice-content">
第一条应在所预约时间内按流程规定使用会客厅申请方应主动与社区联系并重新调整申请使用时间逾期未使用则由社区另作调剂会客厅的使用权
</view><br>
<view class="notice-content">
第二条如预约单位有逾期使用的需求需重新按程序申请若申请逾期的使用时间段内已有其他单位预约使用逾期使用的预约单位不得继续占用会客厅的使用权
</view><br>
<view class="notice-content">
第三条会客厅内的设施设备属于社区的固定资产在作为会客厅使用时由社区专人转交给申请单位临时使用社区专人对接和临时移交申请使用单位申请单位须安排专人负责申请使用期间会客厅内的物资财产的保管与使用由申请使用方负责使用者要爱护会客厅内的公共设施损坏照价赔偿未经社区允许不得擅自将会客厅内的多媒体设备桌椅等物资财产置于会客厅以外范围使用
</view><br>
<view class="notice-content">
第四条会客厅在使用期间应不影响社区正常办公居民正常生活同时保持内部的整洁有序使用者应在使用完毕后对会议室进行复位整理复位桌椅关闭窗户及电器设备等使用单位应安排专人进行检查提醒宾客与会人员带走自己的随身物品若因遗落而丢失或被清理社区概不承责如发现设备故障或公物损坏应及时报至社区由使用方负责维修或照价赔偿
</view><br>
<view class="notice-content">
第五条以上内容的最终解释权归近山社区所有
</view>
<view style="display: flex; align-items: flex-start; color: black; margin-top: 20px;">
<checkbox-group @change="checkboxChange">
<label>
<checkbox :value="isreaded" style="transform:scale(0.7)"/><text style="font-size: 16px;">{{name}}</text>
</label>
</checkbox-group>
</view>
</view>
</template>
<script>
export default {
name: 'instruction',
data() {
return {
checkboxValue1: [],
isreaded: false,
name: '我(单位)已阅读并清楚近山社区城市青年会客厅使用说明中的使用须知和注意事项'
}
},
methods: {
checkboxChange(n) {
console.log('change', n);
if(n.detail.value.length>0){
this.$emit('change',false)
}else{
this.$emit('change',true)
}
}
}
}
</script>
<style scoped>
.notice-container {
height: 600rpx;
width: 600rpx;
color: #666;
font-size: 12px;
line-height: 20px;
overflow-y: scroll;
margin: 20px;
}
.notice-content {
text-indent: 2em;
}
/* pages/meeting-room/guide.wxss */
.container {
padding: 20rpx;
color: #333;
font-size: 28rpx;
line-height: 1.6;
}
.header {
text-align: center;
margin-bottom: 40rpx;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #eee;
}
.title {
font-size: 36rpx;
font-weight: bold;
color: #2c3e50;
}
.section {
margin-bottom: 40rpx;
}
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #2c3e50;
border-left: 8rpx solid #07c160;
padding-left: 20rpx;
margin: 30rpx 0 20rpx;
}
.info-box {
background-color: #f8f9fa;
padding: 20rpx;
border-radius: 10rpx;
margin: 20rpx 0;
}
.info-item {
display: block;
margin-bottom: 10rpx;
}
.rule,
.note {
margin-bottom: 30rpx;
background-color: #f8f9fa;
padding: 20rpx;
border-radius: 10rpx;
}
.rule-title,
.note-title {
font-size: 30rpx;
font-weight: bold;
color: #07c160;
margin-bottom: 15rpx;
}
.footer {
text-align: center;
margin-top: 60rpx;
padding-top: 30rpx;
border-top: 1rpx solid #eee;
color: #7f8c8d;
font-size: 26rpx;
}
.footer view {
display: block;
margin-bottom: 10rpx;
}
</style>

View File

@ -24,8 +24,6 @@
</view> </view>
<image v-if="msg.sender === 'me'" :src="myAvatar" class="avatar"></image> <image v-if="msg.sender === 'me'" :src="myAvatar" class="avatar"></image>
</view> </view>
</scroll-view> </scroll-view>
<!-- 输入区域 --> <!-- 输入区域 -->

View File

@ -63,15 +63,8 @@
<u-icon name="edit-pen" size="34" color="#2979ff"></u-icon> <u-icon name="edit-pen" size="34" color="#2979ff"></u-icon>
<text class="section-title">备注信息</text> <text class="section-title">备注信息</text>
</view> </view>
<u--textarea <u--textarea v-model="remark" placeholder="请输入备注信息(选填)" count maxlength="200" height="120" border="none"
v-model="remark" :customStyle="{background: '#f8f9fa', borderRadius: '12rpx', padding: '20rpx'}"></u--textarea>
placeholder="请输入备注信息(选填)"
count
maxlength="200"
height="120"
border="none"
:customStyle="{background: '#f8f9fa', borderRadius: '12rpx', padding: '20rpx'}"
></u--textarea>
</view> </view>
</view> </view>
@ -120,6 +113,11 @@
formatTime, formatTime,
formatRelativeTime formatRelativeTime
} from '@/utils/timeFormat'; } from '@/utils/timeFormat';
import {
applyType,
usage,
thingTheme
} from '@/utils/dict.js'
export default { export default {
data() { data() {
const now = new Date(); const now = new Date();
@ -181,6 +179,7 @@
onLoad(options) { onLoad(options) {
if (options && options.Id) { if (options && options.Id) {
this.Id = options.Id; this.Id = options.Id;
console.log(applyType.getAll())
console.log("====", this.Id) console.log("====", this.Id)
} }
}, },
@ -310,31 +309,31 @@
}); });
// API // API
post('/api/v1/app_auth/metting-room/order/register',bookingInfo).then((res)=>{ post('/api/v1/app_auth/metting-room/order/register', bookingInfo).then((res) => {
console.log("===res",res) console.log("===res", res)
if (!res || !res.success) { if (!res || !res.success) {
throw new Error('会议室预定失败'); throw new Error('会议室预定失败');
} }
uni.showToast({ uni.showToast({
title: '会议室预定成功!', title: '会议室预定成功!',
icon: 'success' icon: 'success'
}); });
this.remark = null; this.remark = null;
setTimeout(()=>{ setTimeout(() => {
uni.navigateTo({ uni.navigateTo({
url: `/pages/meetingList/index`, url: `/pages/meetingList/index`,
success: () => { success: () => {
console.log('导航成功ID:', id); console.log('导航成功ID:', id);
}, },
fail: (err) => { fail: (err) => {
console.error('导航失败:', err); console.error('导航失败:', err);
uni.showToast({ uni.showToast({
title: '打开详情页失败', title: '打开详情页失败',
icon: 'none' icon: 'none'
}); });
} }
}); });
},4000) }, 4000)
}) })
@ -348,7 +347,8 @@
<style lang="scss" scoped> <style lang="scss" scoped>
.meeting-room-detail { .meeting-room-detail {
padding: 20rpx; padding: 20rpx;
padding-bottom: 140rpx; /* 增大底部空间 */ padding-bottom: 140rpx;
/* 增大底部空间 */
background-color: #f5f7fa; background-color: #f5f7fa;
} }
@ -535,7 +535,8 @@
box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.08); box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.08);
.u-button { .u-button {
height: 88rpx; /* 增大高度 */ height: 88rpx;
/* 增大高度 */
font-size: 32rpx; font-size: 32rpx;
font-weight: 500; font-weight: 500;
} }

View File

@ -7,10 +7,11 @@
<!-- 会议室列表 --> <!-- 会议室列表 -->
<view class="room-list" v-if="currentTab === 0"> <view class="room-list" v-if="currentTab === 0">
<view v-if="meetingRoomList.length === 0" class="empty-container"> <view v-if="meetingRoomList.length === 0" class="empty-container">
<text>暂无会议室数据 ({{ meetingRoomList }})</text> <text>暂无会议室数据 ({{ meetingRoomList }})</text>
</view> </view>
<view class="room-item" v-for="(item, index) in meetingRoomList" :key="index" @click="goDetail(item.roomInfo || item)"> <view class="room-item" v-for="(item, index) in meetingRoomList" :key="index"
<image class="room-img" :src="`${IMAGE_BASE_URL}`+item.imgs[0]"> @click="goDetail(item.roomInfo || item)">
<image class="room-img" :src="`${IMAGE_BASE_URL}`+item.imgs[0]">
</image> </image>
<view class="room-info"> <view class="room-info">
<view class="room-header"> <view class="room-header">
@ -68,20 +69,25 @@
</view> </view>
<view class="order-actions"> <view class="order-actions">
<u-button type="primary" plain <u-button type="primary" plain @click="goDetail(item.roomInfo || item)">查看详情</u-button>
@click="goDetail(item.roomInfo || item)">查看详情</u-button> <u-button type="error" plain v-if="item.status === 0" @click="cancelOrder(item.id)">
<u-button type="error" plain v-if="item.status === 0" @click="cancelOrder(item.id)">
取消预约 取消预约
</u-button> </u-button>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<view v-else class="loading-container"> <view v-else class="loading-container">
<u-loading-icon mode="circle" size="36"></u-loading-icon> <u-loading-icon mode="circle" size="36"></u-loading-icon>
<text class="loading-text">加载会议室信息中...</text> <text class="loading-text">加载会议室信息中...</text>
</view> </view>
<u-popup :show="show" mode="center" :round="10">
<instructionVue @change='readChange'/>
<u-button type="primary" text="我已知晓" :disabled="hasReaded" @click="show=false"></u-button>
</u-popup>
</view> </view>
</template> </template>
@ -98,11 +104,34 @@
formatTime, formatTime,
formatRelativeTime formatRelativeTime
} from '@/utils/timeFormat'; } from '@/utils/timeFormat';
import instructionVue from '../../components/instruction.vue';
export default { export default {
components: {
instructionVue
},
data() { data() {
return { return {
hasReaded:true,
checkboxValue1: [],
//
checkboxList1: [{
name: '苹果',
disabled: false
},
{
name: '香蕉',
disabled: false
},
{
name: '橙子',
disabled: true
}
],
IMAGE_BASE_URL, IMAGE_BASE_URL,
tabsReady: false, tabsReady: false,
show: true,
title: '使用说明',
content: '',
tabList: [{ tabList: [{
name: '共享空间' name: '共享空间'
}, },
@ -116,7 +145,7 @@
}; };
}, },
onLoad() { onLoad() {
this.getList(); this.getList();
// this.fetchMeetingRooms().then(() => { // this.fetchMeetingRooms().then(() => {
// this.$nextTick(() => { // this.$nextTick(() => {
// this.tabsReady = true; // this.tabsReady = true;
@ -127,18 +156,20 @@
// this.getList(); // this.getList();
// }, // },
computed: { computed: {
formattedOrderList() { formattedOrderList() {
return this.orderList.map(item => ({ return this.orderList.map(item => ({
...item, ...item,
roomTitle: item.roomInfo ? item.roomInfo.title : '会议室', roomTitle: item.roomInfo ? item.roomInfo.title : '会议室',
hasImages: item.roomInfo && item.roomInfo.imgs && item.roomInfo.imgs.length > 0, hasImages: item.roomInfo && item.roomInfo.imgs && item.roomInfo.imgs.length > 0,
firstImage: item.roomInfo && item.roomInfo.imgs && item.roomInfo.imgs[0] ? firstImage: item.roomInfo && item.roomInfo.imgs && item.roomInfo.imgs[0] ?
`${IMAGE_BASE_URL}${item.roomInfo.imgs[0]}` : '' `${IMAGE_BASE_URL}${item.roomInfo.imgs[0]}` : ''
})) }))
} }
}, },
methods: { methods: {
readChange(flag){
this.hasReaded=flag
},
handleTabChange(index) { handleTabChange(index) {
this.currentTab = index.index; this.currentTab = index.index;
if (index.index == 1) { if (index.index == 1) {
@ -333,7 +364,7 @@
.room-item { .room-item {
display: flex; display: flex;
margin-bottom: 40rpx; margin-bottom: 30rpx;
border-radius: $card-radius; border-radius: $card-radius;
overflow: hidden; overflow: hidden;
background-color: #fff; background-color: #fff;
@ -472,7 +503,8 @@
margin-bottom: 20rpx; margin-bottom: 20rpx;
font-size: 28rpx; font-size: 28rpx;
color: $sub-text-color; color: $sub-text-color;
text{
text {
padding-left: 30rpx; padding-left: 30rpx;
} }
@ -585,7 +617,8 @@
color: #07c160; color: #07c160;
} }
&.cancelled, &.rejected { &.cancelled,
&.rejected {
background-color: rgba(#ee0a24, 0.1); background-color: rgba(#ee0a24, 0.1);
color: #ee0a24; color: #ee0a24;
} }

19
utils/dict.js Normal file
View File

@ -0,0 +1,19 @@
import { dictManage } from "./dictClass"
//申请类型
export const applyType=new dictManage([
{value:1,name:'单位申请'},
{value:2,name:'个人申请'},
])
//使用情况
export const usage=new dictManage([
{value:1,name:'已复位'},
{value:2,name:'设置设备需维修'},
{value:1,name:'设施设备需照价赔偿'}
])
//事由主题
export const thingTheme=new dictManage([
{value:1,name:'开会'},
{value:2,name:'学术报告'},
{value:3,name:'活动'},
{value:4,name:'其他'}
])

26
utils/dictClass.js Normal file
View File

@ -0,0 +1,26 @@
export class dictManage {
constructor(data) {
this.data = data
this.valueMap = new Map(data.map(item => [item.value, item.name]))
this.nameMap = new Map(data.map(item => [item.name, item.value]))
}
getAll() {
return this.data
}
getValue(name) {
return this.nameMap.get(name) || ''
}
getName(value) {
return this.valueMap.get(value) || ''
}
// 获取所有value的数组
getValues() {
return Array.from(this.valueMap.keys());
}
// 获取所有name的数组
getNames() {
return Array.from(this.valueMap.values());
}
}