Bladeren bron

fix: 咨询管理

IlhamTahir 1 jaar geleden
bovenliggende
commit
f2db16447d

+ 2 - 0
components.d.ts

@@ -32,6 +32,8 @@ declare module 'vue' {
     TPopconfirm: typeof import('tdesign-vue-next')['Popconfirm']
     TRadioButton: typeof import('tdesign-vue-next')['RadioButton']
     TRadioGroup: typeof import('tdesign-vue-next')['RadioGroup']
+    TSelect: typeof import('tdesign-vue-next')['Select']
+    TSelectInput: typeof import('tdesign-vue-next')['SelectInput']
     TSpace: typeof import('tdesign-vue-next')['Space']
     TTable: typeof import('tdesign-vue-next')['Table']
     TTag: typeof import('tdesign-vue-next')['Tag']

+ 2 - 2
src/api/category.ts

@@ -2,8 +2,8 @@ import httpClient from '@/api/httpClient'
 import type { PageResult } from '@/model/base'
 import type { Category,CategorySearchFilter, } from '@/model/category'
 
-export const searchCategories = (categoryFilterParam:CategorySearchFilter ) => {
-  return httpClient.get<PageResult<Category>>('/categories',categoryFilterParam)
+export const searchCategories = (categoryFilterParam :CategorySearchFilter ) => {
+  return httpClient.get<PageResult<Category>>('/categories', categoryFilterParam)
 }
 export const searchCategoryListRequest = ( ) => {
   return httpClient.get<Category[]>('/categories/list',)

+ 1 - 0
src/model/category.ts

@@ -10,6 +10,7 @@ export interface Category extends AuditBaseModel{
 
 export interface CategorySearchFilter extends Partial<Paging>{
   order?: string
+  name?: string
 }
 
 

+ 62 - 75
src/pages/article/components/ArticleDialog.vue

@@ -1,88 +1,30 @@
-<template>
-  <t-dialog
-    width="60%"
-    :header="header"
-    :confirmBtn="confirmBtn"
-    :closeOnOverlayClick="false"
-    @close="handleCloseDialog"
-    @confirm="saveArticleData"
-  >
-    <t-space direction="vertical" style="width: 100%">
-      <TForm ref="form" :data="articleData" :rules="rules" resetType="initial">
-        <TFormItem label="咨询标题:" name="title" help="名称长度大于2个汉字,小于120个汉字">
-          <t-input v-model.trim="articleData.title" clearable placeholder="请输入咨询标题" />
-        </TFormItem>
-        <TFormItem label="咨询分类:" name="categoryId">
-          <t-select-input
-            :value="articleData.categoryName"
-            placeholder="请选择咨询分类"
-            :popup-visible="popupVisible"
-            :popup-props="{ overlayInnerStyle: { padding: '6px' } }"
-            clearable
-            allow-input
-            @popup-visible-change="onPopupVisibleChange"
-            @clear="onClear"
-            @input-change="onInputChange"
-          >
-            <template #panel>
-              <ul class="flex flex-col gap-1 p-0">
-                <li
-                  v-for="item in categoryList"
-                  :key="item.id"
-                  class="block rounded-sm cursor-pointer px-2 py-0.5 text-gray-900 transition-colors duration-200 whitespace-nowrap overflow-hidden text-ellipsis hover:bg-gray-200"
-                  @click="() => onOptionClick({ id: item.id, value: item.name })"
-                >
-                  {{ item.name }}
-                </li>
-              </ul>
-            </template>
-            <template #suffixIcon>
-              <chevron-down-icon />
-            </template>
-          </t-select-input>
-        </TFormItem>
-        <TFormItem label="内容:" name="content"> </TFormItem>
-      </TForm>
-    </t-space>
-  </t-dialog>
-</template>
 <script lang="ts" setup>
 import type { Category } from '@/model/category'
 import type { Article } from '@/model/article'
 import { computed, ref, reactive, watch } from 'vue'
-import type { FormInstanceFunctions, FormProps, SelectInputProps } from 'tdesign-vue-next'
+import type {
+  FormInstanceFunctions,
+  FormProps,
+  SelectInputProps,
+  TdSelectProps
+} from 'tdesign-vue-next'
 import { MessagePlugin } from 'tdesign-vue-next'
-import { ChevronDownIcon } from 'tdesign-icons-vue-next'
 import { updateArticlesByIdRequest, createArticlesRequest } from '@/api/article'
+import { searchCategories } from '@/api/category'
 const props = defineProps<{
   isEdit?: Boolean | null
   headerTitle?: String | null
-  article?: Article | {}
+  article: Article | null
   categoryList: Category[] | []
 }>()
 const formRef = ref<FormInstanceFunctions | null>(null)
 const headerText = computed(() => `${props.isEdit ? '编辑' : '创建'}${props.headerTitle || ''}`)
 const confirmBtnText = computed(() => (props.isEdit ? '保存' : '确定'))
-const articleData: FormProps['data'] = reactive({ categoryName: '' })
+const articleData = reactive<{
+  categoryName: string,
+  title: string
+}>({ categoryName: '', title: '' })
 
-const popupVisible = ref(false)
-const onOptionClick = (item: { id: string; value: string }) => {
-  articleData.categoryName = item.value
-  articleData.categoryId = item.id
-  // 选中后立即关闭浮层
-  popupVisible.value = false
-}
-const onClear: SelectInputProps['onClear'] = () => {
-  articleData.categoryId = ''
-  articleData.categoryName = undefined
-}
-const onPopupVisibleChange: SelectInputProps['onPopupVisibleChange'] = (val) => {
-  popupVisible.value = val
-}
-const onInputChange: SelectInputProps['onInputChange'] = (val, context) => {
-  // 过滤功能
-  console.log(val, context)
-}
 const rules: FormProps['rules'] = {
   name: [
     {
@@ -153,8 +95,8 @@ const emit = defineEmits<{
   onInputChange: [void]
 }>()
 const saveArticleData = async () => {
-  if (form.value) {
-    const valid = await form.value.validate()
+  if (formRef.value) {
+    const valid = await formRef.value.validate()
     if (valid && typeof valid === 'boolean') {
       const { title, categoryId, content, id } = articleData
       if (!props.isEdit) {
@@ -170,9 +112,54 @@ const saveArticleData = async () => {
 }
 const handleCloseDialog = () => {
   // 数据&&规则校验结果重置
-  if (form.value) {
-    form.value.reset()
-    form.value.clearValidate()
+  if (formRef.value) {
+    formRef.value.reset()
+    formRef.value.clearValidate()
   }
 }
+
+const categoryOptions = ref<TdSelectProps['options']>([])
+const categoryName = ref('')
+
+const fetchCategories = async () => {
+  const { data } = await searchCategories({ name: categoryName.value })
+  categoryOptions.value = data.map((category) => {
+    return {
+      label: category.name,
+      value: category.id
+    }
+  })
+}
+
+fetchCategories()
+
 </script>
+<template>
+  <t-dialog
+    width="60%"
+    :header="headerText"
+    :confirmBtn="confirmBtnText"
+    :closeOnOverlayClick="false"
+    @close="handleCloseDialog"
+    @confirm="saveArticleData"
+  >
+    <t-space direction="vertical" style="width: 100%">
+      <TForm ref="formRef" :data="articleData" :rules="rules" resetType="initial">
+        <TFormItem label="咨询标题:" name="title" help="名称长度大于2个汉字,小于120个汉字">
+          <t-input v-model.trim="articleData.title" clearable placeholder="请输入咨询标题" />
+        </TFormItem>
+        <TFormItem label="咨询分类:" name="categoryId">
+          <TSelect
+            v-model="categoryName"
+            :options="categoryOptions"
+            placeholder="请选择咨询分类"
+            clearable
+            filterable
+            @search="fetchCategories"
+          />
+        </TFormItem>
+        <TFormItem label="内容:" name="content"> </TFormItem>
+      </TForm>
+    </t-space>
+  </t-dialog>
+</template>

+ 40 - 73
src/pages/category/components/CategoryDialog.vue

@@ -1,33 +1,31 @@
 <template>
-  <t-dialog
+  <TDialog
     width="40%"
     :header="headerText"
     :confirmBtn="confirmBtnText"
     :closeOnOverlayClick="false"
-    @close="handleCloseDialog"
-    @confirm="SaveCategoryData"
+    @close="handleClose"
+    @confirm="handleSave"
   >
-    <t-space direction="vertical" style="width: 100%">
-      <TForm ref="form" :data="categoryData" :rules="rules" resetType="initial">
-        <TFormItem label="分类名称:" name="name" help="名称长度小于5个汉字,大于2个汉字">
-          <t-input v-model.trim="categoryData.name" clearable placeholder="请输入分类名称" />
-        </TFormItem>
-        <TFormItem label="分类编号:" name="code" help="编号由大于4个字符的英文字母组成">
-          <t-input v-model.trim="categoryData.code" clearable placeholder="请输入分类编号" />
-        </TFormItem>
-        <TFormItem label="排序级别:" name="order" help="排序级别由正整数组成">
-          <t-input-number
-            :min="0"
-            name="order"
-            theme="normal"
-            class="!w-full"
-            placeholder="请输入排序级别"
-            v-model.trim="categoryData.order"
-          ></t-input-number>
-        </TFormItem>
-      </TForm>
-    </t-space>
-  </t-dialog>
+    <TForm ref="formRef" :data="categoryData" :rules="rules" resetType="initial">
+      <TFormItem label="分类名称:" name="name" help="名称长度小于5个汉字,大于2个汉字">
+        <t-input v-model.trim="categoryData.name" clearable placeholder="请输入分类名称" />
+      </TFormItem>
+      <TFormItem label="分类编号:" name="code" help="编号由大于4个字符的英文字母组成">
+        <t-input v-model.trim="categoryData.code" clearable placeholder="请输入分类编号" />
+      </TFormItem>
+      <TFormItem label="排序级别:" name="order" help="排序级别由正整数组成">
+        <t-input-number
+          :min="0"
+          name="order"
+          theme="normal"
+          class="!w-full"
+          placeholder="请输入排序级别"
+          v-model.trim="categoryData.order"
+        ></t-input-number>
+      </TFormItem>
+    </TForm>
+  </TDialog>
 </template>
 <script lang="ts" setup>
 import type { Category } from '@/model/category'
@@ -51,16 +49,6 @@ const rules: FormProps['rules'] = {
       type: 'error',
       trigger: 'blur'
     },
-    {
-      required: true,
-      message: '分类名称不能为空',
-      type: 'error',
-      trigger: 'change'
-    },
-    {
-      whitespace: true,
-      message: '分类名称不能为空'
-    },
     {
       min: 4,
       message: '输入汉字长度应在2到5之间',
@@ -81,16 +69,6 @@ const rules: FormProps['rules'] = {
       type: 'error',
       trigger: 'blur'
     },
-    {
-      required: true,
-      message: '分类编号不能为空',
-      type: 'error',
-      trigger: 'change'
-    },
-    {
-      whitespace: true,
-      message: '分类编号不能为空'
-    },
     {
       min: 4,
       message: '输入字符应大于4个字符长度',
@@ -111,16 +89,6 @@ const rules: FormProps['rules'] = {
       type: 'error',
       trigger: 'blur'
     },
-    {
-      required: true,
-      message: '排序级别不能为空',
-      type: 'error',
-      trigger: 'change'
-    },
-    {
-      whitespace: true,
-      message: '排序级别不能为空'
-    },
     {
       pattern: /^[1-9]\d*$/,
       message: '排序级别必须为正整数',
@@ -139,27 +107,26 @@ watch(
 const emit = defineEmits<{
   success: [void]
 }>()
-const SaveCategoryData = async () => {
-  if (form.value) {
-    const valid = await form.value.validate()
-    if (valid && typeof valid === 'boolean') {
-      const { code, name, order, id } = categoryData
-      if (!props.isEdit) {
-        await createCategoryRequest({ code, name, order })
-      } else {
-        await updateCategoryByIdRequest(id, { code, name, order })
-      }
-      MessagePlugin.success(`${props.isEdit ? '编辑' : '创建'}分类成功`)
-      emit('success')
-      return
+const handleSave = async () => {
+  if (!formRef.value) return
+
+  const valid = await formRef.value.validate()
+  if (valid === true) {
+    const { code, name, order, id } = categoryData
+    if (!props.category) {
+      await createCategoryRequest({ code, name, order })
+    } else {
+      await updateCategoryByIdRequest(id, { code, name, order })
     }
+    MessagePlugin.success(`${props.category ? '编辑' : '创建'}分类成功`)
+    emit('success')
   }
 }
-const handleCloseDialog = () => {
-  // 数据&&规则校验结果重置
-  if (form.value) {
-    form.value.reset()
-    form.value.clearValidate()
-  }
+
+const handleClose = () => {
+  if (!formRef.value) return
+
+  formRef.value.reset()
+  formRef.value.clearValidate()
 }
 </script>

+ 1 - 1
src/pages/user/index.vue

@@ -79,7 +79,7 @@ const handleRoleSettingSuccess = () => {
             <TFormItem label="手机号码">
               <TInput placeholder="请输入需要搜索的用户姓名"></TInput>
             </TFormItem>
-          </TCol>
+          </TCol>7
           <TCol :span="3">
             <TFormItem label="手机号码">
               <TInput placeholder="请输入需要搜索的用户姓名"></TInput>