Commit 8ce14840 authored by beilang's avatar beilang

新增收藏功能,我的收藏展示,分页模糊查询,删除我的收藏,页面优化调整

parent c8468506
package com.ces.common.core.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.List;
/**
* @author Tao
* @date 2024/12/10
*/
@Data
@AllArgsConstructor
public class TableData<T> {
private long total;
private List<T> rows;
}
package com.ces.framework.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Tao
* @date 2024/12/10
*/
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor paginationInterceptor() {
//1.初始化核心插件
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
//2.添加分页插件
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
package com.ces.web.collect.controller;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ces.common.core.domain.Result;
import com.ces.common.core.domain.TableData;
import com.ces.framework.shiro.dto.UserDTO;
import com.ces.web.collect.entity.DeviceCollect;
import com.ces.web.collect.service.IDeviceCollectService;
import com.ces.web.device.entity.DeviceInfo;
import com.ces.web.device.service.IDeviceService;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.*;
/**
* @author Tao
......@@ -23,39 +26,68 @@ public class DeviceCollectController {
@Autowired
private IDeviceCollectService deviceCollectService;
/**
* 添加收藏
* @param deviceId 设备ID
* @return
*/
@PostMapping("/add")
@Autowired
private IDeviceService deviceService;
@GetMapping("/index")
public String index() {
return "collect/index";
}
@GetMapping("/list")
@ResponseBody
public Result addCollect(Long deviceId) {
public TableData<DeviceCollect> list(DeviceCollect deviceCollect,
@RequestParam(required = false, defaultValue = "1") int pageNo,
@RequestParam(required = false, defaultValue = "10") int pageSize) throws InterruptedException {
UserDTO userDTO = (UserDTO) SecurityUtils.getSubject().getPrincipal();
QueryWrapper<DeviceCollect> queryWrapper = new QueryWrapper<>();
if (StrUtil.isNotBlank(deviceCollect.getPrisonName())) {
queryWrapper.eq("PRISON_NAME", deviceCollect.getPrisonName());
}
if (StrUtil.isNotBlank(deviceCollect.getDeviceName())) {
queryWrapper.like("DEVICE_NAME", deviceCollect.getDeviceName());
}
DeviceCollect collect = new DeviceCollect();
collect.setDeviceId(deviceId);
collect.setUserId(userDTO.getId());
Page<DeviceCollect> page = Page.of(pageNo, pageSize);
page = deviceCollectService.page(page, queryWrapper);
return deviceCollectService.save(collect) ? Result.success() : Result.error();
return new TableData<>(page.getTotal(), page.getRecords());
}
/**
*
* 移除收藏
* @param deviceId 设备ID
* @return
*/
@PostMapping("/remove")
@PostMapping("/{deviceId}")
@ResponseBody
public Result removeCollect(Long deviceId) {
public Result collect(@PathVariable Long deviceId){
QueryWrapper<DeviceCollect> queryWrapper = new QueryWrapper<>();
UserDTO userDTO = (UserDTO) SecurityUtils.getSubject().getPrincipal();
QueryWrapper<DeviceCollect> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("DEVICE_ID", deviceId);
queryWrapper.eq("USER_ID", userDTO.getId());
return deviceCollectService.remove(queryWrapper) ? Result.success() : Result.error();
boolean collected = true;
long count = deviceCollectService.count(queryWrapper);
if (count < 1) {
DeviceCollect deviceCollect = new DeviceCollect();
deviceCollect.setDeviceId(deviceId);
deviceCollect.setUserId(userDTO.getId());
DeviceInfo deviceInfo = deviceService.getById(deviceId);
deviceCollect.setPrisonName(deviceInfo.getPrisonName());
deviceCollect.setDeviceName(deviceInfo.getName());
deviceCollect.setGbid(deviceInfo.getGbId());
deviceCollectService.save(deviceCollect);
} else {
boolean remove = deviceCollectService.remove(queryWrapper);
if (remove) {
collected = false;
}
}
return Result.success().data(collected ? 1 : 0);
}
}
package com.ces.web.collect.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.NoArgsConstructor;
......@@ -15,7 +16,15 @@ public class DeviceCollect {
private Long deviceId;
private String deviceName;
@TableField("GB_ID")
private String gbid;
private String prisonName;
private String userId;
private Integer sort;
}
......@@ -100,13 +100,14 @@ public class DeviceController {
Map<String, String> resultMap = new HashMap<>(gbIdArray.length);
for (String gbId : gbIdArray) {
QueryWrapper queryWrapper = new QueryWrapper("gbid,status");
/*QueryWrapper queryWrapper = new QueryWrapper("gbid,status");
queryWrapper.eq("gbid", gbId);
List<DeviceDTO> deviceByExt = deviceQueryService.getDeviceByExt(queryWrapper);
if (ObjectUtils.isNotEmpty(deviceByExt)) {
DeviceDTO device = deviceByExt.get(0);
resultMap.put(device.getGbid(), device.getStatus());
}
}*/
resultMap.put(gbId, "0");
}
return Result.success(resultMap);
......
......@@ -84,4 +84,10 @@ public class DeviceInfo {
*/
@TableField("BASE_AREA")
private String baseArea;
/**
* 是否已收藏
*/
@TableField(exist = false)
private boolean collected;
}
package com.ces.web.device.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ces.common.core.domain.Result;
import com.ces.framework.shiro.dto.UserDTO;
import com.ces.web.collect.entity.DeviceCollect;
import com.ces.web.collect.service.IDeviceCollectService;
import com.ces.web.device.entity.DeviceInfo;
import com.ces.web.device.mapper.DeviceMapper;
import com.ces.web.device.service.IDeviceService;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
......@@ -16,6 +22,9 @@ import java.util.Map;
@Service
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, DeviceInfo> implements IDeviceService {
@Autowired
private IDeviceCollectService deviceCollectService;
/**
* 获取所有监狱名称
*/
......@@ -78,6 +87,17 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, DeviceInfo> imp
List<DeviceInfo> deviceInfoList = getBaseMapper().getDeviceListByDevice(deviceInfo);
for (DeviceInfo device : deviceInfoList) {
UserDTO userDTO = (UserDTO) SecurityUtils.getSubject().getPrincipal();
QueryWrapper<DeviceCollect> collectQueryWrapper = new QueryWrapper<>();
collectQueryWrapper.eq("DEVICE_ID", device.getId());
collectQueryWrapper.eq("USER_ID", userDTO.getId());
long count = deviceCollectService.count(collectQueryWrapper);
device.setCollected(count > 0);
}
return Result.success(deviceInfoList);
}
......
......@@ -30,15 +30,29 @@
<link rel="stylesheet" type="text/css" href="${ctx}/static/css/commonArea.css"/>
<link rel="stylesheet" type="text/css" href="${ctx}/static/css/leader.css" />
<link rel="stylesheet" type="text/css" href="${ctx}/static/css/layer.css" />
<link rel="stylesheet" type="text/css" href="${ctx}/static/css/main.css" />
<link rel="stylesheet" type="text/css" href="${ctx}/static/css/css/iconfont.css" />
<script src="${ctx}/static/js/scroll.js"></script>
<div class="logout">
<a href="javascript:;">退出登录</a>
<div class="toolbar">
<a href="javascript:;" class="collect">我的收藏</a>
<a href="javascript:;" class="logout">退出登录</a>
</div>
<div id="collect-modal" class="my-modal">
<div class="dialog-layout">
<div class="dialog-box">
<div class="dialog-content">
<div class="title">我的收藏</div>
<iframe allowtransparency="true" id="collectIframe" style="width: 100%; height: 600px;background-color: transparent"></iframe>
</div>
</div>
</div>
</div>
<script>
$(function () {
$(".logout a").click(function () {
$(".toolbar a.logout").click(function () {
layer.confirm('是否确定退出登录?', {
title: '提示信息',
btn: ['确定','取消']
......@@ -49,22 +63,41 @@
});
})
})
$('.toolbar a.collect').click(function(event) {
$("#collectIframe").attr('src', '${ctx}/deviceCollect/index');
$("#collect-modal").fadeIn();
});
$("#collect-modal").click(function (event) {
if ($(event.target).closest('.dialog-box').length) {
} else {
$("#collect-modal").fadeOut();
}
})
/* $(".toolbar .collect").click(function () {
var $modal = $('#collectModal');
$modal.modal("show");
})*/
</script>
<style>
.logout{
.toolbar{
position: fixed;
top: 25px;
right: 30px;
}
.logout a{
.toolbar a{
margin-right: 15px;
color: #fff!important;
font-size: 16px;
text-decoration: none;
}
.logout a:hover{
.toolbar a:hover{
color: #fff!important;
}
.layui-layer-dialog .layui-layer-content{
.layui-layer-dialog .layui-layer-content, .layui-layer-dialog .layui-layer-title{
color: #333!important;
}
.layui-layer-btn a{
......
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<jsp:include page="../base.jsp"/>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="${ctx}/static/css/floorcommon.css"/>
......@@ -167,9 +168,14 @@
</div>
</div>
</div>
<script>
</script>
</body>
</html>
<style>
.flex-box {
display: block;
}
......
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
request.setAttribute("ctx", request.getContextPath());
%>
<html>
<head>
<title>我的收藏</title>
<script src="${ctx}/static/js/jquery-1.8.1.min.js" type=text/javascript></script>
<script src="${ctx}/static/js/popper.min.js"></script>
<link rel="stylesheet" type="text/css" href="${ctx}/static/css/bootstrap.min.css">
<script src="${ctx}/static/js/bootstrap.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-table@1.23.5/dist/bootstrap-table.min.css">
<!-- Latest compiled and minified JavaScript -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.23.5/dist/bootstrap-table.min.js"></script>
<!-- Latest compiled and minified Locales -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap-table@1.23.5/dist/locale/bootstrap-table-zh-CN.min.js"></script>
<link rel="stylesheet" type="text/css" href="${ctx}/static/css/css/iconfont.css" />
<script src="${ctx}/static/js/kmedia-uni.js"></script>
<script>
let ctx = '${ctx}';
</script>
<style>
body{
color: #fff;
}
.page-main{
width: 100%;
display: flex;
}
.tableList{
padding: 10px;
width: 40%;
}
.videoBox{
flex: 1;
padding-top: 20px;
}
.bootstrap-table .fixed-table-container .table tfoot th .th-inner, .bootstrap-table .fixed-table-container .table thead th .th-inner {
padding: 8px;
}
.table-hover>tbody>tr:hover>* {
color: #dddddd;
}
table th, table td{
color: #fff;
}
table a{
cursor: pointer;
}
.select-list select {
border: none;
outline: none;
width: 100px;
height: 36px;
line-height: 36px;
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
padding: 0px 12px;
background-color: #103AA5;
color: #ffffff;
font-size: 16px;
border-radius: 6px;
}
.select-list ul{
margin: 0;
padding: 0;
}
.select-list ul li {
list-style-type: none;
display: inline;
}
.bootstrap-table .fixed-table-container .fixed-table-body {
overflow: auto;
height: 90%;
}
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading{
background: transparent;
}
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .loading-text{
font-size: 16px !important;
color: #fff;
}
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-dot,
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::after,
.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::before{
background: #fff;
}
</style>
</head>
<body style="background-color: transparent;">
<div class="page-main">
<div class="tableList">
<form id="collect-form">
<div class="select-list">
<ul>
<li>
监狱:<select name="prisonName">
<option value="">所有</option>
<option value="沪-五">五角场</option>
<option value="沪-周">周浦</option>
<option value="沪-南">南汇</option>
<option value="沪-总">总医院</option>
<option value="沪-新">新收犯</option>
<option value="沪-青">青浦</option>
<option value="沪-北">北新泾</option>
<option value="沪-女">女子</option>
<option value="沪-未">未管所</option>
<option value="沪-宝">宝山</option>
</select>
</li>
<li>
摄像头名称:<input type="text" name="deviceName" placeholder="请输入摄像头名称"/>
</li>
<li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="tableSearch()"><i class="fa fa-search"></i>&nbsp;搜索</a>
</li>
</ul>
</div>
</form>
<table id="collectTable" class="table table-hover"></table>
</div>
<div class="videoBox">
<p id="cameraName" style="text-align: center"></p>
<div id="video" style="height: 450px">
</div>
</div>
</div>
<script>
$(function () {
loadList();
$(".fixed-table-toolbar").remove();
})
function loadList() {
$('#collectTable').bootstrapTable({
url: ctx + '/deviceCollect/list', //请求后台的URL(*)
method: 'get', //请求方式(*)
contentType: "application/x-www-form-urlencoded",//需要设置为这个参数,后台才能通过对象获取值,这里要注意
dataType: "json",//期待返回数据类型
toolbar: '#toolbar', //工具按钮用哪个容器
toolbarAlign: "left",//工具栏对齐方式
striped: true, //是否显示行间隔色
cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
pagination: true, //是否显示分页(*)
// sortable: false, //是否启用排序
sidePagination: "server", //分页方式:client客户端分页,server服务端分页(*)
pageNumber: 1, //初始化加载第一页,默认第一页
pageSize: 10, //每页的记录行数(*)
pageList: [10], //可供选择的每页的行数(*)
sortOrder: "asc", //排序方式
search: false,//搜索功能
buttonsAlign: "left",//按钮对齐方式
//showColumns: true,//列选择按钮
strictSearch: true,
clickToSelect: true, //是否启用点击选中行
//height: 460, //行高,如果没有设置height属性,表格自动根据记录条数觉得表格高度
cardView: false, //是否显示详细视图
detailView: false, //是否显示父子表
queryParamsType: 'limit',
columns: [
{
field: 'prisonName',
title: '监狱名称',
align: 'center'
},
{
field: 'deviceName',
title: '摄像头名称',
width: '350',
align: 'center',
formatter: function (value, row, index) {
return '<a onclick="showVideo(\'' + row.gbid + '\', \'' + row.deviceName + '\')">' + row.deviceName + '</a>';
}
},
{
title: '操作',
align: 'center',
formatter: function (value, row, index) {
return '<a onclick="removeCollect(\'' + row.deviceId + '\')">移除</a>';
}
}
],
queryParams: queryParams
});
}
function tableSearch() {
$('#collectTable').bootstrapTable('refresh');
}
$('#collectTable').on('load-success.bs.table', function (e, data) {
// data.rows是加载成功后的数据集合数组
var firstRow = data.rows[0];
if (firstRow) {
$("#cameraName").html(firstRow.deviceName + '监控点情况');
player.play(firstRow.gbid);
}
});
function queryParams(params) {
return $.extend(formToJSON('collect-form'), {
pageNo : Math.ceil(params.offset/params.limit) + 1, //页码
pageSize : params.limit, //页面大小
})
}
function showVideo(gbid, deviceName) {
$("#cameraName").html(deviceName + '监控点情况');
player.play(gbid);
}
function removeCollect(deviceId) {
$.ajax({
url: ctx + '/deviceCollect/' +deviceId,
type: 'post',
dataType: 'json',
success: function (res) {
if (res.success) {
$('#collectTable').bootstrapTable('refresh');
} else {
layer.msg('系统异常,请稍后再试~');
}
}
})
}
let player = {
wsUrl: parent.wsUrl,
obj: null,
play: function (gbId) {
if (this.obj === null) {
this.init();
return;
}
let _this = this;
this.obj.loadVideo({
src: {
websocketUrl: _this.wsUrl,
devId: gbId
},
transport: KMediaUni.MODE.WEBRTC,
autoplay: true
});
},
init: function () {
// 初始化播放器
this.obj = new KMediaUni({
selector: '#video',
loading: true,
showMessage: true,
request: {
silentConnection: true,
},
control: {
hideControlsBar: false,
tools: Object.values(KMediaUni.TOOLS)
}
});
}
}
// 获取form下所有的字段并转换为json对象
function formToJSON(formId) {
var json = {};
$.each($("#" + formId).serializeArray(), function(i, field) {
if (json[field.name]) {
json[field.name] += ("," + field.value);
} else {
json[field.name] = field.value;
}
});
return json;
}
</script>
</body>
</html>
@font-face {
font-family: "iconfont"; /* Project id 4775591 */
src: url('iconfont.woff2?t=1733743602615') format('woff2'),
url('iconfont.woff?t=1733743602615') format('woff'),
url('iconfont.ttf?t=1733743602615') format('truetype');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-collected:before {
content: "\e62a";
}
.icon-collect:before {
content: "\e613";
}
#videos li{
position: relative;
}
#videos li i{
position: absolute;
left: -20px;
top: 3px;
color: #fff;
font-size: 20px;
}
#collect-modal{
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.15);
z-index: 99999998;
}
#collect-modal .dialog-layout{
margin: 0 auto;
display: flex;
width: 90% !important;
max-width: 1600px;
height: 100%;
align-items: center;
}
#collect-modal .dialog-box {
/*margin: 50px auto;*/
/*height: 68vh;*/
max-height: 700px;
/* 防止重复平铺 */
width: 100% !important;
max-width: 1600px;
background-image: url(../images/tc_bj.png);
background-size: cover;
background-repeat: no-repeat;
/* background-color: #00254d00; */
border: none;
background-color: transparent;
z-index: 99999999;
}
#collect-modal .dialog-box .dialog-content {
padding: 15px;
}
#collect-modal .dialog-box .dialog-content .title{
text-align: center;
line-height: 35px;
margin-top: 15px;
font-size: 26px;
}
iframe {
border: none;
}
\ No newline at end of file
......@@ -4,7 +4,7 @@ var loadedDom = false;
let asyLock = false;
let wsUrl = 'ws://172.100.100.21:32101';
var wsUrl = 'ws://172.100.100.21:32101';
let dom_temp = '<div class="modal fade" id="cameraModal" tabindex="-1" role="dialog" aria-labelledby="cameraModalLabel"\n' +
' aria-hidden="true">\n' +
......@@ -229,7 +229,11 @@ var VideoPlayer = {
let textColor = '#eee';
if (obj.gbId === _this.gbid) textColor = '#00e5ff'
if (window.deviceStatus[obj.gbId] !== '0') textColor = 'red'
html += '<li data-gbid="' + obj.gbId + '" title="' + title + '"><img src="'+ctx+'/static/images/sp_icon.png"><span style="color: ' + textColor + '">' + name + '</span></li>';
// 收藏图标
let collect_icon = '<i title="' + (obj.collected ? '取消收藏' : '收藏') + '" data-id = "' + obj.id + '" class="collect iconfont ' + (obj.collected ? 'icon-collected' : 'icon-collect') + '"></i>';
html += '<li data-gbid="' + obj.gbId + '" title="' + title + '"><img src="'+ctx+'/static/images/sp_icon.png"><span style="color: ' + textColor + '">' + name + '</span> ' + collect_icon + '</li>';
}
})
$("#videos").append(html);
......@@ -702,4 +706,33 @@ function handleClick (i) {
}
let gbId = datas['arr' + currIndex][i].gbid;
VideoPlayer.show(gbId);
}
\ No newline at end of file
}
$(document).on('click', '.collect', function (event) {
event.stopPropagation();
let deviceId = $(this).data('id');
let $this = $(this);
if (!deviceId) {
return;
}
$.ajax({
url: ctx + '/deviceCollect/' +deviceId,
type: 'post',
dataType: 'json',
success: function (res) {
if (res.success) {
if (res.data) {
$this.removeClass('icon-collect').addClass('icon-collected');
$this.attr("title", "取消收藏");
} else {
$this.removeClass('icon-collected').addClass('icon-collect');
$this.attr("title", "收藏");
}
} else {
layer.msg('系统异常,请稍后再试~');
}
}
})
})
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment