Exp 智能协同管理系统-部门管理前端页面开发

一、需求分析

  1. 页面功能

    • 提供部门信息的展示功能,数据以表格形式呈现,包含序号、部门名称、最后操作时间、操作(编辑和删除)列。
    • 用户可通过新增、编辑和删除功能,实现对部门数据的管理。
    • 数据动态加载,支持实时更新,确保部门信息的准确性。
  2. 功能实现细节

    • 部门展示:从后端接口获取所有部门数据并展示在表格中,支持按序号排序。
    • 新增部门:点击"新增部门"按钮后,弹出表单对话框,用户输入新部门名称并保存。
    • 编辑部门:支持选择部门后修改其信息,数据从后端动态加载并回显在表单中。
    • 删除部门:在用户确认删除操作后,调用后端接口删除指定的部门。
    • 表单校验:新增与编辑时,表单需满足字段校验规则(如必填、长度限制等)。
  3. 技术需求

    • 使用 Vue 3 框架进行页面搭建,支持响应式设计。
    • 使用 Element-Plus 组件库构建界面,简化开发流程。

二、代码解读

总体代码:

html 复制代码
<script setup lang="ts">
import { addApi, deleteApi, getInfoApi, queryAllApi, updateApi } from '@/api/dept';
import type { DeptModel, DeptModelArray } from '@/api/model/model';
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus';
import { onMounted, ref } from 'vue';

const deptList = ref<DeptModelArray>([])


const search = async () => {
  const result = await queryAllApi()
  if (result.code) {
    deptList.value = result.data
  }
}

const formLabelWidth = '140px'
const dialogFormVisible = ref<boolean>(false)
const dept = ref<DeptModel>({
  name: '',
})
const formValue = ref<string>('')

onMounted(() => {
  search()
})


// 添加部门逻辑
const addDept = () => {
  dialogFormVisible.value = true
  //清空公用部门数据
  dept.value = { name: '' }
  //清空表单校验
  resetForm(ruleFormRef.value)
  formValue.value = '部门管理'
}


// 添加和编辑部门逻辑,根据id属性是否为空来区分是新增还是编辑
const save = async (formEl: FormInstance | undefined) => {

  //添加表单校验
  if (!formEl) return
  await formEl.validate(async (valid) => {
    if (valid) {
      //根据ID判断执行添加部门还是编辑部
      let result = null
      if (dept.value.id) {
        result = await updateApi(dept.value)
      } else {
        result = await addApi(dept.value)
      }
      if (result.code) {
        dialogFormVisible.value = false
        ElMessage.success('添加成功')
        search()
      } else {
        ElMessage.error(result.msg)
      }
    } else {
      ElMessage.error('请重新输入')
    }
  })


}


// 编辑部门逻辑
const updateDept = async (id: number) => {
  dialogFormVisible.value = true
  //清空公用部门数据
  dept.value = { name: '' }
  //清空表单校验
  resetForm(ruleFormRef.value)
  formValue.value = '编辑部门'

  //查询回显
  const result = await getInfoApi(id)
  if (result.code) {
    dept.value = result.data
  }
}





// 删除部门逻辑
const deleteById = (id: number) => {
  ElMessageBox.confirm(
    '您确定要删除该部门吗 ?',
    '提示',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  )
    .then(
      async () => {
        const result = await deleteApi(id)
        if (result.code) {
          ElMessage({
            type: 'success',
            message: '删除成功',
          })
        } else {
          ElMessage({
            type: 'error',
            message: '删除失败',
          })
        }
        search()
      })
    .catch(() => {
      ElMessage({
        type: 'info',
        message: '取消删除',
      })
    })
}



//表单校验功能

interface RuleForm {
  name: string
}

const ruleFormRef = ref<FormInstance>()//定义表单引用对象--与表单ref属性绑定

const rules = ref<FormRules<RuleForm>>({
  name: [
    { required: true, message: '部门名称为必填项', trigger: 'blur' },
    { min: 2, max: 10, message: '部门名称长度必须在2-10位', trigger: 'blur' },
  ]
})


const resetForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.resetFields()
}



</script>



