作者 郝子凯

合并分支 '郝子凯' 到 'master'

上传插件



查看合并请求 !3
正在显示 58 个修改的文件 包含 4812 行增加0 行删除

要显示太多修改。

为保证性能只显示 58 of 58+ 个文件。

  1 +{"files":["application\\admin\\controller\\Command.php","application\\admin\\lang\\zh-cn\\command.php","application\\admin\\model\\Command.php","application\\admin\\validate\\Command.php","application\\admin\\view\\command\\add.html","application\\admin\\view\\command\\detail.html","application\\admin\\view\\command\\index.html","public\\assets\\js\\backend\\command.js"],"license":"regular","licenseto":"10789","licensekey":"nUTLWCS6Gjivx0pM \/Qe77lGZWGQWa8IzqinyNA==","domains":["showmerchants.cn"],"licensecodes":[],"validations":["3c36e672cbd8ad7c0b4c2f0562b0c810"],"menus":["command","command\/index","command\/add","command\/detail","command\/execute","command\/del","command\/multi"]}
  1 +<?php
  2 +
  3 +namespace addons\command;
  4 +
  5 +use app\common\library\Menu;
  6 +use think\Addons;
  7 +
  8 +/**
  9 + * 在线命令插件
  10 + */
  11 +class Command extends Addons
  12 +{
  13 +
  14 + /**
  15 + * 插件安装方法
  16 + * @return bool
  17 + */
  18 + public function install()
  19 + {
  20 + $menu = [
  21 + [
  22 + 'name' => 'command',
  23 + 'title' => '在线命令管理',
  24 + 'icon' => 'fa fa-terminal',
  25 + 'sublist' => [
  26 + ['name' => 'command/index', 'title' => '查看'],
  27 + ['name' => 'command/add', 'title' => '添加'],
  28 + ['name' => 'command/detail', 'title' => '详情'],
  29 + ['name' => 'command/execute', 'title' => '运行'],
  30 + ['name' => 'command/del', 'title' => '删除'],
  31 + ['name' => 'command/multi', 'title' => '批量更新'],
  32 + ]
  33 + ]
  34 + ];
  35 + Menu::create($menu);
  36 + return true;
  37 + }
  38 +
  39 + /**
  40 + * 插件卸载方法
  41 + * @return bool
  42 + */
  43 + public function uninstall()
  44 + {
  45 + Menu::delete('command');
  46 + return true;
  47 + }
  48 +
  49 + /**
  50 + * 插件启用方法
  51 + * @return bool
  52 + */
  53 + public function enable()
  54 + {
  55 + Menu::enable('command');
  56 + return true;
  57 + }
  58 +
  59 + /**
  60 + * 插件禁用方法
  61 + * @return bool
  62 + */
  63 + public function disable()
  64 + {
  65 + Menu::disable('command');
  66 + return true;
  67 + }
  68 +
  69 +}
  1 +<?php
  2 +
  3 +return [
  4 +];
  1 +<?php
  2 +
  3 +namespace addons\command\controller;
  4 +
  5 +use think\addons\Controller;
  6 +
  7 +class Index extends Controller
  8 +{
  9 +
  10 + public function index()
  11 + {
  12 + $this->error("当前插件暂无前台页面");
  13 + }
  14 +
  15 +}
  1 +name = command
  2 +title = 在线命令
  3 +intro = 可在线执行FastAdmin的命令行相关命令
  4 +author = Karson
  5 +website = https://www.fastadmin.net
  6 +version = 1.0.6
  7 +state = 1
  8 +url = /addons/command
  9 +license = regular
  10 +licenseto = 10789
  1 +CREATE TABLE IF NOT EXISTS `__PREFIX__command` (
  2 + `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
  3 + `type` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '类型',
  4 + `params` varchar(1500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '参数',
  5 + `command` varchar(1500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '命令',
  6 + `content` text COMMENT '返回结果',
  7 + `executetime` int(10) UNSIGNED DEFAULT NULL COMMENT '执行时间',
  8 + `createtime` int(10) UNSIGNED DEFAULT NULL COMMENT '创建时间',
  9 + `updatetime` int(10) UNSIGNED DEFAULT NULL COMMENT '更新时间',
  10 + `status` enum('successed','failured') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'failured' COMMENT '状态',
  11 + PRIMARY KEY (`id`) USING BTREE
  12 +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '在线命令表';
  1 +<?php
  2 +
  3 +namespace addons\command\library;
  4 +
  5 +/**
  6 + * Class Output
  7 + */
  8 +class Output extends \think\console\Output
  9 +{
  10 +
  11 + protected $message = [];
  12 +
  13 + public function __construct($driver = 'console')
  14 + {
  15 + parent::__construct($driver);
  16 + }
  17 +
  18 + protected function block($style, $message)
  19 + {
  20 + $this->message[] = $message;
  21 + }
  22 +
  23 + public function getMessage()
  24 + {
  25 + return $this->message;
  26 + }
  27 +
  28 +}
  1 +{"files":["application\\admin\\controller\\Tablemake.php","application\\admin\\lang\\zh-cn\\tablemake.php","application\\admin\\model\\TableMakeFields.php","application\\admin\\model\\TableMakeTables.php","application\\admin\\view\\tablemake\\add.html","application\\admin\\view\\tablemake\\dictionary.html","application\\admin\\view\\tablemake\\edit.html","application\\admin\\view\\tablemake\\fields.html","application\\admin\\view\\tablemake\\field_add.html","application\\admin\\view\\tablemake\\field_edit.html","application\\admin\\view\\tablemake\\index.html","public\\assets\\js\\backend\\tablemake.js"],"license":"basic","licenseto":"10789","licensekey":"av2DKJLFXrb17iS5 BN9oIbfq5bUhCSUZWJ\/tmXY+OHXwcMPV0hmvE0Qx2WQ=","domains":["showmerchants.cn"],"licensecodes":[],"validations":["3c36e672cbd8ad7c0b4c2f0562b0c810"],"menus":["tablemake","tablemake\/index","tablemake\/add","tablemake\/edit","tablemake\/del","tablemake\/fields","tablemake\/field_add","tablemake\/field_del"]}
  1 +<?php
  2 +
  3 +namespace addons\tablemake;
  4 +
  5 +use app\common\library\Menu;
  6 +use think\Addons;
  7 +use think\Config;
  8 +use think\Db;
  9 +use think\Exception;
  10 +
  11 +/**
  12 + * 自建表管理插件
  13 + */
  14 +class Tablemake extends Addons {
  15 +
  16 + /**
  17 + * 插件安装方法
  18 + * @return bool
  19 + */
  20 + public function install() {
  21 + $menu = [
  22 + [
  23 + 'name' => 'tablemake',
  24 + 'title' => '自建表管理',
  25 + 'icon' => 'fa fa-cubes',
  26 + 'sublist' => [
  27 + ['name' => 'tablemake/index', 'title' => '查看列表'],
  28 + ['name' => 'tablemake/add', 'title' => '创建新表'],
  29 + ['name' => 'tablemake/edit', 'title' => '编辑表'],
  30 + ['name' => 'tablemake/del', 'title' => '删除模块'],
  31 + ['name' => 'tablemake/fields', 'title' => '字段管理'],
  32 + ['name' => 'tablemake/field_add', 'title' => '添加字段'],
  33 + ['name' => 'tablemake/field_del', 'title' => '删除字段'],
  34 + ]
  35 + ]
  36 + ];
  37 + Menu::create($menu);
  38 + //$this->doUpgrade();
  39 + return true;
  40 + }
  41 +
  42 + /**
  43 + * 插件卸载方法
  44 + * @return bool
  45 + */
  46 + public function uninstall() {
  47 + Menu::delete('tablemake');
  48 + return true;
  49 + }
  50 +
  51 + /**
  52 + * 插件启用方法
  53 + * @return bool
  54 + */
  55 + public function enable() {
  56 + Menu::enable('tablemake');
  57 + //$this->doUpgrade();
  58 + return true;
  59 + }
  60 +
  61 + /**
  62 + * 插件禁用方法
  63 + * @return bool
  64 + */
  65 + public function disable() {
  66 + Menu::disable('tablemake');
  67 + return true;
  68 + }
  69 +
  70 + public function doUpgrade() {
  71 + $prefix = Config::get('database.prefix');
  72 +
  73 + $haTable = Db::query('SHOW TABLES LIKE '."'{$prefix}tablemake_tables'");
  74 + if(!$haTable){
  75 + //数据表不存在,表示是安装动作,非升级动作
  76 + return;
  77 + }
  78 +
  79 + //<editor-fold desc="1.0.7版本更新数据表字段" defaultstate="collapsed">
  80 + /**
  81 + * 1.检测tablemake_tables表是否需要更新,如果需要则更新tablemake_tables表
  82 + */
  83 + $sql = "describe `{$prefix}tablemake_tables` `weigh`;";
  84 + $has_weigh = Db::query($sql);
  85 + if (!$has_weigh) {//tablemake_tables
  86 + Db::startTrans();
  87 + try {
  88 + //1.新增weigh字段
  89 + $sql = "ALTER TABLE `{$prefix}tablemake_tables`
  90 + ADD COLUMN `weigh` bigint(11) NOT NULL DEFAULT 0 COMMENT '排序权重' AFTER `desc`;";
  91 + Db::execute($sql);
  92 + //2.更新weigh字段的值为对应记录的ID值
  93 + $sql = "UPDATE `{$prefix}tablemake_tables` SET `weigh`=`id`;";
  94 + Db::execute($sql);
  95 + //3.原有字段更新
  96 + $sql = "ALTER TABLE `{$prefix}tablemake_tables`
  97 + MODIFY COLUMN `id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT 'ID' FIRST ,
  98 + MODIFY COLUMN `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '自建表名称' AFTER `id`,
  99 + MODIFY COLUMN `table` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '自建表表名' AFTER `name`,
  100 + MODIFY COLUMN `desc` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '自建表简介' AFTER `table`,
  101 + MODIFY COLUMN `createtime` bigint(11) NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `weigh`,
  102 + MODIFY COLUMN `updatetime` bigint(11) NOT NULL DEFAULT 0 COMMENT '更新时间' AFTER `createtime`;";
  103 + Db::execute($sql);
  104 + Db::commit();
  105 + } catch (Exception $e) {
  106 + \think\Log::write("更新{$prefix}tablemake_tables表字段失败,异常:" . $e->getTraceAsString());
  107 + Db::rollback();
  108 + }
  109 + }
  110 + /**
  111 + * 2.检测tablemake_fields表是否需要更新,如果需要则更新tablemake_fields表
  112 + */
  113 + $sql = "describe `{$prefix}tablemake_fields` `weigh`;";
  114 + $has_weigh = Db::query($sql);
  115 + if (!$has_weigh) {//tablemake_fields
  116 + Db::startTrans();
  117 + try {
  118 + //1.新增weigh字段
  119 + $sql = "ALTER TABLE `{$prefix}tablemake_fields`
  120 + ADD COLUMN `desc` varchar(255) NOT NULL DEFAULT '' COMMENT '字段备注' AFTER `comment`,
  121 + ADD COLUMN `weigh` bigint(11) NOT NULL DEFAULT 0 COMMENT '排序权重' AFTER `desc`;";
  122 + Db::execute($sql);
  123 + //2.更新weigh字段的值为对应记录的ID值
  124 + $sql = "UPDATE `{$prefix}tablemake_fields` SET `weigh`=`id`;";
  125 + Db::execute($sql);
  126 + //3.原有字段更新
  127 + $sql = "ALTER TABLE `{$prefix}tablemake_fields`
  128 + MODIFY COLUMN `id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT 'ID' FIRST ,
  129 + MODIFY COLUMN `mid` bigint(11) NOT NULL DEFAULT 0 COMMENT '所属自建表ID' AFTER `id`,
  130 + MODIFY COLUMN `length` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 0 COMMENT '字段长度' AFTER `type`,
  131 + MODIFY COLUMN `default` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '默认值' AFTER `length`,
  132 + MODIFY COLUMN `comment` varchar(2000) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '字段备注' AFTER `default`,
  133 + MODIFY COLUMN `createtime` bigint(11) NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `weigh`,
  134 + MODIFY COLUMN `updatetime` bigint(11) NOT NULL DEFAULT 0 COMMENT '更新时间' AFTER `createtime`;";
  135 + Db::execute($sql);
  136 + Db::commit();
  137 + } catch (Exception $e) {
  138 + \think\Log::write("更新{$prefix}tablemake_fields表字段失败,异常:" . $e->getTraceAsString());
  139 + Db::rollback();
  140 + }
  141 + }
  142 + //</editor-fold>
  143 + }
  144 +
  145 +}
  1 +<?php
  2 +
  3 +return [
  4 +
  5 +];
  1 +<?php
  2 +
  3 +namespace addons\tablemake\controller;
  4 +
  5 +
  6 +
  7 +/**
  8 + * 自建表前台页面,展示数据字典
  9 + */
  10 +class Index extends \think\addons\Controller {
  11 +
  12 +
  13 +
  14 + public function _initialize() {
  15 + parent::_initialize();
  16 + }
  17 +
  18 + /**
  19 + *展示数据字典信息
  20 + */
  21 + public function index() {
  22 + $this->error("当前插件暂无前台页面",url());
  23 +
  24 + }
  25 +
  26 +}
  1 +name = tablemake
  2 +title = 自建数据表管理
  3 +intro = 创建数据表并在线管理表的字段(非本插件创建的表不支持管理),可借助命令行或在线命令工具生成CRUD和菜单
  4 +author = 沉醉寒风
  5 +website = https://www.fastadmin.net
  6 +version = 1.0.7
  7 +state = 1
  8 +url = /addons/tablemake
  9 +license = basic
  10 +licenseto = 10789
  1 +--1.0.0--
  2 +CREATE TABLE IF NOT EXISTS `__PREFIX__tablemake_tables` (
  3 + `id` int(11) NOT NULL AUTO_INCREMENT,
  4 + `name` varchar(50) NOT NULL COMMENT '模型名称',
  5 + `table` varchar(20) NOT NULL COMMENT '表名称',
  6 + `desc` varchar(150) DEFAULT NULL COMMENT '简介',
  7 + `createtime` int(11) NOT NULL COMMENT '创建时间',
  8 + `updatetime` int(11) NOT NULL COMMENT '更新时间',
  9 + PRIMARY KEY (`id`) USING BTREE
  10 +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '自建表管理表' ROW_FORMAT = Compact;
  11 +
  12 +CREATE TABLE IF NOT EXISTS `__PREFIX__tablemake_fields` (
  13 + `id` int(11) NOT NULL AUTO_INCREMENT,
  14 + `mid` int(11) NOT NULL COMMENT '所属模型',
  15 + `category` tinyint(2) NOT NULL COMMENT '字段类型',
  16 + `title` varchar(50) NOT NULL DEFAULT '' COMMENT '字段标题',
  17 + `name` varchar(50) NOT NULL DEFAULT '' COMMENT '字段名称',
  18 + `field` varchar(50) NOT NULL DEFAULT '' COMMENT '字段名',
  19 + `special` varchar(50) NOT NULL DEFAULT '' COMMENT '特殊字段',
  20 + `suffix` varchar(50) NOT NULL DEFAULT '' COMMENT '字段后缀',
  21 + `type` varchar(50) NOT NULL DEFAULT '' COMMENT '字段类型',
  22 + `length` varchar(10) NOT NULL COMMENT '字段长度',
  23 + `default` varchar(255) NOT NULL COMMENT '默认值',
  24 + `comment` varchar(2000) NOT NULL COMMENT '字段备注',
  25 + `createtime` int(11) NOT NULL COMMENT '创建时间',
  26 + `updatetime` int(11) NOT NULL COMMENT '更新时间',
  27 + PRIMARY KEY (`id`) USING BTREE
  28 +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '字段管理表' ROW_FORMAT = Compact;
  29 +
  30 +
  31 +
  32 +
  33 +--1.0.7--
  34 +ALTER TABLE `__PREFIX__tablemake_tables` ADD COLUMN `weigh` bigint(11) NOT NULL DEFAULT 0 COMMENT '排序权重' AFTER `desc`;
  35 +UPDATE `__PREFIX__tablemake_tables` SET `weigh`=`id`;
  36 +ALTER TABLE `__PREFIX__tablemake_tables`
  37 + MODIFY COLUMN `id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT 'ID' FIRST ,
  38 + MODIFY COLUMN `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '自建表名称' AFTER `id`,
  39 + MODIFY COLUMN `table` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '自建表表名' AFTER `name`,
  40 + MODIFY COLUMN `desc` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '自建表简介' AFTER `table`,
  41 + MODIFY COLUMN `createtime` bigint(11) NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `weigh`,
  42 + MODIFY COLUMN `updatetime` bigint(11) NOT NULL DEFAULT 0 COMMENT '更新时间' AFTER `createtime`;
  43 +
  44 +
  45 +ALTER TABLE `__PREFIX__tablemake_fields` ADD COLUMN `desc` varchar(255) NOT NULL DEFAULT '' COMMENT '字段备注' AFTER `comment`, ADD COLUMN `weigh` bigint(11) NOT NULL DEFAULT 0 COMMENT '排序权重' AFTER `desc`;
  46 +UPDATE `__PREFIX__tablemake_fields` SET `weigh`=`id`;
  47 +ALTER TABLE `__PREFIX__tablemake_fields`
  48 + MODIFY COLUMN `id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT 'ID' FIRST ,
  49 + MODIFY COLUMN `mid` bigint(11) NOT NULL DEFAULT 0 COMMENT '所属自建表ID' AFTER `id`,
  50 + MODIFY COLUMN `length` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 0 COMMENT '字段长度' AFTER `type`,
  51 + MODIFY COLUMN `default` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '默认值' AFTER `length`,
  52 + MODIFY COLUMN `comment` varchar(2000) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '字段备注' AFTER `default`,
  53 + MODIFY COLUMN `createtime` bigint(11) NOT NULL DEFAULT 0 COMMENT '创建时间' AFTER `weigh`,
  54 + MODIFY COLUMN `updatetime` bigint(11) NOT NULL DEFAULT 0 COMMENT '更新时间' AFTER `createtime`;
  55 +
  56 +
  57 +
  1 +{"files":["application\\admin\\controller\\Third.php","application\\admin\\lang\\zh-cn\\third.php","application\\admin\\model\\Third.php","application\\admin\\validate\\Third.php","application\\admin\\view\\third\\index.html","application\\index\\controller\\Third.php","application\\index\\view\\third\\prepare.html","public\\assets\\js\\backend\\third.js"],"license":"regular","licenseto":"10789","licensekey":"qM3GZLWgTv0NRjzV pqjZ8BMpdCeTws\/i\/uhLJA==","domains":["showmerchants.cn"],"licensecodes":[],"validations":["3c36e672cbd8ad7c0b4c2f0562b0c810"],"menus":["third","third\/index","third\/del"]}
  1 +<?php
  2 +
  3 +namespace addons\third;
  4 +
  5 +use app\common\library\Menu;
  6 +use think\Addons;
  7 +
  8 +/**
  9 + * 第三方登录
  10 + */
  11 +class Third extends Addons
  12 +{
  13 +
  14 + /**
  15 + * 插件安装方法
  16 + * @return bool
  17 + */
  18 + public function install()
  19 + {
  20 + $menu = [
  21 + [
  22 + 'name' => 'third',
  23 + 'title' => '第三方登录管理',
  24 + 'icon' => 'fa fa-users',
  25 + 'sublist' => [
  26 + [
  27 + "name" => "third/index",
  28 + "title" => "查看"
  29 + ],
  30 + [
  31 + "name" => "third/del",
  32 + "title" => "删除"
  33 + ]
  34 + ]
  35 + ]
  36 + ];
  37 + Menu::create($menu);
  38 + return true;
  39 + }
  40 +
  41 + /**
  42 + * 插件卸载方法
  43 + * @return bool
  44 + */
  45 + public function uninstall()
  46 + {
  47 + Menu::delete("third");
  48 + return true;
  49 + }
  50 +
  51 + /**
  52 + * 插件启用方法
  53 + * @return bool
  54 + */
  55 + public function enable()
  56 + {
  57 + Menu::enable("third");
  58 + return true;
  59 + }
  60 +
  61 + /**
  62 + * 插件禁用方法
  63 + * @return bool
  64 + */
  65 + public function disable()
  66 + {
  67 + Menu::disable("third");
  68 + return true;
  69 + }
  70 +
  71 + /**
  72 + * @param $params
  73 + */
  74 + public function configInit(&$params)
  75 + {
  76 + $config = $this->getConfig();
  77 + $params['third'] = ['status' => explode(',', $config['status'])];
  78 + }
  79 +}
  1 +if (Config.modulename === 'index' && Config.controllername === 'user' && ['login', 'register'].indexOf(Config.actionname) > -1 && $("#register-form,#login-form").size() > 0) {
  2 + $('<style>.social-login{display:flex}.social-login a{flex:1;margin:0 2px;}.social-login a:first-child{margin-left:0;}.social-login a:last-child{margin-right:0;}</style>').appendTo("head");
  3 + $("#register-form,#login-form").append('<div class="form-group social-login"></div>');
  4 + if (Config.third.status.indexOf("wechat") > -1) {
  5 + $('<a class="btn btn-success" href="' + Fast.api.fixurl('/third/connect/wechat') + '"><i class="fa fa-wechat"></i> 微信登录</a>').appendTo(".social-login");
  6 + }
  7 + if (Config.third.status.indexOf("qq") > -1) {
  8 + $('<a class="btn btn-info" href="' + Fast.api.fixurl('/third/connect/qq') + '"><i class="fa fa-qq"></i> QQ登录</a>').appendTo(".social-login");
  9 + }
  10 + if (Config.third.status.indexOf("weibo") > -1) {
  11 + $('<a class="btn btn-danger" href="' + Fast.api.fixurl('/third/connect/weibo') + '"><i class="fa fa-weibo"></i> 微博登录</a>').appendTo(".social-login");
  12 + }
  13 +}
  1 +<?php
  2 +
  3 +return array(
  4 + 0 =>
  5 + array(
  6 + 'name' => 'qq',
  7 + 'title' => 'QQ',
  8 + 'type' => 'array',
  9 + 'content' =>
  10 + array(
  11 + 'app_id' => '',
  12 + 'app_secret' => '',
  13 + 'scope' => 'get_user_info',
  14 + ),
  15 + 'value' =>
  16 + array(
  17 + 'app_id' => '100000000',
  18 + 'app_secret' => '123456',
  19 + 'scope' => 'get_user_info',
  20 + ),
  21 + 'rule' => 'required',
  22 + 'msg' => '',
  23 + 'tip' => '',
  24 + 'ok' => '',
  25 + 'extend' => '',
  26 + ),
  27 + 1 =>
  28 + array(
  29 + 'name' => 'wechat',
  30 + 'title' => '微信',
  31 + 'type' => 'array',
  32 + 'content' =>
  33 + array(
  34 + 'app_id' => '',
  35 + 'app_secret' => '',
  36 + 'callback' => '',
  37 + 'scope' => 'snsapi_base',
  38 + ),
  39 + 'value' =>
  40 + array(
  41 + 'app_id' => '100000000',
  42 + 'app_secret' => '123456',
  43 + 'scope' => 'snsapi_userinfo',
  44 + ),
  45 + 'rule' => 'required',
  46 + 'msg' => '',
  47 + 'tip' => '',
  48 + 'ok' => '',
  49 + 'extend' => '',
  50 + ),
  51 + 2 =>
  52 + array(
  53 + 'name' => 'weibo',
  54 + 'title' => '微博',
  55 + 'type' => 'array',
  56 + 'content' =>
  57 + array(
  58 + 'app_id' => '',
  59 + 'app_secret' => '',
  60 + 'scope' => 'get_user_info',
  61 + ),
  62 + 'value' =>
  63 + array(
  64 + 'app_id' => '100000000',
  65 + 'app_secret' => '123456',
  66 + 'scope' => 'get_user_info',
  67 + ),
  68 + 'rule' => 'required',
  69 + 'msg' => '',
  70 + 'tip' => '',
  71 + 'ok' => '',
  72 + 'extend' => '',
  73 + ),
  74 + 3 =>
  75 + array(
  76 + 'name' => 'bindaccount',
  77 + 'title' => '账号绑定',
  78 + 'type' => 'radio',
  79 + 'content' =>
  80 + array(
  81 + 1 => '开启',
  82 + 0 => '关闭',
  83 + ),
  84 + 'value' => '1',
  85 + 'rule' => 'required',
  86 + 'msg' => '',
  87 + 'tip' => '',
  88 + 'ok' => '是否开启账号绑定',
  89 + 'extend' => '',
  90 + ),
  91 + 4 =>
  92 + array(
  93 + 'name' => 'status',
  94 + 'title' => '前台第三方登录开关',
  95 + 'type' => 'checkbox',
  96 + 'content' =>
  97 + array(
  98 + 'qq' => 'QQ',
  99 + 'wechat' => '微信',
  100 + 'weibo' => '微博',
  101 + ),
  102 + 'value' => 'qq,wechat,weibo',
  103 + 'rule' => '',
  104 + 'msg' => '',
  105 + 'tip' => '',
  106 + 'ok' => '前台第三方登录的开关',
  107 + 'extend' => '',
  108 + ),
  109 + 5 =>
  110 + array(
  111 + 'name' => 'rewrite',
  112 + 'title' => '伪静态',
  113 + 'type' => 'array',
  114 + 'content' =>
  115 + array(),
  116 + 'value' =>
  117 + array(
  118 + 'index/index' => '/third$',
  119 + 'index/connect' => '/third/connect/[:platform]',
  120 + 'index/callback' => '/third/callback/[:platform]',
  121 + 'index/bind' => '/third/bind/[:platform]',
  122 + 'index/unbind' => '/third/unbind/[:platform]',
  123 + ),
  124 + 'rule' => 'required',
  125 + 'msg' => '',
  126 + 'tip' => '',
  127 + 'ok' => '',
  128 + 'extend' => '',
  129 + ),
  130 +);
  1 +<?php
  2 +
  3 +namespace addons\third\controller;
  4 +
  5 +use addons\third\library\Application;
  6 +use app\common\controller\Api as commonApi;
  7 +use addons\third\library\Service;
  8 +use addons\third\model\Third;
  9 +use app\common\library\Sms;
  10 +use fast\Random;
  11 +use think\Lang;
  12 +use think\Config;
  13 +use think\Session;
  14 +use think\Validate;
  15 +
  16 +/**
  17 + * 第三方登录插件
  18 + */
  19 +class Api extends commonApi
  20 +{
  21 + protected $noNeedLogin = ['getAuthUrl', 'callback', 'account']; // 无需登录即可访问的方法,同时也无需鉴权了
  22 + protected $noNeedRight = ['*']; // 无需鉴权即可访问的方法
  23 +
  24 + protected $app = null;
  25 + protected $options = [];
  26 + protected $config = null;
  27 +
  28 + public function _initialize()
  29 + {
  30 + //跨域检测
  31 + check_cors_request();
  32 + //设置session_id
  33 + Config::set('session.id', $this->request->server("HTTP_SID"));
  34 +
  35 + parent::_initialize();
  36 + $this->config = get_addon_config('third');
  37 + $this->app = new Application($this->config);
  38 + }
  39 +
  40 + /**
  41 + * H5获取授权链接
  42 + * @return void
  43 + */
  44 + public function getAuthUrl()
  45 + {
  46 + $url = $this->request->param('url');
  47 + $platform = $this->request->param('platform');
  48 + if (!$url || !$platform || !isset($this->config[$platform])) {
  49 + $this->error('参数错误');
  50 + }
  51 + $this->config[$platform]['callback'] = $url;
  52 + $this->app = new Application($this->config); //
  53 + if (!$this->app->{$platform}) {
  54 + $this->error(__('Invalid parameters'));
  55 + }
  56 + $this->success('', $this->app->{$platform}->getAuthorizeUrl());
  57 + }
  58 +
  59 + /**
  60 + * 公众号:wechat 授权回调的请求【非第三方,自己的前端请求】
  61 + * @return void
  62 + */
  63 + public function callback()
  64 + {
  65 +
  66 + $platform = $this->request->param('platform');
  67 + if (!$this->app->{$platform}) {
  68 + $this->error(__('Invalid parameters'));
  69 + }
  70 + $userinfo = $this->app->{$platform}->getUserInfo($this->request->param());
  71 + if (!$userinfo) {
  72 + $this->error(__('操作失败'));
  73 + }
  74 + $userinfo['apptype'] = 'mp';
  75 + $userinfo['platform'] = $platform;
  76 +
  77 + $third = [
  78 + 'avatar' => $userinfo['userinfo']['avatar'],
  79 + 'nickname' => $userinfo['userinfo']['nickname']
  80 + ];
  81 +
  82 + $user = null;
  83 + if ($this->auth->isLogin() || Service::isBindThird($userinfo['platform'], $userinfo['openid'], $userinfo['apptype'], $userinfo['unionid'])) {
  84 + Service::connect($userinfo['platform'], $userinfo);
  85 + $user = $this->auth->getUserinfo();
  86 + } else {
  87 + $user = false;
  88 + Session::set('third-userinfo', $userinfo);
  89 + }
  90 + $this->success("授权成功!", ['user' => $user, 'third' => $third]);
  91 + }
  92 +
  93 + /**
  94 + * 登录或创建账号
  95 + */
  96 + public function account()
  97 + {
  98 +
  99 + if ($this->request->isPost()) {
  100 + $params = Session::get('third-userinfo');
  101 + $mobile = $this->request->post('mobile', '');
  102 + $code = $this->request->post('code');
  103 + $token = $this->request->post('__token__');
  104 + $rule = [
  105 + 'mobile' => 'require|regex:/^1\d{10}$/',
  106 + '__token__' => 'require|token',
  107 + ];
  108 + $msg = [
  109 + 'mobile' => 'Mobile is incorrect',
  110 + ];
  111 + $data = [
  112 + 'mobile' => $mobile,
  113 + '__token__' => $token,
  114 + ];
  115 + $ret = Sms::check($mobile, $code, 'bind');
  116 + if (!$ret) {
  117 + $this->error(__('验证码错误'));
  118 + }
  119 + $validate = new Validate($rule, $msg);
  120 + $result = $validate->check($data);
  121 + if (!$result) {
  122 + $this->error(__($validate->getError()), ['__token__' => $this->request->token()]);
  123 + }
  124 +
  125 + $userinfo = \app\common\model\User::where('mobile', $mobile)->find();
  126 + if ($userinfo) {
  127 + $result = $this->auth->direct($userinfo->id);
  128 + } else {
  129 + $result = $this->auth->register($mobile, Random::alnum(), '', $mobile);
  130 + }
  131 +
  132 + if ($result) {
  133 + Service::connect($params['platform'], $params);
  134 + $this->success(__('绑定账号成功'), ['userinfo' => $this->auth->getUserinfo()]);
  135 + } else {
  136 + $this->error($this->auth->getError(), ['__token__' => $this->request->token()]);
  137 + }
  138 + }
  139 + }
  140 +
  141 +
  142 +}
  1 +<?php
  2 +
  3 +namespace addons\third\controller;
  4 +
  5 +use addons\third\library\Application;
  6 +use addons\third\library\Service;
  7 +use addons\third\model\Third;
  8 +use think\addons\Controller;
  9 +use think\Config;
  10 +use think\Cookie;
  11 +use think\Hook;
  12 +use think\Lang;
  13 +use think\Session;
  14 +
  15 +/**
  16 + * 第三方登录插件
  17 + */
  18 +class Index extends Controller
  19 +{
  20 + protected $app = null;
  21 + protected $options = [];
  22 +
  23 + public function _initialize()
  24 + {
  25 + parent::_initialize();
  26 + $config = get_addon_config('third');
  27 + $this->app = new Application($config);
  28 + }
  29 +
  30 + /**
  31 + * 插件首页
  32 + */
  33 + public function index()
  34 + {
  35 + if (!\app\admin\library\Auth::instance()->id) {
  36 + $this->error('当前插件暂无前台页面');
  37 + }
  38 + $platformList = [];
  39 + if ($this->auth->id) {
  40 + $platformList = Third::where('user_id', $this->auth->id)->column('platform');
  41 + }
  42 + $this->view->assign('platformList', $platformList);
  43 + return $this->view->fetch();
  44 + }
  45 +
  46 + /**
  47 + * 发起授权
  48 + */
  49 + public function connect()
  50 + {
  51 + $platform = $this->request->param('platform');
  52 + $url = $this->request->request('url', $this->request->server('HTTP_REFERER', '/'), 'trim');
  53 + if (!$this->app->{$platform}) {
  54 + $this->error(__('Invalid parameters'));
  55 + }
  56 + if ($url) {
  57 + Session::set("redirecturl", $url);
  58 + }
  59 + // 跳转到登录授权页面
  60 + $this->redirect($this->app->{$platform}->getAuthorizeUrl());
  61 + return;
  62 + }
  63 +
  64 + /**
  65 + * 通知回调
  66 + */
  67 + public function callback()
  68 + {
  69 + $auth = $this->auth;
  70 +
  71 + //监听注册登录注销的事件
  72 + Hook::add('user_login_successed', function ($user) use ($auth) {
  73 + $expire = input('post.keeplogin') ? 30 * 86400 : 0;
  74 + Cookie::set('uid', $user->id, $expire);
  75 + Cookie::set('token', $auth->getToken(), $expire);
  76 + });
  77 + Hook::add('user_register_successed', function ($user) use ($auth) {
  78 + Cookie::set('uid', $user->id);
  79 + Cookie::set('token', $auth->getToken());
  80 + });
  81 + Hook::add('user_logout_successed', function ($user) use ($auth) {
  82 + Cookie::delete('uid');
  83 + Cookie::delete('token');
  84 + });
  85 + $platform = $this->request->param('platform');
  86 +
  87 + // 成功后返回之前页面
  88 + $url = Session::has("redirecturl") ? Session::pull("redirecturl") : url('index/user/index');
  89 +
  90 + // 授权成功后的回调
  91 + $userinfo = $this->app->{$platform}->getUserInfo();
  92 + if (!$userinfo) {
  93 + $this->error(__('操作失败'), $url);
  94 + }
  95 +
  96 + Session::set("{$platform}-userinfo", $userinfo);
  97 + //判断是否启用账号绑定
  98 + $third = Third::get(['platform' => $platform, 'openid' => $userinfo['openid']]);
  99 + if (!$third) {
  100 + $config = get_addon_config('third');
  101 + //要求绑定账号或会员当前是登录状态
  102 + if ($config['bindaccount'] || $this->auth->id) {
  103 + $this->redirect(url('index/third/prepare') . "?" . http_build_query(['platform' => $platform, 'url' => $url]));
  104 + }
  105 + }
  106 +
  107 + $loginret = Service::connect($platform, $userinfo);
  108 + if ($loginret) {
  109 + $this->redirect($url);
  110 + }
  111 + }
  112 +
  113 + /**
  114 + * 绑定账号
  115 + */
  116 + public function bind()
  117 + {
  118 + $platform = $this->request->request('platform', $this->request->param('platform', ''));
  119 + $url = $this->request->get('url', $this->request->server('HTTP_REFERER'));
  120 + $redirecturl = url("index/third/bind") . "?" . http_build_query(['platform' => $platform, 'url' => $url]);
  121 + $this->redirect($redirecturl);
  122 + return;
  123 + }
  124 +
  125 + /**
  126 + * 解绑账号
  127 + */
  128 + public function unbind()
  129 + {
  130 + $platform = $this->request->request('platform', $this->request->param('platform', ''));
  131 + $url = $this->request->get('url', $this->request->server('HTTP_REFERER'));
  132 + $redirecturl = url("index/third/unbind") . "?" . http_build_query(['platform' => $platform, 'url' => $url]);
  133 + $this->redirect($redirecturl);
  134 + return;
  135 + }
  136 +
  137 +}
  1 +name = third
  2 +title = 第三方登录
  3 +intro = 使用微信、QQ、微博登录插件
  4 +author = FastAdmin
  5 +website = https://www.fastadmin.net
  6 +version = 1.2.3
  7 +state = 1
  8 +url = /addons/third
  9 +license = regular
  10 +licenseto = 10789
  1 +
  2 +CREATE TABLE IF NOT EXISTS `__PREFIX__third` (
  3 + `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
  4 + `user_id` int(10) unsigned DEFAULT '0' COMMENT '会员ID',
  5 + `platform` varchar(30) DEFAULT '' COMMENT '第三方应用',
  6 + `apptype` varchar(50) DEFAULT '' COMMENT '应用类型',
  7 + `unionid` varchar(100) DEFAULT '' COMMENT '第三方UNIONID',
  8 + `openid` varchar(100) DEFAULT '' COMMENT '第三方OPENID',
  9 + `openname` varchar(100) DEFAULT '' COMMENT '第三方会员昵称',
  10 + `access_token` varchar(255) NULL DEFAULT '' COMMENT 'AccessToken',
  11 + `refresh_token` varchar(255) DEFAULT 'RefreshToken',
  12 + `expires_in` int(10) unsigned DEFAULT '0' COMMENT '有效期',
  13 + `createtime` int(10) unsigned DEFAULT NULL COMMENT '创建时间',
  14 + `updatetime` int(10) unsigned DEFAULT NULL COMMENT '更新时间',
  15 + `logintime` int(10) unsigned DEFAULT NULL COMMENT '登录时间',
  16 + `expiretime` int(10) unsigned DEFAULT NULL COMMENT '过期时间',
  17 + PRIMARY KEY (`id`),
  18 + UNIQUE KEY `platform` (`platform`,`openid`),
  19 + KEY `user_id` (`user_id`,`platform`),
  20 + KEY `unionid` (`platform`,`unionid`)
  21 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='第三方登录表';
  22 +
  23 +ALTER TABLE `__PREFIX__third` ADD COLUMN `apptype` varchar(50) NULL DEFAULT '' COMMENT '应用类型' AFTER `platform`;
  24 +
  25 +ALTER TABLE `__PREFIX__third` ADD COLUMN `unionid` varchar(100) NULL DEFAULT '' COMMENT '第三方UnionID' AFTER `apptype`;
  26 +ALTER TABLE `__PREFIX__third` ADD INDEX `unionid`(`platform`, `unionid`);
  27 +
  28 +ALTER TABLE `__PREFIX__third` CHARACTER SET = utf8mb4, COLLATE = utf8mb4_general_ci;
  29 +ALTER TABLE `__PREFIX__third` MODIFY COLUMN `openname` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '第三方会员昵称' AFTER `unionid`;
  30 +
  1 +<?php
  2 +
  3 +namespace addons\third\library;
  4 +
  5 +class Application
  6 +{
  7 +
  8 + /**
  9 + * 配置信息
  10 + * @var array
  11 + */
  12 + private $config = [];
  13 +
  14 + /**
  15 + * 服务提供者
  16 + * @var array
  17 + */
  18 + private $providers = [
  19 + 'qq' => 'Qq',
  20 + 'weibo' => 'Weibo',
  21 + 'wechat' => 'Wechat',
  22 + ];
  23 +
  24 + /**
  25 + * 服务对象信息
  26 + * @var array
  27 + */
  28 + protected $services = [];
  29 +
  30 + public function __construct($options = [])
  31 + {
  32 + $options = array_intersect_key($options, $this->providers);
  33 + $options = array_merge($this->config, is_array($options) ? $options : []);
  34 + foreach ($options as $key => &$option) {
  35 + $option['app_id'] = isset($option['app_id']) ? $option['app_id'] : '';
  36 + $option['app_secret'] = isset($option['app_secret']) ? $option['app_secret'] : '';
  37 + // 如果未定义回调地址则自动生成
  38 + $option['callback'] = isset($option['callback']) && $option['callback'] ? $option['callback'] : addon_url('third/index/callback', [':platform' => $key], false, true);
  39 + }
  40 + $this->config = $options;
  41 + //注册服务器提供者
  42 + $this->registerProviders();
  43 + }
  44 +
  45 + /**
  46 + * 注册服务提供者
  47 + */
  48 + private function registerProviders()
  49 + {
  50 + foreach ($this->providers as $k => $v) {
  51 + $this->services[$k] = function () use ($k, $v) {
  52 + $options = $this->config[$k];
  53 + $objname = __NAMESPACE__ . "\\{$v}";
  54 + return new $objname($options);
  55 + };
  56 + }
  57 + }
  58 +
  59 + public function __set($key, $value)
  60 + {
  61 + $this->services[$key] = $value;
  62 + }
  63 +
  64 + public function __get($key)
  65 + {
  66 + return isset($this->services[$key]) ? $this->services[$key]($this) : null;
  67 + }
  68 +}
  1 +<?php
  2 +
  3 +namespace addons\third\library;
  4 +
  5 +use fast\Http;
  6 +use think\Config;
  7 +use think\Session;
  8 +
  9 +/**
  10 + * QQ
  11 + */
  12 +class Qq
  13 +{
  14 + const GET_AUTH_CODE_URL = "https://graph.qq.com/oauth2.0/authorize";
  15 + const GET_ACCESS_TOKEN_URL = "https://graph.qq.com/oauth2.0/token";
  16 + const GET_USERINFO_URL = "https://graph.qq.com/user/get_user_info";
  17 + const GET_OPENID_URL = "https://graph.qq.com/oauth2.0/me";
  18 +
  19 + /**
  20 + * 配置信息
  21 + * @var array
  22 + */
  23 + private $config = [];
  24 +
  25 + public function __construct($options = [])
  26 + {
  27 + if ($config = Config::get('third.qq')) {
  28 + $this->config = array_merge($this->config, $config);
  29 + }
  30 + $this->config = array_merge($this->config, is_array($options) ? $options : []);
  31 + }
  32 +
  33 + /**
  34 + * 登陆
  35 + */
  36 + public function login()
  37 + {
  38 + header("Location:" . $this->getAuthorizeUrl());
  39 + }
  40 +
  41 + /**
  42 + * 获取authorize_url
  43 + */
  44 + public function getAuthorizeUrl()
  45 + {
  46 + $state = md5(uniqid(rand(), true));
  47 + Session::set('state', $state);
  48 + $queryarr = array(
  49 + "response_type" => "code",
  50 + "client_id" => $this->config['app_id'],
  51 + "redirect_uri" => $this->config['callback'],
  52 + "scope" => $this->config['scope'],
  53 + "state" => $state,
  54 + );
  55 + request()->isMobile() && $queryarr['display'] = 'mobile';
  56 + $url = self::GET_AUTH_CODE_URL . '?' . http_build_query($queryarr);
  57 + return $url;
  58 + }
  59 +
  60 + /**
  61 + * 获取用户信息
  62 + * @param array $params
  63 + * @return array
  64 + */
  65 + public function getUserInfo($params = [])
  66 + {
  67 + $params = $params ? $params : $_GET;
  68 + if (isset($params['access_token']) || (isset($params['state']) && $params['state'] == Session::get('state') && isset($params['code']))) {
  69 + //获取access_token
  70 + $data = isset($params['code']) ? $this->getAccessToken($params['code']) : $params;
  71 + $access_token = isset($data['access_token']) ? $data['access_token'] : '';
  72 + $refresh_token = isset($data['refresh_token']) ? $data['refresh_token'] : '';
  73 + $expires_in = isset($data['expires_in']) ? $data['expires_in'] : 0;
  74 + if ($access_token) {
  75 + $openid = $this->getOpenId($access_token);
  76 + //获取用户信息
  77 + $queryarr = [
  78 + "access_token" => $access_token,
  79 + "oauth_consumer_key" => $this->config['app_id'],
  80 + "openid" => $openid,
  81 + ];
  82 + $ret = Http::get(self::GET_USERINFO_URL, $queryarr);
  83 + $userinfo = (array)json_decode($ret, true);
  84 + if (!$userinfo || !isset($userinfo['ret']) || $userinfo['ret'] !== 0) {
  85 + return [];
  86 + }
  87 + $userinfo = $userinfo ? $userinfo : [];
  88 + $userinfo['avatar'] = isset($userinfo['figureurl_qq_2']) ? $userinfo['figureurl_qq_2'] : '';
  89 + $data = [
  90 + 'access_token' => $access_token,
  91 + 'refresh_token' => $refresh_token,
  92 + 'expires_in' => $expires_in,
  93 + 'openid' => $openid,
  94 + 'userinfo' => $userinfo
  95 + ];
  96 + return $data;
  97 + }
  98 + }
  99 + return [];
  100 + }
  101 +
  102 + /**
  103 + * 获取access_token
  104 + * @param string $code
  105 + * @return array
  106 + */
  107 + public function getAccessToken($code = '')
  108 + {
  109 + if (!$code) {
  110 + return [];
  111 + }
  112 + $queryarr = array(
  113 + "grant_type" => "authorization_code",
  114 + "client_id" => $this->config['app_id'],
  115 + "client_secret" => $this->config['app_secret'],
  116 + "redirect_uri" => $this->config['callback'],
  117 + "code" => $code,
  118 + );
  119 + $ret = Http::get(self::GET_ACCESS_TOKEN_URL, $queryarr);
  120 + $params = [];
  121 + parse_str($ret, $params);
  122 + return $params ? $params : [];
  123 + }
  124 +
  125 + /**
  126 + * 获取open_id
  127 + * @param string $access_token
  128 + * @return string
  129 + */
  130 + private function getOpenId($access_token = '')
  131 + {
  132 + $response = Http::get(self::GET_OPENID_URL, ['access_token' => $access_token]);
  133 + if (strpos($response, "callback") !== false) {
  134 + $lpos = strpos($response, "(");
  135 + $rpos = strrpos($response, ")");
  136 + $response = substr($response, $lpos + 1, $rpos - $lpos - 1);
  137 + }
  138 + $user = (array)json_decode($response, true);
  139 + return isset($user['openid']) ? $user['openid'] : '';
  140 + }
  141 +}
  1 +<?php
  2 +
  3 +namespace addons\third\library;
  4 +
  5 +use addons\third\model\Third;
  6 +use app\common\model\User;
  7 +use fast\Random;
  8 +use think\Db;
  9 +use think\Exception;
  10 +
  11 +/**
  12 + * 第三方登录服务类
  13 + *
  14 + */
  15 +class Service
  16 +{
  17 +
  18 + /**
  19 + * 第三方登录
  20 + * @param string $platform 平台
  21 + * @param array $params 参数
  22 + * @param array $extend 会员扩展信息
  23 + * @param int $keeptime 有效时长
  24 + * @return boolean
  25 + */
  26 + public static function connect($platform, $params = [], $extend = [], $keeptime = 0)
  27 + {
  28 +
  29 + $time = time();
  30 + $nickname = $params['nickname'] ?? ($params['userinfo']['nickname'] ?? '');
  31 + $avatar = $params['avatar'] ?? ($params['userinfo']['avatar'] ?? '');
  32 + $values = [
  33 + 'platform' => $platform,
  34 + 'openid' => $params['openid'],
  35 + 'openname' => $nickname,
  36 + 'access_token' => $params['access_token'],
  37 + 'refresh_token' => $params['refresh_token'],
  38 + 'expires_in' => $params['expires_in'],
  39 + 'logintime' => $time,
  40 + 'expiretime' => $time + $params['expires_in'],
  41 + ];
  42 + $values = array_merge($values, $params);
  43 +
  44 + $auth = \app\common\library\Auth::instance();
  45 +
  46 + $auth->keeptime($keeptime);
  47 + //是否有自己的
  48 + $third = Third::get(['platform' => $platform, 'openid' => $params['openid']], 'user');
  49 + if ($third) {
  50 + if (!$third->user) {
  51 + $third->delete();
  52 + } else {
  53 + $third->allowField(true)->save($values);
  54 + // 写入登录Cookies和Token
  55 + return $auth->direct($third->user_id);
  56 + }
  57 + }
  58 +
  59 + //存在unionid就需要判断是否需要生成新记录
  60 + if (isset($params['unionid']) && !empty($params['unionid'])) {
  61 + $third = Third::get(['platform' => $platform, 'unionid' => $params['unionid']], 'user');
  62 + if ($third) {
  63 + if (!$third->user) {
  64 + $third->delete();
  65 + } else {
  66 + // 保存第三方信息
  67 + $values['user_id'] = $third->user_id;
  68 + $third = Third::create($values, true);
  69 + // 写入登录Cookies和Token
  70 + return $auth->direct($third->user_id);
  71 + }
  72 + }
  73 + }
  74 +
  75 + if ($auth->id) {
  76 + if (!$third) {
  77 + $values['user_id'] = $auth->id;
  78 + Third::create($values, true);
  79 + }
  80 + $user = $auth->getUser();
  81 + } else {
  82 + // 先随机一个用户名,随后再变更为u+数字id
  83 + $username = Random::alnum(20);
  84 + $password = Random::alnum(6);
  85 + $domain = request()->host();
  86 +
  87 + Db::startTrans();
  88 + try {
  89 + // 默认注册一个会员
  90 + $result = $auth->register($username, $password, $username . '@' . $domain, '', $extend);
  91 + if (!$result) {
  92 + throw new Exception($auth->getError());
  93 + }
  94 + $user = $auth->getUser();
  95 + $fields = ['username' => 'u' . $user->id, 'email' => 'u' . $user->id . '@' . $domain];
  96 + if ($nickname) {
  97 + $fields['nickname'] = $nickname;
  98 + }
  99 + if ($avatar) {
  100 + $fields['avatar'] = htmlspecialchars(strip_tags($avatar));
  101 + }
  102 +
  103 + // 更新会员资料
  104 + $user = User::get($user->id);
  105 + $user->save($fields);
  106 +
  107 + // 保存第三方信息
  108 + $values['user_id'] = $user->id;
  109 + Third::create($values, true);
  110 + Db::commit();
  111 + } catch (\Exception $e) {
  112 + Db::rollback();
  113 + $auth->logout();
  114 + return false;
  115 + }
  116 + }
  117 + // 写入登录Cookies和Token
  118 + return $auth->direct($user->id);
  119 + }
  120 +
  121 +
  122 + public static function isBindThird($platform, $openid, $apptype = '', $unionid = '')
  123 + {
  124 + $conddtions = [
  125 + 'platform' => $platform,
  126 + 'openid' => $openid
  127 + ];
  128 + if ($apptype) {
  129 + $conddtions['apptype'] = $apptype;
  130 + }
  131 + $third = Third::get($conddtions, 'user');
  132 + //第三方存在
  133 + if ($third) {
  134 + //用户失效
  135 + if (!$third->user) {
  136 + $third->delete();
  137 + return false;
  138 + }
  139 + return true;
  140 + }
  141 + if ($unionid) {
  142 + $third = Third::get(['platform' => $platform, 'unionid' => $unionid], 'user');
  143 + if ($third) {
  144 + //
  145 + if (!$third->user) {
  146 + $third->delete();
  147 + return false;
  148 + }
  149 + return true;
  150 + }
  151 + }
  152 +
  153 + return false;
  154 + }
  155 +}
  1 +<?php
  2 +
  3 +namespace addons\third\library;
  4 +
  5 +use fast\Http;
  6 +use think\Config;
  7 +use think\Session;
  8 +
  9 +/**
  10 + * 微信
  11 + */
  12 +class Wechat
  13 +{
  14 + const GET_AUTH_CODE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize";
  15 + const GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token";
  16 + const GET_USERINFO_URL = "https://api.weixin.qq.com/sns/userinfo";
  17 +
  18 + /**
  19 + * 配置信息
  20 + * @var array
  21 + */
  22 + private $config = [];
  23 +
  24 + public function __construct($options = [])
  25 + {
  26 + if ($config = Config::get('third.wechat')) {
  27 + $this->config = array_merge($this->config, $config);
  28 + }
  29 + $this->config = array_merge($this->config, is_array($options) ? $options : []);
  30 + }
  31 +
  32 + /**
  33 + * 登陆
  34 + */
  35 + public function login()
  36 + {
  37 + header("Location:" . $this->getAuthorizeUrl());
  38 + }
  39 +
  40 + /**
  41 + * 获取authorize_url
  42 + */
  43 + public function getAuthorizeUrl()
  44 + {
  45 + $state = md5(uniqid(rand(), true));
  46 + Session::set('state', $state);
  47 + $queryarr = array(
  48 + "appid" => $this->config['app_id'],
  49 + "redirect_uri" => $this->config['callback'],
  50 + "response_type" => "code",
  51 + "scope" => $this->config['scope'],
  52 + "state" => $state,
  53 + );
  54 + request()->isMobile() && $queryarr['display'] = 'mobile';
  55 + $url = self::GET_AUTH_CODE_URL . '?' . http_build_query($queryarr) . '#wechat_redirect';
  56 + return $url;
  57 + }
  58 +
  59 + /**
  60 + * 获取用户信息
  61 + * @param array $params
  62 + * @return array
  63 + */
  64 + public function getUserInfo($params = [])
  65 + {
  66 + $params = $params ? $params : request()->get();
  67 + if (isset($params['access_token']) || (isset($params['state']) && $params['state'] == Session::get('state') && isset($params['code']))) {
  68 + //获取access_token
  69 + $data = isset($params['code']) ? $this->getAccessToken($params['code']) : $params;
  70 + $access_token = isset($data['access_token']) ? $data['access_token'] : '';
  71 + $refresh_token = isset($data['refresh_token']) ? $data['refresh_token'] : '';
  72 + $expires_in = isset($data['expires_in']) ? $data['expires_in'] : 0;
  73 + if ($access_token) {
  74 + $openid = isset($data['openid']) ? $data['openid'] : '';
  75 + $unionid = isset($data['unionid']) ? $data['unionid'] : '';
  76 + if (stripos($this->config['scope'], 'snsapi_userinfo') !== false) {
  77 + //获取用户信息
  78 + $queryarr = [
  79 + "access_token" => $access_token,
  80 + "openid" => $openid,
  81 + "lang" => 'zh_CN'
  82 + ];
  83 + $ret = Http::get(self::GET_USERINFO_URL, $queryarr);
  84 + $userinfo = (array)json_decode($ret, true);
  85 + if (!$userinfo || isset($userinfo['errcode'])) {
  86 + return [];
  87 + }
  88 + $userinfo = $userinfo ? $userinfo : [];
  89 + $userinfo['avatar'] = isset($userinfo['headimgurl']) ? $userinfo['headimgurl'] : '';
  90 + } else {
  91 + $userinfo = [];
  92 + }
  93 + $data = [
  94 + 'access_token' => $access_token,
  95 + 'refresh_token' => $refresh_token,
  96 + 'expires_in' => $expires_in,
  97 + 'openid' => $openid,
  98 + 'unionid' => $unionid,
  99 + 'userinfo' => $userinfo
  100 + ];
  101 + return $data;
  102 + }
  103 + }
  104 + return [];
  105 + }
  106 +
  107 + /**
  108 + * 获取access_token
  109 + * @param string code
  110 + * @return array
  111 + */
  112 + public function getAccessToken($code = '')
  113 + {
  114 + if (!$code) {
  115 + return [];
  116 + }
  117 + $queryarr = array(
  118 + "appid" => $this->config['app_id'],
  119 + "secret" => $this->config['app_secret'],
  120 + "code" => $code,
  121 + "grant_type" => "authorization_code",
  122 + );
  123 + $response = Http::get(self::GET_ACCESS_TOKEN_URL, $queryarr);
  124 + $ret = (array)json_decode($response, true);
  125 + return $ret ? $ret : [];
  126 + }
  127 +}
  1 +<?php
  2 +
  3 +namespace addons\third\library;
  4 +
  5 +use fast\Http;
  6 +use think\Config;
  7 +use think\Session;
  8 +
  9 +/**
  10 + * 微博
  11 + */
  12 +class Weibo
  13 +{
  14 + const GET_AUTH_CODE_URL = "https://api.weibo.com/oauth2/authorize";
  15 + const GET_ACCESS_TOKEN_URL = "https://api.weibo.com/oauth2/access_token";
  16 + const GET_USERINFO_URL = "https://api.weibo.com/2/users/show.json";
  17 +
  18 + /**
  19 + * 配置信息
  20 + * @var array
  21 + */
  22 + private $config = [];
  23 +
  24 + public function __construct($options = [])
  25 + {
  26 + if ($config = Config::get('third.weibo')) {
  27 + $this->config = array_merge($this->config, $config);
  28 + }
  29 + $this->config = array_merge($this->config, is_array($options) ? $options : []);
  30 + }
  31 +
  32 + /**
  33 + * 登陆
  34 + */
  35 + public function login()
  36 + {
  37 + header("Location:" . $this->getAuthorizeUrl());
  38 + }
  39 +
  40 + /**
  41 + * 获取authorize_url
  42 + */
  43 + public function getAuthorizeUrl()
  44 + {
  45 + $state = md5(uniqid(rand(), true));
  46 + Session::set('state', $state);
  47 + $queryarr = array(
  48 + "response_type" => "code",
  49 + "client_id" => $this->config['app_id'],
  50 + "redirect_uri" => $this->config['callback'],
  51 + "state" => $state,
  52 + );
  53 + request()->isMobile() && $queryarr['display'] = 'mobile';
  54 + $url = self::GET_AUTH_CODE_URL . '?' . http_build_query($queryarr);
  55 + return $url;
  56 + }
  57 +
  58 + /**
  59 + * 获取用户信息
  60 + * @param array $params
  61 + * @return array
  62 + */
  63 + public function getUserInfo($params = [])
  64 + {
  65 + $params = $params ? $params : $_GET;
  66 + if (isset($params['access_token']) || (isset($params['state']) && $params['state'] == Session::get('state') && isset($params['code']))) {
  67 + //获取access_token
  68 + $data = isset($params['code']) ? $this->getAccessToken($params['code']) : $params;
  69 + $access_token = isset($data['access_token']) ? $data['access_token'] : '';
  70 + $refresh_token = isset($data['refresh_token']) ? $data['refresh_token'] : '';
  71 + $expires_in = isset($data['expires_in']) ? $data['expires_in'] : 0;
  72 + if ($access_token) {
  73 + $uid = isset($data['uid']) ? $data['uid'] : '';
  74 + //获取用户信息
  75 + $queryarr = [
  76 + "access_token" => $access_token,
  77 + "uid" => $uid,
  78 + ];
  79 + $ret = Http::get(self::GET_USERINFO_URL, $queryarr);
  80 + $userinfo = (array)json_decode($ret, true);
  81 + if (!$userinfo || isset($userinfo['error_code'])) {
  82 + return [];
  83 + }
  84 + $userinfo = $userinfo ? $userinfo : [];
  85 + $userinfo['nickname'] = isset($userinfo['screen_name']) ? $userinfo['screen_name'] : '';
  86 + $userinfo['avatar'] = isset($userinfo['profile_image_url']) ? $userinfo['profile_image_url'] : '';
  87 + $data = [
  88 + 'access_token' => $access_token,
  89 + 'refresh_token' => $refresh_token,
  90 + 'expires_in' => $expires_in,
  91 + 'openid' => $uid,
  92 + 'userinfo' => $userinfo
  93 + ];
  94 + return $data;
  95 + }
  96 + }
  97 + return [];
  98 + }
  99 +
  100 + /**
  101 + * 获取access_token
  102 + * @param string code
  103 + * @return array
  104 + */
  105 + public function getAccessToken($code = '')
  106 + {
  107 + if (!$code) {
  108 + return '';
  109 + }
  110 + $queryarr = array(
  111 + "grant_type" => "authorization_code",
  112 + "client_id" => $this->config['app_id'],
  113 + "client_secret" => $this->config['app_secret'],
  114 + "redirect_uri" => $this->config['callback'],
  115 + "code" => $code,
  116 + );
  117 + $response = Http::post(self::GET_ACCESS_TOKEN_URL, $queryarr);
  118 + $ret = (array)json_decode($response, true);
  119 + return $ret ? $ret : [];
  120 + }
  121 +}
  1 +<?php
  2 +
  3 +namespace addons\third\model;
  4 +
  5 +use think\Model;
  6 +
  7 +/**
  8 + * 第三方登录模型
  9 + */
  10 +class Third extends Model
  11 +{
  12 +
  13 + // 开启自动写入时间戳字段
  14 + protected $autoWriteTimestamp = 'int';
  15 + // 定义时间戳字段名
  16 + protected $createTime = 'createtime';
  17 + protected $updateTime = 'updatetime';
  18 + // 追加属性
  19 + protected $append = [
  20 + ];
  21 +
  22 + public function user()
  23 + {
  24 + return $this->belongsTo('\app\common\model\User', 'user_id', 'id', [], 'LEFT');
  25 + }
  26 +}
  1 +<!DOCTYPE html>
  2 +<html>
  3 +<head>
  4 + <title>第三方登录 - {$site.name}</title>
  5 + <meta charset="UTF-8">
  6 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7 +
  8 + <link href="__CDN__/assets/css/frontend.min.css" rel="stylesheet">
  9 +
  10 + <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
  11 + <!--[if lt IE 9]>
  12 + <script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
  13 + <script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
  14 + <![endif]-->
  15 +
  16 +</head>
  17 +<body>
  18 +<div class="container">
  19 + <h2>第三方登录</h2>
  20 + <hr>
  21 + <div class="well">
  22 + <div class="row">
  23 + <div class="col-xs-4">
  24 + {if $user && in_array('qq', $platformList)}
  25 + <a href="{:addon_url('third/index/unbind',[':platform'=>'qq'])}" class="btn btn-block btn-info">
  26 + <i class="fa fa-qq"></i> 点击解绑
  27 + </a>
  28 + {else/}
  29 + <a href="{:addon_url('third/index/connect',[':platform'=>'qq'])}" class="btn btn-block btn-info">
  30 + <i class="fa fa-qq"></i> QQ登录
  31 + </a>
  32 + {/if}
  33 + </div>
  34 + <div class="col-xs-4">
  35 + {if $user && in_array('wechat', $platformList)}
  36 + <a href="{:addon_url('third/index/unbind',[':platform'=>'wechat'])}" class="btn btn-block btn-success">
  37 + <i class="fa fa-wechat"></i> 点击解绑
  38 + </a>
  39 + {else/}
  40 + <a href="{:addon_url('third/index/connect',[':platform'=>'wechat'])}" class="btn btn-block btn-success">
  41 + <i class="fa fa-wechat"></i> 微信登录
  42 + </a>
  43 + {/if}
  44 + </div>
  45 + <div class="col-xs-4">
  46 + {if $user && in_array('weibo', $platformList)}
  47 + <a href="{:addon_url('third/index/unbind',[':platform'=>'weibo'])}" class="btn btn-block btn-danger">
  48 + <i class="fa fa-weibo"></i> 点击解绑
  49 + </a>
  50 + {else/}
  51 + <a href="{:addon_url('third/index/connect',[':platform'=>'weibo'])}" class="btn btn-block btn-danger">
  52 + <i class="fa fa-weibo"></i> 微博登录
  53 + </a>
  54 + {/if}
  55 + </div>
  56 + </div>
  57 + </div>
  58 + <h2>相关链接</h2>
  59 + <hr>
  60 + <table class="table table-striped table-hover">
  61 + <thead>
  62 + <tr>
  63 + <th>QQ</th>
  64 + <th>链接</th>
  65 + </tr>
  66 + </thead>
  67 + <tbody>
  68 + <tr>
  69 + <td>QQ 连接</td>
  70 + <td>{:addon_url('third/index/connect',[':platform'=>'qq'], false, true)}</td>
  71 + </tr>
  72 + <tr>
  73 + <td>QQ 绑定</td>
  74 + <td>{:addon_url('third/index/bind',[':platform'=>'qq'], false, true)}</td>
  75 + </tr>
  76 + <tr>
  77 + <td>QQ 解绑</td>
  78 + <td>{:addon_url('third/index/unbind',[':platform'=>'qq'], false, true)}</td>
  79 + </tr>
  80 + </tbody>
  81 + </table>
  82 + <table class="table table-striped table-hover">
  83 + <thead>
  84 + <tr>
  85 + <th>微信</th>
  86 + <th>链接</th>
  87 + </tr>
  88 + </thead>
  89 + <tbody>
  90 + <tr>
  91 + <td>微信 连接</td>
  92 + <td>{:addon_url('third/index/connect',[':platform'=>'wechat'], false, true)}</td>
  93 + </tr>
  94 + <tr>
  95 + <td>微信 绑定</td>
  96 + <td>{:addon_url('third/index/bind',[':platform'=>'wechat'], false, true)}</td>
  97 + </tr>
  98 + <tr>
  99 + <td>微信 解绑</td>
  100 + <td>{:addon_url('third/index/unbind',[':platform'=>'wechat'], false, true)}</td>
  101 + </tr>
  102 + </tbody>
  103 + </table>
  104 + <table class="table table-striped table-hover">
  105 + <thead>
  106 + <tr>
  107 + <th>微博</th>
  108 + <th>链接</th>
  109 + </tr>
  110 + </thead>
  111 + <tbody>
  112 + <tr>
  113 + <td>微博 连接</td>
  114 + <td>{:addon_url('third/index/connect',[':platform'=>'weibo'], false, true)}</td>
  115 + </tr>
  116 + <tr>
  117 + <td>微博 绑定</td>
  118 + <td>{:addon_url('third/index/bind',[':platform'=>'weibo'], false, true)}</td>
  119 + </tr>
  120 + <tr>
  121 + <td>微博 解绑</td>
  122 + <td>{:addon_url('third/index/unbind',[':platform'=>'weibo'], false, true)}</td>
  123 + </tr>
  124 + </tbody>
  125 + </table>
  126 +</div>
  127 +<!-- jQuery -->
  128 +<script src="https://cdn.jsdelivr.net/npm/jquery@2.1.4/dist/jquery.min.js"></script>
  129 +
  130 +<!-- Bootstrap Core JavaScript -->
  131 +<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
  132 +
  133 +<script type="text/javascript">
  134 + $(function () {
  135 +
  136 + });
  137 +</script>
  138 +</body>
  139 +</html>
  1 +{"files":["public\\assets\\addons\\ueditor\\dialogs\\anchor\\anchor.html","public\\assets\\addons\\ueditor\\dialogs\\attachment\\attachment.css","public\\assets\\addons\\ueditor\\dialogs\\attachment\\attachment.html","public\\assets\\addons\\ueditor\\dialogs\\attachment\\attachment.js","public\\assets\\addons\\ueditor\\dialogs\\attachment\\fileTypeImages\\icon_chm.gif","public\\assets\\addons\\ueditor\\dialogs\\attachment\\fileTypeImages\\icon_default.png","public\\assets\\addons\\ueditor\\dialogs\\attachment\\fileTypeImages\\icon_doc.gif","public\\assets\\addons\\ueditor\\dialogs\\attachment\\fileTypeImages\\icon_exe.gif","public\\assets\\addons\\ueditor\\dialogs\\attachment\\fileTypeImages\\icon_jpg.gif","public\\assets\\addons\\ueditor\\dialogs\\attachment\\fileTypeImages\\icon_mp3.gif","public\\assets\\addons\\ueditor\\dialogs\\attachment\\fileTypeImages\\icon_mv.gif","public\\assets\\addons\\ueditor\\dialogs\\attachment\\fileTypeImages\\icon_pdf.gif","public\\assets\\addons\\ueditor\\dialogs\\attachment\\fileTypeImages\\icon_ppt.gif","public\\assets\\addons\\ueditor\\dialogs\\attachment\\fileTypeImages\\icon_psd.gif","public\\assets\\addons\\ueditor\\dialogs\\attachment\\fileTypeImages\\icon_rar.gif","public\\assets\\addons\\ueditor\\dialogs\\attachment\\fileTypeImages\\icon_txt.gif","public\\assets\\addons\\ueditor\\dialogs\\attachment\\fileTypeImages\\icon_xls.gif","public\\assets\\addons\\ueditor\\dialogs\\attachment\\images\\alignicon.gif","public\\assets\\addons\\ueditor\\dialogs\\attachment\\images\\alignicon.png","public\\assets\\addons\\ueditor\\dialogs\\attachment\\images\\bg.png","public\\assets\\addons\\ueditor\\dialogs\\attachment\\images\\file-icons.gif","public\\assets\\addons\\ueditor\\dialogs\\attachment\\images\\file-icons.png","public\\assets\\addons\\ueditor\\dialogs\\attachment\\images\\icons.gif","public\\assets\\addons\\ueditor\\dialogs\\attachment\\images\\icons.png","public\\assets\\addons\\ueditor\\dialogs\\attachment\\images\\image.png","public\\assets\\addons\\ueditor\\dialogs\\attachment\\images\\progress.png","public\\assets\\addons\\ueditor\\dialogs\\attachment\\images\\success.gif","public\\assets\\addons\\ueditor\\dialogs\\attachment\\images\\success.png","public\\assets\\addons\\ueditor\\dialogs\\background\\background.css","public\\assets\\addons\\ueditor\\dialogs\\background\\background.html","public\\assets\\addons\\ueditor\\dialogs\\background\\background.js","public\\assets\\addons\\ueditor\\dialogs\\background\\images\\bg.png","public\\assets\\addons\\ueditor\\dialogs\\background\\images\\success.png","public\\assets\\addons\\ueditor\\dialogs\\charts\\chart.config.js","public\\assets\\addons\\ueditor\\dialogs\\charts\\charts.css","public\\assets\\addons\\ueditor\\dialogs\\charts\\charts.html","public\\assets\\addons\\ueditor\\dialogs\\charts\\charts.js","public\\assets\\addons\\ueditor\\dialogs\\charts\\images\\charts0.png","public\\assets\\addons\\ueditor\\dialogs\\charts\\images\\charts1.png","public\\assets\\addons\\ueditor\\dialogs\\charts\\images\\charts2.png","public\\assets\\addons\\ueditor\\dialogs\\charts\\images\\charts3.png","public\\assets\\addons\\ueditor\\dialogs\\charts\\images\\charts4.png","public\\assets\\addons\\ueditor\\dialogs\\charts\\images\\charts5.png","public\\assets\\addons\\ueditor\\dialogs\\emotion\\emotion.css","public\\assets\\addons\\ueditor\\dialogs\\emotion\\emotion.html","public\\assets\\addons\\ueditor\\dialogs\\emotion\\emotion.js","public\\assets\\addons\\ueditor\\dialogs\\emotion\\images\\0.gif","public\\assets\\addons\\ueditor\\dialogs\\emotion\\images\\bface.gif","public\\assets\\addons\\ueditor\\dialogs\\emotion\\images\\cface.gif","public\\assets\\addons\\ueditor\\dialogs\\emotion\\images\\fface.gif","public\\assets\\addons\\ueditor\\dialogs\\emotion\\images\\jxface2.gif","public\\assets\\addons\\ueditor\\dialogs\\emotion\\images\\neweditor-tab-bg.png","public\\assets\\addons\\ueditor\\dialogs\\emotion\\images\\tface.gif","public\\assets\\addons\\ueditor\\dialogs\\emotion\\images\\wface.gif","public\\assets\\addons\\ueditor\\dialogs\\emotion\\images\\yface.gif","public\\assets\\addons\\ueditor\\dialogs\\fonts\\buttoniconex.css","public\\assets\\addons\\ueditor\\dialogs\\fonts\\iconfont.eot","public\\assets\\addons\\ueditor\\dialogs\\fonts\\iconfont.svg","public\\assets\\addons\\ueditor\\dialogs\\fonts\\iconfont.ttf","public\\assets\\addons\\ueditor\\dialogs\\fonts\\iconfont.woff","public\\assets\\addons\\ueditor\\dialogs\\fonts\\images\\addfile.svg","public\\assets\\addons\\ueditor\\dialogs\\fonts\\images\\selected.svg","public\\assets\\addons\\ueditor\\dialogs\\gmap\\gmap.html","public\\assets\\addons\\ueditor\\dialogs\\help\\help.css","public\\assets\\addons\\ueditor\\dialogs\\help\\help.html","public\\assets\\addons\\ueditor\\dialogs\\help\\help.js","public\\assets\\addons\\ueditor\\dialogs\\image\\image.css","public\\assets\\addons\\ueditor\\dialogs\\image\\image.html","public\\assets\\addons\\ueditor\\dialogs\\image\\image.js","public\\assets\\addons\\ueditor\\dialogs\\image\\images\\alignicon.jpg","public\\assets\\addons\\ueditor\\dialogs\\image\\images\\bg.png","public\\assets\\addons\\ueditor\\dialogs\\image\\images\\icons.gif","public\\assets\\addons\\ueditor\\dialogs\\image\\images\\icons.png","public\\assets\\addons\\ueditor\\dialogs\\image\\images\\image.png","public\\assets\\addons\\ueditor\\dialogs\\image\\images\\progress.png","public\\assets\\addons\\ueditor\\dialogs\\image\\images\\success.gif","public\\assets\\addons\\ueditor\\dialogs\\image\\images\\success.png","public\\assets\\addons\\ueditor\\dialogs\\insertframe\\insertframe.html","public\\assets\\addons\\ueditor\\dialogs\\internal.js","public\\assets\\addons\\ueditor\\dialogs\\link\\link.html","public\\assets\\addons\\ueditor\\dialogs\\map\\map.html","public\\assets\\addons\\ueditor\\dialogs\\map\\show.html","public\\assets\\addons\\ueditor\\dialogs\\music\\balls.svg","public\\assets\\addons\\ueditor\\dialogs\\music\\music.css","public\\assets\\addons\\ueditor\\dialogs\\music\\music.html","public\\assets\\addons\\ueditor\\dialogs\\music\\music.js","public\\assets\\addons\\ueditor\\dialogs\\preview\\preview.html","public\\assets\\addons\\ueditor\\dialogs\\scrawl\\images\\addimg.png","public\\assets\\addons\\ueditor\\dialogs\\scrawl\\images\\brush.png","public\\assets\\addons\\ueditor\\dialogs\\scrawl\\images\\delimg.png","public\\assets\\addons\\ueditor\\dialogs\\scrawl\\images\\delimgH.png","public\\assets\\addons\\ueditor\\dialogs\\scrawl\\images\\empty.png","public\\assets\\addons\\ueditor\\dialogs\\scrawl\\images\\emptyH.png","public\\assets\\addons\\ueditor\\dialogs\\scrawl\\images\\eraser.png","public\\assets\\addons\\ueditor\\dialogs\\scrawl\\images\\redo.png","public\\assets\\addons\\ueditor\\dialogs\\scrawl\\images\\redoH.png","public\\assets\\addons\\ueditor\\dialogs\\scrawl\\images\\scale.png","public\\assets\\addons\\ueditor\\dialogs\\scrawl\\images\\scaleH.png","public\\assets\\addons\\ueditor\\dialogs\\scrawl\\images\\size.png","public\\assets\\addons\\ueditor\\dialogs\\scrawl\\images\\undo.png","public\\assets\\addons\\ueditor\\dialogs\\scrawl\\images\\undoH.png","public\\assets\\addons\\ueditor\\dialogs\\scrawl\\scrawl.css","public\\assets\\addons\\ueditor\\dialogs\\scrawl\\scrawl.html","public\\assets\\addons\\ueditor\\dialogs\\scrawl\\scrawl.js","public\\assets\\addons\\ueditor\\dialogs\\searchreplace\\searchreplace.html","public\\assets\\addons\\ueditor\\dialogs\\searchreplace\\searchreplace.js","public\\assets\\addons\\ueditor\\dialogs\\snapscreen\\snapscreen.html","public\\assets\\addons\\ueditor\\dialogs\\spechars\\spechars.html","public\\assets\\addons\\ueditor\\dialogs\\spechars\\spechars.js","public\\assets\\addons\\ueditor\\dialogs\\table\\dragicon.png","public\\assets\\addons\\ueditor\\dialogs\\table\\edittable.css","public\\assets\\addons\\ueditor\\dialogs\\table\\edittable.html","public\\assets\\addons\\ueditor\\dialogs\\table\\edittable.js","public\\assets\\addons\\ueditor\\dialogs\\table\\edittd.html","public\\assets\\addons\\ueditor\\dialogs\\table\\edittip.html","public\\assets\\addons\\ueditor\\dialogs\\template\\config.js","public\\assets\\addons\\ueditor\\dialogs\\template\\images\\bg.gif","public\\assets\\addons\\ueditor\\dialogs\\template\\images\\pre0.png","public\\assets\\addons\\ueditor\\dialogs\\template\\images\\pre1.png","public\\assets\\addons\\ueditor\\dialogs\\template\\images\\pre2.png","public\\assets\\addons\\ueditor\\dialogs\\template\\images\\pre3.png","public\\assets\\addons\\ueditor\\dialogs\\template\\images\\pre4.png","public\\assets\\addons\\ueditor\\dialogs\\template\\images\\temp.gif","public\\assets\\addons\\ueditor\\dialogs\\template\\template.css","public\\assets\\addons\\ueditor\\dialogs\\template\\template.html","public\\assets\\addons\\ueditor\\dialogs\\template\\template.js","public\\assets\\addons\\ueditor\\dialogs\\video\\images\\bg.png","public\\assets\\addons\\ueditor\\dialogs\\video\\images\\center_focus.jpg","public\\assets\\addons\\ueditor\\dialogs\\video\\images\\file-icons.gif","public\\assets\\addons\\ueditor\\dialogs\\video\\images\\file-icons.png","public\\assets\\addons\\ueditor\\dialogs\\video\\images\\icons.gif","public\\assets\\addons\\ueditor\\dialogs\\video\\images\\icons.png","public\\assets\\addons\\ueditor\\dialogs\\video\\images\\image.png","public\\assets\\addons\\ueditor\\dialogs\\video\\images\\left_focus.jpg","public\\assets\\addons\\ueditor\\dialogs\\video\\images\\none_focus.jpg","public\\assets\\addons\\ueditor\\dialogs\\video\\images\\progress.png","public\\assets\\addons\\ueditor\\dialogs\\video\\images\\right_focus.jpg","public\\assets\\addons\\ueditor\\dialogs\\video\\images\\success.gif","public\\assets\\addons\\ueditor\\dialogs\\video\\images\\success.png","public\\assets\\addons\\ueditor\\dialogs\\video\\video.css","public\\assets\\addons\\ueditor\\dialogs\\video\\video.html","public\\assets\\addons\\ueditor\\dialogs\\video\\video.js","public\\assets\\addons\\ueditor\\dialogs\\webapp\\webapp.html","public\\assets\\addons\\ueditor\\dialogs\\wordimage\\fClipboard_ueditor.swf","public\\assets\\addons\\ueditor\\dialogs\\wordimage\\imageUploader.swf","public\\assets\\addons\\ueditor\\dialogs\\wordimage\\tangram.js","public\\assets\\addons\\ueditor\\dialogs\\wordimage\\wordimage.html","public\\assets\\addons\\ueditor\\dialogs\\wordimage\\wordimage.js","public\\assets\\addons\\ueditor\\i18n\\zh-cn\\images\\copy.png","public\\assets\\addons\\ueditor\\i18n\\zh-cn\\images\\localimage.png","public\\assets\\addons\\ueditor\\i18n\\zh-cn\\images\\music.png","public\\assets\\addons\\ueditor\\i18n\\zh-cn\\images\\upload.png","public\\assets\\addons\\ueditor\\i18n\\zh-cn\\zh-cn.js","public\\assets\\addons\\ueditor\\themes\\default\\css\\ueditor.css","public\\assets\\addons\\ueditor\\themes\\default\\css\\ueditor.min.css","public\\assets\\addons\\ueditor\\themes\\default\\dialogbase.css","public\\assets\\addons\\ueditor\\themes\\default\\images\\anchor.gif","public\\assets\\addons\\ueditor\\themes\\default\\images\\arrow.png","public\\assets\\addons\\ueditor\\themes\\default\\images\\arrow_down.png","public\\assets\\addons\\ueditor\\themes\\default\\images\\arrow_up.png","public\\assets\\addons\\ueditor\\themes\\default\\images\\button-bg.gif","public\\assets\\addons\\ueditor\\themes\\default\\images\\cancelbutton.gif","public\\assets\\addons\\ueditor\\themes\\default\\images\\charts.png","public\\assets\\addons\\ueditor\\themes\\default\\images\\cursor_h.gif","public\\assets\\addons\\ueditor\\themes\\default\\images\\cursor_h.png","public\\assets\\addons\\ueditor\\themes\\default\\images\\cursor_v.gif","public\\assets\\addons\\ueditor\\themes\\default\\images\\cursor_v.png","public\\assets\\addons\\ueditor\\themes\\default\\images\\dialog-title-bg.png","public\\assets\\addons\\ueditor\\themes\\default\\images\\filescan.png","public\\assets\\addons\\ueditor\\themes\\default\\images\\highlighted.gif","public\\assets\\addons\\ueditor\\themes\\default\\images\\icons-all.gif","public\\assets\\addons\\ueditor\\themes\\default\\images\\icons.gif","public\\assets\\addons\\ueditor\\themes\\default\\images\\icons.png","public\\assets\\addons\\ueditor\\themes\\default\\images\\img-cracked.png","public\\assets\\addons\\ueditor\\themes\\default\\images\\loaderror.png","public\\assets\\addons\\ueditor\\themes\\default\\images\\loading.gif","public\\assets\\addons\\ueditor\\themes\\default\\images\\lock.gif","public\\assets\\addons\\ueditor\\themes\\default\\images\\neweditor-tab-bg.png","public\\assets\\addons\\ueditor\\themes\\default\\images\\pagebreak.gif","public\\assets\\addons\\ueditor\\themes\\default\\images\\scale.png","public\\assets\\addons\\ueditor\\themes\\default\\images\\sortable.png","public\\assets\\addons\\ueditor\\themes\\default\\images\\spacer.gif","public\\assets\\addons\\ueditor\\themes\\default\\images\\sparator_v.png","public\\assets\\addons\\ueditor\\themes\\default\\images\\table-cell-align.png","public\\assets\\addons\\ueditor\\themes\\default\\images\\tangram-colorpicker.png","public\\assets\\addons\\ueditor\\themes\\default\\images\\toolbar_bg.png","public\\assets\\addons\\ueditor\\themes\\default\\images\\unhighlighted.gif","public\\assets\\addons\\ueditor\\themes\\default\\images\\upload.png","public\\assets\\addons\\ueditor\\themes\\default\\images\\videologo.gif","public\\assets\\addons\\ueditor\\themes\\default\\images\\word.gif","public\\assets\\addons\\ueditor\\themes\\default\\images\\wordpaste.png","public\\assets\\addons\\ueditor\\themes\\iframe.css","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\dash.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\dot.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-1.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-10.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-11.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-12.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-13.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-14.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-15.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-16.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-17.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-18.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-19.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-2.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-20.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-21.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-22.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-23.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-24.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-25.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-26.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-27.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-28.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-29.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-3.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-30.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-31.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-32.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-33.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-34.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-35.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-36.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-37.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-38.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-39.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-4.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-40.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-41.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-42.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-43.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-44.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-45.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-46.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-47.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-48.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-49.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-5.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-50.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-51.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-52.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-53.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-54.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-55.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-56.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-57.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-58.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-59.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-6.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-60.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-61.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-62.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-63.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-64.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-65.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-66.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-67.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-68.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-69.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-7.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-70.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-71.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-72.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-73.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-74.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-75.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-76.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-77.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-78.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-79.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-8.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-80.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-81.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-82.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-83.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-84.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-85.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-86.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-87.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-88.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-89.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-9.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-90.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-91.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-92.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-93.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-94.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-95.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-96.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-97.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-1-98.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-1.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-10.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-11.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-12.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-13.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-14.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-15.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-16.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-17.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-18.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-19.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-2.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-20.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-21.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-22.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-23.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-24.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-25.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-26.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-27.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-28.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-29.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-3.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-30.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-31.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-32.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-33.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-34.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-35.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-36.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-37.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-38.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-39.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-4.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-40.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-41.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-42.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-43.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-44.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-45.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-46.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-47.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-48.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-49.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-5.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-50.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-51.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-52.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-53.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-54.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-55.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-56.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-57.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-58.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-59.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-6.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-60.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-61.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-62.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-63.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-64.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-65.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-66.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-67.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-68.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-69.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-7.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-70.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-71.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-72.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-73.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-74.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-75.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-76.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-77.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-78.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-79.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-8.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-80.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-81.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-82.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-83.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-84.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-85.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-86.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-87.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-88.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-89.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-9.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-90.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-91.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-92.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-93.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-94.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-95.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-96.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-97.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-2-98.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-1.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-10.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-11.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-12.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-13.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-14.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-15.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-16.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-17.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-18.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-19.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-2.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-20.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-21.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-22.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-23.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-24.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-25.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-26.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-27.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-28.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-29.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-3.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-30.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-31.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-32.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-33.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-34.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-35.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-36.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-37.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-38.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-39.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-4.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-40.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-41.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-42.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-43.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-44.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-45.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-46.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-47.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-48.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-49.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-5.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-50.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-51.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-52.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-53.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-54.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-55.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-56.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-57.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-58.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-59.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-6.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-60.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-61.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-62.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-63.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-64.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-65.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-66.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-67.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-68.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-69.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-7.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-70.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-71.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-72.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-73.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-74.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-75.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-76.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-77.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-78.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-79.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-8.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-80.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-81.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-82.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-83.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-84.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-85.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-86.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-87.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-88.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-89.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-9.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-90.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-91.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-92.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-93.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-94.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-95.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-96.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-97.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-cn-3-98.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-1.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-10.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-11.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-12.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-13.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-14.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-15.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-16.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-17.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-18.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-19.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-2.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-20.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-21.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-22.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-23.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-24.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-25.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-26.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-27.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-28.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-29.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-3.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-30.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-31.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-32.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-33.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-34.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-35.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-36.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-37.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-38.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-39.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-4.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-40.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-41.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-42.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-43.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-44.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-45.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-46.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-47.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-48.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-49.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-5.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-50.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-51.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-52.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-53.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-54.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-55.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-56.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-57.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-58.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-59.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-6.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-60.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-61.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-62.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-63.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-64.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-65.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-66.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-67.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-68.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-69.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-7.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-70.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-71.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-72.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-73.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-74.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-75.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-76.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-77.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-78.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-79.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-8.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-80.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-81.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-82.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-83.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-84.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-85.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-86.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-87.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-88.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-89.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-9.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-90.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-91.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-92.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-93.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-94.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-95.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-96.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-97.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-1-98.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-1.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-10.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-11.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-12.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-13.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-14.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-15.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-16.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-17.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-18.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-19.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-2.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-20.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-21.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-22.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-23.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-24.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-25.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-26.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-27.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-28.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-29.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-3.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-30.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-31.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-32.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-33.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-34.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-35.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-36.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-37.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-38.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-39.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-4.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-40.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-41.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-42.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-43.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-44.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-45.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-46.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-47.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-48.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-49.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-5.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-50.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-51.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-52.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-53.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-54.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-55.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-56.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-57.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-58.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-59.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-6.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-60.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-61.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-62.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-63.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-64.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-65.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-66.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-67.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-68.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-69.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-7.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-70.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-71.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-72.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-73.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-74.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-75.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-76.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-77.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-78.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-79.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-8.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-80.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-81.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-82.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-83.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-84.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-85.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-86.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-87.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-88.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-89.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-9.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-90.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-91.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-92.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-93.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-94.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-95.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-96.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-97.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-2-98.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-1.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-10.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-11.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-12.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-13.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-14.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-15.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-16.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-17.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-18.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-19.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-2.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-20.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-21.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-22.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-23.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-24.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-25.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-26.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-27.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-28.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-29.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-3.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-30.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-31.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-32.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-33.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-34.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-35.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-36.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-37.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-38.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-39.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-4.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-40.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-41.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-42.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-43.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-44.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-45.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-46.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-47.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-48.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-49.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-5.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-50.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-51.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-52.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-53.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-54.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-55.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-56.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-57.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-58.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-59.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-6.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-60.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-61.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-62.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-63.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-64.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-65.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-66.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-67.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-68.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-69.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-7.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-70.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-71.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-72.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-73.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-74.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-75.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-76.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-77.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-78.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-79.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-8.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-80.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-81.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-82.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-83.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-84.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-85.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-86.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-87.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-88.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-89.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-9.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-90.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-91.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-92.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-93.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-94.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-95.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-96.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-97.gif","public\\assets\\addons\\ueditor\\themes\\ueditor-list\\list-num-3-98.gif","public\\assets\\addons\\ueditor\\third-party\\browser-md5-file.min.js","public\\assets\\addons\\ueditor\\third-party\\codemirror\\codemirror.css","public\\assets\\addons\\ueditor\\third-party\\codemirror\\codemirror.js","public\\assets\\addons\\ueditor\\third-party\\highcharts\\adapters\\mootools-adapter.js","public\\assets\\addons\\ueditor\\third-party\\highcharts\\adapters\\prototype-adapter.js","public\\assets\\addons\\ueditor\\third-party\\highcharts\\adapters\\standalone-framework.js","public\\assets\\addons\\ueditor\\third-party\\highcharts\\highcharts-more.js","public\\assets\\addons\\ueditor\\third-party\\highcharts\\highcharts.js","public\\assets\\addons\\ueditor\\third-party\\highcharts\\modules\\annotations.js","public\\assets\\addons\\ueditor\\third-party\\highcharts\\modules\\canvas-tools.js","public\\assets\\addons\\ueditor\\third-party\\highcharts\\modules\\data.js","public\\assets\\addons\\ueditor\\third-party\\highcharts\\modules\\drilldown.js","public\\assets\\addons\\ueditor\\third-party\\highcharts\\modules\\exporting.js","public\\assets\\addons\\ueditor\\third-party\\highcharts\\modules\\funnel.js","public\\assets\\addons\\ueditor\\third-party\\highcharts\\modules\\heatmap.js","public\\assets\\addons\\ueditor\\third-party\\highcharts\\modules\\map.js","public\\assets\\addons\\ueditor\\third-party\\highcharts\\modules\\no-data-to-display.js","public\\assets\\addons\\ueditor\\third-party\\highcharts\\themes\\dark-blue.js","public\\assets\\addons\\ueditor\\third-party\\highcharts\\themes\\dark-green.js","public\\assets\\addons\\ueditor\\third-party\\highcharts\\themes\\gray.js","public\\assets\\addons\\ueditor\\third-party\\highcharts\\themes\\grid.js","public\\assets\\addons\\ueditor\\third-party\\highcharts\\themes\\skies.js","public\\assets\\addons\\ueditor\\third-party\\jquery-1.10.2.min.js","public\\assets\\addons\\ueditor\\third-party\\jquery-1.10.2.min.map","public\\assets\\addons\\ueditor\\third-party\\snapscreen\\UEditorSnapscreen.exe","public\\assets\\addons\\ueditor\\third-party\\SyntaxHighlighter\\shCore.js","public\\assets\\addons\\ueditor\\third-party\\SyntaxHighlighter\\shCoreDefault.css","public\\assets\\addons\\ueditor\\third-party\\video-js\\font\\vjs.eot","public\\assets\\addons\\ueditor\\third-party\\video-js\\font\\vjs.svg","public\\assets\\addons\\ueditor\\third-party\\video-js\\font\\vjs.ttf","public\\assets\\addons\\ueditor\\third-party\\video-js\\font\\vjs.woff","public\\assets\\addons\\ueditor\\third-party\\video-js\\video-js.css","public\\assets\\addons\\ueditor\\third-party\\video-js\\video-js.min.css","public\\assets\\addons\\ueditor\\third-party\\video-js\\video-js.swf","public\\assets\\addons\\ueditor\\third-party\\video-js\\video.js","public\\assets\\addons\\ueditor\\third-party\\webuploader\\Uploader.swf","public\\assets\\addons\\ueditor\\third-party\\webuploader\\webuploader.css","public\\assets\\addons\\ueditor\\third-party\\webuploader\\webuploader.custom.min.js","public\\assets\\addons\\ueditor\\third-party\\webuploader\\webuploader.flashonly.min.js","public\\assets\\addons\\ueditor\\third-party\\webuploader\\webuploader.html5only.min.js","public\\assets\\addons\\ueditor\\third-party\\webuploader\\webuploader.min.js","public\\assets\\addons\\ueditor\\third-party\\webuploader\\webuploader.withoutimage.min.js","public\\assets\\addons\\ueditor\\third-party\\zeroclipboard\\ZeroClipboard.min.js","public\\assets\\addons\\ueditor\\third-party\\zeroclipboard\\ZeroClipboard.swf","public\\assets\\addons\\ueditor\\ueditor.all.min.js","public\\assets\\addons\\ueditor\\ueditor.config.js","public\\assets\\addons\\ueditor\\ueditor.parse.min.js"],"license":"basic","licenseto":"10789","licensekey":"IeflBpA9nU1FQjDL bLs2GrR0rVi\/foclAXxjZQ==","domains":["showmerchants.cn"],"licensecodes":[],"validations":["3c36e672cbd8ad7c0b4c2f0562b0c810"]}
  1 +<?php
  2 +
  3 +namespace addons\ueditor;
  4 +
  5 +use think\Addons;
  6 +
  7 +/**
  8 + * 百度Ueditor插件
  9 + */
  10 +class Ueditor extends Addons
  11 +{
  12 +
  13 + /**
  14 + * 插件安装方法
  15 + * @return bool
  16 + */
  17 + public function install()
  18 + {
  19 + return true;
  20 + }
  21 +
  22 + /**
  23 + * 插件卸载方法
  24 + * @return bool
  25 + */
  26 + public function uninstall()
  27 + {
  28 + return true;
  29 + }
  30 +
  31 + /**
  32 + * @param $params
  33 + */
  34 + public function configInit(&$params)
  35 + {
  36 + $config = $this->getConfig();
  37 + $params['ueditor'] = ['classname' => $config['classname']??'.editor'];
  38 + }
  39 +}
  1 +window.UEDITOR_HOME_URL = Config.__CDN__ + "/assets/addons/ueditor/";
  2 +require.config({
  3 + paths: {
  4 + 'ueditor.config': '../addons/ueditor/ueditor.config',
  5 + 'ueditor': '../addons/ueditor/ueditor.all.min',
  6 + 'ueditor.zh': '../addons/ueditor/i18n/zh-cn/zh-cn',
  7 + 'zeroclipboard': '../addons/ueditor/third-party/zeroclipboard/ZeroClipboard.min',
  8 + },
  9 + shim: {
  10 + 'ueditor': {
  11 + deps: ['zeroclipboard', 'ueditor.config'],
  12 + exports: 'UE',
  13 + init: function (ZeroClipboard) {
  14 + //导出到全局变量,供ueditor使用
  15 + window.ZeroClipboard = ZeroClipboard;
  16 + },
  17 + },
  18 + 'ueditor.zh': ['ueditor']
  19 + }
  20 +});
  21 +require(['form', 'upload'], function (Form, Upload) {
  22 + var _bindevent = Form.events.bindevent;
  23 + Form.events.bindevent = function (form) {
  24 + _bindevent.apply(this, [form]);
  25 + try {
  26 + //绑定editor事件
  27 + require(['ueditor', 'ueditor.zh'], function (UE, undefined) {
  28 + UE.list = [];
  29 + window.UEDITOR_CONFIG['uploadService'] = function (context, editor) {
  30 + return {
  31 + Upload: () => { return Upload },
  32 + Fast: () => { return Fast },
  33 + }
  34 + };
  35 + $(Config.ueditor.classname || '.editor', form).each(function () {
  36 + var id = $(this).attr("id");
  37 + var name = $(this).attr("name");
  38 + $(this).removeClass('form-control');
  39 + UE.list[id] = UE.getEditor(id, {
  40 + allowDivTransToP: false, //阻止div自动转p标签
  41 + initialFrameWidth: '100%',
  42 + initialFrameHeight: 320,
  43 + autoFloatEnabled: false,
  44 + // autoHeightEnabled: true, //自动高度
  45 + zIndex: 90,
  46 + xssFilterRules: false,
  47 + outputXssFilter: false,
  48 + inputXssFilter: false,
  49 + catchRemoteImageEnable: true
  50 + });
  51 + UE.list[id].addListener("contentChange", function () {
  52 + $('#' + id).val(this.getContent());
  53 + $('textarea[name="' + name + '"]').val(this.getContent());
  54 + })
  55 + });
  56 + })
  57 + } catch (e) {
  58 + console.log('绑定editor事件', e)
  59 + }
  60 + }
  61 +});
  1 +<?php
  2 +
  3 +return [
  4 + [
  5 + 'name' => 'classname',
  6 + 'title' => '渲染文本框元素',
  7 + 'type' => 'string',
  8 + 'content' => [],
  9 + 'value' => '.editor',
  10 + 'rule' => 'required',
  11 + 'msg' => '',
  12 + 'tip' => '用于对指定的元素渲染,一般情况下无需修改',
  13 + 'ok' => '',
  14 + 'extend' => '',
  15 + ],
  16 +];
  1 +name = ueditor
  2 +title = 百度ueditor插件
  3 +intro = 基于百度Ueditor的富文本编辑器
  4 +author = chance
  5 +website = http://it-huai.gitee.io/ueditor-api/
  6 +version = 1.0.8
  7 +state = 1
  8 +url = /addons/ueditor
  9 +license = basic
  10 +licenseto = 10789
  1 +{"files":["application\\admin\\controller\\wechat\\Autoreply.php","application\\admin\\controller\\wechat\\Config.php","application\\admin\\controller\\wechat\\Menu.php","application\\admin\\controller\\wechat\\Response.php","application\\admin\\lang\\zh-cn\\wechat\\autoreply.php","application\\admin\\lang\\zh-cn\\wechat\\config.php","application\\admin\\lang\\zh-cn\\wechat\\response.php","application\\admin\\model\\WechatAutoreply.php","application\\admin\\model\\WechatCaptcha.php","application\\admin\\model\\WechatConfig.php","application\\admin\\model\\WechatContext.php","application\\admin\\model\\WechatResponse.php","application\\admin\\view\\wechat\\autoreply\\add.html","application\\admin\\view\\wechat\\autoreply\\edit.html","application\\admin\\view\\wechat\\autoreply\\index.html","application\\admin\\view\\wechat\\config\\add.html","application\\admin\\view\\wechat\\config\\edit.html","application\\admin\\view\\wechat\\config\\index.html","application\\admin\\view\\wechat\\menu\\index.html","application\\admin\\view\\wechat\\response\\add.html","application\\admin\\view\\wechat\\response\\edit.html","application\\admin\\view\\wechat\\response\\index.html","application\\admin\\view\\wechat\\response\\select.html","public\\assets\\js\\backend\\wechat\\autoreply.js","public\\assets\\js\\backend\\wechat\\config.js","public\\assets\\js\\backend\\wechat\\menu.js","public\\assets\\js\\backend\\wechat\\response.js","public\\assets\\addons\\wechat\\css\\menu.css","public\\assets\\addons\\wechat\\images\\mobile_footer_bg.png","public\\assets\\addons\\wechat\\images\\mobile_header_bg.png","public\\assets\\addons\\wechat\\images\\mobile_index.png","public\\assets\\addons\\wechat\\images\\weixin_icon.png"],"license":"regular","licenseto":"10789","licensekey":"GeD2qP017ZsyuRth MFI\/PaZgDlLDTiOaCyzNQg==","domains":["showmerchants.cn"],"licensecodes":[],"validations":["3c36e672cbd8ad7c0b4c2f0562b0c810"],"menus":["wechat","wechat\/autoreply","wechat\/autoreply\/index","wechat\/autoreply\/add","wechat\/autoreply\/edit","wechat\/autoreply\/del","wechat\/autoreply\/multi","wechat\/config","wechat\/config\/index","wechat\/config\/add","wechat\/config\/edit","wechat\/config\/del","wechat\/config\/multi","wechat\/menu","wechat\/menu\/index","wechat\/menu\/add","wechat\/menu\/edit","wechat\/menu\/del","wechat\/menu\/remote","wechat\/menu\/sync","wechat\/menu\/multi","wechat\/response","wechat\/response\/index","wechat\/response\/add","wechat\/response\/edit","wechat\/response\/del","wechat\/response\/select","wechat\/response\/multi"]}
  1 +<?php
  2 +
  3 +namespace addons\wechat;
  4 +
  5 +use app\common\library\Menu;
  6 +use think\Addons;
  7 +
  8 +/**
  9 + * 微信插件
  10 + */
  11 +class Wechat extends Addons
  12 +{
  13 +
  14 + /**
  15 + * 插件安装方法
  16 + * @return bool
  17 + */
  18 + public function install()
  19 + {
  20 + $menu = [
  21 + [
  22 + 'name' => 'wechat',
  23 + 'title' => '微信管理',
  24 + 'icon' => 'fa fa-wechat',
  25 + 'sublist' => [
  26 + [
  27 + 'name' => 'wechat/autoreply',
  28 + 'title' => '自动回复管理',
  29 + 'icon' => 'fa fa-reply-all',
  30 + 'sublist' => [
  31 + ['name' => 'wechat/autoreply/index', 'title' => '查看'],
  32 + ['name' => 'wechat/autoreply/add', 'title' => '添加'],
  33 + ['name' => 'wechat/autoreply/edit', 'title' => '修改'],
  34 + ['name' => 'wechat/autoreply/del', 'title' => '删除'],
  35 + ['name' => 'wechat/autoreply/multi', 'title' => '批量更新'],
  36 + ]
  37 + ],
  38 + [
  39 + 'name' => 'wechat/config',
  40 + 'title' => '配置管理',
  41 + 'icon' => 'fa fa-cog',
  42 + 'sublist' => [
  43 + ['name' => 'wechat/config/index', 'title' => '查看'],
  44 + ['name' => 'wechat/config/add', 'title' => '添加'],
  45 + ['name' => 'wechat/config/edit', 'title' => '修改'],
  46 + ['name' => 'wechat/config/del', 'title' => '删除'],
  47 + ['name' => 'wechat/config/multi', 'title' => '批量更新'],
  48 + ]
  49 + ],
  50 + [
  51 + 'name' => 'wechat/menu',
  52 + 'title' => '菜单管理',
  53 + 'icon' => 'fa fa-list',
  54 + 'sublist' => [
  55 + ['name' => 'wechat/menu/index', 'title' => '查看'],
  56 + ['name' => 'wechat/menu/add', 'title' => '添加'],
  57 + ['name' => 'wechat/menu/edit', 'title' => '修改'],
  58 + ['name' => 'wechat/menu/del', 'title' => '删除'],
  59 + ['name' => 'wechat/menu/remote', 'title' => '加载远程菜单'],
  60 + ['name' => 'wechat/menu/sync', 'title' => '同步'],
  61 + ['name' => 'wechat/menu/multi', 'title' => '批量更新'],
  62 + ]
  63 + ],
  64 + [
  65 + 'name' => 'wechat/response',
  66 + 'title' => '资源管理',
  67 + 'icon' => 'fa fa-list-alt',
  68 + 'sublist' => [
  69 + ['name' => 'wechat/response/index', 'title' => '查看'],
  70 + ['name' => 'wechat/response/add', 'title' => '添加'],
  71 + ['name' => 'wechat/response/edit', 'title' => '修改'],
  72 + ['name' => 'wechat/response/del', 'title' => '删除'],
  73 + ['name' => 'wechat/response/select', 'title' => '选择'],
  74 + ['name' => 'wechat/response/multi', 'title' => '批量更新'],
  75 + ]
  76 + ]
  77 + ]
  78 + ]
  79 + ];
  80 + Menu::create($menu);
  81 + return true;
  82 + }
  83 +
  84 + /**
  85 + * 插件卸载方法
  86 + * @return bool
  87 + */
  88 + public function uninstall()
  89 + {
  90 + Menu::delete('wechat');
  91 + return true;
  92 + }
  93 +
  94 + /**
  95 + * 插件启用方法
  96 + */
  97 + public function enable()
  98 + {
  99 + Menu::enable('wechat');
  100 + }
  101 +
  102 + /**
  103 + * 插件禁用方法
  104 + */
  105 + public function disable()
  106 + {
  107 + Menu::disable('wechat');
  108 + }
  109 +
  110 +}
  1 +<?php
  2 +
  3 +return [
  4 + [
  5 + 'name' => 'app_id',
  6 + 'title' => 'app_id',
  7 + 'type' => 'string',
  8 + 'content' => [],
  9 + 'value' => '',
  10 + 'rule' => 'required',
  11 + 'msg' => '',
  12 + 'tip' => '',
  13 + 'ok' => '',
  14 + 'extend' => '',
  15 + ],
  16 + [
  17 + 'name' => 'secret',
  18 + 'title' => 'secret',
  19 + 'type' => 'string',
  20 + 'content' => [],
  21 + 'value' => '',
  22 + 'rule' => 'required',
  23 + 'msg' => '',
  24 + 'tip' => '',
  25 + 'ok' => '',
  26 + 'extend' => '',
  27 + ],
  28 + [
  29 + 'name' => 'token',
  30 + 'title' => 'token',
  31 + 'type' => 'string',
  32 + 'content' => [],
  33 + 'value' => '',
  34 + 'rule' => 'required',
  35 + 'msg' => '',
  36 + 'tip' => '',
  37 + 'ok' => '',
  38 + 'extend' => '',
  39 + ],
  40 + [
  41 + 'name' => 'aes_key',
  42 + 'title' => 'aes_key',
  43 + 'type' => 'string',
  44 + 'content' => [],
  45 + 'value' => '',
  46 + 'rule' => 'required',
  47 + 'msg' => '',
  48 + 'tip' => '',
  49 + 'ok' => '',
  50 + 'extend' => '',
  51 + ],
  52 + [
  53 + 'name' => 'debug',
  54 + 'title' => '调试模式',
  55 + 'type' => 'radio',
  56 + 'content' => [
  57 + '否',
  58 + '是',
  59 + ],
  60 + 'value' => '0',
  61 + 'rule' => 'required',
  62 + 'msg' => '',
  63 + 'tip' => '',
  64 + 'ok' => '',
  65 + 'extend' => '',
  66 + ],
  67 + [
  68 + 'name' => 'log_level',
  69 + 'title' => '日志记录等级',
  70 + 'type' => 'select',
  71 + 'content' => [
  72 + 'debug' => 'debug',
  73 + 'info' => 'info',
  74 + 'notice' => 'notice',
  75 + 'warning' => 'warning',
  76 + 'error' => 'error',
  77 + 'critical' => 'critical',
  78 + 'alert' => 'alert',
  79 + 'emergency' => 'emergency',
  80 + ],
  81 + 'value' => 'info',
  82 + 'rule' => 'required',
  83 + 'msg' => '',
  84 + 'tip' => '生产环境日志记录等级',
  85 + 'ok' => '',
  86 + 'extend' => '',
  87 + ],
  88 + [
  89 + 'name' => 'oauth_callback',
  90 + 'title' => '登录回调',
  91 + 'type' => 'string',
  92 + 'content' => [],
  93 + 'value' => 'http://www.yoursite.com/addons/wechat/index/callback',
  94 + 'rule' => 'required',
  95 + 'msg' => '',
  96 + 'tip' => '',
  97 + 'ok' => '',
  98 + 'extend' => '',
  99 + ],
  100 +];
  1 +<?php
  2 +
  3 +namespace addons\wechat\controller;
  4 +
  5 +use addons\wechat\library\Wechat;
  6 +use addons\wechat\model\WechatCaptcha;
  7 +use fast\Http;
  8 +
  9 +/**
  10 + * 微信验证码验证接口
  11 + */
  12 +class Captcha extends \think\addons\Controller
  13 +{
  14 +
  15 + /**
  16 + * 验证码检测接口
  17 + */
  18 + public function check()
  19 + {
  20 + $captcha = $this->request->post("captcha");
  21 + $event = $this->request->post("event");
  22 + $result = WechatCaptcha::check($captcha, $event);
  23 + if ($result) {
  24 + $this->success("验证码正确");
  25 + } else {
  26 + $this->error("验证码错误");
  27 + }
  28 + }
  29 +
  30 + /**
  31 + * 验证码发送接口
  32 + */
  33 + public function send()
  34 + {
  35 + $ip = $this->request->ip();
  36 + $event = $this->request->post("event");
  37 + if (!$event) {
  38 + $this->error("参数错误");
  39 + }
  40 + $captch = WechatCaptcha::where('ip', $ip)
  41 + ->where('event', $event)
  42 + ->whereTime('createtime', '-2 minutes')
  43 + ->find();
  44 + if ($captch) {
  45 + $this->error("获取频繁,请稍后重试");
  46 + }
  47 + $token = Wechat::getAccessToken();
  48 + if (!$token) {
  49 + $this->error("发送失败,请稍后重试");
  50 + }
  51 + $url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={$token}";
  52 + $params = [
  53 + 'expire_seconds' => 120,
  54 + 'action_name' => 'QR_STR_SCENE',
  55 + 'action_info' => [
  56 + 'scene' => [
  57 + 'scene_str' => "captcha_" . $event . "_" . $ip,
  58 + ]
  59 + ],
  60 + ];
  61 + //获取验证码
  62 + $result = Http::sendRequest($url, json_encode($params));
  63 + if ($result['ret']) {
  64 + $msg = (array)json_decode($result['msg'], true);
  65 + if (isset($msg['ticket']) && isset($msg['url'])) {
  66 + $this->success("", null, ['image' => "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" . urlencode($msg['ticket']), 'url' => $msg['url']]);
  67 + }
  68 + }
  69 + $this->error("获取失败!请稍后重试");
  70 + }
  71 +
  72 +}
  1 +<?php
  2 +
  3 +namespace addons\wechat\controller;
  4 +
  5 +use addons\wechat\library\Config;
  6 +use addons\wechat\model\WechatAutoreply;
  7 +use addons\wechat\model\WechatCaptcha;
  8 +use addons\wechat\model\WechatContext;
  9 +use addons\wechat\model\WechatResponse;
  10 +use addons\wechat\model\WechatConfig;
  11 +
  12 +use EasyWeChat\Factory;
  13 +use addons\wechat\library\Wechat as WechatService;
  14 +use addons\wechat\library\Config as ConfigService;
  15 +use think\Log;
  16 +
  17 +/**
  18 + * 微信接口
  19 + */
  20 +class Index extends \think\addons\Controller
  21 +{
  22 +
  23 + public $app = null;
  24 +
  25 + public function _initialize()
  26 + {
  27 + parent::_initialize();
  28 + $this->app = Factory::officialAccount(Config::load());
  29 + }
  30 +
  31 + /**
  32 + *
  33 + */
  34 + public function index()
  35 + {
  36 + $this->error("当前插件暂无前台页面");
  37 + }
  38 +
  39 + /**
  40 + * 微信API对接接口
  41 + */
  42 + public function api()
  43 + {
  44 + $this->app->server->push(function ($message) {
  45 + $wechatService = new WechatService;
  46 +
  47 + $matches = null;
  48 + $openid = $message['FromUserName'];
  49 + $to_openid = $message['ToUserName'];
  50 +
  51 + $unknownMessage = WechatConfig::getValue('default.unknown.message');
  52 + $unknownMessage = $unknownMessage ? $unknownMessage : "";
  53 +
  54 + switch ($message['MsgType']) {
  55 + case 'event': //事件消息
  56 + $event = $message['Event'];
  57 + $eventkey = $message['EventKey'] ? $message['EventKey'] : $message['Event'];
  58 + //验证码消息
  59 + if (in_array($event, ['subscribe', 'SCAN']) && preg_match("/^captcha_([a-zA-Z0-9]+)_([0-9\.]+)/", $eventkey, $matches)) {
  60 + return WechatCaptcha::send($openid, $matches[1], $matches[2]);
  61 + }
  62 + switch ($event) {
  63 + case 'subscribe'://添加关注
  64 + $subscribeMessage = WechatConfig::getValue('default.subscribe.message');
  65 + $subscribeMessage = $subscribeMessage ? $subscribeMessage : "欢迎关注我们!";
  66 + return $subscribeMessage;
  67 + case 'unsubscribe'://取消关注
  68 + return '';
  69 + case 'LOCATION'://获取地理位置
  70 + return '';
  71 + case 'VIEW': //跳转链接,eventkey为链接
  72 + return '';
  73 + case 'SCAN': //扫码
  74 + return '';
  75 + default:
  76 + break;
  77 + }
  78 +
  79 + $wechatResponse = WechatResponse::where(["eventkey" => $eventkey, 'status' => 'normal'])->find();
  80 + if ($wechatResponse) {
  81 + $responseContent = (array)json_decode($wechatResponse['content'], true);
  82 + $wechatContext = WechatContext::where(['openid' => $openid])->order('id', 'desc')->find();
  83 + $data = ['eventkey' => $eventkey, 'command' => '', 'refreshtime' => time(), 'openid' => $openid];
  84 + if ($wechatContext) {
  85 + $wechatContext->save($data);
  86 + } else {
  87 + $wechatContext = WechatContext::create($data, true);
  88 + }
  89 + $result = $wechatService->response($this, $openid, '', $responseContent, $wechatContext);
  90 + if ($result) {
  91 + return $result;
  92 + }
  93 + }
  94 + return $unknownMessage;
  95 + case 'text': //文字消息
  96 + case 'image': //图片消息
  97 + case 'voice': //语音消息
  98 + case 'video': //视频消息
  99 + case 'location': //坐标消息
  100 + case 'link': //链接消息
  101 + default: //其它消息
  102 + //自动回复处理
  103 + if ($message['MsgType'] == 'text') {
  104 + $autoreply = null;
  105 + $autoreplyList = WechatAutoreply::where('status', 'normal')->cache(true)->order('weigh DESC,id DESC')->select();
  106 + foreach ($autoreplyList as $index => $item) {
  107 + //完全匹配和正则匹配
  108 + if ($item['text'] == $message['Content'] || (in_array(mb_substr($item['text'], 0, 1), ['#', '~', '/']) && preg_match($item['text'], $message['Content'], $matches))) {
  109 + $autoreply = $item;
  110 + break;
  111 + }
  112 + }
  113 +
  114 + if ($autoreply) {
  115 + $wechatResponse = WechatResponse::where(["eventkey" => $autoreply['eventkey'], 'status' => 'normal'])->find();
  116 + if ($wechatResponse) {
  117 + $responseContent = (array)json_decode($wechatResponse['content'], true);
  118 + $wechatContext = WechatContext::where(['openid' => $openid])->order('id', 'desc')->find();
  119 + $result = $wechatService->response($this, $openid, $message['Content'], $responseContent, $wechatContext, $matches);
  120 + if ($result) {
  121 + return $result;
  122 + }
  123 + }
  124 + }
  125 + }
  126 + return $unknownMessage;
  127 + }
  128 + return ""; //SUCCESS
  129 + });
  130 +
  131 + $response = $this->app->server->serve();
  132 + // 将响应输出
  133 + $response->send();
  134 + return;
  135 + }
  136 +
  137 + /**
  138 + * 登录回调
  139 + */
  140 + public function callback()
  141 + {
  142 +
  143 + }
  144 +
  145 + /**
  146 + * 支付回调
  147 + */
  148 + public function notify()
  149 + {
  150 + Log::record(file_get_contents('php://input'), "notify");
  151 + $response = $this->app->handlePaidNotify(function ($message, $fail) {
  152 + // 你的逻辑
  153 + return true;
  154 + // 或者错误消息
  155 + $fail('Order not exists.');
  156 + });
  157 +
  158 + $response->send();
  159 + return;
  160 + }
  161 +
  162 +}
  1 +name = wechat
  2 +title = 微信管理
  3 +intro = 在线管理微信公众号插件
  4 +author = FastAdmin
  5 +website = https://www.fastadmin.net
  6 +version = 1.2.0
  7 +state = 1
  8 +url = /addons/wechat
  9 +license = regular
  10 +licenseto = 10789
  1 +
  2 +CREATE TABLE IF NOT EXISTS `__PREFIX__wechat_autoreply` (
  3 + `id` int(10) NOT NULL AUTO_INCREMENT,
  4 + `title` varchar(100) NOT NULL DEFAULT '' COMMENT '标题',
  5 + `text` varchar(100) NOT NULL DEFAULT '' COMMENT '触发文本',
  6 + `eventkey` varchar(50) NOT NULL DEFAULT '' COMMENT '响应事件',
  7 + `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
  8 + `weigh` int(10) NOT NULL DEFAULT '0' COMMENT '权重',
  9 + `createtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '添加时间',
  10 + `updatetime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
  11 + `status` varchar(30) NOT NULL DEFAULT '' COMMENT '状态',
  12 + PRIMARY KEY (`id`),
  13 + KEY `eventkey` (`eventkey`)
  14 +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='微信自动回复表';
  15 +
  16 +BEGIN;
  17 +INSERT INTO `__PREFIX__wechat_autoreply`(`id`, `title`, `text`, `eventkey`, `remark`, `weigh`, `createtime`, `updatetime`, `status`) VALUES (1, '输入hello', 'hello', '58c7d908c4570', '', 1, 1493366855, 1493366855, 'normal');
  18 +INSERT INTO `__PREFIX__wechat_autoreply`(`id`, `title`, `text`, `eventkey`, `remark`, `weigh`, `createtime`, `updatetime`, `status`) VALUES (2, '输入你好', '你好', '58fdfaa9e1965', '', 2, 1493704976, 1493704976, 'normal');
  19 +COMMIT;
  20 +
  21 +CREATE TABLE IF NOT EXISTS `__PREFIX__wechat_captcha` (
  22 + `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  23 + `event` varchar(100) DEFAULT '' COMMENT '事件',
  24 + `openid` varchar(255) DEFAULT NULL COMMENT '用户openid',
  25 + `context` varchar(20) DEFAULT NULL COMMENT '上下文',
  26 + `code` varchar(30) DEFAULT NULL COMMENT '验证码',
  27 + `times` int(10) unsigned DEFAULT '0' COMMENT '验证次数',
  28 + `ip` varchar(50) DEFAULT '' COMMENT 'IP',
  29 + `createtime` int(10) DEFAULT NULL COMMENT '创建时间',
  30 + PRIMARY KEY (`id`),
  31 + KEY `ip` (`ip`,`event`) USING BTREE,
  32 + KEY `openid` (`openid`(191),`event`)
  33 +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='微信公众号验证码';
  34 +
  35 +CREATE TABLE IF NOT EXISTS `__PREFIX__wechat_config` (
  36 + `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  37 + `name` varchar(50) NOT NULL DEFAULT '' COMMENT '配置名称',
  38 + `title` varchar(50) NOT NULL DEFAULT '' COMMENT '配置标题',
  39 + `value` text NOT NULL COMMENT '配置值',
  40 + `createtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
  41 + `updatetime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
  42 + PRIMARY KEY (`id`),
  43 + UNIQUE KEY `name` (`name`) USING BTREE
  44 +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='微信配置表';
  45 +
  46 +BEGIN;
  47 +INSERT INTO `__PREFIX__wechat_config` VALUES ('1', 'menu', '微信菜单', '[{\"name\":\"FastAdmin\",\"sub_button\":[{\"name\":\"官网\",\"type\":\"view\",\"url\":\"http:\\/\\/www.fastadmin.net\"},{\"name\":\"在线演示\",\"type\":\"click\",\"key\":\"\"},{\"name\":\"文档\",\"type\":\"view\",\"url\":\"http:\\/\\/doc.fastadmin.net\"}]},{\"name\":\"在线客服\",\"type\":\"click\",\"key\":\"58cb852984970\"},{\"name\":\"关于我们\",\"type\":\"click\",\"key\":\"58bf944aa0777\"}]', '1497398820', '1500538185'), ('2', 'service', '客服配置', '{\"onlinetime\":\"09:00-18:00\",\"offlinemsg\":\"请在工作时间联系客服!\",\"nosessionmsg\":\"当前没有客服在线!请稍后重试!\",\"waitformsg\":\"请问有什么可以帮到您?\"}', '1497429674', '1497429674'), ('3', 'signin', '连续登录配置', '{\"s1\":\"100\",\"s2\":\"200\",\"s3\":\"300\",\"sn\":\"500\"}', '1497429711', '1497429711');
  48 +COMMIT;
  49 +
  50 +CREATE TABLE IF NOT EXISTS `__PREFIX__wechat_context` (
  51 + `id` int(10) NOT NULL AUTO_INCREMENT,
  52 + `openid` varchar(64) NOT NULL DEFAULT '',
  53 + `type` varchar(30) NOT NULL DEFAULT '' COMMENT '类型',
  54 + `eventkey` varchar(64) NOT NULL DEFAULT '',
  55 + `command` varchar(64) NOT NULL DEFAULT '',
  56 + `message` varchar(255) NOT NULL DEFAULT '' COMMENT '内容',
  57 + `refreshtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最后刷新时间',
  58 + `createtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
  59 + `updatetime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
  60 + PRIMARY KEY (`id`),
  61 + KEY `openid` (`openid`,`eventkey`) USING BTREE
  62 +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='微信上下文表';
  63 +
  64 +CREATE TABLE IF NOT EXISTS `__PREFIX__wechat_response` (
  65 + `id` int(10) NOT NULL AUTO_INCREMENT,
  66 + `title` varchar(100) NOT NULL DEFAULT '' COMMENT '资源名',
  67 + `eventkey` varchar(128) NOT NULL DEFAULT '' COMMENT '事件',
  68 + `type` enum('text','image','news','voice','video','music','link','app') NOT NULL DEFAULT 'text' COMMENT '类型',
  69 + `content` text NOT NULL COMMENT '内容',
  70 + `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
  71 + `createtime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
  72 + `updatetime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
  73 + `status` varchar(30) NOT NULL DEFAULT '' COMMENT '状态',
  74 + PRIMARY KEY (`id`),
  75 + UNIQUE KEY `eventkey` (`eventkey`) USING BTREE
  76 +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='微信资源表';
  77 +
  78 +BEGIN;
  79 +INSERT INTO `__PREFIX__wechat_response` VALUES ('1', '签到送积分', '58adaf7876aab', 'app', '{\"app\":\"signin\"}', '', '1487777656', '1487777656', 'normal'), ('2', '关于我们', '58bf944aa0777', 'app', '{\"app\":\"page\",\"id\":\"1\"}', '', '1488950346', '1488950346', 'normal'), ('3', '自动回复1', '58c7d908c4570', 'text', '{\"content\":\"world\"}', '', '1489492232', '1489492232', 'normal'), ('5', '自动回复2', '58fdfaa9e1965', 'text', '{\"content\":\"我是FastAdmin!\"}', '', '1493039785', '1493039785', 'normal');
  80 +COMMIT;
  81 +
  1 +<?php
  2 +
  3 +namespace addons\wechat\library;
  4 +
  5 +/**
  6 + * 微信配置类
  7 + */
  8 +class Config
  9 +{
  10 +
  11 + public static function load()
  12 + {
  13 + $config = get_addon_config('wechat');
  14 +
  15 + return [
  16 + /**
  17 + * 账号基本信息,请从微信公众平台/开放平台获取
  18 + */
  19 + 'app_id' => $config['app_id'], // AppID
  20 + 'secret' => $config['secret'], // AppSecret
  21 + 'token' => $config['token'], // Token
  22 + 'aes_key' => $config['aes_key'], // EncodingAESKey,安全模式下请一定要填写!!!
  23 +
  24 + /**
  25 + * 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
  26 + * 使用自定义类名时,构造函数将会接收一个 `EasyWeChat\Kernel\Http\Response` 实例
  27 + */
  28 + 'response_type' => 'array',
  29 +
  30 + /**
  31 + * 日志配置
  32 + *
  33 + * level: 日志级别, 可选为:debug/info/notice/warning/error/critical/alert/emergency
  34 + * path:日志文件位置(绝对路径!!!),要求可写权限
  35 + */
  36 + 'log' => [
  37 + 'default' => 'dev', // 默认使用的 channel,生产环境可以改为下面的 prod
  38 + 'channels' => [
  39 + // 测试环境
  40 + 'dev' => [
  41 + 'driver' => 'single',
  42 + 'path' => ROOT_PATH . '/runtime/log/easywechat.log',
  43 + 'level' => 'debug',
  44 + ],
  45 + // 生产环境
  46 + 'prod' => [
  47 + 'driver' => 'daily',
  48 + 'path' => ROOT_PATH . '/runtime/log/easywechat.log',
  49 + 'level' => $config['log_level'],
  50 + ],
  51 + ],
  52 + ],
  53 +
  54 + /**
  55 + * 接口请求相关配置,超时时间等,具体可用参数请参考:
  56 + * http://docs.guzzlephp.org/en/stable/request-config.html
  57 + *
  58 + * - retries: 重试次数,默认 1,指定当 http 请求失败时重试的次数。
  59 + * - retry_delay: 重试延迟间隔(单位:ms),默认 500
  60 + * - log_template: 指定 HTTP 日志模板,请参考:https://github.com/guzzle/guzzle/blob/master/src/MessageFormatter.php
  61 + */
  62 + 'http' => [
  63 + 'max_retries' => 1,
  64 + 'retry_delay' => 500,
  65 + 'timeout' => 5.0,
  66 + // 'base_uri' => 'https://api.weixin.qq.com/', // 如果你在国外想要覆盖默认的 url 的时候才使用,根据不同的模块配置不同的 uri
  67 + ],
  68 +
  69 + /**
  70 + * OAuth 配置
  71 + *
  72 + * scopes:公众平台(snsapi_userinfo / snsapi_base),开放平台:snsapi_login
  73 + * callback:OAuth授权完成后的回调页地址
  74 + */
  75 + 'oauth' => [
  76 + 'scopes' => ['snsapi_userinfo'],
  77 + 'callback' => $config['oauth_callback'],
  78 + ],
  79 + ];
  80 + }
  81 +
  82 +}
  1 +<?php
  2 +
  3 +namespace addons\wechat\library;
  4 +
  5 +use addons\signin\model\Signin;
  6 +use addons\third\model\Third;
  7 +use app\common\model\User;
  8 +use EasyWeChat\Kernel\Messages\News;
  9 +use EasyWeChat\Kernel\Messages\NewsItem;
  10 +use fast\Date;
  11 +use fast\Http;
  12 +use fast\Random;
  13 +use think\Session;
  14 +use think\Config;
  15 +
  16 +/**
  17 + * 微信服务类
  18 + */
  19 +class Wechat
  20 +{
  21 + public static function appConfig()
  22 + {
  23 + return array(
  24 + 'signin' => array(
  25 + 'name' => '签到送积分',
  26 + 'config' => array()
  27 + ),
  28 + 'blog' => array(
  29 + 'name' => '关联博客',
  30 + 'config' => array(
  31 + array(
  32 + 'type' => 'text',
  33 + 'caption' => '日志ID',
  34 + 'field' => 'post_id',
  35 + 'rule' => '',
  36 + 'extend' => 'class="form-control selectpage" data-source="blog/post/index" data-field="title"',
  37 + 'options' => '',
  38 + ),
  39 + array(
  40 + 'type' => 'radio',
  41 + 'caption' => '开启搜索日志',
  42 + 'field' => 'searchpost',
  43 + 'rule' => '',
  44 + 'extend' => '',
  45 + 'options' => [
  46 + '1' => '是',
  47 + '0' => '否',
  48 + ],
  49 + ),
  50 + array(
  51 + 'type' => 'text',
  52 + 'caption' => '正则搜索匹配索引',
  53 + 'field' => 'searchregexindex',
  54 + 'rule' => '',
  55 + 'defaultvalue' => '1',
  56 + 'extend' => '',
  57 + 'options' => [],
  58 + )
  59 + )
  60 + ),
  61 + 'cms' => array(
  62 + 'name' => '关联CMS',
  63 + 'config' => array(
  64 + array(
  65 + 'type' => 'text',
  66 + 'caption' => '文章ID',
  67 + 'field' => 'archives_id',
  68 + 'rule' => '',
  69 + 'extend' => 'class="form-control selectpage" data-source="cms/archives/index" data-field="title"',
  70 + 'options' => ''
  71 + ),
  72 + array(
  73 + 'type' => 'text',
  74 + 'caption' => '单页ID',
  75 + 'field' => 'page_id',
  76 + 'rule' => '',
  77 + 'extend' => 'class="form-control selectpage" data-source="cms/page/index" data-field="title"',
  78 + 'options' => ''
  79 + ),
  80 + array(
  81 + 'type' => 'text',
  82 + 'caption' => '专题ID',
  83 + 'field' => 'special_id',
  84 + 'rule' => '',
  85 + 'extend' => 'class="form-control selectpage" data-source="cms/special/index" data-field="title"',
  86 + 'options' => ''
  87 + ),
  88 + array(
  89 + 'type' => 'radio',
  90 + 'caption' => '开启搜索文章',
  91 + 'field' => 'searcharchives',
  92 + 'rule' => '',
  93 + 'extend' => '',
  94 + 'options' => [
  95 + '1' => '是',
  96 + '0' => '否',
  97 + ],
  98 + ),
  99 + array(
  100 + 'type' => 'radio',
  101 + 'caption' => '开启搜索单页',
  102 + 'field' => 'searchpage',
  103 + 'rule' => '',
  104 + 'extend' => '',
  105 + 'options' => [
  106 + '1' => '是',
  107 + '0' => '否',
  108 + ],
  109 + ),
  110 + array(
  111 + 'type' => 'radio',
  112 + 'caption' => '开启搜索专题',
  113 + 'field' => 'searchspecial',
  114 + 'rule' => '',
  115 + 'extend' => '',
  116 + 'options' => [
  117 + '1' => '是',
  118 + '0' => '否',
  119 + ],
  120 + ),
  121 + array(
  122 + 'type' => 'text',
  123 + 'caption' => '正则搜索匹配索引',
  124 + 'field' => 'searchregexindex',
  125 + 'rule' => '',
  126 + 'defaultvalue' => '1',
  127 + 'extend' => '',
  128 + 'options' => [],
  129 + )
  130 + )
  131 + ),
  132 + 'ask' => array(
  133 + 'name' => '关联问答',
  134 + 'config' => array(
  135 + array(
  136 + 'type' => 'text',
  137 + 'caption' => '问题ID',
  138 + 'field' => 'question_id',
  139 + 'extend' => 'class="form-control selectpage" data-source="ask/question/index" data-field="title"',
  140 + 'options' => ''
  141 + ),
  142 + array(
  143 + 'type' => 'text',
  144 + 'caption' => '文章ID',
  145 + 'field' => 'article_id',
  146 + 'extend' => 'class="form-control selectpage" data-source="ask/article/index" data-field="title"',
  147 + 'options' => ''
  148 + ),
  149 + array(
  150 + 'type' => 'radio',
  151 + 'caption' => '开启搜索问题',
  152 + 'field' => 'searchquestion',
  153 + 'rule' => '',
  154 + 'extend' => '',
  155 + 'options' => [
  156 + '1' => '是',
  157 + '0' => '否',
  158 + ],
  159 + ),
  160 + array(
  161 + 'type' => 'radio',
  162 + 'caption' => '开启搜索文章',
  163 + 'field' => 'searcharticle',
  164 + 'rule' => '',
  165 + 'extend' => '',
  166 + 'options' => [
  167 + '1' => '是',
  168 + '0' => '否',
  169 + ],
  170 + ),
  171 + array(
  172 + 'type' => 'text',
  173 + 'caption' => '正则搜索匹配索引',
  174 + 'field' => 'searchregexindex',
  175 + 'rule' => '',
  176 + 'defaultvalue' => '1',
  177 + 'extend' => '',
  178 + 'options' => [],
  179 + )
  180 + )
  181 + ),
  182 + 'vote' => array(
  183 + 'name' => '关联投票',
  184 + 'config' => array(
  185 + array(
  186 + 'type' => 'text',
  187 + 'caption' => '投票主题ID',
  188 + 'field' => 'subject_id',
  189 + 'extend' => 'class="form-control selectpage" data-source="vote/subject/index" data-field="title"',
  190 + 'rule' => '',
  191 + 'options' => ''
  192 + ),
  193 + array(
  194 + 'type' => 'text',
  195 + 'caption' => '参赛人员ID',
  196 + 'field' => 'player_id',
  197 + 'rule' => '',
  198 + 'extend' => 'class="form-control selectpage" data-source="vote/player/index" data-field="nickname"',
  199 + 'options' => ''
  200 + ),
  201 + array(
  202 + 'type' => 'radio',
  203 + 'caption' => '开启搜索主题',
  204 + 'field' => 'searchsubject',
  205 + 'rule' => '',
  206 + 'extend' => '',
  207 + 'options' => [
  208 + '1' => '是',
  209 + '0' => '否',
  210 + ],
  211 + ),
  212 + array(
  213 + 'type' => 'radio',
  214 + 'caption' => '开启搜索参赛人员',
  215 + 'field' => 'searchplayer',
  216 + 'rule' => '',
  217 + 'extend' => '',
  218 + 'options' => [
  219 + '1' => '是',
  220 + '0' => '否',
  221 + ],
  222 + ),
  223 + array(
  224 + 'type' => 'text',
  225 + 'caption' => '正则搜索匹配索引',
  226 + 'field' => 'searchregexindex',
  227 + 'rule' => '',
  228 + 'defaultvalue' => '1',
  229 + 'extend' => '',
  230 + 'options' => [],
  231 + )
  232 + )
  233 + ),
  234 + );
  235 + }
  236 +
  237 + /**
  238 + * 应用交互
  239 + * @return array|bool|mixed|string
  240 + */
  241 + public function response($obj, $openid, $message, $content, $context, $matches = null)
  242 + {
  243 + $response = false;
  244 + if (isset($content['app'])) {
  245 + $entry = null;
  246 + $keyword = isset($content['searchregexindex']) && $content['searchregexindex'] > -1 && $matches && isset($matches[$content['searchregexindex']])
  247 + ? $matches[$content['searchregexindex']] : $message;
  248 + switch ($content['app']) {
  249 + case 'signin':
  250 + $signinInfo = get_addon_info('signin');
  251 + if (!$signinInfo || !$signinInfo['state']) {
  252 + return "请先在后台管理安装并启用《会员签到》插件";
  253 + }
  254 + $thirdInfo = get_addon_info('third');
  255 + if (!$thirdInfo || !$thirdInfo['state']) {
  256 + return "请先在后台管理安装并启用《第三方登录》插件";
  257 + }
  258 + $user = self::getUserByOpenid($openid);
  259 + if (!$user) {
  260 + return "请先在会员中心绑定微信登录,<a href='" . addon_url('third/index/connect', [':platform' => 'wechat'], true, true) . "'>点击这里绑定</a>";
  261 + }
  262 + $config = get_addon_config('signin');
  263 + $signdata = $config['signinscore'];
  264 + $lastdata = Signin::where('user_id', $user->id)->order('id', 'desc')->find();
  265 + $successions = $lastdata && $lastdata['createtime'] > Date::unixtime('day', -1) ? $lastdata['successions'] : 0;
  266 + $signin = Signin::where('user_id', $user->id)->whereTime('createtime', 'today')->find();
  267 + if ($signin) {
  268 + return '今天已签到,请明天再来!';
  269 + } else {
  270 + $successions++;
  271 + Signin::create(['user_id' => $user->id, 'successions' => $successions, 'createtime' => time()]);
  272 + $score = isset($signdata['s' . $successions]) ? $signdata['s' . $successions] : $signdata['sn'];
  273 +
  274 + $user->setInc('score', $score);
  275 + User::score($score, $user->id, "连续签到{$successions}天");
  276 + return '签到成功!连续签到' . $successions . '天!获得' . $score . '积分,';
  277 + }
  278 + break;
  279 + case 'blog':
  280 + $blogInfo = get_addon_info('blog');
  281 + if (!$blogInfo || !$blogInfo['state']) {
  282 + return "请先在后台管理安装并启用《简单博客》插件";
  283 + }
  284 + $entry = \addons\blog\model\Post::get($content['post_id']);
  285 + if ($entry) {
  286 + $entry['image'] = $entry['thumb'];
  287 + }
  288 + if (!$entry && $content['searchpost']) {
  289 + $entry = \addons\blog\model\Post::where("title|description", 'like', "%{$keyword}%")->where('status', 'normal')->find();
  290 + }
  291 + if (!$entry) {
  292 + return "未搜索到任何匹配信息$keyword" . json_encode($matches);
  293 + }
  294 + break;
  295 + case 'cms':
  296 + $cmsInfo = get_addon_info('cms');
  297 + if (!$cmsInfo || !$cmsInfo['state']) {
  298 + return "请先在后台管理安装并启用《CMS内容管理系统》插件";
  299 + }
  300 + if (isset($content['archives_id']) && $content['archives_id']) {
  301 + $entry = \addons\cms\model\Archives::get($content['archives_id']);
  302 + } elseif (isset($content['page_id']) && $content['page_id']) {
  303 + $entry = \addons\cms\model\Page::get($content['page_id']);
  304 + } elseif (isset($content['special_id']) && $content['special_id']) {
  305 + $entry = \addons\cms\model\Special::get($content['special_id']);
  306 + }
  307 + if (!$entry && $content['searcharchives']) {
  308 + $entry = \addons\cms\model\Archives::where("title|description", 'like', "%{$keyword}%")->where('status', 'normal')->find();
  309 + }
  310 + if (!$entry && $content['searchpage']) {
  311 + $entry = \addons\cms\model\Page::where("title|description", 'like', "%{$keyword}%")->where('status', 'normal')->find();
  312 + }
  313 + if (!$entry && $content['searchspecial']) {
  314 + $entry = \addons\cms\model\Special::where("title|description", 'like', "%{$keyword}%")->where('status', 'normal')->find();
  315 + }
  316 + if (!$entry) {
  317 + return "未搜索到任何匹配信息";
  318 + }
  319 + break;
  320 + case 'ask':
  321 + $blogInfo = get_addon_info('ask');
  322 + if (!$blogInfo || !$blogInfo['state']) {
  323 + return "请先在后台管理安装并启用《知识付费问答》插件";
  324 + }
  325 +
  326 + if (isset($content['question_id']) && $content['question_id']) {
  327 + $entry = \addons\ask\model\Question::get($content['question_id']);
  328 + } elseif (isset($content['article_id']) && $content['article_id']) {
  329 + $entry = \addons\ask\model\Article::get($content['article_id']);
  330 + }
  331 +
  332 + if (!$entry && $content['searchquestion']) {
  333 + $entry = \addons\ask\model\Question::where("title", 'like', "%{$keyword}%")->where('status', 'normal')->find();
  334 + }
  335 + if (!$entry && $content['searcharticle']) {
  336 + $entry = \addons\ask\model\Article::where("title|description", 'like', "%{$keyword}%")->where('status', 'normal')->find();
  337 + }
  338 + if (!$entry) {
  339 + return "未搜索到任何匹配信息";
  340 + }
  341 + break;
  342 + case 'vote':
  343 + $blogInfo = get_addon_info('vote');
  344 + if (!$blogInfo || !$blogInfo['state']) {
  345 + return "请先在后台管理安装并启用《在线投票系统》插件";
  346 + }
  347 + if (isset($content['subject_id']) && $content['subject_id']) {
  348 + $entry = \addons\vote\model\Subject::all($content['subject_id']);
  349 + } elseif (isset($content['player_id']) && $content['player_id']) {
  350 + $entry = \addons\vote\model\Player::all($content['player_id']);
  351 + }
  352 +
  353 + if (!$entry && $content['searchsubject']) {
  354 + $entry = \addons\vote\model\Subject::where("title|description", 'like', "%{$keyword}%")->where('status', 'normal')->find();
  355 + }
  356 + if (!$entry && $content['searchplayer']) {
  357 + $entry = \addons\vote\model\Player::where("nickname", 'like', "%{$keyword}%")->where('status', 'normal')->find();
  358 + }
  359 +
  360 + if (!$entry) {
  361 + return "未搜索到任何匹配信息";
  362 + }
  363 + break;
  364 + default:
  365 + break;
  366 + }
  367 + if (isset($entry) && $entry) {
  368 + $items = [
  369 + new NewsItem([
  370 + 'title' => isset($entry['title']) ? $entry['title'] : (isset($entry['nickname']) ? $entry['nickname'] : ''),
  371 + 'description' => isset($entry['description']) ? $entry['description'] : '',
  372 + 'url' => $entry['fullurl'],
  373 + 'image' => cdnurl($entry['image'], true),
  374 + ]),
  375 + ];
  376 + $news = new News($items);
  377 +
  378 + $response[] = $news;
  379 + }
  380 + } else {
  381 + $response = isset($content['content']) ? $content['content'] : $response;
  382 + }
  383 + return $response;
  384 + }
  385 +
  386 + /**
  387 + * 获取Token
  388 + */
  389 + public static function getAccessToken()
  390 + {
  391 + $token = Session::get('wechat_access_token');
  392 + if (!$token) {
  393 + $config = get_addon_config('wechat');
  394 + $params = [
  395 + 'grant_type' => 'client_credential',
  396 + 'appid' => $config['app_id'],
  397 + 'secret' => $config['secret'],
  398 + ];
  399 + $url = "https://api.weixin.qq.com/cgi-bin/token";
  400 + $result = Http::sendRequest($url, $params, 'GET');
  401 + if ($result['ret']) {
  402 + $msg = (array)json_decode($result['msg'], true);
  403 + if (isset($msg['access_token'])) {
  404 + $token = $msg['access_token'];
  405 + Session::set('wechat_access_token', $token, $msg['expires_in'] - 1);
  406 + }
  407 + }
  408 + }
  409 + return $token;
  410 + }
  411 +
  412 + /**
  413 + * 根据Openid获取用户信息
  414 + * @param string $openid 微信OpenID
  415 + * @return User|null
  416 + */
  417 + public static function getUserByOpenid($openid)
  418 + {
  419 + $third = Third::where('platform', 'wechat')->where('openid', $openid)->find();
  420 + if ($third && $third->user_id) {
  421 + return User::get($third->user_id);
  422 + }
  423 + return null;
  424 + }
  425 +}
  1 +<?php
  2 +
  3 +namespace addons\wechat\model;
  4 +
  5 +use think\Model;
  6 +
  7 +class WechatAutoreply extends Model
  8 +{
  9 +
  10 + // 自动写入时间戳字段
  11 + protected $autoWriteTimestamp = 'int';
  12 + // 定义时间戳字段名
  13 + protected $createTime = 'createtime';
  14 + protected $updateTime = 'updatetime';
  15 +
  16 +}
  1 +<?php
  2 +
  3 +namespace addons\wechat\model;
  4 +
  5 +use fast\Random;
  6 +use think\Model;
  7 +
  8 +class WechatCaptcha extends Model
  9 +{
  10 +
  11 + // 表名
  12 + protected $name = 'wechat_captcha';
  13 + // 自动写入时间戳字段
  14 + protected $autoWriteTimestamp = 'int';
  15 + // 定义时间戳字段名
  16 + protected $createTime = 'createtime';
  17 + protected $updateTime = '';
  18 + // 追加属性
  19 + protected $append = [
  20 + ];
  21 +
  22 + /**
  23 + * 发送验证码
  24 + * @param $openid string 用户OpenID
  25 + * @param $event string 事件
  26 + * @param $ip string IP地址
  27 + * @return string
  28 + */
  29 + public static function send($openid, $event, $ip)
  30 + {
  31 + $captcha = self::where(['openid' => $openid, 'event' => $event])->whereTime('createtime', '-2 minutes')->find();
  32 + if ($captcha) {
  33 + return "验证码发送速度过快,请稍后重试";
  34 + }
  35 + $code = Random::alnum(4);
  36 + $data = [
  37 + 'event' => $event,
  38 + 'openid' => $openid,
  39 + 'code' => $code,
  40 + 'ip' => $ip,
  41 + ];
  42 + self::create($data);
  43 + return "你的验证码是:{$code},2分钟内输入有效";
  44 + }
  45 +
  46 + /**
  47 + * 检测验证码
  48 + * @param $code string 验证码
  49 + * @param $event string 事件
  50 + * @param $ip string IP
  51 + * @return bool
  52 + */
  53 + public static function check($code, $event, $ip = null)
  54 + {
  55 + $ip = is_null($ip) ? request()->ip() : $ip;
  56 + $captcha = self::where(['ip' => $ip, 'event' => $event])->whereTime('createtime', '-2 minutes')->find();
  57 + if ($captcha && $captcha->code == $code && $captcha->times < 10) {
  58 + $captcha->setInc("times");
  59 + return true;
  60 + }
  61 + //验证大于10次或超时
  62 + if ($captcha && ($captcha->times >= 10 || time() - $captcha->createtime > 120)) {
  63 + $captcha->delete();
  64 + }
  65 +
  66 + return false;
  67 + }
  68 +
  69 +}
  1 +<?php
  2 +
  3 +namespace addons\wechat\model;
  4 +
  5 +use think\Model;
  6 +
  7 +class WechatConfig extends Model
  8 +{
  9 +
  10 + // 表名,不含前缀
  11 + public $name = 'wechat_config';
  12 + // 自动写入时间戳字段
  13 + protected $autoWriteTimestamp = 'int';
  14 + // 定义时间戳字段名
  15 + protected $createTime = 'createtime';
  16 + protected $updateTime = 'updatetime';
  17 + // 追加属性
  18 + protected $append = [
  19 + ];
  20 +
  21 + /**
  22 + * 读取指定配置名称的值
  23 + * @param string $name
  24 + * @return string
  25 + */
  26 + public static function getValue($name)
  27 + {
  28 + $item = self::get(['name' => $name]);
  29 + return $item ? $item->value : '';
  30 + }
  31 +
  32 +}
  1 +<?php
  2 +
  3 +namespace addons\wechat\model;
  4 +
  5 +use think\Model;
  6 +
  7 +class WechatContext extends Model
  8 +{
  9 +
  10 + // 自动写入时间戳字段
  11 + protected $autoWriteTimestamp = 'int';
  12 + // 定义时间戳字段名
  13 + protected $createTime = 'createtime';
  14 + protected $updateTime = 'updatetime';
  15 +
  16 +}
  1 +<?php
  2 +
  3 +namespace addons\wechat\model;
  4 +
  5 +use think\Model;
  6 +
  7 +class WechatResponse extends Model
  8 +{
  9 +
  10 + // 自动写入时间戳字段
  11 + protected $autoWriteTimestamp = 'int';
  12 + // 定义时间戳字段名
  13 + protected $createTime = 'createtime';
  14 + protected $updateTime = 'updatetime';
  15 +
  16 +}
  1 +<?php
  2 +
  3 +namespace app\admin\controller;
  4 +
  5 +use app\common\controller\Backend;
  6 +use think\Config;
  7 +use think\console\Input;
  8 +use think\Db;
  9 +use think\Exception;
  10 +
  11 +/**
  12 + * 在线命令管理
  13 + *
  14 + * @icon fa fa-circle-o
  15 + */
  16 +class Command extends Backend
  17 +{
  18 +
  19 + /**
  20 + * Command模型对象
  21 + */
  22 + protected $model = null;
  23 + protected $noNeedRight = ['get_controller_list', 'get_field_list'];
  24 +
  25 + public function _initialize()
  26 + {
  27 + parent::_initialize();
  28 + $this->model = model('Command');
  29 + $this->view->assign("statusList", $this->model->getStatusList());
  30 + }
  31 +
  32 + /**
  33 + * 添加
  34 + */
  35 + public function add()
  36 + {
  37 +
  38 + $tableList = [];
  39 + $list = \think\Db::query("SHOW TABLES");
  40 + foreach ($list as $key => $row) {
  41 + $tableList[reset($row)] = reset($row);
  42 + }
  43 +
  44 + $this->view->assign("tableList", $tableList);
  45 + return $this->view->fetch();
  46 + }
  47 +
  48 + /**
  49 + * 获取字段列表
  50 + * @internal
  51 + */
  52 + public function get_field_list()
  53 + {
  54 + $dbname = Config::get('database.database');
  55 + $prefix = Config::get('database.prefix');
  56 + $table = $this->request->request('table');
  57 + //从数据库中获取表字段信息
  58 + $sql = "SELECT * FROM `information_schema`.`columns` "
  59 + . "WHERE TABLE_SCHEMA = ? AND table_name = ? "
  60 + . "ORDER BY ORDINAL_POSITION";
  61 + //加载主表的列
  62 + $columnList = Db::query($sql, [$dbname, $table]);
  63 + $fieldlist = [];
  64 + foreach ($columnList as $index => $item) {
  65 + $fieldlist[] = $item['COLUMN_NAME'];
  66 + }
  67 + $this->success("", null, ['fieldlist' => $fieldlist]);
  68 + }
  69 +
  70 + /**
  71 + * 获取控制器列表
  72 + * @internal
  73 + */
  74 + public function get_controller_list()
  75 + {
  76 + //搜索关键词,客户端输入以空格分开,这里接收为数组
  77 + $word = (array)$this->request->request("q_word/a");
  78 + $word = implode('', $word);
  79 +
  80 + $adminPath = dirname(__DIR__) . DS;
  81 + $controllerDir = $adminPath . 'controller' . DS;
  82 + $files = new \RecursiveIteratorIterator(
  83 + new \RecursiveDirectoryIterator($controllerDir), \RecursiveIteratorIterator::LEAVES_ONLY
  84 + );
  85 + $list = [];
  86 + foreach ($files as $name => $file) {
  87 + if (!$file->isDir()) {
  88 + $filePath = $file->getRealPath();
  89 + $name = str_replace($controllerDir, '', $filePath);
  90 + $name = str_replace(DS, "/", $name);
  91 + if (!preg_match("/(.*)\.php\$/", $name)) {
  92 + continue;
  93 + }
  94 + if (!$word || stripos($name, $word) !== false) {
  95 + $list[] = ['id' => $name, 'name' => $name];
  96 + }
  97 + }
  98 + }
  99 + $pageNumber = $this->request->request("pageNumber");
  100 + $pageSize = $this->request->request("pageSize");
  101 + return json(['list' => array_slice($list, ($pageNumber - 1) * $pageSize, $pageSize), 'total' => count($list)]);
  102 + }
  103 +
  104 + /**
  105 + * 详情
  106 + */
  107 + public function detail($ids)
  108 + {
  109 + $row = $this->model->get($ids);
  110 + if (!$row) {
  111 + $this->error(__('No Results were found'));
  112 + }
  113 + $this->view->assign("row", $row);
  114 + return $this->view->fetch();
  115 + }
  116 +
  117 + /**
  118 + * 执行
  119 + */
  120 + public function execute($ids)
  121 + {
  122 + $row = $this->model->get($ids);
  123 + if (!$row) {
  124 + $this->error(__('No Results were found'));
  125 + }
  126 + $result = $this->doexecute($row['type'], json_decode($row['params'], true));
  127 + $this->success("", null, ['result' => $result]);
  128 + }
  129 +
  130 + /**
  131 + * 执行命令
  132 + */
  133 + public function command($action = '')
  134 + {
  135 + $commandtype = $this->request->request("commandtype");
  136 + $params = $this->request->request();
  137 + $allowfields = [
  138 + 'crud' => 'table,controller,model,fields,force,local,delete,menu',
  139 + 'menu' => 'controller,delete',
  140 + 'min' => 'module,resource,optimize',
  141 + 'api' => 'url,module,output,template,force,title,author,class,language',
  142 + ];
  143 + $argv = [];
  144 + $allowfields = isset($allowfields[$commandtype]) ? explode(',', $allowfields[$commandtype]) : [];
  145 + $allowfields = array_filter(array_intersect_key($params, array_flip($allowfields)));
  146 + if (isset($params['local']) && !$params['local']) {
  147 + $allowfields['local'] = $params['local'];
  148 + } else {
  149 + unset($allowfields['local']);
  150 + }
  151 + foreach ($allowfields as $key => $param) {
  152 + $argv[] = "--{$key}=" . (is_array($param) ? implode(',', $param) : $param);
  153 + }
  154 + if ($commandtype == 'crud') {
  155 + $extend = 'setcheckboxsuffix,enumradiosuffix,imagefield,filefield,intdatesuffix,switchsuffix,citysuffix,selectpagesuffix,selectpagessuffix,ignorefields,sortfield,editorsuffix,headingfilterfield';
  156 + $extendArr = explode(',', $extend);
  157 + foreach ($params as $index => $item) {
  158 + if (in_array($index, $extendArr)) {
  159 + foreach (explode(',', $item) as $key => $value) {
  160 + if ($value) {
  161 + $argv[] = "--{$index}={$value}";
  162 + }
  163 + }
  164 + }
  165 + }
  166 + $isrelation = (int)$this->request->request('isrelation');
  167 + if ($isrelation && isset($params['relation'])) {
  168 + foreach ($params['relation'] as $index => $relation) {
  169 + foreach ($relation as $key => $value) {
  170 + $argv[] = "--{$key}=" . (is_array($value) ? implode(',', $value) : $value);
  171 + }
  172 + }
  173 + }
  174 + } else {
  175 + if ($commandtype == 'menu') {
  176 + if (isset($params['allcontroller']) && $params['allcontroller']) {
  177 + $argv[] = "--controller=all-controller";
  178 + } else {
  179 + foreach (explode(',', $params['controllerfile']) as $index => $param) {
  180 + if ($param) {
  181 + $argv[] = "--controller=" . substr($param, 0, -4);
  182 + }
  183 + }
  184 + }
  185 + } else {
  186 + if ($commandtype == 'min') {
  187 +
  188 + } else {
  189 + if ($commandtype == 'api') {
  190 +
  191 + } else {
  192 +
  193 + }
  194 + }
  195 + }
  196 + }
  197 + if ($action == 'execute') {
  198 + $result = $this->doexecute($commandtype, $argv);
  199 + $this->success("", null, ['result' => $result]);
  200 + } else {
  201 + $this->success("", null, ['command' => "php think {$commandtype} " . implode(' ', $argv)]);
  202 + }
  203 +
  204 + return;
  205 + }
  206 +
  207 + protected function doexecute($commandtype, $argv)
  208 + {
  209 + $commandName = "\\app\\admin\\command\\" . ucfirst($commandtype);
  210 + $input = new Input($argv);
  211 + $output = new \addons\command\library\Output();
  212 + $command = new $commandName($commandtype);
  213 + $data = [
  214 + 'type' => $commandtype,
  215 + 'params' => json_encode($argv),
  216 + 'command' => "php think {$commandtype} " . implode(' ', $argv),
  217 + 'executetime' => time(),
  218 + ];
  219 + $this->model->save($data);
  220 + try {
  221 + $command->run($input, $output);
  222 + $result = implode("\n", $output->getMessage());
  223 + $this->model->status = 'successed';
  224 + } catch (Exception $e) {
  225 + $result = implode("\n", $output->getMessage()) . "\n";
  226 + $result .= $e->getMessage();
  227 + $this->model->status = 'failured';
  228 + }
  229 + $result = trim($result);
  230 + $this->model->content = $result;
  231 + $this->model->save();
  232 + return $result;
  233 + }
  234 +
  235 +
  236 +}
  1 +<?php
  2 +
  3 +namespace app\admin\controller;
  4 +
  5 +use app\common\controller\Backend;
  6 +use think\Db;
  7 +use think\Config;
  8 +use think\Exception;
  9 +
  10 +//use think\Config;
  11 +
  12 +/**
  13 + * 自建表管理
  14 + *
  15 + * @icon fa fa-circle-o
  16 + */
  17 +class Tablemake extends Backend {
  18 +
  19 + /**
  20 + * Test模型对象
  21 + * @var \app\admin\model\Test
  22 + */
  23 + protected $ModelOnline = null;
  24 + protected $ModelFields = null;
  25 + protected $searchFields = false;//关闭快捷搜索
  26 +
  27 + protected $db_name = '';
  28 + protected $db_prefix = '';
  29 +
  30 +
  31 + public function _initialize() {
  32 + parent::_initialize();
  33 + $this->ModelOnline = model('TableMakeTables');
  34 + $this->ModelFields = model('TableMakeFields');
  35 +
  36 + $dictionary_url = url("tablemake/dictionary", [], true, true);
  37 + $this->view->assign("dictionary_url", $dictionary_url);
  38 + }
  39 +
  40 + /*
  41 + * 数据表列表
  42 + */
  43 +
  44 + public function index() {
  45 +
  46 + $this->searchFields = "name,table,desc";
  47 + if ($this->request->isAjax()) {
  48 + $prefix = Config::get('database.prefix');
  49 + $this->model = $this->ModelOnline;
  50 + list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  51 + $list = $this->model
  52 + ->where($where)
  53 + ->order($sort, $order)
  54 + ->paginate($limit);
  55 + $result = array("total" => $list->total(), "rows" => $list->items(), "prefix" => $prefix);
  56 + return json($result);
  57 + }
  58 +
  59 + return $this->view->fetch();
  60 + }
  61 +
  62 + /*
  63 + * 创建数据表
  64 + */
  65 +
  66 + public function add() {
  67 + if ($this->request->isPost()) {
  68 + $params = $this->request->post("row/a");
  69 + if ($params) {
  70 + if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
  71 + $params[$this->dataLimitField] = $this->auth->id;
  72 + }
  73 + try {
  74 + //是否采用模型验证
  75 + if ($this->modelValidate) {
  76 + $name = str_replace("\\model\\", "\\validate\\", get_class($this->ModelOnline));
  77 + $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : true) : $this->modelValidate;
  78 + $this->ModelOnline->validate($validate);
  79 + }
  80 + $params['createtime'] = time();
  81 + $params['updatetime'] = time();
  82 + $result = $this->ModelOnline->allowField(true)->save($params);
  83 + $prefix = Config::get('database.prefix');
  84 + if ($result !== false) {
  85 + //在此执行创建表的操作
  86 + $sql = "CREATE TABLE IF NOT EXISTS `{$prefix}" . $params['table'] . "` (
  87 + `id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  88 + PRIMARY KEY (`id`)
  89 + ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='" . $params['name'] . "';";
  90 +
  91 + $res = \think\Db::execute($sql);
  92 + //var_export($res);
  93 + $this->success();
  94 + } else {
  95 + $this->error($this->ModelOnline->getError());
  96 + }
  97 + } catch (\think\exception\PDOException $e) {
  98 + $this->error($e->getMessage());
  99 + } catch (\think\Exception $e) {
  100 + $this->error($e->getMessage());
  101 + }
  102 + }
  103 + $this->error(__('Parameter %s can not be empty', ''));
  104 + }
  105 +
  106 + $prefix = Config::get('database.prefix');
  107 + $this->view->assign("prefix", $prefix);
  108 + return $this->view->fetch();
  109 + }
  110 +
  111 + /*
  112 + * 编辑数据表
  113 + */
  114 +
  115 + public function edit($ids = NULL) {
  116 + $row = $this->ModelOnline->get($ids);
  117 + if (!$row)
  118 + $this->error(__('No Results were found'));
  119 + $adminIds = $this->getDataLimitAdminIds();
  120 + if (is_array($adminIds)) {
  121 + if (!in_array($row[$this->dataLimitField], $adminIds)) {
  122 + $this->error(__('You have no permission'));
  123 + }
  124 + }
  125 + if ($this->request->isPost()) {
  126 + $params = $this->request->post("row/a");
  127 + if ($params) {
  128 + try {
  129 + //是否采用模型验证
  130 + if ($this->modelValidate) {
  131 + $name = basename(str_replace('\\', '/', get_class($this->ModelOnline)));
  132 + $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : true) : $this->modelValidate;
  133 + $row->validate($validate);
  134 + }
  135 + $params['updatetime'] = time();
  136 + $result = $row->allowField(true)->save($params);
  137 + if ($result !== false) {
  138 + $prefix = Config::get('database.prefix');
  139 + $sql = "ALTER TABLE `{$prefix}" . $row['table'] . "` COMMENT='" . $row['name'] . "';";
  140 + $res = \think\Db::execute($sql);
  141 + $this->success();
  142 + } else {
  143 + $this->error($row->getError());
  144 + }
  145 + } catch (\think\exception\PDOException $e) {
  146 + $this->error($e->getMessage());
  147 + } catch (\think\Exception $e) {
  148 + $this->error($e->getMessage());
  149 + }
  150 + }
  151 + $this->error(__('Parameter %s can not be empty', ''));
  152 + }
  153 + $prefix = Config::get('database.prefix');
  154 + $this->view->assign("row", $row);
  155 + $this->view->assign("prefix", $prefix);
  156 + return $this->view->fetch();
  157 + }
  158 +
  159 + /*
  160 + * 删除模块
  161 + */
  162 +
  163 + public function del($ids = NULL) {
  164 + if ($ids) {
  165 + $pk = $this->ModelOnline->getPk();
  166 + $adminIds = $this->getDataLimitAdminIds();
  167 + if (is_array($adminIds)) {
  168 + $count = $this->ModelOnline->where($this->dataLimitField, 'in', $adminIds);
  169 + }
  170 + $list = $this->ModelOnline->where($pk, 'in', $ids)->select();
  171 + $prefix = Config::get('database.prefix');
  172 + $count = 0;
  173 + foreach ($list as $k => $v) {
  174 + $sql = "DROP TABLE IF EXISTS `{$prefix}" . $v->table . "`;";
  175 + try {
  176 + $res = \think\Db::execute($sql);
  177 + $this->ModelFields->where("mid", '=', $v->id)->delete();
  178 + $count += $v->delete();
  179 + if ($count) {
  180 + $this->success(__('删除成功!'), null, __('删除成功!'));
  181 + } else {
  182 + $this->error(__('No rows were deleted'));
  183 + }
  184 + } catch (Exception $ex) {
  185 + $this->error(__('No rows were deleted'));
  186 + }
  187 + }
  188 + }
  189 + $this->error(__('Parameter %s can not be empty', 'ids'));
  190 + }
  191 +
  192 + /*
  193 + * 验证重名
  194 + */
  195 +
  196 + public function check($table = null, $name = null) {
  197 + if ($table == null && $name == null) {
  198 + if ($this->request->isAjax()) {
  199 + $table = $this->request->request('table');
  200 + $name = $this->request->request('name');
  201 + }
  202 + }
  203 + if ($table && $name) {
  204 + $sql = "describe `{$table}` `{$name}`";
  205 + $res = \think\Db::query($sql);
  206 + if ($res) {
  207 + return true;
  208 + } else {
  209 + return false;
  210 + }
  211 + } else {
  212 + return false;
  213 + }
  214 + }
  215 +
  216 + /*
  217 + * 字段列表
  218 + */
  219 +
  220 + public function fields($ids = NULL) {
  221 + $this->searchFields = "name,title,comment";
  222 + if ($ids == NULL) {
  223 + $ids = intval($this->request->request('ids'));
  224 + }
  225 + $model = $this->ModelOnline->get($ids);
  226 + if (!$model) {
  227 + $this->error(__('No Results were found'));
  228 + }
  229 +
  230 + if ($this->request->isAjax()) {
  231 + $prefix = Config::get('database.prefix');
  232 + $this->model = $this->ModelFields;
  233 + list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  234 + $list = $this->model
  235 + ->where("mid", '=', $ids)
  236 + ->where($where)
  237 + ->order($sort, $order)
  238 + ->paginate($limit);
  239 + $result = array("total" => $list->total(), "rows" => $list->items(), "prefix" => $prefix);
  240 + return json($result);
  241 +
  242 +
  243 +// $list = $this->ModelFields->where("mid", '=', $ids)->order('id desc')->select();
  244 +// $total = count($list);
  245 +// $prefix = Config::get('database.prefix');
  246 +// $result = array("total" => $total, "rows" => $list, "prefix" => $prefix);
  247 +// return json($result);
  248 + }
  249 + $this->view->assign("ids", $ids);
  250 + return $this->view->fetch();
  251 + }
  252 +
  253 + /*
  254 + * 添加字段
  255 + */
  256 +
  257 + public function field_add($mid = NULL) {
  258 + $mod_table = $this->ModelOnline->get($mid);
  259 + if (!$mod_table)
  260 + $this->error(__('No Results were found'));
  261 + if ($this->request->isPost()) {
  262 + $params = $this->request->post("row/a");
  263 + if ($params) {
  264 + try {
  265 + //是否采用模型验证
  266 + if ($this->modelValidate) {
  267 + $name = str_replace("\\model\\", "\\validate\\", get_class($this->ModelFields));
  268 + $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : true) : $this->modelValidate;
  269 + $this->ModelFields->validate($validate);
  270 + }
  271 + $prefix = Config::get('database.prefix');
  272 + $field = array();
  273 + $fieldData = array();
  274 + switch ($params['category']) {
  275 + case "1":
  276 + $allow = array(
  277 + "text" => array("suffix" => "text", "type" => "varchar", "length" => 200),
  278 + "number" => array("suffix" => "number", "type" => "bigint", "length" => 11),
  279 + "time" => array("suffix" => "time", "type" => "bigint", "length" => 11),
  280 + "image" => array("suffix" => "image", "type" => "varchar", "length" => 255),
  281 + "images" => array("suffix" => "images", "type" => "varchar", "length" => 2000),
  282 + "file" => array("suffix" => "file", "type" => "varchar", "length" => 255),
  283 + "files" => array("suffix" => "files", "type" => "varchar", "length" => 2000),
  284 + "avatar" => array("suffix" => "avatar", "type" => "varchar", "length" => 255),
  285 + "avatars" => array("suffix" => "avatars", "type" => "varchar", "length" => 2000),
  286 + "content" => array("suffix" => "content", "type" => "text", "length" => 0),
  287 + "_id" => array("suffix" => "_id", "type" => "bigint", "length" => 11),
  288 + "_ids" => array("suffix" => "_ids", "type" => "varchar", "length" => 255),
  289 + "list-enum" => array("suffix" => "list", "type" => "enum", "length" => 0),
  290 + "list-set" => array("suffix" => "list", "type" => "set", "length" => 0),
  291 + "data-enum" => array("suffix" => "data", "type" => "enum", "length" => 0),
  292 + "data-set" => array("suffix" => "data", "type" => "set", "length" => 0),
  293 + "json" => array("suffix" => "json", "type" => "varchar", "length" => 2000),
  294 + "switch" => array("suffix" => "switch", "type" => "tinyint", "length" => 1),
  295 + );
  296 + if (isset($allow[$params['suffix']]) && is_array($allow[$params['suffix']])) {
  297 + $fieldData['special'] = "";
  298 + $fieldData['suffix'] = $params['suffix'];
  299 + //$field['name'] = $params['name'] . $allow[$params['suffix']]['suffix']; //字段名
  300 + $field['name'] = $params['name']; //字段名
  301 + $field['field'] = $params['name'] . $allow[$params['suffix']]['suffix']; //字段名
  302 + $field['length'] = $field['length2'] = isset($params['length']) && intval($params['length']) ? intval($params['length']) : $allow[$params['suffix']]['length']; //字段长度
  303 + $field['type'] = $allow[$params['suffix']]['type']; //字段类型
  304 + $field['default'] = isset($params['default']) ? $params['default'] : ""; //默认值
  305 + if ($allow[$params['suffix']]['type'] == "enum" || $allow[$params['suffix']]['type'] == "set") {
  306 + $comment = \GuzzleHttp\json_decode($params['comment'], true);
  307 + $field['comment'] = $params['title'] . ":"; //备注
  308 + $field['length2'] = "";
  309 + $str = "";
  310 + $default_optional = array();
  311 + foreach ($comment as $k => $v) {
  312 + $default_optional[] = $k;
  313 + $field['comment'] .= $str . $k . "=" . $v;
  314 + $field['length2'] .= $str . "'" . $k . "'";
  315 + $str = ",";
  316 + }
  317 + if (!in_array($field['default'], $default_optional)) {
  318 + $field['default'] = $default_optional[0];
  319 + }
  320 + } else {
  321 + $params['comment'] = "";
  322 + $field['comment'] = $params['title']; //备注
  323 + }
  324 + } else {
  325 + $this->error(__('特殊字段类型不正确!'));
  326 + }
  327 + break;
  328 + case "2":
  329 + $allow = array(
  330 + "varchar" => array("type" => "varchar", "length" => 255),
  331 + "int" => array("type" => "bigint", "length" => 11),
  332 + "enum" => array("type" => "enum", "length" => 0),
  333 + "set" => array("type" => "set", "length" => 0),
  334 + "float" => array("type" => "float", "length" => "10,2"),
  335 + "text" => array("type" => "text", "length" => 0),
  336 + "datetime" => array("type" => "datetime", "length" => 11),
  337 + "date" => array("type" => "date", "length" => 11),
  338 + "year" => array("type" => "year", "length" => 4),
  339 + "timestamp" => array("type" => "timestamp", "length" => 11),
  340 + );
  341 + if (isset($allow[$params['type']]) && is_array($allow[$params['type']])) {
  342 + $fieldData['special'] = "";
  343 + $fieldData['suffix'] = "";
  344 + $params['suffix'] = "";
  345 + $field['name'] = $params['name']; //字段名
  346 + $field['field'] = $params['name']; //字段名
  347 + if ($params['type'] == "float") {
  348 + $field['length'] = $field['length2'] = isset($params['length']) && $params['length'] ? $params['length'] : $allow[$params['type']]['length']; //字段长度
  349 + } else {
  350 + $field['length'] = $field['length2'] = isset($params['length']) && intval($params['length']) ? intval($params['length']) : $allow[$params['type']]['length']; //字段长度
  351 + }
  352 + $field['type'] = $allow[$params['type']]['type']; //字段类型
  353 + $field['default'] = isset($params['default']) ? $params['default'] : ""; //默认值
  354 + if ($allow[$params['type']]['type'] == "enum" || $allow[$params['type']]['type'] == "set") {
  355 + $comment = \GuzzleHttp\json_decode($params['comment'], true);
  356 + $field['comment'] = $params['title'] . ":"; //备注
  357 + $field['length2'] = "";
  358 + $str = "";
  359 + $default_optional = array();
  360 + foreach ($comment as $k => $v) {
  361 + $default_optional[] = $k;
  362 + $field['comment'] .= $str . $k . "=" . $v;
  363 + $field['length2'] .= $str . "'" . $k . "'";
  364 + $str = ",";
  365 + }
  366 + if (!in_array($field['default'], $default_optional)) {
  367 + $field['default'] = $default_optional[0];
  368 + }
  369 + } else {
  370 + $params['comment'] = "";
  371 + $field['comment'] = $params['title']; //备注
  372 + }
  373 + } else {
  374 + $this->error(__('特殊字段类型不正确!'));
  375 + }
  376 + break;
  377 + case "3":
  378 + $allow = array(
  379 + "user_id" => array("title" => "会员ID(单选)", "type" => "bigint", "length" => 11),
  380 + "category_id" => array("title" => "分类ID(单选)", "type" => "bigint", "length" => 11),
  381 + "category_ids" => array("title" => "分类ID(多选)", "type" => "varchar", "length" => 200),
  382 + "weigh" => array("title" => "权重", "type" => "bigint", "length" => 11),
  383 + "status" => array("title" => "状态", "type" => "enum", "length" => 0),
  384 + "createtime" => array("title" => "创建时间", "type" => "bigint", "length" => 11),
  385 + "updatetime" => array("title" => "更新时间", "type" => "bigint", "length" => 11),
  386 + "deletetime" => array("title" => "删除时间", "type" => "bigint", "length" => 11),
  387 + );
  388 + if (isset($allow[$params['special']]) && is_array($allow[$params['special']])) {
  389 + $fieldData['special'] = $params['special'];
  390 + $fieldData['suffix'] = "";
  391 + //$params['title'] = $allow[$params['special']]['title'];
  392 +// $params['comment'] = $params['suffix'] = "";
  393 + $field['name'] = $params['special']; //字段名
  394 + $field['field'] = $params['special']; //字段名
  395 + $field['length'] = $field['length2'] = $allow[$params['special']]['length']; //字段长度
  396 +// $field['comment'] = $params['title']; //备注
  397 + $field['type'] = $allow[$params['special']]['type']; //字段类型
  398 + $field['default'] = $field['type'] == "varchar" ? "" : "0"; //默认值
  399 +
  400 + if ($params['special'] == "status") {
  401 + $comment = \GuzzleHttp\json_decode($params['comment'], true);
  402 + $field['comment'] = $params['title'] . ":"; //备注
  403 + $field['length2'] = "";
  404 + $str = "";
  405 + $default_optional = array();
  406 + foreach ($comment as $k => $v) {
  407 + $default_optional[] = $k;
  408 + $field['comment'] .= $str . $k . "=" . $v;
  409 + $field['length2'] .= $str . "'" . $k . "'";
  410 + $str = ",";
  411 + }
  412 + if (!in_array($field['default'], $default_optional)) {
  413 + $field['default'] = $default_optional[0];
  414 + }
  415 + } else {
  416 + $params['comment'] = "";
  417 + $field['comment'] = $params['title']; //备注
  418 + }
  419 + } else {
  420 + $this->error(__('特殊字段类型不正确!'));
  421 + }
  422 + break;
  423 + default :
  424 + $this->error(__('No Results were found'));
  425 + break;
  426 + }
  427 +
  428 + if ($this->check($prefix . $mod_table['table'], $field['name'])) {
  429 + $this->error(__('字段已经存在!'));
  430 + }
  431 + $fieldData['mid'] = $params['mid'];
  432 + $fieldData['category'] = $params['category'];
  433 + $fieldData['title'] = $params['title'];
  434 + $fieldData['name'] = $field['name'];
  435 + $fieldData['field'] = $field['field'];
  436 + $fieldData['type'] = $field['type'];
  437 + $fieldData['length'] = $field['length'];
  438 + $fieldData['default'] = $field['default'];
  439 + $fieldData['comment'] = $field['comment'];
  440 + $fieldData['desc'] = $params['desc'];
  441 + $fieldData['createtime'] = time();
  442 + $fieldData['updatetime'] = time();
  443 + if ($fieldData['type'] == "text") {
  444 + $fieldData['default'] = "";
  445 + }
  446 + if ($field['type'] == "bigint" || $field['type'] == "int") {
  447 + $field['default'] = intval($field['default']);
  448 + } elseif ($field['type'] == "tinyint") {
  449 + $field['default'] = in_array($field['default'], [0, 1]) ? $field['default'] : 0;
  450 + } elseif ($field['type'] == "float") {
  451 + $field['default'] = is_float($field['default']) ? $field['default'] : 0;
  452 + }
  453 +
  454 + \think\Db::startTrans();
  455 + try {
  456 + $result = $this->ModelFields->allowField(true)->save($fieldData);
  457 + if ($result !== false) {
  458 + //在此执行添加字段的操作
  459 + if (in_array($field['type'], ["text", "datetime", "date", "year", "timestamp"])) {
  460 + $sql = "ALTER TABLE `{$prefix}{$mod_table['table']}` ADD COLUMN `{$field['field']}` {$field['type']} NOT NULL COMMENT '{$field['comment']}';";
  461 + } else {
  462 + $sql = "ALTER TABLE `{$prefix}{$mod_table['table']}` ADD COLUMN `{$field['field']}` {$field['type']}({$field['length2']}) NOT NULL DEFAULT '{$field['default']}' COMMENT '{$field['comment']}';";
  463 + }
  464 + try {
  465 + $res = \think\Db::execute($sql);
  466 + } catch (Exception $ex) {
  467 + new Exception('参数错误,请检查字段名,字段长度或者默认值等输入参数是否合法');
  468 + }
  469 + } else {
  470 + new Exception($this->ModelFields->getError());
  471 + }
  472 + \think\Db::commit();
  473 + } catch (Exception $e) {
  474 + \think\Db::rollback();
  475 + $this->error($e->getMessage());
  476 + }
  477 + $this->success();
  478 + } catch (\think\exception\PDOException $e) {
  479 + $this->error($e->getMessage());
  480 + } catch (\think\Exception $e) {
  481 + $this->error($e->getMessage());
  482 + }
  483 + }
  484 + $this->error(__('Parameter %s can not be empty', ''));
  485 + }
  486 + $prefix = Config::get('database.prefix');
  487 + $this->view->assign("prefix", $prefix);
  488 + $this->view->assign("mid", $mid);
  489 + return $this->view->fetch();
  490 + }
  491 +
  492 + /*
  493 + * 修改字段
  494 + */
  495 +
  496 + public function field_edit($ids = NULL) {
  497 + //$oldField_info = $this->ModelFields->get($ids);
  498 + $field_info = $this->ModelFields->get($ids);
  499 + $oldField_info = $field_info->toArray();
  500 + //var_dump($field_info);
  501 + if (!$field_info)
  502 + $this->error(__('No Results were found'));
  503 +
  504 + $mod_table = $this->ModelOnline->get($field_info['mid']);
  505 + if (!$mod_table)
  506 + $this->error(__('No Results were found'));
  507 +
  508 + if ($this->request->isPost()) {
  509 + $params = $this->request->post("row/a");
  510 + if ($params) {
  511 + try {
  512 + //是否采用模型验证
  513 + if ($this->modelValidate) {
  514 + $name = str_replace("\\model\\", "\\validate\\", get_class($this->ModelFields));
  515 + $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : true) : $this->modelValidate;
  516 + $this->ModelFields->validate($validate);
  517 + }
  518 + $prefix = Config::get('database.prefix');
  519 + $field = array();
  520 + $fieldData = array();
  521 + switch ($field_info['category']) {
  522 + case "1":
  523 + $allow = array(
  524 + "text" => array("suffix" => "text", "type" => "varchar", "length" => 200),
  525 + "number" => array("suffix" => "number", "type" => "bigint", "length" => 11),
  526 + "time" => array("suffix" => "time", "type" => "bigint", "length" => 11),
  527 + "image" => array("suffix" => "image", "type" => "varchar", "length" => 255),
  528 + "images" => array("suffix" => "images", "type" => "varchar", "length" => 2000),
  529 + "file" => array("suffix" => "file", "type" => "varchar", "length" => 255),
  530 + "files" => array("suffix" => "files", "type" => "varchar", "length" => 2000),
  531 + "avatar" => array("suffix" => "avatar", "type" => "varchar", "length" => 255),
  532 + "avatars" => array("suffix" => "avatars", "type" => "varchar", "length" => 2000),
  533 + "content" => array("suffix" => "content", "type" => "text", "length" => 0),
  534 + "_id" => array("suffix" => "_id", "type" => "bigint", "length" => 11),
  535 + "_ids" => array("suffix" => "_ids", "type" => "varchar", "length" => 255),
  536 + "list-enum" => array("suffix" => "list", "type" => "enum", "length" => 0),
  537 + "list-set" => array("suffix" => "list", "type" => "set", "length" => 0),
  538 + "data-enum" => array("suffix" => "data", "type" => "enum", "length" => 0),
  539 + "data-set" => array("suffix" => "data", "type" => "set", "length" => 0),
  540 + "json" => array("suffix" => "json", "type" => "varchar", "length" => 2000),
  541 + "switch" => array("suffix" => "switch", "type" => "tinyint", "length" => 1),
  542 + );
  543 + if (isset($allow[$params['suffix']]) && is_array($allow[$params['suffix']])) {
  544 + $fieldData['special'] = "";
  545 + $fieldData['suffix'] = $params['suffix'];
  546 + $field['name'] = $params['name']; //字段名
  547 + $field['field'] = $params['name'] . $allow[$params['suffix']]['suffix']; //字段名
  548 + $field['length'] = $field['length2'] = isset($params['length']) && intval($params['length']) ? intval($params['length']) : $allow[$params['suffix']]['length']; //字段长度
  549 + $field['type'] = $allow[$params['suffix']]['type']; //字段类型
  550 + $field['default'] = isset($params['default']) ? $params['default'] : ""; //默认值
  551 + if ($allow[$params['suffix']]['type'] == "enum" || $allow[$params['suffix']]['type'] == "set") {
  552 + $comment = \GuzzleHttp\json_decode($params['comment'], true);
  553 + $field['comment'] = $params['title'] . ":"; //备注
  554 + $field['length2'] = "";
  555 + $str = "";
  556 + $default_optional = array();
  557 + foreach ($comment as $k => $v) {
  558 + $default_optional[] = $k;
  559 + $field['comment'] .= $str . $k . "=" . $v;
  560 + $field['length2'] .= $str . "'" . $k . "'";
  561 + $str = ",";
  562 + }
  563 + if (!in_array($field['default'], $default_optional)) {
  564 + $field['default'] = $default_optional[0];
  565 + }
  566 + } else {
  567 + $params['comment'] = "";
  568 + $field['comment'] = $params['title']; //备注
  569 + }
  570 + } else {
  571 + $this->error(__('特殊字段类型不正确!'));
  572 + }
  573 + break;
  574 + case "2":
  575 + $allow = array(
  576 + "varchar" => array("type" => "varchar", "length" => 255),
  577 + "int" => array("type" => "bigint", "length" => 11),
  578 + "enum" => array("type" => "enum", "length" => 0),
  579 + "set" => array("type" => "set", "length" => 0),
  580 + "float" => array("type" => "float", "length" => "10,2"),
  581 + "text" => array("type" => "text", "length" => 0),
  582 + "datetime" => array("type" => "datetime", "length" => 11),
  583 + "date" => array("type" => "date", "length" => 11),
  584 + "year" => array("type" => "year", "length" => 4),
  585 + "timestamp" => array("type" => "timestamp", "length" => 11),
  586 + );
  587 + if (isset($allow[$params['type']]) && is_array($allow[$params['type']])) {
  588 + $fieldData['special'] = "";
  589 + $fieldData['suffix'] = "";
  590 + $params['suffix'] = "";
  591 + $field['name'] = $params['name']; //字段名
  592 + $field['field'] = $params['name']; //字段名
  593 + if ($params['type'] == "float") {
  594 + $field['length'] = $field['length2'] = isset($params['length']) && $params['length'] ? $params['length'] : $allow[$params['type']]['length']; //字段长度
  595 + } else {
  596 + $field['length'] = $field['length2'] = isset($params['length']) && intval($params['length']) ? intval($params['length']) : $allow[$params['type']]['length']; //字段长度
  597 + }
  598 + $field['type'] = $allow[$params['type']]['type']; //字段类型
  599 + $field['default'] = isset($params['default']) ? $params['default'] : ""; //默认值
  600 + if ($allow[$params['type']]['type'] == "enum" || $allow[$params['type']]['type'] == "set") {
  601 + $comment = \GuzzleHttp\json_decode($params['comment'], true);
  602 + $field['comment'] = $params['title'] . ":"; //备注
  603 + $field['length2'] = "";
  604 + $str = "";
  605 + $default_optional = array();
  606 + foreach ($comment as $k => $v) {
  607 + $default_optional[] = $k;
  608 + $field['comment'] .= $str . $k . "=" . $v;
  609 + $field['length2'] .= $str . "'" . $k . "'";
  610 + $str = ",";
  611 + }
  612 + if (!in_array($field['default'], $default_optional)) {
  613 + $field['default'] = $default_optional[0];
  614 + }
  615 + } else {
  616 + $params['comment'] = "";
  617 + $field['comment'] = $params['title']; //备注
  618 + }
  619 + } else {
  620 + $this->error(__('特殊字段类型不正确!'));
  621 + }
  622 + break;
  623 + case "3":
  624 + $allow = array(
  625 + "user_id" => array("title" => "会员ID(单选)", "type" => "bigint", "length" => 11),
  626 + "category_id" => array("title" => "分类ID(单选)", "type" => "bigint", "length" => 11),
  627 + "category_ids" => array("title" => "分类ID(多选)", "type" => "varchar", "length" => 200),
  628 + "weigh" => array("title" => "权重", "type" => "bigint", "length" => 11),
  629 + "status" => array("title" => "状态", "type" => "enum", "length" => 0),
  630 + "createtime" => array("title" => "创建时间", "type" => "bigint", "length" => 11),
  631 + "updatetime" => array("title" => "更新时间", "type" => "bigint", "length" => 11),
  632 + "deletetime" => array("title" => "删除时间", "type" => "bigint", "length" => 11),
  633 + );
  634 + if (isset($allow[$params['special']]) && is_array($allow[$params['special']])) {
  635 + $fieldData['special'] = $params['special'];
  636 + $fieldData['suffix'] = "";
  637 +// $params['title'] = $allow[$params['special']]['title'];
  638 +// if ($params['special'] != "status") {
  639 +// $params['comment'] = "";
  640 +// }
  641 +// $params['comment'] =
  642 + $params['suffix'] = "";
  643 + $field['name'] = $params['special']; //字段名
  644 + $field['field'] = $params['special']; //字段名
  645 + $field['length'] = $field['length2'] = $allow[$params['special']]['length']; //字段长度
  646 +// $field['comment'] = $params['title']; //备注
  647 + $field['type'] = $allow[$params['special']]['type']; //字段类型
  648 + $field['default'] = $field['type'] == "varchar" ? "" : "0"; //默认值
  649 +
  650 + if ($params['special'] == "status") {
  651 + $comment = \GuzzleHttp\json_decode($params['comment'], true);
  652 + $field['comment'] = $params['title'] . ":"; //备注
  653 + $field['length2'] = "";
  654 + $str = "";
  655 + $default_optional = array();
  656 + foreach ($comment as $k => $v) {
  657 + $default_optional[] = $k;
  658 + $field['comment'] .= $str . $k . "=" . $v;
  659 + $field['length2'] .= $str . "'" . $k . "'";
  660 + $str = ",";
  661 + }
  662 + if (!in_array($field['default'], $default_optional)) {
  663 + $field['default'] = $default_optional[0];
  664 + }
  665 + } else {
  666 + $params['comment'] = "";
  667 + $field['comment'] = $params['title']; //备注
  668 + }
  669 +
  670 + } else {
  671 + $this->error(__('特殊字段类型不正确!'));
  672 + }
  673 + break;
  674 + default :
  675 + $this->error(__('No Results were found'));
  676 + break;
  677 + }
  678 + /*
  679 + if ($this->check($prefix . $mod_table['table'], $field['name'])) {
  680 + $this->error(__('字段已经存在!'));
  681 + } */
  682 + $fieldData['mid'] = $params['mid'];
  683 + //$fieldData['category'] = $params['category'];
  684 + $fieldData['title'] = $params['title'];
  685 + $fieldData['name'] = $field['name'];
  686 + $fieldData['field'] = $field['field'];
  687 + $fieldData['type'] = $field['type'];
  688 + $fieldData['length'] = $field['length'];
  689 + $fieldData['default'] = $field['default'];
  690 + $fieldData['comment'] = $field['comment'];
  691 + $fieldData['desc'] = $params['desc'];
  692 + $fieldData['updatetime'] = time();
  693 + if ($fieldData['type'] == "text") {
  694 + $fieldData['default'] = "";
  695 + }
  696 +
  697 +
  698 + if ($field['type'] == "bigint" || $field['type'] == "int") {
  699 + $field['default'] = intval($field['default']);
  700 + } elseif ($field['type'] == "tinyint") {
  701 + $field['default'] = in_array($field['default'], [0, 1]) ? $field['default'] : 0;
  702 + } elseif ($field['type'] == "float") {
  703 + $field['default'] = is_float($field['default']) ? $field['default'] : 0;
  704 + }
  705 +
  706 + \think\Db::startTrans();
  707 + try {
  708 + $result = $field_info->save($fieldData);
  709 + if ($result !== false) {
  710 + //在此执行添加字段的操作
  711 + if (in_array($field['type'], ["text", "datetime", "date", "year", "timestamp"])) {
  712 + $sql = "ALTER TABLE `{$prefix}{$mod_table['table']}` CHANGE COLUMN `{$oldField_info['field']}` `{$field['field']}` {$field['type']} NOT NULL COMMENT '{$field['comment']}' ;";
  713 + } else {
  714 + $sql = "ALTER TABLE `{$prefix}{$mod_table['table']}` CHANGE COLUMN `{$oldField_info['field']}` `{$field['field']}` {$field['type']}({$field['length2']}) NOT NULL DEFAULT '{$field['default']}' COMMENT '{$field['comment']}' ;";
  715 + }
  716 + try {
  717 + $res = \think\Db::execute($sql);
  718 + } catch (Exception $ex) {
  719 + // $field_info->save($oldField_info);
  720 + throw new Exception('参数错误,请检查字段名,字段长度或者默认值等输入参数是否合法');
  721 + }
  722 + } else {
  723 + throw new Exception($this->ModelFields->getError());
  724 + }
  725 + \think\Db::commit();
  726 + } catch (Exception $e) {
  727 + \think\Db::rollback();
  728 + $this->error($e->getMessage());
  729 + }
  730 + $this->success();
  731 + } catch (\think\exception\PDOException $e) {
  732 + $field_info->save($oldField_info);
  733 + $this->error($e->getMessage());
  734 + } catch (\think\Exception $e) {
  735 + $field_info->save($oldField_info);
  736 + $this->error($e->getMessage());
  737 + }
  738 + }
  739 + $this->error(__('Parameter %s can not be empty', ''));
  740 + }
  741 + $comment = "";
  742 + if ($field_info['type'] == "enum" || $field_info['type'] == "set") {
  743 + //echo $field_info['comment'];
  744 + $commentStr = substr($field_info['comment'], strpos($field_info['comment'], ":") + 1);
  745 +
  746 + $commentArr = [];
  747 + foreach (explode(",", $commentStr) as $k => $v) {
  748 +
  749 + list($key, $val) = explode("=", $v);
  750 +
  751 + $commentArr[$key] = $val;
  752 + }
  753 +
  754 + $comment = \json_encode($commentArr);
  755 + }
  756 + $prefix = Config::get('database.prefix');
  757 + $this->view->assign("field_info", $field_info);
  758 + $this->view->assign("row", $field_info);
  759 + $this->view->assign("prefix", $prefix);
  760 + $this->view->assign("comment", $comment);
  761 + $this->view->assign("mid", $field_info['mid']);
  762 + return $this->view->fetch();
  763 + }
  764 +
  765 + public function field_del($ids = NULL) {
  766 + if ($ids) {
  767 + $pk = $this->ModelFields->getPk();
  768 + $adminIds = $this->getDataLimitAdminIds();
  769 + if (is_array($adminIds)) {
  770 + $count = $this->ModelFields->where($this->dataLimitField, 'in', $adminIds);
  771 + }
  772 + $list = $this->ModelFields->where($pk, 'in', $ids)->select();
  773 + $prefix = Config::get('database.prefix');
  774 + $count = 0;
  775 + foreach ($list as $k => $v) {
  776 + $mod_table = $this->ModelOnline->get($v['mid']);
  777 + $sql = "ALTER TABLE `{$prefix}{$mod_table['table']}` DROP `{$v['field']}` ";
  778 + try {
  779 + $res = \think\Db::execute($sql);
  780 + $count += $v->delete();
  781 + if ($count) {
  782 + $this->success();
  783 + } else {
  784 + $this->error(__('No rows were deleted'));
  785 + }
  786 + } catch (Exception $ex) {
  787 + $this->error(__('No rows were deleted'));
  788 + }
  789 + }
  790 + }
  791 + $this->error(__('Parameter %s can not be empty', 'ids'));
  792 + }
  793 +
  794 + public function dictionary() {
  795 +
  796 + $this->db_name = \config("database.database");
  797 + $this->db_prefix = \config("database.prefix");
  798 + $this->view->assign('db_name', $this->db_name);
  799 + $this->view->assign('db_prefix', $this->db_prefix);
  800 +
  801 + $dictionary = [
  802 + 'make' => [],
  803 + 'system' => [],
  804 + 'other' => [],
  805 + ];
  806 +
  807 + //读取所有表
  808 + $tables_res = Db::table("information_schema.TABLES")->field("TABLE_NAME")->where(['TABLE_SCHEMA' => $this->db_name,])->select();
  809 + $tables_all = array_column($tables_res, 'TABLE_NAME');
  810 +
  811 + //已经获取到数据字典的表
  812 + $tables_isset = [];
  813 +
  814 + //声明系统表 获取系统表的数据字典
  815 + $tables_system = ['admin', 'admin_log', 'attachment', 'area', 'auth_group', 'auth_group_access', 'auth_rule', 'category', 'config', 'ems', 'sms', 'user', 'user_group', 'user_money_log', 'user_rule', 'user_score_log', 'user_token', 'version'];
  816 + foreach ($tables_system as $k => $v) {
  817 + $table_name = $this->db_prefix . $v;
  818 + $dictionary['system'][] = $this->getSystemTableInfo($table_name);
  819 + $tables_isset[] = $table_name;
  820 + }
  821 +
  822 + //读取自建表 获取自建表数据字典
  823 + $tables_make = \app\admin\model\TableMakeTables::all(function ($query) {
  824 + $query->order("weigh desc,id desc");
  825 + });
  826 + foreach ($tables_make as $k => $v) {
  827 + $table_name = $this->db_prefix . $v['table'];
  828 + $dictionary['make'][] = $this->getMakeTableInfo($table_name, $v);
  829 + $tables_isset[] = $table_name;
  830 + }
  831 +
  832 + //获取其他表数据字典 求差集,计算出其他表
  833 + $tables_other = array_diff($tables_all, $tables_isset);
  834 + foreach ($tables_other as $k => $v) {
  835 + $table_name = $v;
  836 + $dictionary['other'][] = $this->getOtherTableInfo($table_name);
  837 + $tables_isset[] = $table_name;
  838 + }
  839 +
  840 + $this->view->assign('dictionary', $dictionary);
  841 + $this->view->engine->layout(false);
  842 + return $this->view->fetch();
  843 +
  844 + }
  845 +
  846 +
  847 + /**
  848 + * 根据表名获取系统表的数据字典数据
  849 + * @param $table_name 表名
  850 + * @return array
  851 + */
  852 + protected function getSystemTableInfo($table_name) {
  853 + return $this->getOtherTableInfo($table_name);
  854 + }
  855 +
  856 + /**
  857 + * 根据表名获取非自建表的数据字典信息
  858 + * @param $table_name
  859 + * @return array
  860 + */
  861 + protected function getOtherTableInfo($table_name) {
  862 + $table_info = $this->getTableInfo($table_name);
  863 + $result = [
  864 + 'name' => $table_info['table_info']['TABLE_COMMENT'] ? $table_info['table_info']['TABLE_COMMENT'] : $table_name,
  865 + 'table' => preg_replace('/^(' . $this->db_prefix . ').*?/is', '', $table_name),//表名去前缀
  866 + 'table_name' => $table_name,
  867 + 'desc' => $table_info['table_info']['TABLE_COMMENT'],
  868 + 'engine' => $table_info['table_info']['ENGINE'],
  869 + 'table_comment' => $table_info['table_info']['TABLE_COMMENT'],
  870 + 'table_collation' => $table_info['table_info']['TABLE_COLLATION'],
  871 + 'create_time' => $table_info['table_info']['CREATE_TIME'],
  872 + 'update_time' => $table_info['table_info']['UPDATE_TIME'],
  873 + 'fields' => $this->getTableFields($table_info['table_fields']),
  874 + ];
  875 + return $result;
  876 + }
  877 +
  878 + /**
  879 + * 根据表名、自建表信息数据,获取自建表的数据字典信息
  880 + * @param $table_name 表名
  881 + * @param $table
  882 + * @return array
  883 + * @throws \think\exception\DbException
  884 + */
  885 + protected function getMakeTableInfo($table_name, $table) {
  886 + $model_fields = \app\admin\model\TableMakeFields::all(function ($query) use ($table) {
  887 + $query->where(['mid' => $table['id']]);
  888 + $query->order("weigh desc,id desc");
  889 + });
  890 + $result = $this->getOtherTableInfo($table_name);
  891 + $result['name'] = $table['name'];
  892 + $result['table'] = $table['table'];
  893 + $result['desc'] = $table['desc'];
  894 + $result['create_time'] = date("Y-m-d H:i:s", $table['createtime']);
  895 + $result['update_time'] = date("Y-m-d H:i:s", $table['updatetime']);
  896 + $result['fields'] = $this->getTableFieldsByMake($result['fields'], $model_fields);
  897 + return $result;
  898 + }
  899 +
  900 + /**
  901 + * 结合表的字段备注 自建表存储的信息,生成自建表的字段数据字典
  902 + * @param $fields
  903 + * @param array $make_fields
  904 + * @return array
  905 + */
  906 + protected function getTableFieldsByMake($fields, $make_fields = []) {
  907 + $result = [];
  908 + $field_list = [];
  909 + foreach ($fields as $k => $v) {
  910 + $field_list[$v['field_name']] = $v;
  911 + }
  912 + $result[] = $field_list['id'];
  913 + foreach ($make_fields as $k => $v) {
  914 + $result[] = [
  915 + "field_title" => $v['title'],
  916 + "field_name" => $v['field'],
  917 + "character" => isset($field_list[$v['field']]) ? $field_list[$v['field']]['character'] : NULL,
  918 + "field_collation" => isset($field_list[$v['field']]) ? $field_list[$v['field']]['field_collation'] : NULL,
  919 + "data_type" => isset($field_list[$v['field']]) ? $field_list[$v['field']]['data_type'] : NULL,//字段类型
  920 + "column_type" => isset($field_list[$v['field']]) ? $field_list[$v['field']]['column_type'] : NULL,//列类型
  921 + "is_nullable" => isset($field_list[$v['field']]) ? $field_list[$v['field']]['is_nullable'] : NULL,//是否能为空
  922 + "length" => isset($field_list[$v['field']]) ? $field_list[$v['field']]['length'] : NULL,//字符串长度
  923 + "column_comment" => isset($field_list[$v['field']]) ? $field_list[$v['field']]['column_comment'] : NULL,//字段备注
  924 + "default" => isset($field_list[$v['field']]) ? $field_list[$v['field']]['default'] : NULL,//字段默认值
  925 + "desc" => $v['desc'],
  926 + ];
  927 + }
  928 + return $result;
  929 + }
  930 +
  931 + /**
  932 + * 根据表的字段备注,生成字段数据字典
  933 + * @param $fields
  934 + * @return array
  935 + */
  936 + protected function getTableFields($fields) {
  937 + $result = [];
  938 + foreach ($fields as $k => $v) {
  939 + $column_type = preg_replace('/(unsigned).*?/is', '(无符号)', $v['COLUMN_TYPE']);
  940 + list($field_name) = explode(":", $v['COLUMN_COMMENT']);
  941 + $result[] = [
  942 + "field_title" => $field_name ? $field_name : $v['COLUMN_NAME'],
  943 + "field_name" => $v['COLUMN_NAME'],
  944 + "character" => $v['CHARACTER_SET_NAME'],
  945 + "field_collation" => $v['COLLATION_NAME'],
  946 + "data_type" => $v['DATA_TYPE'],//字段类型
  947 + "column_type" => $column_type,//列类型
  948 + "is_nullable" => $v['IS_NULLABLE'],//是否能为空
  949 + "length" => $v['CHARACTER_MAXIMUM_LENGTH'],//字符串长度
  950 + "column_comment" => $v['COLUMN_COMMENT'],//字段备注
  951 + "default" => $v['COLUMN_DEFAULT'],//字段默认值
  952 + "desc" => "",//字段默认值
  953 + ];
  954 + }
  955 + return $result;
  956 +
  957 + }
  958 +
  959 + /**
  960 + * 获取指定表的基本信息
  961 + * @param $table_name
  962 + * @return array
  963 + * @throws \think\db\exception\DataNotFoundException
  964 + * @throws \think\db\exception\ModelNotFoundException
  965 + * @throws \think\exception\DbException
  966 + */
  967 + protected function getTableInfo($table_name) {
  968 +// //读取表信息
  969 +// $sql = "SELECT * FROM information_schema.TABLES WHERE table_schema = '{$db_name}' and TABLE_NAME='{$table_name}'";
  970 +// $res = Db::query($sql);
  971 +// //读取表结构
  972 +// $sql = "SELECT * FROM information_schema.COLUMNS where table_schema ='{$db_name}' and TABLE_NAME = '{$table_name}'";
  973 +// $res = Db::query($sql);
  974 +
  975 + //读取表信息
  976 + $table_info = Db::table("information_schema.TABLES")->field("*")->where(['TABLE_SCHEMA' => $this->db_name, 'TABLE_NAME' => $table_name])->find();
  977 + //读取表结构
  978 + $table_fields = Db::table("information_schema.COLUMNS")->field("*")->where(['TABLE_SCHEMA' => $this->db_name, 'TABLE_NAME' => $table_name])->select();
  979 + return [
  980 + 'table_info' => $table_info,
  981 + 'table_fields' => $table_fields,
  982 + ];
  983 + }
  984 +
  985 +}
  1 +<?php
  2 +
  3 +namespace app\admin\controller;
  4 +
  5 +use app\common\controller\Backend;
  6 +
  7 +/**
  8 + * 第三方登录管理
  9 + *
  10 + * @icon fa fa-circle-o
  11 + */
  12 +class Third extends Backend
  13 +{
  14 +
  15 + /**
  16 + * Third模型对象
  17 + * @var \app\admin\model\Third
  18 + */
  19 + protected $model = null;
  20 +
  21 + public function _initialize()
  22 + {
  23 + parent::_initialize();
  24 + $this->model = new \app\admin\model\Third;
  25 + }
  26 +
  27 + /**
  28 + * 查看
  29 + */
  30 + public function index()
  31 + {
  32 + $this->relationSearch = true;
  33 + //设置过滤方法
  34 + $this->request->filter(['strip_tags']);
  35 + if ($this->request->isAjax()) {
  36 + //如果发送的来源是Selectpage,则转发到Selectpage
  37 + if ($this->request->request('keyField')) {
  38 + return $this->selectpage();
  39 + }
  40 + list($where, $sort, $order, $offset, $limit) = $this->buildparams();
  41 + $total = $this->model
  42 + ->with(['user'])
  43 + ->where($where)
  44 + ->order($sort, $order)
  45 + ->count();
  46 +
  47 + $list = $this->model
  48 + ->with(['user'])
  49 + ->where($where)
  50 + ->order($sort, $order)
  51 + ->limit($offset, $limit)
  52 + ->select();
  53 + foreach ($list as $index => $item) {
  54 + if ($item->user) {
  55 + $item->user->visible(['nickname']);
  56 + }
  57 + }
  58 + $list = collection($list)->toArray();
  59 + $result = array("total" => $total, "rows" => $list);
  60 +
  61 + return json($result);
  62 + }
  63 + return $this->view->fetch();
  64 + }
  65 +
  66 +}
  1 +<?php
  2 +
  3 +namespace app\admin\controller\wechat;
  4 +
  5 +use app\common\controller\Backend;
  6 +use app\admin\model\WechatResponse;
  7 +
  8 +/**
  9 + * 微信自动回复管理
  10 + *
  11 + * @icon fa fa-circle-o
  12 + */
  13 +class Autoreply extends Backend
  14 +{
  15 +
  16 + protected $model = null;
  17 + protected $noNeedRight = ['check_text_unique'];
  18 +
  19 + public function _initialize()
  20 + {
  21 + parent::_initialize();
  22 + $this->model = model('WechatAutoreply');
  23 + }
  24 +
  25 + /**
  26 + * 编辑
  27 + */
  28 + public function edit($ids = null)
  29 + {
  30 + $row = $this->model->get(['id' => $ids]);
  31 + if (!$row) {
  32 + $this->error(__('No Results were found'));
  33 + }
  34 + if ($this->request->isPost()) {
  35 + $params = $this->request->post("row/a");
  36 + if ($params) {
  37 + $row->save($params);
  38 + $this->success();
  39 + }
  40 + $this->error();
  41 + }
  42 + $response = WechatResponse::get(['eventkey' => $row['eventkey']]);
  43 + $this->view->assign("response", $response);
  44 + $this->view->assign("row", $row);
  45 + return $this->view->fetch();
  46 + }
  47 +
  48 + /**
  49 + * 判断文本是否唯一
  50 + * @internal
  51 + */
  52 + public function check_text_unique()
  53 + {
  54 + $row = $this->request->post("row/a");
  55 + $except = $this->request->post("except");
  56 + $text = isset($row['text']) ? $row['text'] : '';
  57 + if ($this->model->where('text', $text)->where(function ($query) use ($except) {
  58 + if ($except) {
  59 + $query->where('text', '<>', $except);
  60 + }
  61 + })->count() == 0) {
  62 + $this->success();
  63 + } else {
  64 + $this->error(__('Text already exists'));
  65 + }
  66 + }
  67 +
  68 +}
  1 +<?php
  2 +
  3 +namespace app\admin\controller\wechat;
  4 +
  5 +use app\common\controller\Backend;
  6 +use think\Controller;
  7 +use think\Request;
  8 +
  9 +/**
  10 + * 微信配置管理
  11 + *
  12 + * @icon fa fa-circle-o
  13 + */
  14 +class Config extends Backend
  15 +{
  16 +
  17 + protected $model = null;
  18 +
  19 + public function _initialize()
  20 + {
  21 + parent::_initialize();
  22 + $this->model = model('WechatConfig');
  23 + }
  24 +
  25 + /**
  26 + * 添加
  27 + */
  28 + public function add()
  29 + {
  30 + if ($this->request->isPost()) {
  31 + $params = $this->request->post("row/a");
  32 + if ($params) {
  33 + foreach ($params as $k => &$v) {
  34 + $v = is_array($v) ? implode(',', $v) : $v;
  35 + }
  36 +
  37 + if ($params['mode'] == 'json') {
  38 + //JSON字段
  39 + $fieldarr = $valuearr = [];
  40 + $field = $this->request->post('field/a');
  41 + $value = $this->request->post('value/a');
  42 + foreach ($field as $k => $v) {
  43 + if ($v != '') {
  44 + $fieldarr[] = $field[$k];
  45 + $valuearr[] = $value[$k];
  46 + }
  47 + }
  48 + $params['value'] = json_encode(array_combine($fieldarr, $valuearr), JSON_UNESCAPED_UNICODE);
  49 + }
  50 + unset($params['mode']);
  51 + try {
  52 + //是否采用模型验证
  53 + if ($this->modelValidate) {
  54 + $name = basename(str_replace('\\', '/', get_class($this->model)));
  55 + $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : true) : $this->modelValidate;
  56 + $this->model->validate($validate);
  57 + }
  58 + $result = $this->model->save($params);
  59 + if ($result !== false) {
  60 + $this->success();
  61 + } else {
  62 + $this->error($this->model->getError());
  63 + }
  64 + } catch (\think\exception\PDOException $e) {
  65 + $this->error($e->getMessage());
  66 + }
  67 + }
  68 + $this->error(__('Parameter %s can not be empty', ''));
  69 + }
  70 + return $this->view->fetch();
  71 + }
  72 +
  73 + /**
  74 + * 编辑
  75 + */
  76 + public function edit($ids = null)
  77 + {
  78 + $row = $this->model->get($ids);
  79 + if (!$row) {
  80 + $this->error(__('No Results were found'));
  81 + }
  82 + if ($this->request->isPost()) {
  83 + $params = $this->request->post("row/a");
  84 + if ($params) {
  85 + foreach ($params as $k => &$v) {
  86 + $v = is_array($v) ? implode(',', $v) : $v;
  87 + }
  88 +
  89 + if ($params['mode'] == 'json') {
  90 + //JSON字段
  91 + $fieldarr = $valuearr = [];
  92 + $field = $this->request->post('field/a');
  93 + $value = $this->request->post('value/a');
  94 + foreach ($field as $k => $v) {
  95 + if ($v != '') {
  96 + $fieldarr[] = $field[$k];
  97 + $valuearr[] = $value[$k];
  98 + }
  99 + }
  100 + $params['value'] = json_encode(array_combine($fieldarr, $valuearr), JSON_UNESCAPED_UNICODE);
  101 + }
  102 + unset($params['mode']);
  103 + try {
  104 + //是否采用模型验证
  105 + if ($this->modelValidate) {
  106 + $name = basename(str_replace('\\', '/', get_class($this->model)));
  107 + $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : true) : $this->modelValidate;
  108 + $row->validate($validate);
  109 + }
  110 + $result = $row->save($params);
  111 + if ($result !== false) {
  112 + $this->success();
  113 + } else {
  114 + $this->error($row->getError());
  115 + }
  116 + } catch (\think\exception\PDOException $e) {
  117 + $this->error($e->getMessage());
  118 + }
  119 + }
  120 + $this->error(__('Parameter %s can not be empty', ''));
  121 + }
  122 + $this->view->assign("row", $row);
  123 + $this->view->assign("value", (array)json_decode($row->value, true));
  124 + return $this->view->fetch();
  125 + }
  126 +
  127 +}
  1 +<?php
  2 +
  3 +namespace app\admin\controller\wechat;
  4 +
  5 +use addons\wechat\library\Config;
  6 +use app\common\controller\Backend;
  7 +use app\admin\model\WechatResponse;
  8 +use EasyWeChat\Factory;
  9 +use think\Exception;
  10 +
  11 +/**
  12 + * 菜单管理
  13 + *
  14 + * @icon fa fa-list-alt
  15 + */
  16 +class Menu extends Backend
  17 +{
  18 + protected $wechatcfg = null;
  19 +
  20 + public function _initialize()
  21 + {
  22 + parent::_initialize();
  23 + $this->wechatcfg = \app\admin\model\WechatConfig::get(['name' => 'menu']);
  24 + }
  25 +
  26 + /**
  27 + * 查看
  28 + */
  29 + public function index()
  30 + {
  31 + $responselist = array();
  32 + $all = WechatResponse::all();
  33 + foreach ($all as $k => $v) {
  34 + $responselist[$v['eventkey']] = $v['title'];
  35 + }
  36 + $this->view->assign('responselist', $responselist);
  37 + $this->view->assign('menu', (array)json_decode($this->wechatcfg->value, true));
  38 + return $this->view->fetch();
  39 + }
  40 +
  41 + /**
  42 + * 修改
  43 + */
  44 + public function edit($ids = null)
  45 + {
  46 + $menu = $this->request->post("menu");
  47 + $menu = (array)json_decode($menu, true);
  48 + foreach ($menu as $index => &$item) {
  49 + if (isset($item['sub_button'])) {
  50 + foreach ($item['sub_button'] as &$subitem) {
  51 + if ($subitem['type'] == 'view') {
  52 + $allowFields = ['type', 'name', 'url'];
  53 + $subitem = ['type' => $subitem['type'], 'name' => $subitem['name'], 'url' => $subitem['url']];
  54 + } else {
  55 + if ($subitem['type'] == 'miniprogram') {
  56 + $allowFields = ['type', 'name', 'url', 'appid', 'pagepath'];
  57 + $subitem = ['type' => $subitem['type'], 'name' => $subitem['name'], 'url' => $subitem['url'], 'appid' => $subitem['appid'], 'pagepath' => $subitem['pagepath']];
  58 + } else {
  59 + $allowFields = ['type', 'name', 'key'];
  60 + $subitem = ['type' => $subitem['type'], 'name' => $subitem['name'], 'key' => $subitem['key']];
  61 + }
  62 + }
  63 + $subitem = array_intersect_key($subitem, array_flip($allowFields));
  64 + }
  65 + } else {
  66 + if ($item['type'] == 'view') {
  67 + $allowFields = ['type', 'name', 'url'];
  68 + } else {
  69 + if ($item['type'] == 'miniprogram') {
  70 + $allowFields = ['type', 'name', 'url', 'appid', 'pagepath'];
  71 + } else {
  72 + $allowFields = ['type', 'name', 'key'];
  73 + }
  74 + }
  75 + $item = array_intersect_key($item, array_flip($allowFields));
  76 + }
  77 + }
  78 + $this->wechatcfg->value = json_encode($menu, JSON_UNESCAPED_UNICODE);
  79 + $this->wechatcfg->save();
  80 + $this->success();
  81 + }
  82 +
  83 + /**
  84 + * 加载远程菜单
  85 + */
  86 + public function remote()
  87 + {
  88 + $app = Factory::officialAccount(Config::load());
  89 +
  90 + try {
  91 + $list = $app->menu->list();
  92 + } catch (\Exception $e) {
  93 + $this->error($e->getMessage());
  94 + }
  95 + if (isset($list['menu']['button'])) {
  96 + $buttons = $list['menu']['button'];
  97 + foreach ($buttons as $index => &$item) {
  98 + if (isset($item['sub_button'])) {
  99 + if ($item['sub_button']) {
  100 + foreach ($item['sub_button'] as $key => &$value) {
  101 + if (!isset($value['sub_button']) || !$value['sub_button']) {
  102 + unset($value['sub_button']);
  103 + }
  104 + }
  105 + } else {
  106 + unset($item['sub_button']);
  107 + }
  108 + }
  109 + }
  110 + $this->wechatcfg->value = json_encode($buttons, JSON_UNESCAPED_UNICODE);
  111 + $this->wechatcfg->save();
  112 + $this->success();
  113 + } else {
  114 + $this->error("加载菜单失败");
  115 + }
  116 + }
  117 +
  118 + /**
  119 + * 同步到服务器
  120 + */
  121 + public function sync($ids = null)
  122 + {
  123 + $app = Factory::officialAccount(Config::load());
  124 + try {
  125 + $hasError = false;
  126 + $menu = json_decode($this->wechatcfg->value, true);
  127 + foreach ($menu as $k => $v) {
  128 + if (isset($v['sub_button'])) {
  129 + foreach ($v['sub_button'] as $m => $n) {
  130 + if ($n['type'] == 'click' && isset($n['key']) && !$n['key']) {
  131 + $hasError = true;
  132 + break 2;
  133 + }
  134 + }
  135 + } else {
  136 + if ($v['type'] == 'click' && isset($v['key']) && !$v['key']) {
  137 + $hasError = true;
  138 + break;
  139 + }
  140 + }
  141 + }
  142 + if (!$hasError) {
  143 + try {
  144 + $ret = $app->menu->create($menu);
  145 + } catch (\Exception $e) {
  146 + $this->error($e->getMessage());
  147 + }
  148 + if ($ret['errcode'] == 0) {
  149 + $this->success();
  150 + } else {
  151 + $this->error($ret['errmsg']);
  152 + }
  153 + } else {
  154 + $this->error(__('Invalid parameters'));
  155 + }
  156 + } catch (Exception $e) {
  157 + $this->error($e->getMessage());
  158 + }
  159 + }
  160 +}
  1 +<?php
  2 +
  3 +namespace app\admin\controller\wechat;
  4 +
  5 +use app\common\controller\Backend;
  6 +use addons\wechat\library\Wechat;
  7 +
  8 +/**
  9 + * 资源管理
  10 + *
  11 + * @icon fa fa-list-alt
  12 + */
  13 +class Response extends Backend
  14 +{
  15 +
  16 + protected $model = null;
  17 + protected $searchFields = 'id,title';
  18 +
  19 + public function _initialize()
  20 + {
  21 + parent::_initialize();
  22 + $this->model = model('WechatResponse');
  23 + }
  24 +
  25 + /**
  26 + * 选择素材
  27 + */
  28 + public function select()
  29 + {
  30 + return $this->view->fetch();
  31 + }
  32 +
  33 + /**
  34 + * 添加
  35 + */
  36 + public function add()
  37 + {
  38 + if ($this->request->isPost()) {
  39 + $params = $this->request->post("row/a");
  40 + $params['eventkey'] = isset($params['eventkey']) && $params['eventkey'] ? $params['eventkey'] : uniqid();
  41 + $params['content'] = json_encode($params['content']);
  42 + $params['createtime'] = time();
  43 + if ($params) {
  44 + $this->model->save($params);
  45 + $this->success();
  46 + $this->content = $params;
  47 + }
  48 + $this->error();
  49 + }
  50 + $appConfig = Wechat::appConfig();
  51 + $this->view->applist = $appConfig;
  52 + return $this->view->fetch();
  53 + }
  54 +
  55 + /**
  56 + * 编辑
  57 + */
  58 + public function edit($ids = NULL)
  59 + {
  60 + $row = $this->model->get($ids);
  61 + if (!$row)
  62 + $this->error(__('No Results were found'));
  63 + if ($this->request->isPost()) {
  64 + $params = $this->request->post("row/a");
  65 + $params['eventkey'] = isset($params['eventkey']) && $params['eventkey'] ? $params['eventkey'] : uniqid();
  66 + $params['content'] = json_encode($params['content']);
  67 + if ($params) {
  68 + $row->save($params);
  69 + $this->success();
  70 + }
  71 + $this->error();
  72 + }
  73 + $this->view->assign("row", $row);
  74 + $appConfig = Wechat::appConfig();
  75 + $this->view->applist = $appConfig;
  76 + return $this->view->fetch();
  77 + }
  78 +
  79 +}
  1 +<?php
  2 +
  3 +return [
  4 + 'Id' => 'ID',
  5 + 'Type' => '类型',
  6 + 'Params' => '参数',
  7 + 'Command' => '命令',
  8 + 'Content' => '返回结果',
  9 + 'Executetime' => '执行时间',
  10 + 'Createtime' => '创建时间',
  11 + 'Updatetime' => '更新时间',
  12 + 'Execute again' => '再次执行',
  13 + 'Successed' => '成功',
  14 + 'Failured' => '失败',
  15 + 'Status' => '状态'
  16 +];
  1 +<?php
  2 +
  3 +return [
  4 + 'Id' => 'ID',
  5 + 'mid' => '自建表ID',
  6 + 'm_name' => '自建表名称',
  7 + 'm_table' => '自建表表名',
  8 + 'm_desc' => '自建表描述',
  9 + 'Admin_id' => '管理员ID',
  10 + 'Category_id' => '分类ID(单选)',
  11 + 'Flag' => '标志(多选)',
  12 + 'Flag hot' => '热门',
  13 + 'Flag index' => '首页',
  14 + 'Flag recommend' => '推荐',
  15 + 'Title' => '标题',
  16 + 'Content' => '内容',
  17 + 'Image' => '图片',
  18 + 'Keywords' => '关键字',
  19 + 'Description' => '描述',
  20 + 'Views' => '点击',
  21 + 'Refreshtime' => '刷新时间(int)',
  22 + 'Createtime' => '创建时间',
  23 + 'Updatetime' => '更新时间',
  24 + 'Weigh' => '权重',
  25 + 'Status' => '状态',
  26 + 'State' => '状态值',
  27 + 'State 0' => '未审核',
  28 + 'State 1' => '正常',
  29 + 'State 2' => '推荐'
  30 +];
  1 +<?php
  2 +
  3 +return [
  4 + 'Id' => 'ID',
  5 + 'User_id' => '会员ID',
  6 + 'Platform' => '第三方应用',
  7 + 'Unionid' => '第三方UnionID',
  8 + 'Openid' => '第三方OpenID',
  9 + 'Openname' => '第三方会员昵称',
  10 + 'Access_token' => 'AccessToken',
  11 + 'Expires_in' => '有效期',
  12 + 'Createtime' => '创建时间',
  13 + 'Updatetime' => '更新时间',
  14 + 'Logintime' => '登录时间',
  15 + 'Expiretime' => '过期时间'
  16 +];
  1 +<?php
  2 +
  3 +return [
  4 + 'Text' => '文本',
  5 + 'Event key' => '响应标识',
  6 + 'Remark' => '备注',
  7 + 'Text already exists' => '文本已经存在',
  8 +];