vue+elementUI+axios+微信小程序云开发实现项目后台管理系统

一、初始化vue项目

Npm install -g [email protected]

Vue init webpack 项目名称

二、安装对应模块

1.安装elementUI

npm i element-ui -S

2.安装axios
Npm install axios

3.mian.js进行挂载

	import ElementUI from 'element-ui';
	import 'element-ui/lib/theme-chalk/index.css';
	Vue.use(ElementUI);
	import  axios  from  "axios"
	Vue.prototype.$axios = axios;

三、 模块封装

1.封装配置文件 global.js

const  AppID = "wx1b41fefe4f9411d6";
const  AppSecret = "XXXXX"
const  env = "re-test"
const _openid = "XXXXXXXX";

// 表进行集中管理

const tables = {
     
  "typeTable":"c-recipeType",
  "userTable":"c-users",
  "recipetable":"c-recipes"
}

export  default {
     
  AppID,
  AppSecret,
  env,
  _openid,
  tables
}

2.获取accesstoken 方法

// 获取accesstoken  

// GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
import  axios  from  "axios"
import  config  from  "./config.js"

const  getAccessToken = ()=>{
     
  let  url = `/api/cgi-bin/token?grant_type=client_credential&appid=${
     config.AppID}&secret=${
     config.AppSecret}`;
  return  axios.get(url)
}

export default  getAccessToken;

3.调用获取accesstoken

import getAccessToken from "./getAccessToken.js";
// 获取accessToken
const _getAccessToken =   async () => {
     
  let accessToken = await getAccessToken();
  return accessToken.data.access_token;
}

export default  {
     
    _getAccessToken
}

4.代理设置

 proxyTable: {
     
      '/api': {
     
        target:'https://api.weixin.qq.com',
        changeOrigin: true,
        pathRewrite: {
     
          '^/api': ''
        }
      }
    },

四、页面【比较丑陋,见谅】

1.app.vue页面

<template>
  <div id="app">
    <el-container>
      <el-header height="80px">
        <el-link :underline="false" type="primary" style="font-size: 25px;">做菜吧管理系统</el-link>
      </el-header>
      <el-container>
        <el-aside width="200px">
          <!-- 左侧导航 -->
          <v-left-menu></v-left-menu>
        </el-aside>
        <el-main>
          <!-- 路由视图 -->
          <router-view></router-view>
        </el-main>
      </el-container>
      <el-footer height="80px">ICP20200929@做菜吧项目备案信息</el-footer>
    </el-container>
  </div>
</template>

<script>
  import vLeftMenu from "./components/LeftMenu.vue"
  export default {
     
    name: 'app',
    components: {
     
      vLeftMenu
    }
  }
</script>

<style>
  .el-header,
  .el-footer {
     
    background-color: #B3C0D1;
    color: #333;
    line-height: 80px;
  }

  .el-aside {
     
    background-color: #ccc;
    color: #333;
    height: 620px;
  }

  .el-main {
     
    background-color: #fff;
    color: #333;

  }

  .el-footer {
     
    position: fixed;
    bottom: 0px;
    left: 0px;
    width: 100%;
    text-align: center;
    color: #000;
  }
</style>

2.左侧lleft-menu页面

<template>
  <div>
  <el-row class="tac">
    <el-col :span="12">
      <el-menu
        default-active="2"
        class="el-menu-vertical-demo"
        @open="handleOpen"
        @close="handleClose">
        <el-submenu index="1">
          <template slot="title">
            <i class="el-icon-user-solid"></i>
            <span>用户管理</span>
          </template>
          <el-menu-item-group>
            <router-link  to="/user/list"><el-menu-item :underline="false" index="1-1">用户列表</el-menu-item></router-link>
          </el-menu-item-group>
          
        </el-submenu>
      <el-submenu index="2">
        <template slot="title">
          <i class="el-icon-s-unfold"></i>
          <span>分类管理</span>
        </template>
        <el-menu-item-group>
          <router-link to="/type/list"><el-menu-item :underline="false" index="1-1">分类列表</el-menu-item></router-link>
          <router-link to="/type/add"><el-menu-item  :underline="false" index="1-2">分类添加</el-menu-item></router-link>
        </el-menu-item-group>
        
      </el-submenu>
      <el-submenu index="3">
        <template slot="title">
          <i class="el-icon-menu"></i>
          <span>菜谱管理</span>
        </template>
        <el-menu-item-group>
           <router-link to="/recipe/list"><el-menu-item :underline="false" index="1-1">菜谱列表</el-menu-item></router-link>
        </el-menu-item-group>
        
      </el-submenu>
      <el-submenu index="4">
        <template slot="title">
          <i class="el-icon-s-shop"></i>
          <span>关注管理</span>
        </template>
        <el-menu-item-group>
          <router-link to="/follow/list"> <el-menu-item :underline="false" index="1-1">关注列表</el-menu-item></router-link>
        </el-menu-item-group>
        
      </el-submenu>
       
      </el-menu>
    </el-col>
   
  </el-row>
  </div>
