Quellcode durchsuchen

Merge branch 'master' of http://110.41.163.243:9980/kd-aiot/aiot-app into dengfei

695593266@qq.com vor 1 Monat
Ursprung
Commit
77c8b19a46

+ 24 - 0
api/saleManage/saleorder/index.js

@@ -140,4 +140,28 @@ export async function saleordersendconfirmInfo(id) {
         return res.data;
     }
     return Promise.reject(new Error(res.message));
+}
+
+/**
+ * 查询异常列表详情
+ * @data data
+ */
+export async function exceptionmanagementInfoAPI(id) {
+    const res = await get(Vue.prototype.apiUrl+`/eom/exceptionmanagement/getById/${id}`, {});
+    if (res.code == 0) {
+        return res.data;
+    }
+    return Promise.reject(new Error(res.message));
+}
+
+/**
+ * 更新异常列表详情
+ * @data data
+ */
+export async function exceptionmanagementUpdateAPI(data) {
+    const res = await putJ(Vue.prototype.apiUrl+`/eom/exceptionmanagement/update`, data);
+    if (res.code == 0) {
+        return res.data;
+    }
+    return Promise.reject(new Error(res.message));
 }

+ 6 - 0
enum/dict.js

@@ -230,3 +230,9 @@ export const materialType = [
   { code: 1, label: "混炼料" },
   { code: 2, label: "混合料" },
 ];
+
+//来源类型
+export const relationTypeOption = {
+  1: '发货确认单',
+  2: '收货确认单'
+};

+ 8 - 0
pages.json

@@ -126,6 +126,14 @@
 				"navigationBarTextStyle": "white"
 			}
 		},
