plm前端
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.

3599 lines
158 KiB

  1. <template>
  2. <div class="mod-config">
  3. <!-- 查询条件 -->
  4. <el-form :inline="true" label-position="top" :model="searchData">
  5. <el-form-item label="序列号">
  6. <el-input v-model="searchData.referenceNo" clearable style="width: 120px"></el-input>
  7. </el-form-item>
  8. <el-form-item label="单据状态">
  9. <el-select v-model="searchData.status" clearable style="width: 120px">
  10. <el-option label="草稿" value="草稿"></el-option>
  11. <el-option label="审批中" value="审批中"></el-option>
  12. <el-option label="已完成" value="已完成"></el-option>
  13. </el-select>
  14. </el-form-item>
  15. <el-form-item label="节点审批人">
  16. <el-input v-model="searchData.currentApprover" clearable style="width: 120px"></el-input>
  17. </el-form-item>
  18. <el-form-item label="当前节点">
  19. <el-select v-model="searchData.nodeId" placeholder="请选择节点" clearable style="width: 120px">
  20. <el-option
  21. v-for="option in nodeOptions"
  22. :key="option.id"
  23. :label="option.name"
  24. :value="option.id">
  25. </el-option>
  26. </el-select>
  27. </el-form-item>
  28. <el-form-item :label="' '">
  29. <el-button v-if="authSearch" @click="getDataList">查询</el-button>
  30. <el-button v-if="authUpdate" @click="addOrUpdateHandle()">新增</el-button>
  31. <el-button v-if="authDelete" type="danger" @click="deleteHandle()">删除</el-button>
  32. <download-excel
  33. v-if="authSearch"
  34. :fields="exportFieldMap"
  35. :data="exportData"
  36. type="xls"
  37. :name="exportName"
  38. :header="exportHeader"
  39. :footer="exportFooter"
  40. :fetch="createExportData"
  41. :before-generate="startDownload"
  42. :before-finish="finishDownload"
  43. worksheet="导出信息"
  44. :class="['el-button', 'el-button--primary', 'el-button--medium', {'is-loading': exportLoading}]">
  45. <i v-if="exportLoading" class="el-icon-loading"></i>
  46. <span>{{ "导出" }}</span>
  47. </download-excel>
  48. <el-button v-if="authSearch" @click="searchHandle()">搜索</el-button>
  49. </el-form-item>
  50. </el-form>
  51. <!-- 列表 -->
  52. <el-table
  53. ref="rohsTable"
  54. :height="height"
  55. :data="dataList"
  56. border
  57. :row-style="rowStyle"
  58. @row-click="changeClickRow"
  59. @current-change="currentChange"
  60. @selection-change="dataListSelectionChange"
  61. v-loading="dataListLoading"
  62. style="width: 100%;">
  63. <el-table-column type="selection" header-align="center" align="center" width="50"></el-table-column>
  64. <el-table-column prop="referenceNo" header-align="center" align="center" label="序列号" width="165"></el-table-column>
  65. <el-table-column prop="status" header-align="center" align="center" label="单据状态" width="120"></el-table-column>
  66. <el-table-column prop="nodeId" header-align="center" align="center" label="当前节点ID" width="130"></el-table-column>
  67. <el-table-column prop="nodeName" header-align="center" align="center" label="当前节点" width="150"></el-table-column>
  68. <el-table-column prop="currentApprover" header-align="center" align="center" label="当前节点审批人" width="170"></el-table-column>
  69. <el-table-column prop="applicant" header-align="center" align="center" label="申请人编码" width="130"></el-table-column>
  70. <el-table-column prop="applicantName" header-align="center" align="center" label="申请人名称" width="150"></el-table-column>
  71. <el-table-column prop="pm" header-align="center" align="center" label="PM编码" width="130"></el-table-column>
  72. <el-table-column prop="pmName" header-align="center" align="center" label="PM名称" width="150"></el-table-column>
  73. <el-table-column prop="applicationDate" header-align="center" align="center" label="申请日期" width="165"></el-table-column>
  74. <el-table-column prop="plannedMassProductionDate" header-align="center" align="center" label="计划转量产时间" width="165">
  75. <template slot-scope="scope">
  76. <span>{{ normalizeDateOnly(scope.row.plannedMassProductionDate) }}</span>
  77. </template>
  78. </el-table-column>
  79. <el-table-column prop="process" header-align="center" align="center" label="工艺" width="120"></el-table-column>
  80. <el-table-column prop="color" header-align="center" align="center" label="颜色" width="120"></el-table-column>
  81. <el-table-column prop="vendorCode" header-align="center" align="center" label="供应商" width="160"></el-table-column>
  82. <el-table-column prop="vendorMaterialCode" header-align="center" align="center" label="供应商材料编码" width="200" :show-overflow-tooltip="true"></el-table-column>
  83. <el-table-column prop="materialClassify" header-align="center" align="center" label="材料分类" width="200" :show-overflow-tooltip="true"></el-table-column>
  84. <el-table-column prop="otherMaterialClassify" header-align="center" align="center" label="其他材料分类" width="210" :show-overflow-tooltip="true"></el-table-column>
  85. <el-table-column prop="materialUseFor" header-align="center" align="center" label="辅材用途" width="180" :show-overflow-tooltip="true"></el-table-column>
  86. <el-table-column prop="endCustomer" header-align="center" align="center" label="最终客户编码" width="160"></el-table-column>
  87. <el-table-column prop="endCustomerName" header-align="center" align="center" label="最终客户名称" width="180"></el-table-column>
  88. <el-table-column prop="projectId" header-align="center" align="center" label="项目编码" width="140"></el-table-column>
  89. <el-table-column prop="projectName" header-align="center" align="center" label="项目名称" width="180"></el-table-column>
  90. <el-table-column prop="commGroup1" header-align="center" align="center" label="商品组1编码" width="170"></el-table-column>
  91. <el-table-column prop="commGroup1Desc" header-align="center" align="center" label="商品组1名称" width="170"></el-table-column>
  92. <el-table-column prop="commGroup2" header-align="center" align="center" label="商品组2编码" width="170"></el-table-column>
  93. <el-table-column prop="commGroup2Desc" header-align="center" align="center" label="商品组2名称" width="170"></el-table-column>
  94. <el-table-column prop="commGroup3" header-align="center" align="center" label="商品组3编码" width="170"></el-table-column>
  95. <el-table-column prop="commGroup3Desc" header-align="center" align="center" label="商品组3名称" width="170"></el-table-column>
  96. <el-table-column prop="needCreateNumber" header-align="center" align="center" label="需创建内部编号" width="200"></el-table-column>
  97. <el-table-column prop="npdEngineer" header-align="center" align="center" label="NPD工程师编码" width="170"></el-table-column>
  98. <el-table-column prop="npdEngineerName" header-align="center" align="center" label="NPD工程师名称" width="170"></el-table-column>
  99. <el-table-column prop="materialValidityTime" header-align="center" align="center" label="材料有效期" width="200"></el-table-column>
  100. <el-table-column prop="needDeviation" header-align="center" align="center" label="是否需偏差许可" width="190"></el-table-column>
  101. <el-table-column prop="technicalPlan" header-align="center" align="center" label="技术计划编码" width="170"></el-table-column>
  102. <el-table-column prop="technicalPlanName" header-align="center" align="center" label="技术计划名称" width="170"></el-table-column>
  103. <el-table-column prop="buyer" header-align="center" align="center" label="采购编码" width="130"></el-table-column>
  104. <el-table-column prop="buyerName" header-align="center" align="center" label="采购名称" width="130"></el-table-column>
  105. <el-table-column prop="expectReportTime" header-align="center" align="center" label="预计提供报告时间(一个月内)" width="200">
  106. <template slot-scope="scope">
  107. <span>{{ normalizeDateOnly(scope.row.expectReportTime) }}</span>
  108. </template>
  109. </el-table-column>
  110. <el-table-column prop="sgsReportNumber" header-align="center" align="center" label="SGS报告编号" width="190" :show-overflow-tooltip="true"></el-table-column>
  111. <el-table-column prop="expiredDate" header-align="center" align="center" label="报告日期" width="165"></el-table-column>
  112. <el-table-column prop="validUntilDisplay" header-align="center" align="center" label="有效期" width="170" :show-overflow-tooltip="true">
  113. <template slot-scope="scope">
  114. <span>{{ getValidUntilDisplay(scope.row.validUntilValue, scope.row.validUntil) }}</span>
  115. </template>
  116. </el-table-column>
  117. <el-table-column prop="isMeetRohsRequirement" header-align="center" align="center" label="符合RoHS" width="170"></el-table-column>
  118. <el-table-column prop="isAhGrade" header-align="center" align="center" label="AH属性" width="140"></el-table-column>
  119. <el-table-column prop="hsfSupplierClassification" header-align="center" align="center" label="HSF供应商等级" width="220"></el-table-column>
  120. <el-table-column prop="hsfApproverName" header-align="center" align="center" label="HSF审批人" width="240" :show-overflow-tooltip="true">
  121. <template slot-scope="scope">
  122. <span>{{ scope.row.hsfApproverName || scope.row.hsfApprover || '' }}</span>
  123. </template>
  124. </el-table-column>
  125. <el-table-column prop="relatedPeopleName" header-align="center" align="center" label="Inform Related people" width="200" :show-overflow-tooltip="true">
  126. <template slot-scope="scope">
  127. <span>{{ scope.row.relatedPeopleName || scope.row.relatedPeople || '' }}</span>
  128. </template>
  129. </el-table-column>
  130. <el-table-column prop="isSameMaterialDiffSize" header-align="center" align="center" label="同材不同规格" width="220"></el-table-column>
  131. <el-table-column prop="ifsPartNo" header-align="center" align="center" label="IFS编号" width="150"></el-table-column>
  132. <el-table-column prop="remark" header-align="center" align="center" label="备注" width="220" :show-overflow-tooltip="true"></el-table-column>
  133. <el-table-column fixed="right" header-align="center" align="center" width="130" label="操作">
  134. <template slot-scope="scope">
  135. <el-link v-if="authUpdate && scope.row.status !== '已完成'" style="cursor: pointer" @click="addOrUpdateHandle(scope.row)">编辑</el-link>
  136. <el-link v-if="authUpdate && scope.row.status === '已完成'" style="cursor: pointer" @click="addOrUpdateHandle(scope.row)">详情</el-link>
  137. <el-link v-if="authIssue && scope.row.status === '草稿'" style="cursor: pointer; margin-left: 10px;" @click="issueModal(scope.row)">下达</el-link>
  138. </template>
  139. </el-table-column>
  140. </el-table>
  141. <!-- 分页 -->
  142. <el-pagination style="margin-top: 0px"
  143. @size-change="sizeChangeHandle"
  144. @current-change="currentChangeHandle"
  145. :current-page="pageIndex"
  146. :page-sizes="[20, 50, 100, 200, 500]"
  147. :page-size="pageSize"
  148. :total="totalPage"
  149. layout="total, sizes, prev, pager, next, jumper">
  150. </el-pagination>
  151. <!-- 编辑模态框 -->
  152. <el-dialog
  153. :title="modalTitle"
  154. :visible.sync="modalFlag"
  155. width="1012px"
  156. top="4vh"
  157. v-drag
  158. :close-on-click-modal="false"
  159. :showClose="false">
  160. <el-tabs tab-position="left" type="border-card" v-model="activeName" style="width: 100%;height: 770px;">
  161. <!-- 基本信息 -->
  162. <el-tab-pane label="基本信息" name="basicInfo">
  163. <div style="height: 755px">
  164. <el-form :inline="true" label-position="top" :model="modalData" style="margin-top: -5px;">
  165. <el-form-item>
  166. <span style="cursor: pointer" v-if="!isRohsFieldDisabled('applicant')" slot="label" @click="getBaseList(103, 1)"><a herf="#">申请人/Reference No.</a></span>
  167. <span v-else slot="label">申请人/Reference No.</span>
  168. <el-input v-model="modalData.applicant" @blur="applicantBlur(103)" :disabled="isRohsFieldDisabled('applicant')" style="width: 100px"></el-input>
  169. <el-input v-model="modalData.applicantName" disabled style="width: 155px"></el-input>
  170. </el-form-item>
  171. <el-form-item label="申请日期/Date">
  172. <el-date-picker v-model="modalData.applicationDate" type="date" value-format="yyyy-MM-dd" :disabled="isRohsFieldDisabled('applicationDate')" style="width: 150px" :editable=false></el-date-picker>
  173. </el-form-item>
  174. <el-form-item label="Site">
  175. <el-input v-model="modalData.site" disabled style="width: 95px"></el-input>
  176. </el-form-item>
  177. <el-form-item label="工艺/Process">
  178. <dict-data-select v-model="modalData.process" clearable @change="handleProcessChange" :disabled="isProcessFieldDisabled()" style="width: 121px" dict-type="rohs_process"></dict-data-select>
  179. </el-form-item>
  180. </el-form>
  181. <el-form :inline="true" label-position="top" :model="modalData">
  182. <el-form-item>
  183. <span slot="label" v-if="!modalData.endCustomerFlag && !isRohsFieldDisabled('endCustomer')" @click="getBaseList(102, 1)"><a herf="#">最终客户/End Customer</a></span>
  184. <span slot="label" v-else>最终客户/End Customer</span>
  185. <el-input :disabled="modalData.endCustomerFlag || isRohsFieldDisabled('endCustomer')" readonly v-model="modalData.endCustomer" @blur="handleQueryCustomer" style="width: 100px"></el-input>
  186. <el-input disabled v-model="modalData.endCustomerName" style="width: 155px"></el-input>
  187. </el-form-item>
  188. <el-form-item>
  189. <span slot="label" v-if="!modalData.projectIdFlag && !isRohsFieldDisabled('projectId')" @click="chooseProjectListFlag = true"><a herf="#">项目编码/Project</a></span>
  190. <span slot="label" v-else>项目编码/Project</span>
  191. <el-input :disabled="modalData.projectIdFlag || isRohsFieldDisabled('projectId')" readonly v-model="modalData.projectId" @blur="handleQueryProjectByCustomer" style="width: 100px"></el-input>
  192. <el-input disabled v-model="modalData.projectName" style="width: 155px"></el-input>
  193. </el-form-item>
  194. <el-form-item label="WM所需求规格/The size that WM need">
  195. <el-input v-model="modalData.wmRequiredSpec" :disabled="isRohsFieldDisabled('wmRequiredSpec')" style="width: 260px"></el-input>
  196. </el-form-item>
  197. </el-form>
  198. <el-form :inline="true" label-position="top" :model="modalData">
  199. <el-form-item label="供应商/Vendor Code">
  200. <el-input v-model="modalData.vendorCode" :disabled="isRohsFieldDisabled('vendorCode')" style="width: 396px"></el-input>
  201. </el-form-item>
  202. <el-form-item label="供应商材料编码/Vendor Material Code">
  203. <el-input v-model="modalData.vendorMaterialCode" :disabled="isRohsFieldDisabled('vendorMaterialCode')" style="width: 396px"></el-input>
  204. </el-form-item>
  205. </el-form>
  206. <el-form :inline="true" label-position="top" :model="modalData">
  207. <el-form-item label="材料分类/Material Classify">
  208. <dict-data-select class="rohs-multiple-two-rows" v-model="modalData.materialClassifyList" multiple :title="getMultipleSelectTitle(modalData.materialClassifyList)" :disabled="isRohsFieldDisabled('materialClassify')" style="width: 532px" dict-type="rohs_material_classify"></dict-data-select>
  209. </el-form-item>
  210. <el-form-item label="其他分类/Other Material Classify" v-if="modalData.materialClassifyList && modalData.materialClassifyList.includes('Other其他')">
  211. <el-input v-model="modalData.otherMaterialClassify" :disabled="isRohsFieldDisabled('otherMaterialClassify')" style="width: 260px"></el-input>
  212. </el-form-item>
  213. </el-form>
  214. <el-form :inline="true" label-position="top" :model="modalData" style="margin-top: 40px">
  215. <el-form-item label="辅材用途/Assiaccessorial Material Use for">
  216. <el-input v-model="modalData.materialUseFor" :disabled="isRohsFieldDisabled('materialUseFor')" style="width: 259px"></el-input>
  217. </el-form-item>
  218. <el-form-item>
  219. <span style="cursor: pointer" v-if="!isRohsFieldDisabled('technicalPlan')" slot="label" @click="getBaseList(2001, 4)"><a herf="#">技术计划/TP</a></span>
  220. <span v-else slot="label">技术计划/TP</span>
  221. <el-input v-model="modalData.technicalPlan" @blur="technicalPlanBlur(2001)" :disabled="isRohsFieldDisabled('technicalPlan')" style="width: 100px"></el-input>
  222. <el-input v-model="modalData.technicalPlanName" disabled style="width: 155px"></el-input>
  223. </el-form-item>
  224. <el-form-item>
  225. <span style="cursor: pointer" v-if="!isRohsFieldDisabled('pm')" slot="label" @click="getBaseList(2054, 5)"><a herf="#">PM人员/PM</a></span>
  226. <span v-else slot="label">PM人员/PM</span>
  227. <el-input v-model="modalData.pm" @blur="pmBlur(2054)" :disabled="isRohsFieldDisabled('pm')" style="width: 100px"></el-input>
  228. <el-input v-model="modalData.pmName" disabled style="width: 156px"></el-input>
  229. </el-form-item>
  230. </el-form>
  231. <el-form :inline="true" label-position="top" :model="modalData">
  232. <el-form-item label="颜色/Color">
  233. <el-input v-model="modalData.color" :disabled="isRohsFieldDisabled('color')" style="width: 532px"></el-input>
  234. </el-form-item>
  235. <el-form-item label="计划转量产时间/Planned Mass Production Date">
  236. <el-date-picker v-model="modalData.plannedMassProductionDate" type="date" value-format="yyyy-MM-dd" :disabled="isRohsFieldDisabled('plannedMassProductionDate')" style="width: 260px" :editable=false></el-date-picker>
  237. </el-form-item>
  238. </el-form>
  239. <el-form :inline="true" label-position="top" :model="modalData">
  240. <el-form-item>
  241. <span style="cursor: pointer" v-if="!isRohsFieldDisabled('commGroup1')" slot="label" @click="getBaseList(110)"><a herf="#">商品组1/Comm Group 1</a></span>
  242. <span v-else slot="label">商品组1/Comm Group 1</span>
  243. <el-input v-model="modalData.commGroup1" @change="commGroup1Blur(110)" :disabled="isRohsFieldDisabled('commGroup1')" style="width: 100px"></el-input>
  244. <el-input v-model="modalData.commGroup1Desc" disabled style="width: 155px"></el-input>
  245. </el-form-item>
  246. <el-form-item>
  247. <span style="cursor: pointer" v-if="!isRohsFieldDisabled('commGroup2')" slot="label" @click="getBaseList(111)"><a herf="#">商品组2/Comm Group 2</a></span>
  248. <span v-else slot="label">商品组2/Comm Group 2</span>
  249. <el-input v-model="modalData.commGroup2" @change="commGroup2Blur(111)" :disabled="isRohsFieldDisabled('commGroup2')" style="width: 100px"></el-input>
  250. <el-input v-model="modalData.commGroup2Desc" disabled style="width: 155px"></el-input>
  251. </el-form-item>
  252. <el-form-item>
  253. <span style="cursor: pointer" v-if="!isRohsFieldDisabled('commGroup3')" slot="label" @click="getBaseList(130)"><a herf="#">商品组3/Comm Group 3</a></span>
  254. <span v-else slot="label">商品组3/Comm Group 3</span>
  255. <el-input v-model="modalData.commGroup3" @change="commGroup3Blur(130)" :disabled="isRohsFieldDisabled('commGroup3')" style="width: 100px"></el-input>
  256. <el-input v-model="modalData.commGroup3Desc" disabled style="width: 156px"></el-input>
  257. </el-form-item>
  258. </el-form>
  259. <el-form :inline="true" label-position="top" :model="modalData">
  260. <el-form-item label="是否是Fiber材料">
  261. <el-radio-group v-model="modalData.isFiberMaterial" :disabled="isRohsFieldDisabled('isFiberMaterial')" style="width: 145px">
  262. <el-radio label="Y" @click.native.prevent="radioClick('isFiberMaterial', 'Y')"></el-radio>
  263. <el-radio label="N" @click.native.prevent="radioClick('isFiberMaterial', 'N')"></el-radio>
  264. </el-radio-group>
  265. </el-form-item>
  266. <el-form-item label="是否需要创建300/700/900号/Dose Need Create 300/700/900 Number">
  267. <el-radio-group v-model="modalData.needCreateNumber" :disabled="isRohsFieldDisabled('needCreateNumber')" style="width: 374px">
  268. <el-radio label="Y" @click.native.prevent="radioClick('needCreateNumber', 'Y')"></el-radio>
  269. <el-radio label="N" @click.native.prevent="radioClick('needCreateNumber', 'N')"></el-radio>
  270. </el-radio-group>
  271. </el-form-item>
  272. <el-form-item label="材料厚度/Material Thickness">
  273. <el-input v-model="modalData.materialThickness" :disabled="isRohsFieldDisabled('materialThickness')" style="width: 260px"></el-input>
  274. </el-form-item>
  275. </el-form>
  276. <el-form :inline="true" label-position="top" :model="modalData">
  277. <el-form-item>
  278. <span style="cursor: pointer" v-if="!isRohsFieldDisabled('npdEngineer')" slot="label" @click="getBaseList(2001, 3)"><a herf="#">NPD工程师/NPD Engineer</a></span>
  279. <span v-else slot="label">NPD工程师/NPD Engineer</span>
  280. <el-input v-model="modalData.npdEngineer" @blur="npdEngineerBlur(2001)" :disabled="isRohsFieldDisabled('npdEngineer')" style="width: 100px"></el-input>
  281. <el-input v-model="modalData.npdEngineerName" disabled style="width: 155px"></el-input>
  282. </el-form-item>
  283. <el-form-item label="是否需要Deviation/If need deviation or not">
  284. <el-radio-group v-model="modalData.needDeviation" :disabled="isRohsFieldDisabled('needDeviation')" style="width: 259px">
  285. <el-radio label="Y" @click.native.prevent="radioClick('needDeviation', 'Y')"></el-radio>
  286. <el-radio label="N" @click.native.prevent="radioClick('needDeviation', 'N')"></el-radio>
  287. </el-radio-group>
  288. </el-form-item>
  289. <el-form-item label="材料有效期/Material Validity Time">
  290. <dict-data-select v-model="modalData.materialValidityTime" clearable :disabled="isRohsFieldDisabled('materialValidityTime')" style="width: 260px" dict-type="rohs_material_validity_time"></dict-data-select>
  291. </el-form-item>
  292. </el-form>
  293. <el-form :inline="true" label-position="top" :model="modalData">
  294. <el-form-item label="材料有效期备注/Material Validity Time Comments">
  295. <el-input v-model="modalData.materialValidityComments" :disabled="isRohsFieldDisabled('materialValidityComments')" style="width: 259px"></el-input>
  296. </el-form-item>
  297. <el-form-item style="margin-left: -2px">
  298. <span style="cursor: pointer" v-if="!isRohsFieldDisabled('buyer')" slot="label" @click="getBaseList(2000, 2)"><a herf="#">采购/Buyer</a></span>
  299. <span v-else slot="label">采购/Buyer</span>
  300. <el-input v-model="modalData.buyer" @blur="buyerBlur(2000)" :disabled="isRohsFieldDisabled('buyer')" style="width: 100px"></el-input>
  301. <el-input v-model="modalData.buyerName" disabled style="width: 156px"></el-input>
  302. </el-form-item>
  303. <el-form-item label="预计提供报告时间(一个月内)/Expect Date">
  304. <el-date-picker v-model="modalData.expectReportTime" type="date" value-format="yyyy-MM-dd" :disabled="isRohsFieldDisabled('expectReportTime')" style="width: 260px" :editable=false></el-date-picker>
  305. </el-form-item>
  306. </el-form>
  307. <el-form :inline="true" label-position="top" :model="modalData">
  308. <el-form-item label="所需审批文件/Qualification Documents needed" >
  309. <dict-data-select
  310. :key="'qualification-default-' + (modalData.referenceNo || '') + '-' + (isEditMode ? 'edit' : 'add')"
  311. class="rohs-multiple-two-rows"
  312. v-model="modalData.qualificationDocumentsNeededList"
  313. multiple
  314. :use-default-value="!isEditMode"
  315. :use-type-multi-default-value="!isEditMode"
  316. :title="getMultipleSelectTitle(modalData.qualificationDocumentsNeededList)"
  317. :disabled="isRohsFieldDisabled('qualificationDocumentsNeeded')"
  318. style="width: 807px"
  319. dict-type="rohs_qualification_docs">
  320. </dict-data-select>
  321. </el-form-item>
  322. </el-form>
  323. <el-form :inline="true" label-position="top" :model="modalData" style="margin-top: 40px">
  324. <el-form-item label="测试报告必测项/Test Report including items">
  325. <dict-data-select
  326. :key="'test-report-default-' + (modalData.referenceNo || '') + '-' + (isEditMode ? 'edit' : 'add')"
  327. class="rohs-multiple-two-rows"
  328. v-model="modalData.testReportIncludingItemsList"
  329. multiple
  330. :use-default-value="!isEditMode"
  331. :use-type-multi-default-value="!isEditMode"
  332. :title="getMultipleSelectTitle(modalData.testReportIncludingItemsList)"
  333. :disabled="isRohsFieldDisabled('testReportIncludingItems')"
  334. style="width: 807px"
  335. dict-type="rohs_test_report_items">
  336. </dict-data-select>
  337. </el-form-item>
  338. </el-form>
  339. <el-form :inline="true" label-position="top" :model="modalData" style="margin-top: 40px">
  340. <el-form-item style="display: block;">
  341. <template slot="label">
  342. <span>备注说明/Comments</span>
  343. <el-button
  344. v-if="authDataEntry"
  345. style="margin-left: 2px;width: 83px;line-height: 0.5;font-size: 10px;"
  346. type="primary"
  347. @click="openRohsRemarkDialog">备注</el-button>
  348. </template>
  349. <el-input type="textarea" :rows="3" v-model="modalData.remark" :disabled="isRohsFieldDisabled('remark')" resize="none" style="width: 804px;height: 30px"></el-input>
  350. </el-form-item>
  351. </el-form>
  352. </div>
  353. </el-tab-pane>
  354. <!-- NPD 信息 -->
  355. <el-tab-pane label="NPD 信息" name="npdInfo">
  356. <div style="height: 755px; overflow-y: auto;">
  357. <el-form :inline="true" label-position="top" :model="modalData" style="margin-top: -5px;">
  358. <el-form-item label="现有材料不同规格/Same Material Diff Size">
  359. <el-radio-group v-model="modalData.isSameMaterialDiffSize" :disabled="isRohsFieldDisabled('isSameMaterialDiffSize')" style="width: 190px">
  360. <el-radio label="Y" @click.native.prevent="radioClick('isSameMaterialDiffSize', 'Y')"></el-radio>
  361. <el-radio label="N" @click.native.prevent="radioClick('isSameMaterialDiffSize', 'N')"></el-radio>
  362. </el-radio-group>
  363. </el-form-item>
  364. </el-form>
  365. <el-form :inline="true" label-position="top" :model="modalData">
  366. <el-form-item label="材料描述/Material Desc." style="display: block;">
  367. <el-input type="textarea" :rows="3" v-model="modalData.materialDesc" :disabled="isRohsFieldDisabled('materialDesc')" resize="none" style="width: 804px;height: 30px"></el-input>
  368. </el-form-item>
  369. </el-form>
  370. <el-form :inline="true" label-position="top" :model="modalData" style="margin-top: 50px">
  371. <el-form-item label="备注说明/NPD Remark" style="display: block;">
  372. <el-input type="textarea" :rows="3" v-model="modalData.npdRemark" :disabled="isRohsFieldDisabled('npdRemark')" resize="none" style="width: 804px;height: 30px"></el-input>
  373. </el-form-item>
  374. </el-form>
  375. <el-form :inline="true" label-position="top" :model="modalData" style="margin-top: 50px">
  376. <el-form-item label="内部TDS/Inner TDS" style="display: block;">
  377. <oss-components
  378. ref="modalTdsOss"
  379. :save-visible="authFileSave"
  380. :download-visible="authFileDownLoad"
  381. :remove-visible="authFileRemove"
  382. :preview-visible="authFilePreview"
  383. :disabled="showModalFlag || modalData.status === '已完成'"
  384. :enable-upgrade="!showModalFlag && modalData.status !== '已完成'"
  385. :require-file-no-rev="true"
  386. :auto-file-no="true"
  387. :single-upload="true"
  388. :row-click-select="true"
  389. :show-order-ref2="false"
  390. label="序列号"
  391. :height="470"
  392. style="margin-top: 2px"
  393. :columns="tdsFileColumnList"
  394. :order-ref1="modalData.site || ''"
  395. :order-ref2="modalData.referenceNo || ''"
  396. order-ref3="tdsProperty">
  397. </oss-components>
  398. </el-form-item>
  399. </el-form>
  400. </div>
  401. </el-tab-pane>
  402. <!-- HSF 填写信息 -->
  403. <el-tab-pane label="HSF 填写信息" name="hsfInfo">
  404. <div style="height: 755px">
  405. <el-form :inline="true" label-position="top" :model="modalData" style="margin-top: -5px;">
  406. <el-form-item label="SGS报告编号/SGS Report Number">
  407. <el-input v-model="modalData.sgsReportNumber" :disabled="isRohsFieldDisabled('sgsReportNumber')" style="width: 190px"></el-input>
  408. </el-form-item>
  409. <el-form-item label="状态/Status">
  410. <el-select v-model="modalData.rohsStatus" clearable :disabled="isRohsFieldDisabled('rohsStatus')" style="width: 190px">
  411. <el-option label="Active" value="Active"></el-option>
  412. <el-option label="Dead" value="Dead"></el-option>
  413. </el-select>
  414. </el-form-item>
  415. </el-form>
  416. <el-form :inline="true" label-position="top" :model="modalData">
  417. <el-form-item label="报告日期/Expired Date">
  418. <el-date-picker v-model="modalData.expiredDate" type="date" value-format="yyyy-MM-dd" :disabled="isRohsFieldDisabled('expiredDate')" style="width: 190px" :editable=false></el-date-picker>
  419. </el-form-item>
  420. <el-form-item label="有效期数值/Valid Until Value">
  421. <el-input-number
  422. v-model="modalData.validUntilValue"
  423. :controls="false"
  424. :min="0"
  425. :step="1"
  426. :precision="0"
  427. :disabled="isValidUntilValueDisabled()"
  428. style="width: 190px">
  429. </el-input-number>
  430. </el-form-item>
  431. <el-form-item label="有效期单位/Valid Until Unit">
  432. <dict-data-select v-model="modalData.validUntil" clearable :disabled="isValidUntilUnitDisabled()" style="width: 190px" dict-type="rohs_valid_until"></dict-data-select>
  433. </el-form-item>
  434. <el-form-item label="失效日期/Expiry Date">
  435. <el-date-picker v-model="modalData.expiryDate" type="date" value-format="yyyy-MM-dd" disabled style="width: 192px" :editable=false></el-date-picker>
  436. </el-form-item>
  437. </el-form>
  438. <el-form :inline="true" label-position="top" :model="modalData">
  439. <el-form-item label="是否符合RoHS/Meet RoHS Req">
  440. <el-radio-group v-model="modalData.isMeetRohsRequirement" :disabled="isRohsFieldDisabled('isMeetRohsRequirement')" style="width: 190px">
  441. <el-radio label="Y" @click.native.prevent="radioClick('isMeetRohsRequirement', 'Y')"></el-radio>
  442. <el-radio label="N" @click.native.prevent="radioClick('isMeetRohsRequirement', 'N')"></el-radio>
  443. </el-radio-group>
  444. </el-form-item>
  445. <el-form-item label=" ">
  446. <el-checkbox
  447. v-model="modalData.isAhGrade"
  448. true-label="Y"
  449. false-label="N"
  450. :disabled="isRohsFieldDisabled('isAhGrade')"
  451. style="width: 190px">材料属性是否是AH/Is AH Grade</el-checkbox>
  452. </el-form-item>
  453. <el-form-item label="HSF供应商等级/Supplier Class">
  454. <el-radio-group v-model="modalData.hsfSupplierClassification" :disabled="isRohsFieldDisabled('hsfSupplierClassification')" style="width: 200px">
  455. <el-radio label="A类" @click.native.prevent="radioClick('hsfSupplierClassification', 'A类')">A类</el-radio>
  456. <el-radio label="B类" @click.native.prevent="radioClick('hsfSupplierClassification', 'B类')">B类</el-radio>
  457. <el-radio label="C类" @click.native.prevent="radioClick('hsfSupplierClassification', 'C类')">C类</el-radio>
  458. </el-radio-group>
  459. </el-form-item>
  460. </el-form>
  461. <el-form :inline="true" label-position="top" :model="modalData">
  462. <el-form-item label="Fiber报告信息/Fiber Information" style="display: block;">
  463. <el-input type="textarea" :rows="3" v-model="modalData.fiberInformation" :disabled="isRohsFieldDisabled('fiberInformation')" resize="none" style="width: 804px;height: 30px"></el-input>
  464. </el-form-item>
  465. </el-form>
  466. <el-form :inline="true" label-position="top" :model="modalData" style="margin-top: 45px">
  467. <el-form-item>
  468. <span style="cursor: pointer" v-if="!isRohsFieldDisabled('hsfApprover')" slot="label" @click="openHsfApproverChooseModal"><a herf="#">HSF审批人/HSF Approver</a></span>
  469. <span v-else slot="label">HSF审批人/HSF Approver</span>
  470. <el-input
  471. v-model="modalData.hsfApproverName"
  472. readonly
  473. :disabled="isRohsFieldDisabled('hsfApprover')"
  474. style="width: 396px"
  475. placeholder="请选择人员"
  476. @focus="openHsfApproverChooseModal">
  477. <span slot="suffix" v-show="modalData.hsfApproverName && !isRohsFieldDisabled('hsfApprover')" @click.stop="clearHsfApproverSelection">
  478. <i class="el-icon-circle-close" style="margin-left: 5px;cursor: pointer;"></i>
  479. </span>
  480. </el-input>
  481. </el-form-item>
  482. <el-form-item>
  483. <span style="cursor: pointer" v-if="!isRohsFieldDisabled('relatedPeople')" slot="label" @click="openRelatedPeopleChooseModal"><a herf="#">Inform Related people</a></span>
  484. <span v-else slot="label">Inform Related people</span>
  485. <el-input
  486. v-model="modalData.relatedPeopleName"
  487. readonly
  488. :disabled="isRohsFieldDisabled('relatedPeople')"
  489. style="width: 396px"
  490. placeholder="请从HSF审批人中选择"
  491. @focus="openRelatedPeopleChooseModal">
  492. <span slot="suffix" v-show="modalData.relatedPeopleName && !isRohsFieldDisabled('relatedPeople')" @click.stop="clearRelatedPeopleSelection">
  493. <i class="el-icon-circle-close" style="margin-left: 5px;cursor: pointer;"></i>
  494. </span>
  495. </el-input>
  496. </el-form-item>
  497. </el-form>
  498. <el-form v-if="shouldShowHsfStandard(modalData.endCustomer)" :inline="true" label-position="top" :model="modalData" style="margin-top: 0px">
  499. <el-form-item label="HSF标准/HSF Standard" style="display: block;">
  500. <el-input type="textarea" :rows="3" v-model="modalData.hsfStandard" :disabled="isRohsFieldDisabled('hsfStandard')" resize="none" style="width: 804px;height: 30px"></el-input>
  501. </el-form-item>
  502. </el-form>
  503. </div>
  504. </el-tab-pane>
  505. <!-- 材料信息 -->
  506. <el-tab-pane label="材料信息" name="materialInfo">
  507. <div style="height: 755px">
  508. <el-form :inline="true" label-position="top" :model="modalData" style="margin-top: -15px;">
  509. <el-form-item label=" ">
  510. <el-button type="primary" v-if="!showModalFlag && canEditRohsMaterial()" @click="openProjectMaterialDialog">新增材料</el-button>
  511. <el-button type="danger" v-if="!showModalFlag && canEditRohsMaterial()" @click="removeSelectedMaterialRows">删除材料</el-button>
  512. </el-form-item>
  513. </el-form>
  514. <el-table
  515. ref="rohsMaterialTable"
  516. class="rohs-material-table"
  517. border
  518. :data="modalData.materialList"
  519. @selection-change="materialSelectionChange"
  520. :header-cell-style="materialDialogHeaderCellStyle"
  521. :height="705"
  522. style="width: 100%">
  523. <el-table-column type="selection" header-align="center" align="center" width="50"></el-table-column>
  524. <el-table-column type="index" label="序号" width="50" header-align="center" align="center"></el-table-column>
  525. <el-table-column prop="finalPartNo" label="IFS物料编码/Final Part No." min-width="150" header-align="center" align="left" :show-overflow-tooltip="true"></el-table-column>
  526. <el-table-column prop="partDesc" label="描述/Part Desc." min-width="250" header-align="center" align="left" :show-overflow-tooltip="true"></el-table-column>
  527. <el-table-column prop="partStatus" label="状态/Part Status" min-width="100" header-align="center" align="left" :show-overflow-tooltip="true"></el-table-column>
  528. </el-table>
  529. </div>
  530. </el-tab-pane>
  531. <el-tab-pane label="附件信息" name="attachmentInfo">
  532. <div style="height: 755px">
  533. <oss-components
  534. ref="modalAttachmentOss"
  535. :save-visible="authFileSave"
  536. :download-visible="authFileDownLoad"
  537. :remove-visible="authFileRemove"
  538. :preview-visible="authFilePreview"
  539. :row-click-select="true"
  540. :disabled="modalData.status === '已完成'"
  541. label="序列号"
  542. :height="705"
  543. style="margin-top: 2px"
  544. :columns="fileColumnList"
  545. :order-ref1="modalData.site || ''"
  546. :order-ref2="modalData.referenceNo || ''"
  547. order-ref3="rohsAttachment">
  548. </oss-components>
  549. </div>
  550. </el-tab-pane>
  551. </el-tabs>
  552. <el-footer style="height:35px;margin-top: 15px;text-align:center">
  553. <el-button type="primary" v-if="canSaveAction()" @click="dataFormSubmit()">保存</el-button>
  554. <el-button type="primary" @click="handleModalClose">关闭</el-button>
  555. <el-button type="primary" v-if="canAgreeAction()" :loading="submitLoading" @click="agreeSubmit">同意</el-button>
  556. <el-button type="primary" v-if="canRejectAction()" :loading="submitLoading" @click="openRejectModal">驳回</el-button>
  557. </el-footer>
  558. </el-dialog>
  559. <!--选择项目模态框-->
  560. <el-dialog title="选择-项目" :close-on-click-modal="false" @close="closeProjectInfoDialog"
  561. @open="searchProjectInfoList" :visible.sync="chooseProjectListFlag" width="35%">
  562. <el-form label-position="top" :model="searchProjectData" ref="closeProjectInfoForm">
  563. <el-row :gutter="10">
  564. <el-col :span="6">
  565. <el-form-item label="项目号">
  566. <el-input v-model="searchProjectData.projectId"></el-input>
  567. </el-form-item>
  568. </el-col>
  569. <el-col :span="6">
  570. <el-form-item label="项目名称">
  571. <el-input v-model="searchProjectData.projectName"></el-input>
  572. </el-form-item>
  573. </el-col>
  574. <el-col :span="6">
  575. <el-form-item label=" ">
  576. <el-button type="primary" @click="searchProjectInfoList">查询</el-button>
  577. </el-form-item>
  578. </el-col>
  579. </el-row>
  580. <el-table :height="223"
  581. :data="projectList"
  582. border
  583. @row-click="projectClickRow">
  584. <el-table-column label="项目号" prop="projectId"/>
  585. <el-table-column label="项目名称" prop="projectName"/>
  586. </el-table>
  587. </el-form>
  588. <el-footer style="height:35px;margin-top: 10px;text-align:center">
  589. <el-button type="primary" @click="chooseProjectListFlag = false">关闭</el-button>
  590. </el-footer>
  591. </el-dialog>
  592. <el-dialog title="选择物料" top="15vh" width="50%" :close-on-click-modal="false" v-drag :visible.sync="projectMaterialDialogFlag">
  593. <el-form :inline="true" label-position="top" :model="projectMaterialSearchData">
  594. <el-form-item label="IFS物料编码/Final Part No.">
  595. <el-input v-model="projectMaterialSearchData.finalPartNo" clearable style="width: 150px"></el-input>
  596. </el-form-item>
  597. <el-form-item label="描述/Part Desc">
  598. <el-input v-model="projectMaterialSearchData.partDesc" clearable style="width: 200px"></el-input>
  599. </el-form-item>
  600. <el-form-item label="状态/Part Status">
  601. <el-input v-model="projectMaterialSearchData.partStatus" clearable style="width: 100px"></el-input>
  602. </el-form-item>
  603. <el-form-item label=" ">
  604. <el-button type="primary" @click="searchProjectMaterialList">查询</el-button>
  605. </el-form-item>
  606. </el-form>
  607. <el-table
  608. ref="projectMaterialTable"
  609. class="rohs-material-table"
  610. border
  611. v-loading="projectMaterialLoading"
  612. :data="projectMaterialList"
  613. @selection-change="projectMaterialSelectionChange"
  614. :header-cell-style="materialDialogHeaderCellStyle"
  615. :height="320"
  616. style="width: 100%">
  617. <el-table-column type="selection" header-align="center" align="center" width="50"></el-table-column>
  618. <el-table-column prop="finalPartNo" label="IFS物料编码/Final Part No." min-width="120" header-align="center" align="left" :show-overflow-tooltip="true"></el-table-column>
  619. <el-table-column prop="partDesc" label="描述/Part Desc." min-width="250" header-align="center" align="left" :show-overflow-tooltip="true"></el-table-column>
  620. <el-table-column prop="partStatus" label="状态/Part Status" min-width="80" header-align="center" align="left" :show-overflow-tooltip="true"></el-table-column>
  621. </el-table>
  622. <el-pagination
  623. style="margin-top: 10px"
  624. @size-change="projectMaterialSizeChangeHandle"
  625. @current-change="projectMaterialCurrentChangeHandle"
  626. :current-page="projectMaterialPageIndex"
  627. :page-sizes="[20, 50, 100]"
  628. :page-size="projectMaterialPageSize"
  629. :total="projectMaterialTotal"
  630. layout="total, sizes, prev, pager, next, jumper">
  631. </el-pagination>
  632. <el-footer style="height:35px;margin-top: 10px;text-align:center">
  633. <el-button type="primary" @click="confirmProjectMaterialSelection">确定</el-button>
  634. <el-button type="primary" @click="projectMaterialDialogFlag = false">关闭</el-button>
  635. </el-footer>
  636. </el-dialog>
  637. <el-dialog title="人员选择" @open="openHsfApproverDialog" @close="closeHsfApproverDialog" v-drag
  638. :visible.sync="hsfApproverFlag" width="40vw" :close-on-click-modal="false">
  639. <el-form :inline="true" label-position="top" :model="hsfApproverSearchData">
  640. <el-form-item label="编码">
  641. <el-input v-model="hsfApproverSearchData.operatorId" clearable style="width: 120px"></el-input>
  642. </el-form-item>
  643. <el-form-item label="名称">
  644. <el-input v-model="hsfApproverSearchData.operatorName" clearable style="width: 120px"></el-input>
  645. </el-form-item>
  646. <el-form-item label=" ">
  647. <el-button type="primary" @click="filterHsfApproverOptions">查询</el-button>
  648. </el-form-item>
  649. </el-form>
  650. <el-table v-if="hsfApproverFlag"
  651. :height="300"
  652. :data="hsfApproverDisplayList"
  653. @selection-change="handleHsfApproverSelectionChange"
  654. @row-click="(row,column,event) => handleHsfApproverTableClick(row,column,event,'hsfApproverTable')"
  655. ref="hsfApproverTable"
  656. border row-key="operatorId"
  657. style="width: 100%;">
  658. <el-table-column
  659. type="selection"
  660. header-align="center"
  661. align="center"
  662. :reserve-selection="true"
  663. width="50">
  664. </el-table-column>
  665. <el-table-column label="编码" property="operatorId" align="left" header-align="center"/>
  666. <el-table-column label="名称" property="operatorName" align="left" header-align="center"/>
  667. </el-table>
  668. <el-footer style="height:40px;margin-top: 20px;text-align:center">
  669. <el-button type="primary" @click="saveHsfApproverChooseModal">确定</el-button>
  670. <el-button type="primary" @click="hsfApproverFlag = false">关闭</el-button>
  671. </el-footer>
  672. </el-dialog>
  673. <el-dialog title="人员选择" @open="openRelatedPeopleDialog" @close="closeRelatedPeopleDialog" v-drag
  674. :visible.sync="relatedPeopleFlag" width="40vw" :close-on-click-modal="false">
  675. <el-form :inline="true" label-position="top" :model="relatedPeopleSearchData">
  676. <el-form-item label="编码">
  677. <el-input v-model="relatedPeopleSearchData.operatorId" clearable style="width: 120px"></el-input>
  678. </el-form-item>
  679. <el-form-item label="名称">
  680. <el-input v-model="relatedPeopleSearchData.operatorName" clearable style="width: 120px"></el-input>
  681. </el-form-item>
  682. <el-form-item label=" ">
  683. <el-button type="primary" @click="filterRelatedPeopleOptions">查询</el-button>
  684. </el-form-item>
  685. </el-form>
  686. <el-table v-if="relatedPeopleFlag"
  687. :height="300"
  688. :data="relatedPeopleDisplayList"
  689. highlight-current-row
  690. @current-change="handleRelatedPeopleCurrentChange"
  691. @row-click="handleRelatedPeopleTableClick"
  692. ref="relatedPeopleTable"
  693. border
  694. style="width: 100%;">
  695. <el-table-column label="编码" property="operatorId" align="left" header-align="center"/>
  696. <el-table-column label="名称" property="operatorName" align="left" header-align="center"/>
  697. </el-table>
  698. <el-footer style="height:40px;margin-top: 20px;text-align:center">
  699. <el-button type="primary" @click="saveRelatedPeopleChooseModal">确定</el-button>
  700. <el-button type="primary" @click="relatedPeopleFlag = false">关闭</el-button>
  701. </el-footer>
  702. </el-dialog>
  703. <el-dialog title="驳回" top="30vh" :close-on-click-modal="false" v-drag :visible.sync="submitModalFlag" width="500px">
  704. <el-form label-position="top">
  705. <el-form-item label="驳回意见/Reject Opinion">
  706. <el-input type="textarea" v-model="rejectOpinion" :rows="3" resize="none" show-word-limit style="width: 479px;height: 30px"></el-input>
  707. </el-form-item>
  708. </el-form>
  709. <el-footer style="height:35px;margin-top:50px;text-align:center">
  710. <el-button type="primary" :loading="submitLoading" @click="rejectSubmit">确定</el-button>
  711. <el-button type="primary" @click="submitModalFlag = false">取消</el-button>
  712. </el-footer>
  713. </el-dialog>
  714. <el-dialog width="700px" title="备注" :close-on-click-modal="false" :visible.sync="rohsRemarkFlag" v-drag>
  715. <el-form label-position="top">
  716. <el-form-item label="备注说明">
  717. <el-input
  718. type="textarea"
  719. v-model="rohsRemarkForm.remark"
  720. :rows="6"
  721. maxlength="255"
  722. show-word-limit
  723. resize="none">
  724. </el-input>
  725. </el-form-item>
  726. </el-form>
  727. <el-footer style="height:35px;margin-top:110px;text-align:center">
  728. <el-button type="primary" @click="refreshRohsRemark">刷新</el-button>
  729. <el-button type="primary" @click="saveRohsRemark">保存</el-button>
  730. <el-button type="primary" @click="rohsRemarkFlag = false">取消</el-button>
  731. </el-footer>
  732. </el-dialog>
  733. <!-- 底部附件页签 -->
  734. <el-tabs v-model="activeTable" style="width: 100%; height: 100%;" type="border-card" @tab-click="refreshCurrentTabTable" class="customer-tab">
  735. <el-tab-pane label="基本信息" name="basicInfo">
  736. <div :style="{height: secondHeight + 'px'}" style="margin-left: 5px;margin-top: 5px; overflow-y: auto;">
  737. <el-form :inline="true" label-position="top" :model="currentRow">
  738. <el-form-item>
  739. <span slot="label">申请人/Reference No.</span>
  740. <el-input :value="currentRow.applicant || ''" disabled style="width: 100px"></el-input>
  741. <el-input :value="currentRow.applicantName || ''" disabled style="width: 155px"></el-input>
  742. </el-form-item>
  743. <el-form-item label="申请日期/Date">
  744. <el-date-picker :value="currentRow.applicationDate" disabled type="date" value-format="yyyy-MM-dd" style="width: 150px"></el-date-picker>
  745. </el-form-item>
  746. <el-form-item label="Site">
  747. <el-input :value="currentRow.site || ''" disabled style="width: 95px"></el-input>
  748. </el-form-item>
  749. <el-form-item label="工艺/Process">
  750. <el-input :value="currentRow.process || ''" disabled style="width: 121px"></el-input>
  751. </el-form-item>
  752. </el-form>
  753. <el-form :inline="true" label-position="top" :model="currentRow">
  754. <el-form-item>
  755. <span slot="label">最终客户/End Customer</span>
  756. <el-input :value="currentRow.endCustomer || ''" disabled style="width: 100px"></el-input>
  757. <el-input :value="currentRow.endCustomerName || ''" disabled style="width: 155px"></el-input>
  758. </el-form-item>
  759. <el-form-item>
  760. <span slot="label">项目编码/Project</span>
  761. <el-input :value="currentRow.projectId || ''" disabled style="width: 100px"></el-input>
  762. <el-input :value="currentRow.projectName || ''" disabled style="width: 155px"></el-input>
  763. </el-form-item>
  764. <el-form-item label="WM所需求规格/The size that WM need">
  765. <el-input :value="currentRow.wmRequiredSpec || ''" disabled style="width: 260px"></el-input>
  766. </el-form-item>
  767. </el-form>
  768. <el-form :inline="true" label-position="top" :model="currentRow">
  769. <el-form-item label="供应商/Vendor Code">
  770. <el-input :value="currentRow.vendorCode || ''" disabled style="width: 396px"></el-input>
  771. </el-form-item>
  772. <el-form-item label="供应商材料编码/Vendor Material Code">
  773. <el-input :value="currentRow.vendorMaterialCode || ''" disabled style="width: 396px"></el-input>
  774. </el-form-item>
  775. </el-form>
  776. <el-form :inline="true" label-position="top" :model="currentRow">
  777. <el-form-item label="材料分类/Material Classify">
  778. <el-input type="textarea" :rows="2" resize="none" :value="currentRow.materialClassify || ''" disabled style="width: 532px"></el-input>
  779. </el-form-item>
  780. <el-form-item label="其他分类/Other Material Classify" v-if="currentRow.materialClassify && currentRow.materialClassify.includes('Other其他')">
  781. <el-input :value="currentRow.otherMaterialClassify || ''" disabled style="width: 260px"></el-input>
  782. </el-form-item>
  783. </el-form>
  784. <el-form :inline="true" label-position="top" :model="currentRow" style="margin-top: 30px">
  785. <el-form-item label="辅材用途/Assiaccessorial Material Use for">
  786. <el-input :value="currentRow.materialUseFor || ''" disabled style="width: 259px"></el-input>
  787. </el-form-item>
  788. <el-form-item>
  789. <span slot="label">技术计划/TP</span>
  790. <el-input :value="currentRow.technicalPlan || ''" disabled style="width: 100px"></el-input>
  791. <el-input :value="currentRow.technicalPlanName || ''" disabled style="width: 155px"></el-input>
  792. </el-form-item>
  793. <el-form-item>
  794. <span slot="label">PM人员/PM</span>
  795. <el-input :value="currentRow.pm || ''" disabled style="width: 100px"></el-input>
  796. <el-input :value="currentRow.pmName || ''" disabled style="width: 156px"></el-input>
  797. </el-form-item>
  798. </el-form>
  799. <el-form :inline="true" label-position="top" :model="currentRow">
  800. <el-form-item label="颜色/Color">
  801. <el-input :value="currentRow.color || ''" disabled style="width: 532px"></el-input>
  802. </el-form-item>
  803. <el-form-item label="计划转量产时间/Planned Mass Production Date">
  804. <el-date-picker :value="normalizeDateOnly(currentRow.plannedMassProductionDate)" disabled type="date" value-format="yyyy-MM-dd" style="width: 260px"></el-date-picker>
  805. </el-form-item>
  806. </el-form>
  807. <el-form :inline="true" label-position="top" :model="currentRow">
  808. <el-form-item>
  809. <span slot="label">商品组1/Comm Group 1</span>
  810. <el-input :value="currentRow.commGroup1 || ''" disabled style="width: 100px"></el-input>
  811. <el-input :value="currentRow.commGroup1Desc || ''" disabled style="width: 155px"></el-input>
  812. </el-form-item>
  813. <el-form-item>
  814. <span slot="label">商品组2/Comm Group 2</span>
  815. <el-input :value="currentRow.commGroup2 || ''" disabled style="width: 100px"></el-input>
  816. <el-input :value="currentRow.commGroup2Desc || ''" disabled style="width: 155px"></el-input>
  817. </el-form-item>
  818. <el-form-item>
  819. <span slot="label">商品组3/Comm Group 3</span>
  820. <el-input :value="currentRow.commGroup3 || ''" disabled style="width: 100px"></el-input>
  821. <el-input :value="currentRow.commGroup3Desc || ''" disabled style="width: 156px"></el-input>
  822. </el-form-item>
  823. </el-form>
  824. <el-form :inline="true" label-position="top" :model="currentRow">
  825. <el-form-item label="是否是Fiber材料">
  826. <el-radio-group :value="currentRow.isFiberMaterial" disabled style="width: 145px">
  827. <el-radio label="Y"></el-radio>
  828. <el-radio label="N"></el-radio>
  829. </el-radio-group>
  830. </el-form-item>
  831. <el-form-item label="是否需要创建300/700/900号/Dose Need Create 300/700/900 Number">
  832. <el-radio-group :value="currentRow.needCreateNumber" disabled style="width: 374px">
  833. <el-radio label="Y"></el-radio>
  834. <el-radio label="N"></el-radio>
  835. </el-radio-group>
  836. </el-form-item>
  837. <el-form-item label="材料厚度/Material Thickness">
  838. <el-input :value="currentRow.materialThickness || ''" disabled style="width: 260px"></el-input>
  839. </el-form-item>
  840. </el-form>
  841. <el-form :inline="true" label-position="top" :model="currentRow">
  842. <el-form-item>
  843. <span slot="label">NPD工程师/NPD Engineer</span>
  844. <el-input :value="currentRow.npdEngineer || ''" disabled style="width: 100px"></el-input>
  845. <el-input :value="currentRow.npdEngineerName || ''" disabled style="width: 155px"></el-input>
  846. </el-form-item>
  847. <el-form-item label="是否需要Deviation/If need deviation or not">
  848. <el-radio-group :value="currentRow.needDeviation" disabled style="width: 259px">
  849. <el-radio label="Y"></el-radio>
  850. <el-radio label="N"></el-radio>
  851. </el-radio-group>
  852. </el-form-item>
  853. <el-form-item label="材料有效期/Material Validity Time">
  854. <dict-data-select :value="currentRow.materialValidityTime || ''" :use-default-value="false" disabled style="width: 260px" dict-type="rohs_material_validity_time"></dict-data-select>
  855. </el-form-item>
  856. </el-form>
  857. <el-form :inline="true" label-position="top" :model="currentRow">
  858. <el-form-item label="材料有效期备注/Material Validity Time Comments">
  859. <el-input :value="currentRow.materialValidityComments || ''" disabled style="width: 259px"></el-input>
  860. </el-form-item>
  861. <el-form-item style="margin-left: -2px">
  862. <span slot="label">采购/Buyer</span>
  863. <el-input :value="currentRow.buyer || ''" disabled style="width: 100px"></el-input>
  864. <el-input :value="currentRow.buyerName || ''" disabled style="width: 156px"></el-input>
  865. </el-form-item>
  866. <el-form-item label="预计提供报告时间(一个月内)/Expect Date">
  867. <el-date-picker :value="normalizeDateOnly(currentRow.expectReportTime)" disabled type="date" value-format="yyyy-MM-dd" style="width: 260px"></el-date-picker>
  868. </el-form-item>
  869. </el-form>
  870. <el-form :inline="true" label-position="top" :model="currentRow">
  871. <el-form-item label="所需审批文件/Qualification Documents needed">
  872. <el-input type="textarea" :rows="2" resize="none" :value="currentRow.qualificationDocumentsNeeded || ''" disabled style="width: 807px"></el-input>
  873. </el-form-item>
  874. </el-form>
  875. <el-form :inline="true" label-position="top" :model="currentRow" style="margin-top: 30px">
  876. <el-form-item label="测试报告必测项/Test Report including items">
  877. <el-input type="textarea" :rows="2" resize="none" :value="currentRow.testReportIncludingItems || ''" disabled style="width: 807px"></el-input>
  878. </el-form-item>
  879. </el-form>
  880. <el-form :inline="true" label-position="top" :model="currentRow" style="margin-top: 30px">
  881. <el-form-item label="备注说明/Comments" style="display: block;">
  882. <el-input type="textarea" :rows="3" :value="currentRow.remark || ''" disabled resize="none" style="width: 804px;height: 30px"></el-input>
  883. </el-form-item>
  884. </el-form>
  885. </div>
  886. </el-tab-pane>
  887. <el-tab-pane label="NPD 信息" name="npdInfo">
  888. <div :style="{height: secondHeight + 'px'}" style="margin-left: 5px;margin-top: 5px; overflow-y: auto;">
  889. <el-form :inline="true" label-position="top" :model="currentRow">
  890. <el-form-item label="现有材料不同规格/Same Material Diff Size">
  891. <el-radio-group :value="currentRow.isSameMaterialDiffSize" disabled style="width: 190px">
  892. <el-radio label="Y"></el-radio>
  893. <el-radio label="N"></el-radio>
  894. </el-radio-group>
  895. </el-form-item>
  896. </el-form>
  897. <el-form :inline="true" label-position="top" :model="currentRow">
  898. <el-form-item label="材料描述/Material Desc." style="display: block;"><el-input type="textarea" :rows="3" :value="currentRow.materialDesc || ''" disabled resize="none" style="width: 804px;height: 30px"></el-input></el-form-item>
  899. </el-form>
  900. <el-form :inline="true" label-position="top" :model="currentRow" style="margin-top: 50px">
  901. <el-form-item label="备注说明/NPD Remark" style="display: block;"><el-input type="textarea" :rows="3" :value="currentRow.npdRemark || ''" disabled resize="none" style="width: 804px;height: 30px"></el-input></el-form-item>
  902. </el-form>
  903. <el-form :inline="true" label-position="top" :model="currentRow" style="margin-top: 50px">
  904. <el-form-item label="内部TDS/Inner TDS" style="display: block;">
  905. <oss-components
  906. ref="bottomTdsOss"
  907. :save-visible="authFileSave"
  908. :download-visible="authFileDownLoad"
  909. :remove-visible="authFileRemove"
  910. :preview-visible="authFilePreview"
  911. :disabled="true"
  912. label="序列号"
  913. :height="180"
  914. style="margin-top: 2px"
  915. :columns="tdsFileColumnList"
  916. :order-ref1="currentRow.site || ''"
  917. :order-ref2="currentRow.referenceNo || ''"
  918. order-ref3="tdsProperty">
  919. </oss-components>
  920. </el-form-item>
  921. </el-form>
  922. </div>
  923. </el-tab-pane>
  924. <el-tab-pane label="HSF 填写信息" name="hsfInfo">
  925. <div :style="{height: secondHeight + 'px'}" style="margin-left: 5px;margin-top: 5px; overflow-y: auto;">
  926. <el-form :inline="true" label-position="top" :model="currentRow">
  927. <el-form-item label="SGS报告编号/SGS Report Number">
  928. <el-input :value="currentRow.sgsReportNumber || ''" disabled style="width: 190px"></el-input>
  929. </el-form-item>
  930. <el-form-item label="状态/Status">
  931. <el-input :value="currentRow.rohsStatus || ''" disabled style="width: 190px"></el-input>
  932. </el-form-item>
  933. </el-form>
  934. <el-form :inline="true" label-position="top" :model="currentRow">
  935. <el-form-item label="报告日期/Expired Date">
  936. <el-date-picker :value="currentRow.expiredDate" disabled type="date" value-format="yyyy-MM-dd" style="width: 190px"></el-date-picker>
  937. </el-form-item>
  938. <el-form-item label="有效期数值/Valid Until Value">
  939. <el-input :value="currentRow.validUntilValue || ''" disabled style="width: 190px"></el-input>
  940. </el-form-item>
  941. <el-form-item label="有效期单位/Valid Until Unit">
  942. <el-input :value="currentRow.validUntil || ''" disabled style="width: 190px"></el-input>
  943. </el-form-item>
  944. <el-form-item label="失效日期/Expiry Date">
  945. <el-date-picker :value="currentRow.expiryDate" disabled type="date" value-format="yyyy-MM-dd" style="width: 192px"></el-date-picker>
  946. </el-form-item>
  947. </el-form>
  948. <el-form :inline="true" label-position="top" :model="currentRow">
  949. <el-form-item label="是否符合RoHS/Meet RoHS Req">
  950. <el-radio-group :value="currentRow.isMeetRohsRequirement" disabled style="width: 190px">
  951. <el-radio label="Y"></el-radio>
  952. <el-radio label="N"></el-radio>
  953. </el-radio-group>
  954. </el-form-item>
  955. <el-form-item label=" ">
  956. <el-checkbox
  957. :value="currentRow.isAhGrade"
  958. true-label="Y"
  959. false-label="N"
  960. disabled
  961. style="width: 190px">材料属性是否是AH/Is AH Grade</el-checkbox>
  962. </el-form-item>
  963. <el-form-item label="HSF供应商等级/Supplier Class">
  964. <el-radio-group :value="currentRow.hsfSupplierClassification" disabled style="width: 200px">
  965. <el-radio label="A类">A类</el-radio>
  966. <el-radio label="B类">B类</el-radio>
  967. <el-radio label="C类">C类</el-radio>
  968. </el-radio-group>
  969. </el-form-item>
  970. </el-form>
  971. <el-form :inline="true" label-position="top" :model="currentRow">
  972. <el-form-item label="Fiber报告信息/Fiber Information" style="display: block;"><el-input type="textarea" :rows="3" :value="currentRow.fiberInformation || ''" disabled resize="none" style="width: 804px;height: 30px"></el-input></el-form-item>
  973. </el-form>
  974. <el-form :inline="true" label-position="top" :model="currentRow" style="margin-top: 45px">
  975. <el-form-item label="HSF审批人/HSF Approver"><el-input :value="currentRow.hsfApproverName || currentRow.hsfApprover || ''" disabled style="width: 396px"></el-input></el-form-item>
  976. <el-form-item label="Inform Related people"><el-input :value="currentRow.relatedPeopleName || currentRow.relatedPeople || ''" disabled style="width: 396px"></el-input></el-form-item>
  977. </el-form>
  978. <el-form v-if="shouldShowHsfStandard(currentRow.endCustomer)" :inline="true" label-position="top" :model="currentRow" style="margin-top: 0px">
  979. <el-form-item label="HSF标准/HSF Standard" style="display: block;"><el-input type="textarea" :rows="3" :value="currentRow.hsfStandard || ''" disabled resize="none" style="width: 804px;height: 30px"></el-input></el-form-item>
  980. </el-form>
  981. </div>
  982. </el-tab-pane>
  983. <el-tab-pane label="材料信息" name="materialInfo">
  984. <div :style="{height: secondHeight + 'px'}" style="overflow-y: auto;">
  985. <el-table
  986. class="rohs-material-table"
  987. border
  988. :data="currentRow.materialList || []"
  989. :height="secondHeight"
  990. style="width: 100%">
  991. <el-table-column type="index" label="序号" width="50" header-align="center" align="center"></el-table-column>
  992. <el-table-column prop="finalPartNo" label="IFS物料编码/Final Part No." min-width="150" header-align="center" align="left" :show-overflow-tooltip="true"></el-table-column>
  993. <el-table-column prop="partDesc" label="描述/Part Desc." min-width="250" header-align="center" align="left" :show-overflow-tooltip="true"></el-table-column>
  994. <el-table-column prop="partStatus" label="状态/Part Status" min-width="100" header-align="center" align="left" :show-overflow-tooltip="true"></el-table-column>
  995. </el-table>
  996. </div>
  997. </el-tab-pane>
  998. <el-tab-pane label="附件信息" name="attachment">
  999. <oss-components
  1000. ref="bottomAttachmentOss"
  1001. :save-visible="authFileSave"
  1002. :download-visible="authFileDownLoad"
  1003. :remove-visible="authFileRemove"
  1004. :preview-visible="authFilePreview"
  1005. :disabled="currentRow.status === '已完成'"
  1006. label="序列号"
  1007. :height="secondHeight - 25"
  1008. style="margin-top: 2px"
  1009. :columns="fileColumnList"
  1010. :order-ref1="currentRow.site"
  1011. :order-ref2="currentRow.referenceNo"
  1012. order-ref3="rohsAttachment">
  1013. </oss-components>
  1014. </el-tab-pane>
  1015. <el-tab-pane label="审批信息" name="approvalInformation">
  1016. <approval-information v-model:data-list="approvalList" :height="secondHeight"></approval-information>
  1017. </el-tab-pane>
  1018. </el-tabs>
  1019. <ChooseList ref="baseList" @getBaseData="getBaseData"></ChooseList>
  1020. <filter-search :visible.sync="filterVisible" @search="queryByAnyField"></filter-search>
  1021. </div>
  1022. </template>
  1023. <script>
  1024. import * as api from '@/api/rohs/rohs'
  1025. import { checkSuperAdmin } from "@/api/changeManagement/changeManagement"
  1026. import { verifyData } from "@/api/chooselist/chooselist.js"
  1027. import { searchProjectInfoList } from "@/api/quotation/quotationInformation.js"
  1028. import { queryCustomer } from "@/api/customer/customerInformation"
  1029. import { queryProjectByCustomer } from "@/api/project/project"
  1030. import uploadFileList from '../common/uploadFileList'
  1031. import ossComponents from '../oss/ossComponents.vue'
  1032. import ChooseList from '@/views/modules/common/Chooselist'
  1033. import DictDataSelect from "../sys/dict-data-select.vue"
  1034. import ApprovalInformation from "../changeManagement/approvalInformation.vue"
  1035. import FilterSearch from "../../common/filterSearch.vue"
  1036. export default {
  1037. components: {
  1038. uploadFileList,
  1039. ossComponents,
  1040. ChooseList,
  1041. DictDataSelect,
  1042. ApprovalInformation,
  1043. FilterSearch
  1044. },
  1045. data () {
  1046. return {
  1047. searchData: {
  1048. site: this.$store.state.user.site,
  1049. referenceNo: '',
  1050. status: '',
  1051. currentApprover: '',
  1052. nodeId: ''
  1053. },
  1054. exportLoading: false,
  1055. exportData: [],
  1056. exportFieldMap: {},
  1057. exportName: '',
  1058. exportHeader: ['RoHs记录'],
  1059. exportFooter: [],
  1060. resultList: [],
  1061. dataList: [],
  1062. pageIndex: 1,
  1063. pageSize: 20,
  1064. totalPage: 0,
  1065. dataListLoading: false,
  1066. activeTable: 'basicInfo',
  1067. menuId: '112001',
  1068. authSearch: false,
  1069. authUpdate: false,
  1070. authIssue: false,
  1071. authSubmit: false,
  1072. authReject: false,
  1073. authFileSave: false,
  1074. authFileDownLoad: false,
  1075. authFileRemove: false,
  1076. authFilePreview: false,
  1077. authDataEntry: false,
  1078. authDelete: false,
  1079. superAdmin: false,
  1080. createBy2: this.$store.state.user.name,
  1081. height: 400,
  1082. secondHeight: 200,
  1083. currentRow: {},
  1084. fileColumnList: [
  1085. {
  1086. columnProp: 'fileName',
  1087. headerAlign: 'center',
  1088. align: 'center',
  1089. columnLabel: '文件名称',
  1090. columnHidden: false,
  1091. columnImage: false,
  1092. columnSortable: false,
  1093. status: true,
  1094. fixed: '',
  1095. columnWidth: 140
  1096. },
  1097. {
  1098. columnProp: 'fileRemark',
  1099. headerAlign: 'center',
  1100. align: 'center',
  1101. columnLabel: '备注',
  1102. columnHidden: false,
  1103. columnImage: false,
  1104. columnSortable: false,
  1105. status: true,
  1106. fixed: '',
  1107. columnWidth: 200
  1108. },
  1109. {
  1110. columnProp: 'createDate',
  1111. headerAlign: 'center',
  1112. align: 'center',
  1113. columnLabel: '上传时间',
  1114. columnHidden: false,
  1115. columnImage: false,
  1116. columnSortable: false,
  1117. status: true,
  1118. fixed: '',
  1119. columnWidth: 150
  1120. },
  1121. {
  1122. columnProp: 'createBy',
  1123. headerAlign: 'center',
  1124. align: 'center',
  1125. columnLabel: '上传人',
  1126. columnHidden: false,
  1127. columnImage: false,
  1128. columnSortable: false,
  1129. status: true,
  1130. fixed: '',
  1131. columnWidth: 120
  1132. }
  1133. ],
  1134. tdsFileColumnList: [
  1135. {
  1136. columnProp: 'fileNo',
  1137. headerAlign: 'center',
  1138. align: 'center',
  1139. columnLabel: '文件编码',
  1140. columnHidden: false,
  1141. columnImage: false,
  1142. columnSortable: false,
  1143. status: true,
  1144. fixed: '',
  1145. columnWidth: 130
  1146. },
  1147. {
  1148. columnProp: 'rev',
  1149. headerAlign: 'center',
  1150. align: 'center',
  1151. columnLabel: '版本号',
  1152. columnHidden: false,
  1153. columnImage: false,
  1154. columnSortable: false,
  1155. status: true,
  1156. fixed: '',
  1157. columnWidth: 90
  1158. },
  1159. {
  1160. columnProp: 'fileName',
  1161. headerAlign: 'center',
  1162. align: 'center',
  1163. columnLabel: '文件名称',
  1164. columnHidden: false,
  1165. columnImage: false,
  1166. columnSortable: false,
  1167. status: true,
  1168. fixed: '',
  1169. columnWidth: 160
  1170. },
  1171. {
  1172. columnProp: 'fileRemark',
  1173. headerAlign: 'center',
  1174. align: 'center',
  1175. columnLabel: '备注',
  1176. columnHidden: false,
  1177. columnImage: false,
  1178. columnSortable: false,
  1179. status: true,
  1180. fixed: '',
  1181. columnWidth: 180
  1182. },
  1183. {
  1184. columnProp: 'createDate',
  1185. headerAlign: 'center',
  1186. align: 'center',
  1187. columnLabel: '上传时间',
  1188. columnHidden: false,
  1189. columnImage: false,
  1190. columnSortable: false,
  1191. status: true,
  1192. fixed: '',
  1193. columnWidth: 150
  1194. },
  1195. {
  1196. columnProp: 'invalidationTime',
  1197. headerAlign: 'center',
  1198. align: 'center',
  1199. columnLabel: '失效时间',
  1200. columnHidden: false,
  1201. columnImage: false,
  1202. columnSortable: false,
  1203. status: true,
  1204. fixed: '',
  1205. columnWidth: 150
  1206. },
  1207. {
  1208. columnProp: 'createBy',
  1209. headerAlign: 'center',
  1210. align: 'center',
  1211. columnLabel: '上传人',
  1212. columnHidden: false,
  1213. columnImage: false,
  1214. columnSortable: false,
  1215. status: true,
  1216. fixed: '',
  1217. columnWidth: 120
  1218. }
  1219. ],
  1220. modalFlag: false,
  1221. chooseProjectListFlag: false,
  1222. projectMaterialDialogFlag: false,
  1223. searchProjectData: {
  1224. site: '',
  1225. projectId: undefined,
  1226. projectName: undefined,
  1227. customerId: undefined,
  1228. },
  1229. projectMaterialSearchData: {
  1230. finalPartNo: '',
  1231. partDesc: '',
  1232. partStatus: ''
  1233. },
  1234. projectMaterialList: [],
  1235. projectMaterialSelections: [],
  1236. dataListSelections: [],
  1237. materialSelections: [],
  1238. projectMaterialPageIndex: 1,
  1239. projectMaterialPageSize: 20,
  1240. projectMaterialTotal: 0,
  1241. projectMaterialLoading: false,
  1242. nodeOptions: [],
  1243. projectList: [],
  1244. hsfApproverOptionList: [],
  1245. hsfApproverDisplayList: [],
  1246. hsfApproverSelectionCache: [],
  1247. hsfApproverFlag: false,
  1248. hsfApproverSearchData: {
  1249. operatorId: '',
  1250. operatorName: ''
  1251. },
  1252. relatedPeopleOptionList: [],
  1253. relatedPeopleDisplayList: [],
  1254. relatedPeopleSelection: null,
  1255. relatedPeopleFlag: false,
  1256. relatedPeopleSearchData: {
  1257. operatorId: '',
  1258. operatorName: ''
  1259. },
  1260. filterVisible: false,
  1261. isFilterSearch: false,
  1262. filterSearchData: {},
  1263. approvalList: [],
  1264. plmRohsAuthorityArr: [],
  1265. nodeAuthorityLoaded: false,
  1266. isEditMode: false,
  1267. modalTitle: 'RoHS 新增',
  1268. activeName: 'basicInfo',
  1269. showModalFlag: false,
  1270. submitModalFlag: false,
  1271. rohsRemarkFlag: false,
  1272. rejectOpinion: '',
  1273. submitLoading: false,
  1274. rohsRemarkForm: {
  1275. remark: ''
  1276. },
  1277. hsfStandardDefaultText: 'With the follow environmental specification: Macallan regulated Substances specification(069-0135) /Macallan sustainable fiber specification(099-00532)',
  1278. modalData: {
  1279. site: 'DEFAULT',
  1280. referenceNo: '',
  1281. applicant: '',
  1282. pm: '',
  1283. pmName: '',
  1284. applicationDate: '',
  1285. process: '',
  1286. plannedMassProductionDate: '',
  1287. color: '',
  1288. vendorCode: '',
  1289. vendorMaterialCode: '',
  1290. materialClassify: '',
  1291. otherMaterialClassify: '',
  1292. materialUseFor: '',
  1293. endCustomer: '',
  1294. projectId: '',
  1295. commGroup1: '',
  1296. commGroup1Desc: '',
  1297. commGroup2: '',
  1298. commGroup2Desc: '',
  1299. commGroup3: '',
  1300. commGroup3Desc: '',
  1301. needCreateNumber: '',
  1302. npdEngineer: '',
  1303. materialValidityTime: '',
  1304. materialValidityComments: '',
  1305. needDeviation: '',
  1306. technicalPlan: '',
  1307. wmRequiredSpec: '',
  1308. isFiberMaterial: '',
  1309. materialThickness: '',
  1310. buyer: '',
  1311. expectReportTime: '',
  1312. qualificationDocumentsNeeded: '',
  1313. qualificationDocumentsNeededList: [],
  1314. testReportIncludingItems: '',
  1315. testReportIncludingItemsList: [],
  1316. remark: '',
  1317. status: '',
  1318. sgsReportNumber: '',
  1319. rohsStatus: 'Active',
  1320. expiredDate: '',
  1321. expiryDate: '',
  1322. fiberInformation: '',
  1323. hsfStandard: '',
  1324. hsfApprover: '',
  1325. hsfApproverName: '',
  1326. hsfApproverCodeList: [],
  1327. relatedPeople: '',
  1328. relatedPeopleName: '',
  1329. buNo: '',
  1330. validUntilValue: 0,
  1331. validUntil: '',
  1332. isMeetRohsRequirement: '',
  1333. isAhGrade: 'N',
  1334. hsfSupplierClassification: '',
  1335. materialDesc: '',
  1336. npdRemark: '',
  1337. isSameMaterialDiffSize: '',
  1338. ifsPartNo: '',
  1339. materialList: [],
  1340. stepId: null,
  1341. rejectFlag: '',
  1342. rejectStepId: null,
  1343. createBy2: '',
  1344. isReject: 'Y',
  1345. tpProcessControl: 'N',
  1346. csProcessControl: 'N'
  1347. }
  1348. }
  1349. },
  1350. created () {
  1351. this.menuId = (this.$route.meta && this.$route.meta.menuId) || this.menuId || '112001'
  1352. this.getButtonAuthData()
  1353. this.checkSuperAdmin()
  1354. },
  1355. mounted () {
  1356. this.fetchNodeOptions()
  1357. if (this.authSearch) {
  1358. this.getDataList()
  1359. }
  1360. this.$nextTick(() => {
  1361. this.height = window.innerHeight / 2 - 30
  1362. /*第二个表格高度的动态调整*/
  1363. this.secondHeight = window.innerHeight / 2 - 186
  1364. })
  1365. },
  1366. watch: {
  1367. activeName (val) {
  1368. if (val === 'attachmentInfo' || val === 'npdInfo') {
  1369. this.$nextTick(() => {
  1370. if (val === 'attachmentInfo') {
  1371. this.refreshOssRef('modalAttachmentOss')
  1372. }
  1373. if (val === 'npdInfo') {
  1374. this.refreshOssRef('modalTdsOss')
  1375. }
  1376. })
  1377. }
  1378. },
  1379. 'modalData.expiredDate' () {
  1380. this.syncExpiryDateByRule()
  1381. },
  1382. 'modalData.validUntilValue' () {
  1383. this.syncExpiryDateByRule()
  1384. },
  1385. 'modalData.validUntil' () {
  1386. this.syncExpiryDateByRule()
  1387. },
  1388. 'modalData.endCustomer' () {
  1389. this.applyHsfStandardDefaultByCustomer(this.modalData)
  1390. }
  1391. },
  1392. methods: {
  1393. fetchNodeOptions () {
  1394. if (!this.searchData.site || !this.menuId) {
  1395. this.nodeOptions = []
  1396. return
  1397. }
  1398. let params = {
  1399. site: this.searchData.site,
  1400. menuId: this.menuId
  1401. }
  1402. api.getNodeList(params).then(({data}) => {
  1403. if (data && data.code === 0 && Array.isArray(data.rows)) {
  1404. this.nodeOptions = data.rows
  1405. .filter(item => item && item.nodeId)
  1406. .map(item => ({
  1407. id: item.nodeId,
  1408. name: item.nodeName
  1409. }))
  1410. } else {
  1411. this.nodeOptions = []
  1412. }
  1413. }).catch(() => {
  1414. this.nodeOptions = []
  1415. })
  1416. },
  1417. loadNodeAuthority (site, stepId) {
  1418. if (!site || stepId === null || stepId === undefined || !this.menuId) {
  1419. this.plmRohsAuthorityArr = []
  1420. this.nodeAuthorityLoaded = true
  1421. return Promise.resolve()
  1422. }
  1423. this.nodeAuthorityLoaded = false
  1424. let params = {
  1425. site: site,
  1426. stepId: stepId,
  1427. menuId: this.menuId
  1428. }
  1429. return api.getRohsNodeAuthority(params).then(({data}) => {
  1430. if (data && data.code === 0 && data.rows) {
  1431. this.plmRohsAuthorityArr = data.rows.plm_rohs || []
  1432. } else {
  1433. this.plmRohsAuthorityArr = []
  1434. }
  1435. this.nodeAuthorityLoaded = true
  1436. }).catch(() => {
  1437. this.plmRohsAuthorityArr = []
  1438. this.nodeAuthorityLoaded = true
  1439. })
  1440. },
  1441. rohsFieldFlag (fieldId) {
  1442. if (!this.plmRohsAuthorityArr || this.plmRohsAuthorityArr.length === 0) {
  1443. return 'N'
  1444. }
  1445. let target = this.plmRohsAuthorityArr.find(item => item.fieldId === fieldId)
  1446. return target ? target.updateFlag : 'N'
  1447. },
  1448. isRohsFieldDisabled (fieldId) {
  1449. if (this.showModalFlag) {
  1450. return true
  1451. }
  1452. if (!this.isEditMode) {
  1453. return false
  1454. }
  1455. return this.rohsFieldFlag(fieldId) === 'N'
  1456. },
  1457. isProcessFieldDisabled () {
  1458. if (this.isEditMode) {
  1459. return true
  1460. }
  1461. return this.isRohsFieldDisabled('process')
  1462. },
  1463. handleProcessChange (value) {
  1464. const processValue = String(value || '').trim()
  1465. this.$set(this.modalData, 'process', processValue)
  1466. this.$set(this.modalData, 'buNo', processValue)
  1467. if (this.isEditMode) {
  1468. return
  1469. }
  1470. this.clearHsfApproverFields(false)
  1471. if (!processValue) {
  1472. return
  1473. }
  1474. this.loadHsfApproverByCurrentProcess(true)
  1475. },
  1476. isRohsFieldDisabledWithFallback (primaryFieldId, fallbackFieldId) {
  1477. if (this.showModalFlag) {
  1478. return true
  1479. }
  1480. if (!this.isEditMode) {
  1481. return false
  1482. }
  1483. const primaryDisabled = this.rohsFieldFlag(primaryFieldId) === 'N'
  1484. if (!primaryDisabled) {
  1485. return false
  1486. }
  1487. return this.rohsFieldFlag(fallbackFieldId) === 'N'
  1488. },
  1489. isValidUntilValueDisabled () {
  1490. return this.isRohsFieldDisabledWithFallback('validUntilValue', 'validUntil')
  1491. },
  1492. isValidUntilUnitDisabled () {
  1493. return this.isRohsFieldDisabledWithFallback('validUntil', 'validUntilValue')
  1494. },
  1495. canEditRohsMaterial () {
  1496. return !this.showModalFlag
  1497. },
  1498. normalizeDateOnly (value) {
  1499. if (value === null || value === undefined || value === '') {
  1500. return ''
  1501. }
  1502. if (value instanceof Date && !Number.isNaN(value.getTime())) {
  1503. const year = value.getFullYear()
  1504. const month = String(value.getMonth() + 1).padStart(2, '0')
  1505. const day = String(value.getDate()).padStart(2, '0')
  1506. return year + '-' + month + '-' + day
  1507. }
  1508. const text = String(value).trim()
  1509. if (!text) {
  1510. return ''
  1511. }
  1512. if (text.includes('T')) {
  1513. return text.split('T')[0]
  1514. }
  1515. return text.length >= 10 ? text.substring(0, 10) : text
  1516. },
  1517. parseDateOnly (value) {
  1518. const text = this.normalizeDateOnly(value)
  1519. if (!text) {
  1520. return null
  1521. }
  1522. const parts = text.split('-')
  1523. if (parts.length !== 3) {
  1524. return null
  1525. }
  1526. const year = Number.parseInt(parts[0], 10)
  1527. const month = Number.parseInt(parts[1], 10)
  1528. const day = Number.parseInt(parts[2], 10)
  1529. if (Number.isNaN(year) || Number.isNaN(month) || Number.isNaN(day)) {
  1530. return null
  1531. }
  1532. const date = new Date(year, month - 1, day)
  1533. if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) {
  1534. return null
  1535. }
  1536. return date
  1537. },
  1538. normalizeValidUntilUnitType (unitValue) {
  1539. const text = String(unitValue || '').trim().toLowerCase()
  1540. if (!text) {
  1541. return ''
  1542. }
  1543. if (text === 'd' || text === 'day' || text === 'days' || text.includes('日')) {
  1544. return 'day'
  1545. }
  1546. if (text === 'w' || text === 'week' || text === 'weeks' || text.includes('周')) {
  1547. return 'week'
  1548. }
  1549. if (text === 'm' || text === 'month' || text === 'months' || text.includes('月')) {
  1550. return 'month'
  1551. }
  1552. if (text === 'y' || text === 'year' || text === 'years' || text.includes('年')) {
  1553. return 'year'
  1554. }
  1555. return ''
  1556. },
  1557. addMonthsKeepDay (baseDate, monthDelta) {
  1558. const year = baseDate.getFullYear()
  1559. const month = baseDate.getMonth()
  1560. const day = baseDate.getDate()
  1561. const targetFirstDay = new Date(year, month + monthDelta, 1)
  1562. const targetYear = targetFirstDay.getFullYear()
  1563. const targetMonth = targetFirstDay.getMonth()
  1564. const lastDay = new Date(targetYear, targetMonth + 1, 0).getDate()
  1565. return new Date(targetYear, targetMonth, Math.min(day, lastDay))
  1566. },
  1567. addYearsKeepDay (baseDate, yearDelta) {
  1568. const targetYear = baseDate.getFullYear() + yearDelta
  1569. const month = baseDate.getMonth()
  1570. const day = baseDate.getDate()
  1571. const lastDay = new Date(targetYear, month + 1, 0).getDate()
  1572. return new Date(targetYear, month, Math.min(day, lastDay))
  1573. },
  1574. calculateExpiryDateByRule (reportDate, validUntilValue, validUntilUnit) {
  1575. const baseDate = this.parseDateOnly(reportDate)
  1576. const durationValue = this.normalizeValidUntilValue(validUntilValue)
  1577. const unitType = this.normalizeValidUntilUnitType(validUntilUnit)
  1578. if (!baseDate || !durationValue || !unitType) {
  1579. return ''
  1580. }
  1581. let resultDate = new Date(baseDate.getTime())
  1582. if (unitType === 'day') {
  1583. resultDate.setDate(resultDate.getDate() + durationValue)
  1584. } else if (unitType === 'week') {
  1585. resultDate.setDate(resultDate.getDate() + durationValue * 7)
  1586. } else if (unitType === 'month') {
  1587. resultDate = this.addMonthsKeepDay(baseDate, durationValue)
  1588. } else if (unitType === 'year') {
  1589. resultDate = this.addYearsKeepDay(baseDate, durationValue)
  1590. } else {
  1591. return ''
  1592. }
  1593. return this.normalizeDateOnly(resultDate)
  1594. },
  1595. syncExpiryDateByRule () {
  1596. if (!this.modalData) {
  1597. return ''
  1598. }
  1599. const expiryDate = this.calculateExpiryDateByRule(this.modalData.expiredDate, this.modalData.validUntilValue, this.modalData.validUntil)
  1600. this.$set(this.modalData, 'expiryDate', expiryDate)
  1601. return expiryDate
  1602. },
  1603. getCurrentDateString () {
  1604. return this.normalizeDateOnly(new Date())
  1605. },
  1606. normalizeCheckboxFlag (value) {
  1607. return String(value || '').trim().toUpperCase() === 'Y' ? 'Y' : 'N'
  1608. },
  1609. normalizeValidUntilValue (value) {
  1610. if (value === null || value === undefined || value === '') {
  1611. return null
  1612. }
  1613. const parsed = Number.parseInt(value, 10)
  1614. if (Number.isNaN(parsed) || parsed <= 0) {
  1615. return null
  1616. }
  1617. return parsed
  1618. },
  1619. getValidUntilDisplay (value, unit) {
  1620. const normalizedValue = this.normalizeValidUntilValue(value)
  1621. const normalizedUnit = String(unit || '').trim()
  1622. if (normalizedValue && normalizedUnit) {
  1623. return normalizedValue + normalizedUnit
  1624. }
  1625. if (normalizedValue) {
  1626. return String(normalizedValue)
  1627. }
  1628. return normalizedUnit
  1629. },
  1630. getRohsSubmitFieldValue (fieldId) {
  1631. const fieldMapping = {
  1632. materialClassify: 'materialClassifyList',
  1633. qualificationDocumentsNeeded: 'qualificationDocumentsNeededList',
  1634. testReportIncludingItems: 'testReportIncludingItemsList',
  1635. hsfApprover: 'hsfApproverCodeList'
  1636. }
  1637. const mappedField = fieldMapping[fieldId]
  1638. if (mappedField) {
  1639. return this.modalData[mappedField]
  1640. }
  1641. return this.modalData[fieldId]
  1642. },
  1643. isSubmitFieldEmpty (value) {
  1644. if (Array.isArray(value)) {
  1645. return value.length === 0
  1646. }
  1647. if (typeof value === 'string') {
  1648. return value.trim() === ''
  1649. }
  1650. return !value
  1651. },
  1652. validateSubmitRequiredFields () {
  1653. if (this.plmRohsAuthorityArr && this.plmRohsAuthorityArr.length > 0) {
  1654. let validUntilPairRequiredChecked = false
  1655. for (let i = 0; i < this.plmRohsAuthorityArr.length; i++) {
  1656. const fieldConfig = this.plmRohsAuthorityArr[i]
  1657. if (fieldConfig.required !== 'Y') {
  1658. continue
  1659. }
  1660. if (fieldConfig.fieldId === 'hsfStandard' && !this.shouldShowHsfStandard(this.modalData.endCustomer)) {
  1661. continue
  1662. }
  1663. if (fieldConfig.fieldId === 'validUntil' || fieldConfig.fieldId === 'validUntilValue') {
  1664. if (validUntilPairRequiredChecked) {
  1665. continue
  1666. }
  1667. const validUntilValue = this.normalizeValidUntilValue(this.modalData.validUntilValue)
  1668. this.$set(this.modalData, 'validUntilValue', validUntilValue)
  1669. if (this.isSubmitFieldEmpty(validUntilValue) || this.isSubmitFieldEmpty(this.modalData.validUntil)) {
  1670. this.$message.warning('有效期数值/单位不能为空!')
  1671. return false
  1672. }
  1673. validUntilPairRequiredChecked = true
  1674. continue
  1675. }
  1676. const value = this.getRohsSubmitFieldValue(fieldConfig.fieldId)
  1677. if (this.isSubmitFieldEmpty(value)) {
  1678. this.$message.warning((fieldConfig.fieldName || fieldConfig.fieldId) + '不能为空!')
  1679. return false
  1680. }
  1681. }
  1682. }
  1683. return true
  1684. },
  1685. validateValidUntilPair () {
  1686. const validUntilValue = this.normalizeValidUntilValue(this.modalData.validUntilValue)
  1687. const validUntilUnit = String(this.modalData.validUntil || '').trim()
  1688. this.$set(this.modalData, 'validUntilValue', validUntilValue)
  1689. this.$set(this.modalData, 'validUntil', validUntilUnit)
  1690. if (!validUntilValue && !validUntilUnit) {
  1691. return true
  1692. }
  1693. if (!validUntilValue) {
  1694. this.$message.warning('请填写有效期数值')
  1695. return false
  1696. }
  1697. if (!validUntilUnit) {
  1698. this.$message.warning('请选择有效期单位')
  1699. return false
  1700. }
  1701. return true
  1702. },
  1703. materialDialogHeaderCellStyle () {
  1704. return {
  1705. whiteSpace: 'nowrap',
  1706. wordBreak: 'keep-all'
  1707. }
  1708. },
  1709. displayYesNo (value) {
  1710. if (value === 'Y') {
  1711. return '是'
  1712. }
  1713. if (value === 'N') {
  1714. return '否'
  1715. }
  1716. return value || ''
  1717. },
  1718. getMultipleSelectTitle (value) {
  1719. if (!Array.isArray(value)) {
  1720. return ''
  1721. }
  1722. return value
  1723. .filter(item => item !== null && item !== undefined && String(item).trim() !== '')
  1724. .map(item => String(item).trim())
  1725. .join(';')
  1726. },
  1727. shouldShowHsfStandard (customerCode) {
  1728. return String(customerCode || '').trim().toUpperCase() === 'C00052'
  1729. },
  1730. applyHsfStandardDefaultByCustomer (formData) {
  1731. if (!formData || !this.shouldShowHsfStandard(formData.endCustomer)) {
  1732. return
  1733. }
  1734. const currentValue = String(formData.hsfStandard || '').trim()
  1735. if (!currentValue) {
  1736. this.$set(formData, 'hsfStandard', this.hsfStandardDefaultText)
  1737. }
  1738. },
  1739. normalizeHsfStandardByCustomer (formData) {
  1740. if (!formData) {
  1741. return
  1742. }
  1743. if (!this.shouldShowHsfStandard(formData.endCustomer)) {
  1744. this.$set(formData, 'hsfStandard', '')
  1745. return
  1746. }
  1747. this.applyHsfStandardDefaultByCustomer(formData)
  1748. },
  1749. resolveOperatorNameById (operatorId) {
  1750. const normalizedId = String(operatorId || '').trim()
  1751. if (!normalizedId) {
  1752. return ''
  1753. }
  1754. const option = (this.hsfApproverOptionList || []).find(item => String(item.operatorId || '').trim() === normalizedId) ||
  1755. (this.relatedPeopleOptionList || []).find(item => String(item.operatorId || '').trim() === normalizedId)
  1756. return option ? String(option.operatorName || '').trim() : normalizedId
  1757. },
  1758. resolveOperatorIdByCodeOrName (operatorValue) {
  1759. const normalizedValue = String(operatorValue || '').trim()
  1760. if (!normalizedValue) {
  1761. return ''
  1762. }
  1763. const option = (this.hsfApproverOptionList || []).find(item => String(item.operatorId || '').trim() === normalizedValue) ||
  1764. (this.hsfApproverOptionList || []).find(item => String(item.operatorName || '').trim() === normalizedValue) ||
  1765. (this.relatedPeopleOptionList || []).find(item => String(item.operatorId || '').trim() === normalizedValue) ||
  1766. (this.relatedPeopleOptionList || []).find(item => String(item.operatorName || '').trim() === normalizedValue)
  1767. return option ? String(option.operatorId || '').trim() : normalizedValue
  1768. },
  1769. syncHsfApproverFields () {
  1770. const sourceList = Array.isArray(this.modalData.hsfApproverCodeList)
  1771. ? this.modalData.hsfApproverCodeList
  1772. : []
  1773. const uniqueCodeList = []
  1774. const seen = new Set()
  1775. sourceList.forEach(item => {
  1776. const value = this.resolveOperatorIdByCodeOrName(item)
  1777. if (!value || seen.has(value)) {
  1778. return
  1779. }
  1780. seen.add(value)
  1781. uniqueCodeList.push(value)
  1782. })
  1783. this.$set(this.modalData, 'hsfApproverCodeList', uniqueCodeList)
  1784. this.$set(this.modalData, 'hsfApprover', uniqueCodeList.join(';'))
  1785. this.$set(this.modalData, 'hsfApproverName', uniqueCodeList.map(item => this.resolveOperatorNameById(item)).join(';'))
  1786. this.buildRelatedPeopleOptions(uniqueCodeList)
  1787. const relatedPeopleCode = this.resolveOperatorIdByCodeOrName(this.modalData.relatedPeople)
  1788. if (relatedPeopleCode && !uniqueCodeList.includes(relatedPeopleCode)) {
  1789. this.$set(this.modalData, 'relatedPeople', '')
  1790. this.$set(this.modalData, 'relatedPeopleName', '')
  1791. return
  1792. }
  1793. if (relatedPeopleCode) {
  1794. this.$set(this.modalData, 'relatedPeople', relatedPeopleCode)
  1795. this.$set(this.modalData, 'relatedPeopleName', this.resolveOperatorNameById(relatedPeopleCode))
  1796. }
  1797. },
  1798. buildRelatedPeopleOptions (selectedOperatorIds) {
  1799. const normalizedIds = (Array.isArray(selectedOperatorIds) ? selectedOperatorIds : (this.modalData.hsfApproverCodeList || []))
  1800. .map(item => this.resolveOperatorIdByCodeOrName(item))
  1801. .filter(item => !!item)
  1802. const selectedSet = new Set(normalizedIds)
  1803. let optionList = (this.hsfApproverOptionList || [])
  1804. .filter(item => selectedSet.has(String(item.operatorId || '').trim()))
  1805. .map(item => ({
  1806. operatorId: item.operatorId,
  1807. operatorName: item.operatorName
  1808. }))
  1809. const existingIdSet = new Set(optionList.map(item => String(item.operatorId || '').trim()))
  1810. normalizedIds.forEach(operatorId => {
  1811. if (existingIdSet.has(operatorId)) {
  1812. return
  1813. }
  1814. optionList.push({
  1815. operatorId: operatorId,
  1816. operatorName: this.resolveOperatorNameById(operatorId)
  1817. })
  1818. existingIdSet.add(operatorId)
  1819. })
  1820. this.relatedPeopleOptionList = optionList
  1821. this.filterRelatedPeopleOptions()
  1822. const selectedRelatedPeopleCode = this.resolveOperatorIdByCodeOrName(this.modalData.relatedPeople)
  1823. const selectedRelatedPeopleRow = optionList.find(item => String(item.operatorId || '').trim() === selectedRelatedPeopleCode)
  1824. if (!selectedRelatedPeopleRow) {
  1825. this.$set(this.modalData, 'relatedPeople', '')
  1826. this.$set(this.modalData, 'relatedPeopleName', '')
  1827. } else {
  1828. this.$set(this.modalData, 'relatedPeople', selectedRelatedPeopleCode)
  1829. this.$set(this.modalData, 'relatedPeopleName', String(selectedRelatedPeopleRow.operatorName || '').trim())
  1830. }
  1831. },
  1832. normalizeHsfApproverOptionList (rows) {
  1833. if (!Array.isArray(rows)) {
  1834. return []
  1835. }
  1836. return rows
  1837. .map(item => {
  1838. const operatorId = String(item.operatorId || item.operator_id || item.username || item.userName || '').trim()
  1839. const operatorName = String(item.operatorName || item.operator_name || item.userDisplay || item.user_display || '').trim()
  1840. if (!operatorId || !operatorName) {
  1841. return null
  1842. }
  1843. return {
  1844. operatorId,
  1845. operatorName
  1846. }
  1847. })
  1848. .filter(item => !!item)
  1849. },
  1850. filterHsfApproverOptions () {
  1851. const operatorIdKeyword = String(this.hsfApproverSearchData.operatorId || '').trim().toUpperCase()
  1852. const operatorNameKeyword = String(this.hsfApproverSearchData.operatorName || '').trim().toUpperCase()
  1853. this.hsfApproverDisplayList = (this.hsfApproverOptionList || []).filter(item => {
  1854. const operatorId = String(item.operatorId || '').toUpperCase()
  1855. const operatorName = String(item.operatorName || '').toUpperCase()
  1856. const matchOperatorId = !operatorIdKeyword || operatorId.includes(operatorIdKeyword)
  1857. const matchOperatorName = !operatorNameKeyword || operatorName.includes(operatorNameKeyword)
  1858. return matchOperatorId && matchOperatorName
  1859. })
  1860. },
  1861. filterRelatedPeopleOptions () {
  1862. const operatorIdKeyword = String(this.relatedPeopleSearchData.operatorId || '').trim().toUpperCase()
  1863. const operatorNameKeyword = String(this.relatedPeopleSearchData.operatorName || '').trim().toUpperCase()
  1864. this.relatedPeopleDisplayList = (this.relatedPeopleOptionList || []).filter(item => {
  1865. const operatorId = String(item.operatorId || '').toUpperCase()
  1866. const operatorName = String(item.operatorName || '').toUpperCase()
  1867. const matchOperatorId = !operatorIdKeyword || operatorId.includes(operatorIdKeyword)
  1868. const matchOperatorName = !operatorNameKeyword || operatorName.includes(operatorNameKeyword)
  1869. return matchOperatorId && matchOperatorName
  1870. })
  1871. },
  1872. openHsfApproverChooseModal () {
  1873. if (this.isRohsFieldDisabled('hsfApprover')) {
  1874. return
  1875. }
  1876. if (!this.modalData || !String(this.modalData.process || '').trim()) {
  1877. this.$message.warning('请先选择工艺')
  1878. return
  1879. }
  1880. this.loadHsfApproverByCurrentProcess(false).then(() => {
  1881. if (!this.hsfApproverOptionList || this.hsfApproverOptionList.length === 0) {
  1882. this.$message.warning('未查询到可选HSF审批人')
  1883. return
  1884. }
  1885. this.hsfApproverFlag = true
  1886. })
  1887. },
  1888. openHsfApproverDialog () {
  1889. this.hsfApproverSearchData = {
  1890. operatorId: '',
  1891. operatorName: ''
  1892. }
  1893. this.filterHsfApproverOptions()
  1894. const selectedOperatorSet = new Set(
  1895. (this.modalData.hsfApproverCodeList || [])
  1896. .map(item => String(item || '').trim())
  1897. .filter(item => !!item)
  1898. )
  1899. const selectedRows = (this.hsfApproverOptionList || []).filter(item => selectedOperatorSet.has(String(item.operatorId || '').trim()))
  1900. this.hsfApproverSelectionCache = JSON.parse(JSON.stringify(selectedRows))
  1901. this.$nextTick(() => {
  1902. if (!this.$refs.hsfApproverTable) {
  1903. return
  1904. }
  1905. this.$refs.hsfApproverTable.clearSelection()
  1906. selectedRows.forEach(item => {
  1907. this.$refs.hsfApproverTable.toggleRowSelection(item, true)
  1908. })
  1909. })
  1910. },
  1911. closeHsfApproverDialog () {
  1912. this.hsfApproverSelectionCache = []
  1913. },
  1914. handleHsfApproverSelectionChange (rows) {
  1915. this.hsfApproverSelectionCache = rows || []
  1916. },
  1917. handleHsfApproverTableClick (row, column, event, tableRef) {
  1918. if (this.$refs[tableRef]) {
  1919. this.$refs[tableRef].toggleRowSelection(row)
  1920. }
  1921. },
  1922. saveHsfApproverChooseModal () {
  1923. const selectedCodes = (this.hsfApproverSelectionCache || [])
  1924. .map(item => String(item.operatorId || '').trim())
  1925. .filter(item => !!item)
  1926. this.$set(this.modalData, 'hsfApproverCodeList', selectedCodes)
  1927. this.syncHsfApproverFields()
  1928. this.hsfApproverFlag = false
  1929. },
  1930. clearHsfApproverSelection () {
  1931. this.$set(this.modalData, 'hsfApproverCodeList', [])
  1932. this.syncHsfApproverFields()
  1933. },
  1934. openRelatedPeopleChooseModal () {
  1935. if (this.isRohsFieldDisabled('relatedPeople')) {
  1936. return
  1937. }
  1938. if (!this.modalData || !Array.isArray(this.modalData.hsfApproverCodeList) || this.modalData.hsfApproverCodeList.length === 0) {
  1939. this.$message.warning('请先选择HSF审批人')
  1940. return
  1941. }
  1942. this.buildRelatedPeopleOptions(this.modalData.hsfApproverCodeList)
  1943. if (!this.relatedPeopleOptionList || this.relatedPeopleOptionList.length === 0) {
  1944. this.$message.warning('未查询到可选Inform Related people')
  1945. return
  1946. }
  1947. this.relatedPeopleFlag = true
  1948. },
  1949. openRelatedPeopleDialog () {
  1950. this.relatedPeopleSearchData = {
  1951. operatorId: '',
  1952. operatorName: ''
  1953. }
  1954. this.filterRelatedPeopleOptions()
  1955. const relatedPeopleCode = String(this.modalData.relatedPeople || '').trim()
  1956. const selectedRow = (this.relatedPeopleOptionList || []).find(item => String(item.operatorId || '').trim() === relatedPeopleCode) || null
  1957. this.relatedPeopleSelection = selectedRow
  1958. this.$nextTick(() => {
  1959. if (!this.$refs.relatedPeopleTable) {
  1960. return
  1961. }
  1962. this.$refs.relatedPeopleTable.setCurrentRow(selectedRow || null)
  1963. })
  1964. },
  1965. closeRelatedPeopleDialog () {
  1966. this.relatedPeopleSelection = null
  1967. },
  1968. handleRelatedPeopleCurrentChange (row) {
  1969. this.relatedPeopleSelection = row || null
  1970. },
  1971. handleRelatedPeopleTableClick (row) {
  1972. this.relatedPeopleSelection = row || null
  1973. if (this.$refs.relatedPeopleTable) {
  1974. this.$refs.relatedPeopleTable.setCurrentRow(row)
  1975. }
  1976. },
  1977. saveRelatedPeopleChooseModal () {
  1978. const selectedCode = this.relatedPeopleSelection ? String(this.relatedPeopleSelection.operatorId || '').trim() : ''
  1979. const selectedName = this.relatedPeopleSelection ? String(this.relatedPeopleSelection.operatorName || '').trim() : ''
  1980. this.$set(this.modalData, 'relatedPeople', selectedCode)
  1981. this.$set(this.modalData, 'relatedPeopleName', selectedName)
  1982. this.relatedPeopleFlag = false
  1983. },
  1984. clearRelatedPeopleSelection () {
  1985. this.$set(this.modalData, 'relatedPeople', '')
  1986. this.$set(this.modalData, 'relatedPeopleName', '')
  1987. this.relatedPeopleSelection = null
  1988. if (this.$refs.relatedPeopleTable) {
  1989. this.$refs.relatedPeopleTable.setCurrentRow(null)
  1990. }
  1991. },
  1992. clearHsfApproverFields (clearBuNo = false) {
  1993. if (clearBuNo) {
  1994. this.$set(this.modalData, 'buNo', '')
  1995. }
  1996. this.hsfApproverOptionList = []
  1997. this.hsfApproverDisplayList = []
  1998. this.hsfApproverSelectionCache = []
  1999. this.relatedPeopleOptionList = []
  2000. this.relatedPeopleDisplayList = []
  2001. this.relatedPeopleSelection = null
  2002. this.relatedPeopleFlag = false
  2003. this.hsfApproverSearchData = {
  2004. operatorId: '',
  2005. operatorName: ''
  2006. }
  2007. this.relatedPeopleSearchData = {
  2008. operatorId: '',
  2009. operatorName: ''
  2010. }
  2011. this.$set(this.modalData, 'hsfApproverCodeList', [])
  2012. this.$set(this.modalData, 'hsfApprover', '')
  2013. this.$set(this.modalData, 'hsfApproverName', '')
  2014. this.$set(this.modalData, 'relatedPeople', '')
  2015. this.$set(this.modalData, 'relatedPeopleName', '')
  2016. },
  2017. loadHsfApproverByCurrentProcess (forceSelectAll = false) {
  2018. if (!this.modalData || !this.modalData.site) {
  2019. this.hsfApproverOptionList = []
  2020. this.hsfApproverDisplayList = []
  2021. this.hsfApproverSelectionCache = []
  2022. if (forceSelectAll) {
  2023. this.clearHsfApproverFields(false)
  2024. }
  2025. return Promise.resolve()
  2026. }
  2027. const buNo = String(this.modalData.process || '').trim()
  2028. if (!buNo) {
  2029. if (forceSelectAll) {
  2030. this.$message.warning('请先选择工艺')
  2031. this.clearHsfApproverFields(false)
  2032. }
  2033. this.hsfApproverOptionList = []
  2034. this.hsfApproverDisplayList = []
  2035. this.hsfApproverSelectionCache = []
  2036. return Promise.resolve()
  2037. }
  2038. const params = {
  2039. site: this.modalData.site,
  2040. buNo: buNo,
  2041. roleNo: 'R015'
  2042. }
  2043. return api.searchBmUser(params).then(({data}) => {
  2044. if (data && data.code === 0 && Array.isArray(data.rows)) {
  2045. this.hsfApproverOptionList = this.normalizeHsfApproverOptionList(data.rows)
  2046. this.filterHsfApproverOptions()
  2047. this.hsfApproverSelectionCache = []
  2048. if (forceSelectAll) {
  2049. const defaultSelectedCodes = this.hsfApproverOptionList.map(item => item.operatorId).filter(item => item)
  2050. this.$set(this.modalData, 'hsfApproverCodeList', defaultSelectedCodes)
  2051. }
  2052. this.syncHsfApproverFields()
  2053. } else {
  2054. this.hsfApproverOptionList = []
  2055. this.hsfApproverDisplayList = []
  2056. this.hsfApproverSelectionCache = []
  2057. if (forceSelectAll) {
  2058. this.clearHsfApproverFields(false)
  2059. }
  2060. }
  2061. }).catch(() => {
  2062. this.hsfApproverOptionList = []
  2063. this.hsfApproverDisplayList = []
  2064. this.hsfApproverSelectionCache = []
  2065. if (forceSelectAll) {
  2066. this.clearHsfApproverFields(false)
  2067. }
  2068. })
  2069. },
  2070. isCurrentApprover () {
  2071. return this.superAdmin || (this.modalData.createBy2 && this.modalData.createBy2.split(';').includes(this.createBy2))
  2072. },
  2073. canSaveAction () {
  2074. return !this.showModalFlag && (this.modalData.status === '草稿' || (this.modalData.status === '审批中' && this.isCurrentApprover()))
  2075. },
  2076. canAgreeAction () {
  2077. return this.authSubmit && this.isCurrentApprover() && this.modalData.status === '审批中' && this.modalData.tpProcessControl !== 'Y' && this.modalData.csProcessControl !== 'Y'
  2078. },
  2079. canRejectAction () {
  2080. return this.authReject && this.isCurrentApprover() && this.modalData.status === '审批中' && this.modalData.isReject === 'Y'
  2081. },
  2082. hasPersistedRohsRecord () {
  2083. return !!(this.modalData && this.modalData.site && this.modalData.referenceNo && !String(this.modalData.referenceNo).startsWith('TEMP-'))
  2084. },
  2085. openRohsRemarkDialog () {
  2086. this.$set(this.rohsRemarkForm, 'remark', this.modalData.remark || '')
  2087. this.rohsRemarkFlag = true
  2088. },
  2089. refreshRohsRemark () {
  2090. if (!this.hasPersistedRohsRecord()) {
  2091. this.$set(this.rohsRemarkForm, 'remark', this.modalData.remark || '')
  2092. return
  2093. }
  2094. api.getRohsDetail(this.modalData.site, this.modalData.referenceNo).then(({data}) => {
  2095. if (data && data.code === 0 && data.data) {
  2096. this.$set(this.rohsRemarkForm, 'remark', data.data.remark || '')
  2097. } else {
  2098. this.$message.error((data && data.msg) || '刷新失败')
  2099. }
  2100. }).catch(() => {
  2101. this.$message.error('刷新失败')
  2102. })
  2103. },
  2104. saveRohsRemark () {
  2105. const remark = this.rohsRemarkForm.remark || ''
  2106. if (!this.hasPersistedRohsRecord()) {
  2107. this.$set(this.modalData, 'remark', remark)
  2108. this.rohsRemarkFlag = false
  2109. this.$message.success('暂存成功,保存单据后写入数据库')
  2110. return
  2111. }
  2112. const params = {
  2113. site: this.modalData.site,
  2114. referenceNo: this.modalData.referenceNo,
  2115. remark: remark
  2116. }
  2117. api.updateRohsRemark(params).then(({data}) => {
  2118. if (data && data.code === 0) {
  2119. this.$set(this.modalData, 'remark', remark)
  2120. if (this.currentRow && this.currentRow.site === this.modalData.site && this.currentRow.referenceNo === this.modalData.referenceNo) {
  2121. this.$set(this.currentRow, 'remark', remark)
  2122. }
  2123. const target = (this.dataList || []).find(item => item.site === this.modalData.site && item.referenceNo === this.modalData.referenceNo)
  2124. if (target) {
  2125. this.$set(target, 'remark', remark)
  2126. }
  2127. this.rohsRemarkFlag = false
  2128. this.$message.success('操作成功')
  2129. } else {
  2130. this.$message.error((data && data.msg) || '保存失败')
  2131. }
  2132. }).catch(() => {
  2133. this.$message.error('保存失败')
  2134. })
  2135. },
  2136. loadModalButtonCondition () {
  2137. if (!this.modalData.site || !this.modalData.referenceNo || this.modalData.status !== '审批中') {
  2138. this.$set(this.modalData, 'createBy2', '')
  2139. this.$set(this.modalData, 'isReject', 'Y')
  2140. this.$set(this.modalData, 'tpProcessControl', 'N')
  2141. this.$set(this.modalData, 'csProcessControl', 'N')
  2142. return
  2143. }
  2144. let params = {
  2145. site: this.modalData.site,
  2146. referenceNo: this.modalData.referenceNo
  2147. }
  2148. api.getRohsButtonCondition(params).then(({data}) => {
  2149. if (data && data.code === 0 && data.data) {
  2150. this.$set(this.modalData, 'createBy2', data.data.createBy2 || '')
  2151. this.$set(this.modalData, 'isReject', data.data.isReject || 'Y')
  2152. this.$set(this.modalData, 'tpProcessControl', data.data.tpProcessControl || 'N')
  2153. this.$set(this.modalData, 'csProcessControl', data.data.csProcessControl || 'N')
  2154. } else {
  2155. this.$set(this.modalData, 'createBy2', '')
  2156. this.$set(this.modalData, 'isReject', 'Y')
  2157. this.$set(this.modalData, 'tpProcessControl', 'N')
  2158. this.$set(this.modalData, 'csProcessControl', 'N')
  2159. }
  2160. }).catch(() => {
  2161. this.$set(this.modalData, 'createBy2', '')
  2162. this.$set(this.modalData, 'isReject', 'Y')
  2163. this.$set(this.modalData, 'tpProcessControl', 'N')
  2164. this.$set(this.modalData, 'csProcessControl', 'N')
  2165. })
  2166. },
  2167. // 列表行选中变色
  2168. rowStyle ({row}) {
  2169. if (this.currentRow && this.currentRow.referenceNo === row.referenceNo) {
  2170. return { 'background-color': '#E8F7F6', cursor: 'pointer' }
  2171. }
  2172. },
  2173. // 获取按钮的权限数据
  2174. getButtonAuthData () {
  2175. this.authSearch = this.isAuth(this.menuId+":search")
  2176. this.authUpdate = this.isAuth(this.menuId+":update")
  2177. this.authIssue = this.isAuth(this.menuId+":issue")
  2178. this.authSubmit = this.isAuth(this.menuId+":submit")
  2179. this.authReject = this.isAuth(this.menuId+":reject")
  2180. this.authFileSave = this.isAuth(this.menuId+":fileSave")
  2181. this.authFileDownLoad = this.isAuth(this.menuId+":fileDownLoad")
  2182. this.authFileRemove = this.isAuth(this.menuId+":fileRemove")
  2183. this.authFilePreview = this.isAuth(this.menuId+":filePreview")
  2184. this.authDataEntry = this.isAuth(this.menuId+":dataEntry")
  2185. this.authDelete = this.isAuth(this.menuId+":delete")
  2186. },
  2187. // 校验是否为超级管理员
  2188. checkSuperAdmin () {
  2189. checkSuperAdmin().then(({data}) => {
  2190. this.superAdmin = data.superAdmin
  2191. })
  2192. },
  2193. changeClickRow (row, column, event) {
  2194. this.loadCurrentRowFromServer(row, row || {})
  2195. },
  2196. currentChange (val) {
  2197. if (val) {
  2198. this.loadCurrentRowFromServer(val, val || {})
  2199. } else {
  2200. this.currentRow = {}
  2201. this.approvalList = []
  2202. }
  2203. },
  2204. dataListSelectionChange (rows) {
  2205. this.dataListSelections = rows || []
  2206. },
  2207. applyCurrentRowData (detailData, fallbackData = {}) {
  2208. this.currentRow = detailData || {}
  2209. if (!Array.isArray(this.currentRow.materialList)) {
  2210. this.$set(this.currentRow, 'materialList', [])
  2211. }
  2212. this.fillDisplayFields(this.currentRow, fallbackData || {})
  2213. this.syncDataListRow(this.currentRow)
  2214. this.refreshCurrentTabTable()
  2215. },
  2216. syncDataListRow (rowData) {
  2217. if (!rowData || !rowData.site || !rowData.referenceNo || !Array.isArray(this.dataList)) {
  2218. return
  2219. }
  2220. const targetIndex = this.dataList.findIndex(item => item.site === rowData.site && item.referenceNo === rowData.referenceNo)
  2221. if (targetIndex < 0) {
  2222. return
  2223. }
  2224. const mergedRow = {
  2225. ...this.dataList[targetIndex],
  2226. ...rowData
  2227. }
  2228. this.fillDisplayFields(mergedRow, this.dataList[targetIndex] || {})
  2229. this.$set(this.dataList, targetIndex, mergedRow)
  2230. },
  2231. loadCurrentRowFromServer (row, fallbackData = {}) {
  2232. if (!row || !row.site || !row.referenceNo) {
  2233. this.applyCurrentRowData(row || {}, fallbackData || {})
  2234. return Promise.resolve()
  2235. }
  2236. return api.getRohsDetail(row.site, row.referenceNo).then(({data}) => {
  2237. if (data && data.code === 0 && data.data) {
  2238. this.applyCurrentRowData(data.data, fallbackData || row)
  2239. } else {
  2240. this.applyCurrentRowData(row || {}, fallbackData || {})
  2241. }
  2242. }).catch(() => {
  2243. this.applyCurrentRowData(row || {}, fallbackData || {})
  2244. })
  2245. },
  2246. refreshCurrentRowFromServer (site, referenceNo) {
  2247. const querySite = site || (this.currentRow && this.currentRow.site)
  2248. const queryReferenceNo = referenceNo || (this.currentRow && this.currentRow.referenceNo)
  2249. if (!querySite || !queryReferenceNo || String(queryReferenceNo).startsWith('TEMP-')) {
  2250. return Promise.resolve()
  2251. }
  2252. return this.loadCurrentRowFromServer({
  2253. site: querySite,
  2254. referenceNo: queryReferenceNo
  2255. }, this.currentRow || {})
  2256. },
  2257. refreshOssRef (refName) {
  2258. const ref = this.$refs[refName]
  2259. if (!ref) {
  2260. return
  2261. }
  2262. const refList = Array.isArray(ref) ? ref : [ref]
  2263. refList.forEach(item => {
  2264. if (item && typeof item.handleQuery === 'function') {
  2265. item.handleQuery()
  2266. }
  2267. })
  2268. },
  2269. refreshAttachmentPanels () {
  2270. this.refreshOssRef('modalAttachmentOss')
  2271. this.refreshOssRef('modalTdsOss')
  2272. this.refreshOssRef('bottomAttachmentOss')
  2273. this.refreshOssRef('bottomTdsOss')
  2274. },
  2275. handleModalClose () {
  2276. const site = this.modalData.site
  2277. const referenceNo = this.modalData.referenceNo
  2278. this.modalFlag = false
  2279. this.$nextTick(() => {
  2280. this.refreshAttachmentPanels()
  2281. })
  2282. this.refreshCurrentRowFromServer(site, referenceNo)
  2283. },
  2284. fillDisplayFields (target, fallbackData = {}) {
  2285. if (!target) {
  2286. return
  2287. }
  2288. const fields = ['nodeId', 'nodeName', 'currentApprover', 'applicantName', 'pmName', 'npdEngineerName', 'technicalPlanName', 'buyerName', 'endCustomerName', 'projectName', 'commGroup1Desc', 'commGroup2Desc', 'commGroup3Desc', 'hsfApproverName', 'relatedPeopleName']
  2289. fields.forEach(field => {
  2290. const value = target[field] || fallbackData[field] || ''
  2291. this.$set(target, field, value)
  2292. })
  2293. this.$set(target, 'endCustomerFlag', !!target.endCustomerFlag)
  2294. this.$set(target, 'projectIdFlag', !!target.projectIdFlag)
  2295. const validUntilValue = target.validUntilValue !== undefined && target.validUntilValue !== null && target.validUntilValue !== ''
  2296. ? target.validUntilValue
  2297. : fallbackData.validUntilValue
  2298. this.$set(target, 'validUntilValue', this.normalizeValidUntilValue(validUntilValue))
  2299. const applicationDate = target.applicationDate || fallbackData.applicationDate || ''
  2300. const plannedMassProductionDate = target.plannedMassProductionDate || fallbackData.plannedMassProductionDate || ''
  2301. const expiredDate = target.expiredDate || fallbackData.expiredDate || ''
  2302. const normalizedExpiredDate = this.normalizeDateOnly(expiredDate)
  2303. this.$set(target, 'applicationDate', this.normalizeDateOnly(applicationDate))
  2304. this.$set(target, 'plannedMassProductionDate', this.normalizeDateOnly(plannedMassProductionDate))
  2305. this.$set(target, 'expiredDate', normalizedExpiredDate)
  2306. this.$set(target, 'expiryDate', this.calculateExpiryDateByRule(normalizedExpiredDate, target.validUntilValue, target.validUntil))
  2307. },
  2308. refreshCurrentTabTable () {
  2309. if (this.activeTable === 'approvalInformation') {
  2310. this.getApprovalList()
  2311. return
  2312. }
  2313. if (this.activeTable === 'attachment') {
  2314. this.refreshOssRef('bottomAttachmentOss')
  2315. return
  2316. }
  2317. if (this.activeTable === 'npdInfo') {
  2318. this.refreshOssRef('bottomTdsOss')
  2319. }
  2320. },
  2321. getApprovalList () {
  2322. if (!this.currentRow || !this.currentRow.site || !this.currentRow.referenceNo) {
  2323. this.approvalList = []
  2324. return
  2325. }
  2326. let params = {
  2327. site: this.currentRow.site,
  2328. menuId: this.menuId,
  2329. documentNo: this.currentRow.referenceNo
  2330. }
  2331. api.getRohsApprovalList(params).then(({data}) => {
  2332. if (data && data.code === 0) {
  2333. this.approvalList = data.rows || []
  2334. } else {
  2335. this.approvalList = []
  2336. }
  2337. }).catch(() => {
  2338. this.approvalList = []
  2339. })
  2340. },
  2341. // 获取列表
  2342. getDataList () {
  2343. if (!this.authSearch) {
  2344. this.dataList = []
  2345. this.dataListSelections = []
  2346. this.totalPage = 0
  2347. this.currentRow = {}
  2348. this.approvalList = []
  2349. this.isFilterSearch = false
  2350. return
  2351. }
  2352. this.dataListLoading = true
  2353. let params = {
  2354. page: this.pageIndex,
  2355. limit: this.pageSize,
  2356. site: this.$store.state.user.site,
  2357. menuId: this.menuId,
  2358. referenceNo: this.searchData.referenceNo,
  2359. status: this.searchData.status,
  2360. currentApprover: this.searchData.currentApprover,
  2361. nodeId: this.searchData.nodeId
  2362. }
  2363. api.getRohsList(params).then(({data}) => {
  2364. if (data && data.code === 0) {
  2365. const list = data.page.list || []
  2366. this.dataList = list.map(item => {
  2367. return {
  2368. applicantName: '',
  2369. pmName: '',
  2370. npdEngineerName: '',
  2371. technicalPlanName: '',
  2372. buyerName: '',
  2373. endCustomerName: '',
  2374. projectName: '',
  2375. nodeId: '',
  2376. nodeName: '',
  2377. currentApprover: '',
  2378. commGroup1Desc: '',
  2379. commGroup2Desc: '',
  2380. commGroup3Desc: '',
  2381. hsfApproverName: '',
  2382. relatedPeopleName: '',
  2383. ...item
  2384. }
  2385. })
  2386. this.dataListSelections = []
  2387. this.totalPage = data.page.totalCount
  2388. this.$nextTick(() => {
  2389. if (this.$refs.rohsTable) {
  2390. this.$refs.rohsTable.clearSelection()
  2391. }
  2392. if (this.$refs.rohsTable && this.dataList.length > 0) {
  2393. this.$refs.rohsTable.setCurrentRow(this.dataList[0])
  2394. } else if (this.$refs.rohsTable) {
  2395. this.$refs.rohsTable.setCurrentRow()
  2396. }
  2397. })
  2398. } else {
  2399. this.dataList = []
  2400. this.dataListSelections = []
  2401. this.totalPage = 0
  2402. this.currentRow = {}
  2403. this.approvalList = []
  2404. }
  2405. this.dataListLoading = false
  2406. }).catch(() => {
  2407. this.dataListSelections = []
  2408. this.currentRow = {}
  2409. this.approvalList = []
  2410. this.dataListLoading = false
  2411. })
  2412. this.isFilterSearch = false
  2413. },
  2414. // 分页
  2415. sizeChangeHandle (val) {
  2416. this.pageSize = val
  2417. this.pageIndex = 1
  2418. if (this.isFilterSearch === false) {
  2419. this.getDataList()
  2420. } else {
  2421. this.queryByAnyField(this.filterSearchData)
  2422. }
  2423. },
  2424. currentChangeHandle (val) {
  2425. this.pageIndex = val
  2426. if (this.isFilterSearch === false) {
  2427. this.getDataList()
  2428. } else {
  2429. this.queryByAnyField(this.filterSearchData)
  2430. }
  2431. },
  2432. // 搜索条件点击
  2433. searchHandle () {
  2434. if (!this.authSearch) {
  2435. return
  2436. }
  2437. this.filterVisible = true
  2438. },
  2439. queryByAnyField (params) {
  2440. const queryParams = {
  2441. ...(params || {})
  2442. }
  2443. queryParams.no = this.pageIndex
  2444. queryParams.size = this.pageSize
  2445. queryParams.userId = this.$store.state.user.id.toString()
  2446. queryParams.site = this.$store.state.user.site
  2447. queryParams.menuId = this.menuId
  2448. this.dataListLoading = true
  2449. api.getRohsListAny(queryParams).then(({data}) => {
  2450. if (data && data.code === 0) {
  2451. const list = (data.page && data.page.list) || []
  2452. this.dataList = list.map(item => {
  2453. return {
  2454. applicantName: '',
  2455. pmName: '',
  2456. npdEngineerName: '',
  2457. technicalPlanName: '',
  2458. buyerName: '',
  2459. endCustomerName: '',
  2460. projectName: '',
  2461. nodeId: '',
  2462. nodeName: '',
  2463. currentApprover: '',
  2464. commGroup1Desc: '',
  2465. commGroup2Desc: '',
  2466. commGroup3Desc: '',
  2467. hsfApproverName: '',
  2468. relatedPeopleName: '',
  2469. ...item
  2470. }
  2471. })
  2472. this.dataListSelections = []
  2473. this.totalPage = data.page.totalCount
  2474. this.$nextTick(() => {
  2475. if (this.$refs.rohsTable) {
  2476. this.$refs.rohsTable.clearSelection()
  2477. }
  2478. if (this.$refs.rohsTable && this.dataList.length > 0) {
  2479. this.$refs.rohsTable.setCurrentRow(this.dataList[0])
  2480. } else if (this.$refs.rohsTable) {
  2481. this.$refs.rohsTable.setCurrentRow()
  2482. }
  2483. })
  2484. } else {
  2485. this.$message.warning((data && data.msg) || '搜索失败')
  2486. this.dataList = []
  2487. this.dataListSelections = []
  2488. this.totalPage = 0
  2489. this.currentRow = {}
  2490. this.approvalList = []
  2491. }
  2492. this.dataListLoading = false
  2493. }).catch(() => {
  2494. this.dataList = []
  2495. this.dataListSelections = []
  2496. this.currentRow = {}
  2497. this.approvalList = []
  2498. this.dataListLoading = false
  2499. })
  2500. this.filterSearchData = JSON.parse(JSON.stringify(queryParams))
  2501. this.isFilterSearch = true
  2502. this.filterVisible = false
  2503. },
  2504. buildExportName () {
  2505. const now = new Date()
  2506. const year = String(now.getFullYear())
  2507. const month = String(now.getMonth() + 1).padStart(2, '0')
  2508. const day = String(now.getDate()).padStart(2, '0')
  2509. const hour = String(now.getHours()).padStart(2, '0')
  2510. const minute = String(now.getMinutes()).padStart(2, '0')
  2511. const second = String(now.getSeconds()).padStart(2, '0')
  2512. return 'RoHs记录' + year + month + day + hour + minute + second
  2513. },
  2514. async createExportData () {
  2515. const params = {
  2516. ...this.searchData,
  2517. site: this.$store.state.user.site,
  2518. menuId: this.menuId,
  2519. page: 1,
  2520. limit: -1
  2521. }
  2522. this.resultList = []
  2523. await api.getRohsList(params).then(({data}) => {
  2524. if (data && data.code === 0 && data.page && Array.isArray(data.page.list)) {
  2525. this.resultList = (data.page.list || []).map(item => {
  2526. const row = {
  2527. ...item
  2528. }
  2529. row.applicationDate = this.normalizeDateOnly(row.applicationDate)
  2530. row.plannedMassProductionDate = this.normalizeDateOnly(row.plannedMassProductionDate)
  2531. row.expectReportTime = this.normalizeDateOnly(row.expectReportTime)
  2532. row.expiredDate = this.normalizeDateOnly(row.expiredDate)
  2533. row.expiryDate = this.normalizeDateOnly(row.expiryDate)
  2534. row.validUntilDisplay = this.getValidUntilDisplay(row.validUntilValue, row.validUntil)
  2535. row.hsfApproverName = row.hsfApproverName || row.hsfApprover || ''
  2536. row.relatedPeopleName = row.relatedPeopleName || row.relatedPeople || ''
  2537. return row
  2538. })
  2539. } else {
  2540. this.$message.warning((data && data.msg) || '导出数据获取失败')
  2541. }
  2542. }).catch(() => {
  2543. this.$message.error('导出数据获取失败')
  2544. })
  2545. return this.resultList
  2546. },
  2547. startDownload () {
  2548. this.exportName = this.buildExportName()
  2549. this.exportFieldMap = this.buildExportFields()
  2550. if (!this.exportFieldMap || Object.keys(this.exportFieldMap).length === 0) {
  2551. this.$message.warning('未获取到可导出的列,请稍后重试')
  2552. }
  2553. this.exportLoading = true
  2554. },
  2555. finishDownload () {
  2556. this.exportLoading = false
  2557. },
  2558. buildExportFields () {
  2559. const tableRef = this.$refs.rohsTable
  2560. if (!tableRef || !Array.isArray(tableRef.columns)) {
  2561. return {}
  2562. }
  2563. const fields = {}
  2564. tableRef.columns.forEach(column => {
  2565. const label = column && column.label ? String(column.label).trim() : ''
  2566. const property = column && column.property ? String(column.property).trim() : ''
  2567. if (!label || !property || label === '操作') {
  2568. return
  2569. }
  2570. fields[label] = property
  2571. })
  2572. return fields
  2573. },
  2574. // 单选可取消
  2575. radioClick (field, value) {
  2576. if (this.modalData[field] === value) {
  2577. this.modalData[field] = ''
  2578. } else {
  2579. this.modalData[field] = value
  2580. }
  2581. },
  2582. // 新增 / 修改
  2583. addOrUpdateHandle (row) {
  2584. if (!row && !this.authUpdate) {
  2585. this.$message.warning('没有新增权限')
  2586. return
  2587. }
  2588. if (row && !this.authUpdate && !this.authDataEntry) {
  2589. this.$message.warning('没有编辑权限')
  2590. return
  2591. }
  2592. this.modalFlag = true
  2593. this.activeName = 'basicInfo'
  2594. this.submitModalFlag = false
  2595. this.rohsRemarkFlag = false
  2596. this.rejectOpinion = ''
  2597. this.rohsRemarkForm = {
  2598. remark: ''
  2599. }
  2600. this.projectMaterialDialogFlag = false
  2601. this.projectMaterialSelections = []
  2602. this.materialSelections = []
  2603. this.hsfApproverOptionList = []
  2604. this.hsfApproverDisplayList = []
  2605. this.hsfApproverSelectionCache = []
  2606. this.hsfApproverSearchData = {
  2607. operatorId: '',
  2608. operatorName: ''
  2609. }
  2610. this.hsfApproverFlag = false
  2611. this.relatedPeopleOptionList = []
  2612. this.relatedPeopleDisplayList = []
  2613. this.relatedPeopleSelection = null
  2614. this.relatedPeopleSearchData = {
  2615. operatorId: '',
  2616. operatorName: ''
  2617. }
  2618. this.relatedPeopleFlag = false
  2619. this.plmRohsAuthorityArr = []
  2620. this.nodeAuthorityLoaded = !row
  2621. this.isEditMode = !!row
  2622. this.projectMaterialPageIndex = 1
  2623. this.projectMaterialTotal = 0
  2624. this.projectMaterialList = []
  2625. this.projectMaterialSearchData = {
  2626. finalPartNo: '',
  2627. partDesc: '',
  2628. partStatus: ''
  2629. }
  2630. this.showModalFlag = !!(row && (row.status === '已完成' || !this.authUpdate))
  2631. if (row) {
  2632. this.modalTitle = 'RoHS 编辑'
  2633. api.getRohsDetail(row.site, row.referenceNo).then(({data}) => {
  2634. if (data && data.code === 0) {
  2635. this.modalData = data.data || {}
  2636. this.$set(this.modalData, 'qualificationDocumentsNeededList', this.modalData.qualificationDocumentsNeeded ? this.modalData.qualificationDocumentsNeeded.split(';').filter(item => item) : [])
  2637. this.$set(this.modalData, 'testReportIncludingItemsList', this.modalData.testReportIncludingItems ? this.modalData.testReportIncludingItems.split(';').filter(item => item) : [])
  2638. this.$set(this.modalData, 'materialClassifyList', this.modalData.materialClassify ? this.modalData.materialClassify.split(';').filter(item => item) : [])
  2639. this.$set(this.modalData, 'materialList', Array.isArray(this.modalData.materialList) ? this.modalData.materialList : [])
  2640. this.$set(this.modalData, 'hsfApproverCodeList', this.modalData.hsfApprover ? this.modalData.hsfApprover.split(';').filter(item => item) : [])
  2641. this.$set(this.modalData, 'buNo', this.modalData.process || '')
  2642. this.$set(this.modalData, 'isAhGrade', this.normalizeCheckboxFlag(this.modalData.isAhGrade))
  2643. this.$set(this.modalData, 'validUntilValue', this.normalizeValidUntilValue(this.modalData.validUntilValue))
  2644. this.syncHsfApproverFields()
  2645. this.fillDisplayFields(this.modalData, row || {})
  2646. this.applyHsfStandardDefaultByCustomer(this.modalData)
  2647. // 编辑时不允许修改最终客户和项目编码
  2648. this.$set(this.modalData, 'endCustomerFlag', true)
  2649. this.$set(this.modalData, 'projectIdFlag', true)
  2650. this.$set(this.modalData, 'createBy2', '')
  2651. this.$set(this.modalData, 'isReject', 'Y')
  2652. this.$set(this.modalData, 'tpProcessControl', 'N')
  2653. this.$set(this.modalData, 'csProcessControl', 'N')
  2654. this.loadModalButtonCondition()
  2655. this.loadHsfApproverByCurrentProcess(false)
  2656. this.loadNodeAuthority(this.modalData.site || row.site, this.modalData.stepId !== null && this.modalData.stepId !== undefined ? this.modalData.stepId : (row.stepId !== null && row.stepId !== undefined ? row.stepId : 10))
  2657. }
  2658. }).catch(() => {
  2659. this.loadNodeAuthority(row.site, row.stepId !== null && row.stepId !== undefined ? row.stepId : 10)
  2660. })
  2661. } else {
  2662. this.modalTitle = 'RoHS 新增'
  2663. this.showModalFlag = false
  2664. // 生成一个临时ID用于附件上传绑定
  2665. const tempReferenceNo = 'TEMP-' + new Date().getTime() + '-' + Math.floor(Math.random() * 1000)
  2666. this.modalData = {
  2667. site: this.$store.state.user.site,
  2668. referenceNo: tempReferenceNo,
  2669. applicant: this.$store.state.user.name || '',
  2670. applicantName: this.$store.state.user.userDisplay || this.$store.state.user.user_display || '',
  2671. pm: '',
  2672. pmName: '',
  2673. applicationDate: this.getCurrentDateString(),
  2674. process: '',
  2675. plannedMassProductionDate: '',
  2676. color: '',
  2677. vendorCode: '',
  2678. vendorMaterialCode: '',
  2679. materialClassify: '',
  2680. materialClassifyList: [],
  2681. otherMaterialClassify: '',
  2682. materialUseFor: '',
  2683. endCustomer: '',
  2684. endCustomerName: '',
  2685. endCustomerFlag: false,
  2686. projectId: '',
  2687. projectName: '',
  2688. projectIdFlag: true,
  2689. commGroup1: '',
  2690. commGroup1Desc: '',
  2691. commGroup2: '',
  2692. commGroup2Desc: '',
  2693. commGroup3: '',
  2694. commGroup3Desc: '',
  2695. needCreateNumber: '',
  2696. npdEngineer: '',
  2697. npdEngineerName: '',
  2698. materialValidityTime: '',
  2699. materialValidityComments: '',
  2700. needDeviation: '',
  2701. technicalPlan: '',
  2702. wmRequiredSpec: '',
  2703. isFiberMaterial: '',
  2704. materialThickness: '',
  2705. buyer: '',
  2706. buyerName: '',
  2707. expectReportTime: '',
  2708. qualificationDocumentsNeeded: '',
  2709. qualificationDocumentsNeededList: [],
  2710. testReportIncludingItems: '',
  2711. testReportIncludingItemsList: [],
  2712. remark: '',
  2713. status: '草稿',
  2714. sgsReportNumber: '',
  2715. rohsStatus: 'Active',
  2716. expiredDate: '',
  2717. expiryDate: '',
  2718. fiberInformation: '',
  2719. hsfStandard: '',
  2720. hsfApprover: '',
  2721. hsfApproverName: '',
  2722. hsfApproverCodeList: [],
  2723. relatedPeople: '',
  2724. relatedPeopleName: '',
  2725. buNo: '',
  2726. validUntilValue: 0,
  2727. validUntil: '',
  2728. isMeetRohsRequirement: '',
  2729. isAhGrade: 'N',
  2730. hsfSupplierClassification: '',
  2731. materialDesc: '',
  2732. npdRemark: '',
  2733. isSameMaterialDiffSize: '',
  2734. ifsPartNo: '',
  2735. materialList: [],
  2736. stepId: 10,
  2737. rejectFlag: 'N',
  2738. rejectStepId: null,
  2739. createBy2: '',
  2740. isReject: 'Y',
  2741. tpProcessControl: 'N',
  2742. csProcessControl: 'N'
  2743. }
  2744. this.nodeAuthorityLoaded = true
  2745. }
  2746. },
  2747. // 表单提交
  2748. dataFormSubmit () {
  2749. if (!this.canSaveAction()) {
  2750. this.$message.warning('当前状态不允许保存')
  2751. return
  2752. }
  2753. this.$set(this.modalData, 'isAhGrade', this.normalizeCheckboxFlag(this.modalData.isAhGrade))
  2754. this.normalizeHsfStandardByCustomer(this.modalData)
  2755. this.syncHsfApproverFields()
  2756. if (!this.validateValidUntilPair()) {
  2757. return
  2758. }
  2759. this.syncExpiryDateByRule()
  2760. this.modalData.qualificationDocumentsNeeded = this.modalData.qualificationDocumentsNeededList.join(';')
  2761. this.modalData.testReportIncludingItems = this.modalData.testReportIncludingItemsList.join(';')
  2762. this.modalData.materialClassify = this.modalData.materialClassifyList.join(';')
  2763. this.modalData.materialList = (this.modalData.materialList || []).map((item, index) => {
  2764. return {
  2765. ...item,
  2766. lineNo: index + 1,
  2767. projectId: this.modalData.projectId
  2768. }
  2769. })
  2770. const submitMethod = this.modalTitle === 'RoHS 新增' ? api.saveRohs : api.updateRohs
  2771. submitMethod(this.modalData).then(({data}) => {
  2772. if (data && data.code === 0) {
  2773. this.$message.success('操作成功')
  2774. this.modalFlag = false
  2775. this.getDataList()
  2776. } else {
  2777. this.$message.error(data.msg || '操作失败')
  2778. }
  2779. })
  2780. },
  2781. // 同意
  2782. agreeSubmit () {
  2783. if (!this.canAgreeAction()) {
  2784. this.$message.warning('当前状态不允许同意')
  2785. return
  2786. }
  2787. this.$confirm('确认同意该申请单?', '提示', {
  2788. confirmButtonText: '确定',
  2789. cancelButtonText: '取消',
  2790. type: 'warning'
  2791. }).then(() => {
  2792. this.submitRohs('Y')
  2793. })
  2794. },
  2795. openRejectModal () {
  2796. if (!this.canRejectAction()) {
  2797. this.$message.warning('当前状态不允许驳回')
  2798. return
  2799. }
  2800. this.rejectOpinion = ''
  2801. this.submitModalFlag = true
  2802. },
  2803. // 驳回
  2804. rejectSubmit () {
  2805. if (!this.rejectOpinion || !this.rejectOpinion.trim()) {
  2806. this.$message.warning('请填写驳回意见')
  2807. return
  2808. }
  2809. this.submitRohs('N')
  2810. },
  2811. submitRohs (nodeConclusion) {
  2812. if (nodeConclusion === 'Y' && !this.canAgreeAction()) {
  2813. this.$message.warning('当前状态不允许同意')
  2814. return
  2815. }
  2816. if (nodeConclusion === 'N' && !this.canRejectAction()) {
  2817. this.$message.warning('当前状态不允许驳回')
  2818. return
  2819. }
  2820. if (!this.modalData.site || !this.modalData.referenceNo) {
  2821. this.$message.warning('单据主键信息缺失,无法提交审批')
  2822. return
  2823. }
  2824. this.$set(this.modalData, 'isAhGrade', this.normalizeCheckboxFlag(this.modalData.isAhGrade))
  2825. this.normalizeHsfStandardByCustomer(this.modalData)
  2826. this.syncHsfApproverFields()
  2827. if (!this.validateValidUntilPair()) {
  2828. return
  2829. }
  2830. this.syncExpiryDateByRule()
  2831. if (!this.nodeAuthorityLoaded) {
  2832. this.$message.warning('节点权限加载中,请稍后重试')
  2833. return
  2834. }
  2835. if (!this.validateSubmitRequiredFields()) {
  2836. return
  2837. }
  2838. const submitMaterialList = this.normalizeMaterialListForSave(this.modalData.materialList || [])
  2839. this.submitLoading = true
  2840. let params = {
  2841. ...this.modalData,
  2842. site: this.modalData.site,
  2843. referenceNo: this.modalData.referenceNo,
  2844. materialClassify: (this.modalData.materialClassifyList || []).join(';'),
  2845. qualificationDocumentsNeeded: (this.modalData.qualificationDocumentsNeededList || []).join(';'),
  2846. testReportIncludingItems: (this.modalData.testReportIncludingItemsList || []).join(';'),
  2847. materialList: submitMaterialList,
  2848. nodeConclusion: nodeConclusion,
  2849. rejectOpinion: nodeConclusion === 'N' ? this.rejectOpinion : '',
  2850. menuId: this.menuId,
  2851. documentNo: this.modalData.referenceNo
  2852. }
  2853. api.submitRohs(params).then(({data}) => {
  2854. if (data && data.code === 0) {
  2855. this.$message.success(nodeConclusion === 'Y' ? '同意成功' : '驳回成功')
  2856. this.submitModalFlag = false
  2857. this.modalFlag = false
  2858. this.getDataList()
  2859. } else {
  2860. this.$message.error(data.msg || '提交失败')
  2861. }
  2862. this.submitLoading = false
  2863. }).catch(() => {
  2864. this.submitLoading = false
  2865. })
  2866. },
  2867. // 下达
  2868. issueModal (row) {
  2869. if (!this.authIssue) {
  2870. this.$message.warning('没有下达权限')
  2871. return
  2872. }
  2873. this.$confirm('确认下达该申请单?', '提示', {
  2874. confirmButtonText: '确定',
  2875. cancelButtonText: '取消',
  2876. type: 'warning'
  2877. }).then(() => {
  2878. let params = {
  2879. site: row.site,
  2880. referenceNo: row.referenceNo,
  2881. menuId: this.menuId
  2882. }
  2883. api.issueRohs(params).then(({data}) => {
  2884. if (data && data.code === 0) {
  2885. this.$message.success('下达成功')
  2886. if (this.modalFlag && this.modalData.referenceNo === row.referenceNo) {
  2887. this.modalData.status = '审批中'
  2888. }
  2889. this.getDataList()
  2890. } else {
  2891. this.$message.error(data.msg || '下达失败')
  2892. }
  2893. })
  2894. })
  2895. },
  2896. deleteHandle () {
  2897. if (!this.authDelete) {
  2898. this.$message.warning('没有删除权限')
  2899. return
  2900. }
  2901. const selectedRows = (this.dataListSelections || []).filter(item => item && item.site && item.referenceNo)
  2902. if (!selectedRows.length) {
  2903. this.$message.warning('请先勾选要删除的单据')
  2904. return
  2905. }
  2906. const nonDraftRows = selectedRows.filter(item => item.status !== '草稿')
  2907. if (nonDraftRows.length) {
  2908. const previewText = nonDraftRows.slice(0, 3).map(item => item.referenceNo).join('、')
  2909. const suffix = nonDraftRows.length > 3 ? (' 等' + nonDraftRows.length + '条') : ''
  2910. this.$message.warning('仅草稿状态的单据允许删除,当前勾选包含非草稿单据:' + previewText + suffix)
  2911. return
  2912. }
  2913. this.$confirm('确认删除选中的' + selectedRows.length + '条RoHS单据?删除后会同步删除材料和附件数据。', '提示', {
  2914. confirmButtonText: '确定',
  2915. cancelButtonText: '取消',
  2916. type: 'warning'
  2917. }).then(() => {
  2918. const deleteTasks = selectedRows.map(item => {
  2919. return api.deleteRohs({
  2920. site: item.site,
  2921. referenceNo: item.referenceNo
  2922. }).then(({data}) => {
  2923. if (data && data.code === 0) {
  2924. return {
  2925. success: true,
  2926. referenceNo: item.referenceNo
  2927. }
  2928. }
  2929. return {
  2930. success: false,
  2931. referenceNo: item.referenceNo,
  2932. msg: (data && data.msg) || '删除失败'
  2933. }
  2934. }).catch(() => {
  2935. return {
  2936. success: false,
  2937. referenceNo: item.referenceNo,
  2938. msg: '删除失败'
  2939. }
  2940. })
  2941. })
  2942. Promise.all(deleteTasks).then(results => {
  2943. const successRows = results.filter(item => item.success)
  2944. const failRows = results.filter(item => !item.success)
  2945. if (this.modalFlag && successRows.some(item => item.referenceNo === this.modalData.referenceNo)) {
  2946. this.modalFlag = false
  2947. }
  2948. if (!failRows.length) {
  2949. this.$message.success('删除成功,共' + successRows.length + '条')
  2950. } else if (!successRows.length) {
  2951. this.$message.error(failRows[0].msg || '删除失败')
  2952. } else {
  2953. this.$message.warning('已删除' + successRows.length + '条,失败' + failRows.length + '条')
  2954. }
  2955. this.getDataList()
  2956. })
  2957. }).catch(() => {})
  2958. },
  2959. openProjectMaterialDialog () {
  2960. if (!this.canEditRohsMaterial()) {
  2961. this.$message.warning('当前状态不允许编辑材料')
  2962. return
  2963. }
  2964. this.projectMaterialDialogFlag = true
  2965. this.projectMaterialPageIndex = 1
  2966. this.searchProjectMaterialList()
  2967. },
  2968. searchProjectMaterialList () {
  2969. this.projectMaterialLoading = true
  2970. const params = {
  2971. page: this.projectMaterialPageIndex,
  2972. limit: this.projectMaterialPageSize,
  2973. site: this.$store.state.user.site,
  2974. partDesc: this.projectMaterialSearchData.partDesc,
  2975. finalPartNo: this.projectMaterialSearchData.finalPartNo,
  2976. partStatus: this.projectMaterialSearchData.partStatus
  2977. }
  2978. api.getRohsProjectMaterialList(params).then(({data}) => {
  2979. if (data && data.code === 0 && data.page) {
  2980. this.projectMaterialList = data.page.list || []
  2981. this.projectMaterialTotal = data.page.totalCount || 0
  2982. this.$nextTick(() => {
  2983. if (this.$refs.projectMaterialTable) {
  2984. this.$refs.projectMaterialTable.clearSelection()
  2985. }
  2986. })
  2987. } else {
  2988. this.projectMaterialList = []
  2989. this.projectMaterialTotal = 0
  2990. this.$message.error(data.msg || '物料查询失败')
  2991. }
  2992. this.projectMaterialLoading = false
  2993. }).catch(() => {
  2994. this.projectMaterialList = []
  2995. this.projectMaterialTotal = 0
  2996. this.projectMaterialLoading = false
  2997. })
  2998. },
  2999. projectMaterialSelectionChange (rows) {
  3000. this.projectMaterialSelections = rows || []
  3001. },
  3002. projectMaterialSizeChangeHandle (val) {
  3003. this.projectMaterialPageSize = val
  3004. this.projectMaterialPageIndex = 1
  3005. this.searchProjectMaterialList()
  3006. },
  3007. projectMaterialCurrentChangeHandle (val) {
  3008. this.projectMaterialPageIndex = val
  3009. this.searchProjectMaterialList()
  3010. },
  3011. confirmProjectMaterialSelection () {
  3012. if (!this.canEditRohsMaterial()) {
  3013. this.$message.warning('当前状态不允许编辑材料')
  3014. return
  3015. }
  3016. if (!this.projectMaterialSelections || this.projectMaterialSelections.length === 0) {
  3017. this.$message.warning('请至少选择一条物料')
  3018. return
  3019. }
  3020. const appendResult = this.appendMaterialRows(this.projectMaterialSelections)
  3021. if (!appendResult.appendedCount) {
  3022. this.$message.warning('所选物料已存在,未新增数据')
  3023. return
  3024. }
  3025. if (!this.shouldPersistMaterialsImmediately()) {
  3026. this.$set(this.modalData, 'materialList', appendResult.materialList)
  3027. this.projectMaterialDialogFlag = false
  3028. this.$message.success('已加入材料列表,保存单据后写入数据库')
  3029. return
  3030. }
  3031. this.$confirm('确认新增选中材料?', '提示', {
  3032. confirmButtonText: '确定',
  3033. cancelButtonText: '取消',
  3034. type: 'warning'
  3035. }).then(() => {
  3036. this.persistMaterialList(appendResult.materialList, '新增材料成功', () => {
  3037. this.projectMaterialDialogFlag = false
  3038. this.projectMaterialSelections = []
  3039. if (this.$refs.projectMaterialTable) {
  3040. this.$refs.projectMaterialTable.clearSelection()
  3041. }
  3042. })
  3043. }).catch(() => {})
  3044. },
  3045. appendMaterialRows (rows) {
  3046. const materialList = Array.isArray(this.modalData.materialList) ? [...this.modalData.materialList] : []
  3047. const exists = new Set(materialList.map(item => item.testPartNo))
  3048. let appendedCount = 0
  3049. rows.forEach(row => {
  3050. const testPartNo = row.testPartNo || row.test_part_no
  3051. if (!testPartNo || exists.has(testPartNo)) {
  3052. return
  3053. }
  3054. exists.add(testPartNo)
  3055. appendedCount++
  3056. materialList.push({
  3057. site: this.modalData.site,
  3058. referenceNo: this.modalData.referenceNo,
  3059. projectId: this.modalData.projectId,
  3060. testPartNo: testPartNo,
  3061. finalPartNo: row.finalPartNo || row.final_part_no || '',
  3062. partDesc: row.partDesc || row.part_desc || '',
  3063. partStatus: row.partStatus || row.part_status || ''
  3064. })
  3065. })
  3066. return {
  3067. materialList,
  3068. appendedCount
  3069. }
  3070. },
  3071. materialSelectionChange (rows) {
  3072. this.materialSelections = rows || []
  3073. },
  3074. shouldPersistMaterialsImmediately () {
  3075. return this.modalTitle === 'RoHS 编辑' && this.modalData && this.modalData.referenceNo && !String(this.modalData.referenceNo).startsWith('TEMP-')
  3076. },
  3077. normalizeMaterialListForSave (materialList) {
  3078. return (materialList || []).map((item, index) => {
  3079. return {
  3080. site: item.site || this.modalData.site || '',
  3081. referenceNo: item.referenceNo || this.modalData.referenceNo || '',
  3082. projectId: item.projectId || this.modalData.projectId || '',
  3083. testPartNo: item.testPartNo || item.test_part_no || '',
  3084. finalPartNo: item.finalPartNo || item.final_part_no || '',
  3085. partDesc: item.partDesc || item.part_desc || '',
  3086. partStatus: item.partStatus || item.part_status || '',
  3087. lineNo: index + 1
  3088. }
  3089. }).filter(item => item.testPartNo)
  3090. },
  3091. persistMaterialList (materialList, successMsg, successCallback) {
  3092. const normalizedList = this.normalizeMaterialListForSave(materialList)
  3093. const payload = {
  3094. site: this.modalData.site,
  3095. referenceNo: this.modalData.referenceNo,
  3096. projectId: this.modalData.projectId,
  3097. materialList: normalizedList
  3098. }
  3099. api.updateRohsMaterials(payload).then(({data}) => {
  3100. if (data && data.code === 0) {
  3101. this.$set(this.modalData, 'materialList', normalizedList)
  3102. this.materialSelections = []
  3103. if (this.currentRow && this.currentRow.referenceNo === this.modalData.referenceNo) {
  3104. this.$set(this.currentRow, 'materialList', normalizedList)
  3105. }
  3106. this.$message.success(successMsg || '保存成功')
  3107. if (typeof successCallback === 'function') {
  3108. successCallback()
  3109. }
  3110. } else {
  3111. this.$message.error((data && data.msg) || '保存失败')
  3112. }
  3113. }).catch(() => {
  3114. this.$message.error('保存失败')
  3115. })
  3116. },
  3117. removeSelectedMaterialRows () {
  3118. if (!this.canEditRohsMaterial()) {
  3119. this.$message.warning('当前状态不允许编辑材料')
  3120. return
  3121. }
  3122. if (!this.materialSelections || this.materialSelections.length === 0) {
  3123. this.$message.warning('请先选择要删除的材料')
  3124. return
  3125. }
  3126. const removeSet = new Set(this.materialSelections.map(item => item.testPartNo))
  3127. const materialList = (this.modalData.materialList || []).filter(item => !removeSet.has(item.testPartNo))
  3128. if (!this.shouldPersistMaterialsImmediately()) {
  3129. this.$set(this.modalData, 'materialList', materialList)
  3130. this.materialSelections = []
  3131. this.$message.success('已删除材料,保存单据后写入数据库')
  3132. return
  3133. }
  3134. this.$confirm('确认删除选中材料?', '提示', {
  3135. confirmButtonText: '确定',
  3136. cancelButtonText: '取消',
  3137. type: 'warning'
  3138. }).then(() => {
  3139. this.persistMaterialList(materialList, '删除材料成功')
  3140. }).catch(() => {})
  3141. },
  3142. // ======== chooseList相关方法 ========
  3143. // 获取基础数据列表
  3144. getBaseList (val, type) {
  3145. this.tagNo = val
  3146. this.tagNo1 = type
  3147. this.$nextTick(() => {
  3148. let strVal = ''
  3149. let conSql = ''
  3150. if (val === 102) {
  3151. if (type === 1) {
  3152. strVal = this.modalData.endCustomer
  3153. conSql = " order by Customer_no "
  3154. }
  3155. }
  3156. if (val === 103 || val === 2001 || val === 2054) {
  3157. if (type === 1) {
  3158. strVal = this.modalData.applicant
  3159. } else if (type === 3) {
  3160. strVal = this.modalData.npdEngineer
  3161. } else if (type === 4) {
  3162. strVal = this.modalData.technicalPlan
  3163. } else if (type === 5) {
  3164. strVal = this.modalData.pm
  3165. }
  3166. conSql = " and b.site = '" + this.$store.state.user.site + "'"
  3167. }
  3168. if (val === 2000) {
  3169. strVal = this.modalData.buyer
  3170. conSql = " and b.site = '" + this.$store.state.user.site + "'"
  3171. }
  3172. if (val === 110) {
  3173. strVal = this.modalData.commGroup1
  3174. }
  3175. if (val === 111) {
  3176. strVal = this.modalData.commGroup2
  3177. }
  3178. if (val === 130) {
  3179. strVal = this.modalData.commGroup3
  3180. }
  3181. this.$refs.baseList.init(val, strVal, conSql)
  3182. })
  3183. },
  3184. // 列表方法的回调
  3185. getBaseData (val) {
  3186. if (this.tagNo === 102) {
  3187. if (this.tagNo1 === 1) {
  3188. if (val.Customer_no === this.modalData.endCustomer) {
  3189. return
  3190. }
  3191. if (this.modalData.projectIdFlag) {
  3192. this.modalData.projectIdFlag = false
  3193. }
  3194. this.modalData.endCustomer = val.Customer_no
  3195. this.modalData.endCustomerName = val.Customer_desc
  3196. this.modalData.projectId = ''
  3197. this.modalData.projectName = ''
  3198. this.$set(this.modalData, 'materialList', [])
  3199. }
  3200. }
  3201. if (this.tagNo === 103 || this.tagNo === 2001 || this.tagNo === 2054) {
  3202. if (this.tagNo1 === 1) {
  3203. this.modalData.applicant = val.username
  3204. this.modalData.applicantName = val.user_display
  3205. } else if (this.tagNo1 === 3) {
  3206. this.modalData.npdEngineer = val.username
  3207. this.modalData.npdEngineerName = val.user_display
  3208. } else if (this.tagNo1 === 4) {
  3209. this.modalData.technicalPlan = val.username
  3210. this.modalData.technicalPlanName = val.user_display
  3211. } else if (this.tagNo1 === 5) {
  3212. this.modalData.pm = val.username
  3213. this.modalData.pmName = val.user_display
  3214. }
  3215. }
  3216. if (this.tagNo === 110) {
  3217. this.modalData.commGroup1 = val.product_group_id
  3218. this.modalData.commGroup1Desc = val.product_group_name
  3219. }
  3220. if (this.tagNo === 111) {
  3221. this.modalData.commGroup2 = val.product_group_id
  3222. this.modalData.commGroup2Desc = val.product_group_name
  3223. }
  3224. if (this.tagNo === 130) {
  3225. this.modalData.commGroup3 = val.product_group_id
  3226. this.modalData.commGroup3Desc = val.product_group_name
  3227. }
  3228. if (this.tagNo === 2000) {
  3229. this.modalData.buyer = val.username
  3230. this.modalData.buyerName = val.user_display
  3231. }
  3232. },
  3233. handleQueryCustomer() {
  3234. if (!this.modalData.endCustomer) {
  3235. this.modalData.endCustomerName = ''
  3236. this.modalData.projectId = ''
  3237. this.modalData.projectName = ''
  3238. this.modalData.projectIdFlag = true
  3239. this.$set(this.modalData, 'materialList', [])
  3240. return
  3241. }
  3242. let params = {
  3243. site: this.$store.state.user.site,
  3244. customerNo: this.modalData.endCustomer
  3245. }
  3246. queryCustomer(params).then(({data}) => {
  3247. if (data && data.code === 0) {
  3248. if (data.rows && data.rows.length === 1) {
  3249. const customer = data.rows[0]
  3250. this.modalData.endCustomerName = customer.customerDesc || customer.Customer_desc || customer.customerName || ''
  3251. this.modalData.projectIdFlag = !!this.modalData.endCustomerFlag
  3252. } else {
  3253. this.modalData.endCustomerName = ''
  3254. this.modalData.projectId = ''
  3255. this.modalData.projectName = ''
  3256. this.modalData.projectIdFlag = true
  3257. this.$set(this.modalData, 'materialList', [])
  3258. }
  3259. } else {
  3260. this.modalData.endCustomerName = ''
  3261. this.modalData.projectId = ''
  3262. this.modalData.projectName = ''
  3263. this.modalData.projectIdFlag = true
  3264. this.$set(this.modalData, 'materialList', [])
  3265. }
  3266. }).catch((error) => {
  3267. this.modalData.endCustomerName = ''
  3268. this.modalData.projectId = ''
  3269. this.modalData.projectName = ''
  3270. this.modalData.projectIdFlag = true
  3271. this.$set(this.modalData, 'materialList', [])
  3272. })
  3273. },
  3274. handleQueryProjectByCustomer() {
  3275. if (!this.modalData.projectId) {
  3276. this.modalData.projectName = ''
  3277. return
  3278. }
  3279. let params = {
  3280. site: this.$store.state.user.site,
  3281. projectId: this.modalData.projectId
  3282. }
  3283. if (this.modalData.endCustomer) {
  3284. params.customerId = this.modalData.endCustomer
  3285. }
  3286. queryProjectByCustomer(params).then(({data}) => {
  3287. if (data && data.code === 0) {
  3288. if (data.rows && data.rows.length === 1) {
  3289. const project = data.rows[0]
  3290. this.modalData.projectName = project.projectName || project.Project_name || ''
  3291. } else {
  3292. this.modalData.projectName = ''
  3293. }
  3294. } else {
  3295. this.modalData.projectName = ''
  3296. }
  3297. }).catch((error) => {
  3298. this.modalData.projectName = ''
  3299. })
  3300. },
  3301. projectClickRow(row) {
  3302. const oldProjectId = this.modalData.projectId
  3303. this.modalData.projectId = row.projectId
  3304. this.modalData.projectName = row.projectName
  3305. if (this.modalData.endCustomer && this.modalData.endCustomer !== '') {
  3306. // do nothing
  3307. } else {
  3308. this.modalData.endCustomer = row.customerId
  3309. this.modalData.endCustomerName = row.customerName
  3310. }
  3311. if (oldProjectId && oldProjectId !== row.projectId) {
  3312. this.$set(this.modalData, 'materialList', [])
  3313. }
  3314. this.chooseProjectListFlag = false
  3315. },
  3316. searchProjectInfoList() {
  3317. this.projectList = [];
  3318. if (this.modalData.endCustomer && this.modalData.endCustomer !== '') {
  3319. this.searchProjectData.customerId = this.modalData.endCustomer
  3320. } else {
  3321. this.searchProjectData.customerId = undefined
  3322. }
  3323. this.searchProjectData.site = this.$store.state.user.site
  3324. searchProjectInfoList(this.searchProjectData).then(({data}) => {
  3325. if (data && data.code === 0) {
  3326. const rows = data.rows || []
  3327. this.projectList = rows
  3328. if ((!this.modalData.endCustomer || this.modalData.endCustomer === '') && rows.length > 0) {
  3329. this.modalData.projectId = rows[0].projectId
  3330. this.modalData.projectName = rows[0].projectName
  3331. this.modalData.endCustomer = rows[0].customerId
  3332. this.modalData.endCustomerName = rows[0].customerName
  3333. }
  3334. } else {
  3335. this.projectList = []
  3336. }
  3337. }).catch((error) => {
  3338. this.$message.error('查询项目信息失败')
  3339. })
  3340. },
  3341. closeProjectInfoDialog() {
  3342. if(this.$refs.closeProjectInfoForm) {
  3343. this.$refs.closeProjectInfoForm.resetFields();
  3344. }
  3345. this.searchProjectData = {
  3346. site: this.$store.state.user.site,
  3347. projectId: undefined,
  3348. projectName: undefined,
  3349. customerId: undefined,
  3350. }
  3351. },
  3352. // 申请人输入校验
  3353. applicantBlur (tagNo) {
  3354. if (this.modalData.applicant != null && this.modalData.applicant !== '') {
  3355. let tempData = {
  3356. tagno: tagNo,
  3357. conditionSql: " and a.username = '" + this.modalData.applicant + "'" + " and b.site = '" + this.$store.state.user.site + "'"
  3358. }
  3359. verifyData(tempData).then(({data}) => {
  3360. if (data && data.code === 0) {
  3361. if (data.baseListData.length > 0) {
  3362. this.modalData.applicant = data.baseListData[0].username
  3363. this.modalData.applicantName = data.baseListData[0].user_display
  3364. return
  3365. }
  3366. }
  3367. this.modalData.applicantName = ''
  3368. })
  3369. } else {
  3370. this.modalData.applicantName = ''
  3371. }
  3372. },
  3373. // PM输入校验
  3374. pmBlur (tagNo) {
  3375. if (this.modalData.pm != null && this.modalData.pm !== '') {
  3376. let tempData = {
  3377. tagno: tagNo,
  3378. conditionSql: " and a.username = '" + this.modalData.pm + "'" + " and b.site = '" + this.$store.state.user.site + "'"
  3379. }
  3380. verifyData(tempData).then(({data}) => {
  3381. if (data && data.code === 0) {
  3382. if (data.baseListData.length > 0) {
  3383. this.modalData.pm = data.baseListData[0].username
  3384. this.modalData.pmName = data.baseListData[0].user_display
  3385. return
  3386. }
  3387. }
  3388. this.modalData.pmName = ''
  3389. })
  3390. } else {
  3391. this.modalData.pmName = ''
  3392. }
  3393. },
  3394. // NPD工程师输入校验
  3395. npdEngineerBlur (tagNo) {
  3396. if (this.modalData.npdEngineer != null && this.modalData.npdEngineer !== '') {
  3397. let tempData = {
  3398. tagno: tagNo,
  3399. conditionSql: " and a.username = '" + this.modalData.npdEngineer + "'" + " and b.site = '" + this.$store.state.user.site + "'"
  3400. }
  3401. verifyData(tempData).then(({data}) => {
  3402. if (data && data.code === 0) {
  3403. if (data.baseListData.length > 0) {
  3404. this.modalData.npdEngineer = data.baseListData[0].username
  3405. this.modalData.npdEngineerName = data.baseListData[0].user_display
  3406. return
  3407. }
  3408. }
  3409. this.modalData.npdEngineerName = ''
  3410. })
  3411. } else {
  3412. this.modalData.npdEngineerName = ''
  3413. }
  3414. },
  3415. // 技术计划输入校验
  3416. technicalPlanBlur (tagNo) {
  3417. if (this.modalData.technicalPlan != null && this.modalData.technicalPlan !== '') {
  3418. let tempData = {
  3419. tagno: tagNo,
  3420. conditionSql: " and a.username = '" + this.modalData.technicalPlan + "'" + " and b.site = '" + this.$store.state.user.site + "'"
  3421. }
  3422. verifyData(tempData).then(({data}) => {
  3423. if (data && data.code === 0) {
  3424. if (data.baseListData.length > 0) {
  3425. this.modalData.technicalPlan = data.baseListData[0].username
  3426. this.modalData.technicalPlanName = data.baseListData[0].user_display
  3427. return
  3428. }
  3429. }
  3430. this.modalData.technicalPlanName = ''
  3431. })
  3432. } else {
  3433. this.modalData.technicalPlanName = ''
  3434. }
  3435. },
  3436. // 采购输入校验
  3437. buyerBlur (tagNo) {
  3438. if (this.modalData.buyer != null && this.modalData.buyer !== '') {
  3439. let tempData = {
  3440. tagno: tagNo,
  3441. conditionSql: " and a.username = '" + this.modalData.buyer + "'" + " and b.site = '" + this.$store.state.user.site + "'"
  3442. }
  3443. verifyData(tempData).then(({data}) => {
  3444. if (data && data.code === 0) {
  3445. if (data.baseListData.length > 0) {
  3446. this.modalData.buyer = data.baseListData[0].username
  3447. this.modalData.buyerName = data.baseListData[0].user_display
  3448. return
  3449. }
  3450. }
  3451. this.modalData.buyerName = ''
  3452. })
  3453. } else {
  3454. this.modalData.buyerName = ''
  3455. }
  3456. },
  3457. // 商品组1输入校验
  3458. commGroup1Blur (tagNo) {
  3459. if (this.modalData.commGroup1 != null && this.modalData.commGroup1 !== '') {
  3460. let tempData = {
  3461. tagno: tagNo,
  3462. conditionSql: " and product_group_id = '" + this.modalData.commGroup1 + "'" + " and site = '" + this.$store.state.user.site + "'"
  3463. }
  3464. verifyData(tempData).then(({data}) => {
  3465. if (data && data.code === 0 && data.baseListData.length > 0) {
  3466. this.modalData.commGroup1 = data.baseListData[0].product_group_id
  3467. this.modalData.commGroup1Desc = data.baseListData[0].product_group_name
  3468. } else {
  3469. this.modalData.commGroup1Desc = ''
  3470. }
  3471. })
  3472. } else {
  3473. this.modalData.commGroup1Desc = ''
  3474. }
  3475. },
  3476. // 商品组2输入校验
  3477. commGroup2Blur (tagNo) {
  3478. if (this.modalData.commGroup2 != null && this.modalData.commGroup2 !== '') {
  3479. let tempData = {
  3480. tagno: tagNo,
  3481. conditionSql: " and product_group_id = '" + this.modalData.commGroup2 + "'" + " and site = '" + this.$store.state.user.site + "'"
  3482. }
  3483. verifyData(tempData).then(({data}) => {
  3484. if (data && data.code === 0 && data.baseListData.length > 0) {
  3485. this.modalData.commGroup2 = data.baseListData[0].product_group_id
  3486. this.modalData.commGroup2Desc = data.baseListData[0].product_group_name
  3487. } else {
  3488. this.modalData.commGroup2Desc = ''
  3489. }
  3490. })
  3491. } else {
  3492. this.modalData.commGroup2Desc = ''
  3493. }
  3494. },
  3495. // 商品组3输入校验
  3496. commGroup3Blur (tagNo) {
  3497. if (this.modalData.commGroup3 != null && this.modalData.commGroup3 !== '') {
  3498. let tempData = {
  3499. tagno: tagNo,
  3500. conditionSql: " and product_group_id = '" + this.modalData.commGroup3 + "'" + " and site = '" + this.$store.state.user.site + "'"
  3501. }
  3502. verifyData(tempData).then(({data}) => {
  3503. if (data && data.code === 0 && data.baseListData.length > 0) {
  3504. this.modalData.commGroup3 = data.baseListData[0].product_group_id
  3505. this.modalData.commGroup3Desc = data.baseListData[0].product_group_name
  3506. } else {
  3507. this.modalData.commGroup3Desc = ''
  3508. }
  3509. })
  3510. } else {
  3511. this.modalData.commGroup3Desc = ''
  3512. }
  3513. }
  3514. }
  3515. }
  3516. </script>
  3517. <style scoped lang="scss">
  3518. /deep/ .customer-tab .el-tabs__content {
  3519. padding: 0 !important;
  3520. }
  3521. /deep/ .rohs-material-table .el-table__header-wrapper th > .cell {
  3522. white-space: nowrap;
  3523. word-break: keep-all;
  3524. }
  3525. /deep/ .rohs-multiple-two-rows.el-select .el-input__inner,
  3526. /deep/ .rohs-multiple-two-rows .el-select .el-input__inner {
  3527. min-height: 62px !important;
  3528. height: auto !important;
  3529. padding-top: 6px !important;
  3530. padding-bottom: 6px !important;
  3531. }
  3532. /deep/ .rohs-multiple-two-rows.el-select .el-select__tags,
  3533. /deep/ .rohs-multiple-two-rows .el-select .el-select__tags {
  3534. max-width: calc(100% - 34px) !important;
  3535. max-height: 50px;
  3536. overflow-y: auto;
  3537. overflow-x: hidden;
  3538. white-space: normal;
  3539. }
  3540. /deep/ .rohs-multiple-two-rows.el-select .el-select__tags > span,
  3541. /deep/ .rohs-multiple-two-rows .el-select .el-select__tags > span {
  3542. display: inline;
  3543. max-width: 100%;
  3544. white-space: normal;
  3545. }
  3546. /deep/ .rohs-multiple-two-rows.el-select .el-select__tags .el-tag,
  3547. /deep/ .rohs-multiple-two-rows .el-select .el-select__tags .el-tag {
  3548. display: inline-flex;
  3549. max-width: 100%;
  3550. height: auto;
  3551. line-height: 16px;
  3552. padding-top: 2px;
  3553. padding-bottom: 2px;
  3554. margin-right: 4px;
  3555. white-space: normal;
  3556. vertical-align: middle;
  3557. }
  3558. /deep/ .rohs-multiple-two-rows.el-select .el-select__tags .el-tag .el-select__tags-text,
  3559. /deep/ .rohs-multiple-two-rows .el-select .el-select__tags .el-tag .el-select__tags-text {
  3560. white-space: normal;
  3561. word-break: break-all;
  3562. }
  3563. </style>