176 lines
4.4 KiB
Vue
176 lines
4.4 KiB
Vue
<script lang="ts" setup>
|
||
import type { AgentApi } from '#/api/agent';
|
||
|
||
import { ref } from 'vue';
|
||
|
||
import { Page, useVbenModal } from '@vben/common-ui';
|
||
|
||
import { Button, Input, InputNumber, Modal, Space, message } from 'ant-design-vue';
|
||
|
||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||
import {
|
||
generateDiamondInviteCode,
|
||
getInviteCodeList,
|
||
} from '#/api/agent';
|
||
|
||
import { useInviteCodeColumns, useInviteCodeFormSchema } from './data';
|
||
|
||
interface QueryParams {
|
||
currentPage: number;
|
||
pageSize: number;
|
||
[key: string]: any;
|
||
}
|
||
|
||
const generateModalVisible = ref(false);
|
||
const generatedCodes = ref<string[]>([]);
|
||
const generateForm = ref({
|
||
count: 1,
|
||
expire_days: 0,
|
||
remark: '',
|
||
});
|
||
|
||
const [Grid, gridApi] = useVbenVxeGrid({
|
||
formOptions: {
|
||
schema: useInviteCodeFormSchema(),
|
||
submitOnChange: true,
|
||
},
|
||
gridOptions: {
|
||
columns: useInviteCodeColumns(),
|
||
proxyConfig: {
|
||
ajax: {
|
||
query: async ({
|
||
page,
|
||
form,
|
||
}: {
|
||
form: Record<string, any>;
|
||
page: QueryParams;
|
||
}) => {
|
||
return await getInviteCodeList({
|
||
...form,
|
||
target_level: 3,
|
||
page: page.currentPage,
|
||
pageSize: page.pageSize,
|
||
});
|
||
},
|
||
},
|
||
props: {
|
||
result: 'items',
|
||
total: 'total',
|
||
},
|
||
},
|
||
},
|
||
});
|
||
|
||
// 生成邀请码
|
||
function handleGenerate() {
|
||
generateForm.value = {
|
||
count: 1,
|
||
expire_days: 0,
|
||
remark: '',
|
||
};
|
||
generatedCodes.value = [];
|
||
generateModalVisible.value = true;
|
||
}
|
||
|
||
// 确认生成
|
||
async function confirmGenerate() {
|
||
try {
|
||
const res = await generateDiamondInviteCode({
|
||
count: generateForm.value.count,
|
||
expire_days:
|
||
generateForm.value.expire_days > 0
|
||
? generateForm.value.expire_days
|
||
: undefined,
|
||
remark: generateForm.value.remark || undefined,
|
||
});
|
||
generatedCodes.value = res.codes;
|
||
message.success('邀请码生成成功');
|
||
gridApi.query();
|
||
} catch (error) {
|
||
console.error('生成邀请码失败:', error);
|
||
}
|
||
}
|
||
|
||
// 复制邀请码
|
||
function copyCodes() {
|
||
const text = generatedCodes.value.join('\n');
|
||
navigator.clipboard.writeText(text).then(() => {
|
||
message.success('邀请码已复制到剪贴板');
|
||
});
|
||
}
|
||
|
||
// 关闭弹窗
|
||
function closeGenerateModal() {
|
||
generateModalVisible.value = false;
|
||
generatedCodes.value = [];
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<Page auto-content-height>
|
||
<Grid table-title="邀请码列表">
|
||
<template #toolbar>
|
||
<Button type="primary" @click="handleGenerate">生成钻石邀请码</Button>
|
||
</template>
|
||
</Grid>
|
||
|
||
<Modal v-model:open="generateModalVisible" :title="generatedCodes.length > 0 ? '生成的邀请码' : '生成钻石邀请码'" :width="600"
|
||
@cancel="closeGenerateModal">
|
||
<div v-if="generatedCodes.length === 0">
|
||
<div class="mb-4">
|
||
<label>生成数量:</label>
|
||
<InputNumber v-model:value="generateForm.count" :min="1" :max="100" class="w-full" />
|
||
</div>
|
||
<div class="mb-4">
|
||
<label>过期天数(0表示不过期):</label>
|
||
<InputNumber v-model:value="generateForm.expire_days" :min="0" class="w-full" />
|
||
</div>
|
||
<div class="mb-4">
|
||
<label>备注:</label>
|
||
<Input.TextArea v-model:value="generateForm.remark" :rows="3" placeholder="请输入备注" />
|
||
</div>
|
||
</div>
|
||
<div v-else>
|
||
<div class="mb-4">
|
||
<strong>已生成 {{ generatedCodes.length }} 个邀请码:</strong>
|
||
</div>
|
||
<div class="code-list">
|
||
<div v-for="(code, index) in generatedCodes" :key="index" class="code-item">
|
||
{{ code }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<template #footer>
|
||
<Button v-if="generatedCodes.length > 0" @click="closeGenerateModal">
|
||
关闭
|
||
</Button>
|
||
<Button v-else @click="closeGenerateModal">取消</Button>
|
||
<Button v-if="generatedCodes.length > 0" type="primary" @click="copyCodes">
|
||
复制所有
|
||
</Button>
|
||
<Button v-else type="primary" @click="confirmGenerate">生成</Button>
|
||
</template>
|
||
</Modal>
|
||
</Page>
|
||
</template>
|
||
|
||
<style lang="less" scoped>
|
||
.code-list {
|
||
max-height: 300px;
|
||
overflow-y: auto;
|
||
border: 1px solid #d9d9d9;
|
||
border-radius: 4px;
|
||
padding: 8px;
|
||
}
|
||
|
||
.code-item {
|
||
padding: 4px 8px;
|
||
font-family: monospace;
|
||
border-bottom: 1px solid #f0f0f0;
|
||
|
||
&:last-child {
|
||
border-bottom: none;
|
||
}
|
||
}
|
||
</style>
|