SpringBoot實戰開發后臺管理-架構說明和開發
1、架構模式
-
單體架構
-
技術結構
-
springboot + mybatisplus + mysql
-
前端技術:jquery / layui
-
字體圖示庫:iconfont
2、后臺開發的架構模式有哪些?
- 純企業開發(全部由公司自己內部去設計后臺的頁面和功能控制,影片,js、css的撰寫)
- 使用開源一些開發模式 (layui、bootstrap、jui、extjs)等等,這些有什么好處呢?快速和方便,里面提供大量的組件和模塊,比如:日期組件、表格、form、按鈕,彈窗等等 95%,
- 新型的后臺開發模式:vue-admin-element、elementui、antd等都一些基于vue-cli架構提提完成的一種前后端分離的架構模式,(95%)
3、后臺開發的選單導航的渲染的問題
有三種比較程式的模式:
1、基于iframe(比較傳統 異步 + 動態頁面渲染)
2、純異步(全部用js來動態拼接和渲染)(比較傳統 異步 + 動態頁面渲染)
3、基于路由跳轉(vue腳手架)-vue-router
4、選單導航的渲染問題
先要把導航欄進行管理控制
思考問題:導航是在每個頁面中,都需要存在,那么我們可以公共的部分用頁面包含的技術進行剝離,然后用定義的語法,在每個頁面中進行匯入,即可
好處就是:方便我們統一維護和后續的升級和控制,
在freemarker或者jsp或者thymeleaf都有這樣的頁面包含的技術,以thymeleaf為例:
新建一個common在里面新建leftnav.html如下
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
<aside id="asideapp" th:fragment="asidebar"
class="byte-layout-sider byte-layout-sider-light mp-main-sider animated fadeInLeft"
style="width: 246px;">
<div class="byte-layout-sider-children">
<div class="mp-menu-wrapper f-min-scroll f-hover-scroll mp-menu-wrapper-can-scroll">
<div class="byte-menu garr-menu">
<div class="byte-menu-inline base_creation_tab">
<div class="byte-menu-inline-header">
<a href="/admin/index" class="">
<span style="padding-left: 0px; display: block;">
<span title="控制臺" class="ksd-icon-sp iconfont fz20 mr-2 iconhome"></span>
<span>控制臺</span>
</span>
</a>
</div>
<div class="byte-menu-inline-content animated fadeIn"
style="height: auto; display: none;"></div>
</div>
<div class="byte-menu-inline base_creation_tab">
<div class="byte-menu-inline-header">
<a href="javascript:void(0);" class="">
<span style="padding-left: 0px;">
<span title="用戶管理" class="ksd-icon-sp iconfont fz20 mr-2 iconiconzh1"></span>
<span>用戶管理</span>
</span>
<span class="byte-menu-icon-suffix">
<svg viewBox="0 0 1024 1024" width="1em" height="1em" fill="currentColor" class="byte-icon byte-icon-down">
</svg>
</span>
</a>
</div>
<div class="byte-menu-inline-content animated fadeIn" style="display: block;">
<div title="用戶管理" data-href="/admin/user/list" class="byte-menu-item">
<span style="padding-left: 24px; display: block;">
<span class="ksd-icon-sp selected-border-right iconfont fz20 mr-2 iconiconzh1"></span>
<a href="javascript:void(0);">用戶管理</a>
</span>
</div>
<div title="統計模塊" data-href="/admin/state/list" class="byte-menu-item">
<span style="padding-left: 24px; display: block;">
<span class="ksd-icon-sp selected-border-right iconfont fz20 mr-2 iconiconzh1"></span>
<a href="javascript:void(0);">統計模塊</a>
</span>
</div>
</div>
</div>
<div class="byte-menu-inline base_creation_tab">
<div class="byte-menu-inline-header">
<a href="javascript:void(0);" class="">
<span style="padding-left: 0px; display: block;">
<span title="角色管理" class="ksd-icon-sp iconfont fz20 mr-2 iconorder1"></span>
<span>通知管理</span>
</span>
<span class="byte-menu-icon-suffix is-open">
<svg viewBox="0 0 1024 1024" width="1em" height="1em" fill="currentColor" class="byte-icon byte-icon-down">
</svg>
</span>
</a>
</div>
<div class="byte-menu-inline-content animated fadeIn"
style="height: auto; display: none;">
<div title="角色串列" data-href="/admin/permission/list" class="byte-menu-item">
<span style="padding-left: 24px; display: block;">
<span class="ksd-icon-sp selected-border-right iconfont fz20 mr-2 iconorder1"></span>
<a href="javascript:void(0);">角色串列</a>
</span>
</div>
<div title="權限串列" data-href="/admin/role/list" class="byte-menu-item">
<span style="padding-left: 24px; display: block;">
<span class="ksd-icon-sp selected-border-right iconfont fz20 mr-2 iconorder1"></span>
<a href="javascript:void(0);">權限串列</a>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</aside>
</body>
</html>
核心代碼
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
<aside th:fragment="asidebar"></aside>
th:fragment="asidebar"給頁面模板的具體位置取一個名字:asidebar,這個名字在需要包含的頁面中引入:如下
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="0">
<title>后臺管理</title>
<meta name="keywords" content="HTML, CSS, XML, XHTML, JavaScript">
<meta name="description" content="免費的 web 技術教程">
<!-- 后臺公共css js存放檔案頁面包含 -->
<div th:replace="~{commons/header::scriptbar}"></div>
</head>
<body data-ext-version="3.1" style="">
<!-- 頭部選單導航 -->
<div th:replace="~{commons/nav::navbar}"></div>
<!-- 內容區域 -->
<div id="root" class="ksd-main">
<div class="pgc-wrapper pgc-index index-wrapper">
<div class="pgc-content">
<section class=" mp-main-contain byte-layout-has-sider">
<!-- 左側選單導航 -->
<div th:replace="~{commons/leftnav::asidebar}"></div>
<!-- 內容表格 -->
<div id="ksd-mainbox" class="animated fadeIn pr"></div>
</section>
</div>
</div>
</div>
<!-- 底部 -->
<div th:replace="~{commons/footer::footerbar}"></div>
<!-- 頁面腳本 -->
<script th:src="@{/js/admin/index.js}"></script>
</body>
</html>
核心代碼:
<div th:replace="~{commons/leftnav::asidebar}"></div>
th:replace 代表的:就把commons/leftnav.html中的具體代碼塊名字是:th:fragment=“asidebar” 取出來,替換這個div,

