소스 검색

前端提交后端增加重复提交功能

xusl 2 년 전
부모
커밋
59e36890aa

+ 13 - 0
backend/src/main/java/com/jiayue/ssi/constant/LoginConstants.java

@@ -0,0 +1,13 @@
+package com.jiayue.ssi.constant;
+/**
+* 登录用到的常量
+*
+* @author xsl
+* @since 2023/03/20
+*/
+public class LoginConstants {
+    /**
+     * 登录锁定后多久时间重试(毫秒)
+     */
+    public static final Long LOGIN_LOCK = 100000L;
+}

+ 0 - 21
backend/src/main/java/com/jiayue/ssi/controller/Test.java

@@ -1,21 +0,0 @@
-package com.jiayue.ssi.controller;
-
-import cn.hutool.core.lang.Validator;
-import org.apache.commons.lang3.RegExUtils;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
-*
-*
-* @author xsl
-* @since 2023/03/16
-*/
-public class Test {
-    public static void main(String args[]) {
-        String str = "18698814578";
-        String pattern = "^1[3|4|5|6|7|8|9][0-9]\\d{8}$";
-        System.out.println(str.matches(pattern));
-    }
-}

+ 1 - 1
backend/src/main/java/com/jiayue/ssi/filter/InterfaceLimitFilter.java

