知识库管理页面开发

master
jiangxucong 2 months ago
parent 87325fc3ad
commit db02bd7d5d

@ -116,7 +116,7 @@
</div>
<!-- 公告栏 -->
<div class="bg-white rounded-md shadow-sm p-3 mb-6">
<!-- <div class="bg-white rounded-md shadow-sm p-3 mb-6">
<div class="flex items-center">
<div class="bg-yellow-100 text-yellow-800 px-2 py-1 rounded-button text-xs font-medium mr-3">公告</div>
<div class="scroll-container w-full">
@ -128,7 +128,7 @@
</div>
</div>
</div>
</div>
</div> -->
<!-- 分类筛选 -->
<div class="flex items-center space-x-4 mb-6 overflow-x-auto pb-2">
@ -336,7 +336,7 @@
</main>
<!-- 页脚 -->
<footer class="w-full bg-gray-800 text-white py-8">
<!-- <footer class="w-full bg-gray-800 text-white py-8">
<div class="container mx-auto px-6">
<div class="grid grid-cols-1 md:grid-cols-4 gap-8 mb-6">
<div>
@ -395,6 +395,6 @@
<p>© 2023 人力管理系统 版权所有 | 京ICP备12345678号-1 | 京公网安备11010802012345号</p>
</div>
</div>
</footer>
</footer> -->
</body>
</html>

