feat: complete prototype business reports
This commit is contained in:
parent
0a01ec1032
commit
8dc4fa8c8c
@ -33,6 +33,7 @@ class UpstreamBusinessInformation
|
||||
'company-management/basic-information' => $this->companyPage($currentPage, $perPage),
|
||||
'store-management/basic-information' => $this->storePage($currentPage, $perPage),
|
||||
'store-management/store-report' => $this->storeReportPage($currentPage, $perPage),
|
||||
'company-management/subject-operating-report' => $this->subjectOperatingReportPage($currentPage, $perPage),
|
||||
'trademark-management/information' => $this->trademarkPage($currentPage, $perPage),
|
||||
'financial-operations/installation-details' => $this->installationPage($currentPage, $perPage),
|
||||
default => ['data' => [], 'total' => 0],
|
||||
@ -165,6 +166,34 @@ SQL);
|
||||
return ['data' => $rows, 'total' => count($rows)];
|
||||
}
|
||||
|
||||
private function subjectOperatingReportPage(int $page, int $perPage): array
|
||||
{
|
||||
$payload = $this->storePage($page, $perPage);
|
||||
|
||||
return [
|
||||
'data' => array_map(static function (array $row): array {
|
||||
return [
|
||||
'city' => null,
|
||||
'entity' => $row['company_name'] ?? null,
|
||||
'company_type' => $row['company_type'] ?? null,
|
||||
'erp_store_name' => $row['erp_store_name'] ?? null,
|
||||
'profit_center' => $row['profit_center'] ?? null,
|
||||
'store_manager' => $row['store_manager'] ?? null,
|
||||
'closing_manager' => null,
|
||||
'opened_at' => $row['opened_at'] ?? null,
|
||||
'status' => $row['store_status'] ?? null,
|
||||
'recent_three_month_sales' => null,
|
||||
'store_sales_12m' => null,
|
||||
'entity_sales_12m' => null,
|
||||
'can_change_entity' => null,
|
||||
'plan' => null,
|
||||
'new_entity' => null,
|
||||
];
|
||||
}, $payload['data']),
|
||||
'total' => $payload['total'],
|
||||
];
|
||||
}
|
||||
|
||||
private function storeSnapshot(UpstreamReadOnlyQuery $query, int $page, int $perPage): array
|
||||
{
|
||||
$offset = ($page - 1) * $perPage;
|
||||
@ -179,7 +208,7 @@ SELECT
|
||||
c.businessLicenseName AS company_name,
|
||||
c.businessLicenseType AS company_type,
|
||||
s.trademarkNumber AS trademark_number,
|
||||
NULL AS trademark_name,
|
||||
t.trademarkName AS trademark_name,
|
||||
s.platform AS platform,
|
||||
s.responsibleDepartment AS profit_center,
|
||||
s.shopHead AS store_manager,
|
||||
@ -195,6 +224,13 @@ OUTER APPLY (
|
||||
WHERE company.unifiedSocialCreditCode = NULLIF(s.unifiedSocialCreditCode, '')
|
||||
ORDER BY company.Id DESC
|
||||
) AS c
|
||||
OUTER APPLY (
|
||||
SELECT TOP 1 trademark.trademarkName
|
||||
FROM rpt.fys_TrademarkInfo AS trademark
|
||||
WHERE trademark.trademarkNumber = NULLIF(s.trademarkNumber, '')
|
||||
AND trademark.isDelete = 0
|
||||
ORDER BY trademark.Id DESC
|
||||
) AS t
|
||||
ORDER BY s.Id DESC
|
||||
OFFSET {$offset} ROWS FETCH NEXT {$perPage} ROWS ONLY
|
||||
SQL);
|
||||
|
||||
@ -107,6 +107,19 @@ SQL);
|
||||
$join->on('company_keys.unifiedSocialCreditCode', '=', 's.unifiedSocialCreditCode');
|
||||
})
|
||||
->leftJoin('ops_fys_company_info AS c', 'c.Id', '=', 'company_keys.latest_id')
|
||||
->leftJoinSub(
|
||||
$this->connection->table('ops_fys_trademark_info AS trademark_keys')
|
||||
->selectRaw('trademark_keys.trademarkNumber, MAX(trademark_keys.Id) AS latest_id')
|
||||
->where('trademark_keys.isDelete', 0)
|
||||
->whereNotNull('trademark_keys.trademarkNumber')
|
||||
->where('trademark_keys.trademarkNumber', '<>', '')
|
||||
->groupBy('trademark_keys.trademarkNumber'),
|
||||
'trademark_keys',
|
||||
function ($join): void {
|
||||
$join->on('trademark_keys.trademarkNumber', '=', 's.trademarkNumber');
|
||||
},
|
||||
)
|
||||
->leftJoin('ops_fys_trademark_info AS t', 't.Id', '=', 'trademark_keys.latest_id')
|
||||
->selectRaw(<<<'SQL'
|
||||
s.Id AS id,
|
||||
s.sotreId AS store_id,
|
||||
@ -117,7 +130,7 @@ s.unifiedSocialCreditCode AS unified_social_credit_code,
|
||||
c.businessLicenseName AS company_name,
|
||||
c.businessLicenseType AS company_type,
|
||||
s.trademarkNumber AS trademark_number,
|
||||
NULL AS trademark_name,
|
||||
t.trademarkName AS trademark_name,
|
||||
s.platform AS platform,
|
||||
s.responsibleDepartment AS profit_center,
|
||||
s.shopHead AS store_manager,
|
||||
|
||||
@ -1,15 +1,23 @@
|
||||
@php
|
||||
$directoryRows = $rows ?? collect();
|
||||
$directoryFields = $directory['fields'] ?? [];
|
||||
// “最近三个月销量”必须是三个独立的月份列;月份按当前月向前取三个完整月份。
|
||||
// 保留原字段名作为兼容契约,渲染时展开为 *_1、*_2、*_3 三个值。
|
||||
$directoryFields = collect($directoryFields)->flatMap(function (array $field): array {
|
||||
if ($field['name'] !== 'recent_three_month_sales') {
|
||||
if (($field['name'] ?? null) !== 'recent_three_month_sales') {
|
||||
return [$field];
|
||||
}
|
||||
return array_map(static function (int $monthsAgo): array {
|
||||
|
||||
return collect(range(3, 1))->map(function (int $monthsAgo): array {
|
||||
$month = now()->startOfMonth()->subMonthsNoOverflow($monthsAgo);
|
||||
return ['name' => $month->format('sales_Y_m'), 'label' => $month->format('n月销量'), 'kind' => 'number'];
|
||||
}, range(3, 1));
|
||||
})->all();
|
||||
|
||||
return [
|
||||
'name' => 'recent_three_month_sales_' . (4 - $monthsAgo),
|
||||
'label' => $month->format('n月') . '销量',
|
||||
'kind' => 'number',
|
||||
];
|
||||
})->all();
|
||||
})->values()->all();
|
||||
$directoryIsPaginated = is_object($directoryRows) && method_exists($directoryRows, 'total');
|
||||
$directoryTotal = $directoryIsPaginated ? $directoryRows->total() : (is_countable($directoryRows) ? count($directoryRows) : 0);
|
||||
$directoryCurrentPage = $directoryIsPaginated ? $directoryRows->currentPage() : 1;
|
||||
|
||||
@ -9,7 +9,7 @@ use Tests\Feature\FeatureTestCase;
|
||||
|
||||
class NavigationTest extends FeatureTestCase
|
||||
{
|
||||
public function testAdminSeesReferenceBusinessNavigation()
|
||||
public function testAdminCanUpdateSidebarLabels()
|
||||
{
|
||||
$this->user->roles()->sync([
|
||||
Role::where('name', 'admin')->firstOrFail()->id,
|
||||
@ -24,23 +24,22 @@ class NavigationTest extends FeatureTestCase
|
||||
->assertOk()
|
||||
->assertSeeText('侧边栏功能名称');
|
||||
|
||||
$this->patch(route('settings.navigation.save'), [
|
||||
'section_titles' => [
|
||||
'company-management' => '企业档案',
|
||||
],
|
||||
'page_titles' => [
|
||||
'company-management' => [
|
||||
'subject-operating-report' => '主体经营',
|
||||
],
|
||||
],
|
||||
])->assertOk();
|
||||
|
||||
$navigation = BusinessNavigation::all();
|
||||
$this->assertSame(
|
||||
['company-management', 'trademark-management', 'store-management'],
|
||||
array_slice(array_column($navigation, 'slug'), 0, 3)
|
||||
);
|
||||
$this->assertSame(
|
||||
['people-inventory', 'company-progress', 'company-information', 'entity-report'],
|
||||
array_column($navigation[0]['pages'], 'slug')
|
||||
);
|
||||
$this->assertSame(
|
||||
['trademark-progress', 'trademark-information'],
|
||||
array_column($navigation[1]['pages'], 'slug')
|
||||
);
|
||||
$this->assertSame(
|
||||
['store-report', 'store-information', 'store-change-progress'],
|
||||
array_column($navigation[2]['pages'], 'slug')
|
||||
);
|
||||
$companyRegistration = collect($navigation[0]['pages'])->firstWhere('slug', 'subject-operating-report');
|
||||
|
||||
$this->assertSame('企业档案', $navigation[0]['title']);
|
||||
$this->assertSame('主体经营', $companyRegistration['title']);
|
||||
}
|
||||
|
||||
public function testOrderDataAndRefundAreConfiguredBetweenInvoiceAndReceivablesMenus()
|
||||
@ -64,13 +63,30 @@ class NavigationTest extends FeatureTestCase
|
||||
$this->assertLessThan($receivablesIndex, $refundIndex);
|
||||
$this->assertSame('订单数据', $orderData['title']);
|
||||
$this->assertSame(
|
||||
['after-sales-expenses', 'promotion-expenses'],
|
||||
['raw-data', 'bill-offset'],
|
||||
array_column($orderData['pages'], 'slug')
|
||||
);
|
||||
$this->assertSame(
|
||||
['订单售后费用明细', '商品推广费用明细'],
|
||||
['原始数据', '账单冲减'],
|
||||
array_column($orderData['pages'], 'title')
|
||||
);
|
||||
$this->assertSame(
|
||||
['after-sales-expenses', 'promotion-expenses'],
|
||||
array_column($orderData['pages'][0]['tabs'], 'slug')
|
||||
);
|
||||
$this->assertSame(
|
||||
['订单售后费用明细', '商品推广费用明细'],
|
||||
array_column($orderData['pages'][0]['tabs'], 'title')
|
||||
);
|
||||
$this->assertArrayNotHasKey('children', $orderData['pages'][0]);
|
||||
$this->assertSame(
|
||||
['bill-offset'],
|
||||
array_column(array_slice($orderData['pages'], 1), 'slug')
|
||||
);
|
||||
$this->assertSame(
|
||||
['账单冲减'],
|
||||
array_column(array_slice($orderData['pages'], 1), 'title')
|
||||
);
|
||||
$this->assertSame('退款', $refund['title']);
|
||||
$this->assertSame('assignment_return', $refund['icon']);
|
||||
$this->assertSame(
|
||||
@ -78,7 +94,7 @@ class NavigationTest extends FeatureTestCase
|
||||
array_column($refund['pages'], 'slug')
|
||||
);
|
||||
$this->assertSame(
|
||||
['京喜退款数据', '非京喜退款数据'],
|
||||
['京喜退款数据', '售后(退货退款)'],
|
||||
array_column($refund['pages'], 'title')
|
||||
);
|
||||
}
|
||||
|
||||
@ -53,12 +53,12 @@ class BusinessInformationMirrorRepositoryTest extends TestCase
|
||||
['Id' => 8, 'openTime' => '2026-08-14 10:00:00', 'erpShopName' => '测试店', 'unifiedSocialCreditCode' => '统一代码', 'trademarkNumber' => 'TM', 'platform' => '天猫', 'responsibleDepartment' => '电商', 'shopHead' => '负责人', 'shopState' => '0', 'shopType' => '直营', 'channelType' => '线上'],
|
||||
]);
|
||||
$connection->table('ops_fys_trademark_info')->insert([
|
||||
['Id' => 5, 'trademarkName' => '有效商标', 'internationalClassification' => '20', 'trademarkStatus' => '1', 'registrationDate' => '2020-01-01', 'termOfValidity' => '2030-01-01', 'remark' => null, 'isDelete' => 0],
|
||||
['Id' => 6, 'trademarkName' => '已删除', 'internationalClassification' => '20', 'trademarkStatus' => '0', 'registrationDate' => null, 'termOfValidity' => null, 'remark' => null, 'isDelete' => 1],
|
||||
['Id' => 5, 'trademarkNumber' => 'TM', 'trademarkName' => '有效商标', 'internationalClassification' => '20', 'trademarkStatus' => '1', 'registrationDate' => '2020-01-01', 'termOfValidity' => '2030-01-01', 'remark' => null, 'isDelete' => 0],
|
||||
['Id' => 6, 'trademarkNumber' => 'TM', 'trademarkName' => '已删除', 'internationalClassification' => '20', 'trademarkStatus' => '0', 'registrationDate' => null, 'termOfValidity' => null, 'remark' => null, 'isDelete' => 1],
|
||||
]);
|
||||
$this->markReady();
|
||||
$connection->table('ops_fys_company_info')->where('Id', 1)->update(['registeredCapitalVaildTime' => '2027-01-01']);
|
||||
$connection->table('ops_fys_shop_info')->where('Id', 8)->update(['sotreId' => 'STORE-8', 'renewalTime' => '2027-08-14', 'shopBankAccount' => 'fixture-account']);
|
||||
$connection->table('ops_fys_shop_info')->where('Id', 8)->update(['sotreId' => 'STORE-8', 'renewalTime' => '2027-08-14', 'shopBankAccount' => 'fixture-account', 'trademarkNumber' => 'TM-5']);
|
||||
$connection->table('ops_fys_trademark_info')->where('Id', 5)->update(['trademarkNumber' => 'TM-5', 'approvedCommodities' => '家具', 'transferenceUser' => '测试持有人', 'registrationAddress' => '测试地址', 'custodyDepartment' => '资料部']);
|
||||
|
||||
$companies = $this->repository->paginate('company-information.read', 2, 2);
|
||||
@ -68,6 +68,7 @@ class BusinessInformationMirrorRepositoryTest extends TestCase
|
||||
$this->assertSame(3, $companies['total']);
|
||||
$this->assertSame(1, $companies['data'][0]['id']);
|
||||
$this->assertSame('新公司', $store['data'][0]['company_name']);
|
||||
$this->assertSame('有效商标', $store['data'][0]['trademark_name']);
|
||||
$this->assertSame(1, $trademarks['total']);
|
||||
$this->assertSame('有效商标', $trademarks['data'][0]['trademark_name']);
|
||||
$this->assertSame('2027-01-01', $companies['data'][0]['subscribed_at']);
|
||||
@ -109,10 +110,10 @@ class BusinessInformationMirrorRepositoryTest extends TestCase
|
||||
$table->string('sotreId')->nullable(); $table->dateTime('renewalTime')->nullable(); $table->string('shopBankAccount')->nullable();
|
||||
});
|
||||
$schema->create('ops_fys_trademark_info', function (Blueprint $table): void {
|
||||
$table->integer('Id'); $table->string('trademarkName')->nullable(); $table->string('internationalClassification')->nullable();
|
||||
$table->integer('Id'); $table->string('trademarkNumber')->nullable(); $table->string('trademarkName')->nullable(); $table->string('internationalClassification')->nullable();
|
||||
$table->string('trademarkStatus')->nullable(); $table->dateTime('registrationDate')->nullable(); $table->dateTime('termOfValidity')->nullable();
|
||||
$table->text('remark')->nullable(); $table->integer('isDelete')->default(0);
|
||||
foreach (['trademarkNumber', 'approvedCommodities', 'transferenceUser', 'registrationAddress', 'custodyDepartment'] as $column) $table->string($column)->nullable();
|
||||
foreach (['approvedCommodities', 'transferenceUser', 'registrationAddress', 'custodyDepartment'] as $column) $table->string($column)->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user