|
@@ -1,300 +1,229 @@
|
|
|
<template>
|
|
<template>
|
|
|
<div class="application-dialog-container">
|
|
<div class="application-dialog-container">
|
|
|
- <el-dialog
|
|
|
|
|
- :title="state.dialog.title"
|
|
|
|
|
|
|
+ <van-popup
|
|
|
|
|
+ v-model:show="state.dialog.isShowDialog"
|
|
|
|
|
+ position="bottom"
|
|
|
|
|
+ :style="{ height: '90vh' }"
|
|
|
|
|
+ round
|
|
|
|
|
+ :closeable="true"
|
|
|
@close="onCancel"
|
|
@close="onCancel"
|
|
|
- :close-on-click-modal="false"
|
|
|
|
|
- v-model="state.dialog.isShowDialog"
|
|
|
|
|
- width="90%"
|
|
|
|
|
|
|
+ :close-on-click-overlay="false"
|
|
|
>
|
|
>
|
|
|
- <el-form
|
|
|
|
|
- ref="expertDialogFormRef"
|
|
|
|
|
- :model="state.form"
|
|
|
|
|
- :rules="rules"
|
|
|
|
|
- size="default"
|
|
|
|
|
- label-width="140px"
|
|
|
|
|
- label-position="top"
|
|
|
|
|
- >
|
|
|
|
|
- <h4 class="mb20 mt8">申请人信息</h4>
|
|
|
|
|
- <el-row class="mb20">
|
|
|
|
|
- <el-col :span="24">
|
|
|
|
|
- <el-form-item
|
|
|
|
|
- label="申请人姓名"
|
|
|
|
|
- prop="userName"
|
|
|
|
|
- >
|
|
|
|
|
- <el-input
|
|
|
|
|
|
|
+ <div class="popup-wrapper">
|
|
|
|
|
+ <h3 class="popup-title">{{ state.dialog.title }}</h3>
|
|
|
|
|
+ <div class="popup-content">
|
|
|
|
|
+ <van-form
|
|
|
|
|
+ ref="expertDialogFormRef"
|
|
|
|
|
+ @submit="onSubmit"
|
|
|
|
|
+ >
|
|
|
|
|
+ <h4 class="mb20 mt8">申请人信息</h4>
|
|
|
|
|
+ <van-cell-group>
|
|
|
|
|
+ <van-field
|
|
|
v-model="state.form.userName"
|
|
v-model="state.form.userName"
|
|
|
- disabled
|
|
|
|
|
|
|
+ label="申请人姓名"
|
|
|
|
|
+ placeholder="申请人姓名"
|
|
|
|
|
+ readonly
|
|
|
|
|
+ required
|
|
|
|
|
+ :rules="rules.userName"
|
|
|
/>
|
|
/>
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- </el-row>
|
|
|
|
|
-
|
|
|
|
|
- <el-row>
|
|
|
|
|
- <el-col :span="24">
|
|
|
|
|
- <el-form-item
|
|
|
|
|
- label="联系电话"
|
|
|
|
|
- prop="phone"
|
|
|
|
|
- >
|
|
|
|
|
- <el-input
|
|
|
|
|
|
|
+ <van-field
|
|
|
v-model="state.form.phone"
|
|
v-model="state.form.phone"
|
|
|
- disabled
|
|
|
|
|
|
|
+ label="联系电话"
|
|
|
|
|
+ placeholder="联系电话"
|
|
|
|
|
+ readonly
|
|
|
/>
|
|
/>
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- </el-row>
|
|
|
|
|
-
|
|
|
|
|
- <el-row>
|
|
|
|
|
- <el-col :span="24">
|
|
|
|
|
- <el-form-item
|
|
|
|
|
- label="课题组"
|
|
|
|
|
- prop="projectGroupId"
|
|
|
|
|
- >
|
|
|
|
|
- <el-input
|
|
|
|
|
|
|
+ <van-field
|
|
|
v-model="state.form.projectGroupName"
|
|
v-model="state.form.projectGroupName"
|
|
|
- disabled
|
|
|
|
|
|
|
+ label="课题组"
|
|
|
placeholder="请选择"
|
|
placeholder="请选择"
|
|
|
- class="w100"
|
|
|
|
|
- ></el-input>
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- </el-row>
|
|
|
|
|
-
|
|
|
|
|
- <el-row>
|
|
|
|
|
- <el-col :span="24">
|
|
|
|
|
- <el-form-item
|
|
|
|
|
- label="科室"
|
|
|
|
|
- prop="deptId"
|
|
|
|
|
- >
|
|
|
|
|
- <el-input
|
|
|
|
|
|
|
+ readonly
|
|
|
|
|
+ required
|
|
|
|
|
+ :rules="rules.projectGroupId"
|
|
|
|
|
+ />
|
|
|
|
|
+ <van-field
|
|
|
v-model="state.form.deptName"
|
|
v-model="state.form.deptName"
|
|
|
- disabled
|
|
|
|
|
|
|
+ label="科室"
|
|
|
|
|
+ placeholder="科室"
|
|
|
|
|
+ readonly
|
|
|
/>
|
|
/>
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- </el-row>
|
|
|
|
|
-
|
|
|
|
|
- <h4 class="mb20 mt20">转出情况</h4>
|
|
|
|
|
- <el-row
|
|
|
|
|
- class="mb20"
|
|
|
|
|
- >
|
|
|
|
|
- <el-col :span="24">
|
|
|
|
|
- <el-form-item
|
|
|
|
|
- label="品种品系"
|
|
|
|
|
- prop="categoryId"
|
|
|
|
|
- >
|
|
|
|
|
- <el-select
|
|
|
|
|
- v-model="state.form.categoryId"
|
|
|
|
|
|
|
+ </van-cell-group>
|
|
|
|
|
+
|
|
|
|
|
+ <h4 class="mb20 mt20">转出情况</h4>
|
|
|
|
|
+ <van-cell-group>
|
|
|
|
|
+ <van-field
|
|
|
|
|
+ v-model="state.form.categoryName"
|
|
|
|
|
+ label="动物品系"
|
|
|
placeholder="请选择"
|
|
placeholder="请选择"
|
|
|
- :disabled="state.dialog.type === 'detail'"
|
|
|
|
|
- >
|
|
|
|
|
- <el-option
|
|
|
|
|
- v-for="item in animalTypeList"
|
|
|
|
|
- :key="item.id"
|
|
|
|
|
- :label="item.name"
|
|
|
|
|
- :value="item.id"
|
|
|
|
|
- />
|
|
|
|
|
- </el-select>
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- </el-row>
|
|
|
|
|
-
|
|
|
|
|
- <el-row>
|
|
|
|
|
- <el-col :span="24">
|
|
|
|
|
- <el-form-item
|
|
|
|
|
- label="转出日期"
|
|
|
|
|
- prop="takeawayDate"
|
|
|
|
|
- >
|
|
|
|
|
- <el-date-picker
|
|
|
|
|
|
|
+ readonly
|
|
|
|
|
+ is-link
|
|
|
|
|
+ required
|
|
|
|
|
+ @click="showCategoryPicker = true"
|
|
|
|
|
+ :rules="rules.categoryId"
|
|
|
|
|
+ />
|
|
|
|
|
+ <van-field
|
|
|
|
|
+ v-model="state.form.variety"
|
|
|
|
|
+ label="品种品系"
|
|
|
|
|
+ placeholder="请输入品种品系"
|
|
|
|
|
+ />
|
|
|
|
|
+ <van-field
|
|
|
v-model="state.form.takeawayDate"
|
|
v-model="state.form.takeawayDate"
|
|
|
- type="date"
|
|
|
|
|
|
|
+ label="转出日期"
|
|
|
placeholder="请选择时间"
|
|
placeholder="请选择时间"
|
|
|
- clearable
|
|
|
|
|
- value-format="YYYY-MM-DD"
|
|
|
|
|
- style="width: 100%"
|
|
|
|
|
- :disabled="state.dialog.type === 'detail'"
|
|
|
|
|
|
|
+ readonly
|
|
|
|
|
+ is-link
|
|
|
|
|
+ required
|
|
|
|
|
+ @click="showDatePicker = true"
|
|
|
|
|
+ :rules="rules.takeawayDate"
|
|
|
/>
|
|
/>
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- </el-row>
|
|
|
|
|
-
|
|
|
|
|
- <el-row
|
|
|
|
|
- class="mb20"
|
|
|
|
|
- >
|
|
|
|
|
- <el-col :span="24">
|
|
|
|
|
- <el-form-item
|
|
|
|
|
- label="送往地点"
|
|
|
|
|
- prop="takeawayAddress"
|
|
|
|
|
- >
|
|
|
|
|
- <el-input
|
|
|
|
|
|
|
+ <van-field
|
|
|
v-model="state.form.takeawayAddress"
|
|
v-model="state.form.takeawayAddress"
|
|
|
|
|
+ label="送往地点"
|
|
|
placeholder="请输入"
|
|
placeholder="请输入"
|
|
|
- :disabled="state.dialog.type === 'detail'"
|
|
|
|
|
|
|
+ required
|
|
|
|
|
+ :rules="rules.takeawayAddress"
|
|
|
/>
|
|
/>
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- </el-row>
|
|
|
|
|
-
|
|
|
|
|
- <el-row>
|
|
|
|
|
- <el-col :span="24">
|
|
|
|
|
- <el-form-item
|
|
|
|
|
- label="带出原因"
|
|
|
|
|
- prop="takeawayReason"
|
|
|
|
|
- >
|
|
|
|
|
- <el-input
|
|
|
|
|
|
|
+ <van-field
|
|
|
v-model="state.form.takeawayReason"
|
|
v-model="state.form.takeawayReason"
|
|
|
|
|
+ label="带出原因"
|
|
|
placeholder="请输入"
|
|
placeholder="请输入"
|
|
|
- :disabled="state.dialog.type === 'detail'"
|
|
|
|
|
|
|
+ required
|
|
|
|
|
+ :rules="rules.takeawayReason"
|
|
|
/>
|
|
/>
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- </el-row>
|
|
|
|
|
-
|
|
|
|
|
- <el-row
|
|
|
|
|
- class="mb20"
|
|
|
|
|
- >
|
|
|
|
|
- <el-col :span="24">
|
|
|
|
|
- <el-form-item
|
|
|
|
|
- label="运输方式"
|
|
|
|
|
- prop="takeawayTransport"
|
|
|
|
|
- >
|
|
|
|
|
- <el-input
|
|
|
|
|
|
|
+ <van-field
|
|
|
v-model="state.form.takeawayTransport"
|
|
v-model="state.form.takeawayTransport"
|
|
|
|
|
+ label="运输方式"
|
|
|
placeholder="请输入"
|
|
placeholder="请输入"
|
|
|
- :disabled="state.dialog.type === 'detail'"
|
|
|
|
|
|
|
+ required
|
|
|
|
|
+ :rules="rules.takeawayTransport"
|
|
|
/>
|
|
/>
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- </el-row>
|
|
|
|
|
-
|
|
|
|
|
- <el-row>
|
|
|
|
|
- <el-col :span="24">
|
|
|
|
|
- <el-form-item
|
|
|
|
|
- label="门禁卡序列号"
|
|
|
|
|
- prop="accessCardNumber"
|
|
|
|
|
- >
|
|
|
|
|
- <el-input
|
|
|
|
|
|
|
+ <van-field
|
|
|
v-model="state.form.accessCardNumber"
|
|
v-model="state.form.accessCardNumber"
|
|
|
|
|
+ label="门禁卡序列号"
|
|
|
placeholder="请输入"
|
|
placeholder="请输入"
|
|
|
- :disabled="state.dialog.type === 'detail'"
|
|
|
|
|
/>
|
|
/>
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- </el-row>
|
|
|
|
|
-
|
|
|
|
|
- <el-row
|
|
|
|
|
- class="mt10"
|
|
|
|
|
- >
|
|
|
|
|
- <el-col :span="24">
|
|
|
|
|
- <el-form-item
|
|
|
|
|
- label="雄性"
|
|
|
|
|
- prop="takeawayMaleNumber"
|
|
|
|
|
- >
|
|
|
|
|
- <el-input-number
|
|
|
|
|
- style="width: 100%"
|
|
|
|
|
- placeholder="雄性数量"
|
|
|
|
|
|
|
+ <van-field
|
|
|
v-model="state.form.takeawayMaleNumber"
|
|
v-model="state.form.takeawayMaleNumber"
|
|
|
- :min="0"
|
|
|
|
|
- :disabled="state.dialog.type === 'detail'"
|
|
|
|
|
- />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- </el-row>
|
|
|
|
|
-
|
|
|
|
|
- <el-row>
|
|
|
|
|
- <el-col :span="24">
|
|
|
|
|
- <el-form-item
|
|
|
|
|
- label="雌性"
|
|
|
|
|
- prop="takewayFemaleNumber"
|
|
|
|
|
- >
|
|
|
|
|
- <el-input-number
|
|
|
|
|
- style="width: 100%"
|
|
|
|
|
- placeholder="雌性数量"
|
|
|
|
|
|
|
+ label="雄性"
|
|
|
|
|
+ placeholder="雄性数量"
|
|
|
|
|
+ type="digit"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #button>
|
|
|
|
|
+ <van-stepper
|
|
|
|
|
+ v-model="state.form.takeawayMaleNumber"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ integer
|
|
|
|
|
+ />
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </van-field>
|
|
|
|
|
+ <van-field
|
|
|
v-model="state.form.takewayFemaleNumber"
|
|
v-model="state.form.takewayFemaleNumber"
|
|
|
- :min="0"
|
|
|
|
|
- :disabled="state.dialog.type === 'detail'"
|
|
|
|
|
- />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- </el-row>
|
|
|
|
|
-
|
|
|
|
|
- <el-row
|
|
|
|
|
- class="mt10"
|
|
|
|
|
- >
|
|
|
|
|
- <el-col
|
|
|
|
|
- :span="24"
|
|
|
|
|
- class="mt30 mb30"
|
|
|
|
|
- >
|
|
|
|
|
- <el-checkbox
|
|
|
|
|
- v-model="safePromiseStatus"
|
|
|
|
|
- :disabled="state.dialog.type === 'detail'"
|
|
|
|
|
- >
|
|
|
|
|
- 本人已阅读并同意
|
|
|
|
|
- <el-link
|
|
|
|
|
- type="primary"
|
|
|
|
|
- :underline="false"
|
|
|
|
|
- @click="handleReadNotice"
|
|
|
|
|
|
|
+ label="雌性"
|
|
|
|
|
+ placeholder="雌性数量"
|
|
|
|
|
+ type="digit"
|
|
|
>
|
|
>
|
|
|
- 《实验动物带离须知》
|
|
|
|
|
- </el-link>
|
|
|
|
|
- 内容
|
|
|
|
|
- </el-checkbox>
|
|
|
|
|
- </el-col>
|
|
|
|
|
- </el-row>
|
|
|
|
|
- </el-form>
|
|
|
|
|
-
|
|
|
|
|
- <template #footer>
|
|
|
|
|
- <span class="dialog-footer">
|
|
|
|
|
- <el-button
|
|
|
|
|
- type="info"
|
|
|
|
|
- @click="onCancel"
|
|
|
|
|
- size="default"
|
|
|
|
|
- >
|
|
|
|
|
- 取 消
|
|
|
|
|
- </el-button>
|
|
|
|
|
- <el-button
|
|
|
|
|
|
|
+ <template #button>
|
|
|
|
|
+ <van-stepper
|
|
|
|
|
+ v-model="state.form.takewayFemaleNumber"
|
|
|
|
|
+ :min="0"
|
|
|
|
|
+ integer
|
|
|
|
|
+ />
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </van-field>
|
|
|
|
|
+ </van-cell-group>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="mt30 mb30 checkbox-wrapper">
|
|
|
|
|
+ <van-checkbox v-model="safePromiseStatus">
|
|
|
|
|
+ 本人已阅读并同意
|
|
|
|
|
+ <span
|
|
|
|
|
+ class="link-text"
|
|
|
|
|
+ @click.stop="handleReadNotice"
|
|
|
|
|
+ >
|
|
|
|
|
+ 《实验动物带离须知》
|
|
|
|
|
+ </span>
|
|
|
|
|
+ 内容
|
|
|
|
|
+ </van-checkbox>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </van-form>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="dialog-footer">
|
|
|
|
|
+ <van-button
|
|
|
v-if="state.dialog.type !== 'detail'"
|
|
v-if="state.dialog.type !== 'detail'"
|
|
|
- color="#2c78ff"
|
|
|
|
|
- @click="onSubmit()"
|
|
|
|
|
- size="default"
|
|
|
|
|
|
|
+ type="primary"
|
|
|
|
|
+ @click="onSubmit"
|
|
|
|
|
+ block
|
|
|
|
|
+ native-type="submit"
|
|
|
>
|
|
>
|
|
|
提交
|
|
提交
|
|
|
- </el-button>
|
|
|
|
|
- </span>
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-dialog>
|
|
|
|
|
-
|
|
|
|
|
- <el-dialog
|
|
|
|
|
- v-model="isShowNotice"
|
|
|
|
|
- title="实验动物带离须知"
|
|
|
|
|
- width="90%"
|
|
|
|
|
|
|
+ </van-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </van-popup>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 动物品系选择器 -->
|
|
|
|
|
+ <van-popup
|
|
|
|
|
+ v-model:show="showCategoryPicker"
|
|
|
|
|
+ position="bottom"
|
|
|
|
|
+ >
|
|
|
|
|
+ <van-picker
|
|
|
|
|
+ :columns="animalTypeList"
|
|
|
|
|
+ :columns-field-names="{ text: 'name', value: 'id' }"
|
|
|
|
|
+ @confirm="onCategoryConfirm"
|
|
|
|
|
+ @cancel="showCategoryPicker = false"
|
|
|
|
|
+ />
|
|
|
|
|
+ </van-popup>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 日期选择器 - 使用日历组件 -->
|
|
|
|
|
+ <van-popup
|
|
|
|
|
+ v-model:show="showDatePicker"
|
|
|
|
|
+ position="bottom"
|
|
|
|
|
+ :style="{ height: '80vh' }"
|
|
|
|
|
+ round
|
|
|
>
|
|
>
|
|
|
- <div class="text">
|
|
|
|
|
- <p
|
|
|
|
|
- class="mb20"
|
|
|
|
|
- v-for="item in AnimalRemovalApplicationNotice.split('\n')"
|
|
|
|
|
- :key="item"
|
|
|
|
|
- >
|
|
|
|
|
- {{ item }}
|
|
|
|
|
- </p>
|
|
|
|
|
|
|
+ <van-calendar
|
|
|
|
|
+ v-model:show="showDatePicker"
|
|
|
|
|
+ @confirm="onDateConfirm"
|
|
|
|
|
+ :min-date="new Date()"
|
|
|
|
|
+ />
|
|
|
|
|
+ </van-popup>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 须知弹窗 -->
|
|
|
|
|
+ <van-popup
|
|
|
|
|
+ v-model:show="isShowNotice"
|
|
|
|
|
+ position="bottom"
|
|
|
|
|
+ round
|
|
|
|
|
+ :closeable="true"
|
|
|
|
|
+ :style="{ height: '70vh' }"
|
|
|
|
|
+ >
|
|
|
|
|
+ <div class="notice-content">
|
|
|
|
|
+ <h4 class="notice-title">实验动物带离须知</h4>
|
|
|
|
|
+ <div class="text">
|
|
|
|
|
+ <p
|
|
|
|
|
+ class="mb20"
|
|
|
|
|
+ v-for="(item, index) in AnimalRemovalApplicationNotice.split('\n').filter((item) => item.trim())"
|
|
|
|
|
+ :key="index"
|
|
|
|
|
+ >
|
|
|
|
|
+ {{ item }}
|
|
|
|
|
+ </p>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div class="notice-footer">
|
|
|
|
|
+ <van-button
|
|
|
|
|
+ type="primary"
|
|
|
|
|
+ @click="isShowNotice = false"
|
|
|
|
|
+ block
|
|
|
|
|
+ >
|
|
|
|
|
+ 确定
|
|
|
|
|
+ </van-button>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
- <template #footer>
|
|
|
|
|
- <el-button
|
|
|
|
|
- type="primary"
|
|
|
|
|
- @click="isShowNotice = false"
|
|
|
|
|
- >
|
|
|
|
|
- 确定
|
|
|
|
|
- </el-button>
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-dialog>
|
|
|
|
|
|
|
+ </van-popup>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
import { reactive, ref, computed } from 'vue'
|
|
import { reactive, ref, computed } from 'vue'
|
|
|
import to from 'await-to-js'
|
|
import to from 'await-to-js'
|
|
|
- import { ElMessage } from 'element-plus'
|
|
|
|
|
- import type { FormRules, FormInstance } from 'element-plus'
|
|
|
|
|
|
|
+ import { showToast, showNotify } from 'vant'
|
|
|
|
|
+ import type { FormInstance } from 'vant/es'
|
|
|
|
|
|
|
|
import { usePlatAnimalCageApplicationApi } from '/@/api/platform/animal'
|
|
import { usePlatAnimalCageApplicationApi } from '/@/api/platform/animal'
|
|
|
import {
|
|
import {
|
|
@@ -306,6 +235,7 @@
|
|
|
import { deepClone } from '/@/utils/other'
|
|
import { deepClone } from '/@/utils/other'
|
|
|
import { useUserInfos } from '/@/hooks/useUserInfos'
|
|
import { useUserInfos } from '/@/hooks/useUserInfos'
|
|
|
import { filterFields } from '/@/utils/func'
|
|
import { filterFields } from '/@/utils/func'
|
|
|
|
|
+ import { formatDate } from '/@/utils/formatTime'
|
|
|
|
|
|
|
|
const emit = defineEmits(['refresh'])
|
|
const emit = defineEmits(['refresh'])
|
|
|
|
|
|
|
@@ -316,20 +246,25 @@
|
|
|
const animalTypeList = ref<{ id: string; name: string }[]>([])
|
|
const animalTypeList = ref<{ id: string; name: string }[]>([])
|
|
|
const safePromiseStatus = ref<boolean>(false)
|
|
const safePromiseStatus = ref<boolean>(false)
|
|
|
const isShowNotice = ref<boolean>(false)
|
|
const isShowNotice = ref<boolean>(false)
|
|
|
|
|
+ const showCategoryPicker = ref<boolean>(false)
|
|
|
|
|
+ const showDatePicker = ref<boolean>(false)
|
|
|
|
|
+ const selectedDate = ref<Date | null>(null)
|
|
|
|
|
+
|
|
|
|
|
+ const rules = {
|
|
|
|
|
+ categoryId: [{ required: true, message: '动物品系不能为空' }],
|
|
|
|
|
+ projectGroupId: [{ required: true, message: '课题组不能为空' }],
|
|
|
|
|
+ takeawayDate: [{ required: true, message: '转出日期不能为空' }],
|
|
|
|
|
+ userName: [{ required: true, message: '申请人姓名不能为空' }],
|
|
|
|
|
+ takeawayAddress: [{ required: true, message: '送往地点不能为空' }],
|
|
|
|
|
+ takeawayReason: [{ required: true, message: '带出原因不能为空' }],
|
|
|
|
|
+ takeawayTransport: [{ required: true, message: '运输方式不能为空' }],
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- const rules = reactive<FormRules<CreateAnimalApplyLeavePayload>>({
|
|
|
|
|
- categoryId: [{ required: true, message: '请选择动物种类', trigger: 'blur' }],
|
|
|
|
|
- projectGroupId: [{ required: true, message: '请选择项目组', trigger: 'blur' }],
|
|
|
|
|
- takeawayDate: [{ required: true, message: '请选择转出日期', trigger: 'blur' }],
|
|
|
|
|
- userName: [{ required: true, message: '请输入申请人姓名', trigger: 'blur' }],
|
|
|
|
|
- takeawayAddress: [{ required: true, message: '不能为空', trigger: 'change' }],
|
|
|
|
|
- takeawayReason: [{ required: true, message: '不能为空', trigger: 'change' }],
|
|
|
|
|
- takeawayTransport: [{ required: true, message: '不能为空', trigger: 'change' }],
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- const defaultFormFields: CreateAnimalApplyLeavePayload = {
|
|
|
|
|
|
|
+ const defaultFormFields: CreateAnimalApplyLeavePayload & { categoryName?: string } = {
|
|
|
accessCardNumber: '',
|
|
accessCardNumber: '',
|
|
|
categoryId: null,
|
|
categoryId: null,
|
|
|
|
|
+ categoryName: '',
|
|
|
|
|
+ variety: '',
|
|
|
projectGroupId: null,
|
|
projectGroupId: null,
|
|
|
projectGroupName: '',
|
|
projectGroupName: '',
|
|
|
takeawayDate: '',
|
|
takeawayDate: '',
|
|
@@ -345,7 +280,7 @@
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const state = reactive<{
|
|
const state = reactive<{
|
|
|
- form: CreateAnimalApplyLeavePayload
|
|
|
|
|
|
|
+ form: CreateAnimalApplyLeavePayload & { categoryName?: string }
|
|
|
safePromise: boolean
|
|
safePromise: boolean
|
|
|
safeRead: boolean
|
|
safeRead: boolean
|
|
|
dialog: { isShowDialog: boolean; type: string; title: string; submitTxt: string }
|
|
dialog: { isShowDialog: boolean; type: string; title: string; submitTxt: string }
|
|
@@ -360,13 +295,7 @@
|
|
|
submitTxt: '',
|
|
submitTxt: '',
|
|
|
},
|
|
},
|
|
|
})
|
|
})
|
|
|
-
|
|
|
|
|
- const animalNumber = computed(() => {
|
|
|
|
|
- const maleNumber = state.form.takeawayMaleNumber || 0
|
|
|
|
|
- const famaleNumber = state.form.takewayFemaleNumber || 0
|
|
|
|
|
- return maleNumber + famaleNumber
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
const getDicts = async () => {
|
|
const getDicts = async () => {
|
|
|
const [_, res]: ToResponse = await to(platAnimalCageApplicationApi.getAnimalTypeList({}))
|
|
const [_, res]: ToResponse = await to(platAnimalCageApplicationApi.getAnimalTypeList({}))
|
|
|
|
|
|
|
@@ -390,11 +319,26 @@
|
|
|
...state.form,
|
|
...state.form,
|
|
|
...sourceData,
|
|
...sourceData,
|
|
|
}
|
|
}
|
|
|
|
|
+ // 设置 categoryName 用于显示
|
|
|
|
|
+ if (sourceData.categoryId) {
|
|
|
|
|
+ const category = animalTypeList.value.find((item) => item.id === sourceData.categoryId)
|
|
|
|
|
+ if (category) {
|
|
|
|
|
+ state.form.categoryName = category.name
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ // 设置日期选择器的值
|
|
|
|
|
+ if (sourceData.takeawayDate) {
|
|
|
|
|
+ const dateParts = sourceData.takeawayDate.split('-')
|
|
|
|
|
+ selectedDate.value = new Date(parseInt(dateParts[0]), parseInt(dateParts[1]) - 1, parseInt(dateParts[2]))
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (type === 'add') {
|
|
if (type === 'add') {
|
|
|
state.dialog.title = '新增实验动物带离单'
|
|
state.dialog.title = '新增实验动物带离单'
|
|
|
- state.form.categoryId = animalTypeList.value[0].id
|
|
|
|
|
|
|
+ if (animalTypeList.value.length > 0) {
|
|
|
|
|
+ state.form.categoryId = animalTypeList.value[0].id
|
|
|
|
|
+ state.form.categoryName = animalTypeList.value[0].name
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
if (type === 'edit') {
|
|
if (type === 'edit') {
|
|
|
state.dialog.title = '编辑实验动物带离单'
|
|
state.dialog.title = '编辑实验动物带离单'
|
|
@@ -408,8 +352,28 @@
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const closeDialog = () => {
|
|
const closeDialog = () => {
|
|
|
- expertDialogFormRef.value.resetFields()
|
|
|
|
|
- state.form = defaultFormFields
|
|
|
|
|
|
|
+ expertDialogFormRef.value?.resetValidation()
|
|
|
|
|
+ // 重置表单数据
|
|
|
|
|
+ state.form = {
|
|
|
|
|
+ accessCardNumber: '',
|
|
|
|
|
+ categoryId: null,
|
|
|
|
|
+ categoryName: '',
|
|
|
|
|
+ variety: '',
|
|
|
|
|
+ projectGroupId: null,
|
|
|
|
|
+ projectGroupName: '',
|
|
|
|
|
+ takeawayDate: '',
|
|
|
|
|
+ takeawayAddress: '',
|
|
|
|
|
+ takeawayReason: '',
|
|
|
|
|
+ takeawayTransport: '',
|
|
|
|
|
+ takewayFemaleNumber: 0,
|
|
|
|
|
+ takeawayMaleNumber: 0,
|
|
|
|
|
+ userName: '',
|
|
|
|
|
+ phone: '',
|
|
|
|
|
+ deptId: '',
|
|
|
|
|
+ deptName: '',
|
|
|
|
|
+ }
|
|
|
|
|
+ safePromiseStatus.value = false
|
|
|
|
|
+ selectedDate.value = null
|
|
|
state.dialog.isShowDialog = false
|
|
state.dialog.isShowDialog = false
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -418,35 +382,80 @@
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const onSubmit = async () => {
|
|
const onSubmit = async () => {
|
|
|
- expertDialogFormRef.value.validate(async (valid: boolean) => {
|
|
|
|
|
- if (!valid) return
|
|
|
|
|
-
|
|
|
|
|
- if (!safePromiseStatus.value) {
|
|
|
|
|
- ElMessage.error('请阅读并勾选安全承诺!')
|
|
|
|
|
- return
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ await expertDialogFormRef.value?.validate()
|
|
|
|
|
+ } catch (error: any) {
|
|
|
|
|
+ // 显示表单验证错误
|
|
|
|
|
+ let errorMessage = '请完善必填信息'
|
|
|
|
|
+ if (error) {
|
|
|
|
|
+ // Vant 表单验证错误可能是数组格式
|
|
|
|
|
+ if (Array.isArray(error) && error.length > 0) {
|
|
|
|
|
+ const firstError = error[0]
|
|
|
|
|
+ if (firstError && firstError.message) {
|
|
|
|
|
+ errorMessage = firstError.message
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if (error.message) {
|
|
|
|
|
+ errorMessage = error.message
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
+ showNotify({
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ message: errorMessage,
|
|
|
|
|
+ })
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- if (!state.form.takeawayMaleNumber && !state.form.takewayFemaleNumber) {
|
|
|
|
|
- ElMessage.error('请添加雄性或雌性数量!')
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (!safePromiseStatus.value) {
|
|
|
|
|
+ showNotify({
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ message: '请阅读并勾选安全承诺!',
|
|
|
|
|
+ })
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!state.form.takeawayMaleNumber && !state.form.takewayFemaleNumber) {
|
|
|
|
|
+ showNotify({
|
|
|
|
|
+ type: 'warning',
|
|
|
|
|
+ message: '请添加雄性或雌性数量!',
|
|
|
|
|
+ })
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- const post = platAnimalCageApplicationApi.createAnimalTakeawayApplications
|
|
|
|
|
- const [err]: ToResponse = await to(
|
|
|
|
|
- post(
|
|
|
|
|
- filterFields({
|
|
|
|
|
- ...deepClone(state.form),
|
|
|
|
|
- deptId: userInfos.value.deptId,
|
|
|
|
|
- projectGroupId: state.form.projectGroupId?.toString(),
|
|
|
|
|
- }),
|
|
|
|
|
- ),
|
|
|
|
|
- )
|
|
|
|
|
-
|
|
|
|
|
- if (err) return
|
|
|
|
|
- ElMessage.success('操作成功')
|
|
|
|
|
- closeDialog()
|
|
|
|
|
- emit('refresh')
|
|
|
|
|
|
|
+ const post = platAnimalCageApplicationApi.createAnimalTakeawayApplications
|
|
|
|
|
+ const [err]: ToResponse = await to(
|
|
|
|
|
+ post(
|
|
|
|
|
+ filterFields({
|
|
|
|
|
+ ...deepClone(state.form),
|
|
|
|
|
+ deptId: userInfos.value.deptId,
|
|
|
|
|
+ projectGroupId: state.form.projectGroupId?.toString(),
|
|
|
|
|
+ takeawayMaleNumber: Number(state.form.takeawayMaleNumber) || 0,
|
|
|
|
|
+ takewayFemaleNumber: Number(state.form.takewayFemaleNumber) || 0,
|
|
|
|
|
+ }),
|
|
|
|
|
+ ),
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ if (err) return
|
|
|
|
|
+ showToast({
|
|
|
|
|
+ type: 'success',
|
|
|
|
|
+ message: '操作成功',
|
|
|
})
|
|
})
|
|
|
|
|
+ closeDialog()
|
|
|
|
|
+ emit('refresh')
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const onCategoryConfirm = ({ selectedOptions }: { selectedOptions: any[] }) => {
|
|
|
|
|
+ if (selectedOptions.length > 0) {
|
|
|
|
|
+ const selected = selectedOptions[0]
|
|
|
|
|
+ state.form.categoryId = selected.id
|
|
|
|
|
+ state.form.categoryName = selected.name
|
|
|
|
|
+ }
|
|
|
|
|
+ showCategoryPicker.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const onDateConfirm = (date: Date) => {
|
|
|
|
|
+ selectedDate.value = date
|
|
|
|
|
+ state.form.takeawayDate = formatDate(date, 'YYYY-mm-dd')
|
|
|
|
|
+ showDatePicker.value = false
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const handleReadNotice = () => {
|
|
const handleReadNotice = () => {
|
|
@@ -459,25 +468,126 @@
|
|
|
</script>
|
|
</script>
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
|
.application-dialog-container {
|
|
.application-dialog-container {
|
|
|
- .el-select {
|
|
|
|
|
- width: 100%;
|
|
|
|
|
|
|
+ .popup-wrapper {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ overflow: hidden;
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- h4 {
|
|
|
|
|
- font-size: 18px;
|
|
|
|
|
- }
|
|
|
|
|
- ul {
|
|
|
|
|
- padding-left: 20px;
|
|
|
|
|
- }
|
|
|
|
|
- .text {
|
|
|
|
|
- p {
|
|
|
|
|
- text-indent: 2em;
|
|
|
|
|
|
|
+
|
|
|
|
|
+ .popup-title {
|
|
|
|
|
+ font-size: 18px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ padding: 16px 0;
|
|
|
|
|
+ margin: 0;
|
|
|
|
|
+ border-bottom: 1px solid #ebedf0;
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ background-color: #fff;
|
|
|
|
|
+ position: sticky;
|
|
|
|
|
+ top: 0;
|
|
|
|
|
+ z-index: 1;
|
|
|
|
|
+ padding-right: 40px; // 为关闭按钮留出空间
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .popup-content {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ padding: 16px;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+ -webkit-overflow-scrolling: touch;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ h4 {
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ margin: 16px 0 8px;
|
|
|
|
|
+ padding-left: 8px;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+
|
|
|
|
|
+ &::before {
|
|
|
|
|
+ content: '';
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ top: 50%;
|
|
|
|
|
+ transform: translateY(-50%);
|
|
|
|
|
+ width: 3px;
|
|
|
|
|
+ height: 16px;
|
|
|
|
|
+ background-color: #1c9bfd;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .checkbox-wrapper {
|
|
|
|
|
+ padding: 16px;
|
|
|
|
|
+ background-color: #f7f8fa;
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ margin: 16px 0;
|
|
|
|
|
+
|
|
|
|
|
+ .link-text {
|
|
|
|
|
+ color: #1989fa;
|
|
|
|
|
+ text-decoration: underline;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .dialog-footer {
|
|
|
|
|
+ padding: 16px;
|
|
|
|
|
+ padding-bottom: calc(16px + env(safe-area-inset-bottom));
|
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
|
+ background-color: #fff;
|
|
|
|
|
+ border-top: 1px solid #ebedf0;
|
|
|
|
|
+ position: sticky;
|
|
|
|
|
+ bottom: 0;
|
|
|
|
|
+ z-index: 10;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .notice-content {
|
|
|
|
|
+ padding: 16px;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+
|
|
|
|
|
+ .notice-title {
|
|
|
|
|
+ font-size: 18px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ padding: 16px 0;
|
|
|
|
|
+ margin: 0 0 16px;
|
|
|
|
|
+ border-bottom: 1px solid #ebedf0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .text {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+ padding: 0 8px;
|
|
|
|
|
+
|
|
|
|
|
+ p {
|
|
|
|
|
+ text-indent: 2em;
|
|
|
|
|
+ line-height: 1.6;
|
|
|
|
|
+ margin-bottom: 12px;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .notice-footer {
|
|
|
|
|
+ padding-top: 16px;
|
|
|
|
|
+ border-top: 1px solid #ebedf0;
|
|
|
|
|
+ margin-top: 16px;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- .el-upload + .el-button {
|
|
|
|
|
- vertical-align: top;
|
|
|
|
|
- }
|
|
|
|
|
- :deep(.el-checkbox) {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.van-checkbox) {
|
|
|
white-space: pre-wrap;
|
|
white-space: pre-wrap;
|
|
|
|
|
+ line-height: 1.6;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.van-field__label) {
|
|
|
|
|
+ width: 120px;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 确保关闭按钮显示在标题上方
|
|
|
|
|
+ :deep(.van-popup__close-icon) {
|
|
|
|
|
+ z-index: 100;
|
|
|
|
|
+ top: 16px;
|
|
|
|
|
+ right: 16px;
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|