lqmac 8 months ago
commit 1ea1fe4144
  1. 14
      app/admin/controller/Wxwholesaler.php
  2. 91
      app/api/controller/Retail.php
  3. 114
      app/api/model/Retail.php
  4. 20
      app/api/model/RetailOrder.php
  5. 20
      app/api/model/user/Retail.php
  6. 121
      app/api/model/user/RetailOrder.php
  7. 142
      app/api/service/Retail.php
  8. 409
      app/api/service/Retail/PaySuccess.php
  9. 344
      app/api/service/Retail/Payment.php
  10. 5
      app/common/library/baidu/OcrLicense.php
  11. 1
      app/common/library/wxserver/Server.php
  12. 18
      app/common/library/wxserver/Wholesaler.php
  13. 50
      app/common/model/Retail.php
  14. 35
      app/common/model/RetailOrder.php
  15. 100
      app/store/controller/Retail.php
  16. 73
      app/store/model/Retail.php

@ -188,6 +188,20 @@ class Wxwholesaler extends Controller
return $this->renderError('操作失败');
}
public function commitOne(): Json
{
$appid = $this->request->get('appid');
$obj = new Wholesaler();
$msg = $obj->privacyInfo($appid);
if ($msg == 'ok') {
$msg = $obj->submitAudit($appid);
if ($msg == 'ok') {
return $this->renderSuccess('success');
}
}
return $this->renderError($msg);
}
/**
* @notes:获取版本信息
* @return Json

@ -0,0 +1,91 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\controller;
use think\response\Json;
use app\api\model\Retail as RetailModel;
use app\api\model\RetailOrder as RetailOrderModel;
use app\api\model\Agreement as AgreementModel;
use app\api\service\order\Checkout as CheckoutService;
class Retail extends Controller
{
/**
* 获取零售批发会员列表
* @param int $retailType
* @return Json
*/
public function list(int $retailType): Json
{
$list = RetailModel::withoutGlobalScope()->where('retail_type',$retailType)->where('retail_status',10)->select();
return $this->renderSuccess(compact('list'));
}
/**
* 获取软件付费协议
* @return Json
*/
public function getSoftAgreement(): Json
{
$params = $this->request->param();
if (empty($params['type'])) {
return $this->renderSuccess("参数错误");
}
$detail = AgreementModel::detail(['type' => $params['type']]);
if (!empty($detail->content)) {
$detail->content = str_ireplace('nowrap', 'inherit', $detail->content);
}
return $this->renderSuccess(compact('detail'));
}
/**
* 获取零售批发会员列表
* @param int $retailType
* @return Json
*/
public function retailPayList(): Json
{
$client = $this->request->post();
if (!$client['client']) {
return $this->renderError('客户端不能为空');
}
$model =new \app\api\model\user\Retail();
$list = $model->userCenter($client);
return $this->renderSuccess(compact('list'));
}
public function submit(): Json
{
$method = $this->request->post('method');
if (!$method) {
return $this->renderError('支付方式不能为空');
}
$client = $this->request->post('client');
if (!$client) {
return $this->renderError('客户端不能为空');
}
$retailPriceId = intval($this->request->post('retail_price_id'));
if (!$retailPriceId) {
return $this->renderError('缺少必要参数');
}
$service = new \app\api\service\Retail();
$data = $service->setMethod($method)
->setClient($client)
->orderPay($retailPriceId);
return $this->renderSuccess($data, $service->getMessage() ?: '下单成功');
}
}

