feat: 登录页密码+验证码双模式 / 首页岗位优化 / 法律页面 / 后端接口完善

- 前端:登录页重构,支持密码登录、验证码登录、注册三种模式
- 前端:首页热门岗位添加「参考示例」标签,去虚构数据
- 前端:面试页顶部优化,岗位名+状态标签展示
- 前端:新增用户协议、隐私政策页面及免责声明
- 后端:新增 POST /api/user/register 注册接口
- 后端:新增 POST /api/user/set-password 设置密码接口
- 后端:修复 user.schema.ts unique 索引导致 null 冲突问题
- 后端:新增 payment-order.schema、positions.schema、site-config.schema
- 后端:package.json 新增 postbuild 脚本自动复制证书
- 管理后台:新增订单管理 Tab
This commit is contained in:
yuzhiran
2026-06-09 15:39:17 +08:00
parent 511f60d0db
commit 37cfdfe93c
27 changed files with 1045 additions and 195 deletions
+42 -50
View File
@@ -6,65 +6,57 @@
</view>
<view class="info-section">
<text class="info-label">产品名称</text>
<text class="info-value">职引 · AI 面试模拟</text>
<text class="info-value">职引 · 宇之然AI磁场</text>
</view>
<view class="info-section">
<text class="info-label">开发团队</text>
<text class="info-value">宇之然</text>
</view>
<view class="desc">
<text>职引是一款 AI 驱动的面试模拟工具帮助求职者通过模拟真实面试简历诊断和优化提升面试通过率</text>
<view class="info-section">
<text class="info-label">联系邮箱</text>
<text class="info-value">contact@yuzhiran.com</text>
</view>
<view class="link-section">
<view class="link-item" @click="goAgreement">
<text class="link-text">用户协议</text>
<text class="link-arrow"></text>
</view>
<view class="link-item" @click="goPrivacy">
<text class="link-text">隐私政策</text>
<text class="link-arrow"></text>
</view>
</view>
<view class="disclaimer">
<text class="disclaimer-title"> AI生成内容免责声明</text>
<text class="disclaimer-text">
本平台的模拟面试简历诊断简历优化等功能由人工智能模型生成仅供参考和学习用途AI输出的内容可能存在不准确不完整或过时的情况不构成任何专业建议用户在做出重要决策前请务必结合自身判断核实相关信息宇之然AI磁场不对因使用AI生成内容导致的任何直接或间接损失承担责任
</text>
</view>
</view>
</template>
<script setup lang="ts">
<script setup>
const goAgreement = () => uni.navigateTo({ url: '/pages/agreement/agreement' })
const goPrivacy = () => uni.navigateTo({ url: '/pages/privacy/privacy' })
</script>
<style scoped>
.page {
background: #f5f6f7;
padding: 60rpx 30rpx;
}
.logo-area {
text-align: center;
padding: 80rpx 0;
}
.logo {
font-size: 48rpx;
font-weight: 700;
background: linear-gradient(135deg, #4F46E5, #7C3AED);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
display: block;
margin-bottom: 16rpx;
}
.version {
font-size: 24rpx;
color: #999;
}
.info-section {
background: #fff;
padding: 24rpx 30rpx;
border-radius: 16rpx;
margin-bottom: 16rpx;
display: flex;
justify-content: space-between;
}
.info-label {
font-size: 26rpx;
color: #999;
}
.info-value {
font-size: 26rpx;
color: #333;
}
.desc {
margin-top: 40rpx;
font-size: 24rpx;
color: #999;
line-height: 1.8;
text-align: center;
}
</style>
.page { background: var(--color-bg); min-height: 100vh; padding: 60rpx 32rpx; }
.logo-area { text-align: center; padding: 60rpx 0 40rpx; }
.logo { font-size: 48rpx; font-weight: 800; background: linear-gradient(135deg, var(--color-gradient-start), var(--color-gradient-end)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; display: block; margin-bottom: 12rpx; }
.version { font-size: 24rpx; color: var(--color-text-tertiary); }
.info-section { background: #FFF; padding: 24rpx 30rpx; border-radius: var(--radius-md); margin-bottom: 12rpx; display: flex; justify-content: space-between; align-items: center; }
.info-label { font-size: 26rpx; color: var(--color-text-secondary); }
.info-value { font-size: 26rpx; color: var(--color-text); font-weight: 500; }
.link-section { background: #FFF; border-radius: var(--radius-md); margin-top: 24rpx; overflow: hidden; }
.link-item { display: flex; justify-content: space-between; align-items: center; padding: 28rpx 30rpx; border-bottom: 1rpx solid var(--color-border); }
.link-item:last-child { border-bottom: none; }
.link-item:active { background: var(--color-bg); }
.link-text { font-size: 26rpx; color: var(--color-text); }
.link-arrow { font-size: 32rpx; color: var(--color-text-tertiary); }
.disclaimer { margin-top: 40rpx; background: #FFF8E1; border-radius: var(--radius-md); padding: 24rpx; }
.disclaimer-title { font-size: 24rpx; font-weight: 700; color: #F59E0B; display: block; margin-bottom: 12rpx; }
.disclaimer-text { font-size: 22rpx; color: var(--color-text-secondary); line-height: 1.8; }
</style>