基于 SSM 的 CRM 客户管理系统

news2024/11/29 0:47:23
  • 1:通过点击【登录】按钮,获取登录的接口地址

  • 2:在UserLoginController类中,增加登录接口

  • 3:首先判断用户名是否存在,其次判断匹配是否匹配

  • 4:处理session问题

  • 代码如下:

  • UserLoginController.java:

/**

  • 登录首页

  • @author likang

  • @date 2018-4-19 下午5:33:34

*/

@Controller

public class UserLoginController {

@Autowired

private IUserService userService;

/**

  • 跳转登录页面

  • @param model

  • @return

*/

@RequestMapping(value = “/login.do”,method = RequestMethod.GET)

public String index(Model model){

return JumpViewConstants.SYSTEM_LOGIN;

}

/**

  • 登录功能

  • @param request

  • @param email 用户名

  • @param password 密码

  • @param sign

  • @return

*/

@RequestMapping(value = “/login.do”,method = RequestMethod.POST)

public String login(HttpServletRequest request,String email,String password,String sign,Model model){

// if (email != null && !“”.equals(email)) {

//

// }

//isnotblank:判断参数是否为空和“”

//isNotEmpty:只会判断参数是否为null

if (StringUtils.isNotBlank(email) && StringUtils.isNotBlank(password)) {

//利用spring容器获取map中的属性值

email = email + ContextUtil.getInitConfig(“email_suffix”);

//验证用户名是否存在

User user = userService.queryUserByEmail(email);

if (user == null) {//用户不存在

// model.addAttribute(ReturnConstants.USER_NOT_EXIST);

model.addAttribute(“msg”, ReturnConstants.USER_NOT_EXIST);

return JumpViewConstants.SYSTEM_LOGIN;

}

//验证密码是否匹配

boolean isExis = userService.isExisPassword(String.valueOf(user.getUserid()), password);

if (!isExis) {

// model.addAttribute(ReturnConstants.PASSWORD_ERROR);

model.addAttribute(“msg”, ReturnConstants.PASSWORD_ERROR);

return JumpViewConstants.SYSTEM_LOGIN;

}

//cookie

//TODO…

//处理session

UserContext.setLoginUser(user);

request.getSession(true).setAttribute(“loginName”, user.getUsername());

request.getSession(true).setAttribute(“ischange”, user.getIschange());

//跳转成功首页

return JumpViewConstants.SYSTEM_INDEX;

}

return ReturnConstants.PARAM_NULL;//接收参数为空

}

}

  • IUserService.java:

/**

  • 用户信息接口

  • @author likang

  • @date 2018-4-23 上午9:36:12

*/

public interface IUserService {

/**

  • 根据邮箱查询用户信息

  • @param email 邮箱

  • @return

*/

public User queryUserByEmail(String email);

/**

  • 验证密码是否匹配

  • @param userid 用户主键ID

  • @param password 密码

  • @return

*/

public boolean isExisPassword(String userid,String password);

}

  • UserServiceImpl.java:

@Service

@Transactional(rollbackFor=Exception.class)

public class UserServiceImpl implements IUserService{

// @Resource//首先按照名称匹配,其次按照类型匹配

@Autowired//只会按照类型匹配(推荐使用)

IDataAccess userDao;

public User queryUserByEmail(String email) {

Map<String, Object> param = new HashMap<String, Object>();

param.put(“email”, email);

List list = userDao.queryByStatment(“queryUserByEmail”, param, null);

if (list != null && list.size() > 0) {

return list.get(0);

}

return null;

}

public boolean isExisPassword(String userid, String password) {

Map<String, Object> param = new HashMap<String, Object>();

param.put(“userid”, userid);

param.put(“password”, MD5Tools.encode(password));

List list = userDao.queryByStatment(“isExisPassword”, param, null);

if (list != null && list.size() > 0) {

return true;

}

return false;

}

}

  • UserMapper.xml:

select

u.userid,u.username,u.email,u.roleid,u.deptid,u.ischange

from hj_user u

where u.email = #{email}

select

u.userid,u.username,u.email,u.roleid,u.deptid

from hj_user u

where u.userid = #{userid} and u.password = #{password}

mybatis-config.xml:

















### []( )登录功能-首页访问–完善功能



*   代码如下:

*   UserLoginController.java:





