| | |
| | | <div class="tab-content"> |
| | | <!-- 查询条件筛选栏 --> |
| | | <div class="filter-bar"> |
| | | <el-input |
| | | v-model="filters.key_word" |
| | | placeholder="输入工单编号/名称/内容/姓名" |
| | | class="filter-item" |
| | | clearable |
| | | @keyup.enter="handleSearch" |
| | | /> |
| | | <el-select |
| | | v-model="filters.create_dept" |
| | | placeholder="请选择所属单位" |
| | | class="filter-item" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="item in departments" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | <el-date-picker |
| | | v-model="filters.dateRange" |
| | | type="daterange" |
| | | range-separator="至" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | class="date-picker" |
| | | value-format="yyyy-MM-dd" |
| | | /> |
| | | <el-input v-model="filters.key_word" placeholder="输入工单编号/名称/内容/姓名" class="filter-item" clearable |
| | | @keyup.enter="handleSearch" /> |
| | | <el-select v-model="filters.create_dept" placeholder="请选择所属单位" class="filter-item" clearable> |
| | | <el-option v-for="item in departments" :key="item.value" :label="item.label" |
| | | :value="item.value" /> |
| | | <el-date-picker v-model="filters.dateRange" type="daterange" range-separator="至" |
| | | start-placeholder="开始日期" end-placeholder="结束日期" class="date-picker" |
| | | value-format="yyyy-MM-dd" /> |
| | | |
| | | </el-select> |
| | | |
| | | <el-select |
| | | v-model="filters.ai_types" |
| | | placeholder="关联算法" |
| | | class="filter-item" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="item in ai_types" |
| | | :key="item.dictKey" |
| | | :label="item.dictValue" |
| | | :value="item.dictKey" |
| | | /> |
| | | <el-select v-model="filters.ai_types" placeholder="关联算法" class="filter-item" clearable> |
| | | <el-option v-for="item in ai_types" :key="item.dictKey" :label="item.dictValue" |
| | | :value="item.dictKey" /> |
| | | </el-select> |
| | | |
| | | <el-select |
| | | v-model="filters.type" |
| | | placeholder="请选择工单类型" |
| | | class="filter-item" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="item in types" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | <el-select v-model="filters.type" placeholder="请选择工单类型" class="filter-item" clearable> |
| | | <el-option v-for="item in types" :key="item.value" :label="item.label" |
| | | :value="item.value" /> |
| | | </el-select> |
| | | |
| | | <el-select |
| | | v-model="filters.status" |
| | | placeholder="请选择工单状态" |
| | | class="filter-item" |
| | | clearable |
| | | > |
| | | <el-option |
| | | v-for="item in statuses" |
| | | :key="item.value" |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | <el-select v-model="filters.status" placeholder="请选择工单状态" class="filter-item" clearable> |
| | | <el-option v-for="item in statuses" :key="item.value" :label="item.label" |
| | | :value="item.value" /> |
| | | </el-select> |
| | | <el-button type="primary" icon="el-icon-search" @click="handleSearch">查询</el-button> |
| | | <el-button icon="el-icon-refresh" @click="handleReset">重置</el-button> |
| | | </div> |
| | | |
| | | <!-- 表格部分 --> |
| | | <avue-crud |
| | | :data="tableData" |
| | | :option="option" |
| | | :page.sync="pagination" |
| | | :table-loading="loading" |
| | | @current-change="handlePaginationChange" |
| | | @size-change="handlePaginationChange" |
| | | @refresh-change="refreshChange" |
| | | @on-load="onLoad" |
| | | > |
| | | <avue-crud :data="tableData" :option="option" :page.sync="pagination" :table-loading="loading" |
| | | @current-change="handlePaginationChange" @size-change="handlePaginationChange" |
| | | @refresh-change="refreshChange" @on-load="onLoad"> |
| | | <template #menu-left> |
| | | <el-button |
| | | type="primary" |
| | | icon="el-icon-plus" |
| | | @click="handleAdd" |
| | | >新建工单</el-button> |
| | | <el-button |
| | | type="success" |
| | | plain |
| | | icon="el-icon-download" |
| | | @click="exportData" |
| | | >导出</el-button> |
| | | <el-button type="primary" icon="el-icon-plus" @click="handleAdd">新建工单</el-button> |
| | | <el-button type="success" plain icon="el-icon-download" @click="exportData">导出</el-button> |
| | | </template> |
| | | <template #menu="{ row }"> |
| | | <el-button |
| | | type="text" |
| | | icon="el-icon-view" |
| | | @click="handleViewDetail(row)" |
| | | >详情</el-button> |
| | | <el-button type="text" icon="el-icon-view" @click="handleViewDetail(row)">详情</el-button> |
| | | </template> |
| | | <template #status="{ row }"> |
| | | <el-tag :type="getStatusTagType(row.status)">{{ mapStatus(row.status) }}</el-tag> |
| | |
| | | <el-col :span="12"> |
| | | <el-form-item label="工单类型" prop="type"> |
| | | <el-select v-model="form.type" placeholder="请选择工单类型"> |
| | | <el-option v-for="item in types" :key="item.value" :label="item.label" :value="item.value" /> |
| | | <el-option v-for="item in types" :key="item.value" :label="item.label" |
| | | :value="item.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | <el-col :span="12"> |
| | | <el-form-item label="处理人员" prop="handler"> |
| | | <el-select v-model="form.handler" placeholder="请选择处理人员"> |
| | | <el-option v-for="item in handlers" :key="item.value" :label="item.label" :value="item.value" /> |
| | | <el-option v-for="item in handlers" :key="item.value" :label="item.label" |
| | | :value="item.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="关联算法" prop="algorithm"> |
| | | <el-select v-model="form.algorithm" placeholder="请选择关联算法"> |
| | | <el-option v-for="item in algorithms" :key="item.value" :label="item.label" :value="item.value" /> |
| | | <el-option v-for="item in algorithms" :key="item.value" :label="item.label" |
| | | :value="item.value" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="24"> |
| | | <el-form-item label="上传图片"> |
| | | <el-upload |
| | | action="/api/upload" |
| | | list-type="picture-card" |
| | | :on-preview="handleUploadPreview" |
| | | :on-remove="handleUploadRemove" |
| | | :on-success="handleUploadSuccess" |
| | | :on-error="handleUploadError" |
| | | :file-list="form.photos" |
| | | :limit="5" |
| | | :multiple="true" |
| | | accept="image/*" |
| | | :before-upload="beforeUpload" |
| | | > |
| | | <el-upload action="/api/upload" list-type="picture-card" :on-preview="handleUploadPreview" |
| | | :on-remove="handleUploadRemove" :on-success="handleUploadSuccess" |
| | | :on-error="handleUploadError" :file-list="form.photos" :limit="5" :multiple="true" |
| | | accept="image/*" :before-upload="beforeUpload"> |
| | | <i class="el-icon-plus"></i> |
| | | <div slot="tip" class="el-upload__tip"> |
| | | 上传工单相关图片(支持jpg/png格式),最多5张,单张不超过5MB |
| | |
| | | <el-col :span="12"> |
| | | <el-form label-width="100px"> |
| | | <el-form-item label="上传照片"> |
| | | <el-upload |
| | | action="/api/upload" |
| | | list-type="picture-card" |
| | | :on-preview="handlePreview" |
| | | :on-remove="handleRemove" |
| | | :file-list="currentDetail.photos" |
| | | > |
| | | <el-upload action="/api/upload" list-type="picture-card" :on-preview="handlePreview" |
| | | :on-remove="handleRemove" :file-list="currentDetail.photos"> |
| | | <i class="el-icon-plus"></i> |
| | | </el-upload> |
| | | <div class="el-upload__tip"> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { getList, createTicket, getTicketInfo } from '@/api/tickets/orderLog'; |
| | | import { getDictionary } from '@/api/system/dictbiz'; |
| | | import { export_json_to_excel } from '@/utils/exportExcel'; |
| | | import geoJson from '@/assets/geoJson.json' |
| | | |
| | | import { mapGetters } from 'vuex' |
| | | import { getAdcodeObj } from '@/utils/disposeData' |
| | | import { getList, createTicket, getTicketInfo } from '@/api/tickets/orderLog' |
| | | import { getDictionary } from '@/api/system/dictbiz' |
| | | import { export_json_to_excel } from '@/utils/exportExcel' |
| | | |
| | | export default { |
| | | name: "TicketPage", |
| | |
| | | loading: false, |
| | | globalCounts: {}, |
| | | mapLoaded: false, |
| | | }; |
| | | } |
| | | }, |
| | | |
| | | computed: { |
| | | ...mapGetters(['userInfo']), |
| | | }, |
| | | |
| | | async created() { |
| | | this.loadAMapScripts(); |
| | | this.fetchDropdownData(); |
| | | var response=await getDictionary({ code: 'SF' }); |
| | | this.ai_types= response.data.data; |
| | | this.loadAMapScripts() |
| | | this.fetchDropdownData() |
| | | var response = await getDictionary({ code: 'SF' }) |
| | | this.ai_types = response.data.data |
| | | |
| | | }, |
| | | mounted() { |
| | | this.fetchTableData(); |
| | | this.fetchTableData() |
| | | }, |
| | | |
| | | |
| | |
| | | try { |
| | | // await loadAMap(); |
| | | // await loadAMapUI(); |
| | | this.mapLoaded = true; |
| | | this.mapLoaded = true |
| | | } catch (error) { |
| | | console.error('Failed to load AMap scripts:', error); |
| | | this.$message.error('地图加载失败,请检查网络或API Key配置'); |
| | | console.error('Failed to load AMap scripts:', error) |
| | | this.$message.error('地图加载失败,请检查网络或API Key配置') |
| | | } |
| | | }, |
| | | formatCycleTime(row){ |
| | | return row.begin_time+"-"+row.end_time+" "+row.rep_rule_val; |
| | | return row.begin_time + "-" + row.end_time + " " + row.rep_rule_val |
| | | }, |
| | | async fetchDropdownData() { |
| | | try { |
| | | const response = await getTicketInfo(); |
| | | console.log('接口返回数据:', response.data.data); |
| | | const { dept_data, event_type } = response.data.data; |
| | | const response = await getTicketInfo() |
| | | console.log('接口返回数据:', response.data.data) |
| | | const { dept_data, event_type } = response.data.data |
| | | |
| | | this.departments = dept_data.map(item => ({ |
| | | label: item.dept_name, |
| | | value: item.id, |
| | | })); |
| | | })) |
| | | |
| | | this.types = Object.entries(event_type).map(([key, value]) => ({ |
| | | label: value, |
| | | value: key, |
| | | })); |
| | | })) |
| | | |
| | | console.log('departments:', this.departments); |
| | | console.log('types:', this.types); |
| | | console.log('departments:', this.departments) |
| | | console.log('types:', this.types) |
| | | } catch (error) { |
| | | console.error('获取下拉框数据失败:', error); |
| | | this.$message.error('加载下拉框数据失败'); |
| | | console.error('获取下拉框数据失败:', error) |
| | | this.$message.error('加载下拉框数据失败') |
| | | } |
| | | }, |
| | | |
| | | async fetchTableData() { |
| | | this.loading = true; |
| | | this.loading = true |
| | | try { |
| | | const currentTab = this.tabs.find(tab => tab.name === this.activeTab); |
| | | const currentTab = this.tabs.find(tab => tab.name === this.activeTab) |
| | | |
| | | const params = { |
| | | key_word: this.filters.key_word || undefined, |
| | |
| | | end_date: this.filters.dateRange?.[1] ? this.formatDate(this.filters.dateRange[1]).replace("00:00:00", "23:59:59") : undefined, |
| | | current: this.pagination.currentPage, |
| | | size: this.pagination.pageSize, |
| | | }; |
| | | console.log("发送的参数:", params); |
| | | const response = await getList(params); |
| | | } |
| | | console.log("发送的参数:", params) |
| | | const response = await getList(params) |
| | | if (!response?.data?.data?.records) { |
| | | throw new Error('接口返回数据格式不正确'); |
| | | throw new Error('接口返回数据格式不正确') |
| | | } |
| | | |
| | | const { total, records } = response.data.data; |
| | | const { total, records } = response.data.data |
| | | this.tableData = records.map(item => { |
| | | |
| | | return item; |
| | | }); |
| | | return item |
| | | }) |
| | | |
| | | if (this.activeTab === 'all') { |
| | | this.updateGlobalCounts(records, total); |
| | | this.updateGlobalCounts(records, total) |
| | | } |
| | | |
| | | this.pagination.total = total || 0; |
| | | this.updateTabCounts(); |
| | | this.pagination.total = total || 0 |
| | | this.updateTabCounts() |
| | | } catch (error) { |
| | | console.error("获取数据失败:", error); |
| | | this.$message.error(error.message || "获取数据失败"); |
| | | this.tableData = []; |
| | | this.pagination.total = 0; |
| | | console.error("获取数据失败:", error) |
| | | this.$message.error(error.message || "获取数据失败") |
| | | this.tableData = [] |
| | | this.pagination.total = 0 |
| | | } finally { |
| | | this.loading = false; |
| | | this.loading = false |
| | | } |
| | | }, |
| | | |
| | | beforeUpload(file) { |
| | | const isImage = file.type.includes('image'); |
| | | const isLt5M = file.size / 1024 / 1024 < 5; |
| | | const isImage = file.type.includes('image') |
| | | const isLt5M = file.size / 1024 / 1024 < 5 |
| | | |
| | | if (!isImage) { |
| | | this.$message.error('只能上传图片文件!'); |
| | | return false; |
| | | this.$message.error('只能上传图片文件!') |
| | | return false |
| | | } |
| | | if (!isLt5M) { |
| | | this.$message.error('图片大小不能超过5MB!'); |
| | | return false; |
| | | this.$message.error('图片大小不能超过5MB!') |
| | | return false |
| | | } |
| | | return true; |
| | | return true |
| | | }, |
| | | |
| | | handleUploadPreview(file) { |
| | | this.$message.info(`预览图片:${file.name}`); |
| | | this.$message.info(`预览图片:${file.name}`) |
| | | }, |
| | | |
| | | handleUploadRemove(file, fileList) { |
| | | this.form.photos = fileList; |
| | | this.$message.success(`已移除图片:${file.name}`); |
| | | this.form.photos = fileList |
| | | this.$message.success(`已移除图片:${file.name}`) |
| | | }, |
| | | |
| | | handleUploadSuccess(response, file, fileList) { |
| | | this.form.photos = fileList; |
| | | this.$message.success(`图片上传成功:${file.name}`); |
| | | this.form.photos = fileList |
| | | this.$message.success(`图片上传成功:${file.name}`) |
| | | }, |
| | | |
| | | handleUploadError(err, file) { |
| | | this.$message.error(`图片上传失败:${file.name}`); |
| | | console.error('上传失败:', err); |
| | | this.$message.error(`图片上传失败:${file.name}`) |
| | | console.error('上传失败:', err) |
| | | }, |
| | | |
| | | async uploadFiles(files) { |
| | | const uploadPromises = files.map(file => { |
| | | return new Promise((resolve) => { |
| | | const formData = new FormData(); |
| | | formData.append('file', file.raw); |
| | | const formData = new FormData() |
| | | formData.append('file', file.raw) |
| | | setTimeout(() => { |
| | | resolve({ |
| | | url: URL.createObjectURL(file.raw), |
| | | name: file.name |
| | | }); |
| | | }, 1000); |
| | | }); |
| | | }); |
| | | return Promise.all(uploadPromises); |
| | | }) |
| | | }, 1000) |
| | | }) |
| | | }) |
| | | return Promise.all(uploadPromises) |
| | | }, |
| | | |
| | | async submitForm() { |
| | | this.$refs.form.validate(async (valid) => { |
| | | if (valid) { |
| | | if (!this.form.location || this.form.location.length !== 2) { |
| | | this.$message.warning('请在地图上选择位置'); |
| | | return; |
| | | this.$message.warning('请在地图上选择位置') |
| | | return |
| | | } |
| | | |
| | | try { |
| | | const unUploadedFiles = this.form.photos.filter(file => file.raw); |
| | | const unUploadedFiles = this.form.photos.filter(file => file.raw) |
| | | if (unUploadedFiles.length > 0) { |
| | | await this.uploadFiles(unUploadedFiles); |
| | | await this.uploadFiles(unUploadedFiles) |
| | | } |
| | | |
| | | const submitData = { |
| | |
| | | photos: this.form.photos.map(file => file.url || file.response?.url), |
| | | location: this.form.location.join(','), |
| | | status: 1 |
| | | }; |
| | | } |
| | | |
| | | await createTicket(submitData); |
| | | this.dialogVisible = false; |
| | | this.$message.success('工单创建成功'); |
| | | this.fetchTableData(); |
| | | await createTicket(submitData) |
| | | this.dialogVisible = false |
| | | this.$message.success('工单创建成功') |
| | | this.fetchTableData() |
| | | } catch (error) { |
| | | console.error('提交失败:', error); |
| | | this.$message.error('工单创建失败: ' + (error.message || '服务器错误')); |
| | | console.error('提交失败:', error) |
| | | this.$message.error('工单创建失败: ' + (error.message || '服务器错误')) |
| | | } |
| | | } |
| | | }); |
| | | }) |
| | | }, |
| | | |
| | | formatDate(date) { |
| | | if (!date) return undefined; |
| | | const d = new Date(date); |
| | | return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')} 00:00:00`; |
| | | if (!date) return undefined |
| | | const d = new Date(date) |
| | | return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')} 00:00:00` |
| | | }, |
| | | |
| | | mapStatus(status) { |
| | |
| | | 3: "处理中", |
| | | 4: "已完成", |
| | | 5: "已完结" |
| | | }; |
| | | return statusTextMap[status] || "未知状态"; |
| | | } |
| | | return statusTextMap[status] || "未知状态" |
| | | }, |
| | | |
| | | getStatusTagType(status) { |
| | |
| | | 3: "primary", |
| | | 4: "success", |
| | | 5: "danger", |
| | | }; |
| | | return statusMap[status] || "info"; |
| | | } |
| | | return statusMap[status] || "info" |
| | | }, |
| | | |
| | | handleTabChange(tab) { |
| | | this.activeTab = tab.props?.name || tab.name; |
| | | this.filters.status = ""; |
| | | this.pagination.currentPage = 1; |
| | | this.fetchTableData(); |
| | | this.activeTab = tab.props?.name || tab.name |
| | | this.filters.status = "" |
| | | this.pagination.currentPage = 1 |
| | | this.fetchTableData() |
| | | }, |
| | | |
| | | handleSearch() { |
| | | this.pagination.currentPage = 1; |
| | | this.fetchTableData(); |
| | | this.pagination.currentPage = 1 |
| | | this.fetchTableData() |
| | | }, |
| | | |
| | | handleReset() { |
| | |
| | | type: "", |
| | | dateRange: [], |
| | | status: "", |
| | | }; |
| | | this.pagination.currentPage = 1; |
| | | this.fetchTableData(); |
| | | } |
| | | this.pagination.currentPage = 1 |
| | | this.fetchTableData() |
| | | }, |
| | | |
| | | handlePaginationChange(val) { |
| | | this.pagination.currentPage = val.currentPage; |
| | | this.pagination.pageSize = val.pageSize; |
| | | this.fetchTableData(); |
| | | this.pagination.currentPage = val.currentPage |
| | | this.pagination.pageSize = val.pageSize |
| | | this.fetchTableData() |
| | | }, |
| | | |
| | | updateGlobalCounts(records, total) { |
| | |
| | | completed: 0, |
| | | closed: 0, |
| | | myTickets: 0 |
| | | }; |
| | | } |
| | | |
| | | records.forEach(item => { |
| | | const tab = this.tabs.find(t => t.value === Number(item.status)); |
| | | const tab = this.tabs.find(t => t.value === Number(item.status)) |
| | | if (tab) { |
| | | counts[tab.name] = (counts[tab.name] || 0) + 1; |
| | | counts[tab.name] = (counts[tab.name] || 0) + 1 |
| | | } |
| | | }); |
| | | }) |
| | | |
| | | this.globalCounts = counts; |
| | | this.globalCounts = counts |
| | | }, |
| | | |
| | | updateTabCounts() { |
| | | if (this.activeTab === 'all') { |
| | | this.tabs.forEach(tab => { |
| | | tab.count = this.globalCounts[tab.name] || 0; |
| | | }); |
| | | tab.count = this.globalCounts[tab.name] || 0 |
| | | }) |
| | | } else { |
| | | this.tabs.forEach(tab => { |
| | | if (tab.name === this.activeTab) { |
| | | tab.count = this.tableData.length; |
| | | tab.count = this.tableData.length |
| | | } else { |
| | | tab.count = this.globalCounts[tab.name] || 0; |
| | | tab.count = this.globalCounts[tab.name] || 0 |
| | | } |
| | | }); |
| | | }) |
| | | } |
| | | }, |
| | | |
| | | handleAdd() { |
| | | this.dialogVisible = true; |
| | | this.dialogVisible = true |
| | | }, |
| | | |
| | | resetForm() { |
| | |
| | | address: '', |
| | | content: '', |
| | | photos: [], |
| | | }; |
| | | } |
| | | if (this.$refs.form) { |
| | | this.$refs.form.resetFields(); |
| | | this.$refs.form.resetFields() |
| | | } |
| | | }, |
| | | |
| | | formatLocation(location) { |
| | | if (!Array.isArray(location)) { |
| | | return '未知位置'; |
| | | return '未知位置' |
| | | } |
| | | return `${location[0].toFixed(6)}, ${location[1].toFixed(6)}`; |
| | | return `${location[0].toFixed(6)}, ${location[1].toFixed(6)}` |
| | | }, |
| | | |
| | | handleViewDetail(row) { |
| | | this.currentDetail = { |
| | | ...row, |
| | | photos: row.photos || [], |
| | | }; |
| | | this.detailVisible = true; |
| | | } |
| | | this.detailVisible = true |
| | | }, |
| | | |
| | | openMap() { |
| | | this.$message.info("地图选址功能暂未实现"); |
| | | let cur = getAdcodeObj(geoJson, 'adcode', this.userInfo.detail.areaCode.substring(0, 6)) |
| | | console.log(cur, 111) |
| | | |
| | | |
| | | |
| | | this.$message.info("地图选址功能暂未实现") |
| | | }, |
| | | |
| | | handlePreview(file) { |
| | | this.$message.info(`预览图片:${file.name}`); |
| | | this.$message.info(`预览图片:${file.name}`) |
| | | }, |
| | | |
| | | handleRemove(file) { |
| | | this.$message.info(`移除图片:${file.name}`); |
| | | this.$message.info(`移除图片:${file.name}`) |
| | | }, |
| | | |
| | | refreshChange() { |
| | | this.fetchTableData(); |
| | | this.fetchTableData() |
| | | }, |
| | | |
| | | onLoad() { |
| | | this.fetchTableData(); |
| | | this.fetchTableData() |
| | | }, |
| | | |
| | | async exportData() { |
| | | try { |
| | | this.loading = true; |
| | | this.loading = true |
| | | const params = { |
| | | keyword: this.filters.keyword || undefined, |
| | | word_order_type: this.filters.type || undefined, |
| | |
| | | dept_id: this.filters.department || undefined, |
| | | start_date: this.filters.dateRange?.[0] ? this.formatDate(this.filters.dateRange[0]) : undefined, |
| | | end_date: this.filters.dateRange?.[1] ? this.formatDate(this.filters.dateRange[1]) : undefined, |
| | | }; |
| | | |
| | | const response = await getList(params); |
| | | if (!response?.data?.data?.records) { |
| | | throw new Error('接口返回数据格式不正确'); |
| | | } |
| | | |
| | | const records = response.data.data.records; |
| | | const response = await getList(params) |
| | | if (!response?.data?.data?.records) { |
| | | throw new Error('接口返回数据格式不正确') |
| | | } |
| | | |
| | | const records = response.data.data.records |
| | | const exportData = records.map(item => ({ |
| | | 工单编号: item.wayline_job_id || '', |
| | | 工单名称: item.event_name || '', |
| | |
| | | 创建人: item.create_user || '未知创建人', |
| | | 处理人: item.update_user || '未分配', |
| | | 工单状态: this.mapStatus(Number(item.status || 0)), |
| | | })); |
| | | })) |
| | | |
| | | export_json_to_excel( |
| | | ['工单编号', '工单名称', '所属单位', '发起时间', '工单内容', '工单类型', '经纬度', '详细地址', '创建人', '处理人', '工单状态'], |
| | | exportData, |
| | | '工单数据' |
| | | ); |
| | | this.$message.success('数据导出成功'); |
| | | ) |
| | | this.$message.success('数据导出成功') |
| | | } catch (error) { |
| | | console.error('导出失败:', error); |
| | | this.$message.error('数据导出失败'); |
| | | console.error('导出失败:', error) |
| | | this.$message.error('数据导出失败') |
| | | } finally { |
| | | this.loading = false; |
| | | this.loading = false |
| | | } |
| | | }, |
| | | }, |
| | | watch: { |
| | | tableData: { |
| | | handler() { |
| | | this.updateTabCounts(); |
| | | this.updateTabCounts() |
| | | }, |
| | | deep: true |
| | | }, |
| | | } |
| | | }; |
| | | } |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |