|
@@ -1,15 +1,16 @@
|
|
|
|
|
+<!-- eslint-disable vue/multi-word-component-names -->
|
|
|
<template>
|
|
<template>
|
|
|
<!-- Tab标签页 -->
|
|
<!-- Tab标签页 -->
|
|
|
- <Tabs v-model:activeKey="activeKey" class="data-quality-page" type="line">
|
|
|
|
|
|
|
+ <Tabs v-model:activeKey="activeKey" class="common-page-tabs" type="line" @change="handleTabChange">
|
|
|
<TabPane key="unresolved" tab="未解决">
|
|
<TabPane key="unresolved" tab="未解决">
|
|
|
<div class="add-button">
|
|
<div class="add-button">
|
|
|
|
|
+ <a-button type="default" preIcon="mdi:download" @click="handleExportExcel" style="margin-right: 8px"> 导出 </a-button>
|
|
|
<a-button type="primary" preIcon="mdi:page-next-outline" @click="handleOpenModal({}, 'add')"> 新增问题 </a-button>
|
|
<a-button type="primary" preIcon="mdi:page-next-outline" @click="handleOpenModal({}, 'add')"> 新增问题 </a-button>
|
|
|
</div>
|
|
</div>
|
|
|
<BasicTable style="padding: 0" @register="registerUnresolvedTable">
|
|
<BasicTable style="padding: 0" @register="registerUnresolvedTable">
|
|
|
<template #queJson="{ record }">
|
|
<template #queJson="{ record }">
|
|
|
- <div style="display: flex; align-items: center; gap: 8px; width: 100%;">
|
|
|
|
|
- <!-- 文字span:添加 flex: 1 占据剩余空间,text-align: center 实现文字居中 -->
|
|
|
|
|
- <span style="flex: 1; text-align: center;">
|
|
|
|
|
|
|
+ <div style="display: flex; align-items: center; gap: 8px; width: 100%">
|
|
|
|
|
+ <span style="flex: 1; text-align: center">
|
|
|
{{ record?.queJson ? formatQueJson(record.queJson) : '' }}
|
|
{{ record?.queJson ? formatQueJson(record.queJson) : '' }}
|
|
|
</span>
|
|
</span>
|
|
|
<!-- 按钮:无需额外样式,自然靠最右侧 -->
|
|
<!-- 按钮:无需额外样式,自然靠最右侧 -->
|
|
@@ -17,7 +18,6 @@
|
|
|
<SvgIcon name="view" />
|
|
<SvgIcon name="view" />
|
|
|
</button>
|
|
</button>
|
|
|
</div>
|
|
</div>
|
|
|
-
|
|
|
|
|
</template>
|
|
</template>
|
|
|
<template #action="{ record }">
|
|
<template #action="{ record }">
|
|
|
<button @click="handleOpenModal(record, 'edit')" class="action-btn">
|
|
<button @click="handleOpenModal(record, 'edit')" class="action-btn">
|
|
@@ -50,14 +50,28 @@
|
|
|
<SvgIcon name="resolved" />
|
|
<SvgIcon name="resolved" />
|
|
|
</button>
|
|
</button>
|
|
|
</Popconfirm>
|
|
</Popconfirm>
|
|
|
- <button @click="handleGoToPage(record, '/basicInfo/accessStatistics')" class="action-btn">
|
|
|
|
|
|
|
+ <button @click="handleGoToPage(record)" class="action-btn">
|
|
|
<SvgIcon name="details" />
|
|
<SvgIcon name="details" />
|
|
|
</button>
|
|
</button>
|
|
|
</template>
|
|
</template>
|
|
|
</BasicTable>
|
|
</BasicTable>
|
|
|
</TabPane>
|
|
</TabPane>
|
|
|
<TabPane key="resolved" tab="已解决">
|
|
<TabPane key="resolved" tab="已解决">
|
|
|
|
|
+ <div class="add-button">
|
|
|
|
|
+ <a-button type="default" preIcon="mdi:download" @click="handleExportExcel" style="margin-right: 8px"> 导出 </a-button>
|
|
|
|
|
+ </div>
|
|
|
<BasicTable style="padding: 0" @register="registerResolvedTable">
|
|
<BasicTable style="padding: 0" @register="registerResolvedTable">
|
|
|
|
|
+ <template #queJson="{ record }">
|
|
|
|
|
+ <div style="display: flex; align-items: center; gap: 8px; width: 100%">
|
|
|
|
|
+ <span style="flex: 1; text-align: center">
|
|
|
|
|
+ {{ record?.queJson ? formatQueJson(record.queJson) : '' }}
|
|
|
|
|
+ </span>
|
|
|
|
|
+ <!-- 按钮:无需额外样式,自然靠最右侧 -->
|
|
|
|
|
+ <button @click="record && handleOpenModal(record, 'view')" class="action-btn">
|
|
|
|
|
+ <SvgIcon name="view" />
|
|
|
|
|
+ </button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
<template #action="{ record }">
|
|
<template #action="{ record }">
|
|
|
<button @click="handleOpenModal(record, 'view')" class="action-btn">
|
|
<button @click="handleOpenModal(record, 'view')" class="action-btn">
|
|
|
<SvgIcon name="details" />
|
|
<SvgIcon name="details" />
|
|
@@ -72,62 +86,127 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
- import { ref, nextTick, computed } from 'vue';
|
|
|
|
|
|
|
+ import { ref, nextTick, computed, onMounted } from 'vue';
|
|
|
import { useRouter } from 'vue-router';
|
|
import { useRouter } from 'vue-router';
|
|
|
- import { BasicTable, useTable } from '/@/components/Table';
|
|
|
|
|
|
|
+ import { BasicTable, useTable, BasicColumn, FormSchema } from '/@/components/Table';
|
|
|
import { useModal } from '/@/components/Modal';
|
|
import { useModal } from '/@/components/Modal';
|
|
|
- import { Tabs, TabPane, Popconfirm } from 'ant-design-vue';
|
|
|
|
|
|
|
+ import { Tabs, TabPane, Popconfirm, message } from 'ant-design-vue';
|
|
|
import DataQualityModal from './components/DataQualityModal.vue';
|
|
import DataQualityModal from './components/DataQualityModal.vue';
|
|
|
import { SvgIcon } from '/@/components/Icon';
|
|
import { SvgIcon } from '/@/components/Icon';
|
|
|
- import { columns, searchFormSchema } from './dataQuality.data';
|
|
|
|
|
|
|
+ import {
|
|
|
|
|
+ getColumns,
|
|
|
|
|
+ getSearchFormSchema,
|
|
|
|
|
+ type ProductionStatusMap,
|
|
|
|
|
+ } from './dataQuality.data';
|
|
|
import { getDataQuaQueList, addDataQuaQue, deleteDataQuaQue, editDataQuaQue } from '../basicInfo.api';
|
|
import { getDataQuaQueList, addDataQuaQue, deleteDataQuaQue, editDataQuaQue } from '../basicInfo.api';
|
|
|
|
|
+ import { findNode } from '/@/utils/helper/treeHelper';
|
|
|
|
|
+ import { useMineStore } from '/@/store/modules/mine';
|
|
|
|
|
+ import { getDictItemsByCode } from '/@/utils/dict';
|
|
|
import dayjs from 'dayjs';
|
|
import dayjs from 'dayjs';
|
|
|
|
|
+ import * as XLSX from 'xlsx';
|
|
|
// 路由实例
|
|
// 路由实例
|
|
|
const router = useRouter();
|
|
const router = useRouter();
|
|
|
|
|
+ // 实例化矿井Store
|
|
|
|
|
+ const mineStore = useMineStore();
|
|
|
// 响应式数据
|
|
// 响应式数据
|
|
|
const activeKey = ref('unresolved'); // 激活的Tab键
|
|
const activeKey = ref('unresolved'); // 激活的Tab键
|
|
|
const pageMode = ref('add');
|
|
const pageMode = ref('add');
|
|
|
|
|
+
|
|
|
|
|
+ // ========== 定义动态状态映射/下拉选项 ==========
|
|
|
|
|
+ // 1. 动态生产状态映射(key: 状态value,value: 包含label/color的配置)
|
|
|
|
|
+ const dynamicProductionStatusMap = ref<ProductionStatusMap>({});
|
|
|
|
|
+ // 2. 动态下拉选项(供搜索表单使用)
|
|
|
|
|
+ const dynamicProductionStatusOptions = ref<{ label: string; value: string | number }[]>([]);
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 颜色分配规则(可根据业务灵活调整)
|
|
|
|
|
+ const getStatusColor = (statusText: string) => {
|
|
|
|
|
+ if (statusText.includes('正常生产')) return 'green'; // 正常生产 → 绿色
|
|
|
|
|
+ if (statusText.includes('拟建矿井')) return 'blue'; // 拟建矿井 → 蓝色
|
|
|
|
|
+ else return 'red'; // 停产/停建/关闭/整改/责令 → 红色
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 从接口获取生产状态列表并生成动态映射/下拉选项
|
|
|
|
|
+ const fetchProductionStatus = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 调用接口获取状态列表
|
|
|
|
|
+ const statusList = await getDictItemsByCode('mineProStatus');
|
|
|
|
|
+ if (!Array.isArray(statusList)) return;
|
|
|
|
|
+
|
|
|
|
|
+ // 生成动态映射和下拉选项
|
|
|
|
|
+ const statusMap: ProductionStatusMap = {};
|
|
|
|
|
+ const statusOptions: { label: string; value: string | number }[] = [];
|
|
|
|
|
+
|
|
|
|
|
+ statusList.forEach((item) => {
|
|
|
|
|
+ const value = item.value; // 接口返回的value(数字/字符串)
|
|
|
|
|
+ const label = item.text || item.label; // 接口返回的文本
|
|
|
|
|
+ const color = getStatusColor(label); // 按规则分配颜色
|
|
|
|
|
+
|
|
|
|
|
+ // 填充映射表
|
|
|
|
|
+ statusMap[value] = { label, value, color };
|
|
|
|
|
+ // 填充下拉选项
|
|
|
|
|
+ statusOptions.push({ label, value });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 赋值到响应式变量
|
|
|
|
|
+ dynamicProductionStatusMap.value = statusMap;
|
|
|
|
|
+ dynamicProductionStatusOptions.value = statusOptions;
|
|
|
|
|
+
|
|
|
|
|
+ // 刷新表格(确保表格使用最新的映射)
|
|
|
|
|
+ await safeReloadActiveTable();
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('获取生产状态列表失败:', error);
|
|
|
|
|
+ message.error('生产状态数据加载失败');
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 生成动态列和搜索表单配置
|
|
|
|
|
+ const columns = computed(() => getColumns(dynamicProductionStatusMap));
|
|
|
|
|
+ const searchFormSchema = computed(() => getSearchFormSchema(dynamicProductionStatusOptions));
|
|
|
|
|
+
|
|
|
// 未解决表格注册
|
|
// 未解决表格注册
|
|
|
- const [registerUnresolvedTable, { reload: reloadUnresolved}] = useTable({
|
|
|
|
|
- api: getQuaQueListByTab(),
|
|
|
|
|
- columns,
|
|
|
|
|
|
|
+ const [registerUnresolvedTable, { reload: reloadUnresolved }] = useTable({
|
|
|
|
|
+ api: async (params: any) => {
|
|
|
|
|
+ return await getDataQuaQueList({ ...params, isOk: false });
|
|
|
|
|
+ },
|
|
|
|
|
+ columns: columns, // 绑定动态列
|
|
|
formConfig: {
|
|
formConfig: {
|
|
|
labelWidth: 120,
|
|
labelWidth: 120,
|
|
|
- schemas: searchFormSchema,
|
|
|
|
|
|
|
+ schemas: searchFormSchema.value,
|
|
|
showAdvancedButton: false,
|
|
showAdvancedButton: false,
|
|
|
schemaGroupNames: ['常规查询'],
|
|
schemaGroupNames: ['常规查询'],
|
|
|
},
|
|
},
|
|
|
useSearchForm: true,
|
|
useSearchForm: true,
|
|
|
pagination: true,
|
|
pagination: true,
|
|
|
- striped: true,
|
|
|
|
|
showIndexColumn: false,
|
|
showIndexColumn: false,
|
|
|
indexColumnProps: {
|
|
indexColumnProps: {
|
|
|
title: '序号',
|
|
title: '序号',
|
|
|
},
|
|
},
|
|
|
- canResize: false,
|
|
|
|
|
|
|
+ // canResize: false,
|
|
|
actionColumn: {
|
|
actionColumn: {
|
|
|
width: 200,
|
|
width: 200,
|
|
|
title: '操作',
|
|
title: '操作',
|
|
|
dataIndex: 'action',
|
|
dataIndex: 'action',
|
|
|
slots: { customRender: 'action' },
|
|
slots: { customRender: 'action' },
|
|
|
},
|
|
},
|
|
|
- immediate: true,
|
|
|
|
|
|
|
+ immediate: false, // 先不立即加载,等状态数据获取后再加载
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
// 已解决表格注册
|
|
// 已解决表格注册
|
|
|
const [registerResolvedTable, { reload: reloadResolved }] = useTable({
|
|
const [registerResolvedTable, { reload: reloadResolved }] = useTable({
|
|
|
- api: getQuaQueListByTab(),
|
|
|
|
|
- columns,
|
|
|
|
|
|
|
+ api: async (params: any) => {
|
|
|
|
|
+ return await getDataQuaQueList({ ...params, isOk: true });
|
|
|
|
|
+ },
|
|
|
|
|
+ columns: columns,
|
|
|
formConfig: {
|
|
formConfig: {
|
|
|
labelWidth: 120,
|
|
labelWidth: 120,
|
|
|
- schemas: searchFormSchema,
|
|
|
|
|
|
|
+ schemas: searchFormSchema.value,
|
|
|
showAdvancedButton: false,
|
|
showAdvancedButton: false,
|
|
|
- schemaGroupNames: ['常规查询', '高级查询'],
|
|
|
|
|
|
|
+ schemaGroupNames: ['常规查询'],
|
|
|
},
|
|
},
|
|
|
useSearchForm: true,
|
|
useSearchForm: true,
|
|
|
pagination: true,
|
|
pagination: true,
|
|
|
striped: true,
|
|
striped: true,
|
|
|
- bordered: true,
|
|
|
|
|
|
|
+ // bordered: true,
|
|
|
showIndexColumn: false,
|
|
showIndexColumn: false,
|
|
|
indexColumnProps: {
|
|
indexColumnProps: {
|
|
|
title: '序号',
|
|
title: '序号',
|
|
@@ -138,14 +217,14 @@
|
|
|
dataIndex: 'action',
|
|
dataIndex: 'action',
|
|
|
slots: { customRender: 'action' },
|
|
slots: { customRender: 'action' },
|
|
|
},
|
|
},
|
|
|
- immediate: true,
|
|
|
|
|
|
|
+ immediate: false, // 先不立即加载
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
// 弹框注册
|
|
// 弹框注册
|
|
|
const [registerModal, { openModal }] = useModal();
|
|
const [registerModal, { openModal }] = useModal();
|
|
|
|
|
|
|
|
// 解析queJson并拼接orderNum+queCon的辅助函数
|
|
// 解析queJson并拼接orderNum+queCon的辅助函数
|
|
|
- function formatQueJson (queJsonStr: string) {
|
|
|
|
|
|
|
+ function formatQueJson(queJsonStr: string) {
|
|
|
// 空值处理
|
|
// 空值处理
|
|
|
if (!queJsonStr) return '无质量问题';
|
|
if (!queJsonStr) return '无质量问题';
|
|
|
try {
|
|
try {
|
|
@@ -160,6 +239,46 @@
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+ // 安全重载当前激活的表格
|
|
|
|
|
+ async function safeReloadActiveTable() {
|
|
|
|
|
+ await nextTick();
|
|
|
|
|
+ if (activeKey.value === 'unresolved') {
|
|
|
|
|
+ try {
|
|
|
|
|
+ await reloadUnresolved();
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ console.warn('未解决表格重载失败:', e);
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ try {
|
|
|
|
|
+ await reloadResolved();
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ console.warn('已解决表格重载失败:', e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ // 按需重载双表格(仅在「标记已解决」等跨Tab操作时用)
|
|
|
|
|
+ async function reloadBothTableSafely() {
|
|
|
|
|
+ await nextTick();
|
|
|
|
|
+ // 未解决表格:await + try/catch 捕获异步错误
|
|
|
|
|
+ try {
|
|
|
|
|
+ await reloadUnresolved();
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ console.warn('未解决表格暂未就绪,跳过重载:', e);
|
|
|
|
|
+ }
|
|
|
|
|
+ // 已解决表格:同理,一个报错不影响另一个
|
|
|
|
|
+ try {
|
|
|
|
|
+ await reloadResolved();
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ console.warn('已解决表格暂未就绪,跳过重载:', e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // tabs切换事件
|
|
|
|
|
+ async function handleTabChange(key: string) {
|
|
|
|
|
+ activeKey.value = key;
|
|
|
|
|
+ await safeReloadActiveTable();
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 根据标签获取表格数据(已解决/未解决)
|
|
* 根据标签获取表格数据(已解决/未解决)
|
|
|
* @param result 弹框数据
|
|
* @param result 弹框数据
|
|
@@ -177,10 +296,7 @@
|
|
|
*/
|
|
*/
|
|
|
function handleOpenModal(record: any, mode: 'view' | 'edit' | 'add' = 'view') {
|
|
function handleOpenModal(record: any, mode: 'view' | 'edit' | 'add' = 'view') {
|
|
|
pageMode.value = mode;
|
|
pageMode.value = mode;
|
|
|
- openModal(true, {
|
|
|
|
|
- record,
|
|
|
|
|
- mode,
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ openModal(true, { record, mode });
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -188,35 +304,45 @@
|
|
|
* @param result 弹框数据
|
|
* @param result 弹框数据
|
|
|
*/
|
|
*/
|
|
|
async function handleModalSuccess(result: any) {
|
|
async function handleModalSuccess(result: any) {
|
|
|
- try{
|
|
|
|
|
|
|
+ try {
|
|
|
if (pageMode.value === 'add') {
|
|
if (pageMode.value === 'add') {
|
|
|
- console.log(result);
|
|
|
|
|
await addDataQuaQue(result);
|
|
await addDataQuaQue(result);
|
|
|
} else if (pageMode.value === 'edit') {
|
|
} else if (pageMode.value === 'edit') {
|
|
|
await editDataQuaQue(result);
|
|
await editDataQuaQue(result);
|
|
|
}
|
|
}
|
|
|
- // 刷新表格
|
|
|
|
|
- await nextTick();
|
|
|
|
|
- reloadUnresolved();
|
|
|
|
|
- reloadResolved();
|
|
|
|
|
- } catch(error) {
|
|
|
|
|
|
|
+ await safeReloadActiveTable();
|
|
|
|
|
+ } catch (error) {
|
|
|
console.log('操作失败:', error);
|
|
console.log('操作失败:', error);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
/**
|
|
/**
|
|
|
- * 通用页面跳转方法
|
|
|
|
|
- * @param record 当前行数据
|
|
|
|
|
- * @param path 目标路径
|
|
|
|
|
- */
|
|
|
|
|
- function handleGoToPage(record: any, path: string) {
|
|
|
|
|
- // 跳转时携带当前煤矿的编号作为参数(根据实际需求调整携带的参数)
|
|
|
|
|
- router.push({
|
|
|
|
|
- path,
|
|
|
|
|
- // query: {
|
|
|
|
|
- // orderNo: record.orderNo, // 煤矿编号
|
|
|
|
|
- // mineName: record.mineName // 煤矿名称
|
|
|
|
|
- // }
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ * 通用页面跳转方法
|
|
|
|
|
+ * @param record 当前行数据
|
|
|
|
|
+ * @param path 目标路径(树形结构所在页面的路由地址)
|
|
|
|
|
+ */
|
|
|
|
|
+ async function handleGoToPage(record: any) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const mineCode = record.mineCode;
|
|
|
|
|
+ const targetNode = findNode(
|
|
|
|
|
+ mineStore.getMineTree,
|
|
|
|
|
+ (item) => item.id === mineCode,
|
|
|
|
|
+ { id: 'id', pid: 'parentId', children: 'childDepart' }
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ let minePath = '';
|
|
|
|
|
+ if (targetNode) {
|
|
|
|
|
+ minePath = targetNode.parentId;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ message.warning(`未找到矿码【${mineCode}】对应的矿井节点`);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 跳转页面(可携带拼接后的矿名/路径等参数)
|
|
|
|
|
+ router.push({ path: `/sealed/${minePath}`, query: {} });
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('矿节点定位失败:', error);
|
|
|
|
|
+ message.error('矿节点定位失败,请稍后重试');
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -230,7 +356,7 @@
|
|
|
* 生成已解决气泡提示文案:XX矿井XX问题是否解决了吗?
|
|
* 生成已解决气泡提示文案:XX矿井XX问题是否解决了吗?
|
|
|
*/
|
|
*/
|
|
|
const getResolveDesc = computed(() => (record: any) => {
|
|
const getResolveDesc = computed(() => (record: any) => {
|
|
|
- const mineName = record.mineName || '该'; // 矿井名称兜底
|
|
|
|
|
|
|
+ const mineName = record.mineName || '该';
|
|
|
return `是否确认${mineName}矿井问题已解决?`;
|
|
return `是否确认${mineName}矿井问题已解决?`;
|
|
|
});
|
|
});
|
|
|
|
|
|
|
@@ -242,7 +368,7 @@
|
|
|
try {
|
|
try {
|
|
|
await deleteDataQuaQue({ id: record.id });
|
|
await deleteDataQuaQue({ id: record.id });
|
|
|
await nextTick();
|
|
await nextTick();
|
|
|
- reloadUnresolved();
|
|
|
|
|
|
|
+ await safeReloadActiveTable();
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
console.error('删除失败:', error);
|
|
console.error('删除失败:', error);
|
|
|
}
|
|
}
|
|
@@ -255,34 +381,111 @@
|
|
|
async function handleOKRecord(record: any) {
|
|
async function handleOKRecord(record: any) {
|
|
|
const copyRecord = {
|
|
const copyRecord = {
|
|
|
...record,
|
|
...record,
|
|
|
- isOk : true,
|
|
|
|
|
|
|
+ isOk: true,
|
|
|
updateTime: dayjs().format('YYYY-MM-DD HH:mm:ss')
|
|
updateTime: dayjs().format('YYYY-MM-DD HH:mm:ss')
|
|
|
};
|
|
};
|
|
|
- copyRecord.isOk = true
|
|
|
|
|
try {
|
|
try {
|
|
|
await editDataQuaQue(copyRecord);
|
|
await editDataQuaQue(copyRecord);
|
|
|
- await nextTick();
|
|
|
|
|
- reloadUnresolved();
|
|
|
|
|
- reloadResolved();
|
|
|
|
|
|
|
+ await safeReloadActiveTable();
|
|
|
}catch (error) {
|
|
}catch (error) {
|
|
|
console.error('操作失败:', error);
|
|
console.error('操作失败:', error);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
-</script>
|
|
|
|
|
|
|
|
|
|
-<style scoped lang="less">
|
|
|
|
|
- .data-quality-page {
|
|
|
|
|
- padding: 0 12px;
|
|
|
|
|
- margin: 16px;
|
|
|
|
|
- border: 1px solid @border-color-base;
|
|
|
|
|
- .ant-form {
|
|
|
|
|
- background-color: #fff;
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取全部未解决数据(不分页)
|
|
|
|
|
+ */
|
|
|
|
|
+ async function getAllUnresolvedData() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await getDataQuaQueList({ pageNum: 1, pageSize: 9999, isOk: false });
|
|
|
|
|
+ return res.records || [];
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('获取未解决数据失败:', error);
|
|
|
|
|
+ return [];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取全部已解决数据(不分页)
|
|
|
|
|
+ */
|
|
|
|
|
+ async function getAllResolvedData() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await getDataQuaQueList({ pageNum: 1, pageSize: 9999, isOk: true });
|
|
|
|
|
+ return res.records || [];
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('获取已解决数据失败:', error);
|
|
|
|
|
+ return [];
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 格式化导出数据(统一字段名 + 状态文本)
|
|
|
|
|
+ */
|
|
|
|
|
+ function formatExportData(dataList: any[]) {
|
|
|
|
|
+ return dataList.map((item) => ({
|
|
|
|
|
+ 煤矿名称: item.mineName || '',
|
|
|
|
|
+ 煤矿简称: item.mineNameAbbr || '',
|
|
|
|
|
+ 生产状态: dynamicProductionStatusMap.value[item.mineProStatus]?.label || '-',
|
|
|
|
|
+ 在线状态: item.mineLinkStatus === 1 ? '在线' : item.mineLinkStatus === 0 ? '离线' : '/',
|
|
|
|
|
+ 质量问题详情: formatQueJson(item.queJson),
|
|
|
|
|
+ 当前状态: item.isOk ? '已解决' : '未解决',
|
|
|
|
|
+ 处理时间: item.updateTime || '',
|
|
|
|
|
+ }));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 导出Excel核心方法
|
|
|
|
|
+ */
|
|
|
|
|
+ async function handleExportExcel() {
|
|
|
|
|
+ let hideLoading: () => void = () => {};
|
|
|
|
|
+ try {
|
|
|
|
|
+ hideLoading = message.loading('正在导出数据,请稍候...');
|
|
|
|
|
+
|
|
|
|
|
+ const unresolvedList = await getAllUnresolvedData();
|
|
|
|
|
+ const resolvedList = await getAllResolvedData();
|
|
|
|
|
+
|
|
|
|
|
+ const formattedUnresolved = formatExportData(unresolvedList);
|
|
|
|
|
+ const formattedResolved = formatExportData(resolvedList);
|
|
|
|
|
+
|
|
|
|
|
+ const workbook = XLSX.utils.book_new();
|
|
|
|
|
+ const unresolvedSheet = XLSX.utils.json_to_sheet(formattedUnresolved);
|
|
|
|
|
+ const resolvedSheet = XLSX.utils.json_to_sheet(formattedResolved);
|
|
|
|
|
+
|
|
|
|
|
+ XLSX.utils.book_append_sheet(workbook, unresolvedSheet, '未解决');
|
|
|
|
|
+ XLSX.utils.book_append_sheet(workbook, resolvedSheet, '已解决');
|
|
|
|
|
+
|
|
|
|
|
+ const fileName = `数据质量问题_${dayjs().format('YYYYMMDDHHmmss')}.xlsx`;
|
|
|
|
|
+ XLSX.writeFile(workbook, fileName);
|
|
|
|
|
+
|
|
|
|
|
+ hideLoading();
|
|
|
|
|
+ message.success('导出成功!');
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ if (hideLoading) hideLoading();
|
|
|
|
|
+ console.error('Excel导出失败:', error);
|
|
|
|
|
+ message.error('导出失败,请稍后重试');
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // ========== 初始化:先获取状态数据,再加载表格 ==========
|
|
|
|
|
+ onMounted(async () => {
|
|
|
|
|
+ await fetchProductionStatus(); // 先获取动态状态数据
|
|
|
|
|
+ await safeReloadActiveTable();
|
|
|
|
|
+ });
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped lang="less">
|
|
|
|
|
+ // .data-quality-page {
|
|
|
|
|
+ // padding: 0 12px;
|
|
|
|
|
+ // margin: 16px;
|
|
|
|
|
+ // border: 1px solid @border-color-base;
|
|
|
|
|
+ // .ant-form {
|
|
|
|
|
+ // background-color: #fff;
|
|
|
|
|
+ // }
|
|
|
|
|
+ // }
|
|
|
.form-part {
|
|
.form-part {
|
|
|
padding: 12px 10px 6px 10px;
|
|
padding: 12px 10px 6px 10px;
|
|
|
margin-bottom: 8px;
|
|
margin-bottom: 8px;
|
|
|
- background-color: #ffffff;
|
|
|
|
|
|
|
+ background-color: @white;
|
|
|
border-radius: 2px;
|
|
border-radius: 2px;
|
|
|
}
|
|
}
|
|
|
.add-button {
|
|
.add-button {
|