diff --git a/components/UserTypeSwitcher/UserTypeSwitcher.vue b/components/UserTypeSwitcher/UserTypeSwitcher.vue
new file mode 100644
index 0000000..cee16dc
--- /dev/null
+++ b/components/UserTypeSwitcher/UserTypeSwitcher.vue
@@ -0,0 +1,100 @@
+
+
+ 用户类型切换(测试用)
+
+
+
+
+ 当前用户类型:{{ getCurrentTypeLabel() }} ({{ currentUserType }})
+
+
+
+
+
+
+
diff --git a/components/selectFilter/selectFilter.vue b/components/selectFilter/selectFilter.vue
index 69db35e..5741750 100644
--- a/components/selectFilter/selectFilter.vue
+++ b/components/selectFilter/selectFilter.vue
@@ -72,6 +72,16 @@ import { ref, reactive, nextTick, onBeforeMount } from 'vue';
import useDictStore from '@/stores/useDictStore';
const { getTransformChildren } = useDictStore();
+// 岗位类型数据
+const getJobTypeData = () => {
+ return [
+ { label: '常规岗位', value: 'regular', text: '常规岗位' },
+ { label: '就业见习岗位', value: 'internship', text: '就业见习岗位' },
+ { label: '实习实训岗位', value: 'training', text: '实习实训岗位' },
+ { label: '社区实践岗位', value: 'community', text: '社区实践岗位' }
+ ];
+};
+
const area = ref(true);
const maskClick = ref(false);
const maskClickFn = ref(null);
@@ -164,6 +174,12 @@ function getoptions() {
if (area.value) {
arr.push(getTransformChildren('area', '区域'));
}
+ // 添加岗位类型选项
+ arr.push({
+ label: '岗位类型',
+ key: 'jobType',
+ options: getJobTypeData()
+ });
filterOptions.value = arr;
activeTab.value = 'education';
}
diff --git a/components/tabbar/midell-box.vue b/components/tabbar/midell-box.vue
index 89ec8b2..669f88d 100644
--- a/components/tabbar/midell-box.vue
+++ b/components/tabbar/midell-box.vue
@@ -21,6 +21,9 @@
diff --git a/pages.json b/pages.json
index d1ba1d1..680199d 100644
--- a/pages.json
+++ b/pages.json
@@ -47,6 +47,20 @@
"navigationStyle": "custom"
}
},
+ {
+ "path": "pages/test/userTypeTest",
+ "style": {
+ "navigationBarTitleText": "用户类型测试",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "pages/job/publishJob",
+ "style": {
+ "navigationBarTitleText": "发布岗位",
+ "navigationStyle": "custom"
+ }
+ },
{
"path": "pages/chat/chat",
"style": {
diff --git a/pages/index/components/index-one.vue b/pages/index/components/index-one.vue
index 4e92dd0..d2472be 100644
--- a/pages/index/components/index-one.vue
+++ b/pages/index/components/index-one.vue
@@ -8,18 +8,99 @@
-
+
附近工作
好岗职等你来
-
+
+
+
+
+
+
+
+
+
+
+
+
+ 服务指导
+
+
+
+
+
+ 事业单位招录
+
+
+
+
+
+ 简历制作
+
+
+
+
+
+ 劳动政策指引
+
+
+
+
+
+ 技能培训信息
+
+
+
+
+
+ 技能评价指引
+
+
+
+
+
+ 题库和考试
+
+
+
+
+
+ 素质测评
+
+
+
+
+
+ AI智能面试
-
+
@@ -176,6 +257,7 @@ import selectFilter from '@/components/selectFilter/selectFilter.vue';
import { useRecommedIndexedDBStore, jobRecommender } from '@/stores/useRecommedIndexedDBStore.js';
import { useScrollDirection } from '@/hook/useScrollDirection';
import { useColumnCount } from '@/hook/useColumnCount';
+import UserTypeSwitcher from '@/components/UserTypeSwitcher/UserTypeSwitcher.vue';
const { isScrollingDown, handleScroll } = useScrollDirection();
const recommedIndexDb = useRecommedIndexedDBStore();
const emits = defineEmits(['onShowTabbar']);
@@ -209,6 +291,8 @@ const rangeOptions = ref([
{ value: 3, text: '疆外' },
]);
const isLoaded = ref(false);
+// 控制用户类型切换器显示(测试用)
+const showUserTypeSwitcher = ref(true);
const { columnCount, columnSpace } = useColumnCount(() => {
pageState.pageSize = 10 * (columnCount.value - 1);
@@ -297,6 +381,35 @@ function nextDetail(job) {
navTo(`/packageA/pages/post/post?jobId=${btoa(job.jobId)}`);
}
+function navToService(serviceType) {
+ // 根据服务类型跳转到不同页面
+ const serviceRoutes = {
+ 'service-guidance': '/pages/service/guidance',
+ 'public-recruitment': '/pages/service/public-recruitment',
+ 'resume-creation': '/packageA/pages/myResume/myResume',
+ 'labor-policy': '/pages/service/labor-policy',
+ 'skill-training': '/pages/service/skill-training',
+ 'skill-evaluation': '/pages/service/skill-evaluation',
+ 'question-bank': '/pages/service/question-bank',
+ 'quality-assessment': '/pages/service/quality-assessment',
+ 'ai-interview': '/pages/chat/chat',
+ 'job-search': '/pages/search/search',
+ 'career-planning': '/pages/service/career-planning',
+ 'salary-query': '/pages/service/salary-query',
+ 'company-info': '/pages/service/company-info',
+ 'interview-tips': '/pages/service/interview-tips',
+ 'employment-news': '/pages/service/employment-news',
+ 'more-services': '/pages/service/more-services'
+ };
+
+ const route = serviceRoutes[serviceType];
+ if (route) {
+ navTo(route);
+ } else {
+ $api.msg('功能开发中,敬请期待');
+ }
+}
+
function openFilter() {
showFilter.value = true;
emits('onShowTabbar', false);
@@ -304,6 +417,7 @@ function openFilter() {
title: '筛选',
maskClick: true,
success: (values) => {
+ console.log('---', values);
pageState.search = {
...pageState.search,
};
@@ -596,7 +710,7 @@ defineExpose({ loadData });
padding: 10rpx 28rpx
display: grid
grid-gap: 38rpx;
- grid-template-columns: 1fr 1fr;
+ grid-template-columns: 1fr;
.card
height: calc(158rpx - 40rpx);
padding: 22rpx 26rpx
@@ -624,6 +738,163 @@ defineExpose({ loadData });
background-size: cover;
background-position: center;
+// 服务功能网格样式
+.service-grid
+ padding: 20rpx 28rpx
+ display: grid
+ grid-template-columns: 1fr 1fr 1fr 1fr
+ grid-gap: 20rpx
+ .service-item
+ display: flex
+ flex-direction: column
+ align-items: center
+ justify-content: center
+ height: 120rpx
+ background: transparent
+ padding: 10px 0px
+ .service-icon
+ width: 88rpx
+ height: 88rpx
+ border-radius: 12rpx
+ margin-bottom: 8rpx
+ flex-shrink: 0
+ .service-icon-1
+ background: linear-gradient(180deg, #FF8E8E 0%, #E53E3E 100%)
+ position: relative
+ display: flex
+ align-items: center
+ justify-content: center
+ .service-icon-2
+ background: linear-gradient(180deg, #6ED5CE 0%, #38B2AC 100%)
+ position: relative
+ display: flex
+ align-items: center
+ justify-content: center
+ .service-icon-3
+ background: linear-gradient(180deg, #6BC5D8 0%, #3182CE 100%)
+ position: relative
+ display: flex
+ align-items: center
+ justify-content: center
+ .service-icon-4
+ background: linear-gradient(180deg, #FFB74D 0%, #ED8936 100%)
+ position: relative
+ display: flex
+ align-items: center
+ justify-content: center
+ .service-icon-5
+ background: linear-gradient(180deg, #F06292 0%, #C2185B 100%)
+ position: relative
+ display: flex
+ align-items: center
+ justify-content: center
+ .service-icon-6
+ background: linear-gradient(180deg, #FFB74D 0%, #ED8936 100%)
+ position: relative
+ display: flex
+ align-items: center
+ justify-content: center
+ .service-icon-7
+ background: linear-gradient(180deg, #6BC5D8 0%, #3182CE 100%)
+ position: relative
+ display: flex
+ align-items: center
+ justify-content: center
+ .service-icon-8
+ background: linear-gradient(180deg, #81C784 0%, #4CAF50 100%)
+ position: relative
+ display: flex
+ align-items: center
+ justify-content: center
+ .service-icon-9
+ background: linear-gradient(180deg, #6BC5D8 0%, #3182CE 100%)
+ position: relative
+ display: flex
+ align-items: center
+ justify-content: center
+ .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
+ .service-icon-11
+ background: linear-gradient(135deg, #FF9800 0%, #FFB74D 100%)
+ position: relative
+ &::before
+ content: '📈'
+ position: absolute
+ top: 50%
+ left: 50%
+ transform: translate(-50%, -50%)
+ font-size: 32rpx
+ .service-icon-12
+ background: linear-gradient(135deg, #4CAF50 0%, #81C784 100%)
+ position: relative
+ &::before
+ content: '💰'
+ position: absolute
+ top: 50%
+ left: 50%
+ transform: translate(-50%, -50%)
+ font-size: 32rpx
+ .service-icon-13
+ background: linear-gradient(135deg, #607D8B 0%, #90A4AE 100%)
+ position: relative
+ &::before
+ content: '🏢'
+ position: absolute
+ top: 50%
+ left: 50%
+ transform: translate(-50%, -50%)
+ font-size: 32rpx
+ .service-icon-14
+ background: linear-gradient(135deg, #E91E63 0%, #F06292 100%)
+ position: relative
+ &::before
+ content: '💡'
+ position: absolute
+ top: 50%
+ left: 50%
+ transform: translate(-50%, -50%)
+ font-size: 32rpx
+ .service-icon-15
+ background: linear-gradient(135deg, #795548 0%, #A1887F 100%)
+ position: relative
+ &::before
+ content: '📰'
+ position: absolute
+ top: 50%
+ left: 50%
+ transform: translate(-50%, -50%)
+ font-size: 32rpx
+ .service-icon-16
+ background: linear-gradient(135deg, #424242 0%, #757575 100%)
+ position: relative
+ &::before
+ content: '⚙️'
+ position: absolute
+ top: 50%
+ left: 50%
+ transform: translate(-50%, -50%)
+ font-size: 32rpx
+ .service-title
+ font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif
+ font-weight: 500
+ font-size: 24rpx
+ color: #333333
+ text-align: center
+ line-height: 1.2
+ white-space: nowrap
+ overflow: hidden
+ text-overflow: ellipsis
+ width: 100%
+ max-width: 100%
+
.nav-filter
padding: 16rpx 28rpx 0 28rpx
font-family: 'PingFangSC-Medium', 'PingFang SC', 'Helvetica Neue', Helvetica, Arial, 'Microsoft YaHei', sans-serif;
diff --git a/pages/job/publishJob.vue b/pages/job/publishJob.vue
new file mode 100644
index 0000000..f159601
--- /dev/null
+++ b/pages/job/publishJob.vue
@@ -0,0 +1,454 @@
+
+
+
+
+
+
+
+
+
+ 岗位基本信息
+
+ 岗位名称 *
+
+
+
+ 岗位类型 *
+
+ {{ selectedJobType || '请选择岗位类型' }}
+
+
+
+ 工作地点 *
+
+
+
+
+
+
+ 薪资待遇
+
+
+ 最低薪资
+
+
+ -
+
+ 最高薪资
+
+
+
+
+ 薪资单位
+
+ {{ selectedSalaryUnit || '请选择薪资单位' }}
+
+
+
+
+
+
+ 任职要求
+
+ 学历要求
+
+ {{ selectedEducation || '请选择学历要求' }}
+
+
+
+ 工作经验
+
+ {{ selectedExperience || '请选择工作经验' }}
+
+
+
+ 招聘人数
+
+
+
+
+
+
+ 岗位描述
+
+ 岗位职责
+
+
+
+ 任职要求
+
+
+
+
+
+
+ 联系方式
+
+ 联系人
+
+
+
+ 联系电话
+
+
+
+ 联系邮箱
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/test/userTypeTest.vue b/pages/test/userTypeTest.vue
new file mode 100644
index 0000000..799b23b
--- /dev/null
+++ b/pages/test/userTypeTest.vue
@@ -0,0 +1,218 @@
+
+
+
+
+
+
+ 当前用户类型:
+ {{ getCurrentTypeLabel() }}
+
+
+
+ 切换用户类型:
+
+
+
+
+
+
+ 底部导航栏配置:
+
+
+ {{ item.text || 'AI助手' }}
+
+
+
+
+
+ 说明:
+ • 企业用户(userType=0):显示"发布岗位"导航,隐藏"招聘会"
+ • 其他用户(userType=1,2,3):显示"招聘会"导航
+ • 切换用户类型后,底部导航栏会自动更新
+ • 企业用户模式下,"招聘会"导航项完全隐藏
+
+
+
+
+
+
+
+
diff --git a/static/tabbar/publish-job-selected.svg b/static/tabbar/publish-job-selected.svg
new file mode 100644
index 0000000..408c313
--- /dev/null
+++ b/static/tabbar/publish-job-selected.svg
@@ -0,0 +1,3 @@
+
diff --git a/static/tabbar/publish-job.svg b/static/tabbar/publish-job.svg
new file mode 100644
index 0000000..12b610e
--- /dev/null
+++ b/static/tabbar/publish-job.svg
@@ -0,0 +1,3 @@
+
diff --git a/stores/useDictStore.js b/stores/useDictStore.js
index 80769dc..5cc02e3 100644
--- a/stores/useDictStore.js
+++ b/stores/useDictStore.js
@@ -135,6 +135,7 @@ const useDictStore = defineStore("dict", () => {
return null
}
+
async function getDictSelectOption(dictType, isDigital) {
const resp = await createRequest(`/app/common/dict/${dictType}`);
if (resp.code === 200 && resp.data) {
diff --git a/stores/useUserStore.js b/stores/useUserStore.js
index 882f15b..776df76 100644
--- a/stores/useUserStore.js
+++ b/stores/useUserStore.js
@@ -111,6 +111,12 @@ const useUserStore = defineStore("user", () => {
resume.value = values.data; // 将用户信息同时存储到resume中
// role.value = values.role;
hasLogin.value = true;
+
+ // 模拟添加用户类型字段,实际项目中应该从接口获取
+ if (!userInfo.value.userType) {
+ userInfo.value.userType = 0; // 默认设置为企业用户
+ }
+
// 持久化存储用户信息到本地缓存
uni.setStorageSync('userInfo', values.data);
}
diff --git a/用户类型导航功能说明.md b/用户类型导航功能说明.md
new file mode 100644
index 0000000..07a85cb
--- /dev/null
+++ b/用户类型导航功能说明.md
@@ -0,0 +1,95 @@
+# 用户类型导航功能实现说明
+
+## 功能概述
+
+根据用户类型动态显示不同的底部导航栏:
+- **企业用户(userType=0)**:显示"发布岗位"导航,隐藏"招聘会"导航
+- **其他用户(userType=1,2,3)**:显示"招聘会"导航
+
+## 实现内容
+
+### 1. 用户信息扩展
+- 在 `stores/useUserStore.js` 中添加了模拟的 `userType` 字段
+- 默认设置为企业用户(userType=0)
+
+### 2. 导航栏组件修改
+- 修改了 `components/tabbar/midell-box.vue`
+- 根据 `userInfo.userType` 动态生成不同的导航配置
+- 企业用户显示"发布岗位",其他用户显示"招聘会"
+- 修复了跳转逻辑:tabBar页面使用 `switchTab`,普通页面使用 `navigateTo`
+- 更新了发布岗位图标:使用自定义SVG图标
+ - 未选中状态:深灰色 (#666666) - 新图标设计
+ - 选中状态:蓝色 (#256BFA) - 新图标设计
+
+### 3. 发布岗位页面
+- 创建了 `pages/job/publishJob.vue` 发布岗位页面
+- 包含完整的岗位信息表单
+- 支持岗位基本信息、薪资待遇、任职要求、岗位描述、联系方式等
+
+### 4. 测试组件
+- 创建了 `components/UserTypeSwitcher/UserTypeSwitcher.vue` 用于测试
+- 创建了 `pages/test/userTypeTest.vue` 测试页面
+- 在首页添加了用户类型切换器(可控制显示/隐藏)
+
+## 用户类型定义
+
+```javascript
+const userTypes = [
+ { value: 0, label: '企业用户' },
+ { value: 1, label: '求职者' },
+ { value: 2, label: '网格员' },
+ { value: 3, label: '政府人员' }
+];
+```
+
+## 导航栏配置
+
+### 企业用户(userType=0)
+- 首页
+- 发布岗位(招聘会导航完全隐藏)
+- AI助手
+- 消息
+- 我的
+
+### 其他用户(userType=1,2,3)
+- 首页
+- 招聘会
+- AI助手
+- 消息
+- 我的
+
+## 使用方法
+
+### 1. 切换用户类型
+```javascript
+// 在组件中切换用户类型
+userInfo.value.userType = 0; // 切换到企业用户
+uni.setStorageSync('userInfo', userInfo.value);
+```
+
+### 2. 测试功能
+- 访问 `/pages/test/userTypeTest` 页面进行测试
+- 在首页可以看到用户类型切换器(测试用)
+
+### 3. 生产环境
+- 移除测试相关的组件和代码
+- 从后端接口获取真实的用户类型信息
+
+## 注意事项
+
+1. 当前是模拟实现,实际项目中需要从后端接口获取用户类型
+2. 发布岗位页面已存在:`/packageA/pages/addPosition/addPosition`
+3. 招聘会页面已存在:`/pages/careerfair/careerfair`
+4. 测试完成后可以隐藏用户类型切换器
+
+## 文件修改清单
+
+- `stores/useUserStore.js` - 添加 userType 字段
+- `components/tabbar/midell-box.vue` - 动态导航配置
+- `pages/job/publishJob.vue` - 发布岗位页面
+- `static/tabbar/publish-job.svg` - 发布岗位图标(普通状态)
+- `static/tabbar/publish-job-selected.svg` - 发布岗位图标(选中状态)
+- `components/UserTypeSwitcher/UserTypeSwitcher.vue` - 测试组件
+- `pages/test/userTypeTest.vue` - 测试页面
+- `pages/index/components/index-one.vue` - 添加测试组件
+- `pages.json` - 添加页面配置