第5章 自定义存储模块功能实现

5.1 模块基础搭建

5.1.1 创建实体类FileStore

在 cn.xueden.domain 包目录下新建一个 FileStore 实体类,代码如下所示:

package cn.xueden.domain;


import cn.xueden.base.BaseEntity;
import lombok.Data;
import org.hibernate.annotations.CreationTimestamp;

import javax.validation.constraints.NotNull;
import javax.persistence.*;
import java.sql.Timestamp;

/**功能描述:文件存储位置实体类
 * @Auther:梁志杰
 * @Date:2022/4/1
 * @Description:cn.xueden
 * @version:1.0
 */
@Data
@Entity
@Table(name="p_file_store")
@org.hibernate.annotations.Table(appliesTo = "p_file_store",comment="文件存储位置表")
public class FileStore extends BaseEntity {

    /**
     * 自增 id
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    @NotNull(groups = Update.class)
    private Long id;

    /**
     * 类型
     * native:表示本地
     * qiniu:七牛云
     * aliyun:阿里云
     */
    private String type;

    /**
     * 加速域名
     */
    private String realmName;

    /**
     * 云存储空间名
     */
    private String spaceName;

    /**
     * “密钥管理”中的AccessKey
     */
    private String accessKey;

    /**
     * “密钥管理”中的SecretKey
     */
    private String secretKey;

    /**
     * 状态
     */
    private Integer status;

}

5.1.2 创建持久层接口FileStoreRepository

在 cn.xueden.repository 包目录下新建一个 FileStoreRepository接口,代码如下所示:

package cn.xueden.repository;

import cn.xueden.domain.FileStore;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

/**文件存储位置持久层
 * @Auther:梁志杰
 * @Date:2022/4/1
 * @Description:cn.xueden.repository
 * @version:1.0
 */
public interface FileStoreRepository extends JpaRepository<FileStore, Long>, JpaSpecificationExecutor<FileStore> {
}

5.1.3 创建业务接口IFileStoreService

在 cn.xueden.service包目录下新建一个 IFileStoreService接口,代码如下所示:

package cn.xueden.service;

/**功能描述:文件存储业务接口
 * @Author:梁志杰
 * @Date:2022/4/1
 * @Description:cn.xueden.service
 * @version:1.0
 */
public interface IFileStoreService {
}

5.1.4 创建业务接口实现类FileStoreServiceImpl

在 cn.xueden.service.impl包目录下新建一个 FileStoreServiceImpl接口实现类,代码如下所示:

package cn.xueden.service.impl;


import cn.xueden.repository.FileStoreRepository;

import cn.xueden.service.IFileStoreService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @Auther:梁志杰
 * @Date:2022/4/1
 * @Description:cn.xueden.service
 * @version:1.0
 */
@Service
@Transactional(readOnly = true)
public class FileStoreServiceImpl implements IFileStoreService {

    private final FileStoreRepository fileStoreRepository;

    public FileStoreServiceImpl(FileStoreRepository fileStoreRepository) {
        this.fileStoreRepository = fileStoreRepository;
    }



}

5.1.5 创建前端控制器FileStoreController

新建一个名为controller的包,并且在该包目录下新建一个FileStoreController类,代码如下所示:

package cn.xueden.controller;

import cn.xueden.service.IFileStoreService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**功能描述:文件存储位置 前端控制器
 * @Author:梁志杰
 * @Date:2022/4/1
 * @Description:cn.xueden.controller
 * @version:1.0
 */
@RestController
@RequestMapping("fileStore")
public class FileStoreController {

    private final IFileStoreService fileStoreService;

    public FileStoreController(IFileStoreService fileStoreService) {
        this.fileStoreService = fileStoreService;
    }
}

5.2 新增功能实现

5.2.1 在FileStoreController类下添加add方法

代码如下所示:

 /**
     * 新增文件存放位置信息
     * @param fileStore
     * @return
     */
    @PostMapping
    public BaseResult add(@RequestBody FileStore fileStore){
        fileStoreService.add(fileStore);
        return BaseResult.success("新增成功");
    }

5.2.2 在IFileStoreService接口下添加add方法

代码如下所示:

 /**
     * 新增记录
     * @param fileStore
     */
    void add(FileStore fileStore);

