updata
This commit is contained in:
parent
1f9057a38a
commit
00bb3e5653
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<transition name="slide">
|
<transition name="slide">
|
||||||
<div v-show="windowsHidden" style="font-size: 14px">
|
<div v-show="windowsHidden" style="font-size: 14px">
|
||||||
<div class="new-floating" style="z-index: 9999;">
|
<div class="new-floating" style="z-index: 99;">
|
||||||
<img src="./img/head.png" alt="">
|
<img src="./img/head.png" alt="">
|
||||||
<div class="cloud-contact-us " @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
|
<div class="cloud-contact-us " @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
|
||||||
<!-- <span class="cloud-contact-us-i"></span>-->
|
<!-- <span class="cloud-contact-us-i"></span>-->
|
||||||
@ -789,7 +789,7 @@ export default {
|
|||||||
top: -28px;
|
top: -28px;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
z-index: 9999;
|
z-index: 99;
|
||||||
}
|
}
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@ -171,7 +171,7 @@ Vue.use(HappyScroll)
|
|||||||
// });
|
// });
|
||||||
|
|
||||||
// console.log(element);
|
// console.log(element);
|
||||||
// console.clear(); // 清除测试日志
|
// console.clear(); // 清除测试日志
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// // 方法4: 检查Eruda等移动端调试工具
|
// // 方法4: 检查Eruda等移动端调试工具
|
||||||
@ -345,6 +345,77 @@ window.addEventListener('beforeunload', function () {
|
|||||||
Object.keys(filters).forEach(key => {
|
Object.keys(filters).forEach(key => {
|
||||||
Vue.filter(key, filters[key])
|
Vue.filter(key, filters[key])
|
||||||
})
|
})
|
||||||
|
// 在 main.js 的 router.beforeEach 中添加
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
// 清空面包屑状态的代码
|
||||||
|
// store.commit('tagsView/resetBreadcrumbState');
|
||||||
|
|
||||||
|
// 新增:检测是否为移动设备
|
||||||
|
const userAgent = navigator.userAgent;
|
||||||
|
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent);
|
||||||
|
|
||||||
|
// 如果是移动设备且访问的是根路径,重定向到移动端首页
|
||||||
|
if (isMobile && to.path === '/') {
|
||||||
|
next('/h5HomePage');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果是移动设备且访问的不是移动端页面,重定向到移动端首页
|
||||||
|
if (isMobile && !to.meta?.isMobile && to.path !== '/h5HomePage' && !to.path.startsWith('/h5HomePage/')) {
|
||||||
|
next('/h5HomePage');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果已登录且有token,但Vuex状态丢失,从sessionStorage恢复
|
||||||
|
if (store.getters.token && (!store.getters.user || !store.getters.userType)) {
|
||||||
|
console.log("检测到状态丢失,从sessionStorage恢复用户状态");
|
||||||
|
|
||||||
|
const user = sessionStorage.getItem('user');
|
||||||
|
const auths = sessionStorage.getItem('auths');
|
||||||
|
const userType = sessionStorage.getItem('userType');
|
||||||
|
const orgType = sessionStorage.getItem('orgType');
|
||||||
|
|
||||||
|
if (user) {
|
||||||
|
store.commit('user/SET_USER', user);
|
||||||
|
}
|
||||||
|
if (auths) {
|
||||||
|
store.commit('user/SET_AUTHS', JSON.parse(auths));
|
||||||
|
}
|
||||||
|
if (userType) {
|
||||||
|
store.commit('user/SET_USER_TYPE', userType);
|
||||||
|
}
|
||||||
|
if (orgType) {
|
||||||
|
store.commit('user/SET_ORG_TYPE', parseInt(orgType));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重新生成路由
|
||||||
|
try {
|
||||||
|
const accessRoutes = store.dispatch('permission/generateRoutes', {
|
||||||
|
user: store.getters.user,
|
||||||
|
auths: store.getters.auths,
|
||||||
|
userType: store.getters.userType,
|
||||||
|
orgType: store.getters.orgType
|
||||||
|
});
|
||||||
|
|
||||||
|
// 重新添加路由
|
||||||
|
router.addRoutes(accessRoutes);
|
||||||
|
|
||||||
|
// 重定向到当前路由以确保路由更新
|
||||||
|
next({ ...to, replace: true });
|
||||||
|
return;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('重新生成路由失败:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onOverflow.forEach(element => {
|
||||||
|
if (to.path == element) {
|
||||||
|
document.querySelector("body").setAttribute("style", "overflow: auto !important;")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
|
|
||||||
|
|||||||
@ -6,8 +6,83 @@ const userAgent = window.navigator.userAgent;
|
|||||||
// 判断是否为移动设备
|
// 判断是否为移动设备
|
||||||
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent);
|
const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent);
|
||||||
|
|
||||||
|
// 如果是移动设备,添加移动端首页路由和根路径重定向
|
||||||
|
if (isMobile) {
|
||||||
|
console.log("检测到移动设备,添加移动端路由");
|
||||||
|
|
||||||
|
// 先添加根路径重定向到移动端首页
|
||||||
|
constantRoutes.unshift({
|
||||||
|
path: '/',
|
||||||
|
redirect: '/h5HomePage',
|
||||||
|
hidden: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// 添加移动端首页路由
|
||||||
|
constantRoutes.push({
|
||||||
|
path: '/h5HomePage',
|
||||||
|
name: 'H5HomePage',
|
||||||
|
title: 'H5首页',
|
||||||
|
component: () => import('@/views/H5/index.vue'),
|
||||||
|
hidden: true,
|
||||||
|
redirect: "/h5HomePage/index",
|
||||||
|
meta: { isMobile: true },
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: "index",
|
||||||
|
title: 'H5首页',
|
||||||
|
component: () => import('@/views/H5/official/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: "H5首页",
|
||||||
|
fullPath: "/h5HomePage/index",
|
||||||
|
isMobile: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "cloud",
|
||||||
|
title: '云',
|
||||||
|
component: () => import('@/views/H5/cloud/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: "云",
|
||||||
|
fullPath: "/h5HomePage/cloud",
|
||||||
|
isMobile: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "calculate",
|
||||||
|
title: '算',
|
||||||
|
component: () => import('@/views/H5/calculate/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: "算",
|
||||||
|
fullPath: "/h5HomePage/calculate",
|
||||||
|
isMobile: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "net",
|
||||||
|
title: '网',
|
||||||
|
component: () => import('@/views/H5/net/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: "网",
|
||||||
|
fullPath: "/h5HomePage/net",
|
||||||
|
isMobile: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "use",
|
||||||
|
title: '用',
|
||||||
|
component: () => import('@/views/H5/use/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: "用",
|
||||||
|
fullPath: "/h5HomePage/use",
|
||||||
|
isMobile: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 修复:更全面的路由过滤逻辑
|
// 修复:更全面的路由过滤逻辑
|
||||||
function filterAsyncRoutes(routes, permissions, userRoles = []) {
|
function filterAsyncRoutes(routes, permissions, userRoles = [], deviceType = 'pc') {
|
||||||
const res = [];
|
const res = [];
|
||||||
|
|
||||||
// 定义需要客户角色才能访问的路由
|
// 定义需要客户角色才能访问的路由
|
||||||
@ -35,6 +110,14 @@ function filterAsyncRoutes(routes, permissions, userRoles = []) {
|
|||||||
return; // 跳过当前路由
|
return; // 跳过当前路由
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新增:根据设备类型过滤路由
|
||||||
|
if (deviceType === 'mobile' && !(route.meta?.isMobile || route.meta?.isMobile === true)) {
|
||||||
|
return; // 移动设备跳过非移动端路由
|
||||||
|
}
|
||||||
|
if (deviceType === 'pc' && route.meta?.isMobile === true) {
|
||||||
|
return; // PC设备跳过移动端路由
|
||||||
|
}
|
||||||
|
|
||||||
// 如果当前路由有权限,则加入结果
|
// 如果当前路由有权限,则加入结果
|
||||||
if (hasPermission) {
|
if (hasPermission) {
|
||||||
res.push(tmpRoute);
|
res.push(tmpRoute);
|
||||||
@ -45,7 +128,7 @@ function filterAsyncRoutes(routes, permissions, userRoles = []) {
|
|||||||
}
|
}
|
||||||
// 如果没有直接权限,但有子路由,递归处理子路由
|
// 如果没有直接权限,但有子路由,递归处理子路由
|
||||||
else if (tmpRoute.children) {
|
else if (tmpRoute.children) {
|
||||||
const filteredChildren = filterAsyncRoutes(tmpRoute.children, permissions, userRoles);
|
const filteredChildren = filterAsyncRoutes(tmpRoute.children, permissions, userRoles, deviceType);
|
||||||
if (filteredChildren.length > 0) {
|
if (filteredChildren.length > 0) {
|
||||||
tmpRoute.children = filteredChildren;
|
tmpRoute.children = filteredChildren;
|
||||||
res.push(tmpRoute); // 即使父路由本身没有权限,只要有子路由有权限,也要保留父路由
|
res.push(tmpRoute); // 即使父路由本身没有权限,只要有子路由有权限,也要保留父路由
|
||||||
@ -57,7 +140,7 @@ function filterAsyncRoutes(routes, permissions, userRoles = []) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 新增:为普通用户添加订单管理和资源管理路由
|
// 新增:为普通用户添加订单管理和资源管理路由
|
||||||
function addUserRoutes(routes, userType, orgType, userRoles = []) {
|
function addUserRoutes(routes, userType, orgType, userRoles = [], deviceType = 'pc') {
|
||||||
console.log("addUserRoutes - userType:", userType, "orgType:", orgType, "userRoles:", userRoles);
|
console.log("addUserRoutes - userType:", userType, "orgType:", orgType, "userRoles:", userRoles);
|
||||||
|
|
||||||
const userRoutes = [];
|
const userRoutes = [];
|
||||||
@ -67,12 +150,13 @@ function addUserRoutes(routes, userType, orgType, userRoles = []) {
|
|||||||
const orderManagementRoute = routes.find(route => route.path === "/orderManagement");
|
const orderManagementRoute = routes.find(route => route.path === "/orderManagement");
|
||||||
const resourceManagementRoute = routes.find(route => route.path === "/resourceManagement");
|
const resourceManagementRoute = routes.find(route => route.path === "/resourceManagement");
|
||||||
|
|
||||||
if (orderManagementRoute) {
|
// 新增:根据设备类型过滤
|
||||||
|
if (orderManagementRoute && (deviceType === 'pc' || orderManagementRoute.meta?.isMobile === true)) {
|
||||||
console.log("添加订单管理路由");
|
console.log("添加订单管理路由");
|
||||||
userRoutes.push(JSON.parse(JSON.stringify(orderManagementRoute))); // 深拷贝
|
userRoutes.push(JSON.parse(JSON.stringify(orderManagementRoute))); // 深拷贝
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resourceManagementRoute) {
|
if (resourceManagementRoute && (deviceType === 'pc' || resourceManagementRoute.meta?.isMobile === true)) {
|
||||||
console.log("添加资源管理路由");
|
console.log("添加资源管理路由");
|
||||||
userRoutes.push(JSON.parse(JSON.stringify(resourceManagementRoute))); // 深拷贝
|
userRoutes.push(JSON.parse(JSON.stringify(resourceManagementRoute))); // 深拷贝
|
||||||
}
|
}
|
||||||
@ -85,10 +169,10 @@ function addUserRoutes(routes, userType, orgType, userRoles = []) {
|
|||||||
routes.find(route => route.path === "/rechargeManagement"),
|
routes.find(route => route.path === "/rechargeManagement"),
|
||||||
routes.find(route => route.path === "/invoiceManagement"),
|
routes.find(route => route.path === "/invoiceManagement"),
|
||||||
routes.find(route => route.path === "/workOrderManagement")
|
routes.find(route => route.path === "/workOrderManagement")
|
||||||
|
|
||||||
].filter(route => {
|
].filter(route => {
|
||||||
// 过滤掉undefined,并且只有客户角色才能看到这些路由
|
// 过滤掉undefined,并且只有客户角色才能看到这些路由
|
||||||
return route && userRoles.includes('客户');
|
return route && userRoles.includes('客户') &&
|
||||||
|
(deviceType === 'pc' || route.meta?.isMobile === true);
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("添加新的客户菜单路由:", newCustomerRoutes.map(r => r.path));
|
console.log("添加新的客户菜单路由:", newCustomerRoutes.map(r => r.path));
|
||||||
@ -97,38 +181,11 @@ function addUserRoutes(routes, userType, orgType, userRoles = []) {
|
|||||||
return userRoutes;
|
return userRoutes;
|
||||||
}
|
}
|
||||||
|
|
||||||
function filterRoutesMobile(routes) {
|
|
||||||
return routes.filter(route => {
|
|
||||||
if (route.children && route.children.length) {
|
|
||||||
route.children = filterRoutesMobile(route.children);
|
|
||||||
return route.children.length > 0;
|
|
||||||
}
|
|
||||||
if (route.meta?.isMobile || route.meta?.isMobile === true) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterRoutesPc(routes) {
|
|
||||||
return routes.filter(route => {
|
|
||||||
if (route.children && route.children.length) {
|
|
||||||
route.children = filterRoutesPc(route.children);
|
|
||||||
return route.children.length > 0;
|
|
||||||
}
|
|
||||||
if (!route.meta?.isMobile || route.meta?.isMobile === false) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
routes: [],
|
routes: [],
|
||||||
addRoutes: [],
|
addRoutes: [],
|
||||||
users: []
|
users: [],
|
||||||
|
isMobile: isMobile // 保存设备类型状态
|
||||||
};
|
};
|
||||||
|
|
||||||
const mutations = {
|
const mutations = {
|
||||||
@ -136,11 +193,15 @@ const mutations = {
|
|||||||
console.log("MUTATION SET_ROUTES - received routes:", routes);
|
console.log("MUTATION SET_ROUTES - received routes:", routes);
|
||||||
state.addRoutes = routes;
|
state.addRoutes = routes;
|
||||||
sessionStorage.setItem("routes", JSON.stringify(routes));
|
sessionStorage.setItem("routes", JSON.stringify(routes));
|
||||||
|
// 将移动端首页路由也包含在内
|
||||||
state.routes = constantRoutes.concat(routes);
|
state.routes = constantRoutes.concat(routes);
|
||||||
console.log("MUTATION SET_ROUTES - final state.routes:", state.routes);
|
console.log("MUTATION SET_ROUTES - final state.routes:", state.routes);
|
||||||
},
|
},
|
||||||
SETUSERS: (state, user) => {
|
SETUSERS: (state, user) => {
|
||||||
state.users = user;
|
state.users = user;
|
||||||
|
},
|
||||||
|
SET_DEVICE_TYPE: (state, isMobile) => {
|
||||||
|
state.isMobile = isMobile;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -161,7 +222,7 @@ const actions = {
|
|||||||
* @param {Object} [params.user] - 用户信息对象
|
* @param {Object} [params.user] - 用户信息对象
|
||||||
* @returns {Promise<Array>} 解析后的动态路由数组
|
* @returns {Promise<Array>} 解析后的动态路由数组
|
||||||
*/
|
*/
|
||||||
generateRoutes({ commit, rootState }, params) {
|
generateRoutes({ commit, rootState, state }, params) {
|
||||||
console.log("ACTION generateRoutes - params:", params);
|
console.log("ACTION generateRoutes - params:", params);
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
let accessedRoutes;
|
let accessedRoutes;
|
||||||
@ -176,10 +237,18 @@ const actions = {
|
|||||||
|
|
||||||
console.log("用户类型:", userType, "orgType:", orgType);
|
console.log("用户类型:", userType, "orgType:", orgType);
|
||||||
|
|
||||||
|
// 确定设备类型
|
||||||
|
const deviceType = state.isMobile ? 'mobile' : 'pc';
|
||||||
|
console.log("设备类型:", deviceType);
|
||||||
|
|
||||||
// 修复:包含 orgType 为 2 和 3 的情况
|
// 修复:包含 orgType 为 2 和 3 的情况
|
||||||
if (params.user && params.user.includes("admin") && orgType != 2 && orgType != 3) {
|
if (params.user && params.user.includes("admin") && orgType != 2 && orgType != 3) {
|
||||||
// 管理员:只显示超级管理员菜单
|
// 管理员:只显示超级管理员菜单(仅PC端)
|
||||||
accessedRoutes = asyncRoutes.filter(item => item.path === '/superAdministrator');
|
if (deviceType === 'pc') {
|
||||||
|
accessedRoutes = asyncRoutes.filter(item => item.path === '/superAdministrator');
|
||||||
|
} else {
|
||||||
|
accessedRoutes = [];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const auths = params.auths ? JSON.parse(JSON.stringify(params.auths)) : [];
|
const auths = params.auths ? JSON.parse(JSON.stringify(params.auths)) : [];
|
||||||
console.log("ACTION generateRoutes - auths:", auths);
|
console.log("ACTION generateRoutes - auths:", auths);
|
||||||
@ -195,8 +264,8 @@ const actions = {
|
|||||||
// 如果权限列表包含空路径,认为用户有所有权限
|
// 如果权限列表包含空路径,认为用户有所有权限
|
||||||
accessedRoutes = asyncRoutes || [];
|
accessedRoutes = asyncRoutes || [];
|
||||||
} else {
|
} else {
|
||||||
// 使用修复后的过滤函数,传入用户角色
|
// 使用修复后的过滤函数,传入用户角色和设备类型
|
||||||
accessedRoutes = filterAsyncRoutes(asyncRoutes, auths, userRoles);
|
accessedRoutes = filterAsyncRoutes(asyncRoutes, auths, userRoles, deviceType);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 如果没有权限列表,不显示任何动态路由
|
// 如果没有权限列表,不显示任何动态路由
|
||||||
@ -205,7 +274,7 @@ const actions = {
|
|||||||
|
|
||||||
// 新增:为普通用户添加订单管理和资源管理路由以及新的五个客户菜单
|
// 新增:为普通用户添加订单管理和资源管理路由以及新的五个客户菜单
|
||||||
console.log("为用户添加特定路由");
|
console.log("为用户添加特定路由");
|
||||||
const userSpecificRoutes = addUserRoutes(asyncRoutes, userType, orgType, userRoles);
|
const userSpecificRoutes = addUserRoutes(asyncRoutes, userType, orgType, userRoles, deviceType);
|
||||||
|
|
||||||
// 确保不重复添加路由,同时检查角色权限
|
// 确保不重复添加路由,同时检查角色权限
|
||||||
userSpecificRoutes.forEach(route => {
|
userSpecificRoutes.forEach(route => {
|
||||||
|
|||||||
BIN
f/web-kboss/src/views/H5/images/bg.png
Normal file
BIN
f/web-kboss/src/views/H5/images/bg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 595 KiB |
@ -2,19 +2,29 @@
|
|||||||
<div class="h5-container">
|
<div class="h5-container">
|
||||||
<!-- 主要内容区域 -->
|
<!-- 主要内容区域 -->
|
||||||
<div ref="mainContent" class="main" @scroll="handleScroll">
|
<div ref="mainContent" class="main" @scroll="handleScroll">
|
||||||
<router-view></router-view>
|
<transition :name="transitionName" mode="out-in">
|
||||||
|
<router-view></router-view>
|
||||||
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
<div style="height: 1.4rem;"></div>
|
<div style="height: 1.4rem;"></div>
|
||||||
|
|
||||||
<!-- 返回顶部按钮 -->
|
<!-- 返回顶部按钮 -->
|
||||||
<transition name="fade">
|
<transition name="fade-scale">
|
||||||
<div
|
<div
|
||||||
v-show="showBackToTop"
|
v-show="showBackToTop"
|
||||||
class="back-to-top"
|
class="back-to-top"
|
||||||
@click="scrollToTop"
|
@click="scrollToTop"
|
||||||
>
|
>
|
||||||
<div class="back-to-top-icon">↑</div>
|
<div class="back-to-top-icon">
|
||||||
<div class="back-to-top-text">顶部</div>
|
<svg viewBox="0 0 24 24" fill="none">
|
||||||
|
<path d="M12 5L12 19M12 5L6 11M12 5L18 11"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="back-to-top-text">回顶部</div>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
|
|
||||||
@ -27,14 +37,20 @@
|
|||||||
@click="switchTab('index')"
|
@click="switchTab('index')"
|
||||||
>
|
>
|
||||||
<div class="item-img">
|
<div class="item-img">
|
||||||
<img
|
<transition name="icon-bounce" mode="out-in">
|
||||||
:src="activeTab === 'index' ? require('./images/tabBar/homeColor.png') : require('./images/tabBar/home.png')"
|
<img
|
||||||
alt="首页"
|
:key="activeTab === 'index'"
|
||||||
/>
|
:src="activeTab === 'index' ? require('./images/tabBar/homeColor.png') : require('./images/tabBar/home.png')"
|
||||||
|
alt="首页"
|
||||||
|
/>
|
||||||
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
<div class="item-text">
|
<div class="item-text">
|
||||||
首页
|
<transition name="text-slide" mode="out-in">
|
||||||
|
<span :key="activeTab === 'index'">首页</span>
|
||||||
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="active-indicator" v-if="activeTab === 'index'"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 云 -->
|
<!-- 云 -->
|
||||||
@ -44,14 +60,20 @@
|
|||||||
@click="switchTab('cloud')"
|
@click="switchTab('cloud')"
|
||||||
>
|
>
|
||||||
<div class="item-img">
|
<div class="item-img">
|
||||||
<img
|
<transition name="icon-bounce" mode="out-in">
|
||||||
:src="activeTab === 'cloud' ? require('./images/tabBar/cloudColor.png') : require('./images/tabBar/cloud.png')"
|
<img
|
||||||
alt="云"
|
:key="activeTab === 'cloud'"
|
||||||
/>
|
:src="activeTab === 'cloud' ? require('./images/tabBar/cloudColor.png') : require('./images/tabBar/cloud.png')"
|
||||||
|
alt="云"
|
||||||
|
/>
|
||||||
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
<div class="item-text">
|
<div class="item-text">
|
||||||
云
|
<transition name="text-slide" mode="out-in">
|
||||||
|
<span :key="activeTab === 'cloud'">云</span>
|
||||||
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="active-indicator" v-if="activeTab === 'cloud'"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 算 -->
|
<!-- 算 -->
|
||||||
@ -61,14 +83,20 @@
|
|||||||
@click="switchTab('calculate')"
|
@click="switchTab('calculate')"
|
||||||
>
|
>
|
||||||
<div class="item-img">
|
<div class="item-img">
|
||||||
<img
|
<transition name="icon-bounce" mode="out-in">
|
||||||
:src="activeTab === 'calculate' ? require('./images/tabBar/calculateColor.png') : require('./images/tabBar/calculate.png')"
|
<img
|
||||||
alt="算"
|
:key="activeTab === 'calculate'"
|
||||||
/>
|
:src="activeTab === 'calculate' ? require('./images/tabBar/calculateColor.png') : require('./images/tabBar/calculate.png')"
|
||||||
|
alt="算"
|
||||||
|
/>
|
||||||
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
<div class="item-text">
|
<div class="item-text">
|
||||||
算
|
<transition name="text-slide" mode="out-in">
|
||||||
|
<span :key="activeTab === 'calculate'">算</span>
|
||||||
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="active-indicator" v-if="activeTab === 'calculate'"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 网 -->
|
<!-- 网 -->
|
||||||
@ -78,14 +106,20 @@
|
|||||||
@click="switchTab('net')"
|
@click="switchTab('net')"
|
||||||
>
|
>
|
||||||
<div class="item-img">
|
<div class="item-img">
|
||||||
<img
|
<transition name="icon-bounce" mode="out-in">
|
||||||
:src="activeTab === 'net' ? require('./images/tabBar/netColor.png') : require('./images/tabBar/net.png')"
|
<img
|
||||||
alt="网"
|
:key="activeTab === 'net'"
|
||||||
/>
|
:src="activeTab === 'net' ? require('./images/tabBar/netColor.png') : require('./images/tabBar/net.png')"
|
||||||
|
alt="网"
|
||||||
|
/>
|
||||||
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
<div class="item-text">
|
<div class="item-text">
|
||||||
网
|
<transition name="text-slide" mode="out-in">
|
||||||
|
<span :key="activeTab === 'net'">网</span>
|
||||||
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="active-indicator" v-if="activeTab === 'net'"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 用 -->
|
<!-- 用 -->
|
||||||
@ -95,14 +129,20 @@
|
|||||||
@click="switchTab('use')"
|
@click="switchTab('use')"
|
||||||
>
|
>
|
||||||
<div class="item-img">
|
<div class="item-img">
|
||||||
<img
|
<transition name="icon-bounce" mode="out-in">
|
||||||
:src="activeTab === 'use' ? require('./images/tabBar/userColor.png') : require('./images/tabBar/user.png')"
|
<img
|
||||||
alt="用"
|
:key="activeTab === 'use'"
|
||||||
/>
|
:src="activeTab === 'use' ? require('./images/tabBar/userColor.png') : require('./images/tabBar/user.png')"
|
||||||
|
alt="用"
|
||||||
|
/>
|
||||||
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
<div class="item-text">
|
<div class="item-text">
|
||||||
用
|
<transition name="text-slide" mode="out-in">
|
||||||
|
<span :key="activeTab === 'use'">用</span>
|
||||||
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="active-indicator" v-if="activeTab === 'use'"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -124,6 +164,8 @@ export default {
|
|||||||
],
|
],
|
||||||
showBackToTop: false, // 是否显示返回顶部按钮
|
showBackToTop: false, // 是否显示返回顶部按钮
|
||||||
scrollThreshold: 200, // 滚动多少距离后显示按钮(可根据需要调整)
|
scrollThreshold: 200, // 滚动多少距离后显示按钮(可根据需要调整)
|
||||||
|
transitionName: 'fade', // 页面切换动画名称
|
||||||
|
isSwitching: false, // 是否正在切换
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@ -142,8 +184,11 @@ export default {
|
|||||||
* @param {string} tabId - 标签ID
|
* @param {string} tabId - 标签ID
|
||||||
*/
|
*/
|
||||||
switchTab(tabId) {
|
switchTab(tabId) {
|
||||||
// 如果点击的是当前已激活的标签,不进行操作
|
// 如果正在切换或点击的是当前已激活的标签,不进行操作
|
||||||
if (this.activeTab === tabId) return;
|
if (this.isSwitching || this.activeTab === tabId) return;
|
||||||
|
|
||||||
|
// 设置正在切换状态
|
||||||
|
this.isSwitching = true;
|
||||||
|
|
||||||
// 更新激活状态
|
// 更新激活状态
|
||||||
this.activeTab = tabId;
|
this.activeTab = tabId;
|
||||||
@ -151,7 +196,39 @@ export default {
|
|||||||
// 根据tabId跳转到对应的路由
|
// 根据tabId跳转到对应的路由
|
||||||
const tab = this.tabList.find(item => item.id === tabId);
|
const tab = this.tabList.find(item => item.id === tabId);
|
||||||
if (tab) {
|
if (tab) {
|
||||||
this.$router.push(tab.path);
|
// 添加点击反馈动画
|
||||||
|
this.animateTabClick(tabId);
|
||||||
|
|
||||||
|
// 延迟路由跳转,让动画先执行
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$router.push(tab.path);
|
||||||
|
// 重置切换状态
|
||||||
|
setTimeout(() => {
|
||||||
|
this.isSwitching = false;
|
||||||
|
}, 300);
|
||||||
|
}, 150);
|
||||||
|
} else {
|
||||||
|
this.isSwitching = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行Tab点击动画
|
||||||
|
* @param {string} tabId - 标签ID
|
||||||
|
*/
|
||||||
|
animateTabClick(tabId) {
|
||||||
|
// 获取点击的tab元素
|
||||||
|
const tabIndex = this.tabList.findIndex(item => item.id === tabId);
|
||||||
|
const tabs = document.querySelectorAll('.tabBar-item');
|
||||||
|
|
||||||
|
if (tabs[tabIndex]) {
|
||||||
|
// 添加点击动画类
|
||||||
|
tabs[tabIndex].classList.add('click-animation');
|
||||||
|
|
||||||
|
// 动画结束后移除类
|
||||||
|
setTimeout(() => {
|
||||||
|
tabs[tabIndex].classList.remove('click-animation');
|
||||||
|
}, 300);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -186,6 +263,15 @@ export default {
|
|||||||
*/
|
*/
|
||||||
scrollToTop() {
|
scrollToTop() {
|
||||||
if (this.$refs.mainContent) {
|
if (this.$refs.mainContent) {
|
||||||
|
// 添加点击反馈效果
|
||||||
|
const btn = document.querySelector('.back-to-top');
|
||||||
|
if (btn) {
|
||||||
|
btn.classList.add('clicked');
|
||||||
|
setTimeout(() => {
|
||||||
|
btn.classList.remove('clicked');
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
|
||||||
this.$refs.mainContent.scrollTo({
|
this.$refs.mainContent.scrollTo({
|
||||||
top: 0,
|
top: 0,
|
||||||
behavior: 'smooth' // 平滑滚动
|
behavior: 'smooth' // 平滑滚动
|
||||||
@ -208,120 +294,5 @@ window.onresize = adapter()
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.h5-container {
|
@import url('./less/home/index.less');
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 100vh;
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main {
|
|
||||||
flex: 1;
|
|
||||||
overflow-y: auto;
|
|
||||||
-webkit-overflow-scrolling: touch; /* 为iOS添加平滑滚动 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 返回顶部按钮样式 */
|
|
||||||
.back-to-top {
|
|
||||||
position: fixed;
|
|
||||||
right: 0.4rem;
|
|
||||||
bottom: 1.5rem; /* 在底部导航栏上方 */
|
|
||||||
z-index: 999;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 1.1rem;
|
|
||||||
height: 1.1rem;
|
|
||||||
background: linear-gradient(90deg, #275AFF 0%, #2EBDFA 100%);
|
|
||||||
border-radius: 50%;
|
|
||||||
box-shadow: 0 0.04rem 0.12rem rgba(0, 0, 0, 0.3);
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
transform: scale(0.95);
|
|
||||||
box-shadow: 0 0.02rem 0.06rem rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: linear-gradient(90deg, #275AFF 0%, #2EBDFA 100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.back-to-top-icon {
|
|
||||||
color: white;
|
|
||||||
font-size: 0.4rem;
|
|
||||||
font-weight: bold;
|
|
||||||
// line-height: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.back-to-top-text {
|
|
||||||
color: white;
|
|
||||||
font-size: 0.26rem;
|
|
||||||
line-height: 0.2rem;
|
|
||||||
// margin-top: -0.04rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 淡入淡出动画 */
|
|
||||||
.fade-enter-active, .fade-leave-active {
|
|
||||||
transition: opacity 0.3s, transform 0.3s;
|
|
||||||
}
|
|
||||||
.fade-enter, .fade-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(0.2rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tabBar {
|
|
||||||
padding: .2rem 0;
|
|
||||||
background-color: #fff;
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-around;
|
|
||||||
align-items: center;
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: 1000;
|
|
||||||
box-shadow: 0 -0.02rem .1rem rgba(0, 0, 0, 0.1);
|
|
||||||
|
|
||||||
.tabBar-item {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
.item-text {
|
|
||||||
color: #1890ff;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.item-img {
|
|
||||||
margin-bottom: .1rem;
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: .5rem;
|
|
||||||
height: .5rem;
|
|
||||||
display: block;
|
|
||||||
transition: transform 0.3s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.item-text {
|
|
||||||
font-size: .24rem;
|
|
||||||
color: #666;
|
|
||||||
transition: color 0.3s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -95,7 +95,7 @@
|
|||||||
width: var(--dialog-width, 6rem) !important;
|
width: var(--dialog-width, 6rem) !important;
|
||||||
max-width: 90%;
|
max-width: 90%;
|
||||||
border-radius: 0.08rem;
|
border-radius: 0.08rem;
|
||||||
z-index: 99999;
|
z-index: 9999;
|
||||||
}
|
}
|
||||||
::v-deep .product-consult-dialog.el-dialog .el-dialog__header {
|
::v-deep .product-consult-dialog.el-dialog .el-dialog__header {
|
||||||
padding: 0.2rem 0.3rem 0.1rem;
|
padding: 0.2rem 0.3rem 0.1rem;
|
||||||
|
|||||||
@ -108,7 +108,7 @@
|
|||||||
width: var(--dialog-width, 6rem) !important;
|
width: var(--dialog-width, 6rem) !important;
|
||||||
max-width: 90%;
|
max-width: 90%;
|
||||||
border-radius: .08rem;
|
border-radius: .08rem;
|
||||||
z-index: 99999;
|
z-index: 9999;
|
||||||
|
|
||||||
.el-dialog__header {
|
.el-dialog__header {
|
||||||
padding: .2rem .3rem .1rem;
|
padding: .2rem .3rem .1rem;
|
||||||
|
|||||||
365
f/web-kboss/src/views/H5/less/home/index.css
Normal file
365
f/web-kboss/src/views/H5/less/home/index.css
Normal file
@ -0,0 +1,365 @@
|
|||||||
|
.h5-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.main {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
/* 为iOS添加平滑滚动 */
|
||||||
|
}
|
||||||
|
/* 页面切换动画 */
|
||||||
|
.fade-enter-active,
|
||||||
|
.fade-leave-active {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
.fade-enter-from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(0.2rem);
|
||||||
|
}
|
||||||
|
.fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-0.2rem);
|
||||||
|
}
|
||||||
|
/* 返回顶部按钮样式 */
|
||||||
|
.back-to-top {
|
||||||
|
position: fixed;
|
||||||
|
right: 0.4rem;
|
||||||
|
bottom: 1.5rem;
|
||||||
|
/* 在底部导航栏上方 */
|
||||||
|
z-index: 999;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 1.1rem;
|
||||||
|
height: 1.1rem;
|
||||||
|
background: linear-gradient(90deg, #275AFF 0%, #2EBDFA 100%);
|
||||||
|
border-radius: 50%;
|
||||||
|
box-shadow: 0 0.08rem 0.24rem rgba(102, 126, 234, 0.4);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
user-select: none;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
/* 悬停效果 */
|
||||||
|
/* 激活效果 */
|
||||||
|
/* 点击动画 */
|
||||||
|
}
|
||||||
|
.back-to-top:hover {
|
||||||
|
transform: translateY(-0.1rem);
|
||||||
|
box-shadow: 0 0.12rem 0.36rem rgba(102, 126, 234, 0.6);
|
||||||
|
background: linear-gradient(90deg, #275AFF 0%, #2EBDFA 100%);
|
||||||
|
}
|
||||||
|
.back-to-top:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
.back-to-top.clicked {
|
||||||
|
animation: pulse 0.3s ease;
|
||||||
|
}
|
||||||
|
.back-to-top .back-to-top-icon {
|
||||||
|
width: 0.45rem;
|
||||||
|
height: 0.45rem;
|
||||||
|
color: white;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 0.04rem;
|
||||||
|
}
|
||||||
|
.back-to-top .back-to-top-icon svg {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
stroke: currentColor;
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
.back-to-top .back-to-top-text {
|
||||||
|
color: white;
|
||||||
|
font-size: 0.24rem;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1;
|
||||||
|
letter-spacing: 0.02rem;
|
||||||
|
text-shadow: 0 0.02rem 0.04rem rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
/* 脉冲动画 */
|
||||||
|
@keyframes pulse {
|
||||||
|
0% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(0.9);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 返回顶部按钮动画 */
|
||||||
|
.fade-scale-enter-active,
|
||||||
|
.fade-scale-leave-active {
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
.fade-scale-enter-from,
|
||||||
|
.fade-scale-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.8) translateY(0.2rem);
|
||||||
|
}
|
||||||
|
/* TabBar 样式 */
|
||||||
|
.tabBar {
|
||||||
|
padding: 0.2rem 0;
|
||||||
|
background-color: rgba(255, 255, 255, 0.95);
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
box-shadow: 0 -0.02rem 0.2rem rgba(0, 0, 0, 0.08);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
-webkit-backdrop-filter: blur(10px);
|
||||||
|
border-top: 1px solid rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
.tabBar .tabBar-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
padding: 0.1rem 0.15rem;
|
||||||
|
border-radius: 0.3rem;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
user-select: none;
|
||||||
|
/* 悬停效果 */
|
||||||
|
/* 激活状态 */
|
||||||
|
/* 点击动画 */
|
||||||
|
/* 激活指示器 */
|
||||||
|
}
|
||||||
|
.tabBar .tabBar-item:hover {
|
||||||
|
background-color: rgba(24, 144, 255, 0.08);
|
||||||
|
transform: translateY(-0.05rem);
|
||||||
|
}
|
||||||
|
.tabBar .tabBar-item.active .item-text {
|
||||||
|
color: #1890ff;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.tabBar .tabBar-item.click-animation {
|
||||||
|
animation: tabClick 0.3s ease;
|
||||||
|
}
|
||||||
|
.tabBar .tabBar-item .active-indicator {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0.05rem;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 0.3rem;
|
||||||
|
height: 0.04rem;
|
||||||
|
border-radius: 0.02rem;
|
||||||
|
animation: indicatorAppear 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
||||||
|
}
|
||||||
|
.tabBar .item-img {
|
||||||
|
margin-bottom: 0.08rem;
|
||||||
|
position: relative;
|
||||||
|
width: 0.5rem;
|
||||||
|
height: 0.5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.tabBar .item-img img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
.tabBar .item-text {
|
||||||
|
font-size: 0.24rem;
|
||||||
|
color: #666;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
position: relative;
|
||||||
|
height: 0.3rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
/* 图标动画 */
|
||||||
|
.icon-bounce-enter-active {
|
||||||
|
animation: iconBounceIn 0.4s cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
||||||
|
}
|
||||||
|
.icon-bounce-leave-active {
|
||||||
|
animation: iconBounceOut 0.3s ease;
|
||||||
|
}
|
||||||
|
@keyframes iconBounceIn {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.3) rotate(-30deg);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(1.2) rotate(10deg);
|
||||||
|
}
|
||||||
|
70% {
|
||||||
|
transform: scale(0.9) rotate(-5deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1) rotate(0deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes iconBounceOut {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1) rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.5) rotate(30deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 文字动画 */
|
||||||
|
.text-slide-enter-active {
|
||||||
|
animation: textSlideIn 0.3s ease-out;
|
||||||
|
}
|
||||||
|
.text-slide-leave-active {
|
||||||
|
animation: textSlideOut 0.2s ease-in;
|
||||||
|
}
|
||||||
|
@keyframes textSlideIn {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(0.1rem);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes textSlideOut {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-0.1rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Tab点击动画 */
|
||||||
|
@keyframes tabClick {
|
||||||
|
0% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 指示器出现动画 */
|
||||||
|
@keyframes indicatorAppear {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-50%) scaleX(0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(-50%) scaleX(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 响应式调整 */
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.back-to-top {
|
||||||
|
right: 0.3rem;
|
||||||
|
bottom: 1.6rem;
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
}
|
||||||
|
.back-to-top .back-to-top-icon {
|
||||||
|
width: 0.4rem;
|
||||||
|
height: 0.4rem;
|
||||||
|
margin-bottom: 0.03rem;
|
||||||
|
}
|
||||||
|
.back-to-top .back-to-top-text {
|
||||||
|
font-size: 0.22rem;
|
||||||
|
}
|
||||||
|
.tabBar {
|
||||||
|
padding: 0.15rem 0;
|
||||||
|
}
|
||||||
|
.tabBar .tabBar-item {
|
||||||
|
padding: 0.08rem 0.12rem;
|
||||||
|
}
|
||||||
|
.tabBar .item-img {
|
||||||
|
width: 0.45rem;
|
||||||
|
height: 0.45rem;
|
||||||
|
}
|
||||||
|
.tabBar .item-text {
|
||||||
|
font-size: 0.22rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.back-to-top {
|
||||||
|
right: 0.5rem;
|
||||||
|
bottom: 2rem;
|
||||||
|
width: 1.2rem;
|
||||||
|
height: 1.2rem;
|
||||||
|
}
|
||||||
|
.back-to-top .back-to-top-icon {
|
||||||
|
width: 0.5rem;
|
||||||
|
height: 0.5rem;
|
||||||
|
margin-bottom: 0.05rem;
|
||||||
|
}
|
||||||
|
.back-to-top .back-to-top-text {
|
||||||
|
font-size: 0.26rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 深色模式支持 */
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.back-to-top {
|
||||||
|
background: linear-gradient(90deg, #275AFF 0%, #2EBDFA 100%);
|
||||||
|
box-shadow: 0 0.08rem 0.24rem rgba(138, 43, 226, 0.4);
|
||||||
|
}
|
||||||
|
.back-to-top:hover {
|
||||||
|
background: linear-gradient(90deg, #275AFF 0%, #2EBDFA 100%);
|
||||||
|
box-shadow: 0 0.12rem 0.36rem rgba(138, 43, 226, 0.6);
|
||||||
|
}
|
||||||
|
.tabBar {
|
||||||
|
background-color: rgba(30, 30, 30, 0.95);
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 0.05);
|
||||||
|
}
|
||||||
|
.tabBar .tabBar-item .item-text {
|
||||||
|
color: #b0b0b0;
|
||||||
|
}
|
||||||
|
.tabBar .tabBar-item:hover {
|
||||||
|
background-color: rgba(100, 181, 246, 0.08);
|
||||||
|
}
|
||||||
|
.tabBar .tabBar-item.active .item-text {
|
||||||
|
color: #64b5f6;
|
||||||
|
}
|
||||||
|
.tabBar .tabBar-item.active .active-indicator {
|
||||||
|
background: linear-gradient(90deg, #64b5f6, #81c784);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 安全区域适配(iPhone X及以上机型) */
|
||||||
|
@supports (padding: max(0px)) {
|
||||||
|
.back-to-top {
|
||||||
|
bottom: calc(1.5rem + env(safe-area-inset-bottom, 0));
|
||||||
|
}
|
||||||
|
.tabBar {
|
||||||
|
padding-bottom: calc(0.2rem + env(safe-area-inset-bottom, 0));
|
||||||
|
}
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.back-to-top {
|
||||||
|
bottom: calc(1.6rem + env(safe-area-inset-bottom, 0));
|
||||||
|
}
|
||||||
|
.tabBar {
|
||||||
|
padding-bottom: calc(0.15rem + env(safe-area-inset-bottom, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.back-to-top {
|
||||||
|
bottom: calc(2rem + env(safe-area-inset-bottom, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
438
f/web-kboss/src/views/H5/less/home/index.less
Normal file
438
f/web-kboss/src/views/H5/less/home/index.less
Normal file
@ -0,0 +1,438 @@
|
|||||||
|
.h5-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
/* 为iOS添加平滑滚动 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 页面切换动画 */
|
||||||
|
.fade-enter-active,
|
||||||
|
.fade-leave-active {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-enter-from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(0.2rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-0.2rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 返回顶部按钮样式 */
|
||||||
|
.back-to-top {
|
||||||
|
position: fixed;
|
||||||
|
right: 0.4rem;
|
||||||
|
bottom: 1.5rem;
|
||||||
|
/* 在底部导航栏上方 */
|
||||||
|
z-index: 999;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 1.1rem;
|
||||||
|
height: 1.1rem;
|
||||||
|
background: linear-gradient(90deg, #275AFF 0%, #2EBDFA 100%);
|
||||||
|
border-radius: 50%;
|
||||||
|
box-shadow: 0 0.08rem 0.24rem rgba(102, 126, 234, 0.4);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
user-select: none;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
|
||||||
|
/* 悬停效果 */
|
||||||
|
&:hover {
|
||||||
|
transform: translateY(-0.1rem);
|
||||||
|
box-shadow: 0 0.12rem 0.36rem rgba(102, 126, 234, 0.6);
|
||||||
|
background: linear-gradient(90deg, #275AFF 0%, #2EBDFA 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 激活效果 */
|
||||||
|
&:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 点击动画 */
|
||||||
|
&.clicked {
|
||||||
|
animation: pulse 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-to-top-icon {
|
||||||
|
width: 0.45rem;
|
||||||
|
height: 0.45rem;
|
||||||
|
color: white;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 0.04rem;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
stroke: currentColor;
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-to-top-text {
|
||||||
|
color: white;
|
||||||
|
font-size: 0.24rem;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1;
|
||||||
|
letter-spacing: 0.02rem;
|
||||||
|
text-shadow: 0 0.02rem 0.04rem rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 脉冲动画 */
|
||||||
|
@keyframes pulse {
|
||||||
|
0% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: scale(0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 返回顶部按钮动画 */
|
||||||
|
.fade-scale-enter-active,
|
||||||
|
.fade-scale-leave-active {
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-scale-enter-from,
|
||||||
|
.fade-scale-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.8) translateY(0.2rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TabBar 样式 */
|
||||||
|
.tabBar {
|
||||||
|
padding: 0.2rem 0;
|
||||||
|
background-color: rgba(255, 255, 255, 0.95);
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
box-shadow: 0 -0.02rem 0.2rem rgba(0, 0, 0, 0.08);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
-webkit-backdrop-filter: blur(10px);
|
||||||
|
border-top: 1px solid rgba(0, 0, 0, 0.05);
|
||||||
|
|
||||||
|
.tabBar-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
padding: 0.1rem 0.15rem;
|
||||||
|
border-radius: 0.3rem;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
/* 悬停效果 */
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(24, 144, 255, 0.08);
|
||||||
|
transform: translateY(-0.05rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 激活状态 */
|
||||||
|
&.active {
|
||||||
|
.item-text {
|
||||||
|
color: #1890ff;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 点击动画 */
|
||||||
|
&.click-animation {
|
||||||
|
animation: tabClick 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 激活指示器 */
|
||||||
|
.active-indicator {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0.05rem;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 0.3rem;
|
||||||
|
height: 0.04rem;
|
||||||
|
// background: linear-gradient(90deg, #1890ff);
|
||||||
|
border-radius: 0.02rem;
|
||||||
|
animation: indicatorAppear 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-img {
|
||||||
|
margin-bottom: 0.08rem;
|
||||||
|
position: relative;
|
||||||
|
width: 0.5rem;
|
||||||
|
height: 0.5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-text {
|
||||||
|
font-size: 0.24rem;
|
||||||
|
color: #666;
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
position: relative;
|
||||||
|
height: 0.3rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 图标动画 */
|
||||||
|
.icon-bounce-enter-active {
|
||||||
|
animation: iconBounceIn 0.4s cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-bounce-leave-active {
|
||||||
|
animation: iconBounceOut 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes iconBounceIn {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.3) rotate(-30deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: scale(1.2) rotate(10deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
70% {
|
||||||
|
transform: scale(0.9) rotate(-5deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1) rotate(0deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes iconBounceOut {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: scale(1) rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: scale(0.5) rotate(30deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 文字动画 */
|
||||||
|
.text-slide-enter-active {
|
||||||
|
animation: textSlideIn 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-slide-leave-active {
|
||||||
|
animation: textSlideOut 0.2s ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes textSlideIn {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(0.1rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes textSlideOut {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-0.1rem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tab点击动画 */
|
||||||
|
@keyframes tabClick {
|
||||||
|
0% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 指示器出现动画 */
|
||||||
|
@keyframes indicatorAppear {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-50%) scaleX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(-50%) scaleX(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式调整 */
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.back-to-top {
|
||||||
|
right: 0.3rem;
|
||||||
|
bottom: 1.6rem;
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
|
||||||
|
.back-to-top-icon {
|
||||||
|
width: 0.4rem;
|
||||||
|
height: 0.4rem;
|
||||||
|
margin-bottom: 0.03rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-to-top-text {
|
||||||
|
font-size: 0.22rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabBar {
|
||||||
|
padding: 0.15rem 0;
|
||||||
|
|
||||||
|
.tabBar-item {
|
||||||
|
padding: 0.08rem 0.12rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-img {
|
||||||
|
width: 0.45rem;
|
||||||
|
height: 0.45rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-text {
|
||||||
|
font-size: 0.22rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.back-to-top {
|
||||||
|
right: 0.5rem;
|
||||||
|
bottom: 2rem;
|
||||||
|
width: 1.2rem;
|
||||||
|
height: 1.2rem;
|
||||||
|
|
||||||
|
.back-to-top-icon {
|
||||||
|
width: 0.5rem;
|
||||||
|
height: 0.5rem;
|
||||||
|
margin-bottom: 0.05rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-to-top-text {
|
||||||
|
font-size: 0.26rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 深色模式支持 */
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.back-to-top {
|
||||||
|
background: linear-gradient(90deg, #275AFF 0%, #2EBDFA 100%);
|
||||||
|
box-shadow: 0 0.08rem 0.24rem rgba(138, 43, 226, 0.4);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: linear-gradient(90deg, #275AFF 0%, #2EBDFA 100%);
|
||||||
|
box-shadow: 0 0.12rem 0.36rem rgba(138, 43, 226, 0.6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabBar {
|
||||||
|
background-color: rgba(30, 30, 30, 0.95);
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 0.05);
|
||||||
|
|
||||||
|
.tabBar-item {
|
||||||
|
.item-text {
|
||||||
|
color: #b0b0b0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(100, 181, 246, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
.item-text {
|
||||||
|
color: #64b5f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active-indicator {
|
||||||
|
background: linear-gradient(90deg, #64b5f6, #81c784);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 安全区域适配(iPhone X及以上机型) */
|
||||||
|
@supports (padding: max(0px)) {
|
||||||
|
.back-to-top {
|
||||||
|
bottom: calc(1.5rem + env(safe-area-inset-bottom, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabBar {
|
||||||
|
padding-bottom: calc(0.2rem + env(safe-area-inset-bottom, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.back-to-top {
|
||||||
|
bottom: calc(1.6rem + env(safe-area-inset-bottom, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabBar {
|
||||||
|
padding-bottom: calc(0.15rem + env(safe-area-inset-bottom, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.back-to-top {
|
||||||
|
bottom: calc(2rem + env(safe-area-inset-bottom, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -72,13 +72,23 @@
|
|||||||
.journey-box .content .item-box,
|
.journey-box .content .item-box,
|
||||||
.latitude-box .content .item-box {
|
.latitude-box .content .item-box {
|
||||||
width: 48%;
|
width: 48%;
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 0.1rem;
|
border-radius: 0.1rem;
|
||||||
padding: 0.2rem;
|
padding: 0.2rem;
|
||||||
box-shadow: 0 0.02rem 0.08rem rgba(0, 0, 0, 0.05);
|
box-shadow: 0 0.02rem 0.08rem rgba(39, 90, 255, 0.08);
|
||||||
margin-bottom: 0.2rem;
|
margin-bottom: 0.2rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
background: linear-gradient(135deg, #f0f7ff 0%, #ffffff 100%);
|
||||||
|
border: 1px solid rgba(39, 90, 255, 0.1);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
.base-box .content .item-box:hover,
|
||||||
|
.journey-box .content .item-box:hover,
|
||||||
|
.latitude-box .content .item-box:hover {
|
||||||
|
box-shadow: 0 0.04rem 0.16rem rgba(39, 90, 255, 0.12);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
border-color: rgba(39, 90, 255, 0.2);
|
||||||
|
background: linear-gradient(135deg, #e8f2ff 0%, #ffffff 100%);
|
||||||
}
|
}
|
||||||
.base-box .content .item-box .item-title,
|
.base-box .content .item-box .item-title,
|
||||||
.journey-box .content .item-box .item-title,
|
.journey-box .content .item-box .item-title,
|
||||||
|
|||||||
@ -78,13 +78,22 @@
|
|||||||
|
|
||||||
.item-box {
|
.item-box {
|
||||||
width: 48%;
|
width: 48%;
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 0.1rem;
|
border-radius: 0.1rem;
|
||||||
padding: 0.2rem;
|
padding: 0.2rem;
|
||||||
box-shadow: 0 .02rem .08rem rgba(0, 0, 0, 0.05);
|
box-shadow: 0 .02rem .08rem rgba(39, 90, 255, 0.08);
|
||||||
margin-bottom: 0.2rem;
|
margin-bottom: 0.2rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
background: linear-gradient(135deg, #f0f7ff 0%, #ffffff 100%);
|
||||||
|
border: 1px solid rgba(39, 90, 255, 0.1);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: 0 .04rem .16rem rgba(39, 90, 255, 0.12);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
border-color: rgba(39, 90, 255, 0.2);
|
||||||
|
background: linear-gradient(135deg, #e8f2ff 0%, #ffffff 100%);
|
||||||
|
}
|
||||||
|
|
||||||
.item-title {
|
.item-title {
|
||||||
font-size: 0.26rem;
|
font-size: 0.26rem;
|
||||||
@ -107,8 +116,6 @@
|
|||||||
display: block;
|
display: block;
|
||||||
font-size: 0.156rem;
|
font-size: 0.156rem;
|
||||||
color: #666;
|
color: #666;
|
||||||
// margin-bottom: 0.08rem;
|
|
||||||
// line-height: 1.4;
|
|
||||||
|
|
||||||
.advantage-icon {
|
.advantage-icon {
|
||||||
width: 0.18rem;
|
width: 0.18rem;
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
<!-- 内容 -->
|
<!-- 内容 -->
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="item-box" v-for="(item, key) in baseData" :key="key">
|
<div class="item-box" v-for="(item, key) in baseData" :key="key">
|
||||||
|
|
||||||
<div class="item-title">{{ item.title }}</div>
|
<div class="item-title">{{ item.title }}</div>
|
||||||
<div class="item-description">{{ item.description }}</div>
|
<div class="item-description">{{ item.description }}</div>
|
||||||
|
|
||||||
|
|||||||
@ -13,13 +13,11 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="content" label="内容" min-width="180">
|
<el-table-column prop="content" label="内容" min-width="180">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="create_time" label="咨询时间" min-width="180">
|
<el-table-column prop="update_time" label="咨询时间" min-width="180">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="update_time" label="联系时间" min-width="180">
|
<el-table-column prop="update_time" label="反馈状态" min-width="180">
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="update_time" label="操作" min-width="180">
|
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button type="text" @click="handleEdit(scope.row)">已回复</el-button>
|
<el-button type="text" >{{ scope.row.feedback === '1' ? '已回复' : '未回复' }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user