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.
 
 
 
 
 

561 lines
14 KiB

<template>
<div class="container">
<div class="wrapper">
<div class="title">基本信息</div>
<div class="box">
<div class="formClass">
<div >
<span class="label">任务标题</span> {{formData.title}}
</div>
<div>
<span class="label">任务周期</span> {{formData.startDate}}-{{formData.endDate}}
</div>
<div>
<span class="label">任务状态</span> <dict-tag :type="DICT_TYPE.TASK_STATE" :value="formData.status" />
</div>
<div>
<span class="label">任务类型</span> {{formData.taskTypeName}}
</div>
<div>
<span class="label">通知时间</span> {{ getDictLabel(DICT_TYPE.TASK_NOTICE_TIME, formData.execCycle) }}
</div>
<div>
<span class="label">发布部门</span> {{formData.deptName}}
</div>
<div class="merge">
<span class="label">任务描述</span> {{formData.description}}
</div>
</div>
</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>
</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>
<div class="page">
<!--12-->
<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>
</div>
<CreateEnterprise ref="formCreateRef" @success="getList" />
</template>
<script setup lang="ts">
import { DICT_TYPE, getStrDictOptions, getDictLabel } from '@/utils/dict'
import { TagLibraryApi } from '@/api/system/taglibrary'
import { EnterprisesVO } from '@/api/enterprises'
import { TaskInfoApi } from '@/api/system/taskinfo'
import CreateEnterprise from './createEnterprise.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 formCreateRef = ref()
const { query } = useRoute()
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 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 selectedEnterprises = ref<EnterprisesVO[]>([])
const handleSelectionChange = (selectedItems: EnterprisesVO[]) => {
selectedEnterprises.value = selectedItems
}
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 isTagMatched2 = (hy: string[], tagList?: string[] | null) => {
// 情况1:无筛选条件 => 直接通过
if (!hy?.length) return true;
// 情况2:目标数据无效 => 拒绝
if (!Array.isArray(tagList) || tagList.length === 0) return false;
// 情况3:正常筛选
return hy.some(tag => tagList.includes(tag));
};
const filterList = (list: EnterprisesVO[]) => {
// 1. 快速返回未过滤的完整列表
if (isAllConditionsEmpty.value || !list?.length) {
return enterprise_copy.value.list || [];
}
// 2. 解构查询参数(带默认值避免undefined)
const {
enterprisesName = '',
qy = null,
hy = [],
userId = null
} = enterprise.value.queryParams || {};
// 3. 使用语义化变量名过滤
return list.filter(item => {
const isNameMatched = enterprisesName
? item.enterprisesName?.toLowerCase().includes(enterprisesName.toLowerCase())
: true;
const isRegionMatched = qy
? item.region === qy
: true;
const isTagMatched = isTagMatched2(hy, item.tagList);
const isUserMatched = userId
? item.userId === userId
: true;
return isNameMatched && isRegionMatched && isTagMatched && isUserMatched;
});
};
/** 搜索按钮操作 */
const handleQuery = () => {
const list = filterList(enterprise.value.list)
enterprise.value.list = list
enterprise.value.total = list?.length
}
/** 重置按钮操作 */
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([])
/**
* 获取标签列表
*/
async function getTagList() {
const codeList = 'hy'
const data = await TagLibraryApi.tagLibraryList(codeList)
hyList.value = data[0].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))
}
/**
* 提交表单
*/
//任务二级标签列表
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(3, 1fr);
align-items: center;
row-gap: 40px;
width: 100%;
font-size: 16px;
color: var(--text-color-primary, #303133);
.merge {
grid-column: span 3;
}
.label {
color: var(--text-color-primary, #606266);
margin-right: 12px;
}
.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: flex-end;
font-size: 14px;
}
}
.footer {
text-align: center;
}
}
}
</style>