| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651 |
- <template>
- <div>
- <el-card>
- <div class="toolbar-wrap">
- <div class="switch-date">
- <div
- class="btn day"
- :class="curSelectedDate == 'd' ? 'actived' : ''"
- @click="selectDate('d')"
- >
- 日
- </div>
- <div
- class="btn week"
- :class="curSelectedDate == 'w' ? 'actived' : ''"
- @click="selectDate('w')"
- >
- 周
- </div>
- <div
- class="btn month"
- :class="curSelectedDate == 'm' ? 'actived' : ''"
- @click="selectDate('m')"
- >
- 月
- </div>
- </div>
- <div class="date-wrap">
- <div class="prev" @click="handlePrev">
- <el-button icon="el-icon-arrow-left" size="small" circle />
- </div>
- <div class="date">
- <el-popover :width="200" placement="top-start" trigger="click">
- <div slot="reference">
- <span class="time">{{ curTime }}</span>
- </div>
- <el-date-picker
- @change="getAppointList"
- style="width: 100%"
- v-model="curTime"
- type="date"
- placeholder="选择日期"
- value-format="yyyy-MM-dd"
- :clearable="false"
- />
- </el-popover>
- <span class="week">{{ WEEKS[moment(curTime).day()] }}</span>
- </div>
- <div class="next" @click="handleNext">
- <el-button icon="el-icon-arrow-right" size="small" circle />
- </div>
- </div>
- </div>
- <div class="table-wrap">
- <el-table :data="appointData" border height="500" style="width: 922px">
- <el-table-column
- type="index"
- width="50"
- align="center"
- ></el-table-column>
- <el-table-column prop="instName" label="仪器名称" min-width="160" />
- <el-table-column
- prop="projectName"
- label="课题组/服务"
- min-width="160"
- >
- <template #default="{ row }">
- <span v-if="row.projectName">{{ row.projectName }}</span>
- <span v-else>{{ row.serviceName }}</span>
- </template>
- </el-table-column>
- <el-table-column prop="startTime" label="开始时间" width="160">
- <template #default="{ row }">
- {{ parseTime(row.startTime, "{y}-{m}-{d}") }}
- </template>
- </el-table-column>
- <el-table-column prop="endTime" label="结束时间" width="160">
- <template #default="{ row }">
- {{ parseTime(row.endTime, "{y}-{m}-{d}") }}
- </template>
- </el-table-column>
- <el-table-column prop="userName" label="预约人" width="140" />
- <el-table-column prop="userContact" label="联系方式" width="160" />
- <el-table-column prop="appointStatus" label="预约状态" width="160">
- <template #default="{ row }">
- {{ setStatus(row.appointStatus) }}
- </template>
- </el-table-column>
- <el-table-column prop="appointStatus" label="违约情况" width="160">
- <template #default="{ row }">
- {{ getBreachTypes(row) }}
- </template>
- </el-table-column>
- <el-table-column prop="breachScore" label="扣分明细" width="160">
- <template #default="{ row }">
- <span>{{ row.breachScore }}分</span>
- </template>
- </el-table-column>
- <el-table-column label="操作" fixed="right" width="160">
- <template #default="{ row }">
- <el-button
- type="primary"
- v-if="row.appointStatus == '10'"
- @click="editAppoint(row)"
- text
- >
- 编辑
- </el-button>
- <el-button
- type="danger"
- v-if="showCancelBtn(row)"
- @click="cancelAppoint(row)"
- text
- >
- 取消
- </el-button>
- </template>
- </el-table-column>
- </el-table>
- </div>
- </el-card>
- </div>
- </template>
- <script>
- import { userCancelAppoint, cancelAppoint } from "@/api/instr";
- import moment from "moment";
- import to from "await-to-js";
- export default {
- name: "UserAppointRecord",
- data() {
- return {
- curSelectedDate: "",
- };
- },
- mounted() {
- this.tabSelect(this.options[0], 0);
- this.curTime = this.getToday();
- this.initChart();
- this.getNotice();
- this.getInstr();
- },
- methods: {
- moment,
- // 獲取當前日期
- getToday() {
- return moment(moment().startOf("day").valueOf()).format("YYYY-MM-DD");
- },
- getYesterday() {
- this.curTime = moment(
- moment(this.curTime).add(-1, "days").startOf("day").valueOf()
- ).format("YYYY-MM-DD");
- },
- getTomorrow() {
- this.curTime = moment(
- moment(this.curTime).add(+1, "days").startOf("day").valueOf()
- ).format("YYYY-MM-DD");
- },
- getPrevWeekDays() {
- this.curTime = moment(this.curTime)
- .subtract(1, "week")
- .format("YYYY-MM-DD");
- },
- getNextWeekDays() {
- this.curTime = moment(this.curTime).add(1, "week").format("YYYY-MM-DD");
- },
- getPrevMonthDays() {
- this.curTime = moment(this.curTime)
- .subtract(1, "months")
- .format("YYYY-MM-DD");
- },
- getNextMonthDays() {
- this.curTime = moment(this.curTime)
- .add(1, "months")
- .format("YYYY-MM-DD");
- },
- getWeekDate() {
- // 获取当前周的周一0点
- var startOfWeek = moment(this.curTime)
- .startOf("isoWeek")
- .format("YYYY-MM-DD HH:mm:ss");
- // 获取下一周的周一0点
- var startOfNextWeek = moment(this.curTime)
- .startOf("isoWeek")
- .add(1, "weeks")
- .format("YYYY-MM-DD HH:mm:ss");
- return [startOfWeek, startOfNextWeek];
- },
- getMonthDate() {
- const date = moment(this.curTime);
- // 获取当前月份的最后一天
- return [
- date.startOf("month").format("YYYY-MM-DD HH:mm:ss"),
- date.endOf("month").add(1, "days").format("YYYY-MM-DD") + " 00:00:00",
- ];
- },
- // 上一周、天、月
- handlePrev() {
- if (this.curSelectedDate == "d") {
- this.getYesterday();
- } else if (this.curSelectedDate == "w") {
- this.getPrevWeekDays();
- } else if (this.curSelectedDate == "m") {
- this.getPrevMonthDays();
- }
- this.getAppointList();
- },
- // 下一周、天、月
- handleNext() {
- if (this.curSelectedDate == "d") {
- this.getTomorrow();
- } else if (this.curSelectedDate == "w") {
- this.getNextWeekDays();
- } else if (this.curSelectedDate == "m") {
- this.getNextMonthDays();
- }
- this.getAppointList();
- },
- selectDate(date) {
- this.curSelectedDate = date;
- this.getAppointList();
- },
- async getAppointList() {
- let startTimeStart = "";
- let startTimeEnd = "";
- if (this.curSelectedDate == "d") {
- startTimeStart = moment(this.curTime).format("YYYY-MM-DD HH:mm:ss");
- startTimeEnd = moment(this.curTime)
- .add(1, "days")
- .format("YYYY-MM-DD HH:mm:ss");
- } else if (this.curSelectedDate == "w") {
- startTimeStart = this.getWeekDate()[0];
- startTimeEnd = this.getWeekDate()[1];
- } else if (this.curSelectedDate == "m") {
- startTimeStart = moment(this.curTime)
- .startOf("month")
- .format("YYYY-MM-DD HH:mm:ss");
- startTimeEnd = this.getMonthDate()[1];
- }
- const [err, res] = await to(
- getInstrListByUser({ startTimeStart, startTimeEnd })
- );
- if (err) return;
- this.appointData = res.data.list;
- },
- setStatus(key) {
- let str = "";
- switch (key) {
- case "10":
- str = "待审核";
- break;
- case "11":
- str = "已退回";
- break;
- case "20":
- str = "已通过";
- break;
- case "30":
- str = "已驳回";
- break;
- case "40":
- str = "已取消";
- break;
- case "50":
- str = "已上机";
- break;
- case "60":
- str = "已完成";
- break;
- case "70":
- str = "审核超时";
- break;
- case "80":
- str = "超时取消";
- break;
- case "90":
- str = "超时未上机";
- break;
- }
- return str;
- },
- getBreachTypes(row) {
- let breachTypes = [];
- if (row.isLate) breachTypes.push("迟到");
- if (row.isOvertime) breachTypes.push("超时");
- if (row.isLeaveEarly) breachTypes.push("早退");
- if (row.isAbsence) breachTypes.push("爽约");
- return breachTypes.join("、") || "-";
- },
- cancelAppoint(row) {
- // 删除附件
- this.$confirm("确认取消预约?", "提示", {
- confirmButtonText: "确认",
- cancelButtonText: "取消",
- type: "warning",
- })
- .then(async () => {
- const post =
- row.userId == props.curUserId
- ? userCancelAppoint({ id: Number(row.id) })
- : cancelAppoint({ id: Number(row.id) });
- const [err] = await to(post);
- if (err) return;
- this.$message.success("取消成功");
- this.getAppointList();
- })
- .catch(() => {});
- },
- editAppoint() {},
- // 选择tab
- tabSelect(row, index) {
- this.active = index;
- this.selectTab = { ...row };
- this.breadList = [...this.routeList, { name: this.selectTab.label }];
- },
- async getNotice() {
- const [err, res] = await to(getNoticeList());
- if (err) return;
- this.noticeList = res.data.list || [];
- },
- async getInstr() {
- const [err, res] = await to(getInstrList({ pageSize: 4, pageNum: 1 }));
- if (err) return;
- this.instrList = res.data.list || [];
- },
- initChart() {
- let chart = echarts.init(document.getElementById("chart"));
- const options = {
- series: [
- {
- type: "gauge",
- startAngle: 180,
- endAngle: 0,
- center: ["50%", "75%"],
- radius: "90%",
- min: 0,
- max: 1,
- splitNumber: 8,
- axisLine: {
- lineStyle: {
- width: 6,
- color: [
- [0.25, "#FF6E76"],
- [0.5, "#FDDD60"],
- [0.75, "#58D9F9"],
- [1, "#7CFFB2"],
- ],
- },
- },
- pointer: {
- icon: "path://M12.8,0.7l12,40.1H0.7L12.8,0.7z",
- length: "12%",
- width: 20,
- offsetCenter: [0, "-60%"],
- itemStyle: {
- color: "auto",
- },
- },
- axisTick: {
- length: 12,
- lineStyle: {
- color: "auto",
- width: 2,
- },
- },
- splitLine: {
- length: 20,
- lineStyle: {
- color: "auto",
- width: 5,
- },
- },
- axisLabel: {
- color: "#464646",
- fontSize: 14,
- distance: -40,
- rotate: "tangential",
- formatter: function (value) {
- if (value === 0.875) {
- return "充足";
- } else if (value === 0.625) {
- return "可控";
- } else if (value === 0.375) {
- return "紧张";
- } else if (value === 0.125) {
- return "危险";
- }
- return "";
- },
- },
- title: {
- offsetCenter: [0, "-10%"],
- fontSize: 14,
- },
- detail: {
- fontSize: 20,
- offsetCenter: [0, "-35%"],
- valueAnimation: true,
- formatter: function (value) {
- return Math.round(value * 100) + "";
- },
- color: "inherit",
- },
- data: [
- {
- value: 0.7,
- name: "危险预算余额",
- },
- ],
- },
- ],
- };
- chart.setOption(options);
- },
- handleDateClick(dateClickInfo) {
- console.log(dateClickInfo);
- },
- },
- };
- </script>
- <style lang="scss" scoped>
- .flex {
- width: 100%;
- flex-wrap: wrap;
- .el-card {
- flex: 0 0 calc(50% - 14px);
- height: 400px;
- ::v-deep .el-card__body {
- padding: 10px;
- height: calc(100% - 79px);
- }
- &.calendar {
- height: 500px;
- ul {
- display: flex;
- flex-direction: column;
- justify-content: space-around;
- height: 130px;
- li {
- font-size: 14px;
- display: flex;
- align-items: center;
- &:before {
- content: "";
- display: inline-block;
- width: 6px;
- height: 6px;
- border-radius: 3px;
- background-color: #a30014;
- margin-right: 4px;
- }
- }
- }
- }
- &.cost {
- height: 300px;
- }
- }
- &.technical .el-card {
- height: auto;
- ::v-deep .el-card__body {
- height: auto;
- }
- }
- }
- .cage-list {
- display: flex;
- flex-wrap: wrap;
- list-style: none;
- li {
- height: 160px;
- width: 221px;
- font-size: 14px;
- border: 1px solid #ebeef5;
- border-radius: 6px;
- display: flex;
- flex-direction: column;
- justify-content: space-around;
- padding: 10px;
- &:nth-child(2n) {
- margin-left: 4px;
- }
- &:nth-child(n + 3) {
- margin-top: 4px;
- }
- header {
- display: flex;
- justify-content: space-between;
- p {
- color: #1d66dc;
- }
- }
- }
- }
- .platform-list {
- height: 100%;
- display: flex;
- flex-direction: column;
- li {
- flex: 1;
- display: flex;
- align-items: center;
- margin: 12px;
- border-radius: 8px;
- overflow: hidden;
- border: 1px solid #ebeef5;
- .text {
- flex: 1;
- height: 100%;
- padding: 12px;
- }
- .btn {
- width: 120px;
- height: 100%;
- color: #fff;
- font-size: 20px;
- background-color: #73b9b9;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: space-around;
- header {
- font-size: 14px;
- }
- .remain-time {
- color: #f56c6c;
- }
- }
- }
- }
- .chart-container {
- display: flex;
- .text {
- flex: 1;
- font-size: 14px;
- display: flex;
- flex-direction: column;
- header {
- color: #1d66dc;
- }
- ul {
- margin-top: 12px;
- flex: 1;
- display: flex;
- flex-direction: column;
- justify-content: space-around;
- }
- li {
- background-color: #e4b5bb;
- border-radius: 4px;
- padding: 4px 8px;
- }
- }
- #chart {
- width: 233px;
- height: 220px;
- }
- }
- .technical {
- p {
- font-size: 16px;
- height: 24px;
- line-height: 24px;
- }
- ul {
- display: flex;
- height: 50px;
- line-height: 50px;
- border-radius: 4px;
- overflow: hidden;
- margin: 20px 0;
- li {
- flex: 1;
- text-align: center;
- background-color: #d9fba5;
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
- &:nth-child(2) {
- background-color: #98ca49;
- }
- &:nth-child(3) {
- background-color: #a4dffa;
- }
- &:nth-child(4) {
- background-color: #48bff4;
- }
- &:nth-child(5) {
- background-color: #b6b6f1;
- }
- &:nth-child(6) {
- background-color: #ebcda7;
- }
- &:nth-child(7) {
- background-color: #f2a4ad;
- }
- }
- }
- }
- .toolbar-wrap {
- height: 30px;
- display: flex;
- justify-content: space-between;
- align-items: center;
- // margin-bottom: 20px;
- .switch-date {
- width: 108px;
- height: 28px;
- border-radius: 2px;
- border: 1px solid #b5c1d8;
- display: flex;
- padding: 4px 6px 0;
- .btn {
- cursor: pointer;
- flex: 1;
- font-size: 13px;
- color: #585858;
- display: flex;
- align-items: center;
- justify-content: center;
- &.actived {
- background: #eef3fe;
- font-weight: bold;
- color: #2c78ff;
- }
- }
- }
- .date-wrap {
- display: flex;
- align-items: center;
- :deep(.el-button--small.is-circle) {
- width: 26px;
- height: 26px;
- }
- .date {
- margin: 0 10px;
- font-size: 14px;
- color: #585858;
- }
- .week {
- color: #2c78ff;
- padding-left: 6px;
- }
- }
- }
- .table-wrap {
- flex: 1;
- margin: 20px 0 0;
- // overflow: hidden;
- }
- </style>
|