若依框架图片上传、富文本框编辑器功能

news2024/11/29 22:33:10

文章目录

    • 一、前言
    • 二、效果
    • 三、编码过程
      • 1.前端:
        • index.vue
        • projectShow.js
        • 富文本框: Editor/index.vue
        • 图片上传:ImgUploadCropper/index.vue
      • 2.后端:
        • 实体ProjectShow
        • ProjectShowController
        • IProjectShowService
        • ProjectShowServiceImpl
        • ProjectShowMapper
        • ProjectShowMapper.xml

一、前言

现在的需求是:实现一个项目展示模块,后端管理页面除了需要基础信息外,要加上一个图片上传和富文本框编辑器功能

二、效果

在这里插入图片描述
点击”图片存储地址”:可上传电脑任何位置的图片,并可对图片进行放大,缩小,和旋转。

在这里插入图片描述
在这里插入图片描述
存入数据库的图片以url地址存放
在这里插入图片描述
url直接百度可看到图片:
在这里插入图片描述

三、编码过程

1.前端:

index.vue

<template>
  <div class="app-container">
    <!-- 新增项目 -->
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          >新增
        </el-button>
      </el-col>
    </el-row>

    <!-- 添加或修改项目展示 -->
    <el-dialog :title="title" :visible.sync="open" width="1000px" append-to-body>
      <el-form ref="formObj" :model="form" :rules="rules" label-width="120px" >
        <el-form-item label="项目名称" prop="projectName">
          <el-input v-model="form.projectName" placeholder="请输入项目名称" />
        </el-form-item>
        <el-form-item label="项目类型" prop="projectType">
          <el-select
            v-model="form.projectType"
            placeholder="请选择项目类型"
            style="width: 65%"
          >
            <el-option
              v-for="dict in projectTypeOptions"
              :key="dict.dictValue"
              :label="dict.dictLabel"
              :value="dict.dictValue"
            ></el-option>
          </el-select>
        </el-form-item>

      <el-form-item prop="picUrl" label="图片存储地址"  required>
        <div class="coverImg-upload" @click="showCoverImgCropper = true">
          <img v-if="form.picUrl" :src="form.picUrl" class="coverImg" />
          <i v-else class="el-icon-plus coverImg-upload-icon" />
        </div>
      </el-form-item>

        <el-form-item prop="projectDetail" label="项目详情">
          <my-quill-editor v-model="form.projectDetail" ref="quillEditor" />
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input
            v-model="form.remark"
            type="textarea"
            placeholder="请输入备注"
          />
        </el-form-item>
      </el-form>
      <img-upload-cropper
      :visible.sync="showCoverImgCropper"
      @upload-success="onCoverImgUploaded"
    />
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
      
    </el-dialog>

    <!-- 项目展示平台查询 -->
    <el-table
      v-loading="loading"
      :data="projectShowList"
      row-key="id"
      default-expand-all
      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
    >
      <el-table-column label="项目名称" align="center" prop="projectName" />
      <el-table-column
        label="图片存储地址"
        align="center"
        prop="picUrl"
        v-if="false"
      />
      <el-table-column
        label="项目详情"
        align="center"
        prop="projectDetail"
        v-if="false"
      />
      <el-table-column
        label="项目类型"
        align="center"
        prop="projectType"
        :formatter="projectTypeFormat"
      />
      <el-table-column label="创建人" align="center" prop="createUser" />
      <el-table-column label="创建时间" align="center" prop="createTime" />
      <el-table-column label="修改人" align="center" prop="updateUser" />
      <el-table-column label="修改时间" align="center" prop="updateTime" />
      <el-table-column label="备注" align="center" prop="remark"/>
      <el-table-column
        label="操作"
        align="center"
        class-name="small-padding fixed-width"
      >
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="text"
            icon="el-icon-edit"
            @click="handleUpdate(scope.row)"
            >修改</el-button
          >
          <el-button
            size="mini"
            type="text"
            icon="el-icon-delete"
            @click="handleDelete(scope.row)"
            >删除</el-button
          >
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>
  
  <script>
import {
  listProjectShow,
  addProjectShow,
  updateProjectShow,
  getProjectShow,
  delProjectShow,
} from "@/api/projectShow/projectShow";
import myQuillEditor from "@/components/Editor";
import ImgUploadCropper from "@/components/ImgUploadCropper";