5.2.3 在FileStoreServiceImpl接口实现类下添加add方法

代码如下所示:

/**
     * 新增记录
     * @param fileStore
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(FileStore fileStore) {
        fileStoreRepository.save(fileStore);
    }

5.2.4 列表页面布局

步骤01 创建文件夹filestore,如图所示:

在这里插入图片描述

步骤02 在filestore文件夹下创建一个名为index.vue的文件

在这里插入图片描述

步骤03 输入如下代码进行页面布局:

<template>
  <div>
    <!--搜索栏 start-->
    <div class="search__example--wrap">

    </div>
    <!--搜索栏 end -->
    <!--操作按钮 start-->
    <div class="button__example--wrap">
      <el-button type="primary" icon="el-icon-circle-plus-outline">新增</el-button>
      <el-button
        type="danger"
        icon="el-icon-delete"
      >删除</el-button>
    </div>
    <!--操作按钮 start-->
    <!--表格 start-->
    <com-table
      v-loading="loading"
      selection
      :columns="columns"
      :data="tableData"
      :pagination="{
        currentPage: defalutParams.pageIndex,
        total: total,
        onSizeChange: handleSizeChange,
        onCurrentChange: handleCurrentChange
      }"
      @selection-change="handleSelectionChange"
    >
    </com-table>
    <!--表格 end-->
    <!--弹出框 start-->
    <com-dialog v-model="dialogVisible" :title="title">
    </com-dialog>
    <!--弹出框 end-->
  </div>
</template>



步骤04 修个如下代码

<script >
export default {
  name: 'Index'
}
</script>

把以上代码修改为:

<script lang="ts">
import { defineComponent, ref } from 'vue'
export default defineComponent({
  components: {

  },
  setup() {

  }
})
</script>

步骤05 修改路由地址

修改src->router->index.ts文件,修改asyncRouterMap对象,代码如下所示:

export const asyncRouterMap: AppRouteRecordRaw[] = [
  {
    path: '/filestore',
    component: Layout,
    redirect: '/filestore/index',
    name: 'FileStore',
    meta: {
      title: '系统设置',
      icon: 'guide',
      alwaysShow: true
    },
    children: [
      {
        path: 'index',
        component: () => import('_v/filestore/index.vue'),
        name: 'FileStore',
        meta: {
          icon: 'cloud-storage',
          title: '自定义存储'
        }
      }
    ]
  }
]

步骤06 在setup函数下定义tableData、columns、loading等对象,代码如下所示:

 // 搜索
    const searchData = []
    // 表格列表名称
    const columns = ref<any[]>([
      {
        field: 'index',
        type: 'index',
        label: '序号',
        width: 60,
        index: (index: number) => {
          return (defalutParams.pageIndex - 1) * defalutParams.pageSize + index + 1
        }
      }
    ])

    const { defalutParams, tableData, loading, total,dialogVisible,title,handleSelectionChange } = useExample()

步骤07 定义searchSubmit、resetSubmit等函数,代码如下所示:

    // 查询
    function searchSubmit(data: any) {
    }

    // 重置
    function resetSubmit(data: any) {
    }

    // 展示多少条
    function handleSizeChange(val: number) {

    }
    // 展示第几页
    function handleCurrentChange(val: number) {
    }

最后return对象代码如下所示:

 return {
      searchData,
      columns,
      defalutParams,
      tableData,
      loading,
      total,
      title,
      dialogVisible,
      searchSubmit,
      resetSubmit,
      handleSizeChange,
      handleCurrentChange,
      handleSelectionChange
    }

5.2.5 添加和修改页面功能实现

步骤01 在filestore目录下新建一个components文件夹,并在此文件夹下创建一个InfoWrite.vue页面,如图所示:

在这里插入图片描述

步骤02 在InfoWrite.vue页面,添加如下代码进行布局:

<template>
  <div>
    <el-form
      ref="formRef"
      :model="form"
      :rules="rules"
      label-width="100px"
    >
      <el-row>
        <el-col :span="12">
          <el-form-item prop="type" label="类型">
            <el-select v-model="form.type" placeholder="请选择类型" style="width: 100%;">
              <el-option v-for="item in typeOptions" :label="item.label" :value="item.value" />
            </el-select>
          </el-form-item>
        </el-col>

        <el-col :span="12">
          <el-form-item prop="status" label="状态">
            <el-select v-model="form.status" placeholder="请选择状态" style="width: 100%;">
              <el-option v-for="item in statusOptions" :label="item.label" :value="item.value" />
            </el-select>
          </el-form-item>
        </el-col>

        <el-col :span="24" v-show="form.type.toString() !== 'native'">
          <el-form-item prop="realmName" label="加速域名">
            <el-input v-model="form.realmName" placeholder="例如:https://www.xueden.cn" />
          </el-form-item>
        </el-col>

        <el-col :span="24">
          <el-form-item prop="spaceName" :label="form.type.toString() === 'native'? '本地路径': '空间名'">
            <el-input v-model="form.spaceName" placeholder="请输入云存储空间" />
          </el-form-item>
        </el-col>

        <el-col :span="24" v-show="form.type.toString() !== 'native'">
          <el-form-item prop="accessKey" label="accessKey">
            <el-input v-model="form.accessKey" placeholder="请输入accessKey" />
          </el-form-item>
        </el-col>

        <el-col :span="24" v-show="form.type.toString() !== 'native'">
          <el-form-item prop="secretKey" label="secretKey">
            <el-input v-model="form.secretKey" placeholder="请输入secretKey" />
          </el-form-item>
        </el-col>

        <el-col :span="24">
          <el-form-item prop="remarks" label="备注">
            <el-input type="textarea" v-model="form.remarks" placeholder="请输入备注" />
          </el-form-item>
        </el-col>

      </el-row>
    </el-form>
    <div class="dialong__button--wrap">
      <el-button @click="close">取消</el-button>
      <el-button :loading="subLoading" type="primary" @click="setListData">保存</el-button>
    </div>
  </div>
</template>



步骤03 定义校验规则提示,代码如下所示

const requiredRule = {
  required: true,
  message: '该项为必填项'
}

步骤04 修改如下代码:

export default {
  name: 'InfoWrite'
}

为:

export default defineComponent({
  name: 'InfoWrite',
  props: {
    info: {
      type: Object as PropType<any>,
      default: () => null
    }
  },
  emits: ['close', 'success'],
  setup(props, { emit }) {
    // 表单对象
    const formRef = ref<HTMLElement | null>(null)
    // 加载对象
    const subLoading = ref<boolean>(false)

    // 定义类型下拉选择项
    const typeOptions = ref<object[]>([{
      label: '本地',
      value: 'native'
    }, {
      label: '阿里云',
      value: 'aliyun'
    }, {
      label: '七牛云',
      value: 'qiniu'
    }])
        
    // 定义状态下拉选择项
    const statusOptions = ref<object[]>([{
      label: '启用',
      value: 1
    }, {
      label: '禁用',
      value: 0
    }])

    return {
      formRef,
      subLoading,
      typeOptions
    }
  }
})

步骤05 定义一个表单对象,代码如下所示:

 // 定义表单对象
    const form = reactive<InfoWriteParams>({
      id: 0, // id
      type: '', // 类型
      realmName: '', // 加速域名
      spaceName: '', // 存储空间
      accessKey: '', // “密钥管理”中的AccessKey
      secretKey: '', // “密钥管理”中的SecretKey
      status: 0, // 状态
      remarks: '' // 备注
    })

步骤06 定义校验规则,代码如下所示:

// 定义表单字段规则,哪些必填,哪些可以不填
    const rules = reactive<InfoWriteRules>({
      type: [requiredRule]
    })

步骤07 在components目录下,创建一个types.ts文件,在里面添加一个参数接口、规则接口等,代码如下所示:

// 设置字段数据类型
export interface InfoWriteParams {
    id?: number, // id
    type: string, // 类型
    realmName: string, // 加速域名
    spaceName: string, // 存储空间
    accessKey: string, // “密钥管理”中的AccessKey
    secretKey: string, // “密钥管理”中的SecretKey
    status: number, // 状态
    remarks: string // 备注
}

// 定义校验规则
export interface InfoWriteRules {
    type?: any[], // 类型
    realmName?: any[], // 加速域名
    spaceName?: any[], // 存储空间
    accessKey?: any[], // “密钥管理”中的AccessKey
    secretKey?: any[], // “密钥管理”中的SecretKey
    status?: any[], // 状态
    remarks?: any[] // 备注
}


步骤08 编写提交表单的函数,包括新增和编辑,代码如下所示:

// 提交表单的函数
    function setListData() {
      const formRefWrap = unref(formRef as any)
      try {
        subLoading.value = true
        formRefWrap.validate(async(valid:boolean) => {
          if (valid) {
            const formData = unref(form)
            const res = await setApi({
              data: formData
            })

            if (res) {
              Message.success(form.id ? '编辑成功' : '添加成功')
              emit('success', form.id ? 'edit' : 'add')
            }
          } else {
            console.log('error submit!!')
            return false
          }
        })
      } catch (err) {
        console.log(err)
      } finally {
        subLoading.value = false
      }
    }

步骤9 编写一个关闭表单的函数

 // 关闭表单
    function close() {
      emit('close')
    }

步骤10 编写调用后端接口的API,

在filestore目录下新增一个名为api.ts的文件,主要编写一个是提交表单的接口函数,代码如下所示:

import { fetch } from '@/axios-config/axios'

// 参数接口
interface PropsData {
    params?: any,
    data?: any
}

// 提交表单接口函数
export const addApi = ({ data }: PropsData): any => {
  return fetch({ url: 'fileStore', method: 'post', data })
}


步骤11 在index.vue添加弹出层组件,代码如下所示:

 <!--弹出框 start-->
    <com-dialog v-model="dialogVisible" :title="title">
      <info-write v-if="comName==='InfoWrite'" :info="info" @close="toggleVisible" @success="success"/>
    </com-dialog>
    <!--弹出框 end-->

添加comName、toggleVisible、currentChange到useExample() 和return{},代码如下所示

const { defalutParams, tableData, loading, total,dialogVisible,title,comName,handleSelectionChange,
      toggleVisible,currentChange} = useExample()

return {
      info,
      columns,
      defalutParams,
      tableData,
      loading,
      total,
      title,
      dialogVisible,
      comName,
      toggleVisible,
      searchSubmit,
      resetSubmit,
      handleSizeChange,
      handleCurrentChange,
      handleSelectionChange
    }

步骤12 编写一个提交表单成功后的回调函数

// 提交表单成功后的回调函数
    function success(type: string) {
      if (type === 'add') {
        currentChange(1)
      }
      toggleVisible()
    }

步骤13 编写一个打开弹出框的函数,代码如下所示:

// 打开弹窗
    function open(row: any, component: string) {
      comName.value = component
      title.value = !row ? '新增' : (component === 'Detail' ? '详情' : '编辑')
      info.value = row || null
      toggleVisible(true)
    }

注意:需要把这个函数放入到return返回对象里面

步骤14 在FileStoreRepository类添加如下方法

 /**
     * 更新所有的状态
     */
    @Modifying
    @Query(value = "update FileStore m set m.status=?1")
    void updateStatusByAll(Integer status);

