Merge branch 'main' into v1.0

es
lqmac 10 months ago
commit d1f8dd0588
  1. 35
      app/api/controller/Invite.php
  2. 22
      app/api/controller/Wholesaler.php
  3. 36
      app/api/controller/Wxserver.php
  4. 12
      app/api/model/Invite/InviteLog.php
  5. 30
      app/api/model/dealer/Capital.php
  6. 2
      app/api/model/wholesaler/Apply.php
  7. 1
      app/api/service/wholesaler/PaySuccess.php
  8. 10
      app/command/CalDealerTime.php
  9. 2
      app/common/library/wechat/WXBizDataCrypt.php
  10. 183
      app/common/library/wxserver/Server.php
  11. 50
      app/common/library/wxserver/WxBizMsgCrypt.php
  12. 14
      app/common/model/WxserverAccount.php
  13. 10
      app/common/model/wholesaler/Apply.php

@ -2,7 +2,11 @@
namespace app\api\controller;
use app\api\model\dealer\User as DealerUserModel;
use app\api\model\Invite\InviteLog;
use app\api\model\wholesaler\Apply;
use app\api\service\User as UserService;
use app\common\enum\WholesalerEnum;
use app\common\model\invite\InviteConfig;
use cores\exception\BaseException;
use think\db\exception\DbException;
@ -43,4 +47,35 @@ class Invite extends Controller
$list = $model->getList();
return $this->renderSuccess(compact('list'));
}
/**
* @notes:
* @return Json
* @throws BaseException
* @author: wanghousheng
*/
public function statistics(): Json
{
$refuse_num = 0;
$adoption_num = 0;
$money = 0;
$model = new InviteLog();
$user_ids = $model->inviteeUserIds();
if ($user_ids) {
$applyModel = new Apply();
//审核通过
$adoption_num = $applyModel->whereIn('user_id', $user_ids)->where(['status' => WholesalerEnum::ADOPT])->count();
//审核拒绝
$refuse_num = $applyModel->whereIn('user_id', $user_ids)->where(['status' => WholesalerEnum::REFUSE])->count();
}
// 当前用户ID
$userId = UserService::getCurrentLoginUserId();
// 分销商用户详情
$dealer = DealerUserModel::detail($userId, []);
if (!empty($dealer->freeze_money)) {
$money = $dealer->freeze_money;
}
$data = compact('refuse_num', 'adoption_num', 'money');
return $this->renderSuccess($data);
}
}

