若依前后端分离学习笔试
文章目录
1.路由问题
注意这个是前端找到你的路由的路径。
2.表格开关按钮快速实现
<el-table-column label="状态" align="center" key="status">
<template slot-scope="scope">
<el-switch
v-model="scope.row.status"
active-value="0"
inactive-value="1"
@change="handleStatusChange(scope.row)"
></el-switch>
</template>
</el-table-column>
//methods add this method
// 状态修改
handleStatusChange(row) {
let text = row.status === "0" ? "启用" : "停用";
this.$modal.confirm('确认要"' + text + '""' + row.title + '"量表吗?').then(function() {
return changeStatus(row.scaleId,row.status);
}).then(() => {
this.$modal.msgSuccess(text + "成功");
}).catch(function() {
row.status = row.status === "0" ? "1" : "0";
});
},
// import this
import { listScaleInfo, getScaleInfo, delScaleInfo, addScaleInfo, updateScaleInfo, changeStatus } from "@/api/businessManagement/scaleBaseinfo";
// 修改分类状态
export function changeStatus(scaleId,status) {
const data = {
scaleId,
status
}
return request({
url: '/businessManage/scaleInfo/changeStatus',
method: 'put',
data: data
})
}
@Log(title = "修改状态", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public AjaxResult changeStatus(@RequestBody ScaleBaseinfo scaleBaseinfo)
{
return toAjax(scaleBaseinfoService.changeStatus(scaleBaseinfo));
}
//interface generate this method automatically
@Override
public int changeStatus(ScaleBaseinfo scaleBaseinfo) {
return scaleBaseinfoMapper.updateScaleBaseinfo(scaleBaseinfo);
}
3.选中指定的导出和批量导出
<el-col :span="1.5">
<template>
<div>
<el-button type="primary" icon="el-icon-download" @click="handleExport" size="mini">批量导出
<el-dropdown @command="handleExportCommand">
<span class="el-dropdown-link">
<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="selected">当前选中</el-dropdown-item>
<el-dropdown-item command="search">当前搜索</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown></el-button>
</div>
</template>
</el-col>
/** 导出按钮操作 */
handleExport() {
// 根据不同的导出选项执行不同的导出逻辑
if (this.exportOption === 'selected') {
// 导出当前选中的数据
// 执行导出逻辑
if(this.queryParams.stuIds.length === 0){
// alert("请选中学生数据进行导出!");
this.$modal.msgWarning("请选中学生数据进行导出!");
return;
}
this.download('usersManage/student/export', {
...this.queryParams
}, `Student_${new Date().getTime()}.xlsx`)
} else if (this.exportOption === 'search') {
// 导出当前搜索的数据
// 执行导出逻辑
this.download('usersManage/student/export', {
...this.queryParams
}, `Student_${new Date().getTime()}.xlsx`)
} else {
// 默认导出全部数据
// 执行导出逻辑
this.$modal.msgWarning("请选中导出的类型!");
}
},
handleExportCommand(command) {
this.exportOption = command;
this.handleExport();
},
后端code
/**
* 导出学生基本信息列表
*/
@PreAuthorize("@ss.hasPermi('usersManage:student:export')")
@Log(title = "学生基本信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, BasicStudent basicStudent)
{
List<BasicStudent> list = bStudentService.selectStudentVoList(basicStudent);
ExcelUtil<BasicStudent> util = new ExcelUtil<BasicStudent>(BasicStudent.class);
util.exportExcel(response, list, "学生基本信息数据");
}
//注意这里第一行实现的东西,直接可以batchExport
<select id="selectBStudentList" parameterType="BasicStudent" resultMap="BStudentResult">
<include refid="selectBStudentVo"/>
<where>
<if test="stuIds != null">
AND stu_id IN
<foreach collection="stuIds" item="stuId" separator="," open="(" close=")">
#{stuId}
</foreach>
</if>
<if test="studentId != null and studentId != ''"> and stu_id = #{studentId}</if>
<if test="stuName != null and stuName != ''"> and stu_name like concat('%', #{stuName}, '%')</if>
<if test="sessionId != null "> and session_id = #{sessionId}</if>
<if test="schId != null "> and b.sch_id = #{schId}</if>
<if test="cId != null "> and clazz_id = #{cId}</if>
<if test="pId != null "> and parent_id = #{pId}</if>
<if test="schoolName != null and schoolName != ''"> and sch.school_name = #{schoolName}</if>
<if test="area != null and area != ''"> and sch.area = #{area}</if>
<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
and date_format(s.createTime,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')
</if>
<if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
and date_format(s.createTime,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d')
</if>
<if test="createBy != null and createBy != ''"> and s.createBy = #{createBy}</if>
<if test="updateBy != null "> and s.updateBy = #{updateBy}</if>
</where>
</select>
4.生产环境打包前端问题
[
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"areaId": 1,
"areaName": "南校区",
"schId": 2,
"basicSchool": null,
"basicGradeList": [
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 1,
"gradeName": "一年级",
"areaId": 1,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 2,
"gradeName": "二年级",
"areaId": 1,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 3,
"gradeName": "三年级",
"areaId": 1,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 4,
"gradeName": "一年级",
"areaId": 2,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 5,
"gradeName": "二年级",
"areaId": 2,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 6,
"gradeName": "一年级",
"areaId": 3,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 7,
"gradeName": "一年级",
"areaId": 3,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 9,
"gradeName": "二年级",
"areaId": 4,
"basicSchoolArea": null,
"basicClassList": null
}
]
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"areaId": 2,
"areaName": "北校区",
"schId": 2,
"basicSchool": null,
"basicGradeList": [
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 1,
"gradeName": "一年级",
"areaId": 1,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 2,
"gradeName": "二年级",
"areaId": 1,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 3,
"gradeName": "三年级",
"areaId": 1,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 4,
"gradeName": "一年级",
"areaId": 2,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 5,
"gradeName": "二年级",
"areaId": 2,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 6,
"gradeName": "一年级",
"areaId": 3,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 7,
"gradeName": "一年级",
"areaId": 3,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 9,
"gradeName": "二年级",
"areaId": 4,
"basicSchoolArea": null,
"basicClassList": null
}
]
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"areaId": 3,
"areaName": "东校区",
"schId": 2,
"basicSchool": null,
"basicGradeList": [
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 1,
"gradeName": "一年级",
"areaId": 1,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 2,
"gradeName": "二年级",
"areaId": 1,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 3,
"gradeName": "三年级",
"areaId": 1,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 4,
"gradeName": "一年级",
"areaId": 2,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 5,
"gradeName": "二年级",
"areaId": 2,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 6,
"gradeName": "一年级",
"areaId": 3,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 7,
"gradeName": "一年级",
"areaId": 3,
"basicSchoolArea": null,
"basicClassList": null
},
{
"createBy": null,
"createTime": null,
"updateBy": null,
"updateTime": null,
"remark": null,
"gradeId": 9,
"gradeName": "二年级",
"areaId": 4,
"basicSchoolArea": null,
"basicClassList": null
}
]这个数据 怎么用elmentUI层级表示,一级显示的label是areaName, children: 'basicGradeList',二级显示的label是gradeName, children: 'basicClassList',三级显示的是className,没有children,怎么用elmentUI表示
5.路由跳转问题
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m54viF4f-1692860445256)(C:\Users\My Windows pc\AppData\Roaming\Typora\typora-user-images\image-20230815164743889.png)]
viewGrade(row){
const areaId = row.areaId;
this.$router.push({
path: "/schoolManage/grade/",
query: {
areaId: areaId
}
});
},
6.远程linux服务器下载文件模板
@GetMapping("/template")
public void testExportTemplate(HttpServletResponse response, String fileName) throws IOException {
DownLoadUtils.template(response,"schoolViewImportStudentTemplate.xls","schoolViewImportStudentTemplate.xls");
}
public class DownLoadUtils {
private static final Logger log = LoggerFactory.getLogger(DownLoadUtils.class);
/**
* 下载模版文件
*
* @param response HttpServletResponse对象
* @param path 模版文件相对路径
* @param name 模版文件保存名称(自动检查后缀.xls)
* @throws IOException
*/
public static void template(HttpServletResponse response, String path, String name) throws IOException {
if (null != name) {
if (!name.toUpperCase().endsWith(".XLS")) {
name = name + ".xls";
}
} else {
name = System.currentTimeMillis() + name.substring(name.indexOf("_") + 1) + ".xls";// 随机名称
}
path = RuoYiConfig.getRemotUrl() + path;
download(response, path, name, "模版文件未找到!", "模版文件读取错误!");
}
/**
* 下载非公开文件
*
* @param response HttpServletResponse对象
* @param filePath 文件相对路径
* @param name 下载文件保存名称
* @param msgUnFind 文件未找到提示信息
* @param msgUnRead 文件读取错误提示信息
* @throws IOException
*/
public static void download(HttpServletResponse response, String filePath, String name, String msgUnFind, String msgUnRead) throws IOException {
// File file = FileUtils.getSecurityFile(path, false);
File file = new File(filePath);
if (null != file && file.exists()) {
try {
InputStream is = null;
try {
is = new BufferedInputStream(new FileInputStream(file));
byte[] buffer = new byte[is.available()];
is.read(buffer);
response.setContentType("application/octet-stream; charset=UTF-8");
response.setHeader("Content-Disposition", "attachment; fileName=\"" + new String((name).getBytes("GBK"), "ISO8859-1"));
OutputStream os = new BufferedOutputStream(response.getOutputStream());
os.write(buffer);
os.flush();
os.close();
} catch (Exception e) {
log.error(msgUnFind + "(" + file + ")", e);
} finally {
if (null != is) {
is.close();
}
}
} catch (Exception e) {
log.error(msgUnFind + "(" + file + ")", e);
}
} else {
log.error(msgUnFind + "(" + file + "," + filePath + ")");
}
}
}
/**
* 读取项目相关配置
*
* @author ruoyi
*/
@Component
@ConfigurationProperties(prefix = "ruoyi")
public class RuoYiConfig
{
/** 项目名称 */
private String name;
/** 版本 */
private String version;
/** 版权年份 */
private String copyrightYear;
/** 实例演示开关 */
private boolean demoEnabled;
/** 上传路径 */
private static String profile;
/**
* linu服务器下载文件地址
*/
private static String remotUrl;
/** 获取地址开关 */
private static boolean addressEnabled;
/** 验证码类型 */
private static String captchaType;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getVersion()
{
return version;
}
public void setVersion(String version)
{
this.version = version;
}
public String getCopyrightYear()
{
return copyrightYear;
}
public void setCopyrightYear(String copyrightYear)
{
this.copyrightYear = copyrightYear;
}
public boolean isDemoEnabled()
{
return demoEnabled;
}
public void setDemoEnabled(boolean demoEnabled)
{
this.demoEnabled = demoEnabled;
}
public static String getProfile()
{
return profile;
}
public void setProfile(String profile)
{
RuoYiConfig.profile = profile;
}
public static boolean isAddressEnabled()
{
return addressEnabled;
}
public void setAddressEnabled(boolean addressEnabled)
{
RuoYiConfig.addressEnabled = addressEnabled;
}
public static String getCaptchaType() {
return captchaType;
}
public void setCaptchaType(String captchaType) {
RuoYiConfig.captchaType = captchaType;
}
public static String getRemotUrl() {
return remotUrl;
}
public void setRemotUrl(String remotUrl) {
RuoYiConfig.remotUrl = remotUrl;
}
/**
* 获取导入上传路径
*/
public static String getImportPath()
{
return getProfile() + "/import";
}
/**
* 获取头像上传路径
*/
public static String getAvatarPath()
{
return getProfile() + "/avatar";
}
/**
* 获取下载路径
*/
public static String getDownloadPath()
{
return getProfile() + "/download/";
}
/**
* 获取上传路径
*/
public static String getUploadPath()
{
return getProfile() + "/upload";
}
}
注意: /**linu服务器下载文件地址
/
private static String remotUrl; 这个属性通过自动 生成Getter方法和Setter方法的时候,Setter方法不要加上 static
6.1前端code 不要使用rouyi自带的前端code,下载之后打开不了亲测有问题
<el-button
type="warning"
icon="el-icon-download"
size="mini">
<a :href="downloadUrl" ><em>模板-下载</em></a>
</el-button>
7 三级联动数据显示不了问题
<el-form-item label="校区" prop="areaId">
<el-select v-model="stuform.areaId" placeholder="校区" @change="listGradeListChange">
<el-option v-for="area in listAreasList" :key="area.areaId" :label="area.areaName" :value="area.areaId"
clearable></el-option>
</el-select>
</el-form-item>
<el-form-item label="年级" prop="gradeId">
<el-select v-model="stuform.gradeId" placeholder="年级" @change="clazzListChage">
<el-option v-for="grade in listGradeList" :key="grade.gradeId" :label="grade.gradeName" :value="grade.gradeId"
clearable></el-option>
</el-select>
</el-form-item>
<el-form-item label="班级" prop="clazzId">
<el-select v-model="stuform.clazzId" placeholder="班级" @change="clazzChage">
<el-option v-for="clazz in clazzList" :key="clazz.clazzId" :label="clazz.className"
:value="clazz.clazzId">{{clazz.className}}</el-option>
</el-select>
</el-form-item>
<el-form-item label="学生姓名" prop="stuNamea" v-show="false">
<el-input v-model="stuform.stuNamea" placeholder="请输入学生姓名" />
</el-form-item>
然后在methods方法加上
clazzChage() {
this.form.stuNamea = this.form.stuNamea + "1"
},
8. 多选按钮联动筛选地学生问题
- 后端需要封装一个三级,校区里面包含多个年级,年级里面包含多个班级这种,最后返回给前端一个三级 的集合。
- 前端需要对它进行一个显示根据 elmentUI的一些示例进行研究显示。
<el-form-item label="手动选择测评人" class="itemLength" v-show="this.addStudentType == 1" style="width: 88%" >
<br/>
<h3> 选择校区</h3>
<el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange" class="floatRight">全选</el-checkbox>
<br/>
<div style="margin: 15px 0px 3 999px;"></div>
<el-checkbox-group v-model="checkedCities" @change="handleCheckedCitiesChange">
<el-checkbox v-for="area in this.cities" :label="area" :key="area.areaId">{{area.areaName}}</el-checkbox>
</el-checkbox-group>
<template id="manualBackground">
<div v-if="this.checkedCities.length != 0">
<h3> 选择年级</h3>
<el-checkbox :indeterminate="isIndeterminate" v-model="checkAllGrades" @change="handleCheckAllGradesChange" class="floatRight" >全选 </el-checkbox>
<span v-for="area in this.checkedCities" :label="area" :key="area.areaId">
<!-- <el-divider></el-divider> -->
<el-divider> {{area.areaName}} </el-divider>
<div style="margin: 15px 0;"></div>
<el-checkbox-group v-model="checkedGrades" @change="handleCheckedGradesChange">
<!-- it's important that <span v-show="false"> {{grade.areaName = area.areaName }}</span> -->
<el-checkbox v-for="grade in area.basicGradeList" :label="grade" :key="grade.gradeId">{{grade.gradeName}} <span v-show="false"> {{grade.areaName = area.areaName }}</span></el-checkbox>
</el-checkbox-group>
</span>
</div>
</template>
<template>
<div v-if="this.checkedGrades.length != 0 && this.checkedCities.length != 0">
<h3> 选择班级</h3>
<el-checkbox :indeterminate="isIndeterminate" v-model="checkAllClasses" @change="handleCheckAllClassesChange" class="floatRight">全选</el-checkbox>
<span v-for="grade in this.checkedGrades" :label="grade" :key="grade.gradeId">
<!-- <el-divider></el-divider> -->
<el-divider> {{grade.areaName}} {{grade.gradeName}}</el-divider>
<div style="margin: 15px 0;"></div>
<el-checkbox-group v-model="checkedClasses" @change="handleCheckedClassesChange">
<el-checkbox v-for="clazz in grade.basicClassList" :label="clazz" :key="clazz.clazzId">{{clazz.className}}</el-checkbox>
</el-checkbox-group>
</span>
</div>
<center> <p> <el-button type="success" @click="filterStudentList()"> 筛选学生数据</el-button></p> </center>
</template>
注意里面的:label=“一个对象” 里面可以这样绑定,然后选中的对象就会被触发。
<el-checkbox v-for="grade in area.basicGradeList" :label="grade" :key="grade.gradeId">{{grade.gradeName}} <span v-show="false"> {{grade.areaName = area.areaName }}</span></el-checkbox>
这个里面 这样处理校区名称 我提高了有些时间。
9. 路由跳转没有执行vue created函数
说是那个 路由里面加上的 name,和路由里面的没有匹配,我的是一样的
**解决办法:**删除 name: “组件名字”
10.前端的按钮点击不了
看看是不是哪个盒子覆盖了你的按钮,导致按钮点击不了,设置按钮的层级为最高,百度下看看怎么设置按钮的层级的
11.卡克前端问题
11.1 路由传递参数不起作用
the.$route.query();在created函数里面不可以获取到数据, 删除组件的name的值
11.2 删除页面标签报错
路由传递参数使用JSON.stringfy()处理一下,后面用JSON.parse()进行解析,可以防止一些参数丢失。
11.3 checkBox查询后端接口之后之前选中的数据没有显示为选中状态
1.el-checkbox,的key尽量使用id主键来绑定,如果使用一个对象进行绑定可以会导致识别不出来
2.查询后端接口之时,可以对选中的checkList进行一个数组的备份checkCopyList,然后查询出来之后,再赋值回去。