轮播图和文章
This commit is contained in:
		| @@ -2,11 +2,8 @@ ENV = 'development' | ||||
| VITE_CLI_PORT = 8088 | ||||
| VITE_SERVER_PORT = 8888 | ||||
| VITE_BASE_API = /api | ||||
| VITE_BASE_PATH = http://192.168.1.147 | ||||
| //VITE_BASE_PATH = http://122.9.143.61 | ||||
| //VITE_BASE_PATH = http://192.168.1.40 | ||||
| VITE_BASE_PATH = http://36b924d2.r12.cpolar.top  | ||||
| VITE_EDITOR = vscode | ||||
| // VITE_EDITOR = webstorm 如果使用webstorm开发且要使用dom定位到代码行功能 请先自定添加 webstorm到环境变量 再将VITE_EDITOR值修改为webstorm | ||||
| // 如果使用docker-compose开发模式,设置为下面的地址或本机主机IP | ||||
| //VITE_BASE_PATH = http://177.7.0.12 | ||||
|  | ||||
|   | ||||
| @@ -4,5 +4,5 @@ VITE_CLI_PORT = 8080 | ||||
| VITE_SERVER_PORT = 8888 | ||||
| VITE_BASE_API = /api | ||||
| #下方修改为你的线上ip | ||||
| VITE_BASE_PATH = https://admin.api.gwkjxb.com | ||||
| //VITE_BASE_PATH = http://test_admin_api.gwkjxb.com | ||||
| VITE_BASE_PATH = http://36b924d2.r12.cpolar.top  | ||||
| //VITE_BASE_PATH = http://36b924d2.r12.cpolar.top  | ||||
|   | ||||
							
								
								
									
										32265
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										32265
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										19
									
								
								src/api/article.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/api/article.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| import service from '@/utils/request' | ||||
