main
wwl 2024-03-27 11:36:29 +08:00
parent 2f7c194a98
commit 820b1ea5cf
11 changed files with 279 additions and 47 deletions

View File

@ -77,6 +77,7 @@ const config = {
root: 'subpages/member',
pages: [
'index', // 会员中心
'qa-page', // 小程序自助服务Q&A
'point-detail', // 积分明细
'point-rule', // 积分规则
'member-level', // 会员等级

BIN
src/assets/hengjiantou.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
src/assets/share.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

View File

@ -141,17 +141,17 @@ function Home () {
}
}, [initState])
useEffect(() => {
if (shopInfo && VERSION_STANDARD) {
fetchWgts()
}
}, [shopInfo])
// useEffect(() => {
// if (shopInfo && VERSION_STANDARD) {
// fetchWgts()
// }
// }, [shopInfo])
useEffect(() => {
if (location && VERSION_STANDARD) {
fetchWgts()
}
}, [location])
// useEffect(() => {
// if (location && VERSION_STANDARD) {
// fetchWgts()
// }
// }, [location])
useShareAppMessage(async (res) => {
const { title, imageUrl } = await api.wx.shareSetting({ shareindex: 'index' })
@ -190,7 +190,7 @@ function Home () {
fetchLocation()
// 非云店
if (!VERSION_STANDARD) {
fetchWgts()
// fetchWgts()
} else {
fetchStoreInfo(location)
}
@ -307,6 +307,7 @@ function Home () {
setState((draft) => {
draft.swiperList = [...activeSwiper, ...list]
draft.goodList = list[0].goods || []
draft.loading = false
draft.activeInfo = {
...activity_info,
total_count,
@ -427,7 +428,7 @@ function Home () {
setState((draft) => {
draft.showRecommend = true
})
}, 400)
}, 1000)
if (!state.showBottom) {
}
}
@ -504,7 +505,7 @@ function Home () {
isTop={!isUpOperation}
isBlack
>
<View
{false && <View
className={classNames('home-body', {
'has-home-header': isShowHomeHeader && isWeixin
})}
@ -516,19 +517,19 @@ function Home () {
<SpRecommend className='recommend-block' info={likeList} />
</HomeWgts>
}
</View>
</View>}
{/* 小程序搜藏提示 */}
{isWeixin && <MCompAddTip />}
{/* {isWeixin && <MCompAddTip />} */}
{/* 开屏广告 */}
{isWeixin && !showAdv && <SpScreenAd />}
{/* {isWeixin && !showAdv && <SpScreenAd />} */}
{/* 优惠券包 */}
{VERSION_STANDARD && <SpCouponPackage />}
{/* {VERSION_STANDARD && <SpCouponPackage />} */}
<View className={classNames('content-box', {
'content-box-ovh': !isUpOperation
// 'content-box-ovh': !isUpOperation
})}>
<View className="swiper-wapper" onTouchStart={handleTouchStart} onTouchEnd={handleTouchEnd}>
{/* <ScrollView
@ -607,12 +608,12 @@ function Home () {
{!isUpOperation && <>
{currentIndex === 0 ? <View className="item-btns">
<View className="item-tit">{activeInfo.activity_name}</View>
<SpLogin newUser={isNewUser} onChange={handleApply}>
{activeInfo.end_time * 1000 >= Date.now() && <View className="item-btn" style={{ padding: '30rpx 60rpx' }} onClick={() => isLogin && handleApply()}>
<View className="item-btn-txt">{activeInfo.total_count ? '已报名' : '活动申请'}</View>
{/* <Image className="jiantou" mode="aspectFit" src={require('../assets/hengjiantou.gif')}></Image> */}
</View>}
</SpLogin>
{/* <SpLogin newUser={isNewUser} onChange={handleApply}> */}
{activeInfo.end_time * 1000 >= Date.now() && <View className="item-btn" style={{ padding: '30rpx 60rpx' }} onClick={() => handleApply()}>
<View className="item-btn-txt">{activeInfo.total_count ? '已报名' : '活动申请'}</View>
{/* <Image className="jiantou" mode="aspectFit" src={require('../assets/hengjiantou.gif')}></Image> */}
</View>}
{/* </SpLogin> */}
</View> :
<View className="item-img-box">
<View className="item-img-txt"> </View>
@ -641,7 +642,7 @@ function Home () {
))}
</ScrollView>}
{/* 推荐图片+商品 isUpOperation && */}
{isUpOperation && <>
{isUpOperation && showRecommend && <>
{recommend.length > 0 && recommend.map((_item, id) => <View key={id + '__item'} className="fadeIn" >
<SpImage width={windowWidth * 2} height={windowWidth >= 400 ? 920 : 800} mode='scaleToFill' src={_item.img} isShowMenuByLongpress={false} lazyLoad isNew >
{/* <View className="recommend_btn" style={{ [_item.postions]: '70rpx' }}>

View File

@ -3,7 +3,6 @@ import { View, Text, Input, Image, Button } from '@tarojs/components'
import Taro, { getCurrentInstance, useDidShow, useShareAppMessage } from '@tarojs/taro'
import { SpPage, SpHtml, SpCheckbox, SpLogin } from '@/components'
import { useSelector } from 'react-redux'
import { getActiveDetail } from '@/api/community'
import { useImmer } from 'use-immer'
import api from '@/api'
import dayjs from 'dayjs'
@ -33,19 +32,6 @@ export default function detail () {
// useDidShow(() => {
// }, [])
useEffect(() => {
if (isLogin && userInfo) {
getActiveDetail()
setState(draft => {
draft.formInfo = {
username: userInfo.username,
mobile: userInfo.mobile,
}
})
}
}, [userInfo, isLogin])
const getActiveDetail = async () => {
const { id: activity_id, alwaysBackUrl } = $instance.router.params
if (!activity_id) return
@ -77,9 +63,26 @@ export default function detail () {
})
}
useEffect(() => {
getActiveDetail()
}, [])
useEffect(() => {
if (isLogin && userInfo) {
setState(draft => {
draft.formInfo = {
username: userInfo.username,
mobile: userInfo.mobile,
}
})
}
}, [userInfo, isLogin])
const { isLoading, activeInfo = {}, visible, formInfo, checked, status, isShare, alwaysBackUrl } = state
const handleConfirm = async () => {
if (!isLogin || !userInfo) return
if (activeInfo.status) {
Taro.navigateTo({ url: '/pages/recommend/status?success=true&id=' + activeInfo.activity_id })
return

View File

@ -127,6 +127,7 @@ function MemberIndex (props) {
const { pointName } = useSelector((state) => state.sys)
// log.debug(`store userInfo: ${JSON.stringify(userInfo)}`)
const dispatch = useDispatch()
const { windowWidth } = Taro.getSystemInfoSync()
Taro.setNavigationBarColor({
frontColor: '#000000',
@ -710,26 +711,30 @@ function MemberIndex (props) {
<View className="member_con_left">
{/* /subpages/pointshop/list */}
<View className="member_con_item" onClick={isLogin && handleClickLink.bind(this, '/subpages/marketing/coupon-center')}>
<SpImage className="member_con_item_img" src="member/jifen.png" height={290} mode='aspectFill' isNew />
<View className="member_con_item_txt">积分兑换</View>
<SpImage className="member_con_item_img" src="member/jifen.png" height={windowWidth < 400 ? 200 : 220} mode='aspectFill' isNew />
<View className="member_con_item_txt">卡券与兑换</View>
</View>
<View className="member_con_item" onClick={isLogin && handleClickLink.bind(this, '/subpages/member/qa-page')}>
<SpImage className="member_con_item_img" src="member/wenti.png" height={windowWidth < 400 ? 200 : 220} mode='aspectFill' isNew />
<View className="member_con_item_txt">常见问题</View>
</View>
<View className="member_con_item" onClick={isLogin && handleClickLink.bind(this, '/pages/member/item-fav')}>
<SpImage className="member_con_item_img" src="member/shoucang.png" height={290} mode='aspectFill' isNew />
<SpImage className="member_con_item_img" src="member/shoucang.png" height={windowWidth < 400 ? 200 : 220} mode='aspectFill' isNew />
<View className="member_con_item_txt">个人收藏</View>
</View>
</View>
<View className='gap'></View>
<View className="member_con_right">
<View className="member_con_item" onClick={isLogin && handleClickLink.bind(this, '/subpages/member/user-info')}>
<SpImage className="member_con_item_img" src="member/geren.png" height={190} mode='aspectFill' isNew />
<SpImage className="member_con_item_img" src="member/geren.png" height={windowWidth < 400 ? 200 : 220} mode='aspectFill' isNew />
<View className="member_con_item_txt">个人信息</View>
</View>
<View className="member_con_item" onClick={handleClickLink.bind(this, '/marketing/pages/member/address')}>
<SpImage className="member_con_item_img" src="member/dizhi.png" height={190} mode='aspectFill' isNew />
<SpImage className="member_con_item_img" src="member/dizhi.png" height={windowWidth < 400 ? 200 : 220} mode='aspectFill' isNew />
<View className="member_con_item_txt">地址管理</View>
</View>
<View className="member_con_item" onClick={isLogin && handleClickLink.bind(this, '/subpage/pages/trade/invoice-record')}>
<SpImage className="member_con_item_img" src="member/fapiao.png" height={190} mode='aspectFill' isNew />
<SpImage className="member_con_item_img" src="member/fapiao.png" height={windowWidth < 400 ? 200 : 220} mode='aspectFill' isNew />
<View className="member_con_item_txt">发票管理</View>
</View>
</View>

View File

@ -310,14 +310,14 @@
justify-content: space-between;
&_left {
display: grid;
grid-template-rows: repeat(2, auto);
grid-template-rows: repeat(3, auto);
grid-gap: 10px;
}
&_item {
position: relative;
&_txt {
position: absolute;
left: 20px;
right: 20px;
bottom: 30px;
color: #fff;
font-size: 32px;

View File

@ -0,0 +1,55 @@
const data = [{
title: "购物相关", isOpen: false, content: [{ subTit: "如何选择鞋子尺码?", subCon: "先量脚长再看尺码会更准确喔。如果您平日穿着的鞋履是42码或42码以下您可以按照正码选购如果您平日穿着的鞋履是42码以上建议您可选小一码。在此判断标准上如您的脚背高、脚宽或者计划搭配袜子穿建议您选择大一码的鞋子或如您打算购买带有羊毛衬里的拖鞋搭配袜子穿着也建议您选择大一码的鞋子。" },
{ subTit: "如何测量脚长?", subCon: "建议您赤脚,脚后紧靠墙面站立,脚下放一把卷尺;读取最长脚趾长度以(毫米为单位)做为依据来选鞋子尺码。" },
{ subTit: "鞋子的窄版和常规版是指什么?", subCon: "一般来说我们40码以下的鞋子为窄版40码以上的鞋子为常规版从解剖学上来说我们常规版的设计更加适合男性的足部构造窄版设计更加适合女性的足部构造。除此之外我们的部分款式39码也有常规版可选您可以点击具体商品的详情页面查看相关信息进行选购。" },
{ subTit: "如何区分常规软木鞋床和软底软木鞋床?", subCon: `我们的软底鞋床印有"Soft-footbed"的蓝色标记,软底鞋床有特殊材料制成的填充物,该材料由数以百万计的微小气泡组成,可以有效缓解由行走或站立带来的疲劳感;常规款的鞋床标记为黑色或金色,环保鞋款鞋床标记则为绿色。` },
{ subTit: "所有BIRKENSTOCK鞋都是男女同款吗", subCon: `视具体鞋款而定我们的大多数鞋款是不分性别皆可穿着的例如Arizona, Boston……某些特定鞋款是在产品设计时就结合了女性的造型时尚和生理学特征例如MayariMadrid……详情可参考具体的产品页面。` },
{ subTit: '为什么一些鞋子看起来款式和颜色都一样,但是价格不同?', subCon: `同款同色的BIRKENSTOCK鞋履可能会因材质不同而有价格略有差异视具体情况而定。` },
{ subTit: '什么是环保商品?所有款式都有环保材质的吗?', subCon: `BIRKENSTOCK 一直秉持环保生产的理念环境保护一直是我们的的首要任务我们使用的绝大部分原料皆为纯天然材料软木、天然乳胶、黄麻等等。BIRKENSTOCK 环保鞋是指在生产过程中完全不使用任何动物性材料,而是有意识地只使用人工合成材料和天然材料,在保证 BIRKENSTOCK 鞋款的功能性和时尚性的同时,打造一个完全动物友好的产品系列。` },
{ subTit: `BIRKENSTOCK鞋防水吗`, subCon: `我们有 EVA 材质制成的防水款式。但大多数款式都不能浸泡在水中,因为过度浸泡会损害密封材料的完整性。` },
{ subTit: `你网站上的所有商品在商店里也有售吗?`, subCon: `线上官方小程序的商品种类,与其他官方渠道可能略有不同,请以实际情况为准。` },
{ subTit: '有固定的促销活动和新品上架时间吗?', subCon: `建议您添加我们的微信官方小程序关注BIRKENSTOCK微信公众号、小红书官方账号、新浪官方微博及时掌握新品上架或促销活动第一手信息。` },
{ subTit: '港澳台及海外地区是否可以购买?', subCon: `我们的配送地址范围为中国大陆地区,暂不支持港澳台及海外地区的配送。` },
{ subTit: `可以使用哪些付款方式?`, subCon: `您可以使用微信支付,目前我们暂不支持其他支付方式。` },
{ subTit: `发货时效和发货快递`, subCon: `您的订单将通过顺丰快递从上海发出顺丰快递服务范围不到的地区我们会为您选用其他的快递服务商。根据地点不同配送所花费的时间也有所差异一般送货周期为2-5天偏远地区送货周期可能会有相应延长。由于物流配送中的不确定性请您谅解我们无法承诺绝对准确的送达时间。` },
{ subTit: `我收到鞋子了,看起来都被刮伤了?`, subCon: `我们的部分特定皮革鞋面是经过油脂涂覆处理的,这能使皮革本身呈现出更加有质感的外观和丰富的色彩变化。经过油脂处理的皮革鞋面上出现表面划痕或看起来像的划痕是正常的,随着皮革在穿着过程中与您足部的磨合,它们会自行淡化。您也可以尝试用手指轻拭,因为您的自然体温可以帮助皮革重新分配其表面的油脂涂层,从而达到柔化痕迹的效果。如果您更喜欢带有统一颜色的外观,我们建议您可以选择磨毛皮、光滑皮革或合成材料制作的鞋履。` },
{ subTit: `怎样进行日常护理清洁?`, subCon: `不同材质的鞋履的护理方式均有所不同建议您关注我们的官方微信公众号或小红书账号”BIRKENSTOCK"并查看相关鞋履的护理、清洁信息。` }]
},
{
title: '订单相关', isOpen: false, content: [{ subTit: "我可以修改订单吗?", subCon: `如果您单次购买多件商品,可在购物车内勾选相关商品一并下单,我们将为你按照一笔订单同时发货。对于来自同一个账户的分时不同批次多订单,我们不能将多张订单进行合并,也不能将多张订单合并发货;另外您一旦点击确认并提交订单后,我们客服将无法修改订单内容,包括商品信息、总价金额等等。` },
{ subTit: '我未付款的订单可以保留多久?', subCon: `若您在提交订单后未在规定的时间内及时付款则在该时限届满后已提交的相关订单将被自动取消。除非本商城的商品详情页面另有不同的说明或该商品使用的销售规则或活动规则另有不同说明如果我们在收到您确认提交订单后30分钟内没有收到全额付款您的该笔订单将被自动取消。` },
{ subTit: `已经发货了,我能取消订单吗?`, subCon: `如果您的订单已经提交且尚未支付,您可以自行取消订单;对于已经发货的订单,您可以在收到商品后七天之内,且商品保持完好的情况下申请无理由退货。` },
{ subTit: `当天购物会当天发货吗?`, subCon: `一般情况下当日15:00之前付款的订单可以当天发货15:00之后的订单为您安排隔日发货。` },
{ subTit: `哪里可以看到发货?为什么很久没收到货品?`, subCon: `您可以登录BIRKENSTOCK微信小程序商城在“我的订单”中找到需要查询的订单订单详情中会有相关物流公司的物流信息。您可直接登陆到相关的物流公司网站查询物流信息或联系在线客服为您进行物流查询服务。为了顾客能尽快收到货品一般情况下我们在您付款后24小时左右会为您安排发货周六、周日均正常发货。而在大型促销活动期间发货会有稍许延迟在已发货的情况下如您长时间未收到货请耐心等待或与物流公司联系。如遇到特殊情况(仓库盘点,节假日)、天气、人力等因素导致延迟发货或延长送货时间,我们将会提前以公告或其他形式告知。` },
{
subTit: `为什么我的订单没发货?`, subCon: `您的订单未发货可能有以下原因:
(1)您的订单中可能有尚待确认的信息所以订单处于保留状态通常在您下单后我们的客服会第一时间与您取得联系请您保持手机畅通一旦确认后将马上进行发货处理;
(2)可能您的订单仓库正在发货订单信息还没有更新成功还请您耐心等待`},
{ subTit: '商品已经发货了,但是我需要更改收货地址,可以吗?', subCon: `我们会联系快递尝试修改地址,已经发货的订单需要到中转站点后才能知晓修改是否成功,相对比较耗时,建议您可以安排拒收,我们也会通知物流进行包裹拦截。若您仍需要此款商品,建议重新下单,非常抱歉由此给您带来的不便,我们会尽快为您跟进处理新的订单。` },
{ subTit: '如果在收到商品时发现错发或者质量有问题的情况怎么办?', subCon: `"请与快递沟通在签收之前检查外包装是否破损以及打开包装验视商品本身,如果商品发生错发或有任何质量问题,请保留相关单据完整并第一时间联系我们 服人员帮您进行后续操作。"` },
{ subTit: '在BIRKENSTOCK小程序官方店购买的商品可以在实体店铺内退换货吗', subCon: '非常抱歉如您对BIRKENSTOCK小程序官方店购买的商品有任何问题请联系在线客服。实体店铺不受理在线上购买商品的退货同样BIRKENSTOCK小程序官方店也不受理在实体店铺购买商品的退货。' },
{ subTit: '退换货政策', subCon: `所有退换商品的包装及鞋子在符合退换货的条件下可进行退换货。详情请查看BIRKENSTOCK勃肯退换货政策word文档加链接` },
{ subTit: '收货后我还可以通过支付差价来换不同的款式吗?', subCon: `非常抱歉,我们只有只能对相同的商品更换不同的尺寸的服务。不提供不同款式的换货服务,如果您的订单已经提交且尚未支付,您可以自行取消订单,并重新下单您心仪的商品。` },
{ subTit: '我可以在同一个退货包中包含多个订单吗?', subCon: `为了能够及时处理您的退货和退款,我们建议您同一订单中的多件商品可以使用同一退货包裹退回; 多个订单中的商品请分别按照原订单中的数量及型号退回,请勿混合退回多个订单中的商品。` },
{ subTit: '我的退货跟踪显示已送达,但我尚未收到退款。我能做什么?', subCon: `我们在收到您的退货要求后会及时为您发起退款流程通常所需时间为1-3周不定如果超出该时间范围请及时联系我们的在线客服。` },
{ subTit: `收到退款需要多长时间?`, subCon: `我们在收到您的退货后会及时为您处理退款流程通常所需时间为1-3周如果超出该时间范围请联系我们的在线客服。` }]
},
{
title: '发票相关', isOpen: false, content: [{ subTit: '可以开具发票吗?', subCon: `可以。如有需要,请您在订单结算时选择“开发票”并在备注栏中正确填写发票抬头,发票金额为您实际支付的商品金额。折扣与快递费用不开具发票,请您谅解。` },
{ subTit: '可以指定开票日期吗?', subCon: `很抱歉,根据税务相关规定我们不提供指定开票日期的服务。` },
{ subTit: `退货后发票怎么办?`, subCon: `订单发生退货,您原来的发票会自动作废,无法再下载使用。如您购买多件商品后申请退货,在退货完成后,您的电子发票信息将会自动更新,在您的历史订单中下载发票。` },
{ subTit: `可以补开发票吗?`, subCon: `可以,您可以通过联系我们的在线客服申请开具已完成订单的发票。` },
{ subTit: `发票抬头如何修改?`, subCon: `如您购买的商品还未付款建议您在有库存的情况下重新下单填并写正确的开票信息。如您购买的商品全部发货未满7天客服查询到您的订单处于未完成状态目前还不能为您更改发票相关信息。待您的订单发货时长达到7天后可联系客服办理。如您购买的商品发货时间达到7天请您提供正确的相关信息给到客服客服会在1-5个工作日为您修改正确的发票抬头并更新在您的订单信息内。` }]
},
{
title: '意见反馈', isOpen: false, content: [{ subTit: `如何反馈其他问题?`, subCon: '如果您对本平台显示的材料或者购物过程中又任何疑虑或异议或希望提供建议和意见您可以联系我们的客服021-62716091或者写信给我们bscn_mp_store@birkenstock.com。' }]
}
]
export default data

View File

@ -0,0 +1,3 @@
export default {
navigationBarTitleText: '小程序自助服务Q&A',
}

View File

@ -0,0 +1,78 @@
import React from 'react'
import { View, Text, ScrollView } from '@tarojs/components'
import { AtAccordion, AtIcon } from 'taro-ui'
import { SpPage, SpHtml } from '@/components'
import { useImmer } from 'use-immer'
import introData from './qa-data'
import { classNames } from '@/utils'
import './qa-page.scss'
const initState = {
introList: introData,
scrollTop: 0,
}
export default function qaPage () {
const [state, setState] = useImmer(initState)
const { introList, scrollTop } = state
return (
<SpPage className="page-member-qa">
<ScrollView scrollY scrollWithAnimation showScrollbar={false} scrollTop={scrollTop} className="qa-page-scrool">
{introList.length ? introList.map((item, index) => <View className={classNames('sp-accordion')} key={`item__${index}`}>
<AtAccordion
open={item.isOpen}
isAnimation={false}
onClick={() => {
setState((draft) => {
draft.introList = draft.introList.map((v, i) => {
v.isOpen = false
return v
})
draft.introList[index].isOpen = !item.isOpen
draft.scrollTop = 0
})
// if (!item.isOpen) {
// setState((draft) => {
// draft.scrollTop = 1042 + Math.random() / 10
// })
// }
}}
title={item.title}
>
{/* <SpHtml content={item.content} /> */}
<View className="content">
{item.content.map((v, i) => (
<View className="content-item" key={i + '_content'}>
<View className="content-item-title">
{v.subTit}
{/* <Text className="title"></Text> */}
</View>
<View className="title-desc">{v.subCon}</View>
</View>
))}
</View>
</AtAccordion>
<View onClick={() => {
setState((draft) => {
draft.introList = draft.introList.map((v, i) => {
v.isOpen = false
return v
})
draft.introList[index].isOpen = !item.isOpen
})
// if (!item.isOpen) {
// setState((draft) => {
// draft.scrollTop = 1042 + Math.random() / 10
// })
// }
}}>
{item.isOpen ? <AtIcon value='subtract' size='16' color='#000' /> :
<AtIcon value='add' size='16' color='#000' />}
{item.isOpen ? <></> : <View className="line"></View>}
</View>
</View>) : <View style={{ height: `calc(100% - 380px)` }}></View>}
</ScrollView>
</SpPage>
)
}

View File

@ -0,0 +1,86 @@
.page-member-qa {
// height: 95vh;
// overflow: hidden;
.sp-page-body {
position: relative;
margin-top: 30rpx;
/* prettier-ignore */
border-top: 1PX solid #9e9e9e80;
}
.scroll-box {
// @include page-scroll(calc(var(--nav-height) + 150px), 40px);
// height: calc(var(--nav-height) + 150px);
margin-bottom: 10px;
box-sizing: border-box;
flex-direction: column;
display: flex;
flex: 1;
overflow-y: scroll;
}
.qa-page-scrool {
--height: calc(var(--status-bar-height) + #{$tabbar-height} + var(--area-bottom-height));
overflow: hidden;
height: calc(100vh - var(--height));
}
.sp-accordion {
position: relative;
&:last-child {
margin-bottom: 40rpx;
}
.at-accordion__header {
padding: 30px 40px;
color: #000;
&::after {
border: none;
// border-bottom: 1px solid #9e9e9e80;
}
.at-accordion__info__title {
font-size: 30px;
}
.at-accordion__arrow {
display: none;
}
}
.at-accordion__content {
&::after {
border: none;
// border-bottom: 1px solid #9e9e9e80;
}
}
.at-accordion__body {
padding: 0 40px;
padding-bottom: 30px;
.content {
&-item {
&-title {
font-size: 30px;
font-weight: bold;
margin-bottom: 10px;
}
.title-desc {
margin-bottom: 40px;
}
}
}
}
.at-icon {
position: absolute;
z-index: 0;
right: 40px;
top: 54px;
transform: translateY(-50%);
transition: all 0.2s ease-in-out;
}
.line {
display: block;
position: absolute;
width: 100%;
height: 1px;
background: #9e9e9e80;
top: 104px;
right: 0;
left: 0;
transition: all 0.2s ease-in-out;
}
}
}