lisy 5 месяцев назад
Родитель
Сommit
7710d60389

+ 23 - 0
src/api/training/index.ts

@@ -75,3 +75,26 @@ export const trainingMembers = (params: any): AxiosPromise => {
         params
     });
 };
+// 报名审批统计
+export const signupCount = (id): AxiosPromise => {
+    return request({
+        url: `/dgtmedicine/trainingSignup/signupCount?trainingId=${id}`,
+        method: 'get'
+    });
+};
+// 报名审核
+export const signupApproval = (data: any): AxiosPromise => {
+    return request({
+        url: '/dgtmedicine/trainingSignup/signupApproval',
+        method: 'post',
+        data
+    });
+};
+// 开关会议临时状态
+export const offOrNoTemp = (params: any): AxiosPromise => {
+    return request({
+        url: `/dgtmedicine/training/offOrNoTemp`,
+        method: 'get',
+        params
+    });
+};

+ 23 - 8
src/views/training/meeting-add/index.vue

@@ -75,7 +75,7 @@
 
                                 </el-form-item>
                             </el-col>
-                            <el-col :span="12">
+                            <el-col :span="12" v-if="form.conditions.totalCheck == '1'">
                                 <el-form-item label="限制条件" prop="restrictiveConditions">
                                     <div class="d-flex">
                                         <div class="d-flex flex-cln">
@@ -88,8 +88,9 @@
                                                     <div class="d-flex a-c">
                                                         <el-checkbox v-model="item.check" true-value="1" false-value="0"
                                                             :label="'所有' + selectDictLabels(vip_level, item.vipLevel, ',') + '参会人数≤'"
-                                                            size="large" /><el-input class="pl-10" v-model="item.total"
-                                                            maxlength="20" placeholder="请输入报名人数" clearable
+                                                            size="large" />
+                                                            <el-input class="pl-10" v-model="item.total"
+                                                            maxlength="20" placeholder="请输入报名人数"
                                                             :disabled="!+item.check" />
                                                     </div>
                                                 </template>
@@ -108,7 +109,7 @@
                                                             :label="selectDictLabels(vip_level, item.vipLevel, ',') + '限制每家单位人数≤'"
                                                             size="large" true-value="1" false-value="0" /><el-input
                                                             class="pl-10" v-model="item.total" maxlength="20"
-                                                            placeholder="请输入报名人数" clearable :disabled="!+item.check" />
+                                                            placeholder="请输入报名人数"  :disabled="!+item.check" />
                                                     </div>
                                                 </template>
 
@@ -124,7 +125,7 @@
                                                         :label="'所有' + selectDictLabels(vip_level, item.vipLevel, ',') + '参会人数≤'"
                                                         size="large" true-value="1" false-value="0" /><el-input
                                                         class="pl-10" v-model="item.total" maxlength="20"
-                                                        placeholder="请输入报名人数" clearable :disabled="!+item.check" />
+                                                        placeholder="请输入报名人数"  :disabled="!+item.check" />
                                                 </div>
                                             </template>
                                         </div>
@@ -136,7 +137,7 @@
                                                         :label="selectDictLabels(vip_level, item.vipLevel, ',') + '限制每家单位人数≤'"
                                                         size="large" true-value="1" false-value="0" /><el-input
                                                         class="pl-10" v-model="item.total" maxlength="20"
-                                                        placeholder="请输入报名人数" clearable :disabled="!+item.check" />
+                                                        placeholder="请输入报名人数"  :disabled="!+item.check" />
                                                 </div>
                                             </template>
                                         </div>
@@ -166,6 +167,11 @@
                                     <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="40"></ImageUpload>
+                                </el-form-item>
+                            </el-col>
                             <el-col :span="12">
                                 <el-form-item label="封面图" prop="coverImg">
                                     <ImageUpload v-model="form.coverImg" :limit="1"></ImageUpload>
@@ -176,10 +182,19 @@
                                     <ImageUpload v-model="form.trainingImg" :fileSize="40"></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>
+                                    <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>此模块报名审核通过后才可查看</div>
+                                    </div>
                                 </el-form-item>
                             </el-col>
                         </el-row>

+ 6 - 4
src/views/training/meeting-detail/index.vue

@@ -18,8 +18,9 @@
                     </template>
                 </div>
             </div>
-            <MeetingDetailInfo v-if="activeName === '1'" :form="form" />
-            <MeetingDetailAttend v-if="activeName === '2'" :form="form" />
+            <MeetingDetailAttend v-if="activeName === '1'" :form="form" />
+            <MeetingDetailInfo v-if="activeName === '2'" :form="form" />
+
         </div>
     </div>
 </template>
