Ver código fonte

feat: 新增项目列表页过滤查询功能

lanjianrong 4 anos atrás
pai
commit
fb13a048e2

+ 3 - 7
.eslintrc.js

@@ -17,19 +17,15 @@ module.exports = defineConfig({
       jsx: true
     }
   },
-  extends: [
-    'plugin:vue/vue3-recommended',
-    'plugin:@typescript-eslint/recommended',
-    'prettier',
-    'plugin:prettier/recommended'
-  ],
+  extends: ['plugin:vue/vue3-recommended', 'plugin:@typescript-eslint/recommended', 'prettier', 'plugin:prettier/recommended'],
   rules: {
     'prettier/prettier': [
       'error',
       {
         semi: false,
         trailingComma: 'none',
-        arrowParens: 'avoid'
+        arrowParens: 'avoid',
+        printWidth: 180
       }
     ],
     '@typescript-eslint/ban-ts-ignore': 'off',

+ 1 - 1
prettier.config.js

@@ -1,5 +1,5 @@
 module.exports = {
-  printWidth: 100,
+  printWidth: 180,
   tabWidth: 2,
   useTabs: false,
   semi: false,

+ 5 - 5
src/api/sys/menu.ts

@@ -1,8 +1,8 @@
-import { defHttp } from '/@/utils/http/axios';
-import { getMenuListByIdParams, getMenuListByIdParamsResultModel } from './model/menuModel';
+import { defHttp } from '/@/utils/http/axios'
+import { getMenuListByIdParams, getMenuListByIdParamsResultModel } from './model/menuModel'
 
 enum Api {
-  GetMenuListById = '/getMenuListById',
+  GetMenuListById = '/getMenuListById'
 }
 
 /**
@@ -10,5 +10,5 @@ enum Api {
  */
 
 export const getMenuListById = (params: getMenuListByIdParams) => {
-  return defHttp.get<getMenuListByIdParamsResultModel>({ url: Api.GetMenuListById, params });
-};
+  return defHttp.get<getMenuListByIdParamsResultModel>({ url: Api.GetMenuListById, params })
+}

+ 21 - 0
src/api/sys/model/officeModel.ts

@@ -0,0 +1,21 @@
+/**
+ * @description: Request list interface parameters
+ */
+export type OfficeListParams = { categoryId?: string }
+
+export interface OfficeListItem {
+  cid: string
+  defult: string
+  districtid: string
+  title: string
+}
+
+export interface CategoriedStaffItem {
+  id: string
+  name: string
+}
+
+/**
+ * @description: Request list return value
+ */
+export type OfficeListGetResultModel = { category: OfficeListItem[]; staff: CategoriedStaffItem[] }

+ 31 - 0
src/api/sys/model/projectModel.ts

@@ -0,0 +1,31 @@
+import { BasicPageParams, BasicFetchResult } from '/@/api/model/baseModel'
+/**
+ * @description: Request list interface parameters
+ */
+export type ProjectListParams = BasicPageParams & { search?: string; insideCategoryId?: string }
+
+export interface ProjectListItem {
+  id: string
+  code: string
+  name: string
+  userId: string
+  userAccount: string
+  categoryId: string
+  category: string
+  staffId: string
+  staffName: string
+  staffQq: string
+  staffPhone: string
+  staffTelephone: string
+  createTime: string
+  createName: string
+  createCategory: string
+  insideCategoryId: string
+  insideCategory: string
+  remark: string
+}
+
+/**
+ * @description: Request list return value
+ */
+export type ProjectListGetResultModel = BasicFetchResult<ProjectListItem[]>

+ 15 - 0
src/api/sys/office.ts

@@ -0,0 +1,15 @@
+import { defHttp } from '/@/utils/http/axios'
+import { OfficeListGetResultModel, OfficeListParams } from './model/officeModel'
+enum Api {
+  GetOfficeList = '/backstage/project/cld'
+}
+
+/**
+ * @description: 获取办事处已经员工
+ */
+export function getOfficeList(params?: OfficeListParams) {
+  return defHttp.get<OfficeListGetResultModel>({
+    url: Api.GetOfficeList,
+    params
+  })
+}

+ 17 - 0
src/api/sys/project.ts

@@ -0,0 +1,17 @@
+import { defHttp } from '/@/utils/http/axios'
+import { ProjectListGetResultModel, ProjectListParams } from './model/projectModel'
+enum Api {
+  GetProjectList = '/backstage/project/list'
+}
+
+/**
+ * @description: 获取项目列表
+ */
+export function getProjectList(params: ProjectListParams) {
+  // params.insideCategoryId = params['category']
+  // delete params['category']
+  return defHttp.post<ProjectListGetResultModel>({
+    url: Api.GetProjectList,
+    params
+  })
+}

+ 32 - 0
src/enums/statusEnum.ts

@@ -0,0 +1,32 @@
+export enum ProjectStatusEnum {
+  NORMAL = 0, // 正常
+  TEST = 1, // 试用
+  STOP = 2 // 停用
+}
+
+export enum ProjectStatusColorEnum {
+  NORMAL = 'text-green-600', // 正常
+  TEST = 'text-yellow-600', // 试用
+  STOP = 'text-red-600' // 停用
+}
+export enum ProjectStatusTextEnum {
+  NORMAL = '正常', // 正常
+  TEST = '试用', // 试用
+  STOP = '停用' // 停用
+}
+
+export const projectStatusColorMap: Map<ProjectStatusEnum, ProjectStatusColorEnum> = (() => {
+  const map = new Map<ProjectStatusEnum, ProjectStatusColorEnum>()
+  map.set(ProjectStatusEnum.NORMAL, ProjectStatusColorEnum.NORMAL)
+  map.set(ProjectStatusEnum.TEST, ProjectStatusColorEnum.TEST)
+  map.set(ProjectStatusEnum.STOP, ProjectStatusColorEnum.STOP)
+  return map
+})()
+
+export const projectStatusTextMap: Map<ProjectStatusEnum, ProjectStatusTextEnum> = (() => {
+  const map = new Map<ProjectStatusEnum, ProjectStatusTextEnum>()
+  map.set(ProjectStatusEnum.NORMAL, ProjectStatusTextEnum.NORMAL)
+  map.set(ProjectStatusEnum.TEST, ProjectStatusTextEnum.TEST)
+  map.set(ProjectStatusEnum.STOP, ProjectStatusTextEnum.STOP)
+  return map
+})()

+ 53 - 0
src/store/modules/office.ts

@@ -0,0 +1,53 @@
+import { defineStore } from 'pinia'
+import { OfficeListItem, CategoriedStaffItem, OfficeListParams } from '/@/api/sys/model/officeModel'
+import { getOfficeList } from '/@/api/sys/office'
+import { store } from '/@/store'
+
+interface OfficeState {
+  categoryList: OfficeListItem[]
+  staffList: CategoriedStaffItem[]
+}
+export const useOfficeStore = defineStore({
+  id: 'app-office',
+  state: (): OfficeState => ({
+    categoryList: [],
+    staffList: []
+  }),
+  getters: {
+    getCategories(): OfficeListItem[] {
+      return this.categoryList
+    },
+    getCategoriedStaff(): CategoriedStaffItem[] {
+      return this.staffList
+    },
+    getCategoryOptions(): { label: string; value: string }[] {
+      return this.categoryList.map(category => ({
+        value: category.cid,
+        label: category.title
+      }))
+    }
+  },
+  actions: {
+    setCategoryList(category: OfficeListItem[]) {
+      this.categoryList = category
+    },
+    setStaffList(staff: CategoriedStaffItem[]) {
+      this.staffList = staff
+    },
+    // 获取办事处列表
+    async getOfficesAction() {
+      const { category = [] } = await getOfficeList()
+      this.setCategoryList(category)
+    },
+    // 获取办事处对应员工列表
+    async getOfficesWithStaffAction(params: OfficeListParams) {
+      const { staff = [] } = await getOfficeList(params)
+      this.setStaffList(staff)
+    }
+  }
+})
+
+// Need to be used outside the setup
+export function useOfficeStoreWidthOut() {
+  return useOfficeStore(store)
+}

+ 41 - 0
src/views/dashboard/tableData.tsx

@@ -0,0 +1,41 @@
+import { BasicColumn } from '/@/components/Table/src/types/table'
+import { projectStatusColorMap, projectStatusTextMap } from '/@/enums/statusEnum'
+console.log(projectStatusColorMap.get(0))
+
+export function getProjectTableColumns(): BasicColumn[] {
+  return [
+    {
+      title: '项目编号',
+      dataIndex: 'code',
+      width: 100
+    },
+    {
+      title: '项目名称',
+      dataIndex: 'name'
+    },
+    {
+      title: '办事处',
+      dataIndex: 'category',
+      width: 200,
+      slots: { filterDropdown: 'filterDropdown' },
+      filterMultiple: false
+    },
+    {
+      title: '负责人',
+      dataIndex: 'staffName',
+      width: 100
+    },
+    {
+      title: '创建时间',
+      dataIndex: 'createTime',
+      width: 200
+      // sorter: true
+    },
+    {
+      title: '状态',
+      dataIndex: 'status',
+      width: 100,
+      customRender: ({ text }) => <span class={projectStatusColorMap.get(text)}>{projectStatusTextMap.get(text)}</span>
+    }
+  ]
+}

+ 54 - 42
src/views/dashboard/workbench/index.vue

@@ -1,54 +1,66 @@
 <template>
   <PageWrapper>
-    <template #headerContent> <WorkbenchHeader /> </template>
-    <div class="lg:flex">
-      <div class="lg:w-7/10 w-full !mr-4 enter-y">
-        <ProjectCard :loading="loading" class="enter-y" />
-        <DynamicInfo :loading="loading" class="!my-4 enter-y" />
-      </div>
-      <div class="lg:w-3/10 w-full enter-y">
-        <QuickNav :loading="loading" class="enter-y" />
-
-        <Card class="!my-4 enter-y" :loading="loading">
-          <img class="xl:h-50 h-30 mx-auto" src="../../../assets/svg/illustration.svg" />
-        </Card>
-
-        <SaleRadar :loading="loading" class="enter-y" />
-      </div>
-    </div>
+    <BasicTable @register="registerTable">
+      <template #toolbar>
+        <span class="w-1/5">
+          <Search @search="value => handleSearch('search', value)" placeholder="项目名称/项目编号" />
+        </span>
+      </template>
+      <template #filterDropdown="{ setSelectedKeys, selectedKeys, confirm, clearFilters }">
+        <div class="p-3">
+          <a-select :options="options" placeholder="按办事处筛选" @select="value => setSelectedKeys([value])" style="width: 180px" allowClear />
+        </div>
+        <div class="pb-3 justify-center flex">
+          <a-button size="small" @click="() => handleSearch('insideCategoryId', selectedKeys[0], confirm)" class="mr-3">确定</a-button>
+          <a-button size="small" @click="() => clearFilters()">重置</a-button>
+        </div>
+      </template>
+    </BasicTable>
   </PageWrapper>
 </template>
 <script lang="ts">
-  import { defineComponent, ref } from 'vue';
-
-  import { Card } from 'ant-design-vue';
-  import { PageWrapper } from '/@/components/Page';
-  import WorkbenchHeader from './components/WorkbenchHeader.vue';
-  import ProjectCard from './components/ProjectCard.vue';
-  import QuickNav from './components/QuickNav.vue';
-  import DynamicInfo from './components/DynamicInfo.vue';
-  import SaleRadar from './components/SaleRadar.vue';
-
+  import { computed, defineComponent } from 'vue'
+  import { BasicTable, useTable } from '/@/components/Table'
+  import { PageWrapper } from '/@/components/Page'
+  import { getProjectList } from '/@/api/sys/project'
+  import { Input, Select } from 'ant-design-vue'
+  import { getProjectTableColumns } from '../tableData'
+  import { useOfficeStore } from '/@/store/modules/office'
+  import { ProjectListItem, ProjectListParams } from '/@/api/sys/model/projectModel'
   export default defineComponent({
     components: {
       PageWrapper,
-      WorkbenchHeader,
-      ProjectCard,
-      QuickNav,
-      DynamicInfo,
-      SaleRadar,
-      Card,
+      BasicTable,
+      Search: Input.Search,
+      ASelect: Select
     },
     setup() {
-      const loading = ref(true);
-
-      setTimeout(() => {
-        loading.value = false;
-      }, 1500);
+      const officeStore = useOfficeStore()
+      const options = computed(() => officeStore.getCategoryOptions)
+      async function checkOffice() {
+        if (!officeStore.getOfficesAction.length) {
+          await officeStore.getOfficesAction()
+        }
+      }
+      const [registerTable, { setTableData }] = useTable({
+        canResize: true,
+        title: '项目列表',
+        rowKey: 'id',
+        api: getProjectList,
+        columns: getProjectTableColumns(),
+        showTableSetting: true
+      })
 
-      return {
-        loading,
-      };
-    },
-  });
+      checkOffice()
+      async function handleSearch(key: keyof ProjectListParams, value: string, fn?: Fn) {
+        if (fn) {
+          fn()
+        } else {
+          const tableData = await getProjectList({ page: 1, pageSize: 10, [key]: value })
+          setTableData<ProjectListItem>(tableData.items)
+        }
+      }
+      return { registerTable, options, handleSearch }
+    }
+  })
 </script>