This commit is contained in:
全栈小学生 2025-03-10 14:14:51 +08:00
parent 582c7a832d
commit 1b06e9a04c
117 changed files with 3174 additions and 893 deletions

View File

@ -270,7 +270,7 @@ class Diy extends BaseAdminController
}
/**
* 获取自定义主题配色
* 获取主题风格列表
* @return Response
*/
public function getDiyTheme()
@ -279,30 +279,79 @@ class Diy extends BaseAdminController
}
/**
* 添加主题配色
* 设置主题风格
* @return Response
*/
public function setDiyTheme()
{
$data = $this->request->params([
[ 'id', '' ],
[ 'key', '' ],
[ 'mode', '' ],
[ 'color_mark', '' ],
[ 'color_name', '' ],
[ 'diy_value', '' ],
[ 'value', '' ],
[ 'addon', '' ],
[ 'title', '' ],
[ 'theme', '' ],
[ 'new_theme', '' ],
]);
( new DiyService() )->setDiyTheme($data);
return success('ADD_SUCCESS');
}
/**
* 设置主题配色
* 获取主题配色列表
* @return Response
*/
public function getDefaultThemeColor()
{
return success(( new DiyService() )->getDefaultThemeColor());
$data = $this->request->params([
[ 'addon', '' ],
]);
return success(( new DiyService() )->getDefaultThemeColor($data));
}
/**
* 添加自定义主题配色
* @return Response
*/
public function addDiyTheme()
{
$data = $this->request->params([
[ 'title', '' ],
[ 'default_theme', '' ],
[ 'theme', '' ],
[ 'new_theme', '' ],
[ 'addon', '' ]
]);
$this->validate($data, 'app\validate\diy\DiyTheme.add');
( new DiyService() )->addDiyTheme($data);
return success('ADD_SUCCESS');
}
/**
* 编辑自定义主题配色
* @param $id
* @return Response
*/
public function editDiyTheme($id)
{
$data = $this->request->params([
[ 'title', '' ],
[ 'theme', '' ],
[ 'new_theme', '' ],
[ 'addon', '' ]
]);
$data[ 'id' ] = $id;
$this->validate($data, 'app\validate\diy\DiyTheme.edit');
( new DiyService() )->editDiyTheme($id, $data);
return success('EDIT_SUCCESS');
}
/**
* 删除自定义主题配色
* @param $id
* @return Response
*/
public function delDiyTheme(int $id)
{
( new DiyService() )->delDiyTheme($id);
return success('DELETE_SUCCESS');
}
}

View File

@ -42,6 +42,21 @@ class DiyForm extends BaseAdminController
return success(( new DiyFormService() )->getPage($data));
}
/**
* @notes 获取万能表单分页列表(用于弹框选择)
* @return Response
*/
public function select()
{
$data = $this->request->params([
[ "title", "" ],
[ "type", "" ],
[ 'addon', '' ],
[ 'verify_form_ids', '' ] // 检测id集合是否存在移除不存在的id纠正数据准确性
]);
return success(( new DiyFormService() )->getSelectPage($data));
}
/**
* @notes 获取万能表单列表
* @return Response
@ -101,7 +116,7 @@ class DiyForm extends BaseAdminController
[ "value", [] ],
[ 'template', '' ],
]);
$data[ 'form_id' ] = $id;
$this->validate($data, 'app\validate\diy\DiyForm.edit');
( new DiyFormService() )->edit($id, $data);
return success('MODIFY_SUCCESS');

View File

@ -120,4 +120,15 @@ class CashOut extends BaseAdminController
(new MemberCashOutService())->checkTransferStatus($id);
return success();
}
/**
* 取消
* @param $id
* @return void
*/
public function cancel($id){
(new MemberCashOutService())->cancel($id);
return success();
}
}

View File

@ -0,0 +1,54 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的saas管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\adminapi\controller\pay;
use app\dict\pay\TransferDict;
use app\service\admin\pay\PayService;
use app\service\admin\pay\TransferService;
use core\base\BaseAdminController;
class Transfer extends BaseAdminController
{
/**
* 转账方式
* @return \think\Response
*/
public function getWechatTransferScene(){
return success(data:(new TransferService())->getWechatTransferScene());
}
/**
* 设置场景id
* @param $scene
* @return void
*/
public function setSceneId($scene){
$data = $this->request->params([
['scene_id', ''],
]);
return success(data:(new TransferService())->setSceneId($scene, $data));
}
/**
* 设置业务转账场景配置
* @param $type
* @return \think\Response
*/
public function setTradeScene($type){
$data = $this->request->params([
['scene', ''],
['infos', []],
['perception', ''],
]);
return success(data:(new TransferService())->setTradeScene($type, $data));
}
}

View File

@ -50,14 +50,21 @@ class System extends BaseAdminController
}
/**
* 清理缓存,更新菜单
* 清理缓存
*/
public function schemaCache()
{
return success((new SystemService())->schemaCache());
}
/**
* 清理缓存
*/
public function clearCache()
{
return success((new SystemService())->clearCache());
}
/**
* 校验消息队列是否正常运行
* @return Response

View File

@ -48,4 +48,42 @@ class Config extends BaseAdminController
return success('SET_SUCCESS');
}
/**
* 设置微信小程序域名
* @return Response
*/
public function setDomain() {
$data = $this->request->params([
['requestdomain', ''],
['wsrequestdomain', ''],
['uploaddomain', ''],
['downloaddomain', ''],
['udpdomain', ''],
['tcpdomain', '']
]);
(new WeappConfigService())->setDomain($data);
return success('SET_SUCCESS');
}
/**
* 获取微信小程序隐私协议
* @return Response
*/
public function getPrivacySetting() {
return success((new WeappConfigService())->getPrivacySetting());
}
/**
* 设置微信小程序隐私协议
* @return Response
*/
public function setPrivacySetting() {
$data = $this->request->params([
['setting_list', []],
['owner_setting', []],
['sdk_privacy_info_list', []]
]);
(new WeappConfigService())->setPrivacySetting($data);
return success('SET_SUCCESS');
}
}

View File

