Newer
Older
smart-metering-front / src / views / business / subpackage / approve / edit.vue
<!-- 分包方资格审批详情 -->
<script lang="ts" setup name="SubpackageApproveEdit">
import type { Ref } from 'vue'
import { ElLoading, ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance } from 'element-plus'
import type { IForm, dictType } from './approve-interface'
import showPhoto from '@/views/system/tool/showPhoto.vue'
import { UploadFile } from '@/api/measure/file'
import type { IAddress } from '@/components/AddressSelect/address-interface'
import { getDictByCode } from '@/api/system/dict'
import { SCHEDULE } from '@/utils/scheduleDict'
import ApprovalDialog from '@/components/Approval/ApprovalDialog.vue'
import { cancelApproval, fetchApproval, submitApproval } from '@/api/approval'
import { UpdateApprove, add, detail, failUpdateApprove, submit } from '@/api/business/subpackage/approval'
const loading = ref(false) // 表单加载状态
const infoId = ref('') // id
const pageType = ref('add') // 页面类型: add, edit, detail
const submitId = ref('') // 提交使用的id
const approvalStatusName = ref('') // 审批状态名字
const $route = useRoute()
const query = $route.query
const textMap: { [key: string]: string } = {
  edit: '编辑',
  add: '新建',
  detail: '详情',
}// 字典
// 从路由中获取页面类型参数
if ($route.params && $route.params.type) {
  pageType.value = $route.params.type as string
  if ($route.params.id) {
    infoId.value = $route.params.id as string
  }
}
// 表单
const dataForm: Ref<IForm> = ref({
  id: '',
  businessContent: '', // 业务内容
  outsourcerName: '', // 公司名称
  outsourcerNo: '', // 分包方编号
  bankAccount: '', // 银行账户名
  bankAccountNumber: '', // 银行账号
  bankName: '', // 银行名称
  outsourcerBriefName: '', // 公司简称
  businessScope: '', // 公司业务范围
  grade: '', // 履约评级
  outsourcerSize: '', // 公司规模
  businessSize: '', // 业务规模-字典code
  evaluation: '', // 整体评价
  fullAddress: '', // 公司地址-详细地址
  addressArea: '', // 公司地址-区编码
  addressCity: '', // 公司地址-市编码
  addressCountry: '', // 公司地址-国家编码
  addressProvince: '', // 公司地址-省编码
  addressAreaName: '', // 公司地址-区
  addressCityName: '', // 公司地址-市
  addressCountryName: '', // 公司地址-国家
  addressProvinceName: '', // 公司地址-省
  director: '', // 负责人
  // fax: '', // 传真
  invoiceFullAddress: '', // 开票地址-详细地址
  invoiceArea: '', // 开票地址-区编码
  invoiceCity: '', // 开票地址-市编码
  invoiceCountry: '', // 开票地址-国家编码
  invoiceProvince: '', // 开票地址-省编码
  invoiceAreaName: '', // 开票地址-区
  invoiceCityName: '', // 开票地址-市
  invoiceCountryName: '', // 开票地址-国家
  invoiceProvinceName: '', // 开票地址-省
  email: '', // 邮箱
  minioFileName: '', // minio存储文件名
  mobile: '', // 手机
  phone: '', // phone
  postalCode: '', // postalCode
  processId: '', // 流程实例id
  remark: '', // 备注
  taxNumber: '', // 税号
  website: '', // 网址

  rejectRemark: '', // 历次驳回原因
})
const fullAddress = ref<string[]>([]) // 公司地址
const invoiceFullAddress = ref<string[]>([]) // 开票地址
const ruleFormRef = ref<FormInstance>()

