This commit is contained in:
全栈小学生 2025-01-03 17:59:22 +08:00
parent 91283fe1bf
commit 1d87b08b07
41 changed files with 1284 additions and 115 deletions

View File

@ -1,6 +1,6 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// | Niucloud-admin 企业快速开发的saas管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
@ -255,4 +255,17 @@ class Diy extends BaseAdminController
{
return success(( new DiyService() )->getApps());
}
/**
* 复制模版
* @return Response
*/
public function copy()
{
$params = $this->request->params([
[ 'id', '' ],
]);
$id = ( new DiyService() )->copy($params);
return success('ADD_SUCCESS', [ 'id' => $id ]);
}
}

View File

@ -0,0 +1,93 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\adminapi\controller\member;
use app\service\admin\member\AddressService;
use core\base\BaseAdminController;
/**
* 会员收货地址控制器
*/
class Address extends BaseAdminController
{
/**
* 获取会员收货地址列表
* @return \think\Response
*/
public function lists(){
$data = $this->request->params([
["member_id",""],
]);
return success((new AddressService())->getList($data));
}
/**
* 会员收货地址详情
* @param $id 会员收货地址id
* @return \think\Response
*/
public function info($id){
$data = $this->request->params([
["member_id",""],
]);
return success((new AddressService())->getInfo($id, $data));
}
/**
* 添加会员收货地址
* @return \think\Response
*/
public function add(){
$data = $this->request->params([
["member_id",""],
["name",""],
["mobile",""],
["province_id",0],
["city_id",0],
["district_id",0],
["address",""],
["address_name", ""],
["full_address",""],
["lng",""],
["lat",""],
["is_default",0],
]);
$id = (new AddressService())->add($data);
return success('ADD_SUCCESS', ['id' => $id]);
}
/**
* 会员收货地址编辑
* @param $id 会员收货地址id
* @return \think\Response
*/
public function edit($id){
$data = $this->request->params([
["member_id",""],
["name",""],
["mobile",""],
["province_id",0],
["city_id",0],
["district_id",0],
["address",""],
["address_name", ""],
["full_address",""],
["lng",""],
["lat",""],
["is_default",0],
]);
(new AddressService())->edit($id, $data);
return success('EDIT_SUCCESS');
}
}

View File

@ -1,6 +1,6 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// | Niucloud-admin 企业快速开发的saas管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
@ -11,7 +11,6 @@
namespace app\adminapi\controller\pay;
use app\dict\pay\PayDict;
use app\service\admin\pay\PayService;
use core\base\BaseAdminController;
@ -57,4 +56,57 @@ class Pay extends BaseAdminController
$reason = input('reason', '');
return success(data: (new PayService())->refuse($out_trade_no, $reason));
}
}
/**
* 去支付
* @return \think\Response
*/
public function pay()
{
$data = $this->request->params([
['type', ''],
['trade_type', ''],//业务类型
['trade_id', ''],//业务id
['quit_url', ''],
['buyer_id', ''],
['return_url', ''],
['voucher', ''],
['openid', '']
]);
return success('SUCCESS',(new PayService())->pay($data['type'], $data['trade_type'], $data['trade_id'], $data['return_url'], $data['quit_url'], $data['buyer_id'], $data['voucher'], $data['openid']));
}
/**
* 支付信息
* @param $trade_type
* @param $trade_id
* @return \think\Response
*/
public function info($trade_type, $trade_id)
{
return success((new PayService())->getInfoByTrade($trade_type, $trade_id));
}
/**
* 找朋友帮忙付支付信息
* @param $trade_type
* @param $trade_id
* @param $channel
* @return \think\Response
*/
public function friendspayInfo($trade_type, $trade_id, $channel)
{
return success(data:(new PayService())->getFriendspayInfoByTrade($trade_type, $trade_id, $channel));
}
/**
* 支付方式列表
* @return \think\Response
*/
public function payTypeList()
{
return success(data:(new PayService())->getPayTypeList());
}
}

View File

@ -0,0 +1,37 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的saas管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\adminapi\controller\poster;
use core\base\BaseAdminController;
/**
* 海报
*/
class Poster extends BaseAdminController
{
/**
* 获取海报
* @return \think\Response
*/
public function poster()
{
$data = $this->request->params([
[ 'id', 0 ], // 海报id
[ 'type', '' ], // 海报类型
[ 'param', [] ], // 数据参数
[ 'channel', 'h5' ], // 数据参数
]);
return success(data: poster(...$data));
}
}

View File