@ -93,6 +93,15 @@ Route::group('diy', function() {
// 获取默认主题配色
Route::get('theme/color', 'diy.Diy/getDefaultThemeColor');
// 添加自定义主题配色
Route::post('theme/add', 'diy.Diy/addDiyTheme');
// 编辑自定义主题配色
Route::put('theme/edit/:id', 'diy.Diy/editDiyTheme');
// 删除自定义主题配色
Route::delete('theme/delete/:id', 'diy.Diy/delDiyTheme');
/***************************************************** 配置相关 *****************************************************/
// 底部导航列表
@ -112,6 +121,9 @@ Route::group('diy', function() {
// 万能表单列表
Route::get('form/list', 'diy.DiyForm/lists');
// 万能表单分页列表(用于弹框选择)
Route::get('form/select', 'diy.DiyForm/select');
// 万能表单类型
Route::get('form/type', 'diy.DiyForm/getFormType');

View File

@ -122,6 +122,8 @@ Route::group('member', function() {
Route::put('cash_out/audit/:id/:action', 'member.CashOut/audit');
//会员提现备注
Route::put('cash_out/remark/:id', 'member.CashOut/remark');
//取消会员提现
Route::put('cash_out/cancel/:id', 'member.CashOut/cancel');
//校验会员提现转账状态
Route::put('cash_out/check/:id', 'member.CashOut/checkTransferStatus');
//转账方式

View File

@ -59,6 +59,14 @@ Route::group('pay', function () {
Route::get('type/list', 'pay.Pay/payTypeList');
//找朋友帮忙付支付信息
Route::get('friendspay/info/:trade_type/:trade_id/:channel', 'pay.Pay/friendspayInfo');
/***************************************************** 转账 *************************************************/
//获取转账场景
Route::get('transfer_scene', 'pay.Transfer/getWechatTransferScene');
//设置场景id
Route::post('transfer_scene/set_scene_id/:scene', 'pay.Transfer/setSceneId');
//设置业务场景配置
Route::post('transfer_scene/set_trade_scene/:type', 'pay.Transfer/setTradeScene');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,

View File

@ -203,6 +203,7 @@ Route::group('sys', function() {
/***************************************************** 清理缓存-刷新菜单 ****************************************************/
Route::post('schema/clear', 'sys.System/schemaCache');
Route::post('cache/clear', 'sys.System/clearCache');
/***************************************************** 公共字典数据 ****************************************************/
Route::get('date/month', 'sys.Common/getMonth');

View File

@ -24,6 +24,12 @@ Route::group('weapp', function() {
Route::get('config', 'weapp.Config/get');
//设置微信配置
Route::put('config', 'weapp.Config/set');
//设置微信域名
Route::put('domain', 'weapp.Config/setDomain');
// 设置微信隐私协议
Route::put('privacysetting', 'weapp.Config/setPrivacySetting');
// 获取微信隐私协议
Route::get('privacysetting', 'weapp.Config/getPrivacySetting');
/***************************************************** 订阅消息 ****************************************************/
//同步订阅消息
@ -41,6 +47,7 @@ Route::group('weapp', function() {
Route::get('upload/:key', 'weapp.Version/uploadLog');
/***************************************************** 小程序发货信息管理服务 ****************************************************/
// 查询小程序是否已开通发货信息管理服务

View File

@ -86,7 +86,8 @@ class Login extends BaseController
[ 'mobile', '' ],
[ 'nickname', '' ],
[ 'headimg', '' ],
[ 'mobile', '' ]
[ 'mobile', '' ],
[ 'openid', '' ]
]);
//校验登录注册配置
( new ConfigService() )->checkLoginConfig(MemberLoginTypeDict::MOBILE);

View File

@ -31,13 +31,14 @@ class Register extends BaseController
[ 'username', '' ],
[ 'password', '' ],
[ 'mobile', '' ],
[ 'wx_openid', '' ]
]);
//校验登录注册配置
( new ConfigService() )->checkLoginConfig(MemberLoginTypeDict::USERNAME);
//参数验证
$this->validate($data, 'app\validate\member\Member.account_register');
//验证码验证
$result = ( new RegisterService() )->account($data[ 'username' ], $data[ 'password' ], $data[ 'mobile' ]);
$result = ( new RegisterService() )->account($data[ 'username' ], $data[ 'password' ], $data[ 'mobile' ], $data[ 'wx_openid' ]);
return success($result);
}

View File

@ -27,12 +27,12 @@ class MemberCashOut extends BaseApiController
public function lists()
{
$data = array_filter($this->request->params([
[ 'status', '' ],
[ 'account_type', '' ]
]), function($value){
['status', ''],
['account_type', '']
]), function ($value) {
return $value !== '';
});
return success(( new MemberCashOutService() )->getPage($data));
return success((new MemberCashOutService())->getPage($data));
}
/**
@ -41,7 +41,7 @@ class MemberCashOut extends BaseApiController
*/
public function info($id)
{
return success(( new MemberCashOutService() )->getInfo($id));
return success((new MemberCashOutService())->getInfo($id));
}
/**
@ -50,7 +50,7 @@ class MemberCashOut extends BaseApiController
*/
public function config()
{
return success(( new MemberCashOutService() )->getCashOutConfig());
return success((new MemberCashOutService())->getCashOutConfig());
}
/**
@ -69,14 +69,14 @@ class MemberCashOut extends BaseApiController
public function apply()
{
$data = $this->request->params([
[ 'apply_money', 0 ],
[ 'account_type', MemberAccountTypeDict::MONEY ],
[ 'transfer_type', '' ],
[ 'account_id', 0 ],
[ 'transfer_payee', []] ,//收款方信息
['apply_money', 0],
['account_type', MemberAccountTypeDict::MONEY],
['transfer_type', ''],
['account_id', 0],
['transfer_payee', []],//收款方信息
]);
$this->validate($data, 'app\validate\member\CashOut.apply');
return success(data:( new MemberCashOutService() )->apply($data));
return success(data: (new MemberCashOutService())->apply($data));
}
/**
@ -86,7 +86,20 @@ class MemberCashOut extends BaseApiController
*/
public function cancel($id)
{
return success(data:( new MemberCashOutService() )->cancel($id));
return success(data: (new MemberCashOutService())->cancel($id));
}
/**
* 开始转账
* @param $id
* @return Response
*/
public function transfer($id)
{
$data = $this->request->params([
['open_id', 0],
]);
return success(data: (new MemberCashOutService())->transfer($id, $data));
}
}

View File

@ -0,0 +1,43 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的saas管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\api\controller\pay;
use app\service\api\pay\PayService;
use core\base\BaseApiController;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Response;
/**
* 微信服务端通信以及网页授权
*/
class Transfer extends BaseApiController
{
/**
* 确认收款
* @return Response
*/
public function confirm($transfer_no)
{
// $data = $this->request->params([
// ['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']));
}
}

View File

@ -80,6 +80,7 @@ class Config extends BaseApiController
{
$data = $this->request->params([
[ 'url', '' ],
[ 'openid', '' ]
]);
$res = [];
@ -90,6 +91,12 @@ class Config extends BaseApiController
$res[ 'login_config' ] = ( new MemberConfigService() )->getLoginConfig($data[ 'url' ]);
$res[ 'theme_list' ] = ( new DiyService() )->getDiyTheme();
// 查询是否已经存在该小程序用户, 如果存在则小程序端快捷登录时不再弹出授权弹框
$res[ 'member_exist' ] = 0;
if (!empty($data[ 'openid' ])) {
$res[ 'member_exist' ] = ( new MemberService() )->getCount([ [ 'weapp_openid', '=', $data[ 'openid' ] ] ]) > 0 ? 1 : 0;
}
( new MemberService() )->initMemberData();
if (isset($res[ 'site_info' ][ 'site_id' ]) && !empty($res[ 'site_info' ][ 'site_id' ])) {

View File

@ -41,4 +41,5 @@ Route::group('file', function() {
Route::post('image/base64', 'upload.Upload/imageBase64');
})->middleware(ApiChannel::class)
->middleware(ApiCheckToken::class, false)
->middleware(ApiLog::class);

View File

@ -66,6 +66,8 @@ Route::group('member', function () {
Route::post('cash_out/apply', 'member.MemberCashOut/apply');
//撤销提现申请
Route::put('cash_out/cancel/:id', 'member.MemberCashOut/cancel');
// 提现转账
Route::post('cash_out/transfer/:id', 'member.MemberCashOut/transfer');
// 提现账号列表
Route::get('cashout_account', 'member.CashOutAccount/lists');
// 提现账号详情
@ -78,7 +80,6 @@ Route::group('member', function () {
Route::put('cashout_account/:account_id', 'member.CashOutAccount/edit');
// 删除提现账号
Route::delete('cashout_account/:account_id', 'member.CashOutAccount/del');
/***************************************************** 会员地址 **************************************************/
//会员收货地址列表
Route::get('address', 'member.Address/lists');

View File

@ -40,6 +40,16 @@ Route::group('pay',function () {
//支付关闭
Route::post('close', 'pay.Pay/close');
})->middleware(ApiChannel::class)
->middleware(ApiCheckToken::class, true)//表示验证登录
->middleware(ApiLog::class);
Route::group('transfer',function () {
//去支付
Route::post('confirm/:transfer_no', 'pay.Pay/pay');
})->middleware(ApiChannel::class)
->middleware(ApiCheckToken::class, true)//表示验证登录
->middleware(ApiLog::class);

View File

@ -560,8 +560,12 @@ function dir_copy(string $src = '', string $dst = '', &$files = [], $exclude_dir
} else {
// 排除文件
if (count($exclude_files) && in_array($file, $exclude_files)) continue;
copy($src . '/' . $file, $dst . '/' . $file);
$copyResult = copy($src . '/' . $file, $dst . '/' . $file);
$files[] = $dst . '/' . $file;
if (!$copyResult) {
closedir($dir);
throw new \core\exception\CommonException("文件{$file}拷贝失败请检查是否有足够的权限");
}
}
}
}
@ -1018,3 +1022,53 @@ function get_last_time($time = null)
}
return $text;
}
/**
* 检查目录及其子目录的权限
* @param string $dir 要检查的目录路径
* @return void
*/
function checkDirPermissions($dir, $data = []) {
if (!is_dir($dir)) {
throw new \RuntimeException(sprintf('指定的路径 "%s" 不是一个有效的目录', $dir));
}
if (empty($data)) {
$data = [
'unreadable' => [],
'not_writable' => []
];
}
try {
if (!is_readable($dir)) {
$data['unreadable'][] = $dir;
}
if (!is_writable($dir)) {
$data['not_writable'][] = $dir;
}
if (is_readable($dir)) {
$dh = opendir($dir);
while (($file = readdir($dh)) !== false) {
if ($file === '.' || $file === '..') {
continue;
}
$fullPath = $dir . DIRECTORY_SEPARATOR . $file;
// 判断是否为目录,如果是则递归调用
if (is_dir($fullPath)) {
$data = checkDirPermissions($fullPath, $data); // 递归调用自身来检查子目录
} else {
// 如果是文件,则检查其读写权限
if (!is_readable($fullPath)) $data['unreadable'][] = $fullPath;
if (!is_writable($fullPath)) $data['not_writable'][] = $fullPath;
}
}
closedir($dh);
}
return $data;
} catch (Exception $e) {
$data['unreadable'][] = $dir;
$data['not_writable'][] = $dir;
return $data;
}
}

View File

@ -614,7 +614,8 @@ class ComponentDict
]
]
],
"offset" => 0 // 偏移量
"offset" => 0, // 上下偏移量
"lateralOffset" => 15 // 左右偏移量
],
],
'HorzBlank' => [

View File

@ -28,136 +28,6 @@ class LinkDict
*/
public static function getLink($params = [])
{
$system_links = [
'SYSTEM_LINK' => [
'title' => get_lang('dict_diy.system_link'),
'addon_info' => [
'title' => '系统',
'key' => 'app'
],
'child_list' => [
[
'name' => 'INDEX',
'title' => get_lang('dict_diy.system_link_index'),
'url' => '/app/pages/index/index',
'is_share' => 1,
'action' => 'decorate' // 默认空decorate 表示支持装修
],
]
],
'MEMBER_LINK' => [
'title' => get_lang('dict_diy.member_link'),
'addon_info' => [
'title' => '系统',
'key' => 'app'
],
'child_list' => [
[
'name' => 'MEMBER_CENTER',
'title' => get_lang('dict_diy.member_index'),
'url' => '/app/pages/member/index',
'is_share' => 1,
'action' => 'decorate'
],
[
'name' => 'MEMBER_PERSONAL',
'title' => get_lang('dict_diy.member_my_personal'),
'url' => '/app/pages/member/personal',
'is_share' => 0,
'action' => ''
],
[
'name' => 'MEMBER_BALANCE',
'title' => get_lang('dict_diy.member_my_balance'),
'url' => '/app/pages/member/balance',
'is_share' => 0,
'action' => ''
],
[
'name' => 'MEMBER_POINT',
'title' => get_lang('dict_diy.member_my_point'),
'url' => '/app/pages/member/point',
'is_share' => 0,
'action' => ''
],
[
'name' => 'MEMBER_COMMISSION',
'title' => get_lang('dict_diy.member_my_commission'),
'url' => '/app/pages/member/commission',
'is_share' => 0,
'action' => ''
],
[
'name' => 'MEMBER_ADDRESS',
'title' => get_lang('dict_diy.member_my_address'),
'url' => '/app/pages/member/address',
'is_share' => 0,
'action' => ''
],
[
'name' => 'MEMBER_MY_LEVEL',
'title' => get_lang('dict_diy.member_my_level'),
'url' => '/app/pages/member/level',
'is_share' => 0,
'action' => ''
],
[
'name' => 'MEMBER_MY_SIGN_IN',
'title' => get_lang('dict_diy.member_my_sign_in'),
'url' => '/app/pages/member/sign_in',
'is_share' => 0,
'action' => ''
],
[
'name' => 'MEMBER_VERIFY_INDEX',
'title' => get_lang('dict_diy.member_verify_index'),
'url' => '/app/pages/verify/index',
'is_share' => 0,
'action' => ''
],
[
'name' => 'MEMBER_CONTACT',
'title' => get_lang('dict_diy.member_contact'),
'url' => '/app/pages/member/contact',
'is_share' => 0,
'action' => ''
],
]
],
'DIY_PAGE' => [
'title' => get_lang('dict_diy.diy_page'),
'addon_info' => [
'title' => '系统',
'key' => 'app'
],
'child_list' => []
],
'DIY_LINK' => [
'title' => get_lang('dict_diy.diy_link'),
'addon_info' => [
'title' => '系统',
'key' => 'app'
],
'child_list' => []
],
'DIY_JUMP_OTHER_APPLET' => [
'title' => get_lang('dict_diy.diy_jump_other_applet'),
'addon_info' => [
'title' => '系统',
'key' => 'app'
],
'child_list' => []
],
'DIY_MAKE_PHONE_CALL' => [
'title' => get_lang('dict_diy.diy_make_phone_call'),
'addon_info' => [
'title' => '系统',
'key' => 'app'
],
'child_list' => []
]
];
// 查询存在页面路由的应用插件列表
if (!empty($params[ 'query' ]) && $params[ 'query' ] == 'addon') {
$system = [
@ -170,8 +40,139 @@ class LinkDict
$app = array_merge($system, $addons);
return $app;
} else {
$system_info = [
'title' => '系统',
'key' => 'app'
];
$system_links = [
'SYSTEM_BASE_LINK' => [
'title' => '系统页面',
'addon_info' => $system_info,
'type' => 'folder', // 类型folder 表示文件夹link 表示链接
'child_list' => [
[
'name' => 'SYSTEM_LINK',
'title' => get_lang('dict_diy.system_link'),
'child_list' => [
[
'name' => 'INDEX',
'title' => get_lang('dict_diy.system_link_index'),
'url' => '/app/pages/index/index',
'is_share' => 1,
'action' => 'decorate' // 默认空decorate 表示支持装修
],
]
],
[
'name' => 'MEMBER_LINK',
'title' => get_lang('dict_diy.member_link'),
'child_list' => [
[
'name' => 'MEMBER_CENTER',
'title' => get_lang('dict_diy.member_index'),
'url' => '/app/pages/member/index',
'is_share' => 1,
'action' => 'decorate'
],
[
'name' => 'MEMBER_PERSONAL',
'title' => get_lang('dict_diy.member_my_personal'),
'url' => '/app/pages/member/personal',
'is_share' => 0,
'action' => ''
],
[
'name' => 'MEMBER_BALANCE',
'title' => get_lang('dict_diy.member_my_balance'),
'url' => '/app/pages/member/balance',
'is_share' => 0,
'action' => ''
],
[
'name' => 'MEMBER_POINT',
'title' => get_lang('dict_diy.member_my_point'),
'url' => '/app/pages/member/point',
'is_share' => 0,
'action' => ''
],
[
'name' => 'MEMBER_COMMISSION',
'title' => get_lang('dict_diy.member_my_commission'),
'url' => '/app/pages/member/commission',
'is_share' => 0,
'action' => ''
],
[
'name' => 'MEMBER_ADDRESS',
'title' => get_lang('dict_diy.member_my_address'),
'url' => '/app/pages/member/address',
'is_share' => 0,
'action' => ''
],
[
'name' => 'MEMBER_MY_LEVEL',
'title' => get_lang('dict_diy.member_my_level'),
'url' => '/app/pages/member/level',
'is_share' => 0,
'action' => ''
],
[
'name' => 'MEMBER_MY_SIGN_IN',
'title' => get_lang('dict_diy.member_my_sign_in'),
'url' => '/app/pages/member/sign_in',
'is_share' => 0,
'action' => ''
],
[
'name' => 'MEMBER_VERIFY_INDEX',
'title' => get_lang('dict_diy.member_verify_index'),
'url' => '/app/pages/verify/index',
'is_share' => 0,
'action' => ''
],
[
'name' => 'MEMBER_CONTACT',
'title' => get_lang('dict_diy.member_contact'),
'url' => '/app/pages/member/contact',
'is_share' => 0,
'action' => ''
],
]
],
[
'name' => 'DIY_FORM_SELECT',
'title' => get_lang('dict_diy.diy_form_select'),
'component' => '/src/app/views/diy_form/components/form-select-content.vue'
],
]
],
'DIY_PAGE' => [
'title' => get_lang('dict_diy.diy_page'),
'addon_info' => $system_info,
'child_list' => []
],
'OTHER_LINK' => [
'title' => '其他页面',
'addon_info' => $system_info,
'type' => 'folder', // 类型folder 表示文件夹link 表示链接
'child_list' => [
[
'name' => 'DIY_LINK',
'title' => get_lang('dict_diy.diy_link'),
],
[
'name' => 'DIY_JUMP_OTHER_APPLET',
'title' => get_lang('dict_diy.diy_jump_other_applet'),
],
[
'name' => 'DIY_MAKE_PHONE_CALL',
'title' => get_lang('dict_diy.diy_make_phone_call'),
]
]
],
];
return ( new DictLoader("UniappLink") )->load([ 'data' => $system_links, 'params' => $params ]);
}
}
}
}

View File

@ -87,7 +87,21 @@ class PagesDict
foreach ($link_list as $ck => $cv) {
if ($cv[ 'addon_info' ][ 'key' ] == $v[ 'key' ]) {
foreach ($cv[ 'child_list' ] as $tk => $tv) {
if ($tv[ 'url' ] == $v[ 'url' ]) {
if (isset($cv[ 'type' ]) && $cv[ 'type' ] == 'folder') {
if (!empty($tv[ 'child_list' ])) {
foreach ($tv[ 'child_list' ] as $child_k => $child_v) {
if ($child_v[ 'url' ] == $v[ 'url' ]) {
$link = [
"parent" => $ck,
"name" => $child_v[ 'name' ],
"title" => $child_v[ 'title' ],
"url" => $child_v[ 'url' ]
];
break;
}
}
}
} else if ($tv[ 'url' ] == $v[ 'url' ]) {
$link = [
"parent" => $ck,
"name" => $tv[ 'name' ],

View File

@ -124,6 +124,7 @@ class ComponentDict
'autofill' => false, // 自动填充上次填写的内容 true开启false关闭
'privacyProtection' => false, // 隐私保护 true开启false关闭隐藏逻辑各组件自行处理
// 'detailComponent' => '/src/app/views/diy_form/components/detail-form-render.vue', // 用于详情展示,后台会返回默认,特殊组件可以重写组件
'cache' => true, // 开启本地数据缓存 true开启false关闭
'default' => '', // 默认值 存储数据类型不同,各组件自行处理
'value' => '', // 字段值 存储数据类型不同,各组件自行处理
],
@ -174,6 +175,7 @@ class ComponentDict
'unique' => false, // 内容不可重复提交 truefalse
'autofill' => false, // 自动填充上次填写的内容 true开启false关闭
'privacyProtection' => false, // 隐私保护 true开启false关闭隐藏逻辑各组件自行处理
'cache' => true, // 开启本地数据缓存 true开启false关闭
'default' => '', // 默认值 存储数据类型不同,各组件自行处理
'value' => '', // 字段值 存储数据类型不同,各组件自行处理
],
@ -225,6 +227,7 @@ class ComponentDict
'unique' => false, // 内容不可重复提交 truefalse
'autofill' => false, // 自动填充上次填写的内容 true开启false关闭
'privacyProtection' => false, // 隐私保护 true开启false关闭隐藏逻辑各组件自行处理
'cache' => true, // 开启本地数据缓存 true开启false关闭
'default' => '', // 默认值 存储数据类型不同,各组件自行处理
'value' => '', // 字段值 存储数据类型不同,各组件自行处理
],
@ -281,6 +284,7 @@ class ComponentDict
'unique' => false, // 内容不可重复提交 truefalse
'autofill' => false, // 自动填充上次填写的内容 true开启false关闭
'privacyProtection' => false, // 隐私保护 true开启false关闭隐藏逻辑各组件自行处理
'cache' => true, // 开启本地数据缓存 true开启false关闭
'default' => [], // 默认值 存储数据类型不同,各组件自行处理
'value' => [], // 字段值 存储数据类型不同,各组件自行处理
],
@ -369,6 +373,7 @@ class ComponentDict
'unique' => false, // 内容不可重复提交 truefalse
'autofill' => false, // 自动填充上次填写的内容 true开启false关闭
'privacyProtection' => false, // 隐私保护 true开启false关闭隐藏逻辑各组件自行处理
'cache' => true, // 开启本地数据缓存 true开启false关闭
'default' => [], // 默认值 存储数据类型不同,各组件自行处理
'value' => [], // 字段值 存储数据类型不同,各组件自行处理
],
@ -451,6 +456,7 @@ class ComponentDict
// 'unique' => false, // 内容不可重复提交 truefalse
// 'autofill' => false, // 自动填充上次填写的内容 true开启false关闭
// 'privacyProtection' => false, // 隐私保护 true开启false关闭隐藏逻辑各组件自行处理
// 'cache' => true, // 开启本地数据缓存 true开启false关闭
// 'default' => '', // 默认值 存储数据类型不同,各组件自行处理
// 'value' => '', // 字段值 存储数据类型不同,各组件自行处理
// ],
@ -500,6 +506,7 @@ class ComponentDict
'unique' => false, // 内容不可重复提交 truefalse
'autofill' => false, // 自动填充上次填写的内容 true开启false关闭
'privacyProtection' => false, // 隐私保护 true开启false关闭隐藏逻辑各组件自行处理
'cache' => true, // 开启本地数据缓存 true开启false关闭
'default' => '', // 默认值 存储数据类型不同,各组件自行处理
'value' => '', // 字段值 存储数据类型不同,各组件自行处理
],
@ -550,6 +557,7 @@ class ComponentDict
'unique' => false, // 内容不可重复提交 truefalse
'autofill' => false, // 自动填充上次填写的内容 true开启false关闭
'privacyProtection' => false, // 隐私保护 true开启false关闭隐藏逻辑各组件自行处理
'cache' => true, // 开启本地数据缓存 true开启false关闭
'default' => '', // 默认值 存储数据类型不同,各组件自行处理
'value' => '', // 字段值 存储数据类型不同,各组件自行处理
],
@ -600,6 +608,7 @@ class ComponentDict
'unique' => false, // 内容不可重复提交 truefalse
'autofill' => false, // 自动填充上次填写的内容 true开启false关闭
'privacyProtection' => false, // 隐私保护 true开启false关闭隐藏逻辑各组件自行处理
'cache' => true, // 开启本地数据缓存 true开启false关闭
'default' => '', // 默认值 存储数据类型不同,各组件自行处理
'value' => '', // 字段值 存储数据类型不同,各组件自行处理
],
@ -650,6 +659,7 @@ class ComponentDict
// 'unique' => false, // 内容不可重复提交 truefalse
// 'autofill' => false, // 自动填充上次填写的内容 true开启false关闭
// 'privacyProtection' => false, // 隐私保护 true开启false关闭隐藏逻辑各组件自行处理
// 'cache' => true, // 开启本地数据缓存 true开启false关闭
// 'detailComponent' => '/src/app/views/diy_form/components/detail-form-table.vue', // 用于详情展示
// 'default' => '', // 默认值 存储数据类型不同,各组件自行处理
// 'value' => '', // 字段值 存储数据类型不同,各组件自行处理
@ -717,6 +727,7 @@ class ComponentDict
'unique' => false, // 内容不可重复提交 truefalse
'autofill' => false, // 自动填充上次填写的内容 true开启false关闭
'privacyProtection' => false, // 隐私保护 true开启false关闭隐藏逻辑各组件自行处理
'cache' => false, // 开启本地数据缓存 true开启false关闭
'default' => [ // 默认值 存储数据类型不同,各组件自行处理
'date' => '', // 例2024-12-27
'timestamp' => 0, // 例1735290511
@ -788,6 +799,7 @@ class ComponentDict
'unique' => false, // 内容不可重复提交 truefalse
'autofill' => false, // 自动填充上次填写的内容 true开启false关闭
'privacyProtection' => false, // 隐私保护 true开启false关闭隐藏逻辑各组件自行处理
'cache' => false, // 开启本地数据缓存 true开启false关闭
// 默认值 存储数据类型不同,各组件自行处理
'default' => [
// todo 在做的过程中可能会再调整字段名称
@ -882,6 +894,7 @@ class ComponentDict
'unique' => false, // 内容不可重复提交 truefalse
'autofill' => false, // 自动填充上次填写的内容 true开启false关闭
'privacyProtection' => false, // 隐私保护 true开启false关闭隐藏逻辑各组件自行处理
'cache' => false, // 开启本地数据缓存 true开启false关闭
'default' => '', // 默认值 存储数据类型不同,各组件自行处理
'value' => '', // 字段值 存储数据类型不同,各组件自行处理
],
@ -933,6 +946,7 @@ class ComponentDict
'unique' => false, // 内容不可重复提交 truefalse
'autofill' => false, // 自动填充上次填写的内容 true开启false关闭
'privacyProtection' => false, // 隐私保护 true开启false关闭隐藏逻辑各组件自行处理
'cache' => false, // 开启本地数据缓存 true开启false关闭
// 默认值 存储数据类型不同,各组件自行处理
'default' => [
'start' => [
@ -1025,6 +1039,7 @@ class ComponentDict
// 'unique' => false, // 内容不可重复提交 truefalse
// 'autofill' => false, // 自动填充上次填写的内容 true开启false关闭
// 'privacyProtection' => false, // 隐私保护 true开启false关闭隐藏逻辑各组件自行处理
// 'cache' => true, // 开启本地数据缓存 true开启false关闭
// 'default' => '', // 默认值 存储数据类型不同,各组件自行处理
// 'value' => '', // 字段值 存储数据类型不同,各组件自行处理
// ],
@ -1127,6 +1142,7 @@ class ComponentDict
'unique' => false, // 内容不可重复提交 truefalse
'autofill' => false, // 自动填充上次填写的内容 true开启false关闭
'privacyProtection' => false, // 隐私保护 true开启false关闭隐藏逻辑各组件自行处理
'cache' => true, // 开启本地数据缓存 true开启false关闭
'detailComponent' => '/src/app/views/diy_form/components/detail-form-image.vue', // 用于详情展示
'default' => '', // 默认值 存储数据类型不同,各组件自行处理
'value' => [], // 字段值 存储数据类型不同,各组件自行处理
@ -1207,6 +1223,7 @@ class ComponentDict
// 'unique' => false, // 内容不可重复提交 truefalse
// 'autofill' => false, // 自动填充上次填写的内容 true开启false关闭
// 'privacyProtection' => false, // 隐私保护 true开启false关闭隐藏逻辑各组件自行处理
// 'cache' => true, // 开启本地数据缓存 true开启false关闭
// 'detailComponent' => '/src/app/views/diy_form/components/detail-form-video.vue', // 用于详情展示
// 'default' => '', // 默认值 存储数据类型不同,各组件自行处理
// 'value' => '', // 字段值 存储数据类型不同,各组件自行处理
@ -1263,6 +1280,7 @@ class ComponentDict
// 'unique' => false, // 内容不可重复提交 truefalse
// 'autofill' => false, // 自动填充上次填写的内容 true开启false关闭
// 'privacyProtection' => false, // 隐私保护 true开启false关闭隐藏逻辑各组件自行处理
// 'cache' => true, // 开启本地数据缓存 true开启false关闭
// 'detailComponent' => '/src/app/views/diy_form/components/detail-form-file.vue', // 用于详情展示
// 'default' => '', // 默认值 存储数据类型不同,各组件自行处理
// 'value' => '', // 字段值 存储数据类型不同,各组件自行处理

View File

@ -1,6 +1,6 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// | Niucloud-admin 企业快速开发的saas管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
@ -181,6 +181,7 @@ class TemplateDict
"unique" => false,
"autofill" => false,
"privacyProtection" => false,
'cache' => true,
"default" => "",
"value" => ""
],
@ -230,6 +231,7 @@ class TemplateDict
"unique" => true,
"autofill" => false,
"privacyProtection" => true,
'cache' => true,
"default" => "",
"value" => ""
],
@ -279,6 +281,7 @@ class TemplateDict
"unique" => true,
"autofill" => false,
"privacyProtection" => false,
'cache' => true,
"default" => "",
"value" => ""
],
@ -328,6 +331,7 @@ class TemplateDict
"unique" => false,
"autofill" => false,
"privacyProtection" => false,
'cache' => true,
"default" => "",
"value" => ""
],
@ -377,13 +381,14 @@ class TemplateDict
"unique" => false,
"autofill" => false,
"privacyProtection" => false,
'cache' => false,
"default" => [
"date" => "2025-01-11",
"timestamp" => 1736564405.243
"date" => "",
"timestamp" => 0
],
"value" => [
"date" => "2025-01-11 11=>02",
"timestamp" => 1736564520
"date" => "",
"timestamp" => 0
]
],
"placeholder" => "请选择日期",
@ -435,6 +440,7 @@ class TemplateDict
"unique" => false,
"autofill" => false,
"privacyProtection" => false,
'cache' => true,
"default" => [],
"value" => []
],
@ -518,6 +524,7 @@ class TemplateDict
"unique" => false,
"autofill" => false,
"privacyProtection" => false,
'cache' => true,
"default" => "",
"value" => ""
],
@ -569,24 +576,25 @@ class TemplateDict
"unique" => false,
"autofill" => false,
"privacyProtection" => false,
'cache' => false,
"default" => [
"start" => [
"date" => "2025-01-11",
"timestamp" => 1736585705
"date" => "",
"timestamp" => 0
],
"end" => [
"date" => "2025-01-18",
"timestamp" => 1737190505
"date" => "",
"timestamp" => 0
]
],
"value" => [
"start" => [
"date" => "2025/01/11",
"timestamp" => 1736524800
"date" => "",
"timestamp" => 0
],
"end" => [
"date" => "2025/01/11",
"timestamp" => 1736524800
"date" => "",
"timestamp" => 0
]
]
],
@ -595,12 +603,12 @@ class TemplateDict
"dateFormat" => "YYYY/MM/DD",
"start" => [
"placeholder" => "请选择起始日期",
"dateWay" => "diy",
"dateWay" => "current",
"defaultControl" => true
],
"end" => [
"placeholder" => "请选择结束日期",
"dateWay" => "diy",
"dateWay" => "current",
"defaultControl" => true
],
"textColor" => "#303133",

