Files
supervision-test-frontend-repo/src/views/bg/fixcontact/FixedContact20260730List.vue
T
wsmandClaude Opus 4.7 08ef8f4865 fix(fixcontact): 调整定点联系单页面格式并修复反馈表单组件引用
- 查询筛选列由 xl=4 放宽为 xl=6,解决联系单位/主办部门多选框被遮挡
- 相关分管所领导筛选框改为常驻显示,展开/收起仅控制协办部门
- Form/BPMForm 宽标签列改为 6/18、7/17,避免长标签文字溢出
- FeedbackForm 修复 SzSelectUser 组件导入名并调整 labelCol/wrapperCol
- 新增 FIXCONTACT_CHECKLIST.md 核对说明文档

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-06 10:36:29 +08:00

839 lines
28 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="p-2 erpNativeList">
<!--查询区域-->
<div class="jeecg-basic-table-form-container">
<a-form ref="formRef" @keyup.enter="searchQuery" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-row :gutter="24" class="search-form-row">
<a-col :xl="6" :lg="6" :md="8" :sm="12">
<a-form-item name="formNo">
<template #label>
<a-tooltip title="支持模糊查询">表单编号</a-tooltip>
</template>
<a-tooltip title="支持模糊查询"><JInput v-model:value="queryParam.formNo" type="like" placeholder="请输入表单编号" allow-clear trim @update:value="searchQuery" /></a-tooltip>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="6" :md="8" :sm="12">
<a-form-item name="contactLeader">
<template #label>
<a-tooltip title="按所党委分管所领导筛选">联系所领导</a-tooltip>
</template>
<a-tooltip title="按所党委分管所领导筛选">
<DeptRoleUserSelectDropDown
v-model:value="queryParam.contactLeader"
:deptId="PARTY_COMMITTEE_DEPT_ID"
:roleId="CHARGE_LEADER_ROLE_ID"
placeholder="请选择"
allow-clear
style="width: 100%"
@change="searchQuery"
/>
</a-tooltip>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="6" :md="8" :sm="12">
<a-form-item name="contactDept">
<template #label>
<a-tooltip title="按联系单位筛选">联系单位</a-tooltip>
</template>
<a-tooltip title="按联系单位筛选"><SzSelectDept v-model:value="queryParam.contactDept" placeholder="请选择" allow-clear style="width: 100%" @change="searchQuery" /></a-tooltip>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="6" :md="8" :sm="12">
<a-form-item name="hostDept">
<template #label>
<a-tooltip title="按主办部门筛选">主办部门</a-tooltip>
</template>
<a-tooltip title="按主办部门筛选"><SzSelectDept v-model:value="queryParam.hostDept" placeholder="请选择" allow-clear style="width: 100%" @change="searchQuery" /></a-tooltip>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="6" :md="8" :sm="12">
<a-form-item name="relatedLeader">
<template #label>
<a-tooltip title="按相关分管所领导筛选">分管所领导</a-tooltip>
</template>
<a-tooltip title="按相关分管所领导筛选">
<DeptRoleUserSelectDropDown
v-model:value="queryParam.relatedLeader"
:deptId="PARTY_COMMITTEE_DEPT_ID"
:roleId="CHARGE_LEADER_ROLE_ID"
placeholder="请选择"
allow-clear
style="width: 100%"
@change="searchQuery"
/>
</a-tooltip>
</a-form-item>
</a-col>
<a-col v-if="toggleSearchStatus" :xl="6" :lg="6" :md="8" :sm="12">
<a-form-item name="coDept">
<template #label>
<a-tooltip title="按协办部门筛选">协办部门</a-tooltip>
</template>
<a-tooltip title="按协办部门筛选"><SzSelectDept v-model:value="queryParam.coDept" placeholder="请选择" allow-clear style="width: 100%" @change="searchQuery" /></a-tooltip>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="6" :md="8" :sm="12">
<span class="table-page-search-submitButtons">
<a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery">查询</a-button>
<a-button preIcon="ant-design:reload-outlined" style="margin-left: 8px" @click="searchReset">重置</a-button>
</span>
</a-col>
<span class="search-toggle-btn">
<a @click="toggleSearchStatus = !toggleSearchStatus" style="cursor: pointer; user-select: none">
{{ toggleSearchStatus ? '收起' : '展开' }}
<Icon :icon="toggleSearchStatus ? 'ant-design:up-outlined' : 'ant-design:down-outlined'" />
</a>
</span>
</a-row>
</a-form>
</div>
<div class="content">
<BasicTable
@register="registerTable"
:rowSelection="rowSelection"
:expandedRowKeys="expandedRowKeys"
@expand="handleExpand"
:expandIcon="expandIcon"
:rowClassName="(r) => 'status-row-' + (r.bpmStatus || '1')"
>
<template #tableTitle>
<a-button type="primary" v-auth="actionAuth.add" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="actionAuth.exportXls" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" v-auth="actionAuth.importExcel" preIcon="ant-design:import-outlined" @click="onImportXls"> 导入</j-upload-button>
<a-button type="primary" v-auth="actionAuth.exportXls" preIcon="ant-design:download-outlined" @click="handleDownloadTemplate">下载模板</a-button>
<j-upload-button type="primary" v-auth="actionAuth.importExcel" preIcon="ant-design:check-outlined" @click="handleCheckExcel">模板校验</j-upload-button>
<j-upload-button type="primary" v-auth="actionAuth.importExcel" preIcon="ant-design:import-outlined" @click="handleImportByTemplate">模板导入</j-upload-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="actionAuth.deleteBatch">
批量操作
<Icon icon="mdi:chevron-down"></Icon>
</a-button>
</a-dropdown>
<super-query :config="superQueryConfig" @search="handleSuperQuery" />
<a-space style="float: right; font-size: 14px; font-weight: bold">
<a-tag color="warning" style="color: #8c6900">未开始 {{ statsData.notStarted }}</a-tag>
<a-tag color="error">督办中 {{ statsData.inProgress }}已逾期 {{ statsData.overdue }}</a-tag>
<a-tag color="success">已完成 {{ statsData.completed }}</a-tag>
</a-space>
</template>
<template #action="{ record }">
<Dropdown :trigger="['hover']" :dropMenuList="getFlowMenuList(record)" popconfirm>
<a-button type="link" size="small" @click.stop>流程操作 <Icon icon="mdi-light:chevron-down" /></a-button>
</Dropdown>
<Dropdown :trigger="['hover']" :dropMenuList="getFormMenuList(record)" popconfirm>
<a-button type="link" size="small" @click.stop>表单操作 <Icon icon="mdi-light:chevron-down" /></a-button>
</Dropdown>
</template>
<template v-slot:bodyCell="{ column, record, text }">
<template v-if="column.dataIndex === 'formNo'">
<a-tooltip title="点击查看详情">
<a style="font-weight: 500" @mousedown.stop @click.stop="handleDetail(record)">{{ text }}</a>
</a-tooltip>
</template>
</template>
<!--嵌套子表-->
<template #expandedRowRender="{ record }">
<div class="feedback-expand-table">
<div class="feedback-expand-header">
<div class="feedback-expand-title">
<span class="feedback-expand-icon">
<Icon icon="ant-design:message-outlined" />
</span>
<span>反馈记录</span>
<template v-if="getFeedbackTableLoading(record)">
<a-tag class="feedback-expand-count" color="processing">加载中</a-tag>
</template>
<template v-else>
<a-tag class="feedback-expand-count"> {{ getFeedbackCount(record) }} </a-tag>
</template>
</div>
<div class="feedback-expand-desc">当前定点联系单的反馈办理记录</div>
</div>
<BasicTable
class="feedback-inner-table"
bordered
size="small"
rowKey="id"
:canResize="false"
:showIndexColumn="false"
:showActionColumn="false"
:showTableSetting="false"
:clickToRowSelect="false"
:columns="feedbackExpandColumns"
:dataSource="getFeedbackTableData(record)"
:loading="getFeedbackTableLoading(record)"
:pagination="false"
:scroll="{ x: 1200 }"
/>
</div>
</template>
</BasicTable>
</div>
<FixedContact20260730Modal ref="registerModal" @success="handleSuccess" />
<FlowScheduleStartModalForBG ref="flowScheduleModalRef" @confirm="handleFlowScheduleConfirm" />
<BusinessProcessListModal ref="businessProcessListModalRef" />
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, h, onMounted } from 'vue';
import { BasicTable } from '/@/components/Table';
import type { BasicColumn } from '/@/components/Table';
import { Dropdown } from '/@/components/Dropdown';
import { useListPage } from '/@/hooks/system/useListPage';
import { Tooltip } from 'ant-design-vue';
import { useMessage } from '/@/hooks/web/useMessage';
import Icon from '/@/components/Icon/index';
import JInput from '/@/components/Form/src/jeecg/components/JInput.vue';
import DeptRoleUserSelectDropDown from '/@/components/semri/userComponent/DeptRoleUserSelectDropDown.vue';
import SzSelectDept from '/@/components/Form/src/jeecg/components/SzSelectDept.vue';
import { PARTY_COMMITTEE_DEPT_ID, CHARGE_LEADER_ROLE_ID } from '/@/constant/supervision';
import FixedContact20260730Modal from './components/FixedContact20260730Modal.vue';
import FlowScheduleStartModalForBG from '/src/components/semri/process/FlowScheduleStartModalForBG.vue';
import BusinessProcessListModal from '/src/components/semri/process/BusinessProcessListModal.vue';
import { defHttp } from '/@/utils/http/axios';
import { startProcessSchedules } from '/@/api/common/api';
import { dateUtil } from '/@/utils/dateUtil';
import { columns, superQuerySchema, fixedContactFeedbackColumns } from './FixedContact20260730.data';
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl, getExportXlsHeadersUrl, getImportExcelByEasyExcelUrl, getCheckExcelByEasyExcelUrl, fixedContactFeedbackList, saveOrUpdate, withDrawFixContact, statusStats } from './FixedContact20260730.api';
import { showImportValidationErrors } from '/@/utils/helper/importError';
function expandIcon({ expanded, onExpand, record }: { expanded: boolean; onExpand: Function; record: Recordable }) {
const iconCls = expanded
? 'ant-table-row-expand-icon ant-table-row-expand-icon-expanded'
: 'ant-table-row-expand-icon ant-table-row-expand-icon-collapsed';
return h(
Tooltip,
{ title: '查看当前联系单反馈记录' },
{
default: () =>
h('button', {
type: 'button',
class: iconCls,
onClick: (e: Event) => onExpand(record, e),
}),
},
);
}
const permissionPrefix = 'bg.fixcontact:fixed_contact_20260730';
const actionAuth = {
add: `${permissionPrefix}:add`,
edit: `${permissionPrefix}:edit`,
delete: `${permissionPrefix}:delete`,
deleteBatch: `${permissionPrefix}:deleteBatch`,
exportXls: `${permissionPrefix}:exportXls`,
importExcel: `${permissionPrefix}:importExcel`,
};
const FLOW_CODE = 'fix_contact';
const BUSINESS_TABLE_NAME = 'fixed_contact_20260730';
const FORM_URL = 'bg/fixcontact/components/FixedContact20260730BPMForm';
const formRef = ref();
const registerModal = ref();
const flowScheduleModalRef = ref();
const businessProcessListModalRef = ref();
const toggleSearchStatus = ref<boolean>(false);
const queryParam = reactive<any>({});
const expandedRowKeys = ref<Array<string | number>>([]);
const feedbackTableData = reactive<Record<string, Recordable[]>>({});
const feedbackTableLoading = reactive<Record<string, boolean>>({});
const statsData = reactive({ notStarted: 0, inProgress: 0, overdue: 0, completed: 0 });
const feedbackExpandColumns: BasicColumn[] = [...fixedContactFeedbackColumns];
const { tableContext, onExportXls, onImportXls } = useListPage({
tableProps: {
title: '定点联系单',
api: list,
columns,
canResize: true,
resizeHeightOffset: 56,
useSearchForm: false,
expandRowByClick: true,
clickToRowSelect: false,
rowSelection: { type: 'checkbox' },
actionColumn: {
width: 240,
fixed: 'right',
},
beforeFetch: async (params) => {
return Object.assign(params, getQueryParams());
},
pagination: {
current: 1,
pageSize: 12,
pageSizeOptions: ['12', '24', '36'],
},
},
exportConfig: {
name: '定点联系单',
url: getExportUrl,
},
importConfig: {
url: getImportUrl,
success: handleSuccess,
},
});
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
const superQueryConfig = reactive(superQuerySchema);
function getFeedbackKey(record: Recordable) {
return String(record?.id ?? '');
}
function getFeedbackTableData(record: Recordable) {
return feedbackTableData[getFeedbackKey(record)] || [];
}
function getFeedbackCount(record: Recordable) {
return getFeedbackTableData(record).length;
}
function getFeedbackTableLoading(record: Recordable) {
return !!feedbackTableLoading[getFeedbackKey(record)];
}
function clearFeedbackTableData() {
Object.keys(feedbackTableData).forEach((key) => {
delete feedbackTableData[key];
});
Object.keys(feedbackTableLoading).forEach((key) => {
delete feedbackTableLoading[key];
});
}
function resetFeedbackExpand() {
expandedRowKeys.value = [];
clearFeedbackTableData();
}
async function loadFeedbackTableData(mainId: string | number) {
const key = String(mainId);
feedbackTableLoading[key] = true;
try {
const res = await fixedContactFeedbackList({ id: mainId });
feedbackTableData[key] = Array.isArray(res) ? res : res?.records || [];
} finally {
feedbackTableLoading[key] = false;
}
}
async function handleExpand(expanded: boolean, record: Recordable) {
const mainId = record?.id;
expandedRowKeys.value = [];
if (!expanded || mainId === undefined || mainId === null || mainId === '') {
return;
}
expandedRowKeys.value = [mainId];
await loadFeedbackTableData(mainId);
}
function handleSuperQuery(params) {
Object.keys(params).map((k) => {
queryParam[k] = params[k];
});
searchQuery();
}
function isEmptyQueryValue(value) {
return value === undefined || value === null || value === '' || value === '**' || (Array.isArray(value) && value.length === 0);
}
function getTrimmedQueryValue(value) {
return typeof value === 'string' ? value.trim() : value;
}
function getQueryParams() {
const params: Recordable = {};
Object.keys(queryParam).forEach((key) => {
const value = getTrimmedQueryValue(queryParam[key]);
if (!isEmptyQueryValue(value)) {
params[key] = value;
}
});
return params;
}
async function fetchStatusStats() {
try {
const res = await statusStats(getQueryParams());
if (res) {
Object.assign(statsData, res);
}
} catch (e) {
// 状态统计失败不阻塞列表
}
}
function searchQuery() {
selectedRowKeys.value = [];
resetFeedbackExpand();
reload({ page: 1 });
fetchStatusStats();
}
function clearQueryParams() {
Object.keys(queryParam).forEach((key) => {
delete queryParam[key];
});
}
function handleAdd() {
registerModal.value.disableSubmit = false;
registerModal.value.add();
}
function handleEdit(record: Recordable) {
registerModal.value.disableSubmit = false;
registerModal.value.edit(record);
}
function handleDetail(record: Recordable) {
expandedRowKeys.value = [];
registerModal.value.disableSubmit = true;
registerModal.value.edit(record);
}
async function handleDelete(record) {
await deleteOne({ id: record.id }, handleSuccess);
}
async function batchHandleDelete() {
await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
}
function handleSuccess() {
selectedRowKeys.value = [];
resetFeedbackExpand();
reload();
fetchStatusStats();
}
const { createMessage } = useMessage();
function getFlowMenuList(record) {
const list: any[] = [];
if (record.bpmStatus == '1' || !record.bpmStatus) {
list.push({
text: '发起流程',
icon: 'ant-design:play-circle-outlined',
event: 'process',
onClick: handleProcess.bind(null, record),
});
}
list.push({
text: '查询督办流程',
icon: 'ant-design:search-outlined',
event: 'queryProcess',
divider: true,
onClick: handleQueryProcess.bind(null, record),
});
if (record.bpmStatus && record.bpmStatus !== '1') {
list.push({
text: '删除关联流程',
icon: 'ant-design:delete-outlined',
event: 'withdraw',
popConfirm: {
title: '确定删除该记录关联的所有运行中流程吗?',
confirm: handleWithDraw.bind(null, record),
placement: 'topLeft',
},
});
}
return list;
}
function getFormMenuList(record) {
return [
{
text: '编辑',
icon: 'ant-design:edit-outlined',
event: 'edit',
onClick: handleEdit.bind(null, record),
},
{
text: '详情',
icon: 'ant-design:file-text-outlined',
event: 'detail',
onClick: handleDetail.bind(null, record),
},
{
text: '删除',
icon: 'ant-design:delete-outlined',
event: 'delete',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
placement: 'topLeft',
},
auth: actionAuth.delete,
},
];
}
interface DeptOption {
label: string;
value: string;
}
function getNextSuperviseCount(value) {
const count = Number(value || 0);
return Number.isFinite(count) ? count + 1 : 1;
}
const CN = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
function toChinese(num: number): string {
return String(num).split('').map(c => CN[Number(c)]).join('');
}
function splitDeptValue(value) {
if (Array.isArray(value)) {
return value.map((item) => String(item || '').trim()).filter(Boolean);
}
return String(value || '')
.split(/[,]/)
.map((item) => item.trim())
.filter(Boolean);
}
function fetchDeptOptions(record): DeptOption[] {
const hostIds = splitDeptValue(record?.hostDept);
const coIds = splitDeptValue(record?.coDept);
const hostNames = splitDeptValue(record?.hostDept_dictText);
const coNames = splitDeptValue(record?.coDept_dictText);
const optionMap = new Map<string, DeptOption>();
[hostIds, coIds].forEach((ids, groupIndex) => {
const names = groupIndex === 0 ? hostNames : coNames;
ids.forEach((deptId, index) => {
if (optionMap.has(deptId)) return;
optionMap.set(deptId, {
value: deptId,
label: names[index] || deptId,
});
});
});
return Array.from(optionMap.values());
}
function getDeptIds(record) {
const hostIds = splitDeptValue(record?.hostDept);
const coIds = splitDeptValue(record?.coDept);
return [...new Set([...hostIds, ...coIds])].join(',');
}
async function handleProcess(record) {
const deptOptions = await fetchDeptOptions(record);
const nextCount = getNextSuperviseCount(record.superviseCount);
const title = nextCount > 1
? `发起流程(${record?.formNo || record?.seqNo || ''}${toChinese(nextCount)}次督办)`
: '发起流程';
flowScheduleModalRef.value?.open({
title,
taskTitle: nextCount > 1 ? `${record?.formNo || record?.seqNo || ''}${nextCount}次督办` : (record?.formNo || record?.seqNo || ''),
payload: { record },
deptOptions,
showSuoleaderFields: true,
isNeedAppro: record?.isNeedAppro,
supDeptleaderid: record?.supDeptleaderid,
showDeadlineField: true,
deadline: record?.contactTime,
showTriggerMode: false,
});
}
function handleQueryProcess(record) {
businessProcessListModalRef.value?.open({
title: '流程列表',
businessId: record.id,
columns: '',
});
}
async function handleWithDraw(record) {
const res = await withDrawFixContact({ id: record.id });
if (res.success) {
createMessage.success(res.message || '删除流程成功');
reload();
fetchStatusStats();
} else {
createMessage.error(res.message || '删除流程失败');
}
}
async function handleFlowScheduleConfirm({ payload, options }) {
const record = payload?.record || {};
const formatDate = (value, format) => {
return value ? dateUtil(value).format(format) : undefined;
};
const formatDeadlineDateTime = (value) => {
const deadlineDate = formatDate(value, 'YYYY-MM-DD');
return deadlineDate ? `${deadlineDate} 00:00:00` : undefined;
};
const nextSuperviseCount = getNextSuperviseCount(record.superviseCount);
const selectedTitle = options.title || record.formNo || record.seqNo || '';
const selectedDeadline = options.deadline || record.contactTime;
const defaultDeptIds = getDeptIds(record);
const flowJsonData = {
...record,
superviseCount: nextSuperviseCount,
title: selectedTitle,
isNeedAppro: options.isNeedAppro ?? '0',
supDeptleaderid: options.supDeptleaderid ?? '',
startApprovalOpinion: options.approvalOpinion,
};
const params = {
intervalType: options.intervalType,
startCount: options.startCount,
taskTask: {
triggerType: options.triggerType,
startTime: options.intervalStartTime,
flowCode: FLOW_CODE,
formUrl: FORM_URL,
flowName: '定点联系督办流程',
jsonData: flowJsonData,
businessTablename: BUSINESS_TABLE_NAME,
businessId: record.id,
title: selectedTitle,
content: record.suggestionSummary || '',
deptId: options.deptId || defaultDeptIds,
deptLeaderId: record.contactLeader || '',
requireFinishDate: formatDate(selectedDeadline, 'YYYY-MM-DD'),
deadline: formatDeadlineDateTime(selectedDeadline),
},
};
await startProcessSchedules(params);
await saveOrUpdate({ id: record.id, bpmStatus: '2', superviseCount: nextSuperviseCount, isNeedAppro: options.isNeedAppro ?? record.isNeedAppro ?? '0', supDeptleaderid: options.supDeptleaderid ?? record.supDeptleaderid ?? '' }, true);
createMessage.success('发起成功');
reload();
fetchStatusStats();
}
const labelCol = reactive({
xs: { span: 24 },
sm: { span: 10 },
xl: { span: 10 },
xxl: { span: 10 },
});
const wrapperCol = reactive({
xs: { span: 24 },
sm: { span: 14 },
});
async function handleDownloadTemplate() {
const data = await defHttp.get(
{ url: getExportXlsHeadersUrl, params: {}, responseType: 'blob', timeout: 60000 },
{ isTransformResponse: false },
);
if (!data) {
createMessage.warning('文件下载失败');
return;
}
const blob = new Blob([data]);
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = '定点联系单-导入模板.xls';
link.click();
URL.revokeObjectURL(link.href);
}
async function handleImportByTemplate(data) {
const isReturn = (fileInfo) => {
try {
if (fileInfo.code === 500 || fileInfo.code === 510) {
if (fileInfo.result && Array.isArray(fileInfo.result) && fileInfo.result.length > 0) {
showImportValidationErrors(fileInfo.message || `${data.file.name} 导入失败`, fileInfo.result);
} else {
createMessage.error(fileInfo.message || `${data.file.name} 导入失败`);
}
} else {
createMessage.success(fileInfo.message || `${data.file.name} 导入成功`);
}
} catch {
// ignore
} finally {
reload();
}
};
await defHttp.uploadFile({ url: getImportExcelByEasyExcelUrl }, { file: data.file }, { success: isReturn });
}
async function handleCheckExcel(data) {
const isReturn = (fileInfo) => {
try {
if (fileInfo.code === 500 || fileInfo.code === 510) {
if (fileInfo.result && Array.isArray(fileInfo.result) && fileInfo.result.length > 0) {
showImportValidationErrors(fileInfo.message || `${data.file.name} 校验失败`, fileInfo.result);
} else {
createMessage.error(fileInfo.message || `${data.file.name} 校验失败`);
}
} else {
createMessage.success(fileInfo.message || `${data.file.name} 校验通过`);
}
} catch {
// ignore
}
};
await defHttp.uploadFile({ url: getCheckExcelByEasyExcelUrl }, { file: data.file }, { success: isReturn });
}
function searchReset() {
formRef.value?.resetFields();
clearQueryParams();
selectedRowKeys.value = [];
resetFeedbackExpand();
reload({ page: 1 });
fetchStatusStats();
}
onMounted(() => {
fetchStatusStats();
});
</script>
<style lang="less" scoped>
.jeecg-basic-table-form-container {
padding: 0;
.search-form-row {
position: relative;
padding-right: 64px;
.search-toggle-btn {
position: absolute;
right: 12px;
top: 0;
height: 32px;
display: flex;
align-items: center;
white-space: nowrap;
}
}
.table-page-search-submitButtons {
display: block;
margin-bottom: 24px;
white-space: nowrap;
}
.ant-form-item:not(.ant-form-item-with-help) {
margin-bottom: 16px;
height: 32px;
}
:deep(.ant-picker),
:deep(.ant-input-number) {
width: 100%;
}
}
.erpNativeList {
height: 100%;
.content {
background-color: #fff;
height: auto;
}
.feedback-expand-table {
margin: 4px 10px 12px 42px;
padding: 12px 14px 14px;
background: #f6fbff;
border: 1px solid #d6e8ff;
border-left: 4px solid #1677ff;
border-radius: 6px;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.72);
.feedback-expand-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
margin-bottom: 10px;
}
.feedback-expand-title {
display: inline-flex;
align-items: center;
min-width: 0;
color: #1f2937;
font-size: 14px;
font-weight: 600;
line-height: 24px;
}
.feedback-expand-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
margin-right: 8px;
color: #1677ff;
background: #e6f4ff;
border-radius: 50%;
}
.feedback-expand-count {
margin-left: 10px;
}
.feedback-expand-desc {
color: #64748b;
font-size: 13px;
line-height: 22px;
white-space: nowrap;
}
:deep(.jeecg-basic-table) {
background: #fff;
}
:deep(.feedback-inner-table .ant-table-wrapper) {
padding: 0;
border-radius: 4px;
}
:deep(.feedback-inner-table .ant-table-thead > tr > th) {
background: #eef6ff;
color: #334155;
font-weight: 600;
}
:deep(.feedback-inner-table .ant-table-tbody > tr > td) {
background: #fff;
}
:deep(.feedback-inner-table .ant-table-tbody > tr:hover > td) {
background: #f8fbff;
}
}
}
:deep(.status-row-1 td) {
background: #fffbe6 !important;
}
:deep(.status-row-2 td) {
background: #fff1f0 !important;
}
:deep(.status-row-3 td) {
background: #f6ffed !important;
}
</style>