Newer
Older
smart-metering-front / src / views / device / receive / createOrCheck.vue
<script lang="ts" setup name="CreateOrCheck">
import { onMounted, reactive, ref } from 'vue'
import type { Ref } from 'vue'
import dayjs from 'dayjs'
import type { FormInstance, FormRules } from 'element-plus'
import { ElLoading, ElMessage, ElMessageBox } from 'element-plus'
import { useRoute, useRouter } from 'vue-router'
import type { IdeviceList, IdeviceListQuery } from './receive'
import SelectDeviceDialog from './selectDeviceDialog.vue'
import { toTreeList } from '@/utils/structure'
import { SCHEDULE } from '@/utils/scheduleDict'
import type { TableColumn } from '@/components/NormalTable/table_interface'
import {
  getReceiveApplyListDetail,
  saveAddReceiveApplyList,
  saveEditReceiveApplyList,
  submitReceiveApplyList,
} from '@/api/device/receive'
import type { userType } from '@/views/system/user/user-interface'
import type { deptType } from '@/views/device/standingBook/standingBook-interface'
import { getDeptTreeList } from '@/api/system/dept'
import { getUserList } from '@/api/system/user'
import { submitApproval } from '@/api/approval'
import ApprovalRecord from '@/components/ApprovalRecord/ApprovalRecord.vue'

const $route = useRoute()
const approvalDialog = ref() // 审批对话框显隐
const typeValue = ref() // add、edit、detail
const approvalStatus = ref() // 审批类型
const useDeptList = ref<deptType[]>([]) // 部门列表
const usePersonList = ref<userType[]>([]) // 申请人列表(用户)
const usePersonOptions = ref<userType[]>([]) // 申请人列表(用户)--模糊搜索数据
const applyPersonLoading = ref(false)
const isMulti = ref(false) // 是否批量添加(允许多选)
const selectIndex = ref() // 点击选择的index--点击第几行
const dialogSelectDiviceVisible = ref(false) // 控制选择设备对话框显隐
const textMap: { [key: string]: string } = {
  edit: '编辑',
  add: '新建',
  detail: '详情',
}// 字典
// 选中的内容
const checkoutList = ref([])
// 表单数据
const form = ref({
  taskId: '', // 任务id(审批用)
  id: '',
  processId: '', // 流程id--查询审批记录使用
  applyName: '', // 申请名称
  applyUnit: '', // 申请单位
  applyPerson: '', // 申请人
  time: '', // 领用时间
  applyDesc: '', // 申请说明
})
const ruleFormRef = ref<FormInstance>() as any
const list = ref<IdeviceList[]>([])// 表格数据

// 查询条件
const listQuery: Ref<IdeviceListQuery> = ref({
  equipmentName: '', // 仪器名称
  equipmentNo: '', // 设备编号
  modelNo: '', // 型号
  mesureRange: '', // 测量范围
  useDeptName: '', // 使用部门
  usePersonName: '', // 使用人
  managerStateName: '', // 管理状态
  validDate: '', // 有效日期
  offset: 1,
  limit: 20,
})
// 表头
const columns = ref<TableColumn[]>([
  { text: '设备编号', value: 'equipmentNo', align: 'center', width: '230' },
  { text: '设备名称', value: 'equipmentName', align: 'center' },
  { text: '型号', value: 'modelNo', align: 'center' },
  { text: '测量范围', value: 'mesureRange', align: 'center' },
  { text: '使用部门', value: 'useDeptName', align: 'center' },
  { text: '使用人', value: 'usePersonName', align: 'center' },
  { text: '管理状态', value: 'managerStateName', align: 'center' },
  { text: '有效日期', value: 'validDate', align: 'center' },
])
// 表单校验规则
const rules = reactive<FormRules>({
  applyName: [{ required: true, message: '申请名称不能为空', trigger: 'blur' }],
  applyUnit: [{ required: true, message: '申请单位不能为空', trigger: 'change' }],
  applyPerson: [{ required: true, message: '申请人不能为空', trigger: 'blur' }],
  time: [{ type: 'date', required: true, message: '领用时间不能为空', trigger: 'change' }],
  applyDesc: [{ required: true, message: '申请说明不能为空', trigger: 'blur' }],
})

