user-table.vue 4.14 KB
<script setup lang="ts">
  import FilterSearch from '@/components/filter/search.vue';
  import FilterSearchItem from '@/components/filter/search-item.vue';
  import FilterTable from '@/components/filter/table.vue';
  import FilterTableColumn from '@/components/filter/table-column.vue';
  import EnumTableColumn from '@/components/filter/enum-table-column.vue';
  import UserTableColumn from '@/components/filter/user-table-column.vue';
  import PhoneTableColumn from '@/components/filter/phone-table-column.vue';
  import { Card, Input, Select, Link } from '@arco-design/web-vue';

  import useUserApi from '@/http/user';
  import useLoading from '@/hooks/loading';
  import { AnyObject, Option } from '@/types/global';
  import { onMounted, ref } from 'vue';
  import useTagApi from '@/http/Tag';
  import { User } from '@/utils/model';

  const props = defineProps<{ selectKey: number }>();
  const emits = defineEmits<{ (e: 'onChange', value: { link_id: number; link_name: string }): void }>();

  const { get } = useUserApi;
  const { loading, setLoading } = useLoading(false);
  const { sexOption, officialStatusOption } = useUserApi;

  const filter = ref({ nick_name: '', email_like: '', phone_like: '', authIds: [], status: 1, setWith: ['authTags:id,name'] });
  const tableRef = ref();
  const authTagOptions = ref<Option[]>([]);

  const onQuery = async (params: AnyObject) => {
    setLoading(true);
    return get({ ...filter.value, ...params }).finally(() => setLoading(false));
  };

  const onSearch = () => tableRef.value?.onPageChange(1);

  const onReset = () => {
    filter.value = { nick_name: '', email_like: '', phone_like: '', authIds: [], status: 1, setWith: ['authTags:id,name'] };
    onSearch();
  };

  onMounted(() => {
    onReset();
    useTagApi.getOption({ type: 4 }).then((data) => (authTagOptions.value = data));
  });

  const onClick = (record: User) => {
    emits('onChange', record.id === props.selectKey ? { link_id: 0, link_name: '' } : { link_id: record.id, link_name: record.nick_name });
  };
</script>

<template>
  <Card :bordered="false">
    <FilterSearch :loading="loading" :model="filter" :inline="true" :split="4" @search="onSearch" @reset="onReset">
      <FilterSearchItem label="用户艺名">
        <Input v-model="filter.nick_name" placeholder="请输入" />
      </FilterSearchItem>
      <FilterSearchItem label="用户邮箱">
        <Input v-model="filter.email_like" placeholder="请输入" />
      </FilterSearchItem>
      <FilterSearchItem label="手机号码">
        <Input v-model="filter.phone_like" placeholder="请输入" />
      </FilterSearchItem>
      <FilterSearchItem label="认证能力">
        <Select
          v-model="filter.authIds"
          placeholder="请选择"
          :options="authTagOptions"
          :max-tag-count="2"
          multiple
          allow-clear
          allow-search
        />
      </FilterSearchItem>
    </FilterSearch>
    <FilterTable ref="tableRef" :loading="loading" :on-query="onQuery" :page-size="10">
      <UserTableColumn title="用户艺名" data-index="id" :width="260" show-avatar />
      <EnumTableColumn title="性别" data-index="sex" :option="sexOption" :dark-value="0" :width="100" />
      <FilterTableColumn title="用户邮箱" data-index="email" :width="260" />
      <PhoneTableColumn title="手机号码" data-index="phone" area-index="area_code" :width="260" />
      <FilterTableColumn title="认证能力">
        <template #default="{ record }: { record: User }">
          <span v-if="record.auth_tags?.length">{{ record.auth_tags?.map((item) => item.name).join('|') }}</span>
          <span v-else style="color: rgba(44, 44, 44, 0.5)"></span>
        </template>
      </FilterTableColumn>
      <EnumTableColumn title="关注服务号" data-index="official_status" :option="officialStatusOption" :dark-value="0" :width="160" />
      <FilterTableColumn title="操作" :width="100">
        <template #default="{ record }: { record: User }">
          <Link @click="onClick(record)">{{ record.id !== selectKey ? '选择' : '取消选择' }}</Link>
        </template>
      </FilterTableColumn>
    </FilterTable>
  </Card>
</template>

<style scoped lang="less"></style>