修改部分样式
This commit is contained in:
@@ -5,16 +5,57 @@
|
||||
<view class="page-layer"><PageHeader title="帮助中心" /></view>
|
||||
<view class="page-content page-layer">
|
||||
<text class="help-source-note">{{ sourceNote }}</text>
|
||||
<view class="search-box"><input v-model.trim="keyword" aria-label="搜索帮助" placeholder="搜索问题关键词" /><text>{{ filteredQuestions.length }} 条</text></view>
|
||||
<scroll-view scroll-x class="category-scroll" :show-scrollbar="false"><view class="category-row"><view v-for="category in helpCategories" :key="category.value" class="category-chip" :class="{ active: activeCategory === category.value }" role="button" @click="activeCategory = category.value">{{ category.label }}</view></view></scroll-view>
|
||||
<view class="search-box"
|
||||
><input
|
||||
v-model.trim="keyword"
|
||||
aria-label="搜索帮助"
|
||||
placeholder="搜索问题关键词"
|
||||
/><text>{{ filteredQuestions.length }} 条</text></view
|
||||
>
|
||||
<scroll-view scroll-x class="category-scroll" :show-scrollbar="false"
|
||||
><view class="category-row"
|
||||
><view
|
||||
v-for="category in helpCategories"
|
||||
:key="category.value"
|
||||
class="category-chip"
|
||||
:class="{ active: activeCategory === category.value }"
|
||||
role="button"
|
||||
@click="activeCategory = category.value"
|
||||
>{{ category.label }}</view
|
||||
></view
|
||||
></scroll-view
|
||||
>
|
||||
<view v-if="filteredQuestions.length" class="question-list">
|
||||
<view v-for="item in filteredQuestions" :key="item.id" class="question-card">
|
||||
<view class="question-heading" role="button" :aria-label="item.question" @click="toggleQuestion(item.id)"><text>{{ item.question }}</text><text>{{ expandedIds.includes(item.id) ? "收起" : "查看" }}</text></view>
|
||||
<text v-if="expandedIds.includes(item.id)" class="answer">{{ item.answer }}</text>
|
||||
<view
|
||||
v-for="item in filteredQuestions"
|
||||
:key="item.id"
|
||||
class="question-card"
|
||||
>
|
||||
<view
|
||||
class="question-heading"
|
||||
role="button"
|
||||
:aria-label="item.question"
|
||||
@click="toggleQuestion(item.id)"
|
||||
><text>{{ item.question }}</text
|
||||
><text>{{
|
||||
expandedIds.includes(item.id) ? "收起" : "查看"
|
||||
}}</text></view
|
||||
>
|
||||
<text v-if="expandedIds.includes(item.id)" class="answer">{{
|
||||
item.answer
|
||||
}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else class="empty-card"><text>没有找到相关问题</text><text>换个关键词试试,或直接提交意见反馈。</text></view>
|
||||
<AppButton block type="secondary" label="联系家谱助手" @click="contactSupport" />
|
||||
<view v-else class="empty-card"
|
||||
><text>没有找到相关问题</text
|
||||
><text>换个关键词试试,或直接提交意见反馈。</text></view
|
||||
>
|
||||
<AppButton
|
||||
block
|
||||
type="secondary"
|
||||
label="联系家谱助手"
|
||||
@click="contactSupport"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -25,39 +66,71 @@ import { onLoad, onShow, onUnload } from "@dcloudio/uni-app";
|
||||
import AppButton from "@/components/AppButton.vue";
|
||||
import ModulePageBackground from "@/components/ModulePageBackground.vue";
|
||||
import PageHeader from "@/components/PageHeader.vue";
|
||||
import { appApi, createRequestController, isRequestCancelled } from "@/utils/api.js";
|
||||
import {
|
||||
appApi,
|
||||
createRequestController,
|
||||
isRequestCancelled,
|
||||
} from "@/utils/api.js";
|
||||
import { openPage } from "@/utils/navigation.js";
|
||||
|
||||
const questions = ref([]);
|
||||
const helpState = ref("loading");
|
||||
const controller = createRequestController();
|
||||
let active = true;
|
||||
const categoryLabels = Object.freeze({ common: "常见问题", member: "成员管理", lineage: "世系关系" });
|
||||
const categoryLabels = Object.freeze({
|
||||
common: "常见问题",
|
||||
member: "成员管理",
|
||||
lineage: "世系关系",
|
||||
});
|
||||
const helpCategories = computed(() => [
|
||||
{ value: "", label: "全部" },
|
||||
...[...new Set(questions.value.map((item) => item.category).filter(Boolean))].map((value) => ({ value, label: categoryLabels[value.toLowerCase()] || value })),
|
||||
...[
|
||||
...new Set(questions.value.map((item) => item.category).filter(Boolean)),
|
||||
].map((value) => ({
|
||||
value,
|
||||
label: categoryLabels[value.toLowerCase()] || value,
|
||||
})),
|
||||
]);
|
||||
const activeCategory = ref("");
|
||||
const keyword = ref("");
|
||||
const expandedIds = ref([]);
|
||||
const sourceNote = computed(() => ({ loading: "正在读取帮助文章…", error: "帮助文章暂时无法读取,请稍后重试。", empty: "暂未收到可展示的帮助文章。", ready: "帮助内容来自服务端,可按分类或关键词查找。" })[helpState.value]);
|
||||
const sourceNote = computed(
|
||||
() =>
|
||||
({
|
||||
loading: "正在读取帮助文章…",
|
||||
error: "帮助文章暂时无法读取,请稍后重试。",
|
||||
empty: "暂未收到可展示的帮助文章。",
|
||||
ready: "帮助内容来自服务端,可按分类或关键词查找。",
|
||||
})[helpState.value],
|
||||
);
|
||||
const filteredQuestions = computed(() => {
|
||||
const query = keyword.value.toLowerCase();
|
||||
return questions.value.filter((item) => (!activeCategory.value || item.category === activeCategory.value) && (!query || `${item.question}${item.answer}`.toLowerCase().includes(query)));
|
||||
return questions.value.filter(
|
||||
(item) =>
|
||||
(!activeCategory.value || item.category === activeCategory.value) &&
|
||||
(!query ||
|
||||
`${item.question}${item.answer}`.toLowerCase().includes(query)),
|
||||
);
|
||||
});
|
||||
const toggleQuestion = (id) => { expandedIds.value = expandedIds.value.includes(id) ? expandedIds.value.filter((item) => item !== id) : [...expandedIds.value, id]; };
|
||||
const toggleQuestion = (id) => {
|
||||
expandedIds.value = expandedIds.value.includes(id)
|
||||
? expandedIds.value.filter((item) => item !== id)
|
||||
: [...expandedIds.value, id];
|
||||
};
|
||||
const contactSupport = () => openPage("M07", {}, "M06");
|
||||
const loadHelpArticles = async () => {
|
||||
controller.abort();
|
||||
helpState.value = "loading";
|
||||
try {
|
||||
const rows = await appApi.getHelpArticles({ requestController: controller });
|
||||
const rows = await appApi.getHelpArticles({
|
||||
requestController: controller,
|
||||
});
|
||||
if (!active) return;
|
||||
questions.value = rows.map((item) => ({
|
||||
id: String(item.helpId),
|
||||
category: String(item.helpCategory || "其他"),
|
||||
question: String(item.helpTitle || "未命名帮助文章"),
|
||||
answer: String(item.helpContent || "暂无正文")
|
||||
answer: String(item.helpContent || "暂无正文"),
|
||||
}));
|
||||
helpState.value = questions.value.length ? "ready" : "empty";
|
||||
} catch (error) {
|
||||
@@ -66,11 +139,149 @@ const loadHelpArticles = async () => {
|
||||
}
|
||||
};
|
||||
onLoad(loadHelpArticles);
|
||||
onShow(() => { if (helpState.value !== "loading") loadHelpArticles(); });
|
||||
onUnload(() => { active = false; controller.abort(); });
|
||||
onShow(() => {
|
||||
if (helpState.value !== "loading") loadHelpArticles();
|
||||
});
|
||||
onUnload(() => {
|
||||
active = false;
|
||||
controller.abort();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use "../../styles/adaptive-frame-profiles.scss" as adaptive;
|
||||
.help-page{display:flex;min-height:100vh;flex-direction:column;background:$paper}.page-layer{z-index:1}.page-content{flex:1;padding:24rpx 28rpx 72rpx}.help-source-note{display:block;margin:0 4rpx 16rpx;color:$ink-muted;font-size:21rpx;line-height:1.55}.search-box{@include adaptive.adaptive-profile-field;display:grid;grid-template-columns:minmax(0,1fr) auto;min-height:86rpx;align-items:center;gap:16rpx;padding:0 30rpx}.search-box input{width:auto;min-width:0;min-height:68rpx;color:$ink;font-size:23rpx}.search-box text{color:$ink-muted;font-size:20rpx}.category-scroll{width:100%;margin-top:18rpx}.category-row{display:flex;width:max-content;gap:12rpx;padding:2rpx}.category-chip{display:flex;min-width:100rpx;min-height:64rpx;align-items:center;justify-content:center;padding:0 22rpx;box-sizing:border-box;color:$ink-muted;font-size:22rpx}.category-chip.active{@include adaptive.adaptive-scroll-button(secondary);color:$brand-red;font-weight:700}.question-list{display:flex;flex-direction:column;gap:14rpx;margin-top:18rpx}.question-card,.empty-card{@include adaptive.adaptive-profile-content}.question-card{min-height:104rpx;padding:24rpx 34rpx}.question-heading{display:grid;grid-template-columns:minmax(0,1fr) auto;min-height:58rpx;align-items:center;gap:18rpx}.question-heading text:first-child{color:$ink;font-size:24rpx;font-weight:700;overflow-wrap:anywhere}.question-heading text:last-child{color:$brand-red;font-size:20rpx}.answer{display:block;padding:14rpx 4rpx 6rpx;border-top:1px solid rgba(181,137,63,.32);color:$ink-muted;font-size:22rpx;line-height:1.65;overflow-wrap:anywhere}.empty-card{min-height:220rpx;padding:58rpx 44rpx;text-align:center}.empty-card text{display:block}.empty-card text:first-child{color:$ink;font-size:29rpx;font-weight:700}.empty-card text:last-child{margin-top:12rpx;color:$ink-muted;font-size:22rpx;line-height:1.5}.page-content>.app-button{margin-top:28rpx}@media(max-width:340px){.page-content{padding-right:20rpx;padding-left:20rpx}}
|
||||
.help-page {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
flex-direction: column;
|
||||
background: $paper;
|
||||
}
|
||||
.page-layer {
|
||||
z-index: 1;
|
||||
}
|
||||
.page-content {
|
||||
flex: 1;
|
||||
padding: 24rpx 28rpx 72rpx;
|
||||
}
|
||||
.help-source-note {
|
||||
display: block;
|
||||
margin: 0 4rpx 16rpx;
|
||||
color: $ink-muted;
|
||||
font-size: 21rpx;
|
||||
line-height: 1.55;
|
||||
}
|
||||
.search-box {
|
||||
@include adaptive.adaptive-profile-field;
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
min-height: 86rpx;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
.search-box input {
|
||||
width: auto;
|
||||
min-width: 0;
|
||||
min-height: 68rpx;
|
||||
color: $ink;
|
||||
font-size: 23rpx;
|
||||
}
|
||||
.search-box text {
|
||||
color: $ink-muted;
|
||||
font-size: 20rpx;
|
||||
}
|
||||
.category-scroll {
|
||||
width: 100%;
|
||||
margin-top: 18rpx;
|
||||
}
|
||||
.category-row {
|
||||
display: flex;
|
||||
width: max-content;
|
||||
gap: 12rpx;
|
||||
padding: 2rpx;
|
||||
}
|
||||
.category-chip {
|
||||
display: flex;
|
||||
min-width: 100rpx;
|
||||
min-height: 64rpx;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 22rpx;
|
||||
box-sizing: border-box;
|
||||
color: $ink-muted;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
.category-chip.active {
|
||||
@include adaptive.adaptive-scroll-button(secondary);
|
||||
color: $brand-red;
|
||||
font-weight: 700;
|
||||
}
|
||||
.question-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14rpx;
|
||||
margin-top: 18rpx;
|
||||
}
|
||||
.question-card,
|
||||
.empty-card {
|
||||
@include adaptive.adaptive-profile-content;
|
||||
}
|
||||
.question-card {
|
||||
min-height: 104rpx;
|
||||
padding: 24rpx 34rpx;
|
||||
}
|
||||
.question-heading {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
min-height: 58rpx;
|
||||
align-items: center;
|
||||
gap: 18rpx;
|
||||
}
|
||||
.question-heading text:first-child {
|
||||
color: $ink;
|
||||
font-size: 24rpx;
|
||||
font-weight: 700;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.question-heading text:last-child {
|
||||
color: $brand-red;
|
||||
font-size: 20rpx;
|
||||
}
|
||||
.answer {
|
||||
display: block;
|
||||
padding: 14rpx 4rpx 6rpx;
|
||||
border-top: 1px solid rgba(181, 137, 63, 0.32);
|
||||
color: $ink-muted;
|
||||
font-size: 22rpx;
|
||||
line-height: 1.65;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
.empty-card {
|
||||
min-height: 220rpx;
|
||||
padding: 58rpx 44rpx;
|
||||
text-align: center;
|
||||
}
|
||||
.empty-card text {
|
||||
display: block;
|
||||
}
|
||||
.empty-card text:first-child {
|
||||
color: $ink;
|
||||
font-size: 29rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
.empty-card text:last-child {
|
||||
margin-top: 12rpx;
|
||||
color: $ink-muted;
|
||||
font-size: 22rpx;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.page-content > .app-button {
|
||||
margin-top: 28rpx;
|
||||
}
|
||||
@media (max-width: 340px) {
|
||||
.page-content {
|
||||
padding-right: 20rpx;
|
||||
padding-left: 20rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user