diff --git a/addons/address/.addonrc b/addons/address/.addonrc
new file mode 100644
index 0000000..f0f934c
--- /dev/null
+++ b/addons/address/.addonrc
@@ -0,0 +1 @@
+{"files":["public\\assets\\addons\\address\\js\\gcoord.min.js","public\\assets\\addons\\address\\js\\jquery.autocomplete.js"],"license":"regular","licenseto":"34485","licensekey":"Fr1gIoX2PBbGmMnp GFErXGAvLGllzXV\/ASjNRQ==","domains":["localhost"],"licensecodes":[],"validations":["757319b447175b6ca1882635b132a594"]}
\ No newline at end of file
diff --git a/addons/address/Address.php b/addons/address/Address.php
new file mode 100644
index 0000000..4bc36ea
--- /dev/null
+++ b/addons/address/Address.php
@@ -0,0 +1,32 @@
+
+ */
+class Address extends Addons
+{
+
+ /**
+ * 插件安装方法
+ * @return bool
+ */
+ public function install()
+ {
+ return true;
+ }
+
+ /**
+ * 插件卸载方法
+ * @return bool
+ */
+ public function uninstall()
+ {
+ return true;
+ }
+
+}
diff --git a/addons/address/bootstrap.js b/addons/address/bootstrap.js
new file mode 100644
index 0000000..655162d
--- /dev/null
+++ b/addons/address/bootstrap.js
@@ -0,0 +1,34 @@
+require([], function () {
+ //绑定data-toggle=addresspicker属性点击事件
+
+ $(document).on('click', "[data-toggle='addresspicker']", function () {
+ var that = this;
+ var callback = $(that).data('callback');
+ var input_id = $(that).data("input-id") ? $(that).data("input-id") : "";
+ var lat_id = $(that).data("lat-id") ? $(that).data("lat-id") : "";
+ var lng_id = $(that).data("lng-id") ? $(that).data("lng-id") : "";
+ var zoom_id = $(that).data("zoom-id") ? $(that).data("zoom-id") : "";
+ var lat = lat_id ? $("#" + lat_id).val() : '';
+ var lng = lng_id ? $("#" + lng_id).val() : '';
+ var zoom = zoom_id ? $("#" + zoom_id).val() : '';
+ var url = "/addons/address/index/select";
+ url += (lat && lng) ? '?lat=' + lat + '&lng=' + lng + (input_id ? "&address=" + $("#" + input_id).val() : "") + (zoom ? "&zoom=" + zoom : "") : '';
+ Fast.api.open(url, '位置选择', {
+ callback: function (res) {
+ input_id && $("#" + input_id).val(res.address).trigger("change");
+ lat_id && $("#" + lat_id).val(res.lat).trigger("change");
+ lng_id && $("#" + lng_id).val(res.lng).trigger("change");
+ zoom_id && $("#" + zoom_id).val(res.zoom).trigger("change");
+
+ try {
+ //执行回调函数
+ if (typeof callback === 'function') {
+ callback.call(that, res);
+ }
+ } catch (e) {
+
+ }
+ }
+ });
+ });
+});
diff --git a/addons/address/config.php b/addons/address/config.php
new file mode 100644
index 0000000..f6715fd
--- /dev/null
+++ b/addons/address/config.php
@@ -0,0 +1,132 @@
+ 'maptype',
+ 'title' => '默认地图类型',
+ 'type' => 'radio',
+ 'content' => [
+ 'baidu' => '百度地图',
+ 'amap' => '高德地图',
+ 'tencent' => '腾讯地图',
+ ],
+ 'value' => 'amap',
+ 'rule' => 'required',
+ 'msg' => '',
+ 'tip' => '',
+ 'ok' => '',
+ 'extend' => '',
+ ],
+ [
+ 'name' => 'zoom',
+ 'title' => '默认缩放级别',
+ 'type' => 'string',
+ 'content' => [],
+ 'value' => '11',
+ 'rule' => 'required',
+ 'msg' => '',
+ 'tip' => '',
+ 'ok' => '',
+ 'extend' => '',
+ ],
+ [
+ 'name' => 'lat',
+ 'title' => '默认Lat',
+ 'type' => 'string',
+ 'content' => [],
+ 'value' => '23.002569',
+ 'rule' => 'required',
+ 'msg' => '',
+ 'tip' => '',
+ 'ok' => '',
+ 'extend' => '',
+ ],
+ [
+ 'name' => 'lng',
+ 'title' => '默认Lng',
+ 'type' => 'string',
+ 'content' => [],
+ 'value' => '113.752215',
+ 'rule' => 'required',
+ 'msg' => '',
+ 'tip' => '',
+ 'ok' => '',
+ 'extend' => '',
+ ],
+ [
+ 'name' => 'baidukey',
+ 'title' => '百度地图KEY',
+ 'type' => 'string',
+ 'content' => [],
+ 'value' => '',
+ 'rule' => '',
+ 'msg' => '',
+ 'tip' => '',
+ 'ok' => '',
+ 'extend' => '',
+ ],
+ [
+ 'name' => 'amapkey',
+ 'title' => '高德地图KEY',
+ 'type' => 'string',
+ 'content' => [],
+ 'value' => '78c9a922ba2d29f005eaa89e3f1b00bb',
+ 'rule' => '',
+ 'msg' => '',
+ 'tip' => '',
+ 'ok' => '',
+ 'extend' => '',
+ ],
+ [
+ 'name' => 'amapsecurityjscode',
+ 'title' => '高德地图安全密钥',
+ 'type' => 'string',
+ 'content' => [],
+ 'value' => '',
+ 'rule' => '',
+ 'msg' => '',
+ 'tip' => '',
+ 'ok' => '',
+ 'extend' => '',
+ ],
+ [
+ 'name' => 'tencentkey',
+ 'title' => '腾讯地图KEY',
+ 'type' => 'string',
+ 'content' => [],
+ 'value' => '',
+ 'rule' => '',
+ 'msg' => '',
+ 'tip' => '',
+ 'ok' => '',
+ 'extend' => '',
+ ],
+ [
+ 'name' => 'coordtype',
+ 'title' => '坐标系类型',
+ 'type' => 'select',
+ 'content' => [
+ 'DEFAULT' => '默认(使用所选地图默认坐标系)',
+ 'GCJ02' => 'GCJ-02',
+ 'BD09' => 'BD-09',
+ ],
+ 'value' => 'DEFAULT',
+ 'rule' => 'required',
+ 'msg' => '',
+ 'tip' => '',
+ 'ok' => '',
+ 'extend' => '',
+ ],
+ [
+ 'name' => '__tips__',
+ 'title' => '温馨提示',
+ 'type' => '',
+ 'content' => [],
+ 'value' => '请先申请对应地图的Key,配置后再使用',
+ 'rule' => '',
+ 'msg' => '',
+ 'tip' => '',
+ 'ok' => '',
+ 'extend' => 'alert-danger-light',
+ ],
+];
diff --git a/addons/address/controller/Index.php b/addons/address/controller/Index.php
new file mode 100644
index 0000000..5cd31e3
--- /dev/null
+++ b/addons/address/controller/Index.php
@@ -0,0 +1,64 @@
+request->langset();
+ $lang = preg_match("/^([a-zA-Z\-_]{2,10})\$/i", $lang) ? $lang : 'zh-cn';
+
+ $site = Config::get("site");
+
+ // 配置信息
+ $config = [
+ 'site' => array_intersect_key($site, array_flip(['name', 'cdnurl', 'version', 'timezone', 'languages'])),
+ 'upload' => null,
+ 'modulename' => 'addons',
+ 'controllername' => 'index',
+ 'actionname' => 'index',
+ 'jsname' => 'addons/address',
+ 'moduleurl' => '',
+ 'language' => $lang
+ ];
+ $config = array_merge($config, Config::get("view_replace_str"));
+
+ // 配置信息后
+ Hook::listen("config_init", $config);
+ // 加载当前控制器语言包
+ $this->view->assign('site', $site);
+ $this->view->assign('config', $config);
+
+ return $this->view->fetch();
+ }
+
+ // 选择地址
+ public function select()
+ {
+ $config = get_addon_config('address');
+ $zoom = (int)$this->request->get('zoom', $config['zoom']);
+ $lng = (float)$this->request->get('lng');
+ $lat = (float)$this->request->get('lat');
+ $address = $this->request->get('address');
+ $lng = $lng ?: $config['lng'];
+ $lat = $lat ?: $config['lat'];
+ $this->view->assign('zoom', $zoom);
+ $this->view->assign('lng', $lng);
+ $this->view->assign('lat', $lat);
+ $this->view->assign('address', $address);
+ $maptype = $config['maptype'];
+ if (!isset($config[$maptype . 'key']) || !$config[$maptype . 'key']) {
+ $this->error("请在配置中配置对应类型地图的密钥");
+ }
+ return $this->view->fetch('index/' . $maptype);
+ }
+
+}
diff --git a/addons/address/info.ini b/addons/address/info.ini
new file mode 100644
index 0000000..b0bb8d1
--- /dev/null
+++ b/addons/address/info.ini
@@ -0,0 +1,10 @@
+name = address
+title = 地址位置选择插件
+intro = 地图位置选择插件,可返回地址和经纬度
+author = FastAdmin
+website = https://www.fastadmin.net
+version = 1.1.8
+state = 1
+url = /addons/address
+license = regular
+licenseto = 34485
diff --git a/addons/address/view/index/amap.html b/addons/address/view/index/amap.html
new file mode 100644
index 0000000..62972fc
--- /dev/null
+++ b/addons/address/view/index/amap.html
@@ -0,0 +1,258 @@
+
+
+
+
+ 地址选择器
+
+
+
+
+
+
+确定
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/address/view/index/baidu.html b/addons/address/view/index/baidu.html
new file mode 100644
index 0000000..86aa74b
--- /dev/null
+++ b/addons/address/view/index/baidu.html
@@ -0,0 +1,243 @@
+
+
+
+
+ 地址选择器
+
+
+
+
+
+
+确定
+
+
+
+
+
+
+
diff --git a/addons/address/view/index/index.html b/addons/address/view/index/index.html
new file mode 100644
index 0000000..07f9712
--- /dev/null
+++ b/addons/address/view/index/index.html
@@ -0,0 +1,132 @@
+
+
+
+
+ 地图位置(经纬度)选择插件
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ | 参数 |
+ 释义 |
+
+
+
+
+ | data-input-id |
+ 填充地址的文本框ID |
+
+
+ | data-lng-id |
+ 填充经度的文本框ID |
+
+
+ | data-lat-id |
+ 填充纬度的文本框ID |
+
+
+ | data-zoom-id |
+ 填充缩放的文本框ID |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/address/view/index/tencent.html b/addons/address/view/index/tencent.html
new file mode 100644
index 0000000..89df386
--- /dev/null
+++ b/addons/address/view/index/tencent.html
@@ -0,0 +1,291 @@
+
+
+
+
+ 地址选择器
+
+
+
+
+
+
+确定
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/shopro/controller/zy/Gym.php b/addons/shopro/controller/zy/Gym.php
new file mode 100644
index 0000000..c8fc870
--- /dev/null
+++ b/addons/shopro/controller/zy/Gym.php
@@ -0,0 +1,80 @@
+request->param();
+ $model = Stadium::where('status', 1);
+ if (isset($params['name'])) {
+ $model->where('name', 'like', '%' . $params['name'] . '%');
+ }
+ $res = $model->select();
+
+
+ $this->success('获取成功', $res);
+ }
+
+ public function add()
+ {
+ $result = false;
+ $params = $this->request->param();
+ Db::startTrans();
+ try {
+ $result = (new Stadium)->allowField(true)->save($params);
+ Db::commit();
+ } catch (ValidateException | PDOException | Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ if ($result === false) {
+ $this->error(__('No rows were inserted'));
+ }
+ $this->success();
+ }
+
+ public function update()
+ {
+ $result = false;
+ $params = $this->request->param();
+ $model = Stadium::get($params['id']);
+ if (empty($model)) {
+ $this->error(__('No rows were found'));
+ }
+ Db::startTrans();
+ try {
+ $result = $model->allowField(true)->save($params);
+ Db::commit();
+ } catch (ValidateException | PDOException | Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ if ($result === false) {
+ $this->error(__('No rows were inserted'));
+ }
+ $this->success();
+ }
+
+ public function view()
+ {
+ $model = Stadium::get($this->request->param('id'));
+ if (empty($model)) {
+ $this->error(__('No rows were found'));
+ }
+ $this->success($model);
+ }
+}
diff --git a/addons/shopro/controller/zy/Tags.php b/addons/shopro/controller/zy/Tags.php
new file mode 100644
index 0000000..02ed7d5
--- /dev/null
+++ b/addons/shopro/controller/zy/Tags.php
@@ -0,0 +1,32 @@
+request->param();
+ $model = new TagsModel();
+ if (isset($params['type'])) {
+ $model->where('type', $params['type']);
+ }
+ if (isset($params['group'])) {
+ $model->where('group', $params['group']);
+ }
+ $res = $model->select();
+ foreach ($res as &$value) {
+ $value['content_json'] = array_values(json_decode($value['content_json'] ?? '[]', true));
+ }
+
+ $this->success('获取成功', $res);
+ }
+}
diff --git a/addons/shopro/service/goods/GoodsService.php b/addons/shopro/service/goods/GoodsService.php
index 06793ac..14392e9 100644
--- a/addons/shopro/service/goods/GoodsService.php
+++ b/addons/shopro/service/goods/GoodsService.php
@@ -20,7 +20,7 @@ class GoodsService
protected $is_activity = false; // 是否处理活动
protected $show_score_shop = false; // 查询积分商城商品
- public function __construct(\Closure $format = null, \think\db\Query $query = null)
+ public function __construct(?\Closure $format = null, ?\think\db\Query $query = null)
{
$this->query = $query ?: new Goods();
$this->format = $format;
diff --git a/application/admin/controller/zy/Stadium.php b/application/admin/controller/zy/Stadium.php
new file mode 100644
index 0000000..ad8bffb
--- /dev/null
+++ b/application/admin/controller/zy/Stadium.php
@@ -0,0 +1,168 @@
+model = new \app\admin\model\zy\Stadium;
+ }
+
+
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+ /**
+ * 查看
+ */
+ public function index()
+ {
+ //当前是否为关联查询
+ $this->relationSearch = true;
+ //设置过滤方法
+ $this->request->filter(['strip_tags', 'trim']);
+ if ($this->request->isAjax()) {
+ //如果发送的来源是Selectpage,则转发到Selectpage
+ if ($this->request->request('keyField')) {
+ return $this->selectpage();
+ }
+ list($where, $sort, $order, $offset, $limit) = $this->buildparams();
+
+ $list = $this->model
+ ->with(['user'])
+ ->where($where)
+ ->order($sort, $order)
+ ->paginate($limit);
+
+ foreach ($list as $row) {
+
+ $row->getRelation('user')->visible(['id', 'username', 'nickname', 'avatar', 'gender']);
+ }
+
+ $result = array("total" => $list->total(), "rows" => $list->items());
+
+ return json($result);
+ }
+ return $this->view->fetch();
+ }
+
+
+ /**
+ * 添加
+ *
+ * @return string
+ * @throws \think\Exception
+ */
+ public function add()
+ {
+ if (false === $this->request->isPost()) {
+ return $this->view->fetch();
+ }
+ $params = $this->request->post('row/a');
+ if (empty($params)) {
+ $this->error(__('Parameter %s can not be empty', ''));
+ }
+ $params = $this->preExcludeFields($params);
+ $params['position'] = sprintf("POINT(%s %s)", $params['lng'], $params['lat']);
+ if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
+ $params[$this->dataLimitField] = $this->auth->id;
+ }
+ $result = false;
+ Db::startTrans();
+ try {
+ //是否采用模型验证
+ if ($this->modelValidate) {
+ $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
+ $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate;
+ $this->model->validateFailException()->validate($validate);
+ }
+ $result = $this->model->allowField(true)->save($params);
+ Db::commit();
+ } catch (ValidateException | PDOException | Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ if ($result === false) {
+ $this->error(__('No rows were inserted'));
+ }
+ $this->success();
+ }
+
+ /**
+ * 编辑
+ *
+ * @param $ids
+ * @return string
+ * @throws DbException
+ * @throws \think\Exception
+ */
+ public function edit($ids = null)
+ {
+ $row = $this->model->get($ids);
+ if (!$row) {
+ $this->error(__('No Results were found'));
+ }
+ $adminIds = $this->getDataLimitAdminIds();
+ if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
+ $this->error(__('You have no permission'));
+ }
+ if (false === $this->request->isPost()) {
+ $point = empty($row['position']) ? [0, 0] : explode(' ', substr($row['position'], 6, -1));
+ $row['lng'] = $point[0];
+ $row['lat'] = $point[1];
+ $this->view->assign('row', $row);
+ return $this->view->fetch();
+ }
+ $params = $this->request->post('row/a');
+ if (empty($params)) {
+ $this->error(__('Parameter %s can not be empty', ''));
+ }
+ $params = $this->preExcludeFields($params);
+ $params['position'] = sprintf("POINT(%s %s)", $params['lng'], $params['lat']);
+ $result = false;
+ Db::startTrans();
+ try {
+ //是否采用模型验证
+ if ($this->modelValidate) {
+ $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
+ $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.edit' : $name) : $this->modelValidate;
+ $row->validateFailException()->validate($validate);
+ }
+ $result = $row->allowField(true)->save($params);
+ Db::commit();
+ } catch (ValidateException | PDOException | Exception $e) {
+ Db::rollback();
+ $this->error($e->getMessage());
+ }
+ if (false === $result) {
+ $this->error(__('No rows were updated'));
+ }
+ $this->success();
+ }
+}
diff --git a/application/admin/controller/zy/Tags.php b/application/admin/controller/zy/Tags.php
new file mode 100644
index 0000000..e2caff6
--- /dev/null
+++ b/application/admin/controller/zy/Tags.php
@@ -0,0 +1,37 @@
+model = new \app\admin\model\zy\Tags;
+
+ }
+
+
+
+ /**
+ * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
+ * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
+ * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
+ */
+
+
+}
diff --git a/application/admin/lang/zh-cn/zy/stadium.php b/application/admin/lang/zh-cn/zy/stadium.php
new file mode 100644
index 0000000..fa93349
--- /dev/null
+++ b/application/admin/lang/zh-cn/zy/stadium.php
@@ -0,0 +1,25 @@
+ '球馆名称',
+ 'Sub_name' => '简称',
+ 'Position' => '位置',
+ 'Address' => '地址',
+ 'City' => '城市',
+ 'Contact' => '联系方式',
+ 'Blurb' => '简介',
+ 'Imgs' => '图片',
+ 'Admin_ids' => '管理员',
+ 'Tags' => '标签',
+ 'Status' => '状态',
+ 'Create_time' => '创建时间',
+ 'Update_time' => '修改时间',
+ 'User.id' => 'ID',
+ 'User.username' => '用户名',
+ 'User.nickname' => '昵称',
+ 'User.avatar' => '头像',
+ 'User.gender' => '性别',
+
+ 'Status0' => '禁用',
+ 'Status1' => '正常',
+];
diff --git a/application/admin/lang/zh-cn/zy/tags.php b/application/admin/lang/zh-cn/zy/tags.php
new file mode 100644
index 0000000..543219e
--- /dev/null
+++ b/application/admin/lang/zh-cn/zy/tags.php
@@ -0,0 +1,21 @@
+ '标签类型',
+ 'Group' => '标签分组',
+ 'Content_json' => '标签内容',
+ 'Choose' => '选择方式',
+ 'Create_time' => '创建时间',
+ 'Update_time' => '修改时间',
+
+ 'Single' => '仅单选',
+ 'Multiple' => '可多选',
+
+ 'General' => '通用标签',
+ 'Ability' => '能力标签',
+ 'Role' => '角色标签',
+
+ 'Gym' => '球馆标签',
+ 'Club' => '俱乐部标签',
+ 'User' => '用户标签',
+];
diff --git a/application/admin/model/zy/Stadium.php b/application/admin/model/zy/Stadium.php
new file mode 100644
index 0000000..264421a
--- /dev/null
+++ b/application/admin/model/zy/Stadium.php
@@ -0,0 +1,44 @@
+belongsTo('app\admin\model\User', 'admin_ids', 'id', [], 'LEFT')->setEagerlyType(0);
+ }
+}
diff --git a/application/admin/model/zy/Tags.php b/application/admin/model/zy/Tags.php
new file mode 100644
index 0000000..837ef07
--- /dev/null
+++ b/application/admin/model/zy/Tags.php
@@ -0,0 +1,40 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/validate/zy/Tags.php b/application/admin/validate/zy/Tags.php
new file mode 100644
index 0000000..919816d
--- /dev/null
+++ b/application/admin/validate/zy/Tags.php
@@ -0,0 +1,27 @@
+ [],
+ 'edit' => [],
+ ];
+
+}
diff --git a/application/admin/view/zy/stadium/add.html b/application/admin/view/zy/stadium/add.html
new file mode 100644
index 0000000..7564ca1
--- /dev/null
+++ b/application/admin/view/zy/stadium/add.html
@@ -0,0 +1,96 @@
+
\ No newline at end of file
diff --git a/application/admin/view/zy/stadium/edit.html b/application/admin/view/zy/stadium/edit.html
new file mode 100644
index 0000000..0ddb151
--- /dev/null
+++ b/application/admin/view/zy/stadium/edit.html
@@ -0,0 +1,106 @@
+
\ No newline at end of file
diff --git a/application/admin/view/zy/stadium/index.html b/application/admin/view/zy/stadium/index.html
new file mode 100644
index 0000000..f9c7d4b
--- /dev/null
+++ b/application/admin/view/zy/stadium/index.html
@@ -0,0 +1,29 @@
+
+ {:build_heading()}
+
+
+
diff --git a/application/admin/view/zy/tags/add.html b/application/admin/view/zy/tags/add.html
new file mode 100644
index 0000000..2668073
--- /dev/null
+++ b/application/admin/view/zy/tags/add.html
@@ -0,0 +1,46 @@
+
diff --git a/application/admin/view/zy/tags/edit.html b/application/admin/view/zy/tags/edit.html
new file mode 100644
index 0000000..a6197cd
--- /dev/null
+++ b/application/admin/view/zy/tags/edit.html
@@ -0,0 +1,43 @@
+
diff --git a/application/admin/view/zy/tags/index.html b/application/admin/view/zy/tags/index.html
new file mode 100644
index 0000000..c15f50c
--- /dev/null
+++ b/application/admin/view/zy/tags/index.html
@@ -0,0 +1,29 @@
+
+ {:build_heading()}
+
+
+
diff --git a/public/assets/addons/address/js/gcoord.min.js b/public/assets/addons/address/js/gcoord.min.js
new file mode 100644
index 0000000..8bf62df
--- /dev/null
+++ b/public/assets/addons/address/js/gcoord.min.js
@@ -0,0 +1,6 @@
+/**
+ * @preserve
+ * gcoord 1.0.6, geographic coordinate library
+ * Copyright (c) 2024 Jiulong Hu
+ */
+var gcoord=function(){"use strict";var r=function(){return r=Object.assign||function(r){for(var t,e=1,n=arguments.length;e=72.004&&r<=137.8347&&t>=.8293&&t<=55.8271}function f(r,c){var f,l,s,h=(s=300+(f=r-105)+2*(l=c-35)+.1*f*f+.1*f*l+.1*n(a(f)),s+=2*(20*t(6*f*o)+20*t(2*f*o))/3,(s+=2*(20*t(f*o)+40*t(f/3*o))/3)+2*(150*t(f/12*o)+300*t(f/30*o))/3),g=function(r,e){var i=2*r-100+3*e+.2*e*e+.1*r*e+.2*n(a(r));return i+=2*(20*t(6*r*o)+20*t(2*r*o))/3,i+=2*(20*t(e*o)+40*t(e/3*o))/3,i+2*(160*t(e/12*o)+320*t(e*o/30))/3}(r-105,c-35),M=c/180*o,v=t(M),p=n(v=1-u*v*v);return[h=180*h/(i/p*e(M)*o),g=180*g/(i*(1-u)/(v*p)*o)]}function l(r){var t=r[0],e=r[1];if(!c(t,e))return[t,e];var n=f(t,e);return[t+n[0],e+n[1]]}function s(r){var t=r[0],e=r[1];if(!c(t,e))return[t,e];for(var n=[t,e],o=n[0],i=n[1],u=l([o,i]),f=u[0]-t,s=u[1]-e;a(f)>1e-6||a(s)>1e-6;)f=(u=l([o-=f,i-=s]))[0]-t,s=u[1]-e;return[o,i]}var h=Math.sin,g=Math.cos,M=Math.atan2,v=Math.sqrt,p=3e3*Math.PI/180;function G(r){var t=r[0]-.0065,e=r[1]-.006,n=v(t*t+e*e)-2e-5*h(e*p),a=M(e,t)-3e-6*g(t*p);return[n*g(a),n*h(a)]}function d(r){var t=r[0],e=r[1],n=v(t*t+e*e)+2e-5*h(e*p),a=M(e,t)+3e-6*g(t*p);return[n*g(a)+.0065,n*h(a)+.006]}var S=180/Math.PI,y=Math.PI/180,P=6378137,b=20037508.342789244;function B(r){return[r[0]*S/P,(.5*Math.PI-2*Math.atan(Math.exp(-r[1]/P)))*S]}function C(r){var t=Math.abs(r[0])<=180?r[0]:r[0]-360*(r[0]<0?-1:1),e=[P*t*y,P*Math.log(Math.tan(.25*Math.PI+.5*r[1]*y))];return e[0]>b&&(e[0]=b),e[0]<-b&&(e[0]=-b),e[1]>b&&(e[1]=b),e[1]<-b&&(e[1]=-b),e}var D,E,m,w,I,W,k=Math.abs,J=[12890594.86,8362377.87,5591021,3481989.83,1678043.12,0],x=[75,60,45,30,15,0],L=[[1.410526172116255e-8,898305509648872e-20,-1.9939833816331,200.9824383106796,-187.2403703815547,91.6087516669843,-23.38765649603339,2.57121317296198,-.03801003308653,17337981.2],[-7.435856389565537e-9,8983055097726239e-21,-.78625201886289,96.32687599759846,-1.85204757529826,-59.36935905485877,47.40033549296737,-16.50741931063887,2.28786674699375,10260144.86],[-3.030883460898826e-8,898305509983578e-20,.30071316287616,59.74293618442277,7.357984074871,-25.38371002664745,13.45380521110908,-3.29883767235584,.32710905363475,6856817.37],[-1.981981304930552e-8,8983055099779535e-21,.03278182852591,40.31678527705744,.65659298677277,-4.44255534477492,.85341911805263,.12923347998204,-.04625736007561,4482777.06],[3.09191371068437e-9,8983055096812155e-21,6995724062e-14,23.10934304144901,-.00023663490511,-.6321817810242,-.00663494467273,.03430082397953,-.00466043876332,2555164.4],[2.890871144776878e-9,8983055095805407e-21,-3.068298e-8,7.47137025468032,-353937994e-14,-.02145144861037,-1234426596e-14,.00010322952773,-323890364e-14,826088.5]],j=[[-.0015702102444,111320.7020616939,0x60e374c3105a3,-0x24bb4115e2e164,0x5cc55543bb0ae8,-0x7ce070193f3784,0x5e7ca61ddf8150,-0x261a578d8b24d0,0x665d60f3742ca,82.5],[.0008277824516172526,111320.7020463578,647795574.6671607,-4082003173.641316,10774905663.51142,-15171875531.51559,12053065338.62167,-5124939663.577472,913311935.9512032,67.5],[.00337398766765,111320.7020202162,4481351.045890365,-23393751.19931662,79682215.47186455,-115964993.2797253,97236711.15602145,-43661946.33752821,8477230.501135234,52.5],[.00220636496208,111320.7020209128,51751.86112841131,3796837.749470245,992013.7397791013,-1221952.21711287,1340652.697009075,-620943.6990984312,144416.9293806241,37.5],[-.0003441963504368392,111320.7020576856,278.2353980772752,2485758.690035394,6070.750963243378,54821.18345352118,9540.606633304236,-2710.55326746645,1405.483844121726,22.5],[-.0003218135878613132,111320.7020701615,.00369383431289,823725.6402795718,.46104986909093,2351.343141331292,1.58060784298199,8.77738589078284,.37238884252424,7.45]];function q(r,t,e){var n=k(t)/e[9],a=e[0]+e[1]*k(r),o=e[2]+e[3]*n+e[4]*Math.pow(n,2)+e[5]*Math.pow(n,3)+e[6]*Math.pow(n,4)+e[7]*Math.pow(n,5)+e[8]*Math.pow(n,6);return[a*=r<0?-1:1,o*=t<0?-1:1]}function N(r){for(var t=r[0],e=r[1],n=[],a=0;ax[a]){n=j[a];break}return q(t,e,n)}function O(r){for(var t=r[0],e=r[1],n=[],a=0;a=J[a]){n=L[a];break}return q(t,e,n)}function T(r,t){if(!r)throw new Error(t)}function A(r){return!!r&&"[object Array]"===Object.prototype.toString.call(r)}function F(r){return!isNaN(Number(r))&&null!==r&&!A(r)}function R(){for(var r=[],t=0;t=2,"Invalid input coordinate: ".concat(r)),T(F(r[0])&&F(r[1]),"Invalid input coordinate: ".concat(r)),r=r.map(Number),i=!0);var u=a;return i?u(r):(U(r,(function(r){var t;t=u(r),r[0]=t[0],r[1]=t[1]})),r)}});return H}();
\ No newline at end of file
diff --git a/public/assets/addons/address/js/jquery.autocomplete.js b/public/assets/addons/address/js/jquery.autocomplete.js
new file mode 100644
index 0000000..78c47cf
--- /dev/null
+++ b/public/assets/addons/address/js/jquery.autocomplete.js
@@ -0,0 +1,215 @@
+/*
+ jQuery autoComplete v1.0.7
+ Copyright (c) 2014 Simon Steinberger / Pixabay
+ GitHub: https://github.com/Pixabay/jQuery-autoComplete
+ License: http://www.opensource.org/licenses/mit-license.php
+*/
+
+(function ($) {
+ $.fn.autoComplete = function (options) {
+ var o = $.extend({}, $.fn.autoComplete.defaults, options);
+
+ // public methods
+ if (typeof options == 'string') {
+ this.each(function () {
+ var that = $(this);
+ if (options == 'destroy') {
+ $(window).off('resize.autocomplete', that.updateSC);
+ that.off('blur.autocomplete focus.autocomplete keydown.autocomplete keyup.autocomplete');
+ if (that.data('autocomplete'))
+ that.attr('autocomplete', that.data('autocomplete'));
+ else
+ that.removeAttr('autocomplete');
+ $(that.data('sc')).remove();
+ that.removeData('sc').removeData('autocomplete');
+ }
+ });
+ return this;
+ }
+
+ return this.each(function () {
+ var that = $(this);
+ // sc = 'suggestions container'
+ that.sc = $('');
+ that.data('sc', that.sc).data('autocomplete', that.attr('autocomplete'));
+ that.attr('autocomplete', 'off');
+ that.cache = {};
+ that.last_val = '';
+
+ that.updateSC = function (resize, next) {
+ that.sc.css({
+ top: that.offset().top + that.outerHeight() - (that.sc.css("position") == "fixed" ? $(window).scrollTop() : 0),
+ left: that.offset().left,
+ width: that.outerWidth()
+ });
+ if (!resize) {
+ that.sc.show();
+ if (!that.sc.maxHeight) that.sc.maxHeight = parseInt(that.sc.css('max-height'));
+ if (!that.sc.suggestionHeight) that.sc.suggestionHeight = $('.autocomplete-suggestion', that.sc).first().outerHeight();
+ if (that.sc.suggestionHeight)
+ if (!next) that.sc.scrollTop(0);
+ else {
+ var scrTop = that.sc.scrollTop(), selTop = next.offset().top - that.sc.offset().top;
+ if (selTop + that.sc.suggestionHeight - that.sc.maxHeight > 0)
+ that.sc.scrollTop(selTop + that.sc.suggestionHeight + scrTop - that.sc.maxHeight);
+ else if (selTop < 0)
+ that.sc.scrollTop(selTop + scrTop);
+ }
+ }
+ }
+ $(window).on('resize.autocomplete', that.updateSC);
+
+ that.sc.appendTo('body');
+
+ that.on('click', function () {
+ if ($(this).val().length > 0 && that.sc.is(":hidden")) {
+ setTimeout(function () {
+ that.sc.show();
+ }, 100);
+ }
+ });
+
+ that.sc.on('mouseleave', '.autocomplete-suggestion', function () {
+ $('.autocomplete-suggestion.selected').removeClass('selected');
+ });
+
+ that.sc.on('mouseenter', '.autocomplete-suggestion', function () {
+ $('.autocomplete-suggestion.selected').removeClass('selected');
+ $(this).addClass('selected');
+ });
+
+ that.sc.on('mousedown click', '.autocomplete-suggestion', function (e) {
+ var item = $(this), v = item.data('val');
+ if (v || item.hasClass('autocomplete-suggestion')) { // else outside click
+ that.val(v);
+ o.onSelect(e, v, item);
+ that.sc.hide();
+ }
+ return false;
+ });
+
+ that.on('blur.autocomplete', function () {
+ try {
+ over_sb = $('.autocomplete-suggestions:hover').length;
+ } catch (e) {
+ over_sb = 0;
+ } // IE7 fix :hover
+ if (!over_sb) {
+ that.last_val = that.val();
+ that.sc.hide();
+ setTimeout(function () {
+ that.sc.hide();
+ }, 350); // hide suggestions on fast input
+ } else if (!that.is(':focus')) setTimeout(function () {
+ that.focus();
+ }, 20);
+ });
+
+ if (!o.minChars) that.on('focus.autocomplete', function () {
+ that.last_val = '\n';
+ that.trigger('keyup.autocomplete');
+ });
+
+ function suggest(data) {
+ var val = that.val();
+ that.cache[val] = data;
+ if (data.length && val.length >= o.minChars) {
+ var s = '';
+ if (data.length > 0) {
+ s += typeof o.header === 'function' ? o.header.call(data, o, that) : o.header;
+ for (var i = 0; i < data.length; i++) s += o.renderItem(data[i], val);
+ s += typeof o.footer === 'function' ? o.footer.call(data, o, that) : o.footer;
+ }
+ that.sc.html(s);
+ that.updateSC(0);
+ } else
+ that.sc.hide();
+ }
+
+ that.on('keydown.autocomplete', function (e) {
+ // down (40), up (38)
+ if ((e.which == 40 || e.which == 38) && that.sc.html()) {
+ var next, sel = $('.autocomplete-suggestion.selected', that.sc);
+ if (!sel.length) {
+ next = (e.which == 40) ? $('.autocomplete-suggestion', that.sc).first() : $('.autocomplete-suggestion', that.sc).last();
+ that.val(next.addClass('selected').data('val'));
+ } else {
+ next = (e.which == 40) ? sel.next('.autocomplete-suggestion') : sel.prev('.autocomplete-suggestion');
+ if (next.length) {
+ sel.removeClass('selected');
+ that.val(next.addClass('selected').data('val'));
+ } else {
+ sel.removeClass('selected');
+ that.val(that.last_val);
+ next = 0;
+ }
+ }
+ that.updateSC(0, next);
+ return false;
+ }
+ // esc
+ else if (e.which == 27) that.val(that.last_val).sc.hide();
+ // enter or tab
+ else if (e.which == 13 || e.which == 9) {
+ var sel = $('.autocomplete-suggestion.selected', that.sc);
+ if (sel.length && that.sc.is(':visible')) {
+ o.onSelect(e, sel.data('val'), sel);
+ setTimeout(function () {
+ that.sc.hide();
+ }, 20);
+ }
+ }
+ });
+
+ that.on('keyup.autocomplete', function (e) {
+ if (!~$.inArray(e.which, [13, 27, 35, 36, 37, 38, 39, 40])) {
+ var val = that.val();
+ if (val.length >= o.minChars) {
+ if (val != that.last_val) {
+ that.last_val = val;
+ clearTimeout(that.timer);
+ if (o.cache) {
+ if (val in that.cache) {
+ suggest(that.cache[val]);
+ return;
+ }
+ // no requests if previous suggestions were empty
+ for (var i = 1; i < val.length - o.minChars; i++) {
+ var part = val.slice(0, val.length - i);
+ if (part in that.cache && !that.cache[part].length) {
+ suggest([]);
+ return;
+ }
+ }
+ }
+ that.timer = setTimeout(function () {
+ o.source(val, suggest)
+ }, o.delay);
+ }
+ } else {
+ that.last_val = val;
+ that.sc.hide();
+ }
+ }
+ });
+ });
+ }
+
+ $.fn.autoComplete.defaults = {
+ source: 0,
+ minChars: 3,
+ delay: 150,
+ cache: 1,
+ menuClass: '',
+ header: '',
+ footer: '',
+ renderItem: function (item, search) {
+ // escape special characters
+ search = search.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
+ var re = new RegExp("(" + search.split(' ').join('|') + ")", "gi");
+ return '' + item.replace(re, "$1") + '
';
+ },
+ onSelect: function (e, term, item) {
+ }
+ };
+}(jQuery));
\ No newline at end of file
diff --git a/public/assets/js/addons.js b/public/assets/js/addons.js
index e03a62f..fac9499 100644
--- a/public/assets/js/addons.js
+++ b/public/assets/js/addons.js
@@ -1,5 +1,40 @@
define([], function () {
- if (typeof Config.upload.storage !== 'undefined' && Config.upload.storage === 'hwobs') {
+ require([], function () {
+ //绑定data-toggle=addresspicker属性点击事件
+
+ $(document).on('click', "[data-toggle='addresspicker']", function () {
+ var that = this;
+ var callback = $(that).data('callback');
+ var input_id = $(that).data("input-id") ? $(that).data("input-id") : "";
+ var lat_id = $(that).data("lat-id") ? $(that).data("lat-id") : "";
+ var lng_id = $(that).data("lng-id") ? $(that).data("lng-id") : "";
+ var zoom_id = $(that).data("zoom-id") ? $(that).data("zoom-id") : "";
+ var lat = lat_id ? $("#" + lat_id).val() : '';
+ var lng = lng_id ? $("#" + lng_id).val() : '';
+ var zoom = zoom_id ? $("#" + zoom_id).val() : '';
+ var url = "/addons/address/index/select";
+ url += (lat && lng) ? '?lat=' + lat + '&lng=' + lng + (input_id ? "&address=" + $("#" + input_id).val() : "") + (zoom ? "&zoom=" + zoom : "") : '';
+ Fast.api.open(url, '位置选择', {
+ callback: function (res) {
+ input_id && $("#" + input_id).val(res.address).trigger("change");
+ lat_id && $("#" + lat_id).val(res.lat).trigger("change");
+ lng_id && $("#" + lng_id).val(res.lng).trigger("change");
+ zoom_id && $("#" + zoom_id).val(res.zoom).trigger("change");
+
+ try {
+ //执行回调函数
+ if (typeof callback === 'function') {
+ callback.call(that, res);
+ }
+ } catch (e) {
+
+ }
+ }
+ });
+ });
+});
+
+if (typeof Config.upload.storage !== 'undefined' && Config.upload.storage === 'hwobs') {
require(['upload'], function (Upload) {
//获取文件MD5值
var getFileMd5 = function (file, cb) {
diff --git a/public/assets/js/backend/zy/stadium.js b/public/assets/js/backend/zy/stadium.js
new file mode 100644
index 0000000..a1da012
--- /dev/null
+++ b/public/assets/js/backend/zy/stadium.js
@@ -0,0 +1,61 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'zy/stadium/index' + location.search,
+ add_url: 'zy/stadium/add',
+ edit_url: 'zy/stadium/edit',
+ del_url: 'zy/stadium/del',
+ multi_url: 'zy/stadium/multi',
+ import_url: 'zy/stadium/import',
+ table: 'zy_stadium',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ fixedColumns: true,
+ fixedRightNumber: 1,
+ columns: [
+ [
+ { checkbox: true },
+ { field: 'id', title: __('Id') },
+ { field: 'name', title: __('Name'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content },
+ { field: 'sub_name', title: __('Sub_name'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content },
+ { field: 'position', title: __('Position') },
+ { field: 'address', title: __('Address'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content },
+ { field: 'city', title: __('City'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content },
+ { field: 'contact', title: __('Contact'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content },
+ { field: 'status', title: __('Status'), formatter: Table.api.formatter.label, searchList: { 0: __('Status0'), 1: __('Status1') } },
+ { field: 'create_time', title: __('Create_time'), operate: 'RANGE', addclass: 'datetimerange', autocomplete: false },
+ { field: 'update_time', title: __('Update_time'), operate: 'RANGE', addclass: 'datetimerange', autocomplete: false },
+ { field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});
diff --git a/public/assets/js/backend/zy/tags.js b/public/assets/js/backend/zy/tags.js
new file mode 100644
index 0000000..0a78aa7
--- /dev/null
+++ b/public/assets/js/backend/zy/tags.js
@@ -0,0 +1,56 @@
+define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
+
+ var Controller = {
+ index: function () {
+ // 初始化表格参数配置
+ Table.api.init({
+ extend: {
+ index_url: 'zy/tags/index' + location.search,
+ add_url: 'zy/tags/add',
+ edit_url: 'zy/tags/edit',
+ del_url: 'zy/tags/del',
+ multi_url: 'zy/tags/multi',
+ import_url: 'zy/tags/import',
+ table: 'zy_tags',
+ }
+ });
+
+ var table = $("#table");
+
+ // 初始化表格
+ table.bootstrapTable({
+ url: $.fn.bootstrapTable.defaults.extend.index_url,
+ pk: 'id',
+ sortName: 'id',
+ columns: [
+ [
+ { checkbox: true },
+ { field: 'id', title: __('Id') },
+ { field: 'type', title: __('Type'), formatter: Table.api.formatter.label, searchList: { 0: __('Gym'), 1: __('Club'), 2: __('User') } },
+ { field: 'group', title: __('Group'), formatter: Table.api.formatter.label, searchList: { 0: __('General'), 1: __('Ability'), 2: __('Role') } },
+ { field: 'choose', title: __('Choose'), formatter: Table.api.formatter.label, searchList: { 0: __('Multiple'), 1: __('Single') } },
+ { field: 'content_json', title: __('Content_json') },
+ { field: 'create_time', title: __('Create_time'), operate: 'RANGE', addclass: 'datetimerange', autocomplete: false },
+ { field: 'update_time', title: __('Update_time'), operate: 'RANGE', addclass: 'datetimerange', autocomplete: false },
+ { field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate }
+ ]
+ ]
+ });
+
+ // 为表格绑定事件
+ Table.api.bindevent(table);
+ },
+ add: function () {
+ Controller.api.bindevent();
+ },
+ edit: function () {
+ Controller.api.bindevent();
+ },
+ api: {
+ bindevent: function () {
+ Form.api.bindevent($("form[role=form]"));
+ }
+ }
+ };
+ return Controller;
+});