TuokeListDialog.vue
12.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
<template>
<el-dialog
:visible.sync="visibleProxy"
:show-close="false"
width="90%"
:close-on-click-modal="false"
custom-class="tuoke-list-dialog"
append-to-body
>
<div class="dialog-inner">
<div class="dialog-header">
<div class="dialog-title">拓客数据</div>
<span class="dialog-close" @click="visibleProxy = false"><i class="el-icon-close"></i></span>
</div>
<div class="dialog-search">
<el-form @submit.native.prevent :inline="true" size="small">
<el-form-item label="拓客时间">
<el-date-picker v-model="query.expansionTime" type="daterange" value-format="timestamp" format="yyyy-MM-dd" start-placeholder="开始" end-placeholder="结束" style="width:220px" />
</el-form-item>
<el-form-item label="拓客活动">
<el-select v-model="query.eventId" placeholder="请选择" clearable filterable style="width:180px" :loading="eventLoading">
<el-option v-for="e in eventList" :key="e.id" :label="e.eventName" :value="e.id" />
</el-select>
</el-form-item>
<el-form-item label="顾客姓名">
<el-input v-model="query.customerName" placeholder="顾客姓名" clearable style="width:140px" />
</el-form-item>
<el-form-item label="电话号码">
<el-input v-model="query.customerPhone" placeholder="电话号码" clearable style="width:140px" />
</el-form-item>
<template v-if="showAll">
<el-form-item label="购买张数">
<el-input v-model="query.buyNumber" placeholder="购买张数" clearable style="width:120px" />
</el-form-item>
<el-form-item label="支付方式">
<el-select v-model="query.paymentMethod" placeholder="支付方式" clearable style="width:120px">
<el-option v-for="p in payMethodOptions" :key="p" :label="p" :value="p" />
</el-select>
</el-form-item>
<el-form-item label="是否加微信">
<el-select v-model="query.isAddWeChat" placeholder="是否加微信" clearable style="width:120px">
<el-option label="是" value="是" /><el-option label="否" value="否" />
</el-select>
</el-form-item>
<el-form-item label="所属战队">
<el-input v-model="query.teamName" placeholder="战队名称" clearable style="width:130px" />
</el-form-item>
</template>
<el-form-item>
<el-button type="primary" @click="search">查询</el-button>
<el-button @click="reset">重置</el-button>
<el-button type="text" @click="showAll = !showAll">
{{ showAll ? '收起' : '展开' }}
<i :class="showAll ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"></i>
</el-button>
</el-form-item>
</el-form>
</div>
<div class="dialog-content">
<el-table v-loading="loading" :data="list" border size="small" :header-cell-style="{ background:'#f8fafc', color:'#64748b', fontWeight:600 }">
<el-table-column prop="eventName" label="拓客活动" show-overflow-tooltip />
<el-table-column prop="expansionUserName" label="拓客人员" show-overflow-tooltip />
<el-table-column prop="storeName" label="所属门店" show-overflow-tooltip />
<el-table-column label="拓客时间" width="140">
<template slot-scope="{ row }">{{ formatDate(row.expansionTime) }}</template>
</el-table-column>
<el-table-column prop="customerName" label="顾客姓名" show-overflow-tooltip />
<el-table-column prop="customerPhone" label="电话号码" show-overflow-tooltip />
<el-table-column prop="buyNumber" label="购买张数" width="90" />
<el-table-column prop="paymentMethod" label="支付方式" width="100" />
<el-table-column prop="isAddWeChat" label="是否加微信" width="110" />
<el-table-column prop="teamName" label="所属战队" show-overflow-tooltip />
<el-table-column prop="remarks" label="备注" width="260" show-overflow-tooltip />
</el-table>
</div>
<div class="dialog-footer">
<el-pagination
background
layout="total, sizes, prev, pager, next, jumper"
:total="total"
:page-size.sync="listQuery.pageSize"
:current-page.sync="listQuery.currentPage"
:page-sizes="[10, 20, 50, 100]"
@size-change="initData"
@current-change="initData"
/>
</div>
</div>
</el-dialog>
</template>
<script>
const MOCK_TUOKE = [
{ id: '1', eventName: '龙城国际20260210', teamName: '3', storeName: '龙城国际', expansionTime: '2026-02-10 17:00:51', expansionUserName: '赵倩', customerName: '李女士', customerPhone: '18571990586', buyNumber: 1, paymentMethod: '微信', isAddWeChat: '是', remarks: '年后来做' },
{ id: '2', eventName: '红光20260210', teamName: '3', storeName: '红光', expansionTime: '2026-02-10 16:41:39', expansionUserName: '赵倩', customerName: '阮女士', customerPhone: '17320569150', buyNumber: 1, paymentMethod: '微信', isAddWeChat: '否', remarks: '和王一起来,龙城国际体验' },
{ id: '3', eventName: '龙城国际20260210', teamName: '3', storeName: '龙城国际', expansionTime: '2026-02-10 16:40:53', expansionUserName: '赵倩', customerName: '王女士', customerPhone: '17674617541', buyNumber: 1, paymentMethod: '微信', isAddWeChat: '是', remarks: '' },
{ id: '4', eventName: '红光20260210', teamName: '1', storeName: '红光', expansionTime: '2026-02-10 16:18:30', expansionUserName: '宁燕', customerName: '杜女士', customerPhone: '18990421079', buyNumber: 1, paymentMethod: '微信', isAddWeChat: '是', remarks: '不要礼品,做4个项目' },
{ id: '5', eventName: '犀浦20260206', teamName: '杨钦岚', storeName: '犀浦', expansionTime: '2026-02-06 17:39:33', expansionUserName: '杨钦岚', customerName: '吕女士', customerPhone: '18708437941', buyNumber: 1, paymentMethod: '微信', isAddWeChat: '是', remarks: '' },
{ id: '6', eventName: '犀浦20260206', teamName: '杨钦岚', storeName: '犀浦', expansionTime: '2026-02-06 16:00:55', expansionUserName: '杨钦岚', customerName: '李女士', customerPhone: '13228452004', buyNumber: 1, paymentMethod: '微信', isAddWeChat: '是', remarks: '' },
{ id: '7', eventName: '犀浦20260206', teamName: '赵倩', storeName: '犀浦', expansionTime: '2026-02-06 15:36:18', expansionUserName: '赵倩', customerName: '曾女士', customerPhone: '13699459777', buyNumber: 1, paymentMethod: '微信', isAddWeChat: '否', remarks: '陈女士同事' },
{ id: '8', eventName: '犀浦20260206', teamName: '赵倩', storeName: '犀浦', expansionTime: '2026-02-06 15:35:25', expansionUserName: '赵倩', customerName: '陈女士', customerPhone: '15982056520', buyNumber: 1, paymentMethod: '微信', isAddWeChat: '是', remarks: '对面培训机构老师' },
{ id: '9', eventName: '犀浦20260206', teamName: '杨钦岚', storeName: '犀浦', expansionTime: '2026-02-06 13:36:43', expansionUserName: '杨钦岚', customerName: '阳女士', customerPhone: '18190344149', buyNumber: 1, paymentMethod: '微信', isAddWeChat: '是', remarks: '' },
{ id: '10', eventName: '犀浦20260206', teamName: '宁燕', storeName: '犀浦', expansionTime: '2026-02-06 12:36:29', expansionUserName: '宁燕', customerName: '何女士', customerPhone: '13778587844', buyNumber: 1, paymentMethod: '微信', isAddWeChat: '否', remarks: '和林女士一起到店体验' }
]
export default {
name: 'TuokeListDialog',
props: { visible: { type: Boolean, default: false } },
data() {
return {
showAll: false,
loading: false,
eventLoading: false,
eventList: [],
list: [],
total: 0,
mockData: MOCK_TUOKE,
query: { expansionTime: undefined, eventId: undefined, customerName: undefined, customerPhone: undefined, buyNumber: undefined, paymentMethod: undefined, isAddWeChat: undefined, teamName: undefined },
listQuery: { currentPage: 1, pageSize: 10, sort: 'desc', sidx: '' },
payMethodOptions: ['微信', '支付宝', '现金', '银行转账']
}
},
computed: {
visibleProxy: {
get() { return this.visible },
set(v) { this.$emit('update:visible', v) }
}
},
watch: {
visible(v) { if (v) { this.initData(); this.getEventList() } }
},
methods: {
formatDate(ts) {
if (!ts) return '-'
if (typeof ts === 'string' && ts.includes('-')) return ts.substring(0, 10)
const d = new Date(typeof ts === 'number' ? ts : Number(ts))
if (isNaN(d.getTime())) return '-'
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
},
getEventList() {
const map = new Map()
this.mockData.forEach(r => { if (!map.has(r.eventName)) map.set(r.eventName, { id: r.eventName, eventName: r.eventName }) })
this.eventList = [...map.values()]
},
initData() {
this.loading = true
setTimeout(() => {
let filtered = [...this.mockData]
if (this.query.eventId) filtered = filtered.filter(r => r.eventName === this.eventList.find(e => e.id === this.query.eventId)?.eventName)
if (this.query.customerName) filtered = filtered.filter(r => r.customerName.includes(this.query.customerName))
if (this.query.customerPhone) filtered = filtered.filter(r => r.customerPhone.includes(this.query.customerPhone))
if (this.query.paymentMethod) filtered = filtered.filter(r => r.paymentMethod === this.query.paymentMethod)
if (this.query.isAddWeChat) filtered = filtered.filter(r => r.isAddWeChat === this.query.isAddWeChat)
if (this.query.teamName) filtered = filtered.filter(r => r.teamName.includes(this.query.teamName))
this.total = filtered.length
const start = (this.listQuery.currentPage - 1) * this.listQuery.pageSize
this.list = filtered.slice(start, start + this.listQuery.pageSize)
this.loading = false
}, 300)
},
search() { this.listQuery.currentPage = 1; this.initData() },
reset() {
for (const k in this.query) this.query[k] = undefined
this.listQuery = { currentPage: 1, pageSize: 10, sort: 'desc', sidx: '' }
this.initData()
}
}
}
</script>
<style lang="scss" scoped>
::v-deep .tuoke-list-dialog { max-width: 1600px; margin-top: 3vh !important; border-radius: 20px; padding: 0; background: radial-gradient(circle at 0 0, rgba(255,255,255,0.96) 0, rgba(248,250,252,0.98) 40%, rgba(241,245,249,0.98) 100%); box-shadow: 0 24px 48px rgba(15,23,42,0.18), 0 0 0 1px rgba(255,255,255,0.9); backdrop-filter: blur(22px); -webkit-backdrop-filter: blur(22px); }
::v-deep .el-dialog__header { display: none; }
::v-deep .el-dialog__body { padding: 0; }
.dialog-inner { display: flex; flex-direction: column; max-height: 92vh; }
.dialog-header { flex-shrink: 0; display: flex; align-items: center; justify-content: space-between; margin: 18px 22px 0; padding: 10px 14px; border-radius: 14px; background: rgba(219,234,254,0.96); }
.dialog-title { font-size: 17px; font-weight: 600; color: #0f172a; }
.dialog-close { cursor: pointer; width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; border-radius: 999px; color: #64748b; transition: all 0.15s; &:hover { background: rgba(0,0,0,0.06); color: #0f172a; } }
.dialog-search { flex-shrink: 0; padding: 12px 22px 4px; }
.dialog-content { flex: 1; min-height: 0; overflow: auto; padding: 0 22px; }
.dialog-footer { flex-shrink: 0; display: flex; align-items: center; justify-content: flex-end; padding: 10px 22px 14px; border-top: 1px solid rgba(229,231,235,0.6); }
::v-deep .tuoke-list-dialog .el-input__inner { border-radius: 999px; height: 32px; line-height: 32px; border-color: #e5e7eb; background-color: #f9fafb; &:focus { border-color: #2563eb; box-shadow: 0 0 0 1px rgba(37,99,235,0.18); } }
::v-deep .tuoke-list-dialog .el-button--primary { border-radius: 999px; background: #2563eb; border-color: #2563eb; box-shadow: 0 4px 10px rgba(37,99,235,0.35); }
::v-deep .tuoke-list-dialog .el-button--default { border-radius: 999px; }
::v-deep .tuoke-list-dialog .el-form-item { margin-bottom: 8px; }
::v-deep .tuoke-list-dialog .el-form-item__label { white-space: nowrap; }
::v-deep .tuoke-list-dialog .el-range-editor.el-input__inner { border-radius: 999px; }
</style>