This commit is contained in:
xuyuncong 2025-11-13 16:07:47 +08:00 committed by sunhaoyuan
parent f14bf7149b
commit bb28d0922c
10 changed files with 556 additions and 154 deletions

View File

@ -79,3 +79,14 @@ export function exportData(params){
responseType: 'blob'
})
}
// 根据ID修改发票信息
export function updateBilled(data) {
return request({
url: '/repair/order-info/updateBilled',
method: 'post',
data: data
})
}

View File

@ -1,4 +1,4 @@
import {v4 as uuidv4} from 'uuid'
import { v4 as uuidv4 } from 'uuid'
/**
* 生成UUID
@ -33,5 +33,13 @@ export function createHashCodeByStr(str) {
export function createUniqueCodeByHead(head = '') {
const min = 100; // 最小值
const max = 999; // 最大值
return head.toString() + Date.now().toString() + Math.floor(Math.random() * (max - min + 1)) + min;
// 获取当前日期并格式化为年月日字符串例如20231225
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0'); // 月份从0开始需要+1
const day = String(now.getDate()).padStart(2, '0');
const dateStr = `${year}${month}${day}`;
return head.toString() + dateStr + Math.floor(Math.random() * (max - min + 1)) + min;
}

View File

@ -126,6 +126,22 @@
</div>
</el-card>
</div>
<!-- 工单列表弹窗 -->
<el-dialog
:title="dialogTitle"
:visible.sync="listDialogVisible"
width="80%"
v-if="listDialogVisible"
>
<TicketManagerItem
:is-type="dialogQueryParams.selectType"
:user-role="userRole"
:external-query-params="dialogQueryParams"
:show-view-only="true"
@close="listDialogVisible = false"
/>
</el-dialog>
</div>
</template>
@ -133,10 +149,14 @@
import request from "@/utils/request";
import { formatCurrency, getDictByCode, getDateRange } from "@/utils/utils";
// import { checkPermi } from "@/utils/permission";
import TicketManagerItem from "@/views/repair/tickets/Components/TicketManagerItem.vue";
export default {
name: "DetailPagePC",
dicts: ["repair_type"],
components: {
TicketManagerItem
},
data() {
return {
currentTab: "0",
@ -156,12 +176,18 @@ export default {
},
dictData: {},
otherInfo: {},
//
listDialogVisible: false,
dialogTitle: "",
dialogQueryParams: {},
userRole: "all" //
};
},
async mounted() {
this.queryParams.dateRange = getDateRange("day");
// this.loadFinanceVisibility();
this.loadData();
this.getDict();
},
methods: {
// checkPermi,
@ -193,22 +219,53 @@ export default {
},
goList(selectType, repairType) {
console.log(selectType, repairType, 6666);
//
this.dialogTitle = this.dictData[repairType] ?
`${this.dictData[repairType]}工单列表` :
`${this.getSelectTypeName(selectType)}工单列表`;
//
this.$router.push({
path: "/repair/tickets/ticket-manager",
query: {
selectType: selectType,
repairType: repairType,
},
});
//
this.dialogQueryParams = {
selectType: selectType,
repairType: repairType,
searchTimeArray: this.queryParams.dateRange
};
//
this.listDialogVisible = true;
},
goListByPayStatus(payStatus) {
//
this.$router.push({
path: "/repair/tickets/ticket-manager",
query: { payStatus: payStatus },
});
//
this.dialogTitle = this.getPayStatusName(payStatus) + "工单列表";
//
this.dialogQueryParams = {
payStatus: payStatus,
searchTimeArray: this.queryParams.dateRange
};
//
this.listDialogVisible = true;
},
getSelectTypeName(selectType) {
const typeMap = {
'jinchang': '进厂',
'weixiuzhong': '维修中',
'yijungong': '已竣工',
'yijiaoche': '已交车',
'weijiesuan': '未结算',
'zaichang': '在厂'
};
return typeMap[selectType] || '工单';
},
getPayStatusName(payStatus) {
const statusMap = {
'receivable': '应收款',
'receivedAmount': '已收款',
'pendingAmount': '待收款'
};
return statusMap[payStatus] || '工单';
},
formatCurrency(amount) {
return formatCurrency(amount);
@ -284,4 +341,4 @@ export default {
font-size: 14px;
color: #7f8fa4;
}
</style>
</style>

View File

@ -94,6 +94,7 @@
<span>{{ scope.row._index + 1 }}</span>
</template>
</el-table-column>
<el-table-column label="工单号" align="center" prop="ticketNo" width="200"/>
<el-table-column label="单号" align="center" prop="soNo" width="200"/>
<el-table-column label="车牌号" align="center" prop="licenseNumber" width="200">
<template slot-scope="scope">

View File

@ -59,6 +59,22 @@
/>
<el-dialog title="单据处理" :visible.sync="dialogVisible" width="80%" v-dialogDrag append-to-body>
<!-- 车辆信息显示区域 -->
<el-descriptions class="margin-top" title="车辆信息" :column="4" border style="margin-bottom: 20px;">
<el-descriptions-item label="车牌号">
{{ formData.licenseNumber || '--' }}
</el-descriptions-item>
<el-descriptions-item label="客户姓名">
{{ formData.userName || '--' }}
</el-descriptions-item>
<el-descriptions-item label="联系电话">
{{ formData.userMobile || '--' }}
</el-descriptions-item>
<el-descriptions-item label="车架号">
{{ formData.vin || '--' }}
</el-descriptions-item>
</el-descriptions>
<el-form :inline="true">
<el-form-item label="名称" prop="query">
<el-input v-model="query"/>

View File

@ -27,6 +27,10 @@ export default {
props:{
value:{
type: Object
},
ticketType: {
type: String,
default: null
}
},
data() {
@ -54,13 +58,17 @@ export default {
methods: {
//
async listTicket(){
// ticketType
if (this.ticketType) {
this.queryParams.ticketType = this.ticketType
}
const res = await getTicketsPage(this.queryParams)
this.ticketList = res.data.records
this.total = res.data.total
},
rowClick(row){
this.ticketSelected = row.id
this.$emit("selected", row.id)
this.$emit("selected", row)
this.$refs.ticketSelect.blur()
},
async searchByNo(val){

View File

@ -117,12 +117,13 @@
size="mini"
@click="handleExport"
:loading="exportLoading"
v-show="!showViewOnly"
>导出</el-button
>
</el-col>
<right-toolbar :showSearch.sync="showSearch"></right-toolbar>
</el-row>
<div class="census" v-hasPermi="['repair:tick:profit']">
<div class="census" v-hasPermi="['repair:tick:profit']" v-show="!showViewOnly">
<span class="credited"
>产值{{ statisticsInfo?.totalLaborPartsMoney || 0 }}</span
>
@ -253,7 +254,7 @@
fixed="right"
align="center"
width="200"
v-if="userRole !== 'repair_warehouse'"
v-if="userRole !== 'repair_warehouse' && !showViewOnly"
>
<template slot-scope="scope">
<!-- 都有 -->
@ -310,6 +311,15 @@
icon="el-icon-refresh"
>{{ userRole === "general_inspection" ? "内返派工" : "修改派工" }}
</el-button>
<!-- 开票按钮 -->
<el-button
size="mini"
type="text"
icon="el-icon-tickets"
@click="scope.row.ifBilled == '1' ? showBilled(scope.row) : unbilled(scope.row)"
>
{{ scope.row.ifBilled == '1' ? '已开票' : '未开票' }}
</el-button>
<el-dropdown
v-if="scope.row.isFinish !== '1'"
@command="
@ -425,7 +435,7 @@
fixed="right"
align="center"
width="200"
v-if="userRole === 'repair_warehouse'"
v-if="userRole === 'repair_warehouse' && !showViewOnly"
>
<template slot-scope="scope">
<el-button
@ -447,6 +457,23 @@
</el-button>
</template>
</el-table-column>
<el-table-column
label="操作"
fixed="right"
align="center"
width="100"
v-if="showViewOnly"
>
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-view"
@click="handleShow(scope.row)"
>查看
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination
@ -461,9 +488,10 @@
:user-role="userRole"
ref="updateRepair"
@success="listTickets"
v-if="!showViewOnly"
/>
<TWOperate ref="twOperate" @success="listTickets" />
<UpdateRecord ref="updateRecord" @success="listTickets" />
<TWOperate ref="twOperate" @success="listTickets" v-if="!showViewOnly" />
<UpdateRecord ref="updateRecord" @success="listTickets" v-if="!showViewOnly" />
<el-dialog
title="退料申请"
@ -471,6 +499,7 @@
width="60%"
v-dialogDrag
append-to-body
v-if="!showViewOnly"
>
<el-table
v-loading="backLoading"
@ -527,8 +556,8 @@
</div>
</el-dialog>
<RecordSetting ref="recordSet" />
<EditTickets ref="editTickets" @success="listTickets" />
<RecordSetting ref="recordSet" v-if="!showViewOnly" />
<EditTickets ref="editTickets" @success="listTickets" v-if="!showViewOnly" />
<el-dialog
title="诊断维修单和车辆维修前照片"
@ -536,6 +565,7 @@
width="60%"
v-dialogDrag
append-to-body
v-if="!showViewOnly"
>
<el-form v-model="beginData" :inline="true" label-width="15rem">
<el-row :gutter="1">
@ -552,7 +582,54 @@
</div>
</el-dialog>
<TicketProgress ref="ticketProgress" />
<TicketProgress ref="ticketProgress" v-if="!showViewOnly" />
<!-- 未开票对话框 -->
<el-dialog title="未开票" :visible.sync="unbilledOpen" width="600px" append-to-body>
<!-- 点击显示弹框 记录开票信息二维码和备注 -->
<el-form ref="unbilledForm" :model="unbilledForm" label-width="120px">
<el-form-item label="图片" prop="billedQrcode">
<image-upload v-model="unbilledForm.billedQrcode" />
</el-form-item>
<el-form-item label="备注" prop="billedRemark">
<el-input v-model="unbilledForm.billedRemark" type="textarea" placeholder="请输入备注"
:autosize="{ minRows: 2, maxRows: 4 }" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="unbilledSubmit"> </el-button>
<el-button @click="unbilledCancel"> </el-button>
</div>
</el-dialog>
<!-- 已开票对话框仅展示-->
<el-dialog title="已开票" :visible.sync="billedOpen" width="600px" append-to-body custom-class="billed-dialog-custom">
<el-form ref="billedFormRef" :model="billedForm" label-width="120px">
<!-- 操作人只读 -->
<el-form-item label="操作人">
<el-input v-model="billedForm.billedUsername" :disabled="true" />
</el-form-item>
<!-- 开票二维码展示 + 预览 -->
<el-form-item label="开票二维码">
<div v-if="billedForm.billedQrcode" class="image-list">
<div v-for="(url, index) in billedForm.billedQrcode.split(',')" :key="index" class="image-item">
<el-image :src="imageUrl + url"
:preview-src-list="billedForm.billedQrcode.split(',').map(u => imageUrl + u)" fit="contain"
style="width:160px;height:160px;border:1px solid #eee;margin-right:10px;margin-bottom:10px" />
</div>
</div>
<span v-else class="text-gray-400">暂无二维码</span>
</el-form-item>
<!-- 发票备注只读 -->
<el-form-item label="发票备注">
<el-input v-model="billedForm.billedRemark" type="textarea" :autosize="{ minRows: 2, maxRows: 4 }"
:disabled="true" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="billedOpen = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
@ -565,6 +642,8 @@ import { getPageType,
exportData,
getStatistics,
} from "@/api/repair/tickets/Tickets";
import { updateBilled } from "@/api/repair/orderinfo/index";
import { getInfo as getUserInfo } from "@/api/login";
import TicketsShow from "@/views/repair/tickets/Components/TicketsShow.vue";
import UpdateRepair from "@/views/repair/tickets/form/UpdateRepair.vue";
import TWOperate from "@/views/repair/tickets/form/TWOperate.vue";
@ -601,6 +680,16 @@ export default {
isType: {
type: String,
},
//
externalQueryParams: {
type: Object,
default: () => ({})
},
//
showViewOnly: {
type: Boolean,
default: false
}
},
data() {
return {
@ -609,7 +698,9 @@ export default {
pageSize: 10,
ticketNo: null,
searchTimeArray: [],
selectType: this.isType,
ticketsStatus: this.isType,
selectType: 'all',
...this.externalQueryParams
},
showSearch: true,
loading: false,
@ -673,9 +764,39 @@ export default {
{'label':'在厂',
'value': 'zaichang'
}
]
],
//
imageUrl: process.env.VUE_APP_PREVIEW_URL,
billedForm: {
billedUsername: '', //
billedQrcode: '', // URL
billedRemark: '' //
},
unbilledForm: {
id: '',
ifBilled: '',
billedUserid: '',
billedUsername: '',
billedQrcode: '',
billedRemark: ''
},
unbilledOpen: false,
billedOpen: false,
loginUserInfo: {}
};
},
watch: {
externalQueryParams: {
handler(newVal) {
this.queryParams = {
...this.queryParams,
...newVal
};
this.listTickets();
},
deep: true
}
},
created(){
if (this.$route.query.payStatus) {
this.queryParams.payStatus = this.$route.query.payStatus;
@ -683,8 +804,8 @@ export default {
if (this.$route.query.repairType) {
this.queryParams.repairType = this.$route.query.repairType;
}
if (this.$route.query.selectType) {
this.queryParams.ticketsStatus = this.$route.query.selectType;
if (this.$route.query.ticketsStatus) {
this.queryParams.ticketsStatus = this.$route.query.ticketsStatus;
}
},
mounted() {
@ -719,9 +840,11 @@ export default {
try {
this.loading = true;
const res = await getPageType(this.queryParams);
const statisticsInfo = await getStatistics(this.queryParams);
this.statisticsInfo = statisticsInfo.data;
console.log("统计信息", this.statisticsInfo);
if (!this.showViewOnly) {
const statisticsInfo = await getStatistics(this.queryParams);
this.statisticsInfo = statisticsInfo.data;
console.log("统计信息", this.statisticsInfo);
}
if (res.data) {
this.list = res.data.records;
this.total = res.data.total;
@ -854,6 +977,12 @@ export default {
case "handleProgress":
this.handleProgress(row);
break;
case "billed":
this.showBilled(row);
break;
case "unbilled":
this.unbilled(row);
break;
default:
break;
}
@ -983,6 +1112,46 @@ export default {
handleProgress(row) {
this.$refs.ticketProgress.open(row.id);
},
//
showBilled(row) {
this.billedForm.billedUsername = row.billedUsername
this.billedForm.billedQrcode = row.billedQrcode
this.billedForm.billedRemark = row.billedRemark
this.billedOpen = true
},
//
unbilledSubmit() {
//
this.$refs.unbilledForm.validate((valid) => {
if (!valid) return;
this.unbilledForm.billedUserid = this.loginUserInfo.id
this.unbilledForm.billedUsername = this.loginUserInfo.nickname
updateBilled(this.unbilledForm).then(response => {
this.$message.success('保存成功');
this.unbilledOpen = false;
this.listTickets();
});
});
},
unbilled(row) {
this.unbilledForm.id = row.id
this.unbilledForm.billedQrcode = row.billedQrcode
this.unbilledForm.billedRemark = row.billedRemark
this.unbilledForm.ifBilled = '1'
this.unbilledOpen = true
this.getLoginUserInfo()
},
unbilledCancel() {
this.unbilledOpen = false;
},
getLoginUserInfo() {
getUserInfo().then(res => {
this.loginUserInfo = res.data.user
})
},
/** 导出按钮操作 */
handleExport() {
this.$modal
@ -1070,4 +1239,4 @@ export default {
.signedPay {
color: orange;
}
</style>
</style>

View File

@ -135,7 +135,7 @@
<!-- <el-button v-if="TicketType === 'tp'" size="mini" type="text" icon="el-icon-refresh-right"-->
<!-- >返结-->
<!-- </el-button>-->
<el-button v-if="TicketType == 'tu'" size="mini" type="text" icon="el-icon-delete"
<el-button v-if="TicketType == 'ts'" size="mini" type="text" icon="el-icon-delete"
@click="handleVoid(scope.row)" v-hasPermi="['repair:tk:void']">作废
</el-button>
<el-button size="mini" type="text" icon="el-icon-printer" @click="handlePrint(scope.row)">下载打印

View File

@ -267,12 +267,12 @@
<div class="button-container">
<PrintButton
ref="printButton"
print-title="工单详情"
print-title="打印结算单"
@click="handlePrint"
>
<template #printContent>
<div class="print-content">
<h1 style="text-align: center">工单详情</h1>
<h1 style="text-align: center">打印结算单</h1>
<h2>工单信息</h2>
<table
class="print-table"

View File

@ -1,7 +1,7 @@
<template>
<div>
<el-row :gutter="24">
<!-- <el-col :span="17" style="padding-right: 0">-->
<!-- <el-col :span="17" style="padding-right: 0">-->
<el-col :span="24" style="padding-right: 0">
<el-card class="top-left">
<el-descriptions class="margin-top" :column="3" :size="'mini'" border>
@ -10,7 +10,7 @@
新增客户信息
</el-button>
<el-button v-if="createTicketType" type="primary" size="small" @click="updateUserInfo(true)"
:disabled="!selectUser.id">
:disabled="!selectUser.id">
完善更多客户信息
</el-button>
</template>
@ -18,69 +18,60 @@
<template slot="label">
用户选择
</template>
<UserChoose v-model="selectUser" :in-list="userInData"/>
<UserChoose v-model="selectUser" :in-list="userInData" />
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
车辆选择
</template>
<CarChoose v-if="selectUser && selectUser.id" v-model="selectCar" :cus-name="selectUser.cusName" :customer-info="selectUser" :in-list="carInData"/>
<CarChoose v-if="selectUser && selectUser.id" v-model="selectCar" :cus-name="selectUser.cusName"
:customer-info="selectUser" :in-list="carInData" />
<span v-else>请先选择客户</span>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
手机
</template>
<el-input disabled v-model="selectUser.phoneNumber"/>
<el-input disabled v-model="selectUser.phoneNumber" />
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
车架号
</template>
<el-input disabled v-model="selectCar.vin"/>
<el-input disabled v-model="selectCar.vin" />
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
品牌车系
</template>
<el-input disabled v-model="selectCar.modelStr"/>
<el-input disabled v-model="selectCar.modelStr" />
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
保险到期
</template>
<el-date-picker disabled
v-model="selectCar.insuranceExpiryDate"
type="date">
<el-date-picker disabled v-model="selectCar.insuranceExpiryDate" type="date">
</el-date-picker>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
年检到期
</template>
<el-date-picker disabled
v-model="selectCar.nextInspectionDate"
type="date">
<el-date-picker disabled v-model="selectCar.nextInspectionDate" type="date">
</el-date-picker>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
进厂时间
</template>
<el-date-picker
v-model="formData.inTime"
type="date"
placeholder="选择日期">
<el-date-picker v-model="formData.inTime" type="date" placeholder="选择日期">
</el-date-picker>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
预计完工
</template>
<el-date-picker
v-model="formData.outTime"
type="date"
placeholder="选择日期">
<el-date-picker v-model="formData.outTime" type="date" placeholder="选择日期">
</el-date-picker>
</el-descriptions-item>
<el-descriptions-item>
@ -141,10 +132,7 @@
<template slot="label">
最近保养日期
</template>
<el-date-picker
v-model="formData.maintenanceDate"
type="date"
placeholder="选择日期">
<el-date-picker v-model="formData.maintenanceDate" type="date" placeholder="选择日期">
</el-date-picker>
</el-descriptions-item>
<el-descriptions-item>
@ -158,15 +146,14 @@
预约订单选择
</template>
<el-select v-model="formData.bookingId" size="small" @change="updateBooking">
<el-option v-for="item in bookingList" :key="item.id" :value="item.id"
:label="item.bookingTime"/>
<el-option v-for="item in bookingList" :key="item.id" :value="item.id" :label="item.bookingTime" />
</el-select>
</el-descriptions-item>
<el-descriptions-item :span="3">
<template slot="label">
服务顾问
</template>
<StaffChoose v-model="selectStaff" :is-get="'true'"/>
<StaffChoose v-model="selectStaff" :is-get="'true'" />
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
@ -174,55 +161,70 @@
</template>
<ImageUpload v-model="formData.image" />
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
业务渠道/来源
</template>
<el-cascader
v-model="formData.busiCascader"
:options="busiCascaderOptions"
:props="{ expandTrigger: 'hover', checkStrictly: true }"
placeholder="请选择业务渠道和来源"
style="width: 100%"
@change="handleBusiCascaderChange"
clearable
size="small"
/>
</el-descriptions-item>
</el-descriptions>
</el-card>
</el-col>
<!-- <el-col :span="7" style="padding-left: 0">-->
<!-- <el-card style="margin-left: 0">-->
<!-- <div slot="header" class="clearfix">-->
<!-- <span style="font-weight: bold; font-size: 16px;"> 会员卡券</span>-->
<!-- </div>-->
<!-- <el-table-->
<!-- :data="couponList"-->
<!-- border-->
<!-- size="mini"-->
<!-- height="270"-->
<!-- style="width: 100%">-->
<!-- <el-table-column prop="couponName" label="卡券名称"/>-->
<!-- <el-table-column label="卡券类型" width="80" align="center" prop="couponType">-->
<!-- <template v-slot="scope">-->
<!-- <dict-tag :type="DICT_TYPE.MEMBER_COUPON_TYPE" :value="scope.row.couponType"/>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="剩余金额/次数" width="120" align="right" prop="balance">-->
<!-- <template v-slot="scope">-->
<!-- {{ scope.row.balance }}{{ scope.row.outRule == 'mehx' ? '元' : '次' }}-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="适用车型" width="80" align="center" prop="carModel">-->
<!-- <template v-slot="scope">-->
<!-- <span v-if="scope.row.carModel == null">不限</span>-->
<!-- <dict-tag :type="DICT_TYPE.MEMBER_CAR" :value="scope.row.carModel"/>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="核销规则" width="100" align="center" prop="outRule">-->
<!-- <template v-slot="scope">-->
<!-- <dict-tag :type="DICT_TYPE.MEMBER_COUPON_OUT_RULE" :value="scope.row.outRule"/>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="开始有效期" align="center" prop="beginTime" width="150">-->
<!-- <template v-slot="scope">-->
<!-- <span>{{ parseTime(scope.row.beginTime) }}</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="结束有效期" align="center" prop="endTime" width="150">-->
<!-- <template v-slot="scope">-->
<!-- <span>{{ parseTime(scope.row.endTime) }}</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- </el-table>-->
<!-- </el-card>-->
<!-- </el-col>-->
<!-- <el-col :span="7" style="padding-left: 0">-->
<!-- <el-card style="margin-left: 0">-->
<!-- <div slot="header" class="clearfix">-->
<!-- <span style="font-weight: bold; font-size: 16px;"> 会员卡券</span>-->
<!-- </div>-->
<!-- <el-table-->
<!-- :data="couponList"-->
<!-- border-->
<!-- size="mini"-->
<!-- height="270"-->
<!-- style="width: 100%">-->
<!-- <el-table-column prop="couponName" label="卡券名称"/>-->
<!-- <el-table-column label="卡券类型" width="80" align="center" prop="couponType">-->
<!-- <template v-slot="scope">-->
<!-- <dict-tag :type="DICT_TYPE.MEMBER_COUPON_TYPE" :value="scope.row.couponType"/>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="剩余金额/次数" width="120" align="right" prop="balance">-->
<!-- <template v-slot="scope">-->
<!-- {{ scope.row.balance }}{{ scope.row.outRule == 'mehx' ? '元' : '次' }}-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="适用车型" width="80" align="center" prop="carModel">-->
<!-- <template v-slot="scope">-->
<!-- <span v-if="scope.row.carModel == null">不限</span>-->
<!-- <dict-tag :type="DICT_TYPE.MEMBER_CAR" :value="scope.row.carModel"/>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="核销规则" width="100" align="center" prop="outRule">-->
<!-- <template v-slot="scope">-->
<!-- <dict-tag :type="DICT_TYPE.MEMBER_COUPON_OUT_RULE" :value="scope.row.outRule"/>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="开始有效期" align="center" prop="beginTime" width="150">-->
<!-- <template v-slot="scope">-->
<!-- <span>{{ parseTime(scope.row.beginTime) }}</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="结束有效期" align="center" prop="endTime" width="150">-->
<!-- <template v-slot="scope">-->
<!-- <span>{{ parseTime(scope.row.endTime) }}</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- </el-table>-->
<!-- </el-card>-->
<!-- </el-col>-->
</el-row>
<el-row :gutter="5" style="margin-bottom: 1rem">
<el-col v-if="createTicketType" :span="4.8">
@ -240,62 +242,63 @@
<el-col v-if="createTicketType" :span="4.8">
<el-select v-model="formData.partDisposal" size="small">
<el-option v-for="item in this.getDictDatas(DICT_TYPE.REPAIR_PART_DISPOSAL)" :key="item.value"
:label="item.label" :value="item.value"/>
:label="item.label" :value="item.value" />
</el-select>
</el-col>
<el-col v-if="createTicketType" :span="4.8">
<el-select v-model="formData.repairType" size="small">
<el-option v-for="item in this.getDictDatas(DICT_TYPE.REPAIR_TYPE)" :key="item.value" :label="item.label"
:value="item.value"/>
:value="item.value" />
</el-select>
</el-col>
<el-col :span="4">
<el-button size="small" v-if="formData.ticketType === '01'" @click="formData.ticketType = '02'">A单</el-button>
<el-button size="small" v-if="formData.ticketType === '02'" @click="formData.ticketType = '01'">B单</el-button>
</el-col>
<el-col :span="4" v-if="formData.ticketType === '02'">
<el-button size="small" @click="openTicketChooseDialog">选择A单</el-button>
<span v-if="formData.parentTicketNo" style="margin-left: 10px; color: #67C23A;">已绑定A单{{ formData.parentTicketNo
}}</span>
<el-button v-if="formData.parentTicketNo" size="small" type="text" @click="clearParentTicket"
style="margin-left: 10px; color: #F56C6C;">清除</el-button>
</el-col>
</el-row>
<span style="font-size: 16px">维修工时项目</span>
<TicketItem item-type="project" :in-list-data="projectList" @tableData="projectData" ref="projectTable"
:coupon-list="couponList" @changeCoupon="changeCoupon"/>
:coupon-list="couponList" @changeCoupon="changeCoupon" />
<span style="font-size: 16px; margin:1rem 0" v-if="createTicketType">更换配件清单</span>
<TicketItem v-if="createTicketType" :in-list-data="partList" item-type="part" @tableData="partData"
:coupon-list="couponList" @changeCoupon="changeCoupon"
ref="partTable"/>
:coupon-list="couponList" @changeCoupon="changeCoupon" ref="partTable" />
<span style="font-size: 16px" v-if="createTicketType">其他</span>
<TicketItem v-if="createTicketType" :in-list-data="otherList" item-type="other" @tableData="otherData"
:coupon-list="couponList" @changeCoupon="changeCoupon"
ref="otherTable"/>
:coupon-list="couponList" @changeCoupon="changeCoupon" ref="otherTable" />
<el-row :gutter="createTicketType ? 2 : 3" style="margin-top: 1rem">
<el-col :span="createTicketType ? 12 : 16">
<el-descriptions class="margin-top" :column="createTicketType ? 2 : 3" border :size="'medium'"
style="margin-bottom: 1rem">
<!-- <el-descriptions-item>-->
<!-- <template slot="label">-->
<!-- 工单号-->
<!-- </template>-->
<!-- <TicketChoose @selected="getTickets"/>-->
<!-- </el-descriptions-item>-->
style="margin-bottom: 1rem">
<!-- <el-descriptions-item>-->
<!-- <template slot="label">-->
<!-- 工单号-->
<!-- </template>-->
<!-- <TicketChoose @selected="getTickets"/>-->
<!-- </el-descriptions-item>-->
<el-descriptions-item>
<template slot="label">
时间
</template>
<el-date-picker
v-model="formData.ticketTime"
type="date"
placeholder="选择日期">
<el-date-picker v-model="formData.ticketTime" type="date" placeholder="选择日期">
</el-date-picker>
</el-descriptions-item>
<el-descriptions-item v-if="!createTicketType">
<template slot="label">
备注
</template>
<el-input v-model="formData.remark"/>
<el-input v-model="formData.remark" />
</el-descriptions-item>
</el-descriptions>
</el-col>
<el-col v-if="createTicketType" :span="12">
<el-descriptions class="margin-top" :column="5" :size="'medium'"
style="margin-left: 1rem;margin-top: 1rem">
<el-descriptions class="margin-top" :column="5" :size="'medium'" style="margin-left: 1rem;margin-top: 1rem">
<el-descriptions-item label="数量">{{ formData.count }}</el-descriptions-item>
<el-descriptions-item label="项目">{{ formData.projectPrice }}</el-descriptions-item>
<el-descriptions-item label="配件">{{ formData.partPrice }}</el-descriptions-item>
@ -305,8 +308,8 @@
</el-col>
<el-col v-else :span="8" style="margin-top:1rem;display: flex;justify-content: right">
<el-button type="success" @click="handleSave" :disabled="isEnable">完成</el-button>
<!-- <el-button type="danger">结算</el-button>-->
<!-- <el-button type="warning" @click="handlePendingSave">挂单</el-button>-->
<!-- <el-button type="danger">结算</el-button>-->
<!-- <el-button type="warning" @click="handlePendingSave">挂单</el-button>-->
</el-col>
</el-row>
<el-row v-if="createTicketType" :gutter="2">
@ -316,22 +319,25 @@
<template slot="label">
备注
</template>
<el-input v-model="formData.remark"/>
<el-input v-model="formData.remark" />
</el-descriptions-item>
</el-descriptions>
</el-col>
<el-col :span="12" style="margin-top:1rem;display: flex;justify-content: right">
<el-button type="success" @click="handleSave" :disabled="isEnable">完成</el-button>
<!-- <el-button type="danger" @click="handlePaid" :disabled="isEnable">结算</el-button>-->
<!-- <el-button type="danger" @click="handlePaid" :disabled="isEnable">结算</el-button>-->
<!-- <el-button type="primary">通知施工</el-button>-->
<!-- <el-button type="primary">领料</el-button>-->
<!-- <el-button type="primary">退料</el-button>-->
</el-col>
</el-row>
<RepairAdvice ref="repairAdvice" v-model="formData.repairAdvice"/>
<QualityExplain ref="qualityExplain" v-model="formData.quality"/>
<UserAndCarForm ref="userAndCarInfo" @success="successCusAndCar"/>
<RepairAdvice ref="repairAdvice" v-model="formData.repairAdvice" />
<QualityExplain ref="qualityExplain" v-model="formData.quality" />
<UserAndCarForm ref="userAndCarInfo" @success="successCusAndCar" />
<!-- A单选择对话框 -->
<ParentTicketDialog :visible.sync="ticketChooseDialogVisible" @selected="handleParentTicketSelected" />
</div>
</template>
@ -340,22 +346,23 @@ import UserChoose from "@/views/repair/Components/UserChoose.vue";
import StaffChoose from "@/views/repair/Components/StaffChoose.vue";
import TicketItem from "@/views/repair/tickets/Components/TicketItem.vue";
import CarChoose from "@/views/repair/Components/CarChoose.vue";
import {createUniqueCodeByHead} from "@/utils/createUniqueCode";
import {createTickets, getTicketsById} from "@/api/repair/tickets/Tickets";
import { createUniqueCodeByHead } from "@/utils/createUniqueCode";
import { createTickets, getTicketsById } from "@/api/repair/tickets/Tickets";
import RepairAdvice from "@/views/repair/tickets/form/RepairAdvice.vue";
import QualityExplain from "@/views/repair/tickets/form/QualityExplain.vue";
import TicketChoose from "@/views/repair/tickets/Components/TicketChoose.vue";
import request from "@/utils/request";
import * as CustomerMainApi from "@/api/base/customer";
import UserAndCarForm from "@/views/repair/tickets/form/UserAndCarForm.vue";
import {getByNameAndMobile} from "@/api/base/customer";
import {getByLicenseNumber} from "@/api/base/carmain";
import { getByNameAndMobile } from "@/api/base/customer";
import { getByLicenseNumber } from "@/api/base/carmain";
import ParentTicketDialog from "@/views/repair/tickets/Components/ParentTicketDialog.vue";
export default {
name: "UserInfo",
components: {
UserAndCarForm,
TicketChoose, QualityExplain, RepairAdvice, CarChoose, TicketItem, StaffChoose, UserChoose
ParentTicketDialog, TicketChoose, QualityExplain, RepairAdvice, CarChoose, TicketItem, StaffChoose, UserChoose
},
props: {
createTicketType: {
@ -444,7 +451,14 @@ export default {
handleName: null,
handleMobile: null,
maintenanceDate: null,
maintenanceMileage: null
maintenanceMileage: null,
parentTicketId: null, // AID
parentTicketNo: null, // A
channelId: null, // ID
busiFrom: null, //
sourceId: null, // ID
cusFrom: null, //
busiCascader: [] // /
},
selectUser: {},
selectCar: {},
@ -457,8 +471,17 @@ export default {
finaCouponList: [],
userInData: null,
carInData: null,
ticketChooseDialogVisible: false, // A
busiAndCusList: [], //
channelList: [], //
sourceList: [], //
busiCascaderOptions: [] // /
}
},
mounted() {
//
this.queryBusiAndCus()
},
methods: {
async getCouponList(id) {
const res = await CustomerMainApi.getCustomerMain(id);
@ -530,10 +553,10 @@ export default {
this.createItemInit()
try {
const count = this.handleValidate()
if (count > 0){
if (count > 0) {
return
}
if (this.formData.image){
if (this.formData.image) {
const data = this.formData.image.split(",")
this.formData.image = data.map(item => {
return item.replace(process.env.VUE_APP_FILE_API, "")
@ -648,13 +671,13 @@ export default {
this.formData.itemList = [...this.formData.itemList, ...this.formatItem("other", this.otherList)]
},
//
handleValidate(){
handleValidate() {
let count = 0
this.formData.itemList.forEach(item => {
if (count !== 0) return count
if (!item.repairIds || !item.saleId){
if (!item.repairIds || !item.saleId) {
let message = ""
switch (item.itemType){
switch (item.itemType) {
case "01":
message += "项目:"
break
@ -720,11 +743,11 @@ export default {
cusName: data.userName,
id: data.userId,
phoneNumber: data.userMobile,
quality: {qualityMileage: data.qualityMileage, qualityDay: data.qualityDay}
quality: { qualityMileage: data.qualityMileage, qualityDay: data.qualityDay }
}
const itemList = this.formData.itemList
this.selectUser = {id: data.userId}
this.selectCar = {id: data.carId}
this.selectUser = { id: data.userId }
this.selectCar = { id: data.carId }
this.projectList = [itemList.find(item => item.itemType === '01')]
this.partList = [itemList.find(item => item.itemType === '02')]
this.otherList = [itemList.find(item => item.itemType === '03')]
@ -801,12 +824,121 @@ export default {
// handleSelectionChange(val){
//
// }
updateBooking(){
updateBooking() {
const data = this.bookingList.filter(item => item.id === this.formData.bookingId)
if (data && data.length > 0){
if (data && data.length > 0) {
this.formData.repairType = data[0].repairType
}
},
// A
openTicketChooseDialog() {
this.ticketChooseDialogVisible = true
},
// A
handleParentTicketSelected(ticket) {
if (ticket) {
this.formData.parentTicketId = ticket.id
this.formData.parentTicketNo = ticket.ticketNo
this.ticketChooseDialogVisible = false
this.$modal.msgSuccess(`已绑定A单${ticket.ticketNo}`)
}
},
// A
clearParentTicket() {
this.formData.parentTicketId = null
this.formData.parentTicketNo = null
this.$modal.msgSuccess('已清除绑定的A单')
},
/**
* 获取业务来源和渠道
*/
queryBusiAndCus() {
request({
url: `/business/list`,
method: 'GET',
params: {
systemCode: 'repair'
}
}).then(res => {
this.busiAndCusList = res.data
console.log('busiAndCusList', this.busiAndCusList);
//
this.processBusiAndCusData()
})
},
/**
* 处理业务渠道和来源数据
*/
processBusiAndCusData() {
// pid0
this.channelList = this.busiAndCusList.filter(item => item.pid === 0)
// pid0
this.sourceList = this.busiAndCusList.filter(item => item.pid !== 0)
//
this.generateCascaderOptions()
},
/**
* 生成级联选择器选项
*/
generateCascaderOptions() {
//
const channels = this.busiAndCusList.filter(item => item.pid === 0)
//
this.busiCascaderOptions = channels.map(channel => {
//
const sources = this.busiAndCusList.filter(item => item.pid === channel.id)
return {
value: channel.id,
label: channel.name,
children: sources.map(source => ({
value: source.id,
label: source.name
}))
}
})
},
/**
* 业务渠道/来源级联选择变化
*/
handleBusiCascaderChange(value) {
if (value && value.length > 0) {
if (value.length === 1) {
//
const channelId = value[0]
const selectedChannel = this.channelList.find(item => item.id === channelId)
if (selectedChannel) {
this.formData.channelId = selectedChannel.id
this.formData.busiFrom = selectedChannel.name
//
this.formData.sourceId = null
this.formData.cusFrom = null
}
} else if (value.length === 2) {
//
const channelId = value[0]
const sourceId = value[1]
const selectedChannel = this.channelList.find(item => item.id === channelId)
const selectedSource = this.sourceList.find(item => item.id === sourceId)
if (selectedChannel && selectedSource) {
this.formData.channelId = selectedChannel.id
this.formData.busiFrom = selectedChannel.name
this.formData.sourceId = selectedSource.id
this.formData.cusFrom = selectedSource.name
}
}
} else {
//
this.formData.channelId = null
this.formData.busiFrom = null
this.formData.sourceId = null
this.formData.cusFrom = null
}
},
}
}
</script>