会员模块+卡密模块

This commit is contained in:
yuhawu 2025-07-01 16:38:44 +08:00
parent d359b106d5
commit cf13ef2881
8 changed files with 123 additions and 22 deletions

View File

@ -1 +0,0 @@
.el-divider{position:relative}.el-divider--horizontal{border-top:1px var(--el-border-color) var(--el-border-style);display:block;height:1px;margin:24px 0;width:100%}.el-divider--vertical{border-left:1px var(--el-border-color) var(--el-border-style);display:inline-block;height:1em;margin:0 8px;position:relative;vertical-align:middle;width:1px}.el-divider__text{background-color:var(--el-bg-color);color:var(--el-text-color-primary);font-size:14px;font-weight:500;padding:0 20px;position:absolute}.el-divider__text.is-left{left:20px;transform:translateY(-50%)}.el-divider__text.is-center{left:50%;transform:translate(-50%) translateY(-50%)}.el-divider__text.is-right{right:20px;transform:translateY(-50%)}.login-container[data-v-7830093b]{display:flex;justify-content:center;align-items:center;height:100vh;background:#f0f2f5}.header[data-v-7830093b]{text-align:center;margin-bottom:30px}.title[data-v-7830093b]{margin-bottom:8px;color:#333;font-size:24px;font-weight:600}.subtitle[data-v-7830093b]{margin:0;color:#666;font-size:14px}[data-v-7830093b] .el-form{width:400px;padding:40px;background:#fff;border-radius:4px;box-shadow:0 2px 12px #0000001a}.form-item[data-v-7830093b]{margin-bottom:24px}.input-item[data-v-7830093b]{height:40px}[data-v-7830093b] .el-input__wrapper{height:100%;padding:0 12px}[data-v-7830093b] .el-input__inner{height:100%}.captcha-wrapper[data-v-7830093b]{display:flex;gap:10px;height:40px}.captcha-input[data-v-7830093b]{flex:1}.captcha-image[data-v-7830093b]{width:120px;height:40px;cursor:pointer;border:1px solid #ddd;border-radius:4px}.custom-divider[data-v-7830093b]{margin:24px 0}.login-btn[data-v-7830093b]{width:100%;height:40px;margin-top:0}[data-v-7830093b] .el-divider__text{color:#909399;font-size:12px}[data-v-7830093b] .el-divider--horizontal{margin:18px 0;border-top:1px solid #e8e8e8}

File diff suppressed because one or more lines are too long

6
dist/index.html vendored
View File

@ -5,10 +5,10 @@
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title> <title>Vite App</title>
<script type="module" crossorigin src="/assets/index.1da7786a.js"></script> <script type="module" crossorigin src="/assets/index.09599c30.js"></script>
<link rel="modulepreload" href="/assets/vendor.74de3ee4.js"> <link rel="modulepreload" href="/assets/vendor.51cc00ea.js">
<link rel="stylesheet" href="/assets/vendor.f9422048.css"> <link rel="stylesheet" href="/assets/vendor.f9422048.css">
<link rel="stylesheet" href="/assets/index.e4158b2f.css"> <link rel="stylesheet" href="/assets/index.b7a6658c.css">
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>

View File

@ -25,8 +25,14 @@ const cardsApi = {
}) })
}, },
// 删除卡密 // 删除卡密(逻辑删除)
deleteCard: (id) => instance.post('/cards/delete', null, { params: { id } }), deleteCard: (id) => instance.post(`/cards/deleteCard`, { id }),
// 停用卡密
disableCard: (id) => instance.post(`/cards/disableCard`, { id }),
// 启用卡密
enableCard: (id) => instance.post(`/cards/enableCard`, { id }),
// 获取卡密 // 获取卡密
createCardSecret: (data) => instance.post('/cards/createCardSecret', data), createCardSecret: (data) => instance.post('/cards/createCardSecret', data),

View File

