配置按钮权限
博主这里就不贴SQL了,自行手动添加一下吧。
更改表结构
ALTER TABLE `tienchin_course` MODIFY COLUMN `info` varchar(255) NULL DEFAULT NULL COMMENT '课程简介' AFTER `apply_to`;
后端
更改实体类数据类型
Course.java:
/** * 课程简介 */ private String info; // get set 略过
插入测试数据
INSERT INTO `TienChin`.`tienchin_course` (`course_id`, `type`, `name`, `price`, `apply_to`, `info`, `remark`, `create_by`, `update_by`, `create_time`, `update_time`, `del_flag`) VALUES (1, 1, '爵士舞', 2999, 1, '爵士舞入门', NULL, NULL, NULL, NULL, '2023-09-24 02:11:21', '0');
CourseController.java
/** * <p> * 前端控制器 * </p> * * @author BNTang * @since 2023-09-23 */ @RestController @RequestMapping("/tienchin/course") public class CourseController extends BaseController { @Resource private ICourseService iCourseService; @PreAuthorize("hasPermission('tienchin:course:list')") @GetMapping("/list") TableDataInfo list() { startPage(); return getDataTable(iCourseService.selectCourseList()); } }
ICourseService.java
/** * <p> * 服务类 * </p> * * @author BNTang * @since 2023-09-23 */ public interface ICourseService extends IService<Course> { /** * 查询课程列表 * * @return 课程列表 */ List<Course> selectCourseList(); }
CourseServiceImpl.java
/** * <p> * 服务实现类 * </p> * * @author BNTang * @since 2023-09-23 */ @Service public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService { @Resource private CourseMapper courseMapper; @Override public List<Course> selectCourseList() { return courseMapper.selectCourseList(); } }
CourseMapper.java
/** * <p> * Mapper 接口 * </p> * * @author BNTang * @since 2023-09-23 */ public interface CourseMapper extends BaseMapper<Course> { /** * 查询课程列表 * * @return 课程列表 */ List<Course> selectCourseList(); }
CourseMapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="top.it6666.course.mapper.CourseMapper"> <select id="selectCourseList" resultType="top.it6666.course.entity.Course"> SELECT * FROM tienchin_course WHERE del_flag = 0 </select> </mapper>
前端
course.js
import request from '@/utils/request' /** * 查询课程列表 * @param query 查询条件参数 * @returns {*} 查询结果 */ export function listCourse(query) { return request({ url: '/tienchin/course/list', method: 'get', params: query }) } /** * 查询渠道列表 * @returns {*} 查询结果 */ export function listChannel() { return request({ url: '/tienchin/activity/channel/list', method: 'get' }) } /** * 查询课程详细 * @param activityId 课程ID * @returns {*} 查询结果 */ export function getInfo(activityId) { return request({ url: '/tienchin/activity/' + activityId, method: 'get' }) } // 查询课程详细 export function getCourse(activityId) { return request({ url: '/tienchin/activity/' + activityId, method: 'get' }) } // 新增课程 export function addCourse(data) { return request({ url: '/tienchin/activity', method: 'post', data: data }) } // 修改课程 export function updateCourse(data) { return request({ url: '/tienchin/activity', method: 'put', data: data }) } // 删除课程 export function delCourse(activityIds) { return request({ url: '/tienchin/activity/' + activityIds, method: 'delete' }) }
index.vue
<template> <div class="app-container"> <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px"> <el-form-item label="课程名称" prop="courseName"> <el-input v-model="queryParams.courseName" placeholder="请输入课程名称" clearable @keyup.enter="handleQuery" /> </el-form-item> <el-form-item label="渠道名称" prop="channelId"> <el-select v-model="queryParams.channelId" placeholder="请选择渠道名称" clearable > <el-option v-for="channel in channelList" :key="channel.channelId" :label="channel.channelName" :value="channel.channelId" /> </el-select> </el-form-item> <el-form-item label="课程状态" prop="courseStatus"> <el-select v-model="queryParams.courseStatus" placeholder="请选择课程状态" clearable > <el-option v-for="dict in course_status" :key="dict.value" :label="dict.label" :value="dict.value" /> </el-select> </el-form-item> <el-form-item label="课程类型" prop="courseType"> <el-select v-model="queryParams.courseType" placeholder="请选择课程类型" clearable > <el-option v-for="dict in course_type" :key="dict.value" :label="dict.label" :value="dict.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> <el-row :gutter="10" class="mb8"> <el-col :span="1.5"> <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['tienchin:course:create']" >新增 </el-button> </el-col> <el-col :span="1.5"> <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['tienchin:course:edit']" >修改 </el-button> </el-col> <el-col :span="1.5"> <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['tienchin:course:remove']" >删除 </el-button> </el-col> <el-col :span="1.5"> <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['tienchin:course:export']" >导出 </el-button> </el-col> <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> </el-row> <el-table v-loading="loading" :data="courseList" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="55" align="center"/> <el-table-column label="课程编号" align="center" prop="courseId" :show-overflow-tooltip="true"/> <el-table-column label="课程类型" align="center"> <template #default="scope"> <dict-tag :options="course_type" :value="scope.row.type"/> </template> </el-table-column> <el-table-column label="课程名称" align="center" :show-overflow-tooltip="true" prop="name"/> <el-table-column label="课程价格" align="center" :show-overflow-tooltip="true" prop="price"/> <el-table-column label="课程适用人群" align="center" width="120"> <template #default="scope"> <dict-tag :options="course_apply_to" :value="scope.row.applyTo"/> </template> </el-table-column> <el-table-column label="课程简介" :show-overflow-tooltip="true" width="180" align="center" prop="info"/> <el-table-column label="课程备注" :show-overflow-tooltip="true" width="180" align="center" prop="remark"/> <el-table-column label="创建时间" align="center" prop="createTime"> <template #default="scope"> <span>{{ parseTime(scope.row.createTime) }}</span> </template> </el-table-column> <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="150"> <template #default="scope"> <el-button type="text" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['tienchin:course:edit']" >修改 </el-button> <el-button type="text" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['tienchin:course:remove']" >删除 </el-button> </template> </el-table-column> </el-table> <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> <!-- 添加或修改课程对话框 --> <el-dialog :title="title" v-model="open" width="500px" append-to-body> <el-form ref="courseRef" :model="form" :rules="rules" label-width="80px"> <el-row> <el-col :span="12"> <el-form-item label="渠道来源" prop="channelId"> <el-select v-model="form.channelId" placeholder="请选择渠道来源" clearable style="width: 240px;" > <el-option v-for="channel in channelList" :key="channel.channelId" :label="channel.channelName" :value="channel.channelId" /> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="课程名称" prop="courseName"> <el-input v-model="form.courseName" placeholder="请输入课程名称"/> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="24"> <el-form-item label="课程时间" style="width: 100%;" prop="courseTime"> <el-date-picker style="width: 100%;" v-model="form.courseTime" format="YYYY-MM-DD HH:mm:ss" type="datetimerange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" /> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="课程简介" prop="courseInfo"> <el-input v-model="form.courseInfo" placeholder="请输入课程简介"/> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="课程类型" prop="courseType"> <el-select v-model="form.courseType" placeholder="请选择课程类型" clearable style="width: 240px;" > <el-option v-for="dict in course_type" :key="dict.value" :label="dict.label" :value="parseInt(dict.value)" /> </el-select> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="15"> <el-form-item label="折扣券" prop="discount" v-if="parseInt(form.courseType) === 1"> <el-input-number v-model="form.discount" placeholder="请输入折扣值" :precision="2" :step="0.1" :max="10" :min="0" style="width: 100%;" /> </el-form-item> <el-form-item label="代金券" prop="voucher" v-if="parseInt(form.courseType) === 2"> <el-input-number v-model="form.voucher" placeholder="请输入代金券面值" :precision="2" :step="100" :min="0" style="width: 100%;" /> </el-form-item> </el-col> </el-row> <el-form-item label="备注" prop="remark"> <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"/> </el-form-item> </el-form> <template #footer> <div class="dialog-footer"> <el-button type="primary" @click="submitForm">确 定</el-button> <el-button @click="cancel">取 消</el-button> </div> </template> </el-dialog> </div> </template> <script setup name="Course"> import { addCourse, listCourse, listChannel, getInfo, updateCourse, delCourse } from "@/api/tienchin/course"; const {proxy} = getCurrentInstance(); const { course_type, course_apply_to, } = proxy.useDict('course_type', 'course_apply_to'); const courseList = ref([]); const channelList = ref([]); const open = ref(false); const loading = ref(true); const showSearch = ref(true); const ids = ref([]); const single = ref(true); const multiple = ref(true); const total = ref(0); const title = ref(""); const data = reactive({ form: {}, queryParams: { pageNum: 1, pageSize: 10, courseName: undefined, channelId: undefined, courseStatus: undefined, courseType: undefined }, rules: { channelId: [{required: true, message: "渠道来源不能为空", trigger: "blur"}], courseName: [{required: true, message: "课程名称不能为空", trigger: "blur"}], courseTime: [{required: true, message: "课程时间不能为空", trigger: "blur"}], courseInfo: [{required: true, message: "课程简介不能为空", trigger: "blur"}], courseType: [{required: true, message: "课程类型不能为空", trigger: "blur"}], discount: [{required: true, message: "折扣值不能为空", trigger: "blur"}], voucher: [{required: true, message: "代金券面值不能为空", trigger: "blur"}] } }); const {queryParams, form, rules} = toRefs(data); /** 查询课程列表 */ function getList() { loading.value = true; listCourse(queryParams.value).then(response => { courseList.value = response.rows; total.value = response.total; loading.value = false; }); } /** 取消按钮 */ function cancel() { open.value = false; reset(); } /** 表单重置 */ function reset() { form.value = { channelId: undefined, courseName: undefined, courseTime: undefined, courseInfo: undefined, courseType: undefined, discount: undefined, voucher: undefined, remark: undefined }; proxy.resetForm("courseRef"); } /** 搜索按钮操作 */ function handleQuery() { queryParams.value.pageNum = 1; getList(); } /** 重置按钮操作 */ function resetQuery() { proxy.resetForm("queryRef"); handleQuery(); } /** 多选框选中数据 */ function handleSelectionChange(selection) { ids.value = selection.map(item => item.courseId); single.value = selection.length !== 1; multiple.value = !selection.length; } /** 新增按钮操作 */ function handleAdd() { reset(); // handelChannelList(); open.value = true; title.value = "添加课程"; } /** 修改按钮操作 */ function handleUpdate(row) { reset(); // 加载渠道列表 // handelChannelList(); const courseId = row.courseId || ids.value; getInfo(courseId).then(response => { form.value = response.data; form.value.courseTime = [form.value.beginTime, form.value.endTime]; open.value = true; title.value = "修改课程"; }); } /** 提交按钮 */ function submitForm() { proxy.$refs["courseRef"].validate(valid => { if (valid) { if (form.value.courseId !== undefined) { form.value.beginTime = formatDate(form.value.courseTime[0]); form.value.endTime = formatDate(form.value.courseTime[1]); // 删除掉,form 中的 updateTime 字段 // 删除掉,form 中的 createTime 字段 delete form.value.updateTime; delete form.value.createTime; updateCourse(form.value).then(response => { proxy.$modal.msgSuccess("修改成功"); open.value = false; getList(); }); } else { form.value.beginTime = formatDate(form.value.courseTime[0]); form.value.endTime = formatDate(form.value.courseTime[1]); addCourse(form.value).then(response => { proxy.$modal.msgSuccess("新增成功"); open.value = false; getList(); }); } } }); } /** 删除按钮操作 */ function handleDelete(row) { const courseIds = row.courseId || ids.value; proxy.$modal.confirm('是否确认删除课程编号为"' + courseIds + '"的数据项?').then(function () { return delCourse(courseIds); }).then(() => { getList(); proxy.$modal.msgSuccess("删除成功"); }).catch(() => { }); } /** 导出按钮操作 */ function handleExport() { proxy.download("tienchin/course/export", { ...queryParams.value }, `course_${new Date().getTime()}.xlsx`); } /** * 获取渠道列表 */ function handelChannelList() { listChannel().then(response => { channelList.value = response.data; }); } function formatDate(isoDateString) { // 创建一个新的日期对象 var date = new Date(isoDateString); // 提取年、月、日、小时、分钟和秒 var year = date.getFullYear(); var month = (date.getMonth() + 1).toString().padStart(2, "0"); var day = date.getDate().toString().padStart(2, "0"); var hours = date.getHours().toString().padStart(2, "0"); var minutes = date.getMinutes().toString().padStart(2, "0"); var seconds = date.getSeconds().toString().padStart(2, "0"); // 构建格式化后的日期时间字符串 var formattedDate = year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds; // 返回格式化后的日期时间字符串 return formattedDate; } handelChannelList(); getList(); </script>