// 校验规则
const rules = ref({
  outsourcerName: [{ required: true, message: '公司名称必填', trigger: 'blur' }],
  outsourcerSize: [{ required: true, message: '公司规模必填', trigger: 'blur' }],
  businessSize: [{ required: true, message: '业务规模必填', trigger: 'blur' }],
  grade: [{ required: true, message: '履约评级必填', trigger: 'blur' }],
  evaluation: [{ required: true, message: '整体评价必填', trigger: 'blur' }],
  // businessContent: [{ required: true, message: '业务内容必填', trigger: 'blur' }],
}) // 表单验证规则
// 初始化router
const $router = useRouter()
// 关闭新增页面的回调
const close = () => {
  $router.back()
}
// ---------------------------------------字典-----------------------------------------
const companySizeList = ref<dictType[]>([]) // 公司规模列表
const businessSizeList = ref<dictType[]>([]) // 业务规模列表
const gradeList = ref<dictType[]>([]) // 履约评级列表
const evaluationList = ref<dictType[]>([]) // 整体评价列表
function getDict() {
  // 获取公司规模
  getDictByCode('companySize').then((response) => {
    companySizeList.value = response.data
  })
  // 获取业务规模
  getDictByCode('businessSize').then((response) => {
    businessSizeList.value = response.data
  })
  // 获取履约评级
  getDictByCode('grade').then((response) => {
    gradeList.value = response.data
  })
  // 获取整体评价
  getDictByCode('evaluation').then((response) => {
    evaluationList.value = response.data
  })
}
// -----------------------------------------------------------------------------------

// 获取详情
const getInfo = () => {
  loading.value = true
  detail({ id: infoId.value }).then((res) => {
    loading.value = false
    dataForm.value = res.data
    if (pageType.value == 'detail') {
      fullAddress.value = [dataForm.value.addressCountryName, dataForm.value.addressProvinceName, dataForm.value.addressCityName, dataForm.value.addressAreaName, dataForm.value.fullAddress]
      invoiceFullAddress.value = [dataForm.value.invoiceCountryName, dataForm.value.invoiceProvinceName, dataForm.value.invoiceCityName, dataForm.value.invoiceAreaName, dataForm.value.invoiceFullAddress]
    }
    else {
      fullAddress.value = [dataForm.value.addressCountry, dataForm.value.addressProvince, dataForm.value.addressCity, dataForm.value.addressArea, dataForm.value.fullAddress]
      invoiceFullAddress.value = [dataForm.value.invoiceCountry, dataForm.value.invoiceProvince, dataForm.value.invoiceCity, dataForm.value.invoiceArea, dataForm.value.invoiceFullAddress]
    }
  })
}

// 公司地址变化后给对象赋值
function fullAddressChange(addressObj: IAddress) {
  dataForm.value.addressCountry = addressObj.country
  dataForm.value.addressProvince = addressObj.province
  dataForm.value.addressCity = addressObj.city
  dataForm.value.addressArea = addressObj.area
  dataForm.value.fullAddress = addressObj.address
  dataForm.value.addressCountryName = addressObj.countryName
  dataForm.value.addressProvinceName = addressObj.provinceName
  dataForm.value.addressCityName = addressObj.cityName
  dataForm.value.addressAreaName = addressObj.areaName
}
// 开票地址发生变化
function invoiceFullAddressChange(addressObj: IAddress) {
  dataForm.value.invoiceCountry = addressObj.country
  dataForm.value.invoiceProvince = addressObj.province
  dataForm.value.invoiceCity = addressObj.city
  dataForm.value.invoiceArea = addressObj.area
  dataForm.value.invoiceFullAddress = addressObj.address
  dataForm.value.invoiceCountryName = addressObj.countryName
  dataForm.value.invoiceProvinceName = addressObj.provinceName
  dataForm.value.invoiceCityName = addressObj.cityName
  dataForm.value.invoiceAreaName = addressObj.areaName
}

// 打印表单
const printObj = ref({
  id: 'form', // 需要打印元素的id
  popTitle: '客户详情', // 打印配置页上方的标题
  extraHead: '<div style="display: flex;flex-direction: column;text-align: center"><h3>分包方档案详情</h3></div>', // 最上方的头部文字,附加在head标签上的额外标签,使用逗号分割
  preview: false, // 是否启动预览模式,默认是false
  standard: '',
  extarCss: '',
})

