Visualization.js 15 KB

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