feat: init project with miniprogram, cloud functions and admin console
这个提交包含在:
@@ -0,0 +1,165 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="toolbar flex-between">
|
||||
<text class="total-text">共 {{ total }} 条</text>
|
||||
<u-button type="primary" size="small" @click="showCreate = true">创建订阅</u-button>
|
||||
</view>
|
||||
|
||||
<view class="table-wrap">
|
||||
<u-table>
|
||||
<u-tr>
|
||||
<u-th>用户ID</u-th>
|
||||
<u-th>昵称</u-th>
|
||||
<u-th>类型</u-th>
|
||||
<u-th>方案</u-th>
|
||||
<u-th>状态</u-th>
|
||||
<u-th>到期时间</u-th>
|
||||
</u-tr>
|
||||
<u-tr v-for="item in subscriptions" :key="item.id">
|
||||
<u-td>{{ item.user_id }}</u-td>
|
||||
<u-td>{{ item.nickname || '-' }}</u-td>
|
||||
<u-td>{{ subTypeMap[item.type] || '-' }}</u-td>
|
||||
<u-td>{{ item.plan || '-' }}</u-td>
|
||||
<u-td>
|
||||
<text :class="item.status === 1 ? 'text-success' : 'text-muted'">
|
||||
{{ subStatusMap[item.status] || '-' }}
|
||||
</text>
|
||||
</u-td>
|
||||
<u-td>{{ formatDate(item.expired_at) }}</u-td>
|
||||
</u-tr>
|
||||
</u-table>
|
||||
</view>
|
||||
|
||||
<view class="pagination">
|
||||
<u-button size="small" :disabled="page <= 1" @click="onPage(page - 1)">上一页</u-button>
|
||||
<text class="page-info">第 {{ page }} 页 / 共 {{ totalPages }} 页</text>
|
||||
<u-button size="small" :disabled="page >= totalPages" @click="onPage(page + 1)">下一页</u-button>
|
||||
</view>
|
||||
|
||||
<u-popup :show="showCreate" @close="showCreate = false" mode="center">
|
||||
<view class="create-form">
|
||||
<view class="form-title">创建订阅</view>
|
||||
<u-form :model="createForm">
|
||||
<u-form-item label="用户ID">
|
||||
<u-input v-model="createForm.user_id" placeholder="输入用户ID" />
|
||||
</u-form-item>
|
||||
<u-form-item label="方案">
|
||||
<u-input v-model="createForm.plan" placeholder="monthly/quarterly/yearly" />
|
||||
</u-form-item>
|
||||
<u-form-item label="天数">
|
||||
<u-input v-model="createForm.days" placeholder="订阅天数" type="number" />
|
||||
</u-form-item>
|
||||
</u-form>
|
||||
<u-button type="primary" @click="onCreate" :loading="creating">创建</u-button>
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { get, post } from '../../utils/request'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
subscriptions: [],
|
||||
total: 0,
|
||||
page: 1,
|
||||
pageSize: 20,
|
||||
showCreate: false,
|
||||
creating: false,
|
||||
createForm: { user_id: '', plan: 'monthly', days: 30 },
|
||||
subTypeMap: { 1: '试用', 2: '正式', 3: '赠送' },
|
||||
subStatusMap: { 1: '有效', 2: '已过期', 3: '已停用' }
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
totalPages() {
|
||||
return Math.ceil(this.total / this.pageSize) || 1
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.loadSubscriptions()
|
||||
},
|
||||
methods: {
|
||||
async loadSubscriptions() {
|
||||
try {
|
||||
const data = await get('/api/v1/admin/subscriptions', { page: this.page, page_size: this.pageSize })
|
||||
this.subscriptions = data.records || []
|
||||
this.total = data.total || 0
|
||||
} catch (e) {}
|
||||
},
|
||||
onPage(p) {
|
||||
this.page = p
|
||||
this.loadSubscriptions()
|
||||
},
|
||||
async onCreate() {
|
||||
this.creating = true
|
||||
try {
|
||||
await post('/api/v1/admin/subscriptions', {
|
||||
user_id: parseInt(this.createForm.user_id),
|
||||
plan: this.createForm.plan,
|
||||
days: parseInt(this.createForm.days)
|
||||
})
|
||||
this.showCreate = false
|
||||
this.loadSubscriptions()
|
||||
uni.showToast({ title: '创建成功', icon: 'success' })
|
||||
} catch (e) {
|
||||
uni.showToast({ title: '创建失败', icon: 'none' })
|
||||
} finally {
|
||||
this.creating = false
|
||||
}
|
||||
},
|
||||
formatDate(d) {
|
||||
return d ? d.slice(0, 10) : '-'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.total-text {
|
||||
font-size: 13px;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 16px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.page-info {
|
||||
font-size: 13px;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.create-form {
|
||||
padding: 24px;
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.form-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.text-success {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #999999;
|
||||
}
|
||||
</style>
|
||||
在新工单中引用
屏蔽一个用户