Merge branch 'main' of http://124.243.245.42:3000/sdz/ks-app-employment-service into dev
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,10 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<!-- 自定义tabbar -->
|
||||
<CustomTabBar :currentPage="2" />
|
||||
|
||||
<!-- 微信授权登录弹窗 -->
|
||||
<WxAuthLogin ref="wxAuthLoginRef" @success="handleLoginSuccess"></WxAuthLogin>
|
||||
<!-- 抽屉遮罩层 -->
|
||||
<view v-if="isDrawerOpen" class="overlay" @click="toggleDrawer"></view>
|
||||
|
||||
@@ -71,13 +76,15 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, inject, nextTick, computed } from 'vue';
|
||||
import { ref, inject, nextTick, computed, onMounted, onUnmounted } from 'vue';
|
||||
const { $api, navTo, insertSortData, config } = inject('globalFunction');
|
||||
import { onLoad, onShow, onHide } from '@dcloudio/uni-app';
|
||||
import useChatGroupDBStore from '@/stores/userChatGroupStore';
|
||||
import useUserStore from '@/stores/useUserStore';
|
||||
import { tabbarManager } from '@/utils/tabbarManager';
|
||||
import aiPaging from './components/ai-paging.vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import WxAuthLogin from '@/components/WxAuthLogin/WxAuthLogin.vue';
|
||||
const { isTyping, tabeList, chatSessionID } = storeToRefs(useChatGroupDBStore());
|
||||
const { userInfo } = storeToRefs(useUserStore());
|
||||
const isDrawerOpen = ref(false);
|
||||
@@ -85,6 +92,7 @@ const scrollIntoView = ref(false);
|
||||
|
||||
const searchText = ref('');
|
||||
const paging = ref(null);
|
||||
const wxAuthLoginRef = ref(null);
|
||||
|
||||
// 实时过滤
|
||||
const filteredList = computed(() => {
|
||||
@@ -103,8 +111,27 @@ onShow(() => {
|
||||
nextTick(() => {
|
||||
paging.value?.closeFile();
|
||||
});
|
||||
// 更新自定义tabbar选中状态
|
||||
tabbarManager.updateSelected(2);
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
// 监听退出登录事件,显示微信登录弹窗
|
||||
uni.$on('showLoginModal', () => {
|
||||
wxAuthLoginRef.value?.open();
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
uni.$off('showLoginModal');
|
||||
});
|
||||
|
||||
// 登录成功回调
|
||||
const handleLoginSuccess = () => {
|
||||
console.log('登录成功');
|
||||
// 可以在这里添加登录成功后的处理逻辑
|
||||
};
|
||||
|
||||
onHide(() => {
|
||||
paging.value?.handleTouchCancel();
|
||||
if (isDrawerOpen.value) {
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
<template>
|
||||
<view class="chat-container">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view class="chat-background">
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-WEIXIN -->
|
||||
<view class="chat-background" v-fade:600="!messages.length">
|
||||
<!-- #endif -->
|
||||
<view class="chat-background" v-if="!messages.length">
|
||||
<image class="backlogo" src="/static/icon/backAI.png"></image>
|
||||
<view class="back-rowTitle">嗨!欢迎使用{{ config.appInfo.areaName }}AI智能求职</view>
|
||||
<view class="back-rowText">
|
||||
@@ -24,6 +20,28 @@
|
||||
<view class="message">{{ recognizedText }} {{ lastFinalText }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-WEIXIN -->
|
||||
<view class="chat-background" v-if="!messages.length">
|
||||
<image class="backlogo" src="/static/icon/backAI.png"></image>
|
||||
<view class="back-rowTitle">嗨!欢迎使用{{ config.appInfo.areaName }}AI智能求职</view>
|
||||
<view class="back-rowText">
|
||||
我可以根据您的简历和求职需求,帮你精准匹配{{ config.appInfo.areaName }}互联网招聘信息,对比招聘信息的优缺点,提供面试指导等,请把你的任务交给我吧~
|
||||
</view>
|
||||
<view class="back-rowh3">猜你所想</view>
|
||||
<view
|
||||
class="back-rowmsg button-click"
|
||||
v-for="(item, index) in queries"
|
||||
:key="index"
|
||||
@click="sendMessageGuess(item)"
|
||||
>
|
||||
{{ item }}
|
||||
</view>
|
||||
<view class="chat-item self" v-if="isRecording">
|
||||
<view class="message">{{ recognizedText }} {{ lastFinalText }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<scroll-view class="chat-list scrollView" :scroll-top="scrollTop" :scroll-y="true" scroll-with-animation>
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view class="chat-list list-content">
|
||||
@@ -946,19 +964,19 @@ image-margin-top = 40rpx
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.list-content {
|
||||
padding: 0 44rpx 44rpx 44rpx;
|
||||
padding: 0 44rpx 10rpx 44rpx;
|
||||
}
|
||||
.chat-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 20rpx;
|
||||
margin-bottom: 10rpx;
|
||||
width: 100%;
|
||||
}
|
||||
.chat-item.self {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.message
|
||||
margin-top: 40rpx
|
||||
margin-top: 0rpx
|
||||
// max-width: 80%;
|
||||
width: 100%;
|
||||
word-break: break-word;
|
||||
@@ -1003,10 +1021,12 @@ image-margin-top = 40rpx
|
||||
}
|
||||
.input-area {
|
||||
padding: 32rpx 28rpx 24rpx 28rpx;
|
||||
padding-bottom: calc(24rpx + env(safe-area-inset-bottom) + 40rpx - 40rpx);
|
||||
position: relative;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0rpx -4rpx 10rpx 0rpx rgba(11,44,112,0.06);
|
||||
transition: height 2s ease-in-out;
|
||||
z-index: 1001;
|
||||
}
|
||||
.input-area::after
|
||||
position: absolute
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<AppLayout title="企业信息">
|
||||
<AppLayout>
|
||||
<view class="company-info-container">
|
||||
<!-- 头部信息 -->
|
||||
<view class="header-info">
|
||||
@@ -79,7 +79,7 @@
|
||||
<view class="label">是否是就业见习基地</view>
|
||||
<view class="input-content">
|
||||
<text class="input-text" :class="{ placeholder: formData.enterpriseType === null }">
|
||||
{{ formData.enterpriseType === null ? '请选择' : (formData.enterpriseType ? '是' : '否') }}
|
||||
{{ formData.enterpriseType === null ? '请选择' : (formData.enterpriseType === 0 ? '是' : '否') }}
|
||||
</text>
|
||||
<uni-icons type="arrowright" size="16" color="#999"></uni-icons>
|
||||
</view>
|
||||
@@ -131,6 +131,15 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 企业规模 -->
|
||||
<view class="form-item clickable" @click="selectScale">
|
||||
<view class="label">企业规模</view>
|
||||
<view class="input-content">
|
||||
<input class="input-con" v-model="formData.scaleText" disabled placeholder="请选择企业规模" />
|
||||
<uni-icons type="arrowright" size="16" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 联系人信息列表 -->
|
||||
<view class="contact-section">
|
||||
<view class="section-title">联系人信息</view>
|
||||
@@ -225,9 +234,11 @@ import { onLoad } from '@dcloudio/uni-app'
|
||||
import AreaCascadePicker from '@/components/area-cascade-picker/area-cascade-picker.vue'
|
||||
import SelectPopup from '@/components/selectPopup/selectPopup.vue'
|
||||
import useDictStore from '@/stores/useDictStore'
|
||||
import useUserStore from '@/stores/useUserStore'
|
||||
|
||||
const { $api } = inject('globalFunction')
|
||||
const dictStore = useDictStore()
|
||||
const userStore = useUserStore()
|
||||
|
||||
// 表单数据
|
||||
const formData = reactive({
|
||||
@@ -241,11 +252,13 @@ const formData = reactive({
|
||||
legalPersonName: '',
|
||||
nature: '', // 企业类型
|
||||
natureText: '', // 企业类型显示文本
|
||||
enterpriseType: null, // 是否是就业见习基地 (true/false/null)
|
||||
enterpriseType: null, // 是否是就业见习基地 (0=是, 1=否, null=未选择)
|
||||
legalIdCard: '', // 法人身份证号
|
||||
legalPhone: '', // 法人联系方式
|
||||
industryType: '', // 是否是本地重点发展产业
|
||||
isLocalCompany: null, // 是否是本地企业 (true/false/null)
|
||||
scale: '', // 企业规模
|
||||
scaleText: '', // 企业规模显示文本
|
||||
companyContactList: [
|
||||
{ contactPerson: '', contactPersonPhone: '' }
|
||||
]
|
||||
@@ -311,7 +324,8 @@ const completionPercentage = computed(() => {
|
||||
formData.legalIdCard,
|
||||
formData.legalPhone,
|
||||
formData.industryType,
|
||||
formData.isLocalCompany !== null ? 'filled' : ''
|
||||
formData.isLocalCompany !== null ? 'filled' : '',
|
||||
formData.scale
|
||||
]
|
||||
|
||||
// 检查联系人信息
|
||||
@@ -445,7 +459,7 @@ const selectEmploymentBase = () => {
|
||||
uni.showActionSheet({
|
||||
itemList: ['是', '否'],
|
||||
success: (res) => {
|
||||
formData.enterpriseType = res.tapIndex === 0
|
||||
formData.enterpriseType = res.tapIndex === 0 ? 0 : 1
|
||||
updateCompletion()
|
||||
$api.msg('选择成功')
|
||||
}
|
||||
@@ -464,6 +478,73 @@ const selectLocalCompany = () => {
|
||||
})
|
||||
}
|
||||
|
||||
// 企业规模选项数据从字典中获取
|
||||
const scaleOptions = computed(() => {
|
||||
const scaleData = dictStore.state?.scale || []
|
||||
console.log('企业规模选项数据:', scaleData)
|
||||
return scaleData
|
||||
})
|
||||
|
||||
// 选择企业规模
|
||||
const selectScale = () => {
|
||||
console.log('点击企业规模,当前数据:', scaleOptions.value)
|
||||
console.log('字典store状态:', dictStore.state.scale)
|
||||
|
||||
// 获取企业规模选项,优先使用字典数据,失败时使用备用数据
|
||||
let options = scaleOptions.value
|
||||
|
||||
if (!options || !options.length) {
|
||||
console.log('企业规模数据为空,尝试重新加载')
|
||||
// 尝试重新加载字典数据
|
||||
dictStore.getDictData().then(() => {
|
||||
if (dictStore.state.scale && dictStore.state.scale.length > 0) {
|
||||
selectScale() // 递归调用
|
||||
} else {
|
||||
// 使用备用数据
|
||||
console.log('使用备用企业规模数据')
|
||||
options = fallbackScaleOptions
|
||||
showScaleSelector(options)
|
||||
}
|
||||
}).catch(() => {
|
||||
// 使用备用数据
|
||||
console.log('字典加载失败,使用备用企业规模数据')
|
||||
options = fallbackScaleOptions
|
||||
showScaleSelector(options)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
showScaleSelector(options)
|
||||
}
|
||||
|
||||
// 备用企业规模选项(当字典数据加载失败时使用)
|
||||
const fallbackScaleOptions = [
|
||||
{ label: '1-10人', value: '1' },
|
||||
{ label: '11-50人', value: '2' },
|
||||
{ label: '51-100人', value: '3' },
|
||||
{ label: '101-500人', value: '4' },
|
||||
{ label: '501-1000人', value: '5' },
|
||||
{ label: '1000人以上', value: '6' }
|
||||
]
|
||||
|
||||
// 显示企业规模选择器
|
||||
const showScaleSelector = (options) => {
|
||||
console.log('企业规模选项列表:', options)
|
||||
|
||||
openSelectPopup({
|
||||
title: '企业规模',
|
||||
maskClick: true,
|
||||
data: [options],
|
||||
success: (_, [value]) => {
|
||||
console.log('选择的企业规模:', value)
|
||||
formData.scale = value.value
|
||||
formData.scaleText = value.label
|
||||
updateCompletion()
|
||||
$api.msg('企业规模选择成功')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 添加联系人
|
||||
const addContact = () => {
|
||||
@@ -573,6 +654,11 @@ const confirm = () => {
|
||||
return
|
||||
}
|
||||
|
||||
if (!formData.scale.trim()) {
|
||||
$api.msg('请选择企业规模')
|
||||
return
|
||||
}
|
||||
|
||||
// 验证身份证号格式
|
||||
const idCardRegex = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
|
||||
if (!idCardRegex.test(formData.legalIdCard)) {
|
||||
@@ -623,6 +709,7 @@ const confirm = () => {
|
||||
legalPhone: formData.legalPhone,
|
||||
industryType: formData.industryType,
|
||||
isLocalCompany: formData.isLocalCompany,
|
||||
scale: formData.scaleText,
|
||||
companyContactList: formData.companyContactList.filter(contact => contact.contactPerson.trim() && contact.contactPersonPhone.trim())
|
||||
}
|
||||
|
||||
@@ -631,11 +718,30 @@ const confirm = () => {
|
||||
company: companyData
|
||||
}
|
||||
|
||||
$api.createRequest('/app/user/registerUser', submitData, 'post')
|
||||
.then((resData) => {
|
||||
$api.createRequest('/registerUser', submitData, 'post')
|
||||
.then(async (resData) => {
|
||||
uni.hideLoading()
|
||||
$api.msg('企业信息保存成功')
|
||||
|
||||
// 如果接口返回了token,需要重新保存token
|
||||
if (resData.token) {
|
||||
try {
|
||||
await userStore.loginSetToken(resData.token)
|
||||
console.log('Token已更新:', resData.token)
|
||||
} catch (error) {
|
||||
console.error('更新Token失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 保存成功后,重新获取用户信息并更新缓存
|
||||
try {
|
||||
await userStore.getUserResume()
|
||||
console.log('用户信息已更新到缓存')
|
||||
} catch (error) {
|
||||
console.error('获取用户信息失败:', error)
|
||||
// 即使获取用户信息失败,也不影响页面跳转
|
||||
}
|
||||
|
||||
// 跳转到首页或企业相关页面
|
||||
uni.reLaunch({
|
||||
url: '/pages/index/index'
|
||||
@@ -720,10 +826,12 @@ defineExpose({
|
||||
font-size: 28rpx
|
||||
color: #333
|
||||
text-align: right
|
||||
line-height: 1.4
|
||||
|
||||
&::placeholder
|
||||
color: #999
|
||||
font-size: 26rpx
|
||||
font-size: 28rpx
|
||||
line-height: 1.4
|
||||
|
||||
.input-con
|
||||
flex: 1
|
||||
@@ -733,10 +841,12 @@ defineExpose({
|
||||
background: transparent
|
||||
border: none
|
||||
outline: none
|
||||
line-height: 1.4
|
||||
|
||||
&::placeholder
|
||||
color: #999
|
||||
font-size: 26rpx
|
||||
font-size: 28rpx
|
||||
line-height: 1.4
|
||||
|
||||
.input-content
|
||||
flex: 1
|
||||
@@ -752,7 +862,8 @@ defineExpose({
|
||||
|
||||
&.placeholder
|
||||
color: #999
|
||||
font-size: 26rpx
|
||||
font-size: 28rpx
|
||||
line-height: 1.4
|
||||
|
||||
&.intro-text
|
||||
max-height: 80rpx
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<view class="wxaddress">{{ config.appInfo.areaName }}公共就业和人才服务中心</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
<swiper-item @touchmove.stop="false">
|
||||
<swiper-item @touchmove.stop="false">
|
||||
<view class="content-one">
|
||||
<view>
|
||||
<view class="content-title">
|
||||
@@ -33,17 +33,19 @@
|
||||
<text>/2</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-input" @click="changeExperience">
|
||||
<view class="input-titile">工作经验</view>
|
||||
<input
|
||||
class="input-con"
|
||||
v-model="state.experienceText"
|
||||
disabled
|
||||
placeholder="请选择您的工作经验"
|
||||
<view class="content-input" :class="{ 'input-error': nameError }">
|
||||
<view class="input-titile">姓名</view>
|
||||
<input
|
||||
class="input-con2"
|
||||
v-model="fromValue.name"
|
||||
maxlength="18"
|
||||
placeholder="请输入姓名"
|
||||
@input="validateName"
|
||||
/>
|
||||
<view v-if="nameError" class="error-message">{{ nameError }}</view>
|
||||
</view>
|
||||
<view class="content-sex">
|
||||
<view class="sex-titile">求职区域</view>
|
||||
<view class="content-sex" :class="{ 'input-error': sexError }">
|
||||
<view class="sex-titile">性别</view>
|
||||
<view class="sext-ri">
|
||||
<view
|
||||
class="sext-box"
|
||||
@@ -61,6 +63,28 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="sexError" class="error-message">{{ sexError }}</view>
|
||||
<view class="content-input" :class="{ 'input-error': ageError }">
|
||||
<view class="input-titile">年龄</view>
|
||||
<input
|
||||
class="input-con2"
|
||||
v-model="fromValue.age"
|
||||
maxlength="3"
|
||||
placeholder="请输入年龄"
|
||||
@input="validateAge"
|
||||
/>
|
||||
<view v-if="ageError" class="error-message">{{ ageError }}</view>
|
||||
</view>
|
||||
<view class="content-input" :class="{ 'input-error': experienceError }" @click="changeExperience">
|
||||
<view class="input-titile">工作经验</view>
|
||||
<input
|
||||
class="input-con"
|
||||
v-model="state.workExperience"
|
||||
disabled
|
||||
placeholder="请选择您的工作经验"
|
||||
/>
|
||||
<view v-if="experienceError" class="error-message">{{ experienceError }}</view>
|
||||
</view>
|
||||
<view class="content-input" @click="changeEducation">
|
||||
<view class="input-titile">学历</view>
|
||||
<input class="input-con" v-model="state.educationText" disabled placeholder="本科" />
|
||||
@@ -69,19 +93,19 @@
|
||||
<view class="input-titile">身份证</view>
|
||||
<input
|
||||
class="input-con2"
|
||||
v-model="fromValue.idcard"
|
||||
v-model="fromValue.idCard"
|
||||
maxlength="18"
|
||||
placeholder="请输入身份证号码"
|
||||
@input="validateIdCard"
|
||||
/>
|
||||
<view v-if="idCardError" class="error-message">{{ idCardError }}</view>
|
||||
<view v-if="fromValue.idcard && !idCardError" class="success-message">✓ 身份证格式正确</view>
|
||||
<view v-if="fromValue.idCard && !idCardError" class="success-message">✓ 身份证格式正确</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="next-btn" @tap="nextStep">下一步</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
<swiper-item @touchmove.stop="false">
|
||||
<view class="next-btn" @tap="nextStep">下一步</view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
<swiper-item @touchmove.stop="false">
|
||||
<view class="content-one">
|
||||
<view>
|
||||
<view class="content-title">
|
||||
@@ -115,6 +139,27 @@
|
||||
<view class="nx-item" v-for="item in state.jobsText">{{ item }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-input" @click="changeSkillLevel">
|
||||
<view class="input-titile">技能等级</view>
|
||||
<input
|
||||
class="input-con"
|
||||
v-model="state.skillLevelText"
|
||||
disabled
|
||||
placeholder="请选择您的技能等级"
|
||||
/>
|
||||
</view>
|
||||
<view class="content-input" @click="changeSkills">
|
||||
<view class="input-titile">技能名称</view>
|
||||
<input
|
||||
class="input-con"
|
||||
disabled
|
||||
v-if="!state.skillsText.length"
|
||||
placeholder="请选择您的技能名称"
|
||||
/>
|
||||
<view class="input-nx" @click="changeSkills" v-else>
|
||||
<view class="nx-item" v-for="(item, index) in state.skillsText" :key="index">{{ item }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-input" @click="changeSalay">
|
||||
<view class="input-titile">期望薪资</view>
|
||||
<input
|
||||
@@ -178,23 +223,33 @@ const state = reactive({
|
||||
risalay: JSON.parse(JSON.stringify(salay)),
|
||||
areaText: '',
|
||||
educationText: '',
|
||||
experienceText: '',
|
||||
workExperience: '',
|
||||
salayText: '',
|
||||
jobsText: [],
|
||||
skillLevelText: '',
|
||||
skillsText: [],
|
||||
});
|
||||
const fromValue = reactive({
|
||||
sex: 1,
|
||||
sex: null,
|
||||
education: '4',
|
||||
salaryMin: 2000,
|
||||
salaryMax: 2000,
|
||||
area: 0,
|
||||
jobTitleId: '',
|
||||
experience: '1',
|
||||
idcard: '',
|
||||
workExperience: '1',
|
||||
idCard: '',
|
||||
name: '',
|
||||
age: '',
|
||||
skillLevel: '',
|
||||
skills: '',
|
||||
});
|
||||
|
||||
// 身份证校验相关
|
||||
// 输入校验相关
|
||||
const idCardError = ref('');
|
||||
const nameError = ref('');
|
||||
const ageError = ref('');
|
||||
const sexError = ref('');
|
||||
const experienceError = ref('');
|
||||
|
||||
onLoad((parmas) => {
|
||||
getTreeselect();
|
||||
@@ -204,11 +259,40 @@ onMounted(() => {});
|
||||
|
||||
function changeSex(sex) {
|
||||
fromValue.sex = sex;
|
||||
// 选择后清除性别错误
|
||||
sexError.value = '';
|
||||
}
|
||||
|
||||
// 姓名实时校验(中文2-18或英文2-30)
|
||||
function validateName() {
|
||||
const name = (fromValue.name || '').trim();
|
||||
if (!name) {
|
||||
nameError.value = '请输入姓名';
|
||||
return;
|
||||
}
|
||||
const cn = /^[\u4e00-\u9fa5·]{2,18}$/;
|
||||
const en = /^[A-Za-z\s]{2,30}$/;
|
||||
nameError.value = cn.test(name) || en.test(name) ? '' : '姓名格式不正确';
|
||||
}
|
||||
|
||||
// 年龄实时校验(16-65的整数)
|
||||
function validateAge() {
|
||||
const ageStr = String(fromValue.age || '').trim();
|
||||
if (!ageStr) {
|
||||
ageError.value = '请输入年龄';
|
||||
return;
|
||||
}
|
||||
const num = Number(ageStr);
|
||||
if (!/^\d{1,3}$/.test(ageStr) || Number.isNaN(num)) {
|
||||
ageError.value = '年龄必须为数字';
|
||||
return;
|
||||
}
|
||||
ageError.value = num >= 16 && num <= 65 ? '' : '年龄需在16-65之间';
|
||||
}
|
||||
|
||||
// 身份证实时校验
|
||||
function validateIdCard() {
|
||||
const idCard = fromValue.idcard.trim();
|
||||
const idCard = (fromValue.idCard || '').trim();
|
||||
|
||||
// 如果为空,清除错误信息
|
||||
if (!idCard) {
|
||||
@@ -231,8 +315,10 @@ function changeExperience() {
|
||||
maskClick: true,
|
||||
data: [oneDictData('experience')],
|
||||
success: (_, [value]) => {
|
||||
fromValue.experience = value.value;
|
||||
state.experienceText = value.label;
|
||||
fromValue.workExperience = value.value;
|
||||
state.workExperience = value.label;
|
||||
// 选择后清除工作经验错误
|
||||
experienceError.value = '';
|
||||
},
|
||||
change(_, [value]) {
|
||||
// this.setColunm(1, [123, 123]);
|
||||
@@ -300,20 +386,153 @@ function changeJobs() {
|
||||
});
|
||||
}
|
||||
|
||||
// 技能等级选择
|
||||
function changeSkillLevel() {
|
||||
const skillLevels = [
|
||||
{ label: '初级', value: '1' },
|
||||
{ label: '中级', value: '2' },
|
||||
{ label: '高级', value: '3' }
|
||||
];
|
||||
|
||||
openSelectPopup({
|
||||
title: '技能等级',
|
||||
maskClick: true,
|
||||
data: [skillLevels],
|
||||
success: (_, [value]) => {
|
||||
fromValue.skillLevel = value.value;
|
||||
state.skillLevelText = value.label;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// 技能名称选择
|
||||
function changeSkills() {
|
||||
const skills = [
|
||||
// 前端开发
|
||||
{ label: 'HTML', value: 'html' },
|
||||
{ label: 'CSS', value: 'css' },
|
||||
{ label: 'JavaScript', value: 'javascript' },
|
||||
{ label: 'TypeScript', value: 'typescript' },
|
||||
{ label: 'React', value: 'react' },
|
||||
{ label: 'Vue', value: 'vue' },
|
||||
{ label: 'Angular', value: 'angular' },
|
||||
{ label: 'jQuery', value: 'jquery' },
|
||||
{ label: 'Bootstrap', value: 'bootstrap' },
|
||||
{ label: 'Sass/Less', value: 'sass' },
|
||||
{ label: 'Webpack', value: 'webpack' },
|
||||
{ label: 'Vite', value: 'vite' },
|
||||
|
||||
// 后端开发
|
||||
{ label: 'Java', value: 'java' },
|
||||
{ label: 'Python', value: 'python' },
|
||||
{ label: 'Node.js', value: 'nodejs' },
|
||||
{ label: 'PHP', value: 'php' },
|
||||
{ label: 'C#', value: 'csharp' },
|
||||
{ label: 'Go', value: 'go' },
|
||||
{ label: 'Ruby', value: 'ruby' },
|
||||
{ label: 'Spring Boot', value: 'springboot' },
|
||||
{ label: 'Django', value: 'django' },
|
||||
{ label: 'Express', value: 'express' },
|
||||
{ label: 'Laravel', value: 'laravel' },
|
||||
|
||||
// 数据库
|
||||
{ label: 'MySQL', value: 'mysql' },
|
||||
{ label: 'PostgreSQL', value: 'postgresql' },
|
||||
{ label: 'MongoDB', value: 'mongodb' },
|
||||
{ label: 'Redis', value: 'redis' },
|
||||
{ label: 'Oracle', value: 'oracle' },
|
||||
{ label: 'SQL Server', value: 'sqlserver' },
|
||||
|
||||
// 移动开发
|
||||
{ label: 'React Native', value: 'reactnative' },
|
||||
{ label: 'Flutter', value: 'flutter' },
|
||||
{ label: 'iOS开发', value: 'ios' },
|
||||
{ label: 'Android开发', value: 'android' },
|
||||
{ label: '微信小程序', value: 'miniprogram' },
|
||||
{ label: 'uni-app', value: 'uniapp' },
|
||||
|
||||
// 云计算与运维
|
||||
{ label: 'Docker', value: 'docker' },
|
||||
{ label: 'Kubernetes', value: 'kubernetes' },
|
||||
{ label: 'AWS', value: 'aws' },
|
||||
{ label: '阿里云', value: 'aliyun' },
|
||||
{ label: 'Linux', value: 'linux' },
|
||||
{ label: 'Nginx', value: 'nginx' },
|
||||
|
||||
// 设计工具
|
||||
{ label: 'Photoshop', value: 'photoshop' },
|
||||
{ label: 'Figma', value: 'figma' },
|
||||
{ label: 'Sketch', value: 'sketch' },
|
||||
{ label: 'Adobe XD', value: 'adobexd' },
|
||||
|
||||
// 其他技能
|
||||
{ label: 'Git', value: 'git' },
|
||||
{ label: 'Jenkins', value: 'jenkins' },
|
||||
{ label: 'Jira', value: 'jira' },
|
||||
{ label: '项目管理', value: 'projectmanagement' },
|
||||
{ label: '数据分析', value: 'dataanalysis' },
|
||||
{ label: '人工智能', value: 'ai' },
|
||||
{ label: '机器学习', value: 'machinelearning' }
|
||||
];
|
||||
|
||||
// 获取当前已选中的技能
|
||||
const currentSelectedValues = fromValue.skills ? fromValue.skills.split(',') : [];
|
||||
|
||||
openSelectPopup({
|
||||
title: '技能名称',
|
||||
maskClick: true,
|
||||
data: [skills],
|
||||
multiSelect: true,
|
||||
rowLabel: 'label',
|
||||
rowKey: 'value',
|
||||
defaultValues: currentSelectedValues,
|
||||
success: (selectedValues, selectedItems) => {
|
||||
const selectedSkills = selectedItems.map(item => item.value);
|
||||
const selectedLabels = selectedItems.map(item => item.label);
|
||||
fromValue.skills = selectedSkills.join(',');
|
||||
state.skillsText = selectedLabels;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function nextStep() {
|
||||
// 校验身份证号码
|
||||
const idCard = fromValue.idcard.trim();
|
||||
if (!idCard) {
|
||||
$api.msg('请输入身份证号码');
|
||||
// 统一必填与格式校验
|
||||
validateName();
|
||||
validateAge();
|
||||
validateIdCard();
|
||||
|
||||
if (fromValue.sex !== 0 && fromValue.sex !== 1) {
|
||||
sexError.value = '请选择性别';
|
||||
}
|
||||
|
||||
// 工作经验校验
|
||||
if (!state.workExperience) {
|
||||
experienceError.value = '请选择您的工作经验';
|
||||
} else {
|
||||
experienceError.value = '';
|
||||
}
|
||||
|
||||
// 学历校验
|
||||
if (!state.educationText) {
|
||||
$api.msg('请选择您的学历');
|
||||
return;
|
||||
}
|
||||
|
||||
const result = IdCardValidator.validate(idCard);
|
||||
|
||||
// 检查所有错误状态
|
||||
if (nameError.value) return;
|
||||
if (sexError.value) return;
|
||||
if (ageError.value) return;
|
||||
if (experienceError.value) return;
|
||||
if (idCardError.value || !fromValue.idCard) {
|
||||
if (!fromValue.idCard) $api.msg('请输入身份证号码');
|
||||
return;
|
||||
}
|
||||
|
||||
const result = IdCardValidator.validate(fromValue.idCard);
|
||||
if (!result.valid) {
|
||||
$api.msg(result.message);
|
||||
return;
|
||||
}
|
||||
|
||||
tabCurrent.value += 1;
|
||||
}
|
||||
|
||||
@@ -359,16 +578,65 @@ function loginTest() {
|
||||
}
|
||||
|
||||
function complete() {
|
||||
const result = IdCardValidator.validate(fromValue.idcard);
|
||||
const result = IdCardValidator.validate(fromValue.idCard);
|
||||
if (result.valid) {
|
||||
$api.createRequest('/app/user/resume', fromValue, 'post').then((resData) => {
|
||||
// 构建 experiencesList 数组
|
||||
const experiencesList = [];
|
||||
if (fromValue.skills && fromValue.skillLevel) {
|
||||
const skillsArray = fromValue.skills.split(',');
|
||||
skillsArray.forEach(skill => {
|
||||
if (skill.trim()) {
|
||||
experiencesList.push({
|
||||
name: skill.trim(),
|
||||
levels: fromValue.skillLevel
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 构建符合要求的请求数据(experiencesList 与 appUser 同级)
|
||||
const requestData = {
|
||||
appUser: {
|
||||
name: fromValue.name,
|
||||
isCompanyUser: 1,
|
||||
age: fromValue.age,
|
||||
sex: fromValue.sex,
|
||||
workExperience: fromValue.workExperience,
|
||||
education: fromValue.education,
|
||||
idCard: fromValue.idCard,
|
||||
area: fromValue.area,
|
||||
jobTitleId: fromValue.jobTitleId,
|
||||
salaryMin: fromValue.salaryMin,
|
||||
salaryMax: fromValue.salaryMax
|
||||
},
|
||||
experiencesList: experiencesList
|
||||
};
|
||||
|
||||
$api.createRequest('/registerUser', requestData, 'post').then(async (resData) => {
|
||||
$api.msg('完成');
|
||||
// 获取用户信息并存储到store中
|
||||
getUserResume().then((userInfo) => {
|
||||
console.log('用户信息已存储到store:', userInfo);
|
||||
uni.reLaunch({
|
||||
url: '/pages/index/index',
|
||||
});
|
||||
|
||||
// 如果接口返回了token,需要重新保存token
|
||||
if (resData.token) {
|
||||
try {
|
||||
await loginSetToken(resData.token);
|
||||
console.log('Token已更新:', resData.token);
|
||||
} catch (error) {
|
||||
console.error('更新Token失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 保存成功后,重新获取用户信息并更新缓存
|
||||
try {
|
||||
await getUserResume();
|
||||
console.log('用户信息已更新到缓存');
|
||||
} catch (error) {
|
||||
console.error('获取用户信息失败:', error);
|
||||
// 即使获取用户信息失败,也不影响页面跳转
|
||||
}
|
||||
|
||||
// 跳转到首页
|
||||
uni.reLaunch({
|
||||
url: '/pages/index/index',
|
||||
});
|
||||
});
|
||||
} else {
|
||||
@@ -403,32 +671,22 @@ function complete() {
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
.nx-item
|
||||
padding: 20rpx 28rpx
|
||||
padding: 16rpx 24rpx
|
||||
width: fit-content
|
||||
border-radius: 12rpx 12rpx 12rpx 12rpx;
|
||||
border: 2rpx solid #E8EAEE;
|
||||
margin-right: 24rpx
|
||||
margin-top: 24rpx
|
||||
.nx-item::before
|
||||
position: absolute;
|
||||
right: 20rpx;
|
||||
top: 60rpx;
|
||||
content: '';
|
||||
width: 4rpx;
|
||||
height: 18rpx;
|
||||
border-radius: 2rpx
|
||||
background: #697279;
|
||||
transform: translate(0, -50%) rotate(-45deg) ;
|
||||
.nx-item::after
|
||||
position: absolute;
|
||||
right: 20rpx;
|
||||
top: 61rpx;
|
||||
content: '';
|
||||
width: 4rpx;
|
||||
height: 18rpx;
|
||||
border-radius: 2rpx
|
||||
background: #697279;
|
||||
transform: rotate(45deg)
|
||||
border-radius: 20rpx
|
||||
border: 2rpx solid #E8EAEE
|
||||
background-color: #f8f9fa
|
||||
margin-right: 16rpx
|
||||
margin-top: 16rpx
|
||||
font-size: 28rpx
|
||||
color: #333333
|
||||
transition: all 0.2s ease
|
||||
|
||||
&:hover
|
||||
background-color: #e9ecef
|
||||
border-color: #256bfa
|
||||
color: #256bfa
|
||||
// 移除技能标签的箭头样式,因为技能标签不需要箭头指示
|
||||
.container
|
||||
// background: linear-gradient(#4778EC, #002979);
|
||||
width: 100%;
|
||||
|
||||
@@ -5,18 +5,53 @@
|
||||
<image class="mp-background" src="/static/icon/background2.png" mode="aspectFill"></image>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- 企业账号显示卡片 -->
|
||||
<view class="enterprise-card btn-feel" v-if="shouldShowCompanyCard" @click="goToCompanyInfo">
|
||||
<view class="card-content">
|
||||
<!-- 企业图标 -->
|
||||
<view class="company-icon">
|
||||
<image
|
||||
v-if="companyInfo.avatar"
|
||||
:src="companyInfo.avatar"
|
||||
class="logo-image"
|
||||
mode="aspectFit"
|
||||
/>
|
||||
<view v-else class="default-logo">
|
||||
<uni-icons type="home-filled" size="32" color="#256BFA"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 企业信息 -->
|
||||
<view class="company-info">
|
||||
<view class="company-name">{{ companyInfo.name || '企业名称' }}</view>
|
||||
<view class="company-details">
|
||||
<text class="industry">{{ companyInfo.industry || '互联网' }}</text>
|
||||
<text class="separator">·</text>
|
||||
<text class="size">{{ companyInfo.scale || '100-999人' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view
|
||||
class="nav-hidden hidden-animation"
|
||||
:class="{ 'hidden-height': shouldHideTop }"
|
||||
>
|
||||
<view class="container-search">
|
||||
<view class="container-search" v-if="shouldShowJobSeekerContent">
|
||||
<view class="search-input button-click" @click="navTo('/pages/search/search')">
|
||||
<uni-icons class="iconsearch" color="#666666" type="search" size="18"></uni-icons>
|
||||
<text class="inpute">职位名称、薪资要求等</text>
|
||||
</view>
|
||||
<!-- 直播入口按钮 -->
|
||||
<view class="live-button press-button" @click="handleLiveClick">
|
||||
<view class="live-icon">
|
||||
<uni-icons type="videocam-filled" size="16" color="#FFFFFF"></uni-icons>
|
||||
</view>
|
||||
<view class="live-text">直播</view>
|
||||
</view>
|
||||
<!-- <view class="chart button-click">职业图谱</view> -->
|
||||
</view>
|
||||
<view class="cards" v-if="userInfo.userType !== 0">
|
||||
<view class="cards" v-if="shouldShowJobSeekerContent">
|
||||
<view class="card press-button" @click="handleNearbyClick">
|
||||
<view class="card-title">附近工作</view>
|
||||
<view class="card-text">好岗职等你来</view>
|
||||
@@ -27,9 +62,8 @@
|
||||
</view> -->
|
||||
</view>
|
||||
|
||||
|
||||
<!-- 服务功能网格 -->
|
||||
<view class="service-grid" v-if="userInfo.userType !== 0">
|
||||
<view class="service-grid" v-if="shouldShowJobSeekerContent">
|
||||
<view class="service-item press-button" @click="handleServiceClick('service-guidance')">
|
||||
<view class="service-icon service-icon-1">
|
||||
<uni-icons type="auth-filled" size="32" color="#FFFFFF"></uni-icons>
|
||||
@@ -84,6 +118,66 @@
|
||||
</view>
|
||||
<view class="service-title">AI智能面试</view>
|
||||
</view>
|
||||
<view class="service-item press-button" @click="handleServiceClick('ai-interview')">
|
||||
<view class="service-icon service-icon-9">
|
||||
<IconfontIcon name="Graduation-simple-" :size="32" color="#FFFFFF" />
|
||||
</view>
|
||||
<view class="service-title" style="overflow:none">高校毕业生<br/>智慧就业服务</view>
|
||||
</view>
|
||||
<view class="service-item press-button" @click="navToTestPage">
|
||||
<view class="service-icon service-icon-10">
|
||||
<uni-icons type="gear-filled" size="32" color="#FFFFFF"></uni-icons>
|
||||
</view>
|
||||
<view class="service-title">测试页面</view>
|
||||
</view>
|
||||
<view class="service-item press-button" @click="handleServiceClick('public-recruitment')">
|
||||
<view class="service-icon service-icon-2">
|
||||
<IconfontIcon name="zhengfulou" :size="48" color="#FFFFFF" />
|
||||
</view>
|
||||
<view class="service-title">事业单位招录</view>
|
||||
</view>
|
||||
<view class="service-item press-button" @click="handleServiceClick('resume-creation')">
|
||||
<view class="service-icon service-icon-3">
|
||||
<IconfontIcon name="jianli" :size="48" color="#FFFFFF" />
|
||||
</view>
|
||||
<view class="service-title">简历制作</view>
|
||||
</view>
|
||||
<view class="service-item press-button" @click="handleServiceClick('labor-policy')">
|
||||
<view class="service-icon service-icon-4">
|
||||
<IconfontIcon name="zhengce" :size="48" color="#FFFFFF" />
|
||||
</view>
|
||||
<view class="service-title">劳动政策指引</view>
|
||||
</view>
|
||||
<view class="service-item press-button" @click="handleServiceClick('skill-training')">
|
||||
<view class="service-icon service-icon-5">
|
||||
<IconfontIcon name="jinengpeixun" :size="48" color="#FFFFFF" />
|
||||
</view>
|
||||
<view class="service-title">技能培训信息</view>
|
||||
</view>
|
||||
<view class="service-item press-button" @click="handleServiceClick('skill-evaluation')">
|
||||
<view class="service-icon service-icon-6">
|
||||
<IconfontIcon name="jinengpingjia" :size="48" color="#FFFFFF" />
|
||||
</view>
|
||||
<view class="service-title">技能评价指引</view>
|
||||
</view>
|
||||
<view class="service-item press-button" @click="handleServiceClick('question-bank')">
|
||||
<view class="service-icon service-icon-7">
|
||||
<IconfontIcon name="suzhicepingtiku" :size="48" color="#FFFFFF" />
|
||||
</view>
|
||||
<view class="service-title">题库和考试</view>
|
||||
</view>
|
||||
<view class="service-item press-button" @click="handleServiceClick('quality-assessment')">
|
||||
<view class="service-icon service-icon-8">
|
||||
<IconfontIcon name="suzhicepingtiku" :size="48" color="#FFFFFF" />
|
||||
</view>
|
||||
<view class="service-title">素质测评</view>
|
||||
</view>
|
||||
<view class="service-item press-button" @click="handleServiceClick('ai-interview')">
|
||||
<view class="service-icon service-icon-9">
|
||||
<IconfontIcon name="ai" :size="68" color="#FFFFFF" />
|
||||
</view>
|
||||
<view class="service-title">AI智能面试</view>
|
||||
</view>
|
||||
<view class="service-item press-button" @click="navTo('/packageB/pages/search/search')">
|
||||
<view class="service-icon service-icon-9">
|
||||
<IconfontIcon name="ai" :size="68" color="#FFFFFF" />
|
||||
@@ -92,11 +186,47 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 企业用户内容 -->
|
||||
<!-- <view class="company-content" v-if="shouldShowCompanyContent">
|
||||
<view class="company-header">
|
||||
<text class="company-title">企业服务</text>
|
||||
<text class="company-subtitle">为您提供专业的企业招聘服务</text>
|
||||
</view>
|
||||
|
||||
<view class="company-grid">
|
||||
<view class="company-item press-button" @click="navTo('/pages/job/publishJob')">
|
||||
<view class="company-icon company-icon-1">
|
||||
<uni-icons type="plus-filled" size="32" color="#FFFFFF"></uni-icons>
|
||||
</view>
|
||||
<view class="company-title">发布岗位</view>
|
||||
</view>
|
||||
<view class="company-item press-button" @click="handleServiceClick('company-management')">
|
||||
<view class="company-icon company-icon-2">
|
||||
<uni-icons type="settings-filled" size="32" color="#FFFFFF"></uni-icons>
|
||||
</view>
|
||||
<view class="company-title">企业管理</view>
|
||||
</view>
|
||||
<view class="company-item press-button" @click="handleServiceClick('recruitment-data')">
|
||||
<view class="company-icon company-icon-3">
|
||||
<uni-icons type="bar-chart-filled" size="32" color="#FFFFFF"></uni-icons>
|
||||
</view>
|
||||
<view class="company-title">招聘数据</view>
|
||||
</view>
|
||||
<view class="company-item press-button" @click="handleServiceClick('talent-pool')">
|
||||
<view class="company-icon company-icon-4">
|
||||
<uni-icons type="person-filled" size="32" color="#FFFFFF"></uni-icons>
|
||||
</view>
|
||||
<view class="company-title">人才库</view>
|
||||
</view>
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
<!-- 吸顶筛选区域占位 -->
|
||||
<view class="filter-placeholder" v-if="shouldStickyFilter && userInfo.userType !== 0"></view>
|
||||
<view class="filter-placeholder" v-if="shouldStickyFilter && shouldShowJobSeekerContent"></view>
|
||||
|
||||
|
||||
<view class="nav-filter" :class="{ 'sticky-filter': shouldStickyFilter }" v-if="userInfo.userType !== 0">
|
||||
<view class="nav-filter" :class="{ 'sticky-filter': shouldStickyFilter }" v-if="shouldShowJobSeekerContent">
|
||||
<view class="filter-top" @touchmove.stop.prevent>
|
||||
<scroll-view :scroll-x="true" :show-scrollbar="false" class="tab-scroll">
|
||||
<view class="jobs-left">
|
||||
@@ -328,7 +458,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, inject, watch, ref, onMounted, onUnmounted, watchEffect, nextTick } from 'vue';
|
||||
import { reactive, inject, watch, ref, onMounted, onUnmounted, watchEffect, nextTick, computed } from 'vue';
|
||||
import img from '@/static/icon/filter.png';
|
||||
import dictLabel from '@/components/dict-Label/dict-Label.vue';
|
||||
const { $api, navTo, vacanciesTo, formatTotal, config } = inject('globalFunction');
|
||||
@@ -336,6 +466,81 @@ import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import useUserStore from '@/stores/useUserStore';
|
||||
const { userInfo, hasLogin, token } = storeToRefs(useUserStore());
|
||||
|
||||
// 计算是否显示求职者内容
|
||||
const shouldShowJobSeekerContent = computed(() => {
|
||||
// 未登录时默认显示求职者内容
|
||||
if (!hasLogin.value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 优先从store获取,如果为空则从缓存获取
|
||||
const storeIsCompanyUser = userInfo.value?.isCompanyUser;
|
||||
const cachedUserInfo = uni.getStorageSync('userInfo') || {};
|
||||
const cachedIsCompanyUser = cachedUserInfo.isCompanyUser;
|
||||
|
||||
// 获取用户类型:优先使用store中的isCompanyUser,如果store中没有,使用缓存中的isCompanyUser
|
||||
// 缓存中的值可能是字符串,需要转换为数值类型
|
||||
const userType = storeIsCompanyUser !== undefined ? Number(storeIsCompanyUser) : Number(cachedIsCompanyUser);
|
||||
|
||||
// 企业用户(isCompanyUser=0)不显示求职者内容,其他用户类型显示
|
||||
return userType !== 0;
|
||||
});
|
||||
|
||||
// 企业信息数据
|
||||
const companyInfo = reactive({
|
||||
name: '',
|
||||
avatar: '',
|
||||
industry: '',
|
||||
scale: '',
|
||||
isVerified: false
|
||||
});
|
||||
|
||||
// 计算是否显示企业卡片
|
||||
const shouldShowCompanyCard = computed(() => {
|
||||
// 未登录时不显示
|
||||
if (!hasLogin.value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 优先从store获取,如果为空则从缓存获取
|
||||
const storeIsCompanyUser = userInfo.value?.isCompanyUser;
|
||||
const cachedUserInfo = uni.getStorageSync('userInfo') || {};
|
||||
const cachedIsCompanyUser = cachedUserInfo.isCompanyUser;
|
||||
|
||||
// 获取用户类型:优先使用store中的isCompanyUser,如果store中没有,使用缓存中的isCompanyUser
|
||||
// 缓存中的值可能是字符串,需要转换为数值类型
|
||||
const userType = storeIsCompanyUser !== undefined ? Number(storeIsCompanyUser) : Number(cachedIsCompanyUser);
|
||||
|
||||
// 只有企业用户(isCompanyUser=0)才显示企业卡片
|
||||
if (userType !== 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查企业信息是否已完善
|
||||
return companyInfo.name && companyInfo.name.trim() !== '';
|
||||
});
|
||||
|
||||
// 计算是否显示企业用户内容
|
||||
const shouldShowCompanyContent = computed(() => {
|
||||
// 未登录时不显示企业内容
|
||||
if (!hasLogin.value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 优先从store获取,如果为空则从缓存获取
|
||||
const storeIsCompanyUser = userInfo.value?.isCompanyUser;
|
||||
const cachedUserInfo = uni.getStorageSync('userInfo') || {};
|
||||
const cachedIsCompanyUser = cachedUserInfo.isCompanyUser;
|
||||
|
||||
// 获取用户类型:优先使用store中的isCompanyUser,如果store中没有,使用缓存中的isCompanyUser
|
||||
// 缓存中的值可能是字符串,需要转换为数值类型
|
||||
const userType = storeIsCompanyUser !== undefined ? Number(storeIsCompanyUser) : Number(cachedIsCompanyUser);
|
||||
|
||||
// 只有企业用户(isCompanyUser=0)才显示企业内容
|
||||
return userType === 0;
|
||||
});
|
||||
|
||||
import useDictStore from '@/stores/useDictStore';
|
||||
const { getTransformChildren, oneDictData } = useDictStore();
|
||||
import useLocationStore from '@/stores/useLocationStore';
|
||||
@@ -345,6 +550,7 @@ import { useScrollDirection } from '@/hook/useScrollDirection';
|
||||
import { useColumnCount } from '@/hook/useColumnCount';
|
||||
import WxAuthLogin from '@/components/WxAuthLogin/WxAuthLogin.vue';
|
||||
import IconfontIcon from '@/components/IconfontIcon/IconfontIcon.vue'
|
||||
// 企业卡片组件已内联到模板中
|
||||
// 滚动状态管理
|
||||
const shouldHideTop = ref(false);
|
||||
const shouldStickyFilter = ref(false);
|
||||
@@ -352,7 +558,6 @@ const lastScrollTop = ref(0);
|
||||
const scrollTop = ref(0);
|
||||
// 当用户与筛选/导航交互时,临时锁定头部显示状态,避免因数据刷新导致回弹显示
|
||||
const isInteractingWithFilter = ref(false);
|
||||
|
||||
// 滚动阈值配置
|
||||
const HIDE_THRESHOLD = 50; // 隐藏顶部区域的滚动阈值(降低阈值,更容易触发)
|
||||
const SHOW_THRESHOLD = 5; // 显示顶部区域的滚动阈值(接近顶部)
|
||||
@@ -421,21 +626,101 @@ const rangeOptions = ref([
|
||||
{ value: 3, text: '疆外' },
|
||||
]);
|
||||
const isLoaded = ref(false);
|
||||
const isInitialized = ref(false); // 添加初始化标志
|
||||
|
||||
const { columnCount, columnSpace } = useColumnCount(() => {
|
||||
pageState.pageSize = 10 * (columnCount.value - 1);
|
||||
getJobRecommend('refresh');
|
||||
|
||||
// 只在首次初始化时调用,避免重复调用
|
||||
if (!isInitialized.value) {
|
||||
isInitialized.value = true;
|
||||
getJobRecommend('refresh');
|
||||
}
|
||||
|
||||
nextTick(() => {
|
||||
waterfallsFlowRef.value?.refresh?.();
|
||||
useLocationStore().getLocation();
|
||||
});
|
||||
});
|
||||
|
||||
// 获取企业信息
|
||||
const getCompanyInfo = () => {
|
||||
try {
|
||||
const cachedUserInfo = uni.getStorageSync('userInfo') || {};
|
||||
console.log('缓存中的userInfo:', cachedUserInfo);
|
||||
|
||||
// 重置企业信息
|
||||
companyInfo.name = '';
|
||||
companyInfo.avatar = '';
|
||||
companyInfo.industry = '';
|
||||
companyInfo.scale = '';
|
||||
companyInfo.isVerified = false;
|
||||
|
||||
// 检查是否有company字段
|
||||
if (cachedUserInfo.company) {
|
||||
const company = cachedUserInfo.company;
|
||||
|
||||
// 基本信息
|
||||
companyInfo.name = company.name || '';
|
||||
companyInfo.avatar = company.avatar || '';
|
||||
companyInfo.industry = company.industryType || '互联网';
|
||||
companyInfo.scale = company.scale || '100-999人';
|
||||
|
||||
// 判断是否实名:legalIdCard字段有值则表示已实名
|
||||
companyInfo.isVerified = !!(company.legalIdCard && company.legalIdCard.trim());
|
||||
|
||||
console.log('企业信息已更新:', {
|
||||
name: companyInfo.name,
|
||||
industry: companyInfo.industry,
|
||||
size: companyInfo.scale,
|
||||
isVerified: companyInfo.isVerified
|
||||
});
|
||||
} else {
|
||||
console.log('缓存中没有company字段,企业信息已重置');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取企业信息失败:', error);
|
||||
// 重置为默认值
|
||||
companyInfo.name = '';
|
||||
companyInfo.avatar = '';
|
||||
companyInfo.industry = '';
|
||||
companyInfo.scale = '';
|
||||
companyInfo.isVerified = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 跳转到企业信息详情页面
|
||||
const goToCompanyInfo = () => {
|
||||
navTo('/pages/mine/company-info');
|
||||
};
|
||||
|
||||
// 组件初始化时加载数据
|
||||
onMounted(() => {
|
||||
getJobRecommend('refresh');
|
||||
// 获取企业信息
|
||||
getCompanyInfo();
|
||||
|
||||
// 监听退出登录事件,显示微信登录弹窗
|
||||
uni.$on('showLoginModal', () => {
|
||||
wxAuthLoginRef.value?.open();
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
uni.$off('showLoginModal');
|
||||
});
|
||||
|
||||
onShow(() => {
|
||||
// 获取最新的企业信息
|
||||
getCompanyInfo();
|
||||
});
|
||||
|
||||
// 监听用户信息变化,当登录状态改变时重新获取企业信息
|
||||
watch([hasLogin, userInfo], () => {
|
||||
if (hasLogin.value) {
|
||||
getCompanyInfo();
|
||||
}
|
||||
}, { deep: true });
|
||||
|
||||
// 登录检查函数
|
||||
const checkLogin = () => {
|
||||
const tokenValue = uni.getStorageSync('token') || '';
|
||||
@@ -451,6 +736,9 @@ const checkLogin = () => {
|
||||
const handleLoginSuccess = () => {
|
||||
// 登录成功后刷新数据
|
||||
getJobRecommend('refresh');
|
||||
|
||||
// 重新获取企业信息
|
||||
getCompanyInfo();
|
||||
};
|
||||
|
||||
// 处理附近工作点击
|
||||
@@ -467,6 +755,16 @@ const handleServiceClick = (serviceType) => {
|
||||
}
|
||||
};
|
||||
|
||||
// 处理直播按钮点击
|
||||
const handleLiveClick = () => {
|
||||
$api.msg('该功能正在开发中');
|
||||
};
|
||||
|
||||
// 跳转到测试页面
|
||||
const navToTestPage = () => {
|
||||
navTo('/pages/test/homepage-test');
|
||||
};
|
||||
|
||||
async function loadData() {
|
||||
try {
|
||||
if (isLoaded.value) return;
|
||||
@@ -478,7 +776,9 @@ async function loadData() {
|
||||
}
|
||||
|
||||
function scrollBottom() {
|
||||
loadmoreRef.value.change('loading');
|
||||
if (loadmoreRef.value && typeof loadmoreRef.value.change === 'function') {
|
||||
loadmoreRef.value.change('loading');
|
||||
}
|
||||
if (state.tabIndex === 'all') {
|
||||
getJobRecommend();
|
||||
} else {
|
||||
@@ -556,7 +856,7 @@ function navToService(serviceType) {
|
||||
'resume-creation': '/packageA/pages/myResume/myResume',
|
||||
'labor-policy': '/pages/service/labor-policy',
|
||||
'skill-training': '/pages/service/skill-training',
|
||||
'skill-evaluation': '/pages/service/skill-evaluation',
|
||||
// 'skill-evaluation': '/pages/service/skill-evaluation',
|
||||
'question-bank': '/pages/service/question-bank',
|
||||
'quality-assessment': '/pages/service/quality-assessment',
|
||||
'ai-interview': '/pages/chat/chat',
|
||||
@@ -566,7 +866,8 @@ function navToService(serviceType) {
|
||||
'company-info': '/pages/service/company-info',
|
||||
'interview-tips': '/pages/service/interview-tips',
|
||||
'employment-news': '/pages/service/employment-news',
|
||||
'more-services': '/pages/service/more-services'
|
||||
'more-services': '/pages/service/more-services',
|
||||
'skill-evaluation': '/packageB/train/index'
|
||||
};
|
||||
|
||||
const route = serviceRoutes[serviceType];
|
||||
@@ -655,6 +956,7 @@ function getJobRecommend(type = 'add') {
|
||||
sessionId: useUserStore().seesionId,
|
||||
...pageState.search,
|
||||
...conditionSearch.value,
|
||||
isPublish: 1,
|
||||
};
|
||||
let comd = { recommend: true, jobCategory: '', tip: '确认你的兴趣,为您推荐更多合适的岗位' };
|
||||
$api.createRequest('/app/job/recommend', params).then((resData) => {
|
||||
@@ -882,13 +1184,14 @@ defineExpose({ loadData });
|
||||
padding: 16rpx 24rpx
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
align-items: center
|
||||
.search-input
|
||||
display: flex
|
||||
align-items: center;
|
||||
width: 100%
|
||||
flex: 1
|
||||
height: 80rpx;
|
||||
line-height: 80rpx
|
||||
margin-right: 24rpx
|
||||
margin-right: 16rpx
|
||||
background: #FFFFFF;
|
||||
border-radius: 75rpx 75rpx 75rpx 75rpx;
|
||||
.iconsearch
|
||||
@@ -899,6 +1202,35 @@ defineExpose({ loadData });
|
||||
font-size: 28rpx;
|
||||
color: #B5B5B5;
|
||||
width: 100%
|
||||
.live-button
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
width: 90rpx
|
||||
height: 42rpx
|
||||
background: linear-gradient(135deg, #FF6B6B 0%, #FF8E8E 100%)
|
||||
border-radius: 40rpx
|
||||
box-shadow: 0 3rpx 8rpx rgba(255, 107, 107, 0.2)
|
||||
transition: all 0.2s ease
|
||||
flex-shrink: 0
|
||||
|
||||
&:active
|
||||
transform: scale(0.96)
|
||||
box-shadow: 0 2rpx 6rpx rgba(255, 107, 107, 0.25)
|
||||
|
||||
.live-icon
|
||||
margin-right: 8rpx
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
|
||||
.live-text
|
||||
font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif
|
||||
font-weight: 500
|
||||
font-size: 24rpx
|
||||
color: #FFFFFF
|
||||
text-align: center
|
||||
white-space: nowrap
|
||||
.chart
|
||||
font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif;
|
||||
width: 170rpx;
|
||||
@@ -1021,13 +1353,9 @@ defineExpose({ loadData });
|
||||
.service-icon-10
|
||||
background: linear-gradient(135deg, #9C27B0 0%, #BA68C8 100%)
|
||||
position: relative
|
||||
&::before
|
||||
content: '🔍'
|
||||
position: absolute
|
||||
top: 50%
|
||||
left: 50%
|
||||
transform: translate(-50%, -50%)
|
||||
font-size: 32rpx
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
.service-icon-11
|
||||
background: linear-gradient(135deg, #FF9800 0%, #FFB74D 100%)
|
||||
position: relative
|
||||
@@ -1100,6 +1428,8 @@ defineExpose({ loadData });
|
||||
text-overflow: ellipsis
|
||||
width: 100%
|
||||
max-width: 100%
|
||||
.service-title-special
|
||||
overflow: none;
|
||||
|
||||
// 吸顶筛选区域占位
|
||||
.filter-placeholder
|
||||
@@ -1346,6 +1676,71 @@ defineExpose({ loadData });
|
||||
background-size contain
|
||||
pointer-events none
|
||||
filter: blur(3rpx)
|
||||
// 企业用户内容样式
|
||||
.company-content
|
||||
padding: 40rpx 30rpx
|
||||
background: #ffffff
|
||||
margin: 20rpx 30rpx
|
||||
border-radius: 20rpx
|
||||
box-shadow: 0rpx 4rpx 12rpx 0rpx rgba(0, 0, 0, 0.1)
|
||||
|
||||
.company-header
|
||||
text-align: center
|
||||
margin-bottom: 40rpx
|
||||
|
||||
.company-title
|
||||
font-size: 36rpx
|
||||
font-weight: bold
|
||||
color: #333333
|
||||
display: block
|
||||
margin-bottom: 10rpx
|
||||
|
||||
.company-subtitle
|
||||
font-size: 24rpx
|
||||
color: #666666
|
||||
display: block
|
||||
|
||||
.company-grid
|
||||
display: grid
|
||||
grid-template-columns: 1fr 1fr
|
||||
gap: 30rpx
|
||||
|
||||
.company-item
|
||||
display: flex
|
||||
flex-direction: column
|
||||
align-items: center
|
||||
padding: 30rpx 20rpx
|
||||
background: #f8f9fa
|
||||
border-radius: 15rpx
|
||||
transition: all 0.3s ease
|
||||
|
||||
&:active
|
||||
transform: scale(0.95)
|
||||
background: #e9ecef
|
||||
|
||||
.company-icon
|
||||
width: 60rpx
|
||||
height: 60rpx
|
||||
border-radius: 50%
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
margin-bottom: 15rpx
|
||||
|
||||
&.company-icon-1
|
||||
background: #256BFA
|
||||
&.company-icon-2
|
||||
background: #52c41a
|
||||
&.company-icon-3
|
||||
background: #fa8c16
|
||||
&.company-icon-4
|
||||
background: #eb2f96
|
||||
|
||||
.company-title
|
||||
font-size: 24rpx
|
||||
color: #333333
|
||||
font-weight: 500
|
||||
|
||||
.recommend-card
|
||||
padding 36rpx 24rpx
|
||||
background: linear-gradient( 360deg, #DFE9FF 0%, #FFFFFF 52%, #FFFFFF 100%);
|
||||
@@ -1424,4 +1819,133 @@ defineExpose({ loadData });
|
||||
.isBut{
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
|
||||
// 企业账号显示卡片样式
|
||||
.enterprise-card
|
||||
margin: 20rpx 28rpx
|
||||
padding: 28rpx
|
||||
background: rgba(255, 255, 255, 0.9)
|
||||
backdrop-filter: blur(20rpx)
|
||||
-webkit-backdrop-filter: blur(20rpx)
|
||||
border-radius: 24rpx
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.4)
|
||||
box-shadow: 0 8rpx 40rpx rgba(0, 0, 0, 0.08), 0 2rpx 8rpx rgba(0, 0, 0, 0.04)
|
||||
position: relative
|
||||
overflow: hidden
|
||||
cursor: pointer
|
||||
transition: all 0.3s ease
|
||||
|
||||
&:active
|
||||
transform: scale(0.98)
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.12), 0 1rpx 4rpx rgba(0, 0, 0, 0.08)
|
||||
|
||||
// 玻璃态效果 - 更强烈的渐变
|
||||
&::before
|
||||
content: ''
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
right: 0
|
||||
bottom: 0
|
||||
background: linear-gradient(135deg,
|
||||
rgba(255, 255, 255, 0.2) 0%,
|
||||
rgba(255, 255, 255, 0.1) 50%,
|
||||
rgba(255, 255, 255, 0.05) 100%)
|
||||
border-radius: 24rpx
|
||||
pointer-events: none
|
||||
z-index: 0
|
||||
|
||||
// 添加微妙的边框高光
|
||||
&::after
|
||||
content: ''
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
right: 0
|
||||
bottom: 0
|
||||
border-radius: 24rpx
|
||||
padding: 1rpx
|
||||
background: linear-gradient(135deg,
|
||||
rgba(255, 255, 255, 0.6) 0%,
|
||||
rgba(255, 255, 255, 0.2) 100%)
|
||||
mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)
|
||||
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)
|
||||
mask-composite: xor
|
||||
-webkit-mask-composite: xor
|
||||
pointer-events: none
|
||||
z-index: 1
|
||||
|
||||
.card-content
|
||||
display: flex
|
||||
align-items: center
|
||||
position: relative
|
||||
z-index: 2
|
||||
|
||||
.company-icon
|
||||
width: 88rpx
|
||||
height: 88rpx
|
||||
border-radius: 18rpx
|
||||
background: linear-gradient(135deg, #256BFA 0%, #4A90E2 100%)
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
margin-right: 28rpx
|
||||
flex-shrink: 0
|
||||
box-shadow: 0 6rpx 16rpx rgba(37, 107, 250, 0.25)
|
||||
position: relative
|
||||
|
||||
// 添加图标内部高光
|
||||
&::before
|
||||
content: ''
|
||||
position: absolute
|
||||
top: 4rpx
|
||||
left: 4rpx
|
||||
right: 4rpx
|
||||
height: 20rpx
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.3) 0%, transparent 100%)
|
||||
border-radius: 18rpx 18rpx 0 0
|
||||
pointer-events: none
|
||||
|
||||
.default-logo
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
color: #ffffff
|
||||
|
||||
.company-info
|
||||
flex: 1
|
||||
min-width: 0
|
||||
z-index: 2
|
||||
position: relative
|
||||
|
||||
.company-name
|
||||
font-size: 34rpx
|
||||
font-weight: 600
|
||||
color: #000000
|
||||
line-height: 1.3
|
||||
margin-bottom: 10rpx
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
white-space: nowrap
|
||||
font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif
|
||||
|
||||
.company-details
|
||||
display: flex
|
||||
align-items: center
|
||||
font-size: 26rpx
|
||||
color: #666666
|
||||
line-height: 1.2
|
||||
|
||||
.industry
|
||||
color: #666666
|
||||
font-weight: 400
|
||||
|
||||
.separator
|
||||
margin: 0 10rpx
|
||||
color: #CCCCCC
|
||||
font-weight: 300
|
||||
|
||||
.size
|
||||
color: #666666
|
||||
font-weight: 400
|
||||
</style>
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
<IndexOne @onShowTabbar="changeShowTabbar" />
|
||||
</view>
|
||||
|
||||
<!-- 统一使用系统tabBar -->
|
||||
<!-- 自定义tabbar -->
|
||||
<CustomTabBar :currentPage="0" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -18,11 +19,17 @@ import IndexOne from './components/index-one.vue';
|
||||
// import IndexTwo from './components/index-two.vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useReadMsg } from '@/stores/useReadMsg';
|
||||
import { tabbarManager } from '@/utils/tabbarManager';
|
||||
const { unreadCount } = storeToRefs(useReadMsg());
|
||||
|
||||
onLoad(() => {
|
||||
// useReadMsg().fetchMessages();
|
||||
});
|
||||
|
||||
onShow(() => {
|
||||
// 更新自定义tabbar选中状态
|
||||
tabbarManager.updateSelected(0);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
|
||||
474
pages/job/companySearch.vue
Normal file
474
pages/job/companySearch.vue
Normal file
@@ -0,0 +1,474 @@
|
||||
<template>
|
||||
<view class="company-search-page">
|
||||
<!-- 头部导航 -->
|
||||
<view class="header">
|
||||
<view class="header-left" @click="goBack">
|
||||
<view class="back-arrow"><uni-icons type="search" size="32" color="#FFFFFF"></uni-icons>‹</view>
|
||||
</view>
|
||||
<view class="header-title">选择企业</view>
|
||||
<view class="header-right"></view>
|
||||
</view>
|
||||
|
||||
<!-- 搜索框 -->
|
||||
<view class="search-container">
|
||||
<view class="search-box">
|
||||
<view class="search-icon">🔍</view>
|
||||
<input
|
||||
class="search-input"
|
||||
placeholder="请输入企业名称进行搜索"
|
||||
v-model="searchKeyword"
|
||||
@input="onSearchInput"
|
||||
/>
|
||||
<view class="clear-btn" v-if="searchKeyword" @click="clearSearch">
|
||||
<view class="clear-icon">✕</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 搜索结果 -->
|
||||
<scroll-view class="content" scroll-y="true" :style="{ height: scrollViewHeight }">
|
||||
<!-- 搜索提示 -->
|
||||
<view class="search-tip" v-if="!searchKeyword">
|
||||
<text class="tip-text">请输入企业名称进行搜索</text>
|
||||
</view>
|
||||
|
||||
<!-- 加载中 -->
|
||||
<view class="loading-container" v-if="loading">
|
||||
<view class="loading-text">搜索中...</view>
|
||||
</view>
|
||||
|
||||
<!-- 搜索结果列表 -->
|
||||
<view class="result-list" v-if="searchResults.length > 0">
|
||||
<view
|
||||
class="result-item"
|
||||
v-for="(company, index) in searchResults"
|
||||
:key="company.companyId"
|
||||
@click="selectCompany(company)"
|
||||
>
|
||||
<view class="company-info">
|
||||
<view class="company-name">{{ company.name }}</view>
|
||||
<view class="company-location" v-if="company.location">
|
||||
<text class="location-icon">📍</text>
|
||||
<text class="location-text">{{ company.location }}</text>
|
||||
</view>
|
||||
<view class="company-scale" v-if="company.scale">
|
||||
<text class="scale-label">规模:</text>
|
||||
<text class="scale-text">{{ getScaleText(company.scale) }}</text>
|
||||
</view>
|
||||
<view class="company-nature" v-if="company.nature">
|
||||
<text class="nature-label">性质:</text>
|
||||
<text class="nature-text">{{ getNatureText(company.nature) }}</text>
|
||||
</view>
|
||||
<view class="company-description" v-if="company.description">
|
||||
<text class="desc-text">{{ company.description }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="select-icon">
|
||||
<view class="arrow-icon">›</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 无结果提示 -->
|
||||
<view class="no-result" v-if="searchKeyword && !loading && searchResults.length === 0">
|
||||
<view class="empty-icon">📭</view>
|
||||
<view class="no-result-text">未找到相关企业</view>
|
||||
<view class="no-result-tip">请尝试其他关键词</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部安全区域 -->
|
||||
<view class="bottom-safe-area"></view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { createRequest } from '@/utils/request';
|
||||
|
||||
// 搜索关键词
|
||||
const searchKeyword = ref('');
|
||||
// 搜索结果
|
||||
const searchResults = ref([]);
|
||||
// 加载状态
|
||||
const loading = ref(false);
|
||||
// 防抖定时器
|
||||
let debounceTimer = null;
|
||||
|
||||
// 滚动视图高度
|
||||
const scrollViewHeight = ref('calc(100vh - 200rpx)');
|
||||
|
||||
// 计算滚动视图高度
|
||||
const calculateScrollViewHeight = () => {
|
||||
const systemInfo = uni.getSystemInfoSync();
|
||||
const windowHeight = systemInfo.windowHeight;
|
||||
const headerHeight = 100; // 头部高度
|
||||
const searchHeight = 120; // 搜索框高度
|
||||
const scrollHeight = windowHeight - headerHeight - searchHeight;
|
||||
scrollViewHeight.value = `${scrollHeight}px`;
|
||||
};
|
||||
|
||||
// 页面加载时计算高度
|
||||
onMounted(() => {
|
||||
calculateScrollViewHeight();
|
||||
});
|
||||
|
||||
// 搜索输入处理(防抖)
|
||||
const onSearchInput = () => {
|
||||
// 清除之前的定时器
|
||||
if (debounceTimer) {
|
||||
clearTimeout(debounceTimer);
|
||||
}
|
||||
|
||||
// 设置新的定时器
|
||||
debounceTimer = setTimeout(() => {
|
||||
if (searchKeyword.value.trim()) {
|
||||
searchCompanies();
|
||||
} else {
|
||||
searchResults.value = [];
|
||||
}
|
||||
}, 500); // 500ms 防抖延迟
|
||||
};
|
||||
|
||||
// 搜索企业
|
||||
const searchCompanies = async () => {
|
||||
if (!searchKeyword.value.trim()) {
|
||||
searchResults.value = [];
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
loading.value = true;
|
||||
|
||||
const response = await createRequest('/app/company/likeList', {
|
||||
name: searchKeyword.value.trim()
|
||||
}, 'get', false);
|
||||
|
||||
if (response.code === 200) {
|
||||
searchResults.value = response.rows || [];
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: response.msg || '搜索失败',
|
||||
icon: 'none'
|
||||
});
|
||||
searchResults.value = [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('搜索企业失败:', error);
|
||||
uni.showToast({
|
||||
title: '搜索失败,请重试',
|
||||
icon: 'none'
|
||||
});
|
||||
searchResults.value = [];
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 清除搜索
|
||||
const clearSearch = () => {
|
||||
searchKeyword.value = '';
|
||||
searchResults.value = [];
|
||||
if (debounceTimer) {
|
||||
clearTimeout(debounceTimer);
|
||||
}
|
||||
};
|
||||
|
||||
// 获取企业规模文本
|
||||
const getScaleText = (scale) => {
|
||||
const scaleMap = {
|
||||
'1': '1-20人',
|
||||
'2': '21-50人',
|
||||
'3': '51-100人',
|
||||
'4': '101-200人',
|
||||
'5': '201-500人',
|
||||
'6': '500人以上'
|
||||
};
|
||||
return scaleMap[scale] || '未知';
|
||||
};
|
||||
|
||||
// 获取企业性质文本
|
||||
const getNatureText = (nature) => {
|
||||
const natureMap = {
|
||||
'1': '有限责任公司',
|
||||
'2': '股份有限公司',
|
||||
'3': '个人独资企业',
|
||||
'4': '合伙企业',
|
||||
'5': '外商投资企业',
|
||||
'6': '其他'
|
||||
};
|
||||
return natureMap[nature] || '未知';
|
||||
};
|
||||
|
||||
// 选择企业
|
||||
const selectCompany = (company) => {
|
||||
// 返回上一页并传递选中的企业信息
|
||||
uni.navigateBack({
|
||||
delta: 1,
|
||||
success: () => {
|
||||
// 通过事件总线或全局状态传递数据
|
||||
uni.$emit('companySelected', {
|
||||
id: company.companyId,
|
||||
name: company.name,
|
||||
address: company.location
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 返回上一页
|
||||
const goBack = () => {
|
||||
uni.navigateBack();
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.company-search-page {
|
||||
height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20rpx 30rpx;
|
||||
background: #fff;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
|
||||
.header-left {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.back-arrow {
|
||||
font-size: 40rpx;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
width: 60rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.search-container {
|
||||
padding: 20rpx 30rpx;
|
||||
background: #fff;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
|
||||
.search-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: #f5f5f5;
|
||||
border-radius: 12rpx;
|
||||
padding: 0 20rpx;
|
||||
height: 80rpx;
|
||||
|
||||
.search-icon {
|
||||
font-size: 32rpx;
|
||||
margin-right: 20rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
background: transparent;
|
||||
border: none;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
line-height: 1.4;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&::placeholder {
|
||||
color: #999;
|
||||
font-size: 28rpx;
|
||||
line-height: 1.4;
|
||||
}
|
||||
}
|
||||
|
||||
.clear-btn {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: 20rpx;
|
||||
|
||||
.clear-icon {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.search-tip {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 400rpx;
|
||||
|
||||
.tip-text {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 200rpx;
|
||||
|
||||
.loading-text {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
.result-list {
|
||||
background: #fff;
|
||||
|
||||
.result-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 30rpx;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
.company-info {
|
||||
flex: 1;
|
||||
|
||||
.company-name {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
margin-bottom: 15rpx;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.company-location {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 10rpx;
|
||||
|
||||
.location-icon {
|
||||
font-size: 20rpx;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.location-text {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.company-scale, .company-nature {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8rpx;
|
||||
|
||||
.scale-label, .nature-label {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.scale-text, .nature-text {
|
||||
font-size: 22rpx;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
.company-description {
|
||||
margin-top: 10rpx;
|
||||
|
||||
.desc-text {
|
||||
font-size: 22rpx;
|
||||
color: #888;
|
||||
line-height: 1.4;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
line-clamp: 2;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.select-icon {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.arrow-icon {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-result {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 400rpx;
|
||||
|
||||
.empty-icon {
|
||||
font-size: 120rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.no-result-text {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.no-result-tip {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-safe-area {
|
||||
height: 120rpx;
|
||||
background: transparent;
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,75 +0,0 @@
|
||||
<template>
|
||||
<view class="tab-container">
|
||||
<view class="uni-margin-wrap">
|
||||
<swiper
|
||||
class="swiper"
|
||||
:current="current"
|
||||
:circular="false"
|
||||
:indicator-dots="false"
|
||||
:autoplay="false"
|
||||
:duration="500"
|
||||
>
|
||||
<swiper-item @touchmove.stop="false">
|
||||
<slot name="tab0"></slot>
|
||||
</swiper-item>
|
||||
<swiper-item @touchmove.stop="false">
|
||||
<slot name="tab1"></slot>
|
||||
</swiper-item>
|
||||
<swiper-item @touchmove.stop="false">
|
||||
<slot name="tab2"></slot>
|
||||
</swiper-item>
|
||||
<swiper-item @touchmove.stop="false">
|
||||
<slot name="tab3"></slot>
|
||||
</swiper-item>
|
||||
<swiper-item @touchmove.stop="false">
|
||||
<slot name="tab3"></slot>
|
||||
</swiper-item>
|
||||
<swiper-item @touchmove.stop="false">
|
||||
<slot name="tab4"></slot>
|
||||
</swiper-item>
|
||||
<swiper-item @touchmove.stop="false">
|
||||
<slot name="tab5"></slot>
|
||||
</swiper-item>
|
||||
<swiper-item @touchmove.stop="false">
|
||||
<slot name="tab6"></slot>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'tab',
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
props: {
|
||||
current: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.tab-container
|
||||
// flex: 1
|
||||
height: 100%
|
||||
width: 100%
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
flex-direction: row
|
||||
.uni-margin-wrap
|
||||
width: 100%
|
||||
height: 100%
|
||||
.swiper
|
||||
width: 100%
|
||||
height: 100%
|
||||
.swiper-item
|
||||
display: block;
|
||||
width: 100%
|
||||
height: 100%
|
||||
</style>
|
||||
@@ -1,490 +0,0 @@
|
||||
<template>
|
||||
<AppLayout title="AI+就业服务程序">
|
||||
<tabcontrolVue :current="tabCurrent">
|
||||
<template v-slot:tab0>
|
||||
<view class="login-content">
|
||||
<image class="logo" src="@/static/logo.png"></image>
|
||||
<view class="logo-title">就业</view>
|
||||
</view>
|
||||
<view class="btns">
|
||||
<button class="wxlogin" @click="loginTest">内测登录</button>
|
||||
<view class="wxaddress">{{ config.appInfo.areaName }}公共就业和人才服务中心</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-slot:tab1>
|
||||
<view class="content-one">
|
||||
<view>
|
||||
<view class="content-title">
|
||||
<view class="title-lf">
|
||||
<view class="lf-h1">请您完善求职名片</view>
|
||||
<view class="lf-text">个人信息仅用于推送优质内容</view>
|
||||
</view>
|
||||
<view class="title-ri">
|
||||
<text style="color: #256bfa">1</text>
|
||||
<text>/2</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-input" @click="changeExperience">
|
||||
<view class="input-titile">工作经验</view>
|
||||
<input
|
||||
class="input-con"
|
||||
v-model="state.experienceText"
|
||||
disabled
|
||||
placeholder="请选择您的工作经验"
|
||||
/>
|
||||
</view>
|
||||
<view class="content-sex">
|
||||
<view class="sex-titile">求职区域</view>
|
||||
<view class="sext-ri">
|
||||
<view
|
||||
class="sext-box"
|
||||
:class="{ 'sext-boxactive': fromValue.sex === 0 }"
|
||||
@click="changeSex(0)"
|
||||
>
|
||||
男
|
||||
</view>
|
||||
<view
|
||||
class="sext-box"
|
||||
:class="{ 'sext-boxactive': fromValue.sex === 1 }"
|
||||
@click="changeSex(1)"
|
||||
>
|
||||
女
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-input" @click="changeEducation">
|
||||
<view class="input-titile">学历</view>
|
||||
<input class="input-con" v-model="state.educationText" disabled placeholder="本科" />
|
||||
</view>
|
||||
<view class="content-input">
|
||||
<view class="input-titile">身份证</view>
|
||||
<input class="input-con2" v-model="fromValue.idcard" maxlength="18" placeholder="本科" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="next-btn" @tap="nextStep">下一步</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-slot:tab2>
|
||||
<view class="content-one">
|
||||
<view>
|
||||
<view class="content-title">
|
||||
<view class="title-lf">
|
||||
<view class="lf-h1">请您完善求职名片</view>
|
||||
<view class="lf-text">个人信息仅用于推送优质内容</view>
|
||||
</view>
|
||||
<view class="title-ri">
|
||||
<text style="color: #256bfa">2</text>
|
||||
<text>/2</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-input" @click="changeArea">
|
||||
<view class="input-titile">求职区域</view>
|
||||
<input
|
||||
class="input-con"
|
||||
v-model="state.areaText"
|
||||
disabled
|
||||
placeholder="请选择您的求职区域"
|
||||
/>
|
||||
</view>
|
||||
<view class="content-input" @click="changeJobs">
|
||||
<view class="input-titile">求职岗位</view>
|
||||
<input
|
||||
class="input-con"
|
||||
disabled
|
||||
v-if="!state.jobsText.length"
|
||||
placeholder="请选择您的求职岗位"
|
||||
/>
|
||||
<view class="input-nx" @click="changeJobs" v-else>
|
||||
<view class="nx-item" v-for="item in state.jobsText">{{ item }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content-input" @click="changeSalay">
|
||||
<view class="input-titile">期望薪资</view>
|
||||
<input
|
||||
class="input-con"
|
||||
v-model="state.salayText"
|
||||
disabled
|
||||
placeholder="请选择您的期望薪资"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="next-btn" @tap="complete">开启求职之旅</view>
|
||||
</view>
|
||||
</template>
|
||||
</tabcontrolVue>
|
||||
<SelectJobs ref="selectJobsModel"></SelectJobs>
|
||||
</AppLayout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import tabcontrolVue from './components/tabcontrol.vue';
|
||||
import SelectJobs from '@/components/selectJobs/selectJobs.vue';
|
||||
import { reactive, inject, watch, ref, onMounted } from 'vue';
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||
import useUserStore from '@/stores/useUserStore';
|
||||
import useDictStore from '@/stores/useDictStore';
|
||||
const { $api, navTo, config, IdCardValidator } = inject('globalFunction');
|
||||
const { loginSetToken, getUserResume } = useUserStore();
|
||||
const { getDictSelectOption, oneDictData } = useDictStore();
|
||||
const openSelectPopup = inject('openSelectPopup');
|
||||
// console.log(config.appInfo.areaName);
|
||||
// status
|
||||
const selectJobsModel = ref();
|
||||
const tabCurrent = ref(0);
|
||||
const salay = [2, 5, 10, 15, 20, 25, 30, 50, 80, 100];
|
||||
const state = reactive({
|
||||
station: [],
|
||||
stationCateLog: 1,
|
||||
lfsalay: [2, 5, 10, 15, 20, 25, 30, 50],
|
||||
risalay: JSON.parse(JSON.stringify(salay)),
|
||||
areaText: '',
|
||||
educationText: '',
|
||||
experienceText: '',
|
||||
salayText: '',
|
||||
jobsText: [],
|
||||
});
|
||||
const fromValue = reactive({
|
||||
sex: 1,
|
||||
education: '4',
|
||||
salaryMin: 2000,
|
||||
salaryMax: 2000,
|
||||
area: 0,
|
||||
jobTitleId: '',
|
||||
experience: '1',
|
||||
idcard: '',
|
||||
});
|
||||
|
||||
onLoad((parmas) => {
|
||||
getTreeselect();
|
||||
});
|
||||
|
||||
onMounted(() => {});
|
||||
|
||||
function changeSex(sex) {
|
||||
fromValue.sex = sex;
|
||||
}
|
||||
function changeExperience() {
|
||||
openSelectPopup({
|
||||
title: '工作经验',
|
||||
maskClick: true,
|
||||
data: [oneDictData('experience')],
|
||||
success: (_, [value]) => {
|
||||
fromValue.experience = value.value;
|
||||
state.experienceText = value.label;
|
||||
},
|
||||
change(_, [value]) {
|
||||
// this.setColunm(1, [123, 123]);
|
||||
console.log(this);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function changeEducation() {
|
||||
openSelectPopup({
|
||||
title: '学历',
|
||||
maskClick: true,
|
||||
data: [oneDictData('education')],
|
||||
success: (_, [value]) => {
|
||||
fromValue.area = value.value;
|
||||
state.educationText = value.label;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function changeArea() {
|
||||
openSelectPopup({
|
||||
title: '区域',
|
||||
maskClick: true,
|
||||
data: [oneDictData('area')],
|
||||
success: (_, [value]) => {
|
||||
fromValue.area = value.value;
|
||||
state.areaText = config.appInfo.areaName + '-' + value.label;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function changeSalay() {
|
||||
let leftIndex = 0;
|
||||
openSelectPopup({
|
||||
title: '薪资',
|
||||
maskClick: true,
|
||||
data: [state.lfsalay, state.risalay],
|
||||
unit: 'k',
|
||||
success: (_, [min, max]) => {
|
||||
fromValue.salaryMin = min.value * 1000;
|
||||
fromValue.salaryMax = max.value * 1000;
|
||||
state.salayText = `${fromValue.salaryMin}-${fromValue.salaryMax}`;
|
||||
},
|
||||
change(e) {
|
||||
const salayData = e.detail.value;
|
||||
if (leftIndex !== salayData[0]) {
|
||||
const copyri = JSON.parse(JSON.stringify(salay));
|
||||
const [lf, ri] = e.detail.value;
|
||||
const risalay = copyri.slice(lf, copyri.length);
|
||||
this.setColunm(1, risalay);
|
||||
leftIndex = salayData[0];
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function changeJobs() {
|
||||
selectJobsModel.value?.open({
|
||||
title: '添加岗位',
|
||||
success: (ids, labels) => {
|
||||
fromValue.jobTitleId = ids;
|
||||
state.jobsText = labels.split(',');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function nextStep() {
|
||||
tabCurrent.value += 1;
|
||||
}
|
||||
|
||||
// 获取职位
|
||||
function getTreeselect() {
|
||||
$api.createRequest('/app/common/jobTitle/treeselect', {}, 'GET').then((resData) => {
|
||||
state.station = resData.data;
|
||||
});
|
||||
}
|
||||
|
||||
// 登录
|
||||
function loginTest() {
|
||||
// uni.share({
|
||||
// provider: 'weixin',
|
||||
// scene: 'WXSceneSession',
|
||||
// type: 2,
|
||||
// imageUrl: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni@2x.png',
|
||||
// success: function (res) {
|
||||
// console.log('success:' + JSON.stringify(res));
|
||||
// },
|
||||
// fail: function (err) {
|
||||
// console.log('fail:' + JSON.stringify(err));
|
||||
// },
|
||||
// });
|
||||
const params = {
|
||||
username: 'test',
|
||||
password: 'test',
|
||||
};
|
||||
$api.createRequest('/app/login', params, 'post').then((resData) => {
|
||||
$api.msg('模拟帐号密码测试登录成功');
|
||||
loginSetToken(resData.token).then((resume) => {
|
||||
if (resume.data.jobTitleId) {
|
||||
// 设置推荐列表,每次退出登录都需要更新
|
||||
useUserStore().initSeesionId();
|
||||
uni.reLaunch({
|
||||
url: '/packageRc/pages/daiban/daiban',
|
||||
});
|
||||
} else {
|
||||
nextStep();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function complete() {
|
||||
const result = IdCardValidator.validate(fromValue.idcard);
|
||||
if (result.valid) {
|
||||
$api.createRequest('/app/user/resume', fromValue, 'post').then((resData) => {
|
||||
$api.msg('完成');
|
||||
// 获取用户信息并存储到store中
|
||||
getUserResume().then((userInfo) => {
|
||||
console.log('用户信息已存储到store:', userInfo);
|
||||
uni.reLaunch({
|
||||
url: '/packageRc/pages/daiban/daiban',
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
$api.msg('身份证校验失败');
|
||||
console.log('验证失败:', result.message);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.input-nx
|
||||
position: relative
|
||||
border-bottom: 2rpx solid #EBEBEB
|
||||
padding-bottom: 30rpx
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
.nx-item
|
||||
padding: 20rpx 28rpx
|
||||
width: fit-content
|
||||
border-radius: 12rpx 12rpx 12rpx 12rpx;
|
||||
border: 2rpx solid #E8EAEE;
|
||||
margin-right: 24rpx
|
||||
margin-top: 24rpx
|
||||
.nx-item::before
|
||||
position: absolute;
|
||||
right: 20rpx;
|
||||
top: 60rpx;
|
||||
content: '';
|
||||
width: 4rpx;
|
||||
height: 18rpx;
|
||||
border-radius: 2rpx
|
||||
background: #697279;
|
||||
transform: translate(0, -50%) rotate(-45deg) ;
|
||||
.nx-item::after
|
||||
position: absolute;
|
||||
right: 20rpx;
|
||||
top: 61rpx;
|
||||
content: '';
|
||||
width: 4rpx;
|
||||
height: 18rpx;
|
||||
border-radius: 2rpx
|
||||
background: #697279;
|
||||
transform: rotate(45deg)
|
||||
.container
|
||||
// background: linear-gradient(#4778EC, #002979);
|
||||
width: 100%;
|
||||
height: calc(100vh - var(--window-top) - var(--status-bar-height) - var(--window-bottom));
|
||||
position: fixed;
|
||||
background: url('@/static/icon/background2.png') 0 0 no-repeat;
|
||||
background-size: 100% 728rpx;
|
||||
display: flex;
|
||||
flex-direction: column
|
||||
.container-hader
|
||||
height: 88rpx;
|
||||
text-align: center;
|
||||
line-height: 88rpx;
|
||||
color: #000000;
|
||||
font-weight: bold
|
||||
font-size: 32rpx
|
||||
|
||||
.login-content
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 40%;
|
||||
transform: translate(-50%, -50%);
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
flex-wrap: nowrap;
|
||||
.logo
|
||||
width: 266rpx;
|
||||
height: 182rpx;
|
||||
.logo-title
|
||||
font-size: 88rpx;
|
||||
color: #22c984;
|
||||
width: 180rpx;
|
||||
.btns
|
||||
position: absolute;
|
||||
top: 70%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0)
|
||||
.wxlogin
|
||||
width: 562rpx;
|
||||
height: 140rpx;
|
||||
border-radius: 70rpx;
|
||||
background-color: #13C57C;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
line-height: 140rpx;
|
||||
font-size: 70rpx;
|
||||
.wxaddress
|
||||
color: #BBBBBB;
|
||||
margin-top: 70rpx;
|
||||
text-align: center;
|
||||
.content-one
|
||||
padding: 60rpx 28rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between
|
||||
height: calc(100% - 120rpx)
|
||||
.content-title
|
||||
display: flex
|
||||
justify-content: space-between;
|
||||
align-items: center
|
||||
margin-bottom: 70rpx
|
||||
.title-lf
|
||||
font-size: 44rpx;
|
||||
color: #000000;
|
||||
font-weight: 600;
|
||||
.lf-text
|
||||
font-weight: 400;
|
||||
font-size: 28rpx;
|
||||
color: #6C7282;
|
||||
.title-ri
|
||||
font-size: 36rpx;
|
||||
color: #000000;
|
||||
font-weight: 600;
|
||||
.content-input
|
||||
margin-bottom: 52rpx
|
||||
.input-titile
|
||||
font-weight: 400;
|
||||
font-size: 28rpx;
|
||||
color: #6A6A6A;
|
||||
.input-con2
|
||||
font-weight: 400;
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
line-height: 80rpx;
|
||||
height: 80rpx;
|
||||
border-bottom: 2rpx solid #EBEBEB
|
||||
.input-con
|
||||
font-weight: 400;
|
||||
font-size: 32rpx;
|
||||
color: #333333;
|
||||
line-height: 80rpx;
|
||||
height: 80rpx;
|
||||
border-bottom: 2rpx solid #EBEBEB
|
||||
position: relative;
|
||||
.input-con::before
|
||||
position: absolute;
|
||||
right: 20rpx;
|
||||
top: calc(50% - 2rpx);
|
||||
content: '';
|
||||
width: 4rpx;
|
||||
height: 18rpx;
|
||||
border-radius: 2rpx
|
||||
background: #697279;
|
||||
transform: translate(0, -50%) rotate(-45deg) ;
|
||||
.input-con::after
|
||||
position: absolute;
|
||||
right: 20rpx;
|
||||
top: 50%;
|
||||
content: '';
|
||||
width: 4rpx;
|
||||
height: 18rpx;
|
||||
border-radius: 2rpx
|
||||
background: #697279;
|
||||
transform: rotate(45deg)
|
||||
.content-sex
|
||||
height: 110rpx;
|
||||
display: flex
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
border-bottom: 2rpx solid #EBEBEB
|
||||
margin-bottom: 52rpx
|
||||
.sex-titile
|
||||
line-height: 80rpx;
|
||||
.sext-ri
|
||||
display: flex
|
||||
align-items: center;
|
||||
.sext-box
|
||||
height: 76rpx;
|
||||
width: 152rpx;
|
||||
text-align: center;
|
||||
line-height: 80rpx;
|
||||
border-radius: 12rpx 12rpx 12rpx 12rpx
|
||||
border: 2rpx solid #E8EAEE;
|
||||
margin-left: 28rpx
|
||||
font-weight: 400;
|
||||
font-size: 28rpx;
|
||||
.sext-boxactive
|
||||
color: #256BFA
|
||||
background: rgba(37,107,250,0.1);
|
||||
border: 2rpx solid #256BFA;
|
||||
.next-btn
|
||||
width: 100%;
|
||||
height: 90rpx;
|
||||
background: #256BFA;
|
||||
border-radius: 12rpx 12rpx 12rpx 12rpx;
|
||||
font-weight: 500;
|
||||
font-size: 32rpx;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
line-height: 90rpx
|
||||
</style>
|
||||
363
pages/mine/company-info.vue
Normal file
363
pages/mine/company-info.vue
Normal file
@@ -0,0 +1,363 @@
|
||||
<template>
|
||||
<AppLayout back-gorund-color="#F4F4F4">
|
||||
<!-- 编辑头像 -->
|
||||
<view class="avatar-section btn-feel" @click="editAvatar">
|
||||
<view class="avatar-label">编辑信息</view>
|
||||
<view class="avatar-container">
|
||||
<image class="company-avatar" :src="companyInfo.avatar || '/static/imgs/avatar.jpg'"></image>
|
||||
<uni-icons color="#A2A2A2" type="right" size="16"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 企业详细信息 -->
|
||||
<view class="info-section">
|
||||
<view class="info-item btn-feel" @click="editInfo('name')">
|
||||
<view class="info-label">企业名称</view>
|
||||
<view class="info-content">
|
||||
<text class="info-value">{{ companyInfo.name || '暂无公司名称' }}</text>
|
||||
<uni-icons color="#A2A2A2" type="right" size="16"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="info-item btn-feel" @click="editInfo('code')">
|
||||
<view class="info-label">统一社会代码</view>
|
||||
<view class="info-content">
|
||||
<text class="info-value">{{ companyInfo.socialCode || '暂无统一社会代码' }}</text>
|
||||
<uni-icons color="#A2A2A2" type="right" size="16"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="info-item btn-feel" @click="editInfo('location')">
|
||||
<view class="info-label">企业注册地点</view>
|
||||
<view class="info-content">
|
||||
<text class="info-value">{{ companyInfo.location || '暂无注册地点' }}</text>
|
||||
<uni-icons color="#A2A2A2" type="right" size="16"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="info-item btn-feel" @click="editInfo('description')">
|
||||
<view class="info-label">企业信息介绍</view>
|
||||
<view class="info-content">
|
||||
<text class="info-value">{{ companyInfo.description || '暂无企业介绍' }}</text>
|
||||
<uni-icons color="#A2A2A2" type="right" size="16"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="info-item btn-feel" @click="editInfo('legalPerson')">
|
||||
<view class="info-label">企业法人姓名</view>
|
||||
<view class="info-content">
|
||||
<text class="info-value">{{ companyInfo.legalPerson || '暂无法人信息' }}</text>
|
||||
<uni-icons color="#A2A2A2" type="right" size="16"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 企业联系人管理 -->
|
||||
<view class="contact-management-section">
|
||||
<view class="contact-section-header">
|
||||
<view class="contact-section-title">企业联系人</view>
|
||||
<view class="edit-contacts-btn btn-feel" @click="editContacts">
|
||||
<uni-icons type="compose" size="16" color="#256BFA"></uni-icons>
|
||||
<text class="edit-text">编辑联系人</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 联系人列表展示 -->
|
||||
<view v-for="(contact, index) in companyInfo.companyContactList" :key="contact.id || index" class="contact-display-item">
|
||||
<view class="contact-display-title">联系人{{ index + 1 }}</view>
|
||||
<view class="contact-display-content">
|
||||
<view class="contact-field">
|
||||
<text class="field-label">姓名:</text>
|
||||
<text class="field-value">{{ contact.contactPerson || '暂无' }}</text>
|
||||
</view>
|
||||
<view class="contact-field">
|
||||
<text class="field-label">电话:</text>
|
||||
<text class="field-value">{{ contact.contactPersonPhone || '暂无' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 如果没有联系人,显示提示 -->
|
||||
<view v-if="!companyInfo.companyContactList || companyInfo.companyContactList.length === 0" class="no-contacts">
|
||||
<text class="no-contacts-text">暂无联系人信息</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</AppLayout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, inject, onMounted } from 'vue';
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||
import AppLayout from '@/components/AppLayout/AppLayout.vue';
|
||||
|
||||
const { $api, navTo } = inject('globalFunction');
|
||||
|
||||
// 企业信息数据
|
||||
const companyInfo = reactive({
|
||||
name: '',
|
||||
avatar: '/static/imgs/avatar.jpg',
|
||||
completeness: '65%',
|
||||
socialCode: '',
|
||||
location: '',
|
||||
description: '',
|
||||
legalPerson: '',
|
||||
companyContactList: [], // 企业联系人列表
|
||||
isVerified: false // 实名状态
|
||||
});
|
||||
|
||||
function editAvatar() {
|
||||
// 编辑头像逻辑
|
||||
// uni.chooseImage({
|
||||
// count: 1,
|
||||
// success: (res) => {
|
||||
// // 上传头像
|
||||
// uploadAvatar(res.tempFilePaths[0]);
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
function uploadAvatar(filePath) {
|
||||
// 上传头像到服务器
|
||||
uni.uploadFile({
|
||||
url: '/api/upload/avatar',
|
||||
filePath: filePath,
|
||||
name: 'avatar',
|
||||
success: (res) => {
|
||||
const data = JSON.parse(res.data);
|
||||
if (data.success) {
|
||||
companyInfo.avatar = data.data.url;
|
||||
uni.showToast({
|
||||
title: '头像更新成功',
|
||||
icon: 'success'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function editInfo(type) {
|
||||
// 根据类型跳转到不同的编辑页面
|
||||
const editPages = {
|
||||
name: '/pages/mine/edit-company-name',
|
||||
code: '/pages/mine/edit-company-code',
|
||||
location: '/pages/mine/edit-company-location',
|
||||
description: '/pages/mine/edit-company-description',
|
||||
legalPerson: '/pages/mine/edit-legal-person'
|
||||
};
|
||||
|
||||
if (editPages[type]) {
|
||||
navTo(editPages[type]);
|
||||
}
|
||||
}
|
||||
|
||||
function editContacts() {
|
||||
// 跳转到联系人编辑页面
|
||||
navTo('/pages/mine/edit-company-contacts');
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
// 获取企业信息
|
||||
getCompanyInfo();
|
||||
});
|
||||
|
||||
// 从缓存获取公司信息
|
||||
function getCompanyInfo() {
|
||||
try {
|
||||
const cachedUserInfo = uni.getStorageSync('userInfo') || {};
|
||||
console.log('缓存中的userInfo:', cachedUserInfo);
|
||||
|
||||
// 检查是否有company字段
|
||||
if (cachedUserInfo.company) {
|
||||
const company = cachedUserInfo.company;
|
||||
|
||||
// 基本信息
|
||||
companyInfo.name = company.name || '';
|
||||
companyInfo.socialCode = company.code || '';
|
||||
companyInfo.location = company.registeredAddress || '';
|
||||
companyInfo.description = company.description || '';
|
||||
companyInfo.legalPerson = company.legalPerson || '';
|
||||
|
||||
// 联系人信息 - 直接使用companyContactList数组
|
||||
companyInfo.companyContactList = company.companyContactList || [];
|
||||
|
||||
// 判断是否实名:legalIdCard字段有值则表示已实名
|
||||
companyInfo.isVerified = !!(company.legalIdCard && company.legalIdCard.trim());
|
||||
|
||||
console.log('公司名称:', companyInfo.name);
|
||||
console.log('实名状态:', companyInfo.isVerified);
|
||||
console.log('legalIdCard值:', company.legalIdCard);
|
||||
} else {
|
||||
console.log('缓存中没有company字段');
|
||||
// 保持默认值
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取公司信息失败:', error);
|
||||
// 保持默认值
|
||||
}
|
||||
}
|
||||
|
||||
function goBack() {
|
||||
uni.navigateBack();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
|
||||
.avatar-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 30rpx;
|
||||
background: #FFFFFF;
|
||||
margin: 20rpx;
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||||
|
||||
.avatar-label {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.avatar-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.company-avatar {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.info-section {
|
||||
background: #FFFFFF;
|
||||
margin: 0 20rpx 40rpx;
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 30rpx;
|
||||
border-bottom: 1rpx solid #F5F5F5;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 28rpx;
|
||||
color: #6C7282;
|
||||
min-width: 200rpx;
|
||||
}
|
||||
|
||||
.info-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
|
||||
.info-value {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
margin-right: 16rpx;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-feel {
|
||||
transition: transform 0.2s ease;
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
}
|
||||
|
||||
.contact-management-section {
|
||||
border-top: 20rpx solid #F4F4F4;
|
||||
|
||||
.contact-section-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20rpx 30rpx;
|
||||
background: #F8F8F8;
|
||||
border-bottom: 1rpx solid #F5F5F5;
|
||||
|
||||
.contact-section-title {
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.edit-contacts-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8rpx 16rpx;
|
||||
background: #E6F7FF;
|
||||
border-radius: 8rpx;
|
||||
|
||||
.edit-text {
|
||||
font-size: 24rpx;
|
||||
color: #256BFA;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.contact-display-item {
|
||||
padding: 20rpx 30rpx;
|
||||
border-bottom: 1rpx solid #F5F5F5;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.contact-display-title {
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.contact-display-content {
|
||||
.contact-field {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 12rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.field-label {
|
||||
font-size: 26rpx;
|
||||
color: #6C7282;
|
||||
min-width: 120rpx;
|
||||
}
|
||||
|
||||
.field-value {
|
||||
font-size: 26rpx;
|
||||
color: #333333;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-contacts {
|
||||
padding: 40rpx 30rpx;
|
||||
text-align: center;
|
||||
|
||||
.no-contacts-text {
|
||||
font-size: 26rpx;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
285
pages/mine/company-mine.vue
Normal file
285
pages/mine/company-mine.vue
Normal file
@@ -0,0 +1,285 @@
|
||||
<template>
|
||||
<AppLayout back-gorund-color="#F4F4F4">
|
||||
<!-- 自定义tabbar -->
|
||||
<CustomTabBar :currentPage="4" />
|
||||
|
||||
<!-- 企业信息卡片 -->
|
||||
<view class="company-info-card btn-feel" @click="goToCompanyInfo">
|
||||
<view class="company-avatar">
|
||||
<image class="company-avatar-img" :src="companyInfo.avatar || '/static/imgs/avatar.jpg'"></image>
|
||||
</view>
|
||||
<view class="company-details">
|
||||
<view class="company-name">{{ companyInfo.name || '暂无公司名称' }}</view>
|
||||
<view class="company-completeness">
|
||||
信息完整度 {{ companyInfo.completeness || '100%' }}
|
||||
<text class="verification-status" :class="{ 'verified': companyInfo.isVerified, 'unverified': !companyInfo.isVerified }">
|
||||
{{ companyInfo.isVerified ? '已实名' : '未实名' }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="company-arrow">
|
||||
<uni-icons color="#A2A2A2" type="right" size="16"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 服务专区 -->
|
||||
<view class="service-zone-card">
|
||||
<view class="service-title">服务专区</view>
|
||||
<view class="service-item btn-feel">
|
||||
<view class="service-left">
|
||||
<uni-icons type="contact" size="20" color="#256BFA"></uni-icons>
|
||||
<text class="service-text">实名认证</text>
|
||||
</view>
|
||||
<view class="service-status" :class="{ 'verified': companyInfo.isVerified, 'unverified': !companyInfo.isVerified }">
|
||||
{{ companyInfo.isVerified ? '已通过' : '未认证' }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="service-item btn-feel">
|
||||
<view class="service-left">
|
||||
<uni-icons type="notification" size="20" color="#256BFA"></uni-icons>
|
||||
<text class="service-text">通知与提醒</text>
|
||||
</view>
|
||||
<view class="service-status">已开启</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 退出登录按钮 -->
|
||||
<view class="logout-btn btn-feel" @click="logOut">
|
||||
退出登录
|
||||
</view>
|
||||
|
||||
<!-- 退出确认弹窗 -->
|
||||
<uni-popup ref="popup" type="dialog">
|
||||
<uni-popup-dialog
|
||||
mode="base"
|
||||
title="确定退出登录吗?"
|
||||
type="info"
|
||||
:duration="2000"
|
||||
:before-close="true"
|
||||
@confirm="confirm"
|
||||
@close="close"
|
||||
></uni-popup-dialog>
|
||||
</uni-popup>
|
||||
</AppLayout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, inject, ref, onMounted, onUnmounted } from 'vue';
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||
import useUserStore from '@/stores/useUserStore';
|
||||
|
||||
const { $api, navTo } = inject('globalFunction');
|
||||
const popup = ref(null);
|
||||
|
||||
// 企业信息数据
|
||||
const companyInfo = reactive({
|
||||
name: '',
|
||||
avatar: '/static/imgs/avatar.jpg',
|
||||
completeness: '100%',
|
||||
isVerified: false // 实名状态
|
||||
});
|
||||
|
||||
function goToCompanyInfo() {
|
||||
navTo('/pages/mine/company-info');
|
||||
}
|
||||
|
||||
function logOut() {
|
||||
popup.value.open();
|
||||
}
|
||||
|
||||
function close() {
|
||||
popup.value.close();
|
||||
}
|
||||
|
||||
function confirm() {
|
||||
// 调用退出登录
|
||||
useUserStore().logOut();
|
||||
// 关闭弹窗
|
||||
popup.value.close();
|
||||
// 跳转到首页
|
||||
uni.reLaunch({
|
||||
url: '/pages/index/index'
|
||||
});
|
||||
}
|
||||
|
||||
onShow(() => {
|
||||
// 获取企业信息
|
||||
getCompanyInfo();
|
||||
});
|
||||
|
||||
// 监听退出登录事件,显示微信登录弹窗
|
||||
onMounted(() => {
|
||||
uni.$on('showLoginModal', () => {
|
||||
// 这里可以显示微信登录弹窗
|
||||
// 由于这个页面没有 WxAuthLogin 组件,我们跳转到首页让首页处理
|
||||
uni.reLaunch({
|
||||
url: '/pages/index/index'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
uni.$off('showLoginModal');
|
||||
});
|
||||
|
||||
// 从缓存获取公司信息
|
||||
function getCompanyInfo() {
|
||||
try {
|
||||
const cachedUserInfo = uni.getStorageSync('userInfo') || {};
|
||||
console.log('缓存中的userInfo:', cachedUserInfo);
|
||||
|
||||
// 检查是否有company字段
|
||||
if (cachedUserInfo.company) {
|
||||
companyInfo.name = cachedUserInfo.company.name || '';
|
||||
// 判断是否实名:legalIdCard字段有值则表示已实名
|
||||
companyInfo.isVerified = !!(cachedUserInfo.company.legalIdCard && cachedUserInfo.company.legalIdCard.trim());
|
||||
console.log('公司名称:', companyInfo.name);
|
||||
console.log('实名状态:', companyInfo.isVerified);
|
||||
console.log('legalIdCard值:', cachedUserInfo.company.legalIdCard);
|
||||
} else {
|
||||
console.log('缓存中没有company字段');
|
||||
companyInfo.name = '';
|
||||
companyInfo.isVerified = false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取公司信息失败:', error);
|
||||
companyInfo.name = '';
|
||||
companyInfo.isVerified = false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.company-info-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 30rpx;
|
||||
background: #FFFFFF;
|
||||
margin: 20rpx;
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||||
|
||||
.company-avatar {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
margin-right: 24rpx;
|
||||
|
||||
.company-avatar-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.company-details {
|
||||
flex: 1;
|
||||
|
||||
.company-name {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.company-completeness {
|
||||
font-size: 28rpx;
|
||||
color: #6C7282;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
|
||||
.verification-status {
|
||||
font-size: 24rpx;
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 12rpx;
|
||||
|
||||
&.verified {
|
||||
background-color: #E8F5E8;
|
||||
color: #52C41A;
|
||||
}
|
||||
|
||||
&.unverified {
|
||||
background-color: #FFF2E8;
|
||||
color: #FA8C16;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.company-arrow {
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.service-zone-card {
|
||||
background: #FFFFFF;
|
||||
margin: 0 20rpx 20rpx;
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||||
padding: 32rpx;
|
||||
|
||||
.service-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #000000;
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.service-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 24rpx 0;
|
||||
border-bottom: 1rpx solid #F5F5F5;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.service-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.service-text {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.service-status {
|
||||
font-size: 28rpx;
|
||||
color: #6E6E6E;
|
||||
|
||||
&.verified {
|
||||
color: #52C41A;
|
||||
}
|
||||
|
||||
&.unverified {
|
||||
color: #FA8C16;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.logout-btn {
|
||||
height: 96rpx;
|
||||
background: #FFFFFF;
|
||||
margin: 0 20rpx 40rpx;
|
||||
border-radius: 20rpx;
|
||||
text-align: center;
|
||||
line-height: 96rpx;
|
||||
font-size: 28rpx;
|
||||
color: #256BFA;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.btn-feel {
|
||||
transition: transform 0.2s ease;
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
470
pages/mine/edit-company-contacts.vue
Normal file
470
pages/mine/edit-company-contacts.vue
Normal file
@@ -0,0 +1,470 @@
|
||||
<template>
|
||||
<AppLayout back-gorund-color="#F4F4F4">
|
||||
|
||||
<!-- 联系人列表 -->
|
||||
<view class="contacts-section">
|
||||
<view v-for="(contact, index) in contactList" :key="contact.tempId || contact.id" class="contact-item">
|
||||
<view class="contact-header">
|
||||
<text class="contact-title">联系人{{ index + 1 }}</text>
|
||||
<view class="contact-actions" v-if="contactList.length > 1">
|
||||
<view class="action-btn delete-btn" @click="deleteContact(index)">
|
||||
<uni-icons type="trash" size="16" color="#FF4D4F"></uni-icons>
|
||||
<text class="action-text">删除</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="contact-form">
|
||||
<view class="form-item">
|
||||
<view class="form-label">联系人姓名</view>
|
||||
<input
|
||||
class="form-input"
|
||||
v-model="contact.contactPerson"
|
||||
placeholder="请输入联系人姓名"
|
||||
@blur="validateContactName(index)"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="form-label">联系电话</view>
|
||||
<input
|
||||
class="form-input"
|
||||
v-model="contact.contactPersonPhone"
|
||||
placeholder="请输入联系电话"
|
||||
type="number"
|
||||
@blur="validateContactPhone(index)"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 添加联系人按钮 -->
|
||||
<view class="add-contact-section" v-if="contactList.length < 3">
|
||||
<view class="add-contact-btn btn-feel" @click="addContact">
|
||||
<uni-icons type="plus" size="20" color="#256BFA"></uni-icons>
|
||||
<text class="add-text">添加联系人</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 保存按钮 -->
|
||||
<view class="save-section">
|
||||
<view class="save-btn btn-feel" @click="saveContacts">
|
||||
<text class="save-text">保存联系人</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 提示信息 -->
|
||||
<view class="tips-section">
|
||||
<view class="tips-title">温馨提示</view>
|
||||
<view class="tips-content">
|
||||
<text class="tips-item">• 至少需要保留一个联系人,最多可添加3个联系人</text>
|
||||
<text class="tips-item">• 联系人姓名和电话为必填项</text>
|
||||
<text class="tips-item">• 联系电话请填写正确的手机号码</text>
|
||||
</view>
|
||||
</view>
|
||||
</AppLayout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, inject, ref, onMounted } from 'vue';
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||
import AppLayout from '@/components/AppLayout/AppLayout.vue';
|
||||
import { createRequest } from '@/utils/request.js';
|
||||
|
||||
const { navTo } = inject('globalFunction');
|
||||
|
||||
// 联系人列表数据
|
||||
const contactList = reactive([]);
|
||||
let tempIdCounter = 0; // 用于生成临时ID
|
||||
|
||||
// 页面加载时获取联系人数据
|
||||
onLoad((options) => {
|
||||
// 从缓存获取企业联系人信息
|
||||
loadContactsFromCache();
|
||||
});
|
||||
|
||||
// 从缓存加载联系人数据
|
||||
function loadContactsFromCache() {
|
||||
try {
|
||||
const cachedUserInfo = uni.getStorageSync('userInfo') || {};
|
||||
if (cachedUserInfo.company && cachedUserInfo.company.companyContactList) {
|
||||
const contacts = cachedUserInfo.company.companyContactList;
|
||||
|
||||
// 如果联系人列表为空,至少添加一个空联系人
|
||||
if (contacts.length === 0) {
|
||||
contactList.push(createEmptyContact());
|
||||
} else {
|
||||
// 为每个联系人添加临时ID(如果没有ID的话)
|
||||
contacts.forEach(contact => {
|
||||
if (!contact.tempId) {
|
||||
contact.tempId = `temp_${++tempIdCounter}`;
|
||||
}
|
||||
contactList.push({ ...contact });
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// 如果没有联系人数据,创建一个空联系人
|
||||
contactList.push(createEmptyContact());
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载联系人数据失败:', error);
|
||||
// 出错时至少创建一个空联系人
|
||||
contactList.push(createEmptyContact());
|
||||
}
|
||||
}
|
||||
|
||||
// 创建空联系人
|
||||
function createEmptyContact() {
|
||||
return {
|
||||
id: '',
|
||||
contactPerson: '',
|
||||
contactPersonPhone: '',
|
||||
tempId: `temp_${++tempIdCounter}`
|
||||
};
|
||||
}
|
||||
|
||||
// 添加联系人
|
||||
function addContact() {
|
||||
if (contactList.length >= 3) {
|
||||
uni.showToast({
|
||||
title: '最多只能添加3个联系人',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
contactList.push(createEmptyContact());
|
||||
}
|
||||
|
||||
// 删除联系人
|
||||
function deleteContact(index) {
|
||||
if (contactList.length <= 1) {
|
||||
uni.showToast({
|
||||
title: '至少需要保留一个联系人',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
uni.showModal({
|
||||
title: '确认删除',
|
||||
content: '确定要删除这个联系人吗?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
contactList.splice(index, 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 验证联系人姓名
|
||||
function validateContactName(index) {
|
||||
const contact = contactList[index];
|
||||
if (!contact.contactPerson || contact.contactPerson.trim() === '') {
|
||||
uni.showToast({
|
||||
title: '请输入联系人姓名',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 验证联系人电话
|
||||
function validateContactPhone(index) {
|
||||
const contact = contactList[index];
|
||||
if (!contact.contactPersonPhone || contact.contactPersonPhone.trim() === '') {
|
||||
uni.showToast({
|
||||
title: '请输入联系电话',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
// 简单的手机号验证
|
||||
const phoneRegex = /^1[3-9]\d{9}$/;
|
||||
if (!phoneRegex.test(contact.contactPersonPhone)) {
|
||||
uni.showToast({
|
||||
title: '请输入正确的手机号码',
|
||||
icon: 'none'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 验证所有联系人
|
||||
function validateAllContacts() {
|
||||
for (let i = 0; i < contactList.length; i++) {
|
||||
if (!validateContactName(i) || !validateContactPhone(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 保存联系人
|
||||
async function saveContacts() {
|
||||
// 验证所有联系人信息
|
||||
if (!validateAllContacts()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
uni.showLoading({
|
||||
title: '保存中...',
|
||||
mask: true
|
||||
});
|
||||
|
||||
// 获取companyId
|
||||
const companyId = getCompanyIdFromCache();
|
||||
if (!companyId) {
|
||||
uni.showToast({
|
||||
title: '获取企业信息失败,请重新登录',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 准备API数据,移除临时ID,添加companyId
|
||||
const apiData = contactList.map(contact => ({
|
||||
id: contact.id || '',
|
||||
contactPerson: contact.contactPerson.trim(),
|
||||
contactPersonPhone: contact.contactPersonPhone.trim(),
|
||||
companyId: companyId
|
||||
}));
|
||||
|
||||
// 调用API保存联系人
|
||||
const response = await createRequest(
|
||||
'/app/companycontact/batchInsertUpdate',
|
||||
{
|
||||
companyContactList: apiData
|
||||
},
|
||||
'POST',
|
||||
false
|
||||
);
|
||||
|
||||
if (response.code === 200) {
|
||||
// 保存成功,更新本地缓存
|
||||
updateLocalCache(apiData);
|
||||
|
||||
uni.showToast({
|
||||
title: '保存成功',
|
||||
icon: 'success'
|
||||
});
|
||||
|
||||
// 延迟返回上一页
|
||||
setTimeout(() => {
|
||||
goBack();
|
||||
}, 1500);
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: response.msg || '保存失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('保存联系人失败:', error);
|
||||
uni.showToast({
|
||||
title: '保存失败,请重试',
|
||||
icon: 'none'
|
||||
});
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
// 从缓存获取companyId
|
||||
function getCompanyIdFromCache() {
|
||||
try {
|
||||
const cachedUserInfo = uni.getStorageSync('userInfo') || {};
|
||||
if (cachedUserInfo.company && cachedUserInfo.company.companyId) {
|
||||
return cachedUserInfo.company.companyId;
|
||||
}
|
||||
return null;
|
||||
} catch (error) {
|
||||
console.error('获取companyId失败:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 更新本地缓存
|
||||
function updateLocalCache(contactData) {
|
||||
try {
|
||||
const cachedUserInfo = uni.getStorageSync('userInfo') || {};
|
||||
if (cachedUserInfo.company) {
|
||||
cachedUserInfo.company.companyContactList = contactData;
|
||||
uni.setStorageSync('userInfo', cachedUserInfo);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('更新本地缓存失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 返回上一页
|
||||
function goBack() {
|
||||
uni.navigateBack();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.save-section {
|
||||
margin: 0 20rpx 20rpx;
|
||||
|
||||
.save-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 88rpx;
|
||||
background: #256BFA;
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(37, 107, 250, 0.3);
|
||||
|
||||
.save-text {
|
||||
font-size: 32rpx;
|
||||
color: #FFFFFF;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.contacts-section {
|
||||
margin: 20rpx;
|
||||
|
||||
.contact-item {
|
||||
background: #FFFFFF;
|
||||
border-radius: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||||
|
||||
.contact-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 30rpx 30rpx 20rpx;
|
||||
border-bottom: 1rpx solid #F5F5F5;
|
||||
|
||||
.contact-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.contact-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.action-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8rpx 16rpx;
|
||||
border-radius: 8rpx;
|
||||
|
||||
&.delete-btn {
|
||||
background: #FFF2F0;
|
||||
|
||||
.action-text {
|
||||
font-size: 24rpx;
|
||||
color: #FF4D4F;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.contact-form {
|
||||
padding: 20rpx 30rpx 30rpx;
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
font-size: 26rpx;
|
||||
color: #6C7282;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
background: #F8F9FA;
|
||||
border: 1rpx solid #E9ECEF;
|
||||
border-radius: 12rpx;
|
||||
padding: 0 20rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:focus {
|
||||
border-color: #256BFA;
|
||||
background: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.add-contact-section {
|
||||
margin: 0 20rpx 20rpx;
|
||||
|
||||
.add-contact-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 88rpx;
|
||||
background: #FFFFFF;
|
||||
border: 2rpx dashed #256BFA;
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||||
|
||||
.add-text {
|
||||
font-size: 28rpx;
|
||||
color: #256BFA;
|
||||
margin-left: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tips-section {
|
||||
margin: 0 20rpx 40rpx;
|
||||
padding: 30rpx;
|
||||
background: #F8F9FA;
|
||||
border-radius: 20rpx;
|
||||
|
||||
.tips-title {
|
||||
font-size: 26rpx;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.tips-content {
|
||||
.tips-item {
|
||||
display: block;
|
||||
font-size: 24rpx;
|
||||
color: #6C7282;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 8rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-feel {
|
||||
transition: transform 0.2s ease;
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,23 @@
|
||||
<template>
|
||||
<AppLayout title="我的" back-gorund-color="#F4F4F4">
|
||||
<view class="mine-userinfo btn-feel" @click="seeDetail">
|
||||
<!-- 自定义tabbar -->
|
||||
<CustomTabBar :currentPage="4" />
|
||||
<!-- 企业用户信息卡片 -->
|
||||
<view v-if="userType === 0" class="company-info-card btn-feel" @click="seeDetail">
|
||||
<view class="company-avatar">
|
||||
<image class="company-avatar-img" :src="companyInfo.avatar || '/static/icon/company-default.png'"></image>
|
||||
</view>
|
||||
<view class="company-details">
|
||||
<view class="company-name">{{ companyInfo.name || '科里喀什分公司' }}</view>
|
||||
<view class="company-completeness">信息完整度 {{ companyInfo.completeness || '100%' }}</view>
|
||||
</view>
|
||||
<view class="company-arrow">
|
||||
<uni-icons color="#A2A2A2" type="right" size="16"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 求职者用户信息卡片 -->
|
||||
<view v-else class="mine-userinfo btn-feel" @click="seeDetail">
|
||||
<view class="userindo-head">
|
||||
<image class="userindo-head-img" v-if="userInfo.sex === '0'" src="/static/icon/boy.png"></image>
|
||||
<image class="userindo-head-img" v-else src="/static/icon/girl.png"></image>
|
||||
@@ -83,7 +100,8 @@
|
||||
<view class="row-right">已开启</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="card-back button-click" @click="logOut">退出登录</view>
|
||||
<view v-if="userType === 2" class="card-help button-click" @click="goToJobHelper">求职帮</view>
|
||||
<view class="card-back button-click" @click="logOut">退出登录</view>
|
||||
<uni-popup ref="popup" type="dialog">
|
||||
<uni-popup-dialog
|
||||
mode="base"
|
||||
@@ -103,19 +121,56 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, inject, watch, ref, onMounted } from 'vue';
|
||||
import { reactive, inject, watch, ref, onMounted, onUnmounted, computed } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||
const { $api, navTo } = inject('globalFunction');
|
||||
import useUserStore from '@/stores/useUserStore';
|
||||
import { tabbarManager } from '@/utils/tabbarManager';
|
||||
const popup = ref(null);
|
||||
const { userInfo, Completion } = storeToRefs(useUserStore());
|
||||
const counts = ref({});
|
||||
|
||||
// 获取用户类型,参考首页的实现方式
|
||||
const userType = computed(() => {
|
||||
// 优先从store获取,如果为空则从缓存获取
|
||||
const storeIsCompanyUser = userInfo.value?.isCompanyUser;
|
||||
const cachedUserInfo = uni.getStorageSync('userInfo') || {};
|
||||
const cachedIsCompanyUser = cachedUserInfo.isCompanyUser;
|
||||
|
||||
// 获取用户类型:优先使用store中的isCompanyUser,如果store中没有,使用缓存中的isCompanyUser
|
||||
// 缓存中的值可能是字符串,需要转换为数值类型
|
||||
return storeIsCompanyUser !== undefined ? Number(storeIsCompanyUser) : Number(cachedIsCompanyUser);
|
||||
});
|
||||
|
||||
// 企业信息数据
|
||||
const companyInfo = reactive({
|
||||
name: '科里喀什分公司',
|
||||
avatar: '/static/icon/company-avatar.png',
|
||||
completeness: '100%'
|
||||
});
|
||||
function logOut() {
|
||||
popup.value.open();
|
||||
}
|
||||
onShow(() => {
|
||||
getUserstatistics();
|
||||
// 更新自定义tabbar选中状态
|
||||
tabbarManager.updateSelected(4);
|
||||
});
|
||||
|
||||
// 监听退出登录事件,显示微信登录弹窗
|
||||
onMounted(() => {
|
||||
uni.$on('showLoginModal', () => {
|
||||
// 这里可以显示微信登录弹窗
|
||||
// 由于这个页面没有 WxAuthLogin 组件,我们跳转到首页让首页处理
|
||||
uni.reLaunch({
|
||||
url: '/pages/index/index'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
uni.$off('showLoginModal');
|
||||
});
|
||||
|
||||
function close() {
|
||||
@@ -135,12 +190,19 @@ function getUserstatistics() {
|
||||
});
|
||||
}
|
||||
function seeDetail() {
|
||||
if (userInfo.isCompanyUser) {
|
||||
navTo('/packageA/pages/myResume/corporateInformation');
|
||||
if (userType === 0) {
|
||||
// 企业用户跳转到企业信息页面
|
||||
navTo('/pages/mine/company-info');
|
||||
} else {
|
||||
// 求职者用户跳转到简历页面
|
||||
navTo('/packageA/pages/myResume/myResume');
|
||||
}
|
||||
}
|
||||
|
||||
function goToJobHelper() {
|
||||
// 跳转到求职者信息补全页面
|
||||
navTo('/pages/complete-info/complete-info');
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
@@ -240,6 +302,16 @@ function seeDetail() {
|
||||
margin: 0
|
||||
}
|
||||
}
|
||||
.card-help{
|
||||
height: 96rpx;
|
||||
background: #FFFFFF;
|
||||
border-radius: 20rpx 20rpx 20rpx 20rpx;
|
||||
text-align: center;
|
||||
line-height: 96rpx;
|
||||
font-size: 28rpx;
|
||||
color: #256BFA;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
.card-back{
|
||||
height: 96rpx;
|
||||
background: #FFFFFF;
|
||||
@@ -321,4 +393,48 @@ function seeDetail() {
|
||||
border-radius: 2rpx
|
||||
background: #A2A2A2;
|
||||
transform: rotate(45deg)
|
||||
|
||||
// 企业信息卡片样式
|
||||
.company-info-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 30rpx;
|
||||
background: #FFFFFF;
|
||||
margin: 20rpx;
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||||
|
||||
.company-avatar {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
margin-right: 24rpx;
|
||||
|
||||
.company-avatar-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.company-details {
|
||||
flex: 1;
|
||||
|
||||
.company-name {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: #333333;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.company-completeness {
|
||||
font-size: 28rpx;
|
||||
color: #6C7282;
|
||||
}
|
||||
}
|
||||
|
||||
.company-arrow {
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -21,34 +21,45 @@
|
||||
<component :is="components[index]" :ref="(el) => handelComponentsRef(el, index)" />
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<ReadComponent v-show="currentIndex === 0" :ref="(el) => handelComponentsRef(el, index)" />
|
||||
<UnreadComponent v-show="currentIndex === 1" :ref="(el) => handelComponentsRef(el, index)" />
|
||||
<ReadComponent v-show="state.current === 0" :ref="(el) => handelComponentsRef(el, index)" />
|
||||
<UnreadComponent v-show="state.current === 1" :ref="(el) => handelComponentsRef(el, index)" />
|
||||
<!-- #endif -->
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
|
||||
<!-- 自定义tabbar -->
|
||||
<CustomTabBar :currentPage="3" />
|
||||
|
||||
<!-- 微信授权登录弹窗 -->
|
||||
<WxAuthLogin ref="wxAuthLoginRef" @success="handleLoginSuccess"></WxAuthLogin>
|
||||
|
||||
<!-- 统一使用系统tabBar -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, inject, watch, ref, onMounted } from 'vue';
|
||||
import { reactive, inject, watch, ref, onMounted, onUnmounted } from 'vue';
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||
import Tabbar from '@/components/tabbar/midell-box.vue';
|
||||
import ReadComponent from './read.vue';
|
||||
import UnreadComponent from './unread.vue';
|
||||
import { tabbarManager } from '@/utils/tabbarManager';
|
||||
import WxAuthLogin from '@/components/WxAuthLogin/WxAuthLogin.vue';
|
||||
const loadedMap = reactive([false, false]);
|
||||
const swiperRefs = [ref(null), ref(null)];
|
||||
const components = [ReadComponent, UnreadComponent];
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useReadMsg } from '@/stores/useReadMsg';
|
||||
const { unreadCount } = storeToRefs(useReadMsg());
|
||||
const wxAuthLoginRef = ref(null);
|
||||
|
||||
onShow(() => {
|
||||
// 获取消息列表
|
||||
useReadMsg().fetchMessages();
|
||||
// 更新自定义tabbar选中状态
|
||||
tabbarManager.updateSelected(3);
|
||||
});
|
||||
const state = reactive({
|
||||
current: 0,
|
||||
@@ -57,8 +68,23 @@ const state = reactive({
|
||||
|
||||
onMounted(() => {
|
||||
handleTabChange(state.current);
|
||||
|
||||
// 监听退出登录事件,显示微信登录弹窗
|
||||
uni.$on('showLoginModal', () => {
|
||||
wxAuthLoginRef.value?.open();
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
uni.$off('showLoginModal');
|
||||
});
|
||||
|
||||
// 登录成功回调
|
||||
const handleLoginSuccess = () => {
|
||||
console.log('登录成功');
|
||||
// 可以在这里添加登录成功后的处理逻辑
|
||||
};
|
||||
|
||||
const handelComponentsRef = (el, index) => {
|
||||
if (el) {
|
||||
swiperRefs[index].value = el;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<scroll-view scroll-y class="main-scroll">
|
||||
<view class="scrollmain">
|
||||
<!-- 消息列表 -->
|
||||
<view
|
||||
class="list-card press-button"
|
||||
v-for="(item, index) in msgList"
|
||||
@@ -35,6 +36,13 @@
|
||||
<view class="info-text line_2">{{ item.subTitle || '消息' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 暂无消息提示 -->
|
||||
<view class="empty-state" v-if="msgList.length === 0">
|
||||
<image class="empty-icon" src="/static/icon/empty.png" mode="aspectFit"></image>
|
||||
<text class="empty-text">暂无消息</text>
|
||||
<text class="empty-desc">您还没有收到任何消息</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</template>
|
||||
@@ -146,4 +154,26 @@ defineExpose({ loadData });
|
||||
font-size: 28rpx;
|
||||
color: #6C7282;
|
||||
margin-top: 4rpx;
|
||||
|
||||
// 空状态样式
|
||||
.empty-state
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 120rpx 40rpx;
|
||||
.empty-icon
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
margin-bottom: 40rpx;
|
||||
opacity: 0.6;
|
||||
.empty-text
|
||||
font-size: 32rpx;
|
||||
color: #999999;
|
||||
font-weight: 500;
|
||||
margin-bottom: 16rpx;
|
||||
.empty-desc
|
||||
font-size: 28rpx;
|
||||
color: #CCCCCC;
|
||||
font-weight: 400;
|
||||
</style>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<scroll-view scroll-y class="main-scroll">
|
||||
<view class="scrollmain">
|
||||
<!-- 未读消息列表 -->
|
||||
<view
|
||||
class="list-card press-button"
|
||||
v-for="(item, index) in unreadMsgList"
|
||||
@@ -33,6 +34,13 @@
|
||||
<view class="info-text line_2">{{ item.subTitle || '消息' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 暂无未读消息提示 -->
|
||||
<view class="empty-state" v-if="unreadMsgList.length === 0">
|
||||
<image class="empty-icon" src="/static/icon/empty.png" mode="aspectFit"></image>
|
||||
<text class="empty-text">暂无未读消息</text>
|
||||
<text class="empty-desc">您没有未读的消息</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</template>
|
||||
@@ -132,4 +140,26 @@ defineExpose({ loadData });
|
||||
font-size: 28rpx;
|
||||
color: #6C7282;
|
||||
margin-top: 4rpx;
|
||||
|
||||
// 空状态样式
|
||||
.empty-state
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 120rpx 40rpx;
|
||||
.empty-icon
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
margin-bottom: 40rpx;
|
||||
opacity: 0.6;
|
||||
.empty-text
|
||||
font-size: 32rpx;
|
||||
color: #999999;
|
||||
font-weight: 500;
|
||||
margin-bottom: 16rpx;
|
||||
.empty-desc
|
||||
font-size: 28rpx;
|
||||
color: #CCCCCC;
|
||||
font-weight: 400;
|
||||
</style>
|
||||
|
||||
156
pages/test/company-mine-test.vue
Normal file
156
pages/test/company-mine-test.vue
Normal file
@@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<AppLayout title="企业我的页面测试" back-gorund-color="#F4F4F4">
|
||||
<view class="test-container">
|
||||
<view class="test-section">
|
||||
<view class="section-title">用户类型切换测试</view>
|
||||
<view class="button-group">
|
||||
<button class="test-btn" @click="switchToCompany">切换到企业用户</button>
|
||||
<button class="test-btn" @click="switchToJobSeeker">切换到求职者</button>
|
||||
</view>
|
||||
<view class="current-type">
|
||||
当前用户类型:{{ getCurrentTypeLabel() }} ({{ currentUserType }})
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="test-section">
|
||||
<view class="section-title">页面跳转测试</view>
|
||||
<view class="button-group">
|
||||
<button class="test-btn" @click="goToCompanyMine">企业我的页面</button>
|
||||
<button class="test-btn" @click="goToCompanyInfo">企业信息页面</button>
|
||||
<button class="test-btn" @click="goToMine">普通我的页面</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="test-section">
|
||||
<view class="section-title">用户信息显示</view>
|
||||
<view class="info-display">
|
||||
<text>用户类型:{{ userInfo.isCompanyUser }}</text>
|
||||
<text>用户名:{{ userInfo.name || '未设置' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</AppLayout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import useUserStore from '@/stores/useUserStore';
|
||||
|
||||
const userStore = useUserStore();
|
||||
const { userInfo } = storeToRefs(userStore);
|
||||
|
||||
const userTypes = [
|
||||
{ value: 0, label: '企业用户' },
|
||||
{ value: 1, label: '求职者' },
|
||||
{ value: 2, label: '网格员' },
|
||||
{ value: 3, label: '政府人员' }
|
||||
];
|
||||
|
||||
const currentUserType = computed(() => userInfo.value?.isCompanyUser !== undefined ? userInfo.value.isCompanyUser : 1);
|
||||
|
||||
const switchToCompany = () => {
|
||||
userInfo.value.isCompanyUser = 0;
|
||||
userInfo.value.name = '科里喀什分公司';
|
||||
uni.setStorageSync('userInfo', userInfo.value);
|
||||
uni.showToast({
|
||||
title: '已切换到企业用户',
|
||||
icon: 'success'
|
||||
});
|
||||
};
|
||||
|
||||
const switchToJobSeeker = () => {
|
||||
userInfo.value.isCompanyUser = 1;
|
||||
userInfo.value.name = '求职者用户';
|
||||
uni.setStorageSync('userInfo', userInfo.value);
|
||||
uni.showToast({
|
||||
title: '已切换到求职者',
|
||||
icon: 'success'
|
||||
});
|
||||
};
|
||||
|
||||
const getCurrentTypeLabel = () => {
|
||||
const type = userTypes.find(t => t.value === currentUserType.value);
|
||||
return type ? type.label : '未知';
|
||||
};
|
||||
|
||||
const goToCompanyMine = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mine/company-mine'
|
||||
});
|
||||
};
|
||||
|
||||
const goToCompanyInfo = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mine/company-info'
|
||||
});
|
||||
};
|
||||
|
||||
const goToMine = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/mine/mine'
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.test-container {
|
||||
padding: 40rpx;
|
||||
background: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.test-section {
|
||||
background: #fff;
|
||||
border-radius: 12rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.test-btn {
|
||||
background: #256BFA;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 8rpx;
|
||||
padding: 20rpx;
|
||||
font-size: 28rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.current-type {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
padding: 20rpx;
|
||||
background: #f8f8f8;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.info-display {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10rpx;
|
||||
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
padding: 10rpx;
|
||||
background: #f8f8f8;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
170
pages/test/company-search-test.vue
Normal file
170
pages/test/company-search-test.vue
Normal file
@@ -0,0 +1,170 @@
|
||||
<template>
|
||||
<view class="test-page">
|
||||
<view class="header">
|
||||
<text class="title">企业搜索功能测试</text>
|
||||
</view>
|
||||
|
||||
<view class="test-section">
|
||||
<view class="section-title">功能说明</view>
|
||||
<view class="description">
|
||||
<text class="desc-text">• 企业用户(isCompanyUser=0):招聘公司输入框为普通输入框</text>
|
||||
<text class="desc-text">• 网格员(isCompanyUser=2):招聘公司输入框为选择器,点击跳转到搜索页面</text>
|
||||
<text class="desc-text">• 搜索页面支持防抖节流,500ms延迟</text>
|
||||
<text class="desc-text">• 搜索接口:/app/company/likeList,参数:name</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="test-section">
|
||||
<view class="section-title">当前用户类型</view>
|
||||
<view class="user-type-info">
|
||||
<text class="type-label">用户类型:</text>
|
||||
<text class="type-value">{{ getCurrentTypeLabel() }} ({{ currentUserType }})</text>
|
||||
</view>
|
||||
<view class="user-type-info">
|
||||
<text class="type-label">是否企业用户:</text>
|
||||
<text class="type-value">{{ isCompanyUser ? '是' : '否' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="test-section">
|
||||
<view class="section-title">测试操作</view>
|
||||
<view class="button-group">
|
||||
<button class="test-btn" @click="switchToCompany">切换到企业用户</button>
|
||||
<button class="test-btn" @click="switchToGrid">切换到网格员</button>
|
||||
<button class="test-btn" @click="goToPublishJob">进入发布岗位页面</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import useUserStore from '@/stores/useUserStore';
|
||||
|
||||
const userStore = useUserStore();
|
||||
const { userInfo } = storeToRefs(userStore);
|
||||
|
||||
const userTypes = [
|
||||
{ value: 0, label: '企业用户' },
|
||||
{ value: 1, label: '求职者' },
|
||||
{ value: 2, label: '网格员' },
|
||||
{ value: 3, label: '政府人员' }
|
||||
];
|
||||
|
||||
const currentUserType = computed(() => userInfo.value?.isCompanyUser !== undefined ? userInfo.value.isCompanyUser : 1);
|
||||
|
||||
const isCompanyUser = computed(() => {
|
||||
return currentUserType.value === 0;
|
||||
});
|
||||
|
||||
const getCurrentTypeLabel = () => {
|
||||
const type = userTypes.find(t => t.value === currentUserType.value);
|
||||
return type ? type.label : '未知';
|
||||
};
|
||||
|
||||
const switchToCompany = () => {
|
||||
userInfo.value.isCompanyUser = 0;
|
||||
uni.setStorageSync('userInfo', userInfo.value);
|
||||
uni.showToast({
|
||||
title: '已切换到企业用户',
|
||||
icon: 'success'
|
||||
});
|
||||
};
|
||||
|
||||
const switchToGrid = () => {
|
||||
userInfo.value.isCompanyUser = 2;
|
||||
uni.setStorageSync('userInfo', userInfo.value);
|
||||
uni.showToast({
|
||||
title: '已切换到网格员',
|
||||
icon: 'success'
|
||||
});
|
||||
};
|
||||
|
||||
const goToPublishJob = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pages/job/publishJob'
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.test-page {
|
||||
padding: 40rpx;
|
||||
background: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.header {
|
||||
text-align: center;
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
.title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.test-section {
|
||||
background: #fff;
|
||||
border-radius: 12rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.description {
|
||||
.desc-text {
|
||||
display: block;
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.user-type-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 15rpx;
|
||||
|
||||
.type-label {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
.type-value {
|
||||
font-size: 28rpx;
|
||||
color: #256BFA;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20rpx;
|
||||
|
||||
.test-btn {
|
||||
height: 80rpx;
|
||||
background: #256BFA;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 12rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
|
||||
&:active {
|
||||
background: #1e5ce6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
296
pages/test/homepage-test.vue
Normal file
296
pages/test/homepage-test.vue
Normal file
@@ -0,0 +1,296 @@
|
||||
<template>
|
||||
<view class="homepage-test">
|
||||
<view class="header">
|
||||
<text class="title">首页内容测试</text>
|
||||
</view>
|
||||
|
||||
<view class="content">
|
||||
<view class="user-info">
|
||||
<text class="label">当前用户类型:</text>
|
||||
<text class="value">{{ getCurrentUserTypeLabel() }}</text>
|
||||
</view>
|
||||
|
||||
<view class="login-status">
|
||||
<text class="label">登录状态:</text>
|
||||
<text class="value" :class="{ 'logged-in': hasLogin, 'not-logged-in': !hasLogin }">
|
||||
{{ hasLogin ? '已登录' : '未登录' }}
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view class="debug-info">
|
||||
<text class="label">调试信息:</text>
|
||||
<text class="value">userType: {{ userInfo?.userType ?? 'undefined' }}</text>
|
||||
<text class="value">hasLogin: {{ hasLogin }}</text>
|
||||
<text class="value">shouldShowJobSeeker: {{ shouldShowJobSeekerContent }}</text>
|
||||
<text class="value">shouldShowCompany: {{ shouldShowCompanyContent }}</text>
|
||||
<text class="value">完整userInfo: {{ JSON.stringify(userInfo) }}</text>
|
||||
</view>
|
||||
|
||||
<view class="content-preview">
|
||||
<text class="section-title">首页内容预览:</text>
|
||||
|
||||
<view class="content-item" v-if="shouldShowJobSeekerContent">
|
||||
<text class="content-label">✅ 求职者内容</text>
|
||||
<text class="content-desc">• 附近工作卡片</text>
|
||||
<text class="content-desc">• 服务功能网格</text>
|
||||
<text class="content-desc">• 职位筛选器</text>
|
||||
</view>
|
||||
|
||||
<view class="content-item" v-if="shouldShowCompanyContent">
|
||||
<text class="content-label">✅ 企业用户内容</text>
|
||||
<text class="content-desc">• 企业服务标题</text>
|
||||
<text class="content-desc">• 发布岗位按钮</text>
|
||||
<text class="content-desc">• 企业管理功能</text>
|
||||
</view>
|
||||
|
||||
<view class="content-item" v-if="!shouldShowJobSeekerContent && !shouldShowCompanyContent">
|
||||
<text class="content-label">❌ 无内容显示</text>
|
||||
<text class="content-desc">请检查用户类型设置</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="test-buttons">
|
||||
<button @click="testLoginAsJobSeeker" class="test-btn">模拟求职者登录</button>
|
||||
<button @click="testLoginAsCompany" class="test-btn">模拟企业用户登录</button>
|
||||
<button @click="testLogout" class="test-btn" v-if="hasLogin">模拟登出</button>
|
||||
<button @click="forceRefreshUserInfo" class="test-btn">强制刷新用户信息</button>
|
||||
<button @click="clearUserInfo" class="test-btn">清除用户信息</button>
|
||||
<button @click="refreshTabBar" class="test-btn">刷新TabBar</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 自定义tabbar -->
|
||||
<CustomTabBar :currentPage="0" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import useUserStore from '@/stores/useUserStore';
|
||||
import { tabbarManager } from '@/utils/tabbarManager';
|
||||
|
||||
const userStore = useUserStore();
|
||||
const { userInfo, hasLogin } = storeToRefs(userStore);
|
||||
|
||||
const userTypes = [
|
||||
{ value: 0, label: '企业用户' },
|
||||
{ value: 1, label: '求职者' },
|
||||
{ value: 2, label: '网格员' },
|
||||
{ value: 3, label: '政府人员' }
|
||||
];
|
||||
|
||||
const currentUserType = computed(() => userInfo.value?.userType || 1);
|
||||
|
||||
const getCurrentUserTypeLabel = () => {
|
||||
const type = userTypes.find(t => t.value === currentUserType.value);
|
||||
return type ? type.label : '未知';
|
||||
};
|
||||
|
||||
// 计算是否显示求职者内容
|
||||
const shouldShowJobSeekerContent = computed(() => {
|
||||
if (!hasLogin.value) {
|
||||
return true;
|
||||
}
|
||||
const userType = userInfo.value?.isCompanyUser;
|
||||
return userType !== 0;
|
||||
});
|
||||
|
||||
// 计算是否显示企业用户内容
|
||||
const shouldShowCompanyContent = computed(() => {
|
||||
if (!hasLogin.value) {
|
||||
return false;
|
||||
}
|
||||
const userType = userInfo.value?.isCompanyUser;
|
||||
return userType === 0;
|
||||
});
|
||||
|
||||
const testLoginAsJobSeeker = () => {
|
||||
const mockUserInfo = {
|
||||
userType: 1,
|
||||
name: '求职者用户',
|
||||
id: 'jobseeker123'
|
||||
};
|
||||
userInfo.value = mockUserInfo;
|
||||
userStore.hasLogin = true;
|
||||
uni.setStorageSync('userInfo', mockUserInfo);
|
||||
uni.showToast({
|
||||
title: '模拟求职者登录成功',
|
||||
icon: 'success'
|
||||
});
|
||||
};
|
||||
|
||||
const testLoginAsCompany = () => {
|
||||
const mockUserInfo = {
|
||||
userType: 0,
|
||||
name: '企业用户',
|
||||
id: 'company123'
|
||||
};
|
||||
userInfo.value = mockUserInfo;
|
||||
userStore.hasLogin = true;
|
||||
uni.setStorageSync('userInfo', mockUserInfo);
|
||||
uni.showToast({
|
||||
title: '模拟企业用户登录成功',
|
||||
icon: 'success'
|
||||
});
|
||||
};
|
||||
|
||||
const testLogout = () => {
|
||||
userStore.logOut(false);
|
||||
uni.showToast({
|
||||
title: '模拟登出成功',
|
||||
icon: 'success'
|
||||
});
|
||||
};
|
||||
|
||||
const forceRefreshUserInfo = () => {
|
||||
// 从本地存储重新加载用户信息
|
||||
const cachedUserInfo = uni.getStorageSync('userInfo');
|
||||
if (cachedUserInfo) {
|
||||
userInfo.value = cachedUserInfo;
|
||||
userStore.hasLogin = true;
|
||||
uni.showToast({
|
||||
title: '用户信息已刷新',
|
||||
icon: 'success'
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '未找到用户信息',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const clearUserInfo = () => {
|
||||
// 清除所有用户信息
|
||||
uni.removeStorageSync('userInfo');
|
||||
uni.removeStorageSync('token');
|
||||
userInfo.value = {};
|
||||
userStore.hasLogin = false;
|
||||
uni.showToast({
|
||||
title: '用户信息已清除',
|
||||
icon: 'success'
|
||||
});
|
||||
};
|
||||
|
||||
const refreshTabBar = () => {
|
||||
// 刷新tabbar
|
||||
tabbarManager.refreshTabBar();
|
||||
uni.showToast({
|
||||
title: 'TabBar已刷新',
|
||||
icon: 'success'
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.homepage-test {
|
||||
padding: 40rpx;
|
||||
min-height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.header {
|
||||
text-align: center;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.content {
|
||||
background: white;
|
||||
border-radius: 20rpx;
|
||||
padding: 40rpx;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.user-info, .login-status, .debug-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 20rpx;
|
||||
padding: 20rpx;
|
||||
background: #f8f9fa;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.debug-info .value {
|
||||
font-size: 20rpx;
|
||||
color: #666;
|
||||
margin: 5rpx 0;
|
||||
display: block;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 28rpx;
|
||||
color: #256BFA;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.logged-in {
|
||||
color: #52c41a !important;
|
||||
}
|
||||
|
||||
.not-logged-in {
|
||||
color: #ff4d4f !important;
|
||||
}
|
||||
|
||||
.content-preview {
|
||||
margin: 30rpx 0;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
margin-bottom: 20rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.content-item {
|
||||
background: #f8f9fa;
|
||||
padding: 20rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.content-label {
|
||||
font-size: 24rpx;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.content-desc {
|
||||
font-size: 22rpx;
|
||||
color: #666;
|
||||
margin: 5rpx 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.test-buttons {
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
|
||||
.test-btn {
|
||||
margin: 10rpx 0;
|
||||
padding: 20rpx 30rpx;
|
||||
background: #256BFA;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 10rpx;
|
||||
font-size: 24rpx;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
293
pages/test/tabbar-test.vue
Normal file
293
pages/test/tabbar-test.vue
Normal file
@@ -0,0 +1,293 @@
|
||||
<template>
|
||||
<view class="tabbar-test">
|
||||
<view class="header">
|
||||
<text class="title">自定义TabBar测试页面</text>
|
||||
</view>
|
||||
|
||||
<view class="content">
|
||||
<view class="user-info">
|
||||
<text class="label">当前用户类型:</text>
|
||||
<text class="value">{{ getCurrentUserTypeLabel() }}</text>
|
||||
</view>
|
||||
|
||||
<view class="login-status">
|
||||
<text class="label">登录状态:</text>
|
||||
<text class="value" :class="{ 'logged-in': hasLogin, 'not-logged-in': !hasLogin }">
|
||||
{{ hasLogin ? '已登录' : '未登录' }}
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view class="debug-info">
|
||||
<text class="label">调试信息:</text>
|
||||
<text class="value">userType: {{ userInfo?.userType ?? 'undefined' }}</text>
|
||||
<text class="value">hasLogin: {{ hasLogin }}</text>
|
||||
<text class="value">shouldShowJobSeeker: {{ shouldShowJobSeekerContent }}</text>
|
||||
<text class="value">shouldShowCompany: {{ shouldShowCompanyContent }}</text>
|
||||
</view>
|
||||
|
||||
<view class="switch-section">
|
||||
<text class="section-title">切换用户类型:</text>
|
||||
<view class="switch-buttons">
|
||||
<button
|
||||
v-for="(type, index) in userTypes"
|
||||
:key="index"
|
||||
@click="switchUserType(type.value)"
|
||||
:class="{ active: currentUserType === type.value }"
|
||||
class="switch-btn"
|
||||
>
|
||||
{{ type.label }}
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="description">
|
||||
<text class="desc-title">功能说明:</text>
|
||||
<text class="desc-text">• 未登录状态:默认显示求职者tabbar(职位 + 招聘会 + AI+ + 消息 + 我的)</text>
|
||||
<text class="desc-text">• 企业用户(userType=0):显示"发布岗位"导航,隐藏"招聘会"</text>
|
||||
<text class="desc-text">• 求职者用户(userType=1,2,3):显示"招聘会"导航</text>
|
||||
<text class="desc-text">• 登录后根据用户角色自动切换对应的tabbar</text>
|
||||
<text class="desc-text">• 系统默认tabbar已被隐藏,使用自定义tabbar</text>
|
||||
</view>
|
||||
|
||||
<view class="test-section">
|
||||
<text class="section-title">测试功能:</text>
|
||||
<button @click="testHideTabBar" class="test-btn">检查系统TabBar状态</button>
|
||||
<button @click="testShowTabBar" class="test-btn">临时显示系统TabBar</button>
|
||||
<button @click="testLogin" class="test-btn" v-if="!hasLogin">模拟登录</button>
|
||||
<button @click="testLogout" class="test-btn" v-if="hasLogin">模拟登出</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 自定义tabbar -->
|
||||
<CustomTabBar :currentPage="0" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import useUserStore from '@/stores/useUserStore';
|
||||
|
||||
const userStore = useUserStore();
|
||||
const { userInfo, hasLogin } = storeToRefs(userStore);
|
||||
|
||||
const userTypes = [
|
||||
{ value: 0, label: '企业用户' },
|
||||
{ value: 1, label: '求职者' },
|
||||
{ value: 2, label: '网格员' },
|
||||
{ value: 3, label: '政府人员' }
|
||||
];
|
||||
|
||||
const currentUserType = computed(() => userInfo.value?.isCompanyUser !== undefined ? userInfo.value.isCompanyUser : 0);
|
||||
|
||||
const switchUserType = (userType) => {
|
||||
console.log('切换用户类型:', userType);
|
||||
userInfo.value.isCompanyUser = userType;
|
||||
// 更新到本地存储
|
||||
uni.setStorageSync('userInfo', userInfo.value);
|
||||
};
|
||||
|
||||
const getCurrentUserTypeLabel = () => {
|
||||
const type = userTypes.find(t => t.value === currentUserType.value);
|
||||
return type ? type.label : '未知';
|
||||
};
|
||||
|
||||
// 计算是否显示求职者内容
|
||||
const shouldShowJobSeekerContent = computed(() => {
|
||||
if (!hasLogin.value) {
|
||||
return true;
|
||||
}
|
||||
const userType = userInfo.value?.isCompanyUser;
|
||||
return userType !== 0;
|
||||
});
|
||||
|
||||
// 计算是否显示企业用户内容
|
||||
const shouldShowCompanyContent = computed(() => {
|
||||
if (!hasLogin.value) {
|
||||
return false;
|
||||
}
|
||||
const userType = userInfo.value?.isCompanyUser;
|
||||
return userType === 0;
|
||||
});
|
||||
|
||||
const testHideTabBar = () => {
|
||||
uni.hideTabBar();
|
||||
uni.showToast({
|
||||
title: '系统TabBar已隐藏',
|
||||
icon: 'success'
|
||||
});
|
||||
};
|
||||
|
||||
const testShowTabBar = () => {
|
||||
uni.showTabBar();
|
||||
uni.showToast({
|
||||
title: '系统TabBar已显示(测试用)',
|
||||
icon: 'none'
|
||||
});
|
||||
// 3秒后自动隐藏
|
||||
setTimeout(() => {
|
||||
uni.hideTabBar();
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
const testLogin = () => {
|
||||
// 模拟登录,设置用户信息
|
||||
const mockUserInfo = {
|
||||
userType: 1, // 默认设置为求职者
|
||||
name: '测试用户',
|
||||
id: 'test123'
|
||||
};
|
||||
userInfo.value = mockUserInfo;
|
||||
userStore.hasLogin = true;
|
||||
uni.setStorageSync('userInfo', mockUserInfo);
|
||||
uni.showToast({
|
||||
title: '模拟登录成功',
|
||||
icon: 'success'
|
||||
});
|
||||
};
|
||||
|
||||
const testLogout = () => {
|
||||
// 模拟登出,清除用户信息
|
||||
userStore.logOut(false);
|
||||
uni.showToast({
|
||||
title: '模拟登出成功',
|
||||
icon: 'success'
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tabbar-test {
|
||||
padding: 40rpx;
|
||||
min-height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.header {
|
||||
text-align: center;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.content {
|
||||
background: white;
|
||||
border-radius: 20rpx;
|
||||
padding: 40rpx;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.user-info, .login-status, .debug-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 20rpx;
|
||||
padding: 20rpx;
|
||||
background: #f8f9fa;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.debug-info .value {
|
||||
font-size: 20rpx;
|
||||
color: #666;
|
||||
margin: 5rpx 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 28rpx;
|
||||
color: #256BFA;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.switch-section {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.switch-buttons {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.switch-btn {
|
||||
padding: 20rpx 30rpx;
|
||||
background: #f0f0f0;
|
||||
border: none;
|
||||
border-radius: 10rpx;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.switch-btn.active {
|
||||
background: #256BFA;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.description {
|
||||
background: #f8f9fa;
|
||||
padding: 30rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.desc-title {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
margin-bottom: 20rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.desc-text {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 10rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.test-section {
|
||||
margin-top: 40rpx;
|
||||
background: #f8f9fa;
|
||||
padding: 30rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.test-btn {
|
||||
margin: 10rpx 0;
|
||||
padding: 20rpx 30rpx;
|
||||
background: #256BFA;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 10rpx;
|
||||
font-size: 24rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.logged-in {
|
||||
color: #52c41a !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.not-logged-in {
|
||||
color: #ff4d4f !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
232
pages/test/tabbar-user-type-test.vue
Normal file
232
pages/test/tabbar-user-type-test.vue
Normal file
@@ -0,0 +1,232 @@
|
||||
<template>
|
||||
<view class="test-page">
|
||||
<view class="header">
|
||||
<text class="title">TabBar用户类型切换测试</text>
|
||||
</view>
|
||||
|
||||
<view class="content">
|
||||
<view class="current-info">
|
||||
<text class="label">当前用户类型:</text>
|
||||
<text class="value">{{ getCurrentTypeLabel() }} ({{ currentUserType }})</text>
|
||||
</view>
|
||||
|
||||
<view class="type-switcher">
|
||||
<text class="section-title">切换用户类型:</text>
|
||||
<view class="buttons">
|
||||
<button
|
||||
v-for="(type, index) in userTypes"
|
||||
:key="index"
|
||||
:class="['btn', { active: currentUserType === type.value }]"
|
||||
@click="switchUserType(type.value)"
|
||||
>
|
||||
{{ type.label }}
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="tabbar-preview">
|
||||
<text class="section-title">TabBar预览:</text>
|
||||
<view class="tabbar-container">
|
||||
<view
|
||||
v-for="(item, index) in tabbarConfig"
|
||||
:key="index"
|
||||
class="tabbar-item"
|
||||
>
|
||||
<text class="tabbar-text">{{ item.text }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="description">
|
||||
<text class="desc-title">功能说明:</text>
|
||||
<text class="desc-text">• 企业用户(userType=0):显示"发布岗位"导航</text>
|
||||
<text class="desc-text">• 求职者(userType=1):显示"招聘会"导航</text>
|
||||
<text class="desc-text">• 网格员(userType=2):显示"招聘会"导航</text>
|
||||
<text class="desc-text">• 政府人员(userType=3):显示"招聘会"导航</text>
|
||||
<text class="desc-text">• 切换用户类型后,底部导航栏会自动更新</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import useUserStore from '@/stores/useUserStore';
|
||||
|
||||
const { userInfo } = storeToRefs(useUserStore());
|
||||
|
||||
const userTypes = [
|
||||
{ value: 0, label: '企业用户' },
|
||||
{ value: 1, label: '求职者' },
|
||||
{ value: 2, label: '网格员' },
|
||||
{ value: 3, label: '政府人员' }
|
||||
];
|
||||
|
||||
const currentUserType = computed(() => userInfo.value?.isCompanyUser !== undefined ? userInfo.value.isCompanyUser : 1);
|
||||
|
||||
const switchUserType = (userType) => {
|
||||
console.log('切换用户类型:', userType);
|
||||
userInfo.value.isCompanyUser = userType;
|
||||
uni.setStorageSync('userInfo', userInfo.value);
|
||||
uni.showToast({
|
||||
title: `已切换到${getCurrentTypeLabel()}`,
|
||||
icon: 'success'
|
||||
});
|
||||
};
|
||||
|
||||
const getCurrentTypeLabel = () => {
|
||||
const type = userTypes.find(t => t.value === currentUserType.value);
|
||||
return type ? type.label : '未知';
|
||||
};
|
||||
|
||||
const tabbarConfig = computed(() => {
|
||||
const baseItems = [
|
||||
{ text: '职位' },
|
||||
{ text: currentUserType.value === 0 ? '发布岗位' : '招聘会' },
|
||||
{ text: 'AI+' },
|
||||
{ text: '消息' },
|
||||
{ text: '我的' }
|
||||
];
|
||||
return baseItems;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.test-page {
|
||||
padding: 40rpx;
|
||||
background: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.header {
|
||||
text-align: center;
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
.title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
.current-info {
|
||||
background: #fff;
|
||||
padding: 30rpx;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #256BFA;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.type-switcher {
|
||||
background: #fff;
|
||||
padding: 30rpx;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.section-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 20rpx;
|
||||
|
||||
.btn {
|
||||
flex: 1;
|
||||
min-width: 140rpx;
|
||||
height: 80rpx;
|
||||
background: #f8f9fa;
|
||||
border: 2rpx solid #e9ecef;
|
||||
border-radius: 12rpx;
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&.active {
|
||||
background: #256BFA;
|
||||
border-color: #256BFA;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tabbar-preview {
|
||||
background: #fff;
|
||||
padding: 30rpx;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.section-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tabbar-container {
|
||||
display: flex;
|
||||
background: #f8f9fa;
|
||||
border-radius: 12rpx;
|
||||
padding: 20rpx;
|
||||
|
||||
.tabbar-item {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 20rpx 10rpx;
|
||||
|
||||
.tabbar-text {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.description {
|
||||
background: #fff;
|
||||
padding: 30rpx;
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
.desc-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.desc-text {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
line-height: 1.6;
|
||||
display: block;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user