更新任务日程

This commit is contained in:
weipengfei 2023-08-14 12:05:31 +08:00
parent 77475478d8
commit 5c486b4ee5
4 changed files with 483 additions and 351 deletions

View File

@ -4,6 +4,18 @@ import request from '@/utils/request'
export function apiTaskAdd(params: any) { export function apiTaskAdd(params: any) {
return request.post({ url: '/task_scheduling_plan.task_scheduling_plan/add', params }) return request.post({ url: '/task_scheduling_plan.task_scheduling_plan/add', params })
} }
//修改任务
export function apiTaskEdit(params: any) {
return request.post({ url: '/task_scheduling_plan.task_scheduling_plan/edit', params })
}
//删除任务
export function apiTaskDelete(params: any) {
return request.post({ url: '/task_scheduling_plan.task_scheduling_plan/delete', params })
}
//任务日程-列表 //任务日程-列表
export function apiTaskList(params: any) { export function apiTaskList(params: any) {
return request.get({ url: '/task_scheduling_plan.task_scheduling_plan/lists', params }) return request.get({ url: '/task_scheduling_plan.task_scheduling_plan/lists', params })

View File

@ -1,132 +1,137 @@
<template> <template>
<div class="dialog"> <div class="dialog">
<div class="dialog__trigger" @click="open"> <div class="dialog__trigger" @click="open">
<!-- 触发弹窗 --> <!-- 触发弹窗 -->
<slot name="trigger"></slot> <slot name="trigger"></slot>
</div>
<el-dialog
v-model="visible"
:custom-class="customClass"
:center="center"
:append-to-body="true"
:width="width"
:close-on-click-modal="clickModalClose"
@closed="close"
>
<!-- 弹窗内容 -->
<template v-if="title" #header>{{ title }}</template>
<!-- 自定义内容 -->
<slot>{{ content }}</slot>
<!-- 底部弹窗页脚 -->
<template #footer>
<div class="dialog-footer">
<el-button v-if="cancelButtonText" @click="handleEvent('cancel')">
{{ cancelButtonText }}
</el-button>
<el-button
v-if="confirmButtonText"
type="primary"
@click="handleEvent('confirm')"
>
{{ confirmButtonText }}
</el-button>
</div>
</template>
</el-dialog>
</div> </div>
<el-dialog
v-model="visible"
:custom-class="customClass"
:center="center"
:append-to-body="true"
:width="width"
:close-on-click-modal="clickModalClose"
@closed="close"
>
<!-- 弹窗内容 -->
<template v-if="title" #header>{{ title }}</template>
<!-- 自定义内容 -->
<slot>{{ content }}</slot>
<!-- 底部弹窗页脚 -->
<template v-if="button" #footer>
<div class="dialog-footer">
<el-button v-if="cancelButtonText" @click="handleEvent('cancel')">
{{ cancelButtonText }}
</el-button>
<el-button
v-if="confirmButtonText"
type="primary"
@click="handleEvent('confirm')"
>
{{ confirmButtonText }}
</el-button>
</div>
</template>
</el-dialog>
</div>
</template> </template>
<script lang="ts"> <script lang="ts">
export default defineComponent({ export default defineComponent({
props: { props: {
title: { title: {
// //
type: String, type: String,
default: '' default: "",
},
content: {
//
type: String,
default: ''
},
confirmButtonText: {
//
type: [String, Boolean],
default: '确定'
},
cancelButtonText: {
//
type: [String, Boolean],
default: '取消'
},
width: {
//
type: String,
default: '400px'
},
disabled: {
//
type: Boolean,
default: false
},
async: {
//
type: Boolean,
default: false
},
clickModalClose: {
//
type: Boolean,
default: false
},
center: {
//
type: Boolean,
default: false
},
customClass: {
type: String,
default: ''
}
}, },
emits: ['confirm', 'cancel', 'close', 'open'], button: {
setup(props, { emit }) { //
const visible = ref(false) type: Boolean,
default: true,
},
content: {
//
type: String,
default: "",
},
confirmButtonText: {
//
type: [String, Boolean],
default: "确定",
},
cancelButtonText: {
//
type: [String, Boolean],
default: "取消",
},
width: {
//
type: String,
default: "400px",
},
disabled: {
//
type: Boolean,
default: false,
},
async: {
//
type: Boolean,
default: false,
},
clickModalClose: {
//
type: Boolean,
default: false,
},
center: {
//
type: Boolean,
default: false,
},
customClass: {
type: String,
default: "",
},
},
emits: ["confirm", "cancel", "close", "open"],
setup(props, { emit }) {
const visible = ref(false);
const handleEvent = (type: 'confirm' | 'cancel') => { const handleEvent = (type: "confirm" | "cancel") => {
emit(type) emit(type);
if (!props.async || type === 'cancel') { if (!props.async || type === "cancel") {
close() close();
} }
} };
const close = () => { const close = () => {
visible.value = false visible.value = false;
nextTick(() => { nextTick(() => {
emit('close') emit("close");
}) });
} };
const open = () => { const open = () => {
if (props.disabled) { if (props.disabled) {
return return;
} }
emit('open') emit("open");
visible.value = true visible.value = true;
} };
provide('visible', visible) provide("visible", visible);
return { return {
visible, visible,
handleEvent, handleEvent,
close, close,
open open,
} };
} },
}) });
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.dialog-body { .dialog-body {
white-space: pre-line; white-space: pre-line;
} }
</style> </style>

View File

@ -1,92 +1,199 @@
<template> <template>
<div class="edit-popup"> <div class="edit-popup">
<popup <popup
ref="popupRef" ref="popupRef"
title="创建日程安排" :title="title"
:async="true" :async="true"
width="800px" width="800px"
@confirm="handleSubmit" @confirm="handleSubmit"
@close="handleClose" @close="handleClose"
> :clickModalClose="mode == 'show'"
<el-form class="formdata" :model="detailsdt" label-width="120px"> :button="mode != 'show'"
<el-form-item label="任务日期"> >
<el-date-picker v-model="formData.time" type="date" placeholder="选择日期" /> <el-form
</el-form-item> ref="formRef"
<el-form-item label="任务模板"> :rules="rules"
<el-input class="formdata"
v-model="formData.template_name" :model="formData"
@click="isShow = true" label-width="120px"
clearable >
placeholder="请输入任务模板" <el-form-item required label="任务日期" prop="datetime">
/> <el-date-picker
</el-form-item> :disabled="isDisabled"
</el-form> v-model="formData.datetime"
</popup> name="datetime"
<el-dialog v-model="isShow" title="选择任务" width="60%"> type="daterange"
<DialogIndex @customEvent="customEvent" /> range-separator="至"
</el-dialog> start-placeholder="开始时间"
</div> end-placeholder="结束时间"
@change="changeDateTime"
/>
</el-form-item>
<el-form-item required label="任务模板" prop="template_id">
<el-input
:disabled="isDisabled"
v-model="formData.template_name"
@click="isShow = true"
name="template_id"
clearable
placeholder="请输入任务模板"
/>
</el-form-item>
<el-form-item v-if="mode == 'show'" label="">
<el-button type="primary" @click="clickUpdate"> 修改 </el-button>
<el-button type="danger" @click="clickDelete"> 删除 </el-button>
</el-form-item>
</el-form>
</popup>
<el-dialog v-model="isShow" title="选择任务" width="60%">
<DialogIndex @customEvent="customEvent" />
</el-dialog>
</div>
</template> </template>
<script lang="ts" setup name="taskEidt"> <script lang="ts" setup name="taskEidt">
import type { FormInstance } from 'element-plus' import type { FormInstance, FormRules } from "element-plus";
import Popup from '@/components/popup/index.vue' import Popup from "@/components/popup/index.vue";
import { apiTaskAdd } from '@/api/task' import { apiTaskAdd, apiTaskEdit, apiTaskDelete } from "@/api/task";
import { reactive, onUpdated, type PropType } from 'vue' import { reactive, onUpdated, type PropType } from "vue";
import DialogIndex from '@/views/task_template/list_two.vue' import DialogIndex from "@/views/task_template/list_two.vue";
const route = useRoute() import { timeFormat } from "@/utils/util";
import feedback from "@/utils/feedback";
const route = useRoute();
const emit = defineEmits(['success', 'close']) const emit = defineEmits(["success", "close"]);
const popupRef = shallowRef<InstanceType<typeof Popup>>() const popupRef = shallowRef<InstanceType<typeof Popup>>();
const mode = ref('add') const mode = ref("add");
const detailsdt = ref({}) const detailsdt = ref({});
const isShow = ref(false) const isShow = ref(false);
const title = ref("创建日程安排");
const changeDateTime = (e: any) => {
formData.start_time = timeFormat(e[0]);
formData.end_time = timeFormat(e[1]);
};
// //
const formData = reactive({ const formData = reactive({
time: '', id: "",
template_id: '', create_user_id: "",
scheduling_id: '', status: "",
template_name: '' template_id: "",
}) scheduling_id: "",
function customEvent(data: any) { template_name: "",
isShow.value = false start_time: "",
formData.template_id = data.id end_time: "",
formData.template_name = data.title datetime: "",
} });
if (route.query.id) {
formData.scheduling_id = route.query.id.toString() interface RuleForm {
datetime: Date | String;
template_id: String;
} }
const rules = reactive<FormRules<RuleForm>>({
datetime: { required: true, message: "请选择时间范围", trigger: "blur" },
template_id: {
required: true,
message: "请选择任务模板",
trigger: "change",
},
});
function customEvent(data: any) {
isShow.value = false;
formData.template_id = data.id;
formData.template_name = data.title;
}
if (route.query.id) {
formData.scheduling_id = route.query.id.toString();
}
const formRef = ref(null);
const props = defineProps({
task: {
type: Object,
defualt: () => {
null;
},
},
});
const isDisabled = ref(false);
const updatedForm = async () => {
if (mode.value == "show") {
title.value = "查看日程安排";
isDisabled.value = true;
Object.keys(formData).forEach((key: any) => {
if (props.task[key] != null && props.task[key] != undefined)
formData[key] = props.task[key];
});
formData.datetime = [
formData.start_time.split(" ")[0],
formData.end_time.split(" ")[0],
];
} else {
isDisabled.value = false;
Object.keys(formData).forEach((key: any) => {
formData[key] = "";
});
}
await nextTick();
formRef.value.resetFields();
};
const clickUpdate = () => {
mode.value = "edit";
isDisabled.value = false;
};
//
const clickDelete = () => {
feedback.confirm("确定要删除吗?").then(async (e) => {
if (e == "confirm") {
await apiTaskDelete({ id: formData.id });
popupRef.value?.close();
emit("success");
}
});
};
// //
const handleSubmit = async () => { const handleSubmit = () => {
const data = { ...formData } if (mode.value == "show") return popupRef.value?.close();
console.log(data) else
mode.value == 'edit' ? await apiTaskAdd(data) : await apiTaskAdd(data) formRef.value.validate(async (e: Boolean) => {
popupRef.value?.close() if (e) {
emit('success') const data = { ...formData };
} mode.value == "edit" ? await apiTaskEdit(data) : await apiTaskAdd(data);
popupRef.value?.close();
emit("success");
}
});
};
// //
const open = (type = 'add') => { const open = (type = "add") => {
mode.value = type mode.value = type;
popupRef.value?.open() popupRef.value?.open();
} };
// //
const handleClose = () => { const handleClose = () => {
emit('close') emit("close");
} };
defineExpose({ defineExpose({
open open,
}) updatedForm,
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.formdata { .formdata {
.el-form-item { .el-form-item {
.el-date-picker { .el-date-picker {
width: 100%; width: 100%;
}
} }
}
} }
</style> </style>

View File

@ -1,205 +1,213 @@
<template> <template>
<div> <div>
<el-card class="!border-none" v-loading="loading" shadow="never"> <el-card class="!border-none" v-loading="loading" shadow="never">
<el-button v-perms="['flow_type/add']" type="primary" @click="handleAdd"> <el-button v-perms="['flow_type/add']" type="primary" @click="handleAdd">
<template #icon> <template #icon>
<icon name="el-icon-Plus" /> <icon name="el-icon-Plus" />
</template> </template>
新增 新增
</el-button> </el-button>
<div class="mt-4"> <div class="mt-4">
<el-calendar v-model="dateValue"> <el-calendar v-model="dateValue">
<template #dateCell="{ data }"> <template #dateCell="{ data }">
<div style="width: 100%; height: 100%"> <div style="width: 100%; height: 100%">
<p <p
:class="data.isSelected ? 'is-selected' : ''" :class="data.isSelected ? 'is-selected' : ''"
style="padding: 8px 8px 0 8px" style="padding: 8px 8px 0 8px"
> >
{{ data.day.split('-').slice(1).join('-') }} {{ data.day.split("-").slice(1).join("-") }}
<!-- {{ data.isSelected ? '✔️' : '' }} --> </p>
</p> <div
<div>{{ dateNow(data.day) }}</div> class="task"
<div @click="clickTask(item)"
class="task" v-for="(item, index) in taskListFilter(data.day)"
:class="{ :key="index"
fou: item.priority == 4, >
tow: item.priority == 2, {{ item.template_name }}
the: item.priority == 3 </div>
}"
@click="handleEdit(item)"
v-for="(item, index) in taskList"
:key="index"
>
{{ item.title }}
</div>
</div>
<!-- <div class="task" style="color: var(--el-color-primary);">完成BUG测试</div>
<div class="task" style="color: var(--el-color-danger);">完成BUG测试</div> -->
</template>
</el-calendar>
</div> </div>
</el-card> </template>
</el-calendar>
</div>
</el-card>
<edit-popup <edit-popup
ref="editRef" ref="editRef"
:dict-data="dictData" :dateValue="dateValue"
:dateValue="dateValue" @success="loadTask"
:detailsdata="detailsdata" @close="showEdit = false"
@success="loadTask" />
@close="showEdit = false" <EditTowPopup
/> ref="editTowRef"
<EditTowPopup :task="task"
ref="editTowRef" :type="popupType"
:dict-data="dictData" @success="loadTask"
:dateValue="dateValue" @close="showEditTow = false"
:detailsdata="detailsdata" />
@success="loadTask" </div>
@close="showEditTow = false"
/>
</div>
</template> </template>
<script lang="ts" setup name="task"> <script lang="ts" setup name="task">
import { timeFormat } from '@/utils/util' import { timeFormat } from "@/utils/util";
import feedback from '@/utils/feedback' import feedback from "@/utils/feedback";
// import { getRoutePath } from "router"; // import { getRoutePath } from "router";
import EditPopup from './edit.vue' import EditPopup from "./edit.vue";
import EditTowPopup from './editTow.vue' import EditTowPopup from "./editTow.vue";
import { reactive, watch } from 'vue' import { reactive, watch } from "vue";
import { apiTaskList, apiTaskDetails } from '@/api/task' import { apiTaskList, apiTaskDetails } from "@/api/task";
import { apiTaskSchedulingPlanAdd } from '@/api/task_scheduling_plan' import { apiTaskSchedulingPlanAdd } from "@/api/task_scheduling_plan";
const route = useRoute() const route = useRoute();
const dateValue = ref(new Date()) const dateValue = ref(new Date());
const detailsdata = reactive({ // watch(
create_time: '', // () => dateValue,
create_user_id: 0, // async (newValue, oldValue) => {
delete_time: '', // const id = taskList.value.find(
end_time: '', // (item) =>
extend: '', // item.start_time.split(" ")[0] == timeFormat(newValue.value.getTime())
id: '', // )?.id;
scheduling_id: '', // if (id) {
sn: '', // const res = await apiTaskDetails({ id });
start_time: '', // Object.keys(detailsdata).forEach((key) => {
status: '', // res[key] ? (detailsdata[key] = res[key]) : null;
task_id: '', // });
task_info: { // editRef.value?.open("add");
admin_id: 0, // initShowDate(timeFormat(newValue.value.getTime()));
content: '', // }
create_time: '', // },
delete_time: '', // { deep: true }
id: 0, // );
money: '',
status: 0, //
title: '', const task = ref({
type: 0, create_user_id: 0,
type_name: '', end_time: "",
update_time: '' id: 0,
}, scheduling_id: 0,
template_id: 0, start_time: "",
update_time: '' status: 0,
}) template_id: 0,
watch( template_name: "",
() => dateValue, });
async (newValue, oldValue) => { const popupType = ref("add");
const id = taskList.value.find( const clickTask = (e: any) => {
(item) => item.start_time.split(' ')[0] == timeFormat(newValue.value.getTime()) popupType.value = "show";
)?.id task.value = e;
if (id) { handleSelect();
const res = await apiTaskDetails({ id }) };
Object.keys(detailsdata).forEach((key) => {
res[key] ? (detailsdata[key] = res[key]) : null
})
editRef.value?.open('add')
initShowDate(timeFormat(newValue.value.getTime()))
}
},
{ deep: true }
)
// //
const loading = ref(true) const loading = ref(true);
const editRef = shallowRef<InstanceType<typeof EditPopup>>() const editRef = shallowRef<InstanceType<typeof EditPopup>>();
const editTowRef = shallowRef<InstanceType<typeof EditPopup>>() const editTowRef = shallowRef<InstanceType<typeof EditPopup>>();
// //
const showEdit = ref(false) const showEdit = ref(false);
const showEditTow = ref(false) const showEditTow = ref(false);
// //
const queryParams = reactive({ const queryParams = reactive({
start_time: '', start_time: "",
end_time: '', end_time: "",
page_no: 1, page_no: 1,
pageSize: 150 pageSize: 150,
}) });
const taskList = ref<any>([]) const taskList = ref<any>([]);
// //
const loadTask = async () => { const loadTask = async () => {
apiTaskList(queryParams).then((res) => { apiTaskList(queryParams).then((res) => {
taskList.value = res.lists taskList.value = res.lists;
}) });
loading.value = false loading.value = false;
} };
const start_date = ref('') const start_date = ref("");
const end_date = ref('') const end_date = ref("");
// //
const initShowDate = (dateStr = '') => { const initShowDate = (dateStr = "") => {
const currentDate = dateStr ? new Date(dateStr) : new Date() const currentDate = dateStr ? new Date(dateStr) : new Date();
const currentYear = currentDate.getFullYear() const currentYear = currentDate.getFullYear();
const currentMonth = currentDate.getMonth() const currentMonth = currentDate.getMonth();
const lastDay = new Date(currentYear, currentMonth + 1, 0).getDay() // const lastDay = new Date(currentYear, currentMonth + 1, 0).getDay(); //
const startDay = new Date(currentYear, currentMonth, 1).getDay() // const startDay = new Date(currentYear, currentMonth, 1).getDay(); //
// console.log(new Date(currentYear, currentMonth, 1-startDay).getDate()); // console.log(new Date(currentYear, currentMonth, 1-startDay).getDate());
// console.log(new Date(currentYear, currentMonth + 1, 6-lastDay).getDate()); // console.log(new Date(currentYear, currentMonth + 1, 6-lastDay).getDate());
start_date.value = timeFormat(new Date(currentYear, currentMonth, 1 - startDay).getTime()) // start_date.value = timeFormat(
end_date.value = timeFormat(new Date(currentYear, currentMonth + 1, 6 - lastDay).getTime()) // new Date(currentYear, currentMonth, 1 - startDay).getTime()
if (queryParams.start_time != start_date.value) { ); //
queryParams.start_time = start_date.value end_date.value = timeFormat(
queryParams.end_time = end_date.value new Date(currentYear, currentMonth + 1, 6 - lastDay).getTime()
loading.value = true ); //
loadTask() if (queryParams.start_time != start_date.value) {
} queryParams.start_time = start_date.value;
} queryParams.end_time = end_date.value;
initShowDate() loading.value = true;
const dateNow = (day) => { loadTask();
return taskList.value.find((item) => item.start_time.split(' ')[0] == day)?.template_name }
} };
initShowDate();
//
const taskListFilter = (e: any) => {
return taskList.value
.filter((item: any) => {
let now = new Date(e).getTime() / 1000;
let start = new Date(item.start_time).getTime() / 1000;
let end = new Date(item.end_time).getTime() / 1000;
return now - start >= 0 && now - end <= 0;
})
.slice(0, 5);
};
// //
const handleAdd = async () => { const handleAdd = async () => {
showEditTow.value = true popupType.value = "add";
await nextTick() showEditTow.value = true;
editTowRef.value?.open('add') await nextTick();
} editTowRef.value?.open("add");
editTowRef.value?.updatedForm();
};
//
const handleSelect = async () => {
popupType.value = "show";
showEditTow.value = true;
await nextTick();
editTowRef.value?.open("show");
editTowRef.value?.updatedForm();
};
</script> </script>
<style lang="scss"> <style lang="scss">
.is-selected { .is-selected {
color: #1989fa; color: #1989fa;
} }
.el-calendar-table .el-calendar-day { .el-calendar-table .el-calendar-day {
height: auto; min-height: 8.2rem;
min-height: 6.2rem; padding: 0;
padding: 0;
} }
.task { .task {
font-size: 0.8rem; font-size: 0.8rem;
color: #f7ba2a; /* color: #f7ba2a; */
white-space: nowrap; /* 设置文本不换行 */ color: #1989fa;
overflow: hidden; /* 隐藏溢出的部分 */ padding: 0 8px;
text-overflow: ellipsis; /* 在溢出的部分显示省略号 */ white-space: nowrap; /* 设置文本不换行 */
overflow: hidden; /* 隐藏溢出的部分 */
text-overflow: ellipsis; /* 在溢出的部分显示省略号 */
&:hover {
background-color: rgba($color: #f38200, $alpha: 0.7);
border-radius: 4px;
color: #fff;
}
} }
.the { .the {
color: #ff5100; color: #ff5100;
} }
.tow { .tow {
color: #f38200; color: #f38200;
} }
.fou { .fou {
color: red; color: red;
} }
</style> </style>