Vue e e-commerce background management system project part 5 - addition, deletion, modification and query of role list & & role authorization

Posted by phpMitch on Mon, 13 Dec 2021 03:42:22 +0100

Addition, deletion, modification and query of role list

1. Add role

First, write the interface according to the API document;

// Add role
export const addRolesApi = (data) => {
  return axios({
    method: 'post',
    url: 'roles',
    data
  })
}

Reference in the role component, and then bind a click event addRolesClick to the "add role" button;

<!-- Add role -->
<el-button type="success" plain @click="addRolesClick">Add role</el-button>

Find the Dialog component in the element UI and add it to the page;

<!-- Add role -->
    <el-dialog title="Add role" :visible.sync="addRolesDialogFormVisible">
      <el-form :model="addRolesForm" label-width="120px" ref="addRolesForm" :rules="rules">
        <el-form-item label="Role name" prop="roleName">
          <el-input v-model="addRolesForm.roleName" autocomplete="off"></el-input>
        </el-form-item>

        <el-form-item label="Role description" prop="roleDesc">
          <el-input v-model="addRolesForm.roleDesc" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="addRolesDialogFormVisible = false;$refs.addRolesForm.resetFields()">Cancel</el-button>
        <el-button type="primary" @click="addRolesConfirm">determine</el-button>
      </div>
    </el-dialog>

Parameter Description:

  1. :visible.sync="addRolesDialogFormVisible" / / whether to hide the component and receive a Boolean value
  2. : model / / bound data object
  3. : rules="rules" / / validate rules
  4. prop="roleName" / / the field to be verified
  5. v-model="addRolesForm.roleName" / / bidirectional data binding

The business logic is the same as the previous user management = > the business logic of adding, deleting, modifying and querying the user list. After the user enters the data, verify whether it is legal, send a request after it is legal, and then refresh the data.

Delete specified permission of role list (key)

Add binding event

There are two types of deletion:

  1. Delete Level 3 permission: delete the current level 3 permission
  2. Delete Level 2 or level 1 permission: when you delete Level 2 permission, the corresponding level 3 permission will also be deleted. Similarly, when you delete level 1 permission, the corresponding level 2 permission will also be deleted

Check the interface document and analyze the processing in the component that deletes the business. In the component, we need to obtain two values: roleid (role id) and rightid (permission id)

Implementation interface method

Bind the event in the vue component and initiate the request. Remember to pass two parameters

Difficulty: data refresh after deletion

  1. We can reload the whole data, but this will cause a very bad user experience: because expanding rows will merge
  2. Our expectation: can we refresh only the data of the current row? Specifically, can we refresh only the data of the current expanded row?

Solution: refresh only the data of the current unfolded row

  1. We found that there is a data attribute in the return value after deleting the permission. This data is the permission data that the role still has after the deletion operation

  2. Therefore, we can directly overwrite the Data source of the expanded row (scope.row.children) with the Data in the returned value

  3. scope.row.children = res.data.data

@close='deleteright(scope.row,third.id)'
----------------------------------------
// Delete specified permissions
deleteright (row, rightid) {
    deleteRightById(row.id, rightid)
        .then(res => {
        console.log('--------------')
        console.log(res)
        console.log('--------------')
        if (res.data.meta.status === 200) {
            this.$message({
                type: 'success',
                message: res.data.meta.msg
            })
            // Refresh of data
            row.children = res.data.data
        }
    })
}

Final template code:

<el-table-column type="expand">
    <!-- When it unfolds, template The structure in the template is the content of the expanded line -->
    <template slot-scope="scope">
        <!-- Traversal of data row objects children -->
        <el-row v-for="first in scope.row.children" :key="first.id" style='margin-bottom:10px;border-bottom:1px dashed #ccc'>
            <el-col :span="4">
                <el-tag closable type="success"  @close='deleteright(scope.row,first.id)' v-if='first.children.length !== 0'>{{first.authName}}</el-tag>
            </el-col>
            <el-col :span="20">
                <el-row v-for='second in first.children' :key='second.id' style='margin-bottom:10px;' >
                    <el-col :span='4'>
                        <el-tag closable type="info"  @close='deleteright(scope.row,second.id)'  v-if='second.children.length !== 0'>{{second.authName}}</el-tag>
                    </el-col>
                    <el-col :span='20'>
                        <el-tag closable type="danger" v-for='third in second.children' :key='third.id' style='margin:0 4px 4px 0' @close='deleteright(scope.row,third.id)'>{{third.authName}}</el-tag>
                    </el-col>
                </el-row>
            </el-col>
        </el-row>
        <el-row>
            <el-col :span="24" v-if='scope.row.children.length === 0'>There is no permission data, please add it first</el-col>
        </el-row>
    </template>
</el-table-column>

Role permission assignment

Add the permission assignment pop-up box

Add a tree component to the pop-up box

  1. Find the component and add the structure

  2. Analyze the properties of the tree component

  3. Dynamically load all permission data

  4. Implement the default selection of the tree component node: obtain the permission id of the current role

  5. Realize permission setting: obtain the IDS corresponding to all permissions selected by the current user, and splice them into separated string format

