index.vue 74 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580
  1. <template>
  2. <div class="index_box">
  3. <div class="content_box">
  4. <div class="content_box_tab">
  5. <div class="task-toolbar">
  6. <el-input
  7. class="task-filter-input"
  8. clearable
  9. v-model="name"
  10. placeholder="请输入筛选项"
  11. @input="seekInput"
  12. />
  13. <div class="task-toolbar-actions">
  14. <el-button type="text" @click="updataTaskList">刷新</el-button>
  15. <el-button type="text" @click="sortTaskList">排序</el-button>
  16. </div>
  17. </div>
  18. <el-tabs
  19. v-model="activeName"
  20. type="card"
  21. stretch
  22. @tab-click="tabClickValue"
  23. >
  24. <el-tab-pane label="工单" name="0">
  25. <div class="custom-tree-node">
  26. <el-tree
  27. :data="produceTaskList"
  28. :props="defaultProps"
  29. node-key="id"
  30. :highlight-current="true"
  31. @node-click="handleNodeClick"
  32. ref="taskListRef"
  33. :key="treeKey"
  34. >
  35. <span class="custom-tree-node" slot-scope="{ node, data }">
  36. <span>{{ node.label }}</span>
  37. <span
  38. style="color: red; font-weight: 700"
  39. v-if="data.number != '0' && data.number"
  40. >({{ data.number >= 100 ? '99+' : data.number }})</span
  41. >
  42. </span>
  43. </el-tree>
  44. </div>
  45. </el-tab-pane>
  46. <el-tab-pane label="任务" name="1">
  47. <div class="custom-tree-node">
  48. <el-tree
  49. :data="produceTaskList"
  50. :props="defaultProps"
  51. node-key="id"
  52. :highlight-current="true"
  53. @node-click="handleNodeClick"
  54. ref="taskListRef"
  55. :key="treeKey"
  56. >
  57. <span class="custom-tree-node" slot-scope="{ node, data }">
  58. <span>{{ node.label }}</span>
  59. <span
  60. style="color: red; font-weight: 700"
  61. v-if="data.number != '0' && data.number"
  62. >({{ data.number >= 100 ? '99+' : data.number }})</span
  63. >
  64. </span>
  65. </el-tree>
  66. </div>
  67. </el-tab-pane>
  68. </el-tabs>
  69. </div>
  70. <div style="width: calc(100% - 220px)">
  71. <div class="seek-list" style="background-color: #157a2c">
  72. <div>
  73. <el-input
  74. style="width: 180px; margin-right: 5px"
  75. clearable
  76. v-model="keyWord"
  77. placeholder="请输入关键字"
  78. @clear="handleSearch"
  79. />
  80. <el-button
  81. size="mini"
  82. type="primary"
  83. style="margin: 0 5px"
  84. @click="handleSearch"
  85. >查询</el-button
  86. >
  87. <template>
  88. <el-popover
  89. placement="top-start"
  90. width="200"
  91. trigger="hover"
  92. content="支持工单编码,产品编码,产品名称,产品规格,牌号,型号,批次号查询。"
  93. >
  94. <i
  95. class="el-icon-question"
  96. slot="reference"
  97. style="color: #40a9ff; font-size: 14px"
  98. ></i> </el-popover
  99. ></template>
  100. </div>
  101. <div
  102. style="
  103. width: 55%;
  104. color: #fff;
  105. display: flex;
  106. justify-content: space-between;
  107. "
  108. >
  109. <div>
  110. <b style="margin-right: 50px">当前工序:{{ title }}</b>
  111. <b>下道工序:{{ title1 }}</b>
  112. </div>
  113. <div> 操作员:{{ info.name }} </div>
  114. </div>
  115. </div>
  116. <ele-split-layout
  117. space="0px"
  118. width="45%"
  119. :resizable="true"
  120. :min-size="200"
  121. :max-size="-200"
  122. :left-style="{
  123. overflow: 'hidden',
  124. width: '100%'
  125. }"
  126. :responsive="false"
  127. style="height: calc(100vh - 70px - 50px - 90px)"
  128. >
  129. <!-- 左侧 工单列表 -->
  130. <div class="left_main">
  131. <div class="top">
  132. <!-- /工单列表 -->
  133. <produceOrder
  134. v-if="produceTaskList.length != 0 && activeName == '0'"
  135. @workSelect="workSelect"
  136. @rowClick="rowClick"
  137. ref="produceOrder"
  138. @getTaskName="getTaskName"
  139. :produceTaskInfo="produceTaskInfo"
  140. >
  141. </produceOrder>
  142. <!-- 任务列表 -->
  143. <task-work-list
  144. v-if="produceTaskList.length != 0 && activeName == '1'"
  145. @taskSelect="taskSelect"
  146. @rowTaskClick="rowTaskClick"
  147. ref="produceOrder"
  148. @getTaskName="getTaskName"
  149. :produceTaskInfo="produceTaskInfo"
  150. >
  151. </task-work-list>
  152. </div>
  153. </div>
  154. <!-- 右侧 详情 -->
  155. <template v-slot:content>
  156. <div class="right_main">
  157. <work-order-detail-preview
  158. v-if="showWorkOrderDetailPreview"
  159. :key="previewWorkOrderDetailKey"
  160. :work-order-info="previewWorkOrderInfo"
  161. />
  162. <template v-else>
  163. <!-- 领料 -->
  164. <div v-if="operationType == 'pick' && activeName == '0'">
  165. <pickDetails
  166. ref="pickListRef"
  167. :workTaskId="workTaskId"
  168. :taskId="taskObj.id"
  169. @pickAdd="pickAdd"
  170. ></pickDetails>
  171. </div>
  172. <div v-if="operationType == 'feed' && activeName == '0'">
  173. <!-- 投料 -->
  174. <feeding
  175. :workListIds="workListIds"
  176. :feedNeedEquipment="feedNeedEquipment"
  177. @reload="reloadFeeding"
  178. ></feeding>
  179. </div>
  180. <div v-if="operationType == 'job'">
  181. <!-- // 报工列表 入库 -->
  182. <warehousing
  183. v-if="taskObj.id == -1 && activeName == '0'"
  184. :workListIds="workListIds"
  185. ref="wareRef"
  186. :workPlanType="workPlanType"
  187. ></warehousing>
  188. <jobBooking
  189. v-else-if="isFinalCheckProduction && activeName == '0'"
  190. :workListIds="workListIds"
  191. ref="jobRef"
  192. :reportNeedFeed="reportNeedFeed"
  193. :workPlanType="workPlanType"
  194. ></jobBooking>
  195. <task-report
  196. ref="taskReportRef"
  197. v-if="activeName == '1' && isFinalCheckProduction"
  198. style="background: #fff"
  199. @success="successTask"
  200. />
  201. </div>
  202. <div v-if="operationType == 'workOrder'">
  203. <workOrderHandover
  204. :workListIds="workListIds"
  205. :workData="workData"
  206. ref="workOrderHandoverRef"
  207. @cancel="closeWorkOrderHandover"
  208. ></workOrderHandover>
  209. </div>
  210. <!-- 工步 -->
  211. <div v-if="operationType == 'workStep'"> </div>
  212. <!-- 质检工序 -->
  213. <div v-if="operationType == 'inspection'">
  214. <inspection
  215. :workListIds="workListIds"
  216. ref="inspectionRef"
  217. ></inspection>
  218. </div>
  219. <!-- 委外 -->
  220. <div
  221. v-if="operationType == 'Outsourcing' && isType == '3'"
  222. class="right_main_box"
  223. >
  224. <outsourcingDetails
  225. ref="outsourcingListRef"
  226. @outsourcingAdd="outsourcingAdd"
  227. v-if="!isStep && !isOutsource && !isPleaseEntrust"
  228. :chooseType="chooseType"
  229. ></outsourcingDetails>
  230. <outsourcing
  231. :outsourceFormVal="outsourceForm"
  232. :taskObj="taskObj"
  233. :workListIds="workListIds[0]"
  234. :workData="workData"
  235. @changePlugIn="changePlugIn"
  236. @changeCancel="changeCancel"
  237. :chooseType="chooseType"
  238. v-if="isStep"
  239. ></outsourcing>
  240. <!-- -->
  241. <outsourceList
  242. :workData="workData"
  243. :taskObj="taskObj"
  244. :outsourceFormVal="outsourceForm"
  245. :chooseType="chooseType"
  246. @closeForm="closeForm"
  247. @outScucc="outScucc"
  248. v-if="isOutsource"
  249. ></outsourceList>
  250. <pleaseEntrust
  251. :outsourceFormVal="outObj"
  252. @closeForm="closeForm"
  253. @outScucc="outScucc"
  254. v-if="isPleaseEntrust"
  255. ></pleaseEntrust>
  256. </div>
  257. </template>
  258. </div>
  259. </template>
  260. </ele-split-layout>
  261. <footBtn
  262. @footBtn="footBtn"
  263. :type="type"
  264. :singleReportInspection="singleReportInspection"
  265. style="background: rgba(223, 250, 222, 0.6); padding: 10px"
  266. :isPreProductionResult="isPreProductionResult"
  267. :qualityInspectionDisabled="qualityInspectionDisabled"
  268. :qualityInspectionDisabledMsg="firstArticlePickFeedMsg"
  269. :activeName="activeName"
  270. ></footBtn>
  271. </div>
  272. </div>
  273. <!--领料弹框 -->
  274. <picking
  275. v-if="pickingShow"
  276. @close="pickingClose"
  277. :workListIds="workListIds"
  278. ></picking>
  279. <!-- 工艺文件 -->
  280. <wokePopup ref="wokePopupRef"></wokePopup>
  281. <!-- 检验报工 -->
  282. <workPlan ref="jobRefs" @closeWorkPlan="closeWorkPlan"> </workPlan>
  283. <!-- 工步 -->
  284. <workStep ref="workStepRef" />
  285. <!-- 任务 -->
  286. <TaskDialog ref="taskDialogRef" />
  287. <!-- 异常 -->
  288. <createError ref="createErrorRef" />
  289. <!-- 设备列表 -->
  290. <device ref="deviceRef" />
  291. <!-- 周转车列表 -->
  292. <turnover ref="turnoverRef" />
  293. <!-- BOM详情 -->
  294. <BomDetailsPop ref="bomDrawer"></BomDetailsPop>
  295. <!-- 产前准备 、 过程控制 、产后检测 -->
  296. <prenatalExamination
  297. ref="prenatalExaminationRef"
  298. @close="closePrenatalExamination"
  299. />
  300. <!-- 新增请托 -->
  301. <addPlease ref="addPleaseRef" @refresh="refreshPlease"></addPlease>
  302. <qualityInspection ref="qualityInspectionRef"></qualityInspection>
  303. <!-- 手动质检过程记录 -->
  304. <select-release-rules
  305. ref="qualityRecordTemplateRef"
  306. :not-produce-task-config="true"
  307. @chooseRules="chooseQualityRecordTemplate"
  308. />
  309. <quality-record-dialog
  310. ref="qualityRecordDialogRef"
  311. :isTempRecord="1"
  312. @reload="handleQualityRecordSaved"
  313. />
  314. <!-- 打码 -->
  315. <encodingDialog ref="encodingDialogRef" />
  316. <encodingDialog80x40 ref="encodingDialog80x40Ref" />
  317. <!-- 打码纸张尺寸选择 -->
  318. <el-dialog
  319. title="选择打印纸尺寸"
  320. :visible.sync="paperSizeDialogVisible"
  321. width="360px"
  322. append-to-body
  323. >
  324. <el-radio-group
  325. v-model="selectedPaperSize"
  326. style="display: flex; flex-direction: column; gap: 10px"
  327. >
  328. <el-radio
  329. v-for="opt in paperSizeOptions"
  330. :key="opt.value"
  331. :label="opt.value"
  332. >{{ opt.label }}</el-radio
  333. >
  334. </el-radio-group>
  335. <div slot="footer">
  336. <el-button size="small" @click="paperSizeDialogVisible = false"
  337. >取消</el-button
  338. >
  339. <el-button size="small" type="primary" @click="confirmPaperSize"
  340. >确定</el-button
  341. >
  342. </div>
  343. </el-dialog>
  344. </div>
  345. </template>
  346. <script>
  347. import TaskDialog from '@/views/produce/components/taskDialog/index.vue';
  348. import Search from './components/search.vue';
  349. import footBtn from './components/footBtn.vue';
  350. // import produceOrder from './components/produceOrder.vue';
  351. import produceOrder from './components/new_produceOrder.vue';
  352. import productionResource from './components/productionResource/index.vue';
  353. import outsourcing from './components/outsourcing/index.vue';
  354. import picking from './components/picking/index.vue';
  355. import wokePopup from './components/picking/wokePopup.vue';
  356. import inspection from './components/inspection/newIndex.vue';
  357. // import inspection from './components/inspection/index.vue';
  358. import pickDetails from './components/picking/details.vue';
  359. import AssetTree from '@/components/AssetTree/joobIndex.vue';
  360. import feeding from './components/feeding/index.vue';
  361. import jobBooking from './components/jobBooking/index.vue';
  362. import workPlan from './components/workPlan/index.vue';
  363. import workes from './components/workPlan/components/work.vue';
  364. import warehousing from './components/warehousing/index.vue';
  365. // import outsourceList from './components/outsourcing/outsourceList.vue';
  366. import outsourceList from './components/outsourcing/new_outsourceList.vue';
  367. import pleaseEntrust from './components/outsourcing/pleaseEntrust.vue';
  368. import workStep from './components/workStep/index.vue';
  369. import createError from './components/createError.vue';
  370. import device from './components/device/index.vue';
  371. import turnover from './components/turnover/index.vue';
  372. import outsourcingDetails from './components/outsourcing/details.vue';
  373. import BomDetailsPop from './components/bom/detailsPop.vue';
  374. import { parameterGetByCode } from '@/api/system/dictionary-data';
  375. import addPlease from './components/outsourcing/addPlease.vue';
  376. import {
  377. getByTaskId,
  378. pcCheckOutsource,
  379. getTaskInstanceById,
  380. checkOutsourceMaterial,
  381. listTask,
  382. factoryworkstationPage,
  383. nextTask,
  384. singleListTask,
  385. pleaseEntrustManagement,
  386. checkPleaseEntrust,
  387. checkRepeatPick,
  388. checkRepeatFeed
  389. } from '@/api/produce/index';
  390. import prenatalExamination from './components/prenatalExamination/index.vue';
  391. import { workorderPage2 } from '@/api/produce/workOrder.js';
  392. import {
  393. checkProductionResult,
  394. getProduceTaskInstanceId
  395. } from '@/api/producetaskrulerecord/index.js';
  396. import qualityInspection from './components/qualityInspection/index.vue';
  397. import selectReleaseRules from '@/components/selectReleaseRules/select-release-rules.vue';
  398. import qualityRecordDialog from './components/prenatalExamination/releaseRulesDialog.vue';
  399. import encodingDialog from './components/encodingDialog/index.vue';
  400. import encodingDialog80x40 from './components/encodingDialog/index80x40.vue';
  401. import { pageByCurrentUser } from '@/api/workOrderList';
  402. import taskWorkList from './components/taskWorkList.vue';
  403. import taskReport from './components/taskReport.vue';
  404. import { getProduceTaskList } from '@/api/aps';
  405. import workOrderHandover from './components/workOrderHandover/index.vue';
  406. import workOrderDetailPreview from './components/workOrderDetailPreview.vue';
  407. export default {
  408. components: {
  409. Search,
  410. footBtn,
  411. wokePopup,
  412. produceOrder,
  413. productionResource,
  414. outsourcing,
  415. picking,
  416. pickDetails,
  417. outsourceList,
  418. feeding,
  419. AssetTree,
  420. jobBooking,
  421. inspection,
  422. warehousing,
  423. workStep,
  424. workPlan,
  425. TaskDialog,
  426. createError,
  427. device,
  428. turnover,
  429. outsourcingDetails,
  430. BomDetailsPop,
  431. prenatalExamination,
  432. pleaseEntrust,
  433. addPlease,
  434. qualityInspection,
  435. selectReleaseRules,
  436. qualityRecordDialog,
  437. taskWorkList,
  438. taskReport,
  439. workOrderHandover,
  440. workOrderDetailPreview,
  441. encodingDialog,
  442. encodingDialog80x40
  443. },
  444. data() {
  445. return {
  446. name: '',
  447. activeName: '0',
  448. taskName: '',
  449. keyWord: '', //搜索
  450. title: '',
  451. type: '',
  452. loading: false,
  453. operationType: null,
  454. popupType: '', // 弹窗
  455. workListIds: [],
  456. factoryworkstationList: [],
  457. title1: '',
  458. arr: [],
  459. arrTow: [],
  460. produceTaskList: [],
  461. taskDataList: [],
  462. produceTaskInfo: null,
  463. isType: '',
  464. isStep: false,
  465. outsourceForm: {},
  466. outObj: {},
  467. pickingShow: false,
  468. wokePopup: false,
  469. workPlanType: '',
  470. isOutsource: false,
  471. isPleaseEntrust: false,
  472. BomObj: {},
  473. defaultProps: {
  474. children: 'children',
  475. label: 'newName'
  476. },
  477. defaultPropsTow: {
  478. children: 'children',
  479. label: 'name',
  480. value: 'code'
  481. },
  482. feedNeedEquipment: 0, //投料是否要添加生产设备1是0否
  483. reportNeedFeed: 0, //生产质检是否需要处置再报工1是0否
  484. singleReportInspection: null, //获取选中的工单是单个还是批量
  485. workTaskId: null, //选中的工单工序id
  486. workStepQueryParam: {
  487. taskId: null,
  488. workOrderId: null,
  489. bomCategoryId: null
  490. },
  491. isFinalCheckProduction: true,
  492. isOpen: false,
  493. buttons: [
  494. { label: '按钮1' },
  495. { label: '按钮2' },
  496. { label: '按钮3' },
  497. { label: '按钮4' }
  498. ],
  499. radius: 120, // 按钮展开的半径
  500. isOpen: false,
  501. lastClicked: '无',
  502. menuItems: [
  503. { label: 'BOM', action: 'Add' },
  504. { label: '周转车', action: 'Bold' },
  505. { label: '设备', action: 'Copy' },
  506. { label: '产前准备', action: 'Delete' },
  507. { label: '过程检测', action: 'Edit' },
  508. { label: '产后检查', action: 'Favorite' }
  509. ],
  510. isPreProductionResult: null,
  511. chooseType: '1',
  512. isUpdataTask: false,
  513. treeKey: '1',
  514. taskData: null,
  515. taskRequestController: null,
  516. firstArticlePickFeedReady: true,
  517. firstArticlePickFeedMsg: '',
  518. firstArticlePickFeedCheckKey: '',
  519. /** 底部按钮点击后隐藏右侧工单详情预览(含 type 为空的按钮,如暂停启动) */
  520. workOrderDetailPreviewSuppressed: false,
  521. paperSizeDialogVisible: false,
  522. selectedPaperSize: '100x80',
  523. paperSizeOptions: [
  524. { label: '100mm × 80mm', value: '100x80', width: 100, height: 80 },
  525. { label: '80mm × 40mm', value: '80x40', width: 80, height: 40 }
  526. ]
  527. };
  528. },
  529. computed: {
  530. /** 勾选工单/任务且未进入底部按钮业务区时,右侧展示工单详情 */
  531. showWorkOrderDetailPreview() {
  532. if (this.workOrderDetailPreviewSuppressed) return false;
  533. if (this.operationType) return false;
  534. if (this.activeName === '0') {
  535. return this.workListIds.length > 0;
  536. }
  537. return !!this.taskData;
  538. },
  539. /** 与当前勾选 id 对齐,避免仅用 list[0] 在取消再选后仍为旧行引用 */
  540. previewWorkOrderInfo() {
  541. if (this.activeName === '0') {
  542. const list = this.workData?.list;
  543. if (!list || !list.length) return {};
  544. const primaryId = this.workListIds[0];
  545. const row =
  546. primaryId != null ? list.find((r) => r.id == primaryId) : null;
  547. const resolved = row || list[0];
  548. return resolved ? { ...resolved } : {};
  549. }
  550. const built = this.buildWorkOrderInfoFromTaskRow(this.taskData);
  551. return built && Object.keys(built).length ? { ...built } : {};
  552. },
  553. previewWorkOrderDetailKey() {
  554. if (this.activeName === '0') {
  555. return this.workListIds.length
  556. ? `wo-${this.workListIds.join(',')}`
  557. : 'wo-empty';
  558. }
  559. return this.taskData?.id != null
  560. ? `task-${this.taskData.id}`
  561. : 'task-empty';
  562. },
  563. taskObj() {
  564. return this.$store.state.user.taskObj;
  565. },
  566. info() {
  567. return this.$store.state.user.info;
  568. },
  569. hasFirstArticleInspectionTarget() {
  570. return this.activeName === '0' && this.workListIds.length > 0;
  571. },
  572. qualityInspectionDisabled() {
  573. return (
  574. this.info?.clientEnvironmentId == 9 &&
  575. this.hasFirstArticleInspectionTarget &&
  576. !this.firstArticlePickFeedReady
  577. );
  578. },
  579. rightShow() {
  580. return (type) => {};
  581. },
  582. actionMap() {
  583. return {
  584. job: this.handleJob,
  585. pick: this.handlePick,
  586. workStep: this.handleWorkStep,
  587. task: this.handleTask,
  588. work: this.handleWork,
  589. device: this.handleDevice,
  590. bom: this.handleBom,
  591. error: this.handleError,
  592. encoding: this.handleEncoding,
  593. Outsourcing: this.handleOutsourcing,
  594. qualityRecord: this.handleQualityRecord,
  595. qualityInspection: this.handleQualityInspection,
  596. workOrder: this.handleWorkOrder,
  597. prenatalExamination: () => this.handleInspection(1),
  598. processDetection: () => this.handleInspection(2),
  599. postpartumExamination: () => this.handleInspection(3)
  600. };
  601. }
  602. },
  603. created() {
  604. this.init();
  605. this.getTaskList();
  606. this.getFactoryworkstationPageList();
  607. this.operationType = null;
  608. this.workListIds = [];
  609. },
  610. methods: {
  611. tabClickValue() {
  612. this.abortTaskRequest();
  613. this.isFinalCheckProduction = false;
  614. this.operationType = '';
  615. this.workOrderDetailPreviewSuppressed = false;
  616. this.resetFirstArticlePickFeedStatus();
  617. this.getTaskList();
  618. this.name = '';
  619. this.seekInput();
  620. },
  621. toggleMenu() {
  622. this.isOpen = !this.isOpen;
  623. },
  624. handleItemClick(item) {
  625. this.lastClicked = item.action;
  626. // console.log(`Clicked: ${item.label} - ${item.action}`);
  627. },
  628. getItemStyle(index) {
  629. if (!this.isOpen) {
  630. return {};
  631. }
  632. const radius = 120;
  633. let angle = -180 + (120 / (this.menuItems.length - 1)) * index;
  634. let rad = (angle * Math.PI) / 180;
  635. let tx = Math.cos(rad) * radius;
  636. let ty = Math.sin(rad) * radius;
  637. return {
  638. '--tx': `${tx}px`,
  639. '--ty': `${ty}px`,
  640. 'transition-delay': `${index * 0.05}s`
  641. };
  642. },
  643. abortTaskRequest() {
  644. if (this.taskRequestController) {
  645. this.taskRequestController.abort();
  646. this.taskRequestController = null;
  647. }
  648. },
  649. isSingleUserTaskMode() {
  650. return localStorage.getItem('singleUserInfo') == '1';
  651. },
  652. getSelectedUserInfo() {
  653. return JSON.parse(localStorage.getItem('chooseUserInfo'));
  654. },
  655. getTaskListRequest() {
  656. return this.isSingleUserTaskMode()
  657. ? singleListTask(this.getSelectedUserInfo())
  658. : listTask();
  659. },
  660. syncCurrentTask(list = this.produceTaskList) {
  661. if (!list?.length) return;
  662. const currentTask = list[0];
  663. this.$store.commit('user/setTaskObj', currentTask);
  664. this.produceTaskInfo = currentTask;
  665. this.$nextTick(() => {
  666. this.$refs.taskListRef?.setCurrentKey(currentTask.id);
  667. });
  668. },
  669. async refreshTaskWorkCountByActiveTab() {
  670. if (this.activeName === '0') {
  671. await this.getTaskWorkNumber();
  672. } else if (this.activeName === '1') {
  673. await this.getTaskWorkList();
  674. }
  675. },
  676. async loadTaskList(options = {}) {
  677. const {
  678. withCount = !this.isSingleUserTaskMode(),
  679. sorted = false,
  680. abort = false
  681. } = options;
  682. if (abort) {
  683. this.abortTaskRequest();
  684. }
  685. const res = await this.getTaskListRequest();
  686. this.handleTaskList(res);
  687. if (withCount) {
  688. await this.refreshTaskWorkCountByActiveTab();
  689. }
  690. if (sorted) {
  691. this.applySortedTaskList();
  692. }
  693. },
  694. // 前端筛选
  695. seekInput() {
  696. // console.log(activeName);
  697. if (this.activeName == '0') {
  698. if (!this.name) return (this.produceTaskList = this.arr);
  699. this.produceTaskList = this.produceTaskList.filter((item) => {
  700. return item.name.indexOf(this.name) > -1;
  701. });
  702. } else {
  703. if (!this.name) return (this.factoryworkstationList = this.arrTow);
  704. this.factoryworkstationList = this.factoryworkstationList.filter(
  705. (item) => {
  706. return item.name.indexOf(this.name) > -1;
  707. }
  708. );
  709. }
  710. },
  711. // 折叠悬浮中样式调整
  712. init() {
  713. this.$store.dispatch('theme/setCollapse', true);
  714. },
  715. async getTaskName(value) {
  716. if (value.length > 0) {
  717. let res = await nextTask({
  718. taskId: this.taskObj.id,
  719. workOrderIds: value.map((item) => item.id)
  720. });
  721. this.title1 = res.data.map((item) => item.taskTypeName).toString();
  722. } else {
  723. this.title1 = '';
  724. }
  725. },
  726. handleSearch() {
  727. let obj = {
  728. keyWord: this.keyWord,
  729. taskName: this.taskName
  730. };
  731. this.$refs.produceOrder.handleSearch(obj);
  732. },
  733. handleNodeClickNew(info) {
  734. let current = { id: info.id };
  735. this.$store.commit('user/currentObj', current);
  736. },
  737. setRootId(id) {
  738. this.rootId = id;
  739. },
  740. // 点击工序
  741. handleNodeClick(data) {
  742. this.feedNeedEquipment = data.feedNeedEquipment;
  743. this.reportNeedFeed = data.reportNeedFeed;
  744. this.produceTaskInfo = data;
  745. this.resetFirstArticlePickFeedStatus();
  746. // 重置按钮 禁用
  747. if (this.produceTaskInfo && this.produceTaskInfo.id != data.id) {
  748. this.isPreProductionResult = null;
  749. }
  750. let obj = {
  751. 1: `${data.workCenterName}-${data.name}(普通工序)`,
  752. 3: `${data.workCenterName}-${data.name}(质检工序)`,
  753. 4: `${data.workCenterName}-${data.name}(包装工序)`,
  754. 5: `${data.workCenterName}-${data.name}(入库工序)`,
  755. 6: `${data.workCenterName}-${data.name}(质检工序)`
  756. };
  757. this.title = obj[data.type] || '';
  758. this.type = data.type;
  759. let taskObj = {};
  760. taskObj = this.produceTaskList.find((item) => item.id === data.id);
  761. taskObj.isOrderListData = false;
  762. this.$store.commit('user/setTaskObj', taskObj);
  763. },
  764. handleChoose(val) {
  765. console.log(val);
  766. },
  767. // 获取工序列表
  768. getTaskList() {
  769. return this.loadTaskList();
  770. // if (localStorage.getItem('singleUserInfo') == '1') {
  771. // singleListTask(
  772. // JSON.parse(localStorage.getItem('chooseUserInfo'))
  773. // ).then((res) => {
  774. // res.map((v) => {
  775. // v.newName = `${v.workCenterName}-${v.name}`;
  776. // });
  777. // this.produceTaskList = res;
  778. // this.arr = JSON.parse(JSON.stringify(this.produceTaskList));
  779. // if (this.produceTaskList?.length) {
  780. // this.$store.commit('user/setTaskObj', this.produceTaskList[0]);
  781. // this.$nextTick(() => {
  782. // this.$refs.taskListRef?.setCurrentKey(
  783. // this.produceTaskList[0].id
  784. // );
  785. // });
  786. // this.produceTaskInfo = this.produceTaskList[0];
  787. // }
  788. // });
  789. // } else {
  790. // listTask().then((res) => {
  791. // res.map((v) => {
  792. // v.newName = `${v.workCenterName}-${v.name}`;
  793. // });
  794. // this.produceTaskList = res;
  795. // this.taskDataList = res;
  796. // this.arr = JSON.parse(JSON.stringify(this.produceTaskList));
  797. // if (this.produceTaskList?.length) {
  798. // this.$store.commit('user/setTaskObj', this.produceTaskList[0]);
  799. // this.$nextTick(() => {
  800. // this.$refs.taskListRef?.setCurrentKey(
  801. // this.produceTaskList[0].id
  802. // );
  803. // });
  804. // this.produceTaskInfo = this.produceTaskList[0];
  805. // }
  806. // if (this.activeName == '0') {
  807. // this.getTaskWorkNumber();
  808. // } else if (this.activeName == '1') {
  809. // this.getTaskWorkList();
  810. // }
  811. // });
  812. // }
  813. },
  814. handleTaskList(res) {
  815. res.forEach((v) => {
  816. v.newName = `${v.workCenterName}-${v.name}`;
  817. });
  818. this.produceTaskList = res;
  819. this.taskDataList = res;
  820. this.arr = JSON.parse(JSON.stringify(res));
  821. // 默认选中第一个
  822. this.syncCurrentTask(res);
  823. },
  824. getTaskNumber(item) {
  825. const number = Number(item?.number);
  826. return Number.isFinite(number) ? number : 0;
  827. },
  828. sortTaskListByNumber(list) {
  829. return [...list]
  830. .map((item, index) => ({ item, index }))
  831. .sort((a, b) => {
  832. const aNumber = this.getTaskNumber(a.item);
  833. const bNumber = this.getTaskNumber(b.item);
  834. const aHasNumber = aNumber > 0;
  835. const bHasNumber = bNumber > 0;
  836. if (aHasNumber !== bHasNumber) {
  837. return aHasNumber ? -1 : 1;
  838. }
  839. if (aHasNumber && aNumber !== bNumber) {
  840. return bNumber - aNumber;
  841. }
  842. return a.index - b.index;
  843. })
  844. .map(({ item }) => item);
  845. },
  846. applySortedTaskList() {
  847. this.taskDataList = this.sortTaskListByNumber(this.taskDataList);
  848. this.produceTaskList = this.taskDataList;
  849. this.arr = JSON.parse(JSON.stringify(this.taskDataList));
  850. this.treeKey = Date.now();
  851. this.syncCurrentTask();
  852. },
  853. async sortTaskList() {
  854. await this.loadTaskList({
  855. withCount: true,
  856. sorted: true,
  857. abort: true
  858. });
  859. },
  860. async fetchTaskWorkCount(apiFn) {
  861. this.taskRequestController = new AbortController();
  862. const signal = this.taskRequestController.signal;
  863. try {
  864. const requests = this.taskDataList.map((item) =>
  865. apiFn(
  866. {
  867. pageNum: 1,
  868. size: 5000,
  869. taskId: item.id
  870. },
  871. { signal }
  872. )
  873. );
  874. const results = await Promise.all(requests);
  875. this.taskDataList = this.taskDataList.map((item, index) => ({
  876. ...item,
  877. number: results[index]?.count || 0
  878. }));
  879. this.produceTaskList = this.taskDataList;
  880. this.treeKey = Date.now();
  881. } catch (err) {
  882. if (err?.name == 'CanceledError' || err?.name == 'AbortError') {
  883. return;
  884. }
  885. console.error(err);
  886. }
  887. },
  888. //获取工序下所有的工单集合
  889. async getTaskWorkNumber() {
  890. await this.fetchTaskWorkCount(workorderPage2);
  891. // for (const [index, item] of this.taskDataList.entries()) {
  892. // await workorderPage2({
  893. // pageNum: 1,
  894. // size: 5000,
  895. // taskId: item.id
  896. // }).then((res) => {
  897. // this.taskDataList[index].number = res.count;
  898. // });
  899. // }
  900. // this.produceTaskList = this.taskDataList;
  901. // this.treeKey = Date.now();
  902. },
  903. //获取工序下所有的任务集合
  904. async getTaskWorkList() {
  905. await this.fetchTaskWorkCount(pageByCurrentUser);
  906. // for (const [index, item] of this.taskDataList.entries()) {
  907. // await pageByCurrentUser({
  908. // pageNum: 1,
  909. // size: 5000,
  910. // taskId: item.id
  911. // }).then((res) => {
  912. // this.taskDataList[index].number = res.count;
  913. // });
  914. // }
  915. // this.produceTaskList = this.taskDataList;
  916. // this.treeKey = Date.now();
  917. },
  918. // 获取工位
  919. getFactoryworkstationPageList() {
  920. factoryworkstationPage({ pageNum: 1, size: 99999999 }).then((res) => {
  921. this.factoryworkstationList = res.list;
  922. this.arrTow = JSON.parse(JSON.stringify(this.factoryworkstationList));
  923. // newName
  924. });
  925. },
  926. changeCancel(activeType) {
  927. this.isStep = false;
  928. this.chooseType = activeType;
  929. // this.$nextTick(() => {
  930. // this.$refs.outsourcingListRef.getDataList(this.workData.list[0].code);
  931. // });
  932. if (this.chooseType == '1') {
  933. this.$nextTick(() => {
  934. this.$refs.outsourcingListRef.getDataList(
  935. this.workData.list[0].code
  936. );
  937. });
  938. } else if (this.chooseType == '2') {
  939. this.$nextTick(() => {
  940. this.$refs.outsourcingListRef.getPleaseData(
  941. this.workData.list[0].code
  942. );
  943. });
  944. }
  945. },
  946. closeForm() {
  947. this.isOutsource = false;
  948. this.isPleaseEntrust = false;
  949. this.$nextTick(() => {
  950. this.$refs.outsourcingListRef.getDataList(this.workData.list[0].code);
  951. });
  952. },
  953. outScucc() {
  954. // this.operationType = null;
  955. this.isOutsource = false;
  956. this.isPleaseEntrust = false;
  957. this.$nextTick(() => {
  958. this.$refs.outsourcingListRef.getDataList(this.workData.list[0].code);
  959. });
  960. },
  961. updataTaskList() {
  962. this.isUpdataTask = true;
  963. this.getTaskList();
  964. },
  965. // 切换组件
  966. async changePlugIn(e, index) {
  967. if (index == '1') {
  968. this.outObj = e;
  969. let req = {
  970. taskId: e.taskId,
  971. taskIds: e.taskIds,
  972. workOrderId: e.workOrderId,
  973. quantity: e.formedNumLast
  974. };
  975. const URL =
  976. index == '1' ? checkOutsourceMaterial : checkPleaseEntrust;
  977. const res = await URL(req);
  978. this.outObj = { ...res.data, ...this.outsourceForm, ...this.outObj };
  979. this.isStep = false;
  980. this.isOutsource = true;
  981. } else if (index == '2') {
  982. this.outObj = e;
  983. let req = {
  984. taskId: e.taskId,
  985. taskIds: e.taskIds,
  986. workOrderId: e.workOrderId,
  987. quantity: e.formedNumLast
  988. };
  989. const res = await checkPleaseEntrust(req);
  990. this.outObj = { ...res.data, ...this.outsourceForm, ...this.outObj };
  991. this.isStep = false;
  992. this.isPleaseEntrust = true;
  993. // this.isOutsource = true;
  994. console.log(res, '请托的结果');
  995. }
  996. },
  997. renderContent(h, { node, data, store }) {
  998. // Use createElement syntax instead of JSX
  999. return h('span', { class: 'custom-tree-node' }, [
  1000. // h('span', node.label),
  1001. h(
  1002. 'el-badge',
  1003. {
  1004. props: {
  1005. value: data.number != '0' ? data.number : '',
  1006. max: 99
  1007. },
  1008. class: 'item'
  1009. },
  1010. [h('span', node.label)]
  1011. )
  1012. ]);
  1013. },
  1014. workSelect(data) {
  1015. this.workOrderDetailPreviewSuppressed = false;
  1016. this.workTaskId = data.list.length > 0 ? data.list[0].taskId : null;
  1017. this.workStepQueryParam.taskId =
  1018. data.list.length > 0 ? data.list[0].taskId : null;
  1019. this.workStepQueryParam.workOrderId =
  1020. data.list.length > 0 ? data.list[0].id : null;
  1021. this.workStepQueryParam.bomCategoryId =
  1022. data.list.length > 0 ? data.list[0].bomCategoryId : null;
  1023. this.singleReportInspection =
  1024. data.list.length > 0 ? data.list[0].singleReport : null; //获取选中的工单是单个还是批量
  1025. this.isStep = false;
  1026. this.operationType = null;
  1027. this.workListIds = data.ids;
  1028. this.workData = data;
  1029. this.checkProductionResult();
  1030. // this.refreshFirstArticlePickFeedStatus();
  1031. },
  1032. taskSelect(data) {
  1033. this.workOrderDetailPreviewSuppressed = false;
  1034. this.taskData = data.list && data.list.length > 0 ? data.list[0] : null;
  1035. this.resetFirstArticlePickFeedStatus();
  1036. },
  1037. buildWorkOrderInfoFromTaskRow(row) {
  1038. if (!row) return {};
  1039. return {
  1040. id: row.workOrderId || row.mesWorkOrderId,
  1041. singleReport: row.singleReport,
  1042. code: row.mesWorkOrderCode,
  1043. apsWorkOrderCode: row.workOrderCode || row.apsWorkOrderCode,
  1044. productionPlanCode: row.productionPlanCode,
  1045. productCode: row.productCode,
  1046. productName: row.productName,
  1047. specification: row.specification,
  1048. model: row.model,
  1049. brandNo: row.brandNo,
  1050. batchNo: row.batchNo,
  1051. formingNum: row.quantity ?? row.formingNum,
  1052. unit: row.measuringUnit ?? row.unit,
  1053. formingWeight: row.weight ?? row.formingWeight,
  1054. weightUnit: row.newWeightUnit ?? row.weightUnit,
  1055. formedNum: row.formedNum,
  1056. formedWeight: row.formedWeight,
  1057. productionCodes: row.productionCodes,
  1058. outsourceStatus: row.outsourceStatus,
  1059. entrustStatus: row.entrustStatus,
  1060. colorKey: row.colorKey,
  1061. modelKey: row.modelKey,
  1062. planStartTime: row.planStartTime,
  1063. planCompleteTime: row.planCompleteTime,
  1064. startTime: row.startTime ?? row.realStartTime,
  1065. completeTime: row.endTime ?? row.realEndTime ?? row.completeTime,
  1066. createTime: row.createTime,
  1067. produceRoutingName: row.produceRoutingName,
  1068. productionPlanId: row.productionPlanId,
  1069. taskId: row.taskId
  1070. };
  1071. },
  1072. pickingWokeClose() {
  1073. this.wokePopup = false;
  1074. },
  1075. async getCodeData(req) {
  1076. await parameterGetByCode({ code: 'enable_quality_plus' }).then(
  1077. (res) => {
  1078. if (res.value == '1') {
  1079. this.$refs.jobRefs.open(req);
  1080. }
  1081. }
  1082. );
  1083. },
  1084. closeWorkPlan(type) {
  1085. this.workPlanType = type;
  1086. },
  1087. async checkQualityResult() {
  1088. if (
  1089. this.produceTaskInfo &&
  1090. this.workListIds.length > 0 &&
  1091. this.produceTaskInfo.id != -1
  1092. ) {
  1093. // 判断是否要求先完成 产前准备等事项
  1094. const result = await checkProductionResult({
  1095. produceTaskId: this.produceTaskInfo.id,
  1096. workOrderIds: this.workListIds
  1097. });
  1098. return result;
  1099. }
  1100. },
  1101. /** 投料前首件两检校验(与报工逻辑一致) */
  1102. async validateFeedFirstArticle() {
  1103. if (this.activeName === '1') {
  1104. const row = this.taskData;
  1105. if (!row) {
  1106. this.$message.warning('请选择一条任务单进行投料');
  1107. return false;
  1108. }
  1109. if (
  1110. this.taskObj.id != '-1' &&
  1111. row.hasFirstArticleDualInspection == '1' &&
  1112. row.totalFirstArticleDualInspectionStatus != '2'
  1113. ) {
  1114. this.$message.warning('请先完成首件两检再投料');
  1115. return false;
  1116. }
  1117. return true;
  1118. }
  1119. if (!this.checkWorkOrder({ min: 1 })) return false;
  1120. if (this.taskObj.id != '-1') {
  1121. const result = await this.checkQualityResult();
  1122. if (!result?.firstArticleDualInspectionResult) {
  1123. this.$message.warning('请完成首件两检再投料!');
  1124. return false;
  1125. }
  1126. }
  1127. return true;
  1128. },
  1129. async footBtn(t) {
  1130. this.workPlanType = '';
  1131. if (['work', 'workStep', 'task'].includes(t)) {
  1132. this.popupType = t;
  1133. } else if (t == 'workOrder') {
  1134. console.log(this.workData, 'workData');
  1135. if (this.workListIds.length == 0) {
  1136. this.$message.warning('请选择工单');
  1137. return;
  1138. }
  1139. if (this.workListIds.length > 1) {
  1140. this.$message.warning('工单交接只能选择一个工单');
  1141. return;
  1142. }
  1143. this.operationType = t;
  1144. } else if (t !== 'feed') {
  1145. this.operationType = t;
  1146. }
  1147. if (!this.checkTaskSelected()) return;
  1148. if (t === 'feed') {
  1149. if (!(await this.validateFeedFirstArticle())) return;
  1150. this.operationType = 'feed';
  1151. }
  1152. this.workOrderDetailPreviewSuppressed = true;
  1153. const handler = this.actionMap[t];
  1154. if (handler) {
  1155. await handler.call(this);
  1156. }
  1157. },
  1158. checkTaskSelected() {
  1159. const taskObj = this.$store.state.user.taskObj;
  1160. if (!taskObj || Object.keys(taskObj).length === 0) {
  1161. this.$message.warning('请选择工序');
  1162. return false;
  1163. }
  1164. return true;
  1165. },
  1166. checkWorkOrder({ min = 1, max = Infinity, msg = {} }) {
  1167. const len = this.workListIds.length;
  1168. if (len < min) {
  1169. this.$message.warning(msg.min || '请选择工单!');
  1170. return false;
  1171. }
  1172. if (len > max) {
  1173. this.$message.warning(msg.max || '只能选择一个工单!');
  1174. return false;
  1175. }
  1176. return true;
  1177. },
  1178. resetFirstArticlePickFeedStatus() {
  1179. this.firstArticlePickFeedReady = true;
  1180. this.firstArticlePickFeedMsg = '';
  1181. this.firstArticlePickFeedCheckKey = '';
  1182. },
  1183. getFirstArticleWorkOrderId(row = {}) {
  1184. return row.workOrderId || row.mesWorkOrderId || row.id;
  1185. },
  1186. getFirstArticleInspectionRows() {
  1187. const selectedIds = new Set(this.workListIds.map((id) => String(id)));
  1188. const rows = this.workData?.list || [];
  1189. const selectedRows = rows.filter((row) =>
  1190. selectedIds.has(String(this.getFirstArticleWorkOrderId(row)))
  1191. );
  1192. return selectedRows.length
  1193. ? selectedRows
  1194. : this.workListIds.map((id) => ({ id }));
  1195. },
  1196. hasNonZeroCheckData(data, keys) {
  1197. if (Array.isArray(data)) {
  1198. return data.some((item) => this.hasNonZeroCheckData(item, keys));
  1199. }
  1200. if (data && typeof data === 'object') {
  1201. const values = keys?.length
  1202. ? keys.map((key) => data[key])
  1203. : Object.values(data);
  1204. return values.some((value) => this.hasNonZeroCheckData(value));
  1205. }
  1206. const num = Number(data);
  1207. if (!Number.isNaN(num)) {
  1208. return num !== 0;
  1209. }
  1210. return Boolean(data);
  1211. },
  1212. async checkFirstArticlePickFeed(row) {
  1213. const workOrderId = this.getFirstArticleWorkOrderId(row);
  1214. if (!workOrderId) {
  1215. return { pickDone: false, feedDone: false };
  1216. }
  1217. const [pickRes, feedRes] = await Promise.all([
  1218. checkRepeatPick({ workOrderId }),
  1219. checkRepeatFeed([
  1220. {
  1221. currentTaskDiagram: row.currentTaskDiagram,
  1222. workOrderId
  1223. }
  1224. ])
  1225. ]);
  1226. return {
  1227. pickDone: this.hasNonZeroCheckData(pickRes?.data),
  1228. feedDone: this.hasNonZeroCheckData(feedRes?.data, [
  1229. 'feedFormed',
  1230. 'feedQuantity',
  1231. 'allFeedQuantity'
  1232. ])
  1233. };
  1234. },
  1235. getFirstArticlePickFeedMsg(results) {
  1236. const needPick = results.some((item) => !item.pickDone);
  1237. const needFeed = results.some((item) => !item.feedDone);
  1238. if (needPick && needFeed) {
  1239. return '请先完成领料、投料后再进行首件两检';
  1240. }
  1241. if (needPick) {
  1242. return '请先完成领料后再进行首件两检';
  1243. }
  1244. if (needFeed) {
  1245. return '请先完成投料后再进行首件两检';
  1246. }
  1247. return '';
  1248. },
  1249. async refreshFirstArticlePickFeedStatus() {
  1250. if (this.info?.clientEnvironmentId != 9 || this.activeName !== '0') {
  1251. this.resetFirstArticlePickFeedStatus();
  1252. return true;
  1253. }
  1254. if (!this.hasFirstArticleInspectionTarget) {
  1255. this.resetFirstArticlePickFeedStatus();
  1256. return true;
  1257. }
  1258. const rows = this.getFirstArticleInspectionRows();
  1259. const checkKey = `${this.activeName}-${rows
  1260. .map((row) => this.getFirstArticleWorkOrderId(row))
  1261. .join(',')}`;
  1262. this.firstArticlePickFeedCheckKey = checkKey;
  1263. this.firstArticlePickFeedReady = false;
  1264. this.firstArticlePickFeedMsg = '正在检查领料、投料状态';
  1265. try {
  1266. const results = await Promise.all(
  1267. rows.map((row) => this.checkFirstArticlePickFeed(row))
  1268. );
  1269. if (this.firstArticlePickFeedCheckKey !== checkKey) {
  1270. return this.firstArticlePickFeedReady;
  1271. }
  1272. const msg = this.getFirstArticlePickFeedMsg(results);
  1273. this.firstArticlePickFeedReady = !msg;
  1274. this.firstArticlePickFeedMsg = msg;
  1275. return this.firstArticlePickFeedReady;
  1276. } catch (error) {
  1277. if (this.firstArticlePickFeedCheckKey === checkKey) {
  1278. this.firstArticlePickFeedReady = false;
  1279. this.firstArticlePickFeedMsg =
  1280. '领料、投料状态检查失败,请稍后重试';
  1281. }
  1282. return false;
  1283. }
  1284. },
  1285. async validateFirstArticlePickFeedBeforeInspection() {
  1286. const ready = await this.refreshFirstArticlePickFeedStatus();
  1287. if (!ready) {
  1288. this.$message.warning(
  1289. this.firstArticlePickFeedMsg ||
  1290. '请先完成领料、投料后再进行首件两检'
  1291. );
  1292. }
  1293. return ready;
  1294. },
  1295. async getFirstArticleConfig() {
  1296. const res = await parameterGetByCode({
  1297. code: 'first_article_dual_inspection_for_report'
  1298. });
  1299. return res.value;
  1300. },
  1301. /* ================== job ================== */
  1302. async handleJob() {
  1303. if (this.activeName == '1') {
  1304. return this.handleTaskJob();
  1305. }
  1306. return this.handleWorkOrderJob();
  1307. },
  1308. async handleTaskJob() {
  1309. this.isFinalCheckProduction = false;
  1310. const row = this.taskData;
  1311. // if (row.disposalStatus == '0') {
  1312. // return this.$message.warning('请先接收任务才能进行报工!');
  1313. // }
  1314. // if (row.disposalStatus == '2') {
  1315. // return this.$message.warning('该任务单已被拒绝接收不能进行报工!');
  1316. // }
  1317. if (!this.checkTaskJob(row)) return;
  1318. this.isFinalCheckProduction = true;
  1319. const currentRow = this.buildCurrentRow(row);
  1320. const form = this.buildForm(row);
  1321. this.$nextTick(() => {
  1322. this.$refs.taskReportRef.open('report', currentRow, form);
  1323. });
  1324. },
  1325. checkTaskJob(row) {
  1326. if (!row) {
  1327. this.$message.warning('请选择一条任务单进行报工');
  1328. return false;
  1329. }
  1330. // 任务状态校验
  1331. const statusMessageMap = {
  1332. 0: '请先接收任务再报工',
  1333. 2: '该任务单已被拒绝'
  1334. };
  1335. if (statusMessageMap[row.disposalStatus]) {
  1336. this.$message.warning(statusMessageMap[row.disposalStatus]);
  1337. return false;
  1338. }
  1339. // 首件两检校验
  1340. if (
  1341. this.taskObj.id != '-1' &&
  1342. row.hasFirstArticleDualInspection == '1' &&
  1343. row.totalFirstArticleDualInspectionStatus != '2'
  1344. ) {
  1345. this.$message.warning('请先完成首件两检再报工');
  1346. return false;
  1347. }
  1348. return true;
  1349. },
  1350. buildCurrentRow(row) {
  1351. return {
  1352. assignCode: row.assignCode,
  1353. mesWorkOrderCode: row.mesWorkOrderCode,
  1354. workOrderCode: row.workOrderCode,
  1355. productionPlanCode: row.productionPlanCode,
  1356. produceRoutingName: row.produceRoutingName,
  1357. formingNum: row.formingNum,
  1358. assignTeamName: row.assignTeamName,
  1359. formingWeight: row.formingWeight,
  1360. planStartTime: row.planStartTime,
  1361. planCompleteTime: row.planCompleteTime,
  1362. startTime: row.startTime,
  1363. endTime: row.endTime,
  1364. firstTaskId: row.firstTaskId,
  1365. taskName: row.taskName,
  1366. firstTaskName: row.firstTaskName,
  1367. assigneeType: row.assigneeType?.desc || '',
  1368. assigneeName: row.assigneeName,
  1369. weight: row.weight,
  1370. quantity: row.quantity,
  1371. durationText: row.durationText,
  1372. apsAssigneeId: row.id,
  1373. batchNo: row.batchNo,
  1374. productCode: row.productCode,
  1375. productName: row.productName,
  1376. specification: row.specification,
  1377. newWeightUnit: row.newWeightUnit,
  1378. measuringUnit: row.measuringUnit,
  1379. reportQuantityReported: row.reportQuantity || 0,
  1380. lossQuantityReported: row.lossQuantity || 0
  1381. };
  1382. },
  1383. buildForm(row) {
  1384. console.log();
  1385. const actualQuantity = this.add(
  1386. row.reportQuantity ? row.reportQuantity : 0,
  1387. row.lossQuantity ? row.lossQuantity : 0
  1388. );
  1389. const remainingQuantity = Math.max(
  1390. this.sub(row.quantity || 0, actualQuantity),
  1391. 0
  1392. );
  1393. return {
  1394. realStartTime: row.realStartTime,
  1395. realEndTime: row.realEndTime,
  1396. qualifiedQuantity: row.qualifiedQuantity,
  1397. qualifiedWeight: row.qualifiedWeight,
  1398. unqualifiedQuantity: row.unqualifiedQuantity,
  1399. unqualifiedWeight: row.unqualifiedWeight,
  1400. reportQuantity: remainingQuantity,
  1401. lossQuantity: 0,
  1402. remark: row.assigneeRemark
  1403. };
  1404. },
  1405. async handleWorkOrderJob() {
  1406. if (!this.checkWorkOrder({ min: 1 })) return;
  1407. this.isFinalCheckProduction = false;
  1408. if (this.taskObj.id != '-1') {
  1409. const result = await this.checkQualityResult();
  1410. console.log(result, 'result');
  1411. if (!result?.firstArticleDualInspectionResult) {
  1412. return this.$message.warning('请完成首件两检再报工!');
  1413. }
  1414. }
  1415. this.isFinalCheckProduction = true;
  1416. if ([2, 3, 6].includes(this.taskObj.type)) {
  1417. this.getCodeData({
  1418. taskId: this.taskObj.id,
  1419. workOrderId: this.workListIds[0],
  1420. data: this.workData.list
  1421. });
  1422. }
  1423. },
  1424. /* ================== pick ================== */
  1425. handlePick() {
  1426. if (this.activeName != '0') return;
  1427. if (!this.checkWorkOrder({ min: 1 })) return;
  1428. this.$nextTick(() => {
  1429. this.$refs.pickListRef.getList(this.workListIds);
  1430. });
  1431. },
  1432. /* ================== workStep ================== */
  1433. handleWorkStep() {
  1434. if (this.activeName != '0') return;
  1435. if (
  1436. !this.checkWorkOrder({
  1437. min: 1,
  1438. max: 1,
  1439. msg: { max: '工步只能选择一个工单!' }
  1440. })
  1441. )
  1442. return;
  1443. this.$refs.workStepRef.open(this.workStepQueryParam);
  1444. },
  1445. /* ================== task ================== */
  1446. handleTask() {
  1447. if (this.activeName != '0') return;
  1448. if (
  1449. !this.checkWorkOrder({
  1450. min: 1,
  1451. max: 1,
  1452. msg: { max: '任务只能选择一个工单!' }
  1453. })
  1454. )
  1455. return;
  1456. this.$refs.taskDialogRef.open(
  1457. this.workStepQueryParam,
  1458. this.workData.list[0]
  1459. );
  1460. },
  1461. /* ================== work ================== */
  1462. async handleWork() {
  1463. const req =
  1464. this.activeName === '0'
  1465. ? this.getWorkOrderForWork()
  1466. : this.getTaskForWork();
  1467. if (!req) return;
  1468. await this.openWorkFile(req);
  1469. },
  1470. getWorkOrderForWork() {
  1471. const valid = this.checkWorkOrder({
  1472. min: 1,
  1473. max: 1,
  1474. msg: { max: '工艺文件只能选择一个工单!' }
  1475. });
  1476. if (!valid) return null;
  1477. const row = this.workData?.list?.[0];
  1478. if (!row) return null;
  1479. return this.buildCraftFileReq(row, this.workListIds[0]);
  1480. },
  1481. getTaskForWork() {
  1482. if (!this.taskData) {
  1483. this.$message.warning('请选择一条任务单');
  1484. return null;
  1485. }
  1486. return this.buildCraftFileReq(this.taskData, this.taskData.workOrderId);
  1487. },
  1488. getCraftFileProductCode(row) {
  1489. return (
  1490. row?.productCode ||
  1491. row?.materialCode ||
  1492. row?.categoryCode ||
  1493. row?.productCategoryCode ||
  1494. ''
  1495. );
  1496. },
  1497. buildCraftFileReq(row, workOrderId) {
  1498. return {
  1499. taskId: this.taskObj.id,
  1500. workOrderId:
  1501. workOrderId || row?.workOrderId || row?.mesWorkOrderId || row?.id,
  1502. productCode: this.getCraftFileProductCode(row)
  1503. };
  1504. },
  1505. async openWorkFile(req) {
  1506. const res = await parameterGetByCode({
  1507. code: 'mes_craft_file_by_category_code'
  1508. });
  1509. const byCategory = res?.value === '1';
  1510. if (byCategory) {
  1511. this.$refs.wokePopupRef.openTwo(req);
  1512. } else {
  1513. this.$refs.wokePopupRef.open(req);
  1514. }
  1515. },
  1516. /* ================== device ================== */
  1517. handleDevice() {
  1518. // if (this.activeName != '0') return;
  1519. if (!this.taskObj.id) {
  1520. return this.$message.warning('请选择工序');
  1521. }
  1522. this.$refs.deviceRef.open(this.taskObj.id);
  1523. },
  1524. /* ================== encoding ================== */
  1525. handleEncoding() {
  1526. if (this.activeName != '0') return;
  1527. if (
  1528. !this.checkWorkOrder({
  1529. min: 1,
  1530. msg: { min: '请选择工单!' }
  1531. })
  1532. )
  1533. return;
  1534. this.selectPaperSizeAndOpenEncoding();
  1535. },
  1536. selectPaperSizeAndOpenEncoding() {
  1537. this.selectedPaperSize = '100x80';
  1538. this.paperSizeDialogVisible = true;
  1539. },
  1540. confirmPaperSize() {
  1541. const size = this.selectedPaperSize;
  1542. this.paperSizeDialogVisible = false;
  1543. this.$nextTick(() => {
  1544. if (size === '80x40') {
  1545. this.$refs.encodingDialog80x40Ref.open(this.workData.list);
  1546. } else {
  1547. this.$refs.encodingDialogRef.open(this.workData.list);
  1548. }
  1549. });
  1550. },
  1551. /* ================== bom ================== */
  1552. handleBom() {
  1553. const isWorkOrder = this.activeName === '0';
  1554. const row = isWorkOrder ? this.getWorkOrderRow() : this.getTaskRow();
  1555. if (!row) return;
  1556. this.openBomDrawer(row);
  1557. },
  1558. getWorkOrderRow() {
  1559. const valid = this.checkWorkOrder({
  1560. min: 1,
  1561. max: 1,
  1562. msg: { max: '查看BOM详情只能选择一个工单!' }
  1563. });
  1564. if (!valid) return null;
  1565. return this.workData?.list?.[0] || null;
  1566. },
  1567. getTaskRow() {
  1568. if (!this.taskData) {
  1569. this.$message.warning('请选择一条任务单');
  1570. return null;
  1571. }
  1572. return this.taskData;
  1573. },
  1574. openBomDrawer(row) {
  1575. this.$refs.bomDrawer.open({
  1576. categoryId: row.categoryId,
  1577. categoryName: row.bomCategoryName,
  1578. code: row.code || '',
  1579. versions: row.bomCategoryVersions,
  1580. rootPathIdParent: row.categoryLevelPathIdParent || '',
  1581. isProduct: true,
  1582. bomType: Number(row.bomType),
  1583. isTemp: 0
  1584. });
  1585. },
  1586. /* ================== Outsourcing ================== */
  1587. handleOutsourcing() {
  1588. if (this.activeName != '0') return;
  1589. if (
  1590. !this.checkWorkOrder({
  1591. min: 1,
  1592. max: 1,
  1593. msg: { max: '委外请托工序只能选择一个工单!' }
  1594. })
  1595. )
  1596. return;
  1597. this.handOutsource(this.workListIds[0]);
  1598. },
  1599. /* ================== 产前 / 过程 / 产后 ================== */
  1600. handleInspection(type) {
  1601. if (this.activeName != '0') return;
  1602. if (
  1603. !this.checkWorkOrder({
  1604. min: 1,
  1605. max: 1
  1606. })
  1607. )
  1608. return;
  1609. this.$refs.prenatalExaminationRef.open(
  1610. this.workData.list[0],
  1611. this.produceTaskInfo,
  1612. type
  1613. );
  1614. },
  1615. /* ================== 手动质检过程记录 ================== */
  1616. handleQualityRecord() {
  1617. if (this.activeName != '0') return;
  1618. if (
  1619. !this.checkWorkOrder({
  1620. min: 1,
  1621. max: 1,
  1622. msg: { max: '质检记录只能选择一个工单!' }
  1623. })
  1624. )
  1625. return;
  1626. if (!this.produceTaskInfo || !this.produceTaskInfo.id) {
  1627. return this.$message.warning('请选择工序');
  1628. }
  1629. this.$refs.qualityRecordTemplateRef.open(2, this.produceTaskInfo.id);
  1630. },
  1631. async chooseQualityRecordTemplate(rule) {
  1632. const workOrderInfo = this.workData?.list?.[0];
  1633. if (!rule || !workOrderInfo || !this.produceTaskInfo) return;
  1634. const produceTaskInstanceInfo = await getProduceTaskInstanceId(
  1635. workOrderInfo.id,
  1636. this.produceTaskInfo.id
  1637. );
  1638. const productionInfo = this.buildQualityRecordInfo(
  1639. rule,
  1640. produceTaskInstanceInfo
  1641. );
  1642. this.$refs.qualityRecordDialogRef.open(productionInfo, workOrderInfo);
  1643. },
  1644. buildQualityRecordInfo(rule, produceTaskInstanceInfo = {}) {
  1645. return {
  1646. recordId: null,
  1647. executeStatus: 0,
  1648. executeMethod: rule.executeMethod || 0,
  1649. itemType: 2,
  1650. produceTaskConfigId: rule.produceTaskConfigId || null,
  1651. produceTaskId: this.produceTaskInfo.id,
  1652. produceTaskName:
  1653. produceTaskInstanceInfo.name ||
  1654. this.produceTaskInfo.name ||
  1655. this.produceTaskInfo.taskTypeName ||
  1656. '',
  1657. produceTaskInstanceId: produceTaskInstanceInfo.id || null,
  1658. reportWorkType: 2,
  1659. brandNo:
  1660. rule.brandNo ||
  1661. this.workData?.list?.[0]?.brandNo ||
  1662. this.workData?.list?.[0]?.brandNum ||
  1663. '',
  1664. recordRulesExecuteMethodId:
  1665. rule.executeMethodId || rule.recordRulesExecuteMethodId || null,
  1666. recordRulesExecuteMethodName:
  1667. rule.executeMethodName || rule.recordRulesExecuteMethodName || '',
  1668. ruleId: rule.id,
  1669. ruleName: rule.name,
  1670. details: []
  1671. };
  1672. },
  1673. handleQualityRecordSaved() {
  1674. this.$refs.produceOrder?.reload?.();
  1675. },
  1676. /* ================== error ================== */
  1677. handleError() {
  1678. if (this.activeName == '0') {
  1679. if (this.workListIds.length !== 1) {
  1680. return this.$message.warning('异常只能选择一个工单!');
  1681. }
  1682. this.$refs.createErrorRef.open('add', this.workData.list[0]);
  1683. }
  1684. },
  1685. /* ================== 首件两检 ================== */
  1686. async handleQualityInspection() {
  1687. if (this.activeName == '0') {
  1688. if (
  1689. !this.checkWorkOrder({
  1690. min: 1,
  1691. max: 1,
  1692. msg: { max: '首件两检只能选择一个工单!' }
  1693. })
  1694. )
  1695. return;
  1696. const item = this.workData?.list?.[0];
  1697. if (!item) return null;
  1698. if (!(await this.validateFirstArticlePickFeedBeforeInspection())) {
  1699. return;
  1700. }
  1701. const req = this.buildCraftFileReq(item, this.workListIds[0]);
  1702. this.$refs.qualityInspectionRef.open(
  1703. this.workData.list[0],
  1704. this.produceTaskInfo,
  1705. '',
  1706. req
  1707. );
  1708. } else {
  1709. console.log(this.taskData, 'this.taskData');
  1710. if (!this.taskData) {
  1711. return this.$message.warning('请选择一条任务单进行首件两检');
  1712. }
  1713. if (this.taskData.disposalStatus == '0') {
  1714. return this.$message.warning('请先接收任务再做首件两检');
  1715. }
  1716. if (this.taskData.disposalStatus == '2') {
  1717. return this.$message.warning('该任务单已被拒绝');
  1718. }
  1719. this.selfRequest(this.taskData);
  1720. }
  1721. },
  1722. /* ================== workOrder ================== */
  1723. handleWorkOrder() {},
  1724. closeWorkOrderHandover() {
  1725. this.operationType = null;
  1726. this.workOrderDetailPreviewSuppressed = false;
  1727. },
  1728. successTask() {
  1729. this.isFinalCheckProduction = false;
  1730. this.$nextTick(() => {
  1731. this.$refs.produceOrder && this.$refs.produceOrder.reload();
  1732. });
  1733. },
  1734. async selfRequest(row) {
  1735. let params = {
  1736. routingId: row.produceRoutingId,
  1737. pageNum: 1,
  1738. size: -1,
  1739. isDetail: true
  1740. };
  1741. const result = await getProduceTaskList(params);
  1742. const taskData = result.list.find(
  1743. (item) => item.sourceTaskId === row.taskId
  1744. );
  1745. // const item = this.workData?.list?.[0];
  1746. // console.log(item, 'item1111');
  1747. // if (!item) return null;
  1748. const req = this.buildCraftFileReq(
  1749. row,
  1750. row.workOrderId || row.mesWorkOrderId || this.workListIds[0]
  1751. );
  1752. this.$refs.qualityInspectionRef.open(row, taskData, 1, req);
  1753. },
  1754. outsourcingAdd(type, activeName) {
  1755. this.chooseType = activeName;
  1756. this.getTaskInstanceByIdFn(this.workListIds[0]);
  1757. if (this.chooseType == '2') {
  1758. this.isStep = true;
  1759. } else {
  1760. this.isOutsource = true;
  1761. }
  1762. },
  1763. refreshPlease() {
  1764. this.$nextTick(() => {
  1765. this.$refs.outsourcingListRef.getPleaseData(
  1766. this.workData.list[0].code
  1767. );
  1768. });
  1769. },
  1770. handOutsource(workOrderId) {
  1771. this.isType = '';
  1772. // return
  1773. let param = {
  1774. taskId: this.taskObj.id,
  1775. workOrderId: workOrderId
  1776. };
  1777. pcCheckOutsource(param).then((res) => {
  1778. this.outsourceForm = {
  1779. ...res.data
  1780. };
  1781. // this.outsourceForm.name = this.taskObj.name + '委外';
  1782. this.isStep = false;
  1783. this.isOutsource = false;
  1784. this.isPleaseEntrust = false;
  1785. if (res.data.outsource) {
  1786. this.isType = '3';
  1787. if (!this.isStep && !this.isOutsource && !this.isPleaseEntrust) {
  1788. this.$nextTick(() => {
  1789. this.$refs.outsourcingListRef.getDataList(
  1790. this.workData.list[0].code
  1791. );
  1792. });
  1793. }
  1794. // this.getTaskInstanceByIdFn(workOrderId);
  1795. // this.$refs.outsourceListRef.getList(workOrderId);
  1796. // console.log(this.workData[0].list, 'this.workData.list');
  1797. } else {
  1798. return this.$message.warning('此工序不能委外/请托');
  1799. }
  1800. });
  1801. },
  1802. getDecimalLength(num) {
  1803. return (num.toString().split('.')[1] || '').length;
  1804. },
  1805. toInteger(num) {
  1806. const len = this.getDecimalLength(num);
  1807. return {
  1808. int: Math.round(num * Math.pow(10, len)),
  1809. factor: Math.pow(10, len)
  1810. };
  1811. },
  1812. add(a, b) {
  1813. const { int: aInt, factor: aFactor } = this.toInteger(a);
  1814. const { int: bInt, factor: bFactor } = this.toInteger(b);
  1815. const maxFactor = Math.max(aFactor, bFactor);
  1816. return (
  1817. (aInt * (maxFactor / aFactor) + bInt * (maxFactor / bFactor)) /
  1818. maxFactor
  1819. );
  1820. },
  1821. sub(a, b) {
  1822. const { int: aInt, factor: aFactor } = this.toInteger(a);
  1823. const { int: bInt, factor: bFactor } = this.toInteger(b);
  1824. const maxFactor = Math.max(aFactor, bFactor);
  1825. return (
  1826. (aInt * (maxFactor / aFactor) - bInt * (maxFactor / bFactor)) /
  1827. maxFactor
  1828. );
  1829. },
  1830. //获取工单列表
  1831. getTaskInstanceByIdFn(workOrderId) {
  1832. getTaskInstanceById(workOrderId).then((res) => {
  1833. let { data } = res;
  1834. if (data.length) {
  1835. data = data.filter((item) => item.taskId != -2);
  1836. let arr = data.findIndex(
  1837. (item) => item.sourceTaskId == this.taskObj.id
  1838. );
  1839. if (arr != -1) {
  1840. data.splice(0, arr);
  1841. }
  1842. this.$set(this.outsourceForm, 'newStepsList', data);
  1843. }
  1844. });
  1845. },
  1846. async pickAdd(type, dataList) {
  1847. if (this.workListIds.length > 1) {
  1848. return this.$message.warning('领料只能选择一个工单!');
  1849. } else if (this.workListIds.length < 1) {
  1850. return this.$message.warning('请选择工单!');
  1851. }
  1852. if (dataList.length == 0) {
  1853. this.pickingShow = true;
  1854. } else {
  1855. const res = await parameterGetByCode({
  1856. code: 'only_one_picking_order'
  1857. });
  1858. if (res.value == '1') {
  1859. return this.$message.warning('已有领料,不能重复领料!');
  1860. } else {
  1861. this.checkPick();
  1862. }
  1863. }
  1864. // this.checkPick();
  1865. // this.pickingShow = true;
  1866. },
  1867. async checkPick() {
  1868. await checkRepeatPick({
  1869. workOrderId: this.workListIds[0]
  1870. }).then((res) => {
  1871. if (res.data == 0) {
  1872. this.pickingShow = true;
  1873. } else {
  1874. this.$confirm('已经有领料是否继续重复领料?', '提示', {
  1875. confirmButtonText: '确定',
  1876. cancelButtonText: '取消',
  1877. type: 'warning'
  1878. })
  1879. .then(() => {
  1880. this.pickingShow = true;
  1881. })
  1882. .catch(() => {});
  1883. }
  1884. });
  1885. },
  1886. // 关闭领料弹窗
  1887. pickingClose(val) {
  1888. if (val) {
  1889. this.$nextTick(() => {
  1890. this.$refs.pickListRef.getList(this.workListIds);
  1891. });
  1892. this.refreshFirstArticlePickFeedStatus();
  1893. }
  1894. this.pickingShow = false;
  1895. },
  1896. rowClick(row, taskId) {
  1897. if (taskId) {
  1898. let params = {
  1899. categoryId: row.categoryId,
  1900. taskId: taskId
  1901. };
  1902. getByTaskId(params).then((res) => {
  1903. this.BomObj = res.data;
  1904. this.$forceUpdate();
  1905. });
  1906. }
  1907. },
  1908. rowTaskClick() {
  1909. if (taskId) {
  1910. let params = {
  1911. categoryId: row.categoryId,
  1912. taskId: taskId
  1913. };
  1914. getByTaskId(params).then((res) => {
  1915. this.BomObj = res.data;
  1916. this.$forceUpdate();
  1917. });
  1918. }
  1919. },
  1920. closePrenatalExamination() {
  1921. this.checkProductionResult();
  1922. },
  1923. //是否完成 产前准备 限制按钮
  1924. async checkProductionResult() {
  1925. if (
  1926. this.produceTaskInfo &&
  1927. this.workListIds.length > 0 &&
  1928. this.produceTaskInfo.id != -1
  1929. ) {
  1930. // 判断是否要求先完成 产前准备等事项
  1931. const result = await checkProductionResult({
  1932. produceTaskId: this.produceTaskInfo.id,
  1933. workOrderIds: this.workListIds
  1934. });
  1935. this.isPreProductionResult = result;
  1936. }
  1937. },
  1938. // 投料后 重新检测按钮状态
  1939. reloadFeeding() {
  1940. this.checkProductionResult();
  1941. this.refreshFirstArticlePickFeedStatus();
  1942. }
  1943. },
  1944. mounted() {
  1945. this.$nextTick(() => {
  1946. const targetElements =
  1947. document.getElementsByClassName('ele-admin-tabs');
  1948. if (targetElements.length > 0) {
  1949. // 遍历所有具有 'ele-admin-tabs' 类的元素
  1950. Array.from(targetElements).forEach((element) => {
  1951. // 对每个元素添加 'new-ele-admin-tabs' 类
  1952. element.classList.add('new-ele-admin-tabs');
  1953. });
  1954. }
  1955. });
  1956. },
  1957. destroyed() {
  1958. this.$nextTick(() => {
  1959. const targetElements =
  1960. document.getElementsByClassName('ele-admin-tabs');
  1961. if (targetElements.length > 0) {
  1962. Array.from(targetElements).forEach((element) => {
  1963. element.classList.remove('new-ele-admin-tabs');
  1964. });
  1965. }
  1966. });
  1967. }
  1968. };
  1969. </script>
  1970. <style lang="scss">
  1971. .content_box {
  1972. display: flex;
  1973. }
  1974. .content_box_tab {
  1975. width: 220px;
  1976. padding: 5px;
  1977. height: calc(100vh - 73px);
  1978. background-color: #fff;
  1979. overflow-y: auto;
  1980. }
  1981. .footBtn {
  1982. position: absolute;
  1983. bottom: 20px;
  1984. left: 0;
  1985. }
  1986. .new-ele-admin-tabs {
  1987. display: none !important;
  1988. }
  1989. .c_title {
  1990. color: #157a2c;
  1991. font-size: 16px;
  1992. font-weight: bold;
  1993. }
  1994. .tableZ_box {
  1995. border: 1px solid #e3e5e5;
  1996. margin: 6px 0;
  1997. &:last-child {
  1998. border-bottom: none;
  1999. }
  2000. .row {
  2001. width: 100%;
  2002. display: flex;
  2003. }
  2004. .col {
  2005. width: calc(100% / 5);
  2006. display: flex;
  2007. align-items: center;
  2008. // min-width: 200px;
  2009. min-height: 32px;
  2010. border-bottom: 1px solid #e3e5e5;
  2011. border-right: 1px solid #e3e5e5;
  2012. &:last-child {
  2013. border-right: none;
  2014. }
  2015. .name {
  2016. display: flex;
  2017. align-items: center;
  2018. padding: 4px;
  2019. width: 60px;
  2020. height: 100%;
  2021. background-color: #d0e4d5;
  2022. color: #000;
  2023. }
  2024. .content {
  2025. padding: 4px 6px;
  2026. color: #000;
  2027. }
  2028. }
  2029. .pd6 {
  2030. padding: 0 6px;
  2031. }
  2032. }
  2033. </style>
  2034. <style lang="scss" scoped>
  2035. .seek-list {
  2036. display: flex;
  2037. justify-content: space-between;
  2038. align-items: center;
  2039. padding: 10px 10px;
  2040. }
  2041. .task-toolbar {
  2042. display: flex;
  2043. align-items: center;
  2044. width: 100%;
  2045. margin-bottom: 2px;
  2046. }
  2047. .task-filter-input {
  2048. flex: 1;
  2049. min-width: 0;
  2050. ::v-deep .el-input__inner {
  2051. padding-left: 10px;
  2052. padding-right: 24px;
  2053. }
  2054. }
  2055. .task-toolbar-actions {
  2056. display: flex;
  2057. align-items: center;
  2058. flex-shrink: 0;
  2059. margin-left: 2px;
  2060. .el-button {
  2061. padding: 0;
  2062. min-width: auto;
  2063. margin-left: 2px;
  2064. &:first-child {
  2065. margin-left: 0;
  2066. }
  2067. }
  2068. }
  2069. .right_main_box {
  2070. background-color: #fff;
  2071. height: 100%;
  2072. box-sizing: border-box;
  2073. }
  2074. .index_box {
  2075. position: relative;
  2076. padding: 10px;
  2077. padding-bottom: 0;
  2078. width: 100%;
  2079. box-sizing: border-box;
  2080. min-width: 1280px !important;
  2081. height: calc(100vh - 60px);
  2082. // overflow-x: auto;
  2083. /* 当内容超出宽度时,允许水平滚动 */
  2084. white-space: nowrap;
  2085. /* 防止内部文本换行,确保所有内容都在一行显示 */
  2086. scrollbar-width: thin;
  2087. /* 设置滚动条宽度(浏览器兼容性可能有所不同) */
  2088. scrollbar-color: #40a9ff transparent;
  2089. /* 设置滚动条颜色和轨道颜色(同样,浏览器兼容性) */
  2090. }
  2091. .main {
  2092. width: 100%;
  2093. min-width: 1280px;
  2094. height: calc(100vh - 70px - 50px - 80px);
  2095. display: flex;
  2096. justify-content: space-between;
  2097. }
  2098. .left_main {
  2099. width: 100%;
  2100. height: 100%;
  2101. display: flex;
  2102. flex-direction: column;
  2103. justify-content: space-around;
  2104. min-width: 640px;
  2105. .top {
  2106. width: 100%;
  2107. height: 100%;
  2108. overflow: hidden;
  2109. }
  2110. // .bottom {
  2111. // width: 100%;
  2112. // min-height: calc((100vh - 70px - 50px - 80px - 20px) / 2);
  2113. // overflow: hidden;
  2114. // }
  2115. }
  2116. ::v-deep .el-tabs__item.is-active {
  2117. background-color: #dffade;
  2118. /* 蓝色背景 */
  2119. color: #333;
  2120. }
  2121. ::v-deep .is-active {
  2122. color: #dffade;
  2123. }
  2124. .right_main {
  2125. min-width: 640px;
  2126. padding-bottom: 12px;
  2127. height: calc((100vh - 70px - 50px - 80px - 12px));
  2128. background: #f0f3f3;
  2129. }
  2130. ::v-deep .el-tree-node__content > .el-tree-node__expand-icon {
  2131. padding: 0 !important;
  2132. }
  2133. // .menu-container {
  2134. // position: relative;
  2135. // width: 200px;
  2136. // height: 200px;
  2137. // margin: 100px;
  2138. // }
  2139. /* 主按钮 */
  2140. // .main-btn {
  2141. // width: 60px;
  2142. // height: 60px;
  2143. // background: #3498db;
  2144. // border-radius: 50%;
  2145. // color: #fff;
  2146. // font-size: 30px;
  2147. // text-align: center;
  2148. // line-height: 60px;
  2149. // cursor: pointer;
  2150. // position: absolute;
  2151. // left: 0;
  2152. // bottom: 0;
  2153. // box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
  2154. // transition: transform 0.3s;
  2155. // }
  2156. // .main-btn:hover {
  2157. // transform: rotate(90deg);
  2158. // }
  2159. /* 子按钮 */
  2160. // .sub-btn {
  2161. // width: 40px;
  2162. // height: 40px;
  2163. // background: #e74c3c;
  2164. // border-radius: 50%;
  2165. // color: #fff;
  2166. // font-size: 14px;
  2167. // text-align: center;
  2168. // line-height: 50px;
  2169. // position: absolute;
  2170. // left: 5px;
  2171. // bottom: 5px;
  2172. // box-shadow: 0 3px 8px rgba(0, 0, 0, 0.25);
  2173. // transform: translate(0, 0);
  2174. // transition: all 0.4s ease;
  2175. // opacity: 1;
  2176. // }
  2177. /* 动画进入/离开 */
  2178. // .fan-enter-active,
  2179. // .fan-leave-active {
  2180. // transition: all 0.4s ease;
  2181. // }
  2182. // .fan-enter,
  2183. // .fan-leave-to {
  2184. // opacity: 0;
  2185. // transform: translate(0, 0);
  2186. // }
  2187. // .box {
  2188. // position: relative;
  2189. // }
  2190. .menu-container {
  2191. position: fixed;
  2192. right: 0;
  2193. margin-top: 42.5%;
  2194. width: 235px;
  2195. height: 100px;
  2196. display: flex;
  2197. justify-content: center;
  2198. align-items: center;
  2199. z-index: 999;
  2200. }
  2201. .toggle-btn {
  2202. position: absolute;
  2203. width: 55px;
  2204. height: 55px;
  2205. background: #2196f3;
  2206. border-radius: 50%;
  2207. display: flex;
  2208. justify-content: center;
  2209. align-items: center;
  2210. color: white;
  2211. font-size: 30px;
  2212. font-weight: bold;
  2213. cursor: pointer;
  2214. box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
  2215. z-index: 100;
  2216. transition: all 0.3s ease;
  2217. border: none;
  2218. left: 60%;
  2219. top: 60%;
  2220. transform: translate(-50%, -50%);
  2221. }
  2222. .toggle-btn:hover {
  2223. transform: translate(-50%, -50%) scale(1.05);
  2224. box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3);
  2225. }
  2226. .toggle-btn:active {
  2227. transform: translate(-50%, -50%) scale(0.95);
  2228. }
  2229. .menu-item {
  2230. position: absolute;
  2231. width: 50px;
  2232. height: 50px;
  2233. background: #4caf50;
  2234. border-radius: 50%;
  2235. display: flex;
  2236. justify-content: center;
  2237. align-items: center;
  2238. color: white;
  2239. font-size: 12px;
  2240. font-weight: bold;
  2241. box-shadow: 0 6px 15px rgba(0, 0, 0, 0.2);
  2242. transition: all 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
  2243. transform: translate(-50%, -50%) scale(0);
  2244. opacity: 0;
  2245. pointer-events: none;
  2246. z-index: 90;
  2247. left: 55%;
  2248. top: 60%;
  2249. }
  2250. .menu-item.active {
  2251. opacity: 1;
  2252. pointer-events: auto;
  2253. transform: translate(var(--tx), var(--ty)) scale(1);
  2254. }
  2255. .menu-item:hover {
  2256. transform: translate(var(--tx), var(--ty)) scale(1.15) !important;
  2257. box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
  2258. background: #66bb6a;
  2259. cursor: pointer;
  2260. }
  2261. .instructions {
  2262. margin-top: 2rem;
  2263. color: white;
  2264. text-align: center;
  2265. background: rgba(255, 255, 255, 0.1);
  2266. padding: 1rem;
  2267. border-radius: 10px;
  2268. max-width: 500px;
  2269. backdrop-filter: blur(5px);
  2270. }
  2271. .custom-tree-node {
  2272. // position: absolute;
  2273. // flex: 1;
  2274. // display: flex;
  2275. // align-items: center;
  2276. // justify-content: space-between;
  2277. font-size: 14px;
  2278. padding-right: 8px;
  2279. }
  2280. .item {
  2281. margin-top: 10px;
  2282. margin-right: 40px;
  2283. }
  2284. </style>