From 78e7233bc00b358984edb96bea1ceb29cd29bde4 Mon Sep 17 00:00:00 2001 From: leon <916117771@qq.com> Date: Sat, 25 Apr 2026 22:35:24 +0800 Subject: [PATCH] =?UTF-8?q?feat(history):=20=E6=B7=BB=E5=8A=A0=E5=8E=86?= =?UTF-8?q?=E5=8F=B2=E6=95=B0=E6=8D=AE=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=92=8C=E6=95=B0=E6=8D=AE=E5=88=86=E6=9E=90=E5=9B=BE=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在addons.php中添加example模块路由配置 - 新增application/config.php配置文件,包含应用设置、数据库配置等 - 实现dashboard.js仪表盘功能,包含冷热号码分析、比例分析图表 - 添加history.js历史数据管理功能,支持号码查询和统计分析 - 集成echarts图表库实现数据可视化展示 - 添加号码颜色映射和生肖映射功能 - 实现号码球样式格式化显示 - 添加遗漏号码、走势图、冷热分析等数据分析功能 --- application/admin/controller/History.php | 43 +++ .../controller/example/Bootstraptable.php | 137 +++++++ .../admin/controller/example/Colorbadge.php | 22 ++ .../controller/example/Controllerjump.php | 22 ++ .../admin/controller/example/Customform.php | 42 +++ .../admin/controller/example/Customsearch.php | 24 ++ .../admin/controller/example/Cxselect.php | 21 ++ .../admin/controller/example/Echarts.php | 44 +++ .../admin/controller/example/Multitable.php | 92 +++++ .../controller/example/Relationmodel.php | 44 +++ .../admin/controller/example/Tablelink.php | 83 +++++ .../controller/example/Tabletemplate.php | 58 +++ application/admin/model/Area.php | 15 + application/admin/model/History.php | 73 +++- .../view/example/bootstraptable/detail.html | 33 ++ .../view/example/bootstraptable/edit.html | 11 + .../view/example/bootstraptable/index.html | 57 +++ .../admin/view/example/colorbadge/index.html | 21 ++ .../view/example/controllerjump/index.html | 21 ++ .../admin/view/example/customform/index.html | 350 ++++++++++++++++++ .../view/example/customsearch/index.html | 126 +++++++ .../admin/view/example/cxselect/index.html | 160 ++++++++ .../admin/view/example/echarts/index.html | 165 +++++++++ .../admin/view/example/multitable/index.html | 27 ++ .../view/example/relationmodel/index.html | 21 ++ .../admin/view/example/tablelink/index.html | 44 +++ .../view/example/tabletemplate/index.html | 67 ++++ application/config.php | 2 +- application/extra/addons.php | 4 + public/assets/js/backend/dashboard.js | 31 +- .../js/backend/example/bootstraptable.js | 323 ++++++++++++++++ .../assets/js/backend/example/colorbadge.js | 52 +++ .../js/backend/example/controllerjump.js | 60 +++ .../assets/js/backend/example/customform.js | 33 ++ .../assets/js/backend/example/customsearch.js | 63 ++++ public/assets/js/backend/example/cxselect.js | 14 + public/assets/js/backend/example/echarts.js | 206 +++++++++++ .../assets/js/backend/example/multitable.js | 93 +++++ .../js/backend/example/relationmodel.js | 48 +++ public/assets/js/backend/example/tablelink.js | 81 ++++ .../js/backend/example/tabletemplate.js | 115 ++++++ public/assets/js/backend/history.js | 43 ++- 42 files changed, 2981 insertions(+), 10 deletions(-) create mode 100644 application/admin/controller/example/Bootstraptable.php create mode 100644 application/admin/controller/example/Colorbadge.php create mode 100644 application/admin/controller/example/Controllerjump.php create mode 100644 application/admin/controller/example/Customform.php create mode 100644 application/admin/controller/example/Customsearch.php create mode 100644 application/admin/controller/example/Cxselect.php create mode 100644 application/admin/controller/example/Echarts.php create mode 100644 application/admin/controller/example/Multitable.php create mode 100644 application/admin/controller/example/Relationmodel.php create mode 100644 application/admin/controller/example/Tablelink.php create mode 100644 application/admin/controller/example/Tabletemplate.php create mode 100644 application/admin/model/Area.php create mode 100644 application/admin/view/example/bootstraptable/detail.html create mode 100644 application/admin/view/example/bootstraptable/edit.html create mode 100644 application/admin/view/example/bootstraptable/index.html create mode 100644 application/admin/view/example/colorbadge/index.html create mode 100644 application/admin/view/example/controllerjump/index.html create mode 100644 application/admin/view/example/customform/index.html create mode 100644 application/admin/view/example/customsearch/index.html create mode 100644 application/admin/view/example/cxselect/index.html create mode 100644 application/admin/view/example/echarts/index.html create mode 100644 application/admin/view/example/multitable/index.html create mode 100644 application/admin/view/example/relationmodel/index.html create mode 100644 application/admin/view/example/tablelink/index.html create mode 100644 application/admin/view/example/tabletemplate/index.html create mode 100644 public/assets/js/backend/example/bootstraptable.js create mode 100644 public/assets/js/backend/example/colorbadge.js create mode 100644 public/assets/js/backend/example/controllerjump.js create mode 100644 public/assets/js/backend/example/customform.js create mode 100644 public/assets/js/backend/example/customsearch.js create mode 100644 public/assets/js/backend/example/cxselect.js create mode 100644 public/assets/js/backend/example/echarts.js create mode 100644 public/assets/js/backend/example/multitable.js create mode 100644 public/assets/js/backend/example/relationmodel.js create mode 100644 public/assets/js/backend/example/tablelink.js create mode 100644 public/assets/js/backend/example/tabletemplate.js diff --git a/application/admin/controller/History.php b/application/admin/controller/History.php index 6e0705b..7b19a59 100644 --- a/application/admin/controller/History.php +++ b/application/admin/controller/History.php @@ -31,6 +31,49 @@ class History extends Backend } + /** + * 查看开奖记录(支持按每月日号筛选) + */ + public function index() + { + $this->request->filter(['strip_tags', 'trim']); + if (false === $this->request->isAjax()) { + return $this->view->fetch(); + } + if ($this->request->request('keyField')) { + return $this->selectpage(); + } + // search_day 在 filter JSON 里,先提取出来再移除 + $filterStr = $this->request->get('filter', '[]', 'trim'); + $opStr = $this->request->get('op', '[]', 'trim'); + $filter = json_decode($filterStr, true) ?: []; + $op = json_decode($opStr, true) ?: []; + $searchDay = isset($filter['search_day']) ? $filter['search_day'] : ''; + unset($filter['search_day'], $op['search_day']); + // 写回 Request 对象 + $ref = new \ReflectionProperty($this->request, 'get'); + $ref->setAccessible(true); + $getData = $ref->getValue($this->request); + if (is_array($getData)) { + $getData['filter'] = json_encode($filter); + $getData['op'] = json_encode($op); + $ref->setValue($this->request, $getData); + } + + [$where, $sort, $order, $offset, $limit] = $this->buildparams(); + $list = $this->model->where($where); + // 按每月日号筛选 + if ($searchDay !== '' && is_numeric($searchDay)) { + $day = intval($searchDay); + if ($day >= 1 && $day <= 31) { + $list = $list->whereRaw('DAY(openTime) = ?', [$day]); + } + } + $query = $list->order($sort, $order)->paginate($limit); + $result = ['total' => $query->total(), 'rows' => $query->items()]; + return json($result); + } + /** * 查询遗漏号码 diff --git a/application/admin/controller/example/Bootstraptable.php b/application/admin/controller/example/Bootstraptable.php new file mode 100644 index 0000000..1d55262 --- /dev/null +++ b/application/admin/controller/example/Bootstraptable.php @@ -0,0 +1,137 @@ +model = model('AdminLog'); + } + + /** + * 查看 + */ + public function index() + { + if ($this->request->isAjax()) { + list($where, $sort, $order, $offset, $limit) = $this->buildparams(null); + $list = $this->model + ->where($where) + ->order($sort, $order) + ->limit($offset, $limit) + ->paginate($limit); + $result = array("total" => $list->total(), "rows" => $list->items(), "extend" => ['money' => mt_rand(100000, 999999), 'price' => 200]); + + return json($result); + } + return $this->view->fetch(); + } + + /** + * 详情 + */ + public function detail($ids) + { + $row = $this->model->get(['id' => $ids]); + if (!$row) { + $this->error(__('No Results were found')); + } + if ($this->request->isAjax()) { + $this->success("Ajax请求成功", null, ['id' => $ids]); + } + $this->view->assign("row", $row->toArray()); + return $this->view->fetch(); + } + + /** + * 启用 + */ + public function start($ids = '') + { + $this->success("模拟启动成功"); + } + + /** + * 暂停 + */ + public function pause($ids = '') + { + $this->success("模拟暂停成功"); + } + + /** + * 切换 + */ + public function change($ids = '') + { + //你需要在此做具体的操作逻辑 + + $this->success("模拟切换成功"); + } + + /** + * 联动搜索 + */ + public function cxselect() + { + $type = $this->request->get('type'); + $group_id = $this->request->get('group_id'); + $list = null; + if ($group_id !== '') { + if ($type == 'group') { + $groupIds = $this->auth->getChildrenGroupIds(true); + $list = \app\admin\model\AuthGroup::where('id', 'in', $groupIds)->field('id as value, name')->select(); + } else { + $adminIds = \app\admin\model\AuthGroupAccess::where('group_id', 'in', $group_id)->column('uid'); + $list = \app\admin\model\Admin::where('id', 'in', $adminIds)->field('id as value, username AS name')->select(); + } + } + $this->success('', null, $list); + } + + /** + * 搜索下拉列表 + */ + public function searchlist() + { + $result = $this->model->limit(10)->select(); + $searchlist = []; + foreach ($result as $key => $value) { + $searchlist[] = ['id' => $value['url'], 'name' => $value['url']]; + } + $data = ['searchlist' => $searchlist]; + $this->success('', null, $data); + } + + public function selectpage() + { + $this->model = new \app\admin\model\AdminLog; + return parent::selectpage(); + } +} diff --git a/application/admin/controller/example/Colorbadge.php b/application/admin/controller/example/Colorbadge.php new file mode 100644 index 0000000..d828b55 --- /dev/null +++ b/application/admin/controller/example/Colorbadge.php @@ -0,0 +1,22 @@ +model = model('AdminLog'); + } +} diff --git a/application/admin/controller/example/Controllerjump.php b/application/admin/controller/example/Controllerjump.php new file mode 100644 index 0000000..01bd6d3 --- /dev/null +++ b/application/admin/controller/example/Controllerjump.php @@ -0,0 +1,22 @@ +model = model('AdminLog'); + } +} diff --git a/application/admin/controller/example/Customform.php b/application/admin/controller/example/Customform.php new file mode 100644 index 0000000..626b371 --- /dev/null +++ b/application/admin/controller/example/Customform.php @@ -0,0 +1,42 @@ +model = model('AdminLog'); + } + + public function index() + { + if ($this->request->isPost()) { + $this->success("提交成功", null, ['data' => json_encode($this->request->post("row/a"), JSON_UNESCAPED_UNICODE)]); + } + return $this->view->fetch(); + } + + public function get_title_list() + { + $query = $this->request->get("query"); + $suggestions = AdminLog::where('title', 'like', '%' . $query . '%')->limit(10)->column("title"); + $result = [ + 'query' => $query, + 'suggestions' => $suggestions + ]; + return json($result); + } +} diff --git a/application/admin/controller/example/Customsearch.php b/application/admin/controller/example/Customsearch.php new file mode 100644 index 0000000..719656d --- /dev/null +++ b/application/admin/controller/example/Customsearch.php @@ -0,0 +1,24 @@ +model = model('AdminLog'); + $ipList = $this->model->whereTime('createtime', '-37 days')->group("ip")->column("ip,ip as aa"); + $this->view->assign("ipList", $ipList); + } +} diff --git a/application/admin/controller/example/Cxselect.php b/application/admin/controller/example/Cxselect.php new file mode 100644 index 0000000..70c882d --- /dev/null +++ b/application/admin/controller/example/Cxselect.php @@ -0,0 +1,21 @@ +model = model('AdminLog'); + } + + /** + * 查看 + */ + public function index() + { + + return $this->view->fetch(); + } + + /** + * 详情 + */ + public function detail($ids) + { + $row = $this->model->get(['id' => $ids]); + if (!$row) { + $this->error(__('No Results were found')); + } + $this->view->assign("row", $row->toArray()); + return $this->view->fetch(); + } +} diff --git a/application/admin/controller/example/Multitable.php b/application/admin/controller/example/Multitable.php new file mode 100644 index 0000000..4a9309e --- /dev/null +++ b/application/admin/controller/example/Multitable.php @@ -0,0 +1,92 @@ +loadlang('general/attachment'); + $this->loadlang('general/crontab'); + return $this->view->fetch(); + } + + public function table1() + { + $this->model = model('Attachment'); + //设置过滤方法 + $this->request->filter(['strip_tags']); + if ($this->request->isAjax()) { + //如果发送的来源是Selectpage,则转发到Selectpage + if ($this->request->request('keyField')) { + return $this->selectpage(); + } + list($where, $sort, $order, $offset, $limit) = $this->buildparams(); + $total = $this->model + ->where($where) + ->field('id,filename,filesize,imagewidth,imageheight,mimetype') + ->order($sort, $order) + ->count(); + + $list = $this->model + ->where($where) + ->field('id,filename,filesize,imagewidth,imageheight,mimetype') + ->order($sort, $order) + ->limit($offset, $limit) + ->select(); + + $result = array("total" => $total, "rows" => $list); + + return json($result); + } + return $this->view->fetch('index'); + } + + public function table2() + { + $this->model = model('AdminLog'); + //设置过滤方法 + $this->request->filter(['strip_tags']); + if ($this->request->isAjax()) { + //如果发送的来源是Selectpage,则转发到Selectpage + if ($this->request->request('keyField')) { + return $this->selectpage(); + } + list($where, $sort, $order, $offset, $limit) = $this->buildparams(); + $total = $this->model + ->where($where) + ->order($sort, $order) + ->count(); + + $list = $this->model + ->where($where) + ->order($sort, $order) + ->limit($offset, $limit) + ->select(); + + $result = array("total" => $total, "rows" => $list); + + return json($result); + } + return $this->view->fetch('index'); + } +} diff --git a/application/admin/controller/example/Relationmodel.php b/application/admin/controller/example/Relationmodel.php new file mode 100644 index 0000000..3342b94 --- /dev/null +++ b/application/admin/controller/example/Relationmodel.php @@ -0,0 +1,44 @@ +model = model('AdminLog'); + } + + /** + * 查看 + */ + public function index() + { + $this->relationSearch = true; + $this->searchFields = "admin.username,id"; + if ($this->request->isAjax()) { + list($where, $sort, $order, $offset, $limit) = $this->buildparams(); + $list = $this->model + ->with("admin") + ->where($where) + ->order($sort, $order) + ->paginate($limit); + + $result = array("total" => $list->total(), "rows" => $list->items()); + + return json($result); + } + return $this->view->fetch(); + } +} diff --git a/application/admin/controller/example/Tablelink.php b/application/admin/controller/example/Tablelink.php new file mode 100644 index 0000000..61af890 --- /dev/null +++ b/application/admin/controller/example/Tablelink.php @@ -0,0 +1,83 @@ +model = model('AdminLog'); + } + + + public function table1() + { + $this->model = model('Admin'); + //设置过滤方法 + $this->request->filter(['strip_tags']); + if ($this->request->isAjax()) { + //如果发送的来源是Selectpage,则转发到Selectpage + if ($this->request->request('keyField')) { + return $this->selectpage(); + } + list($where, $sort, $order, $offset, $limit) = $this->buildparams(); + $total = $this->model + ->where($where) + ->field('id,username') + ->order($sort, $order) + ->count(); + + $list = $this->model + ->where($where) + ->field('id,username') + ->order($sort, $order) + ->limit($offset, $limit) + ->select(); + + $result = array("total" => $total, "rows" => $list); + + return json($result); + } + return $this->view->fetch('index'); + } + + public function table2() + { + $this->model = model('AdminLog'); + //设置过滤方法 + $this->request->filter(['strip_tags']); + if ($this->request->isAjax()) { + //如果发送的来源是Selectpage,则转发到Selectpage + if ($this->request->request('keyField')) { + return $this->selectpage(); + } + list($where, $sort, $order, $offset, $limit) = $this->buildparams(); + $total = $this->model + ->where($where) + ->order($sort, $order) + ->count(); + + $list = $this->model + ->where($where) + ->order($sort, $order) + ->limit($offset, $limit) + ->select(); + + $result = array("total" => $total, "rows" => $list); + + return json($result); + } + return $this->view->fetch('index'); + } +} diff --git a/application/admin/controller/example/Tabletemplate.php b/application/admin/controller/example/Tabletemplate.php new file mode 100644 index 0000000..f51e4f9 --- /dev/null +++ b/application/admin/controller/example/Tabletemplate.php @@ -0,0 +1,58 @@ +model = model('AdminLog'); + } + + /** + * 查看 + */ + public function index() + { + if ($this->request->isAjax()) { + list($where, $sort, $order, $offset, $limit) = $this->buildparams(null); + $total = $this->model + ->where($where) + ->order($sort, $order) + ->count(); + $list = $this->model + ->where($where) + ->order($sort, $order) + ->limit($offset, $limit) + ->select(); + $result = array("total" => $total, "rows" => $list); + + return json($result); + } + return $this->view->fetch(); + } + + /** + * 详情 + */ + public function detail($ids) + { + $row = $this->model->get(['id' => $ids]); + if (!$row) { + $this->error(__('No Results were found')); + } + $this->view->assign("row", $row->toArray()); + return $this->view->fetch(); + } +} diff --git a/application/admin/model/Area.php b/application/admin/model/Area.php new file mode 100644 index 0000000..357d07e --- /dev/null +++ b/application/admin/model/Area.php @@ -0,0 +1,15 @@ +_computeCurrentHotCold($allHistorySorted, $historySorted[0], $lookback); + + return [ + 'list' => $result, + 'current' => $current + ]; + } + + /** + * 基于指定期的lookback窗口,计算所有49个号码的冷热状态 + * @param array $allHistorySorted 全量历史数据 + * @param mixed $targetRow 目标期数据 + * @param int $lookback 向前期数 + * @return array {hot: [{num, count}], cold: [{num, count}], warm: [{num, count}]} + */ + private function _computeCurrentHotCold($allHistorySorted, $targetRow, $lookback) + { + $targetTime = $targetRow['openTime']; + $count = array_fill(1, 49, 0); + $periodCount = 0; + + for ($j = 0; $j < count($allHistorySorted); $j++) { + $checkRow = $allHistorySorted[$j]; + $checkTime = $checkRow['openTime']; + + if ($checkTime >= $targetTime) { + continue; + } + + if ($periodCount >= $lookback) { + break; + } + + $num = (int)$checkRow['num7']; + if ($num >= 1 && $num <= 49) { + $count[$num]++; + } + $periodCount++; + } + + $avgCount = $periodCount > 0 ? $periodCount / 49 : 0; + $hot = []; + $cold = []; + $warm = []; + + for ($num = 1; $num <= 49; $num++) { + $status = 'warm'; + if ($avgCount > 0) { + if ($count[$num] > $avgCount * 1.5) { + $status = 'hot'; + } elseif ($count[$num] < $avgCount * 0.5) { + $status = 'cold'; + } + } + + $item = ['num' => $num, 'count' => $count[$num]]; + if ($status === 'hot') { + $hot[] = $item; + } elseif ($status === 'cold') { + $cold[] = $item; + } else { + $warm[] = $item; + } + } + + // 热号按次数降序,冷号按次数升序 + usort($hot, function ($a, $b) { return $b['count'] - $a['count']; }); + usort($cold, function ($a, $b) { return $a['count'] - $b['count']; }); + usort($warm, function ($a, $b) { return $b['count'] - $a['count']; }); + + return ['hot' => $hot, 'cold' => $cold, 'warm' => $warm]; } /** diff --git a/application/admin/view/example/bootstraptable/detail.html b/application/admin/view/example/bootstraptable/detail.html new file mode 100644 index 0000000..e16348e --- /dev/null +++ b/application/admin/view/example/bootstraptable/detail.html @@ -0,0 +1,33 @@ + + + + + + + + + {volist name="row" id="vo" } + + + + + {/volist} + {if $Think.get.dialog} + + + + + {/if} + +
{:__('Title')}{:__('Content')}
{$key}{$vo|htmlentities}
回传数据 +
+ + 回传数据 +
+
+ diff --git a/application/admin/view/example/bootstraptable/edit.html b/application/admin/view/example/bootstraptable/edit.html new file mode 100644 index 0000000..a69f78a --- /dev/null +++ b/application/admin/view/example/bootstraptable/edit.html @@ -0,0 +1,11 @@ + + + + +
这里是编辑窗口
+ diff --git a/application/admin/view/example/bootstraptable/index.html b/application/admin/view/example/bootstraptable/index.html new file mode 100644 index 0000000..6c29aed --- /dev/null +++ b/application/admin/view/example/bootstraptable/index.html @@ -0,0 +1,57 @@ +
+ +
+ {:build_heading(null,FALSE)} + +
+ + +
+
+ + +
+
+
+ diff --git a/application/admin/view/example/colorbadge/index.html b/application/admin/view/example/colorbadge/index.html new file mode 100644 index 0000000..8d61a3a --- /dev/null +++ b/application/admin/view/example/colorbadge/index.html @@ -0,0 +1,21 @@ +
+ {:build_heading()} + +
+
+
+
+
+ {:build_toolbar('refresh,delete')} +
+ + +
+ + +
+
+ +
+
+
\ No newline at end of file diff --git a/application/admin/view/example/controllerjump/index.html b/application/admin/view/example/controllerjump/index.html new file mode 100644 index 0000000..8d61a3a --- /dev/null +++ b/application/admin/view/example/controllerjump/index.html @@ -0,0 +1,21 @@ +
+ {:build_heading()} + +
+
+
+
+
+ {:build_toolbar('refresh,delete')} +
+ + +
+ + +
+
+ +
+
+
\ No newline at end of file diff --git a/application/admin/view/example/customform/index.html b/application/admin/view/example/customform/index.html new file mode 100644 index 0000000..1a0df2d --- /dev/null +++ b/application/admin/view/example/customform/index.html @@ -0,0 +1,350 @@ + +
+
+
+
+ {:__('自定义图片描述')} +
+
+
+ 温馨提示
+ 默认我们的多图是没有图片描述的,如果我们需要自定义描述,可以使用以下的自定义功能
+ 特别注意的是图片的url和描述是分开储存的,也就是说图片一个字段,描述一个字段,你在前台使用时需要自己匹配映射关系
+ 下面的演示textarea为了便于调试,设置为可见的,实际使用中应该添加个hidden的class进行隐藏 +
+
+
+ +
+
+ +
+ + +
+ +
+ + +
    + + + + + + + +
    +
    +
    + +
    +
    + +
    + + +
    + +
    + + +
      + + + + + + + +
      +
      +
      + +
      + + +
      +
      + +
      +
      +
      + +
      +
      +
      +
      + {:__('自定义Fieldlist示例')} +
      +
      +
      + 温馨提示
      + 默认的fieldlist为键值形式,如果需要一维数组或二维数组,可使用下面的自定义模板来实现
      + 默认追加的元素是没有进行事件绑定的,我们需要监听btn-append这个按钮的fa.event.appendfieldlist事件
      + 下面的演示textarea为了便于调试,设置为可见的,实际使用中应该添加个hidden的class进行隐藏 +
      +
      +
      + +
      +
      +
      + {:__('标题')} +
      +
      + {:__('Append')} +
      +
      + + + + +
      +
      +
      + +
      +
      +
      + {:__('标题')} +
      +
      + {:__('Append')} +
      +
      + + + +
      +
      +
      + +
      + + + + + + + + + + + +
      {:__('标题')}{:__('介绍')}{:__('大小')}{:__('状态')}
      {:__('Append')}
      + + + + +
      +
      +
      + +
      + + + + + + + + + + +
      {:__('管理员')}{:__('图片')}{:__('登录时间')}
      {:__('Append')}
      + + + + +
      +
      +
      + +
      + + +
      +
      + +
      +
      +
      + +
      +
      +
      +
      + 自动完成+标签输入示例,只支持FastAdmin1.3.0+ {if version_compare($Think.config.fastadmin.version, '1.3.0')<0}你当前FastAdmin版本不支持{/if} +
      +
      +
      + 温馨提示
      +
      +
      + +
      + +
      + +
      +
      +
      + +
      + +
      +
      +
      + +
      + +
      +
      +
      +
      +
      +
      +
      +
      +
      + 动态显示,只支持FastAdmin1.3.3+ {if version_compare($Think.config.fastadmin.version, '1.3.3')<0}你当前FastAdmin版本不支持{/if} +
      +
      +
      + +
      + +
      + 类型1 + 类型2 +
      显示内容1
      +
      显示内容2
      +
      +
      +
      +
      + +
      + + + + + + +
      显示内容隐藏的内容
      +
      +
      +
      +
      + +
      + 模式1 + 模式2 +
      +

      显示内容1

      + + + + + +
      显示内容隐藏的内容1
      +
      +
      +

      显示内容2

      + + + + + +
      显示内容隐藏的内容2
      +
      +
      +
      +
      +
      + +
      + +
      显示内容隐藏的内容
      +
      +
      +
      +
      +
      +
      +
      diff --git a/application/admin/view/example/customsearch/index.html b/application/admin/view/example/customsearch/index.html new file mode 100644 index 0000000..85fc818 --- /dev/null +++ b/application/admin/view/example/customsearch/index.html @@ -0,0 +1,126 @@ +
      + {:build_heading()} + +
      +
      +
      +
      +
      + {:build_toolbar('refresh')} +
      + + +
      + +
      +
      + +
      +
      +
      + + diff --git a/application/admin/view/example/cxselect/index.html b/application/admin/view/example/cxselect/index.html new file mode 100644 index 0000000..2d78b77 --- /dev/null +++ b/application/admin/view/example/cxselect/index.html @@ -0,0 +1,160 @@ + +
      + {:build_heading()} + +
      +
      +
      +
      +
      +
      +
      + +
      +
      省市区联动(通过AJAX读取数据)
      +
      +
      +
      +
      + + + +
      +
      +
      +
      +
      +
      + +
      +
      +
      +
      +
      + + + +
      +
      +
      +
      +
      +
      + +
      +
      +
      + +
      +
      +
      +
      +
      类别联动(Ajax读取数据)
      +
      +
      +
      +
      + + +
      +
      +
      +
      +
      +
      + +
      +
      +
      +
      +
      + + +
      +
      +
      +
      +
      +
      + +
      +
      + +
      +
      +
      +
      +
      +
      省市区联动(通过JSON渲染数据)
      +
      +
      +
      + +
      + + + +
      +
      +
      +
      +
      +
      + +
      +
      +
      +
      + +
      + + + +
      +
      +
      +
      +
      +
      + +
      +
      +
      + +
      +
      +
      +
      +
      +
      + +
      +
      +
      \ No newline at end of file diff --git a/application/admin/view/example/echarts/index.html b/application/admin/view/example/echarts/index.html new file mode 100644 index 0000000..1e879b2 --- /dev/null +++ b/application/admin/view/example/echarts/index.html @@ -0,0 +1,165 @@ + +
      +
      + +
      +
      +

      150

      + +

      今日订单

      +
      +
      + +
      + 更多 +
      +
      + +
      + +
      +
      +

      53%

      + +

      同比增长率

      +
      +
      + +
      + 更多 +
      +
      + +
      + +
      +
      +

      44

      + +

      今日注册用户数

      +
      +
      + +
      + 更多 +
      +
      + +
      + +
      +
      +

      65

      + +

      唯一访客用户

      +
      +
      + +
      + 更多 +
      +
      + +
      + + +
      + +
      + + + + + +
      + +
      + + +
      +
      + +
      +
      + + + + +

      + 访客分布 +

      +
      +
      +
      +
      + + +
      + + + +
      +
      + + +

      订单趋势

      + +
      +
      +
      +
      +
      +
      + + +
      + + +
      + +
      + diff --git a/application/admin/view/example/multitable/index.html b/application/admin/view/example/multitable/index.html new file mode 100644 index 0000000..38b662b --- /dev/null +++ b/application/admin/view/example/multitable/index.html @@ -0,0 +1,27 @@ +
      +
      +
      多表格(Multitable)用于展示在一个页面展示多个表格数据,并且每次切换时刷新
      + +
      +
      +
      +
      +
      + {:build_toolbar('refresh')} +
      + +
      +
      +
      +
      + {:build_toolbar('refresh')} +
      + +
      +
      +
      +
      +
      \ No newline at end of file diff --git a/application/admin/view/example/relationmodel/index.html b/application/admin/view/example/relationmodel/index.html new file mode 100644 index 0000000..8d61a3a --- /dev/null +++ b/application/admin/view/example/relationmodel/index.html @@ -0,0 +1,21 @@ +
      + {:build_heading()} + +
      +
      +
      +
      +
      + {:build_toolbar('refresh,delete')} +
      + + +
      + + +
      +
      + +
      +
      +
      \ No newline at end of file diff --git a/application/admin/view/example/tablelink/index.html b/application/admin/view/example/tablelink/index.html new file mode 100644 index 0000000..3c782f6 --- /dev/null +++ b/application/admin/view/example/tablelink/index.html @@ -0,0 +1,44 @@ +
      +
      +
      +
      +
      +
      +
      +
      + {:build_toolbar('refresh')} +
      + + +
      + + +
      +
      + +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      + {:build_toolbar('refresh')} +
      + + +
      + + +
      +
      + +
      +
      +
      +
      +
      \ No newline at end of file diff --git a/application/admin/view/example/tabletemplate/index.html b/application/admin/view/example/tabletemplate/index.html new file mode 100644 index 0000000..5e7c67e --- /dev/null +++ b/application/admin/view/example/tabletemplate/index.html @@ -0,0 +1,67 @@ +
      + {:build_heading()} + +
      +
      +
      +
      +
      + {:build_toolbar('refresh,delete')} + 获取选中项 + 切换视图 +
      + + +
      + +
      +
      + +
      +
      +
      + + + \ No newline at end of file diff --git a/application/config.php b/application/config.php index 2e6052c..e1e6738 100644 --- a/application/config.php +++ b/application/config.php @@ -270,7 +270,7 @@ return [ //FastAdmin配置 'fastadmin' => [ //是否开启前台会员中心 - 'usercenter' => true, + 'usercenter' => false, //会员注册验证码类型email/mobile/wechat/text/false 'user_register_captcha' => 'text', //登录验证码 diff --git a/application/extra/addons.php b/application/extra/addons.php index 6cbb3f9..8e6ce26 100644 --- a/application/extra/addons.php +++ b/application/extra/addons.php @@ -7,6 +7,10 @@ return array ( ), 'route' => array ( + '/example$' => 'example/index/index', + '/example/d/[:name]' => 'example/demo/index', + '/example/d1/[:name]' => 'example/demo/demo1', + '/example/d2/[:name]' => 'example/demo/demo2', ), 'priority' => array ( diff --git a/public/assets/js/backend/dashboard.js b/public/assets/js/backend/dashboard.js index fd43c16..efb6bea 100644 --- a/public/assets/js/backend/dashboard.js +++ b/public/assets/js/backend/dashboard.js @@ -43,13 +43,34 @@ define(['jquery'], function ($) { var html = ''; + // 热号:按次数降序取前5名 + var hotAll = hc.all.slice().sort(function (a, b) { return b.count - a.count; }); + var hotTop5 = hotAll.slice(0, 5); + // 冷号:按次数升序取前5名,第5名有并列则全部包含 + var coldAll = hc.all.slice().sort(function (a, b) { return a.count - b.count; }); + var coldList = coldAll.slice(0, 5); + if (coldList.length >= 5) { + var threshold = coldList[4].count; + var rest = coldAll.slice(5); + for (var k = 0; k < rest.length; k++) { + if (rest[k].count === threshold) coldList.push(rest[k]); + else break; + } + } + html += '

      🔥❄️ 冷热号码

      '; html += '
      热号 Top 5
      '; - for (var i = 0; i < 5; i++) html += ball(hc.hot[i].num, hc.hot[i].color) + ' '; - html += '
      '; - html += '
      冷号 Top 5
      '; - for (var i = 0; i < 5; i++) html += ball(hc.cold[i].num, hc.cold[i].color) + ' '; - html += '
      '; + html += '
      '; + for (var i = 0; i < hotTop5.length; i++) { + html += '' + ball(hotTop5[i].num, hotTop5[i].color) + '
      ' + hotTop5[i].count + '次
      '; + } + html += '
      '; + html += '
      冷号
      '; + html += '
      '; + for (var i = 0; i < coldList.length; i++) { + html += '' + ball(coldList[i].num, coldList[i].color) + '
      ' + coldList[i].count + '次
      '; + } + html += '
      '; html += '

      📊 比例分析

      '; html += '
      '; diff --git a/public/assets/js/backend/example/bootstraptable.js b/public/assets/js/backend/example/bootstraptable.js new file mode 100644 index 0000000..d83af88 --- /dev/null +++ b/public/assets/js/backend/example/bootstraptable.js @@ -0,0 +1,323 @@ +define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function ($, undefined, Backend, Table, Form, Template) { + + var Controller = { + index: function () { + // 初始化表格参数配置 + Table.api.init({ + extend: { + index_url: 'example/bootstraptable/index', + add_url: '', + edit_url: 'example/bootstraptable/edit', + del_url: 'example/bootstraptable/del', + multi_url: '', + } + }); + + var table = $("#table"); + + //在普通搜索提交搜索前 + table.on('common-search.bs.table', function (event, table, query) { + //这里可以获取到普通搜索表单中字段的查询条件 + console.log(query); + }); + + //在普通搜索渲染后 + table.on('post-common-search.bs.table', function (event, table) { + var form = $("form", table.$commonsearch); + $("input[name='title']", form).addClass("selectpage").data("source", "example/bootstraptable/selectpage").data("primaryKey", "title").data("field", "title").data("orderBy", "id desc"); + $("input[name='username']", form).addClass("selectpage").data("source", "auth/admin/index").data("primaryKey", "username").data("field", "username").data("orderBy", "id desc"); + Form.events.cxselect(form); + Form.events.selectpage(form); + }); + + //在表格内容渲染完成后回调的事件 + table.on('post-body.bs.table', function (e, settings, json, xhr) { + console.log(e, settings, json, xhr); + }); + + //当表格数据加载完成时 + table.on('load-success.bs.table', function (e, data) { + //这里可以获取从服务端获取的JSON数据 + console.log(data); + //这里我们手动设置底部的值 + $("#money").text(data.extend.money); + $("#price").text(data.extend.price); + }); + + // 初始化表格 + // 这里使用的是Bootstrap-table插件渲染表格 + // 相关文档:https://doc.fastadmin.net/doc/table.html + table.bootstrapTable({ + //表格参数可以参考:https://doc.fastadmin.net/doc/190.html + url: $.fn.bootstrapTable.defaults.extend.index_url, + columns: [ + [ + //更多列参数可以参考:https://doc.fastadmin.net/doc/191.html + //该列为复选框字段,如果后台的返回state值将会默认选中 + {field: 'state', checkbox: true,}, + //sortable为是否排序,operate为搜索时的操作符,visible表示是否可见 + {field: 'id', title: 'ID', sortable: true, operate: false}, + //直接响应搜索 + {field: 'username', title: __('管理员'), formatter: Table.api.formatter.search}, + //模糊搜索 + {field: 'title', title: __('Title'), operate: 'LIKE %...%', placeholder: '模糊搜索,*表示任意字符', width: '280px'}, + //通过Ajax渲染searchList,也可以使用JSON数据 + { + field: 'url', + title: __('Url'), + align: 'left', + searchList: $.getJSON('example/bootstraptable/searchlist?search=a&field=row[user_id]'), + formatter: Controller.api.formatter.url, + addClass: "selectpicker" + }, + //点击IP时同时执行搜索此IP + { + field: 'ip', + title: __('IP'), + events: Controller.api.events.ip, + formatter: Controller.api.formatter.ip + }, + //自定义栏位,custom是不存在的字段 + {field: 'custom', title: __('切换'), operate: false, formatter: Controller.api.formatter.custom}, + { + field: 'admin_id', title: __('联动搜索'), searchList: function (column) { + return Template('categorytpl', {}); + }, formatter: function (value, row, index) { + return '无'; + }, visible: false + }, + //启用时间段搜索 + { + field: 'createtime', + title: __('Update time'), + sortable: true, + formatter: Table.api.formatter.datetime, + operate: 'RANGE', + addclass: 'datetimerange' + }, + //操作栏,默认有编辑、删除或排序按钮,可自定义配置buttons来扩展按钮 + { + field: 'operate', + width: "150px", + title: __('Operate'), + table: table, + events: Table.api.events.operate, + buttons: [ + { + name: 'click', + title: __('点击执行事件'), + classname: 'btn btn-xs btn-info btn-click', + icon: 'fa fa-leaf', + // dropdown: '更多',//如果包含dropdown,将会以下拉列表的形式展示 + click: function (data) { + Layer.alert("点击按钮执行的事件"); + } + }, + { + name: 'detail', + title: __('弹出窗口打开'), + classname: 'btn btn-xs btn-primary btn-dialog', + icon: 'fa fa-list', + url: 'example/bootstraptable/detail', + callback: function (data) { + Layer.alert("接收到回传数据:" + JSON.stringify(data), {title: "回传数据"}); + } + }, + { + name: 'ajax', + title: __('发送Ajax'), + classname: 'btn btn-xs btn-success btn-magic btn-ajax', + icon: 'fa fa-magic', + confirm: '确认发送Ajax请求?', + url: 'example/bootstraptable/detail', + success: function (data, ret) { + Layer.alert(ret.msg + ",返回数据:" + JSON.stringify(data)); + //如果需要阻止成功提示,则必须使用return false; + //return false; + }, + error: function (data, ret) { + console.log(data, ret); + Layer.alert(ret.msg); + return false; + } + }, + { + name: 'addtabs', + title: __('新选项卡中打开'), + classname: 'btn btn-xs btn-warning btn-addtabs', + icon: 'fa fa-folder-o', + url: 'example/bootstraptable/detail' + } + ], + formatter: Table.api.formatter.operate + }, + ], + ], + //更多配置参数可参考:https://doc.fastadmin.net/doc/190.html + //亦可以参考require-table.js中defaults的配置 + //快捷搜索,这里可在控制器定义快捷搜索的字段 + search: true, + //启用普通表单搜索 + commonSearch: true, + //显示导出按钮 + showExport: true, + //启用跨页选择 + maintainSelected: true, + //启用固定列 + fixedColumns: true, + //固定左侧列数 + fixedNumber: 3, + //固定右侧列数 + fixedRightNumber: 1, + //导出类型 + exportDataType: "all", //共有basic, all, selected三种值 basic当前页 all全部 selected仅选中 + //导出下拉列表选项 + exportTypes: ['json', 'xml', 'csv', 'txt', 'doc', 'excel'], + //可以控制是否默认显示搜索单表,false则隐藏,默认为false + searchFormVisible: true, + queryParams: function (params) { + //这里可以追加搜索条件 + var filter = JSON.parse(params.filter); + var op = JSON.parse(params.op); + //这里可以动态赋值,比如从URL中获取admin_id的值,filter.admin_id=Fast.api.query('admin_id'); + filter.admin_id = 1; + op.admin_id = "="; + params.filter = JSON.stringify(filter); + params.op = JSON.stringify(op); + return params; + }, + }); + + // 为表格绑定事件 + Table.api.bindevent(table); + + // 监听下拉列表改变的事件 + $(document).on('change', 'select[name=admin]', function () { + $("input[name='admin_id']").val($(this).val()); + }); + + //自定义Tab筛选条件 + $('.panel-heading .nav-custom-condition a[data-toggle="tab"]', table.closest(".panel-intro")).on('shown.bs.tab', function (e) { + var value = $(this).data("value"); + var options = table.bootstrapTable('getOptions'); + var queryParams = options.queryParams; + options.pageNumber = 1; + options.queryParams = function (params) { + //这一行必须要存在,否则在点击下一页时会丢失搜索栏数据 + params = queryParams(params); + + //如果希望追加搜索条件,可使用 + var filter = params.filter ? JSON.parse(params.filter) : {}; + var op = params.op ? JSON.parse(params.op) : {}; + if (value) { + //这里可以自定义多个筛选条件 + filter.admin_id = value; + op.admin_id = '='; + } else { + //选全部时要移除相应的条件 + delete filter.admin_id; + delete op.admin_id; + } + + params.filter = JSON.stringify(filter); + params.op = JSON.stringify(op); + + //如果希望忽略搜索栏搜索条件,可使用 + //params.filter = JSON.stringify(value?{admin_id: value}:{}); + //params.op = JSON.stringify(value?{admin_id: '='}:{}); + return params; + }; + + table.trigger("uncheckbox"); + table.bootstrapTable('refresh', {pageNumber: 1}); + return false; + }); + + // 指定搜索条件 + $(document).on("click", ".btn-singlesearch", function () { + var options = table.bootstrapTable('getOptions'); + var queryParams = options.queryParams; + options.pageNumber = 1; + options.queryParams = function (params) { + //这一行必须要存在,否则在点击下一页时会丢失搜索栏数据 + params = queryParams(params); + + //如果希望追加搜索条件,可使用 + var filter = params.filter ? JSON.parse(params.filter) : {}; + var op = params.op ? JSON.parse(params.op) : {}; + filter.url = 'login'; + op.url = 'like'; + + params.filter = JSON.stringify(filter); + params.op = JSON.stringify(op); + + //如果希望忽略搜索栏搜索条件,可使用 + //params.filter = JSON.stringify({url: 'login'}); + //params.op = JSON.stringify({url: 'like'}); + return params; + }; + table.bootstrapTable('refresh', {}); + Toastr.info("当前执行的是自定义搜索,搜索URL中包含login的数据"); + return false; + }); + + // 获取选中项 + $(document).on("click", ".btn-selected", function () { + Layer.alert(JSON.stringify(Table.api.selecteddata(table))); + }); + + // 启动和暂停按钮 + $(document).on("click", ".btn-start,.btn-pause", function () { + //在table外不可以使用添加.btn-change的方法 + //只能自己调用Table.api.multi实现 + //如果操作全部则ids可以置为空 + var ids = Table.api.selectedids(table); + Table.api.multi("changestatus", ids.join(","), table, this); + }); + + }, + add: function () { + Controller.api.bindevent(); + }, + edit: function () { + Controller.api.bindevent(); + }, + detail: function () { + $(document).on('click', '.btn-callback', function () { + Fast.api.close($("input[name=callback]").val()); + }); + }, + api: { + bindevent: function () { + Form.api.bindevent($("form[role=form]")); + }, + formatter: {//渲染的方法 + url: function (value, row, index) { + return '
      '; + }, + ip: function (value, row, index) { + return ' ' + value + ''; + }, + custom: function (value, row, index) { + //添加上btn-change可以自定义请求的URL进行数据处理 + return ''; + }, + }, + events: {//绑定事件的方法 + ip: { + //格式为:方法名+空格+DOM元素 + 'click .btn-ip': function (e, value, row, index) { + e.stopPropagation(); + var container = $("#table").data("bootstrap.table").$container; + var options = $("#table").bootstrapTable('getOptions'); + //这里我们手动将数据填充到表单然后提交 + $("form.form-commonsearch [name='ip']", container).val(value); + $("form.form-commonsearch", container).trigger('submit'); + Toastr.info("执行了自定义搜索操作"); + } + }, + } + } + }; + return Controller; +}); diff --git a/public/assets/js/backend/example/colorbadge.js b/public/assets/js/backend/example/colorbadge.js new file mode 100644 index 0000000..e4dbeed --- /dev/null +++ b/public/assets/js/backend/example/colorbadge.js @@ -0,0 +1,52 @@ +define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) { + + var Controller = { + index: function () { + // 初始化表格参数配置 + Table.api.init({ + extend: { + index_url: 'example/colorbadge/index', + add_url: '', + edit_url: '', + del_url: 'example/colorbadge/del', + multi_url: '', + } + }); + + var table = $("#table"); + + // 初始化表格 + table.bootstrapTable({ + url: $.fn.bootstrapTable.defaults.extend.index_url, + columns: [ + [ + {field: 'state', checkbox: true, }, + {field: 'id', title: 'ID'}, + {field: 'title', title: __('Title')}, + {field: 'ip', title: __('IP')}, + {field: 'createtime', title: __('Create time'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true}, + {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate} + ] + ], + onLoadSuccess: function (data) { + // 在表格第次加载成功后,刷新左侧菜单栏彩色小角标,支持一次渲染多个 + // 如果需要在进入后台即显示左侧的彩色小角标,请使用服务端渲染方式,详情修改application/admin/controller/Index.php + Backend.api.sidebar({ + 'example/colorbadge': data.total + }); + Toastr.info("左侧角标已经刷新成功"); + } + }); + + // 为表格绑定事件 + Table.api.bindevent(table); + }, + add: function () { + Form.api.bindevent($("form[role=form]")); + }, + edit: function () { + Form.api.bindevent($("form[role=form]")); + } + }; + return Controller; +}); \ No newline at end of file diff --git a/public/assets/js/backend/example/controllerjump.js b/public/assets/js/backend/example/controllerjump.js new file mode 100644 index 0000000..a557233 --- /dev/null +++ b/public/assets/js/backend/example/controllerjump.js @@ -0,0 +1,60 @@ +define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) { + + var Controller = { + index: function () { + // 初始化表格参数配置 + Table.api.init({ + extend: { + index_url: 'example/controllerjump/index', + add_url: '', + edit_url: '', + del_url: 'example/controllerjump/del', + multi_url: '', + } + }); + + var table = $("#table"); + + // 初始化表格 + table.bootstrapTable({ + url: $.fn.bootstrapTable.defaults.extend.index_url, + columns: [ + [ + {field: 'state', checkbox: true, }, + {field: 'id', title: 'ID'}, + {field: 'admin_id', title: __('Admin_id')}, + {field: 'title', title: __('Title')}, + {field: 'ip', title: __('IP'),formatter: Controller.api.formatter.ip}, + {field: 'createtime', title: __('Create time'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true}, + {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate} + ] + ] + }); + + // 为表格绑定事件 + Table.api.bindevent(table); + }, + add: function () { + Form.api.bindevent($("form[role=form]")); + }, + edit: function () { + Form.api.bindevent($("form[role=form]")); + }, + api: { + formatter: { + ip: function (value, row, index) { + //这里手动构造URL + url = "example/bootstraptable?" + this.field + "=" + value; + + //方式一,直接返回class带有addtabsit的链接,这可以方便自定义显示内容 + //return '' + __('Search %s', value) + ''; + + //方式二,直接调用Table.api.formatter.addtabs + this.url = url; + return Table.api.formatter.addtabs.call(this, value, row, index); + } + } + } + }; + return Controller; +}); diff --git a/public/assets/js/backend/example/customform.js b/public/assets/js/backend/example/customform.js new file mode 100644 index 0000000..17a7e2b --- /dev/null +++ b/public/assets/js/backend/example/customform.js @@ -0,0 +1,33 @@ +define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) { + + var Controller = { + index: function () { + Template.helper("Fast", Fast); + + //因为日期选择框不会触发change事件,导致无法刷新textarea,所以加上判断 + $(document).on("dp.change", "#second-form .datetimepicker", function () { + $(this).parent().prev().find("input").trigger("change"); + }); + $(document).on("fa.event.appendfieldlist", "#first-table .btn-append", function (e, obj) { + + }); + $(document).on("fa.event.appendfieldlist", "#second-table .btn-append", function (e, obj) { + //绑定动态下拉组件 + Form.events.selectpage(obj); + //绑定日期组件 + Form.events.datetimepicker(obj); + //绑定上传组件 + Form.events.faupload(obj); + + //上传成功回调事件,变更按钮的背景 + $(".upload-image", obj).data("upload-success", function (data) { + $(this).css("background-image", "url('" + Fast.api.cdnurl(data.url) + "')"); + }) + }); + Form.api.bindevent($("form[role=form]"), function (data, ret) { + Layer.alert(data.data); + }); + }, + }; + return Controller; +}); diff --git a/public/assets/js/backend/example/customsearch.js b/public/assets/js/backend/example/customsearch.js new file mode 100644 index 0000000..60501fa --- /dev/null +++ b/public/assets/js/backend/example/customsearch.js @@ -0,0 +1,63 @@ +define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) { + var Controller = { + index: function () { + // + // 初始化表格参数配置 + Table.api.init({ + extend: { + index_url: 'example/customsearch/index', + add_url: 'example/customsearch/add', + edit_url: '', + del_url: 'example/customsearch/del', + multi_url: 'example/customsearch/multi', + table: '', + } + }); + + var table = $("#table"); + + // 初始化表格 + table.bootstrapTable({ + url: $.fn.bootstrapTable.defaults.extend.index_url, + pk: 'id', + sortName: 'id', + searchFormVisible: true, + searchFormTemplate: 'customformtpl', + columns: [ + [ + {checkbox: true}, + {field: 'id', title: 'ID', operate: false}, + {field: 'admin_id', title: __('Admin_id'), visible: false, operate: false}, + {field: 'username', title: __('Username'), formatter: Table.api.formatter.search}, + {field: 'title', title: __('Title')}, + {field: 'url', title: __('Url'), align: 'left'}, + {field: 'ip', title: __('IP')}, + {field: 'createtime', title: __('Create time'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true}, + { + 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/example/cxselect.js b/public/assets/js/backend/example/cxselect.js new file mode 100644 index 0000000..355b77a --- /dev/null +++ b/public/assets/js/backend/example/cxselect.js @@ -0,0 +1,14 @@ +define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) { + + var Controller = { + index: function () { + $("#cxselect-example .col-xs-12").each(function () { + $("textarea", this).val($(this).prev().prev().html().replace(/[ ]{2}/g, '')); + }); + + //这里需要手动为Form绑定上元素事件 + Form.api.bindevent($("form#cxselectform")); + } + }; + return Controller; +}); \ No newline at end of file diff --git a/public/assets/js/backend/example/echarts.js b/public/assets/js/backend/example/echarts.js new file mode 100644 index 0000000..f12e115 --- /dev/null +++ b/public/assets/js/backend/example/echarts.js @@ -0,0 +1,206 @@ +define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template', 'echarts', 'echarts-theme'], function ($, undefined, Backend, Table, Form, Template, Echarts) { + + var Controller = { + index: function () { + //这句话在多选项卡统计表时必须存在,否则会导致影响的图表宽度不正确 + $(document).on("click", ".charts-custom a[data-toggle=\"tab\"]", function () { + var that = this; + setTimeout(function () { + var id = $(that).attr("href"); + var chart = Echarts.getInstanceByDom($(id)[0]); + chart.resize(); + }, 0); + }); + + // 基于准备好的dom,初始化echarts实例 + var lineChart = Echarts.init(document.getElementById('line-chart'), 'walden'); + + // 指定图表的配置项和数据 + var option = { + xAxis: { + type: 'category', + data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] + }, + yAxis: { + type: 'value' + }, + series: [{ + data: [49, 92, 61, 134, 90, 130, 120], + type: 'line' + }] + }; + + // 使用刚指定的配置项和数据显示图表。 + lineChart.setOption(option); + // 基于准备好的dom,初始化echarts实例 + var areaChart = Echarts.init(document.getElementById('area-chart'), 'walden'); + + // 指定图表的配置项和数据 + var option = { + xAxis: { + type: 'category', + boundaryGap: false, + data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] + }, + yAxis: { + type: 'value' + }, + series: [{ + data: [820, 932, 901, 934, 1290, 1330, 1320], + type: 'line', + areaStyle: {} + }] + }; + + // 使用刚指定的配置项和数据显示图表。 + areaChart.setOption(option); + + var pieChart = Echarts.init(document.getElementById('pie-chart'), 'walden'); + var option = { + tooltip: { + trigger: 'item', + formatter: '{a}
      {b}: {c} ({d}%)' + }, + legend: { + orient: 'vertical', + left: 10, + data: ['直接访问', '邮件营销', '联盟广告', '视频广告', '搜索引擎'] + }, + series: [ + { + name: '访问来源', + type: 'pie', + radius: ['50%', '70%'], + avoidLabelOverlap: false, + label: { + normal: { + show: false, + position: 'center' + }, + emphasis: { + show: true, + textStyle: { + fontSize: '30', + fontWeight: 'bold' + } + } + }, + labelLine: { + normal: { + show: false + } + }, + data: [ + {value: 335, name: '直接访问'}, + {value: 310, name: '邮件营销'}, + {value: 234, name: '联盟广告'}, + {value: 135, name: '视频广告'}, + {value: 1548, name: '搜索引擎'} + ] + } + ] + }; + // 使用刚指定的配置项和数据显示图表。 + pieChart.setOption(option); + + var barChart = Echarts.init(document.getElementById('bar-chart'), 'walden'); + option = { + legend: {}, + tooltip: {}, + dataset: { + source: [ + ['产品销售', '2015', '2016', '2017'], + ['风扇', 43.3, 85.8, 93.7], + ['电视机', 83.1, 73.4, 55.1], + ['空调', 86.4, 65.2, 82.5], + ['冰箱', 72.4, 53.9, 39.1] + ] + }, + xAxis: {type: 'category'}, + yAxis: {}, + // Declare several bar series, each will be mapped + // to a column of dataset.source by default. + series: [ + {type: 'bar'}, + {type: 'bar'}, + {type: 'bar'} + ] + }; + // 使用刚指定的配置项和数据显示图表。 + barChart.setOption(option); + + + var barChart = Echarts.init(document.getElementById('simplebar-chart')); + option = { + xAxis: { + type: 'category', + axisLine: { + lineStyle: { + color: "#fff" + } + }, + data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] + }, + yAxis: { + type: 'value', + axisLine: { + lineStyle: { + color: "#fff" + } + } + }, + series: [{ + data: [120, 200, 150, 80, 70, 110, 130], + type: 'bar', + itemStyle: { + color: "#fff", + opacity: 0.6 + } + }] + }; + // 使用刚指定的配置项和数据显示图表。 + barChart.setOption(option); + + var barChart = Echarts.init(document.getElementById('smoothline-chart')); + option = { + textStyle: { + color: "#fff" + }, + color: ['#fff'], + xAxis: { + type: 'category', + boundaryGap: false, + data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'], + axisLine: { + lineStyle: { + color: "#fff" + } + } + }, + yAxis: { + type: 'value', + splitLine: { + show: false + }, + axisLine: { + lineStyle: { + color: "#fff" + } + } + }, + series: [{ + data: [820, 932, 901, 934, 1290, 1330, 1320], + type: 'line', + smooth: true, + areaStyle: { + opacity: 0.4 + } + + }] + }; + // 使用刚指定的配置项和数据显示图表。 + barChart.setOption(option); + } + }; + return Controller; +}); diff --git a/public/assets/js/backend/example/multitable.js b/public/assets/js/backend/example/multitable.js new file mode 100644 index 0000000..73c6e13 --- /dev/null +++ b/public/assets/js/backend/example/multitable.js @@ -0,0 +1,93 @@ +define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) { + + var Controller = { + index: function () { + // 初始化表格参数配置 + Table.api.init(); + + //绑定事件 + $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { + var panel = $($(this).attr("href")); + if (panel.length > 0) { + Controller.table[panel.attr("id")].call(this); + $(this).on('click', function (e) { + $($(this).attr("href")).find(".btn-refresh").trigger("click"); + }); + } + //移除绑定的事件 + $(this).unbind('shown.bs.tab'); + }); + + //必须默认触发shown.bs.tab事件 + $('ul.nav-tabs li.active a[data-toggle="tab"]').trigger("shown.bs.tab"); + }, + table: { + first: function () { + // 表格1 + var table1 = $("#table1"); + table1.bootstrapTable({ + url: 'example/multitable/table1', + toolbar: '#toolbar1', + sortName: 'id', + search: false, + columns: [ + [ + {field: 'state', checkbox: true, }, + {field: 'id', title: 'ID'}, + {field: 'filename', title: __('Name')}, + {field: 'imagewidth', title: __('Imagewidth')}, + {field: 'imageheight', title: __('Imageheight')}, + {field: 'mimetype', title: __('Mimetype')}, + {field: 'operate', title: __('Operate'), table: table1, events: Table.api.events.operate, formatter: Table.api.formatter.operate} + ] + ] + }); + + // 为表格1绑定事件 + Table.api.bindevent(table1); + }, + second: function () { + // 表格2 + var table2 = $("#table2"); + table2.bootstrapTable({ + url: 'example/multitable/table2', + extend: { + index_url: '', + add_url: '', + edit_url: '', + del_url: '', + multi_url: '', + table: '', + }, + toolbar: '#toolbar2', + sortName: 'id', + search: false, + columns: [ + [ + {field: 'id', title: 'ID'}, + {field: 'title', title: __('Title')}, + {field: 'url', title: __('Url'), align: 'left', formatter: Table.api.formatter.url}, + {field: 'ip', title: __('ip')}, + {field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true}, + ] + ] + }); + + // 为表格2绑定事件 + Table.api.bindevent(table2); + } + }, + 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/example/relationmodel.js b/public/assets/js/backend/example/relationmodel.js new file mode 100644 index 0000000..2c24aaa --- /dev/null +++ b/public/assets/js/backend/example/relationmodel.js @@ -0,0 +1,48 @@ +define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) { + + var Controller = { + index: function () { + // 初始化表格参数配置 + Table.api.init({ + extend: { + index_url: 'example/relationmodel/index', + add_url: '', + edit_url: '', + del_url: 'example/relationmodel/del', + multi_url: '', + } + }); + + var table = $("#table"); + + // 初始化表格 + table.bootstrapTable({ + url: $.fn.bootstrapTable.defaults.extend.index_url, + columns: [ + [ + {field: 'state', checkbox: true, }, + {field: 'id', title: 'ID', operate: '='}, + {field: 'title', title: __('Title'), operate: 'LIKE %...%', placeholder: '关键字,模糊搜索'}, + {field: 'admin.avatar', title: __('Avatar'), operate: false, formatter: Table.api.formatter.image}, + {field: 'admin.username', title: __('Username'), operate: 'FIND_IN_SET'}, + {field: 'admin.nickname', title: __('Nickname'), operate: 'LIKE %...%', placeholder: '关键字,模糊搜索'}, + {field: 'ip', title: __('IP'), operate: '='}, + {field: 'createtime', title: __('Create time'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true}, + {field: 'admin.createtime', title: __('Create time'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true}, + {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate} + ] + ], + }); + + // 为表格绑定事件 + Table.api.bindevent(table); + }, + add: function () { + Form.api.bindevent($("form[role=form]")); + }, + edit: function () { + Form.api.bindevent($("form[role=form]")); + }, + }; + return Controller; +}); diff --git a/public/assets/js/backend/example/tablelink.js b/public/assets/js/backend/example/tablelink.js new file mode 100644 index 0000000..689d63d --- /dev/null +++ b/public/assets/js/backend/example/tablelink.js @@ -0,0 +1,81 @@ +define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) { + + var Controller = { + index: function () { + // 初始化表格参数配置 + Table.api.init(); + this.table.first(); + this.table.second(); + }, + table: { + first: function () { + // 表格1 + var table1 = $("#table1"); + table1.bootstrapTable({ + url: 'example/tablelink/table1', + toolbar: '#toolbar1', + sortName: 'id', + search: false, + columns: [ + [ + // {field: 'state', checkbox: true,}, + {field: 'id', title: 'ID'}, + {field: 'username', title: __('Nickname')}, + { + field: 'operate', title: __('Operate'), table: table1, events: Table.api.events.operate, buttons: [ + { + name: 'log', + title: '日志列表', + text: '日志列表', + icon: 'fa fa-list', + classname: 'btn btn-primary btn-xs btn-click', + click: function (e, data) { + $("#myTabContent2 .form-commonsearch input[name='username']").val(data.username); + $("#myTabContent2 .btn-refresh").trigger("click"); + } + } + ], formatter: Table.api.formatter.operate + } + ] + ] + }); + + // 为表格1绑定事件 + Table.api.bindevent(table1); + }, + second: function () { + // 表格2 + var table2 = $("#table2"); + table2.bootstrapTable({ + url: 'example/tablelink/table2', + extend: { + index_url: '', + add_url: '', + edit_url: '', + del_url: '', + multi_url: '', + table: '', + }, + toolbar: '#toolbar2', + sortName: 'id', + search: false, + columns: [ + [ + {field: 'state', checkbox: true,}, + {field: 'id', title: 'ID'}, + {field: 'username', title: __('Nickname')}, + {field: 'title', title: __('Title')}, + {field: 'url', title: __('Url'), align: 'left', formatter: Table.api.formatter.url}, + {field: 'ip', title: __('ip')}, + {field: 'createtime', title: __('Createtime'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true}, + ] + ] + }); + + // 为表格2绑定事件 + Table.api.bindevent(table2); + } + }, + }; + return Controller; +}); diff --git a/public/assets/js/backend/example/tabletemplate.js b/public/assets/js/backend/example/tabletemplate.js new file mode 100644 index 0000000..b181181 --- /dev/null +++ b/public/assets/js/backend/example/tabletemplate.js @@ -0,0 +1,115 @@ +define(['jquery', 'bootstrap', 'backend', 'table', 'form', 'template'], function ($, undefined, Backend, Table, Form, Template) { + + var Controller = { + index: function () { + // 初始化表格参数配置 + Table.api.init({ + extend: { + index_url: 'example/tabletemplate/index', + add_url: '', + edit_url: '', + del_url: 'example/tabletemplate/del', + multi_url: '', + } + }); + + var table = $("#table"); + + Template.helper("Moment", Moment); + + // 初始化表格 + table.bootstrapTable({ + url: $.fn.bootstrapTable.defaults.extend.index_url, + templateView: true, + columns: [ + [ + {field: 'state', checkbox: true, }, + {field: 'id', title: 'ID', operate: false}, + //直接响应搜索 + {field: 'username', title: __('Username'), formatter: Table.api.formatter.search}, + //模糊搜索 + {field: 'title', title: __('Title'), operate: 'LIKE %...%', placeholder: '模糊搜索,*表示任意字符', style: 'width:200px'}, + //通过Ajax渲染searchList + {field: 'url', title: __('Url'), align: 'left', formatter: Controller.api.formatter.url}, + //点击IP时同时执行搜索此IP,同时普通搜索使用下拉列表的形式 + {field: 'ip', title: __('IP'), searchList: ['127.0.0.1', '127.0.0.2'], events: Controller.api.events.ip, formatter: Controller.api.formatter.ip}, + //browser是一个不存在的字段 + //通过formatter来渲染数据,同时为它添加上事件 + {field: 'browser', title: __('Browser'), operate: false, events: Controller.api.events.browser, formatter: Controller.api.formatter.browser}, + //启用时间段搜索 + {field: 'createtime', title: __('Create time'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true}, + {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate} + ], + ], + //禁用默认搜索 + search: false, + //启用普通表单搜索 + commonSearch: false, + //可以控制是否默认显示搜索单表,false则隐藏,默认为false + searchFormVisible: false, + //分页大小 + pageSize: 12 + }); + + // 为表格绑定事件 + Table.api.bindevent(table); + + //指定搜索条件 + $(document).on("click", ".btn-toggle-view", function () { + var options = table.bootstrapTable('getOptions'); + table.bootstrapTable('refreshOptions', {templateView: !options.templateView}); + }); + + //点击详情 + $(document).on("click", ".btn-detail[data-id]", function () { + Backend.api.open('example/bootstraptable/detail/ids/' + $(this).data('id'), __('Detail')); + }); + + //获取选中项 + $(document).on("click", ".btn-selected", function () { + //在templateView的模式下不能调用table.bootstrapTable('getSelections')来获取选中的ID,只能通过下面的Table.api.selectedids来获取 + Layer.alert(JSON.stringify(Table.api.selectedids(table))); + }); + }, + add: function () { + Controller.api.bindevent(); + }, + edit: function () { + Controller.api.bindevent(); + }, + api: { + bindevent: function () { + Form.api.bindevent($("form[role=form]")); + }, + formatter: { + url: function (value, row, index) { + return '
      '; + }, + ip: function (value, row, index) { + return ' ' + value + ''; + }, + browser: function (value, row, index) { + //这里我们直接使用row的数据 + return '' + row.useragent.split(" ")[0] + ''; + } + }, + events: { + ip: { + 'click .btn-ip': function (e, value, row, index) { + var options = $("#table").bootstrapTable('getOptions'); + //这里我们手动将数据填充到表单然后提交 + $("#commonSearchContent_" + options.idTable + " form [name='ip']").val(value); + $("#commonSearchContent_" + options.idTable + " form").trigger('submit'); + Toastr.info("执行了自定义搜索操作"); + } + }, + browser: { + 'click .btn-browser': function (e, value, row, index) { + Layer.alert("该行数据为: " + JSON.stringify(row) + ""); + } + } + } + } + }; + return Controller; +}); \ No newline at end of file diff --git a/public/assets/js/backend/history.js b/public/assets/js/backend/history.js index bf18dc6..6f6d684 100644 --- a/public/assets/js/backend/history.js +++ b/public/assets/js/backend/history.js @@ -35,6 +35,7 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin {field: 'num6', title: __('Num6'), formatter: Controller.api.formatter.numBall}, {field: 'num7', title: __('Num7'), formatter: Controller.api.formatter.numBall}, {field: 'openTime', title: __('OpenTime'), operate:'RANGE', addclass:'datetimerange', autocomplete:false}, + {field: 'search_day', title: '每月日号', visible: false, searchable: true, operate: '=', style: 'width:80px;', extend: 'min="1" max="31" placeholder="1-31"'} ] ] }); @@ -660,12 +661,48 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin return map[status] || ''; }; - if (!data || data.length === 0) { + // 新接口返回 {list: [...], current: {hot: [], cold: [], warm: []}} + var listData = data.list || data; + var current = data.current || null; + + if (!listData || listData.length === 0) { $('#shc-result', layero).html('
      暂无数据
      '); return; } var html = '
      '; + + // 当前冷热号汇总区域 + if (current && (current.hot.length > 0 || current.cold.length > 0)) { + var renderNumBall = function (item) { + var color = getColor(item.num); + return '' + item.num + ''; + }; + + html += '
      '; + html += '
      当前热号
      '; + html += '
      '; + for (var h = 0; h < current.hot.length; h++) { + html += renderNumBall(current.hot[h]); + } + if (current.hot.length === 0) { + html += '暂无热号'; + } + html += '
      '; + html += '
      '; + html += '
      当前冷号
      '; + html += '
      '; + for (var c = 0; c < current.cold.length; c++) { + html += renderNumBall(current.cold[c]); + } + if (current.cold.length === 0) { + html += '暂无冷号'; + } + html += '
      '; + html += '
      '; + } + + // 历史记录表格 html += '' + '' + '' + @@ -676,8 +713,8 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin '' + ''; - for (var i = 0; i < data.length; i++) { - var item = data[i]; + for (var i = 0; i < listData.length; i++) { + var item = listData[i]; var rowClass = ''; if (item.status === 'hot') rowClass = 'style="background:#fff5f5;"'; else if (item.status === 'cold') rowClass = 'style="background:#f5f8ff;"';
      期号排名