dbd-meeting-html/src/views/admin/RepairList.vue
luoyu 2ab5283eeb 20250521修复 筛选过后,点击详情页面查看并返回后,筛选条件都没了,还需要重新筛选,用户使用起来比较麻烦每次都需要重新进行筛选.
解决方案:
采用本地存储、在列表页增加两个按钮供用户自行选择是否保存筛选条件、详情页新增返回列表按钮,便于用户操作
2025-05-21 21:06:19 +08:00

757 lines
24 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>
<a-card :bordered='false'>
<div class='table-page-search-wrapper' v-if='!isShowModel'>
<a-form layout='inline'>
<a-row :gutter='48'>
<a-col :md='7' :sm='15'>
<a-form-item label='维修单号'>
<a-input placeholder='请输入关键词' v-model='queryParam.sn' />
</a-form-item>
</a-col>
<a-col :md='7' :sm='15'>
<a-form-item :labelCol='labelCol' :wrapperCol='wrapperCol' :allowClear='true' label='故障类型'>
<a-select v-model='queryParam.typeId'
v-decorator="['typeId']"
@change='selectDevice'>
<a-select-option v-for='item in typeList' :key='item.id'>{{ item.name }}
</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :md='7' :sm='15'>
<a-form-item :labelCol='labelCol' :wrapperCol='wrapperCol' :allowClear='true' label='故障子类'>
<a-select v-model='queryParam.deviceId'
v-decorator="['deviceId', {rules: [{ required: true, message: '请选择所属设备' }]}]"
@change='getDeviceName'>
<a-select-option v-for='item in deviceList' :key='item.id'>{{ item.name }}
</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :md='7' :sm='20'>
<a-form-item label='关键词(故障描述)'>
<a-input placeholder='请输入关键词' v-model='queryParam.explain' />
</a-form-item>
</a-col>
<a-col :md='7' :sm='15'>
<a-form-item label='故障等级'>
<a-select v-model='queryParam.repairLevel' :allowClear='true'
v-decorator="['repairLevel']">
<a-select-option v-for='item in repairLevelOptions' :key='item.value'>
{{ item.label }}
</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :md='7' :sm='15'>
<a-form-item label='报修来源'>
<a-select v-model='queryParam.remark' :allowClear='true'
v-decorator="['remark']">
<a-select-option v-for='item in remarkOption' :key='item.value'>
{{ item.label }}
</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :md='7' :sm='15'>
<a-form-item :labelCol='labelCol' :wrapperCol='wrapperCol' label='工单状态'>
<a-select v-model='queryParam.type' :allowClear='true'
v-decorator="['status']">
<a-select-option v-for='item in options' :key='item.value'>
{{ item.label }}
</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :md='7' :sm='15'>
<a-form-item label='评价'>
<a-select v-model='queryParam.evalService'
v-decorator="['evalService']">
<a-select-option v-for='item in evalOptions' :key='item.value'>
{{ item.label }}
</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :md='7' :sm='15'>
<a-form-item label='报修时间'>
<a-range-picker v-model='dateRange' @change='onChange' />
</a-form-item>
</a-col>
<a-col :md='8' :sm='24'>
<span class='table-page-search-submitButtons'>
<a-button type='primary' @click='$refs.table.refresh(true)'>查询</a-button>
<a-button style='margin-left: 8px' @click='reset()'>重置</a-button>
<a-button style='margin-left: 8px' type='primary' @click='saveUserFilterConditions'>保存筛选条件</a-button>
<a-button style='margin-left: 8px' type='danger' @click='clearUserFilterConditions'>清除筛选条件</a-button>
<a-button style='margin-left: 8px' type='primary' @click='exportRepair()'>导出工单模版</a-button>
<a-button style='margin-left: 8px' type='primary' @click='importDataVisible()'>导入</a-button>
<a-button style='margin-left: 8px' type='primary' @click='exportRepairList()'>导出工单数据</a-button>
<a-button style='margin-left: 8px' type='primary' @click='exportRepairTypeList()'>导出类型汇总数据</a-button>
</span>
</a-col>
</a-row>
</a-form>
</div>
<div class='table-operator' v-if='!isShowModel'>
<a-button v-if='addEnable' type='primary' icon='plus' @click='$refs.modal.add()'>新建</a-button>
<a-dropdown v-if='removeEnable&&selectedRowKeys.length > 0'>
<a-button type='danger' icon='delete' @click='delByIds(selectedRowKeys)'>删除</a-button>
</a-dropdown>
</div>
<s-table
size='default'
ref='table'
rowKey='id'
showPagination="true"
:rowSelection='{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}'
:columns='columns'
:data='loadData'
>
<span slot='status' slot-scope='text'>
{{ text | statusFilter }}
</span>
<span slot='remark' slot-scope='text'>
<a-tag v-if="text == '5110'" color='blue'>
{{ text }}
</a-tag>
<a-tag v-else color='cyan'>
普通报修
</a-tag>
</span>
<span slot='action' slot-scope='text, record'>
<a v-if='editEnabel' @click='handleView(record.id)'>详情</a>
<!-- <a-divider v-if='!isShowModel' type='vertical' />-->
<!-- <a v-if='editEnabel && !isShowModel' @click='handleEdit(record)'>编辑</a>-->
<a-divider v-if='!isShowModel' type='vertical' />
<a type='danger' v-if='!isShowModel' @click='delByIds(record.id)'>删除</a>
<!-- <a-divider v-if='!isShowModel' type='vertical' />-->
<!-- <a type='danger' v-if='!isShowModel' @click='delByIds(selectedRowKeys)'>批量删除</a>-->
</span>
</s-table>
<repair-modal ref='modal' @success='handleOk' />
<a-modal v-model='visible' title='导入工单'>
<div style='display: flex'>
<a-upload
accept='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel'
@change='customChange'
:customRequest='customRequest'>
<a-button type='primary'>导入工单</a-button>
</a-upload>
</div>
</a-modal>
</a-card>
</template>
<script>
import { STable } from '@/components'
import { getRepairList, complete, delRepair } from '@/api/admin/repair'
import { oneWorkerList, oneFloorList, oneFloorCreateList } from '@/api/admin/repair/repairStats'
import RepairModal from './modules/RepairModal.vue'
import { checkPermission } from '@/utils/permissions'
import { getRepairDeviceList } from '@/api/admin/repair/repairDevice'
import { getRepairTypeList } from '@/api/admin/repair/repairDeviceType'
import { exportRepair, exportRepairType, exportTemplate, importData } from '@/api/admin/repair/repairIo'
import storage from 'store'
import { ACCESS_TOKEN } from '@/store/mutation-types'
import { message } from 'ant-design-vue'
import { delRepairRoom } from '@/api/admin/repair/repairAddressFloor'
export default {
name: 'TableList',
components: {
STable,
RepairModal
},
data() {
return {
dateRange: [],
isShowModel: false, // 是否为查看模式,查看模式下仅允许查看列表、查看详情
labelCol: {
xs: { span: 24 },
sm: { span: 5 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 }
},
form: this.$form.createForm(this),
mdl: {},
visible: false,
headers: {
Authorization: 'Bearer ' + storage.get(ACCESS_TOKEN)
},
// 高级搜索 展开/关闭
advanced: false,
// 查询参数
queryParam: {
'type': 'all',
'explain': '',
'sn': '',
'typeId': '',
'deviceId': '',
'status': '',
'repairLevel': '',
'beginTime': '',
'endTime': '',
'evalService': '',
'timeout': '',
'remark': '',
'name': ''
},
// loadData: [],
typeList: [],
deviceList: [],
repairLevelOptions: [{
value: '',
label: '全部'
}, {
value: '一级',
label: '一级'
}, {
value: '二级',
label: '二级'
}, {
value: '三级',
label: '三级'
}
],
evalOptions: [{
value: '',
label: '全部'
}, {
value: 1,
label: '好评'
}, {
value: 2,
label: '中评'
}, {
value: 3,
label: '差评'
}
],
remarkOption: [{
value: '',
label: '全部'
}, {
value: 'no',
label: '普通报修'
}, {
value: 'yes',
label: '5110'
}
],
options: [{
value: 'all',
label: '全部'
}, {
value: 'wait',
label: '待派单'
}, {
value: 'anew',
label: '重新派单'
}, {
value: 'already',
label: '已派单'
}, {
value: 'process',
label: '处理中'
}, {
value: 'evaling',
label: '待评价'
}, {
value: 'evaled',
label: '已评价'
}, {
value: 'invalid',
label: '无效申请'
}
],
// 表头
columns: [
{
title: '维修单号',
dataIndex: 'sn'
},
{
title: '故障类型',
dataIndex: 'typeName'
},
{
title: '故障子类',
dataIndex: 'deviceName'
},
{
title: '故障等级',
dataIndex: 'repairLevel'
},
{
title: '报修来源',
dataIndex: 'remark',
scopedSlots: { customRender: 'remark' }
},
{
title: '工单状态',
dataIndex: 'status',
scopedSlots: { customRender: 'status' }
},
{
title: '报修人',
dataIndex: 'name'
},
{
title: '报修时间',
dataIndex: 'createTime',
sorter: true
},
{
title: '操作',
width: '200px',
dataIndex: 'action',
scopedSlots: { customRender: 'action' }
}
],
// 加载数据方法 必须为 Promise 对象
loadData: parameter => {
if (this.$route.query.repairUserId != null) {
return oneWorkerList(Object.assign(parameter, { workerId: this.$route.query.repairUserId }))
} else if (this.$route.query.floorId != null) {
return oneFloorList(Object.assign(parameter, { floorerId: this.$route.query.floorId }))
} else if (this.$route.query.floorCreateId != null) {
return oneFloorCreateList(Object.assign(parameter, { floorerId: this.$route.query.floorCreateId }))
} else {
const data = {
'role': 7,
'type': this.queryParam.type,
'repair': {
'explain': this.queryParam.explain,
'sn': this.queryParam.sn,
'typeId': this.queryParam.typeId,
'deviceId': this.queryParam.deviceId,
'status': this.queryParam.status,
'repairLevel': this.queryParam.repairLevel,
'beginTime': this.queryParam.startTime,
'endTime': this.queryParam.endTime,
'evalService': this.queryParam.evalService,
'timeout': this.queryParam.timeout,
'remark': this.queryParam.remark,
'name': this.queryParam.name
}
}
return getRepairList(Object.assign(parameter, data))
}
// return getRepairList(Object.assign(parameter, this.queryParam))
},
selectedRowKeys: [],
selectedRows: [],
addEnable: checkPermission('admin:repair:add'),
editEnabel: checkPermission('admin:repair:edit'),
removeEnable: checkPermission('admin:repair:list')
}
},
filters: {
// 状态:1 待派单,3 重新派单,5 已派单,7 处理中, 9已完成 待评价, 11 已关闭 13 已评价
statusFilter(status) {
const statusMap = {
'1': '待派单',
'3': '重新派单',
'5': '已派单',
'7': '处理中',
'9': '待评价',
'11': '无效申请',
'13': '已评价'
}
return statusMap[status]
}
},
created() {
// console.log('this.$route.query', this.$route.query.evalService)
// 获取三个查询参数
if (this.$route.query.evalService != null) {
this.queryParam.evalService = this.$route.query.evalService
}
this.queryParam.timeout = this.$route.query.timeout
this.queryParam.type = this.$route.query.status || 'all'
// this.selectRepairList()
// 页面部分隐藏
if (this.$route.query.repairUserId != null || this.$route.query.floorId != null || this.$route.query.floorCreateId != null) {
// 从绩效入口进入,不允许新建、查询、编辑、删除等操作
this.isShowModel = true
}
this.selectType()
// 恢复之前保存的筛选条件
this.restoreFilterConditions()
},
activated() {
// 从详情页返回时恢复筛选条件
this.restoreFilterConditions()
},
methods: {
fatherMethod(val) {
console.log('val实际就是子组件传过来的childParam')
},
customChange() {
},
onSelectChange(selectedRowKeys, selectedRows) {
this.selectedRowKeys = selectedRowKeys
this.selectedRows = selectedRows
},
reset() {
// 直接调用清除筛选条件的方法
this.clearUserFilterConditions()
},
customRequest(file) {
// file 是上传的文件 其内容会在放在下面截图中
// 后端需要接受的参数是 formData数据
// uploadFile 我自己的接口
const formData = new FormData()
formData.append('file', file.file)
console.log(file)
importData(formData).then(res => {
if (res.code == 0) {
// 调用组件内方法, 设置为成功状态
file.onSuccess(res, file.file)
file.status = 'done'
this.visible = false
this.$message.success('导入成功')
} else {
this.$message.error(res.msg)
file.onError()
file.status = 'error'
}
})
},
// 导入工单
importDataVisible() {
this.visible = true
},
// 导出工单模板
exportRepair() {
exportTemplate().then(res => {
this.exportExcel('工单模版', res)
})
},
// 导出工单
exportRepairList() {
if (this.dateRange.length < 2) {
message.error('请先设置时间范围系统将根据时间范围导出工单数据')
return
}
const startDate = this.dateRange[0].format('YYYY-MM-DD')
const endDate = this.dateRange[1].format('YYYY-MM-DD')
exportRepair({
'explain': this.queryParam.explain,
'sn': this.queryParam.sn,
'typeId': this.queryParam.typeId,
'deviceId': this.queryParam.deviceId,
'status': this.queryParam.status,
'repairLevel': this.queryParam.repairLevel,
'beginTime': startDate,
'endTime': endDate,
'evalService': this.queryParam.evalService,
'timeout': this.queryParam.timeout,
'remark': this.queryParam.remark,
'name': this.queryParam.name
}).then(res => {
this.exportExcel('工单数据', res)
})
},
exportRepairTypeList() {
if (this.dateRange.length < 2) {
message.error('请先设置时间范围系统将根据时间范围导出工单数据')
return
}
const startDate = this.dateRange[0].format('YYYY-MM-DD')
const endDate = this.dateRange[1].format('YYYY-MM-DD')
exportRepairType({
'beginTime': startDate,
'endTime': endDate
}).then(res => {
this.exportExcel('工单按维修类型汇总', res)
})
},
exportExcel(filename, res) {
const link = document.createElement('a')
let blob = new Blob([res], { type: 'application/vnd.ms-excel;charset=UTF-8' })
link.style.display = 'none'
link.href = URL.createObjectURL(blob)
let num = ''
for (let i = 0; i < 10; i++) {
num += Math.ceil(Math.random() * 10)
}
link.setAttribute('download', filename + '.xls')
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
},
// 切换时间
onChange(value, dateString) {
this.queryParam.startTime = dateString[0]
this.queryParam.endTime = dateString[1]
},
// 查询分类
selectType() {
getRepairTypeList().then(res => {
let _all = []
_all.push({
name: '全部', id: ''
})
_all = _all.concat(res.rows)
this.typeList = _all
// 给设备子类赋值,默认全部为空
this.deviceList = [{
name: '全部', id: ''
}]
})
},
// 查询设备
selectDevice(typeId) {
if (typeId === '') {
// 全部的情况
this.deviceList = [{
name: '全部', id: ''
}]
this.queryParam.deviceId = ''
} else {
// ajax获取
getRepairDeviceList({ 'typeId': typeId }).then(res => {
let _all = []
_all.push({
name: '全部', id: ''
})
_all = _all.concat(res.rows)
this.deviceList = _all
this.queryParam.deviceId = ''
})
}
this.queryParam.typeId = typeId
},
getDeviceName(deviceId) {
this.queryParam.deviceId = deviceId
},
delByIds(ids) {
const _this = this
if (ids === '') {
this.$message.error('请选择后删除')
return
}
this.$confirm({
title: '警告',
content: '删除后不可恢复是否确认删除?',
okText: '',
okType: 'warning',
cancelText: '',
onOk() {
delRepair({ ids: ids.join(',') }).then(res => {
if (res.code === 0) {
_this.message.success('删除成功')
_this.handleOk()
} else {
_this.$message.error(res.msg)
}
_this.selectedRowKeys = []
})
},
onCancel() {
}
})
},
handleAdd() {
this.$refs.modal.add()
},
handleView(repairId) {
// 不再自动保存筛选条件,而是依赖用户主动点击保存按钮
// try {
// this.saveFilterConditions()
// } catch (e) {
// console.error('保存筛选条件失败', e)
// }
// 跳转到详情页
this.$router.push({ name: 'repairView', query: { repairId: repairId } })
},
handleEdit(record) {
this.$refs.modal.edit(record)
},
handleOk(status) {
status = status || false
this.$refs.table.refresh(status)
// console.log('handleSaveOk')
},
handleComplete(id) {
const _this = this
this.$confirm({
title: '警告',
content: '确认要完成工单吗?',
okText: '',
okType: 'warning',
cancelText: '',
onOk() {
complete(id).then(res => {
if (res.code === 0) {
_this.$message.success('操作成功')
_this.$refs.table.refresh(true)
} else {
_this.$message.error(res.msg)
}
}).catch(() => {
this.$message.error('系统错误请稍后再试')
})
},
onCancel() {
}
})
},
// 保存筛选条件到localStorage
saveFilterConditions() {
// 处理日期范围格式
let formattedDateRange = null;
if (this.dateRange && this.dateRange.length === 2) {
formattedDateRange = [
this.dateRange[0].format('YYYY-MM-DD'),
this.dateRange[1].format('YYYY-MM-DD')
];
}
const filterConditions = {
queryParam: JSON.parse(JSON.stringify(this.queryParam)), // 深拷贝查询参数
dateRange: formattedDateRange,
typeId: this.queryParam.typeId || '',
deviceId: this.queryParam.deviceId || ''
}
// 保存到localStorage
localStorage.setItem('repairListFilterConditions', JSON.stringify(filterConditions))
},
// 从localStorage恢复筛选条件
restoreFilterConditions() {
const savedConditions = localStorage.getItem('repairListFilterConditions')
if (savedConditions) {
try {
const conditions = JSON.parse(savedConditions)
// 恢复查询参数
if (conditions.queryParam) {
this.queryParam = conditions.queryParam
}
// 恢复日期范围
if (conditions.dateRange && conditions.dateRange.length === 2) {
this.dateRange = [
this.$moment(conditions.dateRange[0]),
this.$moment(conditions.dateRange[1])
]
this.queryParam.startTime = conditions.dateRange[0]
this.queryParam.endTime = conditions.dateRange[1]
}
// 恢复设备类型及子类
if (conditions.typeId) {
// 先加载设备类型
this.selectDevice(conditions.typeId)
// 确保设备子类被正确设置
if (conditions.deviceId) {
this.$nextTick(() => {
this.queryParam.deviceId = conditions.deviceId
})
}
}
// 刷新表格
this.$nextTick(() => {
if (this.$refs.table) {
this.$refs.table.refresh(true)
// 提示用户当前使用的是保存的筛选条件
this.$message.info('已应用保存的筛选条件')
}
})
} catch (e) {
console.error('恢复筛选条件失败:', e)
}
}
},
saveUserFilterConditions() {
// 实现保存筛选条件的逻辑
try {
// 检查是否有有效的筛选条件
const hasFilter = Object.keys(this.queryParam).some(key => {
// 排除type为'all'的情况,这是默认值
if (key === 'type' && this.queryParam[key] === 'all') {
return false
}
// 检查其他参数是否有值
return this.queryParam[key] !== '' && this.queryParam[key] !== null && this.queryParam[key] !== undefined
})
// 检查日期范围
const hasDateRange = this.dateRange && this.dateRange.length === 2
if (!hasFilter && !hasDateRange) {
this.$message.info('当前没有设置筛选条件无需保存')
return
}
// 保存筛选条件
this.saveFilterConditions()
this.$message.success('筛选条件已保存下次访问将自动应用')
} catch (e) {
console.error('保存筛选条件失败', e)
this.$message.error('保存筛选条件失败')
}
},
clearUserFilterConditions() {
// 实现清除筛选条件的逻辑
try {
// 清除localStorage中保存的筛选条件
localStorage.removeItem('repairListFilterConditions')
// 重置查询参数
this.queryParam = {
'type': 'all',
'explain': '',
'sn': '',
'typeId': '',
'deviceId': '',
'status': '',
'repairLevel': '',
'beginTime': '',
'endTime': '',
'evalService': '',
'timeout': '',
'remark': '',
'name': ''
}
// 重置时间范围
this.dateRange = []
// 刷新列表数据
this.$nextTick(() => {
if (this.$refs.table) {
this.$refs.table.refresh(true)
}
})
this.$message.success('筛选条件已清除列表已重置')
} catch (e) {
console.error('清除筛选条件失败', e)
this.$message.error('清除筛选条件失败')
}
}
},
watch: {}
}
</script>