<template>
	<a-modal
		:title='title'
		:visible='visible'
		:mask-closable='false'
		:confirmLoading='okLoading'
		destroyOnClose
		@cancel='handleCancel'
		@ok='handleOk'
		width='80%'
	>
		<a-tabs default-active-key='1' tab-position='left'>
			<a-tab-pane key='1' :tab="$t('dvp.process-instance')">
				<a-form layout='vertical' :form='form'>
					<!-- 流程信息 -->
					<a-card :title="$t('dvp.process-information')">
						<a-row :gutter='24' style="padding: 12px;">
							<a-col :xl='8' :lg='12' :md='12' :sm='24' :xs='24'>
								<a-form-item :label="$t('dvp.approval-process')">
									<a-select
										:placeholder="$t('dvp.please-select-the-approval-process')"
										@change='handleProcessChange'
										v-decorator="[
											'process',
											{
												rules: [
													{
														required: true,
														message: $t('dvp.please-select-the-approval-process')
													}
												]
											},
										]"
									>
										<a-select-option
											v-for='(process, index) in processList'
											:key='index'
											:value='process.id'
										>
											{{ process.displayName }}
										</a-select-option>
									</a-select>
								</a-form-item>
							</a-col>
						</a-row>
						<!-- 延期申请 -->
						<div v-if='inputArgs.delayFlag'>
							<a-row :gutter='24'>
								<a-col :xl='8' :lg='12' :md='12' :sm='24' :xs='24'>
									<a-form-item :label='delay.tgLabel'>
										<a-input
											read-only
											:value='delay.tgTime'
										/>
									</a-form-item>
								</a-col>
							</a-row>
							<a-row :gutter='24'>
								<a-col :xl='8' :lg='12' :md='12' :sm='24' :xs='24'>
									<a-form-item :label="$t('dvp.extended-until')">
										<a-date-picker
											style='width: 100%'
											:placeholder="$t('dvp.select-time')"
											@change='handleToTgTime'
											:disabled-date='handleDisabledToTgTime'
											v-decorator="[
												'delay.toTgTime',
												{
													rules: [
														{
															required: true,
															message: $t('dvp.select-time')
														}
													]
												},
											]"
										/>
									</a-form-item>
								</a-col>
							</a-row>
							<a-row :gutter='24'>
								<a-col :xl='8' :lg='12' :md='12' :sm='24' :xs='24'>
									<a-form-item :label="$t('dvp.reasons-for-extension-request')">
										<a-textarea
											allowClear
											:placeholder="$t('dvp.enter-delay-apply-reason')"
											@change='handleReason'
											:rows='4'
											:maxLength='255'
											v-decorator="[
												'delay.reason',
												{
													rules: [
														{
															required: true,
															message: $t('dvp.enter-delay-apply-reason')
														}
													]
												},
											]"
										/>
									</a-form-item>
								</a-col>
							</a-row>
						</div>
					</a-card>
					<br />
					<!-- 审批人 -->
					<a-card v-if='userTaskFlag' :title="$t('dvp.approver')" class='mt10'>
						<a-row
							:gutter='24'
							v-for='(userTask, index) in userTaskList'
							:key='userTask.key'
							style="padding:12px;"
						>
							<a-col :xl='8' :lg='12' :md='12' :sm='24' :xs='24'>
								<a-form-item
									:label='userTask.name'
									:required='userTask.required'
								>
									<a-select
										:placeholder="$t('dvp.please-select-approver')"
										:filter-option='handleFilterOption'
										@change='handleUserChange($event, userTask)'
										@search='handleUserSearch'
										allowClear
										showSearch
										:disabled="userTask.isDisabled"
										v-decorator="[
											'userName'+ userTask.key,
											{
												rules: [
													{
														required: userTask.required,
														message: $t('dvp.please-select-approver')
													}
												],
												initialValue: userTask.isDisabled ? partDvpDefault(userTask) : undefined
											},
										]"
									>
										<a-icon slot='suffixIcon' type='search' />
										<a-select-option
											v-for='(user, uIndex) in userList'
											:key='uIndex'
											:value='user.value'
										>
											{{ user.name }}
										</a-select-option>
									</a-select>
								</a-form-item>
							</a-col>
							<a-col :xl='8' :lg='12' :md='12' :sm='24' :xs='24'>
								<a-form-item :label="'\xa0'">
									<a-button
										v-if='userTask.required'
										type='primary'
										shape='circle'
										icon='plus'
										:disabled="userTask.isDisabled"
										@click='add(userTask.key)'
									/>
									<a-button
										v-else
										type='dashed'
										shape='circle'
										icon='minus'
										:disabled="userTask.isDisabled"
										@click='remove(userTask.key)'
									/>
								</a-form-item>
							</a-col>
						</a-row>
					</a-card>
				</a-form>
			</a-tab-pane>
			<a-tab-pane key='2' :tab="$t('dvp.flow-chart')" force-render>
				<SnakerFlowDesigner
					style='height: 65vh'
					ref='designer'
					:viewer='true'
					:value='process'
				/>
			</a-tab-pane>
		</a-tabs>
	</a-modal>
