企业我的页面开发

This commit is contained in:
冯辉
2025-10-24 11:34:11 +08:00
parent 0b339ee061
commit 92ee5c5311
6 changed files with 846 additions and 3 deletions

View File

@@ -0,0 +1,117 @@
# 企业我的页面功能说明
## 功能概述
本功能为企业用户提供了专门的"我的"页面和企业信息展示页面,实现了根据用户类型显示不同内容的功能。
## 页面结构
### 1. 企业我的页面 (`pages/mine/company-mine.vue`)
- **功能**: 企业用户的个人中心页面
- **特点**:
- 显示企业头像、名称和信息完整度
- 包含服务专区(实名认证、通知与提醒)
- 提供退出登录功能
- 点击头像区域可跳转到企业信息页面
### 2. 企业信息展示页面 (`pages/mine/company-info.vue`)
- **功能**: 显示详细的企业信息
- **特点**:
- 显示企业头像编辑功能
- 展示完整的企业信息(名称、统一社会代码、注册地点等)
- 支持编辑各项企业信息
- 包含企业联系人和法人信息
### 3. 修改后的我的页面 (`pages/mine/mine.vue`)
- **功能**: 根据用户类型显示不同的内容
- **特点**:
- 企业用户显示企业信息卡片
- 求职者用户显示个人简历信息
- 自动根据 `userInfo.isCompanyUser` 字段判断用户类型
## 用户类型判断
系统通过 `userInfo.isCompanyUser` 字段来判断用户类型:
- `0` = 企业用户
- `1` = 求职者
- `2` = 网格员
- `3` = 政府人员
## 页面跳转逻辑
### 从我的页面跳转
- **企业用户**: 点击头像区域 → 跳转到企业信息页面 (`/pages/mine/company-info`)
- **求职者用户**: 点击头像区域 → 跳转到简历页面 (`/packageA/pages/myResume/myResume`)
### 企业信息页面功能
- 点击头像 → 编辑头像(调用相册选择图片)
- 点击各项信息 → 跳转到对应的编辑页面(需要后续开发)
## 路由配置
新增的路由配置:
```json
{
"path": "pages/mine/company-mine",
"style": {
"navigationBarTitleText": "我的",
"navigationStyle": "custom"
}
},
{
"path": "pages/mine/company-info",
"style": {
"navigationBarTitleText": "企业信息",
"navigationStyle": "custom"
}
}
```
## 测试页面
创建了测试页面 `pages/test/company-mine-test.vue` 用于测试功能:
- 用户类型切换测试
- 页面跳转测试
- 用户信息显示
## 样式特点
### 企业信息卡片
- 白色背景,圆角设计
- 阴影效果现代化UI
- 头像圆形显示
- 信息完整度显示
### 企业信息页面
- 清晰的信息层级
- 可点击的编辑区域
- 统一的视觉风格
## 数据流
1. 用户登录时设置 `userInfo.isCompanyUser` 字段
2. 我的页面根据此字段判断显示内容
3. 企业用户点击头像跳转到企业信息页面
4. 企业信息页面展示详细的企业数据
## 后续开发建议
1. **编辑功能**: 为每个信息项创建对应的编辑页面
2. **数据接口**: 连接真实的企业信息API
3. **头像上传**: 完善头像上传功能
4. **表单验证**: 添加企业信息编辑的表单验证
5. **权限控制**: 根据用户权限控制可编辑的字段
## 使用方法
1. 在测试页面切换用户类型为企业用户
2. 访问我的页面,查看企业信息卡片
3. 点击头像区域跳转到企业信息页面
4. 在企业信息页面查看详细的企业信息
## 注意事项
- 确保用户类型字段正确设置
- 企业信息数据需要从后端API获取
- 头像上传功能需要配置服务器接口
- 编辑页面需要根据实际需求进行开发

View File

@@ -96,6 +96,13 @@
"navigationStyle": "custom" "navigationStyle": "custom"
} }
}, },
{
"path": "pages/test/company-mine-test",
"style": {
"navigationBarTitleText": "企业我的页面测试",
"navigationStyle": "custom"
}
},
{ {
"path": "pages/job/publishJob", "path": "pages/job/publishJob",
"style": { "style": {
@@ -135,6 +142,20 @@
"navigationBarTitleText": "", "navigationBarTitleText": "",
"navigationStyle": "custom" "navigationStyle": "custom"
} }
},
{
"path": "pages/mine/company-mine",
"style": {
"navigationBarTitleText": "我的",
"navigationStyle": "custom"
}
},
{
"path": "pages/mine/company-info",
"style": {
"navigationBarTitleText": "企业信息",
"navigationStyle": "custom"
}
} }
], ],

263
pages/mine/company-info.vue Normal file
View File

@@ -0,0 +1,263 @@
<template>
<AppLayout title="企业信息" back-gorund-color="#F4F4F4">
<!-- 头部进度显示 -->
<view class="header-progress">
<text class="progress-text">{{ companyInfo.completeness || '100%' }}</text>
</view>
<!-- 编辑头像 -->
<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/icon/company-avatar.png'"></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 || '6217171301012562295' }}</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 || '公司成立于2003年01月27日,位于北京市大兴区经济技术产业开发区天泰一路3号一号楼南四、五楼,目前处于开业状态,经营范围包括信息技术咨询服务;科技中介服务;人工智能等。' }}</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="info-item btn-feel" @click="editInfo('contact1')">
<view class="info-label">企业联系人名称</view>
<view class="info-content">
<text class="info-value">{{ companyInfo.contact1Name || '吴宣萱' }}</text>
<uni-icons color="#A2A2A2" type="right" size="16"></uni-icons>
</view>
</view>
<view class="info-item btn-feel" @click="editInfo('contact1Phone')">
<view class="info-label">企业联系人电话</view>
<view class="info-content">
<text class="info-value">{{ companyInfo.contact1Phone || '15547143804' }}</text>
<uni-icons color="#A2A2A2" type="right" size="16"></uni-icons>
</view>
</view>
<view class="info-item btn-feel" @click="editInfo('contact2')">
<view class="info-label">企业联系人名称</view>
<view class="info-content">
<text class="info-value">{{ companyInfo.contact2Name || '李杰' }}</text>
<uni-icons color="#A2A2A2" type="right" size="16"></uni-icons>
</view>
</view>
<view class="info-item btn-feel" @click="editInfo('contact2Phone')">
<view class="info-label">企业联系人电话</view>
<view class="info-content">
<text class="info-value">{{ companyInfo.contact2Phone || '10700010700' }}</text>
<uni-icons color="#A2A2A2" type="right" size="16"></uni-icons>
</view>
</view>
</view>
</AppLayout>
</template>
<script setup>
import { reactive, inject, onMounted } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app';
const { $api, navTo } = inject('globalFunction');
// 企业信息数据
const companyInfo = reactive({
name: '科里(北京)科技有限公司(喀什分公司)',
avatar: '/static/icon/company-avatar.png',
completeness: '100%',
socialCode: '6217171301012562295',
location: '北京',
description: '公司成立于2003年01月27日,位于北京市大兴区经济技术产业开发区天泰一路3号一号楼南四、五楼,目前处于开业状态,经营范围包括信息技术咨询服务;科技中介服务;人工智能等。',
legalPerson: '孙正云',
contact1Name: '吴宣萱',
contact1Phone: '15547143804',
contact2Name: '李杰',
contact2Phone: '10700010700'
});
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',
contact1: '/pages/mine/edit-contact1',
contact1Phone: '/pages/mine/edit-contact1-phone',
contact2: '/pages/mine/edit-contact2',
contact2Phone: '/pages/mine/edit-contact2-phone'
};
if (editPages[type]) {
navTo(editPages[type]);
}
}
onShow(() => {
// 获取企业信息
getCompanyInfo();
});
function getCompanyInfo() {
// 这里可以调用API获取企业信息
// $api.createRequest('/app/company/info').then((resData) => {
// Object.assign(companyInfo, resData.data);
// });
}
</script>
<style lang="stylus" scoped>
.header-progress {
text-align: center;
padding: 20rpx 0;
.progress-text {
font-size: 28rpx;
color: #6C7282;
}
}
.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);
}
}
</style>

218
pages/mine/company-mine.vue Normal file
View File

@@ -0,0 +1,218 @@
<template>
<AppLayout title="我的" 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/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 class="service-zone-card">
<view class="service-title">服务专区</view>
<view class="service-item btn-feel">
<view class="service-left">
<image class="service-icon" src="/static/icon/real-name-auth.png"></image>
<text class="service-text">实名认证</text>
</view>
<view class="service-status">已通过</view>
</view>
<view class="service-item btn-feel">
<view class="service-left">
<image class="service-icon" src="/static/icon/notification.png"></image>
<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 } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app';
const { $api, navTo } = inject('globalFunction');
const popup = ref(null);
// 企业信息数据
const companyInfo = reactive({
name: '科里喀什分公司',
avatar: '/static/icon/company-avatar.png',
completeness: '100%'
});
function goToCompanyInfo() {
navTo('/pages/mine/company-info');
}
function logOut() {
popup.value.open();
}
function close() {
popup.value.close();
}
function confirm() {
// 这里可以调用退出登录的API
console.log('退出登录');
// 跳转到登录页面或首页
uni.reLaunch({
url: '/pages/index/index'
});
}
onShow(() => {
// 获取企业信息
getCompanyInfo();
});
function getCompanyInfo() {
// 这里可以调用API获取企业信息
// $api.createRequest('/app/company/info').then((resData) => {
// Object.assign(companyInfo, resData.data);
// });
}
</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;
}
}
.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-icon {
width: 44rpx;
height: 44rpx;
margin-right: 16rpx;
}
.service-text {
font-size: 28rpx;
color: #333333;
}
}
.service-status {
font-size: 28rpx;
color: #6E6E6E;
}
}
}
.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>

View File

@@ -2,7 +2,22 @@
<AppLayout title="我的" back-gorund-color="#F4F4F4"> <AppLayout title="我的" back-gorund-color="#F4F4F4">
<!-- 自定义tabbar --> <!-- 自定义tabbar -->
<CustomTabBar :currentPage="4" /> <CustomTabBar :currentPage="4" />
<view class="mine-userinfo btn-feel" @click="seeDetail"> <!-- 企业用户信息卡片 -->
<view v-if="userInfo.isCompanyUser === 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"> <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-if="userInfo.sex === '0'" src="/static/icon/boy.png"></image>
<image class="userindo-head-img" v-else src="/static/icon/girl.png"></image> <image class="userindo-head-img" v-else src="/static/icon/girl.png"></image>
@@ -114,6 +129,13 @@ import { tabbarManager } from '@/utils/tabbarManager';
const popup = ref(null); const popup = ref(null);
const { userInfo, Completion } = storeToRefs(useUserStore()); const { userInfo, Completion } = storeToRefs(useUserStore());
const counts = ref({}); const counts = ref({});
// 企业信息数据
const companyInfo = reactive({
name: '科里喀什分公司',
avatar: '/static/icon/company-avatar.png',
completeness: '100%'
});
function logOut() { function logOut() {
popup.value.open(); popup.value.open();
} }
@@ -140,9 +162,11 @@ function getUserstatistics() {
}); });
} }
function seeDetail() { function seeDetail() {
if (userInfo.isCompanyUser) { if (userInfo.isCompanyUser === 0) {
navTo('/packageA/pages/myResume/corporateInformation'); // 企业用户跳转到企业信息页面
navTo('/pages/mine/company-info');
} else { } else {
// 求职者用户跳转到简历页面
navTo('/packageA/pages/myResume/myResume'); navTo('/packageA/pages/myResume/myResume');
} }
} }
@@ -326,4 +350,48 @@ function seeDetail() {
border-radius: 2rpx border-radius: 2rpx
background: #A2A2A2; background: #A2A2A2;
transform: rotate(45deg) 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> </style>

View 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>