@ -1,14 +1,411 @@
import React, {Fragment, PureComponent} from 'react';
import { SearchOutlined, PlusOutlined, EyeOutlined, DownloadOutlined, BookOutlined, ShareAltOutlined, LeftOutlined, RightOutlined } from '@ant-design/icons';
import styles from './DocKnowledgebase.less';
class DocKnowledgebase extends PureComponent {
constructor(props) {
super(props);
this.state = {
searchKeyword: '',
activeCategory: '全部',
currentPage: 1,
pageSize: 6, // 每页显示6条
knowledgeList: [
{
id: 1,
title: '2023 年员工手册',
category: '政策制度',
description: '包含公司文化、行为规范、考勤制度、福利政策等最新修订版员工手册,适用于全体员工。',
updateTime: '2023-11-20',
downloadCount: 128,
image: 'https://mastergo.com/ai/api/search-image?query=a20modern20business20document20with20clean20design20and20minimalist20layout20on20a20white20desk20with20a20pen20and20coffee20cup20in20the20background&width=400&height=200&orientation=landscape&flag=1e4cf2beacde2cc80fc63a0f89a9703a',
tagColor: 'blue'
},
{
id: 2,
title: '考勤系统操作指南',
category: '操作手册',
description: '详细说明如何使用公司考勤系统,包括打卡、请假申请、加班申请、考勤异常处理等操作步骤。',
updateTime: '2023-10-15',
downloadCount: 256,
image: 'https://mastergo.com/ai/api/search-image?query=a20step20by20step20illustration20of20HR20software20interface20with20clear20numbering20and20annotations20on20a20light20gray20background&width=400&height=200&orientation=landscape&flag=108451af3b1eb2058f31b710d4071080',
tagColor: 'green'
},
{
id: 3,
title: '新员工入职培训',
category: '培训资料',
description: '新员工入职培训全套资料,包含公司介绍、部门职能、产品知识、安全规范等内容。',
updateTime: '2023-09-28',
downloadCount: 189,
image: 'https://mastergo.com/ai/api/search-image?query=a20professional20training20presentation20slide20with20bullet20points20and20infographics20on20a20projector20screen20in20a20meeting20room&width=400&height=200&orientation=landscape&flag=91a52e2f3cc2550ca2a643ea105f2d4b',
tagColor: 'purple'
},
{
id: 4,
title: 'HR 系统常见问题',
category: '常见问题',
description: '整理了员工在使用 HR 系统过程中遇到的常见问题及解决方案,持续更新中。',
updateTime: '2023-11-05',
viewCount: 342,
image: 'https://mastergo.com/ai/api/search-image?query=a20frequently20asked20questions20list20with20question20marks20and20answers20in20a20modern20digital20interface20design&width=400&height=200&orientation=landscape&flag=923ef06f9362683938111ad04bb8643c',
tagColor: 'orange'
},
{
id: 5,
title: '人力资源常用模板',
category: '模板下载',
description: '包含劳动合同、离职申请表、转正申请表、调岗申请表等常用人力资源表格模板。',
updateTime: '2023-08-12',
downloadCount: 421,
image: 'https://mastergo.com/ai/api/search-image?query=a20collection20of20office20document20templates20including20forms20and20contracts20neatly20stacked20on20a20desk20with20a20laptop&width=400&height=200&orientation=landscape&flag=2a11c867bb72b869508c9cbccb7f198c',
tagColor: 'red'
},
{
id: 6,
title: '绩效考核标准与流程',
category: '政策制度',
description: '详细说明公司绩效考核的标准、流程、时间节点及评分细则,适用于管理人员参考。',
updateTime: '2023-07-30',
downloadCount: 178,
image: 'https://mastergo.com/ai/api/search-image?query=a20performance20management20framework20diagram20with20key20metrics20and20evaluation20criteria20presented20in20a20modern20corporate20style&width=400&height=200&orientation=landscape&flag=72c9f106f07f07f22208f2c8edfd99fb',
tagColor: 'blue'
},
{
id: 7,
title: '薪酬福利制度说明',
category: '政策制度',
description: '详细介绍公司薪酬结构、福利制度、奖励机制等相关政策,帮助员工了解薪酬体系。',
updateTime: '2023-06-15',
downloadCount: 298,
image: 'https://mastergo.com/ai/api/search-image?query=salary20and20benefits20chart20with20colorful20infographics20showing20compensation20structure&width=400&height=200&orientation=landscape&flag=abc123',
tagColor: 'blue'
},
{
id: 8,
title: '安全生产操作规范',
category: '操作手册',
description: '公司安全生产相关规定,包括办公安全、设备使用安全、紧急情况处理等操作指南。',
updateTime: '2023-05-20',
downloadCount: 156,
image: 'https://mastergo.com/ai/api/search-image?query=workplace20safety20guidelines20with20warning20signs20and20safety20equipment&width=400&height=200&orientation=landscape&flag=def456',
tagColor: 'green'
},
{
id: 9,
title: '项目管理培训课程',
category: '培训资料',
description: '针对项目经理和团队成员的项目管理培训材料,包含项目计划、执行、监控等内容。',
updateTime: '2023-04-10',
downloadCount: 234,
image: 'https://mastergo.com/ai/api/search-image?query=project20management20training20presentation20with20gantt20charts20and20timeline&width=400&height=200&orientation=landscape&flag=ghi789',
tagColor: 'purple'
},
{
id: 10,
title: '技术支持常见问题集',
category: '常见问题',
description: '整理了IT设备使用、软件操作、网络连接等技术问题的解决方案和常见问题答疑。',
updateTime: '2023-03-25',
viewCount: 567,
image: 'https://mastergo.com/ai/api/search-image?query=technical20support20FAQ20with20computer20icons20and20troubleshooting20steps&width=400&height=200&orientation=landscape&flag=jkl012',
tagColor: 'orange'
},
{
id: 11,
title: '财务报销流程模板',
category: '模板下载',
description: '包含差旅费报销、办公用品采购、培训费用等各类财务报销申请表格和流程说明。',
updateTime: '2023-02-18',
downloadCount: 389,
image: 'https://mastergo.com/ai/api/search-image?query=financial20reimbursement20forms20and20receipts20on20office20desk&width=400&height=200&orientation=landscape&flag=mno345',
tagColor: 'red'
},
{
id: 12,
title: '企业文化建设指南',
category: '政策制度',
description: '公司企业文化核心价值观、行为准则、团队建设活动指导等文化建设相关内容。',
updateTime: '2023-01-30',
downloadCount: 445,
image: 'https://mastergo.com/ai/api/search-image?query=corporate20culture20guide20with20team20building20activities20and20values&width=400&height=200&orientation=landscape&flag=pqr678',
tagColor: 'blue'
},
{
id: 13,
title: 'OA系统使用手册',
category: '操作手册',
description: '办公自动化系统完整使用指南,包括审批流程、文档管理、通讯录等功能说明。',
updateTime: '2022-12-15',
downloadCount: 678,
image: 'https://mastergo.com/ai/api/search-image?query=office20automation20system20interface20with20workflow20diagrams&width=400&height=200&orientation=landscape&flag=stu901',
tagColor: 'green'
},
{
id: 14,
title: '销售技能提升培训',
category: '培训资料',
description: '销售团队技能提升培训材料,包含客户沟通技巧、产品知识、销售流程等内容。',
updateTime: '2022-11-20',
downloadCount: 356,
image: 'https://mastergo.com/ai/api/search-image?query=sales20training20presentation20with20charts20and20customer20interaction&width=400&height=200&orientation=landscape&flag=vwx234',
tagColor: 'purple'
}
]
};
}
handleCategoryChange = (category) => {
this.setState({
activeCategory: category,
currentPage: 1 // 切换分类时重置到第一页
});
};
handleSearch = (e) => {
this.setState({
searchKeyword: e.target.value,
currentPage: 1 // 搜索时重置到第一页
});
};
handlePageChange = (page) => {
this.setState({ currentPage: page });
};
handlePrevPage = () => {
const { currentPage } = this.state;
if (currentPage > 1) {
this.setState({ currentPage: currentPage - 1 });
}
};
handleNextPage = () => {
const { currentPage } = this.state;
const totalPages = this.getTotalPages();
if (currentPage < totalPages) {
this.setState({ currentPage: currentPage + 1 });
}
};
getFilteredList = () => {
const { searchKeyword, activeCategory, knowledgeList } = this.state;
return knowledgeList.filter(item => {
const matchCategory = activeCategory === '全部' || item.category === activeCategory;
const matchSearch = item.title.toLowerCase().includes(searchKeyword.toLowerCase()) ||
item.description.toLowerCase().includes(searchKeyword.toLowerCase());
return matchCategory && matchSearch;
});
};
getTotalPages = () => {
const { pageSize } = this.state;
const filteredList = this.getFilteredList();
return Math.ceil(filteredList.length / pageSize);
};
getCurrentPageData = () => {
const { currentPage, pageSize } = this.state;
const filteredList = this.getFilteredList();
const startIndex = (currentPage - 1) * pageSize;
const endIndex = startIndex + pageSize;
return filteredList.slice(startIndex, endIndex);
};
getVisiblePages = () => {
const { currentPage } = this.state;
const totalPages = this.getTotalPages();
const visiblePages = [];
// 显示当前页前后各2页
const start = Math.max(1, currentPage - 2);
const end = Math.min(totalPages, currentPage + 2);
for (let i = start; i <= end; i++) {
visiblePages.push(i);
}
return visiblePages;
};
getTagClassName = (color) => {
const colorMap = {
blue: styles.tagBlue,
green: styles.tagGreen,
purple: styles.tagPurple,
orange: styles.tagOrange,
red: styles.tagRed
};
return colorMap[color] || styles.tagBlue;
};
render() {
const { searchKeyword, activeCategory, currentPage } = this.state;
const categories = ['全部', '政策制度', '操作手册', '培训资料', '常见问题', '模板下载'];
const currentPageData = this.getCurrentPageData();
const totalPages = this.getTotalPages();
const visiblePages = this.getVisiblePages();
const filteredTotal = this.getFilteredList().length;
return (
<>
<iframe title="知识管理" className={styles.frameContent} src="/知识管理.html"/>
</>
<div className={styles.container}>
{/* 主内容区域 */}
<main className={styles.main}>
{/* 页面标题和操作区 */}
<div className={styles.header}>
{/* <h1 className={styles.title}>知识库管理</h1> */}
<div className={styles.headerActions}>
<div className={styles.searchBox}>
<input
type="text"
placeholder="搜索知识..."
value={searchKeyword}
onChange={this.handleSearch}
className={styles.searchInput}
/>
<SearchOutlined className={styles.searchIcon} />
</div>
<button className={styles.addButton}>
<PlusOutlined />
<span>新建知识</span>
</button>
</div>
</div>
{/* 分类筛选 */}
<div className={styles.categoryFilter}>
{categories.map(category => (
<button
key={category}
className={`${styles.categoryBtn} ${activeCategory === category ? styles.active : ''}`}
onClick={() => this.handleCategoryChange(category)}
>
{category}
</button>
))}
</div>
{/* 结果统计 */}
<div className={styles.resultInfo}>
<span>共找到 {filteredTotal} 条知识当前第 {currentPage} {totalPages} </span>
</div>
{/* 知识卡片列表 */}
<div className={styles.knowledgeGrid}>
{currentPageData.map(item => (
<div key={item.id} className={styles.knowledgeCard}>
<div className={styles.cardImage}>
<img src={item.image} alt={item.title} />
</div>
<div className={styles.cardContent}>
<div className={styles.cardHeader}>
<h3 className={styles.cardTitle}>{item.title}</h3>
<span className={`${styles.categoryTag} ${this.getTagClassName(item.tagColor)}`}>
{item.category}
</span>
</div>
<p className={styles.cardDescription}>{item.description}</p>
<div className={styles.cardMeta}>
<span>更新于 {item.updateTime}</span>
<span>
{item.downloadCount ? `下载 ${item.downloadCount}` : `浏览 ${item.viewCount}`}
</span>
</div>
<div className={styles.cardActions}>
<button className={styles.actionBtn}>
<EyeOutlined />
{item.category === '常见问题' ? '查看' : '预览'}
</button>
<button className={styles.actionBtn}>
{item.category === '常见问题' ? <BookOutlined /> : <DownloadOutlined />}
{item.category === '常见问题' ? '收藏' : '下载'}
</button>
<button className={styles.actionBtn}>
<ShareAltOutlined /> 分享
</button>
</div>
</div>
</div>
))}
</div>
{/* 空状态 */}
{currentPageData.length === 0 && (
<div className={styles.emptyState}>
<SearchOutlined style={{ fontSize: '48px', color: '#d1d5db', marginBottom: '16px' }} />
<p>未找到相关知识</p>
<p>请尝试调整搜索关键词或筛选条件</p>
</div>
)}
{/* 真实分页 */}
{totalPages > 1 && (
<div className={styles.pagination}>
<nav className={styles.paginationNav}>
<button
className={`${styles.paginationBtn} ${currentPage === 1 ? styles.disabled : ''}`}
onClick={this.handlePrevPage}
disabled={currentPage === 1}
>
<LeftOutlined />
</button>
{/* 显示第一页 */}
{visiblePages[0] > 1 && (
<>
<button
className={styles.paginationBtn}
onClick={() => this.handlePageChange(1)}
>
1
</button>
{visiblePages[0] > 2 && (
<span className={styles.paginationEllipsis}>...</span>
)}
</>
)}
{/* 显示可见页码 */}
{visiblePages.map(page => (
<button
key={page}
className={`${styles.paginationBtn} ${currentPage === page ? styles.paginationActive : ''}`}
onClick={() => this.handlePageChange(page)}
>
{page}
</button>
))}
{/* 显示最后一页 */}
{visiblePages[visiblePages.length - 1] < totalPages && (
<>
{visiblePages[visiblePages.length - 1] < totalPages - 1 && (
<span className={styles.paginationEllipsis}>...</span>
)}
<button
className={styles.paginationBtn}
onClick={() => this.handlePageChange(totalPages)}
>
{totalPages}
</button>
</>
)}
<button
className={`${styles.paginationBtn} ${currentPage === totalPages ? styles.disabled : ''}`}
onClick={this.handleNextPage}
disabled={currentPage === totalPages}
>
<RightOutlined />
</button>
</nav>
</div>
)}
</main>
</div>
)
}
}
export default DocKnowledgebase
export default DocKnowledgebase

