前后端项目-part03

这篇博客详细介绍了如何实现课程管理模块,包括机构名称的处理、课程标签的添加、课程图片上传功能以及分页查询课程信息和删除记录的前后端操作。涉及实体类创建、Mapper接口、Service层、Controller层的编写,以及前端Vue组件和JavaScript脚本的修改与测试。
摘要由CSDN通过智能技术生成

5.4.4 机构名称

5.4.4.1 创建实体类Company
package com.zx.system.entity;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;

import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Accessors(chain = true)
@TableName("tb_company")
public class Company {
   
    private Integer id;
    private String name;//名称
    private String orgType;//c机构 p个人
    private String phone;//联系方式
    private String linkname;//联系人名称
    private String handPhotos;//手持证件照
    private String address;//机构地址
    private String logo;//机构logo
    private String email;//邮箱
    private String promiseLetter;//承诺书
    private String trademarkPic;//商标注册证
    private String intro;//简介
    private String briefIntro;
    private String mainCategory;//主营类目
    private String identityPic;//身份证照片
    private String workType;//工具性质
    private String businessPic;//营业执照
    private Date businessTerm;//营业执照有效期
    private String businessRegistNo;//营业执照注册号
    private String eduCertImg;//教育资质/学历证书照片
    private String eduCertTerm;//教育资质证书有效期
    private String eduCertNo;//教育资质/学历编号
    private String approvalStatus;//审核状态
    private String approvalComment;//审批意见
    private String approvalPeople;//审批人
    private Date approvalDate;//审批日期
    private Integer approvalNums;//审核次数
    private String remark;//备注
    private Date createDate;
    private Date changeDate;
    private Integer tenantId;//租户ID
    private String idCard;//身份证号
    private String teacherCertImg;//教师资格证照片
    private String teacherCertNo;//教师资格证号码
    private Integer status;//状态
    private String majorCertImg;//专业证件照片
    private String majorCertNo;//专业证件号码
    private String workExperience;//教学工作经历
    private String workResults;//教学工作成果
    private String title;//机构名称
}

5.4.4.2 创建实体类CompanyMapper
package com.zx.system.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zx.system.entity.Company;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface CompanyMapper extends BaseMapper<Company> {
   
}

5.4.4.3 创建实体类CompanyService
package com.zx.system.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zx.system.entity.Company;
import com.zx.system.mapper.CompanyMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class CompanyService extends ServiceImpl<CompanyMapper, Company> {
   
    @Autowired
    private CompanyMapper companyMapper;

    public List<Company> selectAll(){
   
        QueryWrapper qw = new QueryWrapper();
        qw.select("id","name","org_type","phone","linkname");//查询指定列
        qw.eq("status",1);//1正常0停用
        qw.orderByDesc("create_date");//倒序
        return companyMapper.selectList(qw);
    }

}

5.4.4.4 创建实体类CompanyController
package com.zx.system.controller;

import com.zx.system.entity.Company;
import com.zx.system.service.CompanyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@CrossOrigin
@RequestMapping("/system/company")
public class CompanyController {
   
    @Autowired
    private CompanyService companyService;

    @GetMapping("/selectAll")
    public List<Company> selectAll(){
   
        return companyService.selectAll();
    }
}

5.4.4.5 后端测试

在这里插入图片描述

5.4.4.6 修改basic.js
// 课程管理CRUD
import axios from '../axios.js'

//获取分类信息
const zx_basic = 'http://localhost:9999/basic'

//去后台,获取所有分类的三级树
export const AllCategory = async ()=>{
   
	const res = await axios.get(zx_basic+"/category/getTree")
	return res
}

//去后台,获取一级分类
export const Level1Category = async ()=>{
   
	const res = await axios.get(zx_basic+"/category/level1Category")
	return res
}

//根据字典编号,获取字典信息
export const GetDict = async (code)=>{
   
	const res = await axios.get(zx_basic+"/dictionary/getDicItems/"+code)
	return res
}

//去后台//获取所有机构信息
const zx_system = 'http://localhost:8888/system'
export const GetCompany = async ()=>{
   
	const res = await axios.get(zx_system+"/company/selectAll")
	return res
}

