Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
certificate-print
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
廖旭伟
certificate-print
Commits
037a27d2
Commit
037a27d2
authored
Nov 11, 2022
by
廖旭伟
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
增加API调用接口
parent
bd6e7ac0
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
1072 additions
and
314 deletions
+1072
-314
certificate-manager/doc/api.md
certificate-manager/doc/api.md
+149
-212
certificate-manager/src/main/java/com/mortals/xhx/common/code/HolderIdType.java
...c/main/java/com/mortals/xhx/common/code/HolderIdType.java
+9
-0
certificate-manager/src/main/java/com/mortals/xhx/common/code/HolderType.java
...src/main/java/com/mortals/xhx/common/code/HolderType.java
+9
-0
certificate-manager/src/main/java/com/mortals/xhx/common/utils/ExcelUtil.java
...src/main/java/com/mortals/xhx/common/utils/ExcelUtil.java
+168
-53
certificate-manager/src/main/java/com/mortals/xhx/common/utils/ImageBase64.java
...c/main/java/com/mortals/xhx/common/utils/ImageBase64.java
+50
-0
certificate-manager/src/main/java/com/mortals/xhx/common/utils/ImportExcelUtil.java
...in/java/com/mortals/xhx/common/utils/ImportExcelUtil.java
+267
-0
certificate-manager/src/main/java/com/mortals/xhx/module/certificate/pdu/ApplyLogPdu.java
...a/com/mortals/xhx/module/certificate/pdu/ApplyLogPdu.java
+61
-0
certificate-manager/src/main/java/com/mortals/xhx/module/certificate/pdu/CatalogVO.java
...ava/com/mortals/xhx/module/certificate/pdu/CatalogVO.java
+33
-0
certificate-manager/src/main/java/com/mortals/xhx/module/certificate/service/impl/CertificateCatalogServiceImpl.java
...rtificate/service/impl/CertificateCatalogServiceImpl.java
+13
-16
certificate-manager/src/main/java/com/mortals/xhx/module/certificate/web/CertificateApi.java
...om/mortals/xhx/module/certificate/web/CertificateApi.java
+88
-0
certificate-manager/src/main/java/com/mortals/xhx/module/certificate/web/CertificateCatalogController.java
.../module/certificate/web/CertificateCatalogController.java
+1
-1
certificate-manager/src/main/java/com/mortals/xhx/module/record/service/ApplyLogService.java
...om/mortals/xhx/module/record/service/ApplyLogService.java
+18
-0
certificate-manager/src/main/java/com/mortals/xhx/module/record/service/impl/ApplyLogServiceImpl.java
...s/xhx/module/record/service/impl/ApplyLogServiceImpl.java
+181
-32
certificate-manager/src/main/java/com/mortals/xhx/module/record/web/ApplyLogController.java
...com/mortals/xhx/module/record/web/ApplyLogController.java
+25
-0
No files found.
certificate-manager/doc/api.md
View file @
037a27d2
...
@@ -1461,219 +1461,7 @@ msg|String|消息|-
...
@@ -1461,219 +1461,7 @@ msg|String|消息|-
}
}
```
```
## 证照申请
### 查询证照申请列表
**请求URL:**
record/list
**请求方式:**
POST
**内容类型:**
application/json;charset=utf-8
**简要描述:**
查询证照申请
**请求参数:**
参数名称|类型|必填|描述
:---|:---|:---|:------
page|Integer|否|当前页
size|Integer|否|每页条数,值为-1,查询所有记录
**请求样例:**
```
{
"page":1,
"size":10
}
```
**响应参数:**
参数名称|参数类型|描述
:---|:---|:------
code|Integer|结果码(-1.失败,1.成功)
msg|String|消息
data|object|数据对象
 
per_page|Integer|每页条数
 
total|Integer|总条数
 
last_page|Integer|总页数
 
current_page|Integer|当前页
 
data|array|结果集列表|数组
  
id|Long|序号,主键,自增长
  
catalogId|Long|证照目录ID
  
catalogName|String|目录名称
  
catalogCode|String|目录编号
  
recordStatus|Integer|档案状态
  
createUserId|Long|创建用户
  
createTime|Date|创建时间
  
updateUserId|Long|更新用户
  
updateTime|Date|更新时间
dict|object|字典对象
**响应消息样例:**
```
{
"code":1,
"data":{
}
}
```
### 查看证照申请
**请求URL:**
record/info
**请求方式:**
GET
**内容类型:**
application/json;charset=utf-8
**简要描述:**
查看证照申请,返回实例详细信息
**请求参数:**
参数名称|类型|必填|描述
:---|:---|:---|:------
id|Long|是|ID
**请求样例:**
```
http://localhost/record/info?id=549
```
**响应参数:**
参数名称 |参数类型|描述
:---|:---|:-------
code|Integer|结果码(-1.失败,1.成功)
msg|String|消息
data|object|数据对象
 
id|Long|序号,主键,自增长
 
catalogId|Long|证照目录ID
 
catalogName|String|目录名称
 
catalogCode|String|目录编号
 
recordStatus|Integer|档案状态
 
createUserId|Long|创建用户
 
createTime|Date|创建时间
 
updateUserId|Long|更新用户
 
updateTime|Date|更新时间
dict|object|字典对象
**响应消息样例:**
```
{
"code": 1,
"data": {
"id":173,
"catalogId":3710,
"catalogName":"uiufi9",
"catalogCode":"rp723v",
"recordStatus":7804,
"createUserId":6469,
"createTime":"2022-11-04",
"updateUserId":9812,
"updateTime":"2022-11-04"
}
}
```
### 保存更新证照申请
**请求URL:**
record/save
**请求方式:**
POST
**内容类型:**
application/json;charset=utf-8
**简要描述:**
保存或更新证照申请:id为空时为新增保存,否则为更新提交
**请求参数:**
参数名称|类型|必填|描述
:---|:---|:---|:-------
id|Long|否|序号,主键,自增长
catalogName|String|是|目录名称
catalogCode|String|是|目录编号
recordStatus|Integer|是|档案状态
createUserId|Long|否|创建用户
createTime|Date|否|创建时间
updateUserId|Long|否|更新用户
updateTime|Date|否|更新时间
**请求样例:**
```
{
"catalogId":5208,
"catalogName":"azrqck",
"catalogCode":"t32v0y",
"recordStatus":1385,
}
```
**响应参数:**
参数名称 |参数类型|描述
:---|:---|:------
code|Integer|结果码(-1.失败,1.成功)
msg|String|消息
data|object|数据对象
 
id|Long|保存后主键id
 
entity|object|保存更新实体
  
id|Long|序号,主键,自增长
  
catalogId|Long|证照目录ID
  
catalogName|String|目录名称
  
catalogCode|String|目录编号
  
recordStatus|Integer|档案状态
  
createUserId|Long|创建用户
  
createTime|Date|创建时间
  
updateUserId|Long|更新用户
  
updateTime|Date|更新时间
**响应消息样例:**
```
{
"msg":"新增模块成功",
"code":1,
"data":{}
}
}
```
### 删除证照申请
**请求URL:**
record/delete
**请求方式:**
GET
**内容类型:**
application/json;charset=utf-8
**简要描述:**
删除证照申请
**请求参数:**
参数名称|类型|必填|描述
:---|:---|:---|:------
id|String|是|数组
**请求样例:**
```
http://localhost:8080/record/delete?id=1&id=2'
```
**响应参数:**
参数名称 |参数类型|备注|其它
---|---|---|---
code|Integer|结果码(-1.失败,1.成功)|-
msg|String|消息|-
**响应消息样例:**
```
{
"code":1,
"msg":"成功"
}
```
## 证照申请
## 证照申请
### 查询证照申请列表
### 查询证照申请列表
...
@@ -2253,6 +2041,49 @@ dict|object|字典对象
...
@@ -2253,6 +2041,49 @@ dict|object|字典对象
}
}
```
```
### excel导入
**请求URL:**
apply/log/import
**请求方式:**
POST
**内容类型:**
application/json;charset=utf-8
**简要描述:**
预览正本
**请求参数:**
参数名称|类型|必填|描述
:---|:---|:---|:-------
catalogId|Long|否|目录Id
file|file|是|证件编号
**请求样例:**
```
{
"catalogId": 1,
"file": "cxuyh4.xls"
}
```
**响应参数:**
参数名称 |参数类型|描述
:---|:---|:------
code|Integer|结果码(-1.失败,1.成功)
msg|String|消息
data|object|数据对象
**响应消息样例:**
```
{
"msg":"生成成功",
"code":1,
"data":{}
}
```
## 证照打印记录
## 证照打印记录
### 查询证照打印记录列表
### 查询证照打印记录列表
...
@@ -3243,4 +3074,110 @@ dict|object|字典对象
...
@@ -3243,4 +3074,110 @@ dict|object|字典对象
"dict": null
"dict": null
}
}
```
```
## API接口
### 查询证照目录
**请求URL:**
api/catalog/list
**请求方式:**
POST
**内容类型:**
application/json;charset=utf-8
**简要描述:**
查询证照目录
**请求样例:**
```
{
}
```
**响应参数:**
参数名称|参数类型|描述
:---|:---|:------
code|Integer|结果码(-1.失败,1.成功)
msg|String|消息
 
data|array|结果集列表|数组
  
id|Long|序号,主键,自增长
  
catalogName|String|目录名称
  
catalogCode|String|目录编号
  