const $router = useRouter()
// 点击关闭
const close = () => {
  $router.back()
}

const handleClick = (val: string) => {
  if (val === 'agree') { // 同意
    approvalDialog.value.initDialog('agree', form.value.taskId)
  }
  else if (val === 'reject') { // 驳回
    approvalDialog.value.initDialog('reject', form.value.taskId)
  }
  else if (val === 'refuse') { // 拒绝
    approvalDialog.value.initDialog('refuse', form.value.taskId)
  }
  else if (val === 'revoke') {
    const params = {
      taskId: form.value.taskId!,
      comments: '',
    }
    ElMessageBox.confirm(
      '确认撤回该审批吗?',
      '提示',
      {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
      },
    )
      .then(() => {
        submitApproval('revoke', params).then((res) => {
          ElMessage({
            type: 'success',
            message: '已撤回',
          })
        })
        close()
      })
  }
}

// 多选发生改变时
const handleSelectionChange = (e: any) => {
  checkoutList.value = e
}

// 删除行
const delRow = () => {
  if (checkoutList.value.length <= 0) {
    ElMessage({
      message: '请选中要删除的行',
      type: 'warning',
    })
  }
  else {
    checkoutList.value.forEach((item: IdeviceListQuery) => {
      list.value.forEach((element, index) => {
        if (element.equipmentNo === item.equipmentNo) {
          list.value.splice(index, 1)
        }
      })
    })
  }
}

// 增加行
const addRow = () => {
  const index = list.value.findIndex(item => !item.equipmentNo)
  if (index !== -1) {
    ElMessage.warning('请完善上一条设备信息')
    return
  }
  list.value.push({
    equipmentName: '', // 设备名称
    equipmentNo: '', // 设备编号
    modelNo: '', // 型号
    mesureRange: '', // 测量范围
    useDeptName: '', // 使用部门
    usePersonName: '', // 使用人
    managerStateName: '', // 管理状态
    validDate: '', // 有效日期
    equipmentId: '', // 设备ID
  })
}

// 点击选择
const handleSelect = (index: number, row: IdeviceList) => {
  dialogSelectDiviceVisible.value = true // 选择设备对话框显隐
  isMulti.value = false // 是否单选, false单选、true表格多选
  selectIndex.value = index
}

// 点击批量添加
const multiAdd = () => {
  dialogSelectDiviceVisible.value = true
  isMulti.value = true
}

// 选择设备对话框关闭
const closeDialog = () => {
  dialogSelectDiviceVisible.value = false
}

// 选择好设备了, 添加选好的设备到表格中
const updateDeviceConfirm = (val: Array<IdeviceList>) => {
  if (isMulti.value) { // 批量增加时push
    val.forEach((item: IdeviceList) => {
    // 只添加列表里不存在的
      const index = list.value.findIndex((i: IdeviceList) => item.equipmentNo === i.equipmentNo)
      if (index === -1) {
        list.value.push(item)
      }
    })
  }
  else { // 单选替换
    list.value.splice(selectIndex.value, 1, val[0])
  }

  // 把选择好的设备添加到列表中后,清除空行
  // const index = list.value.findIndex((item: IdeviceList) => !item.equipmentNo)
  // if (index !== -1) {
  //   list.value.splice(index, 1)
  // }
}

// 保存
const save = () => {
  ruleFormRef.value.validate((valid: boolean) => {
    if (valid) {
      const loading = ElLoading.service({
        lock: true,
        background: 'rgba(255, 255, 255, 0.8)',
      })
      const params = {
        applyName: form.value.applyName, // 申请名称
        applyUnit: form.value.applyUnit, // 申请单位
        applyPerson: form.value.applyPerson, // 申请人
        time: form.value.time, // 领用时间
        applyDesc: form.value.applyDesc, // 申请说明
        applyType: '1', // 申请类型 领用1
        id: form.value.id,
        equipmentList: list.value.map((item) => {
          return {
            equipmentId: item.id!,
          }
        }),
      }
      // 新建
      if (typeValue.value === 'add') {
        saveAddReceiveApplyList(params).then((res) => {
          form.value.id = res.data.id
          ElMessage.success('保存成功')
          loading.close()
        })
      }
      // 保存
      else if (typeValue.value === 'edit') {
        saveEditReceiveApplyList(params).then((res) => {
          form.value.id = res.data.id
          ElMessage.success('保存成功')
          loading.close()
        })
      }
    }
    else {
      console.log('表单校验不通过')
    }
  })
}

