<template>
  <el-dialog
    title="处理"
    :before-close="handleClose"
    :visible.sync="dialogVisible"
    :close-on-click-modal="false"
    :append-to-body="true"
    width="80%"
  >
    <div class="app-container">
      <!-- 申请信息 -->
      <el-card class="box-card" v-loading="processInstanceLoading">
        <div slot="header" class="clearfix">
          <span class="el-icon-document"
            >申请信息【{{ processInstance.name }}】 申请人：【{{
              processInstance.startUser?.nickname
            }}】</span
          >
        </div>
        <div v-if="processInstance.processDefinition">
          <async-biz-form-component
            :taskId="listData?.taskId"
            :businessId="listData?.businessId"
            :id="listData?.id"
            :taskDefinitionKey="listData?.taskDefinitionKey"
            @activeCompChange="activeCompChange"
            @handleClose="handleClose"
            ref="bziRef"
          ></async-biz-form-component>
        </div>
      </el-card>
      <!-- 审批信息 -->
      <el-card
        class="box-card"
        v-loading="processInstanceLoading"
        v-for="(item, index) in runningTasks"
        :key="index"
      >
        <div slot="header" class="clearfix">
          <span class="el-icon-picture-outline">审批任务</span>
        </div>
        <div v-if="processInstance.processDefinition">
          <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)"
            @submit="submit"
            @handleClose="handleClose"
            ref="subForm"
          ></async-sub-form-component>
        </div>
        <!-- <el-col :span="16" :offset="6">
          <el-form
            :ref="'form' + index"
            :model="auditForms[index]"
            :rules="auditRule"
            label-width="100px"
          >

            <el-form-item
              label="审批建议"
              prop="reason"
              style="margin-bottom: 20px"
            >
              <el-input
                type="textarea"
                v-model="auditForms[index].reason"
                placeholder="请输入审批建议"
              />
            </el-form-item>
          </el-form>
          <div style="margin-left: 10%; margin-bottom: 20px; font-size: 14px">
            <el-button
              icon="el-icon-edit-outline"
              type="success"
              size="mini"
              @click="handleAudit(item, true)"
              >通过
            </el-button>
            <el-button
              icon="el-icon-circle-close"
              type="danger"
              size="mini"
              @click="handleAudit(item, false)"
              >不通过
            </el-button>
            <el-button
              icon="el-icon-edit-outline"
              type="primary"
              size="mini"
              @click="handleUpdateAssignee(item)"
              >转办
            </el-button>
            <el-button
              icon="el-icon-edit-outline"
              type="primary"
              size="mini"
              @click="handleDelegate(item)"
              >委派
            </el-button>
            <el-button
              icon="el-icon-refresh-left"
              type="warning"
              size="mini"
              @click="handleBackList(item)"
              >退回
            </el-button>
          </div>
        </el-col> -->
      </el-card>

      <!-- 对话框(转办审批人) -->
      <el-dialog
        title="转办审批人"
        :visible.sync="updateAssignee.open"
        width="500px"
        append-to-body
      >
        <el-form
          ref="updateAssigneeForm"
          :model="updateAssignee.form"
          :rules="updateAssignee.rules"
          label-width="110px"
        >
          <el-form-item label="新审批人" prop="assigneeUserId">
            <el-select
              v-model="updateAssignee.form.assigneeUserId"
              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>
        <div slot="footer" class="dialog-footer">
          <el-button type="primary" @click="submitUpdateAssigneeForm"
            >确 定
          </el-button>
          <el-button @click="cancelUpdateAssigneeForm">取 消</el-button>
        </div>
      </el-dialog>
      <!-- 对话框(委派审批人) -->
      <el-dialog
        title="委派审批人"
        :visible.sync="updateDelegate.open"
        width="500px"
        append-to-body
      >
        <el-form
          ref="updateDelegateForm"
          :model="updateDelegate.form"
          :rules="updateDelegate.rules"
          label-width="110px"
        >
          <el-form-item label="新审批人" prop="assigneeUserId">
            <el-select
              v-model="updateDelegate.form.delegateUserId"
              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="委派理由" prop="reason">
            <el-input
              v-model="updateDelegate.form.reason"
              clearable
              placeholder="请输入委派理由"
            />
          </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
          <el-button type="primary" @click="submitUpdateDelegateForm"
            >确 定
          </el-button>
          <el-button @click="cancelUpdateDelegateForm">取 消</el-button>
        </div>
      </el-dialog>
      <!--退回流程-->
      <el-dialog
        title="退回流程"
        :visible.sync="returnOpen"
        width="40%"
        append-to-body
      >
        <el-form
          ref="formRef"
          v-loading="formLoading"
          :model="formData"
          :rules="formRules"
          label-width="110px"
        >
          <el-form-item label="退回节点" prop="targetDefinitionKey">
            <el-select
              v-model="formData.targetDefinitionKey"
              clearable
              style="width: 100%"
            >
              <el-option
                v-for="item in returnList"
                :key="item.definitionKey"
                :label="item.name"
                :value="item.definitionKey"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="回退理由" prop="reason">
            <el-input
              v-model="formData.reason"
              clearable
              placeholder="请输入回退理由"
            />
          </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
          <el-button @click="returnOpen = false">取 消</el-button>
          <el-button
            :disabled="formLoading"
            type="primary"
            @click="submitReturn"
            >确 定</el-button
          >
        </span>
      </el-dialog>
    </div>
  </el-dialog>