</template>

<script>
  export default {
     
    data() {
     
      return {
     

      }
    },
    methods: {
     
      handleOpen(key, keyPath) {
     
        console.log(key, keyPath);
      },
      handleClose(key, keyPath) {
     
        console.log(key, keyPath);
      }
    }
  }
</script>

<style scoped>
  .el-submenu{
     
    width: 196px;
    background-color: #fff;
  }
</style>


3.路由文件(未使用懒加载,未使用路由守卫)

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)
import  UserList   from  "@/pages/users/UserList"
import  FollowList   from  "@/pages/follows/FollowList"
import  RecipeList   from  "@/pages/recipes/RecipeList"
import  TypeAdd   from  "@/pages/types/TypeAdd"
import  TypeList   from  "@/pages/types/TypeList"

const router = new VueRouter({
     
  routes: [
    {
     
      path: '/user/list',
      component: UserList
    },
  {
     
    path: '/follow/list',
    component: FollowList
  },
  {
     
    path: '/recipe/list',
    component: RecipeList
  },
  {
     
    path: '/type/add',
    component: TypeAdd
  },
  {
     
    path: '/type/list',
    component: TypeList
  },
  {
     
    path: '*',
    redirect:"/user/list"
  },
  ]
})

export  default router;

4.用户模块

<template>
  <div>
    <el-table :data="userList" style="width: 100%">
      <el-table-column prop="_id" label="编号" width="400"> </el-table-column>
      <el-table-column prop="_openid" label="用户" width="400">
      </el-table-column>
      <el-table-column prop="userInfo.nickName" label="名称"> </el-table-column>
      <el-table-column align="center">
        <template slot="header" slot-scope="scope"> 头像 </template>
        <template slot-scope="scope">
          <el-image
            style="width: 50px; height: 50px; border-radius: 50%"
            :src="scope.row.userInfo.avatarUrl"
          ></el-image>
        </template>
      </el-table-column>
      <el-table-column align="center">
        <template slot="header" slot-scope="scope"> 操作 </template>
        <template slot-scope="scope">
          <el-button size="mini" @click="handleEdit(scope.$index, scope.row)"
            >Edit</el-button
          >
          <el-button
            size="mini"
            type="danger"
            @click="handleDelete(scope.$index, scope.row)"
            >Delete</el-button
          >
        </template>
      </el-table-column>
    </el-table>
    <el-button-group>
      <el-button type="primary" icon="el-icon-arrow-left" @click="prev"
        >上一页</el-button
      >
      <el-button type="primary" @click="next"
        >下一页<i class="el-icon-arrow-right el-icon--right"></i
      ></el-button>
    </el-button-group>
  </div>
</template>

