OA系统_02 | Eloise's Paradise
0%

OA系统_02

张一明架构师前置知识- Chapter 12

OA 用户模块 02

列表分页

service

1
2
3
4
5
6
7
8
public PageInfo<Account> findByPage(int pageNum, int pageSize) {

PageHelper.startPage(pageNum, pageSize);

AccountExample example = new AccountExample();
PageInfo<Account> pageInfo = new PageInfo<Account>(accMapper.selectByExample(example ),5);
return pageInfo;
}

前端

1
2
3
4
5
<li><a th:href="@{'/account/list?pageNum=' + ${accountList.prePage}}">上一页</a></li>

<li th:each="num : ${accountList.navigatepageNums}"><a th:href="@{'/account/list?pageNum='+${num}}">[[${num}]]</a></li>

<li><a th:href="@{'/account/list?pageNum=' + ${accountList.nextPage}}">下一页</a></li>

增删改查

删除

html

1
<a th:href="@{'javascript:deleteUser('+${account.id}+');'}" >删除</a>

JS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function deleteUser(id){

var url = "/account/deleteAccount";
var args = {accountId:id};
$.post(url,args,function(data){

console.log(data)
if(data.code == 200){

window.location.reload();
}else {

alert("操作失败:" + data.msg)
}
})

}

确认

纯js
1
2
3
4
5
6
7
8
9
var r=confirm("Press a button")
if (r==true)
{
console.log("You pressed OK!")
}
else
{
console.log("You pressed Cancel!")
}
模态窗口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19


<div id="com-alert" class="modal" style="z-index:9999;display: none;" >
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h5 class="modal-title"><i class="fa fa-exclamation-circle"></i> [Title]</h5>
</div>
<div class="modal-body small">
<p>[Message]</p>
</div>
<div class="modal-footer" >
<button type="button" class="btn btn-primary ok" data-dismiss="modal">[BtnOk]</button>
<button type="button" class="btn btn-default cancel" data-dismiss="modal">[BtnCancel]</button>
</div>
</div>
</div>
</div>
js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
$(function () {  
window.Modal = function () {
var reg = new RegExp("\\[([^\\[\\]]*?)\\]", 'igm');
var alr = $("#com-alert");
var ahtml = alr.html();

var _tip = function (options, sec) {
alr.html(ahtml); // 复原
alr.find('.ok').hide();
alr.find('.cancel').hide();
alr.find('.modal-content').width(500);
_dialog(options, sec);

return {
on: function (callback) {
}
};
};

var _alert = function (options) {
alr.html(ahtml); // 复原
alr.find('.ok').removeClass('btn-success').addClass('btn-primary');
alr.find('.cancel').hide();
_dialog(options);

return {
on: function (callback) {
if (callback && callback instanceof Function) {
alr.find('.ok').click(function () { callback(true) });
}
}
};
};

var _confirm = function (options) {
alr.html(ahtml); // 复原
alr.find('.ok').removeClass('btn-primary').addClass('btn-success');
alr.find('.cancel').show();
_dialog(options);

return {
on: function (callback) {
if (callback && callback instanceof Function) {
alr.find('.ok').click(function () { callback(true) });
alr.find('.cancel').click(function () { return; });
}
}
};
};

var _dialog = function (options) {
var ops = {
msg: "提示内容",
title: "操作提示",
btnok: "确定",
btncl: "取消"
};

$.extend(ops, options);

var html = alr.html().replace(reg, function (node, key) {
return {
Title: ops.title,
Message: ops.msg,
BtnOk: ops.btnok,
BtnCancel: ops.btncl
}[key];
});

alr.html(html);
alr.modal({
width: 250,
backdrop: 'static'
});
}

return {
tip: _tip,
alert: _alert,
confirm: _confirm
}

}();
});
function showTip(msg, sec, callback){
if(!sec) {
sec = 1000;
}
Modal.tip({
title:'提示',
msg: msg
}, sec);
setTimeout(callback, sec);
}

/**
* 显示消息
* @param msg
*/
function showMsg(msg, callback){
Modal.alert({
title:'提示',
msg: msg,
btnok: '确定'
}).on(function (e) {
if(callback){
callback();
}
});
}