/**

* 登录首页

* @author likang

* @date   2018-4-19 下午5:33:34

*/

@Controller

public class UserLoginController {





@Autowired

private IUserService userService;



/**

* 跳转登录页面

* @param model

* @return

*/

@RequestMapping(value = "/login.do",method = RequestMethod.GET)

public String index(Model model){

if (UserContext.getLoginUser() != null) {

return "redirect:/main.do";

}

return JumpViewConstants.SYSTEM_LOGIN;

}



/**

* 主页面

* @param model

* @return

*/

@RequestMapping(value = "/main.do",method = RequestMethod.GET)

public String main(Model model){

if (UserContext.getLoginUser() != null) {

return JumpViewConstants.SYSTEM_INDEX;

}

return JumpViewConstants.SYSTEM_LOGIN;

}



/**

* 登录功能

* @param request

* @param email  用户名

* @param password 密码

* @param sign

* @return

*/

@RequestMapping(value = "/login.do",method = RequestMethod.POST)

public String login(HttpServletRequest request,String email,String password,String sign,Model model){

//      if (email != null && !"".equals(email)) {

//          

//      }

//isnotblank:判断参数是否为空和“”

//isNotEmpty:只会判断参数是否为null

if (StringUtils.isNotBlank(email) && StringUtils.isNotBlank(password)) {

//利用spring容器获取map中的属性值

email = email + ContextUtil.getInitConfig("email_suffix");



//验证用户名是否存在

User user = userService.queryUserByEmail(email);

if (user == null) {//用户不存在

//              model.addAttribute(ReturnConstants.USER_NOT_EXIST);

model.addAttribute("msg", ReturnConstants.USER_NOT_EXIST);

return JumpViewConstants.SYSTEM_LOGIN;

}

//验证密码是否匹配

boolean isExis = userService.isExisPassword(String.valueOf(user.getUserid()), password);

if (!isExis) {

//              model.addAttribute(ReturnConstants.PASSWORD_ERROR);

model.addAttribute("msg", ReturnConstants.PASSWORD_ERROR);

return JumpViewConstants.SYSTEM_LOGIN;

}

//cookie

//TODO......



//处理session

UserContext.setLoginUser(user);

request.getSession(true).setAttribute("loginName", user.getUsername());

request.getSession(true).setAttribute("ischange", user.getIschange());

//跳转成功首页

//          return JumpViewConstants.SYSTEM_INDEX;

return "redirect:/main.do";

}

return ReturnConstants.PARAM_NULL;//接收参数为空

}

}









### []( )登录功能-cookie问题



*   开发步骤:



*   1:为了解决用户端禁用浏览器cookie第三方数据的问题

*   2:只需要在服务器中保存一份cookie即可,同步到浏览器客户端

*   示例代码:



*   UserLoginController.java:





private static final String COOKIE_KEY = "_auth_";

private static final String COOKIE_SPI = "_#_";



/**

* 登录功能

* @param request

* @param email  用户名

* @param password 密码

* @param sign

* @return

*/

@RequestMapping(value = "/login.do",method = RequestMethod.POST)

public String login(HttpServletRequest request,HttpServletResponse response,String email,String password,String sign,Model model){

//      if (email != null && !"".equals(email)) {

//          

//      }

//isnotblank:判断参数是否为空和“”

//isNotEmpty:只会判断参数是否为null

if (StringUtils.isNotBlank(email) && StringUtils.isNotBlank(password)) {

//利用spring容器获取map中的属性值

email = email + ContextUtil.getInitConfig("email_suffix");



//验证用户名是否存在

User user = userService.queryUserByEmail(email);

if (user == null) {//用户不存在

//              model.addAttribute(ReturnConstants.USER_NOT_EXIST);

model.addAttribute("msg", ReturnConstants.USER_NOT_EXIST);

return JumpViewConstants.SYSTEM_LOGIN;

}

//验证密码是否匹配

boolean isExis = userService.isExisPassword(String.valueOf(user.getUserid()), password);

if (!isExis) {

//              model.addAttribute(ReturnConstants.PASSWORD_ERROR);

model.addAttribute("msg", ReturnConstants.PASSWORD_ERROR);

return JumpViewConstants.SYSTEM_LOGIN;

}

//cookie

Cookie cok = new Cookie(COOKIE_KEY, URLEncoder.encode(user.getUsername())+COOKIE_SPI+MD5Tools.encode(user.getEmail()));

cok.setPath("/");

cok.setMaxAge(-1);//-1:立即创建,并且在登录成功之后,就生效

//0:在客户端关闭浏览器之后,即失效

response.addCookie(cok);

//处理session

UserContext.setLoginUser(user);

request.getSession(true).setAttribute("loginName", user.getUsername());

request.getSession(true).setAttribute("ischange", user.getIschange());

//跳转成功首页

//          return JumpViewConstants.SYSTEM_INDEX;

return "redirect:/main.do";

}

return ReturnConstants.PARAM_NULL;//接收参数为空

}