@@ -29,7 +29,7 @@ public class InterfaceLimitFilter extends OncePerRequestFilter {
         if (!InterfaceLimitUtil.checkInterface(request, 1000, 5)) {
             log.error("接口拦截:{} 请求超过限制频率【{}次/{}ms】,IP为{}", request.getRequestURI(), 1000, 1, request.getRemoteAddr());
             response.setHeader("Access-Control-Allow-Origin", "*");
-            response.setStatus(401);
+            response.setStatus(410);
             response.setContentType("text/html;charset=utf-8");
             response.getWriter().write("请求过于频繁,请稍后再试!");
             return;

+ 2 - 1
backend/src/main/java/com/jiayue/ssi/handler/CustomAuthenticationFailureHandler.java

@@ -7,6 +7,7 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import com.jiayue.ssi.constant.CacheConstants;
+import com.jiayue.ssi.constant.LoginConstants;
 import com.jiayue.ssi.entity.SysUser;
 import com.jiayue.ssi.service.SysParameterService;
 import com.jiayue.ssi.service.SysUserService;
@@ -42,7 +43,7 @@ public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationF
             // 失败总次数
             int errCount = Integer.parseInt(sysParameterService.queryByKey("errCount","5"));
             if (user.getStatus().equals("1")) {
-                Long xz = (user.getLockTime() + 100000 - System.currentTimeMillis()) / 1000;
+                Long xz = (user.getLockTime() + LoginConstants.LOGIN_LOCK - System.currentTimeMillis()) / 1000;
                 if (xz < 0) {
                     if (errCount-1==0) {
                         errorTips = "用户锁定,稍后再试";

+ 2 - 1
backend/src/main/java/com/jiayue/ssi/service/impl/UserServiceImpl.java

@@ -1,5 +1,6 @@
 package com.jiayue.ssi.service.impl;
 
+import com.jiayue.ssi.constant.LoginConstants;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.core.authority.AuthorityUtils;
 import org.springframework.security.core.userdetails.User;
@@ -30,7 +31,7 @@ public class UserServiceImpl implements UserDetailsService {
             throw new UsernameNotFoundException("用户名错误!");
         }
         else{
-            if (sysUser.getStatus().equals("1") && (System.currentTimeMillis() - sysUser.getLockTime()) < 100000) {
+            if (sysUser.getStatus().equals("1") && (System.currentTimeMillis() - sysUser.getLockTime()) < LoginConstants.LOGIN_LOCK) {
                 sysUser.setPassword("1");
             }
             if (sysUser.getStatus().equals("2")) {

+ 2 - 0
ui/package.json

@@ -21,6 +21,8 @@
     "element-ui": "2.13.0",
     "font-awesome": "^4.7.0",
     "js-cookie": "2.2.0",
+    "lodash": "^4.17.21",
+    "lodash-es": "^4.17.21",
     "moment": "^2.24.0",
     "node-sass": "^6.0.1",
     "normalize.css": "7.0.0",

+ 12 - 5
ui/src/main.js

@@ -21,8 +21,9 @@ import VXETable from 'vxe-table'
 import 'vxe-table/lib/index.css'
 
 import {removeToken} from './utils/auth'
-import { resetForm} from "@/utils/index";
-import {sm2 as sm5, sm2 as sm4, sm2 as sm3, sm2} from "sm-crypto";
+import { resetForm} from "@/utils/index"
+
+import {sm2 as sm5, sm2 as sm4, sm2 as sm3, sm2} from "sm-crypto"
 Vue.prototype.$moment = moment
 Vue.prototype.$echarts = echarts
 Vue.use(VXETable)
@@ -63,8 +64,8 @@ let publicKey2 = '041967638ca43d4577d8dba166bff4437fde944270101f398a95b846ec2f81
 let privateKey1 = '27ce6eec39dbf3b564a77c4da1e129fe1ba01a92f6d61055a33ed14ffcbc949e'
 
 Vue.prototype.$axios.interceptors.request.use(
-
   config => {
+    const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
     // get请求映射params参数
     if (config.method === 'get' && config.params) {
       // 参数加密
@@ -75,9 +76,8 @@ Vue.prototype.$axios.interceptors.request.use(
       config.params = result
     }
 
-    if (config.method === 'post' || config.method === 'put' || config.method === 'delete') {
+    if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put' || config.method === 'delete')) {
       if (config.url != '/getMailCode') {
-
         if (config.data !== undefined) {
           // 参数加密
           let encryptParam = doEncrypt(JSON.stringify(config.data))
@@ -204,6 +204,13 @@ Vue.prototype.$axios.interceptors.response.use(
           console.log('服务器关闭了!')
           resetRouter()
           break
+        case 410:
+          Message({
+            message: error.response.data,
+            type: 'error',
+            duration: 5 * 1000
+          })
+          break
         case 409:
             if (!isRefreshing) {
               isRefreshing = true

+ 7 - 32
ui/src/views/sysManager/sysParameter/index.vue

@@ -4,14 +4,6 @@
       <div slot="header" class="clearfix">
         <span>系统参数</span>
       </div>
-<!--      <el-button-->
-<!--        type="primary"-->
-<!--        size="small"-->
-<!--        style="round-clip: 10px"-->
-<!--        :loading="btnLonding"-->
-<!--        @click="insertEvent"-->
-<!--      >新增</el-button>-->
-
       <el-button
         type="primary"
         plain
@@ -20,7 +12,6 @@
         @click="insertEvent"
       >新增
       </el-button>
-
       <el-input
         v-model="keywords"
         placeholder="通过描述搜索参数"
@@ -31,7 +22,6 @@
         @keyup.enter.native="handleQuery"
       />
       <el-button type="primary" icon="el-icon-search" size="mini" @click="getList">搜索</el-button>
-
       <div style="padding-top: 10px">
         <vxe-table
           ref="xTable"
@@ -49,28 +39,12 @@
           :edit-rules="rules"
           :edit-config="{trigger: 'manual', mode: 'row',autoClear: false,icon:'none',activeMethod: activeCellMethod}"
         >
-<!--        <vxe-table-->
-<!--          ref="xTable"-->
-<!--          highlight-current-row-->
-<!--          v-show="showTable"-->
-<!--          :keep-source="true"-->
-<!--          align="center"-->
-<!--          export-config-->
-<!--          :loading="loading"-->
-<!--          auto-resize-->
-<!--          border-->
-<!--          resizable-->
-<!--          show-overflow-->
-<!--          :edit-rules="rules"-->
-<!--          :data="tableData"-->
-<!--          :edit-config="{trigger: 'manual', mode: 'row',autoClear: false,icon:'none',activeMethod: activeCellMethod}"-->
-<!--        >-->
           <vxe-table-column title="参数配置">
             <vxe-table-column
               field="sysKey"
               title="参数名"
               width="25%"
-              :edit-render="{name: '$input', props: {type: 'text', readonly: !add}}"
+              :edit-render="{name: '$input', props: {type: 'text'}}"
             />
             <vxe-table-column
               field="sysValue"
@@ -141,7 +115,7 @@
   </div>
 </template>
 <script>
-
+import { debounce } from 'lodash'
 export default {
   data() {
     return {
@@ -179,7 +153,7 @@ export default {
       }
       return true
     },
-    getList() {
+    getList:debounce(function(){
       this.loading = true;
       var searchParams = {
         currentPage: this.currentPage,
@@ -200,7 +174,7 @@ export default {
       }).catch((error) => {
         this.$message.error('获取数据出错' + error)
       })
-    },
+    },1000),
     handlePageChange({ currentPage, pageSize }) {
       this.currentPage = currentPage
       this.pageSize = pageSize
@@ -211,7 +185,8 @@ export default {
       this.btnLonding = true
       this.$refs.xTable.setActiveRow(row)
     },
-    saveRowEvent(row) {
+    saveRowEvent:debounce(function(row){
+      console.log(row)
       this.saveLoding = true
       this.$refs.xTable.validate(valid => {
         if (valid) {
@@ -254,7 +229,7 @@ export default {
         }
       })
       this.saveLoding = false
-    },
+    },1000),
     cancelRowEvent(row) {
       this.addType = false
       this.saveLoding = false

+ 8 - 9
ui/src/views/sysManager/userManager/index.vue

@@ -196,8 +196,7 @@
 </template>
 
 <script>
-// import { listUser, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus } from "@/api/system/user";
-
+import { debounce } from 'lodash'
 export default {
   name: "User",
   data() {
@@ -285,7 +284,7 @@ export default {
       return belongTo
     },
     /** 查询用户列表 */
-    getList() {
+    getList:debounce(function(){
       this.loading = true;
       var searchParams = {
         currentPage: this.currentPage,
@@ -308,7 +307,7 @@ export default {
       }).catch((error) => {
         this.$message.error('获取数据出错' + error)
       })
-    },
+    },1000),
     // 用户状态修改
     handleStatusChange(row) {
       let text = row.status === "0" ? "启用" : "停用";
@@ -356,7 +355,7 @@ export default {
       this.form.password = this.initPassword;
     },
     /** 提交按钮 */
-    submitForm: function () {
+    submitForm:debounce(function(){
       this.$refs["form"].validate(valid => {
         if (valid) {
           if (this.form.id != undefined) {
@@ -401,9 +400,9 @@ export default {
           }
         }
       });
-    },
+    },1000),
     /** 重置密码按钮操作 */
-    handleResetPwd(row) {
+    handleResetPwd:debounce(function(row){
       this.$confirm('创建密码并发送到邮箱:' + row.mailbox, '提示', {
         confirmButtonText: '确定',
         cancelButtonText: '取消',
@@ -430,9 +429,9 @@ export default {
         })
       }).catch(() => {
       });
-    },
+    },1000),
     /** 删除按钮操作 */
-    handleDelete() {
+    handleDelete(){
       const _selectData = this.$refs.userTable.getRadioRecord(true)
       if (_selectData == null) {
         this.$message({

+ 3 - 2
ui/src/views/sysManager/userManager/profile/resetPwd.vue

@@ -19,6 +19,7 @@
 <script>
 import { mapGetters } from 'vuex'
 import {userinfoDecrypt} from "@/main";
+import { debounce } from 'lodash'
 export default {
   computed: {
     ...mapGetters([
@@ -79,7 +80,7 @@ export default {
           confirmPassword: undefined
       }
     },
-    submit() {
+    submit:debounce(function(){
       this.$refs["form"].validate(valid => {
         if (valid) {
           // 密码验证规则
@@ -136,7 +137,7 @@ export default {
           })
         }
       });
-    },
+    },1000),
     close() {
       this.$tab.closePage();
     }