InspectionService.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. <?php
  2. namespace app\common\Service;
  3. use app\common\model\inspection\InspectionApplication;
  4. use think\Db;
  5. use think\Exception;
  6. use app\common\exception\BusinessException;
  7. /**
  8. * 验货员申请服务类
  9. */
  10. class InspectionService
  11. {
  12. /**
  13. * 创建验货员申请
  14. * @param int $userId 用户ID
  15. * @param array $data 申请数据
  16. * @return InspectionApplication
  17. * @throws Exception
  18. */
  19. public static function createApplication($userId, $data)
  20. {
  21. // 检查用户是否可以申请
  22. if (!InspectionApplication::canApply($userId)) {
  23. throw new BusinessException('您已有申请记录,请勿重复申请');
  24. }
  25. // 检查手机号是否已被使用
  26. if (InspectionApplication::isPhoneApplied($data['phone'])) {
  27. throw new BusinessException('该手机号已被其他用户申请');
  28. }
  29. // 获取用户信息,获取密码、盐值和头像
  30. $user = \app\common\model\User::get($userId);
  31. if (!$user) {
  32. throw new BusinessException('用户信息不存在');
  33. }
  34. // 补充数据
  35. $data['user_id'] = $userId;
  36. $data['apply_time'] = time();
  37. $data['audit_status'] = InspectionApplication::AUDIT_STATUS_PENDING;
  38. $data['audit_time'] = 0;
  39. $data['reject_reason'] = '';
  40. // 添加用户的认证信息
  41. $data['password'] = $user->password ?: '';
  42. $data['salt'] = $user->salt ?: '';
  43. $data['avatar'] = $user->avatar ?: '';
  44. // 启动事务
  45. Db::startTrans();
  46. try {
  47. $application = InspectionApplication::create($data);
  48. // 提交事务
  49. Db::commit();
  50. return $application;
  51. } catch (Exception $e) {
  52. // 回滚事务
  53. Db::rollback();
  54. throw new BusinessException('申请提交失败:' . $e->getMessage());
  55. }
  56. }
  57. /**
  58. * 获取申请详情
  59. * @param int $applicationId 申请ID
  60. * @param int $userId 用户ID
  61. * @return InspectionApplication|null
  62. * @throws Exception
  63. */
  64. public static function getApplicationDetail($applicationId = 0, $userId = 0)
  65. {
  66. $application = InspectionApplication::where(function($query) use ($applicationId,$userId){
  67. if($applicationId){
  68. $query->where('inspection_application.id', $applicationId);
  69. }
  70. if($userId){
  71. $query->where('inspection_application.user_id', $userId);
  72. }
  73. })
  74. ->find();
  75. // if (!$application) {
  76. // throw new BusinessException('申请记录不存在或无权访问');
  77. // }
  78. return $application;
  79. }
  80. /**
  81. * 获取用户申请列表
  82. * @param int $userId 用户ID
  83. * @return \think\Collection
  84. */
  85. public static function getApplicationList($userId)
  86. {
  87. return InspectionApplication::where('inspection_application.user_id', $userId)
  88. ->order('inspection_application.id', 'desc')
  89. ->select();
  90. }
  91. /**
  92. * 查询用户申请信息
  93. * @param int $userId 用户ID
  94. * @param bool $withUser 是否关联用户信息
  95. * @return InspectionApplication|null
  96. */
  97. public static function getUserApplication($userId, $withUser = false,$withSupplier = false)
  98. {
  99. $query = InspectionApplication::where('user_id', $userId);
  100. if ($withUser) {
  101. $query->with(['user']);
  102. }
  103. if ($withSupplier) {
  104. $query->with(['supplier']);
  105. }
  106. return $query->order('id', 'desc')->find();
  107. }
  108. /**
  109. * 查询用户申请信息
  110. * @param int $userId 用户ID
  111. * @param bool $withUser 是否关联用户信息
  112. * @return InspectionApplication|null
  113. */
  114. public static function getApplicationById($id = 0 , $withUser = false,$withSupplier = false)
  115. {
  116. $query = InspectionApplication::where('id', $id);
  117. if ($withUser) {
  118. $query->with(['user']);
  119. }
  120. if ($withSupplier) {
  121. $query->with(['supplier']);
  122. }
  123. return $query->order('id', 'desc')->find();
  124. }
  125. /**
  126. * 修改申请信息
  127. * @param int $applicationId 申请ID
  128. * @param int $userId 用户ID
  129. * @param array $data 修改数据
  130. * @return InspectionApplication
  131. * @throws Exception
  132. */
  133. public static function updateApplication($applicationId, $userId, $data)
  134. {
  135. $application = InspectionApplication::where('inspection_application.id', $applicationId)
  136. ->where('inspection_application.user_id', $userId)
  137. ->find();
  138. if (!$application) {
  139. throw new BusinessException('申请记录不存在或无权访问');
  140. }
  141. if (!$application->canEdit()) {
  142. throw new BusinessException('该申请状态下不允许修改');
  143. }
  144. // 检查手机号是否已被其他用户使用
  145. if (InspectionApplication::isPhoneApplied($data['phone'], $applicationId)) {
  146. throw new BusinessException('该手机号已被其他用户申请');
  147. }
  148. // 更新申请信息
  149. $application->allowField(true)->save($data);
  150. return $application;
  151. }
  152. /**
  153. * 检查申请资格
  154. * @param int $userId 用户ID
  155. * @return array
  156. */
  157. public static function checkEligibility($userId)
  158. {
  159. $application = InspectionApplication::where('inspection_application.user_id', $userId)
  160. ->order('inspection_application.id', 'desc')
  161. ->find();
  162. if (!$application) {
  163. return [
  164. 'can_apply' => true,
  165. 'status' => 'no_application',
  166. 'message' => '您还未申请验货员,可以提交申请'
  167. ];
  168. }
  169. switch ($application->audit_status) {
  170. case InspectionApplication::AUDIT_STATUS_PENDING:
  171. return [
  172. 'can_apply' => false,
  173. 'status' => 'pending',
  174. 'message' => '您的申请正在审核中,请耐心等待',
  175. 'application' => $application
  176. ];
  177. case InspectionApplication::AUDIT_STATUS_PASSED:
  178. return [
  179. 'can_apply' => false,
  180. 'status' => 'passed',
  181. 'message' => '您已是认证验货员',
  182. 'application' => $application
  183. ];
  184. case InspectionApplication::AUDIT_STATUS_REJECTED:
  185. return [
  186. 'can_apply' => true,
  187. 'status' => 'rejected',
  188. 'message' => '您的申请被驳回,可以重新申请',
  189. 'reject_reason' => $application->reject_reason,
  190. 'application' => $application
  191. ];
  192. default:
  193. return [
  194. 'can_apply' => true,
  195. 'status' => 'unknown',
  196. 'message' => '状态异常,可以重新申请'
  197. ];
  198. }
  199. }
  200. /**
  201. * 管理员审核申请
  202. * @param int $applicationId 申请ID
  203. * @param int $auditStatus 审核状态
  204. * @param string $rejectReason 驳回原因(可选)
  205. * @param int $supplierId 供应商ID(可选)
  206. * @return bool
  207. * @throws Exception
  208. */
  209. public static function auditApplication($applicationId, $auditStatus, $rejectReason = '', $supplierId = 0)
  210. {
  211. $application = InspectionApplication::get($applicationId);
  212. if (!$application) {
  213. throw new BusinessException('申请记录不存在');
  214. }
  215. if ($application->audit_status != InspectionApplication::AUDIT_STATUS_PENDING) {
  216. throw new BusinessException('该申请已被审核,无法重复操作');
  217. }
  218. // 验证审核状态
  219. $validStatuses = [
  220. InspectionApplication::AUDIT_STATUS_PASSED,
  221. InspectionApplication::AUDIT_STATUS_REJECTED
  222. ];
  223. if (!in_array($auditStatus, $validStatuses)) {
  224. throw new BusinessException('无效的审核状态');
  225. }
  226. // 如果是驳回,必须填写驳回原因
  227. if ($auditStatus == InspectionApplication::AUDIT_STATUS_REJECTED && empty($rejectReason)) {
  228. throw new BusinessException('驳回申请必须填写驳回原因');
  229. }
  230. // 如果是审核通过,检查供应商ID
  231. if ($auditStatus == InspectionApplication::AUDIT_STATUS_PASSED && empty($supplierId)) {
  232. throw new BusinessException('审核通过时必须选择绑定的供应商');
  233. }
  234. // 启动事务
  235. Db::startTrans();
  236. try {
  237. $application->audit_status = $auditStatus;
  238. $application->audit_time = time();
  239. $application->reject_reason = $rejectReason;
  240. // 审核通过时设置供应商ID,驳回时清空供应商ID
  241. if ($auditStatus == InspectionApplication::AUDIT_STATUS_PASSED) {
  242. $application->supplier_id = $supplierId;
  243. } else {
  244. $application->supplier_id = 0;
  245. }
  246. $application->save();
  247. // 提交事务
  248. Db::commit();
  249. return true;
  250. } catch (Exception $e) {
  251. // 回滚事务
  252. Db::rollback();
  253. throw new BusinessException('审核失败:' . $e->getMessage());
  254. }
  255. }
  256. /**
  257. * 获取管理员申请列表(分页)
  258. * @param array $param 查询参数
  259. * @return \think\Paginator
  260. */
  261. public static function getAdminApplicationList($param = [])
  262. {
  263. $where = [];
  264. // 审核状态筛选
  265. if (isset($param['audit_status']) && $param['audit_status'] !== '') {
  266. $where['inspection_application.audit_status'] = $param['audit_status'];
  267. }
  268. // 关键词搜索(姓名、手机号)
  269. if (!empty($param['keywords'])) {
  270. $where['inspection_application.name|inspection_application.phone'] = ['like', '%' . $param['keywords'] . '%'];
  271. }
  272. // 时间范围筛选
  273. if (!empty($param['start_time']) && !empty($param['end_time'])) {
  274. $where['inspection_application.apply_time'] = ['between', [strtotime($param['start_time']), strtotime($param['end_time'])]];
  275. }
  276. $pageSize = $param['pageSize'] ?? 20;
  277. return InspectionApplication::where($where)
  278. ->with(['user'])
  279. ->order('inspection_application.id', 'desc')
  280. ->paginate($pageSize);
  281. }
  282. }