@ -4,6 +4,9 @@ const settledMemberRecordApi = {
// 获取入驻会员开通记录列表 // 获取入驻会员开通记录列表
getSettledMemberRecordList: (params) => instance.get('/settledMember/record/list', { params }), getSettledMemberRecordList: (params) => instance.get('/settledMember/record/list', { params }),
getSettledMemberRecordlistWithDetails: (params) => instance.get('/settledMember/record/listWithDetails', { params }),
// 删除入驻会员开通记录 // 删除入驻会员开通记录
deleteSettledMemberRecord: (id) => instance.post('/settledMember/record/delete', null, { params: { id } }), deleteSettledMemberRecord: (id) => instance.post('/settledMember/record/delete', null, { params: { id } }),

View File

@ -49,13 +49,13 @@
}) })
// URL // URL
const captchaUrl = ref('http://146.56.227.42:8089/admin/generateCaptcha?t=' + Date.now()) const captchaUrl = ref('https://newadmin.buzhiyushu.cn/admin/generateCaptcha?t=' + Date.now())
// //
const loading = ref(false) const loading = ref(false)
// //
const router = useRouter() const router = useRouter()
// //
const refreshCaptcha = () => { captchaUrl.value = `http://146.56.227.42:8089/admin/generateCaptcha?t=${Date.now()}` } const refreshCaptcha = () => { captchaUrl.value = `https://newadmin.buzhiyushu.cn/admin/generateCaptcha?t=${Date.now()}` }
// //
const handleLogin = async () => { const handleLogin = async () => {

View File

@ -57,7 +57,8 @@
<span class="expand-label">会员限制:</span> <span class="expand-label">会员限制:</span>
<span v-if="row.constraintJson"> <span v-if="row.constraintJson">
最小本数: {{ getConstraintValue(row.constraintJson, 'books_count_min', 0) }} 最小本数: {{ getConstraintValue(row.constraintJson, 'books_count_min', 0) }}
最大本数: {{ getConstraintValue(row.constraintJson, 'books_count_max', 3000) }} 最大本数: {{ getConstraintValue(row.constraintJson, 'books_count_max', 3000) }}
当前本数: {{ row.booksCount || 0 }}
</span> </span>
<span v-else>-</span> <span v-else>-</span>
</div> </div>
@ -521,7 +522,7 @@ const fetchData = async () => {
} }
console.log('最终发送的分页请求参数:', JSON.stringify(params)); // 使JSON.stringify console.log('最终发送的分页请求参数:', JSON.stringify(params)); // 使JSON.stringify
const res = await settledMemberRecordApi.getSettledMemberRecordList(params) const res = await settledMemberRecordApi.getSettledMemberRecordlistWithDetails(params)
console.log('获取分页数据响应:', res); console.log('获取分页数据响应:', res);
if (res.code === 200 && res.data) { if (res.code === 200 && res.data) {

View File

@ -111,16 +111,29 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="memo" label="备注" min-width="120" /> <el-table-column prop="memo" label="备注" min-width="120" />
<!-- <el-table-column label="操作" fixed="right" width="120"> <el-table-column label="操作" fixed="right" width="180">
<template #default="{ row }"> <template #default="{ row }">
<el-button <el-button
size="small" size="small"
type="danger" type="danger"
@click="handleDelete(row)" @click="handleDelete(row.id)"
:disabled="row.status !== 0" :disabled="row.status === 3 || row.status === 4"
>删除</el-button> >删除</el-button>
<el-button
v-if="row.status !== 3"
size="small"
type="warning"
@click="handleDisable(row.id)"
:disabled="row.status === 4 || row.status === 0"
>停用</el-button>
<el-button
v-else
size="small"
type="success"
@click="handleEnable(row.id)"
>启用</el-button>
</template> </template>
</el-table-column> --> </el-table-column>
</el-table> </el-table>
<!-- 分页 --> <!-- 分页 -->
@ -355,8 +368,10 @@ const submitCardSecretRequest = async () => {
}; };
const res = await cardsApi.createCardSecret(cardData) const res = await cardsApi.createCardSecret(cardData)
// createCardSecret使res // createCardSecret使res
console.log("res",res)
if (res.code === 200) { if (res.code === 200) {
cardSecretValue.value = res.message cardSecretValue.value = res.data
// //
cardParamsDialogVisible.value = false cardParamsDialogVisible.value = false
cardSecretDialogVisible.value = true cardSecretDialogVisible.value = true
@ -370,14 +385,30 @@ const submitCardSecretRequest = async () => {
} }
// //
const handleCopyCardSecret = async () => { const handleCopyCardSecret = () => {
try { try {
await navigator.clipboard.writeText(cardSecretValue.value) //
const textarea = document.createElement('textarea')
textarea.value = cardSecretValue.value
textarea.style.position = 'fixed' //
textarea.style.opacity = '0'
document.body.appendChild(textarea)
textarea.select()
console.log("textarea",textarea)
//
const successful = document.execCommand('copy')
document.body.removeChild(textarea)
if (successful) {
ElMessage.success('复制成功') ElMessage.success('复制成功')
} else {
ElMessage.warning('复制失败,请手动复制')
}
cardSecretDialogVisible.value = false cardSecretDialogVisible.value = false
} catch (error) { } catch (error) {
console.error('复制失败:', error) console.error('复制失败:', error)
ElMessage.error('复制失败') ElMessage.error('复制失败,请手动复制')
} }
} }
@ -418,14 +449,14 @@ const handleCurrentChange = (current) => {
} }
// //
const handleDelete = (row) => { const handleDelete = (id) => {
ElMessageBox.confirm('确定要删除该卡密吗?', '提示', { ElMessageBox.confirm('确定要删除该卡密吗?', '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(async () => { }).then(async () => {
try { try {
const res = await cardsApi.deleteCard(row.id) const res = await cardsApi.deleteCard(id)
if (res.code === 200) { if (res.code === 200) {
ElMessage.success('删除成功') ElMessage.success('删除成功')
fetchData() fetchData()
@ -448,6 +479,68 @@ const handleDelete = (row) => {
}) })
} }
//
const handleDisable = (id) => {
ElMessageBox.confirm('确定要停用该卡密吗?停用后将无法使用', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
try {
const res = await cardsApi.disableCard(id)
if (res.code === 200) {
ElMessage.success('停用成功')
fetchData()
} else {
ElMessage.error(res.message || '停用失败')
}
} catch (error) {
console.error('停用失败:', error)
//
if (error.code === 'ECONNABORTED') {
ElMessage.error('请求超时,请稍后再试')
} else if (error.response) {
ElMessage.error(`停用失败: ${error.response.status} ${error.response.statusText}`)
} else {
ElMessage.error(`停用失败: ${error.message || '未知错误'}`)
}
}
}).catch(() => {
//
})
}
//
const handleEnable = (id) => {
ElMessageBox.confirm('确定要启用该卡密吗?启用后将可以使用', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
try {
const res = await cardsApi.enableCard(id)
if (res.code === 200) {
ElMessage.success('启用成功')
fetchData()
} else {
ElMessage.error(res.message || '启用失败')
}
} catch (error) {
console.error('启用失败:', error)
//
if (error.code === 'ECONNABORTED') {
ElMessage.error('请求超时,请稍后再试')
} else if (error.response) {
ElMessage.error(`启用失败: ${error.response.status} ${error.response.statusText}`)
} else {
ElMessage.error(`启用失败: ${error.message || '未知错误'}`)
}
}
}).catch(() => {
//
})
}
// //
const getStatusType = (status) => { const getStatusType = (status) => {
const map = { const map = {