Commit 66cafb79 by wusiyi

feat: 帮助页内容新增

parent 23a91a5c
...@@ -1464,7 +1464,7 @@ ul li { ...@@ -1464,7 +1464,7 @@ ul li {
/* 菜单主题色 */ /* 菜单主题色 */
.el-menu { .el-menu {
background-color: var(--el-color-primary-light-9) !important; background-color: #fff !important;
} }
/* 评分主题色 */ /* 评分主题色 */
......
<template> <template>
<div <div
class="header bg-white sticky shadow-sm" class="header bg-white sticky"
:class="{ shadow: !$route.path.includes('help') }" :class="{ 'shadow-sm': !$route.path.includes('help') }"
ref="header"> ref="header">
<headHelper v-if="$route.path.includes('help')" /> <headHelper v-if="$route.path.includes('help')" />
<headerNavMobile v-else-if="$isMobile" :userInfo="userInfo" /> <headerNavMobile v-else-if="$isMobile" :userInfo="userInfo" />
......
...@@ -93,10 +93,11 @@ const routes = [ ...@@ -93,10 +93,11 @@ const routes = [
require(['../views/help/pages/index.vue'], resolve), require(['../views/help/pages/index.vue'], resolve),
}, },
{ {
path: 'beginner', path: 'picTutorial/:id',
name: 'HelpBeginner', name: 'PicTutorial',
component: (resolve) => component: (resolve) =>
require(['../views/help/pages/Beginner/beginner.vue'], resolve), require(['../views/help/components/picTutorial.vue'], resolve),
props: true,
}, },
{ {
path: 'artical1', path: 'artical1',
......
<template>
<div>
<el-submenu
v-if="menuItem.children && menuItem.children.length > 0"
:index="String(menuItem.id)">
<template slot="title">
<span>{{ menuItem.name }}</span>
</template>
<menu-item
v-for="child in menuItem.children"
:key="child.id"
:menu-item="child" />
</el-submenu>
<el-menu-item
v-else
:index="
menuItem.url
? '/help/' + menuItem.path + '/' + menuItem.url
: '/help/' + menuItem.path
"
@click="handleMenuItemClick">
<span>{{ menuItem.name }}</span>
</el-menu-item>
</div>
</template>
<script>
import { menuList } from '../menuConfig'
export default {
name: 'MenuItem',
props: {
menuItem: {
type: Object,
required: true,
},
},
methods: {
handleMenuItemClick() {
if (this.menuItem.link) {
this.$router.push({
path: `/help/${this.menuItem.path}/${this.menuItem.url}`,
query: { url: this.menuItem.link },
})
}
const id = [...String(this.menuItem.id)].map(Number)
const result = []
let fullPath = ''
let current = menuList
id.forEach((index, i) => {
current = current?.[index - 1] || current?.children?.[index - 1]
if (i === id.length - 1 && current.url) {
fullPath = current.url
}
result.push({ name: current.name, path: fullPath || 'index' })
})
this.$store.dispatch('path/setCurrentPathNames', result)
},
},
}
</script>
<template> <template>
<div> <div>
<el-breadcrumb separator-class="el-icon-arrow-right"> <el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item <el-breadcrumb-item v-for="(item, index) in breadList" :key="item.id">
v-for="(item, index) in breadList" <a
:key="item.path" v-if="index === 0"
@click.native="handleBreadClick(index)"> href="javascript:void(0)"
<a href="javascript:void(0)">{{ item.name }}</a> @click="handleBreadClick(index)"
:class="{ 'breadcrumb-clickable': true }">
{{ item.name }}
</a>
<span v-else class="breadcrumb-disabled">{{ item.name }}</span>
</el-breadcrumb-item> </el-breadcrumb-item>
</el-breadcrumb> </el-breadcrumb>
</div> </div>
...@@ -15,7 +19,6 @@ export default { ...@@ -15,7 +19,6 @@ export default {
name: 'Bread', name: 'Bread',
computed: { computed: {
breadList() { breadList() {
// currentPathNames 已经包含了帮助中心作为第一项
return this.$store.getters['path/currentPathNames'] || [] return this.$store.getters['path/currentPathNames'] || []
}, },
}, },
...@@ -27,9 +30,31 @@ export default { ...@@ -27,9 +30,31 @@ export default {
const clickedItem = currentPathNames[index] const clickedItem = currentPathNames[index]
const newPathNames = currentPathNames.slice(0, index + 1) const newPathNames = currentPathNames.slice(0, index + 1)
this.$store.dispatch('path/setCurrentPathNames', newPathNames) this.$store.dispatch('path/setCurrentPathNames', newPathNames)
this.$router.push(`/help/${clickedItem.path}`)
// 如果是帮助中心,跳转到 /help/index
if (index === 0) {
this.$router.push('/help/index')
} else {
this.$router.push(`/help/${clickedItem.path}`)
}
} }
}, },
}, },
} }
</script> </script>
<style scoped>
.breadcrumb-clickable {
color: var(--primary-color);
cursor: pointer;
text-decoration: none;
}
.breadcrumb-clickable:hover {
color: var(--el-color-primary-light-4);
}
.breadcrumb-disabled {
color: #606266;
cursor: default;
}
</style>
...@@ -92,15 +92,13 @@ export default { ...@@ -92,15 +92,13 @@ export default {
this.$router.push(content.url) this.$router.push(content.url)
}, },
goToMore(tab) { goToMore() {
const breadcrumbPath = [ // const breadcrumbPath = [
{ name: '帮助中心', path: 'index' }, // { name: '帮助中心', path: 'index' },
{ name: tab.title, path: tab.url }, // { name: tab.title, path: tab.url },
] // ]
// this.$store.dispatch('path/setCurrentPathNames', breadcrumbPath)
this.$store.dispatch('path/setCurrentPathNames', breadcrumbPath) // this.$router.push(`/help/${tab.url}`)
this.$router.push(`/help/${tab.url}`)
}, },
}, },
} }
......
<template>
<div style="height: 80vh">
<iframe :key="link" class="w-full h-full" frameborder="0" :src="link" />
</div>
</template>
<script>
import { FEISHU_BASE_URL } from '../menuConfig.js'
export default {
name: 'PicTutorial',
props: {
id: {
type: [String, Number],
required: true,
},
},
data() {
return {
isLoading: true,
}
},
computed: {
link() {
const anchor = this.$route.query.url || ''
if (!anchor) return ''
if (this.$route.name === 'PicTutorial') {
return FEISHU_BASE_URL + anchor
}
return ''
},
},
watch: {},
methods: {},
}
</script>
<style scoped></style>
<template> <template>
<div> <div>
<div class="top flex flex-col items-center py-16"> <div
v-if="$route.path === '/help/index'"
class="top flex flex-col items-center py-6">
<div class="text-gray-700 text-4xl font-bold">帮助中心</div> <div class="text-gray-700 text-4xl font-bold">帮助中心</div>
<el-input <el-input
v-model="keyword" v-model="keyword"
...@@ -13,7 +15,8 @@ ...@@ -13,7 +15,8 @@
<div class="content p-5"> <div class="content p-5">
<sideNav /> <sideNav />
<div <div
class="right-content w-full h-full p-5" class="right-content w-full p-5"
style="height: 90vh"
:class="{ 'rounded-md bg-white': $route.path !== '/help/index' }"> :class="{ 'rounded-md bg-white': $route.path !== '/help/index' }">
<Bread v-if="$route.path !== '/help/index'" /> <Bread v-if="$route.path !== '/help/index'" />
<router-view></router-view> <router-view></router-view>
......
<template>
<div class="w-full h-full bg-white rounded-md">
<div class="text-xl font-bold my-10">{{ title }}</div>
<div class="content">
<a
v-for="(t, index) in titles"
:key="t"
class="content-title text-gray-600 ml-8 block mb-3 pb-3 border-b border-gray-200"
@click="goArtical(t, index)"
:href="`/help/artical${index + 1}`">
{{ t }}
</a>
</div>
</div>
</template>
<script>
export default {
components: {},
data() {
return {
title: '',
titles: [],
}
},
created() {
const currentPathNames = this.$store.getters['path/currentPathNames']
this.title = currentPathNames[currentPathNames.length - 1].name
try {
const ctx = require.context('./', false, /\.vue$/)
ctx.keys().forEach((key) => {
if (/beginner\.vue$/i.test(key)) return
const mod = ctx(key)
const comp = mod && (mod.default || mod)
if (comp && typeof comp.data === 'function') {
const dataObj = comp.data.call({}) || {}
if (dataObj.title) {
this.titles.push(dataObj.title)
}
}
})
} catch (e) {
// ignore
}
},
methods: {
goArtical(title, index) {
// 调用 vuex action 添加文章路径
this.$store.dispatch('path/addArticlePath', { title, index })
},
},
}
</script>
<style scoped lang="scss">
.content-title {
position: relative;
transition: all 0.2s ease;
&::before {
content: '';
display: block;
width: 6px;
height: 6px;
border-radius: 50%;
position: absolute;
left: -23px;
top: 10px;
background-color: var(--primary-color);
box-shadow: 0 0 0 5px #e6c07977;
}
&:hover {
color: var(--primary-color);
}
}
</style>
<template> <template>
<div class="side-nav mr-5 rounded-md"> <div class="side-nav mr-5 rounded-md overflow-scroll">
<el-input <el-input
class="mt-3 ml-5 w-4/5 mb-5" class="mt-3 ml-5 w-4/5 mb-5"
v-model="searchKeyword" v-model="searchKeyword"
placeholder="在目录中搜索..."></el-input> placeholder="在目录中搜索..."></el-input>
<el-menu <el-menu
@select="handleSelect" :key="menuKey"
router
:unique-opened="true" :unique-opened="true"
:default-active="activeMenu"> :default-active="$route.path"
<span v-for="item in menuList" :key="item.path"> :default-openeds="openedMenus">
<el-submenu <menu-item v-for="item in menuList" :key="item.id" :menu-item="item" />
v-if="item.children && item.children.length > 0"
:index="item.path">
<template slot="title">
<span>{{ item.name }}</span>
</template>
<el-menu-item
v-for="child in item.children"
:key="child.path"
:index="child.path">
<span>{{ child.name }}</span>
</el-menu-item>
</el-submenu>
<el-menu-item v-else :key="item.path" :index="item.path">
<span>{{ item.name }}</span>
</el-menu-item>
</span>
</el-menu> </el-menu>
</div> </div>
</template> </template>
<script> <script>
import MenuItem from './components/MenuItem.vue'
import { menuList } from './menuConfig.js'
export default { export default {
name: 'sideNav', name: 'sideNav',
components: {
MenuItem,
},
data() { data() {
return { return {
searchKeyword: '', searchKeyword: '',
activeMenu: '', menuList,
menuList: [ menuKey: 0,
{
id: 1,
path: 'mustSee',
name: '入门必看',
children: [{ id: 11, path: 'beginner', name: '新手入门' }],
},
{
id: 2,
path: 'pic',
name: '图文教程',
children: [{ id: 21, path: 'base', name: '基础数据维护' }],
},
{ id: 3, path: 'video', name: '视频教程' },
// { id: 4, path: 'problem', name: '常见问题' },
// { id: 5, path: 'contact', name: '联系我们' },
],
} }
}, },
mounted() {
this.syncMenuWithRoute()
},
watch: { watch: {
$route() { '$route.path'() {
this.syncMenuWithRoute() this.$nextTick(() => {
this.menuKey += 1
})
}, },
}, },
methods: { computed: {
syncMenuWithRoute() { // 需要展开的父级菜单
const path = this.$route && this.$route.path ? this.$route.path : '' openedMenus() {
const match = path.match(/^\/help\/([^/]+)/) const id = this.$route.path.split('/').pop()
const currentKey = match ? match[1] : '' const result = Array.from(id).map((_, i) => id.slice(0, i + 1))
return result
this.activeMenu = currentKey
},
handleSelect(key, keyPath) {
if (key === this.activeMenu) return
const names = []
for (const item of this.menuList) {
if (item.path === keyPath[0]) {
names.push({ name: item.name, path: item.path })
if (keyPath[1] && Array.isArray(item.children)) {
for (const child of item.children) {
if (child.path === keyPath[1]) {
names.push({ name: child.name, path: child.path })
break
}
}
}
break
}
}
// 使用 vuex 保存路径名称
this.$store.dispatch('path/setCurrentPathNames', names)
const target = keyPath[1] || keyPath[0]
this.$router.push(`/help/${target}`)
}, },
}, },
} }
...@@ -102,8 +50,8 @@ export default { ...@@ -102,8 +50,8 @@ export default {
<style scoped lang="scss"> <style scoped lang="scss">
.side-nav { .side-nav {
background-color: #ffffff; background-color: #ffffff;
height: 100%; height: 90vh;
width: 13%; width: 15%;
} }
::v-deep .el-input--mini .el-input__inner { ::v-deep .el-input--mini .el-input__inner {
background-color: var(--background-color); background-color: var(--background-color);
......
...@@ -413,7 +413,7 @@ ...@@ -413,7 +413,7 @@
<!-- 九猫物流 --> <!-- 九猫物流 -->
<div <div
v-else-if="activeTab === 'logistics'" v-else-if="activeTab === 'logistics'"
class="flex items-center justify-center bg-white lg:p-10 py-5 lg:w-3/5 w-full"> class="flex items-center justify-center bg-white lg:p-10 py-5 lg:w-3/5 w-full m-auto">
<img <img
class="erp-image" class="erp-image"
src="../../assets/images/product/logistic/01.png" src="../../assets/images/product/logistic/01.png"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment