huangxw 7 сар өмнө
parent
commit
ac7d9eef84

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

@@ -0,0 +1,33 @@
+import request, { download, downloadFile } from '@/utils/request';
+import { AxiosPromise } from 'axios';
+// 查询培训列表
+export const trainingList = (query?: any): AxiosPromise => {
+    return request({
+        url: '/dgtmedicine/training/list',
+        method: 'get',
+        params: query
+    });
+};
+// 会议新增
+export const trainingAdd = (data: any): AxiosPromise => {
+    return request({
+        url: '/dgtmedicine/training/add',
+        method: 'post',
+        data
+    });
+};
+// 会议修改
+export const trainingUpdate = (data: any): AxiosPromise => {
+    return request({
+        url: '/dgtmedicine/training/edit',
+        method: 'post',
+        data
+    });
+};
+// 会议详情
+export const trainingDetail = (id: string): AxiosPromise => {
+    return request({
+        url: `/dgtmedicine/training/getInfo/${id}`,
+        method: 'get'
+    });
+};

+ 50 - 50
src/components/ImagePreview/index.vue

@@ -1,49 +1,49 @@
 <template>
-  <el-image :src="`${realSrc}`" fit="cover" :style="`width:${realWidth};height:${realHeight};`" :preview-src-list="realSrcList" preview-teleported>
-    <template #error>
-      <div class="image-slot">
-        <el-icon><picture-filled /></el-icon>
-      </div>
-    </template>
-  </el-image>
+    <el-image :src="`${realSrc}`" fit="cover" :style="`width:${realWidth};height:${realHeight};`" :preview-src-list="realSrcList" preview-teleported>
+        <template #error>
+            <div class="image-slot">
+                <el-icon><picture-filled /></el-icon>
+            </div>
+        </template>
+    </el-image>
 </template>
 
 <script setup lang="ts">
 import { propTypes } from '@/utils/propTypes';
 
 const props = defineProps({
-  src: propTypes.string.def(''),
-  width: {
-    type: [Number, String],
-    default: ''
-  },
-  height: {
-    type: [Number, String],
-    default: ''
-  }
+    src: propTypes.string.def(''),
+    width: {
+        type: [Number, String],
+        default: ''
+    },
+    height: {
+        type: [Number, String],
+        default: ''
+    }
 });
 
 const realSrc = computed(() => {
-  if (!props.src) {
-    return;
-  }
-  let real_src = props.src.split(',')[0];
-  return real_src;
+    if (!props.src) {
+        return;
+    }
+    let real_src = props.src.split(',')[0];
+    return real_src;
 });
 
 const realSrcList = computed(() => {
-  if (!props.src) {
-    return [];
-  }
-  let real_src_list = props.src.split(',');
-  let srcList: string[] = [];
-  real_src_list.forEach((item: string) => {
-    if (item.trim() === '') {
-      return;
+    if (!props.src) {
+        return [];
     }
-    return srcList.push(item);
-  });
-  return srcList;
+    let real_src_list = props.src.split(',');
+    let srcList: string[] = [];
+    real_src_list.forEach((item: string) => {
+        if (item.trim() === '') {
+            return;
+        }
+        return srcList.push(item);
+    });
+    return srcList;
 });
 
 const realWidth = computed(() => (typeof props.width == 'string' ? props.width : `${props.width}px`));
@@ -53,27 +53,27 @@ const realHeight = computed(() => (typeof props.height == 'string' ? props.heigh
 
 <style lang="scss" scoped>
 .el-image {
-  border-radius: 5px;
-  background-color: #ebeef5;
-  box-shadow: 0 0 5px 1px #ccc;
+    border-radius: 5px;
+    background-color: #ebeef5;
+    box-shadow: 0 0 5px 1px #ccc;
 
-  :deep(.el-image__inner) {
-    transition: all 0.3s;
-    cursor: pointer;
+    :deep(.el-image__inner) {
+        transition: all 0.3s;
+        cursor: pointer;
 
-    &:hover {
-      transform: scale(1.2);
+        &:hover {
+            transform: scale(1.2);
+        }
     }
-  }
 
-  :deep(.image-slot) {
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    width: 100%;
-    height: 100%;
-    color: #909399;
-    font-size: 30px;
-  }
+    :deep(.image-slot) {
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        width: 100%;
+        height: 100%;
+        color: #909399;
+        font-size: 30px;
+    }
 }
 </style>

+ 132 - 0
src/views/training/meeting-add/index.vue

@@ -0,0 +1,132 @@
+<template>
+    <div class="p-3">
+        <div class="bg-fff flex1 ov-hd d-flex flex-cln">
+            <div class="d-flex a-c pd-16 border-bottom">
+                <div class="f-s-20 c-333 f-w-7 mr-10">{{ form.id ? '编辑' : '新增' }}会议</div>
+                <el-button @click="router.go(-1)" type="primary" text>
+                    <el-icon>
+                        <Back />
+                    </el-icon>
+                    返回上一级
+                </el-button>
+            </div>
+            <div class="flex1 over-auto">
+                <el-form ref="formRef" label-width="auto" label-position="top" :model="form" :rules="rules">
+                    <div class="pd-16 border-bottom ov-hd">
+                        <el-row :gutter="20">
+                            <el-col :span="6">
+                                <el-form-item label="会议名称" prop="trainingName">
+                                    <el-input v-model="form.trainingName" placeholder="请输入会议名称" clearable />
+                                </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" 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-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>
+                            </el-col>
+                            <el-col :span="6">
+                                <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>
+                            </el-col>
+                            <el-col v-if="+form?.certFlag" :span="6">
+                                <el-form-item label="证书名称" prop="certificateInfo">
+                                    <el-select v-model="form.certificateInfo" 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-row>
+                        <el-row :gutter="20">
+                            <el-col :span="6">
+                                <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="6">
+                                <el-form-item label="封面图" prop="coverImg">
+                                    <ImageUpload v-model="form.coverImg" :limit="1"></ImageUpload>
+                                </el-form-item>
+                            </el-col>
+                            <el-col :span="6">
+                                <el-form-item label="会议图" prop="trainingImg">
+                                    <ImageUpload v-model="form.trainingImg" :fileSize="40"></ImageUpload>
+                                </el-form-item>
+                            </el-col>
+                            <el-col :span="6">
+                                <el-form-item label="相关文件" prop="attachments">
+                                    <FileUpload v-model="form.attachments" format="array" :limit="20" :fileSize="100"></FileUpload>
+                                </el-form-item>
+                            </el-col>
+                        </el-row>
+                    </div>
+                </el-form>
+            </div>
+            <div class="d-flex a-c j-c pd-16">
+                <el-button @click="router.go(-1)">取消</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 { debounce } from 'lodash';
+import { useRouter } from 'vue-router';
+import { trainingAdd, trainingDetail, trainingUpdate } from '@/api/training';
+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 router = useRouter();
+const route = useRoute();
+const form = ref<any>({
+    id: undefined
+});
+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' }],
+    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' }],
+});
+const formRef = ref();
+
+const save = debounce(async () => {
+    await formRef.value.validate();
+    const res = form.value.id ? await trainingUpdate(form.value) : await trainingAdd(form.value);
+    if (res && res.code === 200) {
+        router.go(-1);
+    }
+}, 500);
+// 获取专家详情
+const getMeetingDetail = async () => {
+    if (route.query?.id) {
+        const res = await trainingDetail(route.query?.id as string);
+        if (!res || res.code !== 200) return;
+        form.value = res.data;
+    }
+};
+onMounted(() => {
+    getMeetingDetail();
+});
+</script>

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

@@ -0,0 +1,4 @@
+<template>
+    <div>xx</div>
+</template>
+<script lang="tsx" setup></script>

+ 146 - 0
src/views/training/meeting/index.vue

@@ -0,0 +1,146 @@
+<template>
+    <div class="p-3">
+        <div class="bg-fff flex1 ov-hd d-flex flex-cln" v-show="showSearch">
+            <div class="pd-16 border-bottom">
+                <div class="f-s-20 c-333 f-w-7 mb-10">会议管理</div>
+                <div class="d-flex">
+                    <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-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>
+                            </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>
+                            </el-form-item>
+                            <el-form-item>
+                                <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+                                <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+                            </el-form-item>
+                        </el-form>
+                    </div>
+                </div>
+            </div>
+            <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>
+                    </div>
+                    <el-button type="primary" @click="router.push({ path: 'meeting-add' })">新增会议</el-button>
+                </div>
+                <div class="flex1 ov-hd">
+                    <vxe-table :loading="loading" border :data="dataList" min-height="0" max-height="100%">
+                        <vxe-column title="序号" align="center" type="seq" width="60" />
+                        <vxe-column title="操作" width="250" align="center" fixed="right">
+                            <template #default="{ row }">
+                                <el-button type="primary" @click="editRow(row)" text>编辑</el-button>
+                                <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" />
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup name="meeting" lang="ts">
+import { colNoData } from '@/utils/noData';
+
+import { DateRange } from '@/views/models/index';
+import { searchTabs } from '@/views/models';
+import { expertList, expertPersonCount, expertPersonDelete, expertPersonOff, expertPersonOn } from '@/api/authority';
+import { trainingList } from '@/api/training';
+const router = useRouter();
+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 loading = ref(true);
+const showSearch = ref(true);
+const total = ref(0);
+const queryFormRef = ref<ElFormInstance>();
+const dataList = ref<any[]>([]);
+const initFormData = {};
+const data = reactive<any>({
+    form: { ...initFormData },
+    queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+    },
+    rules: {}
+});
+
+const { queryParams, form } = toRefs(data);
+/** 查询会员信息列表 */
+const getList = async () => {
+    loading.value = true;
+    const res = await trainingList(queryParams.value);
+    dataList.value = res.rows;
+    total.value = res.total;
+    loading.value = false;
+};
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+    queryParams.value.pageNum = 1;
+    getList();
+};
+// /** 切换前端显示状态 */
+const changeRowPutaway = async (value, row) => {
+    try {
+        if (+value) {
+            await expertPersonOn(row.id);
+            ElMessage.success('上架成功');
+        } else {
+            await expertPersonOff(row.id);
+            ElMessage.success('下架成功');
+        }
+        getList();
+    } catch (error) {
+        ElMessage.error('操作失败');
+    }
+};
+/** 重置按钮操作 */
+const resetQuery = () => {
+    queryFormRef.value?.resetFields();
+    handleQuery();
+};
+
+/** 编辑专家 */
+const editRow = (row) => {
+    router.push({ path: 'authority-input', query: { id: row.id } });
+};
+
+/** 删除专家 */
+const deleteRow = async (row) => {
+    ElMessageBox.confirm(`确认要删除专家为"${row.name}"的数据吗?`, '删除提示', {
+        confirmButtonText: '确认',
+        cancelButtonText: '取消',
+        type: 'warning'
+    }).then(async () => {
+        const res = await expertPersonDelete([row.id]);
+        if (res) {
+            ElMessage.success('删除成功');
+            getList();
+        }
+    });
+};
+// 获取专家统计数量
+const tabs = ref([]);
+const getExpertPersonCount = async () => {
+    const res = await expertPersonCount();
+    if (res?.code === 200) {
+        tabs.value = res.data
+    }
+};
+onMounted(() => {
+    getExpertPersonCount();
+    getList();
+});
+</script>