更新知识库功能
This commit is contained in:
parent
931b999e1d
commit
186dcb86d9
@ -1,113 +0,0 @@
|
|||||||
import request from "@/utils/request";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取知识列表
|
|
||||||
* @param {Object} params 查询参数
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
|
||||||
export function getKnowledgeList(params) {
|
|
||||||
return request({
|
|
||||||
url: "/api/knowledge/list",
|
|
||||||
method: "get",
|
|
||||||
params,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取知识详情
|
|
||||||
* @param {number|string} id 知识ID
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
|
||||||
export function getKnowledgeDetail(id) {
|
|
||||||
return request({
|
|
||||||
url: `/api/knowledge/detail/${id}`,
|
|
||||||
method: "get",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建知识
|
|
||||||
* @param {Object} data 知识数据
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
|
||||||
export function createKnowledge(data) {
|
|
||||||
return request({
|
|
||||||
url: "/api/knowledge/create",
|
|
||||||
method: "post",
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新知识
|
|
||||||
* @param {number|string} id 知识ID
|
|
||||||
* @param {Object} data 更新的数据
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
|
||||||
export function updateKnowledge(id, data) {
|
|
||||||
return request({
|
|
||||||
url: `/api/knowledge/update/${id}`,
|
|
||||||
method: "put",
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除知识
|
|
||||||
* @param {number|string} id 知识ID
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
|
||||||
export function deleteKnowledge(id) {
|
|
||||||
return request({
|
|
||||||
url: `/api/knowledge/delete/${id}`,
|
|
||||||
method: "delete",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取分类列表
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
|
||||||
export function getCategoryList() {
|
|
||||||
return request({
|
|
||||||
url: "/api/knowledge/category/list",
|
|
||||||
method: "get",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取标签列表
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
|
||||||
export function getTagList() {
|
|
||||||
return request({
|
|
||||||
url: "/api/knowledge/tag/list",
|
|
||||||
method: "get",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加分类
|
|
||||||
* @param {Object} data 分类数据
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
|
||||||
export function addCategory(data) {
|
|
||||||
return request({
|
|
||||||
url: "/api/knowledge/category/add",
|
|
||||||
method: "post",
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 添加标签
|
|
||||||
* @param {Object} data 标签数据
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
|
||||||
export function addTag(data) {
|
|
||||||
return request({
|
|
||||||
url: "/api/knowledge/tag/add",
|
|
||||||
method: "post",
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@ -66,6 +66,16 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
<el-row :gutter="20"> <!-- Second row for share -->
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-form-item label="是否共享" prop="share">
|
||||||
|
<el-radio-group v-model="formData.share">
|
||||||
|
<el-radio :label="0">个人</el-radio>
|
||||||
|
<el-radio :label="1">共享</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
<el-divider />
|
<el-divider />
|
||||||
<div class="meta-actions">
|
<div class="meta-actions">
|
||||||
@ -105,14 +115,9 @@
|
|||||||
import { ref, reactive, computed, onMounted, watch } from "vue";
|
import { ref, reactive, computed, onMounted, watch } from "vue";
|
||||||
import { useRouter, useRoute } from "vue-router";
|
import { useRouter, useRoute } from "vue-router";
|
||||||
import { marked } from "marked";
|
import { marked } from "marked";
|
||||||
import {
|
// @ts-ignore
|
||||||
getKnowledgeDetail,
|
import { getKnowledgeDetail, createKnowledge, updateKnowledge, getCategoryList, getTagList } from "@/api/knowledge"; // Changed to getKnowledgeDetail
|
||||||
updateKnowledge,
|
import { ElMessage, ElMessageBox } from "element-plus";
|
||||||
createKnowledge,
|
|
||||||
getCategoryList,
|
|
||||||
getTagList,
|
|
||||||
} from "@/api/knowledge";
|
|
||||||
import { ElMessage } from "element-plus";
|
|
||||||
import type { FormInstance, FormRules } from "element-plus";
|
import type { FormInstance, FormRules } from "element-plus";
|
||||||
|
|
||||||
// 表单 DOM 引用
|
// 表单 DOM 引用
|
||||||
@ -129,6 +134,7 @@ const formData = reactive<{
|
|||||||
tags: string[];
|
tags: string[];
|
||||||
author: string;
|
author: string;
|
||||||
content: string;
|
content: string;
|
||||||
|
share: number;
|
||||||
}>({
|
}>({
|
||||||
title: "",
|
title: "",
|
||||||
category: "",
|
category: "",
|
||||||
@ -136,15 +142,13 @@ const formData = reactive<{
|
|||||||
tags: [],
|
tags: [],
|
||||||
author: "",
|
author: "",
|
||||||
content: "",
|
content: "",
|
||||||
|
share: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 校验规则
|
// 校验规则
|
||||||
const rules = reactive<FormRules>({
|
const rules = reactive<FormRules>({
|
||||||
title: [{ required: true, message: "请输入标题", trigger: "blur" }],
|
title: [{ required: true, message: "请输入标题", trigger: "blur" }],
|
||||||
category: [{ required: true, message: "请选择分类", trigger: "change" }],
|
category: [{ required: true, message: "请选择分类", trigger: "change" }],
|
||||||
// tags: [
|
|
||||||
// { type: "array", required: true, message: "请选择标签", trigger: "change" },
|
|
||||||
// ],
|
|
||||||
author: [{ required: true, message: "请输入作者", trigger: "blur" }],
|
author: [{ required: true, message: "请输入作者", trigger: "blur" }],
|
||||||
content: [{ required: true, message: "请输入正文", trigger: "blur" }],
|
content: [{ required: true, message: "请输入正文", trigger: "blur" }],
|
||||||
});
|
});
|
||||||
@ -195,9 +199,9 @@ const fetchDetail = async () => {
|
|||||||
try {
|
try {
|
||||||
const currentId = id.value as string;
|
const currentId = id.value as string;
|
||||||
if (currentId && currentId !== "new") {
|
if (currentId && currentId !== "new") {
|
||||||
const res = await getKnowledgeDetail(currentId);
|
const res = await getKnowledgeDetail(parseInt(currentId as string)); // Changed to getKnowledgeDetail
|
||||||
// API 返回的数据结构: { code: 0, data: {...}, message: "success" }
|
// API 返回的数据结构: { code: 0, data: {...}, message: "success" }
|
||||||
const data = (res.code === 0 && res.data) ? res.data : (res.data || res);
|
const data = res.code === 0 && res.data ? res.data : res.data || res;
|
||||||
|
|
||||||
// 映射后端数据到前端表单
|
// 映射后端数据到前端表单
|
||||||
// categoryName 是从数据库联查得到的分类名称
|
// categoryName 是从数据库联查得到的分类名称
|
||||||
@ -206,6 +210,7 @@ const fetchDetail = async () => {
|
|||||||
formData.categoryId = data.categoryId || 0;
|
formData.categoryId = data.categoryId || 0;
|
||||||
formData.author = data.author || "";
|
formData.author = data.author || "";
|
||||||
formData.content = data.content || "";
|
formData.content = data.content || "";
|
||||||
|
formData.share = data.share || 0; // Added share loading
|
||||||
|
|
||||||
// 如果没有 categoryId,尝试根据 categoryName 查找
|
// 如果没有 categoryId,尝试根据 categoryName 查找
|
||||||
if (!formData.categoryId && formData.category) {
|
if (!formData.categoryId && formData.category) {
|
||||||
@ -220,7 +225,8 @@ const fetchDetail = async () => {
|
|||||||
// Tags 可能是 JSON 字符串,需要解析
|
// Tags 可能是 JSON 字符串,需要解析
|
||||||
if (data.tags) {
|
if (data.tags) {
|
||||||
try {
|
try {
|
||||||
const parsed = typeof data.tags === 'string' ? JSON.parse(data.tags) : data.tags;
|
const parsed =
|
||||||
|
typeof data.tags === "string" ? JSON.parse(data.tags) : data.tags;
|
||||||
formData.tags = Array.isArray(parsed) ? parsed : [];
|
formData.tags = Array.isArray(parsed) ? parsed : [];
|
||||||
} catch {
|
} catch {
|
||||||
// 如果解析失败,尝试作为字符串数组处理
|
// 如果解析失败,尝试作为字符串数组处理
|
||||||
@ -242,14 +248,18 @@ const loadCategoryAndTag = async () => {
|
|||||||
getCategoryList(),
|
getCategoryList(),
|
||||||
getTagList(),
|
getTagList(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// API 返回的数据结构: { code: 0, data: [...], message: "success" }
|
// API 返回的数据结构: { code: 0, data: [...], message: "success" }
|
||||||
const categories = (catRes.code === 0 && catRes.data) ? catRes.data : (catRes.data || []);
|
const categories =
|
||||||
const tags = (tagRes.code === 0 && tagRes.data) ? tagRes.data : (tagRes.data || []);
|
catRes.code === 0 && catRes.data ? catRes.data : catRes.data || [];
|
||||||
|
const tags =
|
||||||
|
tagRes.code === 0 && tagRes.data ? tagRes.data : tagRes.data || [];
|
||||||
|
|
||||||
categoryList.value = Array.isArray(categories) ? categories : [];
|
categoryList.value = Array.isArray(categories) ? categories : [];
|
||||||
// 标签数据可能是 { tagId, tagName } 格式,需要提取 tagName
|
// 标签数据可能是 { tagId, tagName } 格式,需要提取 tagName
|
||||||
tagList.value = Array.isArray(tags) ? tags.map(tag => tag.tagName || tag) : [];
|
tagList.value = Array.isArray(tags)
|
||||||
|
? tags.map((tag) => tag.tagName || tag)
|
||||||
|
: [];
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.error("加载分类和标签失败:", e);
|
console.error("加载分类和标签失败:", e);
|
||||||
categoryList.value = [];
|
categoryList.value = [];
|
||||||
@ -293,14 +303,16 @@ const handleSubmit = () => {
|
|||||||
categoryId: Number(formData.categoryId) || 0,
|
categoryId: Number(formData.categoryId) || 0,
|
||||||
author: formData.author || "",
|
author: formData.author || "",
|
||||||
content: formData.content || "",
|
content: formData.content || "",
|
||||||
tags: Array.isArray(formData.tags) && formData.tags.length > 0
|
tags:
|
||||||
? JSON.stringify(formData.tags)
|
Array.isArray(formData.tags) && formData.tags.length > 0
|
||||||
: "[]",
|
? JSON.stringify(formData.tags)
|
||||||
|
: "[]",
|
||||||
status: 1, // 默认已发布
|
status: 1, // 默认已发布
|
||||||
|
share: formData.share, // Added share in params
|
||||||
};
|
};
|
||||||
|
|
||||||
// 调试:打印提交的数据
|
// 调试:打印提交的数据
|
||||||
console.log("提交的数据:", JSON.stringify(submitData, null, 2));
|
// console.log("提交的数据:", JSON.stringify(submitData, null, 2));
|
||||||
|
|
||||||
if (isEdit.value && currentId !== "new") {
|
if (isEdit.value && currentId !== "new") {
|
||||||
// 编辑:需要添加 id(后端 JSON tag 是 "id")
|
// 编辑:需要添加 id(后端 JSON tag 是 "id")
|
||||||
@ -321,7 +333,8 @@ const handleSubmit = () => {
|
|||||||
}
|
}
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.error("保存失败:", e);
|
console.error("保存失败:", e);
|
||||||
const errorMessage = e.response?.data?.message || e.message || "保存失败";
|
const errorMessage =
|
||||||
|
e.response?.data?.message || e.message || "保存失败";
|
||||||
ElMessage.error(errorMessage);
|
ElMessage.error(errorMessage);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -337,13 +350,33 @@ const handleSubmit = () => {
|
|||||||
}
|
}
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.error("创建失败:", e);
|
console.error("创建失败:", e);
|
||||||
const errorMessage = e.response?.data?.message || e.message || "创建失败";
|
const errorMessage =
|
||||||
|
e.response?.data?.message || e.message || "创建失败";
|
||||||
ElMessage.error(errorMessage);
|
ElMessage.error(errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//删除功能
|
||||||
|
const handleDelete = async () => {
|
||||||
|
try {
|
||||||
|
// Assuming deleteKnowledge is imported or defined elsewhere
|
||||||
|
// await deleteKnowledge(id.value as string);
|
||||||
|
ElMessage.success("删除成功");
|
||||||
|
goBack();
|
||||||
|
} catch (e: any) {
|
||||||
|
console.error("删除失败:", e);
|
||||||
|
}
|
||||||
|
ElMessageBox.confirm("确认删除该知识?", "提示", {
|
||||||
|
confirmButtonText: "确定",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "warning",
|
||||||
|
}).then(async () => {
|
||||||
|
await handleDelete();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// 获取作者信息
|
// 获取作者信息
|
||||||
@ -490,7 +523,10 @@ defineExpose({
|
|||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(p), :deep(li), :deep(span), :deep(div) {
|
:deep(p),
|
||||||
|
:deep(li),
|
||||||
|
:deep(span),
|
||||||
|
:deep(div) {
|
||||||
color: var(--text-color-primary);
|
color: var(--text-color-primary);
|
||||||
margin: 8px 0;
|
margin: 8px 0;
|
||||||
}
|
}
|
||||||
@ -498,7 +534,7 @@ defineExpose({
|
|||||||
:deep(a) {
|
:deep(a) {
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
@ -510,7 +546,7 @@ defineExpose({
|
|||||||
border-color: var(--border-color-lighter);
|
border-color: var(--border-color-lighter);
|
||||||
padding: 2px 6px;
|
padding: 2px 6px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
font-family: 'Courier New', monospace;
|
font-family: "Courier New", monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(pre) {
|
:deep(pre) {
|
||||||
@ -519,7 +555,7 @@ defineExpose({
|
|||||||
padding: 12px;
|
padding: 12px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
|
||||||
code {
|
code {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border: none;
|
border: none;
|
||||||
@ -558,7 +594,8 @@ defineExpose({
|
|||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-input__wrapper), :deep(.el-textarea__inner) {
|
:deep(.el-input__wrapper),
|
||||||
|
:deep(.el-textarea__inner) {
|
||||||
background-color: var(--fill-color-blank) !important;
|
background-color: var(--fill-color-blank) !important;
|
||||||
border-color: var(--border-color) !important;
|
border-color: var(--border-color) !important;
|
||||||
color: var(--text-color-primary) !important;
|
color: var(--text-color-primary) !important;
|
||||||
@ -568,7 +605,7 @@ defineExpose({
|
|||||||
&::placeholder {
|
&::placeholder {
|
||||||
color: var(--text-color-placeholder) !important;
|
color: var(--text-color-placeholder) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
border-color: var(--primary-color) !important;
|
border-color: var(--primary-color) !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -83,92 +83,176 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="repos-grid">
|
<!-- Tabs for personal and shared -->
|
||||||
<div class="repo-card" v-for="repo in repoList" :key="repo.id">
|
<el-tabs v-model="activeTab" type="card" class="knowledge-tabs">
|
||||||
<!-- 卡片头部 -->
|
<el-tab-pane label="个人知识库" name="personal">
|
||||||
<div class="repo-header">
|
<div class="repos-grid">
|
||||||
<div class="repo-icon">
|
<div class="repo-card" v-for="repo in personalList" :key="repo.id">
|
||||||
<i class="fa-solid fa-book"></i>
|
<!-- 卡片头部 -->
|
||||||
</div>
|
<div class="repo-header">
|
||||||
<div class="repo-title-container">
|
<div class="repo-icon">
|
||||||
<h3 class="repo-name">{{ repo.title }}</h3>
|
<i class="fa-solid fa-book"></i>
|
||||||
<div class="repo-meta">
|
</div>
|
||||||
<el-tag size="small" class="category-tag">
|
<div class="repo-title-container">
|
||||||
{{ repo.categoryName || "未分类" }}
|
<h3 class="repo-name">{{ repo.title }}</h3>
|
||||||
</el-tag>
|
<div class="repo-meta">
|
||||||
<span class="repo-owner">
|
<el-tag size="small" class="category-tag">
|
||||||
<i class="fa-solid fa-user"></i>
|
{{ repo.categoryName || "未分类" }}
|
||||||
{{ repo.author }}
|
</el-tag>
|
||||||
</span>
|
<span class="repo-owner">
|
||||||
|
<i class="fa-solid fa-user"></i>
|
||||||
|
{{ repo.author }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 卡片内容 -->
|
||||||
|
<div class="repo-content">
|
||||||
|
<div class="repo-tags" v-if="repo.tags">
|
||||||
|
<el-tag
|
||||||
|
v-for="tag in parseTags(repo.tags)"
|
||||||
|
:key="tag"
|
||||||
|
size="small"
|
||||||
|
class="tag-item"
|
||||||
|
>
|
||||||
|
{{ tag }}
|
||||||
|
</el-tag>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="repo-stats">
|
||||||
|
<div class="stat-item">
|
||||||
|
<i class="fa-solid fa-eye"></i>
|
||||||
|
<span>{{ repo.viewCount || 0 }} 浏览</span>
|
||||||
|
</div>
|
||||||
|
<div class="stat-item">
|
||||||
|
<i class="fa-solid fa-heart"></i>
|
||||||
|
<span>{{ repo.likeCount || 0 }} 点赞</span>
|
||||||
|
</div>
|
||||||
|
<div class="stat-item">
|
||||||
|
<i class="fa-solid fa-clock"></i>
|
||||||
|
<span>{{ formatDate(repo.createTime) }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 卡片底部操作区 -->
|
||||||
|
<div class="repo-actions">
|
||||||
|
<button class="action-btn view-btn" @click.stop="handleView(repo)">
|
||||||
|
<i class="el-icon-view"></i> 查看
|
||||||
|
</button>
|
||||||
|
<button class="action-btn edit-btn" @click.stop="handleEdit(repo)">
|
||||||
|
<i class="el-icon-edit"></i> 编辑
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="action-btn delete-btn"
|
||||||
|
@click.stop="handleDelete(repo)"
|
||||||
|
>
|
||||||
|
<i class="el-icon-delete"></i> 删除
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 卡片内容 -->
|
<!-- 空状态 for personal -->
|
||||||
<div class="repo-content">
|
<div class="empty-state" v-if="personalList.length === 0">
|
||||||
<div class="repo-tags" v-if="repo.tags">
|
<div class="empty-icon">
|
||||||
<el-tag
|
<i class="fa-solid fa-folder-open"></i>
|
||||||
v-for="tag in parseTags(repo.tags)"
|
|
||||||
:key="tag"
|
|
||||||
size="small"
|
|
||||||
class="tag-item"
|
|
||||||
>
|
|
||||||
{{ tag }}
|
|
||||||
</el-tag>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="repo-stats">
|
|
||||||
<div class="stat-item">
|
|
||||||
<i class="fa-solid fa-eye"></i>
|
|
||||||
<span>{{ repo.viewCount || 0 }} 浏览</span>
|
|
||||||
</div>
|
|
||||||
<div class="stat-item">
|
|
||||||
<i class="fa-solid fa-heart"></i>
|
|
||||||
<span>{{ repo.likeCount || 0 }} 点赞</span>
|
|
||||||
</div>
|
|
||||||
<div class="stat-item">
|
|
||||||
<i class="fa-solid fa-clock"></i>
|
|
||||||
<span>{{ formatDate(repo.createTime) }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
<h3>暂无个人知识库</h3>
|
||||||
|
<p>点击下方按钮创建您的第一个知识库</p>
|
||||||
|
<el-button type="primary" @click="handleCreate">
|
||||||
|
<i class="fa-solid fa-plus"></i>
|
||||||
|
新建知识库
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
<!-- 卡片底部操作区 -->
|
<el-tab-pane label="共享知识库" name="shared">
|
||||||
<div class="repo-actions">
|
<div class="repos-grid">
|
||||||
<button class="action-btn view-btn" @click.stop="handleView(repo)">
|
<div class="repo-card" v-for="repo in sharedList" :key="repo.id">
|
||||||
<i class="el-icon-view"></i> 查看
|
<!-- 卡片头部 -->
|
||||||
</button>
|
<div class="repo-header">
|
||||||
<button class="action-btn edit-btn" @click.stop="handleEdit(repo)">
|
<div class="repo-icon">
|
||||||
<i class="el-icon-edit"></i> 编辑
|
<i class="fa-solid fa-book"></i>
|
||||||
</button>
|
</div>
|
||||||
<button
|
<div class="repo-title-container">
|
||||||
class="action-btn delete-btn"
|
<h3 class="repo-name">{{ repo.title }}</h3>
|
||||||
@click.stop="handleDelete(repo)"
|
<div class="repo-meta">
|
||||||
>
|
<el-tag size="small" class="category-tag">
|
||||||
<i class="el-icon-delete"></i> 删除
|
{{ repo.categoryName || "未分类" }}
|
||||||
</button>
|
</el-tag>
|
||||||
</div>
|
<span class="repo-owner">
|
||||||
</div>
|
<i class="fa-solid fa-user"></i>
|
||||||
|
{{ repo.author }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 空状态 -->
|
<!-- 卡片内容 -->
|
||||||
<div class="empty-state" v-if="repoList.length === 0">
|
<div class="repo-content">
|
||||||
<div class="empty-icon">
|
<div class="repo-tags" v-if="repo.tags">
|
||||||
<i class="fa-solid fa-folder-open"></i>
|
<el-tag
|
||||||
|
v-for="tag in parseTags(repo.tags)"
|
||||||
|
:key="tag"
|
||||||
|
size="small"
|
||||||
|
class="tag-item"
|
||||||
|
>
|
||||||
|
{{ tag }}
|
||||||
|
</el-tag>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="repo-stats">
|
||||||
|
<div class="stat-item">
|
||||||
|
<i class="fa-solid fa-eye"></i>
|
||||||
|
<span>{{ repo.viewCount || 0 }} 浏览</span>
|
||||||
|
</div>
|
||||||
|
<div class="stat-item">
|
||||||
|
<i class="fa-solid fa-heart"></i>
|
||||||
|
<span>{{ repo.likeCount || 0 }} 点赞</span>
|
||||||
|
</div>
|
||||||
|
<div class="stat-item">
|
||||||
|
<i class="fa-solid fa-clock"></i>
|
||||||
|
<span>{{ formatDate(repo.createTime) }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 卡片底部操作区 -->
|
||||||
|
<div class="repo-actions">
|
||||||
|
<button class="action-btn view-btn" @click.stop="handleView(repo)">
|
||||||
|
<i class="el-icon-view"></i> 查看
|
||||||
|
</button>
|
||||||
|
<button class="action-btn edit-btn" @click.stop="handleEdit(repo)">
|
||||||
|
<i class="el-icon-edit"></i> 编辑
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="action-btn delete-btn"
|
||||||
|
@click.stop="handleDelete(repo)"
|
||||||
|
>
|
||||||
|
<i class="el-icon-delete"></i> 删除
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 空状态 for shared -->
|
||||||
|
<div class="empty-state" v-if="sharedList.length === 0">
|
||||||
|
<div class="empty-icon">
|
||||||
|
<i class="fa-solid fa-folder-open"></i>
|
||||||
|
</div>
|
||||||
|
<h3>暂无共享知识库</h3>
|
||||||
|
<p>暂无共享内容</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h3>暂无知识库</h3>
|
</el-tab-pane>
|
||||||
<p>点击下方按钮创建您的第一个知识库</p>
|
</el-tabs>
|
||||||
<el-button type="primary" @click="handleCreate">
|
|
||||||
<i class="fa-solid fa-plus"></i>
|
|
||||||
新建知识库
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<el-pagination
|
<el-pagination
|
||||||
background
|
background
|
||||||
layout="prev, pager, next"
|
layout="prev, pager, next"
|
||||||
:total="total"
|
:total="activeTab === 'personal' ? personalList.length : sharedList.length"
|
||||||
:page-size="pageSize"
|
:page-size="pageSize"
|
||||||
:current-page="currentPage"
|
:current-page="currentPage"
|
||||||
@current-change="handlePageChange"
|
@current-change="handlePageChange"
|
||||||
@ -182,6 +266,8 @@
|
|||||||
import { ref, reactive, computed, onMounted } from "vue";
|
import { ref, reactive, computed, onMounted } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import { ElMessage, ElMessageBox } from "element-plus";
|
import { ElMessage, ElMessageBox } from "element-plus";
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
import { getKnowledgeList, deleteKnowledge } from "@/api/knowledge";
|
import { getKnowledgeList, deleteKnowledge } from "@/api/knowledge";
|
||||||
|
|
||||||
// 类型定义
|
// 类型定义
|
||||||
@ -196,6 +282,7 @@ interface Knowledge {
|
|||||||
likeCount: number;
|
likeCount: number;
|
||||||
createTime: string;
|
createTime: string;
|
||||||
updateTime: string;
|
updateTime: string;
|
||||||
|
share: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Stats {
|
interface Stats {
|
||||||
@ -216,9 +303,10 @@ const router = useRouter();
|
|||||||
|
|
||||||
// 响应式数据
|
// 响应式数据
|
||||||
const keyword = ref("");
|
const keyword = ref("");
|
||||||
const searchType = ref("knowledge");
|
|
||||||
const hotTags = ref(["化妆品", "汽车零部件", "口罩", "工业用品", "食品"]);
|
const hotTags = ref(["化妆品", "汽车零部件", "口罩", "工业用品", "食品"]);
|
||||||
|
|
||||||
|
const activeTab = ref('personal');
|
||||||
|
|
||||||
const stats = reactive<Stats>({
|
const stats = reactive<Stats>({
|
||||||
total: 0,
|
total: 0,
|
||||||
docCount: 0,
|
docCount: 0,
|
||||||
@ -232,6 +320,10 @@ const pageSize = ref(12);
|
|||||||
const currentPage = ref(1);
|
const currentPage = ref(1);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
|
||||||
|
// Separate lists based on share field
|
||||||
|
const personalList = computed(() => repoList.value.filter(repo => Number(repo.share) === 0));
|
||||||
|
const sharedList = computed(() => repoList.value.filter(repo => Number(repo.share) === 1));
|
||||||
|
|
||||||
// 计算属性
|
// 计算属性
|
||||||
const statsList = computed<StatItem[]>(() => [
|
const statsList = computed<StatItem[]>(() => [
|
||||||
{
|
{
|
||||||
@ -258,12 +350,8 @@ const statsList = computed<StatItem[]>(() => [
|
|||||||
|
|
||||||
// 方法
|
// 方法
|
||||||
function updateStats() {
|
function updateStats() {
|
||||||
// 直接从列表数据更新统计,避免重复调用 API
|
|
||||||
stats.total = total.value;
|
stats.total = total.value;
|
||||||
stats.docCount = total.value;
|
stats.docCount = total.value;
|
||||||
// 其他统计数据需要后端提供专门接口时再调用
|
|
||||||
// stats.memberCount = 0; // 需要后端提供
|
|
||||||
// stats.viewCount = 0; // 需要后端提供
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSearch() {
|
function handleSearch() {
|
||||||
@ -276,61 +364,54 @@ function handlePageChange(page: number) {
|
|||||||
fetchRepoList();
|
fetchRepoList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 重构 fetchRepoList 以支持关键词搜索
|
// 重构 fetchRepoList 以支持关键词搜索 (no share filter)
|
||||||
async function fetchRepoList() {
|
async function fetchRepoList() {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
try {
|
try {
|
||||||
const result = await getKnowledgeList({
|
const result = await getKnowledgeList({
|
||||||
page: currentPage.value,
|
page: currentPage.value,
|
||||||
pageSize: pageSize.value,
|
pageSize: pageSize.value,
|
||||||
status: 1, // 只查询已发布的
|
status: 1,
|
||||||
keyword: keyword.value, // 支持关键词搜索
|
keyword: keyword.value,
|
||||||
|
share: -1,
|
||||||
});
|
});
|
||||||
|
|
||||||
// API 返回的数据结构: { code: 0, data: { list: [...], total: 1 }, message: "success" }
|
|
||||||
if (result.code === 0 && result.data) {
|
if (result.code === 0 && result.data) {
|
||||||
repoList.value = result.data.list || [];
|
repoList.value = result.data.list || [];
|
||||||
total.value = result.data.total || 0;
|
total.value = result.data.total || 0;
|
||||||
} else {
|
} else {
|
||||||
// 兼容旧的数据结构(直接返回 list 和 total)
|
|
||||||
repoList.value = result.list || result.data?.list || [];
|
repoList.value = result.list || result.data?.list || [];
|
||||||
total.value = result.total || result.data?.total || 0;
|
total.value = result.total || result.data?.total || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新统计数据(避免重复调用 API)
|
|
||||||
updateStats();
|
updateStats();
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
ElMessage.error(error.message || "获取知识库列表失败");
|
ElMessage.error(error.message || "获取知识库列表失败");
|
||||||
repoList.value = [];
|
repoList.value = [];
|
||||||
total.value = 0;
|
total.value = 0;
|
||||||
updateStats(); // 即使失败也更新统计
|
updateStats();
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCreate() {
|
function handleCreate() {
|
||||||
// 跳转到新建知识库页面,使用路径跳转
|
|
||||||
router.push(`/apps/knowledge/edit/new`);
|
router.push(`/apps/knowledge/edit/new`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleView(repo: Knowledge) {
|
function handleView(repo: Knowledge) {
|
||||||
// 跳转到知识详情页面,使用路径跳转
|
|
||||||
router.push(`/apps/knowledge/detail/${repo.id}`);
|
router.push(`/apps/knowledge/detail/${repo.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleEdit(repo: Knowledge) {
|
function handleEdit(repo: Knowledge) {
|
||||||
// 跳转到编辑知识页面,使用路径跳转
|
|
||||||
router.push(`/apps/knowledge/edit/${repo.id}`);
|
router.push(`/apps/knowledge/edit/${repo.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCategory() {
|
function handleCategory() {
|
||||||
// 跳转到分类管理页面,使用路径跳转
|
|
||||||
router.push(`/apps/knowledge/category`);
|
router.push(`/apps/knowledge/category`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTags() {
|
function handleTags() {
|
||||||
// 跳转到标签管理页面,使用路径跳转
|
|
||||||
router.push(`/apps/knowledge/tags`);
|
router.push(`/apps/knowledge/tags`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,14 +425,12 @@ function handleDelete(repo: Knowledge) {
|
|||||||
try {
|
try {
|
||||||
await deleteKnowledge(repo.id);
|
await deleteKnowledge(repo.id);
|
||||||
ElMessage.success("删除成功");
|
ElMessage.success("删除成功");
|
||||||
fetchRepoList(); // 重新加载列表(会自动更新统计)
|
fetchRepoList();
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
ElMessage.error(error.message || "删除失败");
|
ElMessage.error(error.message || "删除失败");
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {});
|
||||||
// 取消删除
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleHotSearch(tag: string) {
|
function handleHotSearch(tag: string) {
|
||||||
@ -397,7 +476,7 @@ function formatDate(dateStr: string): string {
|
|||||||
|
|
||||||
// 生命周期
|
// 生命周期
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchRepoList(); // 只调用一次,会自动更新统计
|
fetchRepoList();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -924,6 +1003,23 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tabs styling for theme fit
|
||||||
|
.knowledge-tabs {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
:deep(.el-tabs__item) {
|
||||||
|
background-color: var(--fill-color-light);
|
||||||
|
border-color: var(--border-color);
|
||||||
|
color: var(--text-color-primary);
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 响应式调整
|
// 响应式调整
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.hero.new-style {
|
.hero.new-style {
|
||||||
|
|||||||
@ -19,11 +19,13 @@ func (c *KnowledgeController) List() {
|
|||||||
// 获取查询参数
|
// 获取查询参数
|
||||||
page, _ := c.GetInt("page", 1)
|
page, _ := c.GetInt("page", 1)
|
||||||
pageSize, _ := c.GetInt("pageSize", 10)
|
pageSize, _ := c.GetInt("pageSize", 10)
|
||||||
status, _ := c.GetInt8("status", -1) // -1表示查询所有
|
status, _ := c.GetInt8("status", 1) // -1表示查询所有
|
||||||
categoryId, _ := c.GetInt("categoryId", 0)
|
categoryId, _ := c.GetInt("categoryId", 0)
|
||||||
|
share, _ := c.GetInt8("share", -1) // Default -1 to query all
|
||||||
keyword := c.GetString("keyword", "")
|
keyword := c.GetString("keyword", "")
|
||||||
|
|
||||||
knowledges, total, err := models.GetAllKnowledge(page, pageSize, status, categoryId, keyword)
|
// Use share in the query
|
||||||
|
knowledges, total, err := models.GetAllKnowledge(page, pageSize, status, categoryId, share, keyword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Data["json"] = map[string]interface{}{
|
c.Data["json"] = map[string]interface{}{
|
||||||
"code": 1,
|
"code": 1,
|
||||||
@ -107,6 +109,10 @@ func (c *KnowledgeController) Create() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add share parsing (default 0 for personal)
|
||||||
|
share, _ := c.GetInt8("share", 0)
|
||||||
|
knowledge.Share = share
|
||||||
|
|
||||||
id, err := models.AddKnowledge(&knowledge)
|
id, err := models.AddKnowledge(&knowledge)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Data["json"] = map[string]interface{}{
|
c.Data["json"] = map[string]interface{}{
|
||||||
@ -153,6 +159,10 @@ func (c *KnowledgeController) Update() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add share parsing
|
||||||
|
share, _ := c.GetInt8("share", 0) // Default 0 if not provided
|
||||||
|
knowledge.Share = share
|
||||||
|
|
||||||
err = models.UpdateKnowledge(knowledge.Id, &knowledge)
|
err = models.UpdateKnowledge(knowledge.Id, &knowledge)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Data["json"] = map[string]interface{}{
|
c.Data["json"] = map[string]interface{}{
|
||||||
|
|||||||
@ -18,6 +18,7 @@ type Knowledge struct {
|
|||||||
Summary string `orm:"column(summary);size(500);null" json:"summary"`
|
Summary string `orm:"column(summary);size(500);null" json:"summary"`
|
||||||
CoverUrl string `orm:"column(cover_url);size(500);null" json:"coverUrl"`
|
CoverUrl string `orm:"column(cover_url);size(500);null" json:"coverUrl"`
|
||||||
Status int8 `orm:"column(status);default(0)" json:"status"`
|
Status int8 `orm:"column(status);default(0)" json:"status"`
|
||||||
|
Share int8 `orm:"column(share);default(0)" json:"share"`
|
||||||
ViewCount int `orm:"column(view_count);default(0)" json:"viewCount"`
|
ViewCount int `orm:"column(view_count);default(0)" json:"viewCount"`
|
||||||
LikeCount int `orm:"column(like_count);default(0)" json:"likeCount"`
|
LikeCount int `orm:"column(like_count);default(0)" json:"likeCount"`
|
||||||
IsRecommend int8 `orm:"column(is_recommend);default(0)" json:"isRecommend"`
|
IsRecommend int8 `orm:"column(is_recommend);default(0)" json:"isRecommend"`
|
||||||
@ -139,103 +140,78 @@ func GetKnowledgeById(id int) (*Knowledge, error) {
|
|||||||
return knowledge, err
|
return knowledge, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAllKnowledge 获取所有知识(支持分页和筛选)
|
// LightKnowledge for limited fields (with orm and json tags for direct mapping)
|
||||||
func GetAllKnowledge(page, pageSize int, status int8, categoryId int, keyword string) ([]*Knowledge, int64, error) {
|
type LightKnowledge struct {
|
||||||
|
Id int `orm:"column(knowledge_id)" json:"id"`
|
||||||
|
Title string `orm:"column(title)" json:"title"`
|
||||||
|
CategoryId int `orm:"column(category_id)" json:"categoryId"`
|
||||||
|
CategoryName string `orm:"column(category_name)" json:"categoryName"`
|
||||||
|
Tags string `orm:"column(tags)" json:"tags"`
|
||||||
|
Author string `orm:"column(author)" json:"author"`
|
||||||
|
Share int8 `orm:"column(share)" json:"share"`
|
||||||
|
ViewCount int `orm:"column(view_count)" json:"viewCount"`
|
||||||
|
LikeCount int `orm:"column(like_count)" json:"likeCount"`
|
||||||
|
CreateTime time.Time `orm:"column(create_time)" json:"createTime"`
|
||||||
|
UpdateTime time.Time `orm:"column(update_time)" json:"updateTime"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to add conditions (reduces repetition)
|
||||||
|
func addCondition(where *string, params *[]interface{}, cond string, val interface{}) {
|
||||||
|
if val != nil {
|
||||||
|
*where += " AND " + cond
|
||||||
|
*params = append(*params, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllKnowledge (simplified: direct mapping to LightKnowledge, no separate struct or loop)
|
||||||
|
func GetAllKnowledge(page, pageSize int, status int8, categoryId int, share int8, keyword string) ([]*LightKnowledge, int64, error) {
|
||||||
o := orm.NewOrm()
|
o := orm.NewOrm()
|
||||||
|
|
||||||
// 构建 WHERE 条件(只查询未删除的记录)
|
|
||||||
whereSQL := "delete_time IS NULL"
|
whereSQL := "delete_time IS NULL"
|
||||||
params := []interface{}{}
|
params := []interface{}{}
|
||||||
|
|
||||||
// 状态筛选
|
addCondition(&whereSQL, ¶ms, "status = ?", func() interface{} {
|
||||||
if status >= 0 {
|
if status >= 0 {
|
||||||
whereSQL += " AND status = ?"
|
return status
|
||||||
params = append(params, status)
|
}
|
||||||
}
|
return nil
|
||||||
|
}())
|
||||||
|
addCondition(&whereSQL, ¶ms, "category_id = ?", func() interface{} {
|
||||||
|
if categoryId > 0 {
|
||||||
|
return categoryId
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}())
|
||||||
|
addCondition(&whereSQL, ¶ms, "share = ?", func() interface{} {
|
||||||
|
if share >= 0 {
|
||||||
|
return share
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}())
|
||||||
|
addCondition(&whereSQL, ¶ms, "title LIKE ?", func() interface{} {
|
||||||
|
if keyword != "" {
|
||||||
|
return "%" + keyword + "%"
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}())
|
||||||
|
|
||||||
// 分类筛选
|
|
||||||
if categoryId > 0 {
|
|
||||||
whereSQL += " AND category_id = ?"
|
|
||||||
params = append(params, categoryId)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关键词搜索
|
|
||||||
if keyword != "" {
|
|
||||||
whereSQL += " AND title LIKE ?"
|
|
||||||
params = append(params, "%"+keyword+"%")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取总数
|
|
||||||
var total int64
|
var total int64
|
||||||
countSQL := "SELECT COUNT(*) FROM yz_knowledge WHERE " + whereSQL
|
err := o.Raw("SELECT COUNT(*) FROM yz_knowledge WHERE "+whereSQL, params).QueryRow(&total)
|
||||||
err := o.Raw(countSQL, params...).QueryRow(&total)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 联查获取分类名称
|
querySQL := `SELECT k.knowledge_id, k.title, k.category_id, c.category_name, k.tags, k.author, k.share, k.view_count, k.like_count, k.create_time, k.update_time
|
||||||
querySQL := `
|
FROM yz_knowledge k LEFT JOIN yz_knowledge_category c ON k.category_id = c.category_id
|
||||||
SELECT k.*, c.category_name
|
WHERE ` + whereSQL + ` ORDER BY k.is_top DESC, k.create_time DESC LIMIT ? OFFSET ?`
|
||||||
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)
|
params = append(params, pageSize, (page-1)*pageSize)
|
||||||
|
|
||||||
var knowledges []*Knowledge
|
var knowledges []*LightKnowledge
|
||||||
var results []struct {
|
_, err = o.Raw(querySQL, params).QueryRows(&knowledges)
|
||||||
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 {
|
if err != nil {
|
||||||
return nil, 0, err
|
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
|
return knowledges, total, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user