|
|
@@ -11,7 +11,7 @@
|
|
|
</el-button>
|
|
|
</div>
|
|
|
<div class="flex1 over-auto">
|
|
|
- <el-form ref="formRef" label-width="auto" label-position="top" :model="form" :rules="rules">
|
|
|
+ <el-form ref="formRef" label-width="auto" label-position="top" :model="form" :rules="rules" :scroll-into-view-options="scrollOptions" scroll-to-error>
|
|
|
<div class="pd-16 border-bottom ov-hd">
|
|
|
<div class="info-title mb-10">会议信息</div>
|
|
|
<el-row :gutter="20">
|
|
|
@@ -21,21 +21,26 @@
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
<el-col :span="6">
|
|
|
- <el-form-item label="培训时间" prop="trainingTime">
|
|
|
- <el-date-picker v-model="form.trainingTime" type="datetimerange" value-format="YYYY-MM-DD HH:mm:ss" date-format="YYYY-MM-DD" time-format="HH:mm:ss" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" />
|
|
|
+ <el-form-item label="会议时间" prop="trainingTime">
|
|
|
+ <el-date-picker v-model="form.trainingTime" type="datetimerange" value-format="YYYY-MM-DD HH:mm:ss" date-format="YYYY-MM-DD" time-format="HH:mm" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
<el-col :span="6">
|
|
|
- <el-form-item label="培训方式" prop="joinType">
|
|
|
+ <el-form-item label="报名时间" prop="signupTime">
|
|
|
+ <el-date-picker v-model="form.signupsTime" type="datetimerange" value-format="YYYY-MM-DD HH:mm:ss" date-format="YYYY-MM-DD" time-format="HH:mm" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-form-item label="会议方式" prop="joinType">
|
|
|
<!-- 单选框 -->
|
|
|
<el-radio-group v-model="form.joinType">
|
|
|
- <el-radio v-for="item in dm_training_join_type" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
|
|
|
+ <el-radio v-for="item in lm_training_join_type" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
|
|
|
</el-radio-group>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
<el-col v-if="form.joinType === '0'" :span="6">
|
|
|
- <el-form-item label="培训地点" prop="trainingLocation">
|
|
|
- <el-input v-model="form.trainingLocation" placeholder="请输入培训地点" clearable />
|
|
|
+ <el-form-item label="会议地点" prop="trainingLocation">
|
|
|
+ <el-input v-model="form.trainingLocation" placeholder="请输入会议地点" clearable />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
<el-col :span="6">
|
|
|
@@ -48,11 +53,121 @@
|
|
|
<el-input v-model="form.tel" maxlength="20" placeholder="请输入联系电话" clearable />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="可报名人员类型" prop="conditions.typeCheck">
|
|
|
+ <el-checkbox-group v-model="checkedVipLevels" @change="handleCheckedChange">
|
|
|
+ <el-checkbox v-for="city in form.conditions.typeCheck" :key="city" :label="city" :value="city">
|
|
|
+ {{ selectDictLabels(lm_check_join_type, city.vipLevel, ',') }}
|
|
|
+ </el-checkbox>
|
|
|
+ </el-checkbox-group>
|
|
|
+ <div @click="handleCheckAllChange(true)" v-if="!checkAll" class="pl-10 c-s-p">
|
|
|
+ <u>全选</u>
|
|
|
+ </div>
|
|
|
+ <div @click="handleCheckAllChange(false)" v-else class="pl-10 c-s-p"><u>取消全选</u></div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-form-item label="报名人数" prop="conditions.totalCheck">
|
|
|
+ <div class="d-flex a-c">
|
|
|
+ <el-radio-group v-model="form.conditions.totalCheck" style="flex-wrap: nowrap">
|
|
|
+ <el-radio label="0">不限制</el-radio>
|
|
|
+ <el-radio label="1">限制</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12" v-if="form.conditions.totalCheck == '1'">
|
|
|
+ <el-form-item prop="restrictiveConditions">
|
|
|
+ <template #label>
|
|
|
+ <span>限制条件</span>
|
|
|
+ <span class="c-999 f-s-12 f-w-4">(不限制的条件可不填)</span>
|
|
|
+ </template>
|
|
|
+ <div class="d-flex flex-cln pl-10">
|
|
|
+ <div class="d-flex">
|
|
|
+ <div class="c-#606266 f-w-6" style="">报名总人数限制:</div>
|
|
|
+ <el-input class="flex1 pl-5" v-model="form.conditions.total" maxlength="20" placeholder="请输入报名人数" clearable :disabled="form.conditions.totalCheck !== '1'" style="max-width: 200px;" />
|
|
|
+ </div>
|
|
|
+ <div class="c-#606266 f-w-6" style="">条件限制:</div>
|
|
|
+ <div class="d-flex">
|
|
|
+ <div class="d-flex flex-cln">
|
|
|
+ <el-checkbox v-model="form.conditions.levelTotalCheck" label="按单位类型限制" size="large" true-value="1" false-value="0" />
|
|
|
+ <div v-if="form.conditions.levelTotalCheck == '1' && form.conditions.cpyTotalCheck == '0'" class="pl-10 pr-10 pt-5 pb-5 border">
|
|
|
+ <template v-for="(item, index) in form.conditions.levelCheck" :key="index">
|
|
|
+ <div class="d-flex a-c" v-if="checkedVipLevels.some(items => items.vipLevel === item.vipLevel)">
|
|
|
+ <el-checkbox v-model="item.check" true-value="1" false-value="0" :label="'所有' + selectDictLabels(lm_check_join_type, item.vipLevel, ',') + '参会人数≤'" size="large" />
|
|
|
+ <el-input class="pl-10" v-model="item.total" maxlength="20" placeholder="请输入报名人数" :disabled="!+item.check" />
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <el-empty :image-size="20" description="请先选择报名人员类型" v-if="checkedVipLevels.length == 0" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="d-flex flex-cln ml-20">
|
|
|
+ <el-checkbox v-model="form.conditions.cpyTotalCheck" label="按每家单位人数限制" size="large" true-value="1" false-value="0" />
|
|
|
+ <div v-if="form.conditions.cpyTotalCheck == '1' && form.conditions.levelTotalCheck == '0'" class="pl-10 pr-10 pt-5 pb-5 border">
|
|
|
+ <template v-for="(item, index) in form.conditions.cpyCheck" :key="index">
|
|
|
+ <div class="d-flex a-c" v-if="checkedVipLevels.some(items => items.vipLevel === item.vipLevel)">
|
|
|
+ <el-checkbox v-model="item.check" :label="selectDictLabels(lm_check_join_type, item.vipLevel, ',') + '限制每家单位人数≤'" size="large" true-value="1" false-value="0" />
|
|
|
+ <el-input class="pl-10" v-model="item.total" maxlength="20" placeholder="请输入报名人数" :disabled="!+item.check" />
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <el-empty :image-size="20" description="请先选择报名人员类型" v-if="checkedVipLevels.length == 0" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="d-flex border" v-if="form.conditions.levelTotalCheck == '1' && form.conditions.cpyTotalCheck == '1'">
|
|
|
+ <div class="pl-10 pr-10 pt-5 pb-5 ">
|
|
|
+ <template v-for="(item, index) in form.conditions.levelCheck" :key="index">
|
|
|
+ <div class="d-flex a-c" v-if="checkedVipLevels.some(items => items.vipLevel === item.vipLevel)">
|
|
|
+ <el-checkbox v-model="item.check" :label="'所有' + selectDictLabels(lm_check_join_type, item.vipLevel, ',') + '参会人数≤'" size="large" true-value="1" false-value="0" />
|
|
|
+ <el-input class="pl-10" v-model="item.total" maxlength="20" placeholder="请输入报名人数" :disabled="!+item.check" />
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ <div class="pl-10 pr-10 pt-5 pb-5">
|
|
|
+ <template v-for="(item, index) in form.conditions.cpyCheck" :key="index">
|
|
|
+ <div class="d-flex a-c" v-if="checkedVipLevels.some(items => items.vipLevel === item.vipLevel)">
|
|
|
+ <el-checkbox v-model="item.check" :label="selectDictLabels(lm_check_join_type, item.vipLevel, ',') + '限制每家单位人数≤'" size="large" true-value="1" false-value="0" />
|
|
|
+ <el-input class="pl-10" v-model="item.total" maxlength="20" placeholder="请输入报名人数" :disabled="!+item.check" />
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ <div class="flex1 ml--10" v-if="checkedVipLevels.length == 0"><el-empty :image-size="20" description="请先选择报名人员类型" /></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-form-item label="是否电子手签" prop="eleSignature">
|
|
|
+ <div class="d-flex a-c">
|
|
|
+ <el-radio-group v-model="form.eleSignature" style="flex-wrap: nowrap">
|
|
|
+ <el-radio label="1">是</el-radio>
|
|
|
+ <el-radio label="0">否</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <div class="d-flex" style="align-items: flex-end;">
|
|
|
+ <el-form-item label="发放积分" prop="pointsFlag" class="">
|
|
|
+ <el-radio-group v-model="form.pointsFlag" style="flex-wrap: nowrap">
|
|
|
+ <el-radio label="1">是</el-radio>
|
|
|
+ <el-radio label="0">否</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="" prop="points" v-if="form.pointsFlag == '1'" class="flex1 pl-10">
|
|
|
+ <div class="d-flex f-s-14">
|
|
|
+ <div>每成功参会(签到成功)1人发放</div>
|
|
|
+ <el-input v-model="form.points" style="width: 60px" />
|
|
|
+ <div>个单位积分。</div>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
</el-row>
|
|
|
<el-row :gutter="20">
|
|
|
<el-col :span="12">
|
|
|
- <el-form-item label="培训详情" prop="description">
|
|
|
- <el-input v-model="form.description" :rows="4" type="textarea" placeholder="请输入培训详情" />
|
|
|
+ <el-form-item label="会议详情" prop="description">
|
|
|
+ <el-input v-model="form.description" :rows="4" type="textarea" placeholder="请输入会议详情" />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
<el-col :span="12">
|
|
|
@@ -60,108 +175,363 @@
|
|
|
<el-input v-model="form.notice" :rows="4" type="textarea" placeholder="请输入与会须知" />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="会议微信群聊二维码" prop="wechatQrCode">
|
|
|
+ <ImageUpload v-model="form.wechatQrCode" :fileSize="20"></ImageUpload>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
<el-col :span="12">
|
|
|
<el-form-item label="封面图" prop="coverImg">
|
|
|
- <ImageUpload v-model="form.coverImg" :limit="1"></ImageUpload>
|
|
|
+ <ImageUpload v-model="form.coverImg" :limit="1" :fileSize="20"></ImageUpload>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
<el-col :span="12">
|
|
|
<el-form-item label="会议图" prop="trainingImg">
|
|
|
- <ImageUpload v-model="form.trainingImg" :fileSize="40"></ImageUpload>
|
|
|
+ <ImageUpload v-model="form.trainingImg" :fileSize="20"></ImageUpload>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="会议备注" prop="remark">
|
|
|
+ <el-input v-model="form.remark" :rows="4" type="textarea" placeholder="请输入会议备注" />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
<el-col :span="12">
|
|
|
<el-form-item label="相关文件" prop="attachments">
|
|
|
- <FileUpload v-model="form.attachments" format="array" :limit="20" :fileSize="100"></FileUpload>
|
|
|
+ <template #label>
|
|
|
+ <span>相关文件</span>
|
|
|
+ <span class="c-999 f-s-12 f-w-4">(此模块报名审核通过后才可查看)</span>
|
|
|
+ </template>
|
|
|
+ <div class="d-flex flex-cln mt-10 f-s-12 c-#606266">
|
|
|
+ <FileUpload v-model="form.attachments" format="array" :limit="20" :fileSize="100"></FileUpload>
|
|
|
+ </div>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
</div>
|
|
|
- <div class="pd-16 border-bottom">
|
|
|
- <div class="info-title mb-10">证书信息</div>
|
|
|
- <div class="d-flex j-start a-c">
|
|
|
- <el-form-item label="是否颁发证书" prop="certFlag">
|
|
|
- <el-radio-group v-model="form.certFlag">
|
|
|
- <el-radio v-for="item in yes_no" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
|
|
|
- </el-radio-group>
|
|
|
- </el-form-item>
|
|
|
- <div v-if="+form.certFlag" class="ml-20">
|
|
|
- <el-button @click="addCertInfo">新增证书</el-button>
|
|
|
+ <div class="pd-16 border-bottom d-flex">
|
|
|
+ <div class="w-50% ov-at h-1000">
|
|
|
+ <div class="info-title mb-10">证书信息</div>
|
|
|
+ <div class="d-flex j-start a-c">
|
|
|
+ <el-form-item label="是否颁发证书" prop="certFlag">
|
|
|
+ <el-radio-group v-model="form.certFlag">
|
|
|
+ <el-radio v-for="item in yes_no" :key="item.value" :label="item.value">
|
|
|
+ {{ item.label }}
|
|
|
+ </el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ <div v-if="+form.certFlag" class="ml-20">
|
|
|
+ <el-button @click="addCertInfo" type="primary">新增证书</el-button>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- </div>
|
|
|
- <template v-if="form.certFlag">
|
|
|
- <template v-for="(item, index) in form.certificateInfo" :key="index">
|
|
|
- <el-row :gutter="20" class="bg-#f4f4f4 pd-16 mb-10">
|
|
|
- <el-col :span="6">
|
|
|
- <el-form-item label="证书名称" :prop="`certificateInfo.${index}.certType`" :rules="[{ required: true, message: '请选择证书名称', trigger: 'change' }]">
|
|
|
- <el-select v-model="item.certType" placeholder="证书名称" clearable>
|
|
|
- <el-option v-for="item in dm_training_cert" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="6">
|
|
|
- <el-form-item :prop="`certificateInfo.${index}.certImg`" :rules="[{ required: true, message: '请上传证书图片', trigger: 'change' }]">
|
|
|
- <template #label>
|
|
|
- <span>证书模板图片</span>
|
|
|
- <el-button @click="goEditor()" type="primary" text>去编辑模板图片</el-button>
|
|
|
- </template>
|
|
|
- <ImageUpload v-model="item.certImg" :fileSize="40" :limit="1"></ImageUpload>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="6">
|
|
|
- <el-form-item>
|
|
|
- <el-button type="danger" @click="deleteItem(index)">删除</el-button>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
+ <template v-if="form.certFlag">
|
|
|
+ <template v-for="(item, index) in form.certificateInfo" :key="index">
|
|
|
+ <el-row :gutter="20" class="bg-#f4f4f4 pd-16 mb-10">
|
|
|
+ <el-col :span="10">
|
|
|
+ <el-form-item label="证书名称" :prop="`certificateInfo.${index}.certType`" :rules="[{ required: true, message: '请选择证书名称', trigger: 'change' }]">
|
|
|
+ <el-select v-model="item.certType" placeholder="证书名称" clearable>
|
|
|
+ <el-option v-for="item in lm_training_cert" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="10">
|
|
|
+ <el-form-item :prop="`certificateInfo.${index}.certImg`" :rules="[{ required: true, message: '请上传证书图片', trigger: 'change' }]">
|
|
|
+ <template #label>
|
|
|
+ <span>证书模板图片</span>
|
|
|
+ <el-button @click="goEditor()" type="primary" text>去编辑模板图片</el-button>
|
|
|
+ </template>
|
|
|
+ <ImageUpload v-model="item.certImg" :fileSize="40" :limit="1"></ImageUpload>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="4">
|
|
|
+ <el-form-item>
|
|
|
+ <el-button type="danger" @click="deleteItem(index)">删除</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </template>
|
|
|
</template>
|
|
|
- </template>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="w-50% d-flex flex-cln j-c a-c pl-20">
|
|
|
+ <el-button type="primary" class="w-100%" plain style="height: 70px; margin-bottom: 20px;" @click="showSignIn = true">点击去编辑报名信息></el-button>
|
|
|
+ <div class="w-400 h-700 border over-auto">
|
|
|
+ <div class="pd-10 border bg-#fafafa">
|
|
|
+ <div class="pt-10 f-s-20 f-w-6 d-flex j-c a-c flex-cln ">报名信息</div>
|
|
|
+ <div class="f-s-12 f-w-4 d-flex j-start c-red">此页面为意向人报名时所见页面:</div>
|
|
|
+ </div>
|
|
|
+ <template v-for="(item, index) in fixedField" :key="index">
|
|
|
+ <div class="pd-15 border1 c-#D7D7D7 d-flex j-sb">
|
|
|
+ <span class="c-#606266 f-s-16 f-w-6">{{ item.label }}</span>
|
|
|
+ <span class="f-s-14">请输入</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template v-for="(field, index) in fields" :key="index">
|
|
|
+ <div class="meeting-custom-wrapper" @click.stop="showSignIn = true">
|
|
|
+ <meetingCustomPreview :field="field" style="pointer-events: none" v-if="field" />
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <div class="pd-15 border1 c-#D7D7D7 d-flex j-sb">
|
|
|
+ <span class="c-#606266 f-s-16 f-w-6">备注</span>
|
|
|
+ <span class="f-s-14">请输入</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</el-form>
|
|
|
+ <MeetingEditors v-if="showSignIn" v-model:show="showSignIn" v-model:info="fields" />
|
|
|
</div>
|
|
|
<div class="d-flex a-c j-c pd-16">
|
|
|
- <el-button @click="router.go(-1)">取消</el-button>
|
|
|
+ <el-button @click="Cancel">取消</el-button>
|
|
|
<el-button @click="save" type="primary">提交</el-button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
-
|
|
|
<script setup name="meeting-add" lang="ts">
|
|
|
-import { ref, reactive, onMounted } from 'vue';
|
|
|
+import { trainingAdd, trainingDetail, trainingUpdate } from '@/api/training';
|
|
|
import { debounce } from 'lodash';
|
|
|
+import { onMounted, reactive, ref } from 'vue';
|
|
|
import { useRouter } from 'vue-router';
|
|
|
-import { trainingAdd, trainingDetail, trainingUpdate } from '@/api/training';
|
|
|
+import { FieldDefinition } from '../models/type';
|
|
|
+// 需要添加以下导入
|
|
|
+import meetingCustomPreview from '../models/meeting-custom-preview.vue';
|
|
|
+import MeetingEditors from '../models/meeting-editors.vue';
|
|
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
|
-const { dm_training_join_type, yes_no, dm_training_cert } = toRefs<any>(proxy?.useDict('dm_training_join_type', 'yes_no', 'dm_training_cert'));
|
|
|
+const { lm_training_join_type, yes_no, lm_training_cert, lm_check_join_type } = toRefs<any>(proxy?.useDict('lm_training_join_type', 'yes_no', 'lm_training_cert', 'lm_check_join_type'));
|
|
|
+const fields = ref<FieldDefinition[]>([])
|
|
|
+const showSignIn = ref(false);
|
|
|
+const fixedField = ref<FieldDefinition[]>([{
|
|
|
+ name: `ent-${generateSecureRandomString()}`,
|
|
|
+ label: '企业名称', type: '1',
|
|
|
+ required: '1', readonly: '0',
|
|
|
+}, {
|
|
|
+ name: `name-${generateSecureRandomString()}`,
|
|
|
+ label: '姓名', type: '1', readonly: '0',
|
|
|
+ required: '1'
|
|
|
+}, {
|
|
|
+ name: `pos-${generateSecureRandomString()}`,
|
|
|
+ label: '职务', type: '1', readonly: '0',
|
|
|
+ required: '1'
|
|
|
+}, {
|
|
|
+ name: `Con-${generateSecureRandomString()}`,
|
|
|
+ label: '联系方式', type: '1', readonly: '0',
|
|
|
+ required: '1'
|
|
|
+}])
|
|
|
+const scrollOptions = {
|
|
|
+ block: 'center',
|
|
|
+ behavior: 'smooth'
|
|
|
+};
|
|
|
+function generateSecureRandomString(length = 8) {
|
|
|
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
|
|
+ const randomValues = new Uint32Array(length);
|
|
|
+ window.crypto.getRandomValues(randomValues);
|
|
|
+ let result = '';
|
|
|
+ randomValues.forEach((value) => {
|
|
|
+ result += chars[value % chars.length];
|
|
|
+ });
|
|
|
+ return result;
|
|
|
+}
|
|
|
+const Cancel = () => {
|
|
|
+ router.go(-1)
|
|
|
+}
|
|
|
const router = useRouter();
|
|
|
const route = useRoute();
|
|
|
+const levelTypeCheck = computed(() =>
|
|
|
+ String(Number(checkedVipLevels.value.length > 0))
|
|
|
+);
|
|
|
const form = ref<any>({
|
|
|
- id: undefined
|
|
|
+ id: undefined,
|
|
|
+ conditions: {
|
|
|
+ levelTotalCheck: '0',
|
|
|
+ cpyTotalCheck: '0',
|
|
|
+ levelTypeCheck: levelTypeCheck,
|
|
|
+ typeCheck: [
|
|
|
+ {
|
|
|
+ vipLevel: "0",
|
|
|
+ check: "0"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ vipLevel: "1",
|
|
|
+ check: "0"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ vipLevel: "3",
|
|
|
+ check: "0"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ vipLevel: "5",
|
|
|
+ check: "0"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ vipLevel: "6",
|
|
|
+ check: "0"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ vipLevel: "7",
|
|
|
+ check: "0"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ vipLevel: "9",
|
|
|
+ check: "0"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ vipLevel: "10",
|
|
|
+ check: "0"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ levelCheck: [{
|
|
|
+ vipLevel: '0',
|
|
|
+ check: "0",
|
|
|
+ total: ''
|
|
|
+ }, {
|
|
|
+ vipLevel: '1',
|
|
|
+ check: "0",
|
|
|
+ total: ''
|
|
|
+ }, {
|
|
|
+ vipLevel: '3',
|
|
|
+ check: "0",
|
|
|
+ total: ''
|
|
|
+ }, {
|
|
|
+ vipLevel: '5',
|
|
|
+ check: "0",
|
|
|
+ total: ''
|
|
|
+ },
|
|
|
+ {
|
|
|
+ vipLevel: "6",
|
|
|
+ check: "0",
|
|
|
+ total: ''
|
|
|
+ },
|
|
|
+ {
|
|
|
+ vipLevel: "7",
|
|
|
+ check: "0",
|
|
|
+ total: ''
|
|
|
+ },
|
|
|
+ {
|
|
|
+ vipLevel: "9",
|
|
|
+ check: "0",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ vipLevel: "10",
|
|
|
+ total: ''
|
|
|
+ }],
|
|
|
+ cpyCheck: [{
|
|
|
+ vipLevel: '0',
|
|
|
+ check: "0",
|
|
|
+ total: ''
|
|
|
+ }, {
|
|
|
+ vipLevel: '1',
|
|
|
+ check: "0",
|
|
|
+ total: ''
|
|
|
+ }, {
|
|
|
+ vipLevel: '3',
|
|
|
+ check: "0",
|
|
|
+ total: ''
|
|
|
+ }, {
|
|
|
+ vipLevel: '5',
|
|
|
+ check: "0",
|
|
|
+ total: ''
|
|
|
+ }, {
|
|
|
+ vipLevel: '6',
|
|
|
+ check: "0",
|
|
|
+ total: ''
|
|
|
+ }, {
|
|
|
+ vipLevel: '7',
|
|
|
+ check: "0",
|
|
|
+ total: ''
|
|
|
+ }, {
|
|
|
+ vipLevel: '9',
|
|
|
+ check: "0",
|
|
|
+ total: ''
|
|
|
+ }, {
|
|
|
+ vipLevel: '10',
|
|
|
+ check: "0",
|
|
|
+ total: ''
|
|
|
+ }]
|
|
|
+ }
|
|
|
});
|
|
|
+
|
|
|
+const checkAll = ref(false)
|
|
|
+const checkedVipLevels = ref([])
|
|
|
+
|
|
|
+// 选项变化时的处理
|
|
|
+const handleCheckedChange = (selectedValues) => {
|
|
|
+
|
|
|
+ const selectedLevelMap = new Map(selectedValues.map(item => [item.vipLevel, true]));
|
|
|
+
|
|
|
+ form.value.conditions.typeCheck.forEach(item => {
|
|
|
+ item.check = selectedLevelMap.has(item.vipLevel) ? '1' : '0';
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+// 全选/取消全选
|
|
|
+const handleCheckAllChange = (val: boolean) => {
|
|
|
+ checkedVipLevels.value = val
|
|
|
+ ? form.value.conditions.typeCheck.map(item => item)
|
|
|
+ : []
|
|
|
+ handleCheckedChange(checkedVipLevels.value)
|
|
|
+ checkAll.value = val
|
|
|
+}
|
|
|
const rules = reactive({
|
|
|
// 自动生成全部
|
|
|
trainingName: [{ required: true, message: '请输入会议名称', trigger: 'blur' }],
|
|
|
- trainingTime: [{ required: true, message: '请选择培训时间', trigger: 'blur' }],
|
|
|
- joinType: [{ required: true, message: '请选择培训方式', trigger: 'change' }],
|
|
|
- trainingLocation: [{ required: true, message: '请输入培训地点', trigger: 'blur' }],
|
|
|
+ trainingTime: [{ required: true, message: '请选择会议时间', trigger: 'blur' }],
|
|
|
+ joinType: [{ required: true, message: '请选择会议方式', trigger: 'change' }],
|
|
|
+ trainingLocation: [{ required: true, message: '请输入会议地点', trigger: 'blur' }],
|
|
|
+ 'conditions.totalCheck': [{ required: true, message: '请选择是否限制报名人数', trigger: 'change' }],
|
|
|
+ 'conditions.typeCheck': [
|
|
|
+ {
|
|
|
+ validator: (rule, value, callback) => {
|
|
|
+ setTimeout(() => {
|
|
|
+ const isChecked = value.some(item => item.check == "1");
|
|
|
+ if (!isChecked) {
|
|
|
+ callback(new Error('请至少选择一种可报名单位类型'));
|
|
|
+ } else {
|
|
|
+ callback();
|
|
|
+ }
|
|
|
+ }, 300);
|
|
|
+ },
|
|
|
+ trigger: 'change' // 触发校验的时机
|
|
|
+ }
|
|
|
+ ],
|
|
|
certFlag: [{ required: true, message: '请选择是否颁发证书', trigger: 'change' }],
|
|
|
certificateInfo: [{ required: true, message: '请选择证书名称', trigger: 'change' }],
|
|
|
description: [{ required: true, message: '请输入培训详情', trigger: 'blur' }],
|
|
|
- coverImg: [{ required: true, message: '请上传封面图', trigger: 'change' }],
|
|
|
- trainingImg: [{ required: true, message: '请上传会议图', trigger: 'change' }],
|
|
|
+ eleSignature: [{ required: true, message: '请选择是否电子手签', trigger: 'blur' }],
|
|
|
+ pointsFlag: [{ required: true, message: '请选择是否发放积分', trigger: 'blur' }],
|
|
|
+ // coverImg: [{ required: true, message: '请上传封面图', trigger: 'change' }],
|
|
|
+ // trainingImg: [{ required: true, message: '请上传会议图', trigger: 'change' }],
|
|
|
contactName: [{ required: true, message: '请输入会议联系人', trigger: 'blur' }],
|
|
|
tel: [{ required: true, message: '请输入联系电话', trigger: 'blur' }],
|
|
|
});
|
|
|
const formRef = ref();
|
|
|
-
|
|
|
const save = debounce(async () => {
|
|
|
await formRef.value.validate();
|
|
|
+ form.value.conditions.typeCheck.forEach(typeItem => {
|
|
|
+ if (typeItem.check === "0") {
|
|
|
+ // Update cpyCheck
|
|
|
+ const cpyItem = form.value.conditions.cpyCheck.find(item => item.vipLevel === typeItem.vipLevel);
|
|
|
+ if (cpyItem) {
|
|
|
+ cpyItem.check = "0";
|
|
|
+ }
|
|
|
+
|
|
|
+ // Update levelCheck
|
|
|
+ const levelItem = form.value.conditions.levelCheck.find(item => item.vipLevel === typeItem.vipLevel);
|
|
|
+ if (levelItem) {
|
|
|
+ levelItem.check = "0";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
const params = {
|
|
|
...form.value,
|
|
|
trainingStart: form.value.trainingTime ? form.value.trainingTime[0] : undefined,
|
|
|
trainingEnd: form.value.trainingTime ? form.value.trainingTime[1] : undefined,
|
|
|
- certificateInfo: +form.value.certFlag ? form.value.certificateInfo : undefined
|
|
|
+ signupStart: form.value.signupsTime ? form.value.signupsTime[0] : undefined,
|
|
|
+ signupEnd: form.value.signupsTime ? form.value.signupsTime[1] : undefined,
|
|
|
+ certificateInfo: +form.value.certFlag ? form.value.certificateInfo : undefined,
|
|
|
+ questions: fields.value.map((item, index) => ({
|
|
|
+ ...item,
|
|
|
+ sort: index + 1 // 从 1 开始
|
|
|
+ }))
|
|
|
};
|
|
|
const res = form.value.id ? await trainingUpdate(params) : await trainingAdd(params);
|
|
|
if (res && res.code === 200) {
|
|
|
@@ -171,6 +541,7 @@ const save = debounce(async () => {
|
|
|
const goEditor = () => {
|
|
|
window.open('https://lm.yujin.shuziyunyao.com/poster#/editor', '_blank');
|
|
|
}
|
|
|
+
|
|
|
const addCertInfo = () => {
|
|
|
if (!form.value.certificateInfo) {
|
|
|
form.value.certificateInfo = [];
|
|
|
@@ -190,11 +561,23 @@ const getMeetingDetail = async () => {
|
|
|
if (!res || res.code !== 200) return;
|
|
|
form.value = {
|
|
|
...res.data,
|
|
|
- trainingTime: res.data.trainingStart && res.data.trainingEnd ? [res.data.trainingStart, res.data.trainingEnd] : undefined
|
|
|
+ trainingTime: res.data.trainingStart && res.data.trainingEnd ? [res.data.trainingStart, res.data.trainingEnd] : undefined,
|
|
|
+ signupsTime: res.data.signupStart && res.data.signupEnd ? [res.data.signupStart, res.data.signupEnd] : undefined
|
|
|
};
|
|
|
+ fields.value = res.data.questions
|
|
|
+ form.value.conditions.typeCheck.forEach((i) => {
|
|
|
+ if (i.check == '1') {
|
|
|
+ checkedVipLevels.value.push(i)
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
};
|
|
|
onMounted(() => {
|
|
|
getMeetingDetail();
|
|
|
});
|
|
|
</script>
|
|
|
+<style scoped>
|
|
|
+.border {
|
|
|
+ border: 1px solid #dcdfe6;
|
|
|
+}
|
|
|
+</style>
|