add.vue 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. <template>
  2. <div class="intro-add">
  3. <nav-bar></nav-bar>
  4. <div class="page-container">
  5. <!-- 基本信息 -->
  6. <div class="card">
  7. <van-panel title="来访信息" >
  8. <template #header>
  9. <span></span>
  10. </template>
  11. <div class="panel-box">
  12. <van-cell title="机构名称" :value="selectedUser.idCard"></van-cell>
  13. <van-cell title="保修设备" :value="getDictLabel(selectedUser.idType,'letter_id_type')"></van-cell>
  14. <van-cell title="工程商" :value="selectedUser.userName" required is-link @click="onClick"/>
  15. <date-cell title="建议完成时间" v-model="formData.departureTime" required date-type="datetime" />
  16. <van-cell title="紧急程度" :value="selectedUser.userName" required is-link @click="onClick"/>
  17. <van-field
  18. v-model="formData.accompanyingPerson"
  19. rows="1"
  20. autosize
  21. required
  22. :maxlength="200"
  23. placeholder="请输入"
  24. label="报修原因"></van-field>
  25. </div>
  26. <div class="upload-box">
  27. <span>上传图片</span>
  28. <van-cell>
  29. <uploader :maxCount="1" v-model="formData.letterFile"/>
  30. </van-cell>
  31. </div>
  32. <div class="big-btn-box" >
  33. <van-button type="info" size="large" @click="onSubmit">提交</van-button>
  34. </div>
  35. </van-panel>
  36. </div>
  37. </div>
  38. <!-- 人员选择弹窗 -->
  39. <van-popup
  40. class="search-data-popup"
  41. round
  42. lazy-render
  43. v-model="showPicker"
  44. position="bottom"
  45. @click-overlay="clickOverlay"
  46. :close-on-click-overlay="true">
  47. <div class="header-line">
  48. <div class="cancel" @click="onSearchCancel">取消</div>
  49. <div class="title">选择人员</div>
  50. <div class="sure" @click="onSearchConfirm">确定</div>
  51. </div>
  52. <form action="/static">
  53. <van-search placeholder="输入搜索内容" v-model="searchValue" @input="inputSearchValue" />
  54. </form>
  55. <div v-if="userList.length >0" class="lists">
  56. <div class="list-item">
  57. <van-cell
  58. :class="{active:item.checked}"
  59. v-for="(item, index) in userList"
  60. clickable
  61. :key="item.id"
  62. :title="item.userName"
  63. :value="item.companyName"
  64. @click="handleClick(item,index)">
  65. </van-cell>
  66. </div>
  67. </div>
  68. <div v-else class="lists">
  69. <empty description="" />
  70. </div>
  71. </van-popup>
  72. </div>
  73. </template>
  74. <script>
  75. import SearchSelectCell from "@/components/SearchSelectCell/index.vue";
  76. import DateCell from "@/components/dateCell/index.vue";
  77. import Uploader from "@/components/upload/gxuploader.vue";
  78. import {formatDate} from "@/filters/filter";
  79. import {mapGetters} from "vuex";
  80. import {imgUrl} from "@/utils";
  81. import {ImagePreview } from 'vant'
  82. import dayjs from "dayjs";
  83. export default {
  84. components: {SearchSelectCell,Uploader, DateCell},
  85. data(){
  86. return {
  87. minDate:null,
  88. maxDate:new Date(),
  89. visitId:null,
  90. userList:[],
  91. selectedUser:{},
  92. prop:{
  93. label:'userName',
  94. value:'id',
  95. },
  96. formData:{
  97. letterUserId:null,
  98. arrivalTime:null,
  99. departureTime:null,
  100. accompanyingPerson:null,
  101. checkImage:null,
  102. },
  103. dicts:['out_in_approve_status','letter_id_type','out_in_type'],
  104. /*以下为弹窗中的变量*/
  105. searchValue:'',
  106. showPicker:false,
  107. onSelected:null,
  108. pList:[],
  109. }
  110. },
  111. computed:{
  112. ...mapGetters(['orgId','id','dictionary'])
  113. },
  114. mounted(){
  115. this.getUserList();
  116. },
  117. methods:{
  118. dayjs, imgUrl,formatDate,
  119. onClick(){
  120. this.showPicker = true;
  121. },
  122. clickOverlay(){
  123. this.selected = this.value;
  124. this.showPicker = false;
  125. },
  126. handleClick(v,i){
  127. this.userList.forEach(v=>v.checked = false);
  128. // this.$nextTick(()=>{
  129. // this.$set(this.userList[i],'checked',!this.userList[i].checked);
  130. // })
  131. v.checked = !v.checked;
  132. this.userList.splice(i,1,v)
  133. this.onSelected = v;
  134. },
  135. onSearchCancel() {
  136. this.selected = this.value;
  137. this.$emit("cancel");
  138. this.showPicker = false;
  139. },
  140. onSearchConfirm() {
  141. this.onSelected.minDate = dayjs(this.onSelected.startTime).toDate() || new Date();
  142. this.selectedUser = this.onSelected;
  143. this.formData.arrivalTime = null;
  144. this.showPicker = false;
  145. },
  146. inputSearchValue(query) {
  147. //搜索框值发生改变
  148. setTimeout(() => {
  149. this.userList= this.pList.filter(item => {
  150. return item.userName.indexOf(query) > -1;
  151. });
  152. }, 200);
  153. },
  154. onSubmit(){
  155. if(!this.selectedUser.id){
  156. this.$toast('请选择来访人员');
  157. return
  158. }
  159. if(!this.formData.accompanyingPerson){
  160. this.$toast('请输入陪同人员');
  161. return
  162. }
  163. if(!this.formData.checkImage){
  164. this.$toast('请上传审核结果');
  165. return
  166. }
  167. if(!this.formData.arrivalTime){
  168. this.$toast('请选择到达时间');
  169. return
  170. }
  171. let data = {
  172. ...this.formData,
  173. letterId:this.selectedUser.letterId,
  174. checkImage:this.formData.checkImage.map(v=>{return v.imgPath}).toString(','),
  175. letterUserId:this.selectedUser.id,
  176. orgId:this.orgId,
  177. }
  178. //alert(JSON.stringify(data))
  179. userRegister(data).then(res=>{
  180. this.$toast.success('提交成功');
  181. this.$router.replace({
  182. name:'videoIntegrity',
  183. path:'/videoIntegrity',
  184. params:{event:'refresh'},
  185. });
  186. })
  187. },
  188. /* 失效*/
  189. getItemInfo(item){
  190. console.log(dayjs(item.startTime).toDate(),'77777777')
  191. item.maxDate = dayjs(item.startTime).toDate() || new Date();
  192. console.log(item.maxDate,'77777777')
  193. this.selectedUser = item;
  194. this.formData.arrivalTime = null;
  195. },
  196. previewFile(file){
  197. this.openFilePreview(file);
  198. },
  199. getUserList(){
  200. let data = {
  201. orgId:this.orgId,
  202. arrivalTime:formatDate(new Date(),'YYYY-MM-DD')
  203. }
  204. userList(data).then(res=>{
  205. this.userList = res.data.map(v=>{
  206. v.imgFile = v.imgFile.split(',');
  207. if(v.letterFile && v.letterFile.length >0){
  208. v.letterFile = v.letterFile.map(str=>{
  209. return JSON.parse(str)
  210. })
  211. }
  212. return v
  213. })
  214. this.pList = res.data;
  215. })
  216. },
  217. preView(val) {
  218. if(Array.isArray(val)){
  219. let arr = val.map(v=>{
  220. return imgUrl(v);
  221. })
  222. ImagePreview(arr);
  223. }else {
  224. ImagePreview([imgUrl(val)]);
  225. }
  226. },
  227. }
  228. }
  229. </script>
  230. <style lang="scss">
  231. .intro-add{
  232. .van-card{
  233. padding: 20px;
  234. }
  235. .card-cell-box{
  236. width: 70%;
  237. .van-cell{
  238. padding: 10px;
  239. &::after{
  240. left:10px;
  241. right:10px;
  242. }
  243. }
  244. .van-cell__title{
  245. flex:.25;
  246. }
  247. .van-cell__value{
  248. flex:.75;
  249. }
  250. }
  251. }
  252. </style>
  253. <style scoped lang="scss">
  254. .intro-add{
  255. height: 100%;
  256. overflow: hidden;
  257. }
  258. .page-container{
  259. height: calc(100vh - 94px);
  260. overflow: auto;
  261. padding: 20px;
  262. }
  263. .flex-box{
  264. display: flex;
  265. justify-content: space-between;
  266. align-items: center;
  267. >span{
  268. margin: 0 20px;
  269. }
  270. }
  271. .card{
  272. margin-bottom: 20px;
  273. box-shadow: 0 10px 10px #eaeaea;
  274. }
  275. .card:last-child{
  276. margin-bottom: 0;
  277. }
  278. .panel-box{
  279. -padding:0 20px;
  280. }
  281. .panel-box-item{
  282. height: 36px;
  283. line-height: 36px;
  284. }
  285. .item-label{
  286. width: 100%;
  287. display: flex;
  288. justify-content: right;
  289. align-items: center;
  290. }
  291. .item-value{
  292. width: 100%;
  293. display: flex;
  294. justify-content: left;
  295. align-items: center;
  296. }
  297. .upload-box{
  298. padding: 0 30px;
  299. display: flex;
  300. >span{
  301. display: inline-block;
  302. height: 160px;
  303. width: 200px;
  304. line-height: 160px;
  305. font-size: 28px;
  306. color:#999;
  307. >i{
  308. font-style: normal;
  309. color: #ee0a24;
  310. }
  311. }
  312. .required::before{
  313. content: '*';
  314. color: #ee0a24;
  315. position: absolute;
  316. left: 14px;
  317. }
  318. }
  319. .goods-card{
  320. width: 100%;
  321. display: flex;
  322. align-items: center;
  323. padding: 10px;
  324. background-color: #fff;
  325. .card-img-box{
  326. width: 200px;
  327. height: 200px;
  328. margin-right: 10px;
  329. >img{
  330. width: 100%;
  331. height: 100%;
  332. object-fit: cover;
  333. border-radius: 10px;
  334. }
  335. }
  336. }
  337. .file-box{
  338. width: 70%;
  339. display: flex;
  340. justify-content: flex-end;
  341. color:#008cd6;
  342. }
  343. .big-btn-box{
  344. padding: 20px;
  345. }
  346. .nfc-img {
  347. display: inline-block;
  348. width: 140px;
  349. height: 140px;
  350. margin: 0 10px;
  351. position: relative;
  352. > img {
  353. width: 100%;
  354. height: 100%;
  355. border: none;
  356. }
  357. > span {
  358. position: absolute;
  359. padding: 0 10px;
  360. bottom: 0;
  361. left: 0;
  362. display: block;
  363. width: 100%;
  364. background-color: rgba(0, 0, 0, 0.2);
  365. color: #eaeaea;
  366. font-size: 20px;
  367. overflow: hidden;
  368. text-overflow: ellipsis;
  369. white-space: nowrap;
  370. line-height: 30px;
  371. height: 30px;
  372. }
  373. }
  374. .search-data-popup{
  375. .header-line {
  376. display: flex;
  377. justify-content: space-between;
  378. align-items: center;
  379. height: 90px;
  380. }
  381. .header-line .cancel {
  382. padding: 0 30px;
  383. font-size: 28px;
  384. color: #969799;
  385. }
  386. .header-line .title {
  387. font-weight: 500;
  388. font-size: 30px;
  389. color: #343434;
  390. }
  391. .header-line .sure {
  392. padding: 0 30px;
  393. font-size: 28px;
  394. color: #1989fa;
  395. }
  396. .lists {
  397. display: flex;
  398. flex-direction: column;
  399. -padding: 10px 12px 20px 12px;
  400. min-height: 300px;
  401. max-height: 700px;
  402. overflow: auto;
  403. }
  404. .lists .line {
  405. line-height: 40px;
  406. font-size: 16px;
  407. color: #000;
  408. display: flex;
  409. justify-content: space-between;
  410. align-items: center;
  411. }
  412. .lists .line img {
  413. width: 20px;
  414. height: 20px;
  415. }
  416. .tip {
  417. color: #666;
  418. padding-bottom: 5px;
  419. }
  420. .van-empty{
  421. padding: 0;
  422. }
  423. .list-item{
  424. padding:20px;
  425. }
  426. .active{
  427. color:#1989fa;
  428. border-left: 5px solid #1989fa;
  429. }
  430. }
  431. </style>