@@ -36,8 +37,9 @@ const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 const { dm_training_join_type, yes_no, dm_training_cert, dm_training_status, dm_training_signup_status_list } = toRefs<any>(proxy?.useDict('dm_training_join_type', 'yes_no', 'dm_training_cert', 'dm_training_status', 'dm_training_signup_status_list'));
 // 获取详情
 const tabs = ref([
-    { label: '会议信息', value: '1' },
-    { label: '参会人员信息', value: '2' },
+    { label: '参会人员信息', value: '1' },
+    { label: '会议信息', value: '2' },
+
 ])
 const activeName = ref('1');
 const form = ref<any>(null);

+ 92 - 22
src/views/training/meeting/index.vue

@@ -7,16 +7,21 @@
                     <div class="flex1 ov-hd d-flex j-ed">
                         <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="auto">
                             <el-form-item label="会议名称" prop="trainingName">
-                                <el-input v-model="queryParams.trainingName" placeholder="搜会议名称" clearable style="width: 160px" @keyup.enter="handleQuery" />
+                                <el-input v-model="queryParams.trainingName" placeholder="搜会议名称" clearable
+                                    style="width: 160px" @keyup.enter="handleQuery" />
                             </el-form-item>
                             <el-form-item label="培训方式" prop="joinType">
-                                <el-select v-model="queryParams.joinType" placeholder="请选择培训方式" clearable style="width: 160px" @change="handleQuery">
-                                    <el-option v-for="item in dm_training_join_type" :key="item.value" :label="item.label" :value="item.value" />
+                                <el-select v-model="queryParams.joinType" placeholder="请选择培训方式" clearable
+                                    style="width: 160px" @change="handleQuery">
+                                    <el-option v-for="item in dm_training_join_type" :key="item.value"
+                                        :label="item.label" :value="item.value" />
                                 </el-select>
                             </el-form-item>
                             <el-form-item label="是否颁发证书" prop="certFlag">
-                                <el-select v-model="queryParams.certFlag" placeholder="请选择是否颁发证书" clearable style="width: 160px" @change="handleQuery">
-                                    <el-option v-for="item in yes_no" :key="item.value" :label="item.label" :value="item.value" />
+                                <el-select v-model="queryParams.certFlag" placeholder="请选择是否颁发证书" clearable
+                                    style="width: 160px" @change="handleQuery">
+                                    <el-option v-for="item in yes_no" :key="item.value" :label="item.label"
+                                        :value="item.value" />
                                 </el-select>
                             </el-form-item>
                             <el-form-item>
@@ -30,7 +35,8 @@
             <div class="d-flex flex1 ov-hd flex-cln pd-16">
                 <div class="d-flex j-sb mb-16">
                     <div>
-                        <searchTabs v-model="queryParams.status" @change="handleQuery" :list="tabs" key-label="name" key-count="num" key-value="type"></searchTabs>
+                        <searchTabs v-model="queryParams.status" @change="handleQuery" :list="tabs" key-label="name"
+                            key-count="num" key-value="type"></searchTabs>
                     </div>
                     <el-button type="primary" @click="router.push({ path: 'lmmeetingadd' })">新增会议</el-button>
                 </div>
@@ -38,8 +44,11 @@
                     <vxe-table :loading="loading" border :data="dataList" min-height="0" max-height="100%">
                         <vxe-column title="序号" align="center" type="seq" width="60" />
                         <vxe-column field="trainingName" title="会议名称" :formatter="colNoData" />
-                        <vxe-column field="trainingTime" min-width="200" title="培训时间">
-                            <template #default="{ row }">{{ row.trainingStart  }}~{{ row.trainingEnd }}</template>
+                        <vxe-column field="trainingTime" min-width="150" title="培训时间">
+                            <template #default="{ row }">{{ row.trainingStart }}~{{ row.trainingEnd }}</template>
+                        </vxe-column>
+                        <vxe-column field="signupsTime" min-width="150" title="报名时间">
+                            <template #default="{ row }">{{ row.signupStart }}~{{ row.signupEnd }}</template>
                         </vxe-column>
                         <vxe-column field="joinType" title="培训方式" width="80">
                             <template #default="{ row }">
@@ -55,41 +64,70 @@
                         <vxe-column field="joinCount" title="报名人数" width="80" />
                         <vxe-column field="signCount" title="签到人数" width="80" />
                         <vxe-column field="certCount" title="领取证书人数" width="80" />
