|
@@ -1,414 +0,0 @@
|
|
|
-<template>
|
|
|
- <el-row>
|
|
|
- <el-col :span="3">
|
|
|
- <span style="background-color: #11acf5; color: #fff;">
|
|
|
- <el-icon style="display: inline-block; padding-top: 2.5px;" ><Bottom /></el-icon>
|
|
|
- </span>
|
|
|
- <span>基于原始预算降低(百分比)</span>
|
|
|
- </el-col>
|
|
|
- <el-col :span="3">
|
|
|
- <span style="background-color: #11acf5; color: #fff;">
|
|
|
- <el-icon style="display: inline-block; padding-top: 2.5px;"><Top /></el-icon>
|
|
|
- </span>
|
|
|
- <span>基于原始预算升高(百分比)</span>
|
|
|
- </el-col>
|
|
|
- <el-col :span="3">
|
|
|
- <span style="background-color: #3fd4cf; color: #fff;">
|
|
|
- <el-icon style="display: inline-block; padding-top: 2.5px;"><Bottom /></el-icon>
|
|
|
- </span>
|
|
|
- <span>基于原始预算降低(数值)</span>
|
|
|
- </el-col>
|
|
|
- <el-col :span="3">
|
|
|
- <span style="background-color: #3fd4cf; color: #fff;">
|
|
|
- <el-icon style="display: inline-block; padding-top: 2.5px;"><Top /></el-icon>
|
|
|
- </span>
|
|
|
- <span>基于原始预算升高(数值)</span>
|
|
|
- </el-col>
|
|
|
- <el-col :span="3">
|
|
|
- <span style="background-color: #3359b5; color: #fff;">
|
|
|
- <el-icon style="display: inline-block; padding-top: 2.5px;"></el-icon>
|
|
|
- </span>
|
|
|
- <span>固定预算</span>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- <div class="calendar">
|
|
|
- <table class="calendar-table calendar-table-hour">
|
|
|
- <thead class="calendar-head">
|
|
|
- <tr>
|
|
|
- <th rowspan="8" class="week-td">星期 / 时间</th>
|
|
|
- <th colspan="12">00:00 - 12:00</th>
|
|
|
- <th colspan="12">12:00 - 24:00</th>
|
|
|
- <th colspan="4" rowspan="2" class="week-td" style="display: none">小时</th>
|
|
|
- </tr>
|
|
|
- <tr>
|
|
|
- <th colspan="1" v-for="(_, i) in 24" :key="i">{{ i }}</th>
|
|
|
- </tr>
|
|
|
- </thead>
|
|
|
- <tbody class="calendar-body">
|
|
|
- <template v-for="(hoursList, week) in items">
|
|
|
- <tr>
|
|
|
- <th class="td-normal">{{ WeekMap[week] }}</th>
|
|
|
- <td
|
|
|
- class="un-selected" v-for="(info, hour) in hoursList" :key="hour"
|
|
|
- @mousedown="handleMouseDown(week, hour, $event)"
|
|
|
- @mouseover="handleMouseMove(week, hour)"
|
|
|
- @mouseup="handleMouseUp"
|
|
|
- :style="{ background: getCellBackgroundColor(info) }"
|
|
|
- >
|
|
|
- <!-- <div class="cell-text">
|
|
|
-
|
|
|
- </div> -->
|
|
|
- {{ getCellText(info) }}
|
|
|
- <el-icon v-if="info.kind !=='FixBudget'" style="display: inline-block; padding-top: 2px;">
|
|
|
- <Top v-if="info.kind==='UpPercent'|| info.kind==='UpNumber'"/>
|
|
|
- <Bottom v-if="info.kind==='DownPercent' || info.kind==='DownNumber'"/>
|
|
|
- </el-icon>
|
|
|
- </td>
|
|
|
- </tr>
|
|
|
- </template>
|
|
|
- <tr>
|
|
|
- <th colspan="28" class="clear-bar">
|
|
|
- <span class="middle">可拖动鼠标选择时间段</span>
|
|
|
- <span class="hover-link fr" @click="resetAllBid">全部重置</span>
|
|
|
- </th>
|
|
|
- </tr>
|
|
|
- </tbody>
|
|
|
- </table>
|
|
|
-
|
|
|
- <el-dialog
|
|
|
- v-model="dialogVisible"
|
|
|
- :close-on-click-modal="false"
|
|
|
- title="编辑"
|
|
|
- width="30%"
|
|
|
- :before-close="closeDialog"
|
|
|
- >
|
|
|
- <vxe-form :data="formData" :rules="formRules" ref="formRef" @submit="submitBid" @reset="cancelBid">
|
|
|
- <vxe-form-item field="kind" :span="16">
|
|
|
- <el-select v-model="formData.kind" @change="changeKind" style="width: 100%;">
|
|
|
- <el-option
|
|
|
- v-for="item in KindEnum"
|
|
|
- :key="item.value"
|
|
|
- :label="item.label"
|
|
|
- :value="item.value"
|
|
|
- />
|
|
|
- </el-select>
|
|
|
- </vxe-form-item>
|
|
|
- <vxe-form-item field="value" v-if="formData.kind !== ''" :span="8">
|
|
|
- <vxe-input v-model="formData.value" type="float" size="medium" :min="0" :step="formData.kind==='FixBudget'?1:0.01" v-if="isNumber">
|
|
|
- <template #prefix>$</template>
|
|
|
- </vxe-input>
|
|
|
- <vxe-input v-model="formData.value" type="float" size="medium" :min="0" v-else>
|
|
|
- <template #suffix>%</template>
|
|
|
- </vxe-input>
|
|
|
- </vxe-form-item>
|
|
|
- <vxe-form-item align="right" span="24">
|
|
|
- <template #default>
|
|
|
- <vxe-button type="reset" content="取消"></vxe-button>
|
|
|
- <vxe-button type="submit" status="primary" content="确认"></vxe-button>
|
|
|
- </template>
|
|
|
- </vxe-form-item>
|
|
|
- </vxe-form>
|
|
|
- </el-dialog>
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script lang="ts" setup>
|
|
|
-import { ref, onMounted, watch, Ref } from 'vue'
|
|
|
-import { VXETable, VxeFormInstance, VxeFormPropTypes, VxeFormEvents } from 'vxe-table'
|
|
|
-
|
|
|
-interface Props {
|
|
|
- data: {value: string, kind: string}[][],
|
|
|
-}
|
|
|
-interface FormData {
|
|
|
- kind: string,
|
|
|
- value: string
|
|
|
-}
|
|
|
-const props = defineProps<Props>()
|
|
|
-const emits = defineEmits(["cancelBid"])
|
|
|
-
|
|
|
-const mouseDown = ref(false)
|
|
|
-const startRowIndex = ref(0)
|
|
|
-const startColIndex = ref(0)
|
|
|
-const items = ref([])
|
|
|
-const WeekMap = {
|
|
|
- 0: '星期一',
|
|
|
- 1: '星期二',
|
|
|
- 2: '星期三',
|
|
|
- 3: '星期四',
|
|
|
- 4: '星期五',
|
|
|
- 5: '星期六',
|
|
|
- 6: '星期日'
|
|
|
-}
|
|
|
-const dialogVisible = ref(false)
|
|
|
-const selectedItems = ref({})
|
|
|
-
|
|
|
-const KindEnum = [
|
|
|
- { label: '无需调整预算', value: '' },
|
|
|
- { label: '固定预算', value: 'FixBudget', color: '#3359b5' },
|
|
|
- { label: '基于原始预算降低(百分比)', value: 'DownPercent', color: '#11acf5' },
|
|
|
- { label: '基于原始预算升高(百分比)', value: 'UpPercent', color: '#11acf5' },
|
|
|
- { label: '基于原始预算降低(数值)', value: 'DownNumber', color: '#3fd4cf' },
|
|
|
- { label: '基于原始预算升高(数值)', value: 'UpNumber', color: '#3fd4cf' }
|
|
|
-]
|
|
|
-
|
|
|
-const formData:Ref<FormData> = ref({ kind: 'FixBudget', value: '1.00' })
|
|
|
-const isNumber = ref(true)
|
|
|
-const formRef = ref<VxeFormInstance>()
|
|
|
-const formRules = ref<VxeFormPropTypes.Rules>({
|
|
|
- kind: [
|
|
|
- {
|
|
|
- validator({ itemValue }){
|
|
|
- if (itemValue === undefined || itemValue === null) {
|
|
|
- return new Error('必填项')
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- ],
|
|
|
- value: [
|
|
|
- {
|
|
|
- validator({ itemValue }) {
|
|
|
- if (formData.value.kind === 'FixBudget') {
|
|
|
- if (itemValue < 1) {
|
|
|
- return new Error('固定预算必须大于1')
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (itemValue <= 0) {
|
|
|
- return new Error('数值必须大于0')
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- ]
|
|
|
-})
|
|
|
-
|
|
|
-
|
|
|
-onMounted(() => {
|
|
|
- for (let i = 0; i < 7; i++) {
|
|
|
- selectedItems.value[i] = []
|
|
|
- const tmp = []
|
|
|
- for (let j = 0; j < 24; j++) {
|
|
|
- let kind = ''
|
|
|
- let value = ''
|
|
|
- if (props.data.length !== 0) {
|
|
|
- kind = props.data[i][j].kind
|
|
|
- value = props.data[i][j].value
|
|
|
- }
|
|
|
- tmp.push({ kind: kind, value: value })
|
|
|
- }
|
|
|
- items.value.push(tmp)
|
|
|
- }
|
|
|
-})
|
|
|
-
|
|
|
-watch(props.data, () => {
|
|
|
- for (let i = 0; i < 7; i++) {
|
|
|
- for (let j = 0; j < 24; j++) {
|
|
|
- items.value[i][j].kind = props.data[i][j].kind
|
|
|
- items.value[i][j].value = props.data[i][j].value
|
|
|
- }
|
|
|
- }
|
|
|
-})
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-const changeKind = () => {
|
|
|
- if (formData.value.kind === 'DownPercent' || formData.value.kind === 'UpPercent') {
|
|
|
- isNumber.value = false
|
|
|
- } else {
|
|
|
- isNumber.value = true
|
|
|
- }
|
|
|
- formRef.value.clearValidate('value')
|
|
|
-}
|
|
|
-
|
|
|
-const getCellBackgroundColor = (row: any) => {
|
|
|
- if (row.selected) return '#ccdbff'
|
|
|
- if (row.kind) return KindEnum.find(item => item.value===row.kind).color
|
|
|
- return ''
|
|
|
-}
|
|
|
-
|
|
|
-const getCellText = (row: any) => {
|
|
|
- if (row.kind === 'DownPercent' || row.kind === 'UpPercent') return row.value + '%'
|
|
|
- if (row.value) return '$' + row.value
|
|
|
- return ''
|
|
|
-}
|
|
|
-
|
|
|
-const handleMouseDown = ( rowIndex: number, colIndex: number, event: any ) => {
|
|
|
- if (event.button === 0) {
|
|
|
- mouseDown.value = true
|
|
|
- startRowIndex.value = rowIndex
|
|
|
- startColIndex.value = colIndex
|
|
|
- items.value[rowIndex][colIndex].selected = true
|
|
|
- selectedItems.value[rowIndex].push(colIndex)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-const handleMouseUp = (event: any) => {
|
|
|
- if (event.button === 0) {
|
|
|
- mouseDown.value = false
|
|
|
- startColIndex.value = 0
|
|
|
- startRowIndex.value = 0
|
|
|
- dialogVisible.value = true
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-const handleMouseMove = (rowIndex: number, colIndex: number) => {
|
|
|
- if(mouseDown.value) {
|
|
|
- selectCell(rowIndex, colIndex)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-const selectCell = (rowIndex: number, colIndex: number) => {
|
|
|
- const rowStart = Math.min(startRowIndex.value, rowIndex)
|
|
|
- const rowEnd = Math.max(startRowIndex.value, rowIndex)
|
|
|
- const cellStart = Math.min(startColIndex.value, colIndex)
|
|
|
- const cellEnd = Math.max(startColIndex.value, colIndex)
|
|
|
-
|
|
|
- for (let i = rowStart; i <= rowEnd; i++) {
|
|
|
- for (let j = cellStart; j <= cellEnd; j++) {
|
|
|
- items.value[i][j].selected = true
|
|
|
- selectedItems.value[i].push(j)
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-const submitBid = () => {
|
|
|
- if (formData.value.kind === '') {
|
|
|
- for (const row of Object.keys(selectedItems.value)) {
|
|
|
- for (const col of selectedItems.value[row]) {
|
|
|
- props.data[row][col].kind = ''
|
|
|
- props.data[row][col].value = ''
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- for (const row of Object.keys(selectedItems.value)) {
|
|
|
- for (const col of selectedItems.value[row]) {
|
|
|
- props.data[row][col].kind = formData.value.kind
|
|
|
- props.data[row][col].value = formData.value.value
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- clearSelectedItems()
|
|
|
- clearCellBackgroundColor()
|
|
|
- dialogVisible.value = false
|
|
|
-}
|
|
|
-
|
|
|
-const cancelBid = () => {
|
|
|
- clearSelectedItems()
|
|
|
- clearCellBackgroundColor()
|
|
|
- dialogVisible.value = false
|
|
|
- emits('cancelBid')
|
|
|
-}
|
|
|
-
|
|
|
-const closeDialog = (done: Function) => {
|
|
|
- // console.log("closeDialog")
|
|
|
- cancelBid()
|
|
|
- done()
|
|
|
-}
|
|
|
-
|
|
|
-const clearCellBackgroundColor = () => {
|
|
|
- for (const hoursList of items.value) {
|
|
|
- for (const info of hoursList) {
|
|
|
- info.selected = false
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-const clearSelectedItems = () => {
|
|
|
- for (var i = 0; i < 7; i++) {
|
|
|
- selectedItems.value[i] = []
|
|
|
- }
|
|
|
-}
|
|
|
-const resetAllBid = () => {
|
|
|
- for (let i = 0; i < 7; i++) {
|
|
|
- for (let j = 0; j < 24; j++) {
|
|
|
- items.value[i][j].value = 0
|
|
|
- items.value[i][j].selected = false
|
|
|
- props.data[i][j].kind = ''
|
|
|
- props.data[i][j].value = ''
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-</script>
|
|
|
-
|
|
|
-<style lang="scss" scoped>
|
|
|
-.calendar {
|
|
|
- background-color: #fff;
|
|
|
- -webkit-user-select: none;
|
|
|
- position: relative;
|
|
|
- display: inline-block;
|
|
|
-
|
|
|
- .calendar-table {
|
|
|
- border-collapse: collapse;
|
|
|
- }
|
|
|
-
|
|
|
- .week-td {
|
|
|
- width: 90px;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-table {
|
|
|
- display: table;
|
|
|
- border-collapse: separate;
|
|
|
- box-sizing: border-box;
|
|
|
- text-indent: initial;
|
|
|
- border-spacing: 2px;
|
|
|
- border-color: gray;
|
|
|
-
|
|
|
- thead {
|
|
|
- display: table-header-group;
|
|
|
- vertical-align: middle;
|
|
|
- border-color: inherit;
|
|
|
- }
|
|
|
-
|
|
|
- tr {
|
|
|
- border: 1px solid #e0e5f4;
|
|
|
- font-size: 12px;
|
|
|
- text-align: center;
|
|
|
- line-height: 32px;
|
|
|
- color: rgba(0, 0, 0, 0.5);
|
|
|
-
|
|
|
- th {
|
|
|
- min-width: 40px;
|
|
|
- border: 1px solid #e0e5f4;
|
|
|
- font-size: 12px;
|
|
|
- text-align: center;
|
|
|
- line-height: 32px;
|
|
|
- background: #f7f8fa;
|
|
|
- }
|
|
|
-
|
|
|
- td {
|
|
|
- border: 1px solid #e0e5f4;
|
|
|
- font-size: 12px;
|
|
|
- text-align: center;
|
|
|
- line-height: 32px;
|
|
|
- min-width: 40px;
|
|
|
- cursor: pointer;
|
|
|
- color: #fff;
|
|
|
- &:hover {
|
|
|
- background: #ccdbff;
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.clear-bar {
|
|
|
- line-height: 32px;
|
|
|
- padding: 0 12px;
|
|
|
-
|
|
|
- .hover-link {
|
|
|
- color: #1c6bde;
|
|
|
- cursor: pointer;
|
|
|
- font-size: 13px;
|
|
|
- }
|
|
|
- .fr {
|
|
|
- float: right;
|
|
|
- }
|
|
|
- .middle {
|
|
|
- float: center;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.cell-text {
|
|
|
- color: #fff;
|
|
|
-}
|
|
|
-</style>
|