Files
CKB-mini-program/pages/channel/project-select.vue
2026-01-07 11:00:09 +08:00

178 lines
3.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="page-container">
<view class="header">
<view class="title">选择项目</view>
<view class="subtitle">请选择要查看的渠道项目</view>
</view>
<view v-if="loading" class="loading">
<uni-icons type="spinner-cycle" size="32" color="#6366f1"></uni-icons>
<text class="loading-text">加载中...</text>
</view>
<view v-else-if="projects.length === 0" class="empty">
<uni-icons type="info" size="40" color="#ccc"></uni-icons>
<text class="empty-text">暂无可选项目</text>
</view>
<view v-else class="list">
<view
v-for="(item, index) in projects"
:key="index"
class="project-card"
@click="selectProject(item)"
>
<view class="project-main">
<view class="project-name">{{ item.name || '未命名项目' }}</view>
<view class="project-code">编码{{ item.code || '--' }}</view>
</view>
<uni-icons type="arrowright" size="20" color="#999"></uni-icons>
</view>
</view>
</view>
</template>
<script>
import config from '@/config'
export default {
data() {
return {
loading: false,
projects: []
}
},
onShow() {
this.fetchProjects()
},
methods: {
fetchProjects() {
const token = uni.getStorageSync('channelToken')
if (!token) {
uni.showToast({ title: '请先登录', icon: 'none', duration: 2000 })
uni.redirectTo({ url: '/pages/channel/login' })
return
}
this.loading = true
uni.request({
method: 'GET',
url: config.apiUrl2 + '/v1/frontend/distribution/channel/projects',
header: {
'content-type': 'application/x-www-form-urlencoded',
token
},
success: (res) => {
this.loading = false
if (res.data.code === 10000 || res.data.code === 200) {
this.projects = res.data.data?.list || res.data.data || []
} else {
const msg = res.data.message || res.data.msg || '加载失败'
uni.showToast({ title: msg, icon: 'none', duration: 3000 })
}
},
fail: (err) => {
console.error('加载项目失败', err)
this.loading = false
uni.showToast({ title: '网络错误,请重试', icon: 'none', duration: 2000 })
}
})
},
selectProject(item) {
const name = encodeURIComponent(item.name || '')
const code = encodeURIComponent(item.code || '')
uni.navigateTo({
url: `/pages/channel/statistics?name=${name}&code=${code}`
})
}
}
}
</script>
<style lang="scss" scoped>
.page-container {
min-height: 100vh;
background: #f5f6fb;
padding: 32rpx 28rpx 60rpx;
box-sizing: border-box;
}
.header {
margin-bottom: 24rpx;
}
.title {
font-size: 38rpx;
font-weight: 700;
color: #111827;
}
.subtitle {
margin-top: 8rpx;
font-size: 26rpx;
color: #6b7280;
}
.loading,
.empty {
margin-top: 120rpx;
display: flex;
flex-direction: column;
align-items: center;
gap: 20rpx;
color: #999;
}
.loading-text,
.empty-text {
font-size: 28rpx;
color: #666;
}
.list {
display: flex;
flex-direction: column;
gap: 16rpx;
margin-top: 8rpx;
}
.project-card {
background: #fff;
border-radius: 14rpx;
padding: 24rpx;
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: 0 4rpx 14rpx rgba(0, 0, 0, 0.06);
}
.project-main {
display: flex;
flex-direction: column;
gap: 8rpx;
}
.project-name {
font-size: 32rpx;
font-weight: 600;
color: #111827;
}
.project-code {
font-size: 26rpx;
color: #6b7280;
}
/* #ifdef H5 */
.project-card {
cursor: pointer;
transition: all 0.2s ease;
&:hover {
transform: translateY(-2rpx);
box-shadow: 0 8rpx 18rpx rgba(0, 0, 0, 0.08);
}
}
/* #endif */
</style>