$(function () {
// 初始化選單導航
adminAside.init();
// 頁面加載提示
adminLoading.init();
})
// 控制左側選單導航
var adminAside = {
init:function () {
this.animate();
this.menuEvent();
},
// 控制左側選單導航的折疊和展開
animate:function () {
//點擊選單系結點擊事件,然后控制自己下方的選單進行展開和收起
$("#asideapp").find(".byte-menu-inline-header").on("click", function () {
// 控制排它
$(this).parents(".byte-menu-inline").siblings().find(".byte-menu-inline-content").hide();
$(this).parents(".byte-menu-inline").siblings().find(".byte-menu-icon-suffix").removeClass("is-open");
$(this).next().toggle();
$(this).find(".byte-menu-icon-suffix").toggleClass("is-open");
})
},
// 控制選單點擊渲染右側模板
menuEvent:function () {
$("#asideapp").find(".byte-menu-item").on("click", function () {
var href = $(this).data("href");
// $.get(href, function (res) {
// $("#ksd-mainbox").html(res);
// })
$("#ksd-mainbox").load(href);
})
// 觸發第一個元素,作為默認的激活專案
$("#asideapp").find(".byte-menu-item").eq(0).trigger("click");
}
}
// 頁面加載提示
var adminLoading = {
init:function () {
this.animate();
},
animate:function () {
}
}
5、登錄
注意:后臺的開發中處理登錄和退出,是不需要進行登錄,其他的后臺訪問頁面都需要進行登錄攔截才能進行進入,所以我們在做后臺的時候首先考慮的問題之一:登錄攔截
5.1 定義并注冊登錄攔截器
package com.example.config;
import com.example.hander.LoginInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @Auther: 長頸鹿
* @Date: 2021/07/26/16:43
* @Description:
*/
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {
@Bean
public LoginInterceptor getLoginInterceptor() {
return new LoginInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 攔截器注冊
registry.addInterceptor(getLoginInterceptor())
// 排除登錄,退出
.excludePathPatterns("/admin/login",
"/admin/logout",
"/admin/toLogin")
// 攔截后臺所有請求
.addPathPatterns("/admin/**");
}
}
5.2 在攔截器中排除登錄和退出的路由
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 攔截器注冊
registry.addInterceptor(getLoginInterceptor())
// 排除登錄,退出
.excludePathPatterns("/admin/login",
"/admin/logout",
"/admin/toLogin")
// 攔截后臺所有請求
.addPathPatterns("/admin/**");
}
5.3 已登錄,跳轉到首頁
package com.example.controller;
import com.example.common.constant.RConstants;
import com.example.common.exception.ResultCodeEnum;
import com.example.common.exception.ValidationException;
import com.example.entity.User;
import com.example.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpSession;
/**
* @Auther: 長頸鹿
* @Date: 2021/07/25/11:07
* @Description:
*/
@Controller
@Slf4j
public class LoginController extends BaseController {
@Autowired
private UserService userService;
@GetMapping("/login")
public String login(HttpSession session){
// 首先判斷一下,用戶是否已經登錄
User sessionUser = (User) session.getAttribute(RConstants.SESSION_USER);
// 如果已經登錄就直接進入到首頁
if (sessionUser != null) {
return "redirect:/admin/index";
}
// 如果沒有登錄,直接去登錄頁面
return "login";
}
@PostMapping("/toLogin")
@ResponseBody
public String toLogin(HttpSession session, String nickname, String password){
log.info("當前用戶:{},密碼:{}", nickname, password);
// 根據用戶輸入的nickname,查詢用戶是否存在
User user = userService.getByUserName(nickname);
// 如果不存在就回傳fail,代表用戶找不到
if(user == null){
throw new ValidationException(ResultCodeEnum.NICKNAME_NO_EXISTENCE);
}
// 判斷當前用戶輸入的密碼和資料庫密碼是否一致, 如果一致 登錄成功
if (user != null && !user.getPassword().equalsIgnoreCase(password)) {
throw new ValidationException(ResultCodeEnum.PASSWORD_ERROR);
}
// 把登錄成功用戶資訊寫入session會話中
session.setAttribute(RConstants.SESSION_USER, user);
// 登錄成功回傳success
return "success";
}
}
5.4、退出登錄
@GetMapping("/logout")
public String logout(HttpSession session){
// 退出登錄
session.invalidate();
// 退出成功已經,重定向到登錄頁面
return "redirect:/admin/login";
}
<a th:href="@{/admin/logout}" style="width: 86px;"><i class="iconfont iconai-out"></i>退出登錄</a>
5.5、登錄頁面背景設定
.bgpic{
background:url("xxxx.jpg");
position:fixed;
top:0;
left:0;
bottom:0;
right:0;
filter:blur(1px);
background-size:cover;
}
6、完成串列查詢,搜索,分頁
6.1 分頁攔截器的配置
package com.example.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* @Auther: 長頸鹿
* @Date: 2021/07/30/14:53
* @Description:
*/
@Configuration
@EnableTransactionManagement
public class MyBatisPlusConfig {
// 分頁插件
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
6.2 定義分頁邏輯
package com.example.controller.state;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.controller.common.BaseController;
import com.example.entity.State;
import com.example.service.state.StateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
* @Auther: 長頸鹿
* @Date: 2021/07/28/15:27
* @Description:
*/
@Controller
public class StateController extends BaseController {
@Autowired
private StateService stateService;
@GetMapping("state/list")
public String list(ModelMap modelMap){
Page<State> pageState = stateService.pageList(0, 10);
// 2: 把資料放入到作用域
// 每頁顯示的具體資料
modelMap.put("stateList", pageState.getRecords());
// 總記錄數
modelMap.put("total", pageState.getTotal());
//pageSize是每頁顯示多少條
modelMap.put("pageSize", pageState.getSize());
// pageNo 當前頁
modelMap.put("pageNo", pageState.getCurrent());
// pages分了多少頁
modelMap.put("pages", pageState.getPages());
// 3: 渲染的視圖模板
return "state/template";
}
@GetMapping("state/listTemplate")
public String listTemplate(ModelMap modelMap, @RequestParam(name = "pageNo", defaultValue = "1")Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10")Integer pageSize){
Page<State> pageState = stateService.pageList(pageNo,pageSize);
// 2: 把資料放入到作用域
// 每頁顯示的具體資料
modelMap.put("stateList", pageState.getRecords());
// 總記錄數
modelMap.put("total", pageState.getTotal());
//pageSize是每頁顯示多少條
modelMap.put("pageSize", pageState.getSize());
// pageNo 當前頁
modelMap.put("pageNo", pageState.getCurrent());
// pages分了多少頁
modelMap.put("pages", pageState.getPages());
// 3: 渲染的視圖模板
return "state/listTemplate";
}
}
package com.example.service.state;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.entity.State;
import com.example.mapper.StateMapper;
import org.springframework.stereotype.Service;
/**
* @Auther: 長頸鹿
* @Date: 2021/07/30/13:33
* @Description:
*/
@Service
public class StateServiceImpl extends ServiceImpl<StateMapper, State> implements StateService {
@Override
public Page<State> pageList(int pageNo, int pageSize) {
Page<State> page = new Page<>(pageNo, pageSize);
// 查詢分頁
QueryWrapper<State> queryWrapper = new QueryWrapper<>();
Page<State> pageState = this.page(page, queryWrapper);
return pageState;
}
}
package com.example.service.state;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.entity.State;
/**
* @Auther: 長頸鹿
* @Date: 2021/07/30/13:32
* @Description:
*/
public interface StateService extends IService<State> {
Page<State> pageList(int pageNo, int pageSize);
}
6.3 頁面初始化分頁
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
<main id="appbox" class="byte-layout-content garr-container" style="background: rgb(255, 255, 255);">
<div class="layui-tab-item layui-show">
<div id="LAY_preview">
<div class="layui-border-box">
<div class="layui-table-tool">
<span class="mr-4 fl">共 11 條</span>
<div class="layui-table-tool-selfc ml-2 fr">
<a href="https://www.kuangstudy.com/bbs" target="_blank" class="layui-btn layui-btn-sm">
<span class="iconfont iconhome mr-2 fz12"></span>
訪問首頁
</a>
</div>
<div class="layui-table-tool-selfc ml-2 fr">
<button class="layui-btn layui-btn-sm">
<i class="iconfont iconadd mr-2"></i>
添加一級分類
</button>
</div>
<div class="layui-table-tool-selfc fr">
<div class="layui-inline">
<input title="敲enter鍵盤也可以搜索!" maxlength="100" autocomplete="off"
placeholder="請輸入分類標題..." class="layui-input" style="width: 320px; height: 32px; line-height: 32px;">
</div>
<button class="layui-btn layui-btn-sm">搜索</button>
</div>
</div>
</div>
<div class="layui-table-box">
<div class="layui-table-body layui-table-main">
<table cellspacing="0" cellpadding="0" border="0" class="layui-table">
<thead>
<tr>
<th class="layui-table-col-special">
<div class="layui-table-cell laytable-cell-numbers">
<span>ID</span>
</div>
</th>
<th>
<div class="layui-table-cell"><span>標題</span></div>
</th>
<th>
<div class="layui-table-cell"><span>參與人數</span></div>
</th>
<th>
<div class="layui-table-cell"><span>創建時間</span></div>
</th>
<th>
<div class="layui-table-cell"><span>創建用戶</span></div>
</th>
<th>
<div class="layui-table-cell"><span>狀態</span></div>
</th>
<th>
<div class="layui-table-cell"><span>操作</span></div>
</th>
</tr>
</thead>
<tbody id="state-tbody" th:data-total="${total}" th:data-pages="${pages}"
th:data-pageSize="${pageSize}">
<div th:replace="~{state/listTemplate::stateList}"></div>
</tbody>
</table>
</div>
<!-- 翻頁 -->
<div class="layui-table-page" id="state-page" style="height: 60px; text-align: center; margin-top: 50px;"></div>
</div>
</div>
</div>
<script>
// 1:如何初始化,然后并且獲取每次點擊的頁碼
// 2:如何根據分頁查詢對應的資料,把對應的資料查詢出來回傳的指定的位置
var state = {
page:function (total) {
var that = this;
layui.use(['laypage', 'layer'], function() {
var layPage = layui.laypage
, layer = layui.layer;
//總頁數大于頁碼總數
layPage.render({
elem: 'state-page'
, count: total //資料總數
, jump: function (obj) {
// 獲取當前用戶點擊當前頁
var currentPageNo = obj.curr;
// if(currentPageNo > 1){
// 點擊每頁渲染的資料
that.loadData(currentPageNo);
// }
}
});
});
},
// 加載后臺資料
// loadData:function (pageNo) {
// $.get("/admin/state/listTemplate", {pageNo:pageNo}, function (res) {
// // 找到第二頁渲染完畢的tbody的內容
// var tbodyHtml = $(res).find("#state-tbody").html();
// // 把找到的內容放入當前的tbody中
// $("#state-tbody").html(tbodyHtml);
// })
// }
loadData:function(pageNo){
$.get("/admin/state/listTemplate",{pageNo:pageNo},function(res){
$("#state-tbody").html(res);
})
}
};
$(function () {
// 獲取總記錄數
var total = $("#state-tbody").data("total");
// 根據total初始化分頁
state.page(total);
})
</script>
</main>
</body>
</html>
核心代碼
<tbody id="ksd-tbody" th:data-total="${total}" th:data-pages="${pages}">
1、上面的代碼是通過thymeleaf的模板渲染技術,把后臺作用域中的資料取出來,
// 每頁顯示的具體資料
modelMap.put("stateList", pageState.getRecords());
// 總記錄數
modelMap.put("total", pageState.getTotal());
//pageSize是每頁顯示多少條
modelMap.put("pageSize", pageState.getSize());
// pageNo 當前頁
modelMap.put("pageNo", pageState.getCurrent());
// pages分了多少頁
modelMap.put("pages", pageState.getPages());
2、然后通過ajax渲染到左側位置,然后在加載JS,通過jQuery的data語法去重總記錄數,然后初始化分頁即可,
// 當前所有的節點,不包括image和iframe加載完畢,立即觸發的入口函式
$(function(){
// 1、把總記錄數從ksd-tbody屬性上取出來
var total = $("#ksd-tbody").data("total");
// 2、根據total初始化分頁即可
ksdState.page(total);
})
核心代碼
<tbody id="ksd-tbody" th:data-total="${total}" th:data-pages="${pages}">
1、上面的代碼是通過thymeleaf的模板渲染技術,把后臺作用域中的資料取出來,
// 每頁顯示的具體資料
modelMap.put("stateList", pageState.getRecords());
// 總記錄數
modelMap.put("total", pageState.getTotal());
//pageSize是每頁顯示多少條
modelMap.put("pageSize", pageState.getSize());
// pageNo 當前頁
modelMap.put("pageNo", pageState.getCurrent());
// pages分了多少頁
modelMap.put("pages", pageState.getPages());
2、然后通過ajax渲染到左側位置,然后在加載JS,通過jQuery的data語法去重總記錄數,然后初始化分頁即可,
// 當前所有的節點,不包括image和iframe加載完畢,立即觸發的入口函式
$(function(){
// 1、把總記錄數從ksd-tbody屬性上取出來
var total = $("#ksd-tbody").data("total");
// 2、根據total初始化分頁即可
ksdState.page(total);
})
7、洗掉
7.1 實作資料的洗掉
洗掉邏輯一般都是根據主鍵id進行處理和洗掉,洗掉分為邏輯洗掉和物理洗掉,
- 一般開發中一般都是邏輯洗掉,執行的是 :update修改表的狀態,定義欄位is_delete 0代表未洗掉 1 洗掉
- 物理洗掉,直接把表的資料直接刪掉,執行:delete from table where id = xxx
7.2 layui組件的引入
-
下載layui組件:https://www.layui.com/
-
把下載的layui組件解壓到專案的static目錄
-
在header.html頁面引入layui.js
-
<script th:fragment="scriptbar" src="../js/jquery-3.5.1.min.js"></script> <script th:fragment="scriptbar" src="../layui/layui.js"></script> -
使用layui即可
https://www.layui.com/demo/
7.3 后臺邏輯方法(物理洗掉)
@ResponseBody
@PostMapping("state/delete/{id}")
public int deleteState(@PathVariable("id")Integer id){
boolean flag = stateService.removeById(id);
return flag ? 1 : 0;
}
delete:function () {
var mainThat = this;
$("#state-tbody").on("click", ".state-delete-btn", function () {
var that = this; // that代表當前你點擊的每一個洗掉按鈕
// 拿到快取的資料id
var opId = $(this).data("opid");
// 發送異步請求
$.post("/admin/state/delete/"+opId, function (res) {
if(res.code == 200){
// 洗掉成功進行異步洗掉 $(that).parents("tr") 獲取當前洗掉按鈕的所在的tr行
$(that).parents("tr").fadeOut("slow", function () {
// $(this) 這個代表的當前行tr,洗掉當前行
$(this).remove();
// 洗掉一行,總數就減去1次
var total = $("#state-tbody").data("total");
var newTotal = total-1;
$("#state-tbody").data("total",newTotal);
$(".state-total-num").text(newTotal);
// 如果當前頁面的資料已經全部洗掉完畢
var length = $("#state-tbody").children().length;
if(length == 0){
// 重新加載資料
mainThat.page(newTotal);
}
})
}
})
})
}
7.4 layui組件的引入和洗掉邏輯的融合
@ResponseBody
@PostMapping("state/update/{id}")
public int updateState(@PathVariable("id")Integer id){
State state = stateService.getById(id);
if(state != null && state.getIsDelete().equals(0)){
state.setIsDelete(1);
}else if(state != null && state.getIsDelete().equals(1)){
state.setIsDelete(0);
}
System.out.println(state.getIsDelete());
boolean flag = stateService.updateById(state);
System.out.println(state.getIsDelete());
return flag ? state.getIsDelete() : 0;
}
delete:function () {
var mainThat = this;
$("#state-tbody").on("click", ".state-delete-btn", function () {
var that = this; // that代表當前你點擊的每一個洗掉按鈕
// 拿到快取的資料id
var opId = $(this).data("opid");
// 發送異步請求
layui.use('layer', function(){
var layer = layui.layer;
layer.confirm('確定洗掉?', {
btn: ['確定','取消'] //按鈕
}, function(){
// 發送洗掉異步請求
$.post("/admin/state/update/" + opId,function(res){
if(res.code == 200){
layer.msg('洗掉成功');
if(res.data == 1) {
$(that).parents("tr").find(".state-isDelete").removeClass("green").addClass("red").text("已洗掉");
}else{
$(that).parents("tr").find(".state-isDelete").removeClass("red").addClass("green").text("未洗掉");
}
}
});
}, function(){
layer.msg('這個是取消按鈕事件');
});
});
})
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/291326.html
標籤:其他
上一篇:JavaScript基礎大總結
