CoachUser.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. <?php
  2. namespace App\Models;
  3. use App\Models\Order;
  4. use App\Models\Wallet;
  5. use App\Models\ShopInfo;
  6. use App\Models\CoachScore;
  7. use App\Models\MemberUser;
  8. use App\Enums\ProjectStatus;
  9. use App\Models\CoachProject;
  10. use App\Models\OrderComment;
  11. use App\Traits\HasStateText;
  12. use App\Models\CoachLocation;
  13. use App\Models\CoachStatistic;
  14. use App\Enums\TechnicianStatus;
  15. use App\Models\CoachInfoRecord;
  16. use App\Models\CoachQualRecord;
  17. use App\Models\CoachRealRecord;
  18. use App\Models\OrderGrabRecord;
  19. use App\Models\ShopCoachService;
  20. use App\Enums\TechnicianLocationType;
  21. use Illuminate\Database\Eloquent\SoftDeletes;
  22. use Slowlyo\OwlAdmin\Models\BaseModel as Model;
  23. /**
  24. * 技师用户模型
  25. */
  26. class CoachUser extends Model
  27. {
  28. use HasStateText, SoftDeletes;
  29. protected $table = 'coach_users';
  30. protected $guarded = [];
  31. /**
  32. * 状态枚举类
  33. */
  34. protected string $stateEnumClass = TechnicianStatus::class;
  35. /**
  36. * @Author FelixYin
  37. *
  38. * @description 技师关联信息
  39. */
  40. public function info()
  41. {
  42. return $this->hasOne(CoachInfoRecord::class, 'id', 'info_record_id');
  43. }
  44. /**
  45. * 获取技师关联的用户
  46. */
  47. public function user()
  48. {
  49. return $this->belongsTo(MemberUser::class, 'user_id');
  50. }
  51. /**
  52. * 获取技师的统计数据
  53. */
  54. public function statistic()
  55. {
  56. return $this->hasOne(CoachStatistic::class, 'coach_id');
  57. }
  58. /**
  59. * @Author FelixYin
  60. *
  61. * @description 技师所属会员
  62. */
  63. public function member()
  64. {
  65. return $this->belongsTo(MemberUser::class, 'user_id', 'id');
  66. }
  67. /**
  68. * @Author FelixYin
  69. *
  70. * @description 基本信息认证记录
  71. */
  72. public function infoRecords()
  73. {
  74. return $this->hasMany(CoachInfoRecord::class, 'coach_id', 'id');
  75. }
  76. /**
  77. * @Author FelixYin
  78. *
  79. * @description 技师关联资质信息
  80. */
  81. public function qual()
  82. {
  83. return $this->hasOne(CoachQualRecord::class, 'id', 'qualification_record_id');
  84. }
  85. /**
  86. * @Author FelixYin
  87. *
  88. * @description 技师关联评分
  89. */
  90. public function score()
  91. {
  92. return $this->hasOne(CoachScore::class, 'coach_id', 'id');
  93. }
  94. /**
  95. * @Author FelixYin
  96. *
  97. * @description 技师关联定位
  98. */
  99. public function locations()
  100. {
  101. return $this->hasMany(CoachLocation::class, 'coach_id', 'id');
  102. }
  103. /**
  104. * @Author FelixYin
  105. *
  106. * @description 技师关联订单
  107. */
  108. public function orders()
  109. {
  110. return $this->hasMany(Order::class, 'coach_id', 'id');
  111. }
  112. /**
  113. * @Author FelixYin
  114. *
  115. * @description 技师关联抢单记录
  116. */
  117. public function grabRecords()
  118. {
  119. return $this->hasMany(OrderGrabRecord::class, 'coach_id', 'id');
  120. }
  121. /**
  122. * @Author FelixYin
  123. *
  124. * @description 技师关联评论
  125. */
  126. public function comments()
  127. {
  128. return $this->hasMany(OrderComment::class, 'coach_id', 'id');
  129. }
  130. /**
  131. * @Author FelixYin
  132. *
  133. * @description 技师关联钱包
  134. */
  135. public function wallet()
  136. {
  137. return $this->morphOne(Wallet::class, 'owner');
  138. }
  139. /**
  140. * @Author FelixYin
  141. *
  142. * @description 技师所属店铺
  143. */
  144. public function shop()
  145. {
  146. return $this->belongsTo(ShopInfo::class, 'shop_id', 'shop_id', 'id');
  147. }
  148. /**
  149. * @Author FelixYin
  150. *
  151. * @description 技师关联店铺开通服务
  152. */
  153. public function shopOpenService()
  154. {
  155. return $this->hasMany(ShopCoachService::class, 'coach_id', 'id');
  156. }
  157. /**
  158. * @Author FelixYin
  159. *
  160. * @description 技师关联实名信息
  161. */
  162. public function real()
  163. {
  164. return $this->hasOne(CoachRealRecord::class, 'id', 'real_auth_record_id');
  165. }
  166. /**
  167. * @Author FelixYin
  168. *
  169. * @description 技师开通项目
  170. */
  171. public function projects()
  172. {
  173. return $this->hasMany(CoachProject::class, 'coach_id', 'id');
  174. }
  175. /**
  176. * @Author FelixYin
  177. *
  178. * @description 技师关联资质记录
  179. */
  180. public function qualRecords()
  181. {
  182. return $this->hasMany(CoachQualRecord::class, 'coach_id', 'id');
  183. }
  184. /**
  185. * @Author FelixYin
  186. *
  187. * @description 技师关联实名认证记录
  188. */
  189. public function realAuthRecords()
  190. {
  191. return $this->hasMany(CoachRealRecord::class, 'coach_id', 'id');
  192. }
  193. /**
  194. * 验证技师状态是否正常
  195. *
  196. * @param string|null $message 自定义错误消息
  197. * @throws \Illuminate\Http\Exceptions\HttpResponseException 当技师状态异常时抛出异常
  198. */
  199. public function validateActiveStatus(?string $message = null): void
  200. {
  201. abort_if(
  202. $this->state != TechnicianStatus::ACTIVE->value,
  203. 422,
  204. $message ?? '技师状态异常'
  205. );
  206. }
  207. /**
  208. * 创建或更新技师项目关联
  209. *
  210. * @param int $projectId 项目ID
  211. * @param int $state 项目状态
  212. * @return CoachProject 返回创建或更新的技师项目关联实例
  213. */
  214. public function updateOrCreateProjectRelation(int $projectId, int $state): CoachProject
  215. {
  216. return $this->projects()->updateOrCreate(
  217. ['project_id' => $projectId],
  218. [
  219. 'state' => $state,
  220. 'discount_amount' => 0.00, // 默认折扣金额
  221. 'service_gender' => 0, // 默认服务性别(不限)
  222. 'service_distance' => 0, // 默认服务距离
  223. 'traffic_fee_type' => 2, // 默认交通费类型(双程)
  224. ]
  225. );
  226. }
  227. /**
  228. * 获取最新的基本信息审核记录
  229. * 通过 latest() 获取最新的一条记录
  230. *
  231. * 业务逻辑:
  232. * 1. 建立与基本信息记录表的一对一关联
  233. * 2. 按创建时间倒序排序
  234. * 3. 获取最新的一条记录
  235. *
  236. * @return \Illuminate\Database\Eloquent\Relations\HasOne
  237. */
  238. public function latestInfoRecord()
  239. {
  240. // 一对一关联,并按创建时间倒序获取最新记录
  241. return $this->hasOne(CoachInfoRecord::class, 'coach_id')
  242. ->latest();
  243. }
  244. /**
  245. * 获取最新的实名认证审核记录
  246. * 通过 latest() 获取最新的一条记录
  247. *
  248. * 业务逻辑:
  249. * 1. 建立与实名认证记录表的一对一关联
  250. * 2. 按创建时间倒序排序
  251. * 3. 获取最新的一条记录
  252. *
  253. * @return \Illuminate\Database\Eloquent\Relations\HasOne
  254. */
  255. public function latestRealRecord()
  256. {
  257. // 一对一关联,并按创建时间倒序获取最新记录
  258. return $this->hasOne(CoachRealRecord::class, 'coach_id')
  259. ->latest();
  260. }
  261. /**
  262. * 获取最新的资质认证审核记录
  263. * 通过 latest() 获取最新的一条记录
  264. *
  265. * @return \Illuminate\Database\Eloquent\Relations\HasOne
  266. */
  267. public function latestQualRecord()
  268. {
  269. // 一对一关联,并按创建时间倒序获取最新记录
  270. return $this->hasOne(CoachQualRecord::class, 'coach_id')
  271. ->latest();
  272. }
  273. /**
  274. * 获取常用位置
  275. * 只获取类型为常用位置的记录
  276. *
  277. * @return \Illuminate\Database\Eloquent\Relations\HasOne
  278. */
  279. public function commonLocation()
  280. {
  281. // 一对一关联,并限定位置类型为常用位置
  282. return $this->hasOne(CoachLocation::class, 'coach_id')
  283. ->where('type', TechnicianLocationType::COMMON->value);
  284. }
  285. /**
  286. * 获取技师统计数据
  287. * 包含订单数、评分等统计信息
  288. *
  289. * @return \Illuminate\Database\Eloquent\Relations\HasOne
  290. */
  291. public function statistics()
  292. {
  293. // 一对一关联技师统计数据
  294. return $this->hasOne(CoachStatistic::class, 'coach_id');
  295. }
  296. }