|
|
@@ -0,0 +1,299 @@
|
|
|
+<!--
|
|
|
+ * @Author: wanglj wanglijie@dashoo.cn
|
|
|
+ * @Date: 2025-03-18 20:02:42
|
|
|
+ * @LastEditors: wanglj wanglijie@dashoo.cn
|
|
|
+ * @LastEditTime: 2025-03-21 09:46:32
|
|
|
+ * @FilePath: \labsop_h5\src\view\training\enroll.vue
|
|
|
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
|
|
+-->
|
|
|
+<template>
|
|
|
+ <div class="app-container">
|
|
|
+ <van-form ref="formRef" @submit="onSubmit('20')" class="mt10" required="auto">
|
|
|
+ <!-- <h4 class="mb8 mt8">申请人课题组信息</h4>
|
|
|
+ <van-cell-group>
|
|
|
+ <van-field v-model="state.form.pgName" label="课题组" placeholder="课题组" readonly :rules="[{ required: true }]" />
|
|
|
+ <van-field v-model="state.form.mentorName" label="课题组负责人" placeholder="课题组负责人" readonly />
|
|
|
+ <van-field v-model="state.form.mentorDeptName" label="课题组负责人科室" placeholder="课题组负责人科室" readonly />
|
|
|
+ <van-field v-model="state.form.mentorPhone" label="课题组负责人电话" placeholder="课题组负责人电话" readonly />
|
|
|
+ </van-cell-group> -->
|
|
|
+ <h4 class="mb8 mt8">申请入室平台</h4>
|
|
|
+ <van-cell-group v-for="(item, index) in state.form.platformList" :key="item.id">
|
|
|
+ <van-field label="申请平台" placeholder="申请平台">
|
|
|
+ <template #input>
|
|
|
+ <van-checkbox v-model="item.isChecked" name="10">{{ item.platformName }}</van-checkbox>
|
|
|
+ </template>
|
|
|
+ </van-field>
|
|
|
+ <van-field v-model.number="item.platformTime" label="申请时长(月)" placeholder="申请时长(月)" type="number" :disabled="!item.isChecked">
|
|
|
+ <template #extra>个月</template>
|
|
|
+ </van-field>
|
|
|
+ <template v-if="item.platformType == '10'">
|
|
|
+ <van-field v-model="item.cellType" label="拟培养细胞种类" placeholder="拟培养细胞种类" :disabled="!item.isChecked" />
|
|
|
+ <van-field v-model="item.cellType" label="细胞房预约需求" placeholder="细胞房预约需求">
|
|
|
+ <template #input>
|
|
|
+ <van-radio-group v-model="item.cellSourceType" :disabled="!item.isChecked" direction="horizontal">
|
|
|
+ <van-radio v-for="o in item.platformResourceType" :name="o.dictValue">{{ o.dictLabel }}</van-radio>
|
|
|
+ </van-radio-group>
|
|
|
+ </template>
|
|
|
+ </van-field>
|
|
|
+ </template>
|
|
|
+ <template v-else-if="item.platformType == '20'">
|
|
|
+ <van-field v-model="item.platOtherNeed" label="其他需求" placeholder="其他需求" :disabled="!item.isChecked" />
|
|
|
+ </template>
|
|
|
+ </van-cell-group>
|
|
|
+ <h4 class="mb8 mt8">申请人信息</h4>
|
|
|
+ <van-cell-group>
|
|
|
+ <van-field v-model="state.form.memberName" label="申请人姓名" placeholder="申请人姓名" readonly :rules="[{ required: true }]" />
|
|
|
+ <van-field v-model="state.form.memberType" label="人员类型" placeholder="人员类型" readonly :rules="[{ required: true }]">
|
|
|
+ <template #input>{{ getDictLabel(userTypeList, state.form.memberType) }}</template>
|
|
|
+ </van-field>
|
|
|
+ <van-field v-model="state.form.memberPhone" label="申请人手机号" placeholder="申请人手机号" readonly />
|
|
|
+ <van-field v-model="state.form.deptName" label="申请人科室" placeholder="申请人科室" readonly />
|
|
|
+ <van-field v-model="state.form.pgName" label="课题组" placeholder="课题组" readonly :rules="[{ required: true }]" />
|
|
|
+ </van-cell-group>
|
|
|
+ <h4 class="mb8 mt8">安全承诺</h4>
|
|
|
+ <van-checkbox v-model="state.safePromise">本人承诺:如时候遵守实验室及个平台的各项规章制度,遵守在室的积分管理制度。</van-checkbox>
|
|
|
+ <van-checkbox v-model="state.safeRead" :disabled="!state.isRead">
|
|
|
+ 我已完整阅读并同意
|
|
|
+ <a href="javascript:void(0);" @click.stop="onRead">《预约须知》</a>
|
|
|
+ 的内容,承诺如时候遵守实验室及个平台的各项规章制度,遵守在室的积分管理制度。
|
|
|
+ </van-checkbox>
|
|
|
+ <div style="margin: 16px">
|
|
|
+ <van-button round block type="primary" native-type="submit"> 提交 </van-button>
|
|
|
+ </div>
|
|
|
+ </van-form>
|
|
|
+ </div>
|
|
|
+ <van-dialog v-model:show="noticeShow" :title="noticeInfo.noticeTitle" show-cancel-button>
|
|
|
+ <div class="ck-editor" v-html="noticeInfo.noticeContent"></div>
|
|
|
+ </van-dialog>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script name="home" lang="ts" setup>
|
|
|
+ import to from 'await-to-js'
|
|
|
+ import { onMounted, reactive, ref } from 'vue'
|
|
|
+ import { useRouter, useRoute } from 'vue-router'
|
|
|
+ import { useDictApi } from '/@/api/system/dict'
|
|
|
+ import { formatDate } from '/@/utils/formatTime'
|
|
|
+ import { storeToRefs } from 'pinia'
|
|
|
+ import { useUserInfo } from '/@/stores/userInfo'
|
|
|
+ import { getDictLabel } from '/@/utils/other'
|
|
|
+ import { useTrainingApi } from '/@/api/training'
|
|
|
+ import { usePlatformApi } from '/@/api/platform/home'
|
|
|
+ import { usePlatformAppointApi } from '/@/api/platform/appoint'
|
|
|
+
|
|
|
+ import { showDialog, showNotify } from 'vant'
|
|
|
+ const platformAppointApi = usePlatformAppointApi()
|
|
|
+ const trainingApi = useTrainingApi()
|
|
|
+ const storesUseUserInfo = useUserInfo()
|
|
|
+ const { userInfos, openId } = storeToRefs(storesUseUserInfo)
|
|
|
+ const router = useRouter()
|
|
|
+ const route = useRoute()
|
|
|
+ const formRef = ref()
|
|
|
+ const showPicker = ref(false)
|
|
|
+ const dictApi = useDictApi()
|
|
|
+ const userTypeList = ref(<RowDicDataType[]>[])
|
|
|
+ const platformApi = usePlatformApi()
|
|
|
+ const platformList = ref()
|
|
|
+ const state = reactive({
|
|
|
+ safePromise: false,
|
|
|
+ safeRead: false,
|
|
|
+ isRead: false,
|
|
|
+ form: {
|
|
|
+ id: 0,
|
|
|
+ deptId: null,
|
|
|
+ deptName: '',
|
|
|
+ isTemporary: '10',
|
|
|
+ memberId: 0,
|
|
|
+ memberName: '',
|
|
|
+ memberPhone: '',
|
|
|
+ memberType: '',
|
|
|
+ mentorObj: null,
|
|
|
+ pgId: null,
|
|
|
+ pgName: '',
|
|
|
+ mentorId: null,
|
|
|
+ mentorName: '',
|
|
|
+ mentorDeptName: '',
|
|
|
+ mentorPhone: '',
|
|
|
+ platformId: null,
|
|
|
+ platformName: '',
|
|
|
+ platformTime: null,
|
|
|
+ platformType: '',
|
|
|
+ platformList: [] as any[],
|
|
|
+ isCellChecked: '20',
|
|
|
+ cellType: '',
|
|
|
+ cellSourceType: '',
|
|
|
+ isMolecularChecked: '20',
|
|
|
+ molecularTime: null,
|
|
|
+ platOtherNeed: ''
|
|
|
+ }
|
|
|
+ })
|
|
|
+ const noticeShow = ref(false)
|
|
|
+ const noticeInfo = reactive({
|
|
|
+ noticeTitle: '',
|
|
|
+ noticeContent: ''
|
|
|
+ })
|
|
|
+ const getDicts = async () => {
|
|
|
+ await Promise.all([dictApi.getDictDataByType('sys_user_type'), platformApi.getAllPlatformList({ noPage: true })]).then(([type, plat]) => {
|
|
|
+ userTypeList.value = type.data.values || []
|
|
|
+ const platList = plat?.data?.list || []
|
|
|
+ platformList.value = platList.map((item: any) => {
|
|
|
+ const options = JSON.parse(item.platformResourceType)
|
|
|
+ return {
|
|
|
+ isChecked: false,
|
|
|
+ platformId: item.id,
|
|
|
+ platformName: item.platformName,
|
|
|
+ platformType: item.platformType,
|
|
|
+ platformTime: null,
|
|
|
+ cellType: '',
|
|
|
+ cellSourceType: options?.length ? options[0].dictValue : '',
|
|
|
+ platOtherNeed: '',
|
|
|
+ platformResourceType: options,
|
|
|
+ platformDesc: item.platformDesc
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }
|
|
|
+ const initForm = async () => {
|
|
|
+ state.form = {
|
|
|
+ id: 0,
|
|
|
+ deptId: null,
|
|
|
+ deptName: '',
|
|
|
+ isTemporary: '10',
|
|
|
+ memberId: 0,
|
|
|
+ memberName: '',
|
|
|
+ memberPhone: '',
|
|
|
+ memberType: '',
|
|
|
+ mentorObj: null,
|
|
|
+ pgId: null,
|
|
|
+ pgName: '',
|
|
|
+ mentorId: null,
|
|
|
+ mentorName: '',
|
|
|
+ mentorDeptName: '',
|
|
|
+ mentorPhone: '',
|
|
|
+ platformId: null,
|
|
|
+ platformName: '',
|
|
|
+ platformTime: null,
|
|
|
+ platformType: '',
|
|
|
+ platformList: [...platformList.value],
|
|
|
+ isCellChecked: '20',
|
|
|
+ cellType: '',
|
|
|
+ cellSourceType: '',
|
|
|
+ isMolecularChecked: '20',
|
|
|
+ molecularTime: null,
|
|
|
+ platOtherNeed: ''
|
|
|
+ }
|
|
|
+ state.form.memberId = userInfos.value.id
|
|
|
+ state.form.memberName = userInfos.value.nickName
|
|
|
+ state.form.memberType = userInfos.value.userType
|
|
|
+ state.form.memberPhone = userInfos.value.phone
|
|
|
+ state.form.deptId = userInfos.value.deptId
|
|
|
+ state.form.deptName = userInfos.value.deptName
|
|
|
+ const { projectGroup } = userInfos.value
|
|
|
+ if (projectGroup) {
|
|
|
+ state.form.pgId = projectGroup.id
|
|
|
+ state.form.pgName = projectGroup.pgName
|
|
|
+ state.form.mentorId = projectGroup.pgLeaderId
|
|
|
+ state.form.mentorName = projectGroup.pgLeaderName
|
|
|
+ state.form.mentorDeptName = projectGroup.pgOrgPaths
|
|
|
+ state.form.mentorPhone = projectGroup.pgLeaderContact
|
|
|
+ } else {
|
|
|
+ showNotify({
|
|
|
+ message: '当前用户未加入课题组,无法发起入室申请',
|
|
|
+ type: 'danger'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const onRead = () => {
|
|
|
+ noticeShow.value = true
|
|
|
+ noticeInfo.noticeTitle = '预约须知'
|
|
|
+ const arr = state.form.platformList.map((item: any) => {
|
|
|
+ return item.isChecked ? item.platformDesc : ''
|
|
|
+ })
|
|
|
+ if (arr.length) {
|
|
|
+ noticeInfo.noticeContent = arr.join('\n')
|
|
|
+ state.isRead = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const onSubmit = async (type: string) => {
|
|
|
+ if (!state.safePromise || !state.safeRead) {
|
|
|
+ showNotify({
|
|
|
+ type: 'warning',
|
|
|
+ message: '请阅读并勾选安全承诺!'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const [errValid] = await to(formRef.value.validate())
|
|
|
+ if (errValid) return
|
|
|
+ const params = JSON.parse(JSON.stringify(state.form))
|
|
|
+ params.isTemporary = type
|
|
|
+ const arr = params.platformList.filter((item: any) => item.isChecked)
|
|
|
+ params.platformList = arr.map((item: any) => {
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ isChecked: '10'
|
|
|
+ }
|
|
|
+ })
|
|
|
+ if (!params.platformList.length) {
|
|
|
+ showNotify({
|
|
|
+ type: 'warning',
|
|
|
+ message: '请选择平台'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ for (const item of params.platformList) {
|
|
|
+ if (!item.platformTime) {
|
|
|
+ showNotify({
|
|
|
+ type: 'warning',
|
|
|
+ message: '请选择平台预约时间'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const [err]: ToResponse = await to(platformAppointApi.create(params))
|
|
|
+ if (err) return
|
|
|
+ showNotify({
|
|
|
+ type: 'success',
|
|
|
+ message: '入室申请创建成功'
|
|
|
+ })
|
|
|
+ router.push('/entry')
|
|
|
+ }
|
|
|
+ onMounted(async () => {
|
|
|
+ await getDicts()
|
|
|
+ initForm()
|
|
|
+ })
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+ .app-container {
|
|
|
+ header {
|
|
|
+ padding: 14px;
|
|
|
+ background-color: #f9ffff;
|
|
|
+ border-radius: 4px;
|
|
|
+ margin-top: 10px;
|
|
|
+ }
|
|
|
+ h4 {
|
|
|
+ margin: 10px 0;
|
|
|
+ height: 20px;
|
|
|
+ line-height: 20px;
|
|
|
+ &::before {
|
|
|
+ display: inline-block;
|
|
|
+ content: '';
|
|
|
+ background-color: #3c78e3;
|
|
|
+ width: 4px;
|
|
|
+ height: 20px;
|
|
|
+ margin-right: 4px;
|
|
|
+ vertical-align: top;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ :deep(.flow-cell) {
|
|
|
+ margin-left: 22px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .ck-editor {
|
|
|
+ height: calc(100vh - 100px);
|
|
|
+ overflow-y: auto;
|
|
|
+ padding: 0 10px;
|
|
|
+ }
|
|
|
+</style>
|