Browse Source

全部完成

st 2 months ago
parent
commit
e0e1baa79f

+ 1 - 1
.env.development

@@ -3,7 +3,7 @@
 VITE_API_PREFIX = '/web'
 
 # 接口地址
-VITE_API_BASE_URL = 'http://xoyozi9walh9.xiaomiqiu.com/web'
+VITE_API_BASE_URL = 'https://xoyozi9walh9.xiaomiqiu.com/web'
 
 # 接口地址 (WebSocket)
 VITE_API_WS_URL = 'ws://localhost:8000'

+ 3 - 1
src/apis/user/type.ts

@@ -1,6 +1,6 @@
 // user
 export interface UserListResp {
-  id?: number
+  id: number
   tgId?: string
   tgAccount?: string
   firstName?: string
@@ -43,6 +43,8 @@ export interface UserListResp {
 export interface UserQuery {
   userName?: string
   time?: string
+  teamType?: string
+  id?: string
 }
 
 export interface UserPageQuery extends UserQuery, PageQuery {

+ 12 - 0
src/apis/user/userlist.ts

@@ -23,3 +23,15 @@ export function jiangliUpdata(id: number, data: T.JiangliData) {
 export function jiangliDel(id: number) {
   return http.del<any>(`${BASE_URL1}/rules/${id}`)
 }
+
+export function userListUpdata(id: number, data: T.UserListResp) {
+  return http.put<any>(`${BASE_URL}/${id}`, data)
+}
+
+export function userListDisable(id: number) {
+  return http.get<any>(`${BASE_URL}/disable/${id}`)
+}
+
+export function listUserDetailTg(query: T.UserPageQuery) {
+  return http.get<PageRes<T.UserListResp[]>>(`${BASE_URL}/getMyTeamUserList`, query)
+}

+ 23 - 8
src/views/user/userlist/index.vue

@@ -40,26 +40,28 @@
       <template #action="{ record }">
         <a-space>
           <a-link title="详情" @click="onDetail(record)">详情</a-link>
-          <a-link title="一级" @click="onDetail(record)">一级</a-link>
-          <a-link title="二级" @click="onDetail(record)">二级</a-link>
-          <a-link title="空投" @click="onDetail(record)">空投</a-link>
-          <a-link title="空投" @click="onDetail(record)">禁用</a-link>
+          <a-link title="一级" @click="goDetail('A', record.id)">一级</a-link>
+          <a-link title="二级" @click="goDetail('B', record.id)">二级</a-link>
+          <a-link title="禁用" @click="onDisable(record)">禁用</a-link>
           <!--          <a-link v-permission="['system:notice:update']" title="修改" @click="onUpdate(record)">修改</a-link> -->
           <!--          <a-link v-permission="['system:notice:delete']" status="danger" title="删除" @click="onDelete(record)"> 删除 </a-link> -->
         </a-space>
       </template>
     </GiTable>
+    <UserListAddModal ref="UserListAddModalRef" @save-success="search"></UserListAddModal>
   </div>
 </template>
 
 <script setup lang="ts">
+import UserListAddModal from './userlistAddModal.vue'
 import type { TableInstanceColumns } from '@/components/GiTable/type'
 import { useTable } from '@/hooks'
 import { useDict } from '@/hooks/app'
 import { isMobile } from '@/utils'
 import DateRangePicker from '@/components/DateRangePicker/index.vue'
 import type { UserListResp, UserQuery } from '@/apis/user/type'
-import { listUserTg } from '@/apis/user/userlist'
+import { listUserTg, userListDisable } from '@/apis/user/userlist'
+import type { TeamListResp } from '@/apis/team/type'
 
 defineOptions({ name: 'Userlist' })
 
@@ -73,6 +75,7 @@ const {
   loading,
   pagination,
   search,
+  handleDelete,
 } = useTable((page) => listUserTg({ ...queryForm, ...page }), { immediate: true })
 const columns: TableInstanceColumns[] = [
   {
@@ -97,7 +100,7 @@ const columns: TableInstanceColumns[] = [
     title: '操作',
     dataIndex: 'action',
     slotName: 'action',
-    width: 350,
+    width: 200,
     align: 'center',
     fixed: !isMobile() ? 'right' : undefined,
     show: true,
@@ -111,9 +114,21 @@ const reset = () => {
   search()
 }
 
-// 详情
+const UserListAddModalRef = ref<InstanceType<typeof UserListAddModal>>()
 const onDetail = (record: UserListResp) => {
-  router.push({ path: '/system/notice/detail', query: { id: record.id } })
+  UserListAddModalRef.value?.onUpdate(record)
+}
+const onDisable = (record: TeamListResp) => {
+  return handleDelete(() => userListDisable(record.id), {
+    content: `是否禁用该用户`,
+    showModal: true,
+  })
+}
+const goDetail = (type: string, id: number) => {
+  router.push({
+    path: '/user/detail',
+    query: { type, id },
+  })
 }
 </script>
 

+ 97 - 0
src/views/user/userlist/indexDetail.vue

@@ -0,0 +1,97 @@
+<template>
+  <div class="table-page">
+    <GiTable
+      row-key="id"
+      :title="`用户${route.query.type}列表`"
+      :data="dataList"
+      :columns="columns"
+      :loading="loading"
+      :scroll="{ x: '100%', y: '100%', minWidth: 1200 }"
+      :pagination="pagination"
+      :disabled-tools="['size']"
+      :disabled-column-keys="['title']"
+      @refresh="search"
+    >
+      <template #toolbar-left>
+        <a-input-search v-model="queryForm.userName" placeholder="用户昵称" allow-clear @search="search" />
+        <DateRangePicker v-model="queryForm.time" @change="search" />
+        <a-button @click="reset">
+          <template #icon><icon-refresh /></template>
+          <template #default>重置</template>
+        </a-button>
+      </template>
+      <template #toolbar-right>
+        <!--        <a-button v-permission="['system:notice:add']" type="primary" @click="onAdd"> -->
+        <!--          <template #icon><icon-plus /></template> -->
+        <!--          <template #default>新增</template> -->
+        <!--        </a-button> -->
+      </template>
+      <template #avatar="{ record }">
+        <a-avatar v-if="record.avatar">
+          <img :src="record.avatar" />
+        </a-avatar>
+      </template>
+      <template #nickname="{ record }">
+        <span>{{ record.firstName }} {{ record.lastName }}</span>
+      </template>
+      <template #passengerFlowWay="{ record }">
+        <GiCellTag :value="record.passengerFlowWay" :dict="passenger_type" />
+      </template>
+    </GiTable>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { useRoute } from 'vue-router'
+import type { TableInstanceColumns } from '@/components/GiTable/type'
+import { useTable } from '@/hooks'
+import { useDict } from '@/hooks/app'
+import DateRangePicker from '@/components/DateRangePicker/index.vue'
+import type { UserQuery } from '@/apis/user/type'
+import { listUserDetailTg } from '@/apis/user/userlist'
+
+defineOptions({ name: 'Userlist' })
+const route = useRoute()
+const { passenger_type } = useDict('passenger_type')
+
+const queryForm = reactive<UserQuery>({
+  teamType: route.query.type,
+  id: route.query.id,
+} as UserQuery)
+
+const {
+  tableData: dataList,
+  loading,
+  pagination,
+  search,
+} = useTable((page) => listUserDetailTg({ ...queryForm, ...page }), { immediate: true })
+const columns: TableInstanceColumns[] = [
+  {
+    title: '序号',
+    width: 66,
+    align: 'center',
+    render: ({ rowIndex }) => h('span', {}, rowIndex + 1 + (pagination.current - 1) * pagination.pageSize),
+  },
+  { title: 'tgId', dataIndex: 'tgId', slotName: 'tgId', align: 'center', width: 180 },
+  { title: '头像', dataIndex: 'avatar', slotName: 'avatar', align: 'center', width: 180 },
+  { title: '名称', dataIndex: 'nickname', slotName: 'nickname', align: 'center', width: 180 },
+  { title: 'TG账号', dataIndex: 'tgAccount', slotName: 'tgAccount', align: 'center', width: 180 },
+  { title: '钱包地址', dataIndex: 'walletAddress', slotName: 'walletAddress', align: 'center', width: 180 },
+  { title: '推荐人', dataIndex: 'referrerName', slotName: 'referrerName', align: 'center', width: 180 },
+  { title: '年限', dataIndex: 'ageLimit', slotName: 'ageLimit', align: 'center', width: 180 },
+  { title: '客流途径', dataIndex: 'passengerFlowWay', slotName: 'passengerFlowWay', align: 'center', width: 180 },
+  { title: '注册日期', dataIndex: 'createdTime', width: 180 },
+  { title: '在线时间', dataIndex: 'onlineTime', width: 180 },
+  { title: '用户地址', dataIndex: 'ipAddressConvert', width: 180 },
+  { title: 'ip地址', dataIndex: 'loginIp', width: 180 },
+]
+
+// 重置
+const reset = () => {
+  queryForm.userName = undefined
+  queryForm.time = undefined
+  search()
+}
+</script>
+
+<style scoped lang="scss"></style>

+ 99 - 0
src/views/user/userlist/userlistAddModal.vue

@@ -0,0 +1,99 @@
+<template>
+  <a-modal
+    v-model:visible="visible"
+    :title="title"
+    :mask-closable="false"
+    :esc-to-close="false"
+    :width="width >= 500 ? 500 : '100%'"
+    draggable
+    @before-ok="save"
+    @close="reset"
+  >
+    <GiForm ref="formRef" v-model="form" :options="options" :columns="columns">
+    </GiForm>
+  </a-modal>
+</template>
+
+<script setup lang="ts">
+import { Message } from '@arco-design/web-vue'
+import { useWindowSize } from '@vueuse/core'
+import type { Columns, GiForm, Options } from '@/components/GiForm'
+
+import { useResetReactive } from '@/hooks'
+import { teamPost } from '@/apis/team/jiangli'
+import { userListUpdata } from '@/apis/user/userlist'
+import type { UserListResp } from '@/apis/user/type'
+
+const emit = defineEmits<{
+  (e: 'save-success'): void
+}>()
+
+const { width } = useWindowSize()
+
+const dataId = ref()
+const visible = ref(false)
+const isUpdate = computed(() => !!dataId.value)
+const title = computed(() => (isUpdate.value ? '修改用户信息' : '新增用户信息'))
+const formRef = ref<InstanceType<typeof GiForm>>()
+
+const [form, resetForm] = useResetReactive({
+
+})
+const options: Options = {
+  form: { size: 'large' },
+  btns: { hide: true },
+}
+const columns: Columns = reactive([
+  { label: '名', field: 'firstName', type: 'input' },
+  { label: '姓', field: 'lastName', type: 'input' },
+  { label: '钱包地址', field: 'walletAddress', type: 'input' },
+  { label: '空投数量', field: 'airdropCoin', type: 'input' },
+  { label: '金币余额', field: 'goldCoinAmount', type: 'input' },
+  { label: '金币总数量', field: 'goldCoinTotalHis', type: 'input' },
+  { label: '用户余额', field: 'userAmount', type: 'input' },
+])
+
+// 重置
+const reset = () => {
+  formRef.value?.formRef?.resetFields()
+  resetForm()
+}
+
+// 保存
+const save = async () => {
+  try {
+    const isInvalid = await formRef.value?.formRef?.validate()
+    if (isInvalid) return false
+    if (isUpdate.value) {
+      await userListUpdata(dataId.value, form)
+      Message.success('修改成功')
+    } else {
+      await teamPost({ ...form })
+      Message.success('新增成功')
+    }
+    emit('save-success')
+    return true
+  } catch (error) {
+    return false
+  }
+}
+
+// 新增
+const onAdd = () => {
+  reset()
+  dataId.value = null
+  visible.value = true
+}
+
+// 修改
+const onUpdate = async (record: UserListResp) => {
+  reset()
+  dataId.value = record.id
+  Object.assign(form, record)
+  visible.value = true
+}
+
+defineExpose({ onAdd, onUpdate })
+</script>
+
+<style scoped lang="scss"></style>