liujie
昨天 c983a0a398504697a777ffae48e59961b5ee2bd7
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryRef" v-show="showSearch" :inline="true" label-width="80px">
      <el-form-item label="用户编号" prop="userId">
        <el-input v-model="queryParams.userId" placeholder="请输入用户编号" clearable style="width: 160px" @keyup.enter="handleQuery" />
      </el-form-item>
      <el-form-item label="用户手机" prop="phone">
        <el-input v-model="queryParams.phone" placeholder="请输入完整手机号" clearable style="width: 180px" @keyup.enter="handleQuery" />
      </el-form-item>
      <el-form-item label="等级" prop="systemLevel">
        <el-select v-model="queryParams.systemLevel" placeholder="全部等级" clearable style="width: 130px">
          <el-option v-for="level in LEVELS" :key="level" :label="level" :value="level" />
        </el-select>
      </el-form-item>
      <el-form-item label="认证状态" prop="authStatus">
        <el-select v-model="queryParams.authStatus" placeholder="全部状态" clearable style="width: 130px">
          <el-option v-for="item in AUTH_STATUS" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </el-form-item>
      <el-form-item label="主体类型" prop="subjectType">
        <el-select v-model="queryParams.subjectType" placeholder="全部类型" clearable style="width: 150px">
          <el-option v-for="item in SUBJECT_TYPES" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </el-form-item>
      <el-form-item label="所属城市" prop="city">
        <!-- 选项来自城市主数据的启用城市(与城市公司档案共用同一数据源)。
             会员表只存 city(市级、无省份),故这里按市名精确匹配,
             原先「只选省时把该省全部市名拼成 IN」的口径随城市主数据上线一起去掉了。 -->
        <el-select v-model="queryParams.city" placeholder="全部城市" clearable filterable style="width: 180px">
          <el-option
            v-for="item in cityOptions"
            :key="item.id"
            :label="item.province ? item.province + ' / ' + item.cityName : item.cityName"
            :value="item.cityName"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="注册时间">
        <el-date-picker
          v-model="dateRange"
          value-format="YYYY-MM-DD"
          type="daterange"
          range-separator="-"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          style="width: 240px"
        />
      </el-form-item>
      <el-form-item label="账户状态" prop="status">
        <el-select v-model="queryParams.status" placeholder="全部状态" clearable style="width: 130px">
          <el-option v-for="item in ACCOUNT_STATUS" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>
 
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="warning"
          plain
          icon="Download"
          @click="handleExport"
          v-hasPermi="['member:user:export']"
        >下载</el-button>
      </el-col>
      <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>
 
    <!-- 除操作列固定宽度外,其余列一律 min-width:
         全部写死 width 会让宽屏下的剩余空间无处可去,表格右侧留白 -->
    <el-table v-loading="loading" :data="memberList">
      <el-table-column label="用户编号" prop="userId" min-width="100" />
      <el-table-column label="用户手机" prop="phone" min-width="130" />
      <el-table-column label="等级" prop="systemLevel" min-width="90" align="center">
        <template #default="scope">
          <el-tag :type="levelTagType(scope.row.systemLevel)" size="small">{{ scope.row.systemLevel || '-' }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="认证状态" prop="authStatus" min-width="110" align="center">
        <template #default="scope">
          <el-tag :type="authTagType(scope.row.authStatus)" size="small">{{ labelOf(AUTH_STATUS, scope.row.authStatus) }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="主体类型" prop="subjectType" min-width="120">
        <template #default="scope">{{ labelOf(SUBJECT_TYPES, scope.row.subjectType) }}</template>
      </el-table-column>
      <el-table-column label="所属城市" prop="city" min-width="110" show-overflow-tooltip />
      <el-table-column label="注册时间" prop="createTime" min-width="170" />
      <el-table-column label="账户状态" prop="status" min-width="110" align="center">
        <template #default="scope">
          <el-tag :type="statusTagType(scope.row.status)" size="small">{{ labelOf(ACCOUNT_STATUS, scope.row.status) }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" width="150" fixed="right">
        <template #default="scope">
          <el-button link type="primary" @click="handleView(scope.row)" v-hasPermi="['member:user:query']">查看</el-button>
          <el-button
            v-if="canToggleStatus(scope.row.status)"
            link
            type="primary"
            @click="handleToggleStatus(scope.row)"
            v-hasPermi="['member:user:edit']"
          >{{ isEnabled(scope.row.status) ? '禁用' : '启用' }}</el-button>
        </template>
      </el-table-column>
    </el-table>
 
    <pagination
      v-show="total > 0"
      :total="total"
      v-model:page="queryParams.pageNum"
      v-model:limit="queryParams.pageSize"
      @pagination="getList"
    />
  </div>
</template>
 
<script setup name="MemberUser">
import { listMember, changeMemberStatus } from '@/api/user/member'
import { listCityOptions } from '@/api/user/city'
import {
  LEVELS,
  SUBJECT_TYPES,
  AUTH_STATUS,
  ACCOUNT_STATUS,
  labelOf,
  levelTagType,
  authTagType,
  statusTagType,
  isEnabled,
  canToggleStatus
} from '@/utils/member'
 
const { proxy } = getCurrentInstance()
const router = useRouter()
 
const memberList = ref([])
const cityOptions = ref([])
const loading = ref(true)
const showSearch = ref(true)
const total = ref(0)
const dateRange = ref([])
 
const data = reactive({
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    userId: null,
    phone: null,
    systemLevel: null,
    authStatus: null,
    subjectType: null,
    city: null,
    status: null
  }
})
 
const { queryParams } = toRefs(data)
 
// 城市下拉取自城市主数据的启用城市:城市表里没有的市名筛不出人,
// 反过来只要库里那个城市被禁用或被逻辑删除,它也不会出现在选项中。
function getCityOptions() {
  listCityOptions().then(response => {
    cityOptions.value = response.data || []
  })
}
 
function getList() {
  loading.value = true
  // addDateRange 往 params 里塞 beginTime/endTime,与 city 在同一层不冲突
  proxy.addDateRange(queryParams.value, dateRange.value)
  listMember(queryParams.value).then(response => {
    memberList.value = response.rows
    total.value = response.total
    loading.value = false
  })
}
 
function handleQuery() {
  queryParams.value.pageNum = 1
  getList()
}
 
function resetQuery() {
  dateRange.value = []
  proxy.resetForm('queryRef')
  handleQuery()
}
 
function handleView(row) {
  router.push('/member/user-detail/index/' + row.userId)
}
 
function handleToggleStatus(row) {
  const enabled = isEnabled(row.status)
  const action = enabled ? '禁用' : '启用'
  // 只切「正常 <-> 禁用」两态;注销中/已注销由注销审核流程驱动,不在这里改
  const targetStatus = enabled ? '1' : '0'
  // 文案按原型:禁用要说清后果(无法登录与操作小程序),启用则是对称的正向表述
  const tip = enabled
    ? '是否确认禁用该用户,禁用后该用户将无法登录和操作小程序!'
    : '是否确认启用该用户,启用后该用户可正常登录和操作小程序!'
  proxy.$modal.confirm(tip, '提示', { confirmButtonText: '确认' }).then(() => {
    return changeMemberStatus(row.userId, targetStatus)
  }).then(() => {
    getList()
    proxy.$modal.msgSuccess(`${action}成功`)
  }).catch(() => {})
}
 
function handleExport() {
  proxy.download('account/user/export', {
    ...queryParams.value
  }, `member_${new Date().getTime()}.xlsx`)
}
 
getCityOptions()
getList()
</script>