Java毕业设计:办公自动化系统的设计与实现

发布于:2025-06-08 ⋅ 阅读:(17) ⋅ 点赞:(0)

JAVA办公自动化系统

一、系统概述

本办公自动化系统基于Java EE平台开发,实现了企业日常办公的数字化管理。系统包含文档管理、流程审批、会议管理、日程安排、通讯录等核心功能模块,采用B/S架构设计,支持多用户协同工作。系统使用Spring Boot框架简化开发流程,结合MyBatis实现数据持久化,前端采用Vue.js构建现代交互界面,确保系统具有良好的可扩展性和用户体验。

二、系统架构设计

1. 技术选型

  • 前端:Vue.js、Element UI
  • 后端:Spring Boot、Spring Security、MyBatis
  • 数据库:MySQL
  • 开发工具:IntelliJ IDEA
  • 部署环境:Docker、Nginx

2. 系统架构

├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── officeautomation
│   │   │           ├── controller (控制器层)
│   │   │           ├── service (服务层)
│   │   │           ├── mapper (数据访问层)
│   │   │           ├── entity (实体类)
│   │   │           ├── dto (数据传输对象)
│   │   │           ├── config (配置类)
│   │   │           └── utils (工具类)
│   │   ├── resources
│   │   │   ├── mapper (MyBatis映射文件)
│   │   │   ├── application.yml (配置文件)
│   │   │   └── static (静态资源)
│   │   └── webapp
│   │       └── WEB-INF

三、核心代码实现

1. 数据模型设计

// User.java
@Data
@TableName("sys_user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    
    @NotBlank(message = "用户名不能为空")
    private String username;
    
    @NotBlank(message = "密码不能为空")
    private String password;
    
    private String realName;
    private String email;
    private String phone;
    private Integer status;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
    
    @TableField(exist = false)
    private List<Role> roles;
}

// Document.java
@Data
@TableName("oa_document")
public class Document {
    @TableId(type = IdType.AUTO)
    private Long id;
    
    @NotBlank(message = "文档标题不能为空")
    private String title;
    
    private String content;
    private String filePath;
    private String fileType;
    private Long fileSize;
    private Long creatorId;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
    private Integer status;
    private String keywords;
    
    @TableField(exist = false)
    private User creator;
}

// ApprovalProcess.java
@Data
@TableName("oa_approval_process")
public class ApprovalProcess {
    @TableId(type = IdType.AUTO)
    private Long id;
    
    @NotBlank(message = "流程名称不能为空")
    private String processName;
    
    private String processKey;
    private Integer status;
    private String description;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
    
    @TableField(exist = false)
    private List<ApprovalNode> nodes;
}

// Meeting.java
@Data
@TableName("oa_meeting")
public class Meeting {
    @TableId(type = IdType.AUTO)
    private Long id;
    
    @NotBlank(message = "会议主题不能为空")
    private String title;
    
    private String content;
    private LocalDateTime startTime;
    private LocalDateTime endTime;
    private String location;
    private Long organizerId;
    private Integer status;
    private LocalDateTime createTime;
    
    @TableField(exist = false)
    private User organizer;
    
    @TableField(exist = false)
    private List<User> participants;
}

2. 数据库连接配置

// MyBatisConfig.java
@Configuration
public class MyBatisConfig {
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        
        // 设置MyBatis配置
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setCacheEnabled(true);
        factoryBean.setConfiguration(configuration);
        
        // 设置TypeAliases包
        factoryBean.setTypeAliasesPackage("com.officeautomation.entity");
        
        // 设置MapperLocations
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        factoryBean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
        
        return factoryBean.getObject();
    }
    
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

3. 服务层实现

