个人开发文档

96 阅读3分钟

1. 登录

业务逻辑:

​ 管理者登录 (roles)

​ 系统管理员登录(admin)

jquery 开始函数

       $(function(){})

导入静态页面:

原本路径

原本路径
../static/CSS/left.css

实际导入路径
../CSS/left.css

idea 多选:ctrl + shift + alt

=======================================================================================================

2.服务管理

  • 销售经理 : 创建服务、处理服务、反馈服务、查看服务归档

  • 销售主管:分配服务、查看服务归档

指派人:销售主管指派客户经理

服务管理业务流程:

​ 客户经理创建服务, 销售主管分配服务(唯一),客户经理接受指派的服务,处理服务,反馈服务(只有处理完的服务才能进行反馈==>上门反馈,电话反馈 ),最后归档

=======================================================================================================

3.数据库说明

数据库说明:CustomServices表,字段 : CSState

1=新创建
2=已分配
3=已处理
4=已归档

数据库: 角色ID --> 相当于角色的身份,如系统管理员,销售主管

users表中角色表字段说明: (roleID字段)

0系统管理员身份
1销售主管
2客户经理
  • 管理员可以进用户界面也可以进管理员界面,用户只能 进用户界面

字段说明:

userlname登录名 (必须唯一)
username真实姓名

权限的第三个表只是给开发人员看的,角色要行驶什么权限,只要在Ctroller中添加注解,表示什么角色能够操作 (好像也不对)

=======================================================================================================

4.查漏补缺(问题记录)

1.layui的使用

监听表单事件

        $('.layui-form').on('submit',function(data){
          alert(1)
        })

2.存一个session后台所有页面都能拿到吗?

答案: 全局可以拿到session的值,thymleaf中,使用文本拿值,用的是text而不是test

3.select的使用

                <select id="select" >
                    <option selected   th:each="n:${listname}" th:value="${n.userID}" th:text="${n.userName}">
                    </option>

                </select>
    
    获取select 选中的值
    
    var options=$("#select option:selected").val();
    alert(options)

4.thymleaf(方法中获取id)

使用thymleaf传数据给后台,一定要跳页面,不然报错

thymleaf传值给onclick方法

<a  th:οnclick="'javascript:del('+this+','+${user.id}+');'" ></a>
<script>
   function  del(obj,id) {
      alert(id);
                      }
</script>

=======================================================================================================

1.ifranme框架的使用

​ 绑定是用target 属性

2.获取系统时间

 - 日期转字符串 format方法
		java.util.Date day=new Date();
        SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = sdf.format(day);

- 字符串转日期 parse方法
        SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
        String dateInString = "22-12-2000";

        try {

            Date date = formatter.parse(dateInString);
            System.out.println(date);
            System.out.println(formatter.format(date));

        } catch (ParseException e) {
            e.printStackTrace();
        }

    }

3.获取session的值

先注入HttpServletRequest,在取值

    @Autowired
    HttpServletRequest request;

request.getSession().getAttribute("user");

4.三种参见的遍历集合方式

	//2. 增强for(String str : arrays)
    log.info("=================增强for(String str : arrays)遍历=====================");
    for (String str : arrays) {
      log.info(str);
    }
 
    //3. list.forEach((str) -> xxxxx)
    log.info("=================arrays.forEach((str) -> xxxxx)遍历===================");
    arrays.forEach(str -> log.info(str));
 
    //4. 使用Iterator迭代器遍历
    log.info("=================使用Iterator迭代器遍历================================");
    Iterator<String> it = arrays.iterator();
    while (it.hasNext()) {
      String str = (String) it.next();
      log.info(str);
    }
  • 找list对象中的某个属性,给list定义泛型,就可以用get方法了

5.DTO的使用

不得不说,真的好用

6.重定向

  • 重定向是用来跳地址的,Sting直接写是用来跳页面的

7.thymleaf中表达的使用

  • thymleaf中有关于表单的使用,但是一般发表单普通的就能实现效果,暂时没必要折腾

  • // input 类型是button也发不了表单
    <input type="button" value="确定"/>
    
  • thymleaf中发送数据给后台的方法

- 啊链接
<a th:href="'/customservices/lookfile/' +${e.csid}">
    
- 拼接
        url="/customservices/fpservice?csid="+id+"&userID="+userID

8.踩坑----mysql

发现了一个报莫名奇妙的空指针异常,反复检查,代码 感觉,没什么问题,结果真实代码没问题,而是数据库出了问题,

有时间添加数据库的时候多按了一个tab键,再随一个ctrl+s就保存了一个空对象,这就是导致空指针的根本原因,就算是删了这条数据,也会有所影响,如果再次发生这种事情,一定要注意,怎么查看,点击数据表中的设计,查看当前字段是否与数据库的条数是对应的

9.list集合通用方法

package com.zking.util;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import java.util.ArrayList;
import java.util.List;

