会议室预约
This commit is contained in:
parent
d710c820a7
commit
8260925b71
23
App.vue
23
App.vue
@ -1,5 +1,28 @@
|
||||
<script>
|
||||
export default {
|
||||
globalData: {
|
||||
isLogin: false,
|
||||
userInfo: null,
|
||||
applyInfo:null
|
||||
},
|
||||
methods: {
|
||||
checkLogin() {
|
||||
return new Promise((resolve) => {
|
||||
if (this.globalData.isLogin) {
|
||||
resolve(true);
|
||||
} else {
|
||||
// 检查本地存储的 token
|
||||
const token = uni.getStorageSync('token');
|
||||
if (token) {
|
||||
this.globalData.isLogin = true;
|
||||
resolve(true);
|
||||
} else {
|
||||
resolve(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
onLaunch: function() {
|
||||
console.log('App Launch')
|
||||
},
|
||||
|
||||
2
main.js
2
main.js
@ -4,6 +4,8 @@ import App from './App'
|
||||
import Vue from 'vue'
|
||||
import uView from "uview-ui";
|
||||
Vue.use(uView);
|
||||
// 2. 引入 uView 样式
|
||||
import 'uview-ui/index.scss';
|
||||
import './uni.promisify.adaptor'
|
||||
uni.$u.config.unit = 'rpx'
|
||||
Vue.config.productionTip = false
|
||||
|
||||
@ -208,6 +208,12 @@
|
||||
"style": {
|
||||
"navigationBarTitleText": "电子签名"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/docList/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "文件下载"
|
||||
}
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
79
pages/docList/index.vue
Normal file
79
pages/docList/index.vue
Normal file
@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<view class="doc-page">
|
||||
<view class="doc-content">
|
||||
<view class="doc-file" v-for="item of docList" @click="downLoadFile(item)">
|
||||
<image src="/static/imgs/word.png" alt="" srcset="" class="doc-img"/>
|
||||
<view class="doc-name">{{item.name}}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {IMAGE_BASE_URL,BASE_URL} from '@/utils/config';
|
||||
import {downloadPdfFiles} from '@/utils/download.js'
|
||||
export default{
|
||||
data(){
|
||||
return{
|
||||
docList:[],
|
||||
nameList:{
|
||||
'applyPdf':'申请表申请表申请表申请表申请表申请表申请表申请表申请表申请表',
|
||||
'covenantPdf':'协议书'
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
console.log(option);
|
||||
console.log(JSON.parse(option.files));
|
||||
|
||||
const obj=JSON.parse(option.files)
|
||||
this.docList=[
|
||||
{name:'近山社区城市青年会客厅使用说明及申请表',url:BASE_URL+obj.covenantPdf},
|
||||
{name:`${JSON.parse(option.isSelfStudy)?'近山社区自习室个人使用承诺书':'近山社区城市青年会客厅安全使用承诺书'}`,url:BASE_URL+obj.applyPdf},
|
||||
]
|
||||
},
|
||||
methods:{
|
||||
async downLoadFile(fileUrl){
|
||||
const result = await downloadPdfFiles(fileUrl);
|
||||
if(result.success==true){
|
||||
// uni.navigateTo({
|
||||
// url: `/pages/meetingList/index`
|
||||
// });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.doc-page{
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
/* margin: 10rpx; */
|
||||
}
|
||||
.doc-content{
|
||||
margin: 10px;
|
||||
}
|
||||
.doc-file{
|
||||
padding: 20rpx 10rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
/* margin: 10px; */
|
||||
/* border-bottom: 1px solid #c9c9c9; */
|
||||
}
|
||||
.doc-file:not(:last-child){
|
||||
border-bottom: 1px solid #c9c9c9;
|
||||
}
|
||||
.doc-img{
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
}
|
||||
.doc-name{
|
||||
flex: 1;
|
||||
color: #666666;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
@ -39,50 +39,53 @@
|
||||
<text class="section-title">事由主题</text>
|
||||
</view>
|
||||
<view>
|
||||
<checkbox-group @change="thingCheckboxChange" v-model="thingTheme">
|
||||
<radio-group @change="thingCheckboxChange">
|
||||
<label v-for="item in thingThemes">
|
||||
<checkbox :value="item.value" style="transform:scale(0.7)" /><text
|
||||
style="font-size: 12px;color: #333333;">{{item.name}}</text>
|
||||
<radio :value="item.value" style="transform:scale(0.7)"
|
||||
:checked="item.value === applyTheme" />
|
||||
<text style="font-size: 12px;color: #333333;">{{item.name}}</text>
|
||||
</label>
|
||||
</checkbox-group>
|
||||
</radio-group>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="date-section">
|
||||
<view class="section-header">
|
||||
<u-icon name="man-add" size="38" color="#2979ff"></u-icon>
|
||||
<text class="section-title">申请人类型</text>
|
||||
</view>
|
||||
<view class="date-display" @click="showApplyType = true">
|
||||
<view class="date-display" @click="showApplyTypeClick()">
|
||||
<view class="">{{applyName}}</view>
|
||||
<u-icon slot="right" name="arrow-right"></u-icon>
|
||||
</view>
|
||||
<view v-show="applyName=='单位申请'" style="margin-top: 10px;background-color: #f8f9fa;">
|
||||
<u--input placeholder="请输入单位全称" border="null" v-model="companyName"></u--input>
|
||||
<view v-show="applyName=='单位申请'">
|
||||
<view style="margin-top: 10px;background-color: #f8f9fa;">
|
||||
<u--input placeholder="请输入单位全称" border="null" v-model="companyName"></u--input>
|
||||
</view>
|
||||
<view class="" style="margin-top: 10px;background-color: #f8f9fa;">
|
||||
<u--input placeholder="请输入负责人姓名" border="null" v-model="concatName"></u--input>
|
||||
</view>
|
||||
<view class="" style="margin-top: 10px;background-color: #f8f9fa;">
|
||||
<u--input placeholder="请输入负责人电话" border="null" type='tel' v-model="concatPhone"></u--input>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-show="applyName=='个人申请'">
|
||||
<view class="" style="margin-top: 10px;background-color: #f8f9fa;">
|
||||
<u--input placeholder="请输入姓名" border="null" v-model="userName"></u--input>
|
||||
</view>
|
||||
<view class="" style="margin-top: 10px;background-color: #f8f9fa;">
|
||||
<u--input placeholder="请输入身份证号" border="null" v-model="userCard"></u--input>
|
||||
<u--input placeholder="请输入手机号" border="null" type="tel" v-model="userPhone"></u--input>
|
||||
</view>
|
||||
<view class="" style="margin-top: 10px;background-color: #f8f9fa;">
|
||||
<u--input placeholder="请输入身份证号" border="null" type="idcard" v-model="userCardId"></u--input>
|
||||
</view>
|
||||
<view class="" style="margin-top: 10px;background-color: #f8f9fa;">
|
||||
<u--input placeholder="请输入申请人地址" border="null" v-model="userAddress"></u--input>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="date-section">
|
||||
<view class="section-header">
|
||||
<u-icon name="man-add" size="38" color="#2979ff"></u-icon>
|
||||
<text class="section-title">负责人</text>
|
||||
</view>
|
||||
|
||||
<view>
|
||||
<view class="" style="margin-top: 10px;background-color: #f8f9fa;">
|
||||
<u--input placeholder="请输入负责人姓名" border="null" v-model="chargeName"></u--input>
|
||||
</view>
|
||||
<view class="" style="margin-top: 10px;background-color: #f8f9fa;">
|
||||
<u--input placeholder="请输入负责人电话" border="null" v-model="chargePhone"></u--input>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="date-section">
|
||||
<view class="section-header">
|
||||
<u-icon name="pushpin" size="38" color="#2979ff"></u-icon>
|
||||
@ -91,7 +94,7 @@
|
||||
|
||||
<view>
|
||||
<view class="" style="margin-top: 10px;background-color: #f8f9fa;">
|
||||
<u--input placeholder="请输入场次" border="null" v-model="session"></u--input>
|
||||
<u--input placeholder="请输入场次" border="null" v-model="counter"></u--input>
|
||||
</view>
|
||||
<view class="" style="margin-top: 10px;background-color: #f8f9fa;">
|
||||
<u--input placeholder="请输入人数" border="null" v-model="num"></u--input>
|
||||
@ -108,19 +111,19 @@
|
||||
<view class="time-selector" @click="showStartTimePicker = true">
|
||||
<text class="time-label">开始</text>
|
||||
<view class="time-display">
|
||||
{{ selectedStartTime }}
|
||||
{{ startTime }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="time-separator">—</view>
|
||||
<view class="time-selector" @click="showEndTimePicker = true">
|
||||
<text class="time-label">结束</text>
|
||||
<view class="time-display">
|
||||
{{ selectedEndTime }}
|
||||
{{ endTime }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="date-section">
|
||||
<!-- <view class="date-section">
|
||||
<view class="section-header">
|
||||
<u-icon name="list-dot" size="38" color="#2979ff"></u-icon>
|
||||
<text class="section-title">使用情况</text>
|
||||
@ -133,27 +136,20 @@
|
||||
</label>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 预定须知卡片 -->
|
||||
<!-- <view class="notice-card">
|
||||
<view class="card-header">
|
||||
<u-icon name="info-circle" size="34" color="#2979ff"></u-icon>
|
||||
<text class="card-title">预订须知</text>
|
||||
</view>
|
||||
<view class="notice-list">
|
||||
<view class="notice-item" v-for="(item, index) in noticeList" :key="index">
|
||||
<text class="notice-index">{{ index + 1 }}.</text>
|
||||
<text class="notice-content">{{ item }}</text>
|
||||
</view> -->
|
||||
<view class="date-section">
|
||||
<view class="section-header">
|
||||
<u-icon name="list-dot" size="38" color="#2979ff"></u-icon>
|
||||
<text class="section-title">申请理由</text>
|
||||
</view>
|
||||
<view>
|
||||
<u--input placeholder="请输入申请理由" border="null" v-model="reason"></u--input>
|
||||
</view>
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
</view>
|
||||
<!-- 底部固定操作栏 -->
|
||||
<view class="action-bar">
|
||||
<!-- <u-button type="primary" shape="circle" @click="handleBook">立即预订</u-button> -->
|
||||
<u-button type="primary" shape="circle" @click="signatureShow=true">立即预订</u-button>
|
||||
<u-button type="primary" shape="circle" @click="handleBook">立即预订</u-button>
|
||||
</view>
|
||||
|
||||
<!-- 日历组件 -->
|
||||
@ -170,12 +166,6 @@
|
||||
<u-picker :show="showApplyType" :columns="applyTypeColumns" @confirm="applyConfirm"
|
||||
@cancel="showApplyType=false"></u-picker>
|
||||
|
||||
<u-popup :show="signatureShow" :round="10" mode="bottom" closeOnClickOverlay>
|
||||
<view>
|
||||
|
||||
</view>
|
||||
</u-popup>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@ -197,9 +187,9 @@
|
||||
usages,
|
||||
thingThemes
|
||||
} from '@/utils/dict.js'
|
||||
import signature from '../../components/signature.vue';
|
||||
// import signature from '../sign/sign.vue';
|
||||
export default {
|
||||
components:{signature},
|
||||
|
||||
data() {
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
@ -217,24 +207,41 @@
|
||||
if (endHours >= 24) endHours = 0;
|
||||
|
||||
return {
|
||||
chargeName: '',
|
||||
chargePhone: '',
|
||||
companyName: '',
|
||||
userCard: '',
|
||||
userName: '',
|
||||
session:'',
|
||||
num:'',
|
||||
applyRules: {
|
||||
userPhone: '申请人手机号',
|
||||
userName: '申请人姓名',
|
||||
userCardId: '申请人身份证号',
|
||||
userAddress: '申请人地址',
|
||||
concatName: '负责人姓名',
|
||||
concatPhone: '负责人电话',
|
||||
companyName: '公司名称',
|
||||
startTime: '开始时间',
|
||||
endTime: '结束时间',
|
||||
num: "人数",
|
||||
counter: '场次'
|
||||
},
|
||||
userName: '丁',
|
||||
userPhone: "13667879876",
|
||||
userCardId: '1234',
|
||||
userAddress: '北京二环',
|
||||
counter: '10',
|
||||
num: '100',
|
||||
// 会议室图片数组
|
||||
thingTheme: [],
|
||||
applyTheme: 1,
|
||||
applyArea:1,
|
||||
thingThemes: thingThemes.getAll(),
|
||||
usage:[],
|
||||
usages:usages.getAll(),
|
||||
usage: [],
|
||||
usages: usages.getAll(),
|
||||
list1: [],
|
||||
detail: {},
|
||||
signatureShow:false,
|
||||
signatureShow: false,
|
||||
isSelfStudy: true, //dateTime,yearmonth
|
||||
mode: 'datetime',
|
||||
precision: null,
|
||||
concatPhone: '',
|
||||
reason: '',
|
||||
applySign: '', //签名地址
|
||||
// 日历控制(默认隐藏)
|
||||
showCalendar: false,
|
||||
calendarKey: 0,
|
||||
@ -242,7 +249,10 @@
|
||||
applyTypeColumns: [
|
||||
['个人申请', '单位申请']
|
||||
],
|
||||
applyName: '',
|
||||
applyType: 1, //个人1 企业2
|
||||
applyName: '个人申请',
|
||||
concatName: '', //联系人姓名
|
||||
concatPhone: '', //联系人电话
|
||||
// 时间选择器控制
|
||||
showStartTimePicker: false,
|
||||
showEndTimePicker: false,
|
||||
@ -257,8 +267,8 @@
|
||||
maxDate: `${year + 1}-12-31`,
|
||||
|
||||
// 时间相关
|
||||
selectedStartTime: ``,
|
||||
selectedEndTime: ``,
|
||||
startTime: `2025-08`,
|
||||
endTime: `2025-10`,
|
||||
startTimeValue: `${startHours.toString().padStart(2, '0')}:${startMinutes.toString().padStart(2, '0')}`,
|
||||
endTimeValue: `${endHours.toString().padStart(2, '0')}:${endMinutes.toString().padStart(2, '0')}`,
|
||||
|
||||
@ -275,14 +285,10 @@
|
||||
Id: '',
|
||||
};
|
||||
},
|
||||
onReady() {
|
||||
// 微信小程序需要用此写法
|
||||
// this.$refs.startTimePicker.setFormatter(this.formatter)
|
||||
// this.$refs.endTimePicker.setFormatter(this.formatter)
|
||||
},
|
||||
onLoad(options) {
|
||||
if (options && options.Id) {
|
||||
this.Id = options.Id;
|
||||
this.isSelfStudy=JSON.parse(options.isSelfStudy)
|
||||
this.mode = options.isSelfStudy === 'true' ? 'year-month' : 'datetime'
|
||||
}
|
||||
},
|
||||
@ -304,18 +310,9 @@
|
||||
this.getDetail();
|
||||
},
|
||||
methods: {
|
||||
formatter(type, value) {
|
||||
if (type === 'year') {
|
||||
return `${value}年`
|
||||
}
|
||||
if (type === 'month') {
|
||||
return `${value}月`
|
||||
}
|
||||
if (type === 'day') {
|
||||
return `${value}日`
|
||||
}
|
||||
|
||||
return value
|
||||
showApplyTypeClick(){
|
||||
if(this.isSelfStudy) return
|
||||
this.showApplyType=true
|
||||
},
|
||||
// 获取详情页面
|
||||
async getDetail() {
|
||||
@ -339,15 +336,27 @@
|
||||
}
|
||||
},
|
||||
thingCheckboxChange(e) {
|
||||
console.log(e);
|
||||
this.applyTheme = JSON.parse(e.detail.value)
|
||||
},
|
||||
usagesCheckboxChange(e){
|
||||
areaCheckboxChange(e) {
|
||||
this.applyArea = JSON.parse(e.detail.value)
|
||||
},
|
||||
usagesCheckboxChange(e) {
|
||||
console.log(e);
|
||||
},
|
||||
applyConfirm(e) {
|
||||
console.log(e)
|
||||
console.log(e.value[0])
|
||||
const list=['个人申请','单位申请']
|
||||
this.applyName = e.value[0]
|
||||
this.showApplyType = false
|
||||
const index = list.findIndex((item) => item === e.value[0])
|
||||
console.log(index)
|
||||
if(index!=-1){
|
||||
this.applyType = parseInt(index + 1)
|
||||
this.showApplyType = false
|
||||
}else{
|
||||
console.log('未找到');
|
||||
}
|
||||
|
||||
},
|
||||
handleDateConfirm(e) {
|
||||
let selectedDate;
|
||||
@ -373,29 +382,54 @@
|
||||
},
|
||||
|
||||
handleStartTimeConfirm(e) {
|
||||
const date = new Date(e.value)
|
||||
const dateString = this.mode === 'year-month' ? `${date.getFullYear()}-${date.getMonth()+1}` :
|
||||
`${date.getFullYear()}-${date.getMonth()+1}-${date.getDate()} ${date.getHours()}:00`
|
||||
this.selectedStartTime = dateString;
|
||||
const date = new Date(e.value);
|
||||
|
||||
// 补零函数:确保数字是两位数
|
||||
const padZero = num => num.toString().padStart(2, '0');
|
||||
|
||||
const year = date.getFullYear();
|
||||
const month = padZero(date.getMonth() + 1); // 月份补零
|
||||
const day = padZero(date.getDate()); // 日期补零
|
||||
const hours = padZero(date.getHours()); // 小时补零
|
||||
|
||||
const dateString = this.mode === 'year-month' ?
|
||||
`${year}-${month}` // 年月模式:2023-01
|
||||
:
|
||||
`${year}-${month}-${day} ${hours}:00`; // 完整模式:2023-01-02 09:00
|
||||
|
||||
this.startTime = dateString;
|
||||
this.startTimePickerValue = dateString;
|
||||
this.showStartTimePicker = false;
|
||||
// this.adjustEndTime();
|
||||
},
|
||||
|
||||
handleEndTimeConfirm(e) {
|
||||
const date = new Date(e.value)
|
||||
const dateString = this.mode === 'year-month' ? `${date.getFullYear()}-${date.getMonth()+1}` :
|
||||
`${date.getFullYear()}-${date.getMonth()+1}-${date.getDate()} ${date.getHours()}:00`
|
||||
this.selectedEndTime = dateString;
|
||||
const date = new Date(e.value);
|
||||
|
||||
// 补零函数:确保数字是两位数
|
||||
const padZero = num => num.toString().padStart(2, '0');
|
||||
|
||||
const year = date.getFullYear();
|
||||
const month = padZero(date.getMonth() + 1); // 月份补零
|
||||
const day = padZero(date.getDate()); // 日期补零
|
||||
const hours = padZero(date.getHours()); // 小时补零
|
||||
|
||||
const dateString = this.mode === 'year-month' ?
|
||||
`${year}-${month}` // 年月模式:2023-01
|
||||
:
|
||||
`${year}-${month}-${day} ${hours}:00`; // 完整模式:2023-01-02 09:00
|
||||
|
||||
this.endTime = dateString;
|
||||
this.endTimePickerValue = dateString;
|
||||
this.showEndTimePicker = false;
|
||||
// this.validateTime();
|
||||
|
||||
console.log('格式化后的结束时间:', this.endTime);
|
||||
// this.validateTime(); // 如果需要验证时间范围,取消注释
|
||||
},
|
||||
|
||||
adjustEndTime() {
|
||||
console.log(this.selectedStartTime)
|
||||
const [startH, startM] = this.selectedStartTime.split(':').map(Number);
|
||||
let [endH, endM] = this.selectedEndTime.split(':').map(Number);
|
||||
console.log(this.startTime)
|
||||
const [startH, startM] = this.startTime.split(':').map(Number);
|
||||
let [endH, endM] = this.endTime.split(':').map(Number);
|
||||
|
||||
const startTotal = startH * 60 + startM;
|
||||
let endTotal = endH * 60 + endM;
|
||||
@ -404,15 +438,15 @@
|
||||
endTotal = startTotal + 60;
|
||||
endH = Math.floor(endTotal / 60);
|
||||
endM = endTotal % 60;
|
||||
this.selectedEndTime = `${endH.toString().padStart(2, '0')}:${endM.toString().padStart(2, '0')}`;
|
||||
this.endTime = `${endH.toString().padStart(2, '0')}:${endM.toString().padStart(2, '0')}`;
|
||||
this.endTimeValue = `${endH}:${endM}`;
|
||||
this.endTimePickerValue = this.selectedEndTime;
|
||||
this.endTimePickerValue = this.endTime;
|
||||
}
|
||||
},
|
||||
|
||||
validateTime() {
|
||||
const [startH, startM] = this.selectedStartTime.split(':').map(Number);
|
||||
const [endH, endM] = this.selectedEndTime.split(':').map(Number);
|
||||
const [startH, startM] = this.startTime.split(':').map(Number);
|
||||
const [endH, endM] = this.endTime.split(':').map(Number);
|
||||
|
||||
const duration = (endH * 60 + endM) - (startH * 60 + startM);
|
||||
if (duration < 30) {
|
||||
@ -423,56 +457,106 @@
|
||||
this.adjustEndTime();
|
||||
}
|
||||
},
|
||||
|
||||
handleBook() {
|
||||
this.validateTime();
|
||||
|
||||
// 构建预订信息对象
|
||||
const bookingInfo = {
|
||||
startAt: new Date(`${this.selectedDate} ${this.selectedStartTime}`),
|
||||
endAt: new Date(`${this.selectedDate} ${this.selectedEndTime}`),
|
||||
remark: this.remark,
|
||||
roomId: this.Id
|
||||
};
|
||||
|
||||
|
||||
console.log('提交的预订信息:', bookingInfo);
|
||||
|
||||
uni.showToast({
|
||||
title: `已预订 ${this.formattedSelectedDate} ${this.selectedStartTime}-${this.selectedEndTime}`,
|
||||
icon: 'none'
|
||||
});
|
||||
|
||||
// 这里可以添加实际的API调用
|
||||
post('/api/v1/app_auth/metting-room/order/register', bookingInfo).then((res) => {
|
||||
console.log("===res", res)
|
||||
if (!res || !res.success) {
|
||||
throw new Error('会议室预定失败');
|
||||
/**
|
||||
* 验证对象属性是否为空(Promise版)
|
||||
* @param {Object} obj - 要验证的对象
|
||||
* @param {Object} applyRules - 验证规则对象
|
||||
* @returns {Promise} 返回Promise,resolve通过验证,reject失败信息
|
||||
*/
|
||||
validateObject(obj, applyRules = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 参数校验
|
||||
if (!obj || typeof obj !== 'object') {
|
||||
return reject(new Error('参数必须是一个对象'));
|
||||
}
|
||||
uni.showToast({
|
||||
title: '会议室预定成功!',
|
||||
icon: 'success'
|
||||
});
|
||||
this.remark = null;
|
||||
setTimeout(() => {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
console.log(firstInvalidKey)
|
||||
if (firstInvalidKey) {
|
||||
// 返回具体的错误信息
|
||||
const errorMsg = `${applyRules[firstInvalidKey]}不能为空`;
|
||||
reject(new Error(errorMsg));
|
||||
} else {
|
||||
resolve('所有属性验证通过');
|
||||
}
|
||||
});
|
||||
},
|
||||
async handleBook() {
|
||||
try {
|
||||
console.log(this.applyType);
|
||||
let bookingInfo = {
|
||||
roomId: this.Id,
|
||||
applyType: this.applyType,
|
||||
reason: this.reason,
|
||||
applyTheme: this.applyTheme
|
||||
};
|
||||
if (this.applyType === 1) {
|
||||
const userApplyInfo = {
|
||||
userName: this.userName,
|
||||
userPhone: this.userPhone,
|
||||
userAddress: this.userAddress,
|
||||
userCardId: this.userCardId,
|
||||
startTime: this.startTime,
|
||||
endTime: this.endTime,
|
||||
counter: this.counter,
|
||||
num: this.num
|
||||
}
|
||||
await this.validateObject(userApplyInfo, this.applyRules)
|
||||
const applyInfo = Object.assign(bookingInfo, userApplyInfo)
|
||||
// 页面A设置参数
|
||||
const app = getApp()
|
||||
app.globalData.applyInfo = applyInfo
|
||||
uni.navigateTo({
|
||||
url: `/pages/meetingList/index`,
|
||||
success: () => {
|
||||
console.log('导航成功,ID:', id);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('导航失败:', err);
|
||||
uni.showToast({
|
||||
title: '打开详情页失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
url: `/pages/sign/sign?isSelfStudy=${this.isSelfStudy}`
|
||||
})
|
||||
}
|
||||
if (this.applyType === 2) {
|
||||
const userApplyInfo = {
|
||||
concatName: this.concatName,
|
||||
concatPhone: this.concatPhone,
|
||||
companyName: this.companyName,
|
||||
startTime: this.startTime,
|
||||
endTime: this.endTime,
|
||||
counter: this.counter,
|
||||
num: this.num
|
||||
}
|
||||
await this.validateObject(userApplyInfo, this.applyRules)
|
||||
const applyInfo = Object.assign(bookingInfo, userApplyInfo)
|
||||
// 这里可以添加实际的API调用
|
||||
const res = await post('/api/v1/app_auth/metting-room/order/register', applyInfo)
|
||||
if (!res || !res.success) {
|
||||
throw new Error('会议室预定失败');
|
||||
}
|
||||
uni.showToast({
|
||||
title: '会议室预定成功!',
|
||||
icon: 'success'
|
||||
});
|
||||
}, 4000)
|
||||
if(res.success==true){
|
||||
uni.navigateTo({
|
||||
url:`/pages/docList/index?files=${JSON.stringify(res.data)}&&isSelfStudy=${this.isSelfStudy}`
|
||||
})
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
uni.showToast({
|
||||
title: error.message,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
// this.submitBooking(bookingInfo);
|
||||
},
|
||||
|
||||
}
|
||||
@ -688,6 +772,7 @@
|
||||
padding: 20rpx;
|
||||
background: #fff;
|
||||
box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.08);
|
||||
z-index: 999;
|
||||
|
||||
.u-button {
|
||||
height: 88rpx;
|
||||
|
||||
@ -254,7 +254,7 @@
|
||||
|
||||
// 安全获取ID(兼容各种可能的字段名)
|
||||
const id = item.id;
|
||||
const isSelfStudy=item.title==='自习室'?'true':'false'
|
||||
const isSelfStudy=item.title==='自习室'?true:false
|
||||
if (!id) {
|
||||
uni.showToast({
|
||||
title: '会议室信息异常',
|
||||
|
||||
@ -113,7 +113,7 @@
|
||||
IMAGE_BASE_URL,
|
||||
BASE_URL
|
||||
} from '@/utils/config';
|
||||
|
||||
import { navigateTo } from '@/utils/router';
|
||||
export default {
|
||||
components: {
|
||||
Footer
|
||||
@ -582,24 +582,22 @@
|
||||
goPage(item) {
|
||||
if (item.key === 6) { // 联系社区的特殊处理
|
||||
this.handleContactCommunity();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.key === 5) { // 设置的特殊处理
|
||||
this.handleEditClick(); // 调用编辑用户信息的方法
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.checkLogin()) {
|
||||
this.showEditModal = true;
|
||||
return;
|
||||
}
|
||||
// if (!this.checkLogin()) {
|
||||
// this.showEditModal = true;
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (item.pageUrl) {
|
||||
uni.navigateTo({
|
||||
navigateTo({
|
||||
url: `/pages/${item.pageUrl}/index`
|
||||
});
|
||||
},false);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -1,31 +1,33 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="wrapper">
|
||||
<!-- <view class="handRight">
|
||||
<view class="handTitle">请签名</view>
|
||||
</view> -->
|
||||
<view class="handCenter">
|
||||
<canvas class="handWriting" :disable-scroll="true" @touchstart="uploadScaleStart"
|
||||
@touchmove="uploadScaleMove" @touchend="uploadScaleEnd" canvas-id="handWriting"></canvas>
|
||||
</view>
|
||||
<view class="handBtn">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<image @click="selectColorEvent('black','#1A1A1A')"
|
||||
<!-- <image @click="selectColorEvent('black','#1A1A1A')"
|
||||
:src="selectColor === 'black' ? '/static/other/color_black_selected.png' : '/static/other/color_black.png'"
|
||||
class="black-select"></image>
|
||||
<image @click="selectColorEvent('red','#ca262a')"
|
||||
:src="selectColor === 'red' ? '/static/other/color_red_selected.png' : '/static/other/color_red.png'"
|
||||
class="red-select"></image>
|
||||
class="red-select"></image> -->
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-WEIXIN -->
|
||||
<div class="color_pic" :style="{background:lineColor}" @click="showPickerColor=true"></div>
|
||||
<!-- #endif -->
|
||||
<button @click="clear" class="delBtn">清空</button>
|
||||
<button @click="saveCanvasAsImg" class="saveBtn">保存</button>
|
||||
<button @click="previewCanvasImg" class="previewBtn">预览</button>
|
||||
<!-- <button @click="saveCanvasAsImg" class="saveBtn">保存</button> -->
|
||||
<!-- <button @click="previewCanvasImg" class="previewBtn">预览</button> -->
|
||||
<button @click="undo" class="undoBtn">撤销</button>
|
||||
<button @click="subCanvas" class="subBtn">完成</button>
|
||||
</view>
|
||||
<view class="handCenter">
|
||||
<canvas class="handWriting" :disable-scroll="true" @touchstart="uploadScaleStart"
|
||||
@touchmove="uploadScaleMove" @touchend="uploadScaleEnd" canvas-id="handWriting"></canvas>
|
||||
</view>
|
||||
<view class="handRight">
|
||||
<view class="handTitle">请签名</view>
|
||||
</view>
|
||||
|
||||
|
||||
</view>
|
||||
|
||||
<pickerColor :isShow="showPickerColor" :bottom="0" @callback='getPickerColor' />
|
||||
@ -33,8 +35,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import pickerColor from "./pickerColor.vue"
|
||||
import { post } from "../../utils/request";
|
||||
import pickerColor from "./pickerColor.vue"
|
||||
import {IMAGE_BASE_URL,BASE_URL} from '@/utils/config';
|
||||
import {downloadPdfFiles} from '@/utils/download.js'
|
||||
export default {
|
||||
components: {
|
||||
pickerColor
|
||||
@ -62,6 +66,8 @@
|
||||
},
|
||||
toDataURL: void 0,
|
||||
requestAnimationFrame: void 0,
|
||||
applyInfo:null,
|
||||
isSelfStudy:true,
|
||||
};
|
||||
},
|
||||
props: { //可用于修改的参数放在props里 也可单独放在外面做成组件调用 传值
|
||||
@ -94,7 +100,17 @@
|
||||
default: ''
|
||||
},
|
||||
},
|
||||
onLoad() {
|
||||
onLoad(option) {
|
||||
this.isSelfStudy=option.isSelfStudy
|
||||
// 页面A设置参数
|
||||
const app = getApp()
|
||||
if(app.globalData.applyInfo){
|
||||
this.applyInfo=app.globalData.applyInfo
|
||||
}else{
|
||||
uni.navigateTo({
|
||||
url:'/pages/meetingList/index'
|
||||
})
|
||||
}
|
||||
this.ctx = uni.createCanvasContext("handWriting");
|
||||
this.$nextTick(() => {
|
||||
uni.createSelectorQuery().select('.handCenter').boundingClientRect(rect => {
|
||||
@ -418,7 +434,7 @@
|
||||
|
||||
// 1. 保存到本地相册
|
||||
try {
|
||||
await this.saveToAlbum(res.tempFilePath);
|
||||
// await this.saveToAlbum(res.tempFilePath);
|
||||
|
||||
// 2. 上传到服务器
|
||||
uni.showLoading({
|
||||
@ -428,10 +444,30 @@
|
||||
const uploadRes = await this.uploadSignature(res.tempFilePath);
|
||||
|
||||
uni.hideLoading();
|
||||
uni.showToast({
|
||||
title: '签名上传成功',
|
||||
icon: 'success'
|
||||
});
|
||||
this.applyInfo.applySign=uploadRes
|
||||
const response=await post('/api/v1/app_auth/metting-room/order/register', this.applyInfo)
|
||||
console.log("===response", response)
|
||||
if (!response || !response.success) {
|
||||
throw new Error('会议室预定失败');
|
||||
}
|
||||
if(response.success==true){
|
||||
uni.navigateTo({
|
||||
url:`/pages/docList/index?files=${JSON.stringify(response.data)}&&isSelfStudy=${this.isSelfStudy}`
|
||||
})
|
||||
}
|
||||
uni.showToast({
|
||||
title: '会议室预定成功!',
|
||||
icon: 'success'
|
||||
});
|
||||
|
||||
// const result = await downloadPdfFiles(response);
|
||||
// console.log('下载结果:', result);
|
||||
// if(result.success==true){
|
||||
// uni.navigateTo({
|
||||
// url: `/pages/meetingList/index`
|
||||
// });
|
||||
// }
|
||||
|
||||
|
||||
// 3. 可以通过回调或者事件将上传结果返回给父组件
|
||||
// this.$emit('upload-success', {
|
||||
@ -558,20 +594,21 @@
|
||||
|
||||
.wrapper {
|
||||
width: 100%;
|
||||
height: 95vh;
|
||||
margin: 40rpx 0;
|
||||
height: 100vh;
|
||||
/* margin: 40rpx 0; */
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-content: center;
|
||||
flex-direction: row;
|
||||
flex-direction:column;
|
||||
justify-content: center;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.handWriting {
|
||||
background: #fff;
|
||||
width: 100%;
|
||||
height: 95vh;
|
||||
width: 95vw;
|
||||
height: 90vh;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.handRight {
|
||||
@ -583,7 +620,9 @@
|
||||
border: 4rpx dashed #e9e9e9;
|
||||
flex: 5;
|
||||
overflow: hidden;
|
||||
width: 95vw;
|
||||
box-sizing: border-box;
|
||||
margin: 10px auto 0px auto;
|
||||
}
|
||||
|
||||
.handTitle {
|
||||
@ -597,19 +636,21 @@
|
||||
}
|
||||
|
||||
.handBtn {
|
||||
height: 95vh;
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
height: 10vh;
|
||||
display: flex;
|
||||
/* flex-direction: column; */
|
||||
justify-content: space-between;
|
||||
align-content: space-between;
|
||||
flex: 1;
|
||||
align-content:center;
|
||||
align-items: center;
|
||||
/* flex: 1; */
|
||||
}
|
||||
|
||||
.delBtn {
|
||||
position: absolute;
|
||||
/* position: absolute;
|
||||
top: 250rpx;
|
||||
left: 0rpx;
|
||||
transform: rotate(90deg);
|
||||
transform: rotate(90deg); */
|
||||
height: 35px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
@ -620,16 +661,17 @@
|
||||
}
|
||||
|
||||
.subBtn {
|
||||
position: absolute;
|
||||
/* position: absolute;
|
||||
bottom: 52rpx;
|
||||
left: -3rpx;
|
||||
display: inline-flex;
|
||||
transform: rotate(90deg);
|
||||
transform: rotate(90deg); */
|
||||
background: #008ef6;
|
||||
color: #fff;
|
||||
margin-bottom: 30rpx;
|
||||
/* margin-bottom: 30rpx; */
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
height: 35px;
|
||||
/* justify-content: center; */
|
||||
}
|
||||
|
||||
/*Peach - 新增 - 保存*/
|
||||
@ -651,10 +693,11 @@
|
||||
}
|
||||
|
||||
.undoBtn {
|
||||
position: absolute;
|
||||
/* position: absolute;
|
||||
top: 625rpx;
|
||||
left: 0rpx;
|
||||
transform: rotate(90deg);
|
||||
transform: rotate(90deg); */
|
||||
height: 35px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
|
||||
BIN
static/imgs/word.png
Normal file
BIN
static/imgs/word.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
92
utils/download.js
Normal file
92
utils/download.js
Normal file
@ -0,0 +1,92 @@
|
||||
/**
|
||||
* 下载API返回的PDF文件
|
||||
* @param {Object} apiResponse - 接口返回的数据
|
||||
* @param {boolean} [showLoading=true] - 是否显示加载提示
|
||||
*/
|
||||
import {IMAGE_BASE_URL,BASE_URL} from '@/utils/config';
|
||||
export const downloadPdfFiles = (file, showLoading = true) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
const filesToDownload = [{url:file.url,name:file.name}];
|
||||
|
||||
// 2. 收集需要下载的文件
|
||||
// if (applyPdf) filesToDownload.push({ url: BASE_URL+applyPdf, name: '申请表.docx' });
|
||||
// if (covenantPdf) filesToDownload.push({ url: BASE_URL+covenantPdf, name: '协议书.docx' });
|
||||
|
||||
if (filesToDownload.length === 0) {
|
||||
return reject(new Error('未找到可下载的文件'));
|
||||
}
|
||||
|
||||
// 3. 显示加载提示
|
||||
if (showLoading) {
|
||||
wx.showLoading({
|
||||
title: `正在下载文件(0/${filesToDownload.length})`,
|
||||
mask: true
|
||||
});
|
||||
}
|
||||
|
||||
// 4. 逐个下载文件
|
||||
const downloadedFiles = [];
|
||||
let completedCount = 0;
|
||||
|
||||
const updateProgress = () => {
|
||||
if (showLoading) {
|
||||
wx.showLoading({
|
||||
title: `正在下载文件(${completedCount}/${filesToDownload.length})`,
|
||||
mask: true
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
filesToDownload.forEach((file, index) => {
|
||||
wx.downloadFile({
|
||||
url: file.url,
|
||||
success: (res) => {
|
||||
if (res.statusCode === 200) {
|
||||
downloadedFiles.push({
|
||||
tempPath: res.tempFilePath,
|
||||
name: file.name,
|
||||
});
|
||||
|
||||
// 下载完成后自动打开
|
||||
wx.openDocument({
|
||||
filePath: res.tempFilePath,
|
||||
fileType: 'docx',
|
||||
showMenu: true,// 显示Android分享菜单
|
||||
success: () => {
|
||||
console.log(`${file.name} 打开成功`);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error(`${file.name} 打开失败:`, err);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.error(`${file.name} 下载失败,状态码: ${res.statusCode}`);
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error(`${file.name} 下载失败:`, err);
|
||||
},
|
||||
complete: () => {
|
||||
completedCount++;
|
||||
updateProgress();
|
||||
|
||||
// 全部下载完成
|
||||
if (completedCount === filesToDownload.length) {
|
||||
if (showLoading) wx.hideLoading();
|
||||
|
||||
if (downloadedFiles.length > 0) {
|
||||
resolve({
|
||||
success: true,
|
||||
files: downloadedFiles,
|
||||
message: `成功下载 ${downloadedFiles.length} 个文件`
|
||||
});
|
||||
} else {
|
||||
reject(new Error('所有文件下载失败'));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
27
utils/router.js
Normal file
27
utils/router.js
Normal file
@ -0,0 +1,27 @@
|
||||
// utils/router.js
|
||||
export const navigateTo = (options,isNavigate=true) => {
|
||||
const publicPages = ['/pages/index/index', '/pages/chat/index','/pages/mine/index']; // 不需要登录的页面
|
||||
|
||||
if (publicPages.includes(options.url)) {
|
||||
uni.navigateTo(options);
|
||||
return;
|
||||
}
|
||||
|
||||
const app = getApp();
|
||||
app.checkLogin().then((isLogin) => {
|
||||
if (isLogin) {
|
||||
uni.navigateTo(options);
|
||||
} else {
|
||||
if(isNavigate){
|
||||
uni.redirectTo({
|
||||
url: `/pages/mine/index?redirect=${encodeURIComponent(options.url)}`
|
||||
});
|
||||
}else{
|
||||
uni.showToast({
|
||||
title: '请先登录',
|
||||
icon:"none"
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user