diff --git a/app/common/dao/marketing/AgentDao.php b/app/common/dao/marketing/AgentDao.php new file mode 100644 index 0000000..60cd5fd --- /dev/null +++ b/app/common/dao/marketing/AgentDao.php @@ -0,0 +1,83 @@ +where('is_del',0) + ->when(isset($params['id']) && $params['id'] !== '',function($query) use ($params){ + $query->where('id', (int)$params['id']); + }) + ->when(isset($params['uid']) && $params['uid'] !== '',function($query) use ($params){ + $query->where('uid', (int)$params['uid']); + }) + ->when(isset($params['pid']) && $params['pid'] !== '',function($query) use ($params){ + $query->where('pid', (int)$params['pid']); + }) + ->when(isset($params['contact_name']) && $params['contact_name'] !== '',function($query) use ($params){ + $query->where('contact_name', 'like', "%{$params['contact_name']}%"); + }) + ->when(isset($params['contact_phone']) && $params['contact_phone'] !== '',function($query) use ($params){ + $query->where('contact_phone', $params['contact_phone']); + }) + ->when(isset($params['agent_type']) && $params['agent_type'] !== '',function($query) use ($params){ + $query->where('agent_type', (int)$params['agent_type']); + }) + ->with([ + 'user' => function($query){ + $query->field('uid,nickname,avatar'); + }, + 'province' => function($query){ + $query->field('id,name as province_name,code as province_code')->bind(['province_name', 'province_code']); + }, + 'city' => function($query){ + $query->field('id,name as city_name,code as city_code')->bind(['city_name', 'city_code']); + }, + 'area' => function($query){ + $query->field('id,name as area_name,code as area_code')->bind(['area_name', 'area_code']); + }, + 'street' => function($query){ + $query->field('id,name as street_name,code as street_code')->bind(['street_name', 'street_code']); + }, + 'mer' => function($query){ + $query->field('mer_id,mer_name,mer_avatar'); + }, + 'merList' => function($query){ + $query->field('agent_id,mer_name,mer_avatar'); + }, + 'parent' => function($query){ + $query->field('id,uid,agent_type') + ->with([ + 'user' => function($query){ + $query->field('uid,nickname,avatar')->bind(['nickname','avatar']); + } + ]); + }, + ]) + ->order('create_time DESC,id DESC') + ->append(['only_key','mer_id_list','children_count']); + } + + + + + + + + +} diff --git a/app/common/dao/system/merchant/MerchantDao.php b/app/common/dao/system/merchant/MerchantDao.php index be3a8ab..c94a238 100644 --- a/app/common/dao/system/merchant/MerchantDao.php +++ b/app/common/dao/system/merchant/MerchantDao.php @@ -71,6 +71,9 @@ class MerchantDao extends BaseDao ->when(isset($where['mer_id']) && $where['mer_id'] !== '', function ($query) use ($where) { $query->where('mer_id', $where['mer_id']); }) + ->when(isset($where['mer_id_list']) && $where['mer_id_list'] !== '', function ($query) use ($where) { + $query->whereIn('mer_id', $where['mer_id_list']); + }) ->when(isset($where['category_id']) && $where['category_id'] !== '', function ($query) use ($where) { $query->whereIn('category_id', is_array($where['category_id']) ? $where['category_id'] : explode(',', $where['category_id'])); }) diff --git a/app/common/model/BaseModel.php b/app/common/model/BaseModel.php index af3cc0f..2779dd0 100644 --- a/app/common/model/BaseModel.php +++ b/app/common/model/BaseModel.php @@ -7,6 +7,7 @@ namespace app\common\model; use think\db\BaseQuery; +use think\facade\Db; use think\Model; /** @@ -63,4 +64,39 @@ abstract class BaseModel extends Model return self::getInstance()->db($scope); } + public static function batchUpdate(array $update, $whenField = 'id', $whereField = 'id', $raw = false){ + $when = []; + $ids = []; + foreach ($update as $sets) { + # 跳过没有更新主键的数据 + if (!isset($sets[$whenField])) { + continue; + } + $whenValue = $sets[$whenField]; + + foreach ($sets as $fieldName => $value) { + #主键不需要被更新 + if ($fieldName == $whenField) { + array_push($ids, $value); + continue; + }; + if ($raw) { + $when[$fieldName][] = "when {$whenValue} then {$value}"; + } else { + $when[$fieldName][] = "when '{$whenValue}' then '{$value}'"; + } + } + } + + # 没有更新的条件id + if (!$when) return false; + $query = self::whereIn($whereField, $ids); + # 组织sql + foreach ($when as $fieldName => &$item) { + $item = Db::raw("case $whenField " . implode(' ', $item) . ' end '); + } + + return $query->update($when); + } + } diff --git a/app/common/model/marketing/Agent.php b/app/common/model/marketing/Agent.php new file mode 100644 index 0000000..19cb776 --- /dev/null +++ b/app/common/model/marketing/Agent.php @@ -0,0 +1,87 @@ +uid ?? '') . '_' . ($this->agent_type ?? ''); + } + /** + * Common: 获取器 —— 获取配送商关联的商户 + * Author: wu-hui + * Time: 2024/01/25 17:58 + * @return array|string + */ + public function getMerIdListAttr(){ + if(($this->agent_type ?? 0) == 8 && ($this->id ?? 0) > 0){ + return Merchant::where('agent_id',$this->id)->column('mer_id'); + } + + return []; + } + /** + * Common: 获取器 —— 获取下级数量(直属) + * Author: wu-hui + * Time: 2024/01/25 19:06 + * @return int + */ + public function getChildrenCountAttr():int{ + if(($this->id ?? 0) > 0){ + return self::where('pid',$this->id)->count(); + } + return 0; + } + + public function user(){ + return $this->hasOne(User::class, 'uid', 'uid'); + } + public function parent(){ + return $this->hasOne(self::class, 'id', 'pid'); + } + public function province(){ + return $this->hasOne(CityArea::class, 'id', 'province_id'); + } + public function city(){ + return $this->hasOne(CityArea::class, 'id', 'city_id'); + } + public function area(){ + return $this->hasOne(CityArea::class, 'id', 'area_id'); + } + public function street(){ + return $this->hasOne(CityArea::class, 'id', 'street_id'); + } + public function mer(){ + return $this->hasOne(Merchant::class, 'mer_id', 'mer_id'); + } + public function merList(){ + return $this->hasMany(Merchant::class, 'agent_id', 'id'); + } +} diff --git a/app/common/repositories/marketing/AgentRepository.php b/app/common/repositories/marketing/AgentRepository.php new file mode 100644 index 0000000..6927bb3 --- /dev/null +++ b/app/common/repositories/marketing/AgentRepository.php @@ -0,0 +1,206 @@ +dao = $dao; + } + /** + * Common: 获取信息列表 + * Author: wu-hui + * Time: 2024/01/24 15:41 + * @param array $params + * @param int $page + * @param int $limit + * @return array + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function getList(array $params,int $page,int $limit):array{ + $query = $this->dao->searchList($params); + $count = $query->count(); + $list = $query->page($page,$limit)->select(); + + return compact('count','list'); + } + + + /** + * Common: 代理添加/编辑 + * Author: wu-hui + * Time: 2024/01/25 9:03 + * @param int $agentId + * @param array $data + * @param array $childrenList + * @return mixed + */ + public function editInfo(int $agentId, array $data, array $childrenList){ + return Db::transaction(function() use ($agentId, $data, $childrenList){ + // 处理当前角色用户信息 + if($agentId > 0) $this->currentRoleHandle($agentId, $data); + // 处理子类信息 + if(count($childrenList) > 0) $this->childrenListHandle($agentId, $childrenList); + }); + } + /** + * Common: 代理添加/编辑 —— 处理当前角色信息 + * Author: wu-hui + * Time: 2024/01/25 9:03 + * @param int $agentId + * @param array $data + */ + private function currentRoleHandle(int $agentId,array $data){ + // 修改基本信息 + $keys = array_flip((array)[ + "uid", + "pid", + "agent_type", + "agent_stock", + "contact_name", + "contact_phone", + "province_id", + "city_id", + "area_id", + "street_id", + "address", + "lat", + "lng", + "mer_id" + ]); + $updateInfo = array_intersect_key($data, $keys); + Agent::update($updateInfo,['id'=>$agentId]); + // 修改配送商 - 商户关联信息 + $merIdList = is_array($data['mer_id_list']) ? $data['mer_id_list'] : []; + if(count($merIdList) > 0){ + // 删除已经存在的关联信息 + Merchant::update(['agent_id' => null],['agent_id'=>$agentId]); + // 建立新的关联信息 + Merchant::whereIn('mer_id',$data['mer_id_list'])->update(['agent_id' => $agentId]); + } + } + /** + * Common: 代理添加/编辑 —— 处理子类信息 + * Author: wu-hui + * Time: 2024/01/25 17:45 + * @param int $agentId + * @param array $childrenList + * @throws \think\db\exception\DbException + */ + private function childrenListHandle(int $agentId,array $childrenList){ + $insertData = []; + $updateData = []; + $merUpdateData = []; + $keys = array_flip((array)[ + "id", + "uid", + "pid", + "agent_type", + "agent_stock", + "contact_name", + "contact_phone", + "province_id", + "city_id", + "area_id", + "street_id", + "address", + "lat", + "lng", + "mer_id" + ]); + // 循环:区分对应的操作 + foreach($childrenList as $childrenItem){ + unset($childrenItem['user']); + $childrenItemId = $childrenItem['id'] ?? 0; + $handleData = array_intersect_key($childrenItem, $keys); + $handleData['pid'] = $agentId; + // 判断:如果为配送商 处理商户关联信息 + if($childrenItem['agent_type'] == 8){ + // 判断:应该修改还是编辑 + if((int)$childrenItemId > 0) $this->dao->update($childrenItemId,$handleData); + else $childrenItemId = Agent::insertGetId($handleData); + // 处理商户关联信息 + foreach($childrenItem['mer_id_list'] as $merId){ + $merUpdateData[] = [ + 'mer_id' => $merId, + 'agent_id' => $childrenItemId + ]; + } + }else{ + // 判断:应该修改还是编辑 + if((int)$childrenItemId > 0) $updateData[] = $handleData; + else $insertData[] = $handleData; + } + } + // 获取需要删除的数据的id 删除思路:先获取总数据、对修改数据比较、删除缺少的项 + $allIds = $this->dao->searchList([])->where('pid',$agentId)->column('id'); + $updateIds = array_column($updateData,'id'); + $delIds = array_diff($allIds,$updateIds); + + // 处理结果 进行对应的操作;必须按照先删除、在修改、最后添加的顺序进行 + if(count($delIds) > 0) Agent::whereIn('id',$delIds)->where('agent_type','<>',8)->update(['is_del'=>1]); + if(count($updateData) > 0) Agent::batchUpdate(array_values($updateData)); + if(count($insertData) > 0) $this->dao->insertAll($insertData); + if(count($merUpdateData) > 0) { + // 删除已经存在的关联信息 + Merchant::whereIn('agent_id',array_column($childrenList,'id'))->update(['agent_id' => null]); + // 建立新的关联信息 + Merchant::batchUpdate(array_values($merUpdateData),'mer_id','mer_id'); + } + } + /** + * Common: 代理添加/编辑 —— 获取需要编辑的信息 + * Author: wu-hui + * Time: 2024/01/24 16:57 + * @param $params + * @return array + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function getEditInfo($params){ + // 获取当前信息 编辑类型:0=发起人管理,1=发起人,2=省公司,3=省合伙人(外勤),4=省合伙人(内勤),5=区县运营商,6=区县合伙人,7=餐厅,8=配送商 + if((int)$params['agent_id'] > 0) { + // 非发起人管理:存在info及children_list + $info = $this->dao->searchList(['id' => $params['agent_id']])->findOrEmpty(); + $childrenList = $this->dao + ->searchList(['pid' => $params['agent_id']]) + ->select() + ->toArray(); + } + else{ + // 发起人管理:仅存在children_list + $childrenList = $this->dao + ->searchList(['pid' => 0,'agent_type' => 1]) + ->select() + ->toArray(); + } + // 信息处理及返回 + $childrenList = array_column($childrenList,null,'only_key'); + + return [ + 'info' => $info ?? [], + 'children_list' => $childrenList + ]; + } + + + + + + + + + + +} diff --git a/app/controller/admin/marketing/Agent.php b/app/controller/admin/marketing/Agent.php new file mode 100644 index 0000000..7b076c0 --- /dev/null +++ b/app/controller/admin/marketing/Agent.php @@ -0,0 +1,219 @@ +getPage(); + $params = $this->request->params(['uid','agent_type','contact_name','contact_phone']); + $data = app()->make(AgentRepository::class)->getList((array)$params,(int)$page,(int)$limit); + + return app('json')->success($data); + } + /** + * Common: 编辑信息 + * Author: wu-hui + * Time: 2024/01/24 16:05 + * @return mixed + */ + public function editInfo(){ + // 参数获取 + $params = $this->checkParams(); + // 数据处理 + app()->make(AgentRepository::class)->editInfo((int)$params['agentId'],(array)$params['data'],(array)$params['childrenList']); + + + return app('json')->success('操作成功'); + } + /** + * Common: 编辑参数获取 & 参数校验 + * Author: wu-hui + * Time: 2024/01/24 14:16 + * @return array + */ + public function checkParams(){ + // 参数获取 + $data = $this->request->params([ + ['uid',0], + ['pid',0], + ['agent_type',0], + ['agent_stock',0], + 'contact_name', + 'contact_phone', + ['province_id',0], + ['city_id', 0], + ['area_id', 0], + ['street_id', 0], + 'address', + 'lat', + 'lng', + ['mer_id', 0], + ['mer_id_list', []], + ]); + $agentId = (int)$this->request->param('id'); + $childrenList = $this->request->param('children_list'); + // 判断:如果$agentId 为空或者0则当前操作为编辑发起人,至少有一个发起人信息 + if($agentId <= 0){ + if(count($childrenList) <= 0) throw new ValidateException('请至少添加一个发起人!'); + $agentStock = (float)array_sum(array_column($childrenList,'agent_stock')); + if($agentStock != 100) throw new ValidateException('所有发起人的股份总和必须等于100!'); + } + // 循环判断:$childrenList 的数据是否完善 类型:1=发起人,2=省公司,3=省合伙人(外勤),4=省合伙人(内勤),5=区县运营商,6=区县合伙人,7=餐厅,8=配送商 + foreach($childrenList as $childrenItem){ + if(empty($childrenItem['contact_name'])) throw new ValidateException('请输入联系人姓名!'); + if(empty($childrenItem['contact_phone'])) throw new ValidateException('请输入联系人电话!'); + if(isPhone($childrenItem['contact_phone'])) throw new ValidateException('请输入正确的联系人电话!'); + // 判断:根据当前角色判断 数据 + switch((int)$childrenItem['agent_type']){ + case 1: + if((float)$childrenItem['agent_stock'] <= 0) throw new ValidateException('发起人的股份必须大于0!'); + break; + case 2: + case 3: + case 4: + if((float)$childrenItem['province_id'] <= 0) throw new ValidateException('请完善地区信息!'); + break; + case 5: + case 6: + if((float)$childrenItem['province_id'] <= 0) throw new ValidateException('请完善地区信息!'); + if((float)$childrenItem['city_id'] <= 0) throw new ValidateException('请完善地区信息!'); + if((float)$childrenItem['area_id'] <= 0) throw new ValidateException('请完善地区信息!'); + break; + case 7: + if((float)$childrenItem['province_id'] <= 0) throw new ValidateException('请完善地区信息!'); + if((float)$childrenItem['city_id'] <= 0) throw new ValidateException('请完善地区信息!'); + if((float)$childrenItem['area_id'] <= 0) throw new ValidateException('请完善地区信息!'); + if((float)$childrenItem['street_id'] <= 0) throw new ValidateException('请完善地区信息!'); + if(empty($childrenItem['address'])) throw new ValidateException('请完善地区信息!'); + if((float)$childrenItem['lat'] <= 0 || (float)$childrenItem['lng'] <= 0) throw new ValidateException('请选择定位信息!'); + if((float)$childrenItem['mer_id'] <= 0) throw new ValidateException('餐厅必须关联商户!'); + break; + case 8: + if(count($childrenItem['mer_id_list']) <= 0) throw new ValidateException('配送商至少关联一个商户!'); + break; + } + } + // 判断:餐厅关联的商户是否重复 + $merIds = array_filter(array_column($childrenList,'mer_id')); + if(count($merIds) > 0){ + // 判断:是否存在重复 + if(count($merIds) != count(array_unique($merIds))) throw new ValidateException('每个商户只能关联一个餐厅,请勿重复关联!'); + // 判断:当前关联商户中,是否存在其他已经被关联的商户 + $ids = array_filter(array_column($childrenList,'id')); + $isHas = (int)app()->make(AgentRepository::class) + ->getSearch([]) + ->whereNotIn('id',$ids) + ->whereIn('mer_id',$merIds) + ->count(); + if($isHas > 0) throw new ValidateException('每个商户只能关联一个餐厅,请勿重复关联!'); + } + // 判断:配送商关联的商户是否重复 + $merIdList = array_filter(array_column($childrenList,'mer_id_list')); + if(count($merIdList) > 0){ + // 判断:是否存在重复 + $newMerIdList = call_user_func_array('array_merge', $merIdList); + if(count($newMerIdList) != count(array_unique($newMerIdList))) throw new ValidateException('每个商户只能关联一个配送商,请勿重复关联!'); + // 判断:当前关联商户中,是否存在其他已经被关联的商户 + $ids = array_filter(array_column($childrenList,'id')); + $isHas = (int)app()->make(MerchantRepository::class) + ->getSearch([]) + ->whereNotIn('agent_id',$ids) + ->whereIn('mer_id',$newMerIdList) + ->count(); + if($isHas > 0) throw new ValidateException('每个商户只能关联一个配送商,请勿重复关联!'); + } + // 判断:agentId 大于0,验证data的信息 + if($agentId > 0){ + if(empty($data['contact_name'])) throw new ValidateException('请输入联系人姓名!'); + if(empty($data['contact_phone'])) throw new ValidateException('请输入联系人电话!'); + if(isPhone($data['contact_phone'])) throw new ValidateException('请输入正确的联系人电话!'); + // 判断:根据当前角色判断 数据 + switch((int)$data['agent_type']){ + case 2: + case 3: + case 4: + if((float)$data['province_id'] <= 0) throw new ValidateException('请完善地区信息!'); + break; + case 5: + case 6: + if((float)$data['province_id'] <= 0) throw new ValidateException('请完善地区信息!'); + if((float)$data['city_id'] <= 0) throw new ValidateException('请完善地区信息!'); + if((float)$data['area_id'] <= 0) throw new ValidateException('请完善地区信息!'); + break; + case 7: + if((float)$data['province_id'] <= 0) throw new ValidateException('请完善地区信息!'); + if((float)$data['city_id'] <= 0) throw new ValidateException('请完善地区信息!'); + if((float)$data['area_id'] <= 0) throw new ValidateException('请完善地区信息!'); + if((float)$data['street_id'] <= 0) throw new ValidateException('请完善地区信息!'); + if(empty($data['address'])) throw new ValidateException('请完善地区信息!'); + if((float)$data['lat'] <= 0 || (float)$data['lng'] <= 0) throw new ValidateException('请选择定位信息!'); + if((float)$data['mer_id'] <= 0) throw new ValidateException('餐厅必须关联商户!'); + break; + case 8: + if(count($data['mer_id_list']) <= 0) throw new ValidateException('配送商至少关联一个商户!'); + break; + } + // 判断:餐厅关联的商户是否重复 + if((int)$data['mer_id'] > 0){ + // 判断:当前关联商户中,是否存在其他已经被关联的商户 + $isHas = (int)app()->make(AgentRepository::class) + ->getSearch([]) + ->where('id','<>',$agentId) + ->where('mer_id',(int)$data['mer_id']) + ->count(); + if($isHas > 0) throw new ValidateException('每个商户只能关联一个餐厅,请勿重复关联!'); + } + // 判断:配送商关联的商户是否重复 + $merIdList = is_array($data['mer_id_list']) ? $data['mer_id_list'] : []; + if(count($merIdList) > 0){ + // 判断:当前关联商户中,是否存在其他已经被关联的商户 + $isHas = (int)app()->make(MerchantRepository::class) + ->getSearch([]) + ->where('agent_id','<>',$agentId) + ->whereIn('mer_id',$data['mer_id_list']) + ->count(); + if($isHas > 0) throw new ValidateException('每个商户只能关联一个配送商,请勿重复关联!'); + } + } + + return compact("data", "agentId", "childrenList"); + } + /** + * Common: 获取编辑信息 + * Author: wu-hui + * Time: 2024/01/24 18:25 + * @return mixed + */ + public function getEditInfo(){ + // 参数获取 + $params = $this->request->params(['agent_id']); + $data = app()->make(AgentRepository::class)->getEditInfo((array)$params); + + return app('json')->success($data); + } + + + + + + + + + + + + + + +} diff --git a/app/controller/admin/system/merchant/Merchant.php b/app/controller/admin/system/merchant/Merchant.php index 48ac84a..3c1aefe 100644 --- a/app/controller/admin/system/merchant/Merchant.php +++ b/app/controller/admin/system/merchant/Merchant.php @@ -65,7 +65,7 @@ class Merchant extends BaseController public function lst() { [$page, $limit] = $this->getPage(); - $where = $this->request->params(['keyword', 'date', 'status', 'statusTag', 'is_trader', 'category_id', 'type_id',['order','create_time'],'is_best']); + $where = $this->request->params(['mer_id_list','keyword','mer_id', 'date', 'status', 'statusTag', 'is_trader', 'category_id', 'type_id',['order','create_time'],'is_best']); return app('json')->success($this->repository->lst($where, $page, $limit)); } diff --git a/route/admin/marketing.php b/route/admin/marketing.php index ca490d6..253dde4 100644 --- a/route/admin/marketing.php +++ b/route/admin/marketing.php @@ -8,7 +8,6 @@ use app\common\middleware\AllowOriginMiddleware; use app\common\middleware\LogMiddleware; Route::group(function () { - //积分 Route::group('user/integral', function () { Route::get('config', '.UserIntegral/getConfig')->name('systemUserIntegralConfig')->option([ @@ -460,16 +459,42 @@ Route::group(function () { Route::get('pickup_point_record', '.ExchangeQuota/pickupPointRecord')->name('systemUserExchangePickupPointRecord')->option([ '_alias' => '提货记录', ]); - - - - - - })->prefix('admin.user')->option([ '_path' => '/marketing/integral/hold', '_auth' => true, ]); + // 代理中心 + Route::group('marketing/agent', function () { + // 代理商相关 + Route::get('list','/agentList')->name('systemMarketingAgentList')->option([ + '_alias' => '代理列表', + ]); + Route::post('edit_info','/editInfo')->name('systemMarketingAgentEditInfo')->option([ + '_alias' => '代理编辑', + ]); + Route::get('get_edit_info','/getEditInfo')->name('systemMarketingAgentGetEditInfo')->option([ + '_alias' => '获取编辑信息', + ]); + + + + + + + + + + + + + + })->prefix('admin.marketing.Agent')->option([ + '_path' => '/marketing/agent/list', + '_auth' => true, + ]); + + +