| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621 |
- <template>
- <SmartTable
- v-loading="loading"
- ref="smartTableRef"
- v-model:pageNo="pageNo"
- v-model:pageSize="pageSize"
- v-model:total="total"
- v-model:formData="searchFormData"
- v-model:columns="columns"
- :useOnlineHeader="true"
- :tableHeaderSetting="'检验校核'"
- :showSettingTools="true"
- :data="tableData"
- :buttons="buttons"
- :tableProps="{
- onRowDblclick: handleVerifyCLick
- }"
- @on-page-no-change="() => fetchTaskVerifyList()"
- @on-page-size-change="() => fetchTaskVerifyList()"
- @on-reset="() => fetchTaskVerifyList()"
- @on-search="() => fetchTaskVerifyList()"
- @refresh="() => fetchTaskVerifyList()"
- />
- <FunctionalHistory v-if="isShowHistory" v-model="isShowHistory" :id="historyId" />
- <RejectDialog
- v-if="isShowRevert"
- v-model:modelValue="isShowRevert"
- :apiParams="revertParams"
- :apiFn="revertTaskVerify"
- reasonProp="verifyRollbackReason"
- @success="handleRevertSuccess"
- />
- </template>
- <script lang="tsx" setup>
- import SmartTable from '@/components/SmartTable/SmartTable'
- const RejectDialog = defineAsyncComponent(
- () => import('@/views/Functional/components/RejectDialog.vue')
- )
- const FunctionalHistory = defineAsyncComponent(
- () => import('@/views/Functional/components/FunctionalHistory.vue')
- )
- import { getTaskVerifyList, revertTaskVerify } from '@/api/laboratory/functional/task'
- import { useRouter } from 'vue-router'
- import { Close, Operation, ArrowDown, ArrowUp, Plus } from '@element-plus/icons-vue'
- import { useDictStore } from '@/store/modules/dict'
- import dayjs from 'dayjs'
- import _ from 'lodash'
- import { log } from 'console'
- import { SmartInstanceExpose } from '@/types/table'
- import { useEmitt } from '@/hooks/web/useEmitt'
- defineOptions({ name: 'TaskVerifyIndex' })
- const { emitter } = useEmitt()
- const dictStore = useDictStore()
- const router = useRouter()
- const getCheckTypes = computed(() => dictStore.getDictMap['laboratory_inspection_category'])
- const getTaskVerifyStatus = computed(
- () => dictStore.getDictMap['laboratory_inspection_entry_verify_status']
- )
- const smartTableRef = ref<SmartInstanceExpose>()
- const getYesNoOptions = computed(() => [
- { label: '是', value: '1' },
- { label: '否', value: '0' }
- ])
- const columns = shallowRef([
- {
- type: 'selection',
- fieldProps: {
- minWidth: 50,
- },
- },
- {
- type: 'index',
- label: '序号',
- fieldProps: {
- minWidth: 55,
- },
- },
- {
- label: '当前状态',
- prop: 'verifyStatusList',
- search: {
- type: 'select',
- options: getTaskVerifyStatus.value,
- fieldProps: {
- multiple: true
- }
- },
- fieldProps: {
- minWidth: 130,
- },
- render(row, value) {
- let type = 'info'
- switch (row.verifyStatus) {
- case '0':
- type = 'primary'
- break
- case '1':
- type = 'info'
- break
- case '2':
- type = 'warning' // 回退
- break
- default:
- type = 'info' // 默认类型
- }
- return row.verifyStatus === null || row.verifyStatus === undefined || row.verifyStatus === '' ? (
- '-'
- ) : (
- <el-tag type={type} onClick={() => handleGetRevertReasonFn(row)}>
- {getTaskVerifyStatus.value.find((x) => x.value === row.verifyStatus)?.label}
- </el-tag>
- )
- }
- },
- {
- label: '委托单位',
- prop: 'entrustUnitName',
- fieldProps: {
- minWidth: 200,
- },
- showOverflowTooltip: true,
- search: {
- type: 'input'
- }
- },
- {
- prop: 'itemNames',
- label: '检验检测项目',
- fieldProps: {
- minWidth: 300,
- },
- render: (row) => {
- return (
- <div>
- {row.itemNames && row.itemNames.length > 0 ? (
- <div className="reportDOList-item">
- <div
- className={`report-name-list ${isExpanded(row) ? 'expanded' : 'collapsed'}`}
- style={{
- maxHeight: isExpanded(row) ? `${row.itemNames.length * 40}px` : '80px',
- transition: 'all 0.4s cubic-bezier(0.4, 0, 0.2, 1)',
- overflow: 'hidden'
- }}
- >
- {row.itemNames.map((item, index) => (
- <div
- key={index}
- className="report-item-animated"
- style={{
- opacity: isExpanded(row) || index < 3 ? 1 : 0,
- transform:
- isExpanded(row) || index < 3 ? 'translateY(0)' : 'translateY(-10px)',
- transition: `all 0.3s ease ${index * 50}ms`,
- padding: '2px 0'
- }}
- >
- {index + 1}、{item}
- </div>
- ))}
- </div>
- {row.itemNames.length > 3 && (
- <div style={{ textAlign: 'center', marginTop: '10px' }}>
- <el-button
- size="small"
- link
- type="primary"
- onClick={() => toggleExpand(row)}
- style={{
- transition: 'all 0.2s ease',
- transform: 'translateY(0)'
- }}
- onMouseEnter={(e) => {
- e.target.style.transform = 'translateY(-1px)'
- }}
- onMouseLeave={(e) => {
- e.target.style.transform = 'translateY(0)'
- }}
- >
- <span style={{ marginRight: '4px' }}>
- {isExpanded(row) ? '收起' : `查看更多(${row.itemNames.length - 3}条)`}
- </span>
- <span
- style={{
- width: '12px',
- height: '12px',
- display: 'inline-block',
- transition: 'transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)',
- transform: isExpanded(row) ? 'rotate(180deg)' : 'rotate(0deg)'
- }}
- >
- <ArrowDown />
- </span>
- </el-button>
- </div>
- )}
- </div>
- ) : (
- <div>-</div>
- )}
- </div>
- )
- }
- },
- {
- label: '样品名称',
- prop: 'sampleName',
- fieldProps: {
- minWidth: 200,
- },
- showOverflowTooltip: true,
- search: {
- type: 'input'
- },
- render(row, value) {
- return !row.sampleName
- ? '-'
- : <>{row.sampleName.split(';').map((y, index) => <div key={index}>{y}</div>)}</>
- }
- },
- {
- label: '样品编号',
- prop: 'sampleReportNo',
- fieldProps: {
- minWidth: 200,
- },
- showOverflowTooltip: true,
- search: {
- type: 'input'
- },
- render(row, value) {
- return !row.sampleReportNoList
- ? '-'
- : row.sampleReportNoList
- .map((y) => <div>{y}</div>)
- }
- },
- {
- label: '合同/协议编号',
- prop: 'contractNo',
- search: {
- type: 'input'
- },
- fieldProps: {
- minWidth: 160,
- },
- showOverflowTooltip: true,
- render: (row, value) => row.contractNo || row.acceptanceNo || '-'
- },
- {
- label: '记录编号',
- prop: 'reportNo',
- fieldProps: {
- minWidth: 160,
- },
- showOverflowTooltip: true,
- search: {
- type: 'input'
- }
- },
- {
- label: '检验类别',
- prop: 'checkType',
- search: {
- type: 'select',
- options: getCheckTypes.value
- },
- fieldProps: {
- minWidth: 140,
- },
- showOverflowTooltip: true,
- render(row, value) {
- return !value
- ? '-'
- : value
- .split(',')
- .map((y) => <div>{getCheckTypes.value.find((x) => x.value === y)?.label}</div>)
- }
- },
- {
- label: '检验人',
- prop: 'checkByName',
- fieldProps: {
- minWidth: 160,
- },
- showOverflowTooltip: true,
- search: {
- type: 'input'
- }
- },
- {
- label: '检验日期',
- prop: 'createTime',
- fieldProps: {
- minWidth: 160,
- },
- showOverflowTooltip: true,
- search: {
- type: 'daterange'
- },
- render(row, value) {
- return !value ? '-' : dayjs(value).format('YYYY-MM-DD')
- }
- },
- {
- label: '检验费用',
- fieldProps: {
- minWidth: 100,
- },
- showOverflowTooltip: true,
- prop: 'inspectionFees',
- },
- {
- label: '是否加急',
- fieldProps: {
- minWidth: 120,
- },
- showOverflowTooltip: true,
- prop: 'isUrgent',
- search: {
- type: 'select',
- options: getYesNoOptions.value,
- placeholder: '请选择是否加急'
- },
- render(row, value) {
- return !value ? (
- '-'
- ) : (
- <el-tag type={value === '0' ? 'danger' : 'success'}>{value === '0' ? '否' : '是'}</el-tag>
- )
- }
- },
- {
- label: '操作',
- prop: 'Operation',
- fieldProps: {
- fixed: 'right',
- minWidth: 90,
- },
- render(row) {
- // <el-button link type="primary" onClick={() => handleTabelRowDbCLick(row)}>
- // {isVerificationPending ? '校核' : '查看'}
- // </el-button>
- const isVerificationPending = ['0'].includes(row.verifyStatus);
- return (
- <>
- <el-button link type="primary" onClick={() => handleVerifyCLick(row)}>
- {isVerificationPending ? '校核' : '查看'}
- </el-button>
- </>
- );
- },
- }
- ])
- const buttons = shallowRef([
- {
- render: () => (
- <el-button type="primary" onClick={handleBatchRevertStatus}>
- <el-icon>
- <Close />
- </el-icon>
- 批量退回
- </el-button>
- )
- },
- {
- render: () => (
- <el-button type="primary" onClick={handleGetTaskHistory}>
- 流转记录
- </el-button>
- )
- },
- // {
- // render: () => (
- // <el-button type="primary" onClick={handleGetRevertReason}>
- // <el-icon>
- // <Operation />
- // </el-icon>
- // 查看回退原因
- // </el-button>
- // )
- // },
- {
- label: '展开全部检验检测项目',
- render: () => {
- return (
- <el-button
- type={isAllExpanded.value ? 'warning' : 'info'}
- disabled={tableData.value.length === 0}
- onClick={toggleExpandAll}
- style={{ marginLeft: '8px' }}
- >
- {isAllExpanded.value}
- <el-icon>{isAllExpanded.value ? <ArrowUp /> : <ArrowDown />}</el-icon>
- {isAllExpanded.value ? '收起全部检验检测项目' : '展开全部检验检测项目'}
- </el-button>
- )
- }
- }
- ])
- const searchFormData = ref({verifyStatusList: ['0', '2']})
- const pageNo = ref(1)
- const pageSize = ref(10)
- const total = ref(0)
- const loading = ref(false)
- const tableData = ref([])
- // 双击进入任务详情
- const handleTabelRowDbCLick = (row, column?, event?) => {
- router.push({
- name: 'TaskVerifyDetail',
- query: {
- id: row.id
- }
- })
- event?.preventDefault()
- event?.stopPropagation()
- }
- const handleVerifyCLick = (row, column?, event?) => {
- router.push({
- name: 'TaskVerifyDetail',
- query: {
- id: row.id
- }
- })
- event?.preventDefault()
- event?.stopPropagation()
- }
- // 获取任务管理列表
- const fetchTaskVerifyList = async () => {
- // const { verifyStatusList } = searchFormData.value as any
- const params = {
- pageNo: pageNo.value,
- pageSize: pageSize.value,
- ...searchFormData.value,
- // verifyStatusList: verifyStatusList,
- createTime:
- _.has(searchFormData.value, 'createTime') && _.get(searchFormData.value, 'createTime')
- ? [
- dayjs(_.get(searchFormData.value, 'createTime')[0])
- .startOf('day')
- .format('YYYY-MM-DD HH:mm:ss'),
- dayjs(_.get(searchFormData.value, 'createTime')[1])
- .endOf('day')
- .format('YYYY-MM-DD HH:mm:ss')
- ]
- : undefined
- }
- // delete params.verifyStatus
- const result = await getTaskVerifyList(params)
- tableData.value = result.list
- total.value = result.total
- }
- // 批量回退
- const revertParams = ref({})
- const isShowRevert = ref(false)
- const handleBatchRevertStatus = async (status) => {
- const selectedRows = smartTableRef.value?.getTableRef().getSelectionRows()
- if (!selectedRows || selectedRows.length === 0) {
- ElMessage.warning('请选择回退')
- return
- }
- revertParams.value = {
- ids: selectedRows.map((item) => item.id)
- }
- isShowRevert.value = true
- }
- const handleRevertSuccess = async () => {
- await fetchTaskVerifyList()
- }
- // 查看回退原因
- const handleGetRevertReason = () => {
- const selectedRows = smartTableRef.value?.getTableRef().getSelectionRows()
- if (!selectedRows || selectedRows.length === 0) {
- ElMessage.warning('请选择')
- return
- } else if (selectedRows.length > 1) {
- ElMessage.warning('只能选择一个')
- return
- }
- if (selectedRows[0].verifyStatus !== '2') {
- ElMessage.warning('非回退状态')
- return
- }
- ElMessageBox.confirm(selectedRows[0].verifyRollbackReason, '回退原因', {
- confirmButtonText: '确定',
- cancelButtonText: '取消'
- })
- }
- // 查看回退原因
- const handleGetRevertReasonFn = (row) => {
- // const selectedRows = smartTableRef.value?.getTableRef().getSelectionRows()
- // if (!selectedRows || selectedRows.length === 0) {
- // ElMessage.warning('请选择')
- // return
- // } else if (selectedRows.length > 1) {
- // ElMessage.warning('只能选择一个')
- // return
- // }
- if (row.verifyStatus !== '2') {
- ElMessage.warning('非回退状态')
- return
- }
- ElMessageBox.confirm(row.verifyRollbackReason, '回退原因', {
- confirmButtonText: '确定',
- cancelButtonText: '取消'
- })
- }
- // 流转记录
- const isShowHistory = ref(false)
- const historyId = ref('')
- const handleGetTaskHistory = () => {
- const selectedRows = smartTableRef.value?.getTableRef().getSelectionRows()
- if (!selectedRows || selectedRows.length === 0) {
- ElMessage.warning('请选择受理单')
- return
- } else if (selectedRows.length > 1) {
- ElMessage.warning('只能选择一个受理单')
- return
- }
- historyId.value = selectedRows[0].businessAcceptanceId
- isShowHistory.value = true
- }
- // 管理展开状态
- const expandedRows = ref(new Set())
- // 添加全部展开状态管理
- const isAllExpanded = ref(false)
- // 全部展开/收起方法
- const toggleExpandAll = () => {
- if (isAllExpanded.value) {
- // 全部收起
- expandedRows.value.clear()
- isAllExpanded.value = false
- } else {
- // 全部展开
- const newExpandedRows = new Set()
- tableData.value.forEach((row: any) => {
- const rowId = row.id || row.key || JSON.stringify(row)
- if (row.itemNames && row.itemNames.length > 3) {
- newExpandedRows.add(rowId)
- }
- })
- expandedRows.value = newExpandedRows
- isAllExpanded.value = true
- }
- }
- // 监听表格数据变化,自动更新全部展开状态
- watch(
- () => expandedRows.value.size,
- () => {
- // 检查是否所有可展开的行都已展开
- const expandableRows = tableData.value.filter(
- (row: any) => row.itemNames && row.itemNames.length > 3
- )
- const allExpandableRowsExpanded =
- expandableRows.length > 0 &&
- expandableRows.every((row: any) => {
- const rowId = row.id || row.key || JSON.stringify(row)
- return expandedRows.value.has(rowId)
- })
- isAllExpanded.value = allExpandableRowsExpanded
- },
- { deep: true }
- )
- watch(
- () => tableData.value,
- () => {
- // 检查是否所有可展开的行都已展开
- const expandableRows = tableData.value.filter(
- (row: any) => row.itemNames && row.itemNames.length > 3
- )
- const allExpandableRowsExpanded =
- expandableRows.length > 0 &&
- expandableRows.every((row: any) => {
- const rowId = row.id || row.key || JSON.stringify(row)
- return expandedRows.value.has(rowId)
- })
- isAllExpanded.value = allExpandableRowsExpanded
- },
- { deep: true }
- )
- // 切换展开状态
- const toggleExpand = (row) => {
- const rowId = row.id || row.key || JSON.stringify(row)
- const newExpandedRows = new Set(expandedRows.value)
- if (newExpandedRows.has(rowId)) {
- newExpandedRows.delete(rowId)
- } else {
- newExpandedRows.add(rowId)
- }
- expandedRows.value = newExpandedRows
- }
- // 检查是否展开
- const isExpanded = (row) => {
- const rowId = row.id || row.key || JSON.stringify(row)
- return expandedRows.value.has(rowId)
- }
- onMounted(() => {
- smartTableRef.value?.setSearchForm(searchFormData.value)
- fetchTaskVerifyList()
- emitter.on('refresh-TaskVerifyIndex-list', ()=> {
- fetchTaskVerifyList();
- })
- })
- onUnmounted(() => {
- emitter.off('refresh-TaskVerifyIndex-list')
- })
- </script>
- <style scoped lang="scss">
- :deep(.el-table) {
- .el-table__row {
- cursor: pointer;
- }
- }
- </style>
|