+		{ // 销售异常列表
+			"path": "pages/home/wt/components/salesExceptionDeal/processTask",
+			"style": {
+				"navigationBarTitleText": "",
+				"navigationStyle": "custom",
+				"navigationBarTextStyle": "white"
+			}
+		},
 		{
 			"path": "pages/home/wt/components/businessOpportunity/processTask",
 			"style": {

+ 186 - 0
pages/home/wt/components/salesExceptionDeal/processTask.vue

@@ -0,0 +1,186 @@
+<template>
+	<view class="havedone-container">
+		<uni-nav-bar fixed="true" statusBar="true" left-icon="back" :title="uniNavBarTitle"
+		 background-color="#157A2C" color="#fff"
+			@clickLeft="back"></uni-nav-bar>
+			<!-- <iframe src="http://aiot.zoomwin.com.cn:51001/test/a.html" style="width: 200px;height: 600px" frameborder="0"></iframe> -->
+		<view v-if="processInstance.processDefinition">
+			<taskForm id='async-biz-form-component' :taskId="listData.taskId" :businessId="listData.businessId" :id="listData.id"
+				:taskDefinitionKey="listData.taskDefinitionKey"
+				 ref="bziRef"></taskForm>
+				 
+		</view>
+		<view v-for="(item, index) in runningTasks" :key="index">
+			<div v-if="processInstance.processDefinition">
+				<taskSubmit id='async-sub-form-component' :taskId="listData.taskId" :businessId="listData.businessId" :id="listData.id"
+					:taskDefinitionKey="listData.taskDefinitionKey" @handleAudit="handleAudit"
+					@getTableValue="getTableValue" @handleUpdateAssignee="handleUpdateAssignee(item)"
+					@handleBackList="handleBackList(item)" ref="subForm">
+				</taskSubmit>
+			</div>
+		</view>
+		<u-toast ref="uToast"></u-toast>
+	</view>
+</template>
+
+<script>
+	import {
+		getProcessInstance,
+		getTaskListByProcessInstanceId
+	} from '@/api/wt/index.js'
+import Vue from 'vue'
+import taskForm from './taskForm.vue'
+import taskSubmit from './taskSubmit.vue'
+
+	export default {
+		name: 'processTask',
+		components:{ taskForm,taskSubmit },
+		data() {
+			return {
+				uniNavBarTitle: '',
+				processInstanceLoading: false,
+				listData: {},
+				processInstance: {},
+				runningTasks: [],
+				auditForms: [],
+				activeComp: null,
+			}
+		},
+
+		onLoad(option) {
+			this.listData = option
+			this.getDetail()
+			 this.activeComp = 'tab1'
+		},
+		methods: {
+			/** 获得流程实例 */
+		async	getDetail() {
+				// 获得流程实例相关
+				this.processInstanceLoading = true;
+				getProcessInstance({
+					id: this.listData.id
+				}).then(async (response) => {
+					if (!response) {
+						this.$message.error('查询不到流程信息!');
+						return;
+					}
+					// 设置流程信息 
+						this.processInstance = response;
+					this.uniNavBarTitle =`${ response.name } 【${ response.startUser?.nickname}】`
+						
+			
+					// //将业务表单,注册为动态组件
+					// Vue.component('async-biz-form-component', (resolve) => {
+					// 	require(['pages/home' + this.listData.miniHandleRouter], resolve);
+					// });
+					// Vue.component('async-sub-form-component', (resolve) => {
+					// 	require(['pages/home' + this.listData.miniViewRouter], resolve);
+					// });
+					
+				
+					this.processInstanceLoading = false;
+				});
+
+				this.runningTasks = [];
+				this.auditForms = [];
+				getTaskListByProcessInstanceId({
+					processInstanceId: this.listData.id
+				}).then((response) => {
+					console.log(response, 'response');
+					// 审批记录
+					this.tasks = [];
+					// 移除已取消的审批
+					response.forEach((task) => {
+						if (task.result !== 4) {
+							this.tasks.push(task);
+						}
+					});
+					// 排序,将未完成的排在前面,已完成的排在后面;
+					this.tasks.sort((a, b) => {
+						// 有已完成的情况,按照完成时间倒序
+						if (a.endTime && b.endTime) {
+							return b.endTime - a.endTime;
+						} else if (a.endTime) {
+							return 1;
+						} else if (b.endTime) {
+							return -1;
+							// 都是未完成,按照创建时间倒序
+						} else {
+							return b.createTime - a.createTime;
+						}
+					});
+
+					// 需要审核的记录
+					let userInfo = wx.getStorageSync("userInfo");
+					this.tasks.forEach((task) => {
+						if (task.result !== 1 && task.result !== 6) {
+							// 只有待处理才需要
+							return;
+						}
+						if (!task.assigneeUser || task.assigneeUser.id !== userInfo.userId) {
+							// 自己不是处理人
+							return;
+						}
+						if (task.taskDefinitionKey !== this.listData.taskDefinitionKey) {
+							// 不是当前流程的
+							return;
+						}
+						this.runningTasks.push({
+							...task
+						});
+						console.log(this.runningTasks, ' this.runningTasks');
+						this.auditForms.push({
+							reason: ''
+						});
+					});
+				});
+			},
+
+
+			/** 处理审批通过和不通过的操作 */
+			handleAudit(data) {
+				let text = data.status === 1 ? '通过' : '不通过';
+				this.$refs.uToast.show({
+					type: 'success',
+					message: `审批${data.title || text}成功!`,
+					iconUrl: 'https://cdn.uviewui.com/uview/demo/toast/success.png'
+				})
+				// 获得最新详情
+				setTimeout(() => {
+				
+					uni.navigateBack()
+				}, 1000)
+
+
+				// const index = this.runningTasks.indexOf(task);
+				// this.$refs['form' + index][0].validate((valid) => {
+				//   if (!valid) {
+				//     return;
+				//   }
+				//   const data = {
+				//     id: task.id,
+				//     reason: this.auditForms[index].reason
+				//   };
+				//   if (pass) {
+				//     approveTask(data).then((response) => {
+				//       this.$message.success('审批通过成功!');
+				//       this.handleClose(); // 获得最新详情
+				//     });
+				//   } else {
+				//     rejectTask(data).then((response) => {
+				//       this.$message.success('审批不通过成功!');
+				//       this.handleClose(); // 获得最新详情
+				//     });
+				//   }
+				// });
+			},
+			getTableValue(fn) {
+				fn(this.$refs.bziRef.getTableValue());
+			}
+		}
+
+	}
+</script>
+
+<style>
+</style>

+ 307 - 0
pages/home/wt/components/salesExceptionDeal/taskForm.vue

@@ -0,0 +1,307 @@
+<template>
+	<view class="">
+		<u-sticky offset-top="50">
+			<u-subsection fontSize='25' mode='subsection' :list="list" :current="curNow" @change="sectionChange"
+				activeColor='#157A2C'></u-subsection>
+		</u-sticky>
+		<view v-show='curNow===0'>
+			<u--form style="margin: 0 20px;" labelPosition="left" :model="form" ref="uForm" labelWidth='200rpx' :rules="rules">
+				<u-form-item label="编码" prop="code" borderBottom>
+					{{ form.code || '-' }}
+				</u-form-item>
+				<u-form-item label="名称" prop="name" borderBottom>
+					{{ form.name || '-' }}
+				</u-form-item>
+				<u-form-item label="来源类型" prop="relationTypeName" borderBottom>
+					{{ form.relationTypeName || '-' }}
+				</u-form-item>
+				<u-form-item label="来源编码" prop="relationCode" borderBottom>
+					{{ form.relationCode || '-' }}
+				</u-form-item>
+				<u-form-item label="来源名称" prop="relationName" borderBottom>
+					{{ form.relationName || '-' }}
+				</u-form-item>
+				<u-form-item label="创建人" prop="createUserName" borderBottom>
+					{{ form.createUserName || '-' }}
+				</u-form-item>
+				<u-form-item label="创建时间" prop="createTime" borderBottom>
+					{{ form.createTime || '-' }}
+				</u-form-item>
+			</u--form>
+		</view>
+		<view v-show='curNow===1'>
+			<view v-for="(item, index) in form.detailList" :key="index">
+				<view class="product-card">
+					<view class="card-header">
+						<text class="product-name">{{ item.productName || '物品' + (index + 1) }}</text>
+						<text class="product-price">{{ item.productCode || '-' }}</text>
+					</view>
+					<view class="card-body">
+						<view class="info-row">
+							<text class="info-label">异常类型:</text>
+							<uni-data-select v-model="item.exceptionDetermine" :localdata="exceptionDetermineOptions"></uni-data-select>
+						</view>
+						<view class="info-row">
+							<text class="info-label">处置方式:</text>
+							<uni-data-select v-model="item.exceptionDispose" :localdata="exceptionDisposeOptions"></uni-data-select>
+						</view>
+						<view class="info-row" v-for="(field, idx) in tableField.filter(f => f.field !== 'exceptionDetermine' && f.field !== 'exceptionDispose')" :key="idx">
+							<text class="info-label">{{ field.label }}:</text>
+							<text class="info-value">{{ formatValue(item, field) }} {{ field.unit || '' }}</text>
+						</view>
+					</view>
+				</view>
+			</view>
+			<u-empty v-if="!list || list.length === 0" text="暂无物品清单" marginTop="100"></u-empty>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		exceptionmanagementInfoAPI
+	} from '@/api/saleManage/saleorder/index.js'
+	import fileMain from "@/pages/doc/index.vue"
+	import commonProductList from "../common/commonProductList.vue"
+	import { mapGetters } from 'vuex'
+	import {transactionMethodsOp,shippingModeOp,shippingModePurchaseOp, pricingWayList, levelList, quoteTypeOp, relationTypeOption} from '@/enum/dict.js'
+	export default {
+		components: {
+			fileMain,
+			commonProductList
+		},
+		props: {
+			businessId: {
+				default: ''
+			},
+			taskDefinitionKey: {
+				default: ''
+			},
+		},
+		// 暴露方法给父组件调用
+		expose: ['validateDetailList', 'form'],
+		computed: {
+			...mapGetters(['getDictValue']),
+			exceptionDetermineOptions() {
+				return this.form.relationType == 1
+				? [
+					{ text: '多发', value: '1' },
+					{ text: '少发', value: '2' },
+					{ text: '错发', value: '3' },
+					{ text: '损坏', value: '4' }
+					]
+				: [
+					{ text: '多收', value: '1' },
+					{ text: '少收', value: '2' },
+					{ text: '错收', value: '3' },
+					{ text: '损坏', value: '4' }
+					];
+			},
+			tableField() {
+				return [
+					// { label: '异常类型', field: 'exceptionDetermine' },
+					// { label: '处置方式', field: 'exceptionDispose' },
+					{ label: '规格', field: 'specification' },
+					{ label: '型号', field: 'modelType' },
+					{ label: '批次号', field: 'batchNo' },
+					{ label: '发货条码', field: 'barcodes' },
+					{ label: '物料代号', field: 'materielDesignation' },
+					{ label: this.form.relationType == 1 ? '客户代号' : '供应商代号', field: 'clientCode' },
+					{ label: '客户代号', field: 'customerMark' },
+					{ label: '刻码', field: 'engrave' },
+					{ label: '包装规格', field: 'packingSpecification' },
+					{ label: '机型', field: 'modelKey' },
+					{ label: '颜色', field: 'colorKey' },
+					{ label: '异常数量', field: 'totalCount' },
+					{ label: '描述', field: 'describes' },
+				]
+			},
+
+		},
+		data() {
+			return {
+				form: {},
+				list: ['基本信息', '物品清单'],
+				curNow: 0,
+				rules: {
+					// 可添加基础表单校验规则
+				},
+				exceptionDisposeOptions: [
+					{ text: '退货入库', value: '1' },
+					{ text: '返工返修', value: '2' },
+					{ text: '报损', value: '3' },
+					{ text: '报废', value: '4' }
+				],
+				
+			}
+		},
+		async mounted() {
+			await this.getDetailData(this.businessId);
+		},
+		methods: {
+			// 格式化字段值
+			formatValue(item, field) {
+				let value = item[field.field]
+				// 数量字段显示单位
+				if (field.field === 'saleCount') {
+					const unit = item.saleUnit || ''
+					return value ? value + (unit ? ' ' + unit : '') : '-'
+				}
+				// 计量数量字段显示单位
+				if (field.field === 'totalCount') {
+					const unit = item.measuringUnit || ''
+					return value ? value + (unit ? ' ' + unit : '') : '-'
+				}
+				// 单重字段显示单位
+				if (field.field === 'singleWeight') {
+					const unit = item.weightUnit || ''
+					return value ? value + (unit ? ' ' + unit : '') : '-'
+				}
+				// 总重字段显示单位
+				if (field.field === 'totalWeight') {
+					const unit = item.weightUnit || ''
+					return value ? value + (unit ? ' ' + unit : '') : '-'
+				}
+				// 增重重量字段显示单位
+				if (field.field === 'increaseTotalWeight') {
+					const unit = item.weightUnit || ''
+					return value ? value + (unit ? ' ' + unit : '') : '-'
+				}
+				// 计价方式特殊处理
+				if (field.type === 'pricingWay') {
+					const found = pricingWayList.find(p => p.id === value)
+					return found ? found.name : '-'
+				}
+				// 收货状态特殊处理
+				if (field.field === 'isException') {
+					return value == 1 ? '有异常' : '无异常'
+				}
+				if (field.field === 'packingQuantity') { 
+					const unit = item.packingUnit || ''
+					return value ? value + (unit ? ' ' + unit : '') : '-'
+				}
+				if (field.field === 'type') {
+					return value == 1 ? '已回收' : '未回收'
+				}
+				// 字典类型处理
+				if (field.type === 'dict') {
+					return this.getDictValue(field.dictName, value) || '-'
+				}
+				return value || '-'
+			},
+			sectionChange(index) {
+				this.curNow = index;
+			},
+			async getDetailData(id) {
+				const data = await exceptionmanagementInfoAPI(id);
+				data.relationTypeName = relationTypeOption[data.relationType] || '-';
+				// 初始化明细列表的异常类型和处置方式
+				if (data.detailList && data.detailList.length > 0) {
+					data.detailList.forEach(item => {
+						item.exceptionDetermine = item.exceptionDetermine ? String(item.exceptionDetermine) : ''
+						item.exceptionDispose = item.exceptionDispose ? String(item.exceptionDispose) : ''
+					})
+				}
+				this.form = data;
+			},
+			// 校验明细列表
+			validateDetailList() {
+				return new Promise((resolve, reject) => {
+					if (!this.form.detailList || this.form.detailList.length === 0) {
+						resolve()
+						return
+					}
+					for (let i = 0; i < this.form.detailList.length; i++) {
+						const item = this.form.detailList[i]
+						if (!item.exceptionDetermine) {
+							uni.showToast({ title: `第${i + 1}条物品的异常类型不能为空`, icon: 'none' })
+							reject(new Error('异常类型不能为空'))
+							return
+						}
+						if (!item.exceptionDispose) {
+							uni.showToast({ title: `第${i + 1}条物品的处置方式不能为空`, icon: 'none' })
+							reject(new Error('处置方式不能为空'))
+							return
+						}
+					}
+					resolve()
+				})
+			},
+			getTableValue() {
+				return new Promise(async (resolve, reject) => {
+					try {
+						await this.validateDetailList()
+						// await this.$refs.outForm[0].validate()
+						resolve(this.form)
+					} catch {
+						reject(null)
+					}
+
+
+				})
+			},
+		}
+	}
+</script>
+
+<style scoped>
+.btnConcel {
+		margin-top: 20rpx;
+	}
+.product-card {
+	margin: 20rpx;
+	padding: 20rpx;
+	background: #fff;
+	border-radius: 12rpx;
+	box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
+}
+
+.card-header {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	padding-bottom: 16rpx;
+	border-bottom: 1rpx solid #eee;
+	margin-bottom: 16rpx;
+}
+
+.product-name {
+	font-size: 28rpx;
+	font-weight: bold;
+	color: #333;
+}
+
+.product-price {
+	font-size: 26rpx;
+	/* color: #157a2c; */
+	/* font-weight: bold; */
+}
+
+.card-body {
+	display: flex;
+	flex-wrap: wrap;
+}
+
+.info-row {
+	width: 50%;
+	display: flex;
+	padding: 8rpx 0;
+	box-sizing: border-box;
+	align-items: center;
+	padding-right: 10rpx;
+}
+
+.info-label {
+	color: #666;
+	font-size: 26rpx;
+	flex-shrink: 0;
+}
+
+.info-value {
+	color: #333;
+	font-size: 26rpx;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+}
+</style>

+ 152 - 0
pages/home/wt/components/salesExceptionDeal/taskSubmit.vue

@@ -0,0 +1,152 @@
+<template>
+	<view class="">
+		<u--form style="margin: 0 20px;" labelPosition="left" :model="form" :rules="rules" ref="uForm"
+			labelWidth='140rpx'>
+			<u-form-item label="审批建议" prop="reason" required>
+				<u--textarea style="width: 100%;" height='120' border='surround' placeholder="请输入审批建议"
+					v-model="form.reason"></u--textarea>
+			</u-form-item>
+		</u--form>
+		<view class="btnList">
+			<u-button style="width: 45%;margin-bottom: 10rpx;" :loading='loading' type="success" text="通过"
+				@click="handleAudit(1)">
+			</u-button>
+			<u-button style="width: 45%;" :loading='loading' type="error" text="驳回" @click="handleAudit(0)"></u-button>
+		</view>
+		<view class="btnConcel">
+			<u-button @click="showAction = true">更多</u-button>
+		</view>
+		<u-action-sheet :actions="actionList" :closeOnClickOverlay="true" :closeOnClickAction="true" title="更多操作" :show="showAction" @close="showAction = false" @select="selectActionClick"></u-action-sheet>
+	</view>
+</template>
+
+<script>
+	import {
+		approveTaskWithVariables,
+		rejectTask,
+		cancelTask
+	} from '@/api/wt/index.js'
+	import { exceptionmanagementUpdateAPI } from '@/api/saleManage/saleorder/index.js'
+	export default {
+		name: 'taskSubmit',
+		props: {
+			businessId: {
+				default: ''
+			},
+			taskId: {
+				default: ''
+			},
+			id: {
+				default: ''
+			},
+			taskDefinitionKey: {
+				default: ''
+			}
+		},
+
+		data() {
+			return {
+				showAction: false,
+				loading: false,
+				actionList: [{
+					name: '作废',
+					fontSize: '28',
+					color: '#ffaa7f'
+				}],
+				form: {
+					technicianId: '',
+					reason: '同意',
+				},
+				rules: {
+					reason: {
+						type: 'string',
+						required: true,
+						message: '请输入审批建议',
+						trigger: 'blur'
+					}
+				}
+			}
+		},
+		mounted() {
+			this.$refs.uForm.setRules(this.rules)
+		},
+		methods: {
+			selectActionClick(item) {
+				console.log('selectActionClick', item)
+				if (item.name == '作废') {
+					uni.showModal({
+						title: '提示',
+						content: '是否确认作废?',
+						success: (res) => {
+							if (res.confirm) {
+								this.loading = true
+								cancelTask({
+									taskId: this.taskId,
+									id: this.id,
+									reason: this.form.reason,
+									businessId: this.businessId,
+								}).then(() => {
+									if (res.code != '-1') {
+										this.loading = false
+										this.$emit('handleAudit', {
+											title: '作废'
+										});
+									}
+								}).catch(() => {
+									this.loading = false
+									this.$message.error("流程作废失败");
+								});
+							} else if (res.cancel) {
+								console.log('用户点击取消');
+							}
+						}
+					});
+				}
+			},
+			async handleAudit(status) {
+				let res = await this.getTableValue();
+				console.log(res, 'res');
+				if (!!status) await this.$refs.uForm.validate()
+				this.loading = true
+				await exceptionmanagementUpdateAPI(res)
+				await this._approveTaskWithVariables(status);
+			},
+			async _approveTaskWithVariables(status) {
+				let variables = {
+					pass: !!status
+				};
+				const requestUrl = !!status ? approveTaskWithVariables : rejectTask;
+				let res = await requestUrl({
+					id: this.taskId,
+					reason: this.form.reason,
+					variables
+				})
+
+				if (res.code != '-1') {
+					this.$emit('handleAudit', {
+						status,
+						title: status === 0 ? '驳回' : ''
+					});
+				}
+				this.loading = false
+			},
+			getTableValue() {
+				return new Promise((resolve, reject) => {
+					this.$emit('getTableValue', async (data) => {
+						resolve(await data);
+					});
+				});
+			}
+		}
+	}
+</script>
+
+<style scoped>
+	.btnList {
+		display: flex;
+
+	}
+	.btnConcel {
+		margin-top: 20rpx;
+	}
+</style>

+ 5 - 2
pages/home/wt/components/salesInvoiceConfirm/taskForm.vue

@@ -36,10 +36,10 @@
 				<u-form-item label="发货单编码" prop="sendNo" borderBottom>
 					{{ form.sendNo || '-' }}
 				</u-form-item>
-				<u-form-item label="回执附件" prop="repliedFiles" borderBottom>
+				<u-form-item :label="clientEnvironmentId == 6 ? '契约锁签收回执' : '回执附件'" prop="repliedFiles" borderBottom>
 					<fileMain v-model="form.repliedFiles" type="view"></fileMain>
 				</u-form-item>
-				<u-form-item label="是否回执" prop="replied" borderBottom>
+				<u-form-item :label="clientEnvironmentId == 6 ? '契约锁是否签收' : '是否回执'" prop="replied" borderBottom>
 					{{ form.replied == 1 ? '是' : '否' }}
 				</u-form-item>
 				<u-form-item label="审核状态" prop="reviewStatus" borderBottom>
@@ -84,6 +84,9 @@
 				form: {},
 				list: ['基本信息', '物品清单', '托盘清单'],
 				curNow: 0,
+				clientEnvironmentId:
+					uni.getStorageSync("userInfo") &&
+					uni.getStorageSync("userInfo").clientEnvironmentId,
 				tableField: [
 					{ label: '类型', field: 'productCategoryName' },
 					{ label: '批次号', field: 'batchNo' },