目录
2 点击注册提示登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示'。
7 问题:根据上边的下拉框选择规则类型,1:字典 2:数字 3:文字 ;判断现编规则值的填报类型(下拉框还是输入框)
8 问题:后端若依controller层自带的startPage,分页,只会作用于第一次查询。
9 问题:前端传分页参数为5,到后台接收到的分页参数为10。
方法二:导出excel时,将表头下的每一列的单元格都设置问文本格式。
14 导入导出excel常用注解(1)@Excel( name = "名称", prompt = "excel点击表格时显示提示信息")
15 添加权限认证(前提:这张表需要有deptId字段或存userId的字段)
18 下载excel模板,单元格提示信息,默认只展示100行。
记录使用若依框架开发时遇到的一系列问题,以后遇到新问题会随时更新这篇文章。欢迎各位小伙伴私聊补充问题及解决办法。
1验证码失效
问题:修改注册界面,即使去掉了验证码,注册的时候还是会显示验证码失效。
解决:在参数设置里,把验证码关闭即可。
2 点击注册提示登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示'。
原因:request.js里设置了拦截器
解决:在frame下的security配置里添加需要调用的方法
3 弹出错误信息:用户账号不能为空
原因:可能是传值过程中有问题。
我的解决办法:我在register.java里面重写了这些属性,删除掉了原有的继承log日志的username和password,只有两个属性 。
然后我将注册界面添加的多个值都在service里赋值给user。
4 定时任务
注意:这里运行若依自带的定时任务或者添加定时任务可能会在后台报错,错误会跟costTime有关,原因是数据表中缺少这个字段,需要手动添加。
功能实现:
4.1.代码:在quartz模块下的ReTask中,调用相关的service,并实现逻辑方法即可。
4.2然后再定时任务界面新增定时任务。
这里调用方法名为ryTask.changeNoticeStatus。被只好表达式点击确定,即可完成添加定时任务。是否执行看你自己。状态可以设置为关闭,毕竟是测试。用到在打开即可。
状态为关闭状态的话,可以点击操作里的更多,点击执行一次,即可执行定时任务。(注意:测试的时候,cron执行表达式不要设置在当前日期之前,不然点击执行会提示“任务不存在或者已过期”)。
5 字典项问题
问题:字典项显示数字,并非字典项中的值。
错误:在 <el-select>
组件中,v-model
绑定的是 form.isPay
,而我将其赋值为整数 0
。字典项的值 dict.value
是一个字符串类型。
解决:为了解决这个问题,您可以将 form.isPay
的初始值设置为字符串类型的 "0",而不是整数类型的 0
。
<el-form-item label="缴费标志" prop="isPay">
<el-select v-model="form.isPay" placeholder="请选择缴费标志" @change="handleOptionChange">
<el-option
v-for="dict in dict.type.is_pay"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
js里通过 this.form.isPay = "0" 赋值;
6 问题:生成代码form表单有值,但是校验不通过。
解决:查看前端data初始化值和表单清空form内容处,有没有该变量。
7 问题:根据上边的下拉框选择规则类型,1:字典 2:数字 3:文字 ;判断现编规则值的填报类型(下拉框还是输入框)
出现问题:如果规则值类型都绑定的是一个approveValue变量,界面中修改规则类型,从字典改为数字或者文字,页面控制台就会报错
解决:在data的form里新建一个变量,来替换输入框中绑定的值,然后在提交form时,再将新定义的变量的值,赋值给form.approveValue即可。
8 问题:后端若依controller层自带的startPage,分页,只会作用于第一次查询。
解决:可以将复杂的筛选条件使用sql语句解决。
或者
使用自定义分页方法:
1.编写自定义分页方法
代码如下:
package com.active.common.core.page;
import com.active.common.constant.HttpStatus;
import java.util.List;
public class PageUtil {
/**
* 开始分页
* @param list
* @param pageNum 页码
* @param pageSize 每页多少条数据
* @return
*/
public static List startPage(List list, int pageNum,
int pageSize) {
if (list == null) {
return null;
}
if (list.size() == 0) {
return null;
}
int count = list.size(); // 记录总数
int pageCount = 0; // 页数
if (count % pageSize == 0) {
pageCount = count / pageSize;
} else {
pageCount = count / pageSize + 1;
}
int fromIndex = 0; // 开始索引
int toIndex = 0; // 结束索引
if (pageNum != pageCount) {
fromIndex = (pageNum - 1) * pageSize;
toIndex = fromIndex + pageSize;
} else {
fromIndex = (pageNum - 1) * pageSize;
toIndex = count;
}
List pageList = list.subList(fromIndex, toIndex);
return pageList;
}
/**
* 响应请求分页数据
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static TableDataInfo getDataTable(List<?> list, Integer total)
{
TableDataInfo rspData = new TableDataInfo();
rspData.setCode(HttpStatus.SUCCESS);
rspData.setMsg("查询成功");
rspData.setRows(list);
rspData.setTotal(total);
return rspData;
}
}
2. 然后再需要用到的controller方法中使用(注意:如果在其他模块调用自定义分页方法,需要在pom文件中引入common模块依赖)
例如:
关键代码:
@GetMapping("/listbyactivityinfoid")
public TableDataInfo listbyactivityinfoid(PersonAppraiseWx personAppraiseWx)
{
List<PersonAppraiseWx> list = personAppraiseWxService.selectPersonAppraiseListbyactivityinfoid(personAppraiseWx);
//自定义分页
PageDomain pageDomain = TableSupport.buildPageRequest();
Integer pageNum = pageDomain.getPageNum();
Integer pageSize = pageDomain.getPageSize();
if (pageNum != null && pageSize != null){
TableDataInfo tableDataInfo = PageUtil.getDataTable(PageUtil.startPage(list,pageNum,pageSize),list.size());
// 如果list.size=0,将rows赋值为[]
// 解决前端list.size = 0,导致前台分页rows为null的报错问题
if (tableDataInfo.getRows() == null){
tableDataInfo.setRows(Arrays.asList(new String[]{}));
}
}else {
TableDataInfo tableDataInfo = new TableDataInfo();
int errorCode = 500;
String errorMessage = "分页发生错误";
tableDataInfo.setCode(errorCode);
tableDataInfo.setMsg(errorMessage);
return tableDataInfo;
}
}
9 问题:前端传分页参数为5,到后台接收到的分页参数为10。
解决:可能是前端传参错误,前端应该传query,而不是data。
10 若依导入功能实现
10.1添加导入按钮
代码:
<el-col :span="1.5">
<el-button
type="info"
plain
icon="el-icon-upload2"
size="mini"
@click="handleImport"
v-hasPermi="['examManager:dept:import']"
>导入</el-button>
</el-col>
10.2.添加导入的dialog弹窗
代码:
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
<el-upload
ref="upload"
:limit="1"
accept=".xlsx, .xls"
:headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport"
:disabled="upload.isUploading"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
:auto-upload="false"
drag
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip text-center" slot="tip">
<div class="el-upload__tip" slot="tip">
<el-checkbox v-model="upload.updateSupport" /> 是否更新已经存在的用户数据
</div>
<span>仅允许导入xls、xlsx格式文件。</span>
<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFileForm">确 定</el-button>
<el-button @click="upload.open = false">取 消</el-button>
</div>
</el-dialog>
10.3初始化时配置导入参数
代码:
// 导入参数
upload: {
// 是否显示弹出层(用户导入)
open: false,
// 弹出层标题(用户导入)
title: "",
// 是否禁用上传
isUploading: false,
// 是否更新已经存在的用户数据
updateSupport: 0,
// 设置上传的请求头部
headers: { Authorization: "Bearer " + getToken() },
// 上传的地址
url: process.env.VUE_APP_BASE_API + "/examManager/dept/importData"
},
10.4 导入的相关方法
代码:
/** 导入按钮操作 */
handleImport() {
this.upload.title = "部门导入";
this.upload.open = true;
},
/** 下载模板操作 */
importTemplate() {
this.download('examManager/dept/importTemplate', {
}, `dept_template_${new Date().getTime()}.xlsx`)
},
// 文件上传中处理
handleFileUploadProgress(event, file, fileList) {
this.upload.isUploading = true;
},
// 文件上传成功处理
handleFileSuccess(response, file, fileList) {
this.upload.open = false;
this.upload.isUploading = false;
this.$refs.upload.clearFiles();
this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果",
{ dangerouslyUseHTMLString: true });
this.getList();
},
// 提交上传文件
submitFileForm() {
this.$refs.upload.submit();
}
10.5 java domain实体类
10.6 controller层
代码:
/**
* 导入
*/
@Log(title = "招考单位管理", businessType = BusinessType.IMPORT)
// @PreAuthorize("@ss.hasPermi('examManager:dept:import')")
@PostMapping("/importData")
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
{
ExcelUtil<ExamDept> util = new ExcelUtil<ExamDept>(ExamDept.class);
List<ExamDept> deptList = util.importExcel(file.getInputStream());
String operName = getUsername();
String message = examDeptService.importExamDept(deptList, updateSupport, operName);
return success(message);
}
//模板生成
@PostMapping("/importTemplate")
public void importTemplate(HttpServletResponse response)
{
ExcelUtil<ExamDept> util = new ExcelUtil<ExamDept>(ExamDept.class);
util.importTemplateExcel(response, "招考单位数据");
}
10.7 service层
serviceImpl实现类
代码:
/**
* 导入数据
*
* @param deptList 部门数据列表
* @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据
* @param operName 操作用户
* @return 结果
*/
@Override
public String importExamDept(List<ExamDept> deptList, Boolean isUpdateSupport, String operName)
{
if (StringUtils.isNull(deptList) || deptList.size() == 0)
{
throw new ServiceException("导入用户数据不能为空!");
}
int successNum = 0;
int failureNum = 0;
StringBuilder successMsg = new StringBuilder();
StringBuilder failureMsg = new StringBuilder();
for (ExamDept examDept : deptList)
{
try
{
// 验证是否存在这个用户
ExamDept d = examDeptMapper.selectExamDeptByDeptName(examDept.getExamDeptName());
if (StringUtils.isNull(d))
{
BeanValidators.validateWithException(validator, examDept);
examDept.setCreateBy(operName);
examDept.setCreateTime(DateUtils.getNowDate());
examDeptMapper.insertExamDept(examDept);
successNum++;
successMsg.append("<br/>" + successNum + "、部门 " + examDept.getExamDeptName() + " 导入成功");
}
else if (isUpdateSupport)
{
BeanValidators.validateWithException(validator, examDept);
examDept.setExamDeptId(d.getExamDeptId());
examDept.setUpdateTime(DateUtils.getNowDate());
examDeptMapper.updateExamDept(examDept);
successNum++;
successMsg.append("<br/>" + successNum + "、部门 " + examDept.getExamDeptName() + " 更新成功");
}
else
{
failureNum++;
failureMsg.append("<br/>" + failureNum + "、部门 " + examDept.getExamDeptName() + " 已存在");
}
}
catch (Exception e)
{
failureNum++;
String msg = "<br/>" + failureNum + "、部门 " + examDept.getExamDeptName() + " 导入失败:";
failureMsg.append(msg + e.getMessage());
log.error(msg, e);
}
}
if (failureNum > 0)
{
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
throw new ServiceException(failureMsg.toString());
}
else
{
successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
}
return successMsg.toString();
}
11 若依富文本内容存到数据库后,回显到界面。
12 使用elementui的通知框回显若依富文本内容
效果:
代码:
13 导出excel单元格格式设置为文本
问题:导出excel,如果某列内容为过长的纯数字(例如:身份证号),导出显示正常,但是如编辑了这个单元格,就会将这个单元格内容变为计数,导致数据不准确。
解决:设置该单元格格式为文本,就可解决这个问题。
方法一:导出excel时,实现有数据的每一行的单元格格式为文本。(这时空白行的单元格格式都是默认的常规)。
代码实现:在ExcelUtil.java里,将addCell这个方法里的箭头所指向的代码注释掉,然后添加红框里的代码即可解决。
这里的样式是将表头所对应的列下的单元格都设置成了文本类型(单元格除外),并且内容居中。
如果要将表头也设置成文本,使用该方法也可以,不过要在生成表头的方法里修改。
代码如下
// 创建 CellStyle 对象并设置格式为文本
CellStyle textStyle = wb.createCellStyle();
DataFormat format = wb.createDataFormat();
textStyle.setDataFormat(format.getFormat("@"));
// 设置单元格内容居中对齐
textStyle.setAlignment(HorizontalAlignment.CENTER);
textStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 将文本格式的 CellStyle 应用到单元格
cell.setCellStyle(textStyle);
方法二:导出excel时,将表头下的每一列的单元格都设置问文本格式。
实现:1.在ExcelUtil.java中,修改createHeadCell方法,添加一个表头单元个数量的参数,然后加入红框内的代码。即可实现。
2. 在 writeSheet方法下,调用createHeadCell方法时,需要添加传参。
代码如下
// 创建 CellStyle 对象并设置格式为文本
CellStyle textStyle = wb.createCellStyle();
DataFormat format = wb.createDataFormat();
textStyle.setDataFormat(format.getFormat("@"));
// 设置单元格内容居中对齐
textStyle.setAlignment(HorizontalAlignment.CENTER);
textStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 设置表头下的每一列的单元格格式为文本,行数为200条
for (int i = 1; i < 200; i++) {
row = sheet.createRow(i);
for(int j = 0; j < size; j++){
Cell cell1 = row.createCell(j);
cell1.setCellStyle(textStyle);
}
}
注意:这里的行数如果设置过大,会导致导出失败,后台报错:ERROR c.h.c.u.p.ExcelUtil - [exportExcel,588] - 导出Excel异常Attempting to write a row[1] in the range [0,499] that is already written to disk.
14 导入导出excel常用注解
(1)@Excel( name = "名称", prompt = "excel点击表格时显示提示信息")
(2) @NotBlank(message = "不能为空") //导入时的非空校验
(3)@Length(max = 6,min = 1,message = "编码长度必须为1——6位") //导入时设置的长度校验
(4)导出excel时,字典反显注解
1)@Excel(name = "名称" ,dictType= "inout_status"),这种方式会随字典表的修改动态变化。
2)@Excel(name = "名称" ,readConverterExp = "1=是,0=否"),这种方式有种缺点就是在字典表修改后需要手动修改代码。
(5)校验BigDecimal类型的注解
@Digits(integer = 9, fraction=2, message = "amount格式不正确")
@DecimalMin(value = "0.00", message = "amount格式不正确")
@NotNull(message = "amount不为空")
private BigDecimal score;
注解说明:
1. @Digits:digit是数位的意思,这里的integer
意思整数最多有几位,fraction
意思小数最多有几位,只是划定了传入参数的范围,前端传值的时候可以用字符串(只要字符串里面都是数字就行)、数字;
2.@DecimalMin:decimal的最小值,传入参数必须大于等于value
里面的值
3.@NotNull:传入参数不为空,对于BigDecimal格式,用@NotNull
注解,如果传参是空字符串或者只有空格的字符串,也无法通过校验。
15 添加权限认证(前提:这张表需要有deptId字段或存userId的字段)
1.在后台serviceImpl实现类中,找到需要添加权限的方法,添加@DataScope(deptAlias = "t1",userAlias = "t1")注解。
例如:注解里的 t1 ,代表这个方法调执行的sql中,含有dept_id和user_id表的别名
@Override
@DataScope(deptAlias = "t1",userAlias = "t1")
public List<AbucoderBanners> selectAbucoderBannersList(AbucoderBanners abucoderBanners)
{
return abucoderBannersMapper.selectAbucoderBannersList(abucoderBanners);
}
2. 在mapper.xml中,为该表设置别名t1,并在sql语句的where里添加 ${params.dataScope}这个条件即可。
例如:
16.vue界面嵌入静态资源html
1)将静态资源代码放到public文件夹下。如图所示:
这里的web和build是我用到的静态资源存储js等相关文件夹,html存在web下。
2)使用<iframe>标签嵌套,例如:<iframe src="/web/viewer.html" width="100%" height="600px"></iframe>。
注意:这里的src取静态资源使用相对路径,不需要写public!!!
17 导入导出excel,实现字典项下拉框选择。
1)在实体类属性上的@excel注解里加入字典解析。如图:
2)在ExcelUtil.java类中,添加如下代码,实现下拉框回显。
代码如下:
//字典下拉框显示
if(StringUtils.isNotBlank(attr.dictType())){
try {
List<SysDictData> dataList = DictUtils.getDictCache(attr.dictType());
List<String> list = dataList.stream().map(SysDictData::getDictLabel).collect(Collectors.toList());
InvocationHandler invocationHandler = Proxy.getInvocationHandler(attr);
Field h = invocationHandler.getClass().getDeclaredField("memberValues");
h.setAccessible(true);
Map<String, Object> val = (Map<String, Object>) h.get(invocationHandler);
val.put("combo", list.toArray(new String[list.size()]));
h.set(invocationHandler, val);
} catch (Exception e) {
e.printStackTrace();
}
}
18 下载excel模板,单元格提示信息,默认只展示100行。
修改ExcelUtil.java下的 setDataValidation 方法,将红框内的数字改成需要的行数即可。
19.使用tinymce富文本编辑器。
请跳转到该文章查看。
若依前后端分离版本使用tinymce富文本编辑器-CSDN博客
20.前端界面js里获取当前用户id
1.打开ui界面中的src/store/modules/user.js文件,如图所示
2.加入红框中的代码
代码:
LOGIN_ID: (state, userId) => {
state.userId = userId
}
commit('LOGIN_ID', user.userId)
3.在界面的js里使用 如下代码即可获取到当前用户id
this.$store.state.user.userId
21.读取配置文件application.yml 中的数据
代码中取值:
22.前端el-table表格展示日期时间,显示12小时制,而不是24小时制。
问题:实体类中日期转换格式 hh
解决:将实体类中日期转换格式 hh改成HH即可