// 提交表单
const submit = () => {
  const loading = ElLoading.service({
    lock: true,
    background: 'rgba(255, 255, 255, 0.8)',
  })
  if (form.value.id) {
    const params = {
      id: form.value.id,
      formId: SCHEDULE.DEVICE_CONSUMING_APPROVAL, // 表单id
    }
    submitReceiveApplyList(params).then(() => {
      ElMessage.success('提交成功')
      loading.close()
      close()
    })
  }
  else {
    ElMessage.info('请先保存再提交!')
  }
}

// 获取用户列表--(是否有不分页接口?)
const fetchUserList = () => {
  getUserList({ offset: 1, limit: 999999 }).then((res: any) => {
    usePersonList.value = res.data.rows
    usePersonOptions.value = res.data.rows
  })
}

// 获取使用部门
const fetchDeptTreeList = () => {
  getDeptTreeList().then((res: any) => {
    if (res.data) { // 将列表转树结构
      useDeptList.value = toTreeList(res.data, '0', true)
    }
  })
}

// 审批结束回调
const approvalSuccess = () => {
  close()
}

// 编辑、详情--获取详细信息
const fetchReceiveApplyListDetail = () => {
  getReceiveApplyListDetail({ id: form.value.id }).then((res) => {
    form.value.applyUnit = res.data.applyUnit // 部门
    form.value.applyPerson = res.data.applyPerson// 申请人
    form.value.time = res.data.time // 领用时间
    form.value.applyDesc = res.data.applyDesc // 申请说明
    list.value = res.data.equipmentInfoList.map((item: IdeviceList) => {
      return {
        ...item,
        validDate: dayjs(item.validDate).format('YYYY-MM-DD'),
      }
    })
  })
}

// 选择器模糊查询
const remoteMethod = (query: string) => {
  if (query) {
    applyPersonLoading.value = true
    setTimeout(() => {
      applyPersonLoading.value = false
      usePersonOptions.value = usePersonList.value.filter((item) => {
        return item.name.toLowerCase().includes(query.toLowerCase())
      })
    }, 200)
  }
  else {
    usePersonOptions.value = usePersonList.value
  }
}

onMounted(() => {
  typeValue.value = $route.query.typeValue // 类型add、edit、detail
  form.value.id = $route.query.id as string // id
  form.value.taskId = $route.query.taskId as string // 任务id
  form.value.processId = $route.query.processId as string // 任务id
  approvalStatus.value = $route.query.approvalStatus // 审批类型
  // 编辑、详情获取详情页信息
  if (typeValue.value === 'edit' || typeValue.value === 'detail') {
    fetchReceiveApplyListDetail() // 获取详细信息
  }

  // 获取部门信息
  fetchDeptTreeList()
  // 获取人员列表--申请人使用
  fetchUserList()
})
</script>

