diff --git a/pages/meetingDetail/index.vue b/pages/meetingDetail/index.vue index 2724901..3d4161a 100644 --- a/pages/meetingDetail/index.vue +++ b/pages/meetingDetail/index.vue @@ -106,7 +106,29 @@ 借用时间 - + + + 日期 + {{ borrowTimeData }} + + + + + + 开始 + + {{ startTime }} + + + + + 结束 + + {{ endTime }} + + + + 开始 @@ -145,7 +167,7 @@ - - + 立即预订 - + - - - + + + + @@ -203,7 +222,7 @@ - @@ -230,8 +249,8 @@ import gxsign from '../../components/sign/sign.vue'; import gxUpload from '../../components/gx-upload.vue'; // import processImage from '../../components/process-image.vue' - import instructionVue from '../../components/instruction.vue'; - + import instructionVue from '../../components/instruction.vue'; + export default { components: { // processImage, @@ -256,21 +275,76 @@ if (endHours >= 24) endHours = 0; return { + noIsSelfStudy:false, + pickerType: 1, + borrowTimeData: '', + borrowTimeShow: false, + borrowTime: Number(new Date()), companyName: '', - readShow:false, - hasReaded:true, - signUrl:'', - signShow:false, + startTimeColumns: [ + ['08', '09', '10', '11', '13', '14', '15', '16', '17'], + ['00', '30'] + ], + readShow: false, + hasReaded: true, + signUrl: '', + signShow: false, applyRules: { - userPhone: '申请人手机号', - userName: '申请人姓名', - userCardId: '申请人身份证号', - userAddress: '申请人地址', - concatName: '负责人姓名', - concatPhone: '负责人电话', - companyName: '公司名称', - startTime: '开始时间', - endTime: '结束时间' + userPhone: { + name: '申请人手机号', + reg: /^1[3-9]\d{9}$/, + errMsg: '请输入正确的手机号码格式' + }, + userName: { + name: '申请人姓名', + reg: /^.+$/, + errMsg: '申请人姓名不能为空' + }, + userCardId: { + name: '申请人身份证号', + reg: /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/, + errMsg: '身份证格式不正确' + }, + userAddress: { + name: '申请人地址', + reg: /^.+$/, + errMsg: '申请人地址不能为空' + }, + concatName: { + name: '负责人姓名', + reg: /^.+$/, + errMsg: '负责人姓名不能为空' + }, + concatPhone: { + name: '负责人电话', + reg: /^1[3-9]\d{9}$/, + errMsg: '请输入正确的手机号码格式' + }, + companyName: { + name: '公司名称', + reg: /^.+$/, + errMsg: '公司名称不能为空' + }, + startTime: { + name: '开始时间', + reg: /^.+$/, + errMsg: '开始时间不能为空' + }, + endTime: { + name: '结束时间', + reg: /^.+$/, + errMsg: '结束时间不能空' + }, + counter: { + name: '申请场次', + reg: /^[1-9]\d*$/, + errMsg: '申请场次不能空且是正整数' + }, + num: { + name: '申请人数', + reg: /^[1-9]\d*$/, + errMsg: '申请人数不能空且是正整数' + }, }, // userName: '谢雨晴', // userPhone: "15189809052", @@ -278,8 +352,8 @@ // userAddress: '江苏省南通市紫琅科技城3号楼', // startTime: `2025-08-11 09:00`, // 默认开始时间 // endTime: `2025-08-11 10:00`, // 默认结束时间 - startTime: '', // 默认开始时间 - endTime: '', // 默认结束时间 + startTime: '', // 默认开始时间 + endTime: '', // 默认结束时间 userName: '', userPhone: "", userCardId: '', @@ -296,7 +370,7 @@ detail: {}, signatureShow: false, isSelfStudy: true, //dateTime,yearmonth - mode: 'datetime', + mode: 'date', precision: null, concatPhone: '', reason: '', @@ -309,7 +383,7 @@ ['个人申请', '单位申请'] ], applyType: 1, //企业1 个人2 - + concatName: '', //联系人姓名 concatPhone: '', //联系人电话 // 时间选择器控制 @@ -319,25 +393,25 @@ // 使用字符串格式的时间 startTimePickerValue: `${year}-${month}-${day}`, endTimePickerValue: ``, - applyInfo:{}, + applyInfo: {}, // 日期相关 // selectedDate: `${year}-${month}-${day}`, // minDate: `${year}-${month}-${day}`, // maxDate: `${year + 1}-12-31`, - selectedDate: `2025-08-11`, // 默认选中8月1日 - minDate: `2025-08-01`, // 最小可选8月1日 - maxDate: `2025-08-31`, // 最大可选8月31日 + selectedDate: `2025-08-11`, // 默认选中8月1日 + minDate: `2025-08-01`, // 最小可选8月1日 + maxDate: `2025-08-31`, // 最大可选8月31日 // 时间相关 // startTime: `2025-08`, // endTime: `2025-08`, // startTimeValue: `${startHours.toString().padStart(2, '0')}:${startMinutes.toString().padStart(2, '0')}`, // endTimeValue: `${endHours.toString().padStart(2, '0')}:${endMinutes.toString().padStart(2, '0')}`, - - startTimeValue: `09:00`, - endTimeValue: `10:00`, - startTimePickerValue: `2025-08-11 09:00`, - endTimePickerValue: `2025-08-11 10:00`, + + startTimeValue: `09:00`, + endTimeValue: `10:00`, + startTimePickerValue: `2025-08-11 09:00`, + endTimePickerValue: `2025-08-11 10:00`, // 新增备注字段 remark: '', @@ -356,68 +430,78 @@ this.Id = options.Id; this.isSelfStudy = JSON.parse(options.isSelfStudy) this.mode = options.isSelfStudy === 'true' ? 'year-month' : 'datetime' - + // 设置默认时间值 if (this.isSelfStudy) { - // 自习室模式,只显示年月 - const now = new Date(); - const year = now.getFullYear(); - const month = (now.getMonth() + 1).toString().padStart(2, '0'); - - this.startTime = `${year}-${month}`; - this.endTime = `${year}-${month}`; - this.startTimePickerValue = this.startTime; - this.endTimePickerValue = this.endTime; + // 自习室模式,只显示年月 + const now = new Date(); + const year = now.getFullYear(); + const month = (now.getMonth() + 1).toString().padStart(2, '0'); + + this.startTime = `${year}-${month}`; + this.endTime = `${year}-${month}`; + this.startTimePickerValue = this.startTime; + this.endTimePickerValue = this.endTime; } else { - // 普通会议室模式,显示完整日期时间 - const now = new Date(); - const year = now.getFullYear(); - const month = (now.getMonth() + 1).toString().padStart(2, '0'); - const day = now.getDate().toString().padStart(2, '0'); - - this.startTime = `${year}-${month}-${day} 09:00`; - this.endTime = `${year}-${month}-${day} 10:00`; - this.startTimePickerValue = this.startTime; - this.endTimePickerValue = this.endTime; + // 普通会议室模式,显示完整日期时间 + const now = new Date(); + const year = now.getFullYear(); + const month = (now.getMonth() + 1).toString().padStart(2, '0'); + const day = now.getDate().toString().padStart(2, '0'); + this.borrowTimeData = `${year}-${month}-${day} ` + this.startTime = `09:00`; + this.endTime = `10:00`; + this.startTimePickerValue = this.startTime; + this.endTimePickerValue = this.endTime; } - + } }, computed: { formattedSelectedDate() { - if (!this.selectedDate) return '请选择日期'; - - if (this.isSelfStudy) { - // 自习室模式,显示年月格式 - const [year, month] = this.selectedDate.split('-'); - return `${year}年${month}月`; - } else { - // 普通会议室模式,显示完整日期 - const date = new Date(this.selectedDate); - const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; - const month = date.getMonth() + 1; - const day = date.getDate(); - const weekday = weekdays[date.getDay()]; - - return `${month}月${day}日 ${weekday}`; - } + if (!this.selectedDate) return '请选择日期'; + + if (this.isSelfStudy) { + // 自习室模式,显示年月格式 + const [year, month] = this.selectedDate.split('-'); + return `${year}年${month}月`; + } else { + // 普通会议室模式,显示完整日期 + const date = new Date(this.selectedDate); + const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; + const month = date.getMonth() + 1; + const day = date.getDate(); + const weekday = weekdays[date.getDay()]; + + return `${month}月${day}日 ${weekday}`; + } }, - applyName(){ - if(this.applyType===1){ + applyName() { + if (this.applyType === 1) { return '单位申请' - }else{ + } else { return '个人申请' } + }, + borrowMinDate() { + // 今年1月1日 00:00:00 的时间戳 + const year = new Date().getFullYear(); + return new Date(year, 0, 1).getTime(); + }, + borrowMaxDate() { + // 明年12月31日 23:59:59 的时间戳 + const year = new Date().getFullYear() + 1; + return new Date(year, 11, 31, 23, 59, 59).getTime(); } }, - + mounted() { this.getDetail(); }, methods: { - readChange(flag){ - this.hasReaded=flag - + readChange(flag) { + this.hasReaded = flag + }, showApplyTypeClick() { if (this.isSelfStudy) return @@ -443,7 +527,7 @@ this.detail = { ...res.data }; - this.applyType=res.data.roomType + this.applyType = res.data.roomType console.log(this.applyType) } catch (err) { console.error('获取详情失败:', err); @@ -496,55 +580,70 @@ }, handleStartTimeConfirm(e) { - if (this.isSelfStudy) { - // 自习室模式处理年月 - const date = new Date(e.value); - const year = date.getFullYear(); - const month = String(date.getMonth() + 1).padStart(2, '0'); - - this.startTime = `${year}-${month}`; - this.startTimePickerValue = this.startTime; - } else { - // 普通会议室模式处理完整日期时间 - const date = new Date(e.value); - const year = date.getFullYear(); - const month = String(date.getMonth() + 1).padStart(2, '0'); - const day = String(date.getDate()).padStart(2, '0'); - const hours = String(date.getHours()).padStart(2, '0'); - const minutes = String(date.getMinutes()).padStart(2, '0'); - - this.startTime = `${year}-${month}-${day} ${hours}:${minutes}`; - this.startTimePickerValue = this.startTime; - } - - this.showStartTimePicker = false; - }, + if (this.isSelfStudy) { + // 自习室模式处理年月 + const date = new Date(e.value); + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); - handleEndTimeConfirm(e) { - if (this.isSelfStudy) { - // 自习室模式处理年月 - const date = new Date(e.value); - const year = date.getFullYear(); - const month = String(date.getMonth() + 1).padStart(2, '0'); - - this.endTime = `${year}-${month}`; - this.endTimePickerValue = this.endTime; - } else { - // 普通会议室模式处理完整日期时间 - const date = new Date(e.value); - const year = date.getFullYear(); - const month = String(date.getMonth() + 1).padStart(2, '0'); - const day = String(date.getDate()).padStart(2, '0'); - const hours = String(date.getHours()).padStart(2, '0'); - const minutes = String(date.getMinutes()).padStart(2, '0'); - - this.endTime = `${year}-${month}-${day} ${hours}:${minutes}`; - this.endTimePickerValue = this.endTime; - } - - this.showEndTimePicker = false; + this.startTime = `${year}-${month}`; + this.startTimePickerValue = this.startTime; + } else { + // 普通会议室模式处理完整日期时间 + const date = new Date(e.value); + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + const hours = String(date.getHours()).padStart(2, '0'); + const minutes = String(date.getMinutes()).padStart(2, '0'); + + this.startTime = `${year}-${month}-${day} ${hours}:${minutes}`; + this.startTimePickerValue = this.startTime; + } + + this.showStartTimePicker = false; + }, + borrowTimeConfirm(e) { + console.log(e) + if (this.pickerType === 1) { + this.startTime = `${e.value[0]}:${e.value[1]}` + } else { + this.endTime = `${e.value[0]}:${e.value[1]}` + } + this.noIsSelfStudy=false + }, + handleEndTimeConfirm(e) { + if (this.isSelfStudy) { + // 自习室模式处理年月 + const date = new Date(e.value); + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + + this.endTime = `${year}-${month}`; + this.endTimePickerValue = this.endTime; + } else { + // 普通会议室模式处理完整日期时间 + const date = new Date(e.value); + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + const hours = String(date.getHours()).padStart(2, '0'); + const minutes = String(date.getMinutes()).padStart(2, '0'); + + this.endTime = `${year}-${month}-${day} ${hours}:${minutes}`; + this.endTimePickerValue = this.endTime; + } + + this.showEndTimePicker = false; + }, + handleborrowTimeConfirm(e) { + const date = new Date(e.value); + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + this.borrowTimeData = `${year}-${month}-${day}`; + this.borrowTimeShow = false }, - adjustEndTime() { console.log(this.startTime) const [startH, startM] = this.startTime.split(':').map(Number); @@ -579,44 +678,54 @@ /** * 验证对象属性是否为空(Promise版) * @param {Object} obj - 要验证的对象 - * @param {Object} applyRules - 验证规则对象 + * @param {Object} rules - 验证规则对象 (每个 rule.reg 应为 RegExp 对象) * @returns {Promise} 返回Promise,resolve通过验证,reject失败信息 */ - validateObject(obj, applyRules = {}) { + validateObject(obj, rules = {}) { return new Promise((resolve, reject) => { // 参数校验 - if (!obj || typeof obj !== 'object') { - return reject(new Error('参数必须是一个对象')); + if (!obj || typeof obj !== 'object' || obj === null) { + return reject(new Error('第一个参数必须是一个非空对象')); + } + if (!rules || typeof rules !== 'object') { + return reject(new Error('第二个参数(验证规则)必须是一个对象')); } const keys = Object.keys(obj); - let firstInvalidKey = null; - console.log(keys); - // 遍历检查每个属性 - for (const item of keys) { - console.log(item) - const value = obj[item]; - console.log(value); - // 检查空值且该属性在验证规则中 - if ((value === '' || value === null) && applyRules.hasOwnProperty(item)) { - firstInvalidKey = item; - break; + // 建议:只检查规则中定义的字段,而不是所有 obj 的 key + // 这样更可控,避免验证不存在的规则 + for (const field of keys) { + const rule = rules[field]; + if (!rule) { + continue; + } + const errMsg = rule.errMsg + const value = obj[field]; // 获取该字段的值 + // 检查该字段是否有规则定义 + if (!rule || !rule.reg || !rule.name) { + console.warn(`验证规则 ${field} 不完整`); + continue; // 跳过不完整的规则 + } + // 确保 rule.reg 是一个 RegExp 对象 + if (!(rule.reg instanceof RegExp)) { + reject(new Error(`${rule.name} 的验证规则不是有效的正则表达式`)); + return; + } + // 执行验证 + // 注意:这里也应处理 undefined 或 null 的情况 + const stringValue = value == null ? '' : String(value); // 转为字符串并处理 null/undefined + if (!rule.reg.test(stringValue)) { + return reject(new Error(errMsg)); // 找到第一个错误就立即 reject } } - console.log(firstInvalidKey) - if (firstInvalidKey) { - // 返回具体的错误信息 - const errorMsg = `${applyRules[firstInvalidKey]}不能为空`; - reject(new Error(errorMsg)); - } else { - resolve('所有属性验证通过'); - } + // 如果循环完成,说明所有验证都通过了 + resolve('所有属性验证通过'); }); }, async handleBook() { try { - this.readShow=false - console.log(this.applyType); + this.readShow = false + // console.log(this.applyType); let bookingInfo = { roomId: this.Id, applyType: this.applyType, @@ -630,11 +739,11 @@ userPhone: this.userPhone, userAddress: this.userAddress, userCardId: this.userCardId, - startTime: this.startTime, - endTime: this.endTime, + startTime: this.isSelfStudy?this.startTime:`${this.borrowTimeData} ${this.startTime}`, + endTime: this.isSelfStudy?this.endTime:`${this.borrowTimeData} ${this.endTime}`, counter: this.counter, num: this.num, - applyType:this.applyType + // applyType:this.applyType } await this.validateObject(userApplyInfo, this.applyRules) const applyInfo = Object.assign(bookingInfo, userApplyInfo) @@ -642,29 +751,29 @@ const app = getApp() app.globalData.applyInfo = applyInfo this.applyInfo = applyInfo - this.readShow=true + this.readShow = true } //单位申请 if (this.applyType === 1) { if (!this.stampUrl) return uni.showToast({ title: '请上传印章', - icon:'none' + icon: 'none' }) const userApplyInfo = { concatName: this.concatName, concatPhone: this.concatPhone, companyName: this.companyName, - startTime: this.startTime, - endTime: this.endTime, + startTime: this.isSelfStudy?this.startTime:`${this.borrowTimeData} ${this.startTime}`, + endTime: this.isSelfStudy?this.endTime:`${this.borrowTimeData} ${this.endTime}`, counter: this.counter, num: this.num, stampUrl: this.stampUrl, - applyType:this.applyType + // applyType:this.applyType } await this.validateObject(userApplyInfo, this.applyRules) const app = getApp() app.globalData.applyInfo = Object.assign(bookingInfo, userApplyInfo) - this.readShow=true + this.readShow = true } } catch (error) { uni.showToast({ @@ -674,8 +783,8 @@ } }, - async postApply(){ - this.readShow=false + async postApply() { + this.readShow = false uni.navigateTo({ url: `/pages/sign/sign?isSelfStudy=${this.isSelfStudy}` }) @@ -690,7 +799,7 @@ // if (!res || !res.success) { // throw new Error('会议室预定失败'); // } - + // if (res.success == true) { // uni.redirectTo({ // url: `/pages/docList/index?files=${JSON.stringify(res.data)}&&isSelfStudy=${this.isSelfStudy}` @@ -862,40 +971,42 @@ } - .upload-item, .upload-btn { - width: 160rpx; - height: 160rpx; - margin: 5rpx; - position: relative; - background: #f8f8f8; - border-radius: 8rpx; - display: flex; - justify-content: center; - align-items: center; - overflow: hidden; - - image, video { - width: 100%; - height: 100%; - } - - .delete-btn { - position: absolute; - right: 0; - top: 0; - width: 40rpx; - height: 40rpx; - background: rgba(0, 0, 0, 0.5); - border-radius: 0 0 0 8rpx; - display: flex; - justify-content: center; - align-items: center; - } - } - - .upload-btn { - border: 1rpx dashed #c0c4cc; - } + .upload-item, + .upload-btn { + width: 160rpx; + height: 160rpx; + margin: 5rpx; + position: relative; + background: #f8f8f8; + border-radius: 8rpx; + display: flex; + justify-content: center; + align-items: center; + overflow: hidden; + + image, + video { + width: 100%; + height: 100%; + } + + .delete-btn { + position: absolute; + right: 0; + top: 0; + width: 40rpx; + height: 40rpx; + background: rgba(0, 0, 0, 0.5); + border-radius: 0 0 0 8rpx; + display: flex; + justify-content: center; + align-items: center; + } + } + + .upload-btn { + border: 1rpx dashed #c0c4cc; + } /* 新增备注区域 */ .remark-section { diff --git a/pages/meetingList/index.vue b/pages/meetingList/index.vue index 69b2f47..9a1385c 100644 --- a/pages/meetingList/index.vue +++ b/pages/meetingList/index.vue @@ -299,7 +299,7 @@ } // 如果是自习室,先弹出提示确认框 - if (item.roomType == 2 ) { + if (item.roomType == 2&&item.num!==4 ) { uni.showModal({ title: '温馨提示', content: '自习室预约时间按月为单位,单次预约最长两个月,请确认是否继续?', diff --git a/utils/config.js b/utils/config.js index 1004759..7f0d2d6 100644 --- a/utils/config.js +++ b/utils/config.js @@ -1,7 +1,7 @@ -// export const BASE_URL = 'http://10.10.1.6:8071'; -// export const IMAGE_BASE_URL = `http://10.10.1.6:8071`; -export const BASE_URL = 'https://jinshan.nantong.info'; -export const IMAGE_BASE_URL = `https://jinshan.nantong.info`; +export const BASE_URL = 'http://10.10.1.6:8071'; +export const IMAGE_BASE_URL = `http://10.10.1.6:8071`; +// export const BASE_URL = 'https://jinshan.nantong.info'; +// export const IMAGE_BASE_URL = `https://jinshan.nantong.info`; export const WS_BASE_URL = `wss://jinshan.nantong.info`; // export const WS_BASE_URL = 'ws://10.10.1.6:8071';