Visualization.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. Page({
  2. data: {
  3. isEditing: false,
  4. tableName: 'current_reflux', // 确保这个表名在页面中是有效的
  5. fileFormat: 'excel', // 默认是 Excel 格式
  6. shoopingtext: "", // 搜索框内容
  7. filteredRows: [], // 表格过滤后的数据
  8. rows: [], // 所有表格数据
  9. showModal: false, // 控制底部编辑删除弹窗的显示与否
  10. showAddModal: false, // 控制新增数据弹窗的显示与否
  11. currentRow: null, // 当前选中的表格行
  12. // 新增数据弹窗的输入框内容
  13. newData: {
  14. id: "",
  15. OM: "",
  16. CL: "",
  17. CEC: "",
  18. H_plus: "",
  19. HN: "",
  20. Al3_plus: "",
  21. free_alumina: "",
  22. free_iron_oxides: "",
  23. Delta_pH: ""
  24. },
  25. // 中文表头内容,动态生成
  26. tableHeaders: [
  27. "序号", "有机质含量", "土壤粘粒重量", "阳离子交换量", "氢离子含量",
  28. "硝态氮含量","铝离子含量", "游离氧化铝", "游离氧化铁", "酸碱差值",
  29. ]
  30. },
  31. // 页面加载时获取表格数据
  32. onLoad: function() {
  33. this.LoadData();
  34. },
  35. LoadData: function() {
  36. wx.request({
  37. url: 'http://localhost:5000/tables',
  38. method: 'POST',
  39. header: {
  40. 'Content-Type': 'application/json'
  41. },
  42. data: {
  43. table: 'current_reflux'
  44. },
  45. success: (res) => {
  46. console.log('后端返回数据:', res.data.rows); // 打印返回数据,确认格式
  47. if (res.data && Array.isArray(res.data.rows)) {
  48. const rows = res.data.rows.map(row => {
  49. return {
  50. 'id': row[0],
  51. 'OM': row[1],
  52. 'CL': row[2],
  53. 'CEC': row[3],
  54. 'H_plus': row[4],
  55. 'HN': row[5],
  56. 'Al3_plus': row[6],
  57. 'free_alumina': row[7],
  58. 'free_iron_oxides': row[8],
  59. 'Delta_pH': row[9],
  60. };
  61. });
  62. this.setData({
  63. rows: rows,
  64. filteredRows: rows
  65. });
  66. } else {
  67. wx.showToast({
  68. title: '获取数据失败',
  69. icon: 'none'
  70. });
  71. }
  72. },
  73. fail: (err) => {
  74. wx.showToast({
  75. title: '请求失败,请重试',
  76. icon: 'none'
  77. });
  78. console.error('请求失败:', err);
  79. }
  80. });
  81. },
  82. // 搜索框绑定
  83. shoppinginput: function(e) {
  84. this.setData({
  85. shoopingtext: e.detail.value
  86. });
  87. },
  88. // 搜索功能:根据输入内容过滤表格数据
  89. search: function() {
  90. const searchText = this.data.shoopingtext.toLowerCase();
  91. const filteredRows = this.data.rows.filter(item => {
  92. return Object.values(item).some(value =>
  93. String(value).toLowerCase().includes(searchText)
  94. );
  95. });
  96. this.setData({
  97. filteredRows: filteredRows
  98. });
  99. },
  100. // 下载模板函数
  101. onDownloadTemplate: function() {
  102. wx.showLoading({
  103. title: '下载中...',
  104. });
  105. const tableName = 'current_reflux'; // 或者根据需要选择表名
  106. const format = 'excel'; // 或者 'csv' 作为模板格式
  107. wx.request({
  108. url: `http://localhost:5000/download_template?table=${tableName}&format=${format}`,
  109. method: 'GET',
  110. responseType: 'arraybuffer', // 处理二进制文件
  111. success: (res) => {
  112. wx.hideLoading();
  113. // 确保响应体返回的数据是有效的文件
  114. if (res.statusCode === 200) {
  115. const fileType = format === 'excel' ? 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' : 'text/csv';
  116. // 生成唯一的文件名,添加时间戳以确保唯一性
  117. const timestamp = new Date().getTime();
  118. const fileName = `${tableName}_template_${timestamp}.${format}`;
  119. const filePath = wx.env.USER_DATA_PATH + '/' + fileName;
  120. // 使用文件系统管理器保存文件
  121. const fs = wx.getFileSystemManager();
  122. fs.writeFile({
  123. filePath: filePath,
  124. data: res.data,
  125. encoding: 'binary',
  126. success: () => {
  127. wx.showToast({
  128. title: '文件已保存',
  129. icon: 'success'
  130. });
  131. // 触发文件下载
  132. wx.openDocument({
  133. filePath: filePath,
  134. fileType: format === 'excel' ? 'xlsx' : 'csv',
  135. success: () => {
  136. console.log('文件打开成功');
  137. },
  138. fail: (error) => {
  139. console.error('文件打开失败', error);
  140. wx.showToast({
  141. title: '打开文件失败',
  142. icon: 'none'
  143. });
  144. }
  145. });
  146. },
  147. fail: (err) => {
  148. wx.showToast({
  149. title: '文件保存失败',
  150. icon: 'none'
  151. });
  152. console.error('文件保存失败', err);
  153. }
  154. });
  155. } else {
  156. wx.showToast({
  157. title: '下载失败',
  158. icon: 'none'
  159. });
  160. }
  161. },
  162. fail: (err) => {
  163. wx.hideLoading();
  164. wx.showToast({
  165. title: '请求失败,请重试',
  166. icon: 'none'
  167. });
  168. console.error('请求失败:', err);
  169. }
  170. });
  171. },
  172. // 导出数据按钮点击事件
  173. onExport: function () {
  174. const tableName = this.data.tableName;
  175. const fileFormat = this.data.fileFormat;
  176. wx.showLoading({
  177. title: '导出中...',
  178. });
  179. // 向后端发送请求,获取表格数据并导出
  180. wx.request({
  181. url: `http://localhost:5000/export_data?table=${tableName}&format=${fileFormat}`,
  182. method: 'GET',
  183. responseType: 'arraybuffer', // 处理二进制文件
  184. success: (res) => {
  185. wx.hideLoading();
  186. // 确保响应体返回的数据是有效的文件
  187. if (res.statusCode === 200) {
  188. const fileName = `${tableName}_data.${fileFormat === 'excel' ? 'xlsx' : 'csv'}`;
  189. const filePath = wx.env.USER_DATA_PATH + '/' + fileName;
  190. // 保存文件到本地
  191. wx.getFileSystemManager().writeFile({
  192. filePath: filePath,
  193. data: res.data,
  194. encoding: 'binary',
  195. success: () => {
  196. wx.showToast({
  197. title: '文件已保存',
  198. icon: 'success'
  199. });
  200. // 打开已保存的文件
  201. wx.openDocument({
  202. filePath: filePath,
  203. fileType: fileFormat === 'excel' ? 'xlsx' : 'csv',
  204. success: () => {
  205. console.log('文件打开成功');
  206. },
  207. fail: (error) => {
  208. console.error('文件打开失败', error);
  209. wx.showToast({
  210. title: '打开文件失败',
  211. icon: 'none'
  212. });
  213. }
  214. });
  215. },
  216. fail: (err) => {
  217. wx.showToast({
  218. title: '文件保存失败',
  219. icon: 'none'
  220. });
  221. console.error('文件保存失败', err);
  222. }
  223. });
  224. } else {
  225. wx.showToast({
  226. title: '导出失败,请重试',
  227. icon: 'none'
  228. });
  229. }
  230. },
  231. fail: (err) => {
  232. wx.hideLoading();
  233. wx.showToast({
  234. title: '请求失败,请重试',
  235. icon: 'none'
  236. });
  237. console.error('请求失败:', err);
  238. }
  239. });
  240. },
  241. // 导入数据功能
  242. onImport: function () {
  243. wx.chooseMessageFile({
  244. count: 1,
  245. type: 'file',
  246. extension: ['xlsx', 'csv'], // 允许上传的文件类型
  247. success: (res) => {
  248. const filePath = res.tempFiles[0].path; // 获取文件临时路径
  249. const fileName = res.tempFiles[0].name;
  250. wx.showLoading({
  251. title: '上传中...',
  252. });
  253. // 上传文件到后端
  254. wx.uploadFile({
  255. url: 'http://localhost:5000/import_data', // 后端处理导入的接口
  256. filePath: filePath,
  257. name: 'file',
  258. formData: {
  259. table: this.data.tableName, // 表名,后端根据需要解析数据
  260. fileName: fileName
  261. },
  262. success: (res) => {
  263. wx.hideLoading();
  264. const responseData = JSON.parse(res.data);
  265. if (responseData.success) {
  266. wx.showToast({
  267. title: '导入成功',
  268. icon: 'success'
  269. });
  270. // 重新加载数据
  271. this.LoadData();
  272. } else {
  273. wx.showToast({
  274. title: '导入失败,请检查文件格式',
  275. icon: 'none'
  276. });
  277. }
  278. },
  279. fail: (err) => {
  280. wx.hideLoading();
  281. wx.showToast({
  282. title: '导入失败,请重试',
  283. icon: 'none'
  284. });
  285. console.error('文件上传失败:', err);
  286. }
  287. });
  288. },
  289. fail: (err) => {
  290. console.error('文件选择失败:', err);
  291. }
  292. });
  293. },
  294. // 新增按钮点击,显示新增弹窗
  295. onAdd: function() {
  296. console.log("新增按钮被点击了"); // 调试日志
  297. this.setData({
  298. showAddModal: true,
  299. newData: { // 重置新增数据
  300. OM: "",
  301. CL: "",
  302. CEC: "",
  303. H_plus: "",
  304. HN: "",
  305. Al3_plus: "",
  306. free_alumina: "",
  307. free_iron_oxides: "",
  308. Delta_pH: ""
  309. }
  310. });
  311. console.log("showAddModal: ", this.data.showAddModal); // 确认数据更新
  312. },
  313. // 输入框绑定:更新新增数据的对应字段
  314. onInputOM: function(e) {
  315. this.setData({
  316. 'newData.OM': e.detail.value
  317. });
  318. },
  319. onInputCL: function(e) {
  320. this.setData({
  321. 'newData.CL': e.detail.value
  322. });
  323. },
  324. onInputCEC: function(e) {
  325. this.setData({
  326. 'newData.CEC': e.detail.value
  327. });
  328. },
  329. onInputH_plus: function(e) {
  330. this.setData({
  331. 'newData.H_plus': e.detail.value
  332. });
  333. },
  334. onInputHN: function(e) {
  335. this.setData({
  336. 'newData.HN': e.detail.value
  337. });
  338. },
  339. onInputAl3_plus: function(e) {
  340. this.setData({
  341. 'newData.Al3_plus': e.detail.value
  342. });
  343. },
  344. onInputfree_alumina: function(e) {
  345. this.setData({
  346. 'newData.free_alumina': e.detail.value
  347. });
  348. },
  349. onInputfree_iron_oxides: function(e) {
  350. this.setData({
  351. 'newData.free_iron_oxides': e.detail.value
  352. });
  353. },
  354. onInputDelta_pH: function(e) {
  355. this.setData({
  356. 'newData.Delta_pH': e.detail.value
  357. });
  358. },
  359. // 提交新增数据
  360. onSubmitAdd: function() {
  361. const newRow = this.data.newData;
  362. if (Object.values(newRow).some(value => !value)) {
  363. wx.showToast({
  364. title: '所有字段都必须填写!',
  365. icon: 'none'
  366. });
  367. return;
  368. }
  369. wx.request({
  370. url: 'http://localhost:5000/add_item',
  371. method: 'POST',
  372. header: {
  373. 'Content-Type': 'application/json'
  374. },
  375. data: {
  376. table: 'current_reflux',
  377. item: newRow
  378. },
  379. success: (res) => {
  380. if (res.data.success) {
  381. this.setData({
  382. rows: [...this.data.rows, newRow],
  383. showAddModal: false
  384. });
  385. wx.showToast({
  386. title: '新增成功',
  387. icon: 'success'
  388. });
  389. this.LoadData();
  390. } else {
  391. wx.showToast({
  392. title: '新增失败',
  393. icon: 'none'
  394. });
  395. }
  396. },
  397. fail: (err) => {
  398. wx.showToast({
  399. title: '请求失败,请重试',
  400. icon: 'none'
  401. });
  402. console.error('请求失败:', err);
  403. }
  404. });
  405. },
  406. // 取消新增数据
  407. onCancel: function() {
  408. this.setData({
  409. showAddModal: false
  410. });
  411. },
  412. // 编辑按钮点击
  413. onEdit: function(e) {
  414. const { index, row } = this.data.currentRow;
  415. console.log(row);
  416. // 检查 currentRow 是否有定义并且包含数据
  417. if (row) {
  418. this.setData({
  419. isEditing: true,
  420. showModal: false,
  421. showAddModal: true, // 显示编辑弹窗
  422. newData: row, // 将当前行的数据复制到 newData 中,以便在表单中显示
  423. currentRow: { index: index, row: row } // 保存当前行的信息,以便在提交时使用
  424. });
  425. } else {
  426. wx.showToast({
  427. title: '数据加载失败,请重试',
  428. icon: 'none'
  429. });
  430. }
  431. },
  432. // 提交编辑数据
  433. onSubmitEdit: function() {
  434. const updatedRow = this.data.newData;
  435. const { index } = this.data.currentRow;
  436. if (Object.values(updatedRow).some(value => !value)) {
  437. wx.showToast({
  438. title: '所有字段都必须填写!',
  439. icon: 'none'
  440. });
  441. return;
  442. }
  443. wx.request({
  444. url: 'http://localhost:5000/update_item',
  445. method: 'PUT',
  446. header: {
  447. 'Content-Type': 'application/json'
  448. },
  449. data: {
  450. table: 'current_reflux',
  451. item: updatedRow
  452. },
  453. success: (res) => {
  454. if (res.data.success) {
  455. // 更新成功后,更新前端数据
  456. let rows = this.data.rows;
  457. rows[index] = updatedRow; // 用更新后的数据替换旧数据
  458. this.setData({
  459. rows: rows,
  460. showAddModal: false // 关闭编辑弹窗
  461. });
  462. wx.showToast({
  463. title: '编辑成功',
  464. icon: 'success'
  465. });
  466. this.LoadData();
  467. } else {
  468. wx.showToast({
  469. title: '编辑失败',
  470. icon: 'none'
  471. });
  472. }
  473. },
  474. fail: (err) => {
  475. wx.showToast({
  476. title: '请求失败,请重试',
  477. icon: 'none'
  478. });
  479. console.error('请求失败:', err);
  480. }
  481. });
  482. },
  483. // 删除按钮点击
  484. onDelete: function() {
  485. const { index, row } = this.data.currentRow;
  486. console.log("当前选中行的数据:", this.data.currentRow);
  487. const condition = `id=${row.id}`; // 使用条件进行删除
  488. // 发送 DELETE 请求
  489. wx.request({
  490. url: 'http://127.0.0.1:5000/delete_item', // 后端接口地址
  491. method: 'POST', // 使用 POST 请求
  492. data: {
  493. table: 'current_reflux', // 目标表
  494. condition: condition // 删除条件
  495. },
  496. success: (res) => {
  497. if (res.data.success) {
  498. // 删除成功后,更新前端数据
  499. let rows = this.data.rows;
  500. rows.splice(index, 1); // 从数据中删除选中的行
  501. this.setData({
  502. rows: rows,
  503. showModal: false // 隐藏编辑删除弹窗
  504. });
  505. wx.showToast({
  506. title: '删除成功',
  507. icon: 'success'
  508. });
  509. // 重新获取数据
  510. this.LoadData(); // 重新加载数据
  511. } else {
  512. wx.showToast({
  513. title: '删除失败',
  514. icon: 'none'
  515. });
  516. }
  517. },
  518. fail: (err) => {
  519. wx.showToast({
  520. title: '请求失败,请重试',
  521. icon: 'none'
  522. });
  523. console.error('请求失败:', err);
  524. }
  525. });
  526. },
  527. onSubmit: function() {
  528. if (this.data.isEditing) {
  529. this.onSubmitEdit();
  530. } else {
  531. this.onSubmitAdd();
  532. }
  533. },
  534. // 取消编辑删除弹窗
  535. onCancel: function() {
  536. if (this.data.showModal) {
  537. this.setData({
  538. showModal: false
  539. });
  540. } else {
  541. this.setData({
  542. showAddModal: false
  543. });
  544. }
  545. },
  546. // 行点击事件:显示编辑和删除弹窗
  547. onRowClick: function(e) {
  548. const index = e.currentTarget.dataset.index;
  549. const row = e.currentTarget.dataset.row;
  550. this.setData({
  551. currentRow: { index: index, row: row },
  552. showModal: true // 显示编辑删除弹窗
  553. });
  554. }
  555. });