From 43942a545271345ce26e40d82bb97138c5ea7611 Mon Sep 17 00:00:00 2001 From: jiangping <jp@doumee.com> Date: 星期五, 28 六月 2024 13:54:51 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- admin/src/components/operation/OperCarUseBookParamWindow.vue | 603 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 603 insertions(+), 0 deletions(-) diff --git a/admin/src/components/operation/OperCarUseBookParamWindow.vue b/admin/src/components/operation/OperCarUseBookParamWindow.vue new file mode 100644 index 0000000..d8bc84d --- /dev/null +++ b/admin/src/components/operation/OperCarUseBookParamWindow.vue @@ -0,0 +1,603 @@ +<template> + <GlobalWindow + :title="title" + width="1000px" + :visible.sync="visible" + :confirm-working="isWorking" + @confirm="confirm" + > + <div class="modal_wrap"> + <el-form :model="form" ref="formRef" class="el_form" :rules="rules"> + <el-form-item label="鐢ㄨ溅鑼冨洿" prop="type"> + <el-radio v-model="form.type" style="width: 80px" :label="0" + >甯傚唴鐢ㄨ溅</el-radio + > + <el-radio v-model="form.type" style="width: 80px" :label="1" + >甯傚鐢ㄨ溅</el-radio + > + </el-form-item> + <el-form-item label="閫夋嫨杞﹁締" prop="carId"> + <el-select v-model="form.carId" placeholder="閫夋嫨杞﹁締"> + <el-option + v-for="item in carsList" + :key="item.id" + :label="item.code" + :value="item.id" + > + </el-option> + </el-select> + </el-form-item> + <el-form-item label="鐢ㄨ溅鏃堕棿" prop="startTime"> + <div + v-if="form.startTime && form.endTime" + class="sel_btn text" + @click="openTime" + > + {{ form.startTime }}-{{ form.endTime }} + </div> + <div v-else class="sel_btn" @click="openTime">閫夋嫨鏃堕棿</div> + </el-form-item> + <el-form-item label="棰勮鍑哄彂鏃堕棿" prop="planUseDate"> + <el-date-picker + v-if="form.type == '0'" + :disabled="!form.startTime" + v-model="form.planUseDate" + format="yyyy-MM-dd HH:mm" + value-format="yyyy-MM-dd HH:mm:ss" + :picker-options="pickerOptions" + default-time="08:00:00" + type="datetime" + placeholder="閫夋嫨鏃ユ湡鏃堕棿" + /> + <el-date-picker + v-if="form.type == '1'" + :disabled="!form.startTime" + v-model="form.planUseDate" + format="yyyy-MM-dd HH:mm" + value-format="yyyy-MM-dd HH:mm:ss" + :picker-options="pickerOptions2" + default-time="08:00:00" + type="datetime" + placeholder="閫夋嫨鏃ユ湡鏃堕棿" + /> + </el-form-item> + <el-form-item label="鐩殑鍦�" prop="addr"> + <el-input v-model="form.addr" placeholder="璇疯緭鍏ュ唴瀹�"></el-input> + </el-form-item> + <el-form-item label="涔樿溅浜哄憳" prop="memberIds"> + <el-select + v-model="form.memberIds" + multiple + filterable + placeholder="璇烽�夋嫨" + > + <el-option + v-for="item in memberList" + :key="item.id" + :label="item.name" + :value="item.id" + > + </el-option> + </el-select> + </el-form-item> + <el-form-item label="鐢ㄨ溅浜嬬敱" prop="content"> + <el-input + v-model="form.content" + type="textarea" + placeholder="璇疯緭鍏�" + :rows="4" + ></el-input> + </el-form-item> + </el-form> + <div class="tip_wrap"> + <h1>娉ㄦ剰浜嬮」锛�</h1> + <div>1銆佸叕鍙歌溅杈嗗鍑洪渶鍔炵悊鐢ㄨ溅鐢宠琛紝缁忔壒鍑嗗悗鏂瑰彲澶栧嚭锛堝�熷嚭锛夈��</div> + <div>2銆佸競澶栫敤杞﹂渶棰嗗瀹℃牳銆�</div> + <div> + 3銆佸�熷嚭杞﹁締蹇呴』閬靛畧浜ら�氳鍒欙紝瀹夊叏琛岄┒銆傚浜庤溅杈嗗彂鐢熶氦閫氭剰澶栵紝瀵瑰綋浜嬩汉鍙婄涓夋柟閫犳垚浜鸿韩浼ゅ鍙婃崯澶憋紝鍏徃鍙互鍗忓姪澶勭悊淇濋櫓鍏徃璧斿伩鐩稿叧浜嬪疁锛屼絾涓嶆壙鎷呬换浣曡矗浠诲拰璐圭敤銆� + </div> + <div> + 4銆佸叕鍙稿�熺粰鐢宠浜虹敤杞︼紝鐢宠鍊熻溅浜轰负绗竴璐d换浜猴紝涓嶅厑璁歌浆鍊熺粰鍏朵粬浜轰娇鐢紝鑻ヨ鍊熺粰浠栦汉浣跨敤銆傝矗浠讳汉瑕佹壙鎷呭叏閮ㄨ矗浠汇�� + </div> + </div> + </div> + + <!-- 甯傚唴 --> + <el-dialog + title="閫夋嫨鐢ㄨ溅鏃堕棿" + :visible.sync="isShowTime" + append-to-body + width="600px" + > + <el-form :model="form" ref="modalRef" class="el_form" :rules="rules"> + <el-form-item label="鐢ㄨ溅鏃ユ湡" prop="dateDay"> + <el-date-picker + v-model="form.dateDay" + value-format="yyyy-MM-dd" + type="date" + placeholder="閫夋嫨鏃ユ湡" + :picker-options="{ + disabledDate(time) { + return time.getTime() < Date.now() - 8.64e7; + }, + }" + @change="seletedDate" + > + </el-date-picker> + </el-form-item> + <el-form-item label="鐢ㄨ溅鏃堕棿" prop="dateDay"> + <div> + <div class="time_list"> + <div + class="item" + :class="{ + disable: item.isUse == 1, + active: item.checked == '1', + }" + @click="datetimeClick(item, i)" + v-for="(item, i) in timeList" + :key="i" + > + {{ item.startHours }}-{{ item.endHours }} + </div> + </div> + </div> + </el-form-item> + </el-form> + <div class="color_op"> + <div class="item" v-for="item in colorOptions" :key="item.name"> + <div class="box" :style="{ background: item.color }"></div> + <div class="">{{ item.name }}</div> + </div> + </div> + <span slot="footer" class="dialog-footer"> + <div>宸查�夋嫨锛歿{ selDatetime }}</div> + <div class="btn" @click="subTime">纭鏃堕棿</div> + </span> + </el-dialog> + <!-- 甯傚 --> + <el-dialog + title="閫夋嫨鐢ㄨ溅鏃堕棿" + :visible.sync="isShowShiwai" + append-to-body + width="600px" + > + <el-form :model="form" ref="modalRef" class="el_form" :rules="rules"> + <el-form-item label="鐢ㄨ溅寮�濮嬫椂闂�" prop="startTime"> + <el-date-picker + v-model="form.startTime" + format="yyyy-MM-dd HH:mm" + value-format="yyyy-MM-dd HH:mm:ss" + type="datetime" + :picker-options="pickerOptions" + @change="seletedShiwaiDate" + > + </el-date-picker> + </el-form-item> + <el-form-item label="鐢ㄨ溅缁撴潫鏃堕棿" prop="endTime"> + <el-date-picker + v-model="form.endTime" + format="yyyy-MM-dd HH:mm" + value-format="yyyy-MM-dd HH:mm:ss" + type="datetime" + :picker-options="pickerOptions" + @change="seletedShiwaiDate" + > + </el-date-picker> + </el-form-item> + </el-form> + <div class="have_info" v-if="info && info.length > 0"> + <div class="tit">鎮ㄧ敵璇风殑鐢ㄨ溅鏃舵宸叉湁杞﹁締棰勭害</div> + <div class="content" v-for="(item, i) in info" :key="i"> + <div class="card">{{ item.carCode }}</div> + <div class="line"> + <span>鐢ㄨ溅鏃舵</span> + <span> + {{ item.startTime.slice(5, 16) }}鑷硔{ + item.endTime.slice(5, 16) + }}</span + > + </div> + <div class="line"> + <span>鐩殑鍦�</span> + <span>{{ item.addr }}</span> + </div> + <div class="line"> + <span>涔樿溅浜烘暟</span> + <span>{{ item.memberIds.split(",").length }}浜�</span> + </div> + <div class="line"> + <span>鐢ㄨ溅浜嬬敱</span> + <span>{{ item.content }}</span> + </div> + <div class="line"> + <span>鐢宠浜�</span> + <span>{{ item.memberName }} {{ item.memberMobile }}</span> + </div> + </div> + </div> + + <span slot="footer" class="dialog-footer"> + <div>宸查�夋嫨锛歿{ selDatetime }}</div> + <div class="btn" @click="subTime">纭鏃堕棿</div> + </span> + </el-dialog> + </GlobalWindow> +</template> + +<script> +import BaseOpera from '@/components/base/BaseOpera' +import GlobalWindow from '@/components/common/GlobalWindow' +import { allList } from '@/api/business/member' +import { allList as getCarList } from '@/api/business/cars' +import { carCanReservationDate, carUseBookCraete, carUseBookList } from '@/api/business/carUseBook' +import { findTypeMemberInfo } from '@/api/business/memberCard' +import dayjs from 'dayjs' +export default { + name: 'OperCarUseBookParamWindow', + extends: BaseOpera, + components: { GlobalWindow }, + data() { + return { + // 琛ㄥ崟鏁版嵁 + isShowTime: false, + isShowShiwai: false, + + memberList: [], + timeList: [], + selDatetime: '', + colorOptions: [ + { color: this.$store.state.primaryColor, name: '宸查�夋嫨' }, + { color: '#F7F7F7', name: '鍙绾�' }, + { color: '#cccccc', name: '涓嶅彲棰勭害' } + ], + info: [], + + carsList: [], + form: { + type: 0, + startTime: '', + endTime: '', + memberIds: [] + }, + pickerOptions: { + disabledDate: (time) => { + if (this.form.startTime) { + const minTime = new Date(this.form.startTime).getTime() - 8.64e7 + const maxTime = this.form.endTime ? new Date(this.form.endTime).getTime() : '' + return ( + // maxTime ? time.getTime() < minTime || time.getTime() > maxTime : time.getTime() < minTime + time.getTime() < minTime + ) + } else { + return time.getTime() < Date.now() - 8.64e7 + } + } + }, + pickerOptions2: { + disabledDate: (time) => { + if (this.form.startTime && this.form.endTime) { + const minTime = new Date(this.form.startTime).getTime() + const maxTime = new Date(this.form.endTime).getTime() + return ( + time.getTime() < minTime - 8.64e7 || time.getTime() > maxTime + ) + } else { + return time.getTime() < Date.now() - 8.64e7 + } + }, + selectableRange: '00:00:00 - 23:59:59' + }, + // 楠岃瘉瑙勫垯 + rules: { + type: [{ required: true, message: '璇烽�夋嫨', trigger: 'change' }], + carId: [{ required: true, message: '璇烽�夋嫨', trigger: 'change' }], + startTime: [{ required: true, message: '璇烽�夋嫨', trigger: 'change' }], + endTime: [{ required: true, message: '璇烽�夋嫨', trigger: 'change' }], + planUseDate: [{ required: true, message: '璇烽�夋嫨', trigger: 'change' }], + addr: [{ required: true, message: '璇疯緭鍏�', trigger: 'blur' }], + memberIds: [{ type: 'array', required: true, message: '璇烽�夋嫨', trigger: 'change' }], + content: [{ required: true, message: '璇疯緭鍏�', trigger: 'blur' }] + } + } + }, + computed: { + + }, + watch: { + 'form.planUseDate': { + handler(newValue, oldValue) { + if (newValue) { + this.$set(this.pickerOptions, 'selectableRange', this.form.startTime.slice(11, 19) + ' - ' + this.form.endTime.slice(11, 19)) + // this.startPickerOptions = this.startPickerOptions + } + }, + deep: true, + immediate: true + }, + 'form.startTime': { + handler(newValue, oldValue) { + if (newValue) { + this.$set(this.pickerOptions, 'selectableRange', this.form.startTime.slice(11, 19) + ' - ' + '23:59:59') + // this.startPickerOptions = this.startPickerOptions + } + }, + deep: true, + immediate: true + } + }, + created() { + this.initData() + }, + methods: { + open() { + this.title = '鏂板缓鍏姟杞︾敤杞︾敵璇�' + this.form = { + type: 0, + memberIds: [] + } + this.$nextTick(() => { + this.$refs.formRef.clearValidate() + }) + this.visible = true + }, + confirm() { + const form = JSON.parse(JSON.stringify(this.form)) + this.$refs.formRef.validate((valid) => { + const memberList = [] + form.memberIds.forEach(i => { + this.memberList.forEach(item => { + if (i === item.id) { + memberList.push(item) + } + }) + }) + form.memberNames = memberList.map(i => i.name).join(',') + form.memberList = memberList + form.memberIds = form.memberIds.join(',') + if (valid) { + carUseBookCraete({ + ...form + }).then(res => { + this.visible = false + this.$emit('success') + }) + } + }) + }, + openTime() { + const { form } = this + if (!form.carId) { + return this.$tip.error('璇峰厛閫夋嫨杞﹁締') + } + if (this.form.type === 0) { + this.isShowTime = true + } else { + this.isShowShiwai = true + } + }, + subTime() { + if (this.form.type === 0) { + const selTimeList = this.timeList.filter(i => i.checked == '1') + if (selTimeList.length === 0) { + return this.$tip.error('璇峰厛閫夋嫨鐢ㄨ溅鏃堕棿娈�') + } + this.$set(this.form, 'startTime', selTimeList[0].startTime) + this.$set(this.form, 'endTime', selTimeList[selTimeList.length - 1].endTime) + this.isShowTime = false + this.$set(this.form, 'planUseDate', null) + this.$forceUpdate() + } else { + this.$refs.modalRef.validate((valid) => { + this.isShowShiwai = false + }) + } + }, + datetimeClick(item, index) { + if (item.isUse == '1') return + const { timeList } = this + const selTimeList = timeList.filter(i => i.checked == '1') + if (selTimeList.length === 0) { + this.timeList.forEach((ite, i) => { + if (i === index) { + ite.checked = '1' + this.$forceUpdate() + } + }) + } else { + const findIndex = selTimeList.findIndex(i => i.index === index) + console.log('findIndex', findIndex) + if (findIndex === -1) { + const startNum = index - selTimeList[0].index + const endNum = index - selTimeList[selTimeList.length - 1].index + if (startNum == 1 || startNum == -1 || endNum == 1 || endNum == -1) { + console.log('鐩搁偦') + item.checked = true + this.$forceUpdate() + } else { + return this.$tip.error('璇烽�夋嫨鐩搁偦鐨勬椂闂存') + } + } else { + if (index === selTimeList[0].index || index === selTimeList[selTimeList.length - 1].index) { + item.checked = false + this.$forceUpdate() + } else { + return this.$tip.error('璇峰厛鍙栨秷鏈�澶栧眰鐨勬椂闂存') + } + } + } + const selTimeLists = this.timeList.filter(i => i.checked == '1') + // console.log('selTimeList', selTimeList); + if (selTimeLists.length === 0) { + this.selDatetime = '' + } else { + this.selDatetime = this.form.dateDay.slice(5) + ' ' + selTimeLists[0].startHours + '-' + selTimeLists[selTimeLists.length - 1].endHours + } + }, + seletedDate(e) { + this.gettimes() + }, + seletedShiwaiDate() { + const { form } = this + if (form.startTime && form.endTime) { + this.selDatetime = form.startTime + '-' + form.endTime + carUseBookList({ + carId: form.carId, + startTime: form.startTime, + endTime: form.endTime + }).then(res => { + this.info = res || [] + }) + } + }, + gettimes() { + const { form } = this + carCanReservationDate({ + dateDay: form.dateDay, + carId: form.carId + }).then(res => { + this.timeList = res || [] + this.timeList.forEach((i, j) => { + i.checked = '0', + i.index = j + }) + }) + }, + initData() { + getCarList({ + type: 1 + }).then(res => { + this.carsList = res + }) + findTypeMemberInfo({ + type: '2' + }).then(res => { + this.memberList = res || [] + }) + } + } +} +</script> + +<style scoped lang="scss"> +@import "@/assets/style/variables.scss"; +div { + box-sizing: border-box; +} +.modal_wrap { + display: flex; + padding: 20px 0; + .el_form { + flex: 1; + .sel_btn { + width: 100%; + height: 32px; + border-radius: 4px; + border: 1px solid #dcdfe6; + margin-top: 32px; + text-align: left; + padding-left: 12px; + color: #999999; + padding-right: 12px; + box-sizing: border-box; + cursor: pointer; + } + .text { + color: #606266; + } + } + .tip_wrap { + flex: 1; + margin-left: 30px; + padding: 0 30px; + h1 { + margin-bottom: 20px; + } + div { + line-height: 28px; + } + } +} +.time_list { + display: flex; + justify-content: space-between; + flex-wrap: wrap; + .item { + width: 154px; + height: 32px; + line-height: 32px; + text-align: center; + background: #f7f7f7; + border-radius: 4px; + margin-bottom: 10px; + } + .active { + background-color: $primary-color; + color: #fff; + } + .disable { + background-color: #cccccc; + color: #999999; + } +} +.color_op { + display: flex; + .item { + display: flex; + align-items: center; + margin-right: 10px; + .box { + margin-right: 4px; + width: 16px; + height: 16px; + } + } +} +.dialog-footer { + display: flex; + align-items: center; + justify-content: space-between; + .btn { + height: 42px; + line-height: 42px; + background-color: $primary-color; + color: #fff; + width: 120px; + text-align: center; + } +} +.have_info { + padding: 0 0 60px; + .tit { + color: #ed4545; + margin: 20px 0 12px; + } + .content { + background: #f7f7f7; + border-radius: 8px; + padding: 15px 15px 5px; + margin-bottom: 10px; + .card { + margin-bottom: 15px; + font-weight: 500; + font-size: 16px; + color: #222222; + background: #f7f7f7; + padding: 0; + } + .line { + display: flex; + margin-bottom: 10px; + span { + &:nth-of-type(1) { + width: 80px; + color: #888888; + } + &:nth-of-type(2) { + flex: 1; + } + } + } + } +} +</style> -- Gitblit v1.9.3