diff --git a/src/views/repair/tickets/Components/TicketTable.vue b/src/views/repair/tickets/Components/TicketTable.vue
index a67e84c..c4fe83d 100644
--- a/src/views/repair/tickets/Components/TicketTable.vue
+++ b/src/views/repair/tickets/Components/TicketTable.vue
@@ -98,6 +98,7 @@
+
已确认
@@ -116,15 +117,23 @@
>查看
收款
+ 反结算
+
+ 销账
+
结算
结算审核
@@ -235,6 +244,24 @@
+
+
+
+
+
+
+
+
+
+
@@ -244,10 +271,10 @@
-
@@ -459,16 +545,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 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,
@@ -490,48 +580,66 @@ export default {
data() {
return {
loading: false,
- showLoading: false, // 添加加载状态
+ showLoading: false,
formData: {
id: null,
ticketsStatus: null,
billingRemark: null,
payType: null,
isPaid: '1',
- remark: ''
+ remark: '',
+ receivablesAccount: null
},
+ accountList: [],
+ accountLoading: false,
settlementFormData: {
actualMoney: 0,
discountType: this.defaultDiscountType,
discount: 0,
- payType: 'xj', // 默认现结
+ settlementType: 'xj',
chargeCompanyId: null
},
- chargeCompanyList: [], // 挂账单位列表
- searchLoading: false, // 搜索加载状态
- // 新增挂账单位表单
+ chargeCompanyList: [],
+ searchLoading: false,
chargeCompanyForm: {
companyName: '',
contactPerson: '',
contactPhone: '',
address: '',
- status: false, // 默认为禁用状态
+ 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' }],
contactPhone: [{ required: true, message: '联系电话不能为空', trigger: 'blur' }]
},
- chargeCompanyDialogVisible: false, // 新增挂账单位弹窗显示状态
+ chargeCompanyDialogVisible: false,
formRules: {
payType: [{required: true, message: '支付方式不能为空', trigger: 'blur'}],
isPaid: [{required: true, message: '请选择是否支付', trigger: 'blur'}],
+ receivablesAccount: [{required: true, message: '请选择收款账号', trigger: 'blur'}],
remark: [{required: false, message: '收款备注不能为空', trigger: 'blur'}]
},
settlementFormRules: {
discountType: [{required: true, message: '优惠类型不能为空', trigger: 'blur'}],
- discount: [{required: true, message: '优惠不能为空', trigger: 'blur'}]
+ discount: [{required: true, message: '优惠不能为空', trigger: 'blur'}],
+ settlementType: [{required: true, message: '结算方式不能为空', trigger: 'blur'}]
},
dialogVisible: false,
dialogVisibleSettlement: false,
@@ -547,7 +655,6 @@ export default {
value: '2'
}
],
- // 确认收款相关数据
confirmPaymentVisible: false,
confirmPaymentLoading: false,
confirmPaymentSubmitLoading: false,
@@ -561,14 +668,14 @@ export default {
paidTime: '',
payTypeLabel: '',
payConfirm: '',
- payConfirmRemark: ''
+ payConfirmRemark: '',
+ payTime: ''
},
confirmPaymentRules: {
payConfirm: [
{ required: true, message: '请选择确认状态', trigger: 'change' }
]
},
- // 确认状态选项
confirmStatusOptions: [
{
value: '1',
@@ -581,8 +688,29 @@ 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);
+ },
+ isPdfType() {
+ if (!this.selectFile.fileName) return false;
+ return this.selectFile.fileName.toLowerCase().endsWith('.pdf');
+ },
+ isTxtType() {
+ if (!this.selectFile.fileName) return false;
+ return this.selectFile.fileName.toLowerCase().endsWith('.txt');
+ }
+ },
watch: {
- // 监听是否支付状态变化
'formData.isPaid': {
handler(newVal) {
this.updateFormRules(newVal);
@@ -593,14 +721,10 @@ export default {
methods: {
handleShow(row) {
- // 显示加载动画
this.showLoading = true;
- // 调用子组件的open方法
this.$refs.ticketsShow.open(row).then(() => {
- // 加载完成后隐藏加载动画
this.showLoading = false;
}).catch(() => {
- // 出错时也隐藏加载动画
this.showLoading = false;
});
},
@@ -624,9 +748,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 {
+ }
+ },
async handlePrint(row) {
window.open(process.env.VUE_APP_BASE_API + '/admin-api/repair/tickets/print/' + row.id)
},
@@ -640,21 +781,17 @@ export default {
}
},
jisuan() {
- // 根据优惠类型计算
if (this.settlementFormData.discountType === '1') {
this.settlementFormData.actualMoney = this.settlementFormData.money - this.settlementFormData.discount
} else if (this.settlementFormData.discountType === '2') {
- // 保留小数点后两位
this.settlementFormData.actualMoney = this.settlementFormData.money * (1 - this.settlementFormData.discount / 100)
this.settlementFormData.actualMoney = parseFloat(this.settlementFormData.actualMoney).toFixed(2)
}
console.log(this.settlementFormData)
},
- // 处理支付方式变化
async handlePayTypeChange(value) {
if (value === 'gz') {
- // 获取启用状态的挂账单位(systemCode为repair)
try {
const res = await getChargeCompanyList({
status: 1,
@@ -668,7 +805,6 @@ export default {
}
},
- // 搜索挂账单位
async searchChargeCompany(query) {
if (query !== '') {
this.searchLoading = true;
@@ -686,7 +822,6 @@ export default {
this.searchLoading = false;
}
} else {
- // 如果搜索关键词为空,重新加载所有启用的挂账单位
try {
const res = await getChargeCompanyList({
status: 1,
@@ -700,7 +835,6 @@ export default {
}
},
- //收款
handlePaid(row) {
this.formData = {
id: null,
@@ -708,16 +842,33 @@ export default {
billingRemark: null,
payType: null,
isPaid: '1',
- remark: ''
+ remark: '',
+ receivablesAccount: null
}
this.formData['id'] = row.id
this.formData['ticketsStatus'] = '02'
this.dialogVisible = true
this.checkIsHangAccount(row)
this.getSettlement(row)
+ this.loadAccountList()
+ },
+
+ async loadAccountList() {
+ this.accountLoading = true;
+ try {
+ const res = await getAccounts({
+ status: 1,
+ systemCode: 'repair'
+ });
+ this.accountList = res.data.records || [];
+ } catch (err) {
+ console.error('获取收款账号列表失败:', err);
+ this.$modal.msgError('获取收款账号列表失败');
+ } finally {
+ this.accountLoading = false;
+ }
},
- //结算
handleSettlement(row, type) {
this.settlementType = type
if (type == 'js') {
@@ -725,8 +876,8 @@ export default {
ticketId: row.id,
money: row.totalPrice,
actualMoney: row.totalPrice,
- discountType: this.defaultDiscountType, // 加上这一行
- discount: 0 // 加上这一行
+ discountType: this.defaultDiscountType,
+ discount: 0
}
} else if (type === 'jssh') {
this.settlementFormData = row.settlement
@@ -774,8 +925,8 @@ export default {
try {
await this.$refs['formRefSettlement'].validate()
-
if (this.settlementType === 'jssh') {
+ console.log('执行借宿那审核');
await settlementReview(this.settlementFormData)
} else {
await setTicketsSettlement(this.settlementFormData)
@@ -783,7 +934,8 @@ export default {
this.$modal.msgSuccess("提交成功")
this.dialogVisibleSettlement = false
this.$emit("setVoid")
- } catch {
+ } catch (error) {
+ console.error('Error in settlement process:', error);
}
},
getDictDataByCode(code) {
@@ -813,7 +965,6 @@ export default {
}
},
- // 确认收款相关方法
handleConfirmPayment(row) {
this.resetConfirmPaymentForm()
this.confirmPaymentForm = {
@@ -822,17 +973,16 @@ export default {
userName: row.userName,
carNo: row.carNo,
totalPrice: row.totalPrice,
- paidAmount: row.paidAmount || row.totalPrice, // 实收金额,默认为应收金额
- paidTime: row.paidTime || '', // 收款时间
- payTypeLabel: this.getPayTypeLabel(row.payType), // 收款方式标签
- payConfirm: row.payConfirm || '', // 确认状态
- payConfirmRemark: row.payConfirmRemark || '', // 确认备注
- payTime: row.payTime || '', // 付款时间
+ paidAmount: row.paidAmount || row.totalPrice,
+ paidTime: row.paidTime || '',
+ payTypeLabel: this.getPayTypeLabel(row.payType),
+ payConfirm: row.payConfirm || '',
+ payConfirmRemark: row.payConfirmRemark || '',
+ payTime: row.payTime || '',
}
this.confirmPaymentVisible = true
},
- // 获取支付方式标签
getPayTypeLabel(payType) {
if (!payType) return ''
const payTypes = this.getDictDataByCode(this.DICT_TYPE.REPAIR_PAY_TYPE)
@@ -840,55 +990,47 @@ export default {
return payTypeItem ? payTypeItem.label : ''
},
- // 提交确认收款
async submitConfirmPayment() {
this.$refs['confirmPaymentForm'].validate(async valid => {
if (valid) {
this.confirmPaymentSubmitLoading = true
- // 构造提交数据
const data = {
id: this.confirmPaymentForm.id,
payConfirm: this.confirmPaymentForm.payConfirm,
payConfirmRemark: this.confirmPaymentForm.payConfirmRemark
}
- // 注意:这里需要后端提供对应的API接口
- // 由于没有看到具体的API,暂时使用模拟方式
await payConfirm(data)
this.$modal.msgSuccess("确认收款成功")
this.confirmPaymentSubmitLoading = false
this.confirmPaymentVisible = false
- this.$emit("setVoid") // 刷新列表
+ this.$emit("setVoid")
}
})
},
- // 取消确认收款
cancelConfirmPayment() {
this.confirmPaymentVisible = false
this.$refs['confirmPaymentForm'].resetFields()
},
- // 重置确认收款表单
resetConfirmPaymentForm() {
this.confirmPaymentSubmitLoading = false
this.$refs['confirmPaymentForm'] && this.$refs['confirmPaymentForm'].resetFields()
},
- // 根据是否支付状态更新表单验证规则
updateFormRules(isPaid) {
if (isPaid === '0') {
- // 未支付:收款方式可选,收款备注必填
this.formRules.payType = [{required: false, message: '支付方式不能为空', trigger: 'blur'}];
+ this.formRules.receivablesAccount = [{required: false, message: '请选择收款账号', trigger: 'blur'}];
this.formRules.remark = [{required: true, message: '收款备注不能为空', trigger: 'blur'}];
} else {
- // 已支付:收款方式必填,收款备注可选
this.formRules.payType = [{required: true, message: '支付方式不能为空', trigger: 'blur'}];
+ this.formRules.receivablesAccount = [{required: true, message: '请选择收款账号', trigger: 'blur'}];
this.formRules.remark = [{required: false, message: '收款备注不能为空', trigger: 'blur'}];
}
- // 重新设置表单验证规则
this.$nextTick(() => {
if (this.$refs.formRef) {
this.$refs.formRef.clearValidate();
@@ -896,32 +1038,33 @@ export default {
});
},
- // 处理新增挂账单位按钮点击
handleAddChargeCompany() {
- // 重置表单
this.chargeCompanyForm = {
companyName: '',
contactPerson: '',
contactPhone: '',
address: '',
- status: false, // 默认为禁用状态
+ status: false,
systemCode: 'repair',
- remark: ''
+ remark: '',
+ file: ''
};
+ this.uploadFileList = [];
this.chargeCompanyDialogVisible = true;
},
- // 提交新增挂账单位
async submitChargeCompany() {
this.$refs.chargeCompanyFormRef.validate(async (valid) => {
if (valid) {
try {
+ const fileField = this.ensureFileField();
+ console.log('提交时的file字段值:', fileField);
+
await addChargeCompany(this.chargeCompanyForm);
this.$modal.msgSuccess('挂账单位申请成功,请等待审核');
this.chargeCompanyDialogVisible = false;
- // 如果当前是挂账方式,则重新加载挂账单位列表
- if (this.settlementFormData.payType === 'gz') {
- await this.searchChargeCompany(''); // 重新加载列表
+ if (this.settlementFormData.settlementType === 'gz') {
+ await this.searchChargeCompany('');
}
} catch (err) {
console.error('新增挂账单位失败:', err);
@@ -931,10 +1074,157 @@ export default {
});
},
- // 取消新增挂账单位
cancelChargeCompany() {
this.chargeCompanyDialogVisible = false;
this.$refs.chargeCompanyFormRef && this.$refs.chargeCompanyFormRef.resetFields();
+ this.uploadFileList = [];
+ },
+
+ beforeUpload(file) {
+ const isLt20M = file.size / 1024 / 1024 < 20
+ 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
+ this.uploadFileList[index].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)
+ })
+ }
+
+ 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 => {
+ const filePath = file.url || file.name || ''
+
+ 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 || '';
+ if (filePath.startsWith('http://') || filePath.startsWith('https://')) {
+ return filePath;
+ }
+ 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 || '')
+ };
+
+ 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 '未知文件';
+ 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] || '未知文件';
+ },
+
+ ensureFileField() {
+ this.updateFilePaths()
+ return this.chargeCompanyForm.file
}
}
}
@@ -966,4 +1256,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;
+ }
+
\ No newline at end of file