新增会员界面

This commit is contained in:
lxd 2025-06-05 13:27:43 +08:00
parent 6032036f40
commit dbf0710653
7 changed files with 1196 additions and 0 deletions

View File

@ -0,0 +1,92 @@
<template>
<Dialog v-model="dialogVisible" title="新增会员" width="500px" @close="handleClose">
<el-form :model="form" label-width="100px" :rules="rules" ref="formRef">
<el-form-item label="姓名" prop="name">
<el-input v-model="form.name" placeholder="请输入姓名" />
</el-form-item>
<el-form-item label="手机号" prop="phone">
<el-input v-model="form.phone" placeholder="请输入手机号" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="handleClose"> </el-button>
<el-button type="primary" @click="handleSubmit"> </el-button>
</template>
</Dialog>
</template>
<script setup>
import { ref, defineEmits, defineProps, watch } from 'vue'
import { ElMessage } from 'element-plus'
const props = defineProps({
visible: {
type: Boolean,
default: false
}
})
const emit = defineEmits(['update:visible', 'success'])
const dialogVisible = ref(props.visible)
const formRef = ref(null)
const form = ref({
name: '',
phone: ''
})
const rules = {
name: [
{ required: true, message: '请输入姓名', trigger: 'blur' }
],
phone: [
{ required: true, message: '请输入手机号', trigger: 'blur' },
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
]
}
// visible
watch(() => props.visible, (val) => {
dialogVisible.value = val
})
// dialogVisible
watch(dialogVisible, (val) => {
emit('update:visible', val)
})
const handleClose = () => {
dialogVisible.value = false
form.value = {
name: '',
phone: ''
}
formRef.value?.resetFields()
}
const handleSubmit = async () => {
if (!formRef.value) return
await formRef.value.validate((valid) => {
if (valid) {
//
const newMember = {
id: Date.now(),
name: form.value.name,
phone: form.value.phone,
vipStatus: false,
vipExpireDate: ''
}
emit('success', newMember)
handleClose()
}
})
}
</script>
<style scoped>
:deep(.el-form-item) {
margin-bottom: 22px;
}
</style>

View File

@ -0,0 +1,111 @@
<template>
<el-dialog
v-model="dialogVisible"
title="密码验证"
width="400px"
:close-on-click-modal="false"
@close="handleClose"
>
<el-form
ref="formRef"
:model="formData"
:rules="rules"
label-width="80px"
>
<el-form-item label="密码" prop="password">
<el-input
v-model="formData.password"
type="password"
placeholder="请输入当前登录密码"
show-password
/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" @click="handleSubmit" :loading="loading">
确认
</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { ElMessage } from 'element-plus'
const props = defineProps({
visible: {
type: Boolean,
default: false
}
})
const emit = defineEmits(['update:visible', 'success', 'cancel'])
const dialogVisible = ref(false)
const loading = ref(false)
const formRef = ref()
const formData = reactive({
password: ''
})
const rules = {
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, message: '密码长度不能小于6位', trigger: 'blur' }
]
}
// visible
watch(
() => props.visible,
(val) => {
dialogVisible.value = val
}
)
// dialogVisible
watch(
() => dialogVisible.value,
(val) => {
emit('update:visible', val)
}
)
const handleClose = () => {
formData.password = ''
formRef.value?.resetFields()
dialogVisible.value = false
emit('cancel')
}
const handleSubmit = async () => {
if (!formRef.value) return
try {
await formRef.value.validate()
loading.value = true
// TODO: API
// API
setTimeout(() => {
//
emit('success', formData.password)
handleClose()
loading.value = false
}, 1000)
} catch (error) {
console.error('表单验证失败:', error)
}
}
</script>
<style scoped>
.dialog-footer {
text-align: right;
}
</style>

View File

