detail.vue 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  1. <template>
  2. <z-paging
  3. class="page"
  4. ref="paging"
  5. v-model="dataList"
  6. :loading-more-enabled="true"
  7. @query="queryList"
  8. >
  9. <!-- z-paging默认铺满全屏,此时页面所有view都应放在z-paging标签内,否则会被盖住 -->
  10. <!-- 需要固定在页面顶部的view请通过slot="top"插入,包括自定义的导航栏 -->
  11. <template #top>
  12. <!-- 工单基础信息 -->
  13. <view class="item top">
  14. <view class="item-content flex-row align-center">
  15. <view class="item-title full-cell flex-row align-center">
  16. <span class="item-title-width"
  17. >{{ $t("operationRecordFilling.workOrderName") }}:</span
  18. >
  19. <span>{{ params.orderName }}</span>
  20. </view>
  21. </view>
  22. <view class="item-content flex-row align-center">
  23. <view class="item-title full-cell flex-row align-center">
  24. <span class="item-title-width"
  25. >{{ $t("operationRecordFilling.responsiblePerson") }}:</span
  26. >
  27. <span>{{ params.userName }}</span>
  28. </view>
  29. </view>
  30. <view class="item-content flex-row align-center">
  31. <view class="item-title full-cell flex-row align-center">
  32. <span class="item-title-width"
  33. >{{ $t("operation.createTime") }}:</span
  34. >
  35. <span>{{ params.createTime }}</span>
  36. </view>
  37. </view>
  38. </view>
  39. </template>
  40. <!-- 填报列表 -->
  41. <view class="list">
  42. <view class="item" v-for="(item, index) in dataList" :key="index">
  43. <view class="item-module flex-row align-center justify-between">
  44. <view class="module-name">
  45. {{ item.deviceCode }}({{ item.deviceName }})
  46. </view>
  47. <view class="module-border"> </view>
  48. </view>
  49. <view class="item-content flex-row align-center justify-between bold">
  50. <view class="item-title flex-row align-center">
  51. <span>{{ $t("operationRecordFilling.belongToTeam") }}:</span>
  52. <span>{{ item.orgName }}</span>
  53. </view>
  54. </view>
  55. <view
  56. class="item-content flex-row align-center justify-between bold"
  57. v-for="sum in item.sumList"
  58. >
  59. <view class="item-title flex-row align-center word-break-all">
  60. <span>{{ sum.name }}:</span>
  61. </view>
  62. <view class="item-value flex-row align-center justify-end total">
  63. <uni-easyinput
  64. style="text-align: right"
  65. :inputBorder="false"
  66. :clearable="true"
  67. :styles="{ disableColor: '#fff' }"
  68. :value="`${sum.totalRunTime} ${
  69. sum.modelAttr ? (sum.modelAttr.includes('Time') ? 'h' : '') : ''
  70. }`"
  71. :disabled="true"
  72. ></uni-easyinput>
  73. </view>
  74. </view>
  75. <view
  76. class="item-content flex-col align-center justify-between"
  77. :class="{ 'bottom-bold': item.nonSumList.length > 0 }"
  78. v-for="nosum in item.nonSumList"
  79. >
  80. <!-- isCollection为1,提示:以下数值取自PLC,如有不符请修改 -->
  81. <uni-notice-bar
  82. :text="$t('operationRecordFilling.plcNotice')"
  83. v-if="nosum.isCollection == 1"
  84. />
  85. <view class="flex-row align-center justify-between item-content">
  86. <view class="item-title flex-row align-center">
  87. <span>{{ nosum.name }}:</span>
  88. </view>
  89. <!-- 判断填写项的属性 -->
  90. <!-- type为double时,输入框为数字类型 -->
  91. <view
  92. class="item-value flex-row align-center justify-end"
  93. v-if="nosum.type == 'double'"
  94. >
  95. <uni-easyinput
  96. style="text-align: right"
  97. :styles="{ disableColor: '#fff' }"
  98. :inputBorder="false"
  99. :clearable="true"
  100. :placeholder="$t('operation.PleaseFillIn')"
  101. :disabled="!isView"
  102. v-model="nosum.fillContent"
  103. :type="'digit'"
  104. @blur="
  105. nosum.threshold > 0
  106. ? checkThreshold(nosum)
  107. : checkLessThreshold(nosum)
  108. "
  109. @change="handleFillContentChange(nosum, item)"
  110. ></uni-easyinput>
  111. </view>
  112. <!-- type为textarea时,输入框为文本类型 -->
  113. <view
  114. class="item-value flex-row align-center justify-end"
  115. v-else-if="nosum.type == 'textarea'"
  116. >
  117. <uni-easyinput
  118. style="text-align: right"
  119. :styles="{ disableColor: '#fff' }"
  120. :inputBorder="false"
  121. :clearable="true"
  122. :placeholder="$t('operation.PleaseFillIn')"
  123. :disabled="!isView"
  124. v-model="nosum.fillContent"
  125. :type="'textarea'"
  126. :autoHeight="true"
  127. :maxlength="-1"
  128. ></uni-easyinput>
  129. </view>
  130. <!-- type为enum时,使用下拉菜单 -->
  131. <view
  132. class="item-value select flex-row align-center justify-end"
  133. v-else-if="nosum.type == 'enum' && nosum.description !== null"
  134. >
  135. <uni-data-select
  136. :localdata="nosum.enumList"
  137. style="text-align: right"
  138. :styles="{ disableColor: '#fff' }"
  139. :clear="false"
  140. :disabled="!isView"
  141. :placeholder="$t('operation.PleaseSelect')"
  142. v-model="nosum.fillContent"
  143. ></uni-data-select>
  144. </view>
  145. <!-- 其他类型时,输入框为文本类型 -->
  146. <view class="item-value flex-row align-center justify-end" v-else>
  147. <uni-easyinput
  148. style="text-align: right"
  149. :styles="{ disableColor: '#fff' }"
  150. :inputBorder="false"
  151. :clearable="true"
  152. :placeholder="$t('operation.PleaseFillIn')"
  153. :disabled="!isView"
  154. v-model="nosum.fillContent"
  155. :type="'text'"
  156. ></uni-easyinput>
  157. </view>
  158. </view>
  159. </view>
  160. </view>
  161. </view>
  162. <!-- 如果需要使用页脚,请使用slot="bottom"slot节点不支持通过v-if或v-show动态显示/隐藏,若需要动态控制,可将v-if添加在其子节点上 -->
  163. <template #bottom>
  164. <button
  165. style="border-radius: 0"
  166. type="primary"
  167. @click="onSubmit()"
  168. :disabled="dataList.length < totalNum"
  169. v-if="isView"
  170. >
  171. {{ $t("operation.save") }}
  172. </button>
  173. </template>
  174. </z-paging>
  175. </template>
  176. <script setup>
  177. import { ref, reactive, getCurrentInstance, watch, onMounted } from "vue";
  178. import { onReady, onLoad } from "@dcloudio/uni-app";
  179. import dayjs from "dayjs";
  180. import {
  181. getRecordFillingDetailGetPage,
  182. getRecordFillingDetailGetAttrs,
  183. recordFillingDetailInsertLog,
  184. getRecordFillingDetail,
  185. recordFillingUpOperationOrder,
  186. recordFillingDetailGetPageAndAttrs,
  187. recordFillingDetailInsertDataList,
  188. } from "@/api/recordFilling";
  189. import { getUserId, reloginByUserId } from "@/utils/auth.js";
  190. import { useDataDictStore } from "@/store/modules/dataDict";
  191. // 引用全局变量$t
  192. const { appContext } = getCurrentInstance();
  193. const t = appContext.config.globalProperties.$t;
  194. // 获取字典项
  195. const { getStrDictOptions, getIntDictOptions } = useDataDictStore();
  196. // -------------------------------------
  197. const isFromMsg = ref(false);
  198. const params = ref({});
  199. const isView = ref(false); // 是否编辑 -- view == 1为编辑状态
  200. onMounted(() => {
  201. console.log("onMounted");
  202. });
  203. onReady(() => {
  204. console.log("onReady");
  205. });
  206. onLoad(async (option) => {
  207. console.log("onLoad", option);
  208. await reloginByUserId(option.reloginUserId);
  209. isFromMsg.value = !!option.reloginUserId;
  210. // 初始化params
  211. params.value = JSON.parse(option.param);
  212. // 处理createTime
  213. params.value.createTime = params.value.createTime
  214. ? dayjs(Number.parseInt(params.value.createTime)).format("YYYY-MM-DD")
  215. : "";
  216. // 请求工单详情
  217. if (params.value?.orderId) {
  218. const detail = (await getRecordFillingDetail(params.value.orderId)).data;
  219. console.log("🚀getRecordFillingDetail ~ detail:", detail);
  220. params.value = {
  221. ...params.value,
  222. ...detail,
  223. // 处理createTime
  224. createTime: detail.createTime
  225. ? dayjs(Number.parseInt(detail.createTime)).format("YYYY-MM-DD")
  226. : "",
  227. orderId: detail.id,
  228. };
  229. }
  230. console.log("🚀 ~ params.value:", params.value);
  231. // 处理是否可编辑 {0: '待填写', 1: '已完成', 2: '填写中', 3: '忽略'}
  232. isView.value = params.value?.orderStatus % 2 == 0;
  233. console.log("🚀 ~ isView.value:", isView.value);
  234. });
  235. const paging = ref(null);
  236. // v-model绑定的这个变量不要在分页请求结束中自己赋值,直接使用即可
  237. const dataList = ref([]);
  238. // 列表总数
  239. const totalNum = ref(0);
  240. // 监听dataList变化,初始化时计算一次总和
  241. watch(
  242. dataList,
  243. (newVal) => {
  244. // calculateTotalRunTime();
  245. },
  246. { deep: true }
  247. );
  248. // 处理fillContent变化的方法
  249. const handleFillContentChange = (nosum, deviceItem) => {
  250. console.log("🚀 ~ nosum, deviceItem:", nosum, deviceItem);
  251. // 处理增压机
  252. if (
  253. deviceItem.deviceName.includes("增压机") &&
  254. nosum.name === "当日运转时间"
  255. ) {
  256. calculateTotalRunTime("增压机", "当日运转时间"); // 计算当日运转时间总和
  257. }
  258. // 处理提纯撬
  259. if (deviceItem.deviceName.includes("提纯撬") && nosum.name === "当日注气量") {
  260. calculateTotalRunTime("提纯撬", "当日注气量"); // 计算当日注气量总和
  261. }
  262. // 处理注水泵
  263. if (deviceItem.deviceName.includes("注水泵") && nosum.name === "当日注水量") {
  264. calculateTotalRunTime("注水泵", "当日注水量"); // 计算当日注水量总和
  265. }
  266. // 处理箱式变电站
  267. if (
  268. deviceItem.deviceName.includes("箱式变电站") &&
  269. nosum.name === "当日用电量"
  270. ) {
  271. calculateTotalRunTime("箱式变电站", "当日用电量"); // 计算当日用电量总和
  272. }
  273. };
  274. /**
  275. * 计算所有deviceName中包含deviceNameToMatch的对象中对应的reportName的fillContent总和并更新到reportName的fillContent中
  276. * @param deviceNameToMatch {string} 设备名称包含的字符串
  277. * @param reportName {string} 填写项名称
  278. */
  279. const calculateTotalRunTime = (deviceNameToMatch, reportName) => {
  280. console.log(
  281. "🚀calculateTotalRunTime ~ deviceNameToMatch, reportName:",
  282. deviceNameToMatch,
  283. 12
  284. );
  285. // 查找isReport为1的对象
  286. const reportItem = dataList.value.find((item) => item.isReport === 1);
  287. console.log("🚀calculateTotalRunTime ~ reportItem:", reportItem);
  288. if (!reportItem) return;
  289. /**
  290. * @param deviceNameToMatch {string} 设备名称包含的字符串
  291. * @param deviceName {string} 设备名称
  292. * @param reportName {string} 填写项名称
  293. * 查找[生产日报]中对应的填写项
  294. * reportName -> deviceName:reportName
  295. * 当日运转时间 -> 增压机:当日运转时间
  296. * 当日注气量 -> 提纯撬:当日注气量
  297. * 当日注水量 -> 注水泵:当日注水量
  298. * 当日用电量 -> 箱式变电站:当日用电量
  299. */
  300. const targetItem = reportItem.nonSumList.find(
  301. (item) => item.name === reportName
  302. );
  303. if (!targetItem) return;
  304. // 计算所有deviceName中包含deviceNameToMatch的对象中对应的reportName的fillContent总和
  305. let total = null;
  306. dataList.value.forEach((item) => {
  307. if (item.deviceName.includes(deviceNameToMatch) && item.nonSumList) {
  308. item.nonSumList.forEach((nonSum) => {
  309. // 只累加数字类型的值
  310. if (
  311. nonSum.type === "double" &&
  312. nonSum.fillContent &&
  313. nonSum.name === reportName
  314. ) {
  315. console.log("🚀 ~ nonSum.fillContent:", nonSum.fillContent);
  316. console.log("🚀 ~ nonSum:", nonSum);
  317. const value = Number(nonSum.fillContent) || 0;
  318. total += value;
  319. }
  320. });
  321. }
  322. });
  323. console.log("🚀 ~ total:", total);
  324. if (total !== null) {
  325. // 更新目标值,保留两位小数
  326. targetItem.fillContent = toFixed(total);
  327. console.log("🚀 ~ targetItem.fillContent:", targetItem.fillContent);
  328. }
  329. };
  330. // @query所绑定的方法不要自己调用!!需要刷新列表数据时,只需要调用paging.value.reload()即可
  331. const queryList = (pageNo, pageSize) => {
  332. const userId = uni.getStorageSync("userId");
  333. if (!userId) {
  334. paging.value.complete([]);
  335. return;
  336. }
  337. // 请求填报设备及属性
  338. recordFillingDetailGetPageAndAttrs({
  339. pageNo,
  340. pageSize,
  341. orderId: params.value.orderId,
  342. // deviceCategoryId: 1,
  343. })
  344. .then(async (res) => {
  345. console.log("🚀 ~ res:", res);
  346. const { data } = res;
  347. const resList = [].concat(data.list);
  348. // 列表总数
  349. totalNum.value = data.total;
  350. // 遍历列表,处理attrsDetail
  351. resList.map(async (item) => {
  352. const attrParams = {
  353. deviceCode: item.deviceCode,
  354. deviceName: item.deviceName,
  355. deptId: item.deptId,
  356. createTime: params.value.createTime,
  357. deviceCategoryId: item.deviceCategoryId,
  358. deviceId: item.deviceId,
  359. userId: params.value.userId,
  360. orderId: params.value.orderId,
  361. };
  362. // console.log(
  363. // "getRecordFillingDetailGetAttrs- attrParams",
  364. // attrParams
  365. // );
  366. const resAttrs = item?.attrsDetail;
  367. // console.log("resAttrs", resAttrs);
  368. if (resAttrs) {
  369. attrParams.createTime = attrParams.createTime
  370. ? dayjs(attrParams.createTime).format("YYYY-MM-DD")
  371. : "";
  372. attrParams.id = attrParams.orderId;
  373. delete attrParams.orderId;
  374. delete attrParams.deviceName;
  375. resAttrs.map((rtem) => {
  376. // 将rtem中sumList和nonSumList两个数组中的
  377. // fillContent字段判断是否为null, 如果为null,则赋值为0 不为null则保留两位小数
  378. // 将attrParams合并到两个数组的每个对象中
  379. // 然后将sumList和nonSumList分别赋值给item的sumList和nonSumList
  380. if (rtem.sumList) {
  381. rtem.sumList.map((sumItem) => {
  382. if (sumItem.fillContent == null || sumItem.fillContent == "") {
  383. // console.log("🚀 ~ rtem.sumList.map ~ sumItem:", sumItem);
  384. // sumItem.fillContent = 0;
  385. } else {
  386. // 如果是double类型,保留两位小数
  387. if (sumItem.type == "double") {
  388. sumItem.fillContent = toFixed(sumItem.fillContent);
  389. }
  390. }
  391. // 将sumItem的id赋值给modelId
  392. sumItem.modelId = sumItem.id;
  393. sumItem.pointName = sumItem.name;
  394. // 合并attrParams到sumItem中
  395. sumItem = Object.assign(sumItem, attrParams);
  396. });
  397. }
  398. if (rtem.nonSumList) {
  399. //
  400. rtem.nonSumList.map((nonSumItem) => {
  401. if (
  402. nonSumItem.fillContent == null ||
  403. nonSumItem.fillContent == ""
  404. ) {
  405. // console.log(
  406. // "🚀 ~ rtem.nonSumList.map ~ nonSumItem:",
  407. // nonSumItem
  408. // );
  409. // nonSumItem.fillContent = 0;
  410. } else {
  411. // 如果是double类型,保留两位小数
  412. if (nonSumItem.type == "double") {
  413. nonSumItem.fillContent = toFixed(nonSumItem.fillContent);
  414. }
  415. }
  416. nonSumItem.pointName = nonSumItem.name;
  417. // 将nonSumItem的id赋值给modelId
  418. nonSumItem.modelId = nonSumItem.id;
  419. // 合并attrParams到nonSumItem中
  420. nonSumItem = Object.assign(nonSumItem, attrParams);
  421. // 如果是enum类型,且description不为null,则根据description获取对应字典项数组,赋值给enumList
  422. if (nonSumItem.type == "enum" && nonSumItem.description) {
  423. console.log("🚀 ~ onSumItem.description:");
  424. nonSumItem.enumList =
  425. nonSumItem.name === "非生产原因"
  426. ? getIntDictOptions(nonSumItem.description).map(
  427. (dict) => {
  428. return {
  429. ...dict,
  430. text: dict.label,
  431. };
  432. }
  433. )
  434. : getStrDictOptions(nonSumItem.description).map(
  435. (dict) => {
  436. return {
  437. ...dict,
  438. text: dict.label,
  439. };
  440. }
  441. );
  442. console.log(
  443. "🚀 ~ nonSumItem.enumList:",
  444. nonSumItem.enumList
  445. );
  446. }
  447. });
  448. }
  449. item.sumList = rtem.sumList;
  450. item.nonSumList = rtem.nonSumList;
  451. });
  452. console.log("resAttrs-modelId", resAttrs);
  453. }
  454. return item;
  455. });
  456. console.log("resList--", resList);
  457. // 将请求结果通过complete传给z-paging处理,同时也代表请求结束,这一行必须调用
  458. paging.value.complete(resList);
  459. })
  460. .catch((res) => {
  461. // 如果请求失败写paging.value.complete(false);
  462. // 注意,每次都需要在catch中写这句话很麻烦,z-paging提供了方案可以全局统一处理
  463. // 在底层的网络请求抛出异常时,写uni.$emit('z-paging-error-emit');即可
  464. paging.value.complete(false);
  465. });
  466. };
  467. // 判断是否小于阈值 (<0)
  468. const checkLessThreshold = (item) => {
  469. if (item.fillContent < 0) {
  470. uni.showToast({
  471. title:
  472. item.name +
  473. t("operationRecordFilling.fillContentCannotLessThanThreshold") +
  474. "0",
  475. icon: "none",
  476. });
  477. item.fillContent = ""; // 清空输入
  478. return false; // 返回false表示校验失败
  479. }
  480. };
  481. // 判断是否大于阈值
  482. const checkThreshold = (item) => {
  483. checkLessThreshold(item);
  484. // 如果threshold > 0,则判断fillContent是否大于threshold,如果大于则提示用户填写小于等于threshold的值
  485. if (item.fillContent > item.threshold) {
  486. uni.showToast({
  487. title:
  488. item.name +
  489. t("operationRecordFilling.fillContentCannotGreaterThanThreshold") +
  490. item.threshold,
  491. icon: "none",
  492. });
  493. item.fillContent = ""; // 清空输入
  494. return false; // 返回false表示校验失败
  495. }
  496. };
  497. // 保留两位小数
  498. const toFixed = (num) => {
  499. if (num) {
  500. num = Number(num);
  501. num = num.toFixed(2);
  502. } else {
  503. num = 0.0;
  504. }
  505. return num;
  506. };
  507. const onSubmit = async () => {
  508. // console.log("onSubmit", dataList.value);
  509. // 校验是否所有待填写项都已加载
  510. if (dataList.value.length < totalNum) {
  511. uni.showToast({
  512. title: t("operationRecordFilling.PleaseLoadAllItems"),
  513. icon: "none",
  514. });
  515. return; // 校验失败直接返回
  516. }
  517. // 1. 校验所有必填项
  518. // 遍历dataList.value中nonSumList每个item(非生产日报 isReport!=1)的fillContent字段,
  519. // 如果为null或者为空,则提示用户填写,
  520. // 如果threshold > 0,则判断fillContent是否大于threshold,如果大于则提示用户填写小于等于threshold的值
  521. // 如果所有项全部填写,则调用填写记录接口
  522. for (const item of dataList.value) {
  523. const nonSumList = item.nonSumList;
  524. for (const nonSumItem of nonSumList) {
  525. if (
  526. (!item.isReport || item.isReport != 1) &&
  527. (nonSumItem.fillContent == null || nonSumItem.fillContent === "")
  528. ) {
  529. uni.showToast({
  530. title:
  531. t("operation.PleaseFillIn") +
  532. item.deviceCode +
  533. "(" +
  534. item.deviceName +
  535. ")" +
  536. t("operation.allItem"),
  537. icon: "none",
  538. });
  539. return; // 校验失败直接返回
  540. }
  541. if (nonSumItem.fillContent != "" && nonSumItem.fillContent != null) {
  542. console.log("🚀 ~ nonSumItem:", nonSumItem);
  543. console.log("🚀 ~ nonSumItem.fillContent:", nonSumItem.fillContent);
  544. // 先将值转换为字符串进行操作
  545. const fillContentStr = String(nonSumItem.fillContent);
  546. // 将字符串转换为数字
  547. const num = Number(fillContentStr);
  548. // 检查转换后的数字是否有效
  549. if (!isNaN(num)) {
  550. // 检查是否包含小数(使用字符串检查)
  551. if (fillContentStr.includes(".")) {
  552. // 保留两位小数(假设toFixed是你定义的保留两位小数的函数)
  553. nonSumItem.fillContent = toFixed(num);
  554. } else {
  555. // 转换为整数
  556. nonSumItem.fillContent = Math.floor(num);
  557. }
  558. }
  559. }
  560. // 如果threshold > 0,则判断fillContent是否大于threshold
  561. if (nonSumItem.threshold > 0) {
  562. if (nonSumItem.fillContent > nonSumItem.threshold) {
  563. uni.showToast({
  564. title:
  565. item.deviceCode +
  566. "(" +
  567. item.deviceName +
  568. ")" +
  569. nonSumItem.name +
  570. t(
  571. "operationRecordFilling.fillContentCannotGreaterThanThreshold"
  572. ) +
  573. nonSumItem.threshold,
  574. icon: "none",
  575. duration: 3000,
  576. });
  577. nonSumItem.fillContent = ""; // 清空输入
  578. return; // 校验失败直接返回
  579. }
  580. }
  581. }
  582. }
  583. // 定义新的dataList副本 用于提交数据,避免修改原数据
  584. const subDataList = JSON.parse(JSON.stringify(dataList.value));
  585. // 3. 处理副本:删除 enumList(仅修改副本,不影响原数据)
  586. for (const item of subDataList) {
  587. // 先判断 item.nonSumList 存在,避免空指针
  588. if (item.nonSumList && item.nonSumList.length) {
  589. for (const nonSumItem of item.nonSumList) {
  590. if (nonSumItem.enumList) {
  591. delete nonSumItem.enumList;
  592. }
  593. }
  594. }
  595. }
  596. console.log("处理提交用的副本数据:subDataList", subDataList);
  597. // 2. 处理提交数据:将nonSumList和sumList合并为新数组并赋值给deviceInfoList对象,将所有的deviceInfoList合并为submitList
  598. const submitList = subDataList.map((item) => ({
  599. deviceInfoList: [].concat(item.sumList).concat(item.nonSumList),
  600. }));
  601. console.log("提交用的数据:submitList", submitList);
  602. // 3. 提交所有填写记录
  603. await recordFillingDetailInsertDataList(submitList)
  604. .then(async (res) => {
  605. console.log("🚀 ~ 提交工单填报内容结果 ~ res:", res);
  606. if (res?.code === 0) {
  607. // 3. 调用更新工单状态接口
  608. const upRes = await recordFillingUpOperationOrder({
  609. id: params.value.orderId,
  610. });
  611. console.log("🚀 ~ upRes:", upRes);
  612. if (upRes?.code === 0) {
  613. console.log("工单状态更新成功");
  614. uni.showToast({
  615. title: t("operation.success"),
  616. duration: 1500,
  617. icon: "none",
  618. });
  619. setTimeout(() => {
  620. uni.navigateBack();
  621. }, 1500);
  622. } else {
  623. console.error("工单状态更新失败", upRes);
  624. uni.showToast({
  625. title: t("operation.fail"),
  626. icon: "none",
  627. });
  628. }
  629. } else {
  630. uni.showToast({
  631. title: t("operation.fail"),
  632. icon: "none",
  633. });
  634. }
  635. })
  636. .catch((error) => {
  637. console.error("保存失败", error);
  638. uni.showToast({
  639. title: t("operation.fail"),
  640. icon: "error",
  641. });
  642. });
  643. };
  644. </script>
  645. <style lang="scss" scoped>
  646. .page {
  647. padding: 0;
  648. box-sizing: border-box;
  649. }
  650. .top {
  651. padding: 10px;
  652. }
  653. .list {
  654. // margin-top: calc(10px);
  655. padding: 10px;
  656. // height: calc(100%);
  657. }
  658. .item {
  659. width: 100%;
  660. // height: 204px;
  661. background: #ffffff;
  662. border-radius: 6px;
  663. margin-bottom: 10px;
  664. box-sizing: border-box;
  665. padding: 20px 15px;
  666. }
  667. .item-module {
  668. width: 100%;
  669. height: 16px;
  670. position: relative;
  671. font-weight: 600;
  672. font-size: 14px;
  673. color: #333333;
  674. margin-bottom: 10px;
  675. .module-border {
  676. position: absolute;
  677. left: -15px;
  678. width: 0px;
  679. height: 12px;
  680. border: 1px solid #004098;
  681. }
  682. }
  683. .item-content {
  684. position: relative;
  685. width: 100%;
  686. // height: calc(38px);
  687. box-sizing: border-box;
  688. font-weight: 500;
  689. font-size: 14px;
  690. color: #333333;
  691. line-height: 20px;
  692. border-bottom: 1px dashed #cacccf;
  693. &:last-child {
  694. border-bottom: none;
  695. }
  696. &.bold {
  697. font-weight: 600;
  698. // :deep(.uni-easyinput__content-input){
  699. // padding-right: 0 !important;
  700. // }
  701. }
  702. &.bottom-bold {
  703. border-bottom: 1px dashed #cacccf;
  704. }
  705. }
  706. .item-title {
  707. position: relative;
  708. min-height: 38px;
  709. width: 55%;
  710. &.total {
  711. :deep(.is-disabled) {
  712. color: #333333 !important;
  713. }
  714. }
  715. &.full-cell {
  716. width: 100%;
  717. min-width: max-content;
  718. }
  719. }
  720. .item-value {
  721. width: 45%;
  722. position: relative;
  723. &.textarea {
  724. width: 65%;
  725. }
  726. }
  727. .word-break-all {
  728. min-width: unset;
  729. }
  730. :deep(.uni-select) {
  731. border: none;
  732. text-align: right;
  733. padding-right: 0;
  734. .uniui-bottom:before {
  735. content: "\e6b5" !important;
  736. font-size: 16px !important;
  737. }
  738. }
  739. :deep(.uni-select__input-text) {
  740. text-align: right;
  741. .align-left {
  742. text-align: right;
  743. }
  744. }
  745. :deep(.uni-select--disabled) {
  746. color: #d5d5d5 !important;
  747. background-color: transparent;
  748. .uni-select__input-text {
  749. color: #d5d5d5 !important;
  750. }
  751. }
  752. :deep(.uni-select__selector) {
  753. text-align: left;
  754. }
  755. :deep(.uni-select__selector-item) {
  756. border-bottom: 1px dashed #cacccf;
  757. text-align: left;
  758. }
  759. :deep(.uni-easyinput__content-textarea) {
  760. min-height: inherit;
  761. margin: 10px;
  762. }
  763. </style>