既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
</otherwise>
</choose>
<if test="storey!=null">
AND c_house.storey=#{storey}
</if>
<if test="areaMin!=null">
AND c_house.area >= #{areaMin}
</if>
<if test="areaMax!=null">
AND c_house.area <= #{areaMax}
</if>
<choose>
<when test="status!=null and status.length>0 and !status[0]">
<!-- 如果为false,则可以查询到非空闲房子-->
</when>
<otherwise>
AND !status
</otherwise>
</choose>
</where>
<if test="areaOrderASC">
ORDER BY c_house.area
</if>
<if test="areaOrderDESC">
ORDER BY c_house.area DESC
</if>
</select>
>
> 前后端交互controller层,用专门前后端交互的实体类接收参数
>
>
>
// 2.处理搜索请求
// 默认显示所有可以选择的房间,放到左侧的框里,如果选择,双击,这条数据跳到右边的框里
@RequestMapping(“/query/house”)
@ResponseBody
public ResData queryHouse(
// @RequestParam(value = “buildingList”, defaultValue = “List[]”) List buildingList, // 楼栋
// Integer storey, // 楼层,没有用到
// Double areaMin,
// Double areaMax,
// @RequestParam(value = “areaOrderASC”,defaultValue = “false”) Boolean areaOrderASC,
// @RequestParam(value = “areaOrderDESC”,defaultValue = “false”) Boolean areaOrderDESC
@RequestBody HouseFront houseFront
){
Double areaMax = houseFront.getAreaMax();
Double areaMin = houseFront.getAreaMin();
Boolean areaOrderASC = houseFront.getAreaOrderASC();
Boolean areaOrderDESC = houseFront.getAreaOrderDESC();
Integer storey = houseFront.getStorey();
List buildingList = houseFront.getBuildingList();
List buildingIds = buildingList.stream().map(Building::getId).collect(Collectors.toList());
System.out.println("查询条件:"
+areaMin+"/"
+areaMax+"/"
+buildingIds+"/"
+storey+"/"
);
// 大小的问题
if (!StringUtils.isBlank(areaMin) && !StringUtils.isBlank(areaMax)){
if (areaMin.compareTo(areaMax)>0){
return new ResData(1002, "最小面积不能大于最大面积", null);
}
}
// 这个排序顺序不能两个都是true
if (areaOrderASC && areaOrderDESC){
return new ResData(1003, "排序条件冲突", null);
}
List<House> list = houseService.queryAllNoIntoHouse(buildingIds, storey, areaMin, areaMax, areaOrderASC, areaOrderDESC, true);
list.forEach(System.out::println);
return new ResData(200, "ok", list);
}
前端代码
录入业主基础信息:
用户名: 真实姓名: 电话号码:
身份证号:<input type="text" v-model="identity">
性别:
<input type="radio" v-model="gender" value="男">男
<input type="radio" v-model="gender" value="女">女
<br>
备注信息:<textarea v-model="notes" rows="3" cols="22"></textarea><br>
<br>
录入选房信息:<br>
<div>
楼栋编号:
<select v-model="buildingId">
<option value="">--请选择楼栋--</option>
<option v-for="building in buildingList" :value="building.id">{{building.num}}-{{building.unit}}</option>
</select>
<button @click="addBuildingId">添加楼栋</button>
<button @click="resetSelectBuildsBtn">重选楼栋</button>
<br>
选中的楼栋为:
<select multiple style="width: 100px" @dbclick="removeSelectedBuildingsBtn">
<option v-for="building in selectedBuildingList" :value="building.id">{{building.num}}-{{building.unit}}</option>
</select>
楼层:
<select v-model="selectFloor">
<option value="">-选择楼层--</option>
<option v-for="floors in floorList" :value="floors">{{floors}}层</option>
</select>
面积:
<input type="text" v-model="areaMin" style="width: 50px" placeholder="小">---
<input type="text" v-model="areaMax" style="width: 50px" placeholder="大">
<button @click="areaASC">面积升序</button>
<button @click="areaDESC">面积降序</button>
<button @click="searchHouseBtn">搜索房子</button>
<button @click="searchHouseBtnClr">重置搜索</button><br>
</div>
可选的房子为:
<select multiple style="width: 200px" @dblclick="selectHouseDbc">
<option v-for="house in canSelectHouse" :value="house.id">
{{house.num}}--{{house.unit}}--{{house.roomNum}}--{{house.area}}
</option>
</select>
选中的房子为:
<select multiple style="width: 200px" @dblclick="removeSelectedHouseDbc">
<option v-for="house in selectedHouse" :value="house.id">
{{house.num}}--{{house.unit}}--{{house.roomNum}}--{{house.area}}平米
</option>
</select>
<br>
<button @click="add">添加</button>
<button @click="reset">重置</button><br>
<br>
>
> 专门用来前后端交互的实体类
>
>
>
package com.tianju.entity;
import com.alibaba.druid.filter.AutoLoad;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* 专门用来和前端交互的一个对象;
* 用于选房页面的复杂查询
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class HouseFront {
private List buildingList;
private Integer storey;
private Double areaMin;
private Double areaMax;
private Boolean areaOrderASC;
private Boolean areaOrderDESC;
}
## 跨域问题及其解决
### 跨域问题CROS
同源策略:协议、域名(IP)、端口相同即为同源。浏览器的同源策略是一种约定,是浏览器最核心也是最基本的安全功能,如果浏览器少了同源策略,则浏览器的正常功能可能都会受到影响。
![在这里插入图片描述](https://img-blog.csdnimg.cn/3ac974668d2f4082a7d11878e783bca2.png)
>
> 跨域是指:**浏览器A**从**服务器B**获取的静态资源,包括Html、Css、Js,然后在**Js**中通过**Ajax**访问**C服务器**的静态资源或请求。即:浏览器A从B服务器拿的资源,资源中想访问服务器C的资源。
>
>
>
>
> ---
>
>
>
> 同源策略是指:
> **浏览器A**从
> **服务器B**获取的静态资源,包括Html、Css、Js,为了用户安全,浏览器加了限制,其中的
> **Js**通过
> **Ajax**只能访问
> **B服务器**的静态资源或请求。即:浏览器A从哪拿的资源,那资源中就只能访问哪。
>
>
> ---
>
>
>
> 同源是指:同一个请求协议(如:Http或Https)、同一个Ip、同一个端口,3个全部相同,即为同源。
>
>
>
![在这里插入图片描述](https://img-blog.csdnimg.cn/69e8458d455a41b9bfade74b008ed34d.png)
### SpringBoot解决方案
#### (1)解决方案:后台允许跨域@CrossOrigin
要点:
* 出现在类上,表示对所有方法上都起作用;
* 出现在方法上,表示对方法起作用
package com.tinaju.bm.controller;
import com.tinaju.bm.dto.HttpResp;
import com.tinaju.bm.dto.ResultCode;
import com.tinaju.bm.entity.Book;
import com.tinaju.bm.service.IBookService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.List;
@Api(tags = “图书的api接口类”)
@RestController
@RequestMapping(“/api/book”)
@Slf4j
public class BookController {
@Autowired
private IBookService bookService;
@ApiOperation("findPage方法测试")
@ApiImplicitParam(name = "findByPage",value = "分页查询",required = true)
@GetMapping("/findByPage")
public HttpResp findByPage(int currentPage){
List<Book> bookList = bookService.findByPage(currentPage, 5);
return HttpResp.results(ResultCode.BOOK\_SUCCESS,new Date(),bookList);
}
@CrossOrigin // TODO:直接在后台允许跨域
@ApiOperation("查询所有图书接口")
@GetMapping("/findAll")
public HttpResp findAll(){
long s1 = System.currentTimeMillis();
List<Book> list = bookService.findAll();
long s2 = System.currentTimeMillis();
log.debug("查询耗时>>>>>>>>>>>"+(s2-s1)+"毫秒");
return HttpResp.results(ResultCode.BOOK\_SUCCESS,new Date(),list);
}
}
#### (2)创建跨域类addCorsMappings
| 方法类 | 方法名称 | 必填 | 请求头字段 | 说明 |
| --- | --- | --- | --- | --- |
| CorsRegistry | addMapping | 是 | 无, 非Cors属性, 属于SpringBoot配置 | 配置支持跨域的路径 |
| CorsRegistration | allowedOrigins | 是 | Access-Control-Allow-Origin | 配置允许的源 |
| CorsRegistration | allowedMethods | 是 | Access-Control-Allow-Methods | 配置支持跨域请求的方法, 如:GET、POST,一次性返回 |
| CorsRegistration | maxAge | 否 | Access-Control-Max-Age | 配置预检请求的有效时间 |
| CorsRegistration | allowCredentials | 否 | Access-Control-Allow-Credentials | 配置是否允许发送Cookie, 用于 凭证请求 |
| CorsRegistration | allowedHeaders | 否 | Access-Control-Request-Headers | 配置允许的自定义请求头, 用于 预检请求 |
| CorsRegistration | exposedHeaders | 否 | Access-Control-Expose-Headers | 配置响应的头信息, 在其中可以设置其他的头信息 |
>
> implements WebMvcConfigurer
>
>
>
![在这里插入图片描述](https://img-blog.csdnimg.cn/a9792f1688f944b28aa16ab6105daf30.png)
>
> addCorsMappings(CorsRegistry registry)
>
>
>
![在这里插入图片描述](https://img-blog.csdnimg.cn/3f64dc9750834a39a46a55a5d7fdf69a.png)
package com.tinaju.bm.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 解决跨域的问题
*/
@Configuration
public class BmWebConfig implements WebMvcConfigurer {
// 可以不写实现类的原因是 default void configurePathMatch(PathMatchConfigurer configurer)
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/\*\*") // 所以级别下面的都允许跨域
.allowedOrigins("\*") // 允许跨域
.allowedMethods("GET","POST","PUT","DELETE")
.allowedHeaders("\*"); // 允许头部
}
}
### 在Vue中进行代理允许跨域
![在这里插入图片描述](https://img-blog.csdnimg.cn/5b215b00e7c84885b923d7bf7a0b426f.png)
const { defineConfig } = require(‘@vue/cli-service’)
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
port: 8080,
proxy: {
“/api”: { // 1.修改端口号
// (后端服务器地址)
// target: ‘http://124.70.138.34:10050’, // 2.配置代理服务器
target: ‘http://127.0.0.1:10050’, // 2.配置代理服务器
changeOrigin: true, // 3.允许跨域请求
pathRewrite: {
// ‘^/api’: ‘/’ // 4.把代理路径的api删除,类似正则表达
}
}
}
}
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
138.34:10050’, // 2.配置代理服务器
target: ‘http://127.0.0.1:10050’, // 2.配置代理服务器
changeOrigin: true, // 3.允许跨域请求
pathRewrite: {
// ‘^/api’: ‘/’ // 4.把代理路径的api删除,类似正则表达
}
}
}
}
[外链图片转存中…(img-HQOWjauc-1715490880215)]
[外链图片转存中…(img-tcflnUof-1715490880215)]
[外链图片转存中…(img-wwyfkZSr-1715490880216)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上软件测试知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新