You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1096 lines
37 KiB

4 months ago
4 months ago
2 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
3 weeks ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
2 months ago
4 months ago
2 months ago
2 months ago
2 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
2 months ago
2 months ago
2 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
3 months ago
4 months ago
  1. <template>
  2. <div class="mod-config">
  3. <div>
  4. <span @click="favoriteFunction()">
  5. <icon-svg :name="favorite?'xiangqufill':'xiangqu'" class="sl-svg"></icon-svg>
  6. </span>
  7. </div>
  8. <el-form :inline="true" label-position="top">
  9. <el-form-item :label="inputLabel.headerInput.label0">
  10. <el-select v-model="queryHeaderData.site" placeholder="请选择工厂" style="width: 120px;" clearable>
  11. <el-option
  12. v-for="item in siteOptions"
  13. :key="item.site"
  14. :label="item.siteName || item.site"
  15. :value="item.site">
  16. </el-option>
  17. </el-select>
  18. </el-form-item>
  19. <el-form-item :label="inputLabel.headerInput.label1">
  20. <el-input style="width: 150px;" v-model="queryHeaderData.palletId" placeholder="托盘ID" clearable @keyup.enter.native="getDataList()"></el-input>
  21. </el-form-item>
  22. <el-form-item :label="inputLabel.headerInput.label2">
  23. <el-select v-model="queryHeaderData.palletFamily" placeholder="请选择" style="width: 120px;" clearable>
  24. <el-option label="全部" value=""></el-option>
  25. <el-option label="钢托盘" value="A01"></el-option>
  26. <el-option label="围挡托盘" value="A02"></el-option>
  27. <el-option label="平托盘+周转箱" value="A03"></el-option>
  28. </el-select>
  29. </el-form-item>
  30. <el-form-item :label="inputLabel.headerInput.label3">
  31. <el-select v-model="queryHeaderData.status" placeholder="请选择" style="width: 120px;" clearable>
  32. <el-option label="全部" value=""></el-option>
  33. <el-option
  34. v-for="item in statusOptions"
  35. :key="item.value"
  36. :label="item.label"
  37. :value="item.value">
  38. </el-option>
  39. </el-select>
  40. </el-form-item>
  41. <el-form-item :label="inputLabel.headerInput.label4">
  42. <el-input style="width: 150px;" v-model="queryHeaderData.locationCode" placeholder="所在站点" clearable @keyup.enter.native="getDataList()"></el-input>
  43. </el-form-item>
  44. <el-form-item style="margin-top: 20px;">
  45. <el-button @click="getDataList()" type="primary">查询</el-button>
  46. <!-- 导出按钮 - rqrq -->
  47. <download-excel
  48. :fields="fields()"
  49. :data="exportData"
  50. type="xls"
  51. :name="exportName"
  52. :header="exportHeader"
  53. :footer="exportFooter"
  54. :fetch="createExportData"
  55. :before-generate="startDownload"
  56. :before-finish="finishDownload"
  57. worksheet="导出信息"
  58. class="el-button el-button--primary el-button--medium">
  59. {{ '导出' }}
  60. </download-excel>
  61. </el-form-item>
  62. <el-form-item style="margin-top: 20px;">
  63. <!-- <el-button @click="initModel()" type="primary">新增</el-button>-->
  64. <!-- <el-button v-if="isAuth(':pallet:delete')" type="danger" @click="deleteHandle()"-->
  65. <!-- :disabled="dataListSelections.length <= 0">{{ buttons.deleteList}}-->
  66. <!-- </el-button>-->
  67. <!-- 批量新增按钮 - rqrq -->
  68. <el-button @click="openBatchGenerateDialog()" type="success">批量新增托盘</el-button>
  69. </el-form-item>
  70. </el-form>
  71. <el-table
  72. id="palletTable"
  73. :height="height"
  74. :data="dataList"
  75. border
  76. v-loading="dataListLoading"
  77. @selection-change="selectionChangeHandle"
  78. style="width: 100%;">
  79. <el-table-column
  80. v-for="(item,index) in columnList" :key="index"
  81. :sortable="item.columnSortable"
  82. :prop="item.columnProp"
  83. :header-align="item.headerAlign"
  84. :show-overflow-tooltip="item.showOverflowTooltip"
  85. :align="item.align"
  86. :fixed="item.fixed==''?false:item.fixed"
  87. :min-width="item.columnWidth"
  88. :label="item.columnLabel">
  89. <template slot-scope="scope">
  90. <span v-if="!item.columnHidden"> {{scope.row[item.columnProp]}}</span>
  91. <span v-if="item.columnImage"><img :src="scope.row[item.columnProp]"
  92. style="width: 100px; height: 80px"/></span>
  93. </template>
  94. </el-table-column>
  95. <!-- <el-table-column-->
  96. <!-- fixed="right"-->
  97. <!-- header-align="center"-->
  98. <!-- align="center"-->
  99. <!-- width="100"-->
  100. <!-- label="操作">-->
  101. <!-- <template slot-scope="scope">-->
  102. <!-- <a @click="initModel(scope.row)" type="text" >编辑</a>-->
  103. <!--&lt;!&ndash; <a @click="delHeaderData(scope.row)" type="text" >删除</a>&ndash;&gt;-->
  104. <!-- </template>-->
  105. <!-- </el-table-column>-->
  106. </el-table>
  107. <el-pagination
  108. @size-change="sizeChangeHandle"
  109. @current-change="currentChangeHandle"
  110. :current-page="pageIndex"
  111. :page-sizes="[10, 20, 50, 100]"
  112. :page-size="pageSize"
  113. :total="totalPage"
  114. layout="total, sizes, prev, pager, next, jumper">
  115. </el-pagination>
  116. <!-- 新增/编辑dialog - rqrq -->
  117. <el-dialog :close-on-click-modal="false" :close-on-press-escape="false"
  118. v-drag :title="inputLabel.headerInput.label5"
  119. :visible.sync="setUp.reviewFlag" width="900px">
  120. <el-form :model="saveHeaderData" ref="dataForm"
  121. label-position="top" style="margin-top: 1px; margin-left: 0px;">
  122. <!-- 第一行工厂+托盘ID+托盘尺寸+最大承重 - rqrq -->
  123. <el-row :gutter="20">
  124. <el-col :span="6">
  125. <el-form-item :label="inputLabel.headerInput.label0" prop="site">
  126. <el-select v-model="saveHeaderData.site" placeholder="请选择工厂" style="width: 100%;" :disabled="setUp.readonlyFlag" @change="onSiteChange">
  127. <el-option
  128. v-for="item in siteOptions"
  129. :key="item.site"
  130. :label="item.siteName || item.site"
  131. :value="item.site">
  132. </el-option>
  133. </el-select>
  134. </el-form-item>
  135. </el-col>
  136. <el-col :span="6">
  137. <el-form-item :label="inputLabel.headerInput.label1" prop="palletId">
  138. <el-input v-model="saveHeaderData.palletId" readonly placeholder="系统自动生成"></el-input>
  139. </el-form-item>
  140. </el-col>
  141. <el-col :span="6">
  142. <el-form-item label="托盘尺寸">
  143. <el-input v-model="saveHeaderData.palletSize" placeholder="如: 1200x1000"></el-input>
  144. </el-form-item>
  145. </el-col>
  146. <el-col :span="6">
  147. <el-form-item label="最大承重(kg)">
  148. <el-input v-model="saveHeaderData.maxLoad" placeholder="请输入最大承重"></el-input>
  149. </el-form-item>
  150. </el-col>
  151. </el-row>
  152. <!-- 第二行托盘大分类+托盘类型+分拣方式+自动分拣 - rqrq -->
  153. <el-row :gutter="20">
  154. <el-col :span="6">
  155. <el-form-item label="托盘大分类" prop="palletFamily">
  156. <el-select v-model="saveHeaderData.palletFamily" placeholder="请选择" style="width: 100%;" @change="onPalletFamilyChange">
  157. <el-option
  158. v-for="item in palletFamilyOptions"
  159. :key="item.palletFamily"
  160. :label="item.palletFamilyDesc || item.palletFamily"
  161. :value="item.palletFamily">
  162. </el-option>
  163. </el-select>
  164. </el-form-item>
  165. </el-col>
  166. <el-col :span="6">
  167. <el-form-item label="托盘类型" prop="palletType">
  168. <el-select v-model="saveHeaderData.palletType" placeholder="请先选择托盘大分类" style="width: 100%;" @change="onPalletTypeChange">
  169. <el-option
  170. v-for="item in palletTypeOptions"
  171. :key="item.palletType"
  172. :label="item.typeDesc || item.palletType"
  173. :value="item.palletType">
  174. </el-option>
  175. </el-select>
  176. </el-form-item>
  177. </el-col>
  178. <el-col :span="6">
  179. <el-form-item label="分拣方式">
  180. <el-select v-model="saveHeaderData.soreType" placeholder="自动带出" style="width: 100%;">
  181. <el-option label="人工/混装" :value="0"></el-option>
  182. <el-option label="气胀轴自动分拣" :value="1"></el-option>
  183. <el-option label="抱箱自动分拣" :value="2"></el-option>
  184. <el-option label="直接出库" :value="3"></el-option>
  185. </el-select>
  186. </el-form-item>
  187. </el-col>
  188. <el-col :span="6">
  189. <el-form-item label="自动分拣">
  190. <el-select v-model="saveHeaderData.autoSort" placeholder="自动带出" style="width: 100%;">
  191. <el-option label="是" value="Y"></el-option>
  192. <el-option label="否" value="N"></el-option>
  193. </el-select>
  194. </el-form-item>
  195. </el-col>
  196. </el-row>
  197. <!-- 第三行状态+库位编码+WCS库位+空栈板标记 - rqrq -->
  198. <el-row :gutter="20">
  199. <el-col :span="6">
  200. <el-form-item :label="inputLabel.headerInput.label3" prop="status">
  201. <el-select v-model="saveHeaderData.status" placeholder="请选择" style="width: 100%;">
  202. <el-option
  203. v-for="item in statusOptions"
  204. :key="item.value"
  205. :label="item.label"
  206. :value="item.value">
  207. </el-option>
  208. </el-select>
  209. </el-form-item>
  210. </el-col>
  211. <el-col :span="6">
  212. <el-form-item label="站点">
  213. <el-input v-model="saveHeaderData.locationCode" disabled placeholder="请输入站点编码"></el-input>
  214. </el-form-item>
  215. </el-col>
  216. <el-col :span="6">
  217. <el-form-item label="WCS站点">
  218. <el-input v-model="saveHeaderData.wcsLocation" disabled placeholder="请输入WCS站点"></el-input>
  219. </el-form-item>
  220. </el-col>
  221. <el-col :span="6">
  222. <el-form-item label="空栈板标记">
  223. <el-input v-model="saveHeaderData.emptyFlag" readonly placeholder="默认为N" style="background-color: #f5f7fa;"></el-input>
  224. </el-form-item>
  225. </el-col>
  226. </el-row>
  227. <!-- 第四行调用标志 - rqrq -->
  228. <el-row :gutter="20">
  229. <el-col :span="6">
  230. <el-form-item label="调用标志">
  231. <el-select v-model="saveHeaderData.callingFlag" placeholder="请选择" disabled style="width: 100%;">
  232. <el-option label="是" value="Y"></el-option>
  233. <el-option label="否" value="N"></el-option>
  234. </el-select>
  235. </el-form-item>
  236. </el-col>
  237. </el-row>
  238. <!-- 备注占全行 - rqrq -->
  239. <el-row>
  240. <el-col :span="24">
  241. <el-form-item label="最近一次调用备注">
  242. <el-input v-model="saveHeaderData.remark" readonly ></el-input>
  243. </el-form-item>
  244. </el-col>
  245. </el-row>
  246. </el-form>
  247. <div slot="footer" class="dialog-footer" style="margin-top: 52px">
  248. <el-button type="primary" :disabled="setUp.saveButton" @click="saveHeaderFunction()">
  249. {{ setUp.saveButton ? '保存中...' : '确定' }}
  250. </el-button>
  251. <el-button @click="setUp.reviewFlag = false" :disabled="setUp.saveButton">取消</el-button>
  252. </div>
  253. </el-dialog>
  254. <!-- 批量新增托盘弹窗 - rqrq -->
  255. <el-dialog :close-on-click-modal="false" :close-on-press-escape="false"
  256. v-drag :title="'批量新增托盘 - 工厂: ' + batchGenerateDialog.site"
  257. :visible.sync="batchGenerateDialog.visible" width="480px">
  258. <div v-loading="batchGenerateDialog.loading">
  259. <!-- 表头行 - rqrq -->
  260. <div style="display: flex; align-items: center; padding: 10px 0; margin-bottom: 5px; border-bottom: 1px solid #ebeef5; color: #606266; font-weight: bold;">
  261. <span style="flex: 1;">托盘类型</span>
  262. <span style="width: 100px; text-align: center;">当前数量</span>
  263. <span style="width: 140px; text-align: center;">需要新增</span>
  264. </div>
  265. <!-- 托盘列表 - rqrq -->
  266. <div v-for="(item, index) in batchGenerateDialog.palletNoList" :key="index"
  267. style="display: flex; align-items: center; padding: 12px 0; border-bottom: 1px dashed #ebeef5;">
  268. <span style="flex: 1; font-size: 14px; color: #303133;">
  269. {{ item.palletFamilyDesc }}
  270. <span style="color: #909399;">({{ item.prefix }})</span>
  271. </span>
  272. <span style="width: 100px; text-align: center; font-size: 15px; color: #409EFF; font-weight: bold;">
  273. {{ item.totalCount || 0 }}
  274. </span>
  275. <div style="width: 140px; text-align: center;">
  276. <el-input
  277. v-model.number="item.generateCount"
  278. placeholder="0"
  279. size="small"
  280. style="width: 100px;"
  281. @input="validateCount(item)">
  282. </el-input>
  283. </div>
  284. </div>
  285. <!-- 提示信息 - rqrq -->
  286. <div style="margin-top: 15px; color: #909399; font-size: 12px;">
  287. <i class="el-icon-info"></i> 单次每种类型最多新增1000个
  288. </div>
  289. </div>
  290. <div slot="footer" class="dialog-footer">
  291. <el-button type="primary" :disabled="batchGenerateDialog.saving" @click="doBatchGenerate()">
  292. {{ batchGenerateDialog.saving ? '生成中...' : '确定' }}
  293. </el-button>
  294. <el-button @click="batchGenerateDialog.visible = false" :disabled="batchGenerateDialog.saving">取消</el-button>
  295. </div>
  296. </el-dialog>
  297. </div>
  298. </template>
  299. <script>
  300. import {
  301. userFavoriteList,
  302. saveUserFavorite,
  303. removeUserFavorite,
  304. } from '@/api/userFavorite.js'
  305. import {
  306. getPalletList,
  307. savePallet,
  308. updatePallet,
  309. deletePallet,
  310. checkPalletId,
  311. getPalletStatusOptions,
  312. getUserAuthorizedSites,
  313. getPalletFamilyList,
  314. getPalletTypeList,
  315. getMaxPalletNoByFamily,
  316. batchGeneratePallet
  317. } from '@/api/warehouse/pallet.js'
  318. export default {
  319. data() {
  320. return {
  321. saveHeaderData: {
  322. id: null,
  323. site: '',
  324. palletId: '',
  325. palletType: '',
  326. palletSize: '',
  327. maxLoad: null,
  328. status: 'AVAILABLE',
  329. locationCode: '',
  330. wcsLocation: '', // WCS库位 - rqrq
  331. palletFamily: '', // 托盘大分类 - rqrq
  332. soreType: 0, // 分拣方式 - rqrq
  333. autoSort: 'N', // 自动分拣,默认N - rqrq
  334. emptyFlag: 'N', // 空栈板标记,默认N且不可修改 - rqrq
  335. callingFlag: 'N', // 调用标志,默认N - rqrq
  336. remark: '',
  337. createdBy: this.$store.state.user.name,
  338. updatedBy: this.$store.state.user.name
  339. },
  340. queryHeaderData: {
  341. site: '',
  342. palletId: '',
  343. palletType: '',
  344. palletFamily: '',
  345. status: '',
  346. locationCode: '',
  347. page: 1,
  348. limit: 20
  349. },
  350. setUp: {
  351. reviewFlag: false,
  352. saveButton: false,
  353. readonlyFlag: false,
  354. },
  355. inputLabel: {
  356. headerInput: {
  357. label0: '工厂',
  358. label1: '托盘ID',
  359. label2: '托盘大分类',
  360. label3: '托盘状态',
  361. label4: '所在站点',
  362. label5: '托盘信息',
  363. },
  364. },
  365. statusOptions: [],
  366. siteOptions: [],
  367. palletFamilyOptions: [], // 托盘大分类选项 - rqrq
  368. palletTypeOptions: [], // 托盘类型选项 - rqrq
  369. selectedPalletTypeData: null, // 选中的托盘类型完整数据 - rqrq
  370. // table高度
  371. height: 450,
  372. // 是否收藏
  373. favorite: false,
  374. functionId: this.$route.meta.menuId,
  375. // 展示列集 - rqrq
  376. columnList: [
  377. {
  378. columnProp: "site",
  379. headerAlign: "center",
  380. align: "center",
  381. columnLabel: "工厂",
  382. columnWidth: 50,
  383. },
  384. {
  385. columnProp: "palletId",
  386. headerAlign: "center",
  387. align: "center",
  388. columnLabel: "托盘ID",
  389. columnWidth: 100,
  390. },
  391. {
  392. columnProp: "palletFamilyDesc",
  393. headerAlign: "center",
  394. align: "center",
  395. columnLabel: "托盘大分类",
  396. columnWidth: 150,
  397. },
  398. {
  399. columnProp: "typeDesc",
  400. headerAlign: "center",
  401. align: "center",
  402. columnLabel: "托盘类型",
  403. columnWidth: 180,
  404. },
  405. {
  406. columnProp: "soreTypeText",
  407. headerAlign: "center",
  408. align: "center",
  409. columnLabel: "分拣方式",
  410. columnWidth: 120,
  411. },
  412. {
  413. columnProp: "autoSortText",
  414. headerAlign: "center",
  415. align: "center",
  416. columnLabel: "自动分拣",
  417. columnWidth: 80,
  418. },
  419. {
  420. columnProp: "callingFlagText",
  421. headerAlign: "center",
  422. align: "center",
  423. columnLabel: "调用标志",
  424. columnWidth: 80,
  425. },
  426. {
  427. columnProp: "remark",
  428. headerAlign: "center",
  429. align: "left",
  430. columnLabel: "最近一次调用备注",
  431. columnWidth: 150,
  432. },
  433. {
  434. columnProp: "locationCode",
  435. headerAlign: "center",
  436. align: "center",
  437. columnLabel: "所在站点",
  438. columnWidth: 80,
  439. },
  440. {
  441. columnProp: "wcsLocation",
  442. headerAlign: "center",
  443. align: "center",
  444. columnLabel: "WCS库位",
  445. columnWidth: 80,
  446. },
  447. {
  448. columnProp: "emptyFlagText",
  449. headerAlign: "center",
  450. align: "center",
  451. columnLabel: "空栈板标记",
  452. columnWidth: 80,
  453. },
  454. {
  455. columnProp: "statusText",
  456. headerAlign: "center",
  457. align: "center",
  458. columnLabel: "托盘状态",
  459. columnWidth: 80,
  460. },
  461. {
  462. columnProp: "createdBy",
  463. headerAlign: "center",
  464. align: "center",
  465. columnLabel: "创建人",
  466. columnWidth: 100,
  467. },
  468. {
  469. columnProp: "createdTime",
  470. headerAlign: "center",
  471. align: "center",
  472. columnLabel: "创建时间",
  473. columnWidth: 150,
  474. },
  475. {
  476. columnProp: "updatedBy",
  477. headerAlign: "center",
  478. align: "center",
  479. columnLabel: "修改人",
  480. columnWidth: 100,
  481. },
  482. {
  483. columnProp: "updatedTime",
  484. headerAlign: "center",
  485. align: "center",
  486. columnLabel: "修改时间",
  487. columnWidth: 150,
  488. },
  489. {
  490. columnProp: "palletSize",
  491. headerAlign: "center",
  492. align: "center",
  493. columnLabel: "托盘尺寸",
  494. columnWidth: 120,
  495. },
  496. {
  497. columnProp: "maxLoad",
  498. headerAlign: "center",
  499. align: "center",
  500. columnLabel: "最大承重(kg)",
  501. columnWidth: 120,
  502. },
  503. ],
  504. // 数据集
  505. dataList: [],
  506. buttons: {
  507. deleteList: '批量删除',
  508. },
  509. // 分页
  510. pageIndex: 1,
  511. pageSize: 20,
  512. totalPage: 0,
  513. dataListLoading: false,
  514. dataListSelections: [],
  515. // 导出相关 - rqrq
  516. exportData: [],
  517. exportName: '托盘信息' + this.dayjs().format('YYYYMMDDHHmmss'),
  518. exportHeader: ["托盘信息"],
  519. exportFooter: [],
  520. // 验证规则
  521. dataRule: {
  522. site: [
  523. { required: true, message: '工厂不能为空', trigger: 'change' }
  524. ],
  525. palletType: [
  526. { required: true, message: '托盘类型不能为空', trigger: 'change' }
  527. ],
  528. status: [
  529. { required: true, message: '托盘状态不能为空', trigger: 'change' }
  530. ]
  531. },
  532. // 批量新增弹窗状态 - rqrq
  533. batchGenerateDialog: {
  534. visible: false,
  535. loading: false,
  536. saving: false,
  537. site: '',
  538. palletNoList: [] // 各类托盘编号信息列表
  539. }
  540. }
  541. },
  542. mounted() {
  543. this.$nextTick(() => {
  544. this.height = window.innerHeight - 220;
  545. })
  546. },
  547. activated() {
  548. this.getDataList()
  549. this.getStatusOptions()
  550. this.getSiteOptions()
  551. },
  552. methods: {
  553. // 获取状态选项
  554. getStatusOptions() {
  555. getPalletStatusOptions().then(({data}) => {
  556. if (data && data.code === 0) {
  557. this.statusOptions = data.options
  558. }
  559. })
  560. },
  561. // 获取工厂选项
  562. getSiteOptions() {
  563. const params = {
  564. userName: this.$store.state.user.name
  565. }
  566. getUserAuthorizedSites(params).then(({data}) => {
  567. if (data && data.code === 0) {
  568. this.siteOptions = data.data
  569. }
  570. }).catch(error => {
  571. console.error('获取工厂列表失败:', error)
  572. })
  573. },
  574. // 删除托盘
  575. delHeaderData(row) {
  576. this.$confirm(`确定删除托盘 [${row.palletId}]?`, '操作提示', {
  577. confirmButtonText: '确定',
  578. cancelButtonText: '取消',
  579. type: 'warning'
  580. }).then(() => {
  581. deletePallet([row.id]).then(({data}) => {
  582. if (data.code == 0) {
  583. this.$message.success(data.msg)
  584. this.getDataList()
  585. } else {
  586. this.$alert(data.msg, '操作提示', {
  587. confirmButtonText: '确定'
  588. });
  589. }
  590. })
  591. })
  592. },
  593. // 保存托盘
  594. saveHeaderFunction() {
  595. this.$refs.dataForm.validate((valid) => {
  596. if (valid) {
  597. this.setUp.saveButton = true
  598. // 准备提交数据
  599. let submitData = { ...this.saveHeaderData }
  600. // 如果是新增,清空托盘ID让后端自动生成
  601. if (!submitData.id) {
  602. submitData.palletId = ''
  603. }
  604. const apiMethod = submitData.id ? updatePallet : savePallet
  605. apiMethod(submitData).then(({data}) => {
  606. this.setUp.saveButton = false
  607. if (data.code == 0) {
  608. this.$message.success(data.msg)
  609. this.getDataList()
  610. this.setUp.reviewFlag = false
  611. } else {
  612. this.$alert(data.msg, '操作提示', {
  613. confirmButtonText: '确定'
  614. });
  615. }
  616. }).catch(() => {
  617. this.setUp.saveButton = false
  618. })
  619. }
  620. })
  621. },
  622. // 初始化表单 - rqrq
  623. initModel(row) {
  624. this.setUp.reviewFlag = true
  625. this.setUp.saveButton = false
  626. this.setUp.readonlyFlag = false
  627. if (row) {
  628. // 编辑模式 - rqrq
  629. this.setUp.readonlyFlag = true
  630. this.saveHeaderData = {
  631. id: row.id,
  632. site: row.site,
  633. palletId: row.palletId,
  634. palletType: row.palletType,
  635. palletSize: row.palletSize,
  636. maxLoad: row.maxLoad,
  637. status: row.status,
  638. locationCode: row.locationCode,
  639. wcsLocation: row.wcsLocation || '', // WCS库位 - rqrq
  640. palletFamily: row.palletFamily || '', // 托盘大分类 - rqrq
  641. soreType: row.soreType != null ? row.soreType : 0, // 分拣方式 - rqrq
  642. autoSort: row.autoSort || 'N', // 自动分拣 - rqrq
  643. emptyFlag: row.emptyFlag || 'N', // 空栈板标记(只读) - rqrq
  644. callingFlag: row.callingFlag || 'N', // 调用标志 - rqrq
  645. remark: row.remark || '',
  646. updatedBy: this.$store.state.user.name
  647. }
  648. // 编辑时加载托盘大分类和类型选项 - rqrq
  649. if (row.site) {
  650. this.getPalletFamilyOptions(row.site)
  651. if (row.palletFamily) {
  652. this.getPalletTypeOptions(row.site, row.palletFamily)
  653. }
  654. }
  655. } else {
  656. // 新增模式 - rqrq
  657. this.saveHeaderData = {
  658. id: null,
  659. site: '',
  660. palletId: '系统自动生成',
  661. palletType: '',
  662. palletSize: '',
  663. maxLoad: null,
  664. status: 'AVAILABLE',
  665. locationCode: '',
  666. wcsLocation: '', // WCS库位 - rqrq
  667. palletFamily: '', // 托盘大分类 - rqrq
  668. soreType: 0, // 分拣方式 - rqrq
  669. autoSort: 'N', // 自动分拣,默认N - rqrq
  670. emptyFlag: 'N', // 空栈板标记,默认N且不可修改 - rqrq
  671. callingFlag: 'N', // 调用标志,默认N - rqrq
  672. remark: '',
  673. createdBy: this.$store.state.user.name
  674. }
  675. }
  676. },
  677. // 工厂change事件 - rqrq
  678. onSiteChange(value) {
  679. console.log('工厂变更 - rqrq:', value)
  680. // 清空托盘相关字段 - rqrq
  681. this.saveHeaderData.palletFamily = ''
  682. this.saveHeaderData.palletType = ''
  683. this.saveHeaderData.soreType = 0
  684. this.saveHeaderData.autoSort = 'N'
  685. this.palletFamilyOptions = []
  686. this.palletTypeOptions = []
  687. this.selectedPalletTypeData = null
  688. // 加载新工厂的托盘大分类 - rqrq
  689. if (value) {
  690. this.getPalletFamilyOptions(value)
  691. }
  692. },
  693. // 获取托盘大分类选项 - rqrq
  694. getPalletFamilyOptions(site) {
  695. if (!site) {
  696. this.palletFamilyOptions = []
  697. return
  698. }
  699. getPalletFamilyList({ site }).then(({data}) => {
  700. if (data && data.code === 0) {
  701. this.palletFamilyOptions = data.rows || []
  702. }
  703. }).catch(() => {
  704. this.palletFamilyOptions = []
  705. })
  706. },
  707. // 获取托盘类型选项 - rqrq
  708. getPalletTypeOptions(site, palletFamily) {
  709. if (!site) {
  710. this.palletTypeOptions = []
  711. return
  712. }
  713. const params = { site }
  714. if (palletFamily) {
  715. params.palletFamily = palletFamily
  716. }
  717. getPalletTypeList(params).then(({data}) => {
  718. if (data && data.code === 0) {
  719. this.palletTypeOptions = data.rows || []
  720. }
  721. }).catch(() => {
  722. this.palletTypeOptions = []
  723. })
  724. },
  725. // 托盘大分类change事件 - rqrq
  726. onPalletFamilyChange(value) {
  727. console.log('托盘大分类变更 - rqrq:', value)
  728. // 清空托盘类型相关字段 - rqrq
  729. this.saveHeaderData.palletType = ''
  730. this.saveHeaderData.soreType = 0
  731. this.saveHeaderData.autoSort = 'N'
  732. this.selectedPalletTypeData = null
  733. // 重新加载托盘类型列表 - rqrq
  734. if (value && this.saveHeaderData.site) {
  735. this.getPalletTypeOptions(this.saveHeaderData.site, value)
  736. } else {
  737. this.palletTypeOptions = []
  738. }
  739. },
  740. // 托盘类型change事件 - 参考palletAssembly.vue逻辑 - rqrq
  741. onPalletTypeChange(value) {
  742. console.log('托盘类型变更 - rqrq:', value)
  743. // 查找选中的托盘类型完整数据 - rqrq
  744. const selectedType = this.palletTypeOptions.find(item => item.palletType === value)
  745. if (selectedType) {
  746. this.selectedPalletTypeData = selectedType
  747. // 根据托盘类型自动带出字段 - rqrq
  748. this.saveHeaderData.soreType = selectedType.wcsSoreType != null ? selectedType.wcsSoreType : 0
  749. this.saveHeaderData.autoSort = selectedType.wcsAutoSort || 'N'
  750. console.log('自动带出分拣方式 - rqrq:', this.saveHeaderData.soreType)
  751. console.log('自动带出自动分拣 - rqrq:', this.saveHeaderData.autoSort)
  752. } else {
  753. // 未找到数据,重置为默认值 - rqrq
  754. this.saveHeaderData.soreType = 0
  755. this.saveHeaderData.autoSort = 'N'
  756. this.selectedPalletTypeData = null
  757. }
  758. },
  759. // 收藏功能
  760. favoriteFunction() {
  761. let userFavorite = {
  762. userId: this.$store.state.user.id,
  763. functionId: this.$route.meta.menuId,
  764. }
  765. if (this.favorite) {
  766. this.$confirm(`确定取消收藏`, '提示', {
  767. confirmButtonText: '确定',
  768. cancelButtonText: '取消',
  769. type: 'warning'
  770. }).then(() => {
  771. removeUserFavorite(userFavorite).then(({data}) => {
  772. this.$message.success(data.msg)
  773. this.favorite = false
  774. })
  775. })
  776. } else {
  777. saveUserFavorite(userFavorite).then(({data}) => {
  778. this.$message.success(data.msg)
  779. this.favorite = true
  780. })
  781. }
  782. },
  783. // 获取数据列表 - rqrq
  784. getDataList() {
  785. this.dataListLoading = true
  786. this.queryHeaderData.page = this.pageIndex
  787. this.queryHeaderData.limit = this.pageSize
  788. getPalletList(this.queryHeaderData).then(({data}) => {
  789. if (data && data.code === 0) {
  790. // 处理数据,添加文本显示字段 - rqrq
  791. this.dataList = (data.page.list || []).map(item => {
  792. return {
  793. ...item,
  794. // 分拣方式文本显示 - rqrq
  795. soreTypeText: this.getSoreTypeText(item.soreType),
  796. // 自动分拣文本显示 - rqrq
  797. autoSortText: item.autoSort === 'Y' ? '是' : item.autoSort === 'N' ? '否' : '',
  798. // 空栈板标记文本显示 - rqrq
  799. emptyFlagText: item.emptyFlag === 'Y' ? '是' : item.emptyFlag === 'N' ? '否' : '',
  800. // 调用标志文本显示 - rqrq
  801. callingFlagText: item.callingFlag === 'Y' ? '是' : item.callingFlag === 'N' ? '否' : '',
  802. // 状态文本显示 - rqrq
  803. statusText: this.getStatusText(item.status)
  804. }
  805. })
  806. this.totalPage = data.page.totalCount
  807. } else {
  808. this.dataList = []
  809. this.totalPage = 0
  810. }
  811. this.dataListLoading = false
  812. })
  813. },
  814. // 获取分拣方式文本 - rqrq
  815. getSoreTypeText(soreType) {
  816. const soreTypeMap = {
  817. 0: '人工/混装',
  818. 1: '气胀轴自动分拣',
  819. 2: '抱箱自动分拣',
  820. 3: '直接出库'
  821. }
  822. return soreTypeMap[soreType] !== undefined ? soreTypeMap[soreType] : ''
  823. },
  824. // 获取状态文本 - rqrq
  825. getStatusText(status) {
  826. const statusMap = {
  827. 'AVAILABLE': '可用',
  828. 'OCCUPIED': '使用中',
  829. 'DAMAGED': '损坏',
  830. 'DISABLED': '禁用'
  831. }
  832. return statusMap[status] || status
  833. },
  834. // 每页数
  835. sizeChangeHandle(val) {
  836. this.pageSize = val
  837. this.pageIndex = 1
  838. this.getDataList()
  839. },
  840. // 当前页
  841. currentChangeHandle(val) {
  842. this.pageIndex = val
  843. this.getDataList()
  844. },
  845. // 多选
  846. selectionChangeHandle(val) {
  847. this.dataListSelections = val
  848. },
  849. // 批量删除
  850. deleteHandle() {
  851. var ids = this.dataListSelections.map(item => {
  852. return item.id
  853. })
  854. this.$confirm(`确定批量删除选中的托盘?`, '提示', {
  855. confirmButtonText: '确定',
  856. cancelButtonText: '取消',
  857. type: 'warning'
  858. }).then(() => {
  859. deletePallet(ids).then(({data}) => {
  860. if (data && data.code === 0) {
  861. this.$message.success('操作成功')
  862. this.getDataList()
  863. } else {
  864. this.$alert(data.msg, '错误', { confirmButtonText: '确定' })
  865. }
  866. })
  867. })
  868. },
  869. // 导出相关方法 - rqrq
  870. async createExportData() {
  871. const queryParams = {
  872. ...this.queryHeaderData,
  873. page: 1,
  874. limit: 999999 // 设置一个很大的数字来获取全部数据 - rqrq
  875. }
  876. const {data} = await getPalletList(queryParams)
  877. if (data && data.code === 0) {
  878. return (data.page.list || []).map(item => {
  879. return {
  880. ...item,
  881. soreTypeText: this.getSoreTypeText(item.soreType),
  882. autoSortText: item.autoSort === 'Y' ? '是' : item.autoSort === 'N' ? '否' : '',
  883. emptyFlagText: item.emptyFlag === 'Y' ? '是' : item.emptyFlag === 'N' ? '否' : '',
  884. callingFlagText: item.callingFlag === 'Y' ? '是' : item.callingFlag === 'N' ? '否' : '',
  885. statusText: this.getStatusText(item.status)
  886. }
  887. })
  888. }
  889. return []
  890. },
  891. startDownload() {
  892. // 开始导出 - rqrq
  893. },
  894. finishDownload() {
  895. // 导出完成 - rqrq
  896. },
  897. fields() {
  898. let json = "{"
  899. this.columnList.forEach((item, index) => {
  900. if (index == this.columnList.length - 1) {
  901. json += "\"" + item.columnLabel + "\"" + ":" + "\"" + item.columnProp + "\""
  902. } else {
  903. json += "\"" + item.columnLabel + "\"" + ":" + "\"" + item.columnProp + "\"" + ","
  904. }
  905. })
  906. json += "}"
  907. let s = eval("(" + json + ")")
  908. return s
  909. },
  910. // 打开批量新增弹窗 - rqrq
  911. openBatchGenerateDialog() {
  912. // 从store获取当前工厂 - rqrq
  913. this.batchGenerateDialog.site = this.$store.state.user.site
  914. this.batchGenerateDialog.palletNoList = []
  915. this.batchGenerateDialog.saving = false
  916. this.batchGenerateDialog.visible = true
  917. // 自动查询托盘数量 - rqrq
  918. this.loadPalletMaxNos()
  919. },
  920. // 加载托盘最大编号数据 - rqrq
  921. loadPalletMaxNos() {
  922. this.batchGenerateDialog.loading = true
  923. getMaxPalletNoByFamily({ site: this.batchGenerateDialog.site }).then(({data}) => {
  924. this.batchGenerateDialog.loading = false
  925. if (data && data.code === 0) {
  926. this.batchGenerateDialog.palletNoList = (data.rows || []).map(item => ({
  927. ...item,
  928. generateCount: null
  929. }))
  930. } else {
  931. this.$alert(data.msg || '获取托盘编号信息失败', '错误', { confirmButtonText: '确定' })
  932. this.batchGenerateDialog.palletNoList = []
  933. }
  934. }).catch(() => {
  935. this.batchGenerateDialog.loading = false
  936. this.$alert('获取托盘编号信息失败', '错误', { confirmButtonText: '确定' })
  937. this.batchGenerateDialog.palletNoList = []
  938. })
  939. },
  940. // 校验新增数量 - rqrq
  941. validateCount(item) {
  942. if (item.generateCount !== null && item.generateCount !== '') {
  943. let val = parseInt(item.generateCount)
  944. if (isNaN(val) || val < 0) {
  945. item.generateCount = null
  946. } else if (val > 1000) {
  947. item.generateCount = 1000
  948. this.$message.warning('单次最多新增1000个')
  949. } else {
  950. item.generateCount = val
  951. }
  952. }
  953. },
  954. // 执行批量生成 - rqrq
  955. doBatchGenerate() {
  956. // 1. 校验工厂 - rqrq
  957. if (!this.batchGenerateDialog.site) {
  958. this.$message.warning('请先选择工厂')
  959. return
  960. }
  961. // 2. 校验是否有需要生成的数量 - rqrq
  962. const generateItems = this.batchGenerateDialog.palletNoList.filter(item =>
  963. item.generateCount !== null && item.generateCount !== '' && parseInt(item.generateCount) > 0
  964. )
  965. if (generateItems.length === 0) {
  966. this.$message.warning('请至少输入一种托盘的新增数量')
  967. return
  968. }
  969. // 3. 校验数量不超过1000 - rqrq
  970. for (let item of generateItems) {
  971. if (parseInt(item.generateCount) > 1000) {
  972. this.$alert(`${item.palletFamilyDesc}新增数量不能超过1000`, '错误', { confirmButtonText: '确定' })
  973. return
  974. }
  975. }
  976. // 4. 确认提示 - rqrq
  977. let confirmMsg = '确定要生成以下托盘吗?\n\n'
  978. generateItems.forEach(item => {
  979. confirmMsg += `${item.palletFamilyDesc}(${item.prefix}): ${item.generateCount}\n`
  980. })
  981. this.$confirm(confirmMsg, '确认批量生成', {
  982. confirmButtonText: '确定',
  983. cancelButtonText: '取消',
  984. type: 'warning'
  985. }).then(() => {
  986. this.executeBatchGenerate(generateItems)
  987. }).catch(() => {})
  988. },
  989. // 执行批量生成请求 - rqrq
  990. async executeBatchGenerate(generateItems) {
  991. this.batchGenerateDialog.saving = true
  992. let successCount = 0
  993. let failedCount = 0
  994. let resultMsg = ''
  995. // 依次生成每种类型的托盘 - rqrq
  996. for (let item of generateItems) {
  997. try {
  998. const { data } = await batchGeneratePallet({
  999. site: this.batchGenerateDialog.site,
  1000. palletFamily: item.palletFamily,
  1001. count: item.generateCount,
  1002. username: this.$store.state.user.name
  1003. })
  1004. if (data && data.code === 0) {
  1005. successCount++
  1006. resultMsg += `${item.palletFamilyDesc}: 生成${data.count}个 (${data.startPalletId} ~ ${data.endPalletId})\n`
  1007. } else {
  1008. failedCount++
  1009. resultMsg += `${item.palletFamilyDesc}: ${data.msg || '生成失败'}\n`
  1010. }
  1011. } catch (e) {
  1012. failedCount++
  1013. resultMsg += `${item.palletFamilyDesc}: 请求异常\n`
  1014. }
  1015. }
  1016. this.batchGenerateDialog.saving = false
  1017. // 显示结果 - rqrq
  1018. if (failedCount === 0) {
  1019. this.$alert(resultMsg, '生成成功', {
  1020. confirmButtonText: '确定',
  1021. type: 'success',
  1022. callback: () => {
  1023. this.batchGenerateDialog.visible = false
  1024. this.getDataList()
  1025. }
  1026. })
  1027. } else {
  1028. this.$alert(resultMsg, `生成结果(成功${successCount},失败${failedCount}`, {
  1029. confirmButtonText: '确定',
  1030. type: failedCount === generateItems.length ? 'error' : 'warning',
  1031. callback: () => {
  1032. // 刷新编号信息 - rqrq
  1033. this.onBatchSiteChange(this.batchGenerateDialog.site)
  1034. this.getDataList()
  1035. }
  1036. })
  1037. }
  1038. }
  1039. },
  1040. created() {
  1041. // 初始化收藏状态
  1042. this.favorite = false
  1043. }
  1044. }
  1045. </script>
  1046. <style scoped>
  1047. .sl-svg {
  1048. overflow: hidden;
  1049. float: right;
  1050. }
  1051. </style>