- 调整表格列显示微信号替代邮箱字段 - 添加备注和剩余体验次数列 - 移除状态切换功能改为次数设置按钮 - 移动LimitSettingModal组件到页面目录 - 隐藏新建用户按钮简化界面 - 优化查询条件支持微信号搜索
209 lines
4.1 KiB
Vue
209 lines
4.1 KiB
Vue
<script setup>
|
||
import { ref, watch } from 'vue'
|
||
import {
|
||
NModal,
|
||
NButton,
|
||
NSelect,
|
||
NInput,
|
||
NDivider,
|
||
} from 'naive-ui'
|
||
|
||
// Props
|
||
const props = defineProps({
|
||
visible: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
userData: {
|
||
type: Object,
|
||
default: () => ({})
|
||
}
|
||
})
|
||
|
||
// Emits
|
||
const emit = defineEmits(['update:visible', 'save'])
|
||
|
||
// 本地状态
|
||
const limitForm = ref({
|
||
remainingCount: 0,
|
||
type: '免费体验',
|
||
experienceCount: 1,
|
||
notes: ''
|
||
})
|
||
|
||
// 类型选项
|
||
const typeOptions = [
|
||
{ label: '免费体验', value: '免费体验' },
|
||
{ label: '付费用户', value: '付费用户' },
|
||
{ label: 'VIP用户', value: 'VIP用户' }
|
||
]
|
||
|
||
// 监听用户数据变化,初始化表单
|
||
watch(() => props.userData, (newData) => {
|
||
if (newData && Object.keys(newData).length > 0) {
|
||
limitForm.value = {
|
||
remainingCount: newData.remaining_count || 0,
|
||
type: newData.user_type || '免费体验',
|
||
experienceCount: newData.experience_count || 1,
|
||
notes: newData.notes || ''
|
||
}
|
||
}
|
||
}, { immediate: true })
|
||
|
||
// 体验次数增减
|
||
function handleExperienceCountChange(delta) {
|
||
const newCount = limitForm.value.experienceCount + delta
|
||
if (newCount >= 0) {
|
||
limitForm.value.experienceCount = newCount
|
||
}
|
||
}
|
||
|
||
// 保存设置
|
||
function handleSave() {
|
||
const data = {
|
||
user_id: props.userData.id,
|
||
...limitForm.value
|
||
}
|
||
emit('save', data)
|
||
}
|
||
|
||
// 取消操作
|
||
function handleCancel() {
|
||
emit('update:visible', false)
|
||
// 重置表单
|
||
limitForm.value = {
|
||
remainingCount: 0,
|
||
type: '免费体验',
|
||
experienceCount: 1,
|
||
notes: ''
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<NModal
|
||
:show="visible"
|
||
preset="card"
|
||
title="估值设置"
|
||
style="width: 500px;"
|
||
:bordered="false"
|
||
size="huge"
|
||
role="dialog"
|
||
aria-modal="true"
|
||
@update:show="$emit('update:visible', $event)"
|
||
>
|
||
<div class="limit-setting-form">
|
||
<!-- 剩余估值次数 -->
|
||
<div class="form-row">
|
||
<span class="label">剩余估值次数:</span>
|
||
<span class="value">{{ limitForm.remainingCount }}</span>
|
||
</div>
|
||
|
||
<NDivider style="margin: 16px 0;" />
|
||
|
||
<!-- 类型选择 -->
|
||
<div class="form-row">
|
||
<span class="label">类型:</span>
|
||
<NSelect
|
||
v-model:value="limitForm.type"
|
||
:options="typeOptions"
|
||
style="width: 120px;"
|
||
/>
|
||
</div>
|
||
|
||
<!-- 体验次数 -->
|
||
<div class="form-row">
|
||
<span class="label">体验次数:</span>
|
||
<div class="count-control">
|
||
<NButton
|
||
size="small"
|
||
@click="handleExperienceCountChange(-1)"
|
||
:disabled="limitForm.experienceCount <= 0"
|
||
>
|
||
-
|
||
</NButton>
|
||
<span class="count-value">{{ limitForm.experienceCount }}</span>
|
||
<NButton
|
||
size="small"
|
||
@click="handleExperienceCountChange(1)"
|
||
>
|
||
+
|
||
</NButton>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 备注 -->
|
||
<div class="form-row notes-row">
|
||
<span class="label">备注:</span>
|
||
</div>
|
||
<NInput
|
||
v-model:value="limitForm.notes"
|
||
type="textarea"
|
||
placeholder="请输入备注信息"
|
||
:rows="4"
|
||
style="margin-top: 8px;"
|
||
/>
|
||
|
||
<!-- 操作按钮 -->
|
||
<div class="action-buttons">
|
||
<NButton @click="handleCancel">
|
||
取消
|
||
</NButton>
|
||
<NButton type="primary" @click="handleSave">
|
||
确定
|
||
</NButton>
|
||
</div>
|
||
</div>
|
||
</NModal>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.limit-setting-form {
|
||
padding: 16px 0;
|
||
}
|
||
|
||
.form-row {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.notes-row {
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.label {
|
||
font-size: 14px;
|
||
color: #333;
|
||
min-width: 100px;
|
||
margin-right: 12px;
|
||
}
|
||
|
||
.value {
|
||
font-size: 14px;
|
||
color: #666;
|
||
}
|
||
|
||
.count-control {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
}
|
||
|
||
.count-value {
|
||
font-size: 16px;
|
||
font-weight: 500;
|
||
min-width: 20px;
|
||
text-align: center;
|
||
}
|
||
|
||
.action-buttons {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
gap: 12px;
|
||
margin-top: 24px;
|
||
padding-top: 16px;
|
||
border-top: 1px solid #f0f0f0;
|
||
}
|
||
</style>
|