| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433 |
- <script setup lang="ts">
- import { onLaunch, onShow, onHide } from "@dcloudio/uni-app";
- import { isLoggedIn } from "@/utils/auth";
- onLaunch((options: any) => {
- console.log("App Launch", options);
- checkLoginStatus();
- checkInviteCode(options);
- });
- onShow(() => {
- console.log("App Show");
- checkLoginStatus();
- });
- onHide(() => {
- console.log("App Hide");
- });
- const checkLoginStatus = () => {
- const pages = getCurrentPages();
- const currentPage = pages[pages.length - 1];
- const currentPath = currentPage ? currentPage.route : '';
- if (!isLoggedIn() && currentPath !== 'pages/login/login') {
- console.log('未登录,跳转到登录页');
- uni.reLaunch({
- url: '/pages/login/login'
- });
- }
- };
- /**
- * 获取当前登录用户的首页路径
- */
- const getHomePath = (): string => {
- const userType = uni.getStorageSync('admin_user_type') || 'admin';
- if (userType === 'replenisher') {
- return '/pages/replenish/index';
- }
- return '/pages/index/index';
- };
- /**
- * 检测启动参数中的邀请码和补货员绑定码
- * 场景:通过分享链接进入小程序时,会携带 inviteCode/bindingCode 参数
- */
- const checkInviteCode = (options: any) => {
- // 检查 query 参数中的邀请码
- if (options && options.query && options.query.inviteCode) {
- console.log('检测到邀请码:', options.query.inviteCode);
- uni.setStorageSync('pendingInviteCode', options.query.inviteCode);
- return;
- }
- // 检查补货员绑定码
- if (options && options.query && options.query.bindingCode) {
- console.log('检测到补货员绑定码:', options.query.bindingCode);
- uni.navigateTo({
- url: '/pages/replenish/bind?code=' + encodeURIComponent(options.query.bindingCode)
- });
- return;
- }
- // 检查 scene 场景值(小程序码场景)
- if (options && options.scene) {
- const scene = decodeURIComponent(options.scene);
- console.log('检测到场景值:', scene);
- // 尝试解码场景值,如果是绑定码格式则跳转
- if (/^[A-Z0-9]{24}$/.test(scene)) {
- console.log('场景值为补货员绑定码:', scene);
- uni.navigateTo({
- url: '/pages/replenish/bind?code=' + scene
- });
- }
- }
- };
- /**
- * 绑定邀请关系(注册成功后调用)
- * @param onSuccess 绑定成功回调
- */
- const bindPendingInviteRelation = async (onSuccess?: () => void) => {
- const inviteCode = uni.getStorageSync('pendingInviteCode');
- if (!inviteCode) {
- console.log('无待绑定的邀请码');
- return false;
- }
- try {
- const { bindInviteRelation } = await import('@/api/invite');
- const result = await bindInviteRelation({ inviteCode });
- if (result.success) {
- // 绑定成功,清除本地存储的邀请码
- uni.removeStorageSync('pendingInviteCode');
- uni.showToast({
- title: '邀请关系绑定成功',
- icon: 'success'
- });
- if (onSuccess) {
- onSuccess();
- }
- return true;
- } else {
- console.warn('绑定邀请关系返回失败:', result.message);
- return false;
- }
- } catch (error) {
- console.error('绑定邀请关系失败', error);
- // 即使绑定失败也清除邀请码,避免重复尝试
- uni.removeStorageSync('pendingInviteCode');
- return false;
- }
- };
- </script>
- <style>
- /*
- * 暖金黄设计系统 - 与用户端品牌统一
- * 特点: 纯色无渐变、简约清晰、科学排版
- */
- page {
- /* 背景系统 */
- --bg-page: #f8fafc;
- --bg-card: #ffffff;
- --bg-secondary: #f1f5f9;
- --bg-tertiary: #e2e8f0;
-
- background: var(--bg-page);
- font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', sans-serif;
- font-size: 28rpx;
- color: #1e293b;
- line-height: 1.6;
- min-height: 100vh;
- }
- /* ==================== 色彩系统 ==================== */
- :root {
- /* 主色调 - 暖金黄 */
- --primary: #FFC107;
- --primary-light: #FFE082;
- --primary-dark: #FFA000;
- --primary-bg: #FFF8E1;
-
- /* 辅助色 - 活力橙 */
- --accent: #f97316;
- --accent-light: #fb923c;
- --accent-bg: #fff7ed;
-
- /* 信息色 - 天空蓝 */
- --info: #0ea5e9;
- --info-light: #38bdf8;
- --info-bg: #f0f9ff;
-
- /* 功能色 - 成功 */
- --success: #10b981;
- --success-bg: #ecfdf5;
-
- /* 功能色 - 警告 */
- --warning: #f59e0b;
- --warning-bg: #fffbeb;
-
- /* 功能色 - 错误 */
- --error: #ef4444;
- --error-bg: #fef2f2;
-
- /* 文字层级 */
- --text-primary: #1e293b;
- --text-secondary: #475569;
- --text-tertiary: #64748b;
- --text-muted: #94a3b8;
- --text-placeholder: #cbd5e1;
-
- /* 边框与分割 */
- --border: #e2e8f0;
- --border-light: #f1f5f9;
- --divider: #e2e8f0;
-
- /* 卡片 */
- --card-bg: #ffffff;
- --card-border: #e2e8f0;
- --card-radius: 16rpx;
- --card-radius-lg: 24rpx;
- --card-shadow: 0 1rpx 3rpx rgba(0, 0, 0, 0.04);
-
- /* 间距系统 */
- --space-1: 8rpx;
- --space-2: 16rpx;
- --space-3: 24rpx;
- --space-4: 32rpx;
- --space-5: 40rpx;
- --space-6: 48rpx;
-
- /* 圆角系统 */
- --radius-xs: 4rpx;
- --radius-sm: 8rpx;
- --radius-base: 12rpx;
- --radius-md: 16rpx;
- --radius-lg: 20rpx;
- --radius-xl: 24rpx;
- --radius-full: 9999rpx;
- }
- /* ==================== 基础重置 ==================== */
- button {
- margin: 0;
- padding: 0;
- background: transparent;
- line-height: inherit;
- }
- button::after {
- border: none;
- }
- /* ==================== 卡片组件 ==================== */
- .card {
- background: var(--card-bg);
- border: 1rpx solid var(--card-border);
- border-radius: var(--card-radius);
- padding: 32rpx;
- margin: 20rpx;
- }
- /* ==================== 列表项 ==================== */
- .list-item {
- background: var(--card-bg);
- padding: 32rpx;
- border-bottom: 1rpx solid var(--border-light);
- display: flex;
- align-items: center;
- transition: background 0.15s;
- }
- .list-item:active {
- background: var(--bg-secondary);
- }
- .list-item:last-child {
- border-bottom: none;
- }
- /* ==================== 文字工具类 ==================== */
- .ellipsis {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- .ellipsis-2 {
- overflow: hidden;
- text-overflow: ellipsis;
- display: -webkit-box;
- -webkit-line-clamp: 2;
- -webkit-box-orient: vertical;
- }
- /* ==================== 安全区域 ==================== */
- .safe-area-bottom {
- padding-bottom: constant(safe-area-inset-bottom);
- padding-bottom: env(safe-area-inset-bottom);
- }
- /* ==================== 状态标签 ==================== */
- .status-tag {
- padding: 8rpx 16rpx;
- border-radius: 8rpx;
- font-size: 22rpx;
- font-weight: 500;
- display: inline-flex;
- align-items: center;
- justify-content: center;
- }
- .status-tag.success {
- background: var(--success-bg);
- color: var(--success);
- }
- .status-tag.warning {
- background: var(--warning-bg);
- color: var(--warning);
- }
- .status-tag.error {
- background: var(--error-bg);
- color: var(--error);
- }
- .status-tag.info {
- background: var(--info-bg);
- color: var(--info);
- }
- /* ==================== 输入框 ==================== */
- .modern-input {
- background: var(--bg-secondary);
- border: 1rpx solid var(--border);
- border-radius: 12rpx;
- padding: 24rpx 28rpx;
- color: var(--text-primary);
- font-size: 30rpx;
- transition: border-color 0.15s;
- }
- .modern-input:focus {
- border-color: var(--primary);
- }
- /* ==================== 按钮组件 ==================== */
- .btn-primary {
- background: var(--primary);
- color: #fff;
- font-weight: 600;
- padding: 28rpx 48rpx;
- border-radius: 12rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: opacity 0.15s;
- }
- .btn-primary:active {
- opacity: 0.85;
- }
- .btn-secondary {
- background: var(--bg-secondary);
- border: 1rpx solid var(--border);
- color: var(--text-primary);
- font-weight: 500;
- padding: 28rpx 48rpx;
- border-radius: 12rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: background 0.15s;
- }
- .btn-secondary:active {
- background: var(--bg-tertiary);
- }
- /* ==================== 图标容器 ==================== */
- .icon-box {
- width: 88rpx;
- height: 88rpx;
- border-radius: 20rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .icon-box.green { background: var(--primary-bg); }
- .icon-box.amber { background: var(--accent-bg); }
- .icon-box.blue { background: var(--info-bg); }
- .icon-box.red { background: var(--error-bg); }
- .icon-box.purple { background: #faf5ff; }
- .icon-box.cyan { background: #ecfeff; }
- /* ==================== 加载动画 ==================== */
- @keyframes spin {
- to { transform: rotate(360deg); }
- }
- .loading-spinner {
- width: 32rpx;
- height: 32rpx;
- border: 3rpx solid var(--border);
- border-top-color: var(--primary);
- border-radius: 50%;
- animation: spin 1s linear infinite;
- }
- /* ==================== 分割线 ==================== */
- .divider {
- height: 1rpx;
- background: var(--divider);
- }
- .divider-vertical {
- width: 1rpx;
- background: var(--divider);
- }
- /* ==================== 空状态 ==================== */
- .empty-state {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- padding: 100rpx 0;
- }
- .empty-icon {
- width: 120rpx;
- height: 120rpx;
- background: var(--bg-secondary);
- border-radius: 24rpx;
- margin-bottom: 24rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .empty-text {
- font-size: 28rpx;
- color: var(--text-muted);
- display: flex;
- align-items: center;
- justify-content: center;
- }
- </style>
|