需求预约日期默认显示当天日期,工位,工位状态和预约时间前端自行过滤,符合条件的高亮显示
<!--
* 维修用料管理-维修领料出库
-->
<template>
<div class="app-container boardManagement">
<div class="card table-search">
<el-form label-width="120" ref="ruleFormRef" :model="formData">
<el-row>
<el-col :span="6">
<el-form-item label="服务工位">
<el-input
placeholder="请输入"
v-model="formData.stationName"
></el-input
></el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="工位状态">
<el-select placeholder="请选择" v-model="formData.stationState">
<el-option label="可预约" value="1" />
<el-option label="不可预约" value="0" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="预约时间">
<div style="display: flex">
<el-time-select
v-model="formData.startTime"
:max-time="formData.endTime"
class="mr-4"
placeholder="请选择"
start="08:30"
step="00:30"
end="17:30"
/>
<div class="horizontal-spread">-</div>
<el-time-select
v-model="formData.endTime"
:min-time="formData.startTime"
placeholder="请选择"
start="09:00"
step="00:30"
end="18:00"
/>
</div>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="6">
<el-form-item label="预约日期" style="width: 100%">
<el-date-picker
value-format="YYYY-MM-DD"
v-model="data.time"
placeholder="请选择"
style="width: 100%"
></el-date-picker
></el-form-item>
</el-col>
<div class="operation">
<el-button
:icon="Search"
color="rgba(169, 127, 229, 1)"
style="color: #fff"
@click="search"
>搜索</el-button
>
<el-button type="info" :icon="Refresh" @click="reset"
>重置</el-button
>
</div>
</el-row>
</el-form>
</div>
<div class="card table-main">
<el-table
:cell-style="cellStyle"
:data="data.timeList"
v-if="isDialog"
max-height="350"
>
<el-table-column prop="time" width="110">
<template #header>
<div style="max-width: 100px; text-align: right">工位</div>
<div style="text-align: left">时间</div>
</template>
</el-table-column>
<template v-for="item in data.stationList" :key="item.prop">
<el-table-column
:prop="item.prop"
:label="item.label"
:align="'center'"
min-width="100"
>
<template #default="scope">
<el-button
link
v-if="scope.row[item.prop].includes('可预约')"
@click="handlePeservate(scope)"
type="primary"
>
可预约</el-button
>
<span v-else> {{ scope.row[item.prop] }}</span>
</template>
</el-table-column>
</template>
</el-table>
<el-table :cell-style="cellStyle" :data="data.timeList" v-else>
<el-table-column prop="time" width="110">
<template #header>
<div style="max-width: 100px; text-align: right">工位</div>
<div style="text-align: left">时间</div>
</template>
</el-table-column>
<template v-for="item in data.stationList" :key="item.prop">
<el-table-column
:prop="item.prop"
:label="item.label"
:align="'center'"
min-width="100"
>
<template #default="scope">
<el-button
link
v-if="scope.row[item.prop].includes('可预约')"
@click="handlePeservate(scope)"
type="primary"
>
可预约</el-button
>
<span v-else> {{ scope.row[item.prop] }}</span>
</template>
</el-table-column>
</template>
</el-table>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, getCurrentInstance } from "vue";
import { useRouter } from "vue-router";
import http from "@/utils/request";
import { useAppStore } from "@/store";
import { Search, Refresh } from "@element-plus/icons-vue";
import { FormInstance, dayjs } from "element-plus";
import _, { includes } from "lodash";
const timeList = [
{ time: "08:30-09:00" },
{ time: "09:00-09:30" },
{ time: "09:30-10:00" },
{ time: "10:00-10:30" },
{ time: "10:30-11:00" },
{ time: "11:00-11:30" },
{ time: "11:30-12:00" },
{ time: "12:00-12:30" },
{ time: "12:30-13:00" },
{ time: "13:00-13:30" },
{ time: "13:30-14:00" },
{ time: "14:00-14:30" },
{ time: "14:30-15:00" },
{ time: "15:00-15:30" },
{ time: "15:30-16:00" },
{ time: "16:00-16:30" },
{ time: "16:30-17:00" },
{ time: "17:00-17:30" },
{ time: "17:30-18:00" },
];
const jisuan = (time1, time2) => {
const times1 = time1.split(":");
const times2 = time2.split(":");
const num1 = Number(times2[0]) - Number(times1[0]);
const num2 = (Number(times2[1]) - Number(times1[1])) / 60;
return num1 + num2 || "";
};
const format = (times1, times2, key) => {
if (!times2) return true;
if (key) {
return jisuan("8:00", times1) >= jisuan("8:00", times2);
} else {
return jisuan("8:00", times1) <= jisuan("8:00", times2);
}
};
const props = withDefaults(
defineProps<{
isDialog?: boolean;
}>(),
{ isDialog: false }
);
const emits = defineEmits<{
(event: "dialogClose", data: object): void;
}>();
let { proxy } = getCurrentInstance();
const cellStyle = ({ row, column, rowIndex, columnIndex }) => {
if (columnIndex === 0) return;
const state = Object.values(row)[columnIndex] === "可预约" ? "1" : "0";
const start = row.time.split("-")[0];
const end = row.time.split("-")[1];
const all = Object.values(data.cloneData).some((item) => item);
if (!all) {
} else {
if (
(column.label.includes(data.cloneData.stationName) ||
data.cloneData.stationName === "") &&
(data.cloneData.stationState === state ||
data.cloneData.stationState === "") &&
format(start, data.cloneData.startTime, true) &&
format(end, data.cloneData.endTime, false)
) {
return { background: "#d6e6ff" };
}
}
};
const data = reactive(<
{
time: string;
stationList: Array<any>;
timeList: Array<any>;
cloneData: any;
}
>{
time: dayjs().format("YYYY-MM-DD"),
stationList: [],
timeList: [],
cloneData: {},
});
const formData = reactive(<
{
stationName: string;
stationState: string;
startTime: string;
endTime: string;
}
>{
stationName: "",
stationState: "",
startTime: "",
endTime: "",
});
const appStore = useAppStore();
const getTableHeader = () => {
http
.post("/maintain/wx/serveStationReservation/getReservationBoardHead", {
id: appStore.titleId ?? "0",
})
.then((res: any) => {
console.log(res);
// 接口返回的格式
res = [
{ label: "钣金2", prop: "bj2" },
{ label: "喷漆1", prop: "pq1" },
{ label: "机修1", prop: "jx1" },
{ label: "机修2", prop: "jx2" },
{ label: "钣金1", prop: "bj1" },
{ label: "保养1", prop: "by1" },
{ label: "保养2", prop: "by2" },
{ label: "保养3", prop: "by3" },
{ label: "机修3", prop: "jx3" },
{ label: "美容1", prop: "mr1" },
{ label: "美容2", prop: "mr2" },
];
data.stationList = res;
getTableList();
if (res.length) {
data.timeList = timeList;
}
data.stationList.forEach((item) => {
data.timeList.forEach((ele) => {
ele[item.prop] = `可预约`;
});
});
});
};
getTableHeader();
const getTableList = async () => {
await http
.post("/maintain/wx/serveStationReservation/getReservationBoard", {
titleId: appStore.titleId ?? "0",
time: data.time,
})
.then((res: any) => {
data.stationList.forEach((item) => {
data.timeList.forEach((ele) => {
ele[item.prop] = `可预约`;
});
});
console.log(res);
// // 接口返回的格式
res = [
{ plateNum: "津AC3553", prop: "by1", time: "10:00-10:30" },
{ plateNum: "鲁Q15685", prop: "bj1", time: "08:30-09:00" },
{ plateNum: "鲁QZ5685", prop: "mr2", time: "11:30-12:00" },
];
res.forEach((item) => {
const curItem = data.timeList.find((ele) => {
return ele.time === `${item.time}`;
});
if (curItem) {
curItem[item.prop] = item.plateNum;
}
});
});
};
const ruleFormRef = ref<FormInstance>();
const search = async () => {
// console.log(formData, data.timeList);
getTableList().then(() => {
data.cloneData = _.cloneDeep(formData);
});
};
const reset = () => {
if (!ruleFormRef.value) return;
ruleFormRef.value.resetFields();
for (let key in formData) {
formData[key] = "";
}
data.time = dayjs().format("YYYY-MM-DD");
getTableList().then(() => {
data.cloneData = _.cloneDeep(formData);
});
};
const router = useRouter();
const goReservateRegistration = (data) => {
// 判断如果是教师端录题,直接加载页面
if (router.currentRoute.value.name === "createTestQuestion") {
router.push({
query: data,
});
proxy.$mitt.emit("teaRecording", "registerbookingDetail");
return;
}
router.push({
name: "registerbookingDetail",
query: data,
});
};
const handlePeservate = (obj) => {
const time = data.time ? data.time : dayjs().format("YYYY-MM-DD");
const params = {
time: `${time} ${obj.row.time}`,
stationName: obj.column.label,
};
if (props.isDialog) {
emits("dialogClose", params);
} else {
goReservateRegistration(params);
}
};
</script>
<style lang="scss" scoped>
.boardManagement {
.table-main {
display: flex;
overflow: hidden;
flex: 1;
flex-direction: column;
width: 100%;
height: 100%;
.scroll {
overflow-y: auto;
}
}
.table-search {
margin-bottom: 10px;
overflow: hidden;
}
.operation {
position: absolute;
right: 0;
}
}
</style>