@ -0,0 +1,114 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\Retail as RetailModel;
use app\api\model\Payment as PaymentModel;
use app\api\service\identity\Payment;
use app\api\service\User as UserService;
class Retail extends RetailModel
{
// 提示信息
private string $message = '';
// 支付方式 (微信支付、支付宝、余额)
private string $method;
// 下单的客户端
private string $client;
//隐藏字段
protected $hidden = [
'create_time',
'update_time',
'store_id',
];
public function setMethod(string $method): Retail
{
$this->method = $method;
return $this;
}
public static function getRetailList()
{
return self::select();
}
/**
* 设置下单的客户端
* @param string $client 客户端
* @return $this
*/
public function setClient(string $client): Retail
{
$this->client = $client;
return $this;
}
/**
* 返回消息提示
* @return string
*/
public function getMessage(): string
{
return $this->message;
}
public static function detail(array $where = [])
{
$where = [
'retail_price_id'=>$where['retail_price_id'],
'retail_status'=>10
];
return RetailModel::where($where)->select();
}
private function cheapPrice($data): array
{
$one_data = $data[0];
foreach ($data as $key => $value) {
$data[$key]['cheap_price'] = 0;
if (!empty($one_data)) {
if ($key > 0) {
$price = $value['month'] * $one_data['price'];
$data[$key]['cheap_price'] = $price - $value['price'];
}
}
}
return $data;
}
/**
* 确认订单支付事件
* @param int $identityId
* @param array $extra 附加数据
* @return array[]
* @throws BaseException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function orderPay(int $identityId, array $extra = []): array
{
$PaymentService = new Payment();
$result = $PaymentService->setMethod($this->method)
->setClient($this->client)
->orderPay($identityId, $extra);
$this->message = $PaymentService->getMessage();
return $result;
}
}

@ -0,0 +1,20 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\model;
use app\common\model\RetailOrder as RetailOrderModel;
class RetailOrder extends RetailOrderModel
{
}

@ -0,0 +1,20 @@
<?php
declare (strict_types=1);
namespace app\api\model\user;
use app\common\model\Retail as BaseRetail;
class Retail extends BaseRetail
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'create_time',
'update_time',
'store_id',
];
}

@ -0,0 +1,121 @@
<?php
namespace app\api\model\user;
use app\api\service\User as UserService;
use app\common\enum\order\PayStatus;
use app\common\model\RetailOrder as BaseIdentityOrder;
use app\common\service\Order as OrderService;
use cores\exception\BaseException;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\model\relation\HasOne;
use function getPlatform;
class RetailOrder extends BaseIdentityOrder
{
/**
* 隐藏字段
* @var array
*/
protected $hidden = [
'order_type',
'create_time',
'update_time',
'store_id',
];
/**
* @notes:创建订单
* @param array $identityInfo
* @param $method
* @return bool
* @throws BaseException
* @author: wanghousheng
*/
public function createOrder(array $identityInfo, $method): bool
{
$price = $identityInfo['retail_current_price'] * $identityInfo['year'];
$data = [
'user_id' => UserService::getCurrentLoginUserId(),//用户id
'order_no' => OrderService::createOrderNo(),//订单号
'retail_price_id' => $identityInfo['retail_price_id'],//会员id
'order_type' => $identityInfo['retail_type'],//订单类型
'pay_price' => $price,
'year' => $identityInfo['year'],
'platform' => getPlatform(),
'pay_method' => $method,
'store_id' => self::$storeId,
];
return $this->save($data);
}
/**
* 获取订单详情 (待付款状态)
* @param string $orderNo 订单号
* @return array|null|static
*/
public static function getPayDetail(string $orderNo)
{
return self::detail(['order_no' => $orderNo]);
}
/**
* @notes:编辑
* @param $data
* @return bool
* @author: wanghousheng
*/
public function edit($data): bool
{
return $this->save($data) !== false;
}
public function identity(): HasOne
{
return $this->hasOne(Identity::class, 'identity_id', 'identity_id')
->bind(['identity_name' => 'name']);
}
/**
* @notes:开卡记录
* @param array $where
* @return array
* @throws BaseException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
* @author: wanghousheng
*/
public function cardList(array $where = []): array
{
$userId = UserService::getCurrentLoginUserId();
$params['user_id'] = $userId;
$params['pay_status'] = PayStatus::SUCCESS;
$where = array_merge($where, $params);
$list = $this->where($where)
->with(['identity'])
->order('pay_time', 'desc')
->limit(20)
->select();
$data = [];
if (!empty($list)) {
foreach ($list as $value) {
$end_time = date("Y-m-d", strtotime("+{$value['month']} months", $value['pay_time']));
$is_valid = false;
if (strtotime(date("Y-m-d")) < strtotime($end_time)) {
$is_valid = true;
}
$data[] = [
'start_time' => date("Y-m-d", $value['pay_time']),
'end_time' => $end_time,
'name' => $value['identity_name'],
'month' => $value['month'],
'is_valid' => $is_valid
];
}
}
return $data;
}
}

