|
@@ -35,56 +35,64 @@
|
|
|
<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>
|
|
|
+ <tr>
|
|
|
+ <th class="week-td" rowspan="8">星期 / 时间</th>
|
|
|
+ <th colspan="12">00:00 - 12:00</th>
|
|
|
+ <th colspan="12">12:00 - 24:00</th>
|
|
|
+ <th class="week-td" colspan="4" rowspan="2" style="display: none">小时</th>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <th v-for="(_, i) in 24" :key="i" colspan="1">{{ 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"
|
|
|
+ <template v-for="(hoursList, week) in items">
|
|
|
+ <tr>
|
|
|
+ <th class="td-normal">{{ WeekMap[week] }}</th>
|
|
|
+ <td
|
|
|
v-for="(info, hour) in hoursList"
|
|
|
:key="hour"
|
|
|
+ :style="getTdStyle(info)"
|
|
|
+ class="un-selected"
|
|
|
@mousedown="handleMouseDown(week, hour, $event)"
|
|
|
@mouseover="handleMouseMove(week, hour)"
|
|
|
- @mouseup="handleMouseUp"
|
|
|
- :style="getTdStyle(info)">
|
|
|
- {{ getCellText(info) }}
|
|
|
- <el-icon v-if="info.type !== 'FixBudget'" style="display: inline-block; padding-top: 2px">
|
|
|
- <Top v-if="info.type === 'UpPercent' || info.type === 'UpNumber'" />
|
|
|
- <Bottom v-if="info.type === 'DownPercent' || info.type === 'DownNumber'" />
|
|
|
- </el-icon>
|
|
|
- </td>
|
|
|
- </tr>
|
|
|
- </template>
|
|
|
- <tr>
|
|
|
- <th colspan="28" class="clear-bar">
|
|
|
- <span class="middle">可拖动鼠标选择时间段</span>
|
|
|
- <el-button class="hover-link fr" link @click="resetAllBid" :disabled="disabled">全部重置</el-button>
|
|
|
- </th>
|
|
|
+ @mouseup="handleMouseUp">
|
|
|
+ {{ getCellText(info) }}
|
|
|
+ <el-icon v-if="info.type !== 'FixBudget'" style="display: inline-block; padding-top: 2px">
|
|
|
+ <Top v-if="info.type === 'UpPercent' || info.type === 'UpNumber'" />
|
|
|
+ <Bottom v-if="info.type === 'DownPercent' || info.type === 'DownNumber'" />
|
|
|
+ </el-icon>
|
|
|
+ </td>
|
|
|
</tr>
|
|
|
+ </template>
|
|
|
+ <tr>
|
|
|
+ <th class="clear-bar" colspan="28">
|
|
|
+ <span class="middle">可拖动鼠标选择时间段</span>
|
|
|
+ <el-button :disabled="disabled" class="hover-link fr" link @click="resetAllBid">全部重置</el-button>
|
|
|
+ </th>
|
|
|
+ </tr>
|
|
|
</tbody>
|
|
|
</table>
|
|
|
</div>
|
|
|
|
|
|
- <el-dialog v-model="dialogVisible" :close-on-click-modal="false" title="编辑" width="30%" :before-close="closeDialog" :append-to-body="true">
|
|
|
- <el-form :model="formData" ref="formRef" :inline="true">
|
|
|
- <el-form-item prop="type">
|
|
|
- <el-select v-model="formData.type" @change="changeKind" style="width: 250px">
|
|
|
- <el-option v-for="item in KindEnum" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item prop="value" v-if="formData.type !== ''" :rules="{ validator: checkValue, trigger: 'blur' }">
|
|
|
- <InputFloat v-model="formData.value" :prefix="isNumber ? '$' : ''" :suffix="!isNumber ? '%' : ''" maxlength="111111"></InputFloat>
|
|
|
- </el-form-item>
|
|
|
+ <el-dialog v-model="dialogVisible" :append-to-body="true" :before-close="closeDialog" :close-on-click-modal="false"
|
|
|
+ title="编辑" width="520px">
|
|
|
+ <el-form ref="formRef" :inline="true" :model="formData">
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="16">
|
|
|
+ <el-form-item prop="type">
|
|
|
+ <el-select v-model="formData.type" style="width: 280px" @change="changeKind">
|
|
|
+ <el-option v-for="item in KindEnum" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item v-if="formData.type !== ''" :rules="{ validator: checkValue, trigger: 'blur' }" prop="value">
|
|
|
+ <InputFloat v-model="formData.value" :prefix="isNumber ? '$' : ''" :suffix="!isNumber ? '%' : ''"
|
|
|
+ maxlength="111111"></InputFloat>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
</el-form>
|
|
|
<template #footer>
|
|
|
<div class="dialog-footer">
|
|
@@ -97,24 +105,27 @@
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
-import { ref, onMounted, watch, Ref } from 'vue'
|
|
|
-import InputFloat from '/@/components/input-float/index.vue'
|
|
|
-import XEUtils from 'xe-utils'
|
|
|
+import { ref, Ref, watch } from 'vue';
|
|
|
+import InputFloat from '/@/components/input-float/index.vue';
|
|
|
+import XEUtils from 'xe-utils';
|
|
|
+
|
|
|
|
|
|
interface Props {
|
|
|
- data: { value: string; type: string }[][]
|
|
|
- disabled?: boolean
|
|
|
+ data: { value: string; type: string }[][];
|
|
|
+ disabled?: boolean;
|
|
|
}
|
|
|
+
|
|
|
interface FormData {
|
|
|
- type: string
|
|
|
- value: string
|
|
|
+ type: string;
|
|
|
+ value: string;
|
|
|
}
|
|
|
-const props = defineProps<Props>()
|
|
|
|
|
|
-const mouseDown = ref(false)
|
|
|
-const startRowIndex = ref(0)
|
|
|
-const startColIndex = ref(0)
|
|
|
-const items = ref([])
|
|
|
+const props = defineProps<Props>();
|
|
|
+
|
|
|
+const mouseDown = ref(false);
|
|
|
+const startRowIndex = ref(0);
|
|
|
+const startColIndex = ref(0);
|
|
|
+const items = ref([]);
|
|
|
const WeekMap = {
|
|
|
0: '星期一',
|
|
|
1: '星期二',
|
|
@@ -123,9 +134,9 @@ const WeekMap = {
|
|
|
4: '星期五',
|
|
|
5: '星期六',
|
|
|
6: '星期日',
|
|
|
-}
|
|
|
-const dialogVisible = ref(false)
|
|
|
-const selectedItems = ref({})
|
|
|
+};
|
|
|
+const dialogVisible = ref(false);
|
|
|
+const selectedItems = ref({});
|
|
|
|
|
|
const KindEnum = [
|
|
|
{ label: '无需调整预算', value: '' },
|
|
@@ -134,193 +145,193 @@ const KindEnum = [
|
|
|
{ label: '基于原始预算升高(百分比)', value: 'UpPercent', color: '#11acf5' },
|
|
|
{ label: '基于原始预算降低(数值)', value: 'DownNumber', color: '#3fd4cf' },
|
|
|
{ label: '基于原始预算升高(数值)', value: 'UpNumber', color: '#3fd4cf' },
|
|
|
-]
|
|
|
+];
|
|
|
|
|
|
-const formData: Ref<FormData> = ref({ type: 'FixBudget', value: '1.00' })
|
|
|
-const isNumber = ref(true)
|
|
|
-const formRef = ref()
|
|
|
+const formData: Ref<FormData> = ref({ type: 'FixBudget', value: '1.00' });
|
|
|
+const isNumber = ref(true);
|
|
|
+const formRef = ref();
|
|
|
|
|
|
const checkValue = (rule: any, value: string, callback: any) => {
|
|
|
if (formData.value.type === 'FixBudget') {
|
|
|
if (XEUtils.toNumber(value) < 1) {
|
|
|
- return new Error('固定预算必须大于1')
|
|
|
+ return new Error('固定预算必须大于1');
|
|
|
}
|
|
|
} else {
|
|
|
if (XEUtils.toNumber(value) <= 0) {
|
|
|
- return new Error('数值必须大于0')
|
|
|
+ return new Error('数值必须大于0');
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
+};
|
|
|
|
|
|
for (let i = 0; i < 7; i++) {
|
|
|
- selectedItems.value[i] = []
|
|
|
- const tmp = []
|
|
|
+ selectedItems.value[i] = [];
|
|
|
+ const tmp = [];
|
|
|
for (let j = 0; j < 24; j++) {
|
|
|
- let type = ''
|
|
|
- let value = ''
|
|
|
+ let type = '';
|
|
|
+ let value = '';
|
|
|
if (props.data.length !== 0) {
|
|
|
- type = props.data[i][j].type
|
|
|
- value = props.data[i][j].value
|
|
|
+ type = props.data[i][j].type;
|
|
|
+ value = props.data[i][j].value;
|
|
|
}
|
|
|
- tmp.push({ type, value })
|
|
|
+ tmp.push({ type, value });
|
|
|
}
|
|
|
- items.value.push(tmp)
|
|
|
+ items.value.push(tmp);
|
|
|
}
|
|
|
|
|
|
const getCellBackgroundColor = (row: any) => {
|
|
|
- if (row.selected) return '#ccdbff'
|
|
|
- if (row.type) return KindEnum.find((item) => item.value === row.type).color
|
|
|
- return ''
|
|
|
-}
|
|
|
+ if (row.selected) return '#ccdbff';
|
|
|
+ if (row.type) return KindEnum.find((item) => item.value === row.type).color;
|
|
|
+ return '';
|
|
|
+};
|
|
|
|
|
|
const getTdStyle = (info: any) => {
|
|
|
if (props.disabled) {
|
|
|
- let backgroundColor = ''
|
|
|
+ let backgroundColor = '';
|
|
|
if (info.type) {
|
|
|
- backgroundColor = KindEnum.find((item) => item.value === info.type).color
|
|
|
+ backgroundColor = KindEnum.find((item) => item.value === info.type).color;
|
|
|
} else {
|
|
|
- backgroundColor = '#fff'
|
|
|
+ backgroundColor = '#fff';
|
|
|
}
|
|
|
- return { cursor: 'not-allowed', background: backgroundColor }
|
|
|
+ return { cursor: 'not-allowed', background: backgroundColor };
|
|
|
}
|
|
|
- return { background: getCellBackgroundColor(info) }
|
|
|
-}
|
|
|
+ return { background: getCellBackgroundColor(info) };
|
|
|
+};
|
|
|
|
|
|
watch(
|
|
|
- () => props.data,
|
|
|
- () => {
|
|
|
- // console.log(191, props.data)
|
|
|
- if (props.data.length === 0) {
|
|
|
+ () => props.data,
|
|
|
+ () => {
|
|
|
+ // console.log(191, props.data)
|
|
|
+ if (props.data.length === 0) {
|
|
|
+ for (let i = 0; i < 7; i++) {
|
|
|
+ const tmp = [];
|
|
|
+ for (let j = 0; j < 24; j++) {
|
|
|
+ tmp.push({ type: '', value: '' });
|
|
|
+ }
|
|
|
+ props.data.push(tmp);
|
|
|
+ }
|
|
|
+ }
|
|
|
for (let i = 0; i < 7; i++) {
|
|
|
- const tmp = []
|
|
|
for (let j = 0; j < 24; j++) {
|
|
|
- tmp.push({ type: '', value: '' })
|
|
|
+ items.value[i][j].type = props.data[i][j].type;
|
|
|
+ items.value[i][j].value = props.data[i][j].value;
|
|
|
}
|
|
|
- props.data.push(tmp)
|
|
|
}
|
|
|
- }
|
|
|
- for (let i = 0; i < 7; i++) {
|
|
|
- for (let j = 0; j < 24; j++) {
|
|
|
- items.value[i][j].type = props.data[i][j].type
|
|
|
- items.value[i][j].value = props.data[i][j].value
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- { deep: true, immediate: true }
|
|
|
-)
|
|
|
+ },
|
|
|
+ { deep: true, immediate: true }
|
|
|
+);
|
|
|
|
|
|
const changeKind = () => {
|
|
|
if (formData.value.type === 'DownPercent' || formData.value.type === 'UpPercent') {
|
|
|
- isNumber.value = false
|
|
|
+ isNumber.value = false;
|
|
|
} else {
|
|
|
- isNumber.value = true
|
|
|
+ isNumber.value = true;
|
|
|
}
|
|
|
- formRef.value.clearValidate('value')
|
|
|
-}
|
|
|
+ formRef.value.clearValidate('value');
|
|
|
+};
|
|
|
|
|
|
const getCellText = (row: any) => {
|
|
|
- if (row.type === 'DownPercent' || row.type === 'UpPercent') return row.value + '%'
|
|
|
- if (row.value) return '$' + row.value
|
|
|
- return ''
|
|
|
-}
|
|
|
+ if (row.type === 'DownPercent' || row.type === 'UpPercent') return row.value + '%';
|
|
|
+ if (row.value) return '$' + row.value;
|
|
|
+ return '';
|
|
|
+};
|
|
|
|
|
|
const handleMouseDown = (rowIndex: number, colIndex: number, event: any) => {
|
|
|
- if (props.disabled) return
|
|
|
+ if (props.disabled) return;
|
|
|
if (event.button === 0) {
|
|
|
- mouseDown.value = true
|
|
|
- startRowIndex.value = rowIndex
|
|
|
- startColIndex.value = colIndex
|
|
|
- items.value[rowIndex][colIndex].selected = true
|
|
|
- selectedItems.value[rowIndex].push(colIndex)
|
|
|
+ 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 (props.disabled) return
|
|
|
+ if (props.disabled) return;
|
|
|
if (event.button === 0) {
|
|
|
- mouseDown.value = false
|
|
|
- startColIndex.value = 0
|
|
|
- startRowIndex.value = 0
|
|
|
- dialogVisible.value = true
|
|
|
+ mouseDown.value = false;
|
|
|
+ startColIndex.value = 0;
|
|
|
+ startRowIndex.value = 0;
|
|
|
+ dialogVisible.value = true;
|
|
|
}
|
|
|
-}
|
|
|
+};
|
|
|
|
|
|
const handleMouseMove = (rowIndex: number, colIndex: number) => {
|
|
|
- if (props.disabled) return
|
|
|
+ if (props.disabled) return;
|
|
|
if (mouseDown.value) {
|
|
|
- selectCell(rowIndex, colIndex)
|
|
|
+ selectCell(rowIndex, colIndex);
|
|
|
}
|
|
|
-}
|
|
|
+};
|
|
|
|
|
|
const selectCell = (rowIndex: number, colIndex: number) => {
|
|
|
- if (props.disabled) return
|
|
|
- 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)
|
|
|
+ if (props.disabled) return;
|
|
|
+ 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)
|
|
|
+ items.value[i][j].selected = true;
|
|
|
+ selectedItems.value[i].push(j);
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
+};
|
|
|
|
|
|
const submitBid = () => {
|
|
|
if (formData.value.type === '') {
|
|
|
for (const row of Object.keys(selectedItems.value)) {
|
|
|
for (const col of selectedItems.value[row]) {
|
|
|
- props.data[row][col].type = ''
|
|
|
- props.data[row][col].value = ''
|
|
|
+ props.data[row][col].type = '';
|
|
|
+ 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].type = formData.value.type
|
|
|
- props.data[row][col].value = formData.value.value
|
|
|
+ props.data[row][col].type = formData.value.type;
|
|
|
+ props.data[row][col].value = formData.value.value;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- clearSelectedItems()
|
|
|
- clearCellBackgroundColor()
|
|
|
- dialogVisible.value = false
|
|
|
-}
|
|
|
+ clearSelectedItems();
|
|
|
+ clearCellBackgroundColor();
|
|
|
+ dialogVisible.value = false;
|
|
|
+};
|
|
|
|
|
|
const cancelBid = () => {
|
|
|
- clearSelectedItems()
|
|
|
- clearCellBackgroundColor()
|
|
|
- dialogVisible.value = false
|
|
|
-}
|
|
|
+ clearSelectedItems();
|
|
|
+ clearCellBackgroundColor();
|
|
|
+ dialogVisible.value = false;
|
|
|
+};
|
|
|
|
|
|
const closeDialog = (done: Function) => {
|
|
|
- cancelBid()
|
|
|
- done()
|
|
|
-}
|
|
|
+ cancelBid();
|
|
|
+ done();
|
|
|
+};
|
|
|
|
|
|
const clearCellBackgroundColor = () => {
|
|
|
for (const hoursList of items.value) {
|
|
|
for (const info of hoursList) {
|
|
|
- info.selected = false
|
|
|
+ info.selected = false;
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
+};
|
|
|
const clearSelectedItems = () => {
|
|
|
for (var i = 0; i < 7; i++) {
|
|
|
- selectedItems.value[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].type = ''
|
|
|
- props.data[i][j].value = ''
|
|
|
+ items.value[i][j].value = 0;
|
|
|
+ items.value[i][j].selected = false;
|
|
|
+ props.data[i][j].type = '';
|
|
|
+ props.data[i][j].value = '';
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
+};
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
@@ -376,6 +387,7 @@ table {
|
|
|
line-height: 32px;
|
|
|
min-width: 40px;
|
|
|
color: #fff;
|
|
|
+
|
|
|
&:hover {
|
|
|
background: #ccdbff;
|
|
|
cursor: pointer;
|
|
@@ -393,9 +405,11 @@ table {
|
|
|
font-size: 13px;
|
|
|
margin-top: 7px;
|
|
|
}
|
|
|
+
|
|
|
.fr {
|
|
|
float: right;
|
|
|
}
|
|
|
+
|
|
|
.middle {
|
|
|
float: center;
|
|
|
}
|