experimentReport.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  1. <template>
  2. <u-popup :show="show" @close="cancel" :closeable="false">
  3. <view class="mainBox">
  4. <uni-nav-bar fixed="true" statusBar="true" left-icon="back" title="实验" @clickLeft="cancel">
  5. </uni-nav-bar>
  6. <view class="wrapper">
  7. <view class="herder_item">
  8. <view class="herder_text"></view>
  9. <view class="herder_view">
  10. 实验时间
  11. </view>
  12. </view>
  13. <view class="marginTop20">
  14. <uni-datetime-picker v-if="type=='edit'" type="datetime"
  15. v-model="form.experimentalTime"></uni-datetime-picker>
  16. <u-input v-else :disabled="true" placeholder=" " border="surround"
  17. :value="form.experimentalTime"></u-input>
  18. </view>
  19. <view class="herder_item marginTop20">
  20. <view class="herder_text"></view>
  21. <view class="herder_view">
  22. 执行标准
  23. </view>
  24. </view>
  25. <u--input suffixIcon="arrow-right" style="background-color:#fff ;" :disabledColor="'#ffffff'"
  26. :disabled="true" class="marginTop20" placeholder=" " border="surround"
  27. :value="getDictValue('质检标准类型', projectData.qualityStandardType+'')">
  28. </u--input>
  29. <view class="herder_item marginTop20">
  30. <view class="herder_text"></view>
  31. <view class="herder_view">
  32. 实验室
  33. </view>
  34. </view>
  35. <view class="marginTop20">
  36. <uni-data-picker v-if="type=='edit'" :disabled='type=="view"' v-model="form.workshopName"
  37. placeholder="请选择" :localdata="laboratoryList" @change="getWorkshopId">
  38. </uni-data-picker>
  39. <u-input v-else :disabled="true" placeholder=" " border="surround"
  40. :value="form.workshopName"></u-input>
  41. </view>
  42. <!-- <view class="herder_item marginTop20">
  43. <view class="herder_text"></view>
  44. <view class="herder_view">
  45. 实验设备
  46. </view>
  47. </view> -->
  48. <view v-for="(item, index) in form.experimentEquipmentList">
  49. <view class="herder_item marginTop20" @click="delEquipmentList(index)">
  50. <view class="herder_text"></view>
  51. <view class="herder_view">
  52. 实验设备{{(index + 1)}}
  53. </view>
  54. <u-icon name="trash-fill" style="margin-ledt: 10rpx;" color="red" v-if="type=='edit'"></u-icon>
  55. </view>
  56. <u--input class="marginTop20" readonly placeholder="请选择" border="surround" :disabled="type=='view'"
  57. @click.native="add(index,'experimentEquipmentList',2)" v-model="item.equipmentName">
  58. </u--input>
  59. <view class="herder_item marginTop20">
  60. <view class="herder_text"></view>
  61. <view class="herder_view">
  62. 开始时间
  63. </view>
  64. </view>
  65. <uni-datetime-picker v-if="type=='edit'" type="datetime" class="marginTop20"
  66. v-model="item.startTime"></uni-datetime-picker>
  67. <u-input v-else :disabled="true" placeholder=" " border="surround" class="marginTop20"
  68. :value="item.startTime"></u-input>
  69. <view class="herder_item marginTop20">
  70. <view class="herder_text"></view>
  71. <view class="herder_view">
  72. 结束时间
  73. </view>
  74. </view>
  75. <uni-datetime-picker v-if="type=='edit'" type="datetime" class="marginTop20"
  76. v-model="item.endTime"></uni-datetime-picker>
  77. <u-input v-else :disabled="true" placeholder=" " border="surround" class="marginTop20"
  78. :value="item.endTime"></u-input>
  79. <view class="herder_item marginTop20">
  80. <view class="herder_text"></view>
  81. <view class="herder_view">
  82. 运行参数
  83. </view>
  84. </view>
  85. <u-input class="marginTop20" placeholder="请输入内容" border="surround" :disabled="type=='view'"
  86. v-model="item.operatingParameters">
  87. </u-input>
  88. </view>
  89. <view class="marginTop20" v-if="type=='edit'">
  90. <view class="experimentP" @click="addExperimentEquipmentList"><u-icon name="plus-circle"
  91. style="margin-right: 10rpx;"></u-icon>添加实验设备
  92. </view>
  93. </view>
  94. <view class="herder_item marginTop20">
  95. <view class="herder_text"></view>
  96. <view class="herder_view">
  97. 工艺要求
  98. </view>
  99. </view>
  100. <view class="marginTop20 defValue">
  101. {{ form.processRequirementsJson}}
  102. </view>
  103. <view class="herder_item marginTop20">
  104. <view class="herder_text"></view>
  105. <view class="herder_view">
  106. 实验工具
  107. </view>
  108. <u-badge max="99" :value="form.toolJson.length"></u-badge>
  109. </view>
  110. <view class="marginTop20">
  111. <view class="experimentP" @click="addTool('toolJson')"><u-icon name="plus-circle"
  112. style="margin-right: 10rpx;"></u-icon> {{type=='view'?'查看实验工具':'添加实验工具'}}
  113. </view>
  114. </view>
  115. <view class="herder_item marginTop20">
  116. <view class="herder_text"></view>
  117. <view class="herder_view">
  118. 实验耗材
  119. </view>
  120. <u-badge max="99" :value="form.consumablesJson.length"></u-badge>
  121. </view>
  122. <view class="marginTop20">
  123. <view class="experimentP" @click="addTool('consumablesJson')"><u-icon name="plus-circle"
  124. style="margin-right: 10rpx;"></u-icon> {{type=='view'?'查看实验耗材':'添加实验耗材'}}
  125. </view>
  126. </view>
  127. <view class="herder_item marginTop20">
  128. <view class="herder_text"></view>
  129. <view class="herder_view">
  130. 实验过程
  131. </view>
  132. </view>
  133. <experimentationProcess ref="experimentationProcess1" :readonly="type=='view'" class="marginTop20"></experimentationProcess>
  134. <view class="herder_item marginTop20">
  135. <view class="herder_text"></view>
  136. <view class="herder_view">
  137. 实验记录
  138. </view>
  139. </view>
  140. <experimentationProcess ref="experimentationProcess2" :readonly="type=='view'" class="marginTop20"></experimentationProcess>
  141. <view class="herder_item marginTop20">
  142. <view class="herder_text"></view>
  143. <view class="herder_view">
  144. 实验结果
  145. </view>
  146. </view>
  147. <u--textarea class="marginTop20" placeholder="请输入内容" border="surround" autoHeight
  148. :disabled="type=='view'" v-model="form.resultsDescription"></u--textarea>
  149. <view class="herder_item marginTop20">
  150. <view class="herder_text"></view>
  151. <view class="herder_view">
  152. 实验结论
  153. </view>
  154. </view>
  155. <uni-data-picker v-if="type!='view'" class="marginTop20" v-model="form.results" placeholder="请选择"
  156. :localdata="[{
  157. text:'合格',value:1
  158. },{
  159. text:'不合格',value:2
  160. }]">
  161. </uni-data-picker>
  162. <u-input disabled v-else class="marginTop20" placeholder="请输入内容" border="surround"
  163. :value="form.results==2?'不合格':'合格'">
  164. </u-input>
  165. <view class="herder_item marginTop20">
  166. <view class="herder_text"></view>
  167. <view class="herder_view">
  168. 实验图片
  169. </view>
  170. </view>
  171. <view v-if="type!='view'" class="marginTop20 imgAdd" @click="chooseImage('imgUrl')">
  172. <u-icon name="camera"></u-icon>
  173. </view>
  174. <PreviewPhoto :type="type" @imagedelete="imagedelete" :imageList="imgUrl" />
  175. <view class="herder_item marginTop20">
  176. <view class="herder_text"></view>
  177. <view class="herder_view">
  178. 附件图片
  179. </view>
  180. </view>
  181. <view v-if="type!='view'" class="marginTop20 imgAdd" @click="chooseImage('attachmentUrl')">
  182. <u-icon name="camera"></u-icon>
  183. </view>
  184. <PreviewPhoto :type="type" @imagedelete="imagedelete1" :imageList="attachmentUrl" />
  185. </view>
  186. <view style="height: 84rpx;"></view>
  187. <view class="footerButton">
  188. <u-button @click="cancel" type="default" text="返回"></u-button>
  189. <u-button v-if="type!='view'" type="primary" @click="save" text="保存"></u-button>
  190. </view>
  191. </view>
  192. <u-popup :show="toolJsonShow" :closeable="false" v-if="toolJsonShow">
  193. <view style="min-height:400rpx;position:relative">
  194. <uni-nav-bar fixed="true" statusBar="true" left-icon="back" :title="toolKey=='toolJson'?'实验工具':'实验耗材'"
  195. @clickLeft="toolJsonShow=false">
  196. </uni-nav-bar>
  197. <view v-for="(item, index) in form[toolKey]" :key="index" style="position: relative;">
  198. <myCard :item="item" :index="index+1" :btnList="[{
  199. name: '删除',
  200. apiName: 'del',
  201. btnType: 'error ',
  202. type: '2',
  203. pageUrl: '',
  204. judge: [{
  205. fn: isBtn
  206. }],
  207. }]" :columns="columns()" @del="del(index)">
  208. <u-input slot="batchNo" placeholder="请输入" border="surround" :disabled="type=='view'"
  209. v-model="item.batchNo">
  210. </u-input>
  211. <u--textarea slot="remark" placeholder="请输入内容" border="surround" autoHeight
  212. :disabled="type=='view'" v-model="item.remark"></u--textarea>
  213. </myCard>
  214. </view>
  215. <view class="add" @click="add(-1,toolKey,1)" v-if="type=='edit'">
  216. <u-icon name="plus" color="#fff"></u-icon>
  217. </view>
  218. </view>
  219. </u-popup>
  220. </u-popup>
  221. </template>
  222. <script>
  223. const defForm = {
  224. experimentalTime: '',
  225. qualityStandardType: '',
  226. workshopId: '',
  227. workshopName: '',
  228. processRequirementsJson: '',
  229. resultsDescription: '',
  230. results: 1,
  231. experimentEquipmentList: [],
  232. imgUrl: [],
  233. attachmentUrl: [],
  234. toolJson: [],
  235. consumablesJson: [],
  236. correlationId: '',
  237. qualityStandardName: '',
  238. qualityStandardId: '',
  239. qualityWorkOrderId: '',
  240. }
  241. import dictMixns from '@/mixins/dictMixins'
  242. import {
  243. getFactoryarea,
  244. getByIdExperiment,
  245. saveExperiment,
  246. updateExperiment
  247. } from '@/api/inspectionWork/index.js'
  248. import PreviewPhoto from '@/pages/maintenance/check/components/PreviewPhoto.vue'
  249. import myCard from '@/pages/saleManage/components/myCard.vue'
  250. import experimentationProcess from '@/components/templateDiv/experimentationProcess.vue'
  251. export default {
  252. mixins: [dictMixns],
  253. components: {
  254. PreviewPhoto,
  255. myCard,
  256. experimentationProcess
  257. },
  258. props: {
  259. type: {
  260. type: String,
  261. default: 'view'
  262. },
  263. },
  264. computed: {
  265. imgUrl() {
  266. return this.form.imgUrl.map(item => {
  267. return this.getFileUrl(item)
  268. })
  269. },
  270. attachmentUrl() {
  271. return this.form.attachmentUrl.map(item => {
  272. return this.getFileUrl(item)
  273. })
  274. }
  275. },
  276. data() {
  277. return {
  278. dateShow: false,
  279. toolJsonShow: false,
  280. form: {
  281. ...defForm
  282. },
  283. laboratoryList: [],
  284. show: false,
  285. currentIndex: '',
  286. currentKey: '',
  287. toolKey: '',
  288. projectData: {}
  289. }
  290. },
  291. created() {
  292. uni.$off('setProduceList')
  293. uni.$on('setProduceList', (data) => {
  294. if (this.currentKey == 'experimentEquipmentList') {
  295. this.$set(
  296. this.form[this.currentKey][this.currentIndex],
  297. 'equipmentId',
  298. data[0].id
  299. );
  300. this.$set(
  301. this.form[this.currentKey][this.currentIndex],
  302. 'equipmentName',
  303. data[0].name
  304. );
  305. } else {
  306. this.form[this.currentKey].push(...data)
  307. }
  308. })
  309. },
  310. onUnload() {
  311. uni.$off('setProduceList')
  312. },
  313. methods: {
  314. isBtn() {
  315. return this.type == 'edit'
  316. },
  317. columns() {
  318. console.log(this.toolKey, 'this.toolKey')
  319. if (this.toolKey == 'toolJson') {
  320. return [
  321. [{
  322. label: '工具名称:',
  323. prop: 'name',
  324. type: 'title',
  325. }],
  326. [{
  327. label: '型号:',
  328. prop: 'modelType'
  329. }],
  330. [{
  331. label: '编号:',
  332. prop: 'code'
  333. }],
  334. [{
  335. label: '操作:',
  336. prop: 'action',
  337. type: 'action',
  338. className: 'perce100',
  339. }],
  340. ]
  341. } else {
  342. return [
  343. [{
  344. label: '耗材名称:',
  345. prop: 'name',
  346. type: 'title',
  347. }],
  348. [{
  349. label: '编号:',
  350. prop: 'code'
  351. }],
  352. [{
  353. label: '批次号:',
  354. prop: 'batchNo',
  355. slot: 'batchNo',
  356. }],
  357. [{
  358. label: '浓度:',
  359. prop: 'specification',
  360. }],
  361. [{
  362. label: '来源:',
  363. prop: 'gys',
  364. }],
  365. [{
  366. label: '过程:',
  367. prop: 'remark',
  368. slot: 'remark',
  369. }],
  370. [{
  371. label: '操作:',
  372. prop: 'action',
  373. type: 'action',
  374. className: 'perce100',
  375. }],
  376. ]
  377. }
  378. },
  379. getFileUrl(item) {
  380. let fileNames = item.storePath.split('/')
  381. let url = this.apiUrl +
  382. '/main/file/getFile?objectName=' + item.storePath +
  383. '&fullfilename=' + fileNames[fileNames.length -
  384. 1]
  385. return url
  386. },
  387. getWorkshopId({
  388. detail
  389. }) {
  390. if (detail.value[0]) {
  391. this.form.workshopId = detail.value[0].value
  392. } else {
  393. this.form.workshopId = ''
  394. }
  395. },
  396. add(index, key, type) {
  397. this.currentIndex = index;
  398. this.currentKey = key
  399. uni.navigateTo({
  400. url: '/pages/purchasingManage/components/selectProduce?isAll=' + type
  401. })
  402. },
  403. imagedelete(index) {
  404. this.form.imgUrl.splice(index, 1);
  405. },
  406. imagedelete1(index) {
  407. this.form.attachmentUrl.splice(index, 1);
  408. },
  409. addTool(key) {
  410. this.toolKey = key
  411. this.toolJsonShow = true
  412. },
  413. del(index) {
  414. this.form[this.toolKey].splice(index, 1);
  415. },
  416. delEquipmentList(index) {
  417. if (this.view == 'view') {
  418. return
  419. }
  420. this.form.experimentEquipmentList.splice(index, 1);
  421. },
  422. async open(row, type) {
  423. this.projectData = row
  424. if (row.experimentId) {
  425. this.$set(this, 'form', await getByIdExperiment(row.experimentId));
  426. } else {
  427. this.form.correlationId = row.id;
  428. this.form.qualityStandardName = row.qualityStandardName;
  429. this.form.qualityStandardId = row.qualityStandardId;
  430. this.form.qualityWorkOrderId = row.qualityWorkOrderId;
  431. this.form.recordJson = row.recordJson;
  432. this.form.procedureJson = row.procedureJson;
  433. if (row.symbol) {
  434. this.form.processRequirementsJson += row.symbol;
  435. }
  436. if (row.textType == 3) {
  437. this.form.processRequirementsJson +=
  438. row.minValue + '-' + row.maxValue;
  439. } else {
  440. this.form.processRequirementsJson += row.defaultValue;
  441. }
  442. if (row.unitName) {
  443. this.form.processRequirementsJson += row.unitName;
  444. }
  445. }
  446. getFactoryarea({
  447. pageNum: 1,
  448. size: 1000,
  449. type: 3
  450. }).then(res => {
  451. this.laboratoryList = res.list.map(item => {
  452. return {
  453. text: item.workshopName,
  454. value: item.workshopId
  455. }
  456. })
  457. })
  458. this.show = true
  459. this.$nextTick(() => {
  460. // console.log(this.form,'this.form')
  461. if (this.form.procedureJson) {
  462. this.$refs.experimentationProcess1.init(
  463. this.form.procedureJson.tempJson
  464. );
  465. }
  466. if (this.form.recordJson) {
  467. this.$refs.experimentationProcess2.init(
  468. this.form.recordJson.tempJson
  469. );
  470. }
  471. });
  472. // this.init()
  473. },
  474. chooseImage(key) {
  475. const _this = this
  476. uni.chooseImage({
  477. count: 9, //默认9
  478. sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
  479. success: function(res) {
  480. uni.showLoading({
  481. title: '加载中'
  482. })
  483. _this.uploadFile(res.tempFilePaths).then(res => {
  484. _this.form[key].push(...res)
  485. console.log(this.form)
  486. // res.forEach(item => {
  487. // let fileNames = item.storePath.split('/')
  488. // let url = _this.apiUrl +
  489. // '/main/file/getFile?objectName=' + item.storePath +
  490. // '&fullfilename=' + fileNames[fileNames.length -
  491. // 1]
  492. // _this.imgs.push(url)
  493. // })
  494. uni.hideLoading()
  495. })
  496. }
  497. });
  498. },
  499. uploadFile(list) {
  500. let PromiseAll = []
  501. const apiUrl = this.apiUrl
  502. const token = uni.getStorageSync("token"); //取存本地的token
  503. list.forEach(item => {
  504. PromiseAll.push(
  505. new Promise((resolve, reject) => {
  506. uni.uploadFile({
  507. url: apiUrl + '/main/file/upload',
  508. filePath: item,
  509. name: 'multiPartFile',
  510. header: {
  511. authorization: token
  512. },
  513. success: (uploadFileRes) => {
  514. let data = JSON.parse(uploadFileRes.data)
  515. resolve(data.data)
  516. }
  517. });
  518. }),
  519. )
  520. })
  521. return Promise.all(PromiseAll)
  522. },
  523. cancel() {
  524. this.form = {
  525. ...defForm
  526. }
  527. this.show = false;
  528. },
  529. addExperimentEquipmentList() {
  530. this.form.experimentEquipmentList.push({});
  531. },
  532. save() {
  533. // if (!this.form.qualityResultContent) {
  534. // this.$refs.uToast.show({
  535. // type: "error",
  536. // icon: false,
  537. // message: "请填写质检内容!",
  538. // }, )
  539. // return
  540. // }
  541. // if (!this.form.sampleQuantity) {
  542. // this.$refs.uToast.show({
  543. // type: "error",
  544. // icon: false,
  545. // message: "请填写样品数!",
  546. // }, )
  547. // return
  548. // }
  549. let data = JSON.parse(JSON.stringify(this.form));
  550. let procedureJson = this.$refs.experimentationProcess1.getValue();
  551. let recordJson = this.$refs.experimentationProcess2.getValue();
  552. if (procedureJson) {
  553. data.procedureJson = {
  554. tempJson: JSON.stringify(procedureJson)
  555. };
  556. }
  557. if (recordJson) {
  558. data.recordJson = {
  559. tempJson: JSON.stringify(recordJson)
  560. };
  561. }
  562. let api = data.id ? updateExperiment : saveExperiment
  563. // console.log(data,'data')
  564. // return
  565. api(data)
  566. .then((msg) => {
  567. this.$emit('experimentReportSuccess', {
  568. workId: data.qualityWorkOrderId,
  569. projectId: this.projectData.id,
  570. })
  571. this.cancel()
  572. })
  573. .catch((e) => {
  574. this.cancel()
  575. });
  576. },
  577. }
  578. }
  579. </script>
  580. <style lang="scss" scoped>
  581. .mainBox {
  582. background-color: #f3f8fb;
  583. height: 100vh;
  584. font-size: 27rpx;
  585. overflow-y: auto;
  586. }
  587. .footerButton {
  588. width: 100%;
  589. height: 84rpx;
  590. display: flex;
  591. position: fixed;
  592. bottom: 0;
  593. z-index: 10;
  594. background-color: #fff;
  595. /deep/.u-button {
  596. height: 100%;
  597. }
  598. >view {
  599. flex: 1;
  600. }
  601. }
  602. .defValue {
  603. color: #c1353c;
  604. text-indent: 2ch;
  605. }
  606. /deep/.uni-textarea {
  607. padding: 0;
  608. max-height: auto;
  609. }
  610. /deep/uni-textarea {
  611. max-height: auto;
  612. }
  613. /deep/.input-value {
  614. font-size: 28rpx !important;
  615. height: 70rpx
  616. }
  617. .defValue {
  618. color: #c1353c;
  619. text-indent: 2ch;
  620. }
  621. .marginTop20 {
  622. margin-top: 30rpx;
  623. }
  624. .herder_item {
  625. display: flex;
  626. font-weight: bold;
  627. // font-size: 26rpx;
  628. .herder_text {
  629. min-width: 10rpx;
  630. height: 32rpx;
  631. border-radius: 10rpx;
  632. background: #00c0a1;
  633. margin-right: 12rpx;
  634. margin-top: 5rpx;
  635. }
  636. }
  637. .wrapper {
  638. width: 720rpx;
  639. background: #fff;
  640. margin: 20rpx auto 0;
  641. border-radius: 30rpx;
  642. padding: 26rpx;
  643. }
  644. .experimentP {
  645. width: 100%;
  646. background-color: #f7f8fa;
  647. border-radius: 20rpx;
  648. height: 80rpx;
  649. justify-content: center;
  650. align-items: center;
  651. display: flex;
  652. font-weight: 800;
  653. }
  654. .imgAdd {
  655. width: 160rpx;
  656. height: 160rpx;
  657. background-color: #f7f8fa;
  658. border-radius: 20rpx;
  659. display: flex;
  660. justify-content: center;
  661. align-items: center;
  662. }
  663. .add {
  664. width: 96rpx;
  665. height: 96rpx;
  666. border-radius: 48rpx;
  667. background: #3c9cff;
  668. position: absolute;
  669. bottom: 50rpx;
  670. right: 24rpx;
  671. display: flex;
  672. align-items: center;
  673. justify-content: center;
  674. }
  675. </style>