<template> <div class="container"> <div class="wrapper"> <div class="title">基本信息</div> <div class="box"> <el-form ref="formRef" :model="formData" :rules="formRules" label-width="auto" class="formClass" size="large"> <el-form-item label="任务标题" prop="title"> <el-input v-model="formData.title" placeholder="请输入任务标题" /> </el-form-item> <el-form-item label="任务类型" prop="taskType"> <el-select v-model="formData.taskType" placeholder="请选择任务类型" size="large"> <el-option v-for="dict in tagChildList" :key="dict.id" :label="dict.tagName" :value="dict.id" /> </el-select> </el-form-item> <el-form-item label="描述" prop="description" style="width: 100%; padding: 0; margin-top: 0px;" class="descClass"> <el-input type="textarea" v-model="formData.description" :autosize="{ minRows: 5 }" placeholder="请输入描述" /> </el-form-item> <el-form-item label="时间周期" prop="planTime"> <el-date-picker v-model="formData.planTime" type="daterange" format="YYYY年MM月DD日" range-separator="至" size="large" start-placeholder="选择开始时间" end-placeholder="选择结束时间" value-format="YYYY-MM-DD" /> </el-form-item> <!-- <el-form-item label="执行周期" prop="execCycle" v-if="formData.taskType == 2"> <el-select v-model="formData.execCycle" placeholder="请选择执行周期"> <el-option v-for="dict in getIntDictOptions(DICT_TYPE.TASK_EXEC_TIME)" :key="dict.value" :label="dict.label" :value="dict.value" /> </el-select> </el-form-item> --> <el-form-item label="通知时间" prop="execCycle"> <el-select v-model="formData.execCycle" placeholder="请选择任务选项" > <el-option v-for="dict in getStrDictOptions(DICT_TYPE.TASK_NOTICE_TIME)" :key="dict.value" :label="dict.label" :value="dict.value" /> </el-select> </el-form-item> </el-form> </div> </div> <div class="wrapper-down"> <div class="title">执法范围</div> <div class="box"> <div> <el-select v-model="enterprise.queryParams.qy" placeholder="请选择所属区域" clearable size="large" > <el-option v-for="dict in getStrDictOptions(DICT_TYPE.ENTERPRISES_AREA)" :key="dict.value" :label="dict.label" :value="dict.value" /> </el-select> <el-input v-model="enterprise.queryParams.enterprisesName" placeholder="请输入企业名称" size="large" /> </div> <div> <el-select v-model="enterprise.queryParams.hy" placeholder="请选择行业" clearable size="large" > <el-option v-for="dict in hyList" :key="dict.id" :label="dict.tagName" :value="dict.tagName" /> </el-select> <div class="btn"> <el-button type="primary" plain size="large" @click="handleQuery"> <Icon icon="ep:search" class="mr-5px" /> 查询 </el-button> <el-button @click="resetQuery" class="mr-10px" type="primary" plain size="large"> <Icon icon="ep:refresh" class="mr-5px" /> 重置 </el-button> </div> </div> <div> <el-select v-model="enterprise.queryParams.userId" placeholder="请选择执法人员" size="large" filterable clearable> <el-option v-for="dict in userList" :key="dict.id" :label="dict.deptName +'_'+ dict.realName" :value="dict.id" /> </el-select> <div class="btn2"> <el-button @click="insertEnterprise" type="primary" size="large"> <el-icon><Sort /></el-icon> 筛选企业 </el-button> </div> </div> </div> <div class="table"> <el-table ref="multipleTableRef" @selection-change="handleSelectionChange" :data="paginatedData" row-key="id" :cell-style="{'text-align': 'left'}" :header-cell-style="{ borderBottom: '1px solid #EBEEF5', backgroundColor: '#F5F7FA' }" size="large" > <template #empty> <el-empty description="暂无数据" /> </template> <el-table-column type="selection" width="30" :reserve-selection="true"/> <el-table-column property="enterprisesName" label="企业名称" min-width="100" /> <el-table-column property="region" label="区域"> <template #default="scope"> {{ getStrDictOptions(DICT_TYPE.ENTERPRISES_AREA).find( (dict) => dict.value == scope.row.region )?.label || '未知区域' }} </template> </el-table-column> <el-table-column property="enterprisesName" label="行业"> <template #default="scope"> {{ scope.row.tagListName && scope.row.tagListName .filter((item) => item.value == 1) .map((item) => item.label) .join(', ') }} </template> </el-table-column> <el-table-column property="enterprisesName" label="生态"> <template #default="scope"> {{ scope.row.tagListName && scope.row.tagListName .filter((item) => item.value == 2) .map((item) => item.label) .join(', ') }} </template> </el-table-column> <el-table-column property="enterprisesName" label="类型"> <template #default="scope"> {{ scope.row.tagListName && scope.row.tagListName .filter((item) => item.value == 4) .map((item) => item.label) .join(', ') }} </template> </el-table-column> <el-table-column property="inviterName" label="执法人员" min-width="100" /> <el-table-column label="操作" align="center" min-width="80px"> <template #default="scope"> <el-button link type="primary" @click="handleDelete(scope.row.id)" > 删除 </el-button> </template> </el-table-column> </el-table> <div class="page"> <div class="selected">已选择 {{ selectedEnterprises.length }} / {{ enterprise.total }} <el-button link type="primary" @click="deletedSelected" v-show="selectedEnterprises.length > 0" > 删除所选 </el-button> </div> <div class="page-item"> <el-pagination :total="enterprise.total" :show-page-size="false" size="small" layout="total, prev, pager, next" v-model:current-page="enterprise.queryParams.pageNo" v-model:page-size="enterprise.queryParams.pageSize" class="page" /> </div> </div> </div> <div class="footer"> <el-button type="primary" @click="submitForm(false)" size="large">{{btnTitle}}</el-button> <el-button type="primary" v-if="showButton" @click="submitForm(true)" size="large" v-hasPermi="['system:enterprise-inspections:audit']" >审核通过</el-button > <el-button type="danger" link v-if="formData.status == 0" @click="handleDeleteTask('delete')">删除任务?</el-button> <el-button type="warning" link v-if="formData.status == 2" @click="handleDeleteTask('end')">结束任务?</el-button> <el-button @click="goBack" size="large">返回列表</el-button> </div> </div> </div> <CreateEnterprise ref="formCreateRef" @success="getList" /> </template> <script setup lang="ts"> import { DICT_TYPE, getStrDictOptions } from '@/utils/dict' import { TagLibraryApi } from '@/api/system/taglibrary' import { EnterprisesVO } from '@/api/enterprises' import { TaskInfoApi } from '@/api/system/taskinfo' import { useTagsViewStore } from '@/store/modules/tagsView' import CreateEnterprise from './createEnterprise2.vue' import { cloneDeep } from 'lodash-es'; import { getSimpleUserZGList } from '@/api/system/user' defineOptions({ name: 'CreateTask'}) const formData:any = ref({ id: undefined, title: undefined, description: undefined, execCycle: undefined, taskType: undefined, taskTopType: undefined, priority: undefined, status: undefined, startDate: undefined, endDate: undefined, createBy: undefined, updateBy: undefined, parentId: undefined, parentType: undefined, taskStep: undefined, taskTotal: undefined, planTime: [] as any, tags: [], enterprises: [] as any }) const router = useRouter() const route = useRoute() const tagView = useTagsViewStore() const formCreateRef = ref() const message = useMessage() // 消息弹窗 const formRules = reactive({ title: [{ required: true, message: '任务标题不能为空', trigger: 'blur' }], execCycle: [ { required: true, message: '任务通知时间不能为空', trigger: 'change' } ], taskType: [ { required: true, message: '类型不能为空', trigger: 'change' } ], planTime: [{ required: true, message: '时间周期不能为空', trigger: 'blur' }] }) const { query } = useRoute() const formRef = ref() // 表单 Ref` const enterprise:any = ref({ list: [] as any, queryParams: reactive({ pageNo: 1, pageSize: 10, enterprisesName: undefined, qy: undefined, hy: undefined, st: undefined, wr: undefined, inviterName: undefined, userId: undefined, tagList: [] }), total: ref(0) as any }) const goBack = () => { router.go(-1); // 或 router.back() }; const handleDeleteTask = async (type: string) => { try { if (type == 'delete') { await message.delConfirm("是否确定删除任务!", "删除任务") await TaskInfoApi.deleteTaskInfo(formData.value.id) } else { await message.delConfirm("是否确定结束任务", "结束任务") formData.value.status = 3 await TaskInfoApi.updateTaskInfo(formData.value) } } finally { } } //分页 const paginatedData = computed(() => { const start = (enterprise.value.queryParams.pageNo -1) * enterprise.value.queryParams.pageSize const end = enterprise.value.queryParams.pageNo * enterprise.value.queryParams.pageSize return enterprise.value.list.slice(start, end); // 动态计算分页数据:ml-citation{ref="1,4" data="citationList"} }); //删除所选 const deletedSelected = async () => { await message.delConfirm() selectedEnterprises.value.forEach(item=> { deleteHandle(item.id) }) } const selectedEnterprises = ref<EnterprisesVO[]>([]) const handleSelectionChange = (selectedItems: EnterprisesVO[]) => { selectedEnterprises.value = selectedItems } const handleDelete = async (id: number) => { // 删除的二次确认 await message.delConfirm() // 找到目标索引 deleteHandle(id) } const deleteHandle = (id: number) => { const targetIndex = enterprise.value.list.findIndex(item => item.id === id); if (targetIndex === -1) return; // 删除元素(触发响应式更新) enterprise.value.list.splice(targetIndex, 1) enterprise_copy.value = cloneDeep(enterprise.value) enterprise.value.total = enterprise.value.list.length // 可选:自动调整分页页码(如果当前页数据被删空) const { pageNo, pageSize } = enterprise.value.queryParams; const itemsOnCurrentPage = enterprise.value.list.slice( (pageNo - 1) * pageSize, pageNo * pageSize ) if (itemsOnCurrentPage.length === 0 && pageNo > 1) { enterprise.value.queryParams.pageNo = pageNo - 1; } } const enterprise_copy = ref({ list: [] as any, queryParams: reactive({ pageNo: 1, pageSize: 10, enterprisesName: undefined, qy: undefined, hy: undefined, st: undefined, wr: undefined, userId: undefined }), total: ref(0) as any }) const userList:any = ref() // 检查是否所有条件均为空 const isAllConditionsEmpty = computed(() => { const params = enterprise.value.queryParams; return ( !params.enterprisesName && !params.qy && !params.hy && !params.userId ); }); /** 搜索按钮操作 */ const handleQuery = () => { const list = filterList(enterprise.value.list) enterprise.value.list = list enterprise.value.total = list?.length } // 动态过滤函数 const filterList = (list: EnterprisesVO[]) => { console.log('isAllConditionsEmpty.value', isAllConditionsEmpty.value) if (isAllConditionsEmpty.value) return enterprise_copy.value.list; // 直接返回完整列表 if (list.length > 0) { const { enterprisesName, qy, hy, userId } = enterprise.value.queryParams; return list.filter(item => { if (item.tagList) { // 名称匹配(模糊查询) const nameMatch = enterprisesName ? item.enterprisesName?.toLowerCase().includes(enterprisesName.toLowerCase()) : true; // 类型精确匹配 const typeMatch = qy ? item.region == qy : true; //地区精确匹配 const hyMatch = hy ? item.tagList.includes(hy) : true const userIdMatch = userId ? item.userId == userId : true return nameMatch && typeMatch && hyMatch && userIdMatch; } }); } } const insertEnterprise = () => { formCreateRef.value.open() } /** 重置按钮操作 */ const resetQuery = () => { // queryFormRef.value.resetFields() enterprise.value.queryParams = { pageNo: 1, pageSize: 10, enterprisesName: undefined, qy: undefined, hy: undefined, st: undefined, wr: undefined, userId: undefined } enterprise.value = cloneDeep(enterprise_copy.value); handleQuery() } //行业 const hyList:any = ref([]) //生态 const stList:any = ref([]) //污染程度 const wrList:any = ref([]) /** * 获取标签列表 */ async function getTagList() { const codeList = 'codeList=hy&codeList=st&codeList=wr' const data = await TagLibraryApi.tagLibraryList(codeList) hyList.value = data[0].children stList.value = data[1].children wrList.value = data[2].children } /** * 数组去重 * @param arr * @param uniId 唯一id * @returns */ function uniqueFunc(arr, uniId) { const res = new Map() return arr.filter((item) => !res.has(item[uniId]) && res.set(item[uniId], 1)) } /** * 提交表单 */ async function submitForm(isAudit) { let title:any = '' let content:any = '' if (formData.value.id) { if (isAudit) { title = '审核任务' content = '是否确定审核任务?' } else{ title = '修改任务' content = '是否确定修改任务?' } } else { title = '发布任务' content = '是否确定发布新的任务?' } await message.delConfirm(content, title) const validate = await unref(formRef).validate() if (validate) { //把所有数据转成 id的数组 const data = JSON.parse(JSON.stringify(formData.value)) enterprise.value.list //任务状态默认初始值1 data.status = 0 if (enterprise.value.list.length == 0) { message.success('温馨提示:请您选择执法对象') } else { if (data.status < 2) { data.startDate = data.planTime[0] data.endDate = data.planTime[1] data.enterpriseIds = enterprise.value.list.map(i=>i.id) if (data.id) { if (isAudit) { data.status = 1 } TaskInfoApi.updateTaskInfo(data).then(() => { message.success('操作成功') tagView.delView(route) router.go(-1) }) } else { TaskInfoApi.createTaskInfo(data).then(() => { message.success('操作成功') tagView.delView(route) router.go(-1) }) } } else { message.success('温馨提示:该任务已经执行,无法再进行修改') } } } } //任务二级标签列表 const tagChildList:any = ref([]) async function taskTopQuery() { const data = await TagLibraryApi.childrenList(26) tagChildList.value = data } const showButton = ref(false) const btnTitle = ref('发布任务') async function init() { //执法人员列表 const userData = await getSimpleUserZGList() userList.value = userData //任务类型列表 taskTopQuery() if (query.id) { btnTitle.value = '修改任务' showButton.value = true const res= await TaskInfoApi.getTaskInfo(query.id) formData.value = res //查询标签 const tag = await TagLibraryApi.getTagLibrary(res.taskType) formData.value.taskTopType = tag.parentId formData.value.taskType = tag.id formData.value.taskType = tag.id if (formData.value.execCycle) { formData.value.execCycle = formData.value.execCycle.toString() } formData.value.planTime = [formData.value.startDate, formData.value.endDate] formData.value.enterprises = res.enterpriseIdes formData.value.tags = res.taskTagIdes.map((t) => t.tagId) enterprise.value.list = res.enterpriseIdes enterprise.value.total = res.enterpriseIdes.length //深拷贝一份 enterprise_copy.value = cloneDeep(enterprise.value); } } function getList(data) { const diff = data.filter(item => !enterprise.value.list.includes(item)); // 2. 插入到旧数组前面(合并) enterprise.value.list = [...diff, ...enterprise.value.list]; //去重 enterprise.value.list = uniqueFunc(enterprise.value.list, 'id') enterprise.value.total = enterprise.value.list.length enterprise_copy.value = cloneDeep(enterprise.value); } getTagList() onMounted(() => { init() }) </script> <style scoped lang="scss"> .error-border .el-input__wrapper { /* 错误状态边框 */ box-shadow: 0 0 0 1px var(--el-color-danger) inset; } .container { display: flex; flex-direction: column; gap: 20px; max-width: 100%; .wrapper { display: flex; flex-direction: column; padding: 40px; gap: 40px; background-color: white; .title { font-weight: bold; font-size: 20px; } .box { display: flex; gap: 40px; .formClass { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(2, 1fr); align-items: center; gap: 20px; width: 100%; .descClass { grid-row: span 2; flex: 1 0 0; align-self: stretch; } } } } .wrapper-down{ display: flex; flex-direction: column; padding: 40px; gap: 40px; background-color: white; .title { font-weight: bold; font-size: 20px; } .box { display: flex; gap: 20px; div { // background-color: rgb(206, 175, 175); flex: 1; display: flex; flex-direction: column; gap: 20px; justify-items: center; .btn { display: flex; flex-direction: row; align-items: center; } .btn2 { display: flex; align-items: flex-end; justify-content: center; } } } .table { margin-top: -20px; display: flex; flex-direction: column; gap: 20px; .page{ display: flex; flex-direction: row; justify-content: space-between; font-size: 14px; } } .footer { text-align: center; } } } </style>