智能商贸系统总结

day 1
集成Spring +SpringMVC+SpringDataJpa
1 .创建maven项目 配置pom.xml文件,导入整个项目需要用到的jar包
2. 配置applicationContext.xml文件 配置Spring注解扫描,连接池,集成hibernate的jpa功能,配置 JPA事务
3. 使用jpa实现对数据库的持久化操作,配置核心文件persistence.xml
4. 提取一个分页类,用于对查询数据的分页
5. jpa与jdbc的优缺点
6. 配置多表的映射关系配置
7. 抽取工具类 BaseDomain BaseTest JpaRepostory Basequery head.jsp
问题难点总结:
高级查询
easyui的增加,删除,修改操作,dialog会话框数据回显,layout布局,左侧菜单的加载
部门,头像 的 显示
8. 解决no session的问题

<!-- 加上OpenEntityManager -->
<filter>
    <filter-name>openEntity</filter-name>
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>openEntity</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

9 .解决 No serializer问题

创建一个新的类(重写com.fasterxml.jackson.databind.ObjectMapper)

package cn.itsource.pss.common;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

public class CustomMapper extends ObjectMapper {
    public CustomMapper() {
        this.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        // 设置 SerializationFeature.FAIL_ON_EMPTY_BEANS 为 false 对null的bean 不做序列化
        this.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    }
}

第二步:在applicationContext-mvc.xml中配置一下即可

<!-- Spring MVC 配置 -->
<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="supportedMediaTypes">
                <list>
                    <value>application/json; charset=UTF-8</value>
                    <value>application/x-www-form-urlencoded; charset=UTF-8</value>
                </list>
            </property>
            <!-- No serializer:配置 objectMapper 为我们自定义扩展后的 CustomMapper,解决了返回对象有关系对象的报错问题 -->
            <property name="objectMapper">
                <bean class="cn.itsource.pss.common.CustomMapper"></bean>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

显示效果图
在这里插入图片描述**day 2 **

  1. 添加或修改employee表,用户名重复验证 checkName
  2. 添加用户,重复输入密码的验证
  3. 修改操作,因为我们没有修改图片,导致数据丢失问题的解决方法
先查询数据库,获取持久状态的对象,然后把页面的数据set到对象里面
(这种方案也是用得比较多的一种方案)
Employee tempEmployee = employeeService.get(employee.getId());
//需要修改的值就从页面里面的employee放入tempEmployee
tempEmployee.setUsername(employee.getUsername());
employeeService.save(tempEmployee);

  1. 修改部门信息遇到的 n -to -n 问题
    解决方案,将关联对象设置为 null;
  2. velocity 模板技术,与easycode代码生成器

day3

  1. shiro 身份认证,与权限
  2. 自定义realm 集成 AuthorizingRealm 就可以操作身份认证,跟权限
  3. MD5 密码加密,加盐 抽取工具类UtilMD5,给数据库所有的密码加密加盐,后面的添加或修改操作,密码都需要加密
  4. 实现登录验证,跟权限拦截
  5. 绑定回车键登录事件
  6. 解决登录过期,登录页面嵌套的问题
// 检查自己是否是顶级页面
if (top != window) {// 如果不
是顶级
    //把子页面的地址,赋值给顶级页面显示
    window.top.location.href = window.location.href;
}
  1. 展示用户名与注销登录操作
 <shiro:user>
            欢迎[<shiro:principal />]登录,<a href="${pageContext.request.contextPath}/logout">退出</a>
 </shiro:user>

  1. 角色管理,修改权限的操作,实现如下面的效果
    在这里插入图片描述双击右边的一行,添加到左边表格,不能重复添加,双击左边的,移除行
    注意这里修改操作的数据回显问题

day4
1. UserContext:设置与拿到当前登录用户
2. 查询登录的用户的权限,将权限信息以固定格式存入到map 将map配置 给shiro

public Map<String,String> createFilterChainDefinitionMap(){

    Map<String, String> filterChainDefinitionMap = new LinkedHashMap();
    //注:对于一些不登录也可以放行的设置(大家可以根据实际情况添加)
    filterChainDefinitionMap.put("/login","anon");
    filterChainDefinitionMap.put("*.js","anon");
    filterChainDefinitionMap.put("*.css","anon");
    filterChainDefinitionMap.put("/css/**","anon");
    filterChainDefinitionMap.put("/js/**","anon");
    filterChainDefinitionMap.put("/easyui/**","anon");
    filterChainDefinitionMap.put("/images/**","anon");

    filterChainDefinitionMap.put("/logout","logout"); //不登录也可以访问
    //这个值之后从数据库中查询到【用户-角色-权限-资源】
    //从数据库拿到数据,放到咱们的Map中
    //1.拿到所有权限
    List<Permission> permissions = permissionService.findAll();
    //2.遍历权限,拿到权限 资源
    for (Permission permission : permissions) {
        String url = permission.getUrl();//资源
        String sn = permission.getSn();//权限
        //把路径与资源放到拦截中去
        filterChainDefinitionMap.put(url,"yxbPerms["+sn+"]");
    }
    filterChainDefinitionMap.put("/**","authc");
    return  filterChainDefinitionMap;

}

