AgentApply.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. <?php
  2. namespace app\common\Service\commission;
  3. use app\common\model\commission\Apply as ApplyModel;
  4. use app\common\model\commission\Identity as IdentityModel;
  5. use app\common\model\commission\Agent as AgentModel;
  6. use app\common\model\Area;
  7. use app\common\Service\ShopConfigService;
  8. use app\common\Enum\AgentType;
  9. use think\Db;
  10. use think\Exception;
  11. class AgentApply
  12. {
  13. /**
  14. * 获取可用的代理商身份列表
  15. */
  16. public function getIdentityList()
  17. {
  18. return IdentityModel::getEnabledList();
  19. }
  20. /**
  21. * 提交代理商申请
  22. */
  23. public function submitApply($userId, $data)
  24. {
  25. // 验证用户是否已经有申请记录
  26. $existApply = ApplyModel::where('user_id', $userId)
  27. ->where('status', 'in', ['pending', 'approved'])
  28. ->find();
  29. if ($existApply) {
  30. if ($existApply->status == 'approved') {
  31. throw new Exception('您已经是代理商,无需重复申请');
  32. } else {
  33. throw new Exception('您已有待审核的申请,请等待审核结果');
  34. }
  35. }
  36. // 验证身份是否存在
  37. $identity = IdentityModel::where('id', $data['agent_identity_id'])
  38. ->where('status', IdentityModel::STATUS_ENABLED)
  39. ->find();
  40. if (!$identity) {
  41. throw new Exception('选择的代理商身份不存在或已禁用');
  42. }
  43. // 验证地区信息
  44. $this->validateArea($data);
  45. // 根据申请类型验证必要字段
  46. $this->validateApplyData($data);
  47. return Db::transaction(function () use ($userId, $data, $identity) {
  48. // 创建申请记录
  49. $apply = new ApplyModel();
  50. $apply->user_id = $userId;
  51. $apply->apply_type = $data['apply_type'];
  52. $apply->agent_identity_id = $data['agent_identity_id'];
  53. $apply->agent_type = $identity->agent_type; // 从身份配置获取代理商类型
  54. $apply->status = ApplyModel::STATUS_PENDING; // 设置初始状态为待审核
  55. // 地区信息 - 根据代理商类型设置需要的地区字段
  56. $requiredFields = AgentType::getRequiredAreaFields($identity->agent_type);
  57. if (in_array('province_id', $requiredFields)) {
  58. $apply->province_id = $data['province_id'] ?? null;
  59. $apply->province_name = $data['province_name'] ?? '';
  60. }
  61. if (in_array('city_id', $requiredFields)) {
  62. $apply->city_id = $data['city_id'] ?? null;
  63. $apply->city_name = $data['city_name'] ?? '';
  64. }
  65. if (in_array('district_id', $requiredFields)) {
  66. $apply->district_id = $data['district_id'] ?? null;
  67. $apply->district_name = $data['district_name'] ?? '';
  68. }
  69. // 根据申请类型填充对应字段
  70. if ($data['apply_type'] == ApplyModel::APPLY_TYPE_PERSONAL) {
  71. $apply->real_name = $data['real_name'];
  72. $apply->id_card = $data['id_card'];
  73. $apply->id_card_front = $data['id_card_front'];
  74. $apply->id_card_back = $data['id_card_back'];
  75. $apply->mobile = $data['mobile'];
  76. } else {
  77. $apply->company_name = $data['company_name'];
  78. $apply->legal_person = $data['legal_person'];
  79. $apply->legal_mobile = $data['legal_mobile'];
  80. $apply->legal_id_card = $data['legal_id_card'];
  81. $apply->legal_id_front = $data['legal_id_front'];
  82. $apply->legal_id_back = $data['legal_id_back'];
  83. $apply->business_license = $data['business_license'];
  84. }
  85. $apply->save();
  86. // 检查是否需要审核
  87. $needCheck = ShopConfigService::getConfigField('shop.commission.agent_apply_check');
  88. if (!$needCheck) {
  89. // 不需要审核,直接通过
  90. $this->approveApply($apply);
  91. }
  92. return $apply;
  93. });
  94. }
  95. /**
  96. * 验证地区信息
  97. */
  98. private function validateArea($data)
  99. {
  100. // 获取代理商身份信息
  101. $identity = IdentityModel::where('id', $data['agent_identity_id'])
  102. ->where('status', IdentityModel::STATUS_ENABLED)
  103. ->find();
  104. if (!$identity) {
  105. throw new Exception('代理商身份不存在');
  106. }
  107. // 根据代理商类型获取需要的地区字段
  108. $requiredFields = AgentType::getRequiredAreaFields($identity->agent_type);
  109. if (empty($requiredFields)) {
  110. // 普通代理商不需要地区信息
  111. return;
  112. }
  113. // 验证必需的地区字段
  114. foreach ($requiredFields as $field) {
  115. if (empty($data[$field])) {
  116. $fieldTexts = [
  117. 'province_id' => '省份',
  118. 'city_id' => '城市',
  119. 'district_id' => '区域'
  120. ];
  121. throw new Exception($fieldTexts[$field] . '不能为空');
  122. }
  123. }
  124. // 验证地区ID的有效性和层级关系
  125. $this->validateAreaIds($data, $requiredFields);
  126. }
  127. /**
  128. * 验证地区ID的有效性和层级关系
  129. */
  130. private function validateAreaIds($data, $requiredFields)
  131. {
  132. // 验证省份
  133. if (in_array('province_id', $requiredFields) && !empty($data['province_id'])) {
  134. $province = Area::where('id', $data['province_id'])->where('level', 1)->find();
  135. if (!$province) {
  136. throw new Exception('选择的省份不存在');
  137. }
  138. }
  139. // 验证城市
  140. if (in_array('city_id', $requiredFields) && !empty($data['city_id'])) {
  141. $city = Area::where('id', $data['city_id'])->where('level', 2)->find();
  142. if (!$city) {
  143. throw new Exception('选择的城市不存在');
  144. }
  145. // 验证城市是否属于选择的省份
  146. if (!empty($data['province_id']) && $city->pid != $data['province_id']) {
  147. throw new Exception('选择的城市不属于该省份');
  148. }
  149. }
  150. // 验证区域
  151. if (in_array('district_id', $requiredFields) && !empty($data['district_id'])) {
  152. $district = Area::where('id', $data['district_id'])->where('level', 3)->find();
  153. if (!$district) {
  154. throw new Exception('选择的区域不存在');
  155. }
  156. // 验证区域是否属于选择的城市
  157. if (!empty($data['city_id']) && $district->pid != $data['city_id']) {
  158. throw new Exception('选择的区域不属于该城市');
  159. }
  160. }
  161. }
  162. /**
  163. * 验证申请数据
  164. */
  165. private function validateApplyData($data)
  166. {
  167. if ($data['apply_type'] == ApplyModel::APPLY_TYPE_PERSONAL) {
  168. $requiredFields = ['real_name', 'id_card', 'id_card_front', 'id_card_back', 'mobile'];
  169. foreach ($requiredFields as $field) {
  170. if (empty($data[$field])) {
  171. throw new Exception('个人申请信息不完整');
  172. }
  173. }
  174. // 验证身份证格式
  175. if (!$this->validateIdCard($data['id_card'])) {
  176. throw new Exception('身份证号格式不正确');
  177. }
  178. } else {
  179. $requiredFields = ['company_name', 'legal_person', 'legal_mobile', 'legal_id_card', 'legal_id_front', 'legal_id_back', 'business_license'];
  180. foreach ($requiredFields as $field) {
  181. if (empty($data[$field])) {
  182. throw new Exception('企业申请信息不完整');
  183. }
  184. }
  185. // 验证法人身份证格式
  186. if (!$this->validateIdCard($data['legal_id_card'])) {
  187. throw new Exception('法人身份证号格式不正确');
  188. }
  189. }
  190. }
  191. /**
  192. * 验证身份证号格式
  193. */
  194. private function validateIdCard($idCard)
  195. {
  196. return preg_match('/^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/', $idCard);
  197. }
  198. /**
  199. * 审核通过申请
  200. */
  201. public function approveApply(ApplyModel $apply, $adminId = null)
  202. {
  203. return Db::transaction(function () use ($apply, $adminId) {
  204. // 更新申请状态
  205. $apply->status = ApplyModel::STATUS_APPROVED;
  206. $apply->admin_id = $adminId;
  207. $apply->audit_time = time();
  208. $apply->save();
  209. // 创建代理商记录
  210. $this->createAgentFromApply($apply);
  211. return $apply;
  212. });
  213. }
  214. /**
  215. * 审核拒绝申请
  216. */
  217. public function rejectApply(ApplyModel $apply, $reason, $adminId = null)
  218. {
  219. $apply->status = ApplyModel::STATUS_REJECTED;
  220. $apply->reject_reason = $reason;
  221. $apply->admin_id = $adminId;
  222. $apply->audit_time = time();
  223. return $apply->save();
  224. }
  225. /**
  226. * 根据申请信息创建代理商
  227. */
  228. private function createAgentFromApply(ApplyModel $apply)
  229. {
  230. // 检查用户是否已经是分销商
  231. $existAgent = AgentModel::where('user_id', $apply->user_id)->find();
  232. if ($existAgent) {
  233. return $existAgent;
  234. }
  235. // 获取身份信息
  236. $identity = IdentityModel::where('id', $apply->agent_identity_id)->find();
  237. // 创建分销商记录
  238. $agent = new AgentModel();
  239. $agent->user_id = $apply->user_id;
  240. $agent->level = 1; // 默认等级
  241. $agent->agent_type = $apply->agent_type;
  242. $agent->status = AgentModel::AGENT_STATUS_NORMAL;
  243. $agent->become_time = time();
  244. // 如果是区域代理商(省级、市级、区域级),设置管辖区域
  245. if (AgentType::isRegionalAgent($apply->agent_type)) {
  246. // 根据代理商类型设置对应的管辖区域
  247. if ($apply->agent_type == AgentType::PROVINCE && !empty($apply->province_id)) {
  248. $agent->manage_province_id = $apply->province_id;
  249. } elseif ($apply->agent_type == AgentType::CITY) {
  250. if (!empty($apply->province_id)) {
  251. $agent->manage_province_id = $apply->province_id;
  252. }
  253. if (!empty($apply->city_id)) {
  254. $agent->manage_city_id = $apply->city_id;
  255. }
  256. } elseif ($apply->agent_type == AgentType::DISTRICT) {
  257. if (!empty($apply->province_id)) {
  258. $agent->manage_province_id = $apply->province_id;
  259. }
  260. if (!empty($apply->city_id)) {
  261. $agent->manage_city_id = $apply->city_id;
  262. }
  263. if (!empty($apply->district_id)) {
  264. $agent->manage_district_id = $apply->district_id;
  265. }
  266. }
  267. }
  268. $agent->save();
  269. return $agent;
  270. }
  271. /**
  272. * 获取用户的申请记录
  273. */
  274. public function getUserApply($userId)
  275. {
  276. return ApplyModel::where('user_id', $userId)
  277. ->with(['identity', 'province', 'city', 'district'])
  278. ->order('id desc')
  279. ->find();
  280. }
  281. }