Toggle navigation
Toggle navigation
This project
Loading...
Sign in
jiujian
/
client-customer-order-api
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
wangyingyang
2024-12-10 15:16:26 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
74176b43d19c2525d4cc10cbc614b1fbfa4292dd
74176b43
1 parent
e759abc7
fix
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
265 additions
and
3 deletions
src/main/java/com/infoloop/tianting/model/dto/SettlementDTO.java
src/main/java/com/infoloop/tianting/service/impl/SettlementServiceImpl.java
src/main/java/com/infoloop/tianting/model/dto/SettlementDTO.java
View file @
74176b4
...
...
@@ -48,7 +48,16 @@ public class SettlementDTO {
@Data
@Builder
@ApiModel
(
description
=
"SettlementRequestDto"
)
@ApiModel
(
description
=
"SettlementMenuMealDto"
)
public
static
class
SettlementMenuMealDto
{
private
String
skuName
;
private
Integer
price
;
private
Integer
count
;
}
@Data
@Builder
@ApiModel
(
description
=
"SettlementDataDto"
)
public
static
class
SettlementDataDto
{
private
String
client
;
private
String
startTime
;
...
...
@@ -56,6 +65,16 @@ public class SettlementDTO {
private
Map
<
String
,
Map
<
String
,
List
<
SettlementMenuSkuDto
>>>
classifyOrders
;
}
@Data
@Builder
@ApiModel
(
description
=
"SettlementDataByMealDto"
)
public
static
class
SettlementDataByMealDto
{
private
String
client
;
private
LocalDateTime
startTime
;
private
LocalDateTime
endTime
;
private
Map
<
String
,
Map
<
String
,
Map
<
String
,
List
<
SettlementMenuMealDto
>>>>
classifyOrders
;
}
}
...
...
src/main/java/com/infoloop/tianting/service/impl/SettlementServiceImpl.java
View file @
74176b4
...
...
@@ -4,21 +4,33 @@ import com.infoloop.tianting.clientcustomerorderservice.OrderStatusEnum;
import
com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderDetailRpcResponse
;
import
com.infoloop.tianting.clientcustomerorderservice.SingleClientCustomerOrderRpcResponse
;
import
com.infoloop.tianting.context.LoginContextHolder
;
import
com.infoloop.tianting.enums.SettlementDimensionEnum
;
import
com.infoloop.tianting.exception.ClientEndExceptions.BusinessException
;
import
com.infoloop.tianting.exception.ErrorCodeEnum
;
import
com.infoloop.tianting.menuservice.SingleMenuDetailRpcResponse
;
import
com.infoloop.tianting.menuservice.SingleMenuRpcResponse
;
import
com.infoloop.tianting.model.dto.OrderDbDTO.QueryOrderByConditionDto
;
import
com.infoloop.tianting.model.dto.SettlementDTO
;
import
com.infoloop.tianting.model.dto.SettlementDTO.SettlementDataByMealDto
;
import
com.infoloop.tianting.model.dto.SettlementDTO.SettlementDataDto
;
import
com.infoloop.tianting.model.dto.SettlementDTO.SettlementMenuMealDto
;
import
com.infoloop.tianting.model.dto.SettlementDTO.SettlementMenuSkuDto
;
import
com.infoloop.tianting.model.dto.SettlementDTO.SettlementRequestDto
;
import
com.infoloop.tianting.service.SettlementService
;
import
com.infoloop.tianting.service.client.InventoryServiceRpcClient
;
import
com.infoloop.tianting.service.client.MealServiceRpcClient
;
import
com.infoloop.tianting.service.client.MenuServiceRpcClient
;
import
com.infoloop.tianting.service.client.OrderServiceRpcClient
;
import
com.infoloop.tianting.service.client.SkuServiceRpcClient
;
import
com.infoloop.tianting.setmealscheduleservice.SingleMealRpcResponse
;
import
com.infoloop.tianting.utils.DateUtil
;
import
java.time.LocalDate
;
import
java.time.LocalDateTime
;
import
java.time.temporal.ChronoUnit
;
import
java.util.Comparator
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.poi.hpsf.Date
;
import
org.apache.poi.ss.usermodel.Cell
;
import
org.apache.poi.ss.usermodel.Row
;
import
org.apache.poi.ss.usermodel.Sheet
;
...
...
@@ -45,9 +57,19 @@ public class SettlementServiceImpl implements SettlementService {
private
final
MenuServiceRpcClient
menuServiceRpcClient
;
private
final
SkuServiceRpcClient
skuServiceRpcClient
;
private
final
InventoryServiceRpcClient
inventoryServiceRpcClient
;
private
final
MealServiceRpcClient
mealServiceRpcClient
;
@Override
public
ByteArrayOutputStream
generateOrderSettlementExcel
(
SettlementRequestDto
settlementRequest
)
{
if
(
settlementRequest
.
getDimension
().
equals
(
SettlementDimensionEnum
.
BY_SKU
))
{
return
generateOrderSettlementExcelBySku
(
settlementRequest
);
}
else
{
return
generateOrderSettlementExcelByMeal
(
settlementRequest
);
}
}
public
ByteArrayOutputStream
generateOrderSettlementExcelBySku
(
SettlementRequestDto
settlementRequest
)
{
final
var
startDate
=
settlementRequest
.
getTimeStart
().
toLocalDate
().
atStartOfDay
();
final
var
endDate
=
settlementRequest
.
getTimeEnd
().
toLocalDate
().
plusDays
(
1
).
atStartOfDay
();
final
var
operatorLoginInfo
=
LoginContextHolder
.
getLoginInfo
();
...
...
@@ -185,7 +207,7 @@ public class SettlementServiceImpl implements SettlementService {
.
endTime
(
DateUtil
.
formatDate
(
settlementRequest
.
getTimeEnd
(),
DateUtil
.
YYYY_MM_DD
))
.
build
();
try
{
final
var
bytes
=
writeToExcel
(
settlementDataDto
);
final
var
bytes
=
writeToExcel
BySku
(
settlementDataDto
);
return
bytes
;
}
catch
(
IOException
e
)
{
throw
BusinessException
.
build
(
ErrorCodeEnum
.
GENERATE_EXCEL_ERROR
);
...
...
@@ -193,7 +215,7 @@ public class SettlementServiceImpl implements SettlementService {
}
public
static
ByteArrayOutputStream
writeToExcel
(
SettlementDataDto
settlementDataDto
)
public
static
ByteArrayOutputStream
writeToExcel
BySku
(
SettlementDataDto
settlementDataDto
)
throws
IOException
{
Workbook
workbook
=
new
XSSFWorkbook
();
Sheet
sheet
=
workbook
.
createSheet
(
"订单数据"
);
...
...
@@ -295,4 +317,225 @@ public class SettlementServiceImpl implements SettlementService {
return
outputStream
;
}
public
ByteArrayOutputStream
generateOrderSettlementExcelByMeal
(
SettlementRequestDto
settlementRequest
)
{
final
var
startDate
=
settlementRequest
.
getTimeStart
().
toLocalDate
().
atStartOfDay
();
final
var
endDate
=
settlementRequest
.
getTimeEnd
().
toLocalDate
().
plusDays
(
1
).
atStartOfDay
();
final
var
operatorLoginInfo
=
LoginContextHolder
.
getLoginInfo
();
final
var
queryOrderDto
=
QueryOrderByConditionDto
.
builder
()
.
enterpriseId
(
LoginContextHolder
.
hasLogin
()
?
operatorLoginInfo
.
getEnterpriseId
()
:
settlementRequest
.
getEnterpriseId
())
.
shouldFilterCreatedAtTimeStart
(
true
)
.
createdAtTimeStart
(
startDate
)
.
shouldFilterCreatedAtTimeEnd
(
true
)
.
createdAtTimeEnd
(
endDate
)
.
shouldFilterStallIds
(!
settlementRequest
.
getStallIds
().
isEmpty
())
.
stallIds
(
settlementRequest
.
getStallIds
())
.
build
();
final
var
orderList
=
orderServiceRpcClient
.
getOrdersByCondition
(
queryOrderDto
);
List
<
Integer
>
orderIds
=
orderList
.
stream
()
.
filter
(
o
->
!
o
.
getStatus
().
equals
(
OrderStatusEnum
.
ORDER_CANCELED
))
.
map
(
SingleClientCustomerOrderRpcResponse:
:
getId
).
distinct
()
.
collect
(
Collectors
.
toList
());
final
var
orderDetailList
=
orderServiceRpcClient
.
getOrderDetailsByOrderIds
(
orderIds
);
List
<
Integer
>
skuIds
=
orderDetailList
.
stream
()
.
map
(
SingleClientCustomerOrderDetailRpcResponse:
:
getSkuId
)
.
distinct
()
.
collect
(
Collectors
.
toList
());
final
var
skus
=
skuServiceRpcClient
.
getDishSkusByIds
(
skuIds
).
getResponseList
();
List
<
Integer
>
menuIds
=
orderList
.
stream
().
map
(
SingleClientCustomerOrderRpcResponse:
:
getMenuId
).
distinct
()
.
collect
(
Collectors
.
toList
());
final
var
menuList
=
menuServiceRpcClient
.
getMenusByIds
(
operatorLoginInfo
.
getEnterpriseId
(),
menuIds
)
.
getResponsesList
();
final
var
menuDetailList
=
menuServiceRpcClient
.
queryMenuDetailsByMenuIds
(
operatorLoginInfo
.
getEnterpriseId
(),
menuIds
).
getResponsesList
();
//获取到所有的餐别
final
var
allMeals
=
mealServiceRpcClient
.
getAllMeals
(
operatorLoginInfo
.
getEnterpriseId
()).
getResponsesList
();
Map
<
String
,
Map
<
String
,
Map
<
String
,
List
<
SettlementMenuMealDto
>>>>
classifyOrders
=
new
HashMap
<>();
for
(
SingleMenuRpcResponse
menu:
menuList
)
{
final
var
menuName
=
menu
.
getName
();
if
(!
classifyOrders
.
containsKey
(
menuName
))
{
classifyOrders
.
put
(
menuName
,
new
HashMap
<>());
}
final
var
menusMap
=
classifyOrders
.
get
(
menuName
);
//这个餐单下所有已点的orders
final
var
curMenuOrders
=
orderList
.
stream
()
.
filter
(
o
->
o
.
getMenuId
()
==
menu
.
getId
())
.
collect
(
Collectors
.
toList
());
final
var
curMenuOrderIds
=
curMenuOrders
.
stream
()
.
map
(
SingleClientCustomerOrderRpcResponse:
:
getId
)
.
collect
(
Collectors
.
toList
());
//这个餐单下所有已点的order details
final
var
curMenuOrderDetails
=
orderDetailList
.
stream
()
.
filter
(
od
->
curMenuOrderIds
.
contains
(
od
.
getOrderId
()))
.
collect
(
Collectors
.
toList
());
//这个餐单下所有已点的餐别
final
var
curMenuMealIds
=
curMenuOrderDetails
.
stream
()
.
map
(
SingleClientCustomerOrderDetailRpcResponse:
:
getMealId
)
.
distinct
()
.
collect
(
Collectors
.
toList
());
final
var
curMenuMeals
=
allMeals
.
stream
()
.
filter
(
m
->
curMenuMealIds
.
contains
(
m
.
getId
()))
.
collect
(
Collectors
.
toList
());
// 汇总每个餐别的情况
for
(
SingleMealRpcResponse
meal:
curMenuMeals
)
{
final
var
mealName
=
meal
.
getName
();
if
(!
menusMap
.
containsKey
(
mealName
))
{
menusMap
.
put
(
menuName
,
new
HashMap
<>());
}
final
var
mealsMap
=
menusMap
.
get
(
mealName
);
//当前餐别已点的order details
final
var
curMealOrderDetails
=
curMenuOrderDetails
.
stream
()
.
filter
(
od
->
od
.
getMealId
()
==
meal
.
getId
())
.
collect
(
Collectors
.
toList
());
//找出所有需要的日期
final
var
dates
=
curMealOrderDetails
.
stream
()
.
sorted
(
Comparator
.
comparingLong
(
SingleClientCustomerOrderDetailRpcResponse:
:
getCreatedAt
))
.
map
(
o
->
DateUtil
.
formatDateOfUtc
(
o
.
getCreatedAt
(),
DateUtil
.
YYYY_MM_DD_UTC
))
.
distinct
()
.
collect
(
Collectors
.
toList
());
for
(
String
date:
dates
)
{
if
(!
mealsMap
.
containsKey
(
date
))
{
mealsMap
.
put
(
date
,
new
ArrayList
<>());
}
final
var
curMealDateSkuList
=
mealsMap
.
get
(
date
);
//找出当天所有的order details
final
var
curMealDateOrderDetails
=
curMealOrderDetails
.
stream
()
.
filter
(
o
->
DateUtil
.
formatDateOfUtc
(
o
.
getCreatedAt
(),
DateUtil
.
YYYY_MM_DD_UTC
).
equals
(
date
))
.
collect
(
Collectors
.
toList
());
for
(
SingleClientCustomerOrderDetailRpcResponse
detail:
curMealDateOrderDetails
)
{
final
var
settlementOrderDetail
=
SettlementMenuMealDto
.
builder
()
.
skuName
(
detail
.
getShowName
())
.
count
(
detail
.
getCount
())
.
price
(
detail
.
getPrice
())
.
build
();
curMealDateSkuList
.
add
(
settlementOrderDetail
);
}
}
}
}
final
var
client
=
inventoryServiceRpcClient
.
getClientById
(
operatorLoginInfo
.
getEnterpriseId
(),
settlementRequest
.
getClientId
()).
getClient
();
final
var
settlementDataByMealDto
=
SettlementDataByMealDto
.
builder
()
.
classifyOrders
(
classifyOrders
)
.
client
(
client
.
getName
())
.
startTime
(
settlementRequest
.
getTimeStart
())
.
endTime
(
settlementRequest
.
getTimeEnd
())
.
build
();
try
{
final
var
bytes
=
writeToExcelByMeal
(
settlementDataByMealDto
);
return
bytes
;
}
catch
(
IOException
e
)
{
throw
BusinessException
.
build
(
ErrorCodeEnum
.
GENERATE_EXCEL_ERROR
);
}
}
public
static
ByteArrayOutputStream
writeToExcelByMeal
(
SettlementDataByMealDto
settlementDataDto
)
throws
IOException
{
Workbook
workbook
=
new
XSSFWorkbook
();
Sheet
sheet
=
workbook
.
createSheet
(
"订单数据"
);
final
var
classifyOrders
=
settlementDataDto
.
getClassifyOrders
();
int
rowNum
=
0
;
Row
sheetTitleRow
=
sheet
.
createRow
(
rowNum
++);
Cell
sheetTitleCell
=
sheetTitleRow
.
createCell
(
0
);
sheetTitleCell
.
setCellValue
(
settlementDataDto
.
getClient
());
Row
dateRangeRow
=
sheet
.
createRow
(
rowNum
++);
Cell
dateRangeCell
=
dateRangeRow
.
createCell
(
0
);
final
var
dateRange
=
settlementDataDto
.
getStartTime
()
+
"至"
+
settlementDataDto
.
getEndTime
();
dateRangeCell
.
setCellValue
(
dateRange
);
Row
titleRow
=
sheet
.
createRow
(
rowNum
++);
int
columnNum
=
0
;
Cell
menuTitleCell
=
titleRow
.
createCell
(
columnNum
++);
menuTitleCell
.
setCellValue
(
"餐单名称"
);
Cell
mealTitleCell
=
titleRow
.
createCell
(
columnNum
++);
mealTitleCell
.
setCellValue
(
"餐别"
);
final
var
dates
=
getDatesBetween
(
settlementDataDto
.
getStartTime
(),
settlementDataDto
.
getEndTime
());
for
(
String
date:
dates
)
{
Cell
dateTitleCell
=
titleRow
.
createCell
(
columnNum
++);
dateTitleCell
.
setCellValue
(
date
);
}
Cell
priceTitleCell
=
titleRow
.
createCell
(
columnNum
);
priceTitleCell
.
setCellValue
(
"总金额"
);
for
(
Map
.
Entry
<
String
,
Map
<
String
,
Map
<
String
,
List
<
SettlementMenuMealDto
>>>>
outerEntry
:
classifyOrders
.
entrySet
())
{
String
menuNme
=
outerEntry
.
getKey
();
Map
<
String
,
Map
<
String
,
List
<
SettlementMenuMealDto
>>>
innerMap
=
outerEntry
.
getValue
();
int
curMenuTotalRow
=
innerMap
.
size
();
// 写入menu列并合并单元格
int
startRowForMenu
=
rowNum
;
for
(
int
i
=
0
;
i
<
curMenuTotalRow
;
i
++)
{
Row
dateRow
=
sheet
.
createRow
(
rowNum
++);
Cell
menuCell
=
dateRow
.
createCell
(
0
);
menuCell
.
setCellValue
(
menuNme
);
}
int
endRowForDate
=
rowNum
-
1
;
if
(
endRowForDate
>
startRowForMenu
)
{
CellRangeAddress
dateRegion
=
new
CellRangeAddress
(
startRowForMenu
,
endRowForDate
,
0
,
0
);
sheet
.
addMergedRegion
(
dateRegion
);
}
rowNum
=
startRowForMenu
;
for
(
Map
.
Entry
<
String
,
Map
<
String
,
List
<
SettlementMenuMealDto
>>>
innerEntry
:
innerMap
.
entrySet
())
{
String
mealName
=
innerEntry
.
getKey
();
Map
<
String
,
List
<
SettlementMenuMealDto
>>
skuMap
=
innerEntry
.
getValue
();
// 写入meal列并合并单元格
Row
mealRow
=
sheet
.
getRow
(
rowNum
++);
Cell
mealCell
=
mealRow
.
createCell
(
1
);
mealCell
.
setCellValue
(
mealName
);
columnNum
=
2
;
Integer
totalPrice
=
0
;
for
(
String
date:
dates
)
{
final
var
toWriteDateSkuList
=
skuMap
.
get
(
date
);
Integer
price
=
0
;
if
(!
toWriteDateSkuList
.
isEmpty
())
{
for
(
SettlementMenuMealDto
settlementMenuMealDto:
toWriteDateSkuList
)
{
price
+=
settlementMenuMealDto
.
getPrice
()
*
settlementMenuMealDto
.
getCount
();
totalPrice
+=
price
;
}
}
Cell
priceCell
=
mealRow
.
createCell
(
columnNum
++);
priceCell
.
setCellValue
((
double
)
price
/
100
);
}
Cell
totalPriceCell
=
mealRow
.
createCell
(
columnNum
);
totalPriceCell
.
setCellValue
((
double
)
totalPrice
/
100
);
}
}
// 自动调整列宽
for
(
int
i
=
0
;
i
<
7
;
i
++)
{
sheet
.
autoSizeColumn
(
i
);
}
// 将工作簿内容写入字节数组输出流
ByteArrayOutputStream
outputStream
=
new
ByteArrayOutputStream
();
workbook
.
write
(
outputStream
);
workbook
.
close
();
return
outputStream
;
}
public
static
List
<
String
>
getDatesBetween
(
LocalDateTime
startTime
,
LocalDateTime
endTime
)
{
List
<
String
>
dateList
=
new
ArrayList
<>();
LocalDate
startDate
=
startTime
.
toLocalDate
();
LocalDate
endDate
=
endTime
.
toLocalDate
();
long
daysBetween
=
ChronoUnit
.
DAYS
.
between
(
startDate
,
endDate
)
+
1
;
for
(
int
i
=
0
;
i
<
daysBetween
;
i
++)
{
LocalDate
currentDate
=
startDate
.
plusDays
(
i
);
dateList
.
add
(
DateUtil
.
formatDate
(
currentDate
,
DateUtil
.
YYYY_MM_DD
));
}
return
dateList
;
}
}
...
...
Please
register
or
login
to post a comment