Index.cshtml 14.4 KB
@using HHECS.DAQWebClient.ViewModel
@using HHECS.DAQShared.Common.Enums
@model EquipmentPropQueryModel
@{
    Layout = null;
    var propTypes = Enum.GetValues(typeof(EquipmentPropType)).Cast<EquipmentPropType>().Select(x => new SelectListItem
    {
        Value = ((int)x).ToString(),
        Text = x.ToString()
    }).ToList();
    var isAdmin = User.IsInRole(nameof(RoleType.Admin));
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>设备属性 - DataAcquisition</title>
    <environment include="Development">
        <link href="~/lib/layui/css/layui.css" rel="stylesheet" asp-append-version="true" />
    </environment>
    <environment exclude="Development">
        <link href="~/lib/layui/css/layui.min.css" rel="stylesheet" asp-append-version="true" />
    </environment>
</head>
<body>
    <div class="layui-card">
        <div class="layui-card-body">
            <form class="layui-form layui-form-pane" id="form-val-filter" lay-filter="form-val-filter">
                <div class="layui-inline">
                    <label class="layui-form-label">属性编号</label>
                    <div class="layui-input-inline">
                        <input type="text" asp-for="Code" placeholder="" class="layui-input">
                    </div>
                </div>
                <div class="layui-inline">
                    <label class="layui-form-label">属性名称</label>
                    <div class="layui-input-inline">
                        <input type="text" asp-for="Name" placeholder="" class="layui-input">
                    </div>
                </div>
                <div class="layui-inline">
                    <label class="layui-form-label">属性类型</label>
                    <div class="layui-input-inline">
                        <select asp-for="PropType" asp-items="propTypes">
                            <option value="" selected>全部</option>
                        </select>
                    </div>
                </div>
            </form>
        </div>
    </div>
    <div class="layui-panel">
        <table class="layui-hide" id="equipmentPropTable" lay-filter="equipmentPropTable"></table>
    </div>

    <div id="ID-layer-addOrEdit" style="display: none; padding: 15px;">
        <partial name="AddOrEdit" />
    </div>

    <script type="text/html" id="toolbarDemo">
        <div class="layui-btn-container">
            <button class="layui-btn layui-btn-sm" lay-event="search">
                <i class="layui-icon layui-icon-search"></i>
                查询
            </button>
            <button class="layui-btn layui-btn-sm layui-btn-primary" lay-event="refresh">
                <i class="layui-icon layui-icon-refresh"></i>
                重置
            </button>
            <button class="layui-btn layui-btn-sm layui-btn-normal @(isAdmin?"":"layui-hide")" lay-event="add">
                <i class="layui-icon layui-icon-add-1"></i>
                新增
            </button>
            <button class="layui-btn layui-btn-sm layui-btn-danger @(isAdmin?"":"layui-hide")" lay-event="batchDelete">
                <i class="layui-icon layui-icon-delete"></i>
                批量删除
            </button>
        </div>
    </script>
    <partial name="_DateTimeFormatPartial" />
    <script type="text/html" id="toolDemo">
        <div class="layui-clear-space">
            <a class="layui-btn layui-btn-xs layui-btn-warm" lay-event="edit"><i class="layui-icon layui-icon-edit"></i>编辑</a>
            <a class="layui-btn layui-btn-xs layui-btn-danger" lay-event="delete"><i class="layui-icon layui-icon-delete"></i>删除</a>
        </div>
    </script>
    <script type="text/html" id="propTypeTemp">
        @foreach (var item in Enum.GetValues<EquipmentPropType>())
        {
            <span>
                {{#  if(d.propType == @((int)item)){  }}
                @item.ToString()
                {{#  } }}
            </span>
        }
    </script>
    <script type="text/html" id="dataTypeTemp">
        @foreach (var item in Enum.GetValues<EquipmentDataType>())
        {
            <span>
                {{#  if(d.dataType == @((int)item)){  }}
                @item.ToString()
                {{#  } }}
            </span>
        }
    </script>

    <environment include="Development">
        <script src="~/lib/layui/layui.js"></script>
        <script src="~/lib/microsoft-signalr/signalr.js"></script>
    </environment>
    <environment exclude="Development">
        <script src="~/lib/layui/layui.min.js"></script>
        <script src="~/lib/microsoft-signalr/signalr.min.js"></script>
    </environment>
    <script type="text/javascript" asp-append-version="true">
        layui.use(['table', 'form'], function () {
            let table = layui.table;
            let form = layui.form;
            let $ = layui.$;

            let intervalId = null;
            const equipmentId = @Model.EquipmentId;

            let connection = new signalR.HubConnectionBuilder()
                .withUrl('/DAQHub')
                .withAutomaticReconnect()
                .build();

            // 创建渲染实例
            table.render({
                elem: '#equipmentPropTable',
                url: 'Load', // 此处为静态模拟数据,实际使用时需换成真实接口
                toolbar: '#toolbarDemo',
                defaultToolbar: ['filter', 'exports', 'print'],
                height: 'full-75', // 最大高度减去其他容器已占有的高度差
                cellMinWidth: 80,
                page: true,
                cols: [[
                    //{ type: 'checkbox', fixed: 'left' },
                    { field: 'id', fixed: 'left', title: 'ID', hide: true },
                    { field: 'code', fixed: 'left', width: 240, title: '设备编号' },
                    { field: 'name', width: 180, title: '设备名称' },
                    { field: 'propType', width: 160, title: '属性类型', templet:'#propTypeTemp' },
                    { field: 'dataType', width: 100, title: '数据类型', templet:'#dataTypeTemp' },
                    { field: 'address', width: 120, title: '地址' },
                    { field: 'value', width: 80, title: '值' },
                    { field: 'monitorCompareValue', width: 80, title: '比较值' },
                    { field: 'monitorNormal', width: 180, title: '正常输出', hide: true },
                    { field: 'monitorFailure', width: 180, title: '异常输出' },
                    { field: 'remark', minWidth: 180, title: '备注' },
                    { field: 'createdBy', title: '创建人', hide: true },
                    { field: 'created', width: 160, title: '创建时间', templet: '#toolCreated' },
                    { field: 'updatedBy', title: '更新人', hide: true },
                    { field: 'updated', width: 160, title: '更新时间', templet: '#toolUpdated' },
                    { fixed: 'right', title: '操作', width: 140,@(isAdmin?"": "hide:true,") templet: '#toolDemo' }
                ]],
                before: function (options) {
                    options.where.equipmentId = equipmentId;
                },
                complete: function (res, curr, count, origin) {
                    if (intervalId != null) {
                        clearInterval(intervalId);
                    }
                    reloadValue();
                },
                error: function (res, msg) {
                    console.log(res, msg)
                }
            });

            // 工具栏事件
            table.on('toolbar(equipmentPropTable)', function (obj) {
                var id = obj.config.id;
                var checkStatus = table.checkStatus(id);
                var othis = lay(this);
                switch (obj.event) {
                    case 'search':
                        search();
                        break;
                    case 'refresh':
                        refresh();
                        break;
                    case 'add':
                        add();
                        break;
                    case 'batchDelete':
                        batchDelete(checkStatus.data);
                        break;
                };
            });

            // 触发单元格工具事件
            table.on('tool(equipmentPropTable)', function (obj) {
                let data = obj.data; // 获得当前行数据
                if (obj.event === 'edit') {
                    edit(data);
                } else if (obj.event === 'delete') {
                    batchDelete([data]);
                }
            })

            connection.start().then(function () {
                console.log('connection started');
            }).catch(error => {
                layer.msg(error.message, { icon: 2 });
                console.error(error.message);
            });

            function search() {
                let data = form.val('form-val-filter');
                console.log(data);
                table.reloadData('equipmentPropTable', {
                    where: data,
                    scrollPos: true,
                });
            }

            function refresh() {
                $("#form-val-filter")[0].reset();
                table.reloadData('equipmentPropTable', {
                    where: {},
                });
            }

            function add() {
                form.val('form-addOrEdit-filter', { equipmentId: equipmentId });
                layer.open({
                    title: '新增',
                    type: 1,
                    area: ['600px', '80%'],
                    content: $('#ID-layer-addOrEdit'),
                    btn: ['保存', '取消'],
                    yes: function (index, layero, that) {
                        var isValid = form.validate('#form-addOrEdit-filter')
                        if (!isValid) {
                            return false;
                        }
                        let data = form.val('form-addOrEdit-filter');
                        $.post('Add', data).done(function (result) {
                            if (result.code === 0) {
                                table.reloadData('equipmentPropTable');
                                layer.msg(result.msg, { icon: 1 });
                                layer.close(index);
                            } else {
                                layer.msg(result.msg, { icon: 2 });
                            }
                        }).fail(function (xhr, status, error) {
                            layer.msg(`操作失败,状态码${xhr.status}${error}`, { icon: 2 });
                        })
                        return false;
                    },
                    end: function () {
                        //关闭后的回调
                        $("#form-addOrEdit-filter")[0].reset();
                    }
                });
            }

            function edit(data) {
                form.val('form-addOrEdit-filter', data);
                layer.open({
                    title: '编辑 - id:' + data.id,
                    type: 1,
                    area: ['600px', '80%'],
                    content: $('#ID-layer-addOrEdit'),
                    btn: ['保存', '取消'],
                    yes: function (index, layero, that) {
                        var isValid = form.validate('#form-addOrEdit-filter')
                        if (!isValid) {
                            return false;
                        }
                        let data = form.val('form-addOrEdit-filter');
                        $.post('Update', data).done(function (result) {
                            if (result.code === 0) {
                                table.reloadData('equipmentPropTable');
                                layer.msg(result.msg, { icon: 1 });
                                layer.close(index); // 关闭弹层
                            } else {
                                layer.msg(result.msg, { icon: 2 });
                            }
                        }).fail(function (xhr, status, error) {
                            layer.msg(`操作失败,状态码${xhr.status}${error}`, { icon: 2 });
                        })
                        return false;
                    },
                    end: function () {
                        //关闭后的回调
                        $("#form-addOrEdit-filter")[0].reset();
                    }
                });
            }

            function batchDelete(data) {
                layer.confirm('确定删除?', { icon: 3 }, function () {
                    let ids = data.map(x => x.id);
                    $.post('Delete', { ids: ids }).done(function (result) {
                        if (result.code === 0) {
                            table.reloadData('equipmentPropTable');
                            layer.msg(result.msg, { icon: 1 });
                        } else {
                            layer.msg(result.msg, { icon: 2 });
                        }
                    }).fail(function (xhr, status, error) {
                        layer.msg(`操作失败,状态码${xhr.status}${error}`, { icon: 2 });
                    })
                });
            }

            function reloadValue() {
               intervalId = setInterval(function () {
                    if (connection.state != 'Connected') {
                        return;
                    }
                    let cacheData = table.cache['equipmentPropTable'];
                    let ids = cacheData.map(x => x.id);
                    connection.invoke("getEquipmentProps", ids).then(function (result) {
                        if (result.code != 200) {
                            layer.msg(result.msg, { icon: 2 });
                            return;
                        }
                        for (var i = 0; i < cacheData.length; i++) {
                            let item = cacheData[i];
                            let element = result.data.find(x => x.id == item.id);
                            if (element != undefined) {
                                item.value = element.value;
                                item.updated = element.updated
                            }
                        }
                        table.renderData('equipmentPropTable');
                    }).catch(function (err) {
                        layer.msg(err.toString(), { icon: 2 });
                    })
                }, 1000);
            }
        });
    </script>
</body>
</html>