添加:灵活用工插件

This commit is contained in:
wuhui_zzw 2023-11-25 14:51:10 +08:00
parent 609f012aec
commit 14e1972f8f
19 changed files with 1379 additions and 0 deletions

View File

@ -0,0 +1 @@
## 灵活用工

View File

@ -0,0 +1,14 @@
<?php
return [
app\common\events\PluginWasEnabled::class => function ($plugins) {
\Artisan::call('migrate',['--path'=>'plugins/use-staff/migrations','--force'=>true]);
},
app\common\events\PluginWasDisabled::class => function ($plugin) {
},
app\common\events\PluginWasDeleted::class => function () {
\Artisan::call('migrate:rollback',['--path'=>'plugins/use-staff/migrations']);
}
];

View File

@ -0,0 +1,8 @@
"use strict";
$.extend($.locales['en'], {
'welfare': {
test: "JavaScript i18n test: English"
}
});

View File

@ -0,0 +1,5 @@
<?php
return [
'title'=>'this is test title'
];

View File

@ -0,0 +1,6 @@
$.extend($.locales['zh-CN'], {
'welfare': {
test: "JavaScript i18n test: 简体中文"
}
});

View File

@ -0,0 +1,5 @@
<?php
return [
'title'=>'测试标题'
];

View File

@ -0,0 +1,11 @@
{
"name": "use-staff",
"terminal": "wechat|min|wap",
"version": "1.0.1",
"title": "灵活用工",
"description": "灵活用工",
"author": "zzw",
"url": "",
"namespace": "Yunshop\\UseStaff",
"config": "config.tpl"
}

View File

@ -0,0 +1,113 @@
<?php
namespace Yunshop\UseStaff;
class PluginApplication extends \app\common\services\PluginApplication{
protected function setMenuConfig(){
\app\backend\modules\menu\Menu::current()->setPluginMenu('use-staff',[
'name' => '灵活用工',
'type' => 'marketing',
'url' => 'plugin.use-staff.admin.index.index',// url 可以填写http 也可以直接写路由
'url_params' => '',//如果是url填写的是路由则启用参数否则不启用
'permit' => 1,//如果不设置则不会做权限检测
'menu' => 1,//如果不设置则不显示菜单,子菜单也将不显示
'icon' => '',//菜单图标
'list_icon' => 'use-staff',
'item' => 'plugin_use_staff',
'parents' => [],
'top_show' => 0,
'left_first_show' => 0,
'left_second_show' => 1,
'child' => [
'plugin_use_staff_index' => [
'name' => '人员管理',
'permit' => 1,
'menu' => 1,
'icon' => '',
'url' => 'plugin.use-staff.admin.index.index',
'url_params' => '',
'item' => 'plugin_use_staff_index',
'parents' => ['use-staff'],
'child' => [
// 权限补充
'plugin_use_staff_index_index' => [
'name' => '人员管理',
'url' => 'plugin.use-staff.admin.index.index',
'url_params' => '',
'permit' => 1,
'menu' => 0,
'icon' => '',
'item' => 'plugin_use_staff_index_index',
'parents' => ['plugin_use_staff','plugin_use_staff_index'],
],
'plugin_use_staff_index_refreshInfo' => [
'name' => '刷新信息',
'url' => 'plugin.use-staff.admin.index.refreshInfo',
'url_params' => '',
'permit' => 1,
'menu' => 0,
'icon' => '',
'item' => 'plugin_use_staff_index_refreshInfo',
'parents' => ['plugin_use_staff','plugin_use_staff_index'],
],
]
],
'plugin_use_staff_withdrawal' => [
'name' => '提现打款记录',
'permit' => 1,
'menu' => 1,
'icon' => '',
'url' => 'plugin.use-staff.admin.withdrawal.index',
'url_params' => '',
'item' => 'plugin_use_staff_withdrawal',
'parents' => ['use-staff'],
'child' => [
// 权限补充
'plugin_use_staff_withdrawal_index' => [
'name' => '提现打款记录',
'url' => 'plugin.use-staff.admin.withdrawal.index',
'url_params' => '',
'permit' => 1,
'menu' => 0,
'icon' => '',
'item' => 'plugin_use_staff_withdrawal_index',
'parents' => ['plugin_use_staff','plugin_use_staff_withdrawal'],
],
'plugin_use_staff_withdrawal_refreshInfo' => [
'name' => '刷新信息',
'url' => 'plugin.use-staff.admin.withdrawal.refreshInfo',
'url_params' => '',
'permit' => 1,
'menu' => 0,
'icon' => '',
'item' => 'plugin_use_staff_withdrawal_refreshInfo',
'parents' => ['plugin_use_staff','plugin_use_staff_withdrawal'],
],
]
],
/*'plugin_use_staff_index_set' => [
'name' => '基础设置',
'permit' => 1,
'menu' => 1,
'icon' => '',
'url' => 'plugin.use-staff.admin.index.set',
'url_params' => '',
'item' => 'plugin_use_staff_index_set',
'parents' => ['use-staff'],
],*/
]
]);
}
public function boot(){
$events = app('events');
}
}

View File