@ -21,6 +21,7 @@ use think\facade\Route;
Route::group('diy', function() {
/***************************************************** 自定义页面管理 ****************************************************/
// 自定义页面分页列表
Route::get('diy', 'diy.Diy/lists');
@ -80,6 +81,9 @@ Route::group('diy', function() {
// 获取模板页面(存在的应用插件列表)
Route::get('apps', 'diy.Diy/getApps');
// 复制模版
Route::post('copy', 'diy.Diy/copy');
/***************************************************** 配置相关 *****************************************************/
// 底部导航列表

View File

@ -1,6 +1,6 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// | Niucloud-admin 企业快速开发的saas管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
@ -152,6 +152,15 @@ Route::group('member', function() {
Route::get('sign/config', 'member.MemberSign/getSign');
//签到记录
Route::get('sign', 'member.MemberSign/lists');
/***************************************************** 会员地址 ****************************************************/
//会员收货地址列表
Route::get('address', 'member.Address/lists');
//会员收货地址详情
Route::get('address/:id', 'member.Address/info');
//添加会员收货地址
Route::post('address', 'member.Address/add');
//编辑会员收货地址
Route::put('address/:id', 'member.Address/edit');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,

View File

@ -1,6 +1,6 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// | Niucloud-admin 企业快速开发的saas管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
@ -59,6 +59,15 @@ Route::group('pay', function () {
Route::post('refund/transfer', 'pay.PayRefund/transfer');
// 获取全部支付方式
Route::get('type/all', 'pay.PayChannel/getPayTypeList');
/***************************************************** 支付 *************************************************/
//去支付
Route::post('', 'pay.Pay/pay');
//支付信息
Route::get('info/:trade_type/:trade_id', 'pay.Pay/info');
//支付方式列表
Route::get('type/list', 'pay.Pay/payTypeList');
//找朋友帮忙付支付信息
Route::get('friendspay/info/:trade_type/:trade_id/:channel', 'pay.Pay/friendspayInfo');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,

View File

@ -257,6 +257,9 @@ Route::group('sys', function() {
// 自定义海报预览
Route::get('poster/preview', 'sys.Poster/preview');
//获取海报
Route::get('poster/generate', 'poster.Poster/poster');
/***************************************************** 百度编辑器 ****************************************************/
// 获取百度编辑器配置
Route::get('ueditor', 'sys.Ueditor/getConfig');

View File

@ -1,6 +1,6 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// | Niucloud-admin 企业快速开发的saas管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
@ -56,7 +56,19 @@ class Pay extends BaseApiController
public function info($trade_type, $trade_id)
{
return success((new PayService())->getInfoByTrade($trade_type, $trade_id));
$data = $this->request->params([
['scene', '']
]);
return success((new PayService())->getInfoByTrade($trade_type, $trade_id, $data));
}
/**
* 获取找朋友帮忙付支付信息
* @return Response
*/
public function friendspayInfo($trade_type, $trade_id)
{
return success((new PayService())->getFriendspayInfoByTrade($trade_type, $trade_id));
}
/**

View File

@ -22,6 +22,14 @@ Route::any('pay/notify/:channel/:type/:action', 'pay.Pay/notify')
/**
* 路由
*/
Route::group('pay',function () {
//找朋友帮忙付支付信息
Route::get('friendspay/info/:trade_type/:trade_id', 'pay.Pay/friendspayInfo');
})->middleware(ApiChannel::class)
->middleware(ApiCheckToken::class)
->middleware(ApiLog::class);
Route::group('pay',function () {
//去支付
Route::post('', 'pay.Pay/pay');
@ -33,5 +41,5 @@ Route::group('pay',function () {
Route::post('close', 'pay.Pay/close');
})->middleware(ApiChannel::class)
->middleware(ApiCheckToken::class)
->middleware(ApiCheckToken::class, true)//表示验证登录
->middleware(ApiLog::class);

View File

@ -34,11 +34,17 @@ class PayChannelDict
// }
// }
foreach ($channel as $k => $v) {
$list[$k] = [
$temp_pay_type = $pay_type;
$list[ $k ] = [
'name' => $v,
'key' => $k,
'pay_type' => $pay_type
];
// PC端暂不支持 帮付
if ($k == ChannelDict::PC) {
unset($temp_pay_type[ PayDict::FRIENDSPAY ]);
$list[ $k ][ 'pay_type' ] = $temp_pay_type;
}
}
return $list;
}

View File

@ -19,7 +19,8 @@ class PayDict
public const ALIPAY = 'alipay';//支付宝支付
//const UNIPAY = 'unipay';//银联
public const OFFLINEPAY = 'offlinepay';//线下支付
public const BALANCEPAY = 'balancepay';//线下支付
public const BALANCEPAY = 'balancepay';//余额支付
public const FRIENDSPAY = 'friendspay';//找朋友帮忙付
public const ON = '1';
@ -31,10 +32,12 @@ class PayDict
//上传方式 视频
public const ALIPAY_ICON = self::PAY_ICON_PATH . 'alipay.png';//支付宝支付
public const BALANCEPAY_ICON = self::PAY_ICON_PATH . 'balancepay.png';//支付宝支付
public const BALANCEPAY_ICON = self::PAY_ICON_PATH . 'balancepay.png';//余额支付
public const OFFLINEPAY_ICON = self::PAY_ICON_PATH . 'offlinepay.png';//线下支付
public const FRIENDSPAY_ICON = self::PAY_ICON_PATH . 'friendspay.png';//找朋友帮忙付
//支付状态
public const STATUS_WAIT = '0';//待支付
public const STATUS_ING = '1';//支付中
@ -53,27 +56,38 @@ class PayDict
public static function getPayType(array $types = [])
{
$list = [
// 微信支付
self::WECHATPAY => [
'name' => get_lang('dict_pay.type_wechatpay'),
'key' => self::WECHATPAY,
'icon' => self::WECHATPAY_ICON,
'setting_component' => '/src/app/views/setting/components/pay-wechatpay.vue',
'encrypt_params' => ['mch_public_cert_path', 'mch_secret_cert', 'mch_secret_key', 'wechat_public_cert_path'],
],//微信支付
'encrypt_params' => [ 'mch_public_cert_path', 'mch_secret_cert', 'mch_secret_key', 'wechat_public_cert_path' ],
],
// 支付宝支付
self::ALIPAY => [
'name' => get_lang('dict_pay.type_alipay'),
'key' => self::ALIPAY,
'icon' => self::ALIPAY_ICON,
'setting_component' => '/src/app/views/setting/components/pay-alipay.vue',
'encrypt_params' => ['app_secret_cert', 'app_public_cert_path', 'alipay_public_cert_path', 'alipay_root_cert_path'],
],//支付宝支付
'encrypt_params' => [ 'app_secret_cert', 'app_public_cert_path', 'alipay_public_cert_path', 'alipay_root_cert_path' ],
],
// 余额支付
self::BALANCEPAY => [
'name' => get_lang('dict_pay.type_balancepay'),
'key' => self::BALANCEPAY,
'icon' => self::BALANCEPAY_ICON,
'setting_component' => '',
'encrypt_params' => ['secret_key'],
],//微信支付
'encrypt_params' => [ 'secret_key' ],
],
// 找朋友帮忙付
self::FRIENDSPAY => [
'name' => get_lang('dict_pay.type_friendspay'),
'key' => self::FRIENDSPAY,
'icon' => self::FRIENDSPAY_ICON,
'setting_component' => '/src/app/views/setting/components/pay-friendspay.vue',
'encrypt_params' => [],
],
];
$list = array_merge($list, ...event('PayType'));
@ -81,7 +95,7 @@ class PayDict
if (!empty($types)) {
foreach ($list as $k => $v) {
if (!in_array($k, $types)) {
unset($list[$k]);
unset($list[ $k ]);
}
}
}

View File

@ -0,0 +1,25 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的saas管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\dict\pay;
/**
* 支付场景枚举类
* Class PaySceneDict
* @package app\dict\pay
*/
class PaySceneDict
{
//找朋友帮忙付
public const FRIENDSPAY = 'friendspay';
}

View File

@ -114,7 +114,38 @@ class ComponentDict
'points' => [], // [x,y]:左上,右上,右下,左下
],
],
'FriendsPayMessage' => [
'title' => "帮付留言",
'type' => 'text',
'icon' => "nc-iconfont nc-icon-daifuliuyanV6xx",
'path' => "friendspay-message",
'uses' => 1,
'sort' => 10006,
'relate' => 'friendspay_message', // 关联字段,空为不处理
'value' => get_lang('dict_pay_config.pay_leave_message'),
'template' => [
"width" => 611,
"height" => 85,
"minWidth" => 120,
"minHeight" => 44,
]
],
'FriendsPayMoney' => [
'title' => "帮付金额",
'type' => 'text',
'icon' => "nc-iconfont nc-icon-daifujineV6xx",
'path' => "friendspay-money",
'uses' => 1,
'sort' => 10007,
'relate' => 'friendspay_money', // 关联字段,空为不处理
'value' => '帮付金额',
'template' => [
"width" => 436,
"height" => 50,
"minWidth" => 120,
"minHeight" => 44,
]
],
],
],
];

View File

@ -0,0 +1,170 @@
<?php
return [
[
"name" => "找朋友帮忙付模板", // 海报模板名称
'type' => 'friendspay', // 海报类型
"data" => [
"global" => [
"width" => 720,
"height" => 1280,
"bgType" => "url",
"bgColor" => "#ffffff",
"bgUrl" => "static/resource/images/pay/friendspay_bg.jpg"
],
"value" => [
[
"type" => "text",
"path" => "text",
"uses" => 0,
"relate" => "",
"value" => "您的帮付金额",
"id" => "wgvspr9fafk",
"componentName" => "Text",
"componentTitle" => "文本",
"width" => 518,
"height" => 48,
"minWidth" => 120,
"minHeight" => 44,
"x" => "center",
"y" => 759,
"angle" => 0,
"zIndex" => 8,
"fontFamily" => "static/font/SourceHanSansCN-Regular.ttf",
"fontSize" => 24,
"weight" => false,
"lineHeight" => 20,
"fontColor" => "#333333"
],
[
"type" => "text",
"path" => "friendspay-money",
"uses" => 1,
"relate" => "friendspay_money",
"value" => "¥369.00",
"id" => "2waud25nthq0",
"componentName" => "FriendsPayMoney",
"componentTitle" => "帮付金额",
"width" => 518,
"height" => 58,
"minWidth" => 120,
"minHeight" => 44,
"x" => "center",
"y" => 694,
"angle" => 0,
"zIndex" => 9,
"fontFamily" => "static/font/price.ttf",
"fontSize" => 56,
"weight" => false,
"lineHeight" => 10,
"fontColor" => "#FF4142"
],
[
"type" => "text",
"path" => "text",
"uses" => 0,
"relate" => "",
"value" => "长按识别二维码,帮我付款",
"id" => "639vjo8ebo40",
"componentName" => "Text",
"componentTitle" => "文本",
"width" => 518,
"height" => 59,
"minWidth" => 120,
"minHeight" => 44,
"x" => "center",
"y" => 1097,
"angle" => 0,
"zIndex" => 10,
"fontFamily" => "static/font/SourceHanSansCN-Regular.ttf",
"fontSize" => 26,
"weight" => false,
"lineHeight" => 26,
"fontColor" => "#333333"
],
[
"type" => "text",
"path" => "friendspay-message",
"uses" => 1,
"relate" => "friendspay_message",
"value" => "帮我付一下这笔订单吧,谢谢啦~",
"id" => "5oyikcgoylo0",
"componentName" => "FriendsPayMessage",
"componentTitle" => "帮付留言",
"width" => 600,
"height" => 48,
"minWidth" => 120,
"minHeight" => 44,
"x" => "center",
"y" => 570,
"angle" => 0,
"zIndex" => 4,
"fontFamily" => "static/font/SourceHanSansCN-Regular.ttf",
"fontSize" => 26,
"weight" => false,
"lineHeight" => 10,
"fontColor" => "#666666"
],
[
"type" => "qrcode",
"path" => "qrcode",
"uses" => 1,
"relate" => "url",
"value" => "",
"id" => "3m6szk6d98m0",
"componentName" => "Qrcode",
"componentTitle" => "二维码",
"width" => 214,
"height" => 214,
"minWidth" => 60,
"minHeight" => 60,
"x" => 254,
"y" => 844,
"angle" => 0,
"zIndex" => 8
],
[
"type" => "text",
"path" => "nickname",
"uses" => 1,
"relate" => "nickname",
"value" => "",
"id" => "31wsjudfc7m0",
"componentName" => "NickName",
"componentTitle" => "昵称",
"width" => 600,
"height" => 40,
"minWidth" => 120,
"minHeight" => 50,
"x" => "center",
"y" => 512,
"angle" => 0,
"zIndex" => 6,
"fontFamily" => "static/font/SourceHanSansCN-Regular.ttf",
"fontSize" => 30,
"weight" => false,
"lineHeight" => 10,
"fontColor" => "#303133"
],
[
"type" => "image",
"path" => "headimg",
"uses" => 1,
"relate" => "headimg",
"value" => "",
"id" => "5asgzwz9f5s0",
"componentName" => "HeadImg",
"componentTitle" => "头像",
"width" => 149,
"height" => 149,
"minWidth" => 60,
"minHeight" => 60,
"x" => 286,
"y" => 344,
"angle" => 0,
"zIndex" => 7,
"shape" => "circle"
]
]
]
],
];

View File

@ -92,7 +92,8 @@ $system_event = [
'StatField' => [],
// 获取海报数据
'GetPosterData' => [ 'app\listener\system\Poster' ]
'GetPosterType' => [ 'app\listener\system\PosterType' ],
'GetPosterData' => [ 'app\listener\system\Poster' ],
],
'subscribe' => [
],

View File

@ -3,11 +3,13 @@
namespace app\install\controller;
use app\model\sys\Poster;
use app\model\sys\SysUser;
use app\service\admin\auth\LoginService;
use app\service\admin\install\InstallSystemService;
use app\service\core\addon\CoreAddonInstallService;
use app\service\core\addon\CoreAddonService;
use app\service\core\poster\CorePosterService;
use app\service\core\schedule\CoreScheduleInstallService;
use Exception;
use think\facade\Cache;
@ -327,6 +329,23 @@ class Index extends BaseInstall
]);
}
// 创建默认找朋友帮忙付海报
$poster_model = new Poster();
$poster_count = $poster_model->where([
[ 'type', '=', 'friendspay' ]
])->count();
if ($poster_count == 0) {
$poster = new CorePosterService();
$template = $poster->getTemplateList('', 'friendspay')[ 0 ];
$poster->add('', [
'name' => $template[ 'name' ],
'type' => $template[ 'type' ],
'value' => $template[ 'data' ],
'status' => 1,
'is_default' => 1
]);
}
// 安装插件
$this->installAddon();

View File

@ -378,6 +378,7 @@ DROP TABLE IF EXISTS `pay`;
CREATE TABLE `pay` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`main_id` int(11) NOT NULL DEFAULT 0 COMMENT '支付会员id',
`from_main_id` INT(11) NOT NULL DEFAULT 0 COMMENT '发起支付会员id',
`out_trade_no` varchar(255) NOT NULL DEFAULT '' COMMENT '支付流水号',
`trade_type` varchar(255) NOT NULL DEFAULT '' COMMENT '业务类型',
`trade_id` int(11) NOT NULL DEFAULT 0 COMMENT '业务id',

View File

@ -162,6 +162,9 @@ return [
'LEVEL_NOT_ALLOWED_DELETE' => '该等级下存在会员不允许删除',
'MEMBER_LEVEL_MAX' => '最多只能有十个等级',
// 地址相关
'ADDRESS_ANALYSIS_ERROR' => '地址解析异常',
//会员提现
'CASHOUT_NOT_OPEN' => '会员提现业务未开启',
'CASHOUT_TYPE_NOT_OPEN' => '当前会员提现方式未启用',
@ -176,6 +179,8 @@ return [
'MEMBER_CASHOUT_TRANSFER' => '会员提现转账',
'CASH_OUT_ACCOUNT_NOT_EXIST' => '提现账户不存在',
//DIY
'PAGE_NOT_EXIST' => '页面不存在',
//渠道相关 占用 4******
//微信
@ -223,6 +228,8 @@ return [
'VOUCHER_NOT_EMPTY' => '支付单据不能为空',
'ONLY_PAYING_CAN_AUDIT' => '只有待支付的订单才可以操作',
'ONLY_OFFLINEPAY_CAN_AUDIT' => '只有线下支付的单据才可以审核',
'TRADE_NOT_EXIST' => '支付单据不存在',
'PAY_NOT_FOUND_TRADE' => '找不到可支付的交易',
//退款相关
'REFUND_NOT_EXIST' => '退款单据不存在',
//订单相关 8***

View File

@ -38,6 +38,18 @@ return [
'status_off' => '停用'
],
// 站点
'dict_site' => [
//站点类型
'type_cms' => 'cms',
'status_on' => '正常',
'status_experience' => '体验期',
'status_expire' => '已到期',
'status_close' => '已停止',
'pay' => '支付',
'refund' => '退款',
'transfer' => '转账',
],
// 站点
'dict_site_index' => [
//站点类型
'system' => '框架首页',
@ -165,6 +177,7 @@ return [
'type_unipay' => '银联支付',
'type_offline' => '线下支付',
'type_balancepay' => '余额支付',
'type_friendspay' => '找朋友帮忙付',
'status_wait' => '待支付',
'status_ing' => '支付中',
@ -175,6 +188,14 @@ return [
'refund' => '退款',
'transfer' => '转账',
],
//支付配置相关
'dict_pay_config' => [
'pay_leave_message' => '帮我付一下这笔订单吧,谢谢啦~',
'pay_button_name' => '慷慨付款',
'pay_page_name' => '帮我付款',
'pay_explain_title' => '帮付说明',
'pay_explain_content' => "1.付款前请务必和好友进行确认,以避免给你造成损失。\n2.当帮付订单退款成功后,实付金额将原路退还到帮付人账户。\n3.帮付订单信息中显示的金额为单价,但因优惠活动等因素,实付金额可能会发生变化,具体金额以页面显示为准。",
],
//转账相关
'dict_transfer' => [
'type_wechat' => '微信',
@ -227,11 +248,6 @@ return [
'member_verify_index' => '核销台',
'member_contact' => '客服',
'system_web_index' => '系统首页',
'auth_login' => '登录',
'auth_register' => '注册',
'auth_bind' => '手机号绑定',
'diy_page' => '自定义页面',
'diy_link' => '自定义链接',
'diy_jump_other_applet' => '小程序跳转',

View File

@ -0,0 +1,100 @@
<?php
declare ( strict_types = 1 );
namespace app\listener\poster;
use app\dict\pay\PayDict;
use app\model\member\Member;
use app\model\pay\Pay;
use app\service\core\pay\CorePayChannelService;
use app\service\core\sys\CoreSysConfigService;
/**
* 找朋友帮忙付海报数据
*/
class FriendspayPoster
{
/**
* 找朋友帮忙付海报
* @param $data
* @return array
*/
public function handle($data)
{
$type = $data[ 'type' ];
if ($type == 'friendspay') {
// 找朋友帮忙付 海报模板数据
$channel = $data[ 'channel' ];
$param = $data[ 'param' ];
$member_id = $param[ 'member_id' ] ?? 0;
$trade_id = $param[ 'id' ] ?? 0;//交易id
$trade_type = $param[ 'type' ] ?? '';//交易类型
$mode = $param[ 'mode' ] ?? '';
$url_data = [
[ 'key' => 'id', 'value' => $trade_id ],
[ 'key' => 'type', 'value' => $trade_type ]
];
if ($mode == 'preview') {
// 预览模式
$return_data = [
'nickname' => '会员昵称的帮付',
'headimg' => 'static/resource/images/default_headimg.png',
'friendspay_message' => get_lang('dict_pay_config.pay_leave_message'),
'friendspay_money' => '¥369.00',
'url' => [
'url' => ( new CoreSysConfigService() )->getSceneDomain()[ 'wap_url' ],
'page' => 'app/pages/friendspay/money',
'data' => $url_data,
],
];
return $return_data;
}
$pay_info = ( new Pay() )->field('money')->where([
[ 'trade_id', '=', $trade_id ],
[ 'trade_type', '=', $trade_type ],
[ 'status', '<>', PayDict::STATUS_CANCLE ],///不查询已取消的单据
])->findOrEmpty()->toArray();
if (empty($pay_info)) return [];
$member_info = [];
if ($member_id > 0) {
//查询会员信息
$member_info = ( new Member() )->where([ [ 'member_id', '=', $member_id ] ])->findOrEmpty();
if (!empty($member_info)) {
if (empty($member_info[ 'headimg' ])) {
$member_info[ 'headimg' ] = 'static/resource/images/default_headimg.png';
}
}
}
$pay_config = [];
$pay_type_list = ( new CorePayChannelService() )->getAllowPayTypeByChannel($channel, $trade_type);
if (!empty($pay_type_list) && !empty($pay_type_list[ PayDict::FRIENDSPAY ])) {
$pay_config = $pay_type_list[ PayDict::FRIENDSPAY ][ 'config' ];
}
$return_data = [
'friendspay_message' => $pay_config[ 'pay_leave_message' ] ?? get_lang('dict_pay_config.pay_leave_message'),
'friendspay_money' => '¥' . $pay_info[ 'money' ],
'url' => [
'url' => ( new CoreSysConfigService() )->getSceneDomain()[ 'wap_url' ],
'page' => 'app/pages/friendspay/money',
'data' => $url_data,
],
];
if (!empty($member_info)) {
$return_data[ 'nickname' ] = mb_strlen($member_info[ 'nickname' ]) > 12 ? mb_substr($member_info[ 'nickname' ], 0, 12, 'utf-8') . '...的帮付' : $member_info[ 'nickname' ] . '的帮付';
$return_data[ 'headimg' ] = $member_info[ 'headimg' ];
}
return $return_data;
}
}
}

View File

@ -4,6 +4,7 @@ declare ( strict_types = 1 );
namespace app\listener\system;
use app\listener\poster\FriendspayPoster;
use app\model\member\Member;
/**
@ -18,32 +19,39 @@ class Poster
*/
public function handle($data)
{
$type = $data[ 'type' ] ?? '';
switch ($type) {
case 'friendspay':// 找朋友帮忙付海报
return ( new FriendspayPoster() )->handle($data);
break;
default:
$param = $data[ 'param' ];
$member_id = $param[ 'member_id' ] ?? 0;
$param = $data[ 'param' ];
$member_id = $param[ 'member_id' ] ?? 0;
$member_model = new Member();
$member_info = $member_model->where([
[ 'member_id', '=', $member_id ]
])->field('nickname,headimg')->findOrEmpty()->toArray();
$member_model = new Member();
$member_info = $member_model->where([
[ 'member_id', '=', $member_id ]
])->field('nickname,headimg')->findOrEmpty()->toArray();
if (empty($member_info)) {
return [];
}
if (empty($member_info)) {
return [];
$nickname = $member_info[ 'nickname' ];
if (mb_strlen($nickname, 'UTF-8') > 10) {
$nickname = mb_strlen($nickname) > 10 ? mb_substr($nickname, 0, 7, 'UTF-8') . '...' : $nickname;
}
$headimg = $member_info[ 'headimg' ];
if (empty($headimg)) {
$headimg = 'static/resource/images/default_headimg.png';
}
$return_data = [
'nickname' => $nickname,
'headimg' => $headimg,
];
return $return_data;
break;
}
$nickname = $member_info[ 'nickname' ];
if (mb_strlen($nickname, 'UTF-8') > 10) {
$nickname = mb_strlen($nickname) > 10 ? mb_substr($nickname, 0, 7, 'UTF-8') . '...' : $nickname;
}
$headimg = $member_info[ 'headimg' ];
if (empty($headimg)) {
$headimg = 'static/resource/images/default_headimg.png';
}
$return_data = [
'nickname' => $nickname,
'headimg' => $headimg,
];
return $return_data;
}
}

View File

@ -0,0 +1,30 @@
<?php
declare ( strict_types = 1 );
namespace app\listener\system;
/**
* 系统海报类型
*/
class PosterType
{
/**
* 系统海报
* @param array $data
* @return array
*/
public function handle($data = [])
{
return [
[
'type' => 'friendspay',
'addon' => '',
'name' => '找朋友帮忙付海报',
'decs' => '找朋友帮忙付,分享后进入帮付页面',
'icon' => 'static/resource/images/poster/type_friendspay.png'
],
];
}
}

View File

@ -647,4 +647,27 @@ class DiyService extends BaseAdminService
}
}
}
/**
* 复制自定义页面
* @param array $param
* @return mixed
*/
public function copy($param)
{
$info = $this->model->where([ [ 'id', '=', $param[ 'id' ] ] ])->findOrEmpty()->toArray();
if (empty($info)) throw new AdminException('PAGE_NOT_EXIST');
unset($info[ 'id' ]);
$info[ 'page_title' ] = $info[ 'page_title' ] . '_副本';
$info[ 'is_default' ] = 0;
$info[ 'is_change' ] = 0;
$info[ 'share' ] = '';
$info[ 'create_time' ] = time();
$info[ 'update_time' ] = time();
$res = $this->model->create($info);
return $res->id;
}
}

View File

@ -0,0 +1,84 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\service\admin\member;
use app\model\member\MemberAddress;
use app\service\admin\sys\AreaService;
use app\service\core\member\CoreMemberAddressService;
use core\base\BaseAdminService;
use core\exception\AdminException;
/**
* 会员收货地址服务层
*/
class AddressService extends BaseAdminService
{
public function __construct()
{
parent::__construct();
$this->model = new MemberAddress();
}
/**
* 获取会员收货地址列表
* @param array $where
* @return array
*/
public function getList(array $where = [])
{
return ( new CoreMemberAddressService() )->getList($where);
}
/**
* 获取会员收货地址信息
* @param int $id
* @param array $data
* @return array
*/
public function getInfo($id, $data)
{
return ( new CoreMemberAddressService() )->getInfo($id, $data);
}
/**
* 添加会员收货地址
* @param array $data
* @return mixed
*/
public function add(array $data)
{
$analysis_res = ( new AreaService() )->getAddress($data['full_address']);
if ($analysis_res['status'] == 0 && $analysis_res['message'] == 'Success' && !empty($analysis_res['result'])) {
$data['lng'] = $analysis_res['result']['location']['lng'];
$data['lat'] = $analysis_res['result']['location']['lat'];
}
return ( new CoreMemberAddressService() )->add($data);
}
/**
* 会员收货地址编辑
* @param int $id
* @param array $data
* @return bool
*/
public function edit(int $id, array $data)
{
$analysis_res = ( new AreaService() )->getAddress($data['full_address']);
if ($analysis_res['status'] == 0 && $analysis_res['message'] == 'Success' && !empty($analysis_res['result'])) {
$data['lng'] = $analysis_res['result']['location']['lng'];
$data['lat'] = $analysis_res['result']['location']['lat'];
}
return ( new CoreMemberAddressService() )->edit($id, $data);
}
}

View File

@ -107,11 +107,14 @@ class PayChannelService extends BaseAdminService
if ($config_v !== '' && in_array($config_k, $encrypt_params)) $temp_v_item['config'][$config_k] = CommonDict::ENCRYPT_STR;
}
} else {
$temp_v_item = [ 'status' => 0, 'config' => [ 'name' => '' ], 'sort' => 0 ];
$temp_v_item = [ 'status' => 0, 'config' => $this->getConfigByPayType([], $item_k), 'sort' => 0 ];
}
$item_v[ 'config' ] = $temp_v_item[ 'config' ];
$item_v[ 'status' ] = $temp_v_item[ 'status' ];
$item_v[ 'sort' ] = $temp_v_item[ 'sort' ];
if ($item_k == PayDict::FRIENDSPAY) {
$item_v[ 'name' ] = $temp_v_item[ 'config' ][ 'pay_type_name' ] ?? get_lang('dict_pay.type_friendspay');
}
$channel_list[ $k ][ 'pay_type' ][ $item_k ] = $item_v;
}
$temp_pay_type = array_values($channel_list[ $k ][ 'pay_type' ]);
@ -185,6 +188,18 @@ class PayChannelService extends BaseAdminService
'collection_desc' => $data[ 'collection_desc' ] ?? '',// 必填-转账说明
];
break;
case PayDict::FRIENDSPAY:
$config = [
'pay_type_name' => $data[ 'pay_type_name' ] ?? get_lang('dict_pay.type_friendspay'),// 支付方式名称
'pay_leave_message' => $data[ 'pay_leave_message' ] ?? get_lang('dict_pay_config.pay_leave_message'),// 发起帮付默认留言
'pay_button_name' => $data[ 'pay_button_name' ] ?? get_lang('dict_pay_config.pay_button_name'),// 支付按钮名称
'pay_page_name' => $data[ 'pay_page_name' ] ?? get_lang('dict_pay_config.pay_page_name'),// 帮付页面名称
'pay_explain_switch' => $data[ 'pay_explain_switch' ] ?? 1,// 帮付说明开关, 1开启0关闭
'pay_explain_title' => $data[ 'pay_explain_title' ] ?? get_lang('dict_pay_config.pay_explain_title'),// 帮付说明标题
'pay_explain_content' => $data[ 'pay_explain_content' ] ?? get_lang('dict_pay_config.pay_explain_content'),// 帮付说明内容
'pay_info_switch' => $data[ 'pay_info_switch' ] ?? 1,// 订单信息, 1开启0关闭
];
break;
default:
$config = $data;
}