| const api = { | ||||
|   // 文章api | ||||
|   getArticleList: data => { | ||||
|     return service({ | ||||
|       url: '/article/list', | ||||
|       method: 'get', | ||||
|       params: data | ||||
|     }) | ||||
|   }, | ||||
|   addArticle: data => { | ||||
|     return service({ | ||||
|       url: '/article', | ||||
|       method: 'post', | ||||
|       data | ||||
|     }) | ||||
|   } | ||||
| } | ||||
| export default api | ||||
| @@ -1,30 +1,30 @@ | ||||
| import service from '@/utils/request' | ||||
| const api = { | ||||
|   // 轮播图api | ||||
|   getLbtManageList : data => { | ||||
|   getLbtManageList: data => { | ||||
|     return service({ | ||||
|       url: '/sys-index-lbt', | ||||
|       url: '/banner/list', | ||||
|       method: 'get', | ||||
|       params:data | ||||
|       params: data | ||||
|     }) | ||||
|   }, | ||||
|   addLbtManage : data => { | ||||
|   addLbtManage: data => { | ||||
|     return service({ | ||||
|       url: '/sys-index-lbt', | ||||
|       url: '/banner', | ||||
|       method: 'post', | ||||
|       data | ||||
|     }) | ||||
|   }, | ||||
|   editLbtManage : data => { | ||||
|   editLbtManage: data => { | ||||
|     return service({ | ||||
|       url: '/sys-index-lbt/'+data.banner_id, | ||||
|       url: '/banner', | ||||
|       method: 'put', | ||||
|       data | ||||
|     }) | ||||
|   }, | ||||
|   delLbt: data => { | ||||
|     return service({ | ||||
|       url: '/sys-index-lbt', | ||||
|       url: '/banner', | ||||
|       method: 'delete', | ||||
|       data | ||||
|     }) | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
|  */ | ||||
|  | ||||
| const config = { | ||||
|     appName: '嚯奖学吧', | ||||
|     appName: '积明', | ||||
|     appLogo: 'src/assets/logo.png', | ||||
|     showViteLogo: true | ||||
| } | ||||
|   | ||||
							
								
								
									
										429
									
								
								src/view/article/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										429
									
								
								src/view/article/index.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,429 @@ | ||||
|  | ||||
| <script setup> | ||||
| // 引入依赖 | ||||
| import api from '@/api/article' | ||||
| import capi from '@/api/course' | ||||
| import custom from '@/utils/custom' | ||||
| import { formatDate } from '@/utils/format' | ||||
| import _ from 'lodash' | ||||
| // import { toSQLLine } from '@/utils/stringFun' | ||||
| import WarningBar from '@/components/warningBar/warningBar.vue' | ||||
| import ckEditor from '@/components/richText/ckEditor5.vue' | ||||
| import { ref, onMounted } from 'vue' | ||||
| import { ElMessage, ElMessageBox } from 'element-plus' | ||||
| import { useRouter, useRoute } from 'vue-router' | ||||
| const router = useRouter() | ||||
| const route = useRoute() | ||||
| const path = ref(import.meta.env.VITE_BASE_API) | ||||
| import { useUserStore } from '@/pinia/modules/user' | ||||
| const userStore = useUserStore() | ||||
| // 变量 | ||||
| const typeList = custom.getExercisesTypeList() | ||||
| const queryParams = ref({ | ||||
|   page: 1, | ||||
|   pageSize: 10, | ||||
|   // name: '', | ||||
|   // type: '', | ||||
|   // subject: '' | ||||
| }) | ||||
| const subjectParams = ref({ | ||||
|   page: 1, | ||||
|   pageSize: 100, | ||||
| }) | ||||
| const tableData = ref([]) | ||||
| const subjectList = ref([]) | ||||
| const deleteVisible = ref(false) | ||||
| const question_ids = ref([]) | ||||
| const total = ref(0) | ||||
| const dialogFormVisible = ref(false) | ||||
| const dialogTitle = ref('') | ||||
| const form = ref({}) | ||||
| const rules = ref({ | ||||
|   name: [{ required: true, message: '请输入课程名称', trigger: 'blur' }] | ||||
| }) | ||||
| const question_id = ref(0) | ||||
| const content = ref(null) | ||||
| const options = ref([]) // 答案选项数组 | ||||
| const question_form = ref({ | ||||
|   options: [], | ||||
|   answer: '', | ||||
|   title: '' | ||||
| }) | ||||
| // 生命周期 | ||||
| onMounted(() => { | ||||
|   getArticleList() | ||||
|   // getSubject() | ||||
| }) | ||||
| // 方法 | ||||
| async function getArticleList() { | ||||
|   const res = await api.getArticleList(queryParams.value) | ||||
|   if (res.code === 0) { | ||||
|     tableData.value = res.data.list | ||||
|     console.log(tableData.value) | ||||
|     total.value = res.data.total | ||||
|   } | ||||
| } | ||||
| // async function getSubject() { // 获取课程分类 | ||||
| //     const res = await capi.getSubjectList(subjectParams.value) | ||||
| //     if (res.code === 0) { | ||||
| //         subjectList.value = custom.getStdSubject(res.data.records) | ||||
| //     } | ||||
| // } | ||||
| function onSubmit() { | ||||
|   getArticleList() | ||||
| } | ||||
| const onReset = () => { | ||||
|   queryParams.value = { | ||||
|     page: 1, | ||||
|     pageSize: 10, | ||||
|     name: '', | ||||
|     // status: '', | ||||
|     // subject: '' | ||||
|   } | ||||
| } | ||||
| function openDialog(type) { | ||||
|   // let params = {} | ||||
|   switch (type) { | ||||
|     case 'add': | ||||
|       dialogTitle.value = '新增习题' | ||||
|       form.value = {} | ||||
|       break | ||||
|     case 'edit': | ||||
|       // params.question_id = question_id.value | ||||
|       dialogTitle.value = '编辑习题' | ||||
|       break | ||||
|   } | ||||
|   dialogFormVisible.value = true | ||||
|   // router.push({name:'addCourse',params}) | ||||
| } | ||||
| async function onDelete() { | ||||
|   const ids = question_ids.value.map(item => item.question_id) | ||||
|   const res = await api.delExercises({ question_ids: ids }) | ||||
|   if (res.code === 0) { | ||||
|     ElMessage({ | ||||
|       type: 'success', | ||||
|       message: res.msg | ||||
|     }) | ||||
|     // if (tableData.value.length === ids.length && page.value > 1) { | ||||
|     //   page.value-- | ||||
|     // } | ||||
|     deleteVisible.value = false | ||||
|     getArticleList() | ||||
|   } | ||||
| } | ||||
| const handleSelectionChange = (val) => { | ||||
|   question_ids.value = val | ||||
| } | ||||
| function editCourseFunc(row) { | ||||
|   form.value = _.cloneDeep(row) | ||||
|   question_id.value = form.value.question_id | ||||
|   content.value = JSON.parse(form.value.question).title | ||||
|   question_form.value = JSON.parse(form.value.question) | ||||
|   if (!question_form.value.options) { | ||||
|     question_form.value.options = [] | ||||
|   } | ||||
|   openDialog('edit') | ||||
| } | ||||
| function deleteCourseFunc(row) { | ||||
|   ElMessageBox.confirm('此操作将永久删除该数据, 是否继续?', '提示', { | ||||
|     confirmButtonText: '确定', | ||||
|     cancelButtonText: '取消', | ||||
|     type: 'warning' | ||||
|   }) | ||||
|     .then(async() => { | ||||
|       const res = await api.delExercises({ | ||||
|         question_ids: [row.question_id] | ||||
|       }) | ||||
|       if (res.code === 0) { | ||||
|         ElMessage({ | ||||
|           type: 'success', | ||||
|           message: '删除成功!' | ||||
|         }) | ||||
|         getArticleList() | ||||
|       } | ||||
|     }, () => { | ||||
|     }) | ||||
| } | ||||
| function handleCurrentChange(val) { | ||||
|   queryParams.value.page = val | ||||
|   getArticleList() | ||||
| } | ||||
| function handleSizeChange(val) { | ||||
|   queryParams.value.pageSize = val | ||||
|   getArticleList() | ||||
| } | ||||
| function closeDialog() { | ||||
|   dialogFormVisible.value = false | ||||
|   question_form.value = { | ||||
|     options: [], | ||||
|     answer: '', | ||||
|     title: '' | ||||
|   } | ||||
|   form.value = {} | ||||
| } | ||||
| async function enterDialog() { // 提交 | ||||
| //   form.value.score = parseInt(form.value.score) | ||||
| //   form.value.teacher_id = 0 | ||||
| //   form.value.question = JSON.stringify(question_form.value) | ||||
|   let func_name = 'addArticle' | ||||
|   if (form.value.question_id) { // 编辑 | ||||
|     func_name = 'editExercises' | ||||
|   } | ||||
|   const res = await api[func_name](form.value) | ||||
|   if (res.code === 0) { | ||||
|     ElMessage({ | ||||
|       type: 'success', | ||||
|       message: res.msg | ||||
|     }) | ||||
|     // if (tableData.value.length === ids.length && page.value > 1) { | ||||
|     //   page.value-- | ||||
|     // } | ||||
|     // deleteVisible.value = false | ||||
|     closeDialog() | ||||
|     getArticleList() | ||||
|   } | ||||
| } | ||||
| function viewCourseFunc(row) { // 查看课程 | ||||
|   router.push({ name: 'viewCourse', params: { question_id: row.question_id }}) | ||||
| } | ||||
| function getExercisesName(row) { | ||||
|   return JSON.parse(row.question).title | ||||
| } | ||||
| const std_options_title = ref(['A', 'B', 'C', 'D', 'E', 'F']) | ||||
| function addOptionFunc() { | ||||
|   // for(let i=0 ;i<std_options_title.value.length;i++) { | ||||
|   //     if(!options.value.has(std_options_title.value[i])) { | ||||
|   //       options.value.set(std_options_title.value[i],'') | ||||
|   //       break; | ||||
|   //     } | ||||
|   // } | ||||
|  | ||||
|   for (let i = 0; i < std_options_title.value.length; i++) { | ||||
|     let has_flag = false | ||||
|     for (const item of question_form.value.options) { | ||||
|       if (item.name === std_options_title.value[i]) { | ||||
|         has_flag = true | ||||
|       } | ||||
|     } | ||||
|     if (!has_flag) { | ||||
|       const data = { | ||||
|         name: std_options_title.value[i], | ||||
|         value: '' | ||||
|       } | ||||
|       question_form.value.options.push(data) | ||||
|       break | ||||
|     } | ||||
|   } | ||||
| } | ||||
| function delet_func(item) { | ||||
|   question_form.value.options.pop() | ||||
| } | ||||
| function handleAvatarSuccess(res) { | ||||
|   console.log(res) | ||||
|   form.value.cover_img = res.data.file.url | ||||
| } | ||||
| function beforeAvatarUpload(file) { | ||||
|   const isLt05M = file.size / 1024 / 1024 < 20 | ||||
|   const isJPG = file.type.indexOf('image/') === -1 | ||||
|   if (isJPG) { | ||||
|     ElMessage.error('文件格式错误,请上传图片类型,如:JPG,PNG后缀的文件') | ||||
|   } | ||||
|   if (!isLt05M) { | ||||
|     ElMessage.error('上传头像图片大小不能超过 2M!') | ||||
|   } | ||||
|   return !isJPG && isLt05M | ||||
| } | ||||
| </script> | ||||
| <template> | ||||
|   <div> | ||||
|     <!--    搜索框--> | ||||
|     <div class="gva-search-box"> | ||||
|       <el-form ref="searchForm" :inline="true" :model="queryParams"> | ||||
|         <el-form-item label="文章名称"> | ||||
|           <el-input v-model="queryParams.name" placeholder="根据文章名称进行查询" /> | ||||
|         </el-form-item> | ||||
|         <!-- <el-form-item label="课程分类"> | ||||
|           <el-select v-model="queryParams.subject" clearable placeholder="请选择"> | ||||
|             <el-option v-for="item in subjectList" :key="item.id" :label="item.name" :value="item.name" /> | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="题型"> | ||||
|           <el-select v-model="queryParams.type" clearable placeholder="请选择"> | ||||
|             <el-option v-for="item in typeList" :key="item.value" :label="item.label" :value="item.value" /> | ||||
|           </el-select> | ||||
|         </el-form-item> --> | ||||
|         <el-form-item> | ||||
|           <el-button size="small" type="primary" icon="search" @click="onSubmit">查询</el-button> | ||||
|           <el-button size="small" icon="refresh" @click="onReset">重置</el-button> | ||||
|         </el-form-item> | ||||
|       </el-form> | ||||
|     </div> | ||||
|     <!--    表格数据--> | ||||
|     <div class="gva-table-box"> | ||||
|       <!--      批量操作--> | ||||
|       <div class="gva-btn-list"> | ||||
|         <el-button size="small" type="primary" icon="plus" @click="openDialog('add')">新增</el-button> | ||||
|         <el-popover v-model="deleteVisible" placement="top" width="160"> | ||||
|           <p>确定要删除吗?</p> | ||||
|           <div style="text-align: right; margin-top: 8px;"> | ||||
|             <el-button size="small" type="primary" link @click="deleteVisible = false">取消</el-button> | ||||
|             <el-button size="small" type="primary" @click="onDelete">确定</el-button> | ||||
|           </div> | ||||
|           <template #reference> | ||||
|             <el-button | ||||
|               icon="delete" | ||||
|               size="small" | ||||
|               type="danger" | ||||
|               :disabled="!question_ids.length" | ||||
|               style="margin-left: 10px;" | ||||
|               @click="deleteVisible = true" | ||||
|             >删除</el-button> | ||||
|           </template> | ||||
|         </el-popover> | ||||
|       </div> | ||||
|       <!--   数据列表--> | ||||
|       <el-table :data="tableData" @selection-change="handleSelectionChange"> | ||||
|         <el-table-column type="selection" width="55" /> | ||||
|         <el-table-column align="left" label="ID" min-width="60" prop="question_id" sortable="custom" /> | ||||
|         <el-table-column align="left" label="题型" min-width="150" prop="name"> | ||||
|           <template #default="scope"> | ||||
|             {{ custom.getExercisesTypeName(scope.row.type) }} | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column align="left" label="科目" min-width="150" prop="subject" /> | ||||
|         <el-table-column align="left" label="题目" min-width="150"> | ||||
|           <template #default="scope"> | ||||
|             <!--            {{getExercisesName(scope.row)}}--> | ||||
|             <!-- <div v-html="getExercisesName(scope.row)" /> --> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column align="left" label="分值" prop="score" /> | ||||
|         <!-- <el-table-column align="left" label="创建者" min-width="150" prop="teacher_id" /> --> | ||||
|         <el-table-column align="left" label="创建时间" min-width="150"> | ||||
|           <template #default="scope"> | ||||
|             {{ formatDate(scope.row.CreatedAt) }} | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column align="left" fixed="right" label="操作" width="200"> | ||||
|           <template #default="scope"> | ||||
|             <el-button | ||||
|               icon="edit" | ||||
|               size="small" | ||||
|               type="primary" | ||||
|               link | ||||
|               @click="editCourseFunc(scope.row)" | ||||
|             >编辑</el-button> | ||||
|             <el-button | ||||
|               icon="delete" | ||||
|               size="small" | ||||
|               type="danger" | ||||
|               link | ||||
|               @click="deleteCourseFunc(scope.row)" | ||||
|             >删除</el-button> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|       </el-table> | ||||
|       <div class="gva-pagination"> | ||||
|         <el-pagination | ||||
|           :current-page="queryParams.page" | ||||
|           :page-size="queryParams.pageSize" | ||||
|           :page-sizes="[10, 30, 50, 100]" | ||||
|           :total="total" | ||||
|           layout="total, sizes, prev, pager, next, jumper" | ||||
|           @current-change="handleCurrentChange" | ||||
|           @size-change="handleSizeChange" | ||||
|         /> | ||||
|       </div> | ||||
|  | ||||
|     </div> | ||||
|     <el-dialog v-model="dialogFormVisible" :before-close="closeDialog" :title="dialogTitle"> | ||||
|       <el-form ref="apiForm" :model="form" :rules="rules" label-width="80px"> | ||||
|         <el-form-item label="标题" prop="title"> | ||||
|           <!-- <el-select v-model="form.subject" clearable placeholder="请选择"> | ||||
|             <el-option v-for="item in subjectList" :key="item.id" :label="item.name" :value="item.name" /> | ||||
|           </el-select> --> | ||||
|           <el-input v-model="form.title" /> | ||||
|         </el-form-item> | ||||
|         <!-- <el-form-item label="科目" prop="subject"> | ||||
|           <el-select v-model="form.subject" clearable placeholder="请选择"> | ||||
|             <el-option v-for="item in subjectList" :key="item.id" :label="item.name" :value="item.name" /> | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="题型" prop="type"> | ||||
|           <el-select v-model="form.type" clearable placeholder="请选择"> | ||||
|             <el-option v-for="item in typeList" :key="item.value" :label="item.label" :value="item.value" /> | ||||
|           </el-select> | ||||
|         </el-form-item> --> | ||||
|         <el-form-item label="封面" prop="cover_img"> | ||||
|           <el-upload | ||||
|             class="avatar-uploader" | ||||
|             :action="`${path}/fileUploadAndDownload/upload`" | ||||
|             :headers="{ 'x-token': userStore.token }" | ||||
|             :show-file-list="false" | ||||
|             :on-success="handleAvatarSuccess" | ||||
|             :before-upload="beforeAvatarUpload" | ||||
|           > | ||||
|             <img v-if="form.cover_img" :src="form.cover_img" class="img-container"> | ||||
|             <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon> | ||||
|           </el-upload> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="文章内容"> | ||||
|           <ckEditor v-model="form.content" style="width:100%" :content="form.content" /> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="阅读量" prop="reading_num"> | ||||
|           <el-input v-model.number="form.reading_num" /> | ||||
|         </el-form-item> | ||||
|         <!-- <el-form-item label="分值"> | ||||
|           <el-input v-model="form.score" type="number" placeholder="请输入分值" /> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="答案"> | ||||
|           <view class="options-box"> | ||||
|             <view v-for="(item, i) in question_form.options" v-if="question_form" class="option-item"> | ||||
|               <view>{{ item.name }}</view> | ||||
|               <ckEditor v-model="item.value" :content="item.value" style="margin-left:5px;width:100%" /> | ||||
|               <el-icon | ||||
|                 v-if="(i + 1) == question_form.options.length" | ||||
|                 style="margin-left: 5px;cursor: pointer" | ||||
|                 @click="delet_func(item)" | ||||
|               > | ||||
|                 <Delete /> | ||||
|               </el-icon> | ||||
|             </view> | ||||
|             <el-button @click="addOptionFunc">添加答案</el-button> | ||||
|           </view> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="正确答案"> | ||||
|           <el-input v-model="question_form.answer" placeholder="请输入正确答案(如,选择题:A或A-B;填空题直接填值)" /> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="题目解析"> | ||||
|           <ckEditor v-model="form.resolve" style="width:100%" :content="form.resolve" /> | ||||
|         </el-form-item> --> | ||||
|       </el-form> | ||||
|       <template #footer> | ||||
|         <div class="dialog-footer"> | ||||
|           <el-button size="small" @click="closeDialog">取 消</el-button> | ||||
|           <el-button size="small" type="primary" @click="enterDialog">确 定</el-button> | ||||
|         </div> | ||||
|       </template> | ||||
|     </el-dialog> | ||||
|   </div> | ||||
| </template> | ||||
| <style scoped lang="scss"> | ||||
| .option-item { | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     margin-bottom: 10px; | ||||
| } | ||||
|  | ||||
| .button-box { | ||||
|     padding: 10px 20px; | ||||
|  | ||||
|     .el-button { | ||||
|         float: right; | ||||
|     } | ||||
| } | ||||
|  | ||||
| .warning { | ||||
|     color: #dc143c; | ||||
| } | ||||
| </style> | ||||
| @@ -5,7 +5,7 @@ import api from '@/api/course' | ||||
| import com_api from '@/api/common' | ||||
| import custom from '@/utils/custom' | ||||
| // import WarningBar from '@/components/warningBar/warningBar.vue' | ||||
| import {ref,onMounted,provide  } from 'vue' | ||||
| import {ref, onMounted, provide  } from 'vue' | ||||
| import { ElMessage, ElMessageBox } from 'element-plus' | ||||
| import { useRouter, useRoute } from 'vue-router' | ||||
| const router = useRouter() | ||||
| @@ -17,7 +17,7 @@ import chapterCom from '../components/chapter.vue' | ||||
| const path = ref(import.meta.env.VITE_BASE_API) | ||||
| const course_id = ref(0) | ||||
| const active = ref(0) | ||||
| const form = ref({status:1,is_boutique:-1,is_audition:-1}) | ||||
| const form = ref({status:1, is_boutique:-1, is_audition:-1}) | ||||
| const subjectParams = ref({ | ||||
|     page:1, | ||||
|     pageSize:100, | ||||
| @@ -36,7 +36,7 @@ const isChange = ref(false) | ||||
| // 生命周期 | ||||
| onMounted(() => { | ||||
|   course_id.value = route.params.course_id || 0 | ||||
|   if(course_id.value) { | ||||
|   if (course_id.value) { | ||||
|     getCourseInfo() | ||||
|   } | ||||
|   getSubject() | ||||
| @@ -46,7 +46,7 @@ provide('current_subject', current_subject) | ||||
| // 方法 | ||||
| async function getCourseInfo() { // 获取课程信息 | ||||
|   const res = await api.getCourse({id:course_id.value}) | ||||
|   if(res.code === 0) { | ||||
|   if (res.code === 0) { | ||||
|     chapter_info.value = res.data.course_ware_json | ||||
|     res.data.course.price /=100 | ||||
|     form.value = res.data.course | ||||
| @@ -58,16 +58,14 @@ function stepChangeFunc(type) { | ||||
|       active.value -=1 | ||||
|       break; | ||||
|     case 2: // 下一步 | ||||
|         if(active.value == 0) { // 保存第一步的信息 | ||||
|         if (active.value == 0) { // 保存第一步的信息 | ||||
|           // console.log(isChange.value) | ||||
|           if(isChange.value){ | ||||
|           if (isChange.value){ | ||||
|             submitForm(ruleFormRef.value) | ||||
|           } | ||||
|           else{ | ||||
|           } else { | ||||
|             active.value += 1 | ||||
|           } | ||||
|         } | ||||
|         else{ | ||||
|         } else { | ||||
|           active.value +=1 | ||||
|         } | ||||
|       break; | ||||
| @@ -90,7 +88,7 @@ async function saveStep1() { | ||||
|   //   })[0].id | ||||
|   form.value.subject = custom.get_course_category_name(form.value.course_category_id) | ||||
|   form.value.price = parseFloat(form.value.price)<0?0:form.value.price | ||||
|   if(!checkFreeTestFromPrice()) { | ||||
|   if (!checkFreeTestFromPrice()) { | ||||
|     ElMessage({ | ||||
|       type: 'warning', | ||||
|       message: '赠送价格不能超过课程价格!' | ||||
| @@ -103,15 +101,14 @@ async function saveStep1() { | ||||
|   } | ||||
|   params.step1.price = parseInt(parseFloat(params.step1.price)*100) | ||||
|   let func_name ='' | ||||
|   if(course_id.value) { // 编辑 | ||||
|   if (course_id.value) { // 编辑 | ||||
|     params.course_id = parseInt(course_id.value) | ||||
|     func_name = 'editCourse' | ||||
|   } | ||||
|   else{ // 新增 | ||||
|   } else { // 新增 | ||||
|     func_name = 'addCourse' | ||||
|   } | ||||
|   const res = await api[func_name](params) | ||||
|   if(res.code === 0) { | ||||
|   if (res.code === 0) { | ||||
|     active.value += 1 | ||||
|     course_id.value = res.data | ||||
|     current_subject.value = form.value.subject | ||||
| @@ -121,17 +118,17 @@ async function saveStep1() { | ||||
|     }) | ||||
|   } | ||||
| } | ||||
| async function getSubject(){ // 获取课程分类 | ||||
| async function getSubject() { // 获取课程分类 | ||||
|   const res = await api.getSubjectList(subjectParams.value) | ||||
|   if(res.code === 0) { | ||||
|   if (res.code === 0) { | ||||
|     // subjectList.value = custom.getStdSubject(res.data.records) | ||||
|     // subjectList.value = custom.addTreeFormatSubject(res.data.records,'id') | ||||
|     subjectList_inject.value = custom.addTreeFormatSubject(_.cloneDeep(res.data.records),'name') | ||||
|     subjectList.value = custom.addTreeFormatSubject( _.cloneDeep(res.data.records),'id') | ||||
|     subjectList_inject.value = custom.addTreeFormatSubject(_.cloneDeep(res.data.records), 'name') | ||||
|     subjectList.value = custom.addTreeFormatSubject(_.cloneDeep(res.data.records), 'id') | ||||
|     // | ||||
|   } | ||||
| } | ||||
| async function uploadAction(file){//图片上传 非oss | ||||
| async function uploadAction(file) { //图片上传 非oss | ||||
| 		    file.status = 'uploading'; | ||||
|         file.message = '上传中...'; | ||||
|         //开始上传 | ||||
| @@ -140,13 +137,12 @@ async function uploadAction(file){//图片上传 非oss | ||||
|         content.append("file", file.file); | ||||
|         content.append("type", '1'); | ||||
|         const res=await com_api.upload(content); | ||||
|         if(res.code==200){ | ||||
|         if (res.code==200) { | ||||
|           file.status = 'done'; | ||||
|           file.message = '上传成功'; | ||||
|           file.url = res.data.full_path; | ||||
|           this.courseForm.cover = file.url | ||||
|         } | ||||
|         else{ | ||||
|         } else { | ||||
|           file.status = 'failed'; | ||||
|           file.message = '上传失败'; | ||||
|         } | ||||
| @@ -191,7 +187,7 @@ function handlerChange(e) { | ||||
|   isChange.value = true | ||||
| } | ||||
| function freeTestFunc() { // 免费试卷数量 | ||||
|   if(!checkFreeTestFromPrice()) { | ||||
|   if (!checkFreeTestFromPrice()) { | ||||
|     ElMessage({ | ||||
|       type: 'warning', | ||||
|       message: '赠送价格不能超过课程价格!' | ||||
| @@ -202,8 +198,8 @@ function freeTestFunc() { // 免费试卷数量 | ||||
| const STD_TEST_PRICE = 4.9 | ||||
| function checkFreeTestFromPrice() { // 检查免费试卷分数是否合理 | ||||
|   let flag = true | ||||
|   if(form.value.free_test && form.value.price) { | ||||
|     if(parseInt(form.value.free_test) * STD_TEST_PRICE > parseFloat(form.value.price)) { | ||||
|   if (form.value.free_test && form.value.price) { | ||||
|     if (parseInt(form.value.free_test) * STD_TEST_PRICE > parseFloat(form.value.price)) { | ||||
|       flag = false | ||||
|     } | ||||
|   } | ||||
| @@ -214,10 +210,9 @@ const verifyVisible = ref(false) | ||||
| const verifyForm = ref({}) | ||||
| function checkCourseFunc() { // 审核 | ||||
|   // console.log(form.value) | ||||
|   if(form.value.status === 2 || form.value.status === 4 ) { // 未审核 或 未通过 | ||||
|   if (form.value.status === 2 || form.value.status === 4) { // 未审核 或 未通过 | ||||
|     verifyForm.value.is_pass = -1 | ||||
|   } | ||||
|   else{ | ||||
|   } else { | ||||
|     verifyForm.value.is_pass = 1 | ||||
|   } | ||||
|   verifyForm.is_pass = form.value.status | ||||
| @@ -225,11 +220,10 @@ function checkCourseFunc() { // 审核 | ||||
| } | ||||
| function transferStateFromVerify(v_state) { | ||||
|   let state = 0 | ||||
|   if(v_state === 1) { // 审核通过 | ||||
|   if (v_state === 1) { // 审核通过 | ||||
|     // state = form.value.status | ||||
|     state = 3 | ||||
|   } | ||||
|   else{ // 审核拒绝 | ||||
|   } else { // 审核拒绝 | ||||
|     state = 4 | ||||
|   } | ||||
|   return state | ||||
| @@ -244,7 +238,7 @@ async function enterVerifyDialog() { // 审核提交 | ||||
|     course_id:parseInt(course_id.value), | ||||
|     status | ||||
|   }) | ||||
|   if(res.code === 0) { | ||||
|   if (res.code === 0) { | ||||
|     ElMessage({ | ||||
|         type: 'success', | ||||
|         message: '操作成功!' | ||||
| @@ -253,8 +247,7 @@ async function enterVerifyDialog() { // 审核提交 | ||||
|     // getCourseList() | ||||
|     verifyVisible.value = false | ||||
|     getCourseInfo() | ||||
|   } | ||||
|   else{ | ||||
|   } else { | ||||
|     ElMessage({ | ||||
|       type: 'warning', | ||||
|       message: res.msg | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| import api from '@/api/lbt' | ||||
| // import { toSQLLine } from '@/utils/stringFun' | ||||
| import WarningBar from '@/components/warningBar/warningBar.vue' | ||||
| import {ref,onMounted } from 'vue' | ||||
| import { ref, onMounted } from 'vue' | ||||
| import { ElMessage, ElMessageBox } from 'element-plus' | ||||
| import { useRouter, useRoute } from 'vue-router' | ||||
| const router = useRouter() | ||||
| @@ -11,28 +11,28 @@ const route = useRoute() | ||||
| const dialogFormVisible = ref(false) | ||||
| import { useUserStore } from '@/pinia/modules/user' | ||||
| const userStore = useUserStore() | ||||
| import {parseTime} from '@/utils' | ||||
| import { parseTime } from '@/utils' | ||||
| // 变量 | ||||
| const path = ref(import.meta.env.VITE_BASE_API) | ||||
| const queryParams = ref({ | ||||
|   page:1, | ||||
|   pageSize:10 | ||||
|   page: 1, | ||||
|   pageSize: 10 | ||||
| }) | ||||
| const deleteVisible = ref(false) | ||||
| const lbt_ids = ref([]) | ||||
| const dialogTitle = ref('') | ||||
| const form = ref({status:'1'}) | ||||
| const form = ref({ status: '1' }) | ||||
| const lbtType_options = ref([ | ||||
|   { | ||||
|     label:'首页', | ||||
|     value:1 | ||||
|     label: '首页', | ||||
|     value: 1 | ||||
|   } | ||||
| ]) | ||||
| const rules = ref({ | ||||
|   lbtName: [{ required: true, message: '请输入名称', trigger: 'blur' }], | ||||
|   lbtUrl: [{ required: true, message: '请选择素材', trigger: 'blur' }], | ||||
|   lbtSkipUrl:[{ required: true, message: '请填写跳转链接', trigger: 'blur' }], | ||||
|   lbtType:[{ required: true, message: '请选择展示位置', trigger: 'blur' }] | ||||
|   // lbtName: [{ required: true, message: '请输入名称', trigger: 'blur' }], | ||||
|   imgUrl: [{ required: true, message: '请选择素材', trigger: 'blur' }], | ||||
|   link: [{ required: true, message: '请填写跳转链接', trigger: 'blur' }], | ||||
|   // lbtType: [{ required: true, message: '请选择展示位置', trigger: 'blur' }] | ||||
| }) | ||||
| const ruleFormRef = ref(null) | ||||
| const tableData = ref([]) | ||||
| @@ -44,8 +44,8 @@ onMounted(() => { | ||||
| // 方法 | ||||
| async function getLbtList() { | ||||
|   const res = await api.getLbtManageList(queryParams.value) | ||||
|   if(res.code === 0) { | ||||
|     tableData.value = res.data.records | ||||
|   if (res.code === 0) { | ||||
|     tableData.value = res.data.list | ||||
|     total.value = res.data.total | ||||
|   } | ||||
| } | ||||
| @@ -54,10 +54,10 @@ function openDialog(type) { | ||||
|   switch (type) { | ||||
|     case 'add': | ||||
|       dialogTitle.value = '新增轮播图' | ||||
|       break; | ||||
|       break | ||||
|     case 'edit': | ||||
|       dialogTitle.value = '编辑轮播图' | ||||
|       break; | ||||
|       break | ||||
|   } | ||||
| } | ||||
| async function onDelete() { | ||||
| @@ -77,11 +77,11 @@ async function onDelete() { | ||||
| } | ||||
| function closeDialog() { | ||||
|   dialogFormVisible.value = false | ||||
|   form.value = {status:'1'} | ||||
|   form.value = { status: '1' } | ||||
| } | ||||
| function handleAvatarSuccess(res) { | ||||
|   console.log(res) | ||||
|   form.value.lbtUrl = res.data.file.url | ||||
|   form.value.imgUrl = res.data.file.url | ||||
| } | ||||
| function beforeAvatarUpload(file) { | ||||
|   const isLt05M = file.size / 1024 / 1024 < 20 | ||||
| @@ -98,7 +98,7 @@ function enterDialog() { | ||||
|   console.log(form.value) | ||||
|   submitForm(ruleFormRef.value) | ||||
| } | ||||
| const submitForm = async (formEl) => { | ||||
| const submitForm = async(formEl) => { | ||||
|   if (!formEl) return | ||||
|   await formEl.validate((valid, fields) => { | ||||
|     if (valid) { | ||||
| @@ -110,23 +110,26 @@ const submitForm = async (formEl) => { | ||||
|   }) | ||||
| } | ||||
| async function saveForm() { | ||||
|   let func_name = '' | ||||
|   if(form.value.banner_id){ // 编辑 | ||||
|     func_name = 'editLbtManage' | ||||
|   form.value.status = parseInt(form.value.status) | ||||
|   form.value.linkType = parseInt(form.value.linkType) | ||||
|   form.value.lbtType = parseInt(form.value.lbtType) | ||||
|   const params = { // 新参数 | ||||
|     imgUrl: form.value.imgUrl, | ||||
|     link: form.value.link | ||||
|   } | ||||
|   else{ | ||||
|   let func_name = '' | ||||
|   if (form.value.ID) { // 编辑 | ||||
|     func_name = 'editLbtManage' | ||||
|     params.id = form.value.ID | ||||
|   } else { | ||||
|     func_name = 'addLbtManage' | ||||
|   } | ||||
|   form.value.status = parseInt(form.value.status) | ||||
|   form.value.lbtSkipUrlType = parseInt(form.value.lbtSkipUrlType) | ||||
|   form.value.lbtType = parseInt(form.value.lbtType) | ||||
|   const res = await api[func_name](form.value) | ||||
|   if(res.code === 0) | ||||
|   { | ||||
|       ElMessage({ | ||||
|         type: 'success', | ||||
|         message: '操作成功!' | ||||
|       }) | ||||
|   const res = await api[func_name](params) | ||||
|   if (res.code === 0) { | ||||
|     ElMessage({ | ||||
|       type: 'success', | ||||
|       message: '操作成功!' | ||||
|     }) | ||||
|     getLbtList() | ||||
|     closeDialog() | ||||
|   } | ||||
| @@ -144,23 +147,23 @@ function delLbtFunc(item) { | ||||
|     cancelButtonText: '取消', | ||||
|     type: 'warning' | ||||
|   }) | ||||
|   .then(async() => { | ||||
|     console.log(1) | ||||
|     const res = await api.delLbt({ | ||||
|           ids:[item.banner_id] | ||||
|     }) | ||||
|     if (res.code === 0) { | ||||
|       ElMessage({ | ||||
|         type: 'success', | ||||
|         message: '删除成功!' | ||||
|     .then(async() => { | ||||
|       const res = await api.delLbt({ | ||||
|         // ids: [item.ID] | ||||
|          id: item.ID | ||||
|       }) | ||||
|       // if (tableData.value.length === 1 && page.value > 1) { | ||||
|       //   page.value-- | ||||
|       // } | ||||
|       getLbtList() | ||||
|     } | ||||
|   },() => { | ||||
|   }) | ||||
|       if (res.code === 0) { | ||||
|         ElMessage({ | ||||
|           type: 'success', | ||||
|           message: '删除成功!' | ||||
|         }) | ||||
|         // if (tableData.value.length === 1 && page.value > 1) { | ||||
|         //   page.value-- | ||||
|         // } | ||||
|         getLbtList() | ||||
|       } | ||||
|     }, () => { | ||||
|     }) | ||||
| } | ||||
| function handleCurrentChange(val) { | ||||
|   queryParams.value.page = val | ||||
| @@ -183,32 +186,32 @@ function handleSizeChange(val) { | ||||
|             <el-button size="small" type="primary" link @click="deleteVisible = false">取消</el-button> | ||||
|             <el-button size="small" type="primary" @click="onDelete">确定</el-button> | ||||
|           </div> | ||||
|           <template #reference> | ||||
|           <!-- <template #reference> | ||||
|             <el-button icon="delete" size="small" type="danger" :disabled="!lbt_ids.length" style="margin-left: 10px;" @click="deleteVisible = true">删除</el-button> | ||||
|           </template> | ||||
|           </template> --> | ||||
|         </el-popover> | ||||
|       </div> | ||||
|       <!--      数据列表--> | ||||
|       <el-table border :data="tableData" @selection-change="handleSelectionChange"> | ||||
|         <el-table-column | ||||
|         <!-- <el-table-column | ||||
|           type="selection" | ||||
|           width="55" | ||||
|         /> | ||||
|         <el-table-column align="left" label="名称" min-width="150" prop="lbtName" /> | ||||
|         <el-table-column align="left" label="缩略图" min-width="150" prop="lbtUrl"> | ||||
|         /> --> | ||||
|         <!-- <el-table-column align="left" label="名称" min-width="150" prop="lbtName" /> --> | ||||
|         <el-table-column align="left" label="缩略图" min-width="150" prop="imgUrl"> | ||||
|           <template #default="scope"> | ||||
|             <img class="lbt-thumb" :src="scope.row.lbtUrl" alt=""> | ||||
|             <img class="lbt-thumb" :src="scope.row.imgUrl" alt=""> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column align="left" label="是否启用" min-width="150" prop="status" > | ||||
|         <el-table-column align="left" label="是否启用" min-width="150" prop="status"> | ||||
|           <template #default="scope"> | ||||
|             {{scope.row.status == '1'?'启用':'禁用'}} | ||||
|             {{ scope.row.status == '1'?'启用':'禁用' }} | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column align="left" label="说明" min-width="150" prop="lbtIntroduction" /> | ||||
|         <!-- <el-table-column align="left" label="说明" min-width="150" prop="lbtIntroduction" /> --> | ||||
|         <el-table-column align="left" label="更新时间" min-width="150" prop="UpdatedAt"> | ||||
|           <template #default="scope"> | ||||
|             {{parseTime(scope.row.UpdatedAt)}} | ||||
|             {{ parseTime(scope.row.UpdatedAt) }} | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column align="left" label="操作" min-width="150" prop="status"> | ||||
| @@ -245,10 +248,10 @@ function handleSizeChange(val) { | ||||
|     <!--新增、编辑 窗口--> | ||||
|     <el-dialog v-model="dialogFormVisible" :before-close="closeDialog" :title="dialogTitle"> | ||||
|       <el-form ref="ruleFormRef" :model="form" :rules="rules" label-width="80px"> | ||||
|         <el-form-item label="名称" prop="lbtName"> | ||||
|         <!-- <el-form-item label="名称" prop="lbtName"> | ||||
|           <el-input v-model="form.lbtName" placeholder="请输入名称" autocomplete="off" /> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="素材" prop="lbtUrl"> | ||||
|         </el-form-item> --> | ||||
|         <el-form-item label="素材" prop="imgUrl"> | ||||
|           <el-upload | ||||
|             class="avatar-uploader" | ||||
|             :action="`${path}/fileUploadAndDownload/upload`" | ||||
| @@ -257,23 +260,23 @@ function handleSizeChange(val) { | ||||
|             :on-success="handleAvatarSuccess" | ||||
|             :before-upload="beforeAvatarUpload" | ||||
|           > | ||||
|             <img v-if="form.lbtUrl" :src="form.lbtUrl" class="img-container" /> | ||||
|             <img v-if="form.imgUrl" :src="form.imgUrl" class="img-container"> | ||||
|             <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon> | ||||
|           </el-upload> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="说明" prop="lbtIntroduction"> | ||||
|         <!-- <el-form-item label="说明" prop="lbtIntroduction"> | ||||
|           <el-input v-model="form.lbtIntroduction" placeholder="说明" autocomplete="off" /> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="链接状态" prop="method"> | ||||
|           <el-switch v-model="form.lbtSkipUrlType" :active-value="1" :inactive-value="2" active-text="外链" inactive-text="内链" /> | ||||
|           <el-switch v-model="form.linkType" :active-value="1" :inactive-value="2" active-text="外链" inactive-text="内链" /> | ||||
|         </el-form-item> --> | ||||
|         <el-form-item label="链接地址" prop="link"> | ||||
|           <el-input v-model="form.link" placeholder="链接地址" autocomplete="off" /> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="链接地址" prop="lbtSkipUrl"> | ||||
|           <el-input v-model="form.lbtSkipUrl" placeholder="链接地址" autocomplete="off" /> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="启用状态" prop="status"> | ||||
|         <!-- <el-form-item label="启用状态" prop="status"> | ||||
|           <el-switch v-model="form.status" :active-value="1" :inactive-value="2" active-text="启用" inactive-text="禁用" /> | ||||
|         </el-form-item> | ||||
|         <el-form-item label="展示位置" prop="lbtType"> | ||||
|         </el-form-item> --> | ||||
|         <!-- <el-form-item label="展示位置" prop="lbtType"> | ||||
|           <el-select v-model="form.lbtType" class="m-2" placeholder="请选择"> | ||||
|             <el-option | ||||
|               v-for="item in lbtType_options" | ||||
| @@ -282,7 +285,7 @@ function handleSizeChange(val) { | ||||
|               :value="item.value" | ||||
|             /> | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
|         </el-form-item> --> | ||||
|         <el-form-item style="display: none"> | ||||
|           <el-button type="primary" @click="submitForm(ruleFormRef)"> | ||||
|             Create | ||||
|   | ||||
| @@ -60,12 +60,10 @@ export default ({ | ||||
|       port: process.env.VITE_CLI_PORT, | ||||
|       proxy: { | ||||
|         // | ||||
|  | ||||
|  | ||||
|  | ||||
|         // detail: https://cli.vuejs.org/config/#devserver-proxy | ||||
|         [process.env.VITE_BASE_API]: { // 需要代理的路径   例如 '/api' | ||||
|           target: `${process.env.VITE_BASE_PATH}:${process.env.VITE_SERVER_PORT}/`, // 代理到 目标路径 | ||||
|           // target: `${process.env.VITE_BASE_PATH}:${process.env.VITE_SERVER_PORT}/`, // 代理到 目标路径 | ||||
|           target: `${process.env.VITE_BASE_PATH}/`, // 代理到 目标路径 | ||||
|           changeOrigin: true, | ||||
|           rewrite: path => path.replace(new RegExp('^' + process.env.VITE_BASE_API), ''), | ||||
|         } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user