优化企业网站功能

This commit is contained in:
2026-08-20 16:21:07 +08:00
parent 112d60b993
commit 3f0fcb88e7
45 changed files with 8758 additions and 5058 deletions
@@ -0,0 +1,349 @@
<template>
<el-drawer v-model="visible" title="文章预览" size="60%">
<div class="article-preview">
<div class="article-header">
<h1 class="article-title">{{ model?.title || "无标题" }}</h1>
<div class="article-meta">
<span class="meta-item">
<i class="el-icon-price-tag"></i>
<el-tag type="primary">{{ getCategoryName(model?.cate) }}</el-tag>
</span>
<span class="meta-item">
<i class="el-icon-user"></i>
作者:{{ model?.author }}
</span>
<span class="meta-item">
<i class="el-icon-view"></i>
发布人:{{ model?.publisher || "暂未发布" }}
</span>
<span class="meta-item">
<i class="el-icon-view"></i>
阅读量:{{ model?.views || 0 }}
</span>
<span class="meta-item">
<i class="el-icon-view"></i>
收藏量:{{ model?.likes || 0 }}
</span>
<span class="meta-item" v-if="model?.publish_time">
<i class="el-icon-time"></i>
{{ formatDate(model.publish_time) }}
</span>
<span class="meta-item">
<i class="el-icon-view"></i>
创建日期:{{ model?.create_time }}
</span>
</div>
</div>
<div class="article-content">
<div
v-if="model?.content"
v-html="model.content"
class="content-html"
></div>
<div v-else class="no-content">
<el-empty description="暂无内容"></el-empty>
</div>
</div>
</div>
</el-drawer>
</template>
<script lang="ts" setup>
import { ref, watch, onMounted } from "vue";
import { listCategories } from "@/api/article";
import { ElMessage, ElMessageBox } from "element-plus";
const categoryOptions = ref([]);
const props = defineProps({
modelValue: {
type: Boolean,
default: false,
},
model: {
type: Object,
default: () => null,
},
});
// 获取分类列表
const fetchCategories = async () => {
try {
const res = await listCategories({ page: 1, limit: 1000 });
if (res.code === 200) {
categoryOptions.value = Array.isArray(res.data)
? res.data
: Array.isArray(res.data?.list)
? res.data.list
: [];
} else {
ElMessage.error(res?.msg || "获取分类列表失败");
}
} catch (error) {
ElMessage.error("获取分类列表失败");
}
};
// 根据分类ID获取分类名称
const getCategoryName = (cate) => {
if (!cate && cate !== 0) return "无分类";
// 确保比较时类型一致
const cateId = Number(cate);
// 传入的不是数字(已经是分类名),直接展示
if (Number.isNaN(cateId)) return String(cate);
const category = categoryOptions.value.find(
(item) => Number(item.id) === cateId,
);
return category?.name || "无分类";
};
const emit = defineEmits(["update:modelValue"]);
const visible = ref(false);
// 监听对话框显示状态
watch(
() => props.modelValue,
(newVal) => {
visible.value = newVal;
},
);
// 监听visible变化,同步给父组件
watch(visible, (newVal) => {
emit("update:modelValue", newVal);
});
onMounted(() => {
fetchCategories();
});
</script>
<style lang="less" scoped>
.article-preview {
padding: 20px;
.article-header {
border-bottom: 1px solid #ebeef5;
padding-bottom: 20px;
margin-bottom: 20px;
.article-title {
margin: 0 0 15px 0;
font-size: 24px;
font-weight: 600;
color: #303133;
line-height: 1.4;
}
.article-meta {
display: flex;
flex-wrap: wrap;
gap: 15px;
color: #909399;
font-size: 14px;
.meta-item {
display: flex;
align-items: center;
gap: 5px;
i {
font-size: 16px;
}
}
}
}
.article-content {
/* 确保article-content直接子元素的样式 */
& > div {
line-height: 1.8;
color: #606266;
padding: 20px 0;
}
/* 支持所有子元素的内联样式 */
* {
box-sizing: border-box;
}
/* 段落样式 */
p {
margin: 10px 0;
line-height: 1.8;
}
/* 标题样式 */
h1,
h2,
h3,
h4,
h5,
h6 {
margin: 20px 0 10px 0;
font-weight: 600;
}
h1 {
font-size: 28px;
}
h2 {
font-size: 24px;
}
h3 {
font-size: 20px;
}
h4 {
font-size: 18px;
}
h5 {
font-size: 16px;
}
h6 {
font-size: 14px;
}
/* 列表样式 */
ul,
ol {
margin: 10px 0;
padding-left: 30px;
}
/* 引用样式 */
blockquote {
border-left: 4px solid #ebeef5;
padding-left: 15px;
margin: 15px 0;
color: #909399;
font-style: italic;
}
/* 代码样式 */
:deep(code) {
border-radius: 4px;
padding: 2px 6px;
font-family: "JetBrains Mono", "Fira Code", "Consolas", monospace;
font-size: 13px;
color: #f06b6b;
}
/* 代码块样式 */
:deep(pre) {
background: linear-gradient(135deg, #1e1e2e 0%, #2d2d3f 100%);
border-radius: 12px;
padding: 10px;
overflow-x: auto;
margin: 20px 0;
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
}
/* 图片样式 */
img {
max-width: 100%;
height: auto;
border-radius: 4px;
margin: 10px 0;
}
/* 表格样式 */
table {
width: 100%;
border-collapse: collapse;
margin: 15px 0;
th,
td {
border: 1px solid #ebeef5;
padding: 8px 12px;
text-align: left;
}
th {
background-color: #fafafa;
font-weight: 600;
}
}
/* 确保内联样式能够生效 */
[style] {
/* 允许内联样式正常工作 */
all: unset;
/* 重新应用基本样式 */
line-height: 1.8;
color: #606266;
/* 允许特定内联样式覆盖 */
&[style*="text-align"] {
text-align: var(--text-align, inherit) !important;
}
&[style*="color"] {
color: var(--color, inherit) !important;
}
&[style*="font-size"] {
font-size: var(--font-size, inherit) !important;
}
&[style*="font-weight"] {
font-weight: var(--font-weight, inherit) !important;
}
&[style*="font-style"] {
font-style: var(--font-style, inherit) !important;
}
&[style*="text-decoration"] {
text-decoration: var(--text-decoration, inherit) !important;
}
&[style*="margin"] {
margin: var(--margin, inherit) !important;
}
&[style*="padding"] {
padding: var(--padding, inherit) !important;
}
}
/* 直接支持text-align属性 */
[align] {
text-align: attr(align) !important;
}
/* 确保content-html类的样式 */
.content-html {
& > * {
margin: 10px 0;
}
& > h1,
& > h2,
& > h3,
& > h4,
& > h5,
& > h6 {
margin: 20px 0 10px 0;
}
& > p {
margin: 10px 0;
}
/* 支持居中样式 */
& > p[style*="text-align: center"],
& > p[align="center"] {
text-align: center !important;
}
/* 图片居中 */
& > p[style*="text-align: center"] img,
& > p[align="center"] img {
display: inline-block;
margin: 10px auto;
}
}
.no-content {
text-align: center;
padding: 40px 0;
}
}
}
</style>