├── .idea
└── .gitignore
├── README.md
├── api
└── portal
│ ├── controller
│ ├── ArticlesController.php
│ ├── CategoriesController.php
│ ├── IndexController.php
│ ├── ListsController.php
│ ├── PagesController.php
│ ├── TagsController.php
│ ├── UserArticlesController.php
│ └── UserController.php
│ ├── logic
│ └── PortalPostModel.php
│ ├── model
│ ├── PortalCategoryModel.php
│ ├── PortalCategoryPostModel.php
│ ├── PortalPostModel.php
│ ├── PortalTagModel.php
│ ├── PortalTagPostModel.php
│ ├── RecycleBinModel.php
│ └── UserModel.php
│ ├── route.php
│ ├── service
│ ├── PortalCategoryService.php
│ ├── PortalPostService.php
│ └── PortalTagService.php
│ └── validate
│ └── ArticlesValidate.php
├── app
└── portal
│ ├── PortalApp.php
│ ├── api
│ ├── CategoryApi.php
│ └── PageApi.php
│ ├── controller
│ ├── AdminArticleController.php
│ ├── AdminCategoryController.php
│ ├── AdminIndexController.php
│ ├── AdminPageController.php
│ ├── AdminTagController.php
│ ├── ArticleController.php
│ ├── IndexController.php
│ ├── ListController.php
│ ├── PageController.php
│ ├── SearchController.php
│ └── TagController.php
│ ├── data
│ └── portal.sql
│ ├── hooks.php
│ ├── lang
│ ├── en-us.php
│ ├── en-us
│ │ └── common.php
│ ├── zh-cn.php
│ └── zh-cn
│ │ ├── common.php
│ │ └── home.php
│ ├── manifest.json
│ ├── model
│ ├── PortalCategoryModel.php
│ ├── PortalCategoryPostModel.php
│ ├── PortalPostModel.php
│ ├── PortalTagModel.php
│ ├── PortalTagPostModel.php
│ ├── RecycleBinModel.php
│ └── UserModel.php
│ ├── nav.php
│ ├── service
│ ├── ApiService.php
│ └── PostService.php
│ ├── taglib
│ └── Portal.php
│ ├── url.php
│ ├── user_action.php
│ ├── validate
│ ├── AdminArticleValidate.php
│ ├── AdminPageValidate.php
│ └── PortalCategoryValidate.php
│ └── version
└── public
└── themes
├── admin_simpleboot3
└── portal
│ ├── admin_article
│ ├── add.html
│ ├── copy.html
│ ├── edit.html
│ ├── index.html
│ ├── move.html
│ └── recyclebin.html
│ ├── admin_category
│ ├── add.html
│ ├── edit.html
│ ├── index.html
│ └── select.html
│ ├── admin_page
│ ├── add.html
│ ├── edit.html
│ ├── index.html
│ └── recyclebin.html
│ └── admin_tag
│ ├── add.html
│ ├── index.html
│ └── select.html
└── simpleboot3
├── README.md
├── manifest.json
├── portal
├── article.html
├── article.json
├── contact.html
├── contact.json
├── index.html
├── index.json
├── list.html
├── list.json
├── page.html
├── page.json
├── search.html
├── search.json
└── tag.html
├── public
├── assets
│ ├── css
│ │ ├── slippry
│ │ │ ├── assets
│ │ │ │ └── img
│ │ │ │ │ ├── arrows.png
│ │ │ │ │ ├── arrows.svg
│ │ │ │ │ └── sy-loader.gif
│ │ │ └── slippry.css
│ │ └── style.css
│ ├── images
│ │ ├── default-thumbnail.png
│ │ ├── default_tupian1.png
│ │ ├── default_tupian4.png
│ │ ├── demo
│ │ │ ├── 1.jpg
│ │ │ ├── 2.jpg
│ │ │ └── 3.jpg
│ │ ├── favicon.ico
│ │ ├── favicon.png
│ │ ├── ghs.png
│ │ ├── headicon.png
│ │ ├── headicon_128.png
│ │ ├── headicon_30.png
│ │ ├── headicon_40.png
│ │ ├── headicon_50.png
│ │ ├── logo.png
│ │ └── null_cart2.jpg
│ ├── js
│ │ ├── imagesloaded.pkgd.min.js
│ │ ├── jquery-1.10.2.min.js
│ │ ├── jquery-1.10.2.min.map
│ │ ├── jquery-migrate-1.2.1.js
│ │ ├── jquery.infiniteScroll.js
│ │ ├── masonry.pkgd.min.js
│ │ ├── qrcode.min.js
│ │ ├── slippry.min.js
│ │ └── slippry.min.map
│ └── simpleboot3
│ │ ├── bootstrap
│ │ └── js
│ │ │ └── bootstrap.min.js
│ │ ├── canvas-to-blob
│ │ ├── canvas-to-blob.js
│ │ ├── canvas-to-blob.min.js
│ │ └── canvas-to-blob.min.js.map
│ │ ├── cropper
│ │ ├── cropper.css
│ │ ├── cropper.js
│ │ └── jquery-cropper.min.js
│ │ ├── font-awesome
│ │ ├── 4.2.0
│ │ │ ├── css
│ │ │ │ ├── font-awesome-ie7.min.css
│ │ │ │ └── font-awesome.min.css
│ │ │ └── fonts
│ │ │ │ ├── FontAwesome.otf
│ │ │ │ ├── fontawesome-webfont.eot
│ │ │ │ ├── fontawesome-webfont.svg
│ │ │ │ ├── fontawesome-webfont.ttf
│ │ │ │ └── fontawesome-webfont.woff
│ │ └── 4.4.0
│ │ │ ├── css
│ │ │ ├── font-awesome-ie7.min.css
│ │ │ └── font-awesome.min.css
│ │ │ └── fonts
│ │ │ ├── FontAwesome.otf
│ │ │ ├── fontawesome-webfont.eot
│ │ │ ├── fontawesome-webfont.svg
│ │ │ ├── fontawesome-webfont.ttf
│ │ │ ├── fontawesome-webfont.woff
│ │ │ └── fontawesome-webfont.woff2
│ │ └── themes
│ │ ├── fonts
│ │ ├── glyphicons-halflings-regular.eot
│ │ ├── glyphicons-halflings-regular.svg
│ │ ├── glyphicons-halflings-regular.ttf
│ │ ├── glyphicons-halflings-regular.woff
│ │ └── glyphicons-halflings-regular.woff2
│ │ └── simpleboot3
│ │ └── bootstrap.min.css
├── config.html
├── config.json
├── footer.html
├── function.html
├── head.html
├── nav.html
├── nav.json
├── scripts.html
└── usernav.html
└── user
├── comment
└── index.html
├── favorite
└── index.html
├── find_password.html
├── index.html
├── login.html
├── profile
├── avatar.html
├── binding.html
├── center.html
├── edit.html
└── password.html
└── register.html
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /workspace.xml
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ThinkCMF企业门户解决方案,同时兼容ThinkCMF5.1和6.0
2 | ===============
3 | 帮助你更快地搭建企业门户网站
4 |
5 | ### 开发手册
6 | http://www.kancloud.cn/thinkcmf/doc5_1
7 | https://www.kancloud.cn/thinkcmf/theme_tutorial
8 |
9 | ### Git仓库
10 |
11 | 1. GitHub:https://github.com/thinkcmf/portal 主要仓库
12 | 2. 码云:https://gitee.com/thinkcmf/portal 国内仓库
13 |
14 | ### 环境推荐
15 | > php7.1
16 |
17 | > mysql 5.6+
18 |
19 | > 打开rewrite
20 |
21 |
22 | ### 最低环境要求
23 | > php5.6+
24 |
25 | > mysql 5.5+ (mysql5.1安装时选择utf8编码,不支持表情符)
26 |
27 | > 打开rewrite
28 |
29 | ### 安装步骤
30 | 1. 下载本仓库代码,覆盖到你的ThinkCMF里
31 | 2. 导入`app/portal/data/portal.sql`文件(注意把`cmf_`表前缀替换成自己的)
32 | 3. 在后台模板管理里安装`simpleboot3`模板
33 | 4. 如果想用`simpleboot3`模板,可以启用此模板
34 | 5. 导入后台菜单
35 |
36 | 详细安装步骤请查看[ThinkCMF FAQ](https://www.kancloud.cn/thinkcmf/faq/1005840)
37 |
38 |
39 |
40 | ### QQ群:
41 | `ThinkCMF 官方交流群`:316669417
42 |
43 | `ThinkCMF 高级交流群`:100828313 (付费)
44 |
45 | `ThinkCMF 铲屎官交流群`:415136742 (生活娱乐,为有喵的猿人准备)
46 |
47 |
48 | ### 反馈问题
49 | https://github.com/thinkcmf/portal/issues
50 |
51 | ### 更新日志
52 | #### 1.0.0
53 | * 移除所有演示应用、插件、模板代码
54 |
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/api/portal/controller/CategoriesController.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 |
10 | namespace api\portal\controller;
11 |
12 | use api\portal\service\PortalCategoryService;
13 | use cmf\controller\RestBaseController;
14 | use api\portal\model\PortalCategoryModel;
15 |
16 | class CategoriesController extends RestBaseController
17 | {
18 | /**
19 | * 获取分类列表
20 | * @throws \think\db\exception\DataNotFoundException
21 | * @throws \think\db\exception\ModelNotFoundException
22 | * @throws \think\exception\DbException
23 | */
24 | public function index()
25 | {
26 |
27 | $params = $this->request->get();
28 | $categoryService = new PortalCategoryService();
29 | $data = $categoryService->categories($params);
30 | if (empty($this->apiVersion) || $this->apiVersion == '1.0.0') {
31 | $response = $data;
32 | } else {
33 | $response = ['list' => $data];
34 | }
35 |
36 | $this->success('请求成功!', $response);
37 | }
38 |
39 | /**
40 | * 显示指定的分类
41 | * @param $id
42 | * @throws \think\db\exception\DataNotFoundException
43 | * @throws \think\db\exception\ModelNotFoundException
44 | * @throws \think\exception\DbException
45 | */
46 | public function read($id)
47 | {
48 | $categoryModel = new PortalCategoryModel();
49 | $data = $categoryModel
50 | ->where('delete_time', 0)
51 | ->where('status', 1)
52 | ->where('id', $id)
53 | ->find();
54 | if ($data) {
55 | $this->success('请求成功!', $data);
56 | } else {
57 | $this->error('该分类不存在!');
58 | }
59 |
60 | }
61 |
62 | /**
63 | * 获取指定分类的子分类列表
64 | * @throws \think\db\exception\DataNotFoundException
65 | * @throws \think\db\exception\ModelNotFoundException
66 | * @throws \think\exception\DbException
67 | */
68 | public function subCategories()
69 | {
70 | $id = $this->request->get('category_id', 0, 'intval');
71 |
72 | $categoryModel = new PortalCategoryModel();
73 | $categories = $categoryModel->where(['parent_id' => $id])->select();
74 | if (!$categories->isEmpty()) {
75 | $this->success('请求成功', ['categories' => $categories]);
76 | } else {
77 | $this->error('该分类下没有子分类!');
78 | }
79 |
80 |
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/api/portal/controller/IndexController.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 | namespace api\portal\controller;
10 |
11 | use api\portal\model\PortalPostModel;
12 | use cmf\controller\RestBaseController;
13 | use api\portal\model\PortalTagModel;
14 |
15 | class IndexController extends RestBaseController
16 | {
17 | protected $tagModel;
18 |
19 | /**
20 | * 获取标签列表
21 | */
22 | public function index()
23 | {
24 | $this->success('请求成功!', "DD");
25 | }
26 |
27 | /**
28 | * 获取热门标签列表
29 | */
30 | public function hotTags()
31 | {
32 | $params = $this->request->get();
33 | $params['where']['recommended'] = 1;
34 | $data = $this->tagModel->getDatas($params);
35 |
36 | if (empty($this->apiVersion) || $this->apiVersion == '1.0.0') {
37 | $response = $data;
38 | } else {
39 | $response = ['list' => $data,];
40 | }
41 | $this->success('请求成功!', $response);
42 | }
43 |
44 | /**
45 | * 获取标签文章列表
46 | * @param int $id
47 | */
48 | public function articles($id)
49 | {
50 | if (intval($id) === 0) {
51 | $this->error('无效的标签id!');
52 | } else {
53 | $params = $this->request->param();
54 | $postModel = new PortalPostModel();
55 |
56 | unset($params['id']);
57 |
58 | $articles = $postModel->paramsFilter($params)->alias('post')
59 | ->join('__PORTAL_TAG_POST__ tag_post', 'post.id = tag_post.post_id')
60 | ->where(['tag_post.tag_id' => $id])->select();
61 |
62 | if (!empty($params['relation'])) {
63 | $allowedRelations = $postModel->allowedRelations($params['relation']);
64 | if (!empty($allowedRelations)) {
65 | if (count($articles) > 0) {
66 | $articles->load($allowedRelations);
67 | $articles->append($allowedRelations);
68 | }
69 | }
70 | }
71 |
72 |
73 | $this->success('请求成功!', ['articles' => $articles]);
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/api/portal/controller/ListsController.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 | namespace api\portal\controller;
10 |
11 | use api\portal\model\PortalCategoryModel;
12 | use api\portal\service\PortalPostService;
13 | use cmf\controller\RestBaseController;
14 |
15 | class ListsController extends RestBaseController
16 | {
17 |
18 | /**
19 | * 推荐文章列表
20 | * @throws \think\db\exception\DataNotFoundException
21 | * @throws \think\db\exception\ModelNotFoundException
22 | * @throws \think\exception\DbException
23 | */
24 | public function recommended()
25 | {
26 | $param = $this->request->param();
27 | $param['recommended'] = true;
28 |
29 | $portalPostService = new PortalPostService();
30 | $articles = $portalPostService->postArticles($param);
31 | //是否需要关联模型
32 | if (!$articles->isEmpty()) {
33 | if (!empty($param['relation'])) {
34 | $allowedRelations = allowed_relations(['user', 'categories'], $param['relation']);
35 | if (!empty($allowedRelations)) {
36 | $articles->load($allowedRelations);
37 | $articles->append($allowedRelations);
38 | }
39 | }
40 | }
41 | $this->success('ok', ['list' => $articles]);
42 | }
43 |
44 | /**
45 | * 分类文章列表
46 | * @throws \think\db\exception\DataNotFoundException
47 | * @throws \think\db\exception\ModelNotFoundException
48 | * @throws \think\exception\DbException
49 | */
50 | public function getCategoryPostLists()
51 | {
52 | $categoryId = $this->request->param('category_id', 0, 'intval');
53 |
54 | $portalCategoryModel = new PortalCategoryModel();
55 | $findCategory = $portalCategoryModel->where('id', $categoryId)->find();
56 |
57 | //分类是否存在
58 | if (empty($findCategory)) {
59 | $this->error('分类不存在!');
60 | }
61 |
62 | $param = $this->request->param();
63 |
64 | $portalPostService = new PortalPostService();
65 | $articles = $portalPostService->postArticles($param);
66 | //是否需要关联模型
67 | if (!$articles->isEmpty()) {
68 | if (!empty($param['relation'])) {
69 | $allowedRelations = allowed_relations(['user', 'categories'], $param['relation']);
70 | if (!empty($allowedRelations)) {
71 | $articles->load($allowedRelations);
72 | $articles->append($allowedRelations);
73 | }
74 | }
75 | }
76 | $this->success('ok', ['list' => $articles]);
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/api/portal/controller/PagesController.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 |
10 | namespace api\portal\controller;
11 |
12 | use api\portal\service\PortalPostService;
13 | use cmf\controller\RestBaseController;
14 | use api\portal\model\PortalPostModel;
15 |
16 | class PagesController extends RestBaseController
17 | {
18 | /**
19 | * 页面列表
20 | * @throws \think\db\exception\DataNotFoundException
21 | * @throws \think\db\exception\ModelNotFoundException
22 | * @throws \think\exception\DbException
23 | */
24 | public function index()
25 | {
26 | $params = $this->request->get();
27 | $postService = new PortalPostService();
28 | $data = $postService->postArticles($params, true);
29 |
30 | if (empty($this->apiVersion) || $this->apiVersion == '1.0.0') {
31 | $response = $data;
32 | } else {
33 | $response = ['list' => $data,];
34 | }
35 | $this->success('请求成功!', $response);
36 | }
37 |
38 | /**
39 | * 获取页面
40 | * @param $id
41 | * @throws \think\db\exception\DataNotFoundException
42 | * @throws \think\db\exception\ModelNotFoundException
43 | * @throws \think\exception\DbException
44 | */
45 | public function read($id)
46 | {
47 |
48 | $params = $this->request->get();
49 | $field = empty($params['field']) ? '*' : $params['field'];
50 | $postModel = new PortalPostModel();
51 | $data = $postModel
52 | ->field($field)
53 | ->where('id', $id)
54 | ->where('delete_time', 0)
55 | ->where('post_status', 1)
56 | ->where('post_type', 2)
57 | ->find();
58 | if ($data){
59 | $this->success('请求成功!', $data);
60 | }else{
61 | $this->error('文章不存在!');
62 | }
63 |
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/api/portal/controller/TagsController.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 | namespace api\portal\controller;
10 |
11 | use api\portal\model\PortalTagModel;
12 | use api\portal\service\PortalTagService;
13 | use cmf\controller\RestBaseController;
14 | use think\db\Query;
15 |
16 | class TagsController extends RestBaseController
17 | {
18 |
19 | /**
20 | * 获取标签列表
21 | * @throws \think\db\exception\DataNotFoundException
22 | * @throws \think\db\exception\ModelNotFoundException
23 | * @throws \think\exception\DbException
24 | */
25 | public function index()
26 | {
27 | $params = $this->request->get();
28 | $tagService = new PortalTagService();
29 | $data = $tagService->tagList($params);
30 |
31 | if (empty($this->apiVersion) || $this->apiVersion == '1.0.0') {
32 | $response = $data;
33 | } else {
34 | $response = ['list' => $data,];
35 | }
36 | if ($data->isEmpty()) {
37 | $this->error('没有标签!');
38 | }
39 | $this->success('请求成功!', $response);
40 | }
41 |
42 | /**
43 | * 获取热门标签列表
44 | * @throws \think\db\exception\DataNotFoundException
45 | * @throws \think\db\exception\ModelNotFoundException
46 | * @throws \think\exception\DbException
47 | */
48 | public function hotTags()
49 | {
50 | $params = $this->request->get();
51 | $params['where']['recommended'] = 1;
52 |
53 | $tagService = new PortalTagService();
54 | $data = $tagService->tagList($params);
55 |
56 | if (empty($this->apiVersion) || $this->apiVersion == '1.0.0') {
57 | $response = $data;
58 | } else {
59 | $response = ['list' => $data,];
60 | }
61 | $this->success('请求成功!', $response);
62 | }
63 |
64 | /**
65 | * 获取标签文章列表
66 | * @param $id
67 | * @throws \think\db\exception\DataNotFoundException
68 | * @throws \think\db\exception\ModelNotFoundException
69 | * @throws \think\exception\DbException
70 | */
71 | public function articles($id)
72 | {
73 | if (intval($id) === 0) {
74 | $this->error('无效的标签id!');
75 | } else {
76 | $filter = $this->request->param();
77 | $filter['id'] = $id;
78 | $tagService = new PortalTagService();
79 | $tag = $tagService->portalTagArticles($filter);
80 | if ($tag) {
81 | $this->error('没有相关文章');
82 | }
83 | $this->success('请求成功!', $tag);
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/api/portal/controller/UserArticlesController.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 | namespace api\portal\controller;
10 |
11 | use cmf\controller\RestUserBaseController;
12 | use api\portal\logic\PortalPostModel;
13 |
14 | class UserArticlesController extends RestUserBaseController
15 | {
16 | /**
17 | * 显示资源列表
18 | */
19 | public function index()
20 | {
21 | $params = $this->request->get();
22 | $userId = $this->getUserId();
23 | $postModel = new PortalPostModel();
24 | $dates = $postModel->getUserArticles($userId, $params);
25 | $this->success('请求成功!', $dates);
26 | }
27 |
28 | /**
29 | * 保存新建的资源
30 | */
31 | public function save()
32 | {
33 | $dates = $this->request->post();
34 | $dates['user_id'] = $this->getUserId();
35 | $result = $this->validate($dates, 'Articles.article');
36 | if ($result !== true) {
37 | $this->error($result);
38 | }
39 | if (empty($dates['published_time'])) {
40 | $dates['published_time'] = time();
41 | }
42 | $postModel = new PortalPostModel();
43 | $postModel->addArticle($dates);
44 | $this->success('添加成功!');
45 | }
46 |
47 | /**
48 | * 显示指定的资源
49 | * @param $id
50 | */
51 | public function read($id)
52 | {
53 | if (empty($id)) {
54 | $this->error('无效的文章id');
55 | }
56 | $params = $this->request->get();
57 | $params['id'] = $id;
58 | $userId = $this->getUserId();
59 | $postModel = new PortalPostModel();
60 | $dates = $postModel->getUserArticles($userId, $params);
61 | $this->success('请求成功!', $dates);
62 | }
63 |
64 | /**
65 | * 保存更新的资源
66 | * @param $id
67 | */
68 | public function update($id)
69 | {
70 | $data = $this->request->put();
71 | $result = $this->validate($data, 'Articles.article');
72 | if ($result !== true) {
73 | $this->error($result);
74 | }
75 | if (empty($id)) {
76 | $this->error('无效的文章id');
77 | }
78 | $postModel = new PortalPostModel();
79 | $result = $postModel->editArticle($data, $id, $this->getUserId());
80 | if ($result === false) {
81 | $this->error('编辑失败!');
82 | } else {
83 | $this->success('编辑成功!');
84 | }
85 | }
86 |
87 | /**
88 | * 删除指定资源
89 | * @param $id
90 | */
91 | public function delete($id)
92 | {
93 | if (empty($id)) {
94 | $this->error('无效的文章id');
95 | }
96 | $postModel = new PortalPostModel();
97 | $result = $postModel->deleteArticle($id, $this->getUserId());
98 | if ($result == -1) {
99 | $this->error('文章已删除');
100 | }
101 | if ($result) {
102 | $this->success('删除成功!');
103 | } else {
104 | $this->error('删除失败!');
105 | }
106 | }
107 |
108 | /**
109 | * 批量删除文章
110 | */
111 | public function deletes()
112 | {
113 | $ids = $this->request->post('ids/a');
114 | if (empty($ids)) {
115 | $this->error('文章id不能为空');
116 | }
117 | $postModel = new PortalPostModel();
118 | $result = $postModel->deleteArticle($ids, $this->getUserId());
119 | if ($result == -1) {
120 | $this->error('文章已删除');
121 | }
122 | if ($result) {
123 | $this->success('删除成功!');
124 | } else {
125 | $this->error('删除失败!');
126 | }
127 | }
128 |
129 | /**
130 | * 我的文章列表
131 | */
132 | public function my()
133 | {
134 | $params = $this->request->get();
135 | $userId = $this->getUserId();
136 | $postModel = new PortalPostModel();
137 | $data = $postModel->getUserArticles($userId, $params);
138 | $this->success('请求成功!', $data);
139 | }
140 | }
--------------------------------------------------------------------------------
/api/portal/controller/UserController.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 | namespace api\portal\controller;
10 |
11 | use api\portal\service\PortalPostService;
12 | use cmf\controller\RestBaseController;
13 |
14 | class UserController extends RestBaseController
15 | {
16 | /**
17 | * 会员文章列表
18 | * @throws \think\db\exception\DataNotFoundException
19 | * @throws \think\db\exception\ModelNotFoundException
20 | * @throws \think\exception\DbException
21 | */
22 | public function articles()
23 | {
24 | $userId = $this->request->param('user_id', 0, 'intval');
25 |
26 | if (empty($userId)) {
27 | $this->error('用户id不能空!');
28 | }
29 |
30 | $param = $this->request->param();
31 | $param['user_id'] = $userId;
32 | $portalPostService = new PortalPostService();
33 | $articles = $portalPostService->postArticles($param);
34 | if ($articles->isEmpty()) {
35 | $this->error('没有数据');
36 | } else {
37 | $this->success('ok', ['list' => $articles]);
38 | }
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/api/portal/model/PortalCategoryModel.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 |
10 | namespace api\portal\model;
11 |
12 | use think\Model;
13 |
14 | class PortalCategoryModel extends Model
15 | {
16 | /**
17 | * 模型名称
18 | * @var string
19 | */
20 | protected $name = 'portal_category';
21 |
22 | //类型转换
23 | protected $type = [
24 | 'more' => 'array',
25 | ];
26 |
27 |
28 | //模型关联方法
29 | protected $relationFilter = ['articles'];
30 |
31 |
32 | /**
33 | * more 自动转化
34 | * @param $value
35 | * @return array
36 | */
37 | public function getMoreAttr($value)
38 | {
39 | $more = json_decode($value, true);
40 | if (!empty($more['thumbnail'])) {
41 | $more['thumbnail'] = cmf_get_image_url($more['thumbnail']);
42 | }
43 |
44 | if (!empty($more['photos'])) {
45 | foreach ($more['photos'] as $key => $value) {
46 | $more['photos'][$key]['url'] = cmf_get_image_url($value['url']);
47 | }
48 | }
49 | return $more;
50 | }
51 |
52 | /**
53 | * 关联文章表
54 | * @return \think\model\relation\BelongsToMany
55 | */
56 | public function articles()
57 | {
58 | return $this->belongsToMany('PortalPostModel', 'portal_category_post', 'post_id', 'category_id');
59 | }
60 |
61 | /**
62 | * 关联文章分类和文章表
63 | * @return \think\model\relation\HasMany
64 | */
65 | public function PostIds()
66 | {
67 | return $this->hasMany('PortalCategoryPostModel', 'category_id', 'id');
68 | }
69 |
70 | /**
71 | * 此类文章id数组
72 | * @param string $category_id 分类di
73 | * @return array|string|Model|null
74 | * @throws \think\db\exception\DataNotFoundException
75 | * @throws \think\db\exception\ModelNotFoundException
76 | * @throws \think\exception\DbException
77 | */
78 | public static function categoryPostIds($category_id)
79 | {
80 | $ids = [];
81 | $post_ids = self::relation('PostIds')->field(true)->where('id', $category_id)->find();
82 | foreach ($post_ids['PostIds'] as $key => $id) {
83 | $ids[] = $id['post_id'];
84 | }
85 | $post_ids['PostIds'] = $ids;
86 | return $post_ids;
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/api/portal/model/PortalCategoryPostModel.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | namespace api\portal\model;
12 |
13 | use think\Model;
14 |
15 | class PortalCategoryPostModel extends Model
16 | {
17 |
18 | /**
19 | * 模型名称
20 | * @var string
21 | */
22 | protected $name = 'portal_category_post';
23 |
24 | /**
25 | * 基础查询
26 | */
27 | protected function base($query)
28 | {
29 | $query->where('status', 1);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/api/portal/model/PortalTagModel.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 |
10 | namespace api\portal\model;
11 |
12 | use think\Model;
13 |
14 | class PortalTagModel extends Model
15 | {
16 | /**
17 | * 模型名称
18 | * @var string
19 | */
20 | protected $name = 'portal_tag';
21 |
22 | /**
23 | * 关联 文章表
24 | * @return \think\model\relation\BelongsToMany
25 | */
26 | public function articles()
27 | {
28 | return $this->belongsToMany('PortalPostModel','portal_tag_post','post_id','tag_id')->alias('post');
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/api/portal/model/PortalTagPostModel.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 |
10 | namespace api\portal\model;
11 |
12 | use think\Model;
13 |
14 | class PortalTagPostModel extends Model
15 | {
16 | /**
17 | * 模型名称
18 | * @var string
19 | */
20 | protected $name = 'portal_tag_post';
21 |
22 | /**
23 | * 获取指定id相关的文章id数组
24 | * @param $post_id 文章id
25 | * @return array 相关的文章id
26 | */
27 | function getRelationPostIds($post_id)
28 | {
29 | $tagIds = $this->where('post_id', $post_id)
30 | ->column('tag_id');
31 | $postIds = $this->whereIn('tag_id', $tagIds)
32 | ->column('post_id');
33 | return array_unique($postIds);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/api/portal/model/RecycleBinModel.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 | namespace api\portal\model;
10 |
11 | use think\Model;
12 |
13 | class RecycleBinModel extends Model
14 | {
15 | /**
16 | * 模型名称
17 | * @var string
18 | */
19 | protected $name = 'recycle_bin';
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/api/portal/model/UserModel.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 |
10 | namespace api\portal\model;
11 |
12 |
13 | use think\Model;
14 |
15 | class UserModel extends Model
16 | {
17 | /**
18 | * 模型名称
19 | * @var string
20 | */
21 | protected $name = 'user';
22 |
23 | //模型关联方法
24 | protected $relationFilter = ['user'];
25 |
26 |
27 | /**
28 | * more 自动转化
29 | * @param $value
30 | * @return string
31 | */
32 | public function getAvatarAttr($value)
33 | {
34 | $value = !empty($value) ? cmf_get_image_url($value) : $value;
35 | return $value;
36 | }
37 |
38 | /**
39 | * 关联 user表
40 | * @return string 关联数据
41 | */
42 | public function user()
43 | {
44 | return $this->belongsTo('UserModel', 'user_id')->setEagerlyType(1);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/api/portal/route.php:
--------------------------------------------------------------------------------
1 |
8 | // | Date: 2019/01/08
9 | // | Time:上午 10:32
10 | // +----------------------------------------------------------------------
11 |
12 |
13 | namespace api\portal\service;
14 |
15 |
16 | use api\portal\model\PortalCategoryModel;
17 | use think\db\Query;
18 |
19 | class PortalCategoryService
20 | {
21 | /**
22 | * @param $filter
23 | * @return array|\PDOStatement|string|\think\Collection
24 | * @throws \think\db\exception\DataNotFoundException
25 | * @throws \think\db\exception\ModelNotFoundException
26 | * @throws \think\exception\DbException
27 | */
28 | public function categories($filter)
29 | {
30 | $categoryModel = new PortalCategoryModel();
31 | //条件分解
32 | $field = empty($filter['field']) ? '*' : $filter['field'];
33 | $order = empty($filter['order']) ? ['-id'] : explode(',', $filter['order']);
34 | $page = empty($filter['page']) ? '' : $filter['page'];
35 | $limit = empty($filter['limit']) ? '' : $filter['limit'];
36 | if (!empty($page)) {
37 | $categoryModel = $categoryModel->page($page);
38 | } elseif (!empty($limit)) {
39 | $categoryModel = $categoryModel->limit($limit);
40 | } else {
41 | $categoryModel = $categoryModel->limit(10);
42 | }
43 | //转化-+为desc、asc
44 | $orderArr = order_shift($order);
45 |
46 | $result = $categoryModel
47 | ->field($field)
48 | ->where('delete_time', 0)
49 | ->where('status', 1)
50 | ->where(function (Query $query) use ($filter) {
51 | if (!empty($filter['ids'])) {
52 | $query->where('id', 'in', $filter['ids']);
53 | }
54 | })
55 | ->order($orderArr)
56 | ->select();
57 | return $result;
58 | }
59 | }
--------------------------------------------------------------------------------
/api/portal/service/PortalPostService.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 | namespace api\portal\service;
10 |
11 | use api\portal\model\PortalPostModel;
12 | use think\db\Query;
13 |
14 | class PortalPostService
15 | {
16 | //模型关联方法
17 | protected $relationFilter = ['user'];
18 |
19 | /**
20 | * 文章列表
21 | * @param $filter
22 | * @param bool $isPage
23 | * @return array|string|\think\Collection
24 | * @throws \think\db\exception\DataNotFoundException
25 | * @throws \think\db\exception\ModelNotFoundException
26 | * @throws \think\exception\DbException
27 | */
28 | public function postArticles($filter, $isPage = false)
29 | {
30 | $join = [];
31 |
32 | $field = empty($filter['field']) ? 'a.*' : explode(',', $filter['field']);
33 | //转为查询条件
34 | if (is_array($field)) {
35 | foreach ($field as $key => $value) {
36 | $field[$key] = 'a.' . $value;
37 | }
38 | $field = implode(',', $field);
39 | }
40 | $page = empty($filter['page']) ? '' : $filter['page'];
41 | $limit = empty($filter['limit']) ? '' : $filter['limit'];
42 | $order = empty($filter['order']) ? ['-update_time'] : explode(',', $filter['order']);
43 | $category = empty($filter['category_id']) ? 0 : intval($filter['category_id']);
44 | if (!empty($category)) {
45 | array_push($join, ['__PORTAL_CATEGORY_POST__ b', 'a.id = b.post_id']);
46 | $field = $field.',b.id AS post_category_id,b.list_order,b.category_id';
47 | }
48 |
49 | $orderArr = order_shift($order);
50 |
51 | $portalPostModel = new PortalPostModel();
52 |
53 |
54 | if (!empty($page)) {
55 | $portalPostModel = $portalPostModel->page($page);
56 | } elseif (!empty($limit)) {
57 | $portalPostModel = $portalPostModel->limit($limit);
58 | } else {
59 | $portalPostModel = $portalPostModel->limit(10);
60 | }
61 |
62 | $articles = $portalPostModel
63 | ->alias('a')
64 | ->field($field)
65 | ->join($join)
66 | ->where('a.create_time', '>=', 0)
67 | ->where('a.delete_time', 0)
68 | ->where('a.post_status', 1)
69 | ->where(function (Query $query) use ($filter, $isPage) {
70 | if (!empty($filter['user_id'])) {
71 | $query->where('a.user_id', $filter['user_id']);
72 | }
73 | $category = empty($filter['category_id']) ? 0 : intval($filter['category_id']);
74 | if (!empty($category)) {
75 | $query->where('b.category_id', $category);
76 | }
77 | $startTime = empty($filter['start_time']) ? 0 : strtotime($filter['start_time']);
78 | $endTime = empty($filter['end_time']) ? 0 : strtotime($filter['end_time']);
79 | if (!empty($startTime)) {
80 | $query->where('a.published_time', '>=', $startTime);
81 | }
82 | if (!empty($endTime)) {
83 | $query->where('a.published_time', '<=', $endTime);
84 | }
85 | $keyword = empty($filter['keyword']) ? '' : $filter['keyword'];
86 | if (!empty($keyword)) {
87 | $query->where('a.post_title', 'like', "%$keyword%");
88 | }
89 | if ($isPage) {
90 | $query->where('a.post_type', 2);
91 | } else {
92 | $query->where('a.post_type', 1);
93 | }
94 | if (!empty($filter['recommended'])) {
95 | $query->where('a.recommended', 1);
96 | }
97 | if (!empty($filter['ids'])) {
98 | $ids = str_to_arr($filter['ids']);
99 | $query->where('a.id', 'in', $ids);
100 | }
101 | })
102 | ->order($orderArr)
103 | ->select();
104 |
105 | return $articles;
106 | }
107 |
108 | }
109 |
--------------------------------------------------------------------------------
/api/portal/service/PortalTagService.php:
--------------------------------------------------------------------------------
1 |
8 | // | Date: 2019/01/09
9 | // | Time:下午 06:10
10 | // +----------------------------------------------------------------------
11 |
12 |
13 | namespace api\portal\service;
14 |
15 |
16 | use api\portal\model\PortalPostModel;
17 | use api\portal\model\PortalTagModel;
18 | use think\db\Query;
19 |
20 | class PortalTagService
21 | {
22 | /**
23 | * 获取标签列表
24 | * @param array $filter 参数
25 | * @return array|\PDOStatement|string|\think\Collection
26 | * @throws \think\db\exception\DataNotFoundException
27 | * @throws \think\db\exception\ModelNotFoundException
28 | * @throws \think\exception\DbException
29 | */
30 | public function tagList($filter)
31 | {
32 | $field = empty($filter['field']) ? '*' : $filter['field'];
33 | $page = empty($filter['page']) ? '' : $filter['page'];
34 | $limit = empty($filter['limit']) ? '' : $filter['limit'];
35 | $order = empty($filter['order']) ? ['-id'] : explode(',', $filter['order']);
36 | $orderArr = order_shift($order);
37 | $tagModel = new PortalTagModel();
38 | if (!empty($page)) {
39 | $tagModel = $tagModel->page($page);
40 | } elseif (!empty($limit)) {
41 | $tagModel = $tagModel->limit($limit);
42 | } else {
43 | $tagModel = $tagModel->limit(10);
44 | }
45 |
46 | $result = $tagModel
47 | ->field($field)
48 | ->where('status', 1)
49 | ->where(function (Query $query) use ($filter) {
50 | if (!empty($filter['id'])) {
51 | $query->where('id', $filter['id']);
52 | }
53 | })
54 | ->order($orderArr)
55 | ->select();
56 | return $result;
57 | }
58 |
59 | /**
60 | * @param $filter
61 | * @return array|\PDOStatement|string|\think\Model|null
62 | * @throws \think\db\exception\DataNotFoundException
63 | * @throws \think\db\exception\ModelNotFoundException
64 | * @throws \think\exception\DbException
65 | */
66 | public function portalTagArticles($filter)
67 | {
68 | $tagModel = new PortalTagModel();
69 | $tag = $tagModel
70 | ->with([
71 | 'articles' => function (Query $query) use ($filter) {
72 | $field = empty($filter['field']) ? 'post.*' : explode(',', $filter['field']);
73 | //转为查询条件
74 | if (is_array($field)) {
75 | foreach ($field as $key => $value) {
76 | $field[$key] = 'post.' . $value;
77 | }
78 | $field = implode(',', $field);
79 | }
80 | $page = empty($filter['page']) ? '' : $filter['page'];
81 | $limit = empty($filter['limit']) ? '10' : $filter['limit'];
82 | $order = empty($filter['order']) ? ['-post.id'] : explode(',', $filter['order']);
83 | $orderArr = order_shift($order);
84 | $query->field($field);
85 | if (!empty($page)) {
86 | $query->page($page);
87 | } elseif (!empty($limit)) {
88 | $query->limit($limit);
89 | } else {
90 | $query->limit(10);
91 | }
92 | $query->order($orderArr);
93 | $query->hidden(['pivot']);
94 | }
95 | ])
96 | ->where('id', $filter['id'])
97 | ->find();
98 | return $tag;
99 | }
100 | }
--------------------------------------------------------------------------------
/api/portal/validate/ArticlesValidate.php:
--------------------------------------------------------------------------------
1 |
10 | // | Date: 2019/01/11
11 | // | Time:下午 03:24
12 | // +----------------------------------------------------------------------
13 | namespace api\portal\validate;
14 |
15 | use think\Validate;
16 |
17 | class ArticlesValidate extends Validate
18 | {
19 | protected $rule = [
20 | 'post_title' => 'require',
21 | 'post_content' => 'require',
22 | 'categories' => 'require'
23 | ];
24 | protected $message = [
25 | 'post_title.require' => '文章标题不能为空',
26 | 'post_content.require' => '内容不能为空',
27 | 'categories.require' => '文章分类不能为空'
28 | ];
29 |
30 | protected $scene = [
31 | 'article' => [ 'post_title' , 'post_content' , 'categories' ],
32 | 'page' => ['post_title']
33 | ];
34 | }
--------------------------------------------------------------------------------
/app/portal/PortalApp.php:
--------------------------------------------------------------------------------
1 |
8 | // +----------------------------------------------------------------------
9 |
10 | namespace app\portal;
11 |
12 | //Demo应用英文名,改成你的应用英文就行了
13 | class PortalApp
14 | {
15 |
16 | // 应用安装
17 | public function install()
18 | {
19 | return true; //安装成功返回true,失败false
20 | }
21 |
22 | // 应用卸载
23 | public function uninstall()
24 | {
25 | return true; //卸载成功返回true,失败false
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/app/portal/api/CategoryApi.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | namespace app\portal\api;
12 |
13 | use app\portal\model\PortalCategoryModel;
14 | use think\db\Query;
15 |
16 | class CategoryApi
17 | {
18 | /**
19 | * 分类列表 用于模板设计
20 | * @param array $param
21 | * @return false|\PDOStatement|string|\think\Collection
22 | * @throws \think\db\exception\DataNotFoundException
23 | * @throws \think\db\exception\ModelNotFoundException
24 | * @throws \think\exception\DbException
25 | */
26 | public function index($param = [])
27 | {
28 | $portalCategoryModel = new PortalCategoryModel();
29 |
30 | $where = ['delete_time' => 0];
31 |
32 | //返回的数据必须是数据集或数组,item里必须包括id,name,如果想表示层级关系请加上 parent_id
33 | return $portalCategoryModel->where($where)
34 | ->where(function (Query $query) use ($param) {
35 | if (!empty($param['keyword'])) {
36 | $query->where('name', 'like', "%{$param['keyword']}%");
37 | }
38 | })->select();
39 | }
40 |
41 | /**
42 | * 分类列表 用于导航选择
43 | * @return array
44 | */
45 | public function nav()
46 | {
47 | $portalCategoryModel = new PortalCategoryModel();
48 |
49 | $where = ['delete_time' => 0];
50 |
51 | $categories = $portalCategoryModel->where($where)->select();
52 |
53 | $return = [
54 | //'name' => '文章分类',
55 | 'rule' => [
56 | 'action' => 'portal/List/index',
57 | 'param' => [
58 | 'id' => 'id'
59 | ]
60 | ],//url规则
61 | 'items' => $categories //每个子项item里必须包括id,name,如果想表示层级关系请加上 parent_id
62 | ];
63 |
64 | return $return;
65 | }
66 |
67 | }
--------------------------------------------------------------------------------
/app/portal/api/PageApi.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | namespace app\portal\api;
12 |
13 | use app\portal\model\PortalPostModel;
14 | use think\db\Query;
15 |
16 | class PageApi
17 | {
18 | /**
19 | * 页面列表 用于模板设计
20 | * @param array $param
21 | * @return false|\PDOStatement|string|\think\Collection
22 | */
23 | public function index($param = [])
24 | {
25 | $portalPostModel = new PortalPostModel();
26 |
27 | $where = [
28 | 'post_type' => 2,
29 | 'post_status' => 1,
30 | 'delete_time' => 0
31 | ];
32 |
33 | //返回的数据必须是数据集或数组,item里必须包括id,name,如果想表示层级关系请加上 parent_id
34 | return $portalPostModel->field('id,post_title AS name')
35 | ->where($where)
36 | ->where('published_time', '<', time())
37 | ->where('published_time', '>', 0)
38 | ->where(function (Query $query) use ($param) {
39 | if (!empty($param['keyword'])) {
40 | $query->where('post_title', 'like', "%{$param['keyword']}%");
41 | }
42 | })->select();
43 | }
44 |
45 | /**
46 | * 页面列表 用于导航选择
47 | * @return array
48 | */
49 | public function nav()
50 | {
51 | $portalPostModel = new PortalPostModel();
52 |
53 | $where = [
54 | 'post_type' => 2,
55 | 'post_status' => 1,
56 | 'delete_time' => 0
57 | ];
58 |
59 |
60 | $pages = $portalPostModel->field('id,post_title AS name')
61 | ->where('published_time', '<', time())
62 | ->where('published_time', '>', 0)
63 | ->where($where)->select();
64 |
65 | $return = [
66 | 'rule' => [
67 | 'action' => 'portal/Page/index',
68 | 'param' => [
69 | 'id' => 'id'
70 | ]
71 | ],//url规则
72 | 'items' => $pages //每个子项item里必须包括id,name,如果想表示层级关系请加上 parent_id
73 | ];
74 |
75 | return $return;
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/app/portal/controller/AdminIndexController.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | namespace app\portal\controller;
12 |
13 | use cmf\controller\AdminBaseController;
14 |
15 | /**
16 | * Class AdminIndexController
17 | * @package app\portal\controller
18 | * @adminMenuRoot(
19 | * 'name' =>'门户管理',
20 | * 'action' =>'default',
21 | * 'parent' =>'',
22 | * 'display'=> true,
23 | * 'order' => 30,
24 | * 'icon' =>'th',
25 | * 'remark' =>'门户管理'
26 | * )
27 | */
28 | class AdminIndexController extends AdminBaseController
29 | {
30 |
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/app/portal/controller/AdminTagController.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | namespace app\portal\controller;
12 |
13 | use app\portal\model\PortalTagModel;
14 | use app\portal\model\PortalTagPostModel;
15 | use cmf\controller\AdminBaseController;
16 |
17 | /**
18 | * Class AdminTagController 标签管理控制器
19 | * @package app\portal\controller
20 | */
21 | class AdminTagController extends AdminBaseController
22 | {
23 | /**
24 | * 文章标签管理
25 | * @adminMenu(
26 | * 'name' => '文章标签',
27 | * 'parent' => 'portal/AdminIndex/default',
28 | * 'display'=> true,
29 | * 'hasView'=> true,
30 | * 'order' => 10000,
31 | * 'icon' => '',
32 | * 'remark' => '文章标签',
33 | * 'param' => ''
34 | * )
35 | */
36 | public function index()
37 | {
38 | $content = hook_one('portal_admin_tag_index_view');
39 |
40 | if (!empty($content)) {
41 | return $content;
42 | }
43 |
44 | $portalTagModel = new PortalTagModel();
45 | $tags = $portalTagModel->paginate();
46 |
47 | $this->assign("arrStatus", $portalTagModel::$STATUS);
48 | $this->assign("tags", $tags);
49 | $this->assign('page', $tags->render());
50 | return $this->fetch();
51 | }
52 |
53 | /**
54 | * 添加文章标签
55 | * @adminMenu(
56 | * 'name' => '添加文章标签',
57 | * 'parent' => 'index',
58 | * 'display'=> false,
59 | * 'hasView'=> true,
60 | * 'order' => 10000,
61 | * 'icon' => '',
62 | * 'remark' => '添加文章标签',
63 | * 'param' => ''
64 | * )
65 | */
66 | public function add()
67 | {
68 | $portalTagModel = new PortalTagModel();
69 | $this->assign("arrStatus", $portalTagModel::$STATUS);
70 | return $this->fetch();
71 | }
72 |
73 | /**
74 | * 添加文章标签提交
75 | * @adminMenu(
76 | * 'name' => '添加文章标签提交',
77 | * 'parent' => 'index',
78 | * 'display'=> false,
79 | * 'hasView'=> false,
80 | * 'order' => 10000,
81 | * 'icon' => '',
82 | * 'remark' => '添加文章标签提交',
83 | * 'param' => ''
84 | * )
85 | */
86 | public function addPost()
87 | {
88 |
89 | $arrData = $this->request->param();
90 |
91 | $portalTagModel = new PortalTagModel();
92 | $portalTagModel->isUpdate(false)->allowField(true)->save($arrData);
93 |
94 | $this->success(lang("SAVE_SUCCESS"));
95 |
96 | }
97 |
98 | /**
99 | * 更新文章标签状态
100 | * @adminMenu(
101 | * 'name' => '更新标签状态',
102 | * 'parent' => 'index',
103 | * 'display'=> false,
104 | * 'hasView'=> false,
105 | * 'order' => 10000,
106 | * 'icon' => '',
107 | * 'remark' => '更新标签状态',
108 | * 'param' => ''
109 | * )
110 | */
111 | public function upStatus()
112 | {
113 | $intId = $this->request->param("id");
114 | $intStatus = $this->request->param("status");
115 | $intStatus = $intStatus ? 1 : 0;
116 | if (empty($intId)) {
117 | $this->error(lang("NO_ID"));
118 | }
119 |
120 | $portalTagModel = new PortalTagModel();
121 | $portalTagModel->where("id", $intId)->update(["status" => $intStatus]);
122 |
123 | $this->success(lang("SAVE_SUCCESS"));
124 |
125 | }
126 |
127 | /**
128 | * 删除文章标签
129 | * @adminMenu(
130 | * 'name' => '删除文章标签',
131 | * 'parent' => 'index',
132 | * 'display'=> false,
133 | * 'hasView'=> false,
134 | * 'order' => 10000,
135 | * 'icon' => '',
136 | * 'remark' => '删除文章标签',
137 | * 'param' => ''
138 | * )
139 | */
140 | public function delete()
141 | {
142 | $intId = $this->request->param("id", 0, 'intval');
143 |
144 | if (empty($intId)) {
145 | $this->error(lang("NO_ID"));
146 | }
147 |
148 | PortalTagModel::where('id', $intId)->delete();
149 | PortalTagPostModel::where('tag_id', $intId)->delete();
150 | $this->success(lang("DELETE_SUCCESS"));
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/app/portal/controller/ArticleController.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | namespace app\portal\controller;
12 |
13 | use cmf\controller\HomeBaseController;
14 | use app\portal\model\PortalCategoryModel;
15 | use app\portal\service\PostService;
16 | use app\portal\model\PortalPostModel;
17 |
18 | class ArticleController extends HomeBaseController
19 | {
20 | /**
21 | * 文章详情
22 | * @return mixed
23 | * @throws \think\Exception
24 | * @throws \think\db\exception\DataNotFoundException
25 | * @throws \think\db\exception\ModelNotFoundException
26 | * @throws \think\exception\DbException
27 | */
28 | public function index()
29 | {
30 |
31 | $portalCategoryModel = new PortalCategoryModel();
32 | $postService = new PostService();
33 |
34 | $articleId = $this->request->param('id', 0, 'intval');
35 | $categoryId = $this->request->param('cid', 0, 'intval');
36 | $article = $postService->publishedArticle($articleId, $categoryId);
37 |
38 | if (empty($article)) {
39 | abort(404, '文章不存在!');
40 | }
41 |
42 |
43 | $prevArticle = $postService->publishedPrevArticle($articleId, $categoryId);
44 | $nextArticle = $postService->publishedNextArticle($articleId, $categoryId);
45 |
46 | $tplName = 'article';
47 |
48 | if (empty($categoryId)) {
49 | $categories = $article['categories'];
50 |
51 | if (count($categories) > 0) {
52 | $this->assign('category', $categories[0]);
53 | } else {
54 | abort(404, '文章未指定分类!');
55 | }
56 |
57 | } else {
58 | $category = $portalCategoryModel->where('id', $categoryId)->where('status', 1)->find();
59 |
60 | if (empty($category)) {
61 | abort(404, '文章不存在!');
62 | }
63 |
64 | $this->assign('category', $category);
65 |
66 | $tplName = empty($category["one_tpl"]) ? $tplName : $category["one_tpl"];
67 | }
68 |
69 | PortalPostModel::where('id', $articleId)->inc('post_hits')->update();
70 |
71 |
72 | hook('portal_before_assign_article', $article);
73 |
74 | $this->assign('article', $article);
75 | $this->assign('prev_article', $prevArticle);
76 | $this->assign('next_article', $nextArticle);
77 |
78 | $tplName = empty($article['more']['template']) ? $tplName : $article['more']['template'];
79 |
80 | return $this->fetch("/$tplName");
81 | }
82 |
83 | // 文章点赞
84 | public function doLike()
85 | {
86 | $this->checkUserLogin();
87 | $articleId = $this->request->param('id', 0, 'intval');
88 |
89 |
90 | $canLike = cmf_check_user_action("posts$articleId", 1);
91 |
92 | if ($canLike) {
93 | PortalPostModel::where('id', $articleId)->inc('post_like')->update();
94 |
95 | $this->success("赞好啦!");
96 | } else {
97 | $this->error("您已赞过啦!");
98 | }
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/app/portal/controller/IndexController.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | namespace app\portal\controller;
12 |
13 | use cmf\controller\HomeBaseController;
14 |
15 | class IndexController extends HomeBaseController
16 | {
17 | public function index()
18 | {
19 | return $this->fetch(':index');
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/portal/controller/ListController.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | namespace app\portal\controller;
12 |
13 | use cmf\controller\HomeBaseController;
14 | use app\portal\model\PortalCategoryModel;
15 |
16 | class ListController extends HomeBaseController
17 | {
18 | /***
19 | * 文章列表
20 | * @return mixed
21 | * @throws \think\db\exception\DataNotFoundException
22 | * @throws \think\db\exception\ModelNotFoundException
23 | * @throws \think\exception\DbException
24 | */
25 | public function index()
26 | {
27 | $id = $this->request->param('id', 0, 'intval');
28 | $portalCategoryModel = new PortalCategoryModel();
29 |
30 | $category = $portalCategoryModel->where('id', $id)->where('status', 1)->find();
31 |
32 | $this->assign('category', $category);
33 |
34 | $listTpl = empty($category['list_tpl']) ? 'list' : $category['list_tpl'];
35 |
36 | return $this->fetch('/' . $listTpl);
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/app/portal/controller/PageController.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | namespace app\portal\controller;
12 |
13 | use cmf\controller\HomeBaseController;
14 | use app\portal\service\PostService;
15 |
16 | class PageController extends HomeBaseController
17 | {
18 | /**
19 | * 页面管理
20 | * @return mixed
21 | * @throws \think\db\exception\DataNotFoundException
22 | * @throws \think\db\exception\ModelNotFoundException
23 | * @throws \think\exception\DbException
24 | */
25 | public function index()
26 | {
27 | $postService = new PostService();
28 | $pageId = $this->request->param('id', 0, 'intval');
29 | $page = $postService->publishedPage($pageId);
30 |
31 | if (empty($page)) {
32 | abort(404, ' 页面不存在!');
33 | }
34 |
35 | $this->assign('page', $page);
36 |
37 | $more = $page['more'];
38 |
39 | $tplName = empty($more['template']) ? 'page' : $more['template'];
40 |
41 | return $this->fetch("/$tplName");
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/app/portal/controller/SearchController.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | namespace app\portal\controller;
12 |
13 | use cmf\controller\HomeBaseController;
14 |
15 | class SearchController extends HomeBaseController
16 | {
17 | /**
18 | * 搜索
19 | * @return mixed
20 | */
21 | public function index()
22 | {
23 | $keyword = $this->request->param('keyword');
24 |
25 | if (empty($keyword)) {
26 | $this -> error("关键词不能为空!请重新输入!");
27 | }
28 |
29 | $this -> assign("keyword", $keyword);
30 | return $this->fetch('/search');
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/portal/controller/TagController.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | namespace app\portal\controller;
12 |
13 | use cmf\controller\HomeBaseController;
14 | use app\portal\model\PortalTagModel;
15 |
16 | class TagController extends HomeBaseController
17 | {
18 | /**
19 | * 标签
20 | * @return mixed
21 | * @throws \think\db\exception\DataNotFoundException
22 | * @throws \think\db\exception\ModelNotFoundException
23 | * @throws \think\exception\DbException
24 | */
25 | public function index()
26 | {
27 | $id = $this->request->param('id');
28 |
29 | $portalTagModel = new PortalTagModel();
30 |
31 | if(is_numeric($id)){
32 | $tag = $portalTagModel->where('id', $id)->where('status', 1)->find();
33 | }else{
34 | $tag = $portalTagModel->where('name', $id)->where('status', 1)->find();
35 | }
36 |
37 |
38 | if (empty($tag)) {
39 | abort(404, '标签不存在!');
40 | }
41 |
42 | $this->assign('tag', $tag);
43 |
44 | return $this->fetch('/tag');
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/app/portal/data/portal.sql:
--------------------------------------------------------------------------------
1 |
2 | --
3 | -- 表的结构 `cmf_portal_category`
4 | --
5 |
6 | CREATE TABLE IF NOT EXISTS `cmf_portal_category` (
7 | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '分类id',
8 | `parent_id` bigint(20) UNSIGNED NOT NULL DEFAULT '0' COMMENT '分类父id',
9 | `post_count` bigint(20) UNSIGNED NOT NULL DEFAULT '0' COMMENT '分类文章数',
10 | `status` tinyint(3) UNSIGNED NOT NULL DEFAULT '1' COMMENT '状态,1:发布,0:不发布',
11 | `delete_time` int(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '删除时间',
12 | `list_order` float NOT NULL DEFAULT '10000' COMMENT '排序',
13 | `name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '分类名称',
14 | `description` varchar(255) NOT NULL DEFAULT '' COMMENT '分类描述',
15 | `path` varchar(255) NOT NULL DEFAULT '' COMMENT '分类层级关系路径',
16 | `seo_title` varchar(100) NOT NULL DEFAULT '',
17 | `seo_keywords` varchar(255) NOT NULL DEFAULT '',
18 | `seo_description` varchar(255) NOT NULL DEFAULT '',
19 | `list_tpl` varchar(50) NOT NULL DEFAULT '' COMMENT '分类列表模板',
20 | `one_tpl` varchar(50) NOT NULL DEFAULT '' COMMENT '分类文章页模板',
21 | `more` text COMMENT '扩展属性',
22 | PRIMARY KEY (`id`)
23 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='portal应用 文章分类表';
24 |
25 | -- --------------------------------------------------------
26 |
27 | --
28 | -- 表的结构 `cmf_portal_category_post`
29 | --
30 |
31 | CREATE TABLE IF NOT EXISTS `cmf_portal_category_post` (
32 | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
33 | `post_id` bigint(20) UNSIGNED NOT NULL DEFAULT '0' COMMENT '文章id',
34 | `category_id` bigint(20) UNSIGNED NOT NULL DEFAULT '0' COMMENT '分类id',
35 | `list_order` float NOT NULL DEFAULT '10000' COMMENT '排序',
36 | `status` tinyint(3) UNSIGNED NOT NULL DEFAULT '1' COMMENT '状态,1:发布;0:不发布',
37 | PRIMARY KEY (`id`),
38 | KEY `term_taxonomy_id` (`category_id`)
39 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='portal应用 分类文章对应表';
40 |
41 | -- --------------------------------------------------------
42 |
43 | --
44 | -- 表的结构 `cmf_portal_post`
45 | --
46 |
47 | CREATE TABLE IF NOT EXISTS `cmf_portal_post` (
48 | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
49 | `parent_id` bigint(20) UNSIGNED NOT NULL DEFAULT '0' COMMENT '父级id',
50 | `post_type` tinyint(3) UNSIGNED NOT NULL DEFAULT '1' COMMENT '类型,1:文章;2:页面',
51 | `post_format` tinyint(3) UNSIGNED NOT NULL DEFAULT '1' COMMENT '内容格式;1:html;2:md',
52 | `user_id` bigint(20) UNSIGNED NOT NULL DEFAULT '0' COMMENT '发表者用户id',
53 | `post_status` tinyint(3) UNSIGNED NOT NULL DEFAULT '1' COMMENT '状态;1:已发布;0:未发布;',
54 | `comment_status` tinyint(3) UNSIGNED NOT NULL DEFAULT '1' COMMENT '评论状态;1:允许;0:不允许',
55 | `is_top` tinyint(3) UNSIGNED NOT NULL DEFAULT '0' COMMENT '是否置顶;1:置顶;0:不置顶',
56 | `recommended` tinyint(3) UNSIGNED NOT NULL DEFAULT '0' COMMENT '是否推荐;1:推荐;0:不推荐',
57 | `post_hits` bigint(20) UNSIGNED NOT NULL DEFAULT '0' COMMENT '查看数',
58 | `post_like` bigint(20) UNSIGNED NOT NULL DEFAULT '0' COMMENT '点赞数',
59 | `comment_count` bigint(20) UNSIGNED NOT NULL DEFAULT '0' COMMENT '评论数',
60 | `create_time` int(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '创建时间',
61 | `update_time` int(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '更新时间',
62 | `published_time` int(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '发布时间',
63 | `delete_time` int(10) UNSIGNED NOT NULL DEFAULT '0' COMMENT '删除时间',
64 | `post_title` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT 'post标题',
65 | `post_keywords` varchar(150) NOT NULL DEFAULT '' COMMENT 'seo keywords',
66 | `post_excerpt` varchar(500) NOT NULL DEFAULT '' COMMENT 'post摘要',
67 | `post_source` varchar(150) NOT NULL DEFAULT '' COMMENT '转载文章的来源',
68 | `post_content` text COMMENT '文章内容',
69 | `post_content_filtered` text COMMENT '处理过的文章内容',
70 | `more` text COMMENT '扩展属性,如缩略图;格式为json',
71 | PRIMARY KEY (`id`),
72 | KEY `type_status_date` (`post_type`,`post_status`,`create_time`,`id`),
73 | KEY `parent_id` (`parent_id`),
74 | KEY `user_id` (`user_id`),
75 | KEY `create_time` (`create_time`) USING BTREE
76 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='portal应用 文章表' ROW_FORMAT=COMPACT;
77 |
78 | -- --------------------------------------------------------
79 |
80 | --
81 | -- 表的结构 `cmf_portal_tag`
82 | --
83 |
84 | CREATE TABLE IF NOT EXISTS `cmf_portal_tag` (
85 | `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '分类id',
86 | `status` tinyint(3) UNSIGNED NOT NULL DEFAULT '1' COMMENT '状态,1:发布,0:不发布',
87 | `recommended` tinyint(3) UNSIGNED NOT NULL DEFAULT '0' COMMENT '是否推荐;1:推荐;0:不推荐',
88 | `post_count` bigint(20) UNSIGNED NOT NULL DEFAULT '0' COMMENT '标签文章数',
89 | `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '标签名称',
90 | PRIMARY KEY (`id`)
91 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='portal应用 文章标签表';
92 |
93 | -- --------------------------------------------------------
94 |
95 | --
96 | -- 表的结构 `cmf_portal_tag_post`
97 | --
98 |
99 | CREATE TABLE IF NOT EXISTS `cmf_portal_tag_post` (
100 | `id` bigint(20) NOT NULL AUTO_INCREMENT,
101 | `tag_id` bigint(20) UNSIGNED NOT NULL DEFAULT '0' COMMENT '标签 id',
102 | `post_id` bigint(20) UNSIGNED NOT NULL DEFAULT '0' COMMENT '文章 id',
103 | `status` tinyint(3) UNSIGNED NOT NULL DEFAULT '1' COMMENT '状态,1:发布;0:不发布',
104 | PRIMARY KEY (`id`),
105 | KEY `post_id` (`post_id`)
106 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='portal应用 标签文章对应表';
107 |
108 | -- --------------------------------------------------------
109 |
110 |
111 | -- 增缩略图字段
112 | ALTER TABLE `cmf_portal_post` ADD `thumbnail` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '缩略图' AFTER `post_source`;
113 | ALTER TABLE `cmf_portal_post` ADD `post_favorites` INT UNSIGNED NOT NULL DEFAULT '0' COMMENT '收藏数' AFTER `post_hits`;
114 |
--------------------------------------------------------------------------------
/app/portal/hooks.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | return [
12 | 'portal_before_assign_article' => [
13 | "type" => 2,//钩子类型(默认为应用钩子;2:应用钩子;3:模板钩子;4:后台模板钩子)
14 | "name" => '文章显示之前', // 钩子名称
15 | "description" => "文章显示之前", //钩子描述
16 | "once" => 0 // 是否只执行一次
17 | ],
18 | 'portal_admin_after_save_article' => [
19 | "type" => 2,//钩子类型(默认为应用钩子;2:应用钩子;3:模板钩子;4:后台模板钩子)
20 | "name" => '后台文章保存之后', // 钩子名称
21 | "description" => "后台文章保存之后", //钩子描述
22 | "once" => 0 // 是否只执行一次
23 | ],
24 | 'portal_admin_article_index_view' => [
25 | "type" => 2,//钩子类型(默认为应用钩子;2:应用钩子;3:模板钩子;4:后台模板钩子)
26 | "name" => '门户后台文章管理列表界面', // 钩子名称
27 | "description" => "门户后台文章管理列表界面", //钩子描述
28 | "once" => 1 // 是否只执行一次
29 | ],
30 | 'portal_admin_article_add_view' => [
31 | "type" => 2,//钩子类型(默认为应用钩子;2:应用钩子;3:模板钩子;4:后台模板钩子)
32 | "name" => '门户后台文章添加界面', // 钩子名称
33 | "description" => "门户后台文章添加界面", //钩子描述
34 | "once" => 1 // 是否只执行一次
35 | ],
36 | 'portal_admin_article_edit_view' => [
37 | "type" => 2,//钩子类型(默认为应用钩子;2:应用钩子;3:模板钩子;4:后台模板钩子)
38 | "name" => '门户后台文章编辑界面', // 钩子名称
39 | "description" => "门户后台文章编辑界面", //钩子描述
40 | "once" => 1 // 是否只执行一次
41 | ],
42 | 'portal_admin_category_index_view' => [
43 | "type" => 2,//钩子类型(默认为应用钩子;2:应用钩子;3:模板钩子;4:后台模板钩子)
44 | "name" => '门户后台文章分类管理列表界面', // 钩子名称
45 | "description" => "门户后台文章分类管理列表界面", //钩子描述
46 | "once" => 1 // 是否只执行一次
47 | ],
48 | 'portal_admin_category_add_view' => [
49 | "type" => 2,//钩子类型(默认为应用钩子;2:应用钩子;3:模板钩子;4:后台模板钩子)
50 | "name" => '门户后台文章分类添加界面', // 钩子名称
51 | "description" => "门户后台文章分类添加界面", //钩子描述
52 | "once" => 1 // 是否只执行一次
53 | ],
54 | 'portal_admin_category_edit_view' => [
55 | "type" => 2,//钩子类型(默认为应用钩子;2:应用钩子;3:模板钩子;4:后台模板钩子)
56 | "name" => '门户后台文章分类编辑界面', // 钩子名称
57 | "description" => "门户后台文章分类编辑界面", //钩子描述
58 | "once" => 1 // 是否只执行一次
59 | ],
60 | 'portal_admin_page_index_view' => [
61 | "type" => 2,//钩子类型(默认为应用钩子;2:应用钩子;3:模板钩子;4:后台模板钩子)
62 | "name" => '门户后台页面管理列表界面', // 钩子名称
63 | "description" => "门户后台页面管理列表界面", //钩子描述
64 | "once" => 1 // 是否只执行一次
65 | ],
66 | 'portal_admin_page_add_view' => [
67 | "type" => 2,//钩子类型(默认为应用钩子;2:应用钩子;3:模板钩子;4:后台模板钩子)
68 | "name" => '门户后台页面添加界面', // 钩子名称
69 | "description" => "门户后台页面添加界面", //钩子描述
70 | "once" => 1 // 是否只执行一次
71 | ],
72 | 'portal_admin_page_edit_view' => [
73 | "type" => 2,//钩子类型(默认为应用钩子;2:应用钩子;3:模板钩子;4:后台模板钩子)
74 | "name" => '门户后台页面编辑界面', // 钩子名称
75 | "description" => "门户后台页面编辑界面", //钩子描述
76 | "once" => 1 // 是否只执行一次
77 | ],
78 | 'portal_admin_tag_index_view' => [
79 | "type" => 2,//钩子类型(默认为应用钩子;2:应用钩子;3:模板钩子;4:后台模板钩子)
80 | "name" => '门户后台文章标签管理列表界面', // 钩子名称
81 | "description" => "门户后台文章标签管理列表界面", //钩子描述
82 | "once" => 1 // 是否只执行一次
83 | ],
84 | 'portal_admin_article_edit_view_right_sidebar' => [
85 | "type" => 4,//钩子类型(默认为应用钩子;2:应用钩子;3:模板钩子;4:后台模板钩子)
86 | "name" => '门户后台文章添加编辑界面右侧栏', // 钩子名称
87 | "description" => "门户后台文章添加编辑界面右侧栏", //钩子描述
88 | "once" => 0 // 是否只执行一次
89 | ],
90 | 'portal_admin_article_edit_view_main' => [
91 | "type" => 4,//钩子类型(默认为应用钩子;2:应用钩子;3:模板钩子;4:后台模板钩子)
92 | "name" => '门户后台文章添加编辑界面主要内容', // 钩子名称
93 | "description" => "门户后台文章添加编辑界面主要内容", //钩子描述
94 | "once" => 0 // 是否只执行一次
95 | ],
96 | ];
--------------------------------------------------------------------------------
/app/portal/lang/en-us.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | return [
12 | 'ADMIN_CENTER' => 'Admin Center',
13 | ];
--------------------------------------------------------------------------------
/app/portal/lang/en-us/common.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | return [
12 | 'TABLE_PORTAL_CATEGORY' => 'Article Category',
13 | 'TABLE_PORTAL_POST' => 'Article',
14 | 'TABLE_PORTAL_POST#PAGE' => 'Page'
15 | ];
--------------------------------------------------------------------------------
/app/portal/lang/zh-cn.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | return [
12 | 'ADMIN_TAG_ADD' => '添加标签',
13 | 'ADMIN_TAG_DELETE' => '删除标签',
14 | 'ADMIN_TAG_INDEX' => '标签列表',
15 | 'SAVE_SUCCESS' => '保存成功!',
16 | 'DELETE_SUCCESS' => '删除成功!',
17 | 'ADD_SUCCESS' => '添加成功',
18 | 'DELETE_FAILED' => '删除失败',
19 | 'ADD_FAILED' => '添加失败',
20 | ];
21 |
22 |
--------------------------------------------------------------------------------
/app/portal/lang/zh-cn/common.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | return [
12 | 'TABLE_PORTAL_CATEGORY' => '文章分类',
13 | 'TABLE_PORTAL_POST' => '文章',
14 | 'TABLE_SLIDE' => '幻灯片',
15 | 'TABLE_PORTAL_POST#PAGE' => '页面'
16 | ];
--------------------------------------------------------------------------------
/app/portal/lang/zh-cn/home.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | /*前台通用语言包*/
12 | return [
13 | ];
--------------------------------------------------------------------------------
/app/portal/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "门户应用",
3 | "name": "portal",
4 | "version": "1.0.0",
5 | "demo_url": "http://demo.thinkcmf.com",
6 | "author": "ThinkCMF",
7 | "author_url": "http://www.thinkcmf.com",
8 | "keywords": "ThinkCMF portal应用",
9 | "description": "ThinkCMF portal应用"
10 | }
11 |
--------------------------------------------------------------------------------
/app/portal/model/PortalCategoryPostModel.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | namespace app\portal\model;
12 |
13 | use think\Model;
14 |
15 | class PortalCategoryPostModel extends Model
16 | {
17 | /**
18 | * 模型名称
19 | * @var string
20 | */
21 | protected $name = 'portal_category_post';
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/app/portal/model/PortalTagModel.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | namespace app\portal\model;
12 |
13 | use think\Model;
14 |
15 | class PortalTagModel extends Model
16 | {
17 | /**
18 | * 模型名称
19 | * @var string
20 | */
21 | protected $name = 'portal_tag';
22 |
23 | public static $STATUS = array(
24 | 0=>"未启用",
25 | 1=>"已启用",
26 | );
27 | }
--------------------------------------------------------------------------------
/app/portal/model/PortalTagPostModel.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | namespace app\portal\model;
12 |
13 | use think\Model;
14 |
15 | class PortalTagPostModel extends Model
16 | {
17 | /**
18 | * 模型名称
19 | * @var string
20 | */
21 | protected $name = 'portal_tag_post';
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/app/portal/model/RecycleBinModel.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | namespace app\portal\model;
12 |
13 | use think\Model;
14 |
15 | class RecycleBinModel extends Model
16 | {
17 | /**
18 | * 模型名称
19 | * @var string
20 | */
21 | protected $name = 'recycle_bin';
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/app/portal/model/UserModel.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | namespace app\portal\model;
12 |
13 | use think\Model;
14 |
15 | class UserModel extends Model
16 | {
17 |
18 | /**
19 | * 模型名称
20 | * @var string
21 | */
22 | protected $name = 'user';
23 |
24 | protected $type = [
25 | 'more' => 'array',
26 | ];
27 |
28 |
29 | }
--------------------------------------------------------------------------------
/app/portal/nav.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | return [
12 | ['name' => '文章分类', 'api' => "Category/nav"],
13 | ['name' => '所有页面', 'api' => "Page/nav"]
14 | ];
--------------------------------------------------------------------------------
/app/portal/url.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | return [
12 | 'List/index' => [
13 | 'name' => '门户应用-文章列表',
14 | 'vars' => [
15 | 'id' => [
16 | 'pattern' => '\d+',
17 | 'require' => true
18 | ]
19 | ],
20 | 'simple' => true
21 | ],
22 | 'Page/index' => [
23 | 'name' => '门户应用-页面页',
24 | 'vars' => [
25 | 'id' => [
26 | 'pattern' => '\d+',
27 | 'require' => true
28 | ]
29 | ],
30 | 'simple' => true
31 | ],
32 | 'Article/index' => [
33 | 'name' => '门户应用-文章页',
34 | 'vars' => [
35 | 'id' => [
36 | 'pattern' => '\d+',
37 | 'require' => true
38 | ],
39 | 'cid' => [
40 | 'pattern' => '\d+',
41 | 'require' => false
42 | ]
43 | ],
44 | 'simple' => true
45 | ],
46 | 'Search/index' => [
47 | 'name' => '门户应用-搜索页',
48 | 'vars' => [
49 |
50 | ],
51 | 'simple' => false
52 | ],
53 | ];
--------------------------------------------------------------------------------
/app/portal/user_action.php:
--------------------------------------------------------------------------------
1 | [
4 | // 'name' => '用户登录',//用户操作名称
5 | // 'score' => 1,//更改积分,可以为负
6 | // 'coin' => 0,//更改金币,可以为负
7 | // 'cycle_time' => 1,//周期时间值
8 | // 'cycle_type' => 1,//周期类型;0:不限;1:按天;2:按小时;3:永久
9 | // 'reward_number' => 1,//奖励次数
10 | // 'url' => [
11 | // 'action' => 'portal/Test/test',
12 | // 'param' => ['id' => 1]
13 | // ],//执行操作的url
14 | // ]
15 | ];
--------------------------------------------------------------------------------
/app/portal/validate/AdminArticleValidate.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | namespace app\portal\validate;
12 |
13 | use think\Validate;
14 |
15 | class AdminArticleValidate extends Validate
16 | {
17 | protected $rule = [
18 | 'categories' => 'require',
19 | 'post_title' => 'require',
20 | ];
21 | protected $message = [
22 | 'categories.require' => '请指定文章分类!',
23 | 'post_title.require' => '文章标题不能为空!',
24 | ];
25 |
26 | protected $scene = [
27 | // 'add' => ['user_login,user_pass,user_email'],
28 | // 'edit' => ['user_login,user_email'],
29 | ];
30 | }
--------------------------------------------------------------------------------
/app/portal/validate/AdminPageValidate.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | namespace app\portal\validate;
12 |
13 | use app\admin\model\RouteModel;
14 | use think\Validate;
15 |
16 | class AdminPageValidate extends Validate
17 | {
18 | protected $rule = [
19 | 'post_title' => 'require',
20 | 'post_alias' => 'checkAlias'
21 | ];
22 | protected $message = [
23 | 'post_title.require' => '页面标题不能为空',
24 | ];
25 |
26 | protected $scene = [
27 | // 'add' => ['user_login,user_pass,user_email'],
28 | // 'edit' => ['user_login,user_email'],
29 | ];
30 |
31 | // 自定义验证规则
32 | protected function checkAlias($value, $rule, $data)
33 | {
34 | if (empty($value)) {
35 | return true;
36 | }
37 |
38 | if (preg_match("/^\d+$/", $value)) {
39 | return "别名不能为纯数字!";
40 | }
41 |
42 | $routeModel = new RouteModel();
43 | $fullUrl = $routeModel->buildFullUrl('portal/Page/index', ['id' => $data['id']]);
44 | if (!$routeModel->existsRoute($value, $fullUrl)) {
45 | return true;
46 | } else {
47 | return "别名已经存在!";
48 | }
49 |
50 | }
51 | }
--------------------------------------------------------------------------------
/app/portal/validate/PortalCategoryValidate.php:
--------------------------------------------------------------------------------
1 |
10 | // +----------------------------------------------------------------------
11 | namespace app\portal\validate;
12 |
13 | use app\admin\model\RouteModel;
14 | use think\Validate;
15 |
16 | class PortalCategoryValidate extends Validate
17 | {
18 | protected $rule = [
19 | 'name' => 'require',
20 | 'alias' => 'checkAlias',
21 | ];
22 | protected $message = [
23 | 'name.require' => '分类名称不能为空',
24 | ];
25 |
26 | protected $scene = [
27 | // 'add' => ['user_login,user_pass,user_email'],
28 | // 'edit' => ['user_login,user_email'],
29 | ];
30 |
31 | // 自定义验证规则
32 | protected function checkAlias($value, $rule, $data)
33 | {
34 | if (empty($value)) {
35 | return true;
36 | }
37 |
38 | if (preg_match("/^\d+$/", $value)) {
39 | return "别名不能为纯数字!";
40 | }
41 |
42 | $routeModel = new RouteModel();
43 | if (isset($data['id']) && $data['id'] > 0) {
44 | $fullUrl = $routeModel->buildFullUrl('portal/List/index', ['id' => $data['id']]);
45 | } else {
46 | $fullUrl = $routeModel->getFullUrlByUrl($data['alias']);
47 | }
48 | if (!$routeModel->existsRoute($value, $fullUrl)) {
49 | return true;
50 | } else {
51 | return "别名已经存在!";
52 | }
53 |
54 | }
55 | }
--------------------------------------------------------------------------------
/app/portal/version:
--------------------------------------------------------------------------------
1 | 1.0.0
--------------------------------------------------------------------------------
/public/themes/admin_simpleboot3/portal/admin_article/copy.html:
--------------------------------------------------------------------------------
1 |