1.1岗位列表等新版本

This commit is contained in:
2026-08-11 11:54:35 +08:00
parent 1e103627f8
commit d556170969
26 changed files with 2234 additions and 1267 deletions
+88 -2
View File
@@ -33,12 +33,16 @@ export interface JobListItem {
id: string
/** 岗位标题 */
title: string
/** 薪资描述 */
salary?: string
/** 公司全称 */
companyName: string
/** 公司简称 */
companyShortName: string
/** 公司类型(如"上市企业" */
companyType: string
/** 公司Logo URL */
companyLogoUrl?: string
/** 公司标签列表(如 ["新能源汽车", "乘用车制造", "10000人以上"] */
companyTags: string[]
/** 地区名称 */
@@ -51,13 +55,19 @@ export interface JobListItem {
sourceUrl: string
/** 是否已收藏 */
isFavorite: boolean
/** 投递状态(null=未投递,0=已投递 1=面试中 2=有Offer 3=未通过 4=已结束) */
applicationStatus?: number | null
/** 岗位状态:0=有效 1=已下架 2=已过期 */
status: number
/** 发布日期 */
expireAt?: string | null
/** 脚本名字 */
pyname?: string
/** 综合匹配分(0-100 */
matchScore: number
/** 匹配度详情 */
matchDetail: MatchDetail
/** 招聘分类:0=社招 1=校招 2=实习 */
/** 招聘分类:0=社招 1=校招 2=实习 3=其他 */
recruitCategory?: number
/** 学历要求 0=不限 1=大专 2=本科 3=硕士 4=博士 */
education?: number
@@ -97,12 +107,62 @@ export interface JobListParams {
statusFilter?: number[]
/** 搜索关键词 */
keyword?: string
/** 招聘分类 0=招 1=实习 2=社招 3=其他 */
/** 招聘分类 0=招 1=校招 2=实习 3=其他 */
recruitCategory?: number
/** 排除岗位ID列表(用于推荐时排除已推荐过的) */
excludeJobIds?: number[]
/** 公司类型列表(上市企业、独角兽、国企等,可多选) */
companyTypes?: string[]
/** 学历要求列表 0=不限 1=大专 2=本科 3=硕士 4=博士(可多选) */
educations?: number[]
/** 发布开始时间(ISO 8601格式,如 "2026-08-10T21:00:00Z" */
publishStartTime?: string
/** 发布截止时间(ISO 8601格式,如 "2026-08-11T21:00:00Z" */
publishEndTime?: string
}
// ==================== 热门推荐接口 ====================
/** 热门行业项 */
export interface HotIndustryItem {
id: number
name: string
}
/** 热门岗位项 */
export interface HotCategoryItem {
id: number
name: string
}
/** 热门城市项 */
export interface HotCityItem {
code: string
name: string
}
/**
* 获取热门推荐行业
* GET /job/industry/hot
*/
export function fetchHotIndustries() {
return request.get<any, ApiResult<HotIndustryItem[]>>('/job/industry/hot')
}
/**
* 获取热门推荐岗位
* GET /job/category/hot
*/
export function fetchHotCategories() {
return request.get<any, ApiResult<HotCategoryItem[]>>('/job/category/hot')
}
/**
* 获取热门推荐城市
* GET /job/city/hot
*/
export function fetchHotCities() {
return request.get<any, ApiResult<HotCityItem[]>>('/job/city/hot')
}
// ==================== 求职意向 ====================
@@ -156,6 +216,32 @@ export function fetchJobList(params: JobListParams = {}) {
})
}
/**
* 获取筛选岗位数量
* POST /job/list/count
* @param params 与岗位列表相同的筛选参数
*/
export function fetchJobListCount(params: JobListParams = {}) {
return request.post<any, ApiResult<number>>('/job/list/count', {
pageNum: params.pageNum ?? 1,
pageSize: params.pageSize ?? 10,
...params,
})
}
/**
* 深度匹配岗位列表
* POST /job/list/match
* @param params 与岗位列表相同的筛选参数
*/
export function fetchJobListMatch(params: JobListParams = {}) {
return request.post<any, ApiResult<JobPageData>>('/job/list/match', {
pageNum: params.pageNum ?? 1,
pageSize: params.pageSize ?? 15,
...params,
})
}
// ==================== 收藏列表 ====================
/** 收藏列表请求参数 */
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

@@ -56,15 +56,11 @@
// ==================== 下拉面板 ====================
&__panel {
position: absolute;
top: calc(100% + 0.06rem);
left: 0;
width: 3.6rem;
background: $bg-white;
border: 1px solid $border-color;
border-radius: 0.1rem;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
z-index: 100;
padding: 0.1rem;
// 只显示一栏时缩窄面板
@@ -57,15 +57,11 @@
// ==================== 下拉面板 ====================
&__panel {
position: absolute;
top: calc(100% + 0.06rem);
left: 0;
width: 4.8rem;
background: $bg-white;
border: 1px solid $border-color;
border-radius: 0.1rem;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
z-index: 100;
padding: 0.1rem;
// 只显示一栏时缩窄面板
+377 -264
View File
@@ -1,4 +1,4 @@
// 会员弹窗样式(新版)
// 会员弹窗样式 — 新版黑金左右布局
@use '../variables' as *;
// 遮罩层
@@ -10,82 +10,163 @@
display: flex;
align-items: center;
justify-content: center;
// 扫码支付弹窗的遮罩层级更高
&--qrcode {
z-index: 2400;
}
font-size: 0.14rem;
}
// 弹窗主体
// 弹窗主体 — 左右布局
.member-dialog {
box-sizing: border-box;
position: relative;
display: flex;
flex-direction: column;
align-items: flex-start;
padding: 0.24rem 0.32rem;
gap: 0.24rem;
width: 4.8rem;
background: linear-gradient(180deg, #EDF9FA 0%, #FFFFFF 20.63%);
border: 1px solid #F0F0F0;
box-shadow: 0 0 0.16rem rgba(0, 0, 0, 0.05);
border-radius: 0.12rem;
width: 6.49rem;
height: 4rem;
border-radius: 0.16rem;
box-shadow: 0 0.025rem 0.05rem rgba(60, 38, 13, 0.22);
border: 0.00625rem solid #D9B873;
font-size: 0.14rem;
// 扫码支付弹窗变体
&--qrcode {
// ==================== 左侧黑金权益栏 ====================
&__left {
position: relative;
width: 2rem;
height: 100%;
background: linear-gradient(180deg, #0F001E 0%, #1A0B09 18.09%, #452206 66.19%, #2C1500 100%);
padding: 0.24rem 0.20rem;
box-sizing: border-box;
overflow: hidden;
flex-shrink: 0;
border-radius: 0.16rem 0 0 0.16rem;
}
// 装饰线条背景
&__left-deco {
position: absolute;
width: 4.47rem;
height: 2.39rem;
left: -0.52rem;
top: -0.75rem;
background: radial-gradient(ellipse at center, rgba(255, 230, 175, 0.08) 0%, transparent 70%);
pointer-events: none;
}
&__left-title {
position: relative;
font-weight: 600;
font-size: 0.16rem;
line-height: 0.21rem;
color: #FFE9A6;
margin: 0 0 0.06rem;
}
&__left-subtitle {
position: relative;
font-weight: 330;
font-size: 0.12rem;
line-height: 0.16rem;
color: #F4E5CC;
margin: 0 0 0.2rem;
}
// ==================== 左栏权益卡片 ====================
&__benefits {
position: relative;
display: flex;
flex-direction: column;
gap: 0.16rem;
}
&__benefit-card {
box-sizing: border-box;
width: 1.56rem;
height: 0.6rem;
border: 0.00625rem solid #9C6D2D;
border-radius: 0.08rem;
display: flex;
align-items: center;
padding: 0 0.12rem;
gap: 0.12rem;
}
&__benefit-icon {
width: 0.32rem;
height: 0.32rem;
background: #4C3517;
border: 0.00625rem solid #D5A64A;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
svg {
width: 0.16rem;
height: 0.16rem;
}
}
&__benefit-info {
display: flex;
flex-direction: column;
gap: 0.04rem;
}
&__benefit-name {
font-weight: 450;
font-size: 0.14rem;
line-height: 0.19rem;
color: #FFE6AF;
}
&__benefit-desc {
font-weight: 330;
font-size: 0.1rem;
line-height: 0.13rem;
color: #F4E5CC;
}
// ==================== 左右分割金边 ====================
&__divider {
width: 0.01rem;
height: 100%;
background: #D6B15B;
flex-shrink: 0;
}
// ==================== 右侧内容区 ====================
&__right {
flex: 1;
background: linear-gradient(179.38deg, #FCEDD8 0.54%, #FEFBF5 19.09%);
display: flex;
flex-direction: column;
padding: 0.2rem 0.24rem;
box-sizing: border-box;
position: relative;
border-radius: 0 0.16rem 0.16rem 0;
}
// ==================== 顶部标题行 ====================
&__header {
display: flex;
justify-content: space-between;
align-items: flex-start;
width: 100%;
align-items: center;
margin-bottom: 0.2rem;
}
&__header-left {
display: flex;
flex-direction: column;
gap: 0.04rem;
&__title {
font-weight: 600;
font-size: 0.18rem;
line-height: 0.24rem;
color: #1F160F;
margin: 0;
}
&__header-right {
&__header-actions {
display: flex;
align-items: center;
gap: 0.16rem;
}
&__title {
font-weight: 620;
font-size: 0.18rem;
line-height: 0.24rem;
color: $text-dark;
margin: 0;
}
&__subtitle {
font-weight: 330;
font-size: 0.12rem;
line-height: 0.16rem;
color: $text-middle;
margin: 0;
}
&__contact {
font-weight: 330;
font-size: 0.12rem;
line-height: 0.16rem;
color: $text-light;
cursor: pointer;
&:hover {
color: $text-middle;
}
}
// 联系客服外层包装(用于定位二维码弹出框)
// 联系客服
&__contact-wrap {
position: relative;
display: inline-flex;
@@ -96,7 +177,18 @@
}
}
// 联系客服二维码弹出框
&__contact {
font-weight: 330;
font-size: 0.12rem;
line-height: 0.16rem;
color: #2F343B;
cursor: pointer;
&:hover {
color: #1F160F;
}
}
&__contact-qr {
display: none;
position: absolute;
@@ -122,7 +214,6 @@
}
}
// 二维码弹出框底部箭头
&__contact-qr-arrow {
position: absolute;
bottom: -0.07rem;
@@ -133,7 +224,6 @@
border-left: 0.08rem solid transparent;
border-right: 0.08rem solid transparent;
border-top: 0.08rem solid $bg-white;
filter: drop-shadow(0 0.02rem 0.02rem rgba(0, 0, 0, 0.05));
}
&__close {
@@ -143,355 +233,378 @@
align-items: center;
justify-content: center;
font-size: 0.14rem;
color: $text-middle;
color: #2F343B;
cursor: pointer;
&:hover {
color: $text-dark;
color: #1F160F;
}
}
// ==================== 套餐选择区域 ====================
&__plans {
display: flex;
gap: 0.13rem;
width: 100%;
gap: 0.2rem;
margin-bottom: 0.2rem;
}
&__plan-card {
box-sizing: border-box;
width: 1.2rem;
height: 1.4rem;
background: #FFFDF8;
border: 1px solid #E7C991;
border-radius: 0.08rem;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 0.12rem 0.16rem;
gap: 0.04rem;
width: 1.3rem;
height: 1.01rem;
background: $bg-white;
border: 1px solid #F0F0F0;
border-radius: 0.08rem;
gap: 0.08rem;
cursor: pointer;
transition: border-color 0.2s;
position: relative;
transition: border-color 0.2s, box-shadow 0.2s;
&:hover {
border-color: $accent;
border-color: #B77D24;
}
// 选中状态 — 粗边框
// 选中
&--active {
border: 3px solid $accent;
background: linear-gradient(180deg, #FFF4D8 0%, #FDF9F1 100%);
border: 2px solid #B77D24;
box-shadow: 0 0.04rem 0.08rem rgba(183, 125, 36, 0.2);
}
}
&__plan-recommend {
// 推荐角标
&__plan-badge {
position: absolute;
top: -0.1rem;
left: 10%;
top: -0.12rem;
left: 50%;
transform: translateX(-50%);
white-space: nowrap;
background: $accent;
color: $bg-white;
font-size: 0.1rem;
padding: 0.02rem 0.08rem;
border-radius: 0.08rem;
font-weight: 620;
background: #C28A2F;
border: 0.00625rem solid #F0D091;
border-radius: 0.075rem;
padding: 0.04rem 0.12rem;
font-weight: 600;
font-size: 0.12rem;
line-height: 0.16rem;
color: #FFFFFF;
}
&__plan-name {
font-weight: 450;
font-weight: 600;
font-size: 0.14rem;
line-height: 0.19rem;
text-align: center;
color: $text-dark;
color: #1F160F;
}
&__plan-price {
display: flex;
align-items: flex-end;
align-items: baseline;
justify-content: center;
gap: 0.04rem;
padding: 0.04rem 0;
}
&__plan-price-symbol {
font-weight: 450;
font-weight: 600;
font-size: 0.14rem;
line-height: 0.19rem;
color: $text-dark;
color: #1F160F;
}
&__plan-price-num {
font-weight: 630;
font-size: 0.24rem;
line-height: 0.18rem;
color: $text-dark;
font-weight: 600;
font-size: 0.28rem;
line-height: 0.37rem;
color: #1F160F;
}
&__plan-original-price {
&__plan-original {
font-weight: 330;
font-size: 0.12rem;
line-height: 0.16rem;
text-decoration: line-through;
color: $text-light;
color: #7A7D82;
margin-left: 0.04rem;
}
&__plan-daily {
&__plan-tag {
font-weight: 330;
font-size: 0.12rem;
line-height: 0.16rem;
text-align: center;
color: $accent;
color: #3B2A1E;
}
// ==================== 会员权益区域 ====================
&__benefits {
width: 100%;
}
&__benefits-title {
font-weight: 450;
font-size: 0.14rem;
line-height: 0.19rem;
color: $text-dark;
margin: 0 0 0.16rem;
}
&__benefits-cards {
display: flex;
gap: 0.13rem;
width: 100%;
}
&__benefit-card {
box-sizing: border-box;
// ==================== 支付方式选择(步骤一) ====================
&__step-pay {
flex: 1;
display: flex;
align-items: center;
padding: 0.12rem 0.16rem;
gap: 0.1rem;
background: $bg-white;
border: 1px solid #AEE6EA;
border-radius: 0.08rem;
}
&__benefit-icon {
width: 0.4rem;
height: 0.4rem;
display: flex;
align-items: center;
justify-content: center;
background: #EDF9FA;
border-radius: 50%;
flex-shrink: 0;
svg {
width: 0.24rem;
height: 0.24rem;
}
}
&__benefit-info {
display: flex;
flex-direction: column;
gap: 0.04rem;
}
&__benefit-name {
font-weight: 450;
font-size: 0.14rem;
line-height: 0.19rem;
color: $accent;
}
&__benefit-desc {
font-weight: 330;
font-size: 0.12rem;
line-height: 0.16rem;
color: $text-middle;
}
// ==================== 支付方式选择 ====================
&__payment {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
&__payment-section {
margin-bottom: 0.16rem;
}
&__payment-label {
font-weight: 450;
font-size: 0.14rem;
line-height: 0.19rem;
color: $text-dark;
color: #1F160F;
display: block;
margin-bottom: 0.08rem;
}
&__payment-methods {
display: flex;
align-items: center;
gap: 0.24rem;
}
&__payment-item {
box-sizing: border-box;
width: 1.88rem;
height: 0.58rem;
background: #FFFDF8;
border: 1px solid #E7C991;
border-radius: 0.08rem;
display: flex;
align-items: center;
padding: 0.04rem 0.08rem;
gap: 0.06rem;
border-radius: 0.04rem;
padding: 0 0.2rem;
gap: 0.12rem;
cursor: pointer;
transition: background 0.2s;
position: relative;
transition: border-color 0.2s;
svg {
width: 0.16rem;
height: 0.16rem;
width: 0.32rem;
height: 0.32rem;
flex-shrink: 0;
}
// 微信选中态
&--wechat-active {
background: #EBFEF4;
}
// 支付宝选中态
&--alipay-active {
background: #EBF3FF;
// 选中态
&--active {
border-color: #B77D24;
}
}
&__payment-text {
font-weight: 620;
font-size: 0.12rem;
line-height: 0.18rem;
font-weight: 600;
font-size: 0.13rem;
line-height: 0.17rem;
color: #1F160F;
}
&--wechat {
color: #07C160;
}
// 选中圆圈
&__payment-radio {
box-sizing: border-box;
width: 0.14rem;
height: 0.14rem;
background: #FFFDF8;
border: 1px solid #E7C991;
border-radius: 50%;
margin-left: auto;
display: flex;
align-items: center;
justify-content: center;
&--alipay {
color: #1677FF;
.member-dialog__payment-item--active & {
border-color: #C28A2F;
}
}
// ==================== 购买按钮 ====================
&__payment-radio-inner {
width: 0.08rem;
height: 0.08rem;
background: #C28A2F;
border-radius: 50%;
}
// ==================== 底部栏(步骤一/步骤二共用) ====================
&__bottom-bar {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 0.66rem;
background: #FCF4E8;
border-top: 1px solid #E9D4B1;
border-radius: 0 0 0.16rem 0;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 0.24rem;
box-sizing: border-box;
&--qrcode {
height: 1.7rem;
padding: 0.2rem 0.24rem;
gap: 0.24rem;
justify-content: flex-start;
}
}
&__footer-price {
display: flex;
align-items: baseline;
gap: 0.04rem;
}
&__footer-price-label {
font-weight: 330;
font-size: 0.12rem;
line-height: 0.16rem;
color: #1F160F;
margin-right: 0.08rem;
}
&__footer-price-symbol {
font-weight: 600;
font-size: 0.14rem;
color: #1F160F;
}
&__footer-price-num {
font-weight: 600;
font-size: 0.24rem;
line-height: 0.32rem;
color: #1F160F;
}
// 购买会员按钮
&__buy-btn {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
padding: 0.08rem 0.12rem;
height: 0.35rem;
background: #AEE6EA;
padding: 0.08rem 0.24rem;
height: 0.33rem;
background: #C88E35;
border: 1px solid #F0D091;
box-shadow: 0 0.02rem 0.05rem rgba(154, 104, 32, 0.18);
border-radius: 0.08rem;
border: none;
font-weight: 450;
font-size: 0.14rem;
line-height: 0.19rem;
color: $bg-white;
cursor: default;
opacity: 0.4;
transition: background 0.2s, opacity 0.2s;
font-weight: 600;
font-size: 0.13rem;
line-height: 0.15rem;
color: #FFFFFF;
cursor: pointer;
border: 1px solid #F0D091;
transition: opacity 0.2s;
// 选择了支付方式后变为主题色、不透明、可点击
&--active {
background: $accent;
opacity: 1;
cursor: pointer;
&:hover {
opacity: 0.9;
}
&:hover {
background: $accent-hover;
}
&:disabled {
opacity: 0.5;
cursor: default;
}
}
// ==================== 扫码支付弹窗内容 ====================
&__qrcode-content {
// ==================== 扫码支付区域(底部栏内) ====================
&__qrcode-box {
width: 1.2rem;
height: 1.2rem;
border: 2px solid #B77D24;
border-radius: 0.0rem;
display: flex;
align-items: center;
justify-content: center;
background: #FFFFFF;
flex-shrink: 0;
}
&__qrcode-iframe {
border: none;
border-radius: 0.04rem;
}
.qrcode-zhifubao{
transform: scale(0.52);
width: 2.2rem !important;
height: 2.2rem !important;
padding-top: 0.1rem;
padding-left: 0.1rem;
box-sizing: border-box;
}
.qrcode-wechat{
transform: scale(0.66);
width: 1.6rem !important;
height: 1.6rem !important;
box-sizing: border-box;
}
&__qrcode-info {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.16rem;
width: 100%;
}
&__qrcode-image {
width: 2.1rem;
height: 2.1rem;
display: flex;
align-items: center;
justify-content: center;
}
&__payment-iframe {
width: 100%;
height: 100%;
border: none;
border-radius: 0.08rem;
}
&__wechat-qr-iframe {
width: 2.2rem;
height: 2.2rem;
border: none;
border-radius: 0.08rem;
gap: 0.12rem;
}
&__qrcode-price-row {
display: flex;
align-items: flex-end;
gap: 0.08rem;
align-items: center;
gap: 0.04rem;
}
&__qrcode-price {
font-weight: 630;
&__qrcode-price-symbol {
font-weight: 600;
font-size: 0.18rem;
color: #1F160F;
}
&__qrcode-price-num {
font-size: 0.32rem;
line-height: 0.25rem;
color: $text-dark;
font-weight: 600;
line-height: 0.37rem;
color: #1F160F;
}
&__qrcode-tip {
font-weight: 330;
font-size: 0.14rem;
line-height: 0.1rem;
color: $text-dark;
line-height: 0.19rem;
color: #1F160F;
margin-left: 0.08rem;
vertical-align: middle;
}
&__qrcode-agreement {
font-weight: 330;
font-size: 0.14rem;
line-height: 0.19rem;
color: $text-light;
font-size: 0.12rem;
line-height: 0.16rem;
color: #3B2A1E;
margin: 0;
a {
color: $text-light;
color: #A86718;
text-decoration: none;
&:hover {
color: $accent;
color: #A86718;
}
}
}
// 已支付成功按钮
// 已支付成功按钮
&__paid-btn {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
padding: 0.08rem 0.12rem;
height: 0.35rem;
background: $accent;
padding: 0.08rem 0.24rem;
height: 0.33rem;
width: fit-content;
background: #C88E35;
border: 1px solid #F0D091;
box-shadow: 0 0.02rem 0.05rem rgba(154, 104, 32, 0.18);
border-radius: 0.08rem;
border: none;
font-weight: 450;
font-size: 0.14rem;
line-height: 0.19rem;
color: $bg-white;
font-weight: 600;
font-size: 0.13rem;
line-height: 0.15rem;
color: #FFFFFF;
cursor: pointer;
transition: background 0.2s;
transition: opacity 0.2s;
&:hover {
background: $accent-hover;
opacity: 0.9;
}
}
}
@@ -55,15 +55,11 @@
// ==================== 下拉面板 ====================
&__panel {
position: absolute;
top: calc(100% + 0.06rem);
left: 0;
width: 4.2rem;
background: $bg-white;
border: 1px solid $border-color;
border-radius: 0.1rem;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
z-index: 100;
padding: 0.1rem;
// level=2 时只有两栏,面板收窄
+195 -45
View File
@@ -12,6 +12,14 @@
position: fixed;
left: 0;
top: 0;
z-index: 100;
// 窄版模式(window.innerWidth < 1440
&--narrow {
width: 0.8rem;
padding: 0.16rem 0.10rem;
align-items: center;
}
&__header {
display: flex;
@@ -21,6 +29,12 @@
margin-bottom: 0.2rem;
}
// 窄版header居中
&--narrow &__header {
justify-content: center;
padding: 0.1rem 0;
}
&__avatar {
width: 0.36rem;
height: 0.36rem;
@@ -43,6 +57,12 @@
width: 1.32rem;
height: 0.34rem;
display: block;
// 窄版logo
&--narrow {
width: 0.46rem;
height: auto;
}
}
&__menu {
@@ -52,6 +72,11 @@
flex: 1;
}
// 窄版菜单宽度撑满
&--narrow &__menu {
width: 100%;
}
&__item {
position: relative;
display: flex;
@@ -80,18 +105,45 @@
}
}
// 窄版导航项:纵向居中排列
&--narrow &__item {
flex-direction: column;
align-items: center;
justify-content: center;
gap: 0.04rem;
padding: 0.1rem 0.06rem;
}
&__item-icon {
width: 0.2rem;
height: 0.2rem;
object-fit: contain;
font-size: 0.16rem;
// 内部SVG/img统一撑满容器
svg, img {
width: 100%;
height: 100%;
display: block;
}
}
// 窄版图标放大,防止scale缩放后图标过小
&--narrow &__item-icon {
width: 0.24rem;
height: 0.24rem;
}
&__item-label {
}
// 窄版label字号缩小
&--narrow &__item-label {
font-size: 0.11rem;
white-space: nowrap;
}
&__badge {
background: #e85635;
color: #fff;
@@ -119,6 +171,19 @@
text-align: center;
color: #FFFFFF;
flex: none;
// 窄版角标样式(右上角定位)
&--corner {
position: absolute;
top: -0.07rem;
right: -0.05rem;
min-width: auto;
padding: 0.02rem 0.04rem;
height: 0.17rem;
font-size: 0.10rem;
line-height: 0.12rem;
border-radius: 0.03rem;
}
}
// 公测群二维码弹出层(hover索引5时显示)
@@ -147,6 +212,48 @@
gap: 0.04rem;
padding-top: 0.12rem;
}
// 窄版footer居中
&--narrow &__footer {
align-items: center;
width: 100%;
}
}
// ==================== 窄版邀请图片卡片 ====================
.side-nav__referral-card-narrow {
display: flex;
justify-content: center;
margin-top: 0.12rem;
}
.side-nav__referral-card-narrow-img {
width: 0.56rem;
height: 0.85rem;
display: block;
border-radius: 0.06rem;
}
// ==================== 窄版用户信息 ====================
.side-nav__user-info-narrow {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.06rem;
cursor: pointer;
padding: 0.08rem 0;
border-radius: 0.08rem;
&:hover {
}
}
.side-nav__user-avatar-narrow {
width: 0.26rem;
height: 0.26rem;
border-radius: 50%;
display: block;
}
.side-nav__dialog-overlay {
@@ -499,84 +606,120 @@
// ==================== 邀请会员卡片 ====================
.side-nav__referral-card {
position: relative;
width: 100%;
background: linear-gradient(128.17deg, #52CAD1 0%, #82D79B 100%);
height: 2.21rem;
background: linear-gradient(90deg, #DFF5F6 0%, #FBFDF7 100%);
box-shadow: 0px 0px 0.08rem rgba(0, 0, 0, 0.06);
border-radius: 0.08rem;
padding: 0.16rem;
box-sizing: border-box;
margin-top: 0.12rem;
overflow: hidden;
}
// 顶部区域:标题在左上,礼物图片定位在右下角
.side-nav__referral-top {
position: relative;
padding: 0.2rem 0.16rem 0.4rem;
}
.side-nav__referral-top-text {
position: relative;
z-index: 1;
}
.side-nav__referral-title {
font-size: 0.16rem;
font-size: 0.18rem;
font-weight: 630;
color: #FFFFFF;
line-height: 0.21rem;
color: #1A1A1A;
line-height: 0.24rem;
&--accent {
background: linear-gradient(128.17deg, #52CAD1 0%, #82D79B 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
}
.side-nav__referral-subtitle {
font-size: 0.10rem;
font-size: 0.14rem;
font-weight: 330;
color: #EAFBFC;
line-height: 0.13rem;
margin-top: 0.04rem;
color: #6A7282;
line-height: 0.19rem;
margin-top: 0.08rem;
}
// 礼物图片:absolute定位在顶部区域的右下角,底部被毛玻璃面板遮住
.side-nav__referral-gift {
position: absolute;
right: 0.10rem;
bottom: 0.02rem;
width: 0.68rem;
height: 0.68rem;
mix-blend-mode: darken;
}
// 白色毛玻璃面板(覆盖在礼物底部之上)
.side-nav__referral-panel {
background: #FFFFFF;
box-shadow: 0px 0.02rem 0.06rem rgba(26, 26, 26, 0.05);
border-radius: 0.06rem;
padding: 0.10rem 0.08rem;
margin-top: 0.10rem;
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 1.38rem;
background: rgba(255, 255, 255, 0.4);
border: 1px solid #FFFFFF;
border-bottom: none;
backdrop-filter: blur(3px);
border-radius: 0.08rem 0.08rem 0 0;
box-sizing: border-box;
padding: 0.16rem;
}
.side-nav__referral-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.08rem;
}
.side-nav__referral-label {
font-size: 0.10rem;
font-size: 0.14rem;
font-weight: 330;
color: #6B7280;
line-height: 0.13rem;
color: #6A7282;
line-height: 0.19rem;
}
.side-nav__referral-value {
font-size: 0.10rem;
font-weight: 620;
color: #52CAD1;
line-height: 0.13rem;
font-size: 0.14rem;
font-weight: 450;
line-height: 0.19rem;
background: linear-gradient(128.17deg, #52CAD1 0%, #82D79B 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.side-nav__referral-track {
width: 100%;
height: 0.02rem;
background: #D7F1F3;
border-radius: 9999px;
margin-top: 0.06rem;
height: 0.06rem;
background: #EDF9FA;
border-radius: 0.06rem;
margin-top: 0.1rem;
overflow: hidden;
}
.side-nav__referral-fill {
height: 100%;
background: #52CAD1;
border-radius: 9999px;
}
.side-nav__referral-divider {
width: 100%;
border-top: 0.01rem solid #8C8C8C;
margin-top: 0.08rem;
border-radius: 0.06rem;
}
.side-nav__referral-tip {
font-size: 0.10rem;
font-size: 0.12rem;
font-weight: 330;
color: #1A1A1A;
line-height: 0.13rem;
margin-top: 0.08rem;
color: #6A7282;
line-height: 0.16rem;
margin-top: 0.06rem;
strong {
font-weight: 630;
@@ -584,16 +727,22 @@
}
.side-nav__referral-action {
font-size: 0.11rem;
font-weight: 620;
color: #52CAD1;
line-height: 0.15rem;
text-align: center;
margin-top: 0.08rem;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 0.40rem;
background: linear-gradient(90deg, #36C1C9 16.99%, #AFE9D0 100%);
box-shadow: inset 0px 0px 0.06rem rgba(255, 255, 255, 0.5);
border-radius: 0.08rem;
font-size: 0.14rem;
font-weight: 600;
color: #FFFFFF;
margin-top: 0.12rem;
cursor: pointer;
&:hover {
opacity: 0.8;
opacity: 0.9;
}
}
@@ -701,12 +850,13 @@
bottom: calc(100% + 0.08rem);
left: 0;
width: 100%;
min-width: 1.65rem;
background: #FFFFFF;
border: 1px solid #F0F0F0;
box-shadow: 0px 0.02rem 0.08rem rgba(0, 0, 0, 0.04);
border-radius: 0.08rem;
overflow: hidden;
z-index: 100;
z-index: 1000;
}
.side-nav__account-popup-header {
+2 -2
View File
@@ -8,7 +8,7 @@
font-size: 0.14rem;
// 主内容区域(左侧导航栏右边的部分)
&__content {
margin-left: 2.2rem;
margin-left: var(--nav-width, 2.2rem);
flex: 1;
overflow-y: auto;
height: var(--app-height, 100vh);
@@ -1928,7 +1928,7 @@
.agent-page__install-dialog-title {
position: relative;
font-size: 0.18rem;
font-weight: 520;
font-weight: 600;
color: $text-dark;
text-align: center;
margin: 0 0 0.2rem 0;
+1 -1
View File
@@ -3,7 +3,7 @@
// ==================== 岗位详情页 ====================
.job-detail {
&__content {
margin-left: 2.2rem;
margin-left: var(--nav-width, 2.2rem);
margin-right: var(--chat-width, 3.6rem);
flex: 1;
height: var(--app-height, 100vh);
+486 -383
View File
@@ -6,7 +6,7 @@
display: flex;
&__content {
margin-left: 2.2rem;
margin-left: var(--nav-width, 2.2rem);
margin-right: var(--chat-width, 3.6rem);
flex: 1;
padding-bottom: 0.18rem;
@@ -80,7 +80,7 @@
// 筛选条件外层白色背景条
&__filters-bar {
border-radius: 0.12rem;
margin: 0 0.24rem 0.5rem 0.24rem;
margin: 0 0.24rem 0.12rem 0.24rem;
}
// AI 推荐提示条外层
@@ -196,7 +196,223 @@
color: $text-light;
}
// 筛选条件
// 筛选面板
&__filters-panel {
background: $bg-white;
border: 1px solid #F0F0F0;
box-shadow: 0px 2px 6px rgba(15, 23, 42, 0.025);
border-radius: 0.12rem;
padding: 0.12rem 0.16rem;
display: flex;
flex-direction: column;
gap: 0.12rem;
}
// 筛选行
&__filter-row {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
gap: 0.08rem 0.16rem;
background: $bg-white;
}
&__filter-row-inner {
display: flex;
flex-direction: row;
align-items: center;
gap: 0.16rem;
flex: 1;
min-width: 0;
}
// 筛选行标题(行业/岗位/地点/筛选)
&__filter-row-label {
font-size: 0.12rem;
line-height: 0.16rem;
font-weight: 380;
color: $text-middle;
flex-shrink: 0;
white-space: nowrap;
}
// 筛选chip组容器外层(让"更多"固定在行最右边)
&__filter-chips-wrap {
display: flex;
align-items: flex-start;
gap: 0.08rem;
flex: 1;
min-width: 0;
// "更多"选择器组件固定在右边
> .industry-selector,
> .job-category-selector,
> .region-selector {
flex-shrink: 0;
margin-left: auto;
align-self: flex-end;
}
}
// 筛选chip组容器(允许换行)
&__filter-chips {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
align-content: center;
gap: 0.08rem;
flex: 1;
min-width: 0;
}
// 筛选chip(默认灰色背景)
&__filter-chip {
display: flex;
justify-content: center;
align-items: center;
padding: 0.04rem 0.08rem;
background: #F3F4F6;
border-radius: 0.04rem;
font-size: 0.12rem;
line-height: 0.16rem;
font-weight: 330;
color: $text-dark;
cursor: pointer;
white-space: nowrap;
user-select: none;
transition: all 0.15s;
border: 1px solid transparent;
&:hover {
background: #E8F8F9;
color: $accent;
}
// 选中态(带边框浅色背景)
&--active {
background: #F4FBFB;
border-color: $accent;
color: $accent;
font-weight: 520;
}
// 选中态(实心品牌色背景,用于"全部/全国"按钮选中时)
&--active-solid {
background: $accent;
color: #FFFFFF;
font-weight: 520;
border-color: $accent;
}
}
// 底部筛选行(下拉按钮组)
&__filter-row--bottom {
// 不换行
}
// 下拉按钮组容器
&__filter-dropdowns {
display: flex;
align-items: center;
gap: 0.08rem;
flex-wrap: wrap;
}
// 下拉按钮项
&__dropdown-item {
display: flex;
align-items: center;
gap: 0.02rem;
padding: 0.04rem 0.08rem;
border: 1px solid #F0F0F0;
border-radius: 0.04rem;
font-size: 0.12rem;
line-height: 0.16rem;
font-weight: 330;
color: $text-dark;
cursor: pointer;
white-space: nowrap;
position: relative;
user-select: none;
transition: all 0.15s;
&:hover {
border-color: $accent;
color: $accent;
}
.el-range-separator{
padding-bottom:0.03rem !important;
}
}
&__dropdown-arrow {
width: 0.12rem;
height: 0.12rem;
color: $text-middle;
flex-shrink: 0;
}
// 清空筛选条件按钮
&__clear-filters {
font-size: 0.12rem;
color: $text-middle;
cursor: pointer;
white-space: nowrap;
flex-shrink: 0;
&:hover {
color: $accent;
}
}
// 筛选数量 + 深度匹配提示条
&__filter-count-bar {
display: flex;
align-items: center;
gap: 0.12rem;
margin-top: 0.08rem;
}
&__filter-count-text {
font-size: 0.12rem;
color: $text-middle;
white-space: nowrap;
}
&__filter-count-num {
color: $accent;
font-weight: 600;
}
// 深度匹配按钮
&__deep-match-btn {
padding: 0 0.08rem;
height: 0.20rem;
line-height: 0.16rem;
border: none;
border-radius: 0.04rem;
background: linear-gradient(128.17deg, #52CAD1 0%, #82D79B 100%);
color: #fff;
font-size: 0.12rem;
font-weight: 500;
cursor: pointer;
white-space: nowrap;
flex-shrink: 0;
transition: opacity 0.2s;
&:hover {
opacity: 0.85;
}
&:disabled {
opacity: 0.6;
cursor: not-allowed;
}
}
// 筛选条件(保留旧的兼容)
&__filters {
display: flex;
align-items: center;
@@ -248,6 +464,34 @@
box-shadow: 0 0.04rem 0.12rem rgba(0, 0, 0, 0.08);
z-index: 20;
min-width: 100%;
// 发布时间date-picker容器
&__dropdown-item--time {
padding: 0;
border: none;
// 覆盖el-date-picker内部样式适配筛选行
:deep(.el-input__wrapper) {
box-shadow: none;
border: 1px solid #F0F0F0;
border-radius: 0.04rem;
padding: 0 0.06rem;
font-size: 0.12rem;
}
:deep(.el-range-input) {
font-size: 0.12rem;
}
:deep(.el-range-separator) {
font-size: 0.12rem;
padding: 0 0.02rem;
}
:deep(.el-input__icon) {
font-size: 0.12rem;
}
}
}
// 下拉菜单选项
@@ -279,15 +523,16 @@
}
&__search-box {
flex: 1;
display: flex;
align-items: center;
background: $bg-white;
border-radius: 0.08rem;
padding: 0.08rem 0.14rem;
min-width: 1.6rem;
padding: 0.10rem 0.14rem;
border: 1px solid #F0F0F0;
margin-top: 0.12rem;
&:focus-within {
border-color: $accent;
}
}
@@ -297,6 +542,7 @@
color: $text-light;
margin-right: 0.08rem;
flex-shrink: 0;
cursor: pointer;
}
&__search-input {
@@ -319,458 +565,315 @@
height: calc(var(--app-height, 100vh) - 1.8rem);
padding-bottom: 0.2rem;
margin: 0 0.24rem;
// 列表中每张卡片间距用 margin-bottom 替代 gap
& > .jobs-page__job-card {
margin-bottom: 0.12rem;
&:last-child {
margin-bottom: 0;
}
}
}
&__job-card {
background: $bg-white;
border-radius: 0.12rem;
padding: 0.2rem 0.24rem;
transition: all 0.25s ease;
border: 0.02rem solid transparent;
cursor: pointer;
position: relative;
&:hover {
box-shadow: 0 0.04rem 0.16rem rgba(0, 0, 0, 0.06);
//background: #fbfbfb;
}
&--selected {
border-color: $accent;
background: $selected-color;
box-shadow: 0 0.02rem 0.12rem rgba(79, 194, 201, 0.12);
}
}
&__job-main {
display: flex;
align-items: stretch;
gap: 0.2rem;
}
// ========== 左栏:职位信息 ==========
&__col-left {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column; // 纵排,配合 meta-bottom 的 margin-top: auto 把它推到底部
}
&__job-title-row {
display: flex;
align-items: center;
gap: 0.08rem;
}
&__job-name {
font-size: 0.18rem;
font-weight: 620;
color: #000000;
line-height: 0.24rem;
}
// 收藏红心
&__favorite-btn {
background: none;
border: none;
cursor: pointer;
padding: 0.02rem;
display: flex;
align-items: center;
color: #8C8C8C;
transition: color 0.2s;
&:hover {
color: $danger;
}
&--liked {
color: $danger;
}
}
&__favorite-svg {
width: 0.16rem;
height: 0.16rem;
}
&__job-remove {
color: $text-light;
cursor: pointer;
background: none;
border: none;
padding: 0.04rem;
border-radius: 0.04rem;
transition: all 0.2s;
display: flex;
align-items: center;
&:hover {
color: $danger;
background: #FFF0ED;
}
}
&__remove-svg {
width: 0.14rem;
height: 0.14rem;
}
// 职位标签
&__job-tags {
display: flex;
gap: 0.08rem;
flex-wrap: wrap;
margin-top: 0.14rem;
}
&__job-tag {
display: flex;
align-items: center;
justify-content: center;
padding: 0.04rem 0.06rem;
background: #F4F4F4;
border-radius: 0.04rem;
font-size: 0.12rem;
font-weight: 330;
color: #929292;
line-height: 0.16rem;
}
// 底部:地区 + 学历 + 招聘分类,margin-top: auto 把它推到左栏底部
&__job-meta-bottom {
display: flex;
align-items: center;
// 网格容器:列数由 CSS 变量 --job-grid-cols 控制(JS 动态计算)
&__grid {
display: grid;
grid-template-columns: repeat(var(--job-grid-cols, 3), 1fr);
gap: 0.12rem;
margin-top: auto;
padding-top: 0.08rem;
flex-wrap: wrap;
}
&__meta-location {
// ========== 新卡片样式 ==========
&__job-card {
position: relative;
height: 1.33rem;
border: 1px solid #F0F0F0;
border-radius: 0.08rem;
padding: 0.16rem;
box-sizing: border-box;
cursor: pointer;
transition: box-shadow 0.2s;
overflow: hidden;
&:hover {
box-shadow: 0 0.04rem 0.16rem rgba(0, 0, 0, 0.08);
}
// hover 时隐藏公司信息行,显示操作按钮行
&:hover .jobs-page__card-bottom--info {
opacity: 0;
pointer-events: none;
}
&:hover .jobs-page__card-bottom--actions {
opacity: 1;
pointer-events: auto;
}
}
// 上半部分容器
&__card-top {
display: flex;
align-items: center;
gap: 0.02rem;
font-size: 0.14rem;
font-weight: 330;
color: #8C8C8C;
line-height: 0.19rem;
align-items: flex-start;
justify-content: space-between;
gap: 0.08rem;
}
&__location-icon {
width: 0.18rem;
height: 0.18rem;
color: #8C8C8C;
flex-shrink: 0;
}
&__meta-edu {
font-size: 0.14rem;
font-weight: 330;
color: #8C8C8C;
line-height: 0.19rem;
}
&__meta-recruit {
display: flex;
align-items: center;
justify-content: center;
padding: 0.02rem 0.06rem;
background: #EDF9FA;
border-radius: 0.04rem;
font-size: 0.12rem;
font-weight: 330;
color: #fff;
line-height: 0.16rem;
}
// ========== 中栏:公司信息(居中) ==========
&__col-center {
flex: 1; // 参与 flex 空间分配,获得真实宽度约束
min-width: 0; // 防止内容撑破 flex 容器
}
// 公司信息容器,需要 min-width 才能让内部标签换行
&__company-info {
// 上半左侧
&__card-top-left {
min-width: 0;
flex: 1;
}
&__company-row {
display: flex;
align-items: center;
gap: 0.06rem;
margin-bottom: 0.06rem;
flex-wrap: wrap;
// 岗位标题
&__card-title {
font-size: 0.16rem;
font-weight: 520;
color: #1A1A1A;
line-height: 0.21rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
&__company-logo {
width: 0.24rem;
height: 0.24rem;
border-radius: 0.04rem;
// 标签行
&__card-tags {
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
font-size: 0.24rem;
color: #8C8C8C;
gap: 0.08rem;
margin-top: 0.08rem;
flex-wrap: nowrap;
overflow: hidden;
}
&__company-name {
font-size: 0.18rem;
font-weight: 330;
color: #000000;
line-height: 0.24rem;
}
&__company-tags {
display: flex;
align-items: center;
gap: 0.08rem;
flex-wrap: wrap;
min-width: 0; // 允许内容收缩触发换行
margin-top: 0.14rem;
}
&__company-tag {
// 单个标签
&__card-tag {
display: flex;
align-items: center;
justify-content: center;
padding: 0.04rem 0.06rem;
background: #F4F4F4;
padding: 0.03rem 0.06rem;
background: #F3F4F6;
border-radius: 0.04rem;
font-size: 0.12rem;
font-weight: 330;
color: #929292;
font-weight: 380;
color: #6A7282;
line-height: 0.16rem;
white-space: nowrap;
flex-shrink: 0;
}
// ========== 右栏:操作按钮 ==========
&__col-right {
display: flex;
flex-direction: column;
// 右侧匹配度
&__card-match {
text-align: right;
flex-shrink: 0;
}
&__job-action-right {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 0.1rem;
&__card-match-score {
display: block;
font-size: 0.22rem;
font-weight: 520;
line-height: 0.29rem;
text-align: center;
}
&__job-helper {
&__card-match-label {
display: block;
font-size: 0.12rem;
font-weight: 450;
line-height: 0.16rem;
text-align: center;
margin-top: 0.02rem;
}
// 未登录锁定态
&__card-match--locked {
display: flex;
align-items: center;
justify-content: center;
text-align: center;
width: 0.88rem;
height: 0.37rem;
line-height: 0.37rem;
border: 1.23px solid $accent;
border-radius: 0.08rem;
}
&__card-lock-icon {
width: 0.24rem;
height: 0.24rem;
color: $text-light;
}
// 下半部分通用定位
&__card-bottom {
position: absolute;
left: 0.16rem;
right: 0.16rem;
bottom: 0.12rem;
display: flex;
align-items: center;
justify-content: space-between;
transition: opacity 0.2s;
}
// 默认显示公司信息
&__card-bottom--info {
opacity: 1;
}
// hover 时显示操作按钮(默认隐藏)
&__card-bottom--actions {
opacity: 0;
pointer-events: none;
gap: 0.08rem;
}
// 公司信息行
&__card-company {
display: flex;
align-items: center;
gap: 0.04rem;
min-width: 0;
flex: 1;
}
// 公司 logo
&__card-company-logo {
width: 0.24rem;
height: 0.24rem;
border-radius: 0.12rem;
border: 1px solid #F4F4F4;
flex-shrink: 0;
object-fit: cover;
&--default {
display: flex;
align-items: center;
justify-content: center;
background: #FFFFFF;
}
}
// 公司名称
&__card-company-name {
font-size: 0.14rem;
font-weight: 450;
color: #1A1A1A;
line-height: 0.19rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 1.1rem;
}
// 公司类型标签
&__card-company-type {
display: flex;
align-items: center;
justify-content: center;
padding: 0.03rem 0.06rem;
background: #ECFDF3;
border-radius: 0.04rem;
font-size: 0.12rem;
font-weight: 380;
color: #067647;
line-height: 0.16rem;
white-space: nowrap;
flex-shrink: 0;
}
// 发布时间
&__card-publish-time {
font-size: 0.12rem;
font-weight: 330;
color: #99A1AF;
line-height: 0.16rem;
white-space: nowrap;
flex-shrink: 0;
}
// ========== hover 操作按钮行 ==========
// 三点更多按钮
&__card-more-btn {
width: 0.32rem;
height: 0.32rem;
border: none;
background: none;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
border-radius: 0.04rem;
transition: background 0.2s;
flex-shrink: 0;
&:hover {
background: #F3F4F6;
}
}
// 问Nova按钮
&__card-ask-btn {
flex: 1;
height: 0.32rem;
background: #EDF9FA;
border: none;
border-radius: 0.06rem;
font-size: 0.14rem;
font-weight: 450;
color: $accent;
cursor: pointer;
transition: all 0.2s;
transition: background 0.2s;
white-space: nowrap;
&:hover {
background: $theme-color;
background: #D9F2F4;
}
}
&__job-apply-btn {
display: flex;
align-items: center;
justify-content: center;
width: 0.88rem;
height: 0.37rem;
line-height: 0.35rem;
// 去投递按钮
&__card-apply-btn {
flex: 1;
height: 0.32rem;
background: $accent;
border: none;
border-radius: 0.08rem;
border-radius: 0.06rem;
font-size: 0.14rem;
font-weight: 450;
color: #FFFFFF;
cursor: pointer;
transition: all 0.2s;
transition: background 0.2s;
white-space: nowrap;
&:hover {
background: $accent-hover;
}
&--active {
background: $accent;
color: #FFFFFF;
}
}
// 不再显示(默认隐藏,hover 卡片时显示)
&__hide-btn {
display: block;
margin-top: auto;
font-size: 0.14rem;
font-weight: 330;
color: #8C8C8C;
cursor: pointer;
transition: color 0.2s, opacity 0.2s;
line-height: 0.19rem;
white-space: nowrap;
opacity: 0;
&:hover {
color: $text-dark;
}
}
// hover 卡片时显示"不再显示"按钮
&__job-card:hover &__hide-btn {
opacity: 1;
}
// 弹出菜单
&__job-popup {
&__card-popup {
position: absolute;
right: 1.4rem;
top: 0.5rem;
background: $bg-white;
border: 1px solid #E8E8E8;
border-radius: 0.1rem;
left: 0;
bottom: 0.4rem;
background: #FFFFFF;
border: 1px solid #F0F0F0;
border-radius: 0.08rem;
padding: 0.06rem 0;
box-shadow: 0 0.06rem 0.2rem rgba(0, 0, 0, 0.1);
box-shadow: 0 0.04rem 0.16rem rgba(0, 0, 0, 0.1);
z-index: 10;
min-width: 1.2rem;
}
&__job-popup-item {
padding: 0.08rem 0.2rem;
font-size: 0.12rem;
color: $text-dark;
// 弹出菜单项
&__card-popup-item {
display: flex;
align-items: center;
gap: 0.08rem;
padding: 0.08rem 0.16rem;
font-size: 0.14rem;
color: #1A1A1A;
cursor: pointer;
white-space: nowrap;
transition: all 0.15s;
transition: background 0.15s;
&:hover {
background: $theme-color;
color: $accent-hover;
}
}
// ========== 最右侧:匹配度 ==========
&__job-match {
width: 1.01rem;
text-align: center;
flex-shrink: 0;
border-radius: 0.08rem;
padding: 0.14rem 0.1rem;
transition: all 0.25s ease;
&--high {
background: #FBFDF7;
background: #EDF9FA;
}
&--medium {
background: #FFFBF5;
svg {
flex-shrink: 0;
}
&--low {
background: #FFF6F5;
span {
color: inherit;
}
}
&__match-ring {
position: relative;
width: 0.62rem;
height: 0.62rem;
margin: 0 auto;
}
&__ring-svg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
&__match-score {
font-size: 0.18rem;
font-weight: 620;
line-height: 0.62rem;
position: absolute;
top: 0;
left: 0;
width: 100%;
text-align: center;
z-index: 1;
}
&__match-level {
font-size: 0.13rem;
font-weight: 620;
line-height: 0.19rem;
margin-top: 0.04rem;
}
// 高匹配度颜色
&__job-match--high &__match-score {
color: #9FD051;
}
&__job-match--high &__match-level {
color: #9FD051;
}
// 中匹配度颜色
&__job-match--medium &__match-score {
color: #F59E0B;
}
&__job-match--medium &__match-level {
color: #F59E0B;
}
// 低匹配度颜色
&__job-match--low &__match-score {
color: #FE6D52;
}
&__job-match--low &__match-level {
color: #FE6D52;
}
// 未登录锁定态
&__job-match--locked {
background: $bg-main;
border: 1px solid #E8E8E8;
}
&__lock-icon {
width: 0.32rem;
height: 0.32rem;
color: $text-light;
display: block;
margin: 0 auto 0.06rem;
}
&__match-lock-text {
font-size: 0.1rem;
color: $text-light;
white-space: nowrap;
}
// 收藏统计栏
&__fav-stats {
display: flex;
+1 -1
View File
@@ -14,7 +14,7 @@
flex: 1;
height: 100%;
overflow: hidden;
margin-left: 2.2rem;
margin-left: var(--nav-width, 2.2rem);
display: flex;
}
+1 -1
View File
@@ -14,7 +14,7 @@
flex: 1;
height: 100%;
overflow: hidden;
margin-left: 2.2rem;
margin-left: var(--nav-width, 2.2rem);
}
// 左侧主内容区
+1 -1
View File
@@ -3,7 +3,7 @@
// ==================== 个人资料页 ====================
.profile-page {
&__content {
margin-left: 2.2rem;
margin-left: var(--nav-width, 2.2rem);
flex: 1;
padding-bottom: 0.12rem;
height: var(--app-height, 100vh);
+1 -1
View File
@@ -3,7 +3,7 @@
// ==================== 简历详情页 ====================
.resume-detail {
&__content {
margin-left: 2.2rem;
margin-left: var(--nav-width, 2.2rem);
flex: 1;
padding-bottom: 0.24rem;
height: var(--app-height, 100vh);
+1 -1
View File
@@ -3,7 +3,7 @@
// ==================== 简历列表页 ====================
.resume-page {
&__content {
margin-left: 2.2rem;
margin-left: var(--nav-width, 2.2rem);
flex: 1;
height: var(--app-height, 100vh);
box-sizing: border-box;
+2 -2
View File
@@ -152,11 +152,11 @@ function switchTab(tab: 'pending' | 'completed') {
activeTab.value = tab
}
/** 加载待投递列表(pageSize=300 */
/** 加载待投递列表(pageSize=200 */
async function loadPendingList() {
pendingLoading.value = true
try {
const res = await fetchAgentTaskList({ pageNum: 1, pageSize: 300, tab: 1 })
const res = await fetchAgentTaskList({ pageNum: 1, pageSize: 200, tab: 1 })
if (res.code === '0' && res.data) {
pendingList.value = res.data.list || []
}
+206 -226
View File
@@ -3,71 +3,41 @@
<Teleport to="body">
<!-- 遮罩层 点击关闭弹窗 -->
<div v-if="modelValue" class="member-dialog-overlay" @click="$emit('update:modelValue', false)">
<!-- 弹窗主体 阻止点击冒泡 -->
<!-- 弹窗主体 左右布局 -->
<div class="member-dialog" @click.stop>
<!-- 顶部标题行 -->
<div class="member-dialog__header">
<div class="member-dialog__header-left">
<h2 class="member-dialog__title">会员中心</h2>
<p class="member-dialog__subtitle">解锁更多求职功能让投递更高效</p>
</div>
<div class="member-dialog__header-right">
<!-- 联系客服hover显示二维码 -->
<span class="member-dialog__contact-wrap">
<span class="member-dialog__contact">联系客服</span>
<div class="member-dialog__contact-qr">
<img src="@/assets/images/nav/kg-qcCode.png" alt="客服二维码" />
<div class="member-dialog__contact-qr-arrow"></div>
</div>
</span>
<span class="member-dialog__close" @click="$emit('update:modelValue', false)"></span>
</div>
</div>
<!-- 套餐选择区域 -->
<div class="member-dialog__plans">
<div
v-for="plan in plans"
:key="plan.key"
class="member-dialog__plan-card"
:class="{ 'member-dialog__plan-card--active': selectedPlan === plan.key }"
@click="selectedPlan = plan.key"
>
<!-- 推荐标签 -->
<div v-if="plan.recommend" class="member-dialog__plan-recommend"><svg width="10" height="10" viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_180_2594)">
<path d="M0.872709 4.61946C0.867714 4.56192 0.874732 4.50398 0.893317 4.44931C0.911903 4.39464 0.94165 4.34442 0.980672 4.30186C1.01969 4.25929 1.06714 4.2253 1.11999 4.20204C1.17285 4.17878 1.22996 4.16676 1.28771 4.16675H2.08333C2.19384 4.16675 2.29982 4.21065 2.37796 4.28879C2.4561 4.36693 2.5 4.47291 2.5 4.58341V8.54175C2.5 8.65225 2.4561 8.75823 2.37796 8.83637C2.29982 8.91451 2.19384 8.95841 2.08333 8.95841H1.63208C1.5278 8.95844 1.42729 8.91936 1.35042 8.84889C1.27355 8.77842 1.2259 8.68168 1.21688 8.57779L0.872709 4.61946ZM3.75 4.45321C3.75 4.27904 3.85833 4.1232 4.01563 4.04904C4.35917 3.88696 4.94438 3.56133 5.20833 3.12112C5.54854 2.55362 5.61271 1.52841 5.62313 1.29362C5.62458 1.26071 5.62375 1.22779 5.62813 1.19529C5.68458 0.788414 6.46979 1.26362 6.77083 1.76612C6.93438 2.03862 6.95521 2.39675 6.93813 2.67654C6.91958 2.97571 6.83188 3.26466 6.74583 3.55175L6.5625 4.16362H8.82438C8.88875 4.16362 8.95225 4.17853 9.0099 4.20719C9.06754 4.23585 9.11776 4.27748 9.15662 4.32881C9.19547 4.38014 9.22191 4.43977 9.23384 4.50303C9.24578 4.56629 9.2429 4.63145 9.22542 4.69341L8.10667 8.65508C8.08197 8.74245 8.02941 8.81937 7.95698 8.87413C7.88455 8.92888 7.79622 8.95848 7.70542 8.95841H4.16667C4.05616 8.95841 3.95018 8.91451 3.87204 8.83637C3.7939 8.75823 3.75 8.65225 3.75 8.54175V4.45321Z" fill="white" stroke="white" stroke-width="0.833333" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_180_2594">
<rect width="10" height="10" fill="white"/>
</clipPath>
</defs>
</svg>
推荐</div>
<!-- 套餐名称 -->
<div class="member-dialog__plan-name">{{ plan.name }}</div>
<!-- 价格行 -->
<div class="member-dialog__plan-price">
<span class="member-dialog__plan-price-symbol">¥</span>
<span class="member-dialog__plan-price-num">{{ plan.priceInt }}</span>
<span v-if="plan.originalPrice" class="member-dialog__plan-original-price">{{ plan.originalPrice }}</span>
</div>
<!-- 标签描述接口tag字段 -->
<div class="member-dialog__plan-daily mt4">{{ plan.tag }}</div>
</div>
</div>
<!-- 会员权益区域 -->
<div class="member-dialog__benefits">
<h3 class="member-dialog__benefits-title">会员权益</h3>
<div class="member-dialog__benefits-cards">
<!-- 左侧黑金权益栏 -->
<div class="member-dialog__left">
<!-- 装饰线条背景 -->
<div class="member-dialog__left-deco"></div>
<!-- 左栏标题 -->
<h2 class="member-dialog__left-title">Offer派会员专享权益</h2>
<p class="member-dialog__left-subtitle">解锁更多功能让求职更高效</p>
<!-- 权益卡片列表 -->
<div class="member-dialog__benefits">
<div class="member-dialog__benefit-card">
<div class="member-dialog__benefit-icon">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
<rect width="24" height="24" rx="12" fill="#EDF9FA"/>
<path d="M7 8h7v2H7V8zm0 3h10v2H7v-2zm0 3h5v2H7v-2z" fill="#52CAD1"/>
<svg width="14" height="15" viewBox="0 0 13 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.67492 2.29867C5.07359 1.132 6.68559 1.09667 7.15825 2.19267L7.19825 2.29933L7.73625 3.87267C7.85955 4.23349 8.05879 4.56367 8.32054 4.84095C8.58229 5.11822 8.90046 5.33614 9.25359 5.48L9.39825 5.534L10.9716 6.07133C12.1383 6.47 12.1736 8.082 11.0783 8.55467L10.9716 8.59467L9.39825 9.13267C9.03731 9.25588 8.70699 9.45508 8.4296 9.71684C8.1522 9.97859 7.93418 10.2968 7.79025 10.65L7.73625 10.794L7.19892 12.368C6.80025 13.5347 5.18825 13.57 4.71625 12.4747L4.67492 12.368L4.13759 10.7947C4.01437 10.4337 3.81517 10.1034 3.55341 9.82601C3.29166 9.54862 2.97345 9.3306 2.62025 9.18667L2.47625 9.13267L0.902919 8.59533C-0.264415 8.19667 -0.299748 6.58467 0.796252 6.11267L0.902919 6.07133L2.47625 5.534C2.83707 5.4107 3.16726 5.21146 3.44453 4.94971C3.72181 4.68796 3.93973 4.36979 4.08359 4.01667L4.13759 3.87267L4.67492 2.29867ZM11.2703 1.20458e-07C11.395 -1.57315e-07 11.5172 0.0349855 11.623 0.100981C11.7288 0.166977 11.814 0.261335 11.8689 0.373333L11.9009 0.451333L12.1343 1.13533L12.8189 1.36867C12.9439 1.41113 13.0535 1.48974 13.1337 1.59454C13.214 1.69934 13.2613 1.82561 13.2698 1.95735C13.2782 2.08908 13.2473 2.22035 13.1811 2.33453C13.1148 2.4487 13.0161 2.54063 12.8976 2.59867L12.8189 2.63067L12.1349 2.864L11.9016 3.54867C11.859 3.67362 11.7804 3.78313 11.6755 3.86333C11.5707 3.94352 11.4444 3.99079 11.3127 3.99915C11.1809 4.0075 11.0497 3.97656 10.9356 3.91025C10.8214 3.84394 10.7296 3.74524 10.6716 3.62667L10.6396 3.54867L10.4063 2.86467L9.72159 2.63133C9.5966 2.58887 9.48703 2.51026 9.40677 2.40546C9.3265 2.30066 9.27916 2.17439 9.27073 2.04265C9.26231 1.91092 9.29318 1.77965 9.35944 1.66548C9.4257 1.5513 9.52436 1.45937 9.64292 1.40133L9.72159 1.36933L10.4056 1.136L10.6389 0.451333C10.6839 0.319617 10.7689 0.205272 10.8821 0.124333C10.9954 0.0433927 11.1311 -8.35209e-05 11.2703 1.20458e-07Z" fill="#FFE2A1"/>
</svg>
</div>
<div class="member-dialog__benefit-info">
<span class="member-dialog__benefit-name">AI智能投递</span>
<span class="member-dialog__benefit-desc">会员专享</span>
</div>
</div>
<div class="member-dialog__benefit-card">
<div class="member-dialog__benefit-icon">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2639_2062)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.49998 1.66667C9.49998 1.62246 9.48242 1.58007 9.45116 1.54882C9.41991 1.51756 9.37752 1.5 9.33331 1.5H4.66665C4.18042 1.5 3.7141 1.69315 3.37028 2.03697C3.02647 2.38079 2.83331 2.8471 2.83331 3.33333V12.6667C2.83331 13.1529 3.02647 13.6192 3.37028 13.963C3.7141 14.3068 4.18042 14.5 4.66665 14.5H11.3333C11.8195 14.5 12.2859 14.3068 12.6297 13.963C12.9735 13.6192 13.1666 13.1529 13.1666 12.6667V6.098C13.1666 6.0538 13.1491 6.0114 13.1178 5.98015C13.0866 5.94889 13.0442 5.93133 13 5.93133H9.99998C9.86737 5.93133 9.74019 5.87865 9.64643 5.78489C9.55266 5.69112 9.49998 5.56394 9.49998 5.43133V1.66667ZM9.99998 8.16667C10.1326 8.16667 10.2598 8.21935 10.3535 8.31311C10.4473 8.40688 10.5 8.53406 10.5 8.66667C10.5 8.79927 10.4473 8.92645 10.3535 9.02022C10.2598 9.11399 10.1326 9.16667 9.99998 9.16667H5.99998C5.86737 9.16667 5.74019 9.11399 5.64643 9.02022C5.55266 8.92645 5.49998 8.79927 5.49998 8.66667C5.49998 8.53406 5.55266 8.40688 5.64643 8.31311C5.74019 8.21935 5.86737 8.16667 5.99998 8.16667H9.99998ZM9.99998 10.8333C10.1326 10.8333 10.2598 10.886 10.3535 10.9798C10.4473 11.0735 10.5 11.2007 10.5 11.3333C10.5 11.4659 10.4473 11.5931 10.3535 11.6869C10.2598 11.7807 10.1326 11.8333 9.99998 11.8333H5.99998C5.86737 11.8333 5.74019 11.7807 5.64643 11.6869C5.55266 11.5931 5.49998 11.4659 5.49998 11.3333C5.49998 11.2007 5.55266 11.0735 5.64643 10.9798C5.74019 10.886 5.86737 10.8333 5.99998 10.8333H9.99998Z" fill="#FFE2A1"/>
<path d="M10.5 1.88272C10.5 1.76005 10.6287 1.68205 10.724 1.75872C10.8049 1.82405 10.8767 1.90005 10.9393 1.98672L12.948 4.78472C12.9933 4.84872 12.944 4.93139 12.8653 4.93139H10.6667C10.6225 4.93139 10.5801 4.91383 10.5488 4.88257C10.5176 4.85131 10.5 4.80892 10.5 4.76472V1.88272Z" fill="#FFE2A1"/>
</g>
<defs>
<clipPath id="clip0_2639_2062">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>
</div>
<div class="member-dialog__benefit-info">
@@ -77,107 +47,184 @@
</div>
<div class="member-dialog__benefit-card">
<div class="member-dialog__benefit-icon">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
<rect width="24" height="24" rx="12" fill="#EDF9FA"/>
<path d="M12 7l1.5 3 3.5.5-2.5 2.5.5 3.5L12 15l-3 1.5.5-3.5L7 10.5l3.5-.5L12 7z" fill="#52CAD1"/>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.655 1.64404C8.70394 1.5974 8.76182 1.56116 8.82516 1.53753C8.8885 1.5139 8.95597 1.50335 9.0235 1.50654C11.9815 1.64504 14.355 4.01854 14.4935 6.97654C14.4967 7.04411 14.4861 7.11162 14.4624 7.17499C14.4388 7.23835 14.4025 7.29626 14.3558 7.3452C14.3091 7.39414 14.253 7.4331 14.1908 7.45971C14.1286 7.48632 14.0616 7.50004 13.994 7.50004H9C8.86739 7.50004 8.74021 7.44736 8.64645 7.35359C8.55268 7.25982 8.5 7.13264 8.5 7.00004V2.00604C8.49999 1.93835 8.51372 1.87136 8.54036 1.80913C8.567 1.74691 8.60601 1.69074 8.655 1.64404ZM7.345 3.14404C7.39399 3.19074 7.43299 3.24691 7.45964 3.30913C7.48628 3.37136 7.50001 3.43835 7.5 3.50604V7.25004C7.5 7.58156 7.6317 7.8995 7.86612 8.13392C8.10054 8.36834 8.41848 8.50004 8.75 8.50004H12.494C12.5617 8.49996 12.6287 8.51363 12.6909 8.54021C12.7532 8.5668 12.8094 8.60574 12.8561 8.65469C12.9029 8.70364 12.9392 8.76157 12.9629 8.82497C12.9866 8.88837 12.9972 8.95593 12.994 9.02354C12.85 12.0725 10.3335 14.5 7.25 14.5C4.0745 14.5 1.5 11.9255 1.5 8.75004C1.5 5.66604 3.9275 3.14954 6.9765 3.00654C7.04403 3.00335 7.1115 3.0139 7.17484 3.03753C7.23818 3.06116 7.29606 3.0974 7.345 3.14404Z" fill="#FFE2A1"/>
</svg>
</div>
<div class="member-dialog__benefit-info">
<span class="member-dialog__benefit-name">AI+投递助手</span>
<span class="member-dialog__benefit-desc">会员专享</span>
<span class="member-dialog__benefit-name">海量岗位数据</span>
<span class="member-dialog__benefit-desc">全网实时更新</span>
</div>
</div>
<div class="member-dialog__benefit-card">
<div class="member-dialog__benefit-icon">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2C11.4696 2 10.9609 2.21071 10.5858 2.58579C10.2107 2.96086 10 3.46957 10 4C10 4.53043 10.2107 5.03914 10.5858 5.41421C10.9609 5.78929 11.4696 6 12 6C12.5304 6 13.0391 5.78929 13.4142 5.41421C13.7893 5.03914 14 4.53043 14 4C14 3.46957 13.7893 2.96086 13.4142 2.58579C13.0391 2.21071 12.5304 2 12 2Z" fill="#FFE2A1"/>
<path d="M3.33333 2.66663C2.6 2.66663 2 3.26663 2 3.99996V12.6666C2 13.4 2.6 14 3.33333 14H12C12.7333 14 13.3333 13.4 13.3333 12.6666V6.67329C12.9267 6.87329 12.48 6.99996 12 6.99996C10.3467 6.99996 9 5.65329 9 3.99996C9 3.51996 9.12667 3.07329 9.32667 2.66663H3.33333Z" fill="#FFE2A1"/>
</svg>
</div>
<div class="member-dialog__benefit-info">
<span class="member-dialog__benefit-name">校招公告速递</span>
<span class="member-dialog__benefit-desc">名企动态抢先看</span>
</div>
</div>
</div>
</div>
<!-- 支付方式选择 -->
<div class="member-dialog__payment">
<span class="member-dialog__payment-label">选择支付方式</span>
<div class="member-dialog__payment-methods">
<div
class="member-dialog__payment-item"
:class="{ 'member-dialog__payment-item--wechat-active': selectedPayment === 'wechat' }"
@click="selectedPayment = 'wechat'"
>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M14 8c0 3.3-2.7 6-6 6s-6-2.7-6-6 2.7-6 6-6 6 2.7 6 6z" fill="#07C160"/>
<path d="M5.5 6.5c.5-.3 1.2-.1 1.5.4l.5 1 1.5-2c.3-.5 1-.6 1.5-.3.5.3.6 1 .3 1.5l-2.5 3.5c-.2.3-.5.4-.8.4-.3 0-.6-.1-.8-.4L5.2 8c-.3-.5-.2-1.2.3-1.5z" fill="white"/>
</svg>
<span class="member-dialog__payment-text member-dialog__payment-text--wechat">微信支付</span>
</div>
<div
class="member-dialog__payment-item"
:class="{ 'member-dialog__payment-item--alipay-active': selectedPayment === 'alipay' }"
@click="selectedPayment = 'alipay'"
>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
<rect width="16" height="16" rx="3" fill="#1677FF"/>
<text x="4" y="12" fill="white" font-size="10" font-weight="bold"></text>
</svg>
<span class="member-dialog__payment-text member-dialog__payment-text--alipay">支付宝支付</span>
<!-- 左右分割金边 -->
<div class="member-dialog__divider"></div>
<!-- 右侧内容区 -->
<div class="member-dialog__right">
<!-- 顶部标题行 -->
<div class="member-dialog__header">
<h2 class="member-dialog__title">会员中心</h2>
<div class="member-dialog__header-actions">
<!-- 联系客服 -->
<span class="member-dialog__contact-wrap">
<span class="member-dialog__contact">联系客服</span>
<div class="member-dialog__contact-qr">
<img src="@/assets/images/nav/kg-qcCode.png" alt="客服二维码" />
<div class="member-dialog__contact-qr-arrow"></div>
</div>
</span>
<!-- 关闭按钮 -->
<span class="member-dialog__close" @click="$emit('update:modelValue', false)"></span>
</div>
</div>
</div>
<!-- 购买按钮 -->
<button
class="member-dialog__buy-btn"
:class="{ 'member-dialog__buy-btn--active': selectedPayment }"
@click="handleBuy"
>购买会员</button>
</div>
</div>
<!-- ==================== 扫码支付弹窗 ==================== -->
<div v-if="showQrCode" class="member-dialog-overlay member-dialog-overlay--qrcode" @click="handleCloseQrCode">
<div class="member-dialog member-dialog--qrcode" @click.stop>
<!-- 顶部标题行 -->
<div class="member-dialog__header">
<div class="member-dialog__header-left">
<h2 class="member-dialog__title">扫码支付</h2>
<!-- 套餐选择区域 -->
<div class="member-dialog__plans">
<div
v-for="plan in plans"
:key="plan.key"
class="member-dialog__plan-card"
:class="{ 'member-dialog__plan-card--active': selectedPlan === plan.key }"
@click="selectedPlan = plan.key"
>
<!-- 推荐角标 -->
<div v-if="plan.recommend" class="member-dialog__plan-badge">超值推荐</div>
<!-- 套餐名称 -->
<div class="member-dialog__plan-name">{{ plan.name }}</div>
<!-- 价格行 -->
<div class="member-dialog__plan-price">
<span class="member-dialog__plan-price-symbol">¥</span>
<span class="member-dialog__plan-price-num">{{ plan.priceInt }}</span>
<span v-if="plan.originalPrice" class="member-dialog__plan-original">{{ plan.originalPrice }}</span>
</div>
<!-- 标签描述 -->
<div class="member-dialog__plan-tag">{{ plan.tag }}</div>
</div>
</div>
<div class="member-dialog__header-right">
<span class="member-dialog__close" @click="handleCloseQrCode"></span>
<!-- 步骤一选择支付方式 + 底部应付金额购买按钮未创建订单时显示 -->
<div v-if="!showQrCode" class="member-dialog__step-pay">
<!-- 支付方式选择 -->
<div class="member-dialog__payment-section">
<span class="member-dialog__payment-label">选择支付方式</span>
<div class="member-dialog__payment-methods">
<!-- 微信支付 -->
<div
class="member-dialog__payment-item"
:class="{ 'member-dialog__payment-item--active': selectedPayment === 'wechat' }"
@click="selectedPayment = 'wechat'"
>
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2639_1996)">
<path d="M20.8249 10.8533C21.3364 10.8533 21.8348 10.8933 22.32 10.96C21.4282 7 17.3364 4 12.4184 4C6.8446 4 2.32001 7.84 2.32001 12.5733C2.32001 15.3067 3.8282 17.72 6.17574 19.2933L4.85116 22L8.47083 20.4133C9.2446 20.6933 10.0577 20.92 10.9233 21.04C10.8053 20.52 10.7397 19.9867 10.7397 19.4267C10.7266 14.7067 15.2512 10.8533 20.8249 10.8533ZM15.7757 7.85333C15.9411 7.85333 16.1048 7.88644 16.2576 7.95077C16.4103 8.01509 16.5491 8.10938 16.666 8.22824C16.7829 8.3471 16.8757 8.4882 16.9389 8.6435C17.0022 8.7988 17.0348 8.96524 17.0348 9.13333C17.0348 9.30143 17.0022 9.46787 16.9389 9.62317C16.8757 9.77847 16.7829 9.91957 16.666 10.0384C16.5491 10.1573 16.4103 10.2516 16.2576 10.3159C16.1048 10.3802 15.9411 10.4133 15.7757 10.4133C15.4418 10.4133 15.1216 10.2785 14.8855 10.0384C14.6494 9.79838 14.5167 9.47281 14.5167 9.13333C14.5167 8.79386 14.6494 8.46828 14.8855 8.22824C15.1216 7.98819 15.4418 7.85333 15.7757 7.85333ZM9.04788 10.4267C8.71396 10.4267 8.39373 10.2918 8.15762 10.0518C7.92151 9.81172 7.78886 9.48614 7.78886 9.14667C7.78886 8.80719 7.92151 8.48162 8.15762 8.24157C8.39373 8.00152 8.71396 7.86667 9.04788 7.86667C9.38179 7.86667 9.70202 8.00152 9.93814 8.24157C10.1742 8.48162 10.3069 8.80719 10.3069 9.14667C10.3069 9.48614 10.1742 9.81172 9.93814 10.0518C9.70202 10.2918 9.38179 10.4267 9.04788 10.4267Z" fill="#07C160"/>
<path d="M29 19.6638C29 15.9818 25.1942 13 20.5 13C15.8058 13 12 15.9818 12 19.6638C12 23.3457 15.8058 26.3276 20.5 26.3276C21.2691 26.3276 22.0117 26.2239 22.7145 26.0683L27.3027 28L25.7114 24.8885C27.7005 23.6698 29 21.8029 29 19.6638ZM17.9407 19.2489C17.6889 19.2489 17.4428 19.1759 17.2335 19.0392C17.0241 18.9024 16.861 18.708 16.7646 18.4806C16.6683 18.2532 16.643 18.0029 16.6922 17.7615C16.7413 17.5201 16.8625 17.2983 17.0406 17.1243C17.2186 16.9502 17.4454 16.8317 17.6924 16.7836C17.9393 16.7356 18.1953 16.7603 18.4279 16.8545C18.6605 16.9487 18.8593 17.1082 18.9992 17.3129C19.1391 17.5175 19.2137 17.7582 19.2137 18.0043C19.227 18.6914 18.6435 19.2489 17.9407 19.2489ZM23.046 19.2489C22.7084 19.2489 22.3846 19.1178 22.1459 18.8844C21.9071 18.651 21.773 18.3344 21.773 18.0043C21.773 17.6742 21.9071 17.3577 22.1459 17.1243C22.3846 16.8909 22.7084 16.7597 23.046 16.7597C23.3836 16.7597 23.7074 16.8909 23.9462 17.1243C24.1849 17.3577 24.319 17.6742 24.319 18.0043C24.319 18.3344 24.1849 18.651 23.9462 18.8844C23.7074 19.1178 23.3836 19.2489 23.046 19.2489Z" fill="#07C160"/>
</g>
<defs>
<clipPath id="clip0_2639_1996">
<rect width="32" height="32" fill="white"/>
</clipPath>
</defs>
</svg>
<span class="member-dialog__payment-text">微信支付</span>
<!-- 选中圆圈 -->
<div class="member-dialog__payment-radio">
<div v-if="selectedPayment === 'wechat'" class="member-dialog__payment-radio-inner"></div>
</div>
</div>
<!-- 支付宝支付 -->
<div
class="member-dialog__payment-item"
:class="{ 'member-dialog__payment-item--active': selectedPayment === 'alipay' }"
@click="selectedPayment = 'alipay'"
>
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2639_2002)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.4127 4.03125C17.5281 4.03125 17.6226 4.12374 17.6226 4.23954V7.82858H25.2414C25.3583 7.82858 25.4488 7.92605 25.4492 8.0431C25.4496 8.79249 25.2601 9.75641 24.8287 9.75641H17.623V12.2974H22.8164C23.0565 12.2974 23.2477 12.5015 23.2303 12.7419L23.2267 12.7891C23.2051 15.6153 22.2698 18.4489 20.7417 20.9244L21.0142 21.0439C23.4297 22.0928 26.0812 22.9505 29.3624 23.0535C29.7298 23.0652 30.0163 23.3761 29.9993 23.7449L29.9929 23.8687C29.8888 25.7353 29.3682 28.0312 27.4979 28.0312C27.2227 28.0312 26.9576 28.014 26.7016 27.9808C24.2628 27.6909 21.8177 26.1933 19.3166 24.526L18.775 24.1633L18.3641 23.8868C17.6939 24.5493 16.9634 25.1524 16.1769 25.6805C15.9834 25.8062 15.779 25.9218 15.5652 26.0275C13.5181 27.2551 11.1213 27.9891 8.45844 27.9895C4.76459 27.9895 2.05466 25.5465 2.00081 22.4783L2 22.3858L2.00081 22.3325C2.05288 19.2583 4.65006 16.8441 8.34497 16.7956L8.45841 16.7949C11.6748 16.7949 14.2916 17.8455 16.9109 19.0864L16.9248 19.0984L16.978 18.9897C17.6426 17.6065 18.1167 16.0147 18.3135 14.2254L8.16359 14.2252C8.10869 14.2252 8.05603 14.2033 8.01716 14.1645C7.97829 14.1256 7.95638 14.0728 7.95622 14.0178C7.95497 13.333 8.14369 12.2974 8.57666 12.2974H13.6419V9.75641H5.99781C5.88084 9.75641 5.79044 9.65934 5.79044 9.54188C5.79 8.83332 5.97956 7.82858 6.41087 7.82858H13.6419V5.79663L13.6428 5.73444C13.6712 4.76532 14.3841 4.03125 17.4127 4.03125ZM8.028 19.3837C5.69156 19.3837 3.76147 20.6349 3.71934 22.3791L3.71875 22.4185L3.72122 22.5201C3.72714 22.6636 3.74369 22.8064 3.77072 22.9475C4.40375 25.9708 10.6506 27.0115 15.1562 21.801L14.9053 21.6531C12.6859 20.3584 10.4044 19.3837 8.028 19.3837Z" fill="#1677FF"/>
</g>
<defs>
<clipPath id="clip0_2639_2002">
<rect width="32" height="32" fill="white"/>
</clipPath>
</defs>
</svg>
<span class="member-dialog__payment-text">支付宝支付</span>
<!-- 选中圆圈 -->
<div class="member-dialog__payment-radio">
<div v-if="selectedPayment === 'alipay'" class="member-dialog__payment-radio-inner"></div>
</div>
</div>
</div>
</div>
</div>
<!-- 底部栏步骤一显示应付金额+购买按钮步骤二显示二维码+已支付 -->
<div class="member-dialog__bottom-bar" :class="{ 'member-dialog__bottom-bar--qrcode': showQrCode }">
<!-- 步骤一应付金额 + 购买按钮 -->
<template v-if="!showQrCode">
<div class="member-dialog__footer-price">
<span class="member-dialog__footer-price-label">应付金额</span>
<span class="member-dialog__footer-price-symbol">¥</span>
<span class="member-dialog__footer-price-num">{{ currentPlan.priceInt }}</span>
</div>
<button
class="member-dialog__buy-btn"
:disabled="!selectedPayment"
@click="handleBuy"
>购买会员</button>
</template>
<!-- 步骤二扫码支付区域 -->
<template v-else>
<!-- 二维码 -->
<div class="member-dialog__qrcode-box">
<!-- 支付宝iframe 渲染 -->
<iframe
v-if="selectedPayment === 'alipay' && paymentFormHtml"
:srcdoc="paymentFormHtml"
frameborder="0"
class="member-dialog__qrcode-iframe qrcode-zhifubao"
scrolling="auto"
></iframe>
<!-- 微信qrcode.js 渲染 -->
<iframe
v-if="selectedPayment === 'wechat' && wechatCodeUrl"
:srcdoc="wechatQrHtml"
frameborder="0"
class="member-dialog__qrcode-iframe qrcode-wechat"
scrolling="no"
></iframe>
</div>
<!-- 右侧信息 -->
<div class="member-dialog__qrcode-info">
<div class="member-dialog__qrcode-price-row">
<span class="member-dialog__qrcode-price-num">¥{{ currentPlan.priceInt }}</span>
<span class="member-dialog__qrcode-tip">扫码完成支付</span>
</div>
<p class="member-dialog__qrcode-agreement">
开通即代表同意 <a href="javascript:;" @click.prevent="openMemberAgreement">会员服务协议</a>
</p>
<!-- 已支付成功按钮 -->
<button class="member-dialog__paid-btn" @click="handleConfirmPaid">我已支付成功</button>
</div>
</template>
</div>
</div>
<!-- 二维码区域 -->
<div class="member-dialog__qrcode-content">
<!-- 支付宝iframe 渲染支付表单 -->
<div v-if="selectedPayment === 'alipay' && paymentFormHtml" class="member-dialog__qrcode-image">
<iframe
:srcdoc="paymentFormHtml"
frameborder="0"
class="member-dialog__payment-iframe"
scrolling="auto"
></iframe>
</div>
<!-- 微信使用 qrcode.js 渲染二维码 -->
<div v-if="selectedPayment === 'wechat' && wechatCodeUrl" class="member-dialog__qrcode-image">
<iframe
:srcdoc="wechatQrHtml"
frameborder="0"
class="member-dialog__wechat-qr-iframe"
scrolling="no"
></iframe>
</div>
<!-- 金额和提示 -->
<div class="member-dialog__qrcode-price-row">
<span class="member-dialog__qrcode-price">¥{{ currentPlan.priceInt }}</span>
<span class="member-dialog__qrcode-tip">扫码完成支付</span>
</div>
<!-- 协议提示 -->
<p class="member-dialog__qrcode-agreement">
开通即代表同意 <a href="javascript:;" @click.prevent="openMemberAgreement">会员服务协议</a>
</p>
</div>
<!-- 已支付成功按钮 -->
<button class="member-dialog__paid-btn" @click="handleConfirmPaid">已支付成功</button>
</div>
</div>
@@ -203,19 +250,14 @@ const store = useStore()
// ==================== 类型定义 ====================
/** 套餐项类型(包含后端完整数据 + 前端展示字段) */
/** 套餐项类型 */
interface PlanItem {
key: string
name: string
/** 整数价格(元),用于显示 */
priceInt: string
/** 划线价(元) */
originalPrice: string
/** 标签描述(接口tag字段,如"轻量体验"、"低至¥0.56/天" */
tag: string
/** 是否推荐 */
recommend?: boolean
/** 后端原始数据,下单时使用 */
raw: MemberProduct
}
@@ -224,22 +266,22 @@ interface PlanItem {
/** 当前选中的套餐 key */
const selectedPlan = ref('')
/** 当前选中的支付方式wechat / alipay),默认不选 */
/** 当前选中的支付方式 */
const selectedPayment = ref('')
/** 是否显示扫码支付弹窗 */
/** 是否显示扫码支付区域 */
const showQrCode = ref(false)
/** 支付宝表单 HTML(用于 iframe 渲染) */
/** 支付宝表单 HTML */
const paymentFormHtml = ref('')
/** 微信支付 code_url(用于生成二维码) */
/** 微信支付 code_url */
const wechatCodeUrl = ref('')
/** 微信二维码 iframe srcdoc HTML */
/** 微信二维码 iframe srcdoc */
const wechatQrHtml = computed(() => {
if (!wechatCodeUrl.value) return ''
return `<!DOCTYPE html><html><head><meta charset="UTF-8"><script src="https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js"><\/script><style>body{display:flex;align-items:center;justify-content:center;margin:0;height:100%;}</style></head><body><div id="qrcode"></div><script>new QRCode(document.getElementById("qrcode"),{text:"${wechatCodeUrl.value}",width:210,height:210,colorDark:"#000000",colorLight:"#ffffff",correctLevel:QRCode.CorrectLevel.H});<\/script></body></html>`
return `<!DOCTYPE html><html><head><meta charset="UTF-8"><script src="https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js"><\/script><style>body{display:flex;align-items:center;justify-content:center;margin:0;height:100%;}</style></head><body><div id="qrcode"></div><script>new QRCode(document.getElementById("qrcode"),{text:"${wechatCodeUrl.value}",width:160,height:160,colorDark:"#000000",colorLight:"#ffffff",correctLevel:QRCode.CorrectLevel.H});<\/script></body></html>`
})
/** 当前订单ID */
@@ -248,12 +290,12 @@ const orderId = ref('')
/** 是否正在创建订单 */
const creatingOrder = ref(false)
/** 协议预览弹窗显示状态 */
/** 协议预览弹窗 */
const showAgreementDialog = ref(false)
// ==================== 监听 ====================
/** 监听弹窗开关 — 打开时锁定背景滚动,关闭时恢复并重置状态 */
/** 监听弹窗开关 */
watch(() => props.modelValue, (val) => {
document.body.style.overflow = val ? 'hidden' : ''
if (!val) {
@@ -274,18 +316,14 @@ const currentPlan = computed(() => {
// ==================== 数据 ====================
/** 套餐列表(从接口获取) */
/** 套餐列表 */
const plans = ref<PlanItem[]>([])
/** 后端商品数据转换为前端套餐项 */
/** 后端商品数据转换 */
function mapProductToPlan(product: MemberProduct): PlanItem {
// 分转元,直接除以100不四舍五入
const priceYuan = product.price / 100
const originalPriceYuan = product.originalPrice ? product.originalPrice / 100 : 0
// 直接使用接口返回的 productName 作为套餐名称
const name = product.productName
// 价格显示:如果是整数就不显示小数,否则保留实际小数
const priceDisplay = Number.isInteger(priceYuan) ? String(priceYuan) : priceYuan.toFixed(2)
const originalDisplay = originalPriceYuan > priceYuan
? `¥${Number.isInteger(originalPriceYuan) ? originalPriceYuan : originalPriceYuan.toFixed(2)}`
@@ -309,7 +347,6 @@ async function loadMemberProducts() {
if (res.data && res.data.length) {
const sorted = [...res.data].sort((a, b) => a.sortOrder - b.sortOrder)
plans.value = sorted.map(mapProductToPlan)
// 默认选中推荐套餐(季卡),若无则选第一个
const featured = plans.value.find(p => p.recommend)
selectedPlan.value = featured ? featured.key : plans.value[0].key
}
@@ -318,7 +355,6 @@ async function loadMemberProducts() {
}
}
/** 组件挂载时加载商品列表 */
onMounted(() => {
loadMemberProducts()
})
@@ -352,8 +388,6 @@ async function handleBuy() {
wechatCodeUrl.value = ''
}
showQrCode.value = true
// 【注释掉自动轮询,后续如需恢复取消注释即可】
// confirmPaymentPolling()
}
} catch (e) {
console.error('创建订单失败', e)
@@ -362,67 +396,18 @@ async function handleBuy() {
}
}
// /** 轮询计时器 */
// let pollTimer: ReturnType<typeof setInterval> | null = null
// /**
// * 自动轮询查询订单支付状态(已关闭,保留逻辑防止后续要用)
// * 支付成功后自动关闭弹窗并刷新会员状态
// */
// async function confirmPaymentPolling() {
// const startTime = Date.now()
// const timeout = 5 * 60 * 1000 // 5分钟超时
// const interval = 500
//
// if (pollTimer) {
// clearInterval(pollTimer)
// pollTimer = null
// }
//
// pollTimer = setInterval(async () => {
// try {
// const res = await fetchOrderDetail(orderId.value)
// const status = res.data?.status
//
// if (status === 1) {
// clearInterval(pollTimer!)
// pollTimer = null
// showQrCode.value = false
// ElMessage.success('开通成功')
// emit('update:modelValue', false)
// store.dispatch('loadMemberStatus')
// } else if (status === 2 || status === 3) {
// clearInterval(pollTimer!)
// pollTimer = null
// showQrCode.value = false
// ElMessage.error('支付未成功,请重新下单')
// } else if (Date.now() - startTime >= timeout) {
// clearInterval(pollTimer!)
// pollTimer = null
// showQrCode.value = false
// ElMessage.error('支付超时,请重新下单')
// }
// } catch (e) {
// console.error('查询订单状态失败', e)
// }
// }, interval)
// }
/** 点击"已支付成功"按钮 — 手动查询一次订单状态 */
/** 点击"我已支付成功"按钮 */
async function handleConfirmPaid() {
if (!orderId.value) return
try {
const res = await fetchOrderDetail(orderId.value)
const status = res.data?.status
if (status === 1) {
// 支付成功 — 关闭弹窗,刷新会员状态
showQrCode.value = false
ElMessage.success('开通成功')
emit('update:modelValue', false)
// 刷新 vuex 中的会员状态
store.dispatch('loadMemberStatus')
} else {
// 未支付成功
ElMessage.warning('未查询到支付订单,请再次确认')
}
} catch (e) {
@@ -431,11 +416,6 @@ async function handleConfirmPaid() {
}
}
/** 关闭扫码支付弹窗 */
function handleCloseQrCode() {
showQrCode.value = false
}
/** 打开会员服务协议 */
function openMemberAgreement() {
showAgreementDialog.value = true
+50 -26
View File
@@ -1,10 +1,11 @@
<template>
<div class="side-nav">
<div class="side-nav" :class="{ 'side-nav--narrow': isNarrow }">
<!-- 顶部 Logo -->
<div class="side-nav__header">
<!-- 侧边栏Logo图片 -->
<img src="@/assets/images/logo.png" alt="Offer派" class="side-nav__logo-img" />
<!-- 窄版Logologo-min.png -->
<img v-if="isNarrow" src="@/assets/images/logo-min.png" alt="Offer派" class="side-nav__logo-img side-nav__logo-img--narrow" />
<!-- 宽版Logo -->
<img v-else src="@/assets/images/logo.png" alt="Offer派" class="side-nav__logo-img" />
</div>
<!-- 主导航 -->
@@ -20,16 +21,19 @@
@mouseleave="hoverIndex = -1"
>
<!-- SVG图标hover/active 状态显示选中图标否则显示默认图标 -->
<span
<span class="side-nav__item-icon" v-if="index==9">
</span>
<span v-else
class="side-nav__item-icon"
v-html="(isActive(item.name) || hoverIndex === index) && getActiveIcon(index) ? getActiveIcon(index) : item.iconImg"
></span>
<span class="side-nav__item-label">{{ item.label }}</span>
<!-- 索引0的时候显示"全网"小标签 -->
<span v-if="index === 0" class="side-nav__tag-quanwang mt2 ml8">全网</span>
<span v-if="index === 0" class="side-nav__tag-quanwang" :class="{ 'side-nav__tag-quanwang--corner': isNarrow, 'mt2 ml8': !isNarrow }">全网</span>
<!-- 索引5的时候显示"公测群"小标签 -->
<span v-if="index === 5" class="side-nav__tag-quanwang mt2 ml8">公测群</span>
<!-- 索引5的时候显示"公测群"/"加群"小标签 -->
<span v-if="index === 5" class="side-nav__tag-quanwang" :class="{ 'side-nav__tag-quanwang--corner': isNarrow, 'mt2 ml8': !isNarrow }">{{ isNarrow ? '加群' : '公测群' }}</span>
<!-- 索引5 hover时显示公测群二维码 -->
<div v-if="index === 5 && hoverIndex === 5" class="side-nav__qrcode-popup">
<img src="https://offerpie.oss-cn-guangzhou.aliyuncs.com/images/mobile-qcCode.png" alt="公测群二维码" class="side-nav__qrcode-img" />
@@ -42,16 +46,21 @@
<!-- 底部菜单 -->
<div class="side-nav__footer">
<!-- 邀请会员卡片 -->
<div class="side-nav__referral-card cursor-po" @click="showShareDialog = true">
<!-- 顶部标题区域 -->
<div class="side-nav__referral-title">邀请好友送 7 天会员</div>
<div class="side-nav__referral-subtitle">好友加入后自动到账</div>
<!-- 白色面板 -->
<!-- 宽版邀请会员卡片 -->
<div v-if="!isNarrow" class="side-nav__referral-card cursor-po" @click="showShareDialog = true">
<!-- 顶部区域标题 + 礼物图片 -->
<div class="side-nav__referral-top">
<div class="side-nav__referral-top-text">
<div class="side-nav__referral-title">邀请好友<span class="side-nav__referral-title--accent">得会员</span></div>
<div class="side-nav__referral-subtitle">邀1人得7天</div>
</div>
<img src="@/assets/images/nav/gift.png" alt="礼物" class="side-nav__referral-gift" />
</div>
<!-- 白色毛玻璃面板遮住礼物底部 -->
<div class="side-nav__referral-panel">
<!-- 邀请进度行 -->
<!-- 年卡进度行 -->
<div class="side-nav__referral-row">
<span class="side-nav__referral-label">邀请进度</span>
<span class="side-nav__referral-label">年卡进度</span>
<span class="side-nav__referral-value">{{ milestoneProgress }}/{{ milestoneTarget }}</span>
</div>
<!-- 进度条 -->
@@ -59,13 +68,15 @@
<div class="side-nav__referral-fill" :style="{ width: inviteProgressPercent + '%' }"></div>
</div>
<!-- 提示文字 -->
<div class="side-nav__referral-tip">再邀 <strong>{{ inviteRemaining }}</strong> 可获得年会员</div>
<!-- 分隔线 -->
<div class="side-nav__referral-divider"></div>
<div class="side-nav__referral-tip">再邀 <strong>{{ inviteRemaining }}</strong> 可获得年</div>
<!-- 去邀请按钮 -->
<div class="side-nav__referral-action">去邀请</div>
</div>
</div>
<!-- 窄版邀请图片卡片 -->
<div v-if="isNarrow" class="side-nav__referral-card-narrow cursor-po" @click="showShareDialog = true">
<img src="@/assets/images/nav/referral-card-min.png" alt="邀请有礼" class="side-nav__referral-card-narrow-img" />
</div>
<!-- 用户信息模块 -->
<div class="side-nav__user-info-wrapper" v-if="store.state.isAuthenticated && store.state.userInfo">
@@ -87,12 +98,15 @@
<div class="side-nav__account-popup-item" @click="handleAccountLogout">退出登录</div>
</div>
<!-- 窄版用户信息只显示头像+会员标签 -->
<div v-if="isNarrow" class="side-nav__user-info-narrow" @click.stop="showAccountPopup = !showAccountPopup">
<img src="@/assets/images/nav/avatar-default.png" alt="用户头像" class="side-nav__user-avatar-narrow" />
<!-- 会员标签 -->
<div class="side-nav__user-member-tag" :class="memberTagClass">{{ memberTagText }}</div>
</div>
<!-- 用户信息卡片点击弹出/关闭账户弹窗 -->
<div class="side-nav__user-info" :class="{ 'side-nav__user-info--active': showAccountPopup }" @click.stop="showAccountPopup = !showAccountPopup">
<!-- 宽版用户信息卡片点击弹出/关闭账户弹窗 -->
<div v-if="!isNarrow" class="side-nav__user-info" :class="{ 'side-nav__user-info--active': showAccountPopup }" @click.stop="showAccountPopup = !showAccountPopup">
<div class="side-nav__user-left">
<!-- 手机号脱敏显示 -->
<div class="side-nav__user-phone">{{ maskedPhone }}</div>
@@ -276,7 +290,7 @@ import navMentorIcon from '@/assets/images/nav/nav-profile-icon.png'
*/
const activeIconSvgs: string[] = [
// 索引0 — 职位(Jobs
'<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0_268_1536)"><path d="M7.66664 2.16669C6.78388 2.16674 5.91411 2.37928 5.13081 2.78634C4.34751 3.1934 3.6737 3.78302 3.16631 4.50539C2.65891 5.22775 2.33285 6.06164 2.21567 6.93658C2.09849 7.81152 2.19362 8.70182 2.49305 9.53224C2.79247 10.3627 3.28738 11.1088 3.93596 11.7077C4.58454 12.3065 5.36773 12.7404 6.21936 12.9728C7.07099 13.2051 7.96603 13.229 8.82886 13.0426C9.6917 12.8561 10.497 12.4647 11.1766 11.9014L12.962 13.6867C13.0568 13.775 13.1821 13.8231 13.3117 13.8208C13.4412 13.8185 13.5648 13.766 13.6564 13.6744C13.748 13.5828 13.8005 13.4592 13.8028 13.3297C13.805 13.2002 13.757 13.0748 13.6686 12.98L11.8853 11.196C12.5567 10.3935 12.9853 9.41618 13.1208 8.37866C13.2562 7.34115 13.0929 6.28652 12.65 5.33856C12.2071 4.3906 11.503 3.58865 10.6203 3.02682C9.73759 2.465 8.71296 2.16661 7.66664 2.16669Z" fill="#52CAD1"/></g><defs><clipPath id="clip0_268_1536"><rect width="16" height="16" fill="white"/></clipPath></defs></svg>',
'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0_2834_6536)"><path d="M11.5 3.25C10.1759 3.25009 8.87121 3.56889 7.69626 4.17948C6.52131 4.79007 5.51059 5.67451 4.7495 6.75805C3.98842 7.8416 3.49932 9.09242 3.32355 10.4048C3.14777 11.7173 3.29048 13.0527 3.73962 14.2983C4.18875 15.544 4.93112 16.6632 5.90398 17.5614C6.87685 18.4597 8.05164 19.1106 9.32908 19.4591C10.6065 19.8076 11.9491 19.8435 13.2433 19.5638C14.5376 19.2841 15.7455 18.697 16.765 17.852L19.443 20.53C19.5852 20.6625 19.7732 20.7346 19.9675 20.7312C20.1618 20.7277 20.3472 20.649 20.4846 20.5116C20.622 20.3742 20.7008 20.1888 20.7042 19.9945C20.7076 19.8002 20.6355 19.6122 20.503 19.47L17.828 16.794C18.8351 15.5903 19.478 14.1242 19.6812 12.568C19.8843 11.0117 19.6394 9.42975 18.975 8.00781C18.3107 6.58587 17.2545 5.38294 15.9305 4.54021C14.6064 3.69747 13.0695 3.24989 11.5 3.25Z" fill="#52CAD1"/></g><defs><clipPath id="clip0_2834_6536"><rect width="24" height="24" fill="white"/></clipPath></defs></svg>',
// 索引1 — 第二个菜单项(待替换)
'<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0_268_1540)"><path fill-rule="evenodd" clip-rule="evenodd" d="M9.49998 1.66667C9.49998 1.62246 9.48242 1.58007 9.45116 1.54882C9.41991 1.51756 9.37752 1.5 9.33331 1.5H4.66665C4.18042 1.5 3.7141 1.69315 3.37028 2.03697C3.02647 2.38079 2.83331 2.8471 2.83331 3.33333V12.6667C2.83331 13.1529 3.02647 13.6192 3.37028 13.963C3.7141 14.3068 4.18042 14.5 4.66665 14.5H11.3333C11.8195 14.5 12.2859 14.3068 12.6297 13.963C12.9735 13.6192 13.1666 13.1529 13.1666 12.6667V6.098C13.1666 6.0538 13.1491 6.0114 13.1178 5.98015C13.0866 5.94889 13.0442 5.93133 13 5.93133H9.99998C9.86737 5.93133 9.74019 5.87865 9.64643 5.78489C9.55266 5.69112 9.49998 5.56394 9.49998 5.43133V1.66667ZM9.99998 8.16667C10.1326 8.16667 10.2598 8.21935 10.3535 8.31311C10.4473 8.40688 10.5 8.53406 10.5 8.66667C10.5 8.79927 10.4473 8.92645 10.3535 9.02022C10.2598 9.11399 10.1326 9.16667 9.99998 9.16667H5.99998C5.86737 9.16667 5.74019 9.11399 5.64643 9.02022C5.55266 8.92645 5.49998 8.79927 5.49998 8.66667C5.49998 8.53406 5.55266 8.40688 5.64643 8.31311C5.74019 8.21935 5.86737 8.16667 5.99998 8.16667H9.99998ZM9.99998 10.8333C10.1326 10.8333 10.2598 10.886 10.3535 10.9798C10.4473 11.0735 10.5 11.2007 10.5 11.3333C10.5 11.4659 10.4473 11.5931 10.3535 11.6869C10.2598 11.7807 10.1326 11.8333 9.99998 11.8333H5.99998C5.86737 11.8333 5.74019 11.7807 5.64643 11.6869C5.55266 11.5931 5.49998 11.4659 5.49998 11.3333C5.49998 11.2007 5.55266 11.0735 5.64643 10.9798C5.74019 10.886 5.86737 10.8333 5.99998 10.8333H9.99998Z" fill="#52CAD1"/><path d="M10.5 1.88266C10.5 1.75999 10.6287 1.68199 10.724 1.75866C10.8049 1.82399 10.8767 1.89999 10.9393 1.98666L12.948 4.78466C12.9933 4.84866 12.944 4.93132 12.8653 4.93132H10.6667C10.6225 4.93132 10.5801 4.91377 10.5488 4.88251C10.5176 4.85125 10.5 4.80886 10.5 4.76466V1.88266Z" fill="#52CAD1"/></g><defs><clipPath id="clip0_268_1540"><rect width="16" height="16" fill="white"/></clipPath></defs></svg>',
// 索引2 — 第三个菜单项(待替换)
@@ -286,7 +300,7 @@ const activeIconSvgs: string[] = [
// 索引4 — 第五个菜单项(待替换)
'<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip0_268_1538)"><path d="M6.07134 3.63198C6.47001 2.46531 8.08201 2.42998 8.55468 3.52598L8.59468 3.63265L9.13268 5.20598C9.25597 5.5668 9.45521 5.89699 9.71696 6.17426C9.97871 6.45154 10.2969 6.66945 10.65 6.81331L10.7947 6.86731L12.368 7.40465C13.5347 7.80331 13.57 9.41531 12.4747 9.88798L12.368 9.92798L10.7947 10.466C10.4337 10.5892 10.1034 10.7884 9.82602 11.0502C9.54863 11.3119 9.33061 11.6301 9.18668 11.9833L9.13268 12.1273L8.59534 13.7013C8.19668 14.868 6.58468 14.9033 6.11268 13.808L6.07134 13.7013L5.53401 12.128C5.4108 11.767 5.21159 11.4367 4.94984 11.1593C4.68808 10.8819 4.36987 10.6639 4.01668 10.52L3.87268 10.466L2.29934 9.92865C1.13201 9.52998 1.09668 7.91798 2.19268 7.44598L2.29934 7.40465L3.87268 6.86731C4.2335 6.74402 4.56368 6.54478 4.84096 6.28303C5.11823 6.02128 5.33615 5.70311 5.48001 5.34998L5.53401 5.20598L6.07134 3.63198ZM12.6667 1.33331C12.7914 1.33331 12.9136 1.3683 13.0194 1.43429C13.1253 1.50029 13.2105 1.59465 13.2653 1.70665L13.2973 1.78465L13.5307 2.46865L14.2153 2.70198C14.3403 2.74444 14.4499 2.82306 14.5302 2.92786C14.6104 3.03266 14.6578 3.15893 14.6662 3.29066C14.6746 3.4224 14.6437 3.55367 14.5775 3.66784C14.5112 3.78201 14.4126 3.87394 14.294 3.93198L14.2153 3.96398L13.5313 4.19731L13.298 4.88198C13.2555 5.00693 13.1768 5.11645 13.072 5.19664C12.9671 5.27684 12.8408 5.32411 12.7091 5.33246C12.5774 5.34081 12.4461 5.30988 12.332 5.24357C12.2179 5.17726 12.126 5.07856 12.068 4.95998L12.036 4.88198L11.8027 4.19798L11.118 3.96465C10.993 3.92218 10.8835 3.84357 10.8032 3.73877C10.7229 3.63397 10.6756 3.5077 10.6672 3.37597C10.6587 3.24423 10.6896 3.11296 10.7559 2.99879C10.8221 2.88462 10.9208 2.79269 11.0393 2.73465L11.118 2.70265L11.802 2.46931L12.0353 1.78465C12.0803 1.65293 12.1653 1.53859 12.2786 1.45765C12.3918 1.37671 12.5275 1.33323 12.6667 1.33331Z" fill="#52CAD1"/></g><defs><clipPath id="clip0_268_1538"><rect width="16" height="16" fill="white"/></clipPath></defs></svg>',
// 索引5 — 第六个菜单项(待替换)
'<svg width="14" height="13" viewBox="0 0 14 13" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M2.66667 10.6667L1.13333 12.2C0.922223 12.4111 0.680446 12.4584 0.408001 12.342C0.135557 12.2256 -0.000443359 12.0171 1.08578e-06 11.7167V1.33333C1.08578e-06 0.966667 0.130668 0.652889 0.392001 0.392C0.653334 0.131111 0.967112 0.000444444 1.33333 0H12C12.3667 0 12.6807 0.130667 12.942 0.392C13.2033 0.653333 13.3338 0.967111 13.3333 1.33333V9.33333C13.3333 9.7 13.2029 10.014 12.942 10.2753C12.6811 10.5367 12.3671 10.6671 12 10.6667H2.66667ZM6.66667 8.66667C6.85556 8.66667 7.014 8.60267 7.142 8.47467C7.27 8.34667 7.33378 8.18845 7.33333 8C7.33289 7.81156 7.26889 7.65333 7.14133 7.52533C7.01378 7.39733 6.85556 7.33333 6.66667 7.33333C6.47778 7.33333 6.31956 7.39733 6.192 7.52533C6.06445 7.65333 6.00045 7.81156 6 8C5.99956 8.18845 6.06356 8.34689 6.192 8.47533C6.32045 8.60378 6.47867 8.66756 6.66667 8.66667ZM7.142 5.808C7.26956 5.68044 7.33333 5.52222 7.33333 5.33333V2.66667C7.33333 2.47778 7.26933 2.31956 7.14133 2.192C7.01333 2.06444 6.85511 2.00044 6.66667 2C6.47822 1.99956 6.32 2.06356 6.192 2.192C6.064 2.32044 6 2.47867 6 2.66667V5.33333C6 5.52222 6.064 5.68067 6.192 5.80867C6.32 5.93667 6.47822 6.00044 6.66667 6C6.85511 5.99956 7.01356 5.93556 7.142 5.808Z" fill="#52CAD1"/></svg>',
'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9.94013 1.97814C11.1383 0.940907 12.8621 0.940856 14.0602 1.97814C15.0132 2.80372 16.382 4.05138 18.1647 5.83458C19.9482 7.61754 21.197 8.98606 22.0222 9.93907C23.0594 11.1373 23.0594 12.862 22.0222 14.0602C21.1965 15.0137 19.9482 16.3812 18.1647 18.1647C16.3818 19.9481 15.0133 21.1965 14.0602 22.0221C12.862 23.0593 11.1373 23.0594 9.93915 22.0221C8.98613 21.1965 7.61762 19.9481 5.83466 18.1647C4.05133 16.3818 2.80336 15.0132 1.97821 14.0602C0.940907 12.8619 0.940907 11.1373 1.97821 9.93907C2.80384 8.98606 4.05134 7.61743 5.83466 5.83458C7.61762 4.05114 8.98711 2.80329 9.94013 1.97814ZM11.9997 14.567C11.5396 14.5672 11.1667 14.9399 11.1667 15.4V15.4996C11.1667 15.9597 11.5396 16.3334 11.9997 16.3336H12.0993C12.5595 16.3336 12.9332 15.9598 12.9333 15.4996V15.4C12.9333 14.9398 12.5595 14.567 12.0993 14.567H11.9997ZM12.0495 7.567C11.5895 7.56727 11.2165 7.93994 11.2165 8.40001V12.4C11.2166 12.86 11.5895 13.2328 12.0495 13.233C12.5097 13.233 12.8834 12.8602 12.8835 12.4V8.40001C12.8835 7.93977 12.5097 7.567 12.0495 7.567Z" fill="#52CAD1"/></svg>',
]
/**
@@ -392,6 +406,14 @@ const mainMenus = computed<MenuItem[]>(() => {
})
const showShareDialog = ref(false)
/** 是否为窄版导航(窗口宽度 < 1440px */
const isNarrow = ref(window.innerWidth < 1440)
/** 监听窗口宽度变化,动态切换窄版/宽版 */
function handleNavResize() {
isNarrow.value = window.innerWidth < 1440
}
const showMessageDialog = ref(false)
const showFeedbackDialog = ref(false)
/** 当前hover的菜单索引,-1表示无hover */
@@ -758,10 +780,12 @@ onMounted(() => {
loadUnreadCount()
loadInviteStats()
document.addEventListener('click', handleGlobalClick)
window.addEventListener('resize', handleNavResize)
})
onUnmounted(() => {
document.removeEventListener('click', handleGlobalClick)
window.removeEventListener('resize', handleNavResize)
})
/**
+43 -9
View File
@@ -16,13 +16,15 @@
</svg>
</div>
<!-- 下拉面板 -->
<div
v-if="visible"
class="industry-selector__panel"
:class="{ 'industry-selector__panel--one-col': level === 1 }"
@click.stop
>
<!-- 下拉面板Teleport到body避免被父级overflow:hidden裁切 -->
<Teleport to="body">
<div
v-if="visible"
class="industry-selector__panel"
:class="{ 'industry-selector__panel--one-col': level === 1 }"
:style="panelStyle"
@click.stop
>
<!-- 选中区小方块标签展示已选中的行业名称 -->
<div class="industry-selector__selected-area" v-if="selectedItems.length">
@@ -118,6 +120,7 @@
<button class="industry-selector__btn industry-selector__btn--confirm" @click="handleConfirm">确认</button>
</div>
</div>
</Teleport>
</div>
</template>
@@ -154,6 +157,8 @@ const props = withDefaults(
hoverStyle?: Record<string, string>
/** 父组件传入的显示文字自定义样式,用于覆盖 max-width 等默认样式 */
displayStyle?: Record<string, string>
/** 自定义触发按钮默认文字,传入后替换"行业" */
triggerLabel?: string
}>(),
{
maxSelect: 3,
@@ -171,6 +176,27 @@ const store = useStore()
/** 组件根元素引用,用于点击外部关闭判断 */
const selectorRef = ref<HTMLElement | null>(null)
/** 面板的固定定位样式(基于trigger按钮位置动态计算) */
const panelStyle = ref<Record<string, string>>({})
/** 计算面板位置(考虑body transform scale */
function updatePanelPosition() {
if (!selectorRef.value) return
const rect = selectorRef.value.getBoundingClientRect()
// 获取body的scale比例(小屏缩放场景)
const bodyTransform = document.body.style.transform
let scale = 1
const scaleMatch = bodyTransform.match(/scale\(([\d.]+)\)/)
if (scaleMatch) scale = parseFloat(scaleMatch[1]) || 1
// fixed定位在有transform的body内,坐标需除以scale
panelStyle.value = {
position: 'fixed',
top: `${(rect.bottom + 6) / scale}px`,
right: `${(window.innerWidth - rect.right) / scale}px`,
'z-index': '2000',
}
}
// ==================== 响应式状态 ====================
/** 下拉面板是否可见 */
@@ -202,8 +228,9 @@ const industries = computed<IndustryItem[]>(() => store.state.industries)
/** 已选中行业 ID 集合,用于快速判断某项是否选中 */
const selectedIdSet = computed(() => new Set(selectedItems.value.map(i => i.id)))
/** 触发按钮显示文字:无选中显示"行业",有选中则用逗号拼接名称 */
/** 触发按钮显示文字:传了triggerLabel就始终显示它,否则无选中显示默认文字,有选中则用逗号拼接名称 */
const displayText = computed(() => {
if (props.triggerLabel) return props.triggerLabel
if (!selectedItems.value.length) return '行业'
return selectedItems.value.map(i => i.name).join('')
})
@@ -394,12 +421,19 @@ function toggleDropdown() {
if (industries.value.length && !activeParentId.value) {
activeParentId.value = industries.value[0].id
}
// 计算面板位置
updatePanelPosition()
}
}
/** 点击组件外部时关闭下拉面板 */
function onClickOutside(e: MouseEvent) {
if (selectorRef.value && !selectorRef.value.contains(e.target as Node)) {
const target = e.target as Node
// 判断点击是否在组件根元素或Teleport的面板内
if (selectorRef.value && !selectorRef.value.contains(target)) {
// 检查是否点击在面板内(Teleport到body的面板)
const panel = document.querySelector('.industry-selector__panel')
if (panel && panel.contains(target)) return
visible.value = false
}
}
+42 -12
View File
@@ -16,16 +16,18 @@
</svg>
</div>
<!-- 下拉面板 -->
<div
v-if="visible"
class="job-category-selector__panel"
:class="{
'job-category-selector__panel--one-col': level === 1,
'job-category-selector__panel--two-col': level === 2
}"
@click.stop
>
<!-- 下拉面板Teleport到body避免被父级overflow:hidden裁切 -->
<Teleport to="body">
<div
v-if="visible"
class="job-category-selector__panel"
:class="{
'job-category-selector__panel--one-col': level === 1,
'job-category-selector__panel--two-col': level === 2
}"
:style="panelStyle"
@click.stop
>
<!-- 选中区小方块标签展示已选中的岗位名称 -->
<div class="job-category-selector__selected-area" v-if="selectedItems.length">
@@ -141,6 +143,7 @@
<button class="job-category-selector__btn job-category-selector__btn--confirm" @click="handleConfirm">确认</button>
</div>
</div>
</Teleport>
</div>
</template>
@@ -177,6 +180,8 @@ const props = withDefaults(
hoverStyle?: Record<string, string>
/** 父组件传入的显示文字自定义样式,用于覆盖 max-width 等默认样式 */
displayStyle?: Record<string, string>
/** 自定义触发按钮默认文字,传入后替换"岗位" */
triggerLabel?: string
}>(),
{
maxSelect: 3,
@@ -194,6 +199,25 @@ const store = useStore()
/** 组件根元素引用,用于点击外部关闭判断 */
const selectorRef = ref<HTMLElement | null>(null)
/** 面板的固定定位样式(基于trigger按钮位置动态计算) */
const panelStyle = ref<Record<string, string>>({})
/** 计算面板位置(考虑body transform scale */
function updatePanelPosition() {
if (!selectorRef.value) return
const rect = selectorRef.value.getBoundingClientRect()
const bodyTransform = document.body.style.transform
let scale = 1
const scaleMatch = bodyTransform.match(/scale\(([\d.]+)\)/)
if (scaleMatch) scale = parseFloat(scaleMatch[1]) || 1
panelStyle.value = {
position: 'fixed',
top: `${(rect.bottom + 6) / scale}px`,
right: `${(window.innerWidth - rect.right) / scale}px`,
'z-index': '2000',
}
}
// ==================== 响应式状态 ====================
/** 下拉面板是否可见 */
@@ -231,8 +255,9 @@ const categories = computed<JobCategoryItem[]>(() => store.state.jobCategories)
/** 已选中岗位 ID 集合,用于快速判断某项是否选中 */
const selectedIdSet = computed(() => new Set(selectedItems.value.map(i => i.id)))
/** 触发按钮显示文字:无选中显示"岗位",有选中则用逗号拼接名称 */
/** 触发按钮显示文字:传了triggerLabel就始终显示它,否则无选中显示默认文字,有选中则用逗号拼接名称 */
const displayText = computed(() => {
if (props.triggerLabel) return props.triggerLabel
if (!selectedItems.value.length) return '岗位'
return selectedItems.value.map(i => i.name).join('')
})
@@ -493,12 +518,17 @@ function toggleDropdown() {
if (categories.value.length && !activeLevel1Id.value) {
activeLevel1Id.value = categories.value[0].id
}
// 计算面板位置
updatePanelPosition()
}
}
/** 点击组件外部时关闭下拉面板 */
function onClickOutside(e: MouseEvent) {
if (selectorRef.value && !selectorRef.value.contains(e.target as Node)) {
const target = e.target as Node
if (selectorRef.value && !selectorRef.value.contains(target)) {
const panel = document.querySelector('.job-category-selector__panel')
if (panel && panel.contains(target)) return
visible.value = false
}
}
+38 -8
View File
@@ -16,13 +16,15 @@
</svg>
</div>
<!-- 下拉面板level=2 时两栏较窄level=3 时三栏较宽 -->
<div
v-if="visible"
class="region-selector__panel"
:class="{ 'region-selector__panel--two-col': level === 2 }"
@click.stop
>
<!-- 下拉面板Teleport到body避免被父级overflow:hidden裁切 -->
<Teleport to="body">
<div
v-if="visible"
class="region-selector__panel"
:class="{ 'region-selector__panel--two-col': level === 2 }"
:style="panelStyle"
@click.stop
>
<!-- 选中区小方块标签展示已选中的地区名称 -->
<div class="region-selector__selected-area" v-if="selectedItems.length">
@@ -124,6 +126,7 @@
<button class="region-selector__btn region-selector__btn--confirm" @click="handleConfirm">确认</button>
</div>
</div>
</Teleport>
</div>
</template>
@@ -162,6 +165,8 @@ const props = withDefaults(
hoverStyle?: Record<string, string>
/** 父组件传入的显示文字自定义样式,用于覆盖 max-width 等默认样式 */
displayStyle?: Record<string, string>
/** 自定义触发按钮默认文字,传入后替换"城市" */
triggerLabel?: string
}>(),
{
level: 2,
@@ -177,6 +182,25 @@ const store = useStore()
/** 组件根元素引用,用于点击外部关闭判断 */
const selectorRef = ref<HTMLElement | null>(null)
/** 面板的固定定位样式(基于trigger按钮位置动态计算) */
const panelStyle = ref<Record<string, string>>({})
/** 计算面板位置(考虑body transform scale */
function updatePanelPosition() {
if (!selectorRef.value) return
const rect = selectorRef.value.getBoundingClientRect()
const bodyTransform = document.body.style.transform
let scale = 1
const scaleMatch = bodyTransform.match(/scale\(([\d.]+)\)/)
if (scaleMatch) scale = parseFloat(scaleMatch[1]) || 1
panelStyle.value = {
position: 'fixed',
top: `${(rect.bottom + 6) / scale}px`,
right: `${(window.innerWidth - rect.right) / scale}px`,
'z-index': '2000',
}
}
// ==================== 响应式状态 ====================
/** 下拉面板是否可见 */
@@ -207,6 +231,7 @@ const selectedCodeSet = computed(() => new Set(selectedItems.value.map(i => i.co
/** 触发按钮显示文字 */
const displayText = computed(() => {
if (props.triggerLabel) return props.triggerLabel
if (!selectedItems.value.length) return '城市'
return selectedItems.value.map(i => i.name).join('')
})
@@ -345,12 +370,17 @@ function toggleDropdown() {
if (regions.value.length && !activeProvinceCode.value) {
activeProvinceCode.value = regions.value[0].code
}
// 计算面板位置
updatePanelPosition()
}
}
/** 点击组件外部时关闭下拉面板 */
function onClickOutside(e: MouseEvent) {
if (selectorRef.value && !selectorRef.value.contains(e.target as Node)) {
const target = e.target as Node
if (selectorRef.value && !selectorRef.value.contains(target)) {
const panel = document.querySelector('.region-selector__panel')
if (panel && panel.contains(target)) return
visible.value = false
}
}
+5
View File
@@ -70,6 +70,8 @@ const remAdaptPlugin: Plugin = {
// 用 scale 直接驱动(scale=0.625 时满宽4remscale 越小宽度越小)
const chatWidth = 1.0 + (4.0 - 1.0) * scale // scale=1→4rem, scale=0.5→2.5rem, scale=0.3→1.9rem
docEl.style.setProperty('--chat-width', Math.max(chatWidth, 1.0).toFixed(2) + 'rem')
// 小屏导航宽度CSS变量
docEl.style.setProperty('--nav-width', '0.8rem')
// body 高度 = 视口高度 / scale,使其缩放后刚好等于视口高度
// overflow-y: auto 让内容在 body 内部滚动
@@ -94,6 +96,9 @@ const remAdaptPlugin: Plugin = {
docEl.style.overflow = ''
docEl.style.setProperty('--app-height', '100vh')
docEl.style.setProperty('--chat-width', '3.6rem')
// 根据窗口宽度设置导航栏宽度CSS变量
const navWidth = window.innerWidth < 1440 ? '0.8rem' : '2.2rem'
docEl.style.setProperty('--nav-width', navWidth)
}
}
+694 -270
View File
File diff suppressed because it is too large Load Diff