RuoYi前后端分离版本使用过程遇到的问题及解决。

目录

1验证码失效

2 点击注册提示登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示'。

3 弹出错误信息:用户账号不能为空 

4 定时任务

5 字典项问题

6 问题:生成代码form表单有值,但是校验不通过。

7 问题:根据上边的下拉框选择规则类型,1:字典 2:数字 3:文字 ;判断现编规则值的填报类型(下拉框还是输入框) 

8 问题:后端若依controller层自带的startPage,分页,只会作用于第一次查询。

9 问题:前端传分页参数为5,到后台接收到的分页参数为10。

10 若依导入功能实现

11 若依富文本内容存到数据库后,回显到界面。

12 使用elementui的通知框回显若依富文本内容

13 导出excel单元格格式设置为文本

方法一:导出excel时,实现有数据的每一行的单元格格式为文本。(这时空白行的单元格格式都是默认的常规)。代码实现:在ExcelUtil.java里,将addCell这个方法里的箭头所指向的代码注释掉,然后添加红框里的代码即可解决。​编辑

方法二:导出excel时,将表头下的每一列的单元格都设置问文本格式。

14 导入导出excel常用注解(1)@Excel( name = "名称", prompt = "excel点击表格时显示提示信息")

15 添加权限认证(前提:这张表需要有deptId字段或存userId的字段)

16.vue界面嵌入静态资源html

17 导入导出excel,实现字典项下拉框选择。

18 下载excel模板,单元格提示信息,默认只展示100行。

19.使用tinymce富文本编辑器。


记录使用若依框架开发时遇到的一系列问题,以后遇到新问题会随时更新这篇文章。欢迎各位小伙伴私聊补充问题及解决办法。

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" 赋值;
问题:生成代码form表单有值,但是校验不通过。

解决:查看前端data初始化值和表单清空form内容处,有没有该变量。

7 问题:根据上边的下拉框选择规则类型,1:字典 2:数字 3:文字 ;判断现编规则值的填报类型(下拉框还是输入框) 

出现问题:如果规则值类型都绑定的是一个approveValue变量,界面中修改规则类型,从字典改为数字或者文字,页面控制台就会报错

 解决:在data的form里新建一个变量,来替换输入框中绑定的值,然后在提交form时,再将新定义的变量的值,赋值给form.approveValue即可。

问题:后端若依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即可

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vue Router是Vue.js官方的路由管理器。它和Vue.js核心深度集成,让构建单页面应用变得易如反掌。在Vue3中,使用Vue Router也非常简单,下面是使用Vue Router的基本步骤: 1. 安装Vue Router 在终端中执行以下命令安装Vue Router: ``` npm install [email protected] ``` 2. 创建Vue Router实例 在main.js中导入Vue Router并创建Vue Router实例: ```javascript import { createApp } from 'vue' import App from './App.vue' import router from './router' const app = createApp(App) app.use(router) app.mount('#app') ``` 在router.js中创建Vue Router实例: ```javascript import { createRouter, createWebHistory } from 'vue-router' import Home from './views/Home.vue' import About from './views/About.vue' const routes = [ { path: '/', component: Home }, { path: '/about', component: About } ] const router = createRouter({ history: createWebHistory(), routes }) export default router ``` 3. 创建路由组件 在views文件夹中创建两个路由组件: ```vue <template> <div> <h1>Home</h1> <p>Welcome to my home page!</p> </div> </template> ``` ```vue <template> <div> <h1>About</h1> <p>About me!</p> </div> </template> ``` 4. 配置路由链接 在App.vue中添加路由链接: ```vue <template> <div> <h1>My App</h1> <nav> <router-link to="/">Home</router-link> <router-link to="/about">About</router-link> </nav> <router-view></router-view> </div> </template> ``` 5. 运行应用 在终端中执行以下命令启动应用: ``` npm run serve ``` 打开浏览器访问http://localhost:8080,点击路由链接即可看到对应的路由组件。 以上就是使用Vue Router的基本步骤。需要注意的是,在Vue3中,Vue Router的创建方式和Vue2有所不同,需要使用createRouter和createWebHistory等函数创建Vue Router实例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值