從零開始實現放置遊戲(四)——實現掛機戰鬥(2)實現後臺數值配置

丶謙信發表於2019-06-19

  上一章我們將RMS後臺管理系統搭建完畢,本章我們就在這個系統上實現錄入遊戲配置的功能。目前我們需要配置四項,每個等級的人物屬性,每個等級的升級經驗,遊戲地圖,地圖中的怪物。下面我們以遊戲地圖配置為例子,實現對它的增刪查改功能。

一、資料訪問層的實現

  首先,我們需要定義地圖類,這個類在各個模組通用,因此要定義在facade模組中。我們新建一個包com.idlewow.map.model,在其中新建WowMap類,程式碼如下:

package com.idlewow.map.model;

import com.idlewow.common.model.BaseModel;
import lombok.Data;

import java.io.Serializable;

@Data
public class WowMap extends BaseModel implements Serializable {
    private String name;
    private Integer occupy;
    private String description;
}

  然後,我們在core模組中實現資料訪問層的邏輯。新建com.idlewow.map.mapper包,並新建一個介面類WowMapMapper,在介面中定義我們需要用到的一些增刪查改方法,程式碼如下:

package com.idlewow.map.mapper;

import com.idlewow.map.model.WowMap;
import com.idlewow.query.model.WowMapQueryParam;

import java.util.List;

public interface WowMapMapper {
    int insert(WowMap wowMap);

    int batchInsert(List<WowMap> list);

    int update(WowMap levelProp);

    int delete(String id);

    WowMap find(String id);

    List<WowMap> list(WowMapQueryParam queryParam);

    int count(WowMapQueryParam queryParam);
}

  Mapper介面類,只定義了方法,具體實現需要我們在該包下新建一個WowMapMapper.xml檔案,在這個檔案中,通過SQL語句實現介面中的方法:

