#feature: update SQL generator

This commit is contained in:
2026-05-19 14:57:11 +08:00
parent 53bca7d609
commit 3c628eb391
10 changed files with 1043 additions and 165 deletions
+39 -23
View File
@@ -4,11 +4,13 @@ namespace App\Http\Controllers;
use App\Services\JiraService;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class JiraController extends Controller
{
private const WEEKLY_REPORT_PERIODS = ['this_week', 'last_week'];
private JiraService $jiraService;
public function __construct(JiraService $jiraService)
@@ -16,37 +18,44 @@ class JiraController extends Controller
$this->jiraService = $jiraService;
}
/**
* 生成上周周报
* 生成周报
*/
public function generateWeeklyReport(Request $request): JsonResponse
{
try {
$username = $request->input('username') ?: config('jira.default_user');
$period = $request->input('period', 'this_week');
if (!$username) {
if (! $username) {
return response()->json([
'success' => false,
'message' => '请提供用户名'
'message' => '请提供用户名',
], 400);
}
$report = $this->jiraService->generateWeeklyReport($username);
if (! in_array($period, self::WEEKLY_REPORT_PERIODS, true)) {
return response()->json([
'success' => false,
'message' => '无效的周报周期',
], 400);
}
$report = $this->jiraService->generateWeeklyReport($username, $period);
return response()->json([
'success' => true,
'data' => [
'report' => $report,
'username' => $username,
'generated_at' => Carbon::now()->format('Y-m-d H:i:s')
]
'period' => $period,
'generated_at' => Carbon::now()->format('Y-m-d H:i:s'),
],
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => '生成周报失败: ' . $e->getMessage()
'message' => '生成周报失败: '.$e->getMessage(),
], 500);
}
}
@@ -77,14 +86,14 @@ class JiraController extends Controller
'total_records' => $workLogs->count(),
'date_range' => [
'start' => $startDate->format('Y-m-d'),
'end' => $endDate->format('Y-m-d')
]
]
'end' => $endDate->format('Y-m-d'),
],
],
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => '获取工时记录失败: ' . $e->getMessage()
'message' => '获取工时记录失败: '.$e->getMessage(),
], 500);
}
}
@@ -98,8 +107,8 @@ class JiraController extends Controller
'success' => true,
'data' => [
'default_user' => config('jira.default_user', ''),
'host' => config('jira.host', '')
]
'host' => config('jira.host', ''),
],
]);
}
@@ -110,26 +119,33 @@ class JiraController extends Controller
{
try {
$username = $request->input('username') ?: config('jira.default_user');
$period = $request->input('period', 'this_week');
if (!$username) {
if (! $username) {
return response()->json([
'success' => false,
'message' => '请提供用户名'
'message' => '请提供用户名',
], 400);
}
$report = $this->jiraService->generateWeeklyReport($username);
$filename = sprintf('weekly_report_%s_%s.md', $username, Carbon::now()->subWeek()->format('Y-m-d'));
if (! in_array($period, self::WEEKLY_REPORT_PERIODS, true)) {
return response()->json([
'success' => false,
'message' => '无效的周报周期',
], 400);
}
$report = $this->jiraService->generateWeeklyReport($username, $period);
$filename = sprintf('weekly_report_%s_%s_%s.md', $username, $period, Carbon::now()->format('Y-m-d'));
return response($report)
->header('Content-Type', 'text/markdown')
->header('Content-Disposition', 'attachment; filename="' . $filename . '"');
->header('Content-Disposition', 'attachment; filename="'.$filename.'"');
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => '下载周报失败: ' . $e->getMessage()
'message' => '下载周报失败: '.$e->getMessage(),
], 500);
}
}
}
+206 -2
View File
@@ -25,7 +25,7 @@ class SqlGeneratorController extends Controller
if (empty($caseCodes)) {
return response()->json([
'success' => false,
'message' => '请提供有效的 case_id 列表'
'message' => '请提供有效的 case_id 列表',
], 400);
}
@@ -59,8 +59,212 @@ class SqlGeneratorController extends Controller
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => '查询 case_extras 失败: ' . $e->getMessage(),
'message' => '查询 case_extras 失败: '.$e->getMessage(),
], 500);
}
}
/**
* 查询 CRM 加工单关联地址国家,用于区分 PP-CN / PP-US。
*/
public function checkProductionCountries(Request $request): JsonResponse
{
try {
$request->validate([
'production_codes' => 'required|array|min:1',
'production_codes.*' => 'required|string|max:255',
]);
$productionCodes = array_values(array_unique(array_filter(array_map('trim', $request->input('production_codes')))));
if (empty($productionCodes)) {
return response()->json([
'success' => false,
'message' => '请提供有效的加工单列表',
], 400);
}
$productionCountries = $this->getProductionCountries($productionCodes);
return response()->json([
'success' => true,
'data' => [
'production_countries' => $productionCountries,
],
]);
} catch (ValidationException $e) {
return response()->json([
'success' => false,
'message' => '请求参数验证失败',
'errors' => $e->errors(),
], 422);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => '查询 CRM 加工单国家失败: '.$e->getMessage(),
], 500);
}
}
private function getProductionCountries(array $productionCodes): array
{
$productionCountries = [];
foreach (array_chunk($productionCodes, 1000) as $chunk) {
$productions = DB::connection('crmslave')
->table('ea_production as ep')
->join('ea_production_cstm as epc', 'ep.id', '=', 'epc.id_c')
->where('ep.deleted', 0)
->whereIn('ep.name', $chunk)
->select([
'ep.name as production_code',
'epc.ea_case_id_c',
'epc.ea_businessorder_id_c',
'epc.ea_salesorder_id_c',
])
->get();
$caseIds = $productions->pluck('ea_case_id_c')->filter()->unique()->values()->all();
$businessOrderIds = $productions->pluck('ea_businessorder_id_c')->filter()->unique()->values()->all();
$salesOrderIds = $productions->pluck('ea_salesorder_id_c')->filter()->unique()->values()->all();
$caseCountries = $this->getCountriesByCaseIds($caseIds);
$businessOrderCountries = $this->getCountriesByBusinessOrderIds($businessOrderIds);
$salesOrderCountries = $this->getCountriesBySalesOrderIds($salesOrderIds);
foreach ($productions as $production) {
$countries = array_merge(
$caseCountries[(string) $production->ea_case_id_c] ?? [],
$businessOrderCountries[(string) $production->ea_businessorder_id_c] ?? [],
$salesOrderCountries[(string) $production->ea_salesorder_id_c] ?? []
);
$productionCountries[(string) $production->production_code] = array_values(array_unique(array_filter($countries)));
}
}
return $productionCountries;
}
private function getCountriesByCaseIds(array $caseIds): array
{
if (empty($caseIds)) {
return [];
}
$results = DB::connection('crmslave')
->table('ea_case as ec')
->join('accounts_ea_case_1_c as aec1c', function ($join) {
$join->on('aec1c.accounts_ea_case_1ea_case_idb', '=', 'ec.id')
->where('aec1c.deleted', '=', 0);
})
->join('accounts as a', 'a.id', '=', 'aec1c.accounts_ea_case_1accounts_ida')
->join('accounts_cstm as ac', 'ac.id_c', '=', 'a.id')
->where('ec.deleted', 0)
->where('a.deleted', 0)
->whereIn('ec.id', $caseIds)
->whereNotNull('ac.country_c')
->select([
'ec.id as entity_id',
'ac.country_c as country',
'ac.province_c as province',
])
->get();
return $this->groupCountriesByEntityId($results);
}
private function getCountriesByBusinessOrderIds(array $businessOrderIds): array
{
if (empty($businessOrderIds)) {
return [];
}
$results = DB::connection('crmslave')
->table('ea_businessorder as eb')
->join('accounts_ea_businessorder_1_c as aeb1c', function ($join) {
$join->on('aeb1c.accounts_ea_businessorder_1ea_businessorder_idb', '=', 'eb.id')
->where('aeb1c.deleted', '=', 0);
})
->join('accounts as a', 'a.id', '=', 'aeb1c.accounts_ea_businessorder_1accounts_ida')
->join('accounts_cstm as ac', 'ac.id_c', '=', 'a.id')
->where('eb.deleted', 0)
->where('a.deleted', 0)
->whereIn('eb.id', $businessOrderIds)
->whereNotNull('ac.country_c')
->select([
'eb.id as entity_id',
'ac.country_c as country',
'ac.province_c as province',
])
->get();
return $this->groupCountriesByEntityId($results);
}
private function getCountriesBySalesOrderIds(array $salesOrderIds): array
{
if (empty($salesOrderIds)) {
return [];
}
$results = DB::connection('crmslave')
->table('ea_salesorder as es')
->join('accounts_ea_salesorder_1_c as aes1c', function ($join) {
$join->on('aes1c.accounts_ea_salesorder_1ea_salesorder_idb', '=', 'es.id')
->where('aes1c.deleted', '=', 0);
})
->join('accounts as a_base', 'a_base.id', '=', 'aes1c.accounts_ea_salesorder_1accounts_ida')
->join('accounts_cstm as ac', 'ac.id_c', '=', 'aes1c.accounts_ea_salesorder_1accounts_ida')
->where('es.deleted', 0)
->where('a_base.deleted', 0)
->whereIn('es.id', $salesOrderIds)
->whereNotNull('ac.country_c')
->select([
'es.id as entity_id',
'ac.country_c as country',
'ac.province_c as province',
])
->get();
return $this->groupCountriesByEntityId($results);
}
private function groupCountriesByEntityId($results): array
{
$countriesByEntityId = [];
foreach ($results as $result) {
$countryCode = $this->getCountryCode($result->country, $result->province);
if (! $countryCode) {
continue;
}
$entityId = (string) $result->entity_id;
$countriesByEntityId[$entityId] ??= [];
$countriesByEntityId[$entityId][] = $countryCode;
}
return array_map(fn ($countries) => array_values(array_unique($countries)), $countriesByEntityId);
}
private function getCountryCode(?string $country, ?string $province): ?string
{
if (! $country) {
return null;
}
if (in_array($country, ['1', '156'], true) && ! in_array((string) $province, ['710000', '810000', '820000'], true)) {
return 'CN';
}
return [
'840' => 'US',
'US' => 'US',
'316' => 'GU',
'GU' => 'GU',
'630' => 'PR',
'PR' => 'PR',
][strtoupper($country)] ?? strtoupper($country);
}
}