diff --git a/application/admin/controller/Oplog.php b/application/admin/controller/Oplog.php
new file mode 100644
index 000000000..8a9c25086
--- /dev/null
+++ b/application/admin/controller/Oplog.php
@@ -0,0 +1,86 @@
+title = '系统操作日志';
+ $query = $this->_query($this->table)->like('action,node,content,username,geoip');
+ $query->dateBetween('create_at')->order('id desc')->page();
+ }
+
+ /**
+ * 列表数据处理
+ * @param array $data
+ * @throws \Exception
+ */
+ protected function _index_page_filter(&$data)
+ {
+ $ip = new \Ip2Region();
+ foreach ($data as &$vo) {
+ $result = $ip->btreeSearch($vo['geoip']);
+ $vo['isp'] = isset($result['region']) ? $result['region'] : '';
+ $vo['isp'] = str_replace(['内网IP', '0', '|'], '', $vo['isp']);
+ }
+ }
+
+ /**
+ * 清理系统日志
+ * @throws \think\Exception
+ * @throws \think\exception\PDOException
+ */
+ public function clear()
+ {
+ if (Db::name($this->table)->whereRaw('1=1')->delete() !== false) {
+ $this->success('日志清理成功!');
+ } else {
+ $this->error('日志清理失败,请稍候再试!');
+ }
+ }
+
+ /**
+ * 删除系统日志
+ */
+ public function remove()
+ {
+ $this->applyCsrfToken();
+ $this->_delete($this->table);
+ }
+
+}
\ No newline at end of file
diff --git a/application/admin/controller/api/Update.php b/application/admin/controller/api/Update.php
index 7de7557b7..0f33d3b94 100644
--- a/application/admin/controller/api/Update.php
+++ b/application/admin/controller/api/Update.php
@@ -47,7 +47,8 @@ class Update extends Controller
$file = env('root_path') . decode($encode);
if (!file_exists($file)) $this->error('获取文件内容失败!');
$this->success('获取文件内容成功!', [
- 'format' => 'base64', 'content' => base64_encode(file_get_contents($file)),
+ 'format' => 'base64',
+ 'content' => base64_encode(file_get_contents($file)),
]);
}
diff --git a/application/admin/queue/JobsQueue.php b/application/admin/queue/JobsQueue.php
new file mode 100644
index 000000000..32ef24016
--- /dev/null
+++ b/application/admin/queue/JobsQueue.php
@@ -0,0 +1,122 @@
+data = $data;
+ $this->output = new \think\console\Output();
+ $this->id = isset($data['_job_id_']) ? $data['_job_id_'] : '';
+ $this->title = isset($data['_job_title_']) ? $data['_job_title_'] : '';
+ $this->output->newLine();
+ $this->output->writeln(" system task {$this->id} execution start");
+ $this->output->writeln('---------------------------------------------');
+ QueueService::status($this->id, self::STATUS_PROC, $this->statusDesc);
+ if ($this->execute()) {
+ $this->output->writeln('---------------------------------------------');
+ $this->output->info(" successful");
+ $this->status = self::STATUS_COMP;
+ } else {
+ $this->output->writeln('---------------------------------------------');
+ $this->output->error(" failure");
+ $this->status = self::STATUS_FAIL;
+ }
+ $job->delete();
+ QueueService::status($this->id, $this->status, $this->statusDesc);
+ $this->output->writeln('---------------------------------------------');
+ $this->output->newLine();
+ }
+
+ /**
+ * 执行任务
+ * @return boolean
+ */
+ protected function execute()
+ {
+ return true;
+ }
+
+}
\ No newline at end of file
diff --git a/application/admin/service/AuthService.php b/application/admin/service/AuthService.php
new file mode 100644
index 000000000..24ea7a48e
--- /dev/null
+++ b/application/admin/service/AuthService.php
@@ -0,0 +1,176 @@
+column('node,is_menu,is_auth,is_login,title');
+ foreach (Node::getMethodTreeNode(env('app_path')) as $thr => $title) {
+ foreach ($ignore as $str) if (stripos($thr, $str) === 0) continue 2;
+ $tmp = explode('/', $thr);
+ list($one, $two) = ["{$tmp[0]}", "{$tmp[0]}/{$tmp[1]}"];
+ $nodes[$one] = array_merge(isset($alias[$one]) ? $alias[$one] : ['node' => $one, 'title' => '', 'is_menu' => 0, 'is_auth' => 0, 'is_login' => 0], ['pnode' => '']);
+ $nodes[$two] = array_merge(isset($alias[$two]) ? $alias[$two] : ['node' => $two, 'title' => isset($map[$two]) ? $map[$two] : '', 'is_menu' => 0, 'is_auth' => 0, 'is_login' => 0], ['pnode' => $one]);
+ $nodes[$thr] = array_merge(isset($alias[$thr]) ? $alias[$thr] : ['node' => $thr, 'title' => $title, 'is_menu' => 0, 'is_auth' => 0, 'is_login' => 0], ['pnode' => $two]);
+ }
+ foreach ($nodes as &$node) list($node['is_auth'], $node['is_menu'], $node['is_login']) = [intval($node['is_auth']), intval($node['is_menu']), empty($node['is_auth']) ? intval($node['is_login']) : 1];
+ return $nodes;
+ }
+
+ /**
+ * 检查用户节点权限
+ * @param string $node 节点
+ * @return boolean
+ */
+ public static function checkAuthNode($node)
+ {
+ list($module, $controller, $action) = explode('/', str_replace(['?', '=', '&'], '/', "{$node}///"));
+ $current = Node::parseString("{$module}/{$controller}") . strtolower("/{$action}");
+ // 后台入口无需要验证权限
+ if (stripos($node, 'admin/index') === 0) return true;
+ // 超级管理员无需要验证权限
+ if (session('user.username') === 'admin') return true;
+ // 未配置权限的节点默认放行
+ if (!in_array($current, self::getAuthNode())) return true;
+ // 用户指定角色授权放行
+ return in_array($current, (array)session('user.nodes'));
+ }
+
+ /**
+ * 获取授权节点
+ * @return array
+ */
+ public static function getAuthNode()
+ {
+ $nodes = cache('need_access_node');
+ if (empty($nodes)) {
+ $nodes = Db::name('SystemNode')->where(['is_auth' => '1'])->column('node');
+ cache('need_access_node', $nodes);
+ }
+ return $nodes;
+ }
+
+ /**
+ * 应用用户权限节点
+ * @return boolean
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\ModelNotFoundException
+ * @throws \think\exception\DbException
+ */
+ public static function applyNode()
+ {
+ cache('need_access_node', null);
+ if (($uid = session('user.id'))) session('user', Db::name('SystemUser')->where('id', $uid)->find());
+ if (session('user.authorize') && ($ids = explode(',', session('user.authorize')))) {
+ $auths = Db::name('SystemAuth')->whereIn('id', $ids)->where('status', '1')->column('id');
+ if (empty($auths)) return session('user.nodes', []);
+ return session('user.nodes', Db::name('SystemAuthNode')->whereIn('auth', $auths)->column('node'));
+ }
+ return false;
+ }
+
+ /**
+ * 判断用户登录状态
+ * @return boolean
+ */
+ public static function isLogin()
+ {
+ return !!session('user');
+ }
+
+ /**
+ * 获取授权后的菜单
+ * @return array
+ * @throws \ReflectionException
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\ModelNotFoundException
+ * @throws \think\exception\DbException
+ */
+ public static function getAuthMenu()
+ {
+ self::applyNode();
+ $list = Db::name('SystemMenu')->where('status', '1')->order('sort asc,id asc')->select();
+ return self::buildMenuData(Data::arr2tree($list), self::get(), self::isLogin());
+ }
+
+ /**
+ * 后台主菜单权限过滤
+ * @param array $menus 当前菜单列表
+ * @param array $nodes 系统权限节点数据
+ * @param bool $isLogin 是否已经登录
+ * @return array
+ */
+ private static function buildMenuData($menus, $nodes, $isLogin)
+ {
+ foreach ($menus as $key => &$menu) {
+ if (!empty($menu['sub'])) $menu['sub'] = self::buildMenuData($menu['sub'], $nodes, $isLogin);
+ if (!empty($menu['sub'])) $menu['url'] = '#';
+ elseif (preg_match('/^https?\:/i', $menu['url'])) continue;
+ elseif ($menu['url'] !== '#') {
+ $node = join('/', array_slice(explode('/', preg_replace('/[\W]/', '/', $menu['url'])), 0, 3));
+ $menu['url'] = url($menu['url']) . (empty($menu['params']) ? '' : "?{$menu['params']}");
+ if (isset($nodes[$node]) && $nodes[$node]['is_login'] && empty($isLogin)) unset($menus[$key]);
+ elseif (isset($nodes[$node]) && $nodes[$node]['is_auth'] && $isLogin && !self::checkAuthNode($node)) unset($menus[$key]);
+ } else unset($menus[$key]);
+ }
+ return $menus;
+ }
+
+ /**
+ * 检查密码是否合法
+ * @param string $password
+ * @return array
+ */
+ public static function checkPassword($password)
+ {
+ $password = trim($password);
+ if (!strlen($password) >= 6) {
+ return ['code' => 0, 'msg' => '密码必须大于6字符!'];
+ }
+ if (!preg_match("/^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{6,32}$/", $password)) {
+ return ['code' => 0, 'msg' => '密码必需包含大小写字母、数字、符号任意两者组合!'];
+ }
+ return ['code' => 1, 'msg' => '密码复杂度通过验证!'];
+ }
+
+}
diff --git a/application/admin/service/MessageService.php b/application/admin/service/MessageService.php
new file mode 100644
index 000000000..452e9fa8c
--- /dev/null
+++ b/application/admin/service/MessageService.php
@@ -0,0 +1,72 @@
+ $title, 'desc' => $desc, 'url' => $url, 'code' => $code, 'node' => $node];
+ return Db::name('SystemMessage')->insert($data) !== false;
+ }
+
+ /**
+ * 系统消息状态更新
+ * @param integer $code
+ * @return boolean
+ * @throws \think\Exception
+ * @throws \think\exception\PDOException
+ */
+ public static function set($code)
+ {
+ $result = Db::name('SystemMessage')->where(['code' => $code, 'read_state' => '0'])->update([
+ 'read_state' => '1', 'read_at' => date('Y-m-d H:i:s'), 'read_uid' => session('user.id'),
+ ]);
+ return $result !== false;
+ }
+
+ /**
+ * 获取消息列表成功
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\ModelNotFoundException
+ * @throws \think\exception\DbException
+ */
+ public static function gets()
+ {
+ $where = ['read_state' => '0'];
+ $list = Db::name('SystemMessage')->where($where)->order('id desc')->select();
+ foreach ($list as $key => $vo) if (!empty($vo['node']) && !auth($vo['node'])) unset($list[$key]);
+ return $list;
+ }
+
+}
\ No newline at end of file
diff --git a/application/admin/service/OplogService.php b/application/admin/service/OplogService.php
new file mode 100644
index 000000000..f03695d05
--- /dev/null
+++ b/application/admin/service/OplogService.php
@@ -0,0 +1,55 @@
+ Node::current(),
+ 'geoip' => PHP_SAPI === 'cli' ? '127.0.0.1' : request()->ip(),
+ 'action' => $action,
+ 'content' => $content,
+ 'username' => PHP_SAPI === 'cli' ? 'cli' : (string)session('user.username'),
+ ];
+ return Db::name('SystemLog')->insert($data) !== false;
+ }
+
+ /**
+ * 清理系统日志数据
+ * @return boolean
+ * @throws \think\Exception
+ * @throws \think\exception\PDOException
+ */
+ public static function clear()
+ {
+ return Db::name('SystemLog')->where('1=1')->delete() !== false;
+ }
+}
\ No newline at end of file
diff --git a/application/admin/service/QueueService.php b/application/admin/service/QueueService.php
new file mode 100644
index 000000000..ae41eda04
--- /dev/null
+++ b/application/admin/service/QueueService.php
@@ -0,0 +1,128 @@
+insertGetId([
+ 'title' => $title, 'later' => $later, 'uri' => $uri, 'double' => intval($double),
+ 'data' => json_encode($data, 256), 'desc' => $desc, 'status_at' => date('Y-m-d H:i:s'),
+ ]);
+ $data['_job_id_'] = $jobId;
+ $data['_job_title_'] = $title;
+ \think\Queue::later($later, $uri, $data);
+ }
+
+ /**
+ * 更新任务状态
+ * @param integer $jobId
+ * @param integer $status
+ * @param string $statusDesc
+ * @return boolean
+ * @throws \think\Exception
+ * @throws \think\exception\PDOException
+ */
+ public static function status($jobId, $status = self::STATUS_PEND, $statusDesc = '')
+ {
+ $result = Db::name('SystemJobsLog')->where(['id' => $jobId])->update([
+ 'status' => $status, 'status_desc' => $statusDesc, 'status_at' => date('Y-m-d H:i:s'),
+ ]);
+ return $result !== false;
+ }
+
+ /**
+ * 检查任务是否存在
+ * @param string $title
+ * @return boolean
+ */
+ public static function exists($title)
+ {
+ $where = [['title', 'eq', $title], ['status', 'in', [1, 2]]];
+ return Db::name('SystemJobsLog')->where($where)->count() > 0;
+ }
+
+ /**
+ * 获取任务数据
+ * @param integer $jobId
+ * @return array|null
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\ModelNotFoundException
+ * @throws \think\exception\DbException
+ */
+ public static function get($jobId)
+ {
+ return Db::name('SystemJobsLog')->where(['id' => $jobId])->find();
+ }
+
+ /**
+ * 删除任务数据
+ * @param integer $jobId
+ * @return boolean
+ * @throws \think\Exception
+ * @throws \think\exception\PDOException
+ */
+ public static function del($jobId)
+ {
+ $where = [['id', 'eq', $jobId], ['status', 'in', [1, 3, 4]]];
+ if (Db::name('SystemJobsLog')->where($where)->delete() > 0) {
+ Db::name('SystemJobs')->whereLike('payload', '%"_job_id_":"' . $jobId . '"%')->delete();
+ return true;
+ }
+ return false;
+ }
+
+}
\ No newline at end of file
diff --git a/application/admin/view/oplog/index.html b/application/admin/view/oplog/index.html
new file mode 100644
index 000000000..44bfe0ed4
--- /dev/null
+++ b/application/admin/view/oplog/index.html
@@ -0,0 +1,65 @@
+{extend name='main'}
+
+{block name="button"}
+
+{if auth("admin/oplog/clear")}
+
+{/if}
+
+{if auth("admin/oplog/remove")}
+
+{/if}
+
+{/block}
+
+{block name="content"}
+
+
+
+ {empty name='list'}
没有记录哦{else}{$pagehtml|raw|default=''}{/empty}
+
+
+
+{/block}
\ No newline at end of file
diff --git a/application/admin/view/oplog/index_search.html b/application/admin/view/oplog/index_search.html
new file mode 100644
index 000000000..265e38001
--- /dev/null
+++ b/application/admin/view/oplog/index_search.html
@@ -0,0 +1,56 @@
+
+
+
\ No newline at end of file
diff --git a/application/index/controller/Index.php b/application/index/controller/Index.php
index 85e61ff0b..7950b95cc 100644
--- a/application/index/controller/Index.php
+++ b/application/index/controller/Index.php
@@ -9,7 +9,7 @@
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
-// | github开源项目:https://github.com/zoujingli/ThinkAdmin
+// | github开源项目:https://github.com/zoujingli/framework
// +----------------------------------------------------------------------
namespace app\index\controller;
diff --git a/application/service/handler/PublishHandler.php b/application/service/handler/PublishHandler.php
new file mode 100644
index 000000000..d47c3c751
--- /dev/null
+++ b/application/service/handler/PublishHandler.php
@@ -0,0 +1,67 @@
+
+ * @date 2016/10/27 14:14
+ */
+class PublishHandler
+{
+
+ /**
+ * 当前微信APPID
+ * @var string
+ */
+ protected static $appid;
+
+ /**
+ * 事件初始化
+ * @param string $appid
+ * @return string
+ * @throws \WeChat\Exceptions\InvalidDecryptException
+ * @throws \think\Exception
+ * @throws \think\exception\PDOException
+ */
+ public static function handler($appid)
+ {
+ try {
+ $wechat = WechatService::WeChatReceive($appid);
+ } catch (\Exception $e) {
+ return "Wechat message handling failed, {$e->getMessage()}";
+ }
+ /* 分别执行对应类型的操作 */
+ switch (strtolower($wechat->getMsgType())) {
+ case 'text':
+ $receive = $wechat->getReceive();
+ if ($receive['Content'] === 'TESTCOMPONENT_MSG_TYPE_TEXT') {
+ return $wechat->text('TESTCOMPONENT_MSG_TYPE_TEXT_callback')->reply([], true);
+ }
+ $key = str_replace("QUERY_AUTH_CODE:", '', $receive['Content']);
+ WechatService::instance('Service')->getQueryAuthorizerInfo($key);
+ return $wechat->text("{$key}_from_api")->reply([], true);
+ case 'event':
+ $receive = $wechat->getReceive();
+ return $wechat->text("{$receive['Event']}from_callback")->reply([], true);
+ default:
+ return 'success';
+ }
+ }
+
+}
diff --git a/application/service/handler/ReceiveHandler.php b/application/service/handler/ReceiveHandler.php
new file mode 100644
index 000000000..dc6bcd688
--- /dev/null
+++ b/application/service/handler/ReceiveHandler.php
@@ -0,0 +1,64 @@
+
+ * @date 2016/10/27 14:14
+ */
+class ReceiveHandler
+{
+
+ /**
+ * 事件初始化
+ * @param string $appid
+ * @return string
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\ModelNotFoundException
+ * @throws \think\exception\DbException
+ * @throws \think\Exception
+ */
+ public static function handler($appid)
+ {
+ try {
+ $service = WechatService::WeChatReceive($appid);
+ } catch (\Exception $e) {
+ return "Wechat message handling failed, {$e->getMessage()}";
+ }
+ // 验证微信配置信息
+ $config = Db::name('WechatServiceConfig')->where(['authorizer_appid' => $appid])->find();
+ if (empty($config) || empty($config['appuri'])) {
+ \think\facade\Log::error(($message = "微信{$appid}授权配置验证无效"));
+ return $message;
+ }
+ try {
+ list($data, $openid) = [$service->getReceive(), $service->getOpenid()];
+ if (isset($data['EventKey']) && is_object($data['EventKey'])) $data['EventKey'] = (array)$data['EventKey'];
+ $input = ['openid' => $openid, 'appid' => $appid, 'receive' => serialize($data), 'encrypt' => intval($service->isEncrypt())];
+ if (is_string($result = http_post($config['appuri'], $input, ['timeout' => 30]))) {
+ return $result;
+ }
+ } catch (\Exception $e) {
+ \think\facade\Log::error("微信{$appid}接口调用异常,{$e->getMessage()}");
+ }
+ return 'success';
+ }
+
+}
diff --git a/application/service/handler/WechatHandler.php b/application/service/handler/WechatHandler.php
new file mode 100644
index 000000000..0b91cf972
--- /dev/null
+++ b/application/service/handler/WechatHandler.php
@@ -0,0 +1,160 @@
+
+ */
+class WechatHandler
+{
+ /**
+ * 当前微信APPID
+ * @var string
+ */
+ protected $appid;
+
+ /**
+ * 当前微信配置
+ * @var array
+ */
+ protected $config;
+
+ /**
+ * 错误消息
+ * @var string
+ */
+ protected $message;
+
+ /**
+ * Wechat constructor.
+ * @param array $config
+ */
+ public function __construct($config = [])
+ {
+ $this->config = $config;
+ $this->appid = isset($config['authorizer_appid']) ? $config['authorizer_appid'] : '';
+ }
+
+ /**
+ * 检查微信配置服务初始化状态
+ * @return boolean
+ * @throws \think\Exception
+ */
+ private function checkInit()
+ {
+ if (!empty($this->config)) return true;
+ throw new \think\Exception('Wechat Please bind Wechat first');
+ }
+
+ /**
+ * 获取当前公众号配置
+ * @return array|boolean
+ * @throws \think\Exception
+ */
+ public function getConfig()
+ {
+ $this->checkInit();
+ $info = Db::name('WechatServiceConfig')->where(['authorizer_appid' => $this->appid])->find();
+ if (empty($info)) return false;
+ if (isset($info['id'])) unset($info['id']);
+ return $info;
+ }
+
+ /**
+ * 设置微信接口通知URL地址
+ * @param string $notifyUri 接口通知URL地址
+ * @return boolean
+ * @throws \think\Exception
+ * @throws \think\exception\PDOException
+ */
+ public function setApiNotifyUri($notifyUri)
+ {
+ $this->checkInit();
+ if (empty($notifyUri)) throw new \think\Exception('请传入微信通知URL');
+ list($where, $data) = [['authorizer_appid' => $this->appid], ['appuri' => $notifyUri]];
+ return Db::name('WechatServiceConfig')->where($where)->update($data) !== false;
+ }
+
+ /**
+ * 更新接口Appkey(成功返回新的Appkey)
+ * @return bool|string
+ * @throws \think\Exception
+ * @throws \think\exception\PDOException
+ */
+ public function updateApiAppkey()
+ {
+ $this->checkInit();
+ $data = ['appkey' => md5(uniqid())];
+ Db::name('WechatServiceConfig')->where(['authorizer_appid' => $this->appid])->update($data);
+ return $data['appkey'];
+ }
+
+ /**
+ * 获取公众号的配置参数
+ * @param string $name 参数名称
+ * @return array|string
+ * @throws \think\Exception
+ */
+ public function config($name = null)
+ {
+ $this->checkInit();
+ return WechatLogic::WeChatScript($this->appid)->config->get($name);
+ }
+
+ /**
+ * 微信网页授权
+ * @param string $sessid 当前会话id(可用session_id()获取)
+ * @param string $selfUrl 当前会话URL地址(需包含域名的完整URL地址)
+ * @param int $fullMode 网页授权模式(0静默模式,1高级授权)
+ * @return array|bool
+ * @throws \think\Exception
+ */
+ public function oauth($sessid, $selfUrl, $fullMode = 0)
+ {
+ $this->checkInit();
+ $fans = cache("{$this->appid}_{$sessid}_fans");
+ $openid = cache("{$this->appid}_{$sessid}_openid");
+ if (!empty($openid) && (empty($fullMode) || !empty($fans))) {
+ return ['openid' => $openid, 'fans' => $fans, 'url' => ''];
+ }
+ $service = WechatLogic::service();
+ $mode = empty($fullMode) ? 'snsapi_base' : 'snsapi_userinfo';
+ $url = url('@service/api.push/oauth', '', true, true);
+ $params = ['mode' => $fullMode, 'sessid' => $sessid, 'enurl' => encode($selfUrl)];
+ $authurl = $service->getOauthRedirect($this->appid, $url . '?' . http_build_query($params), $mode);
+ return ['openid' => $openid, 'fans' => $fans, 'url' => $authurl];
+ }
+
+ /**
+ * 微信网页JS签名
+ * @param string $url 当前会话URL地址(需包含域名的完整URL地址)
+ * @return array|boolean
+ * @throws \WeChat\Exceptions\InvalidResponseException
+ * @throws \WeChat\Exceptions\LocalCacheException
+ * @throws \think\Exception
+ */
+ public function jsSign($url)
+ {
+ $this->checkInit();
+ return WechatLogic::WeChatScript($this->appid)->getJsSign($url);
+ }
+
+}
\ No newline at end of file
diff --git a/application/service/service/BuildService.php b/application/service/service/BuildService.php
new file mode 100644
index 000000000..562285632
--- /dev/null
+++ b/application/service/service/BuildService.php
@@ -0,0 +1,52 @@
+ env('runtime_path') . 'wechat',
+ 'component_appid' => sysconf('component_appid'),
+ 'component_token' => sysconf('component_token'),
+ 'component_appsecret' => sysconf('component_appsecret'),
+ 'component_encodingaeskey' => sysconf('component_encodingaeskey'),
+ ];
+ // 注册授权公众号 AccessToken 处理
+ $config['GetAccessTokenCallback'] = function ($authorizerAppid) use ($config) {
+ $where = ['authorizer_appid' => $authorizerAppid];
+ if (!($refreshToken = Db::name('WechatServiceConfig')->where($where)->value('authorizer_refresh_token'))) {
+ throw new \think\Exception('The WeChat information is not configured.', '404');
+ }
+ $open = new \WeOpen\MiniApp($config);
+ $result = $open->refreshAccessToken($authorizerAppid, $refreshToken);
+ if (empty($result['authorizer_access_token']) || empty($result['authorizer_refresh_token'])) {
+ throw new \think\Exception($result['errmsg'], '0');
+ }
+ Db::name('WechatServiceConfig')->where($where)->update([
+ 'authorizer_access_token' => $result['authorizer_access_token'],
+ 'authorizer_refresh_token' => $result['authorizer_refresh_token'],
+ ]);
+ return $result['authorizer_access_token'];
+ };
+ $app = new \WeOpen\MiniApp($config);
+ if (in_array(strtolower($name), ['service', 'miniapp'])) {
+ return $app;
+ }
+ if (!in_array($type, ['WeChat', 'WeMini'])) {
+ $type = self::$type;
+ }
+ return $app->instance($name, $appid, $type);
+ }
+
+ /**
+ * 静态初始化对象
+ * @param string $name
+ * @param array $arguments
+ * @return mixed
+ * @throws \think\Exception
+ * @throws \think\exception\PDOException
+ */
+ public static function __callStatic($name, $arguments)
+ {
+ if (substr($name, 0, 6) === 'WeMini') {
+ self::$type = 'WeMini';
+ $name = substr($name, 6);
+ } elseif (substr($name, 0, 6) === 'WeChat') {
+ self::$type = 'WeChat';
+ $name = substr($name, 6);
+ } elseif (substr($name, 0, 5) === 'WePay') {
+ self::$type = 'WePay';
+ $name = substr($name, 5);
+ }
+ return self::instance($name, isset($arguments[0]) ? $arguments[0] : '', self::$type);
+ }
+
+}
diff --git a/application/store/command/AutoRun.php b/application/store/command/AutoRun.php
index 16c97c437..c71ccf89b 100644
--- a/application/store/command/AutoRun.php
+++ b/application/store/command/AutoRun.php
@@ -14,9 +14,6 @@
namespace app\store\command;
-use think\console\Command;
-use think\console\Input;
-use think\console\Output;
use think\Db;
/**
@@ -24,7 +21,7 @@ use think\Db;
* Class AutoRun
* @package app\store\command
*/
-class AutoRun extends Command
+class AutoRun extends \think\console\Command
{
protected function configure()
@@ -34,20 +31,20 @@ class AutoRun extends Command
/**
* 业务指令执行
- * @param Input $input
- * @param Output $output
+ * @param \think\console\Input $input
+ * @param \think\console\Output $output
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/
- protected function execute(Input $input, Output $output)
+ protected function execute(\think\console\Input $input, \think\console\Output $output)
{
// 自动取消30分钟未支付的订单
$this->autoCancelOrder();
// 清理一天前未支付的订单
- $this->autoCleanOrder();
+ $this->autoRemoveOrder();
// 订单自动退款处理
// $this->autoRefundOrder();
// 提现自动打款处理
@@ -61,8 +58,9 @@ class AutoRun extends Command
*/
private function autoCancelOrder()
{
- $where = [['create_at', '<', date('Y-m-d H:i:s', strtotime('-30 minutes'))]];
- $count = Db::name('StoreOrder')->where(['pay_state' => '0'])->whereIn('status', ['1', '2'])->where($where)->update([
+ $datetime = $this->getDatetime('store_order_wait_time');
+ $where = [['status', 'in', ['1', '2']], ['pay_state', 'eq', '0'], ['create_at', '<', $datetime]];
+ $count = Db::name('StoreOrder')->where($where)->update([
'status' => '0',
'cancel_state' => '1',
'cancel_at' => date('Y-m-d H:i:s'),
@@ -83,14 +81,15 @@ class AutoRun extends Command
* @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/
- private function autoCleanOrder()
+ private function autoRemoveOrder()
{
- $where = [['create_at', '<', date('Y-m-d H:i:s', strtotime('-1 day'))]];
- $list = Db::name('StoreOrder')->where(['pay_state' => '0'])->where($where)->limit(20)->select();
- if (count($order_nos = array_unique(array_column($list, 'order_no'))) > 0) {
- $this->output->info("自动删除前一天已经取消的订单:\n\t" . join(',' . PHP_EOL . "\t", $order_nos));
- Db::name('StoreOrder')->whereIn('order_no', $order_nos)->delete();
- Db::name('StoreOrderList')->whereIn('order_no', $order_nos)->delete();
+ $datetime = $this->getDatetime('store_order_clear_time');
+ $where = [['status', 'eq', '0'], ['pay_state', 'eq', '0'], ['create_at', '<', $datetime]];
+ $list = Db::name('StoreOrder')->where($where)->limit(20)->select();
+ if (count($orderNos = array_unique(array_column($list, 'order_no'))) > 0) {
+ $this->output->info("自动删除前一天已经取消的订单:" . PHP_EOL . join(',' . PHP_EOL, $orderNos));
+ Db::name('StoreOrder')->whereIn('order_no', $orderNos)->delete();
+ Db::name('StoreOrderList')->whereIn('order_no', $orderNos)->delete();
} else {
$this->output->comment('没有需要自动删除前一天已经取消的订单!');
}
@@ -172,4 +171,17 @@ class AutoRun extends Command
}
}
+ /**
+ * 获取配置时间
+ * @param string $code
+ * @return string
+ * @throws \think\Exception
+ * @throws \think\exception\PDOException
+ */
+ private function getDatetime($code)
+ {
+ $minutes = intval(sysconf($code) * 60);
+ return date('Y-m-d H:i:s', strtotime("-{$minutes} minutes"));
+ }
+
}
\ No newline at end of file
diff --git a/application/store/controller/Config.php b/application/store/controller/Config.php
index 9bc44a18e..d94bba910 100644
--- a/application/store/controller/Config.php
+++ b/application/store/controller/Config.php
@@ -14,7 +14,7 @@
namespace app\store\controller;
-use app\store\service\Extend;
+use app\store\service\ExtendService;
use library\Controller;
/**
@@ -35,7 +35,7 @@ class Config extends Controller
$this->applyCsrfToken();
$this->title = '商城参数配置';
if ($this->request->isGet()) {
- $this->query = Extend::querySmsBalance();
+ $this->query = ExtendService::querySmsBalance();
$this->fetch();
} else {
foreach ($this->request->post() as $k => $v) sysconf($k, $v);
@@ -43,4 +43,22 @@ class Config extends Controller
}
}
+ /**
+ * 商城短信配置
+ * @throws \think\Exception
+ * @throws \think\exception\PDOException
+ */
+ public function sms()
+ {
+ $this->applyCsrfToken();
+ $this->title = '商城短信配置';
+ if ($this->request->isGet()) {
+ $this->query = ExtendService::querySmsBalance();
+ $this->fetch();
+ } else {
+ foreach ($this->request->post() as $k => $v) sysconf($k, $v);
+ $this->success('商城短信配置保存成功!');
+ }
+ }
+
}
\ No newline at end of file
diff --git a/application/store/controller/ExpressCompany.php b/application/store/controller/ExpressCompany.php
index f0f8649c5..0a4eec427 100644
--- a/application/store/controller/ExpressCompany.php
+++ b/application/store/controller/ExpressCompany.php
@@ -95,7 +95,7 @@ class ExpressCompany extends Controller
/**
* 删除快递公司
*/
- public function del()
+ public function remove()
{
$this->_delete($this->table);
}
diff --git a/application/store/controller/ExpressProvince.php b/application/store/controller/ExpressProvince.php
index c3ef0b6b7..890adaf6b 100644
--- a/application/store/controller/ExpressProvince.php
+++ b/application/store/controller/ExpressProvince.php
@@ -83,7 +83,7 @@ class ExpressProvince extends Controller
/**
* 删除配送省份
*/
- public function del()
+ public function remove()
{
$this->applyCsrfToken();
$this->_delete($this->table);
diff --git a/application/store/controller/ExpressTemplate.php b/application/store/controller/ExpressTemplate.php
index 2dc0a0038..5b406c1b6 100644
--- a/application/store/controller/ExpressTemplate.php
+++ b/application/store/controller/ExpressTemplate.php
@@ -21,11 +21,6 @@ class ExpressTemplate extends Controller
/**
* 邮费模板管理
- * @throws \think\Exception
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- * @throws \think\exception\PDOException
*/
public function index()
{
diff --git a/application/store/controller/Goods.php b/application/store/controller/Goods.php
index d243dfb65..879ed894c 100644
--- a/application/store/controller/Goods.php
+++ b/application/store/controller/Goods.php
@@ -91,7 +91,7 @@ class Goods extends Controller
]);
if (!empty($data)) {
Db::name('StoreGoodsStock')->insertAll($data);
- \app\store\service\Goods::syncStock($post['id']);
+ \app\store\service\GoodsService::syncStock($post['id']);
$this->success('商品信息入库成功!');
}
}
@@ -104,7 +104,7 @@ class Goods extends Controller
*/
public function add()
{
- $this->title = '添加商品';
+ $this->title = '添加商品信息';
$this->isAddMode = '1';
return $this->_form($this->table, 'form');
}
@@ -115,7 +115,7 @@ class Goods extends Controller
*/
public function edit()
{
- $this->title = '编辑商品';
+ $this->title = '编辑商品信息';
$this->isAddMode = '0';
return $this->_form($this->table, 'form');
}
@@ -182,7 +182,7 @@ class Goods extends Controller
/**
* 删除商品信息
*/
- public function del()
+ public function remove()
{
$this->_delete($this->table);
}
diff --git a/application/store/controller/GoodsCate.php b/application/store/controller/GoodsCate.php
index b3149858d..2322f7035 100644
--- a/application/store/controller/GoodsCate.php
+++ b/application/store/controller/GoodsCate.php
@@ -83,7 +83,7 @@ class GoodsCate extends Controller
/**
* 删除商品分类
*/
- public function del()
+ public function remove()
{
$this->_delete($this->table);
}
diff --git a/application/store/controller/Member.php b/application/store/controller/Member.php
index f92f2f9e8..36daffe13 100644
--- a/application/store/controller/Member.php
+++ b/application/store/controller/Member.php
@@ -40,7 +40,8 @@ class Member extends Controller
public function index()
{
$this->title = '会员信息管理';
- $this->_query($this->table)->like('nickname,phone')->equal('vip_level')->dateBetween('create_at')->order('id desc')->page();
+ $query = $this->_query($this->table)->like('nickname,phone')->equal('vip_level');
+ $query->dateBetween('create_at')->order('id desc')->page();
}
/**
diff --git a/application/store/controller/Message.php b/application/store/controller/Message.php
index 16cbaf25b..8e0017579 100644
--- a/application/store/controller/Message.php
+++ b/application/store/controller/Message.php
@@ -40,7 +40,16 @@ class Message extends Controller
public function index()
{
$this->title = '短信发送管理';
- $this->_query($this->table)->like('phone,content,result')->dateBetween('create_at')->order('id desc')->page();
+ $query = $this->_query($this->table)->like('phone,content,result');
+ $query->dateBetween('create_at')->order('id desc')->page();
+ }
+
+ /**
+ * 删除短信记录
+ */
+ public function remove()
+ {
+ $this->_delete($this->table);
}
}
\ No newline at end of file
diff --git a/application/store/controller/Order.php b/application/store/controller/Order.php
index bb9bf70e3..5cb96902e 100644
--- a/application/store/controller/Order.php
+++ b/application/store/controller/Order.php
@@ -83,7 +83,7 @@ class Order extends Controller
$this->_form($this->table);
}
- /***
+ /**
* 快递追踪查询
*/
public function expressQuery()
diff --git a/application/store/controller/api/Notify.php b/application/store/controller/api/Notify.php
index de8a9ca28..5422b474b 100644
--- a/application/store/controller/api/Notify.php
+++ b/application/store/controller/api/Notify.php
@@ -14,7 +14,7 @@
namespace app\store\controller\api;
-use app\store\service\Order;
+use app\store\service\OrderService;
use think\Db;
/**
@@ -64,7 +64,7 @@ class Notify
'pay_price' => $pay_price, 'pay_state' => '1', 'pay_at' => date('Y-m-d H:i:s'),
]);
// 调用会员升级机制
- Order::update($order['order_no']);
+ OrderService::update($order['order_no']);
return $result !== false;
}
diff --git a/application/store/controller/api/member/Center.php b/application/store/controller/api/member/Center.php
index 5a08e6b39..1f968ff46 100644
--- a/application/store/controller/api/member/Center.php
+++ b/application/store/controller/api/member/Center.php
@@ -15,7 +15,7 @@
namespace app\store\controller\api\member;
use app\store\controller\api\Member;
-use app\store\service\Extend;
+use app\store\service\ExtendService;
use think\Db;
/**
@@ -79,7 +79,7 @@ class Center extends Member
$this->error('获取短信模板失败,联系管理员配置!');
}
$cache = cache($cachekey);
- if (Extend::sendSms($this->mid, $phone, str_replace('{code}', $code, $content))) {
+ if (ExtendService::sendSms($this->mid, $phone, str_replace('{code}', $code, $content))) {
$dtime = ($cache['time'] + 120 < time()) ? 0 : (120 - time() + $cache['time']);
$this->success('短信验证码发送成功!', ['time' => $dtime]);
}
diff --git a/application/store/controller/api/member/Order.php b/application/store/controller/api/member/Order.php
index b0aba206e..6771f8530 100644
--- a/application/store/controller/api/member/Order.php
+++ b/application/store/controller/api/member/Order.php
@@ -15,7 +15,7 @@
namespace app\store\controller\api\member;
use app\store\controller\api\Member;
-use app\store\service\Goods;
+use app\store\service\GoodsService;
use library\tools\Data;
use think\Db;
@@ -95,7 +95,7 @@ class Order extends Member
Db::name('StoreOrder')->insert($order);
Db::name('StoreOrderList')->insertAll($orderList);
// 同步商品库存及销量
- foreach (array_unique(array_column($orderList, 'goods_id')) as $goodsId) Goods::syncStock($goodsId);
+ foreach (array_unique(array_column($orderList, 'goods_id')) as $goodsId) GoodsService::syncStock($goodsId);
$this->success('订单创建成功,请补全收货信息后支付!', ['order' => $order]);
} catch (\think\exception\HttpResponseException $exception) {
throw $exception;
@@ -252,7 +252,7 @@ class Order extends Member
'cancel_at' => date('Y-m-d H:i:s'),
'cancel_desc' => '用户主动取消订单!',
]);
- if ($result !== false && \app\store\service\Order::syncStock($order['order_no'])) {
+ if ($result !== false && \app\store\service\OrderService::syncStock($order['order_no'])) {
$this->success('订单取消成功!');
}
$this->error('订单取消失败,请稍候再试!');
diff --git a/application/store/service/Express.php b/application/store/service/ExpressService.php
similarity index 98%
rename from application/store/service/Express.php
rename to application/store/service/ExpressService.php
index 67461467a..e3b652fbb 100644
--- a/application/store/service/Express.php
+++ b/application/store/service/ExpressService.php
@@ -6,10 +6,10 @@ use think\Db;
/**
* 商城邮费服务
- * Class Express
+ * Class ExpressService
* @package app\store\service
*/
-class Express
+class ExpressService
{
/**
diff --git a/application/store/service/Extend.php b/application/store/service/ExtendService.php
similarity index 98%
rename from application/store/service/Extend.php
rename to application/store/service/ExtendService.php
index 3c518cfca..6d26c3f75 100644
--- a/application/store/service/Extend.php
+++ b/application/store/service/ExtendService.php
@@ -19,10 +19,10 @@ use think\Db;
/**
* 业务扩展服务
- * Class Extend
+ * Class ExtendService
* @package app\store\service
*/
-class Extend
+class ExtendService
{
/**
diff --git a/application/store/service/Goods.php b/application/store/service/GoodsService.php
similarity index 98%
rename from application/store/service/Goods.php
rename to application/store/service/GoodsService.php
index 06d13b8ac..b41a1e6d6 100644
--- a/application/store/service/Goods.php
+++ b/application/store/service/GoodsService.php
@@ -18,10 +18,10 @@ use think\Db;
/**
* 商品数据管理
- * Class Goods
+ * Class GoodsService
* @package app\store\logic
*/
-class Goods
+class GoodsService
{
/**
* 同步商品库存信息
diff --git a/application/store/service/Order.php b/application/store/service/OrderService.php
similarity index 95%
rename from application/store/service/Order.php
rename to application/store/service/OrderService.php
index 831986c97..acd952587 100644
--- a/application/store/service/Order.php
+++ b/application/store/service/OrderService.php
@@ -18,10 +18,10 @@ use think\Db;
/**
* 订单服务管理器
- * Class Order
+ * Class OrderService
* @package app\store\service
*/
-class Order
+class OrderService
{
/**
* 根据订单号升级会员等级
@@ -50,7 +50,7 @@ class Order
{
$map = ['order_no' => $order_no];
$goodsIds = Db::name('StoreOrderList')->where($map)->column('goods_id');
- foreach (array_unique($goodsIds) as $goodsId) if (!Goods::syncStock($goodsId)) return false;
+ foreach (array_unique($goodsIds) as $goodsId) if (!GoodsService::syncStock($goodsId)) return false;
return true;
}
diff --git a/application/store/view/config/index.html b/application/store/view/config/index.html
index 64b0a8a0c..4fe5b334a 100644
--- a/application/store/view/config/index.html
+++ b/application/store/view/config/index.html
@@ -1,71 +1,40 @@
{extend name="admin@main"}
{block name="content"}
-