View File

@ -869,6 +869,20 @@ return [
'status' => '1',
'is_show' => '1',
],
[
'menu_name' => '编辑站点用户',
'menu_key' => 'edit_user',
'menu_short_name' => '',
'menu_type' => '2',
'icon' => '',
'api_url' => 'user/user/<uid>',
'router_path' => '',
'view_path' => '',
'methods' => 'put',
'sort' => '100',
'status' => '1',
'is_show' => '1',
],
[
'menu_name' => '删除站点用户',
'menu_key' => 'delete_user',
@ -883,6 +897,20 @@ return [
'status' => '1',
'is_show' => '1',
],
[
'menu_name' => '获取站点用户信息',
'menu_key' => 'get_user_info',
'menu_short_name' => '',
'menu_type' => '2',
'icon' => '',
'api_url' => 'user/user/<uid>',
'router_path' => '',
'view_path' => '',
'methods' => 'get',
'sort' => '100',
'status' => '1',
'is_show' => '0',
],
[
'menu_name' => '获取用户套餐权限',
'menu_key' => 'get_user_create_site_limit',
@ -1635,6 +1663,20 @@ return [
]
]
],
[
'menu_name' => '更新缓存',
'menu_key' => 'update_cache',
'menu_short_name' => '更新缓存',
'menu_type' => '1',
'icon' => 'nc-iconfont nc-icon-qingliV6xx',
'api_url' => 'sys/schema/clear',
'router_path' => 'tools/update_cache',
'view_path' => 'tools/updatecache',
'methods' => 'post',
'sort' => '100',
'status' => '1',
'is_show' => '1',
]
],
],

View File

@ -2022,6 +2022,20 @@ return [
],
],
],
[
'menu_name' => '转账场景',
'menu_key' => 'transfer_scene_config',
'menu_short_name' => '转账场景',
'menu_type' => '1',
'icon' => 'element Postcard',
'api_url' => '',
'router_path' => 'setting/transfer_scene',
'view_path' => 'setting/transfer_scene',
'methods' => 'get',
'sort' => '59',
'status' => '1',
'is_show' => '1',
],
],
],

View File

@ -20,5 +20,18 @@ return [
'variable' => [
'code' => '验证码'
],
]
],
//提示用户收款
// 'member_transfer' => [
// 'key' => 'member_transfer',
// 'receiver_type' => 1,
// 'name' => '提示用户收款',
// 'title' => '后台通过提现申请后,提示用户收款',
// 'async' => false,
// 'variable' => [
// 'transfer_no' => '转账单号',
//
// ],
// ]
];

View File

@ -9,6 +9,10 @@ return [
],
'recharge_success' => [
'content' => '您充值金额¥{price}, 充值后金额¥{balance}',
]
],
// 'member_transfer' => [
// 'content' => '你的编号为{transfer_no}的提现申请已通过,您现在可以在提现中点击提现收款了',
// ]
];

View File

@ -29,7 +29,13 @@ class TransferDict
public const SUCCESS = 'success';//转账成功
public const DEALING = 'dealing';//处理中
public const WAIT = 'wait';//待转账
public const WAIT_USER = 'wait_user';//等待用户确认
public const WAIT_USER_ING = 'wait_user_ing';//用户确认.转账中
public const FAIL_ING = 'fail_ing';//转账撤销中
public const FAIL = 'fail';//失败
@ -57,6 +63,11 @@ class TransferDict
'key' => self::WECHAT,
'is_online' => true
],//微信
self::WECHAT_CODE => [
'name' => get_lang('dict_transfer.type_wechat_code'),
'key' => self::WECHAT_CODE,
'is_online' => false
],//微信收款码(线下转账)
self::ALIPAY => [
'name' => get_lang('dict_transfer.type_ali'),
'key' => self::ALIPAY,
@ -67,11 +78,6 @@ class TransferDict
'key' => self::BANK,
'is_online' => false
],//银行卡
self::WECHAT_CODE => [
'name' => get_lang('dict_transfer.type_wechat_code'),
'key' => self::WECHAT_CODE,
'is_online' => false
],//微信收款码(线下转账)
];
if ($is_all) {
$list[self::OFFLINE] = [
@ -96,12 +102,121 @@ class TransferDict
*/
public static function getStatus()
{
return [
self::WAIT => get_lang('dict_transfer.status_wait'),
self::DEALING => get_lang('dict_transfer.status_dealing'),
self::WAIT_USER => get_lang('dict_transfer.status_wait_user'),
self::WAIT_USER_ING => get_lang('dict_transfer.wait_user_ing'),
self::SUCCESS => get_lang('dict_transfer.status_success'),
self::FAIL => get_lang('dict_transfer.status_fail'),
self::FAIL_ING => get_lang('dict_transfer.status_fail_ing'),
];
}
public const XJYX = 'xjyx';
public const QYPF = 'qypf';
public const YJBC = 'yjbc';
public const CGHK = 'cghk';
public const ESHS = 'eshs';
public const GYBZ = 'gybz';
public const XZBT = 'xzbt';
public const BXLP = 'bxlp';
/**
* 获取微信转账场景
* @return void
*/
public static function getWechatTransferScene(){
return [
self::YJBC => [
'name' => '佣金报酬',
'user_recv_perception' => [
'劳务报酬',
'报销款',
'企业补贴',
'开工利是'
],
'transfer_scene_report_infos' => [
'岗位类型',
'报酬说明'
]
],
self::XJYX => [
'name' => '现金营销',
'user_recv_perception' => [
'活动奖励',
'现金奖励',
],
'transfer_scene_report_infos' => [
'活动名称',
'奖励说明'
]
],
self::QYPF => [
'name' => '企业赔付',
'user_recv_perception' => [
'退款',
'商家赔付',
],
'transfer_scene_report_infos' => [
'赔付原因',
]
],
self::CGHK => [
'name' => '采购货款',
'user_recv_perception' => [
'货款',
],
'transfer_scene_report_infos' => [
'采购商品名称',
]
],
self::ESHS => [
'name' => '二手回收',
'user_recv_perception' => [
'二手回收货款',
],
'transfer_scene_report_infos' => [
'回收商品名称',
]
],
self::GYBZ => [
'name' => '公益补助',
'user_recv_perception' => [
'公益补助金',
],
'transfer_scene_report_infos' => [
'公益活动名称',
'公益活动备案编号'
]
],
self::XZBT => [
'name' => '行政补贴',
'user_recv_perception' => [
'行政补贴',
'行政奖励'
],
'transfer_scene_report_infos' => [
'补贴类型',
]
],
self::BXLP => [
'name' => '保险理赔',
'user_recv_perception' => [
'保险理赔款',
],
'transfer_scene_report_infos' => [
'保险产品备案编号',
'保险名称',
'保险操作单号'
]
],
];
}
}

View File

@ -22,6 +22,8 @@ class CloudDict
const APPLET_AUDITING = 2;
const APPLET_PUBLISHED = 3;
const APPLET_UPLOAD_FAIL = -1;
const APPLET_AUDIT_FAIL = -2;
@ -33,6 +35,7 @@ class CloudDict
self::APPLET_UPLOAD_FAIL => get_lang('dict_cloud_applet.upload_fail'),
self::APPLET_AUDITING => get_lang('dict_cloud_applet.auditing'),
self::APPLET_AUDIT_FAIL => get_lang('dict_cloud_applet.audit_fail'),
self::APPLET_PUBLISHED => get_lang('dict_cloud_applet.published'),
];
return $status_list[$status] ?? '';
}

View File

@ -35,4 +35,6 @@ class ConfigKeyDict
public const WEAPP_AUTHORIZATION_INFO = 'weapp_authorization_info';
public const WECHAT_AUTHORIZATION_INFO = 'wechat_authorization_info';
public const WECHAT_TRANSFER_SCENE_CONFIG = 'WECHAT_TRANSFER_SCENE_CONFIG';//微信转账场景配置
}

View File

@ -97,7 +97,7 @@ $system_event = [
//表单填表人统计导出
'app\listener\diy_form_export\DiyFormRecordsMemberExportTypeListener',
//表单字段统计导出
// 'app\listener\diy_form_export\DiyFormRecordsFieldsExportTypeListener',
'app\listener\diy_form_export\DiyFormRecordsFieldsExportTypeListener',
],
//导出数据源
'ExportData' => [
@ -108,7 +108,7 @@ $system_event = [
//表单填表人统计导出
'app\listener\diy_form_export\DiyFormRecordsMemberExportDataListener',
//表单字段统计导出
// 'app\listener\diy_form_export\DiyFormRecordsFieldsExportDataListener',
'app\listener\diy_form_export\DiyFormRecordsFieldsExportDataListener',
],
//统计执行
'StatExecute' => [],
@ -123,7 +123,13 @@ $system_event = [
'WeappAuthChangeAfter' => [ 'app\listener\system\WeappAuthChangeAfter' ],
'ShowApp' => [
'app\listener\system\ShowAppListener'
]
],
//获取微信转账场景配置
'GetWechatTransferTradeScene' => [
'app\listener\transfer\TransferCashOutListener'
],
//主题色
'ThemeColor' => [ 'app\listener\diy\ThemeColorListener' ],
],
'subscribe' => [
],

View File