@ -0,0 +1,137 @@
<template>
<Dialog v-model="dialogVisible" title="会员续费" width="600px" @close="handleClose">
<div class="package-grid">
<div
v-for="pkg in packages"
:key="pkg.id"
class="package-card"
:class="{ active: selectedPackage === pkg }"
@click="selectedPackage = pkg"
>
<div class="package-name">{{ pkg.name }}</div>
<div class="package-price">
<span class="currency">¥</span>
<span class="amount">{{ pkg.price }}</span>
</div>
<div class="package-duration">{{ pkg.duration }}个月</div>
</div>
</div>
<template #footer>
<el-button @click="handleClose"> </el-button>
<el-button type="primary" @click="handleSubmit"> </el-button>
</template>
</Dialog>
</template>
<script setup>
import { ref, defineEmits, defineProps, watch } from 'vue'
import { ElMessage } from 'element-plus'
const props = defineProps({
visible: {
type: Boolean,
default: false
},
member: {
type: Object,
default: () => ({})
}
})
const emit = defineEmits(['update:visible', 'success'])
const dialogVisible = ref(props.visible)
const selectedPackage = ref(null)
const packages = [
{ id: 1, name: '月度会员', price: 30, duration: 1 },
{ id: 2, name: '季度会员', price: 80, duration: 3 },
{ id: 3, name: '年度会员', price: 298, duration: 12 }
]
// visible
watch(() => props.visible, (val) => {
dialogVisible.value = val
})
// dialogVisible
watch(dialogVisible, (val) => {
emit('update:visible', val)
})
const handleClose = () => {
dialogVisible.value = false
selectedPackage.value = null
}
const handleSubmit = () => {
if (!selectedPackage.value) {
ElMessage.warning('请选择会员套餐')
return
}
//
const currentDate = props.member.vipExpireDate ? new Date(props.member.vipExpireDate) : new Date()
const newExpireDate = new Date(currentDate.setMonth(currentDate.getMonth() + selectedPackage.value.duration))
emit('success', {
memberId: props.member.id,
packageId: selectedPackage.value.id,
expireDate: newExpireDate.toISOString().split('T')[0]
})
handleClose()
}
</script>
<style scoped>
.package-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
padding: 20px 0;
}
.package-card {
border: 1px solid #e4e7ed;
border-radius: 8px;
padding: 20px;
text-align: center;
cursor: pointer;
transition: all 0.3s;
}
.package-card:hover {
border-color: #409eff;
transform: translateY(-2px);
}
.package-card.active {
border-color: #409eff;
background-color: #ecf5ff;
}
.package-name {
font-size: 16px;
font-weight: bold;
margin-bottom: 10px;
}
.package-price {
color: #f56c6c;
margin-bottom: 10px;
}
.package-price .currency {
font-size: 16px;
}
.package-price .amount {
font-size: 24px;
font-weight: bold;
}
.package-duration {
color: #909399;
font-size: 14px;
}
</style>

300
src/views/vip/index.vue Normal file
View File