// UserServiceImpl.java
@Service
@Transactional
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private RoleMapper roleMapper;
    
    @Override
    public User getUserById(Long id) {
        User user = userMapper.selectById(id);
        if (user != null) {
            List<Role> roles = roleMapper.getRolesByUserId(id);
            user.setRoles(roles);
        }
        return user;
    }
    
    @Override
    public User getUserByUsername(String username) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        User user = userMapper.selectOne(wrapper);
        if (user != null) {
            List<Role> roles = roleMapper.getRolesByUserId(user.getId());
            user.setRoles(roles);
        }
        return user;
    }
    
    @Override
    public List<User> getAllUsers() {
        List<User> userList = userMapper.selectList(null);
        for (User user : userList) {
            List<Role> roles = roleMapper.getRolesByUserId(user.getId());
            user.setRoles(roles);
        }
        return userList;
    }
    
    @Override
    public boolean saveUser(User user) {
        if (user.getId() == null) {
            // 新增用户
            user.setCreateTime(LocalDateTime.now());
            user.setUpdateTime(LocalDateTime.now());
            user.setStatus(1);
            
            // 加密密码
            String password = user.getPassword();
            user.setPassword(PasswordEncoderUtil.encode(password));
            
            int result = userMapper.insert(user);
            return result > 0;
        } else {
            // 更新用户
            user.setUpdateTime(LocalDateTime.now());
            
            // 如果密码不为空,则更新密码
            if (!StringUtils.isEmpty(user.getPassword())) {
                user.setPassword(PasswordEncoderUtil.encode(user.getPassword()));
            } else {
                // 不更新密码,移除该字段
                user.setPassword(null);
            }
            
            int result = userMapper.updateById(user);
            return result > 0;
        }
    }
    
    @Override
    public boolean deleteUser(Long id) {
        int result = userMapper.deleteById(id);
        // 删除用户角色关联
        roleMapper.deleteUserRoleByUserId(id);
        return result > 0;
    }
}

// DocumentServiceImpl.java
@Service
@Transactional
public class DocumentServiceImpl implements DocumentService {
    @Autowired
    private DocumentMapper documentMapper;
    
    @Autowired
    private UserService userService;
    
    @Override
    public Document getDocumentById(Long id) {
        Document document = documentMapper.selectById(id);
        if (document != null) {
            User creator = userService.getUserById(document.getCreatorId());
            document.setCreator(creator);
        }
        return document;
    }
    
    @Override
    public List<Document> getDocumentsByPage(Page<Document> page, DocumentQuery query) {
        QueryWrapper<Document> wrapper = new QueryWrapper<>();
        
        if (!StringUtils.isEmpty(query.getTitle())) {
            wrapper.like("title", query.getTitle());
        }
        
        if (query.getCreatorId() != null) {
            wrapper.eq("creator_id", query.getCreatorId());
        }
        
        if (query.getStatus() != null) {
            wrapper.eq("status", query.getStatus());
        }
        
        if (query.getStartTime() != null) {
            wrapper.ge("create_time", query.getStartTime());
        }
        
        if (query.getEndTime() != null) {
            wrapper.le("create_time", query.getEndTime());
        }
        
        wrapper.orderByDesc("create_time");
        
        Page<Document> documentPage = documentMapper.selectPage(page, wrapper);
        List<Document> documentList = documentPage.getRecords();
        
        // 设置创建人信息
        for (Document document : documentList) {
            User creator = userService.getUserById(document.getCreatorId());
            document.setCreator(creator);
        }
        
        return documentList;
    }
    
