index.vue 4.01 KB
<script lang="ts" setup>
import { onMounted, reactive, ref } from 'vue';

import { Page } from '@vben/common-ui';

import {
  ElButton,
  ElCard,
  ElForm,
  ElFormItem,
  ElInput,
  ElOption,
  ElPagination,
  ElSelect,
  ElTable,
  ElTag,
} from 'element-plus';

import { listCustomersApi } from '#/api';

const loading = ref(false);
const table_data = ref<any[]>([]);
const total = ref(0);

const query_form = reactive({
  keyword: '',
  page: 1,
  pageSize: 10,
  status: '' as '' | 'active' | 'disabled',
});

const fetch_list = async () => {
  loading.value = true;
  try {
    const data = await listCustomersApi({
      keyword: query_form.keyword || undefined,
      page: query_form.page,
      pageSize: query_form.pageSize,
      status: query_form.status || undefined,
    });
    table_data.value = data.items;
    total.value = data.total;
  } finally {
    loading.value = false;
  }
};

const handle_search = async () => {
  query_form.page = 1;
  await fetch_list();
};

const handle_reset = async () => {
  query_form.keyword = '';
  query_form.status = '';
  query_form.page = 1;
  await fetch_list();
};

const handle_page_change = async (page: number) => {
  query_form.page = page;
  await fetch_list();
};

const handle_page_size_change = async (page_size: number) => {
  query_form.pageSize = page_size;
  query_form.page = 1;
  await fetch_list();
};

onMounted(fetch_list);
</script>

<template>
  <Page
    title="客户列表(示例)"
    description="一个最小可运行的业务模块示例:路由 + 页面 + API + mock 接口"
  >
    <div class="flex flex-col gap-4">
      <ElCard shadow="never">
        <ElForm class="flex flex-wrap gap-x-4" inline>
          <ElFormItem label="关键词">
            <ElInput
              v-model="query_form.keyword"
              clearable
              placeholder="姓名/手机号"
              style="width: 220px"
              @keyup.enter="handle_search"
            />
          </ElFormItem>
          <ElFormItem label="状态">
            <ElSelect
              v-model="query_form.status"
              clearable
              placeholder="全部"
              style="width: 160px"
            >
              <ElOption label="启用" value="active" />
              <ElOption label="禁用" value="disabled" />
            </ElSelect>
          </ElFormItem>

          <ElFormItem>
            <div class="flex items-center gap-2">
              <ElButton
                type="primary"
                :loading="loading"
                @click="handle_search"
              >
                查询
              </ElButton>
              <ElButton :disabled="loading" @click="handle_reset">
                重置
              </ElButton>
            </div>
          </ElFormItem>
        </ElForm>
      </ElCard>

      <ElCard shadow="never">
        <ElTable :data="table_data" v-loading="loading" stripe>
          <ElTable.TableColumn label="客户ID" prop="id" min-width="220" />
          <ElTable.TableColumn label="姓名" prop="name" min-width="140" />
          <ElTable.TableColumn label="手机号" prop="phone" min-width="140" />
          <ElTable.TableColumn
            label="创建时间"
            prop="createdAt"
            min-width="180"
          />
          <ElTable.TableColumn label="状态" min-width="100">
            <template #default="{ row }">
              <ElTag :type="row.status === 'active' ? 'success' : 'info'">
                {{ row.status === 'active' ? '启用' : '禁用' }}
              </ElTag>
            </template>
          </ElTable.TableColumn>
        </ElTable>

        <div class="mt-4 flex justify-end">
          <ElPagination
            :current-page="query_form.page"
            :page-size="query_form.pageSize"
            :page-sizes="[10, 20, 50, 100]"
            :total="total"
            layout="total, sizes, prev, pager, next, jumper"
            @update:current-page="handle_page_change"
            @update:page-size="handle_page_size_change"
          />
        </div>
      </ElCard>
    </div>
  </Page>
</template>