formContent|String|证照模板表单内容
**响应消息样例:**
```
{
"data": {},
"code": 1,
"msg": "查询证照目录成功",
"dict": null
}
```
### 生成证照
**请求URL:**
api/certificate/submit
**请求方式:**
POST
**内容类型:**
application/json;charset=utf-8
**简要描述:**
查询证照目录
**请求参数:**
参数名称|类型|必填|描述
:---|:---|:---|:-------
catalogId|Long|否|目录Id
certificateCode|String|是|证件编号
certificateName|String|是|证件名称
issueTime|Date|是|颁发时间yyyy-mm-dd HH:MM:SS
pickerName|String|是|取件人姓名
pickerIDCardNo|String|是|取件人证件号码
holderType|Integer|是|持有者类型,1:自然人,2:法人,3:自然人法人
holderIdType|Integer|是|持有者证件类型,1:身份证,2:组织机构代码等
holderName|String|是|持有者名称
holderIDCardNo|String|是|持有者证件号码
enterpriseName|String|是|企业名称
privateID|String|是|专网ID
formContent|String|是|证照模板正本表单内容
**请求样例:**
```
{
"catalogId": 1,
"certificateCode": "cxuyh4",
"certificateName": "卫生许可证",
"issueTime": "2022-10-14 12:11:11",
"pickerName": "张三",
"pickerIDCardNo": "12345678",
"holderType": 1,
"holderIdType": 1,
"holderName": "张三",
"holderIDCardNo": "12334569086765",
"enterpriseName": "成都壹糖文化传播有限公司",
"privateID": "f45vg6",
"formContent": "{'i_1_卫':'川','i_2_字':'2022', 'i_3_号':'10','i_4_单位名称':'成都壹糖文化传播有限公司','i_5_法定代表人':'廖至敬','i_6_地址':'成都市武侯区晋吉南路98号','i_7_许可项目':'奶油蛋糕、生日蛋糕、水果蛋糕、奶茶、鲜切水果','i_8_年始':'2021','i_9_月始':'01','i_10_日始':'01','i_11_年止':'2023','i_12_月止':'12','i_13_日止':'31','i_14_年':'2020','i_15_月':'12','i_16_日':'30'}"
}
```
**响应参数:**
参数名称|参数类型|描述
:---|:---|:------
code|Integer|结果码(-1.失败,1.成功)
msg|String|消息
 