</template>

<script>

import { delCookie, setCookie } from '@/utils/util';
import { snakerXml2LogicFlowJson } from '@/components/SnakerFlowDesigner/src/snakerflow/tool';
import { v4 as uuidv4 } from 'uuid';
import moment from 'moment';
import utils from '@/utils/urlParamUtil';

export default {
	name: 'SubmitApprovalModal',
	props: {
		visible: {
			type: Boolean,
			default: false
		},
		title: {
			type: String,
			default: ''
		},
		rfmeaType: {
			type: String,
			default: ''
		}
	},
	components: {},
	data() {
		return {
			/** 输入参数 */
			inputArgs: {},
			/** 流程定义 */
			process: {
				/** XML数据 */
				xml: '',
				/** 流程ID */
				processId: ''
			},
			/** 用户集合 */
			userList: [],
			/** 零部件dvp内置审批信息 */
			userListForPart: [],
			/** 材料工程师信息 */
			materialsEngineerInfo: undefined,
			/** 试验工程师信息 */
			testEngineerInfo: undefined,
			/** 表单创建 */
			form: this.$form.createForm(this, { name: 'dynamic_rule' }),
			/** 用户任务集合 */
			userTaskList: [],
			/** 按钮【确定】loading */
			okLoading: false,
			/** 流程集合 */
			processList: [],
			/** 用户节点标识，用于创建销毁 */
			userTaskFlag: false,
			/** 延期信息 */
			delay: {
				/** 延期tg名称 */
				tgLabel: '',
				/** 延期tg时间 */
				tgTime: undefined,
				/** 延期至时间 */
				toTgTime: undefined,
				/** 延期原因 */
				reason: undefined
			},
			/** 不接受原因 */
			rejectReason: undefined
		};
	},
	watch: {
		visible(val) {
			if (val) {
				this.userTaskList = [];
				this.getWfProcessList();
				this.handleUserSearch();
				// 零部件DVP 计划/验证审批
				if (this.inputArgs.approveType === '71') {
					// 材料工程师
					this.handleUserSearchForPart(this.inputArgs.materialsEngineerId, 1);
					// 试验工程师
					this.handleUserSearchForPart(this.inputArgs.testEngineerId, 2);
				}
				// 获取延期信息
				if (this.inputArgs.delayFlag) {
					this.getDelayInfo();
				}
			} else {
				this.handleCancel();
			}
		}
	},
	methods: {
		/**
		 * 处理关闭模态框
		 */
		handleCancel() {
			this.userTaskFlag = false;
			this.$emit('close');
		},
		/**
		 * 处理确定
		 */
		async handleOk() {
			let _that = this;
			// 校验
			let flag = false;
			_that.form.validateFields(err => {
				if (!err) {
					flag = true;
				}
			});
			if (!flag) {
				return;
			}

			/****************************** 参数处理 ******************************************/

				// 处理数组分组，按照groupKey
			let arrayGroup = _that.handleArrayGroup('groupKey', this.userTaskList);
			// 处理提交审批参数，逗号拼接
			let args = _that.handleSaveArgs(arrayGroup);

			/****************************** 参数处理 ******************************************/


      // 启动流程之前，先保存变更记录信息

      // 零部件DVP 申请变更 保存 要在选完审批人后
      if (_that.inputArgs.approveType === '61' && _that.inputArgs.dvpType === '2') {
        await _that.$api.partDvpApplyChange(_that.inputArgs.data).then( res => {
          if (res.flag) {
            _that.$message.success(res.message);
            _that.$emit("closeModal")
          } else {
            _that.$message.error(res.message);
          }
        });
      }

      // 系统DVP 申请变更 保存 要在选完审批人后
      if (_that.inputArgs.approveType === '57' && _that.inputArgs.dvpType === '1') {
        await _that.$api.systemApplyChange(_that.inputArgs.data).then( res => {
          if (res.flag) {
            _that.$message.success(res.message);
            _that.$emit("closeModal")
          } else {
            _that.$message.error(res.message);
          }
        });
      }
      // 整车DVP 申请变更 保存 要在选完审批人后
      if (_that.inputArgs.approveType === '52' && _that.inputArgs.dvpType === '0') {
       await _that.$api.applyChange(_that.inputArgs.data).then( res => {
          if (res.flag) {
            _that.$message.success(res.message);
            _that.$emit("closeModal")
          } else {
            _that.$message.error(res.message);
          }
        });
      }

			_that.okLoading = true;
			// 启动流程定义
			let url = '/DFMEA/dvp/approve/start.do';
      _that.$api.post(url, {
				businessId: _that.inputArgs.dvpId ? _that.inputArgs.dvpId: _that.inputArgs.taskId, /** dvp标识 */
				/** 审批类型---
				 * 70 = dvp部门审批（整车、系统）
         * 71 = 零部件DVP 计划/验证审批
         * 52 = 整车dvp申请变更审批
				 * 57 = 系统dvp申请变更审批
				 * 61 = 零部件dvp申请变更审批
         * */
				approveType: _that.inputArgs.approveType,
				yqDate: _that.delay.toTgTime, /** 延期时间 */
				reason: _that.delay.reason, /** 延期原因 */
				dvpType: _that.inputArgs.dvpType, /** dvp类型 0:整车性能DVP 1:系统DVP 2:零部件DVP */
				processId: _that.process.processId, /** 流程ID */
				args: JSON.stringify(args), /** 参数 */
				taskId: _that.inputArgs.taskId,/**任务id*/
				testId: _that.inputArgs.testId,/**试验id*/
			}).then((res) => {
				if (res.flag) {
					_that.$notification.success({ message: res.message });
					// 关闭弹出框
					_that.handleCancel();
					// 返回上一级页面
					_that.backToList();
				} else {
					_that.$notification.error({ message: res.message });
				}
			}).finally(() => {
				_that.okLoading = false;
			});
		},
		/**
		 * 获取流程定义列表
		 */
		getWfProcessList() {
			let _that = this;
			_that.$api.getWfProcessList({
				pageNum: 1, /** 每几页 */
				pageSize: 100, /** 每页大小 */
				state: 1, /** 流程定义状态 */
				approvalType: _that.inputArgs.approveType /** 审批类型 */
			}).then(res => {
				if (res.flag) {
					_that.processList = res.data.data;
				} else {
					_that.$notification.error({ message: res.message });
				}
			});
		},
		/**
		 * 获取延期信息
		 */
		getDelayInfo() {
			let _that = this;
			let url = _that.rfmeaType === 'D' ? '/DFMEA/projectDFMEA/getPrepareApplyDelayDetails.do' :
				'/DFMEA/projectPFMEA/getPrepareApplyDelayDetails.do';
			_that.$api.post(url, {
				dvpId: _that.inputArgs.dvpId
			}).then(res => {
				if (res.flag) {
					_that.inputArgs.approveType = 12 + Number(res.data.displayFlag);
					_that.delay.tgTime = res.data.displayFlag === '1' ? res.data.partTg1Time : res.data.partTg2Time;
					_that.delay.tgLabel = res.data.displayFlag === '1' ? _that.$t('dvp.part-planning-process-time') :
						_that.$t('dvp.part-planning-formal-time');
				} else {
					_that.$notification.error({ message: res.message });
				}
			});
		},
		/**
		 * 处理审批流程选择
		 */
		handleProcessChange(val) {
			let _that = this;
			_that.process.processId = val;
			_that.$api.getWfXml({
				id: val
			}).then(res => {
				if (res.flag) {
					_that.userTaskList = [];
					_that.userTaskFlag = false;
					_that.process.xml = res.data;
					let tranData = snakerXml2LogicFlowJson(_that.process.xml);
					if (tranData.nodes) {
						let nodes = tranData.nodes;
						for (let i = 0; i < nodes.length; i++) {
							let node = nodes[i];
							// 取到任务节点
							if (node.type === 'snaker:task') {
								let userTask = {
									key: uuidv4(),
									groupKey: uuidv4(),
									name: node.text,
									required: true,
									isDisabled: false
								};
								userTask[node.properties.assignee] = node.properties.assignee;
								_that.userTaskList.push(userTask);
							}
						}
						// 零部件DVP 计划/验证审批内置试验工程师、材料工程师审批
						if (_that.inputArgs.approveType === '71') {
							// 材料工程师审批节点
							let materialsEngineerTask = _that.userTaskList[_that.userTaskList.length - 1];
							// 材料工程师/试验工程师审批步骤不可修改
							materialsEngineerTask.isDisabled = true;
							_that.handleUserChange(_that.inputArgs.materialsEngineerId, materialsEngineerTask, 1);
							// 添加审批人
							_that.add(materialsEngineerTask.key);
							// 试验工程师审批节点
							let testEngineerTask = _that.userTaskList[_that.userTaskList.length - 1];
							_that.handleUserChange(_that.inputArgs.testEngineerId, testEngineerTask, 2);
						}
					}
				} else {
					_that.$notification.error({ message: res.message });
				}
			}).finally(() => {
				_that.userTaskFlag = true;
			});
		},
		/**
		 * 处理过滤配置
		 * @param input
		 * @param option
		 */
		handleFilterOption(input, option) {
			return (
				option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
			);
		},
		/**
		 * 零部件计划/验证审批，材料工程师/试验工程师默认设置
		 * @param userTask 审批任务节点
		 */
		partDvpDefault(userTask) {
			let keys = Object.keys(userTask);
			let key = keys.filter(key => {
				return key.indexOf('userTaskName') !== -1;
			});
			return userTask[key];
		},
		/**
		 * 处理用户选择
		 * @param val 选择用户ID
		 * @param userTask 用户任务节点
		 *  @param num 1 材料工程师 2 试验工程师
		 */
		handleUserChange(val, userTask, num) {
			let keys = Object.keys(userTask);
			let k = '', v = '';
			keys = keys.filter(key => {
				return key.indexOf('userTask') !== -1;
			});
			k = keys[0];
			if (keys && keys.length > 1) {
				v = keys[1];
			}
			userTask[k] = val;
			if (!v) {
				v = k.replaceAll('userTask', 'userTaskName');
			}
			// 零部件DVP 计划/验证审批
			if (this.inputArgs.approveType === '71') {
				this.$nextTick(() => {
					userTask[v] = num === 1 ? this.materialsEngineerInfo.name : this.testEngineerInfo.name;
				});
			} else {
				this.userList.forEach(item => {
					if (item.value === val) {
						userTask[v] = item.name;
					}
				});
				this.handleUserSearch(undefined);
			}
		},
		/**
		 * 处理用户检索
		 * @param val 输入值
		 */
		handleUserSearch(val) {
			let _that = this;
				_that.$api.getUserPageList({
					pageNo: 1,
					pageSize: 10,
					userName: val
				}).then(res => {
					if (res.flag) {
						let resData = res.data.data;
						_that.userList = [];
						_that.userList = resData.map(item => {
							return {
								name: item.userName + '/' + item.account + '/' + item.departmentName,
								value: item.userId
							};
						});
					} else {
						_that.$notification.error({ message: res.message });
					}
				});
		},
		/**
		 * 零部件dvp材料工程师/试验工程师信息检索
		 * @param val userId
		 * @param num 1 材料工程师 2 试验工程师
		 */
		handleUserSearchForPart(val, num) {
			let _that = this;
				_that.$api.getUserPageList({
					pageNo: 1,
					pageSize: 10,
					userId: val
				}).then(res => {
					if (res.flag) {
						let resData = res.data.data;
						_that.userListForPart = [];
						_that.userListForPart = resData.map(item => {
							return {
								name: item.userName + '/' + item.account + '/' + item.departmentName,
								value: item.userId
							};
						});
						if (num === 1) {
							// 材料工程师
							_that.materialsEngineerInfo = _that.userListForPart[0];
						} else {
							// 试验工程师
							_that.testEngineerInfo = _that.userListForPart[0];
						}
					} else {
						_that.$notification.error({ message: res.message });
					}
				});
		},
		/**
		 * 处理延期至 -- 时间选择变化
		 * @param date
		 * @param dateString
		 */
		handleToTgTime(date, dateString) {
			this.delay.toTgTime = dateString;
		},
		/**
		 * 处理延期原因 -- 输入变化
		 * @param e
		 */
		handleReason(e) {
			this.delay.reason = e.target.value;
		},
		/**
		 * 处理延期至 -- 禁用时间
		 * @param current
		 */
		handleDisabledToTgTime(current) {
			// Can not select days before today and today
			return current && current < moment(this.delay.tgTime).endOf('day');
		},
		/**
		 * 添加
		 * @param key 标识
		 */
		add(key) {
			for (let i = 0; i < this.userTaskList.length; i++) {
				let userTask = this.userTaskList[i];
				if (userTask.key === key) {
					let target = {};
					Object.assign(target, this.userTaskList[i]);
					target['required'] = false;
					target['key'] = uuidv4();
					let keys = Object.keys(target);
					let k = '', v = '';
					keys = keys.filter(key => {
						return key.indexOf('userTask') !== -1;
					});
					if (keys && keys.length === 2) {
						if (keys[1].indexOf('userTaskName') !== -1) {
							v = keys[1];
							k = keys[0];
						} else {
							v = keys[0];
							k = keys[1];
						}
					} else if (keys && keys.length === 1) {
						k = keys[0];
					}
					if (k) {
						target[k] = '';
					}
					if (v) {
						target[v] = '';
					}
					this.userTaskList.splice(i + 1, 0, target);
				}
			}
		},
		/**
		 * 删除
		 * @param key 标识
		 */
		remove(key) {
			this.userTaskList = this.userTaskList.filter(v => {
				return key !== v.key;
			});
		},
		/**
		 * 处理提交审批参数
		 * @param arrayGroup 数组分组
		 */
		handleSaveArgs(arrayGroup) {
			let newArr = [];
			for (let i = 0; i < arrayGroup.length; i++) {
				let arr = arrayGroup[i];
				let newObj = {};
				if (arr && arr.length > 0) {
					Object.assign(newObj, arr[0]);
					let keys = Object.keys(newObj);
					let k = '', v = '';
					keys = keys.filter(key => {
						return key.indexOf('userTask') !== -1;
					});
					if (keys && keys.length === 2) {
						if (keys[1].indexOf('userTaskName') !== -1) {
							v = keys[1];
							k = keys[0];
						} else {
							v = keys[0];
							k = keys[1];
						}
					}
					let kVal = [], vVal = [];
					for (let j = 0; j < arr.length; j++) {
						// 保证值不为空
						if (arr[j][k]) {
							kVal.push(arr[j][k]);
							vVal.push(arr[j][v]);
						}
					}
					if (k) {
						newObj[k] = kVal.toString();
					}
					if (v) {
						newObj[v] = vVal.toString();
					}
				}
				newArr.push(newObj);
			}
			return newArr;
		},
		/**
		 * 处理数组分组
		 * @param key 属性key
		 * @param source 源数组
		 * @return {*[][]}
		 */
		handleArrayGroup(key, source) {
			const map = new Map();
			source.forEach((item, index, arr) => {
				if (!map.has(item[key])) {
					map.set(
						item[key],
						arr.filter(a => a[key] === item[key])
					);
				}
			});
			return Array.from(map).map(item => [...item[1]]);
		},
		// 提交审批后返回对应列表页面
		backToList() {
			let back = utils.getUrlKey('back');
			let backUrl = this.$api.fmUrl + '/#' + back;
			window.open(backUrl, '_top');
		}
	}
};

</script>

<style lang='less' scoped>

</style>
