detail.vue 12 KB

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