export default {
  name: "cpsp",
  components: {
    myQuillEditor,
    ImgUploadCropper,
  },
  data() {
    return {
      // 遮罩层
      loading: true,
      // 资产分类表格数据
      projectShowList: [],
      //计费方式字典
      projectTypeOptions: [],
      // 弹出层标题
      title: "",
      // 资产分类树选项
      categoryOptions: [],
      // 是否显示弹出层
      open: false,
      // 表单参数
      form: {
        id: null,
        projectName: null,
        projectType: "1",
        picUrl: "",
        projectDetail: "",
        remark: null,
      },
      showCoverImgCropper: false,
      formObj: "",
      // 表单校验
      rules: {
        projectName: [
          { required: true, message: "项目名称不能为空", trigger: "blur" },
        ],
        projectType: [
          { required: true, message: "项目类型不能为空", trigger: "blur" },
        ],
        picUrl: [
          { required: true, trigger: "change", message: "图片存储地址不能为空" },
        ],
      },
    };
  },
  mounted() {
    this.formObj = this.$refs.formObj;
  },
  created() {
    this.getList();
    this.getDicts("project_show_type").then((response) => {
      this.projectTypeOptions = response.data;
    });
  },
  methods: {
    /** 查询资产分类列表 */
    getList() {
      this.loading = true;
      listProjectShow(this.queryParams).then((response) => {
        this.projectShowList = response.data;
        this.loading = false;
      });
    },
    // 项目类型字典翻译
    projectTypeFormat(row, column) {
      return this.selectDictLabel(this.projectTypeOptions, row.projectType);
    },

    // 取消按钮
    cancel() {
      this.open = false;
      this.reset();
    },
    // 表单重置
    reset() {
      this.form = {
        id: null,
        projectName: null,
        projectType: "1",
        picUrl: "",
        projectDetail: "",
        remark: null,
      };
      this.resetForm("formObj");
    },
    /** 新增按钮操作 */
    handleAdd() {
      this.reset();
      this.open = true;
      this.title = "添加项目";
    },
    /**
     * 组件封面图片上传
     */
     onCoverImgUploaded(picUrl) {
      this.form.picUrl = picUrl;
      // 清除表单校验红字
      this.formObj.clearValidate("picUrl");
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs["formObj"].validate((valid) => {
        if (valid) {
          if (this.form.id != null) {
            updateProjectShow(this.form).then((response) => {
              this.msgSuccess("修改成功");
              this.open = false;
              this.getList();
            });
          } else {
            addProjectShow(this.form).then((response) => {
              this.msgSuccess("新增成功");
              this.open = false;
              this.getList();
              console.log(this.form);
            });
          }
        }
      });
    },
    /** 修改按钮操作 */
    handleUpdate(row) {
      this.reset();
      getProjectShow(row.id).then((response) => {
        this.form = response.data;
        this.open = true;
        this.title = "修改项目展示内容";
      });
    },
    /** 删除按钮操作 */
    handleDelete(row) {
      this.$confirm('是否确认删除项目名为"' + row.projectName + '"的数据项?', "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(function () {
          return delProjectShow(row.id);
        })
        .then(() => {
          this.getList();
          this.msgSuccess("删除成功");
        });
    },
  },
};
</script>
<style lang="scss">
  .coverImg-upload {
    margin-top: 10px;
    width: 150px;
    height: 150px;
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    img {
      width: 100%;
      height: 100%;
    }
    .coverImg-upload-icon {
      font-size: 28px;
      color: #8c939d;
      width: 150px;
      height: 150px;
      line-height: 150px;
      text-align: center;
    }
  }
</style>

projectShow.js

import request from '@/utils/request'

// 查询项目展示列表
export function listProjectShow(query) {
  return request({
    url: '/projectShow/list',
    method: 'get',
    params: query
  })
}
// 新增项目展示
export function addProjectShow(data) {
  return request({
    url: '/projectShow',
    method: 'post',
    data: data
  })
}

// 修改项目展示
export function updateProjectShow(data) {
  return request({
    url: '/projectShow',
    method: 'put',
    data: data
  })
}
// 点击修改按钮获取到具体cpsp项目的详情
export function getProjectShow(id) {
  return request({
    url: '/projectShow/' + id,
    method: 'get'
  })
}

