Skip to content
切换导航条
切换导航条
当前项目
正在载入...
登录
张雷
/
skboot-zhongye
转到一个项目
切换导航栏
切换导航栏固定状态
项目
群组
代码片段
帮助
项目
活动
版本库
流水线
图表
问题
0
合并请求
0
维基
网络
创建新的问题
构建
提交
问题看板
文件
提交
网络
比较
分支
标签
1ca30618
由
康伟
编写于
2024-10-17 18:34:36 +0800
浏览文件
选项
浏览文件
标签
下载
电子邮件补丁
差异文件
kangwei : 联调:能环保态势大屏-后端
1 个父辈
691b55e8
隐藏空白字符变更
内嵌
并排
正在显示
9 个修改的文件
包含
470 行增加
和
75 行删除
sk-base-common/src/main/java/com/skua/tool/util/DigitalUtils.java
sk-base-common/src/main/java/com/skua/tool/util/JSUtils.java
sk-module-biz/src/main/java/com/skua/SkApplication.java
sk-module-biz/src/main/java/com/skua/modules/emergency/controller/EmergencyRiskEventController.java
sk-module-biz/src/main/java/com/skua/modules/emergency/entity/EmergencyRiskEvent.java
sk-module-datafill/src/main/java/com/skua/modules/custom/service/impl/FCustomReportDatasetServiceImpl.java
sk-module-datafill/src/main/java/com/skua/modules/report/vo/JnhbLargeScreenVO.java
sk-module-datafill/src/main/java/com/skua/modules/report/vo/largeScreen/ResultChartsVO.java
sk-module-datafill/src/main/java/com/skua/modules/report/vo/largeScreen/ResultNumberVO.java
sk-base-common/src/main/java/com/skua/tool/util/DigitalUtils.java
查看文件 @
1ca3061
...
...
@@ -108,7 +108,9 @@ public class DigitalUtils {
*/
public
static
String
division
(
String
dividend
,
String
divisor
){
String
resultStr
=
null
;
try
{
String
expression
=
dividend
+
"/ "
+
divisor
;
resultStr
=
JSUtils
.
executeExpression
(
expression
,
"0.00"
);
/* try{
if( isNumber(dividend) && isNumber( divisor) && Double.parseDouble(divisor) != 0 ){
BigDecimal dividend_BD = new BigDecimal(dividend);
BigDecimal divisor_BD = new BigDecimal(divisor);
...
...
@@ -116,8 +118,9 @@ public class DigitalUtils {
resultStr = result.toString();
}
}catch(Exception e){
System.out.println("dividend = "+ dividend +"; divisor = "+ divisor);
e.printStackTrace();
}
}
*/
//System.out.print("请输入被除数:");double dividend =scanner.nextDouble();
// System.out.print("请输入除数:");double divisor =scanner.nextDouble();
...
...
sk-base-common/src/main/java/com/skua/tool/util/JSUtils.java
0 → 100644
查看文件 @
1ca3061
package
com
.
skua
.
tool
.
util
;
import
javax.script.ScriptEngine
;
import
javax.script.ScriptEngineManager
;
import
javax.script.ScriptException
;
import
java.math.BigDecimal
;
import
java.text.DecimalFormat
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Scanner
;
import
java.util.Stack
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
/**
* 加减乘除表达式求值算法
* @version 1.0
*/
public
class
JSUtils
{
// 表达式字符合法性校验正则模式,静态常量化可以降低每次使用都要编译地消耗
private
static
final
Pattern
EXPRESSION_PATTERN
=
Pattern
.
compile
(
"[0-9\\.+-/*()= ]+"
);
// 运算符优先级map
private
static
final
Map
<
String
,
Integer
>
OPT_PRIORITY_MAP
=
new
HashMap
<
String
,
Integer
>()
{
private
static
final
long
serialVersionUID
=
6968472606692771458L
;
{
put
(
"("
,
0
);
put
(
"+"
,
2
);
put
(
"-"
,
2
);
put
(
"*"
,
3
);
put
(
"/"
,
3
);
put
(
")"
,
7
);
put
(
"="
,
20
);
}
};
/**
* 输入加减乘除表达式字符串,返回计算结果
*
* @param expression 表达式字符串
* @return 返回计算结果
*/
public
static
String
executeExpression
(
String
expression
,
String
decimalFormat
)
{
String
result
=
"0"
;
if
(
decimalFormat
==
null
)
decimalFormat
=
"0.00"
;
try
{
Double
aDouble
=
executeExpression
(
expression
);
DecimalFormat
df
=
new
DecimalFormat
(
decimalFormat
);
result
=
df
.
format
(
aDouble
);
}
catch
(
Exception
e
){
// e.printStackTrace();
}
return
result
;
}
public
static
double
executeExpression
(
String
expression
)
{
// 非空校验
if
(
null
==
expression
||
""
.
equals
(
expression
.
trim
()))
{
throw
new
IllegalArgumentException
(
"表达式不能为空!"
);
}
// 表达式字符合法性校验
Matcher
matcher
=
EXPRESSION_PATTERN
.
matcher
(
expression
);
if
(!
matcher
.
matches
())
{
throw
new
IllegalArgumentException
(
"表达式含有非法字符!"
);
}
Stack
<
String
>
optStack
=
new
Stack
<>();
// 运算符栈
Stack
<
BigDecimal
>
numStack
=
new
Stack
<>();
// 数值栈,数值以BigDecimal存储计算,避免精度计算问题
StringBuilder
curNumBuilder
=
new
StringBuilder
(
16
);
// 当前正在读取中的数值字符追加器
// 逐个读取字符,并根据运算符判断参与何种计算
for
(
int
i
=
0
;
i
<
expression
.
length
();
i
++)
{
char
c
=
expression
.
charAt
(
i
);
if
(
c
!=
' '
)
{
// 空白字符直接丢弃掉
if
((
c
>=
'0'
&&
c
<=
'9'
)
||
c
==
'.'
)
{
curNumBuilder
.
append
(
c
);
// 持续读取一个数值的各个字符
}
else
{
if
(
curNumBuilder
.
length
()
>
0
)
{
// 如果追加器有值,说明之前读取的字符是数值,而且此时已经完整读取完一个数值
numStack
.
push
(
new
BigDecimal
(
curNumBuilder
.
toString
()));
curNumBuilder
.
delete
(
0
,
curNumBuilder
.
length
());
}
String
curOpt
=
String
.
valueOf
(
c
);
if
(
optStack
.
empty
())
{
// 运算符栈栈顶为空则直接入栈
optStack
.
push
(
curOpt
);
}
else
{
if
(
curOpt
.
equals
(
"("
))
{
// 当前运算符为左括号,直接入运算符栈
optStack
.
push
(
curOpt
);
}
else
if
(
curOpt
.
equals
(
")"
))
{
// 当前运算符为右括号,触发括号内的字表达式进行计算
directCalc
(
optStack
,
numStack
,
true
);
}
else
if
(
curOpt
.
equals
(
"="
))
{
// 当前运算符为等号,触发整个表达式剩余计算,并返回总的计算结果
directCalc
(
optStack
,
numStack
,
false
);
return
numStack
.
pop
().
doubleValue
();
}
else
{
// 当前运算符为加减乘除之一,要与栈顶运算符比较,判断是否要进行一次二元计算
compareAndCalc
(
optStack
,
numStack
,
curOpt
);
}
}
}
}
}
// 表达式不是以等号结尾的场景
if
(
curNumBuilder
.
length
()
>
0
)
{
// 如果追加器有值,说明之前读取的字符是数值,而且此时已经完整读取完一个数值
numStack
.
push
(
new
BigDecimal
(
curNumBuilder
.
toString
()));
}
directCalc
(
optStack
,
numStack
,
false
);
return
numStack
.
pop
().
doubleValue
();
}
/**
* 拿当前运算符和栈顶运算符对比,如果栈顶运算符优先级高于或同级于当前运算符,
* 则执行一次二元运算(递归比较并计算),否则当前运算符入栈
*
* @param optStack 运算符栈
* @param numStack 数值栈
* @param curOpt 当前运算符
*/
public
static
void
compareAndCalc
(
Stack
<
String
>
optStack
,
Stack
<
BigDecimal
>
numStack
,
String
curOpt
)
{
// 比较当前运算符和栈顶运算符的优先级
String
peekOpt
=
optStack
.
peek
();
int
priority
=
getPriority
(
peekOpt
,
curOpt
);
if
(
priority
==
-
1
||
priority
==
0
)
{
// 栈顶运算符优先级大或同级,触发一次二元运算
String
opt
=
optStack
.
pop
();
// 当前参与计算运算符
BigDecimal
num2
=
numStack
.
pop
();
// 当前参与计算数值2
BigDecimal
num1
=
numStack
.
pop
();
// 当前参与计算数值1
BigDecimal
bigDecimal
=
floatingPointCalc
(
opt
,
num1
,
num2
);
// 计算结果当做操作数入栈
numStack
.
push
(
bigDecimal
);
// 运算完栈顶还有运算符,则还需要再次触发一次比较判断是否需要再次二元计算
if
(
optStack
.
empty
())
{
optStack
.
push
(
curOpt
);
}
else
{
compareAndCalc
(
optStack
,
numStack
,
curOpt
);
}
}
else
{
// 当前运算符优先级高,则直接入栈
optStack
.
push
(
curOpt
);
}
}
/**
* 遇到右括号和等号执行的连续计算操作(递归计算)
*
* @param optStack 运算符栈
* @param numStack 数值栈
* @param isBracket true表示为括号类型计算
*/
public
static
void
directCalc
(
Stack
<
String
>
optStack
,
Stack
<
BigDecimal
>
numStack
,
boolean
isBracket
)
{
String
opt
=
optStack
.
pop
();
// 当前参与计算运算符
BigDecimal
num2
=
numStack
.
pop
();
// 当前参与计算数值2
BigDecimal
num1
=
numStack
.
pop
();
// 当前参与计算数值1
BigDecimal
bigDecimal
=
floatingPointCalc
(
opt
,
num1
,
num2
);
// 计算结果当做操作数入栈
numStack
.
push
(
bigDecimal
);
if
(
isBracket
)
{
if
(
"("
.
equals
(
optStack
.
peek
()))
{
// 括号类型则遇左括号停止计算,同时将左括号从栈中移除
optStack
.
pop
();
}
else
{
directCalc
(
optStack
,
numStack
,
isBracket
);
}
}
else
{
if
(!
optStack
.
empty
())
{
// 等号类型只要栈中还有运算符就继续计算
directCalc
(
optStack
,
numStack
,
isBracket
);
}
}
}
/**
* 不丢失精度的二元运算,支持高精度计算
*
* @param opt
* @return
*/
public
static
BigDecimal
floatingPointCalc
(
String
opt
,
BigDecimal
bigDecimal1
,
BigDecimal
bigDecimal2
)
{
BigDecimal
resultBigDecimal
=
new
BigDecimal
(
0
);
switch
(
opt
)
{
case
"+"
:
resultBigDecimal
=
bigDecimal1
.
add
(
bigDecimal2
);
break
;
case
"-"
:
resultBigDecimal
=
bigDecimal1
.
subtract
(
bigDecimal2
);
break
;
case
"*"
:
resultBigDecimal
=
bigDecimal1
.
multiply
(
bigDecimal2
);
break
;
case
"/"
:
resultBigDecimal
=
bigDecimal1
.
divide
(
bigDecimal2
,
10
,
BigDecimal
.
ROUND_HALF_DOWN
);
// 注意此处用法
break
;
default
:
break
;
}
return
resultBigDecimal
;
}
/**
* priority = 0 表示两个运算符同级别
* priority = 1 第二个运算符级别高,负数则相反
*
* @param opt1
* @param opt2
* @return
*/
public
static
int
getPriority
(
String
opt1
,
String
opt2
)
{
int
priority
=
OPT_PRIORITY_MAP
.
get
(
opt2
)
-
OPT_PRIORITY_MAP
.
get
(
opt1
);
return
priority
;
}
/**
* 浮点数相等比较函数
*
* @param value1
* @param value2
* @return
*/
private
static
boolean
isDoubleEquals
(
double
value1
,
double
value2
)
{
System
.
out
.
println
(
"正确结果="
+
value1
+
", 实际计算结果="
+
value2
);
return
Math
.
abs
(
value1
-
value2
)
<=
0.0001
;
}
/* public static void main(String[] args) throws ScriptException {
Scanner in = new Scanner(System.in);
System.out.println("请输入一个算法表达式:");
String str = in.next();
// 表达式字符合法性校验
Matcher matcher = EXPRESSION_PATTERN.matcher(str);
if (!matcher.matches()) {
System.out.println("aaaaa");
return;
}
ScriptEngine se = new ScriptEngineManager().getEngineByName("JavaScript");
Object eval = se.eval(str);
Double aDouble = Double.valueOf(eval.toString());
BigDecimal b = new BigDecimal(aDouble);
double doubleRate = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
str +="=";
double aa = executeExpression(str);
System.out.println("js算:"+doubleRate+"---算法:"+aa);
// // 几个测试数据
// System.out.println(isDoubleEquals(-39.5, executeExpression(" 2 + 3/2 * 3 - 4 *(2 + 5 -2*4/2+9) + 3 + (2*1)-3= ")));
// System.out.println(isDoubleEquals(60.3666, executeExpression("9*2+1/3*2-4+(3*2/5+3+3*6)+3*5-1+3+(4+5*1/2)=")));
// System.out.println(isDoubleEquals(372.8, executeExpression(" 9.2 *(20-1)-1+199 = ")));
// System.out.println(isDoubleEquals(372.8, executeExpression(" 9.2 *(20-1)-1+199 ")));
// System.out.println(isDoubleEquals(372.8, executeExpression(" 9.2 *(20-1)-1+199")));
// System.out.println(isDoubleEquals(-29, executeExpression(" 9 *(20-1)-(1+199) ")));
// System.out.println(isDoubleEquals(1.0E24, executeExpression("1000000000000*1000000000000 = ")));
}*/
public
static
Boolean
executeExpressionForBoolean
(
String
expression
){
ScriptEngine
se
=
new
ScriptEngineManager
().
getEngineByName
(
"JavaScript"
);
Object
eval
=
null
;
Boolean
result
=
null
;
try
{
eval
=
se
.
eval
(
expression
);
result
=
Boolean
.
parseBoolean
(
eval
.
toString
());
}
catch
(
ScriptException
e
)
{
//e.printStackTrace();
return
null
;
}
return
result
;
}
public
static
String
executeExpressionForString
(
String
expression
){
ScriptEngine
se
=
new
ScriptEngineManager
().
getEngineByName
(
"JavaScript"
);
Object
eval
=
null
;
String
result
=
null
;
try
{
eval
=
se
.
eval
(
expression
);
result
=
eval
.
toString
();
}
catch
(
ScriptException
e
)
{
//e.printStackTrace();
return
null
;
}
return
result
;
}
/* ScriptEngine se = new ScriptEngineManager().getEngineByName("JavaScript");
Object eval = null;
try {
eval = se.eval("1+2+(1*3)");
Double aDouble = Double.valueOf(eval.toString());
DecimalFormat df = new DecimalFormat("0.00");
String amountstr = df.format(aDouble);
//amount = new BigDecimal(amountstr);
System.out.println("amountstr = "+amountstr);
} catch (ScriptException e) {
e.printStackTrace();
}*/
}
sk-module-biz/src/main/java/com/skua/SkApplication.java
查看文件 @
1ca3061
...
...
@@ -29,7 +29,6 @@ public class SkApplication {
"swagger-ui: \thttp://"
+
ip
+
":"
+
port
+
path
+
"/swagger-ui.html\n\t"
+
"Doc: \t\thttp://"
+
ip
+
":"
+
port
+
path
+
"/doc.html\n"
+
"----------------------------------------------------------"
);
}
// @Configuration
...
...
sk-module-biz/src/main/java/com/skua/modules/emergency/controller/EmergencyRiskEventController.java
查看文件 @
1ca3061
...
...
@@ -59,8 +59,7 @@ public class EmergencyRiskEventController {
Result
<
List
<
Map
<
String
,
Object
>>>
result
=
new
Result
<>();
QueryWrapper
<
EmergencyRiskEvent
>
queryWrapper
=
new
QueryWrapper
<
EmergencyRiskEvent
>();
//QueryGenerator.initQueryWrapper(equipmentDefectManagement, req.getParameterMap());
queryWrapper
.
select
(
"count(id) count,handle_result handleResult"
);
queryWrapper
.
ge
(
StringUtils
.
isNotEmpty
(
equipmentDefectManagement
.
getStartTime
()),
"report_date"
,
equipmentDefectManagement
.
getStartTime
());
queryWrapper
.
le
(
StringUtils
.
isNotEmpty
(
equipmentDefectManagement
.
getEndTime
()),
"report_date"
,
equipmentDefectManagement
.
getEndTime
());
queryWrapper
.
groupBy
(
"handle_result"
);
List
<
Map
<
String
,
Object
>>
list
=
emergencyRiskEventService
.
listMaps
(
queryWrapper
);
result
.
setSuccess
(
true
);
...
...
@@ -79,8 +78,7 @@ public class EmergencyRiskEventController {
emergencyRiskEventQueryWrapper
.
eq
(
"handle_result"
,
"1"
);
emergencyRiskEventQueryWrapper
.
ne
(
"event_type"
,
""
);
emergencyRiskEventQueryWrapper
.
isNotNull
(
"event_type"
);
emergencyRiskEventQueryWrapper
.
ge
(
StringUtils
.
isNotEmpty
(
equipmentDefectManagement
.
getStartTime
()),
"report_date"
,
equipmentDefectManagement
.
getStartTime
());
emergencyRiskEventQueryWrapper
.
le
(
StringUtils
.
isNotEmpty
(
equipmentDefectManagement
.
getEndTime
()),
"report_date"
,
equipmentDefectManagement
.
getEndTime
());
emergencyRiskEventQueryWrapper
.
groupBy
(
"handle_result"
,
"event_type"
);
List
<
Map
<
String
,
Object
>>
list
=
emergencyRiskEventService
.
listMaps
(
emergencyRiskEventQueryWrapper
);
//已处理应急事件
...
...
@@ -89,8 +87,7 @@ public class EmergencyRiskEventController {
emergencyRiskEventQueryWrapper
.
eq
(
"handle_result"
,
"3"
);
emergencyRiskEventQueryWrapper
.
ne
(
"event_type"
,
""
);
emergencyRiskEventQueryWrapper
.
isNotNull
(
"event_type"
);
emergencyRiskEventQueryWrapper
.
ge
(
StringUtils
.
isNotEmpty
(
equipmentDefectManagement
.
getStartTime
()),
"report_date"
,
equipmentDefectManagement
.
getStartTime
());
emergencyRiskEventQueryWrapper
.
le
(
StringUtils
.
isNotEmpty
(
equipmentDefectManagement
.
getEndTime
()),
"report_date"
,
equipmentDefectManagement
.
getEndTime
());
emergencyRiskEventQueryWrapper
.
groupBy
(
"handle_result"
,
"event_type"
);
List
<
Map
<
String
,
Object
>>
yclList
=
emergencyRiskEventService
.
listMaps
(
emergencyRiskEventQueryWrapper
);
//获取未处理、已处理中的应急事件类型
...
...
@@ -133,40 +130,40 @@ public class EmergencyRiskEventController {
@RequestParam
(
name
=
"pageSize"
,
defaultValue
=
"10"
)
Integer
pageSize
,
HttpServletRequest
req
)
{
Result
<
IPage
<
EmergencyRiskEvent
>>
result
=
new
Result
<
IPage
<
EmergencyRiskEvent
>>();
//2023-10-05 00:00:00 2023-10-05 23:59:59
QueryWrapper
<
EmergencyRiskEvent
>
queryWrapper
=
QueryGenerator
.
initQueryWrapper
(
emergencyRiskEvent
,
req
.
getParameterMap
());
Page
<
EmergencyRiskEvent
>
page
=
new
Page
<
EmergencyRiskEvent
>(
pageNo
,
pageSize
);
if
(
StringUtils
.
isNotEmpty
(
emergencyRiskEvent
.
getStartTime
())){
queryWrapper
.
ge
(
"report_date"
,
emergencyRiskEvent
.
getStartTime
());
}
if
(
StringUtils
.
isNotEmpty
(
emergencyRiskEvent
.
getEndTime
())){
queryWrapper
.
le
(
"report_date"
,
emergencyRiskEvent
.
getEndTime
());
}
IPage
<
EmergencyRiskEvent
>
pageList
=
emergencyRiskEventService
.
page
(
page
,
queryWrapper
);
//获取流程状态
List
<
EmergencyRiskEvent
>
records
=
pageList
.
getRecords
();
Set
<
String
>
processInstanceIdSet
=
records
.
stream
().
filter
(
data
->
StringUtils
.
isNotBlank
(
data
.
getProcessInstanceId
()))
.
map
(
EmergencyRiskEvent:
:
getProcessInstanceId
).
collect
(
Collectors
.
toSet
());
Map
<
String
,
Map
<
String
,
String
>>
processInstanceMap
;
try
{
processInstanceMap
=
flowBusinessService
.
getProcessState
(
processInstanceIdSet
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
processInstanceMap
=
new
HashMap
<>();
}
for
(
EmergencyRiskEvent
record
:
records
)
{
record
.
getFlow
().
setProcessDefinitionKey
(
processInstanceMap
.
getOrDefault
(
record
.
getProcessInstanceId
(),
new
HashMap
<>()).
get
(
"processDefinitionKey"
));
record
.
getFlow
().
setTaskDefinitionKey
(
processInstanceMap
.
getOrDefault
(
record
.
getProcessInstanceId
(),
new
HashMap
<>()).
get
(
"taskDefinitionKey"
));
record
.
getFlow
().
setStatus
(
processInstanceMap
.
getOrDefault
(
record
.
getProcessInstanceId
(),
new
HashMap
<>()).
get
(
"state"
));
record
.
getFlow
().
setTaskName
(
processInstanceMap
.
getOrDefault
(
record
.
getProcessInstanceId
(),
new
HashMap
<>()).
get
(
"processDefinitionName"
));
}
if
(
records
!=
null
&&
!
records
.
isEmpty
()){
Set
<
String
>
processInstanceIdSet
=
records
.
stream
().
filter
(
data
->
StringUtils
.
isNotBlank
(
data
.
getProcessInstanceId
()))
.
map
(
EmergencyRiskEvent:
:
getProcessInstanceId
).
collect
(
Collectors
.
toSet
());
Map
<
String
,
Map
<
String
,
String
>>
processInstanceMap
;
try
{
processInstanceMap
=
flowBusinessService
.
getProcessState
(
processInstanceIdSet
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
processInstanceMap
=
new
HashMap
<>();
}
for
(
EmergencyRiskEvent
record
:
records
)
{
record
.
getFlow
().
setProcessDefinitionKey
(
processInstanceMap
.
getOrDefault
(
record
.
getProcessInstanceId
(),
new
HashMap
<>()).
get
(
"processDefinitionKey"
));
record
.
getFlow
().
setTaskDefinitionKey
(
processInstanceMap
.
getOrDefault
(
record
.
getProcessInstanceId
(),
new
HashMap
<>()).
get
(
"taskDefinitionKey"
));
record
.
getFlow
().
setStatus
(
processInstanceMap
.
getOrDefault
(
record
.
getProcessInstanceId
(),
new
HashMap
<>()).
get
(
"state"
));
record
.
getFlow
().
setTaskName
(
processInstanceMap
.
getOrDefault
(
record
.
getProcessInstanceId
(),
new
HashMap
<>()).
get
(
"processDefinitionName"
));
}
}
result
.
setSuccess
(
true
);
result
.
setResult
(
pageList
);
return
result
;
}
/**
/**
...
...
sk-module-biz/src/main/java/com/skua/modules/emergency/entity/EmergencyRiskEvent.java
查看文件 @
1ca3061
...
...
@@ -143,10 +143,5 @@ public class EmergencyRiskEvent extends FlowEntity {
@Excel
(
name
=
"删除标识,0:正常,1:删除"
,
width
=
15
)
@ApiModelProperty
(
value
=
"删除标识,0:正常,1:删除"
)
private
Integer
delFlag
;
@TableField
(
exist
=
false
)
@ApiModelProperty
(
value
=
"开始时间"
)
private
String
startTime
;
@TableField
(
exist
=
false
)
@ApiModelProperty
(
value
=
"结束时间"
)
private
String
endTime
;
}
...
...
sk-module-datafill/src/main/java/com/skua/modules/custom/service/impl/FCustomReportDatasetServiceImpl.java
查看文件 @
1ca3061
...
...
@@ -2,6 +2,8 @@ package com.skua.modules.custom.service.impl;
import
com.skua.common.report.ReportViewUtil
;
import
com.skua.core.context.SpringContextUtils
;
import
com.skua.core.excel.demo.Student
;
import
com.skua.core.util.ConvertUtils
;
import
com.skua.modules.custom.entity.FCustomReportDataset
;
import
com.skua.modules.custom.mapper.FCustomReportDatasetMapper
;
import
com.skua.modules.custom.service.IFCustomReportDatasetService
;
...
...
@@ -279,18 +281,18 @@ public class FCustomReportDatasetServiceImpl extends ServiceImpl<FCustomReportDa
JnhbLargeScreenVO
largeScreenVO
=
new
JnhbLargeScreenVO
();
//当月数据
String
dataViewName2
=
ReportViewUtil
.
buildView
(
"2119ecbf53a1d2d0708258ff67cfd9e1"
,
"CSL"
,
null
,
dataVO
.
getNowStartTime
(),
dataVO
.
getNowEndTime
());
String
dataViewName3
=
ReportViewUtil
.
buildView
(
"3a243d5715b9e1a3753c180872ca0df9"
,
"DLHJ,GFFDL,QY,WNL,WNHSL,GFCZL,WFCSL,WFCZL"
,
null
,
dataVO
.
getNowStartTime
(),
dataVO
.
getNowEndTime
());
String
dataViewName3
=
ReportViewUtil
.
buildView
(
"3a243d5715b9e1a3753c180872ca0df9"
,
"DLHJ,GFFDL,QY,
YSL,
WNL,WNHSL,GFCZL,WFCSL,WFCZL"
,
null
,
dataVO
.
getNowStartTime
(),
dataVO
.
getNowEndTime
());
List
<
JnhbReportData
>
jnhbReportDataList
=
mapper
.
getJnhbReport
(
dataViewName2
,
dataViewName3
,
dataVO
.
getNowStartTime
(),
dataVO
.
getNowEndTime
(),
null
);
// 上月数据 同比
dataViewName2
=
ReportViewUtil
.
buildView
(
"2119ecbf53a1d2d0708258ff67cfd9e1"
,
"CSL"
,
null
,
dataVO
.
getLastMonthStartTime
(),
dataVO
.
getLastMonthEndTime
());
dataViewName3
=
ReportViewUtil
.
buildView
(
"3a243d5715b9e1a3753c180872ca0df9"
,
"DLHJ,GFFDL,QY,WNL,WNHSL,GFCZL,WFCSL,WFCZL"
,
null
,
dataVO
.
getLastMonthStartTime
(),
dataVO
.
getLastMonthEndTime
());
dataViewName3
=
ReportViewUtil
.
buildView
(
"3a243d5715b9e1a3753c180872ca0df9"
,
"DLHJ,GFFDL,QY,
YSL,
WNL,WNHSL,GFCZL,WFCSL,WFCZL"
,
null
,
dataVO
.
getLastMonthStartTime
(),
dataVO
.
getLastMonthEndTime
());
List
<
JnhbReportData
>
lastMonthReportDataList
=
mapper
.
getJnhbReport
(
dataViewName2
,
dataViewName3
,
dataVO
.
getLastMonthStartTime
(),
dataVO
.
getLastMonthEndTime
(),
null
);
Map
<
String
,
JnhbReportData
>
lastMonthMapData
=
convertJnhbReportDataMap
(
lastMonthReportDataList
);
// 去年数据 环比
dataViewName2
=
ReportViewUtil
.
buildView
(
"2119ecbf53a1d2d0708258ff67cfd9e1"
,
"CSL"
,
null
,
dataVO
.
getLastYearStartTime
(),
dataVO
.
getLastYearEndTime
());
dataViewName3
=
ReportViewUtil
.
buildView
(
"3a243d5715b9e1a3753c180872ca0df9"
,
"DLHJ,GFFDL,QY,WNL,WNHSL,GFCZL,WFCSL,WFCZL"
,
null
,
dataVO
.
getLastYearStartTime
(),
dataVO
.
getLastYearEndTime
());
dataViewName3
=
ReportViewUtil
.
buildView
(
"3a243d5715b9e1a3753c180872ca0df9"
,
"DLHJ,GFFDL,QY,
YSL,
WNL,WNHSL,GFCZL,WFCSL,WFCZL"
,
null
,
dataVO
.
getLastYearStartTime
(),
dataVO
.
getLastYearEndTime
());
List
<
JnhbReportData
>
lastYearReportDataList
=
mapper
.
getJnhbReport
(
dataViewName2
,
dataViewName3
,
dataVO
.
getLastYearStartTime
(),
dataVO
.
getLastYearEndTime
(),
null
);
Map
<
String
,
JnhbReportData
>
lastYearMapData
=
convertJnhbReportDataMap
(
lastYearReportDataList
);
...
...
@@ -316,6 +318,7 @@ public class FCustomReportDatasetServiceImpl extends ServiceImpl<FCustomReportDa
powerConsumeVO
=
new
PowerConsumeVO
(
reportData
.
getDepartId
(),
reportData
.
getDepartName
(),
reportData
.
getDh
(),
reportData
.
getGffdl
(),
reportData
.
getQy
(),
reportData
.
getZhnyxhl
()
,
reportData
.
getEyhtpfl
()
,
reportData
.
getDsdh
()
);
c02NumberVO
=
new
ResultNumberVO
();
c02NumberVO
.
setName
(
reportData
.
getDepartName
()
);
c02NumberVO
.
setValue
(
reportData
.
getCodxjl
()
);
cod_NumberVO
=
new
ResultNumberVO
();
cod_NumberVO
.
setValue
(
reportData
.
getCodxjl
());
nh3n_NumberVO
=
new
ResultNumberVO
();
nh3n_NumberVO
.
setValue
(
reportData
.
getTnxjl
());
...
...
@@ -380,6 +383,35 @@ public class FCustomReportDatasetServiceImpl extends ServiceImpl<FCustomReportDa
int
count2
=
masterDB
.
queryForObject
(
"select count(1) from equipment_info where energy_level = 2"
,
Integer
.
class
);
largeScreenVO
.
setEquipmentL2
(
count2
);
// 各站点系统负荷率排名:负荷率排序、设置排名
if
(
largeScreenVO
.
getLoadRateVOList
()
!=
null
&&
!
largeScreenVO
.
getLoadRateVOList
().
isEmpty
()){
// 根据分数排序
Collections
.
sort
(
largeScreenVO
.
getLoadRateVOList
(),
new
Comparator
<
LoadRateVO
>()
{
public
int
compare
(
LoadRateVO
s1
,
LoadRateVO
s2
)
{
return
Double
.
compare
(
ConvertUtils
.
getDouble
(
s1
.
getWsfhl
(),
0
d
),
ConvertUtils
.
getDouble
(
s1
.
getWsfhl
(),
0
d
));
// 降序排序
}
});
/*int rank = 1; // 设置排名
for( LoadRateVO loadRateVORank: largeScreenVO.getLoadRateVOList()){
loadRateVORank.setRank( rank++);
}*/
}
//各站点能源消耗排名 吨水电耗
if
(
largeScreenVO
.
getPowerConsumeVOList
()
!=
null
&&
!
largeScreenVO
.
getPowerConsumeVOList
().
isEmpty
())
{
// 根据分数排序
Collections
.
sort
(
largeScreenVO
.
getPowerConsumeVOList
(),
new
Comparator
<
PowerConsumeVO
>()
{
public
int
compare
(
PowerConsumeVO
s1
,
PowerConsumeVO
s2
)
{
return
Double
.
compare
(
ConvertUtils
.
getDouble
(
s1
.
getDh
(),
0
d
),
ConvertUtils
.
getDouble
(
s1
.
getDh
(),
0
d
));
// 降序排序
}
});
/*int rank = 1; // 设置排名
for( LoadRateVO loadRateVORank: largeScreenVO.getLoadRateVOList()){
loadRateVORank.setRank( rank++);
}*/
}
return
largeScreenVO
;
}
/**转换为Map<部门编号,JnhbReportData> */
...
...
sk-module-datafill/src/main/java/com/skua/modules/report/vo/JnhbLargeScreenVO.java
查看文件 @
1ca3061
...
...
@@ -50,38 +50,39 @@ public class JnhbLargeScreenVO {
public
void
setHeadStatisticsValue
(
JnhbReportData
reportData
){
// wssjcll, wsfhl, dh, qy, xinshui, zhnyxhl, eyhtpfl, dsdh
////水处理量,系统负荷率,电耗,汽油,新水,综合能耗,C02,吨水
this
.
getHeadStatisticsList
().
get
(
0
).
setValue
(
reportData
.
getWssjcll
(
)
);
this
.
getHeadStatisticsList
().
get
(
1
).
setValue
(
reportData
.
getWsfhl
(
)
);
this
.
getHeadStatisticsList
().
get
(
2
).
setValue
(
reportData
.
getDh
()
);
this
.
getHeadStatisticsList
().
get
(
3
).
setValue
(
reportData
.
getQy
(
)
);
this
.
getHeadStatisticsList
().
get
(
4
).
setValue
(
reportData
.
getXssyl
(
)
);
this
.
getHeadStatisticsList
().
get
(
5
).
setValue
(
reportData
.
getZhnyxhl
(
)
);
this
.
getHeadStatisticsList
().
get
(
6
).
setValue
(
reportData
.
getEyhtpfl
()
);
this
.
getHeadStatisticsList
().
get
(
7
).
setValue
(
reportData
.
getDsdh
()
);
this
.
getHeadStatisticsList
().
get
(
0
).
setValue
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
0
).
getValue
()
,
reportData
.
getWssjcll
()
)
);
this
.
getHeadStatisticsList
().
get
(
1
).
setValue
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
1
).
getValue
()
,
reportData
.
getWsfhl
()
)
);
this
.
getHeadStatisticsList
().
get
(
2
).
setValue
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
2
).
getValue
()
,
reportData
.
getDh
()
)
);
this
.
getHeadStatisticsList
().
get
(
3
).
setValue
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
3
).
getValue
()
,
reportData
.
getQy
()
)
);
this
.
getHeadStatisticsList
().
get
(
4
).
setValue
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
4
).
getValue
()
,
reportData
.
getXssyl
()
)
);
this
.
getHeadStatisticsList
().
get
(
5
).
setValue
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
5
).
getValue
()
,
reportData
.
getZhnyxhl
()
)
);
this
.
getHeadStatisticsList
().
get
(
6
).
setValue
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
6
).
getValue
()
,
reportData
.
getEyhtpfl
()
)
);
this
.
getHeadStatisticsList
().
get
(
7
).
setValue
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
7
).
getValue
()
,
reportData
.
getDsdh
()
)
);
}
public
void
setHeadStatisticsValueTB
(
JnhbReportData
reportData
){
// wssjcll, wsfhl, dh, qy, xinshui, zhnyxhl, eyhtpfl, dsdh
////水处理量,系统负荷率,电耗,汽油,新水,综合能耗,C02,吨水
this
.
getHeadStatisticsList
().
get
(
0
).
setValueTb
(
reportData
.
getWssjcll
()
);
this
.
getHeadStatisticsList
().
get
(
1
).
setValueTb
(
reportData
.
getWsfhl
()
);
this
.
getHeadStatisticsList
().
get
(
2
).
setValueTb
(
reportData
.
getDh
()
);
this
.
getHeadStatisticsList
().
get
(
3
).
setValueTb
(
reportData
.
getQy
()
);
this
.
getHeadStatisticsList
().
get
(
4
).
setValueTb
(
reportData
.
getXssyl
()
);
this
.
getHeadStatisticsList
().
get
(
5
).
setValueTb
(
reportData
.
getZhnyxhl
()
);
this
.
getHeadStatisticsList
().
get
(
6
).
setValueTb
(
reportData
.
getEyhtpfl
()
);
this
.
getHeadStatisticsList
().
get
(
7
).
setValueTb
(
reportData
.
getDsdh
()
);
this
.
getHeadStatisticsList
().
get
(
0
).
setValueTb
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
0
).
getValueTb
()
,
reportData
.
getWssjcll
())
);
this
.
getHeadStatisticsList
().
get
(
1
).
setValueTb
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
1
).
getValueTb
()
,
reportData
.
getWsfhl
())
);
this
.
getHeadStatisticsList
().
get
(
2
).
setValueTb
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
2
).
getValueTb
()
,
reportData
.
getDh
()
));
this
.
getHeadStatisticsList
().
get
(
3
).
setValueTb
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
3
).
getValueTb
()
,
reportData
.
getQy
())
);
this
.
getHeadStatisticsList
().
get
(
4
).
setValueTb
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
4
).
getValueTb
()
,
reportData
.
getXssyl
())
);
this
.
getHeadStatisticsList
().
get
(
5
).
setValueTb
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
5
).
getValueTb
()
,
reportData
.
getZhnyxhl
())
);
this
.
getHeadStatisticsList
().
get
(
6
).
setValueTb
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
6
).
getValueTb
()
,
reportData
.
getEyhtpfl
()
));
this
.
getHeadStatisticsList
().
get
(
7
).
setValueTb
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
7
).
getValueTb
()
,
reportData
.
getDsdh
()
));
}
public
void
setHeadStatisticsValueHB
(
JnhbReportData
reportData
){
// wssjcll, wsfhl, dh, qy, xinshui, zhnyxhl, eyhtpfl, dsdh
////水处理量,系统负荷率,电耗,汽油,新水,综合能耗,C02,吨水
this
.
getHeadStatisticsList
().
get
(
0
).
setValueHb
(
reportData
.
getWssjcll
(
)
);
this
.
getHeadStatisticsList
().
get
(
1
).
setValueHb
(
reportData
.
getWsfhl
(
)
);
this
.
getHeadStatisticsList
().
get
(
2
).
setValueHb
(
reportData
.
getDh
()
);
this
.
getHeadStatisticsList
().
get
(
3
).
setValueHb
(
reportData
.
getQy
(
)
);
this
.
getHeadStatisticsList
().
get
(
4
).
setValueHb
(
reportData
.
getXssyl
(
)
);
this
.
getHeadStatisticsList
().
get
(
5
).
setValueHb
(
reportData
.
getZhnyxhl
(
)
);
this
.
getHeadStatisticsList
().
get
(
6
).
setValueHb
(
reportData
.
getEyhtpfl
()
);
this
.
getHeadStatisticsList
().
get
(
7
).
setValueHb
(
reportData
.
getDsdh
()
);
this
.
getHeadStatisticsList
().
get
(
0
).
setValueHb
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
0
).
getValueHb
()
,
reportData
.
getWssjcll
()
)
);
this
.
getHeadStatisticsList
().
get
(
1
).
setValueHb
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
1
).
getValueHb
()
,
reportData
.
getWsfhl
()
)
);
this
.
getHeadStatisticsList
().
get
(
2
).
setValueHb
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
2
).
getValueHb
()
,
reportData
.
getDh
()
)
);
this
.
getHeadStatisticsList
().
get
(
3
).
setValueHb
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
3
).
getValueHb
()
,
reportData
.
getQy
()
)
);
this
.
getHeadStatisticsList
().
get
(
4
).
setValueHb
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
4
).
getValueHb
()
,
reportData
.
getXssyl
()
)
);
this
.
getHeadStatisticsList
().
get
(
5
).
setValueHb
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
5
).
getValueHb
()
,
reportData
.
getZhnyxhl
()
)
);
this
.
getHeadStatisticsList
().
get
(
6
).
setValueHb
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
6
).
getValueHb
()
,
reportData
.
getEyhtpfl
()
)
);
this
.
getHeadStatisticsList
().
get
(
7
).
setValueHb
(
DigitalUtils
.
add
(
this
.
getHeadStatisticsList
().
get
(
7
).
getValueHb
()
,
reportData
.
getDsdh
()
)
);
}
/***
...
...
@@ -98,13 +99,17 @@ public class JnhbLargeScreenVO {
public
JnhbLargeScreenVO
(){
//头部数值统计
String
names
=
"污水处理量,系统负荷率,电耗,汽油,新水,综合能耗,C02,吨水"
;
String
unit
=
"万吨,%,万千瓦时,吨,吨,吨标准煤,吨CO2当量,千瓦时/吨"
;
String
[]
nameList
=
names
.
split
(
","
);
String
[]
unitList
=
unit
.
split
(
","
);
ResultNumberVO
numberVO
=
null
;
for
(
String
name
:
nameList
){
for
(
int
i
=
0
;
i
<
nameList
.
length
;
i
++
){
numberVO
=
new
ResultNumberVO
();
numberVO
.
setName
(
name
);
numberVO
.
setName
(
nameList
[
i
]);
numberVO
.
setUnit
(
unitList
[
i
]
);
this
.
getHeadStatisticsList
().
add
(
numberVO
)
;
}
//消减量统计
names
=
"COD,NH3-N,TP,TN"
;
nameList
=
names
.
split
(
","
);
...
...
sk-module-datafill/src/main/java/com/skua/modules/report/vo/largeScreen/ResultChartsVO.java
查看文件 @
1ca3061
package
com
.
skua
.
modules
.
report
.
vo
.
largeScreen
;
import
com.skua.core.util.ConvertUtils
;
import
com.skua.modules.report.vo.JnhbReportData
;
import
com.skua.tool.util.DigitalUtils
;
import
io.swagger.annotations.ApiModel
;
...
...
@@ -32,10 +33,10 @@ public class ResultChartsVO {
public
void
setData
(
JnhbReportData
reportData
){
this
.
getXLine
().
add
(
reportData
.
getDepartName
()
)
;
this
.
getCodDataList
().
add
(
reportData
.
getCodxjl
()
)
;
this
.
getNh3DataList
().
add
(
reportData
.
getTnxjl
(
)
)
;
this
.
getTpDataList
().
add
(
reportData
.
getTpxjl
(
)
)
;
this
.
getTnDataList
().
add
(
reportData
.
getTnxjl
(
)
)
;
this
.
getCodDataList
().
add
(
ConvertUtils
.
getString
(
reportData
.
getCodxjl
(),
"0"
)
)
;
this
.
getNh3DataList
().
add
(
ConvertUtils
.
getString
(
reportData
.
getTnxjl
(),
"0"
)
)
;
this
.
getTpDataList
().
add
(
ConvertUtils
.
getString
(
reportData
.
getTpxjl
(),
"0"
)
)
;
this
.
getTnDataList
().
add
(
ConvertUtils
.
getString
(
reportData
.
getTnxjl
(),
"0"
)
)
;
}
public
void
setDataByZhnyxhl
(
JnhbReportData
reportData
){
this
.
getXLine
().
add
(
reportData
.
getDepartName
()
)
;
...
...
sk-module-datafill/src/main/java/com/skua/modules/report/vo/largeScreen/ResultNumberVO.java
查看文件 @
1ca3061
package
com
.
skua
.
modules
.
report
.
vo
.
largeScreen
;
import
com.skua.tool.util.DigitalUtils
;
import
com.skua.tool.util.JSUtils
;
import
io.swagger.annotations.ApiModel
;
import
io.swagger.annotations.ApiModelProperty
;
import
lombok.Data
;
...
...
@@ -14,6 +15,8 @@ public class ResultNumberVO {
@ApiModelProperty
(
value
=
"名称"
)
private
String
name
;
@ApiModelProperty
(
value
=
"单位"
)
private
String
unit
;
@ApiModelProperty
(
value
=
"结果"
)
private
String
value
;
...
...
@@ -24,25 +27,71 @@ public class ResultNumberVO {
@ApiModelProperty
(
value
=
"环比(上月)"
)
private
String
valueHb
;
@ApiModelProperty
(
value
=
"同比(去年同期)排名"
)
private
String
valueTbRank
;
/*
@ApiModelProperty(value = "同比(去年同期)排名")
private String valueTbRank;
*/
@ApiModelProperty
(
value
=
"环比(上月)排名"
)
private
String
valueHbRank
;
private
Integer
rank
;
/* @ApiModelProperty(value = "环比(上月)排名")
private String valueHbRank;*/
@ApiModelProperty
(
value
=
"同比比例"
)
private
String
valueTbRatio
;
@ApiModelProperty
(
value
=
"同比比例箭头"
)
private
Boolean
valueTbArrow
;
@ApiModelProperty
(
value
=
"环比比例"
)
private
String
valueHbRatio
;
private
String
valueHbRatio
;
@ApiModelProperty
(
value
=
"环比比例箭头"
)
private
Boolean
valueHbArrow
;
public
String
getValueTbRatio
()
{
this
.
valueTbRatio
=
DigitalUtils
.
division
(
this
.
value
,
this
.
valueTb
)
;
String
expression
=
this
.
getValue
()
+
">"
+
this
.
getValueTb
();
Boolean
result
=
JSUtils
.
executeExpressionForBoolean
(
expression
);
if
(
result
!=
null
){
if
(
result
){
expression
=
""
+
this
.
getValue
()
+
"/"
+
this
.
getValueTb
()+
"* 100 - 100"
;
}
if
(
!
result
){
expression
=
" 100-"
+
this
.
getValue
()
+
"/"
+
this
.
getValueTb
()+
"* 100 "
;
}
}
this
.
valueTbRatio
=
JSUtils
.
executeExpression
(
expression
,
"0.0"
);
// DigitalUtils.division( this.value , this.valueTb) ;
return
valueTbRatio
;
}
public
String
getValueHbRatio
()
{
this
.
valueHbRatio
=
DigitalUtils
.
division
(
this
.
value
,
this
.
valueHb
)
;
//this.valueHbRatio = DigitalUtils.division( this.value , this.valueHb) ;
// String expression = "" +this.value +"/"+this.valueHb+"* 100 - 100";
String
expression
=
this
.
getValue
()
+
">"
+
this
.
getValueHb
();
Boolean
result
=
JSUtils
.
executeExpressionForBoolean
(
expression
);
if
(
result
!=
null
){
if
(
result
){
expression
=
""
+
this
.
getValue
()
+
"/"
+
this
.
getValueHb
()+
"* 100 - 100"
;
}
if
(
!
result
){
expression
=
" 100 -"
+
this
.
getValue
()
+
"/"
+
this
.
getValueHb
()+
"* 100 "
;
}
}
this
.
valueHbRatio
=
JSUtils
.
executeExpression
(
expression
,
"0.0"
);
// DigitalUtils.division( this.value , this.valueTb) ;
return
valueHbRatio
;
}
public
Boolean
getValueTbArrow
()
{
String
expression
=
this
.
getValue
()
+
">"
+
this
.
getValueHb
();
Boolean
result
=
JSUtils
.
executeExpressionForBoolean
(
expression
);
if
(
result
==
null
)
result
=
true
;
return
result
;
}
public
Boolean
getValueHbArrow
()
{
String
expression
=
this
.
getValue
()
+
">"
+
this
.
getValueHb
();
Boolean
result
=
JSUtils
.
executeExpressionForBoolean
(
expression
);
if
(
result
==
null
)
result
=
true
;
return
result
;
}
}
...
...
编写
预览
支持
Markdown
格式
附加文件
你添加了
0
人
到此讨论。请谨慎行事。
Finish editing this message first!
Cancel
请
注册
或
登录
后发表评论