3个需求处理和插件通信组件引入(和插件共用的一个ts)
@@ -13,6 +13,7 @@ declare module 'vue' {
|
|||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
AgentApplyProgress: typeof import('./src/components/AgentApplyProgress.vue')['default']
|
AgentApplyProgress: typeof import('./src/components/AgentApplyProgress.vue')['default']
|
||||||
AgentApplyProgressPanel: typeof import('./src/components/AgentApplyProgressPanel.vue')['default']
|
AgentApplyProgressPanel: typeof import('./src/components/AgentApplyProgressPanel.vue')['default']
|
||||||
|
AgentBrowserInstallGuide: typeof import('./src/components/AgentBrowserInstallGuide.vue')['default']
|
||||||
AgentChatJobList: typeof import('./src/components/AgentChatJobList.vue')['default']
|
AgentChatJobList: typeof import('./src/components/AgentChatJobList.vue')['default']
|
||||||
AgentJobPreviewPanel: typeof import('./src/components/AgentJobPreviewPanel.vue')['default']
|
AgentJobPreviewPanel: typeof import('./src/components/AgentJobPreviewPanel.vue')['default']
|
||||||
AgentMatchJobAdd: typeof import('./src/components/AgentMatchJobAdd.vue')['default']
|
AgentMatchJobAdd: typeof import('./src/components/AgentMatchJobAdd.vue')['default']
|
||||||
|
|||||||
|
After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 56 KiB |
@@ -531,6 +531,11 @@ body:not(#_) {
|
|||||||
.color-2{
|
.color-2{
|
||||||
color: #222;
|
color: #222;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.color-2F7DEA{
|
||||||
|
color: #2F7DEA;
|
||||||
|
}
|
||||||
|
|
||||||
.color-3{
|
.color-3{
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
@@ -583,6 +588,10 @@ body:not(#_) {
|
|||||||
.color-9B9EAB{
|
.color-9B9EAB{
|
||||||
color:#9B9EAB;
|
color:#9B9EAB;
|
||||||
}
|
}
|
||||||
|
.color-D31414{
|
||||||
|
color: #D31414;
|
||||||
|
}
|
||||||
|
|
||||||
.color-accent{
|
.color-accent{
|
||||||
color:$accent;
|
color:$accent;
|
||||||
}
|
}
|
||||||
@@ -897,6 +906,9 @@ body:not(#_) {
|
|||||||
.max-w1200{
|
.max-w1200{
|
||||||
max-width: 12rem;
|
max-width: 12rem;
|
||||||
}
|
}
|
||||||
|
.max-w602{
|
||||||
|
max-width: 6.02rem;
|
||||||
|
}
|
||||||
.w0{width: 0rem;}
|
.w0{width: 0rem;}
|
||||||
.w1{width: 0.01rem;} .w2{width: 0.02rem;} .w3{width: 0.03rem;} .w4{width: 0.04rem;} .w5{width: 0.05rem;} .w6{width: 0.06rem;} .w7{width: 0.07rem;} .w8{width: 0.08rem;} .w9{width: 0.09rem;} .w10{width: 0.1rem;} .w11{width: 0.11rem;} .w12{width: 0.12rem;} .w13{width: 0.13rem;} .w14{width: 0.14rem;} .w15{width: 0.15rem;} .w16{width: 0.16rem;} .w17{width: 0.17rem;} .w18{width: 0.18rem;} .w19{width: 0.19rem;} .w20{width: 0.2rem;} .w21{width: 0.21rem;} .w22{width: 0.22rem;} .w23{width: 0.23rem;} .w24{width: 0.24rem;} .w25{width: 0.25rem;} .w26{width: 0.26rem;} .w27{width: 0.27rem;} .w28{width: 0.28rem;} .w29{width: 0.29rem;} .w30{width: 0.3rem;} .w31{width: 0.31rem;} .w32{width: 0.32rem;} .w33{width: 0.33rem;} .w34{width: 0.34rem;} .w35{width: 0.35rem;} .w36{width: 0.36rem;} .w37{width: 0.37rem;} .w38{width: 0.38rem;} .w39{width: 0.39rem;} .w40{width: 0.4rem;} .w41{width: 0.41rem;} .w42{width: 0.42rem;} .w43{width: 0.43rem;} .w44{width: 0.44rem;} .w45{width: 0.45rem;} .w46{width: 0.46rem;} .w47{width: 0.47rem;} .w48{width: 0.48rem;} .w49{width: 0.49rem;} .w50{width: 0.5rem;} .w51{width: 0.51rem;} .w52{width: 0.52rem;} .w53{width: 0.53rem;} .w54{width: 0.54rem;} .w55{width: 0.55rem;} .w56{width: 0.56rem;} .w57{width: 0.57rem;} .w58{width: 0.58rem;} .w59{width: 0.59rem;} .w60{width: 0.6rem;} .w61{width: 0.61rem;} .w62{width: 0.62rem;} .w63{width: 0.63rem;} .w64{width: 0.64rem;} .w65{width: 0.65rem;} .w66{width: 0.66rem;} .w67{width: 0.67rem;} .w68{width: 0.68rem;} .w69{width: 0.69rem;} .w70{width: 0.7rem;} .w71{width: 0.71rem;} .w72{width: 0.72rem;} .w73{width: 0.73rem;} .w74{width: 0.74rem;} .w75{width: 0.75rem;} .w76{width: 0.76rem;} .w77{width: 0.77rem;} .w78{width: 0.78rem;} .w79{width: 0.79rem;} .w80{width: 0.8rem;} .w81{width: 0.81rem;} .w82{width: 0.82rem;} .w83{width: 0.83rem;} .w84{width: 0.84rem;} .w85{width: 0.85rem;} .w86{width: 0.86rem;} .w87{width: 0.87rem;} .w88{width: 0.88rem;} .w89{width: 0.89rem;} .w90{width: 0.9rem;} .w91{width: 0.91rem;} .w92{width: 0.92rem;} .w93{width: 0.93rem;} .w94{width: 0.94rem;} .w95{width: 0.95rem;} .w96{width: 0.96rem;} .w97{width: 0.97rem;} .w98{width: 0.98rem;} .w99{width: 0.99rem;}
|
.w1{width: 0.01rem;} .w2{width: 0.02rem;} .w3{width: 0.03rem;} .w4{width: 0.04rem;} .w5{width: 0.05rem;} .w6{width: 0.06rem;} .w7{width: 0.07rem;} .w8{width: 0.08rem;} .w9{width: 0.09rem;} .w10{width: 0.1rem;} .w11{width: 0.11rem;} .w12{width: 0.12rem;} .w13{width: 0.13rem;} .w14{width: 0.14rem;} .w15{width: 0.15rem;} .w16{width: 0.16rem;} .w17{width: 0.17rem;} .w18{width: 0.18rem;} .w19{width: 0.19rem;} .w20{width: 0.2rem;} .w21{width: 0.21rem;} .w22{width: 0.22rem;} .w23{width: 0.23rem;} .w24{width: 0.24rem;} .w25{width: 0.25rem;} .w26{width: 0.26rem;} .w27{width: 0.27rem;} .w28{width: 0.28rem;} .w29{width: 0.29rem;} .w30{width: 0.3rem;} .w31{width: 0.31rem;} .w32{width: 0.32rem;} .w33{width: 0.33rem;} .w34{width: 0.34rem;} .w35{width: 0.35rem;} .w36{width: 0.36rem;} .w37{width: 0.37rem;} .w38{width: 0.38rem;} .w39{width: 0.39rem;} .w40{width: 0.4rem;} .w41{width: 0.41rem;} .w42{width: 0.42rem;} .w43{width: 0.43rem;} .w44{width: 0.44rem;} .w45{width: 0.45rem;} .w46{width: 0.46rem;} .w47{width: 0.47rem;} .w48{width: 0.48rem;} .w49{width: 0.49rem;} .w50{width: 0.5rem;} .w51{width: 0.51rem;} .w52{width: 0.52rem;} .w53{width: 0.53rem;} .w54{width: 0.54rem;} .w55{width: 0.55rem;} .w56{width: 0.56rem;} .w57{width: 0.57rem;} .w58{width: 0.58rem;} .w59{width: 0.59rem;} .w60{width: 0.6rem;} .w61{width: 0.61rem;} .w62{width: 0.62rem;} .w63{width: 0.63rem;} .w64{width: 0.64rem;} .w65{width: 0.65rem;} .w66{width: 0.66rem;} .w67{width: 0.67rem;} .w68{width: 0.68rem;} .w69{width: 0.69rem;} .w70{width: 0.7rem;} .w71{width: 0.71rem;} .w72{width: 0.72rem;} .w73{width: 0.73rem;} .w74{width: 0.74rem;} .w75{width: 0.75rem;} .w76{width: 0.76rem;} .w77{width: 0.77rem;} .w78{width: 0.78rem;} .w79{width: 0.79rem;} .w80{width: 0.8rem;} .w81{width: 0.81rem;} .w82{width: 0.82rem;} .w83{width: 0.83rem;} .w84{width: 0.84rem;} .w85{width: 0.85rem;} .w86{width: 0.86rem;} .w87{width: 0.87rem;} .w88{width: 0.88rem;} .w89{width: 0.89rem;} .w90{width: 0.9rem;} .w91{width: 0.91rem;} .w92{width: 0.92rem;} .w93{width: 0.93rem;} .w94{width: 0.94rem;} .w95{width: 0.95rem;} .w96{width: 0.96rem;} .w97{width: 0.97rem;} .w98{width: 0.98rem;} .w99{width: 0.99rem;}
|
||||||
.w100{width: 1rem;}
|
.w100{width: 1rem;}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
&__job-title {
|
&__job-title {
|
||||||
font-size: 0.18rem;
|
font-size: 0.18rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
color: $text-dark;
|
color: $text-dark;
|
||||||
line-height: 0.27rem;
|
line-height: 0.27rem;
|
||||||
}
|
}
|
||||||
@@ -126,7 +126,7 @@
|
|||||||
// 步骤名称
|
// 步骤名称
|
||||||
&__step-name {
|
&__step-name {
|
||||||
font-size: 0.14rem;
|
font-size: 0.14rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
line-height: 0.19rem;
|
line-height: 0.19rem;
|
||||||
|
|
||||||
&--done {
|
&--done {
|
||||||
|
|||||||
@@ -0,0 +1,158 @@
|
|||||||
|
// Agent浏览器插件安装步骤指引组件样式
|
||||||
|
@use '../variables' as *;
|
||||||
|
|
||||||
|
/* 步骤内容区域 */
|
||||||
|
.agent-browser-guide-drawer__body {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 0 0.32rem 0.32rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.16rem;
|
||||||
|
font-size: 0.14rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 步骤卡片 */
|
||||||
|
.agent-browser-guide-drawer__card {
|
||||||
|
border: 1px solid #F0F0F0;
|
||||||
|
border-radius: 0.12rem;
|
||||||
|
padding: 0.16rem 0.2rem;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-browser-guide-drawer__step-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.12rem;
|
||||||
|
margin-bottom: 0.16rem;
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-browser-guide-drawer__step-num {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 0.32rem;
|
||||||
|
height: 0.32rem;
|
||||||
|
background: #EDF9FA;
|
||||||
|
border-radius: 0.08rem;
|
||||||
|
font-size: 0.18rem;
|
||||||
|
font-weight: 620;
|
||||||
|
color: $accent;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-browser-guide-drawer__step-info {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-browser-guide-drawer__step-title {
|
||||||
|
font-size: 0.18rem;
|
||||||
|
font-weight: 620;
|
||||||
|
color: $text-dark;
|
||||||
|
line-height: 0.24rem;
|
||||||
|
margin: 0 0 0.04rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-browser-guide-drawer__step-desc {
|
||||||
|
font-size: 0.14rem;
|
||||||
|
font-weight: 330;
|
||||||
|
color: $text-middle;
|
||||||
|
line-height: 0.19rem;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 下载按钮区域 */
|
||||||
|
.agent-browser-guide-drawer__download-box {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.16rem;
|
||||||
|
padding: 0.04rem 0.04rem 0.04rem 0.16rem;
|
||||||
|
background: $bg-main;
|
||||||
|
border-radius: 0.12rem;
|
||||||
|
height: 0.44rem;
|
||||||
|
margin-left: 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-browser-guide-drawer__download-name {
|
||||||
|
font-size: 0.14rem;
|
||||||
|
font-weight: 450;
|
||||||
|
color: $text-dark;
|
||||||
|
line-height: 0.19rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-browser-guide-drawer__download-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.04rem;
|
||||||
|
padding: 0.08rem 0.12rem;
|
||||||
|
background: $accent;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0.08rem;
|
||||||
|
color: $bg-white;
|
||||||
|
font-size: 0.14rem;
|
||||||
|
font-weight: 620;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.2s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $accent-hover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 浏览器链接区域 */
|
||||||
|
.agent-browser-guide-drawer__browser-links {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.24rem;
|
||||||
|
margin-bottom: 0.16rem;
|
||||||
|
margin-left: 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-browser-guide-drawer__browser-link {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.04rem;
|
||||||
|
padding: 0.12rem 0.16rem;
|
||||||
|
background: $bg-white;
|
||||||
|
border: 1px solid #F0F0F0;
|
||||||
|
border-radius: 0.08rem;
|
||||||
|
font-size: 0.14rem;
|
||||||
|
font-weight: 450;
|
||||||
|
color: $text-middle;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: border-color 0.2s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: $accent;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.agent-browser-guide-drawer__copy-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.04rem;
|
||||||
|
color: $accent;
|
||||||
|
font-size: 0.14rem;
|
||||||
|
font-weight: 450;
|
||||||
|
margin-left: 0.12rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 步骤示意图 */
|
||||||
|
.agent-browser-guide-drawer__step-img {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 3.52rem;
|
||||||
|
border-radius: 0.08rem;
|
||||||
|
margin-top: 0.12rem;
|
||||||
|
margin-left: 0.4rem;
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
// 标题
|
// 标题
|
||||||
&__header {
|
&__header {
|
||||||
font-size: 0.22rem;
|
font-size: 0.22rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
color: $text-dark;
|
color: $text-dark;
|
||||||
margin-bottom: 0.04rem;
|
margin-bottom: 0.04rem;
|
||||||
line-height: 0.29rem;
|
line-height: 0.29rem;
|
||||||
@@ -127,7 +127,7 @@
|
|||||||
// 岗位名称
|
// 岗位名称
|
||||||
&__title {
|
&__title {
|
||||||
font-size: 0.18rem;
|
font-size: 0.18rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
color: $text-dark;
|
color: $text-dark;
|
||||||
line-height: 0.27rem;
|
line-height: 0.27rem;
|
||||||
}
|
}
|
||||||
@@ -208,7 +208,7 @@
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
border: none;
|
border: none;
|
||||||
font-size: 0.14rem;
|
font-size: 0.14rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
color: $accent;
|
color: $accent;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -232,7 +232,7 @@
|
|||||||
border: none;
|
border: none;
|
||||||
border-radius: 0.08rem;
|
border-radius: 0.08rem;
|
||||||
font-size: 0.14rem;
|
font-size: 0.14rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
@@ -291,7 +291,7 @@
|
|||||||
border: 1px solid $accent;
|
border: 1px solid $accent;
|
||||||
border-radius: 0.22rem;
|
border-radius: 0.22rem;
|
||||||
font-size: 0.14rem;
|
font-size: 0.14rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
|
|
||||||
@@ -325,7 +325,7 @@
|
|||||||
border: none;
|
border: none;
|
||||||
border-radius: 0.22rem;
|
border-radius: 0.22rem;
|
||||||
font-size: 0.14rem;
|
font-size: 0.14rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
/* 标题文字 */
|
/* 标题文字 */
|
||||||
&__title {
|
&__title {
|
||||||
font-size: 0.18rem;
|
font-size: 0.18rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
color: $text-dark;
|
color: $text-dark;
|
||||||
line-height: 0.24rem;
|
line-height: 0.24rem;
|
||||||
}
|
}
|
||||||
@@ -89,7 +89,7 @@
|
|||||||
/* 岗位标题 */
|
/* 岗位标题 */
|
||||||
&__job-title {
|
&__job-title {
|
||||||
font-size: 0.24rem;
|
font-size: 0.24rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
color: $text-dark;
|
color: $text-dark;
|
||||||
line-height: 0.32rem;
|
line-height: 0.32rem;
|
||||||
margin: 0 0 0.08rem;
|
margin: 0 0 0.08rem;
|
||||||
@@ -221,7 +221,7 @@
|
|||||||
|
|
||||||
&__company-name {
|
&__company-name {
|
||||||
font-size: 0.18rem;
|
font-size: 0.18rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
color: $text-dark;
|
color: $text-dark;
|
||||||
line-height: 0.24rem;
|
line-height: 0.24rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
// 区块标题
|
// 区块标题
|
||||||
&__section-title {
|
&__section-title {
|
||||||
font-size: 0.16rem;
|
font-size: 0.16rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
line-height: 0.21rem;
|
line-height: 0.21rem;
|
||||||
color: #1A1A1A;
|
color: #1A1A1A;
|
||||||
}
|
}
|
||||||
@@ -297,7 +297,7 @@
|
|||||||
|
|
||||||
&__edit-dialog-title {
|
&__edit-dialog-title {
|
||||||
font-size: 0.18rem;
|
font-size: 0.18rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
line-height: 0.24rem;
|
line-height: 0.24rem;
|
||||||
color: #1A1A1A;
|
color: #1A1A1A;
|
||||||
}
|
}
|
||||||
@@ -451,7 +451,7 @@
|
|||||||
|
|
||||||
&__title {
|
&__title {
|
||||||
font-size: 0.18rem;
|
font-size: 0.18rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
color: $text-dark;
|
color: $text-dark;
|
||||||
line-height: 0.24rem;
|
line-height: 0.24rem;
|
||||||
}
|
}
|
||||||
@@ -464,6 +464,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.16rem;
|
gap: 0.16rem;
|
||||||
|
font-size: 0.14rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 步骤卡片 */
|
/* 步骤卡片 */
|
||||||
@@ -471,6 +472,8 @@
|
|||||||
border: 1px solid #F0F0F0;
|
border: 1px solid #F0F0F0;
|
||||||
border-radius: 0.12rem;
|
border-radius: 0.12rem;
|
||||||
padding: 0.16rem 0.2rem;
|
padding: 0.16rem 0.2rem;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__step-row {
|
&__step-row {
|
||||||
@@ -478,6 +481,7 @@
|
|||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
gap: 0.12rem;
|
gap: 0.12rem;
|
||||||
margin-bottom: 0.16rem;
|
margin-bottom: 0.16rem;
|
||||||
|
margin-right: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__step-num {
|
&__step-num {
|
||||||
@@ -489,7 +493,7 @@
|
|||||||
background: #EDF9FA;
|
background: #EDF9FA;
|
||||||
border-radius: 0.08rem;
|
border-radius: 0.08rem;
|
||||||
font-size: 0.18rem;
|
font-size: 0.18rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
color: $accent;
|
color: $accent;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
@@ -500,7 +504,7 @@
|
|||||||
|
|
||||||
&__step-title {
|
&__step-title {
|
||||||
font-size: 0.18rem;
|
font-size: 0.18rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
color: $text-dark;
|
color: $text-dark;
|
||||||
line-height: 0.24rem;
|
line-height: 0.24rem;
|
||||||
margin: 0 0 0.04rem;
|
margin: 0 0 0.04rem;
|
||||||
@@ -523,6 +527,7 @@
|
|||||||
background: $bg-main;
|
background: $bg-main;
|
||||||
border-radius: 0.12rem;
|
border-radius: 0.12rem;
|
||||||
height: 0.44rem;
|
height: 0.44rem;
|
||||||
|
margin-left: 0.4rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__download-name {
|
&__download-name {
|
||||||
@@ -542,7 +547,7 @@
|
|||||||
border-radius: 0.08rem;
|
border-radius: 0.08rem;
|
||||||
color: $bg-white;
|
color: $bg-white;
|
||||||
font-size: 0.14rem;
|
font-size: 0.14rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background 0.2s;
|
transition: background 0.2s;
|
||||||
|
|
||||||
@@ -557,6 +562,7 @@
|
|||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
gap: 0.24rem;
|
gap: 0.24rem;
|
||||||
margin-bottom: 0.16rem;
|
margin-bottom: 0.16rem;
|
||||||
|
margin-left: 0.4rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__browser-link {
|
&__browser-link {
|
||||||
@@ -599,9 +605,10 @@
|
|||||||
/* 步骤示意图 */
|
/* 步骤示意图 */
|
||||||
&__step-img {
|
&__step-img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 4rem;
|
max-width: 3.52rem;
|
||||||
border-radius: 0.08rem;
|
border-radius: 0.08rem;
|
||||||
margin-top: 0.12rem;
|
margin-top: 0.12rem;
|
||||||
|
margin-left: 0.4rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
/* 标题文字 */
|
/* 标题文字 */
|
||||||
&__title {
|
&__title {
|
||||||
font-size: 0.18rem;
|
font-size: 0.18rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
color: $text-dark;
|
color: $text-dark;
|
||||||
line-height: 0.24rem;
|
line-height: 0.24rem;
|
||||||
}
|
}
|
||||||
@@ -136,7 +136,7 @@
|
|||||||
/* 岗位标题 */
|
/* 岗位标题 */
|
||||||
&__card-title {
|
&__card-title {
|
||||||
font-size: 0.18rem;
|
font-size: 0.18rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
color: $text-dark;
|
color: $text-dark;
|
||||||
line-height: 0.27rem;
|
line-height: 0.27rem;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
&__title {
|
&__title {
|
||||||
font-size: 0.18rem;
|
font-size: 0.18rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
line-height: 0.24rem;
|
line-height: 0.24rem;
|
||||||
color: #1A1A1A;
|
color: #1A1A1A;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@
|
|||||||
left: 0.08rem;
|
left: 0.08rem;
|
||||||
top: 0.245rem;
|
top: 0.245rem;
|
||||||
font-family: 'MiSans';
|
font-family: 'MiSans';
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
font-size: 0.10rem;
|
font-size: 0.10rem;
|
||||||
line-height: 0.13rem;
|
line-height: 0.13rem;
|
||||||
color: #8FB7BE;
|
color: #8FB7BE;
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
@use './components/member-access-dialog.scss';
|
@use './components/member-access-dialog.scss';
|
||||||
@use './components/step-progress-overlay.scss';
|
@use './components/step-progress-overlay.scss';
|
||||||
@use './components/mentor-aside-panel.scss';
|
@use './components/mentor-aside-panel.scss';
|
||||||
|
@use './components/agent-browser-install-guide.scss';
|
||||||
|
|
||||||
// 全局样式(优先级最高)
|
// 全局样式(优先级最高)
|
||||||
@use './auto.scss';
|
@use './auto.scss';
|
||||||
|
|||||||
@@ -279,8 +279,7 @@
|
|||||||
border-radius: 0.12rem;
|
border-radius: 0.12rem;
|
||||||
max-height: calc(var(--app-height, 100vh) - 1.4rem);
|
max-height: calc(var(--app-height, 100vh) - 1.4rem);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
display: flex;
|
padding: 0.24rem;
|
||||||
flex-direction: column;
|
|
||||||
scrollbar-width: none; // Firefox
|
scrollbar-width: none; // Firefox
|
||||||
-ms-overflow-style: none; // IE/Edge
|
-ms-overflow-style: none; // IE/Edge
|
||||||
|
|
||||||
@@ -690,7 +689,7 @@
|
|||||||
|
|
||||||
&__step2-faq-title {
|
&__step2-faq-title {
|
||||||
font-size: 0.18rem;
|
font-size: 0.18rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
color: $accent;
|
color: $accent;
|
||||||
margin-bottom: 0.13rem;
|
margin-bottom: 0.13rem;
|
||||||
}
|
}
|
||||||
@@ -706,7 +705,7 @@
|
|||||||
|
|
||||||
&__step2-faq-item-title {
|
&__step2-faq-item-title {
|
||||||
font-size: 0.14rem;
|
font-size: 0.14rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
color: $text-dark;
|
color: $text-dark;
|
||||||
margin-bottom: 0.08rem;
|
margin-bottom: 0.08rem;
|
||||||
}
|
}
|
||||||
@@ -972,7 +971,6 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.16rem;
|
gap: 0.16rem;
|
||||||
padding: 0.24rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 单个步骤卡片
|
// 单个步骤卡片
|
||||||
@@ -1014,7 +1012,7 @@
|
|||||||
background: #EDF9FA;
|
background: #EDF9FA;
|
||||||
border-radius: 0.08rem;
|
border-radius: 0.08rem;
|
||||||
font-size: 0.18rem;
|
font-size: 0.18rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
color: $accent;
|
color: $accent;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
@@ -1029,7 +1027,7 @@
|
|||||||
// 步骤标题
|
// 步骤标题
|
||||||
&__install-card-title {
|
&__install-card-title {
|
||||||
font-size: 0.18rem;
|
font-size: 0.18rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
color: $text-dark;
|
color: $text-dark;
|
||||||
margin: 0 0 0.04rem;
|
margin: 0 0 0.04rem;
|
||||||
line-height: 0.24rem;
|
line-height: 0.24rem;
|
||||||
@@ -1087,7 +1085,7 @@
|
|||||||
border-radius: 0.08rem;
|
border-radius: 0.08rem;
|
||||||
color: $bg-white;
|
color: $bg-white;
|
||||||
font-size: 0.14rem;
|
font-size: 0.14rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: opacity 0.2s ease;
|
transition: opacity 0.2s ease;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -1343,7 +1341,7 @@
|
|||||||
border-radius: 0.08rem;
|
border-radius: 0.08rem;
|
||||||
background: $bg-white;
|
background: $bg-white;
|
||||||
font-size: 0.14rem;
|
font-size: 0.14rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
color: $text-middle;
|
color: $text-middle;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
@@ -1372,7 +1370,7 @@
|
|||||||
border: none;
|
border: none;
|
||||||
border-radius: 0.08rem;
|
border-radius: 0.08rem;
|
||||||
font-size: 0.14rem;
|
font-size: 0.14rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
color: $bg-white;
|
color: $bg-white;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
@@ -1772,7 +1770,7 @@
|
|||||||
/* 标题文字 */
|
/* 标题文字 */
|
||||||
&__title {
|
&__title {
|
||||||
font-size: 0.18rem;
|
font-size: 0.18rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
color: $text-dark;
|
color: $text-dark;
|
||||||
line-height: 0.24rem;
|
line-height: 0.24rem;
|
||||||
}
|
}
|
||||||
@@ -1867,3 +1865,127 @@
|
|||||||
transform: translateX(100%);
|
transform: translateX(100%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================== 插件安装确认弹窗 ====================
|
||||||
|
|
||||||
|
/* 遮罩层 */
|
||||||
|
.agent-page__install-dialog-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.3);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 2000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 弹窗主体 */
|
||||||
|
.agent-page__install-dialog {
|
||||||
|
position: relative;
|
||||||
|
width: 3.84rem;
|
||||||
|
background: $bg-white;
|
||||||
|
border: 1px solid #F0F0F0;
|
||||||
|
box-shadow: 0 0 0.16rem rgba(0, 0, 0, 0.05);
|
||||||
|
border-radius: 0.12rem;
|
||||||
|
padding: 0.24rem 0.32rem 0.32rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 渐变背景 */
|
||||||
|
.agent-page__install-dialog-bg {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(180deg, #EDF9FA 0%, #FFFFFF 20.63%);
|
||||||
|
border-radius: 0.12rem;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 关闭按钮 */
|
||||||
|
.agent-page__install-dialog-close {
|
||||||
|
position: absolute;
|
||||||
|
top: 0.24rem;
|
||||||
|
right: 0.24rem;
|
||||||
|
width: 0.24rem;
|
||||||
|
height: 0.24rem;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标题 */
|
||||||
|
.agent-page__install-dialog-title {
|
||||||
|
position: relative;
|
||||||
|
font-size: 0.18rem;
|
||||||
|
font-weight: 520;
|
||||||
|
color: $text-dark;
|
||||||
|
text-align: center;
|
||||||
|
margin: 0 0 0.2rem 0;
|
||||||
|
line-height: 0.24rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 描述文字 */
|
||||||
|
.agent-page__install-dialog-desc {
|
||||||
|
position: relative;
|
||||||
|
font-size: 0.16rem;
|
||||||
|
font-weight: 330;
|
||||||
|
color: $text-middle;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 0.28rem;
|
||||||
|
margin: 0 0 0.24rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部按钮容器 */
|
||||||
|
.agent-page__install-dialog-btns {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
gap: 0.08rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 按钮通用 */
|
||||||
|
.agent-page__install-dialog-btn {
|
||||||
|
flex: 1;
|
||||||
|
height: 0.37rem;
|
||||||
|
border-radius: 0.08rem;
|
||||||
|
font-size: 0.14rem;
|
||||||
|
font-weight: 450;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: all 0.2s;
|
||||||
|
|
||||||
|
/* 描边按钮 — 还未安装 */
|
||||||
|
&--outline {
|
||||||
|
background: $bg-white;
|
||||||
|
border: 1px solid $accent;
|
||||||
|
color: $accent;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $theme-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 实心按钮 — 已安装,继续 */
|
||||||
|
&--primary {
|
||||||
|
background: $accent;
|
||||||
|
border: none;
|
||||||
|
color: #FFFFFF;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $accent-hover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -465,7 +465,7 @@
|
|||||||
border-radius: 0.04rem;
|
border-radius: 0.04rem;
|
||||||
font-size: 0.12rem;
|
font-size: 0.12rem;
|
||||||
font-weight: 330;
|
font-weight: 330;
|
||||||
color: $accent;
|
color: #fff;
|
||||||
line-height: 0.16rem;
|
line-height: 0.16rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1220,7 +1220,7 @@
|
|||||||
/* 标题文字 */
|
/* 标题文字 */
|
||||||
&__title {
|
&__title {
|
||||||
font-size: 0.18rem;
|
font-size: 0.18rem;
|
||||||
font-weight: 520;
|
font-weight: 620;
|
||||||
color: $text-dark;
|
color: $text-dark;
|
||||||
line-height: 0.24rem;
|
line-height: 0.24rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,171 @@
|
|||||||
|
<!-- Agent页面 - 浏览器插件安装步骤指引组件 -->
|
||||||
|
<template>
|
||||||
|
<div class="agent-browser-guide-drawer__body">
|
||||||
|
<!-- 步骤1:下载插件包 -->
|
||||||
|
<div class="agent-browser-guide-drawer__card">
|
||||||
|
<div class="mr100">
|
||||||
|
<div class="agent-browser-guide-drawer__step-row mr0">
|
||||||
|
<span class="agent-browser-guide-drawer__step-num">1</span>
|
||||||
|
<div class="agent-browser-guide-drawer__step-info">
|
||||||
|
<h4 class="agent-browser-guide-drawer__step-title">下载并解压插件压缩包</h4>
|
||||||
|
<p class="agent-browser-guide-drawer__step-desc">下载 Offer派自动投递助手安装包,并将下载好的插件压缩包解压</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="agent-browser-guide-drawer__download-box w263">
|
||||||
|
<span class="agent-browser-guide-drawer__download-name">Offer派智能投递助手.zip</span>
|
||||||
|
<button class="agent-browser-guide-drawer__download-btn" @click="downloadExtension">
|
||||||
|
<svg viewBox="0 0 16 16" fill="none" width="14" height="14"><path d="M8 2v8M8 10L5 7M8 10l3-3M3 13h10" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||||
|
<span>下载</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 步骤1示意图 -->
|
||||||
|
<img src="@/assets/images/agent-setting/1-1.png" alt="打开开发者模式" class="agent-browser-guide-drawer__step-img" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 步骤2:打开扩展管理页面 -->
|
||||||
|
<div class="agent-browser-guide-drawer__card">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="agent-browser-guide-drawer__step-row">
|
||||||
|
<span class="agent-browser-guide-drawer__step-num">2</span>
|
||||||
|
<div class="agent-browser-guide-drawer__step-info">
|
||||||
|
<h4 class="agent-browser-guide-drawer__step-title">打开扩展管理页面</h4>
|
||||||
|
<p class="agent-browser-guide-drawer__step-desc">在浏览器地址栏输入对应地址并回车,打开扩展管理页面</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 浏览器地址链接 -->
|
||||||
|
<div class="agent-browser-guide-drawer__browser-links">
|
||||||
|
<div class="agent-browser-guide-drawer__browser-link" @click="copyToClipboard('chrome://extensions')">
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_guide_chrome)">
|
||||||
|
<path d="M8.00027 12.4507C10.4587 12.4507 12.4516 10.4577 12.4516 7.99929C12.4516 5.54085 10.4587 3.54785 8.00027 3.54785C5.54183 3.54785 3.54883 5.54085 3.54883 7.99929C3.54883 10.4577 5.54177 12.4507 8.0002 12.4507" fill="white"/>
|
||||||
|
<path d="M2.24303 5.81204C1.91094 5.23683 1.52061 4.63314 1.07203 4.00098C0.369757 5.21706 2.38548e-05 6.59661 1.15428e-09 8.0009C-2.38525e-05 9.4052 0.369663 10.7848 1.07189 12.0009C1.77412 13.217 2.78414 14.2268 4.0004 14.9288C5.21666 15.6307 6.59629 16.0001 8.00059 15.9998C8.73688 14.9671 9.2368 14.2225 9.50034 13.766C10.0065 12.8893 10.6612 11.6341 11.4643 10.0004V9.99941C11.1134 10.6077 10.6086 11.113 10.0005 11.4643C9.39241 11.8156 8.70256 12.0006 8.0003 12.0007C7.29804 12.0008 6.60813 11.816 5.99995 11.4649C5.39178 11.1138 4.88677 10.6087 4.53571 10.0005C3.44496 7.96623 2.68073 6.57004 2.24303 5.81204Z" fill="#229342"/>
|
||||||
|
<path d="M8.00046 16.0002C9.05106 16.0004 10.0914 15.7936 11.0621 15.3916C12.0327 14.9896 12.9147 14.4003 13.6575 13.6574C14.4004 12.9145 14.9896 12.0325 15.3915 11.0619C15.7935 10.0912 16.0002 9.05084 16 8.00024C15.9997 6.59593 15.6297 5.21644 14.9273 4.00043C13.4118 3.85105 12.2933 3.77637 11.5719 3.77637C10.7539 3.77637 9.56323 3.85105 7.9999 4.00043L7.99902 4.00105C8.7013 4.00071 9.39128 4.18529 9.99958 4.53623C10.6079 4.88717 11.113 5.39211 11.4643 6.00024C11.8155 6.60838 12.0004 7.29828 12.0004 8.00056C12.0004 8.70284 11.8155 9.39274 11.4642 10.0009L8.00046 16.0002Z" fill="#FBC116"/>
|
||||||
|
<path d="M8.00013 11.1677C9.74913 11.1677 11.1669 9.74992 11.1669 8.00086C11.1669 6.2518 9.74913 4.83398 8.00006 4.83398C6.25113 4.83398 4.83325 6.25186 4.83325 8.00086C4.83325 9.74986 6.25113 11.1677 8.00013 11.1677Z" fill="#1A73E8"/>
|
||||||
|
<path d="M8.00027 4.00027H14.9276C14.2256 2.78399 13.2158 1.77397 11.9997 1.07176C10.7835 0.369547 9.40396 -9.50021e-05 7.99965 1.83149e-08C6.59534 9.50388e-05 5.21581 0.369924 3.99978 1.0723C2.78374 1.77467 1.77406 2.78484 1.07227 4.00121L4.53595 10.0006L4.53689 10.0011C4.18549 9.39306 4.00037 8.70322 4.00017 8.00095C3.99996 7.29868 4.18467 6.60873 4.53571 6.0005C4.88676 5.39226 5.39177 4.88718 5.99995 4.53605C6.60814 4.18491 7.29806 4.0001 8.00033 4.00021L8.00027 4.00027Z" fill="#E33B2E"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_guide_chrome">
|
||||||
|
<rect width="16" height="16" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
<span>Chrome浏览器:chrome://extensions</span>
|
||||||
|
<span class="agent-browser-guide-drawer__copy-btn">
|
||||||
|
<svg viewBox="0 0 14 14" fill="none" width="12" height="12"><rect x="4" y="4" width="8" height="8" rx="1" stroke="currentColor" stroke-width="1"/><path d="M10 4V3a1 1 0 00-1-1H3a1 1 0 00-1 1v6a1 1 0 001 1h1" stroke="currentColor" stroke-width="1"/></svg>
|
||||||
|
复制
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="agent-browser-guide-drawer__browser-link" @click="copyToClipboard('edge://extensions')">
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_guide_edge)">
|
||||||
|
<path d="M14.4375 11.9059C14.225 12.0184 14.0062 12.1184 13.7812 12.1996C13.0625 12.4684 12.3062 12.6059 11.5375 12.6059C8.5812 12.6059 6.0062 10.5746 6.0062 7.96211C6.01245 7.24961 6.4062 6.59336 7.0312 6.25586C4.3562 6.36836 3.6687 9.15586 3.6687 10.7871C3.6687 15.4059 7.92495 15.8746 8.8437 15.8746C9.33745 15.8746 10.0812 15.7309 10.5312 15.5871L10.6125 15.5621C12.3375 14.9684 13.8 13.8059 14.775 12.2621C14.85 12.1434 14.8125 11.9934 14.7 11.9184C14.6187 11.8684 14.5187 11.8621 14.4375 11.9059Z" fill="url(#paint0_linear_guide_edge)"/>
|
||||||
|
<path opacity="0.35" d="M14.4375 11.9059C14.225 12.0184 14.0062 12.1184 13.7812 12.1996C13.0625 12.4684 12.3062 12.6059 11.5375 12.6059C8.5812 12.6059 6.0062 10.5746 6.0062 7.96211C6.01245 7.24961 6.4062 6.59336 7.0312 6.25586C4.3562 6.36836 3.6687 9.15586 3.6687 10.7871C3.6687 15.4059 7.92495 15.8746 8.8437 15.8746C9.33745 15.8746 10.0812 15.7309 10.5312 15.5871L10.6125 15.5621C12.3375 14.9684 13.8 13.8059 14.775 12.2621C14.85 12.1434 14.8125 11.9934 14.7 11.9184C14.6187 11.8684 14.5187 11.8621 14.4375 11.9059Z" fill="url(#paint1_radial_guide_edge)"/>
|
||||||
|
<path d="M6.60629 15.0877C6.05004 14.7439 5.56879 14.2877 5.18754 13.7564C3.54379 11.5064 4.03754 8.3502 6.28754 6.70645C6.52504 6.5377 6.76879 6.38145 7.03129 6.25645C7.22504 6.1627 7.55629 6.0002 8.00004 6.00645C8.63129 6.0127 9.22504 6.3127 9.60629 6.81895C9.85629 7.15645 10 7.5627 10.0063 7.9877C10.0063 7.9752 11.5375 3.0127 5.00629 3.0127C2.26254 3.0127 0.00628588 5.61895 0.00628588 7.9002C-0.00621412 9.10645 0.256286 10.3064 0.762536 11.4002C2.48754 15.0752 6.68754 16.8752 10.5375 15.5939C9.21879 16.0064 7.78129 15.8252 6.60629 15.0877Z" fill="url(#paint2_linear_guide_edge)"/>
|
||||||
|
<path opacity="0.41" d="M6.60629 15.0877C6.05004 14.7439 5.56879 14.2877 5.18754 13.7564C3.54379 11.5064 4.03754 8.3502 6.28754 6.70645C6.52504 6.5377 6.76879 6.38145 7.03129 6.25645C7.22504 6.1627 7.55629 6.0002 8.00004 6.00645C8.63129 6.0127 9.22504 6.3127 9.60629 6.81895C9.85629 7.15645 10 7.5627 10.0063 7.9877C10.0063 7.9752 11.5375 3.0127 5.00629 3.0127C2.26254 3.0127 0.00628588 5.61895 0.00628588 7.9002C-0.00621412 9.10645 0.256286 10.3064 0.762536 11.4002C2.48754 15.0752 6.68754 16.8752 10.5375 15.5939C9.21879 16.0064 7.78129 15.8252 6.60629 15.0877Z" fill="url(#paint3_radial_guide_edge)"/>
|
||||||
|
<path d="M9.51875 9.30625C9.46875 9.36875 9.3125 9.4625 9.3125 9.6625C9.3125 9.825 9.41875 9.98125 9.60625 10.1125C10.5062 10.7375 12.2 10.6562 12.2063 10.6562C12.875 10.6562 13.525 10.475 14.1 10.1375C15.275 9.45 16 8.19375 16 6.83125C16.0187 5.43125 15.5 4.5 15.2937 4.0875C13.9688 1.49375 11.1062 0 8 0C3.625 0 0.0625 3.5125 0 7.8875C0.03125 5.60625 2.3 3.7625 5 3.7625C5.21875 3.7625 6.46875 3.78125 7.625 4.39375C8.64375 4.93125 9.18125 5.575 9.55 6.21875C9.9375 6.8875 10.0063 7.725 10.0063 8.0625C10.0063 8.39375 9.8375 8.89375 9.51875 9.30625Z" fill="url(#paint4_radial_guide_edge)"/>
|
||||||
|
<path d="M9.51875 9.30625C9.46875 9.36875 9.3125 9.4625 9.3125 9.6625C9.3125 9.825 9.41875 9.98125 9.60625 10.1125C10.5062 10.7375 12.2 10.6562 12.2063 10.6562C12.875 10.6562 13.525 10.475 14.1 10.1375C15.275 9.45 16 8.19375 16 6.83125C16.0187 5.43125 15.5 4.5 15.2937 4.0875C13.9688 1.49375 11.1062 0 8 0C3.625 0 0.0625 3.5125 0 7.8875C0.03125 5.60625 2.3 3.7625 5 3.7625C5.21875 3.7625 6.46875 3.78125 7.625 4.39375C8.64375 4.93125 9.18125 5.575 9.55 6.21875C9.9375 6.8875 10.0063 7.725 10.0063 8.0625C10.0063 8.39375 9.8375 8.89375 9.51875 9.30625Z" fill="url(#paint5_radial_guide_edge)"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="paint0_linear_guide_edge" x1="3.66895" y1="11.0634" x2="14.8116" y2="11.0634" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#0C59A4"/>
|
||||||
|
<stop offset="1" stop-color="#114A8B"/>
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient id="paint1_radial_guide_edge" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(9.82444 11.1519) scale(5.96065 5.662)">
|
||||||
|
<stop offset="0.72" stop-opacity="0"/>
|
||||||
|
<stop offset="0.95" stop-opacity="0.53"/>
|
||||||
|
<stop offset="1"/>
|
||||||
|
</radialGradient>
|
||||||
|
<linearGradient id="paint2_linear_guide_edge" x1="9.54822" y1="6.23432" x2="2.58741" y2="13.8163" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#1B9DE2"/>
|
||||||
|
<stop offset="0.16" stop-color="#1595DF"/>
|
||||||
|
<stop offset="0.67" stop-color="#0680D7"/>
|
||||||
|
<stop offset="1" stop-color="#0078D4"/>
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient id="paint3_radial_guide_edge" cx="0" cy="0" r="1" gradientTransform="matrix(1.34287 -8.86118 7.162 1.0743 4.41307 12.4383)" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0.76" stop-opacity="0"/>
|
||||||
|
<stop offset="0.95" stop-opacity="0.5"/>
|
||||||
|
<stop offset="1"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint4_radial_guide_edge" cx="0" cy="0" r="1" gradientTransform="matrix(-0.506075 12.6493 -26.9472 -1.0119 1.61573 2.96205)" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#35C1F1"/>
|
||||||
|
<stop offset="0.11" stop-color="#34C1ED"/>
|
||||||
|
<stop offset="0.23" stop-color="#2FC2DF"/>
|
||||||
|
<stop offset="0.31" stop-color="#2BC3D2"/>
|
||||||
|
<stop offset="0.67" stop-color="#36C752"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint5_radial_guide_edge" cx="0" cy="0" r="1" gradientTransform="matrix(1.70345 5.83918 -4.74533 1.39926 15.0038 4.83786)" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#66EB6E"/>
|
||||||
|
<stop offset="1" stop-color="#66EB6E" stop-opacity="0"/>
|
||||||
|
</radialGradient>
|
||||||
|
<clipPath id="clip0_guide_edge">
|
||||||
|
<rect width="16" height="16" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
<span>Edge浏览器:edge://extensions</span>
|
||||||
|
<span class="agent-browser-guide-drawer__copy-btn">
|
||||||
|
<svg viewBox="0 0 14 14" fill="none" width="12" height="12"><rect x="4" y="4" width="8" height="8" rx="1" stroke="currentColor" stroke-width="1"/><path d="M10 4V3a1 1 0 00-1-1H3a1 1 0 00-1 1v6a1 1 0 001 1h1" stroke="currentColor" stroke-width="1"/></svg>
|
||||||
|
复制
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- 步骤2示意图 -->
|
||||||
|
<img src="@/assets/images/agent-setting/2-1.png" alt="输入扩展地址" class="agent-browser-guide-drawer__step-img" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 步骤3:打开开发者模式 -->
|
||||||
|
<div class="agent-browser-guide-drawer__card">
|
||||||
|
<div class="agent-browser-guide-drawer__step-row">
|
||||||
|
<span class="agent-browser-guide-drawer__step-num">3</span>
|
||||||
|
<div class="agent-browser-guide-drawer__step-info">
|
||||||
|
<h4 class="agent-browser-guide-drawer__step-title">打开开发者模式</h4>
|
||||||
|
<p class="agent-browser-guide-drawer__step-desc"><span class="color-D31414">Chrome浏览器</span>在扩展管理页面的右上角,找到「开发者模式」开关并打开</p>
|
||||||
|
<p class="agent-browser-guide-drawer__step-desc mt3"><span class="color-2F7DEA">Edge浏览器</span>在扩展管理页面左下角,找到「开发者模式」开关并打开</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 步骤3示意图 -->
|
||||||
|
<img src="@/assets/images/agent-setting/3-1.png" alt="打开开发者模式" class="agent-browser-guide-drawer__step-img max-w602" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 步骤4:将CRX安装包拖入安装 -->
|
||||||
|
<div class="agent-browser-guide-drawer__card">
|
||||||
|
<div class="agent-browser-guide-drawer__step-row">
|
||||||
|
<span class="agent-browser-guide-drawer__step-num">4</span>
|
||||||
|
<div class="agent-browser-guide-drawer__step-info">
|
||||||
|
<h4 class="agent-browser-guide-drawer__step-title">点击加载未打包的扩展程序</h4>
|
||||||
|
<p class="agent-browser-guide-drawer__step-desc">点击"加载未打包的扩展程序",选择解压后的插件文件夹,完成安装</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 步骤4示意图 -->
|
||||||
|
<img src="@/assets/images/agent-setting/4-1.png" alt="拖入安装" class="agent-browser-guide-drawer__step-img" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
|
/** 插件下载地址 */
|
||||||
|
const extensionDownloadUrl = 'https://offerpie.oss-cn-guangzhou.aliyuncs.com/extension/Offer派智能投递助手.zip'
|
||||||
|
|
||||||
|
/** 下载插件 */
|
||||||
|
function downloadExtension() {
|
||||||
|
window.open(extensionDownloadUrl, '_blank')
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 复制文本到剪贴板 */
|
||||||
|
function copyToClipboard(text: string) {
|
||||||
|
navigator.clipboard.writeText(text).then(() => {
|
||||||
|
ElMessage.success('已复制到剪贴板')
|
||||||
|
}).catch(() => {
|
||||||
|
ElMessage.error('复制失败,请手动复制')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 暴露方法给父组件调用 */
|
||||||
|
defineExpose({ downloadExtension })
|
||||||
|
</script>
|
||||||
@@ -250,141 +250,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 步骤内容 -->
|
<!-- 步骤内容 -->
|
||||||
<div class="agent-browser-guide-drawer__body">
|
<AgentBrowserInstallGuide />
|
||||||
<!-- 步骤1:下载插件包 -->
|
|
||||||
<div class="agent-browser-guide-drawer__card">
|
|
||||||
<div class="agent-browser-guide-drawer__step-row">
|
|
||||||
<span class="agent-browser-guide-drawer__step-num">1</span>
|
|
||||||
<div class="agent-browser-guide-drawer__step-info">
|
|
||||||
<h4 class="agent-browser-guide-drawer__step-title">下载插件包</h4>
|
|
||||||
<p class="agent-browser-guide-drawer__step-desc">下载 Offer派自动投递助手安装包,下载完成后由步骤 2 进入浏览器扩展页面</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="agent-browser-guide-drawer__download-box w263">
|
|
||||||
<span class="agent-browser-guide-drawer__download-name">Offer派自动投递助手.crx</span>
|
|
||||||
<button class="agent-browser-guide-drawer__download-btn" @click="downloadExtension">
|
|
||||||
<svg viewBox="0 0 16 16" fill="none" width="14" height="14"><path d="M8 2v8M8 10L5 7M8 10l3-3M3 13h10" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
||||||
<span>下载</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 步骤2:打开扩展管理页面 -->
|
|
||||||
<div class="agent-browser-guide-drawer__card">
|
|
||||||
<div class="agent-browser-guide-drawer__step-row">
|
|
||||||
<span class="agent-browser-guide-drawer__step-num">2</span>
|
|
||||||
<div class="agent-browser-guide-drawer__step-info">
|
|
||||||
<h4 class="agent-browser-guide-drawer__step-title">打开扩展管理页面</h4>
|
|
||||||
<p class="agent-browser-guide-drawer__step-desc">在浏览器地址栏输入对应地址并回车,打开扩展管理页面</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 浏览器地址链接 -->
|
|
||||||
<div class="agent-browser-guide-drawer__browser-links">
|
|
||||||
<div class="agent-browser-guide-drawer__browser-link" @click="copyToClipboard('chrome://extensions')">
|
|
||||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g clip-path="url(#clip0_498_5140)">
|
|
||||||
<path d="M8.00027 12.4507C10.4587 12.4507 12.4516 10.4577 12.4516 7.99929C12.4516 5.54085 10.4587 3.54785 8.00027 3.54785C5.54183 3.54785 3.54883 5.54085 3.54883 7.99929C3.54883 10.4577 5.54177 12.4507 8.0002 12.4507" fill="white"/>
|
|
||||||
<path d="M2.24303 5.81204C1.91094 5.23683 1.52061 4.63314 1.07203 4.00098C0.369757 5.21706 2.38548e-05 6.59661 1.15428e-09 8.0009C-2.38525e-05 9.4052 0.369663 10.7848 1.07189 12.0009C1.77412 13.217 2.78414 14.2268 4.0004 14.9288C5.21666 15.6307 6.59629 16.0001 8.00059 15.9998C8.73688 14.9671 9.2368 14.2225 9.50034 13.766C10.0065 12.8893 10.6612 11.6341 11.4643 10.0004V9.99941C11.1134 10.6077 10.6086 11.113 10.0005 11.4643C9.39241 11.8156 8.70256 12.0006 8.0003 12.0007C7.29804 12.0008 6.60813 11.816 5.99995 11.4649C5.39178 11.1138 4.88677 10.6087 4.53571 10.0005C3.44496 7.96623 2.68073 6.57004 2.24303 5.81204Z" fill="#229342"/>
|
|
||||||
<path d="M8.00046 16.0002C9.05106 16.0004 10.0914 15.7936 11.0621 15.3916C12.0327 14.9896 12.9147 14.4003 13.6575 13.6574C14.4004 12.9145 14.9896 12.0325 15.3915 11.0619C15.7935 10.0912 16.0002 9.05084 16 8.00024C15.9997 6.59593 15.6297 5.21644 14.9273 4.00043C13.4118 3.85105 12.2933 3.77637 11.5719 3.77637C10.7539 3.77637 9.56323 3.85105 7.9999 4.00043L7.99902 4.00105C8.7013 4.00071 9.39128 4.18529 9.99958 4.53623C10.6079 4.88717 11.113 5.39211 11.4643 6.00024C11.8155 6.60838 12.0004 7.29828 12.0004 8.00056C12.0004 8.70284 11.8155 9.39274 11.4642 10.0009L8.00046 16.0002Z" fill="#FBC116"/>
|
|
||||||
<path d="M8.00013 11.1677C9.74913 11.1677 11.1669 9.74992 11.1669 8.00086C11.1669 6.2518 9.74913 4.83398 8.00006 4.83398C6.25113 4.83398 4.83325 6.25186 4.83325 8.00086C4.83325 9.74986 6.25113 11.1677 8.00013 11.1677Z" fill="#1A73E8"/>
|
|
||||||
<path d="M8.00027 4.00027H14.9276C14.2256 2.78399 13.2158 1.77397 11.9997 1.07176C10.7835 0.369547 9.40396 -9.50021e-05 7.99965 1.83149e-08C6.59534 9.50388e-05 5.21581 0.369924 3.99978 1.0723C2.78374 1.77467 1.77406 2.78484 1.07227 4.00121L4.53595 10.0006L4.53689 10.0011C4.18549 9.39306 4.00037 8.70322 4.00017 8.00095C3.99996 7.29868 4.18467 6.60873 4.53571 6.0005C4.88676 5.39226 5.39177 4.88718 5.99995 4.53605C6.60814 4.18491 7.29806 4.0001 8.00033 4.00021L8.00027 4.00027Z" fill="#E33B2E"/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip0_498_5140">
|
|
||||||
<rect width="16" height="16" fill="white"/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
<span>Chrome浏览器:chrome://extensions</span>
|
|
||||||
<span class="agent-browser-guide-drawer__copy-btn">
|
|
||||||
<svg viewBox="0 0 14 14" fill="none" width="12" height="12"><rect x="4" y="4" width="8" height="8" rx="1" stroke="currentColor" stroke-width="1"/><path d="M10 4V3a1 1 0 00-1-1H3a1 1 0 00-1 1v6a1 1 0 001 1h1" stroke="currentColor" stroke-width="1"/></svg>
|
|
||||||
复制
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="agent-browser-guide-drawer__browser-link" @click="copyToClipboard('edge://extensions')">
|
|
||||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g clip-path="url(#clip0_498_5157)">
|
|
||||||
<path d="M14.4375 11.9059C14.225 12.0184 14.0062 12.1184 13.7812 12.1996C13.0625 12.4684 12.3062 12.6059 11.5375 12.6059C8.5812 12.6059 6.0062 10.5746 6.0062 7.96211C6.01245 7.24961 6.4062 6.59336 7.0312 6.25586C4.3562 6.36836 3.6687 9.15586 3.6687 10.7871C3.6687 15.4059 7.92495 15.8746 8.8437 15.8746C9.33745 15.8746 10.0812 15.7309 10.5312 15.5871L10.6125 15.5621C12.3375 14.9684 13.8 13.8059 14.775 12.2621C14.85 12.1434 14.8125 11.9934 14.7 11.9184C14.6187 11.8684 14.5187 11.8621 14.4375 11.9059Z" fill="url(#paint0_linear_498_5157)"/>
|
|
||||||
<path opacity="0.35" d="M14.4375 11.9059C14.225 12.0184 14.0062 12.1184 13.7812 12.1996C13.0625 12.4684 12.3062 12.6059 11.5375 12.6059C8.5812 12.6059 6.0062 10.5746 6.0062 7.96211C6.01245 7.24961 6.4062 6.59336 7.0312 6.25586C4.3562 6.36836 3.6687 9.15586 3.6687 10.7871C3.6687 15.4059 7.92495 15.8746 8.8437 15.8746C9.33745 15.8746 10.0812 15.7309 10.5312 15.5871L10.6125 15.5621C12.3375 14.9684 13.8 13.8059 14.775 12.2621C14.85 12.1434 14.8125 11.9934 14.7 11.9184C14.6187 11.8684 14.5187 11.8621 14.4375 11.9059Z" fill="url(#paint1_radial_498_5157)"/>
|
|
||||||
<path d="M6.60629 15.0877C6.05004 14.7439 5.56879 14.2877 5.18754 13.7564C3.54379 11.5064 4.03754 8.3502 6.28754 6.70645C6.52504 6.5377 6.76879 6.38145 7.03129 6.25645C7.22504 6.1627 7.55629 6.0002 8.00004 6.00645C8.63129 6.0127 9.22504 6.3127 9.60629 6.81895C9.85629 7.15645 10 7.5627 10.0063 7.9877C10.0063 7.9752 11.5375 3.0127 5.00629 3.0127C2.26254 3.0127 0.00628588 5.61895 0.00628588 7.9002C-0.00621412 9.10645 0.256286 10.3064 0.762536 11.4002C2.48754 15.0752 6.68754 16.8752 10.5375 15.5939C9.21879 16.0064 7.78129 15.8252 6.60629 15.0877Z" fill="url(#paint2_linear_498_5157)"/>
|
|
||||||
<path opacity="0.41" d="M6.60629 15.0877C6.05004 14.7439 5.56879 14.2877 5.18754 13.7564C3.54379 11.5064 4.03754 8.3502 6.28754 6.70645C6.52504 6.5377 6.76879 6.38145 7.03129 6.25645C7.22504 6.1627 7.55629 6.0002 8.00004 6.00645C8.63129 6.0127 9.22504 6.3127 9.60629 6.81895C9.85629 7.15645 10 7.5627 10.0063 7.9877C10.0063 7.9752 11.5375 3.0127 5.00629 3.0127C2.26254 3.0127 0.00628588 5.61895 0.00628588 7.9002C-0.00621412 9.10645 0.256286 10.3064 0.762536 11.4002C2.48754 15.0752 6.68754 16.8752 10.5375 15.5939C9.21879 16.0064 7.78129 15.8252 6.60629 15.0877Z" fill="url(#paint3_radial_498_5157)"/>
|
|
||||||
<path d="M9.51875 9.30625C9.46875 9.36875 9.3125 9.4625 9.3125 9.6625C9.3125 9.825 9.41875 9.98125 9.60625 10.1125C10.5062 10.7375 12.2 10.6562 12.2063 10.6562C12.875 10.6562 13.525 10.475 14.1 10.1375C15.275 9.45 16 8.19375 16 6.83125C16.0187 5.43125 15.5 4.5 15.2937 4.0875C13.9688 1.49375 11.1062 0 8 0C3.625 0 0.0625 3.5125 0 7.8875C0.03125 5.60625 2.3 3.7625 5 3.7625C5.21875 3.7625 6.46875 3.78125 7.625 4.39375C8.64375 4.93125 9.18125 5.575 9.55 6.21875C9.9375 6.8875 10.0063 7.725 10.0063 8.0625C10.0063 8.39375 9.8375 8.89375 9.51875 9.30625Z" fill="url(#paint4_radial_498_5157)"/>
|
|
||||||
<path d="M9.51875 9.30625C9.46875 9.36875 9.3125 9.4625 9.3125 9.6625C9.3125 9.825 9.41875 9.98125 9.60625 10.1125C10.5062 10.7375 12.2 10.6562 12.2063 10.6562C12.875 10.6562 13.525 10.475 14.1 10.1375C15.275 9.45 16 8.19375 16 6.83125C16.0187 5.43125 15.5 4.5 15.2937 4.0875C13.9688 1.49375 11.1062 0 8 0C3.625 0 0.0625 3.5125 0 7.8875C0.03125 5.60625 2.3 3.7625 5 3.7625C5.21875 3.7625 6.46875 3.78125 7.625 4.39375C8.64375 4.93125 9.18125 5.575 9.55 6.21875C9.9375 6.8875 10.0063 7.725 10.0063 8.0625C10.0063 8.39375 9.8375 8.89375 9.51875 9.30625Z" fill="url(#paint5_radial_498_5157)"/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<linearGradient id="paint0_linear_498_5157" x1="3.66895" y1="11.0634" x2="14.8116" y2="11.0634" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#0C59A4"/>
|
|
||||||
<stop offset="1" stop-color="#114A8B"/>
|
|
||||||
</linearGradient>
|
|
||||||
<radialGradient id="paint1_radial_498_5157" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(9.82444 11.1519) scale(5.96065 5.662)">
|
|
||||||
<stop offset="0.72" stop-opacity="0"/>
|
|
||||||
<stop offset="0.95" stop-opacity="0.53"/>
|
|
||||||
<stop offset="1"/>
|
|
||||||
</radialGradient>
|
|
||||||
<linearGradient id="paint2_linear_498_5157" x1="9.54822" y1="6.23432" x2="2.58741" y2="13.8163" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#1B9DE2"/>
|
|
||||||
<stop offset="0.16" stop-color="#1595DF"/>
|
|
||||||
<stop offset="0.67" stop-color="#0680D7"/>
|
|
||||||
<stop offset="1" stop-color="#0078D4"/>
|
|
||||||
</linearGradient>
|
|
||||||
<radialGradient id="paint3_radial_498_5157" cx="0" cy="0" r="1" gradientTransform="matrix(1.34287 -8.86118 7.162 1.0743 4.41307 12.4383)" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop offset="0.76" stop-opacity="0"/>
|
|
||||||
<stop offset="0.95" stop-opacity="0.5"/>
|
|
||||||
<stop offset="1"/>
|
|
||||||
</radialGradient>
|
|
||||||
<radialGradient id="paint4_radial_498_5157" cx="0" cy="0" r="1" gradientTransform="matrix(-0.506075 12.6493 -26.9472 -1.0119 1.61573 2.96205)" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#35C1F1"/>
|
|
||||||
<stop offset="0.11" stop-color="#34C1ED"/>
|
|
||||||
<stop offset="0.23" stop-color="#2FC2DF"/>
|
|
||||||
<stop offset="0.31" stop-color="#2BC3D2"/>
|
|
||||||
<stop offset="0.67" stop-color="#36C752"/>
|
|
||||||
</radialGradient>
|
|
||||||
<radialGradient id="paint5_radial_498_5157" cx="0" cy="0" r="1" gradientTransform="matrix(1.70345 5.83918 -4.74533 1.39926 15.0038 4.83786)" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#66EB6E"/>
|
|
||||||
<stop offset="1" stop-color="#66EB6E" stop-opacity="0"/>
|
|
||||||
</radialGradient>
|
|
||||||
<clipPath id="clip0_498_5157">
|
|
||||||
<rect width="16" height="16" fill="white"/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
<span>Edge浏览器:edge://extensions</span>
|
|
||||||
<span class="agent-browser-guide-drawer__copy-btn">
|
|
||||||
<svg viewBox="0 0 14 14" fill="none" width="12" height="12"><rect x="4" y="4" width="8" height="8" rx="1" stroke="currentColor" stroke-width="1"/><path d="M10 4V3a1 1 0 00-1-1H3a1 1 0 00-1 1v6a1 1 0 001 1h1" stroke="currentColor" stroke-width="1"/></svg>
|
|
||||||
复制
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 步骤2示意图 -->
|
|
||||||
<img src="@/assets/images/agent-setting/2-1.png" alt="输入扩展地址" class="agent-browser-guide-drawer__step-img" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 步骤3:打开开发者模式 -->
|
|
||||||
<div class="agent-browser-guide-drawer__card">
|
|
||||||
<div class="agent-browser-guide-drawer__step-row">
|
|
||||||
<span class="agent-browser-guide-drawer__step-num">3</span>
|
|
||||||
<div class="agent-browser-guide-drawer__step-info">
|
|
||||||
<h4 class="agent-browser-guide-drawer__step-title">打开开发者模式</h4>
|
|
||||||
<p class="agent-browser-guide-drawer__step-desc">在扩展管理页面的右上角,找到「开发者模式」开关并打开</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 步骤3示意图 -->
|
|
||||||
<img src="@/assets/images/agent-setting/3-1.png" alt="打开开发者模式" class="agent-browser-guide-drawer__step-img" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 步骤4:将CRX安装包拖入安装 -->
|
|
||||||
<div class="agent-browser-guide-drawer__card">
|
|
||||||
<div class="agent-browser-guide-drawer__step-row">
|
|
||||||
<span class="agent-browser-guide-drawer__step-num">4</span>
|
|
||||||
<div class="agent-browser-guide-drawer__step-info">
|
|
||||||
<h4 class="agent-browser-guide-drawer__step-title">将 CRX 安装包拖入安装</h4>
|
|
||||||
<p class="agent-browser-guide-drawer__step-desc">直接将下载好的CRX文件拖拽到扩展管理页面中,浏览器会自动识别并安装插件</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 步骤4示意图 -->
|
|
||||||
<img src="@/assets/images/agent-setting/4-1.png" alt="拖入安装" class="agent-browser-guide-drawer__step-img" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Transition>
|
</Transition>
|
||||||
@@ -399,6 +265,7 @@ import { ElMessage } from 'element-plus'
|
|||||||
import { formatEmploymentType } from '@/stores/index'
|
import { formatEmploymentType } from '@/stores/index'
|
||||||
import JobGoalDialog from '@/components/JobGoalDialog.vue'
|
import JobGoalDialog from '@/components/JobGoalDialog.vue'
|
||||||
import RegionSelector from '@/components/tools/RegionSelector.vue'
|
import RegionSelector from '@/components/tools/RegionSelector.vue'
|
||||||
|
import AgentBrowserInstallGuide from '@/components/AgentBrowserInstallGuide.vue'
|
||||||
import { saveProfile, fetchProfile, fetchEducation } from '@/api/profile'
|
import { saveProfile, fetchProfile, fetchEducation } from '@/api/profile'
|
||||||
import { resolveRegionName } from '@/utils/region'
|
import { resolveRegionName } from '@/utils/region'
|
||||||
import { resolveIndustryName } from '@/utils/industry'
|
import { resolveIndustryName } from '@/utils/industry'
|
||||||
@@ -662,9 +529,6 @@ async function handleSavePreference() {
|
|||||||
/** 浏览器插件安装教程抽屉是否显示 */
|
/** 浏览器插件安装教程抽屉是否显示 */
|
||||||
const showBrowserGuideDrawer = ref(false)
|
const showBrowserGuideDrawer = ref(false)
|
||||||
|
|
||||||
/** 插件下载地址 */
|
|
||||||
const extensionDownloadUrl = 'https://offerpie.oss-cn-guangzhou.aliyuncs.com/extension/chrome-mv3-prod.rar'
|
|
||||||
|
|
||||||
/** 打开浏览器安装指引抽屉 */
|
/** 打开浏览器安装指引抽屉 */
|
||||||
function openBrowserGuide(_browser: string) {
|
function openBrowserGuide(_browser: string) {
|
||||||
showBrowserGuideDrawer.value = true
|
showBrowserGuideDrawer.value = true
|
||||||
@@ -675,20 +539,6 @@ function closeBrowserGuideDrawer() {
|
|||||||
showBrowserGuideDrawer.value = false
|
showBrowserGuideDrawer.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 下载插件 */
|
|
||||||
function downloadExtension() {
|
|
||||||
window.open(extensionDownloadUrl, '_blank')
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 复制文本到剪贴板 */
|
|
||||||
function copyToClipboard(text: string) {
|
|
||||||
navigator.clipboard.writeText(text).then(() => {
|
|
||||||
ElMessage.success('已复制到剪贴板')
|
|
||||||
}).catch(() => {
|
|
||||||
ElMessage.error('复制失败,请手动复制')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==================== 初始化 ====================
|
// ==================== 初始化 ====================
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
<p class="agent-page__intro-desc">请仔细对你的资料评估(包括个人信息、教育背景、工作履历及技能),确保资料齐全</p>
|
<p class="agent-page__intro-desc">请仔细对你的资料评估(包括个人信息、教育背景、工作履历及技能),确保资料齐全</p>
|
||||||
<!-- 按钮 -->
|
<!-- 按钮 -->
|
||||||
<button class="agent-page__intro-gradient-btn" @click="handleNext">下一步</button>
|
<button class="agent-page__intro-gradient-btn" @click="handleNext">下一步</button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -163,164 +164,7 @@
|
|||||||
<!-- 左侧:安装教程内容 -->
|
<!-- 左侧:安装教程内容 -->
|
||||||
<div class="agent-page__right">
|
<div class="agent-page__right">
|
||||||
<div class="agent-page__profile-wrapper bg-f">
|
<div class="agent-page__profile-wrapper bg-f">
|
||||||
<div class="agent-page__install-guide">
|
<AgentBrowserInstallGuide ref="browserInstallGuideRef" />
|
||||||
|
|
||||||
<!-- 步骤1:下载插件包 -->
|
|
||||||
<div class="agent-page__install-card">
|
|
||||||
<div class="agent-page__install-card-row">
|
|
||||||
<div class="agent-page__install-card-left">
|
|
||||||
<div class="agent-page__install-card-header">
|
|
||||||
<span class="agent-page__install-card-num">1</span>
|
|
||||||
<div class="agent-page__install-card-info">
|
|
||||||
<h4 class="agent-page__install-card-title">下载插件包</h4>
|
|
||||||
<p class="agent-page__install-card-desc">下载 Offer派自动投递助手安装包,下载完成后由步骤 2 进入浏览器扩展页面</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="">
|
|
||||||
<div class="agent-page__install-download-box">
|
|
||||||
<span class="agent-page__install-download-name">Offer派自动投递助手.crx</span>
|
|
||||||
<button class="agent-page__install-download-btn2" @click="downloadExtension">
|
|
||||||
<svg viewBox="0 0 16 16" fill="none" width="14" height="14"><path d="M8 2v8M8 10L5 7M8 10l3-3M3 13h10" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
||||||
<span>下载</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 步骤2:打开扩展管理页面 -->
|
|
||||||
<div class="agent-page__install-card">
|
|
||||||
<div class="agent-page__install-card-row">
|
|
||||||
<div class="agent-page__install-card-left">
|
|
||||||
<div class="agent-page__install-card-header">
|
|
||||||
<span class="agent-page__install-card-num">2</span>
|
|
||||||
<div class="agent-page__install-card-info">
|
|
||||||
<h4 class="agent-page__install-card-title">打开扩展管理页面</h4>
|
|
||||||
<p class="agent-page__install-card-desc">在浏览器地址栏输入对应地址并回车,打开扩展管理页面</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 浏览器地址链接 -->
|
|
||||||
<div class="agent-page__install-browser-row">
|
|
||||||
<a class="agent-page__install-browser-link" href="javascript:void(0)" @click="copyToClipboard('chrome://extensions')">
|
|
||||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g clip-path="url(#clip0_525_3895)">
|
|
||||||
<path d="M8.00027 12.4507C10.4587 12.4507 12.4516 10.4577 12.4516 7.99929C12.4516 5.54085 10.4587 3.54785 8.00027 3.54785C5.54183 3.54785 3.54883 5.54085 3.54883 7.99929C3.54883 10.4577 5.54177 12.4507 8.0002 12.4507" fill="white"/>
|
|
||||||
<path d="M2.24303 5.81204C1.91094 5.23683 1.52061 4.63314 1.07203 4.00098C0.369757 5.21706 2.38548e-05 6.59661 1.15428e-09 8.0009C-2.38525e-05 9.4052 0.369663 10.7848 1.07189 12.0009C1.77412 13.217 2.78414 14.2268 4.0004 14.9288C5.21666 15.6307 6.59629 16.0001 8.00059 15.9998C8.73688 14.9671 9.2368 14.2225 9.50034 13.766C10.0065 12.8893 10.6612 11.6341 11.4643 10.0004V9.99941C11.1134 10.6077 10.6086 11.113 10.0005 11.4643C9.39241 11.8156 8.70256 12.0006 8.0003 12.0007C7.29804 12.0008 6.60813 11.816 5.99995 11.4649C5.39178 11.1138 4.88677 10.6087 4.53571 10.0005C3.44496 7.96623 2.68073 6.57004 2.24303 5.81204Z" fill="#229342"/>
|
|
||||||
<path d="M8.00046 16.0002C9.05106 16.0004 10.0914 15.7936 11.0621 15.3916C12.0327 14.9896 12.9147 14.4003 13.6575 13.6574C14.4004 12.9145 14.9896 12.0325 15.3915 11.0619C15.7935 10.0912 16.0002 9.05084 16 8.00024C15.9997 6.59593 15.6297 5.21644 14.9273 4.00043C13.4118 3.85105 12.2933 3.77637 11.5719 3.77637C10.7539 3.77637 9.56323 3.85105 7.9999 4.00043L7.99902 4.00105C8.7013 4.00071 9.39128 4.18529 9.99958 4.53623C10.6079 4.88717 11.113 5.39211 11.4643 6.00024C11.8155 6.60838 12.0004 7.29828 12.0004 8.00056C12.0004 8.70284 11.8155 9.39274 11.4642 10.0009L8.00046 16.0002Z" fill="#FBC116"/>
|
|
||||||
<path d="M8.00037 11.1677C9.74937 11.1677 11.1672 9.74992 11.1672 8.00086C11.1672 6.2518 9.74937 4.83398 8.00031 4.83398C6.25137 4.83398 4.8335 6.25186 4.8335 8.00086C4.8335 9.74986 6.25137 11.1677 8.00037 11.1677Z" fill="#1A73E8"/>
|
|
||||||
<path d="M8.00027 4.00027H14.9276C14.2256 2.78399 13.2158 1.77397 11.9997 1.07176C10.7835 0.369547 9.40396 -9.50021e-05 7.99965 1.83149e-08C6.59534 9.50388e-05 5.21581 0.369924 3.99978 1.0723C2.78374 1.77467 1.77406 2.78484 1.07227 4.00121L4.53595 10.0006L4.53689 10.0011C4.18549 9.39306 4.00037 8.70322 4.00017 8.00095C3.99996 7.29868 4.18467 6.60873 4.53571 6.0005C4.88676 5.39226 5.39177 4.88718 5.99995 4.53605C6.60814 4.18491 7.29806 4.0001 8.00033 4.00021L8.00027 4.00027Z" fill="#E33B2E"/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip0_525_3895">
|
|
||||||
<rect width="16" height="16" fill="white"/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
<span class="agent-page__install-browser-link-label">Chrome浏览器:chrome://extensions</span>
|
|
||||||
<span class="agent-page__install-browser-link-copy">
|
|
||||||
<svg viewBox="0 0 14 14" fill="none" width="12" height="12"><rect x="4" y="4" width="8" height="8" rx="1" stroke="currentColor" stroke-width="1"/><path d="M10 4V3a1 1 0 00-1-1H3a1 1 0 00-1 1v6a1 1 0 001 1h1" stroke="currentColor" stroke-width="1"/></svg>
|
|
||||||
复制
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
<a class="agent-page__install-browser-link" href="javascript:void(0)" @click="copyToClipboard('edge://extensions')">
|
|
||||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g clip-path="url(#clip0_525_3912)">
|
|
||||||
<path d="M14.4377 11.9059C14.2252 12.0184 14.0064 12.1184 13.7814 12.1996C13.0627 12.4684 12.3064 12.6059 11.5377 12.6059C8.58145 12.6059 6.00645 10.5746 6.00645 7.96211C6.0127 7.24961 6.40645 6.59336 7.03145 6.25586C4.35645 6.36836 3.66895 9.15586 3.66895 10.7871C3.66895 15.4059 7.9252 15.8746 8.84395 15.8746C9.3377 15.8746 10.0814 15.7309 10.5314 15.5871L10.6127 15.5621C12.3377 14.9684 13.8002 13.8059 14.7752 12.2621C14.8502 12.1434 14.8127 11.9934 14.7002 11.9184C14.6189 11.8684 14.5189 11.8621 14.4377 11.9059Z" fill="url(#paint0_linear_525_3912)"/>
|
|
||||||
<path opacity="0.35" d="M14.4377 11.9059C14.2252 12.0184 14.0064 12.1184 13.7814 12.1996C13.0627 12.4684 12.3064 12.6059 11.5377 12.6059C8.58145 12.6059 6.00645 10.5746 6.00645 7.96211C6.0127 7.24961 6.40645 6.59336 7.03145 6.25586C4.35645 6.36836 3.66895 9.15586 3.66895 10.7871C3.66895 15.4059 7.9252 15.8746 8.84395 15.8746C9.3377 15.8746 10.0814 15.7309 10.5314 15.5871L10.6127 15.5621C12.3377 14.9684 13.8002 13.8059 14.7752 12.2621C14.8502 12.1434 14.8127 11.9934 14.7002 11.9184C14.6189 11.8684 14.5189 11.8621 14.4377 11.9059Z" fill="url(#paint1_radial_525_3912)"/>
|
|
||||||
<path d="M6.60629 15.0877C6.05004 14.7439 5.56879 14.2877 5.18754 13.7564C3.54379 11.5064 4.03754 8.3502 6.28754 6.70645C6.52504 6.5377 6.76879 6.38145 7.03129 6.25645C7.22504 6.1627 7.55629 6.0002 8.00004 6.00645C8.63129 6.0127 9.22504 6.3127 9.60629 6.81895C9.85629 7.15645 10 7.5627 10.0063 7.9877C10.0063 7.9752 11.5375 3.0127 5.00629 3.0127C2.26254 3.0127 0.00628588 5.61895 0.00628588 7.9002C-0.00621412 9.10645 0.256286 10.3064 0.762536 11.4002C2.48754 15.0752 6.68754 16.8752 10.5375 15.5939C9.21879 16.0064 7.78129 15.8252 6.60629 15.0877Z" fill="url(#paint2_linear_525_3912)"/>
|
|
||||||
<path opacity="0.41" d="M6.60629 15.0877C6.05004 14.7439 5.56879 14.2877 5.18754 13.7564C3.54379 11.5064 4.03754 8.3502 6.28754 6.70645C6.52504 6.5377 6.76879 6.38145 7.03129 6.25645C7.22504 6.1627 7.55629 6.0002 8.00004 6.00645C8.63129 6.0127 9.22504 6.3127 9.60629 6.81895C9.85629 7.15645 10 7.5627 10.0063 7.9877C10.0063 7.9752 11.5375 3.0127 5.00629 3.0127C2.26254 3.0127 0.00628588 5.61895 0.00628588 7.9002C-0.00621412 9.10645 0.256286 10.3064 0.762536 11.4002C2.48754 15.0752 6.68754 16.8752 10.5375 15.5939C9.21879 16.0064 7.78129 15.8252 6.60629 15.0877Z" fill="url(#paint3_radial_525_3912)"/>
|
|
||||||
<path d="M9.51875 9.30625C9.46875 9.36875 9.3125 9.4625 9.3125 9.6625C9.3125 9.825 9.41875 9.98125 9.60625 10.1125C10.5062 10.7375 12.2 10.6562 12.2063 10.6562C12.875 10.6562 13.525 10.475 14.1 10.1375C15.275 9.45 16 8.19375 16 6.83125C16.0187 5.43125 15.5 4.5 15.2937 4.0875C13.9688 1.49375 11.1062 0 8 0C3.625 0 0.0625 3.5125 0 7.8875C0.03125 5.60625 2.3 3.7625 5 3.7625C5.21875 3.7625 6.46875 3.78125 7.625 4.39375C8.64375 4.93125 9.18125 5.575 9.55 6.21875C9.9375 6.8875 10.0063 7.725 10.0063 8.0625C10.0063 8.39375 9.8375 8.89375 9.51875 9.30625Z" fill="url(#paint4_radial_525_3912)"/>
|
|
||||||
<path d="M9.51875 9.30625C9.46875 9.36875 9.3125 9.4625 9.3125 9.6625C9.3125 9.825 9.41875 9.98125 9.60625 10.1125C10.5062 10.7375 12.2 10.6562 12.2063 10.6562C12.875 10.6562 13.525 10.475 14.1 10.1375C15.275 9.45 16 8.19375 16 6.83125C16.0187 5.43125 15.5 4.5 15.2937 4.0875C13.9688 1.49375 11.1062 0 8 0C3.625 0 0.0625 3.5125 0 7.8875C0.03125 5.60625 2.3 3.7625 5 3.7625C5.21875 3.7625 6.46875 3.78125 7.625 4.39375C8.64375 4.93125 9.18125 5.575 9.55 6.21875C9.9375 6.8875 10.0063 7.725 10.0063 8.0625C10.0063 8.39375 9.8375 8.89375 9.51875 9.30625Z" fill="url(#paint5_radial_525_3912)"/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<linearGradient id="paint0_linear_525_3912" x1="3.6692" y1="11.0634" x2="14.8119" y2="11.0634" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#0C59A4"/>
|
|
||||||
<stop offset="1" stop-color="#114A8B"/>
|
|
||||||
</linearGradient>
|
|
||||||
<radialGradient id="paint1_radial_525_3912" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(9.82468 11.1519) scale(5.96065 5.662)">
|
|
||||||
<stop offset="0.72" stop-opacity="0"/>
|
|
||||||
<stop offset="0.95" stop-opacity="0.53"/>
|
|
||||||
<stop offset="1"/>
|
|
||||||
</radialGradient>
|
|
||||||
<linearGradient id="paint2_linear_525_3912" x1="9.54822" y1="6.23432" x2="2.58741" y2="13.8163" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#1B9DE2"/>
|
|
||||||
<stop offset="0.16" stop-color="#1595DF"/>
|
|
||||||
<stop offset="0.67" stop-color="#0680D7"/>
|
|
||||||
<stop offset="1" stop-color="#0078D4"/>
|
|
||||||
</linearGradient>
|
|
||||||
<radialGradient id="paint3_radial_525_3912" cx="0" cy="0" r="1" gradientTransform="matrix(1.34287 -8.86118 7.162 1.0743 4.41307 12.4383)" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop offset="0.76" stop-opacity="0"/>
|
|
||||||
<stop offset="0.95" stop-opacity="0.5"/>
|
|
||||||
<stop offset="1"/>
|
|
||||||
</radialGradient>
|
|
||||||
<radialGradient id="paint4_radial_525_3912" cx="0" cy="0" r="1" gradientTransform="matrix(-0.506075 12.6493 -26.9472 -1.0119 1.61573 2.96205)" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#35C1F1"/>
|
|
||||||
<stop offset="0.11" stop-color="#34C1ED"/>
|
|
||||||
<stop offset="0.23" stop-color="#2FC2DF"/>
|
|
||||||
<stop offset="0.31" stop-color="#2BC3D2"/>
|
|
||||||
<stop offset="0.67" stop-color="#36C752"/>
|
|
||||||
</radialGradient>
|
|
||||||
<radialGradient id="paint5_radial_525_3912" cx="0" cy="0" r="1" gradientTransform="matrix(1.70345 5.83918 -4.74533 1.39926 15.0038 4.83786)" gradientUnits="userSpaceOnUse">
|
|
||||||
<stop stop-color="#66EB6E"/>
|
|
||||||
<stop offset="1" stop-color="#66EB6E" stop-opacity="0"/>
|
|
||||||
</radialGradient>
|
|
||||||
<clipPath id="clip0_525_3912">
|
|
||||||
<rect width="16" height="16" fill="white"/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
<span class="agent-page__install-browser-link-label">Edge浏览器:edge://extensions</span>
|
|
||||||
<span class="agent-page__install-browser-link-copy">
|
|
||||||
<svg viewBox="0 0 14 14" fill="none" width="12" height="12"><rect x="4" y="4" width="8" height="8" rx="1" stroke="currentColor" stroke-width="1"/><path d="M10 4V3a1 1 0 00-1-1H3a1 1 0 00-1 1v6a1 1 0 001 1h1" stroke="currentColor" stroke-width="1"/></svg>
|
|
||||||
复制
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="agent-page__install-card-right">
|
|
||||||
<img src="@/assets/images/agent-setting/2-1.png" alt="输入扩展地址" class="agent-page__install-card-img" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 步骤3:打开开发者模式 -->
|
|
||||||
<div class="agent-page__install-card">
|
|
||||||
<div class="agent-page__install-card-row">
|
|
||||||
<div class="agent-page__install-card-left">
|
|
||||||
<div class="agent-page__install-card-header">
|
|
||||||
<span class="agent-page__install-card-num">3</span>
|
|
||||||
<div class="agent-page__install-card-info">
|
|
||||||
<h4 class="agent-page__install-card-title">打开开发者模式</h4>
|
|
||||||
<p class="agent-page__install-card-desc">在扩展管理页面的右上角,找到「开发者模式」开关并打开</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="agent-page__install-card-right">
|
|
||||||
<img src="@/assets/images/agent-setting/3-1.png" alt="打开开发者模式" class="agent-page__install-card-img" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 步骤4:将CRX安装包拖入安装 -->
|
|
||||||
<div class="agent-page__install-card">
|
|
||||||
<div class="agent-page__install-card-row">
|
|
||||||
<div class="agent-page__install-card-left">
|
|
||||||
<div class="agent-page__install-card-header">
|
|
||||||
<span class="agent-page__install-card-num">4</span>
|
|
||||||
<div class="agent-page__install-card-info">
|
|
||||||
<h4 class="agent-page__install-card-title">将 CRX 安装包拖入安装</h4>
|
|
||||||
<p class="agent-page__install-card-desc">直接将下载好的CRX文件拖拽到扩展管理页面中,浏览器会自动识别并安装插件</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="agent-page__install-card-right">
|
|
||||||
<img src="@/assets/images/agent-setting/4-1.png" alt="拖入安装" class="agent-page__install-card-img" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 右侧:确认卡片 -->
|
<!-- 右侧:确认卡片 -->
|
||||||
@@ -335,8 +179,14 @@
|
|||||||
<h2 class="agent-page__intro-title">安装浏览器自动投递插件</h2>
|
<h2 class="agent-page__intro-title">安装浏览器自动投递插件</h2>
|
||||||
<!-- 描述 -->
|
<!-- 描述 -->
|
||||||
<p class="agent-page__intro-desc">按照左侧步骤完成插件安装,即可开启自动投递功能</p>
|
<p class="agent-page__intro-desc">按照左侧步骤完成插件安装,即可开启自动投递功能</p>
|
||||||
<!-- 按钮 -->
|
<!-- 按钮:在线显示下一步,离线显示安装确认按钮 -->
|
||||||
<button class="agent-page__intro-gradient-btn" @click="handleNext">下一步</button>
|
<button v-if="plugIsOnline" class="agent-page__intro-gradient-btn" @click="handleNext">下一步</button>
|
||||||
|
<button v-else class="agent-page__intro-gradient-btn" @click="handleInstallConfirm">
|
||||||
|
<svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0.625 10.2117V11.0417C0.625 11.7047 0.888392 12.3406 1.35723 12.8094C1.82607 13.2783 2.46196 13.5417 3.125 13.5417H11.4583C12.1214 13.5417 12.7573 13.2783 13.2261 12.8094C13.6949 12.3406 13.9583 11.7047 13.9583 11.0417V10.2083M7.29167 0.625V9.79167M4.375 6.875L7.29167 9.79167L10.2083 6.875" stroke="white" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
下载插件
|
||||||
|
</button>
|
||||||
<button class="agent-page__intro-back-btn" @click="handleBack">上一步</button>
|
<button class="agent-page__intro-back-btn" @click="handleBack">上一步</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -357,6 +207,31 @@
|
|||||||
|
|
||||||
<!-- 求职目标设置弹窗 -->
|
<!-- 求职目标设置弹窗 -->
|
||||||
<JobGoalDialog v-model="showJobGoalDialog" />
|
<JobGoalDialog v-model="showJobGoalDialog" />
|
||||||
|
|
||||||
|
<!-- 插件安装确认弹窗 -->
|
||||||
|
<Teleport to="body">
|
||||||
|
<div v-if="showInstallDialog" class="agent-page__install-dialog-overlay" @click.self="showInstallDialog = false">
|
||||||
|
<div class="agent-page__install-dialog">
|
||||||
|
<!-- 渐变背景 -->
|
||||||
|
<div class="agent-page__install-dialog-bg"></div>
|
||||||
|
<!-- 关闭按钮 -->
|
||||||
|
<div class="agent-page__install-dialog-close" @click="showInstallDialog = false">
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||||
|
<path d="M18 6L6 18M6 6l12 12" stroke="#6A7282" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<!-- 标题 -->
|
||||||
|
<h3 class="agent-page__install-dialog-title">插件是否已安装成功?</h3>
|
||||||
|
<!-- 描述 -->
|
||||||
|
<p class="agent-page__install-dialog-desc">智能投递助手需要配合浏览器插件使用<br/>请确认插件已成功安装并启用<br/>否则将无法正常进行自动填写和投递</p>
|
||||||
|
<!-- 底部按钮 -->
|
||||||
|
<div class="agent-page__install-dialog-btns">
|
||||||
|
<button class="agent-page__install-dialog-btn agent-page__install-dialog-btn--outline" @click="showInstallDialog = false">还未安装</button>
|
||||||
|
<button class="agent-page__install-dialog-btn agent-page__install-dialog-btn--primary" @click="handleInstallConfirmReload">已安装,继续</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Teleport>
|
||||||
</div>
|
</div>
|
||||||
<!-- 功能说明 — 独立区块,仅第2步显示 -->
|
<!-- 功能说明 — 独立区块,仅第2步显示 -->
|
||||||
<div v-if="currentStep === 2" class="agent-page__step2-faq mrl24 mt16">
|
<div v-if="currentStep === 2" class="agent-page__step2-faq mrl24 mt16">
|
||||||
@@ -391,6 +266,7 @@ import JobGoalDialog from '@/components/JobGoalDialog.vue'
|
|||||||
import RegionSelector from '@/components/tools/RegionSelector.vue'
|
import RegionSelector from '@/components/tools/RegionSelector.vue'
|
||||||
import JobCategorySelector from '@/components/tools/JobCategorySelector.vue'
|
import JobCategorySelector from '@/components/tools/JobCategorySelector.vue'
|
||||||
import IndustrySelector from '@/components/tools/IndustrySelector.vue'
|
import IndustrySelector from '@/components/tools/IndustrySelector.vue'
|
||||||
|
import AgentBrowserInstallGuide from '@/components/AgentBrowserInstallGuide.vue'
|
||||||
import { saveProfile, saveEducation, saveWork, saveInternship, saveProject, saveCompetition, fetchProfile, fetchEducation, fetchWork, fetchInternship, fetchProject, fetchCompetition } from '@/api/profile'
|
import { saveProfile, saveEducation, saveWork, saveInternship, saveProject, saveCompetition, fetchProfile, fetchEducation, fetchWork, fetchInternship, fetchProject, fetchCompetition } from '@/api/profile'
|
||||||
import type { SaveEducationItem, SaveWorkItem, SaveProjectItem, SaveCompetitionItem } from '@/api/profile'
|
import type { SaveEducationItem, SaveWorkItem, SaveProjectItem, SaveCompetitionItem } from '@/api/profile'
|
||||||
import { fetchResumeList, setDefaultResume } from '@/api/resume'
|
import { fetchResumeList, setDefaultResume } from '@/api/resume'
|
||||||
@@ -434,6 +310,13 @@ const editInitialData = ref<Record<string, any>>({})
|
|||||||
|
|
||||||
// ==================== 个人档案数据 ====================
|
// ==================== 个人档案数据 ====================
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
// 恢复刷新前保存的步骤号
|
||||||
|
const savedStep = sessionStorage.getItem('wizardStep')
|
||||||
|
if (savedStep) {
|
||||||
|
currentStep.value = Number(savedStep)
|
||||||
|
sessionStorage.removeItem('wizardStep')
|
||||||
|
}
|
||||||
|
|
||||||
if (!store.state.regions.length) store.dispatch('loadCommonData')
|
if (!store.state.regions.length) store.dispatch('loadCommonData')
|
||||||
store.dispatch('loadJobIntention')
|
store.dispatch('loadJobIntention')
|
||||||
await loadProfile()
|
await loadProfile()
|
||||||
@@ -444,6 +327,10 @@ onMounted(async () => {
|
|||||||
await loadCompetition()
|
await loadCompetition()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// ==================== 通信桥接:插件在线状态从 store 全局获取 ====================
|
||||||
|
/** 插件是否在线(从 vuex 全局状态读取) */
|
||||||
|
const plugIsOnline = computed(() => store.state.plugIsOnline)
|
||||||
|
|
||||||
async function loadProfile() {
|
async function loadProfile() {
|
||||||
try {
|
try {
|
||||||
const res = await fetchProfile()
|
const res = await fetchProfile()
|
||||||
@@ -763,19 +650,25 @@ watch(selectedResumeId, async (newId, oldId) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// ==================== 第3步:安装插件 ====================
|
// ==================== 第3步:安装插件 ====================
|
||||||
/** 插件下载地址 */
|
|
||||||
const extensionDownloadUrl = 'https://offerpie.oss-cn-guangzhou.aliyuncs.com/extension/chrome-mv3-prod.rar'
|
|
||||||
|
|
||||||
/** 下载插件 */
|
/** 浏览器插件安装指引组件引用 */
|
||||||
function downloadExtension() { window.open(extensionDownloadUrl, '_blank') }
|
const browserInstallGuideRef = ref<InstanceType<typeof AgentBrowserInstallGuide> | null>(null)
|
||||||
|
|
||||||
/** 复制文本到剪贴板 */
|
/** 插件安装确认弹窗 */
|
||||||
function copyToClipboard(text: string) {
|
const showInstallDialog = ref(false)
|
||||||
navigator.clipboard.writeText(text).then(() => {
|
|
||||||
ElMessage.success('已复制到剪贴板')
|
/** 点击"下载插件":下载插件文件 + 弹出安装确认弹窗 */
|
||||||
}).catch(() => {
|
function handleInstallConfirm() {
|
||||||
ElMessage.error('复制失败,请手动复制')
|
// 触发下载插件文件
|
||||||
})
|
browserInstallGuideRef.value?.downloadExtension()
|
||||||
|
// 显示安装确认弹窗
|
||||||
|
showInstallDialog.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 点击"已安装,继续":保存步骤 + 刷新页面 */
|
||||||
|
function handleInstallConfirmReload() {
|
||||||
|
sessionStorage.setItem('wizardStep', String(currentStep.value))
|
||||||
|
location.reload()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==================== 第4步:配置求职助手 ====================
|
// ==================== 第4步:配置求职助手 ====================
|
||||||
|
|||||||
@@ -10,3 +10,6 @@ createApp(App)
|
|||||||
.use(store)
|
.use(store)
|
||||||
.use(remAdaptPlugin)
|
.use(remAdaptPlugin)
|
||||||
.mount('#app')
|
.mount('#app')
|
||||||
|
|
||||||
|
// 启动浏览器插件心跳监听(全局常驻)
|
||||||
|
store.dispatch('startPlugHeartbeat')
|
||||||
@@ -11,6 +11,7 @@ import { fetchUserInfo } from '@/api/auth'
|
|||||||
import type { UserInfo } from '@/api/auth'
|
import type { UserInfo } from '@/api/auth'
|
||||||
import { fetchMemberStatus } from '@/api/member'
|
import { fetchMemberStatus } from '@/api/member'
|
||||||
import type { MemberStatus } from '@/api/member'
|
import type { MemberStatus } from '@/api/member'
|
||||||
|
import { createChannelBridge } from '@/utils/channelBridge'
|
||||||
|
|
||||||
/** 招聘分类选项:label → 接口参数 recruitCategory */
|
/** 招聘分类选项:label → 接口参数 recruitCategory */
|
||||||
export const JOB_TYPE_OPTIONS: { label: string; value: number }[] = [
|
export const JOB_TYPE_OPTIONS: { label: string; value: number }[] = [
|
||||||
@@ -164,6 +165,12 @@ export interface RootState {
|
|||||||
* 全局会员权限拦截弹窗 — 路由守卫或页面检测到免费用户时触发
|
* 全局会员权限拦截弹窗 — 路由守卫或页面检测到免费用户时触发
|
||||||
*/
|
*/
|
||||||
showMemberAccessDialog: boolean
|
showMemberAccessDialog: boolean
|
||||||
|
|
||||||
|
/** 通信桥接组件的域名标识(用于 BroadcastChannel 频道隔离) */
|
||||||
|
bridgeDomain: string
|
||||||
|
|
||||||
|
/** 浏览器插件是否在线(3秒内有 BroadcastChannel 心跳则为 true) */
|
||||||
|
plugIsOnline: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export default createStore<RootState>({
|
export default createStore<RootState>({
|
||||||
@@ -195,6 +202,10 @@ export default createStore<RootState>({
|
|||||||
settingsTab: 'account',
|
settingsTab: 'account',
|
||||||
inviteCode: '',
|
inviteCode: '',
|
||||||
showMemberAccessDialog: false,
|
showMemberAccessDialog: false,
|
||||||
|
/** 通信桥接组件的域名标识(用于 BroadcastChannel 频道隔离) */
|
||||||
|
bridgeDomain: 'test.offerpai.com.cn',
|
||||||
|
/** 浏览器插件是否在线 */
|
||||||
|
plugIsOnline: false,
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
getAppName: (state) => state.appName,
|
getAppName: (state) => state.appName,
|
||||||
@@ -270,6 +281,9 @@ export default createStore<RootState>({
|
|||||||
SET_SHOW_MEMBER_ACCESS_DIALOG(state, show: boolean) {
|
SET_SHOW_MEMBER_ACCESS_DIALOG(state, show: boolean) {
|
||||||
state.showMemberAccessDialog = show
|
state.showMemberAccessDialog = show
|
||||||
},
|
},
|
||||||
|
SET_PLUG_IS_ONLINE(state, online: boolean) {
|
||||||
|
state.plugIsOnline = online
|
||||||
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
updateAppName({ commit }, name: string) {
|
updateAppName({ commit }, name: string) {
|
||||||
@@ -448,6 +462,81 @@ export default createStore<RootState>({
|
|||||||
return { code: '0', message: 'ok' }
|
return { code: '0', message: 'ok' }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化浏览器插件心跳监听
|
||||||
|
* 双重检测机制:
|
||||||
|
* 1. BroadcastChannel watch — 实时收心跳(插件与本页面同时在线时最快)
|
||||||
|
* 2. 定时轮询 bridge.get 读 IndexedDB — 每3秒兜底检测(覆盖 BroadcastChannel 不通的场景)
|
||||||
|
* 启动时立即 get 一次快速判断初始在线状态
|
||||||
|
* 返回销毁函数
|
||||||
|
*/
|
||||||
|
startPlugHeartbeat({ commit, state }) {
|
||||||
|
const bridge = createChannelBridge({ domain: state.bridgeDomain })
|
||||||
|
let lastHeartbeat = 0
|
||||||
|
|
||||||
|
/** 解析 updateTime 字符串为时间戳(格式:yyyy-MM-dd HH:mm:ss) */
|
||||||
|
function parseTime(timeStr: string): number {
|
||||||
|
return new Date(timeStr.replace(' ', 'T')).getTime()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据 updateTime 判断是否在线并更新状态 */
|
||||||
|
function checkOnline(updateTime: string) {
|
||||||
|
const elapsed = Date.now() - parseTime(updateTime)
|
||||||
|
if (elapsed <= 3000) {
|
||||||
|
lastHeartbeat = Date.now()
|
||||||
|
if (!state.plugIsOnline) {
|
||||||
|
commit('SET_PLUG_IS_ONLINE', true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动时立即 get 一次,根据 updateTime 判断初始在线状态
|
||||||
|
bridge.get<{ usage: string }>(state.bridgeDomain, 'offerpieBrowserPlugUsage').then((data) => {
|
||||||
|
if (data && data.updateTime) {
|
||||||
|
checkOnline(data.updateTime)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 方式1:BroadcastChannel watch — 实时收心跳
|
||||||
|
const unwatch = bridge.watch<{ usage: string }>(
|
||||||
|
state.bridgeDomain,
|
||||||
|
'offerpieBrowserPlugUsage',
|
||||||
|
(data) => {
|
||||||
|
if (data && data.updateTime) {
|
||||||
|
checkOnline(data.updateTime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// 方式2:定时轮询 get IndexedDB — 兜底(覆盖 BroadcastChannel 断连场景)
|
||||||
|
const pollTimer = setInterval(async () => {
|
||||||
|
try {
|
||||||
|
const data = await bridge.get<{ usage: string }>(state.bridgeDomain, 'offerpieBrowserPlugUsage')
|
||||||
|
// console.log('[plugHeartbeat] poll get:', data)
|
||||||
|
if (data && data.updateTime) {
|
||||||
|
checkOnline(data.updateTime)
|
||||||
|
}
|
||||||
|
} catch { /* 忽略读取异常 */ }
|
||||||
|
}, 3000)
|
||||||
|
|
||||||
|
// 定时检查超时(3秒无心跳判定离线)
|
||||||
|
const checkTimer = setInterval(() => {
|
||||||
|
if (lastHeartbeat > 0 && Date.now() - lastHeartbeat > 3000) {
|
||||||
|
if (state.plugIsOnline) {
|
||||||
|
commit('SET_PLUG_IS_ONLINE', false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
|
||||||
|
// 返回销毁函数
|
||||||
|
return () => {
|
||||||
|
unwatch()
|
||||||
|
clearInterval(pollTimer)
|
||||||
|
clearInterval(checkTimer)
|
||||||
|
bridge.destroy()
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
modules: {},
|
modules: {},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -0,0 +1,417 @@
|
|||||||
|
/**
|
||||||
|
* OfferPie 跨标签页通信桥接组件
|
||||||
|
* 用于浏览器插件与网站页面之间的纯本地通信(不依赖任何后端接口)
|
||||||
|
*
|
||||||
|
* 【使用说明】
|
||||||
|
* 1. 引入并创建实例:
|
||||||
|
* import { createChannelBridge } from './channelBridge'
|
||||||
|
* const bridge = createChannelBridge({ domain: 'offerpai.com', isPlugin: true })
|
||||||
|
*
|
||||||
|
* 2. 发送数据(单次,同时写缓存 + 广播):
|
||||||
|
* bridge.put<MyDataType>('offerpai.com', 'resumeStatus', { ... })
|
||||||
|
*
|
||||||
|
* 3. 高频发送(节流写缓存,每次都广播):
|
||||||
|
* bridge.emit<MyDataType>('offerpai.com', 'cursorPosition', { ... })
|
||||||
|
*
|
||||||
|
* 4. 主动获取一次数据(先广播问对方,60ms超时转IndexedDB):
|
||||||
|
* const result = await bridge.get<MyDataType>('offerpai.com', 'resumeStatus')
|
||||||
|
*
|
||||||
|
* 5. 持续监听数据变化(初始读一次缓存,后续实时接收 put/emit):
|
||||||
|
* const unwatch = bridge.watch<MyDataType>('offerpai.com', 'resumeStatus', (data) => { ... })
|
||||||
|
* // 取消监听
|
||||||
|
* unwatch()
|
||||||
|
*
|
||||||
|
* 6. 销毁实例(页面卸载时调用):
|
||||||
|
* bridge.destroy()
|
||||||
|
*
|
||||||
|
* 【参数说明】
|
||||||
|
* - domain: 频道域名标识,不同网站项目用不同域名隔离
|
||||||
|
* - isPlugin: 是否为插件环境,默认 false(非插件时会启用 Web Lock 保活)
|
||||||
|
*
|
||||||
|
* 【数据类型要求】
|
||||||
|
* - 传递的数据必须有 TypeScript 类型定义(泛型约束 extends object)
|
||||||
|
* - 组件自动为每条数据添加 createTime 和 updateTime 字段
|
||||||
|
*
|
||||||
|
* ============================================================
|
||||||
|
* 【通信数据名称注册表】
|
||||||
|
* 在此区域记录所有通信数据的名称、类型和用途说明
|
||||||
|
* 新增数据时在此补充,删除时移除对应行
|
||||||
|
* ------------------------------------------------------------
|
||||||
|
* | 数据名(name) | 中文名称 | 说明 |
|
||||||
|
* | ----------------------------- | -------------- | --------------------------------- |
|
||||||
|
* | offerpieBrowserPlugUsage | 插件使用状态 | 标识插件正在运行 { usage: string } |
|
||||||
|
* ============================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
// ============ 类型定义 ============
|
||||||
|
|
||||||
|
/** 组件自动附加的时间戳字段 */
|
||||||
|
export interface BridgeTimestamp {
|
||||||
|
/** 数据首次创建时间(格式:yyyy-MM-dd HH:mm:ss) */
|
||||||
|
createTime: string
|
||||||
|
/** 数据最近更新时间(格式:yyyy-MM-dd HH:mm:ss) */
|
||||||
|
updateTime: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 带时间戳的完整数据包装 */
|
||||||
|
export type BridgeData<T extends object> = T & BridgeTimestamp
|
||||||
|
|
||||||
|
/** IndexedDB 存储记录结构 */
|
||||||
|
interface DBRecord {
|
||||||
|
/** 数据名称(唯一索引) */
|
||||||
|
name: string
|
||||||
|
/** JSON 数据本体 */
|
||||||
|
data: object
|
||||||
|
/** 创建时间 */
|
||||||
|
createTime: string
|
||||||
|
/** 更新时间 */
|
||||||
|
updateTime: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/** BroadcastChannel 消息结构 */
|
||||||
|
interface ChannelMessage {
|
||||||
|
/** 消息类型 */
|
||||||
|
type: 'put' | 'emit' | 'get-request' | 'get-response'
|
||||||
|
/** 数据名称 */
|
||||||
|
name: string
|
||||||
|
/** 请求唯一ID(用于 get 请求-响应匹配) */
|
||||||
|
id?: string
|
||||||
|
/** 数据本体(put/emit/get-response 携带) */
|
||||||
|
data?: object
|
||||||
|
/** 创建时间 */
|
||||||
|
createTime?: string
|
||||||
|
/** 更新时间 */
|
||||||
|
updateTime?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/** watch 回调函数类型 */
|
||||||
|
type WatchCallback<T extends object> = (data: BridgeData<T> | null) => void
|
||||||
|
|
||||||
|
/** 创建实例的配置参数 */
|
||||||
|
export interface ChannelBridgeOptions {
|
||||||
|
/** 默认域名(可在方法调用时覆盖) */
|
||||||
|
domain: string
|
||||||
|
/** 是否为插件环境,默认 false。非插件时启用 Web Lock 保活 */
|
||||||
|
isPlugin?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============ 常量 ============
|
||||||
|
|
||||||
|
/** IndexedDB 数据库名称(含固定雪花ID保证唯一性) */
|
||||||
|
const DB_NAME = 'offerpie_comm_7394028156183472'
|
||||||
|
/** IndexedDB 版本号 */
|
||||||
|
const DB_VERSION = 1
|
||||||
|
/** get 方法 BroadcastChannel 超时时间(毫秒) */
|
||||||
|
const GET_TIMEOUT_MS = 60
|
||||||
|
/** emit 方法节流写库间隔(毫秒) */
|
||||||
|
const EMIT_THROTTLE_MS = 500
|
||||||
|
|
||||||
|
// ============ 工具函数 ============
|
||||||
|
|
||||||
|
/** 获取当前时间的 localDateTime 格式字符串:yyyy-MM-dd HH:mm:ss */
|
||||||
|
function nowLocalDateTime(): string {
|
||||||
|
const d = new Date()
|
||||||
|
const pad = (n: number) => String(n).padStart(2, '0')
|
||||||
|
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 生成简单唯一ID(用于 get 请求匹配) */
|
||||||
|
function uid(): string {
|
||||||
|
return Date.now().toString(36) + Math.random().toString(36).slice(2, 8)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============ IndexedDB 操作 ============
|
||||||
|
|
||||||
|
/** 打开/创建 IndexedDB 数据库,按 domain 动态创建 ObjectStore */
|
||||||
|
function openDB(storeName: string): Promise<IDBDatabase> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const request = indexedDB.open(DB_NAME, DB_VERSION)
|
||||||
|
request.onupgradeneeded = () => {
|
||||||
|
const db = request.result
|
||||||
|
if (!db.objectStoreNames.contains(storeName)) {
|
||||||
|
const store = db.createObjectStore(storeName, { keyPath: 'name' })
|
||||||
|
store.createIndex('name', 'name', { unique: true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
request.onsuccess = () => {
|
||||||
|
const db = request.result
|
||||||
|
// 如果 store 不存在(版本没升级的情况),关闭后升版本重建
|
||||||
|
if (!db.objectStoreNames.contains(storeName)) {
|
||||||
|
db.close()
|
||||||
|
const version = db.version + 1
|
||||||
|
const req2 = indexedDB.open(DB_NAME, version)
|
||||||
|
req2.onupgradeneeded = () => {
|
||||||
|
const db2 = req2.result
|
||||||
|
if (!db2.objectStoreNames.contains(storeName)) {
|
||||||
|
const store = db2.createObjectStore(storeName, { keyPath: 'name' })
|
||||||
|
store.createIndex('name', 'name', { unique: true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
req2.onsuccess = () => resolve(req2.result)
|
||||||
|
req2.onerror = () => reject(req2.error)
|
||||||
|
} else {
|
||||||
|
resolve(db)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
request.onerror = () => reject(request.error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 写入或更新一条记录到 IndexedDB */
|
||||||
|
async function dbPut(storeName: string, record: DBRecord): Promise<void> {
|
||||||
|
const db = await openDB(storeName)
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const tx = db.transaction(storeName, 'readwrite')
|
||||||
|
const store = tx.objectStore(storeName)
|
||||||
|
store.put(record)
|
||||||
|
tx.oncomplete = () => { db.close(); resolve() }
|
||||||
|
tx.onerror = () => { db.close(); reject(tx.error) }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 从 IndexedDB 读取一条记录 */
|
||||||
|
async function dbGet(storeName: string, name: string): Promise<DBRecord | null> {
|
||||||
|
const db = await openDB(storeName)
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const tx = db.transaction(storeName, 'readonly')
|
||||||
|
const store = tx.objectStore(storeName)
|
||||||
|
const req = store.get(name)
|
||||||
|
req.onsuccess = () => { db.close(); resolve(req.result || null) }
|
||||||
|
req.onerror = () => { db.close(); reject(req.error) }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============ 核心:创建通信桥接实例 ============
|
||||||
|
|
||||||
|
export function createChannelBridge(options: ChannelBridgeOptions) {
|
||||||
|
const { domain, isPlugin = false } = options
|
||||||
|
|
||||||
|
/** BroadcastChannel 实例缓存(按 domain 隔离频道) */
|
||||||
|
const channels = new Map<string, BroadcastChannel>()
|
||||||
|
|
||||||
|
/** watch 订阅回调注册表:key = `${domain}::${name}` */
|
||||||
|
const watchers = new Map<string, Set<WatchCallback<any>>>()
|
||||||
|
|
||||||
|
/** emit 节流定时器:key = `${domain}::${name}` */
|
||||||
|
const emitTimers = new Map<string, ReturnType<typeof setTimeout>>()
|
||||||
|
|
||||||
|
/** emit 节流暂存最新数据:key = `${domain}::${name}` */
|
||||||
|
const emitPending = new Map<string, DBRecord>()
|
||||||
|
|
||||||
|
/** get 请求等待队列:key = requestId */
|
||||||
|
const getResolvers = new Map<string, (data: BridgeData<any> | null) => void>()
|
||||||
|
|
||||||
|
// --- Web Lock 保活(非插件环境) ---
|
||||||
|
if (!isPlugin && typeof navigator !== 'undefined' && navigator.locks) {
|
||||||
|
navigator.locks.request('offerpie-keep-alive', () => new Promise(() => {}))
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取或创建指定 domain 的 BroadcastChannel */
|
||||||
|
function getChannel(channelDomain: string): BroadcastChannel {
|
||||||
|
if (channels.has(channelDomain)) return channels.get(channelDomain)!
|
||||||
|
const ch = new BroadcastChannel(`offerpie-bridge-${channelDomain}`)
|
||||||
|
ch.onmessage = (event: MessageEvent<ChannelMessage>) => handleMessage(channelDomain, event.data)
|
||||||
|
channels.set(channelDomain, ch)
|
||||||
|
return ch
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 处理收到的 BroadcastChannel 消息 */
|
||||||
|
async function handleMessage(channelDomain: string, msg: ChannelMessage) {
|
||||||
|
const watchKey = `${channelDomain}::${msg.name}`
|
||||||
|
|
||||||
|
if (msg.type === 'put' || msg.type === 'emit') {
|
||||||
|
// 收到对方的数据推送,触发本地 watch 回调
|
||||||
|
const wrapped = msg.data && msg.createTime && msg.updateTime
|
||||||
|
? { ...msg.data, createTime: msg.createTime, updateTime: msg.updateTime } as BridgeData<any>
|
||||||
|
: null
|
||||||
|
const callbacks = watchers.get(watchKey)
|
||||||
|
if (callbacks) {
|
||||||
|
callbacks.forEach(cb => cb(wrapped))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.type === 'get-request' && msg.id) {
|
||||||
|
// 收到对方的 get 请求,从本地 IndexedDB 读取数据并回复
|
||||||
|
const record = await dbGet(channelDomain, msg.name)
|
||||||
|
const ch = getChannel(channelDomain)
|
||||||
|
const response: ChannelMessage = {
|
||||||
|
type: 'get-response',
|
||||||
|
name: msg.name,
|
||||||
|
id: msg.id,
|
||||||
|
data: record?.data,
|
||||||
|
createTime: record?.createTime,
|
||||||
|
updateTime: record?.updateTime,
|
||||||
|
}
|
||||||
|
ch.postMessage(response)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.type === 'get-response' && msg.id) {
|
||||||
|
// 收到对方对 get 请求的回复
|
||||||
|
const resolver = getResolvers.get(msg.id)
|
||||||
|
if (resolver) {
|
||||||
|
getResolvers.delete(msg.id)
|
||||||
|
if (msg.data && msg.createTime && msg.updateTime) {
|
||||||
|
resolver({ ...msg.data, createTime: msg.createTime, updateTime: msg.updateTime } as BridgeData<any>)
|
||||||
|
} else {
|
||||||
|
resolver(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化默认频道监听
|
||||||
|
getChannel(domain)
|
||||||
|
|
||||||
|
// --- 公开方法 ---
|
||||||
|
|
||||||
|
/**
|
||||||
|
* put - 单次发送数据(写入 IndexedDB + BroadcastChannel 广播)
|
||||||
|
* @param targetDomain 目标域名频道
|
||||||
|
* @param name 数据名称
|
||||||
|
* @param data 数据本体(需有 TS 类型定义)
|
||||||
|
*/
|
||||||
|
async function put<T extends object>(targetDomain: string, name: string, data: T): Promise<void> {
|
||||||
|
const now = nowLocalDateTime()
|
||||||
|
// 读取已有记录判断是否为新建
|
||||||
|
const existing = await dbGet(targetDomain, name)
|
||||||
|
const createTime = existing?.createTime || now
|
||||||
|
const updateTime = now
|
||||||
|
|
||||||
|
const record: DBRecord = { name, data, createTime, updateTime }
|
||||||
|
// 写入 IndexedDB
|
||||||
|
await dbPut(targetDomain, record)
|
||||||
|
// BroadcastChannel 广播
|
||||||
|
const ch = getChannel(targetDomain)
|
||||||
|
const msg: ChannelMessage = { type: 'put', name, data, createTime, updateTime }
|
||||||
|
ch.postMessage(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* emit - 高频发送数据(每次都广播,节流 500ms 写一次 IndexedDB)
|
||||||
|
* @param targetDomain 目标域名频道
|
||||||
|
* @param name 数据名称
|
||||||
|
* @param data 数据本体(需有 TS 类型定义)
|
||||||
|
*/
|
||||||
|
async function emit<T extends object>(targetDomain: string, name: string, data: T): Promise<void> {
|
||||||
|
const now = nowLocalDateTime()
|
||||||
|
const key = `${targetDomain}::${name}`
|
||||||
|
|
||||||
|
// 先尝试获取 createTime(从暂存或数据库)
|
||||||
|
let createTime: string
|
||||||
|
const pending = emitPending.get(key)
|
||||||
|
if (pending) {
|
||||||
|
createTime = pending.createTime
|
||||||
|
} else {
|
||||||
|
const existing = await dbGet(targetDomain, name)
|
||||||
|
createTime = existing?.createTime || now
|
||||||
|
}
|
||||||
|
const updateTime = now
|
||||||
|
const record: DBRecord = { name, data, createTime, updateTime }
|
||||||
|
|
||||||
|
// 暂存最新数据
|
||||||
|
emitPending.set(key, record)
|
||||||
|
|
||||||
|
// BroadcastChannel 每次都广播(保证 watch 实时性)
|
||||||
|
const ch = getChannel(targetDomain)
|
||||||
|
const msg: ChannelMessage = { type: 'emit', name, data, createTime, updateTime }
|
||||||
|
ch.postMessage(msg)
|
||||||
|
|
||||||
|
// 节流写库
|
||||||
|
if (!emitTimers.has(key)) {
|
||||||
|
emitTimers.set(key, setTimeout(async () => {
|
||||||
|
emitTimers.delete(key)
|
||||||
|
const latestRecord = emitPending.get(key)
|
||||||
|
if (latestRecord) {
|
||||||
|
emitPending.delete(key)
|
||||||
|
await dbPut(targetDomain, latestRecord)
|
||||||
|
}
|
||||||
|
}, EMIT_THROTTLE_MS))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get - 主动获取一次数据(先 BroadcastChannel 请求,60ms 超时转 IndexedDB)
|
||||||
|
* @param targetDomain 目标域名频道
|
||||||
|
* @param name 数据名称
|
||||||
|
* @returns 数据本体(含 createTime/updateTime),无数据返回 null
|
||||||
|
*/
|
||||||
|
async function get<T extends object>(targetDomain: string, name: string): Promise<BridgeData<T> | null> {
|
||||||
|
const ch = getChannel(targetDomain)
|
||||||
|
const requestId = uid()
|
||||||
|
|
||||||
|
// 发起广播请求
|
||||||
|
const msg: ChannelMessage = { type: 'get-request', name, id: requestId }
|
||||||
|
ch.postMessage(msg)
|
||||||
|
|
||||||
|
// 等待响应或超时
|
||||||
|
const result = await new Promise<BridgeData<T> | null>((resolve) => {
|
||||||
|
getResolvers.set(requestId, resolve as any)
|
||||||
|
setTimeout(() => {
|
||||||
|
if (getResolvers.has(requestId)) {
|
||||||
|
getResolvers.delete(requestId)
|
||||||
|
resolve(null) // 超时,标记为未收到响应
|
||||||
|
}
|
||||||
|
}, GET_TIMEOUT_MS)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 如果广播拿到了数据直接返回
|
||||||
|
if (result) return result
|
||||||
|
|
||||||
|
// 超时降级读 IndexedDB
|
||||||
|
const record = await dbGet(targetDomain, name)
|
||||||
|
if (record) {
|
||||||
|
return { ...record.data, createTime: record.createTime, updateTime: record.updateTime } as BridgeData<T>
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* watch - 持续监听数据变化(初始读一次缓存,后续实时接收 put/emit 推送)
|
||||||
|
* @param targetDomain 目标域名频道
|
||||||
|
* @param name 数据名称
|
||||||
|
* @param callback 数据变化回调,参数为最新数据或 null
|
||||||
|
* @returns 取消监听的函数
|
||||||
|
*/
|
||||||
|
function watch<T extends object>(targetDomain: string, name: string, callback: WatchCallback<T>): () => void {
|
||||||
|
const key = `${targetDomain}::${name}`
|
||||||
|
// 确保频道已初始化
|
||||||
|
getChannel(targetDomain)
|
||||||
|
|
||||||
|
// 注册回调
|
||||||
|
if (!watchers.has(key)) watchers.set(key, new Set())
|
||||||
|
watchers.get(key)!.add(callback)
|
||||||
|
|
||||||
|
// 初始读取 IndexedDB
|
||||||
|
dbGet(targetDomain, name).then((record) => {
|
||||||
|
if (record) {
|
||||||
|
callback({ ...record.data, createTime: record.createTime, updateTime: record.updateTime } as BridgeData<T>)
|
||||||
|
} else {
|
||||||
|
callback(null)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 返回取消监听函数
|
||||||
|
return () => {
|
||||||
|
const set = watchers.get(key)
|
||||||
|
if (set) {
|
||||||
|
set.delete(callback)
|
||||||
|
if (set.size === 0) watchers.delete(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* destroy - 销毁实例,关闭所有频道,清除定时器
|
||||||
|
*/
|
||||||
|
function destroy(): void {
|
||||||
|
channels.forEach(ch => ch.close())
|
||||||
|
channels.clear()
|
||||||
|
watchers.clear()
|
||||||
|
emitTimers.forEach(timer => clearTimeout(timer))
|
||||||
|
emitTimers.clear()
|
||||||
|
emitPending.clear()
|
||||||
|
getResolvers.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
return { put, emit, get, watch, destroy }
|
||||||
|
}
|
||||||
@@ -7,18 +7,19 @@
|
|||||||
<!-- 主内容区域 -->
|
<!-- 主内容区域 -->
|
||||||
<div class="agent-page__content" v-loading="pageLoading" element-loading-text="加载中...">
|
<div class="agent-page__content" v-loading="pageLoading" element-loading-text="加载中...">
|
||||||
<!-- 准备向导 — 第1步到第4步-->
|
<!-- 准备向导 — 第1步到第4步-->
|
||||||
<AgentSetupWizard
|
<!-- <AgentSetupWizard
|
||||||
v-if="!pageLoading && showSetupWizard"
|
v-if="!pageLoading && showSetupWizard"
|
||||||
:initial-config="agentConfig"
|
:initial-config="agentConfig"
|
||||||
@complete="handleSetupComplete"
|
@complete="handleSetupComplete"
|
||||||
@launch="handleLaunch"
|
@launch="handleLaunch"
|
||||||
|
/> -->
|
||||||
|
<AgentSetupWizard
|
||||||
|
v-if="true"
|
||||||
|
:initial-config="agentConfig"
|
||||||
|
@complete="handleSetupComplete"
|
||||||
|
@launch="handleLaunch"
|
||||||
/>
|
/>
|
||||||
<!-- <AgentSetupWizard-->
|
|
||||||
<!-- v-if="true"-->
|
|
||||||
<!-- :initial-config="agentConfig"-->
|
|
||||||
<!-- @complete="handleSetupComplete"-->
|
|
||||||
<!-- @launch="handleLaunch"-->
|
|
||||||
<!-- />-->
|
|
||||||
|
|
||||||
<!-- 求职助手正式内容区域 -->
|
<!-- 求职助手正式内容区域 -->
|
||||||
<div v-else-if="!pageLoading" class="agent-main">
|
<div v-else-if="!pageLoading" class="agent-main">
|
||||||
|
|||||||
@@ -175,7 +175,7 @@
|
|||||||
{{ job.regionName }}
|
{{ job.regionName }}
|
||||||
</span>
|
</span>
|
||||||
<span v-if="formatEducation(job.education)" class="jobs-page__meta-edu">{{ formatEducation(job.education) }}</span>
|
<span v-if="formatEducation(job.education)" class="jobs-page__meta-edu">{{ formatEducation(job.education) }}</span>
|
||||||
<span v-if="formatEmploymentType(job.recruitCategory)" class="jobs-page__meta-recruit">{{ formatEmploymentType(job.recruitCategory) }}</span>
|
<span v-if="formatEmploymentType(job.recruitCategory)" class="jobs-page__meta-recruit" :style="{ background: recruitCategoryColor(job.recruitCategory) }">{{ formatEmploymentType(job.recruitCategory) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -404,6 +404,14 @@ const router = useRouter()
|
|||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
|
|
||||||
|
/** 招聘分类标签背景色:校招=#3AC6E5,社招=#B95DDD,实习=#50D3B5 */
|
||||||
|
function recruitCategoryColor(category: number | undefined | null): string {
|
||||||
|
if (category === 1) return '#3AC6E5' // 校招
|
||||||
|
if (category === 0) return '#B95DDD' // 社招
|
||||||
|
if (category === 2) return '#50D3B5' // 实习
|
||||||
|
return '#EDF9FA'
|
||||||
|
}
|
||||||
|
|
||||||
/** 登录状态 — 从 store 读取 */
|
/** 登录状态 — 从 store 读取 */
|
||||||
const isAuthenticated = computed(() => store.state.isAuthenticated)
|
const isAuthenticated = computed(() => store.state.isAuthenticated)
|
||||||
|
|
||||||
|
|||||||