// 删除资产分类
export function delProjectShow(id) {
  return request({
    url: '/projectShow/' + id,
    method: 'delete'
  })
}

富文本框: Editor/index.vue

<template>
  <div>
    <!-- 图片上传组件辅助 -->
    <el-upload
      class="avatar-uploader quill-img"
      :action="uploadImgUrl"
      name="file"
      :headers="headers"
      :show-file-list="false"
      :on-success="quillImgSuccess"
      :on-error="uploadError"
      :before-upload="quillImgBefore"
      accept='.jpg,.jpeg,.png,.gif'
    ></el-upload>

    <!-- 富文本组件 -->
    <quill-editor
      class="editor"
      v-model="content"
      ref="quillEditor"
      :options="editorOption"
      @blur="onEditorBlur($event)"
      @focus="onEditorFocus($event)"
      @change="onEditorChange($event)"
    ></quill-editor>
  </div>
</template>

<script>
import { getToken } from '@/utils/auth'

// 工具栏配置
const toolbarOptions = [
  ["bold", "italic", "underline", "strike"],       // 加粗 斜体 下划线 删除线
  ["blockquote", "code-block"],                    // 引用  代码块
  [{ list: "ordered" }, { list: "bullet" }],       // 有序、无序列表
  [{ indent: "-1" }, { indent: "+1" }],            // 缩进
  [{ size: ["small", false, "large", "huge"] }],   // 字体大小
  [{ header: [1, 2, 3, 4, 5, 6, false] }],         // 标题
  [{ color: [] }, { background: [] }],             // 字体颜色、字体背景颜色
  [{ align: [] }],                                 // 对齐方式
  ["clean"],                                       // 清除文本格式
  ["link", "image", "video"]                       // 链接、图片、视频
];

import { quillEditor } from "vue-quill-editor";
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";

export default {
  model: {
    prop: "value",
    event: "change"
  },
  props: {
    /* 编辑器的内容 */
    value: {
      type: String
    },
    /* 图片大小 */
    maxSize: {
      type: Number,
      default: 4000 //kb
    }
  },
  components: { quillEditor },
  data() {
    return {
      content: this.value,
      editorOption: {
        placeholder: "",
        theme: "snow", // or 'bubble'
        placeholder: "请输入内容",
        modules: {
          toolbar: {
            container: toolbarOptions,
            handlers: {
              image: function(value) {
                if (value) {
                  // 触发input框选择图片文件
                  document.querySelector(".quill-img input").click();
                } else {
                  this.quill.format("image", false);
                }
              }
            }
          }
        }
      },
      // uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
      uploadImgUrl: process.env.VUE_APP_BASE_API + "/system/file/upload",
      headers: {
        Authorization: 'Bearer ' + getToken()
      }
    };
  },
  watch: {
    value: function() {
      this.content = this.value;
    }
  },
  methods: {
    onEditorBlur() {
      //失去焦点事件
    },
    onEditorFocus() {
      //获得焦点事件
    },
    onEditorChange() {
      //内容改变事件
      this.$emit("change", this.content);
    },

    // 富文本图片上传前
    quillImgBefore(file) {
      let fileType = file.type;
			if(fileType === 'image/jpeg' || fileType === 'image/png'){
				return true;
			}else {
				this.$message.error('请插入图片类型文件(jpg/jpeg/png)');
				return false;
			}
    },

    quillImgSuccess(res, file) {
      // res为图片服务器返回的数据
      // 获取富文本组件实例
      let quill = this.$refs.quillEditor.quill;
      // 如果上传成功
      if (res.code == 200) {
        // 获取光标所在位置
        let length = quill.getSelection().index;
        // 插入图片  res.url为服务器返回的图片地址
        quill.insertEmbed(length, "image", res.url);
        // 调整光标到最后
        quill.setSelection(length + 1);
      } else {
        this.$message.error("图片插入失败");
      }
    },
    // 富文本图片上传失败
    uploadError() {
      // loading动画消失
      this.$message.error("图片插入失败");
    }
  }
};
</script> 

<style>
.editor {
  line-height: normal !important;
  /* height: 192px; */
}
.quill-img {
  display: none;
}
.ql-snow .ql-tooltip[data-mode="link"]::before {
  content: "请输入链接地址:";
}
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
  border-right: 0px;
  content: "保存";
  padding-right: 0px;
}