@ -5,11 +5,12 @@ namespace app\api\controller;
use app\api\model\wholesaler\Apply;
use app\api\model\wholesaler\Set;
use cores\exception\BaseException;
use Exception;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\response\Json;
use yiovo\captcha\CaptchaApi;
use yiovo\captcha\facade\CaptchaApi;
class Wholesaler extends Controller
{
@ -109,13 +110,16 @@ class Wholesaler extends Controller
if (!$business) {
return $this->renderError('经营类目不能为空');
}
// 验证短信验证码是否匹配
$avatar_id = intval($this->request->post('avatar_id'));
if (!$avatar_id) {
return $this->renderError('头像不能为空');
}
try {
CaptchaApi::checkSms($mobile_code, $mobile);
} catch (Exception $e) {
return $this->renderError($e->getMessage() ?: '短信验证码不正确');
}
$data = compact('company_name', 'credit_code', 'city_id', 'province_id', 'door_img_id', 'business', 'card_no');
$data = compact('company_name', 'credit_code', 'city_id', 'province_id', 'door_img_id', 'business', 'card_no', 'avatar_id');
$data = array_merge($data, compact('username', 'mobile', 'card_back_img_id', 'card_front_img_id', 'license_img_id'));
$data['total_price'] = $priceInfo['price'];
$data['pay_price'] = $priceInfo['price'];
@ -135,7 +139,7 @@ class Wholesaler extends Controller
*/
public function applyInfo(): Json
{
$info = Apply::info(['cardFrontImg', 'cardBackImg', 'licenseImg', 'doorImg']);
$info = Apply::info(['cardFrontImg', 'cardBackImg', 'licenseImg', 'doorImg', 'avatarImg']);
if (!empty($info->cardFrontImg)) {
unset($info->cardFrontImg);
}
@ -148,6 +152,9 @@ class Wholesaler extends Controller
if (!empty($info->doorImg)) {
unset($info->doorImg);
}
if (!empty($info->avatarImg)) {
unset($info->avatarImg);
}
return $this->renderSuccess(compact('info'));
}
@ -211,13 +218,16 @@ class Wholesaler extends Controller
if (!$business) {
return $this->renderError('经营类目不能为空');
}
// 验证短信验证码是否匹配
$avatar_id = intval($this->request->post('avatar_id'));
if (!$avatar_id) {
return $this->renderError('头像不能为空');
}
try {
CaptchaApi::checkSms($mobile_code, $mobile);
} catch (Exception $e) {
return $this->renderError($e->getMessage() ?: '短信验证码不正确');
}
$data = compact('company_name', 'credit_code', 'city_id', 'province_id', 'door_img_id', 'business', 'card_no');
$data = compact('company_name', 'credit_code', 'city_id', 'province_id', 'door_img_id', 'business', 'card_no', 'avatar_id');
$data = array_merge($data, compact('username', 'mobile', 'card_back_img_id', 'card_front_img_id', 'license_img_id'));
if ((new Apply())->edit($data)) {
return $this->renderSuccess('操作成功');

@ -0,0 +1,36 @@
<?php
declare (strict_types=1);
namespace app\api\controller;
use cores\BaseController;
use think\response\Json;
class Wxserver extends BaseController
{
public function index(): Json
{
$obj = new \app\common\library\wxserver\Server();
$url = $this->request->domain(true) . '/api/wxserver/redirect';
$jumUrl = $obj->jumpH5Url($url);
return $this->renderSuccess(compact('jumUrl'));
}
public function verifyTicket()
{
$xmlData = file_get_contents("php://input");
$obj = new \app\common\library\wxserver\Server();
$obj->getVerifyTicket($xmlData);
echo 'success';
}
public function redirect()
{
$authorization_code = $this->request->get('auth_code');
if ($authorization_code) {
$obj = new \app\common\library\wxserver\Server();
$obj->authorizationInfo($authorization_code);
}
echo 'success';
}
}

@ -119,4 +119,16 @@ class InviteLog extends \app\common\model\invite\InviteLog
$userId = UserService::getCurrentLoginUserId();
return $this->where(['user_id' => $userId])->count();
}
/**
* @notes:获取被邀请人ID
* @return array
* @throws BaseException
* @author: wanghousheng
*/
public function inviteeUserIds(): array
{
$userId = UserService::getCurrentLoginUserId();
return $this->where(['user_id' => $userId])->column('invitee_user_id');
}
}

@ -12,8 +12,9 @@ declare (strict_types=1);
namespace app\api\model\dealer;
use app\common\model\dealer\Capital as CapitalModel;
use app\api\service\User as UserService;
use app\common\model\dealer\Capital as CapitalModel;
use cores\exception\BaseException;
/**
* 分销商资金明细模型
@ -31,23 +32,40 @@ class Capital extends CapitalModel
'update_time',
];
/**
/**
* 获取分销商佣金列表
* @param array $param
* @return \think\Paginator
* @throws \cores\exception\BaseException
* @throws BaseException
* @throws \think\db\exception\DbException
*/
public function getList(array $param = [],int $storeId): \think\Paginator
public function getList(array $param = [], int $storeId): \think\Paginator
{
// 当前用户ID
$userId = UserService::getCurrentLoginUserId();
// 获取分销商佣金列表
$list = $this->getNewQuery()
->where('user_id',$userId)
->where('store_id',$storeId)
->where('user_id', $userId)
->where('store_id', $storeId)
->order(['create_time' => 'desc'])
->paginate(15);
return $list;
}
/**
* @notes:获取收入佣金总额
* @return float
* @throws BaseException
* @author: wanghousheng
*/
public function getTotal(): float
{
// 当前用户ID
$userId = UserService::getCurrentLoginUserId();
return $this->getNewQuery()
->where('user_id', $userId)
->where('store_id', self::$storeId)
->where('flow_type', 10)
->sum('money');
}
}