View File

@ -1,6 +1,6 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// | Niucloud-admin 企业快速开发的saas管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
@ -11,10 +11,20 @@
namespace app\service\admin\pay;
use app\dict\common\ChannelDict;
use app\dict\pay\PayDict;
use app\dict\pay\PaySceneDict;
use app\model\member\Member;
use app\model\pay\Pay;
use app\model\sys\Poster;
use app\service\core\pay\CorePayService;
use app\service\core\paytype\CoreOfflineService;
use app\service\core\sys\CoreSysConfigService;
use core\base\BaseAdminService;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Log;
/**
* 支付服务层
@ -33,9 +43,10 @@ class PayService extends BaseAdminService
* @param array $where
* @return mixed
*/
public function getAuditPage(array $where){
public function getAuditPage(array $where)
{
$field = 'id, out_trade_no, type, money, body, voucher, create_time, trade_id, trade_type, status';
$search_model = $this->model->where([ ['type', '=', PayDict::OFFLINEPAY] ])->withSearch([ 'create_time', 'out_trade_no', 'status' ], $where)->field($field)->append([ 'type_name' ])->order('create_time desc');
$search_model = $this->model->where([ [ 'type', '=', PayDict::OFFLINEPAY ] ])->withSearch([ 'create_time', 'out_trade_no', 'status' ], $where)->field($field)->append([ 'type_name' ])->order('create_time desc');
return $this->pageQuery($search_model);
}
@ -44,9 +55,10 @@ class PayService extends BaseAdminService
* @param int $id
* @return void
*/
public function getDetail(int $id){
public function getDetail(int $id)
{
$field = 'id,out_trade_no,trade_type,trade_id,trade_no,body,money,voucher,status,create_time,pay_time,cancel_time,type,channel,fail_reason';
return $this->model->where([ ['id', '=', $id ] ])
return $this->model->where([ [ 'id', '=', $id ] ])
->field($field)
->append([ 'type_name', 'channel_name', 'status_name' ])
->findOrEmpty()
@ -58,8 +70,9 @@ class PayService extends BaseAdminService
* @param string $out_trade_no
* @return null
*/
public function pass(string $out_trade_no) {
return (new CoreOfflineService())->pass($out_trade_no);
public function pass(string $out_trade_no)
{
return ( new CoreOfflineService() )->pass($out_trade_no);
}
/**
@ -67,8 +80,9 @@ class PayService extends BaseAdminService
* @param string $out_trade_no
* @param string $reason
*/
public function refuse(string $out_trade_no, string $reason) {
return (new CoreOfflineService())->refuse($out_trade_no, $reason);
public function refuse(string $out_trade_no, string $reason)
{
return ( new CoreOfflineService() )->refuse($out_trade_no, $reason);
}
/**
@ -81,4 +95,129 @@ class PayService extends BaseAdminService
{
return $this->model->where($where)->count();
}
/**
* 去支付
* @param string $type
* @param string $trade_type
* @param int $trade_id
* @param string $return_url
* @param string $quit_url
* @param string $buyer_id
* @return mixed
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function pay(string $type, string $trade_type, int $trade_id, string $return_url = '', string $quit_url = '', string $buyer_id = '', string $voucher = '', string $openid = '')
{
return ( new CorePayService() )->pay($trade_type, $trade_id, $type, ChannelDict::PC, $openid, $return_url, $quit_url, $buyer_id, $voucher);
}
/**
* 获取支付信息
* @param string $trade_type
* @param int $trade_id
* @return array
*/
public function getInfoByTrade(string $trade_type, int $trade_id)
{
return ( new CorePayService() )->getInfoByTrade($trade_type, $trade_id, ChannelDict::H5);
}
/**
* 获取找朋友帮忙付支付信息
* @param string $trade_type
* @param int $trade_id
* @return array
*/
public function getFriendspayInfoByTrade(string $trade_type, int $trade_id, string $channel)
{
$pay_info = ( new CorePayService() )->getInfoByTrade($trade_type, $trade_id, ChannelDict::H5, PaySceneDict::FRIENDSPAY);
if (!empty($pay_info)) {
//海报
$poster = ( new Poster() )->field('id')->where([
[ 'type', '=', 'friendspay' ],
[ 'status', '=', 1 ],
[ 'is_default', '=', 1 ]
])->findOrEmpty()->toArray();
if (!empty($poster)) {
$pay_info[ 'poster_id' ] = $poster[ 'id' ];
}
//发起帮付会员信息
$member = ( new Member() )->field('member_id,nickname,headimg')->where([
[ 'member_id', '=', $pay_info[ 'from_main_id' ] ]
])->findOrEmpty()->toArray();
$pay_info[ 'member' ] = $member;
//二维码
$qrcode = $this->getQrcode($trade_type, $trade_id, $channel);
$pay_info[ 'link' ] = $qrcode[ 'url' ];
$pay_info[ 'qrcode' ] = $qrcode[ 'path' ];
}
return $pay_info;
}
/**
* 获取找朋友帮忙付二维码
* @param string $trade_type
* @param int $trade_id
* @return array
*/
public function getQrcode(string $trade_type, int $trade_id, string $channel)
{
$url = ( new CoreSysConfigService() )->getSceneDomain()[ 'wap_url' ];
$page = 'app/pages/friendspay/money';
$data = [
[
'key' => 'id',
'value' => $trade_id
],
[
'key' => 'type',
'value' => $trade_type
]
];
$dir = 'upload/friendspay_qrcode';
$path = '';
try {
$path = qrcode($url, $page, $data, $dir, $channel);
} catch (\Exception $e) {
Log::write('找朋友帮忙付二维码生成error' . $e->getMessage() . $e->getFile() . $e->getLine());
}
$url = $url . '/' . $page;
$scene = [];
foreach ($data as $v) {
$scene[] = $v[ 'key' ] . '=' . $v[ 'value' ];
}
$url .= '?' . implode('&', $scene);
return [
'url' => $url,
'path' => $path
];
}
/**
* 获取支付方式列表
* @return array|array[]
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getPayTypeList()
{
$pay_type_list = ( new CorePayService() )->getPayTypeByTrade('', ChannelDict::H5);
if (!empty($pay_type_list)) {
foreach ($pay_type_list as $k => $v) {
if (!in_array($v['key'], [ PayDict::BALANCEPAY, PayDict::FRIENDSPAY ])) {
unset($pay_type_list[ $k ]);
}
}
$pay_type_list = array_values($pay_type_list);
}
return $pay_type_list;
}
}

View File

@ -87,7 +87,9 @@ class AreaService extends BaseAdminService
while ($area['level'] > 1) {
$area = $this->model->where([ ['id', '=', $area['pid'] ] ])->field('id,level,pid,name')->findOrEmpty();
$tree[ $level[ $area['level'] ] ] = $area->toArray();
if (!$area->isEmpty()) {
$tree[ $level[ $area[ 'level' ] ] ] = $area->toArray();
}
}
}
return $tree;

View File

@ -12,6 +12,7 @@
namespace app\service\api\member;
use app\model\member\MemberAddress;
use app\service\core\member\CoreMemberAddressService;
use core\base\BaseApiService;
@ -35,11 +36,8 @@ class AddressService extends BaseApiService
*/
public function getList(array $where = [])
{
$field = 'id, member_id, name, mobile, province_id, city_id, district_id, address, address_name, full_address, lng, lat, is_default';
$order = 'is_default desc, id desc';
$list = $this->model->where([ ['member_id', '=', $this->member_id ] ])->field($field)->order($order)->select()->toArray();
return $list;
$where['member_id'] = $this->member_id;
return ( new CoreMemberAddressService() )->getList($where);
}
/**
@ -49,10 +47,8 @@ class AddressService extends BaseApiService
*/
public function getInfo(int $id)
{
$field = 'id,member_id,name,mobile,province_id,city_id,district_id,address,address_name,full_address,lng,lat,is_default';
$info = $this->model->field($field)->where([ ['id', '=', $id], ['member_id', '=', $this->member_id ] ])->findOrEmpty()->toArray();
return $info;
$data['member_id'] = $this->member_id;
return ( new CoreMemberAddressService() )->getInfo($id, $data);
}
/**
@ -62,12 +58,8 @@ class AddressService extends BaseApiService
*/
public function add(array $data)
{
if ($data['is_default']) {
$this->model->where([ ['member_id', '=', $this->member_id ] ])->update(['is_default' => 0]);
}
$data['member_id'] = $this->member_id;
$res = $this->model->create($data);
return $res->id;
return ( new CoreMemberAddressService() )->add($data);
}
/**
@ -78,11 +70,8 @@ class AddressService extends BaseApiService
*/
public function edit(int $id, array $data)
{
if ($data['is_default']) {
$this->model->where([ ['member_id', '=', $this->member_id ] ])->update(['is_default' => 0]);
}
$this->model->where([ ['id', '=', $id], ['member_id', '=', $this->member_id ] ])->update($data);
return true;
$data['member_id'] = $this->member_id;
return ( new CoreMemberAddressService() )->edit($id, $data);
}
/**

View File

@ -12,9 +12,15 @@
namespace app\service\api\pay;
use app\dict\common\ChannelDict;
use app\dict\pay\PayDict;
use app\dict\pay\PaySceneDict;
use app\model\member\Member;
use app\model\pay\Pay;
use app\model\sys\Poster;
use app\service\core\member\CoreMemberService;
use app\service\core\pay\CorePayService;
use core\base\BaseApiService;
use core\exception\ApiException;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
@ -57,7 +63,7 @@ class PayService extends BaseApiService
break;
}
return $this->core_pay_service->pay($trade_type, $trade_id, $type, $this->channel, $openid, $return_url, $quit_url, $buyer_id, $voucher);
return $this->core_pay_service->pay($trade_type, $trade_id, $type, $this->channel, $openid, $return_url, $quit_url, $buyer_id, $voucher, $this->member_id);
}
/**
@ -90,8 +96,45 @@ class PayService extends BaseApiService
return $this->core_pay_service->getInfoByOutTradeNo($out_trade_no, $this->channel);
}
public function getInfoByTrade(string $trade_type, int $trade_id){
return $this->core_pay_service->getInfoByTrade($trade_type, $trade_id, $this->channel);
public function getInfoByTrade(string $trade_type, int $trade_id, array $data){
return $this->core_pay_service->getInfoByTrade($trade_type, $trade_id, $this->channel, $data['scene']);
}
/**
* 获取找朋友帮忙付支付信息
* @param string $trade_type
* @param int $trade_id
* @return array
*/
public function getFriendspayInfoByTrade($trade_type, $trade_id){
$from_pay_info = ( new Pay() )->field('id')->where([ [ 'trade_type', '=', $trade_type ], [ 'trade_id', '=', $trade_id ] ])->findOrEmpty()->toArray();//查询发起交易所属的站点id
if (empty($from_pay_info)) throw new ApiException('TRADE_NOT_EXIST');
$pay_info = $this->core_pay_service->getInfoByTrade($trade_type, $trade_id, $this->channel, PaySceneDict::FRIENDSPAY);
if (!empty($pay_info)) {
//todo 查询订单交易信息,其它插件可实现该钩子
$trade_info = array_values(array_filter(event('PayTradeInfo',[ 'trade_type' => $trade_type, 'trade_id' => $trade_id ])))[0] ?? [];
$pay_info['trade_info'] = $trade_info;
if ($pay_info['from_main_id'] != $this->member_id) {
$pay_info['is_self'] = false;
} else {
$pay_info['is_self'] = true;
}
//海报
$poster = ( new Poster() )->field('id')->where([
[ 'type', '=', 'friendspay' ],
[ 'status', '=', 1 ],
[ 'is_default', '=', 1 ]
])->findOrEmpty()->toArray();
if (!empty($poster)) {
$pay_info['poster_id'] = $poster['id'];
}
//发起帮付会员信息
$member = ( new Member() )->field('member_id,nickname,headimg')->where([
[ 'member_id', '=', $pay_info['from_main_id'] ]
])->findOrEmpty()->toArray();
$pay_info['member'] = $member;
}
return $pay_info;
}
/**

View File

@ -13,6 +13,7 @@ namespace app\service\core\member;
use app\model\member\MemberAddress;
use core\base\BaseCoreService;
use core\exception\CommonException;
/**
* 会员标签服务层
@ -28,6 +29,66 @@ class CoreMemberAddressService extends BaseCoreService
$this->model = new MemberAddress();
}
/**
* 获取会员收货地址列表
* @param array $where
* @return array
*/
public function getList(array $where = [])
{
if (empty($where['member_id'])) throw new CommonException('MEMBER_NOT_EXIST');
$field = 'id, member_id, name, mobile, province_id, city_id, district_id, address, address_name, full_address, lng, lat, is_default';
$order = 'is_default desc, id desc';
$list = $this->model->where([ ['member_id', '=', $where['member_id'] ] ])->field($field)->order($order)->select()->toArray();
return $list;
}
/**
* 获取会员收货地址信息
* @param int $id
* @param array $data
* @return array
*/
public function getInfo(int $id, array $data)
{
if (empty($data['member_id'])) throw new CommonException('MEMBER_NOT_EXIST');
$field = 'id,member_id,name,mobile,province_id,city_id,district_id,address,address_name,full_address,lng,lat,is_default';
$info = $this->model->field($field)->where([ ['id', '=', $id], ['member_id', '=', $data['member_id'] ] ])->findOrEmpty()->toArray();
return $info;
}
/**
* 添加会员收货地址
* @param array $data
* @return mixed
*/
public function add(array $data)
{
if (empty($data['member_id'])) throw new CommonException('MEMBER_NOT_EXIST');
if ($data['is_default']) {
$this->model->where([ ['member_id', '=', $data['member_id'] ] ])->update(['is_default' => 0]);
}
$res = $this->model->create($data);
return $res->id;
}
/**
* 会员收货地址编辑
* @param int $id
* @param array $data
* @return bool
*/
public function edit(int $id, array $data)
{
if (empty($data['member_id'])) throw new CommonException('MEMBER_NOT_EXIST');
if ($data['is_default']) {
$this->model->where([ ['member_id', '=', $data['member_id'] ] ])->update(['is_default' => 0]);
}
$this->model->where([ ['id', '=', $id], ['member_id', '=', $data['member_id'] ] ])->update($data);
return true;
}
/**
* 获取会员默认地址

View File

@ -40,7 +40,8 @@ class CorePayChannelService extends BaseCoreService
* @param array $where
* @return PayChannel|array|mixed|Model
*/
public function find(array $where){
public function find(array $where)
{
return $this->model->where($where)->findOrEmpty();
}
@ -53,21 +54,35 @@ class CorePayChannelService extends BaseCoreService
* @throws DbException
* @throws ModelNotFoundException
*/
public function getAllowPayTypeByChannel(string $channel, string $trade_type = ''){
$channel_pay_list = $this->model->where([['channel', '=', $channel], ['status', '=', 1]])->field('type,config')->order('sort asc')->select()->toArray();
public function getAllowPayTypeByChannel(string $channel, string $trade_type = '')
{
$channel_pay_list = $this->model->where([ [ 'channel', '=', $channel ], [ 'status', '=', 1 ] ])->field('type,config')->order('sort asc')->select()->toArray();
if(!empty($channel_pay_list)){
if (!empty($channel_pay_list)) {
$temp_channel_pay_list = array_column($channel_pay_list, 'type');
$pay_type_list = PayDict::getPayType($temp_channel_pay_list);
$pay_type_arr = PayDict::getPayType($temp_channel_pay_list);
foreach ($temp_channel_pay_list as $key) {
if (isset($pay_type_arr[$key])) {
$pay_type_list[$key] = $pay_type_arr[$key];
}
}
}
//充值订单不支持余额支付
if(!empty($pay_type_list) && $trade_type == 'recharge'){
unset($pay_type_list[PayDict::BALANCEPAY]);
//充值订单不支持余额支付和找朋友帮忙付
if (!empty($pay_type_list) && $trade_type == 'recharge') {
unset($pay_type_list[ PayDict::BALANCEPAY ], $pay_type_list[ PayDict::FRIENDSPAY ]);
}
// 线下支付做处理
if (!empty($pay_type_list) && isset($pay_type_list[PayDict::OFFLINEPAY])) {
if (!empty($pay_type_list) && isset($pay_type_list[ PayDict::OFFLINEPAY ])) {
$temp_channel_pay_list = array_column($channel_pay_list, null, 'type');
$pay_type_list[PayDict::OFFLINEPAY]['config'] = $temp_channel_pay_list[PayDict::OFFLINEPAY]['config'];
$pay_type_list[ PayDict::OFFLINEPAY ][ 'config' ] = $temp_channel_pay_list[ PayDict::OFFLINEPAY ][ 'config' ];
}
// 找朋友帮忙付做处理
if (!empty($pay_type_list) && isset($pay_type_list[ PayDict::FRIENDSPAY ])) {
$temp_channel_pay_list = array_column($channel_pay_list, null, 'type');
$pay_type_list[ PayDict::FRIENDSPAY ][ 'config' ] = $temp_channel_pay_list[ PayDict::FRIENDSPAY ][ 'config' ];
if (!empty($temp_channel_pay_list[ PayDict::FRIENDSPAY ][ 'config' ])) {
$pay_type_list[ PayDict::FRIENDSPAY ][ 'name' ] = $temp_channel_pay_list[ PayDict::FRIENDSPAY ][ 'config' ][ 'pay_type_name' ];
}
}
return $pay_type_list ?? [];
@ -79,10 +94,11 @@ class CorePayChannelService extends BaseCoreService
* @param string $type
* @return array|mixed
*/
public function getConfigByChannelAndType(string $channel, string $type){
$pay_channel = $this->model->where([ ['channel', '=', $channel], ['type', '=', $type]])->field('config')->findOrEmpty();
if(!$pay_channel->isEmpty()){
if($type == PayDict::WECHATPAY){
public function getConfigByChannelAndType(string $channel, string $type)
{
$pay_channel = $this->model->where([ [ 'channel', '=', $channel ], [ 'type', '=', $type ] ])->field('config')->findOrEmpty();
if (!$pay_channel->isEmpty()) {
if ($type == PayDict::WECHATPAY) {
$pay_channel->config = array_merge($pay_channel->config, $this->getWechatPayFullConfig());
}
return $pay_channel->config;
@ -90,19 +106,19 @@ class CorePayChannelService extends BaseCoreService
return [];
}
/**
* 获取完整的微信支付配置(根据场景)
* @return array
*/
public function getWechatPayFullConfig(){
public function getWechatPayFullConfig()
{
//TODO 先判断是否是开放平台授权,然后再决定使用什么appid
//查询公众号配置
$core_wechat_config_service = new CoreWechatConfigService();
$mp_app_id = $core_wechat_config_service->getWechatConfig()['app_id'];//公众号appid
$mp_app_id = $core_wechat_config_service->getWechatConfig()[ 'app_id' ];//公众号appid
//查询公众号配置
$core_weapp_config_service = new CoreWeappConfigService();
$mini_app_id = $core_weapp_config_service->getWeappConfig()['app_id'];//小程序appid
$mini_app_id = $core_weapp_config_service->getWeappConfig()[ 'app_id' ];//小程序appid
//todo 查询微信小程序 appid . 应用appid.....
return [
'mp_app_id' => $mp_app_id,

View File

@ -23,7 +23,6 @@ use think\Response;
use Yansongda\Pay\Exception\ContainerException;
use Yansongda\Pay\Exception\InvalidParamsException;
use Yansongda\Pay\Exception\ServiceNotFoundException;
use Yansongda\Supports\Collection;
/**
* 支付服务层
@ -42,7 +41,6 @@ class CorePayEventService extends BaseCoreService
parent::__construct();
}
/**
* 支付引擎外置触点初始化
* @param string $channel
@ -70,7 +68,6 @@ class CorePayEventService extends BaseCoreService
return new PayLoader($this->type, $this->config);
}
/**
* 去支付
* @param string $out_trade_no

View File

@ -13,6 +13,7 @@ namespace app\service\core\pay;
use app\dict\pay\OnlinePayDict;
use app\dict\pay\PayDict;
use app\dict\pay\PaySceneDict;
use app\job\pay\PayReturnTo;
use app\model\pay\Pay;
use core\base\BaseCoreService;
@ -21,7 +22,6 @@ use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Db;
use think\facade\Log;
use think\Model;
use Throwable;
@ -61,6 +61,7 @@ class CorePayService extends BaseCoreService
'body' => $body,
'out_trade_no' => $out_trade_no,
'main_id' => $main_id,
'from_main_id' => $main_id,
'main_type' => $main_type
);
$this->model->create($data);
@ -119,6 +120,30 @@ class CorePayService extends BaseCoreService
return $pay;
}
/**
* 通过业务类型和id查询支付状态
* @param string $trade_type
* @param int $trade_id
* @return bool
*/
public function getPayStatusByTrade(string $trade_type, int $trade_id)
{
$where = array(
[ 'trade_type', '=', $trade_type ],
[ 'trade_id', '=', $trade_id ],
);
$pay_info = $this->model->field('status')->where($where)->findOrEmpty();
if ($pay_info->isEmpty()) {
throw new PayException('TRADE_NOT_EXIST');//支付单据不存在
} else {
if ($pay_info[ 'status' ] == PayDict::STATUS_FINISH) {
return true;
} else {
return false;
}
}
}
/**
* 通过交易信息获取支付单据
* @param string $trade_type
@ -129,7 +154,7 @@ class CorePayService extends BaseCoreService
* @throws DbException
* @throws ModelNotFoundException
*/
public function getInfoByTrade(string $trade_type, string $trade_id, string $channel)
public function getInfoByTrade(string $trade_type, string $trade_id, string $channel, string $scene = '')
{
$pay = $this->findPayInfoByTrade($trade_type, $trade_id);
if ($pay->isEmpty()) {
@ -141,7 +166,13 @@ class CorePayService extends BaseCoreService
}
if (!empty($pay)) {
//todo 校验场景控制支付方式
$pay[ 'pay_type_list' ] = array_values(( new CorePayChannelService() )->getAllowPayTypeByChannel($channel, $pay[ 'trade_type' ]));
$pay_type_list = ( new CorePayChannelService() )->getAllowPayTypeByChannel($channel, $pay[ 'trade_type' ]);
//找朋友帮忙付时不支持找朋友帮忙付
if(!empty($pay_type_list) && !empty($pay_type_list[PayDict::FRIENDSPAY]) && $scene == PaySceneDict::FRIENDSPAY){
$pay[ 'config' ] = $pay_type_list[PayDict::FRIENDSPAY]['config'];
unset($pay_type_list[PayDict::FRIENDSPAY]);
}
$pay[ 'pay_type_list' ] = array_values($pay_type_list);
}
return $pay;
}
@ -176,7 +207,7 @@ class CorePayService extends BaseCoreService
* @throws DbException
* @throws ModelNotFoundException
*/
public function pay($trade_type, $trade_id, $type, $channel, string $openid, string $return_url = '', string $quit_url = '', string $buyer_id = '', string $voucher = '')
public function pay($trade_type, $trade_id, $type, $channel, string $openid, string $return_url = '', string $quit_url = '', string $buyer_id = '', string $voucher = '', $member_id = 0)
{
//检测并创建支付单据
$pay = $this->checkOrCreate($trade_type, $trade_id);
@ -185,10 +216,19 @@ class CorePayService extends BaseCoreService
$body = $pay[ 'body' ];
$trade_type = $pay[ 'trade_type' ];
if (!in_array($type, array_column(( new CorePayChannelService() )->getAllowPayTypeByChannel($channel, $trade_type), 'key'))) throw new PayException('PAYMENT_METHOD_NOT_SCENE');//场景不支持
if ($member_id != 0) {
//更新付款人id
$pay_info = $this->findPayInfoByTrade($trade_type, $trade_id);
$pay_info->save([
'main_id' => $member_id
]);
}
$pay_result = $this->pay_event->init($channel, $type)->pay($out_trade_no, $money, $body, $return_url, $quit_url, $buyer_id, $openid ?? '', $voucher);
//todo 特殊支付方式会直接返回支付状态,状态如果为已支付会直接支付
if (!empty($pay_result[ 'status' ]) && $pay_result[ 'status' ] == PayDict::STATUS_FINISH) {
$pay->save([ 'channel' => $channel ]);
$pay->save([
'channel' => $channel
]);
$this->paySuccess([
'status' => PayDict::STATUS_FINISH,
'type' => $type,
@ -488,6 +528,7 @@ class CorePayService extends BaseCoreService
$type = $params[ 'type' ];
$trade_type = $pay->trade_type;
$trade_id = $pay->trade_id;
$main_id = $pay->main_id;
$data = array(
'pay_time' => time(),
'status' => PayDict::STATUS_FINISH,
@ -503,7 +544,7 @@ class CorePayService extends BaseCoreService
Db::startTrans();
try {
$pay->allowField($allow_field)->save($data);
$result = event('PaySuccess', [ 'out_trade_no' => $out_trade_no, 'trade_type' => $trade_type, 'trade_id' => $trade_id ]);
$result = event('PaySuccess', [ 'out_trade_no' => $out_trade_no, 'trade_type' => $trade_type, 'trade_id' => $trade_id, 'main_id' => $main_id ]);
// if (!check_event_result($result)) {
// Db::rollback();
// return false;

View File

@ -21,7 +21,7 @@ use Throwable;
/**
* 退款服务层
* Class CorePayService
* Class CoreRefundService
* @package app\service\core\pay
*/
class CoreRefundService extends BaseCoreService

View File

@ -0,0 +1,42 @@
<?php
namespace app\upgrade\v144;
use app\model\diy\Diy;
use app\model\site\Site;
use app\model\sys\Poster;
use app\service\core\poster\CorePosterService;
class Upgrade
{
public function handle()
{
$this->handleDiyData();
}
/**
* 处理自定义数据
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function handleDiyData()
{
$poster_model = new Poster();
$poster = new CorePosterService();
$template = $poster->getTemplateList('', 'friendspay')[ 0 ];
$poster_model->where([ [ 'type', '=', 'friendspay' ] ])->delete();
// 创建默认找朋友帮忙付海报
$poster->add('', [
'name' => $template[ 'name' ],
'type' => $template[ 'type' ],
'value' => $template[ 'data' ],
'status' => 1,
'is_default' => 1
]);
}
}

View File

@ -0,0 +1,4 @@
ALTER TABLE `pay` ADD COLUMN `from_main_id` INT(11) NOT NULL DEFAULT 0 COMMENT '发起支付会员id';
ALTER TABLE `pay` MODIFY `from_main_id` INT(11) NOT NULL DEFAULT 0 COMMENT '发起支付会员id' AFTER `main_id`;

View File

@ -1,7 +1,6 @@
<?php
return [
'version' => '1.4.3',
'code' => '202412120001'
'version' => '1.4.4',
'code' => '202501030001'
];

View File

@ -0,0 +1,43 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的saas管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace core\dict;
class RechargeGift extends BaseDict
{
/**
* 加载会员充值赠品组件
* @param array $data
* @return array|mixed
*/
public function load(array $data = [])
{
$addons = $this->getLocalAddons();
foreach ($addons as $v) {
$addon_change_type_file = $this->getAddonDictPath($v) . "recharge" . DIRECTORY_SEPARATOR . "package_gift.php";
if (is_file($addon_change_type_file)) {
$account_change_type_files[] = $addon_change_type_file;
}
}
$account_change_type_datas = $this->loadFiles($account_change_type_files);
$account_change_type_array = [];
foreach ($account_change_type_datas as $account_change_type_data) {
$account_change_type_array = empty($account_change_type_array) ? $account_change_type_data : array_merge2($account_change_type_array, $account_change_type_data);
}
foreach ($account_change_type_array as $key => &$value) {
$value[ 'key' ] = $key;
}
usort($account_change_type_array, function($list_one, $list_two) {
return $list_one[ 'sort' ] <=> $list_two[ 'sort' ];
});
return $account_change_type_array;
}
}

View File

@ -5,7 +5,6 @@ namespace core\pay;
use app\dict\pay\OnlinePayDict;
use app\dict\pay\RefundDict;
use app\dict\pay\TransferDict;
use core\exception\CommonException;
use core\exception\PayException;
use Psr\Http\Message\MessageInterface;
use Psr\Http\Message\ResponseInterface;

View File

@ -53,7 +53,11 @@ class Local extends BaseUpload
{
try {
mkdirs_or_notexist(dirname($key), 0777);
$content = @file_get_contents($url);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$content = curl_exec($ch);
curl_close($ch);
// $content = @file_get_contents($url);//file_get_contents下载网络图片慢更换为curl下载
if (!empty($content)) {
file_put_contents($key, $content);