Steps:

  1. Add the permission assignment pop-up box

  2. Addition of tree component: expand by default + with check box + selected by default

<el-tree
        :data="data2" // data source
        show-checkbox // Show check boxes
        node-key="id" //Each tree node is used as an attribute for unique identification. The whole tree should be unique. Later, this value should be bound to the permission id in the current permission object data
        :default-expanded-keys="[2, 3]" // Default expanded node
        :default-expand-all='true' // Expand all nodes by default
        :default-checked-keys="[5]" // Array of key s of nodes checked by default
        :props="defaultProps" // The configuration of the current node, such as what data you want to display, the value behind it.., Child data
      ></el-tree>

Common properties of tree components

<el-tree
        :data="rightList" // data source
        show-checkbox // Show check boxes
        node-key="id" //Each tree node is used as an attribute for unique identification. The whole tree should be unique. Later, this value should be bound to the permission id in the current permission object data
        :default-expand-all='true' // Expand all nodes by default
        :default-checked-keys="rightListByRole" // Array of key s of nodes checked by default
        :props="defaultProps" // The configuration of the current node, such as what data you want to display, the value behind it.., Child data
      ></el-tree>
---------
defaultProps:{
    label:authName,
    chilren:children
}

The data corresponds to the tree component and displays the permission dynamic data

// Opens the authorization dialog box
showGrantDialog () {
    this.grantdialogFormVisible = true
    // Get all permission data
    getAllRightList('tree')
        .then(res => {
        console.log(res)
        this.rightList = res.data.data
    })
}

Let tree components have default node selection

  1. Select the child node, and the parent node will also be selected

  2. We only need to obtain the permission id corresponding to the node at the lowest level

  3. Level 1 permissions do not necessarily have level 2 permissions. Similarly, level 2 permissions do not necessarily have level 3 permissions - judgment

  4. We have to traverse the permissions of the current role and get all permission IDS (the last level)

// Get all permission IDS owned by the current role
// Empty the permission id array of the previous role first
this.checkedArr.length = 0
row.children.forEach((first) => {
    if (first.children.length > 0) {
        // Traverse secondary permissions
        first.children.forEach(second => {
            if (second.children.length > 0) {
                // Traverse Level 3 permissions
                second.children.forEach(third => {
                    this.checkedArr.push(third.id)
                })
            }
        })
    }
})

Implement the submission of role authorization

  • Analyze the interface document and figure out what the interface needs

  • How do we get the parameters required by the interface?

  • When we observe the structure of the data table, we find that when storing three-level permissions, it also stores two-level permissions and one-level permissions at the same time

  • Therefore, we have a realistic requirement: when obtaining permission ID, we should obtain a complete id with hierarchy: (Level 1 permission, level 2 permission, level 3 permission)

Get permission id: add a ref attribute to the tree

  1. this.$refs.tree.getCheckedKeys(): get the key corresponding to the currently selected check box (node key = "Id")
  2. Don't use getCheckedKeys in this case, because when not all level 3 permissions are selected, it can't get the id corresponding to level 2 permissions and level 1 permissions
  3. this.$refs.tree.getCheckedNodes(): you can get the current node object, which contains the permission data object corresponding to the current node, and the object has a complete parent permission id

Add interface method

// Role authorization
export const grantRightByRoleId = (roleid, rids) => {
  return axios({
    method: 'post',
    url: `roles/${roleid}/rights`,
    data: { rids: rids }
  })
}

Enable authorization submission

// Implement role authorization submission
grantSubmit () {
    // var arr = this.$refs.tree.getCheckedKeys()
    var arr = this.$refs.tree.getCheckedNodes()
    // [authName: "add order", id: 109,path: (...),pid: "107,102"]
    console.log(arr)
    // What we need is the id corresponding to each permission, including their parent id
    // 1. Traverse Arr to obtain two values: ID PID, traverse: I need to traverse the spliced results ["109107102",'154107102 ']
    // It can store the operation result of the callback function into the array created inside the map function, and then return it after traversal
    var temp = arr.map(value => {
        return value.id + ',' + value.pid
    })
    // ["109,107,102", "154,107,102"]
    console.log(temp)
    // Remove duplicate values -- array can be de duplicated
    // Splice the array into the string "109107102154107102"“
    var str = temp.join(',')
    console.log(str)
    console.log(str.split(','))
    // Array de duplication. new Set can create a set object and remove duplicate values at the same time
    var obj = new Set(str.split(','))
    console.log(obj)
    // Finally, you need an array that removes duplicate values,... You can expand the data in the object one by one
    var final = [...obj]
    console.log(final.join(','))

    // Call interface method to implement role authorization
    grantRightByRoleId(this.roleId, final.join(','))
        .then(res => {
        console.log(res)
    })
}

The specific effect and business logic code should be directly pulled down from GitHub and studied in detail: https://github.com/C4az6/vue_manage_system.git

Topics: Javascript Vue Vue.js elementUI