DeviceWarning.html 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. <!DOCTYPE html>
  2. <html class="x-admin-sm">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="renderer" content="webkit">
  6. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  7. <meta name="viewport"
  8. content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi"/>
  9. <link rel="shortcut icon" href="https://osscold.baozhida.cn/favicon.ico">
  10. <link rel="bookmark" href="https://osscold.baozhida.cn/favicon.ico">
  11. <link rel="stylesheet" href="https://osscold.baozhida.cn/css/font.css">
  12. <link rel="stylesheet" href="https://osscold.baozhida.cn/css/xadmin.css">
  13. <script src="https://osscold.baozhida.cn/lib/layui/layui.js" charset="utf-8"></script>
  14. <script type="text/javascript" src="https://osscold.baozhida.cn/js/xadmin.js"></script>
  15. </head>
  16. <body>
  17. <div class="x-nav">
  18. <span class="layui-breadcrumb">
  19. <a href="">首页</a>
  20. <a><cite>宝智达</cite></a>
  21. </span>
  22. <a class="layui-btn layui-btn-normal" style="line-height:1.6em;margin-top:3px;float:right"
  23. onclick="location.reload()" title="刷新">
  24. <i class="layui-icon layui-icon-refresh" style="line-height:30px"></i>
  25. </a>
  26. </div>
  27. <div class="layui-fluid">
  28. <div class="layui-row layui-col-space15">
  29. <div class="layui-col-md12">
  30. <div class="layui-card">
  31. <div class="layui-card-body ">
  32. <form class="layui-form layui-col-space5">
  33. <div class="layui-inline layui-show-xs-block">
  34. <input class="layui-input" autocomplete="off" placeholder="开始日" name="Time_start"
  35. id="Time_start" lay-key="1"></div>
  36. <div class="layui-inline layui-show-xs-block">
  37. <input class="layui-input" autocomplete="off" placeholder="截止日" name="Time_end"
  38. id="Time_end" lay-key="2"></div>
  39. <div class="layui-input-inline layui-show-xs-block">
  40. <input value="{{.T_sn}}" type="text" name="T_sn" style="width: 200px"
  41. placeholder="请输入 Sn (支持模糊搜索)" autocomplete="off" class="layui-input"></div>
  42. <div class="layui-input-inline layui-show-xs-block">
  43. <button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="sreach">
  44. <i class="layui-icon">&#xe615;</i></button>
  45. </div>
  46. <button type="button" style="float: right" class="layui-btn layui-btn-normal layui-btn-xs"
  47. onclick="xadmin.open('添加','/Device/DeviceWarning_',400,450)"><i class="layui-icon">&#xe61f;</i>添加报警
  48. </button>
  49. </form>
  50. </div>
  51. <div class="layui-card-body ">
  52. <table class="layui-table layui-form">
  53. <thead>
  54. <tr>
  55. <th>选择</th>
  56. <th>报警类型</th>
  57. <th>主机</th>
  58. <th>设备</th>
  59. <th>采集内容</th>
  60. <th>状态</th>
  61. <th>采集时间</th>
  62. <th>操作</th>
  63. </tr>
  64. </thead>
  65. <tbody>
  66. {{range $index, $elem := .List}}
  67. <tr {{if eq $elem.T_State 0 }} style="background-color: rgba(0,0,0,0.26)" {{end}}>
  68. <td><input type="checkbox" class="layui-checkbox" name="checkbox" lay-skin="primary"
  69. value="{{$elem.Id}}"></td>
  70. <td type="text" name="T_tp_name">{{$elem.T_tp_name}}
  71. </td>
  72. <td name="t__d_name,t_sn" sn="{{$elem.T_sn}}">{{$elem.T_D_name}},{{$elem.T_sn}}</td>
  73. <td name="t__d_s_name,t_id" t_id="{{$elem.T_id}}">{{$elem.T_DS_name}},{{$elem.T_id}}</td>
  74. <td name="t__remark">{{$elem.T_Remark}}</td>
  75. <td name="t__state">
  76. {{if eq $elem.T_State 1}}
  77. 不处理
  78. {{else if eq $elem.T_State 2}}
  79. 已处理
  80. {{else if eq $elem.T_State 3}}
  81. 未处理
  82. {{else}}
  83. 删除
  84. {{end}}
  85. </td>
  86. <td name="t__ut">{{$elem.T_Ut}}</td>
  87. <td>
  88. <button class="layui-btn-danger layui-btn layui-btn-xs"
  89. onclick="member_del(this,'{{$elem.Id}}','{{$elem.T_Ut}}')" href="javascript:;">
  90. <i class="layui-icon">&#xe640;</i>删除
  91. </button>
  92. <button class="layui-btn-normal layui-btn layui-btn-xs copy-add-btn" id="copy-add-btn"
  93. data-id="{{$elem.Id}},{{$elem.T_Ut}}" >复制添加
  94. </button>
  95. </td>
  96. </tr>
  97. {{end}}
  98. </tbody>
  99. <div class="layui-form layui-border-box layui-row layui-col-space10 layui-form-item">
  100. <button class="layui-btn layui-btn-sm" id="selectAll">全选</button>
  101. <button class="layui-btn layui-btn-sm" id="unselectAll">全不选</button>
  102. <button class="layui-btn layui-btn-sm" id="invertSelect">反选</button>
  103. <button class="layui-btn layui-btn-sm layui-btn-danger" id="batchDelete">批量删除</button>
  104. </div>
  105. </table>
  106. </div>
  107. <div class="layui-card-body ">
  108. <select id="pageSizeSelector">
  109. <option value="100">100 条/页</option>
  110. <option value="200">200 条/页</option>
  111. <option value="500">500 条/页</option>
  112. <option value="1000">1000 条/页</option>
  113. </select>
  114. <div class="page">
  115. <div>
  116. {{range $index, $elem := .Pages}}
  117. {{if eq $elem.A 1}}
  118. <a class="prev" href="?page={{$elem.V}}&T_sn={{$.T_sn}}&Time_start={{$.Time_start}}&Time_end={{$.Time_end}}">&lt;&lt;</a>
  119. {{end}}
  120. {{if eq $elem.A 2}}
  121. <a class="num" href="?page={{$elem.V}}&T_sn={{$.T_sn}}&Time_start={{$.Time_start}}&Time_end={{$.Time_end}}">{{$elem.V}}</a>
  122. {{end}}
  123. {{if eq $elem.A 3}}
  124. <span class="current">{{$elem.V}}</span>
  125. {{end}}
  126. {{if eq $elem.A 4}}
  127. <a class="num" href="?page={{$elem.V}}&T_sn={{$.T_sn}}&Time_start={{$.Time_start}}&Time_end={{$.Time_end}}">{{$elem.V}}</a>
  128. {{end}}
  129. {{if eq $elem.A 5}}
  130. <a class="next" href="?page={{$elem.V}}&T_sn={{$.T_sn}}&Time_start={{$.Time_start}}&Time_end={{$.Time_end}}">&gt;&gt;</a>
  131. {{end}}
  132. {{end}}
  133. </div>
  134. 当前页:{{.Page}}-
  135. 总页数:{{.Page_size}}-
  136. 总条数:{{.cnt}}
  137. </div>
  138. </div>
  139. </div>
  140. </div>
  141. </div>
  142. </div>
  143. </body>
  144. <script>
  145. document.addEventListener('DOMContentLoaded', function() {
  146. // 初始化pageSize,先从localStorage读取,如果没有则使用默认值
  147. var pageSize = localStorage.getItem('pageSize') || 10;
  148. document.getElementById('pageSizeSelector').value = pageSize; // 设置选择框的默认选中项
  149. // 监听选择框变化
  150. document.getElementById('pageSizeSelector').addEventListener('change', function(event) {
  151. var newPageSize = event.target.value;
  152. localStorage.setItem('pageSize', newPageSize); // 更新localStorage中的pageSize
  153. // 调用函数更新分页链接
  154. updatePageLinks(newPageSize);
  155. sendPageSizeToBackend(newPageSize);
  156. });
  157. // 页面加载时执行一次,确保初始状态正确
  158. updatePageLinks(pageSize);
  159. });
  160. // 更新所有分页链接的函数
  161. function updatePageLinks(pageSize) {
  162. console.log("Updating page links with pageSize:", pageSize);
  163. var links = document.querySelectorAll('.num');
  164. for (var i = 0; i < links.length; i++) {
  165. var href = links[i].getAttribute('href');
  166. href = href.replace(/pageSize\s*=\s*\d+/, 'pageSize=' + encodeURIComponent(pageSize)); // 替换pageSize参数
  167. links[i].setAttribute('href', href+"&pageSize="+pageSize);
  168. // window.location.href = links[0].href;
  169. }
  170. console.log("Updated link:", links[0].href);
  171. }
  172. // 新增函数:向后端发送pageSize
  173. function sendPageSizeToBackend(pageSize) {
  174. fetch('/Device/DeviceWarning_page', { // 替换为你的后端接口地址
  175. method: 'POST', // 或者根据你的后端接口要求使用'PUT'、'PATCH'等
  176. headers: {
  177. 'Content-Type': 'application/json',
  178. },
  179. body: JSON.stringify({ pageSize: pageSize }), // 将pageSize作为JSON对象发送
  180. })
  181. .then(response => {
  182. console.log('Sending pageSize to the server:', response);
  183. if (!response.ok) {
  184. throw new Error(`Network response was not ok: ${response.statusText}`);
  185. }
  186. })
  187. }
  188. layui.use(['layer', 'laydate', 'form'],
  189. function () {
  190. var laydate = layui.laydate;
  191. var $ = layui.jquery,
  192. layer = layui.layer; //独立版的layer无需执行这一句
  193. $("#selectAll").on("click", function () {
  194. $(":checkbox[name='checkbox']").prop("checked", true);
  195. $(".layui-form-checkbox").addClass("layui-form-checked"); // 通过类名设置全选
  196. // form.render('checkbox'); // 渲染以显示变化
  197. });
  198. $("#unselectAll").on("click", function () {
  199. $(":checkbox[name='checkbox']").prop("checked", false);
  200. $(".layui-form-checkbox").removeClass("layui-form-checked"); // 通过类名设置全不选
  201. // form.render('checkbox');
  202. });
  203. $("#invertSelect").on("click", function () {
  204. $(":checkbox[name='checkbox']").each(function () {
  205. this.checked = !this.checked; // 切换每个复选框的选中状态
  206. });
  207. $(".layui-form-checkbox").each(function () {
  208. if ($(this).hasClass("layui-form-checked")) {
  209. $(this).removeClass("layui-form-checked");
  210. } else {
  211. $(this).addClass("layui-form-checked");
  212. }
  213. });
  214. // form.render('checkbox'); // 渲染以显示变化
  215. });
  216. $("#batchDelete").on("click", function () {
  217. var selectedIds = [];
  218. $("input[name='checkbox']:checked").each(function () {
  219. var checkbox = $(this);
  220. // selectedIds.push(this.value); // 'this.value'直接获取当前选中复选框的值
  221. var row = checkbox.closest('tr');
  222. var seventhColumnValue = row.find('td:eq(6)').text();
  223. console.log(seventhColumnValue);
  224. // 现在您可以根据需要使用 seventhColumnValue,例如将其与ID一起存储
  225. selectedIds.push({
  226. id: this.value,
  227. ut: seventhColumnValue.trim() // 去除前后空白
  228. });
  229. });
  230. if (selectedIds.length === 0) {
  231. layer.msg('请至少选择一项进行删除!', {icon: 5, time: 2000});
  232. return;
  233. }
  234. console.log(selectedIds);
  235. layer.confirm('您确定要删除选定的 ' + selectedIds.length + ' 条数据吗?', {
  236. icon: 3,
  237. title: '确认删除',
  238. btn: ['确定', '取消']
  239. }, function (index) {
  240. layer.close(index);
  241. $.ajax({
  242. type: "POST",
  243. url: "/Device/DeviceWarning_dels",
  244. data: JSON.stringify({selectedIds}),
  245. contentType: "application/json;charset=utf-8",
  246. dataType: "json",
  247. success: function (response) {
  248. if (response.Code === 200) {
  249. layer.msg('删除成功! 已删除 ' + selectedIds.length + ' 条数据', {icon: 1, time: 2000});
  250. // location.reload();
  251. } else {
  252. layer.msg('删除失败,请重试!', {icon: 5, time: 2000});
  253. }
  254. },
  255. error: function (xhr, status, error) {
  256. console.error("Error occurred: " + error);
  257. layer.msg('请求错误,请检查网络连接!', {icon: 5, time: 2000});
  258. }
  259. });
  260. }, function () {
  261. layer.msg('已取消删除操作', {icon: 1, time: 1000});
  262. });
  263. });
  264. // 绑定复制添加按钮的点击事件
  265. $('body').on('click', '.copy-add-btn', function(){
  266. var btn = $(this);
  267. var row = btn.parents('tr'); // 获取当前按钮所在行
  268. var checkbox = row.find('input[type="checkbox"]'); // 找到本行的复选框
  269. var rowId = checkbox.val(); // 获取当前行的ID(即复选框的value)
  270. var sn = row.find('td[sn]');
  271. var attr = sn.attr('sn');
  272. var t_id = row.find('td[t_id]');
  273. var t_idV = t_id.attr('t_id');
  274. console.log(attr);
  275. // 复制当前行并在其下方插入
  276. var newRow = row.clone(true);
  277. newRow.insertAfter(row);
  278. // 改变复制行的背景色
  279. newRow.css("background-color", "#07c5ea"); // 示例颜色,您可以自定义
  280. // 提取数据并准备发送到后端的逻辑,排除第一列(ID列)和最后一列的按钮
  281. var rowData = {
  282. rowId: rowId,
  283. sn: attr,
  284. t_id: t_idV
  285. };
  286. newRow.find("td:not(:first):not(:last)").each(function(index, cell){
  287. // 假设除了第一列和最后一列外,其他列的数据都需要提交
  288. rowData[`column${index + 1}`] = $(cell).text().trim(); // 动态生成键名以避免覆盖
  289. });
  290. // 发送POST请求到后端
  291. $.ajax({
  292. type: "POST",
  293. url: "/Device/DeviceWarningAdd", // 替换为您的后端接口地址
  294. data: JSON.stringify(rowData),
  295. contentType: "application/json;charset=utf-8",
  296. dataType: "json",
  297. success: function(response){
  298. if(response.Code === 200){
  299. layer.msg('复制并添加成功!', {icon: 1, time: 2000});
  300. } else {
  301. layer.msg('添加失败,请重试!', {icon: 5, time: 2000});
  302. newRow.remove(); // 如果后端返回失败,移除新行
  303. }
  304. },
  305. error: function(xhr, status, error){
  306. layer.msg('请求错误,请检查网络连接!', {icon: 5, time: 2000});
  307. newRow.remove(); // 发生错误时移除新行
  308. }
  309. });
  310. });
  311. // 绑定所有可编辑列的双击事件
  312. $('tbody').on('dblclick', 'td:not(:last-child)', function(e){ // 排除最后一列的按钮
  313. var cell = $(this);
  314. var row = cell.closest('tr'); // 获取当前行
  315. var checkbox = row.find('input[type="checkbox"]'); // 找到本行的复选框
  316. var rowId = checkbox.val(); // 获取当前行的ID(即复选框的value)
  317. var columnName = cell.attr('name'); // 获取当前列的名称
  318. var originalText = cell.text().trim(); // 保存原始文本内容
  319. var T_Ut_cell = row.find('td[name="t__ut"]');
  320. var T_Ut_value = T_Ut_cell.text().trim();
  321. // 检查是否是第一列或第五列
  322. if (columnName === 'T_tp_name' || columnName === 't__state') {
  323. cell.html('<select style="display:block;"></select>');
  324. var selectBox = cell.find('select');
  325. console.log(selectBox);
  326. // 调用方法动态填充下拉选项
  327. populateSelectOptions(selectBox, columnName);
  328. selectBox.val(originalText);
  329. selectBox.focus();
  330. selectBox.change(function() {
  331. var newValue = $(this).val();
  332. if (newValue !== '') {
  333. cell.html(newValue);
  334. submitUpdate(rowId, columnName, newValue,T_Ut_value);
  335. selectBox.off('change'); // 清理事件监听
  336. } else {
  337. cell.text(originalText);
  338. }
  339. });
  340. }else{
  341. // 将当前单元格内容替换为<input>元素
  342. cell.html('<input type="text" class="layui-input inline-edit-input" value="' + originalText + '">');
  343. // 自动聚焦到新创建的输入框
  344. cell.find('.inline-edit-input').focus();
  345. // 监听输入框的失焦事件,以便在用户完成编辑后保存更改
  346. cell.find('.inline-edit-input').blur(function(){
  347. var newValue = $(this).val().trim();
  348. if(newValue !== ''){ // 确保输入不为空
  349. cell.html(newValue); // 用新值替换输入框
  350. // 提交更改到后端,包含列名
  351. submitUpdate(rowId, columnName, newValue,T_Ut_value);
  352. } else {
  353. // 如果用户清空了输入框,则恢复原始内容
  354. cell.text(originalText);
  355. }
  356. });
  357. }
  358. });
  359. // 定义提交更新到后端的函数
  360. function submitUpdate(rowId, columnName, newValue,T_Ut_value) {
  361. var dataToSubmit = {
  362. rowId: rowId,
  363. columnName: columnName,
  364. newValue: newValue,
  365. T_Ut: T_Ut_value
  366. };
  367. // 发起POST请求到后端
  368. $.ajax({
  369. type: "POST",
  370. url: "/Device/DeviceWarningUpdate", // 替换为您的后端更新接口地址
  371. data: JSON.stringify(dataToSubmit),
  372. contentType: "application/json;charset=utf-8",
  373. dataType: "json",
  374. success: function(response){
  375. console.log(response);
  376. if(response.Code === 200){
  377. layer.msg('更新成功!', {icon: 1, time: 2000});
  378. // location.reload()
  379. } else {
  380. layer.msg('更新失败,请重试!', {icon: 5, time: 2000});
  381. }
  382. },
  383. error: function(xhr, status, error){
  384. layer.msg('请求错误,请检查网络连接!', {icon: 5, time: 2000});
  385. }
  386. });
  387. }
  388. function populateSelectOptions(selectBox, columnName) {
  389. // 这里只是一个示例逻辑,根据实际情况动态生成或从服务端获取选项
  390. switch(columnName) {
  391. case 'T_tp_name':
  392. fetch("/Device/DeviceWarning_waraning")
  393. .then(response => {
  394. if (!response.ok) {
  395. throw new Error('Network response was not ok');
  396. }
  397. return response.json(); // 假设后端返回的是JSON格式的数据
  398. })
  399. .then(data => {
  400. // const selectBox = document.getElementById('selectBox');
  401. console.log(data.Data);
  402. // 假设data是一个对象数组,每个对象有Key和Value属性
  403. data.Data.forEach(item => {
  404. console.log(item.Key);
  405. selectBox.append(`<option value='${item.Key}'>${item.Value}</option>`); });
  406. })
  407. .catch(error => {
  408. console.error('There has been a problem with your fetch operation:', error);
  409. });
  410. break;
  411. case 't__state':
  412. selectBox.append('<option value=0>删除</option>');
  413. selectBox.append('<option value=1>不处理</option>');
  414. selectBox.append('<option value=2>已处理</option>');
  415. selectBox.append('<option value=3>未处理</option>');
  416. break;
  417. default:
  418. // 万一其他列也需要处理,可以在这里扩展
  419. break;
  420. }
  421. }
  422. //执行一个laydate实例
  423. laydate.render({
  424. elem: '#Time_start', //指定元素
  425. value:{{.Time_start}}
  426. ,type: 'datetime'
  427. });
  428. //执行一个laydate实例
  429. laydate.render({
  430. elem: '#Time_end', //指定元素
  431. value:{{.Time_end}}
  432. ,type: 'datetime'
  433. });
  434. });
  435. /*用户-删除*/
  436. function member_del(obj, id, t_ut) {
  437. layer.confirm('确认要删除吗?',
  438. function (index) {
  439. //发异步删除数据
  440. $(obj).parents("tr").remove();
  441. $.ajax({
  442. type: 'POST',
  443. url: 'DeviceWarning_Del',//发送请求
  444. data: {Id: id, Ut: t_ut},
  445. success: function (result) {
  446. console.log(result)
  447. if (result.Code == 200) {
  448. layer.msg('已删除!', {
  449. icon: 1,
  450. time: 2000
  451. });
  452. window.location.reload();
  453. } else {
  454. layer.msg('删除失败!', {
  455. time: 2000
  456. });
  457. }
  458. }
  459. });
  460. });
  461. }
  462. </script>
  463. </html>