实现不同的登录用户权限不一样,可以执行的操作也不一样
3. 解决没有权限发送ajax请求,返回页面的问题
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190817231008670.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3ByaW1hcnlrZXkxMjM=,size_16,color_FFFFFF,t_70)解决方式,判断如果发送的是ajax请求【请求头】,出现异常就返回  ‘没有权限’
	自定义过滤器	
public class ItsourceYxbPermissionsAuthorizationFilter extends PermissionsAuthorizationFilter {

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
        Subject subject = this.getSubject(request, response);
        if (subject.getPrincipal() == null) {
            //没有登录成功后的操作
            this.saveRequestAndRedirectToLogin(request, response);
        } else {
            //登录成功后没有权限的操作
            //1.转成http的请求与响应操作
            HttpServletRequest httpRequest = (HttpServletRequest) request;
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            //2.根据请求确定是什么请求
            String xRequestedWith = httpRequest.getHeader("X-Requested-With");
            if (xRequestedWith != null &&"XMLHttpRequest".equals(xRequestedWith)) {
                //3.在这里就代表是ajax请求
                //表示ajax请求 {"success":false,"message":"没有权限"}
                httpResponse.setContentType("text/json; charset=UTF-8");
                httpResponse.getWriter().print("{\"success\":false,\"msg\":\"没有权限\"}");
            }else {
                String unauthorizedUrl = this.getUnauthorizedUrl();
                if (StringUtils.hasText(unauthorizedUrl)) {
                    WebUtils.issueRedirect(request, response, unauthorizedUrl);
                } else {
                    WebUtils.toHttp(response).sendError(401);
                }
            }
        }
        return false;
    }

}
 <!-- 引用自定义的权限过滤器 -->
    <property name="filters">
        <map>
            <entry key="yxbPerms" value-ref="yxbPermissionsAuthorizationFilter"></entry>
        </map>
    </property>
</bean>

<!-- 配置自定义权限过滤器 -->
<bean id="yxbPermissionsAuthorizationFilter" class="cn.itsource.yxb.shiro.filter.ItsourceYxbPermissionsAuthorizationFilter"></bean>


  1. 不同的登录用户的菜单读取
    构建tree需要的json格式,注意理解构建父菜单与子菜单的方法

  2. 没有操作权限,就不显示相应的功能键
    day5

  3. 使用poi完成Excel的创建于读取

  4. easypoi的导出功能实现
    相关的注解 @Excel(name=“用户名”) @Excel(name=“邮件”,width = 25)
    导入图片@Excel(name = “头像”,type = 2,savePath = “/images/head”,height = 23)

  5. 导入功能实现

  6. 自带的注解验证 @NotNull(message = “用户名不为空”)
    @Max(value = 80,message = “max 最大值不能超过80”)

  7. 为了解决用户名重名问题,我们还需要自定义验证【自定义的类中写验证规则】
    实现IExcelVerifyHandler接口 扫描它,把它交给Spring管理

  8. 数据字典 系统的初始数据
    day6

  9. 自定义产品模块 【增删改查功能】

  10. 产品的图片,大小图片的显示问题

  11. 颜色显示 【span】

  12. 添加修改功能产品类型 产品品牌的回显

@Query("select o from Producttype o where o.parent.id is not null")
List<Producttype> findChildren();

<tr>
    <td>类型:</td>
    <td>

        <input  class="easyui-combobox" name="types.id"
                data-options="groupField:'group',valueField:'id',textField:'name',panelHeight:'auto',url:'/util/findChildren'">
    </td>
</tr>

  1. 删除和修改需要删除原来的 大小图片
  2. 上传的 图片需要使用工具压缩出小图片
    效果展示
    在这里插入图片描述
    day7
    采购模块 模型图
    在这里插入图片描述 1. 参构订单 与订单详情表之间配置强级联 和孤儿删除
  3. 日期时间,配置注解如下
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
public Date getVdate() {
    return vdate;
}

@DateTimeFormat(pattern = "yyyy-MM-dd")
public void setVdate(Date vdate) {
    this.vdate = vdate;
}
	这里配置错误会导致保存数据时类型不一致,前台报400错误
  1. 状态信息的显示 0 :待审 1:已审 -1:作废
