Sfoglia il codice sorgente

!26 用elemen plus重写公告通知模块
Merge pull request !26 from babylazsss/master

芋道源码 2 anni fa
parent
commit
42421f509f

+ 1 - 1
src/api/system/notice/index.ts

@@ -1,7 +1,7 @@
 import request from '@/config/axios'
 
 export interface NoticeVO {
-  id: number
+  id: number | undefined
   title: string
   type: number
   content: string

+ 8 - 3
src/components/Icon/src/IconSelect.vue

@@ -45,17 +45,22 @@ const tabsList = [
 const pageList = computed(() => {
   if (currentPage.value === 1) {
     return copyIconList[currentActiveType.value]
-      .filter((v) => v.includes(filterValue.value))
+      ?.filter((v) => v.includes(filterValue.value))
       .slice(currentPage.value - 1, pageSize.value)
   } else {
     return copyIconList[currentActiveType.value]
-      .filter((v) => v.includes(filterValue.value))
+      ?.filter((v) => v.includes(filterValue.value))
       .slice(
         pageSize.value * (currentPage.value - 1),
         pageSize.value * (currentPage.value - 1) + pageSize.value
       )
   }
 })
+const iconCount = computed(() => {
+  return copyIconList[currentActiveType.value] == undefined
+    ? 0
+    : copyIconList[currentActiveType.value].length
+})
 
 const iconItemStyle = computed((): ParameterCSSProperties => {
   return (item) => {
@@ -159,7 +164,7 @@ watch(
 
           <ElPagination
             small
-            :total="copyIconList[currentActiveType].length as unknown as number"
+            :total="iconCount"
             :page-size="pageSize"
             :current-page="currentPage"
             background

+ 131 - 0
src/views/system/notice/form.vue

@@ -0,0 +1,131 @@
+<template>
+  <Dialog :title="modelTitle" v-model="modelVisible">
+    <el-form
+      ref="formRef"
+      :model="formData"
+      :rules="formRules"
+      label-width="80px"
+      v-loading="formLoading"
+    >
+      <el-form-item label="公告标题" prop="title">
+        <el-input v-model="formData.title" placeholder="请输入公告标题" />
+      </el-form-item>
+      <el-form-item label="公告内容" prop="content">
+        <el-input v-model="formData.content" type="textarea" placeholder="请输公告内容" />
+      </el-form-item>
+      <el-form-item label="公告类型" prop="type">
+        <el-select v-model="formData.type" placeholder="请选择公告类型" clearable>
+          <el-option
+            v-for="dict in getDictOptions(DICT_TYPE.SYSTEM_NOTICE_TYPE)"
+            :key="parseInt(dict.value)"
+            :label="dict.label"
+            :value="parseInt(dict.value)"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-select v-model="formData.status" placeholder="请选择状态" clearable>
+          <el-option
+            v-for="dict in getDictOptions(DICT_TYPE.COMMON_STATUS)"
+            :key="parseInt(dict.value)"
+            :label="dict.label"
+            :value="parseInt(dict.value)"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="备注" prop="remark">
+        <el-input v-model="formData.remark" type="textarea" placeholder="请输备注" />
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
+        <el-button @click="modelVisible = false">取 消</el-button>
+      </div>
+    </template>
+  </Dialog>
+</template>
+<script setup lang="ts">
+import { DICT_TYPE, getDictOptions } from '@/utils/dict'
+import * as NoticeApi from '@/api/system/notice'
+
+const { t } = useI18n() // 国际化
+const message = useMessage() // 消息弹窗
+
+const modelVisible = ref(false) // 弹窗的是否展示
+const modelTitle = ref('') // 弹窗的标题
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const formType = ref('') // 表单的类型:create - 新增;update - 修改
+const formData = ref({
+  id: undefined,
+  title: '',
+  type: undefined,
+  content: '',
+  status: undefined,
+  remark: ''
+})
+const formRules = reactive({
+  title: [{ required: true, message: '公告标题不能为空', trigger: 'blur' }],
+  type: [{ required: true, message: '公告类型不能为空', trigger: 'change' }],
+  status: [{ required: true, message: '状态不能为空', trigger: 'change' }],
+  content: [{ required: true, message: '公告内容不能为空', trigger: 'blur' }]
+})
+const formRef = ref() // 表单 Ref
+
+/** 打开弹窗 */
+const openModal = async (type: string, id?: number) => {
+  modelVisible.value = true
+  modelTitle.value = t('action.' + type)
+  formType.value = type
+  resetForm()
+  // 修改时,设置数据
+  if (id) {
+    formLoading.value = true
+    try {
+      formData.value = await NoticeApi.getNoticeApi(id)
+    } finally {
+      formLoading.value = false
+    }
+  }
+}
+defineExpose({ openModal }) // 提供 openModal 方法,用于打开弹窗
+
+/** 提交表单 */
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const submitForm = async () => {
+  // 校验表单
+  if (!formRef) return
+  const valid = await formRef.value.validate()
+  if (!valid) return
+  // 提交请求
+  formLoading.value = true
+  try {
+    const data = formData.value as unknown as NoticeApi.NoticeVO
+    if (formType.value === 'create') {
+      await NoticeApi.createNoticeApi(data)
+      message.success(t('common.createSuccess'))
+    } else {
+      await NoticeApi.updateNoticeApi(data)
+      message.success(t('common.updateSuccess'))
+    }
+    modelVisible.value = false
+    // 发送操作成功的事件
+    emit('success')
+  } finally {
+    formLoading.value = false
+  }
+}
+
+/** 重置表单 */
+const resetForm = () => {
+  formData.value = {
+    id: undefined,
+    title: '',
+    type: undefined,
+    content: '',
+    status: undefined,
+    remark: ''
+  }
+  formRef.value?.resetFields()
+}
+</script>

+ 143 - 123
src/views/system/notice/index.vue

@@ -1,150 +1,170 @@
 <template>
-  <ContentWrap>
-    <el-form ref="searchForm" :model="queryParms" :inline="true">
-      <el-form-item label="公告标题">
-        <el-input v-model="queryParms.title" />
+  <content-wrap>
+    <!-- 搜索工作栏 -->
+    <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+      <el-form-item label="公告标题" prop="title">
+        <el-input
+          v-model="queryParams.title"
+          placeholder="请输入公告标题"
+          clearable
+          @keyup.enter="handleQuery"
+        />
       </el-form-item>
-      <el-form-item label="状态">
-        <el-select v-model="queryParms.status">
-          <el-option label="全部" value="" />
-          <el-option label="开启" :value="1" />
-          <el-option label="关闭" :value="0" />
+      <el-form-item label="公告类型" prop="type">
+        <el-select v-model="queryParams.type" placeholder="请选择公告类型" clearable>
+          <el-option
+            v-for="dict in getDictOptions(DICT_TYPE.SYSTEM_NOTICE_TYPE)"
+            :key="parseInt(dict.value)"
+            :label="dict.label"
+            :value="parseInt(dict.value)"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-select v-model="queryParams.type" placeholder="请选择状态" clearable>
+          <el-option
+            v-for="dict in getDictOptions(DICT_TYPE.COMMON_STATUS)"
+            :key="parseInt(dict.value)"
+            :label="dict.label"
+            :value="parseInt(dict.value)"
+          />
         </el-select>
       </el-form-item>
+
       <el-form-item>
-        <el-button type="primary" @click="getList">Query</el-button>
+        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+        <el-button
+          type="primary"
+          @click="openModal('create')"
+          v-hasPermi="['system:notice:create']"
+        >
+          <Icon icon="ep:plus" class="mr-5px" /> 新增
+        </el-button>
       </el-form-item>
     </el-form>
-    <div style="width: 100%; height: 600px">
-      <el-auto-resizer>
-        <template #default="{ height, width }">
-          <el-table-v2
-            :columns="columns"
-            :data="tableData"
-            :width="width"
-            :height="height - 50"
-            fixed
-          />
+    <!-- 列表 -->
+    <el-table v-loading="loading" :data="list" align="center">
+      <el-table-column label="公告主键" align="center" prop="id" />
+      <el-table-column label="公告标题" align="center" prop="title" />
+      <el-table-column label="公告类型" align="center" prop="type">
+        <template #default="scope">
+          <dict-tag :type="DICT_TYPE.SYSTEM_NOTICE_TYPE" :value="scope.row.type" />
         </template>
-      </el-auto-resizer>
-    </div>
-    <div class="mt-2">
-      <el-pagination
-        :current-page="queryParms.pageNo"
-        :page-size="queryParms.pageSize"
-        :page-sizes="[10, 20, 30, 50, 100]"
-        layout="total, sizes, prev, pager, next, jumper"
-        :total="tableTotal"
-        @size-change="getList"
-        @current-change="getList"
+      </el-table-column>
+      <el-table-column label="状态" align="center" prop="status">
+        <template #default="scope">
+          <dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="公告内容"
+        align="center"
+        prop="content"
+        :show-overflow-tooltip="true"
+      />
+      <el-table-column
+        label="创建时间"
+        align="center"
+        prop="createTime"
+        width="180"
+        :formatter="dateFormatter"
       />
-    </div>
-  </ContentWrap>
+      <el-table-column label="操作" align="center">
+        <template #default="scope">
+          <el-button
+            link
+            type="primary"
+            @click="openModal('update', scope.row.id)"
+            v-hasPermi="['system:notice:update']"
+          >
+            编辑
+          </el-button>
+          <el-button
+            link
+            type="danger"
+            @click="handleDelete(scope.row.id)"
+            v-hasPermi="['system:notice:delete']"
+          >
+            删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页 -->
+    <Pagination
+      :total="total"
+      v-model:page="queryParams.pageNo"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </content-wrap>
+
+  <NoticeForm ref="modalRef" @success="getList" />
 </template>
 <script setup lang="tsx">
-import dayjs from 'dayjs'
-import { Column, ElPagination, ElTableV2, TableV2FixedDir } from 'element-plus'
+import { DICT_TYPE, getDictOptions } from '@/utils/dict'
+import { dateFormatter } from '@/utils/formatTime'
 import * as NoticeApi from '@/api/system/notice'
-import { XTextButton } from '@/components/XButton'
 import { DictTag } from '@/components/DictTag'
+import NoticeForm from './form.vue'
+const message = useMessage() // 消息弹窗
 const { t } = useI18n() // 国际化
 
-const columns: Column<any>[] = [
-  {
-    key: 'id',
-    dataKey: 'id', //需要渲染当前列的数据字段,如{id:9527,name:'Mike'},则填id
-    title: 'id', //显示在单元格表头的文本
-    width: 80, //当前列的宽度,必须设置
-    fixed: true //是否固定列
-  },
-  {
-    key: 'title',
-    dataKey: 'title',
-    title: '公告标题',
-    width: 180
-  },
-  {
-    key: 'type',
-    dataKey: 'type',
-    title: '公告类型',
-    width: 180,
-    cellRenderer: ({ cellData: type }) => (
-      <DictTag type={DICT_TYPE.SYSTEM_NOTICE_TYPE} value={type}></DictTag>
-    )
-  },
-  {
-    key: 'status',
-    dataKey: 'status',
-    title: t('common.status'),
-    width: 180,
-    cellRenderer: ({ cellData: status }) => (
-      <DictTag type={DICT_TYPE.COMMON_STATUS} value={status}></DictTag>
-    )
-  },
-  {
-    key: 'content',
-    dataKey: 'content',
-    title: '公告内容',
-    width: 400,
-    cellRenderer: ({ cellData: content }) => <span v-html={content}></span>
-  },
-  {
-    key: 'createTime',
-    dataKey: 'createTime',
-    title: t('common.createTime'),
-    width: 180,
-    cellRenderer: ({ cellData: createTime }) => (
-      <>{dayjs(createTime).format('YYYY-MM-DD HH:mm:ss')}</>
-    )
-  },
-  {
-    key: 'actionbtns',
-    dataKey: 'actionbtns', //需要渲染当前列的数据字段,如{id:9527,name:'Mike'},则填id
-    title: '操作', //显示在单元格表头的文本
-    width: 160, //当前列的宽度,必须设置
-    fixed: TableV2FixedDir.RIGHT, //是否固定列
-    align: 'center',
-    cellRenderer: ({ cellData: id }) => (
-      <>
-        <XTextButton
-          preIcon="ep:delete"
-          title={t('action.edit')}
-          onClick={handleUpdate.bind(this, id)}
-        ></XTextButton>
-        <XTextButton
-          preIcon="ep:delete"
-          title={t('action.del')}
-          onClick={handleDelete.bind(this, id)}
-        ></XTextButton>
-      </>
-    )
-  }
-]
-
-const tableData = ref([])
-
-const tableTotal = ref(0)
-
-const queryParms = reactive({
+const loading = ref(true) // 列表的加载中
+const total = ref(0) // 列表的总页数
+const list = ref([]) // 列表的数据
+const queryParams = reactive({
   title: '',
+  type: undefined,
   status: undefined,
   pageNo: 1,
   pageSize: 100
 })
+const queryFormRef = ref() // 搜索的表单
 
+/** 查询公告列表 */
 const getList = async () => {
-  const res = await NoticeApi.getNoticePageApi(queryParms)
-  tableData.value = res.list
-  tableTotal.value = res.total
-}
+  loading.value = true
+  try {
+    const data = await NoticeApi.getNoticePageApi(queryParams)
 
-const handleUpdate = (id) => {
-  console.info(id)
+    list.value = data.list
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
 }
-
-const handleDelete = (id) => {
-  console.info(id)
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.pageNo = 1
+  getList()
+}
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value.resetFields()
+  handleQuery()
+}
+/** 添加/修改操作 */
+const modalRef = ref()
+const openModal = (type: string, id?: number) => {
+  modalRef.value.openModal(type, id)
+}
+/** 删除按钮操作 */
+const handleDelete = async (id: number) => {
+  try {
+    // 删除的二次确认
+    await message.delConfirm()
+    // 发起删除
+    await NoticeApi.deleteNoticeApi(id)
+    message.success(t('common.delSuccess'))
+    // 刷新列表
+    await getList()
+  } catch {}
 }
 
-getList()
+/** 初始化 **/
+onMounted(() => {
+  getList()
+})
 </script>