public class PageListUtils {
    /**
     * 分页函数
     * @param currentPage   当前页数
     * @param pageSize  每一页的数据条数
     * @param list  要进行分页的数据列表
     * @return  当前页要展示的数据
     */
    public Page getPages(Integer currentPage, Integer pageSize, List list) {
        Page page = new Page();
        int size = list.size();

        if(pageSize > size) {
            pageSize = size;
        }

        // 求出最大页数,防止currentPage越界
        int maxPage = size % pageSize == 0 ? size / pageSize : size / pageSize + 1;

        if(currentPage > maxPage) {
            currentPage = maxPage;
        }

        // 当前页第一条数据的下标
        int curIdx = currentPage > 1 ? (currentPage - 1) * pageSize : 0;

        List pageList = new ArrayList();

        // 将当前页的数据放进pageList
        for(int i = 0; i < pageSize && curIdx + i < size; i++) {
            pageList.add(list.get(curIdx + i));
        }

        page.setCurrent(currentPage).setSize(pageSize).setTotal(list.size()).setRecords(pageList);
        return page;
    }

}


10.int向上取整 的方法,三目运算符

        int ceil = size / pagesize + (size % pagesize == 0 ? 0 : 1);

11.获取name值的方式(一定要导入jquery啊)

        var page = $("input[name='page']").val();

12.数组越界异常

java.lang.IndexOutOfBoundsException: toIndex = 4

13.关于模板的分角色登录

  • 这个模板的特点,就是可以分角色进行登录,但是点击管理员登录的时候,会将用户登录的模板切到管理员那边,管理员那边又自己写了登录的界面,如何处理这个问题呢?

    正解: 使用z-index显示等级来处理,完美解决

14.thymleaf结合vue使用技巧

  • 如果使用thymleaf保存后台数据,那么session应该在后台保存,如果存前台会导致thymleaf报错,找不到保存的数据

15.前后端不分离的情况下使用vue的小细节

  1. 是同一个域名,但还是要配置跨域,否则报错

  2. 后端登录的Controller要使用@ResponseBody注解,拿参数使用@RequirstBody注解,否则报错

    报错信息

    org.thymeleaf.exceptions.TemplateInputException: Error resolving template "xxx/xxx", template might not exist or might not be accessible by any of the configured Template Resolvers
    	at org.thymeleaf.engine.TemplateManager.resolveTemplate(TemplateManager.java:865) ~[thymeleaf-3.0.2.RELEASE.jar:3.0.2.RELEASE]
    	at org.thymeleaf.engine.TemplateManager.parseAndProcess(TemplateManager.java:608) ~[thymeleaf-3.0.2.RELEASE.jar:3.0.2.RELEASE]
    	at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1087) [thymeleaf-3.0.2.RELEASE.jar:3.0.2.RELEASE]
    	at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1061) [thymeleaf-3.0.2.RELEASE.jar:3.0.2.RELEASE]
    

16.避雷之使用别人的html---注意事项

  • 如果页面展示不出来东西,但是有页面,解决办法之一,把别人的页面删除,重新加载一个

17.vue中v-if的使用,-- 插槽实现

        <el-table-column
                prop="cusState"
                label="客户状态">
        <template slot-scope="s">
            <p v-if="s.row.cusState == '1'">正常</p>
            <p v-if="s.row.cusState == '2'">流失</p>
<!--            <p v-if="cusState == '2'">流失</p>-->
        </template>
        </el-table-column>

18.访问templates中的页面

  • templates目录里存放的html页面,不能通过url直接访问,需跳转后台才能访问,或配置静态资源路径

19.前后端分离条页面的方式

  1. 要么是把数据传如前台,再通过异步返回后台跳转页面
  2. 使用thymleaf语法进行条页面
  • 误区

    1. 跨域和正常发请求一定要清楚区别,登录不进去就时这个原因
    2. vue和其他界面可以混合使用,就是不要跨域,不然拿到的session值不一样

20.退出登录如何跳页面

  • 使用a链接,location跳转到主页,一般这样处理
<span style="cursor: pointer" onclick="top.location='/zhuxiao'" ><img src="images/main_20.gif" style="border:solid 0px red"/></span>

onclick="top.location='/zhuxiao'"

21.文件的上传与下载

导包:文件上传与下载的所有依赖

 <!-- 导出Excel所需依赖 -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.0.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>4.0.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.0.0</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.3.8</version>
        </dependency>
  1. 下载

一种是刚哥的方法,简单,要指定上传路径

另一种是,网上的一种方法, 可以自定义,虽然有点复杂,但是很实用

  1. 上传

刚哥提供一种方法

elementui使用了一种方法

<div id="app">

    <el-upload action="/customservices/importExcel/"
               :show-file-list="false" accept="xlsx"
               :on-success="handleImportSuccess"
               :on-error="handleImportError"
               style="display: inline-block;margin-right: 5px" class="eform">
        <el-button type="primary"> 批量导入 <i class="el-icon-bottom"></i></el-button>
    </el-upload>

</div>
            
