Introduction to e-commerce background management system

Project Introduction

The dark horse background management system is a front-end project of an e-commerce background management system , which is implemented based on Vue+Element. It mainly includes product management, order management, membership management, promotion management, operation management, content management, statistical reports, financial management, authority management, settings and other functions

Development Technology

The technologies I used for this project development are: vue2+node.js+webapck element axios router vuex

Project development process:

  1. Project selection

  2. Build login registration page, rights management, encapsulation interface, vuex, routing configuration, environment configuration, local proxy

  3. Main function page: develop according to the business requirements of each page

  4. packaged items

  5. Code tidying, code comments

sub-module

This project is roughly divided into 7 parts: login, logout, user management, authority management, product management, order management, and data statistics

login module

The logic to realize the user login function is: ①Enter the account number and password on the login page to log in, and send the data to the server ②The server returns the login result, and if the login is successful, the token is returned in the data; ③The client gets the token and saves it, and the follow-up All requests need to send this token to the server, and the server will verify the token to ensure the user's identity.

First, perform login form verification when clicking login

Then add request interception and response interception in request.js. In the request interception, the token field will be added to the request header, and the loading animation will be turned on. In the response interception, you can close some loading animations, and do some operations to check whether the token is valid or expired according to the status code returned by the backend. The next step is to do some encapsulation of the api interface by axios. Here I use async and await to encapsulate the request interface function, so that the asynchronous operation can be synchronized and the code is more friendly.

Handle token expiration in the package, clear local storage and return to the login page.

After the redirect was successful, I configured the routing guard again to determine whether there is a token and whether there is any right to allow him to enter the main page

Layout of the sidebar and rendering request data

The corresponding components are also provided in element-ui, and the corresponding areas of the corresponding components can be found in the NavMenu navigation menu

  • :router Turn on the routing mode, set the index value of el-menu-item to the routing identifier

  • Dynamic rendering: login with different identities, permission control

Define an array leftmenu in data to receive left menu data

 

exit module

Call the interface, delete the token in the local, and jump to the login page

User Management Module

add edit

  • Display: Number of Existing UsersGET

  • Added: username, password, email, mobile phone, reload the page after addingPOST

  • delete: reload page after deletePUT

  • Modification: DELETE1. Change basic information: mobile phone, email 2. Change role: related to permissions

  • Component breadcrumbs, search box, table, paging component, switch state transition

Request data state switching, pagination, breadcrumb navigation switching and then validate the added and edited forms, and then optimize the project

I encapsulate the added and edited components into components for reuse, making page deconstruction clearer.

Implementation of the search function

Bind the value to queryInfo.query using

paging!

@size-change: Listen to the event of page size change @current-change: Listen to the event of page number value change: current-page: current page: page-sizes: number of information items on a page: page-size: current page number layout : Control display content: total: total number of information items

Rights Management Module

role list

  • Add role (simple commit)

  • Edit, delete (simple slot-scope parameter transfer, delete request)

  • assign role (tag)

  • Permission display (table expanded row)

One of the key points of the role list page is to use the plug-inelement ui intable表格展开行

Assigning permissions is also done byelement ui using thetree树形控件

