Files
supervision-test-frontend-repo/src/views/tasklist/components/HelpModal.vue
T

419 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<a-modal
:open="visible"
title="事项计划 — 使用说明"
width="1100px"
:footer="null"
:body-style="{ padding: 0 }"
wrap-class-name="help-doc-modal"
@cancel="handleClose"
>
<div class="help-doc">
<div class="help-doc-nav">
<div
v-for="chapter in chapters"
:key="chapter.id"
class="nav-item"
:class="{ active: activeChapter === chapter.id }"
@click="scrollToChapter(chapter.id)"
>
<Icon :icon="chapter.icon" class="nav-icon" />
<span>{{ chapter.title }}</span>
</div>
</div>
<div ref="contentRef" class="help-doc-content">
<div v-for="chapter in chapters" :key="chapter.id" :id="chapter.id" class="chapter">
<h3 class="chapter-title">
<Icon :icon="chapter.icon" class="chapter-icon" />
{{ chapter.title }}
</h3>
<div v-for="(section, si) in chapter.sections" :key="si" class="section">
<h4 v-if="section.heading" class="section-heading">{{ section.heading }}</h4>
<div v-if="section.text" class="section-text" v-html="section.text"></div>
<div v-if="section.image" class="doc-image">
<img :src="section.image" :alt="section.heading" class="doc-image-img" />
</div>
</div>
</div>
</div>
</div>
</a-modal>
</template>
<script lang="ts" setup>
import { ref, watch, nextTick } from 'vue';
import Icon from '/@/components/Icon';
import createPlanImg from '/@/assets/images/create-plan.png';
import createTaskQuickImg from '/@/assets/images/create-task-quick.png';
import createTaskDetailImg from '/@/assets/images/create-task-detail.png';
import manageCollaboratorImg from '/@/assets/images/manage-collaborator.png';
import subtaskViewImg from '/@/assets/images/subtask-view.png';
const props = defineProps<{ open: boolean }>();
const emit = defineEmits<{ 'update:open': [value: boolean] }>();
const visible = ref(props.open);
watch(
() => props.open,
(val) => {
visible.value = val;
}
);
watch(visible, (val) => {
emit('update:open', val);
});
function handleClose() {
visible.value = false;
}
const contentRef = ref<HTMLElement | null>(null);
const activeChapter = ref('quickstart');
function scrollToChapter(id: string) {
activeChapter.value = id;
nextTick(() => {
const el = document.getElementById(id);
if (el && contentRef.value) {
el.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
}
const chapters = [
// ==================== 1. 快速入门 ====================
{
id: 'quickstart',
title: '快速入门',
icon: 'ant-design:rocket-outlined',
sections: [
{
heading: '创建计划',
text: `
<ol>
<li>左侧边栏 → <strong>"计划总览"</strong> → 点击<strong>所有计划 / 我创建的 / 我参与的</strong></li>
<li>右侧出现"计划列表",点击标题栏 <strong>+</strong> 按钮</li>
<li>填写<strong>计划名称</strong>,选择<strong>密级</strong></li>
<li>点击确定完成创建</li>
</ol>
<p>也可以在左侧边栏的"常用计划"旁点击 <strong>+</strong> 快速创建。</p>
`,
image: createPlanImg,
},
{
heading: '创建事项',
text: `
<p><strong>快速创建:</strong>进入计划 → 事项分组标题栏点击 <strong>+</strong> → 输入名称 → 回车</p>
`,
image: createTaskQuickImg,
},
{
text: `
<p><strong>详细创建:</strong>点击 + 后不输入名称直接确认打开弹窗,可设置名称、描述、负责人、参与人、关注人、优先级、起止时间。</p>
<p>需要权限:<strong>所有者 或可编辑</strong>。</p>
`,
image: createTaskDetailImg,
},
{
heading: '收藏与取消收藏',
text: `
<p><strong>收藏:</strong>进入"所有计划"视图 → 点击计划上的<strong>星标图标 ☆</strong> → 收藏后计划出现在左侧边栏。</p>
<p><strong>取消收藏:</strong>在左侧边栏找到该计划,点击星标(⭐ → ☆),或点击计划旁的 <strong>⋯</strong> → "移除"。</p>
`,
},
],
},
// ==================== 2. 权限说明 ====================
{
id: 'permissions',
title: '权限说明',
icon: 'ant-design:safety-certificate-outlined',
sections: [
{
heading: '三级权限对比',
text: `
<table class="faq-table">
<tr><th></th><th>所有者</th><th>可编辑</th><th>可阅读</th></tr>
<tr><td>创建事项</td><td class="td-yes">✓</td><td class="td-yes">✓</td><td class="td-no">✗</td></tr>
<tr><td>编辑事项</td><td class="td-yes">✓</td><td class="td-yes">✓</td><td class="td-no">✗</td></tr>
<tr><td>完成事项</td><td class="td-yes">✓</td><td class="td-yes">✓</td><td class="td-no">✗</td></tr>
<tr><td>删除事项</td><td class="td-yes">✓</td><td class="td-yes">✓</td><td class="td-no">✗</td></tr>
<tr><td>拖拽排序</td><td class="td-yes">✓</td><td class="td-yes">✓</td><td class="td-no">✗</td></tr>
<tr><td>管理协作者</td><td class="td-yes">✓</td><td class="td-no">✗</td><td class="td-no">✗</td></tr>
<tr><td>删除计划</td><td class="td-yes">✓</td><td class="td-no">✗</td><td class="td-no">✗</td></tr>
</table>
<ul>
<li><strong>所有者</strong>:计划创建者,拥有全部权限</li>
<li><strong>可编辑</strong>:可操作事项,但不能管理协作者和删除计划</li>
<li><strong>可阅读</strong>:只能查看,无法编辑</li>
</ul>
`,
},
{
heading: '密级说明',
text: `
<p>每个计划创建时需指定<strong>密级</strong>。用户只能看到密级 ≤ 自己密级的计划。</p>
<p><strong>密级创建后不可修改</strong>,如需调整请重新创建计划。</p>
`,
},
{
heading: '管理协作者',
text: `
<ol>
<li>进入计划 → 右上角点击<strong>"协作人"</strong>按钮</li>
<li>点击"添加协作人" → 搜索并选择用户 → 设置权限为"可编辑"或"可阅读"</li>
<li>确认添加</li>
</ol>
<p>只有计划的 <strong>所有者</strong> 才能管理协作者。如果看不到此按钮,说明你没有管理权限。</p>
`,
image: manageCollaboratorImg,
},
{
heading: '计划收藏权限说明',
text: `
<p>满足以下任一条件,即可在"所有计划"中看到并收藏该计划:</p>
<ul>
<li>你是该计划的<strong>所有者</strong></li>
<li>被设为该计划的<strong>协作者</strong></li>
<li>被设为计划中某个事项的<strong>负责人</strong>或<strong>参与者</strong></li>
</ul>
`,
},
],
},
// ==================== 3. 事项管理 ====================
{
id: 'task-mgmt',
title: '事项管理',
icon: 'ant-design:check-square-outlined',
sections: [
{
heading: '子事项',
text: `
<ul>
<li>点击事项名 → 详情抽屉 → 底部<strong>"添加子事项"</strong></li>
<li>最多支持 <strong>5 层</strong>嵌套</li>
<li>每个子事项可独立设置负责人、截止时间、优先级</li>
<li>列表中"子事项进度"列显示完成情况(如 2/5</li>
</ul>
`,
image: subtaskViewImg,
},
{
heading: '我的事项与关注事项',
text: `
<p>左侧边栏顶部有两个全局视图:</p>
<ul>
<li><strong>"我的事项"</strong>跨所有计划汇总你被设为"负责人"的事项,扁平列表,可直接编辑、完成、展开子事项</li>
<li><strong>"关注事项"</strong>汇总你关注的所有事项,适合跟踪他人负责但你需要了解进展的事项</li>
</ul>
`,
},
{
heading: '关注事项',
text: `
<p>点击事项名 → 详情抽屉 → 顶部点击<strong>眼睛图标</strong>即可关注。不需要是负责人或协作者,任何你可见的事项都能关注。关注后事项出现在"关注事项"视图中。</p>
`,
},
{
heading: '删除事项与计划',
text: `
<ul>
<li><strong>删除事项:</strong>详情抽屉 → 顶部删除图标(需 所有者 或可编辑)</li>
<li><strong>删除计划:</strong>标题栏 → ⋯ → 删除(需 所有者)</li>
</ul>
<p style="color:#f5222d">⚠ 删除后无法恢复,请谨慎操作。</p>
`,
},
],
},
// ==================== 4. 常见问题 ====================
{
id: 'faq',
title: '常见问题',
icon: 'ant-design:question-circle-outlined',
sections: [
{
heading: '计划的密级创建后能改吗?',
text: `
<p><strong>不能直接修改。</strong>密级创建后不可更改。如需调整,只能删除原计划后重新创建并选择新的密级。</p>
`,
},
{
heading: '事项的截止时间有什么用?',
text: `
<p>设置截止时间后,到期未完成的事项日期会<strong>自动标红</strong>提醒。在"我的事项"视图中可快速识别过期事项。</p>
`,
},
],
},
];
</script>
<style lang="less" scoped>
.help-doc {
display: flex;
height: 80vh;
max-height: 750px;
}
.help-doc-nav {
width: 180px;
min-width: 180px;
padding: 12px 0;
border-right: 1px solid #f0f0f0;
background: #fafafa;
overflow-y: auto;
flex-shrink: 0;
}
.nav-item {
display: flex;
align-items: center;
gap: 8px;
padding: 10px 16px;
font-size: 13px;
color: #595959;
cursor: pointer;
border-left: 3px solid transparent;
transition: all 0.15s;
&:hover {
color: #1a1a1a;
background: #f0f0f0;
}
&.active {
color: #1677ff;
background: #e6f4ff;
border-left-color: #1677ff;
font-weight: 500;
}
}
.nav-icon {
font-size: 14px;
flex-shrink: 0;
}
.help-doc-content {
flex: 1;
overflow-y: auto;
padding: 24px 28px;
min-width: 0;
}
.chapter {
margin-bottom: 32px;
&:last-child {
margin-bottom: 0;
}
}
.chapter-title {
margin: 0 0 16px;
font-size: 17px;
font-weight: 600;
color: #1a1a1a;
display: flex;
align-items: center;
gap: 8px;
padding-bottom: 8px;
border-bottom: 1px solid #f0f0f0;
}
.chapter-icon {
font-size: 18px;
color: #1677ff;
}
.section {
margin-bottom: 20px;
}
.section-heading {
margin: 0 0 8px;
font-size: 14px;
font-weight: 600;
color: #1f2329;
}
.section-text {
font-size: 13px;
line-height: 1.8;
color: #555;
:deep(p) {
margin: 0 0 6px;
}
:deep(ul),
:deep(ol) {
margin: 0 0 6px;
padding-left: 18px;
}
:deep(li) {
margin-bottom: 3px;
}
:deep(strong) {
color: #1a1a1a;
}
:deep(.faq-table) {
width: 100%;
border-collapse: collapse;
margin: 8px 0 12px;
font-size: 13px;
th,
td {
border: 1px solid #d9d9d9;
padding: 8px 12px;
text-align: center;
}
th {
background: #f5f5f5;
font-weight: 600;
}
td:first-child {
text-align: left;
font-weight: 500;
}
.td-yes {
color: #52c41a;
font-weight: 600;
}
.td-no {
color: #d9d9d9;
}
}
}
.doc-image {
margin-top: 10px;
border-radius: 6px;
overflow: hidden;
border: 1px solid #e8e8e8;
}
.doc-image-img {
width: 100%;
display: block;
}
</style>