<script>
import config from "../../utils/config";
export default {
     
  data() {
     
    return {
     
      userList: [], //用户列表
      page: 1,
      limit: 5,
    };
  },
  mounted() {
     
    this.getUsers();
  },
  methods: {
     
    // 执行删除
    handleDelete(index, row) {
     
      this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", {
     
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(async () => {
     
          // console.log('执行删除')
          // 获取条件id
          let _id = row._id;
          // 获取token
          let access_token = await this.$utils._getAccessToken();

          // POST https://api.weixin.qq.com/tcb/databasedelete?access_token=ACCESS_TOKEN
          let result = await this.$axios.post(
            "/api/tcb/databasedelete?access_token=" + access_token,
            {
     
              env: config.env,
              query: `db.collection('${config.tables.userTable}').doc('${_id}').remove()`,
            }
          );

          // console.log(result, "删除");
          if (result.data.deleted == 1) {
     
            this.$message({
     
              type: "success",
              message: "删除成功!",
            });
            this.getUsers();
            // 如果用户删除成功了,需要将所有的用户发布的菜谱都删了
            let res = await this.$axios.post(
              "/api/tcb/databasedelete?access_token=" + access_token,
              {
     
                env: config.env,
                query: `db.collection('${config.tables.recipetable}').where({
     _openid:'${row._openid}'}).remove()`,
              }
            );
              
          }
        })
        .catch(() => {
     
          this.$message({
     
            type: "info",
            message: "已取消删除",
          });
        });
    },
    // 进行修改
    handleEdit() {
     
      this.$message("功能暂时关闭,请删除重新添加!!!");
    },
    // 获取用户信息
    async getUsers() {
     
      let access_token = await this.$utils._getAccessToken();
      let page = this.page;
      let skip = (page - 1) * this.limit;
      let result = await this.$axios.post(
        "/api/tcb/databasequery?access_token=" + access_token,
        {
     
          env: config.env,
          query: `db.collection('${config.tables.userTable}').where({
     }).skip(${
     skip}).limit(${
     this.limit}).get()`,
        }
      );
      if (result.data.data.length <= 0) {
     
        this.$message("最后一页");
        this.page--;
        return;
      }
      result.data.data.map((item, index) => {
     
        result.data.data[index] = JSON.parse(item);
      });

      this.userList = result.data.data;
    },
    // 上一页
    prev() {
     
      if (this.page <= 1) {
     
        this.page = 1;
        return;
      }
      this.page--;
      this.getUsers();
    },

    // 下一页
    next() {
     
      this.page++;
      this.getUsers();
    },
  },
};
</script>

<style scoped>
</style>

5.类别模块(添加)

<template>
  <div>
    <el-form
      :model="ruleForm"
      :rules="rules"
      ref="ruleForm"
      label-width="100px"
      class="demo-ruleForm"
    >
      <el-form-item label="类别名称" prop="name">
        <el-input v-model="ruleForm.name"></el-input>
      </el-form-item>

      <!-- 类别图片功能还未实现 -->
      <el-form-item label="类别图片" prop="name">
        <el-upload
          action="https://jsonplaceholder.typicode.com/posts/"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
        >
          <i class="el-icon-plus"></i>
        </el-upload>
        <!-- 放大图 -->
        <el-dialog :visible.sync="dialogVisible">
          <img width="100%" :src="dialogImageUrl" alt="" />
        </el-dialog>
      </el-form-item>
      <!-- 功能还未实现 -->
      <el-form-item>
        <el-button type="primary" @click="submitForm('ruleForm')"
          >立即添加</el-button
        >
        <el-button @click="resetForm('ruleForm')">重置</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import config from "../../utils/config";
export default {
     
  data() {
     
    return {
     
      // 图片属性
      dialogImageUrl: "",
      dialogVisible: false,

      ruleForm: {
     
        name: "",
      },
      rules: {
     
        name: [
          {
      required: true, message: "请输入菜谱类别名称", trigger: "blur" },
          {
     
            min: 2,
            max: 10,
            message: "长度在 2 到 10 个字符",
            trigger: "blur",
          },
        ],
      },
    };
  },
  mounted() {
     },
  methods: {
     
    handleRemove(file, fileList) {
     
      console.log(file, fileList);
    },
    handlePictureCardPreview(file) {
     
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },

    resetForm(formName) {
     
      this.$refs[formName].resetFields();
    },
    submitForm(formName) {
     
      this.$refs[formName].validate(async (valid) => {
     
        if (valid) {
     
          // POST https://api.weixin.qq.com/tcb/databaseadd?access_token=ACCESS_TOKEN
          // 获取access_token
          let access_token = await this.$utils._getAccessToken();
          // 获取类别名称
          let typeName = this.ruleForm.name;
          // 获取发布者管理员openid
          let _openid = config._openid;
          // 发送请求,进行插入数据库操作
          let result = await this.$axios.post(
            "/api/tcb/databaseadd?access_token=" + access_token,
            {
     
              env: config.env,
              query: `db.collection('${config.tables.typeTable}').add({
     data:[{
     typeName:'${typeName}',_openid:'${_openid}'}]})`,
            }
          );

          // console.log(result,"添加成功")
          if (result.data.id_list.length > 0) {
     
            this.$message("类别添加成功");
            setTimeout(() => {
     
              this.$router.push("/type/list");
            }, 1500);
          }
        } else {
     
          return false;
        }
      });
    },
  },
};
</script>

