Browse Source

Merge branch 'master' of http://git.yujin.shuziyunyao.com/yujin/digital-medicine-front

huangxw 1 tháng trước cách đây
mục cha
commit
a786d5668b

+ 1 - 0
src/utils/request.ts

@@ -182,6 +182,7 @@ export function download(url: any, params = {}, fileName = '') {
     const config: any = {}
     config.headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
     config.responseType = 'blob';
+    config.params = params;
     return service
         .get(url, config)
         .then(async (resp: any) => {

+ 10 - 1
src/views/dgtmedicine/member/index.vue

@@ -28,6 +28,7 @@
                     <el-form-item>
                         <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
                         <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+                        <el-button icon="Bottom" @click="handleExport">导出会员列表</el-button>
                     </el-form-item>
                 </el-form>
             </div>
@@ -178,7 +179,15 @@ const resetQuery = () => {
     queryParams.value.payEndDate = '';
     handleQuery();
 };
-
+const handleExport = () => {
+    proxy?.download(
+        `dgtmedicine/member/exportMemberList?`,
+        {
+            ...queryParams.value
+        },
+        `会员列表_${new Date().getTime()}.xlsx`
+    );
+};
 const memberDetail = (row: any) => {
     router.push({ path: `member-detail`, query: { memberId: row.id } });
 };

+ 18 - 3
src/views/training/meeting/index.vue

@@ -56,12 +56,15 @@
                                 </div>
                             </template>
                         </vxe-column>
-                        <vxe-column field="signupsTime" min-width="350" title="报名时间" class-name="f-w-600">
+                        <vxe-column field="signupsTime" min-width="350" title="报名时间" class-name="f-w-600 p-rtv">
                             <template #default="{ row }">
                                 <div class="d-flex a-c">
                                     {{ row.signupStart.slice(0, -3) }}~{{ row.signupEnd.slice(0, -3) }}
                                     <DictTag :options="lm_training_join_status" :value="row?.joinStatus"></DictTag>
                                 </div>
+                                <div v-if="row.joinStatus == '1'" class="pos-tag">
+                                    <el-button @click="openEnrollRegistration(row)" type="primary" size="small" text>报名二维码{{ '>' }}</el-button>
+                                </div>
                             </template>
                         </vxe-column>
                         <vxe-column field="joinType" title="会议方式" width="80">
@@ -132,6 +135,7 @@
     </div>
     <SignInCode v-if="showSignIn" v-model:show="showSignIn" :info="rowInfo" :dict="{ lm_training_join_type }"></SignInCode>
     <TemporaryRegistration v-if="showTemporary" v-model:show="showTemporary" :info="temporaryRegistration" :dict="{ lm_training_join_type }"></TemporaryRegistration>
+    <EnrollRegistration v-if="showEnroll" v-model:show="showEnroll" :info="rowInfo" :dict="{ lm_training_join_type }"></EnrollRegistration>
     <el-dialog v-model="dialogVisible" title="会议门户" width="500">
         <div class="mb-20">会议名称:{{ training?.trainingName }}</div>
         <div>访问地址:{{ `${VITE_APP_MEETING_URL}/?id=${training?.pageId}` }}</div>
@@ -148,7 +152,7 @@
 import { offOrNoTemp, publishTraining, queryTrainingCount, trainingDelete, trainingList, unpublishTraining,switchPage } from '@/api/training';
 import { colNoData } from '@/utils/noData';
 import { searchTabs } from '@/views/models';
-import { SignInCode, TemporaryRegistration } from '../models';
+import { SignInCode, TemporaryRegistration,EnrollRegistration } from '../models';
 import { copyTextToClipboard } from '@/directive/common/copyText';
 const VITE_APP_MEETING_URL = ref(import.meta.env.VITE_APP_MEETING_URL);
 const router = useRouter();
@@ -157,6 +161,7 @@ const { lm_training_join_type, yes_no, dm_training_cert, lm_training_status,lm_t
 const loading = ref(true);
 const showSearch = ref(true);
 const showSignIn = ref(false);
+const showEnroll = ref(false);
 const total = ref(0);
 const queryFormRef = ref<ElFormInstance>();
 const dataList = ref<any[]>([]);
@@ -206,7 +211,10 @@ const offOrNoTemps = async (row) => {
     })
 }
 
-
+const openEnrollRegistration = (row) => {
+    rowInfo.value = { ...row };
+    showEnroll.value = true;
+};
 const confirmEvent = (row) => {
     if (resolvePromise) {
         loading1.value = false;
@@ -334,3 +342,10 @@ onMounted(() => {
     getList();
 });
 </script>
+<style lang="scss" scoped>
+.pos-tag{
+    position: absolute;
+    bottom: 5px;
+    right: 5px;
+}
+</style>

+ 64 - 0
src/views/training/models/EnrollRegistration.vue

@@ -0,0 +1,64 @@
+<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">会议名称:{{ info?.trainingName }}</div>
+                    <div class="mb-6">会议时间:{{ info?.trainingStart }}~{{ info?.trainingEnd }}</div>
+                    <div class="mb-6">会议方式:{{ selectDictLabel(dict.lm_training_join_type, info.joinType) }}</div>
+                    <div class="mb-6">联系电话:{{ info?.tel }}</div>
+                    <div class="mb-6 h-10"></div>
+                    <div class="d-flex j-c f-w-6 f-s-18 c-333">报名二维码</div>
+                    <div class="d-flex j-c a-c pd-10">
+                        <vueQr :text="VITE_APP_SHARE_QR_CODE_URL + '/meeting-detail?id=' + info?.id + '&tempJoin=0'" :size="300" colorDark="green"></vueQr>
+                    </div>
+                </div>
+            </div>
+
+            <div class="d-flex j-c">
+                <el-button @click="saveImg">保存报名二维码</el-button>
+            </div>
+        </template>
+    </vxe-modal>
+</template>
+
+<script setup name="EnrollRegistration" 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>

+ 1 - 0
src/views/training/models/index.ts

@@ -5,6 +5,7 @@ export { default as TemporaryRegistration } from './temporary-registration.vue';
 export { default as MeetingCustom } from './meeting-custom.vue'; // 查看签到码
 export { default as registrationInfo } from './registration-info.vue';
 export { default as meetingCustomPreview } from './meeting-custom-preview.vue';
+export { default as EnrollRegistration } from './EnrollRegistration.vue'; 
 export { default as MeetingTplH5 } from './meeting-tpl-h5.vue';
 export { default as MeetingTplList } from './meeting-tpl-list.vue';
 export { default as MeetingTplEvents } from './meeting-tpl-events.vue';