<template>
  <app-container>
    <detail-page :title="`设备领用申请-${textMap[typeValue]}`">
      <template #btns>
        <el-button v-if="typeValue === 'edit' && approvalStatus === '2' " type="primary" @click="handleClick('agree')">
          同意
        </el-button>
        <el-button v-if="typeValue === 'edit' && approvalStatus === '2' " type="primary" @click="handleClick('reject')">
          驳回
        </el-button>
        <el-button v-if="typeValue === 'edit' && approvalStatus === '2' " type="primary" @click="handleClick('refuse')">
          拒绝
        </el-button>
        <el-button v-if="typeValue === 'add' || typeValue === 'edit'" type="primary" @click="save">
          保存
        </el-button>
        <el-button v-if="typeValue === 'add'" type="primary" @click="submit">
          提交
        </el-button>
        <el-button v-if="typeValue === 'edit' && approvalStatus === '3'" type="primary" @click="handleClick('revoke')">
          撤回
        </el-button>
        <el-button type="info" @click="close">
          关闭
        </el-button>
      </template>
    </detail-page>
    <div class="create-check">
      <div class="top-info">
        <!-- 表单 -->
        <div class="form-area">
          <el-form
            ref="ruleFormRef"
            :model="form"
            label-width="120px"
            :rules="rules"
          >
            <el-row :gutter="24">
              <el-col :span="6">
                <el-form-item label="申请名称" prop="applyName">
                  <el-input
                    v-model="form.applyName"
                    :placeholder="typeValue === 'detail' ? '' : '请输入申请名称'"
                    clearable
                    :disabled="typeValue === 'detail'"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="申请单位" prop="applyUnit">
                  <dept-select
                    v-model="form.applyUnit"
                    placeholder="请选择申请单位"
                    :data="useDeptList"
                    :disabled="typeValue === 'detail'"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="申请人" prop="applyPerson">
                  <el-select
                    v-model="form.applyPerson"
                    :disabled="typeValue === 'detail'"
                    placeholder="请选择申请人"
                    style="width: 100%;"
                    filterable
                    remote
                    remote-show-suffix
                    :remote-method="remoteMethod"
                    :loading="applyPersonLoading"
                  >
                    <el-option v-for="item in usePersonOptions" :key="item.id" :label="item.name" :value="item.id" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="领用时间" prop="time">
                  <el-date-picker
                    v-model="form.time"
                    type="datetime"
                    placeholder="请选择领用时间"
                    format="YYYY-MM-DD hh:mm"
                    value-format="YYYY-MM-DD hh:mm"
                    :disabled="typeValue === 'detail'"
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="申请说明" prop="applyDesc">
                  <el-input v-model="form.applyDesc" type="textarea" autosize clearable :disabled="typeValue === 'detail'" />
                </el-form-item>
              </el-col>
            </el-row>
          </el-form>
        </div>
      </div>
      <!-- 表格 -->
      <detail-block title="设备领用列表">
        <template #btns>
          <el-button v-if="typeValue !== 'detail'" type="primary" @click="multiAdd">
            批量添加
          </el-button>
          <el-button v-if="typeValue !== 'detail'" type="primary" @click="addRow">
            增加行
          </el-button>
          <el-button v-if="typeValue !== 'detail'" type="info" @click="delRow">
            删除行
          </el-button>
        </template>
        <el-table
          :data="list"
          border
          style="width: 100%;"
          max-height="600"
          @selection-change="handleSelectionChange"
        >
          <el-table-column type="selection" width="38" />
          <el-table-column align="center" label="序号" width="80" type="index" />
          <el-table-column
            v-for="item in columns"
            :key="item.value"
            :prop="item.value"
            :label="item.text"
            :width="item.width"
            show-overflow-tooltip
            align="center"
          >
            <template v-if="item.value === 'equipmentNo' && (typeValue === 'add' || typeValue === 'edit')" #default="scope">
              <el-input v-model="scope.row.equipmentNo" placeholder="请选择设备" class="input">
                <template #append>
                  <el-button size="small" @click="handleSelect(scope.$index, scope.row)">
                    选择
                  </el-button>
                </template>
              </el-input>
            </template>
          </el-table-column>
        </el-table>
      </detail-block>

      <detail-block v-if="typeValue === 'detail'" title="审批流程">
        <approval-record :process-id="form.processId" />
      </detail-block>
    </div>
    <select-device-dialog
      :dialog-select-divice-visible="dialogSelectDiviceVisible"
      :is-multi="isMulti"
      @closeDialog="closeDialog"
      @updateDeviceConfirm="updateDeviceConfirm"
    />

    <!-- 同意、驳回、拒绝对话框显示 -->
    <approval-dialog ref="approvalDialog" @on-success="approvalSuccess" />
  </app-container>
</template>

<style lang="scss" scoped>
// 样式
.create-check {
  margin-top: 10px;

  .top-info {
    display: flex;
    flex-direction: column;
    width: 100%;
    padding-right: 10px;
    border-radius: 10px;
    background-color: #fff;
    // padding: 10px;

    .title-button {
      display: flex;
      align-items: center;

      &::before {
        content: "";
        flex: 1;
      }

      .button-group {
        flex: 1;
        display: flex;
        justify-content: flex-end;
      }
    }

    .form-area {
      margin-top: 40px;
    }
  }
}
</style>