create.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. <template>
  2. <view class="page fault">
  3. <scroll-view scroll-y="true" class="detail">
  4. <view class="form-content">
  5. <uni-forms
  6. ref="faultFormRef"
  7. labelWidth="140px"
  8. :modelValue="maintain"
  9. :rules="maintainRules"
  10. >
  11. <!-- 设备 -->
  12. <uni-forms-item
  13. class="form-item"
  14. :label="$t('maintenanceWorkOrder.equipment')"
  15. name="deviceName"
  16. :required="true"
  17. >
  18. <uni-easyinput
  19. style="text-align: right"
  20. :inputBorder="false"
  21. :clearable="false"
  22. :styles="{ disableColor: '#fff' }"
  23. :placeholder="$t('operation.PleaseSelect')"
  24. v-model="maintain.deviceName"
  25. @focus="onAddDevice"
  26. />
  27. </uni-forms-item>
  28. <!-- 是否解决 -->
  29. <uni-forms-item
  30. class="form-item"
  31. :label="$t('workOrder.isSolved')"
  32. name="ifDeal"
  33. :required="true"
  34. >
  35. <uni-data-select
  36. :clear="false"
  37. v-model="maintain.ifDeal"
  38. :localdata="yesOrNoRange"
  39. @change="ifDealChange"
  40. >
  41. </uni-data-select>
  42. </uni-forms-item>
  43. <!-- 是否协助 -->
  44. <uni-forms-item
  45. class="form-item"
  46. :label="$t('workOrder.isHelp')"
  47. name="needHelp"
  48. :required="true"
  49. >
  50. <uni-data-select
  51. :clear="false"
  52. v-model="maintain.needHelp"
  53. :localdata="yesOrNoRange"
  54. @change="needHelpChange"
  55. >
  56. </uni-data-select>
  57. </uni-forms-item>
  58. <!-- 故障系统 -->
  59. <uni-forms-item
  60. class="form-item"
  61. :label="$t('fault.faultSystem')"
  62. name="failureSystem"
  63. :required="true"
  64. >
  65. <uni-easyinput
  66. style="text-align: right"
  67. :inputBorder="false"
  68. :clearable="true"
  69. :styles="{ disableColor: '#fff' }"
  70. v-model="maintain.failureSystem"
  71. :placeholder="$t('operation.PleaseFillIn')"
  72. />
  73. </uni-forms-item>
  74. <!-- 故障时间 -->
  75. <uni-forms-item
  76. class="form-item"
  77. :label="$t('fault.faultTime')"
  78. name="failureTime"
  79. :required="true"
  80. >
  81. <uni-datetime-picker
  82. type="datetime"
  83. :border="false"
  84. returnType="timestamp"
  85. :placeholder="$t('operation.PleaseSelect')"
  86. :style="{
  87. color: maintain.failureTime ? '#333' : '#999',
  88. 'font-size': maintain.failureTime
  89. ? '14px !important'
  90. : 'inherit !important',
  91. }"
  92. :end="dateMax"
  93. v-model="maintain.failureTime"
  94. >
  95. </uni-datetime-picker>
  96. </uni-forms-item>
  97. <!-- 故障解决时间 是否解决为是,是否协助为否时需要填写-->
  98. <uni-forms-item
  99. class="form-item"
  100. :label="$t('fault.faultResolutionTime')"
  101. name="dealTime"
  102. :required="true"
  103. v-if="maintain.ifDeal"
  104. >
  105. <!-- :end="dateMax" -->
  106. <uni-datetime-picker
  107. type="datetime"
  108. :border="false"
  109. returnType="timestamp"
  110. :placeholder="$t('operation.PleaseSelect')"
  111. :style="{
  112. color: maintain.dealTime ? '#333' : '#999',
  113. 'font-size': maintain.dealTime
  114. ? '14px !important'
  115. : 'inherit !important',
  116. }"
  117. :end="dateMax"
  118. v-model="maintain.dealTime"
  119. >
  120. </uni-datetime-picker>
  121. </uni-forms-item>
  122. <!-- 审批人 是否解决为否 时需要选择 -->
  123. <uni-forms-item
  124. class="form-item"
  125. :label="$t('workOrder.approver')"
  126. name="approvalId"
  127. :required="true"
  128. v-if="maintain.ifDeal == 0"
  129. >
  130. <uni-data-select
  131. :clear="false"
  132. :disabled="true"
  133. v-model="maintain.approvalId"
  134. :localdata="approvalList"
  135. @click="
  136. openLocalSearch(
  137. approvalList,
  138. 'approvalId',
  139. $t('workOrder.approver')
  140. )
  141. "
  142. >
  143. </uni-data-select>
  144. </uni-forms-item>
  145. <!-- 是否停机 -->
  146. <uni-forms-item
  147. class="form-item"
  148. :label="$t('equipmentMaintenance.isStop')"
  149. name="ifStop"
  150. :required="false"
  151. >
  152. <uni-data-select
  153. :clear="false"
  154. v-model="maintain.ifStop"
  155. :localdata="yesOrNoRange"
  156. >
  157. </uni-data-select>
  158. </uni-forms-item>
  159. <!-- 图片 -->
  160. <uni-forms-item
  161. class="form-item"
  162. :label="$t('general.picture')"
  163. name="picList"
  164. :required="false"
  165. >
  166. <uni-file-picker
  167. v-model="maintain.picList"
  168. file-mediatype="image"
  169. mode="grid"
  170. :auto-upload="false"
  171. :limit="1"
  172. :imageStyles="{ border: false }"
  173. :size-type="['compressed']"
  174. @select="upload"
  175. >
  176. <template #default>
  177. <view
  178. class="flex-col align-center justify-center"
  179. style="width: 60px; height: 60px; background-color: #f4f4f4"
  180. >
  181. <uni-icons type="plusempty" color="#ACACAC" size="12" />
  182. </view>
  183. </template>
  184. </uni-file-picker>
  185. </uni-forms-item>
  186. <!-- 故障影响 -->
  187. <uni-forms-item
  188. class="form-item"
  189. :label="$t('fault.faultImpact')"
  190. name="failureInfluence"
  191. :required="false"
  192. >
  193. <uni-easyinput
  194. style="text-align: right"
  195. :inputBorder="false"
  196. :clearable="true"
  197. :styles="{ disableColor: '#fff' }"
  198. v-model="maintain.failureInfluence"
  199. :placeholder="$t('operation.PleaseFillIn')"
  200. />
  201. </uni-forms-item>
  202. <!-- 解决办法 是否解决为是,是否协助为否时需要填写 -->
  203. <uni-forms-item
  204. class="form-item"
  205. :label="$t('fault.solution')"
  206. :required="true"
  207. name="solution"
  208. v-if="maintain.ifDeal"
  209. >
  210. <uni-easyinput
  211. style="text-align: right"
  212. type="textarea"
  213. :autoHeight="true"
  214. :inputBorder="false"
  215. :clearable="true"
  216. :styles="{ disableColor: '#fff' }"
  217. v-model="maintain.solution"
  218. :placeholder="$t('operation.PleaseFillIn')"
  219. />
  220. </uni-forms-item>
  221. <!-- 故障描述 -->
  222. <uni-forms-item
  223. class="form-item"
  224. :label="$t('fault.description')"
  225. :required="false"
  226. name="description"
  227. >
  228. <uni-easyinput
  229. style="text-align: right"
  230. type="textarea"
  231. :autoHeight="true"
  232. :inputBorder="false"
  233. :clearable="true"
  234. :styles="{ disableColor: '#fff' }"
  235. v-model="maintain.description"
  236. :placeholder="$t('operation.PleaseFillIn')"
  237. />
  238. </uni-forms-item>
  239. <!-- 备注 -->
  240. <uni-forms-item
  241. class="form-item"
  242. :label="$t('operation.remark')"
  243. :required="false"
  244. name="remark"
  245. >
  246. <uni-easyinput
  247. style="text-align: right"
  248. type="textarea"
  249. :autoHeight="true"
  250. :inputBorder="false"
  251. :clearable="true"
  252. :styles="{ disableColor: '#fff' }"
  253. v-model="maintain.remark"
  254. :placeholder="$t('operation.PleaseFillIn')"
  255. />
  256. </uni-forms-item>
  257. </uni-forms>
  258. </view>
  259. </scroll-view>
  260. <button class="submit-btn" type="primary" @click="formSubmit(faultFormRef)">
  261. {{ $t("operation.submit") }}
  262. </button>
  263. </view>
  264. <!-- 选择设备 单选 -->
  265. <device-single ref="deviceSingleRef" @devide-submit="onChooseDevice" />
  266. <!-- 本地搜索 (选择审批人) -->
  267. <local-search ref="localSearchRef" @choosed="onChooseLocalSearch" />
  268. </template>
  269. <script setup>
  270. import { onLoad, onReady, onBackPress } from "@dcloudio/uni-app";
  271. import {
  272. reactive,
  273. ref,
  274. watch,
  275. computed,
  276. watchEffect,
  277. onMounted,
  278. onBeforeUnmount,
  279. nextTick,
  280. getCurrentInstance,
  281. } from "vue";
  282. import { createFault, getFailureApprovalList } from "@/api/fault.js";
  283. import dayjs from "dayjs";
  284. import { uploadFile } from "@/api";
  285. import deviceSingle from "@/components/device/single.vue";
  286. import LocalSearch from "@/components/local-search.vue";
  287. import { useDataDictStore } from "@/store/modules/dataDict";
  288. const { getDataDictList } = useDataDictStore();
  289. // 引用全局变量$t
  290. const { appContext } = getCurrentInstance();
  291. const t = appContext.config.globalProperties.$t;
  292. const yesOrNoRange = ref([
  293. {
  294. value: 1,
  295. text: t("operation.yes"),
  296. },
  297. {
  298. value: 0,
  299. text: t("operation.no"),
  300. },
  301. ]);
  302. // 获取当前时间
  303. const now = dayjs().format("YYYY-MM-DD HH:mm:ss");
  304. const dateMax = ref(now);
  305. //故障详情
  306. const maintain = ref({
  307. deviceId: "",
  308. deviceName: "",
  309. picList: [], //用于上传照片 提交时删除
  310. });
  311. // 选择设备
  312. const deviceSingleRef = ref(null);
  313. const selectedDevices = ref([]);
  314. const onAddDevice = () => {
  315. deviceSingleRef.value.open();
  316. };
  317. const onChooseDevice = (data) => {
  318. console.log("onChooseDevice", data);
  319. maintain.value.deviceId = data.id;
  320. maintain.value.deptId = data.deptId;
  321. maintain.value.deviceCode = data.deviceCode;
  322. maintain.value.deviceName = data.deviceName;
  323. console.log("onChooseDevice-maintain", maintain.value);
  324. };
  325. // 上传图片
  326. const upload = async (event) => {
  327. for (const path of event.tempFilePaths) {
  328. maintain.value.pic = (await uploadFile(path)).data;
  329. }
  330. };
  331. // 是否解决
  332. const ifDealChange = (value) => {
  333. console.log("ifDealChange", value);
  334. maintain.value.ifDeal = value;
  335. if (value == 0) {
  336. maintain.value.needHelp = 1;
  337. } else {
  338. maintain.value.needHelp = 0;
  339. }
  340. };
  341. // 是否协助
  342. const needHelpChange = (value) => {
  343. maintain.value.needHelp = value;
  344. if (value == 1) {
  345. maintain.value.ifDeal = 0;
  346. } else {
  347. maintain.value.ifDeal = 1;
  348. }
  349. };
  350. // 审批人列表
  351. const approvalList = ref([]);
  352. const getApprovalList = async () => {
  353. const res = await getFailureApprovalList();
  354. approvalList.value = res.data.map((item) => ({
  355. value: item.id,
  356. text: item.nickname,
  357. }));
  358. };
  359. // 本地搜索
  360. const localSearchRef = ref(null);
  361. // 打开本地搜索
  362. const openLocalSearch = (list, propKey, title) => {
  363. localSearchRef.value.open({
  364. list,
  365. propKey,
  366. title,
  367. choosed: maintain.value[propKey],
  368. });
  369. };
  370. // 本地搜索确认选择
  371. const onChooseLocalSearch = (propKey, item) => {
  372. console.log("🚀 ~ onChooseLocalSearch ~ propKey, item:", propKey, item);
  373. // 根据propKey设置maintain的值
  374. maintain.value[propKey] = item.value;
  375. };
  376. const faultFormRef = ref(null);
  377. const maintainBaseRules = ref({
  378. deviceName: {
  379. rules: [
  380. {
  381. required: true,
  382. errorMessage: `${t("operation.PleaseSelect")}${t("device.deviceName")}`,
  383. },
  384. ],
  385. },
  386. ifDeal: {
  387. rules: [
  388. {
  389. required: true,
  390. errorMessage: `${t("operation.PleaseSelect")}${t(
  391. "workOrder.isSolved"
  392. )}`,
  393. },
  394. ],
  395. },
  396. needHelp: {
  397. rules: [
  398. {
  399. required: true,
  400. errorMessage: `${t("operation.PleaseSelect")}${t(
  401. "workOrder.Needassistance"
  402. )}`,
  403. },
  404. ],
  405. },
  406. failureSystem: {
  407. rules: [
  408. {
  409. required: true,
  410. errorMessage: `${t("operation.PleaseFillIn")}${t("fault.faultSystem")}`,
  411. },
  412. ],
  413. },
  414. failureTime: {
  415. rules: [
  416. {
  417. required: true,
  418. errorMessage: `${t("operation.PleaseSelect")}${t("fault.faultTime")}`,
  419. },
  420. ],
  421. },
  422. dealTime: {
  423. rules: [
  424. {
  425. required: false,
  426. errorMessage: `${t("operation.PleaseSelect")}${t(
  427. "fault.faultResolutionTime"
  428. )}`,
  429. },
  430. ],
  431. },
  432. solution: {
  433. rules: [
  434. {
  435. required: false,
  436. errorMessage: `${t("operation.PleaseFillIn")}${t("fault.solution")}`,
  437. },
  438. ],
  439. },
  440. approvalId: {
  441. rules: [
  442. {
  443. required: false,
  444. errorMessage: `${t("operation.PleaseSelect")}${t(
  445. "workOrder.approver"
  446. )}`,
  447. },
  448. ],
  449. },
  450. });
  451. // 动态计算校验规则
  452. const maintainRules = computed(() => {
  453. const rules = JSON.parse(JSON.stringify(maintainBaseRules.value));
  454. // 根据是否解决动态调整规则
  455. if (maintain.value.ifDeal === 0) {
  456. // 未解决:解决时间 解决办法非必填
  457. rules.dealTime.rules[0].required = false;
  458. rules.solution.rules[0].required = false;
  459. // 未解决:审批人必填
  460. rules.approvalId.rules[0].required = true;
  461. } else {
  462. // 已解决:故障时间 解决时间 解决办法必填
  463. rules.dealTime.rules[0].required = true;
  464. rules.solution.rules[0].required = true;
  465. // 已解决:审批人非必填
  466. rules.approvalId.rules[0].required = false;
  467. }
  468. return rules;
  469. });
  470. // 监听是否解决数据变化,触发规则更新和校验重置
  471. watch(
  472. () => maintain.value.ifDeal,
  473. (newVal, oldVal) => {
  474. console.log("是否解决变更:", oldVal, "->", newVal);
  475. // 是否解决为否, 获取审批人列表
  476. if (newVal == 0) {
  477. getApprovalList();
  478. }
  479. // 重置相关字段的值和校验状态
  480. resetFieldsByTypeChange(newVal, oldVal);
  481. }
  482. );
  483. // 根据是否解决变更重置字段
  484. const resetFieldsByTypeChange = (newType, oldType) => {
  485. // 如果是否解决没有变化或不是初始化阶段,则不执行重置
  486. if (newType === oldType && oldType !== undefined) return;
  487. // 清空故障解决时间和解决办法
  488. if (newType == 0) {
  489. maintain.value.dealTime = "";
  490. maintain.value.solution = "";
  491. // 重置审批人
  492. maintain.value.approvalId = "";
  493. }
  494. // 重置表单校验状态
  495. faultFormRef.value.clearValidate(["dealTime", "solution", "approvalId"]);
  496. };
  497. const formSubmit = async (formEl) => {
  498. if (!formEl) return;
  499. await formEl
  500. .validate()
  501. .then((res) => {
  502. console.log("success", res);
  503. // 当是否解决为是时,故障解决时间不能早于故障时间
  504. if (maintain.value.ifDeal === 1) {
  505. if (maintain.value.dealTime < maintain.value.failureTime) {
  506. uni.showToast({
  507. title: t("fault.timeNotBeEarlier"),
  508. icon: "none",
  509. });
  510. return;
  511. }
  512. }
  513. // 新建参数用于提交
  514. const submitMaintain = {
  515. ...maintain.value,
  516. // 是否解决,是否协助,是否停机更换成true/false
  517. ifDeal: maintain.value.ifDeal ? true : false,
  518. needHelp: maintain.value.needHelp ? true : false,
  519. ifStop: maintain.value.ifStop ? true : false,
  520. };
  521. // 删picList
  522. delete submitMaintain.picList;
  523. console.log("submitMaintain", submitMaintain);
  524. createFault({
  525. ...submitMaintain,
  526. })
  527. .then((res) => {
  528. console.log("createFault", res);
  529. if (res.code == 0) {
  530. uni.showToast({
  531. title: t("operation.success"),
  532. icon: "success",
  533. });
  534. uni.navigateBack();
  535. } else {
  536. uni.showToast({
  537. title: res.msg,
  538. icon: "none",
  539. });
  540. }
  541. })
  542. .catch((err) => {
  543. console.log("err", err);
  544. });
  545. })
  546. .catch((err) => {
  547. console.log("err", err);
  548. });
  549. };
  550. onMounted(() => {
  551. // 监听子页面提交的事件
  552. console.log("onMounted");
  553. uni.$on("inspection-falut", (data) => {
  554. console.log("接收到子页面数据:", data);
  555. onChooseDevice(data);
  556. });
  557. });
  558. onBeforeUnmount(() => {
  559. // 移除监听
  560. console.log("onBeforeUnmount");
  561. uni.$off("inspection-fault");
  562. });
  563. onLoad((option) => {
  564. console.log("falut-create-onLoad", option);
  565. });
  566. onReady(() => {
  567. // 设置自定义表单校验规则,必须在节点渲染完毕后执行
  568. // this.$refs.customForm.setRules(this.customRules)
  569. });
  570. onBackPress((options) => {
  571. // options.from 值为 'navigateBack' 时,表示返回是由 uni.navigateBack() 方法调用触发的
  572. // options.from 值为 'navigator' 时,表示返回是由导航栏返回按钮或物理返回键触发的
  573. console.log("返回触发来源:", options.from);
  574. });
  575. </script>
  576. <style lang="scss" scoped>
  577. @import "@/style/work-order-detail.scss";
  578. </style>