Factory.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <?php
  2. namespace app\common\model\ps;
  3. use app\common\model\User;
  4. use fast\Random;
  5. use think\Db;
  6. use think\Exception;
  7. use think\Model;
  8. /**
  9. * 工厂
  10. */
  11. class Factory extends Model
  12. {
  13. protected $name = 'ps_factory';
  14. protected $autoWriteTimestamp = 'int';
  15. protected $createTime = 'createtime';
  16. protected $updateTime = 'updatetime';
  17. /**
  18. * 会员未入厂时:有邀请码则加入,否则创建工厂当管理员。
  19. * ThinkPHP 5 的 Config::get 只支持两级键,不能用 ps.factory.register_create_factory。
  20. * @param User $user
  21. * @param string $inviteCode
  22. * @return Factory|null
  23. * @throws Exception
  24. */
  25. public static function ensureBound(User $user, $inviteCode = '')
  26. {
  27. if ((int)$user->factory_id > 0) {
  28. return self::get($user->factory_id);
  29. }
  30. $inviteCode = strtoupper(trim((string)$inviteCode));
  31. if ($inviteCode !== '') {
  32. return self::joinByInvite($user, $inviteCode);
  33. }
  34. $factoryCfg = \think\Config::get('ps.factory');
  35. $autoCreate = true;
  36. if (is_array($factoryCfg) && array_key_exists('register_create_factory', $factoryCfg)) {
  37. $autoCreate = (bool)$factoryCfg['register_create_factory'];
  38. }
  39. if (!$autoCreate) {
  40. return null;
  41. }
  42. return self::createForOwner($user);
  43. }
  44. /**
  45. * 为新注册用户创建工厂并设为管理员
  46. * @param User $user
  47. * @return Factory
  48. */
  49. public static function createForOwner(User $user)
  50. {
  51. $name = $user->nickname ?: $user->username;
  52. $scoreCfg = \think\Config::get('ps.score') ?: [];
  53. $gift = isset($scoreCfg['register_gift']) ? (int)$scoreCfg['register_gift'] : 0;
  54. if ($gift < 0) {
  55. $gift = 0;
  56. }
  57. $factory = self::create([
  58. 'name' => $name . '的工厂',
  59. 'code' => 'F' . date('ymd') . $user->id,
  60. 'invite_code' => self::uniqueInviteCode(),
  61. 'owner_user_id' => $user->id,
  62. 'score' => $gift,
  63. 'status' => 'normal',
  64. ]);
  65. $user->save([
  66. 'factory_id' => $factory->id,
  67. 'factory_role' => 'owner',
  68. ]);
  69. return $factory;
  70. }
  71. /**
  72. * 凭邀请码加入工厂(操作员)
  73. * @param User $user
  74. * @param string $inviteCode
  75. * @return Factory
  76. * @throws Exception
  77. */
  78. public static function joinByInvite(User $user, $inviteCode)
  79. {
  80. $factory = self::where('invite_code', strtoupper(trim($inviteCode)))
  81. ->where('status', 'normal')
  82. ->find();
  83. if (!$factory) {
  84. throw new Exception('邀请码无效');
  85. }
  86. $user->save([
  87. 'factory_id' => $factory->id,
  88. 'factory_role' => 'operator',
  89. ]);
  90. return $factory;
  91. }
  92. /**
  93. * 变更工厂积分(行锁)
  94. * @param int $factoryId
  95. * @param int $score 正加负减
  96. * @param string $bizType
  97. * @param int $bizId
  98. * @param string $memo
  99. * @param int $operatorUserId
  100. * @return Factory
  101. * @throws Exception
  102. */
  103. public static function changeScore($factoryId, $score, $bizType, $bizId, $memo, $operatorUserId = 0)
  104. {
  105. if ((int)$score === 0) {
  106. return self::get($factoryId);
  107. }
  108. Db::startTrans();
  109. try {
  110. $factory = self::lock(true)->find($factoryId);
  111. if (!$factory) {
  112. throw new Exception('工厂不存在');
  113. }
  114. $before = (int)$factory->score;
  115. $after = $before + (int)$score;
  116. if ($after < 0) {
  117. throw new Exception('工厂积分不足');
  118. }
  119. $factory->save(['score' => $after]);
  120. FactoryScoreLog::create([
  121. 'factory_id' => $factoryId,
  122. 'operator_user_id' => $operatorUserId,
  123. 'score' => $score,
  124. 'before' => $before,
  125. 'after' => $after,
  126. 'biz_type' => $bizType,
  127. 'biz_id' => $bizId,
  128. 'memo' => $memo,
  129. ]);
  130. Db::commit();
  131. return $factory;
  132. } catch (\Exception $e) {
  133. Db::rollback();
  134. throw $e;
  135. }
  136. }
  137. protected static function uniqueInviteCode()
  138. {
  139. do {
  140. $code = strtoupper(Random::alnum(8));
  141. } while (self::where('invite_code', $code)->find());
  142. return $code;
  143. }
  144. }