Skip to content
main.js 25.7 KiB
Newer Older
beilang's avatar
beilang committed
var player;

var loadedDom = false;

beilang's avatar
beilang committed
let asyLock = false;

beilang's avatar
beilang committed

let dom_temp = '<div class="modal fade" id="cameraModal" tabindex="-1" role="dialog" aria-labelledby="cameraModalLabel"\n' +
    '     aria-hidden="true">\n' +
    '    <div class="modal-dialog" role="document">\n' +
    '        <div class="modal-content">\n' +
    '            <div class="title"></div>\n' +
beilang's avatar
beilang committed
    '<div class="tools" style="display: none">\n' +
beilang's avatar
beilang committed
    '        <div class="timeSelect">\n' +
    '            <div class="time-box">\n' +
    '                开始时间: <input type="text" id="startTime" placeholder="请选择开始时间"/>\n' +
    '            </div>\n' +
    '            <div class="time-box">\n' +
    '                结束时间: <input type="text" id="endTime" placeholder="请选择结束时间"/>\n' +
    '            </div>\n' +
beilang's avatar
beilang committed
    '            <button type="button" class="btn btn-primary" id="ishf">确定</button>\n' +
    '<button type="button" class="btn btn-primary" style="display: none" id="isLive">实时播放</button>' +
beilang's avatar
beilang committed
    '        </div>\n' +
    '    </div>' +
beilang's avatar
beilang committed
    '            <div class="modal-body">\n' +
    '                <div style="width:15%;">\n' +
    '                    <ul id="videos"></ul>\n' +
    '                </div>\n' +
    '                <div style="flex: 1;" id="cameraVideo">\n' +
    '                    <div id="video" style="height: 550px"></div>\n' +
    '                </div>\n' +
    '            </div>\n' +
    '        </div>\n' +
    '    </div>\n' +
    '</div>';

