新增环境

This commit is contained in:
tianfeng 2025-08-15 15:57:09 +08:00
parent f933a81986
commit 9f3c01d50c
9 changed files with 116 additions and 535 deletions

4
.env Normal file
View File

@ -0,0 +1,4 @@
# 默认环境(开发环境)
VITE_NODE_ENV=development
VITE_API_BASE_URL=https://dev-api.likeichat.com
VITE_APP_TITLE=Likei H5 (Development)

4
.env.development Normal file
View File

@ -0,0 +1,4 @@
# 开发环境
VITE_NODE_ENV=development
VITE_API_BASE_URL=https://dev-api.likeichat.com
VITE_APP_TITLE=Likei H5 (Development)

4
.env.production Normal file
View File

@ -0,0 +1,4 @@
# 生产环境
VITE_NODE_ENV=production
VITE_API_BASE_URL=https://api.likeichat.com
VITE_APP_TITLE=Likei H5

4
.env.test Normal file
View File

@ -0,0 +1,4 @@
# 测试环境
VITE_NODE_ENV=test
VITE_API_BASE_URL=https://test-api.likeichat.com
VITE_APP_TITLE=Likei H5 (Test)

View File

@ -7,8 +7,13 @@
"node": "^20.19.0 || >=22.12.0" "node": "^20.19.0 || >=22.12.0"
}, },
"scripts": { "scripts": {
"dev": "vite", "dev": "vite --mode development",
"build": "vite build", "dev:test": "vite --mode test",
"dev:prod": "vite --mode production",
"build": "vite build --mode production",
"build:dev": "vite build --mode development",
"build:test": "vite build --mode test",
"build:prod": "vite build --mode production",
"preview": "vite preview", "preview": "vite preview",
"lint": "eslint . --fix" "lint": "eslint . --fix"
}, },

View File

@ -1,9 +1,13 @@
import './assets/main.css' import './assets/main.css'
import { logEnvInfo } from './utils/env.js'
import { createApp } from 'vue' import { createApp } from 'vue'
import App from './App.vue' import App from './App.vue'
import router from './router' import router from './router'
// 初始化环境信息
logEnvInfo()
const app = createApp(App) const app = createApp(App)
app.use(router) app.use(router)

69
src/utils/env.js Normal file
View File

@ -0,0 +1,69 @@
/**
* 环境配置工具
*/
// 环境类型
export const ENV_TYPES = {
DEVELOPMENT: 'development',
TEST: 'test',
PRODUCTION: 'production'
}
// 获取当前环境
export function getCurrentEnv() {
return import.meta.env.VITE_NODE_ENV || import.meta.env.MODE || ENV_TYPES.DEVELOPMENT
}
// 获取 API 基础 URL
export function getApiBaseUrl() {
return import.meta.env.VITE_API_BASE_URL || 'https://api.likeichat.com'
}
// 获取应用标题
export function getAppTitle() {
return import.meta.env.VITE_APP_TITLE || 'Likei H5'
}
// 是否为开发环境
export function isDevelopment() {
return getCurrentEnv() === ENV_TYPES.DEVELOPMENT
}
// 是否为测试环境
export function isTest() {
return getCurrentEnv() === ENV_TYPES.TEST
}
// 是否为生产环境
export function isProduction() {
return getCurrentEnv() === ENV_TYPES.PRODUCTION
}
// 是否启用调试模式
export function isDebugMode() {
return isDevelopment() || isTest()
}
// 获取完整的环境配置
export function getEnvConfig() {
return {
env: getCurrentEnv(),
apiBaseUrl: getApiBaseUrl(),
appTitle: getAppTitle(),
isDevelopment: isDevelopment(),
isTest: isTest(),
isProduction: isProduction(),
isDebugMode: isDebugMode()
}
}
// 打印环境信息
export function logEnvInfo() {
const config = getEnvConfig()
console.group('🔧 Environment Configuration')
console.log('📦 Environment:', config.env)
console.log('🌐 API Base URL:', config.apiBaseUrl)
console.log('📱 App Title:', config.appTitle)
console.log('🐛 Debug Mode:', config.isDebugMode)
console.groupEnd()
}

