一、编辑部门
src/utils创建ObjCopy.js
//快速把obj1里面对应的东西复制到obj2中去
export default async function objCopy(pbj1,obj2){
Object.keys(obj2).forEach(key=>{
obj2[key]=obj1[key]
})
}
src/views/system/department.vue
onConfirm(){
//表单验证
this.$refs.deptForm.validate(async(valid)=>{
//如果验证通过
if(valid){
let res=null;
//判断当前是新增还是修改(依据:dept的id是否为空)
//发送添加请求
if(this.dept.id===""){
res = await departmentApi.addDept(this.dept)
}else{
//发送修改请求
res = await departmentApi.updateDept(this.dept)
}
//判断是否成功
if(res.success){
//提示成功
this.$message.success(res.message);
//刷新
this.search();
//关闭窗口
this.deptDialog.visible=false;
}else{
//提示失败
this.$message.error(res.message);
}
}
})
},
src/api/department.js
/**
* 编辑部门
*/
async updateDept(params){
return await http.put("/api/department/update",params);
}
删除部门
src/apidepartment.js
/**
* 检查部门下是否存在子部门
*/
async checkDepartment(params){
return await http.getRestApi("/api/department/check",params);
},
/**
* 删除部门
*/
async deleteById(params){
return await http.delete("/api/department/delete",params);
}
二、权限管理菜单
src/views/system/menu/menu.vue
<template>
<el-main>
<!-- 新增按钮 -->
<el-button
type="success"
size="small"
@click="openAddWindow()"
icon="el-icon-plus"
>新增</el-button>
<!-- 数据表格 -->
<el-table
:data="menuList"
:height="tableHeight"
style="width:100%;margin-bottom:20px"
row-key="id"
border
default-expand-all
:tress-props="{children:'children'}"
>
<el-table-column prop="label" label="菜单名称"></el-table-column>
<el-table-column prop="type" label="菜单类型" align="center">
<template slot-scope="scope">
<el-tag size="normal" v-if="scope.row.type===0">目录</el-tag>
<el-tag size="normal" type="success" v-else-if="scope.row.type===1">菜单</el-tag>
<el-tag size="normal" type="warning" v-else>按钮</el-tag>
</template>
</el-table-column>
<el-table-column prop="icon" label="菜单图标">
<template slot-scope="scope">
<i :class="scope.row.icon" v-if="scope.row.icon.includes('el-icon')"></i>
<svg-icon v-else :icon-class="scope.row.icon"></svg-icon>
</template>
</el-table-column>
<el-table-column prop="name" label="路由名称"></el-table-column>
<el-table-column prop="path" label="路由地址"></el-table-column>
<el-table-column prop="url" label="组件路径"></el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button
type="primary"
icon="el-icon-edit"
size="small"
@click="ediMenu(scope.row)"
>编辑
</el-button>
<el-button
type="danger"
size="small"
icon="el-icon-delete"
@click="deleteMenu(scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-main>
</template>
<script>
//导入menu.js脚本文件
import menuApi from '@/api/menu';
export default {
name:"menuList",
data(){
return{
menuList:[],//数据列表
tableHeight:0,//表格高度
}
},
created(){
//查询菜单列表
this.search();
},
mounted(){
this.$nextTick(()=>{
this.tableHeight=window.innerHeight-180;
});
},
methods:{
/**
* 查询菜单列表
*/
async search(){
//发送查询请求
let res=await menuApi.getMenuList();
//判断是否成功
if(res.success){
this.menuList=res.data;
}
},
/**
* 打开新增窗口
*/
openAddWindow(){
},
}
}
</script>
<style lang="scss" scoped >
</style>
src/api创建menu.js
import http from '@/utils/request';
export default{
/*
*查询权限菜单列表
*/
async getMenuList(params){
await http.get("/api/permission/list",params);
}
}
优化滚动条
public/index.html
<style>
::-webkit-scrollbar{
width:5px;
height:5px;
background-color: #F5F5F5;
}
::-webkit-scrollbar-track{
box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.3);
border-radius:8px;
background-color: #F5F5F5;
}
::-webkit-scrollbar-thumb{
border-radius:8px;
box-shadow: inset 0 0 6px rgba(0,0,0,.1);
background-color: #c8c8c8;
}
</style>
新增权限菜单
src/views/system/menu/menuList.vue
<template>
<el-main>
<!-- 新增按钮 -->
<el-button
type="success"
size="small"
@click="openAddWindow()"
icon="el-icon-plus"
>新增</el-button>
<!-- 数据表格 -->
<el-table
:data="menuList"
:height="tableHeight"
style="width:100%;margin-bottom:20px"
row-key="id"
border
default-expand-all
:tress-props="{children:'children'}"
>
<el-table-column prop="label" label="菜单名称"></el-table-column>
<el-table-column prop="type" label="菜单类型" align="center">
<template slot-scope="scope">
<el-tag size="normal" v-if="scope.row.type===0">目录</el-tag>
<el-tag size="normal" type="success" v-else-if="scope.row.type===1">菜单</el-tag>
<el-tag size="normal" type="warning" v-else>按钮</el-tag>
</template>
</el-table-column>
<el-table-column prop="icon" label="菜单图标">
<template slot-scope="scope">
<i :class="scope.row.icon" v-if="scope.row.icon.includes('el-icon')"></i>
<svg-icon v-else :icon-class="scope.row.icon"></svg-icon>
</template>
</el-table-column>
<el-table-column prop="name" label="路由名称"></el-table-column>
<el-table-column prop="path" label="路由地址"></el-table-column>
<el-table-column prop="url" label="组件路径"></el-table-column>
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button
type="primary"
icon="el-icon-edit"
size="small"
@click="ediMenu(scope.row)"
>编辑
</el-button>
<el-button
type="danger"
size="small"
icon="el-icon-delete"
@click="deleteMenu(scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 新增或修改窗口-->
<system-dialog
:title="menuDialog.title"
:visible="menuDialog.visible"
:width="menuDialog.width"
:height="menuDialog.height"
@onClose="onClose()"
@onConfirm="onConfirm()"
>
<div slot="content">
<el-form
:model="menu"
ref="menuForm"
:rules="rules"
label-width="80px"
inline="true"
size="small"
>
<el-col :span="24" >
<el-form-item label="菜单类型" prop="type">
<el-radio-group v-model="menu.type" >
<el-radio :label="0">目录</el-radio>
<el-radio :label="1">菜单</el-radio>
<el-radio :label="2">按钮</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-form-item label="所属菜单" size="small" prop="parentName">
<el-input
@click.native="selectParentMenu"
v-model="menu.parentName"
:readonly="ture"></el-input>
</el-form-item>
<el-form-item label="菜单名称" size="small" prop="label">
<el-input v-model="menu.label" ></el-input>
</el-form-item>
<el-form-item
v-if="menu.type==1"
label="路由名称"
size="small"
prop="name">
<el-input v-model="menu.name"/>
</el-form-item>
<el-form-item
label="路由地址"
v-if="menu.type!=2"
size="small"
prop="path">
<el-input v-model="menu.path"/>
</el-form-item>
<el-form-item
label="组件路由"
v-if="menu.type==1"
size="small"
prop="url">
<el-input v-model="menu.url"/>
</el-form-item>
<el-form-item label="限权字段" size="small" prop="code">
<el-input v-model="menu.label" ></el-input>
</el-form-item>
<el-form-item label="菜单图标" size="small">
<el-input v-model="menu.icon" />
</el-form-item>
<el-form-item label="菜单序号" size="small">
<el-input v-model="menu.orderNum" ></el-input>
</el-form-item>
</el-form>
</div>
</system-dialog>
</el-main>
</template>
<script>
//导入menu.js脚本文件
import menuApi from '@/api/menu';
//导入对话框组件
import SystemDialog from '@/components/system/SystemDialog.vue'
export default {
name:"menuList",
components:{
SystemDialog
},
data(){
return{
menuList:[],//数据列表
tableHeight:0,//表格高度
menuDialog:{
title:"新增菜单",
width:630,
height:270,
visible:false,
},
//菜单属性
menu:{
id:"",
type:"",
parentId:"",
label:"",
icon:"",
name:"",
path:"",
url:"",
code:"",
orderNum:"",
},
rules:{
type:[{required:true,tigger:"change",message:"请选择菜单类型"}],
type:[{required:true,tigger:"change",message:"请选择所属菜单"}],
type:[{required:true,tigger:"blur",message:"请输入菜单名称"}],
type:[{required:true,tigger:"blur",message:"请输入路由名称"}],
type:[{required:true,tigger:"blur",message:"请输入路由地址"}],
type:[{required:true,tigger:"blur",message:"请输入组件路由"}],
type:[{required:true,tigger:"blur",message:"请输入权限字段"}],
},
};
},
created(){
//查询菜单列表
this.search();
},
mounted(){
this.$nextTick(()=>{
this.tableHeight=window.innerHeight-180;
});
},
methods:{
/**
* 查询菜单列表
*/
async search(){
//发送查询请求
let res=await menuApi.getMenuList();
//判断是否成功
if(res.success){
this.menuList=res.data;
}
},
/**
* 打开新增窗口
*/
openAddWindow(){
//清空表单数据
this.$resetForm("menuForm",this.menu);
//设置窗口标题
this.menuDialog.title="新增菜单"
//显示窗口
this.menuDialog.visible=true;
},
/**
* 关闭取消按钮点击事件
*/
onClose(){
//关闭窗口
this.menuDialog.visible=false;
},
/**
* 确定按钮点击事件
*/
onConfirm(){
//表单验证
this.$refs.menuForm.validate((valid)=>{
if(valid){
//关闭窗口
this.menuDialog.visible=false;
}
})
},
/**
* 选择所属菜单
*/
selectParentMenu(){
}
}
}
</script>
<style lang="scss" scoped >
</style>
编写所属权限菜单
src/api/menu.js
/**
* 获取上级菜单
*/
async getParentMenuList(params){
return await http.get("/api/permission/parent/list",params)
}
src/views/system/menu/menuList.vue
<!-- 选择上级菜单 -->
<system-dialog
:title="parentDialog.title"
:width="parentDialog.width"
:height="parentDialog.height"
:visible="parentDialog.visible"
@onClose="onParentClose"
@onConfirm="onParentConfirm"
>
<div slot="content">
<el-tree
style="font-size:14px"
ref="parentTree"
:data="parentMenulist"
node-key="id"
:props="defaultProps"
empty-text="暂无数据"
:show-checkbox="false"
default-expand-all
:highlight-current="ture"
:expand-on-click-node="false"
@node-click="handleNodeClick"
>
<div classs="customer-tree-node" slot-scope="{node,data}">
<!-- 长度为0说明没有下级 -->
<span v-if="data.children.length==0">
<i
class="el-icon-document"
style="color: #8c8c8c; font-size:18px"
></i>
</span>
<span v-else @click.stop="openBtn(data)">
<svg-icon v-if="data.open" icon-class="add-s" />
<svg-icon v-else icon-class="sub-s" />
</span>
<span style="margin-left:3px">{{node.label}}></span>
</div>
</el-tree>
</div>
</system-dialog>
/**
* 选择所属菜单
*/
async selectParentMenu(){
//显示窗口
this.parentDialog.visible=true;
//发送查询请求
let res =await menuApi.getParentMenuLIst();
//判断是否成功
if(res.success){
//赋值
this.parentMenuList=res.data;
}
},
/**
* 选择所属菜单取消事件
*/
onParentClose(){
this.parentDialog.visible=false //关闭窗口
},
/**
* 选择所属菜单确定事件
*/
onParentConfirm(){
this.parentDialog.visible //关闭窗口
},
/**
* 切换图标
*/
openBtn(data){
data.open=!data.open
this.$refs.parentTress.store.nodesMap[data.id].expanded =!data.open
},
/**
* 所属菜单节点点击事件
*/
handleNodeClick(data){
//所属父级菜单ID
this.menu.paretnId=data.id;
//所属父级菜单名称
this.menu.parentName=data.label;
}
优化图标选择器
src/utils创建icon.js
export const elementIcons=["platform-eleme","eleme","delete-solid","delete","s-tools","setting","user-solid","user","phone","phone-outline","more","more-outline","star-on","star-off","s-goods","goods","warning","warning-outline","question","info","remove","cirlce-plus","success","error","zoom-in","zoom-out","remove-outline","circle-plus-outline","circle-check","circle-close","s-help","help","minus","plus","check","close","picture","picture-outline","picture-outline-round","upload","opload2","download","camera-solid","camera","video-camera-solid","vidoe-camera","message-solid","bell","s-cooperation","s-order","s-platform","s-fold","s-unfold","s-operation","s-promotion","s-home","s-release","s-ticket","s-management","s-open","s-shop","s-marketing","s-flag","s-comment","s-finance","s-claim","s-custom","s-opportunity","s-data","s-check","s-grid","menu","share","d-caret","caret-left","caret-right","caret-bottom","caret-top","bottom-let","bottom-right","back","right","bottom","top","top-left","top-right","arrow-left","arrow-right","arrow-down","arrow-up","d-arrow-left","d-arrow-right","video-pause","video-play","refresh","refresh-right","refresh-left","finished","sort","sort-up","sort-down","rank","loading","view","c-scale-to-original","date","edit","edit-outline","folder","folder-opened","folder-add","folder-remove","folder-delete","folder-checked","tickets","document-remove","document-delete","document-copy","document-checked","document","document-add","printer","paperclip","takeaway-box","search","monitor","attract","mobile","scissors","umberlla","headset","brush","mouse","coordinate","magic-stick","reading","data-line","data-board","pie-chart","data-analysis","collection-tag","film","suitcase","suitcase-1","receiving","collection","files","notebook-1","notebook-2","toilet-paper","office-building","school","table-lamp","house","no-smoking","smoking","shopping-cart-full","shopping-cart-1","shopping-cart-2","shopping-bag-1","shopping-bag-2","sold-out","sell","present","box","bank-card","money","coin","wallet","discount","price-tag","news","guide","male","female","thumb","cpu","link","connection","open","turn-off","set-up","chat-round","chat-line-round","chat-square","chat-dot-round","chat-dot-square","chat-line-square","message","postcard","position","turn-off-microphone","microphone","close-notification","bangzhu","time","odometer","crop","aim","switch-button","fulll-screen","copy-document","mic","stopwatch","medal-1","medal","trophy","trophy-1",
"first-aid-kit","discover","place","location","location-outline","location-information","add-location","delete-location","map-location","alarm-clock","timer","watch-1","watch","lock","unlock","key","service","mobile-phone","bicycle","truck","ship","basketball","football","soccer","baseball","wind-power","light-rain","lightning","heavy-rain","sunrise","sunrise-1","sunset","sunny","cloudy","partly-cloudy","clody-and-sunny","moon","moon-light","dish","dish-1","food","chicken","fork-spoon","knife-fork","burger","tableware","sugar","dessert","ice-cream","hot-water","water-cup","coffee-cup","cold-drink","cold-drink","goblet","goblet-full","goblet-square","goblet-square-full","refrigerator","grape","watermelon","chery","apple","pear","orange","coffee","ice-tea","ice-drink","milk-tea","potato-strips","lollipop","ice-cream-square","ice-cream-round"].map(s=>"el-icon"+s);
src/views/system/menu/menuList.vue
<div class="chooseIcons">
<el-popover placement="bottom" width="450" trigger="click">
<span
slot="reference"
style="
display:inline-block;
width:200px;
height:33px;
line-height:33px;">
<i :class="userChooseIcon"></i>
{{userChooseIcon}}
</span>
<div class="iconList">
<i
v-for="item in iconList"
:key="item"
:class="item"
@click="setIcon(item)"
style="font-size:20px"
></i>
</div>
</el-popover>
</div>
<style lang="scss" scoped >
.iconList{
width:400px;
height:300px;
overflow-y:scroll;
display:flex;
justify-content:space-around;
flex-wrap:warp;
i{
display:inline-block;
width:60px;
height:45px;
color:#000000;
font-size:20px;
border: radius 4px;
cursor:pointer;
text-align:center;
line-height:45px;
margin:5px;
&:hover{
color:orange;
border-color: orange;
}
}
}
.chooseIcons{
width:175px;
background-color: #FFFFFF;
background-image: none;
border-radius: 4px;
border:1px solid #DCDFE6;
box-sizing:border-box;
color:#606266;
display:inline-block;
font-size:inherit;
height:33px;
line-height:25px;
outline:none;
padding:0 15px;
transition:border-color 0.2s cubic-bezier(0.645,0.045,0.355,1);
}
封装图标选择器组件
src/components/system创建Mylcon.vue
<template>
<div class="chooseIcons">
<el-popover placement="bottom" width="450" trigger="click">
<span
slot="reference"
style="
display:inline-block;
width:200px;
height:33px;
line-height:33px;">
<i :class="userChooseIcon"></i>
{{userChooseIcon}}
</span>
<div class="iconList">
<i
v-for="item in iconList"
:key="item"
:class="item"
@click="setIcon(item)"
style="font-size:20px"
></i>
</div>
</el-popover>
</div>
</template>
<script>
//导入自定义的icon图标库
import {elementicons} from "@/utils/icons"
export default {
name:"MyIcon",
data(){
return{
userChooseIcon:"",//用户选中的图标
iconList:[],//图标列表
}
},
methods:{
/**
* 获取图标列表
*/
getIconList(){
this.iconList=elementIcons;
},
//将icon绑定的点击事件
setIcon(icon){
this.userChooseIcon=icon;//将i的样式设为选中的样式
this.$emit("selecticon",icon)
}
},
created(){
//获取图标列表
this.getIconList();
}
}
</script>
<style lang="scss" scoped >
.iconList{
width:400px;
height:300px;
overflow-y:scroll;
display:flex;
justify-content:space-around;
flex-wrap:warp;
i{
display:inline-block;
width:60px;
height:45px;
color:#000000;
font-size:20px;
border: radius 4px;
cursor:pointer;
text-align:center;
line-height:45px;
margin:5px;
&:hover{
color:orange;
border-color: orange;
}
}
}
.chooseIcons{
width:175px;
background-color: #FFFFFF;
background-image: none;
border-radius: 4px;
border:1px solid #DCDFE6;
box-sizing:border-box;
color:#606266;
display:inline-block;
font-size:inherit;
height:33px;
line-height:25px;
outline:none;
padding:0 15px;
transition:border-color 0.2s cubic-bezier(0.645,0.045,0.355,1);
}
</style>
编辑权限菜单
src/menu.js
/**
* 修改菜单
*/
async updataMenu(params){
return await http.put("/api/permission/add",params)
}
src/views/system/menu/menuList.vue
onConfirm(){
//表单验证
this.$refs.menuForm.validate(async (valid) =>{
if(valid){
let res=null;
//判断菜单是否为空
if(this.menu.id===""){
//发送添加请求
res=await menuApi.addMenu(this.menu)
}else{
//发送修改请求
}
//判断是否成功
if(res.success){
this.$meaasge.success(res.message);
//刷新
//this.search();
window.location.reload();
//关闭窗口
this.menuDialog.visible=false;
}else{
this.$message.error(res.message);
}
}
/**
* 打开编辑菜单
*/
editMenu(row){
//把当前要编辑的数据复制到数据域,给表单回显
this.$objCopy(row,this.menu);
//设置弹窗属性
this.menuDialog.title="编辑菜单"
this.menuDialog.visible=true;
this.$nextTick(()=>{
this.$refs["child"].userChooseIcon=row.icon//菜单图标回显
})
},
删除权限菜单
src/api/menu.js
/**
* 检查菜单下是否存在子菜单
*/
async checkPermission(param){
return await http.delete("/api/permission/delete",params);
},
/**
* 删除菜单
*/
async deleteById(params){
return await http.delete("api/permission/delete",params)
}
src/views/system/menu/menuList.vue
async deleteMenu(row){
//查询部门下是否存在子部门或用户
let result=await menuApi.checkPermission({id:row.id})
//判断是否可以删除
if(!result.success){
//提示不能删除
this.$message.warning(result.message);
}else{
//确定是否删除
let confirm=await this.$myconfirm("确定要删除该数据吗");
if(confirm){
//发送删除请求
let res =await menuApi.deleteById({id:row.id})
//判断是否成功
if(res.success){
//成功提示
this.$message.success(res.message)
//刷新
this.search();
}else{
//失败提示
this.$message.error(res.message);
}
}
}
}
角色管理
查询角色列表
src/views/system/role创建roleList.vue
<template>
<el-main>
<!-- 查询条件 -->
<el-form
:model="searchModel"
ref="searchForm"
label-width="80px"
:inline="true"
size="small"
>
<el-form-item>
i<el-input v-model="searchModel.roleName" placeholder="请输入角色名称" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search">查询</el-button>
<el-button type="el-icon-refresh-right">重置</el-button>
<el-button type="success" icon="el-icon-plus">新增</el-button>
</el-form-item>
</el-form>
<!-- 数据表格 -->
<el-table
:data="roleList"
:height="tableHeight"
border
stripe
style="width:100%; margin-bottom:10px">
<el-table-column
prop="id"
label="角色编号"
width="100"
align="center"
></el-table-column>
<el-table-column prop="roleCode" label="角色编码"></el-table-column>
<el-table-column prop="roleName" label="角色名称"></el-table-column>
<el-table-column prop="remark" label="角色备注"></el-table-column>
<el-table-column label="操作" align="center" width="290">
<template slot-scope="scope">
<el-button
type="primary"
icon="el-icon-edit"
size="small"
@click="editMenu(scope.row)"
>编辑
</el-button>
<el-button
type="danger"
size="small"
icon="el-icon-delete"
@click="deleteMenu(scope.row)"
>删除
</el-button>
<el-button
type="primary"
size="small"
icon="el-icon-setting"
@click="assignRole(scope.row)"
>分配限权
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页工具 -->
<el-pagination
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageNo"
:page-sizes="[10,20,30,40,50]"
:page-size="10"
layout="total,sizes,prev,pager,next,jumper"
:total="total"
>
</el-pagination>
</el-main>
</template>
<script>
export default {
name:"roleList",
data(){
return{
//查询条件
searchModel:{
rolename:''
},
roleList:[],//数据列表
tableHeight:0,//表格数据
pageNo:1,//当前页码
pageSize:10,//煤业显示数量
total:0,//总数量
}
},
methods:{
/**
* 查询
*/
search(){
},
/**
* 重置查询条件
*/
resetValue(){
},
/**
* 当煤业数量发生变化时,触发该事件
*/
handleSizeChange(size){
},
/**
* 当页码发生变化时触发该事件
*/
handleCurretnChange(page){
},
/**
* 打开编辑器
*/
handleEdit(row){
},
/**
* 删除
*/
handleDelete(row){
},
//初始化时调用
created(){
},
mounted(){
this.$nextTick(()=>{
this.tableHeight=window.innerHeight-220
})
},
}
}
</script>
<style lang="scss" scoped >
</style>
src/api创建role.js
import http from '@/utils/request'
export function getRoutes() {}
export async function getRoles(params) {
return await http.get('/api/role/list',params)
}
export function addRole(data) {}
export function updateRole(id, data) {}
export function deleteRole(id) {}
8.20-8.22学习汇报与总结
1.问题解决
(1)问题:安装jdk出现问题
解决:以管理员身份运行命令提示符,输入命令taskkill /f /pid (这里跟上process id)
(2)问题:由于上一个解决问题关闭了资源管理器,导致电脑白屏
解决:打开任务管理器(ctrl+shift+ecs),点击左上角文件——运行新任务——输入”explorer..exe“
(3)问题:运行报错
解决:找到报错位置
改成:
(4)问题:点击登录没有反应,出现以下报错
解决:没有启动后端项目,启动后端项目即可
(5)问题:运行时报错
解决:注释完1603这一行
(6)问题:连接数据库出问题
解决:按下蓝色键,会报错为”erver returns invalid timezone. Need to set 'serverTimezone' property.“,在url后面加上?serverTimezone=GMT即可
(7)问题:运行后端项目报错
解决:点击Build,点击rebuild,可解决大部分报错
2.学习体会与感受
目前能看到的效果只有登录
登陆报错
分析过后主要是由于我直接后端一起联调,在启动后端程序的位置出了问题,请教了何同学之后,找到了是环境不完整,于是配置完,改完配置报错之后。终于运行起了项目。但是在idea当中报错。按照网上改还是没有能解决
把后端运行起来之后,后面主要就是看效果改报错了。
由此,我深刻意识到,学会单独测试的重要性(九敏)。
3.8.23-8.24学习计划
改报错,尽快完成项目