@ -0,0 +1,300 @@
<template>
<div class="app-container">
<!-- 搜索工作栏 -->
<ContentWrap>
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="68px"
>
<el-form-item label="会员姓名" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入会员姓名"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="会员状态" prop="vipStatus">
<el-select
v-model="queryParams.vipStatus"
placeholder="请选择会员状态"
clearable
class="!w-240px"
>
<el-option label="已开通" :value="true" />
<el-option label="未开通" :value="false" />
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table
v-loading="loading"
:data="memberList"
:show-overflow-tooltip="true"
>
<el-table-column label="姓名" align="center" prop="name" />
<el-table-column label="手机号" align="center" prop="phone" />
<el-table-column label="VIP状态" align="center" prop="vipStatus" >
<template #default="scope">
<el-tag :type="scope.row.vipStatus ? 'success' : 'info'">
{{ scope.row.vipStatus ? '已开通' : '未开通' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="地址" align="center" prop="address" />
<el-table-column label="到期时间" align="center" prop="vipExpireDate" >
<template #default="scope">
<span v-if="scope.row.vipStatus" class="text-primary">{{ scope.row.vipExpireDate }}</span>
<span v-else class="text-gray-400">-</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="180">
<template #default="scope">
<div class="flex items-center justify-center">
<el-button
v-if="!scope.row.vipStatus"
type="primary"
link
size="small"
@click="handleRecharge(scope.row)"
>
<Icon icon="ep:video-play" />开通会员
</el-button>
<el-button
v-else
type="primary"
link
size="small"
@click="handleRecharge(scope.row)"
>
<Icon icon="ep:refresh" />续费
</el-button>
<el-button
v-if="scope.row.vipStatus"
type="danger"
link
size="small"
@click="handleCancel(scope.row)"
>
<Icon icon="ep:close" />取消会员
</el-button>
</div>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
<!-- 续费弹窗 -->
<RechargeDialog
v-model:visible="rechargeDialogVisible"
:member="currentMember"
@success="handleRechargeSuccess"
/>
<!-- 密码验证弹窗 -->
<PasswordVerifyDialog
v-model:visible="passwordVerifyVisible"
@success="handlePasswordVerifySuccess"
/>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import RechargeDialog from './components/RechargeDialog.vue'
import PasswordVerifyDialog from './components/PasswordVerifyDialog.vue'
//
const memberList = ref([])
const loading = ref(false)
const total = ref(0)
//
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
name: undefined,
vipStatus: undefined
})
const queryFormRef = ref()
//
const rechargeDialogVisible = ref(false)
const passwordVerifyVisible = ref(false)
//
const currentMember = ref(null)
//
const mockMembers = [
{
id: 1,
name: '张三',
phone: '13800138000',
vipStatus: true,
vipExpireDate: '2024-12-31'
},
{
id: 2,
name: '李四',
phone: '13800138001',
vipStatus: false,
vipExpireDate: ''
},
{
id: 3,
name: '王五',
phone: '13800138002',
vipStatus: true,
vipExpireDate: '2024-06-30'
}
]
//
const getList = () => {
loading.value = true
setTimeout(() => {
//
let filteredList = [...mockMembers]
if (queryParams.name) {
filteredList = filteredList.filter(m => m.name.includes(queryParams.name))
}
if (queryParams.vipStatus !== undefined) {
filteredList = filteredList.filter(m => m.vipStatus === queryParams.vipStatus)
}
//
const start = (queryParams.pageNo - 1) * queryParams.pageSize
const end = start + queryParams.pageSize
memberList.value = filteredList.slice(start, end)
total.value = filteredList.length
loading.value = false
}, 500)
}
//
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
//
const resetQuery = () => {
queryFormRef.value?.resetFields()
handleQuery()
}
// /
const handleRecharge = (member) => {
currentMember.value = member
rechargeDialogVisible.value = true
}
//
const handleRechargeSuccess = (data) => {
const member = mockMembers.find(m => m.id === data.memberId)
if (member) {
member.vipStatus = true
member.vipExpireDate = data.expireDate
getList()
ElMessage.success('操作成功')
}
}
//
const handleCancel = (member) => {
currentMember.value = member
passwordVerifyVisible.value = true
}
//
const handlePasswordVerifySuccess = (password) => {
// TODO: API
// API
setTimeout(() => {
const index = mockMembers.findIndex(m => m.id === currentMember.value.id)
if (index !== -1) {
mockMembers[index] = {
...currentMember.value,
vipStatus: false,
vipExpireDate: ''
}
getList()
ElMessage.success('已取消会员资格')
//
passwordVerifyVisible.value = false
//
currentMember.value = null
}
}, 500)
}
onMounted(() => {
getList()
})
</script>
<style scoped>
.text-primary {
color: var(--el-color-primary);
}
.text-gray-400 {
color: var(--el-text-color-secondary);
}
:deep(.el-table) {
--el-table-border-color: var(--el-border-color-lighter);
--el-table-border: 1px solid var(--el-table-border-color);
--el-table-text-color: var(--el-text-color-regular);
--el-table-header-text-color: var(--el-text-color-secondary);
--el-table-row-hover-bg-color: var(--el-fill-color-light);
--el-table-current-row-bg-color: var(--el-color-primary-light-9);
--el-table-header-height: 50px;
--el-table-row-height: 60px;
}
:deep(.el-table__cell) {
padding: 12px 0;
}
.operation-buttons {
display: flex;
justify-content: center;
align-items: center;
gap: 4px;
}
:deep(.el-button--link) {
padding: 0 6px;
height: 26px;
font-size: 13px;
}
:deep(.el-button--link .el-icon) {
margin-right: 2px;
font-size: 14px;
}
</style>

