企业付款 todo
parent
eecf325b41
commit
09c53981b5
|
|
@ -69,6 +69,8 @@ class OrderProfitController extends AdminController
|
|||
$show->field('money');
|
||||
$show->field('status')->using(OrderProfit::$statusMap)->dot(OrderProfit::$statusColor);
|
||||
$show->field('paid_at');
|
||||
$show->field('pay_way');
|
||||
$show->field('pay_no');
|
||||
$show->field('remarks');
|
||||
$show->field('created_at');
|
||||
$show->field('updated_at');
|
||||
|
|
|
|||
|
|
@ -175,17 +175,19 @@ class StoreController extends AdminController
|
|||
$form->text('remarks');
|
||||
|
||||
$form->disableDeleteButton();
|
||||
|
||||
// 管理员删除店铺
|
||||
if ($form->isDeleting() && $canAdmin) {
|
||||
$info = Store::find($form->getKey());
|
||||
// 删除店铺关联的数据
|
||||
$info->adminUsers()->detach();
|
||||
$info->productSkus()->detach();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
$info = Store::find($id);
|
||||
// 删除店铺关联的数据
|
||||
$info->adminUsers()->detach();
|
||||
$info->productSkus()->detach();
|
||||
|
||||
return parent::destroy($id);
|
||||
}
|
||||
|
||||
protected function canAdmin()
|
||||
{
|
||||
return Admin::user()->isRole('administrator');
|
||||
|
|
|
|||
|
|
@ -2,9 +2,8 @@
|
|||
|
||||
namespace App\Admin\Controllers;
|
||||
|
||||
use App\Admin\Repositories\Vip;
|
||||
use App\Exceptions\BizException;
|
||||
use App\Models\Vip as VipModel;
|
||||
use App\Models\Vip;
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Form;
|
||||
use Dcat\Admin\Grid;
|
||||
|
|
@ -32,20 +31,20 @@ class VipController extends AdminController
|
|||
|
||||
/** 操作 **/
|
||||
//新增
|
||||
// if (Admin::user()->can('dcat.admin.vips.create')) {
|
||||
// $grid->disableCreateButton(false);
|
||||
// $grid->enableDialogCreate();
|
||||
// }
|
||||
if (Admin::user()->can('dcat.admin.vips.create')) {
|
||||
$grid->disableCreateButton(false);
|
||||
$grid->enableDialogCreate();
|
||||
}
|
||||
//修改
|
||||
$grid->showQuickEditButton(Admin::user()->can('dcat.admin.vips.edit'));
|
||||
//删除以及自定义操作
|
||||
// $grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
// $actions->disableDelete(Admin::user()->cannot('dcat.admin.vips.destroy'));
|
||||
// });
|
||||
$grid->actions(function (Grid\Displayers\Actions $actions) {
|
||||
$actions->disableDelete(Admin::user()->cannot('dcat.admin.vips.destroy'));
|
||||
});
|
||||
|
||||
$grid->filter(function (Grid\Filter $filter) {
|
||||
$filter->panel(false);
|
||||
$filter->like('name');
|
||||
$filter->like('name')->width(3);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -62,6 +61,8 @@ class VipController extends AdminController
|
|||
return Show::make($id, new Vip(), function (Show $show) {
|
||||
$show->field('id');
|
||||
$show->field('name');
|
||||
$show->field('sort');
|
||||
$show->filed('slug');
|
||||
$show->column('ratio')->as(function ($value) {
|
||||
return $value . '%';
|
||||
});
|
||||
|
|
@ -80,18 +81,17 @@ class VipController extends AdminController
|
|||
{
|
||||
return Form::make(new Vip(), function (Form $form) {
|
||||
$form->display('id');
|
||||
$form->number('sort')->min(1)->required()->help('不可重复');
|
||||
$form->text('name')->required();
|
||||
$form->radio('slug')->options(Vip::$typeMap)->default(Vip::TYPE_FAVOITE);
|
||||
$form->number('ratio')->min(0)->max(100)->help('例如: 60%, 填写 60 即可');
|
||||
$form->number('growth_value')->min(0)->default(0);
|
||||
|
||||
$form->display('created_at');
|
||||
$form->display('updated_at');
|
||||
$form->number('growth_value')->min(0)->default(0)->help('升级到此等级所需的成长值');
|
||||
});
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
$vip = VipModel::findOrFail($id);
|
||||
$vip = Vip::findOrFail($id);
|
||||
if ($vip->hasUser()) {
|
||||
throw new BizException(__('vip.options.deny_message'));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,9 +38,18 @@ class ProfitSuccessForm extends Form implements LazyRenderable
|
|||
{
|
||||
$order = OrderProfit::findOrFail($this->payload['id']);
|
||||
$service = new DistributeService();
|
||||
if ($input['pay_way'] === 'wechat-transfer' && !$order->pay_no) {
|
||||
$order->update([
|
||||
'pay_no' => serial_number()
|
||||
]);
|
||||
}
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
$service->success($order, $input);
|
||||
if ($input['pay_way'] === 'wechat-transfer') {
|
||||
$service->wechatTransfer($order);
|
||||
} else {
|
||||
$service->success($order, $input);
|
||||
}
|
||||
DB::commit();
|
||||
} catch (Throwable $th) {
|
||||
DB::rollBack();
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Repositories;
|
||||
|
||||
use App\Models\Vip as Model;
|
||||
use Dcat\Admin\Repositories\EloquentRepository;
|
||||
|
||||
class Vip extends EloquentRepository
|
||||
{
|
||||
/**
|
||||
* Model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $eloquentClass = Model::class;
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ namespace App\Endpoint\Api\Http\Controllers\Order;
|
|||
|
||||
use App\Endpoint\Api\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\{OrderPre, ProductSku};
|
||||
use App\Models\{OrderPre, ProductSku, Store};
|
||||
use App\Services\OrderService;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Exceptions\BizException;
|
||||
|
|
@ -30,19 +30,29 @@ class OrderPreController extends Controller
|
|||
'products.required' => '未选择商品'
|
||||
]);
|
||||
|
||||
// 验证商品是否属于该店铺
|
||||
$store = Store::findOrFail($request->input('store_id'));
|
||||
|
||||
$products = $request->input('products');
|
||||
// 验证商品的购买数量 大于 发货数量
|
||||
foreach($products as $item) {
|
||||
$quantity = $item['quantity'];
|
||||
$send = $item['send'];
|
||||
$sku_id = $item['sku_id'];
|
||||
|
||||
// 验证商品是否属于该店铺
|
||||
if (!$store->productSkus()->wherePivot('product_sku_id', $sku_id)->exists()) {
|
||||
throw new BizException('商品未在该店铺出售, ' . $sku_id);
|
||||
}
|
||||
|
||||
// 验证商品的购买数量 大于 发货数量
|
||||
if ($send > $quantity) {
|
||||
throw new BizException('商品购买数量大于发货数量, ' . $item['sku_id']);
|
||||
throw new BizException('商品购买数量大于发货数量, ' . $sku_id);
|
||||
}
|
||||
}
|
||||
|
||||
$order_pre = OrderPre::create([
|
||||
'user_id' => $user->id,
|
||||
'store_id' => $request->input('store_id'),
|
||||
'store_id' => $store->id,
|
||||
'products' => $request->input('products'),
|
||||
'remarks' => $request->input('remarks'),
|
||||
'others' => [
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ class OrderProfit extends Model
|
|||
3 => 'danger'
|
||||
];
|
||||
|
||||
protected $fillable = ['id', 'order_id', 'from_user_id', 'user_id', 'role', 'role_name', 'growth_value', 'ratio', 'money', 'status', 'paid_at', 'pay_data', 'remarks'];
|
||||
protected $fillable = ['id', 'order_id', 'from_user_id', 'user_id', 'role', 'role_name', 'growth_value', 'ratio', 'money', 'status', 'paid_at', 'pay_no', 'pay_way', 'pay_data', 'remarks'];
|
||||
|
||||
public function user()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ class ShippingRule extends Model
|
|||
public const TYPE_FREE = 1;//包邮
|
||||
public const TYPE_WEIGHT = 2;//计算重量
|
||||
|
||||
protected $fillable = ['info', 'remarks', 'template_id', 'type', 'zones'];
|
||||
|
||||
protected $casts = [
|
||||
// 'info' => JsonArray::class,
|
||||
'zones' => JsonArray::class,
|
||||
|
|
|
|||
|
|
@ -8,8 +8,17 @@ use Illuminate\Database\Eloquent\Model;
|
|||
|
||||
class Vip extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasDateTimeFormatter;
|
||||
use HasFactory, HasDateTimeFormatter;
|
||||
|
||||
const TYPE_FAVOITE = 'favoite';
|
||||
const TYPE_AGENT = 'agent';
|
||||
|
||||
protected $fillable = ['growth_value', 'name', 'ratio', 'slug', 'sort'];
|
||||
|
||||
public static $typeMap = [
|
||||
self::TYPE_FAVOITE => '爱好者',
|
||||
self::TYPE_AGENT => '代理'
|
||||
];
|
||||
|
||||
public function users()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
namespace App\Services;
|
||||
|
||||
use App\Models\{User, Order, SalesValueLog, Vip, OrderProfit};
|
||||
use App\Services\Payment\WxpayService;
|
||||
use App\Enums\SocialiteType;
|
||||
use App\Exceptions\BizException;
|
||||
|
||||
/**
|
||||
* 分销模块
|
||||
|
|
@ -94,6 +97,27 @@ class DistributeService
|
|||
$order->profits()->createMany($profit_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用微信企业付款
|
||||
* 调用之前, 需要提前生成商户订单号
|
||||
*/
|
||||
public function wechatTransfer(OrderProfit $profit)
|
||||
{
|
||||
$user = $profit->user;
|
||||
$openid = $user->socialites()->where('socialite_type', SocialiteType::WechatMiniProgram->value)->value('socialite_id');
|
||||
$result = (new WxpayService())->transfer([
|
||||
'partner_trade_no' => $profit->pay_no,
|
||||
'openid' => $openid,
|
||||
'check_name' => 'NO_CHECK',
|
||||
'amount' => $profit->money * 100,
|
||||
'desc' => '推荐返利',
|
||||
]);
|
||||
|
||||
$this->success($profit, [
|
||||
'paid_at' => data_get($result, 'payment_time')
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返现记录支付成功
|
||||
*
|
||||
|
|
|
|||
|
|
@ -55,6 +55,56 @@ class WxpayService
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信企业付款到零钱
|
||||
*
|
||||
* @param array $params
|
||||
* @return array
|
||||
*/
|
||||
public function transfer(array $params)
|
||||
{
|
||||
$config = config('wechat.payment.default');
|
||||
if (!isset($params['openid']) && config('app.debug')) {
|
||||
$params['openid'] = 'oU7xS5UspzVvpPEBqKZuW6N9WXDg';
|
||||
}
|
||||
$app = Factory::payment($config);
|
||||
|
||||
// 服务商模式 (子商户)
|
||||
$appId = config('wechat.payment.sub.app_id');
|
||||
$mchId = config('wechat.payment.sub.mch_id');
|
||||
|
||||
if ($appId && $mchId) {
|
||||
$app->setSubMerchant($mchId, $appId);
|
||||
}
|
||||
|
||||
/*
|
||||
'partner_trade_no' => '1233455', // 商户订单号,需保持唯一性(只能是字母或者数字,不能包含有符号)
|
||||
'openid' => 'oxTWIuGaIt6gTKsQRLau2M0yL16E',
|
||||
'check_name' => 'FORCE_CHECK', // NO_CHECK:不校验真实姓名, FORCE_CHECK:强校验真实姓名
|
||||
're_user_name' => '王小帅', // 如果 check_name 设置为FORCE_CHECK,则必填用户真实姓名
|
||||
'amount' => 10000, // 企业付款金额,单位为分
|
||||
'desc' => '理赔', // 企业付款操作说明信息。必填
|
||||
*/
|
||||
$result = $app->transfer->toBalance($params);
|
||||
$this->validateResult($result);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询 微信企业付款到零钱 的订单
|
||||
*
|
||||
* @param string $no 商户订单号
|
||||
* @return array
|
||||
*/
|
||||
public function queryTransfer($no)
|
||||
{
|
||||
$config = config('wechat.payment.transfer');
|
||||
$app = Factory::payment($config);
|
||||
$result = $app->transfer->queryBalanceOrder($no);
|
||||
$this->validateResult($result);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据商户订单号退款
|
||||
*
|
||||
|
|
|
|||
|
|
@ -77,6 +77,15 @@ return [
|
|||
'app_id' => env('WECHAT_PAYMENT_SUB_APPID'),
|
||||
'mch_id' => env('WECHAT_PAYMENT_SUB_MCH_ID'),
|
||||
],
|
||||
// 企业付款
|
||||
'transfer' => [
|
||||
'sandbox' => env('WECHAT_PAYMENT_SANDBOX', false),
|
||||
'app_id' => env('WECHAT_PAYMENT_SUB_APPID'),
|
||||
'mch_id' => env('WECHAT_PAYMENT_SUB_MCH_ID'),
|
||||
'key' => env('WECHAT_PAYMENT_SUB_KEY'),
|
||||
'cert_path' => env('WECHAT_PAYMENT_SUB_CERT_PATH'),
|
||||
'key_path' => env('WECHAT_PAYMENT_SUB_KEY_PATH'),
|
||||
],
|
||||
// 商城 - 微信小程序支付
|
||||
'mini_program' => [
|
||||
'sandbox' => env('WECHAT_PAYMENT_SANDBOX', false),
|
||||
|
|
|
|||
|
|
@ -26,7 +26,9 @@ class CreateOrderProfitsTable extends Migration
|
|||
$table->tinyInteger('status')->default(0)->comment('状态(0: 待付款, 1: 付款中, 2: 已付款)');
|
||||
$table->string('remarks')->nullable()->comment('备注');
|
||||
$table->timestamp('paid_at')->nullable()->comment('付款时间');
|
||||
$table->text('pay_data')->nullable()->comment('支付信息{pay_way, pay_sn}');
|
||||
$table->string('pay_way')->nullable()->comment('付款方式');
|
||||
$table->string('pay_no')->nullable()->comment('付款流水号');
|
||||
$table->text('pay_data')->nullable()->comment('支付信息');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ class AdminMenuSeeder extends Seeder
|
|||
'icon' => '',
|
||||
'uri' => 'users',
|
||||
],
|
||||
['title' => '代理等级', 'icon' => '', 'uri' => 'vips']
|
||||
],
|
||||
],
|
||||
[
|
||||
|
|
@ -248,31 +249,32 @@ class AdminMenuSeeder extends Seeder
|
|||
'icon' => 'fa fa-jpy',
|
||||
'uri'=> '',
|
||||
'children'=>[
|
||||
[
|
||||
'title' => '可提账户',
|
||||
'icon'=>'',
|
||||
'uri' => 'wallet-logs',
|
||||
],
|
||||
[
|
||||
'title' => '余额账户',
|
||||
'icon' => '',
|
||||
'uri' => 'balance-logs',
|
||||
],
|
||||
[
|
||||
'title' => '积分账户',
|
||||
'icon' => '',
|
||||
'uri' => 'points-logs',
|
||||
],
|
||||
[
|
||||
'title' =>'提现审核',
|
||||
'icon' => '',
|
||||
'uri' =>'wallet-to-bank-logs',
|
||||
],
|
||||
// [
|
||||
// 'title' => '可提账户',
|
||||
// 'icon'=>'',
|
||||
// 'uri' => 'wallet-logs',
|
||||
// ],
|
||||
// [
|
||||
// 'title' => '余额账户',
|
||||
// 'icon' => '',
|
||||
// 'uri' => 'balance-logs',
|
||||
// ],
|
||||
// [
|
||||
// 'title' => '积分账户',
|
||||
// 'icon' => '',
|
||||
// 'uri' => 'points-logs',
|
||||
// ],
|
||||
// [
|
||||
// 'title' =>'提现审核',
|
||||
// 'icon' => '',
|
||||
// 'uri' =>'wallet-to-bank-logs',
|
||||
// ],
|
||||
[
|
||||
'title' => '售后打款',
|
||||
'icon' => '',
|
||||
'uri' =>'finance-after-sales?state=5',
|
||||
],
|
||||
['title' => '提成管理', 'icon' => '', 'uri' => 'profit']
|
||||
],
|
||||
],
|
||||
[
|
||||
|
|
@ -300,7 +302,6 @@ class AdminMenuSeeder extends Seeder
|
|||
'icon' => '',
|
||||
'uri' =>'auth/menus',
|
||||
],
|
||||
['title' => '代理等级', 'icon' => '', 'uri' => 'vips'],
|
||||
[
|
||||
'title' =>'配置管理',
|
||||
'icon' => '',
|
||||
|
|
@ -317,6 +318,7 @@ class AdminMenuSeeder extends Seeder
|
|||
} catch (Throwable $th) {
|
||||
DB::rollBack();
|
||||
report($th);
|
||||
dump($th->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -309,6 +309,17 @@ class AdminPermissionSeeder extends Seeder
|
|||
'store' => [
|
||||
'name' => '店铺管理',
|
||||
'curd' => ['index', 'create', 'store', 'edit', 'update', 'destroy'],
|
||||
],
|
||||
'vip' => [
|
||||
'name' => '代理等级管理',
|
||||
'curd' => ['index', 'create', 'store', 'edit', 'update', 'destroy'],
|
||||
],
|
||||
'profit' => [
|
||||
'name' => '提成管理',
|
||||
'curd' => ['index', 'create', 'store', 'edit', 'update', 'destroy'],
|
||||
'children' => [
|
||||
'pay' => ['name' => '修改支付状态']
|
||||
]
|
||||
]
|
||||
];
|
||||
// try {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class AdminUserSeeder extends Seeder
|
|||
|
||||
$user = $userModel::create([
|
||||
'username' => 'admin',
|
||||
'password' => 'admin',
|
||||
'password' => bcrypt('admin'),
|
||||
'name' => '管理员',
|
||||
]);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,11 +18,13 @@ class ShippingSeeder extends Seeder
|
|||
'name' => '自提'
|
||||
]);
|
||||
|
||||
ShippingRule::create([
|
||||
\DB::table('shipping_rules')->insert([
|
||||
'template_id' => $template->id,
|
||||
'type' => 1,
|
||||
'info' => json_encode(["threshold" => "100"]),
|
||||
'info' => json_encode(["threshold" => "0"]),
|
||||
'zones' => json_encode(Zone::where('type', Zone::TYPE_AREA)->pluck('id')),
|
||||
'created_at' => now(),
|
||||
'updated_at' => now()
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,11 @@ class UserSeeder extends Seeder
|
|||
DB::table('user_vips')->truncate();
|
||||
DB::table('socialite_users')->truncate();
|
||||
DB::table('personal_access_tokens')->truncate();
|
||||
|
||||
DB::table('wallets')->truncate();
|
||||
DB::table('wallet_logs')->truncate();
|
||||
DB::table('wallet_to_bank_logs')->truncate();
|
||||
|
||||
DB::table('balances')->truncate();
|
||||
DB::table('users')->truncate();
|
||||
$this->faker = $this->withFaker();
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ return [
|
|||
'remarks' => '备注',
|
||||
'paid_at' => '付款时间',
|
||||
'pay_way' => '支付方式',
|
||||
'pay_no' => '订单号',
|
||||
'pay_no' => '流水号',
|
||||
],
|
||||
'options' => [
|
||||
],
|
||||
|
|
|
|||
|
|
@ -8,11 +8,12 @@ return [
|
|||
'fields' => [
|
||||
'name' => '等级名称',
|
||||
'growth_value' => '升级',
|
||||
'sort' => '排序',
|
||||
'ratio' => '比例'
|
||||
'sort' => '等级',
|
||||
'ratio' => '比例',
|
||||
'slug' => '类别'
|
||||
],
|
||||
'options' => [
|
||||
'deny' => '删除失败',
|
||||
'deny_message'=>'当前会员等级下会员人数大于0',
|
||||
'deny_message'=> '该等级下还有用户, 无法删除',
|
||||
],
|
||||
];
|
||||
|
|
|
|||
Loading…
Reference in New Issue