@ -1,10 +1,431 @@
@import '~@/utils/utils.less';
.container {
min-height: 95vh;
max-height: 95vh; // 限制最大高度
display: flex;
flex-direction: column;
background-color: #F5F6FA;
overflow-y: auto; // 垂直滚动
overflow-x: hidden; // 隐藏水平滚动
}
.frameContent {
.main {
flex: 1;
max-width: 1200px;
margin: 0 auto;
padding: 32px 24px;
width: 100%;
height: 100vh;
border: none;
display: block;
margin: 0;
padding: 0;
box-sizing: border-box;
}
.header {
display: flex;
justify-content: flex-end;
align-items: center;
margin-bottom: 24px;
.title {
font-size: 24px;
font-weight: bold;
color: #1f2937;
margin: 0;
}
.headerActions {
display: flex;
gap: 12px;
.searchBox {
position: relative;
.searchInput {
padding: 8px 12px 8px 40px;
font-size: 14px;
border-radius: 4px;
border: 1px solid #d1d5db;
outline: none;
width: 200px;
&:focus {
outline: none;
border-color: #2D5CF6;
box-shadow: 0 0 0 1px #2D5CF6;
}
}
.searchIcon {
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
color: #9ca3af;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
}
}
.addButton {
background-color: #2D5CF6;
color: white;
padding: 8px 16px;
border-radius: 4px;
border: none;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
&:hover {
background-color: rgba(45, 92, 246, 0.9);
}
span {
white-space: nowrap;
}
.anticon {
font-size: 14px;
}
}
}
}
.categoryFilter {
display: flex;
align-items: center;
gap: 16px;
margin-bottom: 24px;
overflow-x: auto; // 水平滚动
padding-bottom: 8px;
// 自定义滚动条样式
&::-webkit-scrollbar {
height: 4px;
}
&::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 2px;
}
&::-webkit-scrollbar-thumb {
background: #888;
border-radius: 2px;
}
&::-webkit-scrollbar-thumb:hover {
background: #555;
}
.categoryBtn {
padding: 8px 16px;
border-radius: 4px;
border: 1px solid #e5e7eb;
background-color: white;
cursor: pointer;
white-space: nowrap;
&:hover {
background-color: #f9fafb;
}
&.active {
background-color: #2D5CF6;
color: white;
border-color: #2D5CF6;
}
}
}
.resultInfo {
margin-bottom: 16px;
font-size: 14px;
color: #6b7280;
}
.knowledgeGrid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
gap: 24px;
margin-bottom: 32px;
min-height: 400px; // 最小高度,确保有内容区域
@media (max-width: 768px) {
grid-template-columns: 1fr;
}
@media (min-width: 769px) and (max-width: 1024px) {
grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 1025px) {
grid-template-columns: repeat(3, 1fr);
}
}
.knowledgeCard {
background-color: white;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
overflow: hidden;
transition: all 0.3s ease;
&:hover {
transform: translateY(-4px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}
.cardImage {
height: 160px;
overflow: hidden;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.cardContent {
padding: 16px;
.cardHeader {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 8px;
.cardTitle {
font-weight: 500;
color: #1f2937;
margin: 0;
font-size: 16px;
}
.categoryTag {
font-size: 12px;
padding: 2px 8px;
border-radius: 4px;
white-space: nowrap;
&.tagBlue {
background-color: #dbeafe;
color: #1e40af;
}
&.tagGreen {
background-color: #dcfce7;
color: #166534;
}
&.tagPurple {
background-color: #f3e8ff;
color: #7c2d12;
}
&.tagOrange {
background-color: #fed7aa;
color: #c2410c;
}
&.tagRed {
background-color: #fecaca;
color: #dc2626;
}
}
}
.cardDescription {
font-size: 14px;
color: #6b7280;
margin-bottom: 12px;
line-height: 1.4;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.cardMeta {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 12px;
color: #9ca3af;
margin-bottom: 12px;
}
.cardActions {
display: flex;
gap: 8px;
.actionBtn {
color: #2D5CF6;
background: none;
border: none;
cursor: pointer;
font-size: 14px;
display: flex;
align-items: center;
gap: 4px;
&:hover {
color: rgba(45, 92, 246, 0.8);
}
.anticon {
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
}
}
}
}
}
.emptyState {
text-align: center;
padding: 64px 0;
color: #9ca3af;
p {
margin: 8px 0;
&:first-of-type {
font-size: 16px;
color: #6b7280;
}
&:last-of-type {
font-size: 14px;
}
}
}
.pagination {
display: flex;
justify-content: center;
margin-top: 32px;
padding-bottom: 32px; // 底部留出空间
.paginationNav {
display: inline-flex;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
.paginationBtn {
padding: 8px 12px;
border: 1px solid #d1d5db;
background-color: white;
color: #374151;
cursor: pointer;
transition: all 0.2s ease;
&:not(:first-child) {
margin-left: -1px;
}
&:first-child {
border-top-left-radius: 8px;
border-bottom-left-radius: 8px;
}
&:last-child {
border-top-right-radius: 8px;
border-bottom-right-radius: 8px;
}
&:hover:not(.disabled):not(.paginationActive) {
background-color: #f9fafb;
border-color: #2D5CF6;
color: #2D5CF6;
}
&.paginationActive {
background-color: #2D5CF6;
color: white;
border-color: #2D5CF6;
z-index: 1;
position: relative;
}
&.disabled {
background-color: #f9fafb;
color: #d1d5db;
cursor: not-allowed;
border-color: #e5e7eb;
}
.anticon {
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
}
}
.paginationEllipsis {
padding: 8px 12px;
border: 1px solid #d1d5db;
background-color: white;
color: #9ca3af;
margin-left: -1px;
display: flex;
align-items: center;
}
}
}
// 响应式设计
@media (max-width: 768px) {
.main {
padding: 16px;
}
.header {
flex-direction: column;
gap: 16px;
align-items: stretch;
.headerActions {
justify-content: space-between;
.searchBox .searchInput {
width: 150px;
}
}
}
.categoryFilter {
gap: 8px;
}
}
// 全局滚动条样式
.container {
// 自定义滚动条样式
&::-webkit-scrollbar {
width: 8px;
}
&::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 4px;
}
&::-webkit-scrollbar-thumb {
background: #888;
border-radius: 4px;
}
&::-webkit-scrollbar-thumb:hover {
background: #555;
}
}
// 为内容区域添加额外的滚动支持
.main {
overflow-x: hidden; // 防止水平溢出
}

@ -1,14 +1,204 @@
import React, {Fragment, PureComponent} from 'react';
import styles from './QaKnowledgebase.less';
class QaKnowledgebase extends PureComponent {
constructor(props) {
super(props);
this.state = {
searchKeyword: '',
activeCategory: '全部',
knowledgeList: [
{
id: 1,
title: '2023 年员工手册',
category: '政策制度',
description: '包含公司文化、行为规范、考勤制度、福利政策等最新修订版员工手册,适用于全体员工。',
updateTime: '2023-11-20',
downloadCount: 128,
image: 'https://mastergo.com/ai/api/search-image?query=a20modern20business20document20with20clean20design20and20minimalist20layout20on20a20white20desk20with20a20pen20and20coffee20cup20in20the20background&width=400&height=200&orientation=landscape&flag=1e4cf2beacde2cc80fc63a0f89a9703a',
tagColor: 'blue'
},
{
id: 2,
title: '考勤系统操作指南',
category: '操作手册',
description: '详细说明如何使用公司考勤系统,包括打卡、请假申请、加班申请、考勤异常处理等操作步骤。',
updateTime: '2023-10-15',
downloadCount: 256,
image: 'https://mastergo.com/ai/api/search-image?query=a20step20by20step20illustration20of20HR20software20interface20with20clear20numbering20and20annotations20on20a20light20gray20background&width=400&height=200&orientation=landscape&flag=108451af3b1eb2058f31b710d4071080',
tagColor: 'green'
},
{
id: 3,
title: '新员工入职培训',
category: '培训资料',
description: '新员工入职培训全套资料,包含公司介绍、部门职能、产品知识、安全规范等内容。',
updateTime: '2023-09-28',
downloadCount: 189,
image: 'https://mastergo.com/ai/api/search-image?query=a20professional20training20presentation20slide20with20bullet20points20and20infographics20on20a20projector20screen20in20a20meeting20room&width=400&height=200&orientation=landscape&flag=91a52e2f3cc2550ca2a643ea105f2d4b',
tagColor: 'purple'
},
{
id: 4,
title: 'HR 系统常见问题',
category: '常见问题',
description: '整理了员工在使用 HR 系统过程中遇到的常见问题及解决方案,持续更新中。',
updateTime: '2023-11-05',
viewCount: 342,
image: 'https://mastergo.com/ai/api/search-image?query=a20frequently20asked20questions20list20with20question20marks20and20answers20in20a20modern20digital20interface20design&width=400&height=200&orientation=landscape&flag=923ef06f9362683938111ad04bb8643c',
tagColor: 'orange'
},
{
id: 5,
title: '人力资源常用模板',
category: '模板下载',
description: '包含劳动合同、离职申请表、转正申请表、调岗申请表等常用人力资源表格模板。',
updateTime: '2023-08-12',
downloadCount: 421,
image: 'https://mastergo.com/ai/api/search-image?query=a20collection20of20office20document20templates20including20forms20and20contracts20neatly20stacked20on20a20desk20with20a20laptop&width=400&height=200&orientation=landscape&flag=2a11c867bb72b869508c9cbccb7f198c',
tagColor: 'red'
},
{
id: 6,
title: '绩效考核标准与流程',
category: '政策制度',
description: '详细说明公司绩效考核的标准、流程、时间节点及评分细则,适用于管理人员参考。',
updateTime: '2023-07-30',
downloadCount: 178,
image: 'https://mastergo.com/ai/api/search-image?query=a20performance20management20framework20diagram20with20key20metrics20and20evaluation20criteria20presented20in20a20modern20corporate20style&width=400&height=200&orientation=landscape&flag=72c9f106f07f07f22208f2c8edfd99fb',
tagColor: 'blue'
}
]
};
}
handleCategoryChange = (category) => {
this.setState({ activeCategory: category });
};
handleSearch = (e) => {
this.setState({ searchKeyword: e.target.value });
};
getTagClassName = (color) => {
const colorMap = {
blue: styles.tagBlue,
green: styles.tagGreen,
purple: styles.tagPurple,
orange: styles.tagOrange,
red: styles.tagRed
};
return colorMap[color] || styles.tagBlue;
};
render() {
const { searchKeyword, activeCategory, knowledgeList } = this.state;
const categories = ['全部', '政策制度', '操作手册', '培训资料', '常见问题', '模板下载'];
const filteredList = knowledgeList.filter(item => {
const matchCategory = activeCategory === '全部' || item.category === activeCategory;
const matchSearch = item.title.toLowerCase().includes(searchKeyword.toLowerCase()) ||
item.description.toLowerCase().includes(searchKeyword.toLowerCase());
return matchCategory && matchSearch;
});
return (
<>
<iframe title="知识管理" className={styles.frameContent} src="/知识管理.html"/>
</>
<div className={styles.container}>
{/* 主内容区域 */}
<main className={styles.main}>
{/* 页面标题和操作区 */}
<div className={styles.header}>
<h1 className={styles.title}>知识库管理</h1>
<div className={styles.headerActions}>
<div className={styles.searchBox}>
<input
type="text"
placeholder="搜索知识..."
value={searchKeyword}
onChange={this.handleSearch}
className={styles.searchInput}
/>
<i className="fas fa-search"></i>
</div>
<button className={styles.addButton}>
<i className="fas fa-plus"></i>
<span>新建知识</span>
</button>
</div>
</div>
{/* 分类筛选 */}
<div className={styles.categoryFilter}>
{categories.map(category => (
<button
key={category}
className={`${styles.categoryBtn} ${activeCategory === category ? styles.active : ''}`}
onClick={() => this.handleCategoryChange(category)}
>
{category}
</button>
))}
</div>
{/* 知识卡片列表 */}
<div className={styles.knowledgeGrid}>
{filteredList.map(item => (
<div key={item.id} className={styles.knowledgeCard}>
<div className={styles.cardImage}>
<img src={item.image} alt={item.title} />
</div>
<div className={styles.cardContent}>
<div className={styles.cardHeader}>
<h3 className={styles.cardTitle}>{item.title}</h3>
<span className={`${styles.categoryTag} ${this.getTagClassName(item.tagColor)}`}>
{item.category}
</span>
</div>
<p className={styles.cardDescription}>{item.description}</p>
<div className={styles.cardMeta}>
<span>更新于 {item.updateTime}</span>
<span>
{item.downloadCount ? `下载 ${item.downloadCount}` : `浏览 ${item.viewCount}`}
</span>
</div>
<div className={styles.cardActions}>
<button className={styles.actionBtn}>
<i className="fas fa-eye"></i>
{item.category === '常见问题' ? '查看' : '预览'}
</button>
<button className={styles.actionBtn}>
<i className={`fas ${item.category === '常见问题' ? 'fa-bookmark' : 'fa-download'}`}></i>
{item.category === '常见问题' ? '收藏' : '下载'}
</button>
<button className={styles.actionBtn}>
<i className="fas fa-share-alt"></i>
</button>
</div>
</div>
</div>
))}
</div>
{/* 分页 */}
<div className={styles.pagination}>
<nav className={styles.paginationNav}>
<button className={styles.paginationBtn}>
<i className="fas fa-chevron-left"></i>
</button>
<button className={`${styles.paginationBtn} ${styles.paginationActive}`}>1</button>
<button className={styles.paginationBtn}>2</button>
<button className={styles.paginationBtn}>3</button>
<button className={styles.paginationBtn}>4</button>
<button className={styles.paginationBtn}>5</button>
<button className={styles.paginationBtn}>
<i className="fas fa-chevron-right"></i>
</button>
</nav>
</div>
</main>
</div>
)
}
}
export default QaKnowledgebase
export default QaKnowledgebase

@ -1,10 +1,371 @@
@import '~@/utils/utils.less';
.frameContent {
width: 100%;
height: 100vh;
border: none;
display: block;
margin: 0;
padding: 0;
.container {
min-height: 1024px;
display: flex;
flex-direction: column;
background-color: #F5F6FA;
}
.main {
flex: 1;
max-width: 1200px;
margin: 0 auto;
padding: 32px 24px;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24px;
.title {
font-size: 24px;
font-weight: bold;
color: #1f2937;
margin: 0;
}
.headerActions {
display: flex;
gap: 12px;
.searchBox {
position: relative;
.searchInput {
padding: 8px 12px 8px 40px;
font-size: 14px;
border-radius: 4px;
border: 1px solid #d1d5db;
outline: none;
width: 200px;
&:focus {
outline: none;
border-color: #2D5CF6;
box-shadow: 0 0 0 1px #2D5CF6;
}
}
i {
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
color: #9ca3af;
display: flex;
justify-content: center;
align-items: center;
}
}
.addButton {
background-color: #2D5CF6;
color: white;
padding: 8px 16px;
border-radius: 4px;
border: none;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
&:hover {
background-color: rgba(45, 92, 246, 0.9);
}
span {
white-space: nowrap;
}
}
}
}
.categoryFilter {
display: flex;
align-items: center;
gap: 16px;
margin-bottom: 24px;
overflow-x: auto;
padding-bottom: 8px;
.categoryBtn {
padding: 8px 16px;
border-radius: 4px;
border: 1px solid #e5e7eb;
background-color: white;
cursor: pointer;
white-space: nowrap;
&:hover {
background-color: #f9fafb;
}
&.active {
background-color: #2D5CF6;
color: white;
border-color: #2D5CF6;
}
}
}
.knowledgeGrid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
gap: 24px;
margin-bottom: 32px;
@media (max-width: 768px) {
grid-template-columns: 1fr;
}
@media (min-width: 769px) and (max-width: 1024px) {
grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 1025px) {
grid-template-columns: repeat(3, 1fr);
}
}
.knowledgeCard {
background-color: white;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
overflow: hidden;
transition: all 0.3s ease;
&:hover {
transform: translateY(-4px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}
.cardImage {
height: 160px;
overflow: hidden;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.cardContent {
padding: 16px;
.cardHeader {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 8px;
.cardTitle {
font-weight: 500;
color: #1f2937;
margin: 0;
font-size: 16px;
}
.categoryTag {
font-size: 12px;
padding: 2px 8px;
border-radius: 4px;
white-space: nowrap;
&.tagBlue {
background-color: #dbeafe;
color: #1e40af;
}
&.tagGreen {
background-color: #dcfce7;
color: #166534;
}
&.tagPurple {
background-color: #f3e8ff;
color: #7c2d12;
}
&.tagOrange {
background-color: #fed7aa;
color: #c2410c;
}
&.tagRed {
background-color: #fecaca;
color: #dc2626;
}
}
}
.cardDescription {
font-size: 14px;
color: #6b7280;
margin-bottom: 12px;
line-height: 1.4;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.cardMeta {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 12px;
color: #9ca3af;
margin-bottom: 12px;
}
.cardActions {
display: flex;
gap: 8px;
.actionBtn {
color: #2D5CF6;
background: none;
border: none;
cursor: pointer;
font-size: 14px;
display: flex;
align-items: center;
gap: 4px;
&:hover {
color: rgba(45, 92, 246, 0.8);
}
i {
display: flex;
justify-content: center;
align-items: center;
}
}
}
}
}
.resultInfo {
margin-bottom: 16px;
font-size: 14px;
color: #6b7280;
}
.emptyState {
text-align: center;
padding: 64px 0;
color: #9ca3af;
p {
margin: 8px 0;
&:first-of-type {
font-size: 16px;
color: #6b7280;
}
&:last-of-type {
font-size: 14px;
}
}
}
.pagination {
display: flex;
justify-content: center;
margin-top: 32px;
.paginationNav {
display: inline-flex;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
.paginationBtn {
padding: 8px 12px;
border: 1px solid #d1d5db;
background-color: white;
color: #374151;
cursor: pointer;
transition: all 0.2s ease;
&:not(:first-child) {
margin-left: -1px;
}
&:first-child {
border-top-left-radius: 8px;
border-bottom-left-radius: 8px;
}
&:last-child {
border-top-right-radius: 8px;
border-bottom-right-radius: 8px;
}
&:hover:not(.disabled):not(.paginationActive) {
background-color: #f9fafb;
border-color: #2D5CF6;
color: #2D5CF6;
}
&.paginationActive {
background-color: #2D5CF6;
color: white;
border-color: #2D5CF6;
z-index: 1;
position: relative;
}
&.disabled {
background-color: #f9fafb;
color: #d1d5db;
cursor: not-allowed;
border-color: #e5e7eb;
}
i {
display: flex;
justify-content: center;
align-items: center;
}
}
.paginationEllipsis {
padding: 8px 12px;
border: 1px solid #d1d5db;
background-color: white;
color: #9ca3af;
margin-left: -1px;
display: flex;
align-items: center;
}
}
}
// 响应式设计
@media (max-width: 768px) {
.main {
padding: 16px;
}
.header {
flex-direction: column;
gap: 16px;
align-items: stretch;
.headerActions {
justify-content: space-between;
.searchBox .searchInput {
width: 150px;
}
}
}
.categoryFilter {
gap: 8px;
}
}
Loading…
Cancel
Save