vue3后台管理系统 vue3+vite+pinia+element-plus+axios上

前言

项目安装与启动

使用vite作为项目脚手架

# pnpm
pnpm create vite my-vue-app --template vue

安装相应依赖

# sass
pnpm i sass
# vue-router
pnpm i vue-router
# element-plus
pnpm i element-plus
# element-plus/icon 
pnpm i @element-plus/icons-vue

安装element-plus按需自动引入插件

pnpm install -D unplugin-vue-components unplugin-auto-import

并在vite.config.js中配置

import { defineConfig } from 'vite'import vue from '@vitejs/plugin-vue'import AutoImport from 'unplugin-auto-import/vite'import Components from 'unplugin-vue-components/vite'import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'export default defineConfig({plugins: [vue(),AutoImport({resolvers: [ElementPlusResolver()],}),Components({resolvers: [ElementPlusResolver()],}),],resolve:{alias: {'@': '/src'}}})

注册elementplus的icon库

import * as ElementPlusIconsVue from '@element-plus/icons-vue'const app = createApp(App)app.use(router).mount('#app')for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component)}

删除helloworld组件和style.css 删除App.vue相应代码

在src目录下创建router文件夹在其中创建index.js 并配置基本内容
import {createRouter,createWebHashHistory} from 'vue-router'
const routes = [
{
path:'/',name:'main',
redirect:"/home",
component:()=>import("@/views/main.vue"),
children:[path:"/home",name:"Home",component:()=>import("@/views/Home.vue")
]}]const router = createRouter({history:createWebHashHistory() ,routes})export default router

并在main.js中注册和在App.vue中使用

//main.js
app.use(router).mount('#app')
//App.vue
<template><router-view></router-view></template>
创建views文件夹,创建Main.vue文件

使用element-plus组件库container布局容器
请添加图片描述