@ -0,0 +1,142 @@
<?php
namespace app\api\service;
use app\api\model\Payment as PaymentModel;
use app\api\service\Retail\Payment;
use app\api\service\User as UserService;
use app\common\service\BaseService;
use cores\exception\BaseException;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use app\api\model\Retail as RetailModel;
class Retail extends BaseService
{
// 提示信息
private string $message = '';
// 支付方式 (微信支付、支付宝、余额)
private string $method;
// 下单的客户端
private string $client;
/**
* 设置当前支付方式
* @param string $method 支付方式
* @return $this
*/
public function setMethod(string $method): Retail
{
$this->method = $method;
return $this;
}
/**
* 设置下单的客户端
* @param string $client 客户端
* @return $this
*/
public function setClient(string $client): Retail
{
$this->client = $client;
return $this;
}
/**
* 开通会员页面数据
* @param string $client 当前客户端
* @return array
* @throws BaseException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function userCenter(array $client): array
{
// 当期用户信息
$userInfo = UserService::getCurrentLoginUser(true);
// //是否分销商
// if (UserService::isDealerMember() || UserService::isStore()) {
// throwError('非法操作');
// }
// 获取充值方案列表
$model = new RetailModel();
$planList = $model->getList(['retail_type' => $client['retail_type']]);
if (!$planList->isEmpty()) {
// $planList = $this->cheapPrice($planList->toArray());
}
//计算优惠价格
// 根据指定客户端获取可用的支付方式
$PaymentModel = new PaymentModel;
$methods = $PaymentModel->getMethodsByClient($client['client']);
// 返回数据
return [
'personal' => $userInfo,
'list' => $planList,
'paymentMethods' => $methods
];
}
private function cheapPrice($data): array
{
$one_data = $data[0];
foreach ($data as $key => $value) {
$data[$key]['cheap_price'] = 0;
if (!empty($one_data)) {
if ($key > 0) {
$price = $value['month'] * $one_data['price'];
$data[$key]['cheap_price'] = $price - $value['price'];
}
}
}
return $data;
}
/**
* 确认订单支付事件
* @param int $identityId
* @param array $extra 附加数据
* @return array[]
* @throws BaseException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function orderPay(int $identityId, array $extra = []): array
{
$PaymentService = new Payment();
$result = $PaymentService->setMethod($this->method)
->setClient($this->client)
->orderPay($identityId);
$this->message = $PaymentService->getMessage();
return $result;
}
/**
* 交易查询
* 查询第三方支付订单是否付款成功
* @param string $outTradeNo 商户订单号
* @return bool
* @throws BaseException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function tradeQuery(string $outTradeNo): bool
{
$PaymentService = new Payment();
return $PaymentService->setMethod($this->method)->setClient($this->client)->tradeQuery($outTradeNo);
}
/**
* 返回消息提示
* @return string
*/
public function getMessage(): string
{
return $this->message;
}
}

