shiro、springboot、vue、elementUI CDN模式前後端分離的許可權管理demo 附源碼

来源:https://www.cnblogs.com/nqdxt/archive/2023/02/09/17106980.html
-Advertisement-
Play Games

源碼下載地址 https://github.com/Aizhuxueliang/springboot_shiro.git 前提你電腦的安裝好這些工具:jdk8、idea、maven、git、mysql; shiro的主要概念 Shiro是一個強大的簡單易用的Java安全框架,主要用來更便捷的認證、授 ...


源碼下載地址

https://github.com/Aizhuxueliang/springboot_shiro.git
open

前提你電腦的安裝好這些工具:jdk8、idea、maven、git、mysql

shiro的主要概念

  1. Shiro是一個強大的簡單易用的Java安全框架,主要用來更便捷的認證、授權、加密、會話管理、與Web集成、緩存等;
  2. Shiro使用起來小而簡單;
  3. spring中有spring security ,是一個許可權框架,它和spring依賴過於緊密,沒有shiro使用簡單;
  4. shiro不依賴於spring,shiro不僅可以實現web應用的許可權管理,還可以實現c/s系統,分散式系統許可權管理;

在應用程式角度來觀察如何使用Shiro完成工作

subject

Subject:主體,代表了當前“用戶”,這個用戶不一定是一個具體的人,與當前應用交互的任何東西都是Subject,如網路爬蟲,機器人等;即一個抽象概念;所有Subject 都綁定到SecurityManager,與Subject的所有交互都會委托給SecurityManager;可以把Subject認為是一個門面;SecurityManager才是實際的執行者;

SecurityManager:安全管理器;即所有與安全有關的操作都會與SecurityManager 交互;且它管理著所有Subject;可以看出它是Shiro 的核心,它負責與後邊介紹的其他組件進行交互,如果學習過SpringMVC,你可以把它看成DispatcherServlet前端控制器;

Realm:域,Shiro從從Realm獲取安全數據(如用戶、角色、許可權),就是說SecurityManager要驗證用戶身份,那麼它需要從Realm獲取相應的用戶進行比較以確定用戶身份是否合法;也需要從Realm得到用戶相應的角色/許可權進行驗證用戶是否能進行操作;可以把Realm看成DataSource,即安全數據源。

shiro官方文檔

https://shiro.apache.org/architecture.html

前端CDN的方式使用elementUI、vue、vue-router、axios畫頁面

CDN(內容分髮網絡)本身是指一種請求資源的方式。說白了就是在本地,通過script頭去請求對應的腳本資源的一種方式。我在這裡要說的就是直接引用 (demo是直接引用的,註意電腦聯網)或者下載Vue.js和elementUI.js放在本地,進行項目開發的方式。而不是通過npm包管理工具去下載vue包。

cdn方式引入elementui 官方API:https://element.eleme.cn/#/zh-CN/component/installation
在這裡插入圖片描述
cdn方式引入vue-router官方API:https://router.vuejs.org/zh/guide/#html
router

DEMO的整體流程設計

技術層面瞭解完就該設計業務流程了,如圖:
process

demo整體結構

如圖:
struct

主要功能頁面

1、登錄
login

2、用戶查詢
query_user

3、分配角色
allot_role

4、刪除角色
remove_role

5、新建用戶
create_user
create_user_1

6、分配許可權
allot_permission

7、新建角色
create_role

主要代碼

com/example/demo/controller/UserCtrl.java

package com.example.demo.controller;

import com.example.demo.entity.Role;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;

/**
 * 控制層
 */
@RestController
@RequestMapping("/user")
public class UserCtrl {

    @Autowired
    private UserService userService;

