mp_rcXcdjl_excelZxxzAdd.html 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta
  6. name="viewport"
  7. content="width=device-width, initial-scale=1.0, user-scalable=no"
  8. />
  9. <title>校长巡查</title>
  10. <script src="/js/mp_base/base.js"></script>
  11. </head>
  12. <body>
  13. <div id="app" v-cloak>
  14. <!-- 加载状态 -->
  15. <div v-if="loading" class="loading-container">
  16. <div class="loading-spinner"></div>
  17. <div class="loading-text">加载中...</div>
  18. </div>
  19. <!-- 校长巡查表单 -->
  20. <div v-else class="form-container" style="padding-top: 12px">
  21. <!-- 循环遍历巡查点数据 -->
  22. <div
  23. v-for="(item, index) in xunchaList"
  24. :key="item.xcdid"
  25. class="xuncha-section"
  26. >
  27. <div class="section-title">{{ item.xcdmc }}</div>
  28. <table class="xuncha-table">
  29. <tr>
  30. <th>情况描述</th>
  31. <td style="position: relative">
  32. <ss-input
  33. v-model="formData[`xcd_${index}`].qkms"
  34. :name="`xcd_${index}_qkms`"
  35. placeholder="请输入情况描述"
  36. :required="true"
  37. />
  38. </td>
  39. </tr>
  40. <tr>
  41. <th>处理描述</th>
  42. <td style="position: relative">
  43. <ss-input
  44. v-model="formData[`xcd_${index}`].clms"
  45. :name="`xcd_${index}_clms`"
  46. placeholder="请输入处理描述"
  47. :required="true"
  48. />
  49. </td>
  50. </tr>
  51. <tr>
  52. <th>责任人</th>
  53. <td style="position: relative">
  54. <ss-input
  55. v-model="formData[`xcd_${index}`].zrr"
  56. :name="`xcd_${index}_zrr`"
  57. placeholder="请输入责任人"
  58. :required="true"
  59. />
  60. </td>
  61. </tr>
  62. </table>
  63. </div>
  64. </div>
  65. <!-- 使用SsBottom组件 -->
  66. <ss-bottom
  67. :show-shyj="false"
  68. :buttons="bottomButtons"
  69. @button-click="handleBottomAction"
  70. :disabled="submitting"
  71. />
  72. </div>
  73. <script>
  74. SS.ready(function () {
  75. window.SS.dom.initializeFormApp({
  76. el: "#app",
  77. data() {
  78. return {
  79. // 加载状态
  80. loading: true,
  81. submitting: false,
  82. // 巡查数据
  83. xunchaList: [],
  84. formData: {},
  85. // 页面参数
  86. rcid: 521185, // 写死,后续会从小程序传过来
  87. // 底部按钮
  88. bottomButtons: [
  89. { text: "取消", action: "cancel" },
  90. { text: "保存并提交", action: "submit" },
  91. ],
  92. };
  93. },
  94. mounted() {
  95. // 页面加载时初始化数据
  96. this.initPage();
  97. },
  98. methods: {
  99. // 初始化页面数据
  100. async initPage() {
  101. try {
  102. // console.log('🔄 开始加载巡查数据...');
  103. // 获取URL参数
  104. const urlParams = this.getUrlParams();
  105. // 调用初始化接口
  106. const response = await request.post(
  107. `/service?ssToken=${urlParams.ssToken}`,
  108. {},
  109. { loading: false }
  110. );
  111. console.log("✅ 巡查数据加载成功:", response);
  112. if (response && response.data.ssData) {
  113. // console.log('✅ 巡查数据加载成功:', response.data.ssData);
  114. // 使用新格式的数据结构
  115. this.initFormData(response.data.ssData.xcdjlList);
  116. // 如果需要,可以使用返回的rcid
  117. if (response.data.ssData.rcid) {
  118. this.rcid = response.data.ssData.rcid;
  119. }
  120. }
  121. } catch (error) {
  122. console.log("❌ 加载巡查数据失败:", error);
  123. } finally {
  124. this.loading = false;
  125. }
  126. },
  127. // 初始化表单数据
  128. initFormData(xunchaData) {
  129. console.log("🔧 初始化表单数据:", xunchaData);
  130. // 保存巡查点列表
  131. this.xunchaList = xunchaData || [];
  132. // 初始化表单数据
  133. const newFormData = {};
  134. this.xunchaList.forEach((item, index) => {
  135. const areaKey = `xcd_${index}`;
  136. newFormData[areaKey] = {
  137. qkms: item.qkms || "",
  138. clms: item.clms || "",
  139. zrr: item.zrr || "",
  140. };
  141. });
  142. this.formData = newFormData;
  143. console.log("✅ 表单数据初始化完成:", this.formData);
  144. // 初始化校验规则
  145. this.$nextTick(() => {
  146. this.initValidationRules();
  147. });
  148. },
  149. // 获取URL参数
  150. getUrlParams() {
  151. const params = {};
  152. const urlSearchParams = new URLSearchParams(
  153. window.location.search
  154. );
  155. for (const [key, value] of urlSearchParams) {
  156. params[key] = decodeURIComponent(value);
  157. }
  158. return params;
  159. },
  160. // 显示提示
  161. showToast(message, type = "info") {
  162. // 这里可以使用SS框架的提示组件
  163. console.log(`${type.toUpperCase()}: ${message}`);
  164. // 临时使用alert
  165. window.showToast(message);
  166. },
  167. // 初始化ssVm校验规则
  168. initValidationRules() {
  169. console.log("🔧 初始化ssVm校验规则...");
  170. // 为每个巡查点添加校验规则
  171. this.xunchaList.forEach((item, index) => {
  172. const prefix = `xcd_${index}`;
  173. const areaName = item.xcdmc;
  174. // 情况描述校验 - 使用required选项
  175. ssVm.add("notNull", [`${prefix}_qkms`], {
  176. msgPrfx: `${areaName}的情况描述`,
  177. required: true,
  178. });
  179. // 处理描述校验
  180. ssVm.add("notNull", [`${prefix}_clms`], {
  181. msgPrfx: `${areaName}的处理描述`,
  182. required: true,
  183. });
  184. // 责任人校验
  185. ssVm.add("notNull", [`${prefix}_zrr`], {
  186. msgPrfx: `${areaName}的责任人`,
  187. required: true,
  188. });
  189. });
  190. console.log("✅ ssVm校验规则初始化完成");
  191. },
  192. // 处理底部按钮点击
  193. handleBottomAction(data) {
  194. console.log("底部按钮操作:", data);
  195. switch (data.action) {
  196. case "cancel":
  197. this.handleCancel();
  198. break;
  199. case "submit":
  200. this.handleSubmit();
  201. break;
  202. }
  203. },
  204. // 处理取消操作 - 使用bridge.js的goBack方法
  205. handleCancel() {
  206. // 使用bridge.js提供的goBack方法
  207. NavigationManager.goBack({ refreshParent: true });
  208. },
  209. // 获取URL参数
  210. getUrlParams() {
  211. const params = {};
  212. const urlSearchParams = new URLSearchParams(
  213. window.location.search
  214. );
  215. for (const [key, value] of urlSearchParams) {
  216. params[key] = decodeURIComponent(value);
  217. }
  218. return params;
  219. },
  220. // 处理提交操作
  221. async handleSubmit() {
  222. if (this.submitting) return;
  223. try {
  224. this.submitting = true;
  225. console.log("📝 开始提交表单...");
  226. // 校验表单
  227. if (!this.validateForm()) {
  228. return;
  229. }
  230. // 构建提交数据(模拟JSP表单格式)
  231. const submitData = this.buildSubmitData();
  232. console.log("📤 提交数据:", submitData);
  233. // 调用提交接口
  234. const response = await request.post(
  235. "/service?ssServ=rcXcdjl_excelSaveAddByZxxz&ssDest=info",
  236. submitData,
  237. {
  238. loading: false,
  239. formData: true, // 使用表单格式提交,数组会被展开为多个同名参数
  240. }
  241. );
  242. console.log("✅ 提交成功:", response);
  243. this.showToast("提交成功!", "success");
  244. // 延迟返回
  245. setTimeout(() => {
  246. this.returnToHome();
  247. }, 1500);
  248. } catch (error) {
  249. console.error("❌ 提交失败:", error);
  250. this.showToast("提交失败", "error");
  251. } finally {
  252. this.submitting = false;
  253. }
  254. },
  255. // 校验表单 - 使用项目的ValidationManager
  256. validateForm() {
  257. console.log("🔍 使用ssVm校验表单数据...");
  258. // 使用ValidationManager的validateAll方法
  259. const result = ssVm.validateAll();
  260. if (!result.valid) {
  261. console.log("❌ 表单校验失败:", result.errors);
  262. // ValidationManager会自动显示错误信息
  263. return false;
  264. }
  265. console.log("✅ 表单校验通过");
  266. return true;
  267. },
  268. // 构建提交数据(JSP格式)
  269. buildSubmitData() {
  270. const submitData = {
  271. // 隐藏字段
  272. rcid: this.rcid,
  273. requestParentViewObject: "rc",
  274. // 巡查点数据 - 使用JSP中的字段名格式
  275. xcdid: [],
  276. xcdjlid: [],
  277. qkms: [],
  278. clms: [],
  279. zrr: [],
  280. };
  281. // 填充数组数据(按JSP中的格式)
  282. this.xunchaList.forEach((item, index) => {
  283. submitData.xcdid.push(item.xcdid);
  284. submitData.xcdjlid.push(item.xcdjlid || "null");
  285. submitData.qkms.push(this.formData[`xcd_${index}`].qkms);
  286. submitData.clms.push(this.formData[`xcd_${index}`].clms);
  287. submitData.zrr.push(this.formData[`xcd_${index}`].zrr);
  288. });
  289. return submitData;
  290. },
  291. // 2025-12-08 修改 by xu:提交成功后回到小程序首页
  292. returnToHome() {
  293. console.log("🏠 退出小程序")
  294. wx.miniProgram.reLaunch({
  295. url: "/pages/main/index"
  296. })
  297. },
  298. // 显示提示
  299. showToast(message, type = "info") {
  300. console.log(`${type.toUpperCase()}: ${message}`);
  301. // 使用浏览器原生alert,后续可以替换为更好的提示组件
  302. alert(message);
  303. },
  304. },
  305. });
  306. });
  307. </script>
  308. <style>
  309. /* 防止Vue模板闪烁 */
  310. [v-cloak] {
  311. display: none !important;
  312. }
  313. /* 加载状态样式 */
  314. .loading-container {
  315. display: flex;
  316. flex-direction: column;
  317. align-items: center;
  318. justify-content: center;
  319. height: 200px;
  320. color: #666;
  321. }
  322. .loading-spinner {
  323. width: 40px;
  324. height: 40px;
  325. border: 4px solid #f3f3f3;
  326. border-top: 4px solid #40ac6d;
  327. border-radius: 50%;
  328. animation: spin 1s linear infinite;
  329. margin-bottom: 15px;
  330. }
  331. @keyframes spin {
  332. 0% {
  333. transform: rotate(0deg);
  334. }
  335. 100% {
  336. transform: rotate(360deg);
  337. }
  338. }
  339. .loading-text {
  340. font-size: 14px;
  341. }
  342. /* 巡查区域样式 */
  343. .xuncha-section {
  344. margin-bottom: 20px;
  345. /* border: 1px solid #e0e0e0; */
  346. /* border-radius: 8px; */
  347. overflow: hidden;
  348. }
  349. .section-title {
  350. /* background: #f5f5f5; */
  351. padding: 12px 0;
  352. font-weight: bold;
  353. font-size: 16px;
  354. color: #333;
  355. /* border-bottom: 1px solid #e0e0e0; */
  356. }
  357. .xuncha-table {
  358. width: 100%;
  359. border-collapse: collapse;
  360. }
  361. .xuncha-table th {
  362. background: #fafafa;
  363. padding: 12px 15px;
  364. text-align: left;
  365. font-weight: normal;
  366. color: #666;
  367. border-bottom: 1px solid #e0e0e0;
  368. width: 100px;
  369. }
  370. .xuncha-table td {
  371. padding: 12px 15px;
  372. border-bottom: 1px solid #e0e0e0;
  373. }
  374. /* .xuncha-table tr:last-child th,
  375. .xuncha-table tr:last-child td {
  376. border-bottom: none;
  377. } */
  378. /* 表单容器样式 */
  379. .form-container {
  380. padding: 15px;
  381. padding-bottom: 45px;
  382. background: #fff;
  383. min-height: calc(100vh - 100px);
  384. }
  385. </style>
  386. </body>
  387. </html>