This commit is contained in:
CQ 2025-11-21 14:49:09 +08:00
parent 643eadfd14
commit 54510e953d
147 changed files with 11285 additions and 5164 deletions

View File

@ -89,13 +89,6 @@ class ExceptionHandle extends Handle
'previous' => $e->getPrevious(),
] : [];
// 添加自定义异常处理机制
if (strpos($e->getMessage(), 'open_basedir') !== false) {
return fail('OPEN_BASEDIR_ERROR');
}
if (strpos($e->getMessage(), 'Allowed memory size of') !== false) {
return fail('PHP_SCRIPT_RUNNING_OUT_OF_MEMORY');
}
if ($e instanceof DbException) {
return fail(get_lang('DATA_GET_FAIL').':'.$e->getMessage(), [
'file' => $e->getFile(),
@ -122,17 +115,28 @@ class ExceptionHandle extends Handle
}
private function handleException(Throwable $e) {
// 添加自定义异常处理机制
if (strpos($e->getMessage(), 'open_basedir') !== false) {
return fail('OPEN_BASEDIR_ERROR');
}
if (strpos($e->getMessage(), 'Allowed memory size of') !== false) {
return fail('PHP_SCRIPT_RUNNING_OUT_OF_MEMORY');
}
if (preg_match('/^(fopen|file_get_contents|file_put_contents|include|require)\((.+?)\):.*Permission denied/', $e->getMessage(), $matches)) {
$filePath = $matches[2]; // 提取出来的文件路径
return fail("请检查文件{$filePath}是否存在或权限是否正确");
}
$trace = array_map(function ($class){
return str_replace('\\', '/', $class);
}, array_column($e->getTrace(), 'class'));
$debug = env("APP_DEBUG", false);
foreach ($trace as $class) {
if (preg_match('#^addon/([^/]+)/#', $class, $matches)) {
return fail("{$matches[1]}插件内{$class}{$e->getLine()}行出现异常,异常信息:" .$e->getMessage());
return fail("{$matches[1]}插件内{$class}{$e->getLine()}行出现异常,异常信息:" .$e->getMessage(),$debug?$e->getTrace():[]);
}
}
$debug = env("APP_DEBUG", false);
return fail("{$trace[0]}{$e->getLine()}行出现异常,异常信息:" .$e->getMessage(), $debug ? $e->getTrace() : []);
}

View File

@ -52,14 +52,23 @@ class Request extends \think\Request
*/
public function paramFilter($param, bool $filter = true)
{
if (!$param || !$filter || !is_string($param)) return $param;
// 把数据过滤
if (!$param || !$filter || !is_string($param)) {
return $param;
}
// 过滤危险标签
$filter_rule = [
"/<(\\/?)(script|i?frame|style|html|body|title|link|metaf|alert|font|object|\\?|\\%)([^>]*?)>/isU",
"/(<[^>]*)on[a-zA-Z]+\s*=([^>]*>)/isU",
"/<(\\/?)(script|iframe|frame|style|html|body|title|link|meta|alert|font|object|\\?|\\%)([^>]*?)>/isU",
"/(<[^>]*?)on[a-zA-Z]+\s*=[\s\"'][^\"']*?([\s\"'][^>]*?>)/isU",
"/\\b(select|join|where|drop|like|modify|rename|insert|update|table|database|alter|truncate|\'|\/\*|\.\.\/|\.\/|union|into|load_file|outfile)\\b/is"
];
return preg_replace($filter_rule, '', $param);
$replace = [
'', // 移除整个危险标签
'$1$2', // 仅移除 onxxx 属性,保留标签
''
];
return preg_replace($filter_rule, $replace, $param);
}
/**
@ -89,6 +98,7 @@ class Request extends \think\Request
}
}
/**
* 用户账号
* @param string $username
@ -136,6 +146,7 @@ class Request extends \think\Request
return $this->header(system_name('api_token_name'));
}
/**
* 获取场景
* @return array|string

View File

@ -228,6 +228,21 @@ class Addon extends BaseAdminController
return success(( new AddonService() )->getShowMarketingTools());
}
/**
* 统一展示 安装的插件 应用 营销工具等。。
* @return Response
*/
public function showCustomer()
{
return success((new AddonService())->showCustomer());
}
public function getSpecialMenuList()
{
return success('SUCCESS', (new AddonService())->getSpecialMenuList());
}
/**
* 获取首页应用标签
* @description 获取首页应用标签

View File

@ -75,7 +75,7 @@ class AddonDevelop extends BaseAdminController
/**
* 开发插件更新
* @description 开发插件更新
* @param string $id
* @param string $key
* @return Response
*/
public function edit(string $key)
@ -101,7 +101,7 @@ class AddonDevelop extends BaseAdminController
/**
* 删除开发插件
* @description 删除开发插件
* @param $key
* @param string $key
* @return Response
*/
public function del(string $key)
@ -114,7 +114,7 @@ class AddonDevelop extends BaseAdminController
* 校验key是否被占用
* @description 校验key是否被占用
* @param $key
* @return void
* @return Response
*/
public function checkKey($key)
{

View File

@ -78,7 +78,7 @@ class Backup extends BaseAdminController
/**
* 恢复备份
* @description 恢复备份
* @return Response
* @return array
*/
public function restoreBackup()
{
@ -107,7 +107,7 @@ class Backup extends BaseAdminController
/**
* 手动备份
* @description 手动备份
* @return Response
* @return array
*/
public function manualBackup()
{

View File

@ -12,7 +12,11 @@
namespace app\adminapi\controller\auth;
use app\service\admin\auth\AuthService;
use app\service\admin\auth\AuthSiteService;
use core\base\BaseAdminController;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Response;
@ -31,12 +35,7 @@ class Auth extends BaseAdminController
*/
public function authMenuList()
{
$data = $this->request->params([
[ 'status', 1 ],
[ 'is_tree', 1 ],
[ 'is_button', 1 ]
]);
return success(( new AuthService() )->getAuthMenuList($data[ 'status' ], $data[ 'is_tree' ], $data[ 'is_button' ]));
return success((new AuthService())->getAuthMenuList(1, 1));
}
/**

View File

@ -11,6 +11,7 @@
namespace app\adminapi\controller\channel;
use app\dict\channel\AppDict;
use app\service\admin\channel\AppService;
use app\service\admin\channel\H5Service;
use core\base\BaseAdminController;
@ -43,8 +44,117 @@ class App extends BaseAdminController
$data = $this->request->params([
['wechat_app_id', ""],
['wechat_app_secret', ""],
['android_app_key', ''],
['application_id', ''],
['uni_app_id', ''],
['app_name', '']
]);
(new AppService())->setConfig($data);
return success('SET_SUCCESS');
}
public function versionList() {
$data = $this->request->params([
["platform",""],
]);
return success((new AppService())->getVersionPage($data));
}
public function versionInfo($id) {
return success((new AppService())->getVersionInfo($id));
}
/**
* 添加app版本
* @description 添加app版本
* @return \think\Response
*/
public function add(){
$data = $this->request->params([
["version_code",""],
["version_name",""],
["version_desc",""],
["platform",""],
["is_forced_upgrade",0],
["package_path", ""],
["package_type", ""],
["build", []],
["cert", []],
["upgrade_type", ""],
]);
$id = (new AppService())->addVersion($data);
return success('ADD_SUCCESS', ['id' => $id]);
}
/**
* app版本管理编辑
* @description 编辑app版本
* @param $id app版本id
* @return \think\Response
*/
public function edit(int $id){
$data = $this->request->params([
["version_code",""],
["version_name",""],
["version_desc",""],
["platform",""],
["is_forced_upgrade",0],
["package_path", ""],
["package_type", ""],
["build", []],
["cert", []],
["upgrade_type", ""],
]);
(new AppService())->editVersion($id, $data);
return success('EDIT_SUCCESS');
}
/**
* app版本管理删除
* @description 删除app版本
* @param $id app版本id
* @return \think\Response
*/
public function del(int $id){
(new AppService())->delVersion($id);
return success('DELETE_SUCCESS');
}
public function appPlatform() {
return success(AppDict::getAppPlatform());
}
/**
* 获取app生成日志
*/
public function buildLog(string $key) {
return success((new AppService())->getBuildLog($key));
}
/**
* 发布
* @description 发布
* @param $id app版本id
* @return \think\Response
*/
public function release(int $id) {
(new AppService())->release($id);
return success('RELEASE_SUCCESS');
}
public function generateSingCert() {
$data = $this->request->params([
['key_alias', ''],
['key_password', ''],
['store_password', ''],
['limit', 30],
['cn', ''],
['o', ''],
['ou', ''],
['c', ''],
['st', ''],
['l', ''],
]);
return success(data:(new AppService())->generateSingCert($data));
}
}

View File

@ -44,6 +44,8 @@ class Config extends BaseAdminController
$data = $this->request->params([
['is_captcha', 0],
['bg', ''],
['login_logo', ''],
['login_bg_img', ''],
]);
(new ConfigService())->setConfig($data);
return success('MODIFY_SUCCESS');

View File

@ -35,7 +35,7 @@ class Transfer extends BaseAdminController
* 设置场景id
* @description 设置场景id
* @param $scene
* @return void
* @return \think\Response
*/
public function setSceneId($scene){
$data = $this->request->params([

View File

@ -74,7 +74,7 @@ class Area extends BaseAdminController
/**
* 根据code获取地址信息
* @description 根据code获取地址信息
* @return void
* @return Response
*/
public function areaByAreaCode(string $code) {
return success((new AreaService())->getAreaByAreaCode($code));

View File

@ -134,6 +134,7 @@ class Config extends BaseAdminController
{
$data = $this->request->params([
[ 'key', '' ],
[ 'amap_key', ''],
[ 'is_open', 0 ], // 是否开启定位
[ 'valid_time', 0 ] // 定位有效期/分钟过期后将重新获取定位信息0为不过期
]);
@ -187,6 +188,56 @@ class Config extends BaseAdminController
return success();
}
/**
* 设置布局设置
* @description 设置布局设置
* @return Response
*/
public function setLayout()
{
$data = $this->request->params([
[ 'key', '' ],
[ 'value', '' ],
]);
( new ConfigService() )->setLayout($data);
return success();
}
/**
* 获取布局设置
* @description 获取布局设置
* @return Response
*/
public function getLayout()
{
return success(data: ( new ConfigService() )->getLayout());
}
/**
* 设置色调设置
* @description 设置色调设置
* @return Response
*/
public function setThemeColor()
{
$data = $this->request->params([
[ 'key', '' ],
[ 'value', '' ],
]);
( new ConfigService() )->setThemeColor($data);
return success();
}
/**
* 获取色调设置
* @description 获取色调设置
* @return Response
*/
public function getThemeColor()
{
return success(data: ( new ConfigService() )->getThemeColor());
}
/**
* 获取install.php配置
* @return Response

View File

@ -79,7 +79,7 @@ class Export extends BaseAdminController
/**
* 获取导出状态列表
* @description 获取导出状态列表
* @param string $type
* @return Response
*/
public function getExportStatus()
{

View File

@ -94,6 +94,21 @@ class Role extends BaseAdminController
return success('EDIT_SUCCESS');
}
/**
* 修改状态
* @description 修改状态
* @return \think\Response
*/
public function modifyStatus()
{
$data = $this->request->params([
[ 'role_id', '' ],
[ 'status', '' ],
]);
( new RoleService() )->modifyStatus($data);
return success('SUCCESS');
}
/**
* 删除单个用户组
* @description 删除单个用户组
@ -107,19 +122,4 @@ class Role extends BaseAdminController
return success('DELETE_SUCCESS');
}
/**
* 设置角色状态
* @description 设置角色状态
* @param $role_id
* @return Response
*/
public function modifyStatus($role_id)
{
$data = $this->request->params([
['status', RoleStatusDict::ON],
]);
(new RoleService())->modifyStatus($role_id, $data['status']);
return success('DELETE_SUCCESS');
}
}

View File

@ -14,13 +14,13 @@ namespace app\adminapi\controller\user;
use app\dict\sys\UserDict;
use app\service\admin\user\UserService;
use core\base\BaseAdminController;
use Exception;
use think\Response;
/**
* 站点用户接口
* @description 站点用户
* 用户管理
* Class User
* @description 用户管理
* @package app\adminapi\controller\user
*/
class User extends BaseAdminController
{
@ -37,28 +37,25 @@ class User extends BaseAdminController
['role', ''],
['create_time', []],
]);
$list = (new UserService())->getPage($data);
return success($list);
}
/**
* 用户详情
* @description 用户详情
* @param $uid
* @return Response
*/
public function info($uid)
{
if(!is_numeric($uid))
{
$uid = 0;
}
return success((new UserService())->getInfo($uid));
}
/**
* 获取全部用户
* @description 获取全部用户
* 获取用户列表
* @description 获取用户列表
* @return Response
*/
public function getUserAll()
@ -73,92 +70,141 @@ class User extends BaseAdminController
}
/**
* 新增用户
* @description 新增用户
* 获取用户下拉框
* @description 获取用户下拉框
* @return Response
* @throws Exception
*/
public function add()
public function getUserSelect()
{
$data = $this->request->params([
['username', '']
]);
$list = (new UserService())->getUserSelect($data);
return success($list);
}
/**
* 检查用户是否存在
* @description 检查用户是否存在
* @return Response
* @throws \think\db\exception\DbException
*/
public function checkUserIsExist() {
$data = $this->request->params([
['username', ''],
]);
$is_exist = (new UserService())->checkUsername($data['username']);
return success(data:$is_exist);
}
/**
* 添加用户
* @description 添加用户
* @return Response
* @throws \Exception
*/
public function add() {
$data = $this->request->params([
['username', ''],
['password', ''],
['mobile', ''],
['real_name', ''],
['head_img', ''],
['status', UserDict::ON],
['role_ids', []]
]);
$this->validate($data, 'app\validate\sys\User.add');
$uid = (new UserService())->addUser($data);
return success('ADD_SUCCESS', ['uid' => $uid]);
(new UserService())->add($data);
return success();
}
/**
* 更新用户
* @description 更新用户
* 编辑用户
* @description 编辑用户
* @return Response
* @throws \Exception
*/
public function edit($uid)
{
public function edit($uid) {
$data = $this->request->params([
['password', ''],
['mobile', ''],
['real_name', ''],
['head_img', ''],
['status', UserDict::ON],
['role_ids', []],
['password', '']
]);
(new UserService())->editUser($uid, $data);
return success('MODIFY_SUCCESS');
(new UserService())->edit($uid, $data);
return success();
}
/**
* 更新字段
* @description 更新字段
* @param $uid
* @param $field
* @return Response
*/
public function modify($uid, $field)
{
$data = $this->request->params([
['value', ''],
['field', $field]
]);
$data[$field] = $data['value'];
// $this->validate($data, 'app\validate\sys\User.modify');
(new UserService())->modify($uid, $field, $data['value']);
return success('MODIFY_SUCCESS');
}
/**
* 删除单个用户
* @description 删除单个用户
* 删除用户
* @description 删除用户
* @param $uid
* @return Response
*/
public function del($uid)
{
public function del($uid) {
(new UserService())->del($uid);
return success('DELETE_SUCCESS');
return success("DELETE_SUCCESS");
}
/**
* 锁定用户
* @description 锁定用户
* 获取用户站点创建限制
* @description 获取用户站点创建限制
* @param $uid
* @return Response
*/
public function lock($uid)
{
(new UserService())->lock($uid);
return success('MODIFY_SUCCESS');
public function getUserCreateSiteLimit($uid){
return success(data:(new UserService())->getUserCreateSiteLimit($uid));
}
/**
* 解锁用户
* @description 解锁用户
* 获取用户站点创建限制
* @description 获取用户站点创建限制
* @param $id
* @return Response
*/
public function unlock($uid)
{
(new UserService())->unlock($uid);
return success('MODIFY_SUCCESS');
public function getUserCreateSiteLimitInfo($id){
return success(data:(new UserService())->getUserCreateSiteLimitInfo($id));
}
/**
* 添加用户站点创建限制
* @description 添加用户站点创建限制
* @param $uid
* @return Response
*/
public function addUserCreateSiteLimit($uid){
$data = $this->request->params([
['uid', 0],
['group_id', 0],
['num', 1],
['month', 1],
]);
(new UserService())->addUserCreateSiteLimit($data);
return success('SUCCESS');
}
/**
* 编辑用户站点创建限制
* @description 编辑用户站点创建限制
* @param $id
* @return Response
*/
public function editUserCreateSiteLimit($id){
$data = $this->request->params([
['num', 1],
['month', 1],
]);
(new UserService())->editUserCreateSiteLimit($id, $data);
return success('SUCCESS');
}
/**
* 删除用户站点创建限制
* @description 删除用户站点创建限制
* @param $id
* @return Response
*/
public function delUserCreateSiteLimit($id){
(new UserService())->delUserCreateSiteLimit($id);
return success('SUCCESS');
}
}

View File

@ -56,5 +56,45 @@ class Config extends BaseAdminController
return success('SET_SUCCESS');
}
/**
* 设置微信小程序域名
* @description 设置微信小程序域名
* @return Response
*/
public function setDomain() {
$data = $this->request->params([
['requestdomain', ''],
['wsrequestdomain', ''],
['uploaddomain', ''],
['downloaddomain', ''],
['udpdomain', ''],
['tcpdomain', '']
]);
(new WeappConfigService())->setDomain($data);
return success('SET_SUCCESS');
}
/**
* 获取微信小程序隐私协议
* @description 获取微信小程序隐私协议
* @return Response
*/
public function getPrivacySetting() {
return success((new WeappConfigService())->getPrivacySetting());
}
/**
* 设置微信小程序隐私协议
* @description 设置微信小程序隐私协议
* @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

@ -24,7 +24,7 @@ class Delivery extends BaseAdminController
/**
* 查询小程序是否已开通发货信息管理服务
* @description 查询小程序是否已开通发货信息管理服务
* @return bool
* @return \think\Response
* @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
*/
public function getIsTradeManaged()

View File

@ -53,7 +53,8 @@ class Version extends BaseAdminController
public function add()
{
$data = $this->request->params([
['desc', '']
['desc', ''],
['version', '']//特殊指定版本号
]);
return success(data:(new WeappVersionService())->add($data));
}

View File

@ -42,7 +42,8 @@ class Config extends BaseAdminController
['token', ''],
['encoding_aes_key', ''],
['qr_code', ''],
['encryption_type', '']
['encryption_type', ''],
['base_uri', '']
]);
$this->validate($data, 'app\validate\channel\Wechat.set');
(new WechatConfigService())->setWechatConfig($data);

View File

@ -27,6 +27,7 @@ class AdminCheckRole
{
$check_role_service = new AuthService();
$check_role_service->checkRole($request);
//处理用户的权限
return $next($request);
}

View File

@ -16,6 +16,8 @@ use app\Request;
use app\service\admin\user\UserLogService;
use Closure;
use ReflectionClass;
use think\facade\Log;
use think\facade\Route;
/**
* admin用户操作日志
@ -29,6 +31,7 @@ class AdminLog
//写入日志
if ($request->method() != 'GET') {
$path = $request->rule()->getRoute();
try {
if (strstr($path, '@')) {
$arr = explode('@', $path);
$controller = $arr[0] ?? "";
@ -36,13 +39,20 @@ class AdminLog
} else {
//暂时只有APP目录下使用这样的路由定义
list($controllerStr, $action) = explode('/', $path, 2);
list($module, $controller) = explode('.', $controllerStr, 2);
$parts = preg_split('/[\.\\\\]/', $controllerStr, 2);
list($module, $controller) = $parts;
if (count($parts) >= 2) {
// 拼接完整类名(根据 TP 命名空间规则调整)
$controllerClass = "app\\adminapi\\controller\\{$module}\\{$controller}";
$controller = $controllerClass;
}
}
$operation = $this->extractDescFromAnnotation($controller, $action);
} catch (\Exception $e) {
$operation = "";
Log::write('获取路由描述错误:path' . $path . ' error' . $e->getMessage());
}
$data = [
'uid' => $request->uid(),
'username' => $request->username(),

View File

@ -27,13 +27,13 @@ Route::group(function () {
Route::get('addon/:id', 'addon.Addon/info');
//安装插件
Route::post('addon/install/:addon', 'addon.Addon/install');
Route::post('addon/install/:addon', 'addon.Addon/install')->pattern(['addon' => '[\w|\,]+']);
//云安装插件
Route::post('addon/cloudinstall/:addon', 'addon.Addon/cloudInstall');
Route::post('addon/cloudinstall/:addon', 'addon.Addon/cloudInstall')->pattern(['addon' => '[\w|\,]+']);
// 云编译进度
Route::get('addon/cloudinstall/:addon', 'addon.Addon/cloudInstallLog');
Route::get('addon/cloudinstall/:addon', 'addon.Addon/cloudInstallLog')->pattern(['addon' => '[\w|\,]+']);
//插件安装检测安装环境
Route::get('addon/install/check/:addon', 'addon.Addon/installCheck');
Route::get('addon/install/check/:addon', 'addon.Addon/installCheck')->pattern(['addon' => '[\w|\,]+']);
// 获取安装任务
Route::get('addon/installtask', 'addon.Addon/getInstallTask');
//下载插件
@ -77,6 +77,9 @@ Route::group(function () {
Route::post('addon_develop/download/:key', 'addon.AddonDevelop/download');
//插件标识黑名单
Route::get('addon_develop/key/blacklist', 'addon.AddonDevelop/keyBlackList');
// 获取应用列表
Route::get('addon/showCustomer', 'addon.Addon/showCustomer');
Route::get('addon/special_menu', 'addon.Addon/getSpecialMenuList');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,
@ -89,8 +92,7 @@ Route::group(function () {
Route::group(function () {
//获取已安装插件列表
Route::get('addon/list/install', 'addon.Addon/getInstallList');
// 获取应用列表
Route::get('addon/list/showapp', 'addon.Addon/showApp');
// 获取营销列表
Route::get('addon/list/showApp', 'addon.Addon/showApp');
Route::get('showMarketing', 'addon.Addon/showMarketing');
});

View File

@ -24,12 +24,15 @@ Route::group('auth', function () {
/***************************************************** 授权信息 ****************************************************/
//授权用户站点菜单
Route::get('authmenu', 'auth.Auth/authMenuList');
//授权用户站点应用
Route::get('authaddon', 'auth.Auth/getAuthAddonList');
//授权用户信息
Route::get('get', 'auth.Auth/get');
//授权用户信息
Route::put('edit', 'auth.Auth/edit');
//授权用户信息
Route::put('modify/:field', 'auth.Auth/modify');
//授权用户信息
Route::put('edit', 'auth.Auth/edit');
})->middleware([
AdminCheckToken::class,
AdminCheckRole::class,

View File

@ -33,6 +33,24 @@ Route::group('channel', function () {
Route::get('app/config', 'channel.App/get');
//设置手机端配置
Route::put('app/config', 'channel.App/set');
// 获取app版本列表
Route::get('app/version', 'channel.App/versionList');
// 获取app版本详情
Route::get('app/version/:id', 'channel.App/versionInfo');
// 添加app版本
Route::post('app/version', 'channel.App/add');
// 编辑app版本
Route::put('app/version/:id', 'channel.App/edit');
// 删除app版本
Route::delete('app/version/:id', 'channel.App/del');
// 获取app平台
Route::get('app/platfrom', 'channel.App/appPlatform');
// 获取app生成日志
Route::get('app/build/log/:key', 'channel.App/buildLog');
// 发布
Route::put('app/version/:id/release', 'channel.App/release');
// 生成证书
Route::post('app/generate_sing_cert', 'channel.App/generateSingCert');
})->middleware([
AdminCheckToken::class,

View File

@ -149,9 +149,9 @@ Route::group('member', function() {
//全部会员等级
Route::get('level/all', 'member.MemberLevel/getAll');
// 获取会员权益内容
Route::get('benefits/content', 'member.Member/getMemberBenefitsContent');
Route::post('benefits/content', 'member.Member/getMemberBenefitsContent');
// 获取会员礼包内容
Route::get('gifts/content', 'member.Member/getMemberGiftsContent');
Route::post('gifts/content', 'member.Member/getMemberGiftsContent');
/***************************************************** 会员签到 ****************************************************/
//签到设置
Route::put('sign/config', 'member.MemberSign/setSign');

View File

@ -39,8 +39,6 @@ Route::group('sys', function() {
Route::put('role/:role_id', 'sys.Role/edit');
//删除用户组
Route::delete('role/:role_id', 'sys.Role/del');
// 修改用户组状态
Route::put('role/status', 'sys.Role/modifyStatus');
/***************************************************** 菜单 ****************************************************/
//菜单新增
Route::post('menu', 'sys.Menu/add');
@ -67,8 +65,6 @@ Route::group('sys', function() {
Route::get('menu/system_menu', 'sys.Menu/getSystem');
Route::get('menu/addon_menu/all', 'sys.Menu/getAllAddonMenu');
Route::get('menu/addon_menu/:app_key', 'sys.Menu/getAddonMenu');
Route::get('menu/dir/:addon', 'sys.Menu/getMenuByTypeDir');
@ -99,6 +95,16 @@ Route::group('sys', function() {
// 开发者key
Route::get('config/developer_token', 'sys.Config/getDeveloperToken');
// 布局设置
Route::get('config/layout', 'sys.Config/getLayout');
// 布局设置
Route::put('config/layout', 'sys.Config/setLayout');
// 色调设置
Route::get('config/themecolor', 'sys.Config/getThemeColor');
// 色调设置
Route::put('config/themecolor', 'sys.Config/setThemeColor');
/***************************************************** 图片上传 ****************************************************/
//附件图片上传
Route::post('image', 'upload.Upload/image');
@ -342,6 +348,8 @@ Route::group('sys', function() {
Route::get('web/website', 'sys.Config/getWebsite');
// 获取版权信息
Route::get('web/copyright', 'sys.Config/getCopyright');
// 查询布局设置
Route::get('web/layout', 'sys.Config/getLayout');
// 获取install.php配置
Route::get('install/config', 'sys.Config/getInstallConfig');
});

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

@ -11,6 +11,7 @@
namespace app\api\controller\channel;
use app\service\api\channel\AppService;
use app\service\api\login\LoginService;
use app\service\api\wechat\WechatAppService;
use core\base\BaseController;
@ -53,10 +54,20 @@ class App extends BaseController
'mobile' => 'mobile'
]);
// 校验手机验证码(电脑端扫码)
// 校验手机验证码
( new LoginService() )->checkMobileCode($data[ 'mobile' ]);
$wechat_app_service = new WechatAppService();
return success($wechat_app_service->register($data[ 'openid' ], $data[ 'mobile' ], $data[ 'nickname' ], $data[ 'avatar' ], $data[ 'avatar' ]));
}
public function getNewVersion()
{
$data = $this->request->params([
[ 'version_code', '' ], // 当前版本
[ 'platform', '' ], // 请求平台
]);
$app_service = new AppService();
return success(data:$app_service->getNewVersion($data));
}
}

View File

@ -51,7 +51,7 @@ class Pay extends BaseApiController
['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']));
return success('SUCCESS',(new PayService())->pay($data['type'], $data['trade_type'], (int)$data['trade_id'], $data['return_url'], $data['quit_url'], $data['buyer_id'], $data['voucher'], $data['openid']));
}
public function info($trade_type, $trade_id)

View File

@ -13,10 +13,6 @@ 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;
/**
* 微信服务端通信以及网页授权
@ -27,7 +23,7 @@ class Transfer extends BaseApiController
/**
* 确认收款
* @return Response
* @return void
*/
public function confirm($transfer_no)
{

View File

@ -81,14 +81,18 @@ class Config extends BaseApiController
['url', ''],
['openid', '']
]);
$config_service = new ConfigService();
$res = [];
$res['tabbar_list'] = (new DiyConfigService())->getBottomList();
$res[ 'map_config' ] = ( new ConfigService() )->getMap();
$res[ 'site_info' ] = ( new ConfigService() )->getWebSite();
$res['map_config'] = $config_service->getMap();
$res['site_info'] = $config_service->getWebSite();
$res[ 'site_info' ]['wap_url'] = $config_service->getSceneDomain()['wap_url'];
$res['member_level'] = (new MemberLevelService())->getList();
$res['login_config'] = (new MemberConfigService())->getLoginConfig($data['url']);
$res['theme_list'] = (new DiyService())->getDiyTheme();
$res['app_config'] = $config_service->getAppConfig();
$res['copyright'] = $config_service->getCopyright();
$openid_field = match ($this->request->getChannel()) {
'wechat' => 'wx_openid',
'weapp' => 'weapp_openid',

View File

@ -13,6 +13,7 @@ namespace app\api\controller\wechat;
use app\service\api\login\LoginService;
use app\service\api\wechat\WechatAuthService;
use app\service\api\wechat\WechatConfigService;
use core\base\BaseController;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
@ -140,6 +141,16 @@ class Wechat extends BaseController
return success($wechat_auth_service->scanLogin());
}
/**
* 检查微信公众号是否配置
* @return Response
*/
public function checkWechatConfig()
{
return success('SUCCESS', (new WechatConfigService())->checkWechatConfig());
}
/**
* 更新openid
* @return Response

View File

@ -73,6 +73,9 @@ Route::group(function () {
// app通过wx code登录
Route::post('wxapp/login', 'channel.App/wechatLogin');
// 获取App新的版本
Route::get('app/newversion', 'channel.App/getNewVersion');
//登录
Route::get('login', 'login.Login/login');
//第三方绑定
@ -153,6 +156,7 @@ Route::group(function () {
Route::get('task/growth', 'sys.Task/growth');
// 获取积分任务
Route::get('task/point', 'sys.Task/point');
})->middleware(ApiChannel::class)
->middleware(ApiCheckToken::class)
->middleware(ApiLog::class);

View File

@ -0,0 +1,30 @@
<?php
declare (strict_types=1);
namespace app\command;
use app\upgrade\v156\Upgrade;
use think\console\Command;
use think\console\Input;
use think\console\Output;
class RefreshBottom extends Command
{
public function configure()
{
// 指令配置
$this->setName('refresh:bottom')
->setDescription('升级156版本底部导航异常刷新底部导航。');
}
/**
* 执行任务
* @return void
*/
protected function execute(Input $input, Output $output)
{
$output->writeln('开始处理');
(new Upgrade())->handle();
$output->writeln('刷新完成,请重新发布小程序');
}
}

View File

@ -0,0 +1,26 @@
<?php
declare (strict_types = 1);
namespace app\command;
use app\service\admin\auth\LoginService;
use think\console\Command;
use think\console\Input;
use think\console\Output;
class Resetpassword extends Command
{
protected function configure()
{
// 指令配置
$this->setName('reset')
->setDescription('the reset administrator password command');
}
protected function execute(Input $input, Output $output)
{
LoginService::resetAdministratorPassword();
// 指令输出
$output->writeln('password reset success');
}
}

View File

@ -0,0 +1,27 @@
<?php
declare (strict_types = 1);
namespace app\command;
use app\job\refreshArea;
use app\service\admin\auth\LoginService;
use think\console\Command;
use think\console\Input;
use think\console\Output;
class refreshAreaCommand extends Command
{
protected function configure()
{
// 指令配置
$this->setName('refreshArea')
->setDescription('更新地区命令');
}
protected function execute(Input $input, Output $output)
{
(new refreshArea())->execute($output);
// 指令输出
$output->writeln('地区更新成功');
}
}

View File

@ -774,7 +774,7 @@ function project_path()
/**
* 图片转base64
* @param string $path
* @param $is_delete `转换后是否删除原图`
* @param $is_delete 转换后是否删除原图
* @return string
*/
function image_to_base64(string $path, $is_delete = false)
@ -897,7 +897,7 @@ function file_copy(string $source_file, string $to_file)
function qrcode($url, $page, $data, $dir = '', $channel = 'h5', $style = ['is_transparent' => true], $outfile = true)
{
if ($outfile) {
$dir = $dir ? : 'upload' . '/' . 'qrcode/';//二维码默认存储位置
$dir = $dir ?: 'upload' . '/' . 'qrcode' ;//二维码默认存储位置
if (!is_dir($dir) && !mkdir($dir, 0777, true) && !is_dir($dir)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $dir));
}
@ -1051,9 +1051,9 @@ function get_last_time($time = null)
/**
* 检查目录及其子目录的权限
* @param $dir `要检查的目录路径`
* @param $dir 要检查的目录路径
* @param $data
* @param $exclude_dir `排除排除无需检测的的文件夹`
* @param $exclude_dir 排除排除无需检测的的文件夹
* @return array|array[]|mixed
*/
function checkDirPermissions($dir, $data = [], $exclude_dir = [])
@ -1116,8 +1116,8 @@ function checkDirPermissions($dir, $data = [], $exclude_dir = [])
/**
* 下载网络图片
* @param $img_url `图片URL`
* @param $file_name `本地保存位置`
* @param $img_url 图片URL
* @param $file_name 本地保存位置
* @return bool
*/
function downloadImage($img_url, $file_name)

View File

@ -0,0 +1,56 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\dict\channel;
class AppDict
{
// ********** 平台类型 **************
const ANDROID = 'android';
const IOS = 'ios';
public static function getAppPlatform() {
return [
self::ANDROID => 'Android',
// self::IOS => 'ios'
];
}
public static function getAppPlatformName($platform) {
$app_platform = self::getAppPlatform();
return $app_platform[$platform] ?? '';
}
// ********** 版本状态 **************
const STATUS_UPLOAD_SUCCESS = 'upload_success';
const STATUS_CREATE_FAIL = 'create_fail';
const STATUS_PUBLISHED = 'published';
const STATUS_CREATING = 'creating';
public static function getStatus() {
return [
self::STATUS_UPLOAD_SUCCESS => '上传成功',
self::STATUS_CREATE_FAIL => '创建失败',
self::STATUS_PUBLISHED => '已发布',
self::STATUS_CREATING => '创建中'
];
}
public static function getStatusName($status) {
return self::getStatus()[$status] ?? '';
}
}

View File

@ -26,8 +26,10 @@ class CommonActiveDict
const EXCHANGE = 'exchange';// 积分商城 积
const MANJIANSONG = 'manjiansong'; // 满减送 满减
const NEWCOMER_DISCOUNT = 'newcomer_discount'; // 新人专享 新
const FRIEND_HELP = 'friend_help'; // 好友助力 友
const PINTUAN = 'pintuan'; // 新人专享 新
const SECKILL = 'seckill'; // 秒杀 秒
const RELAY = 'relay'; // 接龙 接
public static function getActiveShort($active = '')
{
@ -72,6 +74,16 @@ class CommonActiveDict
'active_name' => get_lang('common_active_short.pintuan_name'),
'bg_color' => '#FF1C77'
],
self::RELAY => [
'name' => get_lang('common_active_short.relay_short'),
'active_name' => get_lang('common_active_short.relay_name'),
'bg_color' => '#0EB108'
],
self::FRIEND_HELP => [
'name' => get_lang('common_active_short.friend_help_short'),
'active_name' => get_lang('common_active_short.friend_help_name'),
'bg_color' => '#F20C8A'
],
];
return !empty($active) ? $data[$active] ?? [] : $data;
}

View File

@ -150,7 +150,16 @@ class PagesDict
'imgHeight' => '',
"bottomTabBar" => [
'control' => true,
'isShow' => true
'isShow' => true,
'designNav' => [
'title' => '',
'key' => ''
]
],
"copyright" => [
'control' => true,
'isShow' => false,
'textColor' =>'#ccc'
],
"template" => [
'textColor' => "#303133",
@ -225,7 +234,16 @@ class PagesDict
'imgHeight' => '',
"bottomTabBar" => [
'control' => true,
'isShow' => true
'isShow' => true,
'designNav' => [
'title' => '',
'key' => ''
]
],
"copyright" => [
'control' => true,
'isShow' => false,
'textColor' =>'#ccc'
],
"template" => [
'textColor' => "#303133",
@ -694,7 +712,16 @@ class PagesDict
'imgHeight' => 403,
"bottomTabBar" => [
'control' => true,
'isShow' => true
'isShow' => true,
'designNav' => [
'title' => '',
'key' => ''
],
],
"copyright" => [
'control' => true,
'isShow' => false,
'textColor' =>'#ccc'
],
"template" => [
'textColor' => "#303133",

View File

@ -79,7 +79,16 @@ class TemplateDict
],
"bottomTabBar" => [
'control' => true,
'isShow' => true
'isShow' => true,
'designNav' => [
'title' => '',
'key' => ''
]
],
"copyright" => [
'control' => true,
'isShow' => false,
'textColor' =>'#ccc'
],
"popWindow" => [
"imgUrl" => "",
@ -724,7 +733,16 @@ class TemplateDict
],
"bottomTabBar" => [
'control' => true,
'isShow' => true
'isShow' => true,
'designNav' => [
'title' => '',
'key' => ''
]
],
"copyright" => [
'control' => true,
'isShow' => false,
'textColor' =>'#ccc'
],
"popWindow" => [
"imgUrl" => "",

View File

@ -24,7 +24,6 @@ class MemberRegisterChannelDict extends ChannelDict
public static function getType($type = '')
{
$data = ChannelDict::getType($type);
$data[self::MANUAL] = get_lang('dict_member.register_manual');//手动添加
if (empty($type)) {

View File

@ -0,0 +1,62 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\dict\menu;
/**
* 菜单类
* Class MenuDict
* @package app\dict\sys
*/
class MenuDict
{
public const ADDON_CHILD_MENU_DICT_SYSTEM_TOOL = 'system_tool';
public const ADDON_CHILD_MENU_DICT_MARKING_TOOL = 'marketing_tool';
public const ADDON_CHILD_MENU_DICT_MARKING_ACTIVE = 'marketing_active';
public const ADDON_CHILD_MENU_DICT_ADDON_TOOL = 'addon_tool';
/**
* 站点应用管理特殊子菜单
* @return array
*/
public static function getAddonChildMenu()
{
//注意 sort 倒序排序使用
return [
self::ADDON_CHILD_MENU_DICT_SYSTEM_TOOL => [
'key' => self::ADDON_CHILD_MENU_DICT_SYSTEM_TOOL,
'name' => get_lang('dict_addon_menu.system_tool'),
'short_name' => get_lang('dict_addon_menu.system_tool_short'),
'sort' => 97
],
self::ADDON_CHILD_MENU_DICT_MARKING_TOOL => [
'key' => self::ADDON_CHILD_MENU_DICT_MARKING_TOOL,
'name' => get_lang('dict_addon_menu.marking_tool'),
'short_name' => get_lang('dict_site.marking_tool_short'),
'sort' => 99
],
self::ADDON_CHILD_MENU_DICT_MARKING_ACTIVE => [
'key' => self::ADDON_CHILD_MENU_DICT_MARKING_ACTIVE,
'name' => get_lang('dict_addon_menu.marking_active'),
'short_name' => get_lang('dict_addon_menu.marking_active_short'),
'sort' => 100
],
self::ADDON_CHILD_MENU_DICT_ADDON_TOOL => [
'key' => self::ADDON_CHILD_MENU_DICT_ADDON_TOOL,
'name' => get_lang('dict_addon_menu.addon_tool'),
'short_name' => get_lang('dict_addon_menu.addon_tool_short'),
'sort' => 98
],
];
}
}

View File

@ -1073,37 +1073,37 @@ return [
],
],
],
[
'menu_name' => '营销管理',
'menu_key' => 'active',
'menu_short_name' => '营销',
'parent_key' => '',
'menu_type' => '0',
'icon' => 'iconfont iconyingxiao2',
'api_url' => '',
'router_path' => 'app/marketing',
'view_path' => '',
'methods' => '',
'sort' => '87',
'status' => '1',
'is_show' => '1',
'children' => [
[
'menu_name' => '营销列表',
'menu_key' => 'marketing_list',
'menu_short_name' => '营销列表',
'menu_type' => '1',
'icon' => 'iconfont iconmanage-apply',
'api_url' => 'marketing/list',
'router_path' => 'app/marketing',
'view_path' => 'app/marketing',
'methods' => 'get',
'sort' => '160',
'status' => '1',
'is_show' => '1',
],
],
],
// [
// 'menu_name' => '营销管理',
// 'menu_key' => 'active',
// 'menu_short_name' => '营销',
// 'parent_key' => '',
// 'menu_type' => '0',
// 'icon' => 'iconfont iconyingxiao2',
// 'api_url' => '',
// 'router_path' => 'app/marketing',
// 'view_path' => '',
// 'methods' => '',
// 'sort' => '87',
// 'status' => '1',
// 'is_show' => '1',
// 'children' => [
// [
// 'menu_name' => '营销列表',
// 'menu_key' => 'marketing_list',
// 'menu_short_name' => '营销列表',
// 'menu_type' => '1',
// 'icon' => 'iconfont iconmanage-apply',
// 'api_url' => 'marketing/list',
// 'router_path' => 'app/marketing',
// 'view_path' => 'app/marketing',
// 'methods' => 'get',
// 'sort' => '160',
// 'status' => '1',
// 'is_show' => '1',
// ],
// ],
// ],
[
'menu_name' => '核销管理',
'menu_key' => 'verify',
@ -1225,7 +1225,7 @@ return [
'menu_name' => '签到管理',
'menu_key' => 'sign',
'menu_short_name' => '签到管理',
'parent_key' => 'active',
'parent_key' => 'addon',
'menu_type' => '0',
'icon' => 'element FolderChecked',
'api_url' => '',
@ -1290,8 +1290,8 @@ return [
'menu_type' => '0',
'icon' => 'iconfont iconyingyong21',
'api_url' => '',
'router_path' => '',
'view_path' => '',
'router_path' => 'app/index',
'view_path' => 'app/index',
'methods' => '',
'sort' => '86',
'status' => '1',
@ -1307,7 +1307,7 @@ return [
'router_path' => 'app/index',
'view_path' => 'app/index',
'methods' => 'get',
'sort' => '130',
'sort' => '999',
'status' => '1',
'is_show' => '1',
],
@ -1783,6 +1783,64 @@ return [
'sort' => '0',
'status' => '1',
'is_show' => '0',
],
[
'menu_name' => 'App端',
'menu_key' => 'channel_app',
'menu_short_name' => 'App端',
'menu_type' => '1',
'icon' => '',
'api_url' => '',
'router_path' => 'channel/app',
'view_path' => 'channel/app/access',
'methods' => '',
'sort' => '50',
'status' => '1',
'is_show' => '1',
],
[
'menu_name' => 'App端配置',
'menu_key' => 'channel_app_config',
'menu_short_name' => 'app端配置',
'menu_type' => '1',
'icon' => '',
'api_url' => 'channel/app/config',
'router_path' => 'channel/app/config',
'view_path' => 'channel/app/config',
'methods' => 'get',
'sort' => '100',
'status' => '1',
'is_show' => '0',
'children' => [
[
'menu_name' => '设置app端配置',
'menu_key' => 'set_channel_app_config',
'menu_short_name' => '设置app端配置',
'menu_type' => '2',
'icon' => '',
'api_url' => 'channel/app/config',
'router_path' => '',
'view_path' => '',
'methods' => 'put',
'sort' => '100',
'status' => '1',
'is_show' => '1',
]
]
],
[
'menu_name' => 'APP版本管理',
'menu_key' => 'app_version_list',
'menu_short_name' => '版本管理',
'menu_type' => '1',
'icon' => '',
'api_url' => 'channel/app/version',
'router_path' => 'channel/app/version',
'view_path' => 'channel/app/version',
'methods' => 'get',
'sort' => '100',
'status' => '1',
'is_show' => '0',
]
],
],
@ -2998,7 +3056,7 @@ return [
'is_show' => '1',
'children' => [
[
'menu_name' => '插件管理',
'menu_name' => '应用管理',
'menu_key' => 'app_store',
'menu_short_name' => '应用',
'menu_type' => '1',
@ -3557,7 +3615,7 @@ return [
'methods' => '',
'sort' => '101',
'status' => '1',
'is_show' => '1',
'is_show' => '0',
],
[
'menu_name' => '升级记录',

View File

@ -16,7 +16,6 @@ use app\dict\common\ChannelDict;
class PayChannelDict
{
/**
* 支付渠道类型
* @return array
@ -49,5 +48,4 @@ class PayChannelDict
return $list;
}
}

View File

@ -40,6 +40,9 @@ class ConfigKeyDict
public const SMS = 'SMS';//短信配置
public const PINTUAN_ORDER_CONFIG = 'PINTUAN_ORDER_CONFIG';//拼团订单配置
public const FRIEND_HELP_CONFIG = 'FRIEND_HELP_CONFIG';//拼团订单配置
public const RELAY_ORDER_CONFIG = 'RELAY_ORDER_CONFIG';//接龙订单配置
public const FRIEND_HELP_ORDER_CONFIG = 'FRIEND_HELP_ORDER_CONFIG';//接龙订单配置
public const APP = 'app';
}

View File

@ -35,6 +35,10 @@ class FileDict
public const EXCEL = 'excel';//excel导入
public const APP_PACKAGE = 'app_package';//应用包
public const ANDROID_CERT = 'android_cert';//android证书
/**
* 附件类型
* @return array
@ -74,8 +78,11 @@ class FileDict
self::IMAGE,//图片上传
self::VIDEO,//视频上传
self::AUDIO,//视频上传
self::DOCUMENT,//文件上传
self::APPLET,//小程序包上传
self::EXCEL,//excel导入
self::APP_PACKAGE,//应用包
self::ANDROID_CERT,//android证书
];
}

View File

@ -47,6 +47,18 @@ $system_event = [
],
//协议类型加载
'AgreementType' => [],
//站点首页加载
'SiteIndex' => [
'app\listener\system\SiteIndexListener'
],
// 站点端布局
'SiteLayout' => [
'app\listener\system\SiteLayout'
],
//平台首页加载
'AdminIndex' => [
'app\listener\system\AdminIndexListener'
],
'BottomNavigation' => [
'app\listener\system\BottomNavigationListener'
],
@ -103,18 +115,26 @@ $system_event = [
'GetPosterType' => ['app\listener\system\PosterType'],
'GetPosterData' => ['app\listener\system\Poster'],
// 小程序授权变更事件
'WeappAuthChangeAfter' => ['app\listener\system\WeappAuthChangeAfter'],
'ShowApp' => [
'app\listener\system\ShowAppListener'
],
'ShowMarketing' => [
'app\listener\system\ShowMarketingListener'
],
'ShowCustomer' => [
'app\listener\system\ShowCustomerListener'
],
//获取微信转账场景配置
'GetWechatTransferTradeScene' => [
'app\listener\transfer\TransferCashOutListener'
],
//主题色
'ThemeColor' => ['app\listener\diy\ThemeColorListener'],
'AfterCashApply' => ['app\listener\member\cash\AfterCashApplyListener'],
'AfterCashRefuse' => ['app\listener\member\cash\AfterCashRefuseListener'],
'AfterCashFinish' => ['app\listener\member\cash\AfterCashFinishListener'],
],
'subscribe' => [
],

View File

@ -1,9 +1,9 @@

SET NAMES utf8mb4;
SET NAMES utf8mb4;
DROP TABLE IF EXISTS `account_log`;
CREATE TABLE `account_log` (
CREATE TABLE `account_log`
(
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`type` varchar(255) NOT NULL DEFAULT 'pay' COMMENT '账单类型pay,refund,transfer',
`money` decimal(10, 2) NOT NULL DEFAULT 0.00 COMMENT '交易金额',
@ -35,7 +35,8 @@ CREATE TABLE `activity_exchange_code`
DROP TABLE IF EXISTS `addon`;
CREATE TABLE `addon` (
CREATE TABLE `addon`
(
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`title` varchar(40) NOT NULL DEFAULT '' COMMENT '插件名称',
`icon` varchar(255) NOT NULL DEFAULT '' COMMENT '插件图标',
@ -57,7 +58,8 @@ CREATE TABLE `addon` (
DROP TABLE IF EXISTS `addon_log`;
CREATE TABLE `addon_log` (
CREATE TABLE `addon_log`
(
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`action` varchar(40) NOT NULL DEFAULT '' COMMENT '操作类型 install 安装 uninstall 卸载 update 更新',
`key` varchar(20) NOT NULL DEFAULT '' COMMENT '插件标识',
@ -69,7 +71,8 @@ CREATE TABLE `addon_log` (
DROP TABLE IF EXISTS `applet_site_version`;
CREATE TABLE `applet_site_version` (
CREATE TABLE `applet_site_version`
(
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`version_id` int(11) NOT NULL DEFAULT 0 COMMENT '版本id',
`type` varchar(20) NOT NULL DEFAULT '' COMMENT '小程序类型',
@ -80,7 +83,8 @@ CREATE TABLE `applet_site_version` (
DROP TABLE IF EXISTS `applet_version`;
CREATE TABLE `applet_version` (
CREATE TABLE `applet_version`
(
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`config` varchar(255) NOT NULL DEFAULT '' COMMENT '配置信息',
`type` varchar(20) NOT NULL DEFAULT '' COMMENT '小程序类型',
@ -99,7 +103,8 @@ CREATE TABLE `applet_version` (
DROP TABLE IF EXISTS `diy_form`;
CREATE TABLE `diy_form` (
CREATE TABLE `diy_form`
(
`form_id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '表单id',
`page_title` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '表单名称(用于后台展示)',
`title` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '表单名称(用于前台展示)',
@ -118,7 +123,8 @@ CREATE TABLE `diy_form` (
DROP TABLE IF EXISTS `diy_form_fields`;
CREATE TABLE `diy_form_fields` (
CREATE TABLE `diy_form_fields`
(
`field_id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '字段id',
`form_id` INT(11) NOT NULL DEFAULT 0 COMMENT '所属万能表单id',
`field_key` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '字段唯一标识',
@ -138,7 +144,8 @@ CREATE TABLE `diy_form_fields` (
DROP TABLE IF EXISTS `diy_form_records`;
CREATE TABLE `diy_form_records` (
CREATE TABLE `diy_form_records`
(
`record_id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '表单填写记录id',
`form_id` INT(11) NOT NULL DEFAULT 0 COMMENT '所属万能表单id',
`value` LONGTEXT DEFAULT NULL COMMENT '填写的表单数据',
@ -150,7 +157,8 @@ CREATE TABLE `diy_form_records` (
DROP TABLE IF EXISTS `diy_form_records_fields`;
CREATE TABLE `diy_form_records_fields` (
CREATE TABLE `diy_form_records_fields`
(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`form_id` INT(11) NOT NULL DEFAULT 0 COMMENT '所属万能表单id',
`form_field_id` INT(11) NOT NULL DEFAULT 0 COMMENT '关联表单字段id',
@ -172,7 +180,8 @@ CREATE TABLE `diy_form_records_fields` (
DROP TABLE IF EXISTS `diy_form_submit_config`;
CREATE TABLE `diy_form_submit_config` (
CREATE TABLE `diy_form_submit_config`
(
`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`form_id` INT(11) NOT NULL DEFAULT 0 COMMENT '所属万能表单id',
`submit_after_action` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '填表人提交后操作text文字信息voucher核销凭证',
@ -189,7 +198,8 @@ CREATE TABLE `diy_form_submit_config` (
DROP TABLE IF EXISTS `diy_form_write_config`;
CREATE TABLE `diy_form_write_config` (
CREATE TABLE `diy_form_write_config`
(
`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '主键id',
`form_id` INT(11) NOT NULL DEFAULT 0 COMMENT '所属万能表单id',
`write_way` VARCHAR(255) NOT NULL COMMENT '填写方式no_limit不限制scan仅限微信扫一扫url仅限链接进入',
@ -211,7 +221,8 @@ CREATE TABLE `diy_form_write_config` (
DROP TABLE IF EXISTS `diy_page`;
CREATE TABLE `diy_page` (
CREATE TABLE `diy_page`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`page_title` varchar(255) NOT NULL DEFAULT '' COMMENT '页面名称(用于后台展示)',
`title` varchar(255) NOT NULL DEFAULT '' COMMENT '页面标题(用于前台展示)',
@ -231,7 +242,8 @@ CREATE TABLE `diy_page` (
DROP TABLE IF EXISTS `diy_route`;
CREATE TABLE `diy_route` (
CREATE TABLE `diy_route`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL DEFAULT '' COMMENT '页面名称',
`name` varchar(255) NOT NULL DEFAULT '' COMMENT '页面标识',
@ -244,7 +256,8 @@ CREATE TABLE `diy_route` (
DROP TABLE IF EXISTS `diy_theme`;
CREATE TABLE `diy_theme` (
CREATE TABLE `diy_theme`
(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`title` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '标题',
`type` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '插件类型appaddon',
@ -262,7 +275,8 @@ CREATE TABLE `diy_theme` (
DROP TABLE IF EXISTS `generate_column`;
CREATE TABLE `generate_column` (
CREATE TABLE `generate_column`
(
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
`table_id` int(11) NOT NULL DEFAULT 0 COMMENT '表id',
`column_name` varchar(100) NOT NULL DEFAULT '' COMMENT '字段名称',
@ -292,7 +306,8 @@ CREATE TABLE `generate_column` (
DROP TABLE IF EXISTS `generate_table`;
CREATE TABLE `generate_table` (
CREATE TABLE `generate_table`
(
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`table_name` varchar(255) NOT NULL DEFAULT '' COMMENT '表名',
`table_content` varchar(255) NOT NULL DEFAULT '' COMMENT '描述前缀',
@ -310,7 +325,8 @@ CREATE TABLE `generate_table` (
DROP TABLE IF EXISTS `jobs`;
CREATE TABLE `jobs` (
CREATE TABLE `jobs`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`queue` varchar(255) NOT NULL DEFAULT '',
`payload` longtext NOT NULL,
@ -323,7 +339,8 @@ CREATE TABLE `jobs` (
DROP TABLE IF EXISTS `jobs_failed`;
CREATE TABLE `jobs_failed` (
CREATE TABLE `jobs_failed`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`connection` text NOT NULL,
`queue` text NOT NULL,
@ -335,7 +352,8 @@ CREATE TABLE `jobs_failed` (
DROP TABLE IF EXISTS `member`;
CREATE TABLE `member` (
CREATE TABLE `member`
(
`member_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
`member_no` varchar(255) NOT NULL DEFAULT '' COMMENT '会员编码',
`pid` int(11) NOT NULL DEFAULT 0 COMMENT '推广会员id',
@ -393,7 +411,8 @@ CREATE TABLE `member` (
DROP TABLE IF EXISTS `member_account_log`;
CREATE TABLE `member_account_log` (
CREATE TABLE `member_account_log`
(
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`member_id` int(11) NOT NULL DEFAULT 0 COMMENT '用户id',
`account_type` varchar(255) NOT NULL DEFAULT 'point' COMMENT '账户类型',
@ -408,7 +427,8 @@ CREATE TABLE `member_account_log` (
DROP TABLE IF EXISTS `member_address`;
CREATE TABLE `member_address` (
CREATE TABLE `member_address`
(
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
`member_id` int NOT NULL DEFAULT 0 COMMENT '会员id',
`name` varchar(255) NOT NULL DEFAULT '' COMMENT '用户姓名',
@ -425,11 +445,13 @@ CREATE TABLE `member_address` (
PRIMARY KEY (`id`)
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '会员收货地址' ROW_FORMAT = Dynamic;
ALTER TABLE `member_address`ADD INDEX IDX_member_address (member_id);
ALTER TABLE `member_address`
ADD INDEX IDX_member_address (member_id);
DROP TABLE IF EXISTS `member_cash_out`;
CREATE TABLE `member_cash_out` (
CREATE TABLE `member_cash_out`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`cash_out_no` varchar(50) NOT NULL DEFAULT '' COMMENT '提现交易号',
`member_id` int(11) NOT NULL DEFAULT 0 COMMENT '会员id',
@ -462,7 +484,8 @@ CREATE TABLE `member_cash_out` (
DROP TABLE IF EXISTS `member_cash_out_account`;
CREATE TABLE `member_cash_out_account` (
CREATE TABLE `member_cash_out_account`
(
`account_id` int(11) NOT NULL AUTO_INCREMENT,
`member_id` int(11) NOT NULL DEFAULT 0 COMMENT '会员id',
`account_type` varchar(255) NOT NULL DEFAULT '' COMMENT '账户类型',
@ -477,7 +500,8 @@ CREATE TABLE `member_cash_out_account` (
DROP TABLE IF EXISTS `member_label`;
CREATE TABLE `member_label` (
CREATE TABLE `member_label`
(
`label_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '标签id',
`label_name` varchar(50) NOT NULL DEFAULT '' COMMENT '标签名称',
`memo` varchar(1000) NOT NULL DEFAULT '' COMMENT '备注',
@ -490,7 +514,8 @@ CREATE TABLE `member_label` (
DROP TABLE IF EXISTS `member_level`;
CREATE TABLE `member_level` (
CREATE TABLE `member_level`
(
`level_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '会员等级',
`level_name` varchar(50) NOT NULL DEFAULT '' COMMENT '等级名称',
`growth` int(11) NOT NULL DEFAULT '0' COMMENT '所需成长值',
@ -505,7 +530,8 @@ CREATE TABLE `member_level` (
DROP TABLE IF EXISTS `member_sign`;
CREATE TABLE `member_sign` (
CREATE TABLE `member_sign`
(
`sign_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`member_id` int(11) NOT NULL DEFAULT '0' COMMENT '会员id',
`days` int(11) NOT NULL DEFAULT '0' COMMENT '连续签到天数',
@ -520,7 +546,8 @@ CREATE TABLE `member_sign` (
DROP TABLE IF EXISTS `niu_sms_template`;
CREATE TABLE `niu_sms_template` (
CREATE TABLE `niu_sms_template`
(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`sms_type` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '短信服务商类型 niuyun-牛云 aliyun-阿里云 tencent-腾讯',
`username` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '子账号名称',
@ -539,7 +566,8 @@ CREATE TABLE `niu_sms_template` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci COMMENT='牛云短信模板表';
DROP TABLE IF EXISTS `pay`;
CREATE TABLE `pay` (
CREATE TABLE `pay`
(
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
`main_id` int(11) NOT NULL DEFAULT 0 COMMENT '支付会员id',
`from_main_id` INT(11) NOT NULL DEFAULT 0 COMMENT '发起支付会员id',
@ -565,7 +593,8 @@ CREATE TABLE `pay` (
DROP TABLE IF EXISTS `pay_channel`;
CREATE TABLE `pay_channel` (
CREATE TABLE `pay_channel`
(
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
`type` varchar(255) NOT NULL DEFAULT '' COMMENT '支付类型',
`channel` varchar(255) NOT NULL DEFAULT '' COMMENT '支付渠道',
@ -579,7 +608,8 @@ CREATE TABLE `pay_channel` (
DROP TABLE IF EXISTS `pay_refund`;
CREATE TABLE `pay_refund` (
CREATE TABLE `pay_refund`
(
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
`refund_no` varchar(255) NOT NULL DEFAULT '' COMMENT '退款单号',
`out_trade_no` varchar(255) NOT NULL DEFAULT '' COMMENT '支付流水号',
@ -604,7 +634,8 @@ CREATE TABLE `pay_refund` (
DROP TABLE IF EXISTS `pay_transfer`;
CREATE TABLE `pay_transfer` (
CREATE TABLE `pay_transfer`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`trade_type` varchar(255) NOT NULL DEFAULT '' COMMENT '业务类型',
`transfer_no` varchar(50) NOT NULL DEFAULT '' COMMENT '转账单号',
@ -636,7 +667,8 @@ CREATE TABLE `pay_transfer` (
DROP TABLE IF EXISTS `pay_transfer_scene`;
CREATE TABLE `pay_transfer_scene` (
CREATE TABLE `pay_transfer_scene`
(
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
`type` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '业务类型',
`scene` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '场景',
@ -648,7 +680,8 @@ CREATE TABLE `pay_transfer_scene` (
DROP TABLE IF EXISTS `stat_hour`;
CREATE TABLE `stat_hour` (
CREATE TABLE `stat_hour`
(
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`addon` varchar(255) NOT NULL DEFAULT '' COMMENT '插件',
`field` varchar(255) NOT NULL DEFAULT '' COMMENT '统计字段',
@ -686,7 +719,8 @@ CREATE TABLE `stat_hour` (
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '小时统计表' ROW_FORMAT = Dynamic;
DROP TABLE IF EXISTS `sys_agreement`;
CREATE TABLE `sys_agreement` (
CREATE TABLE `sys_agreement`
(
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
`agreement_key` varchar(255) NOT NULL DEFAULT '' COMMENT '协议关键字',
`title` varchar(255) NOT NULL DEFAULT '' COMMENT '协议标题',
@ -698,7 +732,8 @@ CREATE TABLE `sys_agreement` (
DROP TABLE IF EXISTS `sys_area`;
CREATE TABLE `sys_area` (
CREATE TABLE `sys_area`
(
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`pid` int(11) NOT NULL DEFAULT 0 COMMENT '父级',
`name` varchar(50) NOT NULL DEFAULT '' COMMENT '名称',
@ -713,7 +748,8 @@ CREATE TABLE `sys_area` (
DROP TABLE IF EXISTS `sys_attachment`;
CREATE TABLE `sys_attachment` (
CREATE TABLE `sys_attachment`
(
`att_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL DEFAULT '' COMMENT '附件名称',
`real_name` varchar(255) NOT NULL DEFAULT '' COMMENT '原始文件名',
@ -731,7 +767,8 @@ CREATE TABLE `sys_attachment` (
DROP TABLE IF EXISTS `sys_attachment_category`;
CREATE TABLE `sys_attachment_category` (
CREATE TABLE `sys_attachment_category`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`pid` int(11) NOT NULL DEFAULT 0 COMMENT '父级ID',
`type` varchar(50) NOT NULL DEFAULT '' COMMENT '文件管理类型image,video',
@ -760,7 +797,8 @@ CREATE TABLE `sys_backup_records`
DROP TABLE IF EXISTS `sys_config`;
CREATE TABLE `sys_config` (
CREATE TABLE `sys_config`
(
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
`config_key` varchar(255) NOT NULL DEFAULT '' COMMENT '配置项关键字',
`value` text NULL COMMENT '配置值json',
@ -773,7 +811,8 @@ CREATE TABLE `sys_config` (
DROP TABLE IF EXISTS `sys_cron_task`;
CREATE TABLE `sys_cron_task` (
CREATE TABLE `sys_cron_task`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`status` int(11) NOT NULL DEFAULT 1 COMMENT '任务状态',
`count` int(11) NOT NULL DEFAULT 0 COMMENT '执行次数',
@ -795,7 +834,8 @@ CREATE TABLE `sys_cron_task` (
DROP TABLE IF EXISTS `sys_dict`;
CREATE TABLE `sys_dict` (
CREATE TABLE `sys_dict`
(
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'id',
`name` varchar(50) NOT NULL DEFAULT '' COMMENT '字典名称',
`key` varchar(100) NOT NULL DEFAULT '' COMMENT '字典关键词',
@ -808,7 +848,8 @@ CREATE TABLE `sys_dict` (
DROP TABLE IF EXISTS `sys_export`;
CREATE TABLE `sys_export` (
CREATE TABLE `sys_export`
(
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`export_key` varchar(255) NOT NULL DEFAULT '' COMMENT '主题关键字',
`export_num` int(11) NOT NULL DEFAULT '0' COMMENT '导出数据数量',
@ -822,7 +863,8 @@ CREATE TABLE `sys_export` (
DROP TABLE IF EXISTS `verifier`;
CREATE TABLE `verifier` (
CREATE TABLE `verifier`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`member_id` int(11) NOT NULL DEFAULT '0' COMMENT '会员id',
`uid` int(11) NOT NULL DEFAULT '0' COMMENT '用户id',
@ -833,7 +875,8 @@ CREATE TABLE `verifier` (
DROP TABLE IF EXISTS `verify`;
CREATE TABLE `verify` (
CREATE TABLE `verify`
(
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`code` varchar(255) NOT NULL DEFAULT '' COMMENT '核销码',
`data` varchar(255) NOT NULL DEFAULT '' COMMENT '核销参数',
@ -849,7 +892,8 @@ CREATE TABLE `verify` (
DROP TABLE IF EXISTS `sys_menu`;
CREATE TABLE `sys_menu` (
CREATE TABLE `sys_menu`
(
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '菜单ID',
`app_type` varchar(255) NOT NULL DEFAULT 'admin' COMMENT '应用类型',
`menu_name` varchar(32) NOT NULL DEFAULT '' COMMENT '菜单名称',
@ -876,7 +920,8 @@ CREATE TABLE `sys_menu` (
DROP TABLE IF EXISTS `sys_notice`;
CREATE TABLE `sys_notice` (
CREATE TABLE `sys_notice`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`key` varchar(50) NOT NULL DEFAULT '' COMMENT '标识',
`sms_content` text NULL COMMENT '短信配置参数',
@ -894,7 +939,8 @@ CREATE TABLE `sys_notice` (
DROP TABLE IF EXISTS `sys_notice_log`;
CREATE TABLE `sys_notice_log` (
CREATE TABLE `sys_notice_log`
(
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '通知记录ID',
`key` varchar(255) NULL DEFAULT '' COMMENT '消息key',
`notice_type` varchar(50) NULL DEFAULT 'sms' COMMENT '消息类型sms,wechat.weapp',
@ -914,7 +960,8 @@ CREATE TABLE `sys_notice_log` (
DROP TABLE IF EXISTS `sys_notice_sms_log`;
CREATE TABLE `sys_notice_sms_log` (
CREATE TABLE `sys_notice_sms_log`
(
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
`mobile` varchar(11) NOT NULL DEFAULT '' COMMENT '手机号码',
`sms_type` varchar(32) NOT NULL DEFAULT '' COMMENT '发送关键字(注册、找回密码)',
@ -933,7 +980,8 @@ CREATE TABLE `sys_notice_sms_log` (
DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role` (
CREATE TABLE `sys_role`
(
`role_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '角色id',
`role_name` varchar(255) NOT NULL DEFAULT '' COMMENT '角色名称',
`rules` text NULL COMMENT '角色权限(menus_id)',
@ -946,7 +994,8 @@ CREATE TABLE `sys_role` (
DROP TABLE IF EXISTS `sys_poster`;
CREATE TABLE `sys_poster` (
CREATE TABLE `sys_poster`
(
`id` int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(255) NOT NULL DEFAULT '' COMMENT '海报名称',
`type` varchar(255) NOT NULL DEFAULT '' COMMENT '海报类型',
@ -962,7 +1011,8 @@ CREATE TABLE `sys_poster` (
DROP TABLE IF EXISTS `sys_printer`;
CREATE TABLE `sys_printer` (
CREATE TABLE `sys_printer`
(
`printer_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`printer_name` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '打印机名称',
`brand` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '设备品牌易联云365飞鹅',
@ -982,7 +1032,8 @@ CREATE TABLE `sys_printer` (
DROP TABLE IF EXISTS `sys_printer_template`;
CREATE TABLE `sys_printer_template` (
CREATE TABLE `sys_printer_template`
(
`template_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`template_name` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '模板名称',
`template_type` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '模板类型',
@ -994,7 +1045,8 @@ CREATE TABLE `sys_printer_template` (
DROP TABLE IF EXISTS `sys_schedule`;
CREATE TABLE `sys_schedule` (
CREATE TABLE `sys_schedule`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`addon` varchar(255) NOT NULL DEFAULT '' COMMENT '所属插件',
`key` varchar(255) NOT NULL DEFAULT '' COMMENT '计划任务模板key',
@ -1012,7 +1064,8 @@ CREATE TABLE `sys_schedule` (
DROP TABLE IF EXISTS `sys_schedule_log`;
CREATE TABLE `sys_schedule_log` (
CREATE TABLE `sys_schedule_log`
(
`id` int NOT NULL AUTO_INCREMENT COMMENT '执行记录id',
`schedule_id` int NOT NULL DEFAULT 0 COMMENT '任务id',
`addon` varchar(255) NOT NULL DEFAULT '' COMMENT '所属插件',
@ -1046,7 +1099,8 @@ CREATE TABLE `sys_upgrade_records`
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
CREATE TABLE `sys_user`
(
`uid` smallint(5) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '系统用户ID',
`username` varchar(255) NOT NULL DEFAULT '' COMMENT '用户账号',
`head_img` varchar(255) NOT NULL DEFAULT '',
@ -1068,7 +1122,8 @@ CREATE TABLE `sys_user` (
DROP TABLE IF EXISTS `sys_user_log`;
CREATE TABLE `sys_user_log` (
CREATE TABLE `sys_user_log`
(
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '管理员操作记录ID',
`ip` varchar(50) NOT NULL DEFAULT '' COMMENT '登录IP',
`uid` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '管理员id',
@ -1083,7 +1138,8 @@ CREATE TABLE `sys_user_log` (
DROP TABLE IF EXISTS `sys_user_role`;
CREATE TABLE `sys_user_role` (
CREATE TABLE `sys_user_role`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`uid` int(11) NOT NULL DEFAULT 0 COMMENT '用户id',
`role_ids` varchar(255) NOT NULL DEFAULT '' COMMENT '角色id',
@ -1095,7 +1151,8 @@ CREATE TABLE `sys_user_role` (
DROP TABLE IF EXISTS `weapp_version`;
CREATE TABLE `weapp_version` (
CREATE TABLE `weapp_version`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`version` varchar(255) NOT NULL DEFAULT '',
`version_no` int(11) NOT NULL DEFAULT 1,
@ -1110,7 +1167,8 @@ CREATE TABLE `weapp_version` (
DROP TABLE IF EXISTS `web_adv`;
CREATE TABLE `web_adv` (
CREATE TABLE `web_adv`
(
`adv_id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`adv_key` VARCHAR(50) NOT NULL DEFAULT '0' COMMENT '广告位key',
`adv_title` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '广告内容描述',
@ -1123,7 +1181,8 @@ CREATE TABLE `web_adv` (
DROP TABLE IF EXISTS `web_friendly_link`;
CREATE TABLE `web_friendly_link` (
CREATE TABLE `web_friendly_link`
(
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '索引id',
`link_title` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '标题',
`link_url` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '链接',
@ -1135,7 +1194,8 @@ CREATE TABLE `web_friendly_link` (
DROP TABLE IF EXISTS `web_nav`;
CREATE TABLE `web_nav` (
CREATE TABLE `web_nav`
(
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
`nav_title` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '导航名称',
`nav_url` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '链接地址',
@ -1149,7 +1209,8 @@ CREATE TABLE `web_nav` (
DROP TABLE IF EXISTS `wechat_fans`;
CREATE TABLE `wechat_fans` (
CREATE TABLE `wechat_fans`
(
`fans_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '粉丝ID',
`nickname` varchar(255) NOT NULL DEFAULT '' COMMENT '昵称',
`avatar` varchar(500) NOT NULL DEFAULT '' COMMENT '头像',
@ -1174,7 +1235,8 @@ CREATE TABLE `wechat_fans` (
DROP TABLE IF EXISTS `wechat_media`;
CREATE TABLE `wechat_media` (
CREATE TABLE `wechat_media`
(
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` varchar(255) NOT NULL DEFAULT '' COMMENT '类型',
`value` text NULL COMMENT '',
@ -1186,7 +1248,8 @@ CREATE TABLE `wechat_media` (
DROP TABLE IF EXISTS `wechat_reply`;
CREATE TABLE `wechat_reply` (
CREATE TABLE `wechat_reply`
(
`id` int UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(64) NOT NULL DEFAULT '' COMMENT '规则名称',
`keyword` varchar(64) NOT NULL DEFAULT '' COMMENT '关键词',
@ -1202,12 +1265,14 @@ CREATE TABLE `wechat_reply` (
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '公众号消息回调表' ROW_FORMAT = Dynamic;
INSERT INTO `sys_user` VALUES ('1', '', '', '', '', '', '0', '0', '0', '1', '0', '0', '1', '', '1');
INSERT INTO `sys_user`
VALUES ('1', '', '', '', '', '', '0', '0', '0', '1', '0', '0', '1', '', '1');
INSERT INTO `sys_user_role` VALUES ('1', '1', '', '0', '1', '1');
INSERT INTO `sys_user_role`
VALUES ('1', '1', '', '0', '1', '1');
INSERT INTO `sys_area` VALUES
(110000, 0, '北京市', '北京', '116.40529', '39.904987', 1, 0, 1),
INSERT INTO `sys_area`
VALUES (110000, 0, '北京市', '北京', '116.40529', '39.904987', 1, 0, 1),
(110100, 110000, '北京市', '北京', '116.40529', '39.904987', 2, 0, 1),
(110101, 110100, '东城区', '东城', '116.418755', '39.917545', 3, 0, 1),
(110102, 110100, '西城区', '西城', '116.36679', '39.91531', 3, 0, 1),
@ -4851,4 +4916,73 @@ INSERT INTO `sys_area` VALUES
(460400405, 460400, '国营蓝洋农场', '国营蓝洋农场', '109.670723', '19.458984', 3, 0, 1),
(460400407, 460400, '国营八一农场', '国营八一农场', '109.364519', '19.413460', 3, 0, 1),
(460400499, 460400, '洋浦经济开发区', '洋浦经济开发区', '109.202064', '19.736941', 3, 0, 1),
(460400500, 460400, '华南热作学院', '华南热作学院', '109.494073', '19.505382', 3, 0, 1);
(460400500, 460400, '华南热作学院', '华南热作学院', '109.494073', '19.505382', 3, 0, 1),
(232718, 232700, '加格达奇区', '加格达奇区', '124.126716', '50.424654', 3, 0, 1),
(330113, 330100, '临平区', '临平区', '120.299376', '30.419025', 3, 0, 1),
(330114, 330100, '钱塘区', '钱塘区', '120.493972', '30.322904', 3, 0, 1),
(460301, 460300, '西沙区', '西沙区', '112.3386402', '16.8310066', 3, 0, 1),
(460302, 460300, '南沙区', '南沙区', '112.891018', '9.543575', 3, 0, 1),
(632825, 632800, '海西蒙古族藏族自治州直辖', '海西蒙古族藏族自治州直辖', '95.357233', '37.853631', 3, 0, 1),
(710000, 0, '台湾省', '台湾省', '121.509062', '25.044332', 1, 0, 1),
(810000, 0, '香港特别行政区', '香港特别行政区', '114.173355', '22.320048', 1, 0, 1),
(810001, 810000, '中西区', '中西区', '114.1543731', '22.28198083', 3, 0, 1),
(810002, 810000, '湾仔区', '湾仔区', '114.1829153', '22.27638889', 3, 0, 1),
(810003, 810000, '东区', '东区', '114.2260031', '22.27969306', 3, 0, 1),
(810004, 810000, '南区', '南区', '114.1600117', '22.24589667', 3, 0, 1),
(810005, 810000, '油尖旺区', '油尖旺区', '114.1733317', '22.31170389', 3, 0, 1),
(810006, 810000, '深水埗区', '深水埗区', '114.1632417', '22.33385417', 3, 0, 1),
(810007, 810000, '九龙城区', '九龙城区', '114.1928467', '22.31251', 3, 0, 1),
(810008, 810000, '黄大仙区', '黄大仙区', '114.2038856', '22.33632056', 3, 0, 1),
(810009, 810000, '观塘区', '观塘区', '114.2140542', '22.32083778', 3, 0, 1),
(810010, 810000, '荃湾区', '荃湾区', '114.1210792', '22.36830667', 3, 0, 1),
(810011, 810000, '屯门区', '屯门区', '113.9765742', '22.39384417', 3, 0, 1),
(810012, 810000, '元朗区', '元朗区', '114.0324381', '22.44142833', 3, 0, 1),
(810013, 810000, '北区', '北区', '114.1473639', '22.49610389', 3, 0, 1),
(810014, 810000, '大埔区', '大埔区', '114.1717431', '22.44565306', 3, 0, 1),
(810015, 810000, '西贡区', '西贡区', '114.264645', '22.31421306', 3, 0, 1),
(810016, 810000, '沙田区', '沙田区', '114.1953653', '22.37953167', 3, 0, 1),
(810017, 810000, '葵青区', '葵青区', '114.1393194', '22.36387667', 3, 0, 1),
(810018, 810000, '离岛区', '离岛区', '113.94612', '22.28640778', 3, 0, 1),
(820000, 0, '澳门特别行政区', '澳门特别行政区', '113.54909', '22.198951', 1, 0, 1),
(820001, 820000, '花地玛堂区', '花地玛堂区', '113.5528956', '22.20787', 3, 0, 1),
(820002, 820000, '花王堂区', '花王堂区', '113.5489608', '22.1992075', 3, 0, 1),
(820003, 820000, '望德堂区', '望德堂区', '113.5501828', '22.19372083', 3, 0, 1),
(820004, 820000, '大堂区', '大堂区', '113.5536475', '22.18853944', 3, 0, 1),
(820005, 820000, '风顺堂区', '风顺堂区', '113.5419278', '22.18736806', 3, 0, 1),
(820006, 820000, '嘉模堂区', '嘉模堂区', '113.5587044', '22.15375944', 3, 0, 1),
(820007, 820000, '路凼填海区', '路凼填海区', '113.5695992', '22.13663', 3, 0, 1),
(820008, 820000, '圣方济各堂区', '圣方济各堂区', '113.5599542', '22.12348639', 3, 0, 1);
DROP TABLE IF EXISTS `app_version`;
CREATE TABLE `app_version`
(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`site_id` INT(11) NOT NULL DEFAULT 0 COMMENT '站点id',
`version_code` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '版本号',
`version_name` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '版本名称',
`version_desc` VARCHAR(1500) NOT NULL DEFAULT '' COMMENT '版本描述',
`platform` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'app平台 Android Ios',
`package_path` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '安装包路径',
`status` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '状态',
`is_forced_upgrade` INT(11) NOT NULL DEFAULT 0 COMMENT '是否需要强制升级',
`task_key` VARCHAR(255) NOT NULL DEFAULT '',
`fail_reason` VARCHAR(255) NOT NULL DEFAULT '',
`upgrade_type` VARCHAR(255) NOT NULL DEFAULT 'app' COMMENT 'app 整包更新 hot 热更新 market 应用市场更新',
`release_time` INT(11) NOT NULL DEFAULT 0 COMMENT '发布时间',
`create_time` INT(11) NOT NULL DEFAULT 0 COMMENT '创建时间',
`update_time` INT(11) NOT NULL DEFAULT 0 COMMENT '修改时间',
PRIMARY KEY (`id`)
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'app版本管理' ROW_FORMAT = Dynamic;
ALTER TABLE activity_exchange_code
CHANGE COLUMN activity_type activity_type VARCHAR(20) NOT NULL DEFAULT '' COMMENT '例seckill-秒杀活动';
ALTER TABLE activity_exchange_code
ADD COLUMN type_item_id INT(11) NOT NULL DEFAULT 0 COMMENT '规格id';
ALTER TABLE member
ADD COLUMN wxapp_openid VARCHAR(255) NOT NULL DEFAULT '' COMMENT '微信移动应用openid';
ALTER TABLE member
MODIFY wxapp_openid VARCHAR(255) NOT NULL DEFAULT '' COMMENT '微信移动应用openid' AFTER weapp_openid;

File diff suppressed because one or more lines are too long

View File

@ -27,16 +27,12 @@ class AutoClearPosterAndQrcode extends BaseJob
// 清理海报目录
$dir = 'upload/poster';
$dir = public_path($dir);
Log::write('AutoClearPosterAndQrcode尝试清理海报目录: ' . $dir);
$res = $this->clearDirectory($dir);
Log::write('AutoClearPosterAndQrcode海报目录清理结果: ' . ($res ? '成功' : '失败'));
// 清理二维码目录
$qrcode_dir = 'upload/qrcode';
$qrcode_dir = public_path($qrcode_dir);
Log::write('AutoClearPosterAndQrcode尝试清理二维码目录: ' . $qrcode_dir);
$res = $this->clearDirectory($qrcode_dir);
Log::write('AutoClearPosterAndQrcode二维码目录清理结果: ' . ($res ? '成功' : '失败'));
return true;
} catch (\Exception $e) {

View File

@ -0,0 +1,31 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\job\sys;
use app\service\core\addon\CoreAddonInstallService;
use core\base\BaseJob;
/**
* 队列异步执行插件安装任务
*/
class AddonInstall extends BaseJob
{
public function doJob($addon, $task)
{
(new CoreAddonInstallService($addon))->executeTask($task);
}
public function failed($data)
{
}
}

View File

@ -57,6 +57,7 @@ return [
//用户管理
'USER_NOT_EXIST' => '用户不存在',
'ADMIN_NOT_ALLOW_EDIT_ROLE' => '超级管理员不允许改动权限',
'USERNAME_REPEAT' => '用户名重复',

View File

@ -24,6 +24,7 @@ return [
'ADD_FAIL' => '添加失败',
'ADD_SUCCESS' => '添加成功',
'UPLOAD_FAIL' => '上传失败',
'RELEASE_SUCCESS' => '发布成功',
'ATTACHMENT_DELETE_FAIL' => '附件删除失败',
'DATA_NOT_EXIST' => '数据不存在',
'DOWNLOAD_FAIL' => '下载失败',
@ -65,6 +66,7 @@ return [
'NOT_EXIST_UPGRADE_CONTENT' => '没有获取到可以升级的内容',
'CLOUD_BUILD_AUTH_CODE_NOT_FOUND' => '请先填写授权码',
'TASK_CYCLE_ERROR' => '任务周期填写错误',
'UPGRADE_TASK_EXIST' => '有正在执行的升级任务,可以展开正在升级的任务,也可以在开发>更新缓存中清除缓存重新开始升级',
//登录注册重置账号....
'LOGIN_SUCCESS' => '登录成功',
@ -77,6 +79,7 @@ return [
'OLD_PASSWORD_ERROR' => '原始密码不正确',
'MOBILE_LOGIN_UNOPENED' => '手机号登录注册未开启',
'APP_TYPE_NOT_EXIST' => '无效的登录端口',
"USER_NOT_ALLOW_DEL" => "该用户是一些站点的管理员不允许删除",
"SUPER_ADMIN_NOT_ALLOW_DEL" => "超级管理员不允许删除",
//用户组权限
@ -96,6 +99,7 @@ return [
'USER_NOT_EXIST' => '用户不存在',
'ADMIN_NOT_ALLOW_EDIT_ROLE' => '超级管理员不允许改动权限',
'USERNAME_REPEAT' => '账号重复',
'MOBILE_REPEAT' => '手机号重复',
//角色管理
'USER_ROLE_NOT_EXIST' => '角色不存在',
@ -134,8 +138,6 @@ return [
'NOTICE_SMS_NOT_OPEN' => '短信未启用',
'NOTICE_TEMPLATE_IS_NOT_EXIST' => '消息不存在',
'WEB_ADV_POSITION_NOT_EXIST' => '广告位不存在',
//会员相关
'MOBILE_IS_EXIST' => '当前手机号已绑定账号',
'ACCOUNT_INSUFFICIENT' => '账户余额不足',
@ -216,9 +218,9 @@ return [
'WEAPP_NOT_EXIST' => '微信小程序未配置完善',
'WEAPP_EMPOWER_NOT_EXIST' => '微信小程序授信信息不存在',
'WEAPP_EMPOWER_TEL_NOT_EXIST' => '微信小程序授信手机号不存在',
'CURR_SITE_IS_NOT_OPEN_SSL' => '微信小程序请求地址只支持https请先配置ssl',
'WECHAT_MINI_PROGRAM_CODE_GENERATION_FAILED' => '微信小程序码生成失败',
//支付相关(todo 注意:7段不共享)
'ALIPAY_TRANSACTION_NO_NOT_EXIST' => '无效的支付交易号',
'PAYMENT_METHOD_NOT_SUPPORT' => '您选择到支付方式不受业务支持',
@ -284,6 +286,8 @@ return [
// 授权相关
'AUTH_NOT_EXISTS' => '未获取到授权信息',
/********************************************************* home端专用 **************************************/
// 云服务
'CLOUD_WEAPP_COMPILE_NOT_EXIST' => '未找到微信小程序编译包',
'WEAPP_APPID_EMPTY' => '还没有配置微信小程序',
@ -323,6 +327,14 @@ return [
'DIRECTORY' => '目录',
'WAS_NOT_CREATED' => '创建失败',
/********************************************************* 微信开放平台 **************************************/
'WECHAT_OPLATFORM_NOT_EXIST' => '未配置微信开放平台',
'WEAPP_EXIST' => '该小程序已经授权给其他站点',
'WECHAT_EXIST' => '该公众号已经授权给其他站点',
'NOT_YET_PRESENT_TEMPLATE_LIBRARY' => '平台尚未上传小程序到模板库',
'WEAPP_VERSION_NOT_EXIST' => '未获取到小程序版本提交记录',
'NOT_ALLOWED_CANCEL_AUDIT' => '只有审核中的才可以撤回',
'PRINTER_NOT_EXIST' => '打印机不存在',
/*******************************************牛云短信 start ********************************************************/
'NIU_SMS_ENABLE_FAILED' => '需登录账号并配置签名后才能启用牛云短信',

View File

@ -472,5 +472,23 @@ return [
'pintuan_name' => '拼团',
'seckill_short' => '秒',
'seckill_name' => '秒杀',
'relay_short' => '接',
'relay_name' => '接龙',
'friend_help_short' => '友',
'friend_help_name' => '好友助力',
],
//应用菜单下 特殊菜单定义
'dict_addon_menu' => [
'system_tool_short' => '系统',
'system_tool' => '系统工具',
'marking_tool_short' => '工具',
'marking_tool' => '营销工具',
'marking_active_short' => '活动',
'marking_active' => '营销活动',
'addon_tool_short' => '插件',
'addon_tool' => '应用插件',
]
];

View File

@ -0,0 +1,31 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\listener\member\cash;
use think\facade\Log;
/**
*
* Class AfterCashApplyListener
* @package app\listener\member\cash
*/
class AfterCashApplyListener
{
public function handle($params)
{
$member_id = $params['member_id'];
$data = $params['data'];
Log::write("发起提现后事件接收参数 member_id:{$member_id} data:" . json_encode($data, 256));
return true;
}
}

View File

@ -0,0 +1,30 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\listener\member\cash;
use think\facade\Log;
/**
*提现完成后事件
* Class AfterCashFinishListener
* @package app\listener\member\cash
*/
class AfterCashFinishListener
{
public function handle($params)
{
$cash_out = $params['cash_out'];
Log::write("提现完成后事件接收参数 data:".json_encode($cash_out,256));
return true;
}
}

View File

@ -0,0 +1,30 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\listener\member\cash;
use think\facade\Log;
/**
*提现被拒绝后事件
* Class AfterCashRefuseListener
* @package app\listener\member\cash
*/
class AfterCashRefuseListener
{
public function handle($params)
{
$cash_out = $params['cash_out'];
Log::write("拒绝提现后事件接收参数 data:" . json_encode($cash_out, 256));
return true;
}
}

View File

@ -12,7 +12,7 @@ class WechatQrcodeListener extends BaseNoticeTemplate
public function handle(array $params)
{
if ('wechat' == $params['channel'] || $params['channel'] == 'h5') {
if ('wechat' == $params['channel'] || $params['channel'] == 'h5' || $params['channel'] == 'app') {
$page = $params['page'];
$url = $params['url'];
$data = $params['data'];
@ -33,7 +33,7 @@ class WechatQrcodeListener extends BaseNoticeTemplate
$url .= '?'.implode('&', $scene);
}
ob_start();//开启缓冲区
\core\util\QRcode::png($url, $path, QR_ECLEVEL_L, 4, 1);
\core\util\QRcode::png($url, $path, QR_ECLEVEL_L, 10, 1);
if($outfile === false){
$img = ob_get_contents();//获取缓冲区内容
$path = 'data:image/png;base64,' . base64_encode($img);//转base64

View File

@ -0,0 +1,30 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\listener\system;
/**
* 平台首页加载事件
* Class AdminIndexListenerIndex
* @package app\listener\system
*/
class AdminIndexListener
{
public function handle()
{
return [
[
"name" => get_lang("dict_admin_index.system"),
"view_path" => "index/index"
]
];
}
}

View File

@ -0,0 +1,75 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\listener\system;
use app\dict\menu\MenuDict;
/**
* 查询营销列表
* Class ShowAppListener
* @package app\listener\system
*/
class ShowCustomerListener
{
public function handle()
{
// 应用app、addon 待定
// 营销marketing
// 工具tool
return [
// 应用
MenuDict::ADDON_CHILD_MENU_DICT_SYSTEM_TOOL => [
[
'title' => '核销管理',
'desc' => '管理核销员及核销记录',
'icon' => 'static/resource/images/marketing/verifier.png',
'key' => 'verify',
'url' => '/marketing/verify/index',
],
[
'title' => '万能表单',
'desc' => '适用于各种应用场景,满足多样化的业务需求',
'icon' => 'static/resource/images/diy_form/icon.png',
'key' => 'diy_form',
'url' => '/diy_form/list',
],
[
'title' => '小票打印',
'desc' => '支持打印机添加,便捷创建小票打印模板',
'icon' => 'static/resource/images/tool/printer_icon.png',
'key' => 'printer_management',
'url' => '/printer/list',
],
[
'title' => '数据导出',
'desc' => '展示导出文件,支持删除与下载',
'icon' => 'static/resource/images/tool/export_icon.png',
'key' => 'setting_export',
'url' => '/setting/export',
],
],
// 工具
MenuDict::ADDON_CHILD_MENU_DICT_MARKING_TOOL => [
],
// 营销
MenuDict::ADDON_CHILD_MENU_DICT_MARKING_ACTIVE => [
[
'title' => '签到管理',
'desc' => '客户每日签到发放奖励',
'icon' => 'static/resource/images/marketing/sign.png',
'key' => 'sign',
'url' => '/marketing/sign/config',
],
]
];
}
}

View File

@ -0,0 +1,49 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\model\sys;
use app\dict\channel\AppDict;
use core\base\BaseModel;
use think\db\Query;
class AppVersion extends BaseModel
{
protected $pk = 'id';
//类型
protected $type = [
'release_time' => 'timestamp',
];
/**
* 模型名称
* @var string
*/
protected $name = 'app_version';
public function searchPlatformAttr(Query $query, $value, $data)
{
if ($value) {
$query->where('platform', $value);
}
}
public function getPlatformNameAttr($value, $data)
{
return AppDict::getAppPlatformName($data['platform']);
}
public function getStatusNameAttr($value, $data)
{
return AppDict::getStatusName($data['status']);
}
}

View File

@ -45,19 +45,6 @@ class SysNoticeLog extends BaseModel
// 设置JSON数据返回数组
protected $jsonAssoc = true;
/**
* 名称
* @param $value
* @param $data
* @return string
*/
public function getContentAttr($value, $data)
{
if ($value) {
$temp = json_decode($value, true);
}
return $temp ?? $value;
}
/**
* 名称

View File

@ -14,6 +14,7 @@ namespace app\model\sys;
use app\dict\sys\UserDict;
use core\base\BaseModel;
use think\model\concern\SoftDelete;
use think\model\relation\HasMany;
/**
* 系统用户模型
@ -56,17 +57,6 @@ class SysUser extends BaseModel
*/
protected $defaultSoftDelete = 0;
/**
* 状态字段转化
* @param $value
* @param $data
* @return mixed
*/
public function getStatusNameAttr($value, $data)
{
if (empty($data[ 'status' ])) return '';
return UserDict::getStatus()[ $data[ 'status' ] ] ?? '';
}
public function getCreateTimeAttr($value, $data)
@ -100,6 +90,18 @@ class SysUser extends BaseModel
}
/**
* 角色状态
* @param $value
* @param $data
* @return string
*/
public function getStatusNameAttr($value, $data)
{
if (empty($data['status'])) return '';
return UserDict::getStatus()[$data['status']] ?? '';
}
/**
* 是否删除搜索器
* @param $query

View File

@ -94,7 +94,7 @@ class AddonDevelopService extends BaseAdminService
/**
* 下载
* @param string $key
* @return array|string|string[]|\think\response\File
* @return \think\response\File
*/
public function download(string $key){
return (new CoreAddonDevelopBuildService())->download($key);

View File

@ -13,8 +13,10 @@ namespace app\service\admin\addon;
use app\dict\addon\AddonDict;
use app\dict\menu\MenuDict;
use app\model\addon\Addon;
use app\model\sys\SysMenu;
use app\service\admin\auth\AuthService;
use app\service\core\addon\CoreAddonCloudService;
use app\service\core\addon\CoreAddonDownloadService;
use app\service\core\addon\CoreAddonInstallService;
@ -273,6 +275,112 @@ class AddonService extends BaseAdminService
return $list;
}
/**
* @return array[]
*/
public function showCustomer($is_sort=true)
{
$show_list = event('ShowCustomer', []);
$addon_type_list = MenuDict::getAddonChildMenu();
$return = [];
foreach ($show_list as $item) {
foreach ($addon_type_list as $key => $value) {
if (!isset($return[$key])) {
$return[$key] = [
'title' => $value['name'],
'sort' => $value['sort'],
'list' => [],
];
}
$return[$key]['list'] = array_merge($return[$key]['list'], $item[$key] ?? []);
}
}
//防止有未实现对应事件的插件额外做一次查询 未实现的直接放到 addon_tool 里面
$keys = [];
foreach ($return as $item) {
foreach ($item['list'] as $value) {
$keys[] = $value['key'];
}
}
$addon_list = $this->getAddonList([]);
$menu_model = (new SysMenu());
$addon_urls = $menu_model
->where([['addon', 'in', array_column($addon_list, 'key')], ['addon', 'not in', $keys], ['is_show', '=', 1], ['menu_type', '=', 1]])
->order('id asc')
->group('addon')
->column('router_path', 'addon');
if (!empty($addon_list)) {
foreach ($addon_list as $k => $v) {
if (in_array($v['key'], $keys)) {
continue;
}
$url = $addon_urls[$v['key']] ?? '';
$return['addon_tool']['list'][] = [
'title' => $v['title'],
'desc' => $v['desc'],
'icon' => $v['icon'],
'key' => $v['key'],
'url' => $url ? '/' . $url : ''
];
}
}
if($is_sort){
usort($return, function (array $a, array $b) {
$sortA = isset($a['sort']) ? (int)$a['sort'] : 0;
$sortB = isset($b['sort']) ? (int)$b['sort'] : 0;
return $sortB <=> $sortA;
});
}
return $return;
}
//生成菜单数据
public function getSpecialMenuList()
{
$auth_menu_list = (new AuthService())->getAuthMenuList('all',1);
$auth_menu_list = array_column($auth_menu_list, null, 'menu_key');
$auth_menu_list = $auth_menu_list['addon']['children'] ?? [];
$list = $this->showCustomer(false);//获取对应的需要展示的key
$addon_menu_list = MenuDict::getAddonChildMenu();
$menu_list = [];
foreach ($addon_menu_list as $item) {
$menu_key_list = array_column($list[$item['key']]['list'] ?? [], 'key');
$temp_menu = [
'app_type'=>'admin',
'menu_name' => $item['name'],
'menu_key' => $item['key'],
'menu_short_name' => $item['short_name'],
'parent_key' => 'addon',
'menu_type' => '0',
'icon' => 'iconfont iconzhuangxiu3',
'api_url' => '',
'router_path' => 'app/index',
'view_path' => 'app/index',
'methods' => 'get',
'sort' => $item['sort'],
'status' => '1',
'is_show' => '1',
];
$children = [];
foreach ($auth_menu_list as $datum_item) {
if (in_array($datum_item['menu_key'], $menu_key_list)) {
$children[] = $datum_item;
}
}
$temp_menu['children'] = $children;
$menu_list[] = $temp_menu;
}
usort($menu_list, function (array $a, array $b) {
$sortA = isset($a['sort']) ? (int)$a['sort'] : 0;
$sortB = isset($b['sort']) ? (int)$b['sort'] : 0;
return $sortB <=> $sortA;
});
return [
'parent_key' => 'addon',
'list' => $menu_list
];
}
private function getAllAddonAndTool()
{
$markting_list = $this->getMarketing() ?? [];

View File

@ -38,6 +38,8 @@ class ConfigService extends BaseAdminService
{
$info = (new CoreConfigService())->getConfig(ConfigKeyDict::ADMIN_LOGIN)['value'] ?? [];
return [
'login_logo' => '',
'login_bg_img' => '',
'is_captcha' => $info['is_captcha'] ?? 0,//是否启用验证码
'bg' => $info['bg'] ?? config('install.admin_login_bg'),//平台登录端 背景
];
@ -53,6 +55,8 @@ class ConfigService extends BaseAdminService
$config = [
'is_captcha' => $data['is_captcha'] ?? 0,//是否启用验证码
'bg' => $data['bg'] ?? '',//平台登录端 背景
'login_logo' => $data['login_logo'] ?? '',//平台登录端 背景
'login_bg_img' => $data['login_bg_img'] ?? '',//平台登录端 背景
];
(new CoreConfigService())->setConfig(ConfigKeyDict::ADMIN_LOGIN, $config);
return true;

View File

@ -11,11 +11,12 @@
namespace app\service\admin\channel;
use app\dict\sys\ConfigKeyDict;
use app\dict\channel\AppDict;
use app\model\sys\AppVersion;
use app\service\core\channel\CoreAppCloudService;
use app\service\core\channel\CoreAppService;
use app\service\core\channel\CoreH5Service;
use app\service\core\sys\CoreConfigService;
use core\base\BaseAdminService;
use core\exception\CommonException;
/**
* 配置服务层
@ -24,6 +25,13 @@ use core\base\BaseAdminService;
*/
class AppService extends BaseAdminService
{
public function __construct()
{
parent::__construct();
$this->model = new AppVersion();
}
/**
* 设置app信息
* @param array $value
@ -41,4 +49,133 @@ class AppService extends BaseAdminService
public function getConfig(){
return (new CoreAppService())->getConfig();
}
/**
* @param array $where
* @return array
* @throws \think\db\exception\DbException
*/
public function getVersionPage(array $where = [])
{
$order = 'id desc';
$search_model = $this->model->where([ [ 'id' ,">", 0 ] ])->withSearch(["platform"], $where)->append(['platform_name', 'status_name'])->field("*")->order($order);
$list = $this->pageQuery($search_model);
return $list;
}
/**
* @param $id
* @return AppVersion|array|mixed|\think\Model
*/
public function getVersionInfo($id) {
return $this->model->where([ ['id', '=', $id] ])->findOrEmpty()->toArray();
}
/**
* 添加版本
* @param array $data
* @return mixed
*/
public function addVersion(array $data) {
$not_release = $this->model->where([['release_time', '=', 0]])->findOrEmpty();
if (!$not_release->isEmpty()) throw new CommonException("当前已存在未发布的版本");
$last_version = $this->model->where([['id', '>', 0]])->order('id desc')->findOrEmpty();
if (!$last_version->isEmpty() && $data['version_code'] <= $last_version['version_code']) throw new CommonException("版本号必须高于上一版本设置的值");
$model = [
'version_code' => $data['version_code'],
'version_name' => $data['version_name'],
'version_desc' => $data['version_desc'],
'platform' => $data['platform'],
'is_forced_upgrade' => $data['is_forced_upgrade'],
'package_path' => $data['package_path'],
'upgrade_type' => $data['upgrade_type'],
];
if ($data['package_type'] == 'cloud') {
$task_key = (new CoreAppCloudService())->appCloudBuid($data);
$model['task_key'] = $task_key['key'];
$model['status'] = AppDict::STATUS_CREATING;
} else {
$model['status'] = AppDict::STATUS_UPLOAD_SUCCESS;
}
$res = $this->model->create($model);
return $res->id;
}
/**
* 编辑版本
* @param int $id
* @param array $data
* @return true
*/
public function editVersion(int $id, array $data)
{
$last_version = $this->model->where([ ['id', '<>', $id]])->order('id desc')->findOrEmpty();
if (!$last_version->isEmpty() && $data['version_code'] <= $last_version['version_code']) throw new CommonException("版本号必须高于上一版本设置的值");
$model = [
'version_code' => $data['version_code'],
'version_name' => $data['version_name'],
'version_desc' => $data['version_desc'],
'platform' => $data['platform'],
'is_forced_upgrade' => $data['is_forced_upgrade'],
'package_path' => $data['package_path'],
'upgrade_type' => $data['upgrade_type'],
];
if ($data['package_type'] == 'cloud') {
$task_key = (new CoreAppCloudService())->appCloudBuid($data);
$model['task_key'] = $task_key['key'];
$model['status'] = AppDict::STATUS_CREATING;
} else {
$model['status'] = AppDict::STATUS_UPLOAD_SUCCESS;
}
$this->model->where([['id', '=', $id]])->update($model);
return true;
}
/**
* 删除app版本
* @param int $id
* @return bool
*/
public function delVersion(int $id)
{
$model = $this->model->where([['id', '=', $id]])->find();
$res = $model->delete();
return $res;
}
public function getBuildLog(string $key) {
$result = (new CoreAppCloudService())->getAppCompileLog($key);
if ($result['status'] == 'fail') {
$this->model->update(['status' => AppDict::STATUS_CREATE_FAIL, 'fail_reason' => $result['fail_reason'], 'update_time' => time() ], ['task_key' => $key]);
}
if ($result['status'] == 'success') {
$this->model->update(['status' => AppDict::STATUS_UPLOAD_SUCCESS, 'package_path' => $result['file_path'], 'update_time' => time() ], ['task_key' => $key]);
}
return $result;
}
/**
* 发布
* @param string $key
* @return void
*/
public function release(int $id) {
$version = $this->model->where([['id', '=', $id]])->findOrEmpty();
if ($version->isEmpty()) throw new CommonException("版本不存在");
if ($version['status'] != AppDict::STATUS_UPLOAD_SUCCESS) throw new CommonException("版本未上传成功");
$this->model->update(['release_time' => time(), 'status' => AppDict::STATUS_PUBLISHED], ['id' => $id]);
}
public function generateSingCert($data) {
return (new CoreAppCloudService())->generateSingCert($data);
}
}

View File

@ -779,7 +779,7 @@ class DiyService extends BaseAdminService
*/
public function getDiyTheme()
{
$addon_list = ( new CoreAddonService() )->getInstallAddonList();
$addon_list = ( new CoreAddonService() )->getInstallAddonList(false);
$apps = [];
foreach ($addon_list as $k => $v) {
if ($v[ 'type' ] == 'app') {

View File

@ -120,7 +120,7 @@ class NiuSmsService extends BaseAdminService
{
$account_info = $this->niu_service->loginAccount($params);
if ($account_info) {
(new CoreNiuSmsService())->setNiuLoginConfig($params, true);
$this->niu_service->setNiuLoginConfig($params, true);
}
return $account_info;
}

View File

@ -150,6 +150,7 @@ class ConfigService extends BaseAdminService
{
$data = [
'key' => $value[ 'key' ],
'amap_key' => $value['amap_key'],
'is_open' => $value[ 'is_open' ], // 是否开启定位
'valid_time' => $value[ 'valid_time' ] // 定位有效期/分钟过期后将重新获取定位信息0为不过期
];
@ -167,6 +168,7 @@ class ConfigService extends BaseAdminService
$info = [];
$info[ 'value' ] = [
'key' => '',
'amap_key' => '',
'is_open' => 1, // 是否开启定位
'valid_time' => 5 // 定位有效期/分钟过期后将重新获取定位信息0为不过期
];
@ -174,6 +176,8 @@ class ConfigService extends BaseAdminService
$info[ 'value' ][ 'is_open' ] = $info[ 'value' ][ 'is_open' ] ?? 1;
$info[ 'value' ][ 'valid_time' ] = $info[ 'value' ][ 'valid_time' ] ?? 5;
$info[ 'value' ][ 'amap_key' ] = $info[ 'value' ][ 'amap_key' ] ?? '';
return $info[ 'value' ];
}
@ -199,11 +203,56 @@ class ConfigService extends BaseAdminService
/**
* 设置开发者key
* @param array $data
* @return \app\model\sys\SysConfig|array|bool|\think\Model
* @return array
*/
public function setDeveloperToken(array $data)
{
return ( new CoreConfigService() )->setConfig("DEVELOPER_TOKEN", $data);
}
/**
* 获取开发者key
* @return array
*/
public function getLayout()
{
return ( new CoreConfigService() )->getConfigValue("LAYOUT_SETTING");
}
/**
* 设置布局风格
* @param array $data
* @return array
*/
public function setLayout(array $data)
{
$config_service = new CoreConfigService();
$config = $config_service->getConfigValue( "LAYOUT_SETTING");
$config[ $data[ 'key' ] ] = $data[ 'value' ];
return ( new CoreConfigService() )->setConfig( "LAYOUT_SETTING", $config);
}
/**
* 获取色调设置
* @return array
*/
public function getThemeColor()
{
return ( new CoreConfigService() )->getConfigValue( "THEMECOLOR_SETTING");
}
/**
* 设置色调
* @param array $data
* @return array
*/
public function setThemeColor(array $data)
{
$config_service = new CoreConfigService();
$config = $config_service->getConfigValue("THEMECOLOR_SETTING");
$config[ $data[ 'key' ] ] = $data[ 'value' ];
return ( new CoreConfigService() )->setConfig("THEMECOLOR_SETTING", $config);
}
}

View File

@ -125,7 +125,7 @@ class StorageConfigService extends BaseAdminService
{
$config['default'] = $storage_type;
}else if ($config['default'] == $storage_type) {
$config['default'] = '';
throw new AdminException('UPLOAD_STORAGE_TYPE_ALL_CLOSE');
}
foreach ($storage_type_list[$storage_type]['params'] as $k_param => $v_param)
{

View File

@ -48,7 +48,7 @@ class UserService extends BaseAdminService
$field = 'uid,username,head_img,real_name,last_ip,last_time,login_count,status, role_ids, is_admin';
$search = [
'username' => $where[ 'username' ],
'realname' => $where[ 'realname' ],
'real_name' => $where[ 'realname' ],
'create_time' => $where[ 'create_time' ]
];
if (!empty($where[ 'role' ])) {
@ -99,32 +99,13 @@ class UserService extends BaseAdminService
'real_name' => $data[ 'real_name' ],
'password' => create_password($data[ 'password' ]),
'is_admin' => $data[ 'is_admin' ],
'is_admin' => $data[ 'is_admin' ]??0,
'role_ids' => $data[ 'role_ids' ],
];
$user = ( new SysUser() )->create($user_data);
return $user?->uid;
}
/**
* 添加对应站点用户(添加站点,同时添加站点用户,用于添加站点以及站点添加站点用户)
* @param $data
* @return bool
*/
public function addUser($data)
{
$role_ids = $data[ 'role_ids' ] ?? [];
$is_admin = $data[ 'is_admin' ] ?? 0;
$data[ 'is_admin' ] = $is_admin;
if (!$is_admin) {
$data[ 'role_ids' ] = $role_ids;
}
//添加用户
$uid = $this->add($data);
return $uid;
}
/**
* 更新对应站点用户
* @param $uid

View File

@ -11,7 +11,11 @@
namespace app\service\admin\weapp;
use app\dict\sys\CloudDict;
use app\service\core\site\CoreSiteService;
use app\service\core\weapp\CoreWeappCloudService;
use app\service\core\weapp\CoreWeappConfigService;
use app\service\core\weapp\CoreWeappService;
use core\base\BaseAdminService;
use app\model\weapp\WeappVersion;
use core\exception\CommonException;
@ -35,11 +39,14 @@ class WeappVersionService extends BaseAdminService
{
$uploading = $this->model->where([ ['status', '=', 0]])->field('id')->findOrEmpty();
if (!$uploading->isEmpty()) throw new CommonException('WEAPP_UPLOADING');
if (empty($data['version'])) {
$version_no = $this->model->where([['id', '>', 0]])->order('version_no desc')->field('version_no')->findOrEmpty()->toArray()['version_no'] ?? 0;
$version_no += 1;
$version = "1.0.{$version_no}";
}else{
$version_no = 0;//自定义的version_no标记为0 不因自定义版本打断默认的连续性
$version = $data['version'];
}
$upload_res = (new CoreWeappCloudService())->uploadWeapp([
'version' => $version,
'desc' => $data['desc'] ?? ''
@ -55,9 +62,17 @@ class WeappVersionService extends BaseAdminService
return $res->id;
}
public function getPreviewImage() {
public function getPreviewImage()
{
try {
$version = $this->model->where([['id', '>', 0]])->order('id desc')->findOrEmpty();
if (!$version->isEmpty() || in_array($version['status'], [CloudDict::APPLET_UPLOAD_SUCCESS, CloudDict::APPLET_AUDITING])) {
if ($version['from_type'] == 'cloud_build') {
return (new CoreWeappCloudService())->getWeappPreviewImage();
} else {
return image_to_base64((new CoreWeappService())->getWeappPreviewImage(), true);
}
}
} catch (\Exception $e) {
return '';
}
@ -74,7 +89,8 @@ class WeappVersionService extends BaseAdminService
$order = 'create_time desc';
$where[] = ['id', '>', 0];
$search_model = $this->model->where($where)->field($field)->order($order)->append(['status_name']);
return $this->pageQuery($search_model);
$list = $this->pageQuery($search_model);
return $list;
}
/**
@ -96,7 +112,8 @@ class WeappVersionService extends BaseAdminService
* @param int $id
* @return true
*/
public function del(int $id){
public function del(int $id)
{
$this->model->where([['id', '=', $id]])->delete();
return true;
}
@ -106,7 +123,20 @@ class WeappVersionService extends BaseAdminService
* @param string $key
* @return null
*/
public function getUploadLog(string $key) {
return (new CoreWeappCloudService())->getWeappCompileLog($key);
public function getUploadLog(string $key)
{
$build_log = (new CoreWeappCloudService())->getWeappCompileLog($key);
if (isset($build_log['data']) && isset($build_log['data'][0]) && is_array($build_log['data'][0])) {
$last = end($build_log['data'][0]);
if ($last['code'] == 0) {
(new WeappVersion())->update(['status' => CloudDict::APPLET_UPLOAD_FAIL, 'fail_reason' => $last['msg'] ?? '', 'update_time' => time()], ['task_key' => $key]);
return $build_log;
}
if ($last['percent'] == 100) {
(new WeappVersion())->update(['status' => CloudDict::APPLET_UPLOAD_SUCCESS, 'update_time' => time()], ['task_key' => $key]);
}
}
return $build_log;
}
}

View File

@ -0,0 +1,34 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\service\api\channel;
use app\dict\channel\AppDict;
use app\model\sys\AppVersion;
use core\base\BaseApiService;
class AppService extends BaseApiService
{
/**
* 获取新的版本
* @param $data
* @return array
*/
public function getNewVersion($data)
{
$version = (new AppVersion())->where([
['platform', '=', $data['platform'] ],
['version_code', '>', $data['version_code'] ],
['status', '=', AppDict::STATUS_PUBLISHED],
])->order("version_code desc")->findOrEmpty()->toArray();
return empty($version) ? null : $version;
}
}

View File

@ -115,10 +115,11 @@ class LoginService extends BaseApiService
if (!empty($params['openid'])) {
$mobile = $params[ 'mobile' ];
$openid = $params[ 'openid' ];
;
$openid_field = match ( $this->channel ) {
'wechat' => 'wx_openid',
'weapp' => 'weapp_openid',
'app' => 'wxapp_openid',
default => ''
};
@ -335,6 +336,7 @@ class LoginService extends BaseApiService
* 重置密码
* @param string $mobile
* @param string $password
* @return true
*/
public function resetPassword(string $mobile, string $password)
{

View File

@ -12,8 +12,10 @@
namespace app\service\api\sys;
use app\service\core\addon\CoreAddonService;
use app\service\core\channel\CoreAppService;
use app\service\core\sys\CoreConfigService;
use app\service\core\sys\CoreSysConfigService;
use app\service\core\weapp\CoreWeappConfigService;
use core\base\BaseApiService;
/**
@ -88,4 +90,12 @@ class ConfigService extends BaseApiService
return (new CoreSysConfigService())->getMap();
}
public function getAppConfig() {
$config = (new CoreAppService())->getConfig();
if (!empty($config) && isset($config['wechat_app_secret'])) unset($config['wechat_app_secret']);
$weapp_config = (new CoreWeappConfigService())->getWeappConfig();
$config['weapp_original'] = $weapp_config['weapp_original'];
return $config;
}
}

View File

@ -160,6 +160,7 @@ class WechatAuthService extends BaseApiService
if (!empty($avatar)) $member_info->headimg = $avatar;
if (!empty($nickname)) $member_info->nickname = $nickname;
}
if (empty($member_info->wx_unionid) && !empty($unionid)) $member_info->wx_unionid = $unionid;
return $login_service->login($member_info, MemberLoginTypeDict::WECHAT);
}
}

View File

@ -133,6 +133,7 @@ class CoreAddonCloudService extends CoreCloudBaseService
return $build_log;
}
if ($last['percent'] == 100) {
$addon = isset($install_task['addon_list']) ? implode(',', $install_task['addon_list']) : $addon;
$build_log['data'][0] = $this->buildSuccess($addon, $build_log['data'][0], $install_task['timestamp']);
}
}

View File

@ -21,6 +21,7 @@ use think\db\exception\DbException;
use think\db\exception\PDOException;
use think\facade\Cache;
use think\facade\Db;
use think\facade\Log;
/**
* 安装服务层
@ -61,11 +62,14 @@ class CoreAddonInstallService extends CoreAddonBaseService
private $install_task = null;
private $addon_list = [];
public function __construct($addon)
{
parent::__construct();
$this->addon = $addon;
$this->install_addon_path = $this->addon_path . $addon . DIRECTORY_SEPARATOR;
$this->addon_list = explode(',', $addon);
$this->addon = $this->addon_list[0];
$this->install_addon_path = $this->addon_path . $this->addon . DIRECTORY_SEPARATOR;
$this->cache_key = "install_{$addon}";
@ -91,30 +95,17 @@ class CoreAddonInstallService extends CoreAddonBaseService
*/
public function installCheck()
{
$from_admin_dir = $this->install_addon_path . 'admin' . DIRECTORY_SEPARATOR;
$from_web_dir = $this->install_addon_path . 'web' . DIRECTORY_SEPARATOR;
$from_wap_dir = $this->install_addon_path . 'uni-app' . DIRECTORY_SEPARATOR;
$from_resource_dir = $this->install_addon_path . 'resource' . DIRECTORY_SEPARATOR;
// 放入的文件
$to_admin_dir = $this->root_path . 'admin' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'addon'. DIRECTORY_SEPARATOR . $this->addon . DIRECTORY_SEPARATOR;
$to_admin_dir = $this->root_path . 'admin' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'addon'. DIRECTORY_SEPARATOR;
$to_web_dir = $this->root_path . 'web' . DIRECTORY_SEPARATOR;
$to_wap_dir = $this->root_path . 'uni-app' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'addon'. DIRECTORY_SEPARATOR . $this->addon . DIRECTORY_SEPARATOR;
$to_wap_dir = $this->root_path . 'uni-app' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'addon'. DIRECTORY_SEPARATOR;
$to_resource_dir = public_path() . 'addon' . DIRECTORY_SEPARATOR . $this->addon . DIRECTORY_SEPARATOR;
$to_resource_dir = public_path() . 'addon' . DIRECTORY_SEPARATOR;
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;
$package_file = [];
search_dir($package_path, $package_file);
$package_file = array_map(function ($file) use ($package_path) {
return str_replace($package_path . DIRECTORY_SEPARATOR, '', $file);
}, $package_file);
$data = [
// 目录检测
'dir' => [
@ -125,10 +116,7 @@ class CoreAddonInstallService extends CoreAddonBaseService
]
];
if (is_dir($from_admin_dir)) $data['dir']['is_readable'][] = ['dir' => str_replace(project_path(), '', $from_admin_dir), 'status' => is_readable($from_admin_dir)];
if (is_dir($from_web_dir)) $data['dir']['is_readable'][] = ['dir' => str_replace(project_path(), '', $from_web_dir), 'status' => is_readable($from_web_dir)];
if (is_dir($from_wap_dir)) $data['dir']['is_readable'][] = ['dir' => str_replace(project_path(), '', $from_wap_dir), 'status' => is_readable($from_wap_dir)];
if (is_dir($from_resource_dir)) $data['dir']['is_readable'][] = ['dir' => str_replace(project_path(), '', $from_resource_dir), 'status' => is_readable($from_resource_dir)];
if (is_dir($this->addon_path)) $data['dir']['is_readable'][] = ['dir' => str_replace(project_path(), '', $this->addon_path), 'status' => is_readable($this->addon_path)];
$data['dir']['is_write'][] = ['dir' => str_replace(project_path(), '', $to_admin_dir), 'status' => is_dir($to_admin_dir) ? is_write($to_admin_dir) : mkdir($to_admin_dir, 0777, true)];
$data['dir']['is_write'][] = ['dir' => str_replace(project_path(), '', $to_web_dir), 'status' => is_dir($to_web_dir) ? is_write($to_web_dir) : mkdir($to_web_dir, 0777, true)];
@ -136,7 +124,8 @@ class CoreAddonInstallService extends CoreAddonBaseService
$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 = checkDirPermissions($this->addon_path);
$check_res = array_merge2($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'));
@ -151,13 +140,65 @@ class CoreAddonInstallService extends CoreAddonBaseService
}
}
$check_res = array_merge(
array_column($data['dir']['is_readable'], 'status'),
array_column($data['dir']['is_write'], 'status')
);
// 检测插件
$framework_version = config('version.version');
$framework_version_arr = explode('.', $framework_version);
$data['addon_check'] = [];
foreach ($this->addon_list as $addon) {
$install_data = $this->getAddonConfig($addon);
if (empty($install_data)) {
$data['addon_check'][] = [
'msg' => "未找到插件{$addon}的info.json文件",
'status' => false
];
continue;
}
$core_addon_service = new CoreAddonService();
if (!empty($core_addon_service->getInfoByKey($addon))) {
$data['addon_check'][] = [
'msg' => $install_data['title'] . '插件已安装,不能重复安装',
'status' => false
];
continue;
}
if (isset($install_data['support_app']) && !empty($install_data['support_app']) &&
empty($core_addon_service->getInfoByKey($install_data['support_app'])) && !in_array($install_data['support_app'], $this->addon_list)) {
$support_app_data = $this->getAddonConfig($install_data['support_app']);
$data['addon_check'][] = [
'msg' => $install_data['title'] . '插件的主应用'. (empty($support_app_data) ? $install_data['support_app'] : $support_app_data['title']) .'插件还未安装,请先安装主应用',
'status' => false
];
continue;
}
if (!isset($install_data['support_version']) || empty($install_data['support_version'])) {
$data['addon_check'][] = [
'msg' => $install_data['title'] . '插件的info.json文件中未检测到匹配框架当前版本['. $framework_version_arr[0].'.'.$framework_version_arr[1] .'.*]的信息无法安装,<a style="text-decoration: underline;" href="https://www.kancloud.cn/niucloud/niucloud-admin-develop/3244512" target="blank">点击查看相关手册</a>',
'status' => false
];
continue;
}
$support_framework_arr = explode('.', $install_data['support_version']);
if ($framework_version_arr[0].$framework_version_arr[1] != $support_framework_arr[0].$support_framework_arr[1]) {
if ((float) "$support_framework_arr[0].$support_framework_arr[1]" < (float) "$framework_version_arr[0].$framework_version_arr[1]") {
$data['addon_check'][] = [
'msg' => $install_data['title'] . '插件的info.json文件中检测到支持的框架版本['. $install_data['support_version'] .']低于当前框架版本['. $framework_version_arr[0].'.'.$framework_version_arr[1] .'.*]无法安装,<a style="text-decoration: underline;" href="https://www.kancloud.cn/niucloud/niucloud-admin-develop/3244512" target="blank">点击查看相关手册</a>',
'status' => false
];
}
}
}
// 是否通过校验
$data['is_pass'] = !in_array(false, $check_res);
$data['is_pass'] = !in_array(false, array_merge(
array_column($data['dir']['is_readable'], 'status'),
array_column($data['dir']['is_write'], 'status'),
array_column($data['addon_check'], 'status')
));
$data['file_permission_is_pass'] = !in_array(false, array_merge(
array_column($data['dir']['is_readable'], 'status'),
array_column($data['dir']['is_write'], 'status'),
));
Cache::set($this->cache_key . '_install_check', $data['is_pass']);
return $data;
}
@ -168,60 +209,36 @@ class CoreAddonInstallService extends CoreAddonBaseService
*/
public function install(string $mode = 'local')
{
$core_addon_service = new CoreAddonService();
if (!empty($core_addon_service->getInfoByKey($this->addon))) throw new AddonException('REPEAT_INSTALL');
$install_data = $this->getAddonConfig($this->addon);
if (empty($install_data)) throw new AddonException('ADDON_INFO_FILE_NOT_EXIST');
$framework_version = config('version.version');
$framework_version_arr = explode('.', $framework_version);
// 检测框架版本是否支持
if (!isset($install_data['support_version']) || empty($install_data['support_version']))
throw new AddonException('您要安装的插件或应用的info.json文件中未检测到匹配框架当前版本['. $framework_version_arr[0].'.'.$framework_version_arr[1] .'.*]的信息无法安装,<a style="text-decoration: underline;" href="https://www.kancloud.cn/niucloud/niucloud-admin-develop/3244512" target="blank">点击查看相关手册</a>');
$support_framework_arr = explode('.', $install_data['support_version']);
if ($framework_version_arr[0].$framework_version_arr[1] != $support_framework_arr[0].$support_framework_arr[1]) {
if ((float) "$support_framework_arr[0].$support_framework_arr[1]" < (float) "$framework_version_arr[0].$framework_version_arr[1]") {
throw new AddonException('您要安装的插件或应用的info.json文件中检测到支持的框架版本['. $install_data['support_version'] .']低于当前框架版本['. $framework_version_arr[0].'.'.$framework_version_arr[1] .'.*]无法安装,<a style="text-decoration: underline;" href="https://www.kancloud.cn/niucloud/niucloud-admin-develop/3244512" target="blank">点击查看相关手册</a>');
}
}
$check_res = Cache::get($this->cache_key . '_install_check');
if (!$check_res) throw new CommonException('INSTALL_CHECK_NOT_PASS');
if ($this->install_task) throw new CommonException('ADDON_INSTALLING');
$this->install_task = [ 'mode' => $mode, 'addon' => $this->addon, 'step' => [], 'timestamp' => time() ];
$this->install_task = [ 'mode' => $mode, 'addon' => $this->addon, 'addon_list' => $this->addon_list, 'step' => [], 'fail_addon' => [], 'timestamp' => time() ];
Cache::set('install_task', $this->install_task);
set_time_limit(0);
$install_step = ['installDir','installWap','installDepend'];
if (!empty($install_data['compile']) || $mode == 'cloud') {
// 备份前端目录
$install_step[] = 'backupFrontend';
}
$this->backupFrontend();
$tips = [];
if ($mode != 'cloud') $tips[] = get_lang('dict_addon.install_after_update');
foreach ($this->addon_list as $addon) {
$this->install_task['addon'] = $addon;
Cache::set('install_task', $this->install_task);
$this->addon = $addon;
$this->install_addon_path = $this->addon_path . $this->addon . DIRECTORY_SEPARATOR;
$install_data = $this->getAddonConfig($addon);
$install_step = ['installDir','installDepend'];
// 检测插件是否存在编译内容
if (!empty($install_data['compile'])) {
$install_step[] = 'coverCompile';
}
if ($mode == 'cloud') {
$install_step[] = 'cloudInstall';
} else {
$install_step[] = 'handleAddonInstall';
}
try {
foreach ($install_step as $step) {
$this->install_task['step'][] = $step;
$this->$step();
if ($step != 'handleAddonInstall') Cache::set('install_task', $this->install_task);
}
if ($mode != 'cloud') {
// 配置文件
$package_path = $this->install_addon_path . 'package' . DIRECTORY_SEPARATOR;
@ -231,49 +248,68 @@ class CoreAddonInstallService extends CoreAddonBaseService
return str_replace($package_path . DIRECTORY_SEPARATOR, '', $file);
}, $package_file);
$tips = [get_lang('dict_addon.install_after_update')];
if (in_array('admin-package.json', $package_file)) $tips[] = get_lang('dict_addon.install_after_admin_update');
if (in_array('composer.json', $package_file)) $tips[] = get_lang('dict_addon.install_after_composer_update');
if (in_array('uni-app-package.json', $package_file)) $tips[] = get_lang('dict_addon.install_after_wap_update');
if (in_array('web-package.json', $package_file)) $tips[] = get_lang('dict_addon.install_after_web_update');
return $tips;
if (in_array('admin-package.json', $package_file) && !in_array(get_lang('dict_addon.install_after_admin_update'), $tips)) $tips[] = get_lang('dict_addon.install_after_admin_update');
if (in_array('composer.json', $package_file) && !in_array(get_lang('dict_addon.install_after_composer_update'), $tips)) $tips[] = get_lang('dict_addon.install_after_composer_update');
if (in_array('uni-app-package.json', $package_file) && !in_array(get_lang('dict_addon.install_after_wap_update'), $tips)) $tips[] = get_lang('dict_addon.install_after_wap_update');
if (in_array('web-package.json', $package_file) && !in_array(get_lang('dict_addon.install_after_web_update'), $tips) ) $tips[] = get_lang('dict_addon.install_after_web_update');
}
return true;
} catch (\Exception $e) {
try {
$this->install_task['step'] = [];
foreach ($install_step as $step) {
$this->install_task['step'][] = $step;
Cache::set('install_task', $this->install_task);
$this->installExceptionHandle();
$this->$step();
}
} catch (\Exception $e) {
$this->install_task['fail_addon'] = $this->addon;
$this->installExceptionHandle($addon);
if (count($this->addon_list) == 1) {
throw new CommonException($e->getMessage());
}
Log::write($install_data['title'] . '插件安装失败');
Log::write($e->getTrace());
$tips[] = $install_data['title'] . '插件安装失败';
}
}
$this->installWap();
if ($mode == 'cloud') {
$this->install_task['tips'] = $tips;
Cache::set('install_task', $this->install_task);
$this->cloudInstall();
} else {
$this->handleAddonInstall();
}
return empty($tips) ? true : $tips;
}
/**
* 安装异常处理
* @return void
*/
public function installExceptionHandle() {
public function installExceptionHandle($name = '') {
$install_task = Cache::get('install_task');
if (in_array('installDir', $install_task['step'])) {
foreach ($this->addon_list as $addon) {
if (!empty($name) && $name != $addon) continue;
@$this->uninstallDir();
}
if (in_array('installWap', $install_task['step'])) {
@$this->uninstallWap();
}
if (in_array('backupFrontend', $install_task['step'])) {
@$this->revertFrontendBackup();
}
Cache::set('install_task', null);
}
/**
* 取消安装任务
* @return void
*/
public function cancleInstall() {
if (Cache::get('install_task')) $this->installExceptionHandle();
if (Cache::get('install_task')) {
$this->installExceptionHandle();
Cache::set('install_task', null);
}
}
/**
@ -409,6 +445,16 @@ class CoreAddonInstallService extends CoreAddonBaseService
*/
public function handleAddonInstall()
{
$core_addon_service = new CoreAddonService();
$fail_addon = $this->install_task['fail_addon'] ?? [];
foreach ($this->addon_list as $addon) {
if (in_array($addon, $fail_addon)) continue;
$this->addon = $addon;
$this->install_addon_path = $this->addon_path . $this->addon . DIRECTORY_SEPARATOR;
// 执行安装sql
$this->installSql();
// 安装菜单
@ -416,18 +462,20 @@ class CoreAddonInstallService extends CoreAddonBaseService
// 安装计划任务
$this->installSchedule();
$core_addon_service = new CoreAddonService();
$install_data = $this->getAddonConfig($this->addon);
$install_data['icon'] = 'addon/' . $this->addon . '/icon.png';
$core_addon_service->set($install_data);
//清理缓存
Cache::tag(self::$cache_tag_name)->clear();
//执行命令
//执行插件安装方法
$class = "addon\\" . $this->addon . "\\" . 'Addon';
if (class_exists($class)) {
(new $class())->install();
}
}
//清理缓存
Cache::tag(self::$cache_tag_name)->clear();
// 清除插件安装中标识
Cache::delete('install_task');
Cache::delete($this->cache_key . '_install_check');
@ -505,8 +553,7 @@ class CoreAddonInstallService extends CoreAddonBaseService
/**
* 插件卸载环境检测
* @param string $addon
* @return void
* @return array|array[]
*/
public function uninstallCheck() {
$data = [
@ -546,6 +593,7 @@ class CoreAddonInstallService extends CoreAddonBaseService
*/
public function uninstall()
{
(new CoreAddonDevelopBuildService())->build($this->addon);
//执行插件卸载方法
@ -684,13 +732,13 @@ class CoreAddonInstallService extends CoreAddonBaseService
{
// 编译 diy-group 自定义组件代码文件
$this->compileDiyComponentsCode($this->root_path . 'uni-app' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR, $this->addon);
$this->compileDiyComponentsCode($this->root_path . 'uni-app' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR, $this->addon_list);
// 编译 pages.json 页面路由代码文件
$this->installPageCode($this->root_path . 'uni-app' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR);
$this->installPageCode($this->root_path . 'uni-app' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR, $this->addon_list);
// 编译 加载插件标题语言包
$this->compileLocale($this->root_path . 'uni-app' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR, $this->addon);
$this->compileLocale($this->root_path . 'uni-app' . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR, $this->addon_list);
}
@ -777,7 +825,7 @@ class CoreAddonInstallService extends CoreAddonBaseService
/**
* 处理编译之后的文件
* @return void
* @return true
*/
public function handleBuildFile() {
return true;

View File

@ -219,10 +219,10 @@ class CoreAddonService extends CoreAddonBaseService
* 查询已安装的有效的应用
* @return array
*/
public function getInstallAddonList()
public function getInstallAddonList($is_change_img=true)
{
$addon_list = $this->model->where([['status', '=', AddonDict::ON]])->append(['status_name'])->column('title, icon, key, desc, status, type, support_app', 'key');
if (!empty($addon_list)) {
if (!empty($addon_list) &&$is_change_img) {
foreach ($addon_list as &$data) {
$data['icon'] = is_file($data['icon']) ? image_to_base64($data['icon']) : '';
}

View File

@ -38,7 +38,7 @@ trait WapTrait
$content .= " <view v-show=\"component.componentIsShow\"\n";
$content .= " @click=\"diyStore.changeCurrentIndex(index, component)\"\n";
$content .= " :class=\"diyGroup.getComponentClass(index,component)\" :style=\"component.pageStyle\">\n";
$content .= " <view class=\"relative\" :style=\"{ marginTop : component.margin.top < 0 ? (component.margin.top * 2) + 'rpx' : '0' }\">\n";
$content .= " <view class=\"relative\" :style=\"{ marginTop : component.margin.top < 0 ? (component.margin.top * 2) + 'rpx' : '0', marginBottom : component.margin.bottom < 0 ? (component.margin.bottom * 2) + 'rpx' : '0' }\">\n";
$content .= " <!-- 装修模式下,设置负上边距后超出的内容,禁止选中设置 -->\n";
$content .= " <view v-if=\"diyGroup.isShowPlaceHolder(index,component)\" class=\"absolute w-full z-1\" :style=\"{ height : (component.margin.top * 2 * -1) + 'rpx' }\" @click.stop=\"diyGroup.placeholderEvent\"></view>\n";
@ -83,7 +83,12 @@ trait WapTrait
}
}
if (!empty($addon)) {
$addon_arr[] = $addon; // 追加新装插件
// 追加新装插件
if (is_array($addon)) {
$addon_arr = array_merge($addon_arr, $addon);
} else if (is_string($addon)) {
$addon_arr[] = $addon;
}
}
$addon_arr = array_unique($addon_arr);
@ -121,9 +126,12 @@ trait WapTrait
$content .= " </view>\n";
$content .= " </view>\n";
$content .= " </template>\n";
$content .= " <template v-if=\"diyStore.mode == '' && data.global && diyGroup.showCopyright.value && data.global.copyright && data.global.copyright.isShow\">\n";
$content .= " <copy-right :textColor=\"data.global.copyright.textColor\" />\n";
$content .= " </template>\n\n";
$content .= " <template v-if=\"diyStore.mode == '' && data.global && data.global.bottomTabBar && data.global.bottomTabBar.isShow\">\n";
$content .= " <view class=\"pt-[20rpx]\"></view>\n";
$content .= " <tabbar />\n";
$content .= " <tabbar :addon=\"data.global.bottomTabBar.designNav.key\" />\n";
$content .= " </template>\n";
$content .= " </view>\n";
$content .= "</template>\n";
@ -181,7 +189,7 @@ trait WapTrait
* @param $compile_path
* @return bool|int|void
*/
public function installPageCode($compile_path)
public function installPageCode($compile_path, $addon = '')
{
if (!file_exists($this->geAddonPackagePath($this->addon) . 'uni-app-pages.php')) return;
@ -192,7 +200,25 @@ trait WapTrait
}
$pages = [];
$addon_arr = array_unique(array_merge([ $this->addon ], array_column(( new CoreAddonService() )->getInstallAddonList(), 'key')));
$addon_service = new CoreAddonService();
$addon_list = $addon_service->getInstallAddonList();
$addon_arr = [];
if (!empty($addon_list)) {
foreach ($addon_list as $k => $v) {
$addon_arr[] = $v[ 'key' ];
}
}
if (!empty($addon)) {
// 追加新装插件
if (is_array($addon)) {
$addon_arr = array_merge($addon_arr, $addon);
} else if (is_string($addon)) {
$addon_arr[] = $addon;
}
}
$addon_arr = array_unique($addon_arr);
foreach ($addon_arr as $addon) {
if (!file_exists($this->geAddonPackagePath($addon) . 'uni-app-pages.php')) continue;
$uniapp_pages = require $this->geAddonPackagePath($addon) . 'uni-app-pages.php';
@ -281,10 +307,18 @@ trait WapTrait
$json = json_decode($app_json, true);
// 清空当前安装/卸载的插件语言包
foreach ($json as $jk => $jc) {
if (is_array($addon)) {
foreach ($addon as $key) {
if (strpos($jk, $key) !== false) {
unset($json[ $jk ]);
}
}
} else {
if (strpos($jk, $addon) !== false) {
unset($json[ $jk ]);
}
}
}
$locale_data[ $cv ] = [
'path' => $ck,
'json' => $json
@ -302,8 +336,16 @@ trait WapTrait
$addon_arr[] = $v[ 'key' ];
}
}
$addon_arr[] = $addon; // 追加新装插件
if (!empty($addon)) {
// 追加新装插件
if (is_array($addon)) {
$addon_arr = array_merge($addon_arr, $addon);
} else if (is_string($addon)) {
$addon_arr[] = $addon;
}
}
$addon_arr = array_unique($addon_arr);
foreach ($addon_arr as $k => $v) {
$addon_path = $compile_path . str_replace('/', DIRECTORY_SEPARATOR, 'addon/' . $v . '/locale'); // 插件语言包根目录
$addon_file_arr = getFileMap($addon_path, []);
@ -337,7 +379,6 @@ trait WapTrait
{
$manifest_json = str_replace('/', DIRECTORY_SEPARATOR, $compile_path . 'src/manifest.json');
$manifest_content = $this->jsonStringToArray(file_get_contents($manifest_json));
( new CoreAddonBaseService() )->writeArrayToJsonFile(array_merge2($manifest_content, $merge_data), $manifest_json);
}
@ -348,8 +389,7 @@ trait WapTrait
*/
private function jsonStringToArray($string)
{
$list = explode(PHP_EOL, $string);
$list = explode("\n", $string);
$json_array = [];
foreach ($list as $index => $item) {
if (strpos($item, '/*') === false) {

View File

@ -90,8 +90,8 @@ class CoreAppletSiteVersionService extends BaseCoreService
$list = $this->model->where($where)->with(['appletVersion'])->select()->toArray();
$list = array_column($list, null, 'version_num');
ksort($list);
$site_version = reset($list);
return $site_version['version'] ?? '';
$version = reset($list);
return $version['version'] ?? '';
}
/**

View File

@ -0,0 +1,328 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\service\core\channel;
use app\dict\addon\AddonDict;
use app\model\addon\Addon;
use app\service\api\diy\DiyConfigService;
use app\service\core\addon\CoreAddonBaseService;
use app\service\core\addon\CoreAddonDevelopDownloadService;
use app\service\core\addon\WapTrait;
use app\service\core\niucloud\CoreCloudBaseService;
use app\service\core\niucloud\CoreModuleService;
use app\service\core\sys\CoreConfigService;
use app\service\core\sys\CoreSysConfigService;
use core\exception\CommonException;
use core\util\niucloud\BaseNiucloudClient;
use core\util\niucloud\CloudService;
use think\facade\Cache;
/**
* 微信APP云服务
* Class CoreWeappAuthService
* @package app\service\core\weapp
*/
class CoreAppCloudService extends CoreCloudBaseService
{
private $addon;
private $addon_path;
private $cache_key = 'app_cloud_build';
use WapTrait;
public function __construct()
{
parent::__construct();
$this->root_path = dirname(root_path()) . DIRECTORY_SEPARATOR;
$this->addon_path = root_path() . 'addon' . DIRECTORY_SEPARATOR;
}
/**
* 上传APP
* @param $addon
*/
public function appCloudBuid(array $data)
{
$action_token = ( new CoreModuleService() )->getActionToken('appbuild', [ 'data' => [ 'product_key' => BaseNiucloudClient::PRODUCT ] ]);
$app_config = (new CoreAppService())->getConfig();
if (empty($app_config['app_name'])) throw new CommonException("请先配置应用名称");
if (empty($app_config['uni_app_id'])) throw new CommonException("请先配置应用ID");
if (empty($app_config['android_app_key'])) throw new CommonException("请先配置应用密钥");
if (empty($app_config['application_id'])) throw new CommonException("请先配置应用包名");
$wap_url = (new CoreSysConfigService())->getSceneDomain()['wap_url'];
$map_config = ( new CoreConfigService() )->getConfigValue('MAPKEY');
$build = [
'app_name' => $app_config['app_name'],
'uni_app_id' => $app_config['uni_app_id'],
'wechat_app_id' => $app_config['wechat_app_id'],
'wechat_app_secret' => $app_config['wechat_app_secret'],
'android_app_key' => $app_config['android_app_key'],
'application_id' => $app_config['application_id'],
'privacy_agreement' => $wap_url . '/app/pages/auth/agreement?key=privacy&=',
'service_agreement' => $wap_url . '/app/pages/auth/agreement?key=service&=',
'qq_map_key' => $map_config['key'] ?? '',
'amap_key' => $map_config['amap_key'] ?? '',
'version_name' => $data['version_name'],
'version_code' => $data['version_code'],
'cert' => $data['cert']
];
// 上传任务key
$task_key = time();
// 此次上传任务临时目录
$temp_dir = runtime_path() . 'build_app' . DIRECTORY_SEPARATOR . $task_key;
$package_dir = $temp_dir . DIRECTORY_SEPARATOR . 'package' . DIRECTORY_SEPARATOR;
// uni
$uni_dir = $package_dir . 'uni-app';
dir_copy($this->root_path . 'uni-app', $uni_dir, exclude_dirs: [ 'node_modules', 'unpackage', 'dist', '.git' ]);
// 替换env文件
$this->weappEnvReplace($uni_dir . DIRECTORY_SEPARATOR . '.env.production');
// 拷贝证书文件
if ($data['cert']['type'] == 'private') {
if (!file_exists($data['cert']['file'])) throw new CommonException('证书文件不存在');
$cert_content = file_get_contents($data['cert']['file']);
file_put_contents($package_dir . 'cert.jks', $cert_content);
}
// 拷贝icon文件
file_copy($data['build']['icon'], $package_dir . 'drawable.zip');
( new CoreAddonBaseService() )->writeArrayToJsonFile($build, $package_dir . 'build.json');
// 处理 mainifest.json
$this->mergeManifestJson($uni_dir . DIRECTORY_SEPARATOR, [
"name" => $app_config['app_name'],
"appid" => $app_config['uni_app_id'],
"versionName" => $data['version_name'],
"versionCode" => $data['version_code'],
]);
// 将临时目录下文件生成压缩包
$zip_file = $temp_dir . DIRECTORY_SEPARATOR . 'app.zip';
( new CoreAddonDevelopDownloadService('') )->compressToZip($package_dir, $zip_file);
$query = [
'authorize_code' => $this->auth_code,
'timestamp' => $task_key,
'token' => $action_token[ 'data' ][ 'token' ] ?? ''
];
$response = ( new CloudService(true, 'http://java.oss.niucloud.com/') )->httpPost('/cloud/appbuild?' . http_build_query($query), [
'multipart' => [
[
'name' => 'file',
'contents' => fopen($zip_file, 'r'),
'filename' => 'app.zip'
]
],
]);
// 删除临时文件
del_target_dir($temp_dir, true);
if (isset($response[ 'code' ]) && $response[ 'code' ] == 0) throw new CommonException($response[ 'msg' ]);
return [ 'key' => $query[ 'timestamp' ] ];
}
/**
* 处理底部导航【暂时停止调用存在APP兼容性问题】
* @param $compile_path
* @param $addon_arr
* @return void
*/
public function handleTabbar($compile_path, $addon_arr = [])
{
$bottomList = array_column(( new DiyConfigService() )->getBottomList(), null, 'key');
$tabbarList = [];
if (empty($addon_arr)) {
foreach ($bottomList as $app_item) {
array_push($tabbarList, ...$app_item[ 'value' ][ 'list' ]);
}
} else {
foreach ($addon_arr as $addon) {
if (isset($bottomList[ $addon ])) {
array_push($tabbarList, ...$bottomList[ $addon ][ 'value' ][ 'list' ]);
}
}
}
$tabbarList = array_map(function ($item) {
if (strpos($item[ 'link' ][ 'url' ], '?') !== false) {
$item[ 'link' ][ 'url' ] = explode('?', $item[ 'link' ][ 'url' ])[0];
}
$link = array_filter(explode('/', $item[ 'link' ][ 'url' ]));
$item[ 'link' ] = $item[ 'link' ][ 'url' ];
$item[ 'component' ] = implode('-', $link);
$item[ 'name' ] = lcfirst(implode('', array_map(function ($str) {
return ucfirst($str);
}, $link)));
return $item;
}, $tabbarList);
$tabbarList = array_column($tabbarList, null, 'name');
if (isset($tabbarList[ 'appPagesIndexIndex' ])) unset($tabbarList[ 'appPagesIndexIndex' ]);
if (isset($tabbarList[ 'appPagesMemberIndex' ])) unset($tabbarList[ 'appPagesMemberIndex' ]);
// 处理vue文件
$tpl = str_replace('/', DIRECTORY_SEPARATOR, public_path() . 'static/tpl/tabbar.tpl');
$content = view($tpl, [ 'tabbarList' => $tabbarList ])->getContent();
file_put_contents(str_replace('/', DIRECTORY_SEPARATOR, $compile_path . 'app/pages/index/tabbar.vue'), $content);
// 处理tabbar.json
file_put_contents($compile_path . 'tabbar.json', json_encode(array_column($tabbarList, 'link'), JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
}
/**
* 小程序上传env文件处理
* @param string $env_file
* @return void
*/
private function weappEnvReplace(string $env_file)
{
$env = file_get_contents($env_file);
$env = str_replace("VITE_APP_BASE_URL=''", "VITE_APP_BASE_URL='" . (string) url('/', [], '', true) . 'api/' . "'", $env);
$env = str_replace("VITE_IMG_DOMAIN=''", "VITE_IMG_DOMAIN='" . (string) url('/', [], '', true) . "'", $env);
file_put_contents($env_file, $env);
}
/**
* 获取APP编译日志
* @param string $timestamp
* @return void
*/
public function getAppCompileLog(string $timestamp)
{
$result = [
'status' => '',
'build_log' => [],
'file_path' => '',
'fail_reason' => ''
];
$query = [
'authorize_code' => $this->auth_code,
'timestamp' => $timestamp
];
$build_log = ( new CloudService(true, 'http://java.oss.niucloud.com/') )->httpGet('cloud/get_appbuild_logs?' . http_build_query($query));
$result['build_log'] = $build_log;
if (isset($build_log['data']) && isset($build_log['data'][0]) && is_array($build_log['data'][0])) {
$last = end($build_log['data'][0]);
if ($last['code'] == 0) {
$result['status'] = 'fail';
$result['fail_reason'] = $last['msg'] ?? '';
return $result;
}
if ($last['percent'] == 100) {
$result = $this->buildSuccess($result, $timestamp);
}
}
return $result;
}
public function buildSuccess(array $result, string $task_key)
{
try {
$query = [
'authorize_code' => $this->auth_code,
'timestamp' => $task_key
];
$chunk_size = 1 * 1024 * 1024;
$temp_dir = 'upload' . DIRECTORY_SEPARATOR . 'download' . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . $task_key . DIRECTORY_SEPARATOR;
if (!is_dir($temp_dir)) mkdirs($temp_dir);
$build_task = Cache::get($this->cache_key . $task_key) ?? [];
if (!isset($build_task[ 'index' ])) {
$response = ( new CloudService(true, 'http://java.oss.niucloud.com/') )->request('HEAD', 'cloud/apk_download?' . http_build_query($query), [
'headers' => [ 'Range' => 'bytes=0-' ]
]);
$length = $response->getHeader('Content-range');
$length = (int) explode("/", $length[ 0 ])[ 1 ];
$step = (int) ceil($length / $chunk_size);
$filename = $response->getHeader('filename')[0];
$build_task = array_merge($build_task, [ 'step' => $step, 'index' => 0, 'length' => $length, 'file_name' => $filename ]);
Cache::set($this->cache_key . $task_key, $build_task);
} else {
$file = $temp_dir . $build_task[ 'file_name' ];
$file_resource = fopen($file, 'a');
if (( $build_task[ 'index' ] + 1 ) <= $build_task[ 'step' ]) {
$start = $build_task[ 'index' ] * $chunk_size;
$end = ( $build_task[ 'index' ] + 1 ) * $chunk_size;
$end = min($end, $build_task[ 'length' ]);
$response = ( new CloudService(true, 'http://java.oss.niucloud.com/') )->request('GET', 'cloud/apk_download?' . http_build_query($query), [
'headers' => [ 'Range' => "bytes={$start}-{$end}" ]
]);
fwrite($file_resource, $response->getBody());
fclose($file_resource);
$build_task[ 'index' ] += 1;
Cache::set($this->cache_key . $task_key, $build_task);
$result['build_log'][] = [ 'code' => 1, 'action' => '安装包下载中,已下载' . round($build_task[ 'index' ] / $build_task[ 'step' ] * 100) . '%', 'percent' => '99' ];
} else {
$result['build_log'][] = [ 'code' => 1, 'action' => '安装包下载中,已下载' . round($build_task[ 'index' ] / $build_task[ 'step' ] * 100) . '%', 'percent' => '100' ];
$result['status'] = 'success';
$result['file_path'] = $file;
Cache::set($this->cache_key . $task_key, null);
}
}
} catch (\Exception $e) {
$result['status'] = 'fail';
$result['fail_reason'] = $e->getMessage().$e->getFile().$e->getLine();
$result['build_log'][] = [ 'code' => 0, 'msg' => $e->getMessage(), 'action' => '', 'percent' => '100' ];
}
return $result;
}
public function generateSingCert(array $data) {
$dname = "CN={$data['cn']}, OU={$data['ou']}, O={$data['o']}, L={$data['l']}, ST={$data['st']}, C={$data['c']}";
$query = [
'key_alias' => $data['key_alias'],
'key_password' => $data['key_password'],
'store_password' => $data['store_password'],
'limit' => $data['limit'] * 365,
'dname' => $dname
];
$response = ( new CloudService(true, 'http://java.oss.niucloud.com/') )->request('GET', 'cloud/getcert?' . http_build_query($query));
$content_type = $response->getHeaders()['Content-Type'][0];
if ($content_type == 'application/json') {
$content = json_decode($response->getBody()->getContents(), true);
if (isset($content[ 'code' ]) && $content[ 'code' ] == 0) throw new CommonException($content[ 'msg' ]);
}
$dir = 'upload' . DIRECTORY_SEPARATOR . 'download' . DIRECTORY_SEPARATOR . 'cert' . DIRECTORY_SEPARATOR;
if (!is_dir($dir)) mkdirs($dir);
$file = $dir . $data['key_alias'] . '.zip';
if (file_exists($file)) unlink($file);
$file_resource = fopen($file, 'a');
fwrite($file_resource, $response->getBody());
fclose($file_resource);
return $file;
}
}

View File

@ -39,6 +39,16 @@ class CoreAppService extends BaseCoreService
public function getConfig()
{
$info = (new CoreConfigService())->getConfig(ConfigKeyDict::APP)['value'] ?? [];
if (empty($info)) {
$info = [
'wechat_app_id' => '',
'wechat_app_secret' => '',
'uni_app_id' => '',
'app_name' => '',
'android_app_key' => '',
'application_id' => ''
];
}
return $info;
}

View File

@ -66,6 +66,17 @@ class CoreH5Service extends BaseCoreService
]
]
]
],
"app-plus" => [
"distribute" => [
"sdkConfigs" => [
"maps" => [
"tencent" => [
"key" => $map_key
]
]
]
]
]
]);
}

View File

@ -33,6 +33,7 @@ class CoreMemberAccountService extends BaseCoreService
$member_model = new Member();
$member_account_log_model = new MemberAccountLog();
//账户检测
Db::startTrans();
$member_info = $member_model->where([
[ 'member_id', '=', $member_id ],
])->field($account_type . ',' . $account_type . "_get" . ', username, mobile, nickname')->lock(true)->find();
@ -55,8 +56,6 @@ class CoreMemberAccountService extends BaseCoreService
'memo' => $memo,
'related_id' => $related_id,
];
Db::startTrans();
try {
$res = $member_account_log_model->create($data);

View File

@ -80,6 +80,10 @@ class CoreMemberCashOutService extends BaseCoreService
$cash_out->account_type . '_cash_outing' => $member[$cash_out->account_type . '_cash_outing'] - $cash_out->apply_money
]
);
//提现完成后事件
event('AfterCashFinish',[
'cash_out'=>$cash_out
]);
return true;
}
@ -169,12 +173,16 @@ class CoreMemberCashOutService extends BaseCoreService
$core_member_cash_out_service->audit($cash_out->id, 'agree');
}
Db::commit();
//发起提现后事件
event('AfterCashApply',[
'member_id'=>$member_id,
'data'=>$data
]);
return $cash_out['id'];
} catch ( Exception $e ) {
Db::rollback();
throw new CommonException($e->getMessage());
}
return true;
}
/**
@ -341,6 +349,10 @@ class CoreMemberCashOutService extends BaseCoreService
$cash_out->account_type . '_cash_outing' => $member[$cash_out->account_type . '_cash_outing'] - $cash_out->apply_money
]
);
//提现拒绝后事件
event('AfterCashRefuse',[
'cash_out'=>$cash_out
]);
return true;
}
@ -382,7 +394,7 @@ class CoreMemberCashOutService extends BaseCoreService
/**
* 取消提现
* @param int $id
* @return void
* @return true
*/
public function cancel(int $id){
$cash_out = $this->find($id);

View File

@ -408,7 +408,7 @@ class CoreNiuSmsService extends BaseAdminService
// 获取域名(含端口)
$host = $_SERVER['HTTP_HOST'];
// 组合成全域名
$return_url = $protocol . '://' . $host . "/site/setting/sms/pay";
$return_url = $protocol . '://' . $host . "/setting/sms/pay";
$url = $this->niushop_url_prefix . sprintf(self::ORDER_PAY_URL, $username);
$params['notify_url'] = $this->niushop_url_prefix . self::ORDER_NOTIFY_URL;

View File

@ -14,6 +14,7 @@ namespace app\service\core\pay;
use app\dict\pay\PayDict;
use app\model\pay\PayChannel;
use app\service\core\channel\CoreAppService;
use app\service\core\weapp\CoreWeappConfigService;
use app\service\core\wechat\CoreWechatConfigService;
use core\base\BaseCoreService;
@ -119,10 +120,15 @@ class CorePayChannelService extends BaseCoreService
//查询公众号配置
$core_weapp_config_service = new CoreWeappConfigService();
$mini_app_id = $core_weapp_config_service->getWeappConfig()[ 'app_id' ];//小程序appid
// 查询微信移动应用配置
$core_app_service = new CoreAppService();
$app_id = $core_app_service->getConfig()['wechat_app_id'] ?? ''; //App appid
//todo 查询微信小程序 appid . 应用appid.....
return [
'mp_app_id' => $mp_app_id,
'mini_app_id' => $mini_app_id
'mini_app_id' => $mini_app_id,
'app_id' => $app_id
//............
];
}

View File

@ -40,7 +40,7 @@ class CoreConfigService extends BaseCoreService
{
$cache_name = 'config_cache';
$where = array(
[ 'config_key', '=', $key ]
[ 'config_key', '=', $key ],
);
// 缓存清理
$info = cache_remember(
@ -99,7 +99,7 @@ class CoreConfigService extends BaseCoreService
public function modifyStatus( int $status, string $key)
{
$where = array(
[ 'config_key', '=', $key ]
[ 'config_key', '=', $key ],
);
$data = array(
'status' => $status,
@ -120,4 +120,19 @@ class CoreConfigService extends BaseCoreService
}
return $config_info[ 'value' ];
}
/**
* 清除配置
* @param string $key
* @param array $value
* @return SysConfig|bool|Model
*/
public function clearConfig(string $key)
{
$where = array(
[ 'config_key', '=', $key ],
);
$this->model->where($where)->delete();
Cache::tag(self::$cache_tag_name)->clear();
}
}

View File

@ -66,6 +66,7 @@ class CoreWeappAuthService extends BaseCoreService
public function getUserPhoneNumber(string $code)
{
$api = CoreWeappService::appApiClient();
CoreWeappService::refreshToken(); // 为防止多次拒绝手机号的情况需要刷新token
return $api->postJson('wxa/business/getuserphonenumber', [
'code' => (string) $code
]);

View File

@ -47,7 +47,6 @@ class CoreWeappCloudService extends CoreCloudBaseService
*/
public function uploadWeapp(array $data)
{
if (!request()->isSsl()) throw new CommonException('CURR_SITE_IS_NOT_OPEN_SSL');
$config = ( new CoreWeappConfigService() )->getWeappConfig();
if (empty($config[ 'app_id' ])) throw new CommonException('WEAPP_APPID_EMPTY');

View File

@ -47,7 +47,6 @@ class CoreWeappConfigService extends BaseCoreService
/**
* 微信小程序配置
* @param
* @param array $data
* @return SysConfig|bool|Model
*/
@ -68,4 +67,33 @@ class CoreWeappConfigService extends BaseCoreService
];
return ( new CoreConfigService() )->setConfig(ConfigKeyDict::WEAPP, $config);
}
/**
* 获取小程序授权信息
* @return mixed
*/
public function getWeappAuthorizationInfo()
{
return ( new CoreConfigService() )->getConfigValue(ConfigKeyDict::WEAPP_AUTHORIZATION_INFO);
}
/**
* 设置小程序授权信息
* @param array $config
* @return SysConfig|bool|Model
*/
public function setWeappAuthorizationInfo(array $config)
{
return ( new CoreConfigService() )->setConfig(ConfigKeyDict::WEAPP_AUTHORIZATION_INFO, $config);
}
/**
* 清除小程序授权信息
* @param array $config
* @return SysConfig|bool|Model
*/
public function clearWeappAuthorizationInfo()
{
return ( new CoreConfigService() )->clearConfig(ConfigKeyDict::WEAPP_AUTHORIZATION_INFO);
}
}

View File

@ -11,6 +11,7 @@
namespace app\service\core\weapp;
use app\service\core\wxoplatform\CoreOplatformService;
use core\base\BaseCoreService;
use core\exception\CommonException;
use core\exception\WechatException;
@ -49,6 +50,7 @@ class CoreWeappService extends BaseCoreService
],
);
return new Application($config);
}
@ -62,6 +64,21 @@ class CoreWeappService extends BaseCoreService
return self::app()->getClient();
}
/**
* 刷新token
* @return void
* @throws InvalidArgumentException
*/
public static function refreshToken()
{
$core_weapp_service = new CoreWeappConfigService();
$weapp_config = $core_weapp_service->getWeappConfig();
if (!$weapp_config['is_authorization']) {
self::app()->getAccessToken()->refresh();
}
}
/**
* 生成小程序码
* @param $page
@ -94,7 +111,7 @@ class CoreWeappService extends BaseCoreService
/**
* 获取小程序体验码
* @return void
* @return string
*/
public function getWeappPreviewImage()
{

View File

@ -17,6 +17,7 @@ use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use EasyWeChat\Kernel\Support\Collection;
use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\ResponseInterface;
use think\facade\Log;
/**
* 微信小程序服务提供
@ -38,12 +39,13 @@ class CoreWeappTemplateService extends BaseCoreService
*/
public function send(string $template_id, string $touser, array $data, string $page = ''){
$api = CoreWeappService::appApiClient();
$api->postJson('cgi-bin/message/subscribe/send', [
$res = $api->postJson('cgi-bin/message/subscribe/send', [
'template_id' => $template_id, // 所需下发的订阅模板id
'touser' => $touser, // 接收者(用户)的 openid
'page' => $page, // 点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,示例index?foo=bar。该字段不填则模板无跳转。
'data' => $data,
]);
Log::write('小程序消息发送RESPONSE'.json_encode($res->toArray(),256));
}
/**

View File

@ -0,0 +1,76 @@
<?php
// +----------------------------------------------------------------------
// | Niucloud-admin 企业快速开发的多应用管理平台
// +----------------------------------------------------------------------
// | 官方网址https://www.niucloud.com
// +----------------------------------------------------------------------
// | niucloud团队 版权所有 开源版本可自由商用
// +----------------------------------------------------------------------
// | Author: Niucloud Team
// +----------------------------------------------------------------------
namespace app\service\core\wechat;
use app\service\core\channel\CoreAppService;
use core\base\BaseCoreService;
use core\exception\CommonException;
use core\exception\WechatException;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\OfficialAccount\Application;
/**
* 微信服务api提供
* Class CoreWechatApiService
* @package app\service\core\wechat
*/
class CoreWechatAppService extends BaseCoreService
{
/**
* 获取公众号的handle
* @return Application
* @throws InvalidArgumentException
*/
public static function app()
{
$app_config = (new CoreAppService())->getConfig();
if (empty($app_config['wechat_app_id']) || empty($app_config['wechat_app_secret'])) throw new WechatException('WECHAT_NOT_EXIST');//公众号未配置
$config = array(
'app_id' => $app_config['wechat_app_id'],
'secret' => $app_config['wechat_app_secret'],
'token' => "",
'aes_key' => 'not_encrypt',
'http' => [
'timeout' => 5.0,
'retry' => true, // 使用默认重试配置
]
);
return new Application($config);
}
/**
* 微信实例接口调用
* @return \EasyWeChat\Kernel\HttpClient\AccessTokenAwareClient
* @throws InvalidArgumentException
*/
public static function appApiClient()
{
return self::app()->getClient();
}
/**
* 处理授权回调
* @param string $code
* @return \Overtrue\Socialite\Contracts\UserInterface
*/
public static function userFromCode(string $code)
{
try {
$oauth = self::app()->getOauth();
return $oauth->userFromCode($code);
} catch (\Exception $e) {
throw new CommonException($e->getCode() . '' . $e->getMessage());
}
}
}

View File

@ -42,7 +42,8 @@ class CoreWechatConfigService extends BaseCoreService
'token' => $info['token'] ?? '',
'encoding_aes_key' => $info['encoding_aes_key'] ?? '',
'encryption_type' => $info['encryption_type'] ?? 'not_encrypt',//加解密模式 not_encrypt 明文 compatible 兼容 safe 安全
'is_authorization' => $info[ 'is_authorization' ] ?? 0
'is_authorization' => $info['is_authorization'] ?? 0,
'base_uri' => $info['base_uri'] ?? ''
];
}
@ -85,4 +86,32 @@ class CoreWechatConfigService extends BaseCoreService
'encryption_type' => WechatDict::getEncryptionType()
];
}
/**
* 获取小程序授权信息
* @return mixed
*/
public function getWechatAuthorizationInfo()
{
return (new CoreConfigService())->getConfigValue(ConfigKeyDict::WECHAT_AUTHORIZATION_INFO);
}
/**
* 设置小程序授权信息
* @param array $config
* @return SysConfig|bool|Model
*/
public function setWechatAuthorizationInfo(array $config)
{
return (new CoreConfigService())->setConfig(ConfigKeyDict::WECHAT_AUTHORIZATION_INFO, $config);
}
/**
* 清除授权信息
* @return mixed
*/
public function clearWechatAuthorizationInfo()
{
return (new CoreConfigService())->clearConfig(ConfigKeyDict::WECHAT_AUTHORIZATION_INFO);
}
}

View File

@ -41,33 +41,25 @@ class CoreWechatMessageService extends BaseCoreService
case WechatDict::MESSAGE_TYPE_EVENT:
return $this->event($message);
// return '收到事件消息';
break;
case WechatDict::MESSAGE_TYPE_TEXT:
//调用文本回复
return $this->text($message);
// return '收到文字消息';
break;
case WechatDict::MESSAGE_TYPE_IMAGE:
return '收到图片消息';
break;
case WechatDict::MESSAGE_TYPE_VOICE:
return '收到语音消息';
break;
case WechatDict::MESSAGE_TYPE_VIDEO:
return '收到视频消息';
break;
case WechatDict::MESSAGE_TYPE_LOCATION:
return '收到坐标消息';
break;
case WechatDict::MESSAGE_TYPE_LINK:
return '收到链接消息';
break;
case WechatDict::MESSAGE_TYPE_FILE:
return '收到文件消息';
// ... 其它消息
default:
return '收到其它消息';
break;
}
}
@ -75,15 +67,13 @@ class CoreWechatMessageService extends BaseCoreService
* 事件分流
* @return void
*/
public function event($message)
public function event(int $message)
{
switch ($message['Event'] ) {
case WechatDict::EVENT_SUBSCRIBE:
return $this->subscribe($message);
break;
case WechatDict::EVENT_SCAN:
return $this->scan($message);
break;
}
}
@ -93,7 +83,7 @@ class CoreWechatMessageService extends BaseCoreService
* @param $message
* @return Lang
*/
public function scan($message){
public function scan(int $message){
$key = str_replace('qrscene_', '', $message['EventKey']);
$core_scan_service = new CoreScanService();
$core_scan_service->actionByScan($key, ['openid' => $message['FromUserName']]);
@ -103,9 +93,9 @@ class CoreWechatMessageService extends BaseCoreService
/**
* 关注事件
* @param $message
* @return News|Text|false
* @return false
*/
public function subscribe($message){
public function subscribe(int $message){
//todo 新增粉丝或将原有的粉丝改为关注状态
// 因为时间的原因,这里可能需要将实践放在消息队列里面
$core_wechat_fans_service = new CoreWechatFansService();
@ -134,12 +124,12 @@ class CoreWechatMessageService extends BaseCoreService
/**
* 文本回复事件
* @param $message
* @return News|Text|false
* @return false
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
function text($message)
function text(int $message)
{
$core_wechat_reply_service = new CoreWechatReplyService();
return $core_wechat_reply_service->reply(WechatDict::REPLY_KEYWORD, $message['Content'], openid: $message['FromUserName']) ?? false;

View File

@ -62,7 +62,7 @@ class CoreWechatService extends BaseCoreService
/**
* 回复文本消息
* @param string $content 文本内容
* @return
* @return string[]
*/
public static function text($content)
{
@ -75,7 +75,7 @@ class CoreWechatService extends BaseCoreService
/**
* 回复图片消息
* @param string $media_id 媒体资源 ID
* @return
* @return void
*/
public static function image($media_id)
{
@ -90,11 +90,10 @@ class CoreWechatService extends BaseCoreService
/**
* 回复声音消息
* @return
* @return void
*/
public static function music()
{
return;
}
/**

View File

@ -0,0 +1,92 @@
<?php
namespace app\upgrade\v157;
use app\model\diy\Diy;
use app\model\diy_form\DiyForm;
class Upgrade
{
public function handle()
{
$this->handleDiyData();
$this->handleDiyFormData();
}
/**
* 处理自定义数据
* @return void
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function handleDiyData()
{
$diy_model = new Diy();
$where = [
['value', '<>', ''],
];
$field = 'id,value';
$list = $diy_model->where($where)->field($field)->select()->toArray();
if (!empty($list)) {
foreach ($list as $k => $v) {
$diy_data = json_decode($v['value'], true);
if (!isset($diy_data['global']['copyright'])) {
$diy_data['global']['copyright'] = [
'control' => true,
'isShow' => false,
'textColor' => '#ccc'
];
}
if (!isset($diy_data['global']['bottomTabBar']['designNav'])) {
$diy_data['global']['bottomTabBar']['designNav'] = ['title'=>'','key'=>''];
}
$diy_data = json_encode($diy_data);
$diy_model->where([['id', '=', $v['id']]])->update(['value' => $diy_data]);
}
}
}
/**
* 处理万能表单数据
* @return void
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function handleDiyFormData()
{
$diy_form_model = new DiyForm();
$where = [
['value', '<>', '']
];
$field = 'form_id,value';
$list = $diy_form_model->where($where)->field($field)->select()->toArray();
if (!empty($list)) {
foreach ($list as $k => $v) {
$diy_data = $v['value'];
if (!isset($diy_data['global']['copyright'])) {
$diy_data['global']['copyright'] = [
'control' => true,
'isShow' => false,
'textColor' => '#ccc',
];
}
if (!isset($diy_data['global']['bottomTabBar']['designNav'])) {
$diy_data['global']['bottomTabBar']['designNav'] = ['title'=>'','key'=>''];
}
$diy_form_model->where([['form_id', '=', $v['form_id']]])->update(['value' => $diy_data]);
}
}
}
}

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