@ -227,13 +227,14 @@ CREATE TABLE `diy_theme` (
`title` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '标题',
`type` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '插件类型appaddon',
`addon` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '所属应用app系统shop商城、o2o上门服务',
`color_mark` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '颜色标识',
`color_name` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '颜色名称',
`mode` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '模式default默认【跟随系统】diy自定义配色',
`value` TEXT DEFAULT NULL COMMENT '配色',
`diy_value` TEXT DEFAULT NULL COMMENT '自定义配色',
`create_time` INT(11) NOT NULL DEFAULT 0 COMMENT '创建时间',
`update_time` INT(11) NOT NULL DEFAULT 0 COMMENT '更新时间',
`theme_type` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '配色类型default默认diy自定义',
`default_theme` text DEFAULT NULL COMMENT '当前色调的默认值',
`theme` text DEFAULT NULL COMMENT '当前色调',
`new_theme` text DEFAULT NULL COMMENT '新增颜色集合',
`is_selected` tinyint NOT NULL DEFAULT 0 COMMENT '已选色调01.是',
`create_time` int NOT NULL DEFAULT 0 COMMENT '创建时间',
`update_time` int NOT NULL DEFAULT 0 COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='自定义主题配色表';
@ -597,10 +598,24 @@ CREATE TABLE `pay_transfer` (
`batch_id` varchar(500) NOT NULL DEFAULT '' COMMENT '转账批次id',
`transfer_payee` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '在线转账数据(json)',
`out_batch_no` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '扩展数据,主要用于记录接收到线上打款的业务数据编号',
`package_info` VARCHAR(1000) NOT NULL DEFAULT '' COMMENT '跳转领取页面的package信息',
`extra` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '扩展信息',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '转账表' ROW_FORMAT = Dynamic;
DROP TABLE IF EXISTS `pay_transfer_scene`;
CREATE TABLE `pay_transfer_scene` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
`site_id` INT(11) NOT NULL DEFAULT 0 COMMENT '站点id',
`type` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '业务类型',
`scene` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '场景',
`infos` VARCHAR(2000) NOT NULL DEFAULT '' COMMENT '转账报备背景',
`create_time` INT(11) NOT NULL DEFAULT 0 COMMENT '创建时间',
`perception` VARCHAR(500) NOT NULL DEFAULT '' COMMENT '转账收款感知',
PRIMARY KEY (`id`)
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '支付转账场景表' ROW_FORMAT = Dynamic;
DROP TABLE IF EXISTS `site`;
CREATE TABLE `site` (
`site_id` int(11) NOT NULL AUTO_INCREMENT,

View File

@ -58,6 +58,7 @@ return [
'ADDON_IS_INSTALLED_NOT_ALLOW_DEL' => '已安装的插件不允许删除',
'ADDON_ZIP_ERROR' => '插件压缩失败',
'PHP_SCRIPT_RUNNING_OUT_OF_MEMORY' => 'PHP脚本运行内存不足, 具体操作方法<a style="text-decoration: underline;" href="https://www.kancloud.cn/niushop/niushop_v6/3248604" target="blank">点击查看相关手册</a>',
'BEFORE_UPGRADING_NEED_UPGRADE_FRAMEWORK' => '升级插件前需要先升级框架',
//登录注册重置账号....
'LOGIN_SUCCESS' => '登录成功',
@ -177,15 +178,23 @@ return [
'MEMBER_APPLY_CASHOUT' => '会员申请提现,扣除零钱',
'CASHOUT_MONEY_TOO_LITTLE' => '会员提现金额不能小于最低提现金额',
'CASHOUT_STATUS_NOT_IN_WAIT_TRANSFER' => '当前提现申请未处于待转账状态',
'CASHOUT_STATUS_NOT_IN_CANCEL' => '只有进行中的提现才可以取消',
'CASHOUT_STATUS_NOT_IN_WAIT_AUDIT' => '当前提现申请未处于待审核状态',
'MEMBER_CASHOUT_TRANSFER' => '会员提现转账',
'CASH_OUT_ACCOUNT_NOT_EXIST' => '提现账户不存在',
'CASH_OUT_WECHAT_ACCOUNT_NOT_ALLOW_ADMIN' => '在转账到微信零钱的提现场景下,提现操作应该由用户在客户端发起',
'CASH_OUT_ACCOUNT_NOT_FOUND_VALUE' => '转账到微信零钱缺少参数',
//DIY
'PAGE_NOT_EXIST' => '页面不存在',
'APP_COLOR_NOT_EXIST' => '系统配色不存在',
'DIY_THEME_COLOR_NOT_EXIST' => '主题配色不存在',
'DIY_THEME_DEFAULT_COLOR_CAN_NOT_DELETE' => '系统默认配色不能删除',
'DIY_THEME_SELECTED_CAN_NOT_DELETE' => '主题配色已选中不能删除',
//海报
'POSTER_NOT_EXIST' => '海报不存在',
'POSTER_IN_USE_NOT_ALLOW_MODIFY' => '海报使用中禁止修改状态',
//万能表单
'DIY_FORM_NOT_EXIST' => '表单不存在',
@ -230,6 +239,7 @@ return [
'TREAT_PAYMENT_IS_OPEN' => '只有待支付时可以关闭',
'TRANFER_STATUS_NOT_IN_WAIT_TANSFER' => '当前转账未处于待转账状态',
'TRANSFER_ORDER_INVALID' => '无效的转账单据',
'TRANSFER_IS_FAILING' => '单据正在撤销中,请等待片刻或稍后再试',
'TRANFER_CONFIG_ERROR' => '参数有误或未开通转账业务',
'IS_PAY_REMOVE_NOT_RESETTING' => '已支付和已取消的单据不可以重置',
'DOCUMENT_IS_PAY_REMOVE' => '当前单据已支付或已取消',
@ -243,6 +253,8 @@ return [
'ONLY_OFFLINEPAY_CAN_AUDIT' => '只有线下支付的单据才可以审核',
'TRADE_NOT_EXIST' => '支付单据不存在',
'PAY_NOT_FOUND_TRADE' => '找不到可支付的交易',
'MERCHANT_TRANSFER_SCENARIOS_THAT_DO_NOT_EXIST' => '不存在的商户转账场景',
//退款相关
'REFUND_NOT_EXIST' => '退款单据不存在',
//订单相关 8***
@ -265,6 +277,7 @@ return [
// 缓存相关
'CLEAR_MYSQL_CACHE_SUCCESS' => '数据表缓存清除成功',
'CACHE_CLEAR_SUCCESS' => '缓存清除成功',
//任务队列相关
'JOB_NOT_EXISTS' => '任务类不存在',
@ -323,6 +336,7 @@ return [
'WEAPP_EXIST' => '该小程序已经授权给其他站点',
'WECHAT_EXIST' => '该公众号已经授权给其他站点',
'PLEASE_ADD_FIRST_SITE_GROUP' => '请先添加站点套餐',
'NOT_YET_PRESENT_TEMPLATE_LIBRARY' => '平台尚未上传小程序到模板库',
'PRINTER_NOT_EXIST' => '打印机不存在'
];

View File

@ -233,7 +233,7 @@ return [
'page_diy' => '微页面',
'component_type_basic' => '基础组件',
'system_title' => '系统',
'system_title' => '系统页面',
'system_link' => '启动页',
'system_link_index' => '首页',
@ -252,7 +252,9 @@ return [
'diy_page' => '自定义页面',
'diy_link' => '自定义链接',
'diy_jump_other_applet' => '小程序跳转',
'diy_make_phone_call' => '拨打电话'
'diy_make_phone_call' => '拨打电话',
'diy_form_select' => '万能表单'
],
// 自定义海报
'dict_diy_poster' => [
@ -380,7 +382,8 @@ return [
'upload_fail' => '上传失败',
'auditing' => '审核中',
'audit_success' => '审核通过',
'audit_fail' => '审核失败'
'audit_fail' => '审核失败',
'published' => '已发布'
],
'dict_wechat_media' => [
'type_image' => '图片',

View File

@ -165,6 +165,8 @@ return [
// 自定义
'validate_diy' => [
'type_not_exist' => '不存在的页面模板',
'theme_title_unique' => '色调名称必须是唯一的',
'page_title_unique' => '表单名称必须是唯一的',
],
// 会员提现账号
'validate_member_cash_out_account' => [

View File

@ -0,0 +1,90 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的saas管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\listener\diy;
/**
* 主题色
* Class ThemeColorListener
* @package addon\shop\app\listener\diy
*/
class ThemeColorListener
{
public function handle($params)
{
if (!empty($params[ 'key' ]) && $params[ 'key' ] == 'app') {
return [
// 系统主题色
'theme_color' => [
[
'title' => '商务蓝',
'name' => 'blue',
'theme' => [
'--page-bg-color' => "#F6F6F6",//页面背景色
'--primary-color' => "#007aff",//主色调
'--primary-color-light' => "#ecf5ff",//主色调浅色(淡)
'--primary-color-light2' => "#FFF4ED",//主色调深色(深)
'--primary-help-color2' => "#007aff",//辅色调
'--primary-color-dark' => "#999999",//灰色调
'--primary-color-disabled' => "#CCCCCC",//禁用色
]
]
],
// 主题颜色字段前端展示用字段中的value值颜色为添加自定义颜色的默认值默认黑色风格
'theme_field' => [
[
'title' => '页面背景色',
'label' => "--page-bg-color",
'value' => "#F6F6F6",
'tip' => "页面背景色在uniapp中使用var(--page-bg-color)",
],
[
'title' => '主色调',
'label' => "--primary-color",
'value' => "rgba(51, 51, 51, 1)",
'tip' => "主色调在uniapp中使用var(--primary-color)",
],
[
'title' => '主色调浅色(淡)',
'label' => "--primary-color-light",
'value' => "rgba(51, 51, 51, 0.1)",
'tip' => "主色调浅色在uniapp中使用var(--primary-color-light)",
],
[
'title' => '主色调深色(深)',
'label' => "--primary-color-light2",
'value' => "rgba(51, 51, 51, 0.8)",
'tip' => "主色调深色在uniapp中使用var(--primary-color-light2)",
],
[
'title' => '辅色调',
'label' => "--primary-help-color2",
'value' => "rgba(51, 51, 51, 1)",
'tip' => "辅色调在uniapp中使用var(--primary-help-color2)",
],
[
'title' => '灰色调',
'label' => "--primary-color-dark",
'value' => "#999999",
'tip' => "灰色调在uniapp中使用var(--primary-color-dark)",
],
[
'title' => '禁用色',
'label' => "--primary-color-disabled",
'value' => "#CCCCCC",
'tip' => "禁用色在uniapp中使用var(--primary-color-disabled)",
],
]
];
}
}
}

View File

@ -0,0 +1,121 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的saas管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\listener\diy_form_export;
use app\model\diy_form\DiyFormRecords;
use app\model\diy_form\DiyFormRecordsFields;
use app\service\admin\diy_form\DiyFormService;
/**
* 表单填表人统计导出数据源查询
* Class DiyFormRecordsMemberExportDataListener
* @package app\listener\diy_form_export
*/
class DiyFormRecordsFieldsExportDataListener
{
public function handle($param)
{
$data = [];
if ($param['type'] == 'diy_form_records_fields') {
$site_id = $param[ 'site_id' ];
$where = $param[ 'where' ];
$field_list = ( new DiyFormService() )->getFieldsList($where, 'field_id, field_key, field_type, field_name');
$simple_field_list = array_filter($field_list, function($v) { return !in_array($v[ 'field_type' ], [ 'FormRadio', 'FormCheckbox', 'FormDateScope', 'FormTimeScope', 'FormImage' ]); });
$json_field_list = array_filter($field_list, function($v) { return in_array($v[ 'field_type' ], [ 'FormRadio', 'FormCheckbox', 'FormDateScope', 'FormTimeScope' ]); });
$records_field_model = new DiyFormRecordsFields();
foreach ($simple_field_list as $k => &$v) {
$value_list = $records_field_model->field('form_id, field_key, field_type, field_name, field_value, count(*) as write_count')->where([
[ 'site_id', '=', $site_id ],
[ 'field_key', '=', $v[ 'field_key' ] ],
[ 'field_type', '=', $v[ 'field_type' ] ]
])->withSearch([ 'form_id' ], $where)->group('field_value')->append([ 'render_value' ])->select()->toArray();
$total_count = $records_field_model->where([
[ 'site_id', '=', $site_id ],
[ 'field_key', '=', $v[ 'field_key' ] ],
[ 'field_type', '=', $v[ 'field_type' ] ]
])->withSearch([ 'form_id' ], $where)->count();
if ($total_count > 0) {
$total_percent = 100;
foreach ($value_list as $k1 => &$v1) {
if ($k1 == count($value_list) - 1) {
$item_percent = $total_percent;
} else {
$item_percent = round($v1[ 'write_count' ] / $total_count * 100, 2);
}
$v1[ 'write_percent' ] = floatval($item_percent);
$total_percent = bcsub($total_percent, $item_percent, 2);
}
}
$data = array_merge($data, $value_list);
}
foreach ($json_field_list as $k => &$v) {
$field_list = $records_field_model->field('form_id, field_key, field_type, field_name, field_value')->where([
[ 'site_id', '=', $site_id ],
[ 'field_key', '=', $v[ 'field_key' ] ],
[ 'field_type', '=', $v[ 'field_type' ] ]
])->withSearch([ 'form_id' ], $where)->append([ 'render_value' ])->select()->toArray();
$total_count = 0;
$value_list = [];
foreach ($field_list as $k1 => &$v1) {
if ($v1[ 'field_type' ] != 'FormCheckbox') {
$key = $v1[ 'field_key' ] . '_' . $v1[ 'render_value' ];
if (isset($value_list[ $key ])) {
$value_list[ $key ][ 'write_count' ] = $value_list[ $key ][ 'write_count' ] + 1;
$total_count++;
} else {
// 如果不存在则初始化为1
$value_list[ $key ] = $v1;
$value_list[ $key ][ 'write_count' ] = 1;
$total_count++;
}
} else {
$value_arr = explode(',', $v1[ 'render_value' ]);
foreach ($value_arr as $k2 => $v2) {
$key = $v1[ 'field_key' ] . '_' . $v2;
if (isset($value_list[ $key ])) {
$value_list[ $key ][ 'write_count' ] = $value_list[ $key ][ 'write_count' ] + 1;
$total_count++;
} else {
$value_list[ $key ] = $v1;
$value_list[ $key ][ 'render_value' ] = $v2;
$value_list[ $key ][ 'write_count' ] = 1;
$total_count++;
}
}
}
}
if ($total_count > 0) {
$value_list = array_values($value_list);
$total_percent = 100;
foreach ($value_list as $k1 => &$v1) {
if ($k1 == count($value_list) - 1) {
$item_percent = $total_percent;
} else {
$item_percent = round($v1[ 'write_count' ] / $total_count * 100, 2);
}
$v1[ 'write_percent' ] = floatval($item_percent);
$total_percent = bcsub($total_percent, $item_percent, 2);
}
}
$data = array_merge($data, $value_list);
}
foreach ($data as $k => &$v) {
$v[ 'render_value' ] = $v[ 'render_value' ] . "\t";
}
$data = array_values($data);
}
return $data;
}
}

View File

@ -0,0 +1,36 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的saas管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\listener\diy_form_export;
/**
* 表单字段统计导出数据类型查询
* Class DiyFormRecordsFieldsExportTypeListener
* @package app\listener\diy_form_export
*/
class DiyFormRecordsFieldsExportTypeListener
{
public function handle($param)
{
return [
'diy_form_records_fields' => [
'name' => '表单字段统计列表',
'column' => [
'field_name' => [ 'name' => '字段', 'merge_type' => 'column' ],
'render_value' => [ 'name' => '选项值' ],
'write_count' => [ 'name' => '小计' ],
'write_percent' => [ 'name' => '比例' ],
]
]
];
}
}

View File

@ -26,7 +26,7 @@ class MemberExportDataListener
$data = [];
if ($param['type'] == 'member') {
$model = new Member();
$field = 'member_id, member_no, mobile, nickname, birthday, member_level, point, balance, money, growth, commission, register_channel, status, create_time, last_visit_time';
$field = 'member_id, member_no, mobile, nickname, sex, birthday, member_level, point, balance, money, growth, commission, register_channel, status, create_time, last_visit_time';
//查询导出数据
$search_model = $model->where([['site_id', '=', $param['site_id']]])->withSearch(['keyword','register_type', 'create_time', 'is_del', 'member_label', 'register_channel'], $param['where'])
->with(['memberLevelNameBind'])->field($field)->append(['register_channel_name', 'sex_name', 'status_name']);
@ -36,6 +36,7 @@ class MemberExportDataListener
$data = $search_model->select()->toArray();
}
foreach ($data as $key => $value) {
$data[$key]['member_no'] = $value['member_no']."\t";
$data[$key]['mobile'] = $value['mobile']."\t";
$data[$key]['create_time'] = !empty($value['create_time']) ? $value['create_time'] : '';
$data[$key]['last_visit_time'] = !empty($value['last_visit_time']) ? $value['last_visit_time'] : '';

View File

@ -25,6 +25,7 @@ class MemberExportTypeListener
'member' => [
'name' => '会员列表',
'column' => [
'member_no' => [ 'name' => '会员编号'],
'nickname' => [ 'name' => '会员昵称'],
'mobile' => [ 'name' => '手机号'],
'member_level_name' => [ 'name' => '会员等级'],

View File

@ -10,9 +10,9 @@
// +----------------------------------------------------------------------
namespace app\listener\system;
use app\model\sys\Poster;
use app\model\sys\SysAttachment;
use app\model\sys\SysAttachmentCategory;
use app\service\core\diy\CoreDiyService;
use app\service\core\poster\CorePosterService;
/**
@ -538,6 +538,8 @@ class AddSiteAfterListener
'is_default' => 1
]);
// 创建默认主题风格颜色
( new CoreDiyService() )->initDefaultDiyTheme($site_id);
return true;
}
}

View File

@ -0,0 +1,38 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的saas管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\listener\transfer;
use app\dict\pay\TransferDict;
use app\service\core\site\CoreSiteAccountService;
/**
* 微信支付转账场景监听器
*/
class TransferCashOutListener
{
public function handle($data = [])
{
//账单记录添加
// (new CoreSiteAccountService())->addPayLog($pay_info);
return [
'member_cash_out' => [
'name' => '佣金提现',
'scene' => TransferDict::YJBC,
'perception' => '劳务报酬',
'infos' => [
'岗位类型' => '业务顾问',
'报酬说明' => '佣金提现'
]
]
];
}
}

View File

@ -36,7 +36,7 @@ class DiyTheme extends BaseModel
protected $name = 'diy_theme';
// 设置json类型字段
protected $json = [ 'value', 'diy_value' ];
protected $json = [ 'default_theme', 'theme', 'new_theme' ];
// 设置JSON数据返回数组
protected $jsonAssoc = true;

View File

@ -73,7 +73,7 @@ class MemberCashOut extends BaseModel
public function transfer()
{
return $this->hasOne(Transfer::class, 'transfer_no', 'transfer_no')->joinType('left')
->withField('transfer_no, transfer_type, transfer_realname, transfer_mobile, transfer_bank, transfer_account, transfer_voucher, transfer_remark, transfer_fail_reason, transfer_status')->append(['transfer_status_name', 'transfer_type_name']);
->withField('transfer_no, transfer_type, transfer_realname, transfer_mobile, transfer_bank, transfer_account, transfer_voucher, transfer_remark, transfer_fail_reason, transfer_status, package_info, extra')->append(['transfer_status_name', 'transfer_type_name']);
}
/**

View File

@ -42,7 +42,7 @@ class Transfer extends BaseModel
];
// 设置json类型字段
protected $json = [ 'transfer_payee' ];
protected $json = [ 'transfer_payee', 'extra' ];
// 设置JSON数据返回数组
protected $jsonAssoc = true;

View File

@ -0,0 +1,49 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的saas管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\model\pay;
use app\dict\pay\TransferDict;
use core\base\BaseModel;
/**
* 微信转账场景模型
* Class Order
* @package app\model\order
*/
class TransferScene extends BaseModel
{
/**
* 数据表主键
* @var string
*/
protected $pk = 'id';
/**
* 模型名称
* @var string
*/
protected $name = 'pay_transfer_scene';
//类型
protected $type = [
];
// 设置json类型字段
protected $json = [ 'infos'];
// 设置JSON数据返回数组
protected $jsonAssoc = true;
}

View File

@ -47,10 +47,42 @@ class DiyRouteService extends BaseAdminService
foreach ($link as $k => $v) {
if (!empty($v[ 'child_list' ])) {
foreach ($v[ 'child_list' ] as $ck => $cv) {
if (!empty($cv[ 'url' ])) {
if (!empty($cv[ 'child_list' ])) {
foreach ($cv[ 'child_list' ] as $ck2 => $cv2) {
$is_add = true;
if (isset($where[ 'title' ]) && $where[ 'title' ] != '' && !str_contains($cv2[ 'title' ], $where[ 'title' ])) {
$is_add = false;
}
if (!empty($where[ 'url' ]) && $where[ 'url' ] != $cv2[ 'url' ]) {
$is_add = false;
}
if (!empty($v[ 'addon_info' ]) && !empty($where[ 'addon_name' ]) && $where[ 'addon_name' ] != $v[ 'addon_info' ][ 'key' ]) {
$is_add = false;
}
$item = [
'addon_info' => $v[ 'addon_info' ] ?? '',
'title' => $cv2[ 'title' ],
'name' => $cv2[ 'name' ],
'parent' => $k,
'page' => $cv2[ 'url' ],
'is_share' => $cv2[ 'is_share' ],
'action' => $cv2[ 'action' ] ?? '',
'sort' => ++$sort
];
if ($is_add) {
$diy_route_list[] = $item;
}
}
} else if (!empty($cv[ 'url' ])) {
$is_add = true;
if (isset($where[ 'title' ]) && $where[ 'title' ] !='' && !str_contains($cv[ 'title' ], $where[ 'title' ])) {
if (isset($where[ 'title' ]) && $where[ 'title' ] != '' && !str_contains($cv[ 'title' ], $where[ 'title' ])) {
$is_add = false;
}
@ -181,7 +213,6 @@ class DiyRouteService extends BaseAdminService
$link = LinkDict::getLink([
'query' => 'addon'
]);
return $link;
}

View File

@ -821,33 +821,25 @@ class DiyService extends BaseAdminService
public function getDiyTheme()
{
$site_addon = ( new CoreSiteService() )->getSiteCache($this->site_id);
$theme_data = ( new DiyTheme() )->where([['site_id', '=', $this->site_id], ['type', '=', 'app']])->column('id,color_mark,color_name,diy_value,value,title,mode','addon');
$defaultColor = ( new CoreDiyService() )->getDefaultColor();
$theme_data = ( new DiyTheme() )->where([['site_id', '=', $this->site_id], ['type', '=', 'app'], ['is_selected', '=', 1]])->column('id,title,theme','addon');
$system_theme = array_values(array_filter(event('ThemeColor', [ 'key' => 'app'])))[0] ?? [];
$app_theme['app'] = [
'id' => $theme_data['app']['id'] ?? '',
'icon' => '',
'addon_title' => '系统',
'mode' => 'diy',
'title' => $theme_data['app']['title'] ?? '系统主色调',
'color_mark' => $theme_data['app']['color_mark'] ?? $defaultColor['name'],
'color_name' => $theme_data['app']['color_name'] ?? $defaultColor['title'],
'value' => $theme_data['app']['value'] ?? $defaultColor['theme'],
'diy_value' => $theme_data['app']['diy_value'] ?? '',
'title' => $theme_data['app']['title'] ?? (!empty($system_theme) ? $system_theme['theme_color'][0]['title'] : ''),
'theme' => $theme_data['app']['theme'] ?? (!empty($system_theme) ? $system_theme['theme_color'][0]['theme'] : '')
];
$data = [];
foreach ($site_addon[ 'apps' ] as $value){
$default_theme_data = array_values(array_filter(event('ThemeColor', [ 'key' => $value['key']])))[0] ?? [];
$addon_theme = array_values(array_filter(event('ThemeColor', [ 'key' => $value['key']])))[0] ?? [];
$data[$value['key']]['id'] = $theme_data[$value['key']]['id'] ?? '';
$data[$value['key']]['icon'] = $value['icon'] ?? '';
$data[$value['key']]['mode'] = $theme_data[$value['key']]['mode'] ?? 'diy';
$data[$value['key']]['addon_title'] = $value['title'] ?? '';
$data[$value['key']]['title'] = $theme_data[$value['key']]['title'] ?? $value['title'].'主色调';
$data[$value['key']]['color_mark'] = $theme_data[$value['key']]['color_mark'] ?? ($default_theme_data ? $default_theme_data[ 'name' ] : $defaultColor['name']);
$data[$value['key']]['color_name'] = $theme_data[$value['key']]['color_name'] ?? ($default_theme_data ? $default_theme_data[ 'title' ] : $defaultColor['title']);
$data[$value['key']]['value'] = $theme_data[$value['key']]['value'] ?? ($default_theme_data ? $default_theme_data[ 'theme' ] : $defaultColor['theme']);
$data[$value['key']]['diy_value'] = $theme_data[$value['key']]['diy_value'] ?? '';
$data[$value['key']]['title'] = $theme_data[$value['key']]['title'] ?? (!empty($addon_theme) ? $addon_theme['theme_color'][0][ 'title' ] : '');
$data[$value['key']]['theme'] = $theme_data[$value['key']]['theme'] ?? (!empty($addon_theme) ? $addon_theme['theme_color'][0][ 'theme' ] : '');
}
if (count($site_addon[ 'apps' ]) > 1) {
if (count($site_addon[ 'apps' ]) > 1) {// 应用数量大于1时展示系统主题色设置只有一个应用时不展示系统主题色设置
$data = array_merge($app_theme,$data);
}
@ -861,9 +853,11 @@ class DiyService extends BaseAdminService
*/
public function setDiyTheme($data)
{
$diy_theme_model = new (new DiyTheme());
$addon_data = (new addon())->where([['support_app', '=', $data['key']]])->select()->toArray();
$diy_theme_model = new DiyTheme();
$diy_theme_count = $diy_theme_model->where([['id', '=', $data['id']], ['site_id', '=', $this->site_id]])->count();
if ($diy_theme_count == 0) throw new AdminException("DIY_THEME_COLOR_NOT_EXIST");
// 应用选择主题色is_selected发生变更时主应用下的插件也同步发生变更
$addon_data = (new addon())->field('key')->where([['support_app', '=', $data['addon']]])->select()->toArray();
$addon_save_data = [];
if (!empty($addon_data)){
foreach ($addon_data as $value){
@ -871,11 +865,10 @@ class DiyService extends BaseAdminService
'site_id' => $this->site_id,
'type' => 'addon',
'addon' => $value['key'],
'color_mark' => $data['color_mark'],
'color_name' => $data['color_name'],
'mode' => $data['mode'],
'value' => $data['value'],
'diy_value' => $data['diy_value'],
'title' => $data['title'],
'theme' => $data['theme'],
'new_theme' => $data['new_theme'],
'is_selected' => 1,
'update_time' => time(),
];
}
@ -884,25 +877,16 @@ class DiyService extends BaseAdminService
try {
Db::startTrans();
if(!empty($data['id'])){
$diy_theme_model->where([['addon', '=', $data['addon']], ['is_selected', '=', 1], ['site_id', '=', $this->site_id]])->update(['is_selected' => 0]);
$data['is_selected'] = 1;
$data['update_time'] = time();
unset($data['key']);
$diy_theme_model->where([['id', '=', $data['id']], ['site_id', '=', $this->site_id]])->update($data);
if (!empty($addon_save_data)){
foreach ($addon_save_data as $value){
$diy_theme_model->where([['addon', '=', $value['addon']], ['site_id', '=', $this->site_id]])->update($value);
$diy_theme_model->where([['addon', '=', $value['addon']], ['is_selected', '=', 1], ['site_id', '=', $this->site_id]])->update(['is_selected' => 0]);
$diy_theme_model->where([['addon', '=', $value['addon']], ['title', '=', $data['title']], ['site_id', '=', $this->site_id]])->update($value);
}
}
}else{
$data['site_id'] = $this->site_id;
$data['type'] = 'app';
$data['addon'] = $data['key'];
$data['crete_time'] = time();
unset($data['id'],$data['key']);
array_unshift($addon_save_data, $data);
foreach ($addon_save_data as $value){
unset($value['update_time']);
$diy_theme_model->create($value);
}
}
Db::commit();
return true;
@ -916,9 +900,137 @@ class DiyService extends BaseAdminService
* 获取默认主题配色
* @return array
*/
public function getDefaultThemeColor()
public function getDefaultThemeColor($data)
{
return ( new CoreDiyService() )->getDefaultThemeColor();
$theme_list = ( new DiyTheme() )->field('id,title,addon,default_theme,theme,new_theme,theme_type')->where([['site_id', '=', $this->site_id], ['addon', '=', $data['addon']]])->select()->toArray();
foreach ($theme_list as &$value) {
$addon_theme = array_values(array_filter(event('ThemeColor', [ 'key' => $value['addon'] ])))[0] ?? [];
if (!empty($addon_theme) && !empty($addon_theme['theme_field'])) {
$value['theme_field'] = $addon_theme['theme_field'];//返回各个应用的主题颜色字段
}
}
return $theme_list;
}
/**
* 添加自定义主题配色
* @param array $data
* @return bool
*/
public function addDiyTheme($data)
{
// 主应用添加自定义主题色时,主应用下的插件也同步添加自定义主题色
$addon_data = (new addon())->field('key')->where([['support_app', '=', $data['addon']]])->select()->toArray();
$addon_save_data = [];
if (!empty($addon_data)){
foreach ($addon_data as $value){
$addon_save_data[] = [
'site_id' => $this->site_id,
'type' => 'addon',
'addon' => $value['key'],
'title' => $data['title'],
'default_theme' => $data['default_theme'],
'theme' => $data['theme'],
'new_theme' => $data['new_theme'],
'theme_type' => 'diy',
'create_time' => time(),
];
}
}
Db::startTrans();
try {
$data[ 'site_id' ] = $this->site_id;
$data[ 'type' ] = 'app';
$data[ 'theme_type' ] = 'diy';
$data[ 'create_time' ] = time();
$diy_theme_model = new DiyTheme();
$diy_theme_model->create($data);
if (!empty($addon_save_data)){
$diy_theme_model->insertAll($addon_save_data);
}
Db::commit();
return true;
} catch (Exception $e) {
Db::rollback();
throw new AdminException($e->getMessage());
}
}
/**
* 编辑自定义主题配色
* @param int $id
* @param array $data
* @return bool
*/
public function editDiyTheme(int $id, array $data)
{
$diy_theme_model = new DiyTheme();
$diy_theme_info = $diy_theme_model->field('title')->where([ [ 'id', '=', $id ], [ 'site_id', '=', $this->site_id ] ])->findOrEmpty()->toArray();
if (empty($diy_theme_info)) throw new AdminException("DIY_THEME_COLOR_NOT_EXIST");
// 主应用主题颜色发生改变时,主应用下的插件也同步更新主题颜色
$addon_data = $diy_theme_model->field('id')->where([ [ 'title', '=', $diy_theme_info['title'] ], [ 'type', '=', 'addon' ], [ 'site_id', '=', $this->site_id ] ])->select()->toArray();
$addon_save_data = [];
if (!empty($addon_data)){
foreach ($addon_data as $value){
$addon_save_data[] = [
'id' => $value['id'],
'title' => $data['title'],
'theme' => $data['theme'],
'new_theme' => $data['new_theme'],
'update_time' => time(),
];
}
}
Db::startTrans();
try {
$data[ 'update_time' ] = time();
$diy_theme_model->where([ [ 'id', '=', $id ], [ 'site_id', '=', $this->site_id ] ])->update($data);
if (!empty($addon_save_data)){
$diy_theme_model->saveAll($addon_save_data);
}
Db::commit();
return true;
} catch (Exception $e) {
Db::rollback();
throw new AdminException($e->getMessage());
}
}
/**
* 删除自定义主题配色
* @param int $id
* @return bool
*/
public function delDiyTheme(int $id)
{
$diy_theme_model = new DiyTheme();
$diy_theme_info = $diy_theme_model->field('title,theme_type,is_selected')->where([ [ 'id', '=', $id ], [ 'site_id', '=', $this->site_id ] ])->findOrEmpty()->toArray();
if (empty($diy_theme_info)) throw new AdminException("DIY_THEME_COLOR_NOT_EXIST");
if ($diy_theme_info['theme_type'] == 'default') throw new AdminException("DIY_THEME_DEFAULT_COLOR_CAN_NOT_DELETE");
if ($diy_theme_info['is_selected'] == 1) throw new AdminException("DIY_THEME_SELECTED_CAN_NOT_DELETE");
$res = $diy_theme_model->where([ [ 'title', '=', $diy_theme_info['title'] ], [ 'site_id', '=', $this->site_id ] ])->delete();
return $res;
}
/**
* 检测自定义主题配色名称唯一性
* @param array $data
* @return bool
*/
public function checkDiyThemeTitleUnique($data)
{
$where = [
[ 'title', "=", $data[ 'title' ] ],
[ 'addon', "=", $data['addon'] ],
[ 'site_id', "=", $this->site_id ]
];
if (!empty($data[ 'id' ])) {
$where[] = [ 'id', "<>", $data[ 'id' ] ];
}
$diy_theme_model = new DiyTheme();
return $diy_theme_model->where($where)->count() > 0;
}
}

View File

@ -52,21 +52,27 @@ class DiyFormRecordsService extends BaseAdminService
public function getFieldStatList(array $where = [])
{
$field_list = ( new DiyFormService() )->getFieldsList($where, 'field_id, field_key, field_type, field_name');
// 一般格式存储的表单字段列表,如单行文本、多行文本、数字、手机号、邮箱、身份证号
$simple_field_list = array_filter($field_list, function($v) { return !in_array($v[ 'field_type' ], [ 'FormRadio', 'FormCheckbox', 'FormDateScope', 'FormTimeScope', 'FormImage' ]); });
// json格式存储的表单字段列表如单选框、多选框、日期、日期范围、时间、时间范围
$json_field_list = array_filter($field_list, function($v) { return in_array($v[ 'field_type' ], [ 'FormRadio', 'FormCheckbox', 'FormDateScope', 'FormTimeScope' ]); });
// 一般格式数据类型统计
$records_field_model = new DiyFormRecordsFields();
foreach ($simple_field_list as $k => &$v) {
// 按填写字段内容分组查询某个组件各字段内容填写次数
$value_list = $records_field_model->field('form_id, field_key, field_type, field_value, count(*) as write_count')->where([
[ 'site_id', '=', $this->site_id ],
[ 'field_key', '=', $v[ 'field_key' ] ],
[ 'field_type', '=', $v[ 'field_type' ] ]
])->withSearch([ 'form_id' ], $where)->group('field_value')->append([ 'render_value' ])->select()->toArray();
// 查询某个组件填写总次数
$total_count = $records_field_model->where([
[ 'site_id', '=', $this->site_id ],
[ 'field_key', '=', $v[ 'field_key' ] ],
[ 'field_type', '=', $v[ 'field_type' ] ]
])->withSearch([ 'form_id' ], $where)->count();
// 循环计算各字段内容填写占比
if ($total_count > 0) {
$total_percent = 100;
foreach ($value_list as $k1 => &$v1) {
@ -81,7 +87,9 @@ class DiyFormRecordsService extends BaseAdminService
}
$v[ 'value_list' ] = $value_list;
}
// json格式数据类型统计
foreach ($json_field_list as $k => &$v) {
// 查询某个组件填写记录
$field_list = $records_field_model->field('form_id, field_key, field_type, field_value')->where([
[ 'site_id', '=', $this->site_id ],
[ 'field_key', '=', $v[ 'field_key' ] ],
@ -91,7 +99,7 @@ class DiyFormRecordsService extends BaseAdminService
$total_count = 0;
$value_list = [];
foreach ($field_list as $k1 => &$v1) {
if ($v1[ 'field_type' ] != 'FormCheckbox') {
if ($v1[ 'field_type' ] != 'FormCheckbox') {//非多选项组件的内容填写次数统计、总次数统计
$key = $v1[ 'field_key' ] . '_' . $v1[ 'render_value' ];
if (isset($value_list[ $key ])) {
$value_list[ $key ][ 'write_count' ] = $value_list[ $key ][ 'write_count' ] + 1;
@ -104,7 +112,7 @@ class DiyFormRecordsService extends BaseAdminService
}
} else {
$value_arr = explode(',', $v1[ 'render_value' ]);
foreach ($value_arr as $k2 => $v2) {
foreach ($value_arr as $k2 => $v2) {//多选项组件的每个选项选择次数统计、总次数统计
$key = $v1[ 'field_key' ] . '_' . $v2;
if (isset($value_list[ $key ])) {
$value_list[ $key ][ 'write_count' ] = $value_list[ $key ][ 'write_count' ] + 1;
@ -118,6 +126,7 @@ class DiyFormRecordsService extends BaseAdminService
}
}
}
// 循环计算各字段内容填写占比
if ($total_count > 0) {
$value_list = array_values($value_list);
$total_percent = 100;
@ -133,6 +142,7 @@ class DiyFormRecordsService extends BaseAdminService
}
$v[ 'value_list' ] = $value_list;
}
// 合并返回一般格式数据类型统计和json格式数据类型统计
return array_merge($simple_field_list, $json_field_list);
}

View File

@ -55,7 +55,6 @@ class DiyFormService extends BaseAdminService
*/
public function getPage(array $where = [])
{
$where[] = [ 'site_id', '=', $this->site_id ];
$field = 'form_id, page_title, title, type, status, addon, share, write_num, remark, update_time';
$order = "form_id desc";
@ -63,6 +62,37 @@ class DiyFormService extends BaseAdminService
return $this->pageQuery($search_model);
}
/**
* 获取万能表单分页列表(用于弹框选择)
* @param array $where
* @return array
*/
public function getSelectPage(array $where = [])
{
$verify_form_ids = [];
// 检测id集合是否存在移除不存在的id纠正数据准确性
if (!empty($where[ 'verify_form_ids' ])) {
$verify_form_ids = $this->model->where([
[ 'form_id', 'in', $where[ 'verify_form_ids' ] ]
])->field('form_id')->select()->toArray();
if (!empty($verify_form_ids)) {
$verify_form_ids = array_column($verify_form_ids, 'form_id');
}
}
$field = 'form_id, page_title, title, type, status, addon, share, write_num, remark, update_time';
$order = "form_id desc";
$search_model = $this->model->where([
[ 'site_id', '=', $this->site_id ],
[ 'status', '=', 1 ],
])->withSearch([ "title", "type", 'addon' ], $where)->field($field)->order($order)->append([ 'type_name', 'addon_name' ]);
$list = $this->pageQuery($search_model);
$list[ 'verify_form_ids' ] = $verify_form_ids;
return $list;
}
/**
* 获取万能表单列表
* @param array $where
@ -285,9 +315,15 @@ class DiyFormService extends BaseAdminService
if ($status_count > 0) throw new AdminException('ON_STATUS_PROHIBIT_DELETE');
foreach ($form_ids as $form_id) {
$result = event('BeforeFormDelete', [ 'form_id' => $form_id, 'site_id' => $this->site_id ])[ 0 ] ?? [];
if (!empty($result) && !$result[ 'allow_operate' ]) {
$form_info = $this->model->field('page_title')->where([ [ 'form_id', '=', $form_id ], [ 'site_id', '=', $this->site_id ] ])->findOrEmpty()->toArray();
throw new AdminException($form_info[ 'page_title' ] . '已被使用,禁止删除');
}
}
$form_fields_model = new DiyFormFields();
$form_records_model = new DiyFormRecords();
$form_records_fields_model = new DiyFormRecordsFields();
$form_submit_config_model = new DiyFormSubmitConfig();
$form_write_config_model = new DiyFormWriteConfig();
@ -299,12 +335,6 @@ class DiyFormService extends BaseAdminService
//删除万能表单字段表
$form_fields_model->where($where)->delete();
//删除万能表单填写记录
$form_records_model->where($where)->delete();
//删除万能表单填写字段
$form_records_fields_model->where($where)->delete();
//删除万能表单提交页配置
$form_submit_config_model->where($where)->delete();
@ -412,11 +442,15 @@ class DiyFormService extends BaseAdminService
}
$componentType($form_component_list, 'diy_form');
$diy_service = new DiyService();
$diy_component_list = $diy_service->getComponentList();
$componentType($diy_component_list, 'diy');
$data = $form_component_list;
$data = array_merge($form_component_list, $diy_component_list);
if ($type == 'DIY_FORM') {
$diy_service = new DiyService();
$diy_component_list = $diy_service->getComponentList();
$componentType($diy_component_list, 'diy');
$data = array_merge($form_component_list, $diy_component_list);
}
return $data;
}
@ -521,6 +555,11 @@ class DiyFormService extends BaseAdminService
*/
public function modifyStatus($data)
{
$result = event('BeforeFormDelete', [ 'form_id' => $data[ 'form_id' ], 'site_id' => $this->site_id ])[ 0 ] ?? [];
if (!empty($result) && !$result[ 'allow_operate' ] && $data[ 'status' ] == 0) {
$form_info = $this->model->field('page_title')->where([ [ 'form_id', '=', $data[ 'form_id' ] ], [ 'site_id', '=', $this->site_id ] ])->findOrEmpty()->toArray();
throw new AdminException($form_info[ 'page_title' ] . '已被使用,不可禁用');
}
return $this->model->where([
[ 'form_id', '=', $data[ 'form_id' ] ],
[ 'site_id', '=', $this->site_id ]
@ -633,4 +672,21 @@ class DiyFormService extends BaseAdminService
];
}
/**
* 检测表单名称唯一性
* @param array $data
* @return bool
*/
public function checkPageTitleUnique($data)
{
$where = [
[ 'page_title', "=", $data[ 'page_title' ] ],
[ 'site_id', "=", $this->site_id ]
];
if (!empty($data[ 'form_id' ])) {
$where[] = [ 'form_id', "<>", $data[ 'form_id' ] ];
}
return $this->model->where($where)->count() > 0;
}
}

View File

@ -12,9 +12,11 @@
namespace app\service\admin\member;
use app\dict\member\MemberCashOutDict;
use app\dict\pay\TransferDict;
use app\model\member\MemberCashOut;
use app\service\core\member\CoreMemberCashOutService;
use core\base\BaseAdminService;
use core\exception\CommonException;
/**
* 会员提现服务层
@ -79,6 +81,9 @@ class MemberCashOutService extends BaseAdminService
*/
public function transfer(int $id, array $data){
$core_member_cash_out_service = new CoreMemberCashOutService();
$cash_out = $core_member_cash_out_service->find($this->site_id, $id);
if ($cash_out->isEmpty()) throw new CommonException('RECHARGE_LOG_NOT_EXIST');
if ($cash_out['status'] != MemberCashOutDict::WAIT_TRANSFER && $cash_out['transfer_type'] == TransferDict::WECHAT) throw new CommonException('CASH_OUT_WECHAT_ACCOUNT_NOT_ALLOW_ADMIN');
return $core_member_cash_out_service->transfer($this->site_id, $id, $data);
}
@ -118,4 +123,14 @@ class MemberCashOutService extends BaseAdminService
return $core_member_cash_out_service->checkTransferStatus($this->site_id, $id);
}
/**
* 取消体现
* @param int $id
* @return mixed
*/
public function cancel(int $id){
$core_member_cash_out_service = new CoreMemberCashOutService();
return $core_member_cash_out_service->cancel($this->site_id, $id);
}
}

View File

@ -43,7 +43,6 @@ class MemberService extends BaseAdminService
*/
public function getPage(array $where = [])
{
$field = 'member_id, member_no, site_id, username, mobile, password, register_channel, register_type, nickname, headimg, member_level, member_label, wx_openid, weapp_openid, wx_unionid, ali_openid, douyin_openid, login_ip, login_type, login_channel, login_count, login_time, create_time, last_visit_time, last_consum_time, sex, status, birthday, point, point_get, balance, balance_get, growth, growth_get, is_member, member_time, is_del, province_id, city_id, district_id, address, location, delete_time, money, money_get, commission, commission_get, commission_cash_outing';
$search_model = $this->model->where([['site_id', '=', $this->site_id]])->withSearch(['keyword','register_type', 'create_time', 'is_del', 'member_label', 'register_channel','member_level'],$where)
->field($field)

View File

@ -0,0 +1,76 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的saas管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\service\admin\pay;
use app\dict\common\ChannelDict;
use app\dict\pay\PayDict;
use app\dict\pay\PaySceneDict;
use app\dict\pay\TransferDict;
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\pay\CoreTransferSceneService;
use app\service\core\pay\CoreTransferService;
use app\service\core\paytype\CoreOfflineService;
use app\service\core\sys\CoreSysConfigService;
use core\base\BaseAdminService;
use core\exception\AdminException;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Log;
/**
* 支付服务层
*/
class TransferService extends BaseAdminService
{
public function __construct()
{
parent::__construct();
$this->model = new Pay();
}
public function getWechatTransferScene(){
return (new CoreTransferSceneService())->getWechatTransferScene($this->site_id);
}
/**
* 设置转账场景id
* @param $scene
* @param $data
* @return void
*/
public function setSceneId($scene, $data){
$core_transfer_service = new CoreTransferSceneService();
$config = $core_transfer_service->getWechatTransferSceneConfig($this->site_id) ?? [];
$scene_list = TransferDict::getWechatTransferScene();
if(empty($scene_list[$scene])) throw new AdminException('MERCHANT_TRANSFER_SCENARIOS_THAT_DO_NOT_EXIST');
$config[$scene] = $data['scene_id'];
$core_transfer_service->setWechatTransferSceneConfig($this->site_id, $config);
return true;
}
/**
* 设置业务转账场景配置
* @param $type
* @param $data
* @return void
*/
public function setTradeScene($type, $data){
$core_transfer_service = new CoreTransferSceneService();
$core_transfer_service->setTradeScene($this->site_id, $type, $data);
return true;
}
}

View File

@ -246,12 +246,26 @@ class SiteService extends BaseAdminService
$name = "\\$model";
$class = new $name();
if (in_array('site_id', $class->getTableFields())) {
$class->where([ [ 'site_id', '=', $site[ 'site_id' ] ] ])->delete();
$class::destroy(function($query) use ($site){
$query->where([ [ 'site_id', '=', $site[ 'site_id' ] ] ]);
});
// $class->where([ [ 'site_id', '=', $site[ 'site_id' ] ] ])->delete();
}
} catch (\Exception $e) {
}
}
//删除站点时同步删除该站点的所有管理员的关联信息
$sys_userrole_model = new SysUserRole();
$site_uids = $sys_userrole_model->where('site_id', $site_id)->field('site_id,uid')->select()->toArray();
$del_res = $sys_userrole_model->where('site_id', $site_id)->field('site_id,uid')->delete();
if ($del_res){
//删除成功是清除对应的缓存
foreach ($site_uids as $item){
Cache::delete('user_role_'.$item['uid'].'_'.$site_id);
Cache::delete('user_role_list_' .$item['uid']);
}
}
Cache::tag(self::$cache_tag_name . $site_id)->clear();
Db::commit();
return true;

View File

@ -114,6 +114,12 @@ class PosterService extends BaseAdminService
*/
public function modifyStatus($data)
{
$poster_info = $this->model->field('is_default')->where([
[ 'id', '=', $data[ 'id' ] ],
[ 'site_id', '=', $this->site_id ]
])->findOrEmpty()->toArray();
if (empty($poster_info)) throw new AdminException('POSTER_NOT_EXIST');
if ($poster_info[ 'is_default' ] == 1) throw new AdminException('POSTER_IN_USE_NOT_ALLOW_MODIFY');
return $this->model->where([
[ 'id', '=', $data[ 'id' ] ],
[ 'site_id', '=', $this->site_id ]

View File

@ -15,6 +15,7 @@ use app\job\sys\CheckJob;
use app\service\core\site\CoreSiteService;
use app\service\core\sys\CoreSysConfigService;
use core\base\BaseAdminService;
use think\facade\Cache;
use think\facade\Db;
use Throwable;
@ -114,17 +115,26 @@ class SystemService extends BaseAdminService
}
/**
* 清理缓存
* 清除表缓存
* @return string
*/
public function schemaCache()
{
if (is_dir(dirname($_SERVER[ 'DOCUMENT_ROOT' ]) . '/runtime/schema')) {
rmdirs(dirname($_SERVER[ 'DOCUMENT_ROOT' ]) . '/runtime/schema');
}
return 'CLEAR_MYSQL_CACHE_SUCCESS';
}
/**
* 清理缓存
*/
public function clearCache()
{
Cache::clear();
return 'CACHE_CLEAR_SUCCESS';
}
/**
*校验消息队列是否正常运行
* @return bool

View File

@ -29,6 +29,7 @@ use core\exception\CommonException;
use core\util\niucloud\BaseNiucloudClient;
use think\facade\Cache;
use think\facade\Db;
use function DI\string;
/**
* 框架及插件升级
@ -81,13 +82,9 @@ class UpgradeService extends BaseAdminService
$web_dir = $this->root_path . 'web' . DIRECTORY_SEPARATOR;
$wap_dir = $this->root_path . 'uni-app' . DIRECTORY_SEPARATOR;
try {
if (!is_dir($admin_dir)) throw new CommonException('ADMIN_DIR_NOT_EXIST');
if (!is_dir($web_dir)) throw new CommonException('WEB_DIR_NOT_EXIST');
if (!is_dir($wap_dir)) throw new CommonException('UNIAPP_DIR_NOT_EXIST');
} catch (\Exception $e) {
throw new CommonException($e->getMessage());
}
if (!is_dir($admin_dir)) throw new CommonException('ADMIN_DIR_NOT_EXIST');
if (!is_dir($web_dir)) throw new CommonException('WEB_DIR_NOT_EXIST');
if (!is_dir($wap_dir)) throw new CommonException('UNIAPP_DIR_NOT_EXIST');
$data = [
// 目录检测
@ -109,6 +106,22 @@ class UpgradeService extends BaseAdminService
$data['dir']['is_write'][] = ['dir' => str_replace(project_path(), '', $web_dir), 'status' => is_write($web_dir) ];
$data['dir']['is_write'][] = ['dir' => str_replace(project_path(), '', $wap_dir), 'status' => is_write($wap_dir) ];
// 校验niucloud/public下 wap web admin 目录及文件是否可读可写
$check_res = checkDirPermissions(public_path() . 'wap');
$check_res = array_merge2($check_res, checkDirPermissions(public_path() . 'admin'));
$check_res = array_merge2($check_res, checkDirPermissions(public_path() . 'web'));
if (!empty($check_res['unreadable'])) {
foreach ($check_res['unreadable'] as $item) {
$data['dir']['is_readable'][] = ['dir' => str_replace(project_path(), '', $item),'status' => false];
}
}
if (!empty($check_res['not_writable'])) {
foreach ($check_res['not_writable'] as $item) {
$data['dir']['is_write'][] = ['dir' => str_replace(project_path(), '', $item),'status' => false];
}
}
$check_res = array_merge(
array_column($data['dir']['is_readable'], 'status'),
array_column($data['dir']['is_write'], 'status')
@ -127,6 +140,8 @@ class UpgradeService extends BaseAdminService
public function upgrade(string $addon = '') {
if ($this->upgrade_task) throw new CommonException('UPGRADE_TASK_EXIST');
$upgrade_content = $this->getUpgradeContent($addon);
$upgrade = [
'product_key' => BaseNiucloudClient::PRODUCT,
'framework_version' => config('version.version')
@ -137,6 +152,12 @@ class UpgradeService extends BaseAdminService
} else {
$upgrade['app_key'] = $addon;
$upgrade['version'] = (new Addon())->where([ ['key', '=', $addon] ])->value('version');
// 判断框架版本是否低于插件支持版本
$last_version = $upgrade_content['version_list'][ count($upgrade_content['version_list']) - 1];
if (str_replace('.', '', config('version.version')) < str_replace('.', '', $last_version['niucloud_version']['version_no'])) {
throw new CommonException('BEFORE_UPGRADING_NEED_UPGRADE_FRAMEWORK');
}
}
$response = (new CoreAddonCloudService())->upgradeAddon($upgrade);
@ -150,18 +171,19 @@ class UpgradeService extends BaseAdminService
dir_mkdir($upgrade_dir);
}
$upgrade_tsak = [
$upgrade_task = [
'key' => $key,
'upgrade' => $upgrade,
'steps' => $this->steps,
'step' => 'requestUpgrade',
'executed' => ['requestUpgrade'],
'log' => [ $this->steps['requestUpgrade']['title'] ],
'params' => ['token' => $response['token'] ],
'upgrade_content' => $this->getUpgradeContent($addon)
'upgrade_content' => $upgrade_content
];
Cache::set($this->cache_key, $upgrade_tsak);
return $upgrade_tsak;
Cache::set($this->cache_key, $upgrade_task);
return $upgrade_task;
} catch (\Exception $e) {
throw new CommonException($e->getMessage());
}
@ -174,7 +196,7 @@ class UpgradeService extends BaseAdminService
public function execute() {
if (!$this->upgrade_task) return true;
$steps = array_keys($this->steps);
$steps = isset($this->upgrade_task['steps']) ? array_keys($this->upgrade_task['steps']) : array_keys($this->steps);
$index = array_search($this->upgrade_task['step'], $steps);
$step = $steps[ $index + 1 ] ?? '';
$params = $this->upgrade_task['params'] ?? [];
@ -194,7 +216,8 @@ class UpgradeService extends BaseAdminService
Cache::set($this->cache_key, $this->upgrade_task);
} catch (\Exception $e) {
$this->upgrade_task['step'] = $step;
$this->upgrade_task['error'] = $e->getMessage();
$this->upgrade_task['error'][] = '升级失败,失败原因:' . $e->getMessage().$e->getFile().$e->getLine();
Cache::set($this->cache_key, $this->upgrade_task);
$this->upgradeErrorHandle();
}
return true;
@ -481,20 +504,55 @@ class UpgradeService extends BaseAdminService
* @return true|void
*/
public function upgradeErrorHandle() {
$steps = [];
$steps[$this->upgrade_task['step']] = [];
if (isset($this->upgrade_task['is_cover'])) {
$steps['restoreCode'] = ['step' => 'restoreCode', 'title' => '恢复源码备份'];
$steps['restoreSql'] = ['step' => 'restoreSql', 'title' => '恢复数据库备份'];
}
$steps['restoreComplete'] = ['step' => 'restoreComplete', 'title' => '备份恢复完成'];
$this->upgrade_task['steps'] = $steps;
Cache::set($this->cache_key, $this->upgrade_task);
}
/**
* 恢复源码
* @return void
*/
public function restoreCode() {
try {
if (isset($this->upgrade_task['is_cover'])) {
$restore_service = (new RestoreService());
$restore_service->restoreCode();
$restore_service->restoreSql();
}
$this->clearUpgradeTask(5);
(new RestoreService())->restoreCode();
return true;
} catch (\Exception $e) {
$this->clearUpgradeTask(5);
$backup_dir = $this->upgrade_dir .$this->upgrade_task['key'] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'code' . DIRECTORY_SEPARATOR;
$this->upgrade_task['error'][] = '源码备份恢复失败稍后请手动恢复,源码备份文件路径:'. $backup_dir .',失败原因:' . $e->getMessage().$e->getFile().$e->getLine();
Cache::set($this->cache_key, $this->upgrade_task);
return true;
}
}
/**
* 恢复数据库
* @return void
*/
public function restoreSql() {
try {
(new RestoreService())->restoreSql();
return true;
} catch (\Exception $e) {
$backup_dir = $this->upgrade_dir .$this->upgrade_task['key'] . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR;
$this->upgrade_task['error'][] = '数据库备份恢复失败稍后请手动恢复,数据库备份文件路径:'. $backup_dir .',失败原因:' . $e->getMessage().$e->getFile().$e->getLine();
Cache::set($this->cache_key, $this->upgrade_task);
return true;
}
}
public function restoreComplete() {
$this->clearUpgradeTask(5);
return true;
}
/**
* 获取升级内容
* @param string $addon

View File

@ -14,8 +14,11 @@ namespace app\service\admin\weapp;
use app\dict\common\CommonDict;
use app\model\sys\SysConfig;
use app\service\core\weapp\CoreWeappConfigService;
use app\service\core\wxoplatform\CoreOplatformService;
use core\base\BaseAdminService;
use core\exception\CommonException;
use think\Model;
use app\service\admin\wxoplatform\WeappVersionService;
/**
* 微信小程序设置
@ -36,6 +39,23 @@ class WeappConfigService extends BaseAdminService
$config_info[$k] = CommonDict::ENCRYPT_STR;
}
}
$config_info['domain'] = [
'requestdomain' => '',
'wsrequestdomain' => '',
'uploaddomain' => '',
'downloaddomain' => '',
'tcpdomain' => '',
'udpdomain' => ''
];
if ($config_info[ 'is_authorization' ] == 1) {
try {
$domain = CoreOplatformService::getDomain($this->site_id);
foreach ($config_info[ 'domain' ] as $k => $v) {
$config_info[ 'domain' ][ $k ] = isset($domain[$k]) && is_array($domain[$k]) ? implode(';', $domain[$k]) : '';
}
} catch (\Exception $e) {
}
}
return array_merge($config_info, $this->getWeappStaticInfo());
}
@ -71,4 +91,39 @@ class WeappConfigService extends BaseAdminService
'upload_ip' => gethostbyname('oss.niucloud.com')
];
}
/**
* 设置域名
* @param $data
* @return void
*/
public function setDomain($data){
foreach ($data as $k => $v) {
$data[$k] = empty($v) ? [] : explode(';', $v);
}
$result = CoreOplatformService::setDomain($this->site_id, $data);
if (isset($result['errcode']) && $result['errcode'] != 0) {
throw new CommonException($result['errmsg']);
}
}
/**
* 获取隐私协议
* @return array
*/
public function getPrivacySetting(){
return CoreOplatformService::getPrivacySetting($this->site_id);
}
/**
* 设置隐私协议
* @return array
*/
public function setPrivacySetting($data){
$data['privacy_ver'] = 1;
CoreOplatformService::setPrivacySetting($this->site_id, $data);
// 提交小程序
(new WeappVersionService())->siteWeappCommit();
}
}

View File

@ -94,7 +94,7 @@ class OplatformServerService extends BaseAdminService
private function weappAuditSuccess($message) {
$site_id = CoreOplatformService::getSiteIdByAuthorizerAppid($message['ToUserName']);
CoreOplatformService::releaseWeapp($site_id);
(new WeappVersion())->where(['site_id' => $site_id, 'status' => CloudDict::APPLET_AUDITING ])->update(['status' => CloudDict::APPLET_UPLOAD_SUCCESS ]);
(new WeappVersion())->where(['site_id' => $site_id, 'status' => CloudDict::APPLET_AUDITING ])->update(['status' => CloudDict::APPLET_PUBLISHED ]);
// 发布后重新设置下域名
request()->siteId($site_id);

View File

@ -216,14 +216,14 @@ class WeappVersionService extends BaseAdminService
*/
public static function weappCommit($site_id, $site_group_id) {
$version = (new WxOplatfromWeappVersion())->where([ ['site_group_id', '=', $site_group_id], ['template_id', '<>', '' ] ])->order('id desc')->findOrEmpty();
if ($version->isEmpty()) return true;
if ($version->isEmpty()) throw new CommonException('NOT_YET_PRESENT_TEMPLATE_LIBRARY');
$is_exist = (new WeappVersion())->where(['site_id' => $site_id, 'status' => CloudDict::APPLET_AUDITING ])->findOrEmpty();
if (!$is_exist->isEmpty()) throw new CommonException('EXIST_AUDITING_VERSION');
$weapp_config = (new CoreWeappConfigService())->getWeappConfig($site_id);
CoreOplatformService::commitWeapp($site_id, [
$commit_result = CoreOplatformService::commitWeapp($site_id, [
'template_id' => $version['template_id'],
'user_version' => $version['user_version'],
'user_desc' => $version['user_desc'],
@ -236,8 +236,9 @@ class WeappVersionService extends BaseAdminService
'directCommit' => true
])
]);
(new WeappVersion())->where(['site_id' => $site_id, 'version' => $version['user_version'] ])->delete();
if (isset($commit_result['errcode']) && $commit_result['errcode'] != 0) {
throw new CommonException($commit_result['errmsg']);
}
$create_res = (new WeappVersion())->create([
'site_id' => $site_id,

View File

@ -160,26 +160,24 @@ class DiyService extends BaseApiService
{
$site_addon = ( new CoreSiteService() )->getSiteCache($this->site_id);
$addon_list = array_merge($site_addon['apps'],$site_addon['site_addons']);
$theme_data = (new DiyTheme())->where([['site_id', '=', $this->site_id]])->column('id,color_name,color_mark,value,diy_value,title','addon');
$defaultColor = ( new CoreDiyService() )->getDefaultColor();
$theme_data = (new DiyTheme())->where([['site_id', '=', $this->site_id], ['is_selected', '=', 1]])->column('id,title,theme,new_theme','addon');
$system_theme = array_values(array_filter(event('ThemeColor', [ 'key' => 'app'])))[0] ?? [];
$app_theme['app'] = [
'color_name' => $theme_data['app']['color_name'] ?? $defaultColor['name'],
'color_mark' => $theme_data['app']['color_mark'] ?? $defaultColor['title'],
'value' => $theme_data['app']['value'] ?? $defaultColor['theme'],
'diy_value' => $theme_data['app']['diy_value'] ?? '',
'title' => $theme_data['app']['title'] ?? (!empty($system_theme) ? $system_theme['theme_color'][0]['title'] : ''),
'theme' => $theme_data['app']['theme'] ?? (!empty($system_theme) ? $system_theme['theme_color'][0]['theme'] : ''),
'new_theme' => $theme_data['app']['new_theme'] ?? '',
];
$data = [];
foreach ($addon_list as $key=>$value){
foreach ($addon_list as $key => $value){
if (isset($value['support_app']) && empty($value['support_app']) && $value['type'] == 'addon'){
continue;
}
$default_theme_data = array_values(array_filter(event('ThemeColor', [ 'key' => $value['key']])))[0] ?? [];
$data[$value['key']]['color_mark'] = $theme_data[$value['key']]['color_mark'] ?? ($default_theme_data ? $default_theme_data[ 'name' ] : $defaultColor['name']);
$data[$value['key']]['color_name'] = $theme_data[$value['key']]['color_name'] ?? ($default_theme_data ? $default_theme_data[ 'title' ] : $defaultColor['title']);
$data[$value['key']]['value'] = $theme_data[$value['key']]['value'] ?? ($default_theme_data ? $default_theme_data[ 'theme' ] : $defaultColor['theme']);
$data[$value['key']]['diy_value'] = $theme_data[$value['key']]['diy_value'] ?? '';
$addon_theme = array_values(array_filter(event('ThemeColor', [ 'key' => $value['key']])))[0] ?? [];
$data[$value['key']]['title'] = $theme_data[$value['key']]['title'] ?? (!empty($addon_theme) ? $addon_theme['theme_color'][0][ 'title' ] : '');
$data[$value['key']]['theme'] = $theme_data[$value['key']]['theme'] ?? (!empty($addon_theme) ? $addon_theme['theme_color'][0][ 'theme' ] : '');
$data[$value['key']]['new_theme'] = $theme_data[$value['key']]['new_theme'] ?? '';
}
if (count($site_addon[ 'apps' ]) > 1) {
if (count($site_addon[ 'apps' ]) > 1) {// 应用数量大于1时展示系统主题色设置只有一个应用时不展示系统主题色设置
$data = array_merge($app_theme,$data);
}
return $data;

View File

@ -118,7 +118,8 @@ class LoginService extends BaseApiService
$data = array(
'mobile' => $params[ 'mobile' ],
'nickname' => $params[ 'nickname' ],
'headimg' => $params[ 'headimg' ]
'headimg' => $params[ 'headimg' ],
'wx_openid' => $params[ 'openid' ]
);
return ( new RegisterService() )->register($params[ 'mobile' ], $data, MemberRegisterTypeDict::MOBILE, false);
} else {
@ -202,7 +203,7 @@ class LoginService extends BaseApiService
//发送
if (!in_array($type, SmsDict::SCENE_TYPE)) throw new AuthException('MEMBER_MOBILE_CAPTCHA_ERROR');
$code = str_pad(random_int(1, 9999), 4, 0, STR_PAD_LEFT);// 生成4位随机数左侧补0
// ( new NoticeService() )->send('member_verify_code', [ 'code' => $code, 'mobile' => $mobile ]);
( new NoticeService() )->send('member_verify_code', [ 'code' => $code, 'mobile' => $mobile ]);
//将验证码存入缓存
$key = md5(uniqid('', true));
$cache_tag_name = "mobile_key" . $mobile . $type;
@ -255,20 +256,21 @@ class LoginService extends BaseApiService
if (!empty($open_id)) {
Log::write('channel_1' . $this->channel);
if (!empty($this->channel)) {
$openid_field = match($this->channel){
'wechat' => 'wx_openid',
$openid_field = match ( $this->channel ) {
'wechat' => 'wx_openid',
'weapp' => 'weapp_openid',
default => ''
};
if (!empty($openid_field)) {
if (!$member->isEmpty()) {
if (empty($member->$openid_field)) {
//todo 定义当前第三方授权方没有退出登录功能,故这儿不做openid是否存在账号验证
// $member_service = new MemberService();
// $open_member = $member_service->findMemberInfo([$openid_field => $open_id, 'site_id' => $this->site_id]);
$member->$openid_field = $open_id;
$member->save();
$member_service = new MemberService();
$open_member = $member_service->findMemberInfo([ $openid_field => $open_id, 'site_id' => $this->site_id ]);
// 检测openid是否存在账号验证
if (empty($open_member)) {
$member->$openid_field = $open_id;
$member->save();
}
} else {
if ($member->$openid_field != $open_id) {
throw new AuthException('MEMBER_IS_BIND_AUTH');

View File

@ -11,7 +11,6 @@
namespace app\service\api\login;
use app\dict\common\ChannelDict;
use app\dict\member\MemberLoginTypeDict;
use app\dict\member\MemberRegisterTypeDict;
use app\job\member\SetMemberNoJob;
@ -111,7 +110,7 @@ class RegisterService extends BaseApiService
* @param $mobile
* @return array
*/
public function account(string $username, string $password, $mobile)
public function account(string $username, string $password, $mobile, $wx_openid)
{
//todo 校验验证码 可以加try catch 后续
( new CaptchaService() )->check();
@ -130,6 +129,14 @@ class RegisterService extends BaseApiService
'username' => $username,
'password' => $password_hash,
);
if (!empty($wx_openid)) {
// 检测openid是否被使用
$member_service = new MemberService();
$member_info = $member_service->findMemberInfo([ 'wx_openid' => $wx_openid, 'site_id' => $this->site_id ]);
if (empty($member_info->toArray())) {
$data[ 'wx_openid' ] = $wx_openid;
}
}
return $this->register($mobile, $data, MemberRegisterTypeDict::USERNAME);
}
@ -181,7 +188,7 @@ class RegisterService extends BaseApiService
$config = ( new MemberConfigService() )->getLoginConfig();
$is_bind_mobile = $config[ 'is_bind_mobile' ];
$with_field = match($type){
$with_field = match ( $type ) {
MemberLoginTypeDict::USERNAME => 'username',
MemberLoginTypeDict::MOBILE => 'mobile',
MemberLoginTypeDict::WECHAT => 'wx_openid',

View File

@ -81,15 +81,16 @@ class MemberCashOutService extends BaseApiService
])->findOrEmpty();
if($cash_out->isEmpty()) throw new ApiException('RECHARGE_LOG_NOT_EXIST');
if($cash_out['status'] != MemberCashOutDict::WAIT_AUDIT) throw new CommonException('CASHOUT_STATUS_NOT_IN_WAIT_AUDIT');
$cash_out->save(
[
'cancel_time' => time(),
'status' => MemberCashOutDict::CANCEL
]
);
(new CoreMemberCashOutService())->giveback($this->site_id, $cash_out);
// if($cash_out['status'] != MemberCashOutDict::WAIT_AUDIT) throw new CommonException('CASHOUT_STATUS_NOT_IN_WAIT_AUDIT');
(new CoreMemberCashOutService())->cancel($this->site_id, $id);
// $cash_out->save(
//
// [
// 'cancel_time' => time(),
// 'status' => MemberCashOutDict::CANCEL
// ]
// );
// (new CoreMemberCashOutService())->giveback($this->site_id, $cash_out);
return true;
}
@ -101,4 +102,14 @@ class MemberCashOutService extends BaseApiService
return (new CoreMemberConfigService())->getCashOutConfig($this->site_id);
}
/**
* 提现转账(主要用于微信商家转账)
* @param int $id
* @return void
*/
public function transfer(int $id, array $data){
$data['channel'] = $this->channel;
$result = (new CoreMemberCashOutService())->transfer($this->site_id, $id, $data);
return $result;
}
}

View File

@ -35,9 +35,7 @@ class MemberConfigService extends BaseApiService
// 检测公众号配置是否成功
$wechat_auth = ( new WechatAuthService() )->jssdkConfig($url);
} catch (\Exception $e) {
$res[ 'is_auth_register' ] = 0;
$res[ 'is_force_access_user_info' ] = 0;
$res[ 'is_bind_mobile' ] = 0;
$res[ 'wechat_error' ] = $e->getMessage();
}
}
return $res;

View File

@ -63,6 +63,15 @@ class MemberService extends BaseApiService
return $this->model->where([['member_id', '=', $this->member_id]])->with(['member_level_name_bind'])->field($field)->append(['sex_name'])->findOrEmpty()->toArray();
}
/**
* 检测会员信息是否存在
* @return int
*/
public function getCount($condition)
{
return $this->model->where($condition)->count();
}
/**
* 会员中心信息
*/

View File

@ -0,0 +1,69 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的saas管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\service\api\pay;
use app\dict\common\ChannelDict;
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;
/**
* 支付业务
*/
class TransferService extends BaseApiService
{
public $core_pay_service;
public function __construct()
{
parent::__construct();
$this->core_pay_service = new CorePayService();
}
/**
* 去支付
* @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 confirm(string $transfer_no, array $data = []){
// $member = (new CoreMemberService())->getInfoByMemberId($this->site_id, $this->member_id);
// switch ($this->channel) {
// case ChannelDict::WECHAT://公众号
// $openid = $openid ? $openid : $member['wx_openid'] ?? '';
// break;
// case ChannelDict::WEAPP://微信小程序
// $openid = $openid ? $openid : $member['weapp_openid'] ?? '';
// break;
// }
// /**/return $this->core_pay_service->pay($this->site_id, $trade_type, $trade_id, $type, $this->channel, $openid, $return_url, $quit_url, $buyer_id, $voucher, $this->member_id);
}
}

View File

@ -107,6 +107,7 @@ class WeappAuthService extends BaseApiService
$is_auth_register = $config[ 'is_auth_register' ];
$is_force_access_user_info = $config[ 'is_force_access_user_info' ];
$is_bind_mobile = $config[ 'is_bind_mobile' ];
$is_mobile = $config[ 'is_mobile' ];
if ($member_info->isEmpty()) {
@ -147,6 +148,12 @@ class WeappAuthService extends BaseApiService
} else {
return [ 'openid' => $openid, 'unionid' => $unionid ]; // 将重要信息返回给前端保存
}
} else if($is_mobile) {
if (!empty($data[ 'mobile' ]) || !empty($data[ 'mobile_code' ])) {
return $this->register($openid, $data[ 'mobile' ], $data[ 'mobile_code' ], $unionid);
} else {
return [ 'openid' => $openid, 'unionid' => $unionid ]; // 将重要信息返回给前端保存
}
}
}
} else {

View File

@ -148,14 +148,16 @@ class WechatAuthService extends BaseApiService
return $this->register($openid, '', $nickname, $avatar, $unionid);
}
} else {
return [ 'openid' => $openid, 'unionid' => $unionid ]; // 将重要信息返回给前端保存
}
} else {
// 可能会更新用户和粉丝表
$login_service = new LoginService();
// 若用户头像为空,那么从微信获取头像和昵称,然后进行更新
if (empty($member_info->headimg)) {
$member_info->headimg = $avatar;
$member_info->nickname = $nickname;
if (!empty($avatar)) $member_info->headimg = $avatar;
if (!empty($nickname)) $member_info->nickname = $nickname;
}
return $login_service->login($member_info, MemberLoginTypeDict::WECHAT);
}

View File

@ -105,13 +105,9 @@ class CoreAddonInstallService extends CoreAddonBaseService
$to_resource_dir = public_path() . 'addon' . DIRECTORY_SEPARATOR . $this->addon . DIRECTORY_SEPARATOR;
try {
if (!is_dir($this->root_path . 'admin' . DIRECTORY_SEPARATOR)) throw new CommonException('ADMIN_DIR_NOT_EXIST');
if (!is_dir($this->root_path . 'web' . DIRECTORY_SEPARATOR)) throw new CommonException('WEB_DIR_NOT_EXIST');
if (!is_dir($this->root_path . 'uni-app' . DIRECTORY_SEPARATOR)) throw new CommonException('UNIAPP_DIR_NOT_EXIST');
} catch (\Exception $e) {
throw new CommonException($e->getMessage());
}
if (!is_dir($this->root_path . 'admin' . DIRECTORY_SEPARATOR)) throw new CommonException('ADMIN_DIR_NOT_EXIST');
if (!is_dir($this->root_path . 'web' . DIRECTORY_SEPARATOR)) throw new CommonException('WEB_DIR_NOT_EXIST');
if (!is_dir($this->root_path . 'uni-app' . DIRECTORY_SEPARATOR)) throw new CommonException('UNIAPP_DIR_NOT_EXIST');
// 配置文件
$package_path = $this->install_addon_path . 'package' . DIRECTORY_SEPARATOR;
@ -141,6 +137,22 @@ class CoreAddonInstallService extends CoreAddonBaseService
$data['dir']['is_write'][] = ['dir' => str_replace(project_path(), '', $to_wap_dir), 'status' => is_dir($to_wap_dir) ? is_write($to_wap_dir) : mkdir($to_wap_dir, 0777, true)];
$data['dir']['is_write'][] = ['dir' => str_replace(project_path(), '', $to_resource_dir), 'status' => is_dir($to_resource_dir) ? is_write($to_resource_dir) : mkdir($to_resource_dir, 0777, true)];
// 校验niucloud/public下 wap web admin 目录及文件是否可读可写
$check_res = checkDirPermissions(public_path() . 'wap');
$check_res = array_merge2($check_res, checkDirPermissions(public_path() . 'admin'));
$check_res = array_merge2($check_res, checkDirPermissions(public_path() . 'web'));
if (!empty($check_res['unreadable'])) {
foreach ($check_res['unreadable'] as $item) {
$data['dir']['is_readable'][] = ['dir' => str_replace(project_path(), '', $item),'status' => false];
}
}
if (!empty($check_res['not_writable'])) {
foreach ($check_res['not_writable'] as $item) {
$data['dir']['is_write'][] = ['dir' => str_replace(project_path(), '', $item),'status' => false];
}
}
$check_res = array_merge(
array_column($data['dir']['is_readable'], 'status'),
array_column($data['dir']['is_write'], 'status')

View File

@ -1,7 +0,0 @@
import request from '@/utils/request'
/***************************************************** hello world ****************************************************/
export function getHelloWorld() {
return request.get(`{key}/hello_world`)
}

View File

@ -1,17 +0,0 @@
<template>
<span class="text-[20px]">{{hello_world_text}}</span>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { getHelloWorld } from '@/addon/{key}/api/hello_world'
const hello_world_text = ref('');
const getHelloWorldInfo = async () => {
hello_world_text.value = await (await getHelloWorld()).data
}
getHelloWorldInfo()
</script>
<style lang="scss" scoped>
</style>

View File

@ -1,19 +0,0 @@
<?php
return [
'pages' => <<<EOT
// PAGE_BEGIN
// *********************************** {{addon_name}} ***********************************
{
"root": "addon/{{addon_name}}",
"pages": [
{
"path": "pages/hello_world/index",
"style": {
"navigationBarTitleText": "%{{addon_name}}.pages.hello_world.index%"
}
}
]
},
// PAGE_END
EOT
];

View File

@ -1,36 +0,0 @@
<?php
namespace addon\{key};
/**
* 插件安装之后单独的插件方法
*/
class Addon
{
/**
* 插件安装执行
*/
public function install()
{
return true;
}
/**
* 插件卸载执行
*/
public function uninstall()
{
return true;
}
/**
* 插件升级执行
*/
public function upgrade()
{
return true;
}
}

View File

@ -1,29 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\{key}\app\adminapi\controller\hello_world;
use core\base\BaseAdminController;
use think\Response;
class Index extends BaseAdminController
{
/**
* Hello World
* @return Response
*/
public function index()
{
return success('SUCCESS', 'Hello World');
}
}

View File

@ -1,4 +0,0 @@
<?php
return [
];

View File

@ -1,30 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
use think\facade\Route;
use app\adminapi\middleware\AdminCheckRole;
use app\adminapi\middleware\AdminCheckToken;
use app\adminapi\middleware\AdminLog;
/**
* {title}
*/
Route::group('{key}', function () {
/***************************************************** hello world ****************************************************/
Route::get('hello_world', 'addon\{key}\app\adminapi\controller\hello_world\Index@index');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,
AdminLog::class
]);

View File

@ -1,27 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace addon\{key}\app\api\controller\hello_world;
use core\base\BaseApiController;
use think\Response;
class Index extends BaseApiController
{
/**
* Hello World
* @return Response
*/
public function index()
{
return success('SUCCESS', 'Hello World');
}
}

View File

@ -1,36 +0,0 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
use app\api\middleware\ApiCheckToken;
use app\api\middleware\ApiLog;
use app\api\middleware\ApiChannel;
use think\facade\Route;
/**
* {title}
*/
Route::group('{key}', function() {
/***************************************************** hello world ****************************************************/
Route::get('hello_world', 'addon\{key}\app\api\controller\hello_world\Index@index');
})->middleware(ApiChannel::class)
->middleware(ApiCheckToken::class, false) //false表示不验证登录
->middleware(ApiLog::class);
Route::group('{key}', function() {
})->middleware(ApiChannel::class)
->middleware(ApiCheckToken::class, true) //表示验证登录
->middleware(ApiLog::class);

View File

@ -1,4 +0,0 @@
<?php
return [
];

View File

@ -1,12 +0,0 @@
<?php
return [
'bind' => [
],
'listen' => [
],
'subscribe' => [
],
];

View File

@ -1,11 +0,0 @@
{
"title": "{title}",
"desc": "{desc}",
"key": "{key}",
"version": "{version}",
"author": "{author}",
"type": "{type}",
"support_app": "{support_app}",
"compile":[],
"support_version": "{support_version}"
}

View File

@ -1,33 +0,0 @@
<?php
return [
[
'menu_name' => '{title}',
'menu_key' => '{key}',
'menu_type' => 0,
'icon' => '',
'api_url' => '',
'router_path' => '',
'view_path' => '',
'methods' => '',
'sort' => 100,
'status' => 1,
'is_show' => 1,
'children' => [
[
'menu_name' => '{title}',
'menu_key' => '{key}_hello_world',
'menu_type' => 1,
'icon' => '',
'api_url' => '{key}/hello_world',
'router_path' => '{key}/hello_world',
'view_path' => 'hello_world/index',
'methods' => 'get',
'sort' => 100,
'status' => 1,
'is_show' => 1,
'children' => []
],
]
]
];

View File

@ -1,8 +0,0 @@
import request from '@/utils/request'
/***************************************************** hello world ****************************************************/
export function getHelloWorld() {
return request.get(`{key}/hello_world`)
}

View File

@ -1,18 +0,0 @@
<template>
<text class="text-[20px]">{{helloWorld}}</text>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { getHelloWorld } from '@/addon/{key}/api/hello_world'
import { onLoad } from '@dcloudio/uni-app'
let helloWorld = ref('');
onLoad(() => {
getHelloWorld().then((res) => {
helloWorld.value = res.data
})
})
</script>
<style lang="scss" scoped>
</style>

View File

@ -1,8 +0,0 @@
/**
* hello world
*/
export function getHelloWorld() {
return request.get('{key}/hello_world')
}

View File

@ -1,9 +0,0 @@
{
"pages": {
"{key}": {
"hello_world": {
"index": "hello_world"
}
}
}
}

View File

@ -1,6 +0,0 @@
export default [
{
path: "/{key}/hello_world/index",
component: () => import('~/addon/{key}/pages/hello_world/index.vue')
}
]

View File

@ -1,15 +0,0 @@
<template>
<span class="text-[24px]">{{hello_world_text}}</span>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { getHelloWorld } from '@/addon/{key}/api/hello_world'
const hello_world_text = ref('');
getHelloWorld().then(res => {
hello_world_text.value = res.data;
})
</script>
<style lang="scss" scoped></style>

View File

@ -11,11 +11,10 @@
namespace app\service\core\diy;
use app\dict\sys\ConfigKeyDict;
use app\model\sys\SysConfig;
use app\service\core\sys\CoreConfigService;
use app\model\addon\Addon;
use app\model\diy\DiyTheme;
use app\service\core\site\CoreSiteService;
use core\base\BaseCoreService;
use think\Model;
/**
* 自定义页面服务层
@ -24,77 +23,79 @@ use think\Model;
*/
class CoreDiyService extends BaseCoreService
{
/**
* 获取系统默认主题配色
* @return array
*/
public function getDefaultColor()
{
return [
'title' => '商务蓝',
'name' => 'blue',
'theme' => [
'--primary-color' => '#007aff', // 主色
'--primary-help-color' => '#007aff', // 辅色
'--price-text-color' => '#FF4142',// 价格颜色
'--primary-color-dark' => '#398ade', // 灰色
'--primary-color-disabled' => '#9acafc', // 禁用色
'--primary-color-light' => '#ecf5ff', // 边框色(深)
'--primary-color-light2' => '#fff7f7', // 边框色(淡)
'--page-bg-color' => '#f6f6f6', // 页面背景色
],
];
}
/**
* 获取默认主题配色
* @return array
* 初始化默认自定义主题配色
* @return true
*/
public function getDefaultThemeColor()
public function initDefaultDiyTheme($site_id)
{
return [
[
'title' => '商务蓝',
'name' => 'blue',
'theme' => [
'--primary-color' => '#007aff', // 主色
'--primary-help-color' => '#007aff', // 辅色
'--price-text-color' => '#FF4142',// 价格颜色
'--primary-color-dark' => '#398ade', // 灰色
'--primary-color-disabled' => '#9acafc', // 禁用色
'--primary-color-light' => '#ecf5ff', // 边框色(深)
'--primary-color-light2' => '#fff7f7', // 边框色(淡)
'--page-bg-color' => '#f6f6f6', // 页面背景色
],
],
[
'title' => '热情红',
'name' => 'red',
'theme' => [
'--primary-color' => '#FF4142', // 主色
'--primary-help-color' => '#FB7939', // 辅色
'--price-text-color' => '#FF4142',// 价格颜色
'--primary-color-dark' => '#F26F3E', // 灰色
'--primary-color-disabled' => '#FFB397', // 禁用色
'--primary-color-light' => '#FFEAEA', // 边框色(深)
'--primary-color-light2' => '#fff7f7', // 边框色(淡)
'--page-bg-color' => '#f6f6f6', // 页面背景色
],
],
[
'title' => '活力橙',
'name' => 'orange',
'theme' => [
'--primary-color' => '#FA6400', // 主色
'--primary-help-color' => '#FA6400', // 辅色
'--price-text-color' => '#FF2525',// 价格颜色
'--primary-color-dark' => '#F48032', // 灰色
'--primary-color-disabled' => '#FFC29A', // 禁用色
'--primary-color-light' => '#FFF4ED', // 边框色(深)
'--primary-color-light2' => '#FFF4ED', // 边框色(淡)
'--page-bg-color' => '#f6f6f6', // 页面背景色
],
]
];
$site_addon = ( new CoreSiteService() )->getSiteCache($site_id);
$system_theme = array_values(array_filter(event('ThemeColor', [ 'key' => 'app'])))[0] ?? [];
foreach ($system_theme['theme_color'] as $k => $v) {
$data[] = [
'type' => 'app',
'addon' => 'app',
'site_id' => $site_id,
'title' => $v['title'],
'theme' => $v['theme'],
'default_theme' => $v['theme'],
'theme_type' => 'default',
'is_selected' => $k == 0 ? 1 : 0,
'create_time' => time(),
];
}
foreach ($site_addon[ 'apps' ] as $value){
$addon_theme = array_values(array_filter(event('ThemeColor', [ 'key' => $value['key'] ])))[0] ?? [];
if (empty($addon_theme)) continue;
foreach ($addon_theme['theme_color'] as $k => $v){
$data[] = [
'type' => 'app',
'addon' => $value['key'],
'site_id' => $site_id,
'title' => $v['title'],
'theme' => $v['theme'],
'default_theme' => $v['theme'],
'theme_type' => 'default',
'is_selected' => $k == 0 ? 1 : 0,
'create_time' => time(),
];
}
$addon_data = (new addon())->field('key')->where([['support_app', '=', $value['key']]])->select()->toArray();
if (!empty($addon_data)){
foreach ($addon_data as $v){
foreach ($addon_theme['theme_color'] as $theme_k => $theme_v){
$data[] = [
'type' => 'addon',
'addon' => $v['key'],
'site_id' => $site_id,
'title' => $theme_v['title'],
'theme' => $theme_v['theme'],
'default_theme' => $theme_v['theme'],
'theme_type' => 'default',
'is_selected' => $theme_k == 0 ? 1 : 0,
'create_time' => time(),
];
}
}
}
}
$diy_theme_model = new DiyTheme();
foreach ($data as $k => &$v) {
$theme_count = $diy_theme_model->where([
[ 'site_id', "=", $site_id ],
[ 'title', "=", $v[ 'title' ] ],
[ 'addon', "=", $v['addon'] ]
])->count();
// 如果已有该主题风格颜色则不再添加
if ($theme_count > 0) {
unset($data[ $k ]);
}
}
if (!empty($data)) {
$diy_theme_model->insertAll($data);
}
return true;
}
}

View File

@ -167,7 +167,7 @@ class CoreDiyFormRecordsService extends BaseCoreService
if (!empty($form_field_info)) {
if ($form_field_info[ 'field_required' ] == 1 && empty($field_value)) {
throw new CommonException($component[ 'componentTitle' ] . '不能为空');
throw new CommonException(($component[ 'field' ][ 'name' ] ?? $component[ 'componentTitle' ]) . '不能为空');
} else if (empty($check_field_value)) {
// 过滤空数据
continue;
@ -181,7 +181,7 @@ class CoreDiyFormRecordsService extends BaseCoreService
[ 'field_type', '=', $component[ 'componentName' ] ]
])->column('field_value');
if ($form_field_info[ 'field_unique' ] == 1 && in_array($field_value, $field_values)) {
throw new CommonException($component[ 'componentTitle' ] . '不能重复');
throw new CommonException(($component[ 'field' ][ 'name' ] ?? $component[ 'componentTitle' ]) . '不能重复');
}
} else if (empty($check_field_value)) {
// 过滤空数据

View File

@ -132,12 +132,13 @@ class CoreMemberCashOutService extends BaseCoreService
$cash_out_account = (new CoreMemberCashOutAccountService())->getInfo($data['account_id'], $site_id, $member_id);
if (empty($cash_out_account)) throw new CommonException('CASH_OUT_ACCOUNT_NOT_EXIST');
} else {
$data_transfer_payee = $data['transfer_payee'] ?? [];
if (empty($data_transfer_payee)) throw new CommonException('CASH_OUT_ACCOUNT_NOT_FOUND_VALUE');//转账到微信零钱缺少参数
$transfer_payee = [
'open_id' => $data_transfer_payee['open_id'] ?? '',
'channel' => $data_transfer_payee['channel'] ?? '',
];
// $data_transfer_payee = $data['transfer_payee'] ?? [];
// if (empty($data_transfer_payee)) throw new CommonException('CASH_OUT_ACCOUNT_NOT_FOUND_VALUE');//转账到微信零钱缺少参数
// $transfer_payee = [
// 'open_id' => $data_transfer_payee['open_id'] ?? '',
// 'channel' => $data_transfer_payee['channel'] ?? '',
// ];
$transfer_payee = [];
}
Db::startTrans();
@ -204,6 +205,7 @@ class CoreMemberCashOutService extends BaseCoreService
}
/**
* 审核
* @param int $site_id
* @param int $id
* @param string $action
@ -240,14 +242,18 @@ class CoreMemberCashOutService extends BaseCoreService
'audit_time' => time(),
'status' => MemberCashOutDict::WAIT_TRANSFER
]);
$config = (new CoreMemberConfigService())->getCashOutConfig($site_id);
if ($config['is_auto_transfer']) {
try {
$this->transfer($site_id, $cash_out['id']);
} catch ( Throwable $e ) {
// $config = (new CoreMemberConfigService())->getCashOutConfig($site_id);
// if ($config['is_auto_transfer']) {
// try {
//会员提现需要在前端手动发起
// if($cash_out['transfer_type'] != TransferDict::WECHAT){
// $this->transfer($site_id, $cash_out['id']);
// }
}
}
// } catch ( Throwable $e ) {
// }
// }
return true;
}
@ -288,16 +294,10 @@ class CoreMemberCashOutService extends BaseCoreService
$transfer_type = $cash_out['transfer_type'];
if ($transfer_type == TransferDict::WECHAT) {//如果是转账到微信钱包则需要获取openid
//根据转账方式和会员的授权信息来判断可以使用的转账方式
// $member = (new CoreMemberService())->find($site_id, $cash_out['member_id']);
// if(!empty($member['wx_openid'])){
// $data['openid'] = $member['wx_openid'];
// } else if(!empty($member['weapp_openid'])){
// $data['openid'] = $member['wweapp_openid'];
// }else{
// $data['openid'] = '';
// }
// $data['openid'] = $member['wx_openid'];
$data['transfer_payee'] = $cash_out['transfer_payee'] ?? [];
$data['transfer_payee'] = [
'open_id' => $data['open_id'] ?? '',
'channel' => $data['channel'] ?? '',
];
}
} else {
$transfer_type = $cash_out['transfer_type'];
@ -305,7 +305,7 @@ class CoreMemberCashOutService extends BaseCoreService
$result = (new CoreTransferService())->transfer($site_id, $transfer_no, $transfer_type, $data);
Db::commit();
return true;
return $result;
// 提交事务
} catch (\Exception $e) {
@ -393,4 +393,27 @@ class CoreMemberCashOutService extends BaseCoreService
]);
return true;
}
/**
* 取消提现
* @param int $site_id
* @param int $id
* @return void
*/
public function cancel(int $site_id, int $id){
$cash_out = $this->find($site_id, $id);
if ($cash_out->isEmpty()) throw new CommonException('RECHARGE_LOG_NOT_EXIST');
if ($cash_out['status'] != MemberCashOutDict::WAIT_AUDIT && $cash_out['status'] != MemberCashOutDict::WAIT_TRANSFER && $cash_out['status'] != MemberCashOutDict::TRANSFER_ING) throw new CommonException('CASHOUT_STATUS_NOT_IN_CANCEL');
if($cash_out['transfer_type'] == TransferDict::WECHAT){
if($cash_out['status'] == MemberCashOutDict::TRANSFER_ING){
$core_transfer_service = new CoreTransferService();
$core_transfer_service->cancel($site_id, $cash_out['transfer_no']);
}
}
$cash_out->save([
'status' => MemberCashOutDict::CANCEL,
]);
$this->giveback($site_id, $cash_out);
return true;
}
}

View File

@ -170,9 +170,15 @@ class CoreMemberConfigService extends BaseCoreService
//校验转账方式是否合法
$transfer_type_list = array_keys(TransferDict::getTransferType());
if (array_diff(array_diff($data[ 'transfer_type' ], $transfer_type_list), $transfer_type_list)) throw new CommonException('TRANSFER_TYPE_NOT_EXIST');
foreach ($transfer_type_list as $key => $item) {
if (!in_array($item, $data[ 'transfer_type' ])) {
unset($transfer_type_list[ $key ]);
}
}
$transfer_type_list = array_values($transfer_type_list);
$config = [
'is_open' => $data[ 'is_open' ],//是否启用提现
'transfer_type' => $data[ 'transfer_type' ] ?? [],//提现方式
'transfer_type' => $transfer_type_list ?? [],//提现方式
'min' => $data[ 'min' ] ?? '',//最低提现金额
'is_auto_verify' => $data[ 'is_auto_verify' ] ?? 0, //是否自动审核
'is_auto_transfer' => $data[ 'is_auto_transfer' ] ?? 0, //是否自动转账

View File

@ -11,9 +11,11 @@
namespace app\service\core\niucloud;
use app\dict\addon\AddonDict;
use app\model\addon\Addon;
use app\service\core\addon\CoreAddonBaseService;
use app\service\core\addon\CoreAddonDevelopDownloadService;
use app\service\core\addon\WapTrait;
use core\base\BaseCoreService;
use core\exception\CommonException;
use core\util\niucloud\BaseNiucloudClient;
@ -33,6 +35,8 @@ class CoreCloudBuildService extends BaseCoreService
protected $auth_code;
use WapTrait;
public function __construct()
{
parent::__construct();
@ -69,15 +73,30 @@ class CoreCloudBuildService extends BaseCoreService
]
];
$data['dir']['is_readable'][] = ['dir' => str_replace(project_path(), '', $niucloud_dir), 'status' => is_readable($niucloud_dir)];
$data['dir']['is_readable'][] = ['dir' => str_replace(project_path(), '', $admin_dir), 'status' => is_readable($admin_dir)];
$data['dir']['is_readable'][] = ['dir' => str_replace(project_path(), '', $web_dir), 'status' => is_readable($web_dir)];
$data['dir']['is_readable'][] = ['dir' => str_replace(project_path(), '', $wap_dir), 'status' => is_readable($wap_dir)];
clearstatcache();
$data['dir']['is_write'][] = ['dir' => str_replace(project_path(), '', $niucloud_dir), 'status' => is_write($niucloud_dir) ];
$data['dir']['is_write'][] = ['dir' => str_replace(project_path(), '', $admin_dir), 'status' => is_write($admin_dir) ];
$data['dir']['is_write'][] = ['dir' => str_replace(project_path(), '', $web_dir), 'status' => is_write($web_dir) ];
$data['dir']['is_write'][] = ['dir' => str_replace(project_path(), '', $wap_dir), 'status' => is_write($wap_dir) ];
// 校验niucloud/public niucloud/vendor 目录是否可读可写
$data['dir']['is_readable'][] = ['dir' => str_replace(project_path(), '', public_path()), 'status' => is_readable(public_path())];
$data['dir']['is_readable'][] = ['dir' => str_replace(project_path(), '', $niucloud_dir . 'vendor'), 'status' => is_readable($niucloud_dir . 'vendor')];
$data['dir']['is_write'][] = ['dir' => str_replace(project_path(), '', public_path()), 'status' => is_write(public_path())];
$data['dir']['is_write'][] = ['dir' => str_replace(project_path(), '', $niucloud_dir . 'vendor'), 'status' => is_write($niucloud_dir . 'vendor')];
// 校验niucloud/public下 wap web admin 目录及文件是否可读可写
$check_res = checkDirPermissions(public_path() . 'wap');
$check_res = array_merge2($check_res, checkDirPermissions(public_path() . 'admin'));
$check_res = array_merge2($check_res, checkDirPermissions(public_path() . 'web'));
if (!empty($check_res['unreadable'])) {
foreach ($check_res['unreadable'] as $item) {
$data['dir']['is_readable'][] = ['dir' => str_replace(project_path(), '', $item),'status' => false];
}
}
if (!empty($check_res['not_writable'])) {
foreach ($check_res['not_writable'] as $item) {
$data['dir']['is_write'][] = ['dir' => str_replace(project_path(), '', $item),'status' => false];
}
}
$check_res = array_merge(
array_column($data['dir']['is_readable'], 'status'),
@ -112,6 +131,7 @@ class CoreCloudBuildService extends BaseCoreService
$wap_is_compile = (new Addon())->where([ ['compile', 'like', '%wap%'] ])->field('id')->findOrEmpty();
if ($wap_is_compile->isEmpty()) {
dir_copy($this->root_path . 'uni-app', $package_dir . 'uni-app', exclude_dirs:['node_modules', 'unpackage', 'dist']);
$this->handleUniapp($package_dir . 'uni-app');
}
// 拷贝admin端文件
$admin_is_compile = (new Addon())->where([ ['compile', 'like', '%admin%'] ])->field('id')->findOrEmpty();
@ -155,6 +175,11 @@ class CoreCloudBuildService extends BaseCoreService
return $this->build_task;
}
private function handleUniapp(string $dir) {
$addon = ( new Addon() )->where([ [ 'status', '=', AddonDict::ON ] ])->value('key', '');
$this->compileDiyComponentsCode($dir . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR, $addon);
}
private function handleCustomPort(string $package_dir) {
$addons = get_site_addons();
@ -255,15 +280,15 @@ class CoreCloudBuildService extends BaseCoreService
$zip->extractTo($temp_dir . 'download');
$zip->close();
if (is_dir($temp_dir . 'download' . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'admin')) {
del_target_dir(public_path() .'admin', true);
}
if (is_dir($temp_dir . 'download' . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'web')) {
del_target_dir(public_path() .'web', true);
}
if (is_dir($temp_dir . 'download' . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'wap')) {
del_target_dir(public_path() .'wap', true);
}
// if (is_dir($temp_dir . 'download' . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'admin')) {
// del_target_dir(public_path() .'admin', true);
// }
// if (is_dir($temp_dir . 'download' . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'web')) {
// del_target_dir(public_path() .'web', true);
// }
// if (is_dir($temp_dir . 'download' . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'wap')) {
// del_target_dir(public_path() .'wap', true);
// }
dir_copy($temp_dir . 'download', root_path());

View File

@ -288,5 +288,14 @@ class CorePayEventService extends BaseCoreService
}
/**
* 转账取消
* @param array $param
* @return array
* @throws Exception
*/
public function transferCancel(array $param)
{
return $this->app()->transferCancel($param);
}
}

Some files were not shown because too many files have changed in this diff Show More