workOrderReport.vue 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295
  1. <template>
  2. <u-popup :show="visible" :round="0" :closeOnClickOverlay="false" :zIndex="99999" @close="closePopup"
  3. class="u-popup-my">
  4. <view class="popup-content">
  5. <view class="popup-header">
  6. <text class="popup-title">{{ title }}</text>
  7. <view class="close-btn" @click="closePopup">×</view>
  8. </view>
  9. <scroll-view class="popup-body" scroll-y>
  10. <view class="page">
  11. <view class="card-a">
  12. <!-- 头部 -->
  13. <view class="a-header">
  14. <text class="a-main-title">{{ form.ruleName }}</text>
  15. <view class="a-sub">
  16. <text>📋
  17. {{
  18. getDictValue("记录规则类型", form.recordRulesClassify)
  19. }}</text>
  20. </view>
  21. </view>
  22. <!-- 基本信息网格 -->
  23. <view class="info-grid">
  24. <view class="info-item">
  25. <text class="info-label">检查时间</text>
  26. <uni-datetime-picker type="datetime" v-model="form.checkStartTime"
  27. returnType="timestamp" :disabled="title == '详情'">
  28. <view class="info-value">{{
  29. form.checkStartTime&& dayjs(form.checkStartTime).format('YYYY-MM-DD HH:mm:ss')|| "请选择" }}</view>
  30. </uni-datetime-picker>
  31. </view>
  32. <view class="info-item">
  33. <text class="info-label">报工时间</text>
  34. <uni-datetime-picker type="datetime" v-model="form.checkFinishTime"
  35. :disabled="title == '详情'" returnType="timestamp">
  36. <view class="info-value">
  37. {{ form.checkFinishTime&& dayjs(form.checkFinishTime).format('YYYY-MM-DD HH:mm:ss')|| "请选择"}}
  38. </view>
  39. </uni-datetime-picker>
  40. </view>
  41. <view class="info-item" v-if="!form.type">
  42. <text class="info-label">部门</text>
  43. <view class="info-value" :class="{ disabled: title == '详情' }"
  44. @click="title != '详情' && $refs.treePicker._show()">{{ form.groupName || "请选择" }}
  45. </view>
  46. </view>
  47. <view class="info-item" v-if="!form.type">
  48. <text class="info-label">指定负责人</text>
  49. <view class="info-value" :class="{ disabled: title == '详情' }"
  50. @click="title != '详情' && $refs.selector.open()">{{
  51. form.executeUsers.map((item) => item.userName).toString() ||
  52. "请选择"
  53. }}</view>
  54. </view>
  55. <view class="info-item" v-if="form.type">
  56. <text class="info-label">班组</text>
  57. <view class="info-value">{{ form.teamName }}</view>
  58. </view>
  59. <view class="info-item" v-if="form.type">
  60. <text class="info-label">执行人</text>
  61. <view class="info-value" :class="{ disabled: title == '详情' }"
  62. @click="title != '详情' && $refs.selector.open()">{{
  63. form.executeUsers.map((item) => item.userName).toString() ||
  64. "请选择"
  65. }}</view>
  66. </view>
  67. <view class="info-item" v-if="form.type">
  68. <text class="info-label">场站</text>
  69. <view class="info-value" :class="{ disabled: title == '详情' }"
  70. @click="title != '详情' && (showProductLineIdPicker = true)">
  71. {{ form.productLineName || "请选择" }}
  72. </view>
  73. </view>
  74. <view class="info-item" v-if="pageName == 'productionRecords' || pageName == 'qualityTestRecords'
  75. "><text class="info-label">客户</text>
  76. <view class="info-value" :class="{ disabled: title == '详情' }"
  77. @click="title != '详情' && selectContactShow(17)">{{ form.contactName || "请选择" }}
  78. </view>
  79. </view>
  80. <view class="info-item"
  81. v-if="['QualityInspection', 'TransportAsh', 'HaulSlag'].includes(pageName)">
  82. <text class="info-label">供应商</text>
  83. <view class="info-value" :class="{ disabled: title == '详情' }"
  84. @click="title != '详情' && selectContactShow(19)">{{ form.supplierName || "请选择" }}
  85. </view>
  86. </view>
  87. <view class="info-item" v-if="
  88. ['QualityInspection', 'TransportAsh', 'HaulSlag'].includes(pageName)
  89. ">
  90. <text class="info-label">采购订单</text>
  91. <view class="info-value" :class="{ disabled: title == '详情' }" @click="openOrd">
  92. {{ form.purchaseOrderNo || "请选择" }}
  93. </view>
  94. </view>
  95. <view class="info-item" v-if="pageName == 'QualityInspection'">
  96. <text class="info-label">检查卸车是否到位</text>
  97. <view class="info-value" :class="{ disabled: title == '详情' }">
  98. <u-radio-group class="result-group" v-model="form.unloadCheckStatus"
  99. :disabled="title == '详情'">
  100. <u-radio label="已到位" :name="1"></u-radio>
  101. <u-radio label="未到位" :name="2"></u-radio>
  102. </u-radio-group>
  103. </view>
  104. </view>
  105. <view class="info-item" v-if="pageName == 'QualityInspection'">
  106. <view class="info-label" style="display: flex;align-items: center;">车辆照片 <u-button
  107. type="primary" style="width: 150rpx;margin-left: 10px;" size="small" text="拍照上传"
  108. v-if="title != '详情'" @click="chooseImage"></u-button>
  109. </view>
  110. </view>
  111. </view>
  112. <view style="padding-left: 30rpx;" v-if="pageName == 'QualityInspection'">
  113. <AlbumDeletable :urls="getUrl(form.vehiclePhotoUrl)" :singleSize="170" :multipleSize="170"
  114. :deletable="title != '详情'" @delete="handleDeleteImage"></AlbumDeletable>
  115. </view>
  116. <!-- 运行参数记录区 -->
  117. <view class="records-area">
  118. <view class="section-header">
  119. <view class="section-title">
  120. <text>📊 记录数据</text>
  121. </view>
  122. </view>
  123. <!-- 批量操作按钮放在标题下方 -->
  124. <view class="batch-bar" v-if="![
  125. 'qualityTestRecords',
  126. 'productionRecords',
  127. 'QualityInspection',
  128. 'HaulSlag',
  129. 'TransportAsh'
  130. ].includes(pageName) && title != '详情'">
  131. <button class="btn btn-primary" @click="batchCheck">
  132. ✅ 批量检查
  133. </button>
  134. <button class="btn btn-secondary" @click="batchQualified">
  135. 🏭 批量合格
  136. </button>
  137. </view>
  138. <!-- 检查项列表 -->
  139. <view v-for="(item, idx) in form.detailList" :key="idx" class="check-item-a">
  140. <view class="item-row1">
  141. <view class="item-info">
  142. <text class="item-name">{{ idx + 1 }}. {{ item.paramValue }}
  143. {{ item.unitName ? "(" + item.unitName + ")" : "" }}</text>
  144. </view>
  145. </view>
  146. <view class="item-row-input" v-if="item.substanceName">
  147. <text class="input-label">设备</text>
  148. <view class="item-input"> {{ item.substanceName }}</view>
  149. </view>
  150. <!-- 描述/数量 -->
  151. <view class="item-row-input">
  152. <text class="input-label">值</text>
  153. <input class="item-input" v-model="item.num" type="text" placeholder="请输入数量"
  154. @input="setValue" :disabled="title == '详情'" />
  155. </view>
  156. <view class="item-row-input" v-if="pageName == 'qualityTestRecords'">
  157. <text class="input-label">执行人</text>
  158. <view class="info-value" style="padding: 6px 10px; flex: 1; border-radius: 28rpx"
  159. :class="{ disabled: title == '详情' }"
  160. @click="title != '详情' && itemExecuteUsers(idx, item)">{{
  161. (item.checkUsers &&
  162. item.checkUsers
  163. .map((item) => item.userName)
  164. .toString()) ||
  165. "请选择"
  166. }}</view>
  167. </view>
  168. <view class="item-actions" v-if="![
  169. 'qualityTestRecords',
  170. 'productionRecords',
  171. 'QualityInspection',
  172. 'HaulSlag',
  173. 'TransportAsh'
  174. ].includes(pageName)">
  175. <u-radio-group class="result-group" v-model="item.checkStatus"
  176. :disabled="title == '详情'">
  177. <u-radio label="已检查" :name="1"></u-radio>
  178. <u-radio label="未检查" :name="0"></u-radio>
  179. </u-radio-group>
  180. <u-radio-group class="result-group" v-model="item.checkResult"
  181. :disabled="title == '详情'">
  182. <u-radio label="合格" :name="1"></u-radio>
  183. <u-radio label="不合格" :name="0"></u-radio>
  184. </u-radio-group>
  185. </view>
  186. </view>
  187. </view>
  188. </view>
  189. </view>
  190. </scroll-view>
  191. <view class="popup-footer">
  192. <u-button type="default" @click="closePopup">关闭</u-button>
  193. <u-button type="primary" @click="submit()" v-if="title == '报工'" :loading="loading">提交</u-button>
  194. </view>
  195. </view>
  196. <u-toast ref="uToast"></u-toast>
  197. <ba-tree-picker ref="treePicker" key="verify" :multiple="false" @select-change="searchDeptNodeClick"
  198. title="选择部门" :localdata="classificationList" valueKey="id" textKey="name" childrenKey="children" />
  199. <search-select :multiple="true" ref="selector" v-model="form.executeUsersIds" :data-list="
  200. executorList.map((val) => {
  201. return {
  202. text: val.name,
  203. value: val.id,
  204. };
  205. })
  206. " title="选择" @confirm="executeIdListChange">
  207. </search-select>
  208. <!-- 场站 -->
  209. <u-picker :show="showProductLineIdPicker" keyName="label" :columns="[
  210. productLineList.map((item) => {
  211. return {
  212. label: item.name,
  213. value: item.id,
  214. };
  215. }),
  216. ]" @confirm="confirmProductLine" @cancel="showProductLineIdPicker = false"></u-picker>
  217. <search-select :multiple="true" ref="selector1" v-model="checkUsersIds" :data-list="
  218. (form.executeUsers &&
  219. form.executeUsers.map((val) => {
  220. return {
  221. text: val.userName,
  222. value: val.userId,
  223. };
  224. })) ||
  225. []
  226. " title="选择" @confirm="executeIdListChange1">
  227. </search-select>
  228. <orderListDialog ref="orderListDialogRef" @changeParent="orderListDialogSuccess" :radioValue='true'></orderListDialog>
  229. </u-popup>
  230. </template>
  231. <script>
  232. const formBaseData = {
  233. id: null,
  234. workshopArea: "",
  235. workshopAreaId: null,
  236. checkFinishTime: "",
  237. checkStartTime: "",
  238. checkValidity: null,
  239. checkValidityUnit: "",
  240. checkValidityUnit: "",
  241. conclusion: null,
  242. detailList: [],
  243. deviceId: 0,
  244. deviceName: "",
  245. batchNo: "",
  246. executeMethod: 0,
  247. formingNum: 0,
  248. itemType: 0,
  249. produceRoutingId: 0,
  250. produceRoutingName: "",
  251. produceTaskConfigId: 0,
  252. produceTaskId: 0,
  253. produceTaskName: "",
  254. productCode: "",
  255. productModel: "",
  256. productName: "",
  257. recordRulesClassify: null,
  258. recordTemplateStyle: null,
  259. ruleId: 0,
  260. ruleName: "",
  261. reportWorkType: 0,
  262. specification: "",
  263. workOrderCode: "",
  264. workOrderId: 0,
  265. itemTaskName: "",
  266. brandNo: "",
  267. duration: null,
  268. // 执行人
  269. executeUsersIds: [],
  270. executeUsers: [],
  271. showProductLineIdPicker: false,
  272. // 班组id
  273. teamId: "",
  274. groupId: null,
  275. // 物料字段name
  276. pickDetails: [],
  277. // 本次产出明细
  278. outputDetails: [],
  279. recordRulesExecuteMethodId: null,
  280. recordRulesExecuteMethodName: "",
  281. // 产出类型 1-原材料,2-在制品,3.BOM标准产出
  282. outputType: 1,
  283. type: 0,
  284. contactName: "",
  285. contactId: "",
  286. supplierId: "",
  287. supplierName: "",
  288. productLineId: null,
  289. productLineName: "",
  290. unloadCheckStatus: '',
  291. vehiclePhotoUrl: [],
  292. purchaseOrderId: '',
  293. purchaseOrderNo: '',
  294. clientEnvironmentId: uni.getStorageSync("userInfo") &&
  295. uni.getStorageSync("userInfo").clientEnvironmentId,
  296. };
  297. import {
  298. getById,
  299. producetaskrulerecordSaveOrUpdateAndSubmit,
  300. } from "@/api/recordRules/index";
  301. import {
  302. getTeamPage
  303. } from "@/api/pda/workOrderHandover.js";
  304. import {
  305. getUserPage,
  306. listOrganizations
  307. } from "@/api/common.js";
  308. import {
  309. toTreeData
  310. } from "@/utils/utils.js";
  311. import {
  312. mapGetters
  313. } from "vuex";
  314. import searchSelect from "@/pages/salesServiceManagement/accessory/components/searchSelect.vue";
  315. import AlbumDeletable from "@/components/AlbumDeletable/AlbumDeletable.vue";
  316. import orderListDialog from './OrderListDialog.vue';
  317. import {
  318. getPurchaseOrderList
  319. } from '@/api/purchasingManage/index.js'
  320. import dayjs from 'dayjs'
  321. export default {
  322. data() {
  323. return {
  324. visible: false,
  325. executeUsersIds: [],
  326. imgs: [],
  327. title: "",
  328. loading: false,
  329. butLoading: false,
  330. checked: false,
  331. teamUserList: [],
  332. teamList: [],
  333. teamAllList: [],
  334. classificationList: [],
  335. showProductLineIdPicker: false,
  336. showCheckUsersIds: false,
  337. checkUsersIds: '',
  338. executorList: [],
  339. allTeamList: [],
  340. productLineList: [],
  341. dayjs,
  342. currentIndex: "",
  343. form: JSON.parse(JSON.stringify(formBaseData)),
  344. };
  345. },
  346. computed: {
  347. ...mapGetters(["getDictValue"]),
  348. },
  349. components: {
  350. searchSelect,
  351. AlbumDeletable,
  352. orderListDialog
  353. },
  354. props: {
  355. pageName: "",
  356. },
  357. methods: {
  358. async open(row, type) {
  359. uni.$off("setSelectList");
  360. uni.$on("setSelectList", (data) => {
  361. if (data && data.length > 0) {
  362. this.form.contactName = data[0].name;
  363. this.form.contactId = data[0].id;
  364. this.form.supplierName = data[0].name;
  365. this.form.supplierId = data[0].id;
  366. if (['QualityInspection', 'HaulSlag', 'TransportAsh'].includes(
  367. this.pageName
  368. )) {
  369. this.form.purchaseOrderId = ''
  370. this.form.purchaseOrderNo = ''
  371. //来煤获取采购订单
  372. getPurchaseOrderList({
  373. pageNum: 1,
  374. size: 999,
  375. orderStatus: 2,
  376. partbId: data[0].id
  377. }).then((res) => {
  378. if (res.list?.length == 1) {
  379. this.form.purchaseOrderId = res.list[0].id;
  380. this.form.purchaseOrderNo = res.list[0].orderNo;
  381. }
  382. });
  383. }
  384. }
  385. });
  386. if (type == "edit") {
  387. this.title = "报工";
  388. } else {
  389. this.title = "详情";
  390. }
  391. this.getTreeList();
  392. await this.getOrderDetials(row.id);
  393. this.visible = true;
  394. },
  395. cancel() {
  396. this.form = {
  397. ...JSON.parse(JSON.stringify(formBaseData)),
  398. };
  399. this.visible = false;
  400. },
  401. async getTreeList() {
  402. const data = await listOrganizations({});
  403. let treeList = toTreeData({
  404. data: data || [],
  405. idField: "id",
  406. parentIdField: "parentId",
  407. });
  408. this.classificationList = treeList;
  409. },
  410. selectContactShow(type) {
  411. uni.navigateTo({
  412. url: "/pages/saleManage/components/selectContact?isAll=" +
  413. false +
  414. "&contactType=" +
  415. type + '&code=' + this.getCode(),
  416. });
  417. },
  418. confirmProductLine(e) {
  419. this.form.productLineId = e.value[0].value;
  420. this.form.productLineName = e.value[0].label;
  421. this.showProductLineIdPicker = false;
  422. },
  423. closePopup() {
  424. this.cancel();
  425. },
  426. openOrd() {
  427. if (!this.form.supplierId) {
  428. this.$refs.uToast.show({
  429. type: "error",
  430. icon: false,
  431. message: `请先选择供应商!`,
  432. });
  433. return;
  434. }
  435. this.$refs.orderListDialogRef.open(
  436. this.form.supplierId,
  437. //渣和灰拿委外订单
  438. ['TransportAsh', 'HaulSlag'].includes(this.pageName) ?
  439. '3,4,5,6,7' :
  440. ''
  441. );
  442. },
  443. orderListDialogSuccess(data) {
  444. this.form.purchaseOrderId = data.id;
  445. this.form.purchaseOrderNo = data.orderNo;
  446. },
  447. getCode() {
  448. if (this.clientEnvironmentId == 10) {
  449. return this.pageName == 'QualityInspection' ?
  450. '06mei' :
  451. this.pageName == 'TransportAsh' ?
  452. '07lafei' :
  453. this.pageName == 'HaulSlag' ?
  454. '08lazha' :
  455. '';
  456. } else {
  457. return '';
  458. }
  459. },
  460. // 获取工单详情
  461. async getOrderDetials(id) {
  462. try {
  463. const data = await getById(id);
  464. data.detailList = data.detailList.map((i) => {
  465. i.toolNames = i.tools.map((j) => j.toolName).join(",");
  466. if (i.checkUsers && i.checkUsers.length > 0) {
  467. console.log("i.checkUsers", i.checkUsers);
  468. i.checkUsersIds = i.checkUsers.map((j) => j.userId);
  469. }
  470. if (
  471. (!i.checkUsersIds || i.checkUsersIds.length == 0) &&
  472. data.executeUsers.length > 0
  473. ) {
  474. // 默认执行人作为检查人
  475. i.checkUsersIds = data.executeUsers
  476. .filter((i) => i.userId)
  477. .map((j) => j.userId);
  478. i.checkUsers = data.executeUsers
  479. .filter((i) => i.userId)
  480. .map((j) => {
  481. return {
  482. teamId: j.teamId,
  483. teamName: j.teamName,
  484. userId: j.userId,
  485. userName: j.userName,
  486. };
  487. });
  488. }
  489. return i;
  490. });
  491. // this.$util.assignObject(this.form, data);
  492. Object.assign(this.form, data);
  493. this.form.vehiclePhotoUrl = this.form.vehiclePhotoUrl || [];
  494. this.form.unloadCheckStatus = this.form.unloadCheckStatus || 1;
  495. this.form.checkStartTime =
  496. this.form.checkStartTime ||
  497. dayjs(new Date()).format('YYYY-M-D HH:mm:ss');
  498. this.form.checkFinishTime =
  499. this.form.checkFinishTime ||
  500. dayjs(new Date()).format('YYYY-M-D HH:mm:ss');
  501. console.log(
  502. this.form.checkStartTime,
  503. 'this.form.checkStartTime'
  504. );
  505. this.form.executeUsersIds = this.form.executeUsers
  506. .map((i) => i.userId)
  507. .filter((i) => i); // 过滤掉 undefined
  508. if (this.form.executeUsers.length > 0 && !this.form.type) {
  509. this.form.groupId = this.form.executeUsers[0]?.groupId + "";
  510. this.form.groupName = this.form.executeUsers[0]?.groupName;
  511. if (this.form.groupId) {
  512. this.searchDeptNodeClick(
  513. this.form.groupId,
  514. this.form.groupName,
  515. "init",
  516. );
  517. }
  518. }
  519. if (!this.form.teamId && this.teamList.length > 0) {
  520. this.form.teamId = this.teamList[0].id;
  521. }
  522. this.form.recordRulesClassify += "";
  523. // 加载班组人员列表
  524. if (this.form.teamId && this.form.type) {
  525. await this.getAllTeamList();
  526. const index = this.allTeamList.findIndex(
  527. (item) => item.id == this.form.teamId,
  528. );
  529. this.executorList = this.allTeamList[index].userVOList;
  530. this.productLineList = [];
  531. this.allTeamList[index].factoryWorkstationVOList.forEach((item) => {
  532. if (
  533. !this.productLineList.find((p) => p.id === item.productionLineId)
  534. ) {
  535. this.productLineList.push({
  536. name: item.productionLineName,
  537. id: item.productionLineId,
  538. });
  539. }
  540. });
  541. }
  542. //宇信
  543. if (
  544. this.clientEnvironmentId == 10 && ['productionRecords',
  545. 'qualityTestRecords'
  546. ].includes(this.pageName)
  547. ) {
  548. //客户:5#和6#默认是重油公司7#默认是红山 2008389016775864321==7#
  549. if (this.form.productLineId == '2008389016775864321') {
  550. this.form.contactId =
  551. this.form.contactId || '2008562263580520449';
  552. this.form.contactName =
  553. this.form.contactName || '克拉玛依红山油田有限责任公司';
  554. } else {
  555. this.form.contactId =
  556. this.form.contactId || '2008383566202318850';
  557. this.form.contactName =
  558. this.form.contactName || '中国石油新疆油田分公司(重油公司)';
  559. }
  560. }
  561. this.setValue();
  562. this.$nextTick(() => {
  563. this.loading = false;
  564. });
  565. } catch (error) {
  566. console.log("error", error);
  567. this.loading = false;
  568. }
  569. },
  570. checkTeamList(id) {
  571. const index = this.teamList.findIndex((item) => item.id == id);
  572. this.teamUserList = this.teamAllList[index];
  573. this.form.teamName = this.teamList[index].name;
  574. console.log("this.teamUserList", this.teamUserList);
  575. },
  576. chooseImage() {
  577. const _this = this
  578. uni.chooseImage({
  579. count: 9, //默认9
  580. sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
  581. sourceType: ['camera'], //从相册选择
  582. success: function(res) {
  583. uni.showLoading({
  584. title: '加载中'
  585. })
  586. _this.uploadFile(res.tempFilePaths).then(res => {
  587. res.forEach(item => {
  588. let fileNames = item.storePath.split('/')
  589. let url =
  590. '/main/file/getFile?objectName=' + item.storePath +
  591. '&fullfilename=' + fileNames[fileNames.length -
  592. 1]
  593. _this.form.vehiclePhotoUrl.push(url)
  594. })
  595. uni.hideLoading()
  596. })
  597. }
  598. });
  599. },
  600. getUrl(arr) {
  601. console.log(arr, 'arr')
  602. if (arr.length) {
  603. return arr.map(item => {
  604. return this.apiUrl + item
  605. })
  606. } else {
  607. return []
  608. }
  609. },
  610. uploadFile(list) {
  611. let PromiseAll = []
  612. const apiUrl = this.apiUrl
  613. const token = uni.getStorageSync("token"); //取存本地的token
  614. list.forEach(item => {
  615. PromiseAll.push(
  616. new Promise((resolve, reject) => {
  617. uni.uploadFile({
  618. url: apiUrl + '/main/file/upload',
  619. filePath: item,
  620. name: 'multiPartFile',
  621. header: {
  622. authorization: token
  623. },
  624. success: (uploadFileRes) => {
  625. let data = JSON.parse(uploadFileRes.data)
  626. resolve(data.data)
  627. }
  628. });
  629. }),
  630. )
  631. })
  632. return Promise.all(PromiseAll)
  633. },
  634. setValue() {
  635. if (this.title == '报工') {
  636. this.form.detailList.forEach((item, index) => {
  637. if (this.pageName == 'qualityTestRecords') {
  638. let num1 = this.form.detailList.find(
  639. (item1) => item1.paramValue == '给水量'
  640. )?.num;
  641. let num2 = this.form.detailList.find(
  642. (item1) => item1.paramValue == '炉水量'
  643. )?.num;
  644. let num = 0;
  645. if (num1 && num2) {
  646. num = (num2 - num1) / num2;
  647. }
  648. if (item.paramValue == '干度') {
  649. this.$set(
  650. this.form.detailList[index],
  651. 'num',
  652. parseFloat(num.toFixed(5)) * 100
  653. );
  654. }
  655. if (item.paramValue == '是否合格' && num1) {
  656. this.$set(
  657. this.form.detailList[index],
  658. 'num',
  659. parseFloat(num.toFixed(5)) * 100 >= 90 ? '合格' : '不合格'
  660. );
  661. }
  662. }
  663. if (this.pageName == 'productionRecords') {
  664. let num1 = this.form.detailList.find(
  665. (item1) => item1.paramValue == '日用水量'
  666. )?.num;
  667. let num = 0;
  668. if (num1) {
  669. num = num1 * 0.1034;
  670. }
  671. if (item.paramValue == '日用煤量') {
  672. this.$set(
  673. this.form.detailList[index],
  674. 'num',
  675. parseFloat(num.toFixed(5))
  676. );
  677. }
  678. }
  679. });
  680. }
  681. },
  682. handleDeleteImage(index) {
  683. this.form.vehiclePhotoUrl.splice(index, 1);
  684. },
  685. // 批量检查
  686. batchCheck() {
  687. this.form.detailList.forEach((i, index) => {
  688. this.$set(this.form.detailList[index], "checkStatus", 1);
  689. });
  690. },
  691. // 批量合格
  692. batchQualified() {
  693. this.form.detailList.forEach((i, index) => {
  694. this.$set(this.form.detailList[index], "checkResult", 1);
  695. });
  696. },
  697. itemExecuteUsers(index, row) {
  698. this.currentIndex = index;
  699. this.$refs.selector1.open();
  700. },
  701. executeIdListChange1() {
  702. this.$set(
  703. this.form.detailList[this.currentIndex],
  704. "checkUsersIds",
  705. this.checkUsersIds,
  706. );
  707. const checkUsersIds = this.checkUsersIds;
  708. this.checkUsersIds = [];
  709. const checkUsers = checkUsersIds.map((i) => {
  710. const user = this.form.executeUsers.find((item) => item.userId === i);
  711. return user;
  712. });
  713. console.log(checkUsers, "checkUsers");
  714. this.$set(
  715. this.form.detailList[this.currentIndex],
  716. "checkUsers",
  717. checkUsers,
  718. );
  719. },
  720. // 获取审核人列表、巡点检人员
  721. async getUserList(params) {
  722. try {
  723. let data = {
  724. pageNum: 1,
  725. size: -1,
  726. };
  727. // 如果传了参数就是获取部门人员数据
  728. if (params) {
  729. data = Object.assign(data, params);
  730. }
  731. const res = await getUserPage(data);
  732. if (params) {
  733. this.executorList = res.list;
  734. }
  735. } catch (error) {}
  736. },
  737. //选择部门(搜索)
  738. async searchDeptNodeClick(id, name, type) {
  739. this.form.groupId = id;
  740. this.form.groupName = name;
  741. if (id) {
  742. // 根据部门获取人员
  743. const params = {
  744. groupId: id,
  745. };
  746. await this.getUserList(params);
  747. } else {
  748. this.form.groupId = null;
  749. }
  750. if (type != "init") {
  751. this.form.detailList.forEach((detail) => {
  752. detail.checkUsersIds = [];
  753. detail.checkUsers = [];
  754. });
  755. this.form.executeUsers = [];
  756. this.form.executeUsersIds = [];
  757. }
  758. },
  759. // 负责人变更 同步执行人列表
  760. executeIdListChange() {
  761. console.log(this.form.executeUsersIds, "this.form.executeUsersIds");
  762. this.form.executeUsers = this.form.executeUsersIds
  763. .map((userId) => {
  764. const user = this.executorList.find((u) => u.id === userId);
  765. if (!user) return null;
  766. return {
  767. userId: user.id,
  768. userName: user.name,
  769. groupId: user.groupId,
  770. groupName: user.groupName,
  771. };
  772. })
  773. .filter((i) => i);
  774. // 同步详情执行人
  775. this.form.detailList.forEach((detail, index) => {
  776. this.$set(
  777. this.form.detailList[index],
  778. "checkUsersIds",
  779. this.form.executeUsersIds,
  780. );
  781. this.$set(
  782. this.form.detailList[index],
  783. "checkUsers",
  784. this.form.executeUsers,
  785. );
  786. });
  787. console.log("this.form.executeUsers", this.form.detailList);
  788. },
  789. async getAllTeamList() {
  790. const {
  791. list
  792. } = await getTeamPage({
  793. pageNum: 1,
  794. size: -1,
  795. });
  796. console.log("teamAllList 班组", list);
  797. this.allTeamList = list;
  798. },
  799. // 提交
  800. async submit() {
  801. // 验证检查时间和报工时间必填
  802. if (!this.form.checkStartTime) {
  803. this.$refs.uToast.show({
  804. type: "error",
  805. icon: false,
  806. message: `请选择检查时间`,
  807. });
  808. return;
  809. }
  810. if (!this.form.checkFinishTime) {
  811. this.$refs.uToast.show({
  812. type: "error",
  813. icon: false,
  814. message: `请选择报工时间`,
  815. });
  816. return;
  817. }
  818. // if (this.pageName == 'steamInjectionInspectionRecord' && !this.form.contactName) {
  819. // this.$refs.uToast.show({
  820. // type: "error",
  821. // icon: false,
  822. // message: `请选择甲方检查人!`,
  823. // });
  824. // return;
  825. // }
  826. // if (this.pageName == 'solidWasteRecord' && !this.form.supplierName) {
  827. // this.$refs.uToast.show({
  828. // type: "error",
  829. // icon: false,
  830. // message: `请选择处理方!`,
  831. // });
  832. // return;
  833. // }
  834. // 验证报工时间必须大于等于检查时间
  835. const startTime = new Date(this.form.checkStartTime).getTime();
  836. const finishTime = new Date(this.form.checkFinishTime).getTime();
  837. if (finishTime < startTime) {
  838. this.$refs.uToast.show({
  839. type: "error",
  840. icon: false,
  841. message: `报工时间不能早于检查时间`,
  842. });
  843. return;
  844. }
  845. if (this.form.executeUsersIds.length == 0) {
  846. this.$refs.uToast.show({
  847. type: "error",
  848. icon: false,
  849. message: `请选择执行人`,
  850. });
  851. return;
  852. }
  853. if (![
  854. 'qualityTestRecords',
  855. 'productionRecords',
  856. 'QualityInspection',
  857. 'HaulSlag',
  858. 'TransportAsh'
  859. ].includes(this.pageName)) {
  860. // 验证检查项目
  861. const detailRequired = this.form.detailList.some((i) => {
  862. return i.checkResult == null || i.checkStatus == null;
  863. });
  864. if (detailRequired) {
  865. this.$refs.uToast.show({
  866. type: "error",
  867. icon: false,
  868. message: `请先完善、检查情况、检查结果`,
  869. });
  870. return;
  871. }
  872. }
  873. this.form.checkStartTime = dayjs(this.form.checkStartTime).format('YYYY-MM-DD HH:mm:ss')
  874. this.form.checkFinishTime = dayjs(this.form.checkFinishTime).format('YYYY-MM-DD HH:mm:ss')
  875. const body = JSON.parse(JSON.stringify(this.form));
  876. try {
  877. await producetaskrulerecordSaveOrUpdateAndSubmit(body);
  878. this.$emit("refresh");
  879. this.closePopup();
  880. } catch (error) {
  881. console.log(error, "dsdsd");
  882. }
  883. },
  884. },
  885. };
  886. </script>
  887. <style scoped lang="scss">
  888. .popup-content {
  889. width: 100vw;
  890. height: calc(100vh - 100px);
  891. background: #fff;
  892. border-radius: 0;
  893. display: flex;
  894. background-color: #eff2f7;
  895. flex-direction: column;
  896. }
  897. .popup-header {
  898. display: flex;
  899. justify-content: space-between;
  900. align-items: center;
  901. padding: 30rpx;
  902. border-bottom: 1rpx solid #e5e5e5;
  903. .popup-title {
  904. font-size: 36rpx;
  905. font-weight: bold;
  906. color: #333;
  907. }
  908. .close-btn {
  909. width: 60rpx;
  910. height: 60rpx;
  911. display: flex;
  912. align-items: center;
  913. justify-content: center;
  914. font-size: 60rpx;
  915. color: #999;
  916. line-height: 1;
  917. }
  918. }
  919. .popup-body {
  920. flex: 1;
  921. overflow-y: auto;
  922. padding: 28rpx;
  923. }
  924. .page {
  925. font-family:
  926. system-ui,
  927. -apple-system,
  928. "Segoe UI",
  929. Roboto,
  930. Helvetica,
  931. sans-serif;
  932. }
  933. .design-section {
  934. /* margin-bottom: 60rpx; */
  935. }
  936. .design-header {
  937. margin-bottom: 20rpx;
  938. padding-left: 8rpx;
  939. }
  940. .design-title {
  941. font-size: 44rpx;
  942. font-weight: 800;
  943. color: #1f2b3c;
  944. display: block;
  945. }
  946. .design-desc {
  947. font-size: 26rpx;
  948. color: #6b7280;
  949. margin-top: 6rpx;
  950. }
  951. /* 卡片白色风格 */
  952. .card-a {
  953. background: #ffffff;
  954. border-radius: 48rpx;
  955. box-shadow: 0 12rpx 40rpx rgba(0, 0, 0, 0.05);
  956. overflow: hidden;
  957. }
  958. .a-header {
  959. padding: 40rpx 32rpx 24rpx;
  960. border-bottom: 2rpx solid #f0f2f5;
  961. }
  962. .a-main-title {
  963. font-size: 36rpx;
  964. font-weight: 800;
  965. background: linear-gradient(135deg, #1f2b3c, #2c3e50);
  966. background-clip: text;
  967. -webkit-background-clip: text;
  968. color: transparent;
  969. letter-spacing: -0.5rpx;
  970. }
  971. .a-sub {
  972. font-size: 24rpx;
  973. color: #8e9aae;
  974. margin-top: 12rpx;
  975. display: flex;
  976. gap: 24rpx;
  977. }
  978. .info-grid {
  979. padding: 30rpx 32rpx;
  980. display: grid;
  981. grid-template-columns: 1fr 1fr;
  982. gap: 28rpx 20rpx;
  983. // background: #fcfdfe;
  984. border-bottom: 2rpx solid #f0f2f5;
  985. }
  986. .info-item {
  987. display: flex;
  988. flex-direction: column;
  989. gap: 8rpx;
  990. }
  991. .info-label {
  992. font-size: 26rpx;
  993. font-weight: 600;
  994. color: #6c7a91;
  995. text-transform: uppercase;
  996. }
  997. .records-area {
  998. padding: 16rpx 28rpx 32rpx;
  999. }
  1000. .section-header {
  1001. display: flex;
  1002. justify-content: space-between;
  1003. align-items: center;
  1004. margin: 16rpx 0 20rpx 8rpx;
  1005. }
  1006. .section-title {
  1007. font-size: 36rpx;
  1008. font-weight: 700;
  1009. color: #1f2a44;
  1010. display: flex;
  1011. align-items: center;
  1012. gap: 16rpx;
  1013. }
  1014. .badge {
  1015. background: #eff3fa;
  1016. padding: 6rpx 20rpx;
  1017. border-radius: 60rpx;
  1018. font-size: 24rpx;
  1019. font-weight: normal;
  1020. color: #2c5f8a;
  1021. }
  1022. .device-card-a {
  1023. background: #f8fbfe;
  1024. border-radius: 36rpx;
  1025. padding: 20rpx 24rpx;
  1026. margin-bottom: 30rpx;
  1027. display: flex;
  1028. align-items: center;
  1029. justify-content: space-between;
  1030. flex-wrap: wrap;
  1031. border: 2rpx solid #e9edf2;
  1032. }
  1033. .device-label {
  1034. font-weight: 700;
  1035. font-size: 28rpx;
  1036. color: #1f2a44;
  1037. background: #eff3fa;
  1038. padding: 8rpx 24rpx;
  1039. border-radius: 60rpx;
  1040. }
  1041. .device-input-a {
  1042. flex: 1;
  1043. min-width: 280rpx;
  1044. background: #ffffff;
  1045. border: 2rpx solid #dce3ec;
  1046. border-radius: 36rpx;
  1047. padding: 16rpx 24rpx;
  1048. font-size: 28rpx;
  1049. }
  1050. .check-item-a {
  1051. background: #ffffff;
  1052. border-radius: 36rpx;
  1053. padding: 24rpx 24rpx;
  1054. margin-bottom: 24rpx;
  1055. box-shadow:
  1056. 0 4rpx 16rpx rgba(0, 0, 0, 0.02),
  1057. 0 0 0 2rpx #edf2f7;
  1058. }
  1059. .item-row1 {
  1060. display: flex;
  1061. justify-content: space-between;
  1062. align-items: baseline;
  1063. flex-wrap: wrap;
  1064. margin-bottom: 20rpx;
  1065. gap: 16rpx;
  1066. }
  1067. .item-name {
  1068. font-weight: 620;
  1069. font-size: 30rpx;
  1070. color: #1f2a44;
  1071. background: #f5f7fb;
  1072. padding: 6rpx 20rpx;
  1073. border-radius: 50rpx;
  1074. }
  1075. .item-info {
  1076. display: flex;
  1077. flex-direction: column;
  1078. gap: 8rpx;
  1079. }
  1080. .item-row-input {
  1081. display: flex;
  1082. align-items: center;
  1083. gap: 16rpx;
  1084. margin-bottom: 20rpx;
  1085. padding: 0 8rpx;
  1086. }
  1087. .input-label {
  1088. font-size: 28rpx;
  1089. color: #555;
  1090. font-weight: 500;
  1091. white-space: nowrap;
  1092. }
  1093. .item-input {
  1094. // background: #f8fafe;
  1095. border: 2rpx solid #e2e8f0;
  1096. border-radius: 36rpx;
  1097. padding: 12rpx 24rpx;
  1098. font-size: 30rpx;
  1099. min-height: 60rpx;
  1100. flex: 1;
  1101. font-family: monospace;
  1102. }
  1103. .item-actions {
  1104. display: flex;
  1105. justify-content: space-between;
  1106. align-items: center;
  1107. flex-wrap: wrap;
  1108. gap: 20rpx;
  1109. }
  1110. .check-status,
  1111. .result-group {
  1112. display: flex;
  1113. align-items: center;
  1114. gap: 24rpx;
  1115. background: #f8fafe;
  1116. padding: 8rpx 24rpx;
  1117. border-radius: 60rpx;
  1118. font-size: 28rpx;
  1119. }
  1120. /deep/.result-group {
  1121. .u-radio__text {
  1122. font-size: 28rpx !important;
  1123. }
  1124. .u-radio__icon-wrap {
  1125. width: 30rpx !important;
  1126. height: 30rpx !important;
  1127. }
  1128. }
  1129. .radio-label {
  1130. display: flex;
  1131. align-items: center;
  1132. gap: 8rpx;
  1133. }
  1134. .batch-bar {
  1135. display: flex;
  1136. gap: 16rpx;
  1137. margin: 16rpx 0 20rpx 8rpx;
  1138. }
  1139. .btn {
  1140. flex: 1;
  1141. text-align: center;
  1142. border-radius: 80rpx;
  1143. font-weight: 700;
  1144. font-size: 30rpx;
  1145. border: none;
  1146. }
  1147. .btn-primary {
  1148. background: #1e6f5c;
  1149. color: white;
  1150. box-shadow: 0 4rpx 12rpx rgba(30, 111, 92, 0.2);
  1151. }
  1152. .btn-secondary {
  1153. background: #2c7da0;
  1154. color: white;
  1155. }
  1156. .footnote {
  1157. font-size: 22rpx;
  1158. color: #8e9aab;
  1159. text-align: center;
  1160. margin-top: 16rpx;
  1161. display: block;
  1162. }
  1163. /* 修复组件样式 */
  1164. radio,
  1165. checkbox {
  1166. transform: scale(0.9);
  1167. margin-right: 6rpx;
  1168. }
  1169. button:after {
  1170. border: none;
  1171. }
  1172. .info-value {
  1173. font-size: 28rpx;
  1174. font-weight: 500;
  1175. color: #1e2a3a;
  1176. // background: #f2f5f9;
  1177. padding: 16rpx 20rpx;
  1178. border-radius: 24rpx;
  1179. border: 2rpx solid #e9edf2;
  1180. &.disabled {
  1181. color: #999;
  1182. background: #f5f5f5;
  1183. }
  1184. }
  1185. .popup-footer {
  1186. display: flex;
  1187. padding: 20rpx 30rpx;
  1188. border-top: 1rpx solid #e5e5e5;
  1189. gap: 20rpx;
  1190. /deep/ .u-button {
  1191. flex: 1;
  1192. }
  1193. }
  1194. /deep/.uni-select {
  1195. border-radius: 36rpx;
  1196. }
  1197. </style>