// 保存
function saveForm(formEl: FormInstance | undefined) {
  if (!formEl) { return }
  formEl.validate((valid, fields) => {
    if (valid) {
      const loading = ElLoading.service({
        lock: true,
        background: 'rgba(255, 255, 255, 0.8)',
      })
      if (pageType.value === 'add') { // 新建
        add(dataForm.value).then((res) => {
          if (res.code === 200) {
            submitId.value = res.data.id
            loading.close()
            ElMessage.success('保存成功')
          }
        }).catch(() => {
          loading.close()
        })
      }
      else if (pageType.value === 'edit') { // 编辑
        if (approvalStatusName.value === '未通过-驳回') {
          failUpdateApprove(dataForm.value).then((res) => {
            if (res.code === 200) {
              loading.close()
              ElMessage.success('保存成功')
              close()
            }
          }).catch(() => {
            loading.close()
          })
        }
        else { // 草稿箱和已取消
          UpdateApprove(dataForm.value).then((res) => {
            if (res.code === 200) {
              loading.close()
              ElMessage.success('保存成功')
              close()
            }
          }).catch(() => {
            loading.close()
          })
        }
      }
    }
  })
}
// 提交
const handleSubmit = () => {
  if (submitId.value) {
    const loading = ElLoading.service({
      lock: true,
      background: 'rgba(255, 255, 255, 0.8)',
    })
    const params = {
      id: submitId.value,
      formId: SCHEDULE.BUSINESS_SUBPACKAGE_APPROVE, // 表单id
      processId: dataForm.value.processId, // 流程实例id
    }
    submit(params).then(() => {
      ElMessage.success('已提交')
      loading.close()
      close()
    })
  }
  else {
    ElMessage.warning('请先保存!')
  }
}

// -----------------------------------------文件上传-----------------------------------
const fileRef = ref() // 文件上传input
const onFileChange = (event: any) => {
  if (event.target.files?.length !== 0) {
    // 创建formdata对象
    const fd = new FormData()
    fd.append('multipartFile', event.target.files[0])
    const loading = ElLoading.service({
      lock: true,
      background: 'rgba(255, 255, 255, 0.8)',
    })
    UploadFile(fd).then((res) => {
      if (res.code === 200) {
        dataForm.value.minioFileName = res.data[0]
        // 重置当前验证
        ElMessage.success('文件上传成功')
        loading.close()
      }
      else {
        ElMessage.error(res.message)
        loading.close()
      }
    })
  }
}
const upload = () => {
  fileRef.value.click()
}
// -------------------------------------------审批----------------------------------------
const approvalRecordData = ref([]) // 审批流程数据
const approvalDialog = ref() // 审批对话ref

// 查询审批记录
function getApprovalRecord(processId: string) {
  if (pageType.value !== 'add') {
    if (processId) {
      fetchApproval(processId).then((res) => {
        approvalRecordData.value = res.data
      })
    }
    else {
      ElMessage.warning('流程实例id为空')
    }
  }
}
// 审批结束回调
const approvalSuccess = () => {
  close() // 返回上一页
}
// 审批
const handleApprove = (val: string, title = '') => {
  if (val === '取消') {
    const params = {
      processInstanceId: dataForm.value.processId!,
      comments: '',
    }
    ElMessageBox.confirm(
      '确认取消该审批吗?',
      '提示',
      {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
      },
    )
      .then(() => {
        cancelApproval(params).then((res) => {
          ElMessage({
            type: 'success',
            message: '取消成功',
          })
          close()
        })
      })
  }
  else if (val === '同意') {
    approvalDialog.value.initDialog('agree', query.taskId)
  }
  else if (val === '驳回') {
    approvalDialog.value.initDialog('reject', query.taskId)
  }
  else if (val === '拒绝') {
    approvalDialog.value.initDialog('refuse', query.taskId)
  }
}
// ---------------------------------------------------------------------------------------
onMounted(() => {
  approvalStatusName.value = query.approvalStatusName as string // 审批状态名字
  dataForm.value.processId = query.processId as string // 流程实例id
  // 非添加页面获取详情
  if (pageType.value !== 'add') {
    getInfo()
    if (query.approvalStatusName !== '草稿箱') {
      getApprovalRecord(dataForm.value.processId) // 获取审批流程
    }
  }
  getDict()
})

// 监听到驳回原因
const giveRejectRemark = (reason: string) => {
  if (dataForm.value.rejectRemark) {
    const lastIndex = dataForm.value.rejectRemark.lastIndexOf(reason)
    if (lastIndex === -1) { // 本次原因和上次最后一次原因不同才去拼接
      dataForm.value.rejectRemark = `${dataForm.value.rejectRemark};${reason}`
    }
  }
  else {
    dataForm.value.rejectRemark = reason
  }
}
</script>

