From 5526dfe6f444d1c941109671d34dafd4fe05a025 Mon Sep 17 00:00:00 2001 From: suyi Date: Mon, 11 Mar 2024 15:21:10 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E9=9D=99=E6=80=81=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E8=A1=A5=E5=85=85=E8=B7=A8=E5=9F=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/config/static.php | 46 +++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/server/config/static.php b/server/config/static.php index 6313679..aeb88fb 100644 --- a/server/config/static.php +++ b/server/config/static.php @@ -1,23 +1,25 @@ - - * @copyright walkor - * @link http://www.workerman.net/ - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ - -/** - * Static file settings - */ -return [ - 'enable' => true, - 'middleware' => [ // Static file Middleware - //app\middleware\StaticFile::class, - ], + + * @copyright walkor + * @link http://www.workerman.net/ + * @license http://www.opensource.org/licenses/mit-license.php MIT License + */ + +/** + * Static file settings + */ +return [ + 'enable' => true, + 'middleware' => [ // Static file Middleware + // 跨域中间件 + app\common\http\middleware\AdminAllowMiddleware::class, + //app\middleware\StaticFile::class, + ], ]; \ No newline at end of file -- Gitee From d2d307591d9a8acf56b40bd7464461cd498bd934 Mon Sep 17 00:00:00 2001 From: suyi Date: Mon, 11 Mar 2024 16:40:38 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/generator/stub/vue/api.stub | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/server/app/common/service/generator/stub/vue/api.stub b/server/app/common/service/generator/stub/vue/api.stub index 1858e9a..9225f23 100644 --- a/server/app/common/service/generator/stub/vue/api.stub +++ b/server/app/common/service/generator/stub/vue/api.stub @@ -1,26 +1,26 @@ -import request from '@/utils/request' - -// {COMMENT}列表 -export function api{UPPER_CAMEL_NAME}Lists(params: any) { - return request.get({ url: '/{ROUTE}/lists', params }) -} - -// 添加{COMMENT} -export function api{UPPER_CAMEL_NAME}Add(params: any) { - return request.post({ url: '/{ROUTE}/add', params }) -} - -// 编辑{COMMENT} -export function api{UPPER_CAMEL_NAME}Edit(params: any) { - return request.post({ url: '/{ROUTE}/edit', params }) -} - -// 删除{COMMENT} -export function api{UPPER_CAMEL_NAME}Delete(params: any) { - return request.post({ url: '/{ROUTE}/delete', params }) -} - -// {COMMENT}详情 -export function api{UPPER_CAMEL_NAME}Detail(params: any) { - return request.get({ url: '/{ROUTE}/detail', params }) +import request from '@/utils/request' + +// {COMMENT}列表 +export function api{UPPER_CAMEL_NAME}Lists(params: any) { + return request.get({ url: "/{ROUTE}/lists", params }) +} + +// 添加{COMMENT} +export function api{UPPER_CAMEL_NAME}Add(params: any) { + return request.post({ url: "/{ROUTE}/add", params }) +} + +// 编辑{COMMENT} +export function api{UPPER_CAMEL_NAME}Edit(params: any) { + return request.post({ url: "/{ROUTE}/edit", params }) +} + +// 删除{COMMENT} +export function api{UPPER_CAMEL_NAME}Delete(params: any) { + return request.post({ url: "/{ROUTE}/delete", params }) +} + +// {COMMENT}详情 +export function api{UPPER_CAMEL_NAME}Detail(params: any) { + return request.get({ url: "/{ROUTE}/detail", params }) } \ No newline at end of file -- Gitee From ae405362153de5fdda279d5ea8e1f0aa303316f8 Mon Sep 17 00:00:00 2001 From: suyi Date: Wed, 13 Mar 2024 15:02:02 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dpc=E8=B7=B3=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/app/api/logic/PcLogic.php | 478 +++++++++++++++---------------- 1 file changed, 239 insertions(+), 239 deletions(-) diff --git a/server/app/api/logic/PcLogic.php b/server/app/api/logic/PcLogic.php index 074084d..7407988 100644 --- a/server/app/api/logic/PcLogic.php +++ b/server/app/api/logic/PcLogic.php @@ -1,240 +1,240 @@ - $decoratePage, - 'all' => $allArticle, - 'new' => $newArticle, - 'hot' => $hotArticle - ]; - } - - - /** - * @notes 获取文章 - * @param string $sortType - * @param int $limit - * @return mixed - * @author 段誉 - * @date 2022/10/19 9:53 - */ - public static function getLimitArticle(string $sortType, int $limit = 0, int $cate = 0, int $excludeId = 0) - { - // 查询字段 - $field = [ - 'id', 'cid', 'title', 'desc', 'abstract', 'image', - 'author', 'click_actual', 'click_virtual', 'create_time' - ]; - - // 排序条件 - $orderRaw = 'sort desc, id desc'; - if ($sortType == 'new') { - $orderRaw = 'id desc'; - } - if ($sortType == 'hot') { - $orderRaw = 'click_actual + click_virtual desc, id desc'; - } - - // 查询条件 - $where[] = ['is_show', '=', YesNoEnum::YES]; - if (!empty($cate)) { - $where[] = ['cid', '=', $cate]; - } - if (!empty($excludeId)) { - $where[] = ['id', '<>', $excludeId]; - } - - $article = Article::field($field) - ->where($where) - ->append(['click']) - ->orderRaw($orderRaw) - ->hidden(['click_actual', 'click_virtual']); - - if ($limit) { - $article->limit($limit); - } - - return $article->select()->toArray(); - } - - - /** - * @notes 获取配置 - * @return array - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\DbException - * @throws \think\db\exception\ModelNotFoundException - * @author 段誉 - * @date 2022/9/21 19:38 - */ - public static function getConfigData() - { - // 登录配置 - $loginConfig = [ - // 登录方式 - 'login_way' => ConfigService::get('login', 'login_way', config('project.login.login_way')), - // 注册强制绑定手机 - 'coerce_mobile' => ConfigService::get('login', 'coerce_mobile', config('project.login.coerce_mobile')), - // 政策协议 - 'login_agreement' => ConfigService::get('login', 'login_agreement', config('project.login.login_agreement')), - // 第三方登录 开关 - 'third_auth' => ConfigService::get('login', 'third_auth', config('project.login.third_auth')), - // 微信授权登录 - 'wechat_auth' => ConfigService::get('login', 'wechat_auth', config('project.login.wechat_auth')), - // qq授权登录 - 'qq_auth' => ConfigService::get('login', 'qq_auth', config('project.login.qq_auth')), - ]; - - // 网站信息 - $website = [ - 'shop_name' => ConfigService::get('website', 'shop_name'), - 'shop_logo' => FileService::getFileUrl(ConfigService::get('website', 'shop_logo')), - 'pc_logo' => FileService::getFileUrl(ConfigService::get('website', 'pc_logo')), - 'pc_title' => ConfigService::get('website', 'pc_title'), - 'pc_ico' => FileService::getFileUrl(ConfigService::get('website', 'pc_ico')), - 'pc_desc' => ConfigService::get('website', 'pc_desc'), - 'pc_keywords' => ConfigService::get('website', 'pc_keywords'), - ]; - - // 备案信息 - $copyright = ConfigService::get('copyright', 'config', []); - - // 公众号二维码 - $oaQrCode = ConfigService::get('oa_setting', 'qr_code', ''); - $oaQrCode = empty($oaQrCode) ? $oaQrCode : FileService::getFileUrl($oaQrCode); - // 小程序二维码 - $mnpQrCode = ConfigService::get('mnp_setting', 'qr_code', ''); - $mnpQrCode = empty($mnpQrCode) ? $mnpQrCode : FileService::getFileUrl($mnpQrCode); - - return [ - 'domain' => FileService::getFileUrl(), - 'login' => $loginConfig, - 'website' => $website, - 'version' => config('project.version'), - 'copyright' => $copyright, - 'admin_url' => request()->host() . '/adminapi', - 'qrcode' => [ - 'oa' => $oaQrCode, - 'mnp' => $mnpQrCode, - ] - ]; - } - - - /** - * @notes 资讯中心 - * @return array - * @throws \think\db\exception\DataNotFoundException - * @throws \think\db\exception\DbException - * @throws \think\db\exception\ModelNotFoundException - * @author 段誉 - * @date 2022/10/19 16:55 - */ - public static function getInfoCenter() - { - $data = ArticleCate::field(['id', 'name']) - ->with(['article' => function ($query) { - $query->hidden(['content', 'click_virtual', 'click_actual']) - ->order(['sort' => 'desc', 'id' => 'desc']) - ->append(['click']) - ->limit(10); - }]) - ->where(['is_show' => YesNoEnum::YES]) - ->order(['sort' => 'desc', 'id' => 'desc']) - ->select() - ->toArray(); - - return $data; - } - - - /** - * @notes 获取文章详情 - * @param $userId - * @param $articleId - * @param string $source - * @return array - * @author 段誉 - * @date 2022/10/20 15:18 - */ - public static function getArticleDetail($userId, $articleId, $source = 'default') - { - // 文章详情 - $detail = Article::getArticleDetailArr($articleId); - - // 根据来源列表查找对应列表 - $nowIndex = 0; - $lists = self::getLimitArticle($source, 0, $detail['cid']); - foreach ($lists as $key => $item) { - if ($item['id'] == $articleId) { - $nowIndex = $key; - } - } - // 上一篇 - $detail['last'] = $lists[$nowIndex - 1] ?? []; - // 下一篇 - $detail['next'] = $lists[$nowIndex + 1] ?? []; - - // 最新资讯 - $detail['new'] = self::getLimitArticle('new', 8, $detail['cid'], $detail['id']); - // 关注状态 - $detail['collect'] = ArticleCollect::isCollectArticle($userId, $articleId); - // 分类名 - $detail['cate_name'] = ArticleCate::where('id', $detail['cid'])->value('name'); - - return $detail; - } - + $decoratePage, + 'all' => $allArticle, + 'new' => $newArticle, + 'hot' => $hotArticle + ]; + } + + + /** + * @notes 获取文章 + * @param string $sortType + * @param int $limit + * @return mixed + * @author 段誉 + * @date 2022/10/19 9:53 + */ + public static function getLimitArticle(string $sortType, int $limit = 0, int $cate = 0, int $excludeId = 0) + { + // 查询字段 + $field = [ + 'id', 'cid', 'title', 'desc', 'abstract', 'image', + 'author', 'click_actual', 'click_virtual', 'create_time' + ]; + + // 排序条件 + $orderRaw = 'sort desc, id desc'; + if ($sortType == 'new') { + $orderRaw = 'id desc'; + } + if ($sortType == 'hot') { + $orderRaw = 'click_actual + click_virtual desc, id desc'; + } + + // 查询条件 + $where[] = ['is_show', '=', YesNoEnum::YES]; + if (!empty($cate)) { + $where[] = ['cid', '=', $cate]; + } + if (!empty($excludeId)) { + $where[] = ['id', '<>', $excludeId]; + } + + $article = Article::field($field) + ->where($where) + ->append(['click']) + ->orderRaw($orderRaw) + ->hidden(['click_actual', 'click_virtual']); + + if ($limit) { + $article->limit($limit); + } + + return $article->select()->toArray(); + } + + + /** + * @notes 获取配置 + * @return array + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + * @author 段誉 + * @date 2022/9/21 19:38 + */ + public static function getConfigData() + { + // 登录配置 + $loginConfig = [ + // 登录方式 + 'login_way' => ConfigService::get('login', 'login_way', config('project.login.login_way')), + // 注册强制绑定手机 + 'coerce_mobile' => ConfigService::get('login', 'coerce_mobile', config('project.login.coerce_mobile')), + // 政策协议 + 'login_agreement' => ConfigService::get('login', 'login_agreement', config('project.login.login_agreement')), + // 第三方登录 开关 + 'third_auth' => ConfigService::get('login', 'third_auth', config('project.login.third_auth')), + // 微信授权登录 + 'wechat_auth' => ConfigService::get('login', 'wechat_auth', config('project.login.wechat_auth')), + // qq授权登录 + 'qq_auth' => ConfigService::get('login', 'qq_auth', config('project.login.qq_auth')), + ]; + + // 网站信息 + $website = [ + 'shop_name' => ConfigService::get('website', 'shop_name'), + 'shop_logo' => FileService::getFileUrl(ConfigService::get('website', 'shop_logo')), + 'pc_logo' => FileService::getFileUrl(ConfigService::get('website', 'pc_logo')), + 'pc_title' => ConfigService::get('website', 'pc_title'), + 'pc_ico' => FileService::getFileUrl(ConfigService::get('website', 'pc_ico')), + 'pc_desc' => ConfigService::get('website', 'pc_desc'), + 'pc_keywords' => ConfigService::get('website', 'pc_keywords'), + ]; + + // 备案信息 + $copyright = ConfigService::get('copyright', 'config', []); + + // 公众号二维码 + $oaQrCode = ConfigService::get('oa_setting', 'qr_code', ''); + $oaQrCode = empty($oaQrCode) ? $oaQrCode : FileService::getFileUrl($oaQrCode); + // 小程序二维码 + $mnpQrCode = ConfigService::get('mnp_setting', 'qr_code', ''); + $mnpQrCode = empty($mnpQrCode) ? $mnpQrCode : FileService::getFileUrl($mnpQrCode); + + return [ + 'domain' => FileService::getFileUrl(), + 'login' => $loginConfig, + 'website' => $website, + 'version' => config('project.version'), + 'copyright' => $copyright, + 'admin_url' => request()->host() . '/admin', + 'qrcode' => [ + 'oa' => $oaQrCode, + 'mnp' => $mnpQrCode, + ] + ]; + } + + + /** + * @notes 资讯中心 + * @return array + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + * @author 段誉 + * @date 2022/10/19 16:55 + */ + public static function getInfoCenter() + { + $data = ArticleCate::field(['id', 'name']) + ->with(['article' => function ($query) { + $query->hidden(['content', 'click_virtual', 'click_actual']) + ->order(['sort' => 'desc', 'id' => 'desc']) + ->append(['click']) + ->limit(10); + }]) + ->where(['is_show' => YesNoEnum::YES]) + ->order(['sort' => 'desc', 'id' => 'desc']) + ->select() + ->toArray(); + + return $data; + } + + + /** + * @notes 获取文章详情 + * @param $userId + * @param $articleId + * @param string $source + * @return array + * @author 段誉 + * @date 2022/10/20 15:18 + */ + public static function getArticleDetail($userId, $articleId, $source = 'default') + { + // 文章详情 + $detail = Article::getArticleDetailArr($articleId); + + // 根据来源列表查找对应列表 + $nowIndex = 0; + $lists = self::getLimitArticle($source, 0, $detail['cid']); + foreach ($lists as $key => $item) { + if ($item['id'] == $articleId) { + $nowIndex = $key; + } + } + // 上一篇 + $detail['last'] = $lists[$nowIndex - 1] ?? []; + // 下一篇 + $detail['next'] = $lists[$nowIndex + 1] ?? []; + + // 最新资讯 + $detail['new'] = self::getLimitArticle('new', 8, $detail['cid'], $detail['id']); + // 关注状态 + $detail['collect'] = ArticleCollect::isCollectArticle($userId, $articleId); + // 分类名 + $detail['cate_name'] = ArticleCate::where('id', $detail['cid'])->value('name'); + + return $detail; + } + } \ No newline at end of file -- Gitee From 6de363f6927e772c83a13338df4b93456a613c48 Mon Sep 17 00:00:00 2001 From: suyi Date: Thu, 14 Mar 2024 14:47:22 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/.example.env | 2 +- server/app/crontab/Task.php | 43 ++++++++++ server/composer.json | 159 ++++++++++++++++++------------------ server/composer.lock | 58 ++++++++++++- server/config/process.php | 144 ++++++++++++++++++-------------- 5 files changed, 263 insertions(+), 143 deletions(-) create mode 100644 server/app/crontab/Task.php diff --git a/server/.example.env b/server/.example.env index 2ad2ecb..9433f01 100644 --- a/server/.example.env +++ b/server/.example.env @@ -1 +1 @@ -APP_DEBUG=true SQL_DEBUG=true SERVER_LISTEN="http://127.0.0.1:8789" TASK_STATUS=false TASK_LISTEN=http://127.0.0.1:8790 DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=server_admin DB_USERNAME=root DB_PASSWORD=root DB_PREFIX=la_ SESSION_DRIVER=file CACHE_PREFIX=report_admin CACHE_SESSION_PREFIX=report_admin_session REDIS_CONNECTION=default REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null REDIS_PORT=6379 REDIS_DB=24 REDIS_QUEUE_STATUS=false REDIS_QUEUE_PREFIX=report_admin_queue REDIS_QUEUE_CONNECTION=default REDIS_QUEUE_HOST=127.0.0.1 REDIS_QUEUE_PASSWORD= REDIS_QUEUE_PORT=6379 REDIS_QUEUE_DB=0 YLY_PARTNER=25991 YLY_API_KEY=d955cc2296d69b4094c6465aad360dc6b19a8c77 YLY_REQUEST_URL=http://open.10ss.net:8888 UNIQUE_IDENTIFICATION = "8727" DEMO_ENV = "" \ No newline at end of file +#debug APP_DEBUG=true #sql debug打印 SQL_DEBUG=true #服务提供端口 SERVER_LISTEN="http://127.0.0.1:8789" #慢业务端口 SLOW_PROCESS_STATUS= SLOW_SERVER_LISTEN=http://127.0.0.1:8790 #定时任务 CRONTAB_STATUS= #数据库链接 DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=server_admin DB_USERNAME=root DB_PASSWORD=root DB_PREFIX=la_ #SESSION存储引擎 SESSION_DRIVER=redis #缓存前缀 CACHE_PREFIX=report_admin #SESSION存储前缀 CACHE_SESSION_PREFIX=report_admin_session #redis配置 REDIS_CONNECTION=default REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null REDIS_PORT=6379 REDIS_DB=24 #redis队列配置 REDIS_QUEUE_STATUS= REDIS_QUEUE_PREFIX=report_admin_queue REDIS_QUEUE_CONNECTION=default REDIS_QUEUE_HOST=127.0.0.1 REDIS_QUEUE_PASSWORD= REDIS_QUEUE_PORT=6379 REDIS_QUEUE_DB=0 #密码凭证 UNIQUE_IDENTIFICATION = "8727" \ No newline at end of file diff --git a/server/app/crontab/Task.php b/server/app/crontab/Task.php new file mode 100644 index 0000000..8faf4ec --- /dev/null +++ b/server/app/crontab/Task.php @@ -0,0 +1,43 @@ +=7.2", - "workerman/webman-framework": "^1.4.7", - "monolog/monolog": "^2.0", - "webman/think-orm": "^1.0", - "vlucas/phpdotenv": "^5.4", - "psr/container": "^1.1.1", - "webman/think-cache": "^1.0", - "ext-json": "*", - "phpoffice/phpspreadsheet": "^1.19", - "aliyuncs/oss-sdk-php": "^2.6", - "tencentcloud/tencentcloud-sdk-php": "^3.0", - "webman/console": "v1.2.35", - "qiniu/php-sdk": "7.4", - "qcloud/cos-sdk-v5": "^2.6", - "dragonmantank/cron-expression": "^3.3", - "tinywan/storage": "^0.3.4", - "webman/log": "^1.1", - "taoser/webman-validate": "^1.7", - "webman/redis-queue": "^1.3", - "w7corp/easywechat": "^6.8" - }, - "config": { - "preferred-install": "dist", - "allow-plugins": { - "easywechat-composer/easywechat-composer": false - } - }, - "suggest": { - "ext-event": "For better performance. " - }, - "autoload": { - "psr-4": { - "": "./", - "app\\": "./app", - "App\\": "./app", - "app\\View\\Components\\": "./app/view/components" - }, - "files": [ - "./support/helpers.php" - ] - }, - "scripts": { - "post-package-install": [ - "support\\Plugin::install" - ], - "post-package-update": [ - "support\\Plugin::install" - ], - "pre-package-uninstall": [ - "support\\Plugin::uninstall" - ] - } -} +{ + "name": "workerman/webman", + "type": "project", + "keywords": [ + "high performance", + "http service" + ], + "homepage": "https://www.workerman.net", + "license": "MIT", + "description": "High performance HTTP Service Framework.", + "authors": [ + { + "name": "walkor", + "email": "walkor@workerman.net", + "homepage": "https://www.workerman.net", + "role": "Developer" + } + ], + "support": { + "email": "walkor@workerman.net", + "issues": "https://github.com/walkor/webman/issues", + "forum": "https://wenda.workerman.net/", + "wiki": "https://workerman.net/doc/webman", + "source": "https://github.com/walkor/webman" + }, + "require": { + "php": ">=7.2", + "workerman/webman-framework": "^1.4.7", + "monolog/monolog": "^2.0", + "webman/think-orm": "^1.0", + "vlucas/phpdotenv": "^5.4", + "psr/container": "^1.1.1", + "webman/think-cache": "^1.0", + "ext-json": "*", + "phpoffice/phpspreadsheet": "^1.19", + "aliyuncs/oss-sdk-php": "^2.6", + "tencentcloud/tencentcloud-sdk-php": "^3.0", + "webman/console": "v1.2.35", + "qiniu/php-sdk": "7.4", + "qcloud/cos-sdk-v5": "^2.6", + "dragonmantank/cron-expression": "^3.3", + "tinywan/storage": "^0.3.4", + "webman/log": "^1.1", + "taoser/webman-validate": "^1.7", + "webman/redis-queue": "^1.3", + "w7corp/easywechat": "^6.8", + "workerman/crontab": "^1.0" + }, + "config": { + "preferred-install": "dist", + "allow-plugins": { + "easywechat-composer/easywechat-composer": false + } + }, + "suggest": { + "ext-event": "For better performance. " + }, + "autoload": { + "psr-4": { + "": "./", + "app\\": "./app", + "App\\": "./app", + "app\\View\\Components\\": "./app/view/components" + }, + "files": [ + "./support/helpers.php" + ] + }, + "scripts": { + "post-package-install": [ + "support\\Plugin::install" + ], + "post-package-update": [ + "support\\Plugin::install" + ], + "pre-package-uninstall": [ + "support\\Plugin::uninstall" + ] + } +} diff --git a/server/composer.lock b/server/composer.lock index e290037..2647fbc 100644 --- a/server/composer.lock +++ b/server/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8a643af7f5f85db72b3baa6291ba1a08", + "content-hash": "f9638acbbea944964f7a699cf84815d6", "packages": [ { "name": "aliyuncs/oss-sdk-php", @@ -5408,6 +5408,62 @@ }, "time": "2022-06-03T18:03:27+00:00" }, + { + "name": "workerman/crontab", + "version": "v1.0.6", + "source": { + "type": "git", + "url": "https://github.com/walkor/crontab.git", + "reference": "b78f1556f2977715b9cb5653129e6d9cf160d966" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/walkor/crontab/zipball/b78f1556f2977715b9cb5653129e6d9cf160d966", + "reference": "b78f1556f2977715b9cb5653129e6d9cf160d966", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "php": ">=7.0", + "workerman/workerman": ">=4.0.20" + }, + "type": "library", + "autoload": { + "psr-4": { + "Workerman\\Crontab\\": "./src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "walkor", + "email": "walkor@workerman.net", + "homepage": "http://www.workerman.net", + "role": "Developer" + } + ], + "description": "A crontab written in PHP based on workerman", + "homepage": "http://www.workerman.net", + "keywords": [ + "crontab" + ], + "support": { + "email": "walkor@workerman.net", + "forum": "http://wenda.workerman.net/", + "issues": "https://github.com/walkor/workerman/issues", + "source": "https://github.com/walkor/crontab", + "wiki": "http://doc.workerman.net/" + }, + "time": "2022-10-17T01:59:19+00:00" + }, { "name": "workerman/redis", "version": "v2.0.2", diff --git a/server/config/process.php b/server/config/process.php index 0578f83..2e93387 100644 --- a/server/config/process.php +++ b/server/config/process.php @@ -1,62 +1,82 @@ - - * @copyright walkor - * @link http://www.workerman.net/ - * @license http://www.opensource.org/licenses/mit-license.php MIT License - */ - -use Workerman\Worker; -//慢进程,nginx反向代理部分需要慢执行的路由到TASK_LISTEN的端口进程执行解决堵塞问题 -//https://www.workerman.net/doc/webman/others/task.html -$task = [ - 'name' => 'name', - 'handler' => \Webman\App::class, - 'listen' => getenv('TASK_LISTEN'), - 'count' => 8, // 进程数 - 'user' => '', - 'group' => '', - 'reusePort' => true, - 'constructor' => [ - 'request_class' => \support\Request::class, // request类设置 - 'logger' => \support\Log::channel('default'), // 日志实例 - 'app_path' => app_path(), // app目录位置 - 'public_path' => public_path() // public目录位置 - ] -]; -$returnData = [ - // File update detection and automatic reload - 'monitor' => [ - 'handler' => process\Monitor::class, - 'reloadable' => false, - 'constructor' => [ - // Monitor these directories - 'monitor_dir' => array_merge([ - app_path(), - config_path(), - base_path() . '/process', - base_path() . '/support', - base_path() . '/other_resource', - base_path() . '/.env', - ], glob(base_path() . '/plugin/*/app'), glob(base_path() . '/plugin/*/config'), glob(base_path() . '/plugin/*/api')), - // Files with these suffixes will be monitored - 'monitor_extensions' => [ - 'php', 'html', 'htm', 'env' - ], - 'options' => [ - 'enable_file_monitor' => !Worker::$daemonize && DIRECTORY_SEPARATOR === '/', - 'enable_memory_monitor' => DIRECTORY_SEPARATOR === '/', - ] - ] - ], -]; -if (getenv('TASK_STATUS',false)===true){ - $returnData['task'] = $task; -} -return $returnData; + + * @copyright walkor + * @link http://www.workerman.net/ + * @license http://www.opensource.org/licenses/mit-license.php MIT License + */ + +use app\crontab\Task; +use Workerman\Worker; +//慢进程,nginx反向代理部分需要慢执行的路由到TASK_LISTEN的端口进程执行解决堵塞问题 +//https://www.workerman.net/doc/webman/others/task.html +$task = [ + 'name' => 'name', + 'handler' => \Webman\App::class, + 'listen' => getenv('SLOW_SERVER_LISTEN'), + 'count' => 8, // 进程数 + 'user' => '', + 'group' => '', + 'reusePort' => true, + 'constructor' => [ + 'request_class' => \support\Request::class, // request类设置 + 'logger' => \support\Log::channel('default'), // 日志实例 + 'app_path' => app_path(), // app目录位置 + 'public_path' => public_path() // public目录位置 + ] +]; +/** + * crontab并不是异步的,例如一个task进程里设置了A和B两个定时器,都是每秒执行一次任务,但是A任务耗时10秒,那么B需要等待A执行完才能被执行,导致B执行会有延迟。 + * 'task1' => [ + * 'handler' => process\Task1::class + * ], + * 'task2' => [ + * 'handler' => process\Task2::class + * ], + */ +$crontabs = [ + 'crontab'=>[ + 'handler' => Task::class + ] +]; +$returnData = [ + // File update detection and automatic reload + 'monitor' => [ + 'handler' => process\Monitor::class, + 'reloadable' => false, + 'constructor' => [ + // Monitor these directories + 'monitor_dir' => array_merge([ + app_path(), + config_path(), + base_path() . '/process', + base_path() . '/support', + base_path() . '/other_resource', + base_path() . '/.env', + ], glob(base_path() . '/plugin/*/app'), glob(base_path() . '/plugin/*/config'), glob(base_path() . '/plugin/*/api')), + // Files with these suffixes will be monitored + 'monitor_extensions' => [ + 'php', 'html', 'htm', 'env' + ], + 'options' => [ + 'enable_file_monitor' => !Worker::$daemonize && DIRECTORY_SEPARATOR === '/', + 'enable_memory_monitor' => DIRECTORY_SEPARATOR === '/', + ] + ] + ], +]; +if (getenv('SLOW_PROCESS_STATUS',false)){ + $returnData['slow_process'] = $task; +} +if (getenv('CRONTAB_STATUS',false)){ + foreach ($crontabs as $crontabKey=>$crontab){ + $returnData[$crontabKey] = $crontab; + } +} +return $returnData; -- Gitee From 84aef89d9660caabc9908fc5f45ade049f59b850 Mon Sep 17 00:00:00 2001 From: suyi Date: Thu, 14 Mar 2024 14:55:23 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../generator/core/VueApiGenerator.php | 272 ++--- .../generator/core/VueEditGenerator.php | 970 +++++++++--------- .../generator/core/VueIndexGenerator.php | 600 +++++------ .../common/service/pay/WeChatPayService.php | 792 +++++++------- 4 files changed, 1317 insertions(+), 1317 deletions(-) diff --git a/server/app/common/service/generator/core/VueApiGenerator.php b/server/app/common/service/generator/core/VueApiGenerator.php index 3b9dbaf..87775ac 100644 --- a/server/app/common/service/generator/core/VueApiGenerator.php +++ b/server/app/common/service/generator/core/VueApiGenerator.php @@ -1,137 +1,137 @@ -getCommentContent(), - $this->getUpperCamelName(), - $this->getRouteContent(), - ]; - - $templatePath = $this->getTemplatePath('vue/api'); - - // 替换内容 - $content = $this->replaceFileData($needReplace, $waitReplace, $templatePath); - - $this->setContent($content); - } - - - /** - * @notes 描述 - * @return mixed - * @author bingo - * @date 2022/6/22 18:19 - */ - public function getCommentContent() - { - return $this->tableData['table_comment']; - } - - - /** - * @notes 路由名称 - * @return array|string|string[] - * @author bingo - * @date 2022/6/22 18:19 - */ - public function getRouteContent() - { - $content = $this->getTableName(); - if (!empty($this->classDir)) { - $content = $this->classDir . '/' . $this->classComment; - } - return $content; - } - - - /** - * @notes 获取文件生成到模块的文件夹路径 - * @return mixed|void - * @author bingo - * @date 2022/6/22 18:19 - */ - public function getModuleGenerateDir() - { - $admin_url = env('GENERATOR.GENERATORURL',false); - if ($admin_url){ - $dir = $admin_url . '/src/api/'; - }else{ - $dir = dirname(root_path()). '/adminapi/src/api/'; - } - $this->checkDir($dir); - return $dir; - } - - - /** - * @notes 获取文件生成到runtime的文件夹路径 - * @return string - * @author bingo - * @date 2022/6/22 18:20 - */ - public function getRuntimeGenerateDir() - { - $dir = $this->generatorDir . 'vue/src/api/'; - $this->checkDir($dir); - return $dir; - } - - - /** - * @notes 生成的文件名 - * @return string - * @author bingo - * @date 2022/6/22 18:20 - */ - public function getGenerateName() - { - return $this->getLowerTableName() . '.ts'; - } - - - /** - * @notes 文件信息 - * @return array - * @author bingo - * @date 2022/6/23 15:57 - */ - public function fileInfo(): array - { - return [ - 'name' => $this->getGenerateName(), - 'type' => 'ts', - 'content' => $this->content - ]; - } - - +getCommentContent(), + $this->getUpperCamelName(), + $this->getRouteContent(), + ]; + + $templatePath = $this->getTemplatePath('vue/api'); + + // 替换内容 + $content = $this->replaceFileData($needReplace, $waitReplace, $templatePath); + + $this->setContent($content); + } + + + /** + * @notes 描述 + * @return mixed + * @author bingo + * @date 2022/6/22 18:19 + */ + public function getCommentContent() + { + return $this->tableData['table_comment']; + } + + + /** + * @notes 路由名称 + * @return array|string|string[] + * @author bingo + * @date 2022/6/22 18:19 + */ + public function getRouteContent() + { + $content = $this->getTableName(); + if (!empty($this->classDir)) { + $content = $this->classDir . '/' . $this->classComment; + } + return $content; + } + + + /** + * @notes 获取文件生成到模块的文件夹路径 + * @return mixed|void + * @author bingo + * @date 2022/6/22 18:19 + */ + public function getModuleGenerateDir() + { + $admin_url = getenv('GENERATOR.GENERATORURL',false); + if ($admin_url){ + $dir = $admin_url . '/src/api/'; + }else{ + $dir = dirname(root_path()). '/adminapi/src/api/'; + } + $this->checkDir($dir); + return $dir; + } + + + /** + * @notes 获取文件生成到runtime的文件夹路径 + * @return string + * @author bingo + * @date 2022/6/22 18:20 + */ + public function getRuntimeGenerateDir() + { + $dir = $this->generatorDir . 'vue/src/api/'; + $this->checkDir($dir); + return $dir; + } + + + /** + * @notes 生成的文件名 + * @return string + * @author bingo + * @date 2022/6/22 18:20 + */ + public function getGenerateName() + { + return $this->getLowerTableName() . '.ts'; + } + + + /** + * @notes 文件信息 + * @return array + * @author bingo + * @date 2022/6/23 15:57 + */ + public function fileInfo(): array + { + return [ + 'name' => $this->getGenerateName(), + 'type' => 'ts', + 'content' => $this->content + ]; + } + + } \ No newline at end of file diff --git a/server/app/common/service/generator/core/VueEditGenerator.php b/server/app/common/service/generator/core/VueEditGenerator.php index 315f990..26f4d0f 100644 --- a/server/app/common/service/generator/core/VueEditGenerator.php +++ b/server/app/common/service/generator/core/VueEditGenerator.php @@ -1,486 +1,486 @@ -getFormViewContent(), - $this->getUpperCamelName(), - $this->getDictDataContent(), - $this->getDictDataApiContent(), - $this->getFormDataContent(), - $this->getFormValidateContent(), - $this->tableData['table_comment'], - $this->getPkContent(), - $this->getTableName(), - $this->getCheckBoxJoinContent(), - $this->getCheckBoxSplitContent(), - $this->getFormDateContent(), - $this->getLowerCamelName(), - $this->getImportListsContent(), - $this->getTreeConstContent(), - $this->getTreeListsContent(), - ]; - - $templatePath = $this->getTemplatePath('vue/edit'); - - // 替换内容 - $content = $this->replaceFileData($needReplace, $waitReplace, $templatePath); - - $this->setContent($content); - } - - - /** - * @notes 复选框处理 - * @return string - * @author bingo - * @date 2022/6/24 19:30 - */ - public function getCheckBoxJoinContent() - { - $content = ''; - foreach ($this->tableColumn as $column) { - if (empty($column['view_type']) || $column['is_pk']) { - continue; - } - if ($column['view_type'] != 'checkbox') { - continue; - } - $content .= $column['column_name'] . ': formData.' . $column['column_name'] . '.join(",")' . PHP_EOL; - } - if (!empty($content)) { - $content = substr($content, 0, -1); - } - return $content; - } - - - /** - * @notes 复选框处理 - * @return string - * @author bingo - * @date 2022/6/24 19:30 - */ - public function getCheckBoxSplitContent() - { - $content = ''; - foreach ($this->tableColumn as $column) { - if (empty($column['view_type']) || $column['is_pk']) { - continue; - } - if ($column['view_type'] != 'checkbox') { - continue; - } - $content .= '//@ts-ignore' . PHP_EOL; - $content .= 'data.' . $column['column_name'] . ' && ' .'(formData.' . $column['column_name'] . ' = String(data.' . $column['column_name'] . ').split(","))' . PHP_EOL; - } - if (!empty($content)) { - $content = substr($content, 0, -1); - } - return $this->setBlankSpace($content, ' '); - } - - - /** - * @notes 树表contst - * @return string - * @author bingo - * @date 2022/12/22 18:19 - */ - public function getTreeConstContent() - { - $content = ""; - if ($this->isTreeCrud()) { - $content = file_get_contents($this->getTemplatePath('vue/other_item/editTreeConst')); - } - return $content; - } - - - /** - * @notes 获取树表列表 - * @return string - * @author bingo - * @date 2022/12/22 18:26 - */ - public function getTreeListsContent() - { - $content = ''; - if (!$this->isTreeCrud()) { - return $content; - } - - $needReplace = [ - '{TREE_ID}', - '{TREE_NAME}', - '{UPPER_CAMEL_NAME}', - ]; - $waitReplace = [ - $this->treeConfig['tree_id'], - $this->treeConfig['tree_name'], - $this->getUpperCamelName(), - ]; - - $templatePath = $this->getTemplatePath('vue/other_item/editTreeLists'); - if (file_exists($templatePath)) { - $content = $this->replaceFileData($needReplace, $waitReplace, $templatePath); - } - - return $content; - } - - - /** - * @notes 表单日期处理 - * @return string - * @author bingo - * @date 2022/6/27 16:45 - */ - public function getFormDateContent() - { - $content = ''; - foreach ($this->tableColumn as $column) { - if (empty($column['view_type']) || $column['is_pk']) { - continue; - } - if ($column['view_type'] != 'datetime' || $column['column_type'] != 'int') { - continue; - } - $content .= '//@ts-ignore' . PHP_EOL; - $content .= 'formData.' . $column['column_name'] . ' = timeFormat(formData.' . $column['column_name'] . ','."'yyyy-mm-dd hh:MM:ss'".') ' . PHP_EOL; - } - if (!empty($content)) { - $content = substr($content, 0, -1); - } - return $this->setBlankSpace($content, ' '); - } - - - /** - * @notes 获取表单内容 - * @return string - * @author bingo - * @date 2022/6/23 11:57 - */ - public function getFormViewContent() - { - $content = ''; - foreach ($this->tableColumn as $column) { - if (!$column['is_insert'] || !$column['is_update'] || $column['is_pk']) { - continue; - } - $needReplace = [ - '{COLUMN_COMMENT}', - '{COLUMN_NAME}', - '{DICT_TYPE}', - ]; - $waitReplace = [ - $column['column_comment'], - $column['column_name'], - $column['dict_type'], - ]; - - $viewType = $column['view_type']; - // 树表,树状结构下拉框 - if ($this->isTreeCrud() && $column['column_name'] == $this->treeConfig['tree_pid']) { - $viewType = 'treeSelect'; - array_push($needReplace, '{TREE_ID}', '{TREE_NAME}'); - array_push($waitReplace, $this->treeConfig['tree_id'], $this->treeConfig['tree_name']); - } - - $templatePath = $this->getTemplatePath('vue/form_item/' . $viewType); - if (!file_exists($templatePath)) { - continue; - } - - // 单选框值处理 - if ($column['view_type'] == 'radio' || $column['view_type'] == 'select') { - $stubItemValue = 'item.value'; - $intFieldValue = ['tinyint', 'smallint', 'mediumint', 'int', 'integer', 'bigint']; - if (in_array($column['column_type'], $intFieldValue)) { - $stubItemValue = 'parseInt(item.value)'; - } - array_push($needReplace, '{ITEM_VALUE}'); - array_push($waitReplace, $stubItemValue); - } - - $content .= $this->replaceFileData($needReplace, $waitReplace, $templatePath) . PHP_EOL; - } - - if (!empty($content)) { - $content = substr($content, 0, -1); - } - - $content = $this->setBlankSpace($content, ' '); - return $content; - } - - - /** - * @notes 获取字典数据内容 - * @return string - * @author bingo - * @date 2022/6/23 11:58 - */ - public function getDictDataContent() - { - $content = ''; - $isExist = []; - foreach ($this->tableColumn as $column) { - if (empty($column['dict_type']) || $column['is_pk']) { - continue; - } - if (in_array($column['dict_type'], $isExist)) { - continue; - } - $content .= $column['dict_type'] . ': ' . "[]," . PHP_EOL; - $isExist[] = $column['dict_type']; - } - if (!empty($content)) { - $content = substr($content, 0, -1); - } - return $this->setBlankSpace($content, ' '); - } - - - /** - * @notes 获取字典数据api内容 - * @return false|string - * @author bingo - * @date 2022/6/23 11:58 - */ - public function getDictDataApiContent() - { - $content = ''; - $isExist = []; - foreach ($this->tableColumn as $column) { - if (empty($column['dict_type']) || $column['is_pk']) { - continue; - } - if (in_array($column['dict_type'], $isExist)) { - continue; - } - $needReplace = [ - '{UPPER_CAMEL_NAME}', - '{DICT_TYPE}', - ]; - $waitReplace = [ - $this->getUpperCamelName(), - $column['dict_type'], - ]; - $templatePath = $this->getTemplatePath('vue/other_item/dictDataApi'); - if (!file_exists($templatePath)) { - continue; - } - $content .= $this->replaceFileData($needReplace, $waitReplace, $templatePath) . '' . PHP_EOL; - - $isExist[] = $column['dict_type']; - } - $content = substr($content, 0, -1); - return $content; - } - - - /** - * @notes 获取表单默认字段内容 - * @return string - * @author bingo - * @date 2022/6/23 15:15 - */ - public function getFormDataContent() - { - $content = ''; - $isExist = []; - foreach ($this->tableColumn as $column) { - if (!$column['is_insert'] || !$column['is_update'] || $column['is_pk']) { - continue; - } - if (in_array($column['column_name'], $isExist)) { - continue; - } - - // 复选框类型返回数组 - if ($column['view_type'] == 'checkbox') { - $content .= $column['column_name'] . ': ' . "[]," . PHP_EOL; - } else { - $content .= $column['column_name'] . ': ' . "''," . PHP_EOL; - } - - $isExist[] = $column['column_name']; - } - if (!empty($content)) { - $content = substr($content, 0, -1); - } - return $this->setBlankSpace($content, ' '); - } - - - /** - * @notes 表单验证内容 - * @return false|string - * @author bingo - * @date 2022/6/23 15:16 - */ - public function getFormValidateContent() - { - $content = ''; - $isExist = []; - $specDictType = ['input', 'textarea', 'editor']; - - foreach ($this->tableColumn as $column) { - if (!$column['is_required'] || $column['is_pk']) { - continue; - } - if (in_array($column['column_name'], $isExist)) { - continue; - } - - $validateMsg = in_array($column['view_type'], $specDictType) ? '请输入' : '请选择'; - $validateMsg .= $column['column_comment']; - - $needReplace = [ - '{COLUMN_NAME}', - '{VALIDATE_MSG}', - ]; - $waitReplace = [ - $column['column_name'], - $validateMsg, - ]; - $templatePath = $this->getTemplatePath('vue/other_item/formValidate'); - if (!file_exists($templatePath)) { - continue; - } - - $content .= $this->replaceFileData($needReplace, $waitReplace, $templatePath) . ',' . PHP_EOL; - - $isExist[] = $column['column_name']; - } - $content = substr($content, 0, -2); - return $content; - } - - - /** - * @notes 树表时导入列表 - * @author bingo - * @date 2022/12/23 9:56 - */ - public function getImportListsContent() - { - $content = ""; - if ($this->isTreeCrud()) { - $content = "api". $this->getUpperCamelName(). 'Lists,'; - } - - if (empty($content)) { - return $content; - } - - return $this->setBlankSpace($content, ' '); - } - - - /** - * @notes 获取文件生成到模块的文件夹路径 - * @return mixed|void - * @author bingo - * @date 2022/6/22 18:19 - */ - public function getModuleGenerateDir() - { - $admin_url = env('GENERATOR.GENERATORURL',false); - if ($admin_url){ - $dir = $admin_url . '/src/views/' . $this->getTableName() . '/'; - }else{ - $dir = dirname(root_path()). '/adminapi/src/views/' . $this->getTableName() . '/'; - } - $this->checkDir($dir); - return $dir; - } - - - /** - * @notes 获取文件生成到runtime的文件夹路径 - * @return string - * @author bingo - * @date 2022/6/22 18:20 - */ - public function getRuntimeGenerateDir() - { - $dir = $this->generatorDir . 'vue/src/views/' . $this->getTableName() . '/'; - $this->checkDir($dir); - return $dir; - } - - - /** - * @notes 生成的文件名 - * @return string - * @author bingo - * @date 2022/6/22 18:20 - */ - public function getGenerateName() - { - return 'edit.vue'; - } - - - /** - * @notes 文件信息 - * @return array - * @author bingo - * @date 2022/6/23 15:57 - */ - public function fileInfo(): array - { - return [ - 'name' => $this->getGenerateName(), - 'type' => 'vue', - 'content' => $this->content - ]; - } - - +getFormViewContent(), + $this->getUpperCamelName(), + $this->getDictDataContent(), + $this->getDictDataApiContent(), + $this->getFormDataContent(), + $this->getFormValidateContent(), + $this->tableData['table_comment'], + $this->getPkContent(), + $this->getTableName(), + $this->getCheckBoxJoinContent(), + $this->getCheckBoxSplitContent(), + $this->getFormDateContent(), + $this->getLowerCamelName(), + $this->getImportListsContent(), + $this->getTreeConstContent(), + $this->getTreeListsContent(), + ]; + + $templatePath = $this->getTemplatePath('vue/edit'); + + // 替换内容 + $content = $this->replaceFileData($needReplace, $waitReplace, $templatePath); + + $this->setContent($content); + } + + + /** + * @notes 复选框处理 + * @return string + * @author bingo + * @date 2022/6/24 19:30 + */ + public function getCheckBoxJoinContent() + { + $content = ''; + foreach ($this->tableColumn as $column) { + if (empty($column['view_type']) || $column['is_pk']) { + continue; + } + if ($column['view_type'] != 'checkbox') { + continue; + } + $content .= $column['column_name'] . ': formData.' . $column['column_name'] . '.join(",")' . PHP_EOL; + } + if (!empty($content)) { + $content = substr($content, 0, -1); + } + return $content; + } + + + /** + * @notes 复选框处理 + * @return string + * @author bingo + * @date 2022/6/24 19:30 + */ + public function getCheckBoxSplitContent() + { + $content = ''; + foreach ($this->tableColumn as $column) { + if (empty($column['view_type']) || $column['is_pk']) { + continue; + } + if ($column['view_type'] != 'checkbox') { + continue; + } + $content .= '//@ts-ignore' . PHP_EOL; + $content .= 'data.' . $column['column_name'] . ' && ' .'(formData.' . $column['column_name'] . ' = String(data.' . $column['column_name'] . ').split(","))' . PHP_EOL; + } + if (!empty($content)) { + $content = substr($content, 0, -1); + } + return $this->setBlankSpace($content, ' '); + } + + + /** + * @notes 树表contst + * @return string + * @author bingo + * @date 2022/12/22 18:19 + */ + public function getTreeConstContent() + { + $content = ""; + if ($this->isTreeCrud()) { + $content = file_get_contents($this->getTemplatePath('vue/other_item/editTreeConst')); + } + return $content; + } + + + /** + * @notes 获取树表列表 + * @return string + * @author bingo + * @date 2022/12/22 18:26 + */ + public function getTreeListsContent() + { + $content = ''; + if (!$this->isTreeCrud()) { + return $content; + } + + $needReplace = [ + '{TREE_ID}', + '{TREE_NAME}', + '{UPPER_CAMEL_NAME}', + ]; + $waitReplace = [ + $this->treeConfig['tree_id'], + $this->treeConfig['tree_name'], + $this->getUpperCamelName(), + ]; + + $templatePath = $this->getTemplatePath('vue/other_item/editTreeLists'); + if (file_exists($templatePath)) { + $content = $this->replaceFileData($needReplace, $waitReplace, $templatePath); + } + + return $content; + } + + + /** + * @notes 表单日期处理 + * @return string + * @author bingo + * @date 2022/6/27 16:45 + */ + public function getFormDateContent() + { + $content = ''; + foreach ($this->tableColumn as $column) { + if (empty($column['view_type']) || $column['is_pk']) { + continue; + } + if ($column['view_type'] != 'datetime' || $column['column_type'] != 'int') { + continue; + } + $content .= '//@ts-ignore' . PHP_EOL; + $content .= 'formData.' . $column['column_name'] . ' = timeFormat(formData.' . $column['column_name'] . ','."'yyyy-mm-dd hh:MM:ss'".') ' . PHP_EOL; + } + if (!empty($content)) { + $content = substr($content, 0, -1); + } + return $this->setBlankSpace($content, ' '); + } + + + /** + * @notes 获取表单内容 + * @return string + * @author bingo + * @date 2022/6/23 11:57 + */ + public function getFormViewContent() + { + $content = ''; + foreach ($this->tableColumn as $column) { + if (!$column['is_insert'] || !$column['is_update'] || $column['is_pk']) { + continue; + } + $needReplace = [ + '{COLUMN_COMMENT}', + '{COLUMN_NAME}', + '{DICT_TYPE}', + ]; + $waitReplace = [ + $column['column_comment'], + $column['column_name'], + $column['dict_type'], + ]; + + $viewType = $column['view_type']; + // 树表,树状结构下拉框 + if ($this->isTreeCrud() && $column['column_name'] == $this->treeConfig['tree_pid']) { + $viewType = 'treeSelect'; + array_push($needReplace, '{TREE_ID}', '{TREE_NAME}'); + array_push($waitReplace, $this->treeConfig['tree_id'], $this->treeConfig['tree_name']); + } + + $templatePath = $this->getTemplatePath('vue/form_item/' . $viewType); + if (!file_exists($templatePath)) { + continue; + } + + // 单选框值处理 + if ($column['view_type'] == 'radio' || $column['view_type'] == 'select') { + $stubItemValue = 'item.value'; + $intFieldValue = ['tinyint', 'smallint', 'mediumint', 'int', 'integer', 'bigint']; + if (in_array($column['column_type'], $intFieldValue)) { + $stubItemValue = 'parseInt(item.value)'; + } + array_push($needReplace, '{ITEM_VALUE}'); + array_push($waitReplace, $stubItemValue); + } + + $content .= $this->replaceFileData($needReplace, $waitReplace, $templatePath) . PHP_EOL; + } + + if (!empty($content)) { + $content = substr($content, 0, -1); + } + + $content = $this->setBlankSpace($content, ' '); + return $content; + } + + + /** + * @notes 获取字典数据内容 + * @return string + * @author bingo + * @date 2022/6/23 11:58 + */ + public function getDictDataContent() + { + $content = ''; + $isExist = []; + foreach ($this->tableColumn as $column) { + if (empty($column['dict_type']) || $column['is_pk']) { + continue; + } + if (in_array($column['dict_type'], $isExist)) { + continue; + } + $content .= $column['dict_type'] . ': ' . "[]," . PHP_EOL; + $isExist[] = $column['dict_type']; + } + if (!empty($content)) { + $content = substr($content, 0, -1); + } + return $this->setBlankSpace($content, ' '); + } + + + /** + * @notes 获取字典数据api内容 + * @return false|string + * @author bingo + * @date 2022/6/23 11:58 + */ + public function getDictDataApiContent() + { + $content = ''; + $isExist = []; + foreach ($this->tableColumn as $column) { + if (empty($column['dict_type']) || $column['is_pk']) { + continue; + } + if (in_array($column['dict_type'], $isExist)) { + continue; + } + $needReplace = [ + '{UPPER_CAMEL_NAME}', + '{DICT_TYPE}', + ]; + $waitReplace = [ + $this->getUpperCamelName(), + $column['dict_type'], + ]; + $templatePath = $this->getTemplatePath('vue/other_item/dictDataApi'); + if (!file_exists($templatePath)) { + continue; + } + $content .= $this->replaceFileData($needReplace, $waitReplace, $templatePath) . '' . PHP_EOL; + + $isExist[] = $column['dict_type']; + } + $content = substr($content, 0, -1); + return $content; + } + + + /** + * @notes 获取表单默认字段内容 + * @return string + * @author bingo + * @date 2022/6/23 15:15 + */ + public function getFormDataContent() + { + $content = ''; + $isExist = []; + foreach ($this->tableColumn as $column) { + if (!$column['is_insert'] || !$column['is_update'] || $column['is_pk']) { + continue; + } + if (in_array($column['column_name'], $isExist)) { + continue; + } + + // 复选框类型返回数组 + if ($column['view_type'] == 'checkbox') { + $content .= $column['column_name'] . ': ' . "[]," . PHP_EOL; + } else { + $content .= $column['column_name'] . ': ' . "''," . PHP_EOL; + } + + $isExist[] = $column['column_name']; + } + if (!empty($content)) { + $content = substr($content, 0, -1); + } + return $this->setBlankSpace($content, ' '); + } + + + /** + * @notes 表单验证内容 + * @return false|string + * @author bingo + * @date 2022/6/23 15:16 + */ + public function getFormValidateContent() + { + $content = ''; + $isExist = []; + $specDictType = ['input', 'textarea', 'editor']; + + foreach ($this->tableColumn as $column) { + if (!$column['is_required'] || $column['is_pk']) { + continue; + } + if (in_array($column['column_name'], $isExist)) { + continue; + } + + $validateMsg = in_array($column['view_type'], $specDictType) ? '请输入' : '请选择'; + $validateMsg .= $column['column_comment']; + + $needReplace = [ + '{COLUMN_NAME}', + '{VALIDATE_MSG}', + ]; + $waitReplace = [ + $column['column_name'], + $validateMsg, + ]; + $templatePath = $this->getTemplatePath('vue/other_item/formValidate'); + if (!file_exists($templatePath)) { + continue; + } + + $content .= $this->replaceFileData($needReplace, $waitReplace, $templatePath) . ',' . PHP_EOL; + + $isExist[] = $column['column_name']; + } + $content = substr($content, 0, -2); + return $content; + } + + + /** + * @notes 树表时导入列表 + * @author bingo + * @date 2022/12/23 9:56 + */ + public function getImportListsContent() + { + $content = ""; + if ($this->isTreeCrud()) { + $content = "api". $this->getUpperCamelName(). 'Lists,'; + } + + if (empty($content)) { + return $content; + } + + return $this->setBlankSpace($content, ' '); + } + + + /** + * @notes 获取文件生成到模块的文件夹路径 + * @return mixed|void + * @author bingo + * @date 2022/6/22 18:19 + */ + public function getModuleGenerateDir() + { + $admin_url = getenv('GENERATOR.GENERATORURL',false); + if ($admin_url){ + $dir = $admin_url . '/src/views/' . $this->getTableName() . '/'; + }else{ + $dir = dirname(root_path()). '/adminapi/src/views/' . $this->getTableName() . '/'; + } + $this->checkDir($dir); + return $dir; + } + + + /** + * @notes 获取文件生成到runtime的文件夹路径 + * @return string + * @author bingo + * @date 2022/6/22 18:20 + */ + public function getRuntimeGenerateDir() + { + $dir = $this->generatorDir . 'vue/src/views/' . $this->getTableName() . '/'; + $this->checkDir($dir); + return $dir; + } + + + /** + * @notes 生成的文件名 + * @return string + * @author bingo + * @date 2022/6/22 18:20 + */ + public function getGenerateName() + { + return 'edit.vue'; + } + + + /** + * @notes 文件信息 + * @return array + * @author bingo + * @date 2022/6/23 15:57 + */ + public function fileInfo(): array + { + return [ + 'name' => $this->getGenerateName(), + 'type' => 'vue', + 'content' => $this->content + ]; + } + + } \ No newline at end of file diff --git a/server/app/common/service/generator/core/VueIndexGenerator.php b/server/app/common/service/generator/core/VueIndexGenerator.php index 3913274..b89b6b9 100644 --- a/server/app/common/service/generator/core/VueIndexGenerator.php +++ b/server/app/common/service/generator/core/VueIndexGenerator.php @@ -1,301 +1,301 @@ -getSearchViewContent(), - $this->getListsViewContent(), - $this->getUpperCamelName(), - $this->getQueryParamsContent(), - $this->getDictDataContent(), - $this->getPkContent(), - $this->getTableName(), - $this->getPermsContent(), - $this->getPermsContent('edit'), - $this->getPermsContent('delete'), - $this->getLowerCamelName() - ]; - - $templatePath = $this->getTemplatePath('vue/index'); - - if ($this->isTreeCrud()) { - // 插入树表相关 - array_push($needReplace, '{TREE_ID}', '{TREE_PID}'); - array_push($waitReplace, $this->treeConfig['tree_id'], $this->treeConfig['tree_pid']); - $templatePath = $this->getTemplatePath('vue/index-tree'); - } - - // 替换内容 - $content = $this->replaceFileData($needReplace, $waitReplace, $templatePath); - - $this->setContent($content); - } - - - /** - * @notes 获取搜索内容 - * @return string - * @author bingo - * @date 2022/6/23 11:57 - */ - public function getSearchViewContent() - { - $content = ''; - foreach ($this->tableColumn as $column) { - if (!$column['is_query'] || $column['is_pk']) { - continue; - } - - $needReplace = [ - '{COLUMN_COMMENT}', - '{COLUMN_NAME}', - '{DICT_TYPE}', - ]; - $waitReplace = [ - $column['column_comment'], - $column['column_name'], - $column['dict_type'], - ]; - - $searchStubType = $column['view_type']; - if ($column['view_type'] == 'radio') { - $searchStubType = 'select'; - } - - $templatePath = $this->getTemplatePath('vue/search_item/' . $searchStubType); - if (!file_exists($templatePath)) { - continue; - } - $content .= $this->replaceFileData($needReplace, $waitReplace, $templatePath) . PHP_EOL; - } - - if (!empty($content)) { - $content = substr($content, 0, -1); - } - - $content = $this->setBlankSpace($content, ' '); - return $content; - } - - - /** - * @notes 获取列表内容 - * @return string - * @author bingo - * @date 2022/6/23 11:57 - */ - public function getListsViewContent() - { - $content = ''; - foreach ($this->tableColumn as $column) { - if (!$column['is_lists']) { - continue; - } - - $needReplace = [ - '{COLUMN_COMMENT}', - '{COLUMN_NAME}', - '{DICT_TYPE}', - ]; - $waitReplace = [ - $column['column_comment'], - $column['column_name'], - $column['dict_type'], - ]; - - $templatePath = $this->getTemplatePath('vue/table_item/default'); - if ($column['view_type'] == 'imageSelect') { - $templatePath = $this->getTemplatePath('vue/table_item/image'); - } - if (in_array($column['view_type'], ['select', 'radio', 'checkbox'])) { - $templatePath = $this->getTemplatePath('vue/table_item/options'); - } - if ($column['column_type'] == 'int' && $column['view_type'] == 'datetime') { - $templatePath = $this->getTemplatePath('vue/table_item/datetime'); - } - if (!file_exists($templatePath)) { - continue; - } - - $content .= $this->replaceFileData($needReplace, $waitReplace, $templatePath) . PHP_EOL; - } - if (!empty($content)) { - $content = substr($content, 0, -1); - } - return $this->setBlankSpace($content, ' '); - } - - - /** - * @notes 获取查询条件内容 - * @return string - * @author bingo - * @date 2022/6/23 11:57 - */ - public function getQueryParamsContent() - { - $content = ''; - $queryDate = false; - foreach ($this->tableColumn as $column) { - if (!$column['is_query'] || $column['is_pk']) { - continue; - } - $content .= $column['column_name'] . ": ''," . PHP_EOL; - if ($column['query_type'] == 'between' && $column['view_type'] == 'datetime') { - $queryDate = true; - } - } - if ($queryDate) { - $content .= "start_time: ''," . PHP_EOL; - $content .= "end_time: ''," . PHP_EOL; - } - $content = substr($content, 0, -2); - return $this->setBlankSpace($content, ' '); - } - - - /** - * @notes 获取字典数据内容 - * @return string - * @author bingo - * @date 2022/6/23 11:58 - */ - public function getDictDataContent() - { - $content = ''; - $isExist = []; - foreach ($this->tableColumn as $column) { - if (empty($column['dict_type']) || $column['is_pk']) { - continue; - } - if (in_array($column['dict_type'], $isExist)) { - continue; - } - $content .= $column['dict_type'] .","; - $isExist[] = $column['dict_type']; - } - if (!empty($content)) { - $content = substr($content, 0, -1); - } - return $this->setBlankSpace($content, ''); - } - - - /** - * @notes 权限规则 - * @param string $type - * @return string - * @author bingo - * @date 2022/7/7 9:47 - */ - public function getPermsContent($type = 'add') - { - if (!empty($this->classDir)) { - $classDir = $this->classDir . '.'; - } else { - $classDir = ''; - } - return trim($classDir . $this->getLowerTableName() . '/' . $type); - } - - - /** - * @notes 获取文件生成到模块的文件夹路径 - * @return mixed|void - * @author bingo - * @date 2022/6/22 18:19 - */ - public function getModuleGenerateDir() - { - $admin_url = env('GENERATOR.GENERATORURL',false); - if ($admin_url){ - $dir = $admin_url . '/src/views/' . $this->getLowerTableName() . '/'; - }else{ - $dir = dirname(root_path()) . '/adminapi/src/views/' . $this->getLowerTableName() . '/'; - } - $this->checkDir($dir); - return $dir; - } - - - /** - * @notes 获取文件生成到runtime的文件夹路径 - * @return string - * @author bingo - * @date 2022/6/22 18:20 - */ - public function getRuntimeGenerateDir() - { - $dir = $this->generatorDir . 'vue/src/views/' . $this->getLowerTableName() . '/'; - $this->checkDir($dir); - return $dir; - } - - - /** - * @notes 生成的文件名 - * @return string - * @author bingo - * @date 2022/6/22 18:20 - */ - public function getGenerateName() - { - return 'index.vue'; - } - - - /** - * @notes 文件信息 - * @return array - * @author bingo - * @date 2022/6/23 15:57 - */ - public function fileInfo(): array - { - return [ - 'name' => $this->getGenerateName(), - 'type' => 'vue', - 'content' => $this->content - ]; - } - - +getSearchViewContent(), + $this->getListsViewContent(), + $this->getUpperCamelName(), + $this->getQueryParamsContent(), + $this->getDictDataContent(), + $this->getPkContent(), + $this->getTableName(), + $this->getPermsContent(), + $this->getPermsContent('edit'), + $this->getPermsContent('delete'), + $this->getLowerCamelName() + ]; + + $templatePath = $this->getTemplatePath('vue/index'); + + if ($this->isTreeCrud()) { + // 插入树表相关 + array_push($needReplace, '{TREE_ID}', '{TREE_PID}'); + array_push($waitReplace, $this->treeConfig['tree_id'], $this->treeConfig['tree_pid']); + $templatePath = $this->getTemplatePath('vue/index-tree'); + } + + // 替换内容 + $content = $this->replaceFileData($needReplace, $waitReplace, $templatePath); + + $this->setContent($content); + } + + + /** + * @notes 获取搜索内容 + * @return string + * @author bingo + * @date 2022/6/23 11:57 + */ + public function getSearchViewContent() + { + $content = ''; + foreach ($this->tableColumn as $column) { + if (!$column['is_query'] || $column['is_pk']) { + continue; + } + + $needReplace = [ + '{COLUMN_COMMENT}', + '{COLUMN_NAME}', + '{DICT_TYPE}', + ]; + $waitReplace = [ + $column['column_comment'], + $column['column_name'], + $column['dict_type'], + ]; + + $searchStubType = $column['view_type']; + if ($column['view_type'] == 'radio') { + $searchStubType = 'select'; + } + + $templatePath = $this->getTemplatePath('vue/search_item/' . $searchStubType); + if (!file_exists($templatePath)) { + continue; + } + $content .= $this->replaceFileData($needReplace, $waitReplace, $templatePath) . PHP_EOL; + } + + if (!empty($content)) { + $content = substr($content, 0, -1); + } + + $content = $this->setBlankSpace($content, ' '); + return $content; + } + + + /** + * @notes 获取列表内容 + * @return string + * @author bingo + * @date 2022/6/23 11:57 + */ + public function getListsViewContent() + { + $content = ''; + foreach ($this->tableColumn as $column) { + if (!$column['is_lists']) { + continue; + } + + $needReplace = [ + '{COLUMN_COMMENT}', + '{COLUMN_NAME}', + '{DICT_TYPE}', + ]; + $waitReplace = [ + $column['column_comment'], + $column['column_name'], + $column['dict_type'], + ]; + + $templatePath = $this->getTemplatePath('vue/table_item/default'); + if ($column['view_type'] == 'imageSelect') { + $templatePath = $this->getTemplatePath('vue/table_item/image'); + } + if (in_array($column['view_type'], ['select', 'radio', 'checkbox'])) { + $templatePath = $this->getTemplatePath('vue/table_item/options'); + } + if ($column['column_type'] == 'int' && $column['view_type'] == 'datetime') { + $templatePath = $this->getTemplatePath('vue/table_item/datetime'); + } + if (!file_exists($templatePath)) { + continue; + } + + $content .= $this->replaceFileData($needReplace, $waitReplace, $templatePath) . PHP_EOL; + } + if (!empty($content)) { + $content = substr($content, 0, -1); + } + return $this->setBlankSpace($content, ' '); + } + + + /** + * @notes 获取查询条件内容 + * @return string + * @author bingo + * @date 2022/6/23 11:57 + */ + public function getQueryParamsContent() + { + $content = ''; + $queryDate = false; + foreach ($this->tableColumn as $column) { + if (!$column['is_query'] || $column['is_pk']) { + continue; + } + $content .= $column['column_name'] . ": ''," . PHP_EOL; + if ($column['query_type'] == 'between' && $column['view_type'] == 'datetime') { + $queryDate = true; + } + } + if ($queryDate) { + $content .= "start_time: ''," . PHP_EOL; + $content .= "end_time: ''," . PHP_EOL; + } + $content = substr($content, 0, -2); + return $this->setBlankSpace($content, ' '); + } + + + /** + * @notes 获取字典数据内容 + * @return string + * @author bingo + * @date 2022/6/23 11:58 + */ + public function getDictDataContent() + { + $content = ''; + $isExist = []; + foreach ($this->tableColumn as $column) { + if (empty($column['dict_type']) || $column['is_pk']) { + continue; + } + if (in_array($column['dict_type'], $isExist)) { + continue; + } + $content .= $column['dict_type'] .","; + $isExist[] = $column['dict_type']; + } + if (!empty($content)) { + $content = substr($content, 0, -1); + } + return $this->setBlankSpace($content, ''); + } + + + /** + * @notes 权限规则 + * @param string $type + * @return string + * @author bingo + * @date 2022/7/7 9:47 + */ + public function getPermsContent($type = 'add') + { + if (!empty($this->classDir)) { + $classDir = $this->classDir . '.'; + } else { + $classDir = ''; + } + return trim($classDir . $this->getLowerTableName() . '/' . $type); + } + + + /** + * @notes 获取文件生成到模块的文件夹路径 + * @return mixed|void + * @author bingo + * @date 2022/6/22 18:19 + */ + public function getModuleGenerateDir() + { + $admin_url = getenv('GENERATOR.GENERATORURL',false); + if ($admin_url){ + $dir = $admin_url . '/src/views/' . $this->getLowerTableName() . '/'; + }else{ + $dir = dirname(root_path()) . '/adminapi/src/views/' . $this->getLowerTableName() . '/'; + } + $this->checkDir($dir); + return $dir; + } + + + /** + * @notes 获取文件生成到runtime的文件夹路径 + * @return string + * @author bingo + * @date 2022/6/22 18:20 + */ + public function getRuntimeGenerateDir() + { + $dir = $this->generatorDir . 'vue/src/views/' . $this->getLowerTableName() . '/'; + $this->checkDir($dir); + return $dir; + } + + + /** + * @notes 生成的文件名 + * @return string + * @author bingo + * @date 2022/6/22 18:20 + */ + public function getGenerateName() + { + return 'index.vue'; + } + + + /** + * @notes 文件信息 + * @return array + * @author bingo + * @date 2022/6/23 15:57 + */ + public function fileInfo(): array + { + return [ + 'name' => $this->getGenerateName(), + 'type' => 'vue', + 'content' => $this->content + ]; + } + + } \ No newline at end of file diff --git a/server/app/common/service/pay/WeChatPayService.php b/server/app/common/service/pay/WeChatPayService.php index 22d9f78..4a38e0c 100644 --- a/server/app/common/service/pay/WeChatPayService.php +++ b/server/app/common/service/pay/WeChatPayService.php @@ -1,397 +1,397 @@ -terminal = $terminal; - $this->config = WeChatConfigService::getPayConfigByTerminal($terminal); - $this->app = new Application($this->config); - if ($userId !== null) { - $this->auth = UserAuth::where(['user_id' => $userId, 'terminal' => $terminal])->findOrEmpty(); - } - } - - - /** - * @notes 发起微信支付统一下单 - * @param $from - * @param $order - * @return array|false|string - * @author 段誉 - * @date 2021/8/4 15:05 - */ - public function pay($from, $order) - { - try { - switch ($this->terminal) { - case UserTerminalEnum::WECHAT_MMP: - $config = WeChatConfigService::getMnpConfig(); - $result = $this->jsapiPay($from, $order, $config['app_id']); - break; - case UserTerminalEnum::WECHAT_OA: - $config = WeChatConfigService::getOaConfig(); - $result = $this->jsapiPay($from, $order, $config['app_id']); - break; - case UserTerminalEnum::IOS: - case UserTerminalEnum::ANDROID: - $config = WeChatConfigService::getOpConfig(); - $result = $this->appPay($from, $order, $config['app_id']); - break; - case UserTerminalEnum::H5: - $config = WeChatConfigService::getOaConfig(); - $result = $this->mwebPay($from, $order, $config['app_id']); - break; - case UserTerminalEnum::PC: - $config = WeChatConfigService::getOaConfig(); - $result = $this->nativePay($from, $order, $config['app_id']); - break; - default: - throw new \Exception('支付方式错误'); - } - - return [ - 'config' => $result, - 'pay_way' => PayEnum::WECHAT_PAY - ]; - } catch (\Exception $e) { - $this->setError($e->getMessage()); - return false; - } - } - - - /** - * @notes jsapiPay - * @param $from - * @param $order - * @param $appId - * @return mixed - * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException - * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException - * @author 段誉 - * @date 2023/2/28 12:12 - */ - public function jsapiPay($from, $order, $appId) - { - $response = $this->app->getClient()->postJson("v3/pay/transactions/jsapi", [ - "appid" => $appId, - "mchid" => $this->config['mch_id'], - "description" => $this->payDesc($from), - "out_trade_no" => $order['pay_sn'], - "notify_url" => $this->config['notify_url'], - "amount" => [ - "total" => intval($order['order_amount'] * 100), - ], - "payer" => [ - "openid" => $this->auth['openid'] - ], - 'attach' => $from - ]); - - $result = $response->toArray(false); - $this->checkResultFail($result); - return $this->getPrepayConfig($result['prepay_id'], $appId); - } - - - /** - * @notes 网站native - * @param $from - * @param $order - * @param $appId - * @return mixed - * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException - * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException - * @author 段誉 - * @date 2023/2/28 12:12 - */ - public function nativePay($from, $order, $appId) - { - $response = $this->app->getClient()->postJson('v3/pay/transactions/native', [ - 'appid' => $appId, - 'mchid' => $this->config['mch_id'], - 'description' => $this->payDesc($from), - 'out_trade_no' => $order['pay_sn'], - 'notify_url' => $this->config['notify_url'], - 'amount' => [ - 'total' => intval($order['order_amount'] * 100), - ], - 'attach' => $from - ]); - $result = $response->toArray(false); - $this->checkResultFail($result); - return $result['code_url']; - } - - - /** - * @notes appPay - * @param $from - * @param $order - * @param $appId - * @return mixed - * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException - * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException - * @author 段誉 - * @date 2023/2/28 12:12 - */ - public function appPay($from, $order, $appId) - { - $response = $this->app->getClient()->postJson('v3/pay/transactions/app', [ - 'appid' => $appId, - 'mchid' => $this->config['mch_id'], - 'description' => $this->payDesc($from), - 'out_trade_no' => $order['pay_sn'], - 'notify_url' => $this->config['notify_url'], - 'amount' => [ - 'total' => intval($order['order_amount'] * 100), - ], - 'attach' => $from - ]); - $result = $response->toArray(false); - $this->checkResultFail($result); - return $result['prepay_id']; - } - - - /** - * @notes h5 - * @param $from - * @param $order - * @param $appId - * @param $redirectUrl - * @return mixed - * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException - * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException - * @author 段誉 - * @date 2023/2/28 12:13 - */ - public function mwebPay($from, $order, $appId) - { - $response = $this->app->getClient()->postJson('v3/pay/transactions/h5', [ - 'appid' => $appId, - 'mchid' => $this->config['mch_id'], - 'description' => $this->payDesc($from), - 'out_trade_no' => $order['pay_sn'], - 'notify_url' => $this->config['notify_url'], - 'amount' => [ - 'total' => intval($order['order_amount'] * 100), - ], - 'attach' => $from, - 'scene_info' => [ - 'payer_client_ip' => request()->getRemoteIp(), - 'h5_info' => [ - 'type' => 'Wap', - ] - ] - ]); - $result = $response->toArray(false); - $this->checkResultFail($result); - - $domain = request()->domain(); - if (!empty(env('project.test_web_domain')) && env('APP_DEBUG')) { - $domain = env('project.test_web_domain'); - } - $redirectUrl = $domain . '/mobile'. $order['redirect_url'] .'?id=' . $order['id'] . '&from='. $from . '&checkPay=true'; - return $result['h5_url'] . '&redirect_url=' . urlencode($redirectUrl); - } - - - /** - * @notes 退款 - * @param array $refundData - * @return mixed - * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException - * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException - * @author 段誉 - * @date 2023/2/28 16:53 - */ - public function refund(array $refundData) - { - $response = $this->app->getClient()->postJson('v3/refund/domestic/refunds', [ - 'transaction_id' => $refundData['transaction_id'], - 'out_refund_no' => $refundData['refund_sn'], - 'amount' => [ - 'refund' => intval($refundData['refund_amount'] * 100), - 'total' => intval($refundData['total_amount'] * 100), - 'currency' => 'CNY', - ] - ]); - $result = $response->toArray(false); - $this->checkResultFail($result); - return $result; - } - - - /** - * @notes 查询退款 - * @param $refundSn - * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException - * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException - * @author 段誉 - * @date 2023/3/1 11:16 - */ - public function queryRefund($refundSn) - { - $response = $this->app->getClient()->get("v3/refund/domestic/refunds/{$refundSn}"); - return $response->toArray(false); - } - - - /** - * @notes 支付描述 - * @param $from - * @return string - * @author 段誉 - * @date 2023/2/27 17:54 - */ - public function payDesc($from) - { - $desc = [ - 'order' => '商品', - 'recharge' => '充值', - ]; - return $desc[$from] ?? '商品'; - } - - - /** - * @notes 捕获错误 - * @param $result - * @throws \Exception - * @author 段誉 - * @date 2023/2/28 12:09 - */ - public function checkResultFail($result) - { - if (!empty($result['code']) || !empty($result['message'])) { - throw new \Exception('微信:'. $result['code'] . '-' . $result['message']); - } - } - - - /** - * @notes 预支付配置 - * @param $prepayId - * @param $appId - * @return mixed[] - * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException - * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException - * @author 段誉 - * @date 2023/2/28 17:38 - */ - public function getPrepayConfig($prepayId, $appId) - { - return $this->app->getUtils()->buildBridgeConfig($prepayId, $appId); - } - - - /** - * @notes 支付回调 - * @return \Psr\Http\Message\ResponseInterface - * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException - * @throws \EasyWeChat\Kernel\Exceptions\RuntimeException - * @throws \ReflectionException - * @throws \Throwable - * @author 段誉 - * @date 2023/2/28 14:20 - */ - public function notify() - { - $server = $this->app->getServer(); - // 支付通知 - $server->handlePaid(function (Message $message) { - if ($message['trade_state'] === 'SUCCESS') { - $extra['transaction_id'] = $message['transaction_id']; - $attach = $message['attach']; - $message['out_trade_no'] = mb_substr($message['out_trade_no'], 0, 18); - switch ($attach) { - case 'recharge': - $order = RechargeOrder::where(['sn' => $message['out_trade_no']])->findOrEmpty(); - if($order->isEmpty() || $order->pay_status == PayEnum::ISPAID) { - return true; - } - PayNotifyLogic::handle('recharge', $message['out_trade_no'], $extra); - break; - } - } - return true; - }); - - // 退款通知 - $server->handleRefunded(function (Message $message) { - return true; - }); - return $server->serve(); - } - - - - - +terminal = $terminal; + $this->config = WeChatConfigService::getPayConfigByTerminal($terminal); + $this->app = new Application($this->config); + if ($userId !== null) { + $this->auth = UserAuth::where(['user_id' => $userId, 'terminal' => $terminal])->findOrEmpty(); + } + } + + + /** + * @notes 发起微信支付统一下单 + * @param $from + * @param $order + * @return array|false|string + * @author 段誉 + * @date 2021/8/4 15:05 + */ + public function pay($from, $order) + { + try { + switch ($this->terminal) { + case UserTerminalEnum::WECHAT_MMP: + $config = WeChatConfigService::getMnpConfig(); + $result = $this->jsapiPay($from, $order, $config['app_id']); + break; + case UserTerminalEnum::WECHAT_OA: + $config = WeChatConfigService::getOaConfig(); + $result = $this->jsapiPay($from, $order, $config['app_id']); + break; + case UserTerminalEnum::IOS: + case UserTerminalEnum::ANDROID: + $config = WeChatConfigService::getOpConfig(); + $result = $this->appPay($from, $order, $config['app_id']); + break; + case UserTerminalEnum::H5: + $config = WeChatConfigService::getOaConfig(); + $result = $this->mwebPay($from, $order, $config['app_id']); + break; + case UserTerminalEnum::PC: + $config = WeChatConfigService::getOaConfig(); + $result = $this->nativePay($from, $order, $config['app_id']); + break; + default: + throw new \Exception('支付方式错误'); + } + + return [ + 'config' => $result, + 'pay_way' => PayEnum::WECHAT_PAY + ]; + } catch (\Exception $e) { + $this->setError($e->getMessage()); + return false; + } + } + + + /** + * @notes jsapiPay + * @param $from + * @param $order + * @param $appId + * @return mixed + * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException + * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException + * @author 段誉 + * @date 2023/2/28 12:12 + */ + public function jsapiPay($from, $order, $appId) + { + $response = $this->app->getClient()->postJson("v3/pay/transactions/jsapi", [ + "appid" => $appId, + "mchid" => $this->config['mch_id'], + "description" => $this->payDesc($from), + "out_trade_no" => $order['pay_sn'], + "notify_url" => $this->config['notify_url'], + "amount" => [ + "total" => intval($order['order_amount'] * 100), + ], + "payer" => [ + "openid" => $this->auth['openid'] + ], + 'attach' => $from + ]); + + $result = $response->toArray(false); + $this->checkResultFail($result); + return $this->getPrepayConfig($result['prepay_id'], $appId); + } + + + /** + * @notes 网站native + * @param $from + * @param $order + * @param $appId + * @return mixed + * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException + * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException + * @author 段誉 + * @date 2023/2/28 12:12 + */ + public function nativePay($from, $order, $appId) + { + $response = $this->app->getClient()->postJson('v3/pay/transactions/native', [ + 'appid' => $appId, + 'mchid' => $this->config['mch_id'], + 'description' => $this->payDesc($from), + 'out_trade_no' => $order['pay_sn'], + 'notify_url' => $this->config['notify_url'], + 'amount' => [ + 'total' => intval($order['order_amount'] * 100), + ], + 'attach' => $from + ]); + $result = $response->toArray(false); + $this->checkResultFail($result); + return $result['code_url']; + } + + + /** + * @notes appPay + * @param $from + * @param $order + * @param $appId + * @return mixed + * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException + * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException + * @author 段誉 + * @date 2023/2/28 12:12 + */ + public function appPay($from, $order, $appId) + { + $response = $this->app->getClient()->postJson('v3/pay/transactions/app', [ + 'appid' => $appId, + 'mchid' => $this->config['mch_id'], + 'description' => $this->payDesc($from), + 'out_trade_no' => $order['pay_sn'], + 'notify_url' => $this->config['notify_url'], + 'amount' => [ + 'total' => intval($order['order_amount'] * 100), + ], + 'attach' => $from + ]); + $result = $response->toArray(false); + $this->checkResultFail($result); + return $result['prepay_id']; + } + + + /** + * @notes h5 + * @param $from + * @param $order + * @param $appId + * @param $redirectUrl + * @return mixed + * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException + * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException + * @author 段誉 + * @date 2023/2/28 12:13 + */ + public function mwebPay($from, $order, $appId) + { + $response = $this->app->getClient()->postJson('v3/pay/transactions/h5', [ + 'appid' => $appId, + 'mchid' => $this->config['mch_id'], + 'description' => $this->payDesc($from), + 'out_trade_no' => $order['pay_sn'], + 'notify_url' => $this->config['notify_url'], + 'amount' => [ + 'total' => intval($order['order_amount'] * 100), + ], + 'attach' => $from, + 'scene_info' => [ + 'payer_client_ip' => request()->getRemoteIp(), + 'h5_info' => [ + 'type' => 'Wap', + ] + ] + ]); + $result = $response->toArray(false); + $this->checkResultFail($result); + + $domain = request()->domain(); + if (!empty(getenv('project.test_web_domain')) && getenv('APP_DEBUG')) { + $domain = getenv('project.test_web_domain'); + } + $redirectUrl = $domain . '/mobile'. $order['redirect_url'] .'?id=' . $order['id'] . '&from='. $from . '&checkPay=true'; + return $result['h5_url'] . '&redirect_url=' . urlencode($redirectUrl); + } + + + /** + * @notes 退款 + * @param array $refundData + * @return mixed + * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException + * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException + * @author 段誉 + * @date 2023/2/28 16:53 + */ + public function refund(array $refundData) + { + $response = $this->app->getClient()->postJson('v3/refund/domestic/refunds', [ + 'transaction_id' => $refundData['transaction_id'], + 'out_refund_no' => $refundData['refund_sn'], + 'amount' => [ + 'refund' => intval($refundData['refund_amount'] * 100), + 'total' => intval($refundData['total_amount'] * 100), + 'currency' => 'CNY', + ] + ]); + $result = $response->toArray(false); + $this->checkResultFail($result); + return $result; + } + + + /** + * @notes 查询退款 + * @param $refundSn + * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException + * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException + * @author 段誉 + * @date 2023/3/1 11:16 + */ + public function queryRefund($refundSn) + { + $response = $this->app->getClient()->get("v3/refund/domestic/refunds/{$refundSn}"); + return $response->toArray(false); + } + + + /** + * @notes 支付描述 + * @param $from + * @return string + * @author 段誉 + * @date 2023/2/27 17:54 + */ + public function payDesc($from) + { + $desc = [ + 'order' => '商品', + 'recharge' => '充值', + ]; + return $desc[$from] ?? '商品'; + } + + + /** + * @notes 捕获错误 + * @param $result + * @throws \Exception + * @author 段誉 + * @date 2023/2/28 12:09 + */ + public function checkResultFail($result) + { + if (!empty($result['code']) || !empty($result['message'])) { + throw new \Exception('微信:'. $result['code'] . '-' . $result['message']); + } + } + + + /** + * @notes 预支付配置 + * @param $prepayId + * @param $appId + * @return mixed[] + * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException + * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException + * @author 段誉 + * @date 2023/2/28 17:38 + */ + public function getPrepayConfig($prepayId, $appId) + { + return $this->app->getUtils()->buildBridgeConfig($prepayId, $appId); + } + + + /** + * @notes 支付回调 + * @return \Psr\Http\Message\ResponseInterface + * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException + * @throws \EasyWeChat\Kernel\Exceptions\RuntimeException + * @throws \ReflectionException + * @throws \Throwable + * @author 段誉 + * @date 2023/2/28 14:20 + */ + public function notify() + { + $server = $this->app->getServer(); + // 支付通知 + $server->handlePaid(function (Message $message) { + if ($message['trade_state'] === 'SUCCESS') { + $extra['transaction_id'] = $message['transaction_id']; + $attach = $message['attach']; + $message['out_trade_no'] = mb_substr($message['out_trade_no'], 0, 18); + switch ($attach) { + case 'recharge': + $order = RechargeOrder::where(['sn' => $message['out_trade_no']])->findOrEmpty(); + if($order->isEmpty() || $order->pay_status == PayEnum::ISPAID) { + return true; + } + PayNotifyLogic::handle('recharge', $message['out_trade_no'], $extra); + break; + } + } + return true; + }); + + // 退款通知 + $server->handleRefunded(function (Message $message) { + return true; + }); + return $server->serve(); + } + + + + + } \ No newline at end of file -- Gitee From 6fc79a6fbc3b97ef1f44011860b0f2e3e5626da0 Mon Sep 17 00:00:00 2001 From: suyi Date: Thu, 14 Mar 2024 14:56:44 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E6=B3=A8=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/config/process.php | 1 + 1 file changed, 1 insertion(+) diff --git a/server/config/process.php b/server/config/process.php index 2e93387..c40b535 100644 --- a/server/config/process.php +++ b/server/config/process.php @@ -39,6 +39,7 @@ $task = [ * 'task2' => [ * 'handler' => process\Task2::class * ], + * https://www.workerman.net/doc/webman/components/crontab.html */ $crontabs = [ 'crontab'=>[ -- Gitee