Day20-前端Web案例——部门管理
目录
- 部门管理
- 1. 前后端分离开发
- 2. 准备工作
- 2.1 创建Vue项目
- 2.2 安装依赖
- 2.3 精简项目
- 3. 页面布局
- 3.1 介绍
- 3.2 整体布局
- 3.3 左侧菜单
- 4. Vue Router
- 4.1 介绍
- 4.2 入门
- 4.3 案例
- 4.4 首页制作
- 5. 部门管理
- 5.1部门列表
- 5.1.1. 基本布局
- 5.1.2 加载数据
- 5.1.3 程序优化
- 5.2 新增部门
- 5.3 修改部门
- 5.3.1 查询回显
- 5.3.2 保存修改
- 5.4 删除部门
- 5.5 表单校验
- 5.5.1 ElementPlus 参考
- 5.5.2 实现
部门管理
在前面的课程中,我们学习了Vue工程化的基础内容、TS、ElementPlus,那接下来呢,我们要通过一个案例,加强大家对于Vue项目的理解,并掌握Vue项目的开发。 这个案例呢,就是我们之前所做的Tlias智能学习辅助系统。
在这个案例中,我们主要完成 部门管理 和 员工管理 的功能开发。 而今天呢,我们先来完成部门管理的功能开发,而在完成部门管理的功能开发之前,先需要完成基础的准备工作。 所以今天的课程安排如下:
- 前后端分类开发
- 准备工作
- 页面布局
- Vue-Router
- 部门管理
1. 前后端分离开发
在之前的课程中,我们介绍过,现在的企业项目开发有2种开发模式:前后台混合开发和前后台分离开发。
前后台混合开发,顾名思义就是前台后台代码混在一起开发。这种开发模式有如下缺点:
- 沟通成本高:后台人员发现前端有问题,需要找前端人员修改,前端修改成功,再交给后台人员使用
- 分工不明确:后台开发人员需要开发后台代码,也需要开发部分前端代码。很难培养专业人才
- 不便管理:所有的代码都在一个工程中
- 难以维护:前端代码更新,和后台无关,但是需要整个工程包括后台一起重新打包部署。
所以我们目前基本都是采用的前后台分离开发方式,如下图所示:
我们将原先的工程分为前端工程和后端工程这2个工程,然后前端工程交给专业的前端人员开发,后端工程交给专业的后端人员开发。
前端页面需要数据,可以通过发送异步请求,从后台工程获取。但是,我们前后台是分开来开发的,那么前端人员怎么知道后台返回数据的格式呢?后端人员开发,怎么知道前端人员需要的数据格式呢?
所以针对这个问题,我们前后台统一制定一套规范!我们前后台开发人员都需要遵循这套规范开发,这就是我们的接口文档。
那么接口文档的内容怎么来的呢?是我们后台开发者根据产品经理提供的产品原型和需求文档所撰写出来的。
那么基于前后台分离开发的模式下,我们后台开发者开发一个功能的具体流程如何呢?如下图所示:
- 需求分析:首先我们需要阅读需求文档,分析需求,理解需求。
- 接口定义:查询接口文档中关于需求的接口的定义,包括地址,参数,响应数据类型等等
- 前后台并行开发:各自按照接口文档进行开发,实现需求
- 测试:前后台开发完了,各自按照接口文档进行测试
- 前后段联调测试:前段工程请求后端工程,测试功能
2. 准备工作
2.1 创建Vue项目
在自己工作目录下,运行 cmd
打开命令行,运行如下指令,来创建vue项目【
npm init vue@latest
2.2 安装依赖
1). 在命令行中执行如下命令,为创建好的Vue项目安装 ElementPlus、Axios
的依赖。
npm install element-plus --save
npm install axios
2). 为创建好的 Vue项目 配置ElementPlus (参照官网),在 main.ts
中引入如下配置信息 【注意:是追加如下内容】:
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import zhCn from 'element-plus/es/locale/lang/zh-cn'import * as ElementPlusIconsVue from '@element-plus/icons-vue'//引入ElementPlus的Icon组件
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component)
}
app.use(ElementPlus, {locale: zhCn})app.mount('#app')
最终完整的 main.ts
文件内容如下:
import { createApp } from 'vue'
import { createPinia } from 'pinia'import App from './App.vue'
import router from './router'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import './assets/main.css'import zhCn from 'element-plus/es/locale/lang/zh-cn'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'const app = createApp(App)for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component)
}
app.use(createPinia())
app.use(router)
app.use(ElementPlus, {locale: zhCn})app.mount('#app')
3). 在 env.d.ts
中引入ElementPlus的语言包(可不做)
declare module 'element-plus/es/locale/lang/zh-cn'
2.3 精简项目
由于基于Vue脚手架创建的项目里面携带了很多的多余的Vue组件。 并准备对应的组件存放目录 。
- 删除
components
目录中的vue文件 - 删除
views
目录中的vue文件 - 清空根组件文件
App.vue
中的内容,只保留基础的vue组件文件的结构标签<script>
<template>
<style>
3. 页面布局
3.1 介绍
我们在制作一个页面的时候,一定是先关注整体的页面布局,然后再关注具体的细节处理 。 所以这一小节,我们就先来完成页面的整体布局。
我们会看到,整个页面分为这么三个部分:
①. 页头部分
②. 侧边栏
③. 主区域
而要完成这样的页面布局,我们其实是可以借助于 ElementPlus
中提供的 Container布局容器
来实现:
Container布局容器,用于布局的容器组件,方便快速搭建页面的基本结构:
<el-container>
:外层容器。 当子元素中包含 <el-header>
或 <el-footer>
时,全部子元素会垂直上下排列, 否则会水平左右排列。
<el-header>
:顶栏容器。
<el-aside>
:侧边栏容器。
<el-main>
:主要区域容器。
<el-footer>
:底栏容器。
而针对于我们当前案例的页面布局,基本的结构如下:
提示:当
<el-container>
子元素中包含<el-header>
或<el-footer>
时,全部子元素会垂直上下排列, 否则会水平左右排列。
3.2 整体布局
我们可以参照 ElementPlus
的官方网站中的 布局,拷贝其源码,然后对其做一个改造。 具体参照的源码如下:
1). 在 src/views
目录下,再创建一个子目录 layout
,在其中新建一个页面,页面命名为:index.vue
。
2). 在 index.vue
中准备好基础的组件结构后,就可以将代码直接复制到 <template> </template>
标签中。
<script setup lang="ts"></script><template><div class="common-layout"><el-container><!-- 顶栏 - header --><el-header>Header</el-header><!-- 左侧菜单 & 主区域 --><el-container><el-aside width="200px">Aside</el-aside><el-main>Main</el-main></el-container></el-container></div>
</template><style scoped></style>
然后,我们先根据页面原型中的布局显示进行调整。 先完成顶栏部分的制作,具体的代码如下:
<script setup lang="ts"></script><template><div class="common-layout"><el-container><!-- 顶栏 - header --><el-header class="header"><span class="title">Tlias智能学习辅助系统</span><span class="right_tool"><a href=""><el-icon><EditPen /></el-icon> 修改密码 </a><a href=""><el-icon><SwitchButton /></el-icon> 退出登录 </a></span></el-header><!-- 左侧菜单 & 主区域 --><el-container><el-aside width="200px">Aside</el-aside><el-main>Main</el-main></el-container></el-container></div>
</template><style scoped>
.header {background-image: linear-gradient(to right, #e70cc5, #e94dcf, #eb6fd8, #ec8bdf, #eea5e6);line-height: 60px;
}.title {color: white;font-size: 35px;font-family: 楷体;}.right_tool {float: right;
}a {text-decoration: none;color: white;
}
</style>
最终的顶栏布局效果如下所示:
3.3 左侧菜单
顶栏布局完毕之后,接下来,我们再来完成左侧菜单栏的制作。 左侧菜单栏的制作,也不需要我们自己实现,其实在 ElementPlus
中已经提供了对应的菜单组件,我们可以直接参考【PS: 其实就是复制过来,参考页面原型和需求,将其改造成我们需要的样子就可以了】。
参考代码的出处如下:
然后就可以参考其提供的源码,复制到我们的侧边栏部分 <el-aside> ... </el-aside>
,然后根据我们案例的需要进行改造,改造成我们需要的样子即可。
最终左侧菜单栏的代码如下:
<!-- 左侧菜单 -->
<el-aside width="200px" class="aside"><el-scrollbar><el-menu router><!-- 首页菜单 --><el-menu-item index="/index"><el-icon><Promotion /></el-icon> 首页</el-menu-item><!-- 班级管理菜单 --><el-sub-menu index="/manage"><template #title><el-icon><Menu /></el-icon> 班级学员管理</template><el-menu-item index="/clazz"><el-icon><HomeFilled /></el-icon>班级管理</el-menu-item><el-menu-item index="/stu"><el-icon><UserFilled /></el-icon>学员管理</el-menu-item></el-sub-menu><!-- 系统信息管理 --><el-sub-menu index="/system"><template #title><el-icon><Tools /></el-icon>系统信息管理</template><el-menu-item index="/dept"><el-icon><HelpFilled /></el-icon>部门管理</el-menu-item><el-menu-item index="/emp"><el-icon><Avatar /></el-icon>员工管理</el-menu-item></el-sub-menu><!-- 数据统计管理 --><el-sub-menu index="/report"><template #title><el-icon><Histogram /></el-icon>数据统计管理</template><el-menu-item index="/empReport"><el-icon><InfoFilled /></el-icon>员工信息统计</el-menu-item><el-menu-item index="/stuReport"><el-icon><Share /></el-icon>学员信息统计</el-menu-item><el-menu-item index="/log"><el-icon><Document /></el-icon>日志信息统计</el-menu-item></el-sub-menu></el-menu></el-scrollbar>
</el-aside>
并在 <style></style>
中添加如下样式:
.aside {border: 1px solid #ccc;height: 690px;width: 220px;
}
最终,浏览器打开的效果如下:
到目前为止,layout/index.vue
中的内容如下:
<script setup lang="ts"></script><template><div class="common-layout"><el-container><!-- 顶栏 - header --><el-header class="header"><span class="title">Tlias智能学习辅助系统</span><span class="right_tool"><a href=""><el-icon><EditPen /></el-icon> 修改密码 </a><a href=""><el-icon><SwitchButton /></el-icon> 退出登录 </a></span></el-header><!-- 左侧菜单 & 主区域 --><el-container><!-- 左侧菜单 --><el-aside width="200px" class="aside"><el-scrollbar><el-menu router><!-- 首页菜单 --><el-menu-item index="/index"><el-icon><Promotion /></el-icon> 首页</el-menu-item><!-- 班级管理菜单 --><el-sub-menu index="/manage"><template #title><el-icon><Menu /></el-icon> 班级学员管理</template><el-menu-item index="/clazz"><el-icon><HomeFilled /></el-icon>班级管理</el-menu-item><el-menu-item index="/stu"><el-icon><UserFilled /></el-icon>学员管理</el-menu-item></el-sub-menu><!-- 系统信息管理 --><el-sub-menu index="/system"><template #title><el-icon><Tools /></el-icon>系统信息管理</template><el-menu-item index="/dept"><el-icon><HelpFilled /></el-icon>部门管理</el-menu-item><el-menu-item index="/emp"><el-icon><Avatar /></el-icon>员工管理</el-menu-item></el-sub-menu><!-- 数据统计管理 --><el-sub-menu index="/report"><template #title><el-icon><Histogram /></el-icon>数据统计管理</template><el-menu-item index="/empReport"><el-icon><InfoFilled /></el-icon>员工信息统计</el-menu-item><el-menu-item index="/stuReport"><el-icon><Share /></el-icon>学员信息统计</el-menu-item><el-menu-item index="/log"><el-icon><Document /></el-icon>日志信息统计</el-menu-item></el-sub-menu></el-menu></el-scrollbar></el-aside><el-main>Main</el-main></el-container></el-container></div>
</template><style scoped>
.header {background-image: linear-gradient(to right, #e70cc5, #e94dcf, #eb6fd8, #ec8bdf, #eea5e6);line-height: 60px;
}.title {color: white;font-size: 35px;font-family: 楷体;}.right_tool {float: right;
}a {text-decoration: none;color: white;
}.aside {border: 1px solid #ccc;height: 690px;width: 220px;
}
</style>
目前,我们点击左侧的菜单,右侧主区域展示的内容,还不能做到动态变化。 那应该如何做到动态变化呢 ?
那要完成这个功能效果,我们就需要用到Vue生态中的路由 Vue-Router
。
4. Vue Router
4.1 介绍
- Vue Router:Vue的官方路由。 为Vue提供富有表现力、可配置的、方便的路由。
- Vue中的路由,主要定义的是路径与组件之间的对应关系。
比如,我们打开一个网站,点击左侧菜单,地址栏的地址发生变化。 地址栏地址一旦发生变化,在主区域显示对应的页面组件。
VueRouter主要由以下三个部分组成,如下所示:
- VueRouter:路由器类,根据路由请求在路由视图中动态渲染选中的组件
- <router-link>:请求链接组件,浏览器会解析成<a>
- <router-view>:动态视图组件,用来渲染展示与路由路径对应的组件
4.2 入门
介绍完了VueRouter之后,接下来,我们就通过一个入门程序,来演示一下VueRouter的使用。
1). 安装 vue-router
(创建Vue项目时,可以选择)
npm install vue-router@4
2). 在 main.ts
入口文件中进行配置,加入如下配置
import router from './router'//..... 创建完vue的应用实例后,调用app.use
app.use(router)
3). 在 src/views 目录下再定义一个文件夹,在文件夹中再创建一个 vue 组件文件
4). 定义路由
在 src/router/index.ts
中定义路由表信息,在其中主要是定义请求路径与组件之间的对应关系。 完整的文件内容如下:
import { createRouter, createWebHistory } from 'vue-router'const router = createRouter({history: createWebHistory(import.meta.env.BASE_URL),routes: [{path: '/',name: 'home',component: () => import('../views/layout/index.vue')},{path: '/index',name: 'index',component: () => import('../views/index/index.vue')}]
})export default router
5). 在 App.vue
根组件中,定义 <RouterView></RouterView>
标签
该标签将用于显示,访问的请求路径对应的组件。
<script setup lang="ts"></script><template><RouterView></RouterView>
</template><style scoped></style>
6). 测试
浏览器访问请求路径 http://127.0.0.1:5173/index,展示如下页面内容(该页面内容,就是我们在 index/index.vue
中定义的页面内容):
浏览器访问请求路径 http://127.0.0.1:5173/,展示如下页面内容 (该页面内容,就是我们在 layout/index.vue
中定义的页面内容):
到此,我们发现,我们请求不同的请求路径,就可以在页面中显示不同的组件。具体的访问流程如下:
4.3 案例
那接下来,我们就要基于 VueRouter
来完成点击 左侧菜单,动态切换主展示区域内容的动态效果。
1). 准备案例的空页面
<script setup lang="ts"></script><template>班级管理|学生管理|员工管理|部门管理|首页展示
</template><style scoped></style>
2). 在 src/router/index.ts
中配置路由信息
这里我们用到了Vue中的嵌套路由,具体定义方式,主要是在配置路由信息时,通过children
来描述。如你所见,children
配置只是另一个路由数组,就像 routes
本身一样。因此,你可以根据自己的需要,不断地嵌套视图。
import { createRouter, createWebHistory } from 'vue-router'const router = createRouter({history: createWebHistory(import.meta.env.BASE_URL),routes: [{path: '/',name: 'home',component: () => import('../views/layout/index.vue'),redirect: '/index',children: [{path: 'index',name: 'index',component: () => import('../views/index/index.vue') //首页},{path: 'emp',name: 'emp',component: () => import('../views/emp/index.vue') //员工管理},{path: 'dept',name: 'dept',component: () => import('../views/dept/index.vue') //部门管理},{path: 'clazz',name: 'clazz',component: () => import('../views/clazz/index.vue') //班级管理},{path: 'stu',name: 'stu',component: () => import('../views/stu/index.vue') //学员管理}]}]
})export default router
3). 完善左侧菜单栏 layout/index.vue
,菜单栏关联路由
菜单关联了路由之后,我们点击对应的菜单,就会根据菜单的唯一标识 index
,在地址栏中请求访问对应的地址。
4). 在Vue组件中,动态展示与路由对应的组件 。
需要在 layout/index.vue
中的 <el-main></el-main>
中添加动态路由视图组件 <RouterView></RouterView>
。如下:
<!-- 主展示区域 -->
<el-main><RouterView></RouterView>
</el-main>
最终完整的 layout/index.vue
代码如下:
<script setup lang="ts"></script><template><div class="common-layout"><el-container><!-- 顶栏 - header --><el-header class="header"><span class="title">Tlias智能学习辅助系统</span><span class="right_tool"><a href=""><el-icon><EditPen /></el-icon> 修改密码 </a><a href=""><el-icon><SwitchButton /></el-icon> 退出登录 </a></span></el-header><!-- 左侧菜单 & 主区域 --><el-container><!-- 左侧菜单 --><el-aside width="200px" class="aside"><el-scrollbar><el-menu router><!-- 首页菜单 --><el-menu-item index="/index"><el-icon><Promotion /></el-icon> 首页</el-menu-item><!-- 班级管理菜单 --><el-sub-menu index="/manage"><template #title><el-icon><Menu /></el-icon> 班级学员管理</template><el-menu-item index="/clazz"><el-icon><HomeFilled /></el-icon>班级管理</el-menu-item><el-menu-item index="/stu"><el-icon><UserFilled /></el-icon>学员管理</el-menu-item></el-sub-menu><!-- 系统信息管理 --><el-sub-menu index="/system"><template #title><el-icon><Tools /></el-icon>系统信息管理</template><el-menu-item index="/dept"><el-icon><HelpFilled /></el-icon>部门管理</el-menu-item><el-menu-item index="/emp"><el-icon><Avatar /></el-icon>员工管理</el-menu-item></el-sub-menu><!-- 数据统计管理 --><el-sub-menu index="/report"><template #title><el-icon><Histogram /></el-icon>数据统计管理</template><el-menu-item index="/empReport"><el-icon><InfoFilled /></el-icon>员工信息统计</el-menu-item><el-menu-item index="/stuReport"><el-icon><Share /></el-icon>学员信息统计</el-menu-item><el-menu-item index="/log"><el-icon><Document /></el-icon>日志信息统计</el-menu-item></el-sub-menu></el-menu></el-scrollbar></el-aside><!-- 主展示区域 --><el-main><RouterView></RouterView></el-main></el-container></el-container></div>
</template><style scoped>
.header {background-image: linear-gradient(to right, #e70cc5, #e94dcf, #eb6fd8, #ec8bdf, #eea5e6);line-height: 60px;
}.title {color: white;font-size: 35px;font-family: 楷体;}.right_tool {float: right;
}a {text-decoration: none;color: white;
}.aside {border: 1px solid #ccc;height: 690px;width: 220px;
}
</style>
5). 测试
4.4 首页制作
其实首页,我们只需要展示一张图片即可。 直接在 index/index.vue
中引入一张图片即可,具体代码如下:
<script setup lang="ts"></script><template><img src="@/assets/index.png">
</template><style scoped></style>
最终效果如下:
5. 部门管理
部门管理的页面内容,写在 src/views/dept/index.vue
中。
5.1部门列表
5.1.1. 基本布局
首先,根据页面原型、需求说明、接口文档,先完成页面的基本布局 。 可以参考 ElementPlus
中的组件,拷贝过来适当做一个改造。
部门管理组件 src/views/dept/index.vue
具体的页面布局代码如下:
<script setup lang="ts">
import {ref} from 'vue'
import type { DeptModelArray } from '@/api/model/model'//声明列表展示数据
let tableData = ref<DeptModelArray>([])
</script><template><h1>部门管理</h1><el-button type="primary" style="float: right" @click="">+ 新增</el-button><br><br><!-- 部门数据表格 --><el-table :data="tableData" border style="width: 100%"><el-table-column type="index" label="序号" width="80" align="center"/><el-table-column prop="name" label="部门名称" width="250" align="center"/><el-table-column prop="updateTime" label="最后操作时间" width="300" align="center"/><el-table-column label="操作" align="center"><template #default="scope"><el-button size="small" type="primary" @click="">修改</el-button><el-button size="small" type="danger" @click="">删除</el-button></template></el-table-column></el-table>
</template><style scoped></style>
表格中每一列展示的属性 prop
都是根据接口文档来的,接口文档返回什么样的数据,我们就安装对应的数据格式进行解析。
5.1.2 加载数据
根据需求,需要在新增、修改、删除部门之后,加载最新的部门数据。 在打开页面之后,也需要自动加载部门数据。 那接下来,我们就需要基于axios发送异步请求,动态获取数据。
需要在 src/views/dept/index.vue
中增加如下代码,在页面加载完成发送异步请求(https://mock.apifox.com/m1/3161925-0-default/depts),动态加载的Axios。
<script setup lang="ts">
import {ref, onMounted} from 'vue'
import type { DeptModelArray } from '@/api/model/model'
import axios from 'axios'//声明列表展示数据
let tableData = ref<DeptModelArray>([])//动态加载数据-查询部门
const queryAll = async () => {const result = await axios.get('https://mock.apifox.com/m1/3161925-0-default/depts')tableData.value = result.data.data
}//钩子函数
onMounted(() => {queryAll()
})
</script>
添加代码后,最终 src/views/dept/index.vue
代码如下:
<script setup lang="ts">
import {ref, onMounted} from 'vue'
import type { DeptModelArray } from '@/api/model/model'
import axios from 'axios'//声明列表展示数据
let tableData = ref<DeptModelArray>([])//动态加载数据-查询部门
const queryAll = async () => {const result = await axios.get('https://mock.apifox.com/m1/3161925-0-default/depts')tableData.value = result.data.data
}//钩子函数
onMounted(() => {queryAll()
})
</script><template><h1>部门管理</h1><el-button type="primary" style="float: right" @click="">+ 新增</el-button><br><br><!-- 部门数据表格 --><el-table :data="tableData" border style="width: 100%"><el-table-column type="index" label="序号" width="80" align="center"/><el-table-column prop="name" label="部门名称" width="250" align="center"/><el-table-column prop="updateTime" label="最后操作时间" width="300" align="center"/><el-table-column label="操作" align="center"><template #default="scope"><el-button size="small" type="primary" @click="">修改</el-button><el-button size="small" type="danger" @click="">删除</el-button></template></el-table-column></el-table>
</template><style scoped></style>
代码编写完成之后,打开浏览器进行测试 ,我们可以看到数据可以正常的查询出来,并展示在页面中。
思考:直接在Vue组件中,基于axios发送异步请求,存在什么问题?
我们刚才在完成部门列表查询时,是直接基于axios发送异步请求,直接将接口的请求地址放在组件文件 .vue
中。 而如果开发一个大型的项目,组件文件可能会很多很多很多,如果前端开发完毕,进行前后端联调测试了,需要修改请求地址,那么此时,就需要找到每一个 .vue
文件,然后挨个修改。 所以上述的代码,虽然实现了动态加载数据的功能。 但是存在以下问题:
- 请求路径难以维护
- 数据解析繁琐
5.1.3 程序优化
1). 为了解决上述问题,我们在前端项目开发时,通常会定义一个请求处理的工具类 - src/utils/request.ts
。 在这个工具类中,对axios进行了封装。 具体代码如下:
import axios from 'axios'//创建axios实例对象
const request = axios.create({baseURL: '/api',timeout: 600000
})//axios的响应 response 拦截器
request.interceptors.response.use((response) => { //成功回调return response.data},(error) => { //失败回调return Promise.reject(error)}
)export default request
2). 而与服务端进行异步交互的逻辑,通常会按模块,封装在一个单独的API中,如:src/api/dept.ts
import request from "@/utils/request"
import type { ResultModel } from "./model/model"//列表查询
export const queryAllApi = () => request.get<any, ResultModel>('/depts')
3). 修改 src/views/dept/index.vue
中的代码
现在就不需要每次直接调用axios发送异步请求了,只需要将我们定义的对应模块的API导入进来,就可以直接使用了。
<script setup lang="ts">
import {ref, onMounted} from 'vue'
import type { DeptModelArray } from '@/api/model/model'
import {queryAllApi} from '@/api/dept'//声明列表展示数据
let tableData = ref<DeptModelArray>([])//动态加载数据-查询部门
const queryAll = async () => {const result = await queryAllApi()tableData.value = result.data
}//钩子函数
onMounted(() => {queryAll()
})
</script>
做完上面这三部之后,我们打开浏览器发现,并不能访问到接口数据。原因是因为,目前请求路径不对。
4). 在 vite.config.ts
中配置前端请求服务器的信息
在服务器中配置代理proxy的信息,并在配置代理时,执行目标服务器。 以及url路径重写的规则。
server: {proxy: {'/api': {target: 'http://localhost:8080',secure: false,changeOrigin: true,rewrite: (path) => path.replace(/^\/api/, ''),}}}
添加位置如下所示:
然后,我们就可以启动服务器端的程序,进行测试了(测试时,记得将之前编写的登录校验的过滤器、拦截器、AOP程序全部注释掉)。
5.2 新增部门
接下来,我们再来完成新增部门的功能实现。
1). 在 src/views/dept/index.vue
中完成页面布局,并编写交互逻辑,完成数据绑定。
完整代码如下:
<script setup lang="ts">
import {ref, onMounted} from 'vue'
import type { DeptModelArray, DeptModel } from '@/api/model/model'
import {queryAllApi, addApi} from '@/api/dept'
import { ElMessage } from 'element-plus';//声明列表展示数据
let tableData = ref<DeptModelArray>([])//动态加载数据-查询部门
const queryAll = async () => {const result = await queryAllApi()tableData.value = result.data
}//钩子函数
onMounted(() => {queryAll()
})//新增部门
const dialogFormVisible = ref<boolean>(false)
const deptForm = ref<DeptModel>({name: ''})
const formTitle = ref<string>('')//点击新增按钮触发的函数
const add = () => {formTitle.value = '新增部门'dialogFormVisible.value = truedeptForm.value = {name: ''}
}//点击保存按钮-发送异步请求
const save = async () => {const result = await addApi(deptForm.value)if(result.code){ElMessage.success('操作成功')}else{ElMessage.error(result.msg)}dialogFormVisible.value = falsequeryAll()
}</script><template><h1>部门管理</h1><el-button type="primary" style="float: right" @click="add">+ 新增</el-button><br><br><!-- 部门数据表格 --><el-table :data="tableData" border style="width: 100%"><el-table-column type="index" label="序号" width="80" align="center"/><el-table-column prop="name" label="部门名称" width="250" align="center"/><el-table-column prop="updateTime" label="最后操作时间" width="300" align="center"/><el-table-column label="操作" align="center"><template #default="scope"><el-button size="small" type="primary" @click="">修改</el-button><el-button size="small" type="danger" @click="">删除</el-button></template></el-table-column></el-table><!-- 新增部门 / 修改部门对话框 --><el-dialog v-model="dialogFormVisible" :title="formTitle" width="30%"><el-form :model="deptForm"><el-form-item label="部门名称" label-width="80px"><el-input v-model="deptForm.name" autocomplete="off" /></el-form-item></el-form><template #footer><span class="dialog-footer"><el-button @click="dialogFormVisible = false">取消</el-button><el-button type="primary" @click="save">确定</el-button></span></template></el-dialog></template><style scoped></style>
2). 在 src/api/dept.ts
中增加如下代码
//添加部门
export const addApi = (dept:DeptModel) => request.post<any, ResultModel>('/depts', dept)
目前 src/api/dept.ts
文件中完整代码如下:
import request from "@/utils/request"
import type { DeptModel, ResultModel } from "./model/model"//列表查询
export const queryAllApi = () => request.get<any, ResultModel>('/depts')//添加部门
export const addApi = (dept:DeptModel) => request.post<any, ResultModel>('/depts', dept)
打开浏览器进行测试,效果如下:
5.3 修改部门
对于修改操作,通常会分为两步进行:
- 查询回显
- 保存修改
交互逻辑:
- 点击 编辑 按钮,根据ID进行查询,弹出对话框,完成页面回显展示。(查询回显)
- 点击 确定 按钮,保存修改后的数据,完成数据更新操作。(保存修改)
5.3.1 查询回显
1). 在 src/api/dept.ts
中定义根据id查询的请求
//根据ID查询
export const queryInfoApi = (id:number) => request.get(`/depts/${id}`)
2). 在 src/views/dept/index.vue
中添加根据ID查询回显的逻辑
为修改按钮绑定事件 <template></template>
:
<el-button size="small" type="primary" @click="update(scope.row.id)">修改</el-button>
在 <script> </script>
添加JS逻辑:
//修改部门-查询回显
const update = async (id:number) => {formTitle.value = '修改部门'dialogFormVisible.value = truedeptForm.value = {name: ''}const result = await queryInfoApi(id)deptForm.value = result.data
}
到目前为止,完整的 src/views/dept/index.vue
代码如下:
<script setup lang="ts">
import {ref, onMounted} from 'vue'
import type { DeptModelArray, DeptModel } from '@/api/model/model'
import {queryAllApi, addApi, queryInfoApi} from '@/api/dept'
import { ElMessage } from 'element-plus';//声明列表展示数据
let tableData = ref<DeptModelArray>([])//动态加载数据-查询部门
const queryAll = async () => {const result = await queryAllApi()tableData.value = result.data
}//钩子函数
onMounted(() => {queryAll()
})//新增部门
const dialogFormVisible = ref<boolean>(false)
const deptForm = ref<DeptModel>({name: ''})
const formTitle = ref<string>('')//点击新增按钮触发的函数
const add = () => {formTitle.value = '新增部门'dialogFormVisible.value = truedeptForm.value = {name: ''}
}//点击保存按钮-发送异步请求
const save = async () => {const result = await addApi(deptForm.value)if(result.code){ElMessage.success('操作成功')}else{ElMessage.error(result.msg)}dialogFormVisible.value = falsequeryAll()
}//修改部门-查询回显
const update = async (id:number) => {formTitle.value = '修改部门'dialogFormVisible.value = truedeptForm.value = {name: ''}const result = await queryInfoApi(id)deptForm.value = result.data
}</script><template><h1>部门管理</h1><el-button type="primary" style="float: right" @click="add">+ 新增</el-button><br><br><!-- 部门数据表格 --><el-table :data="tableData" border style="width: 100%"><el-table-column type="index" label="序号" width="80" align="center"/><el-table-column prop="name" label="部门名称" width="250" align="center"/><el-table-column prop="updateTime" label="最后操作时间" width="300" align="center"/><el-table-column label="操作" align="center"><template #default="scope"><el-button size="small" type="primary" @click="update(scope.row.id)">修改</el-button><el-button size="small" type="danger" @click="">删除</el-button></template></el-table-column></el-table><!-- 新增部门 / 修改部门对话框 --><el-dialog v-model="dialogFormVisible" :title="formTitle" width="30%"><el-form :model="deptForm"><el-form-item label="部门名称" label-width="80px"><el-input v-model="deptForm.name" autocomplete="off" /></el-form-item></el-form><template #footer><span class="dialog-footer"><el-button @click="dialogFormVisible = false">取消</el-button><el-button type="primary" @click="save">确定</el-button></span></template></el-dialog></template><style scoped></style>
5.3.2 保存修改
由于 新增部门 和 修改部门使用的是同一个Dialog对话框,当前点击 “确定” 按钮的时候,有可能执行的是新增操作,也有可能是修改操作。
那应该如何辨别到底是新增,还是修改操作呢 ?
其实,我们只需要根据 deptForm
对象的id属性值,来判断即可。 如果没有id,则是新增操作 ;如果有id,则是修改操作。
所以,保存修改功能实现如下:
1). 在 src/api/dept.ts
中增加如下修改部门的请求
//修改部门
export const updateApi = (dept:DeptModel) => request.put<any, ResultModel>('/depts', dept)
2). 在 src/views/dept/index.vue
中完善(修改) save 函数的逻辑
//点击保存按钮-发送异步请求
const save = async () => {let result = null;if(deptForm.value.id){result = await updateApi(deptForm.value) //有id, 执行修改操作}else {result = await addApi(deptForm.value) //没有id, 执行新增操作}if(result.code){ElMessage.success('操作成功')}else{ElMessage.error(result.msg)}dialogFormVisible.value = falsequeryAll()
}
5.4 删除部门
1). 在 src/api/dept.ts
中增加如下删除部门的请求
//删除部门
export const deleteApi = (id:number) => request.delete<any, ResultModel>(`/depts?id=${id}`)
2). 在 src/views/dept/index.vue
中为什么 删除 按钮绑定事件
<el-button size="small" type="danger" @click="deleteById(scope.row.id)">删除</el-button>
3). 在 src/views/dept/index.vue
编写根据ID删除数据的函数
//删除部门
const deleteById =async (id:number) => {//弹出确认框ElMessageBox.confirm('您确认删除此部门吗? ', '确认删除').then( async () => {let result = await deleteApi(id)if(result.code){ //成功ElMessage.success('删除成功')queryAll()}else {ElMessage.error(result.msg)}}).catch(() => {ElMessage.info('取消删除')})
}
打开浏览器做一个测试:
5.5 表单校验
目前,我们已经基本完成了部门管理的增删改查操作。 接下来,我们对部门管理的功能进行,最后一块完善工作,增加表单校验。 从页面原型中,我们可以看到,新增部门的时候部门名称,不能为空,而且长度得在2-10之间。
5.5.1 ElementPlus 参考
Form 组件允许你验证用户的输入是否符合规范,来帮助你找到和纠正错误。Form
组件提供了表单验证的功能,只需为 rules
属性传入约定的验证规则,并将 form-Item
的 prop
属性设置为需要验证的特殊键值即可。
5.5.2 实现
1). 定义表单校验规则
//定义表单校验规则
const deptFormRef = ref<FormInstance>()
const rules = ref<FormRules<DeptModel>>({name: [{ required: true, message: '部门名称不能为空', trigger: 'blur' },{ min: 2, max: 10, message: '部门名称长度在2-10个字之间', trigger: 'blur' },]
})
2). 将表单校验规则与表单绑定
为表单 <el-form>
绑定 rules
属性绑定表单校验规则 。 为每一个表单项,指定 prop
属性,设置为需要验证的属性名。
3). 表单提交时,校验表单,校验通过,则允许提交表单。
修改save方法的逻辑,需要加入表单校验的逻辑。
//点击保存按钮-发送异步请求
const save = async (form:FormInstance | undefined) => {if(!form) return;await form.validate(async (valid) => {if (valid) {let result = null;if(deptForm.value.id){result = await updateApi(deptForm.value)}else {result = await addApi(deptForm.value)}if(result.code){ElMessage.success('操作成功')}else{ElMessage.error(result.msg)}dialogFormVisible.value = falsequeryAll()}})
}
4). 重置表单校验结果
//重置表单校验结果
const resetForm = (formEl: FormInstance | undefined) => {if (!formEl) returnformEl.resetFields()
}
然后在点击 “新增” / “修改” 按钮的时候,调用 resetForm 函数,重置表单校验结果。
最终,部门管理的完整代码如下:
1). src/api/dept.ts
import request from "@/utils/request"
import type { DeptModel, ResultModel } from "./model/model"//列表查询
export const queryAllApi = () => request.get<any, ResultModel>('/depts')//添加部门
export const addApi = (dept:DeptModel) => request.post<any, ResultModel>('/depts', dept)//根据ID查询
export const queryInfoApi = (id:number) => request.get(`/depts/${id}`)//修改部门
export const updateApi = (dept:DeptModel) => request.put<any, ResultModel>('/depts', dept)//删除部门
export const deleteApi = (id:number) => request.delete<any, ResultModel>(`/depts?id=${id}`)
2). src/views/dept/index.vue
<script setup lang="ts">
import {ref, onMounted} from 'vue'
import type { DeptModelArray, DeptModel } from '@/api/model/model'
import {queryAllApi, addApi, queryInfoApi, updateApi, deleteApi} from '@/api/dept'
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus';//声明列表展示数据
let tableData = ref<DeptModelArray>([])//动态加载数据-查询部门
const queryAll = async () => {const result = await queryAllApi()tableData.value = result.data
}//钩子函数
onMounted(() => {queryAll()
})//新增部门
const dialogFormVisible = ref<boolean>(false)
const deptForm = ref<DeptModel>({name: ''})
const formTitle = ref<string>('')//点击新增按钮触发的函数
const add = () => {formTitle.value = '新增部门'dialogFormVisible.value = truedeptForm.value = {name: ''}
}//点击保存按钮-发送异步请求
const save = async (form:FormInstance | undefined) => {if(!form) return;await form.validate(async (valid) => {if (valid) {let result = null;if(deptForm.value.id){result = await updateApi(deptForm.value)}else {result = await addApi(deptForm.value)}if(result.code){ElMessage.success('操作成功')}else{ElMessage.error(result.msg)}dialogFormVisible.value = falsequeryAll()}})
}//修改部门-查询回显
const update = async (id:number) => {formTitle.value = '修改部门'dialogFormVisible.value = truedeptForm.value = {name: ''}const result = await queryInfoApi(id)deptForm.value = result.data
}//删除部门
const deleteById =async (id:number) => {//弹出确认框ElMessageBox.confirm('您确认删除此部门吗? ', '确认删除').then( async () => {let result = await deleteApi(id)if(result.code){ //成功ElMessage.success('删除成功')queryAll()}else {ElMessage.error(result.msg)}}).catch(() => {ElMessage.info('取消删除')})
}//定义表单校验规则
const deptFormRef = ref<FormInstance>()
const rules = ref<FormRules<DeptModel>>({name: [{ required: true, message: '部门名称不能为空', trigger: 'blur' },{ min: 2, max: 10, message: '部门名称长度在2-10个字之间', trigger: 'blur' },]
})//重置表单校验结果
const resetForm = (form: FormInstance | undefined) => {if (!form) returnform.resetFields()
}
</script><template><h1>部门管理</h1><el-button type="primary" style="float: right" @click="add(); resetForm(deptFormRef);">+ 新增</el-button><br><br><!-- 部门数据表格 --><el-table :data="tableData" border style="width: 100%"><el-table-column type="index" label="序号" width="80" align="center"/><el-table-column prop="name" label="部门名称" width="250" align="center"/><el-table-column prop="updateTime" label="最后操作时间" width="300" align="center"/><el-table-column label="操作" align="center"><template #default="scope"><el-button size="small" type="primary" @click="update(scope.row.id); resetForm(deptFormRef);">修改</el-button><el-button size="small" type="danger" @click="deleteById(scope.row.id)">删除</el-button></template></el-table-column></el-table><!-- 新增部门 / 修改部门对话框 --><el-dialog v-model="dialogFormVisible" :title="formTitle" width="30%"><el-form :model="deptForm" :rules="rules" ref="deptFormRef"><el-form-item label="部门名称" label-width="80px" prop="name"><el-input v-model="deptForm.name" autocomplete="off" /></el-form-item></el-form><template #footer><span class="dialog-footer"><el-button @click="dialogFormVisible = false; resetForm(deptFormRef);">取消</el-button><el-button type="primary" @click="save(deptFormRef)">确定</el-button></span></template></el-dialog></template><style scoped></style>
相关文章:
Day20-前端Web案例——部门管理
目录 部门管理1. 前后端分离开发2. 准备工作2.1 创建Vue项目2.2 安装依赖2.3 精简项目 3. 页面布局3.1 介绍3.2 整体布局3.3 左侧菜单 4. Vue Router4.1 介绍4.2 入门4.3 案例4.4 首页制作 5. 部门管理5.1部门列表5.1.1. 基本布局5.1.2 加载数据5.1.3 程序优化 5.2 新增部门5.3…...
实验3 以太坊交易周期的需求分析
区块链技术 实验报告 实验名称 实验3 以太坊交易周期的需求分析 一、实验目的 1、学习并掌握以太坊交易的内容; 2、学习并掌握以太坊交易周期的四个阶段; 3、学习并掌握结构化需求分析方法; 4、学习并掌握面向对象的需求分析方法&…...
Linux 通过压缩包安装 MySQL 并设置远程连接教程
一、引言 在 Linux 系统中,有时候我们需要通过压缩包的方式手动安装 MySQL 数据库,并且为了方便在其他设备上对数据库进行管理和操作,还需要设置允许远程连接。本文将详细介绍在 Linux(以 CentOS 为例)系统中通过压缩包安装 MySQL 8 并设置远程连接的步骤。 二、安装前准…...
【商城实战(56)】商城数据生命线:恢复流程与演练全解析
【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配…...
Java学习笔记-XXH3哈希算法
XXH3是由Yann Collet设计的非加密哈希算法,属于XXHash系列的最新变种,专注于极速性能与低碰撞率,适用于对计算效率要求极高的场景。 极速性能 在RAM速度限制下运行,小数据(如 1-128 字节)处理可达纳秒级&…...
同旺科技USB to SPI 适配器 ---- 指令循环发送功能
所需设备: 内附链接 1、同旺科技USB to SPI 适配器 1、周期性的指令一次输入,即可以使用 “单次发送” 功能,也可以使用 “循环发送” 功能,大大减轻发送指令的编辑效率; 2、 “单次发送” 功能,“发送数据…...
在Mac M1/M2芯片上完美安装DeepCTR库:避坑指南与实战验证
让推荐算法在Apple Silicon上全速运行 概述 作为推荐系统领域的最经常用的明星库,DeepCTR集成了CTR预估、多任务学习等前沿模型实现。但在Apple Silicon架构的Mac设备上,安装过程常因ARM架构适配、依赖库版本冲突等问题受阻。本文通过20次环境搭建实测…...
【CXX-Qt】2.5 继承
某些 Qt API 要求你从抽象基类中重写某些方法,例如 QAbstractItemModel。 为了支持直接从 Rust 中创建这样的子类,CXX-Qt 提供了多种辅助工具。 某些基类可能需要特殊的构造参数。这可以通过使用自定义构造函数来实现。 访问基类方法 要在 Rust 中访…...
Linux系统之美:环境变量的概念以及基本操作
本节重点 理解环境变量的基本概念学会在指令和代码操作上查询更改环境变量环境变量表的基本概念父子进程间环境变量的继承与隔离 一、引入 1.1 自定义命令(我们的exe) 我们以往的Linux编程经验告诉我们,我们在对一段代码编译形成可执行文件后…...
【nnUnetv2】推理+评估+测试
在 Windows 系统下设置环境变量 之前训练和推理的时候开着AutoDL的服务器,是在 Linux 系统下设置的环境变量。 但是现在开始研究具体代码了,就在本地跑(一直开着服务器有点费钱),所以就在Windows 系统下设置环境变量。 ①右键点击 “此电脑”,选择 “属性”。 ②在左侧…...
损失函数理解(一)——极大似然估计
本博客内容来自B站up主【王木头学科学】的视频内容 习惯看视频的小伙伴可移至视频链接[待补充]:~~~ 首先通俗地解释一下极大似然估计(Maximum Likelihood Estimation,MLE)的思想:通过结果寻找使该结果发生的最可能的原…...
ios端使用TCplayer直播播放三秒直接卡顿bug
1. 查看配置项没问题 setTcPlayer() {let that this;player new TcPlayer("videoPlayer", {live: this.activatPlayType "livePlay" ? true : false,x5_type: "h5",x5_fullscreen: true,systemFullscreen: true,x5_orientation: 1,x5_player…...
大模型-提示词工程与架构
什么是提示工程 提示工程(Prompt Engineering)是一门新兴的技术领域,专注于研究如何设计、构建和优化提示词,以充分发挥大模型的潜力 。它涉及到对语言结构、任务需求、模型特性等多方面因素的综合考量。提示工程的目标是通过精心…...
高斯数据库-WDR Snapshot生成性能报告
docker 安装高斯数据库: docker pull opengauss/opengauss:latestdocker run --name opengauss --privilegedtrue -d -e GS_PASSWORDopenGauss123 -p 8090:5432 -v /opengauss:/var/lib/opengauss/data opengauss/opengauss:latest 进入容器设置用户权限ÿ…...
损失函数理解(二)——交叉熵损失
损失函数的目的是为了定量描述不同模型(例如神经网络模型和人脑模型)的差异。 交叉熵,顾名思义,与熵有关,先把模型换成熵这么一个数值,然后用这个数值比较不同模型之间的差异。 为什么要做这一步转换&…...
CSS学习笔记
【1】CSS样式规则 【2】CSS样式表引入方式 1、行内式 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"/><meta name"vi…...
AI比人脑更强,因为被植入思维模型【15】马斯洛需求层次理论
马斯洛需求层次模型思维模型 定义 马斯洛需求层次模型是由美国心理学家亚伯拉罕马斯洛(Abraham Maslow)于1943年提出的一种心理学理论,用于描述人类动机的层次结构。该模型将人类的需求从低到高分为五个层次,分别是生理需求、安…...
cartographer中地图转换
文章目录 地图种类栅格地图 坐标系种类ros坐标系像素坐标系物理坐标系(世界坐标系) 地图种类 栅格地图 地图的初始化 在Cartographer中,栅格地图通过概率值来表示每个栅格的状态。每个栅格的初始概率值通常设置为0.5,表示未知状态。这种初始化方式允许…...
关于MTU的使用(TCP/IP网络下载慢可能与此有关)
参考链接:告诉你mtu值怎么设置才能网速最好! -Win7系统之家 出现网络速度被限制,可能与MTU值相关,先查看下本机的MTU winR,然后输入:netsh interface ipv4 show subinterfaces ,查看自己网络中的MTU&…...
【AI解题】Cache直接映射地址划分解析
一、问题背景 某32位总线处理器的Cache采用直接映射方式,已知 Cache总容量为16KB,每个Cache块大小为16字节。需要确定内存地址中 Offset(块内偏移)、Index(块索引)、Tag(标签) 三部…...
android音频概念解析
音频硬件接口(我们可以理解为ASOC的声卡) 官方代码里叫audio hardware interface 也称为module,定义在services/audiopolicy/config/audio_policy_configuration.xml: 分别有primary,a2dp,usb࿰…...
项目生命周期 和 项目管理生命周期的差异
在项目管理中,明确区分 项目生命周期 和 项目管理生命周期 是理解项目运作的关键。以下从定义、阶段划分到实际应用进行系统性分析: 一、项目生命周期(Project Life Cycle) 定义 项目生命周期是项目从 启动到结束 的自然演进过程,描述项目交付成果的 技术性阶段,通常与…...
UDP 协议
文章目录 UDP 协议简介数据包格式UDP 通信流程抓包分析参考 本文为笔者学习以太网对网上资料归纳整理所做的笔记,文末均附有参考链接,如侵权,请联系删除。 UDP 协议 UDP 是一种面向无连接的传输层协议,属于 TCP/IP 协议簇的一种。…...
[已解决]jupyter notebook报错 500 : Internal Server Error及notebook闪退
jupyter notebook出现如上图的报错,可以在黑色窗口中检查是为什么报错。 我检查发现是nbconvert导致的问题,卸载重装nbconvert。 但是这时候出现,jupyter notebook闪退问题。jupyter的黑色窗口出现一秒钟就没了。 在Anaconda Prompt中检查ju…...
APM 仿真遥控指南
地面站开发了一段时间了,由于没有硬件,所以一直在 APM 模拟器中验证。我们已经实现了 MAVLink 消息接收和解析,显示无人机状态,给无人机发送消息,实现一键起飞,飞往指定地点,降落,返…...
使用 ncurses 库创建文本用户界面:基础函数详解
简介 ncurses 是一个功能强大的库,用于在 Unix-like 系统中创建文本用户界面。它提供了丰富的函数来控制屏幕上的文本显示、处理键盘输入、绘制图形元素等。本文将详细介绍 ncurses 库中的一些基础函数,包括 printw、wrefresh、获取用户信息、键盘输入、…...
dify创建第一个Agent
1、首先LLM模型必须支持 Function Calling 由于deepseek-R1本地化部署时还不支持,所以使用 qwq模型。 2、创建空白 Agent 3、为Agent添加工具 4、测试 当未添加时间工具时 询问 时间 如下 5、开启时间工具 询问如下...
nebula graph传统使用Docker进行项目发版
nebula graph传统使用Docker进行项目发版 1. nebula graph服务2. 搭建ES集群3. 注意事项3.1 图数据库的启动顺序3.2 模糊查询失效 1. nebula graph服务 1.在测试服务器中执行如下命令 docker commit 85b6e2b8xxx xxx_nebula_es:1.0.0.2执行docker images之后能看到新的镜像 x…...
OpenCV vs MediaPipe:哪种方案更适合实时手势识别?
引言 手势识别是计算机视觉的重要应用,在人机交互(HCI)、增强现实(AR)、虚拟现实(VR)、智能家居控制、游戏等领域有广泛的应用。实现实时手势识别的技术方案主要有基于传统计算机视觉的方法&am…...
PRODIGY: “不折腾人”的蛋白-蛋白/蛋白-小分子结合能计算工具
PRODIGY(全称为 PROtein binDIng enerGY prediction)是一种蛋白质结合能预测工具,可利用蛋白质-蛋白质复合物的三维结构来预测其结合亲和力。PRODIGY 利用一种高效的基于接触的方法,在估计结合自由能和解离常数的同时,…...
IDEA修改默认作者名称
User: IDEA提示注释缺少author信息,但自动设置后,名称不是我想要的默认名称,应该如何修改IDEA里默认的作者名称? Kimi: 以下是几种修改IntelliJ IDEA中默认作者名称的方法: ### 方法一:修改File and Code …...
【嵌入式学习2】C语言 - VScode环境搭建
目录 ## 语言分类 ## c语言编译器 ## VScode相关配置 ## 语言分类 编译型语言:C,C解释型语言:python,JS ## c语言编译器 分类GCC 系列MinGWCygwinMSVC系列一套编程语言编译器将GCC编译器和GNU Binutils移植到Win32平台下的产物…...
【TI MSPM0】Timer学习
一、计数器 加法计数器:每进入一个脉冲,就加一减法计算器:每进入一个脉冲,就减一 当计数器减到0,触发中断 1.最短计时时间 当时钟周期为1khz时,最短计时时间为1ms,最长计时时间为65535ms 当时…...
SQL Server数据库慢SQL调优
SQL Server中慢SQL会显著降低系统性能并引发级联效应。首先,用户直接体验响应时间延长,核心业务操作(如交易处理、报表生成)效率下降,导致客户满意度降低甚至业务中断。其次,资源利用率失衡,CPU…...
大数据平台上的数据建模与分析:从数据到决策的跃迁
大数据平台上的数据建模与分析:从数据到决策的跃迁 随着数字化转型的深入,大数据平台成为了企业实现智能决策和创新的核心技术基础。大量结构化、半结构化和非结构化数据的生成和存储,促使企业需要更高效的方式来管理、分析、以及从中提取有价值的信息。在这一过程中,数据…...
C++ --- 多态
1 多态的概念 多态(polymorphism)的概念:通俗来说,就是多种形态。多态分为编译时多态(静态多态)和运⾏时多 态(动态多态),这⾥我们重点讲运⾏时多态,编译时多态(静态多态)和运⾏时多态(动态多态)。编译时 多态(静态多态)主要就是我…...
细说卫星导航:测距定位原理
测距定位原理 1. 伪距测量技术 核心原理:卫星发射信号,用户接收并记录传播时间,乘以光速得到距离(伪距)。 技术细节: 信号传播路径分析 信号结构: 卫星信号包含三部分: 载波&…...
【AI News | 20250322】每日AI进展
AI Repos 1、DeTikZify 可以把草图或图形转换成TikZ代码的模型,可用来绘制复杂的科学图表,输入草图或文字描述即可转换成TikZ代码。DeTikZify强大的地方在于它能理解图表的语义信息, 能识别图表中的不同组成部分及其含义,比如坐标…...
【js逆向入门】图灵爬虫练习平台 第九题
地址:aHR0cHM6Ly9zdHUudHVsaW5ncHl0b24uY24vcHJvYmxlbS1kZXRhaWwvOS8 f12进入了debugger,右击选择一律不在此处暂停, 点击继续执行 查看请求信息 查看载荷,2个加密参数,m和tt 查看启动器,打上断点 进来 往…...
重新复活的(手机端)一站式应用管理与下载平台
应用乐园(安卓) 应用乐园作者去年3月表示,由于精力问题,要停止维护奇妙搜索、应用乐园、奇妙影视这些软件了。 然而最近,令人意外的是,应用乐园竟然“复活”了!更准确地说,它进行了…...
AI密码学
嗯,用户给了一个需要破译的密码文档:“Uif qjh jt po uif usff.”,提示是用字母往前推移1的凯撒密码。首先,我得确认自己是否正确理解提示。凯撒密码通常是将字母按照一定位移来替换,这里的提示是往前推1位,…...
Python设计模式 - 适配器模式
定义 适配器模式(Adapter Pattern)是一种结构型设计模式,它用于将一个类的接口转换为客户端所期待的另一个接口。 注:在适配器模式定义中所提及的接口是指广义的接口,它可以表示一个方法或者一组方法的集合。 结构 …...
S32K324 MCAL SPI波特率配置不对问题排查
文章目录 前言MCAL配置检查SPI时钟源问题处理总结 前言 项目开发过程中,MCAL SPI配置时发现实际配置的波特率和用逻辑分析仪采集的时钟频率对不上,实际的频率只有配置的一半,本文记录该问题的排查过程。 MCAL配置检查 MCAL SPI配置波特率在…...
STM32八股【2】-----ARM架构
1、架构包含哪几部分内容 寄存器处理模式流水线MMU指令集中断FPU总线架构 2、以STM32为例进行介绍 2.1 寄存器 寄存器名称作用R0-R3通用寄存器用于数据传递、计算及函数参数传递;R0 也用于存储函数返回值。R4-R12通用寄存器用于存储局部变量,减少频繁…...
Java 记忆链表,LinkedList 的升级版
文章目录 记忆链表 MemoryLinkedList实战源代码 众所周知,ArrayList 和 LinkedList 是 Java 集合中两个基本的数据结构,对应数据结构理论中的数组和链表。但在这两个数据结构,开发者们通常使用 ArrayList,而不使用 LinkedList。JD…...
浔川社团官方联合会维权成功
在2025.3.2日,我社团检测文章侵权中,检测出3篇文章疑似遭侵权,随后,总社团联合会立即联系CSDN版权,经过17天的维权,至今日晚,我社团维权成功!侵权文章全部被设置为转载。 在此&…...
asp.net core mvc模块化开发
razor类库 新建PluginController using Microsoft.AspNetCore.Mvc;namespace RazorClassLibrary1.Controllers {public class PluginController : Controller{public IActionResult Index(){return View();}} }Views下Plugin下新建Index.cshtml {ViewBag.Title "插件页…...
Linux——线程
Linux——线程 目录 一、线程 1.1 创建一个线程 1.2 主函数等待线程结束pthread_join 为什么输出是乱序的 一、线程 线程:进程内部的一条执行路径 进程:一个正在运行的程序 进程相当于工厂车间,线程就是车间里的许多工人 1.1 创建一个…...
dubbo异步调用
Dubbo 异步调用分为 Provider 端异步调用和 Consumer 端异步两种模式。 Consumer 端异步是指发起 RPC 调用后立即返回,调用线程继续处理其他业务逻辑,当响应结果返回后通过回调函数通知消费端结果。Provider 端异步执行将阻塞的业务从 Dubbo 内部线程池…...
2025知识图谱峰会(脱敏)PPT合集(18份).zip
2025知识图谱峰会(脱敏)PPT合集,共18份。 一、GraphRAG:核心技术与应用 1、多模态GraphRAG初探:文档智能知识图谱大模型结合范式.pdf 2、GraphRAG在CVTE多业务场景下的探索与应用.pdf 二、企业知识管理智能化升级&am…...