detail.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. <template>
  2. <div class="record-detail">
  3. <nav-bar></nav-bar>
  4. <div class="page-container">
  5. <!-- 基本信息 -->
  6. <div class="card">
  7. <van-panel >
  8. <template #header>
  9. <span></span>
  10. </template>
  11. <div class="panel-box">
  12. <van-cell title="来访人员" :value="selectedUser.userName"></van-cell>
  13. <van-cell title="介绍信类型" :value="getDictLabel(selectedUser.letterType,'out_in_type')"></van-cell>
  14. <van-cell title="来访事由" :value="selectedUser.letterReasons"></van-cell>
  15. <van-cell title="来访单位" :value="selectedUser.companyName"></van-cell>
  16. <van-cell title="证件类型" :value="getDictLabel(selectedUser.idType,'letter_id_type')"></van-cell>
  17. <van-cell title="证件号码" :value="selectedUser.idCard"></van-cell>
  18. <div class="upload-box" v-if="selectedUser.imgFile && selectedUser.imgFile.length > 0">
  19. <span>证件图片</span>
  20. <van-cell >
  21. <div
  22. class="nfc-img van-hairline--surround"
  23. v-for="(v, i) in selectedUser.imgFile"
  24. :key="v"
  25. @click="preView(selectedUser.imgFile)">
  26. <img :src="imgUrl(v)" alt="" />
  27. </div>
  28. </van-cell>
  29. </div>
  30. <div class="upload-box" v-if="selectedUser.letterFile && selectedUser.letterFile.length > 0">
  31. <span>介绍信附件</span>
  32. <van-cell >
  33. <div
  34. class="nfc-img van-hairline--surround"
  35. v-for="(v, i) in selectedUser.letterFile"
  36. :key="v"
  37. @click="preView(selectedUser.letterFile)">
  38. <img :src="imgUrl(v)" alt="" />
  39. </div>
  40. </van-cell>
  41. </div>
  42. <div class="upload-box" v-if="selectedUser.checkImage && selectedUser.checkImage.length > 0">
  43. <span>核验结果</span>
  44. <van-cell >
  45. <div
  46. class="nfc-img van-hairline--surround"
  47. v-for="(v, i) in selectedUser.checkImage"
  48. :key="v"
  49. @click="preView(selectedUser.checkImage)">
  50. <img :src="imgUrl(v)" alt="" />
  51. </div>
  52. </van-cell>
  53. </div>
  54. <div class="upload-box" v-if="canRecord() && !selectedUser.departureTime && !selectedUser.checkImage">
  55. <span class="required">核验结果</span>
  56. <van-cell>
  57. <uploader :maxCount="2" v-model="formData.checkImage"/>
  58. </van-cell>
  59. </div>
  60. <van-cell v-if="selectedUser.accompanyingPerson" title="陪同人员" :value="selectedUser.accompanyingPerson"></van-cell>
  61. <!-- <date-cell v-if="selectedUser.approveStatus==1 && !selectedUser.accompanyingPerson" required title="到达时间" :max-date="maxData" :min-date='minDate' :is-row="true" v-model="formData.arrivalTime" date-type="datetime" /> -->
  62. <van-field
  63. v-if="canRecord() && !selectedUser.accompanyingPerson"
  64. v-model="formData.accompanyingPerson"
  65. rows="1"
  66. autosize
  67. required
  68. :maxlength="200"
  69. placeholder="请输入陪同人员姓名"
  70. label="陪同人员"></van-field>
  71. <van-cell title="到达时间" v-if="selectedUser.arrivalTime" :value="dayjs(selectedUser.arrivalTime).format('YYYY-MM-DD HH:mm')"></van-cell>
  72. <van-cell title="离开时间" v-if="selectedUser.departureTime" :value="dayjs(selectedUser.departureTime).format('YYYY-MM-DD HH:mm')"></van-cell>
  73. <div class="upload-box" v-if="selectedUser.submitSign">
  74. <span>登记签名</span>
  75. <van-cell >
  76. <div
  77. class="nfc-img van-hairline--surround"
  78. :key="selectedUser.submitSign"
  79. @click="preView(selectedUser.submitSign)">
  80. <img :src="imgUrl(selectedUser.submitSign)" alt="" />
  81. </div>
  82. </van-cell>
  83. </div>
  84. <date-cell v-if="canRecord() && !selectedUser.arrivalTime" required title="到达时间" :max-date="maxData" :min-date='minDate' :is-row="true" v-model="formData.arrivalTime" date-type="datetime" />
  85. <date-cell v-if="canRecord() && selectedUser.arrivalTime && !selectedUser.departureTime" required title="离开时间" :max-date="maxData" :min-date='minDate' :is-row="true" v-model="formData.departureTime" date-type="datetime" />
  86. </div>
  87. <van-action-sheet v-model="showSign" title="签名" class="sheet">
  88. <writingPad ref="esign" :old-signature-seal="oldSignatureSeal" @resultImg="resultImg" @cancelSign="cancelSign"></writingPad>
  89. </van-action-sheet>
  90. <div v-if="canRecord() &&!selectedUser.departureTime" class="big-btn-box" >
  91. <van-button type="info" size="large" @click="onSubmit">确认登记</van-button>
  92. </div>
  93. </van-panel>
  94. <van-dialog v-model="confirmShow" title="引入签名" show-cancel-button @confirm="confirmSignImg">
  95. <van-image :src="this_window + oldSignatureSeal" />
  96. </van-dialog>
  97. </div>
  98. </div>
  99. </div>
  100. </template>
  101. <script>
  102. import DateCell from "@/components/dateCell/index.vue";
  103. import Uploader from "@/components/upload/gxuploader.vue";
  104. import {formatDate} from "@/filters/filter";
  105. import {mapGetters} from "vuex";
  106. import {imgUrl} from "@/utils";
  107. import { ImagePreview } from 'vant'
  108. import writingPad from '@/components/writingPad/index.vue'
  109. import imgCom from '@/components/imgCom/index.vue'
  110. import { base64ToBlob } from '@/utils/base64TurnImg.js'
  111. import { upload } from '@/api/public'
  112. import {userDetails, userDepart} from './api'
  113. import dayjs from 'dayjs'
  114. import { compatibleWithIOSStringToDate } from '@/utils/date.js'
  115. export default {
  116. components: {Uploader, DateCell,writingPad,imgCom},
  117. data(){
  118. return {
  119. maxData:new Date(),
  120. minDate:null,
  121. visitId:null,
  122. userList:[],
  123. selectedUser:{},
  124. showSign:false,
  125. prop:{
  126. label:'userName',
  127. value:'id'
  128. },
  129. formData:{
  130. arrivalTime:null,
  131. departureTime:null,
  132. checkImage:null,
  133. accompanyingPerson:null,
  134. },
  135. dicts:['out_in_approve_status','out_in_type','letter_id_type'],
  136. oldSignatureSeal:"",
  137. confirmShow:false,
  138. this_window: process.env.NODE_ENV === 'development' ? '/dev' : window.origin,
  139. }
  140. },
  141. computed:{
  142. ...mapGetters(['orgId','id','dictionary']),
  143. },
  144. created(){
  145. this.visitId = this.$route.query.id;
  146. this.getUserInfo();
  147. },
  148. mounted() {
  149. this.oldSignatureSeal = JSON.parse(window.sessionStorage.getItem('SET_MASTER_SIGNATURE_SEAL')) + '';
  150. },
  151. methods:{
  152. dayjs,
  153. imgUrl,formatDate,
  154. canRecord(){
  155. return this.selectedUser.approveStatus==1 && this.selectedUser.status!=3
  156. },
  157. onSubmit(){
  158. let {arrivalTime,departureTime,accompanyingPerson,checkImage} = this.formData;
  159. if(!this.selectedUser.checkImage && !checkImage){
  160. this.$toast('请上传审核结果');
  161. return
  162. }
  163. if(!this.selectedUser.accompanyingPerson && !accompanyingPerson){
  164. this.$toast('请输入陪同人员姓名');
  165. return
  166. }
  167. if(!this.selectedUser.arrivalTime && !arrivalTime){
  168. this.$toast('请选择到达时间');
  169. return
  170. }
  171. if(this.selectedUser.arrivalTime && !this.selectedUser.departureTime && !departureTime){
  172. this.$toast('请选择离开时间');
  173. return
  174. }
  175. if(departureTime){
  176. this.signatureHandler();
  177. }
  178. else{
  179. this.submitRecordData(arrivalTime,departureTime,accompanyingPerson,checkImage);
  180. }
  181. },
  182. submitRecordData(arrivalTime,departureTime,accompanyingPerson,checkImage,signImgUrl)
  183. {
  184. let data = {
  185. id:this.selectedUser.id,
  186. // accompanyingPerson:this.selectedUser.accompanyingPerson?this.selectedUser.accompanyingPerson:accompanyingPerson,
  187. // arrivalTime: this.selectedUser.arrivalTime ? this.selectedUser.arrivalTime:arrivalTime,
  188. // departureTime,
  189. }
  190. if(arrivalTime)
  191. {
  192. data.arrivalTime=arrivalTime;
  193. }
  194. if(departureTime)
  195. {
  196. data.departureTime=departureTime;
  197. }
  198. if(accompanyingPerson)
  199. {
  200. data.accompanyingPerson=accompanyingPerson;
  201. }
  202. if(checkImage)
  203. {
  204. data.checkImage=checkImage.map(v=>{return v.imgPath}).toString(',');
  205. }
  206. if(signImgUrl)
  207. {
  208. data.submitSign=signImgUrl;
  209. }
  210. //alert(JSON.stringify(data))
  211. userDepart(data).then(res=>{
  212. this.$toast.success('提交成功');
  213. this.$router.replace({
  214. name:'visitRecord',
  215. path:'/visitRecord',
  216. params:{event:'refresh'},
  217. });
  218. })
  219. },
  220. signatureHandler() {
  221. this.showSign = true
  222. },
  223. cancelSign()
  224. {
  225. this.showSign=false;
  226. },
  227. confirmSignImg(){
  228. this.cancelSign();
  229. //this.submitSign(this.oldSignatureSeal);
  230. let {arrivalTime,departureTime,accompanyingPerson,checkImage} = this.formData;
  231. let signImgUrl = this.oldSignatureSeal;
  232. this.submitRecordData(arrivalTime,departureTime,accompanyingPerson,checkImage,signImgUrl);
  233. },
  234. //上传签名图到服务器
  235. resultImg(img,oldImgUrl) {
  236. if (oldImgUrl !== "" && oldImgUrl !== null && oldImgUrl !== "null"){
  237. //this.submitSign(oldImgUrl)
  238. this.confirmShow =true;
  239. this.oldSignatureSeal = oldImgUrl;
  240. }else {
  241. let obj = base64ToBlob(img)
  242. let formData = new FormData()
  243. obj.name = '签名.jpg'
  244. formData.append('file', base64ToBlob(img))
  245. upload(formData, 'image')
  246. .then(res => {
  247. console.log(process.env.NODE_ENV)
  248. /*上传成功*/
  249. let signImgUrl = process.env.NODE_ENV === 'development' ? res.data.url : res.data.url
  250. // this.submitSign(imgUrl)
  251. let {arrivalTime,departureTime,accompanyingPerson,checkImage} = this.formData;
  252. this.submitRecordData(arrivalTime,departureTime,accompanyingPerson,checkImage,signImgUrl);
  253. // this.$emit("imgUrl", res.data.url);
  254. })
  255. .catch(err => {
  256. /*上传失败*/
  257. })
  258. }
  259. },
  260. getUserInfo(){
  261. userDetails(this.visitId).then(res=>{
  262. let checkImage = "";
  263. if(res.data.checkImage)
  264. {
  265. checkImage= res.data.checkImage.split(',')
  266. }
  267. let imgFile = res.data.imgFile.split(',');
  268. let letterFile = [];
  269. if(res.data.letterFile && res.data.letterFile.length > 0){
  270. letterFile = res.data.letterFile.map(v=>{
  271. let data = JSON.parse(v);
  272. return data.imgPath;
  273. })
  274. }
  275. this.selectedUser = res.data;
  276. this.selectedUser.checkImage = checkImage;
  277. this.selectedUser.imgFile = imgFile;
  278. this.selectedUser.letterFile = letterFile;
  279. //设置最小时间
  280. let minDate = this.selectedUser.arrivalTime;
  281. // this.minDate = compatibleWithIOSStringToDate(this.selectedUser.arrivalTime)
  282. if(minDate)
  283. {
  284. this.minDate = new Date(this.dayjs(minDate));
  285. // this.minDate = new Date(minDate)
  286. // // 苹果手机下 某些版本 new Date(minDate) 对格式有严格要求
  287. // if(!this.minDate){
  288. // let objStart=minDate.replace(/-/g,"/");
  289. // this.minDate = Date.parse(new Date(objStart));
  290. // console.log("111",this.minDate)
  291. // }
  292. // let objStart=minDate.replace(/-/g,"/");
  293. // console.log("111",objStart,new Date(minDate))
  294. // this.minDate = Date.parse(new Date(objStart));
  295. // console.log("1112",this.minDate)
  296. }
  297. else{
  298. this.minDate = new Date(null);
  299. }
  300. })
  301. },
  302. previewFile(file){
  303. this.openFilePreview(file);
  304. },
  305. preView(val) {
  306. if(Array.isArray(val)){
  307. let arr = val.map(v=>{
  308. return imgUrl(v);
  309. })
  310. ImagePreview(arr);
  311. }else {
  312. ImagePreview([imgUrl(val)]);
  313. }
  314. },
  315. }
  316. }
  317. </script>
  318. <style lang="scss">
  319. .record-detail{
  320. .van-card{
  321. padding: 20px;
  322. }
  323. .card-cell-box{
  324. width: 70%;
  325. .van-cell{
  326. padding: 10px;
  327. &::after{
  328. left:10px;
  329. right:10px;
  330. }
  331. }
  332. .van-cell__title{
  333. flex:.25;
  334. }
  335. .van-cell__value{
  336. flex:.75;
  337. }
  338. }
  339. }
  340. </style>
  341. <style scoped lang="scss">
  342. .record-detail{
  343. height: 100%;
  344. overflow: hidden;
  345. }
  346. .page-container{
  347. height: calc(100vh - 94px);
  348. overflow: auto;
  349. padding: 20px;
  350. }
  351. .flex-box{
  352. display: flex;
  353. justify-content: space-between;
  354. align-items: center;
  355. >span{
  356. margin: 0 20px;
  357. }
  358. }
  359. .card{
  360. margin-bottom: 20px;
  361. box-shadow: 0 10px 10px #eaeaea;
  362. }
  363. .card:last-child{
  364. margin-bottom: 0;
  365. }
  366. .panel-box{
  367. -padding:0 20px;
  368. }
  369. .panel-box-item{
  370. height: 36px;
  371. line-height: 36px;
  372. }
  373. .item-label{
  374. width: 100%;
  375. display: flex;
  376. justify-content: right;
  377. align-items: center;
  378. }
  379. .item-value{
  380. width: 100%;
  381. display: flex;
  382. justify-content: left;
  383. align-items: center;
  384. }
  385. .upload-box{
  386. padding: 20px 30px;
  387. display: flex;
  388. >span{
  389. display: inline-block;
  390. height: 160px;
  391. width: 200px;
  392. line-height: 160px;
  393. font-size: 28px;
  394. color:#999;
  395. >i{
  396. font-style: normal;
  397. color: #ee0a24;
  398. }
  399. }
  400. .required::before{
  401. content: '*';
  402. color: #ee0a24;
  403. position: absolute;
  404. left: 14px;
  405. }
  406. }
  407. .goods-card{
  408. width: 100%;
  409. display: flex;
  410. align-items: center;
  411. padding: 10px;
  412. background-color: #fff;
  413. .card-img-box{
  414. width: 200px;
  415. height: 200px;
  416. margin-right: 10px;
  417. >img{
  418. width: 100%;
  419. height: 100%;
  420. object-fit: cover;
  421. border-radius: 10px;
  422. }
  423. }
  424. }
  425. .big-btn-box{
  426. padding: 20px;
  427. }
  428. .file-box{
  429. width: 70%;
  430. display: flex;
  431. justify-content: flex-end;
  432. color:#008cd6;
  433. }
  434. .nfc-img {
  435. display: inline-block;
  436. width: 140px;
  437. height: 140px;
  438. margin: 0 10px;
  439. position: relative;
  440. > img {
  441. width: 100%;
  442. height: 100%;
  443. border: none;
  444. }
  445. > span {
  446. position: absolute;
  447. padding: 0 10px;
  448. bottom: 0;
  449. left: 0;
  450. display: block;
  451. width: 100%;
  452. background-color: rgba(0, 0, 0, 0.2);
  453. color: #eaeaea;
  454. font-size: 20px;
  455. overflow: hidden;
  456. text-overflow: ellipsis;
  457. white-space: nowrap;
  458. line-height: 30px;
  459. height: 30px;
  460. }
  461. }
  462. .sheet {
  463. height: 45%;
  464. }
  465. </style>