U8ThirtyPartyDatabaseServerService.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. <?php
  2. namespace App\Service;
  3. use Illuminate\Support\Facades\Config;
  4. use Illuminate\Support\Facades\DB;
  5. use Illuminate\Support\Facades\Log;
  6. class U8ThirtyPartyDatabaseServerService extends Service
  7. {
  8. protected $connectionName = '';
  9. public function __construct($data)
  10. {
  11. $this->createConnection($data);
  12. }
  13. private function createConnection($data)
  14. {
  15. $mainConnName = $data['connect_name'];
  16. $this->connectionName = $mainConnName;
  17. // 创建连接
  18. $mainConfig = [
  19. 'driver' => 'sqlsrv',
  20. 'host' => $data['api_host'],
  21. 'port' => $data['database_port'],
  22. 'database' => 'UFDATA_001_2025',
  23. 'username' => $data['username'],
  24. 'password' => $data['password'],
  25. 'options' => [
  26. \PDO::SQLSRV_ATTR_QUERY_TIMEOUT => 15, // 减少超时
  27. \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
  28. ],
  29. ];
  30. // 配置注入
  31. Config::set("database.connections.{$mainConnName}", $mainConfig);
  32. }
  33. public function getStockCountByCategory()
  34. {
  35. try {
  36. $result = DB::connection($this->connectionName)
  37. ->table('Inventory as i')
  38. ->lock('WITH(NOLOCK)')
  39. ->join('InventoryClass as ic', 'i.cInvCCode', '=', 'ic.cInvCCode')
  40. ->join('CurrentStock as s', 'i.cInvCode', '=', 's.cInvCode')
  41. ->select([
  42. 'ic.cInvCCode as category_code',
  43. 'ic.cInvCName as category_name',
  44. DB::raw('SUM(s.iQuantity) as total_quantity')
  45. ])
  46. ->groupBy('ic.cInvCCode', 'ic.cInvCName')
  47. ->orderBy('ic.cInvCCode', 'ASC')
  48. ->get()
  49. ->map(function($item) {
  50. return [
  51. 'category_code' => trim($item->category_code),
  52. 'category_name' => trim($item->category_name),
  53. 'total_quantity' => (float)$item->total_quantity,
  54. ];
  55. })
  56. ->toArray();
  57. return [true, $result];
  58. } catch (\Throwable $e) {
  59. return [false, $e->getMessage()];
  60. }
  61. }
  62. public function getStockCountWithPercentage()
  63. {
  64. try {
  65. // 1. 获取基础数据:明细分类库存
  66. $details = DB::connection($this->connectionName)
  67. ->table('Inventory as i')
  68. ->lock('WITH(NOLOCK)')
  69. ->join('InventoryClass as ic', 'i.cInvCCode', '=', 'ic.cInvCCode')
  70. ->join('CurrentStock as s', 'i.cInvCode', '=', 's.cInvCode')
  71. ->select([
  72. 'ic.cInvCCode as sub_code', // 明细编码 (如 0102)
  73. 'ic.cInvCName as sub_name', // 明细名称
  74. DB::raw('SUM(s.iQuantity) as sub_quantity')
  75. ])
  76. ->groupBy('ic.cInvCCode', 'ic.cInvCName')
  77. ->get();
  78. // 2. 转换数据结构,按大类进行逻辑汇总
  79. $collection = $details->map(function ($item) {
  80. return [
  81. 'parent_code' => substr(trim($item->sub_code), 0, 2), // 截取前两位作为大类编码
  82. 'sub_code' => trim($item->sub_code),
  83. 'sub_name' => trim($item->sub_name),
  84. 'sub_quantity' => (float)$item->sub_quantity,
  85. ];
  86. });
  87. // 3. 计算每个大类的总数 (以 parent_code 分组求和)
  88. $parentTotals = $collection->groupBy('parent_code')->map(function ($group) {
  89. return $group->sum('sub_quantity');
  90. });
  91. // 4. 组装最终结果,合并大类总数并计算百分比
  92. $result = $collection->map(function ($item) use ($parentTotals) {
  93. $parentSum = $parentTotals[$item['parent_code']] ?? 0;
  94. // 计算占比:(子类数量 / 父类总数) * 100
  95. $percentage = $parentSum > 0
  96. ? round(($item['sub_quantity'] / $parentSum) * 100, 2)
  97. : 0;
  98. return [
  99. 'parent_category_code' => $item['parent_code'],
  100. 'category_code' => $item['sub_code'],
  101. 'category_name' => $item['sub_name'],
  102. 'total_quantity' => $item['sub_quantity'],
  103. 'parent_total' => $parentSum,
  104. 'percentage' => $percentage, // 格式化为百分比字符串
  105. ];
  106. })->values()->toArray();
  107. return [true, $result];
  108. } catch (\Throwable $e) {
  109. return [false, $e->getMessage()];
  110. }
  111. }
  112. }