补齐京东钱包每日账单同步并增加覆盖校验
This commit is contained in:
parent
81bf2bd779
commit
144937bfa3
172
app/Console/Commands/VerifyErpDailyBillCoverage.php
Normal file
172
app/Console/Commands/VerifyErpDailyBillCoverage.php
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class VerifyErpDailyBillCoverage extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'business-mirror:verify-erp-daily-coverage
|
||||||
|
{--from=2026-07-01 : 起始日期 YYYY-MM-DD}
|
||||||
|
{--to= : 截止日期 YYYY-MM-DD,默认昨日}
|
||||||
|
{--json : 输出 JSON}';
|
||||||
|
|
||||||
|
protected $description = '核对京东日账单、京东钱包、头条放心购的月份与截止日覆盖是否完整';
|
||||||
|
|
||||||
|
private const TARGETS = [
|
||||||
|
'jd-daily' => [
|
||||||
|
'label' => '京东日账单',
|
||||||
|
'periods' => 'jd_daily_bill_periods',
|
||||||
|
'rows' => 'jd_daily_bill_rows',
|
||||||
|
],
|
||||||
|
'jd-wallet' => [
|
||||||
|
'label' => '京东钱包',
|
||||||
|
'periods' => 'jd_wallet_bill_periods',
|
||||||
|
'rows' => 'jd_wallet_bill_rows',
|
||||||
|
],
|
||||||
|
'douyin' => [
|
||||||
|
'label' => '头条放心购',
|
||||||
|
'periods' => 'douyin_authoritative_periods',
|
||||||
|
'rows' => 'douyin_authoritative_bills',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
$fromText = (string) $this->option('from');
|
||||||
|
$toText = (string) ($this->option('to') ?: now('Asia/Shanghai')->subDay()->toDateString());
|
||||||
|
$from = $this->date($fromText);
|
||||||
|
$to = $this->date($toText);
|
||||||
|
|
||||||
|
if ($from === null || $to === null || $from->gt($to)) {
|
||||||
|
$this->error('日期范围无效,应为 from <= to,格式 YYYY-MM-DD。');
|
||||||
|
return self::FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = DB::connection(config('upstream_mirrors.connection', 'business_mirror'));
|
||||||
|
$schema = Schema::connection(config('upstream_mirrors.connection', 'business_mirror'));
|
||||||
|
$results = [];
|
||||||
|
$failed = false;
|
||||||
|
|
||||||
|
foreach (self::TARGETS as $key => $target) {
|
||||||
|
if (! $schema->hasTable($target['periods']) || ! $schema->hasTable($target['rows'])) {
|
||||||
|
$results[] = [
|
||||||
|
'dataset' => $key,
|
||||||
|
'label' => $target['label'],
|
||||||
|
'month' => null,
|
||||||
|
'required_start' => $from->toDateString(),
|
||||||
|
'required_through' => $to->toDateString(),
|
||||||
|
'imported_start' => null,
|
||||||
|
'imported_end' => null,
|
||||||
|
'row_count' => 0,
|
||||||
|
'registered_rows' => null,
|
||||||
|
'income' => null,
|
||||||
|
'expense' => null,
|
||||||
|
'status' => 'missing_table',
|
||||||
|
'issue' => '镜像表不存在',
|
||||||
|
];
|
||||||
|
$failed = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$month = $from->copy()->startOfMonth();
|
||||||
|
while ($month->lte($to)) {
|
||||||
|
$monthEnd = $month->copy()->endOfMonth();
|
||||||
|
$requiredStart = $month->lt($from) ? $from->copy() : $month->copy();
|
||||||
|
$requiredThrough = $monthEnd->gt($to) ? $to->copy() : $monthEnd->copy();
|
||||||
|
$requiredEndExclusive = $requiredThrough->copy()->addDay();
|
||||||
|
$period = $db->table($target['periods'])
|
||||||
|
->where('period_start', $month->toDateString())
|
||||||
|
->first();
|
||||||
|
|
||||||
|
$status = 'ok';
|
||||||
|
$rowCount = 0;
|
||||||
|
$issue = null;
|
||||||
|
$summary = null;
|
||||||
|
|
||||||
|
if ($period === null) {
|
||||||
|
$status = 'missing_month';
|
||||||
|
$issue = '缺少该月份导入记录';
|
||||||
|
} elseif (Carbon::parse((string) $period->period_end)->lt($requiredEndExclusive)) {
|
||||||
|
$status = 'partial';
|
||||||
|
$issue = '导入截止日早于要求日期';
|
||||||
|
} else {
|
||||||
|
$summary = $db->table($target['rows'])
|
||||||
|
->where('generation', $period->active_generation)
|
||||||
|
->selectRaw('COUNT(*) AS rows_count, COALESCE(SUM(income), 0) AS income, COALESCE(SUM(expense), 0) AS expense')
|
||||||
|
->first();
|
||||||
|
$rowCount = (int) ($summary->rows_count ?? 0);
|
||||||
|
if ($rowCount === 0) {
|
||||||
|
$status = 'empty';
|
||||||
|
$issue = '有效版本没有明细';
|
||||||
|
} elseif ($rowCount !== (int) $period->row_count) {
|
||||||
|
$status = 'row_count_mismatch';
|
||||||
|
$issue = '有效版本实际行数与期间登记不一致';
|
||||||
|
} elseif (abs(round((float) $summary->income, 2) - (float) $period->income) > 0.005
|
||||||
|
|| abs(round((float) $summary->expense, 2) - (float) $period->expense) > 0.005) {
|
||||||
|
$status = 'amount_mismatch';
|
||||||
|
$issue = '有效版本收支合计与期间登记不一致';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($status !== 'ok') {
|
||||||
|
$failed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$results[] = [
|
||||||
|
'dataset' => $key,
|
||||||
|
'label' => $target['label'],
|
||||||
|
'month' => $month->format('Y-m'),
|
||||||
|
'required_start' => $requiredStart->toDateString(),
|
||||||
|
'required_through' => $requiredThrough->toDateString(),
|
||||||
|
'imported_start' => $period?->period_start,
|
||||||
|
'imported_end' => $period?->period_end,
|
||||||
|
'row_count' => $rowCount,
|
||||||
|
'registered_rows' => $period === null ? null : (int) $period->row_count,
|
||||||
|
'income' => isset($summary) ? round((float) $summary->income, 2) : null,
|
||||||
|
'expense' => isset($summary) ? round((float) $summary->expense, 2) : null,
|
||||||
|
'status' => $status,
|
||||||
|
'issue' => $issue,
|
||||||
|
];
|
||||||
|
|
||||||
|
unset($summary);
|
||||||
|
$month->addMonthNoOverflow()->startOfMonth();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->option('json')) {
|
||||||
|
$this->line(json_encode($results, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||||
|
} else {
|
||||||
|
$this->table(
|
||||||
|
['数据集', '月份', '要求覆盖', '导入覆盖', '实际行数', '登记行数', '收入', '支出', '状态', '说明'],
|
||||||
|
array_map(static fn (array $row): array => [
|
||||||
|
$row['label'],
|
||||||
|
$row['month'] ?? '—',
|
||||||
|
($row['required_start'] ?? '—') . ' ~ ' . ($row['required_through'] ?? '—'),
|
||||||
|
($row['imported_start'] ?? '—') . ' ~ ' . ($row['imported_end'] ?? '—'),
|
||||||
|
number_format((int) $row['row_count']),
|
||||||
|
$row['registered_rows'] === null ? '—' : number_format((int) $row['registered_rows']),
|
||||||
|
$row['income'] === null ? '—' : number_format((float) $row['income'], 2),
|
||||||
|
$row['expense'] === null ? '—' : number_format((float) $row['expense'], 2),
|
||||||
|
$row['status'],
|
||||||
|
$row['issue'] ?? '',
|
||||||
|
], $results),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $failed ? self::FAILURE : self::SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function date(string $value): ?Carbon
|
||||||
|
{
|
||||||
|
if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $value) !== 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$date = Carbon::createFromFormat('!Y-m-d', $value, 'Asia/Shanghai');
|
||||||
|
return $date !== false && $date->format('Y-m-d') === $value ? $date : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -8,16 +8,20 @@
|
|||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| `toutiao` | 头条放心购 → 资金流水 | `business-mirror:import-douyin-authoritative` | 账单流水数据 › 店铺收款账户账单 › **抖音账户** |
|
| `toutiao` | 头条放心购 → 资金流水 | `business-mirror:import-douyin-authoritative` | 账单流水数据 › 店铺收款账户账单 › **抖音账户** |
|
||||||
| `jd` | 京东商城 → 京东日账单 | `business-mirror:import-jd-daily` | **京东账单 + 京喜账单**(一次导入按店铺名拆两边,两边合计恒等于导出行数) |
|
| `jd` | 京东商城 → 京东日账单 | `business-mirror:import-jd-daily` | **京东账单 + 京喜账单**(一次导入按店铺名拆两边,两边合计恒等于导出行数) |
|
||||||
|
| `jd-wallet` | 京东商城 → 京东钱包 | `business-mirror:import-jd-wallet` | **京东网银钱包账户** |
|
||||||
|
|
||||||
## 用法
|
## 用法
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
# 两个平台都跑:区间「月初 → 昨日」
|
# 三个平台都跑:区间「月初 → 昨日」
|
||||||
pwsh -File scripts\erp-daily-bills\run-erp-daily.ps1
|
pwsh -File scripts\erp-daily-bills\run-erp-daily.ps1
|
||||||
|
|
||||||
# 只跑京东,补历史月份
|
# 只跑京东,补历史月份
|
||||||
pwsh -File scripts\erp-daily-bills\run-erp-daily.ps1 -Platform jd -Through 2026-07-31
|
pwsh -File scripts\erp-daily-bills\run-erp-daily.ps1 -Platform jd -Through 2026-07-31
|
||||||
|
|
||||||
|
# 只跑京东钱包,补历史月份
|
||||||
|
pwsh -File scripts\erp-daily-bills\run-erp-daily.ps1 -Platform jd-wallet -Through 2026-07-31
|
||||||
|
|
||||||
# 只导出不导入(排查)
|
# 只导出不导入(排查)
|
||||||
pwsh -File scripts\erp-daily-bills\run-erp-daily.ps1 -Platform toutiao -Through 2026-10-05 -SkipImport
|
pwsh -File scripts\erp-daily-bills\run-erp-daily.ps1 -Platform toutiao -Through 2026-10-05 -SkipImport
|
||||||
```
|
```
|
||||||
@ -26,9 +30,19 @@ pwsh -File scripts\erp-daily-bills\run-erp-daily.ps1 -Platform toutiao -Through
|
|||||||
- **无差异跳过**:该平台该月已导入且笔数/收入/支出完全一致时跳过导入(`-ForceImport` 可强制重刷);状态记在 `runtime/private/erp-exports/imported-state.json`。
|
- **无差异跳过**:该平台该月已导入且笔数/收入/支出完全一致时跳过导入(`-ForceImport` 可强制重刷);状态记在 `runtime/private/erp-exports/imported-state.json`。
|
||||||
- 超过胜算同步导出上限(响应 `超出同步导出允许最大数据量`)时,脚本自动轮询「异步导出下载管理」取回本次任务的全部分片,逐片转 CSV 后合并成一份再导入;仍可用 `-Start/-Through` 分段导出。
|
- 超过胜算同步导出上限(响应 `超出同步导出允许最大数据量`)时,脚本自动轮询「异步导出下载管理」取回本次任务的全部分片,逐片转 CSV 后合并成一份再导入;仍可用 `-Start/-Through` 分段导出。
|
||||||
- 导入前用页面笔数(共 N 条)与导出行数核对,不一致就跳过导入(`-ForceImport` 可强制),避免只导入一部分。
|
- 导入前用页面笔数(共 N 条)与导出行数核对,不一致就跳过导入(`-ForceImport` 可强制),避免只导入一部分。
|
||||||
- 稳定性:导出失败自动重试一次(胜算页面偶发日历面板/授权弹窗异常);上传与"导入+回验"失败自动重试 3 次(含重新上传 CSV),用于吸收服务器 SSH 偶发断连。
|
- 稳定性:导出最多重试 3 次(胜算页面偶发日历面板/授权弹窗异常);上传与"导入+回验"失败自动重试 3 次(含重新上传 CSV),用于吸收服务器 SSH 偶发断连。
|
||||||
- 失败即失败:导出/转 CSV/笔数核对/上传/导入回验任一步失败,都会**不写本地状态、不归档**,并在结束时以退出码 1 结束(下次运行会重新导入),不会把失败当成功记入 `imported-state.json`。
|
- 失败即失败:导出/转 CSV/笔数核对/上传/导入回验任一步失败,都会**不写本地状态、不归档**,并在结束时以退出码 1 结束(下次运行会重新导入),不会把失败当成功记入 `imported-state.json`。
|
||||||
|
|
||||||
|
## 覆盖校验
|
||||||
|
|
||||||
|
导入后可核对三个数据集在指定区间内是否逐月覆盖到截止日:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
docker exec -u www-data caiwu_app php artisan business-mirror:verify-erp-daily-coverage --from=2026-07-01 --to=2026-10-19
|
||||||
|
```
|
||||||
|
|
||||||
|
命令会逐个月份检查期间起止范围、有效版本行数和登记行数;缺月、只导到月中或行数不一致都会返回失败。
|
||||||
|
|
||||||
## 组成
|
## 组成
|
||||||
|
|
||||||
| 文件 | 作用 |
|
| 文件 | 作用 |
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
*
|
*
|
||||||
* --platform=toutiao 头条放心购 → 资金流水 (导入 import-douyin-authoritative → 抖音账户)
|
* --platform=toutiao 头条放心购 → 资金流水 (导入 import-douyin-authoritative → 抖音账户)
|
||||||
* --platform=jd 京东商城 → 京东日账单 (导入 import-jd-daily → 京东账单 + 京喜账单,按店铺名拆分)
|
* --platform=jd 京东商城 → 京东日账单 (导入 import-jd-daily → 京东账单 + 京喜账单,按店铺名拆分)
|
||||||
|
* --platform=jd-wallet 京东商城 → 京东钱包 (导入 import-jd-wallet → 京东网银钱包账户)
|
||||||
*
|
*
|
||||||
* 用法:
|
* 用法:
|
||||||
* node export-daily.mjs --platform=toutiao # 本月月初 → 昨日
|
* node export-daily.mjs --platform=toutiao # 本月月初 → 昨日
|
||||||
@ -24,6 +25,7 @@ const BASE = path.dirname(fileURLToPath(import.meta.url));
|
|||||||
const PLATFORMS = {
|
const PLATFORMS = {
|
||||||
toutiao: { label: '头条放心购', subTab: '资金流水', filePrefix: '头条放心购_资金流水', exportMainName: '头条放心购头条资金流水' },
|
toutiao: { label: '头条放心购', subTab: '资金流水', filePrefix: '头条放心购_资金流水', exportMainName: '头条放心购头条资金流水' },
|
||||||
jd: { label: '京东商城', subTab: '京东日账单', filePrefix: '京东日账单', exportMainName: '京东商城京东日账单' },
|
jd: { label: '京东商城', subTab: '京东日账单', filePrefix: '京东日账单', exportMainName: '京东商城京东日账单' },
|
||||||
|
'jd-wallet': { label: '京东商城', subTab: '京东钱包', filePrefix: '京东钱包', exportMainName: '京东商城京东钱包' },
|
||||||
};
|
};
|
||||||
const arg = (name, fallback = null) => {
|
const arg = (name, fallback = null) => {
|
||||||
const hit = process.argv.find((a) => a.startsWith(`--${name}=`));
|
const hit = process.argv.find((a) => a.startsWith(`--${name}=`));
|
||||||
@ -41,7 +43,7 @@ const BILL_URL = 'https://ss.erp321.com/process/platform-bill-new';
|
|||||||
const platformKey = arg('platform', 'toutiao');
|
const platformKey = arg('platform', 'toutiao');
|
||||||
const platform = PLATFORMS[platformKey];
|
const platform = PLATFORMS[platformKey];
|
||||||
if (!platform) {
|
if (!platform) {
|
||||||
throw new Error('未知平台:' + platformKey + '(可选 toutiao / jd)');
|
throw new Error('未知平台:' + platformKey + '(可选 toutiao / jd / jd-wallet)');
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.mkdirSync(OUT_DIR, { recursive: true });
|
fs.mkdirSync(OUT_DIR, { recursive: true });
|
||||||
|
|||||||
@ -1,19 +1,21 @@
|
|||||||
<#
|
<#
|
||||||
聚胜算每日账单 → 财务系统(统一入口)
|
聚胜算每日账单 → 财务系统(统一入口)
|
||||||
|
|
||||||
平台:toutiao = 头条放心购→资金流水(落 抖音账户)
|
平台:toutiao = 头条放心购→资金流水(落 抖音账户)
|
||||||
jd = 京东商城→京东日账单(一次导入按店铺名拆 京东账单 + 京喜账单)
|
jd = 京东商城→京东日账单(一次导入按店铺名拆 京东账单 + 京喜账单)
|
||||||
|
jd-wallet = 京东商城→京东钱包(落 京东网银钱包账户)
|
||||||
|
|
||||||
流程:导出 → xlsx 转 CSV → 与已导入期间比对(无差异则跳过)→ 上传 → 受控导入 → 页面回验 → 归档 → 写日志
|
流程:导出 → xlsx 转 CSV → 与已导入期间比对(无差异则跳过)→ 上传 → 受控导入 → 页面回验 → 归档 → 写日志
|
||||||
|
|
||||||
用法:
|
用法:
|
||||||
pwsh -File run-erp-daily.ps1 # 两个平台,区间「月初 → 昨日」
|
pwsh -File run-erp-daily.ps1 # 三个平台,区间「月初 → 昨日」
|
||||||
pwsh -File run-erp-daily.ps1 -Platform jd -Through 2026-07-31
|
pwsh -File run-erp-daily.ps1 -Platform jd -Through 2026-07-31
|
||||||
|
pwsh -File run-erp-daily.ps1 -Platform jd-wallet -Through 2026-07-31
|
||||||
pwsh -File run-erp-daily.ps1 -Platform toutiao -SkipImport
|
pwsh -File run-erp-daily.ps1 -Platform toutiao -SkipImport
|
||||||
#>
|
#>
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
param(
|
param(
|
||||||
[ValidateSet('toutiao', 'jd', 'both')][string]$Platform = 'both',
|
[ValidateSet('toutiao', 'jd', 'jd-wallet', 'both')][string]$Platform = 'both',
|
||||||
[string]$Through,
|
[string]$Through,
|
||||||
[string]$Start,
|
[string]$Start,
|
||||||
[switch]$SkipImport,
|
[switch]$SkipImport,
|
||||||
@ -45,9 +47,10 @@ function Write-Log {
|
|||||||
$specs = @{
|
$specs = @{
|
||||||
toutiao = @{ label = '头条放心购'; artifact = 'douyin'; importCmd = 'business-mirror:import-douyin-authoritative'; verifyTabs = @('douyin'); split = $false }
|
toutiao = @{ label = '头条放心购'; artifact = 'douyin'; importCmd = 'business-mirror:import-douyin-authoritative'; verifyTabs = @('douyin'); split = $false }
|
||||||
jd = @{ label = '京东日账单'; artifact = 'jd'; importCmd = 'business-mirror:import-jd-daily'; verifyTabs = @('jd-transactions', 'jingxi'); split = $true }
|
jd = @{ label = '京东日账单'; artifact = 'jd'; importCmd = 'business-mirror:import-jd-daily'; verifyTabs = @('jd-transactions', 'jingxi'); split = $true }
|
||||||
|
'jd-wallet' = @{ label = '京东钱包'; artifact = 'jd-wallet'; importCmd = 'business-mirror:import-jd-wallet'; verifyTabs = @('jd-wallet'); split = $false }
|
||||||
}
|
}
|
||||||
|
|
||||||
$targets = if ($Platform -eq 'both') { @('toutiao', 'jd') } else { @($Platform) }
|
$targets = if ($Platform -eq 'both') { @('toutiao', 'jd', 'jd-wallet') } else { @($Platform) }
|
||||||
$state = if (Test-Path -LiteralPath $stateFile) { (Get-Content -LiteralPath $stateFile -Raw | ConvertFrom-Json) } else { New-Object psobject }
|
$state = if (Test-Path -LiteralPath $stateFile) { (Get-Content -LiteralPath $stateFile -Raw | ConvertFrom-Json) } else { New-Object psobject }
|
||||||
|
|
||||||
$auth = Start-CaiwuDeploymentAuth -Server '218.93.190.75' -SshUser 'root'
|
$auth = Start-CaiwuDeploymentAuth -Server '218.93.190.75' -SshUser 'root'
|
||||||
@ -144,7 +147,7 @@ try {
|
|||||||
# 2) 无差异跳过
|
# 2) 无差异跳过
|
||||||
$key = $target + ':' + $month
|
$key = $target + ':' + $month
|
||||||
$prev = $state.$key
|
$prev = $state.$key
|
||||||
$same = $prev -and ([int]$prev.rows -eq $rows) -and ([math]::Abs([double]$prev.income - $income) -lt 0.005) -and ([math]::Abs([double]$prev.expense - $expense) -lt 0.005)
|
$same = $prev -and ([string]$prev.through -eq [string]$summary.through) -and ([int]$prev.rows -eq $rows) -and ([math]::Abs([double]$prev.income - $income) -lt 0.005) -and ([math]::Abs([double]$prev.expense - $expense) -lt 0.005)
|
||||||
if ($same -and -not $ForceImport) {
|
if ($same -and -not $ForceImport) {
|
||||||
Write-Log ('该月已导入且无差异({0} 笔 / {1} / {2}),跳过导入' -f $rows, $income, $expense)
|
Write-Log ('该月已导入且无差异({0} 笔 / {1} / {2}),跳过导入' -f $rows, $income, $expense)
|
||||||
continue
|
continue
|
||||||
@ -170,9 +173,11 @@ require '/var/www/html/vendor/autoload.php';
|
|||||||
`$repo = app(Modules\EcommerceFinance\Repositories\StoreReceivingDouyinBillMirrorRepository::class);
|
`$repo = app(Modules\EcommerceFinance\Repositories\StoreReceivingDouyinBillMirrorRepository::class);
|
||||||
`$tabs = ['__TABS__'];
|
`$tabs = ['__TABS__'];
|
||||||
foreach (`$tabs as `$tab) {
|
foreach (`$tabs as `$tab) {
|
||||||
`$r = `$tab === 'douyin'
|
`$r = match (`$tab) {
|
||||||
? `$repo->paginate(['start' => '__START__', 'end' => '__THROUGH__'], 'occurred_at', 'desc', 1, 1)
|
'douyin' => `$repo->paginate(['start' => '__START__', 'end' => '__THROUGH__'], 'occurred_at', 'desc', 1, 1),
|
||||||
: app(Modules\EcommerceFinance\Repositories\JdDailyBillRepository::class)->paginate(['start' => '__START__', 'end' => '__THROUGH__'], 'occurred_at', 'desc', 1, 1, `$tab);
|
'jd-wallet' => app(Modules\EcommerceFinance\Repositories\StoreReceivingJdWalletBillRepository::class)->paginate(['start' => '__START__', 'end' => '__THROUGH__'], 'occurred_at', 'desc', 1, 1),
|
||||||
|
default => app(Modules\EcommerceFinance\Repositories\JdDailyBillRepository::class)->paginate(['start' => '__START__', 'end' => '__THROUGH__'], 'occurred_at', 'desc', 1, 1, `$tab),
|
||||||
|
};
|
||||||
echo 'PAGE ' . `$tab . ' total=' . `$r['total'] . ' ' . json_encode(`$r['summary'], JSON_UNESCAPED_UNICODE) . PHP_EOL;
|
echo 'PAGE ' . `$tab . ' total=' . `$r['total'] . ' ' . json_encode(`$r['summary'], JSON_UNESCAPED_UNICODE) . PHP_EOL;
|
||||||
}
|
}
|
||||||
PHP
|
PHP
|
||||||
@ -197,12 +202,14 @@ rm -f /tmp/daily_bills.csv $remoteFile
|
|||||||
}
|
}
|
||||||
|
|
||||||
# 4) 记录状态 + 归档
|
# 4) 记录状态 + 归档
|
||||||
$state | Add-Member -NotePropertyName $key -NotePropertyValue ([pscustomobject]@{ rows = $rows; income = $income; expense = $expense; file = $csvFile; at = (Get-Date -Format 'yyyy-MM-dd HH:mm:ss') }) -Force
|
$state | Add-Member -NotePropertyName $key -NotePropertyValue ([pscustomobject]@{ rows = $rows; income = $income; expense = $expense; through = $summary.through; file = $csvFile; at = (Get-Date -Format 'yyyy-MM-dd HH:mm:ss') }) -Force
|
||||||
$state | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath $stateFile -Encoding UTF8
|
$state | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath $stateFile -Encoding UTF8
|
||||||
|
|
||||||
$shareDir = 'Z:\高祝兰\财务系统\9月'
|
$monthNumber = [int]$month.Substring(5, 2)
|
||||||
|
$shareDir = Join-Path 'Z:\高祝兰\财务系统' ('{0}月' -f $monthNumber)
|
||||||
if (Test-Path -LiteralPath 'Z:\高祝兰\财务系统') {
|
if (Test-Path -LiteralPath 'Z:\高祝兰\财务系统') {
|
||||||
try {
|
try {
|
||||||
|
New-Item -ItemType Directory -Path $shareDir -Force | Out-Null
|
||||||
foreach ($f in $rawFiles) {
|
foreach ($f in $rawFiles) {
|
||||||
Copy-Item -LiteralPath $f -Destination (Join-Path $shareDir ([IO.Path]::GetFileName($f))) -Force
|
Copy-Item -LiteralPath $f -Destination (Join-Path $shareDir ([IO.Path]::GetFileName($f))) -Force
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user