<!-- Table -->
      <el-table :data="list" border style="width: 100%">
        <el-table-column type="expand">
          <template v-slot="scope">
            <!-- Current role permission rendering -->
            <el-row
              v-for="(item, i1) in scope.row.children"
              :key="item.id"
              :class="[i1 === 0 ? '' : 'bdtop', 'vcenter']"
            >
              <el-col :span="6">
                <!-- level one -->
                <el-tag closable>{
  
  { item.authName }}</el-tag>
              </el-col>
              <el-col :span="18">
                <!-- Secondary -->
                <el-row
                  v-for="(it, i2) in item.children"
                  :key="it.id"
                  :class="[i2 === 0 ? '' : 'bdtop', 'vcenter']"
                >
                  <the-col>
                    <el-tag
                      type="success"
                      closable
                      @close="delRight(scope.row, it.id)"
                      >{
  
  { it.authName }}</el-tag
                    >
                  </el-col>
                  <!-- Level 3-->
                  <el-col :span="18">
                    <el-tag
                      type="warning"
                      closable
                      v-for="i in it.children"
                      :key="i.id"
                      @close="delRight(scope.row, i.id)"
                      >{
  
  { i.authName }}</el-tag
                    >
                  </el-col>
                </el-row>
              </el-col>
            </el-row>
          </template>
        </el-table-column>
        <el-table-column type="index" label="#"></el-table-column>
        <el-table-column prop="roleName" label="role name" align="center">
        </el-table-column>
        <el-table-column prop="roleDesc" label="role description" align="center">
        </el-table-column>
        <el-table-column label="操作" align="center" width="300px">
          <template slot-scope="scope">
            <el-button
              type="primary"
              size="mini"
              @click="handleEdit(scope.$index, scope.row)"
              >Edit</el-button
            >
            <el-button
              type="success"
              size="mini"
              @click="handleDelete(scope.row)"
              >Delete</el-button
            >
            <el-button type="warning" size="mini" @click="showfen(scope.row)"
              >Assign permissions</el-button
            >
          </template>

Expand all permissions (the attribute that comes with the tree structure: default-expand-all) Display: first check the three-level permissions you have (three-level forEach, get the set of all three-level permissions, and assign them to checklistArr) :default- checked-keys="checklistArr"

After ref is bound, it is convenient to use his events

this.$refs.tree.getCheckedKeys() returns the array composed of the keys of the currently selected nodes this.$refs.tree.getHalfCheckedKeys() returns the array composed of the keys of the currently half-selected nodes data is the bound data []

show-checkbox show checkbox

node-key node key

default-expand-all Whether to expand all nodes by default

default-checked-keys An array of keys of nodes checked by default

props configuration options

permission list

The point is that the level of authority can be used 插槽to v-if v-else-ifjudge the level of authority

commodity management

The product management page is divided into three pages: product classification parameter product list

product list

add edit

Pagination, breadcrumb navigation switching and validation of added and edited forms, and then in order to optimize the project

I encapsulate the addition and editing into components for reuse to make the page clearer.

Implementation of the search function

Bind the value to queryInfo.query using

Pagination @size-change: Listen to the event of page size change @current-change: Listen to the event of page number value change: current-page: current page: page-sizes: number of information items on a page: page-size: current page number layout: control display content: total: the total number of information items

Upload pictures (Upload component, Baidu Web Uploader)

To request an upload interface, a token needs to be set (here is not sending an axios request)

  • :on-removeHook when file list removes files

  • on-successHook when file upload is successful

  • headersSet the upload request header

  • actionupload address

  • on-previewHook when clicking on an uploaded file in the file list

  • list-typeType of file list

classification parameters

The data of this module is divided into dynamic parameters and static attributes, so different requests are sent separately, the obtained data is saved locally, and then rendered using the tabs component, adding, modifying, and deleting functions

  • Cascading selector type=3 shows three-level classification

  • dynamic (involves list expansion), static parameters

  • Query name, price, weight, parameter management

  • Add a detailed description of the product (name, price, focus, quantity, category, parameters, attributes, pictures)

  • Step bar component + vertical tabs component (need to be wrapped in el-form) (parallel relationship)

  • upload image

Categories

On this page we use a new component. tree-table 树形表格First, we need to download the form vue-table-with-tree-grid plugin and import it globally

show-index //serial number
• align="center" //Whether the table text is in the play
•        width="220px"
• index-text="#" // Set the label attribute of the serial number
• :data="list" //All data in the form
• :columns="columns" //Set attributes

I think adding classification is one of the most difficult points of the whole project, it is a three-level linkage

  options: data source
   props: //target object
   value: //selected attribute
• label: //Displayed name
• children: //Nested structure
• v-model: // select the array
• @changed: //The function triggered when the selection item changes

 

Order List

add edit

  • Display: Number of Existing UsersGET

  • Added: user address, mobile phone, reload the page after addingPOST

  • delete: reload page after deletePUT

  • Modification: DELETE1. Change basic information: mobile phone number, user address 2. Change role: related to permissions

  • Component breadcrumbs, search box, table, paging component, switch state transition

