MMerchantFlow.Class.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. <?php
  2. namespace JinDouYun\Model\Finance;
  3. use JinDouYun\Controller\Common\Logger;
  4. use JinDouYun\Dao\Finance\DMerchantFlow;
  5. use JinDouYun\Model\Enterprise\MEnterprise;
  6. use JinDouYun\Model\MBaseModel;
  7. use JinDouYun\Model\Merchant\MMerchant;
  8. use JinDouYun\Model\Order\MOrder;
  9. use Mall\Framework\Core\ErrorCode;
  10. use Mall\Framework\Core\ResultWrapper;
  11. use Mall\Framework\Core\StatusCode;
  12. /**
  13. * @copyright Copyright (c) https://www.qianniaovip.com All rights reserved
  14. * Description:
  15. * Class MMerchantFlow
  16. * @package JinDouYun\Model\Finance
  17. */
  18. class MMerchantFlow extends MBaseModel
  19. {
  20. /**
  21. * @var DMerchantFlow
  22. */
  23. private $objDMerchantFlow;
  24. /**
  25. * @var int
  26. */
  27. private $onlineEnterpriseId;
  28. /**
  29. * @var int
  30. */
  31. private $onlineUserId;
  32. /**
  33. * MMerchantFlow constructor.
  34. * @param $onlineEnterpriseId
  35. * @param $onlineUserId
  36. * @throws \Exception
  37. */
  38. public function __construct($onlineEnterpriseId, $onlineUserId)
  39. {
  40. $this->onlineEnterpriseId = $onlineEnterpriseId;
  41. $this->onlineUserId = $onlineUserId;
  42. parent::__construct($onlineEnterpriseId, $onlineUserId);
  43. $this->objDMerchantFlow = new DMerchantFlow();
  44. $this->objDMerchantFlow->setTable('qianniao_merchant_flow_' . $this->onlineEnterpriseId);
  45. }
  46. /**
  47. * Doc: (des="多商户结算,不在此处计算抽成,提现时计算抽成")
  48. * User: XMing 放在确认收款 和 支付回调
  49. * Date: 2020/12/7
  50. * Time: 4:01 下午
  51. * @param int $orderId
  52. * @return ResultWrapper
  53. * @throws \Exception
  54. */
  55. public function calculation(int $orderId): ResultWrapper
  56. {
  57. Logger::logs(E_USER_ERROR,'订单id',__CLASS__,__LINE__,$orderId);
  58. $objMOrder = new MOrder($this->onlineUserId,$this->onlineEnterpriseId);
  59. $orderResult = $objMOrder->getOrderByOrderId($orderId);
  60. if (!$orderResult->isSuccess()){
  61. Logger::logs(E_USER_ERROR,'sql错误',__CLASS__,__LINE__,$orderResult->getData());
  62. return ResultWrapper::fail($orderResult->getData(),$orderResult->getErrorCode());
  63. }
  64. $order = $orderResult->getData();
  65. if ($order['payStatus'] == StatusCode::$delete){
  66. Logger::logs(E_USER_ERROR,'订单未支付',__CLASS__,__LINE__,$order['payStatus']);
  67. return ResultWrapper::fail('订单未支付',ErrorCode::$paramError);
  68. }
  69. if ($order['isSettel'] == StatusCode::$standard){
  70. Logger::logs(E_USER_ERROR,'isSettel',__CLASS__,__LINE__,$order);
  71. return ResultWrapper::fail('订单已经结算',ErrorCode::$paramError);
  72. }
  73. $objMEnterprise = new MEnterprise();
  74. $enterpriseResult = $objMEnterprise->getEnterpriseDataByEnterpriseId($this->onlineEnterpriseId);
  75. if (!$enterpriseResult->isSuccess()){
  76. Logger::logs(E_USER_ERROR,'sql错误',__CLASS__,__LINE__,$enterpriseResult->getData());
  77. return ResultWrapper::fail($enterpriseResult->getData(),$enterpriseResult->getErrorCode());
  78. }
  79. $enterprise = $enterpriseResult->getData();
  80. if (empty($enterprise)){
  81. Logger::logs(E_USER_ERROR,'未获取到平台信息',__CLASS__,__LINE__,'');
  82. return ResultWrapper::fail('未获取到平台信息',ErrorCode::$paramError);
  83. }
  84. //获取商户的信息
  85. $objMMerchant = new MMerchant($this->onlineEnterpriseId,$this->onlineUserId);
  86. $shopResult = $objMMerchant->getMerchByShopId($order['shopId']);
  87. if (!$shopResult->isSuccess()){
  88. Logger::logs(E_USER_ERROR,'sql',__CLASS__,__LINE__,$shopResult->getData());
  89. return ResultWrapper::fail($shopResult->getData(),$shopResult->getErrorCode());
  90. }
  91. $shop = $shopResult->getData();
  92. //计算第三方支付的手续费(不计入平余额)
  93. if (!isset($order['payAmount']) || empty($order['payAmount'])){
  94. Logger::logs(E_USER_ERROR,'payAmount参数异常',__CLASS__,__LINE__,'');
  95. return ResultWrapper::fail('payAmount参数异常',ErrorCode::$paramError);
  96. }
  97. $tradeMoney = $order['payAmount'];
  98. $logInserts = [];
  99. $buildPlatformResult = self::buildPlatform($tradeMoney,$order,$shop,$enterprise);
  100. if (!$buildPlatformResult->isSuccess()){
  101. Logger::logs(E_USER_ERROR,'构建平台流水记录时出错',__CLASS__,__LINE__,$buildPlatformResult->getData());
  102. return ResultWrapper::fail($buildPlatformResult->getData(),$buildPlatformResult->getErrorCode());
  103. }
  104. $buildPlatform = $buildPlatformResult->getData();
  105. $logInserts = array_merge($logInserts,$buildPlatform);
  106. $buildMerchResult = self::buildMerch($tradeMoney,$order,$shop,$enterprise);
  107. if (!$buildMerchResult->isSuccess()){
  108. Logger::logs(E_USER_ERROR,'构建商户流水记录时出错',__CLASS__,__LINE__,$buildMerchResult->getData());
  109. return ResultWrapper::fail($buildMerchResult->getData(),$buildMerchResult->getErrorCode());
  110. }
  111. $buildMerch = $buildMerchResult->getData();
  112. $logInserts = array_merge($logInserts,$buildMerch['logs']);
  113. $updateBalance = $buildMerch['updateBalance'];
  114. if (empty($logInserts)){
  115. Logger::logs(E_USER_ERROR,'构建流水记录为空',__CLASS__,__LINE__,$logInserts);
  116. return ResultWrapper::fail('构建流水记录为空',ErrorCode::$paramError);
  117. }
  118. Logger::logs(E_USER_ERROR,'流水数据',__CLASS__,__LINE__,$logInserts);
  119. Logger::logs(E_USER_ERROR,'商户余额更新数据',__CLASS__,__LINE__,$updateBalance);
  120. $this->objDMerchantFlow->beginTransaction();
  121. $insertResult = $this->objDMerchantFlow->insert($logInserts,true);
  122. if ($insertResult === false){
  123. $this->objDMerchantFlow->rollBack();
  124. Logger::logs(E_USER_ERROR,'sql',__CLASS__,__LINE__,$this->objDMerchantFlow->error());
  125. return ResultWrapper::fail($this->objDMerchantFlow->error,ErrorCode::$dberror);
  126. }
  127. $updateBalanceResult = $objMMerchant->update($updateBalance['merchantId'],['orderNum' => $updateBalance['orderNum'],'balance' => $updateBalance['balance'],'updateTime' => time()]);
  128. if (!$updateBalanceResult->isSuccess()){
  129. $this->objDMerchantFlow->rollBack();
  130. Logger::logs(E_USER_ERROR,'sql',__CLASS__,__LINE__,$updateBalanceResult->getData());
  131. return ResultWrapper::fail($updateBalanceResult->getData(),$updateBalanceResult->getErrorCode());
  132. }
  133. $updateSettelResult = $objMOrder->updateSettel($orderId);
  134. if (!$updateSettelResult->isSuccess()){
  135. $this->objDMerchantFlow->rollBack();
  136. Logger::logs(E_USER_ERROR,'sql',__CLASS__,__LINE__,$updateSettelResult->getData());
  137. return ResultWrapper::fail($updateSettelResult->getData(),$updateSettelResult->getErrorCode());
  138. }
  139. $this->objDMerchantFlow->commit();
  140. return ResultWrapper::success(true);
  141. }
  142. /**
  143. * Doc: (des="构建平台的流水记录")
  144. * User: XMing
  145. * Date: 2020/12/7
  146. * Time: 5:46 下午
  147. * @param float $tradeMoney
  148. * @param array $order
  149. * @param array $shop
  150. * @param array $enterprise
  151. * @return ResultWrapper
  152. */
  153. public function buildPlatform(float $tradeMoney,array $order,array $shop,array $enterprise): ResultWrapper
  154. {
  155. if($order['payType'] != StatusCode::$payType['wxPay']){
  156. return ResultWrapper::success([]);
  157. }
  158. $changeMoney = bcmul($tradeMoney,WX_RATE,2);
  159. $log = [
  160. 'no' => createOrderSn(StatusCode::$orderType['saleOrder'],StatusCode::$orderType['saleOrder'],$this->onlineUserId),
  161. 'merchantId' => $shop['merchantId'],
  162. 'merchantName' => $shop['merchantName'],
  163. 'shopId' => $shop['id'],
  164. 'shopName' => $shop['name'],
  165. 'originId' => $order['id'],
  166. 'originNo' => $order['no'],
  167. 'tradeMoney' => $tradeMoney,
  168. 'payType' => $order['payType'],
  169. 'originMoney' => $enterprise['balance'],
  170. 'changeMoney' => $changeMoney,
  171. 'nowMoney' => $enterprise['balance'],//不改变余额
  172. 'rate' => WX_RATE,
  173. 'fee' => $changeMoney,
  174. 'type' => StatusCode::$standard,
  175. 'isPayment' => StatusCode::$standard,
  176. 'isPlatform' => StatusCode::$standard,
  177. 'source' => 1,
  178. 'describe' => '本次交易微信支付金额:'.$tradeMoney.'元,微信交易手续费:'.$changeMoney.'元,不计入平余额',
  179. ];
  180. $buildLog = self::buildFlowData($log);
  181. return ResultWrapper::success([$buildLog]);
  182. }
  183. /**
  184. * Doc: (des="构建商户的流水记录")
  185. * User: XMing
  186. * Date: 2020/12/7
  187. * Time: 5:46 下午
  188. * @param float $tradeMoney
  189. * @param array $order
  190. * @param array $shop
  191. * @param array $enterprise
  192. * @return ResultWrapper
  193. */
  194. public function buildMerch(float $tradeMoney,array $order,array $shop,array $enterprise): ResultWrapper
  195. {
  196. $originMoney = $shop['balance'];
  197. $nowMoney = bcadd($originMoney,$tradeMoney,2);
  198. $logs = [];
  199. $finalBalance = $nowMoney;
  200. $finalOrderNum = bcadd($shop['orderNum'],1);
  201. $step_one = [
  202. 'no' => createOrderSn(StatusCode::$orderType['saleOrder'],StatusCode::$orderType['saleOrder'],$this->onlineUserId),
  203. 'merchantId' => $shop['merchantId'],
  204. 'merchantName' => $shop['merchantName'],
  205. 'shopId' => $shop['id'],
  206. 'shopName' => $shop['name'],
  207. 'originId' => $order['id'],
  208. 'originNo' => $order['no'],
  209. 'tradeMoney' => $tradeMoney,
  210. 'payType' => $order['payType'],
  211. 'originMoney' => $originMoney,
  212. 'changeMoney' => $tradeMoney,
  213. 'nowMoney' => $nowMoney,
  214. 'rate' => 0,
  215. 'fee' => 0,
  216. 'type' => StatusCode::$standard,
  217. 'isPayment' => StatusCode::$delete,
  218. 'isPlatform' => StatusCode::$delete,
  219. 'source' => 1,
  220. 'describe' => '本次交易支付金额:'.$tradeMoney.'元',
  221. ];
  222. $logs[] = $step_one;
  223. Logger::logs(E_USER_ERROR,'订单数据--',__CLASS__,__LINE__,$order);
  224. if ($order['payType'] == StatusCode::$payType['wxPay']){
  225. $fee = bcmul($tradeMoney,WX_RATE,2);
  226. $step_two = [
  227. 'no' => createOrderSn(StatusCode::$orderType['saleOrder'],StatusCode::$orderType['saleOrder'],$this->onlineUserId),
  228. 'merchantId' => $shop['merchantId'],
  229. 'merchantName' => $shop['merchantName'],
  230. 'shopId' => $shop['id'],
  231. 'shopName' => $shop['name'],
  232. 'originId' => $order['id'],
  233. 'originNo' => $order['no'],
  234. 'tradeMoney' => $tradeMoney,
  235. 'payType' => $order['payType'],
  236. 'originMoney' => $nowMoney,//上次计算后的金额
  237. 'changeMoney' => $fee,
  238. 'nowMoney' => bcsub($nowMoney,$fee,2),
  239. 'rate' => WX_RATE,
  240. 'fee' => $fee,
  241. 'type' => StatusCode::$delete,
  242. 'isPayment' => StatusCode::$standard,
  243. 'isPlatform' => StatusCode::$delete,
  244. 'source' => 1,
  245. 'describe' => '本次微信交易支付金额:'.$tradeMoney.'元,微信交易手续费:'.$fee.'元',
  246. ];
  247. $finalBalance = bcsub($finalBalance,$fee,2);
  248. $logs[] = $step_two;
  249. }
  250. $return = [
  251. 'logs' => $logs,
  252. 'updateBalance' => [
  253. 'shopId' => $shop['id'],
  254. 'merchantId' => $shop['merchantId'],
  255. 'balance' => $finalBalance,
  256. 'orderNum' => $finalOrderNum,
  257. ],
  258. ];
  259. return ResultWrapper::success($return);
  260. }
  261. /**
  262. * Doc: (des="添加流水记录")
  263. * User: XMing
  264. * Date: 2020/12/7
  265. * Time: 3:48 下午
  266. * @param array $params
  267. * @return ResultWrapper
  268. */
  269. public function add(array $params): ResultWrapper
  270. {
  271. $insert = self::buildFlowData($params);
  272. $result = $this->objDMerchantFlow->insert($insert);
  273. if ($result === false){
  274. return ResultWrapper::fail($this->objDMerchantFlow->error,ErrorCode::$dberror);
  275. }
  276. return ResultWrapper::success(true);
  277. }
  278. /**
  279. * Doc: (des="构建流水记录数据")
  280. * User: XMing
  281. * Date: 2020/12/7
  282. * Time: 3:50 下午
  283. * @param array $params
  284. * @return array
  285. */
  286. private static function buildFlowData(array $params): array
  287. {
  288. return [
  289. "no" => getArrayItem($params, 'no', createOrderSn(StatusCode::$orderType['saleOrder'],StatusCode::$orderType['saleOrder'],1)),
  290. //varchar(30) DEFAULT NULL COMMENT '流水号',
  291. "merchantId" => getArrayItem($params, 'merchantId', 0),
  292. //int(10) DEFAULT NULL COMMENT '商户Id',
  293. "merchantName" => getArrayItem($params, 'merchantName', ''),
  294. //varchar(30) DEFAULT NULL COMMENT '商户名称',
  295. "shopId" => getArrayItem($params, 'shopId', 0),
  296. //int(10) DEFAULT NULL COMMENT '店铺Id',
  297. "shopName" => getArrayItem($params, 'shopName', ''),
  298. //varchar(30) DEFAULT NULL COMMENT '店铺名称',
  299. "originId" => getArrayItem($params, 'originId', 0),
  300. //int(10) DEFAULT NULL COMMENT '原单据id',
  301. "originNo" => getArrayItem($params, 'originNo', ''),
  302. //varchar(30) DEFAULT NULL COMMENT '原始单号',
  303. "tradeMoney" => getArrayItem($params, 'tradeMoney', '0.00'),
  304. //decimal(10,2) NOT NULL COMMENT '流水金额 eg: 支付100元 提现100元',
  305. "payType" => getArrayItem($params, 'payType', 0),
  306. //tinyint(3) NOT NULL DEFAULT '0' COMMENT '支付方式',
  307. "originMoney" => getArrayItem($params, 'originMoney', '0.00'),
  308. //decimal(10,2) NOT NULL COMMENT '原金额',
  309. "changeMoney" => getArrayItem($params, 'changeMoney', '0.00'),
  310. //decimal(10,2) NOT NULL COMMENT '变动金额',
  311. "nowMoney" => getArrayItem($params, 'nowMoney', '0.00'),
  312. //decimal(10,2) NOT NULL COMMENT '变动后金额',
  313. "rate" => getArrayItem($params, 'rate', '0.00'),
  314. //decimal(10,4) DEFAULT NULL COMMENT '抽成比率 eg: 0.006% (0.006)',
  315. "fee" => getArrayItem($params, 'fee', '0.00'),
  316. //decimal(10,2) DEFAULT NULL COMMENT '抽成金额',
  317. "type" => getArrayItem($params, 'type', 0),
  318. //tinyint(3) DEFAULT '5' COMMENT '5加 4减',
  319. "isPayment" => getArrayItem($params, 'isPayment', 0),
  320. //tinyint(3) DEFAULT '4' COMMENT '是否是第三方支付手续费 5是 4否',
  321. "isPlatform" => getArrayItem($params,'isPlatform',0),
  322. //tinyint(3) DEFAULT '4' COMMENT '记录类型 4 商户 5 平台',
  323. "source" => getArrayItem($params, 'source', 0),
  324. //tinyint(3) DEFAULT '1' COMMENT '1支付结算 2提现',
  325. "describe" => getArrayItem($params, 'describe', ''),
  326. //varchar(50) DEFAULT NULL COMMENT '描述',
  327. "createTime" => getArrayItem($params, 'createTime', time()),
  328. //int(10) NOT NULL DEFAULT '0' COMMENT '创建时间',
  329. "updateTime" => getArrayItem($params, 'updateTime', time()),
  330. //int(10) NOT NULL DEFAULT '0' COMMENT '更新时间',
  331. ];
  332. }
  333. /**
  334. * Doc: (des="资金变动记录")
  335. * User: XMing
  336. * Date: 2020/12/9
  337. * Time: 4:30 下午
  338. * @param $selectParams
  339. * @return ResultWrapper
  340. */
  341. public function getAll($selectParams): ResultWrapper
  342. {
  343. $fields = ' * ';
  344. $countFields = ' COUNT(id) AS total ';
  345. $whereSql = '';
  346. if (isset($selectParams['isPlatform']) && !empty($selectParams['isPlatform'])){
  347. $whereSql .= ' AND isPlatform = '.$selectParams['isPlatform'];
  348. }
  349. if (isset($selectParams['shopId']) && !empty($selectParams['shopId'])){
  350. $whereSql .= ' AND shopId = '.$selectParams['shopId'];
  351. }
  352. if (isset($selectParams['originNo']) && !empty($selectParams['originNo'])){
  353. $whereSql .= ' AND originNo = '.$selectParams['originNo'];
  354. }
  355. if (isset($selectParams['source']) && !empty($selectParams['source'])){
  356. $whereSql .= ' AND source = '.$selectParams['source'];
  357. }
  358. if (isset($selectParams['startTime']) && !empty($selectParams['startTime'])){
  359. $whereSql .= ' AND startTime BETWEEN '.$selectParams['startTime'].' AND '.$selectParams['endTime'];
  360. }
  361. $countSql = 'SELECT '.$countFields.' FROM qianniao_merchant_flow_'.$this->onlineEnterpriseId.' WHERE id IS NOT NULL '.$whereSql;
  362. $count = $this->objDMerchantFlow->query($countSql);
  363. $whereSql .= ' ORDER BY createTime DESC ';
  364. if (isset($selectParams['limit']) && !empty($selectParams['limit'])){
  365. $whereSql .= ' LIMIT '.$selectParams['offset'].','.$selectParams['limit'];
  366. }
  367. $sql = 'SELECT '.$fields.' FROM qianniao_merchant_flow_'.$this->onlineEnterpriseId.' WHERE id IS NOT NULL '.$whereSql;
  368. $lists = $this->objDMerchantFlow->query($sql);
  369. if ($lists === false){
  370. return ResultWrapper::fail($this->objDMerchantFlow->error,ErrorCode::$dberror);
  371. }
  372. $ret = [
  373. 'data' => $lists,
  374. 'total' => isset($count[0]['total']) ? $count[0]['total'] : 0
  375. ];
  376. return ResultWrapper::success($ret);
  377. }
  378. }