<template><div class="commom-layout"><el-container class="lay-container"><common-aside></common-aside><el-container><el-header class="el-header"><commonHeader></commonHeader></el-header><common-tab></common-tab><el-main class="right-main"><RouterView></RouterView></el-main></el-container></el-container></div></template><script setup>import commonAside from '../components/commonAside.vue';import commonHeader from '../components/commonHeader.vue';import commonTab from '../components/commonTab.vue';</script><style scoped lang="scss">.commom-layout, .lay-container{height:100%;}.el-header{background-color: #333;}</style>
布局已经搭好 让我们完成里面的组件

创建component文件夹创建common-aside.vue文件,也就是el-aside中套了一个el-menu,并使用vue-router中跳转路由,并用pinia
状态管理工具 来控制兄弟组件中的通信
所以需要先引入pinia,并创建store文件夹与index.js文件

pnpm i pinia 
//在main.js
const pinia = createPinia()app.use(pinia)
// store/index.js
import { defineStore } from 'pinia'state:() => {return {isCollapse: true,
menuList:[],
}},
<template><el-aside :width="MenuWidth"><el-menubackground-color="#545c64"text-color="#fff":collapse="isCollapse":collapse-transition="false":default-active="activeMenu"><h3 v-show="!isCollapse">通用后台管理系统</h3><h3 v-show="isCollapse">后台</h3><el-menu-item v-for="item in noChildren" :index="item.path" :key="item.path"@click="handleMenu(item)"><component class="icons" :is="item.icon"></component><span>{{ item.label }}</span></el-menu-item><el-sub-menu v-for="item in hasChildren" :index="item.path" :key="item.path"><template #title><component class="icons" :is="item.icon"></component><span>{{ item.label }}</span></template><el-menu-item-group><el-menu-itemv-for="(subItem,subIndex) in item.children":key="subItem.path":subIndex="subItem.path"@click="handleMenu(subItem)"><component class="icons" :is="subItem.icon"></component><span>{{ subItem.label }}</span></el-menu-item></el-menu-item-group></el-sub-menu></el-menu></el-aside></template><script setup>import { ref, computed } from 'vue'import { useRouter ,useRoute} from 'vue-router';import { useAllDataStore } from '../stores/index.js'// const list = ref([// { path: '/home', name: 'home', label: '首页', icon: 'house', url: 'Home' },// { path: '/mall', name: 'mall', label: '商品管理', icon: 'video-play', url: 'Mall' },// { path: '/user', name: 'user', label: '用户管理', icon: 'user', url: 'User' },// {// path: 'other', label: '其他', icon: 'location', children: [{ path: '/page1', name: 'page1', label: '页面1', icon: 'setting', url: 'Page1' },// { path: '/page2', name: 'page2', label: '页面2', icon: 'setting', url: 'Page2' }]// }])const AllDataStore = useAllDataStore()const list = computed(()=>AllDataStore.$state.menuList)const noChildren = computed(() => list.value.filter(item => !item.children))const hasChildren = computed(() => list.value.filter(item => item.children))const clickMenu = (item) => { router.push(item.path) }const isCollapse = computed(() => AllDataStore.$state.isCollapse)const MenuWidth= computed(() => AllDataStore.$state.isCollapse ? '64px' : '180px')const router = useRouter()const route = useRoute()const activeMenu = computed(()=>route.path)const handleMenu= (item) => {router.push(item.path)AllDataStore.selectMenu(item)}</script>
<style lang="scss" scoped>
// var asideColor: #545c64;
.icons{
height:18px;
width:18px;
margin-right:5px;
}
.el-menu{
border-right:none;
h3{
line-height:48px;
color:#fff;
text-align:center;
}
}
.el-aside{
height:100%;
background-color: #545c64;
}
</style>
comonheader组件搭建 使用下拉框el-dropdown和面包屑el-breadcrumb
<template><div class="header"><div class="l-content"><el-button size="small" @click="handleCollapse"><component class="icons" is="menu"></component></el-button><el-breadcrumb separator="/" class="bread"><el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item></el-breadcrumb></div><div class="r-content"><el-dropdown><span class="el-dropdown-link"><span><img :src="getImageUrl('user')" class="user"></span></span><template #dropdown><el-dropdown-menu><el-dropdown-item>个人中心</el-dropdown-item><el-dropdown-item @click="handleLoginOut">退出</el-dropdown-item></el-dropdown-menu></template></el-dropdown></div></div></template><script setup>import {useAllDataStore}from '../stores/index.js'import {useRouter}from 'vue-router'import {computed} from 'vue'const AllData = useAllDataStore()const getImageUrl = (user) => {return new URL(`../assets/images/${user}.png`,import.meta.url).href}const handleCollapse = () => {AllData.$state.isCollapse = !AllData.$state.isCollapse}</script><style lang="scss" scoped>.header {display:flex;justify-content: space-between;align-items: center;height:100%;width:100%;background-color: #333;}.icons{height:20px;width:20px;}.l-content{display: flex;align-items: center;.el-button{margin-right:20px;}}.r-content{.user{width:40px;height:40px;border-radius: 50%;outline: none;}}//样式穿透:deep(.bread span){color:#fff !important;cursor:pointer !important;}</style>
接下来实现首页剩余内容

使用elementplus中的layout布局 通过基础的 24 分栏,迅速简便地创建布局,在使用el-card卡片来分隔不同内容
请添加图片描述

<template><el-row class="home" :gutter="20"><el-col :span="8" style="margin-top:20px"><el-card shadow="hover"><div class="user"><img :src="getImageUrl('user')" class="user"/><div class="user-info"><p class="user-info-admin">Admin</p><p class="user-info-p">超级管理员</p></div></div><div class="login_info"><p>上次登陆时间:<span>2024-07-24</span></p><p>上次登陆地点:<span>北京</span></p></div></el-card><el-card shadow="hover" class="user-table"><el-table :data="tableData"><el-table-columnv-for="(val,key) in tableLabel":key = "key":prop = "key":label = "val"></el-table-column></el-table></el-card></el-col><el-col :span="16" style="margin-top:20px"><div class="num"><el-card :body-style="{display:'flex', padding:0}"v-for="item in countData":key="item.name"><component :is="item.icon" class="icons" :style="{background:item.color}"></component><div class="detail"><p class="num">${{ item.value }}</p><p class="txt">${{ item.name }}</p></div></el-card></div><el-card class="top-echart"><div ref="echart" style="height:230px"></div></el-card><div class="graph"><el-card><div ref="userEchart" style="height:240px"></div></el-card><el-card><div ref="videoEchart" style="height:240px"></div></el-card></div></el-col></el-row></template><script setup>import {ref,getCurrentInstance,onMounted,reactive} from 'vue'import * as echarts from 'echarts'const {proxy} = getCurrentInstance()const getImageUrl = (user) => {return new URL(`../assets/images/${user}.png`,import.meta.url).href}const observer =ref(null)const tableData = ref([])const countData = ref([])const chartData = ref([])const tableLabel = ref({name: "课程",todayBuy: "今日购买",monthBuy: "本月购买",totalBuy: "总购买",})const getTableData = async () => {const data = await proxy.$api.getTableData()tableData.value = data.tableData}const getCountData = async () => {const data = await proxy.$api.getCountData()countData.value = data}const xOptions = reactive({// 图例文字颜色textStyle: {color: "#333",},legend: {},grid: {left: "20%",},// 提示框tooltip: {trigger: "axis",},xAxis: {type: "category", // 类目轴data: [],axisLine: {lineStyle: {color: "#17b3a3",},},axisLabel: {interval: 0,color: "#333",},},yAxis: [{type: "value",axisLine: {lineStyle: {color: "#17b3a3",},},},],color: ["#2ec7c9", "#b6a2de", "#5ab1ef", "#ffb980", "#d87a80", "#8d98b3"],series: [],})const pieOptions = reactive({tooltip: {trigger: "item",},legend: {},color: ["#0f78f4","#dd536b","#9462e5","#a6a6a6","#e1bb22","#39c362","#3ed1cf",],series: []})const getChartData = async () => {const {orderData,userData,videoData}= await proxy.$api.getChartData()xOptions.xAxis.data = orderData.date;xOptions.series = Object.keys(orderData.data[0]).map(val=>({name:val,data:orderData.data.map(item => item[val]),type:'line'}))const oneEchart = echarts.init(proxy.$refs['echart'])oneEchart.setOption(xOptions)xOptions.xAxis.data = userData.map(item => item.date)xOptions.series=[{name:'新增用户',data:userData.map(item=>item.new),type:'bar'},{name:'活跃用户',data:userData.map(item=>item.active),type:'bar'}]const twoEchart = echarts.init(proxy.$refs['userEchart'])twoEchart.setOption(xOptions)pieOptions.series = [{data:videoData,type:'pie',}]const threeEchart = echarts.init(proxy.$refs['videoEchart'])threeEchart.setOption(pieOptions)//监听页面的变化observer.value = new ResizeObserver(() => {oneEchart.resize()twoEchart.resize()threeEchart.resize()})if(proxy.$refs['echart']){observer.value.observe(proxy.$refs["echart"])}}onMounted(() => {getTableData()getCountData()getChartData()})</script><style lang="scss" scoped>.home{height:150vh;overflow:hidden;.user{display:flex;align-items:center;border-bottom:1px solid #ccc;margin-bottom:20px;img{width:150px;height:150px;border-radius: 50%;margin-right: 40px;}.user-info{p{line-height:40px;}.user-info-p{color:#999;}.user-info-admin{font-size:35px;}}}.login_info{p{line-height:30px;font-size:14px;color:#990;}span{color:#666;margin-left:60px;}}.user-table{margin-top:20px;}.num {display: flex;flex-wrap: wrap;justify-content: space-between;.el-card {width: 32%;margin-bottom: 20px;}.icons {width: 80px;height: 80px;font-size: 30px;text-align: center;line-height: 80px;color: #fff;}.detail {margin-left: 15px;display: flex;flex-direction: column;justify-content: center;.num {font-size: 30px;margin-bottom: 10px;}.txt {font-size: 14px;text-align: center;color: #999;}}}.graph {margin-top: 20px;display: flex;justify-content: space-between;.el-card {width: 48%;height: 260px;}}}</style>
没有后端 我们用mock来模拟网络请求 使用axios来处理网络请求
pnpm i axios
pnpm i mockjs
创建api文件夹 创建request.js 文件 二次封装下axios
import axios from "axios";import config from '../config/index'const service = axios.create({baseURL:config.baseApi,});const NETWORK_ERROR = '网络错误...'service.interceptors.request.use((config) => {return config},(error) => {return Promise.reject(error)})service.interceptors.response.use((res) => {const {code,data,msg} = res.dataif(code===200){return data}else{return Promise.reject(msg || NETWORK_ERROR)}})function request(options){// console.log(config.env)options.method = options.method || "get"if(options.method.toLowerCase() === "get"){options.params = options.data}//对mock的开关做一个处理let isMock = config.mockif(config.env !== "undefined"){isMock = config.env}//针对环境作处理if(config.env === "prod"){service.defaults.baseURL = config.baseAPi;}else{// console.log('isMock',isMock)service.defaults.baseURL = isMock ? config.mockApi : config.baseApi;}return service(options)}export default request

在api文件下创建api.js

import request from './request.js'export default {getTableData(){return request({url:"/home/getTable",method:'get',})},getCountData(){return request({url:"/home/getCountData",method:'get',})},getChartData(){return request({url:"/home/getChartData",method:'get',})},}

使用mock模拟请求 在api文件下创建mockData下创建home.js 并在api目录下创建mock.js作为出口

//mock.js
import Mock from "mockjs"
import homeApi from "./mockData/home.js"
Mock.mock(/api\/home\/getTableData/,"get",homeApi.getTableData)Mock.mock(/api\/home\/getCountData/,"get",homeApi.getCountData)Mock.mock(/api\/home\/getChartData/,"get",homeApi.getChartData)
// mockData/home.js
export default {getTableData: () => {return {code: 200,data: {tableData: [{name: "oppo",todayBuy: 500,monthBuy: 3500,totalBuy: 22000,},{name: "vivo",todayBuy: 300,monthBuy: 2200,totalBuy: 24000,},{name: "苹果",todayBuy: 800,monthBuy: 4500,totalBuy: 65000,},{name: "小米",todayBuy: 1200,monthBuy: 6500,totalBuy: 45000,},{name: "三星",todayBuy: 300,monthBuy: 2000,totalBuy: 34000,},{name: "魅族",todayBuy: 350,monthBuy: 3000,totalBuy: 22000,},],},}},getCountData: () => {return {code: 200,data: [{name: "今日支付订单",value: 1234,icon: "SuccessFilled",color: "#2ec7c9",},{name: "今日收藏订单",value: 210,icon: "StarFilled",color: "#ffb980",},{name: "今日未支付订单",value: 1234,icon: "GoodsFilled",color: "#5ab1ef",},{name: "本月支付订单",value: 1234,icon: "SuccessFilled",color: "#2ec7c9",},{name: "本月收藏订单",value: 210,icon: "StarFilled",color: "#ffb980",},{name: "本月未支付订单",value: 1234,icon: "GoodsFilled",color: "#5ab1ef",},],};},getChartData: () => {return {code: 200,data: {orderData: {date: ["2019-10-01","2019-10-02","2019-10-03","2019-10-04","2019-10-05","2019-10-06","2019-10-07",],data: [{苹果: 3839,小米: 1423,华为: 4965,oppo: 3334,vivo: 2820,一加: 4751,},{苹果: 3560,小米: 2099,华为: 3192,oppo: 4210,vivo: 1283,一加: 1613,},{苹果: 1864,小米: 4598,华为: 4202,oppo: 4377,vivo: 4123,一加: 4750,},{苹果: 2634,小米: 1458,华为: 4155,oppo: 2847,vivo: 2551,一加: 1733,},{苹果: 3622,小米: 3990,华为: 2860,oppo: 3870,vivo: 1852,一加: 1712,},{苹果: 2004,小米: 1864,华为: 1395,oppo: 1315,vivo: 4051,一加: 2293,},{苹果: 3797,小米: 3936,华为: 3642,oppo: 4408,vivo: 3374,一加: 3874,},],},videoData: [{ name: "小米", value: 2999 },{ name: "苹果", value: 5999 },{ name: "vivo", value: 1500 },{ name: "oppo", value: 1999 },{ name: "魅族", value: 2200 },{ name: "三星", value: 4500 },],userData: [{ date: "周一", new: 5, active: 200 },{ date: "周二", new: 10, active: 500 },{ date: "周三", new: 12, active: 550 },{ date: "周四", new: 60, active: 800 },{ date: "周五", new: 65, active: 550 },{ date: "周六", new: 53, active: 770 },{ date: "周日", new: 33, active: 170 },],},};}}

最终效果
请添加图片描述

如果对你有所帮助就点个关注吧

本文是这篇文章的笔记
https://www.bilibili.com/video/BV1LS421d7cY?p=5&vd_source=e73709c9a1618b4c6dfd58c6c40d8986

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/387491.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++第一篇 入门基础

目录 1.C的第一个程序 2.c历代版本 3.命名空间 3.1 namespace关键字 namespace的用法&#xff1a; namespace中定义函数 namespace中定义结构体 C中的域&#xff1a; 3.2就近原则 4.命名空间的使用 5.C输入输出 6.缺省参数 全缺省: 半缺省:必须从右往左连续缺省(也…

爆“卷”的AI视频,大厂向左,创企向右

文&#xff5c;白 鸽 编&#xff5c;王一粟 “生成的人物一转身就变成老外&#xff0c;怎么解决呢&#xff1f;” “没有办法&#xff0c;10s中动作大的&#xff0c;人物一致性有问题&#xff0c;只能抽卡&#xff0c;多刷几个&#xff0c;选择一个变化不大的。” 在一个以…

RocketMQ Server Windows安装

RocketMQ阿里开发 开源给apache 官网:RocketMQ 官方网站 | RocketMQ 下载后解压 配置环境变量 注意启动顺序 双击 注意 4.9.0这个版本必须 jdk 8 高了用不了 namesrv是注册中心的作用 broke是核心用于接收生产者消息 存储消息 发送给消费者消息 类似DubboZookeeper…

Java红娘相亲交友平台系统源码小程序

&#x1f495;遇见真爱&#xff0c;从“红娘相亲交友平台系统”开始&#xff01;&#x1f46b; &#x1f339;【精准匹配&#xff0c;缘分不再擦肩而过】 还在为茫茫人海中找不到那个TA而烦恼吗&#xff1f;“红娘相亲交友平台系统”利用先进的大数据分析技术&#xff0c;根据…

匿名内部类

一个类的内部又完整的嵌套了另一个类结构&#xff0c;被嵌套的类称为内部类&#xff0c;嵌套其他的类称为外部类。 类的五大成员&#xff1a;属性、方法、构造器、代码块、内部类 内部类最大的特点的就是直接访问私有属性&#xff0c;并且可以体现类鱼类之间的包含关系。 基本…

北斗三号海上人员落水报警及示位搜救系统升级方案

随着海洋经济的快速发展&#xff0c;海上作业活动日益频繁&#xff0c;人员安全问题也日益凸显。传统的海上救援手段存在诸多不足&#xff0c;如救援响应时间长、定位不准确等。为了提高海上救援的效率和成功率&#xff0c;北斗三号海上人员落水报警及示位搜救系统应运而生。该…

微波传感器 - 从零开始认识各种传感器【第二十期】

微波传感器|从零开始认识各种传感器 1、什么是微波传感器 微波传感器是一种利用微波技术进行探测和测量的传感器。 一般来说&#xff0c;微波是波长为1到1000毫米的电磁波。使用微波传感器&#xff0c;在不接触目标物体的情况下&#xff0c;通过检测和分析微波信号的反射、散…

Matplotlib柱形图大揭秘:让数据‘站’起来,比增高鞋垫还管用!

1. Matplotlib绘制柱形图/柱状图/条形图 柱状图是一种用矩形柱来表示数据分类的图表&#xff0c;柱状图可以垂直绘制&#xff0c;也可以水平绘制&#xff0c;它的高度与其表示的数据成正比关系 # 导包 import numpy as np import pandas as pd import matplotlib.pyplot as p…

机械学习—零基础学习日志(高数16——函数极限性质)

零基础为了学人工智能&#xff0c;真的开始复习高数 这里我们继续学习函数极限的性质。 局部有界性 充分条件与必要条件 极限存在是函数局部有界的充分条件。什么是充分条件&#xff0c;什么是必要条件呢&#xff1f;我这里做了一点小思考&#xff0c;和大家分享&#xff0c…

Windows11下 Visual Studio 2022 + Qt6 的 WebSocket 线程池异步 客户端

Windows11下 Visual Studio 2022 + Qt6 的 WebSocket 线程池异步 客户端 1 开发 WebSocket 客户端1.1 开发环境1.1.1 为Qt 6安装 websockets1.2 .基于Qt6的 QWebSocket 客户端示例1.2.1 实现 WebSocket 客户端1.2.2 创建 QtQWesocketClient1.2.3 创建QWebsocket对象1.2.3.1 添加…

iOS object-C 解答算法:找到所有数组中消失的数字(leetCode-448)

找到所有数组中消失的数字(leetCode-448) 题目如下图:(也可以到leetCode上看完整题目,题号448) 光看题看可能有点难以理解,我们结合示例1来理解一下这道题. 有8个整数的数组 nums [4,3,2,7,8,2,3,1], 求在闭区间[1,8]范围内(即1,2,3,4,5,6,7,8)的数字,哪几个没有出现在数组 …

新装centos7虚拟机如何配置网络,NAT配置固定IP

首先声明&#xff0c;我想使用的是NAT连接模式&#xff0c;并且设置完IP之后&#xff0c;使得这个IP固定住&#xff0c;以后不会再变了。 文章目录 1&#xff0c;打开Vmware软件的【编辑】-【虚拟网络编辑器】2&#xff0c;先选择VMnet8&#xff08;画1处&#xff09;&#xf…

解析capl文件生成XML Test Module对应的xml工具

之前一直用的CAPL Test Module来写代码&#xff0c;所有的控制都是在MainTest()函数来实现的&#xff0c;但是有一次&#xff0c;代码都写完了&#xff0c;突然需要用xml的这种方式来实现&#xff0c;很突然&#xff0c;之前也没研究过&#xff0c;整理这个xml整的一身汗&#…

Hive3:库操作常用语句

1、创建库 create database if not exists myhive;2、选择库 use myhive;3、查看当前选择的库 SELECT current_database();4、查看库详细信息 desc database myhive;可以查看数据文件在hdfs集群中的存储位置 5、创建库时制定hdfs的存储位置 create database myhive2 …

安全防护软件的必要性:从微软蓝屏事件谈起

最近微软遭遇了的大规模蓝屏事件&#xff0c;让全球很多用户措手不及。这次事件告诉我们&#xff0c;保护我们的电脑和数据&#xff0c;安全防护软件是多么重要。 微软蓝屏事件源于网络安全公司CrowdStrike的技术更新错误&#xff0c;导致全球范围内大量Windows用户系统崩溃&a…

什么是五力分析?5分钟带你了解它在企业财务经营中的应用与价值!

如今&#xff0c;随着全球化进程的不断加速&#xff0c;市场环境复杂多变&#xff0c;市场竞争日益激烈&#xff0c;财务经营已经成为了企业应对复杂市场环境、保持自身竞争力的关键。体系化的五力分析平台能够为企业提供一套全面的解决方案&#xff0c;帮助企业在盈利能力、偿…

HamonyOS性能优化工具和方法

性能优化&#xff0c;如何做到更快的启动、更流畅的使用&#xff0c;概括图如下 ArkTS高性能编程&#xff1a; 1. ArkTS规则&#xff1a;有利于方舟编译运行时进行编译优化 2. 使用AOT(Ahead Of Time)模式对应用进行编译优化&#xff1a;方舟编译运行时通过采用PGO(Profile-Gui…

React 学习——组件内通信(兄弟之间)

A组件 > B组件 核心思路&#xff1a; 1、A组件先通过子传父的方式把数据传给父组件App 2、App拿到数据后通过父传子的方式再传递给B组件 import { useState } from "react" function A({onGetMsg}){const AMsg 我是A组件的消息return (<div><button…

ESP-ADF适配到自定义开发板中

ESP-ADF适配到自定义开发板中 前言:项目开发完了,来记录一下开发过程。 安装: 这里采用vscode+ESP-IDF+ESP-ADF的开发方式。 安装esp-idf的方法很简单,网上都是,这里不说了。想用esp-adf那么你idf的环境肯定是已经搭建好了。 安装adf也很简单,一步完成。 按下F1,选…

鸿蒙对接极光推送时候报错1000900010,厂商token获取失败

在AppGallery Connect上配置项目的调试证书&#xff0c;然后手动导入&#xff0c;不要用IDE的自动构建证书&#xff1a; https://developer.huawei.com/consumer/cn/service/josp/agc/index.html#/