View File

@ -0,0 +1,90 @@
<template>
<el-dialog
title="回访详情"
v-model="dialogVisible"
width="600px"
append-to-body
destroy-on-close
>
<el-descriptions :column="1" border>
<el-descriptions-item label="会员姓名">{{ visit?.name }}</el-descriptions-item>
<el-descriptions-item label="手机号">{{ visit?.phone }}</el-descriptions-item>
<el-descriptions-item label="回访状态">
<el-tag :type="visit?.visitStatus ? 'success' : 'warning'">
{{ visit?.visitStatus ? '已回访' : '未回访' }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="回访时间">{{ visit?.visitTime || '-' }}</el-descriptions-item>
<el-descriptions-item label="回访内容">{{ visit?.content || '-' }}</el-descriptions-item>
<el-descriptions-item label="回访结果">
<el-tag :type="getResultType(visit?.result)">
{{ visit?.result || '-' }}
</el-tag>
</el-descriptions-item>
<el-descriptions-item label="下次回访">{{ visit?.nextVisitTime || '-' }}</el-descriptions-item>
</el-descriptions>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
const props = defineProps({
visible: {
type: Boolean,
required: true
},
visit: {
type: Object,
default: () => null
}
})
const emit = defineEmits(['update:visible'])
const dialogVisible = ref(false)
// 访
const getResultType = (result) => {
const types = {
'满意': 'success',
'一般': 'warning',
'不满意': 'danger'
}
return types[result] || 'info'
}
// visible
watch(
() => props.visible,
(val) => {
dialogVisible.value = val
}
)
// dialogVisible
watch(
() => dialogVisible.value,
(val) => {
emit('update:visible', val)
}
)
</script>
<style scoped>
.dialog-footer {
text-align: right;
}
:deep(.el-descriptions__label) {
width: 120px;
justify-content: flex-end;
}
</style>

View File

@ -0,0 +1,169 @@
<template>
<el-dialog
:title="visit?.visitStatus ? '编辑回访记录' : '新增回访记录'"
v-model="dialogVisible"
width="600px"
append-to-body
destroy-on-close
>
<el-form
ref="formRef"
:model="formData"
:rules="rules"
label-width="100px"
>
<el-form-item label="会员姓名" prop="name">
<el-input v-model="formData.name" disabled />
</el-form-item>
<el-form-item label="手机号" prop="phone">
<el-input v-model="formData.phone" disabled />
</el-form-item>
<el-form-item label="回访时间" prop="visitTime">
<el-date-picker
v-model="formData.visitTime"
type="datetime"
placeholder="选择回访时间"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="回访内容" prop="content">
<el-input
v-model="formData.content"
type="textarea"
:rows="4"
placeholder="请输入回访内容"
/>
</el-form-item>
<el-form-item label="回访结果" prop="result">
<el-select v-model="formData.result" placeholder="请选择回访结果" style="width: 100%">
<el-option label="满意" value="满意" />
<el-option label="一般" value="一般" />
<el-option label="不满意" value="不满意" />
</el-select>
</el-form-item>
<el-form-item label="下次回访" prop="nextVisitTime">
<el-date-picker
v-model="formData.nextVisitTime"
type="date"
placeholder="选择下次回访时间"
style="width: 100%"
/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="handleSubmit"> </el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { ref, reactive, watch } from 'vue'
import { ElMessage } from 'element-plus'
import {Icon} from '@/components/Icon'
const props = defineProps({
visible: {
type: Boolean,
required: true
},
visit: {
type: Object,
default: () => null
}
})
const emit = defineEmits(['update:visible', 'success'])
const dialogVisible = ref(false)
const formRef = ref()
//
const formData = reactive({
id: undefined,
name: '',
phone: '',
visitTime: '',
content: '',
result: '',
nextVisitTime: ''
})
//
const rules = {
visitTime: [{ required: true, message: '请选择回访时间', trigger: 'change' }],
content: [{ required: true, message: '请输入回访内容', trigger: 'blur' }],
result: [{ required: true, message: '请选择回访结果', trigger: 'change' }],
nextVisitTime: [{ required: true, message: '请选择下次回访时间', trigger: 'change' }]
}
//
const resetForm = () => {
if (formRef.value) {
formRef.value.resetFields()
}
Object.assign(formData, {
id: undefined,
name: '',
phone: '',
visitTime: '',
content: '',
result: '',
nextVisitTime: ''
})
}
// visible
watch(
() => props.visible,
(val) => {
dialogVisible.value = val
}
)
// dialogVisible
watch(
() => dialogVisible.value,
(val) => {
emit('update:visible', val)
}
)
// visit
watch(
() => props.visit,
(val) => {
if (val) {
Object.assign(formData, val)
} else {
resetForm()
}
},
{ immediate: true }
)
//
const handleSubmit = async () => {
if (!formRef.value) return
await formRef.value.validate((valid) => {
if (valid) {
//
setTimeout(() => {
emit('success', {
...formData,
visitStatus: true
})
dialogVisible.value = false
}, 500)
}
})
}
</script>
<style scoped>
.dialog-footer {
text-align: right;
}
</style>

View File

@ -0,0 +1,297 @@
<template>
<div class="app-container">
<!-- 搜索工作栏 -->
<ContentWrap>
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="68px"
>
<el-form-item label="会员姓名" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入会员姓名"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="回访状态" prop="visitStatus">
<el-select
v-model="queryParams.visitStatus"
placeholder="请选择回访状态"
clearable
class="!w-240px"
>
<el-option label="已回访" :value="true" />
<el-option label="未回访" :value="false" />
</el-select>
</el-form-item>
<el-form-item label="回访结果" prop="result">
<el-select
v-model="queryParams.result"
placeholder="请选择回访结果"
clearable
class="!w-240px"
>
<el-option label="满意" value="满意" />
<el-option label="一般" value="一般" />
<el-option label="不满意" value="不满意" />
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table
v-loading="loading"
:data="visitList"
:show-overflow-tooltip="true"
>
<el-table-column label="姓名" align="center" prop="name" width="160" />
<el-table-column label="手机号" align="center" prop="phone" />
<el-table-column label="回访状态" align="center" prop="visitStatus" >
<template #default="scope">
<el-tag :type="scope.row.visitStatus ? 'success' : 'warning'">
{{ scope.row.visitStatus ? '已回访' : '未回访' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="回访时间" align="center" prop="visitTime" />
<el-table-column label="回访结果" align="center" prop="result" >
<template #default="scope">
<el-tag :type="getResultType(scope.row.result)">
{{ scope.row.result || '-' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="下次回访" align="center" prop="nextVisitTime" />
<el-table-column label="操作" align="center" width="150">
<template #default="scope">
<div class="flex items-center justify-center">
<el-button
type="primary"
link
size="default"
@click="handleVisit(scope.row)"
>
<Icon icon="ep:edit" class="mr-5px" />{{ scope.row.visitStatus ? '编辑' : '回访' }}
</el-button>
<el-button
v-if="scope.row.visitStatus"
type="info"
link
size="default"
@click="handleDetail(scope.row)"
>
<Icon icon="ep:view" class="mr-5px" />详情
</el-button>
</div>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
<!-- 回访弹窗 -->
<VisitDialog
v-model:visible="visitDialogVisible"
:visit="currentVisit"
@success="handleVisitSuccess"
/>
<!-- 详情弹窗 -->
<VisitDetail
v-model:visible="detailDialogVisible"
:visit="currentVisit"
/>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import VisitDialog from './components/VisitDialog.vue'
import VisitDetail from './components/VisitDetail.vue'
import { Icon } from '@/components/Icon'
// 访
const visitList = ref([])
const loading = ref(false)
const total = ref(0)
//
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
name: undefined,
visitStatus: undefined,
result: undefined
})
const queryFormRef = ref()
//
const visitDialogVisible = ref(false)
const detailDialogVisible = ref(false)
// 访
const currentVisit = ref(null)
// 访
const getResultType = (result) => {
const types = {
'满意': 'success',
'一般': 'warning',
'不满意': 'danger'
}
return types[result] || 'info'
}
//
const mockVisits = [
{
id: 1,
name: '张三',
phone: '13800138000',
visitStatus: true,
visitTime: '2024-03-20 14:30:00',
content: '客户对产品使用体验非常满意,建议增加更多功能',
result: '满意',
nextVisitTime: '2024-04-20'
},
{
id: 2,
name: '李四',
phone: '13800138001',
visitStatus: false,
visitTime: '',
content: '',
result: '',
nextVisitTime: ''
},
{
id: 3,
name: '王五',
phone: '13800138002',
visitStatus: true,
visitTime: '2024-03-19 10:00:00',
content: '客户反映产品偶尔会出现卡顿现象',
result: '一般',
nextVisitTime: '2024-04-19'
}
]
// 访
const getList = () => {
loading.value = true
setTimeout(() => {
//
let filteredList = [...mockVisits]
if (queryParams.name) {
filteredList = filteredList.filter(m => m.name.includes(queryParams.name))
}
if (queryParams.visitStatus !== undefined) {
filteredList = filteredList.filter(m => m.visitStatus === queryParams.visitStatus)
}
if (queryParams.result) {
filteredList = filteredList.filter(m => m.result === queryParams.result)
}
//
const start = (queryParams.pageNo - 1) * queryParams.pageSize
const end = start + queryParams.pageSize
visitList.value = filteredList.slice(start, end)
total.value = filteredList.length
loading.value = false
}, 500)
}
//
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
//
const resetQuery = () => {
queryFormRef.value?.resetFields()
handleQuery()
}
// 访/
const handleVisit = (visit) => {
currentVisit.value = visit
visitDialogVisible.value = true
}
//
const handleDetail = (visit) => {
currentVisit.value = visit
detailDialogVisible.value = true
}
// 访
const handleVisitSuccess = (data) => {
const index = mockVisits.findIndex(m => m.id === data.id)
if (index !== -1) {
mockVisits[index] = data
getList()
ElMessage.success('操作成功')
}
}
onMounted(() => {
getList()
})
</script>
<style scoped>
:deep(.el-table) {
--el-table-border-color: var(--el-border-color-lighter);
--el-table-border: 1px solid var(--el-table-border-color);
--el-table-text-color: var(--el-text-color-regular);
--el-table-header-text-color: var(--el-text-color-secondary);
--el-table-row-hover-bg-color: var(--el-fill-color-light);
--el-table-current-row-bg-color: var(--el-color-primary-light-9);
--el-table-header-height: 50px;
--el-table-row-height: 60px;
}
:deep(.el-table__cell) {
padding: 12px 0;
}
.operation-buttons {
display: flex;
justify-content: center;
align-items: center;
gap: 4px;
}
:deep(.el-button--link) {
padding: 0 6px;
height: 26px;
font-size: 13px;
}
:deep(.el-button--link .el-icon) {
margin-right: 2px;
font-size: 14px;
}
</style>