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.

1822 lines
59 KiB

  1. <template>
  2. <div class="customer-css">
  3. <!-- 查询条件 -->
  4. <el-form :inline="true" label-position="top" class="search-form-inline">
  5. <div class="search-row">
  6. <el-form-item label="供应商编码" class="search-item">
  7. <el-input v-model="searchData.supplierNo" style="width: 120px" @keyup.enter.native="getMainData"/>
  8. </el-form-item>
  9. <el-form-item label="供应商名称" class="search-item">
  10. <el-input v-model="searchData.supplierName" style="width: 200px" @keyup.enter.native="getMainData"/>
  11. </el-form-item>
  12. <el-form-item label="反馈单号" class="search-item">
  13. <el-input v-model="searchData.issueNo" style="width: 120px" @keyup.enter.native="getMainData"/>
  14. </el-form-item>
  15. <el-form-item label="问题日期" class="search-item">
  16. <el-date-picker
  17. v-model="searchData.issueDate"
  18. type="date"
  19. value-format="yyyy-MM-dd"
  20. placeholder="选择日期"
  21. style="width: 150px"
  22. clearable>
  23. </el-date-picker>
  24. </el-form-item>
  25. <el-form-item label="状态" class="search-item">
  26. <el-select v-model="searchData.statusDb" clearable placeholder="全部" style="width: 100%">
  27. <el-option label="全部" value="" />
  28. <el-option label="已确认" value="Confirmed" />
  29. <el-option label="已分析" value="Analyzed" />
  30. <el-option label="已关闭" value="Closed" />
  31. <el-option label="已取消" value="Cancelled" />
  32. </el-select>
  33. </el-form-item>
  34. </div>
  35. <div class="search-row">
  36. <el-form-item label=" " class="search-item search-btn-item">
  37. <el-button type="primary" @click="getMainData" class="customer-bun-min">查询</el-button>
  38. <el-button type="primary" @click="addQualityIssue" class="customer-bun-min">新增</el-button>
  39. <el-button type="primary" @click="exportExcel" class="customer-bun-min">导出</el-button>
  40. </el-form-item>
  41. </div>
  42. </el-form>
  43. <el-table
  44. :height="height"
  45. :data="mainDataList"
  46. border
  47. ref="mainTable"
  48. highlight-current-row
  49. @row-click="changeData"
  50. v-loading="dataListLoading"
  51. style="margin-top: 0px; width: 100%;">
  52. <el-table-column
  53. v-for="(item,index) in columnArray1" :key="index"
  54. :sortable="item.columnSortable"
  55. :prop="item.columnProp"
  56. :header-align="item.headerAlign"
  57. :show-overflow-tooltip="item.showOverflowTooltip"
  58. :align="item.align"
  59. :fixed="item.fixed==''?false:item.fixed"
  60. :min-width="item.columnWidth"
  61. :label="item.columnLabel">
  62. <template slot-scope="scope">
  63. <span v-if="!item.columnHidden">{{ scope.row[item.columnProp] }}</span>
  64. <span v-if="item.columnImage"><img :src="scope.row[item.columnProp]"
  65. style="width: 100px; height: 100px"/></span>
  66. </template>
  67. </el-table-column>
  68. <el-table-column fixed="right" header-align="center" align="center" width="240" label="操作">
  69. <template slot-scope="scope">
  70. <!-- 编辑 -->
  71. <a v-if="scope.row.status === '已确认'"
  72. class="customer-a"
  73. @click="editQualityIssue(scope.row)">编辑 </a>
  74. <!-- 删除 -->
  75. <a v-if="scope.row.status === '已确认'"
  76. class="customer-a"
  77. @click="deleteQualityIssue(scope.row)">删除 </a>
  78. <!-- 回复 -->
  79. <a v-if="scope.row.status === '已确认'"
  80. class="customer-a"
  81. @click="replyQualityIssue(scope.row)">回复 </a>
  82. <!-- 赔偿 -->
  83. <a v-if="['已确认','已分析'].includes(scope.row.status)"
  84. class="customer-a"
  85. @click="compensationQualityIssue(scope.row)">赔偿 </a>
  86. <!-- 关闭 -->
  87. <a v-if="scope.row.status === '已分析'"
  88. class="customer-a"
  89. @click="closeQualityIssueAction(scope.row)">关闭</a>
  90. </template>
  91. </el-table-column>
  92. </el-table>
  93. <!-- 分页插件 -->
  94. <el-pagination style="margin-top: 0px"
  95. @size-change="sizeChangeHandle"
  96. @current-change="currentChangeHandle"
  97. :current-page="pageIndex"
  98. :page-sizes="[20, 50, 100, 200, 500]"
  99. :page-size="pageSize"
  100. :total="totalPage"
  101. layout="total, sizes, prev, pager, next, jumper">
  102. </el-pagination>
  103. <!-- 详情页签 -->
  104. <el-tabs v-model="activeTab" style="margin-top: 0px; width: 99%;" @tab-click="handleTabClick" class="customer-tab" type="border-card">
  105. <!-- 详情 -->
  106. <el-tab-pane label="详情" name="detail">
  107. <quality-issue-detail :detail-data="currentRow" />
  108. </el-tab-pane>
  109. <!-- 附件 -->
  110. <el-tab-pane label="附件" name="attachment">
  111. <quality-issue-attachment :detail-data="currentRow" :table-height="detailHeight" />
  112. </el-tab-pane>
  113. </el-tabs>
  114. <!-- 新增弹窗 -->
  115. <el-dialog
  116. title="质量问题 - 新增"
  117. :visible.sync="addDialogVisible"
  118. width="70%"
  119. top="5vh"
  120. :close-on-click-modal="false"
  121. @close="handleCloseAddDialog">
  122. <el-form :model="addFormData" :rules="addRules" ref="addFormData" label-width="110px" size="mini" class="add-dialog-form">
  123. <!-- 第一行 -->
  124. <el-row :gutter="10">
  125. <el-col :span="6">
  126. <el-form-item label="反馈单号">
  127. <el-input v-model="addFormData.issueNo" placeholder="自动生成" disabled size="mini"></el-input>
  128. </el-form-item>
  129. </el-col>
  130. <el-col :span="6">
  131. <el-form-item label="问题日期" prop="issueDate">
  132. <el-date-picker
  133. v-model="addFormData.issueDate"
  134. type="date"
  135. value-format="yyyy-MM-dd"
  136. placeholder="选择日期"
  137. size="mini"
  138. style="width: 100%">
  139. </el-date-picker>
  140. </el-form-item>
  141. </el-col>
  142. <el-col :span="6">
  143. <el-form-item label="要求回复日期" prop="requireReplyDate">
  144. <el-date-picker
  145. v-model="addFormData.requireReplyDate"
  146. type="date"
  147. value-format="yyyy-MM-dd"
  148. placeholder="选择日期"
  149. size="mini"
  150. style="width: 100%">
  151. </el-date-picker>
  152. </el-form-item>
  153. </el-col>
  154. <el-col :span="6">
  155. <el-form-item label="状态">
  156. <el-input v-model="addFormData.status" value="已确认" disabled size="mini"></el-input>
  157. </el-form-item>
  158. </el-col>
  159. </el-row>
  160. <!-- 新增行PO No批次数量拒收批次数量投诉接收日期样品接收日期 -->
  161. <el-row :gutter="10">
  162. <el-col :span="6">
  163. <el-form-item label="PO No">
  164. <el-input v-model="addFormData.poNo" placeholder="请输入" size="mini"></el-input>
  165. </el-form-item>
  166. </el-col>
  167. <el-col :span="6">
  168. <el-form-item label="批次数量">
  169. <el-input v-model="addFormData.batchQty" placeholder="请输入" size="mini" type="number"></el-input>
  170. </el-form-item>
  171. </el-col>
  172. <el-col :span="6">
  173. <el-form-item label="拒收批次数量">
  174. <el-input v-model="addFormData.rejectBatchQty" placeholder="请输入" size="mini" type="number"></el-input>
  175. </el-form-item>
  176. </el-col>
  177. <el-col :span="6">
  178. <el-form-item label="投诉接收日期">
  179. <el-date-picker
  180. v-model="addFormData.receiveComplaintDate"
  181. type="date"
  182. value-format="yyyy-MM-dd"
  183. placeholder="选择日期"
  184. size="mini"
  185. style="width: 100%">
  186. </el-date-picker>
  187. </el-form-item>
  188. </el-col>
  189. </el-row>
  190. <el-row :gutter="10">
  191. <el-col :span="6">
  192. <el-form-item label="样品接收日期">
  193. <el-date-picker
  194. v-model="addFormData.receiveSampleDate"
  195. type="date"
  196. value-format="yyyy-MM-dd"
  197. placeholder="选择日期"
  198. size="mini"
  199. style="width: 100%">
  200. </el-date-picker>
  201. </el-form-item>
  202. </el-col>
  203. </el-row>
  204. <!-- 第二行 -->
  205. <el-row :gutter="10">
  206. <el-col :span="6">
  207. <el-form-item label="供应商编码" prop="supplierNo">
  208. <el-input v-model="addFormData.supplierNo" placeholder="请选择" readonly @click.native="selectSupplier" size="mini">
  209. <i slot="suffix" class="el-icon-search" style="cursor: pointer;"></i>
  210. </el-input>
  211. </el-form-item>
  212. </el-col>
  213. <el-col :span="12">
  214. <el-form-item label="供应商名称">
  215. <el-input v-model="addFormData.supplierName" disabled size="mini"></el-input>
  216. </el-form-item>
  217. </el-col>
  218. <el-col :span="6">
  219. <el-form-item label="供应商负责人">
  220. <el-input v-model="addFormData.supplierResponsible" placeholder="请输入" size="mini"></el-input>
  221. </el-form-item>
  222. </el-col>
  223. </el-row>
  224. <!-- 第三行 -->
  225. <el-row :gutter="10">
  226. <el-col :span="6">
  227. <el-form-item label="Plant">
  228. <el-select v-model="addFormData.plant" placeholder="请选择" size="mini" style="width: 100%">
  229. <el-option label="Mx : Mexico" value="Mx"></el-option>
  230. <el-option label="IR : Ireland" value="IR"></el-option>
  231. <el-option label="TN : Tennessee" value="TN"></el-option>
  232. </el-select>
  233. </el-form-item>
  234. </el-col>
  235. <el-col :span="6">
  236. <el-form-item label="Claim No">
  237. <el-input v-model="addFormData.claimNo" placeholder="请输入" size="mini"></el-input>
  238. </el-form-item>
  239. </el-col>
  240. <el-col :span="6">
  241. <el-form-item label="Product Category">
  242. <el-select v-model="addFormData.productCategory" placeholder="请选择" size="mini" style="width: 100%">
  243. <el-option label="Metal Pen" value="Metal Pen"></el-option>
  244. <el-option label="CUP" value="CUP"></el-option>
  245. </el-select>
  246. </el-form-item>
  247. </el-col>
  248. <el-col :span="6">
  249. <el-form-item label="Part No">
  250. <el-input v-model="addFormData.partNo" placeholder="请输入" size="mini"></el-input>
  251. </el-form-item>
  252. </el-col>
  253. </el-row>
  254. <!-- 第四行 -->
  255. <el-row :gutter="10">
  256. <el-col :span="18">
  257. <el-form-item label="问题简述" prop="issueSummary">
  258. <el-input v-model="addFormData.issueSummary" placeholder="请输入问题简述" size="mini"></el-input>
  259. </el-form-item>
  260. </el-col>
  261. <el-col :span="6">
  262. <el-form-item label="Inspector">
  263. <el-input v-model="addFormData.inspector" placeholder="请输入" size="mini"></el-input>
  264. </el-form-item>
  265. </el-col>
  266. </el-row>
  267. <!-- 第五行 -->
  268. <el-row :gutter="10">
  269. <el-col :span="18">
  270. <el-form-item label="问题详细描述">
  271. <el-input
  272. v-model="addFormData.issueDescription"
  273. type="textarea"
  274. :rows="4"
  275. placeholder="请输入问题详细描述"
  276. size="mini">
  277. </el-input>
  278. </el-form-item>
  279. </el-col>
  280. </el-row>
  281. <!-- 第六行 -->
  282. <el-row :gutter="10">
  283. <el-col :span="6">
  284. <el-form-item label="Level">
  285. <el-input v-model="addFormData.levelNo" placeholder="请输入" size="mini"></el-input>
  286. </el-form-item>
  287. </el-col>
  288. <el-col :span="6">
  289. <el-form-item label="Mode 1">
  290. <el-select v-model="addFormData.mode1" placeholder="请选择" size="mini" style="width: 100%">
  291. <el-option label="Appearance" value="Appearance"></el-option>
  292. <el-option label="Function" value="Function"></el-option>
  293. </el-select>
  294. </el-form-item>
  295. </el-col>
  296. <el-col :span="6">
  297. <el-form-item label="Mode 2">
  298. <el-select v-model="addFormData.mode2" placeholder="请选择" size="mini" style="width: 100%">
  299. <el-option label="Loose part" value="Loose part"></el-option>
  300. <el-option label="Others" value="Others"></el-option>
  301. <el-option label="Contamination" value="Contamination"></el-option>
  302. </el-select>
  303. </el-form-item>
  304. </el-col>
  305. <el-col :span="6">
  306. <el-form-item label="Mode 3">
  307. <el-select v-model="addFormData.mode3" placeholder="请选择" size="mini" style="width: 100%">
  308. <el-option label="Part Missing" value="Part Missing"></el-option>
  309. <el-option label="Glue" value="Glue"></el-option>
  310. </el-select>
  311. </el-form-item>
  312. </el-col>
  313. </el-row>
  314. </el-form>
  315. <div slot="footer" class="dialog-footer">
  316. <el-button type="primary" @click="handleSaveAdd" class="customer-bun-min">保存</el-button>
  317. <el-button @click="handleCloseAddDialog" class="customer-bun-min">关闭</el-button>
  318. </div>
  319. </el-dialog>
  320. <!-- 编辑弹窗 -->
  321. <el-dialog
  322. title="质量问题 - 编辑"
  323. :visible.sync="editDialogVisible"
  324. width="70%"
  325. top="5vh"
  326. :close-on-click-modal="false"
  327. @close="handleCloseEditDialog">
  328. <el-form :model="editFormData" :rules="editRules" ref="editFormData" label-width="110px" size="mini" class="add-dialog-form">
  329. <!-- 第一行 -->
  330. <el-row :gutter="10">
  331. <el-col :span="6">
  332. <el-form-item label="反馈单号">
  333. <el-input v-model="editFormData.issueNo" placeholder="自动生成" disabled size="mini"></el-input>
  334. </el-form-item>
  335. </el-col>
  336. <el-col :span="6">
  337. <el-form-item label="问题日期" prop="issueDate">
  338. <el-date-picker
  339. v-model="editFormData.issueDate"
  340. type="date"
  341. value-format="yyyy-MM-dd"
  342. placeholder="选择日期"
  343. size="mini"
  344. style="width: 100%">
  345. </el-date-picker>
  346. </el-form-item>
  347. </el-col>
  348. <el-col :span="6">
  349. <el-form-item label="要求回复日期" prop="requireReplyDate">
  350. <el-date-picker
  351. v-model="editFormData.requireReplyDate"
  352. type="date"
  353. value-format="yyyy-MM-dd"
  354. placeholder="选择日期"
  355. size="mini"
  356. style="width: 100%">
  357. </el-date-picker>
  358. </el-form-item>
  359. </el-col>
  360. <el-col :span="6">
  361. <el-form-item label="状态">
  362. <el-input v-model="editFormData.status" disabled size="mini"></el-input>
  363. </el-form-item>
  364. </el-col>
  365. </el-row>
  366. <!-- 新增行PO No批次数量拒收批次数量投诉接收日期样品接收日期 -->
  367. <el-row :gutter="10">
  368. <el-col :span="6">
  369. <el-form-item label="PO No">
  370. <el-input v-model="editFormData.poNo" placeholder="请输入" size="mini"></el-input>
  371. </el-form-item>
  372. </el-col>
  373. <el-col :span="6">
  374. <el-form-item label="批次数量">
  375. <el-input v-model="editFormData.batchQty" placeholder="请输入" size="mini" type="number"></el-input>
  376. </el-form-item>
  377. </el-col>
  378. <el-col :span="6">
  379. <el-form-item label="拒收批次数量">
  380. <el-input v-model="editFormData.rejectBatchQty" placeholder="请输入" size="mini" type="number"></el-input>
  381. </el-form-item>
  382. </el-col>
  383. <el-col :span="6">
  384. <el-form-item label="投诉接收日期">
  385. <el-date-picker
  386. v-model="editFormData.receiveComplaintDate"
  387. type="date"
  388. value-format="yyyy-MM-dd"
  389. placeholder="选择日期"
  390. size="mini"
  391. style="width: 100%">
  392. </el-date-picker>
  393. </el-form-item>
  394. </el-col>
  395. </el-row>
  396. <el-row :gutter="10">
  397. <el-col :span="6">
  398. <el-form-item label="样品接收日期">
  399. <el-date-picker
  400. v-model="editFormData.receiveSampleDate"
  401. type="date"
  402. value-format="yyyy-MM-dd"
  403. placeholder="选择日期"
  404. size="mini"
  405. style="width: 100%">
  406. </el-date-picker>
  407. </el-form-item>
  408. </el-col>
  409. </el-row>
  410. <!-- 第二行 -->
  411. <el-row :gutter="10">
  412. <el-col :span="6">
  413. <el-form-item label="供应商编码">
  414. <el-input v-model="editFormData.supplierNo" disabled size="mini"></el-input>
  415. </el-form-item>
  416. </el-col>
  417. <el-col :span="12">
  418. <el-form-item label="供应商名称">
  419. <el-input v-model="editFormData.supplierName" disabled size="mini"></el-input>
  420. </el-form-item>
  421. </el-col>
  422. <el-col :span="6">
  423. <el-form-item label="供应商负责人">
  424. <el-input v-model="editFormData.supplierResponsible" placeholder="请输入" size="mini"></el-input>
  425. </el-form-item>
  426. </el-col>
  427. </el-row>
  428. <!-- 第三行 -->
  429. <el-row :gutter="10">
  430. <el-col :span="6">
  431. <el-form-item label="Plant">
  432. <el-select v-model="editFormData.plant" placeholder="请选择" size="mini" style="width: 100%">
  433. <el-option label="Mx : Mexico" value="Mx"></el-option>
  434. <el-option label="IR : Ireland" value="IR"></el-option>
  435. <el-option label="TN : Tennessee" value="TN"></el-option>
  436. </el-select>
  437. </el-form-item>
  438. </el-col>
  439. <el-col :span="6">
  440. <el-form-item label="Claim No">
  441. <el-input v-model="editFormData.claimNo" placeholder="请输入" size="mini"></el-input>
  442. </el-form-item>
  443. </el-col>
  444. <el-col :span="6">
  445. <el-form-item label="Product Category">
  446. <el-select v-model="editFormData.productCategory" placeholder="请选择" size="mini" style="width: 100%">
  447. <el-option label="Metal Pen" value="Metal Pen"></el-option>
  448. <el-option label="CUP" value="CUP"></el-option>
  449. </el-select>
  450. </el-form-item>
  451. </el-col>
  452. <el-col :span="6">
  453. <el-form-item label="Part No">
  454. <el-input v-model="editFormData.partNo" placeholder="请输入" size="mini"></el-input>
  455. </el-form-item>
  456. </el-col>
  457. </el-row>
  458. <!-- 第四行 -->
  459. <el-row :gutter="10">
  460. <el-col :span="18">
  461. <el-form-item label="问题简述" prop="issueSummary">
  462. <el-input v-model="editFormData.issueSummary" placeholder="请输入问题简述" size="mini"></el-input>
  463. </el-form-item>
  464. </el-col>
  465. <el-col :span="6">
  466. <el-form-item label="Inspector">
  467. <el-input v-model="editFormData.inspector" placeholder="请输入" size="mini"></el-input>
  468. </el-form-item>
  469. </el-col>
  470. </el-row>
  471. <!-- 第五行 -->
  472. <el-row :gutter="10">
  473. <el-col :span="18">
  474. <el-form-item label="问题详细描述">
  475. <el-input
  476. v-model="editFormData.issueDescription"
  477. type="textarea"
  478. :rows="4"
  479. placeholder="请输入问题详细描述"
  480. size="mini">
  481. </el-input>
  482. </el-form-item>
  483. </el-col>
  484. </el-row>
  485. <!-- 第六行 -->
  486. <el-row :gutter="10">
  487. <el-col :span="6">
  488. <el-form-item label="Level">
  489. <el-input v-model="editFormData.levelNo" placeholder="请输入" size="mini"></el-input>
  490. </el-form-item>
  491. </el-col>
  492. <el-col :span="6">
  493. <el-form-item label="Mode 1">
  494. <el-select v-model="editFormData.mode1" placeholder="请选择" size="mini" style="width: 100%">
  495. <el-option label="Appearance" value="Appearance"></el-option>
  496. <el-option label="Function" value="Function"></el-option>
  497. </el-select>
  498. </el-form-item>
  499. </el-col>
  500. <el-col :span="6">
  501. <el-form-item label="Mode 2">
  502. <el-select v-model="editFormData.mode2" placeholder="请选择" size="mini" style="width: 100%">
  503. <el-option label="Loose part" value="Loose part"></el-option>
  504. <el-option label="Others" value="Others"></el-option>
  505. <el-option label="Contamination" value="Contamination"></el-option>
  506. </el-select>
  507. </el-form-item>
  508. </el-col>
  509. <el-col :span="6">
  510. <el-form-item label="Mode 3">
  511. <el-select v-model="editFormData.mode3" placeholder="请选择" size="mini" style="width: 100%">
  512. <el-option label="Part Missing" value="Part Missing"></el-option>
  513. <el-option label="Glue" value="Glue"></el-option>
  514. </el-select>
  515. </el-form-item>
  516. </el-col>
  517. </el-row>
  518. </el-form>
  519. <div slot="footer" class="dialog-footer">
  520. <el-button type="primary" @click="handleSaveEdit" class="customer-bun-min">保存</el-button>
  521. <el-button @click="handleCloseEditDialog" class="customer-bun-min">关闭</el-button>
  522. </div>
  523. </el-dialog>
  524. <!-- 回复弹窗 -->
  525. <el-dialog
  526. title="质量问题 - 回复"
  527. :visible.sync="replyDialogVisible"
  528. width="50%"
  529. top="10vh"
  530. :close-on-click-modal="false"
  531. @close="handleCloseReplyDialog">
  532. <div class="reply-dialog-info">
  533. <el-row :gutter="20">
  534. <el-col :span="8">
  535. <div class="info-item">
  536. <span class="info-label">反馈单号</span>
  537. <span class="info-value">{{ replyFormData.issueNo }}</span>
  538. </div>
  539. </el-col>
  540. <el-col :span="8">
  541. <div class="info-item">
  542. <span class="info-label">回复日期</span>
  543. <span class="info-value">{{ replyFormData.replyTime }}</span>
  544. </div>
  545. </el-col>
  546. <el-col :span="8">
  547. <div class="info-item">
  548. <span class="info-label">回复人</span>
  549. <span class="info-value">{{ replyFormData.replyBy }}</span>
  550. </div>
  551. </el-col>
  552. </el-row>
  553. </div>
  554. <el-form :model="replyFormData" :rules="replyRules" ref="replyFormData" label-position="top" size="mini" class="reply-dialog-form">
  555. <!-- Why Escape 下拉框 -->
  556. <el-form-item label="Why Escape" prop="whyEscape">
  557. <el-select v-model="replyFormData.whyEscape" placeholder="请选择流出原因" size="mini" style="width: 30%" clearable>
  558. <el-option label="AQL" value="AQL"></el-option>
  559. <el-option label="Transportation" value="Transportation"></el-option>
  560. </el-select>
  561. </el-form-item>
  562. <!-- 原因分析 -->
  563. <el-form-item label="原因分析" prop="analysis">
  564. <el-input
  565. v-model="replyFormData.analysis"
  566. type="textarea"
  567. :rows="4"
  568. placeholder="请输入原因分析"
  569. size="mini">
  570. </el-input>
  571. </el-form-item>
  572. <!-- 后续措施 -->
  573. <el-form-item label="后续措施" prop="correctiveAction">
  574. <el-input
  575. v-model="replyFormData.correctiveAction"
  576. type="textarea"
  577. :rows="4"
  578. placeholder="请输入后续措施"
  579. size="mini">
  580. </el-input>
  581. </el-form-item>
  582. </el-form>
  583. <div slot="footer" class="dialog-footer">
  584. <el-button type="primary" @click="handleSaveReply" class="customer-bun-min">保存</el-button>
  585. <el-button @click="handleCloseReplyDialog" class="customer-bun-min">关闭</el-button>
  586. </div>
  587. </el-dialog>
  588. <!-- 赔偿弹窗 -->
  589. <el-dialog
  590. title="质量问题 - 赔偿"
  591. :visible.sync="compensationDialogVisible"
  592. width="50%"
  593. top="10vh"
  594. :close-on-click-modal="false"
  595. @close="handleCloseCompensationDialog">
  596. <div class="compensation-dialog-info">
  597. <el-row :gutter="20">
  598. <el-col :span="8">
  599. <div class="info-item">
  600. <span class="info-label">反馈单号</span>
  601. <span class="info-value">{{ compensationFormData.issueNo }}</span>
  602. </div>
  603. </el-col>
  604. </el-row>
  605. </div>
  606. <el-form :model="compensationFormData" :rules="compensationRules" ref="compensationFormData" label-position="top" size="mini" class="compensation-dialog-form">
  607. <!-- 索赔信息和被索赔金额 -->
  608. <el-row :gutter="10">
  609. <el-col :span="8">
  610. <el-form-item label="索赔信息">
  611. <el-checkbox v-model="compensationFormData.isClaimed">是否被索赔</el-checkbox>
  612. </el-form-item>
  613. </el-col>
  614. <el-col :span="16">
  615. <el-form-item label="被索赔金额" prop="claimAmount">
  616. <el-input v-model="compensationFormData.claimAmount" placeholder="请输入被索赔金额" size="mini"></el-input>
  617. </el-form-item>
  618. </el-col>
  619. </el-row>
  620. <!-- 处置备注 -->
  621. <el-form-item label="处置备注">
  622. <el-input
  623. v-model="compensationFormData.disposalRemark"
  624. type="textarea"
  625. :rows="3"
  626. placeholder="请输入处置备注"
  627. size="mini">
  628. </el-input>
  629. </el-form-item>
  630. </el-form>
  631. <div slot="footer" class="dialog-footer">
  632. <el-button type="primary" @click="handleSaveCompensation" class="customer-bun-min">保存</el-button>
  633. <el-button @click="handleCloseCompensationDialog" class="customer-bun-min">关闭</el-button>
  634. </div>
  635. </el-dialog>
  636. <Chooselist ref="baseList" @getBaseData="getBaseData"></Chooselist>
  637. </div>
  638. </template>
  639. <script>
  640. import { queryQualityIssuePage, saveQualityIssue,deleteQualityIssue,updateQualityIssue, saveReply, saveClaim, closeQualityIssue } from '@/api/quality/qualityIssue.js'
  641. import Chooselist from '@/views/modules/common/Chooselist_eam'
  642. import ComQualityIssueDetail from './com_qualityIssueDetail.vue'
  643. import ComQualityIssueAttachment from './com_qualityIssueAttachment.vue'
  644. import excel from '@/utils/excel-util.js'
  645. export default {
  646. components: {
  647. Chooselist,
  648. QualityIssueDetail: ComQualityIssueDetail,
  649. QualityIssueAttachment: ComQualityIssueAttachment
  650. },
  651. data () {
  652. return {
  653. functionId: this.$route.meta.menuId,
  654. height: 400,
  655. detailHeight: 400,
  656. currentRow: {},
  657. activeTab: 'detail',
  658. // 新增弹窗相关数据
  659. addDialogVisible: false,
  660. addFormData: {
  661. issueNo: '',
  662. issueDate: '',
  663. requireReplyDate: '',
  664. supplierNo: '',
  665. supplierName: '',
  666. supplierResponsible: '',
  667. plant: '',
  668. claimNo: '',
  669. productCategory: '',
  670. partNo: '',
  671. poNo: '',
  672. batchQty: '',
  673. rejectBatchQty: '',
  674. receiveComplaintDate: '',
  675. receiveSampleDate: '',
  676. issueCategory: '',
  677. issueSummary: '',
  678. issueDescription: '',
  679. inspector: '',
  680. levelNo: '',
  681. mode1: '',
  682. mode2: '',
  683. mode3: '',
  684. status: '已确认'
  685. },
  686. addRules: {
  687. issueDate: [
  688. { required: true, message: '请选择问题日期', trigger: 'change' }
  689. ],
  690. requireReplyDate: [
  691. { required: true, message: '请选择要求回复日期', trigger: 'change' }
  692. ],
  693. supplierNo: [
  694. { required: true, message: '请选择供应商', trigger: 'change' }
  695. ],
  696. issueCategory: [
  697. { required: true, message: '请选择问题分类', trigger: 'change' }
  698. ],
  699. issueSummary: [
  700. { required: true, message: '请输入问题简述', trigger: 'blur' }
  701. ]
  702. },
  703. // 编辑弹窗相关数据
  704. editDialogVisible: false,
  705. editFormData: {
  706. issueNo: '',
  707. issueDate: '',
  708. requireReplyDate: '',
  709. supplierNo: '',
  710. supplierName: '',
  711. supplierResponsible: '',
  712. plant: '',
  713. claimNo: '',
  714. productCategory: '',
  715. partNo: '',
  716. poNo: '',
  717. batchQty: '',
  718. rejectBatchQty: '',
  719. receiveComplaintDate: '',
  720. receiveSampleDate: '',
  721. issueCategory: '',
  722. issueSummary: '',
  723. issueDescription: '',
  724. inspector: '',
  725. levelNo: '',
  726. mode1: '',
  727. mode2: '',
  728. mode3: '',
  729. status: '',
  730. site: ''
  731. },
  732. editRules: {
  733. issueDate: [
  734. { required: true, message: '请选择问题日期', trigger: 'change' }
  735. ],
  736. requireReplyDate: [
  737. { required: true, message: '请选择要求回复日期', trigger: 'change' }
  738. ],
  739. issueCategory: [
  740. { required: true, message: '请选择问题分类', trigger: 'change' }
  741. ],
  742. issueSummary: [
  743. { required: true, message: '请输入问题简述', trigger: 'blur' }
  744. ]
  745. },
  746. // 回复弹窗相关数据
  747. replyDialogVisible: false,
  748. replyFormData: {
  749. site: '',
  750. issueNo: '',
  751. analysis: '',
  752. correctiveAction: '',
  753. whyEscape:'',
  754. replyBy: '',
  755. replyTime: ''
  756. },
  757. replyRules: {
  758. analysis: [
  759. { required: true, message: '请输入原因分析', trigger: 'blur' }
  760. ],
  761. correctiveAction: [
  762. { required: true, message: '请输入后续措施', trigger: 'blur' }
  763. ]
  764. },
  765. // 赔偿弹窗相关数据
  766. compensationDialogVisible: false,
  767. compensationFormData: {
  768. site: '',
  769. issueNo: '',
  770. isClaimed: false,
  771. claimAmount: '',
  772. disposalRemark: ''
  773. },
  774. compensationRules: {
  775. claimAmount: [
  776. { required: true, message: '请输入被索赔金额', trigger: 'blur' }
  777. ]
  778. },
  779. tagNo: '',
  780. searchData: {
  781. issueNo: '',
  782. supplierNo: '',
  783. supplierName: '',
  784. issueCategory: '',
  785. statusDb: '',
  786. issueDate: '',
  787. page: 1,
  788. limit: 50
  789. },
  790. searchType: '',
  791. pageIndex: 1,
  792. pageSize: 50,
  793. totalPage: 0,
  794. mainDataList: [],
  795. dataListLoading: false,
  796. columnArray1: [
  797. {
  798. userId: this.$store.state.user.name,
  799. functionId: this.functionId,
  800. serialNumber: 'QualityIssueTable1IssueNo',
  801. tableId: 'QualityIssueTable1',
  802. tableName: '质量问题',
  803. columnProp: 'issueNo',
  804. headerAlign: 'center',
  805. align: 'left',
  806. columnLabel: '反馈单号',
  807. columnWidth: '120',
  808. columnHidden: false,
  809. columnImage: false,
  810. columnSortable: false,
  811. sortLv: 0,
  812. status: true,
  813. fixed: false
  814. },
  815. {
  816. userId: this.$store.state.user.name,
  817. functionId: this.functionId,
  818. serialNumber: 'QualityIssueTable1IssueDate',
  819. tableId: 'QualityIssueTable1',
  820. tableName: '质量问题',
  821. columnProp: 'issueDate',
  822. headerAlign: 'center',
  823. align: 'center',
  824. columnLabel: '问题日期',
  825. columnWidth: '120',
  826. columnHidden: false,
  827. columnImage: false,
  828. columnSortable: false,
  829. sortLv: 0,
  830. status: true,
  831. fixed: false
  832. },
  833. {
  834. userId: this.$store.state.user.name,
  835. functionId: this.functionId,
  836. serialNumber: 'QualityIssueTable1SupplierNo',
  837. tableId: 'QualityIssueTable1',
  838. tableName: '质量问题',
  839. columnProp: 'supplierNo',
  840. headerAlign: 'center',
  841. align: 'left',
  842. columnLabel: '供应商编码',
  843. columnWidth: '120',
  844. columnHidden: false,
  845. columnImage: false,
  846. columnSortable: false,
  847. sortLv: 0,
  848. status: true,
  849. fixed: false
  850. },
  851. {
  852. userId: this.$store.state.user.name,
  853. functionId: this.functionId,
  854. serialNumber: 'QualityIssueTable1SupplierName',
  855. tableId: 'QualityIssueTable1',
  856. tableName: '质量问题',
  857. columnProp: 'supplierName',
  858. headerAlign: 'center',
  859. align: 'left',
  860. columnLabel: '供应商名称',
  861. columnWidth: '150',
  862. columnHidden: false,
  863. columnImage: false,
  864. columnSortable: false,
  865. sortLv: 0,
  866. status: true,
  867. fixed: false
  868. },
  869. {
  870. userId: this.$store.state.user.name,
  871. functionId: this.functionId,
  872. serialNumber: 'QualityIssueTable1IssueCategory',
  873. tableId: 'QualityIssueTable1',
  874. tableName: '质量问题',
  875. columnProp: 'issueCategory',
  876. headerAlign: 'center',
  877. align: 'left',
  878. columnLabel: '问题分类',
  879. columnWidth: '120',
  880. columnHidden: false,
  881. columnImage: false,
  882. columnSortable: false,
  883. sortLv: 0,
  884. status: true,
  885. fixed: false
  886. },
  887. {
  888. userId: this.$store.state.user.name,
  889. functionId: this.functionId,
  890. serialNumber: 'QualityIssueTable1IssueSummary',
  891. tableId: 'QualityIssueTable1',
  892. tableName: '质量问题',
  893. columnProp: 'issueSummary',
  894. headerAlign: 'center',
  895. align: 'left',
  896. columnLabel: '问题简述',
  897. columnWidth: '200',
  898. columnHidden: false,
  899. columnImage: false,
  900. columnSortable: false,
  901. sortLv: 0,
  902. status: true,
  903. fixed: false
  904. },
  905. {
  906. userId: this.$store.state.user.name,
  907. functionId: this.functionId,
  908. serialNumber: 'QualityIssueTable1Status',
  909. tableId: 'QualityIssueTable1',
  910. tableName: '质量问题',
  911. columnProp: 'status',
  912. headerAlign: 'center',
  913. align: 'center',
  914. columnLabel: '状态',
  915. columnWidth: '100',
  916. columnHidden: false,
  917. columnImage: false,
  918. columnSortable: false,
  919. sortLv: 0,
  920. status: true,
  921. fixed: false
  922. },
  923. {
  924. userId: this.$store.state.user.name,
  925. functionId: this.functionId,
  926. serialNumber: 'QualityIssueTable1CreateBy',
  927. tableId: 'QualityIssueTable1',
  928. tableName: '质量问题',
  929. columnProp: 'createBy',
  930. headerAlign: 'center',
  931. align: 'left',
  932. columnLabel: '录入人',
  933. columnWidth: '100',
  934. columnHidden: false,
  935. columnImage: false,
  936. columnSortable: false,
  937. sortLv: 0,
  938. status: true,
  939. fixed: false
  940. },
  941. {
  942. userId: this.$store.state.user.name,
  943. functionId: this.functionId,
  944. serialNumber: 'QualityIssueTable1CreateDate',
  945. tableId: 'QualityIssueTable1',
  946. tableName: '质量问题',
  947. columnProp: 'createDate',
  948. headerAlign: 'center',
  949. align: 'center',
  950. columnLabel: '录入时间',
  951. columnWidth: '150',
  952. columnHidden: false,
  953. columnImage: false,
  954. columnSortable: false,
  955. sortLv: 0,
  956. status: true,
  957. fixed: false
  958. }
  959. ]
  960. }
  961. },
  962. mounted () {
  963. this.$nextTick(() => {
  964. this.height = (window.innerHeight - 220) / 2
  965. this.detailHeight = (window.innerHeight - 220) / 2
  966. this.getMainData()
  967. })
  968. },
  969. methods: {
  970. // 获取基础数据列表
  971. getBaseList (val, type) {
  972. this.tagNo = val
  973. this.searchType = type || ''
  974. this.$nextTick(() => {
  975. let strVal = ''
  976. let conSql = ''
  977. if (val === 1100) {
  978. strVal = this.addFormData.supplierNo || ''
  979. conSql = " and site = '" + this.$store.state.user.site + "'"
  980. }
  981. this.$refs.baseList.init(val, strVal, conSql)
  982. })
  983. },
  984. /* 列表方法的回调 */
  985. getBaseData (val) {
  986. if (this.tagNo === 1100) {
  987. // 新增弹窗:使用下划线命名的字段,使用$set确保响应式
  988. this.$set(this.addFormData, 'supplierNo', val.supplier_no || '')
  989. this.$set(this.addFormData, 'supplierName', val.supplier_name || '')
  990. }
  991. },
  992. // 查询数据
  993. getMainData () {
  994. this.searchData.limit = this.pageSize
  995. this.searchData.page = this.pageIndex
  996. this.searchData.site = this.$store.state.user.site
  997. this.dataListLoading = true
  998. queryQualityIssuePage(this.searchData).then(({ data }) => {
  999. if (data.code === 0) {
  1000. this.mainDataList = data.page.list
  1001. this.pageIndex = data.page.currPage
  1002. this.pageSize = data.page.pageSize
  1003. this.totalPage = data.page.totalCount
  1004. this.$nextTick(() => {
  1005. if (this.$refs.mainTable) {
  1006. this.$refs.mainTable.clearSelection()
  1007. }
  1008. })
  1009. // 判断是否有数据
  1010. if (this.mainDataList.length > 0) {
  1011. this.$refs.mainTable.setCurrentRow(this.mainDataList[0])
  1012. this.changeData(this.mainDataList[0])
  1013. } else {
  1014. this.changeData(null)
  1015. }
  1016. }
  1017. this.dataListLoading = false
  1018. }).catch(() => {
  1019. this.dataListLoading = false
  1020. })
  1021. },
  1022. // 每页数
  1023. sizeChangeHandle (val) {
  1024. this.pageSize = val
  1025. this.pageIndex = 1
  1026. this.getMainData()
  1027. },
  1028. // 当前页
  1029. currentChangeHandle (val) {
  1030. this.pageIndex = val
  1031. this.getMainData()
  1032. },
  1033. // 页签点击事件
  1034. handleTabClick (tab) {
  1035. // 每次点击页签都触发对应页签的查询
  1036. if (tab.name === 'detail') {
  1037. // 详情页签
  1038. } else if (tab.name === 'attachment') {
  1039. // 附件页签
  1040. this.$nextTick(() => {
  1041. if (this.$refs.attachmentTab) {
  1042. this.$refs.attachmentTab.loadAttachmentList()
  1043. }
  1044. })
  1045. }
  1046. },
  1047. // 行点击事件
  1048. changeData (row) {
  1049. this.currentRow = row ? JSON.parse(JSON.stringify(row)) : {}
  1050. },
  1051. // 新增质量问题
  1052. addQualityIssue () {
  1053. this.addDialogVisible = true
  1054. this.resetAddForm()
  1055. },
  1056. // 关闭新增弹窗
  1057. handleCloseAddDialog () {
  1058. this.addDialogVisible = false
  1059. this.resetAddForm()
  1060. },
  1061. // 关闭编辑弹窗
  1062. handleCloseEditDialog () {
  1063. this.editDialogVisible = false
  1064. this.resetEditForm()
  1065. },
  1066. // 重置表单
  1067. resetAddForm () {
  1068. const today = new Date()
  1069. const year = today.getFullYear()
  1070. const month = String(today.getMonth() + 1).padStart(2, '0')
  1071. const day = String(today.getDate()).padStart(2, '0')
  1072. const todayStr = `${year}-${month}-${day}`
  1073. this.addFormData = {
  1074. issueNo: '',
  1075. issueDate: todayStr,
  1076. requireReplyDate: '',
  1077. supplierNo: '',
  1078. supplierName: '',
  1079. supplierResponsible: '',
  1080. plant: '',
  1081. claimNo: '',
  1082. productCategory: '',
  1083. partNo: '',
  1084. poNo: '',
  1085. batchQty: '',
  1086. rejectBatchQty: '',
  1087. receiveComplaintDate: '',
  1088. receiveSampleDate: '',
  1089. issueCategory: '',
  1090. issueSummary: '',
  1091. issueDescription: '',
  1092. inspector: '',
  1093. levelNo: '',
  1094. mode1: '',
  1095. mode2: '',
  1096. mode3: '',
  1097. status: '已确认'
  1098. }
  1099. if (this.$refs.addFormData) {
  1100. this.$refs.addFormData.clearValidate()
  1101. }
  1102. },
  1103. // 重置编辑表单
  1104. resetEditForm () {
  1105. this.editFormData = {
  1106. issueNo: '',
  1107. issueDate: '',
  1108. requireReplyDate: '',
  1109. supplierNo: '',
  1110. supplierName: '',
  1111. supplierResponsible: '',
  1112. plant: '',
  1113. claimNo: '',
  1114. productCategory: '',
  1115. partNo: '',
  1116. poNo: '',
  1117. batchQty: '',
  1118. rejectBatchQty: '',
  1119. receiveComplaintDate: '',
  1120. receiveSampleDate: '',
  1121. issueCategory: '',
  1122. issueSummary: '',
  1123. issueDescription: '',
  1124. inspector: '',
  1125. levelNo: '',
  1126. mode1: '',
  1127. mode2: '',
  1128. mode3: '',
  1129. status: '',
  1130. site: ''
  1131. }
  1132. if (this.$refs.editFormData) {
  1133. this.$refs.editFormData.clearValidate()
  1134. }
  1135. },
  1136. // 选择供应商(仅新增模式)
  1137. selectSupplier () {
  1138. this.tagNo = 1100
  1139. this.$nextTick(() => {
  1140. const conSql = " and site = '" + this.$store.state.user.site + "'"
  1141. this.$refs.baseList.init(1100, this.addFormData.supplierNo || '', conSql)
  1142. })
  1143. },
  1144. // 保存新增
  1145. handleSaveAdd () {
  1146. this.$refs.addFormData.validate((valid) => {
  1147. if (valid) {
  1148. // 构建提交数据
  1149. const submitData = {
  1150. issueDate: this.addFormData.issueDate,
  1151. requireReplyDate: this.addFormData.requireReplyDate,
  1152. supplierNo: this.addFormData.supplierNo,
  1153. supplierName: this.addFormData.supplierName,
  1154. supplierResponsible: this.addFormData.supplierResponsible,
  1155. plant: this.addFormData.plant,
  1156. claimNo: this.addFormData.claimNo,
  1157. productCategory: this.addFormData.productCategory,
  1158. partNo: this.addFormData.partNo,
  1159. poNo: this.addFormData.poNo,
  1160. batchQty: this.addFormData.batchQty ? parseFloat(this.addFormData.batchQty) : null,
  1161. rejectBatchQty: this.addFormData.rejectBatchQty ? parseFloat(this.addFormData.rejectBatchQty) : null,
  1162. receiveComplaintDate: this.addFormData.receiveComplaintDate,
  1163. receiveSampleDate: this.addFormData.receiveSampleDate,
  1164. issueCategory: this.addFormData.issueCategory,
  1165. issueSummary: this.addFormData.issueSummary,
  1166. issueDescription: this.addFormData.issueDescription,
  1167. inspector: this.addFormData.inspector,
  1168. levelNo: this.addFormData.levelNo,
  1169. mode1: this.addFormData.mode1,
  1170. mode2: this.addFormData.mode2,
  1171. mode3: this.addFormData.mode3,
  1172. status: this.addFormData.status,
  1173. site: this.$store.state.user.site
  1174. }
  1175. console.log('提交数据:', submitData)
  1176. saveQualityIssue(submitData).then(({ data }) => {
  1177. console.log('保存接口返回:', data)
  1178. if (data.code === 0) {
  1179. this.$message.success('保存成功')
  1180. this.handleCloseAddDialog()
  1181. this.getMainData()
  1182. } else {
  1183. this.$message.error(data.msg || '保存失败')
  1184. }
  1185. }).catch((error) => {
  1186. console.error('保存接口错误:', error)
  1187. this.$message.error('保存失败,请稍后重试')
  1188. })
  1189. } else {
  1190. console.log('表单验证失败')
  1191. this.$message.warning('请填写完整的表单信息')
  1192. }
  1193. })
  1194. },
  1195. // 保存编辑
  1196. handleSaveEdit () {
  1197. this.$refs.editFormData.validate((valid) => {
  1198. if (valid) {
  1199. // 构建提交数据
  1200. const submitData = {
  1201. site: this.editFormData.site,
  1202. issueNo: this.editFormData.issueNo,
  1203. issueDate: this.editFormData.issueDate,
  1204. requireReplyDate: this.editFormData.requireReplyDate,
  1205. supplierResponsible: this.editFormData.supplierResponsible,
  1206. plant: this.editFormData.plant,
  1207. claimNo: this.editFormData.claimNo,
  1208. productCategory: this.editFormData.productCategory,
  1209. partNo: this.editFormData.partNo,
  1210. poNo: this.editFormData.poNo,
  1211. batchQty: this.editFormData.batchQty ? parseFloat(this.editFormData.batchQty) : null,
  1212. rejectBatchQty: this.editFormData.rejectBatchQty ? parseFloat(this.editFormData.rejectBatchQty) : null,
  1213. receiveComplaintDate: this.editFormData.receiveComplaintDate,
  1214. receiveSampleDate: this.editFormData.receiveSampleDate,
  1215. issueCategory: this.editFormData.issueCategory,
  1216. issueSummary: this.editFormData.issueSummary,
  1217. issueDescription: this.editFormData.issueDescription,
  1218. inspector: this.editFormData.inspector,
  1219. levelNo: this.editFormData.levelNo,
  1220. mode1: this.editFormData.mode1,
  1221. mode2: this.editFormData.mode2,
  1222. mode3: this.editFormData.mode3,
  1223. status: this.editFormData.status
  1224. }
  1225. console.log('更新数据:', submitData)
  1226. updateQualityIssue(submitData).then(({ data }) => {
  1227. console.log('更新接口返回:', data)
  1228. if (data.code === 0) {
  1229. this.$message.success('更新成功')
  1230. this.handleCloseEditDialog()
  1231. this.getMainData()
  1232. } else {
  1233. this.$message.error(data.msg || '更新失败')
  1234. }
  1235. }).catch((error) => {
  1236. console.error('更新接口错误:', error)
  1237. this.$message.error('更新失败,请稍后重试')
  1238. })
  1239. } else {
  1240. console.log('表单验证失败')
  1241. this.$message.warning('请填写完整的表单信息')
  1242. }
  1243. })
  1244. },
  1245. // 编辑质量问题
  1246. editQualityIssue (row) {
  1247. this.editDialogVisible = true
  1248. // 自动填充表格中的数据
  1249. this.editFormData = {
  1250. issueNo: row.issueNo || '',
  1251. issueDate: row.issueDate || '',
  1252. requireReplyDate: row.requireReplyDate || '',
  1253. supplierNo: row.supplierNo || '',
  1254. supplierName: row.supplierName || '',
  1255. supplierResponsible: row.supplierResponsible || '',
  1256. plant: row.plant || '',
  1257. claimNo: row.claimNo || '',
  1258. productCategory: row.productCategory || '',
  1259. partNo: row.partNo || '',
  1260. poNo: row.poNo || '',
  1261. batchQty: row.batchQty || '',
  1262. rejectBatchQty: row.rejectBatchQty || '',
  1263. receiveComplaintDate: row.receiveComplaintDate || '',
  1264. receiveSampleDate: row.receiveSampleDate || '',
  1265. issueCategory: row.issueCategory || '',
  1266. issueSummary: row.issueSummary || '',
  1267. issueDescription: row.issueDescription || '',
  1268. inspector: row.inspector || '',
  1269. levelNo: row.levelNo || '',
  1270. mode1: row.mode1 || '',
  1271. mode2: row.mode2 || '',
  1272. mode3: row.mode3 || '',
  1273. status: row.status || '',
  1274. site: row.site || this.$store.state.user.site
  1275. }
  1276. // 清除验证状态
  1277. this.$nextTick(() => {
  1278. if (this.$refs.editFormData) {
  1279. this.$refs.editFormData.clearValidate()
  1280. }
  1281. })
  1282. },
  1283. // 删除质量问题
  1284. deleteQualityIssue(row) {
  1285. this.$confirm('确定要删除该质量问题吗?删除后无法恢复!', '提示', {
  1286. confirmButtonText: '确定删除',
  1287. cancelButtonText: '取消',
  1288. type: 'warning',
  1289. dangerouslyUseHTMLString: true
  1290. }).then(() => {
  1291. // 显示加载中
  1292. const loading = this.$loading({
  1293. lock: true,
  1294. text: '删除中...',
  1295. spinner: 'el-icon-loading',
  1296. background: 'rgba(0, 0, 0, 0.7)'
  1297. });
  1298. // 构建删除参数
  1299. const deleteParams = {
  1300. site: row.site || this.$store.state.user.site,
  1301. issueNo: row.issueNo
  1302. };
  1303. console.log('删除参数:', deleteParams);
  1304. // 调用删除接口
  1305. deleteQualityIssue(deleteParams).then(({ data }) => {
  1306. loading.close();
  1307. if (data.code === 0) {
  1308. this.$message.success('删除成功');
  1309. // 判断当前页是否还有数据
  1310. const isLastItem = this.mainDataList.length === 1;
  1311. // 刷新列表
  1312. if (isLastItem && this.pageIndex > 1) {
  1313. // 如果是最后一页的最后一条数据,跳转到上一页
  1314. this.pageIndex--;
  1315. }
  1316. this.getMainData();
  1317. } else {
  1318. this.$message.error(data.msg || '删除失败');
  1319. }
  1320. }).catch((error) => {
  1321. loading.close();
  1322. console.error('删除接口错误:', error);
  1323. this.$message.error('删除失败,请稍后重试');
  1324. });
  1325. }).catch(() => {
  1326. this.$message.info('已取消删除');
  1327. });
  1328. },
  1329. // 回复质量问题
  1330. replyQualityIssue (row) {
  1331. this.replyDialogVisible = true
  1332. // 自动填充表格中的数据
  1333. const now = new Date()
  1334. const year = now.getFullYear()
  1335. const month = String(now.getMonth() + 1).padStart(2, '0')
  1336. const day = String(now.getDate()).padStart(2, '0')
  1337. const currentDate = `${year}-${month}-${day}`
  1338. this.replyFormData = {
  1339. site: row.site || this.$store.state.user.site,
  1340. issueNo: row.issueNo || '',
  1341. analysis: row.analysis || '', // 从行数据中获取已有值
  1342. correctiveAction: row.correctiveAction || '', // 从行数据中获取已有值
  1343. whyEscape: row.whyEscape || '', // 添加这行:从行数据中获取已有值
  1344. replyBy: this.$store.state.user.name || '',
  1345. replyTime: currentDate
  1346. }
  1347. // 清除验证状态
  1348. this.$nextTick(() => {
  1349. if (this.$refs.replyFormData) {
  1350. this.$refs.replyFormData.clearValidate()
  1351. }
  1352. })
  1353. },
  1354. // 关闭回复弹窗
  1355. handleCloseReplyDialog () {
  1356. this.replyDialogVisible = false
  1357. this.resetReplyForm()
  1358. },
  1359. // 重置回复表单
  1360. resetReplyForm () {
  1361. this.replyFormData = {
  1362. site: '',
  1363. issueNo: '',
  1364. analysis: '',
  1365. correctiveAction: '',
  1366. replyBy: '',
  1367. replyTime: ''
  1368. }
  1369. if (this.$refs.replyFormData) {
  1370. this.$refs.replyFormData.clearValidate()
  1371. }
  1372. },
  1373. // 保存回复
  1374. handleSaveReply () {
  1375. this.$refs.replyFormData.validate((valid) => {
  1376. if (valid) {
  1377. // 构建提交数据 - 添加 whyEscape
  1378. const submitData = {
  1379. site: this.replyFormData.site,
  1380. issueNo: this.replyFormData.issueNo,
  1381. analysis: this.replyFormData.analysis,
  1382. correctiveAction: this.replyFormData.correctiveAction,
  1383. whyEscape: this.replyFormData.whyEscape // 添加这个字段
  1384. }
  1385. console.log('回复数据:', submitData)
  1386. saveReply(submitData).then(({ data }) => {
  1387. console.log('回复接口返回:', data)
  1388. if (data.code === 0) {
  1389. this.$message.success('回复成功')
  1390. this.handleCloseReplyDialog()
  1391. this.getMainData()
  1392. } else {
  1393. this.$message.error(data.msg || '回复失败')
  1394. }
  1395. }).catch((error) => {
  1396. console.error('回复接口错误:', error)
  1397. this.$message.error('回复失败,请稍后重试')
  1398. })
  1399. } else {
  1400. console.log('表单验证失败')
  1401. this.$message.warning('请填写完整的回复信息')
  1402. }
  1403. })
  1404. },
  1405. // 赔偿质量问题
  1406. compensationQualityIssue (row) {
  1407. this.compensationDialogVisible = true
  1408. // 自动填充表格中的数据
  1409. this.compensationFormData = {
  1410. site: row.site || this.$store.state.user.site,
  1411. issueNo: row.issueNo || '',
  1412. isClaimed: row.claimFlag === 'Y' ? true : false,
  1413. claimAmount: row.claimAmount || '',
  1414. disposalRemark: row.disposalRemark || ''
  1415. }
  1416. // 清除验证状态
  1417. this.$nextTick(() => {
  1418. if (this.$refs.compensationFormData) {
  1419. this.$refs.compensationFormData.clearValidate()
  1420. }
  1421. })
  1422. },
  1423. // 关闭赔偿弹窗
  1424. handleCloseCompensationDialog () {
  1425. this.compensationDialogVisible = false
  1426. this.resetCompensationForm()
  1427. },
  1428. // 重置赔偿表单
  1429. resetCompensationForm () {
  1430. this.compensationFormData = {
  1431. site: '',
  1432. issueNo: '',
  1433. isClaimed: false,
  1434. claimAmount: '',
  1435. disposalRemark: ''
  1436. }
  1437. if (this.$refs.compensationFormData) {
  1438. this.$refs.compensationFormData.clearValidate()
  1439. }
  1440. },
  1441. // 保存赔偿
  1442. handleSaveCompensation () {
  1443. this.$refs.compensationFormData.validate((valid) => {
  1444. if (valid) {
  1445. // 构建提交数据 - 将前端的isClaimed转换为后端的claimFlag(Y/N)
  1446. const submitData = {
  1447. site: this.compensationFormData.site,
  1448. issueNo: this.compensationFormData.issueNo,
  1449. claimFlag: this.compensationFormData.isClaimed ? 'Y' : 'N',
  1450. claimAmount: this.compensationFormData.claimAmount ? parseFloat(this.compensationFormData.claimAmount) : null,
  1451. disposalRemark: this.compensationFormData.disposalRemark
  1452. }
  1453. console.log('赔偿数据:', submitData)
  1454. // 调用后端赔偿接口
  1455. saveClaim(submitData).then(({ data }) => {
  1456. if (data.code === 0) {
  1457. this.$message.success('保存成功')
  1458. this.handleCloseCompensationDialog()
  1459. this.getMainData()
  1460. } else {
  1461. this.$message.error(data.msg || '保存失败')
  1462. }
  1463. }).catch((error) => {
  1464. console.error('赔偿接口错误:', error)
  1465. this.$message.error('保存失败,请稍后重试')
  1466. })
  1467. } else {
  1468. console.log('表单验证失败')
  1469. this.$message.warning('请填写完整的赔偿信息')
  1470. }
  1471. })
  1472. },
  1473. // 关闭质量问题
  1474. closeQualityIssueAction (row) {
  1475. this.$confirm('确定要关闭该质量问题吗?关闭后将无法修改!', '提示', {
  1476. confirmButtonText: '确定关闭',
  1477. cancelButtonText: '取消',
  1478. type: 'warning',
  1479. dangerouslyUseHTMLString: true
  1480. }).then(() => {
  1481. // 显示加载中
  1482. const loading = this.$loading({
  1483. lock: true,
  1484. text: '关闭中...',
  1485. spinner: 'el-icon-loading',
  1486. background: 'rgba(0, 0, 0, 0.7)'
  1487. });
  1488. // 构建关闭参数
  1489. const closeParams = {
  1490. site: row.site || this.$store.state.user.site,
  1491. issueNo: row.issueNo
  1492. };
  1493. console.log('关闭参数:', closeParams);
  1494. // 调用关闭接口
  1495. closeQualityIssue(closeParams).then(({ data }) => {
  1496. loading.close();
  1497. if (data.code === 0) {
  1498. this.$message.success('关闭成功');
  1499. this.getMainData();
  1500. } else {
  1501. this.$message.error(data.msg || '关闭失败');
  1502. }
  1503. }).catch((error) => {
  1504. loading.close();
  1505. console.error('关闭接口错误:', error);
  1506. this.$message.error('关闭失败,请稍后重试');
  1507. });
  1508. }).catch(() => {
  1509. this.$message.info('已取消关闭');
  1510. });
  1511. },
  1512. // 导出
  1513. exportExcel () {
  1514. console.log('开始导出...')
  1515. // 生成文件名(使用原生 Date)
  1516. const now = new Date()
  1517. const year = now.getFullYear()
  1518. const month = String(now.getMonth() + 1).padStart(2, '0')
  1519. const day = String(now.getDate()).padStart(2, '0')
  1520. const hour = String(now.getHours()).padStart(2, '0')
  1521. const minute = String(now.getMinutes()).padStart(2, '0')
  1522. const second = String(now.getSeconds()).padStart(2, '0')
  1523. const exportName = `质量问题${year}${month}${day}${hour}${minute}${second}`
  1524. console.log('导出参数:', this.searchData)
  1525. // 获取当前查询条件
  1526. const exportParams = {
  1527. ...this.searchData,
  1528. limit: -1, // 导出全部数据
  1529. page: 1
  1530. }
  1531. try {
  1532. excel.exportTable({
  1533. url: '/srm/qualityIssue/queryPage',
  1534. columnMapping: this.columnArray1,
  1535. mergeSetting: [],
  1536. params: exportParams,
  1537. fileName: exportName + '.xlsx',
  1538. rowFetcher: res => {
  1539. console.log('导出数据响应:', res)
  1540. return res.data.page.list
  1541. },
  1542. columnFormatter: [],
  1543. dropColumns: []
  1544. })
  1545. console.log('导出请求已发送')
  1546. } catch (error) {
  1547. console.error('导出失败:', error)
  1548. this.$message.error('导出失败: ' + error.message)
  1549. }
  1550. }
  1551. },
  1552. created () {
  1553. this.getMainData()
  1554. }
  1555. }
  1556. </script>
  1557. <style scoped lang="scss">
  1558. .search-form-inline {
  1559. background: #fff;
  1560. }
  1561. .search-row {
  1562. display: flex;
  1563. align-items: flex-end;
  1564. flex-wrap: nowrap;
  1565. gap: 15px;
  1566. }
  1567. .search-row:last-child {
  1568. margin-top: -10px;
  1569. }
  1570. .search-item {
  1571. flex: none;
  1572. margin-bottom: 10px;
  1573. }
  1574. .search-btn-item {
  1575. flex: none;
  1576. margin-bottom: 10px;
  1577. }
  1578. .search-btn-item /deep/ .el-form-item__content {
  1579. line-height: normal;
  1580. }
  1581. .search-item /deep/ .el-form-item__label {
  1582. font-size: 13px;
  1583. color: #606266;
  1584. padding-bottom: 5px;
  1585. line-height: 1;
  1586. height: auto;
  1587. }
  1588. .search-item /deep/ .el-form-item__content {
  1589. line-height: normal;
  1590. }
  1591. .date-range {
  1592. display: flex;
  1593. align-items: center;
  1594. }
  1595. .split {
  1596. padding: 0 6px;
  1597. color: #606266;
  1598. font-size: 13px;
  1599. }
  1600. /deep/ .customer-tab .el-tabs__content {
  1601. padding: 5px !important;
  1602. }
  1603. .add-dialog-form /deep/ .el-form-item {
  1604. margin-bottom: 8px;
  1605. }
  1606. .add-dialog-form /deep/ .el-form-item__label {
  1607. text-align: left;
  1608. float: none;
  1609. display: block;
  1610. padding: 0 0 3px 0;
  1611. line-height: 1;
  1612. font-size: 12px;
  1613. }
  1614. .add-dialog-form /deep/ .el-form-item__content {
  1615. margin-left: 0 !important;
  1616. }
  1617. .dialog-footer {
  1618. text-align: center;
  1619. }
  1620. /* 回复弹窗样式 */
  1621. .reply-dialog-info {
  1622. margin-bottom: 20px;
  1623. padding: 15px;
  1624. background-color: #f5f7fa;
  1625. border-radius: 4px;
  1626. }
  1627. .reply-dialog-info .info-item {
  1628. display: flex;
  1629. align-items: center;
  1630. margin-bottom: 10px;
  1631. }
  1632. .reply-dialog-info .info-item:last-child {
  1633. margin-bottom: 0;
  1634. }
  1635. .reply-dialog-info .info-label {
  1636. font-size: 13px;
  1637. color: #606266;
  1638. font-weight: 500;
  1639. min-width: 80px;
  1640. }
  1641. .reply-dialog-info .info-value {
  1642. font-size: 13px;
  1643. color: #303133;
  1644. flex: 1;
  1645. }
  1646. .reply-dialog-form /deep/ .el-form-item {
  1647. margin-bottom: 15px;
  1648. }
  1649. .reply-dialog-form /deep/ .el-form-item__label {
  1650. font-size: 13px;
  1651. color: #606266;
  1652. font-weight: 500;
  1653. padding-bottom: 5px;
  1654. line-height: 1;
  1655. height: auto;
  1656. }
  1657. .reply-dialog-form /deep/ .el-form-item__content {
  1658. line-height: normal;
  1659. }
  1660. /* 赔偿弹窗样式 */
  1661. .compensation-dialog-info {
  1662. margin-bottom: 20px;
  1663. padding: 15px;
  1664. background-color: #f5f7fa;
  1665. border-radius: 4px;
  1666. }
  1667. .compensation-dialog-info .info-item {
  1668. display: flex;
  1669. align-items: center;
  1670. margin-bottom: 10px;
  1671. }
  1672. .compensation-dialog-info .info-item:last-child {
  1673. margin-bottom: 0;
  1674. }
  1675. .compensation-dialog-info .info-label {
  1676. font-size: 13px;
  1677. color: #606266;
  1678. font-weight: 500;
  1679. min-width: 80px;
  1680. }
  1681. .compensation-dialog-info .info-value {
  1682. font-size: 13px;
  1683. color: #303133;
  1684. flex: 1;
  1685. }
  1686. .compensation-dialog-form /deep/ .el-form-item {
  1687. margin-bottom: 15px;
  1688. }
  1689. .compensation-dialog-form /deep/ .el-form-item__label {
  1690. font-size: 13px;
  1691. color: #606266;
  1692. font-weight: 500;
  1693. padding-bottom: 5px;
  1694. line-height: 1;
  1695. height: auto;
  1696. }
  1697. .compensation-dialog-form /deep/ .el-form-item__content {
  1698. line-height: normal;
  1699. }
  1700. </style>