This commit is contained in:
tianfeng 2025-08-18 18:00:52 +08:00
parent 2574b722b9
commit cee6b25a3d
9 changed files with 228 additions and 31 deletions

View File

@ -2,3 +2,9 @@
VITE_NODE_ENV=development
VITE_API_BASE_URL=https://api.likeichat.com
VITE_APP_TITLE=Likei H5 (Development)
# 普通用户
VITE_USER_AUTH=5439442DA903907EF23975732147F0D4.djIlM0ExOTU0MDU5NzkzOTYzMzkzMDI1JTNBTElLRUklM0ExNzU4MDIxMTM0NTM2JTNBMTc1NTQyOTEzNDUzNg==
# 代理用户 8826603
# VITE_USER_AUTH=747E27BE38B21A129CE41BB1F80EA924.djIlM0ExOTU3MzU2MTM4NTIzMDY2MzY5JTNBTElLRUklM0ExNzU4MDk3MDg4NDA0JTNBMTc1NTUwNTA4ODQwNA==

View File

@ -137,13 +137,12 @@ export function sendTeamApplyJoin(data) {
/**
* 获取团队申请记录
* @param {Object} params - 查询参数
* @param {string} params.teamId - 团队ID
* @param {string} params.status - 状态 (WAIT/AGREE/REJECT)
* @param {string} teamId - 团队ID
* @param {string} status - 状态 (WAIT/AGREE/REJECT)
* @returns {Promise} 返回申请记录列表
*/
export function getTeamApplyRecord(params) {
return get('/team/user/apply/record', { params })
export function getTeamApplyRecord(teamId, status) {
return get(`/team/user/apply/record?teamId=${teamId}&status=${status}`)
}
/**

View File

@ -3,6 +3,8 @@
* 用于H5页面与原生APP之间的通信
*/
import {COMMON_HEADERS} from "@/utils/http.js";
/**
* 检测是否为iOS系统
* @returns {boolean}
@ -182,10 +184,10 @@ export function connectApplication(renderFun) {
// 开发环境可以提供模拟数据
if (process.env.NODE_ENV === 'development') {
const mockAccess = JSON.stringify({
'Authorization': 'Bearer 5439442DA903907EF23975732147F0D4.djIlM0ExOTU0MDU5NzkzOTYzMzkzMDI1JTNBTElLRUklM0ExNzU4MDIxMTM0NTM2JTNBMTc1NTQyOTEzNDUzNg==',
'Req-Lang': 'en',
'Req-App-Intel': 'build=1.0;version=2.1;channel=official;Req-Imei=mock-imei',
'Req-Sys-Origin': 'origin=LIKEI;originChild=LIKEI'
'Authorization': COMMON_HEADERS.authorization,
'Req-Lang': COMMON_HEADERS['req-lang'],
'Req-App-Intel': COMMON_HEADERS['req-app-intel'],
'Req-Sys-Origin': COMMON_HEADERS['req-sys-origin']
})
setTimeout(() => renderFun(mockAccess), 100)
}

View File

@ -8,6 +8,11 @@ export const ENV_TYPES = {
TEST: 'test'
}
// 获取当前用户Token
export function getUserAuth() {
return import.meta.env.VITE_USER_AUTH
}
// 获取当前环境
export function getCurrentEnv() {
return import.meta.env.VITE_NODE_ENV || import.meta.env.MODE || ENV_TYPES.DEVELOPMENT

View File

@ -1,5 +1,5 @@
// HTTP请求配置
import { getApiBaseUrl, getCurrentEnv, isDebugMode } from './env.js'
import {getApiBaseUrl, getCurrentEnv, getUserAuth, isDebugMode} from './env.js'
const API_BASE_URL = getApiBaseUrl()
const NODE_ENV = getCurrentEnv()
@ -11,9 +11,10 @@ if (DEBUG_MODE) {
console.log('🔗 API Base URL:', API_BASE_URL)
}
const token = getUserAuth()
// 默认公共请求头配置
let COMMON_HEADERS = {
'authorization': 'Bearer 5439442DA903907EF23975732147F0D4.djIlM0ExOTU0MDU5NzkzOTYzMzkzMDI1JTNBTElLRUklM0ExNzU4MDIxMTM0NTM2JTNBMTc1NTQyOTEzNDUzNg==',
'authorization': `Bearer ${token}`,
'req-app-intel': 'version=1.0.0;build=1;model=SM-G9550;sysVersion=9;channel=Google',
'req-client': 'Android',
'req-imei': '8fa54d728ab449e04f9292329ed44bda',
@ -81,6 +82,9 @@ export function setHeadersFromApp(headerInfo) {
updateCommonHeaders(updatedHeaders)
}
// 在http.js中添加导出
export { COMMON_HEADERS }
/**
* 通用HTTP请求函数
* @param {string} url - 请求URL

117
src/utils/userStore.js Normal file
View File

@ -0,0 +1,117 @@
/**
* 用户信息存储
*/
// 用户信息缓存
let userProfileCache = null
let teamInfoCache = null
/**
* 设置用户信息缓存
* @param {Object} memberProfile - 用户资料
* @param {Object} teamInfo - 团队信息
*/
export function setUserInfo(memberProfile, teamInfo = null) {
userProfileCache = memberProfile
teamInfoCache = teamInfo
// 可选存储到localStorage以便持久化
if (memberProfile) {
localStorage.setItem('userProfile', JSON.stringify(memberProfile))
}
if (teamInfo) {
localStorage.setItem('teamInfo', JSON.stringify(teamInfo))
}
}
/**
* 获取用户信息缓存
* @returns {Object|null} 用户资料
*/
export function getUserProfile() {
if (userProfileCache) {
return userProfileCache
}
// 从localStorage恢复
const stored = localStorage.getItem('userProfile')
if (stored) {
try {
userProfileCache = JSON.parse(stored)
return userProfileCache
} catch (error) {
console.error('解析用户缓存失败:', error)
}
}
return null
}
/**
* 获取团队信息缓存
* @returns {Object|null} 团队信息
*/
export function getTeamInfo() {
if (teamInfoCache) {
return teamInfoCache
}
// 从localStorage恢复
const stored = localStorage.getItem('teamInfo')
if (stored) {
try {
teamInfoCache = JSON.parse(stored)
return teamInfoCache
} catch (error) {
console.error('解析团队缓存失败:', error)
}
}
return null
}
/**
* 清除用户信息缓存
*/
export function clearUserProfile() {
userProfileCache = null
teamInfoCache = null
localStorage.removeItem('userProfile')
localStorage.removeItem('teamInfo')
}
/**
* 获取用户ID
* @returns {string|null}
*/
export function getUserId() {
const profile = getUserProfile()
return profile?.id || null
}
/**
* 获取TeamID
* @returns {string|null}
*/
export function getTeamId() {
const profile = getTeamInfo()
return profile?.id || null
}
/**
* 获取用户昵称
* @returns {string|null}
*/
export function getUserNickname() {
const profile = getUserProfile()
return profile?.userNickname || null
}
/**
* 获取用户账号
* @returns {string|null}
*/
export function getUserAccount() {
const profile = getUserProfile()
return profile?.account || null
}

View File

@ -18,6 +18,7 @@
type="text"
placeholder="Please enter the agent ID"
class="agent-input"
@input="onAgentIdChange"
/>
</div>
@ -28,12 +29,18 @@
<!-- 申请按钮 -->
<button
v-if="applyRecords.length === 0"
class="apply-btn"
@click="submitApplication"
:disabled="!agentId.trim() || isLoading"
>
{{ isLoading ? 'Applying...' : 'Apply' }}
</button>
<!-- 已有申请记录时的提示 -->
<div v-else class="existing-application">
<p>您已有在处理中的申请请等待审核结果</p>
</div>
</div>
</div>
@ -80,13 +87,25 @@ const applyRecords = ref([])
//
const fetchApplyRecords = async () => {
if (!agentId.value.trim()) return
try {
const response = await getTeamApplyRecord({})
const response = await getTeamApplyRecord(agentId.value.trim(), 'WAIT')
if (response.status && response.body) {
applyRecords.value = response.body
}
} catch (error) {
console.error('获取申请记录失败:', error)
applyRecords.value = []
}
}
// ID
const onAgentIdChange = () => {
if (agentId.value.trim()) {
fetchApplyRecords()
} else {
applyRecords.value = []
}
}
@ -150,10 +169,10 @@ const getStatusClass = (status) => {
return classMap[status] || ''
}
//
onMounted(() => {
fetchApplyRecords()
})
//
// onMounted(() => {
// fetchApplyRecords()
// })
</script>
<style scoped>
@ -361,4 +380,18 @@ onMounted(() => {
background-color: #FEE2E2;
color: #DC2626;
}
.existing-application {
padding: 12px;
background-color: #FEF3C7;
border: 1px solid #F59E0B;
border-radius: 6px;
text-align: center;
}
.existing-application p {
margin: 0;
font-size: 14px;
color: #D97706;
}
</style>

View File

@ -135,6 +135,7 @@ import { useRouter } from 'vue-router'
import MobileHeader from '../components/MobileHeader.vue'
import { getBankBalance, getUserIdentity, getTeamEntry } from '../api/wallet.js'
import { connectApplication, parseAccessOrigin, parseHeader, setHttpHeaders, isInApp } from '../utils/appBridge.js'
import { setUserInfo } from '../utils/userStore.js'
const router = useRouter()
@ -146,13 +147,6 @@ const headerInfo = ref({})
const userProfile = ref(null)
const identityChecked = ref(false)
//
const identities = [
{ label: 'Host', value: 'host' },
{ label: 'Agency', value: 'agency' },
{ label: 'Coin Seller', value: 'coin-seller' }
]
// APP
const connectToApp = async () => {
console.group('🔗 APP Connection Process')
@ -291,8 +285,11 @@ const fetchTeamEntry = async () => {
if (response && response.status && response.body) {
userProfile.value = response.body
//
//
if (response.body.memberProfile) {
setUserInfo(response.body.memberProfile, response.body.teamProfile)
//
userInfo.userNickname = response.body.memberProfile.userNickname
userInfo.account = response.body.memberProfile.account
}

View File

@ -17,11 +17,15 @@
<div class="user-info">
<div class="user-avatar">
<img v-if="message.avatar" :src="message.avatar" :alt="message.name" />
<span v-else>{{ message.name }}</span>
<span v-else>{{ message.name?.charAt(0) || 'U' }}</span>
</div>
<div class="user-details">
<h4>{{ message.name }}</h4>
<p>ID: {{ message.id }}</p>
<h4>{{ message.name || 'Unknown User' }}</h4>
<p>ID: {{ message.account || message.userId }}</p>
<p v-if="message.countryName" class="country-info">
{{ message.countryName }} ({{ message.countryCode }})
</p>
<p class="apply-time">{{ new Date(message.createTime).toLocaleString() }}</p>
</div>
</div>
<div class="action-buttons">
@ -48,6 +52,7 @@ import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import MobileHeader from '../components/MobileHeader.vue'
import { getApplyRecord } from '../api/teamBill.js'
import {getTeamId, getTeamInfo, getUserId} from "@/utils/userStore.js";
const router = useRouter()
const loading = ref(false)
@ -67,10 +72,29 @@ const mockMessages = [
const fetchMessages = async () => {
loading.value = true
try {
const response = await getApplyRecord('1954059793963393025', 'WAIT') //
loading.value = false
const response = await getApplyRecord(getTeamId(), 'WAIT')
if (response.status && response.body) {
//
messages.value = response.body.map(item => ({
id: item.id,
reason: item.reason,
teamId: item.teamId,
status: item.status,
createTime: item.createTime,
//
userId: item.createUserProfile.id,
account: item.createUserProfile.account,
name: item.createUserProfile.userNickname,
avatar: item.createUserProfile.userAvatar,
userSex: item.createUserProfile.userSex,
age: item.createUserProfile.age,
countryName: item.createUserProfile.countryName,
countryCode: item.createUserProfile.countryCode
}))
}
} catch (error) {
console.error('获取消息失败:', error)
} finally {
loading.value = false
}
@ -189,11 +213,21 @@ onMounted(() => {
}
.user-details p {
margin: 0;
margin: 0 0 2px 0;
font-size: 14px;
color: #666;
}
.country-info {
font-size: 12px !important;
color: #8B5CF6 !important;
}
.apply-time {
font-size: 12px !important;
color: #999 !important;
}
.action-buttons {
display: flex;
gap: 8px;