.ql-snow .ql-tooltip[data-mode="video"]::before {
  content: "请输入视频地址:";
}

.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
  content: "14px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
  content: "10px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
  content: "18px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
  content: "32px";
}

.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
  content: "文本";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
  content: "标题1";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
  content: "标题2";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
  content: "标题3";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
  content: "标题4";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
  content: "标题5";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
  content: "标题6";
}

.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
  content: "标准字体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
  content: "衬线字体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
  content: "等宽字体";
}
</style>

图片上传:ImgUploadCropper/index.vue

<template>
  <el-dialog
    class="img-upload-cropper"
    :title="title"
    :visible.sync="show"
    width="800px"
    append-to-body
    @close="onDialogClose"
  >
    <el-row>
      <el-col :xs="24" :md="12" :style="{ height: '350px' }">
        <vue-cropper
          ref="cropper"
          :img="options.img"
          outputType="png"
          :info="true"
          :autoCrop="options.autoCrop"
          :autoCropWidth="options.autoCropWidth"
          :autoCropHeight="options.autoCropHeight"
          :fixedBox="options.fixedBox"
          @realTime="realTime"
        />
      </el-col>
      <el-col :xs="24" :md="12" :style="{ height: '350px' }">
        <div
          class="upload-preview"
          :style="`width:${options.autoCropWidth}px;height:${options.autoCropHeight}px;border-radius:${previewBorderRaidus}`"
        >
          <img :src="previews.url" :style="previews.img" />
        </div>
      </el-col>
    </el-row>
    <br />
    <el-row>
      <el-col :lg="2" :md="2">
        <el-upload
          action="#"
          :http-request="httpRequest"
          :show-file-list="false"
          :before-upload="beforeUpload"
        >
          <el-button size="small">
            上传
            <i class="el-icon-upload el-icon--right"></i>
          </el-button>
        </el-upload>
      </el-col>
      <el-col :lg="{ span: 1, offset: 2 }" :md="2">
        <el-button
          icon="el-icon-plus"
          size="small"
          @click="changeScale(1)"
        ></el-button>
      </el-col>
      <el-col :lg="{ span: 1, offset: 1 }" :md="2">
        <el-button
          icon="el-icon-minus"
          size="small"
          @click="changeScale(-1)"
        ></el-button>
      </el-col>
      <el-col :lg="{ span: 1, offset: 1 }" :md="2">
        <el-button
          icon="el-icon-refresh-left"
          size="small"
          @click="rotateLeft()"
        ></el-button>
      </el-col>
      <el-col :lg="{ span: 1, offset: 1 }" :md="2">
        <el-button
          icon="el-icon-refresh-right"
          size="small"
          @click="rotateRight()"
        ></el-button>
      </el-col>
      <el-col :lg="{ span: 2, offset: 6 }" :md="2">
        <el-button type="primary" size="small" @click="uploadImg()"
          >提 交</el-button
        >
      </el-col>
    </el-row>
  </el-dialog>
</template>

<script>
import { VueCropper } from "vue-cropper";
import { fileUpload } from "@/api/system/upload";
import { uploadAvatar } from "@/api/system/user";

