Vue3实战四:账户管理

目录

1、添加路由

2、api/admin.js API

3、账户Admin.vue

4、个人中心 view/Mine.vue

5、重置密码ResetPwd.vue

6、上传图片组件和上传图片方法

7、Error404.vue


1、添加路由

2、api/admin.js API

增、删、改、查、分页、图片上传

//定义管理员API
import { $get, $post, $setToken } from "../utils/request.js"
import md5 from 'js-md5'
import { $msg_s, $msg_e, $confirm } from '../utils/msg.js'

export let login = async (params) => {
  //解构出ckMe
  let { ckMe } = params
  params.loginPwd = md5(md5(params.loginPwd).split('').reverse().join(''))
  let { success, message, token } = await $get('Admin/Login', params)
  if (success) {
    //sessionStorage缓存数据,浏览器关闭清空
    //localStorage缓存数据,手动清除,否则一直存在浏览器中
    sessionStorage.setItem('token', token)
    $setToken()
    $msg_s(message)
    //登录成功缓存账号
    localStorage.setItem('loginId', params.loginId)

    //判断是否需要记住我
    if (ckMe) {
      //缓存密码
      localStorage.setItem('loginPwd', params.loginPwd)
    }
  } else {
    $msg_e(message)
  }
  return success
}
//自动登录
export let loginAuto = async () => {
  let loginId = localStorage.getItem('loginId')
  let loginPwd = localStorage.getItem('loginPwd')
  if (loginId & loginPwd) {
    let params = {
      loginId,
      loginPwd
    }
    let { success, token } = await $get('Admin/Login', params)
    if (success) {
      sessionStorage.setItem('token', token)
      $setToken()
      return true
    } else {
      return false
    }
  } else {
    return false
  }
}

//查询账户信息
export let list = async (params) => {
  let ret = await $get('Admin/List', params)
  return ret
}
export let add = async (params) => {
  //验证账户信息
  if (!params.loginId) {
    $msg_e("请输入账号")
    return false
  } else if (!params.loginPwd) {
    $msg_e("请输入密码")
    return false

  } else if (params.loginPwd.length < 6) {
    $msg_e("密码长度不得小于6")
    return false

  } else if (params.loginPwd != params.loginPwd2) {
    $msg_e("两次密码不一致")
    return false

  } else if (!params.name) {
    $msg_e("请输入姓名")
    return false
  } else if (!params.phone) {
    $msg_e("请输入电话")
    return false
  } else if (!(/^1\d{10}$/.test(params.phone))) {
    $msg_e("电话格式错误")
    return false
  } else if (params.roleId == 0) {
    $msg_e("请选个角色")
    return false
  }
  // 密码加密
  params.loginPwd = md5(md5(params.loginPwd).split('').reverse().join(''))
  let { success, message } = await $post('Admin/Add', params)
  if (success) {
    $msg_s(message)

  } else {
    $msg_e(message)
  }
  return success
}
//更新
export let update = async (params) => {
  //验证账户信息
  if (!params.name) {
    $msg_e("请输入姓名")
    return false
  } else if (!params.phone) {
    $msg_e("请输入电话")
    return false
  } else if (!(/^1\d{10}$/.test(params.phone))) {
    $msg_e("电话格式错误")
    return false
  } else if (params.roleId == 0) {
    $msg_e("请选个角色")
    return false
  }
  let { success, message } = await $post('Admin/Update', params)
  if (success) {
    $msg_s(message)

  } else {
    $msg_e(message)
  }
  return success
}
//删除
export let del = async (params) => {
  //提示是否确认删除
  await $confirm('确定是否删除')
  let { success, message } = await $post('Admin/Delete', params)
  if (success) {
    $msg_s(message)

  } else {
    $msg_e(message)
  }
  return success
}

//根据账号返回一个账户对象
export let getOne = async (params) => {
  let r = await $get('Admin/GetOne', params)
  return r
}

