wechatUser.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. <template>
  2. <div class="agent_page adffc">
  3. <div class="ap_title">{{ title }}</div>
  4. <el-form :model="queryParams" ref="queryRef" label-width="118px" style="margin-top: 20px;">
  5. <el-row>
  6. <el-col :span="8" style="padding-right: 20px;">
  7. <el-form-item label="用户昵称/手机号">
  8. <el-input v-model="queryParams.keyword" placeholder="请输入用户昵称/手机号" style="width: 100%;"></el-input>
  9. </el-form-item>
  10. </el-col>
  11. <el-col :span="8" style="padding-right: 20px;">
  12. <el-form-item label="时间周期">
  13. <el-date-picker
  14. v-model="queryParams.startEndTime"
  15. type="datetimerange"
  16. range-separator="至"
  17. start-placeholder="开始时间"
  18. end-placeholder="结束时间">
  19. </el-date-picker>
  20. </el-form-item>
  21. </el-col>
  22. </el-row>
  23. <el-row>
  24. <el-col :span="8" style="padding-right: 20px;">
  25. <el-form-item label="渠道类型">
  26. <el-select v-model="queryParams.channelType" placeholder="请选择渠道类型" clearable style="width: 100%">
  27. <el-option v-for="item in channel_type" :label="item.label" :value="item.value"></el-option>
  28. </el-select>
  29. </el-form-item>
  30. </el-col>
  31. <el-col :span="8" style="padding-right: 20px;">
  32. <el-form-item label="用户标签">
  33. <el-select v-model="queryParams.userBrief" placeholder="请选择用户标签" clearable style="width: 100%">
  34. <el-option v-for="item in user_brief" :label="item.label" :value="item.value"></el-option>
  35. </el-select>
  36. </el-form-item>
  37. </el-col>
  38. <el-col :span="8">
  39. <el-form-item>
  40. <div style="margin-left: -118px;">
  41. <el-button icon="Refresh" @click="resetQuery">重置</el-button>
  42. <el-button type="primary" @click="getList">查询</el-button>
  43. <el-button type="primary" @click="handleGive" v-hasPermi="['core:wechatuser:give']">赠送</el-button>
  44. </div>
  45. </el-form-item>
  46. </el-col>
  47. </el-row>
  48. </el-form>
  49. <el-table :data="dataList" border @selection-change="handleSelectionChange" cell-class-name="vertical-top-cell" v-loading="loading" empty-text="暂无小程序用户" max-height="578px" style="margin-top: 5px;">
  50. <el-table-column
  51. type="selection"
  52. width="55">
  53. </el-table-column>
  54. <el-table-column label="序号" width="50">
  55. <template #default="scope">
  56. {{ scope.$index + 1 }}
  57. </template>
  58. </el-table-column>
  59. <el-table-column label="用户昵称" prop="realName"></el-table-column>
  60. <el-table-column label="用户标签" prop="userBrief">
  61. <template #default="{ row }">{{ user_brief.find(u=>u.value===row.userBrief)?.label||'/' }}</template>
  62. </el-table-column>
  63. <el-table-column label="手机号码" prop="mobile"></el-table-column>
  64. <el-table-column label="注册编号" prop="registerId" width="180"></el-table-column>
  65. <el-table-column label="用户类型" prop="xx">
  66. <template #default="{ row }">{{ typeCfg[row.type] }}</template>
  67. </el-table-column>
  68. <el-table-column label="注册渠道" prop="channelName"></el-table-column>
  69. <el-table-column label="渠道类型" prop="channelType">
  70. <template #default="{ row }">{{ channel_type.find(c=>c.value===row.channelType)?.label }}</template>
  71. </el-table-column>
  72. <el-table-column label="注册时间" prop="createDate"></el-table-column>
  73. <!-- <el-table-column label="最近登录时间" prop="xx"></el-table-column> -->
  74. <el-table-column label="操作" width="150">
  75. <template #default="scope">
  76. <el-button link type="text" size="mini" @click="handleReview(scope.row)">查看</el-button>
  77. <el-button link type="text" size="mini" @click="handleTag(scope.row)">更改标签</el-button>
  78. </template>
  79. </el-table-column>
  80. </el-table>
  81. <el-row style="display: flex;justify-content: center;">
  82. <el-pagination
  83. @size-change="handleSizeChange"
  84. @current-change="handleCurrentChange"
  85. :current-page="queryParams.page"
  86. :page-sizes="[5, 10, 20, 50]"
  87. :page-size="10"
  88. layout="total, sizes, prev, pager, next, jumper"
  89. :total="total"
  90. v-show="total > 0">
  91. </el-pagination>
  92. </el-row>
  93. <el-dialog width="40%" :visible.sync="show" title="更改用户标签" @close="cancel">
  94. <el-form ref="tagRef" :model="tagForm" :rules="tagRules" label-width="100px" style="width: 90%;margin: 0 auto;">
  95. <el-form-item label="用户标签" prop="userBrief">
  96. <el-select v-model="tagForm.userBrief" placeholder="请选择用户标签类型" clearable style="width: 100%;">
  97. <el-option v-for="item in user_brief" :label="item.label" :value="item.value"></el-option>
  98. </el-select>
  99. </el-form-item>
  100. </el-form>
  101. <div class="demo-drawer__footer" style="display: flex;justify-content: end;">
  102. <el-button :loading="buttonLoading" type="primary" @click="submitForm">保 存</el-button>
  103. <el-button @click="cancel" style="margin-right: 5%;">取 消</el-button>
  104. </div>
  105. </el-dialog>
  106. <el-dialog width="30%" :visible.sync="giveShow" title="赠送" @close="cancelGive">
  107. <el-form ref="giveRef" :model="giveForm" :rules="giveRules" label-width="100px" style="width: 90%;margin: 0 auto;">
  108. <el-form-item label="赠送类型" prop="type">
  109. <el-radio-group v-model="giveForm.type">
  110. <el-radio :label="1">个人版</el-radio>
  111. <el-radio :label="2">团队版</el-radio>
  112. </el-radio-group>
  113. </el-form-item>
  114. <el-form-item label="赠送次数" prop="orderCount">
  115. <el-input-number v-model="giveForm.orderCount" :min="1" :max="9999999" label="请输入赠送次数" style="width: 100%;"></el-input-number>
  116. </el-form-item>
  117. </el-form>
  118. <div class="demo-drawer__footer" style="display: flex;justify-content: end;">
  119. <el-button :loading="buttonLoadingGive" type="primary" @click="submitFormGive">保 存</el-button>
  120. <el-button @click="cancelGive" style="margin-right: 5%;">取 消</el-button>
  121. </div>
  122. </el-dialog>
  123. </div>
  124. </template>
  125. <script setup name="">
  126. import { ref, getCurrentInstance, onMounted } from 'vue'
  127. import {
  128. getWechatUserList,updateBrief,saveBatch
  129. } from '@/api/agent/indexTwo.js'
  130. const { proxy } = getCurrentInstance();
  131. const { channel_type,user_brief } = proxy.useDict("channel_type","user_brief");
  132. const title = proxy.$route.meta.title;
  133. const queryParams = ref({
  134. page:1,
  135. limit:10,
  136. channelType:'',
  137. userBrief:'',
  138. keyword:'',
  139. startEndTime:'',
  140. beginTime:'',
  141. endTime:''
  142. })
  143. const typeCfg = ref({
  144. 1:'个人版',
  145. 2:'团队版',
  146. 0:'团队PRO版',
  147. 3:'高级',
  148. 4:'中级',
  149. 5:'初级',
  150. })
  151. const dataList = ref([])
  152. const total = ref(0)
  153. const loading = ref(false)
  154. const show = ref(false)
  155. const buttonLoading = ref(false)
  156. const tagForm = ref({
  157. id:'',
  158. userBrief:''
  159. })
  160. const tagRules = ref({
  161. userBrief:[{ required: true, message: '请选择用户标签', trigger: 'change' }],
  162. })
  163. const multipleSelection = ref([])
  164. const giveRef = ref(null)
  165. const giveShow = ref(false)
  166. const giveForm = ref({
  167. userIds:[],
  168. type:1,
  169. orderCount:1
  170. })
  171. const giveRules = ref({
  172. type:[{ required: true, message: '请选择赠送类型', trigger: 'change' }],
  173. orderCount:[{ required: true, message: '请输入赠送次数', trigger: 'blur' }],
  174. })
  175. const buttonLoadingGive = ref(false)
  176. const handleSelectionChange = (val) => {
  177. multipleSelection.value = val;
  178. }
  179. const resetQuery = () => {
  180. // 重置表单字段
  181. proxy.$refs.queryRef.resetFields();
  182. // 重置查询参数到初始状态
  183. queryParams.value = {
  184. page:1, // 重置页码为1
  185. limit:10, // 重置每页显示数量为10
  186. channelType:'', // 清空渠道类型筛选
  187. keyword:'', // 清空关键字搜索
  188. startEndTime:'', // 清空时间范围选择
  189. beginTime:'', // 清空开始时间
  190. endTime:'' // 清空结束时间
  191. }
  192. // 重新获取数据列表
  193. getList();
  194. }
  195. const handleGive = () => {
  196. if(multipleSelection.value.length === 0) return proxy.$message.warning('请选择需要赠送的用户!')
  197. giveForm.value.userIds = multipleSelection.value.map(item => item.id);
  198. giveShow.value = true;
  199. }
  200. const getList = async () => {
  201. let query = JSON.parse(JSON.stringify(queryParams.value));
  202. if(query.startEndTime && query.startEndTime.length > 0) {
  203. query.beginTime = proxy.parseTime(new Date(query.startEndTime[0]), '{yy}-{mm}-{dd} {hh}:{ii}:{ss}')
  204. query.endTime = proxy.parseTime(new Date(query.startEndTime[1]), '{yy}-{mm}-{dd} {hh}:{ii}:{ss}')
  205. }
  206. loading.value = true;
  207. delete query.startEndTime;
  208. const res = await getWechatUserList(query);
  209. dataList.value = res.data.list;
  210. total.value = res.data.total;
  211. loading.value = false;
  212. }
  213. const handleSizeChange = (e)=>{
  214. queryParams.value.limit = e;
  215. getList();
  216. }
  217. const handleCurrentChange = (e)=>{
  218. queryParams.value.page = e;
  219. getList();
  220. }
  221. const handleReview = (row) => {
  222. proxy.$router.push({
  223. path:'/wechatUserDetail',
  224. query:{
  225. id:row.id
  226. }
  227. })
  228. }
  229. const handleTag = (row) => {
  230. tagForm.value.id = row.id;
  231. tagForm.value.userBrief = row.userBrief;
  232. show.value = true;
  233. }
  234. const reset = () => {
  235. tagForm.value = {
  236. id:'',
  237. userBrief:''
  238. };
  239. proxy.resetForm("tagRef");
  240. }
  241. const submitForm = () => {
  242. proxy.$refs.tagRef.validate((valid) => {
  243. if (valid) {
  244. buttonLoading.value = true;
  245. updateBrief(tagForm.value).then((res)=>{
  246. if(res.code!==0) return proxy.$message.error(res.msg);
  247. buttonLoading.value = false;
  248. show.value = false;
  249. getList();
  250. })
  251. } else {
  252. return false;
  253. }
  254. });
  255. }
  256. const cancel = () => {
  257. show.value = false;
  258. reset();
  259. }
  260. const submitFormGive = () => {
  261. proxy.$refs.giveRef.validate((valid) => {
  262. if (valid) {
  263. buttonLoadingGive.value = true;
  264. saveBatch(giveForm.value).then((res)=>{
  265. if(res.code!==0) return proxy.$message.error(res.msg);
  266. proxy.$message.success('赠送成功!');
  267. buttonLoadingGive.value = false;
  268. giveShow.value = false;
  269. getList();
  270. })
  271. } else {
  272. return false;
  273. }
  274. });
  275. }
  276. const cancelGive = () => {
  277. giveShow.value = false;
  278. giveForm.value = {
  279. userIds:[],
  280. type:1,
  281. orderCount:1
  282. };
  283. proxy.resetForm("giveRef");
  284. }
  285. onMounted(()=>{
  286. getList();
  287. })
  288. </script>
  289. <style scoped lang="scss">
  290. :v-deep .el-dialog__wrapper{
  291. background: rgba(0,0,0,.3) !important;
  292. }
  293. ::v-deep .el-dialog__title{
  294. font-weight: bold !important;
  295. }
  296. ::v-deep .el-dialog{
  297. margin-top: 20vh !important;
  298. }
  299. ::v-deep .el-drawer__header span{
  300. font-weight: bold;
  301. font-size: 16px;
  302. color: #1D2129;
  303. line-height: 22px;
  304. }
  305. .agent_page{
  306. padding: 24px 16px;
  307. }
  308. </style>