dict-management.html 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. <!DOCTYPE html>
  2. <html lang="zh-CN" class="iframe-content">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>字典管理 - 爱智农</title>
  7. <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css">
  8. <link rel="stylesheet" href="https://at.alicdn.com/t/font_3114978_qe0b39no76.css">
  9. <link rel="stylesheet" href="../assets/css/global.css">
  10. <style>
  11. body {
  12. font-family: "PingFang SC", "Microsoft YaHei", sans-serif;
  13. background-color: #f5f7f9;
  14. color: #333;
  15. margin: 0;
  16. padding: 0;
  17. height: auto;
  18. overflow-y: auto;
  19. overflow-x: hidden;
  20. min-height: 100%;
  21. }
  22. .page-container {
  23. padding: 20px;
  24. position: relative;
  25. min-height: 100vh;
  26. width: 100%;
  27. max-width: 100%;
  28. box-sizing: border-box;
  29. }
  30. </style>
  31. </head>
  32. <body>
  33. <div class="page-container responsive-container">
  34. <div class="flex justify-between items-center mb-6">
  35. <h1 class="text-2xl font-bold">字典管理</h1>
  36. <button class="btn btn-primary" id="addDictBtn">
  37. <i class="iconfont icon-plus btn-icon"></i>
  38. 新增字典
  39. </button>
  40. </div>
  41. <div class="card p-6 mb-6">
  42. <div class="flex flex-wrap gap-4">
  43. <div class="search-box flex-grow">
  44. <input type="text" class="input" placeholder="请输入字典名称/编码">
  45. <button class="btn btn-primary">
  46. <i class="iconfont icon-search btn-icon"></i>
  47. 搜索
  48. </button>
  49. <button class="btn btn-default">
  50. <i class="iconfont icon-reload btn-icon"></i>
  51. 重置
  52. </button>
  53. </div>
  54. <div class="flex gap-2">
  55. <select class="select">
  56. <option value="">所有状态</option>
  57. <option value="1">启用</option>
  58. <option value="0">禁用</option>
  59. </select>
  60. </div>
  61. </div>
  62. </div>
  63. <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
  64. <!-- 左侧字典类型列表 -->
  65. <div class="card">
  66. <div class="flex justify-between items-center border-b p-4">
  67. <h2 class="font-medium">字典类型</h2>
  68. </div>
  69. <div class="table-container">
  70. <div class="table-scroll-controls">
  71. <button class="table-scroll-btn table-scroll-left">
  72. <i class="iconfont icon-left"></i>
  73. </button>
  74. <button class="table-scroll-btn table-scroll-right">
  75. <i class="iconfont icon-right"></i>
  76. </button>
  77. </div> <table class="table-fixed-right table-fixed-right">
  78. <thead>
  79. <tr>
  80. <th>字典名称</th>
  81. <th>字典编码</th>
  82. <th class="min-w-[80px]">状态</th>
  83. </tr>
  84. </thead>
  85. <tbody>
  86. <tr class="dict-type-row active" data-id="1">
  87. <td>用户性别</td>
  88. <td>sys_user_sex</td>
  89. <td><span class="badge badge-success">启用</span></td>
  90. </tr>
  91. <tr class="dict-type-row" data-id="2">
  92. <td>菜单状态</td>
  93. <td>sys_menu_status</td>
  94. <td><span class="badge badge-success">启用</span></td>
  95. </tr>
  96. <tr class="dict-type-row" data-id="3">
  97. <td>系统开关</td>
  98. <td>sys_normal_disable</td>
  99. <td><span class="badge badge-success">启用</span></td>
  100. </tr>
  101. <tr class="dict-type-row" data-id="4">
  102. <td>任务状态</td>
  103. <td>sys_job_status</td>
  104. <td><span class="badge badge-success">启用</span></td>
  105. </tr>
  106. <tr class="dict-type-row" data-id="5">
  107. <td>任务分组</td>
  108. <td>sys_job_group</td>
  109. <td><span class="badge badge-success">启用</span></td>
  110. </tr>
  111. <tr class="dict-type-row" data-id="6">
  112. <td>通知类型</td>
  113. <td>sys_notice_type</td>
  114. <td><span class="badge badge-success">启用</span></td>
  115. </tr>
  116. <tr class="dict-type-row" data-id="7">
  117. <td>通知状态</td>
  118. <td>sys_notice_status</td>
  119. <td><span class="badge badge-success">启用</span></td>
  120. </tr>
  121. <tr class="dict-type-row" data-id="8">
  122. <td>作业状态</td>
  123. <td>farm_task_status</td>
  124. <td><span class="badge badge-success">启用</span></td>
  125. </tr>
  126. <tr class="dict-type-row" data-id="9">
  127. <td>设备类型</td>
  128. <td>device_type</td>
  129. <td><span class="badge badge-success">启用</span></td>
  130. </tr>
  131. <tr class="dict-type-row" data-id="10">
  132. <td>作物类型</td>
  133. <td>crop_type</td>
  134. <td><span class="badge badge-success">启用</span></td>
  135. </tr>
  136. </tbody>
  137. </table>
  138. </div>
  139. <div class="p-4 flex justify-between items-center">
  140. <div class="text-sm text-gray-500">
  141. 共 <span class="font-medium">10</span> 条记录,每页 <span class="font-medium">10</span> 条
  142. </div>
  143. <div class="pagination">
  144. <div class="pagination-item disabled">
  145. <i class="iconfont icon-left"></i>
  146. </div>
  147. <div class="pagination-item active">1</div>
  148. <div class="pagination-item">
  149. <i class="iconfont icon-right"></i>
  150. </div>
  151. </div>
  152. </div>
  153. </div>
  154. <!-- 右侧字典数据列表 -->
  155. <div class="card lg:col-span-2">
  156. <div class="flex justify-between items-center border-b p-4">
  157. <h2 class="font-medium">字典数据 - 用户性别</h2>
  158. <button class="btn btn-primary" id="addDictDataBtn">
  159. <i class="iconfont icon-plus btn-icon"></i>
  160. 新增字典数据
  161. </button>
  162. </div>
  163. <div class="table-container">
  164. <div class="table-scroll-controls">
  165. <button class="table-scroll-btn table-scroll-left">
  166. <i class="iconfont icon-left"></i>
  167. </button>
  168. <button class="table-scroll-btn table-scroll-right">
  169. <i class="iconfont icon-right"></i>
  170. </button>
  171. </div> <table class="table-fixed-right table-fixed-right">
  172. <thead>
  173. <tr>
  174. <th>字典标签</th>
  175. <th>字典键值</th>
  176. <th>字典排序</th>
  177. <th class="min-w-[80px]">状态</th>
  178. <th class="min-w-[150px]">操作</th>
  179. </tr>
  180. </thead>
  181. <tbody>
  182. <tr>
  183. <td>男</td>
  184. <td>1</td>
  185. <td>1</td>
  186. <td><span class="badge badge-success">启用</span></td>
  187. <td>
  188. <div class="flex gap-2">
  189. <button class="btn btn-default btn-sm edit-data-btn" data-id="1">
  190. <i class="iconfont icon-edit btn-icon"></i>
  191. 编辑
  192. </button>
  193. <button class="btn btn-danger btn-sm">
  194. <i class="iconfont icon-delete btn-icon"></i>
  195. 删除
  196. </button>
  197. </div>
  198. </td>
  199. </tr>
  200. <tr>
  201. <td>女</td>
  202. <td>2</td>
  203. <td>2</td>
  204. <td><span class="badge badge-success">启用</span></td>
  205. <td>
  206. <div class="flex gap-2">
  207. <button class="btn btn-default btn-sm edit-data-btn" data-id="2">
  208. <i class="iconfont icon-edit btn-icon"></i>
  209. 编辑
  210. </button>
  211. <button class="btn btn-danger btn-sm">
  212. <i class="iconfont icon-delete btn-icon"></i>
  213. 删除
  214. </button>
  215. </div>
  216. </td>
  217. </tr>
  218. <tr>
  219. <td>未知</td>
  220. <td>0</td>
  221. <td>3</td>
  222. <td><span class="badge badge-success">启用</span></td>
  223. <td>
  224. <div class="flex gap-2">
  225. <button class="btn btn-default btn-sm edit-data-btn" data-id="3">
  226. <i class="iconfont icon-edit btn-icon"></i>
  227. 编辑
  228. </button>
  229. <button class="btn btn-danger btn-sm">
  230. <i class="iconfont icon-delete btn-icon"></i>
  231. 删除
  232. </button>
  233. </div>
  234. </td>
  235. </tr>
  236. </tbody>
  237. </table>
  238. </div>
  239. <div class="p-4 flex justify-between items-center">
  240. <div class="text-sm text-gray-500">
  241. 共 <span class="font-medium">3</span> 条记录,每页 <span class="font-medium">10</span> 条
  242. </div>
  243. <div class="pagination">
  244. <div class="pagination-item disabled">
  245. <i class="iconfont icon-left"></i>
  246. </div>
  247. <div class="pagination-item active">1</div>
  248. <div class="pagination-item">
  249. <i class="iconfont icon-right"></i>
  250. </div>
  251. </div>
  252. </div>
  253. </div>
  254. </div>
  255. </div>
  256. <!-- 字典类型表单弹窗 -->
  257. <div class="modal-overlay" id="dictModal">
  258. <div class="modal">
  259. <div class="modal-header">
  260. <h3 class="modal-title" id="dictModalTitle">新增字典</h3>
  261. <div class="modal-close" id="closeDictModal">&times;</div>
  262. </div>
  263. <div class="modal-body">
  264. <form id="dictForm">
  265. <div class="form-group">
  266. <label class="form-label" for="dictName">字典名称</label>
  267. <input type="text" id="dictName" class="form-input" placeholder="请输入字典名称">
  268. </div>
  269. <div class="form-group">
  270. <label class="form-label" for="dictCode">字典编码</label>
  271. <input type="text" id="dictCode" class="form-input" placeholder="请输入字典编码">
  272. </div>
  273. <div class="form-group">
  274. <label class="form-label" for="dictDesc">字典描述</label>
  275. <textarea id="dictDesc" class="form-input" rows="3" placeholder="请输入字典描述"></textarea>
  276. </div>
  277. <div class="form-group">
  278. <label class="form-label">状态</label>
  279. <div class="flex items-center gap-4">
  280. <label class="flex items-center">
  281. <input type="radio" name="dictStatus" value="1" checked class="mr-2">
  282. 启用
  283. </label>
  284. <label class="flex items-center">
  285. <input type="radio" name="dictStatus" value="0" class="mr-2">
  286. 禁用
  287. </label>
  288. </div>
  289. </div>
  290. </form>
  291. </div>
  292. <div class="modal-footer">
  293. <button class="btn btn-default" id="cancelDictBtn">取消</button>
  294. <button class="btn btn-primary" id="saveDictBtn">保存</button>
  295. </div>
  296. </div>
  297. </div>
  298. <!-- 字典数据表单弹窗 -->
  299. <div class="modal-overlay" id="dictDataModal">
  300. <div class="modal">
  301. <div class="modal-header">
  302. <h3 class="modal-title" id="dictDataModalTitle">新增字典数据</h3>
  303. <div class="modal-close" id="closeDictDataModal">&times;</div>
  304. </div>
  305. <div class="modal-body">
  306. <form id="dictDataForm">
  307. <div class="form-group">
  308. <label class="form-label" for="dictType">字典类型</label>
  309. <input type="text" id="dictType" class="form-input" value="用户性别" readonly>
  310. </div>
  311. <div class="form-group">
  312. <label class="form-label" for="dictLabel">字典标签</label>
  313. <input type="text" id="dictLabel" class="form-input" placeholder="请输入字典标签">
  314. </div>
  315. <div class="form-group">
  316. <label class="form-label" for="dictValue">字典键值</label>
  317. <input type="text" id="dictValue" class="form-input" placeholder="请输入字典键值">
  318. </div>
  319. <div class="form-group">
  320. <label class="form-label" for="dictSort">字典排序</label>
  321. <input type="number" id="dictSort" class="form-input" placeholder="请输入字典排序" value="1">
  322. </div>
  323. <div class="form-group">
  324. <label class="form-label">状态</label>
  325. <div class="flex items-center gap-4">
  326. <label class="flex items-center">
  327. <input type="radio" name="dataStatus" value="1" checked class="mr-2">
  328. 启用
  329. </label>
  330. <label class="flex items-center">
  331. <input type="radio" name="dataStatus" value="0" class="mr-2">
  332. 禁用
  333. </label>
  334. </div>
  335. </div>
  336. <div class="form-group">
  337. <label class="form-label" for="remark">备注</label>
  338. <textarea id="remark" class="form-input" rows="2" placeholder="请输入备注"></textarea>
  339. </div>
  340. </form>
  341. </div>
  342. <div class="modal-footer">
  343. <button class="btn btn-default" id="cancelDataBtn">取消</button>
  344. <button class="btn btn-primary" id="saveDataBtn">保存</button>
  345. </div>
  346. </div>
  347. </div>
  348. <script>
  349. document.addEventListener("DOMContentLoaded", function() {
  350. // 初始化表格滚动功能
  351. function initTableScroll() {
  352. const tableContainer = document.querySelector(".table-container");
  353. if (!tableContainer) return;
  354. const scrollLeftBtn = document.querySelector(".table-scroll-left");
  355. const scrollRightBtn = document.querySelector(".table-scroll-right");
  356. if (!scrollLeftBtn || !scrollRightBtn) return;
  357. // 检查表格是否需要水平滚动
  358. function checkTableOverflow() {
  359. if (tableContainer.scrollWidth > tableContainer.clientWidth) {
  360. tableContainer.classList.add("has-overflow");
  361. } else {
  362. tableContainer.classList.remove("has-overflow");
  363. }
  364. }
  365. // 左右滚动按钮点击事件
  366. scrollLeftBtn.addEventListener("click", function() {
  367. tableContainer.scrollLeft -= 150;
  368. });
  369. scrollRightBtn.addEventListener("click", function() {
  370. tableContainer.scrollLeft += 150;
  371. });
  372. // 初始检查和窗口大小变化时检查
  373. checkTableOverflow();
  374. window.addEventListener("resize", checkTableOverflow);
  375. // 滚动事件处理
  376. tableContainer.addEventListener("scroll", function() {
  377. // 根据滚动位置显示/隐藏滚动按钮
  378. if (tableContainer.scrollLeft <= 10) {
  379. scrollLeftBtn.style.opacity = "0.5";
  380. } else {
  381. scrollLeftBtn.style.opacity = "1";
  382. }
  383. if (tableContainer.scrollLeft >= tableContainer.scrollWidth - tableContainer.clientWidth - 10) {
  384. scrollRightBtn.style.opacity = "0.5";
  385. } else {
  386. scrollRightBtn.style.opacity = "1";
  387. }
  388. });
  389. // 初始触发滚动事件,设置初始按钮状态
  390. tableContainer.dispatchEvent(new Event("scroll"));
  391. }
  392. // 初始化表格滚动
  393. initTableScroll(); document.addEventListener('DOMContentLoaded', function() {
  394. // 字典类型行点击事件
  395. const dictTypeRows = document.querySelectorAll('.dict-type-row');
  396. dictTypeRows.forEach(row => {
  397. row.addEventListener('click', function() {
  398. // 移除其他行的活动状态
  399. dictTypeRows.forEach(r => r.classList.remove('active'));
  400. // 添加当前行的活动状态
  401. this.classList.add('active');
  402. // 更新右侧标题
  403. const dictName = this.querySelector('td:first-child').textContent;
  404. document.querySelector('.card.lg\\:col-span-2 h2').textContent = `字典数据 - ${dictName}`;
  405. // 更新字典数据表单中的字典类型
  406. document.getElementById('dictType').value = dictName;
  407. // 实际应用中,这里应该发送请求获取对应的字典数据
  408. });
  409. });
  410. // 字典类型表单弹窗
  411. const dictModal = document.getElementById('dictModal');
  412. const dictModalTitle = document.getElementById('dictModalTitle');
  413. const addDictBtn = document.getElementById('addDictBtn');
  414. const closeDictModal = document.getElementById('closeDictModal');
  415. const cancelDictBtn = document.getElementById('cancelDictBtn');
  416. const saveDictBtn = document.getElementById('saveDictBtn');
  417. // 打开新增字典弹窗
  418. addDictBtn.addEventListener('click', function() {
  419. dictModalTitle.textContent = '新增字典';
  420. document.getElementById('dictForm').reset();
  421. dictModal.style.display = 'flex';
  422. });
  423. // 关闭字典弹窗
  424. function closeDictModalFunc() {
  425. dictModal.style.display = 'none';
  426. }
  427. closeDictModal.addEventListener('click', closeDictModalFunc);
  428. cancelDictBtn.addEventListener('click', closeDictModalFunc);
  429. // 保存字典
  430. saveDictBtn.addEventListener('click', function() {
  431. alert('字典保存成功!');
  432. closeDictModalFunc();
  433. });
  434. // 字典数据表单弹窗
  435. const dictDataModal = document.getElementById('dictDataModal');
  436. const dictDataModalTitle = document.getElementById('dictDataModalTitle');
  437. const addDictDataBtn = document.getElementById('addDictDataBtn');
  438. const closeDictDataModal = document.getElementById('closeDictDataModal');
  439. const cancelDataBtn = document.getElementById('cancelDataBtn');
  440. const saveDataBtn = document.getElementById('saveDataBtn');
  441. const editDataBtns = document.querySelectorAll('.edit-data-btn');
  442. // 打开新增字典数据弹窗
  443. addDictDataBtn.addEventListener('click', function() {
  444. dictDataModalTitle.textContent = '新增字典数据';
  445. document.getElementById('dictDataForm').reset();
  446. // 设置字典类型为当前选中的字典类型
  447. const activeType = document.querySelector('.dict-type-row.active td:first-child').textContent;
  448. document.getElementById('dictType').value = activeType;
  449. dictDataModal.style.display = 'flex';
  450. });
  451. // 打开编辑字典数据弹窗
  452. editDataBtns.forEach(btn => {
  453. btn.addEventListener('click', function() {
  454. const dataId = this.getAttribute('data-id');
  455. dictDataModalTitle.textContent = '编辑字典数据';
  456. // 模拟获取字典数据
  457. if (dataId === '1') {
  458. document.getElementById('dictLabel').value = '男';
  459. document.getElementById('dictValue').value = '1';
  460. document.getElementById('dictSort').value = '1';
  461. document.querySelector('input[name="dataStatus"][value="1"]').checked = true;
  462. document.getElementById('remark').value = '男性用户';
  463. }
  464. dictDataModal.style.display = 'flex';
  465. });
  466. });
  467. // 关闭字典数据弹窗
  468. function closeDictDataModalFunc() {
  469. dictDataModal.style.display = 'none';
  470. }
  471. closeDictDataModal.addEventListener('click', closeDictDataModalFunc);
  472. cancelDataBtn.addEventListener('click', closeDictDataModalFunc);
  473. // 保存字典数据
  474. saveDataBtn.addEventListener('click', function() {
  475. alert('字典数据保存成功!');
  476. closeDictDataModalFunc();
  477. });
  478. // 点击弹窗外部关闭弹窗
  479. window.addEventListener('click', function(e) {
  480. if (e.target === dictModal) {
  481. closeDictModalFunc();
  482. }
  483. if (e.target === dictDataModal) {
  484. closeDictDataModalFunc();
  485. }
  486. });
  487. // 添加表格行的悬停效果
  488. const tableRows = document.querySelectorAll('tbody tr');
  489. tableRows.forEach(row => {
  490. row.classList.add('hover:bg-gray-50', 'cursor-pointer');
  491. });
  492. });
  493. </script>
  494. </body>
  495. </html>