<script>
    var vue = new Vue({
        el:'#app',
        data:{

        },
        methods:{
            handleImportSuccess() {
                this.$message.success("上传成功")
            },
            handleImportError() {
                this.$message.error("上传失败")
            }
        }
    })
</script>
@RequestMapping("importExcel")
    @ResponseBody
    public void importExcel(MultipartFile file) {
        boolean flag = true;
        try {
            InputStream in = file.getInputStream();
//        //io流给ExcelReader
            ExcelReader excelReader = ExcelUtil.getReader(in);
            // 从excel表中得到的对象集合
            List<Map<String, Object>> readAll = excelReader.readAll();
            System.out.println(excelReader);
            System.out.println(readAll);
            //需要加入两个表,第一个用户信息表 第二个sys_user_role 用户信息关系表
            for (int i = 0; i < readAll.size(); i++) {
                // 创建时间
                java.util.Date day = new Date();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String format = sdf.format(day);
                // 创建人id

                Users user = (Users) request.getSession().getAttribute("user");

                Integer userID = user.getUserID();
//拿到字段中对应的值
                readAll.get(i).get("客户编号");
                readAll.get(i).get("服务类型");
                readAll.get(i).get("服务概要");
                readAll.get(i).get("详细信息");

                Customservices customservices = new Customservices();
                customservices.setCusID(readAll.get(i).get("客户编号").toString());
                customservices.setStid(Integer.parseInt(readAll.get(i).get("服务类型").toString().toString()));
                customservices.setCSTitle(readAll.get(i).get("服务概要").toString());
                customservices.setCSDesc(readAll.get(i).get("详细信息").toString());

                customservices.setCSCreateID(userID);
                customservices.setCSCreateDate(format);
                mapper.insert(customservices);

            }
        } catch (IOException e) {
            flag = false;
            e.printStackTrace();
        } finally {

        }
    }

22.滑动验证

=======================================================================================================

5.报错情况

1、已解决

  1. 如果,登录跳转不到Controller,表达发送请求没问题

解决,检查是否有脚本阻止了表单提交事件

  1. 啊啊啊,thymleaf中的属性是区分大小写的,我吐了啊(花了一个小时)
  2. 前台一定要有提示,使用layui接受返回的结果集进行提示

2、未解决

(已解决)

使用自定义mapper查询用户,明明查的是对象,输出的确实一个属性

原因: 自定义mapper传的泛型为String,我想要的类型是Users,所以不会自动匹配,这总东西,最好是用通用mapper写

不会出错,虽然复杂一点,但能直接解决问题

6.项目流程(答辩的时候可以上台讲的)

1.服务处理

业务逻辑:查询的时候就进行账号筛选,是本账号且有被分配服务的才会显示,没有分配则不显示

项目中layui的统一引用方法

    <link href="../layui/css/layui.css" rel="stylesheet" type="text/css" />
    <script src="../layui/layui.js"></script>
  • 服务归档中查询的实现-- 使用了嵌套for,定义一个新集合,将两个集合的字段重新add到新集合再返回给前台

7.从字符串中截取数据(小数或者整数)

    //取字符串中的数字
    public static String checkNum(String str) {
//        String str = "abcd123和345.56jia567.23.23jian345and23or345.56";
        //先判断有没有整数,如果没有整数那就肯定就没有小数
        Pattern p = Pattern.compile("(\\d+)");
        Matcher m = p.matcher(str);
        String result = "";
        if (m.find()) {
            Map<Integer, String> map = new TreeMap();
            Pattern p2 = Pattern.compile("(\\d+\\.\\d+)");
            m = p2.matcher(str);
            //遍历小数部分
            while (m.find()) {
                result = m.group(1) == null ? "" : m.group(1);
                int i = str.indexOf(result);
                String s = str.substring(i, i + result.length());
                map.put(i, s);
                //排除小数的整数部分和另一个整数相同的情况下,寻找整数位置出现错误的可能,还有就是寻找重复的小数
                // 例子中是排除第二个345.56时第一个345.56产生干扰和寻找整数345的位置时,前面的小数345.56会干扰
                str = str.substring(0, i) + str.substring(i + result.length());
            }
            //遍历整数
            Pattern p3 = Pattern.compile("(\\d+)");
            m = p3.matcher(str);
            while (m.find()) {
                result = m.group(1) == null ? "" : m.group(1);
                int i = str.indexOf(result);
                //排除jia567.23.23在第一轮过滤之后留下来的jia.23对整数23产生干扰
                if (String.valueOf(str.charAt(i - 1)).equals(".")) {
                    //将这个字符串删除
                    str = str.substring(0, i - 1) + str.substring(i + result.length());
                    continue;
                }
                String s = str.substring(i, i + result.length());
                map.put(i, s);
                str = str.substring(0, i) + str.substring(i + result.length());
            }
            result = "";
            for (Map.Entry<Integer, String> e : map.entrySet()) {
                result += e.getValue() + ",";
            }
            result = result.substring(0, result.length()-1);
        } else {
            result = "";
        }
        return result;
    }