-                        <vxe-column title="创建人" align="center" field="createByName" width="80" :formatter="colNoData" />
-                        <vxe-column title="创建时间" align="center" field="createTime" min-width="100" :formatter="colNoData" />
                         <vxe-column field="certFlag" title="会议状态" width="80">
                             <template #default="{ row }">
                                 <DictTag :options="dm_training_status" :value="row?.trainingStatus"></DictTag>
                             </template>
                         </vxe-column>
-                        <vxe-column title="操作" width="300" fixed="right">
+                        <vxe-column field="certFlag" title="签到二维码" width="120" align="center">
                             <template #default="{ row }">
-                                <el-button v-if="['3'].includes(row?.trainingStatus)" type="primary" text @click="trainingOn(row)">上架</el-button>
-                                <span></span>
-                                <el-button v-if="!['3'].includes(row?.trainingStatus)" type="danger" text @click="trainingOff(row)">下架</el-button>
+                                <el-button @click="trainingSignIn(row)"
+                                    :style="{ color: !['1', '0'].includes(row?.trainingStatus) ? '#999' : '#0079fe' }"
+                                    text :disabled="!['1', '0'].includes(row?.trainingStatus)">
+                                    查看
+                                </el-button>
+                            </template>
+                        </vxe-column>
+                        <vxe-column title="临时报名通道" align="center" field="createByName" width="130"
+                            :formatter="colNoData">
+                            <template #default="{ row }">
+                                <el-popconfirm confirm-button-text="修改" cancel-button-text="取消" title="是否修改临时报名的状态?"
+                                    @confirm="confirmEvent(row)" @cancel="cancelEvent">
+                                    <template #reference>
+                                        <el-switch v-model="row.tempStatus" :loading="loading1" active-value="1"
+                                            inactive-value="0" :before-change="beforeChange1" />
+                                    </template>
+                                </el-popconfirm>
+                                <el-button v-if="row.tempStatus == '1'" type="primary" text>
+                                    查看
+                                </el-button>
+                            </template>
+                        </vxe-column>
+                        <vxe-column title=" 创建人" align="center" field="createByName" width="80"
+                            :formatter="colNoData" />
+                        <vxe-column title="创建时间" align="center" field="createTime" width="200" :formatter="colNoData" />
+                        <vxe-column title="操作" width="300" fixed="right" align="center">
+                            <template #default="{ row }">
+                                <el-button v-if="['3'].includes(row?.trainingStatus)" type="primary" text
+                                    @click="trainingOn(row)">上架</el-button>
                                 <span></span>
-                                <el-button v-if="['3'].includes(row?.trainingStatus)" type="primary" @click="editRow(row)" text>编辑</el-button>
+                                <el-button v-if="!['3'].includes(row?.trainingStatus)" type="danger" text
+                                    @click="trainingOff(row)">下架</el-button>
                                 <span></span>
-                                <el-button v-if="['1', '0'].includes(row?.trainingStatus)" @click="trainingSignIn(row)" style="color: #0079fe;" text>签到二维码</el-button>
+                                <el-button v-if="['3'].includes(row?.trainingStatus)" type="primary"
+                                    @click="editRow(row)" text>编辑</el-button>
                                 <span></span>
-                                <el-button @click="router.push({ path: 'lmmeetingdetail', query: { id: row?.id } })" style="color: #0079fe;" text>详情</el-button>
+                                <el-button @click="router.push({ path: 'lmmeetingdetail', query: { id: row?.id } })"
+                                    style="color: #0079fe;" text>人员管理及详情</el-button>
                                 <span></span>
                                 <el-button text type="danger" @click="deleteRow(row)">删除</el-button>
                             </template>
                         </vxe-column>
                     </vxe-table>
                 </div>
-                <pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+                <pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
+                    @pagination="getList" />
             </div>
         </div>
     </div>
-    <SignInCode v-if="showSignIn" v-model:show="showSignIn" :info="rowInfo" :dict="{ dm_training_join_type }"></SignInCode>
+    <SignInCode v-if="showSignIn" v-model:show="showSignIn" :info="rowInfo" :dict="{ dm_training_join_type }">
+    </SignInCode>
 </template>
 
 <script setup name="meeting" lang="ts">
 import { colNoData, colNoUnm } from '@/utils/noData';
 import { searchTabs } from '@/views/models';
