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.

445 lines
11 KiB

  1. <template>
  2. <div class="customer-css">
  3. <!-- 操作按钮 -->
  4. <el-form :inline="true" style="margin-bottom: 2px;">
  5. <el-button type="primary" icon="el-icon-plus" size="mini" @click="showSelectPoDialog" :disabled="!supplierNo">选择PO</el-button>
  6. </el-form>
  7. <!-- 已关联PO列表表格 -->
  8. <el-table
  9. :data="issuePoList"
  10. border
  11. v-loading="loading"
  12. style="width: 100%;"
  13. :height="tableHeight"
  14. :header-cell-style="{ textAlign: 'center' }">
  15. <el-table-column
  16. prop="poNo"
  17. label="PO"
  18. width="180"
  19. align="center"/>
  20. <el-table-column
  21. prop="poDate"
  22. label="PO Date"
  23. width="180"
  24. align="center"/>
  25. <el-table-column
  26. prop="sku"
  27. label="SKU"
  28. min-width="250"
  29. show-overflow-tooltip/>
  30. <el-table-column
  31. prop="poQty"
  32. label="Qty"
  33. width="120"
  34. align="right"/>
  35. <el-table-column
  36. prop="shippedQty"
  37. label="Qty Shipped"
  38. width="110"
  39. align="right"/>
  40. <el-table-column
  41. label="操作"
  42. width="80"
  43. align="center"
  44. fixed="right">
  45. <template slot-scope="scope">
  46. <el-link type="danger" @click="handleDeletePo(scope.row)">删除</el-link>
  47. </template>
  48. </el-table-column>
  49. </el-table>
  50. <!-- 选择PO对话框 -->
  51. <el-dialog
  52. title="选择PO"
  53. :visible.sync="selectPoDialogVisible"
  54. width="50%"
  55. top="10vh"
  56. :close-on-click-modal="false"
  57. append-to-body>
  58. <!-- 查询条件 -->
  59. <el-form :inline="true" label-position="top" class="search-form-inline">
  60. <div class="search-row">
  61. <el-form-item label="PO" class="search-item">
  62. <el-input
  63. v-model="poSearchData.poNo"
  64. placeholder="PO号"
  65. style="width:120px"
  66. @keyup.enter.native="loadAvailablePoList"/>
  67. </el-form-item>
  68. <el-form-item label="Part No" class="search-item">
  69. <el-input
  70. v-model="poSearchData.partNo"
  71. placeholder="料号"
  72. style="width:120px"
  73. @keyup.enter.native="loadAvailablePoList"/>
  74. </el-form-item>
  75. <el-form-item label="开始日期" class="search-item">
  76. <el-date-picker
  77. v-model="poSearchData.beginDate"
  78. type="date"
  79. value-format="yyyy-MM-dd"
  80. placeholder="开始日期"
  81. style="width:120px"
  82. clearable>
  83. </el-date-picker>
  84. </el-form-item>
  85. <el-form-item label="结束日期" class="search-item">
  86. <el-date-picker
  87. v-model="poSearchData.endDate"
  88. type="date"
  89. value-format="yyyy-MM-dd"
  90. placeholder="结束日期"
  91. style="width:120px"
  92. clearable>
  93. </el-date-picker>
  94. </el-form-item>
  95. <el-form-item label=" " class="search-item search-btn-item">
  96. <el-button
  97. type="primary"
  98. size="small"
  99. @click="loadAvailablePoList">
  100. 查询
  101. </el-button>
  102. </el-form-item>
  103. </div>
  104. </el-form>
  105. <!-- 可用PO列表 -->
  106. <el-table
  107. ref="availablePoTable"
  108. :data="availablePoList"
  109. border
  110. size="mini"
  111. style="width: 100%; margin-top: 10px;"
  112. height="300"
  113. @selection-change="handleSelectionChange"
  114. :header-cell-style="{ textAlign: 'center' }">
  115. <el-table-column type="selection" width="50" />
  116. <el-table-column prop="poNo" label="PO" width="120" />
  117. <el-table-column prop="poDate" label="PO Date" width="160" />
  118. <el-table-column prop="sku" label="SKU" />
  119. <el-table-column prop="qty" label="Qty" width="100" align="right" />
  120. <el-table-column prop="shippedQty" label="Qty Shipped" width="120" align="right" />
  121. </el-table>
  122. <span slot="footer" class="dialog-footer">
  123. <el-button type="primary" :loading="saveLoading" @click="handleSavePo">保存</el-button>
  124. <el-button @click="selectPoDialogVisible = false">关闭</el-button>
  125. </span>
  126. </el-dialog>
  127. </div>
  128. </template>
  129. <script>
  130. import { getIssuePoList, getAvailablePoList, saveIssuePo, deleteIssuePo } from '@/api/quality/qualityIssue.js'
  131. export default {
  132. name: 'QualityIssuePoList',
  133. props: {
  134. issueNo: {
  135. type: String,
  136. default: ''
  137. },
  138. site: {
  139. type: String,
  140. default: ''
  141. },
  142. supplierNo: {
  143. type: String,
  144. default: ''
  145. },
  146. tableHeight: {
  147. type: Number,
  148. default: 400
  149. }
  150. },
  151. data() {
  152. return {
  153. issuePoList: [],
  154. loading: false,
  155. saveLoading: false,
  156. selectPoDialogVisible: false,
  157. availablePoList: [],
  158. selectedPoRows: [],
  159. poSearchData: {
  160. poNo: '',
  161. partNo: '',
  162. beginDate: '',
  163. endDate: ''
  164. }
  165. }
  166. },
  167. watch: {
  168. issueNo: {
  169. immediate: true,
  170. handler(newVal) {
  171. if (newVal) {
  172. this.loadIssuePoList()
  173. } else {
  174. this.issuePoList = []
  175. }
  176. }
  177. }
  178. },
  179. mounted() {
  180. // 组件加载时默认执行一次查询
  181. if (this.issueNo) {
  182. this.loadIssuePoList()
  183. }
  184. },
  185. methods: {
  186. // 供父组件调用的加载数据方法
  187. loadData() {
  188. this.loadIssuePoList()
  189. },
  190. // 加载已关联的PO列表
  191. loadIssuePoList() {
  192. if (!this.issueNo) {
  193. this.issuePoList = []
  194. return
  195. }
  196. this.loading = true
  197. getIssuePoList({
  198. site: this.site,
  199. issueNo: this.issueNo
  200. }).then(({ data }) => {
  201. if (data.code === 0) {
  202. this.issuePoList = data.data || []
  203. } else {
  204. this.issuePoList = []
  205. }
  206. this.loading = false
  207. }).catch(error => {
  208. console.error('加载PO列表失败:', error)
  209. this.loading = false
  210. })
  211. },
  212. // 显示选择PO对话框
  213. showSelectPoDialog() {
  214. if (!this.supplierNo) {
  215. this.$message.warning('请先选择有供应商的质量问题记录')
  216. return
  217. }
  218. this.selectPoDialogVisible = true
  219. // 重置搜索条件
  220. this.poSearchData = {
  221. poNo: '',
  222. partNo: '',
  223. beginDate: '',
  224. endDate: ''
  225. }
  226. this.loadAvailablePoList()
  227. },
  228. // 加载可用PO列表
  229. loadAvailablePoList() {
  230. const params = {
  231. site: this.site,
  232. supplierNo: this.supplierNo,
  233. poNo: this.poSearchData.poNo || undefined,
  234. partNo: this.poSearchData.partNo || undefined,
  235. beginDate: this.poSearchData.beginDate || undefined,
  236. endDate: this.poSearchData.endDate || undefined
  237. }
  238. getAvailablePoList(params).then(({ data }) => {
  239. if (data.code === 0) {
  240. this.availablePoList = (data.page && data.page.list) || []
  241. this.$nextTick(() => {
  242. if (this.$refs.availablePoTable) {
  243. this.$refs.availablePoTable.clearSelection()
  244. }
  245. })
  246. } else {
  247. this.availablePoList = []
  248. }
  249. }).catch(error => {
  250. console.error('加载可用PO列表失败:', error)
  251. this.availablePoList = []
  252. })
  253. },
  254. // 选择行变化
  255. handleSelectionChange(selection) {
  256. this.selectedPoRows = selection
  257. },
  258. // 保存选中的PO
  259. handleSavePo() {
  260. if (this.selectedPoRows.length === 0) {
  261. this.$message.warning('请至少选择一条PO记录')
  262. return
  263. }
  264. // 检查 site 和 issueNo 是否有效
  265. if (!this.site || !this.issueNo) {
  266. this.$message.error('缺少必要参数:site或issueNo为空')
  267. console.error('保存失败:site=', this.site, 'issueNo=', this.issueNo)
  268. return
  269. }
  270. const poList = this.selectedPoRows.map(row => ({
  271. poNo: row.poNo,
  272. itemNo: row.itemNo,
  273. partNo: row.partNo,
  274. sku: row.sku,
  275. qty: row.qty,
  276. shippedQty: row.shippedQty
  277. }))
  278. const params = {
  279. site: this.site,
  280. issueNo: this.issueNo,
  281. poList: poList
  282. }
  283. console.log('保存PO数据:', params)
  284. this.saveLoading = true
  285. saveIssuePo(params).then(({ data }) => {
  286. if (data.code === 0) {
  287. this.$message.success('保存成功')
  288. this.selectPoDialogVisible = false
  289. this.loadIssuePoList()
  290. } else {
  291. this.$message.error(data.msg || '保存失败')
  292. }
  293. this.saveLoading = false
  294. }).catch(error => {
  295. console.error('保存PO失败:', error)
  296. this.$message.error('保存失败,请稍后重试')
  297. this.saveLoading = false
  298. })
  299. },
  300. // 删除PO
  301. handleDeletePo(row) {
  302. this.$confirm('确定要删除该PO吗?', '提示', {
  303. confirmButtonText: '确定',
  304. cancelButtonText: '取消',
  305. type: 'warning'
  306. }).then(() => {
  307. const params = {
  308. site: this.site,
  309. issueNo: this.issueNo,
  310. poNo: row.poNo,
  311. itemNo: row.itemNo
  312. }
  313. deleteIssuePo(params).then(({ data }) => {
  314. if (data.code === 0) {
  315. this.$message.success('删除成功')
  316. this.loadIssuePoList()
  317. } else {
  318. this.$message.error(data.msg || '删除失败')
  319. }
  320. }).catch(error => {
  321. console.error('删除PO失败:', error)
  322. this.$message.error('删除失败,请稍后重试')
  323. })
  324. }).catch(() => {})
  325. }
  326. }
  327. }
  328. </script>
  329. <style scoped lang="scss">
  330. .customer-css {
  331. padding: 0;
  332. margin: 0;
  333. background: #fff;
  334. height: 100%;
  335. }
  336. .search-form-inline {
  337. background: #fff;
  338. padding: 0;
  339. margin-bottom: 10px;
  340. }
  341. .search-row {
  342. display: flex;
  343. align-items: flex-end;
  344. flex-wrap: wrap;
  345. gap: 0;
  346. }
  347. .search-item {
  348. flex: none;
  349. margin-bottom: 0;
  350. margin-right: 12px;
  351. }
  352. .search-item /deep/ .el-form-item__label {
  353. padding-bottom: 5px;
  354. line-height: 1;
  355. height: auto;
  356. }
  357. .search-item /deep/ .el-form-item__content {
  358. line-height: normal;
  359. }
  360. .search-btn-item {
  361. margin-right: 0;
  362. }
  363. .date-range {
  364. display: flex;
  365. align-items: center;
  366. }
  367. .split {
  368. padding: 0 6px;
  369. color: #606266;
  370. font-size: 13px;
  371. }
  372. .dialog-footer {
  373. text-align: center;
  374. }
  375. // 表格样式统一 - 表头背景色改为青绿色
  376. /deep/ .el-table {
  377. font-size: 12px;
  378. }
  379. /deep/ .el-table th {
  380. background-color: #17B3A3;
  381. color: #fff;
  382. font-weight: 500;
  383. text-align: center;
  384. }
  385. /deep/ .el-table tr {
  386. background-color: #fff;
  387. }
  388. /deep/ .el-table--enable-row-hover .el-table__body tr:hover > td {
  389. background-color: #f5f7fa;
  390. }
  391. /deep/ .el-link {
  392. font-size: 12px;
  393. }
  394. </style>