| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- <?php
- /**
- * User: Qinii
- * Date: 2020-06-03
- * Time: 09:41
- */
- namespace app\common\repositories\user;
- use app\common\repositories\BaseRepository;
- use app\common\dao\user\UserAddressDao as dao;
- use app\common\repositories\store\shipping\CityRepository;
- use app\entity\data\user\UserAddressEntity;
- use crmeb\services\HttpService;
- use think\facade\Log;
- /**
- * Class UserAddressRepository
- * @package app\common\repositories\user
- * @day 2020/6/3
- * @mixin dao
- */
- class UserAddressRepository extends BaseRepository
- {
- /**
- * @var dao
- */
- protected $dao;
- /**
- * UserAddressRepository constructor.
- * @param dao $dao
- */
- public function __construct(dao $dao)
- {
- $this->dao = $dao;
- }
- /**
- * @param int $id
- * @param int $uid
- * @return bool
- * @author Qinii
- */
- public function fieldExists(int $id,int $uid)
- {
- return $this->dao->userFieldExists($this->dao->getPk(),$id,$uid);
- }
- /**
- * @param int $uid
- * @return bool
- * @author Qinii
- */
- public function defaultExists(int $uid)
- {
- return $this->dao->userFieldExists('is_default',1,$uid);
- }
- /**
- * @param int $id
- * @return mixed
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- * @author Qinii
- */
- public function checkDefault(int $id)
- {
- $res = $this->dao->getWhere([$this->dao->getPk() => $id]);
- return $res['is_default'];
- }
- /**
- * @param $province
- * @param $city
- * @return mixed
- * @author Qinii
- */
- public function getCityId($province,$city)
- {
- $make = app()->make(CityRepository::class);
- $provinceData = $make->getWhere(['name' => $province]);
- $cityData = $make->getWhere(['name' => $city,'parent_id' => $provinceData['city_id']]);
- if(!$cityData)$cityData = $make->getWhere([['name','like','直辖'.'%'],['parent_id' ,'=', $provinceData['city_id']]]);
- return $cityData['city_id'];
- }
- /**
- * @param $uid
- * @param $page
- * @param $limit
- * @return array
- * @author Qinii
- */
- public function getList($uid)
- {
- $list = $this->dao->getAll($uid)->order('is_default desc')->select();
- foreach ($list as &$address){
- $code_list = explode(',',$address['code_list']);
- if (isset($code_list[3])) {
- $address['town'] = \think\facade\Db::name('regions')->where('id', $code_list[3])->value('name');
- }
- }
- return compact('list');
- }
- /**
- * @param $id
- * @param $uid
- * @return array|\think\Model|null
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\DbException
- * @throws \think\db\exception\ModelNotFoundException
- * @author Qinii
- */
- public function get($id,$uid)
- {
- $address = $this->dao->getWhere(['address_id' => $id,'uid' => $uid]) ?? [] ;
- $code_list = explode(',',$address['code_list']);
- if (isset($code_list[3])) {
- $address['town'] = \think\facade\Db::name('regions')->where('id', $code_list[3])->value('name');
- }
- return $address;
- }
- /**
- * 根据 地址ID 获取地址实体
- *
- * @param $addressId
- * @return UserAddressEntity
- */
- public function getAddressEntityByAddressId($addressId): UserAddressEntity
- {
- /** @var UserAddressEntity $addressEntity */
- $addressEntity = $this->dao->getAddressEntityByAddressId($addressId);
- return $addressEntity;
- }
- /**
- * 阿里云市场 - 地址解析
- *
- * 调用阿里云市场地址解析接口,将完整的地址文本解析为省/市/区/街道等结构化信息,
- * 并从 rrx_regions 表查询省/市/区/街道的 id 追加到返回数据中
- *
- * 接口文档: https://market.aliyun.com/detail/cmapi00067026
- * 请求方式: POST
- * 认证方式: Authorization:APPCODE
- *
- * @param string $address 待解析的地址文本,如 "北京市朝阳区建国路88号SOHO现代城A座1508室"
- * @return array 统一返回格式:
- * 成功 {"code":200,"msg":"成功","data":{...}}
- * 失败 {"code":-1,"msg":"错误信息","data":[]}
- */
- public function parse($address)
- {
- $config = config('third_party.aliyun_address_parse');
- $appCode = $config['appCode'] ?? '';
- if (empty($appCode)) {
- $msg = '地址解析失败:未配置阿里云市场 AppCode';
- Log::error($msg);
- return ['code' => -1, 'msg' => $msg, 'data' => []];
- }
- if (empty($address)) {
- $msg = '地址解析失败:地址文本为空';
- Log::error($msg);
- return ['code' => -2, 'msg' => $msg, 'data' => []];
- }
- $url = rtrim($config['gatewayUrl'] ?? 'https://slyparcel.market.alicloudapi.com', '/')
- . ($config['apiPath'] ?? '/v2/express_address/query');
- $header = ['Authorization:APPCODE ' . $appCode];
- try {
- $res = HttpService::postRequest($url, ['rawAddress' => $address], $header);
- if ($res === false) {
- $msg = '地址解析请求失败';
- Log::error($msg . ':' . $url . ',地址:' . $address);
- return ['code' => -3, 'msg' => $msg, 'data' => []];
- }
- $result = json_decode($res, true);
- if (json_last_error() !== JSON_ERROR_NONE) {
- $msg = '地址解析返回数据解析失败:' . json_last_error_msg();
- Log::error($msg . ',原始数据:' . $res);
- return ['code' => -4, 'msg' => $msg, 'data' => []];
- }
- // 接口返回格式:{"msg":"成功","success":true,"code":200,"data":{"orderNo":"...","data":{...}}}
- // 提取内层 data.data 作为解析结果
- if (isset($result['code']) && $result['code'] == 200 && isset($result['data']['data'])) {
- $data = $result['data']['data'];
- // 从 rrx_regions 表查询省/市/区/街道的 id
- $data = $this->appendRegionIds($data);
- return ['code' => 200, 'msg' => '成功', 'data' => $data];
- }
- // 如果外层 code 不是 200,返回接口的错误信息
- if (isset($result['code']) && $result['code'] != 200) {
- $msg = $result['msg'] ?? '地址解析失败';
- Log::error($msg . ',原始数据:' . $res);
- return ['code' => $result['code'], 'msg' => $msg, 'data' => []];
- }
- // 兜底:返回原始结果
- return ['code' => 200, 'msg' => '成功', 'data' => $result];
- } catch (\Throwable $e) {
- $msg = '地址解析异常:' . $e->getMessage();
- Log::error($msg . ',文件:' . $e->getFile() . ',行号:' . $e->getLine());
- return ['code' => -5, 'msg' => $msg, 'data' => []];
- }
- }
- /**
- * 根据省/市/区/街道名称从 rrx_regions 表查询对应的 id,并追加到返回数据中
- *
- * 注意:每次查询必须重新调用 Db::name('regions'),避免 ThinkPHP 查询构造器复用导致 where 条件叠加
- *
- * @param array $data 接口返回的地址解析数据,包含 province/city/district/street
- * @return array
- */
- private function appendRegionIds(array $data)
- {
- $provinceId = 0;
- $cityId = 0;
- $districtId = 0;
- $streetId = 0;
- // 查询省份 id (level = 1),未查到返回 0
- if (!empty($data['province'])) {
- $province = \think\facade\Db::name('regions')
- ->whereLike('name', '%' . $data['province'] . '%')
- ->where('level', 1)
- ->find();
- $provinceId = $province ? (int)$province['id'] : 0;
- }
- $data['province_id'] = $provinceId;
- // 查询城市 id (level = 2),未查到返回 0
- if (!empty($data['city'])) {
- $city = \think\facade\Db::name('regions')
- ->whereLike('name', '%' . $data['city'] . '%')
- ->where('level', 2)
- ->find();
- $cityId = $city ? (int)$city['id'] : 0;
- }
- $data['city_id'] = $cityId;
- // 查询区/县 id (level = 3),未查到返回 0
- if (!empty($data['district'])) {
- $district = \think\facade\Db::name('regions')
- ->whereLike('name', '%' . $data['district'] . '%')
- ->where('level', 3)
- ->find();
- $districtId = $district ? (int)$district['id'] : 0;
- }
- $data['district_id'] = $districtId;
- // 查询街道/乡镇 id (level = 4),未查到返回 0
- if (!empty($data['street'])) {
- $street = \think\facade\Db::name('regions')
- ->whereLike('name', '%' . $data['street'] . '%')
- ->where('level', 4)
- ->find();
- $streetId = $street ? (int)$street['id'] : 0;
- }
- $data['village'] = $data['street'];
- $data['village_id'] = $streetId;
- // 拼接 code_list,格式:province_id,city_id,district_id,street_id
- $codeList = implode(',', [$provinceId, $cityId, $districtId, $streetId]);
- $data['code_list'] = $codeList;
- return $data;
- }
- }
|