TransferService.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. <?php
  2. namespace App\Module\Transfer\Services;
  3. use App\Module\Transfer\Dtos\TransferAppDto;
  4. use App\Module\Transfer\Dtos\TransferOrderDto;
  5. use App\Module\Transfer\Logics\TransferLogic;
  6. use App\Module\Transfer\Models\TransferApp;
  7. use App\Module\Transfer\Models\TransferOrder;
  8. use App\Module\Transfer\Services\FeeService;
  9. /**
  10. * Transfer模块对外服务接口
  11. * 供其他模块调用的主要服务类
  12. */
  13. class TransferService
  14. {
  15. /**
  16. * 创建转出订单
  17. *
  18. * @param int $transferAppId 划转应用ID
  19. * @param int $userId 用户ID
  20. * @param string $amount 转出金额
  21. * @param string $password 安全密码
  22. * @param string|null $googleCode 谷歌验证码
  23. * @param string|null $outUserId 外部用户ID
  24. * @param string|null $remark 备注
  25. * @param array $callbackData 回调数据
  26. * @return TransferOrderDto|string 成功返回DTO,失败返回错误信息
  27. */
  28. public static function createTransferOut(
  29. int $transferAppId,
  30. int $userId,
  31. string $amount,
  32. string $password,
  33. ?string $googleCode = null,
  34. ?string $outUserId = null,
  35. ?string $remark = null,
  36. array $callbackData = []
  37. ): TransferOrderDto|string
  38. {
  39. try {
  40. $data = [
  41. 'transfer_app_id' => $transferAppId,
  42. 'user_id' => $userId,
  43. 'amount' => $amount,
  44. 'password' => $password,
  45. 'google_code' => $googleCode,
  46. 'out_user_id' => $outUserId,
  47. 'remark' => $remark,
  48. 'callback_data' => $callbackData,
  49. ];
  50. $order = TransferLogic::createTransferOutFromArray($data);
  51. return TransferOrderDto::fromModel($order);
  52. } catch (\Exception $e) {
  53. return $e->getMessage();
  54. }
  55. }
  56. /**
  57. * 创建转入订单
  58. *
  59. * @param int $transferAppId 划转应用ID
  60. * @param int $userId 用户ID
  61. * @param string $businessId 业务订单ID
  62. * @param string $amount 转入金额
  63. * @param string|null $outUserId 外部用户ID
  64. * @param string|null $remark 备注
  65. * @param array $callbackData 回调数据
  66. * @return TransferOrderDto|string 成功返回DTO,失败返回错误信息
  67. */
  68. public static function createTransferIn(
  69. int $transferAppId,
  70. int $userId,
  71. string $businessId,
  72. string $amount,
  73. ?string $outUserId = null,
  74. ?string $remark = null,
  75. array $callbackData = []
  76. ): TransferOrderDto|string
  77. {
  78. try {
  79. $data = [
  80. 'transfer_app_id' => $transferAppId,
  81. 'user_id' => $userId,
  82. 'out_order_id' => $businessId,
  83. 'amount' => $amount,
  84. 'out_user_id' => $outUserId,
  85. 'remark' => $remark,
  86. 'callback_data' => $callbackData,
  87. ];
  88. $order = TransferLogic::createTransferInFromArray($data, $userId);
  89. return TransferOrderDto::fromModel($order);
  90. } catch (\Exception $e) {
  91. return $e->getMessage();
  92. }
  93. }
  94. /**
  95. * 查询订单信息
  96. *
  97. * @param int $orderId 订单ID
  98. * @param int|null $userId 用户ID(可选,用于权限验证)
  99. * @return TransferOrderDto|null
  100. */
  101. public static function getOrderInfo(int $orderId, ?int $userId = null): ?TransferOrderDto
  102. {
  103. $query = TransferOrder::where('id', $orderId);
  104. if ($userId !== null) {
  105. $query->where('user_id', $userId);
  106. }
  107. $order = $query->first();
  108. return $order ? TransferOrderDto::fromModel($order) : null;
  109. }
  110. /**
  111. * 根据外部订单ID查询订单信息
  112. *
  113. * @param string $outOrderId 外部订单ID
  114. * @param int $outId 开放接口ID
  115. * @return TransferOrderDto|null
  116. */
  117. public static function getOrderByOutId(string $outOrderId, int $outId): ?TransferOrderDto
  118. {
  119. $order = TransferOrder::where('out_order_id', $outOrderId)
  120. ->where('out_id', $outId)
  121. ->first();
  122. return $order ? TransferOrderDto::fromModel($order) : null;
  123. }
  124. /**
  125. * 获取用户可用的划转应用列表
  126. *
  127. * @param int $userId 用户ID
  128. * @return TransferAppDto[]
  129. */
  130. public static function getAvailableApps(int $userId): array
  131. {
  132. $apps = TransferApp::where('is_enabled', true)->get();
  133. return $apps->map(function ($app) {
  134. return TransferAppDto::fromModel($app);
  135. })->toArray();
  136. }
  137. /**
  138. * 获取用户订单列表
  139. *
  140. * @param int $userId 用户ID
  141. * @param array $filters 筛选条件
  142. * @return array
  143. */
  144. public static function getUserOrders(int $userId, array $filters = []): array
  145. {
  146. $query = TransferOrder::where('user_id', $userId);
  147. // 应用筛选条件
  148. if (isset($filters['type'])) {
  149. $query->where('type', $filters['type']);
  150. }
  151. if (isset($filters['status'])) {
  152. $query->where('status', $filters['status']);
  153. }
  154. if (isset($filters['transfer_app_id'])) {
  155. $query->where('transfer_app_id', $filters['transfer_app_id']);
  156. }
  157. if (isset($filters['start_date'])) {
  158. $query->where('created_at', '>=', $filters['start_date']);
  159. }
  160. if (isset($filters['end_date'])) {
  161. $query->where('created_at', '<=', $filters['end_date']);
  162. }
  163. // 分页参数
  164. $page = $filters['page'] ?? 1;
  165. $perPage = $filters['per_page'] ?? 20;
  166. $orders = $query->orderBy('created_at', 'desc')
  167. ->paginate($perPage, [ '*' ], 'page', $page);
  168. return [
  169. 'data' => $orders->items(),
  170. 'current_page' => $orders->currentPage(),
  171. 'per_page' => $orders->perPage(),
  172. 'total' => $orders->total(),
  173. 'last_page' => $orders->lastPage(),
  174. ];
  175. }
  176. /**
  177. * 获取应用配置信息
  178. *
  179. * @param int $appId 应用ID
  180. * @return TransferAppDto|null
  181. */
  182. public static function getAppConfig(int $appId): ?TransferAppDto
  183. {
  184. $app = TransferApp::find($appId);
  185. return $app ? TransferAppDto::fromModel($app) : null;
  186. }
  187. /**
  188. * 根据应用标识获取配置信息
  189. *
  190. * @param string $keyname 应用标识
  191. * @return TransferAppDto|null
  192. */
  193. public static function getAppByKeyname(string $keyname): ?TransferAppDto
  194. {
  195. $app = TransferApp::where('keyname', $keyname)
  196. ->where('is_enabled', true)
  197. ->first();
  198. return $app ? TransferAppDto::fromModel($app) : null;
  199. }
  200. /**
  201. * 处理回调结果
  202. *
  203. * @param array $callbackData 回调数据
  204. * @return bool
  205. */
  206. public static function processCallback(array $callbackData): bool
  207. {
  208. try {
  209. return TransferLogic::processCallback($callbackData);
  210. } catch (\Exception $e) {
  211. \Log::error('Transfer callback processing failed', [
  212. 'error' => $e->getMessage(),
  213. 'data' => $callbackData
  214. ]);
  215. return false;
  216. }
  217. }
  218. /**
  219. * 快速创建转出订单(简化版本,用于测试或内部调用)
  220. *
  221. * @param int $transferAppId 划转应用ID
  222. * @param int $userId 用户ID
  223. * @param string $amount 转出金额
  224. * @param string $password 安全密码
  225. * @return TransferOrderDto|string
  226. */
  227. public static function quickCreateTransferOut(
  228. int $transferAppId,
  229. int $userId,
  230. string $amount,
  231. string $password
  232. ): TransferOrderDto|string
  233. {
  234. return self::createTransferOut(
  235. transferAppId: $transferAppId,
  236. userId: $userId,
  237. amount: $amount,
  238. password: $password
  239. );
  240. }
  241. /**
  242. * 快速创建转入订单(简化版本,用于测试或内部调用)
  243. *
  244. * @param int $transferAppId 划转应用ID
  245. * @param int $userId 用户ID
  246. * @param string $businessId 业务订单ID
  247. * @param string $amount 转入金额
  248. * @return TransferOrderDto|string
  249. */
  250. public static function quickCreateTransferIn(
  251. int $transferAppId,
  252. int $userId,
  253. string $businessId,
  254. string $amount
  255. ): TransferOrderDto|string
  256. {
  257. return self::createTransferIn(
  258. transferAppId: $transferAppId,
  259. userId: $userId,
  260. businessId: $businessId,
  261. amount: $amount
  262. );
  263. }
  264. /**
  265. * 获取应用的手续费配置
  266. *
  267. * @param int $transferAppId 划转应用ID
  268. * @return array
  269. */
  270. public static function getFeeConfig(int $transferAppId): array
  271. {
  272. try {
  273. $app = TransferApp::findOrFail($transferAppId);
  274. return FeeService::getFeeConfig($app);
  275. } catch (\Exception $e) {
  276. return [
  277. 'error' => $e->getMessage(),
  278. 'in' => [ 'rate' => 0, 'min' => 0, 'max' => 0, 'enabled' => false ],
  279. 'out' => [ 'rate' => 0, 'min' => 0, 'max' => 0, 'enabled' => false ],
  280. 'account_uid' => 0,
  281. ];
  282. }
  283. }
  284. /**
  285. * 获取手续费统计信息
  286. *
  287. * @param int $appId 应用ID(0表示所有应用)
  288. * @param string $startDate 开始日期
  289. * @param string $endDate 结束日期
  290. * @return array
  291. */
  292. public static function getFeeStatistics(int $appId = 0, string $startDate = '', string $endDate = ''): array
  293. {
  294. try {
  295. return FeeService::getFeeStatistics($appId, $startDate, $endDate);
  296. } catch (\Exception $e) {
  297. return [
  298. 'error' => $e->getMessage(),
  299. 'total_orders' => 0,
  300. 'total_fee' => 0,
  301. 'avg_fee_rate' => 0,
  302. 'in_orders' => 0,
  303. 'in_fee' => 0,
  304. 'out_orders' => 0,
  305. 'out_fee' => 0,
  306. ];
  307. }
  308. }
  309. /**
  310. * 获取应用的手续费收入统计
  311. *
  312. * @param int $appId 应用ID
  313. * @param int $days 统计天数
  314. * @return array
  315. */
  316. public static function getAppFeeIncome(int $appId, int $days = 30): array
  317. {
  318. try {
  319. return FeeService::getAppFeeIncome($appId, $days);
  320. } catch (\Exception $e) {
  321. return [
  322. 'error' => $e->getMessage(),
  323. 'app_id' => $appId,
  324. 'days' => $days,
  325. 'total_fee' => 0,
  326. 'total_orders' => 0,
  327. 'avg_daily_fee' => 0,
  328. 'daily_stats' => [],
  329. ];
  330. }
  331. }
  332. }