Files
supervision-test-frontend-repo/src/views/dq/inspectProblem/DqInspectProblemList.vue
T
new_new_new 6628b68b4c !51 refactor: 提取部门角色ID常量到统一配置文件
* Merge branch 'master' of gitee.com:sz_30/supervision-vue into feature/20260518
* refactor: 提取部门角色ID常量到统一配置文件
* Merge branch 'master' into feature/20260518
* feat(inspectTask): 独立发起流程弹窗,替换党群领导审批组件
* style(inspectProgress): 进展表单对齐BPM表单样式
* style(xispeak): 反馈表单对齐BPM表单样式
* perf(xispeak): 反馈统计查询由逐条请求改为批量接口
* refactor(xispeak): BPM表单和巡视整改表单牵头部门组件替换为SzSelectDept
* style(xispeak): 优化查询表单布局并替换牵头部门选人组件
2026-06-22 06:38:19 +00:00

503 lines
14 KiB
Vue

<template>
<div class="p-2">
<!--查询区域-->
<div class="jeecg-basic-table-form-container">
<a-form @keyup.enter.native="searchQuery" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-row :gutter="24">
<a-col :lg="4" :md="6" :sm="8">
<a-form-item label="年份" name="year">
<JDictSelectTag v-model:value="queryParam.year" dictCode="super_year" placeholder="请选择年份" allow-clear @change="searchQuery" />
</a-form-item>
</a-col>
<a-col :lg="6">
<a-form-item name="problemName">
<template #label><span title="问题名称">问题名称</span></template>
<JInput v-model:value="queryParam.problemName"/>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
<a-col :lg="6">
<a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery">查询</a-button>
<a-button type="primary" preIcon="ant-design:reload-outlined" @click="searchReset" style="margin-left: 8px">重置</a-button>
</a-col>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!--引用表格-->
<BasicTable @register="registerTable" :rowSelection="rowSelection" :expandedRowKeys="expandedRowKeys" @expand="handleExpand" @fetch-success="onFetchSuccess">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" v-auth="'dqinspectproblem:dq_inspect_problem:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
<a-menu-item key="1" @click="batchHandleDelete">
<Icon icon="ant-design:delete-outlined"></Icon>
删除
</a-menu-item>
</a-menu>
</template>
<a-button v-auth="'dqinspectproblem:dq_inspect_problem:deleteBatch'"
>批量操作
<Icon icon="ant-design:down-outlined"></Icon>
</a-button>
</a-dropdown>
<!-- 高级查询 -->
<super-query :config="superQueryConfig" @search="handleSuperQuery" />
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
</template>
<!--字段回显插槽-->
<template v-slot:bodyCell="{ column, record, index, text }">
</template>
</BasicTable>
<!-- 表单区域 -->
<DqInspectProblemModal ref="registerModal" @success="handleSuccess"></DqInspectProblemModal>
</div>
</template>
<script lang="ts" name="dqinspectproblem-dqInspectProblem" setup>
import { ref, reactive, unref } from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { columns, superQuerySchema } from './DqInspectProblem.data';
import {list, deleteDqInspectProblem, batchDeleteDqInspectProblem, getExportUrl,getImportUrl, getChildList,getChildListBatch} from './DqInspectProblem.api';
import { downloadFile } from '/@/utils/common/renderUtils';
import DqInspectProblemModal from './components/DqInspectProblemModal.vue'
import { useMessage } from '/@/hooks/web/useMessage';
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
import JSelectMultiple from '/@/components/Form/src/jeecg/components/JSelectMultiple.vue';
import JSelectDept from '/@/components/Form/src/jeecg/components/JSelectDept.vue';
import JSelectUser from '/@/components/Form/src/jeecg/components/JSelectUser.vue';
import JInput from "/@/components/Form/src/jeecg/components/JInput.vue";
const { createMessage } = useMessage();
const NODE_TYPE_CATEGORY = 'category';
const NODE_TYPE_SURFACE = 'surface';
const NODE_TYPE_SPECIFIC = 'specific';
const expandedRowKeys = ref([]);
const queryParam = ref<any>({});
const toggleSearchStatus = ref<boolean>(false);
const registerModal = ref();
//注册table数据
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
tableProps: {
title: 'dq_inspect_problem',
api: list,
columns,
canResize:false,
useSearchForm: false,
pagination: {
current: 1,
pageSize: 12,
pageSizeOptions: ['12', '24', '36'],
},
isTreeTable: true,
customRow: (record) => {
return {
onClick: (event) => handleRowClick(record, event),
style: {
cursor: hasExpandableChildren(record) ? 'pointer' : 'default',
},
};
},
actionColumn: {
width: 120,
fixed: 'right',
},
beforeFetch: async (params) => {
params.hasQuery = "true";
return Object.assign(params, queryParam.value);
},
},
exportConfig: {
name: "dq_inspect_problem",
url: getExportUrl,
},
importConfig: {
url: getImportUrl,
success: success
},
});
const [registerTable, {reload, collapseAll, updateTableDataRecord, findTableDataRecord,getDataSource},{ rowSelection, selectedRowKeys }] = tableContext
const labelCol = reactive({
xs:24,
sm:4,
xl:6,
xxl:4
});
const wrapperCol = reactive({
xs: 24,
sm: 20,
});
const ROW_CLICK_IGNORE_SELECTOR = [
'a',
'button',
'input',
'textarea',
'select',
'.ant-btn',
'.ant-checkbox-wrapper',
'.ant-dropdown-trigger',
'.ant-table-row-expand-icon',
'.ant-table-selection-column',
'.ant-table-cell-fix-right',
].join(',');
// 高级查询配置
const superQueryConfig = reactive(superQuerySchema);
/**
* 高级查询事件
*/
function handleSuperQuery(params) {
Object.keys(params).map((k) => {
queryParam.value[k] = params[k];
});
reload();
}
/**
* 新增事件
*/
function handleAdd() {
registerModal.value.disableSubmit = false;
registerModal.value.add();
}
/**
* 编辑事件
*/
async function handleEdit(record) {
registerModal.value.disableSubmit = false;
registerModal.value.edit(record);
}
/**
* 详情
*/
async function handleDetail(record) {
registerModal.value.disableSubmit = true;
registerModal.value.edit(record);
}
/**
* 删除事件
*/
async function handleDelete(record) {
await deleteDqInspectProblem({ id: record.id }, success);
}
/**
* 批量删除事件
*/
async function batchHandleDelete() {
const ids = selectedRowKeys.value.filter((item) => !item.includes('loadChild'));
await batchDeleteDqInspectProblem({ id: ids }, success);
}
/**
* 成功回调刷新页面
*/
function success() {
(selectedRowKeys.value = []) && reload();
}
/**
* 添加下级
*/
function handleAddSub(record) {
if (record.nodeType === NODE_TYPE_SPECIFIC) {
createMessage.warning('具体问题下不能新增问题节点');
return;
}
const childNodeType = record.nodeType === NODE_TYPE_CATEGORY ? NODE_TYPE_SURFACE : NODE_TYPE_SPECIFIC;
registerModal.value.disableSubmit = false;
registerModal.value.add({
pid: record.id,
nodeType: childNodeType,
secretLevel: record.secretLevel,
year: record.year,
});
}
/**
* 成功回调
*/
async function handleSuccess({ isUpdate, values, expandedArr, changeParent }) {
if (isUpdate) {
if (changeParent) {
reload();
} else {
let data = await list({ id: values.id, pageSize: 1, pageNo: 1, pid: values['pid'] });
if (data && data.records && data.records.length > 0) {
// 编辑回调
updateTableDataRecord(values.id, data.records[0]);
}else{
updateTableDataRecord(values.id, values);
}
}
} else {
if (!values['id'] || !values['pid']) {
//新增根节点
reload();
} else {
//新增子集
expandedRowKeys.value = [];
for (let key of unref(expandedArr)) {
await expandTreeNode(key);
}
}
}
}
/**
* 接口请求成功后回调
*/
function onFetchSuccess(result) {
getDataByResult(result.items) && loadDataByExpandedRows();
}
/**
* 根据已展开的行查询数据(用于保存后刷新时异步加载子级的数据)
*/
async function loadDataByExpandedRows() {
if (unref(expandedRowKeys).length > 0) {
const res = await getChildListBatch({ parentIds: unref(expandedRowKeys).join(',') });
if (res.success && res.result.records.length > 0) {
//已展开的数据批量子节点
let records = res.result.records;
const listMap = new Map();
for (let item of records) {
let pid = item['pid'];
if (unref(expandedRowKeys).includes(pid)) {
let mapList = listMap.get(pid);
if (mapList == null) {
mapList = [];
}
mapList.push(item);
listMap.set(pid, mapList);
}
}
let childrenMap = listMap;
let fn = (list) => {
if (list) {
list.forEach((data) => {
if (unref(expandedRowKeys).includes(data.id)) {
data.children = getDataByResult(childrenMap.get(data.id));
fn(data.children);
}
});
}
};
fn(getDataSource());
}
}
}
/**
* 处理数据集
*/
function getDataByResult(result) {
if (result && result.length > 0) {
return result.map((item) => {
//判断是否标记了带有子节点
if (item['hasChild'] == '1') {
let loadChild = { id: item.id + '_loadChild', name: 'loading...', isLoading: true };
item.children = [loadChild];
}
return item;
});
}
}
/**
* 行点击展开前先过滤按钮、复选框、展开图标等交互区,避免和原有操作互相触发。
*/
async function handleRowClick(record, event) {
if (!hasExpandableChildren(record) || isInteractiveClick(event)) {
return;
}
if (expandedRowKeys.value.includes(record.id)) {
collapseTreeNode(record);
} else {
await handleExpand(true, record);
}
}
/**
* 判断当前节点是否具备展开能力;loading 占位行和叶子节点不参与行点击切换。
*/
function hasExpandableChildren(record) {
return !!record && !record.isLoading && (record.hasChild == '1' || (record.children && record.children.length > 0));
}
function isInteractiveClick(event) {
const target = event?.target;
return !!target?.closest && !!target.closest(ROW_CLICK_IGNORE_SELECTOR);
}
/**
* 收起当前节点时同步清理已展开子孙节点,避免再次展开时残留旧展开状态。
*/
function collapseTreeNode(record) {
const removeKeys = new Set([record.id]);
collectChildKeys(record.children, removeKeys);
expandedRowKeys.value = expandedRowKeys.value.filter((key) => !removeKeys.has(key));
}
function collectChildKeys(children, keys) {
if (!children || children.length === 0) {
return;
}
children.forEach((child) => {
keys.add(child.id);
collectChildKeys(child.children, keys);
});
}
/**
*树节点展开合并
*/
async function handleExpand(expanded, record) {
// 判断是否是展开状态,展开状态(expanded)并且存在子集(children)并且未加载过(isLoading)的就去查询子节点数据
if (expanded) {
if (!expandedRowKeys.value.includes(record.id)) {
expandedRowKeys.value.push(record.id);
}
if (record.hasChild == '1' && (!record.children || record.children.length === 0 || !!record.children[0].isLoading)) {
let result = await getChildList({ pid: record.id});
result = result.records ? result.records : result;
if (result && result.length > 0) {
record.children = getDataByResult(result);
} else {
record.children = null;
record.hasChild = '0';
}
}
} else {
collapseTreeNode(record);
}
}
/**
* 操作表格后处理树节点展开合并
*/
async function expandTreeNode(key) {
let record = findTableDataRecord(key);
if (!expandedRowKeys.value.includes(key)) {
expandedRowKeys.value.push(key);
}
let result = await getChildList({ pid: key });
if (result && result.length > 0) {
record.children = getDataByResult(result);
} else {
record.children = null;
record.hasChild = '0';
}
updateTableDataRecord(key, record);
}
/**
* 操作栏
*/
function getTableAction(record) {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'dqinspectproblem:dq_inspect_problem:edit'
}
];
}
/**
* 下拉操作栏
*/
function getDropDownAction(record){
return [
{
label: '详情',
onClick: handleDetail.bind(null, record),
},
{
label: '添加下级',
onClick: handleAddSub.bind(null, record),
ifShow: () => record.nodeType !== NODE_TYPE_SPECIFIC,
},
{
label: '删除',
popConfirm: {
title: '确定删除吗?',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
},
auth: 'dqinspectproblem:dq_inspect_problem:delete'
}
];
}
/**
* 查询
*/
function searchQuery() {
reload();
}
/**
* 重置
*/
function searchReset() {
queryParam.value = {};
selectedRowKeys.value = [];
//刷新数据
reload();
}
/**
* form点击事件(以逗号分割)
* @param key
* @param value
*/
function handleFormJoinChange(key, value) {
if (typeof value != 'string') {
queryParam.value[key] = value.join(',');
}
}
</script>
<style lang="less" scoped>
.jeecg-basic-table-form-container {
padding: 0;
.table-page-search-submitButtons {
display: block;
margin-bottom: 24px;
white-space: nowrap;
}
.query-group-cust{
min-width: 100px !important;
}
.query-group-split-cust{
width: 30px;
display: inline-block;
text-align: center
}
.ant-form-item:not(.ant-form-item-with-help){
margin-bottom: 16px;
height: 32px;
}
:deep(.ant-picker),:deep(.ant-input-number){
width: 100%;
}
}
</style>