<?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.idlewow.map.mapper.WowMapMapper">
    <resultMap id="BaseResultMap" type="com.idlewow.map.model.WowMap">
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="occupy" property="occupy"/>
        <result column="description" property="description"/>
        <result column="create_user" property="createUser"/>
        <result column="update_user" property="updateUser"/>
        <result column="create_time" property="createTime"/>
        <result column="update_time" property="updateTime"/>
        <result column="is_delete" property="isDelete"/>
        <result column="version" property="version"/>
    </resultMap>
    <!-- 新增 -->
    <insert id="insert">
        insert into map (name, occupy, description, create_user)
        values (#{name}, #{occupy}, #{description}, #{createUser})
    </insert>
    <!-- 批量新增 -->
    <insert id="batchInsert">
        insert into map (name, occupy, description, create_user)
        values
        <foreach collection="list" item="item" separator=",">
            (#{item.name}, #{item.occupy}, #{item.description}, #{item.createUser})
        </foreach>
    </insert>
    <!-- 修改 -->
    <update id="update">
        update map
        set name = #{name},
            occupy = #{occupy},
            description = #{description},
            update_user = #{updateUser},
            version = version + 1
        where id = #{id} and is_delete = 0
    </update>
    <!-- 刪除 -->
    <update id="delete" parameterType="String">
        update map
        set is_delete = 1
        where id = #{id}
    </update>
    <!-- id查詢 -->
    <select id="find" resultMap="BaseResultMap">
        select *
        from map
        where id = #{id} and is_delete = 0
    </select>
    <!-- 列表查詢總數 -->
    <select id="count" resultType="int">
        select count(1)
        from map
        <where>
            is_delete = 0
            <if test="name != null and name != ''">
                and name like concat('%', #{name}, '%')
            </if>
        </where>
    </select>
    <!-- 列表查詢 -->
    <select id="list" resultMap="BaseResultMap">
        select *
        from map
        <where>
            is_delete = 0
            <if test="name != null and name != ''">
                and name like concat('%', #{name}, '%')
            </if>
        </where>
        <if test="pageParam != null">
            limit ${(pageParam.pageIndex - 1) * pageParam.pageSize}, ${pageParam.pageSize}
        </if>
    </select>
</mapper>
WowMapMapper.xml

  最後,我們新建com.idlewow.map.manager包,新建一個類WowMapManager,此類通過呼叫mapper來實現具體業務:

package com.idlewow.map.manager;

import com.idlewow.common.model.PageList;
import com.idlewow.map.mapper.WowMapMapper;
import com.idlewow.map.model.WowMap;
import com.idlewow.query.model.WowMapQueryParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class WowMapManager {
    @Autowired
    WowMapMapper wowMapMapper;

    public void insert(WowMap wowMap) {
        int effected = wowMapMapper.insert(wowMap);
        if (effected == 0) {
            throw new RuntimeException("sql effected 0 rows");
        }
    }

    public void batchInsert(List<WowMap> list) {
        int splitSize = 100;
        int index = 0;
        int total = list.size();
        while (index <= total) {
            int end = index + splitSize;
            if (end > total) {
                end = total;
            }

            List<WowMap> sublist = list.subList(index, end);
            int effected = wowMapMapper.batchInsert(sublist);
            if (effected == 0) {
                throw new RuntimeException("sql effected 0 rows");
            }

            index += splitSize;
        }
    }

    public void update(WowMap t) {
        int effected = wowMapMapper.update(t);
        if (effected == 0) {
            throw new RuntimeException("sql effected 0 rows");
        }
    }

    public void delete(String id) {
        int effected = wowMapMapper.delete(id);
        if (effected == 0) {
            throw new RuntimeException("sql effected 0 rows");
        }
    }

    public WowMap find(String id) {
        WowMap wowMap = wowMapMapper.find(id);
        return wowMap;
    }

    public PageList<WowMap> list(WowMapQueryParam queryParam) {
        PageList<WowMap> pageList = new PageList<WowMap>();
        int count = wowMapMapper.count(queryParam);
        List<WowMap> list = wowMapMapper.list(queryParam);
        pageList.setTotalCount(count);
        pageList.setData(list);
        pageList.setPageParam(queryParam.getPageParam());
        return pageList;
    }
}

  另外,@Componet註解需要依賴spring-context包。還有我們寫SQL的xml檔案是資原始檔,但為了方便檢視編輯,我們直接把它放在了程式碼目錄下,所以編譯的時候不會被打包,需要在pom中新增配置如下:

    </dependencies>
        ........
        ........
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.6.RELEASE</version>
        </dependency>
    </dependencies>
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>

  這樣,我們的資料訪問層邏輯就全部實現了。通過在RMS模組的controller中注入manager,即可實現對底層資料的訪問。

二、controller層的實現

  在com.idlewow.rms.controller包中,新建類MapController,在Contoller中,我們初步實現了對資料的增刪查改。注意,這裡list()方法,返回的字串“/manage/map/list",代表檢視所在路徑,根據spring-mvc.xml中配置的檢視路由解析規則,即返回/WEB-INF/views/manage/map/list.jsp頁面。但如果在該方法上加上註解@ResponseBody,則代表直接返回該字串,不會去尋找檢視。在post方法中,我們就是直接返回資料的json串。程式碼如下:

package com.idlewow.rms.controller;

import com.idlewow.common.model.CommonResult;
import com.idlewow.common.model.PageList;
import com.idlewow.map.manager.WowMapManager;
import com.idlewow.map.model.WowMap;
import com.idlewow.query.model.WowMapQueryParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;


@Controller
@RequestMapping("/manage/map")
public class MapController extends BaseController {
    @Autowired
    WowMapManager wowMapManager;

    @RequestMapping("/list")
    public Object list() {
        return "/manage/map/list";
    }

    @ResponseBody
    @RequestMapping(value = "/list", method = RequestMethod.POST)
    public Object list(@RequestParam(value = "page", defaultValue = "1") int pageIndex, @RequestParam(value = "limit", defaultValue = "10") int pageSize, WowMapQueryParam queryParam) {
        queryParam.setPage(pageIndex, pageSize);
        PageList<WowMap> pageList = wowMapManager.list(queryParam);
        return this.parseTable(pageList);
    }

    @RequestMapping("/add")
    public Object add() {
        return "/manage/map/add";
    }

    @ResponseBody
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public Object add(@RequestBody WowMap wowMap) {
        try {
            wowMap.setCreateUser(this.currentUserName());
            wowMapManager.insert(wowMap);
            return CommonResult.success();
        } catch (Exception ex) {
            return CommonResult.fail();
        }
    }

    @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
    public Object edit(@PathVariable String id, Model model) {
        WowMap wowMap = wowMapManager.find(id);
        model.addAttribute(wowMap);
        return "/manage/map/edit";
    }

    @ResponseBody
    @RequestMapping(value = "/edit/{id}", method = RequestMethod.POST)
    public Object edit(@PathVariable String id, @RequestBody WowMap wowMap) {
        try {
            if (!id.equals(wowMap.getId())) {
                return CommonResult.fail("id不一致");
            }

            wowMap.setUpdateUser(this.currentUserName());
            wowMapManager.update(wowMap);
            return CommonResult.success();
        } catch (Exception ex) {
            return CommonResult.fail();
        }
    }

    @ResponseBody
    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
    public Object delete(@PathVariable String id) {
        try {
            wowMapManager.delete(id);
            return CommonResult.success();
        } catch (Exception ex) {
            return CommonResult.fail();
        }
    }
}
MapController.java

  其中, CommonResult類是我定義的一個通用的結果返回類,PageList和PageParam是分頁相關的輔助類,WowMapQueryParam是列表查詢的引數類。

  另外,前端列表展示使用了layui的datatable,需要給他返回對應的資料結構。因此,我們定義一個抽象類BaseController,實現對列表資料結構的轉換,同時提供查詢當前登入使用者的方法。其他的Controller如無特殊情況均繼承BaseController,程式碼如下:

package com.idlewow.rms.vo;

import lombok.Data;

import java.io.Serializable;
import java.util.List;

@Data
public class LayuiDataTable<T> implements Serializable {
    private Integer code;
    private String message;
    private Integer count;
    private List<T> data;
}
LayuiDataTable.java
package com.idlewow.rms.controller;

import com.idlewow.admin.model.SysAdmin;
import com.idlewow.common.model.PageList;
import com.idlewow.rms.vo.LayuiDataTable;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpSession;

public abstract class BaseController {
    private static final String LoginUserKey = "loginuser";
    @Autowired
    protected HttpSession httpSession;

    protected SysAdmin currentUser() {
        return (SysAdmin) httpSession.getAttribute(LoginUserKey);
    }

    protected String currentUserName() {
        return this.currentUser().getUsername();
    }

    protected LayuiDataTable parseTable(PageList pageList) {
        LayuiDataTable dataTable = new LayuiDataTable();
        dataTable.setMessage("讀取成功");
        dataTable.setCode(0);
        dataTable.setCount(pageList.getTotalCount());
        dataTable.setData(pageList.getData());
        return dataTable;
    }
}
BaseController.java

  寫完控制器,前端頁面,我們直接套用x-admin的模板。在/WEB-INF/views/manage/map目錄下,建立頁面:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="/authorize.jsp" %>
<!DOCTYPE html>
<html class="x-admin-sm">
<head>
    <meta charset="UTF-8">
    <title>地圖管理</title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport"
          content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi"/>
    <link rel="stylesheet" href="<%=path%>/css/font.css">
    <link rel="stylesheet" href="<%=path%>/css/xadmin.css">
    <script type="text/javascript" src="<%=path%>/lib/layui/layui.js" charset="utf-8"></script>
    <script type="text/javascript" src="<%=path%>/js/xadmin.js"></script>
</head>
<body>
<div class="x-nav">
          <span class="layui-breadcrumb">
            <a href="">首頁</a>
            <a href="">後臺管理</a>
            <a>
              <cite>地圖</cite></a>
          </span>
    <a class="layui-btn layui-btn-small" style="line-height:1.6em;margin-top:3px;float:right"
       onclick="location.reload()" title="重新整理">
        <i class="layui-icon layui-icon-refresh" style="line-height:30px"></i></a>
</div>
<div class="layui-fluid">
    <div class="layui-row layui-col-space15">
        <div class="layui-col-md12">
            <div class="layui-card">
                <div class="layui-card-body ">
                    <form id="queryForm" class="layui-form layui-col-space5" method="post">
                        <div class="layui-inline layui-show-xs-block">
                            <input type="text" name="name" placeholder="請輸入地圖名稱" autocomplete="off" class="layui-input">
                        </div>
                        <div class="layui-inline layui-show-xs-block">
                            <button class="layui-btn" lay-submit lay-filter="search" type="button" onclick="search();">
                                <i class="layui-icon">&#xe615;</i>查詢
                            </button>
                        </div>
                        <div class="layui-inline layui-show-xs-block">
                            <button class="layui-btn" type="button" onclick="reset();"> 重置</button>
                        </div>
                        <div class="layui-inline layui-show-xs-block">
                            <button type="button" class="layui-btn" onclick="xadmin.open('新增地圖','add',500,500)">
                                <i class="layui-icon"></i>新增地圖
                            </button>
                        </div>
                        <div class="layui-upload layui-inline layui-show-xs-block">
                            <button type="button" class="layui-btn layui-btn-normal" id="btnSelectFile">選擇Excel</button>
                            <button type="button" class="layui-btn" id="btnImport">開始匯入</button>
                        </div>
                    </form>
                </div>
                <div class="layui-card-body ">
                    <table class="layui-table layui-form" id="datatable"></table>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
<script type="text/javascript" src="<%=path%>/js/helper.js?v=0530"></script>
<script type="text/javascript" src="<%=path%>/js/wow/manage/map/list.js?v=0530"></script>
</html>
list.jsp
<%@ page import="com.idlewow.rms.util.DropDownUtil" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="/authorize.jsp" %>
<!DOCTYPE html>
<html class="x-admin-sm">
<head>
    <meta charset="UTF-8">
    <title>編輯地圖</title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport"
          content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi"/>
    <link rel="stylesheet" href="<%=path%>/css/font.css">
    <link rel="stylesheet" href="<%=path%>/css/xadmin.css">
    <script type="text/javascript" src="<%=path%>/lib/layui/layui.js" charset="utf-8"></script>
    <script type="text/javascript" src="<%=path%>/js/xadmin.js"></script>
</head>
<body>
<div class="layui-fluid">
    <div class="layui-row">
        <form:form class="layui-form" method="post" modelAttribute="wowMap">
            <form:hidden path="id"/>
            <div class="layui-form-item">
                <form:label path="name" class="layui-form-label"> <span class="x-red">*</span>地圖名稱 </form:label>
                <div class="layui-input-inline">
                    <form:input path="name" lay-verify="required" autocomplete="off" class="layui-input"/>
                </div>
            </div>
            <div class="layui-form-item">
                <form:label path="occupy" class="layui-form-label"> <span class="x-red">*</span>領土歸屬 </form:label>
                <div class="layui-input-inline">
                    <form:select path="occupy" items="<%= DropDownUtil.OccupyMap %>"></form:select>
                </div>
            </div>
            <div class="layui-form-item">
                <form:label path="description" class="layui-form-label"> 地圖描述 </form:label>
                <div class="layui-input-inline">
                    <form:textarea path="description" class="layui-textarea"></form:textarea>
                </div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label"></label>
                <div class="layui-input-inline">
                    <button class="layui-btn" lay-filter="edit" lay-submit type="button">修改</button>
                </div>
            </div>
        </form:form>
    </div>
</div>
<script type="text/javascript" src="<%=path%>/js/helper.js?v=0531"></script>
<script type="text/javascript" src="<%=path%>/js/wow/manage/map/edit.js?v=0510"></script>
</body>
</html>
edit.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="com.idlewow.rms.util.DropDownUtil" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="/authorize.jsp" %>
<!DOCTYPE html>
<html class="x-admin-sm">
<head>
    <meta charset="UTF-8">
    <title>新增地圖</title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport"
          content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi"/>
    <link rel="stylesheet" href="<%=path%>/css/font.css">
    <link rel="stylesheet" href="<%=path%>/css/xadmin.css">
    <script type="text/javascript" src="<%=path%>/lib/layui/layui.js" charset="utf-8"></script>
    <script type="text/javascript" src="<%=path%>/js/xadmin.js"></script>
</head>
<body>
<div class="layui-fluid">
    <div class="layui-row">
        <form class="layui-form" method="post">
            <div class="layui-form-item">
                <label for="name" class="layui-form-label"> <span class="x-red">*</span>地圖名稱 </label>
                <div class="layui-input-inline">
                    <input type="text" id="name" name="name" required lay-verify="required"
                           autocomplete="off" class="layui-input">
                </div>
            </div>
            <div class="layui-form-item">
                <label for="occupy" class="layui-form-label"> <span class="x-red">*</span>領土歸屬 </label>
                <div class="layui-input-inline">
                    <% request.setAttribute("occupyMap", DropDownUtil.OccupyMap); %>
                    <select name="occupy" id="occupy">
                        <option value="">請選擇領土歸屬</option>
                        <c:forEach items="${occupyMap}" var="item">
                            <option value="${item.key}">${item.value}</option>
                        </c:forEach>
                    </select>
                </div>
            </div>
            <div class="layui-form-item">
                <label for="description" class="layui-form-label"> 地圖描述 </label>
                <div class="layui-input-inline">
                    <textarea name="description" id="description" class="layui-textarea"></textarea>
                </div>
            </div>
            <div class="layui-form-item">
                <label class="layui-form-label"></label>
                <div class="layui-input-inline">
                    <button class="layui-btn" lay-filter="add" lay-submit type="button">新增</button>
                </div>
            </div>
        </form>
    </div>
</div>
<script type="text/javascript" src="<%=path%>/js/helper.js?v=0531"></script>
<script type="text/javascript" src="<%=path%>/js/wow/manage/map/add.js?v=0531"></script>
</body>
</html>
add.jsp

  在/js/wow/manage/map目錄下,建立相應的js指令碼:

layui.use(['upload', 'table', 'form'], function () {
    var table = layui.table;
    table.render({
        elem: '#datatable'
        , url: '/manage/map/list'
        , method: 'post'
        , cellMinWidth: 80
        , cols: [[
            {field: 'id', width: 50, title: 'id'}
            , {field: 'name', title: '地圖名稱'}
            , {
                field: 'occupy', title: '領土歸屬', templet: function (d) {
                    return enumUtil.occupyImage(d.occupy) + enumUtil.occupy(d.occupy);
                }
            }
            , {
                title: '操作', templet: function (d) {
                    return '<button class="layui-btn layui-btn-xs"  onclick="xadmin.open(\'編輯地圖\',\'edit/' + d.id + '\', 500, 500)" type="button"><i class="layui-icon">&#xe642;</i>編輯</button>' +
                        '<button class="layui-btn-danger layui-btn layui-btn-xs"  onclick="remove(this, \'' + d.id + '\')" type="button"><i class="layui-icon">&#xe640;</i>刪除</button>';
                }
            }
        ]]
        , page: {
            layout: ['limit', 'count', 'prev', 'page', 'next', 'skip'] //自定義分頁佈局
            , limits: [10, 20, 30, 40, 50]
            , groups: 3 //只顯示 1 個連續頁碼
            , first: '首頁'
            , last: '尾頁'
        }
    });
});

function search() {
    var table = layui.table;
    table.reload('datatable', {
        where: {
            name: $('input[name="name"]').val()
        },
        page: {
            curr: 1
        }
    });
}

function reset(){
    $('#queryForm').reset();
}

function remove(obj, id) {
    layer.confirm('確認要刪除嗎?', function () {
        $.ajax({
            url: '/manage/map/delete/' + id,
            type: 'post',
            success: function (result) {
                if (result.code === 1) {
                    $(obj).parents("tr").remove();
                    layer.msg('刪除成功', {icon: 1, time: 1000});
                } else {
                    layer.alert("刪除失敗", {icon: 5});
                }
            },
            error: function () {
                layer.alert("請求失敗", {icon: 5});
            }
        });
    });
}
list.js
layui.use(['form', 'layer'],
    function () {
        var form = layui.form;
        form.render();
        form.verify({});
        form.on('submit(edit)',
            function (data) {
                $.ajax({
                    url: '/manage/map/edit/' + data.field.id,
                    type: 'post',
                    contentType: "application/json; charset=utf-8",
                    data: JSON.stringify(data.field),
                    success: function (result) {
                        if (result.code === 1) {
                            layer.alert(result.message, {icon: 6},
                                function () {
                                    xadmin.close();
                                    xadmin.father_reload();
                                });
                        } else {
                            layer.alert(result.message, {icon: 5});
                        }
                    },
                    error: function () {
                        layer.alert("請求失敗", {icon: 5});
                    }
                });
            });
    });
edit.js
layui.use(['form', 'layer'],
    function () {
        var form = layui.form;
        form.verify({});
        form.on('submit(add)',
            function (data) {
                $.ajax({
                    url: '/manage/map/add',
                    type: 'post',
                    contentType: "application/json; charset=utf-8",
                    data: JSON.stringify(data.field),
                    success: function (result) {
                        if (result.code === 1) {
                            layer.alert(result.message, {icon: 6},
                                function () {
                                    xadmin.close();
                                    xadmin.father_reload();
                                });
                        } else {
                            layer.alert(result.message, {icon: 5});
                        }
                    },
                    error: function () {
                        layer.alert("請求失敗", {icon: 5});
                    }
                });
            });
    });
add.js

三、專案啟動

  本次,我們修改了facade和core專案,這兩個專案是作為jar包被rms模組引用的,因此必須先將其編譯打包,這裡我們用第(二)章定義的打包命令直接將整個專案重新打包。以後凡是jar包專案有改動,我們啟動web專案前,都先重新打包一遍。

  另外,maven的編譯外掛可能預設的jdk版本是1.5,我們在pom中配置一下,配成1.8,配置如下:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            
            …………
            …………
        </plugins>
    </build>

  OK,全部搞定之後,我們執行一下,看下效果:

  

 

小結

  本章,我們初步實現了後臺管理系統資料配置的增刪查改,但還有很多功能不完善。

  比如,新增、編輯時的資料沒有進行校驗;單個錄入資料太麻煩,想要通過excel批量錄入;出現異常時缺乏相應的日誌記錄,等等。

  這些內容,我們都將在後面的章節中持續完善。

  本章原始碼下載地址:https://idlestudio.ctfile.com/fs/14960372-383560985

 

歡迎1元催更

相關文章