/**
* @notes 菜鸟退货入仓费明细核对逻辑(优化版)
* @param
y
e
a
r
M
o
n
t
h
∗
@
r
e
t
u
r
n
b
o
o
l
∗
@
t
h
r
o
w
s
D
a
t
a
N
o
t
F
o
u
n
d
E
x
c
e
p
t
i
o
n
∗
@
t
h
r
o
w
s
D
b
E
x
c
e
p
t
i
o
n
∗
@
t
h
r
o
w
s
M
o
d
e
l
N
o
t
F
o
u
n
d
E
x
c
e
p
t
i
o
n
∗
@
a
u
t
h
o
r
胡军
∗
@
d
a
t
e
2025
/
06
/
26
∗
/
p
u
b
l
i
c
f
u
n
c
t
i
o
n
c
o
m
p
u
t
e
R
e
t
u
r
n
I
t
e
m
V
e
r
i
f
y
D
o
(
yearMonth∗@returnbool∗@throwsDataNotFoundException∗@throwsDbException∗@throwsModelNotFoundException∗@author胡军∗@date2025/06/26∗/publicfunctioncomputeReturnItemVerifyDo( yearMonth): bool {
// 获取指定月份的时间范围(月初到月末)
m
o
n
t
h
T
i
m
e
R
a
n
g
e
=
monthTimeRange= this->getMonthTimeRange(
y
e
a
r
M
o
n
t
h
)
;
/
/
预加载并缓存报价数据,使用键值对存储(仓库名
=
>
报价信息)
/
/
避免在后续循环中重复查询数据库,提高性能
yearMonth);//预加载并缓存报价数据,使用键值对存储(仓库名=>报价信息)//避免在后续循环中重复查询数据库,提高性能 warehouseQuotes = [];
w
a
r
e
h
o
u
s
e
L
i
s
t
=
C
o
m
p
u
t
e
R
e
t
u
r
n
I
t
e
m
i
z
a
t
i
o
n
M
o
d
e
l
:
:
w
h
e
r
e
B
e
t
w
e
e
n
(
′
b
u
s
i
n
e
s
s
t
i
m
e
′
,
[
warehouseList=ComputeReturnItemizationModel::whereBetween(
′
business
t
ime
′
,[ monthTimeRange[‘startTime’],
m
o
n
t
h
T
i
m
e
R
a
n
g
e
[
′
e
n
d
T
i
m
e
′
]
]
)
−
>
g
r
o
u
p
(
′
w
a
r
e
h
o
u
s
e
n
a
m
e
′
)
−
>
c
o
l
u
m
n
(
′
w
a
r
e
h
o
u
s
e
n
a
m
e
′
)
;
/
/
批量获取所有仓库的首件和每增加一件报价记录
(
同一个仓库报价必须是两条并且首件报价在前每增加一件报价在后否则计算错误
)
f
o
r
e
a
c
h
(
monthTimeRange[
′
endTime
′
]])−>group(
′
warehouse
n
ame
′
)−>column(
′
warehouse
n
ame
′
);//批量获取所有仓库的首件和每增加一件报价记录(同一个仓库报价必须是两条并且首件报价在前每增加一件报价在后否则计算错误)foreach( warehouseList as ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: …记录
firstResult = ComputeReturnFeeQuoteModel::where(‘warehouse’,
w
a
r
e
h
o
u
s
e
)
−
>
o
r
d
e
r
(
′
i
d
a
s
c
′
)
−
>
f
i
n
d
(
)
;
warehouse)−>order(
′
idasc
′
)−>find(); firstOrderQuote =
f
i
r
s
t
R
e
s
u
l
t
?
firstResult? firstResult->toArray() : [];
// 获取该仓库的每增加一件报价记录
l
a
s
t
R
e
s
u
l
t
=
C
o
m
p
u
t
e
R
e
t
u
r
n
F
e
e
Q
u
o
t
e
M
o
d
e
l
:
:
w
h
e
r
e
(
′
w
a
r
e
h
o
u
s
e
′
,
lastResult=ComputeReturnFeeQuoteModel::where(
′
warehouse
′
, warehouse)->order(‘id desc’)->find();
l
a
s
t
O
r
d
e
r
Q
u
o
t
e
=
lastOrderQuote= lastResult ?
l
a
s
t
R
e
s
u
l
t
−
>
t
o
A
r
r
a
y
(
)
:
[
]
;
/
/
仅当首件和续件报价都存在时才保存(确保数据完整性)
i
f
(
!
e
m
p
t
y
(
lastResult−>toArray():[];//仅当首件和续件报价都存在时才保存(确保数据完整性)if(!empty( firstOrderQuote) && !empty(ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: … warehouseQuotes[
w
a
r
e
h
o
u
s
e
]
=
[
′
f
i
r
s
t
′
=
>
warehouse]=[
′
first
′
=> firstOrderQuote, // 首件价格信息
‘last’ => ParseError: KaTeX parse error: Expected 'EOF', got '}' at position 61: …];
}̲
}
… status = true; // 处理状态标识
b
a
t
c
h
S
i
z
e
=
500
;
/
/
批次大小即每次读取的数据条数
batchSize=500;//批次大小即每次读取的数据条数 reconnectInterval = 200; // 每10万条重新连接一次数据库(200批次=10万条)
u
p
d
a
t
e
C
o
u
n
t
=
0
;
/
/
记录已更新的总记录数
updateCount=0;//记录已更新的总记录数 batchCount = 0; // 记录当前批次数
try {
// 使用游标分批处理数据,每次只加载少量数据到内存
// 避免一次性加载大量数据导致内存溢出
q
u
e
r
y
=
C
o
m
p
u
t
e
R
e
t
u
r
n
I
t
e
m
i
z
a
t
i
o
n
M
o
d
e
l
:
:
w
h
e
r
e
B
e
t
w
e
e
n
(
′
b
u
s
i
n
e
s
s
t
i
m
e
′
,
[
query=ComputeReturnItemizationModel::whereBetween(
′
business
t
ime
′
,[ monthTimeRange[‘startTime’],
m
o
n
t
h
T
i
m
e
R
a
n
g
e
[
′
e
n
d
T
i
m
e
′
]
]
)
;
monthTimeRange[
′
endTime
′
]]); query->chunk(
b
a
t
c
h
S
i
z
e
,
f
u
n
c
t
i
o
n
(
batchSize,function( items) use (
&ParseError: KaTeX parse error: Expected 'EOF', got '&' at position 51: … &̲ updateCount, // 引用传递更新计数
&
b
a
t
c
h
C
o
u
n
t
,
/
/
引用传递批次计数
batchCount,//引用传递批次计数 warehouseQuotes, // 仓库报价数据
r
e
c
o
n
n
e
c
t
I
n
t
e
r
v
a
l
,
/
/
重连间隔
reconnectInterval,//重连间隔 yearMonth
) {
b
a
t
c
h
C
o
u
n
t
+
+
;
batchCount++; updateBuffer = []; // 批量更新缓冲区,存储待更新的数据
// 遍历当前批次的所有明细记录
foreach (
i
t
e
m
s
a
s
itemsas item) {
w
a
r
e
h
o
u
s
e
N
a
m
e
=
warehouseName= item->warehouse_name;
i
t
e
m
D
a
t
a
=
itemData= item->toArray();
t
h
e
o
r
e
t
i
c
a
l
F
e
e
=
0
;
/
/
检查仓库是否有对应的报价数据
i
f
(
i
s
s
e
t
(
theoreticalFee=0;//检查仓库是否有对应的报价数据if(isset( warehouseQuotes[ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: … quoteData =
w
a
r
e
h
o
u
s
e
Q
u
o
t
e
s
[
warehouseQuotes[ warehouseName];
// 将CN订单SKU总重量(克)转换为千克
b
u
b
b
l
e
V
o
l
u
m
e
K
g
=
bubbleVolumeKg= itemData[‘bubble_volume_1kg’] / 1000;
q
u
a
n
t
i
t
y
=
quantity= itemData[‘total_goods_quantity’];
// 确定价格类型
p
r
i
c
e
T
y
p
e
=
priceType= bubbleVolumeKg <= 0.5 ? ‘tiny’ :
(
b
u
b
b
l
e
V
o
l
u
m
e
K
g
<
=
3
?
′
s
m
a
l
l
′
:
(
bubbleVolumeKg<=3?
′
small
′
:( bubbleVolumeKg <= 5 ? ‘medium’ :
(
b
u
b
b
l
e
V
o
l
u
m
e
K
g
<
=
10
?
′
l
a
r
g
e
′
:
′
t
e
n
′
)
)
)
;
/
/
计算费用
bubbleVolumeKg<=10?
′
large
′
:
′
ten
′
)));//计算费用 theoreticalFee += ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: …irst']["price_{ priceType}"];
if (ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: … theoreticalFee += (
q
u
a
n
t
i
t
y
−
1
)
∗
quantity−1)∗ quoteData[‘last’]["price_{ParseError: KaTeX parse error: Expected 'EOF', got '}' at position 11: priceType}̲"];
… yearMonth .
“的订单明细核对匹配不到退货入仓费报价表la_compute_return_fee_quote当中的仓库名称,明细数据id为” .
i
t
e
m
D
a
t
a
[
′
i
d
′
]
)
;
/
/
未匹配时设置为
n
u
l
l
以便标识
itemData[
′
id
′
]);//未匹配时设置为null以便标识 theoreticalFee = null;
}
// 准备更新数据,存入缓冲区
u
p
d
a
t
e
B
u
f
f
e
r
[
updateBuffer[ itemData[‘id’]] = [
‘theoretical_fee’ =>
t
h
e
o
r
e
t
i
c
a
l
F
e
e
,
/
/
理论费
用
′
f
e
e
d
i
f
f
e
r
e
n
c
e
′
=
>
theoreticalFee,//理论费用
′
fee
d
ifference
′
=> itemData[‘billing_amount’] - (ParseError: KaTeX parse error: Expected 'EOF', got '}' at position 71: … }̲
… this->batchUpdate(‘la_compute_return_fee’,
u
p
d
a
t
e
B
u
f
f
e
r
,
[
′
t
h
e
o
r
e
t
i
c
a
l
f
e
e
′
,
′
f
e
e
d
i
f
f
e
r
e
n
c
e
′
]
)
;
updateBuffer,[
′
theoretical
f
ee
′
,
′
fee
d
ifference
′
]); updateCount += count(
u
p
d
a
t
e
B
u
f
f
e
r
)
;
/
/
更新总计数
/
/
定期重连数据库,避免长时间运行导致连接断开
i
f
(
updateBuffer);//更新总计数//定期重连数据库,避免长时间运行导致连接断开if( batchCount % ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: … this->reconnectDatabase();
Log::info(“菜鸟退货入仓费用核对已处理 {ParseError: KaTeX parse error: Expected 'EOF', got '}' at position 13: updateCount}̲ 条,进行数据库重连");
… items, ParseError: KaTeX parse error: Expected 'EOF', got '}' at position 29: …);
}̲);
} ca… e) {
// 记录异常信息,确保错误可追溯(保留原始注释逻辑)
Log::error(‘【菜鸟退货入仓费明细核对异常】–月份为:’ .
y
e
a
r
M
o
n
t
h
.
"
的费用核对发生错误
:
"
.
yearMonth."的费用核对发生错误:". e->getMessage());
ParseError: KaTeX parse error: Expected 'EOF', got '}' at position 37: …标记处理失败
}̲
// 记录处… updateCount} 条记录”);
return $ status;
}
/** * 高效批量更新方法(单SQL更新多条) * @param string $ table 表名 * @param array $ data 更新数据,格式:[id => ['field1' => 'value1', 'field2' => 'value2']] * @param array $ fields 需要更新的字段 */ private function batchUpdate(string $ table, array $ data, array $ fields) { // 数据为空时直接返回,避免无效操作 if (empty($ data) || empty($ fields)) return; $ cases = []; // 存储CASE WHEN语句的数组 $ ids = []; // 存储所有需要更新的ID $ params = []; // 存储预处理语句的参数 // 构建CASE WHEN更新语句(每个字段一个CASE WHEN) foreach ($ fields as $ field) { $ cases[$ field] = 'CASE id '; // 为每个ID和对应字段值构建WHEN子句 foreach ($ data as $ id => $ row) { $ cases[$ field] .= "WHEN {$ id} THEN ? "; // 占位符用于预处理语句 $ params[] = $ row[$ field]; // 对应的值 $ ids[] = $ id; // 记录ID } $ cases[$ field] .= 'END'; // 结束CASE语句 } // 去重并拼接ID列表 $ idsStr = implode(',', array_unique($ ids)); // 构建SET子句(每个字段的CASE WHEN语句) $ setClauses = []; foreach ($ fields as $ field) { $ setClauses[] = "{$ field} = {$ cases[$ field]}"; } // 构建完整的UPDATE SQL语句(保留SQL案例注释) /* 最后的执行sql可以视为(案例sql): UPDATE la_reverse_delivery_fee SET theoretical_amount = CASE id WHEN 1001 THEN 100 -- 当ID=1001时,更新为100 WHEN 1002 THEN 200 -- 当ID=1002时,更新为200 END, fee_difference = CASE id WHEN 1001 THEN 5 -- 当ID=1001时,更新为5 WHEN 1002 THEN 10 -- 当ID=1002时,更新为10 END WHERE id IN (1001,1002); 其实就是巧妙地利用了 SQL 的CASE WHEN语法,将多行更新合并为单条 SQL,是一种常见的数据库优化技巧! */ $ sql = "UPDATE {$ table} SET " . implode(', ', $ setClauses) . " WHERE id IN ({$ idsStr})"; // 执行预处理语句,提高安全性和性能 Db::execute($ sql, $ params); } // 数据库重连方法,用于长时间运行的任务,避免连接超时 private function reconnectDatabase() { try { $ connection = \think\facade\Db::connect(); $ connection->close(); // 关闭当前连接 $ connection->connect(); // 重新建立连接 } catch (\Exception $ e) { // 记录重连失败日志,但不中断程序执行 Log::error('【菜鸟退货入仓费用核对数据库重连失败】' . $ e->getMessage()); } }
/**
* @notes 根据年月比如2025-05获取当月时间范围 精确到秒
* @param string
y
e
a
r
M
o
n
t
h
∗
@
r
e
t
u
r
n
a
r
r
a
y
∗
@
a
u
t
h
o
r
胡军
∗
@
d
a
t
e
2025
/
06
/
23
∗
/
p
r
i
v
a
t
e
f
u
n
c
t
i
o
n
g
e
t
M
o
n
t
h
T
i
m
e
R
a
n
g
e
(
s
t
r
i
n
g
yearMonth∗@returnarray∗@author胡军∗@date2025/06/23∗/privatefunctiongetMonthTimeRange(string yearMonth): array
{
// 验证输入格式 (YYYY-MM)
if (!preg_match(‘/^\d{4}-(0[1-9]|1[0-2])
/
′
,
/
′
, yearMonth)) {
throw new InvalidArgumentException(‘输入格式不正确,必须为YYYY-MM格式’);
}
list(
y
e
a
r
,
year, month) = explode(’-',
y
e
a
r
M
o
n
t
h
)
;
/
/
构建开始时间
yearMonth);//构建开始时间 startTime = “{ParseError: KaTeX parse error: Expected 'EOF', got '}' at position 6: year}̲-{ month}-01 00:00:00”;
// 使用DateTime类计算当月最后一天
ParseError: KaTeX parse error: Undefined control sequence: \DateTime at position 17: …lastDay = (new \̲D̲a̲t̲e̲T̲i̲m̲e̲("{ year}-{ParseError: KaTeX parse error: Expected 'EOF', got '}' at position 7: month}̲-01"))
… endTime = "{ParseError: KaTeX parse error: Expected 'EOF', got '}' at position 6: year}̲-{ month}-{ParseError: KaTeX parse error: Expected 'EOF', got '}' at position 9: lastDay}̲ 23:59:59";
… startTime,
‘endTime’ => $ endTime
];
}
这是我之前的业务模块处理100万数据核对的代码,也是您给出的方案,那么我上次提问的代码:
/**
* @notes 京东仓储服务费核对逻辑
* @param
y
e
a
r
M
o
n
t
h
∗
@
r
e
t
u
r
n
b
o
o
l
∗
@
t
h
r
o
w
s
D
a
t
a
N
o
t
F
o
u
n
d
E
x
c
e
p
t
i
o
n
∗
@
t
h
r
o
w
s
D
b
E
x
c
e
p
t
i
o
n
∗
@
t
h
r
o
w
s
M
o
d
e
l
N
o
t
F
o
u
n
d
E
x
c
e
p
t
i
o
n
∗
@
a
u
t
h
o
r
胡军
∗
@
d
a
t
e
2025
/
06
/
27
∗
/
p
u
b
l
i
c
f
u
n
c
t
i
o
n
w
a
r
e
H
o
u
s
i
n
g
F
e
e
V
e
r
i
f
y
D
o
(
yearMonth∗@returnbool∗@throwsDataNotFoundException∗@throwsDbException∗@throwsModelNotFoundException∗@author胡军∗@date2025/06/27∗/publicfunctionwareHousingFeeVerifyDo( yearMonth):bool{
m
o
n
t
h
T
i
m
e
R
a
n
g
e
=
monthTimeRange= this->getMonthTimeRange(
y
e
a
r
M
o
n
t
h
)
;
/
/
获取时间范围内的数据并进行分组统计
/
/
t
o
t
a
l
q
u
a
n
t
i
t
y
总数
/
/
t
o
t
a
l
s
e
t
t
l
e
m
e
n
t
a
m
o
u
n
t
总的结算金额
yearMonth);//获取时间范围内的数据并进行分组统计//total
q
uantity总数//total
s
ettlement
a
mount总的结算金额 itemizationMonthList = WareHousingFeesItemizationModel::whereBetween(‘business_time’, [
m
o
n
t
h
T
i
m
e
R
a
n
g
e
[
′
s
t
a
r
t
T
i
m
e
′
]
,
monthTimeRange[
′
startTime
′
], monthTimeRange[‘endTime’]])
->field([
‘document_number’,
‘document_type’,
‘SUM(quantity) as total_quantity’,
‘SUM(settlement_amount) as total_settlement_amount’
])
->group(‘document_number, document_type’)
->select()
->toArray();
//一次性读取报价单避免foreach循环 提升效率
q
u
o
t
e
L
i
s
t
=
W
a
r
e
H
o
u
s
i
n
g
F
e
e
s
Q
u
o
t
e
M
o
d
e
l
:
:
s
e
l
e
c
t
(
)
−
>
t
o
A
r
r
a
y
(
)
;
quoteList=WareHousingFeesQuoteModel::select()−>toArray(); quoteListRst = [];
foreach (
q
u
o
t
e
L
i
s
t
a
s
quoteListas item) {
q
u
o
t
e
L
i
s
t
R
s
t
[
quoteListRst[ item[‘service_type’]] = ParseError: KaTeX parse error: Expected 'EOF', got '}' at position 16: item;
}̲
if(!em… quoteListRst)){
foreach(
i
t
e
m
i
z
a
t
i
o
n
M
o
n
t
h
L
i
s
t
a
s
itemizationMonthListas key => ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: … itemizationMonthList[
k
e
y
]
[
′
t
h
e
o
r
e
t
i
c
a
l
a
m
o
u
n
t
′
]
=
0
;
i
f
(
key][
′
theoretical
a
mount
′
]=0;if( value[‘document_type’] == ‘出库单’ && !empty(ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: … // value[‘total_quantity’] 数量
if(ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: … itemizationMonthList[
k
e
y
]
[
′
t
h
e
o
r
e
t
i
c
a
l
a
m
o
u
n
t
′
]
=
key][
′
theoretical
a
mount
′
]= quoteListRst[‘出库单’][‘first_three_items’];
} else {
i
t
e
m
i
z
a
t
i
o
n
M
o
n
t
h
L
i
s
t
[
itemizationMonthList[ key][‘theoretical_amount’] =
q
u
o
t
e
L
i
s
t
R
s
t
[
′
出库
单
′
]
[
′
f
i
r
s
t
t
h
r
e
e
i
t
e
m
s
′
]
+
(
quoteListRst[
′
出库单
′
][
′
first
t
hree
i
tems
′
]+( value[‘total_quantity’] - 3) * ParseError: KaTeX parse error: Expected 'EOF', got '}' at position 63: … }̲
… value[‘document_type’] == ‘退供单’ && !empty(ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: … itemizationMonthList[
k
e
y
]
[
′
t
h
e
o
r
e
t
i
c
a
l
a
m
o
u
n
t
′
]
=
key][
′
theoretical
a
mount
′
]= quoteListRst[‘退供单’][‘first_three_items’] * ParseError: KaTeX parse error: Expected 'EOF', got '}' at position 43: … }̲
… value[‘document_type’] == ‘退货单’ && !empty(ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: … if( value[‘total_quantity’] <= 3){
i
t
e
m
i
z
a
t
i
o
n
M
o
n
t
h
L
i
s
t
[
itemizationMonthList[ key][‘theoretical_amount’] = ParseError: KaTeX parse error: Expected 'EOF', got '}' at position 64: … }̲ else {
… itemizationMonthList[
k
e
y
]
[
′
t
h
e
o
r
e
t
i
c
a
l
a
m
o
u
n
t
′
]
=
key][
′
theoretical
a
mount
′
]= quoteListRst[‘退货单’][‘first_three_items’] + (
v
a
l
u
e
[
′
t
o
t
a
l
q
u
a
n
t
i
t
y
′
]
−
3
)
∗
value[
′
total
q
uantity
′
]−3)∗ quoteListRst[‘退货单’][‘additional_items’];
}
}
//正常计算出来的理论金额不应该是0 那么这个时候就要记录日志便于排查
if(
i
t
e
m
i
z
a
t
i
o
n
M
o
n
t
h
L
i
s
t
[
itemizationMonthList[ key][‘theoretical_amount’] == 0){
//echo
v
a
l
u
e
[
′
d
o
c
u
m
e
n
t
n
u
m
b
e
r
′
]
.
P
H
P
E
O
L
;
L
o
g
:
:
w
a
r
n
i
n
g
(
′
【京东仓储服务费明细核对】
−
−
月份为
:
′
.
value[
′
document
n
umber
′
].PHP
E
OL;Log::warning(
′
【京东仓储服务费明细核对】−−月份为:
′
. yearMonth.“的京东仓储服务费订单明细核对匹配不到京东仓储服务费报价表la_storage_service_quotes当中的类型,明细单据编号为”.
v
a
l
u
e
[
′
d
o
c
u
m
e
n
t
n
u
m
b
e
r
′
]
)
;
u
n
s
e
t
(
value[
′
document
n
umber
′
]);unset( itemizationMonthList[ParseError: KaTeX parse error: Expected 'EOF', got '}' at position 55: … }̲else{
… itemizationMonthList[
k
e
y
]
[
′
b
a
l
a
n
c
e
′
]
=
key][
′
balance
′
]= value[‘total_settlement_amount’] -
i
t
e
m
i
z
a
t
i
o
n
M
o
n
t
h
L
i
s
t
[
itemizationMonthList[ key][‘theoretical_amount’];
}
}
//批量分批次更新数据库
s
t
a
t
u
s
=
t
r
u
e
;
status=true; batchSize = 50; // 每批10条记录
t
o
t
a
l
C
o
u
n
t
=
c
o
u
n
t
(
totalCount=count( itemizationMonthList);
b
a
t
c
h
C
o
u
n
t
=
c
e
i
l
(
batchCount=ceil( totalCount /
b
a
t
c
h
S
i
z
e
)
;
batchSize); itemizationModel = new WareHousingFeesItemVeryModel();
for (
i
=
0
;
i=0; i <
b
a
t
c
h
C
o
u
n
t
;
batchCount; i++) {
b
a
t
c
h
D
a
t
a
=
a
r
r
a
y
s
l
i
c
e
(
batchData=array
s
lice( itemizationMonthList,
i
∗
i∗ batchSize,
b
a
t
c
h
S
i
z
e
)
;
batchSize); documentNumbers = array_column(ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: … itemizationModel->startTrans();
// 批量删除操作(根据单据号)
if (!empty(ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: … itemizationModel->whereIn(‘document_number’, ParseError: KaTeX parse error: Expected 'EOF', got '}' at position 50: … }̲
… itemizationModel->saveAll(
b
a
t
c
h
D
a
t
a
)
;
batchData); itemizationModel->commit();
} catch (\Exception ParseError: KaTeX parse error: Expected '}', got 'EOF' at end of input: … itemizationModel->rollback();
//记录日志
Log::error(‘【京东仓储服务费明细核对异常】–月份为:’.
y
e
a
r
M
o
n
t
h
.
"
的费用核对发生错误
:
"
.
yearMonth."的费用核对发生错误:". e->getMessage());
//其中一个批次数据处理失败则直接退出循环 不再继续执行后续批次的数据处理 报错给前端显示
ParseError: KaTeX parse error: Expected 'EOF', got '}' at position 61: … }̲
}
… status;
}else{
return false;
}
}
/** * @notes 根据年月比如2025-05获取当月时间范围 精确到秒 (git有问题未解决 暂时无法写入common.php当中 临时放这) * @param string $ yearMonth * @return array * @author 胡军 * @date 2025/06/27 */ private function getMonthTimeRange(string $ yearMonth): array { // 验证输入格式 (YYYY-MM) if (!preg_match('/^\d{4}-(0[1-9]|1[0-2])$/', $ yearMonth)) { throw new InvalidArgumentException('输入格式不正确,必须为YYYY-MM格式'); } list($ year, $ month) = explode('-', $ yearMonth); // 构建开始时间 $ startTime = "{$ year}-{$ month}-01 00:00:00"; // 使用DateTime类计算当月最后一天 $ lastDay = (new \DateTime("{$ year}-{$ month}-01")) ->modify('last day of this month') ->format('d'); // 构建结束时间 $ endTime = "{$ year}-{$ month}-{$ lastDay} 23:59:59"; return [ 'startTime' => $ startTime, 'endTime' => $ endTime ]; }
是不是也可以按照这种优化思路去改造呢?
最新发布