    @Override
    public boolean saveDocument(Document document, MultipartFile file) {
        try {
            if (document.getId() == null) {
                // 新增文档
                document.setCreateTime(LocalDateTime.now());
                document.setUpdateTime(LocalDateTime.now());
                document.setStatus(1);
                
                // 处理上传文件
                if (file != null && !file.isEmpty()) {
                    String filePath = FileUploadUtil.uploadFile(file, "documents");
                    document.setFilePath(filePath);
                    document.setFileName(file.getOriginalFilename());
                    document.setFileSize(file.getSize());
                    document.setFileType(file.getContentType());
                }
                
                int result = documentMapper.insert(document);
                return result > 0;
            } else {
                // 更新文档
                document.setUpdateTime(LocalDateTime.now());
                
                // 处理上传文件
                if (file != null && !file.isEmpty()) {
                    // 删除原有文件
                    Document oldDocument = documentMapper.selectById(document.getId());
                    if (oldDocument != null && !StringUtils.isEmpty(oldDocument.getFilePath())) {
                        FileUploadUtil.deleteFile(oldDocument.getFilePath());
                    }
                    
                    String filePath = FileUploadUtil.uploadFile(file, "documents");
                    document.setFilePath(filePath);
                    document.setFileName(file.getOriginalFilename());
                    document.setFileSize(file.getSize());
                    document.setFileType(file.getContentType());
                }
                
                int result = documentMapper.updateById(document);
                return result > 0;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    
    @Override
    public boolean deleteDocument(Long id) {
        // 删除文档前先删除关联文件
        Document document = documentMapper.selectById(id);
        if (document != null && !StringUtils.isEmpty(document.getFilePath())) {
            FileUploadUtil.deleteFile(document.getFilePath());
        }
        
        int result = documentMapper.deleteById(id);
        return result > 0;
    }
}

4. 控制器层实现

// UserController.java
@RestController
@RequestMapping("/api/users")
@Api(tags = "用户管理")
public class UserController {
    @Autowired
    private UserService userService;
    
    @GetMapping("/{id}")
    @ApiOperation("获取用户详情")
    public Result<User> getUser(@PathVariable Long id) {
        User user = userService.getUserById(id);
        return Result.success(user);
    }
    
    @GetMapping
    @ApiOperation("获取用户列表")
    public Result<List<User>> listUsers() {
        List<User> userList = userService.getAllUsers();
        return Result.success(userList);
    }
    
    @PostMapping
    @ApiOperation("新增用户")
    @PreAuthorize("hasAuthority('sys:user:add')")
    public Result<?> addUser(@RequestBody User user) {
        boolean result = userService.saveUser(user);
        if (result) {
            return Result.success();
        } else {
            return Result.error("新增用户失败");
        }
    }
    
    @PutMapping
    @ApiOperation("更新用户")
    @PreAuthorize("hasAuthority('sys:user:edit')")
    public Result<?> updateUser(@RequestBody User user) {
        boolean result = userService.saveUser(user);
        if (result) {
            return Result.success();
        } else {
            return Result.error("更新用户失败");
        }
    }
    
    @DeleteMapping("/{id}")
    @ApiOperation("删除用户")
    @PreAuthorize("hasAuthority('sys:user:delete')")
    public Result<?> deleteUser(@PathVariable Long id) {
        boolean result = userService.deleteUser(id);
        if (result) {
            return Result.success();
        } else {
            return Result.error("删除用户失败");
        }
    }
}

// DocumentController.java
@RestController
@RequestMapping("/api/documents")
@Api(tags = "文档管理")
public class DocumentController {
    @Autowired
    private DocumentService documentService;
    
    @GetMapping("/{id}")
    @ApiOperation("获取文档详情")
    public Result<Document> getDocument(@PathVariable Long id) {
        Document document = documentService.getDocumentById(id);
        return Result.success(document);
    }
    
    @GetMapping
    @ApiOperation("获取文档列表")
    public Result<PageInfo<Document>> listDocuments(
            @RequestParam(required = false, defaultValue = "1") Integer pageNum,
            @RequestParam(required = false, defaultValue = "10") Integer pageSize,
            DocumentQuery query) {
        
        Page<Document> page = new Page<>(pageNum, pageSize);
        List<Document> documentList = documentService.getDocumentsByPage(page, query);
        
        PageInfo<Document> pageInfo = new PageInfo<>(documentList);
        pageInfo.setTotal(page.getTotal());
        pageInfo.setPages((int) page.getPages());
        
        return Result.success(pageInfo);
    }
    
    @PostMapping
    @ApiOperation("新增文档")
    @PreAuthorize("hasAuthority('oa:document:add')")
    public Result<?> addDocument(@RequestBody Document document) {
        boolean result = documentService.saveDocument(document, null);
        if (result) {
            return Result.success();
        } else {
            return Result.error("新增文档失败");
        }
    }
    
    @PostMapping("/upload")
    @ApiOperation("上传文档")
    @PreAuthorize("hasAuthority('oa:document:add')")
    public Result<?> uploadDocument(@RequestParam("file") MultipartFile file,
                                  @RequestParam("title") String title,
                                  @RequestParam("content") String content,
                                  @RequestParam("creatorId") Long creatorId) {
        
        Document document = new Document();
        document.setTitle(title);
        document.setContent(content);
        document.setCreatorId(creatorId);
        
        boolean result = documentService.saveDocument(document, file);
        if (result) {
            return Result.success();
        } else {
            return Result.error("上传文档失败");
        }
    }
    
    @PutMapping
    @ApiOperation("更新文档")
    @PreAuthorize("hasAuthority('oa:document:edit')")
    public Result<?> updateDocument(@RequestBody Document document) {
        boolean result = documentService.saveDocument(document, null);
        if (result) {
            return Result.success();
        } else {
            return Result.error("更新文档失败");
        }
    }
    
    @DeleteMapping("/{id}")
    @ApiOperation("删除文档")
    @PreAuthorize("hasAuthority('oa:document:delete')")
    public Result<?> deleteDocument(@PathVariable Long id) {
        boolean result = documentService.deleteDocument(id);
        if (result) {
            return Result.success();
        } else {
            return Result.error("删除文档失败");
        }
    }
}

5. 前端组件示例(Vue.js)

<!-- DocumentList.vue -->
<template>
  <div class="document-list">
    <el-card class="box-card">
      <template #header>
        <div class="clearfix">
          <span>文档列表</span>
          <el-button style="float: right; padding: 3px 0" type="primary" @click="handleAdd">
            新增文档
          </el-button>
        </div>
      </template>
      
      <el-form :inline="true" :model="queryParams" class="demo-form-inline">
        <el-form-item label="标题">
          <el-input v-model="queryParams.title" placeholder="请输入标题"></el-input>
        </el-form-item>
        
        <el-form-item label="创建人">
          <el-select v-model="queryParams.creatorId" placeholder="请选择创建人">
            <el-option v-for="user in userList" :key="user.id" :label="user.realName" :value="user.id"></el-option>
          </el-select>
        </el-form-item>
        
        <el-form-item>
          <el-date-picker
            v-model="queryParams.startTime"
            type="date"
            placeholder="开始日期">
          </el-date-picker>
        </el-form-item>
        
        <el-form-item>
          <el-date-picker
            v-model="queryParams.endTime"
            type="date"
            placeholder="结束日期">
          </el-date-picker>
        </el-form-item>
        
        <el-form-item>
          <el-button type="primary" @click="handleQuery">查询</el-button>
          <el-button @click="handleReset">重置</el-button>
        </el-form-item>
      </el-form>
      
      <el-table :data="documentList" stripe border fit highlight-current-row>
        <el-table-column prop="id" label="ID" width="80"></el-table-column>
        <el-table-column prop="title" label="标题"></el-table-column>
        <el-table-column prop="creator.realName" label="创建人"></el-table-column>
        <el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
        <el-table-column prop="fileSize" label="文件大小" width="100">
          <template #default="scope">
            {{ formatFileSize(scope.row.fileSize) }}
          </template>
        </el-table-column>
        <el-table-column label="操作" width="200">
          <template #default="scope">
            <el-button size="mini" @click="handleView(scope.row)">查看</el-button>
            <el-button size="mini" type="warning" @click="handleEdit(scope.row)">编辑</el-button>
            <el-button size="mini" type="danger" @click="handleDelete(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="currentPage"
        :page-sizes="[10, 20, 50, 100]"
        :page-size="pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total">
      </el-pagination>
    </el-card>
    
    <!-- 新增/编辑对话框 -->
    <el-dialog :visible.sync="dialogVisible" title="文档管理">
      <el-form :model="formData" ref="formRef" label-width="120px">
        <el-form-item label="标题" :rules="{ required: true, message: '请输入标题', trigger: 'blur' }">
          <el-input v-model="formData.title"></el-input>
        </el-form-item>
        
        <el-form-item label="内容">
          <el-input type="textarea" v-model="formData.content" rows="4"></el-input>
        </el-form-item>
        
        <el-form-item label="上传文件">
          <el-upload
            class="upload-demo"
            action="/api/documents/upload"
            :on-success="handleUploadSuccess"
            :before-upload="beforeUpload"
            :show-file-list="false">
            <el-button size="small" type="primary">点击上传</el-button>
            <div slot="tip" class="el-upload__tip">只能上传PDF、Word、Excel文件,且不超过10MB</div>
          </el-upload>
          <div v-if="formData.fileName" class="mt-2">
            <el-link :href="formData.filePath" type="primary" target="_blank">{{ formData.fileName }}</el-link>
            <el-button size="mini" type="danger" @click="removeFile">删除文件</el-button>
          </div>
        </el-form-item>
      </el-form>
      
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="saveDocument">确定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script>
export default {
  data() {
    return {
      documentList: [],
      userList: [],
      queryParams: {
        title: '',
        creatorId: null,
        startTime: null,
        endTime: null
      },
      currentPage: 1,
      pageSize: 10,
      total: 0,
      dialogVisible: false,
      formData: {},
      isEdit: false
    }
  },
  
  created() {
    this.fetchDocumentList();
    this.fetchUserList();
  },
  
  methods: {
    // 获取文档列表
    fetchDocumentList() {
      this.$http.get('/api/documents', {
        params: {
          pageNum: this.currentPage,
          pageSize: this.pageSize,
          ...this.queryParams
        }
      }).then(res => {
        if (res.code === 200) {
          this.documentList = res.data.list;
          this.total = res.data.total;
        } else {
          this.$message.error(res.message);
        }
      }).catch(err => {
        console.error(err);
        this.$message.error('获取文档列表失败');
      });
    },
    
    // 获取用户列表
    fetchUserList() {
      this.$http.get('/api/users').then(res => {
        if (res.code === 200) {
          this.userList = res.data;
        } else {
          this.$message.error(res.message);
        }
      }).catch(err => {
        console.error(err);
        this.$message.error('获取用户列表失败');
      });
    },
    
    // 格式化文件大小
    formatFileSize(bytes) {
      if (bytes === 0) return '0 B';
      const k = 1024;
      const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
      const i = Math.floor(Math.log(bytes) / Math.log(k));
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    },
    
    // 分页相关
    handleSizeChange(size) {
      this.pageSize = size;
      this.fetchDocumentList();
    },
    
    handleCurrentChange(page) {
      this.currentPage = page;
      this.fetchDocumentList();
    },
    
    // 查询与重置
    handleQuery() {
      this.currentPage = 1;
      this.fetchDocumentList();
    },
    
    handleReset() {
      this.queryParams = {
        title: '',
        creatorId: null,
        startTime: null,
        endTime: null
      };
      this.currentPage = 1;
      this.fetchDocumentList();
    },
    
    // 新增文档
    handleAdd() {
      this.isEdit = false;
      this.formData = {
        creatorId: this.$store.state.user.id
      };
      this.dialogVisible = true;
    },
    
    // 查看文档
    handleView(row) {
      this.$router.push({ name: 'DocumentDetail', params: { id: row.id } });
    },
    
    // 编辑文档
    handleEdit(row) {
      this.isEdit = true;
      this.formData = { ...row };
      this.dialogVisible = true;
    },
    
    // 删除文档
    handleDelete(row) {
      this.$confirm('确定要删除该文档吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.$http.delete(`/api/documents/${row.id}`).then(res => {
          if (res.code === 200) {
            this.$message.success('删除成功');
            this.fetchDocumentList();
          } else {
            this.$message.error(res.message);
          }
        }).catch(err => {
          console.error(err);
          this.$message.error('删除失败');
        });
      }).catch(() => {
        // 取消操作
      });
    },
    
    // 上传文件前的校验
    beforeUpload(file) {
      const isPdf = file.type === 'application/pdf';
      const isWord = file.type === 'application/msword' || file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
      const isExcel = file.type === 'application/vnd.ms-excel' || file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
      const isLt10M = file.size / 1024 / 1024 < 10;
      
      if (!(isPdf || isWord || isExcel)) {
        this.$message.error('只能上传PDF、Word、Excel文件');
        return false;
      }
      
      if (!isLt10M) {
        this.$message.error('文件大小不能超过10MB');
        return false;
      }
      
      return true;
    },
    
    // 上传成功处理
    handleUploadSuccess(response, file) {
      if (response.code === 200) {
        this.$message.success('上传成功');
        this.formData.fileName = file.originalName;
        this.formData.filePath = response.data.filePath;
        this.formData.fileSize = file.size;
      } else {
        this.$message.error(response.message);
      }
    },
    
    // 删除已上传文件
    removeFile() {
      this.formData.fileName = null;
      this.formData.filePath = null;
      this.formData.fileSize = null;
    },
    
    // 保存文档
    saveDocument() {
      this.$refs.formRef.validate(valid => {
        if (valid) {
          const url = this.isEdit ? `/api/documents` : `/api/documents`;
          const method = this.isEdit ? 'put' : 'post';
          
          this.$http[method](url, this.formData).then(res => {
            if (res.code === 200) {
              this.$message.success(this.isEdit ? '更新成功' : '创建成功');
              this.dialogVisible = false;
              this.fetchDocumentList();
            } else {
              this.$message.error(res.message);
            }
          }).catch(err => {
            console.error(err);
            this.$message.error(this.isEdit ? '更新失败' : '创建失败');
          });
        } else {
          return false;
        }
      });
    }
  }
}
</script>

<style scoped>
.upload-demo {
  margin-bottom: 10px;
}

.mt-2 {
  margin-top: 10px;
}
</style>

四、系统功能模块

1. 用户权限管理

  • 用户管理:用户信息的增删改查
  • 角色管理:角色信息的管理和权限分配
  • 权限管理:系统功能权限的定义和分配

2. 文档管理

  • 文档上传:支持多种格式文档上传
  • 文档分类:自定义文档分类体系
  • 文档检索:基于关键词的文档搜索
  • 文档权限:细粒度的文档访问权限控制

3. 流程审批

  • 流程设计:可视化流程设计器
  • 审批管理:流程发起、审批、跟踪
  • 统计分析:审批效率统计和分析

4. 会议管理

  • 会议安排:会议计划和安排
  • 会议通知:自动发送会议通知
  • 会议纪要:会议记录和归档

5. 日程安排

  • 个人日程:个人工作计划和安排
  • 共享日程:团队成员之间的日程共享
  • 日程提醒:定时提醒功能

五、系统部署与测试

1. 环境要求

  • JDK 11+
  • MySQL 8.0+
  • Maven 3.6+
  • Node.js 14+

2. 部署步骤

  1. 创建数据库并导入表结构
  2. 配置数据库连接信息
  3. 编译后端项目:mvn clean package
  4. 编译前端项目:npm install && npm run build
  5. 部署后端应用到服务器
  6. 配置Nginx代理前端静态资源