@ -0,0 +1,409 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\service\identity;
use app\api\model\PaymentTrade as PaymentTradeModel;
use app\api\model\recharge\Order as OrderModel;
use app\api\model\User as UserModel;
use app\api\model\user\BalanceLog as BalanceLogModel;
use app\api\model\user\IdentityOrder;
use app\common\enum\order\PayStatus;
use app\common\enum\payment\Method as PaymentMethodEnum;
use app\common\enum\recharge\order\PayStatus as PayStatusEnum;
use app\common\enum\user\balanceLog\Scene as SceneEnum;
use app\common\enum\user\IdentityEnum;
use app\common\enum\user\UserTypeEnum;
use app\common\library\Lock;
use app\common\library\Log;
use app\common\service\BaseService;
use app\store\model\dealer\User;
use cores\exception\BaseException;
/**
* 余额充值订单支付成功服务类
* Class PaySuccess
* @package app\api\service\order
*/
class PaySuccess extends BaseService
{
// 当前订单信息
public IdentityOrder $orderInfo;
// 当前用户信息
private UserModel $userInfo;
// 当前订单号
private string $orderNo;
// 当前订单ID
private int $orderId;
// 订单支付方式
private string $method;
// 第三方交易记录ID
private ?int $tradeId = null;
// 第三方支付成功返回的数据
private array $paymentData = [];
private int $type;
/**
* 设置支付的订单ID
* @param int $orderId 订单ID
*/
public function setOrderId(int $orderId): PaySuccess
{
$this->orderId = $orderId;
return $this;
}
public function setType($type): PaySuccess
{
$this->type = $type;
return $this;
}
/**
* 设置当前的订单号
* @param string $orderNo
* @return $this
*/
public function setOrderNo(string $orderNo): PaySuccess
{
$this->orderNo = $orderNo;
return $this;
}
/**
* 设置订单支付方式
* @param string $method
* @return $this
*/
public function setMethod(string $method): PaySuccess
{
$this->method = $method;
return $this;
}
/**
* 第三方支付交易记录ID
* @param int|null $tradeId
* @return $this
*/
public function setTradeId(?int $tradeId = null): PaySuccess
{
$this->tradeId = $tradeId;
return $this;
}
/**
* 第三方支付成功返回的数据
* @param array $paymentData
* @return $this
*/
public function setPaymentData(array $paymentData): PaySuccess
{
$this->paymentData = $paymentData;
return $this;
}
/**
* 订单支付成功业务处理
* @return bool
* @throws BaseException
*/
public function handle(): bool
{
// 验证当前参数是否合法
$this->verifyParameters();
// 当前订单开启并发锁
$this->lockUp();
// 验证当前订单是否允许支付
if ($this->checkOrderStatusOnPay()) {
// 更新订单状态为已付款
$this->updatePayStatus();
}
// 当前订单解除并发锁
$this->unLock();
return true;
}
/**
* 验证当前参数是否合法
* @throws BaseException
*/
private function verifyParameters()
{
if (empty($this->orderNo)) {
throwError('orderNo not found');
}
if (empty($this->method)) {
throwError('method not found');
}
if ($this->tradeId) {
empty($this->paymentData) && throwError('PaymentData not found');
!isset($this->paymentData['tradeNo']) && throwError('PaymentData not found');
}
// 记录日志
Log::append('PaySuccess', [
'orderNo' => $this->orderNo, 'method' => $this->method,
'tradeId' => $this->tradeId, 'paymentData' => $this->paymentData
]);
}
/**
* 订单模型
* @return IdentityOrder|null
* @throws BaseException
*/
private function orderModel(): ?IdentityOrder
{
return $this->getOrderInfo();
}
/**
* 订单已付款事件
* @return void
* @throws BaseException
*/
private function updatePayStatus(): void
{
// 记录日志
Log::append('PaySuccess --updatePayStatus', ['title' => '订单已付款事件']);
// 当前订单信息
$orderInfo = $this->getOrderInfo();
// 事务处理
$this->orderModel()->transaction(function () use ($orderInfo) {
// 更新订单状态
$this->updateOrderStatus();
// 累积用户总消费金额
UserModel::setIncPayMoney($orderInfo['user_id'], (float)$orderInfo['pay_price']);
// 记录订单支付信息
$this->updatePayInfo();
//更改会员角色
$this->activate();
});
}
/**
* 记录订单支付的信息
* @throws BaseException
*/
private function updatePayInfo()
{
// 当前订单信息
$orderInfo = $this->getOrderInfo();
// 余额支付
if ($this->method == PaymentMethodEnum::BALANCE) {
// 更新用户余额
UserModel::setDecBalance((int)$orderInfo['user_id'], (float)$orderInfo['pay_price']);
// 新增余额变动记录
$type = SceneEnum::MEMBER;
if ($this->type == IdentityEnum::DEALER) {
$type = SceneEnum::DEALER;
}
BalanceLogModel::add($type, [
'user_id' => (int)$orderInfo['user_id'],
'money' => -$orderInfo['pay_price'],
], ['order_no' => $orderInfo['order_no']]);
}
// 将第三方交易记录更新为已支付状态
if (in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY])) {
$this->updateTradeRecord();
}
}
/**
* 将第三方交易记录更新为已支付状态
*/
private function updateTradeRecord()
{
if ($this->tradeId && !empty($this->paymentData)) {
PaymentTradeModel::updateToPaySuccess($this->tradeId, $this->paymentData['tradeNo']);
}
}
/**
* 更新订单状态
* @throws BaseException
*/
private function updateOrderStatus(): void
{
// 更新订单状态
$this->orderModel()->save([
'pay_method' => $this->method,
'pay_status' => PayStatus::SUCCESS,
'pay_time' => time(),
'trade_id' => $this->tradeId ?: 0,
]);
}
/**
* 获取买家用户信息
* @return UserModel|array|null
* @throws BaseException
*/
private function getUserInfo()
{
if (empty($this->userInfo)) {
$this->userInfo = UserModel::detail($this->getOrderInfo()['user_id']);
}
if (empty($this->userInfo)) {
throwError('未找到买家用户信息');
}
return $this->userInfo;
}
/**
* 验证当前订单是否允许支付
* @return bool
* @throws BaseException
*/
private function checkOrderStatusOnPay(): bool
{
// 当前订单信息
$orderInfo = $this->getOrderInfo();
// 验证余额支付时用户余额是否满足
if ($this->method == PaymentMethodEnum::BALANCE) {
if ($this->getUserInfo()['balance'] < $orderInfo['pay_price']) {
throwError('账户余额不足,无法使用余额支付');
}
}
// 检查订单状态是否为已支付
if ($orderInfo['pay_status'] == PayStatusEnum::SUCCESS) {
$this->onOrderPaid();
return false;
}
return true;
}
/**
* 处理订单已支付的情况
* @throws BaseException
*/
private function onOrderPaid()
{
// 记录日志
Log::append('PaySuccess --onOrderPaid', ['title' => '处理订单已支付的情况']);
// 当前订单信息
$orderInfo = $this->getOrderInfo();
// 余额支付直接返回错误信息
if ($this->method == PaymentMethodEnum::BALANCE) {
throwError('当前订单已支付,无需重复支付');
}
// 第三方支付判断是否为重复下单 (因异步回调可能存在网络延迟的原因,在并发的情况下会出现同时付款两次,这里需要容错)
// 如果订单记录中已存在tradeId并且和当前支付的tradeId不一致, 那么判断为重复的订单, 需进行退款处理
if ($this->tradeId > 0 && $orderInfo['trade_id'] != $this->tradeId) {
// 执行原路退款
throwError('当前订单异常');
}
}
/**
* 获取当前订单的详情信息
* @return OrderModel|null
* @throws BaseException
*/
private function getOrderInfo(): ?IdentityOrder
{
// 获取订单详情 (待支付状态)
if (empty($this->orderInfo)) {
$this->orderInfo = IdentityOrder::getPayDetail($this->orderNo);
}
// 判断订单是否存在
if (empty($this->orderInfo)) {
throwError('未找到该订单信息');
}
return $this->orderInfo;
}
/**
* 订单锁:防止并发导致重复支付
* @throws BaseException
*/
private function lockUp()
{
$orderInfo = $this->getOrderInfo();
Lock::lockUp("IdentityOrderPaySuccess_{$orderInfo['order_id']}");
}
/**
* 订单锁:防止并发导致重复支付
* @throws BaseException
*/
private function unLock()
{
$orderInfo = $this->getOrderInfo();
Lock::unLock("IdentityOrderPaySuccess_{$orderInfo['order_id']}");
}
/**
* @notes:修改会员身份信息
* @throws BaseException
* @author: wanghousheng
*/
private function activate(): void
{
$orderInfo = $this->getOrderInfo();
$userInfo = $this->getUserInfo();
//判断当前用户角色
$orderType = $orderInfo['order_type'];
$userType = $userInfo['user_type'];
if ($userType == UserTypeEnum::STORE) {
return;
}
$userModel = new UserModel();
$up = [];
$time = date('Y-m-d');
//已经是会员或者未开通会员
if ($orderType == IdentityEnum::MEMBER && $userType != UserTypeEnum::DEALER) {
$up['user_type'] = UserTypeEnum::MEMBER;
//已经是会员
if ($userType == UserTypeEnum::MEMBER) {
//是否到期
if (!empty($userInfo['effective_time']) && strtotime($userInfo['effective_time']) > strtotime(date('Y-m-d'))) {
$time = $userInfo['effective_time'];
}
}
$up['effective_time'] = date("Y-m-d", strtotime("+{$orderInfo['month']} months", strtotime($time)));
} else {
$up['user_type'] = UserTypeEnum::DEALER;
//已经是分销商
if ($userType == UserTypeEnum::DEALER) {
//是否到期
if (!empty($userInfo['fx_effective_time']) && strtotime($userInfo['fx_effective_time']) > strtotime(date('Y-m-d'))) {
$time = $userInfo['fx_effective_time'];
}
}
if (!User::isDealerUser($userInfo['user_id'])) {
// 新增分销商用户
$model = new UserModel();
$mobile = $model->where(['user_id' => $userInfo['user_id']])->value('mobile');
User::add($userInfo['user_id'], [
'real_name' => $mobile,
'mobile' => $mobile,
'store_id' => $userInfo['store_id'] ?? 0,
]);
} else {
//更新分销用户
User::update(['is_delete' => 0], ['user_id' => $userInfo['user_id']]);
}
$up['fx_effective_time'] = date("Y-m-d", strtotime("+{$orderInfo['month']} months", strtotime($time)));
}
$userModel->where(['user_id' => $userInfo['user_id']])->save($up);
}
}