/**
* 模态对话框
* @param msg
* @returns
*/
function showConfirm(msg,callback){
//var res = false;
Modal.confirm(
{
title:'提示',
msg: msg,
}).on( function (e) {
callback();
//res=true;
});
//return res;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function deleteUser(id){

var url = "/account/deleteAccount";
var args = {accountId:id};

showConfirm("确认要删除吗?", function() {
$.post(url,args,function(data){

console.log(data)
if(data.code == 200){

window.location.reload();
}else {

alert("操作失败:" + data.msg)
}
})
});
}
代码调用
1
2
3
showTip("haha", 1000, function() {});
showMsg("haha", function() {});
showConfirm("haha", function() {});

表单校验

文件上传

1
2
3


spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:D:/upload/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@RequestMapping("/fileUploadController")
public String fileUpload (MultipartFile filename,String password) {
System.out.println("password:" + password);
System.out.println("file:" + filename.getOriginalFilename());
try {

File path = new File(ResourceUtils.getURL("classpath:").getPath());
File upload = new File(path.getAbsolutePath(), "static/upload/");

System.out.println("upload:" + upload);


filename.transferTo(new File(upload+"/"+filename.getOriginalFilename()));


} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "profile";
}

项目部署

添加包名称

1
2
<build> 的子标签下 添加
<packaging>war</packaging>

引入依赖 避免Tomcat的包重复

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<!--打包的时候可以不用包进去,别的设施会提供。事实上该依赖理论上可以参与编译,测试,运行等周期。
相当于compile,但是打包阶段做了exclude操作-->
<scope>provided</scope>
</dependency>

在入口类上添加标记
public class ServletInitializer extends SpringBootServletInitializer {

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
//此处的Application.class为带有@SpringBootApplication注解的启动类
return builder.sources(Application.class);
}

}

批量生成文件

导入依赖

pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
		
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.1.2</version>
</dependency>

<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
</dependency>

官方示例

https://mp.baomidou.com/guide/generator.html

自定义注入

1
2
3
4
5
6
7
8
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
HashMap<String, Object> map = new HashMap<>();
map.put("xxoo", "yimingge");
this.setMap(map);
}
};

自定义模板

模板文件实际位置

src/main/resources/templates/entity.ftl

1
2
3
4
5
// 配置模板
TemplateConfig templateConfig = new TemplateConfig();


templateConfig.setEntity("/templates/entity");

读取自定义注入内容

末班文件中加入

1
${cfg.xxoo}

freemarker 模板

1
2
3
4
5
6
7
${"abc"?cap_first}  //首字母大写
${entity} 实体类名
${table} 表
${table.controllerName} controller名称
${r'${itemStat.count}'} 转义
${table.entityName} 大写类名
${table.name} 小写

循环

1
2
3
4
	<#list table.fields as field>

<td th:text="${r'${item.'}${field.propertyName}}">${field.propertyName}</td>
</#list>

自定义输出

1
2
3
4
5
6
7
8
9
10
11
12
// 添加前端页面
// 输入
String html_list_Path = "/templates/html_list.ftl";
//输出
focList.add(new FileOutConfig(html_list_Path) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return projectPath + "/src/main/resources/templates/" + pc.getModuleName()
+ "/" + tableInfo.getEntityName() + "List.html";
}
});

entity模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package ${package.Entity};
import java.io.Serializable;

/**


* <p>
${cfg.xxoo}
* ${table.comment!}
* </p>
*
* @author ${author}
* @since ${date}
*/
public class ${entity} implements Serializable {

<#if entitySerialVersionUID>
private static final long serialVersionUID = 1L;
</#if>


//TableInfo(importPackages=[java.io.Serializable], convert=false, name=menu, comment=, entityName=Menu, mapperName=MenuMapper, xmlName=MenuMapper, serviceName=IMenuService, serviceImplName=MenuServiceImpl, controllerName=MenuController, fields=[TableField(convert=false, keyFlag=false, keyIdentityFlag=false, name=name, type=varchar(45), propertyName=name, columnType=STRING, comment=, fill=null, customMap=null), TableField(convert=false, keyFlag=false, keyIdentityFlag=false, name=roles, type=varchar(45), propertyName=roles, columnType=STRING, comment=, fill=null, customMap=null), TableField(convert=false, keyFlag=false, keyIdentityFlag=false, name=index, type=varchar(45), propertyName=index, columnType=STRING, comment=, fill=null, customMap=null)], commonFields=[TableField(convert=false, keyFlag=true, keyIdentityFlag=true, name=id, type=int(11), propertyName=id, columnType=INTEGER, comment=, fill=null, customMap=null)], fieldNames=name, roles, index)

<#-- ---------- 主键 字段循环遍历 ---------->
<#list table.commonFields as field>
private ${field.propertyType} ${field.propertyName};
</#list>
<#-- ---------- BEGIN 字段循环遍历 ---------->
<#list table.fields as field>
private ${field.propertyType} ${field.propertyName};
</#list>
<#------------ END 字段循环遍历 ---------->

<#if !entityLombokModel>
<#list table.fields as field>
<#if field.propertyType == "boolean">
<#assign getprefix="is"/>
<#else>
<#assign getprefix="get"/>
</#if>
public ${field.propertyType} ${getprefix}${field.capitalName}() {
return ${field.propertyName};
}

<#if entityBuilderModel>
public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
<#else>
public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
</#if>
this.${field.propertyName} = ${field.propertyName};
<#if entityBuilderModel>
return this;
</#if>
}
</#list>
</#if>