Request data state switching, pagination, breadcrumb navigation switching and then validate the added and edited forms, and then optimize the project

I encapsulate the added and edited components into components for reuse, making page deconstruction clearer.

Implementation of the search function

Bind the value to queryInfo.query using

paging
@size-change: Listen to the event of pagesize change
@current-change: Listen to the event that the page number value changes
:current-page: current page
:page-sizes: the number of information items on a page
:page-size: current page size
layout: control display content
:total: total number of messages

Statistics

// Install echarts library npm install echarts -S

// import echarts interface import echarts from 'echarts'

 

Project Difficulties

[Difficulty 1] Authority management

1. When creating a vue instance, it is said that vue-router is mounted, but at this time, vue-router mounts some logins or does not need permissions

public page of .

2. When the user logs in, obtain the user's role, compare the role with the required permissions of each page in the routing table, and generate the end user.

Accessible routing table.

3. Call router.addRoutes to add user-accessible routes.

4. Use vuex to manage the routing table, and render sidebar components according to the routes accessible in vuex.

[Difficulty 2] Three-level permission display, tree structure, row, col structure

A product of requesting a list of roles, so the data is included getRoleListin the return value. Understand the relationship between el-row and el-col, both of which become one-dimensional.

<el-row :gutter="20">
  <el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
  <el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
  <el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
  <el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
