guest_form.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. <template>
  2. <view>
  3. <u-toast ref="uToast"></u-toast>
  4. <view class="card" >
  5. <view class="form">
  6. <view class="flex">
  7. <view class="need" >*</view>
  8. <view>访问区域</view>
  9. </view>
  10. <view class="bg-gray padding-20 " >
  11. <input disabled type="text" v-model="data.guestPosition" />
  12. </view>
  13. </view>
  14. <view class="form">
  15. <view class="flex">
  16. <view class="need" >*</view>
  17. <view>访问日期</view>
  18. </view>
  19. <view class="bg-gray padding-20 " >
  20. <u-input type="select" :select-open="timeShow" v-model="data.guestTime" placeholder="请选择访问日期" @click="timeShow=true"></u-input>
  21. </view>
  22. </view>
  23. <view class="form">
  24. <view class="flex">
  25. <view class="need" >*</view>
  26. <view>接待人</view>
  27. </view>
  28. <view class="bg-gray padding-20 " >
  29. <input :disabled="isDisabled" type="text" placeholder="请填写接待人" v-model="data.userName" />
  30. </view>
  31. </view>
  32. <view class="form">
  33. <view class="flex">
  34. <view class="need" >*</view>
  35. <view>您的姓名:</view>
  36. </view>
  37. <view class="bg-gray padding-20 " >
  38. <input :disabled="isDisabled" type="text" placeholder="请填写您的姓名" v-model="data.guestName" />
  39. </view>
  40. </view>
  41. <view class="form ">
  42. <view class="flex">
  43. <view class="need" >*</view>
  44. <view>您的联系方式</view>
  45. </view>
  46. <view class="bg-gray padding-20 flex justify-between " style="box-sizing: border-box;" >
  47. <input disabled maxlength="11" type="number" placeholder="请获取您的联系方式" v-model="data.guestTel" />
  48. <button :disabled="isDisabled" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber" class="light sm cu-btn bg-blue radius">
  49. 获取手机号
  50. </button>
  51. </view>
  52. </view>
  53. <view class="form ">
  54. <view class="flex">
  55. <view class="need" >*</view>
  56. <view>您的身份证号</view>
  57. </view>
  58. <view class="bg-gray padding-20 " >
  59. <input :disabled="isDisabled" placeholder="请输入您的身份证号" v-model="data.guestIdcard" />
  60. </view>
  61. </view>
  62. </view>
  63. <view class="card ">
  64. <view class="form" style="height: 320rpx;">
  65. <view class="flex">
  66. <view class="need" >*</view>
  67. <view>来访目的</view>
  68. </view>
  69. <view class="bg-gray padding-10">
  70. <textarea :disabled="isDisabled" v-model="data.guestReason" maxlength="100" style="width: 100%;height: 270rpx;line-height: 50rpx;" placeholder="请填写来访原因"></textarea>
  71. <view class="text-right text-df text-gray padding-top-10">
  72. {{data.guestReason.length}} / 100
  73. </view>
  74. </view>
  75. </view>
  76. </view>
  77. <view class="bg-white" style="height: 160rpx;"></view>
  78. <view v-if="!islock&&auditStatus==null" style="z-index: 999;" class=" footer-fixed" @click="submit">
  79. <view class="cu-btn flex text-lg bg-red-btn" style="padding: 46rpx 0;">
  80. 确定提交
  81. </view>
  82. </view>
  83. <button open-type="share" v-if="!islock&&auditStatus==0" style="z-index: 999;" class=" footer-fixed" >
  84. <view class="cu-btn flex text-lg bg-orange light" style="padding: 46rpx 0;">
  85. 待审核,通知被访者审核
  86. </view>
  87. </button>
  88. <view @click="auditStatus=null;operaType=1;oldData=$u.deepClone(data)" v-if="!islock&&auditStatus==2" style="z-index: 999;" class=" footer-fixed" >
  89. <view class="cu-btn flex text-lg bg-red" style="padding: 46rpx 0;">
  90. 审核不通过,点击重新填表
  91. </view>
  92. </view>
  93. <view v-if="islock" style="z-index: 999;" class=" footer-fixed" >
  94. <view class="cu-btn flex text-lg bg-gray" style="padding: 46rpx 0;">
  95. 已锁定
  96. </view>
  97. </view>
  98. <u-mask z-index="99999" :show="maskShow" @click="hideMask">
  99. <view style="margin: 20rpx;" @click.stop="">
  100. <textarea @keyboardheightchange="keyboardheightchange" v-model="data.visitReason" value="" style="background-color: #FFFFFF;width: 100%;padding: 20rpx;box-sizing: border-box;" placeholder="请填写来访原因" />
  101. <view class="bg-white text-right text-df text-gray padding-10">
  102. {{data.visitReason.length}} / 100
  103. </view>
  104. </view>
  105. </u-mask>
  106. <!--弹窗-->
  107. <view class="modal-mask" v-if="showModal"></view>
  108. <view class="modal-dialog" v-if="showModal">
  109. <view class="modal-title">提示</view>
  110. <view class="modal-content">
  111. <view class="modal-input">
  112. <text class="password">填写成功,请转发给好友审核</text>
  113. </view>
  114. </view>
  115. <view class="modal-footer">
  116. <button class="btn-confirm" @click="showModal=false;getAuthRecords()" data-status="confirm">暂不转发</button>
  117. <button class="btn-cancel" open-type="share" data-status="cancel">立即转发</button>
  118. </view>
  119. </view>
  120. <view v-if="auditStatus==0" @click="getAuthRecords" class="cuIcon cu-btn" style="width: 88rpx;height: 88rpx;background-color: rgba(0,0,0,.2);color: #FFFFFF;position: fixed;bottom: 40%;right: 20rpx;">
  121. <text class="cuIcon-refresh" style="font-size: 50rpx;"></text>
  122. </view>
  123. <u-picker @confirm="timeConfirm" :params="params" v-model="timeShow" mode="time"></u-picker>
  124. </view>
  125. </template>
  126. <script>
  127. var app=getApp()
  128. var that;
  129. export default {
  130. components:{
  131. },
  132. data() {
  133. return {
  134. //0新增表单操作,1修改表单操作
  135. operaType:0,
  136. id:'',//授权记录的id
  137. doorNeedAudit:0,//该授权开门是否需要审核
  138. memberId:'',//业主的 memberId,用来获取设备列表
  139. residentialId:'',//小区id,用来获取设备列表
  140. openId:'',
  141. sessionKey:'',
  142. showModal:false,
  143. //查询出来的审核状态
  144. auditStatus:null,
  145. islock:false,
  146. //时间选择器
  147. timeShow:false,
  148. params: {
  149. year: true,
  150. month: true,
  151. day: true,
  152. hour: true,
  153. minute: true,
  154. second: true
  155. },
  156. //审核不通过重新修改时的旧数据
  157. oldData:{},
  158. //提交的数据
  159. data:{
  160. //授权记录的表id
  161. guestAuthId:'',
  162. //被访者区域
  163. guestPosition:'',
  164. //来访日期
  165. guestTime:this.$u.timeFormat(new Date(),'yyyy-mm-dd hh:MM:ss'),
  166. //接待人
  167. userName:'',
  168. //来访者姓名
  169. guestName:'',
  170. //来访者联系方式
  171. guestTel:'',
  172. //来访者身份证号
  173. guestIdcard:'',
  174. //来访原因
  175. guestReason:'',
  176. //审核状态
  177. auditStatus:0
  178. },
  179. //添加访客记录后,将访客记录id分享给好友审核
  180. shareId:'',
  181. }
  182. },
  183. computed:{
  184. isDisabled:{
  185. get(){
  186. if (this.auditStatus==null) {
  187. if (this.islock) {
  188. return true
  189. }else{
  190. return false
  191. }
  192. }else{
  193. return true
  194. }
  195. }
  196. }
  197. },
  198. onShareAppMessage: function (ops) {
  199. this.showModal=false
  200. this.getAuthRecords()
  201. return {
  202. title: "我是"+this.data.guestName+",我正在填表申请开门,请审核",
  203. path:"/pages/record/record?id="+this.shareId
  204. };
  205. },
  206. onLoad(options) {
  207. that=this
  208. if (!this.$isEmpty(options.scene)) {
  209. let scene=decodeURIComponent(options.scene).split(",")
  210. //从小程序二维码进入
  211. options.id=scene[0]
  212. options.doorNeedAudit=scene[1]
  213. options.memberId=scene[2]
  214. }
  215. //附带的页面参数id为空,则锁定页面
  216. if (this.$isEmpty(options.id)) {
  217. uni.showModal({
  218. showCancel:false,
  219. content:"系统错误,已锁定",
  220. success: (res) => {
  221. if (res.confirm) {
  222. that.islock=true
  223. }
  224. }
  225. })
  226. return
  227. }
  228. this.id=options.id
  229. this.doorNeedAudit=options.doorNeedAudit
  230. this.memberId=options.memberId
  231. this.data.guestAuthId=this.id
  232. this.getAuthRecords()
  233. },
  234. methods: {
  235. getPhoneNumber (e) {
  236. let that=this
  237. if (e.detail.errMsg == "getPhoneNumber:ok") {
  238. console.log(e);
  239. let params={
  240. sessionKey:that.sessionKey,
  241. encryptedData:e.detail.encryptedData,
  242. iv:e.detail.iv
  243. }
  244. let operation = 'miniprogram/getOpenData';
  245. getApp().globalData.postRequest(params,operation,function(res){
  246. that.data.guestTel=res.data.purePhoneNumber
  247. })
  248. }else{
  249. this.$refs.uToast.show({
  250. title: '获取手机号失败!',
  251. position:"top",
  252. type: 'error',
  253. })
  254. return
  255. }
  256. },
  257. /**
  258. * 跳转到设备列表
  259. */
  260. jumpOpenDoor(){
  261. let params={
  262. memberId:this.memberId,
  263. residentialId:this.residentialId,
  264. guestTel:this.data.guestTel
  265. }
  266. uni.redirectTo({
  267. url:"/pages/guest/open_door"+this.$u.queryParams(params)
  268. })
  269. },
  270. timeConfirm(e){
  271. this.data.guestTime=e.year+"-"+e.month+"-"+e.day+" "+e.hour+":"+e.minute+":"+e.second
  272. console.log(this.data.guestTime);
  273. },
  274. /**
  275. * 先通过id查询授权记录表查看该授权是否过期
  276. * 过期了就不能进行接下来的操作,提示访客联系业主重新授权
  277. * 没有过期就判断审核配置,配置了不需要审核表单就直接跳到设备列表,
  278. * 需要审核就通过授权记录的id和openid查询访客记录表,查询到记录就直接跳到设备列表
  279. * 查不到记录就填表
  280. */
  281. async getAuthRecords(){
  282. let that=this
  283. let operation="guestAuthorize/getById/"+this.id
  284. let params={}
  285. let res=await app.globalData.postRequestAsync(params, operation);
  286. if (res.data.result_code!=1) {
  287. uni.showModal({
  288. showCancel:false,
  289. content:"没有该授权记录,或者授权记录已被撤销",
  290. success: (res) => {
  291. if (res.confirm) {
  292. that.islock=true
  293. }
  294. }
  295. })
  296. return
  297. }
  298. //授权详情
  299. let guestAuthorize=res.data.guestAuthorize
  300. that.residentialId=guestAuthorize.residentialId
  301. //授权结束时间
  302. that.data.endTime=guestAuthorize.endDate
  303. let endDate= that.$commonDate(guestAuthorize.endDate).getTime()
  304. //当前时间
  305. let now= new Date().getTime()
  306. //判断授权是否过期
  307. if (now>endDate) {
  308. uni.showModal({
  309. title:"提示",
  310. content:"授权时间已过期,请联系被访者重新授权",
  311. showCancel:false,
  312. success: (res) => {
  313. if (res.confirm) {
  314. that.islock=true
  315. }
  316. }
  317. })
  318. return
  319. }
  320. // 授权没有过期
  321. //通过openid,授权记录id查询访客记录表
  322. let guestRes=await this.getGuestRecords()
  323. if (guestRes.data.result_code!=1) {
  324. //没有记录,就填表
  325. that.data.guestPosition=guestAuthorize.residentialName+","
  326. +guestAuthorize.buildingName+","+guestAuthorize.unitName+","+
  327. guestAuthorize.roomName
  328. that.data.userName=guestAuthorize.userName
  329. that.data.residentialId=guestAuthorize.residentialId
  330. that.data.residentialName=guestAuthorize.residentialName
  331. that.data.userId=guestAuthorize.userId
  332. return
  333. }
  334. //有记录,就判断审核状态
  335. let guestRecord=guestRes.data.guestRecords[0]
  336. var {orgId,orgPosition,rootOrgId,createDate,...restData} = guestRecord
  337. that.data=restData
  338. that.auditStatus=guestRecord.auditStatus
  339. if (that.auditStatus==1) {
  340. //审核通过。跳转到设备列表
  341. that.jumpOpenDoor()
  342. }
  343. },
  344. /**
  345. * 通过openid和授权记录id和审核通过的状态查看访客记录表
  346. */
  347. async getGuestRecords(){
  348. let jsCode = await new Promise((resolve, reject) => {
  349. uni.login({
  350. provider: 'weixin',
  351. success: res => {
  352. resolve(res.code);
  353. },
  354. fail: err => {
  355. reject(err);
  356. }
  357. })
  358. })
  359. let params = {
  360. js_code:jsCode,
  361. name:'community'
  362. };
  363. let operation = 'miniprogram/getOpenid'; //发起请求
  364. let res= await app.globalData.postRequestAsync(params, operation);
  365. that.sessionKey=res.data.session_key
  366. this.openId=res.data.openid
  367. //获取成功
  368. let url='guestRecord/getByCondition'
  369. let guestParams={
  370. guestAuthId:this.id,
  371. openId:this.openId
  372. }
  373. let guestRes=await app.globalData.postRequestAsync(guestParams,url)
  374. return guestRes
  375. },
  376. submit(){
  377. let that=this
  378. if (this.$isEmpty(this.data.guestPosition)) {
  379. uni.showModal({
  380. title:"提示",
  381. content:"系统错误",
  382. showCancel:false,
  383. success: (res) => {
  384. if (res.confirm) {
  385. that.islock=true
  386. }
  387. }
  388. })
  389. return
  390. }
  391. if (this.$isEmpty(this.data.guestTime)) {
  392. this.$refs.uToast.show({
  393. title: '请选择访问日期',
  394. position:"top",
  395. type: 'error',
  396. })
  397. return
  398. }
  399. if (this.$isEmpty(this.data.userName)) {
  400. this.$refs.uToast.show({
  401. title: '请填写接待人姓名',
  402. position:"top",
  403. type: 'error',
  404. })
  405. return
  406. }
  407. if (this.$isEmpty(this.data.guestName)) {
  408. this.$refs.uToast.show({
  409. title: '请填写您的姓名',
  410. position:"top",
  411. type: 'error',
  412. })
  413. return
  414. }
  415. if (this.$isEmpty(this.data.guestTel)) {
  416. this.$refs.uToast.show({
  417. title: '请填写联系方式',
  418. position:"top",
  419. type: 'error',
  420. })
  421. return
  422. }
  423. if (!this.$u.test.mobile(this.data.guestTel)) {
  424. this.$refs.uToast.show({
  425. title: '联系方式不正确',
  426. position:"top",
  427. type: 'error',
  428. })
  429. return
  430. }
  431. if (this.$isEmpty(this.data.guestIdcard)) {
  432. this.$refs.uToast.show({
  433. title: '请填写身份证号',
  434. position:"top",
  435. type: 'error',
  436. })
  437. return
  438. }
  439. if (!this.$u.test.idCard(this.data.guestIdcard)) {
  440. this.$refs.uToast.show({
  441. title: '身份证号不正确',
  442. position:"top",
  443. type: 'error',
  444. })
  445. return
  446. }
  447. if (this.$isEmpty(this.data.guestReason)) {
  448. this.$refs.uToast.show({
  449. title: '请填写来访目的',
  450. position:"top",
  451. type: 'error',
  452. })
  453. return
  454. }
  455. if (JSON.stringify(this.oldData)==JSON.stringify(this.data)) {
  456. this.$refs.uToast.show({
  457. title: '无任何修改痕迹,请先修改后再提交',
  458. position:"top",
  459. type: 'error',
  460. icon:false,
  461. duration:2500
  462. })
  463. return
  464. }
  465. this.data.openId=this.openId
  466. let operation=''
  467. if (this.operaType==0) {
  468. //新增
  469. operation="guestRecord/addGuestRecord"
  470. if (this.doorNeedAudit==0) {
  471. //1不需要审核,直接审核通过
  472. this.data.auditStatus=1
  473. }
  474. }else{
  475. //修改
  476. operation="guestRecord/updateGuestRecord"
  477. this.data.auditStatus=0
  478. }
  479. app.globalData.postRequest(this.data, operation,function(res){
  480. if (res.data.result_code==1) {
  481. if (that.doorNeedAudit==0) {
  482. //不需要审核,直接跳转到设备列表页
  483. that.jumpOpenDoor()
  484. }else{
  485. that.shareId=res.data.guestRecordId
  486. //需要审核,弹框分享给好友审核
  487. that.showModal=true
  488. }
  489. }else{
  490. that.$refs.uToast.show({
  491. title: '操作失败',
  492. position:"top",
  493. type: 'error',
  494. })
  495. }
  496. })
  497. }
  498. }
  499. }
  500. </script>
  501. <style lang="scss">
  502. .bg-gray{
  503. background-color: #f7f7f7;
  504. }
  505. .card{
  506. box-sizing: border-box;
  507. background-color: #FFFFFF;
  508. }
  509. .card .form{
  510. padding: 20rpx 40rpx;
  511. }
  512. .need{
  513. font-size: 38rpx;
  514. font-weight: 800;
  515. color: #ff0000;
  516. padding-right: 10rpx;
  517. }
  518. .modal-mask {
  519. width: 100%;
  520. height: 100%;
  521. position: fixed;
  522. top: 0;
  523. left: 0;
  524. background: #000;
  525. opacity: 0.5;
  526. overflow: hidden;
  527. z-index: 9000;
  528. color: #fff;
  529. }
  530. .modal-dialog {
  531. width: 540rpx;
  532. overflow: hidden;
  533. position: fixed;
  534. top: 45%;
  535. left: 0;
  536. z-index: 9999;
  537. background: #f9f9f9;
  538. margin: -180rpx 105rpx;
  539. border-radius: 36rpx;
  540. }
  541. .modal-title {
  542. padding-top: 50rpx;
  543. font-size: 36rpx;
  544. color: #030303;
  545. text-align: center;
  546. }
  547. .modal-content {
  548. padding: 60rpx 0;
  549. }
  550. .modal-input {
  551. display: flex;
  552. font-size: 30rpx;
  553. }
  554. .password {
  555. width: 100%;
  556. height: 80rpx;
  557. font-size: 30rpx;
  558. line-height: 80rpx;
  559. padding: 0 20rpx;
  560. box-sizing: border-box;
  561. color: #606266;
  562. text-align: center;
  563. }
  564. input-holder {
  565. color: #666;
  566. font-size: 28rpx;
  567. }
  568. .modal-footer {
  569. display: flex;
  570. flex-direction: row;
  571. height: 86rpx;
  572. border-top: 1px solid #dedede;
  573. font-size: 34rpx;
  574. line-height: 86rpx;
  575. }
  576. .modal-footer button::after{
  577. border: none;
  578. }
  579. .modal-footer .btn-cancel {
  580. width: 50%;
  581. color: #2a7fff;
  582. text-align: center;
  583. border-radius: 0;
  584. }
  585. .modal-footer .btn-confirm {
  586. width: 50%;
  587. color: #666;
  588. border-right: 1px solid #dedede;
  589. text-align: center;
  590. }
  591. </style>