<!-- 部门表格 -->
<template>
  <h1>部门管理</h1> <br>
  <el-button type="primary" @click="addDept">+ 新增部门</el-button> <br><br>

  <el-table :data="deptList" border style="width: 100%">
    <el-table-column type="index" label="序号" width="100" align="center" />
    <el-table-column prop="name" label="部门名称" width="200" align="center" />
    <el-table-column prop="updateTime" label="最后操作时间" width="250" align="center" />
    <el-table-column label="操作" align="center">
      <template #default="scope">
        <el-button size="small" type="success" @click="updateDept(scope.row.id)">编辑</el-button>
        <el-button size="small" type="danger" @click="deleteById(scope.row.id)">删除</el-button>
      </template>
    </el-table-column>
  </el-table>

  <!-- 新增与编辑部门表单 -->
  <el-dialog v-model="dialogFormVisible" :title=formValue width="500">
    <el-form :model="dept" :rules="rules" ref="ruleFormRef">
      <el-form-item label="部门名称" :label-width="formLabelWidth" prop="name">
        <el-input v-model="dept.name" autocomplete="off" />
      </el-form-item>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        {{ dept }}
        <el-button @click="dialogFormVisible = false">取消</el-button>
        <el-button type="primary" @click="save(ruleFormRef)">确认</el-button>
      </div>
    </template>
  </el-dialog>

</template>

<style scoped></style>

总体异步请求封装:

TypeScript 复制代码
//编写与服务器进行异步交互的代码
import request from '@/utils/request'
import type { DeptModel, ResultModel } from './model/model'

//1. 查询所有部门 ---> 第二个泛型, 指服务器响应的数据类型
export const queryAllApi = () =>  request.get<any, ResultModel>('/depts')

//2. 新增部门 ---> 第二个泛型, 指服务器响应的数据类型
export const addApi = (dept:DeptModel) =>  request.post<any, ResultModel>('/depts', dept)

//3. 根据id查询 ---> 第二个泛型, 指服务器响应的数据类型
export const getInfoApi = (id:number) =>  request.get<any, ResultModel>(`/depts/${id}`)

//4. 修改部门 ---> 第二个泛型, 指服务器响应的数据类型
export const updateApi = (dept:DeptModel) =>  request.put<any, ResultModel>(`/depts`, dept)

//5. 删除部门 ---> 第二个泛型, 指服务器响应的数据类型
export const deleteApi = (id:number) =>  request.delete<any, ResultModel>(`/depts?id=${id}`)

页面初始化与数据加载

定义search方法:

TypeScript 复制代码
const search = async () => {
    const result = await queryAllApi();
    if (result.code) {
        deptList.value = result.data;
    }
};
  • 通过queryAllApi接口从后端获取部门数据,并赋值给响应式变量deptList
  • 判断接口返回值的code是否为成功状态以更新数据。

页面加载时调用:

TypeScript 复制代码
onMounted(() => {
    search();
});

利用 Vue 生命周期的onMounted钩子,在页面加载时自动加载部门数据

新增与编辑功能

弹出表单的初始化

1. 新增部门初始化逻辑

TypeScript 复制代码
const addDept = () => {
    dialogFormVisible.value = true;
    dept.value = { name: '' }; // 清空部门数据
    resetForm(ruleFormRef.value); // 重置表单校验
    formValue.value = '新增部门';
};
  • 弹出新增部门的对话框。
  • 清空dept对象,重置表单内容。

2. 编辑部门初始化逻辑

TypeScript 复制代码
const updateDept = async (id: number) => {
    dialogFormVisible.value = true;
    dept.value = { name: '' }; // 清空部门数据
    resetForm(ruleFormRef.value); // 重置表单校验
    formValue.value = '编辑部门';

    const result = await getInfoApi(id); // 获取部门详细信息
    if (result.code) {
        dept.value = result.data; // 回显数据
    }
};
  • 弹出编辑部门的对话框。
  • 根据部门ID调用接口获取详情并回显。

保存部门数据

TypeScript 复制代码
// 添加和编辑部门逻辑,根据id属性是否为空来区分是新增还是编辑
const save = async (formEl: FormInstance | undefined) => {

  //添加表单校验
  if (!formEl) return
  await formEl.validate(async (valid) => {
    if (valid) {
      //根据ID判断执行添加部门还是编辑部
      let result = null
      if (dept.value.id) {
        result = await updateApi(dept.value)
      } else {
        result = await addApi(dept.value)
      }
      if (result.code) {
        dialogFormVisible.value = false
        ElMessage.success('添加成功')
        search()
      } else {
        ElMessage.error(result.msg)
      }
    } else {
      ElMessage.error('请重新输入')
    }
  })


}
  • 检查表单校验是否通过。
  • 根据dept.value.id判断操作类型:
    • 新增操作 :调用addApi接口。
    • 编辑操作 :调用updateApi接口。
  • 操作成功后刷新数据列表。

删除功能

TypeScript 复制代码
const deleteById = (id: number) => {
    ElMessageBox.confirm('您确定要删除该部门吗 ?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
    }).then(async () => {
        const result = await deleteApi(id);
        if (result.code) {
            ElMessage.success('删除成功');
            search(); // 刷新数据
        } else {
            ElMessage.error('删除失败');
        }
    });
};
  • 弹出确认框,用户点击"确定"后执行删除。
  • 调用deleteApi接口删除部门数据。
  • 删除成功后刷新页面数据。

