|
@@ -0,0 +1,342 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+<a-card
|
|
|
|
|
+ title="计划模板"
|
|
|
|
|
+>
|
|
|
|
|
+<a-row>
|
|
|
|
|
+ <a-col>
|
|
|
|
|
+ <a-button type="primary" @click="openModal">新建模板</a-button>
|
|
|
|
|
+ </a-col>
|
|
|
|
|
+</a-row>
|
|
|
|
|
+<a-table
|
|
|
|
|
+ :loading="state.loading"
|
|
|
|
|
+ style="margin-top: 20px"
|
|
|
|
|
+ :columns="columns"
|
|
|
|
|
+ :dataSource="state.dataSource"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #bodyCell="{ column, record }">
|
|
|
|
|
+ <template v-if="column.key === 'planUse'">
|
|
|
|
|
+ <a-space>
|
|
|
|
|
+ <a-tag :color="planUseMap.get(record.planUse)?.color" >{{planUseMap.get(record.planUse)?.label}}</a-tag>
|
|
|
|
|
+ </a-space>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template v-if="column.key === 'action'">
|
|
|
|
|
+ <a-popconfirm
|
|
|
|
|
+ title="确定要删除这计划吗"
|
|
|
|
|
+ ok-text="Yes"
|
|
|
|
|
+ cancel-text="No"
|
|
|
|
|
+ @confirm="delPlan(record.planNum)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <a :disabled="parseInt(record.planNum) === 0" @click="deletePlan(record.planNum)" >删除</a>
|
|
|
|
|
+ </a-popconfirm>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </a-table>
|
|
|
|
|
+</a-card>
|
|
|
|
|
+
|
|
|
|
|
+<modal-pro
|
|
|
|
|
+ style="width: 800px;"
|
|
|
|
|
+ label="新增工作计划"
|
|
|
|
|
+ :open="state.visible"
|
|
|
|
|
+ @cancel="state.visible = false"
|
|
|
|
|
+ destroyOnClose
|
|
|
|
|
+ @ok="onsubmitSchedule"
|
|
|
|
|
+>
|
|
|
|
|
+ <a-row >
|
|
|
|
|
+ <a-col :span="4">计划名称:</a-col>
|
|
|
|
|
+ <a-col ><a-input v-model:value="state.scheduleName"></a-input></a-col>
|
|
|
|
|
+ </a-row>
|
|
|
|
|
+ <a-row style="margin-top: 20px;" >
|
|
|
|
|
+ <table border="" style="user-select: none;" >
|
|
|
|
|
+ <thead>
|
|
|
|
|
+ <tr>
|
|
|
|
|
+ <td width="100" :rowSpan="2" :colSpan="0" > 星期/时间</td>
|
|
|
|
|
+ <td colSpan="12" style='text-align: center' > 00:00-12:00</td>
|
|
|
|
|
+ <td colSpan="12" style='text-align: center' > 12:00-24:00</td>
|
|
|
|
|
+ </tr>
|
|
|
|
|
+ </thead>
|
|
|
|
|
+ <tbody>
|
|
|
|
|
+ <tr>
|
|
|
|
|
+ <td ></td>
|
|
|
|
|
+ <td
|
|
|
|
|
+ v-for="(item, index) in new Array(24).fill(1)"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ width="25"
|
|
|
|
|
+ :col-span="1"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{index >= 10 ? index: "0" + index}}
|
|
|
|
|
+ </td>
|
|
|
|
|
+ </tr>
|
|
|
|
|
+ <tr
|
|
|
|
|
+ :key="i"
|
|
|
|
|
+ v-for="(item , i) in new Array(7).fill(1)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <th > 星期{{calcWeek(String(i + 1))}} </th>
|
|
|
|
|
+ <td
|
|
|
|
|
+ :col-span="1"
|
|
|
|
|
+ v-for="(item, index) in new Array(24).fill(1)"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ :time="JSON.stringify({
|
|
|
|
|
+ week: String(i + 1),
|
|
|
|
|
+ hour: calcTime(index)
|
|
|
|
|
+ })"
|
|
|
|
|
+ @mousedown="onMouseDown"
|
|
|
|
|
+ @mouseenter="onMouseEnter"
|
|
|
|
|
+ @mouseup="onMouseUp"
|
|
|
|
|
+ style="cursor: pointer"
|
|
|
|
|
+ ></td>
|
|
|
|
|
+ </tr>
|
|
|
|
|
+ </tbody>
|
|
|
|
|
+ </table>
|
|
|
|
|
+ <a-row style="margin-top: 16px; width: 100%" :gutter="[8, 8]" >
|
|
|
|
|
+ <a-col> <a-row> <div style="width: 15px;height: 30px; border: 1px solid #ccc; margin-right: 5px" ></div> 未选</a-row> </a-col>
|
|
|
|
|
+ <a-col> <a-row> <div style="width: 15px;height: 30px; background-color: skyblue; margin-right: 5px" > </div> 已选</a-row> </a-col>
|
|
|
|
|
+ <a-row style="margin-top: 20px; width: 100%" >
|
|
|
|
|
+ <a-col :span="24" :key="item.week" v-for="item in state.selectTime" >
|
|
|
|
|
+ <a-row :gutter="[8, 8]">
|
|
|
|
|
+ <a-col :span="4" >星期{{calcWeek(item.week)}}:</a-col>
|
|
|
|
|
+ <a-col :span="20" >
|
|
|
|
|
+ <a-row :guttr="[8, 2]" >
|
|
|
|
|
+ <a-col v-for="_ in item.desc" :key="_" >{{_}}</a-col>
|
|
|
|
|
+ </a-row>
|
|
|
|
|
+ </a-col>
|
|
|
|
|
+ </a-row>
|
|
|
|
|
+ </a-col>
|
|
|
|
|
+ </a-row>
|
|
|
|
|
+ </a-row>
|
|
|
|
|
+ </a-row>
|
|
|
|
|
+</modal-pro>
|
|
|
|
|
+</template>
|
|
|
|
|
+<script lang='ts' setup >
|
|
|
|
|
+
|
|
|
|
|
+import { PlanController } from '@/controller'
|
|
|
|
|
+import { message } from 'ant-design-vue'
|
|
|
|
|
+import { reactive, onMounted, watch, onUnmounted } from 'vue'
|
|
|
|
|
+
|
|
|
|
|
+const weekMap = new Map([
|
|
|
|
|
+ ['1', '一'],
|
|
|
|
|
+ ['2', '二'],
|
|
|
|
|
+ ['3', '三'],
|
|
|
|
|
+ ['4', '四'],
|
|
|
|
|
+ ['5', '五'],
|
|
|
|
|
+ ['6', '六'],
|
|
|
|
|
+ ['7', '天']
|
|
|
|
|
+])
|
|
|
|
|
+const calcWeek = (week: string) => weekMap.get(week)
|
|
|
|
|
+
|
|
|
|
|
+const calcTime = (index: number) => index < 10 ? '0' + index : index
|
|
|
|
|
+
|
|
|
|
|
+const calcLtTen = (time: number) => time < 10 ? `0${time}` : time
|
|
|
|
|
+
|
|
|
|
|
+const initSelectTime = [
|
|
|
|
|
+ { week: '1', time: [], desc: [], value: '000000000000000000000000' },
|
|
|
|
|
+ { week: '2', time: [], desc: [], value: '000000000000000000000000' },
|
|
|
|
|
+ { week: '3', time: [], desc: [], value: '000000000000000000000000' },
|
|
|
|
|
+ { week: '4', time: [], desc: [], value: '000000000000000000000000' },
|
|
|
|
|
+ { week: '5', time: [], desc: [], value: '000000000000000000000000' },
|
|
|
|
|
+ { week: '6', time: [], desc: [], value: '000000000000000000000000' },
|
|
|
|
|
+ { week: '7', time: [], desc: [], value: '000000000000000000000000' }
|
|
|
|
|
+]
|
|
|
|
|
+
|
|
|
|
|
+const planUseMap = new Map([
|
|
|
|
|
+ [0, { color: 'volcano', label: '未使用' }],
|
|
|
|
|
+ [1, { color: 'green', label: '使用中' }]
|
|
|
|
|
+])
|
|
|
|
|
+
|
|
|
|
|
+const columns = [
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '模版编号',
|
|
|
|
|
+ dataIndex: 'planNum',
|
|
|
|
|
+ key: 'planNum'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '模版状态',
|
|
|
|
|
+ dataIndex: 'planUse',
|
|
|
|
|
+ key: 'planUse'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '模板名称',
|
|
|
|
|
+ dataIndex: 'planName',
|
|
|
|
|
+ key: 'planName'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '模板时间',
|
|
|
|
|
+ dataIndex: 'planTime',
|
|
|
|
|
+ key: 'planTime'
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ title: '操作',
|
|
|
|
|
+ dataIndex: 'action',
|
|
|
|
|
+ key: 'action'
|
|
|
|
|
+ }
|
|
|
|
|
+]
|
|
|
|
|
+
|
|
|
|
|
+const state = reactive({
|
|
|
|
|
+ loading: false,
|
|
|
|
|
+ visible: false,
|
|
|
|
|
+ selectVisible: false, // 是否开始选择
|
|
|
|
|
+ dataSource: [],
|
|
|
|
|
+ selectTime: JSON.parse(JSON.stringify(initSelectTime)),
|
|
|
|
|
+ scheduleName: ''
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+watch(
|
|
|
|
|
+ () => state.selectVisible,
|
|
|
|
|
+ () => {
|
|
|
|
|
+ const $r = state.selectTime.map(item => {
|
|
|
|
|
+ if (!item.time.length) {
|
|
|
|
|
+ item.desc = []
|
|
|
|
|
+ return item
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const sortArr = item.time.sort((a, b) => a - b)
|
|
|
|
|
+
|
|
|
|
|
+ let len = 0
|
|
|
|
|
+
|
|
|
|
|
+ let start = sortArr[len]
|
|
|
|
|
+
|
|
|
|
|
+ const r = [[start]]
|
|
|
|
|
+
|
|
|
|
|
+ let col = 0
|
|
|
|
|
+
|
|
|
|
|
+ const _value = item.value.split('')
|
|
|
|
|
+
|
|
|
|
|
+ _value[Number(start)] = '1'
|
|
|
|
|
+
|
|
|
|
|
+ while (len < sortArr.length - 1) {
|
|
|
|
|
+ if (Number(start) + 1 !== Number(sortArr[len + 1])) {
|
|
|
|
|
+ col++
|
|
|
|
|
+ r.push([])
|
|
|
|
|
+ }
|
|
|
|
|
+ start = sortArr[len + 1]
|
|
|
|
|
+ r[col].push(start)
|
|
|
|
|
+ _value[Number(start)] = '1'
|
|
|
|
|
+
|
|
|
|
|
+ len++
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ item.value = _value.join('')
|
|
|
|
|
+
|
|
|
|
|
+ item.desc = r.map(v => {
|
|
|
|
|
+ const isTwentyThree = Number(v[v.length - 1]) === 23 ? -1 : Number(v[v.length - 1])
|
|
|
|
|
+
|
|
|
|
|
+ if (v.length !== 1) {
|
|
|
|
|
+ return `${calcLtTen(Number(v[0]))}: 00 ~ ${calcLtTen(isTwentyThree + 1)}: 00`
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return `${calcLtTen(Number(v[0]))}: 00 ~ ${calcLtTen(isTwentyThree + 1)}: 00`
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ return item
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ state.selectTime = $r
|
|
|
|
|
+
|
|
|
|
|
+ getPlan().then()
|
|
|
|
|
+ }
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+const deletePlan = async (planNum: number) => {
|
|
|
|
|
+ await PlanController.del(planNum)
|
|
|
|
|
+ getPlan()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const onMouseUp = () => {
|
|
|
|
|
+ state.selectVisible = false
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const onMouseEnter = (e: MouseEvent) => {
|
|
|
|
|
+ if (!state.selectVisible) return
|
|
|
|
|
+ e.target.style.backgroundColor = e.target.style.backgroundColor ? '' : 'skyblue'
|
|
|
|
|
+ const cusAttr = JSON.parse(Array.from(e.target.attributes).find(item => item.name === 'time').nodeValue)
|
|
|
|
|
+ const $r = state.selectTime.map(item => {
|
|
|
|
|
+ if (item.week === cusAttr.week) {
|
|
|
|
|
+ if (e.target.style.backgroundColor) {
|
|
|
|
|
+ item.time.push(cusAttr.hour)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ item.time = item.time.filter(_ => _ !== cusAttr.hour)
|
|
|
|
|
+ }
|
|
|
|
|
+ item.time = Array.from(new Set([...item.time]))
|
|
|
|
|
+ }
|
|
|
|
|
+ return item
|
|
|
|
|
+ })
|
|
|
|
|
+ state.selectTime = $r
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const onMouseDown = (e) => {
|
|
|
|
|
+ const cusAttr = JSON.parse(Array.from(e.target.attributes).find(item => item.name === 'time').nodeValue)
|
|
|
|
|
+
|
|
|
|
|
+ e.target.style.backgroundColor = e.target.style.backgroundColor ? '' : 'skyblue'
|
|
|
|
|
+ const $r = state.selectTime.map(item => {
|
|
|
|
|
+ if (item.week === cusAttr.week) {
|
|
|
|
|
+ if (e.target.style.backgroundColor) {
|
|
|
|
|
+ item.time.push(cusAttr.hour)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ item.time = item.time.filter(_ => _ !== cusAttr.hour)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ item.time = Array.from(new Set([...item.time]))
|
|
|
|
|
+ }
|
|
|
|
|
+ return item
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ state.selectTime = $r
|
|
|
|
|
+ state.selectVisible = true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const onsubmitSchedule = async () => {
|
|
|
|
|
+ if (state.scheduleName === '' || state.scheduleName === undefined) {
|
|
|
|
|
+ message.warn('请填写计划名称')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ const summary = state.selectTime.map((item, index) => item.desc.length ? `星期${calcWeek(String(index + 1))} ${item.desc}` : '').filter(_ => _)
|
|
|
|
|
+
|
|
|
|
|
+ const $par = {
|
|
|
|
|
+ operation: 1,
|
|
|
|
|
+ planName: state.scheduleName,
|
|
|
|
|
+ planTime: JSON.stringify(summary),
|
|
|
|
|
+ planValue: state.selectTime.map((item, index) => item.value).join('')
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ await PlanController.add($par)
|
|
|
|
|
+
|
|
|
|
|
+ state.scheduleName = ''
|
|
|
|
|
+ state.selectTime = JSON.parse(JSON.stringify(initSelectTime))
|
|
|
|
|
+
|
|
|
|
|
+ state.visible = false
|
|
|
|
|
+ getPlan()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const openModal = () => {
|
|
|
|
|
+ state.selectTime = JSON.parse(JSON.stringify(initSelectTime))
|
|
|
|
|
+ state.visible = true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const delPlan = async (planNum: number) => {
|
|
|
|
|
+ await PlanController.del(planNum)
|
|
|
|
|
+ getPlan()
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const getPlan = async () => {
|
|
|
|
|
+ state.loading = true
|
|
|
|
|
+ const { data } = await PlanController.page()
|
|
|
|
|
+ console.log(data)
|
|
|
|
|
+
|
|
|
|
|
+ state.dataSource = data
|
|
|
|
|
+ state.loading = false
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+onUnmounted(() => {
|
|
|
|
|
+ document.removeEventListener('mouseup', () => {})
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+onMounted(() => {
|
|
|
|
|
+ getPlan()
|
|
|
|
|
+
|
|
|
|
|
+ document.addEventListener('mouseup', () => {
|
|
|
|
|
+ state.selectVisible = false
|
|
|
|
|
+ })
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
|
|
+</script>
|
|
|
|
|
+<style lang='less' scoped >
|
|
|
|
|
+</style>
|