<style scoped>
</style>

6.类别模块(显示)

<template>
  <div>
    <el-table :data="typesList" style="width: 100%">
      <el-table-column prop="_id" label="编号" width="400"> </el-table-column>
      <el-table-column prop="_openid" label="用户" width="400">
      </el-table-column>
      <el-table-column prop="typeName" label="类名"> </el-table-column>
      <el-table-column align="center">
        <template slot="header" slot-scope="scope"> 操作 </template>
        <template slot-scope="scope">
          <el-button size="mini" @click="handleEdit(scope.$index, scope.row)"
            >Edit</el-button
          >
          <el-button
            size="mini"
            type="danger"
            @click="handleDelete(scope.$index, scope.row)"
            >Delete</el-button
          >
        </template>
      </el-table-column>
    </el-table>
    <el-button-group>
      <el-button type="primary" icon="el-icon-arrow-left" @click="prev"
        >上一页</el-button
      >
      <el-button type="primary" @click="next"
        >下一页<i class="el-icon-arrow-right el-icon--right"></i
      ></el-button>
    </el-button-group>
  </div>
</template>

<script>
import config from "../../utils/config";
export default {
     
  data() {
     
    return {
     
      typesList: [],
      page: 1,
      limit: 5,
    };
  },
  mounted() {
     
    this.getTypes();
  },
  methods: {
     
    // 进行修改
    handleEdit(){
     
      this.$message("功能暂时关闭,请删除重新添加!!!")
    },
    // 执行删除
    handleDelete(index, row) {
     
      this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", {
     
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(async () => {
     
          // console.log('执行删除')
          // 获取条件id
          let _id = row._id;
          // 获取token
          let access_token = await this.$utils._getAccessToken();

          // POST https://api.weixin.qq.com/tcb/databasedelete?access_token=ACCESS_TOKEN
          let result = await this.$axios.post(
            "/api/tcb/databasedelete?access_token=" + access_token,
            {
     
              env: config.env,
              query: `db.collection('${config.tables.typeTable}').doc('${_id}').remove()`,
            }
          );

          // console.log(result, "删除");
          if (result.data.deleted == 1) {
     
            this.$message({
     
              type: "success",
              message: "删除成功!",
            });
            this.getTypes();
          }
        })
        .catch(() => {
     
          this.$message({
     
            type: "info",
            message: "已取消删除",
          });
        });
    },
    // 获取分类列表
    async getTypes() {
     
      let access_token = await this.$utils._getAccessToken();

      // https://api.weixin.qq.com/tcb/databasecollectionget?access_token=ACCESS_TOKEN
      // https://api.weixin.qq.com/tcb/databasequery?access_token=ACCESS_TOKEN
      let page = this.page;
      let skip = (page - 1) * this.limit;
      let result = await this.$axios.post(
        "/api/tcb/databasequery?access_token=" + access_token,
        {
     
          env: config.env,
          // query:
          //   'db.collection("c-recipeType").where({}).skip(' +
          //   skip +
          //   ").limit(" +
          //   this.limit +
          //   ").get()",
            query:`db.collection('${config.tables.typeTable}').where({
     }).skip(${
     skip}).limit(${
     this.limit}).get()`
        }
      );
      // console.log(result.data.data.length)
      if (result.data.data.length <= 0) {
     
        this.$message("最后一页");
        this.page--;
        return;
      }
      result.data.data.map((item, index) => {
     
        result.data.data[index] = JSON.parse(item);
      });

      this.typesList = result.data.data;
    },

    // 上一页
    prev() {
     
      if (this.page <= 1) {
     
        this.page = 1;
        return;
      }
      this.page--;
      this.getTypes();
    },

    // 下一页
    next() {
     
      this.page++;
      this.getTypes();
    },
  },
};
</script>

<style scoped>
</style>

备注:
只写了部分的模块操作,一定要设置好云开发的环境!!!

你可能感兴趣的:(node,微信小程序,vue,vue,小程序)