export default {
  name: "img-upload-cropper",
  components: { VueCropper },
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    title: {
      type: String,
      default: "",
    },
    compType: {
      type: String,
      default: "",
    },
    /**
     * 右边预览图的border-radius,单位自定
     */
    previewBorderRaidus: {
      type: String,
      default: "",
    },
  },
  computed: {},
  watch: {
    visible(val) {
      this.show = val;
    },
  },
  data() {
    return {
      options: {
        img: "", //裁剪图片的地址
        autoCrop: true, // 是否默认生成截图框
        autoCropWidth: 200, // 默认生成截图框宽度
        autoCropHeight: 200, // 默认生成截图框高度
        fixedBox: true, // 固定截图框大小 不允许改变
      },
      show: false,
      previews: {},
    };
  },
  created() {},
  mounted() {},
  methods: {
    /**
     * 关闭时
     */
    onDialogClose() {
      this.$emit("update:visible", false);
    },
    /**
     * 图片上传之前
     */
    beforeUpload(file) {
      if (file.type.indexOf("image/") == -1) {
        this.msgError("文件格式错误,请上传图片类型,如:JPG,PNG后缀的文件。");
      } else {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = () => {
          this.options.img = reader.result;
        };
      }
    },
    /**
     * 上传到服务器
     */
    uploadImg() {
      this.$refs.cropper.getCropBlob((data) => {
        let formData = new FormData();

        if (this.compType === "avatar") {
          // 头像上传
          formData.append("avatarfile", data);

          uploadAvatar(formData).then((response) => {
            console.log(
              "🚀 ~ file: index.vue ~ line 161 ~ uploadAvatar ~ response",
              response
            );
            if (response.code === 200) {
              this.show = false;

              this.options.img = "";
              this.$emit("upload-success", response.imgUrl);

              this.msgSuccess("修改成功");
            }
          });
        } else {
          formData.append("file", data);

          fileUpload(formData).then((response) => {
            if (response.code === 200) {
              // this.$refs.cropper.clearCrop();

              this.show = false;

              this.options.img = "";

              this.$emit("upload-success", response.url);

              this.msgSuccess("上传成功");
            }
          });
        }
      });
    },
    // 向左旋转
    rotateLeft() {
      this.$refs.cropper.rotateLeft();
    },
    // 向右旋转
    rotateRight() {
      this.$refs.cropper.rotateRight();
    },
    // 图片缩放
    changeScale(num) {
      num = num || 1;
      this.$refs.cropper.changeScale(num);
    },
    // 实时预览
    realTime(data) {
      this.previews = data;
    },
    /**
     * 覆盖默认的上传行为,可以自定义上传的实现
     * 留空即可,不写这个的话会有点报错
     */
    httpRequest() {},
  },
};
</script>

<style lang="scss" scoped>
.img-upload-cropper {
  .upload-preview {
    position: absolute;
    top: 50%;
    transform: translate(50%, -50%);
    border-radius: 0;
    box-shadow: 0 0 4px #ccc;
    overflow: hidden;
  }
}
</style>

2.后端:

实体ProjectShow

@Data
public class ProjectShow {
    /** 自增长主键ID */
    private Long id;

    /** 项目名称 */
    @NotNull(message = "项目名称不能为空")
    private String projectName;

    /** 项目类型*/
    @NotNull(message = "项目类型不能为空")
    private String projectType;

    /** 图片路径 */
    @NotNull(message = "图片路径不能为空")
    private String picUrl;

    /** 项目详情*/
    @NotNull(message = "项目详情不能为空")
    private String projectDetail;

    /** 创建人 */
    @NotNull(message = "创建人不能为空")
    private String createUser;

    /** 创建日期  */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date createTime;

    /** 更新人 */
    private String updateUser;

    /** 更新日期  */
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date updateTime;

    /** 备注 */
    private String remark;
}

ProjectShowController

@RestController
@RequestMapping("/projectShow")
public class ProjectShowController extends BaseController {
    @Autowired
    private IProjectShowService iProjectShowService;

    @GetMapping("/list")
    public AjaxResult list(ProjectShow projectShow) {
        List<ProjectShow> list = iProjectShowService.selectProjectShowList(projectShow);
        return  AjaxResult.success(list);
    }
    @PostMapping
    public AjaxResult add(@RequestBody ProjectShow projectShow) {
        return toAjax(iProjectShowService.insertProjectShow(projectShow));
    }

    /**
     * 修改
     */
    @PutMapping
    public AjaxResult edit(@RequestBody ProjectShow projectShow) {
        return toAjax(iProjectShowService.updateProjectShow(projectShow));
    }

    /**
     * 点击修改按钮后获项目展示的详细信息
     */
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return AjaxResult.success(iProjectShowService.selectProjectShowById(id));
    }

    /**
     * 删除
     */

    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(iProjectShowService.deleteProjectShowByIds(ids));
    }


}

IProjectShowService

public interface IProjectShowService {
    public List<ProjectShow> selectProjectShowList(ProjectShow projectShow);



    public int insertProjectShow(ProjectShow projectShow);

    public int updateProjectShow(ProjectShow projectShow);

    public ProjectShow  selectProjectShowById(Long id);

    public int deleteProjectShowByIds(Long[] ids);

}

ProjectShowServiceImpl