var VideoPlayer = {
beilang's avatar
beilang committed
    loadIndex: '',
beilang's avatar
beilang committed
    gbid: '',
beilang's avatar
beilang committed
    initDom: function () {
        if (!loadedDom) {
beilang's avatar
beilang committed
            // 加载必须的文件
            let script = document.createElement('script');
            script.src = ctx + '/static/js/bootstrap.min.js';
            $(document).find("body").append(script);

            let css1 = document.createElement('link');
            css1.rel = 'stylesheet';
            css1.href = ctx + '/static/css/bootstrap.min.css'
            $(document).find("body").append(css1);

            let css2 = document.createElement('link');
            css2.rel = 'stylesheet';
            css2.href = ctx + '/static/css/modal.css'
            $(document).find("body").append(css2);

beilang's avatar
beilang committed
            let datetimecss = document.createElement('link');
            datetimecss.rel = 'stylesheet';
            datetimecss.href = ctx + '/static/libs/datetimepicker/css/bootstrap-datetimepicker.min.css'
            $(document).find("body").append(datetimecss);

            let datetimejs = document.createElement('script');
            datetimejs.src = ctx + '/static/libs/datetimepicker/js/bootstrap-datetimepicker.min.js';
            $(document).find("body").append(datetimejs);

            let datetimecnjs = document.createElement('script');
            datetimecnjs.src = ctx + '/static/libs/datetimepicker/js/bootstrap-datetimepicker.zh-CN.js';
            $(document).find("body").append(datetimecnjs);

beilang's avatar
beilang committed
            $(document).find('body').append(dom_temp);
            loadedDom = true;
        }
    },
beilang's avatar
beilang committed
    eventRegister: function () {
        $("#startTime").datetimepicker({
            language: 'zh-CN',
            weekStart: 1,
            todayBtn: 1,
            autoclose: true,
            todayHighlight: 1,
            startView: 2,
            minView: 0,
            maxView: 4,
            forceParse: true,
            format: 'yyyy-mm-dd hh:ii:ss'
        }).on('show', function (event) {
            event.preventDefault();
            event.stopPropagation();
            $('.datetimepicker .prev').html('<')
            $('.datetimepicker .next').html('>')
        })

        $("#endTime").datetimepicker({
            language: 'zh-CN',
            weekStart: 1,
            todayBtn: 1,
            autoclose: true,
            todayHighlight: 1,
            startView: 2,
            minView: 0,
            maxView: 4,
            forceParse: true,
            format: 'yyyy-mm-dd hh:ii:ss'
        }).on('show', function (event) {
            event.preventDefault();
            event.stopPropagation();
            $('.datetimepicker .prev').html('<')
            $('.datetimepicker .next').html('>')
        })

        $(".dropdown-menu").css({'--bs-dropdown-min-width': 0})
    },
beilang's avatar
beilang committed
    initModal: function (data) {
beilang's avatar
beilang committed
        this.gbid = data.curr.gbId;
beilang's avatar
beilang committed
        var $modal = $('#cameraModal');

beilang's avatar
beilang committed
        $('.modal-content .title').html(data.curr.place + '监控点情况 <button type="button" class="btn btn-primary btn-sm" id="payerhf">加载回放</button>');
beilang's avatar
beilang committed
        // 假设每个摄像头的视频源可能不同,可以设置为动态获取

        this.renderList(data.list);

        // 隐藏模态框的关闭按钮和右上角的关闭按钮
        // $modal.find('.close').hide();
        $modal.modal({backdrop: 'static', keyboard: false});

        // 显示模态框
        $modal.modal('show');

        if (!player) {
            this.initPlayer();
        }
        this.play(data.curr.gbId);
beilang's avatar
beilang committed
        asyLock = false;
beilang's avatar
beilang committed
    },
    initPlayer: function () {
        // 初始化播放器
        player = new KMediaUni({
            selector: '#video',
            loading: true,
            showMessage: true,
            request: {
                silentConnection: true,
            },
            control: {
                hideControlsBar: false,
                tools: Object.values(KMediaUni.TOOLS)
                // tools: ['play']
            }
        });
    },
    play: function (gbId) {
        player.loadVideo({
            src: {
                websocketUrl: wsUrl,
                devId: gbId
            },
            transport: KMediaUni.MODE.WEBRTC,
            autoplay: true
        });
    },
    show: function (gbId) {
beilang's avatar
beilang committed
        this.loadIndex = layer.load(1, {
            shade: [0.1,'#fff'] //0.1透明度的白色背景
        });
        if (!gbId) {
            layer.msg('缺少必填参数[gbid]');
            layer.close(this.loadIndex)
            return;
        }
beilang's avatar
beilang committed
        this.gbid = gbId;
beilang's avatar
beilang committed
        $('#isLive').hide();
beilang's avatar
beilang committed
        if (asyLock) {
beilang's avatar
beilang committed
            layer.close(this.loadIndex)
beilang's avatar
beilang committed
            return;
        }
        this.exec('loadVideo');
        asyLock = true;
beilang's avatar
beilang committed
        this.getDeviceInfo(gbId);

    },
    getDeviceInfo: function (gbId) {
        let _this = this;
        $.ajax({
            async: false,
            url: ctx + '/device/getDeviceListByGbId',
            data: {gbId: gbId},
            dataType: 'json',
            success: function (res) {
                if (res.success && res.data && res.data.length > 0) {
                    _this.initDom();
beilang's avatar
beilang committed
                    _this.eventRegister();
beilang's avatar
beilang committed
                    _this.initModal(_this.dataHandle(res, gbId));
beilang's avatar
beilang committed
                    layer.close(_this.loadIndex);
beilang's avatar
beilang committed
                    return;
                }
beilang's avatar
beilang committed
                layer.close(_this.loadIndex);
                layer.msg('未获取到此设备信息');
beilang's avatar
beilang committed
            }
        })
    },
    renderList: function (data) {
        $("#videos").empty();
beilang's avatar
beilang committed
        let _this = this;
beilang's avatar
beilang committed
        let html = '';
beilang's avatar
beilang committed
        let gbIds = '';
beilang's avatar
beilang committed
        $.each(data, function (i, obj) {
beilang's avatar
beilang committed
            gbIds += obj.gbId + ',';
beilang's avatar
beilang committed
            let name = obj.place + (obj.deviceNo ? '-' + obj.deviceNo : '');
            let title = name;
            if (name.length > 6) {
                let splitArray = name.split('-');
                if (splitArray.length === 2) {
                    if (splitArray[0].length <= 4 && splitArray[1].length <=2) {
                        name = splitArray[0] + '-' + splitArray[1];
                    } else {
                        if (splitArray[0].length >= 5) {
                            name = name.substring(0, 5) + '...';
                        } else {
                            name = name.substring(0, 6) + '...';
                        }
                    }
                } else {
                    name = name.substring(0, 5) + '...';
                }
            }
beilang's avatar
beilang committed

            if (window.deviceStatus[obj.gbId] === '0') {
                let textColor = '#eee';
                if (obj.gbId === _this.gbid) textColor = '#00e5ff'
                if (window.deviceStatus[obj.gbId] !== '0') textColor = 'red'

                // 收藏图标
                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>';
beilang's avatar
beilang committed
            }
beilang's avatar
beilang committed
        })
        $("#videos").append(html);
beilang's avatar
beilang committed
        // _this.getListStatus(gbIds);
beilang's avatar
beilang committed
    },
    getListStatus: function (gbIds) {
      $.ajax({
          url: ctx + '/device/getListStatus',
          data: {gbIds: gbIds},
          dataType: 'json',
          success: function (res) {
              if (res.success && res.data) {
                  $("#videos li").each(function (i, ele) {
                      let gbId = $(this).data('gbid');
beilang's avatar
beilang committed
                      if (window.deviceStatus[gbId] !== '0') {
beilang's avatar
beilang committed
                          $(this).find("span").css({'color': 'red'});
                      }
                  })
              }
          }
      })
beilang's avatar
beilang committed
    },
    dataHandle: function (res, gbId) {
        let dataList = res.data;
        let data = {}
        $.each(dataList, function (i, obj) {
            if (obj.gbId === gbId) data.curr = obj;
        })
        data.list = dataList;
        return data;
beilang's avatar
beilang committed
    },
    exec: function (cmd, ...args) {
        if (player && player[cmd]) {
            player[cmd](...args);
        }
beilang's avatar
beilang committed
    },
    loadVideo: function () {
        let gbId = this.gbid;
        let startTime = $('#startTime').val();
        let endTime = $('#endTime').val();

beilang's avatar
beilang committed
        if (!startTime || !endTime) {
beilang's avatar
beilang committed
            layer.msg('请填写回放开始时间和结束时间');
beilang's avatar
beilang committed
            return;
        }
beilang's avatar
beilang committed
        if (gbId) {
            player.loadVideo({
                src: {
                    websocketUrl: wsUrl,
                    devId: gbId,
                    startTime: startTime,
                    endTime: endTime
                },
                transport: KMediaUni.MODE.WEBRTC,
                autoplay: true
            });
beilang's avatar
beilang committed
            $("#isLive").show();
beilang's avatar
beilang committed
            return;
        }
beilang's avatar
beilang committed
        layer.msg('未找到播放源');
beilang's avatar
beilang committed
    },
beilang's avatar
beilang committed
}

