|
|
@@ -1,31 +1,6 @@
|
|
|
<template>
|
|
|
<el-col :span="16" :offset="6">
|
|
|
<el-form label-width="100px" ref="formRef" :model="form">
|
|
|
- <!-- <el-form-item
|
|
|
- label="技术员"
|
|
|
- prop="technicianId"
|
|
|
- style="margin-bottom: 20px"
|
|
|
- :rules="{
|
|
|
- required: true,
|
|
|
- message: '请选择',
|
|
|
- trigger: 'change'
|
|
|
- }"
|
|
|
- v-if="taskDefinitionKey == 'productionSupervisorApprove1'"
|
|
|
- >
|
|
|
- <el-select
|
|
|
- v-model="form.technicianId"
|
|
|
- clearable
|
|
|
- style="width: 100%"
|
|
|
- :filterable="true"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="item in userOptions"
|
|
|
- :key="item.id"
|
|
|
- :label="item.name"
|
|
|
- :value="item.id"
|
|
|
- />
|
|
|
- </el-select>
|
|
|
- </el-form-item> -->
|
|
|
<el-form-item
|
|
|
label="审批意见"
|
|
|
|
|
|
@@ -40,33 +15,32 @@
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
<div style="margin-left: 10%; margin-bottom: 20px; font-size: 14px">
|
|
|
+ <!-- 生产主管指派节点:通过没有任何意义,必须指派技术员才能流转到下一节点 -->
|
|
|
<el-button
|
|
|
- icon="el-icon-edit-outline"
|
|
|
+ v-if="taskDefinitionKey === 'productionSupervisorApprove1'"
|
|
|
+ icon="el-icon-user"
|
|
|
type="success"
|
|
|
size="mini"
|
|
|
v-click-once
|
|
|
- @click="$refs.approvalOpinion.validate(1) && handleAudit(1)"
|
|
|
- >通过
|
|
|
+ @click="$refs.approvalOpinion.validate(1) && openAssign()"
|
|
|
+ >指派技术员
|
|
|
</el-button>
|
|
|
- <!-- <el-button
|
|
|
+ <el-button
|
|
|
+ v-else
|
|
|
icon="el-icon-edit-outline"
|
|
|
type="success"
|
|
|
size="mini"
|
|
|
- v-if="taskDefinitionKey === 'productionSupervisorApprove1'"
|
|
|
- @click="head"
|
|
|
- >指派技术员
|
|
|
- </el-button> -->
|
|
|
+ v-click-once
|
|
|
+ @click="$refs.approvalOpinion.validate(1) && handleAudit(1)"
|
|
|
+ >通过
|
|
|
+ </el-button>
|
|
|
<el-button
|
|
|
icon="el-icon-circle-close"
|
|
|
type="danger"
|
|
|
size="mini"
|
|
|
v-click-once
|
|
|
@click="$refs.approvalOpinion.validate(0) && handleAudit(0)"
|
|
|
- v-if="
|
|
|
- !['starter'].includes(
|
|
|
- taskDefinitionKey
|
|
|
- )
|
|
|
- "
|
|
|
+ v-if="!['starter'].includes(taskDefinitionKey)"
|
|
|
>驳回
|
|
|
</el-button>
|
|
|
|
|
|
@@ -76,43 +50,14 @@
|
|
|
<el-dropdown-item command="cancel">作废</el-dropdown-item>
|
|
|
</el-dropdown-menu>
|
|
|
</el-dropdown>
|
|
|
-
|
|
|
- <!-- <el-button
|
|
|
- icon="el-icon-circle-close"
|
|
|
- type="danger"
|
|
|
- size="mini"
|
|
|
- @click="handleBackList"
|
|
|
- >退回
|
|
|
- </el-button> -->
|
|
|
- <!-- <el-button
|
|
|
- icon="el-icon-circle-close"
|
|
|
- type="danger"
|
|
|
- size="mini"
|
|
|
- @click="handleAudit(0)"
|
|
|
- v-if="taskDefinitionKey != 'productionSupervisorApprove1'"
|
|
|
- >不通过
|
|
|
- </el-button>
|
|
|
- <el-button
|
|
|
- icon="el-icon-edit-outline"
|
|
|
- type="primary"
|
|
|
- size="mini"
|
|
|
- v-if="taskDefinitionKey != 'productionSupervisorApprove1'"
|
|
|
- @click="handleUpdateAssignee"
|
|
|
- >转办
|
|
|
- </el-button> -->
|
|
|
</div>
|
|
|
<head-list ref="headRef" @changeParent="changePersonel"></head-list>
|
|
|
</el-col>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
- import {
|
|
|
- updateTech,
|
|
|
- UpdateInformation,
|
|
|
- cancel
|
|
|
- } from '@/api/bpm/components/saleManage/quotation';
|
|
|
+ import { UpdateInformation } from '@/api/bpm/components/saleManage/quotation';
|
|
|
import {approveTaskWithVariables, rejectTask,cancelTask} from '@/api/bpm/task';
|
|
|
- import { listAllUserBind } from '@/api/system/organization';
|
|
|
import headList from '@/components/headList';
|
|
|
// 流程实例的详情页,可用于审批
|
|
|
export default {
|
|
|
@@ -137,99 +82,91 @@
|
|
|
data() {
|
|
|
return {
|
|
|
form: {
|
|
|
- technicianId: '',
|
|
|
reason: '同意'
|
|
|
},
|
|
|
- userOptions: []
|
|
|
+ // 指派技术员时,人员选择弹窗里选中的人
|
|
|
+ pickedUserId: ''
|
|
|
};
|
|
|
},
|
|
|
- created() {
|
|
|
- this.userOptions = [];
|
|
|
- listAllUserBind().then((data) => {
|
|
|
- this.userOptions.push(...data);
|
|
|
- });
|
|
|
- },
|
|
|
methods: {
|
|
|
- /** 处理转办审批人 */
|
|
|
- handleUpdateAssignee() {
|
|
|
- this.$emit('handleUpdateAssignee');
|
|
|
- },
|
|
|
- /** 退回 */
|
|
|
- handleBackList() {
|
|
|
- this.$emit('handleBackList');
|
|
|
- },
|
|
|
- head() {
|
|
|
- this.$refs.headRef.open();
|
|
|
+ /** 指派技术员:选人后提交(流转变量 userId) */
|
|
|
+ openAssign() {
|
|
|
+ this.pickedUserId = '';
|
|
|
+ this.$refs.headRef.open(null, 0, '指派技术员');
|
|
|
},
|
|
|
+ /** 人员选择回调 */
|
|
|
changePersonel(data) {
|
|
|
- this.form.technicianId = data.id;
|
|
|
- this.handleAudit(1, 'zp');
|
|
|
+ if (!data || !data.id) return;
|
|
|
+ this.pickedUserId = data.id;
|
|
|
+ this.handleAudit(1, 'assign');
|
|
|
},
|
|
|
async handleAudit(status, type) {
|
|
|
- //生产主管审批选择技术员
|
|
|
- // if (this.taskDefinitionKey === 'productionSupervisorApprove1') {
|
|
|
- // if (!this.form.technicianId && type == 'zp') {
|
|
|
- // this.$message.warning(`请选择技术人员!`);
|
|
|
- // return;
|
|
|
- // }
|
|
|
- // }
|
|
|
- //技术员修改
|
|
|
- // if (this.taskDefinitionKey === 'technicianApprove' && status === 1) {
|
|
|
- // let data = await this.getTableValue();
|
|
|
- // if (!arr) {
|
|
|
- // return;
|
|
|
- // }
|
|
|
- // let arr = data.map((item) => {
|
|
|
- // return {
|
|
|
- // id: item.id,
|
|
|
- // technicalAnswerId: item.technicalAnswerId,
|
|
|
- // technicalAnswerName: item.technicalAnswerName,
|
|
|
- // technicalDrawings: item.technicalDrawings,
|
|
|
- // technicalParams: item.technicalParams
|
|
|
- // };
|
|
|
- // });
|
|
|
- // try {
|
|
|
- // await updateTech(arr);
|
|
|
- // } catch (error) {}
|
|
|
- // }
|
|
|
- //销售员补充
|
|
|
- if ((this.taskDefinitionKey === 'salesmanApprove'||this.taskDefinitionKey === 'starter')&&status === 1) {
|
|
|
- let arr = await this.getTableValue();
|
|
|
- if (!arr) {
|
|
|
- return;
|
|
|
- }
|
|
|
- let data = await UpdateInformation(arr);
|
|
|
- if (data.code != '0') {
|
|
|
+ // 指派技术员必须选人:后端靠 variables.userId 决定任务交给谁
|
|
|
+ if (type === 'assign' && !this.pickedUserId) {
|
|
|
+ this.$message.warning('请选择技术人员!');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 通过时必须回写报价单:明细表里的单价/备注/附件/工艺路线等修改都要落库,
|
|
|
+ // 不能靠“是否改过单价”来判断,否则改了备注、附件这些字段就会漏调 UpdateInformation
|
|
|
+ if (status === 1) {
|
|
|
+ try {
|
|
|
+ const payload = await this.getTableValue();
|
|
|
+ // 详情组件在必填校验不通过时会返回空值(如生产交付交期没选),
|
|
|
+ // 此时表格已经弹过具体是哪个必填项,这里直接拦下不再提交审批
|
|
|
+ if (!payload) {
|
|
|
+ console.warn('报价单取值为空(校验未通过),已阻止提交审批');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const data = await UpdateInformation(payload);
|
|
|
+ if (data.code != '0') {
|
|
|
+ // 回写失败不能静默跳过,否则点通过后流程动了、修改却没保存
|
|
|
+ this.$message.error(data.message || '报价单回写失败,未提交审批');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ this.$message.error(error.message || '报价单回写失败,未提交审批');
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
- this._approveTaskWithVariables(status, this.form.technicianId, type);
|
|
|
+ this._approveTaskWithVariables(status, type);
|
|
|
},
|
|
|
- async _approveTaskWithVariables(status, technicianId, type) {
|
|
|
+ async _approveTaskWithVariables(status, type) {
|
|
|
let variables = {
|
|
|
pass: !!status
|
|
|
};
|
|
|
- if (technicianId && type == 'zp') {
|
|
|
- variables['technicianId'] = technicianId;
|
|
|
+ // 后端流程变量名是 userId(不是 technicianId):指派技术员时把选中的人带上
|
|
|
+ if (status && type === 'assign' && this.pickedUserId) {
|
|
|
+ variables['userId'] = this.pickedUserId;
|
|
|
}
|
|
|
|
|
|
+ const failText = status === 0 ? '驳回失败' : '审批失败';
|
|
|
+
|
|
|
let API = !!status ? approveTaskWithVariables : rejectTask;
|
|
|
API({
|
|
|
id: this.taskId,
|
|
|
reason: this.form.reason,
|
|
|
variables
|
|
|
- }).then((res) => {
|
|
|
- if (res.data.code != '-1') {
|
|
|
- this.$emit('handleAudit', {
|
|
|
- status,
|
|
|
- title: status === 0 ? '驳回' : ''
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
+ })
|
|
|
+ .then((res) => {
|
|
|
+ // 后端成功码是 0(其余一律视为失败),不能再只判断 -1,
|
|
|
+ // 否则遇到 -2 / 500 之类的错误码会误报成功并关掉弹窗
|
|
|
+ if (res?.data?.code == 0) {
|
|
|
+ this.$emit('handleAudit', {
|
|
|
+ status,
|
|
|
+ title: status === 0 ? '驳回' : ''
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.$message.error(res?.data?.message || failText);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ this.$message.error(failText);
|
|
|
+ });
|
|
|
},
|
|
|
|
|
|
getTableValue() {
|
|
|
return new Promise((resolve, reject) => {
|
|
|
+ // 父组件回调:data 为报价单整单数据(含 quoteProductList)
|
|
|
this.$emit('getTableValue', async (data) => {
|
|
|
resolve(await data);
|
|
|
});
|