@Service
@Slf4j
public class ProjectShowServiceImpl  implements IProjectShowService {
    @Autowired
    private ProjectShowMapper projectShowMapper;

    @Autowired
    private TokenService tokenService;

    @Override
    public List<ProjectShow> selectProjectShowList(ProjectShow projectShow) {
        return projectShowMapper.selectProjectShowList(projectShow);
    }

    @Override
    public int insertProjectShow(ProjectShow projectShow) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        SysUser user = loginUser.getUser();
        projectShow.setCreateUser(user.getUserName());
        projectShow.setCreateTime(new Date());
        return projectShowMapper.insertProjectShow(projectShow);
    }

    @Override
    public int updateProjectShow(ProjectShow projectShow) {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        SysUser user = loginUser.getUser();
        projectShow.setUpdateUser(user.getUserName());
        projectShow.setUpdateTime(new Date());
        return  projectShowMapper.updateProjectShow(projectShow);
    }

    @Override
    public ProjectShow selectProjectShowById(Long id) {
        return projectShowMapper.selectProjectShowById(id);
    }

    @Override
    public int deleteProjectShowByIds(Long[] ids) {
        return projectShowMapper.deleteProjectShowByIds(ids);
    }

}

ProjectShowMapper

@Repository
public interface ProjectShowMapper {
    public List<ProjectShow> selectProjectShowList(ProjectShow projectShow);
    public List<ProjectShow> selectProjectShowList();

    public int insertProjectShow(ProjectShow projectShow);

    //修改
    public int updateProjectShow(ProjectShow projectShow);
    public ProjectShow selectProjectShowById(Long id);

    public int deleteProjectShowByIds(Long[] ids);
}

ProjectShowMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.activate.module.projectshow.mapper.ProjectShowMapper">

    <resultMap type="com.activate.module.projectshow.domain.ProjectShow" id="ProjectShowResult">
        <result property="id" column="id"/>
        <result property="projectName" column="project_name"/>
        <result property="projectType" column="project_type"/>
        <result property="picUrl" column="pic_url"/>
        <result property="projectDetail" column="project_detail"/>
        <result property="createUser" column="create_user"/>
        <result property="createTime" column="create_time"/>
        <result property="updateUser" column="update_user"/>
        <result property="updateTime" column="update_time"/>
        <result property="remark" column="remark"/>
    </resultMap>
    <sql id="selectProjectShowVo">
        select id, project_name, project_type, pic_url, project_detail, create_user, create_time ,update_user ,update_time ,remark from project_show
    </sql>

    <select id="selectProjectShowList" parameterType="com.activate.module.projectshow.domain.ProjectShow" resultMap="ProjectShowResult">
        <include refid="selectProjectShowVo"/>
    </select>
    <select id="selectProjectShowById" parameterType="Long" resultMap="ProjectShowResult">
        <include refid="selectProjectShowVo"/>
        where id = #{id}
    </select>

    <insert id="insertProjectShow" parameterType="com.activate.module.projectshow.domain.ProjectShow" useGeneratedKeys="true"
            keyProperty="id">
        insert into project_show
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="projectName != null and projectName != ''">project_name,</if>
            <if test="projectType != null and projectType != ''">project_type,</if>
            <if test="picUrl != null ">pic_url,</if>
            <if test="projectDetail != null ">project_detail,</if>
            <if test="createUser != null ">create_user,</if>
            <if test="createTime != null ">create_time,</if>
            <if test="updateUser != null ">update_user,</if>
            <if test="updateTime != null ">update_time,</if>
            <if test="remark != null ">remark,</if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="projectName != null and projectName != ''">#{projectName},</if>
            <if test="projectType != null and projectType != ''">#{projectType},</if>
            <if test="picUrl != null">#{picUrl},</if>
            <if test="projectDetail != null">#{projectDetail},</if>
            <if test="createUser != null">#{createUser},</if>
            <if test="createTime != null ">#{createTime},</if>
            <if test="updateUser != null ">#{updateUser},</if>
            <if test="updateTime != null ">#{updateTime},</if>
            <if test="remark != null ">#{remark},</if>

        </trim>
    </insert>

    <update id="updateProjectShow" parameterType="com.activate.module.projectshow.domain.ProjectShow">
        update project_show
        <trim prefix="SET" suffixOverrides=",">
            <if test="projectName != null and projectName != ''">project_name=#{projectName},</if>
            <if test="projectType != null and projectType != ''">project_type=#{projectType},</if>
            <if test="picUrl != null">pic_url=#{picUrl},</if>
            <if test="projectDetail != null">project_detail=#{projectDetail},</if>
            <if test="createUser != null">create_user=#{createUser},</if>
            <if test="createTime != null ">create_time=#{createTime},</if>
            <if test="updateUser != null ">update_user=#{updateUser},</if>
            <if test="updateTime != null ">update_time=#{updateTime},</if>
            <if test="remark != null ">remark=#{remark},</if>
        </trim>
        where id = #{id}
    </update>

    <delete id="deleteProjectShowByIds" parameterType="String">
        delete from project_show where id in
        <foreach item="id" collection="array" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>
