基于springboot+vue2+mysql,不能添加重复数据的实现

1.后端代码的实现:

1.1controller层

@PostMapping("/save")
	public ResultData saveNotice(@RequestAttribute Long _userId,@RequestBody OperationMaintenance operationMaintenance ) throws IOException {

		try {
			operationMaintenanceService.saveData(_userId, operationMaintenance);
			return ResultData.success();
		} catch (CustomTitleExistsException e) {
			// 捕获自定义异常,并返回错误响应
			return ResultData.fail(e.getMessage());

		} catch (Exception e) {
			// 捕获其他异常,并返回错误响应
			return ResultData.fail("运维标题已存在");
		}
	}

1.2serviceimpl层

@Override
	public void saveData(Long _userId, OperationMaintenance operationMaintenance) throws IOException {
		if (isTitleExists(operationMaintenance.getTitle())) {
			throw new CustomTitleExistsException("运维标题已存在,请重新输入");
		}else {
		operationMaintenance.setId(_userId);
		operationMaintenance.setCreateUserId(_userId);
		operationMaintenance.setCreateTime(LocalDateTime.now());
		operationMaintenanceMapper.insert(operationMaintenance);
		}

	}
@Override
	public Boolean isTitleExists(String title) throws IOException {
		OperationMaintenance existing = operationMaintenanceMapper.findByTitle(title);
		return existing != null;
	}

1.3xml中的sql实现

 <select id="findByTitle" resultType="com.todod.model.OperationMaintenance">
            SELECT * FROM operation_maintenance om WHERE  om.om_title = #{title}
    </select>

1.4自定义异常类:

public class CustomTitleExistsException extends RuntimeException{
    public CustomTitleExistsException(String message) {
        super(message);
    }
}

1.5返回结果类:

	private static final String OK = "ok";
	private static final String ERROR = "error";
    private  static  final String fail = "运维标题存在,请重新输入";
	public static final int OK_CODE = 20000; // 成功
	public static final int ERROR_CODE = 50000; // 系统异常
	public static final int PARAM_ERROR_CODE = 50002; // 参数错误
	public static final int METHOD_NOT_SUPPORTED = 50003; // 请求方式不正确
	public static final int REQUEST_INTERFACE_ERROE_CODE = 50004; // 接口请求异常

	public static final int ESTIMATE_ERROR_CODE = 50100; // 自定义异常

	public static final int USER_NOT_LOGIN = 50101; // 用户未登录
	public static final int USER_LOGIN_EXPIRED = 50102; // 用户登陆超时
	public static final int USER_LOGIN_AcountError = 50103; // 用户名或密码错误
	public static final int USER_LOGIN_StateError = 50104; // 用户状态禁用
	public static final int INTERFACE_ERROR = 50105; // 接口请求异常
	public static final int SINGLE_LOGIN_ERROR = 50106; // 单用户登陆异常
	public static final int USER_UPLOAD_PASSWORD = 50107; // 强制用户修改密码
	/**
	 * 响应结果
	 */
	private int code;

	/**
	 * 响应消息
	 */
	private String msg;
	/**
	 * 响应消息
	 */
	private Object data;

	public ResultData() {
	}

	public ResultData(int code, String msg) {
		super();
		this.code = code;
		this.msg = msg;
	}

	public ResultData(int code, String msg, Object data) {
		super();
		this.code = code;
		this.msg = msg;
		this.data = data;
	}

	public static ResultData fail(String message) {
		return new ResultData(PARAM_ERROR_CODE, fail);
	}


	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}

	public static ResultData success() {
		return new ResultData(OK_CODE, OK);
	}

	public static ResultData success(String msg) {
		return new ResultData(OK_CODE, msg);
	}

	public static ResultData success(String msg, Object data) {
		return new ResultData(OK_CODE, msg, data);
	}

	public static ResultData error() {
		return new ResultData(ERROR_CODE, ERROR);
	}

	public static ResultData error(String msg) {
		return new ResultData(ERROR_CODE, msg);
	}

	public static ResultData error(String msg, Object data) {
		return new ResultData(ERROR_CODE, msg, data);
	}

	public static ResultData error(int code, String msg) {
		return new ResultData(code, msg);
	}

	public static ResultData error(int code, String msg, Object data) {
		return new ResultData(code, msg, data);
	}

	public int getCode() {
		return code;
	}

	public void setCode(int code) {
		this.code = code;
	}

	public Object getData() {
		return data;
	}

	public void setData(Object data) {
		this.data = data;
	}

2.前端代码的实现:

2.1添加数据页面:

<template>
  <div style="width:100%;height:auto; margin:0 auto;">
    <el-form :model="form" label-width="100px" label-position="left">
      <el-row :gutter="20">
        <el-col :span="24">
          <el-form-item>
            <div slot="label">项目名称<font color="red">*</font></div>           
            <el-select v-model="form.dirId" clearable style="width:100%;" @change="selectGoodsByGroupId($event)">
              <el-option v-for="item in symbols" :key="item.id" :label="item.name" :value="item.id" />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item>
            <div slot="label">运维标题<font color="red">*</font></div>
            <el-input v-model="form.title" placeholder="运维标题" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item>
            <div slot="label" >运维人员<font color="red">*</font></div>
            <el-select v-model="form.staffId" clearable style="width:100%;" @change="selectGoodsByGroupId($event)">
              <el-option v-for="item in symbols2" :key="item.id" :label="item.nickName" :value="item.id" />
            </el-select>
          </el-form-item>
        </el-col>  
      <el-col :span="12">
        <el-form-item>
            <div slot="label">运维日期<font color="red">*</font></div>
            <el-date-picker
            v-model="form.itemTime"
            value-format="yyyy-MM-dd"
            class="filter-item"
            type="daterange"
            range-separator="至"
            start-placeholder="运维开始日期"
            end-placeholder="运维结束日期"
            style="width: 100%;"
            :clearable="false"
            />
          </el-form-item>
      </el-col>
      </el-row>
      <el-form-item label="内容">
        <el-input v-model="form.content" type="textarea" :autosize="{ minRows: 3, maxRows: 6}" />
      </el-form-item>
      <el-form-item label="备注">
        <el-input v-model="form.message" type="textarea" :autosize="{ minRows: 3, maxRows: 6}" />
      </el-form-item>
      <el-form-item label="检测报告" prop="gysId">
        <el-upload
        class="upload-demo"
        accept=".jpg,.png,.jpeg,.bmp,.gif,.svg,.mp4,.avi,.wmv,.mpg,.rmvb,.flv,.doc,.docx,.xlsx"
        :on-change="handleChange"
        :action="uploadpath"
        :headers="uoloadheaders"
        :on-success="handleAvatarSuccess"
        :on-remove="handleRemove"
        :on-exceed="handleExceed"
        :file-list="fileList"
        :before-upload="beforeAvatarUpload"
        name="uploadfile_ant"
      >
        <el-button size="small" icon="el-icon-upload" type="primary">选择文件</el-button>
        <span style="color:red;">  上传文件不超过100MB</span>
      </el-upload>
    </el-form-item>
    <el-form-item label="回复文档" prop="gysId">
      <el-upload
        class="upload-demo"
        accept=".jpg,.png,.jpeg,.bmp,.gif,.svg,.mp4,.avi,.wmv,.mpg,.rmvb,.flv,.doc,.docx,.xlsx"
        :on-change="handleChange2"
        :action="uploadpath2"
        :headers="uoloadheaders"
        :on-success="handleAvatarSuccess2"
        :on-remove="handleRemove2"
        :on-exceed="handleExceed2"
        :file-list="fileList2"
        :before-upload="beforeAvatarUpload2"
        name="uploadfile_ant"
      >
        <el-button size="small" icon="el-icon-upload" type="primary">选择文件</el-button>
        <span style="color:red;">  上传文件不超过100MB</span>
      </el-upload>
    </el-form-item>
    </el-form>
        
    <div style="text-align:center;">
      <el-button type="primary" @click="save()">保存</el-button>
      <el-button type="danger" @click="closePage">取消</el-button>
    </div>
  </div>
</template>
<script>
 import { saveData } from '@/api/operationMaintenance'
 import { getAllList ,} from '@/api/maApplicationInfo'