    /**
     * 登錄介面
     *
     * @param user user
     * @return resultMap
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public Map<String, Object> login(@RequestBody User user) {
        //拿到主體
        Subject subject = SecurityUtils.getSubject();
        try {
            UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getUsername(), user.getPassword());
            subject.login(usernamePasswordToken);
            Object permissions = subject.getSession().getAttribute("permissions");
            subject.getSession().removeAttribute("permissions");
            return userService.resultMap("permissions", permissions, "token",  subject.getSession().getId(), "", "");
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

    /**
     * 獲取用戶的角色類型
     *
     * @param user user
     * @return resultMap
     */
    @RequestMapping(value = "/findRoleListByUserId", method = RequestMethod.POST)
    public Map<String, Object> findRoleListByUserId(@RequestBody User user) {
        try{
            return userService.findRoleListByUserId(user.getId());
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

    /**
     * 獲取角色的許可權類型
     *
     * @param role role
     * @return resultMap
     */
    @RequestMapping(value = "/findPermissionListByRoleId", method = RequestMethod.POST)
    public Map<String, Object> findPermissionListByRoleId(@RequestBody Role role) {
        try{
            return userService.findPermissionListByRoleId(role.getId());
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

    /**
     * 更新角色具有的許可權
     *
     * @param role role
     * @return resultMap
     */
    @RequestMapping(value = "/updateRolePermission", method = RequestMethod.POST)
    public Map<String, Object> updateRolePermission(@RequestBody Role role) {
        try{
            return userService.updateRolePermission(role);
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

    /**
     * 刪除角色
     *
     * @param role role
     * @return resultMap
     */
    @RequestMapping(value = "/removeRole", method = RequestMethod.POST)
    public Map<String, Object> removeRole(@RequestBody Role role) {
        try{
            return userService.removeRole(role);
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

    /**
     * 添加角色
     *
     * @param role role
     * @return resultMap
     */
    @RequestMapping(value = "/addRole", method = RequestMethod.POST)
    public Map<String, Object> addRole(@RequestBody Role role) {
        try{
            return userService.addRole(role);
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

    /**
     * 更新用戶具有的角色
     *
     * @param user user
     * @return resultMap
     */
    @RequestMapping(value = "/updateUserRole", method = RequestMethod.POST)
    public Map<String, Object> updateUserRole(@RequestBody User user) {
        try{
            return userService.updateUserRole(user);
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

    /**
     * 根據用戶提供的條件分頁查詢用戶
     *
     * @param user user
     * @return resultMap
     */
    @RequestMapping(value = "/queryUserListPage", method = RequestMethod.POST)
    public Map<String, Object> queryUserListPage(@RequestBody User user) {
        try{
            return userService.queryUserListPage(user);
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

    /**
     * 刪除用戶
     *
     * @param user user
     * @return resultMap
     */
    @RequestMapping(value = "/removeUser", method = RequestMethod.POST)
    public Map<String, Object> removeUser(@RequestBody User user) {
        try{
            return userService.removeUser(user);
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

    /**
     * 新增用戶
     *
     * @param user user
     * @return resultMap
     */
    @RequestMapping(value = "/insertUser", method = RequestMethod.POST)
    public Map<String, Object> insertUser(@RequestBody User user) {
        try{
            return userService.insertUser(user);
        }catch (Exception e){
            e.printStackTrace();
            return userService.resultMap("error", e.getMessage(), "",  "", "", "");
        }
    }

}

com/example/demo/service/UserService.java

package com.example.demo.service;

import com.example.demo.entity.Permission;
import com.example.demo.entity.Role;
import com.example.demo.entity.User;
import com.example.demo.mapper.PermissionMapper;
import com.example.demo.mapper.UserMapper;
import com.example.demo.mapper.RoleMapper;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 服務層
 */
@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    public User findUserByName(String userName) {
        User user = userMapper.findUserByName(userName);
        //用戶角色的集合
        List<Role> roleList = roleMapper.findRoleListByUserId(user.getId());
        user.setRoleList(roleList);
        return user;
    }

    public Map<String, Object> findRoleListByUserId(int userId){
        //用戶具有的角色集合
        List<Role> beRoleList = roleMapper.findRoleListByUserIdNotPermission(userId);
        //用戶沒有的角色集合
        List<Role> notRoleList = roleMapper.findNotRoleListByUserIdNotPermission(userId);
        //所有角色集合
        Collection<?> allRoleList = CollectionUtils.union(beRoleList, notRoleList);
        return this.resultMap("beRoleList", beRoleList, "notRoleList", notRoleList, "allRoleList", allRoleList);
    }

    @Transactional(rollbackFor = {Exception.class})
    public Map<String, Object> updateUserRole(User user){
        int removeUserRole = userMapper.removeUserRoleByUserId(user.getId());
        int addUserRole = 0;
        if (user.getRoleList().size()!=0 && user.getRoleList()!=null){
            addUserRole = userMapper.addUserRole(user);
        }
        return this.resultMap("removeUserRole", removeUserRole, "addUserRole", addUserRole, "", "");
    }

    public Map<String, Object> findPermissionListByRoleId(int roleId){
        //角色具有的許可權集合
        List<Permission> bePermissionList = permissionMapper.findByPermissionListByRoleId(roleId);
        //角色沒有的許可權集合
        List<Permission> notPermissionList = permissionMapper.findNotPermissionListByRoleId(roleId);
        //所有許可權集合
        Collection<?> allPermissionList = CollectionUtils.union(bePermissionList, notPermissionList);
        return this.resultMap("bePermissionList", bePermissionList, "notPermissionList", notPermissionList, "allPermissionList", allPermissionList);
    }

    @Transactional(rollbackFor = {Exception.class})
    public Map<String, Object> updateRolePermission(Role role){
        int removeRolePermission = roleMapper.removeRolePermissionByRoleId(role.getId());
        int addRolePermission = 0;
        if (role.getPermissionList().size()!=0 && role.getPermissionList()!=null){
            addRolePermission = roleMapper.addRolePermission(role);
        }
        return this.resultMap("removeRolePermission", removeRolePermission, "addRolePermission", addRolePermission, "", "");
    }

    @Transactional(rollbackFor = {Exception.class})
    public Map<String, Object> removeRole(Role role){
        int removeRolePermission = roleMapper.removeRolePermissionByRoleId(role.getId());
        int removeRole = roleMapper.removeRoleByRoleId(role.getId());
        int removeUserRole = userMapper.removeUserRoleByRoleId(role.getId());
        return this.resultMap("removeRolePermission", removeRolePermission, "removeRole", removeRole, "removeUserRole", removeUserRole);
    }

    public Map<String, Object> queryUserListPage(User user){
        //當前頁頁碼
        int pageNow = user.getReserve1() < 1 ? 1 : user.getReserve1();
        //當前頁第一行索引
        user.setReserve1(5*(pageNow - 1));
        List<User> userListPage = userMapper.queryUserListPage(user);
        int userRowCount = userMapper.getUserRowCount(user);
        return this.resultMap("userListPage", userListPage, "userRowCount",  userRowCount, "", "");
    }

    public Map<String, Object> addRole(Role role){
        int addRole = roleMapper.addRole(role);
        return this.resultMap("addRole", addRole, "",  "", "", "");
    }

    @Transactional(rollbackFor = {Exception.class})
    public Map<String, Object> removeUser(User user){
        int removeUser = userMapper.removeUserByUserId(user.getId());
        int removeUserRole = userMapper.removeUserRoleByUserId(user.getId());
        return this.resultMap("removeUser", removeUser, "removeUserRole", removeUserRole, "", "");
    }

    public Map<String, Object> insertUser(User user) {
        int addUser = userMapper.insertUser(user);
        return this.resultMap("addUser", addUser, "", "", "", "");
    }

    public Map<String, Object> resultMap(String str1, Object obj1, String str2, Object obj2, String str3, Object obj3){
        Map<String, Object> resultMap = new HashMap<>();
        if (!"".equals(str1) || !"".equals(obj1))
            resultMap.put(str1, obj1);
        if (!"".equals(str2) || !"".equals(obj2))
            resultMap.put(str2, obj2);
        if (!"".equals(str3) || !"".equals(obj3))
            resultMap.put(str3, obj3);
        return resultMap;
    }

}

CDN模式下的vue、vue-router、template模板掛載操作

參考:src/main/resources/static/index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <!-- import CSS -->
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
</head>
<body>
<div id="app">
    <router-view></router-view>
</div>
<template id="sign">
    <div class="handle">
        <div class="handle-input">
            <div class="high70">
                <span>用戶名稱:</span>
                <el-input
                        v-model="username"
                        placeholder="請輸入用戶名稱"
                        clearable></el-input>
            </div>
            <div class="high70">
                <span>密碼:</span>
                <el-input
                        v-model="password"
                        placeholder="請輸入密碼"
                        clearable
                        show-password></el-input>
            </div>
            <el-button @click="login" plain>登錄</el-button>
        </div>
    </div>
</template>
<template id="manager">
    <el-tabs :tab-position="tabPosition">
        <el-tab-pane label="用戶設置" v-if="permissionsFlag.query_user || permissionsFlag.add_user || permissionsFlag.allot_roles || permissionsFlag.remove_user">
            <el-row type="flex" justify="center">
                <el-col :span="18">
                    <div class="handle-area">
                        <div class="demo-input" v-show="permissionsFlag.query_user || permissionsFlag.add_user || permissionsFlag.allot_roles || permissionsFlag.remove_user">
                            <span>用戶ID:</span>
                            <el-input
                                    v-model="id"
                                    placeholder="請輸入用戶ID"
                                    type="number"
                                    size="medium"
                                    clearable></el-input>
                            <span>用戶名稱:</span>
                            <el-input
                                    v-model="username"
                                    placeholder="請輸入用戶名稱"
                                    size="medium"
                                    clearable></el-input>
                            <el-button
                                    :plain="true"
                                    @click="queryUserList"
                                    icon="el-icon-search"
                                    size="medium">查詢用戶</el-button>
                        </div>
                        <el-button
                                v-show="permissionsFlag.add_user"
                                :plain="true"
                                @click="handleAddUser"
                                icon="el-icon-user"
                                size="medium">新建用戶</el-button>
                    </div>
                    <el-table
                            :data="tableData"
                            border
                            highlight-current-row>
                        <el-table-column
                                prop="id"
                                label="用戶ID">
                        </el-table-column>
                        <el-table-column
                                prop="username"
                                label="用戶名稱">
                        </el-table-column>
                        <el-table-column
                                label="操作">
                            <template slot-scope="scope">
                                <el-button
                                        v-show="permissionsFlag.allot_roles"
                                        type="text"
                                        icon="el-icon-set-up"
                                        @click="handleEditUser(scope.$index, scope.row)">分配角色
                                </el-button>
                                <el-button
                                        v-show="permissionsFlag.remove_user"
                                        type="text"
                                        icon="el-icon-remove-outline"
                                        @click="handleDeleteUser(scope.$index, scope.row)">刪除用戶
                                </el-button>
                            </template>
                        </el-table-column>
                    </el-table>
                    <el-pagination
                            layout="total, prev, pager, next, jumper"
                            :total="userRowCount"
                            :page-size="5"
                            :current-page.sync="currentPage"
                            @current-change="queryUserListPage"
                            :hide-on-single-page="hidePageFlag"
                            background>
                    </el-pagination>
                </el-col>
            </el-row>
            <el-dialog :title="roleTitle" :visible.sync="dialogEditUser" :before-close="handleClose">
                <el-transfer
                        v-model="transferValue"
                        :data="transferData"
                        :titles="['待分配角色', '已分配角色']">
                </el-transfer>
                <span slot="footer" class="dialog-footer">
			        <el-button @click="handleClose">取 消</el-button>
			        <el-button type="primary" @click="assignRoles">確 定</el-button>
		        </span>
            </el-dialog>
            <el-dialog title="新建用戶" :visible.sync="dialogAddUser" :before-close="handleClose">
                <div class="high70">
                    <span>用戶名稱:</span>
                    <el-input
                            v-model="username"
                            placeholder="請輸入用戶名稱"
                            size="medium"
                            clearable></el-input>
                </div>
                <div class="high70">
                    <span>密碼:</span>
                    <el-input
                            v-model="password"
                            placeholder="請輸入密碼"
                            size="medium"
                            clearable
                            show-password></el-input>
                </div>
                <div class="high70">
                    <span>再次輸入密碼:</span>
                    <el-input
                            v-model="password1"
                            placeholder="請再次輸入密碼"
                            size="medium"
                            show-password></el-input>
                </div>
                <div class="high70">
                    <span>備註:</span>
                    <el-input
                            v-model="reserve"
                            placeholder="請輸入用戶備註"
                            size="medium"></el-input>
                </div>
                <span slot="footer" class="dialog-footer">
			        <el-button @click="handleClose">取 消</el-button>
			        <el-button type="primary" @click="insertUser">確 定</el-button>
		        </span>
            </el-dialog>
        </el-tab-pane>

        <el-tab-pane label="角色設置" v-if="permissionsFlag.allot_roles || permissionsFlag.query_role || permissionsFlag.add_role || permissionsFlag.remove_role || permissionsFlag.allot_permission">
            <el-row type="flex" justify="center">
                <el-col :span="18">
                    <div class="handle-area">
                        <el-button
                                v-show="permissionsFlag.allot_roles || permissionsFlag.query_role || permissionsFlag.add_role || permissionsFlag.remove_role || permissionsFlag.allot_permission"
                                :plain="true"
                                @click="queryRoleList"
                                icon="el-icon-search"
                                size="medium">角色查詢</el-button>
                        <el-button
                                v-show="permissionsFlag.add_role"
                                :plain="true"
                                @click="handleAddRole"
                                icon="el-icon-circle-plus-outline"
                                size="medium">新建角色</el-button>
                    </div>
                    <el-table
                            :data="roleData"
                            border
                            highlight-current-row>
                        <el-table-column
                                prop="id"
                                label="角色ID">
                        </el-table-column>
                        <el-table-column
                                prop="name"
                                label="角色名稱">
                        </el-table-column>
                        <el-table-column
                                prop="description"
                                label="角色描述">
                        </el-table-column>
                        <el-table-column
                                label="操作">
                            <template slot-scope="scope">
                                <el-button
                                        v-show="permissionsFlag.allot_permission"
                                        type="text"
                                        icon="el-icon-s-operation"
                                        @click="handleEditRole(scope.$index, scope.row)">分配許可權
                                </el-button>
                                <el-button
                                        v-show="permissionsFlag.remove_role"
                                        type="text"
                                        icon="el-icon-remove-outline"
                                        @click="handleDeleteRole(scope.$index, scope.row)">刪除角色
                                </el-button>
                            </template>
                        </el-table-column>
                    </el-table>
                </el-col>
            </el-row>
            <el-dialog :title="permissionsTitle" :visible.sync="dialogEditRole" :before-close="handleClose">
                <el-checkbox-group v-model="checkedPermissions" class="el-checkbox-group-dialog">
                    <el-checkbox v-for="permission in permissions" :label="permission.name" :key="permission.name">{{permission.description}}</el-checkbox>
                </el-checkbox-group>
                <span slot="footer" class="dialog-footer">
			        <el-button @click="handleClose">取 消</el-button>
			        <el-button type="primary" @click="assignPermissions">確 定</el-button>
		        </span>
            </el-dialog>
            <el-dialog title="新建角色" :visible.sync="dialogAddRole" :before-close="handleClose">
                <div class="high70">
                    <span>角色名稱:</span>
                    <el-input
                            v-model="name"
                            placeholder="請輸入角色名稱"
                            size="medium"></el-input>
                </div>
                <div class="high70">
                    <span>角色描述:</span>
                    <el-input
                            v-model="description"
                            placeholder="請輸入角色描述"
                            size="medium"></el-input>
                </div>
                <span slot="footer" class="dialog-footer">
			        <el-button @click="handleClose">取 消</el-button>
			        <el-button type="primary" @click="insertRole">確 定</el-button>
		        </span>
            </el-dialog>
        </el-tab-pane>

        <el-tab-pane label="許可權列表" v-if="permissionsFlag.allot_permission">
            <el-row type="flex" justify="center">
                <el-col :span="18">
                    <div class="handle-area">
                        <el-button
                                v-show="permissionsFlag.allot_permission"
                                :plain="true"
                                @click="queryPermissionList"
                                icon="el-icon-search"
                                size="medium">許可權查詢</el-button>
                    </div>
                    <el-table
                            :data="permissionData"
                            border
                            highlight-current-row>
                        <el-table-column
                                prop="id"
                                label="許可權ID">
                        </el-table-column>
                        <el-table-column
                                prop="name"
                                label="許可權名稱">
                        </el-table-column>
                        <el-table-column
                                prop="description"
                                label="許可權描述">
                        </el-table-column>
                    </el-table>
                </el-col>
            </el-row>
        </el-tab-pane>
    </el-tabs>
</template>
</body>
<!-- import Vue before Element -->
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<!-- import JavaScript -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<!-- import Axios -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- import Router -->
<script src="https://cdn.staticfile.org/vue-router/2.7.0/vue-router.min.js"></script>
<script>
    const Sign = {
        props: ['todo'],
        template: '#sign',
        data() {
            return {
                username: '',
                password: '',
                permissionsStr: [],
                token: ''
            }
        },
        methods: {
            login() {
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/login',
                    data: JSON.stringify({
                        username: this.username,
                        password: this.password
                    })
                }).then(response => {
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        this.username = '';
                        this.password = '';
                        ELEMENT.Notification.error({
                            title: '登錄失敗!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        return;
                    }
                    this.permissionsStr = response.data.permissions;
                    this.token = response.data.token;
                    this.$router.push({
                        name: 'manager',
                        params: {
                            token: this.token,
                            permissionsStr: this.permissionsStr
                        }
                    });
                }).catch(error => {
                    console.log(error);
                    ELEMENT.Message(error);
                });
            }
        },
        mounted() {
            console.log('組件Sign被掛載了');
        }
    };
    const Manager = {
        // todo-item 組件現在接受一個
        // "prop",類似於一個自定義 attribute。
        // 這個 prop 名為 todo。
        props: ['todo'],
        template: '#manager',
        data() {
            return {
                // 角色信息
                roleData: [],
                roleId: null,
                name: '',
                description: '',
                dialogEditRole: false,
                dialogAddRole: false,
                permissions: [],
                checkedPermissions: [],
                permissionList: [],
                permissionsTitle: '',
                // 許可權信息
                permissionData: [],
                // 穿梭框
                transferValue: [],
                transferData: [],
                // 表格及分頁
                tableData: [],
                tabPosition: 'top',
                userRowCount: 0,
                currentPage: 0,
                hidePageFlag: true,
                // 彈框
                dialogEditUser: false,// 分配角色彈框
                dialogAddUser: false,// 新建用戶彈框
                // 用戶信息
                allRoleList: [],
                roleList: [],
                id: null,
                username: '',
                password: '',
                password1: '',
                reserve: '',
                roleTitle: '',
                permissionsStr: [],
                permissionsFlag: {
                    query_user: false,
                    add_user: false,
                    remove_user: false,
                    allot_roles: false,
                    query_role: false,
                    add_role: false,
                    remove_role: false,
                    allot_permission: false
                },
                token: ''

            }
        },
        methods: {
            queryPermissionList() {
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/findPermissionListByRoleId',
                    data: JSON.stringify({
                        id: 0
                    })
                }).then(response => {
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        ELEMENT.Notification.error({
                            title: '查詢失敗!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        return;
                    }
                    this.permissionData = response.data.allPermissionList;
                }).catch(error => {
                    console.log(error);
                    ELEMENT.Message(error);
                });
            },
            queryRoleList() {
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/findRoleListByUserId',
                    data: JSON.stringify({
                        id: 0
                    })
                }).then(response => {
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        ELEMENT.Notification.error({
                            title: '查詢失敗!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        return;
                    }
                    this.roleData = response.data.allRoleList;
                }).catch(error => {
                    console.log(error);
                    ELEMENT.Message(error);
                });

            },
            handleEditRole(index, row){
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/findPermissionListByRoleId',
                    data: JSON.stringify({
                        id: row.id
                    })
                }).then(response => {
                    console.log(response.data);
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        ELEMENT.Notification.error({
                            title: '查詢失敗!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        return;
                    }
                    this.permissions = response.data.allPermissionList;
                    for(let item of response.data.bePermissionList){
                        this.checkedPermissions.push(item.name);
                    }
                    this.roleId = row.id;
                    this.name = row.name;
                    this.permissionsTitle = '為角色'+row.name+'分配許可權';
                    this.dialogEditRole = true;
                }).catch(error => {
                    console.log(error);
                    ELEMENT.Message(error);
                });
            },
            handleDeleteRole(index, row){
                ELEMENT.MessageBox.confirm('此操作將永久刪除角色'+row.name+', 是否繼續?', '提示', {
                    confirmButtonText: '確定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    axios.defaults.headers.token = this.token;
                    axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                    axios({
                        method: 'post',
                        url: '/user/removeRole',
                        data: JSON.stringify({
                            id: row.id
                        })
                    }).then(response => {
                        if(typeof response.data.error !== 'undefined' || response.data.error != null){
                            ELEMENT.Notification.error({
                                title: '角色'+row.name+',刪除失敗!',
                                message: response.data.error,
                                position: 'top-right',
                                showClose: false,
                                offset: 110
                            });
                            return;
                        }
                        if (response.data.removeRolePermission >= 0 && response.data.removeRole >= 0 && response.data.removeUserRole >= 0) {
                            this.queryRoleList();
                            ELEMENT.Notification({
                                title: '刪除成功',
                                message: '角色'+row.name+',刪除成功!',
                                type: 'success',
                                position: 'top-right',
                                showClose: false,
                                offset: 110
                            });
                        }
                    }).catch(error => {
                        ELEMENT.Message({ type: 'info', message: error});
                    });
                }).catch(() => {
                    ELEMENT.Message({ type: 'info', message: '已取消刪除'});
                });
            },
            handleAddRole(){
                this.dialogAddRole = true;
                this.name = '';
                this.description = '';
            },
            insertRole(){
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/addRole',
                    data: JSON.stringify({
                        name: this.name,
                        description: this.description
                    })
                }).then(response => {
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        ELEMENT.Notification.error({
                            title: '角色'+this.name+',添加失敗!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        this.dialogAddRole = false;
                        this.name = '';
                        this.description = '';
                        return;
                    }
                    if(response.data.addRole > 0) {
                        this.queryRoleList();
                        ELEMENT.Notification({
                            title: '添加成功',
                            message: '角色'+this.name+',添加成功!',
                            type: 'success',
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        this.dialogAddRole = false;
                        this.name = '';
                        this.description = '';
                    }
                    console.log(response.data);
                }).catch(error => {
                    ELEMENT.Message({ type: 'info', message: error});
                });
            },
            assignPermissions(){
                for(let item of this.permissions){
                    for(let i in this.checkedPermissions){
                        if (this.checkedPermissions[i] == item.name) {
                            this.permissionList.push(item);
                        }
                    }
                }
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/updateRolePermission',
                    data: JSON.stringify({
                        id: this.roleId,
                        permissionList: this.permissionList,
                    })
                }).then(response => {
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        this.dialogEditRole = false;
                        ELEMENT.Notification.error({
                            title: '為角色'+this.name+',分配許可權失敗!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        this.roleId = null;
                        this.name = null;
                        this.permissions = [];
                        this.checkedPermissions = [];
                        this.permissionList = [];
                        this.permissionsTitle = '';
                        return;
                    }
                    if (response.data.removeRolePermission >= 0 && response.data.addRolePermission >= 0) {
                        this.dialogEditRole = false;
                        ELEMENT.Notification({
                            title: '更新成功',
                            message: '為角色'+this.name+',分配許可權成功!',
                            type: 'success',
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        this.roleId = null;
                        this.name = null;
                        this.permissions = [];
                        this.checkedPermissions = [];
                        this.permissionList = [];
                        this.permissionsTitle = '';
                    }
                    console.log(response.data);
                }).catch(error => {
                    console.log(error);
                    ELEMENT.Message(error);
                });
            },
            // ------------------------用戶設置部分--------------
            queryUserList() {
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/queryUserListPage',
                    data: JSON.stringify({
                        id: this.id,
                        username: this.username
                    })
                }).then(response => {
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        ELEMENT.Notification.error({
                            title: '查詢用戶失敗!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        return;
                    }
                    console.log(response.data);
                    this.tableData = response.data.userListPage;
                    this.userRowCount = response.data.userRowCount;
                    if(this.userRowCount > 5) {
                        this.hidePageFlag = false;
                    } else {
                        this.hidePageFlag = true;
                    }
                    this.currentPage = 1;
                }).catch(error => {
                    console.log(error);
                    ELEMENT.Message(error);
                });
            },
            queryUserListPage() {
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/queryUserListPage',
                    data: JSON.stringify({
                        id: this.id,
                        username: this.username,
                        reserve1: this.currentPage
                    })
                }).then(response => {
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        ELEMENT.Notification.error({
                            title: '查詢用戶失敗!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        return;
                    }
                    console.log(response.data);
                    this.tableData = response.data.userListPage;
                    this.userRowCount = response.data.userRowCount;
                    if(this.userRowCount > 5) {
                        this.hidePageFlag = false;
                    } else {
                        this.hidePageFlag = true;
                    }
                }).catch(error => {
                    console.log(error);
                    ELEMENT.Message(error);
                });
            },
            handleEditUser(index, row) {
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/findRoleListByUserId',
                    data: JSON.stringify({
                        id: row.id
                    })
                }).then(response => {
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        this.dialogEditUser = false;
                        ELEMENT.Notification.error({
                            title: '為用戶'+row.username+'分配角色失敗!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        return;
                    }
                    console.log(response.data);
                    for(let item of response.data.allRoleList){
                        this.transferData.push({
                            key: item.id,
                            label: item.description
                        });
                    }
                    for(let item of response.data.beRoleList){
                        this.transferValue.push(item.id);
                    }
                    this.id = row.id;
                    this.username = row.username;
                    this.allRoleList = response.data.allRoleList;
                    this.roleTitle = '為用戶'+row.username+'分配角色';
                    this.dialogEditUser = true;
                }).catch(error => {
                    console.log(error);
                    ELEMENT.Message(error);
                });
            },
            assignRoles() {
                for(let item of this.allRoleList){
                    for(let i in this.transferValue){
                        if (this.transferValue[i] == item.id) {
                            this.roleList.push(item);
                        }
                    }
                }
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/updateUserRole',
                    data: JSON.stringify({
                        id: this.id,
                        username: this.username,
                        roleList: this.roleList
                    })
                }).then(response => {
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        this.dialogEditUser = false;
                        ELEMENT.Notification.error({
                            title: '為用戶'+row.username+'分配角色失敗!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        this.id = null;
                        this.username = '';
                        this.allRoleList = [];
                        this.roleList = [];
                        this.transferData = [];
                        this.transferValue = [];
                        return;
                    }
                    if (response.data.removeUserRole >= 0 && response.data.addUserRole >= 0) {
                        this.dialogEditUser = false;
                        ELEMENT.Notification({
                            title: '更新成功',
                            message: '為用戶'+this.username+',分配角色成功!',
                            type: 'success',
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        this.id = null;
                        this.username = '';
                        this.allRoleList = [];
                        this.roleList = [];
                        this.transferData = [];
                        this.transferValue = [];
                    }
                    console.log(response.data);
                }).catch(error => {
                    console.log(error);
                });

            },
            handleDeleteUser(index, row) {
                //this.ruleForm = Object.assign({}, row, index); //這句是關鍵!!!
                ELEMENT.MessageBox.confirm('此操作將永久刪除用戶'+row.id+', 是否繼續?', '提示', {
                    confirmButtonText: '確定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    axios.defaults.headers.token = this.token;
                    axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                    axios({
                        method: 'post',
                        url: '/user/removeUser',
                        data: JSON.stringify({
                            id: row.id
                        })
                    }).then(response => {
                        if(typeof response.data.error !== 'undefined' || response.data.error != null){
                            ELEMENT.Notification.error({
                                title: '用戶'+row.username+',刪除失敗!',
                                message: response.data.error,
                                position: 'top-right',
                                showClose: false,
                                offset: 110
                            });
                            return;
                        }
                        if (response.data.removeUser >= 0 && response.data.removeUserRole >= 0) {
                            if(((this.userRowCount - 1) % 5 == 0) && ((this.userRowCount - 1) / 5 == (this.currentPage - 1))) {
                                this.currentPage = this.currentPage - 1;
                            }
                            this.queryUserListPage();
                            ELEMENT.Notification({
                                title: '刪除成功',
                                message: '用戶'+row.username+',刪除成功!',
                                type: 'success',
                                position: 'top-right',
                                showClose: false,
                                offset: 110
                            });
                        }
                    }).catch(error => {
                        ELEMENT.Message({ type: 'info', message: error});
                    });
                }).catch(() => {
                    ELEMENT.Message({ type: 'info', message: '已取消刪除'});
                });
            },
            handleClose() {
                // 用戶設置
                this.dialogEditUser = false;
                this.dialogAddUser = false;
                this.id = null;
                this.username = '';
                this.password = '';
                this.password1 = '';
                this.reserve = '';
                this.allRoleList = [];
                this.roleList = [];
                this.transferData = [];
                this.transferValue = [];
                this.roleTitle = '';
                // 角色設置
                this.dialogEditRole = false;
                this.dialogAddRole = false;
                this.roleId = null;
                this.name = null;
                this.permissions = [];
                this.checkedPermissions = [];
                this.permissionList = [];
                this.permissionsTitle = '';
                ELEMENT.Message({
                    message: '取消操作,系統不會保留任何更改',
                    type:'warning'
                });
            },
            handleAddUser(){
                this.dialogAddUser = true;
                this.id = null;
                this.username = '';
                this.password = '';
                this.password1 = '';
                this.reserve = '';
            },
            insertUser() {
                axios.defaults.headers.token = this.token;
                axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
                axios({
                    method: 'post',
                    url: '/user/insertUser',
                    data: JSON.stringify({
                        username: this.username,
                        password: this.password,
                        reserve: this.reserve
                    })
                }).then(response => {
                    if(response.data.addUser > 0) {
                        this.dialogAddUser = false;
                        this.password = '';
                        this.password1 = '';
                        this.reserve = '';
                        this.queryUserList();
                        ELEMENT.Notification({
                            title: '添加成功',
                            message: '用戶'+this.username+',添加成功!',
                            type: 'success',
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                    }
                    if(typeof response.data.error !== 'undefined' || response.data.error != null){
                        this.dialogAddUser = false;
                        this.password = '';
                        this.password1 = '';
                        this.reserve = '';
                        this.queryUserList();
                        ELEMENT.Notification.error({
                            title: '用戶'+this.username+',添加失敗!',
                            message: response.data.error,
                            position: 'top-right',
                            showClose: false,
                            offset: 110
                        });
                        return;
                    }
                    console.log(response.data);
                }).catch(error => {
                    ELEMENT.Message({ type: 'info', message: error});
                });
            }
        },
        mounted() {
            console.log('組件Manager被掛載了');
        },
        created() {
            this.permissionsStr = this.$route.params.permissionsStr;
            this.token = this.$route.params.token;
            for(let key in this.permissionsFlag){
                for(let i in this.permissionsStr){
                    if(this.permissionsStr[i] == key){
                        this.permissionsFlag[key] = true;
                    }
                }
                console.log(key + '---' + this.permissionsFlag[key])
            }
        }
    };
    const router = new VueRouter({
        routes:[
            {
                path: '/',
                name: 'sign',
                component: Sign
            },
            {
                path: '/manager',
                name: 'manager',
                component: Manager
            }
        ]
    });
    new Vue({
        router,
        el: '#app',
        data: {},
        methods: {}
    })
</script>
<style>
    .el-pagination {
        display: flex;
        justify-content: flex-end;
        align-items: center;
        height: 60px;
    }
    .el-transfer {
        display: flex;
        justify-content: center;
        align-items: center;
    }
    .handle-area {
        display: flex;
        align-items: center;
        justify-content: space-between;
        height: 70px;
        flex-wrap: nowrap;
    }
    .demo-input {
        display: flex;
        align-items: center;
    }
    .demo-input span {
        white-space: nowrap;
    }
    .el-dialog__body {
        display: flex;
        flex-direction: column;
        justify-content: center;
        flex-wrap: nowrap;
        height: 280px;
    }
    .el-checkbox-group-dialog {
        height: 100%;
        display: flex;
        flex-direction: column;
        justify-content: center;
        margin: auto;
    }
    .el-checkbox {
        height: 30px;
        line-height: 30px;
    }
    .high70 {
        height: 70px;
    }
    .handle {
        position: absolute;
        width: 100%;
        height: 100%;
        top: 0;
        left: 0;
        margin: 0;
        background-image: url(banner.jpg);
        background-position: center;
        background-repeat: no-repeat;
        background-size: cover;
        overflow: hidden;
        display: flex;
        justify-content: center;
        align-items: center;
    }
    .handle-input {
        display: flex;
        flex-direction: column;
    }
</style>
</html>

具體看index.html 代碼,如果沒看懂,參考網址:
https://blog.csdn.net/laow1314/article/details/109323527
https://blog.csdn.net/qq_29722281/article/details/85016524

許可權相關表

最基礎的CRUD操作無法體現shiro的功能,需引入RBAC (Role-Based Access Control)思想,配置至少需要三張主表分別代表用戶(user)、角色(role)、許可權(permission),及兩個附表分別是用戶和角色(user_role),角色與許可權(role_permission)表,表結構如下:
ER

對應的實體如下:
1、com/example/demo/entity/User.java

package com.example.demo.entity;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Data
@ToString
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User {
    /**
     * 主鍵
     */
    private int id;
    /**
     * 用戶名
     */
    private String username;
    /**
     * 密碼
     */
    private String password;
    /**
     * 保留欄位
     */
    private String reserve;

    /**
     * 保留欄位1
     */
    private int reserve1;
    /**
     * 角色集合
     */
    private List<Role> roleList = new ArrayList<>();

    public User(String json) throws IOException {
        User user = new ObjectMapper().readValue(json,User.class);
        this.id = user.getId();
        this.username = user.getUsername();
        this.password = user.getPassword();
        this.reserve = user.getReserve();
        this.reserve1 = user.getReserve1();
        this.roleList = u

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • MySQL基礎查詢練習 前提準備 使用ddl語句創建資料庫 student表格: create table student( id int PRIMARY KEY COMMENT 'id主鍵', `name` varchar(20) COMMENT '名稱', gender TINYINT(2) C ...
  • 表: 查詢語句 -- 查詢姓“猴”的學生名單 SELECT * from student WHERE 姓名 like "猴%"; -- 查詢姓“孟”老師的個數 SELECT COUNT(教師姓名) FROM teacher WHERE 教師姓名 LIKE "孟%"; -- 查詢課程編號為“0002” ...
  • 一:背景 1. 講故事 在面試中我相信有很多朋友會被問到 truncate 和 delete 有什麼區別 ,這是一個很有意思的話題,本篇我就試著來回答一下,如果下次大家遇到這類問題,我的答案應該可以幫你成功度過吧。 二:區別詳解 1. 思考 從巨集觀角度來說, delete 是 DML 語句, tru ...
  • 環境概述 操作系統:WIN2019 ORACLE版本:19.17.0.0.0 故障現象 客戶反饋資料庫經常用著用著就連不上,通過查看alert日誌發現是資料庫實例崩潰。具體信息如下 2023-02-09T03:04:36.619773+08:00 Errors in file D:\APP\ADMI ...
  • 摘要:用戶創建hash分佈表,使用pbe方式執行使用分佈列作為查詢條件的語句時報錯 本文分享自華為雲社區《GaussDB(DWS)現網案例之collation報錯》,作者: 你是猴子請來的救兵嗎 。 用戶創建hash分佈表,使用pbe方式執行使用分佈列作為查詢條件的語句時報錯,ERROR: coul ...
  • 什麼是ChatGPT? ChatGPT是美國人工智慧研究實驗室OpenAI開發的一種全新聊天機器人模型,它能夠通過學習和理解人類的語言來進行對話,還能根據聊天的上下文進行互動,並協助人類完成一系列任務,因此有望成為提高辦公、學習效率的工具。以前的人工智慧AlphaGo打敗了柯潔,但只是在圍棋領域,而 ...
  • 前言 這篇筆記用來收集在日常開發中所用到的安卓adb shell命令,參照了一些大佬的再加上我自己平時用到的整理在了一塊兒,感謝無私共用的大佬們。 將會持續更新,歡迎收藏~ 一、基本用法 命令語法 adb 命令的基本語法如下: adb [-d|-e|-s <serialNumber>] <comma ...
  • 隨著對用戶體驗要求的提高,產品要求提升用戶體驗,多端體驗一致。隨著多端相同的業務也越來越多,需要投入IOS,Android,Web多端開發人員。這就迫切的需要一種一次開發同時使用在Android ,IOS ,Web的解決方案。達到降本增效的目的。在幾個小業面嘗試,總結經驗後,我們採用react-na... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...