@ -0,0 +1,103 @@
<?php
namespace Yunshop\UseStaff\admin;
use app\common\components\BaseController;
use app\common\helpers\PaginationHelper;
use Yunshop\UseStaff\models\ExternalApi;
use Yunshop\UseStaff\models\UseStaff;
class IndexController extends BaseController{
/**
* Common: 进入员工管理列表
* Author: wu-hui
* Time: 2023/10/09 14:18
* @return array|string
* @throws \Throwable
*/
public function index(){
//参数获取
$pageSize = request()->input('page_size',10);
$search = request()->input('search');
// 获取列表信息
$result = UseStaff::getList($pageSize,$search);
$data = [
'list' => $result['data'],
'pager' => PaginationHelper::show($result['total'],$result['current_page'],$result['per_page']),
'search' => $search
];
return view('Yunshop\UseStaff::admin.index.index',$data)->render();
}
/**
* Common: 刷新员工入驻信息
* Author: wu-hui
* Time: 2023/10/09 14:31
* @return mixed
*/
public function refreshInfo(){
try{
// 参数获取
$id = request()->input('id');
// 刷新信息
$memberId = UseStaff::where('id',$id)->value('member_id');
(new ExternalApi())->personnelResult($memberId);
// 刷新完成
return $this->message('刷新成功');
}catch(\Exception $e){
return $this->message($e->getMessage());
}
}
public function test(){
// 员工入驻
$info = [
'uid' => '228',
'name' => '胡治金',// 账号名称
'tel' => 18982255122,// 手机号
'card_type' => 1,// 卡类型1=对私2=对公
// 'bank_sub_name' => '',//开户银行支行名称,卡类型为2-对公必填
'account_id_start' => '20201107',// 证件有效期开始时间,格式YYYYMMDD
'bank_act_name' => '胡治金',// 银行卡持有人姓名
'card_num' => '6217253100008301299',// 银行卡卡号
'account_id' => '511321198404020899',// 银行卡持有人身份证号码
'mer_type' => 3,// 商户类型1=个体户3=个人
];
(new ExternalApi())->personnelAccess($info);
// 员工入驻 - 结果查询
/*$staffInfo = (new ExternalApi())->personnelResult(592217313649454896);
debug($staffInfo);*/
// 员工签约
// $result = (new ExternalApi())->personalContractCreate(592217313649454896);
// 员工签约状态查询
// $result = (new ExternalApi())->personalContractQuery(592217313649454896);
// debug($result);
// 费用代发接外部订单号(新)
// $rand = rand(0,50) / 100;
// if($rand == 0) $rand = 0.1;
// $info = [
// 'uid' => '228',
// 'month' => date("Ym",time()),
// 'member_id' => '592217313649454896',
// 'salary' => $rand
// ];
// $result = (new ExternalApi())->salaryModelOutOrder($info);
// debug(['请求结果'=>$result]);
// // 费用代发 - 结果查询
// $result = (new ExternalApi())->salaryOutOrderResult('SHB000007570');
// debug($result);
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace Yunshop\UseStaff\admin;
use app\common\components\BaseController;
use app\common\helpers\PaginationHelper;
use Yunshop\UseStaff\models\ExternalApi;
use Yunshop\UseStaff\models\UseStaffSalary;
class WithdrawalController extends BaseController{
/**
* Common: 进入提现记录列表
* Author: wu-hui
* Time: 2023/10/09 14:58
* @return array|string
* @throws \Throwable
*/
public function index(){
//参数获取
$pageSize = request()->input('page_size',10);
$search = request()->input('search');
// 获取列表信息
$result = UseStaffSalary::getList($pageSize,$search);
$data = [
'list' => $result['data'],
'pager' => PaginationHelper::show($result['total'],$result['current_page'],$result['per_page']),
'search' => $search
];
return view('Yunshop\UseStaff::admin.withdrawal.index',$data)->render();
}
/**
* Common: 刷新提现打款信息
* Author: wu-hui
* Time: 2023/10/09 15:00
* @return mixed
*/
public function refreshInfo(){
try{
// 参数获取
$id = request()->input('id');
// 刷新信息
$attachId = UseStaffSalary::where('id',$id)->value('attach_id');
(new ExternalApi())->salaryOutOrderResult($attachId);
// 刷新完成
return $this->message('刷新成功');
}catch(\Exception $e){
return $this->message($e->getMessage());
}
}
}

View File

@ -0,0 +1,65 @@
<?php
namespace Yunshop\UseStaff\api;
use app\common\components\ApiController;
use Yunshop\UseStaff\models\ExternalApi;
use Yunshop\UseStaff\models\UseStaff;
class IndexController extends ApiController{
/**
* Common: 获取某个用户入驻信息
* Author: wu-hui
* Time: 2023/10/10 11:40
* @return \Illuminate\Http\JsonResponse
* @throws \Exception
*/
public function getInfo(){
$uid = \YunShop::app()->getMemberId();
$field = ['id','name','tel','card_type','bank_sub_name','account_id_start','bank_act_name','card_num','account_id','mer_type','status','member_id','trans_seq_id'];
$staff = UseStaff::getSingleInfo(['uid'=>$uid],$field,true);
return $this->successJson('获取成功',$staff ?? []);
}
/**
* Common: 员工入驻申请 | 编辑信息
* Author: wu-hui
* Time: 2023/10/10 12:02
* @return \Illuminate\Http\JsonResponse
*/
public function applyToJoin(){
// 参数获取
$info = request()->input('info');
$info['uid'] = \YunShop::app()->getMemberId();
try{
$applyResult = (new ExternalApi())->personnelAccess($info);
(new ExternalApi())->personnelResult($applyResult['memberId'],$applyResult['transSeqId']);
return $this->successJson('申请成功');
}catch(\Exception $e){
return $this->errorJson($e->getMessage());
}
}
/**
* Common: 获取合同信息
* Author: wu-hui
* Time: 2023/10/10 14:35
* @return \Illuminate\Http\JsonResponse
*/
public function getContractInfo(){
try{
$uid = \YunShop::app()->getMemberId();
$result = (new ExternalApi())->personalContractCreate($uid);
return $this->successJson('合同信息',[
'down_url' => urldecode($result['downUrl']),
'sign_url' => urldecode($result['signUrl']),
'view_url' => urldecode($result['viewUrl'])
]);
}catch(\Exception $e){
return $this->errorJson($e->getMessage());
}
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace Yunshop\UseStaff\api;
use app\common\components\ApiController;
use Yunshop\UseStaff\models\ExternalApi;
use Yunshop\UseStaff\models\UseStaff;
class NotifyController extends ApiController{
protected $ignoreAction = ['access','salary'];
/**
* Common: 员工入驻 - 申请入驻 - 异步通知
* Author: wu-hui
* Time: 2023/10/09 12:02
* @return false|string
*/
public function access(){
// 参数获取并且处理
try{
$info = request()->all();
\Log::debug('------- [异步通知]员工入驻 - 申请入驻 -----',$info);
$staff = UseStaff::getSingleInfo(['order_id'=>$info['transSeqId']]);
// 修改状态
UseStaff::uniacid()->where('member_id',$info['memberId'])->update([
'status' => $info['state']
]);
return 'RECV_ORD_ID_'.$staff['order_id'];
}catch(\Exception $e){
\Log::debug('------- [异步通知]员工入驻 - 申请入驻 - 错误 -----',$e->getMessage());
}
return false;
}
/**
* Common: 费用代发 - 申请代发 - 异步通知
* Author: wu-hui
* Time: 2023/10/09 11:54
* @return string
*/
public function salary(){
try{
// 参数获取并且处理
$info = request()->all();
\Log::debug('------- [异步通知]费用代发 - 申请代发 -----',$info);
// 为了保证数据的一致性 这里需要调用查询接口进行处理
(new ExternalApi())->salaryOutOrderResult($info['attachId']);
return 'RECV_ORD_ID_'.$info['orderId'];
}catch(\Exception $e){
\Log::debug('------- [异步通知]费用代发 - 申请代发 - 错误 -----',$e->getMessage());
}
return false;
}
}

View File

@ -0,0 +1,341 @@
<?php
namespace Yunshop\UseStaff\models;
use app\common\models\BaseModel;
use Exception;
use Illuminate\Support\Facades\URL;
class ExternalApi extends BaseModel{
public $table = false;
// 测试环境
private $apiLink = 'https://bwmsweb.testpnr.com/bwmsweb';// 生产地址
private $accessId = 'CQZL0606202306061047027822700798';// 接入ID
private $accessSecret = '0sSEAHC80w3HJ55FLS0akVzIKR0TTH6S';// 请求密钥
private $groundAgentId = 'L20221116094640944';// 落地公司机构号
private $bmemberId = '942103656627706351';// 落地公司商户号
private $coreAgentId = 'C20230109095415231';// 核心企业机构号
private $memberId = '637870957126184445';// 核心企业商户号
// 生产环境
// private $apiLink = 'https://ms.xs-ygj.com/bwmsweb';// 生产地址
// private $accessId = '';// 接入ID
// private $accessSecret = '';// 请求密钥
// private $groundAgentId = '';// 落地公司机构号
// private $bmemberId = '';// 落地公司商户号
// private $coreAgentId = '';// 核心企业机构号
// private $memberId = '';// 核心企业商户号
public function __construct(array $attributes = []){
parent::__construct($attributes);
}
/**
* Common: 发起请求 - 请求接口
* Author: wu-hui
* Time: 2023/10/08 15:46
* @param $api
* @param $params
* @return mixed|void
*/
private function requestApi($api,$params){
try{
// 获取签名
$sign = $this->getSign($params);
// 发起请求
$data = [
'jsonStr' => json_encode($params,JSON_UNESCAPED_UNICODE),
'sign' => $sign,
];
$header = [
'Content-Type: application/json; charset=utf-8',
'Cache-Control: no-cache',
'Pragma: no-cache'
];
$result = curlPost($this->apiLink.$api,$data,30,$header,'json');
$result['jsonStr'] = json_decode($result['jsonStr'],true);
return $result['jsonStr'];
}catch(\Exception $e){
\Log::debug('------- 灵活务工 - 接口请求 - 失败原因 -----',$e->getMessage());
return $e->getMessage();
}
}
/**
* Common: 发起请求 - 获取签名
* Author: wu-hui
* Time: 2023/10/08 14:41
* @param $params
* @return false|string
*/
private function getSign($params){
// 按照 key 的 ASCII 字符串顺序升序排列
ksort($params);
// 获取签名字符串
$signStr = '';
foreach($params as $key => $val){
$signStr .= is_array($val) ? json_encode($val) : $val;
}
// 获取签名
return hash_hmac("sha256",$signStr,$this->accessSecret);
}
/**
* Common: 根据方法名称 返回回调地址
* Author: wu-hui
* Time: 2023/10/09 11:24
* @param $funName
* @return string
* @throws Exception
*/
private function getNotifyUrl($funName){
// 异步通知地址前缀
$domainName = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http";
$domainName .= "://" . $_SERVER['HTTP_HOST'];
$uniacid = \YunShop::app()->uniacid;
// 回调地址长度不能超过100
$notifyUrl = $domainName."/addons/yun_shop/api.php?i={$uniacid}&route=plugin.use-staff.api.notify.".$funName;
if(strlen($notifyUrl) > 100) throw new \Exception('异步通知地址长度超出限制,请联系管理员处理');
return $notifyUrl;
}
/**
* Common: 员工入驻 - 申请入驻
* Author: wu-hui
* Time: 2023/10/08 16:58
* @param $info
* @return mixed|void
* @throws Exception
*/
public function personnelAccess($info){
// 基本参数
$params = [
'accessId' => $this->accessId,// [必填]接入ID
'orderId' => createNo('YCH',6,TRUE),// [必填]请求流水号
'coreAgentId' => $this->coreAgentId,// [必填]核心企业机构号
'groundAgentId' => $this->groundAgentId,// [必填]落地公司机构号
'noticeUrl' => $this->getNotifyUrl('access'),// [必填]异步通知地址
'name' => $info['name'],// [必填]账户名称
// 'jobNum' => '',// [选填]工号
'contactTelNo' => $info['tel'],// [必填]手机号
// 'bankProvId' => '510000',// [必填]银行所在省
// 'bankCityId' => '510100',// [必填]银行所在市
'cardType' => $info['card_type'],// [必填]卡类型(1-对私/2-对公)
// 'bankName' => '',// [选填]银行名称
'bankSubName' => $info['bank_sub_name'] ?? '',// [条件必填]开户银行支行名称,卡类型为2-对公必填
'accountIdSdate' => $info['account_id_start'],// [必填]证件有效期开始时间
// 'accountIdEdate' => '20401107',// [选填]证件有效期终止时间,YYYYMMDD或长期
'bankActName' => $info['bank_act_name'],// [必填]卡号姓名
'cardNum' => $info['card_num'],// [必填]卡号
'accountIdNo' => $info['account_id'],// [必填]持卡人证件号
'accountIdType' => '1',// [选填]证件类型1.身份证 9.其他类型不填默认1
'merType' => $info['mer_type'],// [必填]商户类型 (1-个体户/3-个人)
// 'merName' => '',// [条件必填]商户注册名称
// 'merShortName' => '',// [条件必填]商户简称
// 'provId' => '',// [条件必填]商户经营所在省
// 'cityId' => '',// [条件必填]商户经营所在市
// 'areaId' => '',// [条件必填]商户经营所在区县
// 'merAddress' => '',// [条件必填]商户经营地址
// 'businessCode' => '',// [条件必填]营业执照号
// 'businessSdate' => '',// [条件必填]营业执照有效期开始日期
// 'businessEdate' => '',// [条件必填]营业执照有效期结束日期,YYYYMMDD或长期
];
// 发起请求
$result = $this->requestApi('/api/personnel/personnelAccess',$params);
$result['memberId'] = '';
if((int)$result['respCode'] === 0) {
$params['uid'] = $info['uid'];
$params['memberId'] = $result['memberId'];
$params['trans_seq_id'] = $result['transSeqId'];
$params['status'] = $result['state'];
// 判断:当前用户是否已经存在账号信息
$isHas = (int)UseStaff::uniacid()->where('uid',$info['uid'])->value('id');
if($isHas > 0) (new UseStaff())->updateRecord($params);
else (new UseStaff())->addRecord($params);
return $result;
}else throw new Exception($result['respDesc']);
}
/**
* Common: 员工入驻 - 入驻结果查询
* Author: wu-hui
* Time: 2023/10/08 17:02
* @param $memberId
* @param $transSeqId
* @return mixed|void
* @throws Exception
*/
public function personnelResult($memberId = '',$transSeqId = ''){
// 基本参数
$params = [
'accessId' => $this->accessId,// [必填]接入ID
'transSeqId' => $transSeqId,// [选填]系统流水号
'memberId' => $memberId,// [选填]会员号
];
// 发起请求
$result = $this->requestApi('/api/personnel/queryPersonnel',$params);
if((int)$result['respCode'] === 0) {
UseStaff::uniacid()->where('member_id',$memberId)->update([
'status' => $result['state'],
'member_id' => $result['memberId']
]);
return $result;
}else throw new Exception($result['respDesc']);
}
/**
* Common: 员工签约
* Author: wu-hui
* Time: 2023/10/08 17:46
* @param $uid
* @return mixed|void
* @throws Exception
*/
public function personalContractCreate($uid){
// 获取员工信息
$staff = UseStaff::getSingleInfo(['uid'=>$uid]);
// 基本参数
$params = [
'accessId' => $this->accessId,// [必填]接入ID
'orderId' => createNo('YCH',4,TRUE),// [必填]请求流水号
'coreAgentId' => $this->coreAgentId,// [必填]核心企业机构号
'groundAgentId' => $this->groundAgentId,// [必填]落地公司机构号
'memberId' => $staff['member_id'],// [必填]个人会员号
'signResultViewUrl' => '',// [选填]签约结果提示显示页面
];
// 发起请求
$result = $this->requestApi('/api/contract/personalContractCreate',$params);
if((int)$result['respCode'] === 0) {
UseStaff::uniacid()->where('member_id',$staff['member_id'])->update([
'signing_status' => $result['signState'],
'contract_id' => $result['contractId'],
'contract_name' => $result['contractName'],
]);
return $result;
}else throw new Exception($result['respDesc']);
}
/**
* Common: 员工签约 - 签约结果查询
* Author: wu-hui
* Time: 2023/10/08 17:50
* @param $memberId
* @return mixed|void
* @throws Exception
*/
public function personalContractQuery($memberId){
// 获取员工信息
$staff = UseStaff::getSingleInfo(['member_id'=>$memberId]);
// 基本参数
$params = [
'accessId' => $this->accessId,// [必填]接入ID
'orderId' => createNo('YCH',6,TRUE),// [必填]请求流水号
'contractId' => $staff['contract_id'],// [必填]核心企业机构号
];
// 发起请求
$result = $this->requestApi('/api/contract/personalContractQuery',$params);
if((int)$result['respCode'] === 0) {
UseStaff::uniacid()->where('member_id',$staff['member_id'])->update([
'signing_status' => $result['signState'],
]);
return $result;
}else throw new Exception($result['respDesc']);
}
/**
* Common: 费用代发 - 申请代发
* Author: wu-hui
* Time: 2023/10/09 10:15
* @param $info
* @return mixed|void
* @throws Exception
*/
public function salaryModelOutOrder($info){
// 获取员工信息
$staff = UseStaff::getSingleInfo($info);
// 基本参数
$orderNo = createNo('YCH',6,TRUE);
$params = [
'accessId' => $this->accessId,// [必填]接入ID
'orderId' => $orderNo,// [必填]请求流水号
'agentId' => $this->coreAgentId,// [必填]核心企业机构号
'bmemberId' => $this->bmemberId,// [必填]落地公司商户号,落地公司memberId
'salaryModle' => '1',// [必填]代发模式,1-普票 2-专票
'accountModle' => '2',// [必填]走账模式,2-代发
'modeIdcompany' => '1',// [必填]走账类型,1-单账户模式
'noticeUrl' => $this->getNotifyUrl('salary'),// [必填]异步通知地址
// [必填]代发费用明细
'batchSalaryOutOrderModleDtos' => [[
'memberId' => $staff['member_id'],// [必填]会员号
'outOrderId' => $orderNo,// [必填]外部订单号
'salary' => $info['salary'],// [必填]费用金额
'salaryMonth' => $info['month'],// [必填]月份,格式YYYYMM
]],
];
// 发起请求
$result = $this->requestApi('/api/salaryInfo/salaryModleOutOrder',$params);
if((int)$result['respCode'] === 2) {
$time = time();
UseStaffSalary::insert([
'uniacid' => \YunShop::app()->uniacid,
'uid' => $info['uid'],
'order_no' => $orderNo,
'member_id' => $staff['member_id'],
'salary' => $info['salary'],
'salary_month' => $info['month'],
'attach_id' => $result['attachId'],
'created_at' => $time,
'updated_at' => $time,
]);
return $result;
}else throw new Exception($result['respDesc']);
}
/**
* Common: 费用代发 - 结果查询
* Author: wu-hui
* Time: 2023/10/09 10:51
* @param $attachId
* @return mixed|void
* @throws Exception
*/
public function salaryOutOrderResult($attachId){
// 基本参数
$params = [
'accessId' => $this->accessId,// [必填]接入ID
'memberId' => $this->memberId,// [必填]智汇管家代理商会员号
'attachId' => $attachId,// [条件必填]若订单号未填,则批次号必填
// 'orderId' => $this->accessId,// [条件必填]若批次号未填,则订单号必填
];
// 发起请求
$result = $this->requestApi('/api/queryresult/salaryOutOrderResult',$params);
if((int)$result['respCode'] === 0) {
$salaryOutOrderRespDto = $result['salaryOutOrderRespDto'];
$first = collect($salaryOutOrderRespDto)->first();
UseStaffSalary::where('attach_id',$attachId)
->update([
'attach_state' => $result['attachState'],
'order_amt' => $first['orderAmt'],
'real_trans_amt' => $first['realTransAmt'],
'out_member_id' => $first['outMemberId'],
'salary_state' => $first['salaryState'],
'trans_fee' => $first['transFee'],
]);
return $result;
}else throw new Exception($result['respDesc']);
}
}

View File

@ -0,0 +1,152 @@
<?php
namespace Yunshop\UseStaff\models;
use app\common\models\BaseModel;
use app\common\models\Member;
class UseStaff extends BaseModel{
public $table = 'yz_use_staff';
public $casts =[
'created_at' => 'datetime:Y-m-d H:i',
'card_type' => 'string',
'mer_type' => 'string',
];
/**
* Common: 添加入驻记录
* Author: wu-hui
* Time: 2023/10/08 16:39
* @param $params
* @throws \Exception
*/
public function addRecord($params){
// 判断:是否已经存在
$isHas = (int)self::uniacid()->where('card_num',$params['cardNum'])->value('id');
if($isHas > 0) throw new \Exception('当前银行卡账号已经存在,请勿重复添加!');
// 添加存在
$time = time();
$data = [
'uniacid' => \YunShop::app()->uniacid,
'uid' => $params['uid'],
'order_id' => $params['orderId'],
'name' => $params['name'],
'tel' => $params['contactTelNo'],
'card_type' => $params['cardType'],
'account_id_start' => $params['accountIdSdate'],
'bank_act_name' => $params['bankActName'],
'card_num' => $params['cardNum'],
'account_id' => $params['accountIdNo'],
'mer_type' => $params['merType'],
'member_id' => $params['memberId'],
'status' => $params['status'],
'created_at' => $time,
'updated_at' => $time,
'trans_seq_id' => $params['trans_seq_id'],
];
self::insert($data);
}
/**
* Common: 修改入驻记录
* Author: wu-hui
* Time: 2023/10/10 12:01
* @param $params
*/
public function updateRecord($params){
self::uniacid()->where('uid',$params['uid'])->update([
'order_id' => $params['orderId'],
'name' => $params['name'],
'tel' => $params['contactTelNo'],
'card_type' => $params['cardType'],
'account_id_start' => $params['accountIdSdate'],
'bank_act_name' => $params['bankActName'],
'card_num' => $params['cardNum'],
'account_id' => $params['accountIdNo'],
'mer_type' => $params['merType'],
'member_id' => $params['memberId'],
'status' => $params['status'],
'updated_at' => time(),
'trans_seq_id' => $params['trans_seq_id'],
]);
}
/**
* Common: 获取一条信息(支持刷新信息然后返回)
* Author: wu-hui
* Time: 2023/10/10 11:40
* @param $params
* @param string $field
* @param false $isAllowRefresh
* @return array
* @throws \Exception
*/
public static function getSingleInfo($params,$field = '*',$isAllowRefresh = false){
// 条件
$where = [];
if((int)$params['member_id'] > 0) $where[] = ['member_id','=',(int)$params['member_id']];
else if((int)$params['uid'] > 0) $where[] = ['uid','=',(int)$params['uid']];
else if(!empty($params['order_id'])) $where[] = ['order_id','=',(int)$params['order_id']];
else throw new \Exception("参数错误,必要参数至少存在一个!");
// 获取信息
$info = self::uniacid()
->select($field)
->where($where)
->first();
$info = $info ? $info->toArray() : [];
// 判断:是否执行一次刷新 入驻状态1=待开户2=开户成功待签约3=开户失败4=签约成功5=签约失败
if(array_key_exists('status',$info) && (array_key_exists('member_id',$info) || array_key_exists('trans_seq_id',$info)) && $isAllowRefresh){
if(in_array($info['status'],[1,2])){
(new ExternalApi())->personnelResult($info['member_id'],$info['trans_seq_id']);
return self::getSingleInfo($params,$field,false);
}
}
return $info;
}
/**
* Common: 获取员工账号列表
* Author: wu-hui
* Time: 2023/10/09 13:41
* @param $pageSize
* @param $search
* @param string[] $field
* @return array
*/
public function getList($pageSize,$search,$field = ['*']){
// 条件生成
$where = [];
if($search['name']) $where[] = ['name','like',"%{$search['name']}%"];
if($search['tel']) $where[] = ['tel','=',$search['tel']];
if((int)$search['card_type'] > 0) $where[] = ['card_type','=',$search['card_type']];
if($search['bank_act_name']) $where[] = ['bank_act_name','like',"%{$search['bank_act_name']}%"];
if((int)$search['mer_type'] > 0) $where[] = ['mer_type','=',$search['mer_type']];
if((int)$search['status'] > 0) $where[] = ['status','=',$search['status']];
// 列表获取
$list = self::uniacid()
->select($field)
->where($where)
->with([
'member' => function($query){
$query->select(['uid','nickname','realname','avatar']);
},
])
->orderBy('created_at','DESC')
->orderBy('id','DESC')
->paginate($pageSize);
return $list ? $list->toArray() : [];
}
/**
* Common: 一对一关联 用户信息
* Author: wu-hui
* Time: 2023/10/09 13:40
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function member(){
return $this->hasOne(Member::class,'uid','uid');
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace Yunshop\UseStaff\models;
use app\common\models\BaseModel;
use app\common\models\Member;
class UseStaffSalary extends BaseModel{
public $table = 'yz_use_staff_salary';
public $casts =[
'created_at' => 'datetime'
];
/**
* Common: 获取打款记录列表
* Author: wu-hui
* Time: 2023/10/09 14:50
* @param $pageSize
* @param $search
* @param string[] $field
* @return array
*/
public function getList($pageSize,$search,$field = ['*']){
// 条件生成
$where = [];
if($search['uid']) $where[] = ['uid','=',$search['uid']];
if((int)$search['attach_state'] > 0) $where[] = ['attach_state','=',$search['attach_state']];
// 列表获取
$list = self::uniacid()
->select($field)
->where($where)
->with([
'member' => function($query){
$query->select(['uid','nickname','realname','avatar']);
},
])
->orderBy('created_at','DESC')
->orderBy('id','DESC')
->paginate($pageSize);
return $list ? $list->toArray() : [];
}
/**
* Common: 一对一关联 用户信息
* Author: wu-hui
* Time: 2023/10/09 13:40
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function member(){
return $this->hasOne(Member::class,'uid','uid');
}
}

View File

@ -0,0 +1,160 @@
@extends('layouts.base')
<style>
.user{
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
justify-content: flex-start;
overflow: hidden;
height: 80px;
}
.user .user-avatar{
height: 50px;
width: 50px;
margin-right: 5px;
border-radius: 50%;
overflow: hidden;
}
.user .user-avatar .avatar-image{
width: 100% !important;
height: 100% !important;
}
.user .user-info{
height: 50px;
text-align: left;
}
.user .user-info .user-nickname{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.user .user-info .user-status{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
@section('content')
<div class="w1200 m0a" id="terminalMerchantsIndex">
{{--顶部搜索--}}
<div class="panel panel-info">
<div class="panel-body">
<form action="" method="post" class="form-horizontal" role="form" id="form1">
<div class="form-group">
<div class="col-sm-11 col-xs-12">
<div class="row row-fix tpl-category-container" >
<div class="col-xs-12 col-sm-8 col-lg-3">
<input class="form-control" name="search[name]" type="text" value="{{ $search['name'] }}" placeholder="请输入账号名称">
</div>
<div class="col-xs-12 col-sm-8 col-lg-3">
<input class="form-control" name="search[tel]" type="text" value="{{ $search['tel'] }}" placeholder="请输入联系电话">
</div>
<div class="col-xs-12 col-sm-8 col-lg-3">
<input class="form-control" name="search[bank_act_name]" type="text" value="{{ $search['bank_act_name'] }}" placeholder="请输入银行卡持有人姓名">
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-11 col-xs-12">
<div class="row row-fix tpl-category-container" >
<div class="col-xs-12 col-sm-8 col-lg-3">
<select class="form-control tpl-category-parent" name="search[card_type]">
{{--卡类型1=对私2=对公--}}
<option value="0" @if (!$search['card_type']) selected="selected" @endif>全部</option>
<option value="1" @if ($search['card_type'] == 1) selected="selected" @endif>对私</option>
<option value="2" @if ($search['card_type'] == 2) selected="selected" @endif>对公</option>
</select>
</div>
<div class="col-xs-12 col-sm-8 col-lg-3">
<select class="form-control tpl-category-parent" name="search[status]">
{{-- 入驻状态1=待开户2=开户成功待签约3=开户失败4=签约成功5=签约失败 --}}
<option value="0" @if (!$search['status']) selected="selected" @endif>全部</option>
<option value="1" @if ($search['status'] == 1) selected="selected" @endif>待开户</option>
<option value="2" @if ($search['status'] == 2) selected="selected" @endif>开户成功待签约</option>
<option value="3" @if ($search['status'] == 3) selected="selected" @endif>开户失败</option>
<option value="4" @if ($search['status'] == 4) selected="selected" @endif>签约成功</option>
<option value="5" @if ($search['status'] == 5) selected="selected" @endif>签约失败</option>
</select>
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="col-xs-12 col-sm-6 col-lg-6">
<button class="btn btn-success" id="search"><i class="fa fa-search"></i> 搜索</button>
</div>
</div>
</form>
</div>
</div>
{{--信息列表--}}
<div class="panel panel-default">
<div class="panel-body" style="padding-top: 0;margin-bottom: 30px;overflow: auto;padding-right: 30px;">
<table class="table" style="min-width:1500px;overflow: auto;">
<thead>
<tr>
<th style="text-align:center;width: 80px;">ID</th>
<th style="text-align:left;">用户信息</th>
<th style="text-align:left;">账号信息</th>
<th style="text-align:left;">银行卡信息</th>
<th style="text-align:center;">状态</th>
<th style="text-align:center;">入驻时间</th>
<th style="text-align:center;width: 350px;">操作</th>
</tr>
</thead>
<tbody>
@foreach ($list as $item)
<tr style="height: 50px;">
<td style="text-align:center;">{{ $item['id'] }}</td>
<td style="text-align:left;">
<div class="user">
<div class="user-avatar">
<img class="avatar-image" src="{{$item['member']['avatar_image']}}" />
</div>
<div class="user-info">
<div class="user-nickname">昵称:{{ $item['member']['nickname'] }}</div>
<div class="user-status">ID{{ $item['member']['uid'] }}</div>
</div>
</div>
</td>
<td style="text-align:left;">
<div class="contacts">
账号名称:{{ $item['name'] }}<br />
联系电话:{{ $item['tel'] }}<br />
</div>
</td>
<td style="text-align:left;">
<div class="contacts">
持有人姓名:{{ $item['bank_act_name'] }}<br />
卡号:{{ $item['card_num'] }}<br />
类型:{{ $item['card_type'] == 1 ? '对私' : '对公' }}<br />
</div>
</td>
<td style="text-align:center;">
@switch($item['status'])
@case(1)<span class="label label-default">待开户</span>@break
@case(2)<span class="label label-primary">开户成功待签约</span>@break
@case(3)<span class="label label-danger">开户失败</span>@break
@case(4)<span class="label label-success">签约成功</span>@break
@case(5)<span class="label label-danger">签约失败</span>@break
@endswitch
</td>
<td style="text-align:center;">{{ $item['created_at'] }}</td>
<td style="text-align:center;">
<a href="{{yzWebUrl('plugin.use-staff.admin.index.refreshInfo', ['id' => $item['id']])}}">
<button type="button" class="btn btn-info btn-sm">刷新信息</button>
</a>
</td>
</tr>
@endforeach
</tbody>
</table>
{!! $pager !!}
</div>
</div>
</div>
<script type="text/javascript"></script>
@endsection

View File

@ -0,0 +1,88 @@
@extends('layouts.base')
@section('content')
<div class="w1200 m0a">
开发中...
{{--<div class="rightlist">
<form action="" method="post" class="form-horizontal form" enctype="multipart/form-data">
<div class='panel panel-default form-horizontal form'>
<div class='panel-heading'>基础设置</div>
<div class='panel-body'>
<div class="form-group">
<label class="col-xs-12 col-sm-3 col-md-2 control-label">开启</label>
<div class="col-sm-4 col-xs-6">
<label class="radio-inline">
<input type="radio" name="use_staff[switch]" value="0" @if ($set['switch'] != 1) checked="checked" @endif />关闭
</label>
<label class="radio-inline">
<input type="radio" name="use_staff[switch]" value="1" @if ($set['switch'] == 1) checked="checked" @endif />开启
</label>
</div>
</div>
<div class="form-group">
<label class="col-xs-12 col-sm-3 col-md-2 control-label">名额距离</label>
<div class="col-sm-6 col-xs-6">
<input type='number' name='use_staff[distance]]' class="form-control discounts_value" value="{{$set['distance']}}"/>
<span class="help-block">抽奖名额的距离,设置为10时当第10个排名出现则第一个排名中奖第20个排名出现则第二个中奖以此类推</span>
</div>
</div>
<div class="form-group">
<label class="col-xs-12 col-sm-3 col-md-2 control-label">用户名额间隔</label>
<div class="col-sm-6 col-xs-6">
<input type='number' name='use_staff[interval]]' class="form-control discounts_value" value="{{$set['interval']}}"/>
<span class="help-block">每个用户之间名额的间隔</span>
</div>
</div>
<div class="form-group">
<label class="col-xs-12 col-sm-3 col-md-2 control-label">金额目标</label>
<div class="col-sm-6 col-xs-6">
<input type='number' name='use_staff[target]]' class="form-control discounts_value" value="{{$set['target']}}"/>
<span class="help-block">用户购买指定商品,累计消费金额到达目标则获得一个抽奖名额</span>
</div>
</div>
<div class="form-group">
<label class="col-xs-12 col-sm-3 col-md-2 control-label">首页公告内容</label>
<div class="col-sm-6 col-xs-6">
<input type='text' name='use_staff[tip_text]]' class="form-control discounts_value" value="{{$set['tip_text']}}"/>
<span class="help-block">首页公告内容,默认为“恭喜[username]获得公排中奖”。<br />
参数说明:[username]显示用户昵称;[balance]显示奖励余额;[integral]显示奖励积分
</span>
</div>
</div>
<div class="form-group">
<label class="col-xs-12 col-sm-3 col-md-2 control-label">门店-收银台订单参与比例(%)</label>
<div class="col-sm-6 col-xs-6">
<input type='number' name='use_staff[store_cashier_ratio]]' min="0" max="100" class="form-control discounts_value" value="{{$set['store_cashier_ratio']}}"/>
<span class="help-block">门店-收银台订单参与比例(%请设置0-100正整数</span>
</div>
</div>
</div>
<div class='panel-heading'>奖励设置</div>
<div class='panel-body'>
<div class="form-group">
<label class="col-xs-12 col-sm-3 col-md-2 control-label">奖励余额</label>
<div class="col-sm-6 col-xs-6">
<input type='number' name='use_staff[balance]]' class="form-control discounts_value" value="{{$set['balance']}}"/>
</div>
</div>
<div class="form-group">
<label class="col-xs-12 col-sm-3 col-md-2 control-label">奖励积分</label>
<div class="col-sm-6 col-xs-6">
<input type='number' name='use_staff[integral]]' class="form-control discounts_value" value="{{$set['integral']}}"/>
</div>
</div>
</div>
--}}{{--提交按钮--}}{{--
<div class="form-group"></div>
<div class="form-group">
<label class="col-xs-12 col-sm-3 col-md-2 control-label"></label>
<div class="col-sm-9 col-xs-12">
<input type="submit" name="submit" value="保存" class="btn btn-primary col-lg-1"/>
</div>
</div>
</div>
</form>
</div>--}}
@endsection

View File

@ -0,0 +1,138 @@
@extends('layouts.base')
<style>
.user{
display: inline-flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
justify-content: flex-start;
overflow: hidden;
height: 80px;
}
.user .user-avatar{
height: 50px;
width: 50px;
margin-right: 5px;
border-radius: 50%;
overflow: hidden;
}
.user .user-avatar .avatar-image{
width: 100% !important;
height: 100% !important;
}
.user .user-info{
height: 50px;
text-align: left;
}
.user .user-info .user-nickname{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.user .user-info .user-status{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
@section('content')
<div class="w1200 m0a" id="terminalMerchantsIndex">
{{--顶部搜索--}}
<div class="panel panel-info">
<div class="panel-body">
<form action="" method="post" class="form-horizontal" role="form" id="form1">
<div class="form-group">
<div class="col-sm-11 col-xs-12">
<div class="row row-fix tpl-category-container" >
<div class="col-xs-12 col-sm-8 col-lg-3">
<input class="form-control" name="search[uid]" type="text" value="{{ $search['uid'] }}" placeholder="请输入用户id">
</div>
<div class="col-xs-12 col-sm-8 col-lg-3">
<select class="form-control tpl-category-parent" name="search[attach_state]">
{{--状态1=代发处理中2=代发处理成功3=代发部分处理成功4=代发处理失败--}}
<option value="0" @if (!$search['attach_state']) selected="selected" @endif>全部</option>
<option value="1" @if ($search['attach_state'] == 1) selected="selected" @endif>处理中</option>
<option value="2" @if ($search['attach_state'] == 2) selected="selected" @endif>处理成功</option>
<option value="3" @if ($search['attach_state'] == 3) selected="selected" @endif>部分处理成功</option>
<option value="4" @if ($search['attach_state'] == 4) selected="selected" @endif>处理失败</option>
</select>
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="col-xs-12 col-sm-6 col-lg-6">
<button class="btn btn-success" id="search"><i class="fa fa-search"></i> 搜索</button>
</div>
</div>
</form>
</div>
</div>
{{--信息列表--}}
<div class="panel panel-default">
<div class="panel-body" style="padding-top: 0;margin-bottom: 30px;overflow: auto;padding-right: 30px;">
<table class="table" style="min-width:1500px;overflow: auto;">
<thead>
<tr>
<th style="text-align:center;width: 80px;">ID</th>
<th style="text-align:left;">用户信息</th>
<th style="text-align:left;">申请提现信息</th>
<th style="text-align:left;">打款信息</th>
<th style="text-align:center;">状态</th>
<th style="text-align:center;">申请时间</th>
<th style="text-align:center;width: 350px;">操作</th>
</tr>
</thead>
<tbody>
@foreach ($list as $item)
<tr style="height: 50px;">
<td style="text-align:center;">{{ $item['id'] }}</td>
<td style="text-align:left;">
<div class="user">
<div class="user-avatar">
<img class="avatar-image" src="{{$item['member']['avatar_image']}}" />
</div>
<div class="user-info">
<div class="user-nickname">昵称:{{ $item['member']['nickname'] }}</div>
<div class="user-status">ID{{ $item['member']['uid'] }}</div>
</div>
</div>
</td>
<td style="text-align:left;">
<div class="contacts">
批次号:{{ $item['attach_id'] }}<br />
提现金额:{{ $item['salary'] }}<br />
</div>
</td>
<td style="text-align:left;">
<div class="contacts">
实际打款金额:{{ $item['real_trans_amt'] }}<br />
转账服务费:{{ $item['trans_fee'] }}<br />
</div>
</td>
<td style="text-align:center;">
{{--状态1=代发处理中2=代发处理成功3=代发部分处理成功4=代发处理失败--}}
@switch($item['attach_state'])
@case(1)<span class="label label-default">处理中</span>@break
@case(2)<span class="label label-success">处理成功</span>@break
@case(3)<span class="label label-primary">部分处理成功</span>@break
@case(4)<span class="label label-danger">处理失败</span>@break
@endswitch
</td>
<td style="text-align:center;">{{ $item['created_at'] }}</td>
<td style="text-align:center;">
<a href="{{yzWebUrl('plugin.use-staff.admin.withdrawal.refreshInfo', ['id' => $item['id']])}}">
<button type="button" class="btn btn-info btn-sm">刷新信息</button>
</a>
</td>
</tr>
@endforeach
</tbody>
</table>
{!! $pager !!}
</div>
</div>
</div>
<script type="text/javascript"></script>
@endsection

View File