pageData.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. // data.js - 数据管理、导入导出相关功能
  2. function initializeDataPage() {
  3. // 生成数据标签页内容
  4. generateDataTabContent();
  5. // 加载项目标题和自定义参数数据
  6. loadProjectTitle();
  7. loadCustomParamsData();
  8. }
  9. // 生成数据标签页内容
  10. function generateDataTabContent() {
  11. console.log('generateDataTabContent');
  12. const dataTab = document.createElement('div');
  13. dataTab.id = 'data';
  14. dataTab.className = 'tab-content';
  15. // 创建内容容器
  16. const contentContainer = document.createElement('div');
  17. contentContainer.className = 'content-container';
  18. contentContainer.style.flexDirection = 'column';
  19. // 创建项目标题和按钮部分
  20. const titleSection = document.createElement('div');
  21. titleSection.style.marginBottom = '1.5rem';
  22. // 创建标题输入部分
  23. const titleRow = document.createElement('div');
  24. titleRow.style.display = 'flex';
  25. titleRow.style.alignItems = 'center';
  26. titleRow.style.marginBottom = '1rem';
  27. const titleLabel = document.createElement('label');
  28. titleLabel.htmlFor = 'project-title';
  29. titleLabel.style.marginRight = '1rem';
  30. titleLabel.style.fontWeight = 'bold';
  31. titleLabel.textContent = '工程标题:';
  32. const titleInput = document.createElement('input');
  33. titleInput.type = 'text';
  34. titleInput.id = 'project-title';
  35. titleInput.placeholder = '请输入工程标题';
  36. titleInput.style.flex = '1';
  37. titleInput.style.padding = '0.5rem';
  38. titleInput.style.border = '1px solid #ccc';
  39. titleInput.style.borderRadius = '4px';
  40. titleInput.oninput = updateProjectTitle;
  41. titleRow.appendChild(titleLabel);
  42. titleRow.appendChild(titleInput);
  43. // 创建按钮容器
  44. const buttonContainer = document.createElement('div');
  45. buttonContainer.className = 'button-container';
  46. // 创建导出按钮
  47. const exportBtn = document.createElement('button');
  48. exportBtn.className = 'export-btn';
  49. exportBtn.textContent = '导出数据';
  50. exportBtn.onclick = exportData;
  51. // 创建导入按钮
  52. const importBtn = document.createElement('button');
  53. importBtn.className = 'import-btn';
  54. importBtn.textContent = '导入数据';
  55. importBtn.onclick = function () {
  56. document.getElementById('importFile').click();
  57. };
  58. // 创建新建工程按钮
  59. const newProjectBtn = document.createElement('button');
  60. newProjectBtn.className = 'export-btn';
  61. newProjectBtn.style.backgroundColor = '#dc3545';
  62. newProjectBtn.textContent = '新建工程';
  63. newProjectBtn.onclick = newProject;
  64. // 创建文件输入(隐藏)
  65. const importFile = document.createElement('input');
  66. importFile.type = 'file';
  67. importFile.id = 'importFile';
  68. importFile.accept = '.json,.txt';
  69. importFile.style.display = 'none';
  70. importFile.onchange = importData;
  71. // 添加按钮到容器
  72. buttonContainer.appendChild(exportBtn);
  73. buttonContainer.appendChild(importBtn);
  74. buttonContainer.appendChild(newProjectBtn);
  75. buttonContainer.appendChild(importFile);
  76. // 组装标题部分
  77. titleSection.appendChild(titleRow);
  78. titleSection.appendChild(buttonContainer);
  79. // 创建自定义参数部分
  80. const customParamsSection = document.createElement('div');
  81. customParamsSection.style.marginTop = '1.5rem';
  82. customParamsSection.style.border = '1px solid #eee';
  83. customParamsSection.style.borderRadius = '4px';
  84. customParamsSection.style.padding = '1rem';
  85. // 添加标题
  86. const customParamsTitle = document.createElement('h3');
  87. customParamsTitle.style.marginTop = '0';
  88. customParamsTitle.style.marginBottom = '1rem';
  89. customParamsTitle.textContent = '自定义参数';
  90. // 创建参数容器
  91. const customParamsContainer = document.createElement('div');
  92. customParamsContainer.id = 'custom-params-container';
  93. customParamsContainer.style.display = 'flex';
  94. customParamsContainer.style.flexDirection = 'column';
  95. customParamsContainer.style.gap = '0.5rem';
  96. customParamsContainer.style.maxHeight = '300px';
  97. customParamsContainer.style.overflowY = 'auto';
  98. // 添加按钮
  99. const addParamBtn = document.createElement('div');
  100. addParamBtn.className = 'add-input-btn';
  101. addParamBtn.style.marginTop = '1rem';
  102. addParamBtn.onclick = addCustomParam;
  103. const addParamSpan = document.createElement('span');
  104. addParamSpan.textContent = '+ 添加参数';
  105. addParamBtn.appendChild(addParamSpan);
  106. // 组装自定义参数部分
  107. customParamsSection.appendChild(customParamsTitle);
  108. customParamsSection.appendChild(customParamsContainer);
  109. customParamsSection.appendChild(addParamBtn);
  110. // 组装整个内容
  111. contentContainer.appendChild(titleSection);
  112. contentContainer.appendChild(customParamsSection);
  113. dataTab.appendChild(contentContainer);
  114. if (document.getElementById('container')) {
  115. console.log('appendChild dataTab');
  116. document.getElementById('container').appendChild(dataTab);
  117. }
  118. // 添加版本信息
  119. const versionInfo = document.createElement('div');
  120. versionInfo.style.textAlign = 'center';
  121. versionInfo.style.marginTop = '1rem';
  122. versionInfo.style.color = '#666';
  123. versionInfo.style.fontSize = '0.8rem';
  124. versionInfo.textContent = 'Ver 1.1.02.250628';
  125. dataTab.appendChild(versionInfo);
  126. }
  127. // 添加自定义参数
  128. function addCustomParam() {
  129. const container = document.getElementById('custom-params-container');
  130. const paramRow = document.createElement('div');
  131. paramRow.className = 'custom-param-row';
  132. paramRow.style.display = 'flex';
  133. paramRow.style.alignItems = 'center';
  134. paramRow.style.gap = '0.5rem';
  135. const nameInput = document.createElement('input');
  136. nameInput.type = 'text';
  137. nameInput.className = 'param-name';
  138. nameInput.placeholder = '参数名称';
  139. nameInput.style.flex = '1';
  140. nameInput.style.padding = '0.5rem';
  141. nameInput.style.border = '1px solid #ccc';
  142. nameInput.style.borderRadius = '4px';
  143. nameInput.oninput = saveCustomParamsData;
  144. const valueInput = document.createElement('input');
  145. valueInput.type = 'text';
  146. valueInput.className = 'param-value';
  147. valueInput.placeholder = '参数值';
  148. valueInput.style.flex = '1';
  149. valueInput.style.padding = '0.5rem';
  150. valueInput.style.border = '1px solid #ccc';
  151. valueInput.style.borderRadius = '4px';
  152. valueInput.oninput = saveCustomParamsData;
  153. const deleteBtn = document.createElement('span');
  154. deleteBtn.className = 'delete-btn';
  155. deleteBtn.innerHTML = '×';
  156. deleteBtn.onclick = function () {
  157. container.removeChild(paramRow);
  158. saveCustomParamsData();
  159. };
  160. paramRow.appendChild(nameInput);
  161. paramRow.appendChild(valueInput);
  162. paramRow.appendChild(deleteBtn);
  163. container.appendChild(paramRow);
  164. }
  165. // 清除自定义参数数据
  166. function clearCustomParamsData() {
  167. // 清除自定义参数
  168. const customParamsContainer = document.getElementById('custom-params-container');
  169. while (customParamsContainer.firstChild) {
  170. customParamsContainer.removeChild(customParamsContainer.firstChild);
  171. }
  172. saveCustomParamsData();
  173. }
  174. // 保存自定义参数数据
  175. function saveCustomParamsData() {
  176. const customParams = Array.from(document.querySelectorAll('#custom-params-container .custom-param-row')).map(row => ({
  177. name: row.querySelector('.param-name').value,
  178. value: row.querySelector('.param-value').value
  179. }));
  180. setLocalStorage('customParamsData', JSON.stringify(customParams));
  181. }
  182. // 从localStorage加载自定义参数数据
  183. function loadCustomParamsData() {
  184. const savedParams = getLocalStorage('customParamsData');
  185. console.log('customParamsData', savedParams);
  186. if (savedParams) {
  187. try {
  188. const params = JSON.parse(savedParams);
  189. const container = document.getElementById('custom-params-container');
  190. // 清除现有参数
  191. while (container.firstChild) {
  192. container.removeChild(container.firstChild);
  193. }
  194. // 添加保存的自定义参数
  195. params.forEach(param => {
  196. const paramRow = document.createElement('div');
  197. paramRow.className = 'custom-param-row';
  198. paramRow.style.display = 'flex';
  199. paramRow.style.alignItems = 'center';
  200. paramRow.style.gap = '0.5rem';
  201. const nameInput = document.createElement('input');
  202. nameInput.type = 'text';
  203. nameInput.className = 'param-name';
  204. nameInput.placeholder = '参数名称';
  205. nameInput.style.flex = '1';
  206. nameInput.style.padding = '0.5rem';
  207. nameInput.style.border = '1px solid #ccc';
  208. nameInput.style.borderRadius = '4px';
  209. nameInput.value = param.name;
  210. nameInput.oninput = saveCustomParamsData;
  211. const valueInput = document.createElement('input');
  212. valueInput.type = 'text';
  213. valueInput.className = 'param-value';
  214. valueInput.placeholder = '参数值';
  215. valueInput.style.flex = '1';
  216. valueInput.style.padding = '0.5rem';
  217. valueInput.style.border = '1px solid #ccc';
  218. valueInput.style.borderRadius = '4px';
  219. valueInput.value = param.value;
  220. valueInput.oninput = saveCustomParamsData;
  221. const deleteBtn = document.createElement('span');
  222. deleteBtn.className = 'delete-btn';
  223. deleteBtn.innerHTML = '×';
  224. deleteBtn.onclick = function () {
  225. container.removeChild(paramRow);
  226. saveCustomParamsData();
  227. };
  228. paramRow.appendChild(nameInput);
  229. paramRow.appendChild(valueInput);
  230. paramRow.appendChild(deleteBtn);
  231. container.appendChild(paramRow);
  232. });
  233. } catch (e) {
  234. console.error('加载自定义参数失败:', e);
  235. }
  236. }
  237. }
  238. // 从localStorage加载项目标题
  239. function loadProjectTitle() {
  240. const savedTitle = getLocalStorage('projectTitle');
  241. if (savedTitle) {
  242. try {
  243. const titleInput = document.getElementById('project-title');
  244. console.log('projectTitle', savedTitle);
  245. if (titleInput) {
  246. titleInput.value = savedTitle;
  247. }
  248. } catch (e) {
  249. console.error('加载项目标题失败:', e);
  250. }
  251. }
  252. }
  253. function newProject() {
  254. if (confirm('确定要新建工程吗?这将清除所有当前数据!')) {
  255. // 清除整个localStorage
  256. localStorage.clear();
  257. // 刷新页面
  258. location.reload();
  259. }
  260. }
  261. // 导出数据
  262. function exportData() {
  263. // 获取所有localStorage数据
  264. const data = {};
  265. for (let i = 0; i < localStorage.length; i++) {
  266. const key = localStorage.key(i);
  267. try {
  268. // 尝试解析JSON数据
  269. const value = localStorage.getItem(key);
  270. data[key] = JSON.parse(value);
  271. } catch (e) {
  272. // 如果不是JSON格式则直接存储原始值
  273. data[key] = localStorage.getItem(key);
  274. }
  275. }
  276. const projectTitle = document.getElementById('project-title').value;
  277. const jsonString = JSON.stringify(data, null, 2);
  278. const blob = new Blob([jsonString], { type: 'application/json' });
  279. const url = URL.createObjectURL(blob);
  280. const a = document.createElement('a');
  281. a.href = url;
  282. const fileName = `_LabStatistics_${new Date().toISOString().split('.')[0]}.json`;
  283. a.download = `${projectTitle}${fileName.replace(/-/g, '_')}`;
  284. document.body.appendChild(a);
  285. a.click();
  286. document.body.removeChild(a);
  287. URL.revokeObjectURL(url);
  288. }
  289. // 导入数据
  290. function importData() {
  291. const fileInput = document.getElementById('importFile');
  292. const file = fileInput.files[0];
  293. if (!file) {
  294. alert('请选择要导入的文件!');
  295. return;
  296. }
  297. const reader = new FileReader();
  298. reader.onload = function (e) {
  299. try {
  300. const data = JSON.parse(e.target.result);
  301. // 清除现有数据
  302. localStorage.clear();
  303. // 导入所有数据到localStorage
  304. // 遍历数据对象的所有键
  305. for (const key in data) {
  306. try {
  307. // 检查数据类型并相应处理
  308. if (typeof data[key] === 'object' && data[key] !== null) {
  309. // 对象类型数据转换为JSON字符串存储
  310. localStorage.setItem(key, JSON.stringify(data[key]));
  311. } else {
  312. // 其他类型直接存储
  313. localStorage.setItem(key, data[key]);
  314. }
  315. } catch (error) {
  316. console.error(`导入键 ${key} 时出错:`, error);
  317. }
  318. }
  319. // 导入完成后重新加载页面以更新显示
  320. location.reload();
  321. alert('数据导入成功!');
  322. } catch (error) {
  323. alert('导入失败!请检查文件格式。');
  324. console.error('导入错误:', error);
  325. }
  326. };
  327. reader.readAsText(file);
  328. }