|
@@ -93,6 +93,14 @@
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
<el-table-column prop="familyId" label="家庭ID" width="100"></el-table-column>
|
|
<el-table-column prop="familyId" label="家庭ID" width="100"></el-table-column>
|
|
|
|
|
+ <el-table-column label="会员级别" width="100">
|
|
|
|
|
+ <template slot-scope="{ row }">
|
|
|
|
|
+ <el-tag :type="memberLevelType(row.memberLevel)" size="small">{{ memberLevelLabel(row.memberLevel) }}</el-tag>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </el-table-column>
|
|
|
|
|
+ <el-table-column label="推荐人" width="140">
|
|
|
|
|
+ <template slot-scope="{ row }">{{ row.referrerName || '—' }}</template>
|
|
|
|
|
+ </el-table-column>
|
|
|
<el-table-column prop="createdAt" label="创建时间" width="180">
|
|
<el-table-column prop="createdAt" label="创建时间" width="180">
|
|
|
<template slot-scope="scope">
|
|
<template slot-scope="scope">
|
|
|
{{ formatDate(scope.row.createdAt) }}
|
|
{{ formatDate(scope.row.createdAt) }}
|
|
@@ -146,6 +154,26 @@
|
|
|
<el-form-item label="手机号" prop="phone">
|
|
<el-form-item label="手机号" prop="phone">
|
|
|
<el-input v-model="editForm.phone" placeholder="请输入手机号"></el-input>
|
|
<el-input v-model="editForm.phone" placeholder="请输入手机号"></el-input>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
+ <el-form-item label="推荐人">
|
|
|
|
|
+ <el-select
|
|
|
|
|
+ v-model="editForm.referrerId"
|
|
|
|
|
+ filterable
|
|
|
|
|
+ remote
|
|
|
|
|
+ reserve-keyword
|
|
|
|
|
+ clearable
|
|
|
|
|
+ placeholder="搜索推荐人(昵称/手机号/ID)"
|
|
|
|
|
+ :remote-method="searchUsersForReferrer"
|
|
|
|
|
+ :loading="userSearchLoading"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-option
|
|
|
|
|
+ v-for="u in userSearchResults"
|
|
|
|
|
+ :key="u.id"
|
|
|
|
|
+ :label="(u.nickname || u.realName || '') + ' (ID:' + u.id + ')'"
|
|
|
|
|
+ :value="u.id"
|
|
|
|
|
+ ></el-option>
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
<el-form-item label="角色">
|
|
<el-form-item label="角色">
|
|
|
<el-checkbox-group v-model="editForm.roles">
|
|
<el-checkbox-group v-model="editForm.roles">
|
|
|
<el-checkbox
|
|
<el-checkbox
|
|
@@ -200,7 +228,7 @@
|
|
|
|
|
|
|
|
<script>
|
|
<script>
|
|
|
import SortMixin from '@/mixins/SortMixin'
|
|
import SortMixin from '@/mixins/SortMixin'
|
|
|
-import { getUserList, updateUser, deleteUser, resetUserPassword } from '@/api/admin'
|
|
|
|
|
|
|
+import { getUserList, updateUser, deleteUser, resetUserPassword, searchUsers } from '@/api/admin'
|
|
|
|
|
|
|
|
import { getRoleLabel } from '@/utils/permissions'
|
|
import { getRoleLabel } from '@/utils/permissions'
|
|
|
|
|
|
|
@@ -241,7 +269,8 @@ export default {
|
|
|
nickname: '',
|
|
nickname: '',
|
|
|
realName: '',
|
|
realName: '',
|
|
|
phone: '',
|
|
phone: '',
|
|
|
- roles: []
|
|
|
|
|
|
|
+ roles: [],
|
|
|
|
|
+ referrerId: null
|
|
|
},
|
|
},
|
|
|
editRules: {
|
|
editRules: {
|
|
|
nickname: [
|
|
nickname: [
|
|
@@ -258,7 +287,9 @@ export default {
|
|
|
{ value: 'nutritionist', label: '营养师', disabled: false },
|
|
{ value: 'nutritionist', label: '营养师', disabled: false },
|
|
|
{ value: 'supplier', label: '供应商', disabled: false },
|
|
{ value: 'supplier', label: '供应商', disabled: false },
|
|
|
{ value: 'activity_manager', label: '活动管理员', disabled: false },
|
|
{ value: 'activity_manager', label: '活动管理员', disabled: false },
|
|
|
- ]
|
|
|
|
|
|
|
+ ],
|
|
|
|
|
+ userSearchResults: [],
|
|
|
|
|
+ userSearchLoading: false,
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
mounted() {
|
|
mounted() {
|
|
@@ -286,9 +317,10 @@ export default {
|
|
|
}
|
|
}
|
|
|
if (this.sortState.length > 0) params.sort = this.sortState
|
|
if (this.sortState.length > 0) params.sort = this.sortState
|
|
|
|
|
|
|
|
- const res = await getUserList(params)
|
|
|
|
|
- this.tableData = res.data.records || res.data || []
|
|
|
|
|
- this.pagination.total = res.data.total || this.tableData.length
|
|
|
|
|
|
|
+const res = await getUserList(params)
|
|
|
|
|
+ this.tableData = res.data.records || res.data || []
|
|
|
|
|
+ this.pagination.total = res.data.total || this.tableData.length
|
|
|
|
|
+ await this.resolveReferrerNames(this.tableData)
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
this.$message.error(error.message || '加载用户列表失败')
|
|
this.$message.error(error.message || '加载用户列表失败')
|
|
|
} finally {
|
|
} finally {
|
|
@@ -325,7 +357,8 @@ export default {
|
|
|
nickname: row.nickname,
|
|
nickname: row.nickname,
|
|
|
realName: row.realName || '',
|
|
realName: row.realName || '',
|
|
|
phone: row.phone || '',
|
|
phone: row.phone || '',
|
|
|
- roles: row.roles ? [...row.roles] : (row.role ? [row.role] : [])
|
|
|
|
|
|
|
+ roles: row.roles ? [...row.roles] : (row.role ? [row.role] : []),
|
|
|
|
|
+ referrerId: row.referrerId || null
|
|
|
}
|
|
}
|
|
|
this.editDialogVisible = true
|
|
this.editDialogVisible = true
|
|
|
},
|
|
},
|
|
@@ -412,6 +445,56 @@ export default {
|
|
|
formatDate(dateStr) {
|
|
formatDate(dateStr) {
|
|
|
if (!dateStr) return '-'
|
|
if (!dateStr) return '-'
|
|
|
return String(dateStr).replace('T', ' ').substring(0, 19)
|
|
return String(dateStr).replace('T', ' ').substring(0, 19)
|
|
|
|
|
+ },
|
|
|
|
|
+ memberLevelLabel(level) {
|
|
|
|
|
+ const map = { FREE: '免费', FAMILY: '家庭会员', PROVIDER: '服务商' }
|
|
|
|
|
+ return map[level] || '免费'
|
|
|
|
|
+ },
|
|
|
|
|
+ memberLevelType(level) {
|
|
|
|
|
+ const map = { FREE: 'info', FAMILY: 'success', PROVIDER: 'warning' }
|
|
|
|
|
+ return map[level] || 'info'
|
|
|
|
|
+ },
|
|
|
|
|
+ async searchUsersForReferrer(query) {
|
|
|
|
|
+ if (!query) {
|
|
|
|
|
+ this.userSearchResults = []
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ this.userSearchLoading = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await searchUsers({ keyword: query })
|
|
|
|
|
+ this.userSearchResults = res.data || []
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ this.userSearchResults = []
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ this.userSearchLoading = false
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ resolveReferrerNames(items) {
|
|
|
|
|
+ if (!items || items.length === 0) return Promise.resolve()
|
|
|
|
|
+ var ids = []
|
|
|
|
|
+ items.forEach(function(item) {
|
|
|
|
|
+ if (item.referrerId && ids.indexOf(item.referrerId) === -1) ids.push(item.referrerId)
|
|
|
|
|
+ })
|
|
|
|
|
+ if (ids.length === 0) return Promise.resolve()
|
|
|
|
|
+ var nameMap = {}
|
|
|
|
|
+ return Promise.all(ids.map(function(id) {
|
|
|
|
|
+ return searchUsers({ keyword: String(id) })
|
|
|
|
|
+ .then(function(res) {
|
|
|
|
|
+ if (res.data && res.data.length > 0) {
|
|
|
|
|
+ var u = res.data[0]
|
|
|
|
|
+ nameMap[id] = u.nickname || u.realName || '用户' + id
|
|
|
|
|
+ } else {
|
|
|
|
|
+ nameMap[id] = '用户' + id
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch(function() {
|
|
|
|
|
+ nameMap[id] = '用户' + id
|
|
|
|
|
+ })
|
|
|
|
|
+ })).then(function() {
|
|
|
|
|
+ items.forEach(function(item) {
|
|
|
|
|
+ item.referrerName = nameMap[item.referrerId] || ''
|
|
|
|
|
+ })
|
|
|
|
|
+ })
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|