5.4.4.7 修改course.vue
<template>
	<el-card shadow="always">
		<h3><el-icon><ElementPlus /></el-icon>课程管理</h3>
	
		<el-row style="padding:10px;" gutter="3">
			<el-col span="8">
				<el-button type="primary" size="small" @click="toAdd">
					<el-icon><CirclePlus /></el-icon>&nbsp;新增
				</el-button>
				<el-button v-if="multipleSelection.length" type="danger" size="small" @click="handlerMuchDel">删除多条</el-button>
			</el-col>
			<el-col span="16">
				<el-input size="small" v-model="searchName" placeholder="按课程名称搜索">
					<template #append><el-icon><Search/></el-icon></template>
				</el-input>
			</el-col>
		</el-row>
		
		<el-table :data="filterData" @selection-change="handleSelectionChange" border>
			<el-table-column prop="id" type="selection" width="55"></el-table-column>
			<el-table-column prop="planNum" label="计划数量" heder-align="center"></el-table-column>
			<el-table-column prop="companyName" label="公司名称" heder-align="center" ></el-table-column>
			<el-table-column prop="name" label="课程名称" heder-align="center"></el-table-column>
			<el-table-column prop="tags" label="课程标签" heder-align="center" ></el-table-column>
			<el-table-column prop="mtName" label="大分类名称" heder-align="center" ></el-table-column>
			<el-table-column prop="stName" label="小分类名称" heder-align="center" ></el-table-column>
			<el-table-column prop="grade" label="课程等级" heder-align="center" ></el-table-column>
			<el-table-column prop="teachmode" label="教学模式" heder-align="center" ></el-table-column>
			<el-table-column prop="auditStatus" label="审核状态" heder-align="center" ></el-table-column>
			<el-table-column prop="coursePubId" label="发布标识" heder-align="center" ></el-table-column>
			<el-table-column prop="price" label="课程单价" heder-align="center" ></el-table-column>
			<el-table-column prop="createDate" label="创建时间" :formatter="formatDate" align="center"/>
			<el-table-column prop="auditDate" label="审核时间" :formatter="formatDate" align="center"/>
			
			<el-table-column label="操作" align="center">
				<template #default="scope">
					<el-button @click="toEdit(scope.$index)" type="success" size="small"><el-icon><EditPen/></el-icon>修改</el-button>
					<el-button @click="handleDel(scope.row.id)" type="danger" size="small"><el-icon><Delete/></el-icon>删除</el-button>
					<el-button @click="handlePub(scope.row.id)" type="danger" size="small"><el-icon><Delete/></el-icon>发布</el-button>
					<el-button @click="handleDown(scope.row.id)" type="danger" size="small"><el-icon><Delete/></el-icon>下架</el-button>
				</template>
			</el-table-column>
		</el-table>
		
		<!-- 分页条 -->
		<div style="">
			<el-pagination :current-page="page.pageNum" :page-size="page.pageSize" :page-sizes="[5,10,50,100]"
				layout="total,sizes,prev,pager,next,jumper" :total="page.total" 
					@size-change="handleSizeChange" @current-change="handleCurrentChange">
			</el-pagination>
		</div>
	</el-card>
	
	<!-- 设置对话框 -->
	<el-dialog v-model="dialogVisible" draggable>
		<template #header>
			<h4><el-icon><Brush/></el-icon> {
  {dialogType==='add'?'新增':'修改'}}课程管理</h4>
		</template>
		
		<el-form :model="form.data" label-position="left" label-width="120px">
			<el-form-item label="机构名称">
				<el-select v-model="form.data.companyId" placeholder="请选择">
					<el-option v-for="item in companyOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
				</el-select>
			</el-form-item>
			<el-form-item label="课程名称">
				<el-input v-model="form.data.name" show-word-limit maxlength="100"></el-input>
			</el-form-item>
			<el-form-item label="适用人群">
				<el-input v-model="form.data.users" type="textarea"
							show-word-limit maxlength="500" :autosize="{minRows:2,maxRows:4}"></el-input>
			</el-form-item>
			
			<el-form-item label="课程标签">
				<el-input v-model="form.data.tags"></el-input>
			</el-form-item>
			
			<!-- 4个下拉框 -->
			<el-form-item label="一级分类">
				<el-select v-model="form.data.mt" placeholder="请选择">
					<el-option v-for="item in mtOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
				</el-select>
			</el-form-item>
			
			<el-form-item label="二级分类"><!-- 二级分类树 -->
				<el-select v-model="form.data.st" placeholder="请选择">
					<el-option :value="selectValue" :label="selectValue" style="height: 200px;overflow: auto;" >
						<el-tree :data="stOptions" @node-click="handleNodeClick"></el-tree>
					</el-option>
				</el-select>
			</el-form-item>
			
			<el-form-item label="课程等级">
				<el-select v-model="form.data.grade" placeholder="请选择">
					<!-- 遍历gradeOptions :key遍历的id  :label要展示的数据 :value根据key获取到的value-->
					<el-option v-for="item in gradeOptions" :key="item.code" :label="item.desc" :value="item.code"></el-option>
				</el-select>
			</el-form-item>
			
			<el-form-item label="教学模式">
				<el-select v-model="form.data.teachmode" placeholder="请选择">
					<el-option v-for="item in teachmodeOptions" :key="item.code" :label="item.desc" :value="item.code"></el-option>
				</el-select>
			</el-form-item>
			
			<el-form-item label="课程介绍">
				<el-input v-model="form.data.description" type="textarea"
							show-word-limit maxlength="1000" :autosize="{minRows:4,maxRows:10}"></el-input>
			</el-form-item>
			
			<el-form-item label="课程图片">
				<el-input v-model="form.data.pic"></el-input>
			</el-form-item>
			
			<el-form-item label="课程单价">
				<el-input v-model="form.data.price">(元)</el-input>
			</el-form-item>
		</el-form>
		
		<div style="">
			<el-button @click="dialogSave" type="success">保存</el-button>
			<el-button @click="dialogCancle" type="primary">取消</el-button>
		</div>
	</el-dialog>