<template>
  <app-container>
    <detail-page v-loading="loading" :title="`分包方资格审批-${textMap[pageType]}`">
      <template #btns>
        <el-button v-if="pageType === 'detail' && query.approvalStatusName === '待审批'" type="primary" @click="handleApprove('同意')">
          同意
        </el-button>
        <el-button v-if="pageType === 'detail' && query.approvalStatusName === '待审批' && query.decisionItem !== '3'" type="primary" @click="handleApprove('驳回')">
          驳回
        </el-button>
        <el-button v-if="pageType === 'detail' && query.approvalStatusName === '待审批' && query.decisionItem !== '2'" type="danger" @click="handleApprove('拒绝')">
          拒绝
        </el-button>
        <!-- <el-button v-if="pageType === 'detail'" v-print="printObj" type="primary">
          打印
        </el-button> -->
        <el-button v-if="pageType === 'add'" type="primary" @click="handleSubmit">
          提交
        </el-button>
        <el-button v-if="pageType !== 'detail'" type="primary" @click="saveForm(ruleFormRef)">
          保存
        </el-button>
        <el-button v-if="pageType === 'detail' && query.approvalStatusName === '审批中'" type="info" @click="handleApprove('取消')">
          取消
        </el-button>
        <el-button type="info" @click="close">
          关闭
        </el-button>
      </template>
      <div id="form">
        <el-form
          ref="ruleFormRef"
          :model="dataForm"
          :label-width="120"
          label-position="right"
          :rules="rules"
        >
          <el-row :gutter="24">
            <el-col :span="6">
              <el-form-item label="分包方编号:" prop="outsourcerNo">
                <el-input
                  v-model="dataForm.outsourcerNo"
                  :placeholder="pageType === 'detail' ? '' : '系统自动生成'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  disabled
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="公司名称:" prop="outsourcerName">
                <el-input
                  v-model.trim="dataForm.outsourcerName"
                  :placeholder="pageType === 'detail' ? '' : '请输入公司名称'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  :disabled="pageType === 'detail'"
                />
              </el-form-item>
            </el-col><el-col :span="6">
              <el-form-item label="公司简称:">
                <el-input
                  v-model="dataForm.outsourcerBriefName"
                  :placeholder="pageType === 'detail' ? '' : '请输入公司简称'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  :disabled="pageType === 'detail'"
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="业务内容:" prop="businessContent">
                <el-input
                  v-model.trim="dataForm.businessContent"
                  :placeholder="pageType === 'detail' ? '' : '请输入业务内容'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  :disabled="pageType === 'detail'"
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="公司规模" prop="outsourcerSize">
                <el-select v-model="dataForm.outsourcerSize" :placeholder="pageType === 'detail' ? ' ' : '请选择公司规模'" :disabled="pageType === 'detail'" class="full-width-input">
                  <el-option v-for="item in companySizeList" :key="item.id" :label="item.name" :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="业务规模" prop="businessSize">
                <el-select v-model="dataForm.businessSize" :placeholder="pageType === 'detail' ? ' ' : '请选择业务规模'" :disabled="pageType === 'detail'" class="full-width-input">
                  <el-option v-for="item in businessSizeList" :key="item.id" :label="item.name" :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="履约评级" prop="grade">
                <el-select v-model="dataForm.grade" :placeholder="pageType === 'detail' ? ' ' : '请选择履约评级'" :disabled="pageType === 'detail'" class="full-width-input">
                  <el-option v-for="item in gradeList" :key="item.id" :label="item.name" :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="整体评价" prop="evaluation">
                <el-select v-model="dataForm.evaluation" :placeholder="pageType === 'detail' ? ' ' : '请选择整体评价'" :disabled="pageType === 'detail'" class="full-width-input">
                  <el-option v-for="item in evaluationList" :key="item.id" :label="item.name" :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="税号:" prop="taxNumber">
                <el-input
                  v-model="dataForm.taxNumber"
                  :placeholder="pageType === 'detail' ? '' : '请输入税号'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  :disabled="pageType === 'detail'"
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="银行账户名:">
                <el-input
                  v-model="dataForm.bankAccount"
                  :placeholder="pageType === 'detail' ? '' : '请输入银行账户名'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  :disabled="pageType === 'detail'"
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="银行名称:">
                <el-input
                  v-model="dataForm.bankName"
                  :placeholder="pageType === 'detail' ? '' : '请输入银行名称'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  :disabled="pageType === 'detail'"
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="银行账号:">
                <el-input
                  v-model="dataForm.bankAccountNumber"
                  :placeholder="pageType === 'detail' ? '' : '请输入银行账号'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  :disabled="pageType === 'detail'"
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="邮编:">
                <el-input
                  v-model="dataForm.postalCode"
                  :placeholder="pageType === 'detail' ? '' : '请输入邮编'"
                  :disabled="pageType === 'detail'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="负责人:">
                <el-input
                  v-model="dataForm.director"
                  :placeholder="pageType === 'detail' ? '' : '请输入负责人'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  :disabled="pageType === 'detail'"
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="电话:">
                <el-input
                  v-model="dataForm.phone"
                  :placeholder="pageType === 'detail' ? '' : '请输入电话'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  :disabled="pageType === 'detail'"
                />
              </el-form-item>
            </el-col>
            <!-- <el-col :span="6">
              <el-form-item label="传真:">
                <el-input
                  v-model="dataForm.fax"
                  :placeholder="pageType === 'detail' ? '' : '请输入传真'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  :disabled="pageType === 'detail'"
                />
              </el-form-item>
            </el-col> -->
            <el-col :span="6">
              <el-form-item label="手机:">
                <el-input
                  v-model="dataForm.mobile"
                  :placeholder="pageType === 'detail' ? '' : '请输入手机'"
                  :disabled="pageType === 'detail'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="邮箱:">
                <el-input
                  v-model="dataForm.email"
                  :placeholder="pageType === 'detail' ? '' : '请输入邮箱'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  :disabled="pageType === 'detail'"
                />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="网址:">
                <el-input
                  v-model="dataForm.website"
                  :placeholder="pageType === 'detail' ? '' : '请输入网址'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                  :disabled="pageType === 'detail'"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="24">
            <el-col :span="12">
              <el-form-item label="公司地址:">
                <address-select style="width: 100%;" :data="fullAddress" :detail="pageType === 'detail'" @on-change="fullAddressChange" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="24">
            <el-col :span="12">
              <el-form-item label="开票地址:">
                <address-select style="width: 100%;" :data="invoiceFullAddress" :detail="pageType === 'detail'" @on-change="invoiceFullAddressChange" />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="24">
            <el-col :span="14">
              <el-form-item label="公司业务范围:">
                <el-input
                  v-model="dataForm.businessScope"
                  :placeholder="pageType === 'detail' ? '' : '请输入公司业务范围'"
                  :disabled="pageType === 'detail'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="24">
            <el-col :span="14">
              <el-form-item label="备注:">
                <el-input
                  v-model="dataForm.remark"
                  :placeholder="pageType === 'detail' ? '' : '请输入备注'"
                  :disabled="pageType === 'detail'"
                  :class="{ 'detail-input': pageType === 'detail' }"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row :gutter="24" class="marg">
            <el-col :span="14">
              <el-form-item label="附件:">
                <show-photo v-if="dataForm.minioFileName" :minio-file-name="dataForm.minioFileName" />
                <span v-else-if="pageType === 'detail'">无</span>
                <input v-show="pageType === ''" ref="fileRef" type="file" @change="onFileChange">
                <el-button v-if="pageType !== 'detail'" id="file" type="primary" :disabled="pageType === 'detail'" :style="{ 'margin-left': dataForm.minioFileName === '' ? '0px' : '20px' }" @click="upload">
                  {{ dataForm.minioFileName === '' ? '上传' : '更换附件' }}
                </el-button>
              </el-form-item>
            </el-col>
          </el-row>

          <el-row v-if="query.approvalStatusName === '未通过-驳回'" :gutter="20">
            <el-col :span="24">
              <el-form-item label="历次驳回原因:">
                <el-input
                  v-model.trim="dataForm.rejectRemark"
                  :placeholder="pageType === 'detail' ? '' : '历次驳回原因'"
                  class="full-width-input"
                  clearable
                  type="textarea"
                  autosize
                  disabled
                />
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
      </div>
    </detail-page>
    <detail-block v-if="query.approvalStatusName !== '草稿箱' && pageType !== 'add'" title="审批流程">
      <!-- 审批流程 -->
      <approval-record ref="approvalRecord" :approval-record-data="approvalRecordData" @give-reject-remark="giveRejectRemark" />
    </detail-block>
    <!-- 审批弹窗 -->
    <approval-dialog ref="approvalDialog" @on-success="approvalSuccess" />
  </app-container>
</template>

<style lang="scss" scoped>
// 样式
</style>