<#if entityColumnConstant>
<#list table.fields as field>
public static final String ${field.name?upper_case} = "${field.name}";

</#list>
</#if>
<#if activeRecord>
@Override
protected Serializable pkVal() {
<#if keyPropertyName??>
return this.${keyPropertyName};
<#else>
return null;
</#if>
}

</#if>


<#list table.commonFields as field>

public void set${field.propertyName?cap_first}(${field.propertyType} ${field.propertyName}){
this.${field.propertyName} = ${field.propertyName};
};


public ${field.propertyType} get${field.propertyName?cap_first}(){

return ${field.propertyName};
};
</#list>

<#-- ---------- get set 字段循环遍历 ---------->
<#list table.fields as field>

public void set${field.propertyName?cap_first}(${field.propertyType} ${field.propertyName}){
this.${field.propertyName} = ${field.propertyName};
};


public ${field.propertyType} get${field.propertyName?cap_first}(){

return ${field.propertyName};
};
</#list>
<#------------ END 字段循环遍历 ---------->

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

/**
* <p>
* ${table.comment!} 前端控制器
* </p>
*${table}
* @author ${author}
* @since ${date}
*/
@Controller
@RequestMapping("<#if package.ModuleName??>/${package.ModuleName}</#if>/<#if controllerMappingHyphenStyle??>${controllerMappingHyphen}<#else>${table.entityPath}</#if>")

public class ${table.controllerName} {



@Autowired
${entity}Service ${table.name}Srv;


@RequestMapping("/delete${entity}")
@ResponseBody
public RespStat delete${table.controllerName}(int id) {
System.out.println("id:" + id);
RespStat stat = ${table.name}Srv.delete(id);
return stat;
}



@RequestMapping("/list")
public String list(@RequestParam(defaultValue = "1") int pageNum,@RequestParam(defaultValue = "1" ) int pageSize,Model model) {

PageInfo<${entity}>accountList = ${table.name}Srv.findByPage(pageNum,pageSize);

return "/${table.name}/list";
}

后面要讲的

  1. 多表关联查询

课后作业

    1. 注册功能 异步
    2. 修改密码
    3. 权限认证
      1. 修改权限 后台 accountController->List 方法里 用户权限的增删改查
      2. 对修改动作 做权限控制
        1. 要不要显示给 User的用户
        2. 提交删除请求的时候 ,查一下 当前操作用户的权限是不是admin
    4. 翻页功能
    5. 欠下的
    6. bootstrap - table 替换现有 的表格
    7. 修改头像 上传图片
      1. 表里 添加一个字段(图片的完整 url 路径,相对路径(文件名))
      2. 前端页面 修改头像的功能
      3. 有个默认头像 (如果表字段里没有图 显示默认)
    8. 一定要有自学的能力

本文为本人整理的听课笔记, 稍有修改.
自学之用, 不作任何商业用途.如有侵权, 请联系删除

原文引用于如下原创内容 :

[Original]([https://github.com/bjmashibing/InternetArchitect/blob/master/03%20OA%E8%B4%A6%E6%88%B7%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86/OA%20%E7%94%A8%E6%88%B7%E6%A8%A1%E5%9D%97%2002.md](https://github.com/bjmashibing/InternetArchitect/blob/master/03 OA账户权限管理/OA 用户模块 02.md))

-------------本文结束感谢您的阅读-------------