From d7460f898d6d51f9740062c25dab84ec1343d5bf Mon Sep 17 00:00:00 2001
From: xcbyy <2578898740@qq.com>
Date: Sat, 10 Oct 2026 16:57:48 +0800
Subject: [PATCH] feat(expert): create dedicated expert apply page and navigate
from user center
---
pwuniapp/pages.json | 9 +
pwuniapp/pages/expert/apply.vue | 983 ++++++++++++++++++++++++++
pwuniapp/pages/user/index.vue | 246 +------
server/tests/content-security.spec.ts | 41 +-
4 files changed, 1037 insertions(+), 242 deletions(-)
create mode 100644 pwuniapp/pages/expert/apply.vue
diff --git a/pwuniapp/pages.json b/pwuniapp/pages.json
index 3626291..82e8510 100644
--- a/pwuniapp/pages.json
+++ b/pwuniapp/pages.json
@@ -56,6 +56,15 @@
"backgroundColor": "#0A0F1D"
}
},
+ {
+ "path": "pages/expert/apply",
+ "style": {
+ "navigationBarTitleText": "大神入驻认证",
+ "navigationBarBackgroundColor": "#0A0F1D",
+ "navigationBarTextStyle": "white",
+ "backgroundColor": "#0A0F1D"
+ }
+ },
{
"path": "pages/order/create",
"style": {
diff --git a/pwuniapp/pages/expert/apply.vue b/pwuniapp/pages/expert/apply.vue
new file mode 100644
index 0000000..0318ef7
--- /dev/null
+++ b/pwuniapp/pages/expert/apply.vue
@@ -0,0 +1,983 @@
+
+
+
+
+
+
+
+ 已通过大神实名认证
+ 您已具备平台专属接单特权,可前往工作台开启接单服务与收益结算。
+
+
+
+ 认证身份
+ 平台认证金牌陪伴师
+
+
+ 权限状态
+ 接单功能已就绪
+
+
+
+
+
+
+
+
+
+
+
+
+ 实名认证审核中
+ 您的入驻申请已成功提交至平台审核中心,运营团队将在 24 小时内完成人工核验。
+
+
+
+
+ 提交申请
+
+
+
+
+ 官方核验中
+
+
+
+
+ 审核开通
+
+
+
+
+
+ 审核说明
+ 核验通过后系统将自动开通接单模式
+
+
+ 服务保障
+ 平台资金托管与 7x24h 履约安全保障
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 实名认证与合规入驻指引
+ 为构建健康绿色的同城陪伴生态,申请者须提交真实有效的身份信息,平台全面落实微信内容安全与用户隐私保障。
+
+
+
+
+
+
+
+
+ 真实姓名
+ *
+
+
+
+
+
+
+
+ 身份证号码
+ *
+
+
+
+
+
+
+
+ 主营陪伴品类
+ *
+
+
+
+ {{ trk }}
+
+
+
+
+
+
+
+ 期望服务单价 (元/小时)
+ *
+ 限价 ¥{{ expertPriceMin }} - ¥{{ expertPriceMax }}
+
+
+ ¥
+
+
+
+
+
+
+
+ 技能专长标签
+ (最多任选 6 项,展示在个人接单主页)
+
+
+
+ {{ tag }}
+
+
+
+
+
+
+
+
+
+
+
+ 我已阅读并完全同意
+ 《陪伴师入驻规范与安全履约协议》
+ ,保证所提交全部材料真实合法。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pwuniapp/pages/user/index.vue b/pwuniapp/pages/user/index.vue
index 497b306..2700470 100644
--- a/pwuniapp/pages/user/index.vue
+++ b/pwuniapp/pages/user/index.vue
@@ -261,74 +261,6 @@
-
-
-
-
-
-
-
- 提交真实有效资料,平台将在 24 小时内由运营团队人工核验后开通接单工作台。
-
-
-
- 真实姓名
-
-
-
-
- 身份证号码
-
-
-
-
- 主营陪伴品类
-
-
- {{ trk }}
-
-
-
-
-
- 期望服务单价 (元/小时,平台限价: ¥{{ expertPriceMin }} - ¥{{ expertPriceMax }})
-
-
-
-
- 技能专长标签 (最多选6项)
-
-
- {{ tg }}
-
-
-
-
-
-
-
-
-
@@ -346,7 +278,7 @@ import { ICONS } from '@/common/icons.js';
import { getCurrentThemeKey, setTheme, THEME_KEYS, applyThemeToNativeUI } from '@/common/theme.js';
import { getCurrentRole, setCurrentRole, ROLE_TYPES, toggleRole as toggleUserRole, isExpertCertified, getExpertCertStatus, setExpertCertStatus, CERT_STATUS } from '@/common/role.js';
import { getNavBarInfo } from '@/common/nav.js';
-import { getUserProfile, rechargeBalance, withdrawCommission, getUserFinanceRecords, updateUserProfile, uploadImage, getRechargeTiers, getPlatformConfigs } from '@/common/api.js';
+import { getUserProfile, rechargeBalance, withdrawCommission, getUserFinanceRecords, updateUserProfile, uploadImage, getRechargeTiers, getPlatformConfigs, applyExpertCert } from '@/common/api.js';
const DEFAULT_GUEST_AVATAR = 'https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=200';
const isLoggedIn = ref(true);
@@ -895,115 +827,14 @@ const showInvitePoster = () => {
});
};
+// 大神实名入驻认证已全面升级重构为独立专享页面 /pages/expert/apply
const showExpertCertModal = ref(false);
-const expertCertForm = ref({
- realName: '',
- idCard: '',
- track: '同城陪吃',
- hourlyRate: 88,
- tags: []
-});
-
-const expertPriceMin = computed(() => {
- return platformConfigs.value.expert_rules?.minHourlyRate || 30;
-});
-const expertPriceMax = computed(() => {
- return platformConfigs.value.expert_rules?.maxHourlyRate || 500;
-});
-const expertDefaultRate = computed(() => {
- return platformConfigs.value.expert_rules?.defaultHourlyRate || 88;
-});
-const expertCandidateTags = computed(() => {
- return platformConfigs.value.expert_rules?.candidateTags || [
- '国服王者', '声优达人', '幽默风趣', '随叫随到', '暖心倾听',
- '百星野王', '金牌探店', '量贩麦霸', '微醺搭子'
- ];
-});
-
-const toggleCertTag = (tag) => {
- const idx = expertCertForm.value.tags.indexOf(tag);
- if (idx > -1) {
- expertCertForm.value.tags.splice(idx, 1);
- } else {
- if (expertCertForm.value.tags.length >= 6) {
- uni.showToast({ title: '最多选择6个技能标签', icon: 'none' });
- return;
- }
- expertCertForm.value.tags.push(tag);
- }
-};
-
-const submitExpertCertForm = async () => {
- if (!expertCertForm.value.realName || !expertCertForm.value.realName.trim()) {
- uni.showToast({ title: '请输入真实姓名', icon: 'none' });
- return;
- }
- if (!expertCertForm.value.idCard || expertCertForm.value.idCard.length < 15) {
- uni.showToast({ title: '请输入有效身份证号', icon: 'none' });
- return;
- }
-
- const rate = Number(expertCertForm.value.hourlyRate) || expertDefaultRate.value;
- if (rate < expertPriceMin.value || rate > expertPriceMax.value) {
- uni.showToast({ title: `单价需在 ¥${expertPriceMin.value} - ¥${expertPriceMax.value} 之间`, icon: 'none' });
- return;
- }
-
- uni.showLoading({ title: '正在提交认证...' });
- try {
- await applyExpertCert({
- userId: user.value.id || 1001,
- name: expertCertForm.value.realName.trim(),
- idCard: expertCertForm.value.idCard.trim(),
- track: expertCertForm.value.track,
- hourlyRate: rate,
- tags: expertCertForm.value.tags,
- avatar: user.value.avatar,
- gender: user.value.gender === 'male' ? '男' : '女'
- });
- setExpertCertStatus(CERT_STATUS.PENDING);
- showExpertCertModal.value = false;
- uni.hideLoading();
- uni.showModal({
- title: '申请已提交',
- content: '您的入驻申请已成功提交至平台审核中心,运营团队核准后即可自动开通接单工作台。',
- showCancel: false,
- confirmText: '我知道了'
- });
- } catch (e) {
- uni.hideLoading();
- uni.showToast({ title: e.message || '提交申请失败', icon: 'none' });
- }
-};
const applyExpert = () => {
if (!ensureLoggedIn()) return;
- const certStatus = getExpertCertStatus();
- if (certStatus === CERT_STATUS.APPROVED) {
- uni.showToast({
- title: '您已通过大神实名认证,接单权限正常',
- icon: 'none'
- });
- return;
- }
- if (certStatus === CERT_STATUS.PENDING) {
- uni.showModal({
- title: '认证审核中',
- content: '您的入驻申请正在平台运营端审核中,请耐心等待核准。',
- showCancel: false,
- confirmText: '我知道了'
- });
- return;
- }
-
- expertCertForm.value = {
- realName: '',
- idCard: '',
- track: '同城陪吃',
- hourlyRate: expertDefaultRate.value,
- tags: []
- };
- showExpertCertModal.value = true;
+ uni.navigateTo({
+ url: '/pages/expert/apply'
+ });
};
const contactService = () => {
@@ -1854,73 +1685,6 @@ const navTo = (url) => {
}
}
-.expert-cert-modal {
- max-height: 85vh;
- overflow-y: auto;
-
- .cert-alert {
- background: rgba(99, 102, 241, 0.08);
- border: 1px solid rgba(99, 102, 241, 0.2);
- border-radius: 12rpx;
- padding: 16rpx 20rpx;
- margin-bottom: 24rpx;
-
- .cert-alert-text {
- font-size: 24rpx;
- color: #6366F1;
- line-height: 1.5;
- }
- }
-
- .track-chips, .tags-chips {
- display: flex;
- flex-wrap: wrap;
- gap: 14rpx;
- margin-top: 10rpx;
-
- .track-chip, .tag-pill {
- font-size: 24rpx;
- padding: 12rpx 24rpx;
- border-radius: 30rpx;
- background: var(--bg-card, #1E293B);
- color: #94A3B8;
- border: 1px solid rgba(255, 255, 255, 0.1);
- transition: all 0.2s ease;
-
- &.active {
- background: #6366F1;
- color: #FFFFFF;
- border-color: #6366F1;
- box-shadow: 0 4rpx 12rpx rgba(99, 102, 241, 0.35);
- }
- }
- }
-}
-
-.theme-warm .expert-cert-modal {
- .cert-alert {
- background: #FFF7ED;
- border-color: #FDBA74;
-
- .cert-alert-text {
- color: #EA580C;
- }
- }
-
- .track-chips .track-chip, .tags-chips .tag-pill {
- background: #FDFBF7;
- color: #78716C;
- border-color: #E7E2D8;
-
- &.active {
- background: linear-gradient(135deg, #EA580C, #F97316);
- color: #FFFFFF;
- border-color: #EA580C;
- box-shadow: 0 4rpx 14rpx rgba(234, 88, 12, 0.35);
- }
- }
-}
-
.guest-badge {
font-size: 20rpx;
color: #94A3B8;
diff --git a/server/tests/content-security.spec.ts b/server/tests/content-security.spec.ts
index bd7e57b..ea1a3cb 100644
--- a/server/tests/content-security.spec.ts
+++ b/server/tests/content-security.spec.ts
@@ -130,7 +130,7 @@ describe('ContentSecurityService & Compliance Architecture (TDD 微信内容安
const raw = fs.readFileSync(pagesJsonPath, 'utf-8');
const config = JSON.parse(raw);
expect(Array.isArray(config.pages)).toBe(true);
- expect(config.pages.length).toBe(13);
+ expect(config.pages.length).toBe(14);
for (const pageItem of config.pages) {
const vueFilePath = path.join(rootDir, 'pwuniapp', `${pageItem.path}.vue`);
@@ -407,5 +407,44 @@ describe('ContentSecurityService & Compliance Architecture (TDD 微信内容安
expect(emojiRegex.test(text)).toBe(false);
});
});
+
+ describe('11. 大神实名认证专属独立页面与多态流程验证 (pages/expert/apply.vue)', () => {
+ it('pages.json 必须成功注册 pages/expert/apply 且物理文件必须存在', () => {
+ const applyPath = path.join(rootDir, 'pwuniapp', 'pages', 'expert', 'apply.vue');
+ expect(fs.existsSync(applyPath)).toBe(true);
+ const pagesJsonPath = path.join(rootDir, 'pwuniapp', 'pages.json');
+ const pagesJson = fs.readFileSync(pagesJsonPath, 'utf-8');
+ expect(pagesJson).toContain('pages/expert/apply');
+ expect(pagesJson).toContain('大神入驻认证');
+ });
+
+ it('大神入驻申请独立页面必须包含完整表单、协议声明与提交接口', () => {
+ const applyPath = path.join(rootDir, 'pwuniapp', 'pages', 'expert', 'apply.vue');
+ const content = fs.readFileSync(applyPath, 'utf-8');
+ expect(content).toContain('applyForm');
+ expect(content).toContain('applyExpertCert');
+ expect(content).toContain('TRACK_OPTIONS');
+ expect(content).toContain('expertPriceMin');
+ expect(content).toContain('expertPriceMax');
+ expect(content).toContain('candidateTags');
+ expect(content).toContain('submitApply');
+ expect(content).toContain('实名认证审核中');
+ expect(content).toContain('已通过大神实名认证');
+ });
+
+ it('个人中心的大神入驻入口必须路由跳转至 /pages/expert/apply', () => {
+ const userIndexPath = path.join(rootDir, 'pwuniapp', 'pages', 'user', 'index.vue');
+ const content = fs.readFileSync(userIndexPath, 'utf-8');
+ expect(content).toContain('/pages/expert/apply');
+ });
+
+ it('新页面与改造代码严禁包含任何系统 Emoji', () => {
+ const applyPath = path.join(rootDir, 'pwuniapp', 'pages', 'expert', 'apply.vue');
+ const content = fs.readFileSync(applyPath, 'utf-8');
+ const emojiRegex = /(?:\p{Extended_Pictographic}|\p{Emoji_Presentation}|[\u2600-\u27BF])/u;
+ expect(emojiRegex.test(content)).toBe(false);
+ });
+ });
});
+