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.

1615 lines
76 KiB

2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
3 weeks ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
  1. <template>
  2. <!-- 盘点查询页面 - rqrq -->
  3. <div class="mod-config yzz">
  4. <!-- 盘点模式开关区域 - rqrq -->
  5. <div class="count-mode-panel" :class="{'count-mode-on': countModeStatus === 'Y', 'count-mode-off': countModeStatus === 'N'}">
  6. <div class="count-mode-content">
  7. <span class="count-mode-icon">
  8. <i :class="countModeStatus === 'Y' ? 'el-icon-success' : 'el-icon-warning'"></i>
  9. </span>
  10. <span class="count-mode-label">盘点模式</span>
  11. <span class="count-mode-value">{{ countModeStatus === 'Y' ? '已开启' : '已关闭' }}</span>
  12. <el-switch
  13. v-model="countModeSwitch"
  14. active-color="#67C23A"
  15. inactive-color="#F56C6C"
  16. :loading="countModeLoading"
  17. @change="handleCountModeChange"
  18. style="margin-left: 15px;">
  19. </el-switch>
  20. <span class="count-mode-tip" v-if="countModeStatus === 'Y'">盘点模式下其他业务操作将受限</span>
  21. <span class="count-mode-tip" v-else>关闭盘点模式后可进行其他业务操作</span>
  22. </div>
  23. </div>
  24. <!-- 查询区域 -->
  25. <el-form label-position="top" style="margin-top: 1px; margin-left: 0px;">
  26. <el-form :inline="true" label-position="top" style="margin-top: 0px">
  27. <el-form-item label="盘点单号" style="margin-right: 10px;">
  28. <el-input v-model="queryForm.searchCountNo" placeholder="请输入盘点单号" clearable style="width: 150px;" @keyup.enter.native="search"></el-input>
  29. </el-form-item>
  30. <el-form-item label="盘点类型" style="margin-right: 10px;">
  31. <el-select v-model="queryForm.searchCountType" placeholder="请选择" clearable style="width: 120px;">
  32. <el-option label="循环盘点" value="CYCLE"></el-option>
  33. <el-option label="手工盘点" value="MANUAL"></el-option>
  34. </el-select>
  35. </el-form-item>
  36. <el-form-item label="状态" style="margin-right: 10px;">
  37. <el-select v-model="queryForm.searchStatus" placeholder="请选择" clearable style="width: 120px;">
  38. <el-option label="全部" value=""></el-option>
  39. <el-option label="草稿" value="DRAFT"></el-option>
  40. <el-option label="已下达" value="RELEASED"></el-option>
  41. <el-option label="盘点中" value="CHECKING"></el-option>
  42. <el-option label="已审批" value="APPROVED"></el-option>
  43. <el-option label="已完成" value="COMPLETED"></el-option>
  44. <el-option label="已取消" value="CANCELLED"></el-option>
  45. </el-select>
  46. </el-form-item>
  47. <el-form-item label="申请日期" style="margin-right: 10px;">
  48. <el-date-picker v-model="queryForm.startDate" type="date" placeholder="开始日期" value-format="yyyy-MM-dd" style="width: 130px;"></el-date-picker>
  49. <span style="margin: 0 5px;"></span>
  50. <el-date-picker v-model="queryForm.endDate" type="date" placeholder="结束日期" value-format="yyyy-MM-dd" style="width: 130px;"></el-date-picker>
  51. </el-form-item>
  52. <el-form-item label=" " style="margin-right: 10px;">
  53. <el-button type="primary" @click="search">查询</el-button>
  54. <el-button @click="resetQuery">重置</el-button>
  55. <el-button type="success" @click="showCycleCountDialog">循环盘点</el-button>
  56. <el-button type="warning" @click="handleCreateManualCount">手工盘点</el-button>
  57. </el-form-item>
  58. </el-form>
  59. </el-form>
  60. <!-- 主表格 - rqrq -->
  61. <el-table :data="dataList" @row-click="handleRowClick" :height="height" border highlight-current-row ref="mainTable" v-loading="dataListLoading" style="width: 100%;">
  62. <el-table-column
  63. v-for="(item,index) in mainColumnList" :key="index"
  64. :sortable="item.columnSortable"
  65. :prop="item.columnProp"
  66. :header-align="item.headerAlign"
  67. :show-overflow-tooltip="item.showOverflowTooltip"
  68. :align="item.align"
  69. :fixed="item.fixed==''?false:item.fixed"
  70. :min-width="item.columnWidth"
  71. :label="item.columnLabel">
  72. <template slot-scope="scope">
  73. <span v-if="item.columnProp === 'statusDesc'" :style="{color: getStatusColor(scope.row.status)}">{{ scope.row.statusDesc }}</span>
  74. <span v-else-if="item.columnProp === 'countPercent'">{{ scope.row.countPercent ? scope.row.countPercent + '%' : '' }}</span>
  75. <span v-else-if="item.columnProp === 'countProgress'">{{ scope.row.checkedPalletCount }}/{{ scope.row.totalPalletCount }}</span>
  76. <span v-else-if="item.columnProp === 'applyDate'">{{ formatDateTime(scope.row.applyDate) }}</span>
  77. <span v-else-if="item.columnProp === 'releaseDate'">{{ formatDateTime(scope.row.releaseDate) }}</span>
  78. <span v-else>{{ scope.row[item.columnProp] }}</span>
  79. </template>
  80. </el-table-column>
  81. <el-table-column header-align="center" align="center" fixed="right" width="240" label="操作">
  82. <template slot-scope="scope">
  83. <a type="text" style="margin-right: 10px;" @click.stop="handleAddMaterial(scope.row)" v-if="scope.row.status === 'DRAFT' && scope.row.countType === 'MANUAL'">添加物料</a>
  84. <a type="text" style="margin-right: 10px;" @click.stop="handleRelease(scope.row)" v-if="scope.row.status === 'DRAFT'">下达</a>
  85. <a type="text" style="margin-right: 10px;" @click.stop="handlePush(scope.row)" v-if="scope.row.status === 'RELEASED'">推送</a>
  86. <a type="text" style="margin-right: 10px;" @click.stop="handleComplete(scope.row)" v-if=" scope.row.status === 'CHECKING'">完成</a>
  87. <a type="text" style="margin-right: 10px;" @click.stop="handleCancel(scope.row)" v-if="scope.row.status !== 'COMPLETED' && scope.row.status !== 'CANCELLED'">取消</a>
  88. <a type="text" style="color: #F56C6C; margin-right: 10px;" @click.stop="handleDelete(scope.row)" v-if="scope.row.status === 'DRAFT'">删除</a>
  89. <a type="text" style="color: #67C23A; margin-right: 10px;" @click.stop="handleExportFrontend(scope.row)">导出明细</a>
  90. </template>
  91. </el-table-column>
  92. </el-table>
  93. <!-- 分页 -->
  94. <el-pagination @size-change="sizeChangeHandle" @current-change="currentChangeHandle" :current-page="pageIndex" :page-sizes="[20, 50, 100, 1000]" :page-size="pageSize" :total="totalPage" layout="total, sizes, prev, pager, next, jumper">
  95. </el-pagination>
  96. <!-- Tab标签页 -->
  97. <el-tabs style="font-size: 12px;min-height: 200px" class="customer-tab" v-model="activeName" type="border-card" @tab-click="tabClick">
  98. <el-tab-pane label="标签明细" name="label">
  99. <!-- 标签明细表格 - rqrq -->
  100. <el-table :data="labelList" :height="height" border v-loading="labelListLoading" style="width: 100%;">
  101. <el-table-column
  102. v-for="(item,index) in labelColumnList" :key="index"
  103. :sortable="item.columnSortable"
  104. :prop="item.columnProp"
  105. :header-align="item.headerAlign"
  106. :show-overflow-tooltip="item.showOverflowTooltip"
  107. :align="item.align"
  108. :fixed="item.fixed==''?false:item.fixed"
  109. :min-width="item.columnWidth"
  110. :label="item.columnLabel">
  111. <template slot-scope="scope">
  112. <span v-if="item.columnProp === 'countFlagDesc'" :style="{color: scope.row.countFlag === 'Y' ? '#67C23A' : '#F56C6C'}">{{ scope.row.countFlagDesc }}</span>
  113. <span v-else-if="item.columnProp === 'countDate'">{{ formatDateTime(scope.row.countDate) }}</span>
  114. <span v-else>{{ scope.row[item.columnProp] }}</span>
  115. </template>
  116. </el-table-column>
  117. </el-table>
  118. </el-tab-pane>
  119. <el-tab-pane label="物料汇总" name="summary">
  120. <!-- 物料汇总表格 - rqrq -->
  121. <el-table :data="summaryList" :height="height" border v-loading="summaryListLoading" style="width: 100%;">
  122. <el-table-column
  123. v-for="(item,index) in summaryColumnList" :key="index"
  124. :sortable="item.columnSortable"
  125. :prop="item.columnProp"
  126. :header-align="item.headerAlign"
  127. :show-overflow-tooltip="item.showOverflowTooltip"
  128. :align="item.align"
  129. :fixed="item.fixed==''?false:item.fixed"
  130. :min-width="item.columnWidth"
  131. :label="item.columnLabel">
  132. <template slot-scope="scope">
  133. <span>{{ scope.row[item.columnProp] }}</span>
  134. </template>
  135. </el-table-column>
  136. </el-table>
  137. </el-tab-pane>
  138. <el-tab-pane label="栈板明细" name="pallet">
  139. <!-- 栈板明细表格 - rqrq -->
  140. <el-table :data="palletList" :height="height" border v-loading="palletListLoading" style="width: 100%;">
  141. <el-table-column
  142. v-for="(item,index) in palletColumnList" :key="index"
  143. :sortable="item.columnSortable"
  144. :prop="item.columnProp"
  145. :header-align="item.headerAlign"
  146. :show-overflow-tooltip="item.showOverflowTooltip"
  147. :align="item.align"
  148. :fixed="item.fixed==''?false:item.fixed"
  149. :min-width="item.columnWidth"
  150. :label="item.columnLabel">
  151. <template slot-scope="scope">
  152. <span v-if="item.columnProp === 'countFlagDesc'" :style="{color: scope.row.countFlag === 'Y' ? '#67C23A' : '#F56C6C'}">{{ scope.row.countFlagDesc }}</span>
  153. <span v-else-if="item.columnProp === 'countDate'">{{ formatDateTime(scope.row.countDate) }}</span>
  154. <span v-else>{{ scope.row[item.columnProp] }}</span>
  155. </template>
  156. </el-table-column>
  157. </el-table>
  158. </el-tab-pane>
  159. <el-tab-pane label="盘点结果" name="result">
  160. <!-- 盘点结果表格 - rqrq -->
  161. <el-table :data="resultList" :height="height" border v-loading="resultListLoading" style="width: 100%;">
  162. <el-table-column
  163. v-for="(item,index) in resultColumnList" :key="index"
  164. :sortable="item.columnSortable"
  165. :prop="item.columnProp"
  166. :header-align="item.headerAlign"
  167. :show-overflow-tooltip="item.showOverflowTooltip"
  168. :align="item.align"
  169. :fixed="item.fixed==''?false:item.fixed"
  170. :min-width="item.columnWidth"
  171. :label="item.columnLabel">
  172. <template slot-scope="scope">
  173. <span v-if="item.columnProp === 'countResultDesc'" :style="{color: getResultColor(scope.row.countResult)}">{{ scope.row.countResultDesc }}</span>
  174. <span v-else-if="item.columnProp === 'diffQty'" :style="{color: scope.row.diffQty != 0 ? '#F56C6C' : '#67C23A'}">{{ scope.row.diffQty }}</span>
  175. <span v-else-if="item.columnProp === 'handleFlagDesc'" :style="{color: scope.row.handleFlag === 'Y' ? '#67C23A' : '#F56C6C'}">{{ scope.row.handleFlagDesc }}</span>
  176. <span v-else-if="item.columnProp === 'countDate'">{{ formatDateTime(scope.row.countDate) }}</span>
  177. <span v-else>{{ scope.row[item.columnProp] }}</span>
  178. </template>
  179. </el-table-column>
  180. </el-table>
  181. </el-tab-pane>
  182. <!-- 盘点结果差异页签 - rqrq -->
  183. <el-tab-pane label="盘点结果差异" name="resultDiff">
  184. <el-table :data="resultDiffList" :height="height" border v-loading="resultDiffListLoading" style="width: 100%;">
  185. <el-table-column
  186. v-for="(item,index) in resultColumnList2" :key="index"
  187. :sortable="item.columnSortable"
  188. :prop="item.columnProp"
  189. :header-align="item.headerAlign"
  190. :show-overflow-tooltip="item.showOverflowTooltip"
  191. :align="item.align"
  192. :fixed="item.fixed==''?false:item.fixed"
  193. :min-width="item.columnWidth"
  194. :label="item.columnLabel">
  195. <template slot-scope="scope">
  196. <span v-if="item.columnProp === 'countResultDesc'" :style="{color: getResultColor(scope.row.countResult)}">{{ scope.row.countResultDesc }}</span>
  197. <span v-else-if="item.columnProp === 'diffQty'" :style="{color: scope.row.diffQty != 0 ? '#F56C6C' : '#67C23A'}">{{ scope.row.diffQty }}</span>
  198. <span v-else-if="item.columnProp === 'handleFlagDesc'" :style="{color: scope.row.handleFlag === 'Y' ? '#67C23A' : '#F56C6C'}">{{ scope.row.handleFlagDesc }}</span>
  199. <span v-else-if="item.columnProp === 'countDate'">{{ formatDateTime(scope.row.countDate) }}</span>
  200. <span v-else>{{ scope.row[item.columnProp] }}</span>
  201. </template>
  202. </el-table-column>
  203. </el-table>
  204. </el-tab-pane>
  205. <!-- 任务单页签 - rqrq -->
  206. <el-tab-pane label="任务单" name="task">
  207. <div style="display: flex; gap: 10px;">
  208. <!-- 左边任务单主表 - rqrq -->
  209. <div style="flex: 1;">
  210. <div style="font-weight: bold; margin-bottom: 5px; font-size: 12px;">任务单</div>
  211. <el-table :data="taskList" :height="height" border v-loading="taskListLoading"
  212. highlight-current-row @row-click="onTaskRowClick" style="width: 100%;">
  213. <el-table-column prop="taskNo" label="任务号" min-width="120" header-align="center" align="center"></el-table-column>
  214. <el-table-column prop="sourceType" label="来源类型" min-width="140" header-align="center" align="center"></el-table-column>
  215. <el-table-column prop="status" label="状态" min-width="80" header-align="center" align="center">
  216. <template slot-scope="scope">
  217. <span :style="{color: scope.row.status === '已完成' ? '#67C23A' : '#E6A23C'}">{{ scope.row.status }}</span>
  218. </template>
  219. </el-table-column>
  220. <el-table-column prop="createdBy" label="创建人" min-width="80" header-align="center" align="center"></el-table-column>
  221. <el-table-column prop="createdTime" label="创建时间" min-width="140" header-align="center" align="center">
  222. <template slot-scope="scope">
  223. <span>{{ formatDateTime(scope.row.createdTime) }}</span>
  224. </template>
  225. </el-table-column>
  226. </el-table>
  227. </div>
  228. <!-- 右边任务单明细 - rqrq -->
  229. <div style="flex: 1;">
  230. <div style="font-weight: bold; margin-bottom: 5px; font-size: 12px;">任务单明细</div>
  231. <el-table :data="taskDetailList" :height="height" border v-loading="taskDetailListLoading" style="width: 100%;">
  232. <el-table-column prop="seqNo" label="序号" min-width="60" header-align="center" align="center"></el-table-column>
  233. <el-table-column prop="palletId" label="栈板号" min-width="150" header-align="center" align="center"></el-table-column>
  234. <el-table-column prop="wmsStatus" label="WMS状态" min-width="100" header-align="center" align="center">
  235. <template slot-scope="scope">
  236. <span :style="{color: scope.row.wmsStatus === '已盘点' ? '#67C23A' : '#909399'}">{{ scope.row.wmsStatus }}</span>
  237. </template>
  238. </el-table-column>
  239. </el-table>
  240. </div>
  241. </div>
  242. </el-tab-pane>
  243. <!-- 盘盈盘亏记录页签 - rqrq -->
  244. <el-tab-pane label="盘盈盘亏记录" name="adjustment">
  245. <div style="display: flex; gap: 10px;">
  246. <!-- 左边盘盈盘亏明细 - rqrq -->
  247. <div style="flex: 1;">
  248. <div style="font-weight: bold; margin-bottom: 5px; font-size: 12px;">盘盈盘亏明细</div>
  249. <el-table :data="adjustmentTransList" :height="height" border v-loading="adjustmentTransLoading"
  250. highlight-current-row @row-click="onAdjustmentTransRowClick" style="width: 100%;">
  251. <el-table-column prop="transNo" label="单据号" min-width="120" header-align="center" align="center"></el-table-column>
  252. <el-table-column prop="transTypeDesc" label="事务类型" min-width="80" header-align="center" align="center">
  253. <template slot-scope="scope">
  254. <span :style="{color: scope.row.transTypeDb === 'PY' ? '#67C23A' : '#F56C6C'}">{{ scope.row.transTypeDesc }}</span>
  255. </template>
  256. </el-table-column>
  257. <el-table-column prop="itemNo" label="行号" min-width="60" header-align="center" align="center"></el-table-column>
  258. <el-table-column prop="partNo" label="物料号" min-width="120" header-align="center" align="center"></el-table-column>
  259. <el-table-column prop="transQty" label="数量" min-width="100" header-align="center" align="center"></el-table-column>
  260. <el-table-column prop="batchNo" label="批号" min-width="100" header-align="center" align="center"></el-table-column>
  261. <el-table-column prop="locationId" label="库位" min-width="100" header-align="center" align="center"></el-table-column>
  262. <el-table-column prop="directionDesc" label="方向" min-width="60" header-align="center" align="center">
  263. <template slot-scope="scope">
  264. <span :style="{color: scope.row.direction === '+' ? '#67C23A' : '#F56C6C'}">{{ scope.row.directionDesc }}</span>
  265. </template>
  266. </el-table-column>
  267. <el-table-column prop="warehouseId" label="仓库" min-width="80" header-align="center" align="center"></el-table-column>
  268. <el-table-column prop="userName" label="操作人" min-width="80" header-align="center" align="center"></el-table-column>
  269. </el-table>
  270. </div>
  271. <!-- 右边标签明细 - rqrq -->
  272. <div style="flex: 1;">
  273. <div style="font-weight: bold; margin-bottom: 5px; font-size: 12px;">标签明细</div>
  274. <el-table :data="adjustmentTransSubList" :height="height" border v-loading="adjustmentTransSubLoading" style="width: 100%;">
  275. <el-table-column prop="subNo" label="标签号" min-width="150" header-align="center" align="center"></el-table-column>
  276. <el-table-column prop="subQty" label="数量" min-width="80" header-align="center" align="center"></el-table-column>
  277. <el-table-column prop="partNo" label="物料号" min-width="120" header-align="center" align="center"></el-table-column>
  278. <el-table-column prop="batchNo" label="批号" min-width="100" header-align="center" align="center"></el-table-column>
  279. <el-table-column prop="locationId" label="库位" min-width="100" header-align="center" align="center"></el-table-column>
  280. <el-table-column prop="palletId" label="栈板号" min-width="120" header-align="center" align="center"></el-table-column>
  281. <el-table-column prop="directionDesc" label="方向" min-width="60" header-align="center" align="center">
  282. <template slot-scope="scope">
  283. <span :style="{color: scope.row.direction === '+' ? '#67C23A' : '#F56C6C'}">{{ scope.row.directionDesc }}</span>
  284. </template>
  285. </el-table-column>
  286. </el-table>
  287. </div>
  288. </div>
  289. </el-tab-pane>
  290. </el-tabs>
  291. <!-- 循环盘点弹窗 -->
  292. <el-dialog title="创建循环盘点单" :visible.sync="cycleCountDialogVisible" width="400px" :close-on-click-modal="false" v-drag>
  293. <el-form :model="cycleCountForm" label-width="100px">
  294. <el-form-item label="未盘比例(%)">
  295. <el-input v-model="nowPercent" disabled style="width: 250px;"></el-input>
  296. </el-form-item>
  297. <el-form-item label="盘点比例(%)">
  298. <el-input v-model="cycleCountForm.countPercent" style="width: 250px;"></el-input>
  299. </el-form-item>
  300. <el-form-item label="备注">
  301. <el-input v-model="cycleCountForm.remark" type="textarea" :rows="3" style="width: 250px;"></el-input>
  302. </el-form-item>
  303. </el-form>
  304. <el-footer style="height:30px;margin-top: 60px;text-align:center">
  305. <el-button type="primary" @click="createCycleCount" :loading="createLoading" :disabled="createLoading">{{ createLoading ? '创建中...' : '创 建' }}</el-button>
  306. <el-button @click="cycleCountDialogVisible = false" :disabled="createLoading"> </el-button>
  307. </el-footer>
  308. </el-dialog>
  309. <!-- 添加物料弹窗显示已有标签列表-->
  310. <el-dialog :title="'添加物料 - ' + (addMaterialRow ? addMaterialRow.countNo : '')" :visible.sync="addMaterialDialogVisible" width="1000px" :close-on-click-modal="false" v-drag>
  311. <div style="margin-bottom: 10px; display: flex; align-items: center; gap: 15px;">
  312. <el-button type="primary" size="small" @click="showMaterialQueryDialog">选择物料</el-button>
  313. <!-- 一键物料操作 - rqrq -->
  314. <div style="display: flex; align-items: center; gap: 5px;">
  315. <span style="font-size: 12px; color: #606266;">一键物料操作:</span>
  316. <el-input
  317. v-model="quickMaterialPartNo"
  318. placeholder="输入物料号回车"
  319. clearable
  320. ref="part"
  321. size="small"
  322. style="width: 150px;"
  323. @keyup.enter.native="handleQuickMaterialAction"
  324. :disabled="quickMaterialLoading">
  325. </el-input>
  326. <el-select v-model="quickMaterialAction" size="small" style="width: 80px;">
  327. <el-option label="添加" value="add"></el-option>
  328. <el-option label="删除" value="delete"></el-option>
  329. </el-select>
  330. <el-button
  331. :type="quickMaterialAction === 'add' ? 'success' : 'danger'"
  332. size="small"
  333. @click="handleQuickMaterialAction"
  334. :loading="quickMaterialLoading"
  335. :disabled="quickMaterialLoading || !quickMaterialPartNo">
  336. {{ quickMaterialLoading ? '处理中...' : (quickMaterialAction === 'add' ? '添加' : '删除') }}
  337. </el-button>
  338. </div>
  339. </div>
  340. <!-- 当前标签列表表格 - rqrq -->
  341. <el-table :data="currentLabelList" :height="350" border v-loading="currentLabelListLoading" style="width: 100%;">
  342. <el-table-column
  343. v-for="(item,index) in currentLabelColumnList" :key="index"
  344. :sortable="item.columnSortable"
  345. :prop="item.columnProp"
  346. :header-align="item.headerAlign"
  347. :show-overflow-tooltip="item.showOverflowTooltip"
  348. :align="item.align"
  349. :fixed="item.fixed==''?false:item.fixed"
  350. :min-width="item.columnWidth"
  351. :label="item.columnLabel">
  352. <template slot-scope="scope">
  353. <span>{{ scope.row[item.columnProp] }}</span>
  354. </template>
  355. </el-table-column>
  356. </el-table>
  357. <span slot="footer" class="dialog-footer">
  358. <el-button @click="addMaterialDialogVisible = false"> </el-button>
  359. </span>
  360. </el-dialog>
  361. <!-- 物料查询弹窗添加物料时使用-->
  362. <el-dialog title="查询物料" :visible.sync="materialQueryDialogVisible" width="900px" :close-on-click-modal="false" v-drag append-to-body>
  363. <el-form :inline="true" :model="materialQueryForm" label-position="top">
  364. <el-form-item label="物料编码" style="margin-right: 10px;">
  365. <el-input v-model="materialQueryForm.searchPartNo" placeholder="请输入物料编码" clearable style="width: 150px;" @keyup.enter.native="queryMaterialForAdd"></el-input>
  366. </el-form-item>
  367. <el-form-item label="批号" style="margin-right: 10px;">
  368. <el-input v-model="materialQueryForm.searchBatchNo" placeholder="请输入批号" clearable style="width: 120px;"></el-input>
  369. </el-form-item>
  370. <el-form-item label="WDR号" style="margin-right: 10px;">
  371. <el-input v-model="materialQueryForm.searchWdr" placeholder="请输入WDR号" clearable style="width: 120px;"></el-input>
  372. </el-form-item>
  373. <el-form-item label=" ">
  374. <el-button type="primary" @click="queryMaterialForAdd" :loading="materialQueryLoading">查询</el-button>
  375. </el-form-item>
  376. </el-form>
  377. <!-- 物料查询表格 - rqrq -->
  378. <el-table :data="materialQueryList" :height="300" border highlight-current-row ref="materialQueryTable" v-loading="materialQueryLoading" @selection-change="handleMaterialSelectionChange" style="width: 100%;">
  379. <el-table-column type="selection" width="30"></el-table-column>
  380. <el-table-column
  381. v-for="(item,index) in materialQueryColumnList" :key="index"
  382. :sortable="item.columnSortable"
  383. :prop="item.columnProp"
  384. :header-align="item.headerAlign"
  385. :show-overflow-tooltip="item.showOverflowTooltip"
  386. :align="item.align"
  387. :fixed="item.fixed==''?false:item.fixed"
  388. :min-width="item.columnWidth"
  389. :label="item.columnLabel">
  390. <template slot-scope="scope">
  391. <span>{{ scope.row[item.columnProp] }}</span>
  392. </template>
  393. </el-table-column>
  394. </el-table>
  395. <span slot="footer" class="dialog-footer">
  396. <el-button @click="materialQueryDialogVisible = false" :disabled="addMaterialLoading"> </el-button>
  397. <el-button type="primary" @click="confirmAddMaterial" :loading="addMaterialLoading" :disabled="addMaterialLoading || selectedMaterials.length === 0">{{ addMaterialLoading ? '添加中...' : '确认添加' }}</el-button>
  398. </span>
  399. </el-dialog>
  400. </div>
  401. </template>
  402. <script>
  403. import { searchCountHeaderList, createCycleCount, createManualCount, queryMaterialForManualCount, addMaterialToCount, quickAddMaterialByPartNo, deleteMaterialByPartNo,
  404. releaseCount, pushCountToWcs, completeCount, cancelCount, deleteCount, searchCountLabelList,
  405. searchCountPalletList, searchCountResultList, searchMaterialSummary, searchOrderTaskByCountNo,
  406. searchOrderTaskDetail, getSysIfCount, updateSysIfCount, queryAdjustmentTransList,
  407. queryAdjustmentTransSubList, selectNowUnCountPercent, exportCountDataExcel } from '@/api/check/physicalInventory'
  408. import * as XLSX from 'xlsx' // 前端Excel导出 - rqrq
  409. export default {
  410. name: 'searchPhysicalInventory',
  411. data() {
  412. return {
  413. // 盘点模式相关 - rqrq
  414. countModeStatus: 'N', // 当前盘点模式状态 Y=开启 N=关闭
  415. countModeSwitch: false, // 开关状态
  416. countModeLoading: false, // 开关loading状态
  417. // 主表相关 - rqrq
  418. dataList: [],
  419. dataListLoading: false,
  420. pageIndex: 1,
  421. pageSize: 20,
  422. totalPage: 0,
  423. height: 300,
  424. currentRow: null,
  425. // 查询表单 - rqrq
  426. queryForm: {
  427. searchCountNo: '',
  428. searchCountType: '',
  429. searchStatus: '',
  430. startDate: '',
  431. endDate: ''
  432. },
  433. // 主表格列配置 - rqrq
  434. mainColumnList: [
  435. { columnProp: "countNo", headerAlign: "center", align: "center", columnLabel: "盘点单号", columnWidth: 160, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  436. { columnProp: "countTypeDesc", headerAlign: "center", align: "center", columnLabel: "盘点类型", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  437. { columnProp: "statusDesc", headerAlign: "center", align: "center", columnLabel: "状态", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  438. { columnProp: "countPercent", headerAlign: "center", align: "center", columnLabel: "循环比例", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  439. { columnProp: "countProgress", headerAlign: "center", align: "center", columnLabel: "盘点进度(栈板)", columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  440. { columnProp: "totalLabelCount", headerAlign: "center", align: "center", columnLabel: "标签数", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  441. { columnProp: "applyUser", headerAlign: "center", align: "center", columnLabel: "申请人", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  442. { columnProp: "applyDate", headerAlign: "center", align: "center", columnLabel: "申请日期", columnWidth: 140, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  443. { columnProp: "releaseUser", headerAlign: "center", align: "center", columnLabel: "下达人", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  444. { columnProp: "releaseDate", headerAlign: "center", align: "center", columnLabel: "下达日期", columnWidth: 140, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  445. { columnProp: "remark", headerAlign: "center", align: "left", columnLabel: "备注", columnWidth: 150, columnSortable: false, showOverflowTooltip: true, fixed: "" }
  446. ],
  447. // Tab相关 - rqrq
  448. activeName: 'label',
  449. labelList: [],
  450. labelListLoading: false,
  451. palletList: [],
  452. palletListLoading: false,
  453. resultList: [],
  454. resultListLoading: false,
  455. resultDiffList: [], // 盘点结果差异列表(非OK的结果)- rqrq
  456. resultDiffListLoading: false,
  457. summaryList: [],
  458. summaryListLoading: false,
  459. // 标签明细列配置 - rqrq
  460. labelColumnList: [
  461. { columnProp: "unitId", headerAlign: "center", align: "center", columnLabel: "标签号", columnWidth: 150, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  462. { columnProp: "partNo", headerAlign: "center", align: "center", columnLabel: "物料号", columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  463. { columnProp: "partDesc", headerAlign: "center", align: "left", columnLabel: "物料描述", columnWidth: 180, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  464. { columnProp: "qty", headerAlign: "center", align: "center", columnLabel: "数量", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  465. { columnProp: "batchNo", headerAlign: "center", align: "center", columnLabel: "批号", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  466. { columnProp: "palletId", headerAlign: "center", align: "center", columnLabel: "栈板号", columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  467. { columnProp: "locationZ", headerAlign: "center", align: "center", columnLabel: "所在层数", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  468. { columnProp: "labelTypeDesc", headerAlign: "center", align: "center", columnLabel: "标签类型", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  469. { columnProp: "countFlagDesc", headerAlign: "center", align: "center", columnLabel: "盘点状态", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  470. { columnProp: "countUser", headerAlign: "center", align: "center", columnLabel: "盘点人", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  471. { columnProp: "countDate", headerAlign: "center", align: "center", columnLabel: "盘点时间", columnWidth: 140, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  472. { columnProp: "warehouseName", headerAlign: "center", align: "center", columnLabel: "仓库", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  473. { columnProp: "locationName", headerAlign: "center", align: "center", columnLabel: "库位", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" }
  474. ],
  475. // 栈板明细列配置 - rqrq
  476. palletColumnList: [
  477. { columnProp: "seqNo", headerAlign: "center", align: "center", columnLabel: "序号", columnWidth: 60, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  478. { columnProp: "palletId", headerAlign: "center", align: "center", columnLabel: "栈板号", columnWidth: 150, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  479. { columnProp: "labelCount", headerAlign: "center", align: "center", columnLabel: "标签数", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  480. { columnProp: "checkedCount", headerAlign: "center", align: "center", columnLabel: "已盘点", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  481. { columnProp: "progressPercent", headerAlign: "center", align: "center", columnLabel: "进度", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  482. { columnProp: "countFlagDesc", headerAlign: "center", align: "center", columnLabel: "盘点状态", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  483. { columnProp: "stationArea", headerAlign: "center", align: "center", columnLabel: "站点区域", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  484. { columnProp: "stationId", headerAlign: "center", align: "center", columnLabel: "站点ID", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  485. { columnProp: "locationZ", headerAlign: "center", align: "center", columnLabel: "所在层数", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  486. { columnProp: "countUser", headerAlign: "center", align: "center", columnLabel: "盘点人", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  487. { columnProp: "countDate", headerAlign: "center", align: "center", columnLabel: "盘点时间", columnWidth: 140, columnSortable: false, showOverflowTooltip: true, fixed: "" }
  488. ],
  489. // 盘点结果列配置 - rqrq
  490. resultColumnList: [
  491. { columnProp: "unitId", headerAlign: "center", align: "center", columnLabel: "标签号", columnWidth: 150, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  492. { columnProp: "partNo", headerAlign: "center", align: "center", columnLabel: "物料号", columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  493. { columnProp: "partDesc", headerAlign: "center", align: "left", columnLabel: "物料描述", columnWidth: 180, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  494. { columnProp: "qty", headerAlign: "center", align: "center", columnLabel: "数量", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  495. { columnProp: "diffQty", headerAlign: "center", align: "center", columnLabel: "差异数量", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  496. { columnProp: "batchNo", headerAlign: "center", align: "center", columnLabel: "批号", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  497. { columnProp: "palletId", headerAlign: "center", align: "center", columnLabel: "栈板号", columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  498. { columnProp: "countResultDesc", headerAlign: "center", align: "center", columnLabel: "盘点结果", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  499. // { columnProp: "handleFlagDesc", headerAlign: "center", align: "center", columnLabel: "是否处理", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  500. { columnProp: "handleTypeDesc", headerAlign: "center", align: "center", columnLabel: "处理方式", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  501. { columnProp: "countUser", headerAlign: "center", align: "center", columnLabel: "盘点人", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  502. { columnProp: "countDate", headerAlign: "center", align: "center", columnLabel: "盘点时间", columnWidth: 140, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  503. { columnProp: "remark", headerAlign: "center", align: "left", columnLabel: "备注", columnWidth: 300, columnSortable: false, showOverflowTooltip: true, fixed: "" }
  504. ],
  505. // 盘点结果差异配置 - rqrq
  506. resultColumnList2: [
  507. { columnProp: "unitId", headerAlign: "center", align: "center", columnLabel: "标签号", columnWidth: 150, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  508. { columnProp: "partNo", headerAlign: "center", align: "center", columnLabel: "物料号", columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  509. { columnProp: "partDesc", headerAlign: "center", align: "left", columnLabel: "物料描述", columnWidth: 180, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  510. { columnProp: "qty", headerAlign: "center", align: "center", columnLabel: "数量", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  511. { columnProp: "diffQty", headerAlign: "center", align: "center", columnLabel: "差异数量", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  512. { columnProp: "batchNo", headerAlign: "center", align: "center", columnLabel: "批号", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  513. { columnProp: "palletId", headerAlign: "center", align: "center", columnLabel: "栈板号", columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  514. { columnProp: "countResultDesc", headerAlign: "center", align: "center", columnLabel: "盘点结果", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  515. { columnProp: "handleFlagDesc", headerAlign: "center", align: "center", columnLabel: "是否处理", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  516. { columnProp: "handleTypeDesc", headerAlign: "center", align: "center", columnLabel: "处理方式", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  517. { columnProp: "countUser", headerAlign: "center", align: "center", columnLabel: "盘点人", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  518. { columnProp: "countDate", headerAlign: "center", align: "center", columnLabel: "盘点时间", columnWidth: 140, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  519. { columnProp: "remark", headerAlign: "center", align: "left", columnLabel: "备注", columnWidth: 300, columnSortable: false, showOverflowTooltip: true, fixed: "" }
  520. ],
  521. // 物料汇总列配置 - rqrq
  522. summaryColumnList: [
  523. { columnProp: "partNo", headerAlign: "center", align: "center", columnLabel: "物料号", columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  524. { columnProp: "partDesc", headerAlign: "center", align: "left", columnLabel: "物料描述", columnWidth: 180, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  525. { columnProp: "batchNo", headerAlign: "center", align: "center", columnLabel: "批号", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  526. { columnProp: "wdr", headerAlign: "center", align: "center", columnLabel: "WDR号", columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  527. { columnProp: "warehouseName", headerAlign: "center", align: "center", columnLabel: "仓库", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  528. { columnProp: "locationName", headerAlign: "center", align: "center", columnLabel: "库位", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  529. { columnProp: "labelCount", headerAlign: "center", align: "center", columnLabel: "标签数", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  530. { columnProp: "totalQty", headerAlign: "center", align: "center", columnLabel: "总数量", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  531. { columnProp: "palletCount", headerAlign: "center", align: "center", columnLabel: "栈板数", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  532. { columnProp: "checkedLabelCount", headerAlign: "center", align: "center", columnLabel: "已盘点", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  533. { columnProp: "progressPercent", headerAlign: "center", align: "center", columnLabel: "进度", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" }
  534. ],
  535. // 循环盘点弹窗 - rqrq
  536. cycleCountDialogVisible: false,
  537. cycleCountForm: {
  538. countPercent: 10,
  539. remark: ''
  540. },
  541. nowPercent:null,//当前未盘比例
  542. createLoading: false,
  543. // 添加物料弹窗 - rqrq
  544. addMaterialDialogVisible: false,
  545. addMaterialRow: null,
  546. currentLabelList: [],
  547. currentLabelListLoading: false,
  548. // 一键物料操作 - rqrq
  549. quickMaterialPartNo: '',
  550. quickMaterialAction: 'add', // add-添加 delete-删除
  551. quickMaterialLoading: false,
  552. // 当前标签列表列配置 - rqrq
  553. currentLabelColumnList: [
  554. { columnProp: "unitId", headerAlign: "center", align: "center", columnLabel: "标签号", columnWidth: 150, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  555. { columnProp: "partNo", headerAlign: "center", align: "center", columnLabel: "物料号", columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  556. { columnProp: "partDesc", headerAlign: "center", align: "left", columnLabel: "物料描述", columnWidth: 180, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  557. { columnProp: "qty", headerAlign: "center", align: "center", columnLabel: "数量", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  558. { columnProp: "batchNo", headerAlign: "center", align: "center", columnLabel: "批号", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  559. { columnProp: "palletId", headerAlign: "center", align: "center", columnLabel: "栈板号", columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  560. { columnProp: "labelTypeDesc", headerAlign: "center", align: "center", columnLabel: "标签类型", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  561. { columnProp: "warehouseName", headerAlign: "center", align: "center", columnLabel: "仓库", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  562. { columnProp: "locationName", headerAlign: "center", align: "center", columnLabel: "库位", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" }
  563. ],
  564. // 物料查询弹窗 - rqrq
  565. materialQueryDialogVisible: false,
  566. materialQueryForm: {
  567. searchPartNo: '',
  568. searchBatchNo: '',
  569. searchWdr: ''
  570. },
  571. materialQueryList: [],
  572. materialQueryLoading: false,
  573. selectedMaterials: [],
  574. addMaterialLoading: false,
  575. // 物料查询列配置 - rqrq
  576. materialQueryColumnList: [
  577. { columnProp: "partNo", headerAlign: "center", align: "center", columnLabel: "物料号", columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  578. { columnProp: "partDesc", headerAlign: "center", align: "left", columnLabel: "物料描述", columnWidth: 180, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  579. { columnProp: "batchNo", headerAlign: "center", align: "center", columnLabel: "批号", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  580. { columnProp: "wdr", headerAlign: "center", align: "center", columnLabel: "WDR号", columnWidth: 120, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  581. { columnProp: "warehouseName", headerAlign: "center", align: "center", columnLabel: "仓库", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  582. { columnProp: "locationName", headerAlign: "center", align: "center", columnLabel: "库位", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  583. { columnProp: "labelCount", headerAlign: "center", align: "center", columnLabel: "标签数", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  584. { columnProp: "totalQty", headerAlign: "center", align: "center", columnLabel: "总数量", columnWidth: 100, columnSortable: false, showOverflowTooltip: true, fixed: "" },
  585. { columnProp: "palletCount", headerAlign: "center", align: "center", columnLabel: "栈板数", columnWidth: 80, columnSortable: false, showOverflowTooltip: true, fixed: "" }
  586. ],
  587. // 任务单相关 - rqrq
  588. taskList: [],
  589. taskListLoading: false,
  590. taskDetailList: [],
  591. taskDetailListLoading: false,
  592. currentTask: null,
  593. // 盘盈盘亏记录相关 - rqrq
  594. adjustmentTransList: [], // 盘盈盘亏明细列表
  595. adjustmentTransLoading: false,
  596. adjustmentTransSubList: [], // 标签明细列表
  597. adjustmentTransSubLoading: false,
  598. currentAdjustmentTrans: null, // 当前选中的事务
  599. // 导出相关 - rqrq
  600. exportLoading: false
  601. }
  602. },
  603. mounted() {
  604. // 计算表格高度 - rqrq
  605. this.height = (window.innerHeight - 315) / 2
  606. // 加载盘点模式状态 - rqrq
  607. this.loadCountModeStatus()
  608. this.search()
  609. },
  610. methods: {
  611. // ==================== 盘点模式管理 ==================== - rqrq
  612. // 加载盘点模式状态 - rqrq
  613. loadCountModeStatus() {
  614. const params = {
  615. site: this.$store.state.user.site
  616. }
  617. getSysIfCount(params).then(({ data }) => {
  618. if (data && data.code === 0) {
  619. this.countModeStatus = data.value || 'N'
  620. this.countModeSwitch = this.countModeStatus === 'Y'
  621. }
  622. })
  623. },
  624. // 盘点模式开关变更 - rqrq
  625. handleCountModeChange(val) {
  626. const newValue = val ? 'Y' : 'N'
  627. const actionText = val ? '开启' : '关闭'
  628. this.$confirm(`确认${actionText}盘点模式?${val ? '开启后其他业务操作将受限。' : ''}`, '提示', {
  629. confirmButtonText: '确定',
  630. cancelButtonText: '取消',
  631. type: 'warning'
  632. }).then(() => {
  633. this.countModeLoading = true
  634. const params = {
  635. site: this.$store.state.user.site,
  636. value: newValue
  637. }
  638. updateSysIfCount(params).then(({ data }) => {
  639. if (data && data.code === 0) {
  640. this.countModeStatus = newValue
  641. this.countModeSwitch = val
  642. this.$message.success(`盘点模式已${actionText}`)
  643. } else {
  644. // 恢复开关状态
  645. this.countModeSwitch = !val
  646. this.$alert(data.msg || `${actionText}盘点模式失败`, '错误', { confirmButtonText: '确定' })
  647. }
  648. }).catch(() => {
  649. // 恢复开关状态
  650. this.countModeSwitch = !val
  651. this.$alert('网络错误', '错误', { confirmButtonText: '确定' })
  652. }).finally(() => {
  653. this.countModeLoading = false
  654. })
  655. }).catch(() => {
  656. // 用户取消,恢复开关状态
  657. this.countModeSwitch = !val
  658. })
  659. },
  660. // ==================== 查询相关 ==================== - rqrq
  661. // 查询 - rqrq
  662. search() {
  663. this.pageIndex = 1
  664. this.getDataList()
  665. },
  666. // 重置查询 - rqrq
  667. resetQuery() {
  668. this.queryForm = {
  669. searchCountNo: '',
  670. searchCountType: '',
  671. searchStatus: '',
  672. startDate: '',
  673. endDate: ''
  674. }
  675. this.search()
  676. },
  677. // 获取主表数据 - rqrq
  678. getDataList() {
  679. this.dataListLoading = true
  680. const params = {
  681. ...this.queryForm,
  682. site: this.$store.state.user.site,
  683. page: this.pageIndex,
  684. limit: this.pageSize
  685. }
  686. searchCountHeaderList(params).then(({ data }) => {
  687. if (data && data.code === 0) {
  688. this.dataList = data.page.list
  689. this.totalPage = data.page.totalCount
  690. // 自动选择第一条记录并加载明细 - rqrq
  691. if (this.dataList && this.dataList.length > 0) {
  692. this.$nextTick(() => {
  693. this.$refs.mainTable.setCurrentRow(this.dataList[0])
  694. this.currentRow = this.dataList[0]
  695. this.loadTabData()
  696. })
  697. } else {
  698. this.currentRow = null
  699. this.labelList = []
  700. this.palletList = []
  701. this.resultList = []
  702. this.resultDiffList = []
  703. this.summaryList = []
  704. }
  705. } else {
  706. this.$alert(data.msg || '查询失败', '错误', { confirmButtonText: '确定' })
  707. }
  708. }).catch(() => {
  709. this.$alert('网络错误', '错误', { confirmButtonText: '确定' })
  710. }).finally(() => {
  711. this.dataListLoading = false
  712. })
  713. },
  714. // 行点击 - rqrq
  715. handleRowClick(row) {
  716. this.currentRow = row
  717. this.loadTabData()
  718. },
  719. // Tab点击 - rqrq
  720. tabClick() {
  721. this.loadTabData()
  722. },
  723. // 加载Tab数据 - rqrq
  724. loadTabData() {
  725. if (!this.currentRow) return
  726. const params = {
  727. site: this.$store.state.user.site,
  728. countNo: this.currentRow.countNo
  729. }
  730. if (this.activeName === 'label') {
  731. this.loadLabelList(params)
  732. } else if (this.activeName === 'pallet') {
  733. this.loadPalletList(params)
  734. } else if (this.activeName === 'result') {
  735. this.loadResultList(params)
  736. } else if (this.activeName === 'resultDiff') {
  737. this.loadResultDiffList(params)
  738. } else if (this.activeName === 'summary') {
  739. this.loadSummaryList(params)
  740. } else if (this.activeName === 'task') {
  741. this.loadTaskList(params)
  742. } else if (this.activeName === 'adjustment') {
  743. this.loadAdjustmentTransList(params)
  744. }
  745. },
  746. // 加载标签明细 - rqrq
  747. loadLabelList(params) {
  748. this.labelListLoading = true
  749. searchCountLabelList(params).then(({ data }) => {
  750. if (data && data.code === 0) {
  751. this.labelList = data.rows
  752. }
  753. }).finally(() => {
  754. this.labelListLoading = false
  755. })
  756. },
  757. // 加载栈板明细 - rqrq
  758. loadPalletList(params) {
  759. this.palletListLoading = true
  760. searchCountPalletList(params).then(({ data }) => {
  761. if (data && data.code === 0) {
  762. this.palletList = data.rows
  763. }
  764. }).finally(() => {
  765. this.palletListLoading = false
  766. })
  767. },
  768. // 加载盘点结果 - rqrq
  769. loadResultList(params) {
  770. this.resultListLoading = true
  771. searchCountResultList(params).then(({ data }) => {
  772. if (data && data.code === 0) {
  773. this.resultList = data.rows
  774. }
  775. }).finally(() => {
  776. this.resultListLoading = false
  777. })
  778. },
  779. // 加载盘点结果差异(只显示非OK的结果)- rqrq
  780. loadResultDiffList(params) {
  781. this.resultDiffListLoading = true
  782. searchCountResultList(params).then(({ data }) => {
  783. if (data && data.code === 0) {
  784. // 过滤出非OK的结果 - rqrq
  785. this.resultDiffList = (data.rows || []).filter(item => item.countResult !== 'OK')
  786. }
  787. }).finally(() => {
  788. this.resultDiffListLoading = false
  789. })
  790. },
  791. // 加载物料汇总 - rqrq
  792. loadSummaryList(params) {
  793. this.summaryListLoading = true
  794. searchMaterialSummary(params).then(({ data }) => {
  795. if (data && data.code === 0) {
  796. this.summaryList = data.rows
  797. }
  798. }).finally(() => {
  799. this.summaryListLoading = false
  800. })
  801. },
  802. // 加载任务单列表 - rqrq
  803. loadTaskList(params) {
  804. this.taskListLoading = true
  805. this.taskList = []
  806. this.taskDetailList = []
  807. this.currentTask = null
  808. searchOrderTaskByCountNo(params).then(({ data }) => {
  809. if (data && data.code === 0) {
  810. this.taskList = data.rows || []
  811. // 默认选中第一行
  812. if (this.taskList.length > 0) {
  813. this.currentTask = this.taskList[0]
  814. this.loadTaskDetailList()
  815. }
  816. }
  817. }).finally(() => {
  818. this.taskListLoading = false
  819. })
  820. },
  821. // 任务单行点击 - rqrq
  822. onTaskRowClick(row) {
  823. this.currentTask = row
  824. this.loadTaskDetailList()
  825. },
  826. // 加载任务单明细 - rqrq
  827. loadTaskDetailList() {
  828. if (!this.currentTask) {
  829. this.taskDetailList = []
  830. return
  831. }
  832. this.taskDetailListLoading = true
  833. const params = {
  834. site: this.$store.state.user.site,
  835. taskNo: this.currentTask.taskNo
  836. }
  837. searchOrderTaskDetail(params).then(({ data }) => {
  838. if (data && data.code === 0) {
  839. this.taskDetailList = data.rows || []
  840. }
  841. }).finally(() => {
  842. this.taskDetailListLoading = false
  843. })
  844. },
  845. // 加载盘盈盘亏事务记录 - rqrq
  846. loadAdjustmentTransList(params) {
  847. this.adjustmentTransLoading = true
  848. this.adjustmentTransList = []
  849. this.adjustmentTransSubList = []
  850. this.currentAdjustmentTrans = null
  851. queryAdjustmentTransList(params).then(({ data }) => {
  852. if (data && data.code === 0) {
  853. this.adjustmentTransList = data.rows || []
  854. // 默认选中第一行
  855. if (this.adjustmentTransList.length > 0) {
  856. this.currentAdjustmentTrans = this.adjustmentTransList[0]
  857. this.loadAdjustmentTransSubList()
  858. }
  859. }
  860. }).finally(() => {
  861. this.adjustmentTransLoading = false
  862. })
  863. },
  864. // 盘盈盘亏事务行点击 - rqrq
  865. onAdjustmentTransRowClick(row) {
  866. this.currentAdjustmentTrans = row
  867. this.loadAdjustmentTransSubList()
  868. },
  869. // 加载盘盈盘亏标签明细 - rqrq
  870. loadAdjustmentTransSubList() {
  871. if (!this.currentAdjustmentTrans) {
  872. this.adjustmentTransSubList = []
  873. return
  874. }
  875. this.adjustmentTransSubLoading = true
  876. const params = {
  877. site: this.$store.state.user.site,
  878. transNo: this.currentAdjustmentTrans.transNo
  879. }
  880. queryAdjustmentTransSubList(params).then(({ data }) => {
  881. if (data && data.code === 0) {
  882. this.adjustmentTransSubList = data.rows || []
  883. }
  884. }).finally(() => {
  885. this.adjustmentTransSubLoading = false
  886. })
  887. },
  888. // 分页 - rqrq
  889. sizeChangeHandle(val) {
  890. this.pageSize = val
  891. this.pageIndex = 1
  892. this.getDataList()
  893. },
  894. currentChangeHandle(val) {
  895. this.pageIndex = val
  896. this.getDataList()
  897. },
  898. // 显示循环盘点弹窗 - rqrq
  899. showCycleCountDialog() {
  900. this.cycleCountForm = {
  901. countPercent: 10,
  902. remark: ''
  903. }
  904. const params = {
  905. site: this.$store.state.user.site,
  906. }
  907. selectNowUnCountPercent(params).then(({ data }) => {
  908. if (data && data.code === 0) {
  909. this.nowPercent=data.result
  910. }
  911. })
  912. this.$nextTick(() => {
  913. this.cycleCountDialogVisible = true
  914. } )
  915. },
  916. // 创建循环盘点 - rqrq
  917. createCycleCount() {
  918. if (!this.cycleCountForm.countPercent || this.cycleCountForm.countPercent < 1 || this.cycleCountForm.countPercent > 50) {
  919. this.$message.warning('盘点比例必须在1-50之间')
  920. return
  921. }
  922. this.createLoading = true
  923. const params = {
  924. site: this.$store.state.user.site,
  925. countPercent: this.cycleCountForm.countPercent,
  926. remark: this.cycleCountForm.remark,
  927. username: this.$store.state.user.name
  928. }
  929. createCycleCount(params).then(({ data }) => {
  930. if (data && data.code === 0) {
  931. this.$message.success('创建成功,盘点单号:' + data.row.countNo)
  932. this.cycleCountDialogVisible = false
  933. this.search()
  934. } else {
  935. this.$alert(data.msg || '创建失败', '提示', { type: 'error' })
  936. }
  937. }).catch(() => {
  938. this.$alert('网络错误', '错误', { confirmButtonText: '确定' })
  939. }).finally(() => {
  940. this.createLoading = false
  941. })
  942. },
  943. // 创建手工盘点单 - rqrq
  944. handleCreateManualCount() {
  945. this.$confirm('是否创建手工盘点单?', '提示', {
  946. confirmButtonText: '确定',
  947. cancelButtonText: '取消',
  948. type: 'info'
  949. }).then(() => {
  950. this.createLoading = true
  951. const params = {
  952. site: this.$store.state.user.site,
  953. username: this.$store.state.user.name
  954. }
  955. createManualCount(params).then(({ data }) => {
  956. if (data && data.code === 0) {
  957. this.$message.success('创建成功,盘点单号:' + data.row.countNo)
  958. this.search()
  959. // 自动打开添加物料弹窗 - rqrq
  960. this.$nextTick(() => {
  961. this.handleAddMaterial(data.row)
  962. })
  963. } else {
  964. this.$alert(data.msg || '创建失败', '提示', { type: 'error' })
  965. }
  966. }).catch(() => {
  967. this.$alert('网络错误', '错误', { confirmButtonText: '确定' })
  968. }).finally(() => {
  969. this.createLoading = false
  970. })
  971. }).catch(() => {})
  972. },
  973. // 打开添加物料弹窗 - rqrq
  974. handleAddMaterial(row) {
  975. this.addMaterialRow = row
  976. this.addMaterialDialogVisible = true
  977. this.loadCurrentLabelList()
  978. },
  979. // 加载当前盘点单的标签列表 - rqrq
  980. loadCurrentLabelList() {
  981. if (!this.addMaterialRow) return
  982. this.currentLabelListLoading = true
  983. const params = {
  984. site: this.$store.state.user.site,
  985. countNo: this.addMaterialRow.countNo
  986. }
  987. searchCountLabelList(params).then(({ data }) => {
  988. if (data && data.code === 0) {
  989. this.currentLabelList = data.rows
  990. }
  991. }).finally(() => {
  992. this.currentLabelListLoading = false
  993. })
  994. },
  995. // 显示物料查询弹窗 - rqrq
  996. showMaterialQueryDialog() {
  997. this.materialQueryForm = {
  998. searchPartNo: '',
  999. searchBatchNo: '',
  1000. searchWdr: ''
  1001. }
  1002. this.materialQueryList = []
  1003. this.selectedMaterials = []
  1004. this.materialQueryDialogVisible = true
  1005. },
  1006. // 一键物料操作处理 - rqrq
  1007. handleQuickMaterialAction() {
  1008. if (!this.quickMaterialPartNo) {
  1009. this.$message.warning('请输入物料号')
  1010. return
  1011. }
  1012. if (!this.addMaterialRow) return
  1013. const partNo = this.quickMaterialPartNo.trim()
  1014. if (this.quickMaterialAction === 'add') {
  1015. // 一键添加物料 - rqrq
  1016. // this.$confirm(`确认添加物料 ${partNo} 的所有标签到盘点单?`, '提示', {
  1017. // confirmButtonText: '确定',
  1018. // cancelButtonText: '取消',
  1019. // type: 'info'
  1020. // }).then(() => {
  1021. this.quickMaterialLoading = true
  1022. const params = {
  1023. site: this.$store.state.user.site,
  1024. countNo: this.addMaterialRow.countNo,
  1025. searchPartNo: partNo,
  1026. username: this.$store.state.user.name
  1027. }
  1028. quickAddMaterialByPartNo(params).then(({ data }) => {
  1029. if (data && data.code === 0) {
  1030. this.$message.success('添加成功,新增 ' + data.result + ' 个标签')
  1031. this.quickMaterialPartNo = ''
  1032. this.loadCurrentLabelList()
  1033. this.getDataList()
  1034. this.$nextTick(() => {
  1035. setTimeout(() => {
  1036. this.$refs.part.focus();
  1037. }, 50);
  1038. });
  1039. } else {
  1040. this.$alert(data.msg || '添加失败', '提示', { type: 'error' })
  1041. }
  1042. }).catch(() => {
  1043. this.$alert('网络错误', '错误', { confirmButtonText: '确定' })
  1044. }).finally(() => {
  1045. this.quickMaterialLoading = false
  1046. })
  1047. // }).catch(() => {})
  1048. } else {
  1049. // 一键删除物料 - rqrq
  1050. // this.$confirm(`确认删除物料 ${partNo} 的所有标签?此操作不可恢复!`, '警告', {
  1051. // confirmButtonText: '确定',
  1052. // cancelButtonText: '取消',
  1053. // type: 'warning'
  1054. // }).then(() => {
  1055. this.quickMaterialLoading = true
  1056. const params = {
  1057. site: this.$store.state.user.site,
  1058. countNo: this.addMaterialRow.countNo,
  1059. searchPartNo: partNo
  1060. }
  1061. deleteMaterialByPartNo(params).then(({ data }) => {
  1062. if (data && data.code === 0) {
  1063. this.$message.success('删除成功,已删除 ' + data.result + ' 个标签')
  1064. this.quickMaterialPartNo = ''
  1065. this.loadCurrentLabelList()
  1066. this.getDataList()
  1067. this.$nextTick(() => {
  1068. setTimeout(() => {
  1069. this.$refs.part.focus();
  1070. }, 50);
  1071. });
  1072. } else {
  1073. this.$alert(data.msg || '删除失败', '提示', { type: 'error' })
  1074. }
  1075. }).catch(() => {
  1076. this.$alert('网络错误', '错误', { confirmButtonText: '确定' })
  1077. }).finally(() => {
  1078. this.quickMaterialLoading = false
  1079. })
  1080. // }).catch(() => {})
  1081. }
  1082. },
  1083. // 查询物料 - rqrq
  1084. queryMaterialForAdd() {
  1085. if (!this.materialQueryForm.searchPartNo) {
  1086. this.$message.warning('请输入物料编码')
  1087. return
  1088. }
  1089. this.materialQueryLoading = true
  1090. const params = {
  1091. site: this.$store.state.user.site,
  1092. ...this.materialQueryForm
  1093. }
  1094. queryMaterialForManualCount(params).then(({ data }) => {
  1095. if (data && data.code === 0) {
  1096. this.materialQueryList = data.rows
  1097. if (data.rows.length === 0) {
  1098. this.$message.warning('未找到符合条件的物料')
  1099. }
  1100. } else {
  1101. this.$alert(data.msg || '查询失败', '提示', { type: 'error' })
  1102. }
  1103. }).catch(() => {
  1104. this.$alert('网络错误', '错误', { confirmButtonText: '确定' })
  1105. }).finally(() => {
  1106. this.materialQueryLoading = false
  1107. })
  1108. },
  1109. // 物料选择变化 - rqrq
  1110. handleMaterialSelectionChange(selection) {
  1111. this.selectedMaterials = selection
  1112. },
  1113. // 确认添加物料 - rqrq
  1114. confirmAddMaterial() {
  1115. if (this.selectedMaterials.length === 0) {
  1116. this.$message.warning('请选择要添加的物料')
  1117. return
  1118. }
  1119. this.addMaterialLoading = true
  1120. const params = {
  1121. site: this.$store.state.user.site,
  1122. countNo: this.addMaterialRow.countNo,
  1123. selectedMaterials: this.selectedMaterials,
  1124. username: this.$store.state.user.name
  1125. }
  1126. addMaterialToCount(params).then(({ data }) => {
  1127. if (data && data.code === 0) {
  1128. this.$message.success('添加成功,新增 ' + data.result + ' 个标签')
  1129. this.materialQueryDialogVisible = false
  1130. this.loadCurrentLabelList()
  1131. this.getDataList()
  1132. } else {
  1133. this.$alert(data.msg || '添加失败', '提示', { type: 'error' })
  1134. }
  1135. }).catch(() => {
  1136. this.$alert('网络错误', '错误', { confirmButtonText: '确定' })
  1137. }).finally(() => {
  1138. this.addMaterialLoading = false
  1139. })
  1140. },
  1141. // 下达盘点单 - rqrq
  1142. handleRelease(row) {
  1143. this.$confirm('确认下达盘点单 ' + row.countNo + '?', '提示', {
  1144. confirmButtonText: '确定',
  1145. cancelButtonText: '取消',
  1146. type: 'warning'
  1147. }).then(() => {
  1148. const params = {
  1149. site: this.$store.state.user.site,
  1150. countNo: row.countNo,
  1151. username: this.$store.state.user.name
  1152. }
  1153. releaseCount(params).then(({ data }) => {
  1154. if (data && data.code === 0) {
  1155. this.$message.success('下达成功')
  1156. this.getDataList()
  1157. } else {
  1158. this.$alert(data.msg || '下达失败', '提示', { type: 'error' })
  1159. }
  1160. }).catch(() => {
  1161. this.$alert('网络错误', '错误', { confirmButtonText: '确定' })
  1162. })
  1163. }).catch(() => {})
  1164. },
  1165. // 推送盘点单到WCS - rqrq
  1166. handlePush(row) {
  1167. this.$confirm('确认推送盘点单 ' + row.countNo + ' 到WCS?将开始出库前10个栈板。', '提示', {
  1168. confirmButtonText: '确定',
  1169. cancelButtonText: '取消',
  1170. type: 'warning'
  1171. }).then(() => {
  1172. const params = {
  1173. site: this.$store.state.user.site,
  1174. countNo: row.countNo,
  1175. username: this.$store.state.user.name
  1176. }
  1177. pushCountToWcs(params).then(({ data }) => {
  1178. if (data && data.code === 0) {
  1179. this.$message.success('推送成功,本次推送栈板数: ' + data.result)
  1180. this.getDataList()
  1181. } else {
  1182. this.$alert(data.msg || '推送失败', '提示', { type: 'error' })
  1183. }
  1184. }).catch(() => {
  1185. this.$alert('网络错误', '错误', { confirmButtonText: '确定' })
  1186. })
  1187. }).catch(() => {})
  1188. },
  1189. // 完成盘点单 - rqrq
  1190. handleComplete(row) {
  1191. this.$confirm('确认完成盘点单 ' + row.countNo + '?', '提示', {
  1192. confirmButtonText: '确定',
  1193. cancelButtonText: '取消',
  1194. type: 'warning'
  1195. }).then(() => {
  1196. const params = {
  1197. site: this.$store.state.user.site,
  1198. countNo: row.countNo,
  1199. username: this.$store.state.user.name
  1200. }
  1201. completeCount(params).then(({ data }) => {
  1202. if (data && data.code === 0) {
  1203. this.$message.success('操作成功')
  1204. this.getDataList()
  1205. } else {
  1206. this.$alert(data.msg || '操作失败', '提示', { type: 'error' })
  1207. }
  1208. }).catch(() => {
  1209. this.$alert('网络错误', '错误', { confirmButtonText: '确定' })
  1210. })
  1211. }).catch(() => {})
  1212. },
  1213. // 取消盘点单 - rqrq
  1214. handleCancel(row) {
  1215. this.$confirm('确认取消盘点单 ' + row.countNo + '?', '提示', {
  1216. confirmButtonText: '确定',
  1217. cancelButtonText: '取消',
  1218. type: 'warning'
  1219. }).then(() => {
  1220. const params = {
  1221. site: this.$store.state.user.site,
  1222. countNo: row.countNo,
  1223. username: this.$store.state.user.name
  1224. }
  1225. cancelCount(params).then(({ data }) => {
  1226. if (data && data.code === 0) {
  1227. this.$message.success('取消成功')
  1228. this.getDataList()
  1229. } else {
  1230. this.$alert(data.msg || '取消失败', '提示', { type: 'error' })
  1231. }
  1232. }).catch(() => {
  1233. this.$alert('网络错误', '错误', { confirmButtonText: '确定' })
  1234. })
  1235. }).catch(() => {})
  1236. },
  1237. // 删除盘点单 - rqrq
  1238. handleDelete(row) {
  1239. this.$confirm('确认删除盘点单 ' + row.countNo + '?删除后不可恢复!', '警告', {
  1240. confirmButtonText: '确定',
  1241. cancelButtonText: '取消',
  1242. type: 'warning'
  1243. }).then(() => {
  1244. const params = {
  1245. site: this.$store.state.user.site,
  1246. countNo: row.countNo
  1247. }
  1248. deleteCount(params).then(({ data }) => {
  1249. if (data && data.code === 0) {
  1250. this.$message.success('删除成功')
  1251. this.getDataList()
  1252. } else {
  1253. this.$alert(data.msg || '删除失败', '提示', { type: 'error' })
  1254. }
  1255. }).catch(() => {
  1256. this.$alert('网络错误', '错误', { confirmButtonText: '确定' })
  1257. })
  1258. }).catch(() => {})
  1259. },
  1260. // 格式化日期时间 - rqrq
  1261. formatDateTime(dateTime) {
  1262. if (!dateTime) return ''
  1263. const date = new Date(dateTime)
  1264. const year = date.getFullYear()
  1265. const month = String(date.getMonth() + 1).padStart(2, '0')
  1266. const day = String(date.getDate()).padStart(2, '0')
  1267. const hours = String(date.getHours()).padStart(2, '0')
  1268. const minutes = String(date.getMinutes()).padStart(2, '0')
  1269. return `${year}-${month}-${day} ${hours}:${minutes}`
  1270. },
  1271. // 获取状态颜色 - rqrq
  1272. getStatusColor(status) {
  1273. const colorMap = {
  1274. 'DRAFT': '#909399',
  1275. 'RELEASED': '#409EFF',
  1276. 'CHECKING': '#E6A23C',
  1277. 'COMPLETED': '#67C23A',
  1278. 'CANCELLED': '#F56C6C'
  1279. }
  1280. return colorMap[status] || '#909399'
  1281. },
  1282. // 获取盘点结果颜色 - rqrq
  1283. getResultColor(result) {
  1284. const colorMap = {
  1285. 'OK': '#67C23A',
  1286. 'MISSING': '#F56C6C',
  1287. 'SURPLUS': '#E6A23C',
  1288. 'QTY_DIFF': '#F56C6C'
  1289. }
  1290. return colorMap[result] || '#909399'
  1291. },
  1292. // ==================== 导出功能 ==================== - rqrq
  1293. /**
  1294. * 前端导出Excel方式一使用xlsx库在前端生成- rqrq
  1295. * @param row 当前行数据
  1296. */
  1297. async handleExportFrontend(row) {
  1298. if (this.exportLoading) return
  1299. this.exportLoading = true
  1300. this.$message.success('正在导出数据,请稍候...')
  1301. try {
  1302. const site = this.$store.state.user.site
  1303. const countNo = row.countNo
  1304. const params = { site, countNo }
  1305. // 并行获取所有数据 - rqrq
  1306. const [labelRes, summaryRes, palletRes, resultRes, adjustmentRes] = await Promise.all([
  1307. searchCountLabelList(params),
  1308. searchMaterialSummary(params),
  1309. searchCountPalletList(params),
  1310. searchCountResultList(params),
  1311. queryAdjustmentTransList(params)
  1312. ])
  1313. const labelList = (labelRes.data && labelRes.data.code === 0) ? labelRes.data.rows || [] : []
  1314. const summaryList = (summaryRes.data && summaryRes.data.code === 0) ? summaryRes.data.rows || [] : []
  1315. const palletList = (palletRes.data && palletRes.data.code === 0) ? palletRes.data.rows || [] : []
  1316. const resultList = (resultRes.data && resultRes.data.code === 0) ? resultRes.data.rows || [] : []
  1317. const resultDiffList = resultList.filter(item => item.countResult !== 'OK')
  1318. const adjustmentList = (adjustmentRes.data && adjustmentRes.data.code === 0) ? adjustmentRes.data.rows || [] : []
  1319. // 创建工作簿 - rqrq
  1320. const wb = XLSX.utils.book_new()
  1321. // Sheet1: 标签明细 - rqrq
  1322. const labelData = labelList.map(item => ({
  1323. '标签号': item.unitId,
  1324. '物料号': item.partNo,
  1325. '物料描述': item.partDesc,
  1326. '数量': item.qty,
  1327. '批号': item.batchNo,
  1328. '栈板号': item.palletId,
  1329. '所在层数': item.locationZ,
  1330. '标签类型': item.labelTypeDesc,
  1331. '盘点状态': item.countFlagDesc,
  1332. '盘点人': item.countUser,
  1333. '盘点时间': this.formatDateTime(item.countDate),
  1334. '仓库': item.warehouseName,
  1335. '库位': item.locationName
  1336. }))
  1337. const ws1 = XLSX.utils.json_to_sheet(labelData)
  1338. XLSX.utils.book_append_sheet(wb, ws1, '标签明细')
  1339. // Sheet2: 物料汇总 - rqrq
  1340. const summaryData = summaryList.map(item => ({
  1341. '物料号': item.partNo,
  1342. '物料描述': item.partDesc,
  1343. '批号': item.batchNo,
  1344. 'WDR号': item.wdr,
  1345. '仓库': item.warehouseName,
  1346. '库位': item.locationName,
  1347. '标签数': item.labelCount,
  1348. '总数量': item.totalQty,
  1349. '栈板数': item.palletCount,
  1350. '已盘点': item.checkedLabelCount,
  1351. '进度': item.progressPercent
  1352. }))
  1353. const ws2 = XLSX.utils.json_to_sheet(summaryData)
  1354. XLSX.utils.book_append_sheet(wb, ws2, '物料汇总')
  1355. // Sheet3: 栈板明细 - rqrq
  1356. const palletData = palletList.map(item => ({
  1357. '序号': item.seqNo,
  1358. '栈板号': item.palletId,
  1359. '标签数': item.labelCount,
  1360. '已盘点': item.checkedCount,
  1361. '进度': item.progressPercent,
  1362. '盘点状态': item.countFlagDesc,
  1363. '站点区域': item.stationArea,
  1364. '站点ID': item.stationId,
  1365. '所在层数': item.locationZ,
  1366. '盘点人': item.countUser,
  1367. '盘点时间': this.formatDateTime(item.countDate)
  1368. }))
  1369. const ws3 = XLSX.utils.json_to_sheet(palletData)
  1370. XLSX.utils.book_append_sheet(wb, ws3, '栈板明细')
  1371. // Sheet4: 盘点结果 - rqrq
  1372. const resultData = resultList.map(item => ({
  1373. '标签号': item.unitId,
  1374. '物料号': item.partNo,
  1375. '物料描述': item.partDesc,
  1376. '数量': item.qty,
  1377. '差异数量': item.diffQty,
  1378. '批号': item.batchNo,
  1379. '栈板号': item.palletId,
  1380. '盘点结果': item.countResultDesc,
  1381. '处理方式': item.handleTypeDesc,
  1382. '盘点人': item.countUser,
  1383. '盘点时间': this.formatDateTime(item.countDate),
  1384. '备注': item.remark
  1385. }))
  1386. const ws4 = XLSX.utils.json_to_sheet(resultData)
  1387. XLSX.utils.book_append_sheet(wb, ws4, '盘点结果')
  1388. // Sheet5: 盘点结果差异 - rqrq
  1389. const resultDiffData = resultDiffList.map(item => ({
  1390. '标签号': item.unitId,
  1391. '物料号': item.partNo,
  1392. '物料描述': item.partDesc,
  1393. '数量': item.qty,
  1394. '差异数量': item.diffQty,
  1395. '批号': item.batchNo,
  1396. '栈板号': item.palletId,
  1397. '盘点结果': item.countResultDesc,
  1398. '是否处理': item.handleFlagDesc,
  1399. '处理方式': item.handleTypeDesc,
  1400. '盘点人': item.countUser,
  1401. '盘点时间': this.formatDateTime(item.countDate),
  1402. '备注': item.remark
  1403. }))
  1404. const ws5 = XLSX.utils.json_to_sheet(resultDiffData)
  1405. XLSX.utils.book_append_sheet(wb, ws5, '盘点结果差异')
  1406. // Sheet6: 盘盈盘亏明细 - rqrq
  1407. const adjustmentData = adjustmentList.map(item => ({
  1408. '单据号': item.transNo,
  1409. '事务类型': item.transTypeDesc,
  1410. '行号': item.itemNo,
  1411. '物料号': item.partNo,
  1412. '数量': item.transQty,
  1413. '批号': item.batchNo,
  1414. '库位': item.locationId,
  1415. '方向': item.directionDesc,
  1416. '仓库': item.warehouseId,
  1417. '操作人': item.userName
  1418. }))
  1419. const ws6 = XLSX.utils.json_to_sheet(adjustmentData)
  1420. XLSX.utils.book_append_sheet(wb, ws6, '盘盈盘亏明细')
  1421. // 导出文件 - rqrq
  1422. const fileName = `盘点数据_${countNo}_${this.dayjs().format('YYYYMMDDHHmmss')}.xlsx`
  1423. XLSX.writeFile(wb, fileName)
  1424. this.$message.success('导出成功')
  1425. } catch (error) {
  1426. console.error('导出失败:', error)
  1427. this.$alert('导出失败:' + (error.message || error), '错误', { confirmButtonText: '确定' })
  1428. } finally {
  1429. this.exportLoading = false
  1430. }
  1431. },
  1432. /**
  1433. * 后端导出Excel方式二后端生成Excel文件下载- rqrq
  1434. * @param row 当前行数据
  1435. */
  1436. handleExportBackend(row) {
  1437. if (this.exportLoading) return
  1438. this.exportLoading = true
  1439. this.$message.success('正在导出数据,请稍候...')
  1440. const params = {
  1441. site: this.$store.state.user.site,
  1442. countNo: row.countNo
  1443. }
  1444. exportCountDataExcel(params).then(response => {
  1445. // 从响应中获取blob数据 - rqrq
  1446. const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
  1447. const fileName = `盘点数据_${row.countNo}_${this.dayjs().format('YYYYMMDDHHmmss')}.xlsx`
  1448. // 创建下载链接 - rqrq
  1449. const link = document.createElement('a')
  1450. link.href = window.URL.createObjectURL(blob)
  1451. link.download = fileName
  1452. link.click()
  1453. window.URL.revokeObjectURL(link.href)
  1454. this.$message.success('导出成功')
  1455. }).catch(error => {
  1456. console.error('导出失败:', error)
  1457. this.$alert('导出失败:' + (error.message || error), '错误', { confirmButtonText: '确定' })
  1458. }).finally(() => {
  1459. this.exportLoading = false
  1460. })
  1461. }
  1462. }
  1463. }
  1464. </script>
  1465. <style scoped>
  1466. /deep/ .el-table a {
  1467. color: #409EFF;
  1468. cursor: pointer;
  1469. }
  1470. /deep/ .el-table a:hover {
  1471. text-decoration: underline;
  1472. }
  1473. /* 盘点模式面板样式 - rqrq */
  1474. .count-mode-panel {
  1475. padding: 12px 20px;
  1476. border-radius: 6px;
  1477. margin-bottom: 15px;
  1478. display: flex;
  1479. align-items: center;
  1480. transition: all 0.3s ease;
  1481. }
  1482. .count-mode-panel.count-mode-on {
  1483. background: linear-gradient(135deg, #e8f5e9 0%, #c8e6c9 100%);
  1484. border: 2px solid #67C23A;
  1485. box-shadow: 0 2px 8px rgba(103, 194, 58, 0.2);
  1486. }
  1487. .count-mode-panel.count-mode-off {
  1488. background: linear-gradient(135deg, #fff3e0 0%, #ffe0b2 100%);
  1489. border: 2px solid #E6A23C;
  1490. box-shadow: 0 2px 8px rgba(230, 162, 60, 0.2);
  1491. }
  1492. .count-mode-content {
  1493. display: flex;
  1494. align-items: center;
  1495. width: 100%;
  1496. }
  1497. .count-mode-icon {
  1498. font-size: 24px;
  1499. margin-right: 10px;
  1500. }
  1501. .count-mode-on .count-mode-icon {
  1502. color: #67C23A;
  1503. }
  1504. .count-mode-off .count-mode-icon {
  1505. color: #E6A23C;
  1506. }
  1507. .count-mode-label {
  1508. font-size: 16px;
  1509. font-weight: bold;
  1510. color: #303133;
  1511. }
  1512. .count-mode-value {
  1513. font-size: 16px;
  1514. font-weight: bold;
  1515. margin-left: 5px;
  1516. }
  1517. .count-mode-on .count-mode-value {
  1518. color: #67C23A;
  1519. }
  1520. .count-mode-off .count-mode-value {
  1521. color: #E6A23C;
  1522. }
  1523. .count-mode-tip {
  1524. font-size: 12px;
  1525. color: #909399;
  1526. margin-left: 15px;
  1527. }
  1528. </style>