create.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  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 && deptName !== 'rh'"
  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 {
  283. createFault,
  284. getFailureApprovalList,
  285. getDeptName,
  286. } from "@/api/fault.js";
  287. import dayjs from "dayjs";
  288. import { uploadFile } from "@/api";
  289. import deviceSingle from "@/components/device/single.vue";
  290. import LocalSearch from "@/components/local-search.vue";
  291. import { useDataDictStore } from "@/store/modules/dataDict";
  292. const { getDataDictList } = useDataDictStore();
  293. // 引用全局变量$t
  294. const { appContext } = getCurrentInstance();
  295. const t = appContext.config.globalProperties.$t;
  296. const yesOrNoRange = ref([
  297. {
  298. value: 1,
  299. text: t("operation.yes"),
  300. },
  301. {
  302. value: 0,
  303. text: t("operation.no"),
  304. },
  305. ]);
  306. // 获取当前时间
  307. const now = dayjs().format("YYYY-MM-DD HH:mm:ss");
  308. const dateMax = ref(now);
  309. //故障详情
  310. const maintain = ref({
  311. deviceId: "",
  312. deviceName: "",
  313. picList: [], //用于上传照片 提交时删除
  314. });
  315. // 选择设备
  316. const deviceSingleRef = ref(null);
  317. const selectedDevices = ref([]);
  318. const onAddDevice = () => {
  319. deviceSingleRef.value.open();
  320. };
  321. let deptName = ref("");
  322. const onChooseDevice = (data) => {
  323. console.log("onChooseDevice", data);
  324. maintain.value.deviceId = data.id;
  325. maintain.value.deptId = data.deptId;
  326. maintain.value.deviceCode = data.deviceCode;
  327. maintain.value.deviceName = data.deviceName;
  328. console.log("onChooseDevice-maintain", maintain.value);
  329. getDeptName(data.id).then((res) => {
  330. console.log("🚀 ~ getDeptName>>>>>>>>>>>>>>>>>>>> ~ res:", res);
  331. deptName.value = res.data;
  332. });
  333. };
  334. // 上传图片
  335. const upload = async (event) => {
  336. for (const path of event.tempFilePaths) {
  337. maintain.value.pic = (await uploadFile(path)).data;
  338. }
  339. };
  340. // 是否解决
  341. const ifDealChange = (value) => {
  342. console.log("ifDealChange", value);
  343. maintain.value.ifDeal = value;
  344. if (value == 0) {
  345. maintain.value.needHelp = 1;
  346. } else {
  347. maintain.value.needHelp = 0;
  348. }
  349. };
  350. // 是否协助
  351. const needHelpChange = (value) => {
  352. maintain.value.needHelp = value;
  353. if (value == 1) {
  354. maintain.value.ifDeal = 0;
  355. } else {
  356. maintain.value.ifDeal = 1;
  357. }
  358. };
  359. // 审批人列表
  360. const approvalList = ref([]);
  361. const getApprovalList = async () => {
  362. const res = await getFailureApprovalList();
  363. approvalList.value = res.data.map((item) => ({
  364. value: item.id,
  365. text: item.nickname,
  366. }));
  367. };
  368. // 本地搜索
  369. const localSearchRef = ref(null);
  370. // 打开本地搜索
  371. const openLocalSearch = (list, propKey, title) => {
  372. localSearchRef.value.open({
  373. list,
  374. propKey,
  375. title,
  376. choosed: maintain.value[propKey],
  377. });
  378. };
  379. // 本地搜索确认选择
  380. const onChooseLocalSearch = (propKey, item) => {
  381. console.log("🚀 ~ onChooseLocalSearch ~ propKey, item:", propKey, item);
  382. // 根据propKey设置maintain的值
  383. maintain.value[propKey] = item.value;
  384. };
  385. const faultFormRef = ref(null);
  386. const maintainBaseRules = ref({
  387. deviceName: {
  388. rules: [
  389. {
  390. required: true,
  391. errorMessage: `${t("operation.PleaseSelect")}${t("device.deviceName")}`,
  392. },
  393. ],
  394. },
  395. ifDeal: {
  396. rules: [
  397. {
  398. required: true,
  399. errorMessage: `${t("operation.PleaseSelect")}${t(
  400. "workOrder.isSolved"
  401. )}`,
  402. },
  403. ],
  404. },
  405. needHelp: {
  406. rules: [
  407. {
  408. required: true,
  409. errorMessage: `${t("operation.PleaseSelect")}${t(
  410. "workOrder.Needassistance"
  411. )}`,
  412. },
  413. ],
  414. },
  415. failureSystem: {
  416. rules: [
  417. {
  418. required: true,
  419. errorMessage: `${t("operation.PleaseFillIn")}${t("fault.faultSystem")}`,
  420. },
  421. ],
  422. },
  423. failureTime: {
  424. rules: [
  425. {
  426. required: true,
  427. errorMessage: `${t("operation.PleaseSelect")}${t("fault.faultTime")}`,
  428. },
  429. ],
  430. },
  431. dealTime: {
  432. rules: [
  433. {
  434. required: false,
  435. errorMessage: `${t("operation.PleaseSelect")}${t(
  436. "fault.faultResolutionTime"
  437. )}`,
  438. },
  439. ],
  440. },
  441. solution: {
  442. rules: [
  443. {
  444. required: false,
  445. errorMessage: `${t("operation.PleaseFillIn")}${t("fault.solution")}`,
  446. },
  447. ],
  448. },
  449. approvalId: {
  450. rules: [
  451. {
  452. required: false,
  453. errorMessage: `${t("operation.PleaseSelect")}${t(
  454. "workOrder.approver"
  455. )}`,
  456. },
  457. ],
  458. },
  459. });
  460. // 动态计算校验规则
  461. const maintainRules = computed(() => {
  462. const rules = JSON.parse(JSON.stringify(maintainBaseRules.value));
  463. // 根据是否解决动态调整规则
  464. if (maintain.value.ifDeal === 0) {
  465. // 未解决:解决时间 解决办法非必填
  466. rules.dealTime.rules[0].required = false;
  467. rules.solution.rules[0].required = false;
  468. // 未解决:审批人必填
  469. rules.approvalId.rules[0].required = true;
  470. } else {
  471. // 已解决:故障时间 解决时间 解决办法必填
  472. rules.dealTime.rules[0].required = true;
  473. rules.solution.rules[0].required = true;
  474. // 已解决:审批人非必填
  475. rules.approvalId.rules[0].required = false;
  476. }
  477. return rules;
  478. });
  479. // 监听是否解决数据变化,触发规则更新和校验重置
  480. watch(
  481. () => maintain.value.ifDeal,
  482. (newVal, oldVal) => {
  483. console.log("是否解决变更:", oldVal, "->", newVal);
  484. // 是否解决为否, 获取审批人列表
  485. if (newVal == 0) {
  486. getApprovalList();
  487. }
  488. // 重置相关字段的值和校验状态
  489. resetFieldsByTypeChange(newVal, oldVal);
  490. }
  491. );
  492. // 根据是否解决变更重置字段
  493. const resetFieldsByTypeChange = (newType, oldType) => {
  494. // 如果是否解决没有变化或不是初始化阶段,则不执行重置
  495. if (newType === oldType && oldType !== undefined) return;
  496. // 清空故障解决时间和解决办法
  497. if (newType == 0) {
  498. maintain.value.dealTime = "";
  499. maintain.value.solution = "";
  500. // 重置审批人
  501. maintain.value.approvalId = "";
  502. }
  503. // 重置表单校验状态
  504. faultFormRef.value.clearValidate(["dealTime", "solution", "approvalId"]);
  505. };
  506. const formSubmit = async (formEl) => {
  507. if (!formEl) return;
  508. await formEl
  509. .validate()
  510. .then((res) => {
  511. console.log("success", res);
  512. // 当是否解决为是时,故障解决时间不能早于故障时间
  513. if (maintain.value.ifDeal === 1) {
  514. if (maintain.value.dealTime < maintain.value.failureTime) {
  515. uni.showToast({
  516. title: t("fault.timeNotBeEarlier"),
  517. icon: "none",
  518. });
  519. return;
  520. }
  521. }
  522. // 新建参数用于提交
  523. const submitMaintain = {
  524. ...maintain.value,
  525. // 是否解决,是否协助,是否停机更换成true/false
  526. ifDeal: maintain.value.ifDeal ? true : false,
  527. needHelp: maintain.value.needHelp ? true : false,
  528. ifStop: maintain.value.ifStop ? true : false,
  529. };
  530. // 删picList
  531. delete submitMaintain.picList;
  532. console.log("submitMaintain", submitMaintain);
  533. createFault({
  534. ...submitMaintain,
  535. })
  536. .then((res) => {
  537. console.log("createFault", res);
  538. if (res.code == 0) {
  539. uni.showToast({
  540. title: t("operation.success"),
  541. icon: "success",
  542. });
  543. uni.navigateBack();
  544. } else {
  545. uni.showToast({
  546. title: res.msg,
  547. icon: "none",
  548. });
  549. }
  550. })
  551. .catch((err) => {
  552. console.log("err", err);
  553. });
  554. })
  555. .catch((err) => {
  556. console.log("err", err);
  557. });
  558. };
  559. onMounted(() => {
  560. // 监听子页面提交的事件
  561. console.log("onMounted");
  562. uni.$on("inspection-falut", (data) => {
  563. console.log("接收到子页面数据:", data);
  564. onChooseDevice(data);
  565. });
  566. });
  567. onBeforeUnmount(() => {
  568. // 移除监听
  569. console.log("onBeforeUnmount");
  570. uni.$off("inspection-fault");
  571. });
  572. onLoad((option) => {
  573. console.log("falut-create-onLoad", option);
  574. });
  575. onReady(() => {
  576. // 设置自定义表单校验规则,必须在节点渲染完毕后执行
  577. // this.$refs.customForm.setRules(this.customRules)
  578. });
  579. onBackPress((options) => {
  580. // options.from 值为 'navigateBack' 时,表示返回是由 uni.navigateBack() 方法调用触发的
  581. // options.from 值为 'navigator' 时,表示返回是由导航栏返回按钮或物理返回键触发的
  582. console.log("返回触发来源:", options.from);
  583. });
  584. </script>
  585. <style lang="scss" scoped>
  586. @import "@/style/work-order-detail.scss";
  587. </style>