表单校验

定义校验规则:

TypeScript 复制代码
const rules = ref<FormRules<RuleForm>>({
    name: [
        { required: true, message: '部门名称为必填项', trigger: 'blur' },
        { min: 2, max: 10, message: '部门名称长度必须在2-10位', trigger: 'blur' },
    ],
});
  • 部门名称为必填项。
  • 限制名称长度在2到10个字符。

重置表单校验:

TypeScript 复制代码
const resetForm = (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    formEl.resetFields();
};
  • 重置表单内容与校验状态。

页面模板与样式

部门表格

TypeScript 复制代码
<el-table :data="deptList" border style="width: 100%">
    <el-table-column type="index" label="序号" width="100" align="center" />
    <el-table-column prop="name" label="部门名称" width="200" align="center" />
    <el-table-column prop="updateTime" label="最后操作时间" width="250" align="center" />
    <el-table-column label="操作" align="center">
        <template #default="scope">
            <el-button size="small" type="success" @click="updateDept(scope.row.id)">编辑</el-button>
            <el-button size="small" type="danger" @click="deleteById(scope.row.id)">删除</el-button>
        </template>
    </el-table-column>
</el-table>
  • 表格展示部门数据,包含序号、名称、时间及操作列。
  • 操作列内嵌"编辑"和"删除"按钮。

新增与编辑部门表单模板

TypeScript 复制代码
<!-- 新增与编辑部门表单 -->
<el-dialog v-model="dialogFormVisible" :title=formValue width="500">
  <el-form :model="dept" :rules="rules" ref="ruleFormRef">
    <el-form-item label="部门名称" :label-width="formLabelWidth" prop="name">
      <el-input v-model="dept.name" autocomplete="off" />
    </el-form-item>
  </el-form>
  <template #footer>
    <div class="dialog-footer">
      <el-button @click="dialogFormVisible = false">取消</el-button>
      <el-button type="primary" @click="save(ruleFormRef)">确认</el-button>
    </div>
  </template>
</el-dialog>

1. 使用el-dialog构建弹窗

  • 属性v-model="dialogFormVisible":控制对话框的显示与隐藏。

  • 属性:title="formValue":动态设置弹窗标题("新增部门"或"编辑部门")。

  • 属性width="500":设置弹窗宽度为500px。

2. 表单部分:使用el-form组件

  • 属性:model="dept":绑定表单数据模型dept

    • dept是响应式变量,数据结构为DeptModel类型,包含idname字段。
  • 属性:rules="rules":绑定表单校验规则,确保数据完整性。

  • 属性ref="ruleFormRef":定义表单引用,用于后续的校验操作。

3. 表单项el-form-item

  • 属性label="部门名称":定义表单字段标签。

  • 属性:label-width="formLabelWidth":设置标签宽度,取值为formLabelWidth变量(默认值为140px)。

  • 属性prop="name":绑定校验规则name,用于触发校验。

4. 输入框el-input

  • 属性v-model="dept.name":双向绑定dept对象的name字段,用于存储用户输入。

底部按钮区域(Slot: footer)

取消按钮:

html 复制代码
<el-button @click="dialogFormVisible = false">取消</el-button>

点击按钮时,将dialogFormVisible设为false以关闭弹窗。

确认按钮:

html 复制代码
<el-button type="primary" @click="save(ruleFormRef)">确认</el-button>

点击按钮时,调用save()方法提交表单数据。

三、总结

  • 使用响应式数据结合Element-Plus组件,构建了直观、友好的用户界面。
  • 数据接口的封装简化了与后端的交互,减少冗余代码。
  • 表单校验与弹框功能有效提升了用户操作体验。
相关推荐
一城烟雨_28 分钟前
vue3 实现将html内容导出为图片、pdf和word
前端·javascript·vue.js·pdf
树懒的梦想1 小时前
调整vscode的插件安装位置
前端·cursor
漫 漫,1 小时前
基于Node+HeadlessBrowser的浏览器自动化方案
前端框架
低代码布道师2 小时前
第二部分:网页的妆容 —— CSS(下)
前端·css
一纸忘忧2 小时前
成立一周年!开源的本土化中文文档知识库
前端·javascript·github
涵信3 小时前
第九节:性能优化高频题-首屏加载优化策略
前端·vue.js·性能优化
前端小巷子3 小时前
CSS单位完全指南
前端·css
SunTecTec4 小时前
Flink Docker Application Mode 命令解析 - 修改命令以启用 Web UI
大数据·前端·docker·flink
拉不动的猪5 小时前
前端常见数组分析
前端·javascript·面试
小吕学编程5 小时前
ES练习册
java·前端·elasticsearch