| | |
| | | @keyup.enter="handleSearch" |
| | | /> |
| | | |
| | | <el-select |
| | | <el-select |
| | | v-model="filters.create_dept" |
| | | placeholder="请选择所属单位" |
| | | class="filter-item" |
| | |
| | | :label="item.label" |
| | | :value="item.value" |
| | | /> |
| | | </el-select> |
| | | |
| | | |
| | | <el-date-picker |
| | | v-model="filters.dateRange" |
| | | type="daterange" |
| | | range-separator="至" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | class="filter-item" |
| | | style="width:80px" |
| | | value-format="yyyy-MM-dd" |
| | | /> |
| | | |
| | | </el-select> |
| | | |
| | | <el-date-picker |
| | | v-model="filters.dateRange" |
| | | type="daterange" |
| | | range-separator="至" |
| | | start-placeholder="开始日期" |
| | | end-placeholder="结束日期" |
| | | class="filter-item" |
| | | style="width: 80px" |
| | | value-format="yyyy-MM-dd" |
| | | /> |
| | | |
| | | <el-select |
| | | v-model="filters.ai_types" |
| | | placeholder="关联算法" |
| | |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="关联航线" prop="file_id"> |
| | | <el-select v-model="form.file_id" placeholder="请选择航线" @change="getFlyingNestBy" > |
| | | <el-select v-model="form.file_id" placeholder="请选择航线" @change="getFlyingNestBy"> |
| | | <el-option |
| | | v-for="item in wayLineList" |
| | | :key="item.wayline_id" |
| | | :label="item.name" |
| | | :value="item.wayline_id" |
| | | |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | |
| | | |
| | | <el-col :span="3"> |
| | | <el-time-picker |
| | | style="width:100px" |
| | | style="width: 100px" |
| | | v-model="form.deal_time" |
| | | prop="deal_time" |
| | | value-format="HH:mm" |
| | |
| | | @close="resetForm" |
| | | > |
| | | <el-form :model="form" ref="form" label-width="100px"> |
| | | |
| | | |
| | | <div class="custom-steps-container"> |
| | | <!-- 标题行 --> |
| | | <div class="steps-titles" > |
| | | |
| | | <div v-for="(record, index) in form.record_list" :class="{ 'active': record.user_id >=0 }" :key="index" class="step-title" >{{record.status_str}}</div> |
| | | |
| | | |
| | | |
| | | |
| | | </div> |
| | | |
| | | <!-- Element Steps 组件 --> |
| | | <el-steps :active="form.active" align-center class="custom-steps" > |
| | | |
| | | <el-step v-for="(record, index) in form.record_list" :key="index"> |
| | | <template #description> |
| | | <div class="step-description">{{record.user_name}}</div> |
| | | </template> |
| | | </el-step> |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | </el-steps> |
| | | </div> |
| | | |
| | | |
| | | |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="工单名称" prop="name"> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="关联航线" prop="file_id"> |
| | | <el-select v-model="form.file_id" placeholder="请选择航线" @change="getFlyingNestBy" > |
| | | <el-form-item label="关联航线" prop="file_id"> |
| | | <el-select v-model="form.file_id" placeholder="请选择航线" @change="getFlyingNestBy"> |
| | | <el-option |
| | | v-for="item in wayLineList" |
| | | :key="item.wayline_id" |
| | | :label="item.name" |
| | | :value="item.wayline_id" |
| | | |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="关联机巢" prop="device_sns"> |
| | | <el-form-item label="关联机巢" prop="device_sns"> |
| | | <el-select v-model="form.device_sns" placeholder="请选择机巢" multiple> |
| | | <el-option |
| | | v-for="item in device_sns" |
| | |
| | | |
| | | <el-button |
| | | type="danger" |
| | | v-if="form.status == 0|| form.status == 2 && userInfo.user_id == form.create_user" |
| | | v-if="form.status == 0 || (form.status == 2 && userInfo.user_id == form.create_user)" |
| | | @click="submitForm(1)" |
| | | >发布</el-button |
| | | > |
| | |
| | | |
| | | <el-col :span="3"> |
| | | <el-time-picker |
| | | style="width: 100px" |
| | | v-model="form.deal_time" |
| | | prop="deal_time" |
| | | value-format="HH:mm" |
| | |
| | | orderLogRecall, |
| | | orderLogReject, |
| | | orderLogPass, |
| | | orderLogExport, |
| | | } from '@/api/tickets/orderLog'; |
| | | import { getDictionary } from '@/api/system/dictbiz'; |
| | | import{getWaylineFileListByArea} from '@/api/resource/wayline'; |
| | | import { getWaylineFileListByArea } from '@/api/resource/wayline'; |
| | | import { export_json_to_excel } from '@/utils/exportExcel'; |
| | | import {getFlyingNestBy} from '@/api/device/device'; |
| | | import { getFlyingNestBy } from '@/api/device/device'; |
| | | import { mapGetters } from 'vuex'; |
| | | import NProgress from 'nprogress'; |
| | | import { downloadXls } from '@/utils/util'; |
| | | import 'nprogress/nprogress.css'; |
| | | |
| | | export default { |
| | | name: 'TicketPage', |
| | |
| | | }, |
| | | departments: [], |
| | | types: [], |
| | | device_sns:[], |
| | | device_sns: [], |
| | | ai_types: [], |
| | | wayLineList:[], |
| | | |
| | | wayLineList: [], |
| | | |
| | | statuses: [ |
| | | { label: '草稿', value: '0' }, |
| | | { label: '待审核', value: '1' }, |
| | |
| | | { label: '工单内容', prop: 'content', width: 160 }, |
| | | { label: '关联航线', prop: 'wayline_name', width: 160 }, |
| | | { label: '关联算法', prop: 'ai_type_str', width: 180 }, |
| | | { label: '关联机巢', prop: 'device_names', width: 180 }, |
| | | |
| | | { label: '创建人', prop: 'creator_name', width: 180 }, |
| | | { label: '关联机巢', prop: 'device_names', width: 108 }, |
| | | { |
| | |
| | | var response = await getDictionary({ code: 'SF' }); |
| | | var word_order_typeResponse = await getDictionary({ code: 'WORK_ORDER_TYPE' }); |
| | | this.ai_types = response.data.data; |
| | | this.types=word_order_typeResponse.data.data; |
| | | |
| | | this.types = word_order_typeResponse.data.data; |
| | | }, |
| | | mounted() { |
| | | this.fetchTableData(); |
| | | }, |
| | | computed: { |
| | | ...mapGetters(['userInfo']), |
| | | |
| | | }, |
| | | |
| | | methods: { |
| | |
| | | return row.begin_time + '-' + row.end_time + ' ' + row.rep_rule_val; |
| | | }, |
| | | |
| | | |
| | | async fetchTableData() { |
| | | this.loading = true; |
| | | try { |
| | | const currentTab = this.tabs.find(tab => tab.name === this.activeTab); |
| | | |
| | | const params = { |
| | | key_word: this.filters.key_word || undefined, |
| | | create_dept: this.filters.create_dept || undefined, |
| | | ai_types: |
| | | this.filters.ai_types && this.filters.ai_types.length > 0 |
| | | ? [this.filters.ai_types] |
| | | : null, |
| | | file_id: this.filters.file_id || undefined, |
| | | status: this.filters.status !== '' ? Number(this.filters.status) : currentTab?.value, |
| | | 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]).replace('00:00:00', '23:59:59') |
| | | : undefined, |
| | | current: this.pagination.currentPage, |
| | | size: this.pagination.pageSize, |
| | | }; |
| | | let params = this.getQueryParam(); |
| | | console.log('发送的参数:', params); |
| | | const response = await getList(params); |
| | | if (!response?.data?.data?.records) { |
| | |
| | | } |
| | | }, |
| | | |
| | | getQueryParam() { |
| | | const currentTab = this.tabs.find(tab => tab.name === this.activeTab); |
| | | |
| | | |
| | | const params = { |
| | | key_word: this.filters.key_word || undefined, |
| | | create_dept: this.filters.create_dept || undefined, |
| | | ai_types: |
| | | this.filters.ai_types && this.filters.ai_types.length > 0 |
| | | ? [this.filters.ai_types] |
| | | : null, |
| | | file_id: this.filters.file_id || undefined, |
| | | status: this.filters.status !== '' ? Number(this.filters.status) : currentTab?.value, |
| | | 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]).replace('00:00:00', '23:59:59') |
| | | : undefined, |
| | | current: this.pagination.currentPage, |
| | | size: this.pagination.pageSize, |
| | | }; |
| | | return params; |
| | | }, |
| | | |
| | | async submitForm(status) { |
| | | this.$refs.form.validate(async valid => { |
| | | if (valid) { |
| | |
| | | } |
| | | this.dialogVisible = false; |
| | | this.detailVisible = false; |
| | | this.device_sns=[], |
| | | this.wayLineList=[], |
| | | this.fetchTableData(); |
| | | (this.device_sns = []), (this.wayLineList = []), this.fetchTableData(); |
| | | } |
| | | }); |
| | | }, |
| | | //驳回原因显示 |
| | | async rejectDetail(id){ |
| | | const response = await orderLogDetails(id); |
| | | let data=response.data.data; |
| | | async rejectDetail(id) { |
| | | const response = await orderLogDetails(id); |
| | | let data = response.data.data; |
| | | this.$confirm(data.remark, '驳回原因', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | this.form = { |
| | | ...response.data.data, |
| | | }; |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }).then(() => { |
| | | this.form = { |
| | | ...response.data.data, |
| | | }; |
| | | this.detailVisible = true; |
| | | }) |
| | | |
| | | |
| | | }); |
| | | }, |
| | | formatDate(date) { |
| | | if (!date) return undefined; |
| | |
| | | handleAdd() { |
| | | this.form = {}; |
| | | this.dialogVisible = true; |
| | | //航线列表 |
| | | //航线列表 |
| | | this.asyncgetWaylineFileListByArea(); |
| | | }, |
| | | |
| | |
| | | this.detailVisible = true; |
| | | //航线列表 |
| | | this.asyncgetWaylineFileListByArea(); |
| | | this.device_sns=response.data.data.deviceList; |
| | | this.device_sns = response.data.data.deviceList; |
| | | }, |
| | | |
| | | |
| | | |
| | | //导出 |
| | | async exportData() { |
| | | this.$confirm('是否智飞工单数据?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning', |
| | | }).then(() => { |
| | | NProgress.start(); |
| | | let params = this.getQueryParam(); |
| | | orderLogExport(params).then(res => { |
| | | downloadXls(res.data, `智飞工单${this.$dayjs().format('YYYY-MM-DD')}.xlsx`); |
| | | NProgress.done(); |
| | | }); |
| | | }); |
| | | }, |
| | | |
| | | refreshChange() { |
| | | this.fetchTableData(); |
| | | }, |
| | | //获取航线列表 |
| | | async asyncgetWaylineFileListByArea(name){ |
| | | var wayLineListResponse= await getWaylineFileListByArea(this.userInfo.detail.areaCode); |
| | | this.wayLineList=wayLineListResponse.data.data; |
| | | |
| | | }, |
| | | //可飞行机巢列表 |
| | | async getFlyingNestBy(waylineId){ |
| | | //按照航线来 |
| | | const params = { |
| | | type:0, |
| | | waylineId:waylineId, |
| | | } |
| | | var wayLineListResponse= await getFlyingNestBy(params); |
| | | this.device_sns=wayLineListResponse.data.data; |
| | | |
| | | }, |
| | | async asyncgetWaylineFileListByArea(name) { |
| | | var wayLineListResponse = await getWaylineFileListByArea(this.userInfo.detail.areaCode); |
| | | this.wayLineList = wayLineListResponse.data.data; |
| | | }, |
| | | //可飞行机巢列表 |
| | | async getFlyingNestBy(waylineId) { |
| | | //按照航线来 |
| | | const params = { |
| | | type: 0, |
| | | waylineId: waylineId, |
| | | }; |
| | | var wayLineListResponse = await getFlyingNestBy(params); |
| | | this.device_sns = wayLineListResponse.data.data; |
| | | }, |
| | | |
| | | //撤回 |
| | | async orderLogRecall(id) { |
| | |
| | | * 驳回 |
| | | */ |
| | | async orderLogReject(id) { |
| | | this.$prompt('','驳回原因',{ |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | }).then(async({ value }) => { |
| | | let response = await orderLogReject(id, value); |
| | | let data = response.data.data; |
| | | this.$message.success('驳回成果'); |
| | | this.detailVisible = false; |
| | | }); |
| | | }, |
| | | async exportData() { |
| | | try { |
| | | this.loading = true; |
| | | const params = { |
| | | keyword: this.filters.keyword || undefined, |
| | | word_order_type: this.filters.type || undefined, |
| | | status: this.filters.status || 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 exportData = records.map(item => ({ |
| | | 工单编号: item.wayline_job_id || '', |
| | | 工单名称: item.event_name || '', |
| | | 所属单位: this.departments.find(d => d.value === item.deptId)?.label || '未知单位', |
| | | 发起时间: item.create_time || '', |
| | | 工单内容: item.ai_types || '', |
| | | 工单类型: this.types.find(t => t.value === item.event_dict_key)?.label || '未知类型', |
| | | 经纬度: `${item.longitude || '未知'}, ${item.latitude || '未知'}`, |
| | | 详细地址: item.address || '暂无地址信息', |
| | | 创建人: item.create_user || '未知创建人', |
| | | 处理人: item.update_user || '未分配', |
| | | 工单状态: this.mapStatus(Number(item.status || 0)), |
| | | })); |
| | | |
| | | export_json_to_excel( |
| | | [ |
| | | '工单编号', |
| | | '工单名称', |
| | | '所属单位', |
| | | '发起时间', |
| | | '工单内容', |
| | | '工单类型', |
| | | '经纬度', |
| | | '详细地址', |
| | | '创建人', |
| | | '处理人', |
| | | '工单状态', |
| | | ], |
| | | exportData, |
| | | '工单数据' |
| | | ); |
| | | this.$message.success('数据导出成功'); |
| | | } catch (error) { |
| | | console.error('导出失败:', error); |
| | | this.$message.error('数据导出失败'); |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | this.$prompt('', '驳回原因', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | }).then(async ({ value }) => { |
| | | let response = await orderLogReject(id, value); |
| | | let data = response.data.data; |
| | | this.$message.success('驳回成果'); |
| | | this.detailVisible = false; |
| | | }); |
| | | }, |
| | | }, |
| | | |
| | | watch: { |
| | | tableData: { |
| | | handler() { |
| | |
| | | color: #909399; |
| | | margin-top: 7px; |
| | | } |
| | | |
| | | |
| | | |
| | | .custom-steps-container { |
| | | width: 100%; |
| | | margin: 20px 0; |
| | | } |
| | | |
| | | .steps-titles { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | margin-bottom: 16px; |
| | | position: relative; |
| | | } |
| | | |
| | | .step-title { |
| | | text-align: center; |
| | | flex: 1; |
| | | font-size: 16px; |
| | | color: #999; |
| | | position: relative; |
| | | padding-bottom: 10px; |
| | | } |
| | | |
| | | .step-title.active { |
| | | color: #409EFF; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .custom-steps { |
| | | margin-top: -20px; /* 向上移动与标题重叠 */ |
| | | } |
| | | |
| | | .el-step__head { |
| | | margin-top: 0; |
| | | } |
| | | |
| | | .el-step__description { |
| | | margin-top: 8px; |
| | | padding: 0 20px; |
| | | } |
| | | |
| | | .step-description { |
| | | font-size: 14px; |
| | | color: #666; |
| | | line-height: 1.5; |
| | | } |
| | | |
| | | </style> |