</template>

<script>
  // import { getProcessDefinitionBpmnXML } from '@/api/bpm/definition';
  import store from '@/store';
  //   import {decodeFields} from "@/utils/formGenerator";
  //   import Parser from '@/components/parser/Parser'
  import { getProcessInstance } from '@/api/bpm/processInstance';
  import { listAllUserBind } from '@/api/system/organization';
  import Vue from 'vue';

  import {
    approveTask,
    delegateTask,
    getReturnList,
    getTaskListByProcessInstanceId,
    rejectTask,
    returnTask,
    updateTaskAssignee
  } from '@/api/bpm/task';
  // import { getDate } from '@/utils/dateUtils';

  // 流程实例的详情页，可用于审批
  export default {
    name: 'ProcessInstanceDetail',
    components: {
      //   Parser
    },
    data() {
      return {
        // 遮罩层
        processInstanceLoading: true,
        dialogVisible: false,
        // 流程实例
        listData: {
          id: undefined, // 流程实例的编号
          pcHandleRouter: '',
          pcViewRouter: '',
          businessId: '', // 业务id
          taskDefinitionKey: '',
          taskId: '' //任务编码
        },

        processInstance: {},
        formLoading: false,
        // 流程表单详情
        detailForm: {
          fields: []
        },
        //回退列表数据
        returnList: [],
        formData: {
          id: '',
          targetDefinitionKey: undefined,
          reason: ''
        },
        formRules: {
          targetDefinitionKey: [
            { required: true, message: '必须选择回退节点', trigger: 'change' }
          ],
          reason: [
            { required: true, message: '回退理由不能为空', trigger: 'blur' }
          ]
        },
        returnOpen: false,
        activityList: [],

        tasks: [],

        // 审批表单
        runningTasks: [],
        auditForms: [],
        auditRule: {
          reason: [
            { required: true, message: '审批建议不能为空', trigger: 'blur' }
          ]
        },
        // 转派审批人
        userOptions: [],
        updateAssignee: {
          open: false,
          form: {
            assigneeUserId: undefined
          },
          rules: {
            assigneeUserId: [
              { required: true, message: '新审批人不能为空', trigger: 'change' }
            ]
          }
        },
        updateDelegate: {
          open: false,
          form: {
            delegateUserId: undefined,
            reason: ''
          },
          rules: {
            delegateUserId: [
              { required: true, message: '新审批人不能为空', trigger: 'change' }
            ],
            reason: [
              { required: true, message: '委派理由不能为空', trigger: 'blur' }
            ]
          }
        }
      };
    },
    created() {
      //   this.id = this.$route.query.id;
      //   if (!this.id) {
      //     this.$message.error('未传递 id 参数，无法查看流程信息');
      //     return;
      //   }
      //   this.getDetail();

      // 获得用户列表
      this.userOptions = [];
      listAllUserBind().then((data) => {
        this.userOptions.push(...data);
      });
    },
    methods: {
      submit(data) {
        this.$refs.bziRef.save(data);
      },
      open(data) {
        this.listData = data;
        console.log('实例流程~~~~~~', data);
        this.dialogVisible = true;
        this.getDetail();
      },
      activeCompChange(activeComp) {
        console.log(activeComp);
        this.$refs.subForm[0].activeCompChange(activeComp);
      },
      /** 获得流程实例 */
      getDetail() {
        // 获得流程实例相关
        this.processInstanceLoading = true;
        getProcessInstance(this.listData.id).then((response) => {
          if (!response) {
            this.$message.error('查询不到流程信息！');
            return;
          }
          // 设置流程信息
          console.log('==', response);
          console.log('==', this.listData);
          this.processInstance = response;
          // //将业务表单，注册为动态组件
          // let formCustomCreatePath = JSON.parse(
          //   this.processInstance.processDefinition.formCustomCreatePath
          // );
          // const bizpath = formCustomCreatePath.pcView;
          // const subpath = formCustomCreatePath.pcHandle;
          Vue.component('async-biz-form-component', (resolve) => {
            require([`@/views${this.listData.pcViewRouter}`], resolve);
          });
          Vue.component('async-sub-form-component', (resolve) => {
            require([`@/views${this.listData.pcHandleRouter}`], resolve);
          });
          //   // 设置表单信息
          //   if (this.processInstance.processDefinition.formType === 10) {
          //     this.detailForm = {
          //       ...JSON.parse(this.processInstance.processDefinition.formConf),
          //       disabled: true, // 表单禁用
          //       formBtns: false, // 按钮隐藏
          //       fields: decodeFields(this.processInstance.processDefinition.formFields)
          //     }
          //     // 设置表单的值
          //     this.detailForm.fields.forEach(item => {
          //       const val = this.processInstance.formVariables[item.__vModel__]
          //       if (val) {
          //         item.__config__.defaultValue = val
          //       }
          //     });
          //   }

          // 取消加载中
          this.processInstanceLoading = false;
        });

        this.runningTasks = [];
        this.auditForms = [];
        getTaskListByProcessInstanceId(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;
            }
          });

          // 需要审核的记录
          const userId = store.getters.user.info.userId;
          this.tasks.forEach((task) => {
            if (task.result !== 1 && task.result !== 6) {
              // 只有待处理才需要
              return;
            }
            if (!task.assigneeUser || task.assigneeUser.id !== 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.$message.success(`审批${data.title || text}成功！`);
        this.handleClose(); // 获得最新详情

        // 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(); // 获得最新详情
        //     });
        //   }
        // });
      },
      /** 处理转办审批人 */
      handleUpdateAssignee(task) {
        // 设置表单
        this.resetUpdateAssigneeForm();
        this.updateAssignee.form.id = task.id;
        // 设置为打开
        this.updateAssignee.open = true;
      },
      /** 提交转办审批人 */
      submitUpdateAssigneeForm() {
        this.$refs['updateAssigneeForm'].validate((valid) => {
          if (!valid) {
            return;
          }
          updateTaskAssignee(this.updateAssignee.form).then((response) => {
            this.$message.success('转办任务成功！');

            this.updateAssignee.open = false;
            this.handleClose(); // 获得最新详情
          });
        });
      },
      /** 取消转办审批人 */
      cancelUpdateAssigneeForm() {
        this.updateAssignee.open = false;
        this.resetUpdateAssigneeForm();
      },
      /** 重置转办审批人 */
      resetUpdateAssigneeForm() {
        this.updateAssignee.form = {
          id: undefined,
          assigneeUserId: undefined
        };
        this.resetForm('updateAssigneeForm');
      },
      /** 处理审批委派的操作 */
      handleDelegate(task) {
        //this.$modal.msgError("暂不支持【委派】功能，可以使用【转派】替代！");
        this.resetUpdateDelegateForm();
        this.updateDelegate.form.id = task.id;
        // 设置为打开
        this.updateDelegate.open = true;
      },
      /** 提交委派审批人 */
      submitUpdateDelegateForm() {
        this.$refs['updateDelegateForm'].validate((valid) => {
          if (!valid) {
            return;
          }
          delegateTask(this.updateDelegate.form).then((response) => {
            this.$message.success('委派任务成功！');
            this.updateDelegate.open = false;
            this.handleClose(); // 获得最新详情
          });
        });
      },
      /** 取消委派审批人 */
      cancelUpdateDelegateForm() {
        this.updateDelegate.open = false;
        this.resetUpdateDelegateForm();
      },
      /** 重置委派审批人 */
      resetUpdateDelegateForm() {
        this.updateDelegate.form = {
          id: undefined,
          delegateUserId: undefined
        };
        this.resetForm('updateDelegateForm');
      },
      /** 处理审批退回的操作 */
      /** 返回退回节点列表 */
      handleBackList(task) {
        // 可参考 http://blog.wya1.com/article/636697030/details/7296
        getReturnList(task.id).then((response) => {
          this.returnList = response.data.data;
          if (this.returnList.length == 0) {
            this.$message.error('当前没有可回退的节点！');

            return;
          }
          this.formData.id = task.id;
          this.returnOpen = true;
        });
      },
      /** 提交退回任务 */
      submitReturn() {
        if (!this.formData.targetDefinitionKey) {
          this.$message.error('请选择退回节点！');
        }
        this.$refs['formRef'].validate((valid) => {
          if (!valid) {
            return;
          }
          returnTask(this.formData).then((res) => {
            if (res.data) {
              this.$message.success('回退成功！');

              this.returnOpen = false;
              this.handleClose(); // 获得最新详情
            }
          });
        });
      },
      handleClose() {
        this.$emit('reload');
        this.dialogVisible = false;
      },
      getTableValue(fn) {
        fn(this.$refs.bziRef.getTableValue());
      }
    }
  };
</script>

<style lang="scss">
  .my-process-designer {
    height: calc(100vh - 200px);
  }

  .box-card {
    width: 100%;
    margin-bottom: 20px;
  }
</style>