</template>

<script setup>
	
	// 一级分类:::: 1.引入js
	import {
     GetCompany,Level1Category,AllCategory,GetDict} from '../../api/basic.js'
	
	import {
      ref, reactive } from 'vue'
	import {
     ElMessageBox} from 'element-plus'//导入消息提示框
	import {
     toast} from '../../tools/utils.js'
	import {
     CoursePage,CourseDel,CourseSave} from '../../api/course.js'
	
	
	
	const dialogVisible = ref(false)//对话框是否展示
	const dialogType = ref('add')//对话框新增还是修改
	const searchName = ref('')//按照课程名称查询
	
	//查后台数据,准备4个下拉框的值,value值是要传给后台的,label的值是要在页面展示的
	
	//:::: 一级分类:::: 2.使用1.引入js的结果,利用axios获取数据
	let mtOptions = ref([]) //一级分类//响应式声明变量
	Level1Category()
	.then(res=>{
     
		// console.log(res)
		mtOptions.value = res //给响应式变量赋值要用value属性
	})
	.catch(err=>{
     
		
	})
	
	//:::: 二级分类:::: 
	let stOptions = ref([]) 
	AllCategory()
	.then(res=>{
     
		stOptions=res
		console.log(res+'-'+stOptions)
	}).catch(err=>{
     
		console.log(err)
	})
	const selectValue=ref()
	const handleNodeClick=(e,node)=>{
     
		selectValue.value=e.value+'->'+e.label
		form.data.st=selectValue.value
	}
	
	let gradeOptions = ref([]) //课程等级204,课程模式200
	GetDict(204).then((res=>{
     
		// console.log(res)
		gradeOptions.value=res
	})).catch(err=>{
     
		console.log(err)
	})
	
	let teachmodeOptions = ref([]) //教学模式
	GetDict(200).then(res=>{
     
		teachmodeOptions=res
	}).catch(err=>{
     
		console.log(err)
	})
	
	//===============机构名称
	let companyOptions = ref([]) 
	GetCompany().then(res=>{
     
		companyOptions.value=res
	}).catch(err=>{
     console.log(err)})
	
	
	//多选
	const multipleSelection = ref([])//临时存放选中的数据,实际上就是多个row
	const handleSelectionChange=(val)=>{
     //当点击多选按钮时就会触发
		multipleSelection.value = val
	}
	
	//准备表格数据,
	const state = reactive({
     tableDate:[]})//空数组
	const handleDel=(id)=>{
     
		ElMessageBox.confirm('您是否确认删除此记录?','提示',{
     confirmButtonText:'确认',cancelButtonText:'取消',type:'warning'})
			.then(()=>{
     
				CourseDel(id).then(res=>{
     
					toast('删除记录成功!')
					loadingData(1,page.pageSize)//重新查询,默认展示第一页
				})
				.catch(err=>{
     
					console.log(err)
				})
			})
			.catch(()=>{
     
				
			})
	}
	
	//删除多条
	const handlerMuchDel=()=>{
     
		ElMessageBox.confirm('您是否确认删除此记录?','提示',{
     confirmButtonText:'确认',cancelButtonText:'取消',type:'warning'})
			.then(()=>{
     
				multipleSelection.value.forEach(row=>{
     
					CourseDel(row.id).then(res=>{
     
						toast('删除成功!')
						loadingData(1,page.pageSize)//重新查询一次,默认展示第一页
					}).catch(err=>{
     
						console.log(err)
					})
				})
			})
			.catch(()=>{
     
				
			})
	}
	
	//转向新增页面(打开对话框)
	const toAdd =()=>{
     
		dialogVisible.value=true//展现对话框
		form.data={
     
			...form.data,
			...formInit //利用formInit对数据进行初始化
		}
	}
	
	//新增或修改的保存按钮
	const dialogSave=()=>{
     
		CourseSave(form.data).then(res=>{
     
			toast('保存数据成功')//弹窗
			loadingData(1,page.pageSize)//重新查询,展示第一页
		}).catch(err=>{
     
			console.log(err)
		})
		dialogVisible.value=false //关闭对话框
	}
	
	//取消按钮
	const dialogCancle=()=>{
     
		dialogVisible.value=false //关闭对话框
	}
	
	//转向修改页面(打开对话框,并回显数据)
	const toEdit =(index)=>{
     
		form.data = {
     
			...form.data,
			...state.tableDate[index] //回显数据
		}
		dialogVisible.value=true //打开对话框
		dialogType.value='edit' //修改
	}
	
	
	//对话框form初始化
	const formInit={
     
		id:null,
		companyId:null,
		companyName:null,
		name:null,
		users:null,
		tags:null,
		mt:null,
		st:null,
		grade:null,
		teachmode:null,
		description:null,
		pic:null,
		price:null
	}
	let form = reactive(formInit)//对话框表单绑定数据
	console.log(form.data+'=================================')
	//分页参数对象
	const page = reactive({
     
		total:0,
		pageNum:1,
		pageSize:10//可以改成20 50..
	})
	//加载分页数据,刷新方法
	const loadingData=(pageNum,pageSize)=>{
     
		//promise函数
		CoursePage(pageNum,pageSize).then(res=>{
     
			state.tableDate=reactive(res.data.records)//后台查的表格数据
			page.total=res.data.total//后台返回的总记录数
		}).catch(err=>{
     
			console.log(err)
		})
	}
	loadingData(page.pageNum,page.pageSize) //初始化开始执行
	
	//修改每页的记录数时会触发,底层给我们传递val参数
	const handleSizeChange = (val)=>{
     
	//console.log('每页多少条记录:'+ val)
		page.pageSize = val
		loadingData(1,page.pageSize)//重新查询·展示第一页
	}
	
	//点击某页数据·底层会给我们传递val参数·现在选择的是第几页
	const handleCurrentChange = (val)=>{
     
	//console.log('当前页是:'+val)
		page.pageNum = val
		loadingData(page.pageNum,page.pageSize) //重新查询·展示第一页
	}

	//搜索框,computed会随着函数中的响应式变量的变化而触发
	import {
     computed} from 'vue'
	let filterData = computed(()=>{
     
				if(state.tableData != null) //有数据再过滤,否则报错没定义不能用filter
					return state.tableData.filter((row)=>{
     
				// 判断条件
				return row.name.includes(searchName.value)
		})
	})
	
	
	//导入日期函数库
	import {
     format } from 'date-fns'
	//表格数据加载时·每行都会执行这个函数·每个日期就可以被格式化
	const formatDate = (row, index,cellValue)=>{
     
		if(cellValue != null){
     
			//cellValue它不是一个日期的类型·底层传过来是字符串类型·必须先转化
			return format(new Date(cellValue),'yyyy-MM-dd')//格式化成年月日形式
		}
		return cellValue
	}
	
</script>

<style>
</style>

5.4.4.8 测试

在这里插入图片描述

5.4.5 课程标签

5.4.5.1 效果

在这里插入图片描述

5.4.5.2 修改course.vue
<template>
	<el-card shadow="always">
		<h3><el-icon><ElementPlus /></el-icon>课程管理</h3>
	
		<el-row style="padding:10px;" gutter="3">
			<el-col span="8">
				<el-button type="primary" size="small" @click="toAdd">
					<el-icon><CirclePlus /></el-icon>&nbsp;新增
				</el-button>
				<el-button v-if="multipleSelection.length" type="danger" size="small" @click="handlerMuchDel">删除多条</el-button>
			</el-col>
			<el-col span="16">
				<el-input size="small" v-model="searchName" placeholder="按课程名称搜索">
					<template #append><el-icon><Search/></el-icon></template>
				</el-input>
			</el-col>
		</el-row>
		
		<el-table :data="filterData" 
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值