feat(service): 重构服务列表页面

- 更新服务列表获取逻辑,使用新的 API 接口
- 优化服务列表渲染逻辑,支持动态加载
This commit is contained in:
huangze
2025-07-03 14:45:36 +08:00
parent ce9b94ffd8
commit 88361595e8
12 changed files with 199 additions and 98 deletions

2
.env
View File

@@ -3,4 +3,4 @@ NODE_ENV = 'dev' // 如果是生产环境请记得切换为production
# flag
VUE_APP_FLAG='dev'
VUE_APP_ADMIN='http://localhost:7100'
VUE_APP_ADMIN='http://127.0.0.1:7100'

View File

@@ -4,3 +4,4 @@ NODE_ENV = 'dev' // 如果是生产环境请记得切换为production
# flag
VUE_APP_FLAG='dev'
VUE_APP_ADMIN='http://127.0.0.1:7100'
# VUE_APP_ADMIN='/api'

View File

@@ -4,7 +4,7 @@ import getUrl from '@/assets/js/utils/get-url'
// 获取服务列表
export function fetchServiceList(data) {
return request({
url: getUrl('/sysUserEx/redirectlogin'),
url: getUrl('/sysMenuEx/getTreeMenu'),
method: 'post',
data: data
})

View File

@@ -0,0 +1,17 @@
const ecosystemMap = {
'1': 'health-management',
'28': 'elderly-service',
'38': 'child-education',
'48': 'wealth-management',
'55': 'life-entertainment'
}
// 根据 ecosystemMap 获取对应的 ecosystem
export function getEcosystem(ecosystem) {
return ecosystemMap[ecosystem]
}
// 根据 value 获取对应的 ecosystem
export function getEcosystemByValue(value) {
return Object.keys(ecosystemMap).find(key => ecosystemMap[key] === value)
}

View File

@@ -3,6 +3,7 @@ import config from '@/config'
export default function getUrl(url, domainType = 'admin') {
let domain = process.env.VUE_APP_ADMIN || ''
// domain = "/api"s
// if (domainType === 'admin') {
// domain = config.admin
// }

View File

@@ -1,6 +1,6 @@
import axios from 'axios'
import { Dialog, Toast } from 'vant'
import { getToken, hasLogin } from './user-login'
import { getToken, hasLogin } from './user-login'
// 创建axios实例
const service = axios.create({
@@ -10,7 +10,7 @@ const service = axios.create({
service.interceptors.request.use(
async config => {
Toast.loading()
!hasLogin() && (config.headers['sid'] = await getToken())
config.headers['sid'] = await getToken()
return config
},
error => {
@@ -28,7 +28,7 @@ service.interceptors.response.use(
if (typeof res.sts !== 'undefined') {
return res
}
if (res.code === '000' || res.code === '999') {
if (Number(res.code) === 0 || res.code === '999') {
return res
}
console.log('response', res)

View File

@@ -1,12 +1,13 @@
import { ref } from 'vue'
import { fetchServiceList as fetchList } from '../../api/service-list'
export function fetchServiceList() {
export function fetchServiceList(menuCode) {
const list = ref()
fetchList().then(res => {
debugger
list.value = res
fetchList({
menuCode: menuCode
}).then(res => {
const { content } = res.content
list.value = content
})
return { list }
}

View File

@@ -139,28 +139,20 @@ const vm = new Vue({
}).$mount('#app')
window.page = vm
!hasLogin() &&
fetchToken({
apikey: 'a6sdngp99fd0zokkddusob7dd58e6f',
customerNo: '12',
id: '',
name: 'test-user',
openid: '12',
sex: '1',
status: 0,
type: '1'
})
.then(res => {
const { content } = res.contents
const token = getParamsFromUrl(content).get('token')
console.log(token, 'token')
// fetchToken({
// apikey: 'a6sdngp99fd0zokkddusob7dd58e6f',
// customerNo: '12',
// id: '',
// name: 'test-user',
// openid: '12',
// sex: '1',
// status: 0,
// type: '1'
// }).then(res => {
// const { content } = res.contents
// debugger
// const token = getParamsFromUrl(content).get('token')
// console.log(token, 'token')
globalThis.localStorage.setItem('token', token)
})
.catch(err => {
const { content } = err.content
const token = getParamsFromUrl(content).get('token')
console.log(token, 'token')
globalThis.localStorage.setItem('token', token)
})
// globalThis.localStorage.setItem('token', token)
// })

View File

@@ -40,14 +40,14 @@ export default [
}
},
{
path: '/service',
path: '/service/:ecosystem',
component: () => import('@/views/service/service-t.vue'),
meta: {
title: '健康管理'
}
},
{
path: '/service-info/:id/:type',
path: '/service-info/:ecosystem/:id/:type',
name: 'service-info',
component: () => import('@/views/service/views/service-info.vue'),
meta: {

View File

@@ -2,6 +2,7 @@
import { Image as VanImage, Icon } from 'vant';
import { title as _title } from './hooks/home';
import Swiper from './components/swiper/swiper.vue';
import { getEcosystem } from '@/assets/js/utils/ecosystem'
export default {
name: "home",
@@ -24,6 +25,19 @@ export default {
titleSrc: "http://ncc.ebiz-digits.com:39527/gsc/IHRHN5/7b/04/63/7b0463aa135f4a1f922b5171bcec1d14/images/主页/u26.png",
bannerSrc: "http://ncc.ebiz-digits.com:39527/gsc/IHRHN5/7b/04/63/7b0463aa135f4a1f922b5171bcec1d14/images/主页/u44.svg",
}
},
methods: {
goEcosystem(ecosystem, swe) {
this.$router.push({
path: '/service/:ecosystem',
params: {
ecosystem: ecosystem
},
query: {
swe: swe
}
})
}
}
}
</script>
@@ -55,16 +69,16 @@ export default {
<h4>健康管理</h4>
<p>点击下方查看更多服务</p>
</div>
<button class="go-btn">去看看</button>
<button class="go-btn" @click="goEcosystem(1, true)">去看看</button>
</div>
<div style="grid-column: 16 / 24;">
<div class="line-bg" style="margin-bottom: 10px;">
<span>养老服务</span>
<button class="go-btn-v">去看看</button>
<button class="go-btn-v" @click="goEcosystem(28)">去看看</button>
</div>
<div class="line-bg">
<span>财富管理</span>
<button class="go-btn-v">去看看</button>
<button class="go-btn-v" @click="goEcosystem(48)">去看看</button>
</div>
</div>
<div class="service-item" style="grid-column: 1 / 12;">
@@ -72,14 +86,14 @@ export default {
<h4>健康管理</h4>
<p>点击下方查看更多服务</p>
</div>
<button class="go-btn">去看看</button>
<button class="go-btn" @click="goEcosystem(1)">去看看</button>
</div>
<div class="service-item" style="grid-column: 12 / 24;">
<div>
<h4>健康管理</h4>
<p>点击下方查看更多服务</p>
</div>
<button class="go-btn">去看看</button>
<button class="go-btn" @click="goEcosystem(55)">去看看</button>
</div>
</div>
</section>

View File

@@ -24,7 +24,9 @@
<ul>
<li v-for="(item, index) in shopList" :key="index" :class="{ typeStyle: index === currentIndex }"
@click="onClickNav(index)">
<span class="leftTit" :class="{ typeFontSize: index === currentIndex }">{{ item.name }}</span>
<span class="leftTit" :class="{ typeFontSize: index === currentIndex }">
{{ singleWordMenu ? `${item.menuName[0]}` : item.menuName }}
</span>
</li>
</ul>
</div>
@@ -32,16 +34,14 @@
<div class="rightContent">
<ul ref="shopContent">
<li class="eventList" v-for="(item, index) in shopList" :key="index">
<div class="rightTtitle">{{ item.value == 'pensionService' ? item.name + '服务' : item.name }}
<div class="rightTtitle">{{ item.menuName }}
</div>
<ul>
<li class="gather" v-for="(subItem, index) in item.shopGather" :key="index"
<li class="gather" v-for="(subItem, index) in item.children" :key="index"
@click="goList(item, subItem)">
<div>
<img :src="subItem.img" />
</div>
<img :src="subItem.img" />
<div class="distance">
<div class="shopName">{{ subItem.text }}</div>
<div class="shopName">{{ subItem.menuName }}</div>
</div>
</li>
<div style="height: 1px"></div>
@@ -50,13 +50,6 @@
</ul>
</div>
</div>
<van-popup class="vanP" v-model="popopShow" :close-on-click-overlay="false">
<div class="smsTit">温馨提示</div>
<div class="smsCont">您可通过个人养老金信息管理服务平台获取您的扣税凭据后个人所得税完成抵扣申请</div>
<div class="buttons">
<div class="sub" @click="popopShow = false">确认</div>
</div>
</van-popup>
</div>
</template>
@@ -65,30 +58,26 @@
import { Popup, Search } from 'vant'
import BScroll from 'better-scroll'
import { shopList } from '@/views/service/js/mock/shop-list'
import { fetchServiceList } from "@/hooks/request/service-list"
import { fetchServiceList } from "@/api/service-list"
import { getEcosystemByValue } from '@/assets/js/utils/ecosystem'
export default {
components: {
[Popup.name]: Popup,
[Search.name]: Search,
},
setup() {
const { list } = fetchServiceList()
// return { list }
return {
shopList: []
}
props: {
},
data() {
return {
singleWordMenu: this.$route.query.swe,
shopList: [],
searchParams: '',
imgUrls: {
// 无数据
noData: 'http://ncc.ebiz-digits.com:39527/gsc/IHRHN5/7b/04/63/7b0463aa135f4a1f922b5171bcec1d14/images/健康管理/u102.png',
// noData: require('@/assets/images/public/noData.png'),
},
userInfo: {},
popopShow: false,
InterUrl: '',
serviceType: '',
scrollY: 0, // 右侧滑动的时候距离顶部的值
@@ -98,34 +87,6 @@ export default {
selectId: '',
}
},
created() {
// 进入保全项清空一下相关保存的信息
window.sessionStorage.removeItem('paymentDTO') // 删除暂存的银行信息
window.sessionStorage.removeItem('temporaryDetail') // 删除补发保单暂存的数据/追加投资暂存数据
window.sessionStorage.removeItem('bussInfoVO') // 删除电子发票暂存的列表信息(电子发票申请接口需要)
window.sessionStorage.removeItem('selectedTab')
if (this.$route.query.shareUrlId) {
sessionStorage.setItem('shareUrlId', this.$route.query.shareUrlId)
}
if (localStorage.token) {
this.getUser()
}
this.getInterUrl()
},
mounted() {
this.$nextTick(() => {
if (this.$route.query.searchParams) {
this.searchParams = this.$route.query.searchParams
this.onSearch('1')
}
if (this.$route.query.type) {
this.serviceType = this.$route.query.type
this.onSearch('2')
}
})
this.initializeRoll() //滑动初始化方法
this.initializeOwn() //初始化rightSide方法
},
//计算属性
computed: {
// 计算出当前分类的下标
@@ -150,12 +111,85 @@ export default {
return index
},
},
created() {
// 获取 list 内容
fetchServiceList({ menuCode: getEcosystemByValue(this.$route.params.ecosystem) }).then(res => {
this.shopList = res.content.content[0].children
// 在数据加载完成后等待DOM更新后再初始化滚动
this.$nextTick(() => {
this.initializeRoll()
this.initializeOwn()
})
})
// 进入保全项清空一下相关保存的信息
window.sessionStorage.removeItem('paymentDTO') // 删除暂存的银行信息
window.sessionStorage.removeItem('temporaryDetail') // 删除补发保单暂存的数据/追加投资暂存数据
window.sessionStorage.removeItem('bussInfoVO') // 删除电子发票暂存的列表信息(电子发票申请接口需要)
window.sessionStorage.removeItem('selectedTab')
if (this.$route.query.shareUrlId) {
sessionStorage.setItem('shareUrlId', this.$route.query.shareUrlId)
}
if (localStorage.token) {
this.getUser()
}
this.getInterUrl()
},
mounted() {
//页面激活时触发
// this.$mm.pages.current.rect()
//this.getUser()
//this.getInterUrl()
// 滚动初始化已移到数据加载完成后执行
},
methods: {
onSearch(type) {
return
if ((type == '0' || type == '1') && !this.searchParams) {
this.handleClear() // 修正方法名为handleClear
return
}
// 遍历所有菜单项
for (let i = 0; i < this.shopList.length; i++) {
const item = this.shopList[i]
// 确保item.children存在
if (!item.children || !Array.isArray(item.children)) {
continue
}
// 遍历子菜单
for (let j = 0; j < item.children.length; j++) {
const ele = item.children[j]
// 搜索关键字
if (type == '0' || type == '1') {
// 使用menuName代替text确保menuName存在
if (ele.menuName && ele.menuName.includes(this.searchParams)) {
this.onClickNav(i) // 使用当前索引i而不是item.id
console.log('找到匹配项:', ele.menuName)
return // 找到匹配后立即返回,停止搜索
}
}
// 按类型搜索
else if (type == '2' && this.serviceType) {
console.log('按类型搜索:', ele.type, this.serviceType)
if (ele.type == this.serviceType) {
this.onClickNav(i) // 使用当前索引i
console.log('找到匹配类型:', ele.type)
return // 找到匹配后立即返回,停止搜索
}
}
}
}
// 如果没有找到匹配项
console.log('没有找到匹配项')
},
handleClear() {
this.onClickNav(Number('0'))
// 清除搜索并返回到第一个分类
this.searchParams = ''
this.onClickNav(0) // 直接使用0不需要Number转换
},
getUser() {
@@ -174,15 +208,36 @@ export default {
},
// 初始化滚动
initializeRoll() {
// 检查DOM元素是否存在
const leftNavEl = document.querySelector('.leftNav')
const rightContentEl = document.querySelector('.rightContent')
if (!leftNavEl || !rightContentEl) {
console.error('滚动容器元素未找到')
return
}
// 销毁已存在的实例以防止重复创建
if (this.leftScroll) {
this.leftScroll.destroy()
}
if (this.foodsScroll) {
this.foodsScroll.destroy()
}
// new一个类的实例前提必须确保父元素和子元素的内容已经正确渲染了不然不会生效
new BScroll('.leftNav', {
this.leftScroll = new BScroll('.leftNav', {
click: true,
scrollY: true,
mouseWheel: true
})
// 组件实例上挂属性
this.foodsScroll = new BScroll('.rightContent', {
// scrollY: true,
scrollY: true,
probeType: 3, // 因为惯性滑动不会触发
click: true,
mouseWheel: true
})
// 给右侧列表绑定scroll监听
@@ -198,12 +253,25 @@ export default {
},
// 初始化rightSide
initializeOwn() {
// 检查DOM元素是否存在
if (!this.$refs.shopContent) {
console.error('shopContent ref is not found')
return
}
// 初始化rightSide
const rightSide = []
let top = 0
rightSide.push(top)
// 找到所有分类下的li
const lis = this.$refs.shopContent.getElementsByClassName('eventList') //获取dom元素liieventList对其进行操作
// 检查是否找到元素
if (!lis || lis.length === 0) {
console.error('No eventList elements found')
return
}
// slice() 方法返回一个新的数组对象
Array.prototype.slice.call(lis).forEach((li) => {
top += li.clientHeight //相当于top = top + li.clientHeight

View File

@@ -12,7 +12,14 @@ module.exports = {
outputDir: 'dist', //打包输出目录
productionSourceMap: false,
devServer: {
https: false
https: false,
proxy: {
'/api': {
target: 'http://127.0.0.1:7100',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
}
}
},
css: {
sourceMap: true, // 查看css属于哪个css文件