@ -59,7 +59,7 @@ class Apply extends \app\common\model\wholesaler\Apply
throwError('申请已通过无法编辑');
}
$userId = UserService::getCurrentLoginUserId();
if ($this->where(['user_id' => $userId])->update($data)) {
if ($this->where(['user_id' => $userId])->save($data) !== false) {
return true;
}
return false;

@ -338,6 +338,7 @@ class PaySuccess extends BaseService
$add['credit_code'] = $orderInfo['credit_code'];
$add['business'] = $orderInfo['business'];
$add['user_id'] = $orderInfo['user_id'];
$add['avatar_id'] = $orderInfo['avatar_id'];
$info = Apply::detail(['user_id' => $orderInfo['user_id']]);
if (empty($info->id)) {
(new Apply())->add($add);

@ -7,6 +7,7 @@ namespace app\command;
use app\api\model\dealer\User as DealerUserModel;
use app\api\model\User;
use app\common\enum\user\UserTypeEnum;
use app\common\model\wholesaler\Apply;
use think\console\Command;
use think\console\Input;
use think\console\Output;
@ -79,6 +80,10 @@ class CalDealerTime extends Command
if ($normalUserIds) {
$normalUserIds = array_unique($normalUserIds);
(new User)->whereIn('user_id', $normalUserIds)->update(['user_type' => UserTypeEnum::NORMAL]);
//删除采购商申请
Apply::destroy(function ($query) use ($normalUserIds) {
$query->whereIn('user_id', $normalUserIds);
});
}
$dealerUserIds = array_unique(array_merge($normalUserIds, $plusUserIds));
//删除分销商(软)
@ -113,7 +118,12 @@ class CalDealerTime extends Command
}
if ($normalUserIds) {
(new User)->whereIn('user_id', $normalUserIds)->update(['user_type' => UserTypeEnum::NORMAL]);
//删除采购商申请
Apply::destroy(function ($query) use ($normalUserIds) {
$query->whereIn('user_id', $normalUserIds);
});
}
}
}
}

@ -57,6 +57,8 @@ class WXBizDataCrypt
return ErrorCode::$IllegalBuffer;
}
$content = $resultArr;
var_dump($content);
exit();
return ErrorCode::$OK;
}

@ -0,0 +1,183 @@
<?php
declare (strict_types=1);
namespace app\common\library\wxserver;
use app\common\model\WxserverAccount;
use think\facade\Cache;
use think\facade\Db;
class Server
{
const APPID = 'wxc03d95d3597e348a';
const SECRET = 'e2720e31673906be6e92afd377b927ba';
const TOKEN = 'obUzmSA4MvMjOblZ5NCpgecTZYaGtAg6';//消息校验Token
const KEY = '2tujZuThOCzcuoBcBmeqMPjL6phcsv2dY7pgwYJwdtX'; //消息加解密Key
protected WxBizMsgCrypt $crypt;
public function __construct()
{
$this->crypt = new WxBizMsgCrypt(self::TOKEN, self::KEY, self::APPID);
}
/**
* @notes:保存Ticket
* @param string $xml
* @return mixed|string
* @author: wanghousheng
*/
public function getVerifyTicket(string $xml)
{
$ticket = '';
$xmlData = $this->crypt->fromXml($xml);
if (!empty($xmlData['Encrypt'])) {
//解密
$encryptXml = $this->crypt->decryptMsg($xmlData['Encrypt']);
$data = $this->crypt->fromXml($encryptXml);
if (!empty($data['ComponentVerifyTicket'])) {
$ticket = $data['ComponentVerifyTicket'];
Db::table('yoshop_wx_server')->insertGetId(['content' => '存入ticket成功&' . $ticket, 'created_at' => date('Y-m-d H:i:s')]);
Cache::set('component_verify_ticket', $ticket, 3600);
}
}
return $ticket;
}
/**
* @notes:获取令牌
* @return mixed|string
* @author: wanghousheng
*/
public function getComponentAccessToken()
{
if (Cache::has('ComponentAccessToken')) {
return Cache::get('ComponentAccessToken');
}
$url = 'https://api.weixin.qq.com/cgi-bin/component/api_component_token';
$ticket = Cache::get('component_verify_ticket');
if (!empty($ticket)) {
$data = [];
$data['component_appid'] = self::APPID;
$data['component_appsecret'] = self::SECRET;
$data['component_verify_ticket'] = $ticket;
$result = $this->curlPost($url, json_encode($data), 10);
$result = json_decode($result, true);
if (!empty($result['component_access_token'])) {
Cache::set('ComponentAccessToken', $result['component_access_token'], 6200);
return $result['component_access_token'];
}
}
return '';
}
/**
* @notes:生成H5授权链接
* @param string $redirect_uri //授权后重定向的回调链接地址
* @param string $biz_appid //业务公众号appid
* @return string
* @author: wanghousheng
*/
public function jumpH5Url(string $redirect_uri, string $biz_appid = ''): string
{
$url = '';
$auth_code = $this->getPreAuthCode();
if ($auth_code) {
$url = "'https://open.weixin.qq.com/wxaopen/safe/bindcomponent?action=bindcomponent&no_scan=1";
$url .= "&component_appid=" . self::APPID . '&pre_auth_code=' . $auth_code . '&redirect_uri=' . $redirect_uri;
$url .= '&auth_type=3&biz_appid=' . $biz_appid . '#wechat_redirect';
}
return $url;
}
/**
* @notes:获取预授权码
* @return false|mixed
* @author: wanghousheng
*/
public function getPreAuthCode()
{
$token = $this->getComponentAccessToken();
if ($token) {
$url = 'https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token=' . $token;
$data['component_appid'] = self::APPID;
$result = $this->curlPost($url, json_encode($data));
$result = json_decode($result, true);
if ($result && !empty($result['pre_auth_code'])) {
return $result['pre_auth_code'];
}
}
return false;
}
/**
* @notes:获取授权信息
* @param $authorization_code
* @author: wanghousheng
*/
public function authorizationInfo($authorization_code)
{
$url = 'https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=' . $this->getComponentAccessToken();
$data = [];
$data['component_appid'] = self::APPID;
$data['authorization_code'] = $authorization_code;
$result = $this->curlPost($url, json_encode($data));
$result = json_decode($result, true);
if ($result && !empty($result['authorization_info']) && !empty($result['authorization_info']['authorizer_appid'])) {
$url = 'https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token=' . $this->getComponentAccessToken();
$data = [];
$data['component_appid'] = self::APPID;
$data['authorizer_appid'] = $result['authorization_info']['authorizer_appid'];
$res = $this->curlPost($url, json_encode($data));
$res = json_decode($res, true);
if ($res && !empty($res['authorizer_info']) && !empty($res['authorization_info'])) {
$authorizer_info = $res['authorizer_info'];
$authorization_info = $res['authorization_info'];
$insert_data['appid'] = $authorization_info['authorizer_appid'];
$insert_data['access_token'] = $result['authorization_info']['authorizer_access_token'];
$insert_data['refresh_token'] = $authorization_info['authorizer_refresh_token'];
$insert_data['nick_name'] = $authorizer_info['nick_name'];
$insert_data['head_image'] = $authorizer_info['head_img'];
$insert_data['user_name'] = $authorizer_info['user_name'];
$insert_data['qrcode_image'] = $authorizer_info['qrcode_url'];
$insert_data['principal_name'] = $authorizer_info['principal_name'];
$insert_data['signature'] = $authorizer_info['signature'];
$model = new WxserverAccount();
$model->insertGetId($insert_data);
}
}
}
private function curlPost($url, $post_data, $timeout = 5)
{
$ch = curl_init();
if (stripos($url, 'https://') !== false) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSLVERSION, 1);
}
if (is_string($post_data)) {
$strPOST = $post_data;
} else {
$aPOST = array();
foreach ($post_data as $key => $val) {
$aPOST[] = $key . '=' . urlencode($val);
}
$strPOST = join('&', $aPOST);
}
curl_setopt($ch, CURLOPT_HTTP_VERSION, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $strPOST);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
$result = curl_exec($ch);
$aStatus = curl_getinfo($ch);
curl_close($ch);
if (intval($aStatus['http_code']) == 200) {
return $result;
} else {
return false;
}
}
}

