Ver código fonte

feat: 布兰德

IlhamTahir 8 meses atrás
pai
commit
90fc98fa6a

+ 7 - 2
src/api/httpClient.ts

@@ -9,8 +9,13 @@ const client: AxiosInstance = axios.create({
 })
 
 const handleError = (errorResponse: ErrorResponse) => {
-  
-  MessagePlugin.error(errorResponse.message)
+  if (errorResponse.code === 401) {
+    useAppStore().logout()
+    MessagePlugin.error('登录信息失效,请重新登录')
+  } else {
+    MessagePlugin.error(errorResponse.message)
+
+  }
 }
 client.interceptors.response.use(
   (response) => {

+ 22 - 0
src/api/petVariety.ts

@@ -0,0 +1,22 @@
+import httpClient from '@/api/httpClient'
+import type { PageResult } from '@/model/base'
+import type { PetVariety, SearchPetVarietyFilter } from '@/model/pet-variety'
+
+export const searchPetVarieties = async (searchPetVarietyFilter: SearchPetVarietyFilter) => {
+  return httpClient.get<PageResult<PetVariety>>('/pet-varieties', searchPetVarietyFilter)
+}
+
+
+export const createPetVariety = async (name: string) => {
+  return httpClient.post<PetVariety>('/pet-varieties', { name })
+}
+
+
+export const editPetVariety = async (id: string, name: string) => {
+  return httpClient.put<PetVariety>(`/pet-varieties/${id}`, { name })
+}
+
+
+export const deletePetVariety = async (id: string) => {
+  return httpClient.delete(`/pet-varieties/${id}`)
+}

+ 7 - 0
src/model/pet-variety.ts

@@ -0,0 +1,7 @@
+import type { BaseFilterRequest, BaseModel } from '@/model/base'
+
+export interface PetVariety extends BaseModel{
+  name: string
+}
+
+export interface SearchPetVarietyFilter extends BaseFilterRequest {}

+ 72 - 0
src/pages/pet-variety/components/PetVarietyDialog.vue

@@ -0,0 +1,72 @@
+<script setup lang="ts">
+import { type CreateProductRequest, type Product } from '@/model/product'
+import { type FormInstanceFunctions, type FormRules, MessagePlugin } from 'tdesign-vue-next'
+import { createPetVariety, editPetVariety } from '@/api/petVariety'
+
+const props = defineProps<{
+  data: Product | null
+}>()
+
+
+
+const formData = ref<{
+  name: string
+}>({
+  name: ''
+})
+
+
+
+watch(
+  () => props.data,
+  (newData) => {
+    if (newData) {
+      formData.value = newData
+    }
+  }
+)
+
+const rules: FormRules<CreateProductRequest> = {
+  name: [
+    {
+      required: true,
+      message: '品种名称不能为空'
+    }
+  ],
+
+}
+
+const formRef = ref<FormInstanceFunctions | null>(null)
+const emits = defineEmits<{
+  success: [void]
+}>()
+
+const editId = computed(() => props.data?.id)
+const handleSave = async () => {
+  const validate = await formRef.value?.validate()
+
+  if (validate !== true) return
+
+  try {
+    editId.value
+      ? await editPetVariety(editId.value, formData.value.name)
+      : await createPetVariety(formData.value.name)
+    await MessagePlugin.success(`${editId.value ? '编辑' : '创建'}成功`)
+    emits('success')
+  } finally {
+    formRef.value?.reset()
+  }
+}
+</script>
+
+<template>
+  <TDialog @confirm="handleSave">
+    <TForm ref="formRef" :data="formData" :rules="rules" resetType="initial">
+      <TFormItem label="宠物品种名称" name="name">
+        <TInput v-model.trim="formData.name" clearable placeholder="请输入宠物品种名称" />
+      </TFormItem>
+    </TForm>
+  </TDialog>
+</template>
+
+<style scoped></style>

+ 118 - 0
src/pages/pet-variety/index.vue

@@ -0,0 +1,118 @@
+<script setup lang="ts">
+import { onMounted } from 'vue'
+import RegularPage from '@/components/RegularPage.vue'
+
+import { type BaseTableColumns, MessagePlugin } from 'tdesign-vue-next'
+import { useSearchable } from '@/composables/useSearchable'
+import { deleteProduct } from '@/api/product'
+import type { Product } from '@/model/product'
+import ProductDialog from '@/pages/product/components/ProductDialog.vue'
+import ImagePreviewer from '@/components/ImagePreviewer.vue'
+import type { PetVariety, SearchPetVarietyFilter } from '@/model/pet-variety'
+import { deletePetVariety, searchPetVarieties } from '@/api/petVariety'
+import PetVarietyDialog from '@/pages/pet-variety/components/PetVarietyDialog.vue'
+const { data, loading, pagination, onPageChange, fetchData } = useSearchable<
+  SearchPetVarietyFilter,
+  PetVariety
+>(searchPetVarieties)
+
+const columns: BaseTableColumns = [
+  {
+    title: '品种名称',
+    colKey: 'name',
+  },
+  {
+    title: '创建时间',
+    colKey: 'createdTime',
+  },
+  {
+    title: '操作',
+    colKey: 'operation',
+  }
+]
+
+
+onMounted(fetchData)
+
+
+const productDialogVisible = ref(false)
+
+const editData = ref<PetVariety | null>(null)
+
+const handleEdit = (data: PetVariety) => {
+  editData.value = data
+  productDialogVisible.value = true
+}
+
+
+const handleDelete = async (id: string) => {
+  loading.value = true
+  try {
+    await deletePetVariety(id)
+    await fetchData()
+    await MessagePlugin.success('删除成功')
+  } catch (e) {
+    await MessagePlugin.error('删除失败')
+  }finally {
+    loading.value = false
+  }
+}
+
+
+const handleSuccess = async () => {
+  await fetchData()
+  productDialogVisible.value = false
+  editData.value = null
+}
+
+const handleClose = () => {
+  editData.value = null
+}
+
+</script>
+
+<template>
+  <RegularPage title="宠物品种">
+    <template #right-area>
+      <TButton @click="productDialogVisible = true">添加品种</TButton>
+    </template>
+    <TTable
+      class="w-full h-full"
+      row-key="id"
+      height="92%"
+      table-layout="auto"
+      :data="data"
+      :loading="loading"
+      :columns="columns"
+      cell-empty-content="-"
+      :paginationAffixedBottom="true"
+      :pagination="{
+        total: pagination.total,
+        current: pagination.page,
+        pageSize: pagination.size,
+        onChange: onPageChange
+      }"
+    >
+
+      <template #operation="{ row }">
+        <TSpace :size="1">
+          <TButton variant="text" size="small" theme="primary" @click="() => handleEdit(row)"
+          >编辑</TButton
+          >
+          <t-popconfirm
+            theme="default"
+            content="确定删除此品种吗?"
+            @confirm="() => handleDelete(row.id)"
+          >
+            <TButton variant="text" size="small" theme="danger">删除</TButton>
+          </t-popconfirm>
+        </TSpace>
+      </template>
+    </TTable>
+    <PetVarietyDialog v-model:visible="productDialogVisible" :data="editData" @success="handleSuccess" @close="handleClose"></PetVarietyDialog>
+  </RegularPage>
+</template>
+
+<style scoped>
+
+</style>

+ 9 - 0
src/router/index.ts

@@ -40,6 +40,15 @@ export const asyncRoutes: RouteRecordRaw[] = [
       icon: 'shop'
     },
     component: () => import('@/pages/product/index.vue')
+  },
+  {
+    name: 'pet-variety',
+    path: 'pet-variety',
+    meta: {
+      title: '宠物品种',
+      icon: 'cat'
+    },
+    component: () => import('@/pages/pet-variety/index.vue')
   }
 ]