sampling.vue 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942
  1. <template>
  2. <hc-body split :project-nmae="projectInfo?.projectName">
  3. <template #tree>
  4. <TestTree
  5. :auto-expand-keys="treeAutoExpandKeys" :project-id="projectId" :tenant-id="userInfo?.tenant_id"
  6. :wbs-temp-id="projectInfo?.referenceWbsTemplateIdTrial" :wbs-type="2" @node-tap="wbsElTreeClick"
  7. />
  8. </template>
  9. <hc-new-card w-to="1919">
  10. <template #headerToSearch>
  11. <div class="w-50">
  12. <el-select v-model="searchForm.contractId" placeholder="选择合同段" filterable block>
  13. <el-option v-for="item in contractData" :key="item.id" :label="item.contractName" :value="item.id" />
  14. </el-select>
  15. </div>
  16. <div class="ml-2 w-250px">
  17. <hc-date-picker :dates="betweenTime" clearable @change="betweenTimeUpdate" />
  18. </div>
  19. <div class="ml-2 w-72">
  20. <el-input v-model="searchForm.queryValue" clearable placeholder="请输入名称、规格、样品编号查询" @keyup="keyUpEvent" />
  21. </div>
  22. <div class="ml-2">
  23. <el-button type="primary" @click="searchClick">
  24. <hc-icon name="search-2" />
  25. <span>搜索</span>
  26. </el-button>
  27. </div>
  28. </template>
  29. <template #extraToHeader>
  30. <hc-tooltip keys="tentative_material_sampling_add">
  31. <el-button :disabled="!primaryKeyId" hc-btn type="primary" @click="addFormModalClick">
  32. <hc-icon name="add-circle" />
  33. <span>新增</span>
  34. </el-button>
  35. </hc-tooltip>
  36. <hc-tooltip keys="tentative_material_sampling_edit">
  37. <el-button :disabled="tableCheckedKeys.length <= 0" hc-btn type="primary" color="#12C060" style="color: white;" @click="editFormModalClick">
  38. <hc-icon name="edit" />
  39. <span>编辑</span>
  40. </el-button>
  41. </hc-tooltip>
  42. <hc-tooltip keys="tentative_material_sampling_copy">
  43. <el-button :disabled="tableCheckedKeys.length <= 0" hc-btn color="#A16222" @click="copyTableModalClick">
  44. <hc-icon name="file-copy-2" />
  45. <span>复制</span>
  46. </el-button>
  47. </hc-tooltip>
  48. <hc-tooltip keys="tentative_material_sampling_del">
  49. <el-button v-del-com:[delModalClick] :disabled="tableCheckedKeys.length <= 0" hc-btn color="#e03997">
  50. <hc-icon name="delete-bin-2" />
  51. <span>删除</span>
  52. </el-button>
  53. </hc-tooltip>
  54. <hc-tooltip keys="tentative_material_sampling_printer">
  55. <el-button :disabled="tableCheckedKeys.length <= 0" :loading="printerLoading" hc-btn color="#567722" @click="printerClick">
  56. <hc-icon name="printer" />
  57. <span>打印</span>
  58. </el-button>
  59. </hc-tooltip>
  60. <hc-tooltip keys="tentative_material_sampling_import">
  61. <el-button :disabled="!primaryKeyId" hc-btn color="#567722" @click="importModalClick">
  62. <hc-icon name="folder-upload" />
  63. <span>导入</span>
  64. </el-button>
  65. </hc-tooltip>
  66. <hc-tooltip keys="tentative_material_sampling_delegation">
  67. <el-button hc-btn color="#E75643" :disabled="!nodeErTreeId" @click="delegationClick">
  68. <hc-icon name="slack" />
  69. <span>委托</span>
  70. </el-button>
  71. </hc-tooltip>
  72. </template>
  73. <hc-table
  74. ref="tableRef" :column="tableColumn" :datas="tableData" :loading="tableLoading" is-check
  75. :index-style="{ width: 60 }" :check-style="{ width: 29 }" @selection-change="tableSelection"
  76. >
  77. <template #materialCount="{ row }">{{ row.materialCount === -1 ? "" : row.materialCount }}</template>
  78. <template #representativeCount="{ row }">
  79. {{ row.representativeCount === -1 ? "" : row.representativeCount }}
  80. </template>
  81. </hc-table>
  82. <template #action>
  83. <hc-pages :pages="searchForm" @change="pageChange" />
  84. </template>
  85. </hc-new-card>
  86. <!-- 新增/编辑 -->
  87. <hc-new-dialog v-model="addEditFormModal" :title="`${addEditFormModel.id ? '编辑' : '新增'}样品信息`" is-row-footer widths="50rem" @close="addEditFormModalClose">
  88. <el-form ref="addEditFormRef" :model="addEditFormModel" :rules="addEditFormRules" label-width="auto" size="large">
  89. <div class="hc-form-item">
  90. <el-form-item label="样品名称" prop="materialName">
  91. <el-input v-model="addEditFormModel.materialName" />
  92. </el-form-item>
  93. <el-form-item label="进场日期">
  94. <el-date-picker v-model="addEditFormModel.mobilizationDate" :clearable="false" class="block" type="date" value-format="YYYY-MM-DD" />
  95. </el-form-item>
  96. </div>
  97. <div class="hc-form-item">
  98. <el-form-item label="样品编号" prop="specificationNumber">
  99. <el-input v-model="addEditFormModel.specificationNumber" />
  100. </el-form-item>
  101. <el-form-item label="取样日期">
  102. <el-date-picker v-model="addEditFormModel.samplingDate" :clearable="false" class="block" type="date" value-format="YYYY-MM-DD" />
  103. </el-form-item>
  104. </div>
  105. <div class="hc-form-item">
  106. <el-form-item label="规格型号">
  107. <el-input v-model="addEditFormModel.specificationModel" />
  108. </el-form-item>
  109. <el-form-item label="取样地点">
  110. <el-input v-model="addEditFormModel.samplingLocation" />
  111. </el-form-item>
  112. </div>
  113. <div class="hc-form-item">
  114. <el-form-item label="试样数量">
  115. <el-input v-model="addEditFormModel.materialCount" type="number" />
  116. </el-form-item>
  117. <el-form-item label="试样单位">
  118. <el-input v-model="addEditFormModel.calculationUnit" />
  119. </el-form-item>
  120. </div>
  121. <div class="hc-form-item">
  122. <el-form-item label="代表数量">
  123. <el-input v-model="addEditFormModel.representativeCount" type="number" />
  124. </el-form-item>
  125. <el-form-item label="代表单位">
  126. <el-input v-model="addEditFormModel.representativeUnit" />
  127. </el-form-item>
  128. </div>
  129. <div class="hc-form-item">
  130. <el-form-item label="是否外委">
  131. <el-radio-group v-model="addEditFormModel.isOutsourcing" size="large">
  132. <el-radio :value="1">是</el-radio>
  133. <el-radio :value="0">否</el-radio>
  134. </el-radio-group>
  135. </el-form-item>
  136. <el-form-item label="供应商">
  137. <el-input v-model="addEditFormModel.supplierUnit" />
  138. </el-form-item>
  139. </div>
  140. <div class="hc-form-item">
  141. <el-form-item label="生产批号">
  142. <el-input v-model="addEditFormModel.batchNumber" />
  143. </el-form-item>
  144. <el-form-item label="取样人">
  145. <el-select v-model="addEditFormModel.userId" block @change="changeusername">
  146. <el-option v-for="item in userListData" :key="item.userId" :label="item.userName" :value="item.userId" />
  147. </el-select>
  148. </el-form-item>
  149. </div>
  150. <div class="hc-form-item">
  151. <el-form-item label="拟用部位">
  152. <el-input v-model="addEditFormModel.proposedPosition" />
  153. </el-form-item>
  154. <el-form-item label="RFID编号">
  155. <el-input v-model="addEditFormModel.rfid" />
  156. </el-form-item>
  157. </div>
  158. <el-form-item label="样品描述">
  159. <el-input v-model="addEditFormModel.sampleDescription" />
  160. </el-form-item>
  161. </el-form>
  162. <template #leftRowFooter>
  163. <hc-tooltip keys="tentative_material_sampling_links">
  164. <el-button hc-btn type="primary" @click="linksApproachModalClick(addEditFormModel.mobilizationId)">
  165. <hc-icon name="links" />
  166. <span>关联进场材料</span>
  167. </el-button>
  168. </hc-tooltip>
  169. </template>
  170. <template #rightRowFooter>
  171. <el-button size="large" @click="addEditFormModalClose">
  172. <hc-icon name="close" />
  173. <span>取消</span>
  174. </el-button>
  175. <el-button :loading="addEditFormLoading" hc-btn type="primary" @click="addEditFormClick">
  176. <hc-icon name="check" />
  177. <span>确认</span>
  178. </el-button>
  179. </template>
  180. </hc-new-dialog>
  181. <!-- 关联进场材料 -->
  182. <hc-new-dialog v-model="linksApproachModal" is-row-footer is-table title="关联进场材料信息" widths="60%" @close="linksApproachModalClose">
  183. <hc-table :column="linksApproachTableColumn" :datas="linksApproachTableData" :is-index="false" :loading="linksApproachTableLoading">
  184. <template #materialType="{ row }">{{ getRowTableMaterialType(row.materialType) }}</template>
  185. <template #action="{ row }">
  186. <hc-tooltip keys="tentative_material_approach_annex">
  187. <el-button v-if="mobilizationId === row.id" plain size="small" type="primary" @click="cancelApproachRow(row)">取消关联</el-button>
  188. <el-button v-else plain size="small" type="primary" @click="linksApproachRow(row)">关联</el-button>
  189. </hc-tooltip>
  190. </template>
  191. </hc-table>
  192. <template #leftRowFooter>
  193. <hc-pages :pages="ApproachSearchForm" @change="linksApproachPageChange" />
  194. </template>
  195. <template #rightRowFooter>
  196. <el-button size="large" @click="linksApproachModalClose">
  197. <hc-icon name="close" />
  198. <span>取消</span>
  199. </el-button>
  200. <el-button hc-btn type="primary" @click="linksApproachModalSave">
  201. <hc-icon name="check" />
  202. <span>确定</span>
  203. </el-button>
  204. </template>
  205. </hc-new-dialog>
  206. <!-- 复制样品登记信息 -->
  207. <hc-new-dialog v-model="copyTableModal" :loading="copyTableLoading" is-table title="复制样品登记信息" widths="60rem" @close="copyTableModalClose" @save="copyTableClick">
  208. <hc-table :column="copyTableColumn" :datas="copyTableData" is-new :index-style="{ width: 60 }">
  209. <template #specificationNumber="{ row }">
  210. <el-input v-model="row.specificationNumber" placeholder="请输入样品编号" />
  211. </template>
  212. <template #action="{ index }">
  213. <el-button plain size="small" type="danger" @click="specificationNumberDel(index)">删除</el-button>
  214. </template>
  215. </hc-table>
  216. </hc-new-dialog>
  217. <!-- 导入 -->
  218. <hc-new-dialog v-model="importModal" is-row-footer title="导入" widths="38rem" @close="importModalClose">
  219. <HcDragUpload ref="uploadRef" api="/api/blade-business/material/" :datas="uploadData" action="sample/import" @finished="uploadFinished" @progress="uploadprogress" />
  220. <template #leftRowFooter>
  221. <el-button size="large" @click="downloadImportClick">
  222. <hc-icon name="download-2" />
  223. <span>下载模板</span>
  224. </el-button>
  225. </template>
  226. <template #rightRowFooter>
  227. <el-button size="large" @click="importModalClose">
  228. <hc-icon name="close" />
  229. <span>取消导入</span>
  230. </el-button>
  231. <el-button :loading="importModalLoading" hc-btn type="primary" @click="importModalYesClick">
  232. <hc-icon name="folder-upload" />
  233. <span>确认导入</span>
  234. </el-button>
  235. </template>
  236. </hc-new-dialog>
  237. <!-- 创建委托 -->
  238. <hc-new-dialog v-model="delegateModal" ui="hc-delegate-html-modal" is-table is-footer-center title="创建委托" widths="60rem" @close="delegateModalClose">
  239. <div class="hc-delegate-contract hc-flex h-40px">
  240. <el-select v-model="delegateContractId" placeholder="请先选择合同段" filterable class="w-400px" @change="delegateContractChange">
  241. <el-option v-for="item in contractData" :key="item.id" :label="item.contractName" :value="item.id" />
  242. </el-select>
  243. </div>
  244. <div class="hc-delegate-html" :class="delegateContractId ? 'is-show' : ''">
  245. <hc-table-form ref="htmlRef" :pkey="nodeErTreeId" :form="delegateHtmlForm" :html="delegateHtml" :loading="delegateHtmlLoading" @render="delegateHtmlRender" />
  246. </div>
  247. <template #footer>
  248. <el-button @click="delegateModalClose">取消</el-button>
  249. <el-button hc-btn type="primary" :loading="creatingDelegateLoading" @click="creatingDelegate">创建</el-button>
  250. </template>
  251. </hc-new-dialog>
  252. </hc-body>
  253. </template>
  254. <script setup>
  255. import { onActivated, ref, watch } from 'vue'
  256. import { useAppStore } from '~src/store'
  257. import TestTree from './components/TestTree.vue'
  258. import HcDragUpload from './components/HcDragUpload.vue'
  259. import { getStoreValue, setStoreValue } from '~src/utils/storage'
  260. import commissionApi from '~api/tentative/detect/commission'
  261. import samplingApi from '~api/tentative/material/sampling'
  262. import approachApi from '~api/tentative/material/approach'
  263. import { getContractUserList, getDictionary } from '~api/other'
  264. import { arrIndex, arrToId, deepClone, formValidate, getArrValue, getObjValue, isNullES, isString } from 'js-fast-way'
  265. import { toPdfPage } from '~uti/btn-auth'
  266. import Dayjs from 'dayjs'
  267. //变量
  268. const useAppState = useAppStore()
  269. const userInfo = ref(useAppState.getUserInfo)
  270. const projectId = ref(useAppState.getProjectId)
  271. const contractId = ref(useAppState.getContractId)
  272. const projectInfo = ref(useAppState.getProjectInfo)
  273. const isCollapse = ref(useAppState.getCollapse)
  274. //监听
  275. watch(() => useAppState.getCollapse, (collapse) => {
  276. isCollapse.value = collapse
  277. })
  278. //自动展开缓存
  279. const treeAutoExpandKeys = ref(getStoreValue('testTreeExpandKeys') || [])
  280. //渲染完成
  281. onActivated(() => {
  282. getContractData()
  283. getUserListData()
  284. getMaterialType()
  285. })
  286. //获取材料类型
  287. const typeData = ref([])
  288. const getMaterialType = async () => {
  289. const { data } = await getDictionary({
  290. code: 'material_type',
  291. })
  292. typeData.value = getArrValue(data)
  293. }
  294. //获取材料类型
  295. const getRowTableMaterialType = (type) => {
  296. if (type > 0) {
  297. const nodeData = typeData.value
  298. const index = arrIndex(nodeData, 'dictKey', type)
  299. return nodeData[index]?.dictValue ?? type
  300. } else {
  301. return ''
  302. }
  303. }
  304. //获取合同段信息
  305. const contractData = ref([])
  306. const getContractData = async () => {
  307. const { data } = await samplingApi.getErtractInfo({
  308. projectId: projectId.value,
  309. contractId: contractId.value,
  310. })
  311. const res = getArrValue(data)
  312. contractData.value = res
  313. if (res.length > 0) {
  314. searchForm.value.contractId = res[0].id
  315. searchClick()
  316. }
  317. }
  318. //获取用户列表
  319. const userListData = ref([])
  320. const getUserListData = async () => {
  321. const { data } = await getContractUserList({
  322. contractId: contractId.value,
  323. })
  324. userListData.value = getArrValue(data)
  325. }
  326. //搜索表单
  327. const searchForm = ref({
  328. startTime: null, endTime: null, queryValue: null, nodeId: '',
  329. current: 1, size: 20, total: 0,
  330. })
  331. //树相关的变量
  332. const primaryKeyId = ref('')
  333. const nodeErTreeId = ref('')
  334. const nodeItemInfo = ref({})
  335. const nodeDataInfo = ref({})
  336. //树被点击
  337. const wbsElTreeClick = ({ node, data, keys }) => {
  338. nodeItemInfo.value = node
  339. nodeDataInfo.value = data
  340. primaryKeyId.value = data['primaryKeyId'] || ''
  341. nodeErTreeId.value = data['erTreeId'] || ''
  342. //缓存自动展开
  343. treeAutoExpandKeys.value = keys
  344. setStoreValue('testTreeExpandKeys', keys)
  345. //改变搜索表单数据
  346. searchForm.value.nodeId = data['primaryKeyId'] || ''
  347. searchForm.value.current = 1
  348. getTableData()
  349. }
  350. //日期时间被选择
  351. const betweenTime = ref(null)
  352. const betweenTimeUpdate = ({ arr }) => {
  353. betweenTime.value = arr
  354. if (arr.length > 0) {
  355. searchForm.value.startTime = arr[0]
  356. searchForm.value.endTime = arr[1]
  357. } else {
  358. searchForm.value.startTime = ''
  359. searchForm.value.endTime = ''
  360. }
  361. }
  362. //回车搜索
  363. const keyUpEvent = (e) => {
  364. if (e.key === 'Enter') {
  365. searchForm.value.current = 1
  366. getTableData()
  367. }
  368. }
  369. //搜索
  370. const searchClick = () => {
  371. searchForm.value.current = 1
  372. getTableData()
  373. }
  374. //分页被点击
  375. const pageChange = ({ current, size }) => {
  376. searchForm.value.current = current
  377. searchForm.value.size = size
  378. getTableData()
  379. }
  380. //表格数据
  381. const tableRef = ref(null)
  382. const tableColumn = ref([
  383. { key: 'materialName', name: '取样名称' },
  384. { key: 'samplingDate', name: '取样日期' },
  385. { key: 'specificationNumber', name: '样品编号' },
  386. { key: 'specificationModel', name: '规格型号' },
  387. { key: 'materialCount', name: '试样数量' },
  388. { key: 'calculationUnit', name: '试样单位' },
  389. { key: 'proposedPosition', name: '拟用部位' },
  390. { key: 'representativeCount', name: '代表数量' },
  391. { key: 'representativeUnit', name: '代表单位' },
  392. { key: 'userName', name: '取样人' },
  393. ])
  394. //获取数据
  395. const tableLoading = ref(false)
  396. const tableData = ref([])
  397. const getTableData = async () => {
  398. const nodeId = primaryKeyId.value
  399. if (isNullES(nodeId)) return
  400. tableLoading.value = true
  401. const { error, code, data } = await samplingApi.queryPage({
  402. projectId: projectId.value,
  403. nodeId,
  404. ...searchForm.value,
  405. })
  406. //处理数据
  407. tableLoading.value = false
  408. if (!error && code === 200) {
  409. tableData.value = getArrValue(data['records'])
  410. searchForm.value.total = data.total || 0
  411. } else {
  412. tableData.value = []
  413. searchForm.value.total = 0
  414. }
  415. }
  416. //多选
  417. const tableCheckedKeys = ref([])
  418. const tableSelection = (rows) => {
  419. tableCheckedKeys.value = rows
  420. }
  421. //新增
  422. const addEditFormModal = ref(false)
  423. const addFormModalClick = () => {
  424. const toDayDate = new Dayjs().format('YYYY-MM-DD')
  425. addEditFormModel.value = {
  426. isOutsourcing: 0,
  427. mobilizationId: '',
  428. mobilizationDate: toDayDate,
  429. samplingDate: toDayDate,
  430. nodeId: primaryKeyId.value,
  431. userId: userInfo.value.user_id,
  432. }
  433. addEditFormModal.value = true
  434. }
  435. //编辑
  436. const editFormModalClick = () => {
  437. const keys = tableCheckedKeys.value
  438. if (keys.length === 1) {
  439. // addEditFormModel.value = keys[0]
  440. addEditFormModel.value = { ...keys[0] }
  441. addEditFormModel.value.representativeCount = addEditFormModel.value.representativeCount === -1 ? '' : addEditFormModel.value.representativeCount
  442. addEditFormModel.value.materialCount = addEditFormModel.value.materialCount === -1 ? '' : addEditFormModel.value.materialCount
  443. addEditFormModal.value = true
  444. } else if (keys.length > 1) {
  445. window?.$message?.warning('只能选择一条数据编辑')
  446. }
  447. }
  448. const addEditFormModalClose = () => {
  449. addEditFormModal.value = false
  450. addEditFormModel.value = {}
  451. }
  452. //新增/编辑 表单
  453. const addEditFormRef = ref(null)
  454. const addEditFormModel = ref({})
  455. const addEditFormRules = {
  456. materialName: {
  457. required: true,
  458. trigger: 'blur',
  459. message: '请输入样品名称',
  460. },
  461. specificationNumber: {
  462. required: false,
  463. validator: async (rule, value, callback) => {
  464. if (!value) {
  465. // callback(new Error('请输入样品编号'))
  466. } else {
  467. const ver = await verification(value)
  468. if (!ver) {
  469. callback(new Error('样品编号必须是惟一的'))
  470. } else {
  471. callback()
  472. }
  473. }
  474. },
  475. trigger: 'blur',
  476. },
  477. }
  478. //校验材料编号是否唯一
  479. const verification = async (val) => {
  480. const { error, code, data } = await samplingApi.verification({
  481. projectId: projectId.value,
  482. contractId: searchForm.value.contractId,
  483. specificationNumber: val,
  484. id: addEditFormModel.value.id ?? '',
  485. nodeId: primaryKeyId.value,
  486. })
  487. if (!error && code === 200) {
  488. return !data
  489. } else {
  490. return false
  491. }
  492. }
  493. //新增/编辑 保存
  494. const addEditFormLoading = ref(false)
  495. const addEditFormClick = async () => {
  496. const validate = await formValidate(addEditFormRef.value)
  497. if (validate) {
  498. addEditFormLoading.value = true
  499. const { error, code, msg } = await samplingApi.submitForm({
  500. ...addEditFormModel.value,
  501. projectId: projectId.value,
  502. contractId: searchForm.value.contractId,
  503. })
  504. //处理数据
  505. addEditFormLoading.value = false
  506. if (!error && code === 200) {
  507. window?.$message?.success('操作成功')
  508. addEditFormModal.value = false
  509. await getTableData()
  510. } else {
  511. window?.$message?.error(msg || '操作失败')
  512. }
  513. }
  514. }
  515. //复制表格
  516. const copyTableColumn = ref([
  517. { key: 'materialName', name: '样品名称' },
  518. { key: 'specificationNumber', name: '样品编号' },
  519. { key: 'action', name: '操作', width: 100 },
  520. ])
  521. const copyTableData = ref([])
  522. //复制
  523. const copyTableModal = ref(false)
  524. const copyTableModalClick = () => {
  525. copyTableModal.value = true
  526. copyTableData.value = deepClone(tableCheckedKeys.value)
  527. }
  528. //删除
  529. const specificationNumberDel = (index) => {
  530. copyTableData.value.splice(index, 1)
  531. const rows = copyTableData.value
  532. if (rows.length <= 0) {
  533. copyTableModal.value = false
  534. }
  535. }
  536. const copyTableModalClose = () => {
  537. copyTableModal.value = false
  538. }
  539. //复制 保存
  540. const copyTableLoading = ref(false)
  541. const copyTableClick = () => {
  542. copyTableModal.value = false
  543. const rows = copyTableData.value
  544. if (rows.length > 0) {
  545. for (let i = 0; i < rows.length; i++) {
  546. rows[i].dataNumber = i
  547. }
  548. tableCopyData(rows)
  549. } else {
  550. window.$message?.warning('请先在列表勾选要复制的数据')
  551. copyTableModal.value = false
  552. }
  553. }
  554. //复制数据请求
  555. const tableCopyData = async (rows) => {
  556. copyTableLoading.value = true
  557. const { error, code, msg } = await samplingApi.copyData(rows)
  558. //处理数据
  559. copyTableLoading.value = false
  560. if (!error && code === 200) {
  561. window?.$message?.success('操作成功')
  562. copyTableModal.value = false
  563. await getTableData()
  564. } else {
  565. window?.$message?.error(msg || '操作失败')
  566. }
  567. }
  568. //删除
  569. const delModalClick = async (_, resolve) => {
  570. await tableRemoveData()
  571. resolve()
  572. }
  573. //批量删除
  574. const tableRemoveData = async () => {
  575. const rows = tableCheckedKeys.value
  576. if (rows.length > 0) {
  577. const ids = arrToId(rows)
  578. //删除请求
  579. const { error, code, msg } = await samplingApi.removeData({
  580. projectId: projectId.value,
  581. contractId: searchForm.value.contractId,
  582. ids: ids,
  583. })
  584. //处理数据
  585. if (!error && code === 200) {
  586. window?.$message?.success('操作成功')
  587. searchClick()
  588. } else {
  589. window?.$message?.error(msg || '操作失败')
  590. }
  591. }
  592. }
  593. //打印
  594. const printerLoading = ref(false)
  595. const printerClick = async () => {
  596. const rows = tableCheckedKeys.value
  597. if (rows.length > 0) {
  598. printerLoading.value = true
  599. const ids = arrToId(rows)
  600. //删除请求
  601. const { error, code, data } = await samplingApi.exportPdf({
  602. projectId: projectId.value,
  603. contractId: searchForm.value.contractId,
  604. ids: ids,
  605. })
  606. //处理数据
  607. printerLoading.value = false
  608. if (!error && code === 200) {
  609. toPdfPage(data)
  610. //window.open(data, '_blank')
  611. }
  612. }
  613. }
  614. //导入
  615. const uploadRef = ref(null)
  616. const uploadData = ref({})
  617. //导入
  618. const importModal = ref(false)
  619. const importModalClick = () => {
  620. importModal.value = true
  621. uploadData.value = {
  622. contractId: searchForm.value.contractId,
  623. nodeId: primaryKeyId.value,
  624. isCovered: 1,
  625. }
  626. }
  627. //上传进度
  628. const uploadprogress = (res) => {
  629. importModalLoading.value = res
  630. }
  631. //确认导入
  632. const importModalLoading = ref(false)
  633. const importModalYesClick = () => {
  634. uploadRef.value?.submit()
  635. }
  636. //上传完成
  637. const uploadFinished = () => {
  638. importModal.value = false
  639. getTableData()
  640. }
  641. //关闭导入
  642. const importModalClose = () => {
  643. importModal.value = false
  644. }
  645. //更改取样人名称changeusername
  646. const changeusername = (item) => {
  647. userListData.value.forEach((ele) => {
  648. if (item == ele.userId) {
  649. addEditFormModel.value.userName = ele.userName
  650. }
  651. })
  652. }
  653. //关联进场材料
  654. const linksApproachModal = ref(false)
  655. const ApproachSearchForm = ref({
  656. current: 1, size: 20, total: 0,
  657. })
  658. const mobilizationId = ref('')
  659. const linksApproachModalClick = (mId) => {
  660. mobilizationId.value = mId ?? ''
  661. ApproachSearchForm.value.current = 1
  662. linksApproachModal.value = true
  663. getApproachTableData()
  664. }
  665. //分页被点击
  666. const linksApproachPageChange = ({ current, size }) => {
  667. ApproachSearchForm.value.current = current
  668. ApproachSearchForm.value.size = size
  669. getApproachTableData()
  670. }
  671. //关联进场材料数据
  672. const linksApproachTableColumn = ref([
  673. { key: 'materialNumber', name: '材料编号' },
  674. { key: 'mobilizationDate', name: '进场日期' },
  675. { key: 'materialName', name: '材料名称' },
  676. { key: 'materialType', name: '材料类型' },
  677. { key: 'specificationModel', name: '规格型号' },
  678. { key: 'supplierUnit', name: '供应商单位' },
  679. { key: 'proposedPosition', name: '拟用部位' },
  680. { key: 'userName', name: '记录人' },
  681. { key: 'action', name: '操作', width: 100, fixed: 'right', align: 'center' },
  682. ])
  683. const linksApproachTableData = ref([])
  684. //获取进场材料数据
  685. const linksApproachTableLoading = ref(false)
  686. const getApproachTableData = async () => {
  687. linksApproachTableLoading.value = true
  688. const { error, code, data } = await approachApi.queryPage({
  689. projectId: projectId.value,
  690. contractId: searchForm.value.contractId,
  691. ...ApproachSearchForm.value,
  692. })
  693. //处理数据
  694. linksApproachTableLoading.value = false
  695. if (!error && code === 200) {
  696. linksApproachTableData.value = getArrValue(data['records'])
  697. ApproachSearchForm.value.total = data.total || 0
  698. } else {
  699. linksApproachTableData.value = []
  700. ApproachSearchForm.value.total = 0
  701. }
  702. }
  703. //关联
  704. const linksApproachRow = (row) => {
  705. const toDayDate = new Dayjs().format('YYYY-MM-DD')
  706. const form = addEditFormModel.value
  707. form.materialName = row.materialName ?? '' //样品名称
  708. form.mobilizationDate = row.mobilizationDate ?? toDayDate //进场日期
  709. form.specificationNumber = row.materialNumber ?? '' //样品编号
  710. form.specificationModel = row.specificationModel ?? '' //规格型号
  711. form.supplierUnit = row.supplierUnit ?? '' //供应商
  712. form.calculationUnit = row.calculationUnit ?? '' //计算单位
  713. form.batchNumber = row.batchNumber ?? '' //生产批号
  714. form.proposedPosition = row.proposedPosition ?? '' //拟用部位
  715. form.mobilizationId = row.id //关联ID
  716. //更新数据
  717. addEditFormModel.value = form
  718. mobilizationId.value = row.id //关联ID
  719. }
  720. //取消关联
  721. const cancelApproachRow = (row) => {
  722. if (row.id === mobilizationId.value) {
  723. addEditFormModel.value.mobilizationId = ''
  724. mobilizationId.value = ''
  725. }
  726. }
  727. const linksApproachModalSave = () => {
  728. linksApproachModal.value = false
  729. }
  730. //关闭关联进场材料
  731. const linksApproachModalClose = () => {
  732. linksApproachModal.value = false
  733. }
  734. //下载导入模板
  735. const downloadImportClick = () => {
  736. window.open('https://blade-oss-chongqing.oss-cn-shenzhen.aliyuncs.com//upload/20221109/1f1cc15e4e4918d8c793fa6ec0a2ae2a.xlsx', '_blank')
  737. }
  738. //委托
  739. const htmlRef = ref(null)
  740. const delegateModal = ref(false)
  741. const delegateHtml = ref('')
  742. const delegateHtmlForm = ref({})
  743. const delegateHtmlLoading = ref(false)
  744. const delegateContractId = ref(null)
  745. const delegationClick = () => {
  746. const rows = tableCheckedKeys.value
  747. if (rows.length <= 0) {
  748. window.$message.warning('请先勾选一条需要委托的数据')
  749. return
  750. } else if (rows.length > 1) {
  751. window.$message.warning('只能选择其中一条数据进行委托')
  752. return
  753. }
  754. const data = rows[0]
  755. if (!isNullES(data.testId)) {
  756. window.$message.warning('已上报的数据不允许委托')
  757. return
  758. }
  759. delegateModal.value = true
  760. editHtmlId.value = data.id
  761. entrustId.value = data.entrustId
  762. delegateContractId.value = searchForm.value.contractId
  763. if (!isNullES(contractId)) {
  764. delegateContractChange()
  765. }
  766. }
  767. //合同段被选择
  768. const editHtmlId = ref('')
  769. const entrustId = ref('')
  770. const delegateContractChange = async () => {
  771. delegateHtmlLoading.value = true
  772. await getDelegateDataInfo(entrustId.value)
  773. await getDelegateExcelHtml()
  774. delegateHtmlLoading.value = false
  775. }
  776. //获取委托数据
  777. const getDelegateDataInfo = async (editId) => {
  778. const { error, code, msg, data } = await samplingApi.getBussDataInfoTrialEntrust({
  779. id: editId ?? null,
  780. pkeyId: nodeErTreeId.value,
  781. contractId: delegateContractId.value,
  782. })
  783. if (!error && code === 200) {
  784. delegateHtmlForm.value = getObjValue(data[0])
  785. } else {
  786. delegateHtmlForm.value = {}
  787. window.$message.error(msg || '获取委托信息失败')
  788. }
  789. }
  790. //获取委托html
  791. const getDelegateExcelHtml = async () => {
  792. const { error, code, msg, data } = await samplingApi.getExcelHtml({
  793. nodeId: primaryKeyId.value,
  794. contractId: contractId.value,
  795. })
  796. if (!error && code === 200) {
  797. delegateHtml.value = isString(data) ? data : ''
  798. nodeErTreeId.value = msg
  799. } else {
  800. delegateHtml.value = ''
  801. window.$message.error(msg || '获取委托信息失败')
  802. }
  803. }
  804. //渲染完成
  805. const delegateHtmlRender = (form) => {
  806. delegateHtmlForm.value = form
  807. }
  808. //创建委托
  809. const creatingDelegateLoading = ref(false)
  810. const creatingDelegate = async () => {
  811. const rows = tableCheckedKeys.value
  812. if (isNullES(delegateHtml.value)) {
  813. window.$message.error('暂无委托单信息')
  814. return
  815. }
  816. const form = delegateHtmlForm.value
  817. if (isNullES(delegateContractId.value)) {
  818. window.$message.warning('请先选择合同段')
  819. return
  820. }
  821. creatingDelegateLoading.value = true
  822. form.contractId = delegateContractId.value
  823. form.nodeErTreeId = nodeErTreeId.value
  824. form.sampleId = editHtmlId.value
  825. form.nodeId = rows[0].nodeId
  826. const { error, code, msg } = await commissionApi.htmlSave(form)
  827. creatingDelegateLoading.value = false
  828. if (!error && code === 200) {
  829. window.$message.success('创建成功')
  830. delegateModalClose()
  831. } else {
  832. window.$message.error(msg || '创建失败')
  833. }
  834. }
  835. //关闭委托
  836. const delegateModalClose = () => {
  837. delegateModal.value = false
  838. delegateHtml.value = ''
  839. delegateHtmlForm.value = {}
  840. delegateHtmlLoading.value = false
  841. creatingDelegateLoading.value = false
  842. }
  843. </script>
  844. <style lang="scss" scoped>
  845. @import "../../../styles/tentative/material/sampling.scss";
  846. </style>
  847. <style lang="scss">
  848. .el-overlay-dialog .el-dialog.hc-new-dialog.hc-delegate-html-modal {
  849. .hc-new-dialog-body {
  850. padding: 0;
  851. }
  852. .hc-table-form-data-item {
  853. padding: 0;
  854. .el-scrollbar__bar.is-vertical {
  855. right: 0;
  856. }
  857. }
  858. }
  859. .hc-delegate-html-modal {
  860. .hc-delegate-html {
  861. position: relative;
  862. height: calc(100% - 40px);
  863. .hc-table-form-data-item {
  864. background-color: #efefef;
  865. }
  866. &::after {
  867. content: "";
  868. position: absolute;
  869. inset: 0;
  870. background: rgb(161 161 161 / 40%);
  871. z-index: 22;
  872. }
  873. &.is-show {
  874. &::after {
  875. display: none;
  876. z-index: -1;
  877. }
  878. }
  879. }
  880. }
  881. </style>