From 5f00696dfb25bc90034448ceb634ed1ef256681a Mon Sep 17 00:00:00 2001 From: qiyunfeng-create <1940665526@qq.com> Date: 星期四, 21 八月 2025 21:13:35 +0800 Subject: [PATCH] Merge branch 'master' of http://182.92.203.7:2001/r/xiehe_website --- src/views/courseManage/components/class.vue | 502 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 502 insertions(+), 0 deletions(-) diff --git a/src/views/courseManage/components/class.vue b/src/views/courseManage/components/class.vue new file mode 100644 index 0000000..442fd27 --- /dev/null +++ b/src/views/courseManage/components/class.vue @@ -0,0 +1,502 @@ +<template> + <div class="classPage"> + <div class="headerBox"> + <div class="searchBox"> + <el-input v-model="searchKey" @clear="searchData()" clearable placeholder="璇疯緭鍏ュ叧閿瓧"> + <template #append> + <el-button type="primary" class="searchBtn" :icon="Search" @click="searchData()" /> + </template> + </el-input> + </div> + <el-button type="primary" class="applyStartClasses" @click="applyClass">鐢宠寮�鐝�</el-button> + </div> + <div class="classListBox" v-loading="pages.loading"> + <div class="classItem" v-for="(item, index) in classList" :key="index"> + <div class="itemHeader"> + <div class="title">{{ item.name }}</div> + <div class="classId">锛圛D锛歿{ item.id }}锛�</div> + <div class="copyIdBtn" v-if="item.applyState == 'Normal'" @click="copy(item.refCode)"> + 澶嶅埗閭�璇风爜 + </div> + <div + class="copyIdBtn" + style="background: transparent; padding: 0" + v-if="item.applyState == 'Reject'" + > + <el-icon @click="delClass(item)" style="color: red; font-size: 14px" + ><Delete + /></el-icon> + </div> + </div> + <div class="itemInfo" @click="groupDetail(item)"> + <div class="infoBox"> + <p> + 鐘舵�侊細<span v-if="item.applyState == 'WaitAudit'" style="color: #ef9f29"> + 瀹℃牳涓� </span + ><span v-if="item.applyState == 'Normal'" style="color: #1dbd11"> 杩涜涓� </span + ><span v-if="item.applyState == 'Reject'" style="color: red"> 鏈�氳繃 </span> + </p> + <p v-if="item.applyState == 'Reject'"> + 鎷掔粷鍘熷洜锛�<span style="color: red">{{ item.reason != '' ? item.reason : '-' }}</span> + </p> + <p>鐝骇浜烘暟锛歿{ item.memberCount }} / {{ item.maxUserCount }}</p> + <p> + 鏈夋晥鏈燂細{{ moment(item.beginDate).format('YYYY-MM-DD') }} - + {{ moment(item.endDate).format('YYYY-MM-DD') }} + </p> + </div> + </div> + </div> + </div> + <div class="pagination-box" v-if="classList.length > 0"> + <el-pagination + v-model:current-page="pages.page" + v-model:page-size="pages.pageSize" + :background="false" + layout="total, prev, pager, next" + :total="pages.count" + @current-change="pageChange" + @size-change="handleSizeChange" + /> + </div> + <div class="nullBox" v-if="!pages.loading && classList.length == 0"> + <el-empty /> + </div> + <!-- 鐢宠寮�鐝脊妗� --> + <el-dialog v-model="applyClassDialog" width="450" align-center> + <template #title>鐢宠寮�鐝�</template> + <el-form :model="formData" label-position="left" ref="dialogFormRef" label-width="100px"> + <el-form-item + label="鐝骇鍚嶇О" + prop="name" + :rules="[{ required: true, message: '璇疯緭鍏ョ彮绾у悕绉�' }]" + > + <el-input v-model="formData.name" placeholder="璇疯緭鍏ョ彮绾у悕绉�" /> + </el-form-item> + <el-form-item + label="鐝骇浜烘暟" + prop="num" + :rules="[{ required: true, message: '璇疯緭鍏ョ彮绾т汉鏁�' }]" + > + <el-input-number v-model="formData.num" :min="1" :step="1" :precision="0" /> + </el-form-item> + <el-form-item + label="鐝骇鏈夋晥鏈�" + prop="date" + :rules="[{ required: true, message: '璇烽�夋嫨鐝骇鏈夋晥鏈�' }]" + > + <el-date-picker + v-model="formData.date" + type="daterange" + range-separator="-" + start-placeholder="寮�濮嬫椂闂�" + end-placeholder="缁撴潫鏃堕棿" + /> + </el-form-item> + </el-form> + <template #footer> + <div class="dialog-footer"> + <el-button @click="applyClassDialog = false">鍙栨秷</el-button> + <el-button type="primary" @click="submit" :loading="submitLoading">鎻愪氦</el-button> + </div> + </template> + </el-dialog> + </div> +</template> + +<script setup lang="ts"> +import { defineProps, reactive, ref, onMounted, inject, watch } from 'vue' +import { Search } from '@element-plus/icons-vue' +import { ElMessage } from 'element-plus' +import { getPublicImage } from '@/assets/js/middleGround/tool.js' +import moment from 'moment' +import { useRouter } from 'vue-router' +import useClipboard from 'vue-clipboard3' + +const { toClipboard } = useClipboard() +const uRouter = useRouter() +const MG: any = inject('MG') +const props = defineProps<{ + courseId: number + bookInfo: any +}>() + +const emit = defineEmits(['refreshParent']) + +// 鐢宠寮�鐝槻鎶杔oading +const submitLoading = ref(false) + +const classList: any = ref([]) + +onMounted(() => { + getData() +}) + +const searchKey = ref('') +const pages = reactive({ + page: 1, + pageSize: 6, + count: 0, + loading: true +}) + +const searchData = () => { + pages.page = 1 + pages.pageSize = 10 + getData() +} + +// 鑾峰彇鐝骇 +const getData = () => { + pages.loading = true + MG.edu + .getCourseClassList({ + courseId: props.courseId, + start: (pages.page - 1) * pages.pageSize, + size: pages.pageSize, + sort: { + type: 'Desc', + field: 'CreateDate' + }, + filterList: [], + searchList: searchKey.value + ? [ + { + keywords: searchKey.value, + field: 'Name', + compareType: 'Contains' + } + ] + : [] + }) + .then((res: any) => { + pages.loading = false + pages.count = res.totalSize; + classList.value = res.datas.map((item: any) => { + return { + ...item, + name: item.name, + id: item.id, + icon: item.icon ? getPublicImage(item.icon, 80) : '', + introduction: item.description, + reason: item.applyReturnMsg ? JSON.parse(item.applyReturnMsg).reason : '' + } + }) + refreshParent() + }) +} + +// 鍔犲叆鐝骇 +const applyClass = () => { + formData.value = { + name: '', + num: '', + date: '' + } + applyClassDialog.value = true +} + +// 鍒锋柊鐖剁粍浠舵暟鎹� +const refreshParent = () => { + emit('refreshParent', 'del') +} + +const applyClassDialog = ref(false) +const formData = ref({ + name: '', + num: '', + date: '' +}) + +const submit = () => { + submitLoading.value = true + MG.edu + .newCourseClass({ + courseId: props.courseId, + name: formData.value.name, + description: '', + icon: '', + type: 'class', + beginDate: moment(formData.value.date[0]).format('YYYY-MM-DD'), + endDate: moment(formData.value.date[1]).format('YYYY-MM-DD'), + config: '', + price: 0, + maxUserCount: formData.value.num + }) + .then((res: any) => { + if (res) { + setTimeout(() => { + submitLoading.value = false + ElMessage.success('寮�鐝凡鐢宠锛岀瓑寰呯鐞嗗憳瀹℃牳銆�') + applyClassDialog.value = false + getData() + }, 1000) + } + }) + .catch((err: any) => { + ElMessage.error('寮�鐝敵璇峰嚭閿欙紝璇风◢鍚庡啀璇�') + setTimeout(() => { + submitLoading.value = false + }, 1000) + }) +} + +// 澶嶅埗 +const copy = async (text: string) => { + try { + await toClipboard(text) + ElMessage({ + message: '澶嶅埗鎴愬姛', + type: 'success' + }) + } catch (e) { + console.error(e) + } +} + +// 鍒犻櫎鐝骇 +const delClass = (item: any) => { + const data = { + ids: [item.id] + } + MG.edu + .delCourseClass(data) + .then((res: any) => { + if (res) { + ElMessage({ + message: '宸插垹闄�', + type: 'success' + }) + getData() + } + }) + .catch((err: any) => { + ElMessage({ + message: '鍒犻櫎澶辫触', + type: 'error' + }) + console.log(err) + }) +} + +// 鑾峰彇瀹℃牳閫氳繃鐨勮绋� +const coursePages = reactive({ + page: 1, + pageSize: 10, + count: 0, + loading: false +}) +const courseListData = ref([]) + +// const getCourse = () => { +// coursePages.loading = true +// const searchData = [ +// { +// keywords: 'jsek_digitalTextbooks', +// field: 'ProductType' +// } +// ] +// const data = { +// Size: coursePages.pageSize, +// Start: coursePages.pageSize * coursePages.page - coursePages.pageSize, +// sort: { +// type: 'Desc', +// field: 'CreateDate' +// }, +// searchList: searchData +// } +// MG.store +// .getPurchasedProductList(data) +// .then((res: any) => { +// coursePages.count = res.totalSize +// courseListData.value = res.datas.map((item: any) => { +// return { +// ...item, +// img: item.product.icon ? getPublicImage(item.product.icon, 80) : '' +// } +// }) +// coursePages.loading = false +// }) +// .catch(() => { +// coursePages.loading = false +// }) +// } + +const pageChange = (val: number) => { + pages.page = val + getData() +} +const handleSizeChange = (val: number) => { + pages.pageSize = val + getData() +} + +const groupDetail = (item: any) => { + if (item.applyState == 'WaitAudit') { + ElMessage({ + message: '姝e湪瀹℃牳涓�....', + type: 'warning' + }) + return false + } + if (item.applyState == 'Reject') { + ElMessage({ + message: '瀹℃牳鏈�氳繃', + type: 'warning' + }) + return false + } + const bookData = item.linkProductDto.product + let classinfo: any = { + id: item.id, + name: item.name, + courseId: props.courseId, + icon: bookData.icon, + rootCmsItemId: bookData.rootCmsItemId, + bookId: bookData.id, + author: bookData.author, + isbn: bookData.isbn, + bookRefCode: bookData.refCode + } + let page = uRouter.resolve({ + path: '/classManage', + query: { + classInfo: JSON.stringify(classinfo) + } + }) + window.open(page.href, '_blank') +} +</script> + +<style lang="less" scoped> +.classPage { + .headerBox { + margin-bottom: 10px; + overflow: hidden; + .searchBox { + width: 300px; + float: left; + .searchBtn { + background-color: var(--el-color-primary); + color: #fff; + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + } + .applyStartClasses { + float: right; + } + } + .classListBox { + overflow: hidden; + min-height: 200px; + .classItem { + float: left; + width: 49%; + margin-bottom: 16px; + margin-right: 1%; + border-radius: 8px; + border: 1px solid #efefef; + overflow: hidden; + + &:nth-child(2n) { + margin-left: 1%; + margin-right: 0; + } + .itemHeader { + height: 40px; + line-height: 40px; + padding: 0 20px; + background-color: #f8f8f8; + div { + display: inline-block; + } + .classId { + margin-left: 6px; + font-size: 12px; + color: #999; + } + .copyIdBtn { + float: right; + height: 20px; + line-height: 20px; + margin-top: 10px; + font-size: 12px; + background-color: #fff; + color: #3b93fe; + padding: 0 6px; + border-radius: 50px; + overflow: hidden; + cursor: pointer; + } + } + .itemInfo { + height: 128px; + padding: 20px; + flex: 1; + display: flex; + cursor: pointer; + .infoBox { + flex: 1; + font-size: 12px; + p { + margin-bottom: 10px; + } + } + } + } + } +} + +.courseList { + overflow: hidden; + margin-bottom: 20px; + + .courseItem { + float: left; + width: 100px; + margin: 10px; + position: relative; + + .checkBox { + position: absolute; + right: 0; + top: 0; + height: 14px; + + ::v-deep { + .el-checkbox__inner { + border-color: #888; + } + } + } + + .imgBox { + width: 100px; + height: 110px; + margin-bottom: 10px; + } + + p { + line-height: 1.2; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; + } + } +} + +.pagination-box { + padding: 10px 0; + display: flex; + justify-content: center; +} + +.nullBox { + text-align: center; + margin-top: 30px; + font-size: 20px; + color: #ccc; +} +</style> -- Gitblit v1.9.1