@ -0,0 +1,50 @@
<?php
declare (strict_types=1);
namespace app\common\library\wxserver;
class WxBizMsgCrypt
{
private string $appId;
private string $token;
private string $encodingAesKey;
public function __construct(string $token, string $encodingAesKey, string $appId)
{
$this->token = $token;
$this->encodingAesKey = $encodingAesKey;
$this->appId = $appId;
}
/**
* @notes:xml转数组
* @param $xml
* @return mixed
* @author: wanghousheng
*/
public function fromXml($xml)
{
// 禁止引用外部xml实体
libxml_disable_entity_loader();
return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
}
/**
* @notes: 解密
* @param $msg_encrypt
* @return false|string
* @author: wanghousheng
*/
public function decryptMsg($msg_encrypt)
{
$EncodingAESKey = $this->encodingAesKey;
$AESKey = base64_decode($EncodingAESKey . '=');
$iv = substr($AESKey, 0, 16);
$msg_decode = base64_decode($msg_encrypt);
$msg = openssl_decrypt($msg_decode, 'AES-256-CBC', $AESKey, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
$msg_len = unpack('N', substr($msg, 16, 4));
$len = $msg_len[1];
return substr($msg, 20, $len);
}
}

@ -0,0 +1,14 @@
<?php
namespace app\common\model;
use cores\BaseModel;
class WxserverAccount extends BaseModel
{
// 定义表名
protected $name = 'wxserver_account';
// 定义主键
protected $pk = 'id';
}

@ -72,6 +72,16 @@ class Apply extends BaseModel
->bind(['door_img' => 'preview_url']);
}
/**
* 门头照片
* @return HasOne
*/
public function avatarImg(): HasOne
{
return $this->hasOne(UploadFile::class, 'file_id', 'avatar_id')
->bind(['avatar_img' => 'preview_url']);
}
/**
* @notes:地区名称
* @param $value

Loading…
Cancel
Save