</el-row>
{
    "data": [
        {
            "id": 30,
            "roleName": "Supervisor",
            "roleDesc": "Technical Leader",
            "children": [
                {
                    "id": 101,
                    "authName": "Commodity Management",
                    "path": null,
                    "children": [
                        {
                            "id": 104,
                            "authName": "Product List",
                            "path": null,
                            "children": [
                                {
                                    "id": 105,
                                    "authName": "Add Product",
                                    "path": null
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ],
}
<el-row v-for="(item1,i) in scope.row.children" :key="i" class="expand">
    <!-- Put a first-level label in the first column -->
    <el-col :span="4">
        <!-- The label can be removed, the first-level label is displayed here, the method of binding and canceling permissions -->
        <el-tag class="expand" closable @close="delRight(item1.id,scope.row)">{
  
  {item1.authName}}</el-tag>
    </el-col>
    <el-col :span="20">
        <!-- The second column is also one row and two columns -->
        <el-row v-for="(item2,index) in item1.children" :key="index">
            <!-- Put the secondary label in the first column of the second row -->
            <el-col :span="4">
                <el-tag class="expand" type="success" closable @close="delRight(item2.id,scope.row)">{
  
  {item2.authName}}
                </el-tag>
            </el-col>
            <el-col :span="20">
                <el-tag class="expand" @close="delRight(item3.id,scope.row)" closable type="warning"
                    v-for="(item3,indexInner) in item2.children" :key="indexInner">{
  
  {item3.authName}}</el-tag>
            </el-col>
        </el-row>
    </el-col>
</el-row>

[Difficulty 3] Assign permissions, tree structure el-tree select all, half select (how to display)

Expand all permissions (the attribute that comes with the tree structure: default-expand-all) Display: first check the three-level permissions you have (three-level forEach, get the set of all three-level permissions, and assign them to checklistArr) :default- checked-keys="checklistArr" Submit: It is necessary to obtain the set of all the first, second and third level permissions (select all + half select), pass parameters to modify

//show
editRight(role) {
    // The collection of checklist permissions is a tree structure
    this.checklist = role.children
    this.currentRoleId = role.id
    var tmpArr = []
    this.checklist.forEach(item1 => {
        var item2 = item1.children
        item2.forEach(item2 => {
            var item3 = item2.children
            item3.forEach(item3 => {
                tmpArr.push(item3.id)
            })
        })
    })
    this.checklistArr = tmpArr
}
//submit
async confirmRole() {
    let arr1 = this.$refs.mytree.getCheckedKeys()
    let arr2 = this.$refs.mytree.getHalfCheckedKeys()
    let arr = [...arr1, ...arr2]
    const res = await this.$http.post(`roles/${this.currentRoleId}/rights`, { rids: arr.join(',') })
}

[Difficulty 4] The application of the tree component element-tree-grid in the form (component selection, configuration)

Table style: tree structure + [is it valid] [level] [operation] field; Component selection: Since the el-table-column in the first column is to be displayed as a tree structure, use the component element-tree-grid, all props of el-table-column are supported; After obtaining the third-level commodity classification, element-tree-grid only needs to bind the corresponding attributes to display.

 <el-table :data="list" border style="width: 100%">
      <el-table-column type="index" label="#" align="center"></el-table-column>
      <el-table-column prop="authName" label="authority name" align="center">
      </el-table-column>
      <el-table-column prop="path" label="路径" align="center">
      </el-table-column>
      <el-table-column label="permission level" align="center">
        <template v-slot="scope">
          <el-tag v-if="scope.row.level == 0">一级</el-tag>
          <el-tag type="success" v-else-if="scope.row.level == 1">二级</el-tag>
          <el-tag type="warning" v-else>三级</el-tag>
        </template>
      </el-table-column>
    </el-table>

[Difficulty 5] Cascade selector - add classification (understand interface type parameters)

Since the most detailed addition is the third-level classification (or adding the first-level and second-level classification), the cascade selector only needs to display the first-level and second-level parent categories, requesting the classification interface, type=2 value / v-model: Selected The item binding value is the handleChange method of an array cascading selector, which can obtain the closest parent class parameter category id, configuration level and category name, and form an obj as a parameter to send a POST request

<el-dialog
     @close="clearDefault"
      title="Assign Permissions"
      :visible.sync="dialogVisible"
      width="30%"
      :before-close="handleClose"
    >
      <el-tree
        show-checkbox
        default-expand-all
        :default-checked-keys="defaultKeys"
        node-key="id"
        :data="rightstree"
        :props="Propslist"
         ref="treeData"
      ></el-tree>

[Difficulty 6] Classification parameters – only allow setting parameters for three-level classification

  • Cascading selector type=3 shows three-level classification

  • dynamic (involves list expansion), static parameters

How to restrict only the third level to be selected:

handleChange () {
  if (this.selectedOptions.length !== 3) {
    this.$message.warning('Products can only be added to the third-level category')
    this.selectedOptions.length = 0
  }
}

[Difficulty 7] When to render parameters, tabs tab page transformation

el-tab-paneIncluded in it el-tablebind dynamicAttrs el-buttonAfter clicking the cascade selector, render the dynamic and static parameters

async handleChange() {
    if (this.value.length === 3) {
        if (this.active === '1') {
            // dynamic parameter
            const res = await this.$http.get(`categories/${this.value[2]}/attributes?sel=many`)
            this.dynamicAttrs = res.data.data
            this.dynamicAttrs.forEach((item) => {
                // convert attr_vals to array type
                item.attr_vals = item.attr_vals.split(',')
            })
        } else if (this.active === '2') {
            const res1 = await this.$http.get(`categories/${this.value[2]}/attributes?sel=only`)
            this.staticAttrs = res1.data.data
        }
    }
}

project harvest

1. Start from scratch, and after doing it again, the next few modules are relatively similar, and I implemented it myself

2. The biggest gain is to start from getting a project, sort out its functional modules, and then subdivide each module into individual functions such as adding, deleting, modifying, etc., and then implement them one by one

3. When implementing various functions, I learned a lot of logic from the teacher, including the way of thinking about problems. For example, in this project, each function has to be done in the same way. It is nothing more than getting data, processing, rendering, and monitoring user operations. Modify data, submit request

4. There are also scope slots, hierarchical selectors, and tree structures that have not been used much before, appearing in the project,

5. Then there is the use of the axios interceptor, such as the request used when logging in, adding a token to the request when initiating the request, storing the token, and another response, adding the loading effect when obtaining the data;

6. Then I helped myself to review Vue-router and become more familiar with the operation of routing;

7. The use of Element-ui is more proficient

8. I also learned to encapsulate the global button authentication, and encapsulate the added and modified form elements

Guess you like

Origin blog.csdn.net/jiangshen_a/article/details/127630562