[]( )退出功能

-----------------------------------------------------------------



*   开发步骤:



*   1:清除session信息

*   2:清除存放于服务器中的cookie数据

*   3:清除客户端中的cookie数据

*   4:跳转登录页面即可

*   示例代码:



*   UserLoginController.java:





/**

* 退出

* @param request

* @return

*/

@RequestMapping(value = "/logout.do",method = RequestMethod.GET)

public String logout(HttpServletRequest request,HttpServletResponse response){

//清除session

UserContext.clearLoginUser();

//清除服务器中的cookie数据

Cookie cok = new Cookie(COOKIE_KEY,null);

cok.setMaxAge(0);

cok.setPath("/");

response.addCookie(cok);

//清除客户端中的cookie数据

Cookie coksessionID = new Cookie("JSESSIONID",null);

coksessionID.setMaxAge(0);

coksessionID.setPath(request.getContextPath());

response.addCookie(coksessionID);



//跳转登录页面

return "redirect:/main.do";

}









[]( )登录成功-权限管理-左侧菜单展示功能

-------------------------------------------------------------------------------



*   开发步骤:



*   1:根据登录成功用户的角色ID,查询对应的菜单信息,参考第一天的sql语句

*   2:首先查询一级菜单信息

*   3:循环遍历一级菜单信息,查询当前一级菜单对应的二级菜单信息

*   示例代码:



*   UserLoginController.java:





/**

* 主页面

* @param model

* @return

*/

@RequestMapping(value = "/main.do",method = RequestMethod.GET)

public String main(Model model){

if (UserContext.getLoginUser() != null) {

//根据当前登录用户的角色,查询当前角色对应的菜单信息

List
 
   list = userService.queryMenusByRoleId(UserContext.getLoginUser().getRoleid().toString());

model.addAttribute("menus", list);

return JumpViewConstants.SYSTEM_INDEX;

}

return JumpViewConstants.SYSTEM_LOGIN;

}







*   IUserService.java:





/**

* 根据角色主键ID,查询当前角色对应的菜单信息

* @param roleId 角色主键ID

* @return

*/

public List
  
    queryMenusByRoleId(String roleId);







*   UserServiceImpl.java:





@Autowired

IDataAccess
   
     menuDao;