步骤15 修改FileStoreServiceImpl类的add方法,代码如下所示:

/**
     * 新增记录
     * @param fileStore
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(FileStore fileStore) {
        if(fileStore.getStatus()==1){ // 如果添加的记录状态是1,表示启用,其他的就需要禁用
            fileStoreRepository.updateStatusByAll(0);
        }
        // 暂时写死
        fileStore.setCreateBy(1L);
        fileStore.setUpdateBy(1L);
        fileStoreRepository.save(fileStore);
    }

5.3 获取列表功能实现

5.3.1 修改columns对象

代码如下所示:

// 表格列表名称
    const columns = ref<any[]>([
      {
        field: 'index',
        type: 'index',
        label: '序号',
        width: 60,
        index: (index: number) => {
          return (defalutParams.pageIndex - 1) * defalutParams.pageSize + index + 1
        }
      },
      {
        field: 'type',
        label: '类型',
        slots: {
          default: 'status'
        }
      },
      {
        field: 'realmName',
        label: '加速域名',
        showOverflowTooltip: true
      },
      {
        field: 'spaceName',
        label: '存储空间'
      },
      {
        field: 'accessKey',
        label: 'accessKey'
      },
      {
        field: 'secretKey',
        label: 'secretKey'
      },
      {
        field: 'status',
        label: '状态',
        slots: {
          default: 'status'
        }
      },
      {
        field: 'createTime',
        label: '创建时间',
        formatter: (row: any, column: any, cellValue: any, index: number) => {
          return formatTime(row.createTime, 'yyyy-MM-dd')
        },
        showOverflowTooltip: true
      },
      {
        field: 'updateTime',
        label: '更新时间',
        formatter: (row: any, column: any, cellValue: any, index: number) => {
          return formatTime(row.updateTime, 'yyyy-MM-dd')
        },
        showOverflowTooltip: true
      },
      {
        field: 'remarks',
        label: '备注',
        showOverflowTooltip: true
      }

    ])

5.3.2 修改表格

代码如下所示:

  <!--表格 start-->
    <com-table
      v-loading="loading"
      selection
      :columns="columns"
      :data="tableData"
      :pagination="{
        currentPage: defalutParams.pageIndex,
        total: total,
        onSizeChange: handleSizeChange,
        onCurrentChange: handleCurrentChange
      }"
      @selection-change="handleSelectionChange"
    >
      <!--类型-->
      <template #type="scope">
        <el-tag type="success" v-if="scope.row.type === 'native'">本地</el-tag>
        <el-tag type="warning" v-if="scope.row.type === 'aliyun'">阿里云</el-tag>
        <el-tag type="info" v-if="scope.row.type === 'qiniu'">七牛云</el-tag>
      </template>

      <!--状态-->
      <template #status="scope">
        <el-tag
            :type="scope.row.status === 0
            ? 'danger'
            : (scope.row.status === 1
              ? 'warning'
              : 'success')"
        >{{ scope.row.status === 0
            ? '禁用'
            : (scope.row.status === 1
                ? '启用'
                : '未知') }}
        </el-tag>
      </template>

    </com-table>
    <!--表格 end-->

5.3.3 编写获取列表数据函数

代码如下所示:

// 请求列表数据
    async function getList(data?: any): Promise<void> {
      try {
        const res = await getListApi({
          params: Object.assign(defalutParams, data || {})
        })

        total.value = res.totalElements
        tableData.value = res.content
      } finally {
        loading.value = false
      }
    }

5.3.4 编写调用后端接口的API

在api.ts文件下新增一个名为getListApi的函数,代码如下所示:

// 获取列表数据
export const getListApi = ({ params }: PropsData): any => {
  return fetch({url: 'fileStore',method: 'get', params })
}

5.3.5 在FileStoreController类下添加getList方法

代码如下所示:

 /**
     * 带查询参数的分页方法
     * @param queryCriteria 查询条件
     * @param pageVo 分页参数
     * @return
     */
    @GetMapping
    public ResponseEntity<Object> getList(FileStoreQueryCriteria queryCriteria, PageVo pageVo){
        Pageable pageable = PageRequest.of(pageVo.getPageIndex()-1,pageVo.getPageSize(), Sort.Direction.DESC, "id");
        return new ResponseEntity<>(fileStoreService.getList(queryCriteria,pageable), HttpStatus.OK);
    }