-import { trainingList, queryTrainingCount, trainingDelete, publishTraining, unpublishTraining } from '@/api/training';
+import { trainingList, queryTrainingCount, trainingDelete, publishTraining, unpublishTraining, offOrNoTemp } from '@/api/training';
 import { SignInCode } from '../models';
 
 const router = useRouter();
@@ -111,7 +149,7 @@ const data = reactive<any>({
     },
     rules: {}
 });
-
+const temporaryRegistration = ref(false)
 const { queryParams, form } = toRefs(data);
 /** 查询会员信息列表 */
 const getList = async () => {
@@ -121,7 +159,39 @@ const getList = async () => {
     total.value = res.total;
     loading.value = false;
 };
+const loading1 = ref(false)
+let resolvePromise: ((value: boolean) => void) | null = null;
 
+const beforeChange1 = (): Promise<boolean> => {
+    loading1.value = true;
+    return new Promise((resolve) => {
+        // 存储 resolve 以便在 confirm/cancel 时调用
+        resolvePromise = resolve;
+    });
+};
+const offOrNoTemps = async (row) => {
+    const res = await offOrNoTemp({
+        trainingId: row.id,
+        tempStatus: row.tempStatus == '1' ? '0' : '1'
+    })
+}
+
+const confirmEvent = (row) => {
+    if (resolvePromise) {
+        loading1.value = false;
+        resolvePromise(true); // 允许切换
+        resolvePromise = null; // 清空引用
+        offOrNoTemps(row)
+    }
+};
+
+const cancelEvent = () => {
+    if (resolvePromise) {
+        loading1.value = false;
+        resolvePromise(false); // 阻止切换
+        resolvePromise = null; // 清空引用
+    }
+};
 /** 搜索按钮操作 */
 const handleQuery = () => {
     queryParams.value.pageNum = 1;
@@ -196,4 +266,4 @@ onMounted(() => {
     getMeetingCount();
     getList();
 });
-</script>
+</script>

+ 54 - 20
src/views/training/models/meeting-detail-attend.vue

@@ -33,9 +33,9 @@
 
 
         <div class="d-flex a-c j-sb">
-            <searchTabs v-model="queryParams.res" @change="handleQuery" :list="tabs" key-label="name" key-count="num"
-                key-value="type"></searchTabs>
-
+            <searchTabs v-if="form?.conditions?.totalCheck == '1'" v-model="queryParams.res" @change="handleQuery"
+                :list="tabs" key-label="name" key-count="num" key-value="type"></searchTabs>
+            <span style="width: 1px;"></span>
             <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="auto">
                 <el-form-item label="姓名:" prop="name">
                     <el-input v-model="queryParams.name" placeholder="请输入姓名" clearable style="width: 180px" />
@@ -59,6 +59,15 @@
             <!-- 序号 -->
             <vxe-column type="seq" width="60" title="序号" align="center" />
             <vxe-column title="企业名称" field="company" min-width="100" :formatter="colNoData" />
+            <vxe-column title="盟员等级" field="vipLevel" min-width="100" :formatter="colNoData" align="center">
+                <template #default="{ row }">
+                    <div class="d-flex a-c j-c">
+                        <DictTag :options="vip_level" :value="row?.signupStatusForPc">
+                        </DictTag>
+                    </div>
+
+                </template>
+            </vxe-column>
             <vxe-column title="姓名" field="name" min-width="100" :formatter="colNoData" />
             <vxe-column title="职务" field="position" min-width="100" :formatter="colNoData" />
             <vxe-column title="联系方式" field="contact" min-width="100" :formatter="colNoData" />
@@ -70,28 +79,39 @@
                     </DictTag>
                 </template>
             </vxe-column>
-            <vxe-column title="审核状态" min-width="100" fixed="right">
+            <vxe-column v-if="form?.conditions?.totalCheck == '1'" title="审核状态" min-width="100" fixed="right">
                 <template #default="{ row }">
                     <DictTag :options="cpy_res_status" :value="row?.res">
                     </DictTag>
                 </template>
             </vxe-column>
-            <vxe-column title="操作" width="250" align="center" fixed="right">
+            <vxe-column v-if="form?.conditions?.totalCheck == '1'" title="操作" width="250" align="center" fixed="right">
                 <template #default="{ row }">
-                    <el-button type="text" size="small"> 通过</el-button>
-                    <el-button size="small" type="danger">不通过 </el-button>
+                    <el-button type="danger" size="small" v-if="row?.res !== '0'"
+                        @click="openDialog(row)">重审</el-button>
+                    <el-button size="small" type="danger" @click="openDialog(row)" v-else>审核</el-button>
                 </template>
             </vxe-column>
         </vxe-table>
-
         <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
             v-model:limit="queryParams.pageSize" @pagination="getList" />
     </div>
-
+    <el-dialog v-model="dialogVisible" title="审核信息" width="500" center>
+        <span class="f-s-16 mb-15">请填写审核原因:</span>
+        <el-input v-model="dialoginput" type="textarea" :rows="4"></el-input>
+        <template #footer>
+            <div class="dialog-footer">
+                <el-button type="primary" @click="signupApprovals('1')">通过</el-button>
+                <el-button type="danger" @click="signupApprovals('2')">
+                    不通过
+                </el-button>
+            </div>
+        </template>
+    </el-dialog>
 </template>
 <script setup name="MeetingDetailInfo" lang="ts">
 import { ref, reactive, onMounted } from 'vue';
-import { trainingDetailById, trainingMembers } from '@/api/training';
+import { signupCount, trainingMembers, signupApproval } from '@/api/training';
 import { searchTabs } from '@/views/models';
 import { colNoData } from '@/utils/noData';
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
@@ -104,16 +124,15 @@ const props = defineProps({
     },
 });
 
-
+const dialogVisible = ref(false)
+const dialoginput = ref()
+const currentRow = ref()
+const openDialog = (row) => {
+    currentRow.value = row;  // 保存当前行数据
+    dialogVisible.value = true;
+};
 const query = useRoute().query;
-// const getDetail = async () => {
-//     const res = await trainingDetailById(query?.id as string);
-//     if (res.code === 200) {
-//         form.value = res.data;
-//     } else {
-//         ElMessage.error(res.msg);
-//     }
-// };
+
 const queryParams = ref<any>({
     pageNum: 1,
     pageSize: 10,
@@ -123,6 +142,12 @@ const loading = ref(false);
 const total = ref(0);
 const list = ref<any>([]);
 const tabs = ref([]);
+const getExpertPersonCount = async () => {
+    const res = await signupCount(query?.id);
+    if (res?.code === 200) {
+        tabs.value = res.data;
+    }
+};
 const getList = async () => {
     loading.value = true;
     const res = await trainingMembers(queryParams.value);
@@ -131,6 +156,15 @@ const getList = async () => {
     total.value = res.total;
     loading.value = false;
 };
+const signupApprovals = async (type: String) => {
+    const res = await signupApproval({
+        targetId: currentRow.value.id,
+        res: type,
+        msg: dialoginput.value
+    })
+    dialogVisible.value = false
+    handleQuery()
+}
 const handleQuery = () => {
     queryParams.value.pageNum = 1;
     getList();
@@ -141,8 +175,8 @@ const resetQuery = () => {
     handleQuery();
 };
 onMounted(() => {
-    // getDetail();
     getList();
+    getExpertPersonCount()
 });
 </script>
 <style scoped lang="scss">

+ 17 - 3
src/views/training/models/meeting-detail-info.vue

@@ -5,12 +5,12 @@
             <el-descriptions :column="4">
                 <el-descriptions-item label="会议名称:">{{ form?.trainingName || '-' }}</el-descriptions-item>
                 <el-descriptions-item label="培训时间:">{{ form?.trainingStart }}~{{ form?.trainingEnd
-                    }}</el-descriptions-item>
+                }}</el-descriptions-item>
                 <el-descriptions-item label="报名时间:">{{ form?.signupStart }}~{{ form?.signupEnd
-                    }}</el-descriptions-item>
+                }}</el-descriptions-item>
                 <el-descriptions-item label="培训方式:">{{ selectDictLabel(dm_training_join_type, form?.joinType) ||
                     '-'
-                    }}</el-descriptions-item>
+                }}</el-descriptions-item>
                 <el-descriptions-item label="培训地点:">{{ form?.trainingLocation || '-' }}</el-descriptions-item>
                 <el-descriptions-item label="联系人:">{{ form?.contactName || '-' }}</el-descriptions-item>
                 <el-descriptions-item label="联系电话:">{{ form?.tel || '-' }}</el-descriptions-item>
