Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
mes
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ximai
mes
Commits
a102052d
Commit
a102052d
authored
Jan 17, 2025
by
李驰骋
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/dev' into dev
parents
6b6b6e3a
0abf5625
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
1594 additions
and
164 deletions
+1594
-164
application-dev.yml
admin/src/main/resources/application-dev.yml
+4
-4
logback.xml
admin/src/main/resources/logback.xml
+1
-6
Excel.java
common/src/main/java/com/ximai/common/annotation/Excel.java
+89
-132
ExcelHandlerAdapter.java
.../java/com/ximai/common/utils/poi/ExcelHandlerAdapter.java
+13
-0
ExcelUtil.java
...n/src/main/java/com/ximai/common/utils/poi/ExcelUtil.java
+1183
-0
WorkorderStatusEnum.java
...main/java/com/ximai/mes/constant/WorkorderStatusEnum.java
+26
-13
ProTaskWorkunitQuery.java
...om/ximai/mes/pro/domain/vo/task/ProTaskWorkunitQuery.java
+2
-0
ProTaskWorkunitServiceImpl.java
...mes/pro/service/impl/task/ProTaskWorkunitServiceImpl.java
+1
-0
FeedbackController.java
...a/com/ximai/mes/report/controller/FeedbackController.java
+177
-0
WorkOrderProgressController.java
...ai/mes/report/controller/WorkOrderProgressController.java
+13
-0
WorkOrderProgressRequest.java
...om/ximai/mes/report/request/WorkOrderProgressRequest.java
+3
-1
FeedbackResponse.java
.../java/com/ximai/mes/report/response/FeedbackResponse.java
+30
-5
WorkOrderProgressFeedbackListResponse.java
...eport/response/WorkOrderProgressFeedbackListResponse.java
+1
-0
WorkOrderProgressListResponse.java
...ai/mes/report/response/WorkOrderProgressListResponse.java
+20
-0
ProFeedbackMapper.xml
mes/src/main/resources/mapper/pro/ProFeedbackMapper.xml
+21
-1
ProWorkorderMapper.xml
.../resources/mapper/pro/proWorkOrder/ProWorkorderMapper.xml
+10
-2
No files found.
admin/src/main/resources/application-dev.yml
View file @
a102052d
...
...
@@ -18,7 +18,7 @@ ximai-mes:
# 开发环境配置
server
:
# 服务器的HTTP端口,默认为8080
port
:
808
8
port
:
808
0
servlet
:
# 应用的访问路径
context-path
:
/
...
...
@@ -56,9 +56,9 @@ spring:
druid
:
# 主库数据源
master
:
url
:
jdbc:mysql://
localhost:3307
/xm_mes_dev?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username
:
root
password
:
123456
url
:
jdbc:mysql://
192.168.222.136:3306
/xm_mes_dev?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username
:
admin
password
:
t0psunit
# 从库数据源
slave
:
# 从数据源开关/默认关闭
...
...
admin/src/main/resources/logback.xml
View file @
a102052d
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 日志存放路径 -->
<property
name=
"log.path"
value=
"
d:/logs/me
s"
/>
<property
name=
"log.path"
value=
"
/home/ximai/log
s"
/>
<!-- 日志输出格式 -->
<property
name=
"log.pattern"
value=
"%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"
/>
...
...
@@ -9,7 +9,6 @@
<appender
name=
"console"
class=
"ch.qos.logback.core.ConsoleAppender"
>
<encoder>
<pattern>
${log.pattern}
</pattern>
<charset>
UTF-8
</charset>
</encoder>
</appender>
...
...
@@ -25,7 +24,6 @@
</rollingPolicy>
<encoder>
<pattern>
${log.pattern}
</pattern>
<charset>
UTF-8
</charset>
</encoder>
<filter
class=
"ch.qos.logback.classic.filter.LevelFilter"
>
<!-- 过滤的级别 -->
...
...
@@ -48,7 +46,6 @@
</rollingPolicy>
<encoder>
<pattern>
${log.pattern}
</pattern>
<charset>
UTF-8
</charset>
</encoder>
<filter
class=
"ch.qos.logback.classic.filter.LevelFilter"
>
<!-- 过滤的级别 -->
...
...
@@ -71,7 +68,6 @@
</rollingPolicy>
<encoder>
<pattern>
${log.pattern}
</pattern>
<charset>
UTF-8
</charset>
</encoder>
</appender>
...
...
@@ -86,7 +82,6 @@
</rollingPolicy>
<encoder>
<pattern>
${log.pattern}
</pattern>
<charset>
UTF-8
</charset>
</encoder>
</appender>
...
...
common/src/main/java/com/ximai/common/annotation/Excel.java
View file @
a102052d
package
com
.
ximai
.
common
.
annotation
;
import
com.ximai.common.utils.poi.ExcelHandlerAdapter
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
import
java.math.BigDecimal
;
/**
* 自定义导出Excel数据注解
*
*/
/** 自定义导出Excel数据注解 */
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
FIELD
)
public
@interface
Excel
{
/**
* 导出时在excel中排序
*/
public
int
sort
()
default
Integer
.
MAX_VALUE
;
/**
* 导出到Excel中的名字.
*/
public
String
name
()
default
""
;
/**
* 日期格式, 如: yyyy-MM-dd
*/
public
String
dateFormat
()
default
""
;
/**
* 如果是字典类型,请设置字典的type值 (如: sys_user_sex)
*/
public
String
dictType
()
default
""
;
/**
* 读取内容转表达式 (如: 0=男,1=女,2=未知)
*/
public
String
readConverterExp
()
default
""
;
/**
* 分隔符,读取字符串组内容
*/
public
String
separator
()
default
","
;
/**
* BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化)
*/
public
int
scale
()
default
-
1
;
/**
* BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN
*/
public
int
roundingMode
()
default
BigDecimal
.
ROUND_HALF_EVEN
;
/**
* 导出类型(0数字 1字符串)
*/
public
ColumnType
cellType
()
default
ColumnType
.
STRING
;
/**
* 导出时在excel中每个列的高度 单位为字符
*/
public
double
height
()
default
14
;
/**
* 导出时在excel中每个列的宽 单位为字符
*/
public
double
width
()
default
16
;
/**
* 文字后缀,如% 90 变成90%
*/
public
String
suffix
()
default
""
;
/**
* 当值为空时,字段的默认值
*/
public
String
defaultValue
()
default
""
;
/**
* 提示信息
*/
public
String
prompt
()
default
""
;
/**
* 设置只能选择不能输入的列内容.
*/
public
String
[]
combo
()
default
{};
/**
* 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
*/
public
boolean
isExport
()
default
true
;
/**
* 另一个类中的属性名称,支持多级获取,以小数点隔开
*/
public
String
targetAttr
()
default
""
;
/**
* 是否自动统计数据,在最后追加一行统计数据总和
*/
public
boolean
isStatistics
()
default
false
;
/**
* 导出字段对齐方式(0:默认;1:靠左;2:居中;3:靠右)
*/
public
Align
align
()
default
Align
.
AUTO
;
/**
* 自定义数据处理器参数
*/
public
String
[]
args
()
default
{};
public
enum
Align
{
AUTO
(
0
),
LEFT
(
1
),
CENTER
(
2
),
RIGHT
(
3
);
public
@interface
Excel
{
/** 导出时在excel中排序 */
int
sort
()
default
Integer
.
MAX_VALUE
;
/** 导出到Excel中的名字. */
String
name
()
default
""
;
/** 日期格式, 如: yyyy-MM-dd */
String
dateFormat
()
default
""
;
/** 如果是字典类型,请设置字典的type值 (如: sys_user_sex) */
String
dictType
()
default
""
;
/** 读取内容转表达式 (如: 0=男,1=女,2=未知) */
String
readConverterExp
()
default
""
;
/** 分隔符,读取字符串组内容 */
String
separator
()
default
","
;
/** BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化) */
int
scale
()
default
-
1
;
/** BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN */
int
roundingMode
()
default
BigDecimal
.
ROUND_HALF_EVEN
;
/** 导出类型(0数字 1字符串) */
ColumnType
cellType
()
default
ColumnType
.
STRING
;
/** 导出时在excel中每个列的高度 单位为字符 */
double
height
()
default
14
;
/** 导出时在excel中每个列的宽 单位为字符 */
double
width
()
default
16
;
/** 文字后缀,如% 90 变成90% */
String
suffix
()
default
""
;
/** 当值为空时,字段的默认值 */
String
defaultValue
()
default
""
;
/** 提示信息 */
String
prompt
()
default
""
;
/** 设置只能选择不能输入的列内容. */
String
[]
combo
()
default
{};
/** 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写. */
boolean
isExport
()
default
true
;
/** 另一个类中的属性名称,支持多级获取,以小数点隔开 */
String
targetAttr
()
default
""
;
/** 是否自动统计数据,在最后追加一行统计数据总和 */
boolean
isStatistics
()
default
false
;
/** 导出字段对齐方式(0:默认;1:靠左;2:居中;3:靠右) */
Align
align
()
default
Align
.
AUTO
;
/** 自定义数据处理器 */
Class
<?>
handler
()
default
ExcelHandlerAdapter
.
class
;
/** 自定义数据处理器参数 */
String
[]
args
()
default
{};
/** 字段类型(0:导出导入;1:仅导出;2:仅导入) */
Type
type
()
default
Type
.
ALL
;
enum
Align
{
AUTO
(
0
),
LEFT
(
1
),
CENTER
(
2
),
RIGHT
(
3
);
private
final
int
value
;
Align
(
int
value
)
{
Align
(
int
value
)
{
this
.
value
=
value
;
}
public
int
value
()
{
public
int
value
()
{
return
this
.
value
;
}
}
/**
* 字段类型(0:导出导入;1:仅导出;2:仅导入)
*/
Type
type
()
default
Type
.
ALL
;
public
enum
Type
{
ALL
(
0
),
EXPORT
(
1
),
IMPORT
(
2
);
enum
Type
{
ALL
(
0
),
EXPORT
(
1
),
IMPORT
(
2
);
private
final
int
value
;
Type
(
int
value
)
{
Type
(
int
value
)
{
this
.
value
=
value
;
}
public
int
value
()
{
public
int
value
()
{
return
this
.
value
;
}
}
public
enum
ColumnType
{
NUMERIC
(
0
),
STRING
(
1
),
IMAGE
(
2
);
enum
ColumnType
{
NUMERIC
(
0
),
STRING
(
1
),
IMAGE
(
2
);
private
final
int
value
;
ColumnType
(
int
value
)
{
ColumnType
(
int
value
)
{
this
.
value
=
value
;
}
public
int
value
()
{
public
int
value
()
{
return
this
.
value
;
}
}
...
...
common/src/main/java/com/ximai/common/utils/poi/ExcelHandlerAdapter.java
0 → 100644
View file @
a102052d
package
com
.
ximai
.
common
.
utils
.
poi
;
/** Excel数据格式处理适配器 */
public
interface
ExcelHandlerAdapter
{
/**
* 格式化
*
* @param value 单元格数据值
* @param args excel注解args参数组
* @return 处理后的值
*/
Object
format
(
Object
value
,
String
[]
args
);
}
common/src/main/java/com/ximai/common/utils/poi/ExcelUtil.java
0 → 100644
View file @
a102052d
package
com
.
ximai
.
common
.
utils
.
poi
;
import
com.ximai.common.annotation.Excel
;
import
com.ximai.common.annotation.Excel.ColumnType
;
import
com.ximai.common.annotation.Excel.Type
;
import
com.ximai.common.annotation.Excels
;
import
com.ximai.common.config.RuoYiConfig
;
import
com.ximai.common.core.domain.AjaxResult
;
import
com.ximai.common.core.text.Convert
;
import
com.ximai.common.exception.ServiceException
;
import
com.ximai.common.exception.UtilException
;
import
com.ximai.common.utils.DictUtils
;
import
com.ximai.common.utils.data.DateUtils
;
import
com.ximai.common.utils.data.StringUtils
;
import
com.ximai.common.utils.file.FileTypeUtils
;
import
com.ximai.common.utils.file.FileUtils
;
import
com.ximai.common.utils.file.ImageUtils
;
import
com.ximai.common.utils.reflect.ReflectUtils
;
import
org.apache.commons.lang3.RegExUtils
;
import
org.apache.poi.hssf.usermodel.*
;
import
org.apache.poi.ooxml.POIXMLDocumentPart
;
import
org.apache.poi.ss.usermodel.*
;
import
org.apache.poi.ss.util.CellRangeAddress
;
import
org.apache.poi.ss.util.CellRangeAddressList
;
import
org.apache.poi.util.IOUtils
;
import
org.apache.poi.xssf.streaming.SXSSFWorkbook
;
import
org.apache.poi.xssf.usermodel.*
;
import
org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.dao.DataAccessException
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.*
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
import
java.math.BigDecimal
;
import
java.sql.SQLException
;
import
java.text.DecimalFormat
;
import
java.time.LocalDate
;
import
java.time.LocalDateTime
;
import
java.util.*
;
import
java.util.function.Consumer
;
import
java.util.stream.Collectors
;
/**
* Excel相关处理
*/
public
class
ExcelUtil
<
T
>
{
public
static
final
String
FORMULA_REGEX_STR
=
"=|-|\\+|@"
;
public
static
final
String
[]
FORMULA_STR
=
{
"="
,
"-"
,
"+"
,
"@"
};
/**
* Excel sheet最大行数,默认65536
*/
public
static
final
int
sheetSize
=
65536
;
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
ExcelUtil
.
class
);
/**
* 数字格式
*/
private
static
final
DecimalFormat
DOUBLE_FORMAT
=
new
DecimalFormat
(
"######0.00"
);
/**
* 实体对象
*/
public
Class
<
T
>
clazz
;
/**
* 工作表名称
*/
private
String
sheetName
;
/**
* 导出类型(EXPORT:导出数据;IMPORT:导入模板)
*/
private
Type
type
;
/**
* 工作薄对象
*/
private
Workbook
wb
;
/**
* 工作表对象
*/
private
Sheet
sheet
;
/**
* 样式列表
*/
private
Map
<
String
,
CellStyle
>
styles
;
/**
* 导入导出数据列表
*/
private
List
<
T
>
list
;
/**
* 注解列表
*/
private
List
<
Object
[]>
fields
;
/**
* 当前行号
*/
private
int
rownum
;
/**
* 标题
*/
private
String
title
;
/**
* 最大高度
*/
private
short
maxHeight
;
/**
* 统计列表
*/
private
Map
<
Integer
,
Double
>
statistics
=
new
HashMap
<
Integer
,
Double
>();
public
ExcelUtil
(
Class
<
T
>
clazz
)
{
this
.
clazz
=
clazz
;
}
/**
* 获取画布
*/
public
static
Drawing
<?>
getDrawingPatriarch
(
Sheet
sheet
)
{
if
(
sheet
.
getDrawingPatriarch
()
==
null
)
{
sheet
.
createDrawingPatriarch
();
}
return
sheet
.
getDrawingPatriarch
();
}
/**
* 解析导出值 0=男,1=女,2=未知
*
* @param propertyValue 参数值
* @param converterExp 翻译注解
* @param separator 分隔符
* @return 解析后值
*/
public
static
String
convertByExp
(
String
propertyValue
,
String
converterExp
,
String
separator
)
{
StringBuilder
propertyString
=
new
StringBuilder
();
String
[]
convertSource
=
converterExp
.
split
(
","
);
for
(
String
item
:
convertSource
)
{
String
[]
itemArray
=
item
.
split
(
"="
);
if
(
StringUtils
.
containsAny
(
separator
,
propertyValue
))
{
for
(
String
value
:
propertyValue
.
split
(
separator
))
{
if
(
itemArray
[
0
].
equals
(
value
))
{
propertyString
.
append
(
itemArray
[
1
]
+
separator
);
break
;
}
}
}
else
{
if
(
itemArray
[
0
].
equals
(
propertyValue
))
{
return
itemArray
[
1
];
}
}
}
return
StringUtils
.
stripEnd
(
propertyString
.
toString
(),
separator
);
}
/**
* 反向解析值 男=0,女=1,未知=2
*
* @param propertyValue 参数值
* @param converterExp 翻译注解
* @param separator 分隔符
* @return 解析后值
*/
public
static
String
reverseByExp
(
String
propertyValue
,
String
converterExp
,
String
separator
)
{
StringBuilder
propertyString
=
new
StringBuilder
();
String
[]
convertSource
=
converterExp
.
split
(
","
);
for
(
String
item
:
convertSource
)
{
String
[]
itemArray
=
item
.
split
(
"="
);
if
(
StringUtils
.
containsAny
(
separator
,
propertyValue
))
{
for
(
String
value
:
propertyValue
.
split
(
separator
))
{
if
(
itemArray
[
1
].
equals
(
value
))
{
propertyString
.
append
(
itemArray
[
0
]
+
separator
);
break
;
}
}
}
else
{
if
(
itemArray
[
1
].
equals
(
propertyValue
))
{
return
itemArray
[
0
];
}
}
}
return
StringUtils
.
stripEnd
(
propertyString
.
toString
(),
separator
);
}
/**
* 解析字典值
*
* @param dictValue 字典值
* @param dictType 字典类型
* @param separator 分隔符
* @return 字典标签
*/
public
static
String
convertDictByExp
(
String
dictValue
,
String
dictType
,
String
separator
)
{
return
DictUtils
.
getDictLabel
(
dictType
,
dictValue
,
separator
);
}
/**
* 反向解析值字典值
*
* @param dictLabel 字典标签
* @param dictType 字典类型
* @param separator 分隔符
* @return 字典值
*/
public
static
String
reverseDictByExp
(
String
dictLabel
,
String
dictType
,
String
separator
)
{
return
DictUtils
.
getDictValue
(
dictType
,
dictLabel
,
separator
);
}
/**
* 获取Excel2003图片
*
* @param sheet 当前sheet对象
* @param workbook 工作簿对象
* @return Map key:图片单元格索引(1_1)String,value:图片流PictureData
*/
public
static
Map
<
String
,
PictureData
>
getSheetPictures03
(
HSSFSheet
sheet
,
HSSFWorkbook
workbook
)
{
Map
<
String
,
PictureData
>
sheetIndexPicMap
=
new
HashMap
<
String
,
PictureData
>();
List
<
HSSFPictureData
>
pictures
=
workbook
.
getAllPictures
();
if
(!
pictures
.
isEmpty
())
{
for
(
HSSFShape
shape
:
sheet
.
getDrawingPatriarch
().
getChildren
())
{
HSSFClientAnchor
anchor
=
(
HSSFClientAnchor
)
shape
.
getAnchor
();
if
(
shape
instanceof
HSSFPicture
)
{
HSSFPicture
pic
=
(
HSSFPicture
)
shape
;
int
pictureIndex
=
pic
.
getPictureIndex
()
-
1
;
HSSFPictureData
picData
=
pictures
.
get
(
pictureIndex
);
String
picIndex
=
String
.
valueOf
(
anchor
.
getRow1
())
+
"_"
+
String
.
valueOf
(
anchor
.
getCol1
());
sheetIndexPicMap
.
put
(
picIndex
,
picData
);
}
}
return
sheetIndexPicMap
;
}
else
{
return
sheetIndexPicMap
;
}
}
/**
* 获取Excel2007图片
*
* @param sheet 当前sheet对象
* @param workbook 工作簿对象
* @return Map key:图片单元格索引(1_1)String,value:图片流PictureData
*/
public
static
Map
<
String
,
PictureData
>
getSheetPictures07
(
XSSFSheet
sheet
,
XSSFWorkbook
workbook
)
{
Map
<
String
,
PictureData
>
sheetIndexPicMap
=
new
HashMap
<
String
,
PictureData
>();
for
(
POIXMLDocumentPart
dr
:
sheet
.
getRelations
())
{
if
(
dr
instanceof
XSSFDrawing
)
{
XSSFDrawing
drawing
=
(
XSSFDrawing
)
dr
;
List
<
XSSFShape
>
shapes
=
drawing
.
getShapes
();
for
(
XSSFShape
shape
:
shapes
)
{
if
(
shape
instanceof
XSSFPicture
)
{
XSSFPicture
pic
=
(
XSSFPicture
)
shape
;
XSSFClientAnchor
anchor
=
pic
.
getPreferredSize
();
CTMarker
ctMarker
=
anchor
.
getFrom
();
String
picIndex
=
ctMarker
.
getRow
()
+
"_"
+
ctMarker
.
getCol
();
sheetIndexPicMap
.
put
(
picIndex
,
pic
.
getPictureData
());
}
}
}
}
return
sheetIndexPicMap
;
}
public
void
init
(
List
<
T
>
list
,
String
sheetName
,
String
title
,
Type
type
)
{
if
(
list
==
null
)
{
list
=
new
ArrayList
<
T
>();
}
this
.
list
=
list
;
this
.
sheetName
=
sheetName
;
this
.
type
=
type
;
this
.
title
=
title
;
createExcelField
();
createWorkbook
();
createTitle
();
}
/**
* 创建excel第一行标题
*/
public
void
createTitle
()
{
if
(
StringUtils
.
isNotEmpty
(
title
))
{
Row
titleRow
=
sheet
.
createRow
(
rownum
==
0
?
rownum
++
:
0
);
titleRow
.
setHeightInPoints
(
30
);
Cell
titleCell
=
titleRow
.
createCell
(
0
);
titleCell
.
setCellStyle
(
styles
.
get
(
"title"
));
titleCell
.
setCellValue
(
title
);
sheet
.
addMergedRegion
(
new
CellRangeAddress
(
titleRow
.
getRowNum
(),
titleRow
.
getRowNum
(),
titleRow
.
getRowNum
(),
this
.
fields
.
size
()
-
1
));
}
}
/**
* 对excel表单默认第一个索引名转换成list
*
* @param is 输入流
* @return 转换后集合
*/
public
List
<
T
>
importExcel
(
InputStream
is
)
throws
Exception
{
return
importExcel
(
is
,
0
);
}
public
void
importExcel
(
InputStream
is
,
Consumer
<
T
>
header
)
throws
Exception
{
List
<
T
>
list
=
importExcel
(
is
,
0
);
StringBuffer
failureMsg
=
new
StringBuffer
();
int
i
=
1
;
for
(
T
t
:
list
)
{
try
{
header
.
accept
(
t
);
}
catch
(
Exception
e
)
{
Exception
outputException
=
getOutputException
(
e
);
String
msg
=
String
.
format
(
"第%s行数据导入失败,%s"
,
i
,
outputException
.
getMessage
());
failureMsg
.
append
(
msg
);
}
i
++;
}
if
(!
""
.
equals
(
failureMsg
.
toString
()))
{
throw
new
ServiceException
(
failureMsg
.
toString
());
}
}
private
Exception
getOutputException
(
Exception
ex
)
{
if
(
ex
instanceof
ServiceException
)
{
return
ex
;
}
if
(
ex
instanceof
DataAccessException
)
{
SQLException
sqlException
=
deepFindSQLException
((
DataAccessException
)
ex
);
if
(
sqlException
!=
null
)
{
switch
(
sqlException
.
getErrorCode
())
{
case
1062
:
return
new
ServiceException
(
"该数据已被添加,如需修改请使用编辑功能"
,
ex
);
case
2627
:
return
new
ServiceException
(
"该数据已被添加,如需修改请使用编辑功能"
,
ex
);
case
1451
:
case
547
:
return
new
ServiceException
(
"该数据已经被其他数据引用,不能删除"
,
ex
);
default
:
break
;
}
}
}
return
ex
;
}
private
SQLException
deepFindSQLException
(
DataAccessException
ex
)
{
int
varDeep
=
3
;
Throwable
current
=
ex
.
getCause
();
while
(
varDeep
>
0
)
{
if
(
current
==
null
)
{
return
null
;
}
if
(
current
instanceof
SQLException
)
{
return
(
SQLException
)
current
;
}
current
=
current
.
getCause
();
varDeep
--;
}
return
null
;
}
/**
* 对excel表单默认第一个索引名转换成list
*
* @param is 输入流
* @param titleNum 标题占用行数
* @return 转换后集合
*/
public
List
<
T
>
importExcel
(
InputStream
is
,
int
titleNum
)
throws
Exception
{
return
importExcel
(
StringUtils
.
EMPTY
,
is
,
titleNum
);
}
/**
* 对excel表单指定表格索引名转换成list
*
* @param sheetName 表格索引名
* @param titleNum 标题占用行数
* @param is 输入流
* @return 转换后集合
*/
public
List
<
T
>
importExcel
(
String
sheetName
,
InputStream
is
,
int
titleNum
)
throws
Exception
{
this
.
type
=
Type
.
IMPORT
;
this
.
wb
=
WorkbookFactory
.
create
(
is
);
List
<
T
>
list
=
new
ArrayList
<
T
>();
// 如果指定sheet名,则取指定sheet中的内容 否则默认指向第1个sheet
Sheet
sheet
=
StringUtils
.
isNotEmpty
(
sheetName
)
?
wb
.
getSheet
(
sheetName
)
:
wb
.
getSheetAt
(
0
);
if
(
sheet
==
null
)
{
throw
new
IOException
(
"文件sheet不存在"
);
}
boolean
isXSSFWorkbook
=
!(
wb
instanceof
HSSFWorkbook
);
Map
<
String
,
PictureData
>
pictures
;
if
(
isXSSFWorkbook
)
{
pictures
=
getSheetPictures07
((
XSSFSheet
)
sheet
,
(
XSSFWorkbook
)
wb
);
}
else
{
pictures
=
getSheetPictures03
((
HSSFSheet
)
sheet
,
(
HSSFWorkbook
)
wb
);
}
// 获取最后一个非空行的行下标,比如总行数为n,则返回的为n-1
int
rows
=
sheet
.
getLastRowNum
();
if
(
rows
>
0
)
{
// 定义一个map用于存放excel列的序号和field.
Map
<
String
,
Integer
>
cellMap
=
new
HashMap
<
String
,
Integer
>();
// 获取表头
Row
heard
=
sheet
.
getRow
(
titleNum
);
for
(
int
i
=
0
;
i
<
heard
.
getPhysicalNumberOfCells
();
i
++)
{
Cell
cell
=
heard
.
getCell
(
i
);
if
(
StringUtils
.
isNotNull
(
cell
))
{
String
value
=
this
.
getCellValue
(
heard
,
i
).
toString
();
cellMap
.
put
(
value
,
i
);
}
else
{
cellMap
.
put
(
null
,
i
);
}
}
// 有数据时才处理 得到类的所有field.
List
<
Object
[]>
fields
=
this
.
getFields
();
Map
<
Integer
,
Object
[]>
fieldsMap
=
new
HashMap
<
Integer
,
Object
[]>();
for
(
Object
[]
objects
:
fields
)
{
Excel
attr
=
(
Excel
)
objects
[
1
];
Integer
column
=
cellMap
.
get
(
attr
.
name
());
if
(
column
!=
null
)
{
fieldsMap
.
put
(
column
,
objects
);
}
}
for
(
int
i
=
titleNum
+
1
;
i
<=
rows
;
i
++)
{
// 从第2行开始取数据,默认第一行是表头.
Row
row
=
sheet
.
getRow
(
i
);
// 判断当前行是否是空行
if
(
isRowEmpty
(
row
))
{
continue
;
}
T
entity
=
null
;
for
(
Map
.
Entry
<
Integer
,
Object
[]>
entry
:
fieldsMap
.
entrySet
())
{
Object
val
=
this
.
getCellValue
(
row
,
entry
.
getKey
());
// 如果不存在实例则新建.
entity
=
(
entity
==
null
?
clazz
.
newInstance
()
:
entity
);
// 从map中得到对应列的field.
Field
field
=
(
Field
)
entry
.
getValue
()[
0
];
Excel
attr
=
(
Excel
)
entry
.
getValue
()[
1
];
// 取得类型,并根据对象类型设置值.
Class
<?>
fieldType
=
field
.
getType
();
if
(
String
.
class
==
fieldType
)
{
String
s
=
Convert
.
toStr
(
val
);
if
(
StringUtils
.
endsWith
(
s
,
".0"
))
{
val
=
StringUtils
.
substringBefore
(
s
,
".0"
);
}
else
{
String
dateFormat
=
field
.
getAnnotation
(
Excel
.
class
).
dateFormat
();
if
(
StringUtils
.
isNotEmpty
(
dateFormat
))
{
val
=
parseDateToStr
(
dateFormat
,
val
);
}
else
{
val
=
Convert
.
toStr
(
val
);
}
}
}
else
if
((
Integer
.
TYPE
==
fieldType
||
Integer
.
class
==
fieldType
)
&&
StringUtils
.
isNumeric
(
Convert
.
toStr
(
val
)))
{
val
=
Convert
.
toInt
(
val
);
}
else
if
((
Long
.
TYPE
==
fieldType
||
Long
.
class
==
fieldType
)
&&
StringUtils
.
isNumeric
(
Convert
.
toStr
(
val
)))
{
val
=
Convert
.
toLong
(
val
);
}
else
if
(
Double
.
TYPE
==
fieldType
||
Double
.
class
==
fieldType
)
{
val
=
Convert
.
toDouble
(
val
);
}
else
if
(
Float
.
TYPE
==
fieldType
||
Float
.
class
==
fieldType
)
{
val
=
Convert
.
toFloat
(
val
);
}
else
if
(
BigDecimal
.
class
==
fieldType
)
{
val
=
Convert
.
toBigDecimal
(
val
);
}
else
if
(
Date
.
class
==
fieldType
)
{
if
(
val
instanceof
String
)
{
val
=
DateUtils
.
parseDate
(
val
);
}
else
if
(
val
instanceof
Double
)
{
val
=
DateUtil
.
getJavaDate
((
Double
)
val
);
}
}
else
if
(
Boolean
.
TYPE
==
fieldType
||
Boolean
.
class
==
fieldType
)
{
val
=
Convert
.
toBool
(
val
,
false
);
}
if
(
StringUtils
.
isNotNull
(
fieldType
))
{
String
propertyName
=
field
.
getName
();
if
(
StringUtils
.
isNotEmpty
(
attr
.
targetAttr
()))
{
propertyName
=
field
.
getName
()
+
"."
+
attr
.
targetAttr
();
}
else
if
(
StringUtils
.
isNotEmpty
(
attr
.
readConverterExp
()))
{
val
=
reverseByExp
(
Convert
.
toStr
(
val
),
attr
.
readConverterExp
(),
attr
.
separator
());
}
else
if
(
StringUtils
.
isNotEmpty
(
attr
.
dictType
()))
{
val
=
reverseDictByExp
(
Convert
.
toStr
(
val
),
attr
.
dictType
(),
attr
.
separator
());
}
else
if
(!
attr
.
handler
().
equals
(
ExcelHandlerAdapter
.
class
))
{
val
=
dataFormatHandlerAdapter
(
val
,
attr
);
}
else
if
(
ColumnType
.
IMAGE
==
attr
.
cellType
()
&&
StringUtils
.
isNotEmpty
(
pictures
))
{
PictureData
image
=
pictures
.
get
(
row
.
getRowNum
()
+
"_"
+
entry
.
getKey
());
if
(
image
==
null
)
{
val
=
""
;
}
else
{
byte
[]
data
=
image
.
getData
();
val
=
FileUtils
.
writeImportBytes
(
data
);
}
}
ReflectUtils
.
invokeSetter
(
entity
,
propertyName
,
val
);
}
}
list
.
add
(
entity
);
}
}
return
list
;
}
/**
* 对list数据源将其里面的数据导入到excel表单
*
* @param list 导出数据集合
* @param sheetName 工作表的名称
* @return 结果
*/
public
AjaxResult
exportExcel
(
List
<
T
>
list
,
String
sheetName
)
{
return
exportExcel
(
list
,
sheetName
,
StringUtils
.
EMPTY
);
}
/**
* 对list数据源将其里面的数据导入到excel表单
*
* @param list 导出数据集合
* @param sheetName 工作表的名称
* @param title 标题
* @return 结果
*/
public
AjaxResult
exportExcel
(
List
<
T
>
list
,
String
sheetName
,
String
title
)
{
this
.
init
(
list
,
sheetName
,
title
,
Type
.
EXPORT
);
return
exportExcel
();
}
/**
* 对list数据源将其里面的数据导入到excel表单
*
* @param response 返回数据
* @param list 导出数据集合
* @param sheetName 工作表的名称
* @return 结果
*/
public
void
exportExcel
(
HttpServletResponse
response
,
List
<
T
>
list
,
String
sheetName
)
{
exportExcel
(
response
,
list
,
sheetName
,
StringUtils
.
EMPTY
);
}
/**
* 对list数据源将其里面的数据导入到excel表单
*
* @param response 返回数据
* @param list 导出数据集合
* @param sheetName 工作表的名称
* @param title 标题
* @return 结果
*/
public
void
exportExcel
(
HttpServletResponse
response
,
List
<
T
>
list
,
String
sheetName
,
String
title
)
{
response
.
setContentType
(
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
);
response
.
setCharacterEncoding
(
"utf-8"
);
this
.
init
(
list
,
sheetName
,
title
,
Type
.
EXPORT
);
exportExcel
(
response
);
}
/**
* 对list数据源将其里面的数据导入到excel表单
*
* @param sheetName 工作表的名称
* @return 结果
*/
public
AjaxResult
importTemplateExcel
(
String
sheetName
)
{
return
importTemplateExcel
(
sheetName
,
StringUtils
.
EMPTY
);
}
/**
* 对list数据源将其里面的数据导入到excel表单
*
* @param sheetName 工作表的名称
* @param title 标题
* @return 结果
*/
public
AjaxResult
importTemplateExcel
(
String
sheetName
,
String
title
)
{
this
.
init
(
null
,
sheetName
,
title
,
Type
.
IMPORT
);
return
exportExcel
();
}
/**
* 对list数据源将其里面的数据导入到excel表单
*
* @param sheetName 工作表的名称
* @return 结果
*/
public
void
importTemplateExcel
(
HttpServletResponse
response
,
String
sheetName
)
{
importTemplateExcel
(
response
,
sheetName
,
StringUtils
.
EMPTY
);
}
/**
* 对list数据源将其里面的数据导入到excel表单
*
* @param sheetName 工作表的名称
* @param title 标题
* @return 结果
*/
public
void
importTemplateExcel
(
HttpServletResponse
response
,
String
sheetName
,
String
title
)
{
response
.
setContentType
(
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
);
response
.
setCharacterEncoding
(
"utf-8"
);
this
.
init
(
null
,
sheetName
,
title
,
Type
.
IMPORT
);
exportExcel
(
response
);
}
/**
* 对list数据源将其里面的数据导入到excel表单
*
* @return 结果
*/
public
void
exportExcel
(
HttpServletResponse
response
)
{
try
{
writeSheet
();
wb
.
write
(
response
.
getOutputStream
());
}
catch
(
Exception
e
)
{
log
.
error
(
"导出Excel异常{}"
,
e
.
getMessage
());
}
finally
{
IOUtils
.
closeQuietly
(
wb
);
}
}
/**
* 对list数据源将其里面的数据导入到excel表单
*
* @return 结果
*/
public
AjaxResult
exportExcel
()
{
OutputStream
out
=
null
;
try
{
writeSheet
();
String
filename
=
encodingFilename
(
sheetName
);
out
=
new
FileOutputStream
(
getAbsoluteFile
(
filename
));
wb
.
write
(
out
);
return
AjaxResult
.
success
(
filename
);
}
catch
(
Exception
e
)
{
log
.
error
(
"导出Excel异常{}"
,
e
.
getMessage
());
throw
new
UtilException
(
"导出Excel失败,请联系网站管理员!"
);
}
finally
{
IOUtils
.
closeQuietly
(
wb
);
IOUtils
.
closeQuietly
(
out
);
}
}
/**
* 创建写入数据到Sheet
*/
public
void
writeSheet
()
{
// 取出一共有多少个sheet.
int
sheetNo
=
Math
.
max
(
1
,
(
int
)
Math
.
ceil
(
list
.
size
()
*
1.0
/
sheetSize
));
for
(
int
index
=
0
;
index
<
sheetNo
;
index
++)
{
createSheet
(
sheetNo
,
index
);
// 产生一行
Row
row
=
sheet
.
createRow
(
rownum
);
int
column
=
0
;
// 写入各个字段的列头名称
for
(
Object
[]
os
:
fields
)
{
Excel
excel
=
(
Excel
)
os
[
1
];
this
.
createCell
(
excel
,
row
,
column
++);
}
if
(
Type
.
EXPORT
.
equals
(
type
))
{
fillExcelData
(
index
,
row
);
addStatisticsRow
();
}
}
}
/**
* 填充excel数据
*
* @param index 序号
* @param row 单元格行
*/
public
void
fillExcelData
(
int
index
,
Row
row
)
{
int
startNo
=
index
*
sheetSize
;
int
endNo
=
Math
.
min
(
startNo
+
sheetSize
,
list
.
size
());
for
(
int
i
=
startNo
;
i
<
endNo
;
i
++)
{
row
=
sheet
.
createRow
(
i
+
1
+
rownum
-
startNo
);
// 得到导出对象.
T
vo
=
(
T
)
list
.
get
(
i
);
int
column
=
0
;
for
(
Object
[]
os
:
fields
)
{
Field
field
=
(
Field
)
os
[
0
];
Excel
excel
=
(
Excel
)
os
[
1
];
this
.
addCell
(
excel
,
row
,
vo
,
field
,
column
++);
}
}
}
/**
* 创建表格样式
*
* @param wb 工作薄对象
* @return 样式列表
*/
private
Map
<
String
,
CellStyle
>
createStyles
(
Workbook
wb
)
{
// 写入各条记录,每条记录对应excel表中的一行
Map
<
String
,
CellStyle
>
styles
=
new
HashMap
<
String
,
CellStyle
>();
CellStyle
style
=
wb
.
createCellStyle
();
style
.
setAlignment
(
HorizontalAlignment
.
CENTER
);
style
.
setVerticalAlignment
(
VerticalAlignment
.
CENTER
);
Font
titleFont
=
wb
.
createFont
();
titleFont
.
setFontName
(
"Arial"
);
titleFont
.
setFontHeightInPoints
((
short
)
16
);
titleFont
.
setBold
(
true
);
style
.
setFont
(
titleFont
);
styles
.
put
(
"title"
,
style
);
style
=
wb
.
createCellStyle
();
style
.
setAlignment
(
HorizontalAlignment
.
CENTER
);
style
.
setVerticalAlignment
(
VerticalAlignment
.
CENTER
);
style
.
setBorderRight
(
BorderStyle
.
THIN
);
style
.
setRightBorderColor
(
IndexedColors
.
GREY_50_PERCENT
.
getIndex
());
style
.
setBorderLeft
(
BorderStyle
.
THIN
);
style
.
setLeftBorderColor
(
IndexedColors
.
GREY_50_PERCENT
.
getIndex
());
style
.
setBorderTop
(
BorderStyle
.
THIN
);
style
.
setTopBorderColor
(
IndexedColors
.
GREY_50_PERCENT
.
getIndex
());
style
.
setBorderBottom
(
BorderStyle
.
THIN
);
style
.
setBottomBorderColor
(
IndexedColors
.
GREY_50_PERCENT
.
getIndex
());
Font
dataFont
=
wb
.
createFont
();
dataFont
.
setFontName
(
"Arial"
);
dataFont
.
setFontHeightInPoints
((
short
)
10
);
style
.
setFont
(
dataFont
);
styles
.
put
(
"data"
,
style
);
style
=
wb
.
createCellStyle
();
style
.
cloneStyleFrom
(
styles
.
get
(
"data"
));
style
.
setAlignment
(
HorizontalAlignment
.
CENTER
);
style
.
setVerticalAlignment
(
VerticalAlignment
.
CENTER
);
style
.
setFillForegroundColor
(
IndexedColors
.
GREY_50_PERCENT
.
getIndex
());
style
.
setFillPattern
(
FillPatternType
.
SOLID_FOREGROUND
);
Font
headerFont
=
wb
.
createFont
();
headerFont
.
setFontName
(
"Arial"
);
headerFont
.
setFontHeightInPoints
((
short
)
10
);
headerFont
.
setBold
(
true
);
headerFont
.
setColor
(
IndexedColors
.
WHITE
.
getIndex
());
style
.
setFont
(
headerFont
);
styles
.
put
(
"header"
,
style
);
style
=
wb
.
createCellStyle
();
style
.
setAlignment
(
HorizontalAlignment
.
CENTER
);
style
.
setVerticalAlignment
(
VerticalAlignment
.
CENTER
);
Font
totalFont
=
wb
.
createFont
();
totalFont
.
setFontName
(
"Arial"
);
totalFont
.
setFontHeightInPoints
((
short
)
10
);
style
.
setFont
(
totalFont
);
styles
.
put
(
"total"
,
style
);
style
=
wb
.
createCellStyle
();
style
.
cloneStyleFrom
(
styles
.
get
(
"data"
));
style
.
setAlignment
(
HorizontalAlignment
.
LEFT
);
styles
.
put
(
"data1"
,
style
);
style
=
wb
.
createCellStyle
();
style
.
cloneStyleFrom
(
styles
.
get
(
"data"
));
style
.
setAlignment
(
HorizontalAlignment
.
CENTER
);
styles
.
put
(
"data2"
,
style
);
style
=
wb
.
createCellStyle
();
style
.
cloneStyleFrom
(
styles
.
get
(
"data"
));
style
.
setAlignment
(
HorizontalAlignment
.
RIGHT
);
styles
.
put
(
"data3"
,
style
);
return
styles
;
}
/**
* 创建单元格
*/
public
Cell
createCell
(
Excel
attr
,
Row
row
,
int
column
)
{
// 创建列
Cell
cell
=
row
.
createCell
(
column
);
// 写入列信息
cell
.
setCellValue
(
attr
.
name
());
setDataValidation
(
attr
,
row
,
column
);
cell
.
setCellStyle
(
styles
.
get
(
"header"
));
return
cell
;
}
/**
* 设置单元格信息
*
* @param value 单元格值
* @param attr 注解相关
* @param cell 单元格信息
*/
public
void
setCellVo
(
Object
value
,
Excel
attr
,
Cell
cell
)
{
if
(
ColumnType
.
STRING
==
attr
.
cellType
())
{
String
cellValue
=
Convert
.
toStr
(
value
);
// 对于任何以表达式触发字符 =-+@开头的单元格,直接使用tab字符作为前缀,防止CSV注入。
if
(
StringUtils
.
startsWithAny
(
cellValue
,
FORMULA_STR
))
{
cellValue
=
RegExUtils
.
replaceFirst
(
cellValue
,
FORMULA_REGEX_STR
,
"\t$0"
);
}
cell
.
setCellValue
(
StringUtils
.
isNull
(
cellValue
)
?
attr
.
defaultValue
()
:
cellValue
+
attr
.
suffix
());
}
else
if
(
ColumnType
.
NUMERIC
==
attr
.
cellType
())
{
if
(
StringUtils
.
isNotNull
(
value
))
{
cell
.
setCellValue
(
StringUtils
.
contains
(
Convert
.
toStr
(
value
),
"."
)
?
Convert
.
toDouble
(
value
)
:
Convert
.
toInt
(
value
));
}
}
else
if
(
ColumnType
.
IMAGE
==
attr
.
cellType
())
{
ClientAnchor
anchor
=
new
XSSFClientAnchor
(
0
,
0
,
0
,
0
,
(
short
)
cell
.
getColumnIndex
(),
cell
.
getRow
().
getRowNum
(),
(
short
)
(
cell
.
getColumnIndex
()
+
1
),
cell
.
getRow
().
getRowNum
()
+
1
);
String
imagePath
=
Convert
.
toStr
(
value
);
if
(
StringUtils
.
isNotEmpty
(
imagePath
))
{
byte
[]
data
=
ImageUtils
.
getImage
(
imagePath
);
getDrawingPatriarch
(
cell
.
getSheet
()).
createPicture
(
anchor
,
cell
.
getSheet
().
getWorkbook
().
addPicture
(
data
,
getImageType
(
data
)));
}
}
}
/**
* 获取图片类型,设置图片插入类型
*/
public
int
getImageType
(
byte
[]
value
)
{
String
type
=
FileTypeUtils
.
getFileExtendName
(
value
);
if
(
"JPG"
.
equalsIgnoreCase
(
type
))
{
return
Workbook
.
PICTURE_TYPE_JPEG
;
}
else
if
(
"PNG"
.
equalsIgnoreCase
(
type
))
{
return
Workbook
.
PICTURE_TYPE_PNG
;
}
return
Workbook
.
PICTURE_TYPE_JPEG
;
}
/**
* 创建表格样式
*/
public
void
setDataValidation
(
Excel
attr
,
Row
row
,
int
column
)
{
if
(
attr
.
name
().
indexOf
(
"注:"
)
>=
0
)
{
sheet
.
setColumnWidth
(
column
,
6000
);
}
else
{
// 设置列宽
sheet
.
setColumnWidth
(
column
,
(
int
)
((
attr
.
width
()
+
0.72
)
*
256
));
}
if
(
StringUtils
.
isNotEmpty
(
attr
.
prompt
())
||
attr
.
combo
().
length
>
0
)
{
// 提示信息或只能选择不能输入的列内容.
setPromptOrValidation
(
sheet
,
attr
.
combo
(),
attr
.
prompt
(),
1
,
100
,
column
,
column
);
}
}
/**
* 添加单元格
*/
public
Cell
addCell
(
Excel
attr
,
Row
row
,
T
vo
,
Field
field
,
int
column
)
{
Cell
cell
=
null
;
try
{
// 设置行高
row
.
setHeight
(
maxHeight
);
// 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列.
if
(
attr
.
isExport
())
{
// 创建cell
cell
=
row
.
createCell
(
column
);
int
align
=
attr
.
align
().
value
();
cell
.
setCellStyle
(
styles
.
get
(
"data"
+
(
align
>=
1
&&
align
<=
3
?
align
:
""
)));
// 用于读取对象中的属性
Object
value
=
getTargetValue
(
vo
,
field
,
attr
);
String
dateFormat
=
attr
.
dateFormat
();
String
readConverterExp
=
attr
.
readConverterExp
();
String
separator
=
attr
.
separator
();
String
dictType
=
attr
.
dictType
();
if
(
StringUtils
.
isNotEmpty
(
dateFormat
)
&&
StringUtils
.
isNotNull
(
value
))
{
cell
.
setCellValue
(
parseDateToStr
(
dateFormat
,
value
));
}
else
if
(
StringUtils
.
isNotEmpty
(
readConverterExp
)
&&
StringUtils
.
isNotNull
(
value
))
{
cell
.
setCellValue
(
convertByExp
(
Convert
.
toStr
(
value
),
readConverterExp
,
separator
));
}
else
if
(
StringUtils
.
isNotEmpty
(
dictType
)
&&
StringUtils
.
isNotNull
(
value
))
{
cell
.
setCellValue
(
convertDictByExp
(
Convert
.
toStr
(
value
),
dictType
,
separator
));
}
else
if
(
value
instanceof
BigDecimal
&&
-
1
!=
attr
.
scale
())
{
cell
.
setCellValue
((((
BigDecimal
)
value
).
setScale
(
attr
.
scale
(),
attr
.
roundingMode
())).
toString
());
}
else
if
(!
attr
.
handler
().
equals
(
ExcelHandlerAdapter
.
class
))
{
cell
.
setCellValue
(
dataFormatHandlerAdapter
(
value
,
attr
));
}
else
{
// 设置列类型
setCellVo
(
value
,
attr
,
cell
);
}
addStatisticsData
(
column
,
Convert
.
toStr
(
value
),
attr
);
}
}
catch
(
Exception
e
)
{
log
.
error
(
"导出Excel失败{}"
,
e
);
}
return
cell
;
}
/**
* 设置 POI XSSFSheet 单元格提示或选择框
*
* @param sheet 表单
* @param textlist 下拉框显示的内容
* @param promptContent 提示内容
* @param firstRow 开始行
* @param endRow 结束行
* @param firstCol 开始列
* @param endCol 结束列
*/
public
void
setPromptOrValidation
(
Sheet
sheet
,
String
[]
textlist
,
String
promptContent
,
int
firstRow
,
int
endRow
,
int
firstCol
,
int
endCol
)
{
DataValidationHelper
helper
=
sheet
.
getDataValidationHelper
();
DataValidationConstraint
constraint
=
textlist
.
length
>
0
?
helper
.
createExplicitListConstraint
(
textlist
)
:
helper
.
createCustomConstraint
(
"DD1"
);
CellRangeAddressList
regions
=
new
CellRangeAddressList
(
firstRow
,
endRow
,
firstCol
,
endCol
);
DataValidation
dataValidation
=
helper
.
createValidation
(
constraint
,
regions
);
if
(
StringUtils
.
isNotEmpty
(
promptContent
))
{
// 如果设置了提示信息则鼠标放上去提示
dataValidation
.
createPromptBox
(
""
,
promptContent
);
dataValidation
.
setShowPromptBox
(
true
);
}
// 处理Excel兼容性问题
if
(
dataValidation
instanceof
XSSFDataValidation
)
{
dataValidation
.
setSuppressDropDownArrow
(
true
);
dataValidation
.
setShowErrorBox
(
true
);
}
else
{
dataValidation
.
setSuppressDropDownArrow
(
false
);
}
sheet
.
addValidationData
(
dataValidation
);
}
/**
* 数据处理器
*
* @param value 数据值
* @param excel 数据注解
* @return
*/
public
String
dataFormatHandlerAdapter
(
Object
value
,
Excel
excel
)
{
try
{
Object
instance
=
excel
.
handler
().
newInstance
();
Method
formatMethod
=
excel
.
handler
().
getMethod
(
"format"
,
new
Class
[]{
Object
.
class
,
String
[].
class
});
value
=
formatMethod
.
invoke
(
instance
,
value
,
excel
.
args
());
}
catch
(
Exception
e
)
{
log
.
error
(
"不能格式化数据 "
+
excel
.
handler
(),
e
.
getMessage
());
}
return
Convert
.
toStr
(
value
);
}
/**
* 合计统计信息
*/
private
void
addStatisticsData
(
Integer
index
,
String
text
,
Excel
entity
)
{
if
(
entity
!=
null
&&
entity
.
isStatistics
())
{
Double
temp
=
0
D
;
if
(!
statistics
.
containsKey
(
index
))
{
statistics
.
put
(
index
,
temp
);
}
try
{
temp
=
Double
.
valueOf
(
text
);
}
catch
(
NumberFormatException
e
)
{
}
statistics
.
put
(
index
,
statistics
.
get
(
index
)
+
temp
);
}
}
/**
* 创建统计行
*/
public
void
addStatisticsRow
()
{
if
(
statistics
.
size
()
>
0
)
{
Row
row
=
sheet
.
createRow
(
sheet
.
getLastRowNum
()
+
1
);
Set
<
Integer
>
keys
=
statistics
.
keySet
();
Cell
cell
=
row
.
createCell
(
0
);
cell
.
setCellStyle
(
styles
.
get
(
"total"
));
cell
.
setCellValue
(
"合计"
);
for
(
Integer
key
:
keys
)
{
cell
=
row
.
createCell
(
key
);
cell
.
setCellStyle
(
styles
.
get
(
"total"
));
cell
.
setCellValue
(
DOUBLE_FORMAT
.
format
(
statistics
.
get
(
key
)));
}
statistics
.
clear
();
}
}
/**
* 编码文件名
*/
public
String
encodingFilename
(
String
filename
)
{
filename
=
UUID
.
randomUUID
().
toString
()
+
"_"
+
filename
+
".xlsx"
;
return
filename
;
}
/**
* 获取下载路径
*
* @param filename 文件名称
*/
public
String
getAbsoluteFile
(
String
filename
)
{
String
downloadPath
=
RuoYiConfig
.
getDownloadPath
()
+
filename
;
File
desc
=
new
File
(
downloadPath
);
if
(!
desc
.
getParentFile
().
exists
())
{
desc
.
getParentFile
().
mkdirs
();
}
return
downloadPath
;
}
/**
* 获取bean中的属性值
*
* @param vo 实体对象
* @param field 字段
* @param excel 注解
* @return 最终的属性值
* @throws Exception
*/
private
Object
getTargetValue
(
T
vo
,
Field
field
,
Excel
excel
)
throws
Exception
{
Object
o
=
field
.
get
(
vo
);
if
(
StringUtils
.
isNotEmpty
(
excel
.
targetAttr
()))
{
String
target
=
excel
.
targetAttr
();
if
(
target
.
contains
(
"."
))
{
String
[]
targets
=
target
.
split
(
"[.]"
);
for
(
String
name
:
targets
)
{
o
=
getValue
(
o
,
name
);
}
}
else
{
o
=
getValue
(
o
,
target
);
}
}
return
o
;
}
/**
* 以类的属性的get方法方法形式获取值
*
* @param o
* @param name
* @return value
* @throws Exception
*/
private
Object
getValue
(
Object
o
,
String
name
)
throws
Exception
{
if
(
StringUtils
.
isNotNull
(
o
)
&&
StringUtils
.
isNotEmpty
(
name
))
{
Class
<?>
clazz
=
o
.
getClass
();
Field
field
=
clazz
.
getDeclaredField
(
name
);
field
.
setAccessible
(
true
);
o
=
field
.
get
(
o
);
}
return
o
;
}
/**
* 得到所有定义字段
*/
private
void
createExcelField
()
{
this
.
fields
=
getFields
();
this
.
fields
=
this
.
fields
.
stream
().
sorted
(
Comparator
.
comparing
(
objects
->
((
Excel
)
objects
[
1
]).
sort
())).
collect
(
Collectors
.
toList
());
this
.
maxHeight
=
getRowHeight
();
}
/**
* 获取字段注解信息
*/
public
List
<
Object
[]>
getFields
()
{
List
<
Object
[]>
fields
=
new
ArrayList
<
Object
[]>();
List
<
Field
>
tempFields
=
new
ArrayList
<>();
tempFields
.
addAll
(
Arrays
.
asList
(
clazz
.
getSuperclass
().
getDeclaredFields
()));
tempFields
.
addAll
(
Arrays
.
asList
(
clazz
.
getDeclaredFields
()));
for
(
Field
field
:
tempFields
)
{
// 单注解
if
(
field
.
isAnnotationPresent
(
Excel
.
class
))
{
Excel
attr
=
field
.
getAnnotation
(
Excel
.
class
);
if
(
attr
!=
null
&&
(
attr
.
type
()
==
Type
.
ALL
||
attr
.
type
()
==
type
))
{
field
.
setAccessible
(
true
);
fields
.
add
(
new
Object
[]{
field
,
attr
});
}
}
// 多注解
if
(
field
.
isAnnotationPresent
(
Excels
.
class
))
{
Excels
attrs
=
field
.
getAnnotation
(
Excels
.
class
);
Excel
[]
excels
=
attrs
.
value
();
for
(
Excel
attr
:
excels
)
{
if
(
attr
!=
null
&&
(
attr
.
type
()
==
Type
.
ALL
||
attr
.
type
()
==
type
))
{
field
.
setAccessible
(
true
);
fields
.
add
(
new
Object
[]{
field
,
attr
});
}
}
}
}
return
fields
;
}
/**
* 根据注解获取最大行高
*/
public
short
getRowHeight
()
{
double
maxHeight
=
0
;
for
(
Object
[]
os
:
this
.
fields
)
{
Excel
excel
=
(
Excel
)
os
[
1
];
maxHeight
=
Math
.
max
(
maxHeight
,
excel
.
height
());
}
return
(
short
)
(
maxHeight
*
20
);
}
/**
* 创建一个工作簿
*/
public
void
createWorkbook
()
{
this
.
wb
=
new
SXSSFWorkbook
(
500
);
this
.
sheet
=
wb
.
createSheet
();
wb
.
setSheetName
(
0
,
sheetName
);
this
.
styles
=
createStyles
(
wb
);
}
/**
* 创建工作表
*
* @param sheetNo sheet数量
* @param index 序号
*/
public
void
createSheet
(
int
sheetNo
,
int
index
)
{
// 设置工作表的名称.
if
(
sheetNo
>
1
&&
index
>
0
)
{
this
.
sheet
=
wb
.
createSheet
();
this
.
createTitle
();
wb
.
setSheetName
(
index
,
sheetName
+
index
);
}
}
/**
* 获取单元格值
*
* @param row 获取的行
* @param column 获取单元格列号
* @return 单元格值
*/
public
Object
getCellValue
(
Row
row
,
int
column
)
{
if
(
row
==
null
)
{
return
row
;
}
Object
val
=
""
;
try
{
Cell
cell
=
row
.
getCell
(
column
);
if
(
StringUtils
.
isNotNull
(
cell
))
{
if
(
cell
.
getCellType
()
==
CellType
.
NUMERIC
||
cell
.
getCellType
()
==
CellType
.
FORMULA
)
{
val
=
cell
.
getNumericCellValue
();
if
(
DateUtil
.
isCellDateFormatted
(
cell
))
{
val
=
DateUtil
.
getJavaDate
((
Double
)
val
);
// POI Excel 日期格式转换
}
else
{
if
((
Double
)
val
%
1
!=
0
)
{
val
=
new
BigDecimal
(
val
.
toString
());
}
else
{
val
=
new
DecimalFormat
(
"0"
).
format
(
val
);
}
}
}
else
if
(
cell
.
getCellType
()
==
CellType
.
STRING
)
{
val
=
cell
.
getStringCellValue
();
}
else
if
(
cell
.
getCellType
()
==
CellType
.
BOOLEAN
)
{
val
=
cell
.
getBooleanCellValue
();
}
else
if
(
cell
.
getCellType
()
==
CellType
.
ERROR
)
{
val
=
cell
.
getErrorCellValue
();
}
}
}
catch
(
Exception
e
)
{
return
val
;
}
return
val
;
}
/**
* 判断是否是空行
*
* @param row 判断的行
* @return
*/
private
boolean
isRowEmpty
(
Row
row
)
{
if
(
row
==
null
)
{
return
true
;
}
for
(
int
i
=
row
.
getFirstCellNum
();
i
<
row
.
getLastCellNum
();
i
++)
{
Cell
cell
=
row
.
getCell
(
i
);
if
(
cell
!=
null
&&
cell
.
getCellType
()
!=
CellType
.
BLANK
)
{
return
false
;
}
}
return
true
;
}
/**
* 格式化不同类型的日期对象
*
* @param dateFormat 日期格式
* @param val 被格式化的日期对象
* @return 格式化后的日期字符
*/
public
String
parseDateToStr
(
String
dateFormat
,
Object
val
)
{
if
(
val
==
null
)
{
return
""
;
}
String
str
;
if
(
val
instanceof
Date
)
{
str
=
DateUtils
.
parseDateToStr
(
dateFormat
,
(
Date
)
val
);
}
else
if
(
val
instanceof
LocalDateTime
)
{
str
=
DateUtils
.
parseDateToStr
(
dateFormat
,
DateUtils
.
toDate
((
LocalDateTime
)
val
));
}
else
if
(
val
instanceof
LocalDate
)
{
str
=
DateUtils
.
parseDateToStr
(
dateFormat
,
DateUtils
.
toDate
((
LocalDate
)
val
));
}
else
{
str
=
val
.
toString
();
}
return
str
;
}
}
mes/src/main/java/com/ximai/mes/constant/WorkorderStatusEnum.java
View file @
a102052d
...
...
@@ -9,58 +9,71 @@ public enum WorkorderStatusEnum {
/**
* 待发布
*/
PREPARE
(
"PREPARE"
),
PREPARE
(
"PREPARE"
,
"待发布"
),
/**
* 已发布
*/
PUBLISHED
(
"PUBLISHED"
),
PUBLISHED
(
"PUBLISHED"
,
"已发布"
),
/**
* 已组合
*/
COMBINED
(
"COMBINED"
),
COMBINED
(
"COMBINED"
,
"已组合"
),
/**
* 已编排
*/
ORCHESTRATED
(
"ORCHESTRATED"
),
ORCHESTRATED
(
"ORCHESTRATED"
,
"已编排"
),
/**
* 已排产
*/
SCHEDULED
(
"SCHEDULED"
),
SCHEDULED
(
"SCHEDULED"
,
"已排产"
),
/**
* 已完成
*/
FINISHED
(
"FINISHED"
),
FINISHED
(
"FINISHED"
,
"已完成"
),
/**
* 已取消
*/
CANCELED
(
"CANCELED"
),
CANCELED
(
"CANCELED"
,
"已取消"
),
/**
* 暂停
*/
STOPPAGE
(
"STOPPAGE"
),
STOPPAGE
(
"STOPPAGE"
,
"待发布"
),
/**
* 锁定
*/
LOCK
(
"LOCK"
),
LOCK
(
"LOCK"
,
"锁定"
),
/**
* 已下达
*/
ISSUED
(
"ISSUED"
),
ISSUED
(
"ISSUED"
,
"已下达"
),
/**
* 关闭/取消
*/
CLOSE
(
"CLOSE"
),
CANCEL
(
"CANCEL"
),
CLOSE
(
"CLOSE"
,
"关闭"
),
CANCEL
(
"CANCEL"
,
"取消"
),
/**
* 生产中
*/
PRODUCING
(
"PRODUCING"
);
PRODUCING
(
"PRODUCING"
,
"生产中"
);
/**
* Lock type
*/
private
final
String
status
;
/**
* 枚举名称
*/
public
String
enumName
;
WorkorderStatusEnum
(
String
status
,
String
enumName
)
{
this
.
status
=
status
;
this
.
enumName
=
enumName
;
}
public
String
getEnumName
()
{
return
enumName
;
}
/**
* Constructor with field of type
*/
...
...
mes/src/main/java/com/ximai/mes/pro/domain/vo/task/ProTaskWorkunitQuery.java
View file @
a102052d
...
...
@@ -93,4 +93,6 @@ public class ProTaskWorkunitQuery extends BaseEntity {
@ApiModelProperty
(
"是否委外,1:是,0:否"
)
private
Integer
outsourced
;
private
String
taskBatch
;
}
mes/src/main/java/com/ximai/mes/pro/service/impl/task/ProTaskWorkunitServiceImpl.java
View file @
a102052d
...
...
@@ -450,6 +450,7 @@ public class ProTaskWorkunitServiceImpl implements IProTaskWorkunitService {
query
.
eq
(
proTaskWorkunit
.
getOutsourced
()!=
null
,
"ptw.outsourced"
,
proTaskWorkunit
.
getOutsourced
());
query
.
eq
(
StringUtils
.
isNotEmpty
(
proTaskWorkunit
.
getCustomerProjectNo
()),
"wo.customer_project_no"
,
proTaskWorkunit
.
getCustomerProjectNo
());
query
.
eq
(
StringUtils
.
isNotEmpty
(
proTaskWorkunit
.
getOrderCode
()),
"wo.order_code"
,
proTaskWorkunit
.
getOrderCode
());
query
.
eq
(
StringUtils
.
isNotEmpty
(
proTaskWorkunit
.
getTaskBatch
()),
"SUBSTRING_INDEX(t.task_batch, '-', -1)"
,
proTaskWorkunit
.
getTaskBatch
());
query
.
gt
(
"ptw.quantity"
,
0
);
query
.
orderByAsc
(
"schedule_start_date"
);
List
<
ProTaskWorkunit
>
list
=
proTaskWorkunitService
.
selectTaskWorkUnitJoinTask
(
query
);
...
...
mes/src/main/java/com/ximai/mes/report/controller/FeedbackController.java
View file @
a102052d
...
...
@@ -5,6 +5,7 @@ import com.ximai.common.core.controller.BaseController;
import
com.ximai.common.core.domain.AjaxResult
;
import
com.ximai.common.core.page.TableDataInfo
;
import
com.ximai.common.enums.BusinessType
;
import
com.ximai.common.utils.poi.ExcelUtil
;
import
com.ximai.mes.report.request.FeedbackRequest
;
import
com.ximai.mes.report.response.FeedbackResponse
;
import
com.ximai.mes.report.service.FeedbackService
;
...
...
@@ -15,6 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
javax.servlet.http.HttpServletResponse
;
import
java.math.BigDecimal
;
import
java.math.RoundingMode
;
import
java.text.DecimalFormat
;
...
...
@@ -41,6 +43,17 @@ public class FeedbackController extends BaseController {
}
/**
* 明细界面导出
*/
@PreAuthorize
(
"@ss.hasPermi('pro:materialReturn:export')"
)
@Log
(
title
=
"生产报工记录:明细界面导出"
,
businessType
=
BusinessType
.
EXPORT
)
@PostMapping
(
"/getList/export"
)
public
void
export
(
HttpServletResponse
response
,
FeedbackRequest
feedbackRequest
)
{
List
<
FeedbackResponse
>
feedbackResponseList
=
feedbackService
.
getList
(
feedbackRequest
);
ExcelUtil
<
FeedbackResponse
>
util
=
new
ExcelUtil
<>(
FeedbackResponse
.
class
);
util
.
exportExcel
(
response
,
feedbackResponseList
,
"生产报工报表明细"
);
}
@ApiOperation
(
"生产报工记录:统计方式工单"
)
@PreAuthorize
(
"@ss.hasPermi('mes:pro:feedback:get')"
)
...
...
@@ -62,6 +75,33 @@ public class FeedbackController extends BaseController {
return
getDataTable
(
feedbackResponseList
);
}
/**
* 明细界面导出
*/
@PreAuthorize
(
"@ss.hasPermi('pro:materialReturn:export')"
)
@Log
(
title
=
"生产报工记录:统计方式工单界面导出"
,
businessType
=
BusinessType
.
EXPORT
)
@PostMapping
(
"/getListByWorkOrder/export"
)
public
void
getListByWorkOrderExport
(
HttpServletResponse
response
,
FeedbackRequest
feedbackRequest
)
{
List
<
FeedbackResponse
>
feedbackResponseList
=
feedbackService
.
getListByWorkOrder
(
feedbackRequest
);
DecimalFormat
df
=
new
DecimalFormat
(
"0.00%"
);
for
(
FeedbackResponse
feedbackResponse
:
feedbackResponseList
){
if
(
feedbackResponse
.
getQuantityFeedback
()
!=
null
&&
feedbackResponse
.
getQuantityFeedback
().
compareTo
(
BigDecimal
.
ZERO
)
!=
0
&&
feedbackResponse
.
getQuantityUnqualify
()!=
null
){
feedbackResponse
.
setQualificationRate
(
df
.
format
((
feedbackResponse
.
getQuantityQualify
().
divide
(
feedbackResponse
.
getQuantityQualify
().
add
(
feedbackResponse
.
getQuantityUnqualify
()),
2
,
RoundingMode
.
HALF_UP
).
doubleValue
())));
}
else
{
feedbackResponse
.
setQualificationRate
(
"0.00%"
);
}
}
ExcelUtil
<
FeedbackResponse
>
util
=
new
ExcelUtil
<>(
FeedbackResponse
.
class
);
util
.
exportExcel
(
response
,
feedbackResponseList
,
"生产报工报表-统计方式工单"
);
}
@ApiOperation
(
"生产报工记录:统计方式车间"
)
@PreAuthorize
(
"@ss.hasPermi('mes:pro:feedback:get')"
)
@Log
(
title
=
"生产报工记录:统计方式车间"
,
businessType
=
BusinessType
.
QUERY
)
...
...
@@ -82,6 +122,29 @@ public class FeedbackController extends BaseController {
return
getDataTable
(
feedbackResponseList
);
}
/**
* 统计方式车间界面导出
*/
@PreAuthorize
(
"@ss.hasPermi('pro:materialReturn:export')"
)
@Log
(
title
=
"生产报工记录:统计方式车间界面导出"
,
businessType
=
BusinessType
.
EXPORT
)
@PostMapping
(
"/getListByWorkshop/export"
)
public
void
getListByWorkshopExport
(
HttpServletResponse
response
,
FeedbackRequest
feedbackRequest
)
{
List
<
FeedbackResponse
>
feedbackResponseList
=
feedbackService
.
getListByWorkshop
(
feedbackRequest
);
DecimalFormat
df
=
new
DecimalFormat
(
"0.00%"
);
for
(
FeedbackResponse
feedbackResponse
:
feedbackResponseList
){
if
(
feedbackResponse
.
getQuantityFeedback
()
!=
null
&&
feedbackResponse
.
getQuantityFeedback
().
compareTo
(
BigDecimal
.
ZERO
)
!=
0
&&
feedbackResponse
.
getQuantityUnqualify
()!=
null
){
feedbackResponse
.
setQualificationRate
(
df
.
format
((
feedbackResponse
.
getQuantityQualify
().
divide
(
feedbackResponse
.
getQuantityQualify
().
add
(
feedbackResponse
.
getQuantityUnqualify
()),
2
,
RoundingMode
.
HALF_UP
).
doubleValue
())));
}
else
{
feedbackResponse
.
setQualificationRate
(
"0.00%"
);
}
}
ExcelUtil
<
FeedbackResponse
>
util
=
new
ExcelUtil
<>(
FeedbackResponse
.
class
);
util
.
exportExcel
(
response
,
feedbackResponseList
,
"生产报工报表-统计方式车间"
);
}
@ApiOperation
(
"生产报工记录:统计方式工作中心"
)
@PreAuthorize
(
"@ss.hasPermi('mes:pro:feedback:get')"
)
@Log
(
title
=
"生产报工记录:统计方式工作中心"
,
businessType
=
BusinessType
.
QUERY
)
...
...
@@ -103,6 +166,28 @@ public class FeedbackController extends BaseController {
}
/**
* 统计方式车间界面导出
*/
@PreAuthorize
(
"@ss.hasPermi('pro:materialReturn:export')"
)
@Log
(
title
=
"生产报工记录:统计方式工作中心导出"
,
businessType
=
BusinessType
.
EXPORT
)
@PostMapping
(
"/getListByWorkstation/export"
)
public
void
getListByWorkstationExport
(
HttpServletResponse
response
,
FeedbackRequest
feedbackRequest
)
{
List
<
FeedbackResponse
>
feedbackResponseList
=
feedbackService
.
getListByWorkstation
(
feedbackRequest
);
DecimalFormat
df
=
new
DecimalFormat
(
"0.00%"
);
for
(
FeedbackResponse
feedbackResponse
:
feedbackResponseList
){
if
(
feedbackResponse
.
getQuantityFeedback
()
!=
null
&&
feedbackResponse
.
getQuantityFeedback
().
compareTo
(
BigDecimal
.
ZERO
)
!=
0
&&
feedbackResponse
.
getQuantityUnqualify
()!=
null
){
feedbackResponse
.
setQualificationRate
(
df
.
format
((
feedbackResponse
.
getQuantityQualify
().
divide
(
feedbackResponse
.
getQuantityQualify
().
add
(
feedbackResponse
.
getQuantityUnqualify
()),
2
,
RoundingMode
.
HALF_UP
).
doubleValue
())));
}
else
{
feedbackResponse
.
setQualificationRate
(
"0.00%"
);
}
}
ExcelUtil
<
FeedbackResponse
>
util
=
new
ExcelUtil
<>(
FeedbackResponse
.
class
);
util
.
exportExcel
(
response
,
feedbackResponseList
,
"生产报工报表-统计方式工作中心"
);
}
@ApiOperation
(
"生产报工记录:统计方式工作单元"
)
@PreAuthorize
(
"@ss.hasPermi('mes:pro:feedback:get')"
)
@Log
(
title
=
"生产报工记录:统计方式工作单元"
,
businessType
=
BusinessType
.
QUERY
)
...
...
@@ -124,6 +209,27 @@ public class FeedbackController extends BaseController {
}
/**
* 统计方式车间界面导出
*/
@PreAuthorize
(
"@ss.hasPermi('pro:materialReturn:export')"
)
@Log
(
title
=
"生产报工记录:统计统计方式工作单元导出"
,
businessType
=
BusinessType
.
EXPORT
)
@PostMapping
(
"/getListByWorkunit/export"
)
public
void
getListByWorkunitExport
(
HttpServletResponse
response
,
FeedbackRequest
feedbackRequest
)
{
List
<
FeedbackResponse
>
feedbackResponseList
=
feedbackService
.
getListByWorkunit
(
feedbackRequest
);
DecimalFormat
df
=
new
DecimalFormat
(
"0.00%"
);
for
(
FeedbackResponse
feedbackResponse
:
feedbackResponseList
){
if
(
feedbackResponse
.
getQuantityFeedback
()
!=
null
&&
feedbackResponse
.
getQuantityFeedback
().
compareTo
(
BigDecimal
.
ZERO
)
!=
0
&&
feedbackResponse
.
getQuantityUnqualify
()!=
null
){
feedbackResponse
.
setQualificationRate
(
df
.
format
((
feedbackResponse
.
getQuantityQualify
().
divide
(
feedbackResponse
.
getQuantityQualify
().
add
(
feedbackResponse
.
getQuantityUnqualify
()),
2
,
RoundingMode
.
HALF_UP
).
doubleValue
())));
}
else
{
feedbackResponse
.
setQualificationRate
(
"0.00%"
);
}
}
ExcelUtil
<
FeedbackResponse
>
util
=
new
ExcelUtil
<>(
FeedbackResponse
.
class
);
util
.
exportExcel
(
response
,
feedbackResponseList
,
"生产报工报表-统计方式工作单元"
);
}
...
...
@@ -147,6 +253,27 @@ public class FeedbackController extends BaseController {
return
getDataTable
(
feedbackResponseList
);
}
/**
* 统计方式车间界面导出
*/
@PreAuthorize
(
"@ss.hasPermi('pro:materialReturn:export')"
)
@Log
(
title
=
"生产报工记录:统计方式工序导出"
,
businessType
=
BusinessType
.
EXPORT
)
@PostMapping
(
"/getListByProcess/export"
)
public
void
getListByProcessExport
(
HttpServletResponse
response
,
FeedbackRequest
feedbackRequest
)
{
List
<
FeedbackResponse
>
feedbackResponseList
=
feedbackService
.
getListByProcess
(
feedbackRequest
);
DecimalFormat
df
=
new
DecimalFormat
(
"0.00%"
);
for
(
FeedbackResponse
feedbackResponse
:
feedbackResponseList
){
if
(
feedbackResponse
.
getQuantityFeedback
()
!=
null
&&
feedbackResponse
.
getQuantityFeedback
().
compareTo
(
BigDecimal
.
ZERO
)
!=
0
&&
feedbackResponse
.
getQuantityUnqualify
()!=
null
){
feedbackResponse
.
setQualificationRate
(
df
.
format
((
feedbackResponse
.
getQuantityQualify
().
divide
(
feedbackResponse
.
getQuantityQualify
().
add
(
feedbackResponse
.
getQuantityUnqualify
()),
2
,
RoundingMode
.
HALF_UP
).
doubleValue
())));
}
else
{
feedbackResponse
.
setQualificationRate
(
"0.00%"
);
}
}
ExcelUtil
<
FeedbackResponse
>
util
=
new
ExcelUtil
<>(
FeedbackResponse
.
class
);
util
.
exportExcel
(
response
,
feedbackResponseList
,
"生产报工报表-统计方式工序"
);
}
@ApiOperation
(
"生产报工记录:统计方式用户"
)
@PreAuthorize
(
"@ss.hasPermi('mes:pro:feedback:get')"
)
...
...
@@ -168,6 +295,31 @@ public class FeedbackController extends BaseController {
return
getDataTable
(
feedbackResponseList
);
}
/**
* 统计方式车间界面导出
*/
@PreAuthorize
(
"@ss.hasPermi('pro:materialReturn:export')"
)
@Log
(
title
=
"生产报工记录:统计方式用户导出"
,
businessType
=
BusinessType
.
EXPORT
)
@PostMapping
(
"/getListByUser/export"
)
public
void
getListByUserExport
(
HttpServletResponse
response
,
FeedbackRequest
feedbackRequest
)
{
List
<
FeedbackResponse
>
feedbackResponseList
=
feedbackService
.
getListByUser
(
feedbackRequest
);
DecimalFormat
df
=
new
DecimalFormat
(
"0.00%"
);
for
(
FeedbackResponse
feedbackResponse
:
feedbackResponseList
){
if
(
feedbackResponse
.
getQuantityFeedback
()
!=
null
&&
feedbackResponse
.
getQuantityFeedback
().
compareTo
(
BigDecimal
.
ZERO
)
!=
0
&&
feedbackResponse
.
getQuantityUnqualify
()!=
null
){
feedbackResponse
.
setQualificationRate
(
df
.
format
((
feedbackResponse
.
getQuantityQualify
().
divide
(
feedbackResponse
.
getQuantityQualify
().
add
(
feedbackResponse
.
getQuantityUnqualify
()),
2
,
RoundingMode
.
HALF_UP
).
doubleValue
())));
}
else
{
feedbackResponse
.
setQualificationRate
(
"0.00%"
);
}
}
ExcelUtil
<
FeedbackResponse
>
util
=
new
ExcelUtil
<>(
FeedbackResponse
.
class
);
util
.
exportExcel
(
response
,
feedbackResponseList
,
"生产报工报表-统计方式用户"
);
}
@ApiOperation
(
"生产报工记录:统计方式不合格原因"
)
@PreAuthorize
(
"@ss.hasPermi('mes:pro:feedback:get')"
)
@Log
(
title
=
"生产报工记录:统计方式不合格原因"
,
businessType
=
BusinessType
.
QUERY
)
...
...
@@ -187,4 +339,29 @@ public class FeedbackController extends BaseController {
}
return
getDataTable
(
feedbackResponseList
);
}
/**
* 统计方式车间界面导出
*/
@PreAuthorize
(
"@ss.hasPermi('pro:materialReturn:export')"
)
@Log
(
title
=
"生产报工记录:统计方式不合格原因导出"
,
businessType
=
BusinessType
.
EXPORT
)
@PostMapping
(
"/getListByDefect/export"
)
public
void
getListByDefectExport
(
HttpServletResponse
response
,
FeedbackRequest
feedbackRequest
)
{
List
<
FeedbackResponse
>
feedbackResponseList
=
feedbackService
.
getListByDefect
(
feedbackRequest
);
DecimalFormat
df
=
new
DecimalFormat
(
"0.00%"
);
for
(
FeedbackResponse
feedbackResponse
:
feedbackResponseList
){
if
(
feedbackResponse
.
getQuantityFeedback
()
!=
null
&&
feedbackResponse
.
getQuantityFeedback
().
compareTo
(
BigDecimal
.
ZERO
)
!=
0
&&
feedbackResponse
.
getQuantityUnqualify
()!=
null
){
feedbackResponse
.
setQualificationRate
(
df
.
format
((
feedbackResponse
.
getQuantityQualify
().
divide
(
feedbackResponse
.
getQuantityQualify
().
add
(
feedbackResponse
.
getQuantityUnqualify
()),
2
,
RoundingMode
.
HALF_UP
).
doubleValue
())));
}
else
{
feedbackResponse
.
setQualificationRate
(
"0.00%"
);
}
}
ExcelUtil
<
FeedbackResponse
>
util
=
new
ExcelUtil
<>(
FeedbackResponse
.
class
);
util
.
exportExcel
(
response
,
feedbackResponseList
,
"生产报工报表-统计方式不合格原因"
);
}
}
mes/src/main/java/com/ximai/mes/report/controller/WorkOrderProgressController.java
View file @
a102052d
...
...
@@ -4,6 +4,8 @@ import com.ximai.common.annotation.Log;
import
com.ximai.common.core.controller.BaseController
;
import
com.ximai.common.core.page.TableDataInfo
;
import
com.ximai.common.enums.BusinessType
;
import
com.ximai.common.utils.poi.ExcelUtil
;
import
com.ximai.mes.constant.WorkorderStatusEnum
;
import
com.ximai.mes.report.request.FeedbackRequest
;
import
com.ximai.mes.report.request.WorkOrderProgressRequest
;
import
com.ximai.mes.report.response.FeedbackResponse
;
...
...
@@ -17,6 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.*
;
import
javax.servlet.http.HttpServletResponse
;
import
java.util.List
;
@Api
(
"生产进度"
)
...
...
@@ -37,6 +40,16 @@ public class WorkOrderProgressController extends BaseController {
return
getDataTable
(
workOrderProgressListResponses
);
}
@PreAuthorize
(
"@ss.hasPermi('pro:materialReturn:export')"
)
@Log
(
title
=
"生产进度:明细界面导出"
,
businessType
=
BusinessType
.
EXPORT
)
@PostMapping
(
"/getList/export"
)
public
void
export
(
HttpServletResponse
response
,
WorkOrderProgressRequest
workOrderProgressRequest
)
{
List
<
WorkOrderProgressListResponse
>
workOrderProgressListResponses
=
workOrderProgressService
.
getList
(
workOrderProgressRequest
);
workOrderProgressListResponses
.
stream
().
forEach
(
workOrderProgressListResponse
->
workOrderProgressListResponse
.
setStatus
(
WorkorderStatusEnum
.
get
(
workOrderProgressListResponse
.
getStatus
()).
getEnumName
()));
ExcelUtil
<
WorkOrderProgressListResponse
>
util
=
new
ExcelUtil
<>(
WorkOrderProgressListResponse
.
class
);
util
.
exportExcel
(
response
,
workOrderProgressListResponses
,
"生产进度-明细界面导出"
);
}
@ApiOperation
(
"生产进度:工序明细"
)
@PreAuthorize
(
"@ss.hasPermi('mes:pro:feedback:get')"
)
@Log
(
title
=
"生产进度:工序明细"
,
businessType
=
BusinessType
.
QUERY
)
...
...
mes/src/main/java/com/ximai/mes/report/request/WorkOrderProgressRequest.java
View file @
a102052d
...
...
@@ -4,6 +4,8 @@ import com.ximai.common.annotation.Excel;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
import
java.util.List
;
@Data
public
class
WorkOrderProgressRequest
{
/**
...
...
@@ -42,7 +44,7 @@ public class WorkOrderProgressRequest {
private
String
productName
;
@ApiModelProperty
(
"工单状态"
)
private
String
workOrderStatus
;
private
List
<
String
>
workOrderStatus
;
@ApiModelProperty
(
"产线"
)
private
String
lineName
;
...
...
mes/src/main/java/com/ximai/mes/report/response/FeedbackResponse.java
View file @
a102052d
...
...
@@ -28,35 +28,43 @@ public class FeedbackResponse extends ProFeedback {
* 工单类型
*/
@ApiModelProperty
(
"工单类型"
)
@Excel
(
name
=
"工单类型"
)
private
String
workorderType
;
@ApiModelProperty
(
"客户项目号"
)
@Excel
(
name
=
"客户项目号"
)
private
String
customerProjectNo
;
@ApiModelProperty
(
"订单单号"
)
@Excel
(
name
=
"订单单号"
)
private
String
orderCode
;
@ApiModelProperty
(
"工单编码"
)
@Excel
(
name
=
"生产工单"
)
private
String
workorderCode
;
@ApiModelProperty
(
"工单名称"
)
//@Excel(name = "工单名称")
private
String
workorderName
;
/**
* 产品编号
*/
@ApiModelProperty
(
"产品编号"
)
@Excel
(
name
=
"产品编号"
)
private
String
productCode
;
/**
* 产品名称
*/
@ApiModelProperty
(
"产品名称"
)
@Excel
(
name
=
"产品名称"
)
private
String
productName
;
/**
* 任务编号
*/
@ApiModelProperty
(
"工序任务号"
)
@Excel
(
name
=
"工序任务号"
)
private
String
taskCode
;
...
...
@@ -65,11 +73,13 @@ public class FeedbackResponse extends ProFeedback {
* 工序名称
*/
@ApiModelProperty
(
"工序编码"
)
@Excel
(
name
=
"工序编码"
)
private
String
processCode
;
/**
* 工序名称
*/
@ApiModelProperty
(
"工序名称"
)
@Excel
(
name
=
"工序名称"
)
private
String
processName
;
...
...
@@ -77,12 +87,14 @@ public class FeedbackResponse extends ProFeedback {
* 工作中心编号
*/
@ApiModelProperty
(
"工作中心编号"
)
@Excel
(
name
=
"工作中心编号"
)
private
String
workstationCode
;
/**
* 工作中心名称
*/
@ApiModelProperty
(
"工作中心名称"
)
@Excel
(
name
=
"工作中心名称"
)
private
String
workstationName
;
...
...
@@ -90,27 +102,33 @@ public class FeedbackResponse extends ProFeedback {
*
*/
@ApiModelProperty
(
"工作单元ID"
)
@Excel
(
name
=
"工作单元ID"
)
private
Long
workunitId
;
/**
*
*/
@ApiModelProperty
(
"工作单元编码"
)
@Excel
(
name
=
"工作单元编码"
)
private
String
workunitCode
;
@ApiModelProperty
(
"工作单元名称"
)
@Excel
(
name
=
"工作单元名称"
)
private
String
workunitName
;
@ApiModelProperty
(
"报工人员"
)
@Excel
(
name
=
"报工人员"
)
private
String
userName
;
@ApiModelProperty
(
"报工人员名称"
)
@Excel
(
name
=
"报工人员名称"
)
private
String
nickName
;
/**
* 排产数量
*/
@ApiModelProperty
(
"派工数量"
)
@Excel
(
name
=
"派工数量"
)
private
BigDecimal
quantity
;
...
...
@@ -118,37 +136,45 @@ public class FeedbackResponse extends ProFeedback {
* 本次报工数量
*/
@ApiModelProperty
(
"本次报工数量"
)
@Excel
(
name
=
"本次报工数量"
)
private
BigDecimal
quantityFeedback
;
/**
* 合格品数量
*/
@ApiModelProperty
(
"合格品数量"
)
@Excel
(
name
=
"合格品数量"
)
private
BigDecimal
quantityQualify
;
/**
* 不良品数量
*/
@ApiModelProperty
(
"不良品数量"
)
@Excel
(
name
=
"不良品数量"
)
private
BigDecimal
quantityUnqualify
;
/** 异常原因 */
@ApiModelProperty
(
"异常原因"
)
@Excel
(
name
=
"异常原因"
)
private
String
abnormalReason
;
@ApiModelProperty
(
"异常备注"
)
@Excel
(
name
=
"异常备注"
)
private
String
abnormalRemark
;
@ApiModelProperty
(
"标准工时"
)
@Excel
(
name
=
"标准工时"
)
private
BigDecimal
stdWorkingTime
;
@ApiModelProperty
(
"实际工时"
)
@Excel
(
name
=
"实际工时"
)
private
String
machineTime
;
/**
* 预计结束时间
*/
@ApiModelProperty
(
"计划结束时间"
)
@Excel
(
name
=
"计划结束时间"
,
dateFormat
=
"yyyy-MM-dd HH:mm:ss"
)
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
private
Date
scheduleEndDate
;
/**
...
...
@@ -156,18 +182,17 @@ public class FeedbackResponse extends ProFeedback {
*/
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
@ApiModelProperty
(
"报工时间"
)
@Excel
(
name
=
"报工时间"
,
dateFormat
=
"yyyy-MM-dd HH:mm:ss"
)
private
Date
feedbackTime
;
@ApiModelProperty
(
"良率"
)
@Excel
(
name
=
"良率"
)
private
String
qualificationRate
;
@ApiModelProperty
(
"车间编号"
)
@Excel
(
name
=
"车间编号"
)
private
String
workshopCode
;
@ApiModelProperty
(
"车间名称"
)
@Excel
(
name
=
"车间名称"
)
private
String
workshopName
;
}
mes/src/main/java/com/ximai/mes/report/response/WorkOrderProgressFeedbackListResponse.java
View file @
a102052d
...
...
@@ -25,4 +25,5 @@ public class WorkOrderProgressFeedbackListResponse {
@ApiModelProperty
(
"报工时间"
)
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
private
Date
feedbackTime
;
private
String
taskBatch
;
}
mes/src/main/java/com/ximai/mes/report/response/WorkOrderProgressListResponse.java
View file @
a102052d
package
com
.
ximai
.
mes
.
report
.
response
;
import
com.alibaba.excel.annotation.format.NumberFormat
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
com.ximai.common.annotation.Excel
;
import
io.swagger.annotations.ApiModelProperty
;
...
...
@@ -15,46 +16,65 @@ public class WorkOrderProgressListResponse {
* 项目号,订单号,生产工单,工单类型,产品编码,产品名称,计划数量,完工数量,在制进度(百分比),需求实际
*/
@ApiModelProperty
(
"客户项目号"
)
@Excel
(
name
=
"客户项目号"
)
private
String
customerProjectNo
;
@ApiModelProperty
(
"订单单号"
)
@Excel
(
name
=
"订单单号"
)
private
String
orderCode
;
@ApiModelProperty
(
"工单编码"
)
@Excel
(
name
=
"生产工单"
)
private
String
workorderCode
;
@ApiModelProperty
(
"产线"
)
@Excel
(
name
=
"产品名称"
)
private
String
lineName
;
@ApiModelProperty
(
"工单状态"
)
private
String
status
;
/**
* 工单类型
*/
@ApiModelProperty
(
"工单类型"
)
@Excel
(
name
=
"工单类型"
)
private
String
workorderType
;
/**
* 产品编号
*/
@ApiModelProperty
(
"产品编号"
)
@Excel
(
name
=
"产品编号"
)
private
String
productCode
;
/**
* 产品名称
*/
@ApiModelProperty
(
"产品名称"
)
@Excel
(
name
=
"产品名称"
)
private
String
productName
;
@ApiModelProperty
(
"计划数量"
)
@Excel
(
name
=
"计划数量"
)
@NumberFormat
(
value
=
"0.00"
)
private
BigDecimal
quantity
;
/**
* 已生产数量
*/
@ApiModelProperty
(
"已生产数量"
)
@Excel
(
name
=
"完工数量"
)
@NumberFormat
(
value
=
"0.00"
)
private
BigDecimal
quantityProduced
;
/**
* 已生产数量
*/
@ApiModelProperty
(
"在制进度"
)
@Excel
(
name
=
"在制进度%"
)
@NumberFormat
(
value
=
"0.00"
)
private
BigDecimal
quantityMu
;
@ApiModelProperty
(
"需求时间"
)
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
)
@Excel
(
name
=
"需求时间"
,
dateFormat
=
"yyyy-MM-dd HH:mm:ss"
)
private
Date
requestDate
;
}
mes/src/main/resources/mapper/pro/ProFeedbackMapper.xml
View file @
a102052d
...
...
@@ -517,12 +517,32 @@
</select>
<select
id=
"getFeedbackList"
resultType=
"com.ximai.mes.report.response.WorkOrderProgressFeedbackListResponse"
>
select feedback.*,workunit.std_working_time from pro_task_workunit workunit join pro_feedback feedback on feedback.task_workunit_id = workunit.task_workunit_id
SELECT
feedback.user_name,
sum(feedback.quantity) quantity,
sum(feedback.quantity_feedback) quantity_feedback,
sum(feedback.quantity_qualify) quantity_qualify,
sum(feedback.quantity_unqualify) quantity_unqualify,
sum(feedback.quantity_uncheck) quantity_uncheck,
feedback.nick_name,
workunit.std_working_time ,
pro_task.task_batch
FROM
pro_task_workunit workunit
JOIN pro_feedback feedback ON feedback.task_workunit_id = workunit.task_workunit_id
join pro_task on pro_task.task_id = workunit.task_id
<where>
workorder_code = #{workorderCode}
<if
test=
"taskId != null"
>
and feedback.task_id = #{taskId}
</if>
<if
test=
"taskWorkunitId != null"
>
and feedback.task_workunit_id = #{taskWorkunitId}
</if>
</where>
group by
feedback.user_name,
feedback.nick_name,
workunit.std_working_time ,
pro_task.task_batch
order by
pro_task.idx
</select>
<select
id=
"getListByDefect"
resultType=
"com.ximai.mes.report.response.FeedbackResponse"
>
select
...
...
mes/src/main/resources/mapper/pro/proWorkOrder/ProWorkorderMapper.xml
View file @
a102052d
...
...
@@ -262,6 +262,7 @@
pw.in_drawing_no,
pw.erp_create_time,
pw.erp_update_time ,
item.line_name,
sum(case task.is_last_process when 0 THEN 0 ELSE fe.quantity_qualify + fe.quantity_unqualify END) as quantity_produced
FROM
pro_workorder pw
...
...
@@ -274,7 +275,13 @@
<if
test=
"productCode != null and productCode != ''"
>
and pw.product_code = #{productCode}
</if>
<if
test=
"orderCode != null and orderCode !=''"
>
and pw.order_code = #{orderCode}
</if>
<if
test=
"customerProjectNo != null and customerProjectNo !=''"
>
and pw.customer_project_no = #{customerProjectNo}
</if>
<if
test=
"workOrderStatus != null and workOrderStatus !=''"
>
and pw.status = #{workOrderStatus}
</if>
<if
test=
"workOrderStatus != null"
>
and
<foreach
collection=
"workOrderStatus"
item=
"status"
separator=
" or "
open=
"("
close=
")"
>
pw.status = #{status}
</foreach>
</if>
<if
test=
"lineName != null and lineName !=''"
>
and item.line_name = #{lineName}
</if>
</where>
GROUP BY
...
...
@@ -352,7 +359,8 @@
pw.customer_project_no,
pw.in_drawing_no,
pw.erp_create_time,
pw.erp_update_time
pw.erp_update_time,
item.line_name
</select>
<insert
id=
"insertProWorkorder"
parameterType=
"ProWorkorder"
useGeneratedKeys=
"true"
keyProperty=
"workorderId"
>
...
...
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