MarketBuyer.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <?php
  2. namespace app\common\library\ps;
  3. use app\common\model\ps\Factory;
  4. use app\common\model\ps\MarketGoods;
  5. use app\common\model\ps\MarketLicense;
  6. use app\common\model\ps\MarketOrder;
  7. use app\common\model\ps\Template;
  8. use app\common\model\ps\TemplateVersion;
  9. use fast\Random;
  10. use think\Config;
  11. use think\Db;
  12. use think\Exception;
  13. /**
  14. * 模板商城购买:积分扣减(本期不接支付渠道),导入本厂私有库。
  15. * 单次:确认套打后锁定。买断:可反复套打。副本禁止再上架。
  16. */
  17. class MarketBuyer
  18. {
  19. /**
  20. * @param int $goodsId
  21. * @param string $licenseType single|buyout
  22. * @param int $userId
  23. * @return array
  24. * @throws Exception
  25. */
  26. public static function buy($goodsId, $licenseType, $userId)
  27. {
  28. $licenseType = $licenseType === 'buyout' ? 'buyout' : 'single';
  29. $factoryId = FactoryContext::requireId();
  30. $goods = MarketGoods::get($goodsId);
  31. if (!$goods || $goods['status'] !== 'on_sale') {
  32. throw new Exception('商品不存在或已下架');
  33. }
  34. if ((int)$goods['factory_id'] === (int)$factoryId) {
  35. throw new Exception('不能购买本厂上架的模板');
  36. }
  37. $price = $licenseType === 'buyout' ? (int)$goods['price_buyout'] : (int)$goods['price_single'];
  38. $source = Db::name('ps_template')->where('id', (int)$goods['template_id'])->find();
  39. if (!$source) {
  40. throw new Exception('商品模板已失效');
  41. }
  42. if ($licenseType === 'buyout') {
  43. $dup = (new Template())->where('source_template_id', $source['id'])
  44. ->where('license_type', 'market_buyout')
  45. ->find();
  46. if ($dup) {
  47. throw new Exception('本厂已买断该模板,无需重复购买');
  48. }
  49. }
  50. $marketCfg = Config::get('ps.market') ?: [];
  51. $commission = isset($marketCfg['commission_percent']) ? (int)$marketCfg['commission_percent'] : 0;
  52. if ($commission < 0) {
  53. $commission = 0;
  54. }
  55. if ($commission > 100) {
  56. $commission = 100;
  57. }
  58. Db::startTrans();
  59. try {
  60. if ($price > 0) {
  61. Factory::changeScore($factoryId, -$price, 'market_buy', $goodsId, '购买模板:' . $goods['title'], $userId);
  62. $sellerId = (int)$goods['factory_id'];
  63. if ($sellerId > 0) {
  64. $sellerGain = (int)floor($price * (100 - $commission) / 100);
  65. if ($sellerGain > 0) {
  66. Factory::changeScore($sellerId, $sellerGain, 'market_sell', $goodsId, '模板售出:' . $goods['title'], 0);
  67. }
  68. }
  69. }
  70. $copy = self::importCopy($source, $goods, $licenseType, $userId, $factoryId);
  71. $order = new MarketOrder();
  72. $order->allowField(true)->save([
  73. 'order_no' => 'M' . date('YmdHis') . Random::numeric(4),
  74. 'goods_id' => $goods['id'],
  75. 'license_type' => $licenseType,
  76. 'score' => $price,
  77. 'buyer_factory_id' => $factoryId,
  78. 'buyer_user_id' => $userId,
  79. 'seller_factory_id' => (int)$goods['factory_id'],
  80. 'copy_template_id' => $copy['id'],
  81. 'status' => 'paid',
  82. ]);
  83. $license = new MarketLicense();
  84. $license->allowField(true)->save([
  85. 'order_id' => $order->id,
  86. 'template_id' => $copy['id'],
  87. 'license_type' => $licenseType,
  88. 'remain_times' => $licenseType === 'buyout' ? -1 : 1,
  89. 'locked' => 0,
  90. ]);
  91. Db::commit();
  92. } catch (\Exception $e) {
  93. Db::rollback();
  94. throw $e;
  95. }
  96. return [
  97. 'order_no' => $order['order_no'],
  98. 'template_id' => (int)$copy['id'],
  99. 'score' => $price,
  100. 'license' => $licenseType,
  101. ];
  102. }
  103. /**
  104. * @param array $source
  105. * @param MarketGoods $goods
  106. * @param string $licenseType
  107. * @param int $userId
  108. * @param int $factoryId
  109. * @return Template
  110. */
  111. protected static function importCopy(array $source, $goods, $licenseType, $userId, $factoryId)
  112. {
  113. $versionId = (int)$goods['template_version_id'] ?: (int)$source['current_version_id'];
  114. $schema = '';
  115. if ($versionId) {
  116. $ver = Db::name('ps_template_version')->where('id', $versionId)->find();
  117. $schema = $ver ? (string)$ver['schema_json'] : '';
  118. }
  119. $tpl = new Template();
  120. $tpl->allowField(true)->save([
  121. 'creator_user_id' => $userId,
  122. 'name' => $goods['title'] ?: $source['name'],
  123. 'cover' => $goods['cover'] ?: $source['cover'],
  124. 'source' => 'market',
  125. 'license_type' => $licenseType === 'buyout' ? 'market_buyout' : 'market_single',
  126. 'locked' => 0,
  127. 'source_template_id' => (int)$source['id'],
  128. 'source_version_id' => $versionId,
  129. 'is_system' => 0,
  130. 'status' => 'normal',
  131. ]);
  132. $verRow = new TemplateVersion();
  133. $verRow->allowField(true)->save([
  134. 'template_id' => $tpl->id,
  135. 'version' => 1,
  136. 'schema_json' => $schema,
  137. 'remark' => '商城导入',
  138. ]);
  139. $tpl->save(['current_version_id' => $verRow->id]);
  140. return $tpl;
  141. }
  142. }