完成知识库模块
This commit is contained in:
@@ -0,0 +1,366 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"server/models"
|
||||
"strconv"
|
||||
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
)
|
||||
|
||||
// KnowledgeController 知识库控制器
|
||||
type KnowledgeController struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
// List 获取知识列表
|
||||
// @router /api/knowledge/list [get]
|
||||
func (c *KnowledgeController) List() {
|
||||
// 获取查询参数
|
||||
page, _ := c.GetInt("page", 1)
|
||||
pageSize, _ := c.GetInt("pageSize", 10)
|
||||
status, _ := c.GetInt8("status", -1) // -1表示查询所有
|
||||
categoryId, _ := c.GetInt("categoryId", 0)
|
||||
keyword := c.GetString("keyword", "")
|
||||
|
||||
knowledges, total, err := models.GetAllKnowledge(page, pageSize, status, categoryId, keyword)
|
||||
if err != nil {
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 1,
|
||||
"message": "获取知识列表失败: " + err.Error(),
|
||||
"data": nil,
|
||||
}
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": map[string]interface{}{
|
||||
"list": knowledges,
|
||||
"total": total,
|
||||
"page": page,
|
||||
"pageSize": pageSize,
|
||||
},
|
||||
}
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// Detail 获取知识详情
|
||||
// @router /api/knowledge/detail [get]
|
||||
func (c *KnowledgeController) Detail() {
|
||||
id, _ := strconv.Atoi(c.GetString("id"))
|
||||
if id == 0 {
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 1,
|
||||
"message": "知识ID不能为空",
|
||||
"data": nil,
|
||||
}
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
knowledge, err := models.GetKnowledgeById(id)
|
||||
if err != nil {
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 1,
|
||||
"message": "获取知识详情失败: " + err.Error(),
|
||||
"data": nil,
|
||||
}
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": knowledge,
|
||||
}
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// Create 创建知识
|
||||
// @router /api/knowledge/create [post]
|
||||
func (c *KnowledgeController) Create() {
|
||||
// 解析请求体
|
||||
var knowledge models.Knowledge
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &knowledge)
|
||||
if err != nil {
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 1,
|
||||
"message": "请求参数格式错误",
|
||||
"data": nil,
|
||||
}
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
// 验证必填字段
|
||||
if knowledge.Title == "" {
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 1,
|
||||
"message": "标题不能为空",
|
||||
"data": nil,
|
||||
}
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
id, err := models.AddKnowledge(&knowledge)
|
||||
if err != nil {
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 1,
|
||||
"message": "创建知识失败: " + err.Error(),
|
||||
"data": nil,
|
||||
}
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 0,
|
||||
"message": "创建成功",
|
||||
"data": map[string]interface{}{"id": id},
|
||||
}
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// Update 更新知识
|
||||
// @router /api/knowledge/update [post]
|
||||
func (c *KnowledgeController) Update() {
|
||||
// 解析请求体
|
||||
var knowledge models.Knowledge
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &knowledge)
|
||||
if err != nil {
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 1,
|
||||
"message": "请求参数格式错误",
|
||||
"data": nil,
|
||||
}
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
// 验证必填字段
|
||||
if knowledge.Id == 0 {
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 1,
|
||||
"message": "知识ID不能为空",
|
||||
"data": nil,
|
||||
}
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
err = models.UpdateKnowledge(knowledge.Id, &knowledge)
|
||||
if err != nil {
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 1,
|
||||
"message": "更新知识失败: " + err.Error(),
|
||||
"data": nil,
|
||||
}
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 0,
|
||||
"message": "更新成功",
|
||||
"data": nil,
|
||||
}
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// Delete 软删除知识
|
||||
// @router /api/knowledge/delete [post]
|
||||
func (c *KnowledgeController) Delete() {
|
||||
var request map[string]interface{}
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &request)
|
||||
if err != nil {
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 1,
|
||||
"message": "请求参数格式错误",
|
||||
"data": nil,
|
||||
}
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
id, ok := request["id"].(float64)
|
||||
if !ok {
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 1,
|
||||
"message": "知识ID不能为空",
|
||||
"data": nil,
|
||||
}
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
// 从请求头或 session 中获取当前用户信息
|
||||
deleteBy := c.GetString("username")
|
||||
if deleteBy == "" {
|
||||
deleteBy = c.GetString("user")
|
||||
}
|
||||
if deleteBy == "" {
|
||||
deleteBy = "system" // 默认值
|
||||
}
|
||||
|
||||
err = models.DeleteKnowledge(int(id), deleteBy)
|
||||
if err != nil {
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 1,
|
||||
"message": "删除知识失败: " + err.Error(),
|
||||
"data": nil,
|
||||
}
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 0,
|
||||
"message": "删除成功",
|
||||
"data": nil,
|
||||
}
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// GetCategories 获取分类列表
|
||||
// @router /api/knowledge/categories [get]
|
||||
func (c *KnowledgeController) GetCategories() {
|
||||
categories, err := models.GetAllCategories()
|
||||
if err != nil {
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 1,
|
||||
"message": "获取分类列表失败: " + err.Error(),
|
||||
"data": nil,
|
||||
}
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
// 手动转换数据格式,确保字段名正确
|
||||
var result []map[string]interface{}
|
||||
for _, cat := range categories {
|
||||
result = append(result, map[string]interface{}{
|
||||
"categoryId": cat.CategoryId,
|
||||
"categoryName": cat.CategoryName,
|
||||
"categoryDesc": cat.CategoryDesc,
|
||||
"parentId": cat.ParentId,
|
||||
"sortOrder": cat.SortOrder,
|
||||
"createTime": cat.CreateTime,
|
||||
"updateTime": cat.UpdateTime,
|
||||
})
|
||||
}
|
||||
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": result,
|
||||
}
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// GetTags 获取标签列表
|
||||
// @router /api/knowledge/tags [get]
|
||||
func (c *KnowledgeController) GetTags() {
|
||||
tags, err := models.GetAllTags()
|
||||
if err != nil {
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 1,
|
||||
"message": "获取标签列表失败: " + err.Error(),
|
||||
"data": nil,
|
||||
}
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
// 手动转换数据格式,确保字段名正确
|
||||
var result []map[string]interface{}
|
||||
for _, tag := range tags {
|
||||
result = append(result, map[string]interface{}{
|
||||
"tagId": tag.TagId,
|
||||
"tagName": tag.TagName,
|
||||
"tagColor": tag.TagColor,
|
||||
"usageCount": tag.UsageCount,
|
||||
"createTime": tag.CreateTime,
|
||||
"updateTime": tag.UpdateTime,
|
||||
})
|
||||
}
|
||||
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": result,
|
||||
}
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// AddCategory 添加分类
|
||||
// @router /api/knowledge/category/add [post]
|
||||
func (c *KnowledgeController) AddCategory() {
|
||||
var category models.KnowledgeCategory
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &category)
|
||||
if err != nil {
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 1,
|
||||
"message": "请求参数格式错误",
|
||||
"data": nil,
|
||||
}
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
id, err := models.AddCategory(&category)
|
||||
if err != nil {
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 1,
|
||||
"message": "添加分类失败: " + err.Error(),
|
||||
"data": nil,
|
||||
}
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 0,
|
||||
"message": "添加成功",
|
||||
"data": map[string]interface{}{"categoryId": id},
|
||||
}
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// AddTag 添加标签
|
||||
// @router /api/knowledge/tag/add [post]
|
||||
func (c *KnowledgeController) AddTag() {
|
||||
var tag models.KnowledgeTag
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &tag)
|
||||
if err != nil {
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 1,
|
||||
"message": "请求参数格式错误",
|
||||
"data": nil,
|
||||
}
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
id, err := models.AddTag(&tag)
|
||||
if err != nil {
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 1,
|
||||
"message": "添加标签失败: " + err.Error(),
|
||||
"data": nil,
|
||||
}
|
||||
c.ServeJSON()
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = map[string]interface{}{
|
||||
"code": 0,
|
||||
"message": "添加成功",
|
||||
"data": map[string]interface{}{"tagId": id},
|
||||
}
|
||||
c.ServeJSON()
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
# 知识库数据库表创建说明
|
||||
|
||||
## 创建步骤
|
||||
|
||||
### 方法1:执行独立的 SQL 文件(推荐)
|
||||
```bash
|
||||
# 在 MySQL 中执行
|
||||
mysql -u root -p your_database < server/database/create_knowledge_tables.sql
|
||||
```
|
||||
|
||||
### 方法2:手动执行 SQL
|
||||
```sql
|
||||
-- 1. 进入 MySQL
|
||||
mysql -u root -p your_database
|
||||
|
||||
-- 2. 执行 SQL 脚本
|
||||
SOURCE server/database/create_knowledge_tables.sql;
|
||||
```
|
||||
|
||||
### 方法3:在 MySQL 客户端中复制粘贴
|
||||
直接打开 `server/database/create_knowledge_tables.sql` 文件,复制所有内容,在 MySQL 客户端中执行。
|
||||
|
||||
## 创建的表
|
||||
|
||||
1. **yz_knowledge_category** - 知识库分类表
|
||||
2. **yz_knowledge_tags** - 知识库标签表
|
||||
3. **yz_knowledge** - 知识库内容表
|
||||
|
||||
## 默认数据
|
||||
|
||||
- 5 个分类:技术文档、产品手册、用户指南、常见问题、API文档
|
||||
- 8 个标签:Vue、React、TypeScript、Element Plus、Vue Router、Pinia、Go、Python
|
||||
|
||||
## 验证创建
|
||||
|
||||
```sql
|
||||
-- 查看所有知识库相关表
|
||||
SHOW TABLES LIKE 'yz_knowledge%';
|
||||
|
||||
-- 查看知识库表结构
|
||||
DESC yz_knowledge;
|
||||
|
||||
-- 查看数据
|
||||
SELECT * FROM yz_knowledge;
|
||||
SELECT * FROM yz_knowledge_category;
|
||||
SELECT * FROM yz_knowledge_tags;
|
||||
```
|
||||
|
||||
## 如果表已存在
|
||||
|
||||
如果想重新创建表(会清空现有数据):
|
||||
```sql
|
||||
DROP TABLE IF EXISTS yz_knowledge_favorites;
|
||||
DROP TABLE IF EXISTS yz_knowledge;
|
||||
DROP TABLE IF EXISTS yz_knowledge_tags;
|
||||
DROP TABLE IF EXISTS yz_knowledge_category;
|
||||
```
|
||||
然后再执行创建脚本。
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -162,13 +162,108 @@ INSERT INTO yz_menus (name, path, parent_id, icon, `order`, status, component_pa
|
||||
('系统设置', '/settings', 0, 'fa-solid fa-gear', 99, 1, '@/views/settings/index.vue', 1, '系统参数设置'),
|
||||
('应用管理', '/apps', 0, 'fa-solid fa-gear', 4, 1, null, 2, '应用管理功能模块'),
|
||||
('文件管理', '/system/files', 2, 'fa-solid fa-folder', 3, 1, '@/views/system/files/index.vue', 1, '文件管理系统'),
|
||||
('租户管理', '/system/tenant', 2, 'fas fa-user-friends', 2, 1, '@/views/system/tenant/index.vue', 1, '租户管理'),
|
||||
('用户管理', '/system/users', 2, 'fa-solid fa-user', 1, 1, '@/views/system/users/index.vue', 1, '用户信息管理'),
|
||||
('角色管理', '/system/roles', 2, 'fa-solid fa-user-tag', 2, 1, '@/views/system/roles/index.vue', 1, '角色权限管理'),
|
||||
('权限管理', '/system/permissions', 2, 'fa-solid fa-key', 2, 1, '@/views/system/permissions/index.vue', 1, '权限管理'),
|
||||
('菜单管理', '/system/menus', 2, 'fa-solid fa-bars-progress', 2, 1, '@/views/system/menus/manager.vue', 1, '菜单权限管理'),
|
||||
('程序管理', '/system/programs', 2, 'fa-solid fa-grip', 3, 1, '@/views/system/programs/index.vue', 1, '程序功能管理'),
|
||||
('知识库', '/apps/knowledge', 4, 'fa-solid fa-book', 1, 1, '@/views/apps/knowledge/index.vue', 1, '知识库管理'),
|
||||
('编辑', '/apps/knowledge/edit', 11, '', 1, 1, '@/views/apps/knowledge/components/edit.vue', 1, '知识库编辑'),
|
||||
('详情', '/apps/knowledge/detail', 11, '', 1, 1, '@/views/apps/knowledge/components/detail.vue', 1, '知识库详情');
|
||||
|
||||
-- =============================================
|
||||
-- 4. 知识库相关表
|
||||
-- =============================================
|
||||
|
||||
-- 创建知识库分类表
|
||||
CREATE TABLE IF NOT EXISTS yz_knowledge_category (
|
||||
category_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '分类ID',
|
||||
category_name VARCHAR(100) NOT NULL COMMENT '分类名称',
|
||||
category_desc VARCHAR(500) DEFAULT NULL COMMENT '分类描述',
|
||||
parent_id INT DEFAULT 0 COMMENT '父分类ID,0表示顶级分类',
|
||||
sort_order INT DEFAULT 0 COMMENT '排序序号',
|
||||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
INDEX idx_parent_id (parent_id),
|
||||
INDEX idx_sort_order (sort_order)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='知识库分类表';
|
||||
|
||||
-- 创建知识库标签表
|
||||
CREATE TABLE IF NOT EXISTS yz_knowledge_tags (
|
||||
tag_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '标签ID',
|
||||
tag_name VARCHAR(50) NOT NULL COMMENT '标签名称',
|
||||
tag_color VARCHAR(20) DEFAULT NULL COMMENT '标签颜色',
|
||||
usage_count INT DEFAULT 0 COMMENT '使用次数',
|
||||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
UNIQUE KEY uk_tag_name (tag_name),
|
||||
INDEX idx_usage_count (usage_count)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='知识库标签表';
|
||||
|
||||
-- 创建知识库内容表
|
||||
CREATE TABLE IF NOT EXISTS yz_knowledge (
|
||||
knowledge_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '知识ID',
|
||||
title VARCHAR(200) NOT NULL COMMENT '标题',
|
||||
category_id INT DEFAULT NULL COMMENT '分类ID',
|
||||
tags TEXT COMMENT '标签JSON数组,存储标签名称',
|
||||
author VARCHAR(50) NOT NULL COMMENT '作者',
|
||||
content LONGTEXT COMMENT '正文内容(富文本)',
|
||||
summary VARCHAR(500) DEFAULT NULL COMMENT '摘要',
|
||||
cover_url VARCHAR(500) DEFAULT NULL COMMENT '封面图片URL',
|
||||
status TINYINT DEFAULT 0 COMMENT '状态:0-草稿,1-已发布,2-已归档',
|
||||
view_count INT DEFAULT 0 COMMENT '查看次数',
|
||||
like_count INT DEFAULT 0 COMMENT '点赞数',
|
||||
is_recommend TINYINT DEFAULT 0 COMMENT '是否推荐:0-否,1-是',
|
||||
is_top TINYINT DEFAULT 0 COMMENT '是否置顶:0-否,1-是',
|
||||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
create_by VARCHAR(50) DEFAULT NULL COMMENT '创建人',
|
||||
update_by VARCHAR(50) DEFAULT NULL COMMENT '更新人',
|
||||
INDEX idx_category_id (category_id),
|
||||
INDEX idx_author (author),
|
||||
INDEX idx_title (title),
|
||||
INDEX idx_status (status),
|
||||
INDEX idx_create_time (create_time),
|
||||
INDEX idx_view_count (view_count),
|
||||
INDEX idx_is_recommend (is_recommend),
|
||||
INDEX idx_is_top (is_top)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='知识库内容表';
|
||||
|
||||
-- 创建知识库收藏表
|
||||
CREATE TABLE IF NOT EXISTS yz_knowledge_favorites (
|
||||
favorite_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '收藏ID',
|
||||
knowledge_id INT NOT NULL COMMENT '知识ID',
|
||||
user_id INT NOT NULL COMMENT '用户ID',
|
||||
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
UNIQUE KEY uk_knowledge_user (knowledge_id, user_id),
|
||||
INDEX idx_user_id (user_id),
|
||||
CONSTRAINT yz_fk_fav_knowledge FOREIGN KEY (knowledge_id) REFERENCES yz_knowledge (knowledge_id) ON DELETE CASCADE,
|
||||
CONSTRAINT yz_fk_fav_user FOREIGN KEY (user_id) REFERENCES yz_users (id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='知识库收藏表';
|
||||
|
||||
-- 插入默认知识库分类
|
||||
INSERT INTO yz_knowledge_category (category_name, category_desc, parent_id, sort_order) VALUES
|
||||
('技术文档', '技术相关的文档资料', 0, 1),
|
||||
('产品手册', '产品使用手册和说明', 0, 2),
|
||||
('用户指南', '用户操作指南和教程', 0, 3),
|
||||
('常见问题', '常见问题解答', 0, 4),
|
||||
('API文档', 'API接口文档', 0, 5),
|
||||
('Vue', 'Vue框架相关', 1, 101),
|
||||
('React', 'React框架相关', 1, 102),
|
||||
('Go', 'Go语言相关', 1, 103);
|
||||
|
||||
-- 插入默认知识库标签
|
||||
INSERT INTO yz_knowledge_tags (tag_name, tag_color, usage_count) VALUES
|
||||
('Vue', '#4CAF50', 0),
|
||||
('React', '#42A5F5', 0),
|
||||
('TypeScript', '#3178C6', 0),
|
||||
('Element Plus', '#409EFF', 0),
|
||||
('Vue Router', '#4FC08D', 0),
|
||||
('Pinia', '#FFD54F', 0),
|
||||
('Go', '#00ADD8', 0),
|
||||
('Python', '#3776AB', 0);
|
||||
|
||||
-- 插入默认程序分类
|
||||
INSERT INTO yz_program_category (category_name, category_desc, parent_id, sort_order) VALUES
|
||||
('办公软件', '办公相关程序', 0, 1),
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
# 知识库分类联查更新说明
|
||||
|
||||
## 更新内容
|
||||
|
||||
本次更新将 `yz_knowledge` 表中的 `category_name` 字段移除,改为通过联查获取分类名称。
|
||||
|
||||
## 数据库变更
|
||||
|
||||
### 移除的字段
|
||||
|
||||
从 `yz_knowledge` 表中移除 `category_name` 字段:
|
||||
```sql
|
||||
ALTER TABLE `yz_knowledge` DROP COLUMN `category_name`;
|
||||
```
|
||||
|
||||
### 更新后的表结构
|
||||
|
||||
`yz_knowledge` 表现在只保留 `category_id` 字段,通过 `LEFT JOIN` 联查 `yz_knowledge_category` 表获取分类名称:
|
||||
|
||||
```sql
|
||||
SELECT k.*, c.category_name
|
||||
FROM yz_knowledge k
|
||||
LEFT JOIN yz_knowledge_category c ON k.category_id = c.category_id
|
||||
WHERE k.knowledge_id = ?
|
||||
```
|
||||
|
||||
## Go 代码变更
|
||||
|
||||
### server/models/knowledge.go
|
||||
|
||||
1. **Knowledge 结构体**:
|
||||
- `CategoryName` 字段的 ORM 标签改为 `orm:"-"`,表示不在数据库中存储
|
||||
- 从联查结果中获取分类名称
|
||||
|
||||
2. **GetKnowledgeById 方法**:
|
||||
- 使用 `LEFT JOIN` 联查获取分类名称
|
||||
- 使用原生 SQL 查询替代 ORM 查询
|
||||
|
||||
3. **GetAllKnowledge 方法**:
|
||||
- 使用原生 SQL 查询进行联查
|
||||
- 支持分页、状态筛选、分类筛选、关键词搜索
|
||||
|
||||
4. **UpdateKnowledge 方法**:
|
||||
- 移除了对 `category_name` 字段的更新操作
|
||||
- 只更新 `category_id` 字段
|
||||
|
||||
## 前端代码变更
|
||||
|
||||
### front/src/views/apps/knowledge/components/detail.vue
|
||||
|
||||
- 将 `categoryName` 映射到显示用的 `category` 字段
|
||||
- 添加 `parseTags` 方法解析标签数组
|
||||
|
||||
### front/src/views/apps/knowledge/components/edit.vue
|
||||
|
||||
- 接收数据时使用 `data.categoryName` 获取分类名称
|
||||
- 提交数据时不需要传递 `categoryName`,只传递 `category_id`
|
||||
|
||||
## 使用说明
|
||||
|
||||
### 创建知识记录
|
||||
|
||||
创建知识记录时,只传递 `category_id`:
|
||||
|
||||
```javascript
|
||||
{
|
||||
title: "标题",
|
||||
category_id: 1, // 只需传递分类ID
|
||||
// category_name 不需要传递,后台会从联查获取
|
||||
}
|
||||
```
|
||||
|
||||
### 获取知识详情
|
||||
|
||||
获取知识详情时,会自动联查获取 `category_name`:
|
||||
|
||||
```javascript
|
||||
{
|
||||
id: 1,
|
||||
title: "标题",
|
||||
category_id: 1,
|
||||
category_name: "技术文档", // 从联查获取
|
||||
}
|
||||
```
|
||||
|
||||
## 优势
|
||||
|
||||
1. **数据冗余消除**:分类名称不再冗余存储
|
||||
2. **数据一致性**:分类名称始终与分类表保持一致
|
||||
3. **易于维护**:修改分类名称时,所有知识的分类名称都会自动更新
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 确保 `yz_knowledge_category` 表存在并包含必要的分类数据
|
||||
2. 所有知识记录的 `category_id` 必须存在于 `yz_knowledge_category` 表中
|
||||
3. 如果某个知识没有分类(`category_id` 为 NULL),联查返回的 `category_name` 将为 NULL
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
-- 创建知识库分类表
|
||||
CREATE TABLE `yz_knowledge_category` (
|
||||
`category_id` INT NOT NULL AUTO_INCREMENT COMMENT '分类ID',
|
||||
`category_name` VARCHAR(100) NOT NULL COMMENT '分类名称',
|
||||
`category_desc` VARCHAR(500) DEFAULT NULL COMMENT '分类描述',
|
||||
`parent_id` INT DEFAULT 0 COMMENT '父分类ID,0表示顶级分类',
|
||||
`sort_order` INT DEFAULT 0 COMMENT '排序序号',
|
||||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`category_id`),
|
||||
KEY `idx_parent_id` (`parent_id`),
|
||||
KEY `idx_sort_order` (`sort_order`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='知识库分类表';
|
||||
|
||||
-- 创建知识库标签表
|
||||
CREATE TABLE `yz_knowledge_tags` (
|
||||
`tag_id` INT NOT NULL AUTO_INCREMENT COMMENT '标签ID',
|
||||
`tag_name` VARCHAR(50) NOT NULL COMMENT '标签名称',
|
||||
`tag_color` VARCHAR(20) DEFAULT NULL COMMENT '标签颜色',
|
||||
`usage_count` INT DEFAULT 0 COMMENT '使用次数',
|
||||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
PRIMARY KEY (`tag_id`),
|
||||
UNIQUE KEY `uk_tag_name` (`tag_name`),
|
||||
KEY `idx_usage_count` (`usage_count`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='知识库标签表';
|
||||
|
||||
-- 创建知识库内容表
|
||||
CREATE TABLE `yz_knowledge` (
|
||||
`knowledge_id` INT NOT NULL AUTO_INCREMENT COMMENT '知识ID',
|
||||
`title` VARCHAR(200) NOT NULL COMMENT '标题',
|
||||
`category_id` INT DEFAULT NULL COMMENT '分类ID',
|
||||
`tags` TEXT COMMENT '标签JSON数组,存储标签名称',
|
||||
`author` VARCHAR(50) NOT NULL COMMENT '作者',
|
||||
`content` LONGTEXT COMMENT '正文内容(富文本)',
|
||||
`summary` VARCHAR(500) DEFAULT NULL COMMENT '摘要',
|
||||
`cover_url` VARCHAR(500) DEFAULT NULL COMMENT '封面图片URL',
|
||||
`status` TINYINT DEFAULT 0 COMMENT '状态:0-草稿,1-已发布,2-已归档',
|
||||
`view_count` INT DEFAULT 0 COMMENT '查看次数',
|
||||
`like_count` INT DEFAULT 0 COMMENT '点赞数',
|
||||
`is_recommend` TINYINT DEFAULT 0 COMMENT '是否推荐:0-否,1-是',
|
||||
`is_top` TINYINT DEFAULT 0 COMMENT '是否置顶:0-否,1-是',
|
||||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`create_by` VARCHAR(50) DEFAULT NULL COMMENT '创建人',
|
||||
`update_by` VARCHAR(50) DEFAULT NULL COMMENT '更新人',
|
||||
PRIMARY KEY (`knowledge_id`),
|
||||
KEY `idx_category_id` (`category_id`),
|
||||
KEY `idx_author` (`author`),
|
||||
KEY `idx_status` (`status`),
|
||||
KEY `idx_create_time` (`create_time`),
|
||||
KEY `idx_view_count` (`view_count`),
|
||||
KEY `idx_is_recommend` (`is_recommend`),
|
||||
KEY `idx_is_top` (`is_top`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='知识库内容表';
|
||||
|
||||
-- 创建知识库收藏表
|
||||
CREATE TABLE `yz_knowledge_favorites` (
|
||||
`favorite_id` INT NOT NULL AUTO_INCREMENT COMMENT '收藏ID',
|
||||
`knowledge_id` INT NOT NULL COMMENT '知识ID',
|
||||
`user_id` INT NOT NULL COMMENT '用户ID',
|
||||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
PRIMARY KEY (`favorite_id`),
|
||||
UNIQUE KEY `uk_knowledge_user` (`knowledge_id`, `user_id`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
CONSTRAINT `yz_fk_fav_knowledge` FOREIGN KEY (`knowledge_id`) REFERENCES `yz_knowledge` (`knowledge_id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `yz_fk_fav_user` FOREIGN KEY (`user_id`) REFERENCES `yz_users` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='知识库收藏表';
|
||||
|
||||
-- 插入默认分类
|
||||
INSERT INTO `yz_knowledge_category` (`category_name`, `category_desc`, `parent_id`, `sort_order`) VALUES
|
||||
('技术文档', '技术相关的文档资料', 0, 1),
|
||||
('产品手册', '产品使用手册和说明', 0, 2),
|
||||
('用户指南', '用户操作指南和教程', 0, 3),
|
||||
('常见问题', '常见问题解答', 0, 4),
|
||||
('API文档', 'API接口文档', 0, 5),
|
||||
('Vue', 'Vue框架相关', 1, 101),
|
||||
('React', 'React框架相关', 1, 102),
|
||||
('Go', 'Go语言相关', 1, 103);
|
||||
|
||||
-- 插入默认标签
|
||||
INSERT INTO `yz_knowledge_tags` (`tag_name`, `tag_color`, `usage_count`) VALUES
|
||||
('Vue', '#4CAF50', 0),
|
||||
('React', '#42A5F5', 0),
|
||||
('TypeScript', '#3178C6', 0),
|
||||
('Element Plus', '#409EFF', 0),
|
||||
('Vue Router', '#4FC08D', 0),
|
||||
('Pinia', '#FFD54F', 0),
|
||||
('Go', '#00ADD8', 0),
|
||||
('Python', '#3776AB', 0);
|
||||
|
||||
--插入默认知识
|
||||
INSERT INTO `yz_knowledge` (`title`, `category_id`, `tags`, `author`, `content`, `summary`, `cover_url`, `status`, `view_count`, `like_count`, `is_recommend`, `is_top`, `create_time`, `update_time`, `create_by`, `update_by`) VALUES
|
||||
('Vue', 1, 'Vue', 'admin', 'Vue is a progressive framework for building user interfaces.', 'Vue is a progressive framework for building user interfaces.', 'https://vuejs.org/images/logo.png', 1, 0, 0, 0, 0, '2021-01-01 00:00:00', '2021-01-01 00:00:00', 'admin', 'admin');
|
||||
@@ -0,0 +1,318 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
)
|
||||
|
||||
// Knowledge 知识库模型
|
||||
type Knowledge struct {
|
||||
Id int `orm:"column(knowledge_id);pk;auto" json:"id"`
|
||||
Title string `orm:"column(title);size(200)" json:"title"`
|
||||
CategoryId int `orm:"column(category_id);default(0);null" json:"categoryId"`
|
||||
CategoryName string `orm:"-" json:"categoryName"` // 不映射到数据库,从联查获取
|
||||
Tags string `orm:"column(tags);type(text);null" json:"tags"`
|
||||
Author string `orm:"column(author);size(50)" json:"author"`
|
||||
Content string `orm:"column(content);type(longtext)" json:"content"`
|
||||
Summary string `orm:"column(summary);size(500);null" json:"summary"`
|
||||
CoverUrl string `orm:"column(cover_url);size(500);null" json:"coverUrl"`
|
||||
Status int8 `orm:"column(status);default(0)" json:"status"`
|
||||
ViewCount int `orm:"column(view_count);default(0)" json:"viewCount"`
|
||||
LikeCount int `orm:"column(like_count);default(0)" json:"likeCount"`
|
||||
IsRecommend int8 `orm:"column(is_recommend);default(0)" json:"isRecommend"`
|
||||
IsTop int8 `orm:"column(is_top);default(0)" json:"isTop"`
|
||||
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"createTime"`
|
||||
UpdateTime time.Time `orm:"column(update_time);auto_now;type(datetime)" json:"updateTime"`
|
||||
CreateBy string `orm:"column(create_by);size(50);null" json:"createBy"`
|
||||
UpdateBy string `orm:"column(update_by);size(50);null" json:"updateBy"`
|
||||
DeleteTime time.Time `orm:"column(delete_time);type(datetime);null" json:"deleteTime"`
|
||||
DeleteBy string `orm:"column(delete_by);size(50);null" json:"deleteBy"`
|
||||
}
|
||||
|
||||
// TableName 设置表名
|
||||
func (k *Knowledge) TableName() string {
|
||||
return "yz_knowledge"
|
||||
}
|
||||
|
||||
// KnowledgeCategory 知识库分类模型
|
||||
type KnowledgeCategory struct {
|
||||
CategoryId int `orm:"column(category_id);pk;auto" json:"categoryId"`
|
||||
CategoryName string `orm:"column(category_name);size(100)" json:"categoryName"`
|
||||
CategoryDesc string `orm:"column(category_desc);size(500);null" json:"categoryDesc"`
|
||||
ParentId int `orm:"column(parent_id);default(0)" json:"parentId"`
|
||||
SortOrder int `orm:"column(sort_order);default(0)" json:"sortOrder"`
|
||||
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"createTime"`
|
||||
UpdateTime time.Time `orm:"column(update_time);auto_now;type(datetime)" json:"updateTime"`
|
||||
}
|
||||
|
||||
// TableName 设置表名
|
||||
func (kc *KnowledgeCategory) TableName() string {
|
||||
return "yz_knowledge_category"
|
||||
}
|
||||
|
||||
// KnowledgeTag 知识库标签模型
|
||||
type KnowledgeTag struct {
|
||||
TagId int `orm:"column(tag_id);pk;auto" json:"tagId"`
|
||||
TagName string `orm:"column(tag_name);size(50);unique" json:"tagName"`
|
||||
TagColor string `orm:"column(tag_color);size(20);null" json:"tagColor"`
|
||||
UsageCount int `orm:"column(usage_count);default(0)" json:"usageCount"`
|
||||
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"createTime"`
|
||||
UpdateTime time.Time `orm:"column(update_time);auto_now;type(datetime)" json:"updateTime"`
|
||||
}
|
||||
|
||||
// TableName 设置表名
|
||||
func (kt *KnowledgeTag) TableName() string {
|
||||
return "yz_knowledge_tags"
|
||||
}
|
||||
|
||||
// AddKnowledge 创建知识
|
||||
func AddKnowledge(k *Knowledge) (int64, error) {
|
||||
o := orm.NewOrm()
|
||||
id, err := o.Insert(k)
|
||||
return id, err
|
||||
}
|
||||
|
||||
// GetKnowledgeById 根据ID获取知识详情(使用联查获取分类名称)
|
||||
func GetKnowledgeById(id int) (*Knowledge, error) {
|
||||
o := orm.NewOrm()
|
||||
|
||||
// 使用联查获取分类名称(只查询未删除的记录)
|
||||
querySQL := `
|
||||
SELECT k.*, c.category_name
|
||||
FROM yz_knowledge k
|
||||
LEFT JOIN yz_knowledge_category c ON k.category_id = c.category_id
|
||||
WHERE k.knowledge_id = ? AND k.delete_time IS NULL
|
||||
`
|
||||
|
||||
var result struct {
|
||||
Id int `orm:"column(knowledge_id)"`
|
||||
Title string `orm:"column(title)"`
|
||||
CategoryId int `orm:"column(category_id)"`
|
||||
CategoryName string `orm:"column(category_name)"`
|
||||
Tags string `orm:"column(tags)"`
|
||||
Author string `orm:"column(author)"`
|
||||
Content string `orm:"column(content)"`
|
||||
Summary string `orm:"column(summary)"`
|
||||
CoverUrl string `orm:"column(cover_url)"`
|
||||
Status int8 `orm:"column(status)"`
|
||||
ViewCount int `orm:"column(view_count)"`
|
||||
LikeCount int `orm:"column(like_count)"`
|
||||
IsRecommend int8 `orm:"column(is_recommend)"`
|
||||
IsTop int8 `orm:"column(is_top)"`
|
||||
CreateTime time.Time `orm:"column(create_time)"`
|
||||
UpdateTime time.Time `orm:"column(update_time)"`
|
||||
CreateBy string `orm:"column(create_by)"`
|
||||
UpdateBy string `orm:"column(update_by)"`
|
||||
}
|
||||
|
||||
err := o.Raw(querySQL, id).QueryRow(&result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
knowledge := &Knowledge{
|
||||
Id: result.Id,
|
||||
Title: result.Title,
|
||||
CategoryId: result.CategoryId,
|
||||
CategoryName: result.CategoryName,
|
||||
Tags: result.Tags,
|
||||
Author: result.Author,
|
||||
Content: result.Content,
|
||||
Summary: result.Summary,
|
||||
CoverUrl: result.CoverUrl,
|
||||
Status: result.Status,
|
||||
ViewCount: result.ViewCount,
|
||||
LikeCount: result.LikeCount,
|
||||
IsRecommend: result.IsRecommend,
|
||||
IsTop: result.IsTop,
|
||||
CreateTime: result.CreateTime,
|
||||
UpdateTime: result.UpdateTime,
|
||||
CreateBy: result.CreateBy,
|
||||
UpdateBy: result.UpdateBy,
|
||||
}
|
||||
|
||||
// 增加查看次数
|
||||
knowledge.ViewCount++
|
||||
_, err = o.Raw("UPDATE yz_knowledge SET view_count = ? WHERE knowledge_id = ?", knowledge.ViewCount, id).Exec()
|
||||
|
||||
return knowledge, err
|
||||
}
|
||||
|
||||
// GetAllKnowledge 获取所有知识(支持分页和筛选)
|
||||
func GetAllKnowledge(page, pageSize int, status int8, categoryId int, keyword string) ([]*Knowledge, int64, error) {
|
||||
o := orm.NewOrm()
|
||||
|
||||
// 构建 WHERE 条件(只查询未删除的记录)
|
||||
whereSQL := "delete_time IS NULL"
|
||||
params := []interface{}{}
|
||||
|
||||
// 状态筛选
|
||||
if status >= 0 {
|
||||
whereSQL += " AND status = ?"
|
||||
params = append(params, status)
|
||||
}
|
||||
|
||||
// 分类筛选
|
||||
if categoryId > 0 {
|
||||
whereSQL += " AND category_id = ?"
|
||||
params = append(params, categoryId)
|
||||
}
|
||||
|
||||
// 关键词搜索
|
||||
if keyword != "" {
|
||||
whereSQL += " AND title LIKE ?"
|
||||
params = append(params, "%"+keyword+"%")
|
||||
}
|
||||
|
||||
// 获取总数
|
||||
var total int64
|
||||
countSQL := "SELECT COUNT(*) FROM yz_knowledge WHERE " + whereSQL
|
||||
err := o.Raw(countSQL, params...).QueryRow(&total)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// 联查获取分类名称
|
||||
querySQL := `
|
||||
SELECT k.*, c.category_name
|
||||
FROM yz_knowledge k
|
||||
LEFT JOIN yz_knowledge_category c ON k.category_id = c.category_id
|
||||
WHERE ` + whereSQL + `
|
||||
ORDER BY k.is_top DESC, k.create_time DESC
|
||||
LIMIT ? OFFSET ?
|
||||
`
|
||||
params = append(params, pageSize, (page-1)*pageSize)
|
||||
|
||||
var knowledges []*Knowledge
|
||||
var results []struct {
|
||||
Id int `orm:"column(knowledge_id)"`
|
||||
Title string `orm:"column(title)"`
|
||||
CategoryId int `orm:"column(category_id)"`
|
||||
CategoryName string `orm:"column(category_name)"`
|
||||
Tags string `orm:"column(tags)"`
|
||||
Author string `orm:"column(author)"`
|
||||
Content string `orm:"column(content)"`
|
||||
Summary string `orm:"column(summary)"`
|
||||
CoverUrl string `orm:"column(cover_url)"`
|
||||
Status int8 `orm:"column(status)"`
|
||||
ViewCount int `orm:"column(view_count)"`
|
||||
LikeCount int `orm:"column(like_count)"`
|
||||
IsRecommend int8 `orm:"column(is_recommend)"`
|
||||
IsTop int8 `orm:"column(is_top)"`
|
||||
CreateTime time.Time `orm:"column(create_time)"`
|
||||
UpdateTime time.Time `orm:"column(update_time)"`
|
||||
CreateBy string `orm:"column(create_by)"`
|
||||
UpdateBy string `orm:"column(update_by)"`
|
||||
}
|
||||
|
||||
_, err = o.Raw(querySQL, params...).QueryRows(&results)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// 转换结果
|
||||
for _, r := range results {
|
||||
k := &Knowledge{
|
||||
Id: r.Id,
|
||||
Title: r.Title,
|
||||
CategoryId: r.CategoryId,
|
||||
CategoryName: r.CategoryName,
|
||||
Tags: r.Tags,
|
||||
Author: r.Author,
|
||||
Content: r.Content,
|
||||
Summary: r.Summary,
|
||||
CoverUrl: r.CoverUrl,
|
||||
Status: r.Status,
|
||||
ViewCount: r.ViewCount,
|
||||
LikeCount: r.LikeCount,
|
||||
IsRecommend: r.IsRecommend,
|
||||
IsTop: r.IsTop,
|
||||
CreateTime: r.CreateTime,
|
||||
UpdateTime: r.UpdateTime,
|
||||
CreateBy: r.CreateBy,
|
||||
UpdateBy: r.UpdateBy,
|
||||
}
|
||||
knowledges = append(knowledges, k)
|
||||
}
|
||||
|
||||
return knowledges, total, nil
|
||||
}
|
||||
|
||||
// UpdateKnowledge 更新知识
|
||||
func UpdateKnowledge(id int, k *Knowledge) error {
|
||||
o := orm.NewOrm()
|
||||
knowledge := &Knowledge{Id: id}
|
||||
err := o.Read(knowledge)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 更新字段(不包含category_name,因为它是从联查获取的)
|
||||
knowledge.Title = k.Title
|
||||
knowledge.CategoryId = k.CategoryId
|
||||
knowledge.Tags = k.Tags
|
||||
knowledge.Author = k.Author
|
||||
knowledge.Content = k.Content
|
||||
knowledge.Summary = k.Summary
|
||||
knowledge.CoverUrl = k.CoverUrl
|
||||
knowledge.Status = k.Status
|
||||
knowledge.IsRecommend = k.IsRecommend
|
||||
knowledge.IsTop = k.IsTop
|
||||
knowledge.UpdateBy = k.UpdateBy
|
||||
|
||||
_, err = o.Update(knowledge, "title", "category_id", "tags", "author", "content", "summary", "cover_url", "status", "is_recommend", "is_top", "update_by", "update_time")
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteKnowledge 软删除知识
|
||||
func DeleteKnowledge(id int, deleteBy string) error {
|
||||
o := orm.NewOrm()
|
||||
knowledge := &Knowledge{Id: id}
|
||||
err := o.Read(knowledge)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 执行软删除:设置 delete_time 和 delete_by
|
||||
_, err = o.Raw("UPDATE yz_knowledge SET delete_time = ?, delete_by = ? WHERE knowledge_id = ?", time.Now(), deleteBy, id).Exec()
|
||||
return err
|
||||
}
|
||||
|
||||
// GetAllCategories 获取所有分类
|
||||
func GetAllCategories() ([]*KnowledgeCategory, error) {
|
||||
o := orm.NewOrm()
|
||||
var categories []*KnowledgeCategory
|
||||
_, err := o.QueryTable("yz_knowledge_category").OrderBy("sort_order").All(&categories)
|
||||
return categories, err
|
||||
}
|
||||
|
||||
// GetCategoryById 根据ID获取分类
|
||||
func GetCategoryById(id int) (*KnowledgeCategory, error) {
|
||||
o := orm.NewOrm()
|
||||
category := &KnowledgeCategory{CategoryId: id}
|
||||
err := o.Read(category)
|
||||
return category, err
|
||||
}
|
||||
|
||||
// GetAllTags 获取所有标签
|
||||
func GetAllTags() ([]*KnowledgeTag, error) {
|
||||
o := orm.NewOrm()
|
||||
var tags []*KnowledgeTag
|
||||
_, err := o.QueryTable("yz_knowledge_tags").All(&tags)
|
||||
return tags, err
|
||||
}
|
||||
|
||||
// AddCategory 添加分类
|
||||
func AddCategory(category *KnowledgeCategory) (int64, error) {
|
||||
o := orm.NewOrm()
|
||||
id, err := o.Insert(category)
|
||||
return id, err
|
||||
}
|
||||
|
||||
// AddTag 添加标签
|
||||
func AddTag(tag *KnowledgeTag) (int64, error) {
|
||||
o := orm.NewOrm()
|
||||
id, err := o.Insert(tag)
|
||||
return id, err
|
||||
}
|
||||
@@ -268,6 +268,9 @@ func Init() {
|
||||
orm.RegisterModel(new(ProgramCategory))
|
||||
orm.RegisterModel(new(ProgramInfo))
|
||||
orm.RegisterModel(new(FileInfo))
|
||||
orm.RegisterModel(new(Knowledge))
|
||||
orm.RegisterModel(new(KnowledgeCategory))
|
||||
orm.RegisterModel(new(KnowledgeTag))
|
||||
|
||||
ormConfig, err := beego.AppConfig.String("orm")
|
||||
if err != nil {
|
||||
|
||||
@@ -82,6 +82,17 @@ func init() {
|
||||
// 文件管理路由 - 自动映射到 /api/file/*
|
||||
beego.AutoRouter(&controllers.FileController{})
|
||||
|
||||
// 知识库路由
|
||||
beego.Router("/api/knowledge/list", &controllers.KnowledgeController{}, "get:List")
|
||||
beego.Router("/api/knowledge/detail", &controllers.KnowledgeController{}, "get:Detail")
|
||||
beego.Router("/api/knowledge/create", &controllers.KnowledgeController{}, "post:Create")
|
||||
beego.Router("/api/knowledge/update", &controllers.KnowledgeController{}, "post:Update")
|
||||
beego.Router("/api/knowledge/delete", &controllers.KnowledgeController{}, "post:Delete")
|
||||
beego.Router("/api/knowledge/categories", &controllers.KnowledgeController{}, "get:GetCategories")
|
||||
beego.Router("/api/knowledge/tags", &controllers.KnowledgeController{}, "get:GetTags")
|
||||
beego.Router("/api/knowledge/category/add", &controllers.KnowledgeController{}, "post:AddCategory")
|
||||
beego.Router("/api/knowledge/tag/add", &controllers.KnowledgeController{}, "post:AddTag")
|
||||
|
||||
// 手动配置特殊路由(无法通过自动路由处理的)
|
||||
beego.Router("/api/menus/active", &controllers.MenuController{}, "get:GetActiveMenus")
|
||||
beego.Router("/api/allmenu", &controllers.MenuController{}, "get:GetAllMenus")
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user