@@ -36,12 +36,26 @@
                     <div class="c-333 mb-10">与会须知:</div>
                     <div>{{ form?.notice || '-' }}</div>
                 </div>
+                <div class="flex1">
+                    <div class="c-333 mb-10">会议备注:</div>
+                    <div>{{ form?.remark || '-' }}</div>
+                </div>
                 <div v-if="form?.attachments" class="flex1">
                     <div class="c-333 mb-10">相关文件:</div>
                     <FileLook v-model="form.attachments" :span="12"></FileLook>
                 </div>
             </div>
             <div class="d-flex f-s-14 c-666">
+                <div v-if="form?.attachments" class="flex1">
+                    <div class="c-333 mb-10">微信群聊二维码:</div>
+                    <div class="d-flex flex-wrap">
+                        <template v-for="(item, index) in form?.wechatQrCode" :key="index">
+                            <div class="mr-10 mb-10">
+                                <ImagePreview :src="item" :width="100"></ImagePreview>
+                            </div>
+                        </template>
+                    </div>
+                </div>
                 <div class="flex1">
                     <div class="c-333 mb-10">封面图:</div>
                     <div>

+ 1 - 1
src/views/training/models/sign-in-code.vue

@@ -2,7 +2,7 @@
     <vxe-modal v-model="dialogVisible" :title="title" show-zoom resize show-footer destroy-on-close transfer @hide="close" :width="width" :z-index="1002">
         <template #default>
             <div>