View File

@ -1,5 +1,15 @@
// HTTP请求配置 // HTTP请求配置
const API_BASE_URL = 'https://api.likeichat.com' import { getApiBaseUrl, getCurrentEnv, isDebugMode } from './env.js'
const API_BASE_URL = getApiBaseUrl()
const NODE_ENV = getCurrentEnv()
const DEBUG_MODE = isDebugMode()
// 环境信息日志
if (DEBUG_MODE) {
console.log('🌍 Current Environment:', NODE_ENV)
console.log('🔗 API Base URL:', API_BASE_URL)
}
// 默认公共请求头配置 // 默认公共请求头配置
let COMMON_HEADERS = { let COMMON_HEADERS = {
@ -103,7 +113,9 @@ export async function request(url, options = {}) {
} }
try { try {
console.log('🚀 API Request:', fullUrl, config) if (DEBUG_MODE) {
console.log('🚀 API Request:', fullUrl, config)
}
const response = await fetch(fullUrl, config) const response = await fetch(fullUrl, config)
@ -113,7 +125,9 @@ export async function request(url, options = {}) {
const result = await response.json() const result = await response.json()
console.log('✅ API Response:', result) if (DEBUG_MODE) {
console.log('✅ API Response:', result)
}
// 检查业务状态 // 检查业务状态
if (result.status === false) { if (result.status === false) {
@ -122,7 +136,9 @@ export async function request(url, options = {}) {
return result return result
} catch (error) { } catch (error) {
console.error('❌ API Error:', error) if (DEBUG_MODE) {
console.error('❌ API Error:', error)
}
throw error throw error
} }
} }

View File

@ -158,31 +158,6 @@ const submitApplyJoin = async () => {
} }
} }
//
const cancelApplication = async () => {
if (!applyMessageId.value) {
return
}
try {
cancelling.value = true
await post('/team/user/join-apply-cancel', {
id: applyMessageId.value
})
//
Object.assign(teamProfile, {})
Object.assign(teamOwnUserProfile, {})
applyMessageId.value = ''
alert('Application cancelled successfully')
} catch (error) {
console.error('Failed to cancel application:', error)
} finally {
cancelling.value = false
}
}
// //
const loadInviteMessage = async () => { const loadInviteMessage = async () => {
try { try {
@ -200,21 +175,6 @@ const loadInviteMessage = async () => {
} }
} }
//
const processInvite = async (type, item) => {
Object.assign(processingItem, item)
contactForm.id = item.id
if (type === 'PASS') {
contactForm.status = 1
showContactModal.value = true
return
}
contactForm.status = 2
await submitInviteProcess()
}
// //
const submitInviteProcess = async () => { const submitInviteProcess = async () => {
try { try {
@ -237,59 +197,17 @@ const submitInviteProcess = async () => {
} }
} }
//
const getAvatarColor = (name) => {
if (!name) return '#8B5CF6'
const colors = ['#8B5CF6', '#3B82F6', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6']
const index = name.charCodeAt(0) % colors.length
return colors[index]
}
const formatAccount = (userProfile) => {
if (!userProfile) return ''
if (userProfile.ownSpecialId && userProfile.ownSpecialId.account) {
return userProfile.ownSpecialId.account
}
return userProfile.account || ''
}
const truncateName = (name) => {
if (!name) return ''
return name.length > 12 ? name.substring(0, 12) + '...' : name
}
// //
const showHelp = () => { const showHelp = () => {
showHelpModal.value = true showHelpModal.value = true
} }
const goBackToSearch = () => {
Object.assign(teamProfile, {})
Object.assign(teamOwnUserProfile, {})
applyMessageId.value = ''
}
const showInviteMessages = () => {
showInviteModal.value = true
loadInviteMessage()
}
const closeInviteModal = () => {
showInviteModal.value = false
}
const closeContactModal = () => { const closeContactModal = () => {
showContactModal.value = false showContactModal.value = false
contactForm.contact = '' contactForm.contact = ''
} }
const submitContactInfo = () => {
if (!contactForm.contact.trim()) {
alert('Please enter WhatsApp number')
return
}
submitInviteProcess()
}
// //
onMounted(() => { onMounted(() => {
@ -401,189 +319,6 @@ onMounted(() => {
cursor: not-allowed; cursor: not-allowed;
} }
.apply-tips {
background-color: #F0F9FF;
padding: 12px;
border-radius: 8px;
border-left: 4px solid #3B82F6;
}
.apply-tips p {
margin: 0;
font-size: 14px;
color: #1E40AF;
}
/* 团队信息区域 */
.team-profile-section {
display: flex;
flex-direction: column;
gap: 16px;
}
.team-profile-card {
background-color: white;
padding: 20px;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
text-align: center;
}
.team-owner-info {
margin-bottom: 24px;
}
.avatar-wrapper {
margin: 0 auto 12px auto;
width: 80px;
height: 80px;
}
.owner-avatar {
width: 80px;
height: 80px;
border-radius: 50%;
object-fit: cover;
}
.name-avatar {
width: 80px;
height: 80px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 32px;
font-weight: 600;
}
.owner-details {
text-align: center;
}
.owner-name {
font-size: 18px;
font-weight: 600;
color: #333;
margin-bottom: 4px;
}
.owner-id {
font-size: 14px;
color: #666;
}
.action-buttons {
display: flex;
gap: 12px;
justify-content: center;
}
.btn-cancel,
.btn-confirm,
.btn-cancel-apply {
padding: 12px 24px;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
}
.btn-cancel {
background-color: #F3F4F6;
color: #374151;
}
.btn-cancel:hover {
background-color: #E5E7EB;
}
.btn-confirm {
background-color: #10B981;
color: white;
}
.btn-confirm:hover:not(:disabled) {
background-color: #059669;
}
.btn-cancel-apply {
background-color: #EF4444;
color: white;
}
.btn-cancel-apply:hover:not(:disabled) {
background-color: #DC2626;
}
.btn-cancel:disabled,
.btn-confirm:disabled,
.btn-cancel-apply:disabled {
opacity: 0.6;
cursor: not-allowed;
}
/* 底部消息栏 */
.bottom-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background-color: white;
border-top: 1px solid #E5E7EB;
padding: 12px 16px;
z-index: 10;
}
.message-btn {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
width: 100%;
padding: 12px;
background-color: #8B5CF6;
color: white;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
position: relative;
transition: background-color 0.2s;
}
.message-btn:hover {
background-color: #7C3AED;
}
.message-btn.has-unread {
background-color: #EF4444;
}
.message-btn.has-unread:hover {
background-color: #DC2626;
}
.unread-badge {
position: absolute;
top: -4px;
right: -4px;
background-color: #FBBF24;
color: #92400E;
width: 20px;
height: 20px;
border-radius: 50%;
font-size: 12px;
font-weight: bold;
display: flex;
align-items: center;
justify-content: center;
}
/* 模态框样式 */ /* 模态框样式 */
.modal-overlay { .modal-overlay {
position: fixed; position: fixed;
@ -599,24 +334,6 @@ onMounted(() => {
padding: 16px; padding: 16px;
} }
.help-modal,
.invite-modal,
.contact-modal {
background: white;
border-radius: 12px;
width: 100%;
max-width: 400px;
max-height: 80vh;
overflow: hidden;
display: flex;
flex-direction: column;
}
.help-modal {
padding: 20px;
text-align: center;
max-width: 300px;
}
.help-modal h3 { .help-modal h3 {
margin: 0 0 16px 0; margin: 0 0 16px 0;
@ -638,188 +355,12 @@ onMounted(() => {
cursor: pointer; cursor: pointer;
} }
/* 邀请和联系模态框 */
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
border-bottom: 1px solid #E5E7EB;
}
.modal-header h3 { .modal-header h3 {
margin: 0; margin: 0;
font-size: 18px; font-size: 18px;
font-weight: 600; font-weight: 600;
} }
.close-btn {
background: none;
border: none;
font-size: 24px;
cursor: pointer;
color: #666;
padding: 0;
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
}
.modal-body {
padding: 16px;
overflow-y: auto;
flex: 1;
}
/* 邀请列表 */
.invite-list {
display: flex;
flex-direction: column;
gap: 12px;
}
.invite-item {
background-color: #F6FAFA;
padding: 16px;
border-radius: 8px;
}
.invite-profile {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 8px;
}
.invite-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
object-fit: cover;
}
.invite-details {
flex: 1;
}
.invite-name {
font-size: 14px;
font-weight: 600;
color: #333;
}
.invite-id,
.invite-country {
font-size: 12px;
color: #666;
margin-top: 2px;
}
.invite-status {
margin-bottom: 8px;
}
.status-pending {
background-color: #FEF3C7;
color: #D97706;
padding: 2px 8px;
border-radius: 12px;
font-size: 12px;
font-weight: 500;
}
.status-passed {
background-color: #D1FAE5;
color: #059669;
padding: 2px 8px;
border-radius: 12px;
font-size: 12px;
font-weight: 500;
}
.status-refused {
background-color: #FEE2E2;
color: #DC2626;
padding: 2px 8px;
border-radius: 12px;
font-size: 12px;
font-weight: 500;
}
.invite-message-text {
font-size: 14px;
color: #666;
margin-bottom: 12px;
word-break: break-word;
}
.invite-actions {
display: flex;
gap: 8px;
}
.btn-refuse,
.btn-accept {
flex: 1;
padding: 8px 16px;
border: none;
border-radius: 6px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: background-color 0.2s;
}
.btn-refuse {
background-color: #FEE2E2;
color: #DC2626;
}
.btn-refuse:hover {
background-color: #FECACA;
}
.btn-accept {
background-color: #D1FAE5;
color: #059669;
}
.btn-accept:hover {
background-color: #A7F3D0;
}
/* 联系方式表单 */
.contact-profile {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 16px;
}
.contact-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
object-fit: cover;
}
.contact-details {
flex: 1;
}
.contact-name {
font-size: 14px;
font-weight: 600;
color: #333;
}
.contact-id {
font-size: 12px;
color: #666;
margin-top: 2px;
}
.contact-form .form-group { .contact-form .form-group {
margin-bottom: 16px; margin-bottom: 16px;
@ -833,74 +374,11 @@ onMounted(() => {
margin-bottom: 6px; margin-bottom: 6px;
} }
.contact-input {
width: 100%;
padding: 8px 12px;
border: 1px solid #D1D5DB;
border-radius: 6px;
font-size: 14px;
}
.contact-input:focus {
outline: none;
border-color: #8B5CF6;
}
.form-actions {
display: flex;
gap: 12px;
}
.btn-submit {
flex: 1;
padding: 8px 16px;
background-color: #8B5CF6;
color: white;
border: none;
border-radius: 6px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
}
.btn-submit:hover:not(:disabled) {
background-color: #7C3AED;
}
.btn-submit:disabled {
background-color: #9CA3AF;
cursor: not-allowed;
}
/* 加载和空状态 */
.loading-container {
display: flex;
flex-direction: column;
align-items: center;
padding: 40px 20px;
color: #666;
}
.loading-spinner {
width: 32px;
height: 32px;
border: 3px solid #f3f3f3;
border-top: 3px solid #8B5CF6;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 12px;
}
@keyframes spin { @keyframes spin {
0% { transform: rotate(0deg); } 0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); } 100% { transform: rotate(360deg); }
} }
.empty-invites {
text-align: center;
padding: 40px 20px;
color: #666;
}
.empty-invites p { .empty-invites p {
margin: 0; margin: 0;
@ -919,12 +397,5 @@ onMounted(() => {
margin-top: 8px; margin-top: 8px;
} }
.action-buttons {
flex-direction: column;
}
.bottom-bar {
padding-bottom: calc(12px + env(safe-area-inset-bottom));
}
} }
</style> </style>