data|array|结果集列表|数组
**响应消息样例:**
```
{
"data": {},
"code": 1,
"msg": "证照生成成功",
"dict": null
}
```
## 字典附录
## 字典附录
certificate-manager/src/main/java/com/mortals/xhx/common/code/HolderIdType.java
View file @
037a27d2
...
@@ -22,6 +22,15 @@ public enum HolderIdType implements IBaseEnum {
...
@@ -22,6 +22,15 @@ public enum HolderIdType implements IBaseEnum {
this
.
style
=
style
;
this
.
style
=
style
;
}
}
public
static
HolderIdType
getByDesc
(
String
desc
)
{
for
(
HolderIdType
e
:
HolderIdType
.
values
())
{
if
(
e
.
getDesc
().
equals
(
desc
))
{
return
e
;
}
}
return
null
;
}
@Override
@Override
public
int
getValue
()
{
public
int
getValue
()
{
return
this
.
value
;
return
this
.
value
;
...
...
certificate-manager/src/main/java/com/mortals/xhx/common/code/HolderType.java
View file @
037a27d2
...
@@ -49,6 +49,15 @@ public enum HolderType implements IBaseEnum {
...
@@ -49,6 +49,15 @@ public enum HolderType implements IBaseEnum {
return
null
;
return
null
;
}
}
public
static
HolderType
getByDesc
(
String
desc
)
{
for
(
HolderType
e
:
HolderType
.
values
())
{
if
(
e
.
getDesc
().
equals
(
desc
))
{
return
e
;
}
}
return
null
;
}
public
static
Map
<
String
,
String
>
getEnumMap
(
int
...
eItem
)
{
public
static
Map
<
String
,
String
>
getEnumMap
(
int
...
eItem
)
{
Map
<
String
,
String
>
resultMap
=
new
LinkedHashMap
<
String
,
String
>();
Map
<
String
,
String
>
resultMap
=
new
LinkedHashMap
<
String
,
String
>();
for
(
HolderType
item
:
HolderType
.
values
())
{
for
(
HolderType
item
:
HolderType
.
values
())
{
...
...
certificate-manager/src/main/java/com/mortals/xhx/common/utils/ExcelUtil.java
View file @
037a27d2
package
com.mortals.xhx.common.utils
;
package
com.mortals.xhx.common.utils
;
import
org.apache.poi.hssf.usermodel.*
;
import
org.apache.poi.hssf.usermodel.*
;
import
org.apache.poi.ss.usermodel.DataValidation
;
import
org.apache.poi.ss.usermodel.*
;
import
org.apache.poi.ss.usermodel.DataValidationConstraint
;
import
org.apache.poi.ss.util.CellRangeAddress
;
import
org.apache.poi.ss.usermodel.DataValidationHelper
;
import
org.apache.poi.ss.usermodel.Sheet
;
import
org.apache.poi.ss.util.CellRangeAddressList
;
import
org.apache.poi.ss.util.CellRangeAddressList
;
import
org.checkerframework.checker.units.qual.C
;
import
java.io.File
;
import
java.io.File
;
import
java.io.FileNotFoundException
;
import
java.io.FileNotFoundException
;
import
java.io.FileOutputStream
;
import
java.io.FileOutputStream
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.List
;
...
@@ -19,10 +19,10 @@ public class ExcelUtil {
...
@@ -19,10 +19,10 @@ public class ExcelUtil {
/**
/**
* @Title: createExcelTemplate
* @Title: createExcelTemplate
* @Description: 生成Excel导入模板
* @Description: 生成Excel导入模板
* @param
@param
filePath Excel文件路径
* @param filePath Excel文件路径
* @param
@param handers
Excel列标题(数组)
* @param
title
Excel列标题(数组)
* @param
@param
downData 下拉框数据(数组)
* @param downData 下拉框数据(数组)
* @param
@param
downRows 下拉列的序号(数组,序号从0开始)
* @param downRows 下拉列的序号(数组,序号从0开始)
* @return void
* @return void
* @throws
* @throws
*/
*/
...
@@ -41,8 +41,8 @@ public class ExcelUtil {
...
@@ -41,8 +41,8 @@ public class ExcelUtil {
// 新建sheet
// 新建sheet
HSSFSheet
sheet1
=
wb
.
createSheet
(
"Sheet1"
);
HSSFSheet
sheet1
=
wb
.
createSheet
(
"Sheet1"
);
HSSFSheet
sheet2
=
wb
.
createSheet
(
"Sheet2"
);
//
HSSFSheet sheet2 = wb.createSheet("Sheet2");
HSSFSheet
sheet3
=
wb
.
createSheet
(
"Sheet3"
);
//
HSSFSheet sheet3 = wb.createSheet("Sheet3");
// 生成sheet1内容
// 生成sheet1内容
// 第一个sheet的第一行为标题
// 第一个sheet的第一行为标题
...
@@ -79,40 +79,40 @@ public class ExcelUtil {
...
@@ -79,40 +79,40 @@ public class ExcelUtil {
// Sheet2第A1到A5000作为下拉列表来源数据
// Sheet2第A1到A5000作为下拉列表来源数据
String
strFormula
=
"Sheet2!$"
+
arr
[
index
]+
"$1:$"
+
arr
[
index
]+
"$5000"
;
String
strFormula
=
"Sheet2!$"
+
arr
[
index
]+
"$1:$"
+
arr
[
index
]+
"$5000"
;
// 设置每列的列宽
// 设置每列的列宽
sheet2
.
setColumnWidth
(
r
,
4000
);
//
sheet2.setColumnWidth(r, 4000);
// 设置数据有效性加载在哪个单元格上,参数分别是:从sheet2获取A1到A5000作为一个下拉的数据、起始行、终止行、起始列、终止列
// 设置数据有效性加载在哪个单元格上,参数分别是:从sheet2获取A1到A5000作为一个下拉的数据、起始行、终止行、起始列、终止列
//下拉列表元素很多的情况
//下拉列表元素很多的情况
sheet1
.
addValidationData
(
SetDataValidation
(
strFormula
,
1
,
50000
,
rownum
,
rownum
));
sheet1
.
addValidationData
(
SetDataValidation
(
strFormula
,
1
,
50000
,
rownum
,
rownum
));
//2、生成sheet2内容
//2、生成sheet2内容
for
(
int
j
=
0
;
j
<
dlData
.
length
;
j
++){
//
for(int j=0;j<dlData.length;j++){
if
(
index
==
0
){
//第1个下拉选项,直接创建行、列
//
if(index==0){ //第1个下拉选项,直接创建行、列
// 创建数据行
//
// 创建数据行
row
=
sheet2
.
createRow
(
j
);
//
row = sheet2.createRow(j);
// 设置每列的列宽
//
// 设置每列的列宽
sheet2
.
setColumnWidth
(
j
,
4000
);
//
sheet2.setColumnWidth(j, 4000);
// 设置对应单元格的值
//
// 设置对应单元格的值
row
.
createCell
(
0
).
setCellValue
(
dlData
[
j
]);
//
row.createCell(0).setCellValue(dlData[j]);
//
}
else
{
//非第1个下拉选项
//
} else { //非第1个下拉选项
//
int
rowCount
=
sheet2
.
getLastRowNum
();
//
int rowCount = sheet2.getLastRowNum();
//System.out.println("========== LastRowNum =========" + rowCount);
//
//System.out.println("========== LastRowNum =========" + rowCount);
// 前面创建过的行,直接获取行,创建列
//
// 前面创建过的行,直接获取行,创建列
if
(
j
<=
rowCount
){
//
if(j<=rowCount){
// 获取行,创建列
//
// 获取行,创建列
// 设置对应单元格的值
//
// 设置对应单元格的值
sheet2
.
getRow
(
j
).
createCell
(
index
).
setCellValue
(
dlData
[
j
]);
//
sheet2.getRow(j).createCell(index).setCellValue(dlData[j]);
//
}
else
{
//未创建过的行,直接创建行、创建列
//
} else { //未创建过的行,直接创建行、创建列
// 设置每列的列宽
//
// 设置每列的列宽
sheet2
.
setColumnWidth
(
j
,
4000
);
//
sheet2.setColumnWidth(j, 4000);
// 创建行、创建列
//
// 创建行、创建列
// 设置对应单元格的值
//
// 设置对应单元格的值
sheet2
.
createRow
(
j
).
createCell
(
index
).
setCellValue
(
dlData
[
j
]);
//
sheet2.createRow(j).createCell(index).setCellValue(dlData[j]);
}
//
}
}
//
}
}
//
}
index
++;
index
++;
}
}
}
}
...
@@ -144,12 +144,12 @@ public class ExcelUtil {
...
@@ -144,12 +144,12 @@ public class ExcelUtil {
*
*
* @Title: SetDataValidation
* @Title: SetDataValidation
* @Description: 下拉列表元素很多的情况 (255以上的下拉)
* @Description: 下拉列表元素很多的情况 (255以上的下拉)
* @param
@param
strFormula
* @param strFormula
* @param
@param
firstRow 起始行
* @param firstRow 起始行
* @param
@param
endRow 终止行
* @param endRow 终止行
* @param
@param
firstCol 起始列
* @param firstCol 起始列
* @param
@param
endCol 终止列
* @param endCol 终止列
* @
param @
return
* @return
* @return HSSFDataValidation
* @return HSSFDataValidation
* @throws
* @throws
*/
*/
...
@@ -168,13 +168,12 @@ public class ExcelUtil {
...
@@ -168,13 +168,12 @@ public class ExcelUtil {
*
*
* @Title: setDataValidation
* @Title: setDataValidation
* @Description: 下拉列表元素不多的情况(255以内的下拉)
* @Description: 下拉列表元素不多的情况(255以内的下拉)
* @param @param sheet
* @param sheet
* @param @param textList
* @param textList
* @param @param firstRow
* @param firstRow
* @param @param endRow
* @param endRow
* @param @param firstCol
* @param firstCol
* @param @param endCol
* @param endCol
* @param @return
* @return DataValidation
* @return DataValidation
* @throws
* @throws
*/
*/
...
@@ -197,7 +196,7 @@ public class ExcelUtil {
...
@@ -197,7 +196,7 @@ public class ExcelUtil {
/**
/**
* @Title: delFile
* @Title: delFile
* @Description: 删除文件
* @Description: 删除文件
* @param
@param
filePath 文件路径
* @param filePath 文件路径
* @return void
* @return void
* @throws
* @throws
*/
*/
...
@@ -206,4 +205,120 @@ public class ExcelUtil {
...
@@ -206,4 +205,120 @@ public class ExcelUtil {
delFile
.
delete
();
delFile
.
delete
();
}
}
public
static
void
createCatalogTemplate
(
String
filePath
,
List
<
String
>
formInfo
){
List
<
String
>
basisInfo
=
new
ArrayList
<>();
basisInfo
.
add
(
"证照编号"
);
basisInfo
.
add
(
"证照名称"
);
basisInfo
.
add
(
"持有者名称"
);
basisInfo
.
add
(
"持有者类型"
);
basisInfo
.
add
(
"持有者证件类型"
);
basisInfo
.
add
(
"持有者证件号码"
);
basisInfo
.
add
(
"取件人姓名"
);
basisInfo
.
add
(
"取件人证件号码"
);
basisInfo
.
add
(
"颁发时间"
);
basisInfo
.
add
(
"专网ID"
);
basisInfo
.
add
(
"企业名称"
);
HSSFWorkbook
wb
=
new
HSSFWorkbook
();
//创建工作薄
//表头样式
HSSFCellStyle
style
=
wb
.
createCellStyle
();
// 创建一个居中格式
style
.
setAlignment
(
HorizontalAlignment
.
CENTER
);
//字体样式
HSSFFont
fontStyle
=
wb
.
createFont
();
fontStyle
.
setFontName
(
"微软雅黑"
);
fontStyle
.
setFontHeightInPoints
((
short
)
12
);
// fontStyle.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
style
.
setFont
(
fontStyle
);
//设置边框
style
.
setBorderTop
(
BorderStyle
.
THIN
);
style
.
setBorderRight
(
BorderStyle
.
THIN
);
style
.
setBorderBottom
(
BorderStyle
.
THIN
);
style
.
setBorderLeft
(
BorderStyle
.
THIN
);
// 新建sheet
HSSFSheet
sheet1
=
wb
.
createSheet
(
"Sheet1"
);
int
bIndex
=
basisInfo
.
size
()-
1
;
int
fIndex
=
formInfo
.
isEmpty
()?
0
:
formInfo
.
size
()-
1
;
//设置第一行合并的单元格
CellRangeAddress
regionx1
=
new
CellRangeAddress
(
0
,
0
,
0
,
bIndex
);
CellRangeAddress
regionx2
=
new
CellRangeAddress
(
0
,
0
,
bIndex
+
1
,
fIndex
+
bIndex
+
1
);
sheet1
.
addMergedRegion
(
regionx1
);
sheet1
.
addMergedRegion
(
regionx2
);
//第一行标题
HSSFRow
row0
=
sheet1
.
createRow
(
0
);
// HSSFCell cell_00 = row0.createCell(0);
// cell_00.setCellValue("证照目录基本信息");
// //cell_00.setCellStyle(style);
// HSSFCell cell_01 = row0.createCell(bIndex+1);
// cell_01.setCellValue("证照表单信息");
//cell_01.setCellStyle(style);
// 第二行 表头设置
HSSFRow
row1
=
sheet1
.
createRow
(
1
);
List
<
String
>
cellList
=
new
ArrayList
<>();
cellList
.
addAll
(
basisInfo
);
cellList
.
addAll
(
formInfo
);
for
(
int
i
=
0
;
i
<
cellList
.
size
();
i
++)
{
String
s
=
cellList
.
get
(
i
);
HSSFCell
cell_0
=
row0
.
createCell
(
i
);
if
(
i
==
0
){
cell_0
.
setCellValue
(
"证照目录基本信息(颁发时间格式:yyyy-mm-dd)"
);
}
if
(
i
==(
bIndex
+
1
)){
cell_0
.
setCellValue
(
"证照表单信息"
);
}
cell_0
.
setCellStyle
(
style
);
HSSFCell
cell
=
row1
.
createCell
(
i
);
// 设置每列的列宽
sheet1
.
setColumnWidth
(
i
,
4000
);
//sheet1.autoSizeColumn(i);
//sheet1.setColumnWidth(i,sheet1.getColumnWidth(i)*17/10);
//加样式
cell
.
setCellStyle
(
style
);
cell
.
setCellValue
(
s
);
//CellRangeAddressList range = new CellRangeAddressList(2,65535,0,0);
//DVConstraint constraint = DVConstraint.createTimeConstraint()
}
String
[]
str1
=
{
"自然人"
,
"法人"
,
"自然人、法人"
};
String
[]
str2
=
{
"身份证"
,
"组织机构代码"
};
// 255以内的下拉,参数分别是:作用的sheet、下拉内容数组、起始行、终止行、起始列、终止列
sheet1
.
addValidationData
(
setDataValidation
(
sheet1
,
str1
,
2
,
500
,
3
,
3
));
//超过255个报错
sheet1
.
addValidationData
(
setDataValidation
(
sheet1
,
str2
,
2
,
500
,
4
,
4
));
CellStyle
textStyle
=
wb
.
createCellStyle
();
DataFormat
format
=
wb
.
createDataFormat
();
textStyle
.
setDataFormat
(
format
.
getFormat
(
"@"
));
//证件号码,颁发时间设置为文本格式
sheet1
.
setDefaultColumnStyle
(
5
,
textStyle
);
sheet1
.
setDefaultColumnStyle
(
7
,
textStyle
);
sheet1
.
setDefaultColumnStyle
(
8
,
textStyle
);
//所有表单设置为文本格式
for
(
int
cl
=
11
;
cl
<
formInfo
.
size
();
cl
++){
sheet1
.
setDefaultColumnStyle
(
cl
,
textStyle
);
}
try
{
File
f
=
new
File
(
filePath
);
//写文件
//不存在则新增
if
(!
f
.
getParentFile
().
exists
()){
f
.
getParentFile
().
mkdirs
();
}
if
(!
f
.
exists
()){
f
.
createNewFile
();
}
FileOutputStream
out
=
new
FileOutputStream
(
f
);
out
.
flush
();
wb
.
write
(
out
);
out
.
close
();
}
catch
(
FileNotFoundException
e
)
{
e
.
printStackTrace
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
}
}
certificate-manager/src/main/java/com/mortals/xhx/common/utils/ImageBase64.java
0 → 100644
View file @
037a27d2
package
com.mortals.xhx.common.utils
;
import
java.io.FileInputStream
;
import
java.io.FileOutputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
/***
* 测试转化图片为base64字符串
* @author Administrator
*
*/
public
class
ImageBase64
{
//转化图片为base64
public
static
String
convertStr
(
String
filePath
)
throws
Exception
{
InputStream
is
=
new
FileInputStream
(
filePath
);
byte
[]
data
=
null
;
data
=
new
byte
[
is
.
available
()];
is
.
read
(
data
);
is
.
close
();
return
java
.
util
.
Base64
.
getEncoder
().
encodeToString
(
data
);
}
//转化字符串为图片
public
static
String
convertImg
(
String
base64
,
String
filePath
)
throws
Exception
{
byte
[]
arr
=
java
.
util
.
Base64
.
getDecoder
().
decode
(
base64
);
for
(
int
i
=
0
;
i
<
arr
.
length
;
++
i
)
{
if
(
arr
[
i
]
<
0
)
{
// 调整异常数据
arr
[
i
]
+=
256
;
}
}
OutputStream
out
=
new
FileOutputStream
(
filePath
);
out
.
write
(
arr
);
out
.
flush
();
out
.
close
();
return
filePath
;
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
// String filePath = "D:\\mortals\\app\\data\\cpm\\file\\uploadfile\\test.jpg";
// System.out.println(filePath);
// String str = convertStr(filePath);
// System.out.println(str);
String
ab
=
"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"
;
//贴上后发现有点长,就去掉了
String
filePath2
=
"D:\\mortals\\app\\data\\cpm\\file\\uploadfile\\b.png"
;
convertImg
(
ab
,
filePath2
);
}
}
certificate-manager/src/main/java/com/mortals/xhx/common/utils/ImportExcelUtil.java
0 → 100644
View file @
037a27d2
package
com.mortals.xhx.common.utils
;
import
com.alibaba.fastjson.JSONArray
;
import
com.alibaba.fastjson.JSONObject
;
import
com.mortals.xhx.common.code.HolderIdType
;
import
com.mortals.xhx.common.code.HolderType
;
import
com.mortals.xhx.module.record.model.ApplyLogEntity
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
import
org.apache.poi.ss.usermodel.*
;
import
org.apache.poi.hssf.usermodel.HSSFWorkbook
;
import
org.apache.poi.xssf.usermodel.XSSFWorkbook
;
import
java.io.FileInputStream
;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.text.DecimalFormat
;
import
java.text.ParseException
;
import
java.text.SimpleDateFormat
;
import
java.util.*
;
@Slf4j
public
class
ImportExcelUtil
{
private
static
final
String
EXCEL_XLS_SUFFIX
=
".xls"
;
private
static
final
String
EXCEL_XLSX_SUFFIX
=
".xlsx"
;
/**
* 读取Excel数据内容
*
* @param rowIndex 指定行号
* @param columnIndex 指定列号
* @return Map 包含单元格数据内容的Map对象
*/
public
static
List
<
Map
<
Integer
,
Object
>>
readExcelContent
(
String
filepath
,
Integer
startRow
,
Integer
rowIndex
,
Integer
columnIndex
)
throws
Exception
{
List
<
Map
<
Integer
,
Object
>>
returnList
=
new
LinkedList
<>();
Workbook
wb
=
null
;
Sheet
sheet
;
Row
row
;
try
{
InputStream
is
=
new
FileInputStream
(
filepath
);
if
(
filepath
.
endsWith
(
EXCEL_XLS_SUFFIX
))
{
wb
=
new
HSSFWorkbook
(
is
);
}
else
if
(
filepath
.
endsWith
(
EXCEL_XLSX_SUFFIX
))
{
wb
=
new
XSSFWorkbook
(
is
);
}
if
(
wb
==
null
)
{
throw
new
Exception
(
"Workbook对象为空!"
);
}
sheet
=
wb
.
getSheetAt
(
0
);
//解析文件总行数、总列数
int
rowNum
=
rowIndex
!=
null
?
rowIndex
:
sheet
.
getLastRowNum
();
row
=
sheet
.
getRow
(
startRow
);
int
colNum
=
columnIndex
!=
null
?
columnIndex
:
row
.
getLastCellNum
();
//循环列
for
(
int
colIndex
=
colNum
;
colIndex
>
0
;
colIndex
--)
{
Cell
cell
=
row
.
getCell
(
colIndex
);
if
(
cell
!=
null
&&
!
""
.
equals
(
cell
.
toString
()))
{
colNum
=
colIndex
;
break
;
}
}
log
.
info
(
"have data col:{}"
,
colNum
);
// 正文内容应该从第二行开始,第一行为表头的标题
for
(
int
i
=
startRow
;
i
<=
rowNum
;
i
++)
{
row
=
sheet
.
getRow
(
i
);
int
j
=
0
;
int
size
=
(
int
)
(
colNum
/
.
75
f
)
+
1
;
//存储单元格数据
Map
<
Integer
,
Object
>
cellValue
=
new
LinkedHashMap
<>(
size
);
if
(
row
==
null
)
{
continue
;
}
while
(
j
<=
colNum
)
{
Cell
cell
=
row
.
getCell
(
j
);
System
.
out
.
println
(
"j:"
+
j
+
",cell:"
+
cell
.
toString
());
if
(
j
==
8
){
System
.
out
.
println
(
cell
.
toString
());
}
String
value
=
""
;
//日期单元格需格式化日期
if
(
cell
!=
null
)
{
if
(
cell
.
getCellType
()
==
CellType
.
NUMERIC
)
{
if
(
DateUtil
.
isCellDateFormatted
(
cell
))
{
Date
d
=
cell
.
getDateCellValue
();
SimpleDateFormat
formatter
=
new
SimpleDateFormat
(
"yyyy-MM-dd"
);
value
=
formatter
.
format
(
d
);
}
else
if
(
cell
.
toString
().
contains
(
"E"
))
{
DecimalFormat
nf
=
new
DecimalFormat
(
"0"
);
value
=
nf
.
format
(
cell
.
getNumericCellValue
());
}
else
{
value
=
cell
.
toString
().
endsWith
(
".0"
)
?
cell
.
toString
().
replace
(
".0"
,
""
)
:
cell
.
toString
().
trim
();
}
}
else
if
(
cell
.
getCellType
()
==
CellType
.
FORMULA
)
{
value
=
String
.
valueOf
(
cell
.
getNumericCellValue
());
}
else
{
value
=
cell
.
toString
().
trim
();
}
}
cellValue
.
put
(
j
,
value
);
j
++;
}
returnList
.
add
(
cellValue
);
}
wb
.
close
();
}
catch
(
FileNotFoundException
e
)
{
log
.
error
(
"FileNotFoundException"
,
e
);
}
catch
(
IOException
e
)
{
log
.
error
(
"IOException"
,
e
);
}
finally
{
if
(
wb
!=
null
)
{
wb
.
close
();
}
}
return
returnList
;
}
/**
* 读取Excel数据内容
* @param startRow 从第几行开始读取
* @param rowIndex 指定行号
* @param columnIndex 指定列号
* @return Map 包含单元格数据内容的Map对象
*/
public
static
List
<
Map
<
Integer
,
Object
>>
readExcelContent
(
String
fileName
,
InputStream
is
,
Integer
startRow
,
Integer
rowIndex
,
Integer
columnIndex
)
throws
Exception
{
List
<
Map
<
Integer
,
Object
>>
returnList
=
new
LinkedList
<>();
Workbook
wb
=
null
;
Sheet
sheet
;
Row
row
;
try
{
if
(
fileName
.
endsWith
(
EXCEL_XLS_SUFFIX
))
{
wb
=
new
HSSFWorkbook
(
is
);
}
else
if
(
fileName
.
endsWith
(
EXCEL_XLSX_SUFFIX
))
{
wb
=
new
XSSFWorkbook
(
is
);
}
if
(
wb
==
null
)
{
throw
new
Exception
(
"Workbook对象为空!"
);
}
sheet
=
wb
.
getSheetAt
(
0
);
//解析文件总行数、总列数
int
rowNum
=
rowIndex
!=
null
?
rowIndex
:
sheet
.
getLastRowNum
();
row
=
sheet
.
getRow
(
startRow
);
int
colNum
=
columnIndex
!=
null
?
columnIndex
:
row
.
getLastCellNum
();
//循环列
for
(
int
colIndex
=
colNum
;
colIndex
>
0
;
colIndex
--)
{
Cell
cell
=
row
.
getCell
(
colIndex
);
if
(
cell
!=
null
&&
!
""
.
equals
(
cell
.
toString
()))
{
colNum
=
colIndex
;
break
;
}
}
log
.
info
(
"have data col:{}"
,
colNum
);
// 正文内容应该从第二行开始,第一行为表头的标题
for
(
int
i
=
startRow
;
i
<=
rowNum
;
i
++)
{
row
=
sheet
.
getRow
(
i
);
int
j
=
0
;
int
size
=
(
int
)
(
colNum
/
.
75
f
)
+
1
;
//存储单元格数据
Map
<
Integer
,
Object
>
cellValue
=
new
LinkedHashMap
<>(
size
);
if
(
row
==
null
)
{
continue
;
}
while
(
j
<=
colNum
)
{
Cell
cell
=
row
.
getCell
(
j
);
String
value
=
""
;
//日期单元格需格式化日期
if
(
cell
!=
null
)
{
if
(
cell
.
getCellType
()
==
CellType
.
NUMERIC
)
{
if
(
DateUtil
.
isCellDateFormatted
(
cell
))
{
Date
d
=
cell
.
getDateCellValue
();
SimpleDateFormat
formatter
=
new
SimpleDateFormat
(
"yyyy-MM-dd"
);
value
=
formatter
.
format
(
d
);
}
else
if
(
cell
.
toString
().
contains
(
"E"
))
{
DecimalFormat
nf
=
new
DecimalFormat
(
"0"
);
value
=
nf
.
format
(
cell
.
getNumericCellValue
());
}
else
{
value
=
cell
.
toString
().
endsWith
(
".0"
)
?
cell
.
toString
().
replace
(
".0"
,
""
)
:
cell
.
toString
().
trim
();
}
}
else
if
(
cell
.
getCellType
()
==
CellType
.
FORMULA
)
{
value
=
String
.
valueOf
(
cell
.
getNumericCellValue
());
}
else
{
value
=
cell
.
toString
().
trim
();
}
}
cellValue
.
put
(
j
,
value
);
j
++;
}
returnList
.
add
(
cellValue
);
}
wb
.
close
();
}
catch
(
FileNotFoundException
e
)
{
log
.
error
(
"FileNotFoundException"
,
e
);
}
catch
(
IOException
e
)
{
log
.
error
(
"IOException"
,
e
);
}
finally
{
if
(
wb
!=
null
)
{
wb
.
close
();
}
}
return
returnList
;
}
public
static
void
main
(
String
[]
args
){
String
filepath
=
"D:\\mortals\\app\\data\\cpm\\excel\\test3.xls"
;
try
{
List
<
Map
<
Integer
,
Object
>>
dataList
=
ImportExcelUtil
.
readExcelContent
(
filepath
,
1
,
null
,
null
);
dataList
.
forEach
(
m
->{
System
.
out
.
println
(
m
);
});
Map
<
Integer
,
Object
>
header
=
dataList
.
get
(
0
);
List
<
ApplyLogEntity
>
applyLogList
=
new
ArrayList
<>();
String
cf
=
"{\"config\":{\"disabled\":false,\"dynamicTableAllowed\":true,\"formModel\":\"form\",\"formRef\":\"elForm\",\"formRules\":\"rules\",\"gutter\":15,\"labelPosition\":\"top\",\"labelWidth\":120,\"rules\":\"rules\",\"size\":\"medium\",\"version\":\"1.10\"},\"list\":[{\"_id\":\"i_1_姓名\",\"append\":\"\",\"clearable\":true,\"compIcon\":\"input\",\"compName\":\"证书名称\",\"compType\":\"input\",\"config\":true,\"disabled\":false,\"ele\":\"el-input\",\"gutter\":15,\"id\":\"i_2_证书名称\",\"label\":\"证书名称\",\"labelWidth\":120,\"layout\":\"colItem\",\"maxLength\":50,\"placeholder\":\"请输入证书名称\",\"prefix-icon\":\"\",\"prepend\":\"\",\"readonly\":false,\"required\":true,\"rules\":[],\"rulesType\":\"default\",\"showLabel\":true,\"span\":24,\"status\":\"normal\",\"viewType\":\"text\",\"width\":\"100%\"},{\"_id\":\"i_2_性别\",\"append\":\"\",\"clearable\":true,\"compIcon\":\"input\",\"compName\":\"证书编号\",\"compType\":\"input\",\"config\":true,\"disabled\":false,\"ele\":\"el-input\",\"gutter\":15,\"id\":\"i_1_证书编号\",\"label\":\"证书编号\",\"labelWidth\":120,\"layout\":\"colItem\",\"maxLength\":50,\"placeholder\":\"请输入证书编号\",\"prefix-icon\":\"\",\"prepend\":\"\",\"readonly\":false,\"required\":true,\"rules\":[],\"rulesType\":\"default\",\"showLabel\":true,\"span\":24,\"status\":\"normal\",\"viewType\":\"text\",\"width\":\"100%\"}]}"
;
JSONObject
formContent
=
JSONObject
.
parseObject
(
cf
);
JSONArray
formList
=
formContent
.
getJSONArray
(
"list"
);
for
(
int
r
=
1
;
r
<
dataList
.
size
();
r
++){
Map
<
Integer
,
Object
>
row
=
dataList
.
get
(
r
);
ApplyLogEntity
entity
=
new
ApplyLogEntity
();
entity
.
setCertificateCode
(
String
.
valueOf
(
row
.
get
(
0
)));
entity
.
setCertificateName
(
String
.
valueOf
(
row
.
get
(
1
)));
entity
.
setHolderName
(
String
.
valueOf
(
row
.
get
(
2
)));
HolderType
holderType
=
HolderType
.
getByDesc
(
String
.
valueOf
(
row
.
get
(
3
)));
entity
.
setHolderType
(
holderType
==
null
?
HolderType
.
LEGAL_AND_PERSON
.
getValue
():
holderType
.
getValue
());
HolderIdType
holderIdType
=
HolderIdType
.
getByDesc
(
String
.
valueOf
(
row
.
get
(
4
)));
entity
.
setHolderIdType
(
holderIdType
==
null
?
HolderIdType
.
ID_CARD
.
getValue
():
holderIdType
.
getValue
());
entity
.
setHolderIDCardNo
(
String
.
valueOf
(
row
.
get
(
5
)));
entity
.
setPickerName
(
String
.
valueOf
(
row
.
get
(
6
)));
entity
.
setPickerIDCardNo
(
String
.
valueOf
(
row
.
get
(
7
)));
try
{
SimpleDateFormat
formatter
=
new
SimpleDateFormat
(
"yyyy-MM-dd"
);
entity
.
setIssueTime
(
formatter
.
parse
(
String
.
valueOf
(
row
.
get
(
8
))));
}
catch
(
ParseException
e
){
entity
.
setIssueTime
(
new
Date
());
}
entity
.
setPrivateID
(
String
.
valueOf
(
row
.
get
(
9
)));
entity
.
setEnterpriseName
(
String
.
valueOf
(
row
.
get
(
10
)));
JSONObject
formJson
=
new
JSONObject
();
int
formSize
=
row
.
size
();
for
(
int
i
=
11
;
i
<
formSize
;
i
++)
{
formJson
.
put
(
String
.
valueOf
(
header
.
get
(
i
)),
String
.
valueOf
(
row
.
get
(
i
)));
for
(
int
j
=
0
;
j
<
formList
.
size
();
j
++)
{
JSONObject
jsonObject
=
formList
.
getJSONObject
(
j
);
if
(
jsonObject
.
getString
(
"_id"
).
equals
(
String
.
valueOf
(
header
.
get
(
i
)))){
jsonObject
.
put
(
"value"
,
String
.
valueOf
(
row
.
get
(
i
)));
break
;
}
}
}
System
.
out
.
println
(
formJson
.
toJSONString
());
entity
.
setFormContent
(
formJson
.
toJSONString
());
System
.
out
.
println
(
formContent
.
toJSONString
());
entity
.
setFormTemplate
(
formContent
.
toJSONString
());
entity
.
setCreateTime
(
new
Date
());
System
.
out
.
println
(
entity
.
toString
());
}
}
catch
(
Exception
e
){
e
.
printStackTrace
();
}
}
}
certificate-manager/src/main/java/com/mortals/xhx/module/certificate/pdu/ApplyLogPdu.java
0 → 100644
View file @
037a27d2
package
com.mortals.xhx.module.certificate.pdu
;
import
lombok.Data
;
import
java.util.Date
;
@Data
public
class
ApplyLogPdu
{
/**
* 证照目录ID
*/
private
Long
catalogId
;
/**
* 证件编号
*/
private
String
certificateCode
;
/**
* 证件名称
*/
private
String
certificateName
;
/**
* 颁发时间
*/
private
Date
issueTime
;
/**
* 取件人姓名
*/
private
String
pickerName
;
/**
* 取件人证件号码
*/
private
String
pickerIDCardNo
;
/**
* 持有者类型,1:自然人,2:法人,3:自然人法人
*/
private
Integer
holderType
;
/**
* 持有者证件类型,1:身份证,2:组织机构代码等
*/
private
Integer
holderIdType
;
/**
* 持有者名称
*/
private
String
holderName
;
/**
* 持有者证件号码
*/
private
String
holderIDCardNo
;
/**
* 企业名称
*/
private
String
enterpriseName
;
/**
* 专网ID
*/
private
String
privateID
;
/**
* 证照模板正本表单内容
*/
private
String
formContent
;
}
certificate-manager/src/main/java/com/mortals/xhx/module/certificate/pdu/CatalogVO.java
0 → 100644
View file @
037a27d2
package
com.mortals.xhx.module.certificate.pdu
;
import
lombok.Data
;
@Data
public
class
CatalogVO
{
/**
* 主键
*/
private
Long
id
;
/**
* 目录名称
*/
private
String
catalogName
;
/**
* 目录编号
*/
private
String
catalogCode
;
/**
* 证照模板表单内容
*/
private
String
formContent
;
public
CatalogVO
(
Long
id
,
String
catalogName
,
String
catalogCode
)
{
this
.
id
=
id
;
this
.
catalogName
=
catalogName
;
this
.
catalogCode
=
catalogCode
;
}
public
CatalogVO
()
{
}
}
certificate-manager/src/main/java/com/mortals/xhx/module/certificate/service/impl/CertificateCatalogServiceImpl.java
View file @
037a27d2
...
@@ -125,15 +125,15 @@ public class CertificateCatalogServiceImpl extends AbstractCRUDServiceImpl<Certi
...
@@ -125,15 +125,15 @@ public class CertificateCatalogServiceImpl extends AbstractCRUDServiceImpl<Certi
List
<
ListItem
>
collect
=
new
ArrayList
<>();
List
<
ListItem
>
collect
=
new
ArrayList
<>();
HashSet
<
String
>
hs
=
new
HashSet
<>();
//去除重复标签
HashSet
<
String
>
hs
=
new
HashSet
<>();
//去除重复标签
List
<
String
>
excelList
=
new
ArrayList
<>();
//Excel模板
List
<
String
>
excelList
=
new
ArrayList
<>();
//Excel模板
excelList
.
add
(
"证照目录ID"
);
//
excelList.add("证照目录ID");
excelList
.
add
(
"证照编号"
);
//
excelList.add("证照编号");
excelList
.
add
(
"证照名称"
);
//
excelList.add("证照名称");
excelList
.
add
(
"颁发时间"
);
//
excelList.add("颁发时间");
excelList
.
add
(
"取件人姓名"
);
//
excelList.add("取件人姓名");
excelList
.
add
(
"取件人证件号码"
);
//
excelList.add("取件人证件号码");
excelList
.
add
(
"持有者名称"
);
//
excelList.add("持有者名称");
excelList
.
add
(
"持有者证件号码"
);
//
excelList.add("持有者证件号码");
excelList
.
add
(
"企业名称"
);
//
excelList.add("企业名称");
for
(
MetaTemplate
item
:
template
.
getElementTemplates
())
{
for
(
MetaTemplate
item
:
template
.
getElementTemplates
())
{
if
(
hs
.
contains
(
item
.
variable
())){
if
(
hs
.
contains
(
item
.
variable
())){
continue
;
continue
;
...
@@ -195,9 +195,7 @@ public class CertificateCatalogServiceImpl extends AbstractCRUDServiceImpl<Certi
...
@@ -195,9 +195,7 @@ public class CertificateCatalogServiceImpl extends AbstractCRUDServiceImpl<Certi
root
.
setList
(
collect
);
root
.
setList
(
collect
);
String
fileName
=
"file/uploadfile/excel/"
+
entity
.
getCatalogName
()+
"_批量导入模板.xls"
;
String
fileName
=
"file/uploadfile/excel/"
+
entity
.
getCatalogName
()+
"_批量导入模板.xls"
;
String
excelFilePath
=
rootPath
+
fileName
;
String
excelFilePath
=
rootPath
+
fileName
;
List
<
String
[]>
downData
=
new
ArrayList
();
ExcelUtil
.
createCatalogTemplate
(
excelFilePath
,
excelList
);
String
[]
downRows
=
{};
ExcelUtil
.
createExcelTemplate
(
excelFilePath
,
excelList
.
toArray
(
new
String
[
excelList
.
size
()]),
downData
,
downRows
);
entity
.
setExcelFile
(
fileName
);
entity
.
setExcelFile
(
fileName
);
if
(!
onlyExcel
)
{
if
(!
onlyExcel
)
{
entity
.
setFormContent
(
JSON
.
toJSONString
(
root
));
entity
.
setFormContent
(
JSON
.
toJSONString
(
root
));
...
@@ -205,16 +203,15 @@ public class CertificateCatalogServiceImpl extends AbstractCRUDServiceImpl<Certi
...
@@ -205,16 +203,15 @@ public class CertificateCatalogServiceImpl extends AbstractCRUDServiceImpl<Certi
}
}
public
static
void
main
(
String
[]
args
){
public
static
void
main
(
String
[]
args
){
String
excelFilePath
=
"D:/mortals/app/data/cpm/"
+
"excel/test.xls"
;
String
excelFilePath
=
"D:/mortals/app/data/cpm/"
+
"excel/test
1
.xls"
;
List
<
String
>
excelList
=
new
ArrayList
<>();
List
<
String
>
excelList
=
new
ArrayList
<>();
excelList
.
add
(
"i_1_姓名"
);
excelList
.
add
(
"i_1_姓名"
);
excelList
.
add
(
"i_2_性别"
);
excelList
.
add
(
"i_2_性别"
);
excelList
.
add
(
"i_3_年龄"
);
excelList
.
add
(
"i_3_年龄"
);
excelList
.
add
(
"i_4_证件编号"
);
excelList
.
add
(
"i_4_证件编号"
);
excelList
.
add
(
"i_5_证件名称"
);
excelList
.
add
(
"i_5_证件名称"
);
List
<
String
[]>
downData
=
new
ArrayList
();
String
[]
downRows
=
{};
ExcelUtil
.
createCatalogTemplate
(
excelFilePath
,
excelList
);
ExcelUtil
.
createExcelTemplate
(
excelFilePath
,
excelList
.
toArray
(
new
String
[
excelList
.
size
()]),
downData
,
downRows
);
}
}
@Override
@Override
...
...
certificate-manager/src/main/java/com/mortals/xhx/module/certificate/web/CertificateApi.java
0 → 100644
View file @
037a27d2
package
com.mortals.xhx.module.certificate.web
;
import
com.alibaba.fastjson.JSONArray
;
import
com.alibaba.fastjson.JSONObject
;
import
com.mortals.framework.annotation.UnAuth
;
import
com.mortals.framework.exception.AppException
;
import
com.mortals.xhx.module.certificate.model.CertificateCatalogEntity
;
import
com.mortals.xhx.module.certificate.model.CertificateCatalogQuery
;
import
com.mortals.xhx.module.certificate.pdu.ApplyLogPdu
;
import
com.mortals.xhx.module.certificate.pdu.CatalogVO
;
import
com.mortals.xhx.module.certificate.service.CertificateCatalogService
;
import
com.mortals.xhx.module.record.service.ApplyLogService
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
@RestController
@RequestMapping
(
"api"
)
public
class
CertificateApi
{
@Autowired
private
CertificateCatalogService
certificateCatalogService
;
@Autowired
private
ApplyLogService
applyLogService
;
@PostMapping
({
"catalog/list"
})
@UnAuth
public
String
getCatalogList
(){
JSONObject
ret
=
new
JSONObject
();
Map
<
String
,
Object
>
model
=
new
HashMap
();
byte
code
=
1
;
try
{
List
<
CertificateCatalogEntity
>
list
=
certificateCatalogService
.
find
(
new
CertificateCatalogQuery
());
List
<
CatalogVO
>
catalogList
=
new
ArrayList
<>();
for
(
CertificateCatalogEntity
entity:
list
){
CatalogVO
catalogVO
=
new
CatalogVO
(
entity
.
getId
(),
entity
.
getCatalogName
(),
entity
.
getCatalogCode
());
JSONObject
formContent
=
JSONObject
.
parseObject
(
entity
.
getFormContent
());
JSONArray
formList
=
formContent
.
getJSONArray
(
"list"
);
JSONObject
json
=
new
JSONObject
();
for
(
int
j
=
0
;
j
<
formList
.
size
();
j
++)
{
JSONObject
jsonObject
=
formList
.
getJSONObject
(
j
);
json
.
put
(
jsonObject
.
getString
(
"id"
),
""
);
}
catalogVO
.
setFormContent
(
json
.
toJSONString
());
catalogList
.
add
(
catalogVO
);
}
model
.
put
(
"message_info"
,
"获取证照目录成功"
);
ret
.
put
(
"data"
,
catalogList
);
}
catch
(
Exception
e
){
code
=
-
1
;
model
.
put
(
"message_info"
,
"系统发生异常,请稍后再试"
);
}
ret
.
put
(
"code"
,
Integer
.
valueOf
(
code
));
ret
.
put
(
"msg"
,
model
.
remove
(
"message_info"
));
return
ret
.
toJSONString
();
}
@PostMapping
({
"certificate/submit"
})
@UnAuth
public
String
postA
(
@RequestBody
ApplyLogPdu
applyLogPdu
){
JSONObject
ret
=
new
JSONObject
();
Map
<
String
,
Object
>
model
=
new
HashMap
();
byte
code
=
1
;
try
{
applyLogService
.
apiSaveApplyLog
(
applyLogPdu
);
model
.
put
(
"message_info"
,
"生成证照成功"
);
}
catch
(
Exception
e
){
code
=
-
1
;
model
.
put
(
"message_info"
,
"生成证照发生异常"
);
if
(
e
instanceof
AppException
){
model
.
put
(
"message_info"
,
e
.
getMessage
());
}
}
ret
.
put
(
"code"
,
Integer
.
valueOf
(
code
));
ret
.
put
(
"msg"
,
model
.
remove
(
"message_info"
));
return
ret
.
toJSONString
();
}
}
certificate-manager/src/main/java/com/mortals/xhx/module/certificate/web/CertificateCatalogController.java
View file @
037a27d2
...
@@ -72,7 +72,7 @@ public class CertificateCatalogController extends BaseCRUDJsonBodyMappingControl
...
@@ -72,7 +72,7 @@ public class CertificateCatalogController extends BaseCRUDJsonBodyMappingControl
Object
msg
=
model
.
get
(
"message_info"
);
Object
msg
=
model
.
get
(
"message_info"
);
return
this
.
createFailJsonResp
(
msg
==
null
?
"系统异常"
:
msg
.
toString
());
return
this
.
createFailJsonResp
(
msg
==
null
?
"系统异常"
:
msg
.
toString
());
}
}
this
.
init
(
model
,
context
);
//
this.init(model, context);
ret
.
put
(
"data"
,
model
);
ret
.
put
(
"data"
,
model
);
ret
.
put
(
"code"
,
1
);
ret
.
put
(
"code"
,
1
);
ret
.
put
(
"msg"
,
model
.
remove
(
"message_info"
));
ret
.
put
(
"msg"
,
model
.
remove
(
"message_info"
));
...
...
certificate-manager/src/main/java/com/mortals/xhx/module/record/service/ApplyLogService.java
View file @
037a27d2
...
@@ -3,9 +3,11 @@ package com.mortals.xhx.module.record.service;
...
@@ -3,9 +3,11 @@ package com.mortals.xhx.module.record.service;
import
com.mortals.framework.exception.AppException
;
import
com.mortals.framework.exception.AppException
;
import
com.mortals.framework.model.Context
;
import
com.mortals.framework.model.Context
;
import
com.mortals.framework.service.ICRUDService
;
import
com.mortals.framework.service.ICRUDService
;
import
com.mortals.xhx.module.certificate.pdu.ApplyLogPdu
;
import
com.mortals.xhx.module.record.model.ApplyLogEntity
;
import
com.mortals.xhx.module.record.model.ApplyLogEntity
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
/**
/**
* ApplyLogService
* ApplyLogService
...
@@ -39,4 +41,20 @@ public interface ApplyLogService extends ICRUDService<ApplyLogEntity,Long>{
...
@@ -39,4 +41,20 @@ public interface ApplyLogService extends ICRUDService<ApplyLogEntity,Long>{
* @throws AppException
* @throws AppException
*/
*/
List
<
ApplyLogEntity
>
ApplyRecord
(
Long
applyId
)
throws
AppException
;
List
<
ApplyLogEntity
>
ApplyRecord
(
Long
applyId
)
throws
AppException
;
/**
* 批量导入
* @param dataList
* @param catalogId
* @param context
* @return
*/
String
importData
(
List
<
Map
<
Integer
,
Object
>>
dataList
,
Long
catalogId
,
Context
context
)
throws
AppException
;
/**
* api接口提交数据
* @param pdu
* @throws AppException
*/
void
apiSaveApplyLog
(
ApplyLogPdu
pdu
)
throws
AppException
;
}
}
\ No newline at end of file
certificate-manager/src/main/java/com/mortals/xhx/module/record/service/impl/ApplyLogServiceImpl.java
View file @
037a27d2
...
@@ -4,6 +4,8 @@ import cn.hutool.core.convert.Convert;
...
@@ -4,6 +4,8 @@ import cn.hutool.core.convert.Convert;
import
cn.hutool.core.io.FileUtil
;
import
cn.hutool.core.io.FileUtil
;
import
cn.hutool.core.util.RandomUtil
;
import
cn.hutool.core.util.RandomUtil
;
import
cn.hutool.core.util.StrUtil
;
import
cn.hutool.core.util.StrUtil
;
import
com.alibaba.fastjson.JSONArray
;
import
com.alibaba.fastjson.JSONObject
;
import
com.deepoove.poi.XWPFTemplate
;
import
com.deepoove.poi.XWPFTemplate
;
import
com.deepoove.poi.config.Configure
;
import
com.deepoove.poi.config.Configure
;
import
com.deepoove.poi.config.ConfigureBuilder
;
import
com.deepoove.poi.config.ConfigureBuilder
;
...
@@ -18,15 +20,14 @@ import com.mortals.framework.model.PageInfo;
...
@@ -18,15 +20,14 @@ import com.mortals.framework.model.PageInfo;
import
com.mortals.xhx.base.system.upload.service.UploadService
;
import
com.mortals.xhx.base.system.upload.service.UploadService
;
import
com.mortals.xhx.base.system.user.model.UserEntity
;
import
com.mortals.xhx.base.system.user.model.UserEntity
;
import
com.mortals.xhx.base.system.user.service.UserService
;
import
com.mortals.xhx.base.system.user.service.UserService
;
import
com.mortals.xhx.common.code.ClassifyType
;
import
com.mortals.xhx.common.code.*
;
import
com.mortals.xhx.common.code.GenerateStatus
;
import
com.mortals.xhx.common.code.OperTypeEnum
;
import
com.mortals.xhx.common.code.YesNoEnum
;
import
com.mortals.xhx.common.utils.ExportDocUtil
;
import
com.mortals.xhx.common.utils.ExportDocUtil
;
import
com.mortals.xhx.common.utils.ImageBase64
;
import
com.mortals.xhx.common.utils.StringUtils
;
import
com.mortals.xhx.common.utils.StringUtils
;
import
com.mortals.xhx.common.utils.WordUtil
;
import
com.mortals.xhx.common.utils.WordUtil
;
import
com.mortals.xhx.module.certificate.model.CertificateCatalogEntity
;
import
com.mortals.xhx.module.certificate.model.CertificateCatalogEntity
;
import
com.mortals.xhx.module.certificate.model.CertificateClassifyEntity
;
import
com.mortals.xhx.module.certificate.model.CertificateClassifyEntity
;
import
com.mortals.xhx.module.certificate.pdu.ApplyLogPdu
;
import
com.mortals.xhx.module.certificate.service.CertificateCatalogService
;
import
com.mortals.xhx.module.certificate.service.CertificateCatalogService
;
import
com.mortals.xhx.module.certificate.service.CertificateClassifyService
;
import
com.mortals.xhx.module.certificate.service.CertificateClassifyService
;
import
com.mortals.xhx.module.record.dao.RecordDao
;
import
com.mortals.xhx.module.record.dao.RecordDao
;
...
@@ -49,11 +50,11 @@ import com.mortals.xhx.module.record.service.ApplyLogService;
...
@@ -49,11 +50,11 @@ import com.mortals.xhx.module.record.service.ApplyLogService;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.transaction.annotation.Transactional
;
import
org.springframework.util.ObjectUtils
;
import
org.springframework.util.ObjectUtils
;
import
org.springframework.web.multipart.MultipartFile
;
import
org.springframework.web.multipart.MultipartFile
;
import
sun.misc.BASE64Decoder
;
import
java.io.ByteArrayOutputStream
;
import
java.io.*
;
import
java.io.FileInputStream
;
import
java.text.ParseException
;
import
java.io.FileNotFoundException
;
import
java.text.SimpleDateFormat
;
import
java.io.IOException
;
import
java.util.*
;
import
java.util.*
;
import
java.util.stream.Collectors
;
import
java.util.stream.Collectors
;
...
@@ -251,29 +252,6 @@ public class ApplyLogServiceImpl extends AbstractCRUDServiceImpl<ApplyLogDao, Ap
...
@@ -251,29 +252,6 @@ public class ApplyLogServiceImpl extends AbstractCRUDServiceImpl<ApplyLogDao, Ap
printWaitQueueService
.
creatWaitQueueByApply
(
applyLogEntity
,
GenerateStatus
.
ORIGINAL
.
getValue
(),
context
);
printWaitQueueService
.
creatWaitQueueByApply
(
applyLogEntity
,
GenerateStatus
.
ORIGINAL
.
getValue
(),
context
);
}
}
@Override
public
List
<
ApplyLogEntity
>
ApplyRecord
(
Long
applyId
)
throws
AppException
{
ApplyLogEntity
applyLogEntity
=
this
.
dao
.
get
(
applyId
);
if
(
applyLogEntity
==
null
){
throw
new
AppException
(
"数据不存在"
);
}
UserEntity
userEntity
=
userService
.
get
(
applyLogEntity
.
getCreateUserId
());
ApplyLogEntity
query
=
new
ApplyLogEntity
();
query
.
setRecordId
(
applyLogEntity
.
getRecordId
());
List
<
ApplyLogEntity
>
list
=
dao
.
getList
(
query
);
for
(
ApplyLogEntity
entity:
list
){
OperTypeEnum
operTypeEnum
=
OperTypeEnum
.
getByValue
(
entity
.
getOperType
());
if
(
operTypeEnum
!=
null
){
entity
.
setOperTypeName
(
operTypeEnum
.
getDesc
()+
entity
.
getCertificateName
());
}
if
(
userEntity
!=
null
){
entity
.
setCreateUserName
(
userEntity
.
getRealName
());
}
}
return
list
;
}
private
String
preview
(
DocTemplateVO
docTemplate
,
Context
context
){
private
String
preview
(
DocTemplateVO
docTemplate
,
Context
context
){
String
rootPath
=
this
.
filePath
.
endsWith
(
"/"
)
?
this
.
filePath
:
this
.
filePath
+
"/"
;
String
rootPath
=
this
.
filePath
.
endsWith
(
"/"
)
?
this
.
filePath
:
this
.
filePath
+
"/"
;
//转换表单参数为map集合
//转换表单参数为map集合
...
@@ -346,7 +324,7 @@ public class ApplyLogServiceImpl extends AbstractCRUDServiceImpl<ApplyLogDao, Ap
...
@@ -346,7 +324,7 @@ public class ApplyLogServiceImpl extends AbstractCRUDServiceImpl<ApplyLogDao, Ap
MultipartFile
multipartFile
=
new
MockMultipartFile
(
templateName
,
templateName
,
MultipartFile
multipartFile
=
new
MockMultipartFile
(
templateName
,
templateName
,
ContentType
.
APPLICATION_OCTET_STREAM
.
toString
(),
byteArrayOutputStream
.
toByteArray
());
ContentType
.
APPLICATION_OCTET_STREAM
.
toString
(),
byteArrayOutputStream
.
toByteArray
());
String
mergedocPath
=
uploadService
.
saveFileUpload
(
multipartFile
,
"/mergedoc"
,
context
.
getUser
());
String
mergedocPath
=
uploadService
.
saveFileUpload
(
multipartFile
,
"/mergedoc"
,
context
==
null
?
null
:
context
.
getUser
());
log
.
info
(
"mergedocPath:"
+
mergedocPath
);
log
.
info
(
"mergedocPath:"
+
mergedocPath
);
String
mergedoc
=
rootPath
+
mergedocPath
;
String
mergedoc
=
rootPath
+
mergedocPath
;
//转换预览图片
//转换预览图片
...
@@ -373,4 +351,175 @@ public class ApplyLogServiceImpl extends AbstractCRUDServiceImpl<ApplyLogDao, Ap
...
@@ -373,4 +351,175 @@ public class ApplyLogServiceImpl extends AbstractCRUDServiceImpl<ApplyLogDao, Ap
}
}
return
""
;
return
""
;
}
}
@Override
public
List
<
ApplyLogEntity
>
ApplyRecord
(
Long
applyId
)
throws
AppException
{
ApplyLogEntity
applyLogEntity
=
this
.
dao
.
get
(
applyId
);
if
(
applyLogEntity
==
null
){
throw
new
AppException
(
"数据不存在"
);
}
UserEntity
userEntity
=
userService
.
get
(
applyLogEntity
.
getCreateUserId
());
ApplyLogEntity
query
=
new
ApplyLogEntity
();
query
.
setRecordId
(
applyLogEntity
.
getRecordId
());
List
<
ApplyLogEntity
>
list
=
dao
.
getList
(
query
);
for
(
ApplyLogEntity
entity:
list
){
OperTypeEnum
operTypeEnum
=
OperTypeEnum
.
getByValue
(
entity
.
getOperType
());
if
(
operTypeEnum
!=
null
){
entity
.
setOperTypeName
(
operTypeEnum
.
getDesc
()+
entity
.
getCertificateName
());
}
if
(
userEntity
!=
null
){
entity
.
setCreateUserName
(
userEntity
.
getRealName
());
}
}
return
list
;
}
@Override
public
String
importData
(
List
<
Map
<
Integer
,
Object
>>
dataList
,
Long
catalogId
,
Context
context
)
throws
AppException
{
if
(
catalogId
==
null
){
throw
new
AppException
(
"目录ID不能为空"
);
}
CertificateCatalogEntity
catalog
=
certificateCatalogService
.
get
(
catalogId
);
if
(
catalog
==
null
){
throw
new
AppException
(
"目录ID不正确"
);
}
JSONObject
formContent
=
JSONObject
.
parseObject
(
catalog
.
getFormContent
());
JSONArray
formList
=
formContent
.
getJSONArray
(
"list"
);
Map
<
Integer
,
Object
>
header
=
dataList
.
get
(
0
);
List
<
ApplyLogEntity
>
applyLogList
=
new
ArrayList
<>();
for
(
int
r
=
1
;
r
<
dataList
.
size
();
r
++){
Map
<
Integer
,
Object
>
row
=
dataList
.
get
(
r
);
ApplyLogEntity
entity
=
new
ApplyLogEntity
();
entity
.
setCatalogId
(
catalogId
);
entity
.
setCatalogCode
(
catalog
.
getCatalogCode
());
entity
.
setCatalogName
(
catalog
.
getCatalogName
());
entity
.
setCertificateCode
(
String
.
valueOf
(
row
.
get
(
0
)));
entity
.
setCertificateName
(
String
.
valueOf
(
row
.
get
(
1
)));
entity
.
setHolderName
(
String
.
valueOf
(
row
.
get
(
2
)));
HolderType
holderType
=
HolderType
.
getByDesc
(
String
.
valueOf
(
row
.
get
(
3
)));
entity
.
setHolderType
(
holderType
==
null
?
HolderType
.
LEGAL_AND_PERSON
.
getValue
():
holderType
.
getValue
());
HolderIdType
holderIdType
=
HolderIdType
.
getByDesc
(
String
.
valueOf
(
row
.
get
(
4
)));
entity
.
setHolderIdType
(
holderIdType
==
null
?
HolderIdType
.
ID_CARD
.
getValue
():
holderIdType
.
getValue
());
entity
.
setHolderIDCardNo
(
String
.
valueOf
(
row
.
get
(
5
)));
entity
.
setPickerName
(
String
.
valueOf
(
row
.
get
(
6
)));
entity
.
setPickerIDCardNo
(
String
.
valueOf
(
row
.
get
(
7
)));
try
{
SimpleDateFormat
formatter
=
new
SimpleDateFormat
(
"yyyy-MM-dd"
);
entity
.
setIssueTime
(
formatter
.
parse
(
String
.
valueOf
(
row
.
get
(
8
))));
}
catch
(
ParseException
e
){
entity
.
setIssueTime
(
new
Date
());
}
entity
.
setPrivateID
(
String
.
valueOf
(
row
.
get
(
9
)));
entity
.
setEnterpriseName
(
String
.
valueOf
(
row
.
get
(
10
)));
JSONObject
formJson
=
new
JSONObject
();
int
formSize
=
row
.
size
();
for
(
int
i
=
11
;
i
<
formSize
;
i
++)
{
formJson
.
put
(
String
.
valueOf
(
header
.
get
(
i
)),
String
.
valueOf
(
row
.
get
(
i
)));
for
(
int
j
=
0
;
j
<
formList
.
size
();
j
++)
{
JSONObject
jsonObject
=
formList
.
getJSONObject
(
j
);
if
(
jsonObject
.
getString
(
"_id"
).
equals
(
String
.
valueOf
(
header
.
get
(
i
)))){
jsonObject
.
put
(
"value"
,
String
.
valueOf
(
row
.
get
(
i
)));
break
;
}
}
}
entity
.
setFormContent
(
formJson
.
toJSONString
());
entity
.
setFormTemplate
(
formContent
.
toJSONString
());
if
(
context
!=
null
&&
context
.
getUser
()!=
null
)
{
entity
.
setCreateUserId
(
context
.
getUser
().
getId
());
}
entity
.
setCreateTime
(
new
Date
());
applyLogList
.
add
(
entity
);
}
int
successNum
=
0
;
int
failureNum
=
0
;
StringBuilder
successMsg
=
new
StringBuilder
();
StringBuilder
failureMsg
=
new
StringBuilder
();
for
(
ApplyLogEntity
applyLogEntity:
applyLogList
){
try
{
this
.
generateOriginal
(
applyLogEntity
,
context
);
successNum
++;
}
catch
(
Exception
var11
)
{
this
.
log
.
error
(
"导入异常"
,
var11
);
++
failureNum
;
}
}
successMsg
.
insert
(
0
,
"数据导入成功!共 "
+
successNum
+
" 条"
);
if
(
failureNum
>
0
)
{
failureMsg
.
insert
(
0
,
"导入失败!共 "
+
failureNum
+
" 条数据格式不正确"
);
successMsg
.
append
(
"\n"
);
successMsg
.
append
(
failureMsg
);
}
return
successMsg
.
toString
();
}
@Override
public
void
apiSaveApplyLog
(
ApplyLogPdu
pdu
)
throws
AppException
{
CertificateCatalogEntity
catalog
=
certificateCatalogService
.
get
(
pdu
.
getCatalogId
());
if
(
catalog
==
null
){
throw
new
AppException
(
"目录ID不正确"
);
}
ApplyLogEntity
entity
=
new
ApplyLogEntity
();
entity
.
setCatalogId
(
catalog
.
getId
());
entity
.
setCatalogCode
(
catalog
.
getCatalogCode
());
entity
.
setCatalogName
(
catalog
.
getCatalogName
());
entity
.
setCertificateCode
(
pdu
.
getCertificateCode
());
entity
.
setCertificateName
(
pdu
.
getCertificateName
());
entity
.
setHolderName
(
pdu
.
getHolderName
());
entity
.
setHolderType
(
pdu
.
getHolderType
());
entity
.
setHolderIdType
(
pdu
.
getHolderIdType
());
entity
.
setHolderIDCardNo
(
pdu
.
getHolderIDCardNo
());
entity
.
setPickerName
(
pdu
.
getPickerName
());
entity
.
setPickerIDCardNo
(
pdu
.
getPickerIDCardNo
());
entity
.
setIssueTime
(
pdu
.
getIssueTime
());
entity
.
setPrivateID
(
pdu
.
getPrivateID
());
entity
.
setEnterpriseName
(
pdu
.
getEnterpriseName
());
entity
.
setCreateUserId
(
1L
);
JSONObject
formContent
=
JSONObject
.
parseObject
(
pdu
.
getFormContent
());
Map
<
String
,
String
>
formMap
=
new
HashMap
<>();
formContent
.
forEach
((
key
,
value
)
->
{
//图片处理
if
(
key
.
indexOf
(
"@image"
)
!=
-
1
)
{
String
base64
=
String
.
valueOf
(
value
);
if
(
StringUtils
.
isEmpty
(
base64
)){
throw
new
AppException
(
"图片不能为空"
);
}
String
imageName
=
new
Date
().
getTime
()
+
".png"
;
String
imagePath
=
"/file/uploadfile/"
+
imageName
;
String
filePath
=
this
.
filePath
.
endsWith
(
"/"
)
?
this
.
filePath
:
this
.
filePath
+
imagePath
;
try
{
ImageBase64
.
convertImg
(
base64
.
trim
(),
filePath
);
formMap
.
put
(
key
,
imagePath
);
}
catch
(
Exception
e
){
log
.
error
(
"base64图片转换异常"
,
e
.
fillInStackTrace
());
formMap
.
put
(
key
,
""
);
}
}
else
{
formMap
.
put
(
key
,
String
.
valueOf
(
value
));
}
});
entity
.
setFormContent
(
JSONObject
.
toJSONString
(
formMap
));
JSONObject
formTemplate
=
JSONObject
.
parseObject
(
catalog
.
getFormContent
());
JSONArray
formList
=
formTemplate
.
getJSONArray
(
"list"
);
JSONObject
json
=
new
JSONObject
();
for
(
int
j
=
0
;
j
<
formList
.
size
();
j
++)
{
JSONObject
jsonObject
=
formList
.
getJSONObject
(
j
);
String
key
=
jsonObject
.
getString
(
"id"
);
json
.
put
(
key
,
formMap
.
get
(
key
));
}
entity
.
setFormTemplate
(
formTemplate
.
toJSONString
());
try
{
this
.
generateOriginal
(
entity
,
null
);
}
catch
(
Exception
e
){
log
.
error
(
"API接口生成证照失败"
,
e
.
fillInStackTrace
());
throw
new
AppException
(
"API接口生成证照失败"
);
}
}
}
}
\ No newline at end of file
certificate-manager/src/main/java/com/mortals/xhx/module/record/web/ApplyLogController.java
View file @
037a27d2
...
@@ -2,10 +2,13 @@ package com.mortals.xhx.module.record.web;
...
@@ -2,10 +2,13 @@ package com.mortals.xhx.module.record.web;
import
com.mortals.framework.annotation.UnAuth
;
import
com.mortals.framework.annotation.UnAuth
;
import
com.mortals.framework.common.IBaseEnum
;
import
com.mortals.framework.common.IBaseEnum
;
import
com.mortals.framework.common.Rest
;
import
com.mortals.framework.common.Rest
;
import
com.mortals.framework.utils.ReflectUtils
;
import
com.mortals.framework.utils.poi.ExcelUtil
;
import
com.mortals.framework.web.BaseCRUDJsonBodyMappingController
;
import
com.mortals.framework.web.BaseCRUDJsonBodyMappingController
;
import
com.mortals.xhx.base.system.param.service.ParamService
;
import
com.mortals.xhx.base.system.param.service.ParamService
;
import
com.mortals.xhx.base.system.upload.service.UploadService
;
import
com.mortals.xhx.base.system.upload.service.UploadService
;
import
com.mortals.xhx.common.code.*
;
import
com.mortals.xhx.common.code.*
;
import
com.mortals.xhx.common.utils.ImportExcelUtil
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
...
@@ -125,4 +128,26 @@ public class ApplyLogController extends BaseCRUDJsonBodyMappingController<ApplyL
...
@@ -125,4 +128,26 @@ public class ApplyLogController extends BaseCRUDJsonBodyMappingController<ApplyL
return
ret
;
return
ret
;
}
}
@PostMapping
({
"/import"
})
public
String
importFile
(
MultipartFile
file
,
Long
catalogId
)
{
JSONObject
ret
=
new
JSONObject
();
Map
<
String
,
Object
>
model
=
new
HashMap
();
Context
context
=
this
.
getContext
();
String
busiDesc
=
"导入"
+
this
.
getModuleDesc
();
byte
code
=
1
;
try
{
String
fileName
=
file
.
getOriginalFilename
();
List
<
Map
<
Integer
,
Object
>>
returnList
=
ImportExcelUtil
.
readExcelContent
(
fileName
,
file
.
getInputStream
(),
1
,
null
,
null
);
String
message
=
this
.
service
.
importData
(
returnList
,
catalogId
,
context
);
model
.
put
(
"message_info"
,
message
);
this
.
recordSysLog
(
this
.
request
,
busiDesc
+
" 【成功】"
);
}
catch
(
Exception
var13
)
{
code
=
-
1
;
this
.
doException
(
this
.
request
,
busiDesc
,
model
,
var13
);
}
ret
.
put
(
"code"
,
Integer
.
valueOf
(
code
));
ret
.
put
(
"msg"
,
model
.
remove
(
"message_info"
));
return
ret
.
toJSONString
();
}
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment