|
|
@@ -142,6 +142,11 @@
|
|
|
<u-icon name="calendar" size="28" color="#666" />
|
|
|
<text class="info-text">有效期:{{ item.startDate }} 至 {{ item.endDate }}</text>
|
|
|
</view>
|
|
|
+ <!-- 申请状态信息 -->
|
|
|
+ <view class="info-row" v-if="getPositionApplicationStatus(item)">
|
|
|
+ <u-icon name="checkmark-circle" size="28" color="#1890ff" />
|
|
|
+ <text class="info-text" style="color: #1890ff;">我的申请:{{ getPositionApplicationStatus(item) }}</text>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
|
|
|
<!-- 操作按钮 -->
|
|
|
@@ -286,7 +291,8 @@ import {
|
|
|
getAvailablePositions,
|
|
|
getMyApplications,
|
|
|
cancelApplication,
|
|
|
- getCurrentStudentInfo
|
|
|
+ getCurrentStudentInfo,
|
|
|
+ getStudentApplicationStatusList
|
|
|
} from '@/api/workStudy.js';
|
|
|
|
|
|
export default {
|
|
|
@@ -354,7 +360,10 @@ export default {
|
|
|
refreshing: false,
|
|
|
|
|
|
// 用户信息
|
|
|
- studentInfo: null
|
|
|
+ studentInfo: null,
|
|
|
+
|
|
|
+ // 学生申请状态列表(用于判断申请状态)
|
|
|
+ studentApplications: []
|
|
|
};
|
|
|
},
|
|
|
|
|
|
@@ -396,6 +405,8 @@ export default {
|
|
|
try {
|
|
|
// 获取学生信息
|
|
|
await this.loadStudentInfo();
|
|
|
+ // 获取学生申请状态列表
|
|
|
+ await this.loadStudentApplications();
|
|
|
// 加载岗位列表
|
|
|
await this.loadPositionList(true);
|
|
|
} catch (error) {
|
|
|
@@ -419,6 +430,18 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
|
|
|
+ // 加载学生申请状态列表
|
|
|
+ async loadStudentApplications() {
|
|
|
+ try {
|
|
|
+ const response = await getStudentApplicationStatusList();
|
|
|
+ if (response.code === 200) {
|
|
|
+ this.studentApplications = response.data || [];
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取申请状态失败:', error);
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
// 加载岗位列表
|
|
|
async loadPositionList(reset = false) {
|
|
|
if (this.loading) return;
|
|
|
@@ -532,16 +555,21 @@ export default {
|
|
|
},
|
|
|
|
|
|
// 刷新数据
|
|
|
- refreshData() {
|
|
|
+ async refreshData() {
|
|
|
this.refreshing = true;
|
|
|
- if (this.currentTab === 0) {
|
|
|
- this.loadPositionList(true).finally(() => {
|
|
|
- this.refreshing = false;
|
|
|
- });
|
|
|
- } else {
|
|
|
- this.loadMyApplications(true).finally(() => {
|
|
|
- this.refreshing = false;
|
|
|
- });
|
|
|
+ try {
|
|
|
+ // 同时刷新学生申请状态
|
|
|
+ await this.loadStudentApplications();
|
|
|
+
|
|
|
+ if (this.currentTab === 0) {
|
|
|
+ await this.loadPositionList(true);
|
|
|
+ } else {
|
|
|
+ await this.loadMyApplications(true);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('刷新数据失败:', error);
|
|
|
+ } finally {
|
|
|
+ this.refreshing = false;
|
|
|
}
|
|
|
},
|
|
|
|
|
|
@@ -564,23 +592,45 @@ export default {
|
|
|
});
|
|
|
},
|
|
|
|
|
|
- // 申请岗位
|
|
|
- handleApply(event, item) {
|
|
|
- // 如果只传了一个参数,说明是从卡片点击调用的,第一个参数就是item
|
|
|
- if (!item && typeof event === 'object' && event.id) {
|
|
|
- item = event;
|
|
|
+ // 申请岗位(参考web端实现)
|
|
|
+ handleApply(event, position) {
|
|
|
+ // 如果只传了一个参数,说明是从卡片点击调用的,第一个参数就是position
|
|
|
+ if (!position && typeof event === 'object' && event.id) {
|
|
|
+ position = event;
|
|
|
}
|
|
|
|
|
|
- if (!this.canApply(item)) {
|
|
|
+ const application = this.studentApplications.find(app => app.positionId === position.id);
|
|
|
+
|
|
|
+ // 如果已有申请且状态为已提交或审核中,跳转到申请管理页面
|
|
|
+ if (application && ['submitted', 'college_reviewing', 'final_reviewing'].includes(application.status)) {
|
|
|
+ uni.switchTab({
|
|
|
+ url: '/pages/workStudy/index'
|
|
|
+ });
|
|
|
+ // 切换到"我的申请"标签页
|
|
|
+ this.currentTab = 1;
|
|
|
+ this.onTabChange(1);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果已录用,不允许操作
|
|
|
+ if (application && application.status === 'approved') {
|
|
|
uni.showToast({
|
|
|
- title: this.getApplyButtonText(item),
|
|
|
+ title: '您已被该岗位录用',
|
|
|
+ icon: 'none'
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!this.canApply(position)) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '该岗位当前不可申请',
|
|
|
icon: 'none'
|
|
|
});
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
uni.navigateTo({
|
|
|
- url: `/pages/workStudy/apply?positionId=${item.id}`
|
|
|
+ url: `/pages/workStudy/apply?positionId=${position.id}`
|
|
|
});
|
|
|
},
|
|
|
|
|
|
@@ -661,53 +711,140 @@ export default {
|
|
|
return typeMap[status] || 'default';
|
|
|
},
|
|
|
|
|
|
- // 判断是否可以申请
|
|
|
- canApply(item) {
|
|
|
- return item.status === 'RECRUITING' &&
|
|
|
- (item.currentCount || 0) < (item.requiredCount || 0);
|
|
|
+ // 判断是否可以申请(完全参考web端实现)
|
|
|
+ canApply(position) {
|
|
|
+ const application = this.studentApplications.find(app => app.positionId === position.id);
|
|
|
+
|
|
|
+ // 如果已录用,禁用按钮
|
|
|
+ if (application && application.status === 'approved') {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查岗位状态
|
|
|
+ if (!['PUBLISHED', 'RECRUITING'].includes(position.status || '')) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查是否还有空缺
|
|
|
+ const current = position.currentCount || 0;
|
|
|
+ const required = position.requiredCount || 0;
|
|
|
+ if (current >= required) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查有效期
|
|
|
+ if (position.endDate) {
|
|
|
+ const endDate = new Date(position.endDate);
|
|
|
+ if (endDate < new Date()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
},
|
|
|
|
|
|
- // 获取申请按钮文字
|
|
|
- getApplyButtonText(item) {
|
|
|
- if (item.status !== 'RECRUITING') {
|
|
|
- return '暂不可申请';
|
|
|
+ // 获取申请按钮文字(参考web端实现8种状态)
|
|
|
+ getApplyButtonText(position) {
|
|
|
+ const application = this.studentApplications.find(app => app.positionId === position.id);
|
|
|
+
|
|
|
+ // 如果已录用
|
|
|
+ if (application && application.status === 'approved') {
|
|
|
+ return '申请已通过';
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果有申请且状态为审核中
|
|
|
+ if (application && ['submitted', 'college_reviewing', 'final_reviewing'].includes(application.status)) {
|
|
|
+ return '申请审核中';
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果被拒绝
|
|
|
+ if (application && application.status === 'rejected') {
|
|
|
+ return '重新申请';
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查岗位状态
|
|
|
+ if (!['PUBLISHED', 'RECRUITING'].includes(position.status || '')) {
|
|
|
+ if (position.status === 'EXPIRED') {
|
|
|
+ return '岗位已过期';
|
|
|
+ } else if (position.status === 'SUSPENDED') {
|
|
|
+ return '岗位已暂停';
|
|
|
+ } else if (position.status === 'CANCELLED') {
|
|
|
+ return '岗位已取消';
|
|
|
+ } else {
|
|
|
+ return '暂不可申请';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查是否还有空缺
|
|
|
+ const current = position.currentCount || 0;
|
|
|
+ const required = position.requiredCount || 0;
|
|
|
+ if (current >= required) {
|
|
|
+ return '岗位已满员';
|
|
|
}
|
|
|
- if ((item.currentCount || 0) >= (item.requiredCount || 0)) {
|
|
|
- return '已满员';
|
|
|
+
|
|
|
+ // 检查有效期
|
|
|
+ if (position.endDate) {
|
|
|
+ const endDate = new Date(position.endDate);
|
|
|
+ if (endDate < new Date()) {
|
|
|
+ return '岗位已过期';
|
|
|
+ }
|
|
|
}
|
|
|
- return '申请岗位';
|
|
|
+
|
|
|
+ // 默认可申请
|
|
|
+ return '申请此岗位';
|
|
|
},
|
|
|
|
|
|
- // 获取申请状态文字
|
|
|
+ // 获取申请状态文字(与web端保持一致)
|
|
|
getApplicationStatusText(item) {
|
|
|
- const statusMap = {
|
|
|
- 'DRAFT': '草稿',
|
|
|
- 'SUBMITTED': '已提交',
|
|
|
- 'COLLEGE_REVIEWING': '学院审核中',
|
|
|
- 'COLLEGE_APPROVED': '学院审核通过',
|
|
|
- 'COLLEGE_REJECTED': '学院审核未通过',
|
|
|
- 'FINAL_REVIEWING': '学生处审核中',
|
|
|
- 'FINAL_APPROVED': '审核通过',
|
|
|
- 'FINAL_REJECTED': '审核未通过',
|
|
|
- 'CANCELLED': '已撤销'
|
|
|
- };
|
|
|
- return statusMap[item.status] || '未知状态';
|
|
|
+ if (!item) return '未申请';
|
|
|
+
|
|
|
+ // 支持两种格式:web端的小写格式和移动端的大写格式
|
|
|
+ const status = item.status ? item.status.toLowerCase() : '';
|
|
|
+
|
|
|
+ switch (status) {
|
|
|
+ case 'submitted':
|
|
|
+ case 'SUBMITTED':
|
|
|
+ return '已提交';
|
|
|
+ case 'college_reviewing':
|
|
|
+ case 'COLLEGE_REVIEWING':
|
|
|
+ return '学院审核中';
|
|
|
+ case 'final_reviewing':
|
|
|
+ case 'FINAL_REVIEWING':
|
|
|
+ return '学生处审核中';
|
|
|
+ case 'approved':
|
|
|
+ case 'FINAL_APPROVED':
|
|
|
+ return '审核通过';
|
|
|
+ case 'rejected':
|
|
|
+ case 'FINAL_REJECTED':
|
|
|
+ return '审核不通过';
|
|
|
+ case 'cancelled':
|
|
|
+ case 'CANCELLED':
|
|
|
+ return '已撤销';
|
|
|
+ case 'draft':
|
|
|
+ case 'DRAFT':
|
|
|
+ return '草稿';
|
|
|
+ default:
|
|
|
+ return '未知状态';
|
|
|
+ }
|
|
|
},
|
|
|
|
|
|
- // 获取申请状态类型
|
|
|
+ // 获取申请状态类型(与web端保持一致)
|
|
|
getApplicationStatusType(item) {
|
|
|
+ if (!item) return 'default';
|
|
|
+
|
|
|
+ // 支持两种格式:web端的小写格式和移动端的大写格式
|
|
|
+ const status = item.status ? item.status.toLowerCase() : '';
|
|
|
+
|
|
|
const typeMap = {
|
|
|
- 'DRAFT': 'info',
|
|
|
- 'SUBMITTED': 'warning',
|
|
|
- 'COLLEGE_REVIEWING': 'warning',
|
|
|
- 'COLLEGE_APPROVED': 'success',
|
|
|
- 'COLLEGE_REJECTED': 'error',
|
|
|
- 'FINAL_REVIEWING': 'warning',
|
|
|
- 'FINAL_APPROVED': 'success',
|
|
|
- 'FINAL_REJECTED': 'error',
|
|
|
- 'CANCELLED': 'info'
|
|
|
+ 'draft': 'info',
|
|
|
+ 'submitted': 'warning',
|
|
|
+ 'college_reviewing': 'warning',
|
|
|
+ 'final_reviewing': 'warning',
|
|
|
+ 'approved': 'success',
|
|
|
+ 'rejected': 'error',
|
|
|
+ 'cancelled': 'info'
|
|
|
};
|
|
|
- return typeMap[item.status] || 'default';
|
|
|
+ return typeMap[status] || 'default';
|
|
|
},
|
|
|
|
|
|
// 获取审核状态文字
|
|
|
@@ -720,9 +857,22 @@ export default {
|
|
|
return statusMap[status] || '未知';
|
|
|
},
|
|
|
|
|
|
- // 判断是否可以撤销申请
|
|
|
+ // 判断是否可以撤销申请(与web端保持一致)
|
|
|
canCancelApplication(item) {
|
|
|
- return ['DRAFT', 'SUBMITTED', 'COLLEGE_REVIEWING'].includes(item.status);
|
|
|
+ if (!item) return false;
|
|
|
+
|
|
|
+ // 支持两种格式:web端的小写格式和移动端的大写格式
|
|
|
+ const status = item.status ? item.status.toLowerCase() : '';
|
|
|
+ return ['draft', 'submitted', 'college_reviewing'].includes(status) ||
|
|
|
+ ['DRAFT', 'SUBMITTED', 'COLLEGE_REVIEWING'].includes(item.status);
|
|
|
+ },
|
|
|
+
|
|
|
+ // 获取岗位的申请状态(用于在岗位卡片中显示)
|
|
|
+ getPositionApplicationStatus(position) {
|
|
|
+ const application = this.studentApplications.find(app => app.positionId === position.id);
|
|
|
+ if (!application) return null;
|
|
|
+
|
|
|
+ return this.getApplicationStatusText(application);
|
|
|
}
|
|
|
}
|
|
|
};
|