function formatStatus(action) {
    var data = {
        0:"<div style='color:red;'>待审</div>",
        1:"<div style='color: green'>已审</div>",
        "-1":"<div><s>作废</s></div>"
    };
    return data[action];
}

  1. 订单管理页面的高级查询,这里需要注意,如果查询的起始时间与结束时间是同一天,
    需要在后台对结束时间 +1天
public Specification createSpecification(){
    //如果日期不为空,结束日期加1
    Date tempDate = null;
    if(endDate!=null){
        tempDate = DateUtils.addDays(endDate, 1);
    }

    //根据条件把数据返回即可
    Specification<Purchasebill> spec = Specifications.<Purchasebill>and()
            .eq(status!=null,"status",status )
            .ge(beginDate!=null, "vdate",beginDate) //大于等于
            .lt(endDate!=null, "vdate",tempDate) //小于
            .build();

    return spec;
}

  1. 添加,修改功能实现需要使用http://www.easyui-extlib.com/ ->Datagrid-Edit -单元格编辑
    效果如下
    在这里插入图片描述
    这里注意上面三个下拉列表【combobox】数据的回显 整个dialog是一个form表单,下面部分是一个 datadrid数据表格
    保存数据时需要提交额外的参数
save:function () {
    var url  = "/purchasebill/save";
    var id = $("#purchasebillId").val();
    if(id){
        url = "/purchasebill/update?cmd=update";
    }
    purchasebillForm.form('submit', {
        url:url,
        onSubmit: function(param){
            //这里加上param这个参数,为它设置值,就可以做额外的参数提交
            //拿到当前页的所有参数 并进行名称修改 items[0].product.id /item[1].price,...
            var rows = gridItems.datagrid('getRows');
            //param.items[0].product.id = 1;
            for (var i = 0; i < rows.length; i++) {
                var rowData = rows[i];
                param["items[" + i + "].product.id"] = rowData.productId.id;
                param["items[" + i + "].price"] = rowData.price;
                param["items[" + i + "].num"] = rowData.num;
                param["items[" + i + "].descs"] = rowData.descs;
                //完成当前 这一行数据的验证
                if(!gridItems.datagrid("validateRow",i)){
                    alert("你的明细数据有还有问题!");
                    return false;
                }
            }
            return purchasebillForm.form("validate");

day8

  1. 订单详情报表 需要使用3. EasyUI(datagrid-groupview) 插件 效果如下
    在这里插入图片描述

  2. 创建一个报表的类,其中有一个分组字段 private String groupField = “”; //分组字段

  3. 带条件查询就是拼接sql 的查询条件
    注意,jpql中 order by后面不要跟 ? 这里有个bug
    还要注意拼接出来的sql 语句中,每个单词之间的缺少空格可能会导致sql语句失效

  4. HighChart 统计图
    这个引入相关的支持,扒下源码,构建它需要的数据格式就行
    效果如下
    在这里插入图片描述

//查询到图表需要的值,并且封装成相应的格式[{name:aa,y:43},{name:bb,y:20},...]
public List<Map> findCharts(PurchaseBillItemQuery itemQuery){
    List<Map> chartList = new ArrayList<>();
    //完成查询的JPQL拼接
    String jpql = "select "+itemQuery.getGroupBy()+",sum(o.amount) from PurchaseBillItem o "+itemQuery.getWhereSql()+" group by "+itemQuery.getGroupBy();
    //System.out.println(jpql);
    List<Object[]> list = findByJpql(jpql, itemQuery.getParams().toArray());
    for (Object[] objects : list) {
        Map map = new HashMap();
        map.put("name",objects[0]);
        map.put("y",objects[1]);
        chartList.add(map);
    }
    return chartList;
}

day9

  1. 入库操作:涉及到入库订单,和入库订单详情这两张表的数据更新
  2. 审核操作:涉及到仓库表,即时库存表的数据更新
    即时库存表,同一产品同一仓库,如果没有这一产品,就直接保存
    如果有这一产品,需要使用加权平均操作
  3. 解决spring测试时没有tomcat环境 的el 问题
<dependency>
    <groupId>javax.el</groupId>
    <artifactId>javax.el-api</artifactId>
    <version>2.2.4</version>
</dependency>
<dependency>
    <groupId>org.glassfish.web</groupId>
    <artifactId>javax.el</artifactId>
    <version>2.2.4</version>
</dependency>

  1. 到库存不足时,需要预警
    我们使用Quartz 来预警操作
  2. Spring发送邮件
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值