You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

761 lines
20 KiB

<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-input
v-model="enterprise.queryParams.enterprisesName"
placeholder="请输入企业名称" size="large"
/>
<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>
<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>
<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.hy"
placeholder="请选择行业列别"
clearable
size="large"
multiple
filterable
>
<el-option
v-for="dict in hyList"
:key="dict.id"
:label="dict.tagName"
:value="dict.tagName"
/>
</el-select>
<div class="btn2">
<el-button @click="insertEnterprise" type="primary" size="large">
<el-icon><Sort /></el-icon> &nbsp; 筛选企业
</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="inviterName" label="执法人员" min-width="100" >
<template #default="scope">
{{scope.row.inviterName}} | {{scope.row.inviterNameDept}}
</template>
</el-table-column>
<el-table-column label="操作" align="left" >
<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" v-if="!formData.status || formData.status == 0 || formData.status == 1" >{{btnTitle}}</el-button>
<el-button
type="primary"
v-if="formData.status == 0"
@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 ? hy.filter(h => item.tagList.includes(h)) : 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>