3. 测试用例

// UserServiceTest.java
@SpringBootTest
class UserServiceTest {
    @Autowired
    private UserService userService;
    
    @Test
    void testGetUserById() {
        User user = userService.getUserById(1L);
        assertNotNull(user);
        assertEquals("admin", user.getUsername());
    }
    
    @Test
    void testGetUserByUsername() {
        User user = userService.getUserByUsername("admin");
        assertNotNull(user);
        assertEquals("admin", user.getUsername());
    }
    
    @Test
    void testSaveUser() {
        User user = new User();
        user.setUsername("testuser");
        user.setPassword("123456");
        user.setRealName("测试用户");
        user.setEmail("test@example.com");
        user.setPhone("13800138000");
        
        boolean result = userService.saveUser(user);
        assertTrue(result);
        
        User savedUser = userService.getUserByUsername("testuser");
        assertNotNull(savedUser);
        assertEquals("测试用户", savedUser.getRealName());
    }
    
    @Test
    void testDeleteUser() {
        // 先创建一个用户
        User user = new User();
        user.setUsername("testuser");
        user.setPassword("123456");
        user.setRealName("测试用户");
        user.setEmail("test@example.com");
        user.setPhone("13800138000");
        
        userService.saveUser(user);
        User savedUser = userService.getUserByUsername("testuser");
        assertNotNull(savedUser);
        
        // 删除用户
        boolean result = userService.deleteUser(savedUser.getId());
        assertTrue(result);
        
        // 验证用户已删除
        User deletedUser = userService.getUserById(savedUser.getId());
        assertNull(deletedUser);
    }
}

六、毕业设计文档框架

1. 论文框架

  1. 引言
  2. 相关技术综述
  3. 系统需求分析
  4. 系统设计
  5. 系统实现
  6. 系统测试
  7. 总结与展望

2. 外文翻译

  • 推荐翻译Java EE开发、办公自动化系统设计等相关的外文文献
  • 翻译内容应与系统实现技术密切相关

七、总结

本办公自动化系统基于Java EE平台开发,实现了企业日常办公的数字化管理。系统采用前后端分离架构,结合Spring Boot、MyBatis和Vue.js等技术,具有良好的可扩展性和用户体验。通过本项目的开发,深入掌握了Java EE开发、数据库设计、前端开发等多项技术,为企业办公自动化提供了完整的解决方案。


网站公告

今日签到

点亮在社区的每一天
去签到