</mapper>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/26389.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux命令大全

前言 Linux 的学习对于一个程序员的重要性是不言而喻的。前端开发相比后端开发&#xff0c;接触 Linux机会相对较少&#xff0c;因此往往容易忽视它。但是学好它却是程序员必备修养之一。 作者使用的是阿里云服务器 ECS &#xff08;最便宜的那种&#xff09; CentOS 7.7 64位…

指针初阶(C语言)

指针 指针是什么 内存划分是一个字节一个字节来划分的&#xff0c;其中每个字节都有一个编号来标识它&#xff0c;我们将这个编号称为地址&#xff0c;而指针就是地址 注意&#xff1a;编号是不占内存空间的&#xff0c;&#xff08;这些编号在内存中用十六进制表示&#xff0…

正厚软件 | App测试面试题及参考答案

最近整理了一些关于App测试的面试题。 本参照答案是本人在工作实践中总结&#xff0c;仅代表个人观点&#xff0c;如有错误&#xff0c;请谅解。 问&#xff1a;说一些你在测试过程中常用到的adb命名 答&#xff1a;回答本问题时&#xff0c;首先不要想到哪个命名就说哪个命令…

锐捷ISIS基础实验

目录 ISIS理论讲解 配置ISIS邻居建立 配置路由渗透&#xff08;泄露&#xff09; ISIS其它的配置特性 配置ISIS时间属性 配置ISIS认证 ISIS理论讲解 ISIS——基本概念1&#xff08;邻居建立、路由计算、报文封装&#xff09;_静下心来敲木鱼的博客-CSDN博客https://blog…

2022年全球高被引科学家公布

博士后、访问学者及联合培养申请者&#xff0c;都希望去名校及牛导麾下深造。名校有世界几大排名体系做参考&#xff0c;其知名度毋庸置疑。但牛导的概念是什么呢&#xff1f;知识人网小编在此介绍最新推出的“2022年度高被引科学家”&#xff0c;这里云集了全球自然科学和社会…

教你使用 SO_REUSEPORT 套接字选项提升服务性能

前言 Linux 网络栈中有一个相对较新的特性——SO_REUSEPORT 套接字选项&#xff0c;可以使用它来提升你的服务性能。 图 1: 上面的服务是使用并行监听器来避免请求连接瓶颈&#xff0c;而下面的服务只使用一个监听器来接收连接 概要 HAProxy 和 NGINX 是少数几个使用 Linux …

线段树什么的不是简简单单嘛,我教你!:基础篇

线段树什么的不是简简单单嘛&#xff0c;我教你&#xff01;&#xff1a;基础篇 零、序言——万物滴开篇 也许你是苦于笔试的打工人&#xff0c;也许你是步入算法圈不久的小小萌新&#xff08;我也是萌新&#xff09; &#xff0c;也许你是在网上搜索数据结构课设的倒霉学生。…

2049. 统计最高分的节点数目-数组树构造+遍历求解最大值数目

2049. 统计最高分的节点数目-数组树构造遍历求解最大值数目 给你一棵根节点为 0 的 二叉树 &#xff0c;它总共有 n 个节点&#xff0c;节点编号为 0 到 n - 1 。同时给你一个下标从 0 开始的整数数组 parents 表示这棵树&#xff0c;其中 parents[i] 是节点 i 的父节点。由于…

音视频 - 视频编码原理