//重置密码
export let resetPwd = async (params) => {
  if (!params.oldLoginPwd) {
    $msg_e("请输入原始密码")
    return false
  } else if (!params.newLoginPwd) {
    $msg_e("请输入最新密码")
    return false
  } else if (!params.newLoginPwd2) {
    $msg_e("请输入确认密码")
    return false
  } else if (params.newLoginPwd != params.newLoginPwd2) {
    $msg_e("两次密码不一致")
    return false
  }
  params.oldLoginPwd = md5(md5(params.oldLoginPwd).split('').reverse().join(''))
  params.newLoginPwd = md5(md5(params.newLoginPwd).split('').reverse().join(''))
  let { success, message } = await $post('Admin/ResetPwd', params)
  if (success) {
    $msg_s(message)
  } else {
    $msg_e(message)
  }
  return success

}

3、账户Admin.vue

<template>
  <div class="search">
    <span>账号:</span>
    <el-select v-model="roleId" size="small">
      <el-option v-for="item in roleList" :key="item.roleId" :label="item.roleName" :value="item.roleId" />
    </el-select>

    <el-button size="small" type="success" @click="loadTable">查询</el-button>
    <el-button size="small" type="primary" @click="openDrawer = true">添加</el-button>
  </div>
  <el-table size="" :data="tableData" style="width: 100%">
    <el-table-column prop="id" label="编号" width="100" />
    <el-table-column prop="loginId" label="账号" width="100" />
    <el-table-column prop="name" label="姓名" width="100" />
    <el-table-column prop="phone" label="电话" width="120" />
    <!-- <el-table-column prop="photo" label="头像" width="100" /> -->
    <el-table-column label="头像" width="100">
      <template #default="scope">
        <el-image style="width: 60px; height: 60px" :src="admin_photo_base_url + (scope.row.photo || 'default.jpg')"
          fit="cover" />

      </template>
    </el-table-column>
    <el-table-column prop="role.roleName" label="角色" width="100" />

    <el-table-column fixed="right" label="操作" width="180">
      <template #default="scope">
        <el-button size="small" type="warning" @click="handleEdit(scope.row)">编辑</el-button>
        <el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button>
      </template>
    </el-table-column>
  </el-table>
  <div class="pagination">
    <el-pagination background layout="prev, pager, next" :page-size="pageSize" :total="total"
      v-model:current-page="pageIndex" />
  </div>
  <el-drawer v-model="openDrawer" :title="isAdd ? '添加账户' : '修改账户'" size="30%" direction="rtl" :before-close="drawerClose">
    <div class="edititem">
      <span>头像:</span>
      <div>
        <el-upload class="avatar-uploader" :action="admin_upload_url" :show-file-list="false"
          :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload">
          <img v-if="formData.photo" :src="admin_photo_base_url + formData.photo" class="avatar" />
          <el-icon v-else class="avatar-uploader-icon">
            <Plus />
          </el-icon>
        </el-upload>
      </div>
    </div>
    <div class="edititem" v-if="isAdd">
      <span>账号:</span>
      <div><el-input v-model="formData.loginId" placeholder="请输入账号" /></div>
    </div>
    <div class="edititem">
      <span>姓名:</span>
      <div><el-input v-model="formData.name" placeholder="请输入姓名" /></div>
    </div>
    <div class="edititem" v-if="isAdd">
      <span>密码:</span>
      <div><el-input type="password" v-model="formData.loginPwd" placeholder="请输入密码" /></div>
    </div>
    <div class="edititem" v-if="isAdd">
      <span>确认密码:</span>
      <div><el-input type="password" v-model="formData.loginPwd2" placeholder="请输入确认密码" /></div>
    </div>
    <div class="edititem">
      <span>电话:</span>
      <div><el-input v-model="formData.phone" placeholder="请输入电话" /></div>
    </div>
    <div class="edititem">
      <span>角色:</span>
      <el-select v-model="formData.roleId" size="small">
        <el-option v-for="item in roleList" :key="item.roleId" :label="item.roleName" :value="item.roleId" />
      </el-select>

    </div>
    <div class="item">
      <span></span>
      <div>
        <el-button size="small" type="primary" @click="editForm">{{ isAdd ? '添加' : '修改' }}</el-button>
        <el-button size="small" type="default" @click="clearFormData">取消</el-button>
      </div>
    </div>
  </el-drawer>