public List
    
      queryMenusByRoleId(String roleId) {



Map
    
   
  
 

UserServiceImpl.java:

public void saveOrUpdateUser(User user) {

if (user != null) {

if (user.getUserid() != null) {//修改

user.setUpdate_id(UserContext.getLoginUser().getUserid());

user.setUpdate_time(new Timestamp(System.currentTimeMillis()));

userDao.update(user);

}else{//增加

user.setCreate_id(UserContext.getLoginUser().getUserid());

user.setCreate_time(new Timestamp(System.currentTimeMillis()));

userDao.insert(user);

}

}

}









### []( )删除



*   开发步骤:



*   1:通过前端找到删除的接口地址(支持批量删除,真正企业做的时候,接口是后台来定义)

*   2:增加删除的接口和方法

*   示例代码:



*   UserController.java:





/**

* 删除用户信息,支持批量删除

* @param request

* @param ids 用户主键ID,多个用逗号隔开

* @return

*/

@RequestMapping(value = "/system/deleteUser.do",method = RequestMethod.POST)

public @ResponseBody String deleteUsers(HttpServletRequest request,String ids){

if (StringUtils.isNotBlank(ids)) {

userService.deleteUserByIds(ids);

return ReturnConstants.SUCCESS;

}

return ReturnConstants.PARAM_NULL;

}







*   IUserService.java:





/**

* 删除用户信息,批量删除

* @param ids 用户主键ID,多个用逗号隔开

*/

public void deleteUserByIds(String ids);







*   UserServiceImpl.java:





public void deleteUserByIds(String ids) {

if (StringUtils.isNotBlank(ids)) {

userDao.deleteByIds(User.class, ids);

}

}







*   提示:



*   1:回顾mysql的删除别名问题

*   2:练习mybatis中的for标签



### []( )页面展示



\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xHQiKuqq-1602315802000)(https://i.imgur.com/rUyy9qq.png)\]



[]( )测试环境项目部署过程

-----------------------------------------------------------------------



*   系统环境:



*   linux-CentOS7

*   使用工具:



*   CRT\\SCP

*   部署步骤:



*   1:首先确认本地访问运行没有任何问题

*   2:导出本地的数据库脚本,将脚本文件在虚拟机服务器的数据库中执行

*   3:使用scp工具连接服务器,将本地tomcat的webapps目录下的项目,拖到虚拟机服务器tomcat的webapps目录下(可选:修改项目访问名称,ROOT在访问时,不需要输入)

*   4:修改虚拟机服务器中项目的jdbc配置文件,修改为虚拟机数据库的连接信息

*   5:使用crt工具,启动tomcat

*   6:本地访问服务器项目信息

*   注意事项:



*   1:本地连接服务器的数据库,需要开启3306端口号(防火墙允许3306端口允许)





命令:/sbin/iptables -I INPUT -p tcp --dport 3306 -j ACCEPT







*   2:需要开启tomcat访问的端口号,命令如下:





/sbin/iptables -I INPUT -p tcp --dport 8080 -j ACCEPT







*   3:如果新增增量补丁,如下地方是需要重启tomcat服务的





- 接口代码

- 配置文件、属性文件

- xml对应的sql语句







*   4:查看服务器mysql是否开启的命令





ps -ef|grep mysql









[]( )菜单管理

-----------------------------------------------------------------



### []( )跳转页面





略,参考工程文件







### []( )查询





略,参考工程文件







### []( )增加、修改





略,参考工程文件







### []( )删除



*   需求:



1:如果菜单存在下一级菜单,则不允许删除  

2:如果菜单已经被分配,则不允许删除



*   开发步骤:



1://查询菜单ID,是否存在下一级菜单  

2://查询菜单ID,是否存在权限分配  

3://如果当前菜单ID,既不存在下一级菜单,又不存在权限分配,则可以直接删除成功  

4://如果满足其中一条信息,则都不允许删除,返回错误信息  

5://如果都不满足,删除成功



*   示例代码:



*   MenuController.java:





/**

* 菜单删除功能

* 

* 	1:如果菜单存在下一级菜单,则不允许删除

*	2:如果菜单已经被分配,则不允许删除

*

*  error1 = [菜单:用户管理,菜单管理]  存在下一级菜单信息,不允许删除

*  error2 = [菜单:角色管理,部门管理]  存在权限分配,不允许删除

*

* @param request

* @param ids 菜单主键ID,多个用逗号隔开

* @return

*/

@RequestMapping(value = "/menu/delete.do",method = RequestMethod.POST)

public @ResponseBody String deleteMenus(HttpServletRequest request,String ids){

if (StringUtils.isNotBlank(ids)) {



StringBuffer error1 = new StringBuffer();

StringBuffer error2 = new StringBuffer();

boolean ishasCh = false;

boolean ishasrm = false;



for (String id : ids.split(",")) {

//查询菜单ID,是否存在下一级菜单

if (menuService.isHasChiredMenu(id)) {//true:存在下一级菜单

if (!ishasCh) {

ishasCh = true;

}

if (error1.length() == 0){

error1.append("[菜单:");

}

error1.append(menuService.queryMenuById(id) != null ?menuService.queryMenuById(id).getMenuname() : "" ).append(",");

continue;

}

//查询菜单ID,是否存在权限分配

if (menuService.isHasRoleMenu(id)) {//true:存在权限分配

if (!ishasrm) {

ishasrm = true;

}

if (error2.length() == 0){

error2.append("[菜单:");

}

error2.append(menuService.queryMenuById(id) != null ?menuService.queryMenuById(id).getMenuname() : "" ).append(",");

continue;

}

menuService.deleleMenuById(id);//如果当前菜单ID,既不存在下一级菜单,又不存在权限分配,则可以直接删除成功

}



//如果满足其中一条信息,则都不允许删除,返回错误信息

if (ishasCh){

error1.deleteCharAt(error1.length() - 1).append("]  存在下一级菜单信息,不允许删除");

}

if (ishasrm){

error2.deleteCharAt(error2.length() - 1).append("]  存在权限分配,不允许删除");

}







// String msgbegin = ishasCh ? error1.toString() : “” + ishasrm ? ishasCh?error1.toString() : “”:""+error2.toString():"";





String msg = error1.toString()+error2.toString();



if (StringUtils.isNotBlank(msg)) {

return msg;

}

//如果都不满足,删除成功

return ReturnConstants.SUCCESS;



}

return ReturnConstants.PARAM_NULL;



}







*   IMenuService.java:





/**

* 根据菜单主键ID,判断当前菜单是否存在下一级菜单

* @param id 菜单主键ID

* @return

*/

public boolean isHasChiredMenu(String id);



/**

* 根据菜单主键ID,判断当前菜单是否存在权限分配

* @param id 菜单主键ID

* @return

*/

public boolean isHasRoleMenu(String id);





/**

* 根据菜单id,查询菜单信息

* @param id 主键ID

* @return

*/

public Menu queryMenuById(String id);





/**

* 根据主键ID,删除菜单信息

* @param id

*/

public void deleleMenuById(String id);







MenuServiceImpl.java:





public boolean isHasChiredMenu(String id) {

Map

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java计算机毕业设计ssm智能会议室管理系统0v396(附源码、数据库)

java计算机毕业设计ssm智能会议室管理系统0v396&#xff08;附源码、数据库&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xf…

TAPD新增需求自动通知飞书

【实现效果&#xff1a;】TAPD新增需求/缺陷&#xff0c;可以自动通知飞书机器人并通知相关人员&#xff0c;让相关人员可以及时关注到新增需求/缺陷并及时处理。 【流程配置】 第一步&#xff1a;打开腾讯云HiFlow模版中心&#xff0c;搜索打开“TAPD需求/项目更新实时通知飞…

C# !(null包容)运算符的使用

总目录 文章目录总目录前言一、!(null包容&#xff09;运算符是什么&#xff1f;二、!(null包容&#xff09;运算符如何使用&#xff1f;1.使用2.扩展-预处理器指令启用或关闭null检查总结前言 本文主要讲解&#xff01;&#xff08;null包容&#xff09;运算符的使用&#xf…

艾美捷科研专用西妥昔单抗Cetuximab相关介绍

西妥昔单抗&#xff08;Cetuximab&#xff09;&#xff0c;商品名尔必得舒&#xff08;Erbitux&#xff09;&#xff0c;是美商英克隆公司和美商百时美施贵宝的专-利药。西妥昔单抗是一种对抗表皮生长因子受体&#xff08;EGFR&#xff09;的单克隆抗体&#xff0c;经美国食品药…

MySQL表的增删查改(下)

作者&#xff1a;~小明学编程 文章专栏&#xff1a;MySQL 格言&#xff1a;目之所及皆为回忆&#xff0c;心之所想皆为过往 今天给大家分享的是增删查改中的一些比较核心的东西同时也是难点&#xff0c;希望能给大家带来一些帮助吧。 目录 数据库的约束 NULL约束 Unique的…

数据结构C语言版 —— 顺序表增删改查实现

文章目录顺序表1. 线性表2. 顺序表3. 顺序表基本概念4. 顺序表实现顺序表初始化顺序表的扩容顺序表的插入顺序表的删除顺序表的查找顺序表的修改顺序表的销毁5. 顺序表总结顺序表 1. 线性表 线性表&#xff1a;线性表是由n个具有相同特性的数据元素组成的序列。线性表是一种在…

【DevOps】总结下容器方式构建Grafana-reporter生成PDF格式报告

目录 Grafana-reporter1、编写Dockerfile2、构建镜像3、运行Grafana-reporter4、在Grafana配置Link即文章:【DevOps】Prometheus+Grafana:生成pdf报表总结下Grafana-reporter镜像打包过程 最终pdf实现效果类似: Grafana-reporter 简介:“A simple http service that gen…

[附源码]Python计算机毕业设计仿咸鱼二手物品交易系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

TCP/IP 网络原理【TCP篇】

&#x1f389;&#x1f389;&#x1f389;写在前面&#xff1a; 博主主页&#xff1a;&#x1f339;&#x1f339;&#x1f339;戳一戳&#xff0c;欢迎大佬指点&#xff01; 目标梦想&#xff1a;进大厂&#xff0c;立志成为一个牛掰的Java程序猿&#xff0c;虽然现在还是一个…

joinquant量化是什么?是主流的量化平台吗?

joinquant量化是什么&#xff1f;我们做量化投资的时候&#xff0c;目前比较流行的平台&#xff0c;我推荐的是这三个&#xff0c;一个是Ricequant&#xff0c;另外一个是JoinQuant&#xff0c;还有一个QUANTOPIAN&#xff0c;国内实际上就是优矿。这几个现在比较流行&#xff…

git分支管理

分支管理&#xff08;拙见&#xff09; 1&#xff0c;首先master分支是最高级别分支。不可编辑 2&#xff0c;创建一个release分支&#xff0c;从master上拉取&#xff0c;用于上线分支 3&#xff0c;创建dev开发分支&#xff0c;从relase分支拉取&#xff0c;如果有开发环境…

裸辞美团花两月吃透这 Java 岗 798 道真题解析,定级阿里 P7

2023 的面试即将到来&#xff0c;大家准备的怎么样了呢&#xff1f;你有没有正在为此而发愁呢&#xff1f;那么一起来看看小编整理的这富含的 15 个互联网大厂 Java 高级工程师核心面试问题整理吧&#xff01;已助我在 2023 年的金三银四跳槽季中拿到阿里 P7. 内容包括&#x…

Stm32旧版库函数9——ADC读取电压值

#include <stm32f10x_lib.h> #include "adc.h" unsigned char i0; u16 ad[3]{0,0,0}; //初始化ADC //这里我们仅以规则通道为例 void Adc_init(void) { //先初始化…

Unity - Baking System - 烘焙失效的问题

文章目录环境问题解决方法环境 unity : 2020.2.5f1, 2020.3.37f1 pipeline : BRP 问题 我之前有去搜索过场景烘焙失效的问题&#xff0c;都是 unity 发包后和 unity Editor 下运行不同&#xff1a;发包后丢失 烘焙效果&#xff0c;一般都是说&#xff1a;shader 中的 Lightma…

【Hive】分隔符 『 单字节分隔符 | 多字节分隔符』

文章目录1. 概述2. 单字节分隔符方法&#xff1a;使用delimited关键字3. 其它复杂情况方式一&#xff1a;写MR程序进行字符替换转为单字节分隔符问题&#xff08;不推荐&#xff09;方式二&#xff1a;自定义InputFormat转为单字节分隔符问题&#xff08;不推荐&#xff09;方式…

矩阵

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 车车的爱之矩阵是一个行数为 n&#xff0c;列数为 m 的矩阵并满足以下条件: 111. 矩阵元素 xij​ 为整数并满足 0<∣xij​∣⩽114514。 222. 对于在矩阵边界的元素&#xff0c;即 iii 为 1 或…

[附源码]Node.js计算机毕业设计非处方药的查询与推荐系统Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

Flutter - ScrollController 滚动监听及控制

1 ScrollController jumpTo(double offset)、animateTo(double offset,…)&#xff1a;这两个方法用于跳转到指定的位置&#xff0c;它们不同之处在于&#xff0c;后者在跳转时会执行一个动画&#xff0c;而前者不会。 实例 点击按钮返回顶部 ,且按钮在list滑动一定距离后才…

事务·数据库

事务就是一个完整的业务逻辑 举例&#xff1a; a账户转账至b账户&#xff0c;该操作是一个工作单元&#xff0c;要么同时成功要么同时失败&#xff0c;不可再分。 只有DML(INSERT DELETE UPDATE)语句才会有和事务有关系&#xff0c;因为这三个是操作数据库表中数据进行增删改的…

磨金石教育兴趣技能分享||运用好透视规律,就不会为大场面拍摄发愁了

许多摄影初学者&#xff0c;在拍摄简单的单独景物照或人物照时&#xff0c;经过简单的练习往往很快就能得心应手。 当画面稍微大一些&#xff0c;各种景物元素增多&#xff0c;空间立体感变强时&#xff0c;就会不知所措。拍出的照片不协调&#xff0c;而且杂乱。 这时候&…