index.vue 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563
  1. <template>
  2. <div class="ele-body">
  3. <el-card shadow="never" v-loading="loading">
  4. <productionPlan-search
  5. @search="reload"
  6. ref="searchRef"
  7. :statusOpt="statusOpt"
  8. :planType="planType"
  9. :activeName="activeName"
  10. >
  11. </productionPlan-search>
  12. <!-- <div class="statistics">
  13. <el-row :gutter="24">
  14. <el-col :span="cardSpan">
  15. <el-card shadow="hover" class="cardItem">
  16. <div>
  17. <div class="cardText">待排产计划数量</div>
  18. <div class="cardNum">{{ planStatistics.waitPlanNum }}</div>
  19. </div>
  20. </el-card>
  21. </el-col>
  22. <el-col :span="cardSpan">
  23. <el-card shadow="hover" class="cardItem">
  24. <div>
  25. <div class="cardText">计划生产数量</div>
  26. <div class="cardNum">{{ planStatistics.planNum }}</div>
  27. </div>
  28. </el-card>
  29. </el-col>
  30. <el-col :span="cardSpan">
  31. <el-card shadow="hover" class="cardItem">
  32. <div>
  33. <div class="cardText">已下发生产数量</div>
  34. <div class="cardNum">{{ planStatistics.issueNum }}</div>
  35. </div>
  36. </el-card>
  37. </el-col>
  38. <el-col :span="cardSpan">
  39. <el-card shadow="hover" class="cardItem">
  40. <div>
  41. <div class="cardText">待派工数量</div>
  42. <div class="cardNum">0</div>
  43. </div>
  44. </el-card>
  45. </el-col>
  46. <el-col :span="cardSpan">
  47. <el-card shadow="hover" class="cardItem">
  48. <div>
  49. <div class="cardText">待完工生产数量</div>
  50. <div class="cardNum">{{ planStatistics.waitFinishNum }}</div>
  51. </div>
  52. </el-card>
  53. </el-col>
  54. <el-col :span="cardSpan">
  55. <el-card shadow="hover" class="cardItem">
  56. <div>
  57. <div class="cardText">待领料数量</div>
  58. <div class="cardNum">0</div>
  59. </div>
  60. </el-card>
  61. </el-col>
  62. <el-col :span="cardSpan">
  63. <el-card shadow="hover" class="cardItem">
  64. <div>
  65. <div class="cardText">已完工数量</div>
  66. <div class="cardNum">{{ planStatistics.finishNum }}</div>
  67. </div>
  68. </el-card>
  69. </el-col>
  70. <el-col :span="cardSpan">
  71. <el-card shadow="hover" class="cardItem">
  72. <div>
  73. <div class="cardText">已入库数量</div>
  74. <div class="cardNum">{{ planStatistics.stockNum }}</div>
  75. </div>
  76. </el-card>
  77. </el-col>
  78. </el-row>
  79. </div> -->
  80. <div class="btn_box">
  81. <el-button
  82. type="success"
  83. size="mini"
  84. v-if="
  85. timeDimensionPlanType == 3 &&
  86. $hasPermission('aps:productionplan:add')
  87. "
  88. @click="factAdd(3)"
  89. >新增</el-button
  90. >
  91. <!-- <el-button type="success" size="mini" @click="homogeneityInspect"
  92. >齐套性检查</el-button
  93. > -->
  94. <el-dropdown
  95. trigger="click"
  96. @command="homogeneityInspect"
  97. v-if="$hasPermission('aps:productionpaln:homogeneityInspect')"
  98. >
  99. <el-button size="mini" type="success">齐套性检查</el-button>
  100. <el-dropdown-menu slot="dropdown">
  101. <el-dropdown-item command="1"> 自制件 </el-dropdown-item>
  102. <el-dropdown-item command="2"> 采购件 </el-dropdown-item>
  103. <el-dropdown-item command="4"> 受托件 </el-dropdown-item>
  104. </el-dropdown-menu>
  105. </el-dropdown>
  106. <el-button
  107. type="primary"
  108. size="mini"
  109. v-if="
  110. isshow && $hasPermission('aps:productionplan:plandecomposition')
  111. "
  112. @click="disassemblePlan"
  113. >计划分解</el-button
  114. >
  115. <el-button
  116. type="primary"
  117. size="mini"
  118. v-if="$hasPermission('aps:productionplan:orderplan')"
  119. >补单计划</el-button
  120. >
  121. <el-button
  122. type="info"
  123. size="mini"
  124. v-if="$hasPermission('aps:productionplan:plannedcalendar')"
  125. >计划行事历</el-button
  126. >
  127. <el-button
  128. type="warning"
  129. size="mini"
  130. v-if="$hasPermission('aps:productionplan:alertsettings')"
  131. >预警设置</el-button
  132. >
  133. <el-button
  134. type="primary"
  135. size="mini"
  136. v-if="isshow && $hasPermission('aps:productionplan:batchmerging')"
  137. @click="handleMerge"
  138. >合批</el-button
  139. >
  140. <el-button
  141. type="danger"
  142. size="mini"
  143. v-if="$hasPermission('aps:productionplan:extensionapplication')"
  144. >延期申请</el-button
  145. >
  146. <el-button
  147. type="danger"
  148. size="mini"
  149. v-if="$hasPermission('aps:productionplan:changerequest')"
  150. >变更申请</el-button
  151. >
  152. <!-- <el-button type="danger" size="mini" @click="planDotLine"
  153. >计划布点</el-button
  154. > -->
  155. <!-- <el-button
  156. class="my-btn"
  157. size="mini"
  158. v-if="$hasPermission('aps:productionplan:changerequest')"
  159. >补料申请</el-button
  160. > -->
  161. <!-- <el-button type="primary" size="mini" @click="productionPreparations"
  162. >生产前准备</el-button
  163. > -->
  164. <el-button
  165. type="info"
  166. icon="el-icon-upload2"
  167. size="mini"
  168. @click="$refs.importDialogRef.open()"
  169. v-if="isImport && $hasPermission('aps:productionplan:upload')"
  170. >导入</el-button
  171. >
  172. </div>
  173. <el-tabs
  174. v-model="activeName"
  175. type="card"
  176. size="mini"
  177. @tab-click="handleSele"
  178. >
  179. <el-tab-pane label="未发布" name="first"></el-tab-pane>
  180. <el-tab-pane label="已发布" name="second"></el-tab-pane>
  181. <el-tab-pane label="已变更" name="change"></el-tab-pane>
  182. </el-tabs>
  183. <!-- 数据表格 -->
  184. <ele-pro-table
  185. ref="table"
  186. :key="activeName"
  187. :initLoad="false"
  188. :columns="columns"
  189. :datasource="datasource"
  190. row-key="code"
  191. :selection.sync="selection"
  192. :cache-key="cacheKeyUrl"
  193. @sort-change="onSortChange"
  194. autoAmendPage
  195. :parse-data="parseData"
  196. @update:selection="handleSelectionChange"
  197. @columns-change="handleColumnChange"
  198. height="calc(100vh - 390px)"
  199. full-height="calc(100vh - 116px)"
  200. :page-size="20"
  201. >
  202. <template v-slot:batchNo="{ row }">
  203. <el-link type="primary" :underline="false">
  204. <!-- @click.stop="splitDetails(1, row)" -->
  205. <el-tag type="success" size="mini" v-if="row.joinPlanCode">
  206. 拆</el-tag
  207. >
  208. <el-tag
  209. type="danger"
  210. size="mini"
  211. v-if="row.splitBatch == 2"
  212. @click.stop="splitDetails(2, row)"
  213. >
  214. 合</el-tag
  215. >
  216. {{ row.batchNo }}
  217. </el-link>
  218. </template>
  219. <template v-slot:selection="{ row }">
  220. <div class="check_box" @click="handOneSelection(row)">
  221. <div class="check act_check" v-if="selectionFilter(row)">
  222. <i class="el-icon-check"></i>
  223. </div>
  224. <div class="check" v-else></div>
  225. </div>
  226. </template>
  227. <template v-slot:code="{ row }">
  228. <el-link type="primary" :underline="false" @click="goDetail(row)">
  229. {{ row.code }}
  230. </el-link>
  231. </template>
  232. <template v-slot:salesCode="{ row }">
  233. {{ row.salesCode }}
  234. </template>
  235. <template v-slot:priority="{ row }">
  236. <div style="display: flex">
  237. <el-input
  238. v-model="row.priority"
  239. type="number"
  240. size="mini"
  241. :min="0"
  242. :max="10"
  243. @change="priorityChange(row)"
  244. style="width: 80px"
  245. >
  246. </el-input>
  247. <el-popover
  248. placement="right"
  249. width="200"
  250. trigger="hover"
  251. content="数值越大优先级越高(0-3普通, 4-6优先, 7-10紧急)"
  252. >
  253. <div class="sort-wrap" slot="reference">
  254. <i class="el-icon-caret-top" @click="sortTop(row)"></i>
  255. <i class="el-icon-caret-bottom" @click="sortBottom(row)"></i>
  256. </div>
  257. </el-popover>
  258. </div>
  259. </template>
  260. <template v-slot:productNum="{ row }">
  261. <span v-if="row.productNum">
  262. {{ row.productNum }} {{ row.measuringUnit }}
  263. </span>
  264. </template>
  265. <template v-slot:productWeight="{ row }">
  266. {{ row.productWeight }} {{ row.weightUnit }}
  267. </template>
  268. <template v-slot:requiredFormingNum="{ row }">
  269. {{ row.requiredFormingNum }} {{ row.measuringUnit }}
  270. </template>
  271. <template v-slot:newSumOrderWeight="{ row }">
  272. {{ row.newSumOrderWeight }} {{ row.newWeightUnit }}
  273. </template>
  274. <template v-slot:status="{ row }">
  275. <span :class="{ 'ele-text-danger': row.status == 3 }">
  276. {{ statusFormatter(row.status) }}
  277. </span>
  278. </template>
  279. <!-- 操作列 -->
  280. <template v-slot:action="{ row }">
  281. <el-link
  282. type="primary"
  283. :underline="false"
  284. v-if="canApprove(row)"
  285. @click="handleOrderPublish(1, row)"
  286. >
  287. 审批
  288. </el-link>
  289. <el-link
  290. type="primary"
  291. v-if="
  292. row.status == 3 && $hasPermission('aps:productionplan:release')
  293. "
  294. :underline="false"
  295. @click="handleOrderPublish(2, row)"
  296. >
  297. 重新发起审批
  298. </el-link>
  299. <el-link
  300. v-if="
  301. row.splitBatch != 2 &&
  302. row.splitBatch != 1 &&
  303. !row.joinPlanCode &&
  304. activeName == 'first' &&
  305. $hasPermission('aps:productionplan:update') &&
  306. row.approvalStatus != 1
  307. "
  308. type="primary"
  309. :underline="false"
  310. @click="planEdit(row)"
  311. >
  312. 修改
  313. </el-link>
  314. <el-link
  315. v-if="
  316. row.joinPlanCode &&
  317. activeName == 'first' &&
  318. row.status != 4 &&
  319. $hasPermission('aps:productionplan:delete')
  320. "
  321. type="danger"
  322. :underline="false"
  323. @click="handleDel(row)"
  324. >
  325. 删除
  326. </el-link>
  327. <el-link
  328. v-if="
  329. !row.joinPlanCode &&
  330. !row.childList.length &&
  331. activeName == 'first' &&
  332. isLineNumbre &&
  333. row.status != 4 &&
  334. $hasPermission('aps:productionplan:delete')
  335. "
  336. type="danger"
  337. :underline="false"
  338. @click="handleDel(row)"
  339. >
  340. 删除
  341. </el-link>
  342. <el-link
  343. v-if="
  344. clientEnvironmentId != 4 &&
  345. activeName == 'first' &&
  346. row.splitBatch != 2 &&
  347. !row.joinPlanCode &&
  348. $hasPermission('aps:productionplan:dismantlingbatch') &&
  349. row.approvalStatus != 1
  350. "
  351. type="primary"
  352. :underline="false"
  353. @click="toUnpack(row)"
  354. >
  355. 拆批
  356. </el-link>
  357. <el-link
  358. type="primary"
  359. :underline="false"
  360. v-if="
  361. planDotLineEnabled &&
  362. (row.status == 3 || row.status == 2) &&
  363. row.approvalStatus != 1
  364. "
  365. @click="planDotLine(row)"
  366. >
  367. 布点
  368. </el-link>
  369. <el-link
  370. type="primary"
  371. :underline="false"
  372. v-if="
  373. row.approvalStatus != 1 && (row.status == 3 || row.status == 2)
  374. "
  375. @click="productionPreparations(row)"
  376. >
  377. 生产准备
  378. </el-link>
  379. </template>
  380. </ele-pro-table>
  381. </el-card>
  382. <unpackDialog ref="unpackRef" @success="newReload" />
  383. <mergeDialog ref="mergeRef" @success="reload"></mergeDialog>
  384. <unpackDetails ref="DetailsRef"></unpackDetails>
  385. <homogeneityInspectDialog
  386. ref="homogeneityInspectDialog"
  387. @success="reload"
  388. />
  389. <homogeneityInspectInstallDialog
  390. ref="homogeneityInspectInstallDialog"
  391. @success="reload"
  392. />
  393. <disassemblePlanPop
  394. ref="disassemblePlanRef"
  395. @close="reload"
  396. ></disassemblePlanPop>
  397. <!-- v-if="factoryShow" :factoryObj="factoryObj" -->
  398. <factoryAdd
  399. ref="factoryAddRef"
  400. :factoryType="factoryType"
  401. @close="factoryClose"
  402. ></factoryAdd>
  403. <importDialog
  404. ref="importDialogRef"
  405. @success="reload"
  406. :fileUrl="'/aps/productionplan/importTemplate'"
  407. :isWeb="false"
  408. fileName="生产临时计划模板"
  409. apiUrl="/aps/productionplan/importFile"
  410. />
  411. <processDetail ref="processDetailRef" />
  412. <checkProductionPreparations
  413. ref="checkProductionPreparationsRef"
  414. type="plan"
  415. @update="reload"
  416. />
  417. <planDotLine ref="planDotLineRef" @success="reload" />
  418. </div>
  419. </template>
  420. <script>
  421. import {
  422. getList,
  423. del,
  424. updatePriority,
  425. getPlanStatistics,
  426. factoryDelete,
  427. planIsReview
  428. } from '@/api/productionPlan/index.js';
  429. import productionPlanSearch from './components/productionPlan-search.vue';
  430. import unpackDialog from './components/unpackDialog.vue';
  431. import mergeDialog from './components/mergeDialog.vue';
  432. import homogeneityInspectDialog from './components/homogeneityInspectDialog.vue';
  433. import homogeneityInspectInstallDialog from './components/homogeneityInspectInstallDialog.vue';
  434. import unpackDetails from './components/unpackDetails.vue';
  435. import disassemblePlanPop from './components/disassemblePlanPop.vue';
  436. import factoryAdd from './components/factoryAdd/index.vue';
  437. import { release, releaseByApproval } from '@/api/productionPlan/order.js';
  438. import { getCode } from '@/api/codeManagement';
  439. import { fieldModel } from '@/api/saleOrder';
  440. import { debounce } from 'lodash';
  441. import tabMixins from '@/mixins/tableColumnsMixin';
  442. import importDialog from '@/components/upload/import-dialog.vue';
  443. import { parameterGetByCode } from '@/api/mainData/index';
  444. import processDetail from './components/detail/processDetail.vue';
  445. import checkProductionPreparations from './components/checkProductionPreparations.vue';
  446. import planDotLine from './components/planDotLine.vue';
  447. import {
  448. findBomCategoryByCategoryId,
  449. listBomType
  450. } from '@/api/productionPlan/index';
  451. export default {
  452. mixins: [tabMixins],
  453. components: {
  454. productionPlanSearch,
  455. unpackDialog,
  456. mergeDialog,
  457. unpackDetails,
  458. disassemblePlanPop,
  459. factoryAdd,
  460. homogeneityInspectDialog,
  461. homogeneityInspectInstallDialog,
  462. importDialog,
  463. processDetail,
  464. checkProductionPreparations,
  465. planDotLine
  466. },
  467. props: {
  468. timeDimensionPlanType: { type: Number, default: 1 },
  469. isLineNumbre: {
  470. default: false
  471. },
  472. isImport: {
  473. default: false
  474. },
  475. cacheKeyUrl: { type: String, default: '513b2388-aps-productionPlan' }
  476. },
  477. data() {
  478. return {
  479. planStatistics: {
  480. waitPlanNum: 0,
  481. planNum: 0,
  482. issueNum: 0,
  483. waitFinishNum: 0,
  484. finishNum: 0,
  485. stockNum: 0
  486. },
  487. activeName: 'first',
  488. isshow: true,
  489. // 加载状态
  490. loading: false,
  491. pageType: 'add',
  492. dialogTitle: '',
  493. isBindPlan: false,
  494. tabMixinsInit: false,
  495. statusOpt: {
  496. first: [
  497. { label: '所有状态', value: '3,2' },
  498. { label: '待发布', value: '2' },
  499. { label: '发布失败', value: '3' },
  500. { label: '已发布', value: '4' }
  501. ],
  502. second: [
  503. { label: '所有状态', value: '7,4,5,6' },
  504. { label: '待生产', value: '4' },
  505. { label: '生产中', value: '5' },
  506. { label: '已完成', value: '6' },
  507. { label: '已延期', value: '7' }
  508. ],
  509. change: [{ label: '已变更', value: '9' }]
  510. },
  511. planType: [
  512. { label: '所有计划类型', value: null },
  513. { label: '内销计划', value: '1' },
  514. { label: '外销计划', value: '2' },
  515. { label: '预制计划', value: '3' },
  516. { label: '改型计划', value: '4' },
  517. { label: '返工返修计划', value: '5' }
  518. ],
  519. columns: [],
  520. selection: [],
  521. clientEnvironmentId: '',
  522. // factoryShow: false,
  523. factoryType: 3,
  524. factoryObj: {},
  525. cardSpan: 3,
  526. columnsVersion: 1,
  527. isReview: false,
  528. planDotLineEnabled: false
  529. // homogeneityDialog: false
  530. };
  531. },
  532. computed: {
  533. // clientEnvironmentId() {
  534. // return this.$store.state.user.info.clientEnvironmentId;
  535. // },
  536. // 表格列配置
  537. // columns() {
  538. // const num = this.columnsVersion;
  539. // const opt = {
  540. // first: [],
  541. // second: [
  542. // {
  543. // prop: 'releaseTime',
  544. // label: '工单发布日期',
  545. // align: 'center',
  546. // minWidth: 110
  547. // },
  548. // {
  549. // prop: 'planFormingTime',
  550. // label: '预测生产日期',
  551. // align: 'center',
  552. // minWidth: 110
  553. // },
  554. // {
  555. // prop: 'deliveryTime',
  556. // label: '预测交货日期',
  557. // align: 'center',
  558. // minWidth: 110
  559. // },
  560. // {
  561. // prop: 'formingTime',
  562. // label: '实际交货日期',
  563. // align: 'center',
  564. // minWidth: 110
  565. // }
  566. // ],
  567. // change: []
  568. // };
  569. // return
  570. // }
  571. },
  572. created() {
  573. this.setColumns();
  574. this.getFieldModel();
  575. this.getPlanDotLine();
  576. },
  577. mounted() {
  578. this.clientEnvironmentId =
  579. this.$store.state.user.info.clientEnvironmentId;
  580. this.getPlanStatistics();
  581. this.getplannedReleaseRequire('planned_release_require');
  582. },
  583. methods: {
  584. canApprove(row) {
  585. const canRelease =
  586. row.status == 2 &&
  587. row.splitBatch != 1 &&
  588. row.approvalStatus != 1 &&
  589. row.approvalStatus != 2 &&
  590. this.$hasPermission('aps:productionplan:release');
  591. // 开启计划布点参数时,必须完成布点才允许审批
  592. if (this.planDotLineEnabled) {
  593. return canRelease && row.dotLineStatus == 1;
  594. }
  595. return canRelease;
  596. },
  597. setColumns() {
  598. let clientEnvironmentId =
  599. this.$store.state.user.info.clientEnvironmentId;
  600. this.columns = [
  601. {
  602. width: 45,
  603. type: 'selection',
  604. columnKey: 'selection',
  605. align: 'center',
  606. slot: 'selection'
  607. },
  608. {
  609. columnKey: 'index',
  610. label: '序号',
  611. type: 'index',
  612. width: 55,
  613. align: 'center',
  614. showOverflowTooltip: true
  615. },
  616. {
  617. slot: 'batchNo',
  618. prop: 'batchNo',
  619. label: '批次号',
  620. align: 'center',
  621. minWidth: 140,
  622. sortable: true
  623. },
  624. this.isLineNumbre
  625. ? {
  626. prop: 'lineNumber',
  627. label: '行号',
  628. align: 'center',
  629. showOverflowTooltip: true
  630. }
  631. : {
  632. width: 1
  633. },
  634. {
  635. slot: 'code',
  636. prop: 'code',
  637. action: 'code',
  638. label: '计划编号',
  639. align: 'center',
  640. minWidth: 160,
  641. sortable: true
  642. },
  643. {
  644. prop: 'salesCode',
  645. action: 'salesCode',
  646. label: '销售订单号',
  647. align: 'center',
  648. minWidth: 160
  649. },
  650. {
  651. prop: 'taskName',
  652. action: 'taskName',
  653. label: '工序进度',
  654. align: 'center',
  655. minWidth: 160
  656. },
  657. // {
  658. // prop: 'mesStatusName',
  659. // label: '工单状态',
  660. // align: 'center',
  661. // minWidth: 160
  662. // },
  663. {
  664. prop: 'productCode',
  665. label: '编码',
  666. align: 'center',
  667. minWidth: 140
  668. },
  669. {
  670. prop: 'productName',
  671. label: '名称',
  672. align: 'center',
  673. showOverflowTooltip: true,
  674. minWidth: 140
  675. },
  676. {
  677. prop: 'specification',
  678. label: '规格',
  679. align: 'center',
  680. minWidth: 150,
  681. showOverflowTooltip: true
  682. },
  683. {
  684. prop: 'stockNum',
  685. label: '库存',
  686. align: 'center',
  687. minWidth: 100,
  688. showOverflowTooltip: true
  689. },
  690. {
  691. prop: 'productionCodes',
  692. label: '生产编号',
  693. align: 'center',
  694. minWidth: 150,
  695. showOverflowTooltip: true
  696. },
  697. {
  698. prop: 'productionRequirements',
  699. label: '生产要求',
  700. align: 'center',
  701. minWidth: 200,
  702. showOverflowTooltip: true
  703. },
  704. {
  705. prop: 'model',
  706. label: '型号',
  707. align: 'center',
  708. showOverflowTooltip: true
  709. },
  710. {
  711. prop: 'brandNo',
  712. label: '牌号',
  713. align: 'center',
  714. showOverflowTooltip: true
  715. },
  716. {
  717. prop: 'priority',
  718. label: '优先级',
  719. align: 'center',
  720. minWidth: 120,
  721. slot: 'priority',
  722. sortable: 'custom'
  723. },
  724. {
  725. prop: 'productType',
  726. label: 'BOM类型',
  727. align: 'center',
  728. width: 120,
  729. formatter: (row) => {
  730. if (row.produceType == 1) {
  731. return 'PBOM';
  732. }
  733. if (row.produceType == 2) {
  734. return 'MBOM';
  735. }
  736. if (row.produceType == 3) {
  737. return 'ABOM';
  738. }
  739. return '';
  740. }
  741. },
  742. {
  743. prop: 'bomCategoryName',
  744. label: 'BOM版本',
  745. align: 'center',
  746. width: 130,
  747. showOverflowTooltip: true,
  748. formatter: (row) => {
  749. if (row.bomCategoryName) {
  750. return `${row.bomCategoryName} (V${row.bomCategoryVersions}.0)`;
  751. }
  752. return '';
  753. }
  754. },
  755. {
  756. prop: 'produceRoutingName',
  757. label: '工艺路线',
  758. align: 'center',
  759. width: 140,
  760. showOverflowTooltip: true
  761. },
  762. {
  763. prop: 'modelKey',
  764. label: '机型',
  765. align: 'center',
  766. minWidth: 120,
  767. showOverflowTooltip: true
  768. },
  769. {
  770. prop: 'colorKey',
  771. label: '颜色',
  772. align: 'center',
  773. minWidth: 120,
  774. showOverflowTooltip: true
  775. },
  776. {
  777. prop: 'productNum',
  778. label: '订单数量',
  779. align: 'center',
  780. slot: 'productNum'
  781. },
  782. {
  783. prop: 'productWeight',
  784. label: '计划重量',
  785. align: 'center',
  786. slot: 'productWeight'
  787. },
  788. {
  789. prop: 'requiredFormingNum',
  790. label: '计划生产数量',
  791. align: 'center',
  792. slot: 'requiredFormingNum'
  793. },
  794. {
  795. prop: 'newSumOrderWeight',
  796. label: '要求生产重量',
  797. align: 'center',
  798. slot: 'newSumOrderWeight',
  799. formatter: (row) => {
  800. if (row.newSumOrderWeight) {
  801. return `${row.newSumOrderWeight}${row.newWeightUnit}`;
  802. }
  803. }
  804. },
  805. // {
  806. // prop: 'scheduleStatusName',
  807. // label: '进度状态',
  808. // align: 'center',
  809. // minWidth: 100
  810. // },
  811. // {
  812. // prop: '',
  813. // label: '已排产数量',
  814. // align: 'center',
  815. // showOverflowTooltip: true
  816. // },
  817. // {
  818. // prop: '',
  819. // label: '未排产数量',
  820. // align: 'center',
  821. // showOverflowTooltip: true
  822. // },
  823. // {
  824. // prop: '',
  825. // label: '已生产数量',
  826. // align: 'center',
  827. // showOverflowTooltip: true
  828. // },
  829. // {
  830. // prop: '',
  831. // label: '未生产数量',
  832. // align: 'center',
  833. // showOverflowTooltip: true
  834. // },
  835. {
  836. prop: 'factoriesName',
  837. label: '所属工厂',
  838. align: 'center'
  839. },
  840. // {
  841. // prop: '',
  842. // label: '合格品数',
  843. // align: 'center'
  844. // },
  845. // {
  846. // prop: '',
  847. // label: '不合格品数',
  848. // align: 'center'
  849. // },
  850. // {
  851. // prop: '',
  852. // label: '合格率',
  853. // align: 'center'
  854. // },
  855. {
  856. prop: 'moCount',
  857. label: '模数',
  858. align: 'center',
  859. show: clientEnvironmentId == '4'
  860. },
  861. {
  862. prop: 'blockCount',
  863. label: '块数',
  864. align: 'center',
  865. show: clientEnvironmentId == '4'
  866. },
  867. {
  868. prop: 'noWordCount',
  869. label: '未排程块数',
  870. align: 'center',
  871. show: clientEnvironmentId == '4',
  872. minWidth: 110
  873. },
  874. {
  875. prop: 'planDeliveryTime',
  876. label: '计划交付日期',
  877. align: 'center',
  878. width: 110,
  879. showOverflowTooltip: true
  880. },
  881. {
  882. prop: 'reqMoldTime',
  883. label: '订单要求计划交付日期',
  884. align: 'center',
  885. width: 110,
  886. showOverflowTooltip: true
  887. },
  888. {
  889. prop: 'startTime',
  890. label: '计划开始日期',
  891. align: 'center',
  892. width: 110,
  893. showOverflowTooltip: true
  894. },
  895. {
  896. prop: 'endTime',
  897. label: '计划结束日期',
  898. align: 'center',
  899. width: 110,
  900. showOverflowTooltip: true
  901. },
  902. {
  903. prop: 'orderType',
  904. label: '计划类型',
  905. align: 'center',
  906. formatter: (row) => {
  907. const obj = this.planType.find((i) => i.value == row.planType);
  908. return obj && obj.label;
  909. }
  910. },
  911. {
  912. prop: 'version',
  913. label: '版本',
  914. align: 'center',
  915. minWidth: 80
  916. },
  917. {
  918. prop: 'createTime',
  919. label: '创建时间',
  920. align: 'center',
  921. width: 110,
  922. showOverflowTooltip: true
  923. },
  924. {
  925. columnKey: 'status',
  926. slot: 'status',
  927. label: '状态',
  928. align: 'center',
  929. formatter: (row) => {
  930. const obj = this.statusOpt[this.activeName].find(
  931. (i) => i.value == row.status
  932. );
  933. return obj && obj.label;
  934. }
  935. },
  936. {
  937. prop: 'customerName',
  938. label: '客户名称',
  939. align: 'center',
  940. showOverflowTooltip: true
  941. },
  942. {
  943. prop: 'serialNo',
  944. label: '客户代号',
  945. align: 'center',
  946. showOverflowTooltip: true
  947. },
  948. {
  949. prop: 'simpleName',
  950. label: '客户简称',
  951. align: 'center',
  952. showOverflowTooltip: true
  953. }
  954. ];
  955. },
  956. getPlanDotLine() {
  957. parameterGetByCode({
  958. code: 'plan_dot_line'
  959. }).then((res) => {
  960. if (res) {
  961. this.planDotLineEnabled = res.value == '1' ? true : false;
  962. }
  963. });
  964. },
  965. handleSele(e) {
  966. if (e.index === '1') {
  967. this.isshow = false;
  968. } else {
  969. this.isshow = true;
  970. }
  971. },
  972. async getplannedReleaseRequire(code) {
  973. parameterGetByCode({ code }).then((res) => {
  974. if (res) {
  975. this.isReview = res.value == '1' ? true : false;
  976. console.log(this.isReview, 'isReview');
  977. }
  978. });
  979. },
  980. async getPlanStatistics() {
  981. let res = await getPlanStatistics();
  982. console.log(res);
  983. this.planStatistics = res;
  984. },
  985. // handleClick(val) {
  986. // console.log(val, 'val');
  987. // // this.$emit('check');
  988. // },
  989. homogeneityInspect(val) {
  990. if (this.selection.length == 0) {
  991. this.$message.warning('请至少选择一条计划!');
  992. return;
  993. }
  994. for (let i = 0; i < this.selection.length; i++) {
  995. let el = this.selection[i];
  996. // if (!el.bomCategoryId) {
  997. // return this.$message.warning('请选择有BOM版本的数据');
  998. // }
  999. }
  1000. console.log(val, 'val');
  1001. // this.homogeneityDialog = true;
  1002. this.$refs.homogeneityInspectDialog.open(this.selection, val);
  1003. // this.$nextTick(() => {
  1004. // });
  1005. // let flag = false;
  1006. // let type = 0;
  1007. // for (let item of this.selection) {
  1008. // type = item.produceType;
  1009. // for (let ele of this.selection) {
  1010. // if (item.produceType != ele.produceType) {
  1011. // flag = true;
  1012. // break;
  1013. // }
  1014. // }
  1015. // }
  1016. // if (flag) {
  1017. // this.$message.warning('请选择生产类型相同的计划!');
  1018. // return;
  1019. // }
  1020. // console.log(type);
  1021. // if (type == 2) {
  1022. // this.$refs.homogeneityInspectDialog.open(this.selection);
  1023. // } else if (type == 3) {
  1024. // this.$refs.homogeneityInspectInstallDialog.open(this.selection);
  1025. // } else {
  1026. // this.$message.warning('请确认生产类型!');
  1027. // }
  1028. },
  1029. statusFormatter(status) {
  1030. const obj = this.statusOpt[this.activeName].find(
  1031. (i) => i.value == status
  1032. );
  1033. return obj && obj.label;
  1034. },
  1035. /* 表格数据源 */
  1036. datasource({ page, limit, where }) {
  1037. return getList({
  1038. pageNum: page,
  1039. timeDimensionPlanType: this.timeDimensionPlanType,
  1040. size: limit,
  1041. ...where,
  1042. ...this.sort
  1043. });
  1044. },
  1045. // 发布工单
  1046. handleOrderPublish(type, row) {
  1047. if (!row.produceRoutingName) {
  1048. return this.$message.error('请先选择工艺路线!');
  1049. }
  1050. const titleText = this.isReview
  1051. ? '是否发起流程'
  1052. : '发布工单后不可撤回,确定发布吗?';
  1053. const title = this.isReview ? '流程确认' : '发布确认';
  1054. const text = this.isReview ? '流程发布中...' : '工单发布中...';
  1055. this.$confirm(titleText, title)
  1056. .then(async () => {
  1057. const loading = this.$loading({
  1058. lock: true,
  1059. fullscreen: true,
  1060. text
  1061. });
  1062. try {
  1063. let code = row.workOrderCode;
  1064. if (!code) {
  1065. code = await getCode('product_order_code');
  1066. }
  1067. // 反显对象会报错 status
  1068. const URL = this.isReview ? releaseByApproval : release;
  1069. const data = await URL([row.id]);
  1070. if (data || data === 0) {
  1071. this.$message.success('发布成功!');
  1072. } else {
  1073. this.$message.error('发布失败,请重新发布!');
  1074. }
  1075. this.reload();
  1076. } catch (error) {
  1077. console.error(error);
  1078. }
  1079. loading.close();
  1080. })
  1081. .catch((err) => {
  1082. console.error(err);
  1083. });
  1084. // this.$router.push({
  1085. // path: '/productionPlan/workOrderPublish',
  1086. // query: {
  1087. // type,
  1088. // id: row.id
  1089. // }
  1090. // });
  1091. },
  1092. // 修改计划
  1093. async planEdit(row) {
  1094. console.log(row, 'row 11');
  1095. if (row.timeDimensionPlanType == 3) {
  1096. this.factoryObj = row;
  1097. // this.factoryType = ;
  1098. // this.factoryShow = true;
  1099. this.$refs.factoryAddRef.open(row);
  1100. } else {
  1101. let categoryId = row.categoryId;
  1102. let produceType = '';
  1103. let params = { categoryId: categoryId };
  1104. const res = await listBomType(params);
  1105. console.log(res, 'res 000');
  1106. let bomMap = {
  1107. 1: { code: 1, name: 'PBOM' },
  1108. 2: { code: 2, name: 'MBOM' },
  1109. 3: { code: 3, name: 'ABOM' }
  1110. };
  1111. let arr = [];
  1112. res.map((item) => {
  1113. if (bomMap[item.bomType]) {
  1114. arr.push(bomMap[item.bomType]);
  1115. delete bomMap[item.bomType];
  1116. }
  1117. });
  1118. // const res = await findBomCategoryByCategoryId(categoryId);
  1119. // let arr = [];
  1120. // if (res.length > 0) {
  1121. // let obj = res.find((item) => item.id === row.bomCategoryId);
  1122. // produceType = obj ? obj.bomType : produceType;
  1123. // let listMap = {
  1124. // 1: { code: 1, name: 'PBOM' },
  1125. // 2: { code: 2, name: 'MBOM' },
  1126. // 3: { code: 3, name: 'ABOM' }
  1127. // };
  1128. // res.forEach((el) => {
  1129. // if (listMap[el.bomType]) {
  1130. // arr.push(listMap[el.bomType]);
  1131. // delete listMap[el.bomType];
  1132. // }
  1133. // });
  1134. // }
  1135. console.log(arr, 'arr 222');
  1136. this.$router
  1137. .push({
  1138. path: '/saleOrder/salesToProduction',
  1139. query: {
  1140. type: 'edit',
  1141. id: row.id,
  1142. produceType,
  1143. categoryId,
  1144. producedList: JSON.stringify(arr)
  1145. }
  1146. })
  1147. .catch((error) => {
  1148. // 忽略重复导航错误
  1149. if (error.name !== 'NavigationDuplicated') {
  1150. console.error('路由跳转失败:', error);
  1151. }
  1152. });
  1153. }
  1154. },
  1155. getFieldModel() {
  1156. fieldModel({ fieldModel: 't_main_category' }).then((res) => {
  1157. const privateColumn = [];
  1158. if (this.activeName == 'first') {
  1159. privateColumn.push({
  1160. columnKey: 'action',
  1161. label: '操作',
  1162. width: 240,
  1163. align: 'center',
  1164. resizable: false,
  1165. fixed: 'right',
  1166. slot: 'action'
  1167. });
  1168. } else {
  1169. privateColumn = [];
  1170. }
  1171. let newRes = res.map((m) => {
  1172. return {
  1173. prop: 'extField.' + m.prop,
  1174. label: m.label,
  1175. align: 'center',
  1176. showOverflowTooltip: true
  1177. };
  1178. });
  1179. // this.newColumns = [...this.columns, ...newRes, ...privateColumn];
  1180. this.columns = [...this.columns, ...newRes, ...privateColumn];
  1181. this.getTabColumns();
  1182. });
  1183. },
  1184. handleTabChange() {
  1185. this.$refs.searchRef.reset();
  1186. },
  1187. /* 刷新表格 */
  1188. reload(where) {
  1189. this.$nextTick(() => {
  1190. this.$refs.table.reload({ page: 1, where });
  1191. });
  1192. },
  1193. newReload() {
  1194. this.$nextTick(() => {
  1195. this.$refs.table.reload({ page: 1 });
  1196. });
  1197. },
  1198. /* 数据转为树形结构 */
  1199. parseData(data) {
  1200. return {
  1201. ...data,
  1202. list: this.$util.toTreeData({
  1203. data: data.list,
  1204. count: data.total,
  1205. idField: 'code',
  1206. parentIdField: 'joinPlanCode'
  1207. })
  1208. };
  1209. },
  1210. handleDel(row) {
  1211. this.$confirm('确定删除当前数据?', '提示')
  1212. .then(() => {
  1213. if (this.isLineNumbre) {
  1214. factoryDelete(row.id).then((res) => {
  1215. this.reload();
  1216. this.$message.success('删除成功');
  1217. });
  1218. } else {
  1219. del(row.id).then((res) => {
  1220. this.reload();
  1221. this.$message.success('删除成功');
  1222. });
  1223. }
  1224. })
  1225. .catch(() => {});
  1226. },
  1227. handleSelectionChange(list) {
  1228. console.log(list, 'list ___');
  1229. if (list.length > 0) {
  1230. let _list = [];
  1231. list.forEach((e) => {
  1232. if (e.childList.length > 0 && e.splitBatch != 2) {
  1233. _list.push(...e.childList);
  1234. } else {
  1235. _list.push(e);
  1236. }
  1237. });
  1238. this.selection = _list;
  1239. } else {
  1240. this.selection = [];
  1241. }
  1242. },
  1243. process(row) {
  1244. if (row.approvalStatus == 0) {
  1245. this.$message.info('未提交没有审核流程');
  1246. } else {
  1247. this.$refs.processDetailRef.open(row.processInstanceId);
  1248. }
  1249. },
  1250. handOneSelection(row) {
  1251. const index = this.selection.findIndex((item) => item.id == row.id);
  1252. if (index >= 0) {
  1253. this.selection.splice(index, 1);
  1254. } else {
  1255. this.selection.push(row);
  1256. }
  1257. },
  1258. planDotLine(row) {
  1259. if (!row.bomCategoryId) {
  1260. return this.$message.warning('该计划没有定义BOM,请先添加BOM!');
  1261. }
  1262. this.$refs.planDotLineRef.open(row);
  1263. },
  1264. selectionFilter(row) {
  1265. return this.selection.findIndex((item) => item.id == row.id) >= 0;
  1266. },
  1267. //生产前准备
  1268. productionPreparations(item) {
  1269. this.$refs.checkProductionPreparationsRef.open(item);
  1270. },
  1271. goDetail({ id, processInstanceId }) {
  1272. console.log(id, processInstanceId, 'id, processInstanceId');
  1273. this.$router.push({
  1274. path: '/productionPlan/detail',
  1275. query: { id, processInstanceId }
  1276. });
  1277. },
  1278. // 计划分解
  1279. disassemblePlan() {
  1280. console.log(this.selection, 'this.selection');
  1281. if (this.selection.length != 1) {
  1282. return this.$message.warning('计划分解只能选择一个计划!');
  1283. }
  1284. if (this.selection[0].approvalStatus == 1) {
  1285. return this.$message.warning('该计划正在审核中!');
  1286. }
  1287. this.$refs.disassemblePlanRef.open(this.selection[0]);
  1288. },
  1289. // 拆批
  1290. toUnpack(row) {
  1291. console.log(1111111111111);
  1292. if (!row.batchNo) {
  1293. return this.$message.error('请先填写批次号!');
  1294. }
  1295. this.$refs.unpackRef.open(row);
  1296. },
  1297. // 合并
  1298. handleMerge() {
  1299. if (this.selection.length <= 1) {
  1300. return this.$message.warning('请先勾选二个或多个计划!');
  1301. }
  1302. const productCode = this.selection[0].productCode;
  1303. const produceRoutingId = this.selection[0].produceRoutingId;
  1304. for (var i = 0; i < this.selection.length; i++) {
  1305. if (productCode != this.selection[i].productCode) {
  1306. return this.$message.warning('产品编码不一致!');
  1307. }
  1308. if (produceRoutingId != this.selection[i].produceRoutingId) {
  1309. return this.$message.warning('工艺路线不一致!');
  1310. }
  1311. if (this.selection[i].approvalStatus == 1) {
  1312. return this.$message.warning('该计划正在审核中!');
  1313. }
  1314. }
  1315. this.$refs.mergeRef.open(this.selection);
  1316. console.log(this.selection);
  1317. },
  1318. splitDetails(type, row) {
  1319. this.$refs.DetailsRef.open(type, row);
  1320. },
  1321. factAdd(type) {
  1322. this.factoryType = type;
  1323. this.$refs.factoryAddRef.open();
  1324. // this.factoryShow = true;
  1325. },
  1326. factoryClose(val) {
  1327. // this.factoryShow = false;
  1328. this.factoryType = 3;
  1329. this.factoryObj = {};
  1330. if (val) {
  1331. this.reload();
  1332. }
  1333. },
  1334. onSortChange(e) {
  1335. let sort = {
  1336. orderBy: e.order,
  1337. sortName: e.prop
  1338. };
  1339. this.sort = sort;
  1340. this.reload();
  1341. },
  1342. sortTop(row) {
  1343. row.priority = Number(row.priority) + 1;
  1344. this.priorityChange(row);
  1345. },
  1346. sortBottom(row) {
  1347. if (row.priority <= 1) {
  1348. return;
  1349. }
  1350. row.priority = Number(row.priority) - 1;
  1351. this.priorityChange(row);
  1352. },
  1353. priorityChange(row) {
  1354. if (row.priority > 10) {
  1355. row.priority = 10; // 如果大于 10,则设置为 10
  1356. } else if (row.priority < 0) {
  1357. row.priority = 0; // 如果小于 0,则设置为 0
  1358. }
  1359. this.priorityFn(row);
  1360. },
  1361. priorityFn: debounce(function (row) {
  1362. let params = {
  1363. id: row.id,
  1364. priority: row.priority
  1365. };
  1366. updatePriority(params).then((res) => {});
  1367. }, 800)
  1368. }
  1369. };
  1370. </script>
  1371. <style lang="scss" scoped>
  1372. .btn_box {
  1373. margin-bottom: 6px;
  1374. }
  1375. .my-btn {
  1376. background-color: #d8701b !important;
  1377. border-color: #d8701b !important;
  1378. color: #fff !important;
  1379. }
  1380. .my-btn:hover,
  1381. .my-btn:focus {
  1382. background-color: #d8701b !important;
  1383. border-color: #d8701b !important;
  1384. color: #fff !important;
  1385. }
  1386. .my-btn:active {
  1387. background-color: #d8701b !important;
  1388. border-color: #d8701b !important;
  1389. color: #fff !important;
  1390. }
  1391. .check_box {
  1392. width: 100%;
  1393. display: flex;
  1394. align-items: center;
  1395. justify-content: center;
  1396. cursor: pointer;
  1397. }
  1398. .check {
  1399. width: 14px;
  1400. height: 14px;
  1401. border: 1px solid #dddddd;
  1402. display: flex;
  1403. align-items: center;
  1404. justify-content: center;
  1405. }
  1406. .act_check {
  1407. border: 1px solid #409eff;
  1408. background: #409eff;
  1409. .el-icon-check {
  1410. color: #fff;
  1411. font-size: 10px;
  1412. }
  1413. }
  1414. .statistics {
  1415. padding: 10px 10px 20px;
  1416. }
  1417. .cardItem {
  1418. border: 1px solid rgb(225, 225, 225);
  1419. text-align: center;
  1420. color: white;
  1421. background-color: rgba(24, 144, 255, 0.8);
  1422. overflow: hidden;
  1423. padding: 10px;
  1424. }
  1425. .cardText {
  1426. font-size: 16px;
  1427. white-space: nowrap;
  1428. text-overflow: ellipsis;
  1429. overflow: hidden;
  1430. }
  1431. .cardNum {
  1432. font-size: 32px;
  1433. font-style: italic;
  1434. white-space: nowrap;
  1435. text-overflow: ellipsis;
  1436. overflow: hidden;
  1437. }
  1438. @media (max-width: 768px) {
  1439. .cardText {
  1440. font-size: 14px;
  1441. }
  1442. .cardNum {
  1443. font-size: 24px;
  1444. }
  1445. }
  1446. ::v-deep .el-card__body {
  1447. padding: 17px 12px !important;
  1448. }
  1449. </style>