This commit is contained in:
itcsx committed 2026-09-19 10:24:21 +08:00
1 parent 9344b56334
commit 441d1e821e
37 files changed
+3706 -23

No files matched your search

@@ -0,0 +1,432 @@
<template>
<dragModal wrap-class-name="help-tl-modal" :width="760" v-model:open="visible" @cancel="onCancel">
<template #title>
<div class="htl-title">
<span class="htl-title-icon" :style="{ background: themeSoft, color: themeColor }">
<cust-icon-font :type="themeIcon" :size="18" />
</span>
<span class="htl-title-text">{{ props.title || "使用帮助" }}</span>
</div>
</template>
<div class="htl-body">
<a-spin :spinning="showLoading">
<!-- 功能简介 -->
<p class="htl-intro">{{ doc.intro }}</p>
<!-- 未编写专属文档时的提示,避免用户以为看到了正确流程 -->
<div v-if="!isSpecific" class="htl-notice">
<span class="htl-notice-tag">通用指引</span>
<span>该功能暂无专属帮助文档,下面是各功能页面的通用操作说明。</span>
</div>
<!-- 操作流程:按先后顺序 -->
<div class="htl-section-title">操作流程</div>
<a-timeline class="htl-steps">
<a-timeline-item v-for="(s, i) in doc.steps" :key="'step-' + i">
<template #dot>
<span class="htl-dot" :style="{ background: themeColor }">
<cust-icon-font v-if="isFontIcon(s.icon)" :type="s.icon" :size="13" />
<component v-else-if="s.icon" :is="antdIcon(s.icon)" />
<template v-else>{{ i + 1 }}</template>
</span>
</template>
<div class="htl-step">
<div class="htl-step-head">
<span class="htl-step-no">{{ i + 1 }}</span>
<span class="htl-step-title">{{ s.title }}</span>
</div>
<div class="htl-step-desc">{{ s.desc }}</div>
<div v-if="s.tips" class="htl-step-tips">
<span class="htl-step-tips-label">提示</span>
<span>{{ s.tips }}</span>
</div>
</div>
</a-timeline-item>
</a-timeline>
<!-- 功能点 / 图标说明 -->
<div class="htl-section-title">功能点与图标说明</div>
<div class="htl-features">
<div v-for="(f, i) in doc.features" :key="'feat-' + i" class="htl-feature">
<span class="htl-feature-icon" :style="{ background: themeSoft, color: themeColor }">
<cust-icon-font v-if="isFontIcon(f.icon)" :type="f.icon" :size="16" />
<!-- 其余一律按 Ant Design 图标组件名解析,保证与页面上看到的完全一致 -->
<component v-else :is="antdIcon(f.icon)" :style="{ color: f.color }" />
</span>
<div class="htl-feature-text">
<div class="htl-feature-name">{{ f.name }}</div>
<div class="htl-feature-desc">{{ f.desc }}</div>
</div>
</div>
</div>
</a-spin>
</div>
<!-- 只需要阅读,不需要确认按钮:传空 footer 占位隐藏默认按钮区 -->
<template #footer>
<span />
</template>
</dragModal>
</template>
<script lang="ts" setup>
import { computed, onMounted, ref } from "vue";
import * as antdIcons from "@ant-design/icons-vue";
import { QuestionCircleOutlined } from "@ant-design/icons-vue";
import dragModal from "@/components/basic/DragModal.vue";
import { assembleOrDefault } from "@/data/help/helpDocAssembler";
import securityHelpFunctionService from "@/service/security/securityHelpFunctionService";
import { buildSeedHelpDocData } from "@/data/help/helpDocSeed";
import { SecurityHelpFunctionData } from "@/data/auto/securityHelpFunctionData";
const props = defineProps<{
open: boolean;
/** 目标功能的英文名,决定加载哪份帮助文档 */
functionName?: string;
/** 弹窗标题,一般为功能的本地化名称 */
title?: string;
/** 主题色,沿用所属分组的颜色保持视觉一致 */
color?: string;
soft?: string;
icon?: string;
}>();
const emit = defineEmits<{
(e: "update:open", value: boolean): void;
(e: "cancel"): void;
}>();
/** 双向绑定弹窗显示状态 */
const visible = computed({
get: () => props.open,
set: (v: boolean) => emit("update:open", v),
});
/**
* 接口还没就绪时就先用地上的种子数据(内容和建表数据一致),
* 这样弹窗永远有东西可看,不会白屏。
*/
const seedData: SecurityHelpFunctionData = buildSeedHelpDocData();
/** 当前实际使用的数据:默认种子数据,接口取到后整体替换 */
const rows = ref<SecurityHelpFunctionData>(seedData);
const loading = ref(false);
/** 从表里取数据:接口优先,取不到就继续用种子数据 */
const loadRows = async () => {
try {
loading.value = true;
const data = await securityHelpFunctionService.FindAll();
// 接口返回空说明表里还没灌数据,继续用种子数据
if (data && data.SecurityHelpFunctions && data.SecurityHelpFunctions.length > 0) {
rows.value = data;
}
} catch {
rows.value = seedData;
} finally {
loading.value = false;
}
};
onMounted(loadRows);
/** 把表行组合成页面要显示的文档;表里没有这个功能时退回通用兜底 */
const doc = computed(() => assembleOrDefault(rows.value, props.functionName));
/**
* false 表示表里没有这个功能的专属文档、拿到的是通用兜底,
* 这种情况要在弹窗顶部提示,免得用户以为看到的就是本功能的流程。
*/
const isSpecific = computed(
() =>
!!props.functionName &&
rows.value.SecurityHelpFunctions.some((f) => f.FunctionName === props.functionName)
);
/** 只有真的还没有内容时才显示加载态,避免种子数据明明有内容还挡一层遮罩 */
const showLoading = computed(() => loading.value && doc.value.steps.length === 0);
const themeColor = computed(() => props.color || "#1677ff");
const themeSoft = computed(() => props.soft || "#e6f4ff");
const themeIcon = computed(() => props.icon || "icon-help");
/**
* 图标分两类,判别规则很直白:
* 以 "icon-" 开头 → 项目自定义的 iconfont(如云盘的「预览」icon-qingbaojiankong)
* 其余 → Ant Design 官方图标组件名(如 DeleteOutlined)
* 这样帮助里出现的图标和用户在页面上真实看到的那个是同一个。
*/
const isFontIcon = (name?: string) => !!name && name.startsWith("icon-");
/**
* 按名字取出 antd 图标组件。
* 名字写错或组件库里没有时,退化成问号图标而不是渲染空白,避免出现一个空方块。
*/
const antdIcon = (name?: string) =>
(name && (antdIcons as Record<string, unknown>)[name]) || QuestionCircleOutlined;
const onCancel = () => {
emit("cancel");
};
</script>
<style lang="less" scoped>
.htl-title {
display: flex;
align-items: center;
gap: 8px;
}
.htl-title-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 26px;
height: 26px;
border-radius: 50%;
}
.htl-title-text {
font-size: 15px;
font-weight: 600;
}
.htl-body {
padding-right: 4px;
}
.htl-intro {
margin: 0 0 4px;
color: #303133;
font-size: 13px;
line-height: 1.8;
}
/* 兜底提示:温和提醒,不与主内容抢视线 */
.htl-notice {
display: flex;
align-items: flex-start;
gap: 8px;
margin: 10px 0 14px;
padding: 8px 12px;
border: 1px solid #ffe7ba;
border-radius: 8px;
background: #fff7e6;
color: #ad6800;
font-size: 12px;
line-height: 1.7;
}
.htl-notice-tag {
flex: none;
padding: 1px 6px;
border-radius: 4px;
background: #faad14;
color: #fff;
font-size: 11px;
line-height: 17px;
white-space: nowrap;
}
.htl-section-title {
position: relative;
margin: 14px 0 12px;
padding-left: 10px;
font-size: 14px;
font-weight: 600;
color: #1f2329;
&::before {
content: "";
position: absolute;
top: 50%;
left: 0;
width: 3px;
height: 13px;
border-radius: 2px;
background: #1677ff;
transform: translateY(-50%);
}
}
/* ==================== 时间轴步骤 ==================== */
.htl-steps {
padding-top: 2px;
margin-left:4px;
}
/* antd 默认把内容顶得很开,这里收紧,让「操作流程」更像一套连贯的步骤 */
.htl-steps :deep(.ant-timeline-item-content) {
margin-left: 0;
padding-left: 20px;
top: -4px;
}
.htl-steps :deep(.ant-timeline-item-tail) {
left: 10px;
}
.htl-dot {
display: inline-flex;
align-items: center;
justify-content: center;
width: 21px;
height: 21px;
border: 2px solid #fff;
border-radius: 50%;
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.06);
color: #fff;
font-size: 11px;
font-weight: 600;
line-height: 1;
}
.htl-step {
padding-bottom: 2px;
}
.htl-step-head {
display: flex;
align-items: center;
gap: 7px;
margin-bottom: 3px;
}
.htl-step-no {
flex: none;
min-width: 17px;
height: 17px;
padding: 0 4px;
border-radius: 9px;
background: #f0f2f5;
color: #8a919f;
font-size: 11px;
font-weight: 600;
line-height: 17px;
text-align: center;
}
.htl-step-title {
font-size: 14px;
font-weight: 600;
color: #1f2329;
line-height: 1.5;
}
.htl-step-desc {
color: #5c6470;
font-size: 13px;
line-height: 1.8;
}
.htl-step-tips {
display: flex;
align-items: flex-start;
gap: 6px;
margin-top: 6px;
padding: 7px 10px;
border-left: 3px solid #faad14;
border-radius: 0 6px 6px 0;
background: #fffbe6;
color: #8a6116;
font-size: 12px;
line-height: 1.7;
}
.htl-step-tips-label {
flex: none;
font-weight: 600;
color: #ad6800;
white-space: nowrap;
}
/* ==================== 功能点网格 ==================== */
.htl-features {
display: grid;
grid-template-columns: 1fr;
gap: 8px;
}
/* 宽屏时双列,减少纵向滚动 */
@media (min-width: 900px) {
.htl-features {
grid-template-columns: 1fr 1fr;
}
}
.htl-feature {
display: flex;
align-items: flex-start;
gap: 9px;
padding: 9px 11px;
border: 1px solid #f0f1f3;
border-radius: 9px;
background: #fafbfc;
transition: border-color 0.16s ease, background 0.16s ease;
&:hover {
border-color: #d6e4ff;
background: #fff;
}
}
.htl-feature-icon {
flex: none;
display: inline-flex;
align-items: center;
justify-content: center;
width: 26px;
height: 26px;
border-radius: 7px;
}
.htl-feature-text {
min-width: 0;
}
.htl-feature-name {
font-size: 13px;
font-weight: 600;
color: #1f2329;
line-height: 1.5;
}
.htl-feature-desc {
color: #6b7280;
font-size: 12px;
line-height: 1.7;
}
</style>
<!-- 非 scoped:这部分要作用于 DragModal teleport 出去的 antd Modal 自身结构,scoped 打不到。
全部写在 .help-tl-modal 这个 wrapClass 之下,只影响本组件,不会波及其它弹窗。 -->
<style lang="less">
.help-tl-modal {
/* 隐藏空的底部按钮区(发了空 footer 插槽占位,只是为了让 antd 不渲染默认按钮) */
.ant-modal-footer {
display: none;
}
/* 帮助文档通常比较长:限制高度并让内容区自己滚动 */
.ant-modal-body {
max-height: 68vh;
overflow-y: auto;
}
/* 窄按标题文字,留出右边三个操作图标的位置 */
.ant-modal-title {
padding-right: 48px;
}
@media (max-width: 640px) {
.ant-modal {
max-width: 100vw;
}
.ant-modal-body {
max-height: 74vh;
}
}
}
</style>
+11 -1
View File
@@ -26,7 +26,7 @@
type="text"
class="nav-btn"
:loading="loading"
@click="onBreadcrumbClick(breadcrumbItems[0], 0)"
@click="onRefresh"
>
<ReloadOutlined />
</a-button>
@@ -117,6 +117,16 @@ const onSearch = () => {
const onBreadcrumbClick = (item: BreadcrumbItem, index: number) => {
emit("breadcrumb-click", item, index);
};
/**
* 刷新:重新加载「当前所在目录」,也就是路径的最后一个节点。
* 不能取第一个节点,否则会把路径截回到根目录,变成跳转而不是刷新。
*/
const onRefresh = () => {
const lastIndex = breadcrumbItems.value.length - 1;
if (lastIndex < 0) return;
onBreadcrumbClick(breadcrumbItems.value[lastIndex], lastIndex);
};
</script>
<style lang="less">
+11 -1
View File
@@ -32,7 +32,7 @@
type="text"
class="nav-btn"
:loading="loading"
@click="onBreadcrumbClick(breadcrumbItems[0], 0)"
@click="onRefresh"
>
<ReloadOutlined />
</a-button> </a-tooltip
@@ -248,6 +248,16 @@ const onSearch = () => {
const onBreadcrumbClick = (item: BreadcrumbItem, index: number) => {
emit("breadcrumb-click", item, index);
};
/**
* 刷新:重新加载「当前所在目录」,也就是路径的最后一个节点。
* 不能取第一个节点,否则会把路径截回到根目录,变成跳转而不是刷新。
*/
const onRefresh = () => {
const lastIndex = breadcrumbItems.value.length - 1;
if (lastIndex < 0) return;
onBreadcrumbClick(breadcrumbItems.value[lastIndex], lastIndex);
};
</script>
<style lang="less">
@@ -17,8 +17,9 @@
<span class="row-title">{{ it.FunctionLocalName }}</span>
<span v-if="subtitleOf(it)" class="row-sub">{{ subtitleOf(it) }}</span>
</span>
<span class="row-glyph" :style="{ background: soft, color }">
<cust-icon-font :type="icon" :size="18" />
<span class="row-glyph" :style="{ background: soft, color }" title="使用帮助"
@click.stop="onHelp(it)">
<cust-icon-font type="icon-help" :size="18" />
</span>
</a>
</div>
@@ -50,6 +51,8 @@ const props = defineProps<{
const emit = defineEmits<{
(e: "navigate", route: string): void;
/** 点击行尾圆形图标:请求打开该功能的新手帮助 */
(e: "help", item: GroupCardItem): void;
}>();
const coverStyle = computed(() =>
@@ -59,11 +62,14 @@ const coverStyle = computed(() =>
);
/** 副标题优先取自定义 subtitle,其次回落英文名;都为空则不渲染该行 */
const subtitleOf = (it: GroupCardItem) => (it.subtitle || it.FunctionEngName || "").trim();
const subtitleOf = (it: GroupCardItem) => (it.subtitle || it.Remark || "").trim();
const onClick = (route?: string) => {
if (route) emit("navigate", route);
};
/** 点击行尾圆形图标:请求帮助(.stop 已阻止它冒泡到整行的路由跳转) */
const onHelp = (it: GroupCardItem) => emit("help", it);
</script>
<style lang="less" scoped>
@@ -196,6 +202,20 @@ const onClick = (route?: string) => {
width: 34px;
height: 34px;
border-radius: 50%;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
transition:
transform 0.16s ease,
box-shadow 0.16s ease;
/* 悬停 / 按下给出反馈,提示这里是打开「使用帮助」的入口 */
&:hover {
box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.06);
}
&:active {
transform: scale(0.9);
}
}
@media (min-width: 1200px) {
@@ -13,6 +13,7 @@ export class SecurityFunctionEntity
public ApiRoute: string = "";
public Icon: string = "";
public PageName: string = "";
public Remark: string = "";
static readonly CREATED_DATETIME : string ='CreatedDatetime';
static readonly CREATED_BY : string ='CreatedBy';
@@ -26,8 +27,9 @@ export class SecurityFunctionEntity
static readonly API_ROUTE : string ='ApiRoute';
static readonly ICON : string ='Icon';
static readonly PAGE_NAME : string ='PageName';
static readonly REMARK : string ='Remark';
static readonly DB_NAME_SECURITY_FUNCTION : string ='security_function';
static readonly DB_NAME_FIELDS : string ='created_datetime,created_by,updated_datetime,updated_by,function_name,function_local_name,function_eng_name,function_indc,page_url,api_route,icon,page_name';
static readonly DB_NAME_FIELDS : string ='created_datetime,created_by,updated_datetime,updated_by,function_name,function_local_name,function_eng_name,function_indc,page_url,api_route,icon,page_name,remark';
static readonly DB_CREATED_DATETIME : string ='created_datetime';
static readonly DB_CREATED_BY : string ='created_by';
static readonly DB_UPDATED_DATETIME : string ='updated_datetime';
@@ -40,4 +42,5 @@ export class SecurityFunctionEntity
static readonly DB_API_ROUTE : string ='api_route';
static readonly DB_ICON : string ='icon';
static readonly DB_PAGE_NAME : string ='page_name';
static readonly DB_REMARK : string ='remark';
}
@@ -12,5 +12,6 @@ export class SecurityPermissionPolicy
static readonly Locale : string ='Locale';
static readonly SecurityUserPreference : string ='SecurityUserPreference';
static readonly SecurityLock : string ='SecurityLock';
static readonly SecurityHelpFunction : string ='SecurityHelpFunction';
static readonly CanSeeAllUser : string ='CanSeeAllUser';
}
+98
View File
@@ -0,0 +1,98 @@
import { SecurityHelpFunctionData } from "@/data/auto/securityHelpFunctionData";
import type { SecurityHelpStepEntity } from "@/data/auto/securityHelpStepEntity";
import type { SecurityHelpFeatureEntity } from "@/data/auto/securityHelpFeatureEntity";
import type { HelpDoc, HelpFeature, HelpStep } from "./helpDocs";
import { FALLBACK_FUNCTION } from "./helpDocSeed";
/*
* 把接口返回的 SecurityHelpFunctionData「组合」成页面要显示的 HelpDoc。
*
* 组合规则(全部由表里的序号决定,改顺序不用改代码):
* 步骤 → SecurityHelpSteps 按 step_no
* 功能点 → SecurityHelpFunctionFeatures 按 sort_no 取组,
* 再按 SecurityHelpFeatures.sort_no 取组内各项
*/
/** 按序号升序,序号一样时保持原顺序 */
const bySortNo = <T extends { SortNo: number }>(list: T[]): T[] =>
[...list].sort((a, b) => a.SortNo - b.SortNo);
const byStepNo = (list: SecurityHelpStepEntity[]): SecurityHelpStepEntity[] =>
[...list].sort((a, b) => a.StepNo - b.StepNo);
const byFeatureSort = (list: SecurityHelpFeatureEntity[]): SecurityHelpFeatureEntity[] =>
[...list].sort((a, b) => a.SortNo - b.SortNo);
/** 有箭头的结构(/接口返回缺失时兜底为空数组) */
const listOf = <T>(v?: T[]): T[] => (Array.isArray(v) ? v : []);
/** 从数据表里组装出某个功能的帮助文档;表里没有则返回 null */
export function assembleHelpDoc(data: SecurityHelpFunctionData, functionName: string): HelpDoc | null {
if (!data || !functionName) return null;
const fn = listOf(data.SecurityHelpFunctions).find((f) => f.FunctionName === functionName);
if (!fn) return null;
const steps: HelpStep[] = byStepNo(
listOf(data.SecurityHelpSteps).filter((s) => s.HelpFunctionId === fn.HelpFunctionId)
).map((s) => ({
title: s.Title,
desc: s.Description,
tips: s.Tips || undefined,
icon: s.Icon || undefined,
}));
// 组编码 → 组主键,用于把关系表接到明细表
const groupIdByCode = new Map(
listOf(data.SecurityHelpFeatureGroups).map((g) => [g.GroupCode, g.HelpFeatureGroupId])
);
const features: HelpFeature[] = bySortNo(
listOf(data.SecurityHelpFunctionFeatures).filter((ff) => ff.FunctionName === functionName)
).flatMap((ff) => {
const groupId = groupIdByCode.get(ff.GroupCode);
if (!groupId) return [];
return byFeatureSort(
listOf(data.SecurityHelpFeatures).filter((f) => f.HelpFeatureGroupId === groupId)
).map((f) => ({
icon: f.Icon || undefined,
color: f.Color || undefined,
name: f.Name,
desc: f.Description,
}));
});
return { intro: fn.Intro, steps, features };
}
/** 把整批数据组装成「功能名 → 帮助文档」的字典 */
export function assembleAllHelpDocs(data: SecurityHelpFunctionData): Record<string, HelpDoc> {
const result: Record<string, HelpDoc> = {};
listOf(data?.SecurityHelpFunctions).forEach((fn) => {
const doc = assembleHelpDoc(data, fn.FunctionName);
if (doc) result[fn.FunctionName] = doc;
});
return result;
}
/**
* 取某个功能的文档:表里查不到就退回通用兜底,
* 保证调用方永远拿得到一份能渲染的内容。
*/
export function assembleOrDefault(
data: SecurityHelpFunctionData,
functionName?: string
): HelpDoc {
if (data && functionName) {
const doc = assembleHelpDoc(data, functionName);
if (doc) return doc;
}
return (
(data && assembleHelpDoc(data, FALLBACK_FUNCTION)) || {
intro: "",
steps: [],
features: [],
}
);
}
+107
View File
@@ -0,0 +1,107 @@
-- ============================================================
-- MySQL 8 建表脚本:帮助文档(新手引导)
--
-- 目的:把原先写死在前端 helpDocs.ts 里的内容搬到数据库,
-- 前端只负责「从表里取出来、按关系组合」后展示。
--
-- 设计要点:
-- 1) 内容与关系分离:文案存实体表,谁用哪些存关系表
-- 2) 功能点按「组」复用:工具栏、文件图标、通用增删改查这些
-- 在多个功能里长一个样,只存一份,由 help_function_feature 引用
-- 3) 所有展示顺序都由 sort_no / step_no 决定,改顺序不用改代码
-- 4) 表与表之间不建外键:引用完整性由应用层保证。这样灌数据不必讲究
-- 先后顺序,单表导入导出、按功能整块删除都不会被约束卡住
--
-- 约定:主键统一用 VARCHAR(36) 存 UUID,与项目现有表(如 family_tree)
-- 的主键做法保持一致。
-- ============================================================
-- 1. 功能帮助主表:一个功能一份说明
CREATE TABLE security_help_function (
help_function_id VARCHAR(36) NOT NULL COMMENT '主键 UUID',
function_name VARCHAR(200) NOT NULL COMMENT '对应 security_function.function_name',
intro VARCHAR(1000) NULL COMMENT '一句话说明这个功能是什么',
enabled_indc VARCHAR(1) NOT NULL DEFAULT 'Y' COMMENT '是否启用 Y/N',
created_datetime DATETIME NOT NULL COMMENT '创建时间',
created_by VARCHAR(100) NULL COMMENT '创建人',
updated_datetime DATETIME NOT NULL COMMENT '更新时间',
updated_by VARCHAR(100) NULL COMMENT '更新人',
PRIMARY KEY (help_function_id),
UNIQUE KEY uq_security_help_function (function_name),
KEY ix_security_help_function_name (function_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='功能帮助主表';
-- 2. 操作步骤表:时间轴上的每一步
CREATE TABLE security_help_step (
help_step_id VARCHAR(36) NOT NULL COMMENT '主键 UUID',
help_function_id VARCHAR(36) NOT NULL COMMENT '所属功能 security_help_function.help_function_id',
step_no INT NOT NULL COMMENT '第几步,决定时间轴顺序',
title VARCHAR(200) NOT NULL COMMENT '步骤标题',
description TEXT NULL COMMENT '这一步具体怎么做',
tips TEXT NULL COMMENT '补充说明,可为空',
icon VARCHAR(100) NULL COMMENT 'antd 组件名,或 icon- 开头的 iconfont 名',
created_datetime DATETIME NOT NULL COMMENT '创建时间',
created_by VARCHAR(100) NULL COMMENT '创建人',
updated_datetime DATETIME NOT NULL COMMENT '更新时间',
updated_by VARCHAR(100) NULL COMMENT '更新人',
PRIMARY KEY (help_step_id),
KEY ix_security_help_step_func (help_function_id, step_no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='帮助操作步骤表';
-- 3. 功能点分组表:可复用的一组功能点 / 图标说明
CREATE TABLE security_help_feature_group (
help_feature_group_id VARCHAR(36) NOT NULL COMMENT '主键 UUID',
group_code VARCHAR(100) NOT NULL COMMENT '组编码,如 TOOLBAR / FILE_ICON / CRUD_HEAD',
group_name VARCHAR(200) NULL COMMENT '组名称,便于后台维护时识别',
created_datetime DATETIME NOT NULL COMMENT '创建时间',
created_by VARCHAR(100) NULL COMMENT '创建人',
updated_datetime DATETIME NOT NULL COMMENT '更新时间',
updated_by VARCHAR(100) NULL COMMENT '更新人',
PRIMARY KEY (help_feature_group_id),
UNIQUE KEY uq_security_help_feature_group (group_code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='功能点分组表';
-- 4. 功能点明细表:组里的每一条,也就是页面上某个按钮 / 图标的说明
CREATE TABLE security_help_feature (
help_feature_id VARCHAR(36) NOT NULL COMMENT '主键 UUID',
help_feature_group_id VARCHAR(36) NOT NULL COMMENT '所属组 security_help_feature_group.help_feature_group_id',
icon VARCHAR(100) NULL COMMENT 'antd 组件名,或 icon- 开头的 iconfont 名',
color VARCHAR(50) NULL COMMENT '页面上的真实颜色,如 #faad14 / red / green',
name VARCHAR(200) NOT NULL COMMENT '功能点名称,一般就是按钮上的字',
description TEXT NULL COMMENT '作用说明',
sort_no INT NOT NULL COMMENT '组内显示顺序',
created_datetime DATETIME NOT NULL COMMENT '创建时间',
created_by VARCHAR(100) NULL COMMENT '创建人',
updated_datetime DATETIME NOT NULL COMMENT '更新时间',
updated_by VARCHAR(100) NULL COMMENT '更新人',
PRIMARY KEY (help_feature_id),
KEY ix_security_help_feature_group (help_feature_group_id, sort_no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='功能点明细表';
-- 5. 功能与组的组合关系表:这就是「组合」的地方
-- 一个功能引用若干个组,按 sort_no 依次拼起来显示。
-- 公共组(工具栏、文件图标、通用按钮)可以被多个功能引用,只维护一份。
CREATE TABLE security_help_function_feature (
help_function_feature_id VARCHAR(36) NOT NULL COMMENT '主键 UUID',
function_name VARCHAR(200) NOT NULL COMMENT '功能英文名',
group_code VARCHAR(100) NOT NULL COMMENT '引用的组 security_help_feature_group.group_code',
sort_no INT NOT NULL COMMENT '组在这个功能里的显示顺序',
created_datetime DATETIME NOT NULL COMMENT '创建时间',
created_by VARCHAR(100) NULL COMMENT '创建人',
updated_datetime DATETIME NOT NULL COMMENT '更新时间',
updated_by VARCHAR(100) NULL COMMENT '更新人',
PRIMARY KEY (help_function_feature_id),
UNIQUE KEY uq_security_help_function_feature (function_name, group_code),
KEY ix_security_help_func_feature (function_name, sort_no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='功能与功能点组的组合关系表';
-- ============================================================
-- 初始化数据
-- 表建好后,把前端 src/data/help/helpDocSeed.ts 导出的行灌进来即可:
-- helpFunctionRows -> security_help_function
-- helpStepRows -> security_help_step
-- helpFeatureGroupRows -> security_help_feature_group
-- helpFeatureRows -> security_help_feature
-- helpFunctionFeatureRows -> security_help_function_feature
-- 接口还没就绪时,前端会直接用这批种子行显示,页面不会空白。
-- ============================================================
+346
View File
@@ -0,0 +1,346 @@
-- ============================================================
-- 帮助文档初始化数据(由前端 src/data/help/helpDocSeed.ts 导出)
-- 执行顺序无所谓:表与表之间没有外键
-- 重复执行会主键冲突,如需重跑请先清空这 5 张表
-- ============================================================
-- 1. 功能主表
INSERT INTO security_help_function (help_function_id, function_name, intro, enabled_indc, created_datetime, created_by, updated_datetime, updated_by) VALUES
('HF-DmsFileEnquiry', 'DmsFileEnquiry', '「我的云盘」是存放和管理文件的地方:上传自己的文件、建文件夹归类,也能下载、移动。可共享给家人或者发布到相相册展览、音乐厅、影视厅,这些都可以独立授权。', 'Y', NOW(), '', NOW(), ''),
('HF-DmsFileDeleteEnquiry', 'DmsFileDeleteEnquiry', '「回收站」存放从云盘删除的文件,给误删留一次还原的机会。这里的删除是真的没了,没有第二次机会。', 'Y', NOW(), '', NOW(), ''),
('HF-FamilyGroupShare', 'FamilyGroupShare', '「共享中心」家族成员能看到授权的文件', 'Y', NOW(), '', NOW(), ''),
('HF-FamilyShareOperation', 'FamilyShareOperation', '「家庭共享」把云盘中的某个目录共享给指定的家庭群组,让家人能看到这份内容。', 'Y', NOW(), '', NOW(), ''),
('HF-FamilyGroupOperation', 'FamilyGroupOperation', '「群组」把家庭成员组织成一个个小组,共享时按群组授权,是家庭协作的基础设置。', 'Y', NOW(), '', NOW(), ''),
('HF-FamilyGroupEnquiry', 'FamilyGroupEnquiry', '「群组查询」集中查看所有家庭群组的概况,并从这里进入查看、修改与删除。', 'Y', NOW(), '', NOW(), ''),
('HF-Preview', 'Preview', '「相册浏览」查看已发布的照片:进入后是整页的大图,用左右两个圆形箭头依次翻看。', 'Y', NOW(), '', NOW(), ''),
('HF-PublishPhotoOperation', 'PublishPhotoOperation', '「相册发布」把本地照片整理成一个相册并发布;发布后照片才会出现在相册浏览里。', 'Y', NOW(), '', NOW(), ''),
('HF-PublishPhotoEnquiry', 'PublishPhotoEnquiry', '「照片查询」集中查看自己发布过的相册与照片,便于批量核对和整理。', 'Y', NOW(), '', NOW(), ''),
('HF-PreviewAudio', 'PreviewAudio', '「音乐」用来收听已发布的音频:进入后是一台黑胶唱片机,唱片转起来就在放歌了。', 'Y', NOW(), '', NOW(), ''),
('HF-PublishAudioOperation', 'PublishAudioOperation', '「音频发布」把本地音频整理成专辑并发布;发布后才能在这里收听。', 'Y', NOW(), '', NOW(), ''),
('HF-PublishAudioEnquiry', 'PublishAudioEnquiry', '「音频查询」列出自己发布过的全部专辑与音频,用于集中核对和管理。', 'Y', NOW(), '', NOW(), ''),
('HF-PreviewVideo', 'PreviewVideo', '「视频」用来观看已发布的视频:进入后直接播放,屏幕周围一圈按钮控制播放的各种设置。', 'Y', NOW(), '', NOW(), ''),
('HF-PublishVideoOperation', 'PublishVideoOperation', '「视频发布」把本地视频整理成专辑并发布;发布后才能在这里观看。', 'Y', NOW(), '', NOW(), ''),
('HF-PublishVideoEnquiry', 'PublishVideoEnquiry', '「视频查询」列出自己发布过的全部专辑与视频,用于集中核对和管理。', 'Y', NOW(), '', NOW(), ''),
('HF-FamilyPersonOperation', 'FamilyPersonOperation', '「家庭成员」录入与维护族谱里的每一位成员,是绘制族谱的基础数据。进入就是一张可直接填写的表。', 'Y', NOW(), '', NOW(), ''),
('HF-FamilyPersonEnquiry', 'FamilyPersonEnquiry', '「成员查询」集中查看全部家庭成员,先从列表挑人,再做查看、修改或删除。', 'Y', NOW(), '', NOW(), ''),
('HF-FamilyTreeOperation', 'FamilyTreeOperation', '「族谱」把已录入的家庭成员按亲属关系连成一张树状图,可以直观地看到整个家族的脉络。', 'Y', NOW(), '', NOW(), ''),
('HF-FamilyTreeEnquiry', 'FamilyTreeEnquiry', '「族谱查询」列出全部已创建的族谱,选一张再做查看、修改或删除。', 'Y', NOW(), '', NOW(), ''),
('HF-FALLBACK', 'FALLBACK', '这里用时间轴的方式介绍该功能的操作流程,下方列出页面中各个按钮和图标的作用。', 'Y', NOW(), '', NOW(), '');
-- 2. 功能点分组表(公共组 + 各功能专属组)
INSERT INTO security_help_feature_group (help_feature_group_id, group_code, group_name, created_datetime, created_by, updated_datetime, updated_by) VALUES
('HG-CRUD_HEAD', 'CRUD_HEAD', '顶部三件套(查询 / 重置 / 新增)', NOW(), '', NOW(), ''),
('HG-CRUD_FOOT', 'CRUD_FOOT', '底部操作区(修改 / 保存 / 取消 / 删除)', NOW(), '', NOW(), ''),
('HG-ROW_ACTION', 'ROW_ACTION', '明细行操作(上移 / 下移 / 删除本行)', NOW(), '', NOW(), ''),
('HG-PUBLIC_GROUP', 'PUBLIC_GROUP', '公开群组授权', NOW(), '', NOW(), ''),
('HG-TOOLBAR', 'TOOLBAR', '云盘路径栏 Toolbar.vue', NOW(), '', NOW(), ''),
('HG-FILE_ICON', 'FILE_ICON', '文件列表图标 MyComputer.vue', NOW(), '', NOW(), ''),
('HG-PHOTO_HERO', 'PHOTO_HERO', '相册发布页顶部大图', NOW(), '', NOW(), ''),
('HG-PHOTO_EXTRA', 'PHOTO_EXTRA', '相册发布页「预览相册」', NOW(), '', NOW(), ''),
('HG-AUDIO_HERO', 'AUDIO_HERO', '音频发布页顶部耳机', NOW(), '', NOW(), ''),
('HG-AUDIO_EXTRA', 'AUDIO_EXTRA', '音频发布页「音乐厅」', NOW(), '', NOW(), ''),
('HG-VIDEO_HERO', 'VIDEO_HERO', '视频发布页顶部摄像机', NOW(), '', NOW(), ''),
('HG-DmsFileEnquiry_OWN', 'DmsFileEnquiry_OWN', 'DmsFileEnquiry 专属功能点', NOW(), '', NOW(), ''),
('HG-DmsFileDeleteEnquiry_OWN', 'DmsFileDeleteEnquiry_OWN', 'DmsFileDeleteEnquiry 专属功能点', NOW(), '', NOW(), ''),
('HG-FamilyGroupShare_OWN', 'FamilyGroupShare_OWN', 'FamilyGroupShare 专属功能点', NOW(), '', NOW(), ''),
('HG-FamilyShareOperation_OWN', 'FamilyShareOperation_OWN', 'FamilyShareOperation 专属功能点', NOW(), '', NOW(), ''),
('HG-FamilyGroupOperation_OWN', 'FamilyGroupOperation_OWN', 'FamilyGroupOperation 专属功能点', NOW(), '', NOW(), ''),
('HG-FamilyGroupEnquiry_OWN', 'FamilyGroupEnquiry_OWN', 'FamilyGroupEnquiry 专属功能点', NOW(), '', NOW(), ''),
('HG-Preview_OWN', 'Preview_OWN', 'Preview 专属功能点', NOW(), '', NOW(), ''),
('HG-PublishPhotoOperation_OWN', 'PublishPhotoOperation_OWN', 'PublishPhotoOperation 专属功能点', NOW(), '', NOW(), ''),
('HG-PublishPhotoEnquiry_OWN', 'PublishPhotoEnquiry_OWN', 'PublishPhotoEnquiry 专属功能点', NOW(), '', NOW(), ''),
('HG-PreviewAudio_OWN', 'PreviewAudio_OWN', 'PreviewAudio 专属功能点', NOW(), '', NOW(), ''),
('HG-PublishAudioOperation_OWN', 'PublishAudioOperation_OWN', 'PublishAudioOperation 专属功能点', NOW(), '', NOW(), ''),
('HG-PublishAudioEnquiry_OWN', 'PublishAudioEnquiry_OWN', 'PublishAudioEnquiry 专属功能点', NOW(), '', NOW(), ''),
('HG-PreviewVideo_OWN', 'PreviewVideo_OWN', 'PreviewVideo 专属功能点', NOW(), '', NOW(), ''),
('HG-PublishVideoOperation_OWN', 'PublishVideoOperation_OWN', 'PublishVideoOperation 专属功能点', NOW(), '', NOW(), ''),
('HG-PublishVideoEnquiry_OWN', 'PublishVideoEnquiry_OWN', 'PublishVideoEnquiry 专属功能点', NOW(), '', NOW(), ''),
('HG-FamilyPersonOperation_OWN', 'FamilyPersonOperation_OWN', 'FamilyPersonOperation 专属功能点', NOW(), '', NOW(), ''),
('HG-FamilyPersonEnquiry_OWN', 'FamilyPersonEnquiry_OWN', 'FamilyPersonEnquiry 专属功能点', NOW(), '', NOW(), ''),
('HG-FamilyTreeOperation_OWN', 'FamilyTreeOperation_OWN', 'FamilyTreeOperation 专属功能点', NOW(), '', NOW(), ''),
('HG-FamilyTreeEnquiry_OWN', 'FamilyTreeEnquiry_OWN', 'FamilyTreeEnquiry 专属功能点', NOW(), '', NOW(), ''),
('HG-FALLBACK_OWN', 'FALLBACK_OWN', 'FALLBACK 专属功能点', NOW(), '', NOW(), '');
-- 3. 功能点明细表
INSERT INTO security_help_feature (help_feature_id, help_feature_group_id, icon, color, name, description, sort_no, created_datetime, created_by, updated_datetime, updated_by) VALUES
('HFE-CRUD_HEAD-1', 'HG-CRUD_HEAD', 'FileSearchOutlined', '', '查询', '按输入的编号等条件检索对应记录。', 1, NOW(), '', NOW(), ''),
('HFE-CRUD_HEAD-2', 'HG-CRUD_HEAD', 'ClearOutlined', '', '重置', '清空查询条件与表单,回到待录入状态。', 2, NOW(), '', NOW(), ''),
('HFE-CRUD_HEAD-3', 'HG-CRUD_HEAD', 'FileAddOutlined', '', '新增', '新建一条空白记录。', 3, NOW(), '', NOW(), ''),
('HFE-CRUD_FOOT-1', 'HG-CRUD_FOOT', 'EditOutlined', '', '修改', '把已有记录切换成可编辑状态。', 1, NOW(), '', NOW(), ''),
('HFE-CRUD_FOOT-2', 'HG-CRUD_FOOT', 'SaveOutlined', '', '保存', '确认本次录入或修改,真正写入生效。', 2, NOW(), '', NOW(), ''),
('HFE-CRUD_FOOT-3', 'HG-CRUD_FOOT', 'UndoOutlined', '', '取消', '放弃本次编辑,回到修改前的状态。', 3, NOW(), '', NOW(), ''),
('HFE-CRUD_FOOT-4', 'HG-CRUD_FOOT', 'DeleteOutlined', 'red', '删除', '移除该条记录,危险操作用红色区分。', 4, NOW(), '', NOW(), ''),
('HFE-ROW_ACTION-1', 'HG-ROW_ACTION', 'UpSquareTwoTone', '', '上移', '调整这条明细在列表中的先后顺序。', 1, NOW(), '', NOW(), ''),
('HFE-ROW_ACTION-2', 'HG-ROW_ACTION', 'DownSquareTwoTone', '', '下移', '与上移相反,往下挪一位。', 2, NOW(), '', NOW(), ''),
('HFE-ROW_ACTION-3', 'HG-ROW_ACTION', 'DeleteOutlined', '', '删除本行', '移除这一条明细,不影响其它记录。', 3, NOW(), '', NOW(), ''),
('HFE-PUBLIC_GROUP-1', 'HG-PUBLIC_GROUP', 'PlusSquareTwoTone', '', '新增公开群组', '把这条内容授权给某个公开群组查看。', 1, NOW(), '', NOW(), ''),
('HFE-PUBLIC_GROUP-2', 'HG-PUBLIC_GROUP', 'DeleteOutlined', 'red', '移除公开群组', '取消这个群组的查看权。', 2, NOW(), '', NOW(), ''),
('HFE-TOOLBAR-1', 'HG-TOOLBAR', 'HomeOutlined', '', '返回顶层', '回到「我的云盘」根目录。', 1, NOW(), '', NOW(), ''),
('HFE-TOOLBAR-2', 'HG-TOOLBAR', 'ArrowLeftOutlined', '', '返回上层', '回到上一级文件夹。', 2, NOW(), '', NOW(), ''),
('HFE-TOOLBAR-3', 'HG-TOOLBAR', 'ReloadOutlined', '', '刷新', '重新加载当前目录的内容。', 3, NOW(), '', NOW(), ''),
('HFE-TOOLBAR-4', 'HG-TOOLBAR', 'LaptopOutlined', '', '电脑(路径起点)', '面包屑的第一段,代表云盘这台电脑。', 4, NOW(), '', NOW(), ''),
('HFE-TOOLBAR-5', 'HG-TOOLBAR', 'FolderOutlined', '#faad14', '文件夹(路径)', '橙色文件夹图标,每一段都可点击直接跳过去。', 5, NOW(), '', NOW(), ''),
('HFE-FILE_ICON-1', 'HG-FILE_ICON', 'FolderOutlined', '#faad14', '文件夹', '橙色的文件夹图标,双击进入。', 1, NOW(), '', NOW(), ''),
('HFE-FILE_ICON-2', 'HG-FILE_ICON', 'FileImageOutlined', '#52c41a', '图片文件', '绿色的图片图标。', 2, NOW(), '', NOW(), ''),
('HFE-FILE_ICON-3', 'HG-FILE_ICON', 'VideoCameraOutlined', '#1890ff', '视频文件', '蓝色的摄像机图标。', 3, NOW(), '', NOW(), ''),
('HFE-FILE_ICON-4', 'HG-FILE_ICON', 'PlayCircleOutlined', '#eb2f96', '音频文件', '粉色的播放圈图标。', 4, NOW(), '', NOW(), ''),
('HFE-FILE_ICON-5', 'HG-FILE_ICON', 'FileOutlined', '#8c8c8c', '其它文件', '灰色的普通文件图标。', 5, NOW(), '', NOW(), ''),
('HFE-FILE_ICON-6', 'HG-FILE_ICON', 'UnorderedListOutlined', '', '列表视图', '切换成一排排的列表显示。', 6, NOW(), '', NOW(), ''),
('HFE-FILE_ICON-7', 'HG-FILE_ICON', 'AppstoreOutlined', '', '图标视图', '切换成一块块的宫格显示。', 7, NOW(), '', NOW(), ''),
('HFE-PHOTO_HERO-1', 'HG-PHOTO_HERO', 'PictureOutlined', '', '相册(顶部大图)', '页面上最显眼的那张图片图标,代表整个相册。', 1, NOW(), '', NOW(), ''),
('HFE-PHOTO_EXTRA-1', 'HG-PHOTO_EXTRA', 'EditOutlined', '', '预览相册', '铅笔图标,切换到相册浏览看看发布后的效果。', 1, NOW(), '', NOW(), ''),
('HFE-AUDIO_HERO-1', 'HG-AUDIO_HERO', 'CustomerServiceOutlined', '', '专辑(顶部耳机)', '页面顶部耳机音符图标,代表整张专辑。', 1, NOW(), '', NOW(), ''),
('HFE-AUDIO_EXTRA-1', 'HG-AUDIO_EXTRA', 'EditOutlined', '', '音乐厅', '铅笔图标,切换到黑胶播放器实际听一下效果。', 1, NOW(), '', NOW(), ''),
('HFE-VIDEO_HERO-1', 'HG-VIDEO_HERO', 'VideoCameraOutlined', '', '专辑(顶部摄像机)', '页面顶部摄像机图标,代表整张视频专辑。', 1, NOW(), '', NOW(), ''),
('HFE-DmsFileEnquiry_OWN-1', 'HG-DmsFileEnquiry_OWN', 'FolderAddOutlined', '', '新建文件夹', '在当前目录创建一个新的文件夹。', 1, NOW(), '', NOW(), ''),
('HFE-DmsFileEnquiry_OWN-2', 'HG-DmsFileEnquiry_OWN', 'UploadOutlined', '', '上传文件', '把本地文件上传到当前目录。', 2, NOW(), '', NOW(), ''),
('HFE-DmsFileEnquiry_OWN-3', 'HG-DmsFileEnquiry_OWN', 'DownloadOutlined', '', '下载', '把选中的文件保存到本地。', 3, NOW(), '', NOW(), ''),
('HFE-DmsFileEnquiry_OWN-4', 'HG-DmsFileEnquiry_OWN', 'ShareAltOutlined', '', '共享', '分享给家庭成员或群组查看。', 4, NOW(), '', NOW(), ''),
('HFE-DmsFileEnquiry_OWN-5', 'HG-DmsFileEnquiry_OWN', 'NotificationOutlined', '', '发布', '把选中的媒体文件发布到相册 / 音乐 / 视频。', 5, NOW(), '', NOW(), ''),
('HFE-DmsFileEnquiry_OWN-6', 'HG-DmsFileEnquiry_OWN', 'icon-qingbaojiankong', '', '预览', '预览选中的文件(这个是产品自带图标,不是圆形箭头)。', 6, NOW(), '', NOW(), ''),
('HFE-DmsFileEnquiry_OWN-7', 'HG-DmsFileEnquiry_OWN', 'icon-foldervideo', '', '播放视频', '选中单个视频文件时用于直接播放。', 7, NOW(), '', NOW(), ''),
('HFE-DmsFileEnquiry_OWN-8', 'HG-DmsFileEnquiry_OWN', 'PlayCircleOutlined', 'red', '播放 / 暂停音频', '红色播放圈控制音频,播放中点一下变暂停。', 8, NOW(), '', NOW(), ''),
('HFE-DmsFileEnquiry_OWN-9', 'HG-DmsFileEnquiry_OWN', 'EditOutlined', '', '重命名', '修改选中文件或文件夹的名称。', 9, NOW(), '', NOW(), ''),
('HFE-DmsFileEnquiry_OWN-10', 'HG-DmsFileEnquiry_OWN', 'RotateRightOutlined', '', '移动', '把选中项搬到另一个目录,图标是向右旋转箭头。', 10, NOW(), '', NOW(), ''),
('HFE-DmsFileEnquiry_OWN-11', 'HG-DmsFileEnquiry_OWN', 'DeleteOutlined', 'red', '删除', '移到回收站,并没有真正消失,可去回收站还原。', 11, NOW(), '', NOW(), ''),
('HFE-DmsFileDeleteEnquiry_OWN-1', 'HG-DmsFileDeleteEnquiry_OWN', 'UndoOutlined', 'green', '还原', '绿色回转箭头,把文件恢复到删除前所在目录。', 1, NOW(), '', NOW(), ''),
('HFE-DmsFileDeleteEnquiry_OWN-2', 'HG-DmsFileDeleteEnquiry_OWN', 'DownloadOutlined', '', '下载', '把回收站里的文件保存到本地。', 2, NOW(), '', NOW(), ''),
('HFE-DmsFileDeleteEnquiry_OWN-3', 'HG-DmsFileDeleteEnquiry_OWN', 'DeleteOutlined', 'red', '彻底删除', '红色垃圾桶,永久删除且无法再还原。', 3, NOW(), '', NOW(), ''),
('HFE-DmsFileDeleteEnquiry_OWN-4', 'HG-DmsFileDeleteEnquiry_OWN', 'icon-foldervideo', '', '播放视频', '选中单个视频文件时用于试看后再决定。', 4, NOW(), '', NOW(), ''),
('HFE-DmsFileDeleteEnquiry_OWN-5', 'HG-DmsFileDeleteEnquiry_OWN', 'PlayCircleOutlined', 'red', '播放音频', '试听选中的音频文件。', 5, NOW(), '', NOW(), ''),
('HFE-FamilyGroupShare_OWN-1', 'HG-FamilyGroupShare_OWN', 'TeamOutlined', '', '群组', '共享给谁,按家庭群组为单位。', 1, NOW(), '', NOW(), ''),
('HFE-FamilyGroupShare_OWN-2', 'HG-FamilyGroupShare_OWN', 'FolderOutlined', '#faad14', '共享路径', '橙色文件夹图标显示被共享的目录层级。', 2, NOW(), '', NOW(), ''),
('HFE-FamilyGroupShare_OWN-3', 'HG-FamilyGroupShare_OWN', 'DeleteOutlined', 'red', '取消共享', '删除共享记录,成员即刻失去该目录的访问权。', 3, NOW(), '', NOW(), ''),
('HFE-FamilyShareOperation_OWN-1', 'HG-FamilyShareOperation_OWN', 'FolderOutlined', '#faad14', '被共享目录', '橙色文件夹图标,表示这个目录被共享出去了。', 1, NOW(), '', NOW(), ''),
('HFE-FamilyShareOperation_OWN-2', 'HG-FamilyShareOperation_OWN', 'TeamOutlined', '', '群组', '接收方,一次对整个群组授权。', 2, NOW(), '', NOW(), ''),
('HFE-FamilyShareOperation_OWN-3', 'HG-FamilyShareOperation_OWN', 'FileTextOutlined', '', '只读共享', '成员只能查看和下载,不能修改或删除原文件。', 3, NOW(), '', NOW(), ''),
('HFE-FamilyShareOperation_OWN-4', 'HG-FamilyShareOperation_OWN', 'EditOutlined', '', '可修改共享', '成员可上传和修改,操作会影响原始文件,谨慎开放。', 4, NOW(), '', NOW(), ''),
('HFE-FamilyShareOperation_OWN-5', 'HG-FamilyShareOperation_OWN', 'FileSearchOutlined', '', '查询', '按目录名称关键字筛选,定位到某条共享。', 5, NOW(), '', NOW(), ''),
('HFE-FamilyGroupOperation_OWN-1', 'HG-FamilyGroupOperation_OWN', 'TeamOutlined', '', '群组', '群组的图标是两个小人。', 1, NOW(), '', NOW(), ''),
('HFE-FamilyGroupOperation_OWN-2', 'HG-FamilyGroupOperation_OWN', 'UserAddOutlined', 'green', '添加成员', '绿色小人加号,把家庭成员加进这个群组。', 2, NOW(), '', NOW(), ''),
('HFE-FamilyGroupOperation_OWN-3', 'HG-FamilyGroupOperation_OWN', 'PlusSquareTwoTone', '', '新增共享目录', '给这个群组添加要共享的目录。', 3, NOW(), '', NOW(), ''),
('HFE-FamilyGroupOperation_OWN-4', 'HG-FamilyGroupOperation_OWN', 'CheckCircleTwoTone', '', '确认', '勾形图标,确认新增或修改。', 4, NOW(), '', NOW(), ''),
('HFE-FamilyGroupOperation_OWN-5', 'HG-FamilyGroupOperation_OWN', 'CloseCircleOutlined', '', '取消本次行修改', '叉形图标,放弃这一行的改动。', 5, NOW(), '', NOW(), ''),
('HFE-FamilyGroupOperation_OWN-6', 'HG-FamilyGroupOperation_OWN', 'DeleteOutlined', 'red', '删除本行', '移除这一条明细。', 6, NOW(), '', NOW(), ''),
('HFE-FamilyGroupEnquiry_OWN-1', 'HG-FamilyGroupEnquiry_OWN', 'FileSearchOutlined', '', '查询', '按群组名称关键字筛选。', 1, NOW(), '', NOW(), ''),
('HFE-FamilyGroupEnquiry_OWN-2', 'HG-FamilyGroupEnquiry_OWN', 'TeamOutlined', '', '群组列表', '展示群组名称与基本概况。', 2, NOW(), '', NOW(), ''),
('HFE-FamilyGroupEnquiry_OWN-3', 'HG-FamilyGroupEnquiry_OWN', 'FileTextOutlined', '', '查看', '文档图标,打开这条群组的详情看看。', 3, NOW(), '', NOW(), ''),
('HFE-FamilyGroupEnquiry_OWN-4', 'HG-FamilyGroupEnquiry_OWN', 'EditOutlined', '', '修改', '铅笔图标,编辑这条群组的名称、说明或成员。', 4, NOW(), '', NOW(), ''),
('HFE-FamilyGroupEnquiry_OWN-5', 'HG-FamilyGroupEnquiry_OWN', 'DeleteOutlined', 'red', '删除', '红色垃圾桶,移除这条群组。', 5, NOW(), '', NOW(), ''),
('HFE-Preview_OWN-1', 'HG-Preview_OWN', 'LeftCircleOutlined', '', '上一张', '页面左侧的圆形左箭头。', 1, NOW(), '', NOW(), ''),
('HFE-Preview_OWN-2', 'HG-Preview_OWN', 'RightCircleOutlined', '', '下一张', '页面右侧的圆形右箭头。', 2, NOW(), '', NOW(), ''),
('HFE-Preview_OWN-3', 'HG-Preview_OWN', 'PictureOutlined', '', '照片', '整页显示的就是当前这张照片。', 3, NOW(), '', NOW(), ''),
('HFE-PublishPhotoEnquiry_OWN-1', 'HG-PublishPhotoEnquiry_OWN', 'FileSearchOutlined', '', '查询', '按编号或名称关键字筛选。', 1, NOW(), '', NOW(), ''),
('HFE-PublishPhotoEnquiry_OWN-2', 'HG-PublishPhotoEnquiry_OWN', 'PictureOutlined', '', '照片 / 相册列表', '展示名称、编号、发布时间等主要信息。', 2, NOW(), '', NOW(), ''),
('HFE-PublishPhotoEnquiry_OWN-3', 'HG-PublishPhotoEnquiry_OWN', 'FileTextOutlined', '', '查看', '文档图标,打开这条记录的详情。', 3, NOW(), '', NOW(), ''),
('HFE-PublishPhotoEnquiry_OWN-4', 'HG-PublishPhotoEnquiry_OWN', 'EditOutlined', '', '修改', '铅笔图标,编辑这条相册 / 照片。', 4, NOW(), '', NOW(), ''),
('HFE-PublishPhotoEnquiry_OWN-5', 'HG-PublishPhotoEnquiry_OWN', 'DeleteOutlined', 'red', '删除', '移除后浏览端同步消失。', 5, NOW(), '', NOW(), ''),
('HFE-PreviewAudio_OWN-1', 'HG-PreviewAudio_OWN', 'CustomerServiceOutlined', '', '黑胶唱片', '中间的唱片,没歌时显示的是一个耳机音符图标。', 1, NOW(), '', NOW(), ''),
('HFE-PreviewAudio_OWN-2', 'HG-PreviewAudio_OWN', 'CaretRightFilled', '', '播放', '实心三角,开始播放当前曲目。', 2, NOW(), '', NOW(), ''),
('HFE-PreviewAudio_OWN-3', 'HG-PreviewAudio_OWN', 'PauseOutlined', '', '暂停', '播放中三角会变这个两竖杠,点一下暂停。', 3, NOW(), '', NOW(), ''),
('HFE-PreviewAudio_OWN-4', 'HG-PreviewAudio_OWN', 'StepBackwardFilled', '', '上一首', '实心左箭头加竖线。', 4, NOW(), '', NOW(), ''),
('HFE-PreviewAudio_OWN-5', 'HG-PreviewAudio_OWN', 'StepForwardFilled', '', '下一首', '实心右箭头加竖线。', 5, NOW(), '', NOW(), ''),
('HFE-PreviewAudio_OWN-6', 'HG-PreviewAudio_OWN', 'RetweetOutlined', '', '播放模式', '循环/单曲/顺序,随机时会换成另一个交叉箭头。', 6, NOW(), '', NOW(), ''),
('HFE-PreviewAudio_OWN-7', 'HG-PreviewAudio_OWN', 'UnorderedListOutlined', '', '播放列表', '展开全部曲目,点哪首就播哪首。', 7, NOW(), '', NOW(), ''),
('HFE-PreviewAudio_OWN-8', 'HG-PreviewAudio_OWN', 'InfoCircleOutlined', '', '歌曲信息', '歌名右边的圆圈叹号。', 8, NOW(), '', NOW(), ''),
('HFE-PreviewAudio_OWN-9', 'HG-PreviewAudio_OWN', 'HeartOutlined', '', '喜欢', '空心变实心表示已收藏。', 9, NOW(), '', NOW(), ''),
('HFE-PreviewAudio_OWN-10', 'HG-PreviewAudio_OWN', 'DownloadOutlined', '', '下载', '下载这首歌,旁边的小标 ON/OFF 是下载状态。', 10, NOW(), '', NOW(), ''),
('HFE-PreviewAudio_OWN-11', 'HG-PreviewAudio_OWN', 'AudioOutlined', '', '音量', '喇叭图标,静音时变成带叉的喇叭。', 11, NOW(), '', NOW(), ''),
('HFE-PreviewAudio_OWN-12', 'HG-PreviewAudio_OWN', 'FieldTimeOutlined', '', '定时关闭', '时钟图标,到点自动停止播放。', 12, NOW(), '', NOW(), ''),
('HFE-PreviewAudio_OWN-13', 'HG-PreviewAudio_OWN', 'EllipsisOutlined', '', '更多', '竖着的三点,其余功能都收在这里。', 13, NOW(), '', NOW(), ''),
('HFE-PreviewAudio_OWN-14', 'HG-PreviewAudio_OWN', 'DownOutlined', '', '收起播放器', '左上角向下箭头,返回进入前的页面。', 14, NOW(), '', NOW(), ''),
('HFE-PreviewAudio_OWN-15', 'HG-PreviewAudio_OWN', 'CloseOutlined', '', '关闭列表', '关掉弹出的曲目列表。', 15, NOW(), '', NOW(), ''),
('HFE-PublishAudioEnquiry_OWN-1', 'HG-PublishAudioEnquiry_OWN', 'FileSearchOutlined', '', '查询', '按编号或名称关键字筛选。', 1, NOW(), '', NOW(), ''),
('HFE-PublishAudioEnquiry_OWN-2', 'HG-PublishAudioEnquiry_OWN', 'CustomerServiceOutlined', '', '音频 / 专辑列表', '展示名称、编号、发布时间等信息。', 2, NOW(), '', NOW(), ''),
('HFE-PublishAudioEnquiry_OWN-3', 'HG-PublishAudioEnquiry_OWN', 'FileTextOutlined', '', '查看', '文档图标,打开这条记录的详情。', 3, NOW(), '', NOW(), ''),
('HFE-PublishAudioEnquiry_OWN-4', 'HG-PublishAudioEnquiry_OWN', 'EditOutlined', '', '修改', '铅笔图标,编辑这条专辑 / 音频。', 4, NOW(), '', NOW(), ''),
('HFE-PublishAudioEnquiry_OWN-5', 'HG-PublishAudioEnquiry_OWN', 'DeleteOutlined', 'red', '删除', '移除后音乐里同步消失。', 5, NOW(), '', NOW(), ''),
('HFE-PreviewVideo_OWN-1', 'HG-PreviewVideo_OWN', 'CaretRightFilled', '', '播放', '实心三角,开始播放。', 1, NOW(), '', NOW(), ''),
('HFE-PreviewVideo_OWN-2', 'HG-PreviewVideo_OWN', 'PauseOutlined', '', '暂停', '播放中变成两竖杠,点一下停住。', 2, NOW(), '', NOW(), ''),
('HFE-PreviewVideo_OWN-3', 'HG-PreviewVideo_OWN', 'StepBackwardFilled', '', '上一集', '实心左箭头加竖线。', 3, NOW(), '', NOW(), ''),
('HFE-PreviewVideo_OWN-4', 'HG-PreviewVideo_OWN', 'StepForwardFilled', '', '下一集', '实心右箭头加竖线。', 4, NOW(), '', NOW(), ''),
('HFE-PreviewVideo_OWN-5', 'HG-PreviewVideo_OWN', 'RetweetOutlined', '', '播放模式', '循环/单曲,随机时换成交叉箭头。', 5, NOW(), '', NOW(), ''),
('HFE-PreviewVideo_OWN-6', 'HG-PreviewVideo_OWN', 'UnorderedListOutlined', '', '播放列表', '展开全部剧集,点哪个就看哪个。', 6, NOW(), '', NOW(), ''),
('HFE-PreviewVideo_OWN-7', 'HG-PreviewVideo_OWN', 'FullscreenOutlined', '', '全屏', '四角方框,放大到满屏。', 7, NOW(), '', NOW(), ''),
('HFE-PreviewVideo_OWN-8', 'HG-PreviewVideo_OWN', 'FullscreenExitOutlined', '', '退出全屏', '全屏时按钮会变成这个四角内缩。', 8, NOW(), '', NOW(), ''),
('HFE-PreviewVideo_OWN-9', 'HG-PreviewVideo_OWN', 'HeartOutlined', '', '喜欢', '空心收藏,点完变实心的爱心。', 9, NOW(), '', NOW(), ''),
('HFE-PreviewVideo_OWN-10', 'HG-PreviewVideo_OWN', 'DownloadOutlined', '', '下载', '下载这个视频,旁边小标显示 ON/OFF。', 10, NOW(), '', NOW(), ''),
('HFE-PreviewVideo_OWN-11', 'HG-PreviewVideo_OWN', 'AudioOutlined', '', '音量', '喇叭图标,静音时变成带叉的喇叭。', 11, NOW(), '', NOW(), ''),
('HFE-PreviewVideo_OWN-12', 'HG-PreviewVideo_OWN', 'RotateRightOutlined', '', '旋转', '向右旋转画面,横竖屏不对时用它。', 12, NOW(), '', NOW(), ''),
('HFE-PreviewVideo_OWN-13', 'HG-PreviewVideo_OWN', 'FieldTimeOutlined', '', '定时关闭', '时钟图标,到点自动停止。', 13, NOW(), '', NOW(), ''),
('HFE-PreviewVideo_OWN-14', 'HG-PreviewVideo_OWN', 'EllipsisOutlined', '', '更多', '竖着的三点,其余功能都收在这里。', 14, NOW(), '', NOW(), ''),
('HFE-PreviewVideo_OWN-15', 'HG-PreviewVideo_OWN', 'CloseOutlined', '', '关闭列表', '关掉弹出的剧集列表。', 15, NOW(), '', NOW(), ''),
('HFE-PreviewVideo_OWN-16', 'HG-PreviewVideo_OWN', 'VideoCameraOutlined', '', '暂无视频', '专辑里没有视频时显示这个摄像机图标。', 16, NOW(), '', NOW(), ''),
('HFE-PublishVideoEnquiry_OWN-1', 'HG-PublishVideoEnquiry_OWN', 'FileSearchOutlined', '', '查询', '按编号或名称关键字筛选。', 1, NOW(), '', NOW(), ''),
('HFE-PublishVideoEnquiry_OWN-2', 'HG-PublishVideoEnquiry_OWN', 'VideoCameraOutlined', '', '视频 / 专辑列表', '展示名称、编号、发布时间等信息。', 2, NOW(), '', NOW(), ''),
('HFE-PublishVideoEnquiry_OWN-3', 'HG-PublishVideoEnquiry_OWN', 'FileTextOutlined', '', '查看', '文档图标,打开这条记录的详情。', 3, NOW(), '', NOW(), ''),
('HFE-PublishVideoEnquiry_OWN-4', 'HG-PublishVideoEnquiry_OWN', 'EditOutlined', '', '修改', '铅笔图标,编辑这条专辑 / 视频。', 4, NOW(), '', NOW(), ''),
('HFE-PublishVideoEnquiry_OWN-5', 'HG-PublishVideoEnquiry_OWN', 'DeleteOutlined', 'red', '删除', '移除后视频里同步消失。', 5, NOW(), '', NOW(), ''),
('HFE-FamilyPersonOperation_OWN-1', 'HG-FamilyPersonOperation_OWN', 'FileSearchOutlined', '', '查询', '放大镜图标,检索库里是否已有这位成员。', 1, NOW(), '', NOW(), ''),
('HFE-FamilyPersonOperation_OWN-2', 'HG-FamilyPersonOperation_OWN', 'ClearOutlined', '', '重置', '橡皮图标,清空表单回到空白状态。', 2, NOW(), '', NOW(), ''),
('HFE-FamilyPersonOperation_OWN-3', 'HG-FamilyPersonOperation_OWN', 'UserOutlined', '', '成员头像', '左边的圆形人头,还没传照片时显示的就是它。', 3, NOW(), '', NOW(), ''),
('HFE-FamilyPersonOperation_OWN-4', 'HG-FamilyPersonOperation_OWN', 'CameraOutlined', '', '更换头像', '编辑时盖在头像上的相机图标,点它上传本地照片。', 4, NOW(), '', NOW(), ''),
('HFE-FamilyPersonOperation_OWN-5', 'HG-FamilyPersonOperation_OWN', 'SaveOutlined', '', '保存', '软盘图标,确认写入本次录入或修改。', 5, NOW(), '', NOW(), ''),
('HFE-FamilyPersonOperation_OWN-6', 'HG-FamilyPersonOperation_OWN', 'UndoOutlined', '', '取消', '回转箭头,放弃本次编辑。', 6, NOW(), '', NOW(), ''),
('HFE-FamilyPersonOperation_OWN-7', 'HG-FamilyPersonOperation_OWN', 'EditOutlined', '', '修改', '铅笔图标,把已有成员变成可编辑状态。', 7, NOW(), '', NOW(), ''),
('HFE-FamilyPersonOperation_OWN-8', 'HG-FamilyPersonOperation_OWN', 'DeleteOutlined', 'red', '删除', '红色垃圾桶,移除成员(挂在族谱上的不能删)。', 8, NOW(), '', NOW(), ''),
('HFE-FamilyPersonEnquiry_OWN-1', 'HG-FamilyPersonEnquiry_OWN', 'FileSearchOutlined', '', '查询', '按姓名等关键字筛选。', 1, NOW(), '', NOW(), ''),
('HFE-FamilyPersonEnquiry_OWN-2', 'HG-FamilyPersonEnquiry_OWN', 'UserOutlined', '', '成员列表', '展示家庭成员的姓名、辈分等主要信息。', 2, NOW(), '', NOW(), ''),
('HFE-FamilyPersonEnquiry_OWN-3', 'HG-FamilyPersonEnquiry_OWN', 'FileTextOutlined', '', '查看', '文档图标,只能选一个人时可用。', 3, NOW(), '', NOW(), ''),
('HFE-FamilyPersonEnquiry_OWN-4', 'HG-FamilyPersonEnquiry_OWN', 'EditOutlined', '', '修改', '铅笔图标,只能选一个人时可用。', 4, NOW(), '', NOW(), ''),
('HFE-FamilyPersonEnquiry_OWN-5', 'HG-FamilyPersonEnquiry_OWN', 'DeleteOutlined', 'red', '删除', '红色垃圾桶,可以勾选多人一起删。', 5, NOW(), '', NOW(), ''),
('HFE-FamilyTreeOperation_OWN-1', 'HG-FamilyTreeOperation_OWN', 'ApartmentOutlined', '', '谱系图 / 祖谱系图', '二叉树形状的图标,点它看整张家族树。', 1, NOW(), '', NOW(), ''),
('HFE-FamilyTreeOperation_OWN-2', 'HG-FamilyTreeOperation_OWN', 'FileProtectOutlined', '', '申请管理', '带盾牌的文档,申请成为这个族谱的管理员。', 2, NOW(), '', NOW(), ''),
('HFE-FamilyTreeOperation_OWN-3', 'HG-FamilyTreeOperation_OWN', 'PlusSquareTwoTone', '', '新增夫妻 / 孩子关系', '虚线按钮上的加号方块,用来接上亲属。', 3, NOW(), '', NOW(), ''),
('HFE-FamilyTreeOperation_OWN-4', 'HG-FamilyTreeOperation_OWN', 'UpSquareTwoTone', '', '上移', '调整这位成员在列表中的位置。', 4, NOW(), '', NOW(), ''),
('HFE-FamilyTreeOperation_OWN-5', 'HG-FamilyTreeOperation_OWN', 'DownSquareTwoTone', '', '下移', '与上移相反。', 5, NOW(), '', NOW(), ''),
('HFE-FamilyTreeOperation_OWN-6', 'HG-FamilyTreeOperation_OWN', 'RightOutlined', '', '展开成员', '向右的小箭头,展开这一层的成员列表。', 6, NOW(), '', NOW(), ''),
('HFE-FamilyTreeOperation_OWN-7', 'HG-FamilyTreeOperation_OWN', 'CheckCircleTwoTone', '', '通过申请', '勾形圆圈,批准别人的管理申请。', 7, NOW(), '', NOW(), ''),
('HFE-FamilyTreeOperation_OWN-8', 'HG-FamilyTreeOperation_OWN', 'CrownOutlined', '#faad14', '设为管理员', '金色皇冠,批准对方成为管理员。', 8, NOW(), '', NOW(), ''),
('HFE-FamilyTreeOperation_OWN-9', 'HG-FamilyTreeOperation_OWN', 'CloseCircleOutlined', '', '拒绝申请', '叉形圆圈,驳回管理申请。', 9, NOW(), '', NOW(), ''),
('HFE-FamilyTreeOperation_OWN-10', 'HG-FamilyTreeOperation_OWN', 'EditOutlined', '', '修改', '铅笔图标,重新绘制这张族谱。', 10, NOW(), '', NOW(), ''),
('HFE-FamilyTreeOperation_OWN-11', 'HG-FamilyTreeOperation_OWN', 'SaveOutlined', '', '保存', '软盘图标,确认本次改动。', 11, NOW(), '', NOW(), ''),
('HFE-FamilyTreeOperation_OWN-12', 'HG-FamilyTreeOperation_OWN', 'UndoOutlined', '', '取消', '回转箭头,放弃本次修改。', 12, NOW(), '', NOW(), ''),
('HFE-FamilyTreeOperation_OWN-13', 'HG-FamilyTreeOperation_OWN', 'DeleteOutlined', 'red', '删除', '红色垃圾桶,移除整个族谱(成员档案不受影响)。', 13, NOW(), '', NOW(), ''),
('HFE-FamilyTreeEnquiry_OWN-1', 'HG-FamilyTreeEnquiry_OWN', 'FileAddOutlined', '', '新增', '右上角的新建文件图标,创建一张新族谱。', 1, NOW(), '', NOW(), ''),
('HFE-FamilyTreeEnquiry_OWN-2', 'HG-FamilyTreeEnquiry_OWN', 'ApartmentOutlined', '', '族谱列表', '展示族谱名称、成员数等主要信息。', 2, NOW(), '', NOW(), ''),
('HFE-FamilyTreeEnquiry_OWN-3', 'HG-FamilyTreeEnquiry_OWN', 'FileSearchOutlined', '', '查询', '按族谱名称关键字筛选。', 3, NOW(), '', NOW(), ''),
('HFE-FamilyTreeEnquiry_OWN-4', 'HG-FamilyTreeEnquiry_OWN', 'FileTextOutlined', '', '查看', '文档图标,只能勾一张时可用。', 4, NOW(), '', NOW(), ''),
('HFE-FamilyTreeEnquiry_OWN-5', 'HG-FamilyTreeEnquiry_OWN', 'EditOutlined', '', '修改', '铅笔图标,只能勾一张时可用,进去继续绘制。', 5, NOW(), '', NOW(), ''),
('HFE-FamilyTreeEnquiry_OWN-6', 'HG-FamilyTreeEnquiry_OWN', 'DeleteOutlined', 'red', '删除', '红色垃圾桶,可一次勾选多张删除。', 6, NOW(), '', NOW(), ''),
('HFE-FALLBACK_OWN-1', 'HG-FALLBACK_OWN', 'FileSearchOutlined', '', '查询', '放大镜加文档,按关键字筛选。', 1, NOW(), '', NOW(), ''),
('HFE-FALLBACK_OWN-2', 'HG-FALLBACK_OWN', 'ClearOutlined', '', '重置', '橡皮擦,清空条件恢复完整列表。', 2, NOW(), '', NOW(), ''),
('HFE-FALLBACK_OWN-3', 'HG-FALLBACK_OWN', 'FileAddOutlined', '', '新增', '新建文件图标,录入一条新记录。', 3, NOW(), '', NOW(), ''),
('HFE-FALLBACK_OWN-4', 'HG-FALLBACK_OWN', 'EditOutlined', '', '修改', '铅笔图标,把已有记录改成可编辑。', 4, NOW(), '', NOW(), ''),
('HFE-FALLBACK_OWN-5', 'HG-FALLBACK_OWN', 'SaveOutlined', '', '保存', '软盘图标,确认并写入。', 5, NOW(), '', NOW(), ''),
('HFE-FALLBACK_OWN-6', 'HG-FALLBACK_OWN', 'UndoOutlined', '', '取消', '回转箭头,放弃本次编辑。', 6, NOW(), '', NOW(), ''),
('HFE-FALLBACK_OWN-7', 'HG-FALLBACK_OWN', 'DeleteOutlined', 'red', '删除', '红色垃圾桶,移除选中的记录。', 7, NOW(), '', NOW(), ''),
('HFE-FALLBACK_OWN-8', 'HG-FALLBACK_OWN', 'FileTextOutlined', '', '查看', '文档图标,打开详情只读查看。', 8, NOW(), '', NOW(), '');
-- 4. 操作步骤表
INSERT INTO security_help_step (help_step_id, help_function_id, step_no, title, description, tips, icon, created_datetime, created_by, updated_datetime, updated_by) VALUES
('HS-DmsFileEnquiry-1', 'HF-DmsFileEnquiry', 1, '进入云盘,认认路', '打开后首先看到根目录下的内容,顶部一排小按钮从左到右分别是返回顶层、返回上层、刷新,右边是面包屑路径。', '', 'HomeOutlined', NOW(), '', NOW(), ''),
('HS-DmsFileEnquiry-2', 'HF-DmsFileEnquiry', 2, '在文件夹之间来回穿梭', '双击橘黄色的文件夹进入下一层;用左箭头返回上层,用小房子直接回到最顶层。', '顶部的路径每一段都可以直接点击,能一步跳到该层,不用一层层退出来。', 'FolderOutlined', NOW(), '', NOW(), ''),
('HS-DmsFileEnquiry-3', 'HF-DmsFileEnquiry', 3, '先把文件传上来', '选好目标目录后,点上传按钮(箭头朝上)添加本地文件,或点新建文件夹建立分类目录。', '', 'UploadOutlined', NOW(), '', NOW(), ''),
('HS-DmsFileEnquiry-4', 'HF-DmsFileEnquiry', 4, '选中条目再整理', '单击选中一个,再点下载、重命名、移动、删除;选中单个文件或多个同一类文件时还能共享和发布。', '「移动」的图标是一个向右旋转的箭头,不要错看成其它意思。', 'RotateRightOutlined', NOW(), '', NOW(), ''),
('HS-DmsFileEnquiry-5', 'HF-DmsFileEnquiry', 5, '共享给授权的家人', '选中文件或文件夹后点共享(分享箭头),家庭成员就能在自己的共享中看到它。', '「共享」是快速分享给他人文件的方法之一', 'ShareAltOutlined', NOW(), '', NOW(), ''),
('HS-DmsFileEnquiry-6', 'HF-DmsFileEnquiry', 6, '发布到相册展览、音乐厅、影视厅', '选中文件后点发布,不同文件对应发布到相册展览、音乐厅、影视厅,授权家人可看到它。', '「发布」是快速分享给他人文件的方法之一', 'NotificationOutlined', NOW(), '', NOW(), ''),
('HS-DmsFileDeleteEnquiry-1', 'HF-DmsFileDeleteEnquiry', 1, '打开回收站查看被删内容', '进入回收站,列表中显示已删除的文件、删除时间等,便于确认是不是误删的那份。', '', 'FolderOutlined', NOW(), '', NOW(), ''),
('HS-DmsFileDeleteEnquiry-2', 'HF-DmsFileDeleteEnquiry', 2, '确认是否需要找回', '先看清文件名和删除时间,选中需要找回的那个文件。', '还原按钮是绿色的回转箭头,点了之后文件会回到它原来所在的目录。', 'UndoOutlined', NOW(), '', NOW(), ''),
('HS-DmsFileDeleteEnquiry-3', 'HF-DmsFileDeleteEnquiry', 3, '还原到根目录', '点绿色还原箭头,文件回到根目录:找回误删文件就这一步。', '', '', NOW(), '', NOW(), ''),
('HS-DmsFileDeleteEnquiry-4', 'HF-DmsFileDeleteEnquiry', 4, '确认无用的再彻底删除', '确定彻底不要了,再点红色垃圾桶。这一步不可撤销,执行前请再确认一遍。', '回收站并没有「清空」按钮,只能逐条删除;嫌麻烦时更应该在删除前看清楚。', 'DeleteOutlined', NOW(), '', NOW(), ''),
('HS-FamilyGroupShare-1', 'HF-FamilyGroupShare', 1, '打开共享中心', '进入后列出每条共享记录:群组、共享路径、目录描述一目了然。', '', 'TeamOutlined', NOW(), '', NOW(), ''),
('HS-FamilyGroupShare-2', 'HF-FamilyGroupShare', 2, '核对共享路径', '看橙色文件夹图标旁边显示的路径,确认共享出去的是对的那个目录。', '路径写成「电脑 > 某层 > 某层」,一级是目录的一层。', 'FolderOutlined', NOW(), '', NOW(), ''),
('HS-FamilyGroupShare-3', 'HF-FamilyGroupShare', 3, '核对共享范围是否正确', '确认共享给了对的人、范围没有过大。', '一旦发现共享范围有误,应尽快取消,避免不该看的人看到。', '', NOW(), '', NOW(), ''),
('HS-FamilyGroupShare-4', 'HF-FamilyGroupShare', 4, '取消不再需要的共享', '选中对应的共享记录后删除,该群组会立即看不到这个目录。', '', 'DeleteOutlined', NOW(), '', NOW(), ''),
('HS-FamilyShareOperation-1', 'HF-FamilyShareOperation', 1, '先确认要共享的目录', '回到「我的云盘」确认目标目录已存在、内容正确,这是共享的前置条件。', '建议先整理好目录内容再共享,避免家人看到半成品。', 'FolderOutlined', NOW(), '', NOW(), ''),
('HS-FamilyShareOperation-2', 'HF-FamilyShareOperation', 2, '准备好接收方的群组', '确认「家庭群组」里已经有对应的群组,且需要看到的家人都在群组内。', '', 'TeamOutlined', NOW(), '', NOW(), ''),
('HS-FamilyShareOperation-3', 'HF-FamilyShareOperation', 3, '建立共享', '在共享功能中指定要共享的目录与接收群组,保存后生成共享记录。', '', '', NOW(), '', NOW(), ''),
('HS-FamilyShareOperation-4', 'HF-FamilyShareOperation', 4, '检查共享结果', '回到家庭群组共享列表,确认这条共享记录已经出现、路径无误。', '', 'FileSearchOutlined', NOW(), '', NOW(), ''),
('HS-FamilyShareOperation-5', 'HF-FamilyShareOperation', 5, '让对方登录核实', '请对方登录自己的账号确认可以看到;看不到时优先检查群组成员是否包含他。', '', '', NOW(), '', NOW(), ''),
('HS-FamilyGroupOperation-1', 'HF-FamilyGroupOperation', 1, '打开群组管理', '进入后顶部有查询、重置、新增三个按钮,下方列出已有群组。', '', 'FileSearchOutlined', NOW(), '', NOW(), ''),
('HS-FamilyGroupOperation-2', 'HF-FamilyGroupOperation', 2, '点「新增」建立群组', '填写群组名称等信息,然后保存。', '只有“公开设置”,家族成员才能“申请加入”', 'FileAddOutlined', NOW(), '', NOW(), ''),
('HS-FamilyGroupOperation-3', 'HF-FamilyGroupOperation', 3, '维护群组成员', '成员变动时在群组里增删成员即可,无需重新配置共享。用绿色小人图标把成员加进来。', '只有群组成员才能看到共享给该群组的内容,调整成员等于调整可见范围。', 'UserAddOutlined', NOW(), '', NOW(), ''),
('HS-FamilyGroupOperation-4', 'HF-FamilyGroupOperation', 4, '点「保存」生效', '改完一定要点保存;中途反悔点取消放弃本次编辑。', '', 'SaveOutlined', NOW(), '', NOW(), ''),
('HS-FamilyGroupEnquiry-1', 'HF-FamilyGroupEnquiry', 1, '打开群组查询列表', '进入后表格列出全部群组及其主要信息。', '', 'FileSearchOutlined', NOW(), '', NOW(), ''),
('HS-FamilyGroupEnquiry-2', 'HF-FamilyGroupEnquiry', 2, '筛选出目标群组', '在顶部输入名称关键字点查询,避免在大列表中翻找。', '', '', NOW(), '', NOW(), ''),
('HS-FamilyGroupEnquiry-3', 'HF-FamilyGroupEnquiry', 3, '点一行右侧的按钮处理', '每行的操作列里有查看(文档图标)、修改(铅笔)、删除(垃圾桶)三个按钮,点其中一个即可。', '这里的按钮是逐行点,不需要先勾选整行。', '', NOW(), '', NOW(), ''),
('HS-Preview-1', 'HF-Preview', 1, '进入相册浏览', '打开后直接看到当前相册里的照片,整页显示,背景是暗色。', '', 'PictureOutlined', NOW(), '', NOW(), ''),
('HS-Preview-2', 'HF-Preview', 2, '用左右箭头翻照片', '点左侧的「左圆圈箭头」看上一张,点右侧的「右圆圈箭头」看下一张。', '键盘上的左右方向键也能翻,比点按快得多。', 'RightCircleOutlined', NOW(), '', NOW(), ''),
('HS-Preview-3', 'HF-Preview', 3, '看完直接离开', '这一页没有专门的关闭按钮,用浏览器的返回即可回到进入前的页面。', '', '', NOW(), '', NOW(), ''),
('HS-PublishPhotoOperation-1', 'HF-PublishPhotoOperation', 1, '点「新增」建立相册', '点放大镜旁边的新建文件图标,进入可编辑状态,开始录入一个新相册。', '', 'FileAddOutlined', NOW(), '', NOW(), ''),
('HS-PublishPhotoOperation-2', 'HF-PublishPhotoOperation', 2, '填写相册信息', '最左边是张图片图标,代表整个相册;右边填写相册名称、描述等,编号由系统给出不用自己填。', '公开与否决定家人以外的人能否看到,不确定时先不公开。', 'PictureOutlined', NOW(), '', NOW(), ''),
('HS-PublishPhotoOperation-3', 'HF-PublishPhotoOperation', 3, '选择并上传照片', '在明细区域逐张上传本地图片,用上下箭头调整照片的先后顺序。', '建议先压缩过大的照片,上传更快也更省空间。', 'UploadOutlined', NOW(), '', NOW(), ''),
('HS-PublishPhotoOperation-4', 'HF-PublishPhotoOperation', 4, '点「保存」发布', '确认信息无误后点保存(软盘图标);中途反悔点取消(回转箭头)放弃。', '', 'SaveOutlined', NOW(), '', NOW(), ''),
('HS-PublishPhotoOperation-5', 'HF-PublishPhotoOperation', 5, '到相册浏览核实效果', '发布完成后去相册浏览查看,用左右箭头翻一遍,确认照片能正常显示、顺序正确。', '', 'RightCircleOutlined', NOW(), '', NOW(), ''),
('HS-PublishPhotoEnquiry-1', 'HF-PublishPhotoEnquiry', 1, '打开照片查询列表', '进入后表格列出全部已发布的照片 / 相册记录。', '', 'FileSearchOutlined', NOW(), '', NOW(), ''),
('HS-PublishPhotoEnquiry-2', 'HF-PublishPhotoEnquiry', 2, '筛选出目标记录', '在顶部输入相册编号或名称点查询,直接定位到该条记录。', '', '', NOW(), '', NOW(), ''),
('HS-PublishPhotoEnquiry-3', 'HF-PublishPhotoEnquiry', 3, '点右侧按钮处理', '每行的操作列里有文档图标(查看)、铅笔(修改)、红色垃圾桶(删除)。', '', '', NOW(), '', NOW(), ''),
('HS-PreviewAudio-1', 'HF-PreviewAudio', 1, '进入音乐播放', '打开后自动加载默认专辑中的曲目,中间的黑胶唱片就是当前这首歌。', '', 'CustomerServiceOutlined', NOW(), '', NOW(), ''),
('HS-PreviewAudio-2', 'HF-PreviewAudio', 2, '控制播放', '唱片下方一整排:左边循环/随机切换模式,往右是上一首、播放(三角)、下一首、播放列表。', '播放中的按钮会变成暂停(两竖杠),点一下停住,再点继续。', 'CaretRightFilled', NOW(), '', NOW(), ''),
('HS-PreviewAudio-3', 'HF-PreviewAudio', 3, '调音量和看看歌词', '歌名右边的圆圈叹号可以看歌曲信息;右下角一排小按钮里,喇叭是音量、时钟是定时关闭、心形是收藏。', '', 'AudioOutlined', NOW(), '', NOW(), ''),
('HS-PreviewAudio-4', 'HF-PreviewAudio', 4, '换歌或退出', '点列表图标展开全部曲目直接挑一首;听完点左上角向下的箭头收起播放器返回。', '', 'DownOutlined', NOW(), '', NOW(), ''),
('HS-PublishAudioOperation-1', 'HF-PublishAudioOperation', 1, '点「新增」建立专辑', '点新建文件图标进入可编辑状态,开始录入一个新专辑。', '', 'FileAddOutlined', NOW(), '', NOW(), ''),
('HS-PublishAudioOperation-2', 'HF-PublishAudioOperation', 2, '填写专辑信息', '最左边是耳机音符图标,代表整张专辑;右边填专辑名称、描述,编号由系统生成。', '把同一主题或同一位歌手的音频放进一个专辑,收听时更方便。', 'CustomerServiceOutlined', NOW(), '', NOW(), ''),
('HS-PublishAudioOperation-3', 'HF-PublishAudioOperation', 3, '上传音频并排序', '在明细区域逐个上传音频文件,用上下方块箭头调整曲目顺序。', '音频文件通常较大,上传需要一点时间,请不要中途关闭页面。', 'UploadOutlined', NOW(), '', NOW(), ''),
('HS-PublishAudioOperation-4', 'HF-PublishAudioOperation', 4, '点「保存」发布', '确认无误后点软盘图标保存;想放弃点回转箭头的取消。', '', 'SaveOutlined', NOW(), '', NOW(), ''),
('HS-PublishAudioOperation-5', 'HF-PublishAudioOperation', 5, '到音乐里试听核实', '发布完成后去音乐播放页确认能正常播放、曲目完整。', '', 'CustomerServiceOutlined', NOW(), '', NOW(), ''),
('HS-PublishAudioEnquiry-1', 'HF-PublishAudioEnquiry', 1, '打开音频查询列表', '进入后表格列出全部已发布的音频 / 专辑记录。', '', 'FileSearchOutlined', NOW(), '', NOW(), ''),
('HS-PublishAudioEnquiry-2', 'HF-PublishAudioEnquiry', 2, '筛选出目标记录', '输入专辑编号点查询定位。', '', '', NOW(), '', NOW(), ''),
('HS-PublishAudioEnquiry-3', 'HF-PublishAudioEnquiry', 3, '点右侧按钮处理', '操作列里的文档图标是查看、铅笔是修改、红色垃圾桶是删除。', '', '', NOW(), '', NOW(), ''),
('HS-PreviewVideo-1', 'HF-PreviewVideo', 1, '进入视频播放', '打开后进入播放界面,系统加载当前专辑里的视频内容。', '', 'VideoCameraOutlined', NOW(), '', NOW(), ''),
('HS-PreviewVideo-2', 'HF-PreviewVideo', 2, '控制播放', '画面下方一排:左边是播放模式,往右是上一集、播放/暂停、下一集、播放列表。', '视频文件较大,首次播放可能需要缓冲一会儿。', 'CaretRightFilled', NOW(), '', NOW(), ''),
('HS-PreviewVideo-3', 'HF-PreviewVideo', 3, '用右上方那排小按钮', '心形收藏、箭头下载、方框全屏、旋转、时钟定时、喇叭音量,最后的三点是全部其它功能。', '', 'FullscreenOutlined', NOW(), '', NOW(), ''),
('HS-PreviewVideo-4', 'HF-PreviewVideo', 4, '换下一个或直接离开', '点列表图标展开全部剧集挑一个;看完直接用浏览器返回即可。', '', 'UnorderedListOutlined', NOW(), '', NOW(), ''),
('HS-PublishVideoOperation-1', 'HF-PublishVideoOperation', 1, '点「新增」建立专辑', '点新建文件图标进入可编辑状态,开始录入一个新视频专辑。', '', 'FileAddOutlined', NOW(), '', NOW(), ''),
('HS-PublishVideoOperation-2', 'HF-PublishVideoOperation', 2, '填写专辑信息', '最左边是摄像机图标,代表整张专辑;右边填专辑名称、描述,编号由系统生成。', '', 'VideoCameraOutlined', NOW(), '', NOW(), ''),
('HS-PublishVideoOperation-3', 'HF-PublishVideoOperation', 3, '上传视频并排序', '在明细区域逐个上传视频文件,用上下方块箭头调整播放顺序。', '视频体积大,上传耗时较长,请保持页面打开直到进度完成。', 'UploadOutlined', NOW(), '', NOW(), ''),
('HS-PublishVideoOperation-4', 'HF-PublishVideoOperation', 4, '点「保存」发布', '确认无误后点软盘图标保存;反悔点回转箭头的取消。', '', 'SaveOutlined', NOW(), '', NOW(), ''),
('HS-PublishVideoOperation-5', 'HF-PublishVideoOperation', 5, '到视频里试播核实', '发布完成后去视频播放页确认能正常观看、内容完整。', '', 'VideoCameraOutlined', NOW(), '', NOW(), ''),
('HS-PublishVideoEnquiry-1', 'HF-PublishVideoEnquiry', 1, '打开视频查询列表', '进入后表格列出全部已发布的视频 / 专辑记录。', '', 'FileSearchOutlined', NOW(), '', NOW(), ''),
('HS-PublishVideoEnquiry-2', 'HF-PublishVideoEnquiry', 2, '筛选出目标记录', '输入专辑编号点查询定位。', '', '', NOW(), '', NOW(), ''),
('HS-PublishVideoEnquiry-3', 'HF-PublishVideoEnquiry', 3, '点右侧按钮处理', '操作列里的文档图标是查看、铅笔是修改、红色垃圾桶是删除。', '', '', NOW(), '', NOW(), ''),
('HS-FamilyPersonOperation-1', 'HF-FamilyPersonOperation', 1, '打开成员录入', '进入后顶部只有查询、重置两个按钮(放大镜和橡皮),没有单独的新增按钮:页面本身就可以直接填写。', '想确认库里有没有这个人,先用查询查一下,避免重复录入。', 'FileSearchOutlined', NOW(), '', NOW(), ''),
('HS-FamilyPersonOperation-2', 'HF-FamilyPersonOperation', 2, '先给成员配张头像', '点左边那个圆形头像;处于编辑状态时头像是被相机图标盖住,点它换本地照片。', '', 'CameraOutlined', NOW(), '', NOW(), ''),
('HS-FamilyPersonOperation-3', 'HF-FamilyPersonOperation', 3, '填写成员信息', '填写姓名、称谓、辈分等,带必填标记的项不能为空。', '录入越完整,后续绘制族谱时关系越准确。', '', NOW(), '', NOW(), ''),
('HS-FamilyPersonOperation-4', 'HF-FamilyPersonOperation', 4, '点「保存」完成录入', '确认无误后点软盘图标保存;中途反悔点回转箭头的取消放弃这次编辑。', '', 'SaveOutlined', NOW(), '', NOW(), ''),
('HS-FamilyPersonOperation-5', 'HF-FamilyPersonOperation', 5, '后续修改或删除', '先查询找到该成员,再点铅笔图标修改,或点红色垃圾桶删除。', '已经挂到某个族谱下的成员不允许删除,需先把它从族谱中移除。', '', NOW(), '', NOW(), ''),
('HS-FamilyPersonEnquiry-1', 'HF-FamilyPersonEnquiry', 1, '打开成员列表', '进入后表格列出全部家庭成员及其主要信息。', '', 'FileSearchOutlined', NOW(), '', NOW(), ''),
('HS-FamilyPersonEnquiry-2', 'HF-FamilyPersonEnquiry', 2, '勾选一个人', '点左侧勾选框选中成员。注意查看和修改一次只能勾一个,勾多了按钮会变灰。', '本页没有新增按钮,要录入新成员请去「家庭成员」页面。', '', NOW(), '', NOW(), ''),
('HS-FamilyPersonEnquiry-3', 'HF-FamilyPersonEnquiry', 3, '点下方的按钮处理', '文档图标查看详情、铅笔图标修改、红色垃圾桶删除(删除可以多选)。', '', 'EditOutlined', NOW(), '', NOW(), ''),
('HS-FamilyTreeOperation-1', 'HF-FamilyTreeOperation', 1, '先确保成员已录入', '绘制族谱前,先在「家庭成员」里把需要出现在族谱上的人都录入好。', '成员资料越完整,生成的族谱越准确,建议先把成员录齐再来绘制。', 'UserOutlined', NOW(), '', NOW(), ''),
('HS-FamilyTreeOperation-2', 'HF-FamilyTreeOperation', 2, '点「新增」建立族谱', '顶部三个按钮依次是查询、重置、新增(新建文件图标),点新增开始绘制一张新族谱。', '', 'FileAddOutlined', NOW(), '', NOW(), ''),
('HS-FamilyTreeOperation-3', 'HF-FamilyTreeOperation', 3, '逐个添加亲属关系', '页面上每个成员后面都有「+ 夫妻关系」「+ 孩子关系」这样的虚线按钮,点加号方块逐步把人接上去。', '', 'PlusSquareTwoTone', NOW(), '', NOW(), ''),
('HS-FamilyTreeOperation-4', 'HF-FamilyTreeOperation', 4, '调整顺序与展示', '每位成员右侧的上/下方块调整排位;点中间的二叉树或类图腾看整张谱系图。', '', 'ApartmentOutlined', NOW(), '', NOW(), ''),
('HS-FamilyTreeOperation-5', 'HF-FamilyTreeOperation', 5, '点「保存」完成族谱', '确认布局与连线无误后点软盘图标保存;反悔点回转箭头的取消放弃本次修改。', '', 'SaveOutlined', NOW(), '', NOW(), ''),
('HS-FamilyTreeEnquiry-1', 'HF-FamilyTreeEnquiry', 1, '打开族谱列表', '进入后表格列出全部族谱及其基本信息。', '', 'FileSearchOutlined', NOW(), '', NOW(), ''),
('HS-FamilyTreeEnquiry-2', 'HF-FamilyTreeEnquiry', 2, '点「新增」建新族谱', '右上角的控制区有一个新建文件图标,点了就去创建一张全新族谱。', '', 'FileAddOutlined', NOW(), '', NOW(), ''),
('HS-FamilyTreeEnquiry-3', 'HF-FamilyTreeEnquiry', 3, '勾选一张再操作', '查看和修改一次只能勾一张,多选时这两个按钮会变灰;删除则允许一次勾多张。', '双击某一行也会直接进入查看详情,比点按钮更快。', '', NOW(), '', NOW(), ''),
('HS-FamilyTreeEnquiry-4', 'HF-FamilyTreeEnquiry', 4, '点下方按钮处理', '文档图标查看、铅笔图标修改、红色垃圾桶删除。', '', 'EditOutlined', NOW(), '', NOW(), ''),
('HS-FALLBACK-1', 'HF-FALLBACK', 1, '先从入口进入功能页', '在首页对应的分组卡片里点击功能条目,即可打开这个功能页面。', '', '', NOW(), '', NOW(), ''),
('HS-FALLBACK-2', 'HF-FALLBACK', 2, '看顶部的查询与底部的操作', '放大镜像家协会查询、橡皮是重置、新建文件是新增;下面依次是修改(铅笔)、保存(软盘)、取消(回转箭头)、删除(红色垃圾桶)。', '', 'FileSearchOutlined', NOW(), '', NOW(), ''),
('HS-FALLBACK-3', 'HF-FALLBACK', 3, '按需要填写并提交', '表单填完一定要点软盘图标保存,内容才真正写入;不想保留就点回转箭头取消。', '录入或修改后一定要点保存,否则关掉页面就白填了。', 'SaveOutlined', NOW(), '', NOW(), '');
-- 5. 功能与组的组合关系表(显示顺序就在这张表里)
INSERT INTO security_help_function_feature (help_function_feature_id, function_name, group_code, sort_no, created_datetime, created_by, updated_datetime, updated_by) VALUES
('HFF-DmsFileEnquiry-1', 'DmsFileEnquiry', 'TOOLBAR', 1, NOW(), '', NOW(), ''),
('HFF-DmsFileEnquiry-2', 'DmsFileEnquiry', 'FILE_ICON', 2, NOW(), '', NOW(), ''),
('HFF-DmsFileEnquiry-3', 'DmsFileEnquiry', 'DmsFileEnquiry_OWN', 3, NOW(), '', NOW(), ''),
('HFF-DmsFileDeleteEnquiry-1', 'DmsFileDeleteEnquiry', 'TOOLBAR', 1, NOW(), '', NOW(), ''),
('HFF-DmsFileDeleteEnquiry-2', 'DmsFileDeleteEnquiry', 'FILE_ICON', 2, NOW(), '', NOW(), ''),
('HFF-DmsFileDeleteEnquiry-3', 'DmsFileDeleteEnquiry', 'DmsFileDeleteEnquiry_OWN', 3, NOW(), '', NOW(), ''),
('HFF-FamilyGroupShare-1', 'FamilyGroupShare', 'FamilyGroupShare_OWN', 1, NOW(), '', NOW(), ''),
('HFF-FamilyShareOperation-1', 'FamilyShareOperation', 'FamilyShareOperation_OWN', 1, NOW(), '', NOW(), ''),
('HFF-FamilyGroupOperation-1', 'FamilyGroupOperation', 'CRUD_HEAD', 1, NOW(), '', NOW(), ''),
('HFF-FamilyGroupOperation-2', 'FamilyGroupOperation', 'FamilyGroupOperation_OWN', 2, NOW(), '', NOW(), ''),
('HFF-FamilyGroupOperation-3', 'FamilyGroupOperation', 'CRUD_FOOT', 3, NOW(), '', NOW(), ''),
('HFF-FamilyGroupEnquiry-1', 'FamilyGroupEnquiry', 'FamilyGroupEnquiry_OWN', 1, NOW(), '', NOW(), ''),
('HFF-Preview-1', 'Preview', 'Preview_OWN', 1, NOW(), '', NOW(), ''),
('HFF-PublishPhotoOperation-1', 'PublishPhotoOperation', 'CRUD_HEAD', 1, NOW(), '', NOW(), ''),
('HFF-PublishPhotoOperation-2', 'PublishPhotoOperation', 'PHOTO_HERO', 2, NOW(), '', NOW(), ''),
('HFF-PublishPhotoOperation-3', 'PublishPhotoOperation', 'ROW_ACTION', 3, NOW(), '', NOW(), ''),
('HFF-PublishPhotoOperation-4', 'PublishPhotoOperation', 'PUBLIC_GROUP', 4, NOW(), '', NOW(), ''),
('HFF-PublishPhotoOperation-5', 'PublishPhotoOperation', 'PHOTO_EXTRA', 5, NOW(), '', NOW(), ''),
('HFF-PublishPhotoOperation-6', 'PublishPhotoOperation', 'CRUD_FOOT', 6, NOW(), '', NOW(), ''),
('HFF-PublishPhotoEnquiry-1', 'PublishPhotoEnquiry', 'PublishPhotoEnquiry_OWN', 1, NOW(), '', NOW(), ''),
('HFF-PreviewAudio-1', 'PreviewAudio', 'PreviewAudio_OWN', 1, NOW(), '', NOW(), ''),
('HFF-PublishAudioOperation-1', 'PublishAudioOperation', 'CRUD_HEAD', 1, NOW(), '', NOW(), ''),
('HFF-PublishAudioOperation-2', 'PublishAudioOperation', 'AUDIO_HERO', 2, NOW(), '', NOW(), ''),
('HFF-PublishAudioOperation-3', 'PublishAudioOperation', 'ROW_ACTION', 3, NOW(), '', NOW(), ''),
('HFF-PublishAudioOperation-4', 'PublishAudioOperation', 'PUBLIC_GROUP', 4, NOW(), '', NOW(), ''),
('HFF-PublishAudioOperation-5', 'PublishAudioOperation', 'AUDIO_EXTRA', 5, NOW(), '', NOW(), ''),
('HFF-PublishAudioOperation-6', 'PublishAudioOperation', 'CRUD_FOOT', 6, NOW(), '', NOW(), ''),
('HFF-PublishAudioEnquiry-1', 'PublishAudioEnquiry', 'PublishAudioEnquiry_OWN', 1, NOW(), '', NOW(), ''),
('HFF-PreviewVideo-1', 'PreviewVideo', 'PreviewVideo_OWN', 1, NOW(), '', NOW(), ''),
('HFF-PublishVideoOperation-1', 'PublishVideoOperation', 'CRUD_HEAD', 1, NOW(), '', NOW(), ''),
('HFF-PublishVideoOperation-2', 'PublishVideoOperation', 'VIDEO_HERO', 2, NOW(), '', NOW(), ''),
('HFF-PublishVideoOperation-3', 'PublishVideoOperation', 'ROW_ACTION', 3, NOW(), '', NOW(), ''),
('HFF-PublishVideoOperation-4', 'PublishVideoOperation', 'PUBLIC_GROUP', 4, NOW(), '', NOW(), ''),
('HFF-PublishVideoOperation-5', 'PublishVideoOperation', 'CRUD_FOOT', 5, NOW(), '', NOW(), ''),
('HFF-PublishVideoEnquiry-1', 'PublishVideoEnquiry', 'PublishVideoEnquiry_OWN', 1, NOW(), '', NOW(), ''),
('HFF-FamilyPersonOperation-1', 'FamilyPersonOperation', 'FamilyPersonOperation_OWN', 1, NOW(), '', NOW(), ''),
('HFF-FamilyPersonEnquiry-1', 'FamilyPersonEnquiry', 'FamilyPersonEnquiry_OWN', 1, NOW(), '', NOW(), ''),
('HFF-FamilyTreeOperation-1', 'FamilyTreeOperation', 'CRUD_HEAD', 1, NOW(), '', NOW(), ''),
('HFF-FamilyTreeOperation-2', 'FamilyTreeOperation', 'FamilyTreeOperation_OWN', 2, NOW(), '', NOW(), ''),
('HFF-FamilyTreeEnquiry-1', 'FamilyTreeEnquiry', 'FamilyTreeEnquiry_OWN', 1, NOW(), '', NOW(), ''),
('HFF-FALLBACK-1', 'FALLBACK', 'FALLBACK_OWN', 1, NOW(), '', NOW(), '');
+230
View File
@@ -0,0 +1,230 @@
import { SecurityHelpFunctionEntity } from "@/data/auto/securityHelpFunctionEntity";
import { SecurityHelpStepEntity } from "@/data/auto/securityHelpStepEntity";
import { SecurityHelpFeatureGroupEntity } from "@/data/auto/securityHelpFeatureGroupEntity";
import { SecurityHelpFeatureEntity } from "@/data/auto/securityHelpFeatureEntity";
import { SecurityHelpFunctionFeatureEntity } from "@/data/auto/securityHelpFunctionFeatureEntity";
import { SecurityHelpFunctionData } from "@/data/auto/securityHelpFunctionData";
import {
HELP_DOCS,
fallbackDoc,
crudHeadFeatures,
crudFootFeatures,
rowActionFeatures,
toolbarFeatures,
fileIconFeatures,
publicGroupFeatures,
photoHeroFeatures,
photoExtraFeatures,
audioHeroFeatures,
audioExtraFeatures,
videoHeroFeatures,
} from "./helpDocs";
import type { HelpDoc, HelpFeature } from "./helpDocs";
/*
* 建表用种子数据(实体用的是生成器产出的 SecurityHelp* 系列)
*
* 用途有两个:
* 1) 交给后端做初始化数据(helpDocSchema.sql 建表后灌进去,
* 也可直接用导出的 src\data\help\helpDocSeed.sql)
* 2) 接口还没就绪时,前端拿这批行组合显示,页面不会空白
*
* 组合方式:一个功能引用若干个「功能点组」,按 FUNCTION_LAYOUT 里的顺序拼起来。
* 公共组(顶部三件套、云盘路径栏、文件图标……)只维护一份,多个功能共用。
*/
/** 一个可复用的功能点组 */
interface FeatureGroupSeed {
code: string;
name: string;
items: HelpFeature[];
}
/** layout 里代表「这个功能专属的那部分功能点」 */
export const OWN_GROUP = "OWN";
/** 兜底文档在表里用的功能名 */
export const FALLBACK_FUNCTION = "FALLBACK";
/** 表里的全部功能文档:正式文档 + 通用兜底(兜底也要入库,否则接口没数据时它就没了) */
const ALL_DOCS: Record<string, HelpDoc> = { ...HELP_DOCS, [FALLBACK_FUNCTION]: fallbackDoc };
/** 可复用的功能点组:改这里,所有引用它的功能一起变 */
const FEATURE_GROUP_SEED: FeatureGroupSeed[] = [
{ code: "CRUD_HEAD", name: "顶部三件套(查询 / 重置 / 新增)", items: crudHeadFeatures },
{ code: "CRUD_FOOT", name: "底部操作区(修改 / 保存 / 取消 / 删除)", items: crudFootFeatures },
{ code: "ROW_ACTION", name: "明细行操作(上移 / 下移 / 删除本行)", items: rowActionFeatures },
{ code: "PUBLIC_GROUP", name: "公开群组授权", items: publicGroupFeatures },
{ code: "TOOLBAR", name: "云盘路径栏 Toolbar.vue", items: toolbarFeatures },
{ code: "FILE_ICON", name: "文件列表图标 MyComputer.vue", items: fileIconFeatures },
{ code: "PHOTO_HERO", name: "相册发布页顶部大图", items: photoHeroFeatures },
{ code: "PHOTO_EXTRA", name: "相册发布页「预览相册」", items: photoExtraFeatures },
{ code: "AUDIO_HERO", name: "音频发布页顶部耳机", items: audioHeroFeatures },
{ code: "AUDIO_EXTRA", name: "音频发布页「音乐厅」", items: audioExtraFeatures },
{ code: "VIDEO_HERO", name: "视频发布页顶部摄像机", items: videoHeroFeatures },
];
/**
* 每个功能由哪些组按顺序拼起来。
* 顺序即显示顺序,想调整页面上的先后,改这个数组就行,不用动代码。
*/
export const FUNCTION_LAYOUT: Record<string, string[]> = {
/* 网盘 */
DmsFileEnquiry: ["TOOLBAR", "FILE_ICON", OWN_GROUP],
DmsFileDeleteEnquiry: ["TOOLBAR", "FILE_ICON", OWN_GROUP],
/* 共享中心 */
FamilyGroupShare: [OWN_GROUP],
FamilyShareOperation: [OWN_GROUP],
FamilyGroupOperation: ["CRUD_HEAD", OWN_GROUP, "CRUD_FOOT"],
FamilyGroupEnquiry: [OWN_GROUP],
/* 相册 */
Preview: [OWN_GROUP],
PublishPhotoOperation: ["CRUD_HEAD", "PHOTO_HERO", "ROW_ACTION", "PUBLIC_GROUP", "PHOTO_EXTRA", "CRUD_FOOT"],
PublishPhotoEnquiry: [OWN_GROUP],
/* 音乐 */
PreviewAudio: [OWN_GROUP],
PublishAudioOperation: ["CRUD_HEAD", "AUDIO_HERO", "ROW_ACTION", "PUBLIC_GROUP", "AUDIO_EXTRA", "CRUD_FOOT"],
PublishAudioEnquiry: [OWN_GROUP],
/* 视频 */
PreviewVideo: [OWN_GROUP],
PublishVideoOperation: ["CRUD_HEAD", "VIDEO_HERO", "ROW_ACTION", "PUBLIC_GROUP", "CRUD_FOOT"],
PublishVideoEnquiry: [OWN_GROUP],
/* 族谱 */
FamilyPersonOperation: [OWN_GROUP],
FamilyPersonEnquiry: [OWN_GROUP],
FamilyTreeOperation: ["CRUD_HEAD", OWN_GROUP],
FamilyTreeEnquiry: [OWN_GROUP],
/* 未编写专属文档时的通用兜底 */
[FALLBACK_FUNCTION]: [OWN_GROUP],
};
/** 所有共享组的条目,用来反推出每个功能「专属」的那部分 */
const SHARED_FEATURES = new Set<HelpFeature>();
FEATURE_GROUP_SEED.forEach((g) => g.items.forEach((item) => SHARED_FEATURES.add(item)));
/**
* 某功能专属的功能点 = 它的完整列表里,不属于任何公共组的那些。
* 能这样算是因为 features 里展开的就是公共组的同一批对象。
*/
const ownFeaturesOf = (features: HelpFeature[]): HelpFeature[] =>
features.filter((f) => !SHARED_FEATURES.has(f));
/** 专属组在表里的编码 */
export const ownGroupCode = (functionName: string) => `${functionName}_OWN`;
/** 建一份实体并填字段的小工具 */
const fill = <T extends object>(entity: T, values: Partial<T>): T => Object.assign(entity, values);
/* ==========================================================
* 下面把现有内容摊平成 5 张表的行
* ========================================================== */
/** security_help_function:一个功能一行 */
export const securityHelpFunctionRows: SecurityHelpFunctionEntity[] = [
...Object.keys(ALL_DOCS).map((functionName) =>
fill(new SecurityHelpFunctionEntity(), {
HelpFunctionId: `HF-${functionName}`,
FunctionName: functionName,
Intro: ALL_DOCS[functionName].intro,
EnabledIndc: "Y",
})
),
];
/** security_help_step:时间轴上的每一步一行 */
export const securityHelpStepRows: SecurityHelpStepEntity[] = Object.keys(ALL_DOCS).flatMap(
(functionName) =>
ALL_DOCS[functionName].steps.map((step, index) =>
fill(new SecurityHelpStepEntity(), {
HelpStepId: `HS-${functionName}-${index + 1}`,
HelpFunctionId: `HF-${functionName}`,
StepNo: index + 1,
Title: step.title,
Description: step.desc,
Tips: step.tips ?? "",
Icon: step.icon ?? "",
})
)
);
/** security_help_feature_group:公共组 + 每个功能的专属组 */
export const securityHelpFeatureGroupRows: SecurityHelpFeatureGroupEntity[] = [
...FEATURE_GROUP_SEED.map((g) =>
fill(new SecurityHelpFeatureGroupEntity(), {
HelpFeatureGroupId: `HG-${g.code}`,
GroupCode: g.code,
GroupName: g.name,
})
),
...Object.keys(ALL_DOCS).map((functionName) =>
fill(new SecurityHelpFeatureGroupEntity(), {
HelpFeatureGroupId: `HG-${ownGroupCode(functionName)}`,
GroupCode: ownGroupCode(functionName),
GroupName: `${functionName} 专属功能点`,
})
),
];
/** security_help_feature:每个组里的每一条 */
export const securityHelpFeatureRows: SecurityHelpFeatureEntity[] = [
...FEATURE_GROUP_SEED.flatMap((g) =>
g.items.map((item, index) =>
fill(new SecurityHelpFeatureEntity(), {
HelpFeatureId: `HFE-${g.code}-${index + 1}`,
HelpFeatureGroupId: `HG-${g.code}`,
Icon: item.icon ?? "",
Color: item.color ?? "",
Name: item.name,
Description: item.desc,
SortNo: index + 1,
})
)
),
...Object.keys(ALL_DOCS).flatMap((functionName) =>
ownFeaturesOf(ALL_DOCS[functionName].features).map((item, index) =>
fill(new SecurityHelpFeatureEntity(), {
HelpFeatureId: `HFE-${ownGroupCode(functionName)}-${index + 1}`,
HelpFeatureGroupId: `HG-${ownGroupCode(functionName)}`,
Icon: item.icon ?? "",
Color: item.color ?? "",
Name: item.name,
Description: item.desc,
SortNo: index + 1,
})
)
),
];
/** security_help_function_feature:谁用哪些组、按什么顺序 —— 组合关系就在这张表 */
export const securityHelpFunctionFeatureRows: SecurityHelpFunctionFeatureEntity[] = Object.keys(
FUNCTION_LAYOUT
).flatMap((functionName) =>
FUNCTION_LAYOUT[functionName].map((groupCode, index) =>
fill(new SecurityHelpFunctionFeatureEntity(), {
HelpFunctionFeatureId: `HFF-${functionName}-${index + 1}`,
FunctionName: functionName,
GroupCode: groupCode === OWN_GROUP ? ownGroupCode(functionName) : groupCode,
SortNo: index + 1,
})
)
);
/**
* 按接口返回的结构打成一个包,接口还没就绪时前端直接拿它组合显示。
* 结构和 SecurityHelpFunctionData 完全一致,所以切换数据源时不用改任何渲染逻辑。
*/
export const buildSeedHelpDocData = (): SecurityHelpFunctionData =>
Object.assign(new SecurityHelpFunctionData(), {
SecurityHelpFunctions: securityHelpFunctionRows,
SecurityHelpSteps: securityHelpStepRows,
SecurityHelpFeatureGroups: securityHelpFeatureGroupRows,
SecurityHelpFeatures: securityHelpFeatureRows,
SecurityHelpFunctionFeatures: securityHelpFunctionFeatureRows,
});
+940
View File
@@ -0,0 +1,940 @@
/*
* 各功能的新手帮助文档:上方时间轴讲操作流程,下方网格讲功能点与图标含义。
*
* 维护方式:按「功能英文名 FunctionName」注册一份 HelpDoc,
* 由 HelpTimelineModal 统一渲染。
*
* ============================ 极其重要 ============================
* icon 字段必须照抄页面上真实使用的那个图标,绝不能凭想象另配一套,
* 否则用户拿着帮助文档去页面上根本找不到对应的按钮。
* 以 "icon-" 开头 → 项目自定义 iconfont(如预览 icon-qingbaojiankong)
* 其余 → Ant Design 官方图标组件名(如 DeleteOutlined)
* color 同理,用于还原页面上的真实颜色(如红色的垃圾桶)。
*
* 取值来源(改动前请先回这几处核对):
* Toolbar.vue 返回顶层 / 返回上层 / 刷新 / 面包屑
* OperatorStation.vue 云盘各个操作按钮
* OperatorStationDelete.vue 回收站的还原 / 下载 / 彻底删除
* MyComputer.vue 文件列表中的文件夹与各类文件图标
* VideoPlayer.vue 视频播放器的播放、全屏、音量等
* 以及各功能页自身顶部的查询 / 重置 / 新增三件套与底部操作区。
* ==================================================================
*/
export interface HelpStep {
/** 步骤标题(先做什么) */
title: string;
/** 这一步具体怎么做 */
desc: string;
/** 补充说明,可不填 */
tips?: string;
/** 图标:antd 组件名或 icon- 开头的 iconfont 名,需与页面上一致 */
icon?: string;
}
export interface HelpFeature {
/** 图标:antd 组件名或 icon- 开头的 iconfont 名,需与页面上一致 */
icon?: string;
/**
* 页面上的真实颜色,例如文件夹黄 #faad14、彻底删除红。
* 不填则跟随分组主题色。
*/
color?: string;
/** 功能点名称,一般就是按钮上的字 */
name: string;
/** 作用说明 */
desc: string;
}
export interface HelpDoc {
/** 一句话说明这个功能是什么 */
intro: string;
/** 操作流程,按顺序执行 */
steps: HelpStep[];
/** 页面中各个功能点 / 图标的含义 */
features: HelpFeature[];
}
/* ==========================================================
* 各页面通用的三件套与底部操作:查询 / 重置 / 新增、保存 / 取消 / 修改 / 删除
* 这几个页面顶部和底部的按钮写法完全一致,图标也就复用同一批。
* ========================================================== */
/** 顶部三个按钮:查询 / 重置 / 新增 */
export const crudHeadFeatures: HelpFeature[] = [
{ icon: "FileSearchOutlined", name: "查询", desc: "按输入的编号等条件检索对应记录。" },
{ icon: "ClearOutlined", name: "重置", desc: "清空查询条件与表单,回到待录入状态。" },
{ icon: "FileAddOutlined", name: "新增", desc: "新建一条空白记录。" },
];
/** 底部四个按钮:修改 / 保存 / 取消 / 删除 */
export const crudFootFeatures: HelpFeature[] = [
{ icon: "EditOutlined", name: "修改", desc: "把已有记录切换成可编辑状态。" },
{ icon: "SaveOutlined", name: "保存", desc: "确认本次录入或修改,真正写入生效。" },
{ icon: "UndoOutlined", name: "取消", desc: "放弃本次编辑,回到修改前的状态。" },
{ icon: "DeleteOutlined", color: "red", name: "删除", desc: "移除该条记录,危险操作用红色区分。" },
];
/** 明细行里的三个小图标:上移 / 下移 / 删除 */
export const rowActionFeatures: HelpFeature[] = [
{ icon: "UpSquareTwoTone", name: "上移", desc: "调整这条明细在列表中的先后顺序。" },
{ icon: "DownSquareTwoTone", name: "下移", desc: "与上移相反,往下挪一位。" },
{ icon: "DeleteOutlined", name: "删除本行", desc: "移除这一条明细,不影响其它记录。" },
];
/* ==========================================================
* 网盘
* ========================================================== */
/** 云盘 / 回收站共用:顶部路径栏 Toolbar.vue */
export const toolbarFeatures: HelpFeature[] = [
{ icon: "HomeOutlined", name: "返回顶层", desc: "回到「我的云盘」根目录。" },
{ icon: "ArrowLeftOutlined", name: "返回上层", desc: "回到上一级文件夹。" },
{ icon: "ReloadOutlined", name: "刷新", desc: "重新加载当前目录的内容。" },
{ icon: "LaptopOutlined", name: "电脑(路径起点)", desc: "面包屑的第一段,代表云盘这台电脑。" },
{ icon: "FolderOutlined", color: "#faad14", name: "文件夹(路径)", desc: "橙色文件夹图标,每一段都可点击直接跳过去。" },
];
/** MyComputer.vue 中列表里各类文件的图标 */
export const fileIconFeatures: HelpFeature[] = [
{ icon: "FolderOutlined", color: "#faad14", name: "文件夹", desc: "橙色的文件夹图标,双击进入。" },
{ icon: "FileImageOutlined", color: "#52c41a", name: "图片文件", desc: "绿色的图片图标。" },
{ icon: "VideoCameraOutlined", color: "#1890ff", name: "视频文件", desc: "蓝色的摄像机图标。" },
{ icon: "PlayCircleOutlined", color: "#eb2f96", name: "音频文件", desc: "粉色的播放圈图标。" },
{ icon: "FileOutlined", color: "#8c8c8c", name: "其它文件", desc: "灰色的普通文件图标。" },
{ icon: "UnorderedListOutlined", name: "列表视图", desc: "切换成一排排的列表显示。" },
{ icon: "AppstoreOutlined", name: "图标视图", desc: "切换成一块块的宫格显示。" },
];
/** 我的云盘:OperatorStation.vue */
const dmsFileEnquiry: HelpDoc = {
intro: "「我的云盘」是存放和管理文件的地方:上传自己的文件、建文件夹归类,也能下载、移动。可共享给家人或者发布到相相册展览、音乐厅、影视厅,这些都可以独立授权。",
steps: [
{
title: "进入云盘,认认路",
desc: "打开后首先看到根目录下的内容,顶部一排小按钮从左到右分别是返回顶层、返回上层、刷新,右边是面包屑路径。",
icon: "HomeOutlined",
},
{
title: "在文件夹之间来回穿梭",
desc: "双击橘黄色的文件夹进入下一层;用左箭头返回上层,用小房子直接回到最顶层。",
icon: "FolderOutlined",
tips: "顶部的路径每一段都可以直接点击,能一步跳到该层,不用一层层退出来。",
},
{
title: "先把文件传上来",
desc: "选好目标目录后,点上传按钮(箭头朝上)添加本地文件,或点新建文件夹建立分类目录。",
icon: "UploadOutlined",
},
{
title: "选中条目再整理",
desc: "单击选中一个,再点下载、重命名、移动、删除;选中单个文件或多个同一类文件时还能共享和发布。",
icon: "RotateRightOutlined",
tips: "「移动」的图标是一个向右旋转的箭头,不要错看成其它意思。",
},
{
title: "共享给授权的家人",
desc: "选中文件或文件夹后点共享(分享箭头),家庭成员就能在自己的共享中看到它。",
icon: "ShareAltOutlined",
tips: "「共享」是快速分享给他人文件的方法之一",
},
{
title: "发布到相册展览、音乐厅、影视厅",
desc: "选中文件后点发布,不同文件对应发布到相册展览、音乐厅、影视厅,授权家人可看到它。",
icon: "NotificationOutlined",
tips: "「发布」是快速分享给他人文件的方法之一",
},
],
features: [
...toolbarFeatures,
...fileIconFeatures,
{ icon: "FolderAddOutlined", name: "新建文件夹", desc: "在当前目录创建一个新的文件夹。" },
{ icon: "UploadOutlined", name: "上传文件", desc: "把本地文件上传到当前目录。" },
{ icon: "DownloadOutlined", name: "下载", desc: "把选中的文件保存到本地。" },
{ icon: "ShareAltOutlined", name: "共享", desc: "分享给家庭成员或群组查看。" },
{ icon: "NotificationOutlined", name: "发布", desc: "把选中的媒体文件发布到相册 / 音乐 / 视频。" },
{ icon: "icon-qingbaojiankong", name: "预览", desc: "预览选中的文件(这个是产品自带图标,不是圆形箭头)。" },
{ icon: "icon-foldervideo", name: "播放视频", desc: "选中单个视频文件时用于直接播放。" },
{ icon: "PlayCircleOutlined", color: "red", name: "播放 / 暂停音频", desc: "红色播放圈控制音频,播放中点一下变暂停。" },
{ icon: "EditOutlined", name: "重命名", desc: "修改选中文件或文件夹的名称。" },
{ icon: "RotateRightOutlined", name: "移动", desc: "把选中项搬到另一个目录,图标是向右旋转箭头。" },
{ icon: "DeleteOutlined", color: "red", name: "删除", desc: "移到回收站,并没有真正消失,可去回收站还原。" },
],
};
/** 回收站:OperatorStationDelete.vue,注意它只有三个操作,没有「清空」 */
const dmsFileDeleteEnquiry: HelpDoc = {
intro: "「回收站」存放从云盘删除的文件,给误删留一次还原的机会。这里的删除是真的没了,没有第二次机会。",
steps: [
{
title: "打开回收站查看被删内容",
desc: "进入回收站,列表中显示已删除的文件、删除时间等,便于确认是不是误删的那份。",
icon: "FolderOutlined",
},
{
title: "确认是否需要找回",
desc: "先看清文件名和删除时间,选中需要找回的那个文件。",
icon: "UndoOutlined",
tips: "还原按钮是绿色的回转箭头,点了之后文件会回到它原来所在的目录。",
},
{
title: "还原到根目录",
desc: "点绿色还原箭头,文件回到根目录:找回误删文件就这一步。",
},
{
title: "确认无用的再彻底删除",
desc: "确定彻底不要了,再点红色垃圾桶。这一步不可撤销,执行前请再确认一遍。",
icon: "DeleteOutlined",
tips: "回收站并没有「清空」按钮,只能逐条删除;嫌麻烦时更应该在删除前看清楚。",
},
],
features: [
...toolbarFeatures,
...fileIconFeatures,
{ icon: "UndoOutlined", color: "green", name: "还原", desc: "绿色回转箭头,把文件恢复到删除前所在目录。" },
{ icon: "DownloadOutlined", name: "下载", desc: "把回收站里的文件保存到本地。" },
{ icon: "DeleteOutlined", color: "red", name: "彻底删除", desc: "红色垃圾桶,永久删除且无法再还原。" },
{ icon: "icon-foldervideo", name: "播放视频", desc: "选中单个视频文件时用于试看后再决定。" },
{ icon: "PlayCircleOutlined", color: "red", name: "播放音频", desc: "试听选中的音频文件。" },
],
};
/* ==========================================================
* 共享中心
* ========================================================== */
/** 共享中心 */
const familyGroupShare: HelpDoc = {
intro: "「共享中心」家族成员能看到授权的文件",
steps: [
{
title: "打开共享中心",
desc: "进入后列出每条共享记录:群组、共享路径、目录描述一目了然。",
icon: "TeamOutlined",
},
{
title: "核对共享路径",
desc: "看橙色文件夹图标旁边显示的路径,确认共享出去的是对的那个目录。",
icon: "FolderOutlined",
tips: "路径写成「电脑 > 某层 > 某层」,一级是目录的一层。",
},
{
title: "核对共享范围是否正确",
desc: "确认共享给了对的人、范围没有过大。",
tips: "一旦发现共享范围有误,应尽快取消,避免不该看的人看到。",
},
{
title: "取消不再需要的共享",
desc: "选中对应的共享记录后删除,该群组会立即看不到这个目录。",
icon: "DeleteOutlined",
},
],
features: [
{ icon: "TeamOutlined", name: "群组", desc: "共享给谁,按家庭群组为单位。" },
{ icon: "FolderOutlined", color: "#faad14", name: "共享路径", desc: "橙色文件夹图标显示被共享的目录层级。" },
{ icon: "DeleteOutlined", color: "red", name: "取消共享", desc: "删除共享记录,成员即刻失去该目录的访问权。" },
],
};
/** 家庭共享 */
const familyShareOperation: HelpDoc = {
intro: "「家庭共享」把云盘中的某个目录共享给指定的家庭群组,让家人能看到这份内容。",
steps: [
{
title: "先确认要共享的目录",
desc: "回到「我的云盘」确认目标目录已存在、内容正确,这是共享的前置条件。",
icon: "FolderOutlined",
tips: "建议先整理好目录内容再共享,避免家人看到半成品。",
},
{
title: "准备好接收方的群组",
desc: "确认「家庭群组」里已经有对应的群组,且需要看到的家人都在群组内。",
icon: "TeamOutlined",
},
{
title: "建立共享",
desc: "在共享功能中指定要共享的目录与接收群组,保存后生成共享记录。",
},
{
title: "检查共享结果",
desc: "回到家庭群组共享列表,确认这条共享记录已经出现、路径无误。",
icon: "FileSearchOutlined",
},
{
title: "让对方登录核实",
desc: "请对方登录自己的账号确认可以看到;看不到时优先检查群组成员是否包含他。",
},
],
features: [
{ icon: "FolderOutlined", color: "#faad14", name: "被共享目录", desc: "橙色文件夹图标,表示这个目录被共享出去了。" },
{ icon: "TeamOutlined", name: "群组", desc: "接收方,一次对整个群组授权。" },
{ icon: "FileTextOutlined", name: "只读共享", desc: "成员只能查看和下载,不能修改或删除原文件。" },
{ icon: "EditOutlined", name: "可修改共享", desc: "成员可上传和修改,操作会影响原始文件,谨慎开放。" },
{ icon: "FileSearchOutlined", name: "查询", desc: "按目录名称关键字筛选,定位到某条共享。" },
],
};
/** 群组管理 */
const familyGroupOperation: HelpDoc = {
intro: "「群组」把家庭成员组织成一个个小组,共享时按群组授权,是家庭协作的基础设置。",
steps: [
{
title: "打开群组管理",
desc: "进入后顶部有查询、重置、新增三个按钮,下方列出已有群组。",
icon: "FileSearchOutlined",
},
{
title: "点「新增」建立群组",
desc: "填写群组名称等信息,然后保存。",
icon: "FileAddOutlined",
tips: "只有“公开设置”,家族成员才能“申请加入”",
},
{
title: "维护群组成员",
desc: "成员变动时在群组里增删成员即可,无需重新配置共享。用绿色小人图标把成员加进来。",
icon: "UserAddOutlined",
tips: "只有群组成员才能看到共享给该群组的内容,调整成员等于调整可见范围。",
},
{
title: "点「保存」生效",
desc: "改完一定要点保存;中途反悔点取消放弃本次编辑。",
icon: "SaveOutlined",
},
],
features: [
...crudHeadFeatures,
{ icon: "TeamOutlined", name: "群组", desc: "群组的图标是两个小人。" },
{ icon: "UserAddOutlined", color: "green", name: "添加成员", desc: "绿色小人加号,把家庭成员加进这个群组。" },
{ icon: "PlusSquareTwoTone", name: "新增共享目录", desc: "给这个群组添加要共享的目录。" },
{ icon: "CheckCircleTwoTone", name: "确认", desc: "勾形图标,确认新增或修改。" },
{ icon: "CloseCircleOutlined", name: "取消本次行修改", desc: "叉形图标,放弃这一行的改动。" },
{ icon: "DeleteOutlined", color: "red", name: "删除本行", desc: "移除这一条明细。" },
...crudFootFeatures,
],
};
/** 群组查询 */
const familyGroupEnquiry: HelpDoc = {
intro: "「群组查询」集中查看所有家庭群组的概况,并从这里进入查看、修改与删除。",
steps: [
{
title: "打开群组查询列表",
desc: "进入后表格列出全部群组及其主要信息。",
icon: "FileSearchOutlined",
},
{
title: "筛选出目标群组",
desc: "在顶部输入名称关键字点查询,避免在大列表中翻找。",
},
{
title: "点一行右侧的按钮处理",
desc: "每行的操作列里有查看(文档图标)、修改(铅笔)、删除(垃圾桶)三个按钮,点其中一个即可。",
tips: "这里的按钮是逐行点,不需要先勾选整行。",
},
],
features: [
{ icon: "FileSearchOutlined", name: "查询", desc: "按群组名称关键字筛选。" },
{ icon: "TeamOutlined", name: "群组列表", desc: "展示群组名称与基本概况。" },
{ icon: "FileTextOutlined", name: "查看", desc: "文档图标,打开这条群组的详情看看。" },
{ icon: "EditOutlined", name: "修改", desc: "铅笔图标,编辑这条群组的名称、说明或成员。" },
{ icon: "DeleteOutlined", color: "red", name: "删除", desc: "红色垃圾桶,移除这条群组。" },
],
};
/* ==========================================================
* 相册
* ========================================================== */
/** 发布类页面共用的「公开群组」两个按钮 */
export const publicGroupFeatures: HelpFeature[] = [
{ icon: "PlusSquareTwoTone", name: "新增公开群组", desc: "把这条内容授权给某个公开群组查看。" },
{ icon: "DeleteOutlined", color: "red", name: "移除公开群组", desc: "取消这个群组的查看权。" },
];
/** 相册发布页:顶部大图 + 预览相册 */
export const photoHeroFeatures: HelpFeature[] = [
{ icon: "PictureOutlined", name: "相册(顶部大图)", desc: "页面上最显眼的那张图片图标,代表整个相册。" },
];
export const photoExtraFeatures: HelpFeature[] = [
{ icon: "EditOutlined", name: "预览相册", desc: "铅笔图标,切换到相册浏览看看发布后的效果。" },
];
/** 音频发布页:顶部耳机 + 音乐厅 */
export const audioHeroFeatures: HelpFeature[] = [
{ icon: "CustomerServiceOutlined", name: "专辑(顶部耳机)", desc: "页面顶部耳机音符图标,代表整张专辑。" },
];
export const audioExtraFeatures: HelpFeature[] = [
{ icon: "EditOutlined", name: "音乐厅", desc: "铅笔图标,切换到黑胶播放器实际听一下效果。" },
];
/** 视频发布页:顶部摄像机 */
export const videoHeroFeatures: HelpFeature[] = [
{ icon: "VideoCameraOutlined", name: "专辑(顶部摄像机)", desc: "页面顶部摄像机图标,代表整张视频专辑。" },
];
/** 发布类页面(相册 / 音乐 / 视频)共同的按钮:顶部三件套 + 明细行 + 公开群组 + 底部操作区 */
export const publishFeatures = (hero: HelpFeature[], extra: HelpFeature[] = []): HelpFeature[] => [
...crudHeadFeatures,
...hero,
...rowActionFeatures,
...publicGroupFeatures,
...extra,
...crudFootFeatures,
];
/** 相册浏览:页面上只有左右两个圆形箭头可点 */
const preview: HelpDoc = {
intro: "「相册浏览」查看已发布的照片:进入后是整页的大图,用左右两个圆形箭头依次翻看。",
steps: [
{
title: "进入相册浏览",
desc: "打开后直接看到当前相册里的照片,整页显示,背景是暗色。",
icon: "PictureOutlined",
},
{
title: "用左右箭头翻照片",
desc: "点左侧的「左圆圈箭头」看上一张,点右侧的「右圆圈箭头」看下一张。",
icon: "RightCircleOutlined",
tips: "键盘上的左右方向键也能翻,比点按快得多。",
},
{
title: "看完直接离开",
desc: "这一页没有专门的关闭按钮,用浏览器的返回即可回到进入前的页面。",
},
],
features: [
{ icon: "LeftCircleOutlined", name: "上一张", desc: "页面左侧的圆形左箭头。" },
{ icon: "RightCircleOutlined", name: "下一张", desc: "页面右侧的圆形右箭头。" },
{ icon: "PictureOutlined", name: "照片", desc: "整页显示的就是当前这张照片。" },
],
};
/** 相册发布 */
const publishPhotoOperation: HelpDoc = {
intro: "「相册发布」把本地照片整理成一个相册并发布;发布后照片才会出现在相册浏览里。",
steps: [
{
title: "点「新增」建立相册",
desc: "点放大镜旁边的新建文件图标,进入可编辑状态,开始录入一个新相册。",
icon: "FileAddOutlined",
},
{
title: "填写相册信息",
desc: "最左边是张图片图标,代表整个相册;右边填写相册名称、描述等,编号由系统给出不用自己填。",
icon: "PictureOutlined",
tips: "公开与否决定家人以外的人能否看到,不确定时先不公开。",
},
{
title: "选择并上传照片",
desc: "在明细区域逐张上传本地图片,用上下箭头调整照片的先后顺序。",
icon: "UploadOutlined",
tips: "建议先压缩过大的照片,上传更快也更省空间。",
},
{
title: "点「保存」发布",
desc: "确认信息无误后点保存(软盘图标);中途反悔点取消(回转箭头)放弃。",
icon: "SaveOutlined",
},
{
title: "到相册浏览核实效果",
desc: "发布完成后去相册浏览查看,用左右箭头翻一遍,确认照片能正常显示、顺序正确。",
icon: "RightCircleOutlined",
},
],
features: publishFeatures(photoHeroFeatures, photoExtraFeatures),
};
/** 照片查询 */
const publishPhotoEnquiry: HelpDoc = {
intro: "「照片查询」集中查看自己发布过的相册与照片,便于批量核对和整理。",
steps: [
{
title: "打开照片查询列表",
desc: "进入后表格列出全部已发布的照片 / 相册记录。",
icon: "FileSearchOutlined",
},
{
title: "筛选出目标记录",
desc: "在顶部输入相册编号或名称点查询,直接定位到该条记录。",
},
{
title: "点右侧按钮处理",
desc: "每行的操作列里有文档图标(查看)、铅笔(修改)、红色垃圾桶(删除)。",
},
],
features: [
{ icon: "FileSearchOutlined", name: "查询", desc: "按编号或名称关键字筛选。" },
{ icon: "PictureOutlined", name: "照片 / 相册列表", desc: "展示名称、编号、发布时间等主要信息。" },
{ icon: "FileTextOutlined", name: "查看", desc: "文档图标,打开这条记录的详情。" },
{ icon: "EditOutlined", name: "修改", desc: "铅笔图标,编辑这条相册 / 照片。" },
{ icon: "DeleteOutlined", color: "red", name: "删除", desc: "移除后浏览端同步消失。" },
],
};
/* ==========================================================
* 音乐
* ========================================================== */
/** 音乐播放:VinylAudioPlayer.vue(黑胶唱片播放器) */
const previewAudio: HelpDoc = {
intro: "「音乐」用来收听已发布的音频:进入后是一台黑胶唱片机,唱片转起来就在放歌了。",
steps: [
{
title: "进入音乐播放",
desc: "打开后自动加载默认专辑中的曲目,中间的黑胶唱片就是当前这首歌。",
icon: "CustomerServiceOutlined",
},
{
title: "控制播放",
desc: "唱片下方一整排:左边循环/随机切换模式,往右是上一首、播放(三角)、下一首、播放列表。",
icon: "CaretRightFilled",
tips: "播放中的按钮会变成暂停(两竖杠),点一下停住,再点继续。",
},
{
title: "调音量和看看歌词",
desc: "歌名右边的圆圈叹号可以看歌曲信息;右下角一排小按钮里,喇叭是音量、时钟是定时关闭、心形是收藏。",
icon: "AudioOutlined",
},
{
title: "换歌或退出",
desc: "点列表图标展开全部曲目直接挑一首;听完点左上角向下的箭头收起播放器返回。",
icon: "DownOutlined",
},
],
features: [
{ icon: "CustomerServiceOutlined", name: "黑胶唱片", desc: "中间的唱片,没歌时显示的是一个耳机音符图标。" },
{ icon: "CaretRightFilled", name: "播放", desc: "实心三角,开始播放当前曲目。" },
{ icon: "PauseOutlined", name: "暂停", desc: "播放中三角会变这个两竖杠,点一下暂停。" },
{ icon: "StepBackwardFilled", name: "上一首", desc: "实心左箭头加竖线。" },
{ icon: "StepForwardFilled", name: "下一首", desc: "实心右箭头加竖线。" },
{ icon: "RetweetOutlined", name: "播放模式", desc: "循环/单曲/顺序,随机时会换成另一个交叉箭头。" },
{ icon: "UnorderedListOutlined", name: "播放列表", desc: "展开全部曲目,点哪首就播哪首。" },
{ icon: "InfoCircleOutlined", name: "歌曲信息", desc: "歌名右边的圆圈叹号。" },
{ icon: "HeartOutlined", name: "喜欢", desc: "空心变实心表示已收藏。" },
{ icon: "DownloadOutlined", name: "下载", desc: "下载这首歌,旁边的小标 ON/OFF 是下载状态。" },
{ icon: "AudioOutlined", name: "音量", desc: "喇叭图标,静音时变成带叉的喇叭。" },
{ icon: "FieldTimeOutlined", name: "定时关闭", desc: "时钟图标,到点自动停止播放。" },
{ icon: "EllipsisOutlined", name: "更多", desc: "竖着的三点,其余功能都收在这里。" },
{ icon: "DownOutlined", name: "收起播放器", desc: "左上角向下箭头,返回进入前的页面。" },
{ icon: "CloseOutlined", name: "关闭列表", desc: "关掉弹出的曲目列表。" },
],
};
/** 音频发布 */
const publishAudioOperation: HelpDoc = {
intro: "「音频发布」把本地音频整理成专辑并发布;发布后才能在这里收听。",
steps: [
{
title: "点「新增」建立专辑",
desc: "点新建文件图标进入可编辑状态,开始录入一个新专辑。",
icon: "FileAddOutlined",
},
{
title: "填写专辑信息",
desc: "最左边是耳机音符图标,代表整张专辑;右边填专辑名称、描述,编号由系统生成。",
icon: "CustomerServiceOutlined",
tips: "把同一主题或同一位歌手的音频放进一个专辑,收听时更方便。",
},
{
title: "上传音频并排序",
desc: "在明细区域逐个上传音频文件,用上下方块箭头调整曲目顺序。",
icon: "UploadOutlined",
tips: "音频文件通常较大,上传需要一点时间,请不要中途关闭页面。",
},
{
title: "点「保存」发布",
desc: "确认无误后点软盘图标保存;想放弃点回转箭头的取消。",
icon: "SaveOutlined",
},
{
title: "到音乐里试听核实",
desc: "发布完成后去音乐播放页确认能正常播放、曲目完整。",
icon: "CustomerServiceOutlined",
},
],
features: publishFeatures(audioHeroFeatures, audioExtraFeatures),
};
/** 音频查询 */
const publishAudioEnquiry: HelpDoc = {
intro: "「音频查询」列出自己发布过的全部专辑与音频,用于集中核对和管理。",
steps: [
{
title: "打开音频查询列表",
desc: "进入后表格列出全部已发布的音频 / 专辑记录。",
icon: "FileSearchOutlined",
},
{
title: "筛选出目标记录",
desc: "输入专辑编号点查询定位。",
},
{
title: "点右侧按钮处理",
desc: "操作列里的文档图标是查看、铅笔是修改、红色垃圾桶是删除。",
},
],
features: [
{ icon: "FileSearchOutlined", name: "查询", desc: "按编号或名称关键字筛选。" },
{ icon: "CustomerServiceOutlined", name: "音频 / 专辑列表", desc: "展示名称、编号、发布时间等信息。" },
{ icon: "FileTextOutlined", name: "查看", desc: "文档图标,打开这条记录的详情。" },
{ icon: "EditOutlined", name: "修改", desc: "铅笔图标,编辑这条专辑 / 音频。" },
{ icon: "DeleteOutlined", color: "red", name: "删除", desc: "移除后音乐里同步消失。" },
],
};
/* ==========================================================
* 视频
* ========================================================== */
/** 视频播放:VideoPlayer.vue */
const previewVideo: HelpDoc = {
intro: "「视频」用来观看已发布的视频:进入后直接播放,屏幕周围一圈按钮控制播放的各种设置。",
steps: [
{
title: "进入视频播放",
desc: "打开后进入播放界面,系统加载当前专辑里的视频内容。",
icon: "VideoCameraOutlined",
},
{
title: "控制播放",
desc: "画面下方一排:左边是播放模式,往右是上一集、播放/暂停、下一集、播放列表。",
icon: "CaretRightFilled",
tips: "视频文件较大,首次播放可能需要缓冲一会儿。",
},
{
title: "用右上方那排小按钮",
desc: "心形收藏、箭头下载、方框全屏、旋转、时钟定时、喇叭音量,最后的三点是全部其它功能。",
icon: "FullscreenOutlined",
},
{
title: "换下一个或直接离开",
desc: "点列表图标展开全部剧集挑一个;看完直接用浏览器返回即可。",
icon: "UnorderedListOutlined",
},
],
features: [
{ icon: "CaretRightFilled", name: "播放", desc: "实心三角,开始播放。" },
{ icon: "PauseOutlined", name: "暂停", desc: "播放中变成两竖杠,点一下停住。" },
{ icon: "StepBackwardFilled", name: "上一集", desc: "实心左箭头加竖线。" },
{ icon: "StepForwardFilled", name: "下一集", desc: "实心右箭头加竖线。" },
{ icon: "RetweetOutlined", name: "播放模式", desc: "循环/单曲,随机时换成交叉箭头。" },
{ icon: "UnorderedListOutlined", name: "播放列表", desc: "展开全部剧集,点哪个就看哪个。" },
{ icon: "FullscreenOutlined", name: "全屏", desc: "四角方框,放大到满屏。" },
{ icon: "FullscreenExitOutlined", name: "退出全屏", desc: "全屏时按钮会变成这个四角内缩。" },
{ icon: "HeartOutlined", name: "喜欢", desc: "空心收藏,点完变实心的爱心。" },
{ icon: "DownloadOutlined", name: "下载", desc: "下载这个视频,旁边小标显示 ON/OFF。" },
{ icon: "AudioOutlined", name: "音量", desc: "喇叭图标,静音时变成带叉的喇叭。" },
{ icon: "RotateRightOutlined", name: "旋转", desc: "向右旋转画面,横竖屏不对时用它。" },
{ icon: "FieldTimeOutlined", name: "定时关闭", desc: "时钟图标,到点自动停止。" },
{ icon: "EllipsisOutlined", name: "更多", desc: "竖着的三点,其余功能都收在这里。" },
{ icon: "CloseOutlined", name: "关闭列表", desc: "关掉弹出的剧集列表。" },
{ icon: "VideoCameraOutlined", name: "暂无视频", desc: "专辑里没有视频时显示这个摄像机图标。" },
],
};
/** 视频发布 */
const publishVideoOperation: HelpDoc = {
intro: "「视频发布」把本地视频整理成专辑并发布;发布后才能在这里观看。",
steps: [
{
title: "点「新增」建立专辑",
desc: "点新建文件图标进入可编辑状态,开始录入一个新视频专辑。",
icon: "FileAddOutlined",
},
{
title: "填写专辑信息",
desc: "最左边是摄像机图标,代表整张专辑;右边填专辑名称、描述,编号由系统生成。",
icon: "VideoCameraOutlined",
},
{
title: "上传视频并排序",
desc: "在明细区域逐个上传视频文件,用上下方块箭头调整播放顺序。",
icon: "UploadOutlined",
tips: "视频体积大,上传耗时较长,请保持页面打开直到进度完成。",
},
{
title: "点「保存」发布",
desc: "确认无误后点软盘图标保存;反悔点回转箭头的取消。",
icon: "SaveOutlined",
},
{
title: "到视频里试播核实",
desc: "发布完成后去视频播放页确认能正常观看、内容完整。",
icon: "VideoCameraOutlined",
},
],
features: publishFeatures(videoHeroFeatures),
};
/** 视频查询 */
const publishVideoEnquiry: HelpDoc = {
intro: "「视频查询」列出自己发布过的全部专辑与视频,用于集中核对和管理。",
steps: [
{
title: "打开视频查询列表",
desc: "进入后表格列出全部已发布的视频 / 专辑记录。",
icon: "FileSearchOutlined",
},
{
title: "筛选出目标记录",
desc: "输入专辑编号点查询定位。",
},
{
title: "点右侧按钮处理",
desc: "操作列里的文档图标是查看、铅笔是修改、红色垃圾桶是删除。",
},
],
features: [
{ icon: "FileSearchOutlined", name: "查询", desc: "按编号或名称关键字筛选。" },
{ icon: "VideoCameraOutlined", name: "视频 / 专辑列表", desc: "展示名称、编号、发布时间等信息。" },
{ icon: "FileTextOutlined", name: "查看", desc: "文档图标,打开这条记录的详情。" },
{ icon: "EditOutlined", name: "修改", desc: "铅笔图标,编辑这条专辑 / 视频。" },
{ icon: "DeleteOutlined", color: "red", name: "删除", desc: "移除后视频里同步消失。" },
],
};
/* ==========================================================
* 族谱
* ========================================================== */
/** 家庭成员录入:注意这一页顶部只有查询和重置,没有独立的「新增」按钮 */
const familyPersonOperation: HelpDoc = {
intro: "「家庭成员」录入与维护族谱里的每一位成员,是绘制族谱的基础数据。进入就是一张可直接填写的表。",
steps: [
{
title: "打开成员录入",
desc: "进入后顶部只有查询、重置两个按钮(放大镜和橡皮),没有单独的新增按钮:页面本身就可以直接填写。",
icon: "FileSearchOutlined",
tips: "想确认库里有没有这个人,先用查询查一下,避免重复录入。",
},
{
title: "先给成员配张头像",
desc: "点左边那个圆形头像;处于编辑状态时头像是被相机图标盖住,点它换本地照片。",
icon: "CameraOutlined",
},
{
title: "填写成员信息",
desc: "填写姓名、称谓、辈分等,带必填标记的项不能为空。",
tips: "录入越完整,后续绘制族谱时关系越准确。",
},
{
title: "点「保存」完成录入",
desc: "确认无误后点软盘图标保存;中途反悔点回转箭头的取消放弃这次编辑。",
icon: "SaveOutlined",
},
{
title: "后续修改或删除",
desc: "先查询找到该成员,再点铅笔图标修改,或点红色垃圾桶删除。",
tips: "已经挂到某个族谱下的成员不允许删除,需先把它从族谱中移除。",
},
],
features: [
{ icon: "FileSearchOutlined", name: "查询", desc: "放大镜图标,检索库里是否已有这位成员。" },
{ icon: "ClearOutlined", name: "重置", desc: "橡皮图标,清空表单回到空白状态。" },
{ icon: "UserOutlined", name: "成员头像", desc: "左边的圆形人头,还没传照片时显示的就是它。" },
{ icon: "CameraOutlined", name: "更换头像", desc: "编辑时盖在头像上的相机图标,点它上传本地照片。" },
{ icon: "SaveOutlined", name: "保存", desc: "软盘图标,确认写入本次录入或修改。" },
{ icon: "UndoOutlined", name: "取消", desc: "回转箭头,放弃本次编辑。" },
{ icon: "EditOutlined", name: "修改", desc: "铅笔图标,把已有成员变成可编辑状态。" },
{ icon: "DeleteOutlined", color: "red", name: "删除", desc: "红色垃圾桶,移除成员(挂在族谱上的不能删)。" },
],
};
/** 成员查询:同样没有「新增」按钮 */
const familyPersonEnquiry: HelpDoc = {
intro: "「成员查询」集中查看全部家庭成员,先从列表挑人,再做查看、修改或删除。",
steps: [
{
title: "打开成员列表",
desc: "进入后表格列出全部家庭成员及其主要信息。",
icon: "FileSearchOutlined",
},
{
title: "勾选一个人",
desc: "点左侧勾选框选中成员。注意查看和修改一次只能勾一个,勾多了按钮会变灰。",
tips: "本页没有新增按钮,要录入新成员请去「家庭成员」页面。",
},
{
title: "点下方的按钮处理",
desc: "文档图标查看详情、铅笔图标修改、红色垃圾桶删除(删除可以多选)。",
icon: "EditOutlined",
},
],
features: [
{ icon: "FileSearchOutlined", name: "查询", desc: "按姓名等关键字筛选。" },
{ icon: "UserOutlined", name: "成员列表", desc: "展示家庭成员的姓名、辈分等主要信息。" },
{ icon: "FileTextOutlined", name: "查看", desc: "文档图标,只能选一个人时可用。" },
{ icon: "EditOutlined", name: "修改", desc: "铅笔图标,只能选一个人时可用。" },
{ icon: "DeleteOutlined", color: "red", name: "删除", desc: "红色垃圾桶,可以勾选多人一起删。" },
],
};
/** 族谱制作 */
const familyTreeOperation: HelpDoc = {
intro: "「族谱」把已录入的家庭成员按亲属关系连成一张树状图,可以直观地看到整个家族的脉络。",
steps: [
{
title: "先确保成员已录入",
desc: "绘制族谱前,先在「家庭成员」里把需要出现在族谱上的人都录入好。",
icon: "UserOutlined",
tips: "成员资料越完整,生成的族谱越准确,建议先把成员录齐再来绘制。",
},
{
title: "点「新增」建立族谱",
desc: "顶部三个按钮依次是查询、重置、新增(新建文件图标),点新增开始绘制一张新族谱。",
icon: "FileAddOutlined",
},
{
title: "逐个添加亲属关系",
desc: "页面上每个成员后面都有「+ 夫妻关系」「+ 孩子关系」这样的虚线按钮,点加号方块逐步把人接上去。",
icon: "PlusSquareTwoTone",
},
{
title: "调整顺序与展示",
desc: "每位成员右侧的上/下方块调整排位;点中间的二叉树或类图腾看整张谱系图。",
icon: "ApartmentOutlined",
},
{
title: "点「保存」完成族谱",
desc: "确认布局与连线无误后点软盘图标保存;反悔点回转箭头的取消放弃本次修改。",
icon: "SaveOutlined",
},
],
features: [
...crudHeadFeatures,
{ icon: "ApartmentOutlined", name: "谱系图 / 祖谱系图", desc: "二叉树形状的图标,点它看整张家族树。" },
{ icon: "FileProtectOutlined", name: "申请管理", desc: "带盾牌的文档,申请成为这个族谱的管理员。" },
{ icon: "PlusSquareTwoTone", name: "新增夫妻 / 孩子关系", desc: "虚线按钮上的加号方块,用来接上亲属。" },
{ icon: "UpSquareTwoTone", name: "上移", desc: "调整这位成员在列表中的位置。" },
{ icon: "DownSquareTwoTone", name: "下移", desc: "与上移相反。" },
{ icon: "RightOutlined", name: "展开成员", desc: "向右的小箭头,展开这一层的成员列表。" },
{ icon: "CheckCircleTwoTone", name: "通过申请", desc: "勾形圆圈,批准别人的管理申请。" },
{ icon: "CrownOutlined", color: "#faad14", name: "设为管理员", desc: "金色皇冠,批准对方成为管理员。" },
{ icon: "CloseCircleOutlined", name: "拒绝申请", desc: "叉形圆圈,驳回管理申请。" },
{ icon: "EditOutlined", name: "修改", desc: "铅笔图标,重新绘制这张族谱。" },
{ icon: "SaveOutlined", name: "保存", desc: "软盘图标,确认本次改动。" },
{ icon: "UndoOutlined", name: "取消", desc: "回转箭头,放弃本次修改。" },
{ icon: "DeleteOutlined", color: "red", name: "删除", desc: "红色垃圾桶,移除整个族谱(成员档案不受影响)。" },
],
};
/** 族谱查询 */
const familyTreeEnquiry: HelpDoc = {
intro: "「族谱查询」列出全部已创建的族谱,选一张再做查看、修改或删除。",
steps: [
{
title: "打开族谱列表",
desc: "进入后表格列出全部族谱及其基本信息。",
icon: "FileSearchOutlined",
},
{
title: "点「新增」建新族谱",
desc: "右上角的控制区有一个新建文件图标,点了就去创建一张全新族谱。",
icon: "FileAddOutlined",
},
{
title: "勾选一张再操作",
desc: "查看和修改一次只能勾一张,多选时这两个按钮会变灰;删除则允许一次勾多张。",
tips: "双击某一行也会直接进入查看详情,比点按钮更快。",
},
{
title: "点下方按钮处理",
desc: "文档图标查看、铅笔图标修改、红色垃圾桶删除。",
icon: "EditOutlined",
},
],
features: [
{ icon: "FileAddOutlined", name: "新增", desc: "右上角的新建文件图标,创建一张新族谱。" },
{ icon: "ApartmentOutlined", name: "族谱列表", desc: "展示族谱名称、成员数等主要信息。" },
{ icon: "FileSearchOutlined", name: "查询", desc: "按族谱名称关键字筛选。" },
{ icon: "FileTextOutlined", name: "查看", desc: "文档图标,只能勾一张时可用。" },
{ icon: "EditOutlined", name: "修改", desc: "铅笔图标,只能勾一张时可用,进去继续绘制。" },
{ icon: "DeleteOutlined", color: "red", name: "删除", desc: "红色垃圾桶,可一次勾选多张删除。" },
],
};
/* ==========================================================
* 注册表与查询
* ========================================================== */
/** 未编写专属文档时的通用兜底说明,保证任何功能点开都有东西可看 */
export const fallbackDoc: HelpDoc = {
intro: "这里用时间轴的方式介绍该功能的操作流程,下方列出页面中各个按钮和图标的作用。",
steps: [
{
title: "先从入口进入功能页",
desc: "在首页对应的分组卡片里点击功能条目,即可打开这个功能页面。",
},
{
title: "看顶部的查询与底部的操作",
desc: "放大镜像家协会查询、橡皮是重置、新建文件是新增;下面依次是修改(铅笔)、保存(软盘)、取消(回转箭头)、删除(红色垃圾桶)。",
icon: "FileSearchOutlined",
},
{
title: "按需要填写并提交",
desc: "表单填完一定要点软盘图标保存,内容才真正写入;不想保留就点回转箭头取消。",
icon: "SaveOutlined",
tips: "录入或修改后一定要点保存,否则关掉页面就白填了。",
},
],
features: [
{ icon: "FileSearchOutlined", name: "查询", desc: "放大镜加文档,按关键字筛选。" },
{ icon: "ClearOutlined", name: "重置", desc: "橡皮擦,清空条件恢复完整列表。" },
{ icon: "FileAddOutlined", name: "新增", desc: "新建文件图标,录入一条新记录。" },
{ icon: "EditOutlined", name: "修改", desc: "铅笔图标,把已有记录改成可编辑。" },
{ icon: "SaveOutlined", name: "保存", desc: "软盘图标,确认并写入。" },
{ icon: "UndoOutlined", name: "取消", desc: "回转箭头,放弃本次编辑。" },
{ icon: "DeleteOutlined", color: "red", name: "删除", desc: "红色垃圾桶,移除选中的记录。" },
{ icon: "FileTextOutlined", name: "查看", desc: "文档图标,打开详情只读查看。" },
],
};
/**
* 功能英文名 → 帮助文档
*
* key 来自 SecurityFunctionDisplayData.FunctionName,
* 与仪表盘 DashboardGroupCard 卡片上的功能一一对应。
*/
export const HELP_DOCS: Record<string, HelpDoc> = {
/* 网盘 */
DmsFileEnquiry: dmsFileEnquiry,
DmsFileDeleteEnquiry: dmsFileDeleteEnquiry,
/* 共享中心 */
FamilyGroupShare: familyGroupShare,
FamilyShareOperation: familyShareOperation,
FamilyGroupOperation: familyGroupOperation,
FamilyGroupEnquiry: familyGroupEnquiry,
/* 相册 */
Preview: preview,
PublishPhotoOperation: publishPhotoOperation,
PublishPhotoEnquiry: publishPhotoEnquiry,
/* 音乐 */
PreviewAudio: previewAudio,
PublishAudioOperation: publishAudioOperation,
PublishAudioEnquiry: publishAudioEnquiry,
/* 视频 */
PreviewVideo: previewVideo,
PublishVideoOperation: publishVideoOperation,
PublishVideoEnquiry: publishVideoEnquiry,
/* 族谱 */
FamilyPersonOperation: familyPersonOperation,
FamilyPersonEnquiry: familyPersonEnquiry,
FamilyTreeOperation: familyTreeOperation,
FamilyTreeEnquiry: familyTreeEnquiry,
};
/**
* 取某个功能的帮助文档;没有登记过则返回通用兜底文档,
* 因此调用方永远拿得到一份可渲染的 HelpDoc。
*/
export const getHelpDoc = (functionName?: string): HelpDoc =>
(functionName && HELP_DOCS[functionName]) || fallbackDoc;
/** 该功能是否编写了专属帮助文档(false 表示拿到的是通用兜底) */
export const hasHelpDoc = (functionName?: string): boolean =>
!!functionName && !!HELP_DOCS[functionName];
+35 -4
View File
@@ -36,10 +36,12 @@
class="layout-main"
>
<a-layout-header class="layout-header">
<div class="layout-header-left" @click="onpush()">
<a-avatar shape="square" size="large" src="/youjia.svg" />
<a-page-header style="padding-left: 4px" :title="compnentTitle" />
</div>
<a-tooltip :title="t('layout.header.backToDashboard')" placement="bottomLeft">
<div class="layout-header-left" @click="onpush()">
<a-avatar shape="square" size="large" src="/youjia.svg" />
<a-page-header style="padding-left: 4px" :title="compnentTitle" />
</div>
</a-tooltip>
<a-menu
mode="horizontal"
v-model:selectedKeys="selectedHeaderKeys"
@@ -69,6 +71,17 @@
"
:title="titleHeader"
/>
<!-- 常驻可见的首页入口:手机端没有 hover,提示必须一直显示在那里才有用。
已经在首页时不显示,避免点了没反应。 -->
<a-button
v-if="!isWelcome"
type="link"
class="home-entry"
@click="onpush()"
>
<template #icon><DashboardOutlined /></template>
{{ t("layout.header.backToDashboard") }}
</a-button>
</div>
<div
class="layout-content-view"
@@ -113,6 +126,7 @@ import {
MenuUnfoldOutlined,
MenuFoldOutlined,
LayoutOutlined,
DashboardOutlined,
} from "@ant-design/icons-vue";
const collapsed = ref<boolean>(false);
import {
@@ -643,6 +657,13 @@ provide(layoutProviderMethodKey, {
display: flex;
align-items: center;
cursor: pointer;
border-radius: 8px;
transition: background-color 0.16s ease;
/* 悬停时给一点视觉反馈,配合光标让「这里可以点」更明显 */
&:hover {
background-color: #f0f7ff;
}
}
.ant-layout-header {
@@ -659,6 +680,16 @@ provide(layoutProviderMethodKey, {
justify-content: flex-start;
}
/* 返回首页入口:靠右摆放,避免和标题挤在一起;
父容器没设 align-items,这里单独居中,保证和标题在同一水平线上 */
.home-entry {
flex: none;
align-self: center;
margin-left: auto;
margin-right: 8px;
padding-inline: 4px;
}
.layout-page-header .ant-page-header-heading {
//background-color: silver;
padding: 0;
+2 -1
View File
@@ -5,7 +5,8 @@
"logout": "Exit System",
"message": "New Message(0)",
"amentPassword": "Ament Password",
"amentUserLocalName": "Ament Username"
"amentUserLocalName": "Ament Username",
"backToDashboard": "Back to Home"
},
"notification": {
"message": "System prompt",
+2 -1
View File
@@ -5,7 +5,8 @@
"createdtime": "登录时间:",
"dashboard": "欢迎页",
"logout": "退出系统",
"message": "新消息(0)"
"message": "新消息(0)",
"backToDashboard": "返回首页"
},
"layout": {
"header": {
@@ -0,0 +1,60 @@
import { request } from "@/utils/request";
import type { SecurityHelpFunctionEntity } from "@/data/auto/securityHelpFunctionEntity";
import type { SecurityHelpFunctionData } from "@/data/auto/securityHelpFunctionData";
class SecurityHelpFunctionService{
async FindByKey(data: string) {
return request<SecurityHelpFunctionEntity>(
{
url: "/SecurityHelpFunction/FindByKey?key="+data,
method: "post",
data,
}
)
};
async FindAll() {
return request<SecurityHelpFunctionData>(
{
url: "/SecurityHelpFunction/FindAll",
method: "post",
}
)
};
async Insert(data: SecurityHelpFunctionEntity) {
return request<SecurityHelpFunctionEntity>(
{
url: "/SecurityHelpFunction/Insert",
method: "post",
data,
}
)
};
async Update(data: SecurityHelpFunctionEntity) {
return request<SecurityHelpFunctionEntity>(
{
url: "/SecurityHelpFunction/Update",
method: "post",
data,
}
)
};
async Delete(data: string) {
return request<any>(
{
url: "/SecurityHelpFunction/Delete?key="+data,
method: "post",
data,
}
)
};
}
const securityHelpFunctionService= new SecurityHelpFunctionService();
export default securityHelpFunctionService;
+72 -6
View File
@@ -8,11 +8,16 @@
<div class="page-main ft-page">
<DashboardGroupCard v-for="grp in groups" :id="'grp-' + grp.key" :key="grp.key" :name="grp.name"
:color="grp.color" :soft="grp.soft" :icon="grp.icon" :layout="grp.layout" :cover="grp.cover"
:badge="grp.badge" :items="grp.items" @navigate="onpush" />
:badge="grp.badge" :items="grp.items" @navigate="onpush" @help="onHelp" />
<a-empty v-if="!groups.length && !loading" description="没有匹配的功能" />
</div>
<!-- 新手帮助:统一挂在页面上,由行尾图标触发,按 FunctionName 分发不同文档 -->
<HelpTimelineModal v-model:open="helpOpen" :function-name="helpTarget?.FunctionName"
:title="helpTarget?.FunctionLocalName || helpTarget?.FunctionName" :color="helpColor" :soft="helpSoft"
:icon="helpIcon" />
<!-- 底部快捷栏:与其它页面一致,固定在底部 -->
<div class="page-footer dash-footer">
<DashboardBottomNav :items="navItems" @jump="onNavClick" />
@@ -29,6 +34,7 @@ import type { SecurityFunctionDisplayData } from "@/data/auto/securityFunctionDi
import DashboardHero from "@/components/dashboard/DashboardHero.vue";
import DashboardGroupCard, { type GroupCardItem } from "@/components/dashboard/DashboardGroupCard.vue";
import DashboardBottomNav from "@/components/dashboard/DashboardBottomNav.vue";
import HelpTimelineModal from "@/components/basic/HelpTimelineModal.vue";
interface NavItem {
key: string;
@@ -94,7 +100,7 @@ const resolveGroup = (it: SecurityFunctionDisplayData): GroupKey =>
/* ==================== 自定义副标题 ==================== */
/** 留空时卡片会自动回退到 FunctionEngName */
const SUBTITLE_OF: Record<string, string> = {
DmsFileEnquiry: "上传、下载",
DmsFileEnquiry: "",
DmsFileDeleteEnquiry: "",
FamilyGroupShare: "",
FamilyShareOperation: "",
@@ -103,7 +109,7 @@ const SUBTITLE_OF: Record<string, string> = {
Preview: "",
PublishPhotoOperation: "",
PublishPhotoEnquiry: "",
PreviewAudio: "播放从默认专辑",
PreviewAudio: "",
PublishAudioOperation: "",
PublishAudioEnquiry: "",
PreviewVideo: "",
@@ -127,7 +133,7 @@ const groups = computed(() => {
const items: GroupCardItem[] = [];
for (const it of allItems.value) {
if (resolveGroup(it) !== g.key) continue;
const label = it.FunctionLocalName || it.FunctionName;
const label = it.FunctionLocalName || it.FunctionEngName;
if (taken.has(label)) continue;
taken.add(label);
items.push({ ...it, subtitle: resolveSubtitle(it) });
@@ -149,6 +155,36 @@ const navItems = computed<NavItem[]>(() =>
})
);
/**
* 按左侧菜单的顺序排列。
*
* Orderby 只在「同一个父节点下」才是连续有意义的序号,跨父组直接比大小会错:
* 某个父组(比如从「有家网盘」拆出来的组)内部可能从 0 重新计数,
* 它的子项就会被平铺排序甩到全局最前面。
*
* 所以这里先按父节点自身的序号把「组」排好,再在组内按 Orderby 排,
* 平铺出来的先后就和菜单的树形展开顺序一致。
*/
const sortByMenuOrder = (list: SecurityFunctionDisplayData[]): SecurityFunctionDisplayData[] => {
// 每个节点自己的序号,用作它作为「父」时的排序依据
const parentOrder = new Map<string, number>();
list.forEach((it) => {
if (it.FunctionName) parentOrder.set(it.FunctionName, it.Orderby ?? 0);
});
/** 有父节点就跟着父走,没有(顶层)就用自己的序号 */
const groupOrder = (it: SecurityFunctionDisplayData): number => {
if (it.FunctionNameParent && parentOrder.has(it.FunctionNameParent)) {
return parentOrder.get(it.FunctionNameParent)!;
}
return it.Orderby ?? 0;
};
return [...list].sort(
(a, b) => groupOrder(a) - groupOrder(b) || (a.Orderby ?? 0) - (b.Orderby ?? 0)
);
};
/* ==================== 交互 ==================== */
const onpush = (apiRoute: string) => {
if (apiRoute) router.push(apiRoute);
@@ -157,13 +193,43 @@ const onNavClick = (key: string) => {
document.getElementById("grp-" + key)?.scrollIntoView({ behavior: "smooth", block: "start" });
};
/* ==================== 新手帮助弹窗 ==================== */
const helpOpen = ref(false);
/** 当前请求帮助的功能项,决定 HelpTimelineModal 加载哪份文档 */
const helpTarget = ref<GroupCardItem | null>(null);
/** 帮助弹窗沿用所属分组的主题色,与卡片保持视觉一致 */
const helpTheme = computed(() => {
const key = helpTarget.value ? resolveGroup(helpTarget.value) : undefined;
return groupDefs.find(g => g.key === key) ?? groupDefs[groupDefs.length - 1];
});
const helpColor = computed(() => helpTheme.value.color);
const helpSoft = computed(() => helpTheme.value.soft);
const helpIcon = computed(() => helpTheme.value.icon);
const onHelp = (it: GroupCardItem) => {
helpTarget.value = it;
helpOpen.value = true;
};
onMounted(async () => {
loading.value = true;
try {
const fd = await securityUserService.FindMenuByUsername();
const raw = fd?.SecurityFunctionDisplayDatas ?? [];
allItems.value = raw.filter(
it => it.FunctionIndc !== "N" && (it.PageUrl?.indexOf("master") ?? -1) > 0
// 有些功能会挂在「不存在的父节点」下(例如测试残留的 abc),
// 它和正式记录同名却属于另一条,按 Orderby 排序时会窜到最前面,
// 表现为首页位置与左侧菜单对不上、改了后台顺序也不生效。
// 这里剔掉这类孤立记录,只保留父节点真实存在的。
const knownFunctions = new Set(raw.map(it => it.FunctionName));
allItems.value = sortByMenuOrder(
raw.filter(
it =>
it.FunctionIndc !== "N" &&
(it.PageUrl?.indexOf("master") ?? -1) > 0 &&
(!it.FunctionNameParent || knownFunctions.has(it.FunctionNameParent))
)
);
} finally {
loading.value = false;
@@ -99,6 +99,13 @@
<a-input size="large" placeholder="请输入页面名称" :readonly="!isEdit"
v-model:value="data.SecurityFunction.PageName" />
</div>
<!-- 备注:内容可能较长,占满整行显示 -->
<div class="ft-field ft-field-full">
<div class="ft-label">备注</div>
<a-textarea :auto-size="{ minRows: 3, maxRows: 10 }" :maxlength="1000"
placeholder="请输入备注" :readonly="!isEdit"
v-model:value="data.SecurityFunction.Remark" />
</div>
</div>
</div>