预发布版本
This commit is contained in:
parent
11c24e9d0c
commit
8a546e1b18
@ -22,7 +22,7 @@ export const getTeamMembers = async (teamId) => {
|
||||
*/
|
||||
export const deleteMember = async (memberId) => {
|
||||
try {
|
||||
const response = await post('/team/member/remove', {
|
||||
const response = await post('/team-member/client/removeMemberTeam', {
|
||||
memberId: memberId
|
||||
})
|
||||
return response
|
||||
|
||||
@ -55,10 +55,64 @@ export function userBankSearchUserProfile(type, account) {
|
||||
|
||||
/**
|
||||
* 获取用户身份信息
|
||||
* @param {string} userId - 用户ID
|
||||
* @returns {Promise} 返回用户身份权限信息
|
||||
*/
|
||||
export function getUserIdentity() {
|
||||
return get('/app/h5/1911661502909562881/identity')
|
||||
export function getUserIdentity(userId) {
|
||||
return get(`/app/h5/${userId}/identity`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取团队入口信息
|
||||
* @returns {Promise} 返回团队和用户信息
|
||||
*/
|
||||
export function getTeamEntry() {
|
||||
return get('/team/entry')
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验金币销售商权限
|
||||
* @returns {Promise} 返回是否具有销售商权限
|
||||
*/
|
||||
export function checkFreightDealer() {
|
||||
return get('/wallet/freight/seller/check/dealer')
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取金币销售商余额
|
||||
* @returns {Promise} 返回销售商金币余额
|
||||
*/
|
||||
export function getFreightBalance() {
|
||||
return get('/wallet/freight/balance')
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索用户
|
||||
* @param {string} account - 用户账号
|
||||
* @returns {Promise} 返回用户信息
|
||||
*/
|
||||
export function searchFreightUser(account) {
|
||||
return get(`/wallet/freight/search-user?account=${account}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 金币充值
|
||||
* @param {Object} data - 充值数据
|
||||
* @param {number} data.acceptUserId - 接收用户ID
|
||||
* @param {number} data.quantity - 充值数量
|
||||
* @returns {Promise} 返回剩余可用余额
|
||||
*/
|
||||
export function freightRecharge(data) {
|
||||
return post('/wallet/freight/ship', data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取金币交易流水
|
||||
* @param {string} userId - 用户ID
|
||||
* @returns {Promise} 返回交易流水记录
|
||||
*/
|
||||
export function getFreightWaterFlow(userId) {
|
||||
return get(`/wallet/freight/balance/running/water/client/flowByUserId?userId=${userId}`)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -35,7 +35,7 @@ export function connectApplication(renderFun) {
|
||||
window.renderData = renderFun
|
||||
// 兼容历史版本
|
||||
window.getIosAccessOriginParam = renderFun
|
||||
|
||||
|
||||
try {
|
||||
if (ios()) {
|
||||
// iOS可能需要特殊处理,这里先使用通用方法
|
||||
@ -55,10 +55,10 @@ export function connectApplication(renderFun) {
|
||||
// 开发环境可以提供模拟数据
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
const mockAccess = JSON.stringify({
|
||||
'Authorization': 'Bearer mock-token-for-development',
|
||||
'Authorization': 'Bearer F77126B08E13987C3AD88B6015C5B777.djIlM0ExOTU0MDU5NzkzOTYzMzkzMDI1JTNBTElLRUklM0ExNzU3NzYzODU5NzE1JTNBMTc1NTE3MTg1OTcxNQ==',
|
||||
'Req-Lang': 'en',
|
||||
'Req-App-Intel': 'build=1.0;version=2.1;channel=official;Req-Imei=mock-imei',
|
||||
'Req-Sys-Origin': 'origin=web;child=browser'
|
||||
'Req-Sys-Origin': 'origin=LIKEI;originChild=LIKEI'
|
||||
})
|
||||
setTimeout(() => renderFun(mockAccess), 100)
|
||||
}
|
||||
@ -102,13 +102,13 @@ export function parseHeader(head) {
|
||||
|
||||
/**
|
||||
* 解析键值对字符串 (如: "key1=value1;key2=value2")
|
||||
* @param {string} values
|
||||
* @param {string} values
|
||||
* @returns {Object}
|
||||
*/
|
||||
function getKeyValObj(values) {
|
||||
const keyValBody = {}
|
||||
if (!values) return keyValBody
|
||||
|
||||
|
||||
const valueArray = values.split(';')
|
||||
for (let index = 0; index < valueArray.length; index++) {
|
||||
const keyVal = valueArray[index]
|
||||
@ -150,7 +150,7 @@ export function setHttpHeaders(headerInfo) {
|
||||
}).catch(error => {
|
||||
console.error('Failed to update HTTP headers:', error)
|
||||
})
|
||||
|
||||
|
||||
console.log('🔑 Authorization token set:', headerInfo.authorization)
|
||||
console.log('🌍 Language set:', headerInfo.reqLang)
|
||||
console.log('📱 App info:', {
|
||||
|
||||
@ -21,7 +21,6 @@
|
||||
<!-- 账户状态标签 -->
|
||||
<div class="account-tags">
|
||||
<span class="tag agency-tag">🏢 Agency</span>
|
||||
<span class="tag salary-tag">💰 Salary</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -636,9 +635,7 @@ onMounted(() => {
|
||||
|
||||
.team-bill-card .card-content {
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 通用卡片内容样式 */
|
||||
@ -650,20 +647,37 @@ onMounted(() => {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1F2937;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.card-link {
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
right: 16px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
color: #6B7280;
|
||||
gap: 4px;
|
||||
color: #8B5CF6;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.card-link:hover {
|
||||
color: #7C3AED;
|
||||
}
|
||||
|
||||
.card-link .arrow {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.card-details {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.detail-row {
|
||||
|
||||
@ -40,7 +40,14 @@
|
||||
>
|
||||
<div class="user-info">
|
||||
<div class="user-avatar">
|
||||
<span>{{ user.name.charAt(0) }}</span>
|
||||
<img
|
||||
v-if="user.userAvatar"
|
||||
:src="user.userAvatar"
|
||||
:alt="user.name"
|
||||
class="avatar-image"
|
||||
@error="(e) => e.target.style.display = 'none'"
|
||||
/>
|
||||
<span v-if="!user.userAvatar" class="avatar-text">{{ user.name.charAt(0) }}</span>
|
||||
</div>
|
||||
<div class="user-details">
|
||||
<h4>{{ user.name }}</h4>
|
||||
@ -81,6 +88,7 @@ import { ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import MobileHeader from '../components/MobileHeader.vue'
|
||||
import { setSelectedUser } from '../utils/coinSellerStore.js'
|
||||
import { searchFreightUser } from '../api/wallet.js'
|
||||
|
||||
const router = useRouter()
|
||||
const searchQuery = ref('')
|
||||
@ -104,7 +112,7 @@ const mockUsers = [
|
||||
]
|
||||
|
||||
// 执行搜索
|
||||
const performSearch = () => {
|
||||
const performSearch = async () => {
|
||||
if (!searchQuery.value.trim()) {
|
||||
searchResults.value = []
|
||||
return
|
||||
@ -112,15 +120,28 @@ const performSearch = () => {
|
||||
|
||||
isSearching.value = true
|
||||
|
||||
// 模拟搜索延迟
|
||||
setTimeout(() => {
|
||||
const query = searchQuery.value.toLowerCase()
|
||||
searchResults.value = mockUsers.filter(user =>
|
||||
user.name.toLowerCase().includes(query) ||
|
||||
user.id.includes(query)
|
||||
)
|
||||
try {
|
||||
const response = await searchFreightUser(searchQuery.value.trim())
|
||||
|
||||
if (response && response.status && response.body && response.body.userProfile) {
|
||||
const profile = response.body.userProfile
|
||||
searchResults.value = [{
|
||||
id: profile.account || profile.id,
|
||||
userId: profile.id, // 保存数值型ID用于接口调用
|
||||
name: profile.userNickname || 'User',
|
||||
userNickname: profile.userNickname,
|
||||
account: profile.account,
|
||||
userAvatar: profile.userAvatar
|
||||
}]
|
||||
} else {
|
||||
searchResults.value = []
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('搜索用户失败:', error)
|
||||
searchResults.value = []
|
||||
} finally {
|
||||
isSearching.value = false
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
|
||||
// 清除搜索
|
||||
@ -148,7 +169,11 @@ const selectUser = (user) => {
|
||||
// 将选中的用户信息保存到全局状态
|
||||
setSelectedUser({
|
||||
id: user.id,
|
||||
name: user.name
|
||||
userId: user.userId, // 数值型ID
|
||||
name: user.name,
|
||||
userNickname: user.userNickname,
|
||||
account: user.account,
|
||||
userAvatar: user.userAvatar
|
||||
})
|
||||
|
||||
console.log('Selected user:', user)
|
||||
@ -267,6 +292,21 @@ const selectUser = (user) => {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
margin-right: 12px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.avatar-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: 25px;
|
||||
}
|
||||
|
||||
.avatar-text {
|
||||
color: white;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.user-details h4 {
|
||||
|
||||
@ -2,25 +2,39 @@
|
||||
<div class="coin-seller gradient-background-circles">
|
||||
<MobileHeader title="Coin Seller" />
|
||||
|
||||
<div class="content">
|
||||
<!-- 权限校验加载状态 -->
|
||||
<div v-if="checkingAccess" class="loading-container">
|
||||
<div class="loading-spinner"></div>
|
||||
<p>正在校验权限...</p>
|
||||
</div>
|
||||
|
||||
<!-- 主要内容 -->
|
||||
<div v-else-if="dealerAccess" class="content">
|
||||
<!-- 用户信息卡片 -->
|
||||
<div class="user-card">
|
||||
<div class="user-info">
|
||||
<div class="avatar">
|
||||
<span>{{ userInfo.name.charAt(0) }}</span>
|
||||
<img
|
||||
v-if="userInfo.userAvatar"
|
||||
:src="userInfo.userAvatar"
|
||||
:alt="userInfo.userNickname || userInfo.name"
|
||||
class="avatar-image"
|
||||
@error="handleAvatarError"
|
||||
/>
|
||||
<span v-else class="avatar-text">{{ (userInfo.userNickname || userInfo.name).charAt(0) }}</span>
|
||||
</div>
|
||||
<div class="user-details">
|
||||
<h3>{{ userInfo.name }}</h3>
|
||||
<p>ID: {{ userInfo.id }}</p>
|
||||
<h3>{{ userInfo.userNickname || userInfo.name }}</h3>
|
||||
<p>ID: {{ userInfo.account || userInfo.id }}</p>
|
||||
</div>
|
||||
<button class="settings-btn" @click="goToSettings">
|
||||
<span>⚙️</span>
|
||||
<span>📈</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 账户状态标签 -->
|
||||
<div class="account-tags">
|
||||
<span class="tag seller-tag">🪙 Seller</span>
|
||||
<span class="tag seller-tag">🪙 Salary</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -29,7 +43,8 @@
|
||||
<h3>My coins:</h3>
|
||||
<div class="coins-display">
|
||||
<span class="coin-icon">🪙</span>
|
||||
<span class="coins-amount">{{ coinsAmount }}</span>
|
||||
<span v-if="loadingBalance" class="coins-loading">Loading...</span>
|
||||
<span v-else class="coins-amount">{{ coinsAmount }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -67,10 +82,10 @@
|
||||
</div>
|
||||
<button
|
||||
class="recharge-btn"
|
||||
:disabled="!canRecharge"
|
||||
:disabled="!canRecharge || isRecharging"
|
||||
@click="rechargeNow"
|
||||
>
|
||||
Recharge now
|
||||
{{ isRecharging ? 'Processing...' : 'Recharge now' }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -82,17 +97,26 @@ import { ref, computed, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import MobileHeader from '../components/MobileHeader.vue'
|
||||
import { getSelectedUser, clearSelectedUser } from '../utils/coinSellerStore.js'
|
||||
import { checkFreightDealer, getTeamEntry, getFreightBalance, searchFreightUser, freightRecharge } from '../api/wallet.js'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
// 用户信息
|
||||
const userInfo = ref({
|
||||
name: 'User1',
|
||||
id: '1234567890'
|
||||
id: '1234567890',
|
||||
userNickname: 'User1',
|
||||
account: '1234567890',
|
||||
userAvatar: null
|
||||
})
|
||||
|
||||
// 权限校验状态
|
||||
const dealerAccess = ref(false)
|
||||
const checkingAccess = ref(true)
|
||||
|
||||
// 金币数量
|
||||
const coinsAmount = ref('123456478')
|
||||
const coinsAmount = ref('0')
|
||||
const loadingBalance = ref(false)
|
||||
|
||||
// 选中的用户
|
||||
const selectedUser = ref({
|
||||
@ -100,6 +124,73 @@ const selectedUser = ref({
|
||||
name: ''
|
||||
})
|
||||
|
||||
// 校验销售商权限
|
||||
const checkDealerAccess = async () => {
|
||||
try {
|
||||
checkingAccess.value = true
|
||||
const response = await checkFreightDealer()
|
||||
|
||||
if (response && response.status !== undefined) {
|
||||
dealerAccess.value = response.body === true
|
||||
|
||||
if (!dealerAccess.value) {
|
||||
// 没有权限,跳转回上一页或首页
|
||||
alert('您没有金币销售商权限')
|
||||
router.go(-1)
|
||||
return
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('权限校验失败:', error)
|
||||
dealerAccess.value = false
|
||||
router.go(-1)
|
||||
} finally {
|
||||
checkingAccess.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
const fetchUserInfo = async () => {
|
||||
try {
|
||||
const response = await getTeamEntry()
|
||||
|
||||
if (response && response.status && response.body && response.body.memberProfile) {
|
||||
const profile = response.body.memberProfile
|
||||
userInfo.value = {
|
||||
name: profile.userNickname || 'User',
|
||||
id: profile.account || profile.id,
|
||||
userNickname: profile.userNickname,
|
||||
account: profile.account,
|
||||
userAvatar: profile.userAvatar
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取用户信息失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取金币余额
|
||||
const fetchFreightBalance = async () => {
|
||||
try {
|
||||
loadingBalance.value = true
|
||||
const response = await getFreightBalance()
|
||||
|
||||
if (response && response.status && response.body !== undefined) {
|
||||
coinsAmount.value = response.body.toString()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取金币余额失败:', error)
|
||||
} finally {
|
||||
loadingBalance.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 处理头像加载错误
|
||||
const handleAvatarError = () => {
|
||||
console.log('头像加载失败,使用默认显示')
|
||||
userInfo.value.userAvatar = null
|
||||
}
|
||||
|
||||
// 初始化用户信息
|
||||
const initializeUser = () => {
|
||||
const savedUser = getSelectedUser()
|
||||
@ -110,10 +201,11 @@ const initializeUser = () => {
|
||||
|
||||
// 充值金额
|
||||
const rechargeAmount = ref('')
|
||||
const isRecharging = ref(false)
|
||||
|
||||
// 是否可以充值
|
||||
const canRecharge = computed(() => {
|
||||
return selectedUser.value.id && rechargeAmount.value && parseFloat(rechargeAmount.value) > 0
|
||||
return selectedUser.value.id && rechargeAmount.value && parseFloat(rechargeAmount.value) > 0 && !isRecharging.value
|
||||
})
|
||||
|
||||
// 跳转到设置
|
||||
@ -127,19 +219,64 @@ const searchUser = () => {
|
||||
}
|
||||
|
||||
// 立即充值
|
||||
const rechargeNow = () => {
|
||||
if (!canRecharge.value) return
|
||||
const rechargeNow = async () => {
|
||||
if (!canRecharge.value || isRecharging.value) return
|
||||
|
||||
alert(`Recharge ${rechargeAmount.value} coins to ${selectedUser.value.name}`)
|
||||
const amount = parseFloat(rechargeAmount.value)
|
||||
if (amount <= 0) {
|
||||
alert('请输入正确的充值金额')
|
||||
return
|
||||
}
|
||||
|
||||
// 重置表单
|
||||
rechargeAmount.value = ''
|
||||
// 可以选择是否清除用户选择
|
||||
// 需要获取接收用户的ID(从用户搜索结果中获取)
|
||||
const acceptUserId = selectedUser.value.userId || selectedUser.value.id
|
||||
if (!acceptUserId) {
|
||||
alert('无法获取用户ID,请重新选择用户')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
isRecharging.value = true
|
||||
|
||||
const rechargeData = {
|
||||
acceptUserId: parseInt(acceptUserId),
|
||||
quantity: amount
|
||||
}
|
||||
|
||||
const response = await freightRecharge(rechargeData)
|
||||
|
||||
if (response && response.status) {
|
||||
// 充值成功,更新余额
|
||||
if (response.body !== undefined) {
|
||||
coinsAmount.value = response.body.toString()
|
||||
}
|
||||
|
||||
alert(`成功向 ${selectedUser.value.name} 充值 ${amount} 金币`)
|
||||
|
||||
// 重置表单
|
||||
rechargeAmount.value = ''
|
||||
} else {
|
||||
alert('充值失败,请重试')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('充值失败:', error)
|
||||
alert('充值失败,请检查网络后重试')
|
||||
} finally {
|
||||
isRecharging.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 页面加载时初始化用户信息
|
||||
onMounted(() => {
|
||||
initializeUser()
|
||||
// 页面加载时校验权限和初始化用户信息
|
||||
onMounted(async () => {
|
||||
// 先校验权限
|
||||
await checkDealerAccess()
|
||||
|
||||
// 权限校验通过后获取用户信息和金币余额
|
||||
if (dealerAccess.value) {
|
||||
await fetchUserInfo()
|
||||
await fetchFreightBalance()
|
||||
initializeUser()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -148,6 +285,30 @@ onMounted(() => {
|
||||
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
}
|
||||
|
||||
/* 加载状态 */
|
||||
.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 #F59E0B;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 16px;
|
||||
position: relative;
|
||||
@ -181,6 +342,21 @@ onMounted(() => {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin-right: 12px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.avatar-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: 25px;
|
||||
}
|
||||
|
||||
.avatar-text {
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.user-details {
|
||||
@ -258,6 +434,12 @@ onMounted(() => {
|
||||
color: #F59E0B;
|
||||
}
|
||||
|
||||
.coins-loading {
|
||||
font-size: 16px;
|
||||
color: #9ca3af;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* 用户搜索部分 */
|
||||
.user-section {
|
||||
background-color: white;
|
||||
|
||||
@ -19,11 +19,11 @@
|
||||
|
||||
<div class="user-info">
|
||||
<div class="avatar">
|
||||
<span>{{ userInfo.name.charAt(0) }}</span>
|
||||
<span>{{ (userInfo.userNickname || userInfo.name).charAt(0) }}</span>
|
||||
</div>
|
||||
<div class="user-details">
|
||||
<h3>{{ userInfo.name }}</h3>
|
||||
<p>ID: {{ userInfo.id }}</p>
|
||||
<h3>{{ userInfo.userNickname || userInfo.name }}</h3>
|
||||
<p>ID: {{ userInfo.account || userInfo.id }}</p>
|
||||
<!-- 显示系统信息 -->
|
||||
<p v-if="headerInfo.sysOrigin" class="system-info">
|
||||
{{ headerInfo.sysOrigin }}
|
||||
@ -132,7 +132,7 @@
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import MobileHeader from '../components/MobileHeader.vue'
|
||||
import { getBankBalance, getUserIdentity } from '../api/wallet.js'
|
||||
import { getBankBalance, getUserIdentity, getTeamEntry } from '../api/wallet.js'
|
||||
import { connectApplication, parseAccessOrigin, parseHeader, setHttpHeaders, isInApp } from '../utils/appBridge.js'
|
||||
|
||||
const router = useRouter()
|
||||
@ -142,6 +142,8 @@ const currentIdentity = ref('host')
|
||||
const loading = ref(false)
|
||||
const appConnected = ref(false)
|
||||
const headerInfo = ref({})
|
||||
const userProfile = ref(null)
|
||||
const identityChecked = ref(false)
|
||||
|
||||
// 身份选项(保留显示用,但不再用于切换)
|
||||
const identities = [
|
||||
@ -151,16 +153,16 @@ const identities = [
|
||||
]
|
||||
|
||||
// 连接APP并获取认证信息
|
||||
const connectToApp = () => {
|
||||
const connectToApp = async () => {
|
||||
if (!isInApp()) {
|
||||
console.warn('Not running in APP environment')
|
||||
// 非APP环境,直接执行后续逻辑
|
||||
appConnected.value = true
|
||||
checkUserIdentity()
|
||||
await fetchTeamEntry()
|
||||
return
|
||||
}
|
||||
|
||||
connectApplication(access => {
|
||||
connectApplication(async (access) => {
|
||||
console.log('Received access from APP:', access)
|
||||
|
||||
const result = parseAccessOrigin(access)
|
||||
@ -176,8 +178,8 @@ const connectToApp = () => {
|
||||
|
||||
console.log('APP connection established:', headerInfo.value)
|
||||
|
||||
// 连接成功后获取用户身份和银行余额
|
||||
checkUserIdentity()
|
||||
// 连接成功后获取团队信息和银行余额
|
||||
await fetchTeamEntry()
|
||||
fetchBankBalance()
|
||||
} else {
|
||||
console.error('Failed to parse access origin:', result.error)
|
||||
@ -213,7 +215,9 @@ const fetchBankBalance = async () => {
|
||||
// 用户信息
|
||||
const userInfo = reactive({
|
||||
name: 'User1',
|
||||
id: '1234567890'
|
||||
id: '1234567890',
|
||||
userNickname: 'User1',
|
||||
account: '1234567890'
|
||||
})
|
||||
|
||||
// 收入信息
|
||||
@ -250,24 +254,70 @@ const goToNotification = () => {
|
||||
router.push('/host-setting')
|
||||
}
|
||||
|
||||
// 获取用户身份并自动跳转
|
||||
const checkUserIdentity = async () => {
|
||||
// 获取团队入口信息
|
||||
const fetchTeamEntry = async () => {
|
||||
try {
|
||||
const response = await getUserIdentity()
|
||||
const response = await getTeamEntry()
|
||||
|
||||
if (response && response.status && response.body) {
|
||||
userProfile.value = response.body
|
||||
|
||||
// 更新用户信息显示
|
||||
if (response.body.memberProfile) {
|
||||
userInfo.userNickname = response.body.memberProfile.userNickname
|
||||
userInfo.account = response.body.memberProfile.account
|
||||
}
|
||||
|
||||
// 获取用户ID后检查身份
|
||||
const userId = response.body.memberProfile?.id
|
||||
if (userId) {
|
||||
await checkUserIdentity(userId)
|
||||
}
|
||||
|
||||
return userId
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取团队信息失败:', error)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// 获取用户身份并自动跳转
|
||||
const checkUserIdentity = async (userId) => {
|
||||
if (!userId) {
|
||||
console.error('用户ID不存在')
|
||||
return
|
||||
}
|
||||
|
||||
// 防止重复检查
|
||||
if (identityChecked.value) {
|
||||
console.log('身份已检查,跳过')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
identityChecked.value = true
|
||||
const response = await getUserIdentity(userId)
|
||||
|
||||
if (response && response.status && response.body) {
|
||||
const { freightAgent, anchor, agent } = response.body
|
||||
|
||||
|
||||
console.log('用户身份权限:', { freightAgent, anchor, agent })
|
||||
|
||||
// 根据优先级判断:freightAgent > anchor > agent
|
||||
if (freightAgent) {
|
||||
router.push('/coin-seller')
|
||||
console.log('跳转到 coin-seller')
|
||||
router.replace('/coin-seller')
|
||||
} else if (anchor) {
|
||||
router.push('/agency-center')
|
||||
console.log('跳转到 agency-center')
|
||||
router.replace('/agency-center')
|
||||
} else if (agent) {
|
||||
// 保持在当前Host页面
|
||||
console.log('保持在 host-center')
|
||||
currentIdentity.value = 'host'
|
||||
} else {
|
||||
// 如果没有任何权限,默认保持在Host页面
|
||||
console.log('无特殊权限,保持在 host-center')
|
||||
currentIdentity.value = 'host'
|
||||
}
|
||||
}
|
||||
@ -288,9 +338,9 @@ const transfer = () => {
|
||||
}
|
||||
|
||||
// 页面加载时先连接APP,然后获取数据
|
||||
onMounted(() => {
|
||||
onMounted(async () => {
|
||||
// 先连接APP获取认证信息
|
||||
connectToApp()
|
||||
await connectToApp()
|
||||
|
||||
// 如果不是APP环境,直接获取银行余额
|
||||
if (!isInApp()) {
|
||||
|
||||
@ -25,7 +25,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="record-amount">
|
||||
<span class="coins-amount">{{ record.amount }} coins</span>
|
||||
<span :class="['coins-amount', record.type === 0 ? 'positive' : 'negative']">{{ record.amount }} coins</span>
|
||||
<span class="transaction-type">{{ getTransactionType(record.type, record.origin) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -43,10 +44,12 @@
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import MobileHeader from '../components/MobileHeader.vue'
|
||||
import { getFreightWaterFlow, getTeamEntry } from '../api/wallet.js'
|
||||
|
||||
const router = useRouter()
|
||||
const loading = ref(false)
|
||||
const records = ref([])
|
||||
const currentUserId = ref(null)
|
||||
|
||||
// 模拟记录数据
|
||||
const mockRecords = [
|
||||
@ -73,24 +76,93 @@ const mockRecords = [
|
||||
}
|
||||
]
|
||||
|
||||
// 获取当前用户ID
|
||||
const fetchCurrentUserId = async () => {
|
||||
try {
|
||||
const response = await getTeamEntry()
|
||||
if (response && response.status && response.body && response.body.memberProfile) {
|
||||
currentUserId.value = response.body.memberProfile.id
|
||||
return response.body.memberProfile.id
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取用户ID失败:', error)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// 格式化时间
|
||||
const formatTime = (timestamp) => {
|
||||
const date = new Date(timestamp)
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
const hours = String(date.getHours()).padStart(2, '0')
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0')
|
||||
const seconds = String(date.getSeconds()).padStart(2, '0')
|
||||
|
||||
return `${year}.${month}.${day} ${hours}:${minutes}:${seconds}`
|
||||
}
|
||||
|
||||
// 获取交易类型显示
|
||||
const getTransactionType = (type, origin) => {
|
||||
if (type === 0) {
|
||||
return '进货' // 入账
|
||||
} else if (type === 1) {
|
||||
return '出货' // 出账
|
||||
}
|
||||
return origin || '未知'
|
||||
}
|
||||
|
||||
// 获取金额显示
|
||||
const getAmountDisplay = (type, quantity) => {
|
||||
const prefix = type === 0 ? '+' : '-'
|
||||
return `${prefix}${quantity}`
|
||||
}
|
||||
|
||||
// 获取记录
|
||||
const fetchRecords = async () => {
|
||||
loading.value = true
|
||||
|
||||
try {
|
||||
// 模拟API调用
|
||||
setTimeout(() => {
|
||||
records.value = mockRecords
|
||||
loading.value = false
|
||||
}, 800)
|
||||
// 先获取用户ID
|
||||
const userId = currentUserId.value || await fetchCurrentUserId()
|
||||
|
||||
if (!userId) {
|
||||
console.error('无法获取用户ID')
|
||||
records.value = []
|
||||
return
|
||||
}
|
||||
|
||||
const response = await getFreightWaterFlow(userId)
|
||||
|
||||
if (response && response.status && response.body) {
|
||||
// 处理返回的数据
|
||||
records.value = response.body.map(item => ({
|
||||
id: item.id,
|
||||
userId: item.acceptUserId,
|
||||
userName: `User${item.acceptUserId.toString().slice(-6)}...`, // 显示最后6位
|
||||
amount: getAmountDisplay(item.type, item.quantity),
|
||||
time: formatTime(item.createTime),
|
||||
type: item.type,
|
||||
quantity: item.quantity,
|
||||
balance: item.balance,
|
||||
origin: item.origin,
|
||||
remark: item.remark,
|
||||
rechargeType: item.rechargeType
|
||||
}))
|
||||
} else {
|
||||
records.value = []
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch records:', error)
|
||||
console.error('获取记录失败:', error)
|
||||
records.value = []
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchRecords()
|
||||
onMounted(async () => {
|
||||
await fetchRecords()
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -203,7 +275,20 @@ onMounted(() => {
|
||||
.coins-amount {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #EF4444;
|
||||
}
|
||||
|
||||
.coins-amount.positive {
|
||||
color: #10B981; /* 绿色表示进货/入账 */
|
||||
}
|
||||
|
||||
.coins-amount.negative {
|
||||
color: #EF4444; /* 红色表示出货/出账 */
|
||||
}
|
||||
|
||||
.transaction-type {
|
||||
font-size: 12px;
|
||||
color: #9ca3af;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
|
||||
@ -4,19 +4,6 @@
|
||||
|
||||
<div class="content">
|
||||
<!-- 成员资料信息 -->
|
||||
<div v-if="memberProfile" class="member-profile-card">
|
||||
<div class="member-info">
|
||||
<div class="avatar-wrapper">
|
||||
<img :src="memberProfile.userAvatar" class="member-avatar" alt="Avatar" />
|
||||
<span class="country-flag">{{ memberProfile.countryCode }}</span>
|
||||
</div>
|
||||
<div class="member-details">
|
||||
<div class="member-name">{{ memberProfile.userNickname }}</div>
|
||||
<div class="member-id">ID: {{ memberProfile.account }}</div>
|
||||
<div class="member-status">{{ memberProfile.accountStatusName }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 工作报告标题 -->
|
||||
<div class="work-report-title">
|
||||
@ -32,8 +19,8 @@
|
||||
|
||||
<!-- 账单列表 -->
|
||||
<div v-else-if="billList.length > 0" class="bill-list">
|
||||
<div
|
||||
v-for="bill in billList"
|
||||
<div
|
||||
v-for="bill in billList"
|
||||
:key="bill.id"
|
||||
class="bill-item"
|
||||
@click="showBillDetail(bill)"
|
||||
@ -44,13 +31,13 @@
|
||||
{{ getStatusText(bill.status) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="bill-details">
|
||||
<div class="bill-row">
|
||||
<span class="bill-label">Host Salary:</span>
|
||||
<span class="bill-value">${{ formatSalaryValue(bill.target?.ownSalary) }}</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="bill-row">
|
||||
<span class="bill-label">Agent Salary:</span>
|
||||
<span class="bill-value">${{ formatSalaryValue(bill.target?.memberSalary) }}</span>
|
||||
@ -61,7 +48,7 @@
|
||||
<span class="bill-value total-salary-value">${{ formatSalaryValue(bill.target?.totalSalry) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="more-btn">
|
||||
<span>More</span>
|
||||
<span class="arrow">></span>
|
||||
@ -83,14 +70,14 @@
|
||||
<h3>Work Report Help</h3>
|
||||
<button class="close-btn" @click="closeHelpModal">×</button>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="help-modal-body">
|
||||
<div class="help-section">
|
||||
<p class="help-description">
|
||||
Below is the work report of the team members. Click "More" to view detailed daily work records.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="help-section">
|
||||
<h4>Status Description:</h4>
|
||||
<div class="status-list">
|
||||
@ -118,8 +105,8 @@
|
||||
<!-- 账单详情模态框 (使用 TeamBillMore 组件) -->
|
||||
<div v-if="showDetailModal" class="modal-overlay">
|
||||
<div class="detail-modal-wrapper">
|
||||
<TeamBillMore
|
||||
:billData="selectedBill"
|
||||
<TeamBillMore
|
||||
:billData="selectedBill"
|
||||
@close="closeDetailModal"
|
||||
@propsReceived="handlePropsReceived"
|
||||
/>
|
||||
@ -150,7 +137,7 @@ const fetchTeamMemberWork = async (userId) => {
|
||||
try {
|
||||
loading.value = true
|
||||
const response = await getTeamMemberWork(userId)
|
||||
|
||||
|
||||
if (response.status && response.body) {
|
||||
memberProfile.value = response.body.memberProfile
|
||||
billList.value = response.body.targets || []
|
||||
@ -173,7 +160,7 @@ const formatSalaryValue = (value) => {
|
||||
const getStatusText = (status) => {
|
||||
const statusMap = {
|
||||
'UNPAID': 'In Progress',
|
||||
'HANG_UP': 'Pending',
|
||||
'HANG_UP': 'Pending',
|
||||
'PAID': 'Completed'
|
||||
}
|
||||
return statusMap[status] || status
|
||||
@ -632,4 +619,4 @@ onMounted(() => {
|
||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user