Files
supervision-test-frontend-repo/src/views/bg/bqtakepulse/BgTakepulseList.vue
T

851 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">
<!--查询区域-->
<div class="jeecg-basic-table-form-container">
<a-form ref="formRef" @keyup.enter.native="searchQuery" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-row :gutter="24">
<a-col :lg="6">
<a-form-item name="year">
<template #label><span title="年份">年份</span></template>
<j-select-multiple placeholder="请选择年份" v-model:value="queryParam.year" dictCode="super_year" allow-clear />
</a-form-item>
</a-col>
<a-col :lg="6">
<a-form-item name="taskType">
<template #label><span title="会议类型:行政线、技术线">会议类型</span></template>
<j-select-multiple placeholder="请选择会议类型:行政线、技术线" v-model:value="queryParam.taskType" dictCode="super_takepulse_type" allow-clear />
</a-form-item>
</a-col>
<template v-if="toggleSearchStatus">
<a-col :lg="6">
<a-form-item name="type">
<template #label><span title="类别:党的建设等其他">类别</span></template>
<a-input placeholder="请输入类别:党的建设等其他" v-model:value="queryParam.type" allow-clear ></a-input>
</a-form-item>
</a-col>
<a-col :lg="6">
<a-form-item name="responDeptid">
<template #label><span title="牵头部门">牵头部门</span></template>
<sz-select-dept placeholder="请选择牵头部门" v-model:value="queryParam.responDeptid" checkStrictly allow-clear />
</a-form-item>
</a-col>
<a-col :lg="6">
<a-form-item name="assistDeptid">
<template #label><span title="协办部门">协办部门</span></template>
<sz-select-dept placeholder="请选择协办部门" v-model:value="queryParam.assistDeptid" checkStrictly allow-clear />
</a-form-item>
</a-col>
</template>
<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 preIcon="ant-design:reload-outlined" @click="searchReset" style="margin-left: 8px">重置</a-button>
<a @click="toggleSearchStatus = !toggleSearchStatus" style="margin-left: 8px">
{{ toggleSearchStatus ? '收起' : '展开' }}
<Icon :icon="toggleSearchStatus ? 'ant-design:up-outlined' : 'ant-design:down-outlined'" />
</a>
</a-col>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!--引用表格-->
<BasicTable @register="registerTable" :rowSelection="rowSelection" :expandedRowKeys="expandedRowKeys" @expand="handleExpand" :rowClassName="(r) => r.bpmStatus ? 'status-row-' + r.bpmStatus : ''">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" v-auth="'bqtakepulse:bg_takepulse:add'" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="'bqtakepulse:bg_takepulse:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<a-button type="primary" v-auth="'bqtakepulse:bg_takepulse:exportXls'" preIcon="ant-design:download-outlined" @click="handleDownloadTemplate">下载模板</a-button>
<j-upload-button type="primary" v-auth="'bqtakepulse:bg_takepulse:importExcel'" preIcon="ant-design:check-outlined" @click="handleCheckExcel">模板校验</j-upload-button>
<j-upload-button type="primary" v-auth="'bqtakepulse:bg_takepulse: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="'bqtakepulse:bg_takepulse: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 }">
<TableAction stopButtonPropagation :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
</template>
<!--字段回显插槽-->
<template v-slot:bodyCell="{ column, record, index, text }">
</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" color="warning" style="color: #8c6900">未开始 {{ getFeedbackStatusCount(record).notStarted }}</a-tag>
<a-tag class="feedback-expand-count" color="error">进行中 {{ getFeedbackStatusCount(record).inProgress }}已逾期 {{ getFeedbackStatusCount(record).overdue }}</a-tag>
<a-tag class="feedback-expand-count" color="success">已完成 {{ getFeedbackStatusCount(record).completed }}</a-tag>
<a-tag class="feedback-expand-count">( {{ getFeedbackStatusCount(record).total }} )</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: 1780 }"
>
<template #feedbackAttachments="{ record: feedbackRecord }">
<SUploadFile
v-if="feedbackRecord.id"
class="feedback-attachment-list"
:bussiness-id="feedbackRecord.id"
:disabled="true"
:multiple="true"
/>
<span v-else>-</span>
</template>
</BasicTable>
</div>
</template>
</BasicTable>
<!-- 表单区域 -->
<BgTakepulseModal @register="registerModal" @success="handleSuccess"></BgTakepulseModal>
<!-- 审批记录 -->
<BpmPictureModal @register="registerBpmModal" />
<FlowScheduleStartModalForBG ref="flowScheduleModalRef" @confirm="handleFlowScheduleConfirm" />
<BusinessProcessListModal ref="businessProcessListModalRef" />
</div>
</template>
<script lang="ts" name="bqtakepulse-bgTakepulse" setup>
import {ref, reactive, onMounted} from 'vue';
import {BasicTable, TableAction} from '/@/components/Table';
import type { BasicColumn } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage'
import {useModal} from '/@/components/Modal';
import BgTakepulseModal from './components/BgTakepulseModal.vue'
import {columns, superQuerySchema} from './BgTakepulse.data';
import {list, statusStats, deleteOne, getImportUrl, getExportUrl, getImportExcelByEasyExcelUrl, getCheckExcelByEasyExcelUrl, getExportXlsHeadersUrl, saveOrUpdate, bgTakepulseFeedbackList} from './BgTakepulse.api';
import { defHttp } from '/@/utils/http/axios';
import { showImportValidationErrors } from '/@/utils/helper/importError';
import { useMessage } from '/@/hooks/web/useMessage';
import { countFeedbackStatus } from '/@/views/bg/utils/feedbackStatusCount';
import JSelectMultiple from '/@/components/Form/src/jeecg/components/JSelectMultiple.vue';
import SzSelectDept from '/@/components/Form/src/jeecg/components/SzSelectDept.vue';
import Icon from '/@/components/Icon/index';
import { startProcessSchedules } from '/@/api/common/api';
import { dateUtil } from '/@/utils/dateUtil';
import FlowScheduleStartModalForBG from '/src/components/semri/process/FlowScheduleStartModalForBG.vue';
import BusinessProcessListModal from '/src/components/semri/process/BusinessProcessListModal.vue';
import SUploadFile from '/@/components/semri/fileComponent/SUploadFile.vue';
import {batchDelete} from "@/views/bg/bqtakepulse/BgTakepulse.api";
const [registerBpmModal, { openModal: bpmPicModal }] = useModal();
const FLOW_CODE = 'dev_task_task_001';
const BUSINESS_TABLE_NAME = 'bg_takepulse';
const FORM_URL = 'bg/bqtakepulse/components/BgTakepulseBPMForm';
const FLOW_NAME = '我为四所把把脉';
const formRef = ref();
const queryParam = reactive<any>({});
const expandedRowKeys = ref<Array<string | number>>([]);
const feedbackTableData = reactive<Record<string, Recordable[]>>({});
const statsData = reactive({ notStarted: 0, inProgress: 0, overdue: 0, completed: 0 });
const feedbackTableLoading = reactive<Record<string, boolean>>({});
//注册model
const [registerModal, {openModal}] = useModal();
const flowScheduleModalRef = ref();
const businessProcessListModalRef = ref();
//注册table数据
const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
tableProps:{
title: '我为四所把把脉',
api: list,
columns,
canResize:false,
useSearchForm: false,
expandRowByClick: true,
clickToRowSelect: false,
rowSelection: { type: 'checkbox' },
actionColumn: {
width: 120,
fixed:'right'
},
beforeFetch: async (params) => {
return Object.assign(params, queryParam);
},
pagination: {
current: 1,
pageSize: 12,
pageSizeOptions: ['12', '24', '36'],
},
},
exportConfig: {
name:"我为四所把把脉",
url: getExportUrl,
params: queryParam,
},
importConfig: {
url: getImportUrl,
success: handleSuccess
},
})
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext
interface DeptOption {
label: string;
value: string;
}
// 反馈展开区只读展示子表数据,列配置与 BPM 办理页保持同一组核心反馈字段。
const feedbackExpandColumns: BasicColumn[] = [
{ title: '责任部门名称', dataIndex: 'responDeptname', align: 'center', width: 160 },
{ title: '反馈人姓名', dataIndex: 'responPersonname', align: 'center', width: 110 },
{ title: '计划完成目标', dataIndex: 'planExect', align: 'left', width: 260 },
{
title: '计划完成日期',
dataIndex: 'planTime',
align: 'center',
width: 120,
customRender: ({ text }) => (!text ? '' : String(text).slice(0, 10)),
},
{ title: '实际执行情况', dataIndex: 'actualExect', align: 'left', width: 280 },
{ title: '实际完成日期', dataIndex: 'actualTime', align: 'center', width: 155, customRender: ({ text }) => (!text ? '' : String(text).slice(0, 10)) },
{ title: '调整落实措施及执行情况', dataIndex: 'actSt', align: 'left', width: 260 },
{
title: '完成状态',
dataIndex: 'bpmStatus',
align: 'center',
width: 95,
customRender: ({ record }) => record?.bpmStatus_dictText || record?.bpmStatus,
},
{
title: '附件下载',
dataIndex: 'id',
key: 'attachments',
align: 'left',
width: 340,
slots: { customRender: 'feedbackAttachments' },
},
];
// 高级查询配置
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 getFeedbackStatusCount(record: Recordable) {
return countFeedbackStatus(getFeedbackTableData(record), 'bpmStatus', 'planTime');
}
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 bgTakepulseFeedbackList({
mainId,
pageNo: 1,
pageSize: 9999,
column: 'createTime',
order: 'desc',
});
feedbackTableData[key] = Array.isArray(res) ? res : res?.records || res?.result?.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 searchQuery() {
selectedRowKeys.value = [];
resetFeedbackExpand();
reload({ page: 1 });
}
async function fetchStatusStats() {
try {
const params: Recordable = {};
Object.keys(queryParam).forEach((key) => {
if (queryParam[key] !== undefined && queryParam[key] !== null && queryParam[key] !== '') {
params[key] = queryParam[key];
}
});
const res = await statusStats(params);
if (res) {
Object.assign(statsData, res);
}
} catch (e) {
// stats fetch failure is non-critical
}
}
onMounted(() => {
fetchStatusStats();
});
/**
* 新增事件
*/
function handleAdd() {
openModal(true, {
isUpdate: false,
showFooter: true,
});
}
/**
* 编辑事件
*/
function handleEdit(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: true,
});
}
/**
* 详情
*/
function handleDetail(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: false,
});
}
/**
* 删除事件
*/
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();
}
/**
* 操作栏
*/
function getTableAction(record){
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'bqtakepulse:bg_takepulse:edit'
}
]
}
/**
* 下拉操作栏
*/
function getDropDownAction(record){
let dropDownAction = [
{
label: '详情',
onClick: handleDetail.bind(null, record),
}, {
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record)
},
auth: 'bqtakepulse:bg_takepulse:delete'
},
// {
// label: '审批进度',
// onClick: handlePreviewPic.bind(null, record),
// ifShow: !!record.bpmStatus && record.bpmStatus !== '1',
// },
{
label: '查询督办流程',
onClick: handleQueryProcess.bind(null, record),
}
];
if(record.bpmStatus == '1' || !record.bpmStatus){
dropDownAction.push({
label: '发起督办流程',
onClick: handleProcess.bind(null, record),
})
}
if(record.bpmStatus == '2' || !record.bpmStatus){
dropDownAction.push({
label: '再次督办',
onClick: handleProcess.bind(null, record),
})
}
return dropDownAction;
}
/**
* 提交流程
*/
function handleProcess(record) {
flowScheduleModalRef.value?.open({
title: '发起流程',
taskTitle: record?.title,
payload: { record },
deptOptions: getResponsibleDeptOptions(record),
showSuoleaderFields: true,
isNeedAppro: record?.isNeedAppro,
supDeptleaderid: record?.supDeptleaderid,
showDeadlineField: true,
deadline: record?.deadline,
showUrgencyLevelField: true,
urgencyLevel: record?.urgencyLevel,
});
}
function splitDeptValue(value) {
if (Array.isArray(value)) {
return value.map((item) => String(item || '').trim()).filter(Boolean);
}
return String(value || '')
.split(/[,\uFF0C]/)
.map((item) => item.trim())
.filter(Boolean);
}
function getResponsibleDeptOptions(record): DeptOption[] {
const optionMap = new Map<string, DeptOption>();
[
{
ids: splitDeptValue(record?.responDeptid),
names: splitDeptValue(record?.responDeptid_dictText || record?.responDeptname),
},
{
ids: splitDeptValue(record?.assistDeptid),
names: splitDeptValue(record?.assistDeptid_dictText || record?.assistDeptname),
},
].forEach(({ ids, names }) => {
ids.forEach((deptId, index) => {
if (optionMap.has(deptId)) {
return;
}
optionMap.set(deptId, {
value: deptId,
label: names[index] || deptId,
});
});
});
return Array.from(optionMap.values());
}
function getResponsibleDeptIds(record) {
return getResponsibleDeptOptions(record)
.map((item) => item.value)
.join(',');
}
function getNextSuperviseCount(value) {
const count = Number(value || 0);
return Number.isFinite(count) ? count + 1 : 1;
}
function handleQueryProcess(record) {
businessProcessListModalRef.value?.open({
title: '流程列表',
businessId: record.id,
columns: '',
});
}
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.title || '';
const selectedDeadline = options.deadline || record.deadline;
const selectedUrgencyLevel = options.urgencyLevel ?? record.urgencyLevel ?? '0';
const defaultDeptIds = getResponsibleDeptIds(record);
const flowJsonData = {
...record,
isNeedAppro: options.isNeedAppro ?? record.isNeedAppro ?? '',
supDeptleaderid: options.supDeptleaderid ?? record.supDeptleaderid ?? '',
superviseCount: nextSuperviseCount,
// 用户可在发起前确认本次督办标题,仅影响流程数据,不回写台账标题。
title: selectedTitle,
deadline: selectedDeadline,
// 紧急标记随本次流程发起传出,业务表只回写状态和督办次数。
urgencyLevel: selectedUrgencyLevel,
// 首节点自动完成时读取该字段写入审批历史。
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: FLOW_NAME,
jsonData: flowJsonData,
businessTablename: BUSINESS_TABLE_NAME,
businessId: record.id,
title: selectedTitle,
content: record.content,
urgencyLevel: selectedUrgencyLevel,
deptId: options.deptId || defaultDeptIds,
deptLeaderId: record.responDeptid,
requireFinishDate: formatDate(selectedDeadline, 'YYYY-MM-DD'),
deadline: formatDeadlineDateTime(selectedDeadline),
},
};
await startProcessSchedules(params);
await saveOrUpdate({ id: record.id, bpmStatus: '2', superviseCount: nextSuperviseCount }, true);
handleSuccess();
}
/**
* 审批进度
*/
async function handlePreviewPic(record) {
bpmPicModal(true, {
flowCode: FLOW_CODE,
dataId: record.id,
});
}
/* ----------------------以下为原生查询需要添加的-------------------------- */
const { createMessage } = useMessage();
const toggleSearchStatus = ref<boolean>(false);
const labelCol = reactive({
xs:24,
sm:4,
xl:6,
xxl:4
});
const wrapperCol = reactive({
xs: 24,
sm: 20,
});
/**
* 重置
*/
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 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 });
}
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 });
}
function searchReset() {
formRef.value.resetFields();
selectedRowKeys.value = [];
resetFeedbackExpand();
//刷新数据
reload({ page: 1 });
}
/**
* form点击事件(以逗号分割)
* @param key
* @param value
*/
function handleFormJoinChange(key, value) {
if (typeof value != 'string') {
queryParam[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%;
}
}
.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;
}
.feedback-attachment-list {
min-width: 300px;
:deep(.file-list-wrapper) {
min-height: 0 !important;
padding: 4px 8px !important;
}
:deep(.ant-spin-nested-loading),
:deep(.ant-spin-container) {
min-height: 0 !important;
line-height: 20px;
}
:deep(.file-list-header) {
margin-bottom: 6px;
padding-bottom: 6px;
}
:deep(.file-list .file-item) {
padding: 8px;
margin-bottom: 6px;
}
:deep(.ant-empty) {
margin: 0 !important;
display: flex;
align-items: center;
min-height: 20px;
text-align: left;
}
:deep(.ant-empty-image) {
display: none !important;
}
:deep(.ant-empty-description) {
color: #94a3b8;
font-size: 12px;
line-height: 20px;
}
}
}
</style>
<style lang="less">
.status-row-1 td {
background: #fffbe6 !important;
}
.status-row-2 td {
background: #fff1f0 !important;
}
.status-row-3 td {
background: #f6ffed !important;
}
</style>