更新
This commit is contained in:
parent
aadeb256a7
commit
780f394407
@ -20,6 +20,15 @@ export function getRepairSoPage(params){
|
||||
})
|
||||
}
|
||||
|
||||
// 分页
|
||||
export function getRepairSoPageItems(params){
|
||||
return request({
|
||||
url: preUrl + "/page-with-items",
|
||||
method: "get",
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 统计
|
||||
export function purchase(params){
|
||||
return request({
|
||||
@ -74,7 +83,8 @@ export function inWare(data){
|
||||
// 导出数据
|
||||
export function exportData(params){
|
||||
return request({
|
||||
url: preUrl + "/export",
|
||||
// url: preUrl + "/export",
|
||||
url: preUrl + "/export-with-items",
|
||||
method: 'get',
|
||||
params,
|
||||
responseType: 'blob'
|
||||
|
||||
@ -54,10 +54,11 @@ export function setTicketsSettlement(data){
|
||||
data
|
||||
})
|
||||
}
|
||||
// 结算审核
|
||||
export function settlementReview(data){
|
||||
|
||||
// 反结算
|
||||
export function setTicketsAntiSettlement(data){
|
||||
return request({
|
||||
url: preUrl + "/settlementReview",
|
||||
url: preUrl + "/antiSettlement",
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
@ -107,6 +108,15 @@ export function getStatistics(params){
|
||||
})
|
||||
}
|
||||
|
||||
// 结算审核
|
||||
export function settlementReview(data){
|
||||
return request({
|
||||
url: preUrl + "/settlementReview",
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 判断登录用户的角色,针对维修工单中的四个角色
|
||||
export function getUserRole(){
|
||||
return request({
|
||||
@ -245,6 +255,17 @@ export function exportData(params){
|
||||
})
|
||||
}
|
||||
|
||||
// 导出合并数据
|
||||
export function exportMerged(params){
|
||||
return request({
|
||||
url: preUrl + "/exportMerged",
|
||||
method: 'get',
|
||||
params,
|
||||
responseType: 'blob',
|
||||
timeout: 6000000
|
||||
})
|
||||
}
|
||||
|
||||
// 导出数据 根据工单状态
|
||||
export function exportByStatus(params){
|
||||
return request({
|
||||
|
||||
@ -35,6 +35,15 @@ export function updateChargeCompany(data) {
|
||||
})
|
||||
}
|
||||
|
||||
// 修改挂账单位
|
||||
export function reviewChargeCompany(data) {
|
||||
return request({
|
||||
url: '/base-charge-company/review',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除挂账单位
|
||||
export function deleteChargeCompany(ids) {
|
||||
return request({
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
</el-form>
|
||||
|
||||
<!-- 文件预览对话框 -->
|
||||
<el-dialog :title="'文件预览(' + selectFile.fileName + ')'" :visible.sync="isShowFile" width="70%" append-to-body>
|
||||
<el-dialog :title="'文件预览(' + selectFile.fileName + ')'" :visible.sync="isShowFile" width="70%" append-to- >
|
||||
<!-- 全屏按钮 -->
|
||||
<el-button
|
||||
class="fullscreen-btn"
|
||||
|
||||
@ -191,7 +191,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getChargeCompanyList, getChargeCompany, addChargeCompany, updateChargeCompany, deleteChargeCompany } from './api/chargeCompanyApi'
|
||||
import { getChargeCompanyList, getChargeCompany, addChargeCompany, updateChargeCompany, deleteChargeCompany ,reviewChargeCompany} from './api/chargeCompanyApi'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import { getLastPathSegment } from '@/utils/ruoyi'
|
||||
import ChargeCompanyForm from './form/ChargeCompanyForm'
|
||||
@ -344,7 +344,7 @@ export default {
|
||||
handleStatusChange(row) {
|
||||
const statusMsg = row.status ? '启用' : '禁用'
|
||||
this.$modal.confirm(`是否确认${statusMsg}该挂账单位?`).then(() => {
|
||||
updateChargeCompany(row).then(() => {
|
||||
reviewChargeCompany(row).then(() => {
|
||||
this.$modal.msgSuccess(`${statusMsg}成功`)
|
||||
this.getList()
|
||||
}).catch(() => {
|
||||
|
||||
@ -36,10 +36,10 @@
|
||||
</el-row>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||
<el-table-column label="序号" align="center" width="55">
|
||||
<el-table v-loading="loading" :data="expandedList" :stripe="true" :show-overflow-tooltip="true" :row-key="row => row._rowKey" :span-method="mergeCells">
|
||||
<el-table-column label="序号" align="center" width="55" prop="_index">
|
||||
<template scope="scope">
|
||||
<span>{{ scope.$index + 1 }}</span>
|
||||
<span>{{ scope.row._index + 1 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单号" align="center" prop="soNo" width="200"/>
|
||||
@ -49,14 +49,36 @@
|
||||
<el-table-column label="退货时间" align="center" prop="soTime"
|
||||
width="150"/>
|
||||
<el-table-column label="退货人" align="center" prop="userName" />
|
||||
<el-table-column label="商品" align="center" prop="itemGoodsName" width="180">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.itemGoodsName || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品数量" align="center" prop="itemGoodsCount" width="150">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.itemGoodsCount || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品价格" align="center" prop="itemGoodsPrice" width="150">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.itemGoodsPrice || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="仓库" align="center" prop="houseName" width="180">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.houseName || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" fixed="right" width="180" align="center">
|
||||
<template v-slot="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-view" @click="handleShow(scope.row)"
|
||||
>查看
|
||||
</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-close" @click="handleVoidSo(scope.row)"
|
||||
>作废
|
||||
</el-button>
|
||||
<template v-if="scope.row._isFirstItem">
|
||||
<el-button size="mini" type="text" icon="el-icon-view" @click="handleShow(scope.row)"
|
||||
>查看
|
||||
</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-close" @click="handleVoidSo(scope.row)"
|
||||
>作废
|
||||
</el-button>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -183,7 +205,7 @@ import SupplierChoose from "@/views/repair/Components/SupplierChoose.vue";
|
||||
import StaffChoose from "@/views/repair/Components/StaffChoose.vue";
|
||||
import CorpChoose from "@/views/repair/Components/CorpChoose.vue";
|
||||
import SoReturnForm from "@/views/repair/stockOperate/form/SoReturnForm.vue";
|
||||
import {getRepairSoById, getRepairSoPage, voidSo, exportData} from "@/api/repair/stockOperate/stockOperate";
|
||||
import {getRepairSoById, getRepairSoPage, voidSo, exportData, getRepairSoPageItems} from "@/api/repair/stockOperate/stockOperate";
|
||||
import {getRepairSoiByIds} from "@/api/repair/stockOperate/stockOperateItem";
|
||||
import {getBaseWarehouseList} from "@/api/base/warehouse";
|
||||
|
||||
@ -201,6 +223,7 @@ export default {
|
||||
},
|
||||
showSearch: true,
|
||||
list: [],
|
||||
expandedList: [],
|
||||
total: 0,
|
||||
loading: false,
|
||||
supplier: null,
|
||||
@ -211,6 +234,10 @@ export default {
|
||||
dialogVisible: false,
|
||||
info: {},
|
||||
warehouseList: [],
|
||||
// 需要合并的属性
|
||||
mergeProps: ['_index', 'soNo', 'itemCount', 'totalPrice', 'supplierName', 'soTime', 'userName'],
|
||||
// 项目相关的属性,不需要合并
|
||||
itemProps: ['itemGoodsName', 'itemGoodsCount', 'itemGoodsPrice', 'houseName'],
|
||||
// 导出遮罩层
|
||||
exportLoading: false,
|
||||
}
|
||||
@ -263,12 +290,109 @@ export default {
|
||||
} catch {
|
||||
}
|
||||
},
|
||||
// 处理数据并展开items数组
|
||||
processDataForMergeCells(data) {
|
||||
const result = [];
|
||||
let index = 0;
|
||||
|
||||
data.forEach((item, idx) => {
|
||||
const items = item.items || [];
|
||||
|
||||
if (items.length > 0) {
|
||||
items.forEach((subItem, subIdx) => {
|
||||
const newItem = {
|
||||
...item,
|
||||
_index: idx, // 保存原始索引
|
||||
_rowKey: `${item.id}_${subIdx}`, // 唯一标识
|
||||
_isFirstItem: subIdx === 0,
|
||||
itemGoodsName: subItem.wares?.name || '-',
|
||||
itemGoodsCount: subItem.goodsCount || '-',
|
||||
itemGoodsPrice: subItem.goodsPrice || '-',
|
||||
houseName: subItem.houseName || '-'
|
||||
};
|
||||
result.push(newItem);
|
||||
});
|
||||
} else {
|
||||
// 没有items的情况
|
||||
const newItem = {
|
||||
...item,
|
||||
_index: idx,
|
||||
_rowKey: `${item.id}_0`,
|
||||
_isFirstItem: true,
|
||||
itemGoodsName: '-',
|
||||
itemGoodsCount: '-',
|
||||
itemGoodsPrice: '-',
|
||||
itemWareId: '-'
|
||||
};
|
||||
result.push(newItem);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
// 合并单元格方法
|
||||
mergeCells({row, column, rowIndex, columnIndex}) {
|
||||
// 如果是项目相关列,不合并
|
||||
if (this.itemProps.includes(column.property)) {
|
||||
return { rowspan: 1, colspan: 1 };
|
||||
}
|
||||
|
||||
// 如果是操作列,只在首行显示
|
||||
if (column.property === undefined && column.label === '操作') {
|
||||
if (row._isFirstItem) {
|
||||
const mainId = row.id;
|
||||
let count = 0;
|
||||
|
||||
// 计算相同id的行数
|
||||
for (let i = rowIndex; i < this.expandedList.length; i++) {
|
||||
if (this.expandedList[i].id === mainId) {
|
||||
count++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return { rowspan: count, colspan: 1 };
|
||||
} else {
|
||||
return { rowspan: 0, colspan: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
// 合并其他公用数据列
|
||||
if (this.mergeProps.includes(column.property) || (column.property === undefined && column.label === '序号')) {
|
||||
const mainId = row.id;
|
||||
|
||||
// 只在每个主记录的第一行进行计算
|
||||
if (row._isFirstItem) {
|
||||
let count = 0;
|
||||
|
||||
// 计算相同id的行数
|
||||
for (let i = rowIndex; i < this.expandedList.length; i++) {
|
||||
if (this.expandedList[i].id === mainId) {
|
||||
count++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return { rowspan: count, colspan: 1 };
|
||||
} else {
|
||||
return { rowspan: 0, colspan: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
return { rowspan: 1, colspan: 1 };
|
||||
},
|
||||
|
||||
async getReturnList() {
|
||||
try {
|
||||
this.loading = true
|
||||
const res = await getRepairSoPage(this.queryParams)
|
||||
const res = await getRepairSoPageItems(this.queryParams)
|
||||
this.list = res.data.records
|
||||
this.total = res.data.total
|
||||
// 处理数据,展开items数组并准备合并单元格
|
||||
this.expandedList = this.processDataForMergeCells(this.list)
|
||||
}finally {
|
||||
this.loading = false
|
||||
}
|
||||
|
||||
@ -127,7 +127,7 @@ export default {
|
||||
break
|
||||
case "ts":
|
||||
// this.queryParams.ticketsStatus = "04"
|
||||
this.queryParams.payStatus = "01"
|
||||
this.queryParams.payStatuses = ["01","04"]
|
||||
break
|
||||
default:
|
||||
break
|
||||
|
||||
@ -120,16 +120,20 @@
|
||||
@click="handlePaid(scope.row)" v-if="TicketType === 'tu' && scope.row.settlementType != 'gz'"
|
||||
>收款
|
||||
</el-button>
|
||||
<el-button v-hasPermi="['repair:tk:paid']" size="mini" type="text" icon="el-icon-finished"
|
||||
@click="handleAntiSettlement(scope.row)" v-if="TicketType === 'tu' && scope.row.settlementType != 'gz'"
|
||||
>反结算
|
||||
</el-button>
|
||||
<el-button v-hasPermi="['repair:tk:paid']" size="mini" type="text" icon="el-icon-finished"
|
||||
@click="handlePaid(scope.row)" v-if="TicketType === 'tu' && scope.row.settlementType == 'gz'"
|
||||
>销账
|
||||
</el-button>
|
||||
<el-button v-hasPermi="['repair:tk:settlement']" size="mini" type="text" icon="el-icon-finished"
|
||||
@click="handleSettlement(scope.row,'js')" v-if="TicketType === 'ts' && !scope.row.settlement"
|
||||
@click="handleSettlement(scope.row,'js')" v-if="TicketType === 'ts' && (!scope.row.settlement || scope.row.payStatus == '04')"
|
||||
>结算
|
||||
</el-button>
|
||||
<el-button v-hasPermi="['repair:tk:settlement:review']" size="mini" type="text" icon="el-icon-finished"
|
||||
@click="handleSettlement(scope.row,'jssh')" v-if="TicketType === 'ts' && scope.row.settlement"
|
||||
@click="handleSettlement(scope.row,'jssh')" v-if="TicketType === 'ts' && scope.row.settlement && scope.row.payStatus != '04'"
|
||||
>结算审核
|
||||
</el-button>
|
||||
<!-- <el-button v-if="TicketType === 'tp'" size="mini" type="text" icon="el-icon-refresh-right"-->
|
||||
@ -455,6 +459,17 @@
|
||||
<el-input v-model="chargeCompanyForm.remark" placeholder="请输入备注" type="textarea" />
|
||||
</el-form-item>
|
||||
|
||||
<!-- 资料上传 -->
|
||||
<el-form-item label="资料上传" prop="file">
|
||||
<el-upload class="upload-demo" :action="uploadFileUrl" :multiple="true" :before-upload="beforeUpload"
|
||||
:file-list="uploadFileList" :on-success="handleUploadSuccess" :on-error="handleUploadError"
|
||||
:on-remove="handleRemove" :headers="headers" name="file" accept=".pdf,.doc,.docx,.txt,.jpg,.jpeg,.png"
|
||||
:on-preview="previewFile">
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
<div slot="tip" class="el-upload__tip">支持多文件上传,文件格式:pdf、doc、docx、txt、jpg、jpeg、png,大小不超过20MB</div>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 隐藏字段 -->
|
||||
<el-form-item label="" prop="status" style="display: none;">
|
||||
<el-input v-model="chargeCompanyForm.status" type="hidden" />
|
||||
@ -463,6 +478,10 @@
|
||||
<el-form-item label="" prop="systemCode" style="display: none;">
|
||||
<el-input v-model="chargeCompanyForm.systemCode" type="hidden" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="" prop="file" style="display: none;">
|
||||
<el-input v-model="chargeCompanyForm.file" type="hidden" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div slot="footer" class="dialog-footer">
|
||||
@ -470,6 +489,49 @@
|
||||
<el-button @click="cancelChargeCompany">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 文件预览对话框 -->
|
||||
<el-dialog :title="'文件预览(' + selectFile.fileName + ')'" :visible.sync="isShowFile" width="70%" append-to-body>
|
||||
<!-- 全屏按钮 -->
|
||||
<el-button
|
||||
class="fullscreen-btn"
|
||||
icon="el-icon-full-screen"
|
||||
size="mini"
|
||||
@click="toggleFullScreen"
|
||||
style="position: absolute; top: 10px; right: 100px; z-index: 10;"
|
||||
>
|
||||
全屏
|
||||
</el-button>
|
||||
<div class="preview-container" ref="previewContainer">
|
||||
<!-- 音频预览 -->
|
||||
<audio v-if="isAudioType" class="preview-iframe" controls>
|
||||
<source :src="getPreviewFilePath(selectFile)"/>
|
||||
</audio>
|
||||
<!-- 图片预览 -->
|
||||
<img
|
||||
v-if="isImageType"
|
||||
:src="getPreviewFilePath(selectFile)"
|
||||
class="preview-iframe"
|
||||
style="max-width: 100%; max-height: 80vh; object-fit: contain;"
|
||||
>
|
||||
<!-- Office文档预览 -->
|
||||
<iframe
|
||||
v-if="!isAudioType && !isImageType && !isPdfType && !isTxtType"
|
||||
:src="fileUrl"
|
||||
frameborder="0"
|
||||
class="preview-iframe"
|
||||
>
|
||||
</iframe>
|
||||
<!-- PDF和TXT预览 -->
|
||||
<iframe
|
||||
v-if="isPdfType || isTxtType"
|
||||
:src="getPreviewFilePath(selectFile)"
|
||||
frameborder="0"
|
||||
class="preview-iframe"
|
||||
>
|
||||
</iframe>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -482,17 +544,20 @@ import {
|
||||
setTicketsSettlement,
|
||||
settlementReview,
|
||||
getSettlement,
|
||||
payConfirm
|
||||
payConfirm,
|
||||
setTicketsAntiSettlement
|
||||
} from '@/api/repair/tickets/Tickets'
|
||||
import TicketsShow from "@/views/repair/tickets/Components/TicketsShow.vue";
|
||||
import {getByNameAndMobile} from "@/api/base/customer";
|
||||
import { getByNameAndMobile} from "@/api/base/customer";
|
||||
import EditTickets from "@/views/repair/tickets/form/EditTickets.vue";
|
||||
import { getChargeCompanyList, addChargeCompany } from '@/views/base/chargeCompany/api/chargeCompanyApi'
|
||||
import { getAccounts } from '@/views/company/account/api/accountApi'
|
||||
import { getAccessToken } from "@/utils/auth"
|
||||
import ImagePreview from '@/components/ImagePreview';
|
||||
|
||||
export default {
|
||||
name: "TicketTable",
|
||||
components: {EditTickets, TicketsShow},
|
||||
components: {EditTickets, TicketsShow, ImagePreview},
|
||||
props: {
|
||||
TicketType: {
|
||||
type: String,
|
||||
@ -512,9 +577,9 @@ export default {
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
showLoading: false, // 添加加载状态
|
||||
return {
|
||||
loading: false,
|
||||
showLoading: false, // 添加加载状态
|
||||
formData: {
|
||||
id: null,
|
||||
ticketsStatus: null,
|
||||
@ -543,8 +608,29 @@ export default {
|
||||
address: '',
|
||||
status: false, // 默认为禁用状态
|
||||
systemCode: 'repair',
|
||||
remark: ''
|
||||
remark: '',
|
||||
file: '' // 文件路径,以逗号分隔
|
||||
},
|
||||
// 上传文件列表
|
||||
uploadFileList: [],
|
||||
// 文件预览地址
|
||||
viewFileUrl: process.env.VUE_APP_FILE_API,
|
||||
// 文件上传地址
|
||||
uploadFileUrl: process.env.VUE_APP_BASE_API + "/admin-api/infra/file/upload",
|
||||
// 上传请求头
|
||||
headers: { Authorization: "Bearer " + getAccessToken() },
|
||||
// 正在上传的文件数量
|
||||
uploadingCount: 0,
|
||||
// 文件预览相关
|
||||
isShowFile: false,
|
||||
selectFile: {
|
||||
fileName: '',
|
||||
filePath: '',
|
||||
isImage: false
|
||||
},
|
||||
fileUrl: '',
|
||||
// 是否正在从父组件同步数据
|
||||
isSyncingFromParent: false,
|
||||
chargeCompanyRules: {
|
||||
companyName: [{ required: true, message: '单位名称不能为空', trigger: 'blur' }],
|
||||
contactPerson: [{ required: true, message: '联系人不能为空', trigger: 'blur' }],
|
||||
@ -610,6 +696,32 @@ export default {
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 判断是否为图片类型
|
||||
isImageType() {
|
||||
if (!this.selectFile.fileName) return false;
|
||||
const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp'];
|
||||
const extension = this.selectFile.fileName.substring(this.selectFile.fileName.lastIndexOf('.')).toLowerCase();
|
||||
return imageExtensions.includes(extension);
|
||||
},
|
||||
// 判断是否为音频类型
|
||||
isAudioType() {
|
||||
if (!this.selectFile.fileName) return false;
|
||||
const audioExtensions = ['.mp3', '.wav', '.ogg', '.flac', '.aac'];
|
||||
const extension = this.selectFile.fileName.substring(this.selectFile.fileName.lastIndexOf('.')).toLowerCase();
|
||||
return audioExtensions.includes(extension);
|
||||
},
|
||||
// 判断是否为PDF类型
|
||||
isPdfType() {
|
||||
if (!this.selectFile.fileName) return false;
|
||||
return this.selectFile.fileName.toLowerCase().endsWith('.pdf');
|
||||
},
|
||||
// 判断是否为TXT类型
|
||||
isTxtType() {
|
||||
if (!this.selectFile.fileName) return false;
|
||||
return this.selectFile.fileName.toLowerCase().endsWith('.txt');
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// 监听是否支付状态变化
|
||||
'formData.isPaid': {
|
||||
@ -653,6 +765,26 @@ export default {
|
||||
} catch {
|
||||
}
|
||||
},
|
||||
async handleAntiSettlement(row) {
|
||||
this.$prompt('反结算备注', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
}).then(({value}) => {
|
||||
this.formData.id = row.id
|
||||
this.formData['remark'] = value
|
||||
this.formData.ticketsStatus = "03"
|
||||
this.doAntiSettlement()
|
||||
}).catch(() => {
|
||||
})
|
||||
},
|
||||
async doAntiSettlement() {
|
||||
try {
|
||||
await setTicketsAntiSettlement(this.formData)
|
||||
this.$modal.msgSuccess("反结算成功")
|
||||
this.$emit("setAntiSettlement")
|
||||
} catch {
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 打印
|
||||
*/
|
||||
@ -821,6 +953,7 @@ export default {
|
||||
try {
|
||||
await this.$refs['formRefSettlement'].validate()
|
||||
if (this.settlementType === 'jssh') {
|
||||
console.log('执行借宿那审核');
|
||||
await settlementReview(this.settlementFormData)
|
||||
} else {
|
||||
await setTicketsSettlement(this.settlementFormData)
|
||||
@ -828,7 +961,8 @@ export default {
|
||||
this.$modal.msgSuccess("提交成功")
|
||||
this.dialogVisibleSettlement = false
|
||||
this.$emit("setVoid")
|
||||
} catch {
|
||||
} catch (error) {
|
||||
console.error('Error in settlement process:', error);
|
||||
}
|
||||
},
|
||||
getDictDataByCode(code) {
|
||||
@ -953,8 +1087,11 @@ export default {
|
||||
address: '',
|
||||
status: false, // 默认为禁用状态
|
||||
systemCode: 'repair',
|
||||
remark: ''
|
||||
remark: '',
|
||||
file: ''
|
||||
};
|
||||
// 清空上传文件列表
|
||||
this.uploadFileList = [];
|
||||
this.chargeCompanyDialogVisible = true;
|
||||
},
|
||||
|
||||
@ -963,6 +1100,10 @@ export default {
|
||||
this.$refs.chargeCompanyFormRef.validate(async (valid) => {
|
||||
if (valid) {
|
||||
try {
|
||||
// 确保file字段已正确设置
|
||||
const fileField = this.ensureFileField();
|
||||
console.log('提交时的file字段值:', fileField);
|
||||
|
||||
await addChargeCompany(this.chargeCompanyForm);
|
||||
this.$modal.msgSuccess('挂账单位申请成功,请等待审核');
|
||||
this.chargeCompanyDialogVisible = false;
|
||||
@ -982,6 +1123,183 @@ export default {
|
||||
cancelChargeCompany() {
|
||||
this.chargeCompanyDialogVisible = false;
|
||||
this.$refs.chargeCompanyFormRef && this.$refs.chargeCompanyFormRef.resetFields();
|
||||
// 清空上传文件列表
|
||||
this.uploadFileList = [];
|
||||
},
|
||||
|
||||
// 文件上传前的钩子函数
|
||||
beforeUpload(file) {
|
||||
// 文件大小限制
|
||||
const isLt20M = file.size / 1024 / 1024 < 20 // 限制20MB
|
||||
if (!isLt20M) {
|
||||
this.$message.error('上传文件大小不能超过 20MB!')
|
||||
return false
|
||||
}
|
||||
|
||||
// 显示上传中加载状态
|
||||
if (this.uploadingCount === 0) {
|
||||
this.$modal.loading("正在上传文件,请稍候...")
|
||||
}
|
||||
this.uploadingCount++
|
||||
return true
|
||||
},
|
||||
|
||||
// 文件上传成功处理
|
||||
handleUploadSuccess(res, file, fileList) {
|
||||
this.uploadingCount--
|
||||
|
||||
// 检查响应数据格式
|
||||
console.log('上传成功响应:', res);
|
||||
|
||||
// 使用原始文件名显示
|
||||
const originalFileName = file.name || '未知文件名';
|
||||
|
||||
// 查找当前上传的文件在列表中的索引
|
||||
const index = this.uploadFileList.findIndex(item => item.uid === file.uid)
|
||||
if (index > -1) {
|
||||
// 使用服务器返回的文件路径
|
||||
const filePath = res && res.code === 0 && res.data ? res.data : file.name
|
||||
|
||||
// 更新文件列表
|
||||
this.uploadFileList[index].url = filePath
|
||||
this.uploadFileList[index].status = 'success'
|
||||
this.uploadFileList[index].name = originalFileName // 使用原始文件名显示
|
||||
this.uploadFileList[index].fileName = originalFileName // 添加fileName属性用于显示
|
||||
this.uploadFileList[index].filePath = filePath // 添加filePath属性用于预览
|
||||
this.uploadFileList[index].isImage = this.isImageExtension(originalFileName) // 判断是否为图片类型
|
||||
} else {
|
||||
// 如果在列表中找不到,添加到列表
|
||||
const filePath = res && res.code === 0 && res.data ? res.data : file.name
|
||||
this.uploadFileList.push({
|
||||
uid: file.uid,
|
||||
name: originalFileName,
|
||||
fileName: originalFileName,
|
||||
url: filePath,
|
||||
filePath: filePath,
|
||||
status: 'success',
|
||||
isImage: this.isImageExtension(originalFileName)
|
||||
})
|
||||
}
|
||||
|
||||
// 每次文件上传成功后立即更新file字段
|
||||
this.updateFilePaths()
|
||||
|
||||
// 所有文件上传完成后关闭加载
|
||||
if (this.uploadingCount === 0) {
|
||||
this.$modal.closeLoading()
|
||||
}
|
||||
},
|
||||
|
||||
// 文件上传失败处理
|
||||
handleUploadError(err, file, fileList) {
|
||||
this.uploadingCount--
|
||||
this.$message.error('文件上传失败,请重试')
|
||||
|
||||
if (this.uploadingCount === 0) {
|
||||
this.$modal.closeLoading()
|
||||
}
|
||||
},
|
||||
|
||||
// 文件移除时的处理函数
|
||||
handleRemove(file, fileList) {
|
||||
this.uploadFileList = fileList
|
||||
this.updateFilePaths()
|
||||
},
|
||||
|
||||
// 更新文件路径字符串(以逗号分隔)
|
||||
updateFilePaths() {
|
||||
// 使用上传成功后返回的文件路径
|
||||
const paths = this.uploadFileList
|
||||
.filter(file => file && (file.status === 'success' || file.url)) // 只处理已成功上传的文件
|
||||
.map(file => {
|
||||
// 确保使用正确的文件路径,优先使用url
|
||||
const filePath = file.url || file.name || ''
|
||||
|
||||
// 如果路径包含viewFileUrl,则去掉前缀
|
||||
if (filePath && this.viewFileUrl && filePath.includes(this.viewFileUrl)) {
|
||||
return filePath.replace(this.viewFileUrl, '')
|
||||
}
|
||||
return filePath
|
||||
})
|
||||
|
||||
// 设置文件路径,确保总是一个字符串(即使为空)
|
||||
const filePathStr = paths.join(',') || ''
|
||||
this.chargeCompanyForm.file = filePathStr
|
||||
|
||||
console.log('更新后的file字段值:', filePathStr)
|
||||
},
|
||||
|
||||
// 判断文件是否为图片格式
|
||||
isImageExtension(fileName) {
|
||||
if (!fileName) return false;
|
||||
const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp'];
|
||||
const extension = fileName.substring(fileName.lastIndexOf('.')).toLowerCase();
|
||||
return imageExtensions.includes(extension);
|
||||
},
|
||||
// 获取预览文件路径
|
||||
getPreviewFilePath(file) {
|
||||
if (!file || !file.filePath && !file.url) return '';
|
||||
|
||||
const filePath = file.filePath || file.url || '';
|
||||
// 如果是完整的http链接,直接返回
|
||||
if (filePath.startsWith('http://') || filePath.startsWith('https://')) {
|
||||
return filePath;
|
||||
}
|
||||
// 否则拼接完整的图片预览URL
|
||||
return `${this.viewFileUrl || process.env.VUE_APP_BASE_API}${filePath}`;
|
||||
},
|
||||
// 预览文件
|
||||
previewFile(file) {
|
||||
console.log('预览文件:', file);
|
||||
// 设置选中的文件信息
|
||||
this.selectFile = {
|
||||
fileName: file.name || file.fileName || '未知文件',
|
||||
filePath: file.url || file.filePath || '',
|
||||
isImage: file.isImage || this.isImageExtension(file.name || file.fileName || '')
|
||||
};
|
||||
|
||||
// 对于Office文档,使用Office Online预览
|
||||
if (!this.isImageExtension(this.selectFile.fileName) && !this.isPdfType && !this.isTxtType && !this.isAudioType) {
|
||||
const fileUrl = this.getPreviewFilePath(this.selectFile);
|
||||
this.fileUrl = `https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(fileUrl)}`;
|
||||
}
|
||||
|
||||
// 显示预览对话框
|
||||
this.isShowFile = true;
|
||||
},
|
||||
// 全屏切换
|
||||
toggleFullScreen() {
|
||||
const container = this.$refs.previewContainer;
|
||||
if (!container) return;
|
||||
|
||||
if (!document.fullscreenElement) {
|
||||
container.requestFullscreen().catch(err => {
|
||||
console.error(`全屏切换失败: ${err.message}`);
|
||||
});
|
||||
} else {
|
||||
if (document.exitFullscreen) {
|
||||
document.exitFullscreen();
|
||||
}
|
||||
}
|
||||
},
|
||||
// 从路径中提取文件名
|
||||
extractFileName(path) {
|
||||
if (!path) return '未知文件';
|
||||
// 移除URL前缀
|
||||
let cleanPath = path;
|
||||
if (cleanPath.includes('http://') || cleanPath.includes('https://')) {
|
||||
const urlObj = new URL(cleanPath);
|
||||
cleanPath = urlObj.pathname;
|
||||
}
|
||||
// 提取文件名
|
||||
const parts = cleanPath.split('/');
|
||||
return parts[parts.length - 1] || '未知文件';
|
||||
},
|
||||
|
||||
// 表单提交前确保file字段已正确设置
|
||||
ensureFileField() {
|
||||
this.updateFilePaths()
|
||||
return this.chargeCompanyForm.file
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1013,4 +1331,28 @@ export default {
|
||||
color: #409EFF;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
/* 文件预览样式 */
|
||||
.preview-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.preview-iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.fullscreen-btn {
|
||||
background: #409EFF;
|
||||
color: white;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.fullscreen-btn:hover {
|
||||
background: #66b1ff;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
|
||||
386
src/views/repair/tickets/RepairTicketManagement.vue
Normal file
386
src/views/repair/tickets/RepairTicketManagement.vue
Normal file
@ -0,0 +1,386 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="head-container">
|
||||
<div class="filter-container">
|
||||
<el-input v-model="queryParams.ticketNo" placeholder="工单编号" clearable style="width: 200px" />
|
||||
<el-input v-model="queryParams.carNo" placeholder="车牌号" clearable style="width: 180px" />
|
||||
<el-input v-model="queryParams.userName" placeholder="客户名称" clearable style="width: 180px" />
|
||||
<el-select v-model="queryParams.repairType" placeholder="维修类别" clearable style="width: 120px">
|
||||
<el-option v-for="item in repairTypeList" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
value-format="yyyy-MM-dd"
|
||||
style="width: 250px"
|
||||
/>
|
||||
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
|
||||
<el-button
|
||||
:loading="exportLoading"
|
||||
type="primary"
|
||||
icon="el-icon-download"
|
||||
@click="handleExport"
|
||||
>导出</el-button>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="table-container">
|
||||
<el-table v-loading="loading" :data="expandedTicketList" :stripe="true" :show-overflow-tooltip="true" :row-key="row => row._rowKey" :span-method="mergeCells">
|
||||
<!-- 合并单元格的表格 -->
|
||||
<el-table-column label="序号" align="center" prop="_index">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row._isFirstItem">{{ scope.row._index + 1 }}</span>
|
||||
<span v-else></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="订单编号" align="center" prop="ticketNo" width="200"/>
|
||||
<el-table-column label="维修类别" align="center" prop="repairType" width="100">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :type="DICT_TYPE.REPAIR_TYPE" :value="scope.row.repairType"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="客户信息" align="center">
|
||||
<el-table-column label="客户名称" align="center" prop="userName" width="100"/>
|
||||
<el-table-column label="车牌号" align="center" prop="carNo" width="100"/>
|
||||
<el-table-column label="车系" align="center" prop="carBrandName" width="100"/>
|
||||
<el-table-column label="手机号" align="center" prop="userMobile" width="110"/>
|
||||
</el-table-column>
|
||||
<el-table-column label="经办人姓名" align="center" prop="handleName" width="180"/>
|
||||
<el-table-column label="经办人电话" align="center" prop="handleMobile" width="180"/>
|
||||
<!-- <el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template slot-scope="scope">
|
||||
{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
<el-table-column label="合计金额" align="center" prop="totalPrice" width="80"/>
|
||||
<el-table-column label="参考成本" align="center" prop="cost" width="80"/>
|
||||
<el-table-column label="参考毛利" align="center" prop="profit" width="80"/>
|
||||
<el-table-column label="服务顾问" align="center" prop="adviserName" width="100"/>
|
||||
<!-- 项目详情信息 - 不合并 -->
|
||||
<el-table-column label="项目名称" align="center" width="180" prop="itemName"/>
|
||||
<el-table-column label="数量" align="center" width="180" prop="itemCount"/>
|
||||
<el-table-column label="项目金额" align="center" width="100" prop="itemMoney"/>
|
||||
<el-table-column label="毛利" align="center" width="100" prop="itemProfit"/>
|
||||
<el-table-column label="毛利率" align="center" width="100" prop="itemProfitRate"/>
|
||||
<el-table-column label="类别" align="center" width="100" prop="itemType">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.itemType == '01' ? '公时' : '配件' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="班组" align="center" width="100" prop="workerType">
|
||||
<template slot-scope="scope">
|
||||
<DictTag :type="'repair_work_type'" :value="scope.row.workerType"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="维修员工" align="center" width="100" prop="repairNames"/>
|
||||
<el-table-column label="销售人员" align="center" width="100" prop="saleName"/>
|
||||
<el-table-column label="备注" align="center" prop="remark" width="180"/>
|
||||
<!-- <el-table-column label="所属门店" align="center" prop="corpId" width="180"/> -->
|
||||
<el-table-column label="收款账号" align="center" prop="receivablesAccount" width="180"/>
|
||||
<el-table-column label="确认收款状态" prop="payConfirm" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.payConfirm == '1'" type="success">已确认</el-tag>
|
||||
<el-tag v-else type="danger">未确认</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="确认收款备注" v-if="activeTab === 'tp'" prop="payConfirmRemark" width="100"/>
|
||||
<el-table-column label="操作" fixed="right" align="center" width="100">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row._isFirstItem">
|
||||
<el-button size="mini" type="text" icon="el-icon-printer">下载打印</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<div class="pagination-container">
|
||||
<Pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
:page.sync="queryParams.pageNum"
|
||||
:limit.sync="queryParams.pageSize"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getTicketsPage, exportMerged } from '@/api/repair/tickets/Tickets'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import { DICT_TYPE } from '@/utils/dict'
|
||||
import DictTag from '@/components/DictTag'
|
||||
|
||||
export default {
|
||||
name: 'RepairTicketManagement',
|
||||
components: {
|
||||
Pagination,
|
||||
DictTag
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 原始工单列表
|
||||
ticketList: [],
|
||||
// 展开后的工单列表(支持合并单元格)
|
||||
expandedTicketList: [],
|
||||
// 合并单元格规则
|
||||
mergeRules: [],
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 加载状态
|
||||
loading: false,
|
||||
// 导出加载状态
|
||||
exportLoading: false,
|
||||
// 当前激活的标签页
|
||||
activeTab: 'tu',
|
||||
// 日期范围
|
||||
dateRange: [],
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
ticketNo: '',
|
||||
carNo: '',
|
||||
userName: '',
|
||||
repairType: '',
|
||||
startTime: '',
|
||||
endTime: ''
|
||||
},
|
||||
// 维修类别列表
|
||||
repairTypeList: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
this.loadDictData()
|
||||
},
|
||||
methods: {
|
||||
// 获取工单列表
|
||||
async getList() {
|
||||
this.loading = true
|
||||
try {
|
||||
// 设置日期范围
|
||||
if (this.dateRange && this.dateRange.length > 0) {
|
||||
this.queryParams.startTime = this.dateRange[0]
|
||||
this.queryParams.endTime = this.dateRange[1]
|
||||
} else {
|
||||
this.queryParams.startTime = ''
|
||||
this.queryParams.endTime = ''
|
||||
}
|
||||
|
||||
const res = await getTicketsPage({
|
||||
...this.queryParams
|
||||
})
|
||||
this.ticketList = res.data.records
|
||||
this.total = res.data.total
|
||||
|
||||
// 处理数据为支持合并单元格的格式
|
||||
this.processDataForMergeCells()
|
||||
} catch (error) {
|
||||
console.error('获取工单列表失败:', error)
|
||||
this.$modal.msgError('获取工单列表失败')
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
// 处理数据为支持合并单元格的格式
|
||||
processDataForMergeCells() {
|
||||
const expandedList = []
|
||||
const mergeRules = []
|
||||
let rowIndex = 0
|
||||
|
||||
this.ticketList.forEach((ticket, ticketIndex) => {
|
||||
// 确保 itemList 是数组
|
||||
const items = Array.isArray(ticket.itemList) && ticket.itemList.length > 0 ? ticket.itemList : [{
|
||||
itemName: '-',
|
||||
itemMoney: '-',
|
||||
repairNames: '-',
|
||||
saleName: '-'
|
||||
}]
|
||||
const itemCount = items.length
|
||||
|
||||
// 记录合并规则
|
||||
mergeRules.push({
|
||||
startRow: rowIndex,
|
||||
endRow: rowIndex + itemCount - 1,
|
||||
ticketIndex: ticketIndex,
|
||||
index: ticketIndex + 1 // 存储原始工单序号
|
||||
})
|
||||
|
||||
// 展开数据
|
||||
items.forEach((item, itemIndex) => {
|
||||
expandedList.push({
|
||||
// 原始工单数据
|
||||
...ticket,
|
||||
// 项目数据
|
||||
...item,
|
||||
// 生成唯一行标识
|
||||
_rowKey: `${ticket.id || rowIndex}-${itemIndex}`,
|
||||
// 用于标识是否为第一个项目
|
||||
_isFirstItem: itemIndex === 0,
|
||||
// 存储原始工单序号
|
||||
_index: ticketIndex
|
||||
})
|
||||
rowIndex++
|
||||
})
|
||||
})
|
||||
|
||||
this.expandedTicketList = expandedList
|
||||
this.mergeRules = mergeRules
|
||||
},
|
||||
|
||||
// 合并单元格方法
|
||||
mergeCells({ row, column, rowIndex, columnIndex }) {
|
||||
// 获取当前列的属性名
|
||||
const prop = column.property;
|
||||
|
||||
// 需要合并的列(根据属性名判断更可靠)
|
||||
const mergeProps = ['_index', 'ticketNo', 'repairType', 'userName', 'carNo',
|
||||
'carBrandName', 'userMobile', 'handleName', 'handleMobile',
|
||||
'createTime', 'totalPrice', 'cost', 'profit', 'adviserName',
|
||||
'remark', 'corpId', 'receivablesAccount', 'payConfirm', 'payConfirmRemark'];
|
||||
|
||||
// 项目相关列不合并
|
||||
const itemProps = ['itemName', 'itemMoney', 'repairNames', 'saleName'];
|
||||
if (itemProps.includes(prop)) {
|
||||
return { rowspan: 1, colspan: 1 };
|
||||
}
|
||||
|
||||
// 找到当前行对应的合并规则
|
||||
const rule = this.mergeRules.find(
|
||||
r => rowIndex >= r.startRow && rowIndex <= r.endRow
|
||||
);
|
||||
|
||||
// 如果是需要合并的列且找到了规则
|
||||
if (rule && (mergeProps.includes(prop) || columnIndex === 0)) {
|
||||
if (rowIndex === rule.startRow) {
|
||||
// 开始行,设置rowspan
|
||||
return {
|
||||
rowspan: rule.endRow - rule.startRow + 1,
|
||||
colspan: 1
|
||||
};
|
||||
} else {
|
||||
// 非开始行,不显示
|
||||
return {
|
||||
rowspan: 0,
|
||||
colspan: 0
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 加载字典数据
|
||||
loadDictData() {
|
||||
this.repairTypeList = this.getDictDatas(DICT_TYPE.REPAIR_TYPE)
|
||||
},
|
||||
|
||||
// 处理标签页切换
|
||||
handleTabChange(tab) {
|
||||
this.activeTab = tab.name
|
||||
this.queryParams.pageNum = 1
|
||||
this.getList()
|
||||
},
|
||||
|
||||
// 搜索
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1
|
||||
this.getList()
|
||||
},
|
||||
|
||||
// 重置搜索条件
|
||||
resetQuery() {
|
||||
this.dateRange = []
|
||||
this.queryParams = {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
ticketNo: '',
|
||||
carNo: '',
|
||||
userName: '',
|
||||
repairType: '',
|
||||
startTime: '',
|
||||
endTime: ''
|
||||
}
|
||||
this.getList()
|
||||
},
|
||||
|
||||
// 刷新列表
|
||||
handleRefresh() {
|
||||
this.getList()
|
||||
},
|
||||
|
||||
// 导出功能
|
||||
handleExport() {
|
||||
this.$modal.confirm('是否确认导出当前查询条件所有数据项?').then(() => {
|
||||
this.exportLoading = true
|
||||
// 处理查询参数
|
||||
const exportParams = {...this.queryParams}
|
||||
exportParams.pageNum = undefined
|
||||
exportParams.pageSize = undefined
|
||||
if (this.dateRange && this.dateRange.length > 0) {
|
||||
exportParams.startTime = this.dateRange[0]
|
||||
exportParams.endTime = this.dateRange[1]
|
||||
} else {
|
||||
exportParams.startTime = ''
|
||||
exportParams.endTime = ''
|
||||
}
|
||||
return exportMerged(exportParams)
|
||||
}).then(response => {
|
||||
this.$download.excel(response, '维修工单合并数据.xlsx')
|
||||
}).finally(() => {
|
||||
this.exportLoading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.app-container {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.head-container {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.filter-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 15px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.tab-container {
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
// 响应式设计
|
||||
@media (max-width: 768px) {
|
||||
.filter-container {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.filter-container > * {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue
Block a user