目录 视频编码主要分为 图像的冗余 熵编码 帧内预测 帧间预测 DCT变换和量化 编码器比较 清晰度和耗时对比 一部电影1080P&#xff0c;帧率25fps&#xff0c;时长2小时&#xff0c;文件大小 1920x1080x1.5x25x2x360 521.4G 数据量非常大&#xff0c;对存储和网络传输都…

GMC Graph-Based Multi-View Clustering

GMC Graph-Based Multi-View Clustering 基于图的多视图聚类 abstract 现有的大多数方法没有充分考虑不同视图的权重&#xff0c;需要额外的聚类步骤来生成最终的聚类。还通常基于所有视图的固定图相似矩阵来优化目标。 本文提出了一种通用的基于图的多视图聚类算法(GMC)来解…

Android程序设计之学生考勤管理系统

基于安卓平台开发的学生考勤管理系统&#xff0c;本系统采用java语言设计&#xff0c;数据存储使用SQLite轻量级数据库实现 SQLite 简介 SQLite是一个软件库&#xff0c;实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite是一个增长最快的数据库引擎&…

JSON 对比工具

文章目录JSON对比工具JSON对比工具 JSON 是 Web 开发领域中最常用的数据传输格式之一&#xff0c;因为 JSON 的可读性较高&#xff0c;对于一些简单的 JSON 数据&#xff0c;我们不需要借助任何工具就可以轻易的读取。但对于复杂的 JSON 数据就需要借助工具才行&#xff0c;本…

公众号文案写作技巧有哪些?教你几招

公众号文案写作是每个公众号运营者心中的痛&#xff1a; 你是否每天纠结写什么&#xff1f; 你是否写着写着就词穷了&#xff1f; 你是否不知道该如何下手&#xff1f; 公众号文案应该怎么写&#xff1f;今天伯乐网络传媒就来给大家分享一份超实用的公众号文案写作技巧&…

增量模型和迭代模型的优点与缺点

增量模型&#xff1a; 举个例子&#xff1a; 用户有一个需求&#xff0c;功能包含A,B,C... ABC 增量模型&#xff1a; 开发完A我就直接上线供给用户去使用 开发完C我就直接上线供给用户去使用 开发完B我就直接上线供给用户去使用 增量模型的特点 增量模型的特点…

度量BGP监测源数量对AS可见性的影响

首先&#xff0c;本文介绍了两个公开的BGP数据源项目情况&#xff1b;其次&#xff0c;从可见AS数量和可见AS边关系数量两个方面来分析度量BGP监测源中对等AS的可见性。 BGP数据源介绍 BGP数据源有2个公开的项目&#xff0c;分别是RIPE RIS和Route Views&#xff0c;它们使用路…

VUE基础编程(三)

案例要求 基于Vue Cli和嵌套路由技术&#xff0c;完成以下功能&#xff1a; 站点打开后会默认显示如图3.1所示的“关于公司”页面&#xff0c;单击图3.1页面上的“公司简介”链接&#xff0c;站点会显示如图3.2所示的“公司简介”页面&#xff0c;单击图3.1页面上的“公司治理…

【JAVA程序设计】基于SSM的学校教务管理系统-有文档

基于SSM的学校教务管理系统-有文档项目获取项目简介开发环境项目技术功能结构文档目录运行截图项目获取 获取方式&#xff08;点击下载&#xff09;&#xff1a;是云猿实战 项目经过多人测试运行&#xff0c;可以确保100%成功运行。 项目简介 本项目是基于SSM的学校教务管理…

[附源码]java毕业设计校园失物招领平台

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

idea反编译

1、问题描述 只有jar包&#xff0c;反编译下&#xff0c;看几个配置&#xff1b; 2、问题说明 用的idea里面的插件&#xff0c;java Decoplier&#xff0c;可以反编译jar包&#xff0c;效果挺好的&#xff0c;反编译出来的.java没乱码&#xff0c;可以直接看&#xff1b; 2…

139.深度学习分布式计算框架-2

139.1 Spark MLllib MLlib(Machine Learnig lib) 是Spark对常用的机器学习算法的实现库&#xff0c;同时包括相关的测试和数据生成器。MLlib是MLBase一部分&#xff0c;其中MLBase分为四部分&#xff1a;MLlib、MLI、ML Optimizer和MLRuntime。 ML Optimizer会选择它认为最适合…