@ -0,0 +1,344 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\api\service\Retail;
use app\api\model\Payment as PaymentModel;
use app\api\model\PaymentTrade as PaymentTradeModel;
use app\api\model\Retail as RetailModel;
use app\api\model\user\Retail;
use app\api\model\user\RetailOrder;
use app\api\service\identity\PaySuccess as RetailPaySuccessService;
use app\api\service\Order as OrderService;
use app\api\service\User as UserService;
use app\common\enum\Client as ClientEnum;
use app\common\enum\OrderType as OrderTypeEnum;
use app\common\enum\payment\Method as PaymentMethodEnum;
use app\common\enum\user\IdentityEnum;
use app\common\library\payment\Facade as PaymentFacade;
use app\common\service\BaseService;
use cores\exception\BaseException;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
/**
* 开通会员/分销商订单付款服务类
* Class Payment
* @package app\api\controller
*/
class Payment extends BaseService
{
// 提示信息
private string $message = '';
// 订单信息
private RetailOrder $orderInfo;
// 支付方式 (微信支付、支付宝,余额)
private string $method = '';
// 下单的客户端
private string $client = '';
private int $type;
/**
* 设置当前支付方式
* @param string $method 支付方式
* @return $this
*/
public function setMethod(string $method): Payment
{
$this->method = $method;
return $this;
}
public function setType($type): Payment
{
$this->type = $type;
return $this;
}
/**
* 设置下单的客户端
* @param string $client 客户端
* @return $this
*/
public function setClient(string $client): Payment
{
$this->client = $client;
return $this;
}
/**
* 确认订单支付事件
* @param int $retailPriceId
* @param array $extra 附加数据
* @return array[]
* @throws BaseException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function orderPay(int $retailPriceId, array $extra = []): array
{
// 创建订单信息
$this->orderInfo = $this->createOrder($retailPriceId);
// 订单支付事件
$this->orderPayEvent();
// 构建第三方支付请求的参数
$payment = $this->unifiedorder($extra);
// 记录第三方交易信息
$order_type = OrderTypeEnum::MEMBER;//开通会员
if ($this->orderInfo['order_type'] == IdentityEnum::DEALER) {
$order_type = OrderTypeEnum::DEALER;//开通分销商
}
$this->recordPaymentTrade($payment, $order_type);
// 返回结果
return compact('payment');
}
/**
* 订单支付事件
* @return void
* @throws BaseException
* @author: wanghousheng
*/
private function orderPayEvent(): void
{
// 余额支付
if ($this->method == PaymentMethodEnum::BALANCE) {
$this->setType($this->orderInfo['order_type'])->orderPaySuccess($this->orderInfo['order_no']);
}
}
/**
* 订单支付成功事件
* @param string $orderNo 当前订单号
* @param int|null $tradeId
* @param array $paymentData
* @return void
* @throws BaseException
* @author: wanghousheng
*/
private function orderPaySuccess(string $orderNo, ?int $tradeId = null, array $paymentData = []): void
{
$service = new RetailPaySuccessService();
// 订单支付成功业务处理
$service->setOrderNo($orderNo)
->setMethod($this->method)
->setTradeId($tradeId)
->setType($this->type)
->setPaymentData($paymentData);
if (!$service->handle()) {
throwError($service->getError() ?: '订单支付失败');
}
$this->message = '恭喜您,订单支付成功';
}
/**
* 创建订单
* @param int $identityId
* @return RetailOrder
* @throws BaseException
*/
private function createOrder(int $retailPriceId ,array $extra = []): RetailOrder
{
$extra = $this->request->post('year');
$model = new RetailOrder();
$info = Retail::detail(['retail_price_id' => $retailPriceId]);
$info['year'] = $extra;
if ($info->isEmpty()) {
throwError('记录不存在');
}
//店主不可操作
if (UserService::isStore()) {
throwError('非法操作');
}
if (UserService::isDealerMember() && $info['type'] != IdentityEnum::DEALER) {
throwError('非法操作');
}
if (!$model->createOrder($info->toArray(), $this->method)) {
throwError($model->getError() ?: '创建订单失败');
}
$model['order_id'] = (int)$model['order_id'];
return $model;
}
/**
* 查询订单是否支付成功 (仅限第三方支付订单)
* @param string $outTradeNo 商户订单号
* @return bool
* @throws BaseException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function tradeQuery(string $outTradeNo): bool
{
// 获取支付方式的配置信息
$options = $this->getPaymentConfig();
// 构建支付模块
$Payment = PaymentFacade::store($this->method)->setOptions($options, $this->client);
// 执行第三方支付查询API
$result = $Payment->tradeQuery($outTradeNo);
// 订单支付成功事件
if (!empty($result) && $result['paySuccess']) {
// 获取第三方交易记录信息
$tradeInfo = PaymentTradeModel::detailByOutTradeNo($outTradeNo);
// 订单支付成功事件
$this->orderPaySuccess($tradeInfo['order_no'], $tradeInfo['trade_id'], $result);
}
// 返回订单状态
return $result ? $result['paySuccess'] : false;
}
/**
* 记录第三方交易信息
* @param array $payment 第三方支付数据
* @throws BaseException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
private function recordPaymentTrade(array $payment, int $orderType): void
{
if ($this->method != PaymentMethodEnum::BALANCE) {
PaymentTradeModel::record(
$this->orderInfo,
$this->method,
$this->client,
$orderType,
$payment
);
}
}
/**
* 返回消息提示
* @return string
*/
public function getMessage(): string
{
return $this->message;
}
/**
* 构建第三方支付请求的参数
* @param array $extra 附加数据
* @return array
* @throws BaseException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
private function unifiedorder(array $extra = []): array
{
// 判断支付方式是否合法
if (!in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY])) {
return [];
}
// 生成第三方交易订单号 (并非主订单号)
$outTradeNo = OrderService::createOrderNo();
// 获取支付方式的配置信息
$options = $this->getPaymentConfig();
// 整理下单接口所需的附加数据
$extra = $this->extraAsUnify($extra);
// 构建支付模块
$Payment = PaymentFacade::store($this->method)->setOptions($options, $this->client);
// 执行第三方支付下单API
if (!$Payment->unify($outTradeNo, (string)$this->orderInfo['pay_price'], $extra)) {
throwError('第三方支付下单API调用失败');
}
// 返回客户端需要的支付参数
return $Payment->getUnifyResult();
}
/**
* 获取支付方式的配置信息
* @return mixed
* @throws BaseException
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
private function getPaymentConfig()
{
$PaymentModel = new PaymentModel;
$templateInfo = $PaymentModel->getPaymentInfo($this->method, $this->client, $this->getStoreId());
return $templateInfo['template']['config'][$this->method];
}
/**
* 整理下单接口所需的附加数据
* @param array $extra
* @return array
* @throws BaseException
*/
private function extraAsUnify(array $extra = []): array
{
// 微信支付时需要的附加数据
if ($this->method === PaymentMethodEnum::WECHAT) {
// 微信小程序端和微信公众号端需要openid
if (in_array($this->client, [ClientEnum::WXOFFICIAL, ClientEnum::MP_WEIXIN])) {
$extra['openid'] = $this->getWechatOpenid();
}
}
// 支付宝支付时需要的附加数据
if ($this->method === PaymentMethodEnum::ALIPAY) {
// 支付宝小程序端需要buyerId
if ($this->client == ClientEnum::MP_ALIPAY) {
$extra['buyerId'] = $this->getAlipayBuyerId();
}
}
return $extra;
}
/**
* 获取微信端的用户openid(仅微信小程序和微信公众号)
* @return null
* @throws BaseException
*/
private function getWechatOpenid()
{
if (in_array($this->client, [ClientEnum::MP_WEIXIN, ClientEnum::WXOFFICIAL])) {
// 当前登录用户信息
$useInfo = UserService::getCurrentLoginUser(true);
if (!$useInfo['currentOauth'] || empty($useInfo['currentOauth']['oauth_id'])) {
throwError('很抱歉,您当前不存在openid 无法发起微信支付');
}
// 当前第三方用户标识
return $useInfo['currentOauth']['oauth_id'];
}
return null;
}
/**
* 获取支付宝端的用户buyerId(仅支付宝小程序端)
* @return null
* @throws BaseException
*/
private function getAlipayBuyerId()
{
if ($this->client == ClientEnum::MP_ALIPAY) {
// 当前登录用户信息
$useInfo = UserService::getCurrentLoginUser(true);
if (!$useInfo['currentOauth'] || empty($useInfo['currentOauth']['oauth_id'])) {
throwError('很抱歉,您当前不存在buyerId 无法发起支付宝支付');
}
// 当前第三方用户标识
return $useInfo['currentOauth']['oauth_id'];
}
return null;
}
}