beilang's avatar
beilang committed
let toolsShow = false;

beilang's avatar
beilang committed
$(document).on('click', function (e) {
    if ($(e.target).hasClass('modal')) {
beilang's avatar
beilang committed
        // 时间清空
        $('#startTime').val('');
        $('#endTime').val('');
beilang's avatar
beilang committed
        $('.tools').hide();
        toolsShow = false;
        $('#cameraModal').modal('hide');
beilang's avatar
beilang committed
    }
})

$(document).on('click', '.modal-content li', function () {
beilang's avatar
beilang committed
    let gbId = $(this).data('gbid');
beilang's avatar
beilang committed
    $("#isLive").hide();
beilang's avatar
beilang committed
    VideoPlayer.show(gbId);
beilang's avatar
beilang committed
})
beilang's avatar
beilang committed

$(document).on('click', '#payerhf', function () {
beilang's avatar
beilang committed
    if (toolsShow) {
        $('.tools').hide();
        toolsShow = false;
    } else {
        $('.tools').show();
        toolsShow = true;
    }
})

$(document).on('click', '#ishf', function () {
beilang's avatar
beilang committed
    //加载回放
    VideoPlayer.loadVideo();
beilang's avatar
beilang committed
})

$(document).on('click', '#isLive', function () {
    if (VideoPlayer.gbid) {
        VideoPlayer.show(VideoPlayer.gbid);
    }
beilang's avatar
beilang committed
})

let currIndex = 1;
let datas = [];

function DeviceRender(data, bgSrc, variable, suffix) {

    datas = data;

    this.dataList = data;
    this.bgSrc = bgSrc;
    this.variable = variable || false;
    this.suffix = suffix || '.png';

    let _this = this;

    this.init = function () {
        this.deviceInit(function () {
            // 1、点击上面的li,当前点击的li添加current类,其余兄弟移除类
            $(".tab_list li").click(function () {
                // 链式编程  当前li添加类,其余兄弟移除类
                $(this).addClass('current').siblings().removeClass('current');
                // 2、拿到当前点击的索引号
                let index = $(this).index();
                // 3、下面index对应的模块显示,其余的item隐藏
                $(".tab_con .item").eq(index).show().siblings().hide();
                _this.updateData(index + 1);
            })

            _this.updateData(1);
        })
    }

beilang's avatar
beilang committed
    this.initDeviceCount = function () {
        let keys = Object.keys(this.dataList);

        for (let i = 0; i < keys.length; i++) {
            let y = 0;
            let n = 0;
            let gbids = Array.from(this.dataList[keys[i]], ({gbid})=> gbid)

            $.each(gbids, function(index, value) {
                let status = window.deviceStatus[value];
                if (status === '0') {
                    y ++;
                } else {
                    n ++;
                }
            });

            $(".tab_list ul li").eq(i).find(".monitor").children().eq(0).html(n)
            let yCount = $(`<span style="background-color: #43e04e;">${y}</span>`);
            $(".tab_list ul li").eq(i).find(".monitor").children().eq(0).before(yCount)
        }
    }

beilang's avatar
beilang committed
    this.deviceInit = function (resolve) {
        let loadIndex = layer.load(1, {
            shade: [0.1,'#fff'] //0.1透明度的白色背景
        });

        let gbidArray = [];
        let keys = Object.keys(this.dataList);

        for (let key of keys) {
            let gbids = Array.from(this.dataList[key], ({gbid})=> gbid)
            gbidArray = gbidArray.concat(gbids)
        }

        $.ajax({
            url: ctx + '/device/getListStatus',
            data: {gbIds: gbidArray.join(',')},
            dataType: 'json',
            success: function (res) {
                layer.close(loadIndex)
                if (res.success && res.data) {
                    window.deviceStatus = res.data;
beilang's avatar
beilang committed
                    _this.initDeviceCount();
beilang's avatar
beilang committed
                }
                if (typeof resolve === 'function') {
                    resolve();
                }
            }
        })
    }

    this.updateData = function (index) {
        currIndex = index;
        //循环数组 打摄像头位置
        let divElement = document.querySelector('.room_box');

        let htmlTxt = '<img class="bg_img" src="' + ctx + (this.variable ? this.bgSrc + index + this.suffix : this.bgSrc) + '" alt="">'

        for (let i = 0; i < this.dataList[`arr${index}`].length; i++) {

            let gbid = this.dataList[`arr${index}`][i].gbid;
            let status = window.deviceStatus[gbid];
            this.dataList[`arr${index}`][i].status = status;
            let icon = ctx + '/static/images/' + (status === '0' ? 'camera_ok.png' : 'camera_no.png')

            htmlTxt = htmlTxt + '<img class="camera" src="' + icon + '" ' + ' style="top:' + this.dataList[`arr${index}`][i].top + ";left:" + this.dataList[`arr${index}`][i].left + '" onclick="handleClick(' + i + ')"></img>'
        }
        divElement.innerHTML = htmlTxt;
    }
}

beilang's avatar
beilang committed
let initTable = false;
let initLayer = false;

function PersonRender(prisonName, areaName) {

    this.init = function () {

        let _this = this;

        $.ajax({
            url: ctx + '/convict/getPersonList',
            type: 'post',
            data: {
                jyId: prisonName,
                jqId: areaName
            },
            dataType: 'json',
            success: function (res) {
                if (res.success) {
                    if (!initTable) {
                        _this.initTableBox();
                    }
                    _this.renderList(res.data);
                }
            }
        })
    }

    this.initTableBox = function () {
        $(".menu_box").append('<div class="table-box">\n' +
            '                <div class="table-head">\n' +
            '                    <span>姓名</span><span>年龄</span><span>类别</span>\n' +
            '                </div>\n' +
            '                <div class="myscroll table-body">\n' +
            '                    <ul class="list">\n' +
            '                    </ul>\n' +
            '                </div>\n' +
            '            </div>');
    }

    this.renderList = function (list) {
        if (list && list.length > 0) {
            for (let i = 0; i < list.length; i++) {

                let id = list[i].id;
                let name = list[i].xm;
                let age = getAge(list[i].csRq);
                let type = list[i].aflb;

                $(".table-box ul").append('<li class="list-li" data-id="' + id + '"><div><span>' + name + '</span><span>' + age + '</span><span>' + type + '</span></div></li>');
            }

            this.registerEvent();
        } else {
            $(".table-box").hide();
        }
    }

    this.registerEvent = function () {

        let _this = this;

        $(".table-box").on('click', 'li.list-li', function () {
            let id = $(this).data('id');
            if (!initLayer) {
                _this.initFormLayer();
            }
            _this.getConvictInfo(id,function (data) {

                // 参数初始化
                data.age = getAge(data.csRq);
                if (data.xq && data.xq.indexOf('-') > 0) {
                    let xqFmt = '';
                    let xq = data.xq;
                    let ymr = xq.split('-');
                    let year = parseInt(ymr[0]);
                    let m = parseInt(ymr[1]);
                    if (year > 0) {
                        xqFmt += year + ''

                        if (m > 0) {
                            xqFmt += '' + m + '个月'
                        }
                    } else {
                        if (m > 0) {
                            xqFmt += m + '个月'
                        }
                    }

                    data.xq = xqFmt
                }

                if (data.xqQr) {
                    data.xqQr = data.xqQr.substring(0, 10);
                }
                if (data.xqZr) {
                    data.xqZr = data.xqZr.substring(0, 10);
                }
                if (data.rjRq) {
                    data.rjRq = data.rjRq.substring(0, 10);
                }
                if (data.drRq) {
                    data.drRq = data.drRq.substring(0, 10);
                }
                if (data.tsRq) {
                    data.tsRq = data.tsRq.substring(0, 10);
                }

                $.each(data, function (key, value) {

                    if (!value) {
                        value = '';
                    }

                    let $input = $("input[name=" + key + "]");
                    if ($input.length > 0) {
                        $input.val(value);
                    }
                })
                layerOpen();
            })
        })

        setTimeout(function () {
            $('.myscroll').myScroll({
                speed: 30, //数值越大,速度越慢
                rowHeight: $(".list-li")[0].offsetHeight //li的高度
            });
        }, 1000);
    }


    this.initFormLayer = function () {
        $('html body').append('<div class="layer-wrap">\n' +
            '    <div class="layer-mark" onclick="layerClose()"></div>\n' +
            '    <div class="layer-main">\n' +
            '        <div class="layer-head">\n' +
            '            <div class="layer-title">个人信息</div>\n' +
            '            <a class="layer-close" onclick="layerClose()"></a>\n' +
            '        </div>\n' +
            '        <form class="layui-form">\n' +
            '            <table>\n' +
            '                <tr>\n' +
            '                    <th style="width:0.9rem;">姓名</th>\n' +
            '                    <td><input type="text" name="xm"></td>\n' +
            '                    <th style="width:1rem;">国籍</th>\n' +
            '                    <td><input type="text" name="gj"></td>\n' +
            '                    <th style="width:1rem;">性别</th>\n' +
            '                    <td><input type="text" name="xb"></td>\n' +
            '                </tr>\n' +
            '                <tr>\n' +
            '                    <th>年龄</th>\n' +
            '                    <td><input type="text" name="age"></td>\n' +
            '                    <th>婚姻状况</th>\n' +
            '                    <td><input type="text" name="xyHy"></td>\n' +
            '                    <th>文化程度</th>\n' +
            '                    <td><input type="text" name="xyWh"></td>\n' +
            '                </tr>\n' +
            '                <tr>\n' +
            '                    <th>番号</th>\n' +
            '                    <td><input type="text" name="fh"></td>\n' +
            '                    <th>户籍地址</th>\n' +
            '                    <td><input type="text" name="hjdzDz"></td>\n' +
            '                    <th>身体状况</th>\n' +
            '                    <td><input type="text" name="stZk"></td>\n' +
            '                </tr>\n' +
            '                <tr>\n' +
            '                    <th>籍贯</th>\n' +
            '                    <td><input type="text" name="hjdzSsq"></td>\n' +
            '                    <th>证件类型</th>\n' +
            '                    <td><input type="text" name="zjLx"></td>\n' +
            '                    <th>证件号码</th>\n' +
            '                    <td><input type="text" name="zjHm"></td>\n' +
            '                </tr>\n' +
            '            </table>\n' +
            '            <div class="table-title"><span>刑期信息</span></div>\n' +
            '            <table>\n' +
            '                <tr>\n' +
            '                    <th style="width:0.9rem;">类别</th>\n' +
            '                    <td><input type="text" name="aflb"></td>\n' +
            '                    <th style="width:1rem;">罪名</th>\n' +
            '                    <td><input type="text" name="zm"></td>\n' +
            '                    <th style="width:1rem;">第一罪名</th>\n' +
            '                    <td><input type="text" name="dyZm"></td>\n' +
            '                </tr>\n' +
            '                <tr>\n' +
            '                    <th>刑期</th>\n' +
            '                    <td><input type="text" name="xq"></td>\n' +
            '                    <th>执行刑种</th>\n' +
            '                    <td><input type="text" name="zxXz"></td>\n' +
            '                    <th>收押类别</th>\n' +
            '                    <td><input type="text" name="syLb"></td>\n' +
            '                </tr>\n' +
            '                <tr>\n' +
            '                    <th>刑期起日</th>\n' +
            '                    <td><input type="text" name="xqQr"></td>\n' +
            '                    <th>刑期止日</th>\n' +
            '                    <td><input type="text" name="xqZr"></td>\n' +
            '                    <th>新收/常押</th>\n' +
            '                    <td><input type="text" name="xscy"></td>\n' +
            '                </tr>\n' +
            '                <tr>\n' +
            '                    <th>入监日期</th>\n' +
            '                    <td><input type="text" name="rjRq"></td>\n' +
            '                    <th>调入日期</th>\n' +
            '                    <td><input type="text" name="drRq"></td>\n' +
            '                    <th>投送日期</th>\n' +
            '                    <td><input type="text" name="tsRq"></td>\n' +
            '                </tr>\n' +
            '            </table>\n' +
            '        </form>\n' +
            '    </div>\n' +
            '</div>');
        $(".layui-form input").attr('readonly', 'readonly');
        initLayer = true;
    }

    this.getConvictInfo = function (id, resolve) {
        $.ajax({
            url: ctx + '/convict/getConvictById/' + id,
            dataType: 'json',
            success: function (res) {
                if (res.success) {
                    if (typeof resolve === 'function') {
                        resolve(res.data);
                    }
                } else {
                    layer.msg('系统异常,请稍后再试~');
                }
            }
        })
    }
    // let prisonNames = ['北新泾监狱', '五角场监狱', '南汇监狱', '宝山监狱', '青浦监狱'];
}

function layerOpen() {
    $(".layer-wrap").addClass("active");
}

function layerClose() {
    $(".layer-wrap").removeClass("active");
}

function getAge(birthday) {
    let currentYear = new Date().getFullYear();
    let calculationYear = new Date(birthday).getFullYear();
    const wholeTime = currentYear + birthday.substring(4);
    const calculationAge = currentYear - calculationYear;

    if (new Date().getTime() > new Date(wholeTime).getTime()) {
        return calculationAge;
    } else {
        return calculationAge - 1;
    }
}

beilang's avatar
beilang committed
function handleClick (i) {
    let status = datas['arr' + currIndex][i].status;

    if (status !== '0') {
        layer.msg('当前设备不在线!');
        return false;
    }
    let gbId = datas['arr' + currIndex][i].gbid;
    VideoPlayer.show(gbId);
}

$(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('系统异常,请稍后再试~');
            }
        }
    })
})