|
|
@@ -0,0 +1,993 @@
|
|
|
+<template>
|
|
|
+ <div class="print-container">
|
|
|
+ <!-- 图片预览模式 -->
|
|
|
+ <img
|
|
|
+ v-if="previewImage"
|
|
|
+ class="preview-image"
|
|
|
+ :src="previewImage"
|
|
|
+ alt="确认单预览"
|
|
|
+ />
|
|
|
+
|
|
|
+ <!-- 表单渲染模式 -->
|
|
|
+ <div v-else>
|
|
|
+ <!-- 非工序模板 -->
|
|
|
+ <div
|
|
|
+ ref="container"
|
|
|
+ class="form-container"
|
|
|
+ v-if="detail.workorder?.actiontype === '非工序模板'"
|
|
|
+ >
|
|
|
+ <div class="form-header">
|
|
|
+ <h2 class="form-title">{{ $t("浙江班尼戈流体控制有限公司") }}</h2>
|
|
|
+ <h3 class="form-subtitle">{{ $t("服务确认单") }}</h3>
|
|
|
+ <div class="form-info">
|
|
|
+ <span>{{ $t("日期") }}: {{ detail.createdate }}</span>
|
|
|
+ <span>{{ $t("编号") }}: {{ detail.confirmationno }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <table class="data-table">
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("项目名称") }}</td>
|
|
|
+ <td>{{ detail.workorder.projectname || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("保质期") }}</td>
|
|
|
+ <td>{{ detail.workorder.isouritem === 1 ? $t("内") : $t("外") }}</td>
|
|
|
+ <td class="td-title">{{ $t("服务方式") }}</td>
|
|
|
+ <td>{{ detail.workorder.type || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("服务单号") }}</td>
|
|
|
+ <td>{{ detail.workorder.servicebillno || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("服务类型") }}</td>
|
|
|
+ <td>{{ detail.workorder.servicetype || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("订单号") }}</td>
|
|
|
+ <td>{{ detail.workorder.sonum || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("联系人") }}</td>
|
|
|
+ <td>{{ detail.workorder.scenecontact || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("联系方式") }}</td>
|
|
|
+ <td>{{ detail.workorder.scenecontactphonenumber || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("应用系统") }}</td>
|
|
|
+ <td>{{ detail.workorder.class1 || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("是否保内") }}</td>
|
|
|
+ <td>{{ detail.workorder.inqualityguaranteeperiod ? $t("是") : $t("否") }}</td>
|
|
|
+ <td class="td-title">{{ $t("售后人员") }}</td>
|
|
|
+ <td>{{ detail.workorder.projectleader || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("经销商名称") }}</td>
|
|
|
+ <td>{{ detail.workorder.enterprisename || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("申请原因") }}</td>
|
|
|
+ <td colspan="5">{{ detail.workorder.reason || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("地址") }}</td>
|
|
|
+ <td colspan="5">{{ buildAddress(detail.workorder) }}</td>
|
|
|
+ </tr>
|
|
|
+
|
|
|
+ <!-- 产品列表 -->
|
|
|
+ <tr>
|
|
|
+ <td colspan="6" class="td-padding-0">
|
|
|
+ <el-table
|
|
|
+ :data="detail.trainertitems || []"
|
|
|
+ :header-cell-style="{ background: '#F2F3F5', color: '#000000' }"
|
|
|
+ size="mini"
|
|
|
+ >
|
|
|
+ <el-table-column width="260" prop="itemname" :label="$t('产品名')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.itemname || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="itemno" width="200" :label="$t('编号')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.itemno || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column width="100" prop="qty" :label="$t('数量')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.qty || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column width="200" prop="model" :label="$t('型号')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.model || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column width="200" prop="spec" :label="$t('规格')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.spec || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column width="200" prop="reason_service" :label="$t('异常现象')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.reason_service || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+
|
|
|
+ <!-- 处理方式 -->
|
|
|
+ <tr>
|
|
|
+ <td class="td-title-center" colspan="6">{{ $t("处理方式") }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr
|
|
|
+ v-for="item in detail.trainertitems"
|
|
|
+ :key="item.sa_workorder_node_itemsid"
|
|
|
+ >
|
|
|
+ <td>
|
|
|
+ <p>{{ item.itemname }}</p>
|
|
|
+ <p>{{ item.itemno }}</p>
|
|
|
+ </td>
|
|
|
+ <td colspan="5">{{ item.processing || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+
|
|
|
+ <!-- 处理结果 -->
|
|
|
+ <tr>
|
|
|
+ <td class="td-title-center" colspan="6">{{ $t("处理结果") }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr
|
|
|
+ v-for="item in detail.trainertitems"
|
|
|
+ :key="item.sa_workorder_node_itemsid"
|
|
|
+ >
|
|
|
+ <td>
|
|
|
+ <p>{{ item.itemname }}</p>
|
|
|
+ <p>{{ item.itemno }}</p>
|
|
|
+ </td>
|
|
|
+ <td colspan="5">{{ item.result || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+
|
|
|
+ <!-- 客户签字 -->
|
|
|
+ <tr>
|
|
|
+ <td class="td-signature">{{ $t("客户意见及签字确认") }}:</td>
|
|
|
+ <td colspan="5">
|
|
|
+ <img
|
|
|
+ v-if="signatureUrl"
|
|
|
+ class="signature-image"
|
|
|
+ :src="signatureUrl"
|
|
|
+ alt="客户签名"
|
|
|
+ />
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+
|
|
|
+ <!-- 满意度评分 -->
|
|
|
+ <tr>
|
|
|
+ <td class="td-score">{{ $t("反应速度") }}</td>
|
|
|
+ <td>{{ detail.responsescore || "--" }}</td>
|
|
|
+ <td class="td-score">{{ $t("配合态度") }}</td>
|
|
|
+ <td>{{ detail.attitudescore || "--" }}</td>
|
|
|
+ <td class="td-score">{{ $t("满意度") }}</td>
|
|
|
+ <td>{{ detail.satisfaction || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+
|
|
|
+ <!-- 底部说明 -->
|
|
|
+ <tr>
|
|
|
+ <td colspan="6" class="td-footer">
|
|
|
+ {{ $t("尊敬的用户,感谢您一直以来对我们公司的信任和支持,为更好的为您提供优质服务和产品,请允许我们的客户人员带回您最宝贵的意见") }}
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 安装培训确认单 -->
|
|
|
+ <div
|
|
|
+ ref="container"
|
|
|
+ class="form-container"
|
|
|
+ v-else-if="detail.workorder?.type === '安装培训'"
|
|
|
+ >
|
|
|
+ <div class="form-header">
|
|
|
+ <h2 class="form-title">{{ $t("浙江班尼戈智慧管网股份有限公司") }}</h2>
|
|
|
+ <h3 class="form-subtitle">{{ $t("BZ/Q(EO)P38-02 系统《E 服务确认单》") }}</h3>
|
|
|
+ <div class="form-info">
|
|
|
+ <span>{{ $t("日期") }}: {{ detail.createdate }}</span>
|
|
|
+ <span>{{ $t("编号") }}: {{ detail.confirmationno }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <table class="data-table">
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("服务分类") }}</td>
|
|
|
+ <td>{{ detail.workorder.type || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("应用系统") }}</td>
|
|
|
+ <td>{{ detail.workorder.class1 || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("工单负责人") }}</td>
|
|
|
+ <td>{{ detail.workorder.projectleader || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("项目名称") }}</td>
|
|
|
+ <td>{{ detail.workorder.projectname || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("业务员负责人") }}</td>
|
|
|
+ <td>{{ detail.workorder.saler_name || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("服务经销商") }}</td>
|
|
|
+ <td>{{ detail.workorder.abbreviation || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("联系人") }}</td>
|
|
|
+ <td>{{ detail.workorder.scenecontact || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("联系方式") }}</td>
|
|
|
+ <td>{{ detail.workorder.scenecontactphonenumber || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("地址") }}</td>
|
|
|
+ <td>{{ buildAddress(detail.workorder) }}</td>
|
|
|
+ </tr>
|
|
|
+
|
|
|
+ <!-- 培训人员 -->
|
|
|
+ <tr>
|
|
|
+ <td colspan="6" class="td-padding-0">
|
|
|
+ <el-table
|
|
|
+ :data="detail.trainers || []"
|
|
|
+ :header-cell-style="{ background: '#F2F3F5', color: '#000000' }"
|
|
|
+ size="mini"
|
|
|
+ >
|
|
|
+ <el-table-column width="260" prop="name" :label="$t('培训人员姓名')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.name || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="position" :label="$t('职务')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.position || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column width="200" prop="phonenumber" :label="$t('电话')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.phonenumber || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column width="200" prop="enterprisename" :label="$t('所属经销商')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.enterprisename || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+
|
|
|
+ <!-- 产品列表 -->
|
|
|
+ <tr>
|
|
|
+ <td colspan="6" class="td-padding-0">
|
|
|
+ <el-table
|
|
|
+ :data="detail.trainertitems || []"
|
|
|
+ :header-cell-style="{ background: '#F2F3F5', color: '#000000' }"
|
|
|
+ size="mini"
|
|
|
+ >
|
|
|
+ <el-table-column width="260" prop="itemname" :label="$t('产品名')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.itemname || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="itemno" width="200" :label="$t('编号')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.itemno || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column width="60" prop="qty" :label="$t('数量')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.qty || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column width="200" prop="model" :label="$t('型号')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.model || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column width="200" prop="spec" :label="$t('规格')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.spec || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("现场培训内容") }}</td>
|
|
|
+ <td colspan="5">{{ text.descriptions1 || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("现场互动及测试培训效果") }}</td>
|
|
|
+ <td colspan="5">{{ text.descriptions2 || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-signature">{{ $t("客户意见及签字确认") }}:</td>
|
|
|
+ <td colspan="5">
|
|
|
+ <img v-if="signatureUrl" class="signature-image" :src="signatureUrl" alt="客户签名"/>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-score">{{ $t("反应速度") }}</td>
|
|
|
+ <td colspan="2">{{ detail.responsescore || "--" }}</td>
|
|
|
+ <td class="td-score">{{ $t("配合态度") }}</td>
|
|
|
+ <td colspan="2">{{ detail.attitudescore || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td colspan="6" class="td-footer">
|
|
|
+ {{ $t("尊敬的用户,感谢您一直以来对我们公司的信任和支持,为更好的为您提供优质服务和产品,请允许我们的客户人员带回您最宝贵的意见") }}
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 服务确认单 -->
|
|
|
+ <div
|
|
|
+ ref="container"
|
|
|
+ class="form-container"
|
|
|
+ v-else-if="detail.workorder?.type === '服务'"
|
|
|
+ >
|
|
|
+ <div class="form-header">
|
|
|
+ <h2 class="form-title">{{ $t("浙江班尼戈智慧管网股份有限公司") }}</h2>
|
|
|
+ <h3 class="form-subtitle">{{ $t("售后服务确认单") }}</h3>
|
|
|
+ <div class="form-info">
|
|
|
+ <span>{{ $t("日期") }}: {{ detail.createdate }}</span>
|
|
|
+ <span>{{ $t("编号") }}: {{ detail.confirmationno }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <table class="data-table">
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("项目名称") }}</td>
|
|
|
+ <td>{{ detail.workorder.projectname || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("保质期") }}</td>
|
|
|
+ <td>{{ detail.workorder.isouritem === 1 ? $t("内") : $t("外") }}</td>
|
|
|
+ <td class="td-title">{{ $t("是否有偿服务") }}</td>
|
|
|
+ <td>{{ text.descriptions4 > 0 ? $t("是") : $t("否") }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("服务金额") }}</td>
|
|
|
+ <td>{{ text.descriptions4 || "0" }}</td>
|
|
|
+ <td class="td-title">{{ $t("联系人") }}</td>
|
|
|
+ <td>{{ detail.workorder.scenecontact || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("联系方式") }}</td>
|
|
|
+ <td>{{ detail.workorder.scenecontactphonenumber || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("应用系统") }}</td>
|
|
|
+ <td>{{ detail.workorder.class1 || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("客诉大类") }}</td>
|
|
|
+ <td>{{ detail.workorder.class2 || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("地址") }}</td>
|
|
|
+ <td>{{ buildAddress(detail.workorder) }}</td>
|
|
|
+ </tr>
|
|
|
+
|
|
|
+ <!-- 产品列表 -->
|
|
|
+ <tr>
|
|
|
+ <td colspan="6" class="td-padding-0">
|
|
|
+ <el-table
|
|
|
+ :data="detail.trainertitems || []"
|
|
|
+ :header-cell-style="{ background: '#F2F3F5', color: '#000000' }"
|
|
|
+ size="mini"
|
|
|
+ >
|
|
|
+ <el-table-column width="260" prop="itemname" :label="$t('产品名')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.itemname || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="itemno" width="200" :label="$t('编号')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.itemno || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column width="200" prop="qty" :label="$t('数量')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.qty || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column width="200" prop="model" :label="$t('型号')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.model || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column width="200" prop="spec" :label="$t('规格')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.spec || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("问题简述") }}</td>
|
|
|
+ <td colspan="5">{{ detail.workorder.reason || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("原因及处理措施") }}</td>
|
|
|
+ <td colspan="5">{{ getConfirmValue(detail.confirmationcontent, 8, 'confirm_value') }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("下次处理日期") }}</td>
|
|
|
+ <td colspan="5">{{ getConfirmValue(detail.confirmationcontent, 7, 'nextTreatmentTime.confirm_value') }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("事项说明") }}</td>
|
|
|
+ <td colspan="5">{{ getConfirmValue(detail.confirmationcontent, 9, 'explain.confirm_value') }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-signature">{{ $t("客户意见及签字确认") }}:</td>
|
|
|
+ <td colspan="5">
|
|
|
+ <img v-if="signatureUrl" class="signature-image" :src="signatureUrl" alt="客户签名"/>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-score">{{ $t("反应速度") }}</td>
|
|
|
+ <td colspan="2">{{ detail.responsescore || "--" }}</td>
|
|
|
+ <td class="td-score">{{ $t("配合态度") }}</td>
|
|
|
+ <td colspan="2">{{ detail.attitudescore || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td colspan="6" class="td-footer">
|
|
|
+ {{ $t("尊敬的用户,感谢您一直以来对我们公司的信任和支持,为更好的为您提供优质服务和产品,请允许我们的客户人员带回您最宝贵的意见") }}
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 安装调试确认单 -->
|
|
|
+ <div
|
|
|
+ ref="container"
|
|
|
+ class="form-container"
|
|
|
+ v-else-if="detail.workorder?.type === '安装调试'"
|
|
|
+ >
|
|
|
+ <div class="form-header">
|
|
|
+ <h2 class="form-title">{{ $t("浙江班尼戈智慧管网股份有限公司") }}</h2>
|
|
|
+ <h3 class="form-subtitle">{{ $t("BZ/Q(EO)P38-02 系统《E 服务确认单》") }}</h3>
|
|
|
+ <div class="form-info">
|
|
|
+ <span>{{ $t("日期") }}: {{ detail.createdate }}</span>
|
|
|
+ <span>{{ $t("编号") }}: {{ detail.confirmationno }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <table class="data-table">
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("服务分类") }}</td>
|
|
|
+ <td>{{ detail.workorder.type || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("应用系统") }}</td>
|
|
|
+ <td>{{ detail.workorder.class1 || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("工单负责人") }}</td>
|
|
|
+ <td>{{ detail.workorder.projectleader || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("项目名称") }}</td>
|
|
|
+ <td>{{ detail.workorder.projectname || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("业务员负责人") }}</td>
|
|
|
+ <td>{{ detail.workorder.saler_name || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("服务经销商") }}</td>
|
|
|
+ <td>{{ detail.workorder.abbreviation || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("联系人") }}</td>
|
|
|
+ <td>{{ detail.workorder.scenecontact || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("联系方式") }}</td>
|
|
|
+ <td>{{ detail.workorder.scenecontactphonenumber || "--" }}</td>
|
|
|
+ <td class="td-title">{{ $t("地址") }}</td>
|
|
|
+ <td>{{ buildAddress(detail.workorder) }}</td>
|
|
|
+ </tr>
|
|
|
+
|
|
|
+ <!-- 产品列表 -->
|
|
|
+ <tr>
|
|
|
+ <td colspan="6" class="td-padding-0">
|
|
|
+ <el-table
|
|
|
+ :data="detail.trainertitems || []"
|
|
|
+ :header-cell-style="{ background: '#F2F3F5', color: '#000000' }"
|
|
|
+ size="mini"
|
|
|
+ >
|
|
|
+ <el-table-column width="260" prop="itemname" :label="$t('产品名')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.itemname || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="itemno" :label="$t('编号')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.itemno || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column width="200" prop="qty" :label="$t('数量')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.qty || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column width="200" prop="model" :label="$t('型号')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.model || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column width="200" prop="spec" :label="$t('规格')">
|
|
|
+ <template slot-scope="scope">{{ scope.row.spec || "--" }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+
|
|
|
+ <tr>
|
|
|
+ <td colspan="2" class="td-title">{{ $t("客诉情况") }}</td>
|
|
|
+ <td colspan="1">{{ detail.workorder.reason || "--" }}</td>
|
|
|
+ <td colspan="2" class="td-title">{{ $t("是否为我公司生产、出货产品?") }}</td>
|
|
|
+ <td colspan="1">{{ detail.workorder.isouritem === 1 ? $t("是") : $t("否") }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td colspan="2" class="td-title">{{ $t("是否可以在线维修、调试") }}</td>
|
|
|
+ <td colspan="1">{{ text.descriptions1 || "--" }}</td>
|
|
|
+ <td colspan="2" class="td-title">{{ $t("是否需要拆卸配件或整拆?") }}</td>
|
|
|
+ <td colspan="1">{{ text.descriptions2 || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td colspan="2" class="td-title">{{ $t("与现场协商确认维修方案(包含周期))?") }}</td>
|
|
|
+ <td colspan="1">{{ text.descriptions3 || "--" }}</td>
|
|
|
+ <td colspan="2" class="td-title">{{ $t("是否有偿服务") }}</td>
|
|
|
+ <td colspan="1">{{ text.descriptions4 > 0 ? $t("是") : $t("否") }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td colspan="2" class="td-title">{{ $t("服务金额") }}</td>
|
|
|
+ <td colspan="1">{{ text.descriptions4 || "0" }}</td>
|
|
|
+ <td colspan="2" class="td-title">{{ $t("实施内容") }}</td>
|
|
|
+ <td colspan="1">{{ text.descriptions5 || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td colspan="2" class="td-title">{{ $t("服务测试内容描述") }}</td>
|
|
|
+ <td colspan="1">{{ text.descriptions6 || "--" }}</td>
|
|
|
+ <td colspan="2" class="td-title">{{ $t("现场交代事项") }}</td>
|
|
|
+ <td colspan="1">{{ text.descriptions7 || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("保质期") }}</td>
|
|
|
+ <td colspan="5">{{ detail.workorder.isouritem === 1 ? $t("内") : $t("外") }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-title">{{ $t("备注说明") }}</td>
|
|
|
+ <td colspan="5">{{ detail.workorder.remarks || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-signature">{{ $t("客户意见及签字确认") }}:</td>
|
|
|
+ <td colspan="5">
|
|
|
+ <img v-if="signatureUrl" class="signature-image" :src="signatureUrl" alt="客户签名"/>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td class="td-score">{{ $t("反应速度") }}</td>
|
|
|
+ <td colspan="2">{{ detail.responsescore || "--" }}</td>
|
|
|
+ <td class="td-score">{{ $t("配合态度") }}</td>
|
|
|
+ <td colspan="2">{{ detail.attitudescore || "--" }}</td>
|
|
|
+ </tr>
|
|
|
+ <tr>
|
|
|
+ <td colspan="6" class="td-footer">
|
|
|
+ {{ $t("尊敬的用户,感谢您一直以来对我们公司的信任和支持,为更好的为您提供优质服务和产品,请允许我们的客户人员带回您最宝贵的意见") }}
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import html2canvas from "html2canvas";
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: "PrintTable2",
|
|
|
+ props: {
|
|
|
+ data: {
|
|
|
+ type: Object,
|
|
|
+ default: () => ({})
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ previewImage: "",
|
|
|
+ detail: {
|
|
|
+ servicetype: {},
|
|
|
+ workorder: {},
|
|
|
+ servicetitems: [],
|
|
|
+ confirmationcontent: [],
|
|
|
+ trainertitems: [],
|
|
|
+ trainers: [],
|
|
|
+ attinfos: []
|
|
|
+ },
|
|
|
+ signatureUrl: "",
|
|
|
+ text: {
|
|
|
+ descriptions1: "",
|
|
|
+ descriptions2: "",
|
|
|
+ descriptions3: "",
|
|
|
+ descriptions4: 0,
|
|
|
+ descriptions5: "",
|
|
|
+ descriptions6: "",
|
|
|
+ descriptions7: ""
|
|
|
+ },
|
|
|
+ folderid: this.$route?.query?.parentid || "",
|
|
|
+ isUploading: false
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ ownerid() {
|
|
|
+ return this.$route?.query?.ownerid || "";
|
|
|
+ },
|
|
|
+ token() {
|
|
|
+ return this.$route?.query?.token || "";
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ /**
|
|
|
+ * 构建完整地址
|
|
|
+ */
|
|
|
+ buildAddress(workorder) {
|
|
|
+ if (!workorder) return "--";
|
|
|
+ const parts = [
|
|
|
+ workorder.province,
|
|
|
+ workorder.city,
|
|
|
+ workorder.county,
|
|
|
+ workorder.address
|
|
|
+ ].filter(Boolean);
|
|
|
+ return parts.length > 0 ? parts.join("") : "--";
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取确认内容值(嵌套路径支持)
|
|
|
+ */
|
|
|
+ getConfirmValue(content, index, path) {
|
|
|
+ if (!content || !content[index]) return "--";
|
|
|
+ const keys = path.split(".");
|
|
|
+ let value = content[index];
|
|
|
+ for (const key of keys) {
|
|
|
+ value = value?.[key];
|
|
|
+ }
|
|
|
+ return value || "--";
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 加载签名图片
|
|
|
+ */
|
|
|
+ loadSignature(url) {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ if (!url) {
|
|
|
+ resolve(null);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const img = new Image();
|
|
|
+ img.crossOrigin = "anonymous";
|
|
|
+ img.onload = () => resolve(url);
|
|
|
+ img.onerror = (err) => {
|
|
|
+ console.warn("签名图片加载失败:", err);
|
|
|
+ resolve(null);
|
|
|
+ };
|
|
|
+ // 添加时间戳防止缓存
|
|
|
+ const separator = url.indexOf("?") > -1 ? "&" : "?";
|
|
|
+ img.src = `${url}${separator}t=${Date.now()}`;
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 解析确认内容
|
|
|
+ */
|
|
|
+ parseConfirmationContent(content) {
|
|
|
+ const text = {
|
|
|
+ descriptions1: "",
|
|
|
+ descriptions2: "",
|
|
|
+ descriptions3: "",
|
|
|
+ descriptions4: 0,
|
|
|
+ descriptions5: "",
|
|
|
+ descriptions6: "",
|
|
|
+ descriptions7: ""
|
|
|
+ };
|
|
|
+
|
|
|
+ if (!content || !Array.isArray(content)) return text;
|
|
|
+
|
|
|
+ content.forEach((item) => {
|
|
|
+ Object.keys(item).forEach((key) => {
|
|
|
+ const value = item[key];
|
|
|
+
|
|
|
+ // 累加金额
|
|
|
+ if (value.amount) {
|
|
|
+ text.descriptions4 += Number(value.amount) || 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 匹配字段
|
|
|
+ if (key.includes("现场培训内容")) {
|
|
|
+ text.descriptions1 = value.confirm_value || value.textcontent || "";
|
|
|
+ }
|
|
|
+ if (key.includes("测试培训效果")) {
|
|
|
+ text.descriptions2 = value.confirm_value || value.textcontent || "";
|
|
|
+ }
|
|
|
+ if (key.includes("维修方案")) {
|
|
|
+ text.descriptions3 = value.confirm_value || value.textcontent || "";
|
|
|
+ }
|
|
|
+ if (key.includes("实施内容")) {
|
|
|
+ text.descriptions5 = value.confirm_value || value.textcontent || "";
|
|
|
+ }
|
|
|
+ if (key.includes("测试") || key.includes("验收")) {
|
|
|
+ text.descriptions6 = value.confirm_value || value.textcontent || "";
|
|
|
+ }
|
|
|
+ if (key.includes("注意事项") || key.includes("交代")) {
|
|
|
+ text.descriptions7 = value.confirm_value || value.textcontent || "";
|
|
|
+ }
|
|
|
+ if (key.includes("拆卸")) {
|
|
|
+ text.descriptions2 = value.confirm_value || value.textcontent || "";
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ return text;
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 加载工单数据
|
|
|
+ */
|
|
|
+ async listData() {
|
|
|
+ try {
|
|
|
+ const param = {
|
|
|
+ id: "20230211105803",
|
|
|
+ content: {
|
|
|
+ sa_workorder_confirmationid: this.ownerid
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const res = await this.$api.requested(param);
|
|
|
+ this.detail = res.data;
|
|
|
+
|
|
|
+ // 解析确认内容
|
|
|
+ this.text = this.parseConfirmationContent(res.data.confirmationcontent);
|
|
|
+
|
|
|
+ // 提取签名
|
|
|
+ const signatures = (res.data.attinfos || []).filter(
|
|
|
+ (e) => e.usetype === "signature"
|
|
|
+ );
|
|
|
+
|
|
|
+ // 加载签名图片
|
|
|
+ if (signatures.length > 0 && signatures[0].url) {
|
|
|
+ this.signatureUrl = await this.loadSignature(signatures[0].url);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 等待 DOM 渲染后生成图片
|
|
|
+ await this.$nextTick();
|
|
|
+ await new Promise((resolve) => setTimeout(resolve, 800));
|
|
|
+
|
|
|
+ // 判断是否需要直接上传
|
|
|
+ if (res.data.status === "新建" || this.$route?.query?.action == 1) {
|
|
|
+ await this.generateAndUpload();
|
|
|
+ } else {
|
|
|
+ await this.generatePreview();
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error("加载数据失败:", error);
|
|
|
+ this.$message?.error("加载数据失败,请重试");
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成预览图片
|
|
|
+ */
|
|
|
+ async generatePreview() {
|
|
|
+ const container = this.$refs.container;
|
|
|
+ if (!container) {
|
|
|
+ console.error("容器未找到");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ const canvas = await html2canvas(container, {
|
|
|
+ backgroundColor: "#ffffff",
|
|
|
+ useCORS: true,
|
|
|
+ scale: 2, // 提高清晰度
|
|
|
+ logging: false
|
|
|
+ });
|
|
|
+
|
|
|
+ canvas.toBlob((blob) => {
|
|
|
+ if (blob) {
|
|
|
+ this.previewImage = URL.createObjectURL(blob);
|
|
|
+ }
|
|
|
+ }, "image/jpeg", 0.92);
|
|
|
+ } catch (error) {
|
|
|
+ console.error("生成预览失败:", error);
|
|
|
+ this.$message?.error("生成预览失败");
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成图片并上传
|
|
|
+ */
|
|
|
+ async generateAndUpload() {
|
|
|
+ if (this.isUploading) return;
|
|
|
+ this.isUploading = true;
|
|
|
+
|
|
|
+ const container = this.$refs.container;
|
|
|
+ if (!container) {
|
|
|
+ console.error("容器未找到");
|
|
|
+ this.isUploading = false;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 生成 Canvas
|
|
|
+ const canvas = await html2canvas(container, {
|
|
|
+ backgroundColor: "#ffffff",
|
|
|
+ useCORS: true,
|
|
|
+ scale: 2,
|
|
|
+ logging: false
|
|
|
+ });
|
|
|
+
|
|
|
+ // 转为 Blob
|
|
|
+ const blob = await new Promise((resolve) => {
|
|
|
+ canvas.toBlob(resolve, "image/jpeg", 0.92);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 创建 File 对象
|
|
|
+ const fileName = `${this.detail.workorder?.type || "确认单"}.jpg`;
|
|
|
+ const file = new File([blob], fileName, {
|
|
|
+ type: "image/jpeg"
|
|
|
+ });
|
|
|
+
|
|
|
+ // 设置预览
|
|
|
+ this.previewImage = URL.createObjectURL(blob);
|
|
|
+
|
|
|
+ // 上传到华为云
|
|
|
+ await this.uploadToObs(file);
|
|
|
+ } catch (error) {
|
|
|
+ console.error("生成并上传失败:", error);
|
|
|
+ this.$message?.error("生成确认单失败");
|
|
|
+ } finally {
|
|
|
+ this.isUploading = false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 上传到华为云 OBS
|
|
|
+ */
|
|
|
+ async uploadToObs(file) {
|
|
|
+ try {
|
|
|
+ // 1. 获取上传地址
|
|
|
+ const uploadParams = {
|
|
|
+ accesstoken: this.token,
|
|
|
+ classname: "system.attachment.huawei.OBS",
|
|
|
+ method: "getFileName",
|
|
|
+ content: {
|
|
|
+ filename: `${this.detail.workorder?.type || "确认单"}.jpg`,
|
|
|
+ filetype: "jpg",
|
|
|
+ parentid: this.folderid
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const res = await this.$api.requested(uploadParams);
|
|
|
+ const uploadUrl = res.data.uploadurl;
|
|
|
+ const obsFilename = res.data.serialfilename;
|
|
|
+
|
|
|
+ // 2. 上传文件
|
|
|
+ const uploadConfig = {
|
|
|
+ headers: {
|
|
|
+ "Content-Type": "application/octet-stream"
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ await this.$upload.hw_upload(uploadUrl, file, uploadConfig);
|
|
|
+
|
|
|
+ // 3. 创建附件记录
|
|
|
+ await this.createFileRecord(obsFilename);
|
|
|
+ } catch (error) {
|
|
|
+ console.error("上传失败:", error);
|
|
|
+ throw error;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建附件记录
|
|
|
+ */
|
|
|
+ async createFileRecord(obsFilename) {
|
|
|
+ try {
|
|
|
+ // 1. 上传成功回调
|
|
|
+ const successParams = {
|
|
|
+ accesstoken: this.token,
|
|
|
+ classname: "system.attachment.huawei.OBS",
|
|
|
+ method: "uploadSuccess",
|
|
|
+ content: {
|
|
|
+ serialfilename: obsFilename,
|
|
|
+ ...this.bindData
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const res = await this.$api.requested(successParams);
|
|
|
+
|
|
|
+ if (res.code === 1 && res.data?.attachmentids?.[0]) {
|
|
|
+ // 2. 创建关联
|
|
|
+ const linkParams = {
|
|
|
+ accesstoken: this.token,
|
|
|
+ classname: "system.attachment.Attachment",
|
|
|
+ method: "createFileLink",
|
|
|
+ content: {
|
|
|
+ ownertable: "sa_workorder_confirmation",
|
|
|
+ ownerid: this.ownerid,
|
|
|
+ usetype: "comfirmbill",
|
|
|
+ attachmentids: [res.data.attachmentids[0]]
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ await this.$api.requested(linkParams);
|
|
|
+
|
|
|
+ // 3. 触发成功事件
|
|
|
+ this.$emit("onSuccess", res);
|
|
|
+ this.$message?.success("确认单保存成功");
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error("创建记录失败:", error);
|
|
|
+ throw error;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 手动触发生成并上传
|
|
|
+ */
|
|
|
+ async submit() {
|
|
|
+ await this.generateAndUpload();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ // 同步 token 到 sessionStorage
|
|
|
+ if (this.token) {
|
|
|
+ let account = sessionStorage.getItem("active_account");
|
|
|
+ if (account) {
|
|
|
+ const data = JSON.parse(account);
|
|
|
+ data.token = this.token;
|
|
|
+ sessionStorage.setItem("active_account", JSON.stringify(data));
|
|
|
+ } else {
|
|
|
+ sessionStorage.setItem("active_account", JSON.stringify({ token: this.token }));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.listData();
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.print-container {
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.preview-image {
|
|
|
+ width: 100%;
|
|
|
+ object-fit: contain;
|
|
|
+ display: block;
|
|
|
+}
|
|
|
+
|
|
|
+.form-container {
|
|
|
+ background: #ffffff;
|
|
|
+ padding: 20px;
|
|
|
+ box-sizing: border-box;
|
|
|
+}
|
|
|
+
|
|
|
+.form-header {
|
|
|
+ text-align: center;
|
|
|
+ margin-bottom: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.form-title {
|
|
|
+ margin: 0;
|
|
|
+ font-size: 20px;
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+
|
|
|
+.form-subtitle {
|
|
|
+ margin: 10px 0;
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+
|
|
|
+.form-info {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding: 10px 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.data-table {
|
|
|
+ width: 100%;
|
|
|
+ border-collapse: collapse;
|
|
|
+ border: 1px solid #ebebed;
|
|
|
+}
|
|
|
+
|
|
|
+.data-table tr td {
|
|
|
+ padding: 10px;
|
|
|
+ border: 1px solid #ebebed;
|
|
|
+ word-break: break-all;
|
|
|
+}
|
|
|
+
|
|
|
+.td-title {
|
|
|
+ background: #fafafa;
|
|
|
+ color: #000000;
|
|
|
+ width: 120px;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+.td-title-center {
|
|
|
+ background: #fafafa;
|
|
|
+ color: #000000;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+.td-padding-0 {
|
|
|
+ padding: 0 !important;
|
|
|
+}
|
|
|
+
|
|
|
+.td-signature {
|
|
|
+ background: #fafafa;
|
|
|
+ width: 150px;
|
|
|
+}
|
|
|
+
|
|
|
+.td-score {
|
|
|
+ background: #fafafa;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+.td-footer {
|
|
|
+ padding: 15px 10px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #666;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+.signature-image {
|
|
|
+ width: 450px;
|
|
|
+ height: 100px;
|
|
|
+ object-fit: contain;
|
|
|
+}
|
|
|
+
|
|
|
+.flex {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+
|
|
|
+.noborder td {
|
|
|
+ border-left: none;
|
|
|
+ border-top: none;
|
|
|
+ border-bottom: none;
|
|
|
+}
|
|
|
+</style>
|