import { Message } from 'element-ui'
import {getUserList,getId} from '@/api/user'
import { getDictListByCode } from '@/api/dict'
import tool from '@/utils/tool'
export default {
  inject: ['getList'],
  data() {
    return {
      form: {},
      uploadpath: '',
      uploadpath2: '',
      types: [],
      batchCode:'',
      symbols: [],
      symbols2:[],
      symbols3:[],
      uoloadheaders: {},
      fileData: '', // 文件上传数据(多文件合一)
      fileList: [],
      fileList2: [] // upload多文件数组
    }
  },
 created() {     
    this.getproject()
    this.getStateList('YW_OPEX_STATUS')
  },
  methods: {
    getStateList(code){
      getDictListByCode(code).then(response => {
        if(code === 'YW_OPEX_STATUS'){
            this.symbols3 = response.data
        } 
      })
    },
    getproject(){
      getAllList().then(response=> {
           this.symbols = response.data
           
       })
      getUserList().then(response=>{
        this.symbols2 = response.data
      })    
      this.batchCode = ''
      getId().then(res => {
        this.batchCode = res.data
        let address = process.env.NODE_ENV == 'development' ? process.env.VUE_APP_URL_RECON : process.env.VUE_APP_BASE_API;
        var path = '/inspectionReport/uploadFile'
        var path2 = '/replayDocument/uploadFile' 
        this.uploadpath = address + path
        this.uploadpath2 = address + path2
        this.uoloadheaders = {
          'X-TOKEN' : tool.getCookie('X-Token'),
          'client-url':location.href,
          'applicationId':this.applicationId
        }
      })
    },
    selectGoodsByGroupId(val) { // 根据设备组id获取相应的商品
      if (val != null && val !== '' && val !== undefined) {
        for (var i = 0; i < this.symbols.length; i++) {
          if (this.symbols[i].id === val) {
            this.form.userId = this.symbols[i].customerMid
          }
        }
      }
  },

    save(){
      if (!this.form.dirId) {
        this.$message.error('项目名称称不能为空')
       return
      } else if (!this.form.title) {
         this.$message.error('运维标题不能为空')
        return
       } else if (!this.form.staffId) {
        this.$message.error('运维人员不能为空')
       return
      } else if (!this.form.itemTime) {
       this.$message.error('运维日期不能为空')
         return
    } else {
      this.form.startTime = this.form.itemTime[0]
      this.form.endTime = this.form.itemTime[1]
      const loading = this.$loading({
          lock: true,
          text: 'Loading',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.7)'
        })
      saveData(this.form).then(response => {
        console.log(response.code)
          Message({
            message: '新增成功',
            type: 'success',
            duration: 5 * 1000,
            
          })
          this.$emit('update:visible', false)
          loading.close()
          this.getList()
        }).catch(response => {
          loading.close()
          this.getList()
        })
      }
    },
    handleChange(file, fileList) {
      let fileName = file.name;
      let uid = file.uid
      let pos = fileName.lastIndexOf(".");
      let lastName = fileName.substring(pos, fileName.length);
      var suffix = '.jpg,.png,.jpeg,.bmp,.gif,.svg,.mp4,.avi,.wmv,.mpg,.rmvb,.flv,.doc,.docx,.xlsx'
      if (suffix.indexOf(lastName.toLowerCase()) === -1) {
        this.$message.error("文件必须为.jpg,.png,.jpeg,.bmp,.gif,.svg,.mp4,.avi,.wmv,.mpg,.rmvb,.flv,.doc,.docx,.xlsx类型");
        for(var i = 0;i<fileList.length;i++) {
          if(fileList[i].uid == uid) {
            fileList.splice(i,1)
          }
        }
        return;
      }
      const existFile = fileList.slice(0, fileList.length - 1).find(f => f.name === file.name)
      if (existFile) {
        this.$message.error('当前文件已经存在!')
        fileList.pop()
      }
      this.fileList = fileList
    },
    handleChange2(file, fileList2) {
      let fileName = file.name;
      let uid = file.uid
      let pos = fileName.lastIndexOf(".");
      let lastName = fileName.substring(pos, fileName.length);
      var suffix = '.jpg,.png,.jpeg,.bmp,.gif,.svg,.mp4,.avi,.wmv,.mpg,.rmvb,.flv,.doc,.docx,.xlsx'
      if (suffix.indexOf(lastName.toLowerCase()) === -1) {
        this.$message.error("文件必须为.jpg,.png,.jpeg,.bmp,.gif,.svg,.mp4,.avi,.wmv,.mpg,.rmvb,.flv,.doc,.docx,.xlsx类型");
        for(var i = 0;i<fileList2.length;i++) {
          if(fileList2[i].uid == uid) {
            fileList2.splice(i,1)
          }
        }
        return;
      }
      const existFile = fileList2.slice(0, fileList2.length - 1).find(f => f.name === file.name)
      if (existFile) {
        this.$message.error('当前文件已经存在!')
        fileList2.pop()
      }
      this.fileList2 = fileList2
    },
    handleAvatarSuccess(res, file) {
      this.uploadLoading = false
      if (res.code === 20000) {
         this.form.reportId= res.data.id
        this.upVisible = false
        Message({
          message: '上传成功',
          type: 'success',
          duration: 5 * 1000
        })
      } else {
        this.upVisible = true
        Message({
          message: res.msg,
          type: 'error',
          duration: 5 * 1000
        })
      }
    },
    handleAvatarSuccess2(res, file) {
      this.uploadLoading = false
      if (res.code === 20000) {
        this.form.fileId= res.data.id
        this.upVisible = false
        Message({
          message: '上传成功',
          type: 'success',
          duration: 5 * 1000
        })
      } else {
        this.upVisible = true
        Message({
          message: res.msg,
          type: 'error',
          duration: 5 * 1000
        })
      }
    },
    handleRemove(file, fileList) {
      this.fileList = fileList
    },
    handleExceed(files, fileList) {
      this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)
    },
    beforeAvatarUpload(file) {
      const isLt2M = file.size / 1024 / 1024 < 100

      if (!isLt2M) {
        this.$message.error('上传文件大小不能超过100MB!')
      }
      return isLt2M
    },
    handleRemove2(file, fileList2) {
      this.fileList2 = fileList2
    },
    handleExceed2(files, fileList2) {
      this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList2.length} 个文件`)
    },
    beforeAvatarUpload2(file) {
      const isLt2M = file.size / 1024 / 1024 < 100

      if (!isLt2M) {
        this.$message.error('上传文件大小不能超过100MB!')
      }
      return isLt2M
    },
    closePage() {
      this.$emit('update:visible', false)
    },
    
  }
}
</script>

2.2相关js

import request from '@/utils/request'

export function getInitialLoading() {
  return request({
    url: '/operationMaintenance/getInitialLoading',
    method: 'post'
  })
}

export function getAgainLoading(data) {
  return request({
    url: '/operationMaintenance/getAgainLoading',
    method: 'post',
    params: data
  })
}

export function getPage(data) {
  return request({
    url: '/operationMaintenance/getPage',
    method: 'post',
    data
  })
}

export function saveData(data) {
  return request({
    url: '/operationMaintenance/save',
    method: 'post',
    data
  })
}

export function edit(data) {
  return request({
    url: '/operationMaintenance/edit',
    method: 'post',
    data
  })
}

export function remove(data) {
  return request({
    url: '/operationMaintenance/delete',
    method: 'post',
    params: data
  })
}

export function getInfo(data) {
  return request({
    url: '/operationMaintenance/getInfo',
    method: 'get',
    params: data
  })
}

export function getXiangMuList(data) {
  return request({
    url: '/operationMaintenance/getXiangMuList',
    method: 'post',
    data
  })
}

export function getSelectedPage(data) {
  return request({
    url: '/operationMaintenance/getSelectedPage',
    method: 'post',
    data
  })
}

export function getSelected2Page(data) {
  return request({
    url: '/operationMaintenance/getSelected2Page',
    method: 'post',
    data
  })
}

export function getAllList() {
  return request({
    url: '/operationMaintenance/getAllList',
    method: 'post'
  })
}

export function downloadFile(paran) {
  return request({
    url: '/inspectionReport/downLoad',
    method: 'post',
    params: paran,
    responseType: 'blob'
  })
}
export function downloadFile2(paran) {
  return request({
    url: '/replayDocument/downLoad',
    method: 'post',
    params: paran,
    responseType: 'blob'
  })
}

// 下载文件
export function downloadById(data) {
      return request({
          url: '/inspectionReport/downLoad',
          method: 'post',
          params: data,
          responseType: 'blob'
      })
  }
  export function getTreeData() {
    return request({
     url: '/operationMaintenance/getTreePartData',
     method: 'post'
    })
   }

3.request.js

import axios from 'axios'
import { Message } from 'element-ui'
import router from '.././router'
import tool from './tool'

const otherReq = ['downLoad', 'downloadTemplate','problemTemplate']
let address = process.env.NODE_ENV == 'development' ? process.env.VUE_APP_URL_RECON : process.env.VUE_APP_BASE_API;

// create an axios instance
const service = axios.create({
  baseURL: address, // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: -1 // request timeout
})

// request interceptor
service.interceptors.request.use(
  config => {
    // do something before request is sent
    let token = tool.getCookie('X-Token');
    config.headers['X-TOKEN'] = token
    config.headers['client-url'] = location.href
    return config
  },
  error => {
    // do something with request error
    console.log(error) // for debug
    return Promise.reject(error)
  }
)

// response interceptor
service.interceptors.response.use(
  /**
   * If you want to get http information such as headers or status
   * Please return  response => response
  */

  /**
   * Determine the request status by custom code
   * Here is just an example
   * You can also judge the status by HTTP Status Code
   */
  response => {
    const res = response.data
    var url = response.request.responseURL
    var split = url.split('/')
    var laststr = split[split.length - 1]
    var lastUrl = laststr.split('?')[0]
    if (lastUrl === 'flow') {
      return response
    }
    if (otherReq.indexOf(lastUrl) !== -1) {
      return response
    }
    if (url.indexOf('/data-source/data/') !== -1) {
      return response.data
    }

    // if the custom code is not 20000, it is judged as an error.
    if (res.code !== 20000) {
      if (res.code === 50101 || res.code === 50102) {
        if (url.indexOf('/getFillByTask') !== -1) {
          let data = JSON.parse(response.config.data)
          let taskId = data.taskId;
          router.push({ path: '/loginShare', query: { id: taskId } })
        } else {
          // 获取登录页访问地址
          let ypt = process.env.NODE_ENV == 'development' ? process.env.VUE_APP_HOME_URL : process.env.VUE_APP_HOME_URL_PROD;
          // 如果当前路由不是登录页,跳转到登录页
          if (window.location.href.indexOf(ypt) === -1) {
            window.localStorage.clear();
            tool.clearAllCookie()
            localStorage.stop = true;

            let ypt = process.env.NODE_ENV == 'development' ? process.env.VUE_APP_HOME_URL : process.env.VUE_APP_HOME_URL_PROD;
            window.location.href = ypt
          }
        }

      }else if (res.code === 50002) { //
        Message({
          message: res.msg || 'Error',
          type: 'error',
          duration: 5 * 1000
        })
      }
       else if (res.code === 50107) { // 修改密码
        router.push({
          name: 'uploadPassword', params: { token: res.data.token }
        })
      } else if (res.code === 99999) { // 未授权
        router.push({ path: '/empower/empower' })
      } else if (res.code === 50000) { // 未授权
        Message({
          message: res.msg || 'Error',
          type: 'error',
          duration: 5 * 1000
        })
      }
      // Message({
      //   message: res.msg || 'Error',
      //   type: 'error',
      //   duration: 5 * 1000
      // })
      return Promise.reject(new Error(res.msg || 'Error'))
    } else {
      return res
    }
  },
  error => {
    console.log('err' + error) // for debug
    Message({
      message: error.msg || 'Error',
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

export default service

3.课外知识:

后端打包命令:mvn clean package;

前段打包命令:npm run build;

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

m87里的光

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

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

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

打赏作者

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

抵扣说明:

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

余额充值