@ -17,8 +17,8 @@ class OcrLicense
public function __construct(string $clientId, string $clientSecret)
{
$this->clientId = $clientId;
$this->clientSecret = $clientSecret;
$this->clientId = trim($clientId);
$this->clientSecret = trim($clientSecret);
}
public function check($img_url): array
@ -31,6 +31,7 @@ class OcrLicense
$data['risk_warn'] = 'true';
$url = self::LICENSEURL . '?access_token=' . $token;
$result = $this->post($url, $data);
$this->msg = json_encode($result);
$this->validateData($result);
return $this->resultHandle();
}

@ -660,6 +660,7 @@ class Server
{
$token = $this->authorizerAccessToken($appid);
if ($token) {
$url = "https://api.weixin.qq.com/wxa/setwebviewdomain?access_token=$token";
$data['action'] = 'set';
$data['webviewdomain'] = $domain;

@ -508,9 +508,9 @@ class Wholesaler
if ($token) {
$url = "https://api.weixin.qq.com/wxa/modify_domain_directly?access_token=$token";
$data['action'] = 'set';
$data['requestdomain'] = [$domain, 'https://apis.map.gg.com','https://qiniu.shop.royaum.com.cn'];
$data['uploaddomain'] = [$domain,'https://qiniu.shop.royaum.com.cn'];
$data['downloaddomain'] = [$domain,'https://qiniu.shop.royaum.com.cn'];
$data['requestdomain'] = [$domain, 'https://apis.map.gg.com', 'https://qiniu.shop.royaum.com.cn'];
$data['uploaddomain'] = [$domain, 'https://qiniu.shop.royaum.com.cn'];
$data['downloaddomain'] = [$domain, 'https://qiniu.shop.royaum.com.cn'];
$result = $this->curlPost($url, json_encode($data));
Db::table('yoshop_wx_server')->insertGetId(['content' => "设置域名信息", 'created_at' => date('Y-m-d H:i:s')]);
Db::table('yoshop_wx_server')->insertGetId(['content' => $result, 'created_at' => date('Y-m-d H:i:s')]);
@ -546,8 +546,6 @@ class Wholesaler
$data['owner_setting']['contact_qq'] = '527264601';
$data['owner_setting']['notice_method'] = '公告';
$result = $this->curlPost($url, json_encode($data));
Db::table('yoshop_wx_server')->insertGetId(['content' => "设置隐私信息", 'created_at' => date('Y-m-d H:i:s')]);
Db::table('yoshop_wx_server')->insertGetId(['content' => $result, 'created_at' => date('Y-m-d H:i:s')]);
$result = json_decode($result, true);
if ($result && !empty($result['errmsg']) && $result['errmsg'] == 'ok') {
return true;
@ -659,8 +657,6 @@ class Wholesaler
$data['action'] = 'set';
$data['webviewdomain'] = $domain;
$result = $this->curlPost($url, json_encode($data));
Db::table('yoshop_wx_server')->insertGetId(['content' => "业务域名", 'created_at' => date('Y-m-d H:i:s')]);
Db::table('yoshop_wx_server')->insertGetId(['content' => $result, 'created_at' => date('Y-m-d H:i:s')]);
$result = json_decode($result, true);
if ($result && !empty($result['errmsg']) && $result['errmsg'] == 'ok') {
return true;
@ -698,8 +694,9 @@ class Wholesaler
return 0;
}
public function submitAudit($appid): bool
public function submitAudit($appid)
{
$msg = 'ok';
$access_token = $this->authorizerAccessToken($appid);
if ($access_token) {
$url = 'https://api.weixin.qq.com/wxa/submit_audit?access_token=' . $access_token;
@ -718,11 +715,12 @@ class Wholesaler
$up['audit_time'] = date('Y-m-d H:i:s');
$up['auditid'] = $result['auditid'];
$model->update($up, ['appid' => $appid]);
return true;
} else {
$msg = !empty($result['errmsg']) ? $result['errmsg'] : '提交失败(未知错误)';
}
}
return false;
return $msg;
}
/**

@ -0,0 +1,50 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
class Retail extends BaseModel
{
// 定义表名
protected $name = 'retail_price';
// 定义主键
protected $pk = 'retail_price_id';
// 开启自动写入时间戳
protected $autoWriteTimestamp = true;
// 创建时间字段
protected $createTime = 'create_time';
// 更新时间字段
protected $updateTime = 'update_time';
public function getList(array $where)
{
return $this->where($where)->order('sort', 'asc')->select();
}
/**
* @notes:详情
* @param $where
* @param array $with
* @return static|array|null
* @author: wanghousheng
*/
public static function detail($where, array $with = [])
{
return static::get($where, $with);
}
}

@ -0,0 +1,35 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\common\model;
use cores\BaseModel;
class RetailOrder extends BaseModel
{
// 定义表名
protected $name = 'retail_order';
// 定义主键
protected $pk = 'retail_order_id';
// 开启自动写入时间戳
protected $autoWriteTimestamp = true;
// 创建时间字段
protected $createTime = 'create_time';
// 更新时间字段
protected $updateTime = 'update_time';
}

@ -0,0 +1,100 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\store\controller;
use think\response\Json;
use app\store\model\Retail as RetailModel;
use function Symfony\Component\VarDumper\Dumper\esc;
class Retail extends Controller
{
/**
* 查看所有会员售价
* @return Json
*/
public function list(): Json
{
$where = [];
$type = $this->request->post('retailType');
if ($type) {
$where['retail_type'] = $type;
}
// $model = new RetailModel();
// $list = $model->getList($where);
$list = RetailModel::withoutGlobalScope()->where($where)->select();
return $this->renderSuccess(compact('list'));
}
/**
* @notes:新增
* @return Json
*
*/
public function add(): Json
{
$data = $this->postForm();
$id = $this->getStoreId();
if (!$data) {
return $this->renderError('缺少必要参数');
}
$model = new RetailModel();
if ($model->add($data)) {
return $this->renderSuccess('添加成功');
}
return $this->renderError($model->getError() ?: '添加失败');
}
/**
* @notes:编辑
* @param int $retailPriceId
* @return Json
* @author:
*/
public function edit(int $retailPriceId): Json
{
$data = $this->postForm();
if (!$data) {
return $this->renderError('缺少必要参数');
}
$model = RetailModel::withoutGlobalScope()->where('retail_price_id', $retailPriceId)->find();
if (!$model) {
return $this->renderError('找不到指定的数据');
}
$data['update_time']=time();
RetailModel::withoutGlobalScope()->where('retail_price_id', $retailPriceId)->update($data);
return $this->renderSuccess('编辑成功');
}
/**
* @notes:删除
* @param array $identityId
* @return Json
* @author: wanghousheng
*/
public function delete(array $retailPriceId): Json
{
$model = new RetailModel;
if ($model->remove($retailPriceId)) {
return $this->renderSuccess('删除成功');
}
return $this->renderError('删除失败');
}
}

@ -0,0 +1,73 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\store\model;
use app\common\model\Retail as RetailModel;
class Retail extends RetailModel
{
public function getList(array $where)
{
return $this->where($where)->order('sort', 'asc')->select();
}
/**
* @notes:新增
* @param $data
* @return bool
*/
public function add($data): bool
{
$data['store_id'] = self::$storeId;
return $this->save($data);
}
/**
* @notes:编辑
* @param $data
* @return bool
*/
public function edit($data): bool
{
return $this->save($data) !== false;
}
/**
* @notes:详情
* @param $where
* @param array $with
* @return static|array|null
* @author: wanghousheng
*/
public static function detail($where, array $with = [])
{
return static::get($where, $with);
}
/**
* @notes:删除
* @param array $IdentityId
* @return bool
* @author: wanghousheng
*/
public function remove(array $retailPriceId): bool
{
if (static::whereIn('retail_price_id', $retailPriceId)->delete()) {
return true;
}
return false;
}
}
Loading…
Cancel
Save