Commit 6b3ef861 by lizhilin

更新

parent dabb409e
<?php
namespace App\Admin\Actions;
use Dcat\Admin\Actions\Response;
use App\Admin\Forms\BuyCodeForm;
use App\Models\User;
use Dcat\Admin\Grid\RowAction;
use Dcat\Admin\Traits\HasPermissions;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Http\Request;
use Dcat\Admin\Widgets\Modal;
class UserBuyCode extends RowAction
{
/**
* @return string
*/
protected $title = '<i class="feather icon-stop-circle"> 直购码 </i>';
/**
* 按钮文本
*
* @return string|void
*/
public function title()
{
return '<i class="feather icon-stop-circle"></i> ' . $this->title . '';
}
/**
* Handle the action request.
*
* @param Request $request
*
* @return Response
*/
public function handle(Request $request)
{
$id = $this->getKey() ?? 0;
return $this->response()->success('成功')->refresh();
}
/**
* 渲染模态框.
* @return Modal
*/
public function render()
{
$user_id = $this->getKey() ?? 0;
$userObj = User::find($user_id);
$code = $userObj->buycode ?? '';
// 这里直接创建一个modal框 model的内容由工具表单提供,这里也需要创建一个工具表单才行
return Modal::make()
->lg()
->title('直购码')
->button("直购码")
->body(BuyCodeForm::make())
->onShown(
<<<js
$(document).ready(function () {
var colen = '{$code}';
if(colen.length > 0) {
$(".field_current").html('{$code}');
}
$(".field_userid").val('{$user_id}');
});
js
);
//->button("<button class='btn btn-sm btn-primary'>$this->title</button>"); // 这个button就是对应上面的按钮
}
/**
* @return string|array|void
*/
public function confirm()
{
// return ['Confirm?', 'contents'];
}
/**
* @param Model|Authenticatable|HasPermissions|null $user
*
* @return bool
*/
protected function authorize($user): bool
{
return true;
}
/**
* @return array
*/
protected function parameters()
{
return [];
}
}
......@@ -147,7 +147,7 @@ protected function form()
$form->text('goods_name', '商品名称')->required();
$form->text('goods_sn', '商品编号');
$form->text('first_commission', '直推佣金比例')->help("比例如:30");
$form->text('second_commission', '推佣金比例')->help("比例如:10");
$form->text('second_commission', '推佣金比例')->help("比例如:10");
$form->text('merchant_commission', '商家佣金比例')->help("比例如:10");
$form->text('sale', '销量');
$form->text('high_opinion', '好评率');
......
......@@ -24,7 +24,9 @@ protected function grid()
$grid->column('goods.cover_img', '商品图片')->image('', 100, 100);
$grid->column('goods.goods_name', '商品名称');
$grid->column('attr.attr_val', '商品规格');
$grid->column('change', '增减库存');
$grid->column('change', '增减库存')->display(function ($val) {
return $val > 0 ? "+" . $val : $val;
});
$grid->column('mergs.merchant_name', '商家名称');
$grid->column('mergs.contacts', '联系人');
$grid->column('created_at', '增减日期');
......
......@@ -90,7 +90,7 @@ protected function grid()
// 更改为 panel 布局
$filter->panel();
$filter->equal('order_sn', '订单号')->width(3);
$filter->like('phone', '手机号')->width(3);
$filter->like('mobile', '手机号')->width(3);
$filter->like('merchant.name', '所属商家')->width(3);
//订单状态
$filter->equal('order_status', '订单状态')->select(OrderInfo::STATUS_OPTIONS)->width(3);
......
......@@ -26,7 +26,7 @@ protected function grid()
$uid = request()->get('id');
return Grid::make(User::with(['shuser']), function (Grid $grid) use ($uid) {
$grid->addTableClass(['table-text-center']);
$grid->model()->where('id', $uid)->orderBy('created_at', 'DESC');
$grid->model()->where('spuid', $uid)->orderBy('created_at', 'DESC');
//$grid->column('id')->sortable();
$grid->column('name', '昵称');
$grid->column('phone', '手机号');
......
......@@ -3,6 +3,7 @@
namespace App\Admin\Controllers;
use App\Models\UserBuycodeCheck;
use App\Admin\Forms\CheckBuycode;
use Dcat\Admin\Form;
use Dcat\Admin\Grid;
use Dcat\Admin\Show;
......@@ -20,14 +21,31 @@ protected function grid()
return Grid::make(UserBuycodeCheck::with(['user']), function (Grid $grid) {
$grid->column('id')->sortable();
$grid->column('user.avatar', '用户头像')->image('', 100, 100);
$grid->column('user.nickname', '用户昵称');
$grid->column('user.name', '用户昵称');
$grid->column('user.phone', '手机号');
$grid->column('before_code');
$grid->column('after_code');
$grid->column('status');
$grid->column('status')
->using(UserBuycodeCheck::STATUS)->dot([
0 => 'primary',
1 => 'success',
2 => 'danger'
])
->if(function ($column) {
return $column->getValue() == 0;
})->display('点击审批')->modal(function (Grid\Displayers\Modal $modal) {
// 标题
$modal->title('提现审核');
// 自定义图标
$modal->icon('feather icon-edit');
// 传递当前行字段值
return CheckBuycode::make()->payload(['id' => $this->id]);
});
// $grid->column('created_at');
// $grid->column('updated_at')->sortable();
$grid->disableCreateButton();
$grid->disableActions();
$grid->disableRowSelector();
$grid->filter(function (Grid\Filter $filter) {
// 更改为 panel 布局
$filter->panel();
......
......@@ -4,6 +4,7 @@
use App\Admin\Forms\EditPermission;
use App\Admin\Forms\updatePassword;
use App\Admin\Actions\UserBuyCode;
use Dcat\Admin\Grid\RowAction;
use App\Models\User;
use App\Models\UserPermission;
......@@ -45,6 +46,7 @@ protected function grid()
//$grid->simplePaginate();
$grid->actions(function (Grid\Displayers\Actions $actions) {
$actions->append(new UserBuyCode($actions->row->id));
// 添加一个按钮,并设置其属性
$actions->append('<a href="/user-share?id=' . $this->id . '" alt="查看下级" target="_blank">查看下级</a>');
......@@ -58,7 +60,7 @@ protected function grid()
$filter->like('name')->width(3);
$filter->like('phone')->width(3);
$filter->like('buycode', '直购码')->width(3);
$filter->like('buycode', '所属上级')->width(3);
$filter->like('shuser.name', '所属上级')->width(3);
//$filter->equal('role', '身份')->select(['1' => '用户', '2' => '代理商'])->width(3);
$filter->between('created_at', '注册时间')->datetime()->width(4);
});
......
<?php
namespace App\Admin\Forms;
use App\Admin\Actions\UserBuyCode;
use App\Command\Log;
use App\Models\Company;
use App\Models\Employee;
use App\Models\Income;
use App\Models\Merchant;
use App\Models\Pay;
use App\Models\User;
use App\Models\UserBuycodeCheck;
use Dcat\Admin\Widgets\Form;
use Dcat\Admin\Contracts\LazyRenderable;
use Dcat\Admin\Traits\LazyWidget;
use Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Request;
class BuyCodeForm extends Form implements LazyRenderable
{
use LazyWidget;
/**
* Handle the form request.
*
* @param array $input
*
* @return mixed
*/
public function handle(array $input)
{
DB::beginTransaction();
try {
$aftercode = trim($input['buycode']); //修改后直购码
$uid = trim($input['userid']);
$uObj = User::find($uid);
if ($uObj) {
if (!$uObj->buycode) {
throw new Exception('该用户还没绑定直购码!');
}
$checkObj = new UserBuycodeCheck();
$checkObj->uid = $uid;
$checkObj->before_code = $uObj->buycode;
$checkObj->after_code = $aftercode;
$checkObj->save();
}
DB::commit();
} catch (\Exception $exception) {
DB::rollBack();
return $this->response()->error($exception->getMessage())->refresh();
}
return $this->response()->success('提交成功')->refresh();
}
/**
* Build a form here.
*/
public function form()
{
$this->display('current', '当前直购码');
$this->text('buycode', '修改直购码');
$this->hidden('userid');
}
/**
* The data of the form.
*
* @return array
*/
public function default()
{
// 获取外部传递参数
return [];
}
}
<?php
namespace App\Admin\Forms;
use App\Command\Log;
use App\Models\Company;
use App\Models\Employee;
use App\Models\Income;
use App\Models\Merchant;
use App\Models\Pay;
use App\Models\User;
use App\Models\UserBuycodeCheck;
use Dcat\Admin\Widgets\Form;
use Dcat\Admin\Contracts\LazyRenderable;
use Dcat\Admin\Traits\LazyWidget;
use Exception;
use Illuminate\Support\Facades\DB;
class CheckBuycode extends Form implements LazyRenderable
{
use LazyWidget;
/**
* Handle the form request.
*
* @param array $input
*
* @return mixed
*/
public function handle(array $input)
{
DB::beginTransaction();
$checkObj = UserBuycodeCheck::find($this->payload['id']);
$userId = $checkObj->uid;
$after_code = $checkObj->after_code;
$merObj = Merchant::where('buycode', $after_code)->first();
if (!$merObj) {
return $this->response()->error('该商户不存在!')->refresh();
}
try {
$status = (int)$input['status']; //审核状态 0:审核中 1:通过 2:拒绝
$checkObj->status = $status;
if ($checkObj->save()) {
$uObj = User::find($userId);
$uObj->buycode = $checkObj->after_code;
$uObj->merchant_id = $merObj->id;
$uObj->save();
}
DB::commit();
Log::add('直购码变更', $checkObj->toArray());
} catch (\Exception $exception) {
DB::rollBack();
Log::add('直购码变更失败', $exception->getMessage());
return $this->response()->error($exception->getMessage())->refresh();
}
return $this->response()->success('提交成功')->refresh();
}
/**
* Build a form here.
*/
public function form()
{
$this->radio('status', '审核')->options([1 => '同意', 2 => '拒绝'])
->required();
}
/**
* The data of the form.
*
* @return array
*/
public function default()
{
// 获取外部传递参数
return [];
}
}
......@@ -82,52 +82,6 @@ public function handle(array $input)
return $this->response()->success('用户提现已受理')->refresh();
}
public function handle_202312(array $input)
{
DB::beginTransaction();
try {
$income = Income::find($this->payload['id']);
$income->status = $input['status'];
$income->remark = $input['remark'] ?? '';
if ($income->status == 1) {
// $income->partner_trade_no = Pay::toBalance($income->openid,$income->amount,'用户提现');
$pay_res = Pay::toBalance($income->openid, $income->amount, '用户提现');
Log::add('用户提现-微信结果', $pay_res);
if (!empty($pay_res)) {
$income->partner_trade_no = $pay_res[0];
$income->out_batch_no = $pay_res[1];
$income->batch_id = $pay_res[2];
} else { //提现失败
$income->status = 2;
}
}
$income->save();
if ($income->user_type == 1) {
$em = Employee::find($income->ec_id);
if ($income->status == 2) {
$em->balance += $income->amount;
}
$em->freeze_balance -= $income->amount;;
$em->save();
} else if ($income->user_type == 2) {
$cm = Company::find($income->ec_id);
if ($income->status == 2) {
$cm->balance += $income->amount;
}
$cm->freeze_balance -= $income->amount;
$cm->save();
}
DB::commit();
Log::add('用户提现成功', $income->toArray());
} catch (\Exception $exception) {
DB::rollBack();
Log::add('用户提现失败', $exception);
return $this->response()->error('用户提现失败')->refresh();
}
return $this->response()->success('用户提现成功')->refresh();
}
/**
* Build a form here.
*/
......
......@@ -71,7 +71,7 @@ public function CreateBuyOrder(Request $request)
//----收货地址----
$address = $request->address ?? ''; //详情地址
$area = $request->area ?? '';
$phone = $request->phone ?? '';
$phone = $request->phone ? $request->phone : $userObj->phone;
$consignee = $request->consignee ?? '';
//$address_id = $request->address_id ?? 0; //地址ID
......@@ -160,7 +160,7 @@ public function CreateOrder(Request $request)
//----收货地址----
$address = $request->address ?? ''; //详情地址
$area = $request->area ?? '';
$phone = $request->phone ?? '';
$phone = $request->phone ? $request->phone : $userObj->phone;
$consignee = $request->consignee ?? '';
if (!$catKey) {
return $this->JsonResponse('', '参数错误', 201);
......
......@@ -71,28 +71,30 @@ public static function payNotify($fields = [])
DB::beginTransaction();
try {
//更新订单
$orderObj->order_status = 1;
$orderObj->pay_status = 1;
$orderObj->save();
//更新商品销量、库存
$goodsList = OrderGoods::where("order_id", $orderObj->id)->get();
foreach ($goodsList as $item) {
$gid = $item->goods_id;
$attr_id = $item->attr_id;
$mer_id = $item->merchant_id;
$goods_number = $item->goods_number;
//更新商品规格库存
$attrObj = GoodSku::find($attr_id);
$attr_stock = ($attrObj->stock - $goods_number) > 0 ? $attrObj->stock - $goods_number : 0;
$attrObj->stock = $attr_stock;
$attrObj->save();
//商户规格库存
$mgsObj = MerchantGoodSku::where(['goods_id' => $gid, 'attr_id' => $attr_id, 'merchant_id' => $mer_id])->first();
if ($mer_id && $mgsObj) {
$changeStock = ($mgsObj->stock >= $attr_stock) ? $mgsObj->stock - $attr_stock : 0;
$mgsObj->stock = $changeStock;
$mgsObj->save();
if ($orderObj->pay_status == 0) {
$orderObj->order_status = 1;
$orderObj->pay_status = 1;
$orderObj->save();
//更新商品销量、库存
$goodsList = OrderGoods::where("order_id", $orderObj->id)->get();
foreach ($goodsList as $item) {
$gid = $item->goods_id;
$attr_id = $item->attr_id;
$mer_id = $item->merchant_id;
$goods_number = $item->goods_number;
//更新商品规格库存
$attrObj = GoodSku::find($attr_id);
$attr_stock = ($attrObj->stock - $goods_number) > 0 ? $attrObj->stock - $goods_number : 0;
$attrObj->stock = $attr_stock;
$attrObj->save();
//商户规格库存
$mgsObj = MerchantGoodSku::where(['goods_id' => $gid, 'attr_id' => $attr_id, 'merchant_id' => $mer_id])->first();
if ($mer_id && $mgsObj) {
$changeStock = ($mgsObj->stock >= $attr_stock) ? $mgsObj->stock - $attr_stock : 0;
$mgsObj->stock = $changeStock;
$mgsObj->save();
}
}
}
//支付记录
......
<?php
namespace App\Models;
use WeChatPay\Builder;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Util\PemUtil;
/** * 实测 可用 相关配置弄好
* date: 2022/09/19 18:10
* desc:
*/
class PayV3
{
private $v3_key;
private $merchantId;
private $merchantCertificateSerial;
private $merchantPrivateKeyFilePath;
private $platformCertificateFilePath;
private $platformPublicKeyInstance;
private $instance;
const AUTH_TAG_LENGTH_BYTE = 16;
public function __construct()
{
//证书生成命令(生成的证书在sdk目录 或 自己指定)
//php ./bin/CertificateDownloader.php -k jiaxin**************uzhou20 -m 1614781491 -f /www/wwwroot/项目目录/server/public/cert/apiclient_key.pem -s 629BD177D7******************8CE43244 -o ./
// 商户号
$this->merchantId = env('WX_XCX_MCH_ID');
// v3api秘钥
$this->v3_key = env('WX_XCX_MCH_KEY_V3');
// 「商户API证书」的「证书序列号」 商户平台【API安全】->【API证书】->【查看证书】,可查看商户API证书序列号
$this->merchantCertificateSerial = '45A5D415AAB9AAAF37E7336CE582B4D980CF6B9B';
// 商户API私钥
//$this->merchantPrivateKeyFilePath = $pay_config['apiclient_key']; //"file://"
$this->merchantPrivateKeyFilePath = "file://" .public_path().'/cert/apiclient_key.pem'; //
;
// 微信支付平台证书 首次通过命令行生成 https://github.com/wechatpay-apiv3/wechatpay-php/tree/main/bin
//$this->platformCertificateFilePath = $pay_config['apiclient_cert'];
$this->platformCertificateFilePath ="file:///www/wwwroot/pz/public/cert//wechatpay_4F2000519B652DAF957614D1D6E7879E40DA6EC3.pem" ;
// 构建客户端实例
$this->instance = $this->buildInstance();
//var_dump($this->merchantPrivateKeyFilePath,$this->platformCertificateFilePath);exit;
}
/**
* 商家付款到零钱
* @param string $batch_sn 商户系统内部的商家批次单号
* @param string $out_detail_no 账明细单的唯一标识
* @param float $money 转账金额,单位:元
* @param string $openid 用户openid
* @param string $remark 转账备注
* @param string $user_name 用户姓名,转账金额大于2000元,必填
* @return array
* @throws \Exception
*/
public function transfer(string $batch_sn, string $out_detail_no, float $money, string $openid, string $remark, string $user_name = ''): array
{
$trans_detail = [
'out_detail_no' => $out_detail_no,
'transfer_amount' => intval($money*100) ,
'transfer_remark' => $remark,
'openid' => $openid,
];
if ($money >= 2000) {
if (empty($user_name)) {
throw new \Exception('提现金额大于2000元,真实姓名不能为空');
}
$trans_detail['user_name'] = $this->encrypt($user_name);
}
$response = $this->instance->chain('v3/transfer/batches')->post([
'json' => [
'appid' => env('WX_XCX_APPID'),
'out_batch_no' => $batch_sn,
'batch_name' => '提现转账',
'batch_remark' => '提现转账',
'total_amount' => intval($money*100),
'total_num' => 1,
'transfer_detail_list' => [
$trans_detail
]
]
]);
return json_decode($response->getBody(), true);
}
/**
* 转账明细查询
* @param string $out_batch_no 商户系统内部的商家批次单号
* @param string $out_detail_no 账明细单的唯一标识
* @return array
*/
public function transferQuery(string $out_batch_no, string $out_detail_no = ''): array
{
$api = 'v3/transfer/batches/out-batch-no/' . $out_batch_no;
$query = [];
if ($out_detail_no) {
$api .= '/details/out-detail-no/' . $out_detail_no;
} else {
$query = [
'query' => [
'need_query_detail' => true,
'detail_status' => 'ALL'
]
];
}
$response = $this->instance->chain($api)->get($query);
return json_decode($response->getBody(), true);
}
// 自动更新平台证书
public function autoUpdatePlatformCertificateFile()
{
$result = $this->v3Certificates()['data'];
$data = end($result);
$effective_time = strtotime($data['effective_time']);
if ($effective_time - time() > 0 && $effective_time - time() <= 86400) {
$encrypt_certificate = $data['encrypt_certificate'];
$cert_content = $this->decryptToString($encrypt_certificate['associated_data'], $encrypt_certificate['nonce'], $encrypt_certificate['ciphertext']);
file_exists($this->platformCertificateFilePath) && file_put_contents($this->platformCertificateFilePath, $cert_content);
}
}
// 获取平台证书
private function v3Certificates()
{
$response = $this->instance->chain('v3/certificates')->get();
return json_decode($response->getBody(), true);
}
/**
* Decrypt AEAD_AES_256_GCM ciphertext
* 用于解密v3Certificates接口数据获取证书
* https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_2.shtml
* @param string $associatedData AES GCM additional authentication data
* @param string $nonceStr AES GCM nonce
* @param string $ciphertext AES GCM cipher text
*
* @return string|bool Decrypted string on success or FALSE on failure
*/
private function decryptToString($associatedData, $nonceStr, $ciphertext)
{
$ciphertext = \base64_decode($ciphertext);
if (strlen($ciphertext) <= self::AUTH_TAG_LENGTH_BYTE) {
return false;
}
// ext-sodium (default installed on >= PHP 7.2)
if (function_exists('\sodium_crypto_aead_aes256gcm_is_available') && \sodium_crypto_aead_aes256gcm_is_available()) {
return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $this->v3_key);
}
// ext-libsodium (need install libsodium-php 1.x via pecl)
if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') && \Sodium\crypto_aead_aes256gcm_is_available()) {
return \Sodium\crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $this->v3_key);
}
// openssl (PHP >= 7.1 support AEAD)
if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) {
$ctext = substr($ciphertext, 0, -self::AUTH_TAG_LENGTH_BYTE);
$authTag = substr($ciphertext, -self::AUTH_TAG_LENGTH_BYTE);
return \openssl_decrypt($ctext, 'aes-256-gcm', $this->v3_key, \OPENSSL_RAW_DATA, $nonceStr, $authTag, $associatedData);
}
throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php');
}
// 加密
private function encrypt(string $msg): string
{
return Rsa::encrypt($msg, $this->platformPublicKeyInstance);
}
private function buildInstance(): \WeChatPay\BuilderChainable
{
// 从本地文件中加载「商户API私钥」,「商户API私钥」会用来生成请求的签名
$merchantPrivateKeyInstance = Rsa::from($this->merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);
// 从本地文件中加载 微信支付平台证书
$this->platformPublicKeyInstance = Rsa::from($this->platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
// 从「微信支付平台证书」中获取「证书序列号」
$platformCertificateSerial = PemUtil::parseCertificateSerialNo($this->platformCertificateFilePath);
// 构造一个 APIv3 客户端实例
return Builder::factory([
'mchid' => $this->merchantId,
'serial' => $this->merchantCertificateSerial,
'privateKey' => $merchantPrivateKeyInstance,
'certs' => [
$platformCertificateSerial => $this->platformPublicKeyInstance,
],
]);
}
}
......@@ -11,6 +11,12 @@ class UserBuycodeCheck extends Model
use HasDateTimeFormatter;
protected $table = 'user_buycode_check';
public const STATUS = [
0 => '待审核',
1 => '通过',
2 => '驳回'
];
public function user()
{
return $this->belongsTo(User::class, 'uid');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment