DeviceWarning.html 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  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="10">10 条/页</option>
  110. <option value="20">20 条/页</option>
  111. <option value="50">50 条/页</option>
  112. <option value="100">100 条/页</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. }
  169. }
  170. // 新增函数:向后端发送pageSize
  171. function sendPageSizeToBackend(pageSize) {
  172. fetch('/Device/DeviceWarning_page', { // 替换为你的后端接口地址
  173. method: 'POST', // 或者根据你的后端接口要求使用'PUT'、'PATCH'等
  174. headers: {
  175. 'Content-Type': 'application/json',
  176. },
  177. body: JSON.stringify({ pageSize: pageSize }), // 将pageSize作为JSON对象发送
  178. })
  179. .then(response => {
  180. console.log('Sending pageSize to the server:', response);
  181. if (!response.ok) {
  182. throw new Error(`Network response was not ok: ${response.statusText}`);
  183. }
  184. })
  185. }
  186. layui.use(['layer', 'laydate', 'form'],
  187. function () {
  188. var laydate = layui.laydate;
  189. var $ = layui.jquery,
  190. layer = layui.layer; //独立版的layer无需执行这一句
  191. $("#selectAll").on("click", function () {
  192. $(":checkbox[name='checkbox']").prop("checked", true);
  193. $(".layui-form-checkbox").addClass("layui-form-checked"); // 通过类名设置全选
  194. // form.render('checkbox'); // 渲染以显示变化
  195. });
  196. $("#unselectAll").on("click", function () {
  197. $(":checkbox[name='checkbox']").prop("checked", false);
  198. $(".layui-form-checkbox").removeClass("layui-form-checked"); // 通过类名设置全不选
  199. // form.render('checkbox');
  200. });
  201. $("#invertSelect").on("click", function () {
  202. $(":checkbox[name='checkbox']").each(function () {
  203. this.checked = !this.checked; // 切换每个复选框的选中状态
  204. });
  205. $(".layui-form-checkbox").each(function () {
  206. if ($(this).hasClass("layui-form-checked")) {
  207. $(this).removeClass("layui-form-checked");
  208. } else {
  209. $(this).addClass("layui-form-checked");
  210. }
  211. });
  212. // form.render('checkbox'); // 渲染以显示变化
  213. });
  214. $("#batchDelete").on("click", function () {
  215. var selectedIds = [];
  216. $("input[name='checkbox']:checked").each(function () {
  217. var checkbox = $(this);
  218. // selectedIds.push(this.value); // 'this.value'直接获取当前选中复选框的值
  219. var row = checkbox.closest('tr');
  220. var seventhColumnValue = row.find('td:eq(6)').text();
  221. console.log(seventhColumnValue);
  222. // 现在您可以根据需要使用 seventhColumnValue,例如将其与ID一起存储
  223. selectedIds.push({
  224. id: this.value,
  225. ut: seventhColumnValue.trim() // 去除前后空白
  226. });
  227. });
  228. if (selectedIds.length === 0) {
  229. layer.msg('请至少选择一项进行删除!', {icon: 5, time: 2000});
  230. return;
  231. }
  232. console.log(selectedIds);
  233. layer.confirm('您确定要删除选定的 ' + selectedIds.length + ' 条数据吗?', {
  234. icon: 3,
  235. title: '确认删除',
  236. btn: ['确定', '取消']
  237. }, function (index) {
  238. layer.close(index);
  239. $.ajax({
  240. type: "POST",
  241. url: "/Device/DeviceWarning_dels",
  242. data: JSON.stringify({selectedIds}),
  243. contentType: "application/json;charset=utf-8",
  244. dataType: "json",
  245. success: function (response) {
  246. if (response.Code === 200) {
  247. layer.msg('删除成功! 已删除 ' + selectedIds.length + ' 条数据', {icon: 1, time: 2000});
  248. // location.reload();
  249. } else {
  250. layer.msg('删除失败,请重试!', {icon: 5, time: 2000});
  251. }
  252. },
  253. error: function (xhr, status, error) {
  254. console.error("Error occurred: " + error);
  255. layer.msg('请求错误,请检查网络连接!', {icon: 5, time: 2000});
  256. }
  257. });
  258. }, function () {
  259. layer.msg('已取消删除操作', {icon: 1, time: 1000});
  260. });
  261. });
  262. // 绑定复制添加按钮的点击事件
  263. $('body').on('click', '.copy-add-btn', function(){
  264. var btn = $(this);
  265. var row = btn.parents('tr'); // 获取当前按钮所在行
  266. var checkbox = row.find('input[type="checkbox"]'); // 找到本行的复选框
  267. var rowId = checkbox.val(); // 获取当前行的ID(即复选框的value)
  268. var sn = row.find('td[sn]');
  269. var attr = sn.attr('sn');
  270. var t_id = row.find('td[t_id]');
  271. var t_idV = t_id.attr('t_id');
  272. console.log(attr);
  273. // 复制当前行并在其下方插入
  274. var newRow = row.clone(true);
  275. newRow.insertAfter(row);
  276. // 改变复制行的背景色
  277. newRow.css("background-color", "#07c5ea"); // 示例颜色,您可以自定义
  278. // 提取数据并准备发送到后端的逻辑,排除第一列(ID列)和最后一列的按钮
  279. var rowData = {
  280. rowId: rowId,
  281. sn: attr,
  282. t_id: t_idV
  283. };
  284. newRow.find("td:not(:first):not(:last)").each(function(index, cell){
  285. // 假设除了第一列和最后一列外,其他列的数据都需要提交
  286. rowData[`column${index + 1}`] = $(cell).text().trim(); // 动态生成键名以避免覆盖
  287. });
  288. // 发送POST请求到后端
  289. $.ajax({
  290. type: "POST",
  291. url: "/Device/DeviceWarningAdd", // 替换为您的后端接口地址
  292. data: JSON.stringify(rowData),
  293. contentType: "application/json;charset=utf-8",
  294. dataType: "json",
  295. success: function(response){
  296. if(response.Code === 200){
  297. layer.msg('复制并添加成功!', {icon: 1, time: 2000});
  298. } else {
  299. layer.msg('添加失败,请重试!', {icon: 5, time: 2000});
  300. newRow.remove(); // 如果后端返回失败,移除新行
  301. }
  302. },
  303. error: function(xhr, status, error){
  304. layer.msg('请求错误,请检查网络连接!', {icon: 5, time: 2000});
  305. newRow.remove(); // 发生错误时移除新行
  306. }
  307. });
  308. });
  309. // 绑定所有可编辑列的双击事件
  310. $('tbody').on('dblclick', 'td:not(:last-child)', function(e){ // 排除最后一列的按钮
  311. var cell = $(this);
  312. var row = cell.closest('tr'); // 获取当前行
  313. var checkbox = row.find('input[type="checkbox"]'); // 找到本行的复选框
  314. var rowId = checkbox.val(); // 获取当前行的ID(即复选框的value)
  315. var columnName = cell.attr('name'); // 获取当前列的名称
  316. var originalText = cell.text().trim(); // 保存原始文本内容
  317. var T_Ut_cell = row.find('td[name="t__ut"]');
  318. var T_Ut_value = T_Ut_cell.text().trim();
  319. // 检查是否是第一列或第五列
  320. if (columnName === 'T_tp_name' || columnName === 't__state') {
  321. cell.html('<select style="display:block;"></select>');
  322. var selectBox = cell.find('select');
  323. console.log(selectBox);
  324. // 调用方法动态填充下拉选项
  325. populateSelectOptions(selectBox, columnName);
  326. selectBox.val(originalText);
  327. selectBox.focus();
  328. selectBox.change(function() {
  329. var newValue = $(this).val();
  330. if (newValue !== '') {
  331. cell.html(newValue);
  332. submitUpdate(rowId, columnName, newValue,T_Ut_value);
  333. selectBox.off('change'); // 清理事件监听
  334. } else {
  335. cell.text(originalText);
  336. }
  337. });
  338. }else{
  339. // 将当前单元格内容替换为<input>元素
  340. cell.html('<input type="text" class="layui-input inline-edit-input" value="' + originalText + '">');
  341. // 自动聚焦到新创建的输入框
  342. cell.find('.inline-edit-input').focus();
  343. // 监听输入框的失焦事件,以便在用户完成编辑后保存更改
  344. cell.find('.inline-edit-input').blur(function(){
  345. var newValue = $(this).val().trim();
  346. if(newValue !== ''){ // 确保输入不为空
  347. cell.html(newValue); // 用新值替换输入框
  348. // 提交更改到后端,包含列名
  349. submitUpdate(rowId, columnName, newValue,T_Ut_value);
  350. } else {
  351. // 如果用户清空了输入框,则恢复原始内容
  352. cell.text(originalText);
  353. }
  354. });
  355. }
  356. });
  357. // 定义提交更新到后端的函数
  358. function submitUpdate(rowId, columnName, newValue,T_Ut_value) {
  359. var dataToSubmit = {
  360. rowId: rowId,
  361. columnName: columnName,
  362. newValue: newValue,
  363. T_Ut: T_Ut_value
  364. };
  365. // 发起POST请求到后端
  366. $.ajax({
  367. type: "POST",
  368. url: "/Device/DeviceWarningUpdate", // 替换为您的后端更新接口地址
  369. data: JSON.stringify(dataToSubmit),
  370. contentType: "application/json;charset=utf-8",
  371. dataType: "json",
  372. success: function(response){
  373. console.log(response);
  374. if(response.Code === 200){
  375. layer.msg('更新成功!', {icon: 1, time: 2000});
  376. location.reload()
  377. } else {
  378. layer.msg('更新失败,请重试!', {icon: 5, time: 2000});
  379. }
  380. },
  381. error: function(xhr, status, error){
  382. layer.msg('请求错误,请检查网络连接!', {icon: 5, time: 2000});
  383. }
  384. });
  385. }
  386. function populateSelectOptions(selectBox, columnName) {
  387. // 这里只是一个示例逻辑,根据实际情况动态生成或从服务端获取选项
  388. switch(columnName) {
  389. case 'T_tp_name':
  390. fetch("/Device/DeviceWarning_waraning")
  391. .then(response => {
  392. if (!response.ok) {
  393. throw new Error('Network response was not ok');
  394. }
  395. return response.json(); // 假设后端返回的是JSON格式的数据
  396. })
  397. .then(data => {
  398. // const selectBox = document.getElementById('selectBox');
  399. console.log(data.Data);
  400. // 假设data是一个对象数组,每个对象有Key和Value属性
  401. data.Data.forEach(item => {
  402. console.log(item.Key);
  403. selectBox.append(`<option value='${item.Key}'>${item.Value}</option>`); });
  404. })
  405. .catch(error => {
  406. console.error('There has been a problem with your fetch operation:', error);
  407. });
  408. break;
  409. case 't__state':
  410. selectBox.append('<option value=0>删除</option>');
  411. selectBox.append('<option value=1>不处理</option>');
  412. selectBox.append('<option value=2>已处理</option>');
  413. selectBox.append('<option value=3>未处理</option>');
  414. break;
  415. default:
  416. // 万一其他列也需要处理,可以在这里扩展
  417. break;
  418. }
  419. }
  420. //执行一个laydate实例
  421. laydate.render({
  422. elem: '#Time_start', //指定元素
  423. value:{{.Time_start}}
  424. ,type: 'datetime'
  425. });
  426. //执行一个laydate实例
  427. laydate.render({
  428. elem: '#Time_end', //指定元素
  429. value:{{.Time_end}}
  430. ,type: 'datetime'
  431. });
  432. });
  433. /*用户-删除*/
  434. function member_del(obj, id, t_ut) {
  435. layer.confirm('确认要删除吗?',
  436. function (index) {
  437. //发异步删除数据
  438. $(obj).parents("tr").remove();
  439. $.ajax({
  440. type: 'POST',
  441. url: 'DeviceWarning_Del',//发送请求
  442. data: {Id: id, Ut: t_ut},
  443. success: function (result) {
  444. console.log(result)
  445. if (result.Code == 200) {
  446. layer.msg('已删除!', {
  447. icon: 1,
  448. time: 2000
  449. });
  450. window.location.reload();
  451. } else {
  452. layer.msg('删除失败!', {
  453. time: 2000
  454. });
  455. }
  456. }
  457. });
  458. });
  459. }
  460. </script>
  461. </html>