| | |
| | | <el-tab-pane |
| | | v-for="tab in filteredTabs" |
| | | :key="tab.name" |
| | | :label="`${tab.label} (${tab.count})`" |
| | | :label="tab.name === 'myTickets' ? tab.label : `${tab.label} (${tab.count})`" |
| | | :name="tab.name" |
| | | > |
| | | <basic-main-content> |
| | |
| | | <el-col :span="5"> |
| | | <el-form-item label="选择日期:"> |
| | | <el-date-picker |
| | | clearable |
| | | @clear="handleKeyWords" |
| | | @change="handleSearch" |
| | | v-model="filters.dateRange" |
| | | type="daterange" |
| | | class="filter-item" |
| | |
| | | /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-col :span="4" v-if="activeTab === 'completed'"> |
| | | <el-form-item label="复核状态:"> |
| | | <el-select |
| | | v-model="filters.isReview" |
| | |
| | | > |
| | | 批量审核 |
| | | </el-button> |
| | | |
| | | |
| | | <el-button |
| | | v-if="permissionList.exportBtn" |
| | | type="success" |
| | |
| | | ref="elTable" |
| | | :data="tableData" |
| | | v-loading="loading" |
| | | |
| | | @selection-change="handleSelectionChange" |
| | | border |
| | | style="width: 100%" |
| | |
| | | <el-tooltip-copy :content="row.orderNumber" :showCopyText="true" textAlign="left"> |
| | | {{ row.orderNumber }} |
| | | </el-tooltip-copy> |
| | | |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column prop="orderName" label="工单名称" width="150" show-overflow-tooltip> |
| | | <template #default="{ row }"> |
| | | <el-tooltip-copy :content="row.orderName" :showCopyText="true" textAlign="left"> |
| | |
| | | </el-tooltip-copy> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | |
| | | <el-table-column prop="department" label="所属部门" show-overflow-tooltip /> |
| | | |
| | | |
| | | <el-table-column prop="startTime" label="发起任务时间" width="160" show-overflow-tooltip /> |
| | | |
| | | |
| | | <el-table-column prop="aiType" label="关联算法" show-overflow-tooltip /> |
| | | |
| | | |
| | | <el-table-column prop="type" label="工单类型" width="110" show-overflow-tooltip> |
| | | <template #default="{ row }"> |
| | | {{ getTypeLabel(row.type) }} |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | |
| | | <el-table-column prop="content" label="工单内容" width="132" show-overflow-tooltip> |
| | | <template #default="{ row }"> |
| | | {{ row.address || row.content }} |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | |
| | | <el-table-column prop="creator" label="创建人" width="120" show-overflow-tooltip /> |
| | | |
| | | |
| | | <el-table-column prop="handler" label="处理人" width="120" show-overflow-tooltip /> |
| | | |
| | | <el-table-column |
| | | v-if="['all', 'completed', 'myTickets'].includes(activeTab)" |
| | | label="复核状态" |
| | | prop="isReview" |
| | | |
| | | <el-table-column |
| | | v-if="['all', 'completed', 'myTickets'].includes(activeTab)" |
| | | label="复核状态" |
| | | prop="isReview" |
| | | width="90" |
| | | > |
| | | <template #default="{ row }"> |
| | | <span>{{ showIsReviewText(row) }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | |
| | | <el-table-column label="工单状态" prop="status" width="90"> |
| | | <template #default="{ row }"> |
| | | <span :style="getStatusTagType(row.status) ? 'color:' + getStatusTagType(row.status) : ''"> |
| | |
| | | </span> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | |
| | | <!-- 操作列 --> |
| | | <el-table-column label="操作" width="200" align="center"> |
| | | <template #default="{ row }"> |
| | |
| | | 删除 |
| | | </el-button> |
| | | </template> |
| | | |
| | | |
| | | <template v-else> |
| | | <el-button type="text" icon="el-icon-view" @click="handleViewDetail(row)">详情</el-button> |
| | | </template> |
| | | |
| | | <template v-if="row.status === 4 && activeTab === 'completed'"> |
| | | |
| | | <template v-if="row.status === 4 && !isProd"> |
| | | <el-button type="text" icon="el-icon-download" @click="exportTheTick(row)">导出</el-button> |
| | | </template> |
| | | |
| | | |
| | | <template v-if="permission.tickets_repeat_review"> |
| | | <el-button |
| | | v-if="row.status === 4 && row.isReview !== 1" |
| | |
| | | <dispatch-dialog |
| | | v-model="dispatchDialogVisible" |
| | | :current-detail="currentDetail" |
| | | :departments="departments" |
| | | :department-users="departmentUsers" |
| | | :algorithms="algorithms" |
| | | :types="types" |
| | |
| | | @dispatch-error="handleDispatchError" |
| | | /> |
| | | |
| | | <!-- 添加在其他 dialog 组件之后 --> |
| | | <!-- 批量审核对话框 --> |
| | | <el-dialog |
| | | v-model="reviewDialogVisible" |
| | | title="批量审核" |
| | | width="1100" |
| | | align-center |
| | | append-to-body |
| | | class="ztzf-dialog-mange" |
| | | custom-class="review-dialog" |
| | |
| | | :recheck-data="reCheckData" |
| | | @recheck-success="handleRecheckSuccess" |
| | | /> |
| | | |
| | | </basic-container> |
| | | </template> |
| | | |
| | |
| | | import CreateTicketDialog from '@/views/tickets/ticketComponent/CreateTicketDialog.vue'; |
| | | import TicketDetailDialog from '@/views/tickets/ticketComponent/TicketDetailDialog.vue'; |
| | | const { envName } = getBaseConfig(); |
| | | const isProd = import.meta.env.VITE_APP_ENV === 'production' |
| | | const route = useRoute() |
| | | const router = useRouter() |
| | | const store = useStore() |
| | |
| | | { label: '是', value: 1 }, |
| | | ]) |
| | | const tableData = ref([]) |
| | | const option = reactive({ |
| | | border: true, |
| | | stripe: false, |
| | | selection: true, |
| | | index: true, |
| | | indexLabel: '序号', |
| | | indexWidth: 60, |
| | | menuWidth: 150, |
| | | searchMenuSpan: 6, |
| | | viewBtn: false, |
| | | editBtn: false, |
| | | delBtn: false, |
| | | addBtn: false, |
| | | menu: true, |
| | | page: true, |
| | | height: 'auto', |
| | | calcHeight: 196, |
| | | column: [ |
| | | { label: '工单编号', prop: 'orderNumber', width: 170 }, |
| | | { label: '工单名称', prop: 'orderName', width: 150, overHidden: true, tooltip: true }, |
| | | { label: '所属部门', prop: 'department', overHidden: true, tooltip: true }, |
| | | { label: '发起任务时间', prop: 'startTime', width: 160, overHidden: true }, |
| | | { label: '关联算法', prop: 'aiType', overHidden: true, tooltip: true }, |
| | | { |
| | | label: '工单类型', |
| | | prop: 'type', |
| | | width: 110, |
| | | overHidden: true, |
| | | tooltip: true, |
| | | type: 'select', |
| | | dicData: [], |
| | | }, |
| | | { |
| | | label: '工单内容', |
| | | prop: 'content', |
| | | slot: true, |
| | | width: 152, |
| | | overHidden: true, |
| | | }, |
| | | { label: '创建人', prop: 'creator', width: 120, overHidden: true }, |
| | | { label: '处理人', prop: 'handler', width: 120, overHidden: true }, |
| | | { |
| | | slot: true, |
| | | hide: envName === 'jiangwu' ? true : false, |
| | | label: '复核状态', |
| | | prop: 'isReview', |
| | | width: 90, |
| | | }, |
| | | { label: '工单状态', prop: 'status', slot: true, width: 90 }, |
| | | ], |
| | | }) |
| | | const page = reactive({ |
| | | pageSize: 10, |
| | | currentPage: 1, |
| | |
| | | }) |
| | | const dispatchDialogVisible = ref(false) |
| | | const stepInfos = ref([]) |
| | | const fixedStatuses = ref(['2', '0', '3', '4']) |
| | | const userNameToIdMap = ref({}) |
| | | const workType = ref(0) |
| | | const selections = ref([]) |
| | |
| | | const checkedKeys = ref([]) |
| | | const inputMapShowDefaultCenter = ref(null) |
| | | const userInfo = computed(() => store.state.user.userInfo) |
| | | console.log('userInfo',userInfo); |
| | | const permission = computed(() => store.state.user.permission); |
| | | |
| | | // 计算属性 |
| | | const firstRowData = computed(() => { |
| | | return tableData.value.length > 0 ? tableData.value[0] : null |
| | | }) |
| | | // 动态过滤tabs,保证isShow为true/false |
| | | const filteredTabs = computed(() => { |
| | | const tabStatus = permission.value?.tickets_tab_status === true |
| | | const tabPending = permission.value?.tickets_tab_pending === true |
| | | const tabMyTickets = permission.value?.tickets_tab_mytickets === true |
| | | |
| | | const tabPending = permission.value?.tickets_tab_pending === true//待审核 |
| | | const tabMyTickets = permission.value?.tickets_tab_mytickets === true //我的工单 |
| | | const tabALL = permission.value?.tickets_allWorkOrders === true //全部工单 |
| | | const tabInProgress= permission.value?.tickets_inProgress === true //处理中 |
| | | const tabProcessing= permission.value?.tickets_pending === true //待处理 |
| | | const tabCompleted= permission.value?.tickets_wasDone === true //已完成 |
| | | return tabs.value |
| | | .map(tab => { |
| | | if (tab.name === 'all') { |
| | | return { ...tab, isShow: true } |
| | | .map(tab => { |
| | | switch (tab.name) { |
| | | case 'all': |
| | | return { ...tab, isShow: tabALL } // 全部工单 |
| | | case 'pending': |
| | | return { ...tab, isShow: tabPending } // 待审核 |
| | | case 'myTickets': |
| | | return { ...tab, isShow: tabMyTickets } // 我的工单 |
| | | case 'processing': |
| | | return { ...tab, isShow: tabProcessing } // 待处理 |
| | | case 'inProgress': |
| | | return { ...tab, isShow: tabInProgress } // 处理中 |
| | | case 'completed': |
| | | return { ...tab, isShow: tabCompleted } // 已完成 |
| | | default: |
| | | return { ...tab, isShow: false } // 其他标签默认隐藏 |
| | | } |
| | | if (tab.name === 'pending') { |
| | | return { ...tab, isShow: tabPending } |
| | | } |
| | | if (['processing', 'inProgress', 'completed', 'closed'].includes(tab.name)) { |
| | | return { ...tab, isShow: tabStatus } |
| | | } |
| | | if (tab.name === 'myTickets') { |
| | | return { ...tab, isShow: tabMyTickets } |
| | | } |
| | | return { ...tab, isShow: false } |
| | | }) |
| | | .filter(tab => tab.isShow) |
| | | }) |
| | |
| | | addBtn: validData(permission.value.tickets_add, false), |
| | | delBtn: validData(permission.value.tickets_delete, false), |
| | | exportBtn: validData(permission.value.tickets_export, false), |
| | | reviewBtn: validData(permission.value.tickets_review, false), |
| | | reviewBtn: validData(permission.value.tickets_review_btn, false), |
| | | } |
| | | }) |
| | | const stepStatusList = computed(() => { |
| | | // “我发起的工单”tab用默认流程,其它tab用接口返回的stepInfos |
| | | if (activeTab.value === 'myTickets') { |
| | | if (workType.value === 1) { |
| | | return ['3', '4'] |
| | | } |
| | | return fixedStatuses.value |
| | | // 计算默认激活的标签(无全部工单时优先激活待审核) |
| | | const defaultActiveTab = computed(() => { |
| | | const hasAllTab = filteredTabs.value.some(tab => tab.name === 'all') |
| | | const hasPendingTab = filteredTabs.value.some(tab => tab.name === 'pending') |
| | | |
| | | // 如果没有全部工单权限,但有待审核权限,则默认显示待审核 |
| | | if (!hasAllTab && hasPendingTab) { |
| | | return 'pending' |
| | | } |
| | | // 其它tab直接用接口返回的stepInfos |
| | | // 如果有全部工单权限,则默认显示全部工单 |
| | | else if (hasAllTab) { |
| | | return 'all' |
| | | } |
| | | // 否则显示第一个可用的tab |
| | | else { |
| | | return filteredTabs.value[0]?.name || 'all' |
| | | } |
| | | }) |
| | | // 提取状态列表计算属性 |
| | | const statusList = computed(() => { |
| | | const visibleTabs = filteredTabs.value; |
| | | return visibleTabs |
| | | .filter(tab => tab.name !== 'all' && tab.name !== 'myTickets' && tab.value !== undefined) |
| | | .map(tab => String(tab.value)); |
| | | }); |
| | | const stepStatusList = computed(() => { |
| | | return stepInfos.value.map(step => String(step.status)) |
| | | }) |
| | | const showIsReviewText = computed(() => (row) => { |
| | |
| | | })) |
| | | }) |
| | | // 方法 |
| | | function regExp(label, name) { |
| | | const reg = new RegExp(label + '=([^&]*)(&|$)', 'g') |
| | | return name.match(reg)[0].split('=')[1] |
| | | } |
| | | |
| | | function validData(value, defaultValue) { |
| | | return value !== undefined ? value : defaultValue |
| | | } |
| | | function findObject(array, prop) { |
| | | return array.find(item => item.prop === prop) |
| | | // 获取表格数据 |
| | | async function fetchTableData() { |
| | | if (isFetching.value) return |
| | | isFetching.value = true |
| | | loading.value = true |
| | | const statusListVal = statusList.value; |
| | | try { |
| | | const currentTab = tabs.value.find(tab => tab.name === activeTab.value) |
| | | const params = { |
| | | ai_types: filters.type || undefined, |
| | | status: currentTab?.name === 'myTickets' |
| | | ? undefined |
| | | : filters.status !== '' |
| | | ? Number(filters.status) |
| | | : currentTab?.value, |
| | | event_name: filters.keyword || undefined, |
| | | dept_id: filters.department || undefined, |
| | | start_date: filters.dateRange?.[0] |
| | | ? formatDate(filters.dateRange[0]) |
| | | : undefined, |
| | | end_date: filters.dateRange?.[1] |
| | | ? formatDate(filters.dateRange[1]).replace('00:00:00', '23:59:59') |
| | | : undefined, |
| | | current: Number(page.currentPage), |
| | | size: Number(page.pageSize), |
| | | ai_type: filters.algorithm || undefined, |
| | | is_draft: currentTab?.name === 'myTickets' ? 1 : undefined, |
| | | user_id: currentTab?.name === 'myTickets' ? userInfo.value.user_id : undefined, |
| | | is_review: filters.isReview === '' ? undefined : filters.isReview, |
| | | source: 1, |
| | | status_list:currentTab?.name !== 'myTickets'? statusListVal : undefined |
| | | } |
| | | |
| | | const response = await getList(params) |
| | | if (!response?.data?.data?.records) { |
| | | throw new Error('接口返回数据格式不正确') |
| | | } |
| | | const { total, records } = response.data.data |
| | | let filteredRecords = records |
| | | tableData.value = filteredRecords.map(item => { |
| | | const longitude = Number(item.longitude) || 0 |
| | | const latitude = Number(item.latitude) || 0 |
| | | return { |
| | | id: item.id, |
| | | orderNumber: item.event_num, |
| | | orderName: item.event_name, |
| | | department: departments.value.find(d => d.value === item.dept_id)?.label || item.dept_name, |
| | | startTime: item.job_create_time || '/', |
| | | aiType: item.ai_types, |
| | | content: item.content, |
| | | type: item.work_order_type_dict_key, |
| | | keyData: !isNaN(longitude) && !isNaN(latitude) |
| | | ? `${longitude.toFixed(6)}, ${latitude.toFixed(6)}` |
| | | : '未知位置', |
| | | address: item.address, |
| | | creator: item.event_num?.slice(0, 2) === 'AI' ? '智飞agent' : item.create_user, |
| | | handler: item.update_user || '未分配', |
| | | status: Number(item.status || 0), |
| | | photo_url: item.photo_url || '', |
| | | video_url: item.video_url || '', |
| | | location: !isNaN(longitude) && !isNaN(latitude) ? [longitude, latitude] : null, |
| | | processing_details: item.processing_details || '', |
| | | update_photo_url: item.update_photo_url || '', |
| | | work_type: item.work_type !== undefined ? Number(item.work_type) : 0, |
| | | job_name: item.job_name || '', |
| | | job_create_time: item.job_create_time || '', |
| | | isReview: item.is_review, |
| | | handle_user_id:item.handle_user_id |
| | | |
| | | } |
| | | }) |
| | | |
| | | page.total = total || 0 |
| | | if (isShowInfo.value) { |
| | | handleViewDetail(firstRowData.value) |
| | | isShowInfo.value = false |
| | | } |
| | | await fetchTabCounts() |
| | | } catch (error) { |
| | | console.error('获取数据失败:', error) |
| | | tableData.value = [] |
| | | page.total = 0 |
| | | } finally { |
| | | loading.value = false |
| | | isFetching.value = false |
| | | } |
| | | } |
| | | // 获取工单类型标签 |
| | | function getTypeLabel(typeValue) { |
| | |
| | | } |
| | | }) |
| | | dataList.value = filteredData |
| | | |
| | | } |
| | | }) |
| | | } |
| | |
| | | } |
| | | // 受理并派发 |
| | | function handleApproveAndDispatch(detail) { |
| | | if(!detail.orderName){ |
| | | ElMessage.warning('请填写工单名称'); |
| | | return; |
| | | } |
| | | if(!detail.aiType){ |
| | | ElMessage.warning('请选择关联算法'); |
| | | return; |
| | | } |
| | | |
| | | if(!detail.content){ |
| | | ElMessage.warning('请填写工单内容'); |
| | | return; |
| | | } |
| | | currentDetail.value = detail |
| | | dispatchDialogVisible.value = true |
| | | } |
| | |
| | | try { |
| | | const response = await getTicketInfo() |
| | | const { dept_data, event_type, ai_type, info } = response.data.data |
| | | |
| | | departments.value = dept_data.map(item => ({ |
| | | label: item.dept_name, |
| | | value: item.id, |
| | |
| | | label: value, |
| | | value: key, |
| | | })) |
| | | |
| | | const columnType = findObject(option.column, 'type') |
| | | columnType.dicData = types.value |
| | | allAlgorithms.value = info |
| | | |
| | | algorithms.value = ai_type?.map(item => ({ |
| | |
| | | })) || [] |
| | | |
| | | algorithms2.value = _.cloneDeep(algorithms.value) |
| | | |
| | | |
| | | userNameToIdMap.value = {} |
| | | dept_data.forEach(dept => { |
| | | (dept.user_data || []).forEach(user => { |
| | |
| | | console.error('加载下拉框数据失败:', error) |
| | | } |
| | | } |
| | | // 获取表格数据 |
| | | async function fetchTableData() { |
| | | if (isFetching.value) return |
| | | isFetching.value = true |
| | | loading.value = true |
| | | try { |
| | | const currentTab = tabs.value.find(tab => tab.name === activeTab.value) |
| | | const params = { |
| | | ai_types: filters.type || undefined, |
| | | status: currentTab?.name === 'myTickets' |
| | | ? undefined |
| | | : filters.status !== '' |
| | | ? Number(filters.status) |
| | | : currentTab?.value, |
| | | event_name: filters.keyword || undefined, |
| | | dept_id: filters.department || undefined, |
| | | start_date: filters.dateRange?.[0] |
| | | ? formatDate(filters.dateRange[0]) |
| | | : undefined, |
| | | end_date: filters.dateRange?.[1] |
| | | ? formatDate(filters.dateRange[1]).replace('00:00:00', '23:59:59') |
| | | : undefined, |
| | | current: Number(page.currentPage), |
| | | size: Number(page.pageSize), |
| | | ai_type: filters.algorithm || undefined, |
| | | is_draft: currentTab?.name === 'myTickets' ? 1 : undefined, |
| | | user_id: currentTab?.name === 'myTickets' ? userInfo.value.user_id : undefined, |
| | | is_review: filters.isReview === '' ? undefined : filters.isReview, |
| | | source: 1, |
| | | } |
| | | |
| | | const response = await getList(params) |
| | | if (!response?.data?.data?.records) { |
| | | throw new Error('接口返回数据格式不正确') |
| | | } |
| | | const { total, records } = response.data.data |
| | | let filteredRecords = records |
| | | tableData.value = filteredRecords.map(item => { |
| | | const longitude = Number(item.longitude) || 0 |
| | | const latitude = Number(item.latitude) || 0 |
| | | return { |
| | | id: item.id, |
| | | orderNumber: item.event_num, |
| | | orderName: item.event_name, |
| | | department: departments.value.find(d => d.value === item.dept_id)?.label || item.dept_name, |
| | | startTime: item.job_create_time || '/', |
| | | aiType: item.ai_types, |
| | | content: item.content, |
| | | type: item.work_order_type_dict_key, |
| | | keyData: !isNaN(longitude) && !isNaN(latitude) |
| | | ? `${longitude.toFixed(6)}, ${latitude.toFixed(6)}` |
| | | : '未知位置', |
| | | address: item.address, |
| | | creator: item.event_num?.slice(0, 2) === 'AI' ? '智飞agent' : item.create_user, |
| | | handler: item.update_user || '未分配', |
| | | status: Number(item.status || 0), |
| | | photo_url: item.photo_url || '', |
| | | video_url: item.video_url || '', |
| | | location: !isNaN(longitude) && !isNaN(latitude) ? [longitude, latitude] : null, |
| | | processing_details: item.processing_details || '', |
| | | update_photo_url: item.update_photo_url || '', |
| | | work_type: item.work_type !== undefined ? Number(item.work_type) : 0, |
| | | job_name: item.job_name || '', |
| | | job_create_time: item.job_create_time || '', |
| | | isReview: item.is_review, |
| | | } |
| | | }) |
| | | |
| | | page.total = total || 0 |
| | | if (isShowInfo.value) { |
| | | handleViewDetail(firstRowData.value) |
| | | isShowInfo.value = false |
| | | } |
| | | await fetchTabCounts() |
| | | } catch (error) { |
| | | console.error('获取数据失败:', error) |
| | | tableData.value = [] |
| | | page.total = 0 |
| | | } finally { |
| | | loading.value = false |
| | | isFetching.value = false |
| | | } |
| | | } |
| | | function handleTypeChange(typeValue) { |
| | | if (!typeValue) { |
| | | algorithms2.value = [] |
| | | return |
| | | } |
| | | |
| | | const matchedCategory = allAlgorithms.value.find(category => category.dict_key === typeValue) |
| | | |
| | | if (!matchedCategory || !matchedCategory.algorithms || matchedCategory.algorithms.length === 0) { |
| | | algorithms2.value = [] |
| | | return |
| | | } |
| | | |
| | | algorithms2.value = matchedCategory.algorithms.map(algo => ({ |
| | | label: algo.dict_value, |
| | | value: algo.dict_key, |
| | |
| | | dict_value: algo.dict_value, |
| | | })) |
| | | } |
| | | |
| | | function formatDate(date) { |
| | | if (!date) return undefined |
| | | const d = new Date(date) |
| | |
| | | |
| | | function mapStatus(status) { |
| | | const statusTextMap = { |
| | | '-1': '草稿', |
| | | |
| | | 2: '待审核', |
| | | 0: '待处理', |
| | | 3: '处理中', |
| | |
| | | } |
| | | return statusTextMap[status] || '未知状态' |
| | | } |
| | | |
| | | function getStatusTagType(status) { |
| | | if (status === -1 || status === '-1') return '' |
| | | const colorMap = { |
| | |
| | | } |
| | | return colorMap[String(status)] || '' |
| | | } |
| | | |
| | | async function fetchTabCounts(val) { |
| | | // 获取tab数据 |
| | | async function fetchTabCounts() { |
| | | const statusListVal = statusList.value; |
| | | const params = { |
| | | status_list: val |
| | | status_list: statusListVal |
| | | } |
| | | try { |
| | | const response = await getstatusCount(params) |
| | | const statusCount = response.data.data || {} |
| | | |
| | | const totalCount = Object.values(statusCount).reduce((sum, count) => sum + (count || 0), 0) |
| | | |
| | | const totalCount = Object.entries(statusCount).reduce((sum, [key, count]) => { |
| | | if (key === '6') return sum |
| | | return sum + (count || 0) |
| | | }, 0) |
| | | tabs.value.forEach(tab => { |
| | | if (tab.name === 'all') { |
| | | tab.count = totalCount |
| | |
| | | |
| | | function handleTabChange(tab) { |
| | | activeTab.value = tab.props?.name || tab.name |
| | | const statusList = ['0', '2', '3', '4'] |
| | | fetchTabCounts(statusList) |
| | | fetchTabCounts() |
| | | handleReset() |
| | | page.currentPage = 1 |
| | | fetchTableData() |
| | |
| | | |
| | | // 跳转后触发的Tab切换 |
| | | function handleTabChangeAfterJump() { |
| | | const isReview = findObject(option.column, 'isReview') |
| | | isReview.hide = !['all', 'completed', 'myTickets'].includes(activeTab.value) |
| | | handleReset() |
| | | page.currentPage = 1 |
| | | fetchTableData() |
| | |
| | | } |
| | | |
| | | async function getStepInfoData(val) { |
| | | try { |
| | | const orderNum = val |
| | | const stepResponse = await getStepInfo(orderNum) |
| | | const steps = Array.isArray(stepResponse.data.data) |
| | | ? stepResponse.data.data |
| | | : stepResponse.data.data?.steps || [] |
| | | |
| | | const finishedStep = steps.find(s => String(s.status) === '4') |
| | | totalTime.value = finishedStep && finishedStep.total_time ? finishedStep.total_time : '' |
| | | |
| | | if (activeTab.value !== 'myTickets') { |
| | | stepInfos.value = steps.map(step => ({ |
| | | status: String(step.status), |
| | | name: step.name, |
| | | time: step.time, |
| | | create_time: step.create_time, |
| | | })) |
| | | } else { |
| | | const statusArr = workType.value === 1 ? ['3', '4'] : fixedStatuses.value |
| | | stepInfos.value = statusArr.map(status => { |
| | | const step = steps.find(s => String(s.status) === String(status)) |
| | | return { |
| | | status, |
| | | name: step ? step.name : '', |
| | | time: step ? step.time : null, |
| | | create_time: step ? step.create_time : null, |
| | | } |
| | | }) |
| | | } |
| | | return true |
| | | } catch (error) { |
| | | console.error('获取步骤信息失败:', error) |
| | | if (activeTab.value === 'myTickets') { |
| | | const statusArr = workType.value === 1 ? ['3', '4'] : fixedStatuses.value |
| | | stepInfos.value = statusArr.map(status => ({ |
| | | status, |
| | | name: status === row.status ? row.handler || '未分配' : '未处理', |
| | | time: status === row.status ? row.startTime || '未知时间' : null, |
| | | })) |
| | | } else { |
| | | stepInfos.value = [] |
| | | } |
| | | return false |
| | | } |
| | | } |
| | | |
| | | // 详情 |
| | | async function handleViewDetail(row) { |
| | | console.log('row',row); |
| | | |
| | | currentIndex.value = tableData.value.findIndex(item => item.id === row.id) |
| | | workType.value = row.work_type !== undefined ? Number(row.work_type) : 0 |
| | | |
| | | const detailData = { |
| | | ...row, |
| | | processingDetail: row.processing_details || '', |
| | |
| | | |
| | | await getStepInfoData(row.orderNumber) |
| | | currentDetail.value.status = row.status |
| | | |
| | | |
| | | currentDetail.value = { |
| | | ...detailData, |
| | | showQR: false, |
| | | latAndLon: _.round(detailData.location[0], 6) + ',' + _.round(detailData.location[1], 6), |
| | | } |
| | | // console.log('currentDetail.value',currentDetail.value); |
| | | |
| | | detailVisible.value = true |
| | | handleTypeChange(currentDetail.value.type) |
| | |
| | | if (isFetching.value) return |
| | | fetchTableData() |
| | | } |
| | | |
| | | // 导出数据 |
| | | async function exportData() { |
| | | try { |
| | | loading.value = true |
| | |
| | | |
| | | if (exportData.length === 0) { |
| | | console.warn('没有数据可供导出') |
| | | ElMessage.warning('没有数据可供导出'); |
| | | return |
| | | } |
| | | |
| | |
| | | ] |
| | | |
| | | export_json_to_excel(headers, exportData, '工单数据') |
| | | console.log('数据导出成功') |
| | | } catch (error) { |
| | | console.error('导出失败:', error) |
| | | } finally { |
| | |
| | | // 删除方法 |
| | | function handleDelete(row) { |
| | | |
| | | console.log('删除工单:', row) |
| | | } |
| | | |
| | | // 添加选择变化处理方法 |
| | |
| | | |
| | | const response = await flowEvent(data) |
| | | if (response.data.code === 0) { |
| | | console.log('工单审核通过') |
| | | |
| | | |
| | | const newSelections = [...selections.value] |
| | | newSelections.splice(currentImageIndex.value - 1, 1) |
| | |
| | | |
| | | const response = await flowEvent(data) |
| | | if (response.data.code === 0) { |
| | | console.log('工单审核不通过') |
| | | |
| | | |
| | | const newSelections = [...selections.value] |
| | | newSelections.splice(currentImageIndex.value - 1, 1) |
| | |
| | | elink.click() |
| | | document.body.removeChild(elink) |
| | | }) |
| | | console.log('数据导出成功') |
| | | |
| | | } |
| | | |
| | | // 生命周期 |
| | | onMounted(() => { |
| | | |
| | | inputMapShowDefaultCenter.value = null |
| | | loadAMapScripts() |
| | | fetchDropdownData() |
| | | |
| | | getAlgorithmList() |
| | | // 设置默认activeTab |
| | | activeTab.value = defaultActiveTab.value |
| | | const href = window.location.href; |
| | | if (route?.query?.status !== undefined && route?.query?.status !== null) { |
| | | filters.status = route?.query?.status + '' |
| | |
| | | } |
| | | }) |
| | | } |
| | | |
| | | |
| | | if (tab) { |
| | | const isTabValid = filteredTabs.value.some(t => t.name === tab) |
| | | if (isTabValid) { |
| | |
| | | right: 0; |
| | | padding: 0 30px; |
| | | |
| | | z-index: 1000; |
| | | z-index: 1000; |
| | | } |
| | | :deep(.custom-header th.el-table__cell) { |
| | | color: rgba(0, 0, 0, 0.85); |
| | |
| | | :deep(.el-table__header-wrapper) { |
| | | background-color: #f5f7fa; |
| | | } |
| | | |
| | | |
| | | :deep(.el-table th) { |
| | | background-color: #f5f7fa; |
| | | color: #606266; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | |
| | | :deep(.el-table--border) { |
| | | border: 1px solid #ebeef5; |
| | | } |