index.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. <template>
  2. <doc-alert title="公众号粉丝" url="https://doc.iocoder.cn/mp/user/" />
  3. <!-- 搜索工作栏 -->
  4. <ContentWrap>
  5. <el-form
  6. class="-mb-15px"
  7. :model="queryParams"
  8. ref="queryFormRef"
  9. :inline="true"
  10. label-width="68px"
  11. >
  12. <el-form-item label="公众号" prop="accountId">
  13. <el-select v-model="queryParams.accountId" placeholder="请选择公众号" class="!w-240px">
  14. <el-option
  15. v-for="item in accountList"
  16. :key="item.id"
  17. :label="item.name"
  18. :value="item.id"
  19. />
  20. </el-select>
  21. </el-form-item>
  22. <el-form-item label="用户标识" prop="openid">
  23. <el-input
  24. v-model="queryParams.openid"
  25. placeholder="请输入用户标识"
  26. clearable
  27. @keyup.enter="handleQuery"
  28. class="!w-240px"
  29. />
  30. </el-form-item>
  31. <el-form-item label="昵称" prop="nickname">
  32. <el-input
  33. v-model="queryParams.nickname"
  34. placeholder="请输入昵称"
  35. clearable
  36. @keyup.enter="handleQuery"
  37. class="!w-240px"
  38. />
  39. </el-form-item>
  40. <el-form-item>
  41. <el-button @click="handleQuery"><Icon icon="ep:search" />搜索</el-button>
  42. <el-button @click="resetQuery"><Icon icon="ep:refresh" />重置</el-button>
  43. <el-button type="success" plain @click="handleSync" v-hasPermi="['mp:user:sync']">
  44. <Icon icon="ep:refresh" class="mr-5px" /> 同步
  45. </el-button>
  46. </el-form-item>
  47. </el-form>
  48. </ContentWrap>
  49. <!-- 列表 -->
  50. <ContentWrap>
  51. <el-table v-loading="loading" :data="list">
  52. <el-table-column label="编号" align="center" prop="id" />
  53. <el-table-column label="用户标识" align="center" prop="openid" width="260" />
  54. <el-table-column label="昵称" align="center" prop="nickname" />
  55. <el-table-column label="备注" align="center" prop="remark" />
  56. <el-table-column label="标签" align="center" prop="tagIds" width="200">
  57. <template #default="scope">
  58. <span v-for="(tagId, index) in scope.row.tagIds" :key="index">
  59. <el-tag>{{ tagList.find((tag) => tag.tagId === tagId)?.name }} </el-tag>&nbsp;
  60. </span>
  61. </template>
  62. </el-table-column>
  63. <el-table-column label="订阅状态" align="center" prop="subscribeStatus">
  64. <template #default="scope">
  65. <el-tag v-if="scope.row.subscribeStatus === 0" type="success">已订阅</el-tag>
  66. <el-tag v-else type="danger">未订阅</el-tag>
  67. </template>
  68. </el-table-column>
  69. <el-table-column
  70. label="订阅时间"
  71. align="center"
  72. prop="subscribeTime"
  73. width="180"
  74. :formatter="dateFormatter"
  75. />
  76. <el-table-column label="操作" align="center">
  77. <template #default="scope">
  78. <el-button
  79. type="primary"
  80. link
  81. @click="openForm(scope.row.id)"
  82. v-hasPermi="['mp:user:update']"
  83. >
  84. 修改
  85. </el-button>
  86. </template>
  87. </el-table-column>
  88. </el-table>
  89. <!-- 分页 -->
  90. <Pagination
  91. :total="total"
  92. v-model:page="queryParams.pageNo"
  93. v-model:limit="queryParams.pageSize"
  94. @pagination="getList"
  95. />
  96. </ContentWrap>
  97. <!-- 表单弹窗:修改 -->
  98. <UserForm ref="formRef" @success="getList" />
  99. </template>
  100. <script lang="ts" setup name="MpUser">
  101. import { dateFormatter } from '@/utils/formatTime'
  102. import * as MpAccountApi from '@/api/mp/account'
  103. import * as MpUserApi from '@/api/mp/user'
  104. import * as MpTagApi from '@/api/mp/tag'
  105. import UserForm from './UserForm.vue'
  106. const message = useMessage() // 消息
  107. const loading = ref(true) // 列表的加载中
  108. const total = ref(0) // 列表的总页数
  109. const list = ref([]) // 列表的数据
  110. const queryParams = reactive({
  111. pageNo: 1,
  112. pageSize: 10,
  113. accountId: null,
  114. openid: null,
  115. nickname: null
  116. })
  117. const queryFormRef = ref() // 搜索的表单
  118. const accountList = ref([]) // 公众号账号列表
  119. const tagList = ref([]) // 公众号标签列表
  120. /** 查询列表 */
  121. const getList = async () => {
  122. // 如果没有选中公众号账号,则进行提示。
  123. if (!queryParams.accountId) {
  124. message.error('未选中公众号,无法查询用户')
  125. return false
  126. }
  127. try {
  128. loading.value = true
  129. const data = await MpUserApi.getUserPage(queryParams)
  130. list.value = data.list
  131. total.value = data.total
  132. } finally {
  133. loading.value = false
  134. }
  135. }
  136. /** 搜索按钮操作 */
  137. const handleQuery = () => {
  138. queryParams.pageNo = 1
  139. getList()
  140. }
  141. /** 重置按钮操作 */
  142. const resetQuery = () => {
  143. queryFormRef.value.resetFields()
  144. // 默认选中第一个
  145. if (accountList.value.length > 0) {
  146. queryParams.accountId = accountList.value[0].id
  147. }
  148. handleQuery()
  149. }
  150. /** 添加/修改操作 */
  151. const formRef = ref()
  152. const openForm = (id: number) => {
  153. formRef.value.open(id)
  154. }
  155. /** 同步标签 */
  156. const handleSync = async () => {
  157. const accountId = queryParams.accountId
  158. try {
  159. await message.confirm('是否确认同步粉丝?')
  160. await MpUserApi.syncUser(accountId)
  161. message.success('开始从微信公众号同步粉丝信息,同步需要一段时间,建议稍后再查询')
  162. await getList()
  163. } catch {}
  164. }
  165. /** 初始化 */
  166. onMounted(async () => {
  167. // 加载标签
  168. tagList.value = await MpTagApi.getSimpleTagList()
  169. // 加载账号
  170. accountList.value = await MpAccountApi.getSimpleAccountList()
  171. if (accountList.value.length > 0) {
  172. queryParams.accountId = accountList.value[0].id
  173. }
  174. await getList()
  175. })
  176. </script>