5.3.6 在IFileStoreService接口添加getList方法

代码如下所示:

 /**
     * 待查询添加分页获取列表
     * @param queryCriteria 查询条件
     * @param pageable 分页信息
     * @return
     */
    Object getList(FileStoreQueryCriteria queryCriteria, Pageable pageable);

5.3.7 在FileStoreServiceImpl接口实现类添加getList方法

代码如下所示:

  /**
     * 带查询条件分页获取列表
     * @param queryCriteria 查询条件
     * @param pageable 分页信息
     * @return
     */
    @Override
    public Object getList(FileStoreQueryCriteria queryCriteria, Pageable pageable) {
        Page<FileStore> page = fileStoreRepository.findAll((root, query, criteriaBuilder) -> QueryHelp.getPredicate(root,queryCriteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page);
    }

5.3.8 编写一个查询条件类FileStoreQueryCriteria

代码如下所示:

/**查询文件存放路径模块的添加
 * @Author:梁志杰
 * @Date:2022/4/4
 * @Description:cn.xueden.service.dto
 * @version:1.0
 */
@Data
public class FileStoreQueryCriteria {

    /**
     * 状态
     */
    @EnableXuedenQuery
    private Integer status;

    /**
     * 类型
     */
    @EnableXuedenQuery
    private String type;
}


5.4 查询列表功能实现

5.4.1 在index.vue文件中添加搜索框布局

代码如下所示:

<!--搜索栏 start-->
    <div class="search__example--wrap">
      <com-search :data = "searchData" @search-submit="searchSubmit" @reset-submit="resetSubmit"/>
    </div>
    <!--搜索栏 end -->

5.4.2 添加搜索对象

代码如下所示:

// 搜索框字段
const searchData = [{
  label: '类型',
  value: '',
  itemType: 'select',
  field: 'type',
  options: [{
    title: '本地',
    value: 'native'
  }, {
    title: '阿里云',
    value: 'aliyun'
  }, {
    title: '七牛云',
    value: 'qiniu'
  }]
},
{
  label: '状态',
  value: 0,
  itemType: 'select',
  field: 'status',
  options: [{
    title: '禁用',
    value: 0
  }, {
    title: '启用',
    value: 1
  }]
}
]

注意:需要把searchData添加到return对象里

5.4.3 添加搜索函数和重置函数

代码如下所示:

 // 查询
    function searchSubmit(data: any) {
      // 该方法重置了一些默认参数
      currentChange(1)
      getList(data)
    }

5.4.4 展示第几页功能实现

代码如下所示:

  // 展示第几页
    function handleCurrentChange(val: number) {
      // 该方法重置了一些默认参数
      currentChange(val)
      getList(data)
    }

5.4.5 展示多少条记录功能实现

代码如下所示:

 // 展示多少条
    function handleSizeChange(val: number) {
      // 该方法重置了一些默认参数
      sizeChange(val)
      getList()
    }

5.5 查询详情功能实现

5.5.1 在table表格中添加查看详情的按钮

代码如下所示:

 <!--表格按钮-->
      <template #action="scope">
        <el-button type="primary" size="mini" @click="open(scope.row,'InfoWrite')">编辑</el-button>
      </template>

修改columns对象,在后面加入如下代码:

,
      {
        field: 'action',
        label: '操作',
        width: '220px',
        slots: {
          default: 'action'
        }
      }

5.5.2 在InfoWrite.vue文件中添加getDet()函数

代码如下所示:

 // 获取详情信息
    async function getDet() {
      if (props.info) {
        const id = (props.info as any).id
        try {
          const res = await getDetApi({
            params: {
              id: id
            }
          })

          if (res.status === 200) {
            for (const key in form) {
              form[key] = res.result[key]
            }
          }
        } catch (e) {
          console.log(e)
        }
      }
    }
    getDet()

5.5.3 编写调用后端接口的函数

// 根据ID获取详情信息
export const getDetApi = ({ params }: PropsData): any => {
  return fetch({url: `/fileStore/${params.id}`,method: 'get'})
}

5.5.4 在FileStoreController类中添加获取详情的方法

代码如下所示:

/**
     * 获取详情信息
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public BaseResult detail(@PathVariable Long id){
        if(id == null){
            throw new BadRequestException("获取信息失败");
        }
        FileStore dbFileStore = fileStoreService.getById(id);
        return BaseResult.success(dbFileStore);
    }

5.5.5 在IFileStoreService接口下添加获取详情的方法

代码如下所示:

 /**
     * 根据ID获取详情信息
     * @param id
     * @return
     */
    FileStore getById(Long id);

5.5.6 在FileStoreServiceImpl接口实现类添加获取详情的方法

代码如下所示:

 /**
     * 根据ID获取详情信息
     * @param id
     * @return
     */
    @Override
    public FileStore getById(Long id) {
        return fileStoreRepository.findById(id).orElseGet(FileStore::new);
    }

5.6 更新功能实现

5.6.1 在InfoWrite.vue文件下修改setListData函数

代码如下所示:

  // 提交表单的函数
    function setListData() {
      const formRefWrap = unref(formRef as any)
      try {
        subLoading.value = true
        formRefWrap.validate(async(valid:boolean) => {
          if (valid) {
            const formData = unref(form)
            if (form.id) { // 更新
              const res = await updateApi({
                data: formData
              })
            } else { // 新增
              const res = await addApi({
                data: formData
              })
            }
            if (res) {
              Message.success(form.id ? '编辑成功' : '添加成功')
              emit('success', form.id ? 'edit' : 'add')
            }
          } else {
            console.log('error submit!!')
            return false
          }
        })
      } catch (err) {
        console.log(err)
      } finally {
        subLoading.value = false
      }
    }

5.6.2 在api.ts文件下新增updateApi接口函数

代码如下所示:

// 更新提交表单接口函数
export const updateApi = ({ data }: PropsData): any => {
  return fetch({ url: 'fileStore', method: 'put', data })
}

5.6.3 在FileStoreController类下添加一个更新方法

代码如下所示:

/**
     * 更新信息
     * @param fileStore
     * @return
     */
    @PutMapping
    public BaseResult update(@RequestBody FileStore fileStore){
        fileStoreService.update(fileStore);
        return BaseResult.success("更新成功");
    }

5.6.4 在IFileStoreService接口下添加一个更新方法

代码如下所示:

 /**
     * 更新信息
     * @param fileStore
     */
    void update(FileStore fileStore);

5.6.5 在FileStoreServiceImpl接口实现类添加一个更新方法

代码如下所示:

 /**
     * 更新信息
     * @param fileStore
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(FileStore fileStore) {
        if(fileStore.getId()==null){
            throw new BadRequestException("参数有误");
        }
        // 如果添加的记录状态是1,表示启用,其他的就需要禁用
        if(fileStore.getStatus()==1){
            fileStoreRepository.updateStatusByAll(0);
        }
        FileStore dbFileStore = fileStoreRepository.findById(fileStore.getId()).orElseGet(FileStore::new);
        BeanUtil.copyProperties(fileStore,dbFileStore, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        fileStoreRepository.save(dbFileStore);
    }

5.7 删除功能实现

5.7.1 在table表格添加删除按钮

代码如下所示:

 <!--表格按钮-->
      <template #action="scope">
        <el-button type="primary" size="mini" @click="open(scope.row,'InfoWrite')">编辑</el-button>
        <el-button type="danger" size="mini" @click="dels(scope.row)">删除</el-button>
      </template>

5.7.2 编写一个删除函数

代码如下所示:

 // 删除(一条或多条)
    function dels(item?: any) {
      delData(async() => {
        let ids: string[] = []
        if(item.id){
          ids.push(item.id)
        } else {
          ids = selectionData.value.map((v: any) => {
            return v.id
          })
        }
        const res = await delsApi({
          data: JSON.stringify(ids)
        })
        if(res){
          Message.success(res.message)
          await getList()
        }
      }, { hiddenVerify: item.id })
    }

注意:要把dels函数放到return对象里

5.7.3 编写一个调用后端接口的delsApi函数

代码如下所示:

// 删除记录
export const delsApi = ({ data }: PropsData): any => {
  return fetch({ url: 'fileStore', method: 'delete', data })
}

5.7.4 在FileStoreController类新增一个删除方法

代码如下所示:

/**
     * 删除记录
     * @param ids
     * @return
     */
    @DeleteMapping
    public BaseResult delete(@RequestBody Long[] ids){
        try {
            fileStoreService.delete(ids);
        }catch (Throwable e){
            ThrowableUtil.throwForeignKeyException(e,"删除失败,请稍候再试");
        }
        return BaseResult.success("删除成功");
    }

5.7.5 在IFileStoreService接口下新增一个删除方法

代码如下所示:

 /**
     * 删除
     * @param ids
     */
    void delete(Long[] ids);

5.7.6 在FileStoreServiceImpl接口实现类下新增一个删除方法

代码如下所示:

/**
     * 删除记录
     * @param ids
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long[] ids) {
        fileStoreRepository.deleteAllById(Arrays.stream(ids).toList());
    }

5.7.7 批量删除功能实现

修改index.vue批量删除按钮,代码如下所示:

  <el-button
        type="danger"
        icon="el-icon-delete"
        @click="dels"
      >批量删除</el-button>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墨鱼老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值