-                <div v-if="info" ref="codeImgRef" style="width: 400px; margin: 0 auto;">
+                <div v-if="info" ref="codeImgRef" style="width: 400px; margin: 0 auto;padding: 10px;">
                     <div class="mb-6 f-w-6 f-s-16 c-333">{{ info?.trainingName }}</div>
                     <div class="mb-6">培训时间:{{ info?.trainingStart  }}~{{ info?.trainingEnd }}</div>
                     <div class="mb-6">培训方式:{{ selectDictLabel(dict.dm_training_join_type, info.joinType) }}</div>

+ 63 - 0
src/views/training/models/temporary-registration.vue

@@ -0,0 +1,63 @@
+<template>
+    <vxe-modal v-model="dialogVisible" :title="title" show-zoom resize show-footer destroy-on-close transfer @hide="close" :width="width" :z-index="1002">
+        <template #default>
+            <div>
+                <div v-if="info" ref="codeImgRef" style="width: 400px; margin: 0 auto;">
+                    <div class="mb-6 f-w-6 f-s-16 c-333">{{ info?.trainingName }}</div>
+                    <div class="mb-6">培训时间:{{ info?.trainingStart  }}~{{ info?.trainingEnd }}</div>
+                    <div class="mb-6">培训方式:{{ selectDictLabel(dict.dm_training_join_type, info.joinType) }}</div>
+                    <div class="mb-6">联系电话:{{ info?.tel }}</div>
+                    <div>临时报名二维码</div>
+                    <div class="d-flex j-c a-c pd-20">
+                        <vueQr :text="VITE_APP_SHARE_QR_CODE_URL + '/meeting-sign-in?meetid=' + info?.id" :size="300"></vueQr>
+                    </div>
+                </div>
+            </div>
+
+            <div class="d-flex j-c">
+                <el-button @click="saveImg">保存临时报名二维码</el-button>
+            </div>
+        </template>
+    </vxe-modal>
+</template>
+
+<script setup name="SignInCode" lang="ts">
+import { propTypes } from '@/utils/propTypes';
+import vueQr from 'vue-qr/src/packages/vue-qr.vue';
+import html2canvas from 'html2canvas';
+const emit = defineEmits(['update:show', 'close', 'success']);
+const props = defineProps({
+    show: propTypes.bool.def(false),
+    title: propTypes.string.def('临时报名'),
+    width: propTypes.number.def(500),
+    info: propTypes.any.def(null),
+    dict: propTypes.object.def({})
+});
+const VITE_APP_SHARE_QR_CODE_URL = ref(import.meta.env.VITE_APP_SHARE_QR_CODE_URL);
+const dialogVisible = ref(false);
+const close = () => {
+    emit('update:show', false);
+    emit('close', false);
+};
+const codeImgRef = ref<HTMLElement | null>(null);
+const saveImg = () => {
+    html2canvas(codeImgRef.value, {
+        useCORS: true,
+        allowTaint: false,
+        scale: 2
+    }).then((canvas) => {
+        const url = canvas.toDataURL('image/png');
+        const a: any = document.createElement('a');
+        a.download = `${props?.info?.trainingName}-临时报名二维码.png`;
+        a.href = url;
+        a.click();
+    });
+};
+watch(
+    () => props.show,
+    (val) => {
+        dialogVisible.value = val;
+    },
+    { immediate: true }
+);
+</script>