</template>
<script>
import { list, add, update, del } from '../../api/admin'
import { list as roleList } from '../../api/role'
import { reactive, toRefs, watch } from 'vue'
import { Plus } from '@element-plus/icons-vue'
//上传头像地址和查看头像地址
import { admin_upload_url, admin_photo_base_url } from '../../config/conster'
import { $msg_e } from '../../utils/msg'

export default {
  name: 'Admin',
  setup() {

    let data = reactive({
      //表格数据
      tableData: [],
      roleList: [],

      roleId: 0,
      //当前页
      pageIndex: 1,
      //每页条数
      pageSize: 10,
      //总数量
      total: 0,
      //是否打开抽屉
      openDrawer: false,
      //表单数据
      formData: {
        loginId: '',
        loginPwd: '',
        loginPwd2: '',
        name: '',
        phone: '',
        roleId: '0',
        photo: ''
      },
      //上传账户的地址
      admin_upload_url,
      //查看账户头像根地址
      admin_photo_base_url,

    })
    //加载角色组信息
    let loadRoleList = async () => {
      let ret = await roleList()
      ret.unshift({ roleId: 0, roleName: '请选择角色' })
      data.roleList = ret
    }
    //调用加载角色数组
    loadRoleList()
    data.tableData = [{ id: 1, loginId: 'admin', loginPwd: '', name: '李四', phone: '10086', photo: '', role: { roleId: 2, roleName: '普通管理员' } }, { id: 2, loginId: 'admin2', loginPwd: '', name: '张三', phone: '10087', photo: '', role: { roleId: 1, roleName: '管理员' } }]

    let loadTable = async () => {
      //查询条件
      let params = {
        roleId: data.roleId,
        pageIndex: data.pageIndex,
        pageSize: data.pageSize
      }
      //获取查询结果
      let { count, data: adminData, } = await list(params)
      data.tableData = adminData
      data.total = count
      // data.formData = [{'roleId':'1','roleName':'系统管理员'},{'roleId':'2','roleName':'普通管理员'}]
      console.log(data.formData)
    }
    //执行加载表格数据的方法
    loadTable()
    //监听当前页码是否发生变化
    watch(() => data.pageIndex, () => {
      //执行加载表格数据的方法
      loadTable()

    })
    //头像上传成功指定函数
    let handleAvatarSuccess = (res) => {
      let { filename, success } = res
      if (success) {
        data.formData.phone = filename
      }
      this.imageUrl = URL.createObjectURL(file.raw)
    }
    //头像上传之前调用函数
    let beforeAvatarUpload = (file) => {
      let imgType = ['image/jpeg', 'image/png', 'image/gif']
      const isJPG = imgType.includes(file.type)
      const islt2M = file.size / 1024 / 1024 < 2

      if (!isJPG) {
        $msg_e('请选择正确的图片格式')
        return false
      } else if (!islt2M) {
        $msg_e('图片大小不能超过2M')
        return false
      }
      return true
    }

    let editForm = async () => {
      let r = false
      //判断是执行添加还是修改
      if (data.isAdd) {
        r = await add(data.formData)
        //添加成功清空表单
        if (r) {
          clearFormData()
        }
      } else {
        r = await update(data.formData)
      }
      if (r) {
        loadTable();
      }
    }
    //清空表单
    let clearFormData = () => {
      data.formData = {
        loginId: '',
        loginPwd: '',
        loginPwd2: '',
        name: '',
        phone: '',
        roleId: '0',
        photo: ''
      }

    }
    //关闭抽屉
    let drawerClose = () => {
      data.openDrawer = false
      add.isAdd = true
      clearFormData()
    }

    //执行修改
    let handleEdit = (row) => {
      data.formData = { ...row }
      data.isAdd = false
      data.openDrawer = true
    }
    //执行删除
    let handleDelete = async (row) => {
      let { id } = row
      let r = await del({ id })
      //删除成功,刷新页面
      if (r) {
        loadTable
      }

    }

    return {
      ...toRefs(data),
      loadTable,
      handleAvatarSuccess,
      beforeAvatarUpload,
      drawerClose,
      editForm,
      clearFormData,
      handleEdit,
      handleDelete
    }
  }
}
</script>
<style lang="scss" scoped>
.avatar-uploader {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  width: 178px;
  height: 178px;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader :hover {
  border-color: var(--el-color-primary);
}

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style>

4、个人中心 view/Mine.vue

<template>
  <div class="box">
    <el-image style="width: 100px; height: 100px" 
    :src="admin_photo_base_url+$store.state.admin.photo||'logo.png'" 
    :fit="fill" />
  </div>
  <div class="content">
    <p>账号:admin</p>
    <p>姓名:admin</p>
    <p>电话:18705161482</p>
    <p>角色:管理员</p>
    <!-- <p>账号:{{$store.state.admin.loginId}}</p>
    <p>姓名:{{$store.state.admin.name}}</p>
    <p>电话:{{$store.state.admin.phone}}</p>
    <p>角色:{{$store.state.admin.roleName}}</p> -->
  </div>

</template>
<script>
 //导入头像地址
import {admin_photo_base_url} from "../../config/conster"
export default {
  name: 'Mine',
  setup(){
    return {
      admin_photo_base_url
    }
  }

}
</script>
<style lang="scss" scoped>
.box {
  display: flex;
  .content{
    margin-left: 10px;
    p{
      height: 40px;
    }
  }
}
</style>

5、重置密码ResetPwd.vue

<template>
  <div class="box">
    <div class="edititem" >
        <span>原始密码:</span>
        <div><el-input type="password" v-model="oldLoginPwd" placeholder="请输入原始密码"/></div>
    </div>
    <div class="edititem" >
          <span>最新密码:</span>
          <div><el-input type="password" v-model="newLoginPwd"  placeholder="请输入最新密码"/></div>
    </div>
    <div class="edititem">
          <span>确认密码:</span>
          <div><el-input type="password" v-model="newLoginPwd2" placeholder="请输入确认密码"/></div>
    </div>
    <div class="edititem">
          <span>确认密码:</span>
          <div><el-button  type="primary" @click="editForm">修改</el-button></div>
          <div><el-button  type="default" @click="clearFormData">取消</el-button></div>

    </div>
  </div>

</template>
<script>
import {resetPwd} from '../../api/admin'
import {reactive,toRefs} from 'vue'
import { useStore } from 'vuex'

export default {
  name: 'ResetPwd',
  setup(){
    //获取全局状态管理
    let $store = useStore()
    let data = reactive({
      oldLoginPwd:'',
      newLoginPwd:'',
      newLoginPwd2:'',

    })

    let clearFormData=()=>{
      data.oldLoginPwd=''
      data.newLoginPwd=''
      data.newLoginPwd2=''
    }

    let editForm = async()=>{
      data.id = $store.state.admin.admin.id
      await resetPwd(data)
    }
    return {
      ...toRefs(data),
      clearFormData,
      editForm
    }
  }


}
</script>
<style lang="scss" scoped>
.box{
  width: 400px;
  font-size:16px
}


</style>

6、上传组件和上传方法

    //头像上传成功指定函数
    let handleAvatarSuccess = (res) => {
      let { filename, success } = res
      if (success) {
        data.formData.phone = filename
      }
      this.imageUrl = URL.createObjectURL(file.raw)
    }
    //头像上传之前调用函数
    let beforeAvatarUpload = (file) => {
      let imgType = ['image/jpeg', 'image/png', 'image/gif']
      const isJPG = imgType.includes(file.type)
      const islt2M = file.size / 1024 / 1024 < 2

      if (!isJPG) {
        $msg_e('请选择正确的图片格式')
        return false
      } else if (!islt2M) {
        $msg_e('图片大小不能超过2M')
        return false
      }
      return true
    }

7、Error404.vue

<template>
  <div class="box">
    <img src="../assets/404.jpg" @click="$router.push('/')"/>
  </div>
</template>
<script>
export default{
  name: 'Error404'
}
</script>
<style scoped lang="scss">
.box{
  width: 100vw;
  height: 100vw;
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>

路由配置

  //404
  {
    path: '/:pathMatch(.*)*',
    name: 'Error404',
    component: () => import('../views/Error404.vue')
  }

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值