guest.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. <template>
  2. <view class="">
  3. <view style="padding: 0 20rpx 20rpx;" v-if="appletStatus==1">
  4. <view class="auth">
  5. <view class="flex justify-between padding-bottom-30" >
  6. <view class="flex">
  7. <image style="width: 35rpx;height: 35rpx;display: block;padding-top: 6rpx;padding-right: 10rpx;" src="../../static/icon/tag1.png" mode=""></image>
  8. <text class="text-lg text-bold">访客开门申请</text>
  9. </view>
  10. <navigator url="records/records" style="font-size: 22rpx;font-weight: 800;" class="cu-btn base-line sm round">
  11. <text class="cuIcon-footprint padding-right-sm"></text>
  12. <text>申请记录</text>
  13. </navigator>
  14. </view>
  15. <view class="card">
  16. <u-form :model="model" ref="uForm" >
  17. <u-form-item :required="true" :label-width="labelWidth" label="访问园区" >
  18. <u-input type="select" :select-open="agencyShow" v-model="model.agencyName" placeholder="请选择要访问的园区" @click="agencyShow=true"></u-input>
  19. </u-form-item>
  20. <u-form-item :label-width="labelWidth" label="访问企业" >
  21. <u-input type="select" :select-open="enterpriseShow" v-model="model.enterpriseName" placeholder="请选择要访问的企业" @click="enterpriseShow=true"></u-input>
  22. </u-form-item>
  23. <u-form-item :required="true" :label-width="labelWidth" label="访问时间" >
  24. <u-input type="select" :select-open="interviewTimeShow" v-model="model.interviewTime" placeholder="请选择访问时间" @click="interviewTimeShow=true"></u-input>
  25. </u-form-item>
  26. <u-form :model="model" ref="uForm" >
  27. <u-form-item :required="true" label-position="top" :border-bottom="false" :label-width="labelWidth" label="访问缘由" >
  28. <u-input height="200" v-model="model.guestReason" placeholder="填写访问缘由" type="textarea" :border="border" />
  29. </u-form-item>
  30. <!-- <textarea value="" v-model="model.remarks" placeholder="填写备注信息" /> -->
  31. </u-form>
  32. </u-form>
  33. </view>
  34. </view>
  35. <view class="auth">
  36. <view class="flex">
  37. <image style="width: 35rpx;height: 35rpx;display: block;padding-top: 6rpx;padding-right: 10rpx;" src="../../static/icon/tag1.png" mode=""></image>
  38. <text class="text-lg text-bold">基本信息</text>
  39. </view>
  40. <view class="card">
  41. <u-form :model="model" ref="uForm" >
  42. <u-form-item :required="true" :label-width="labelWidth" label="姓名" >
  43. <u-input placeholder="请输入姓名" v-model="model.guestName" type="text"></u-input>
  44. </u-form-item>
  45. <u-form-item :label-width="labelWidth" label="性别" >
  46. <u-input type="select" :select-open="sexSelectShow" v-model="sexSelectList[sexSelectIndex].text" placeholder="请选择性别" @click="sexSelectShow = true"></u-input>
  47. </u-form-item>
  48. <u-form-item :required="true" label="手机号码" :label-width="labelWidth">
  49. <u-input maxlength="11" placeholder="请输入手机号" v-model="model.guestTel" type="number"></u-input>
  50. </u-form-item>
  51. <u-form-item label="身份证号" :label-width="labelWidth">
  52. <u-input maxlength="18" placeholder="请输入身份证号" v-model="model.guestIdcard" ></u-input>
  53. </u-form-item>
  54. </u-form>
  55. </view>
  56. </view>
  57. <view class="auth">
  58. <view class="flex">
  59. <image style="width: 35rpx;height: 35rpx;display: block;padding-top: 6rpx;padding-right: 10rpx;" src="../../static/icon/tag1.png" mode=""></image>
  60. <text class="text-lg text-bold">人脸信息采集(可选)</text>
  61. </view>
  62. <view style="font-size: 28rpx;padding: 20rpx 0 10rpx 30rpx;">
  63. <text class="text-red text-bold">*</text>
  64. <text style="color: #797979;">人脸照片用于人脸识别开门</text>
  65. </view>
  66. <view class="card">
  67. <view @click="faceSelectShow=true" class="flex justify-center padding-bottom-50">
  68. <view :class="$isNotEmpty(model.imageUri)?'padding-top-30':''">
  69. <upload-img
  70. :width="$isEmpty(model.imageUri)?350:560"
  71. :height="$isEmpty(model.imageUri)?350:420"
  72. :currentImage="model.imageUri"
  73. bgsrc="https://vote-obs.guosen-fumao.cn/c683bfabcdfe4306adb96bb1605394b6-face1%5B0%5D.png"
  74. >
  75. </upload-img>
  76. <view class="text-center padding-top-20 base-color" >
  77. <text class="cuIcon-camera padding-right-sm" style="font-size: 30rpx;"></text>
  78. <text v-if="$isEmpty(model.imageUri)">点击上传人脸</text>
  79. <text style="margin-top: 40rpx;display: inline-block;" v-else>点击重新上传</text>
  80. </view>
  81. </view>
  82. </view>
  83. </view>
  84. </view>
  85. <button @click="submit" :style="{marginBottom:safeAreaBottom}" class="cu-btn base-bg-color round flex" style="padding: 40rpx 0;margin-top: 40rpx;">
  86. <text >提交申请</text>
  87. </button>
  88. <!-- 性别 -->
  89. <u-picker v-model="sexSelectShow" @confirm="sexSelectCallback" :range="sexSelectList" range-key="text" mode="selector"></u-picker>
  90. <!-- 园区 -->
  91. <u-popup border-radius="8" height="60%" mode="bottom" v-model="agencyShow">
  92. <view class="fixed cu-bar search bg-white">
  93. <view class="search-form round">
  94. <text class="cuIcon-search"></text>
  95. <u-input style="width: 90%;" v-model="agencyKeyWord" type="text" :adjust-position="false" placeholder="请输入关键字搜索" confirm-type="search"/>
  96. </view>
  97. </view>
  98. <scroll-view v-if="!$isEmpty(agencyList)" style="padding-top: 110rpx;height: 100%;" :scroll-y="true" >
  99. <view @click="selectAgency(item)" hover-class="hoverClass" class="text-center padding-30 solid-bottom" v-for="(item,index) in agencyList" :key="index">
  100. <text>{{item.agencyName}}</text>
  101. </view>
  102. <u-divider v-if="agencyList.length>=20" height="80">只显示20条数据</u-divider>
  103. </scroll-view>
  104. <u-empty v-else name="search"></u-empty>
  105. </u-popup>
  106. <!-- 企业列表 -->
  107. <u-popup border-radius="8" height="60%" mode="bottom" v-model="enterpriseShow">
  108. <view class="fixed cu-bar search bg-white">
  109. <view class="search-form round">
  110. <text class="cuIcon-search"></text>
  111. <u-input style="width: 90%;" v-model="enterpriseKeyword" type="text" :adjust-position="false" placeholder="请输入关键字搜索" confirm-type="search"/>
  112. </view>
  113. </view>
  114. <scroll-view v-if="!$isEmpty(enterpriseList)" style="padding-top: 110rpx;height: 100%;" :scroll-y="true" >
  115. <view @click="selectEnterprise(item)" hover-class="hoverClass" class="text-center padding-30 solid-bottom" v-for="(item,index) in enterpriseList" :key="index">
  116. <text>{{item.enterpriseName}}</text>
  117. </view>
  118. <u-divider v-if="enterpriseList.length>=20" height="80">只显示20条数据</u-divider>
  119. </scroll-view>
  120. <u-empty v-else name="search"></u-empty>
  121. </u-popup>
  122. <!-- 访问时间 -->
  123. <u-picker @confirm="interviewTimeConfirm" :params="params" v-model="interviewTimeShow" mode="time"></u-picker>
  124. <u-action-sheet @click="faceSelectCallback" z-index="999999" :list="faceSelectList" v-model="faceSelectShow"></u-action-sheet>
  125. </view>
  126. <view v-else>
  127. </view>
  128. </view>
  129. </template>
  130. <script>
  131. import uploadImg from '@/components/uploadimg/uploadImg.vue'
  132. let that;
  133. export default {
  134. components:{
  135. uploadImg
  136. },
  137. data() {
  138. return {
  139. //0 体验版 1正式版
  140. appletStatus:0,
  141. labelWidth:'200',
  142. model: {
  143. openId:'',
  144. agencyId:'',
  145. enterpriseId:'',
  146. guestName:'',
  147. guestTel:'',
  148. guestSex:'1',//1 男 2 女
  149. guestIdcard:'',//身份证号
  150. guestReason:'',//访问缘由
  151. interviewTime:'',//访问时间
  152. imageUri:''
  153. },
  154. //访问时间
  155. interviewTimeShow:false,
  156. params: {
  157. year: true,
  158. month: true,
  159. day: true,
  160. hour: false,
  161. minute: false,
  162. second: false
  163. },
  164. //性别
  165. sexSelectList: [{text: '男',value:1},{text: '女',value:2}],
  166. sexSelectShow: false,
  167. sexSelectIndex:0,
  168. //园区下拉框
  169. agencyList:[],
  170. agencyKeyWord:'',
  171. agencyShow:false,
  172. //企业下拉框
  173. enterpriseShow:false,
  174. enterpriseList:[],
  175. enterpriseKeyword:'',
  176. //上传人脸的方式
  177. faceSelectList: [{
  178. text: '相册上传',
  179. }, {
  180. text: '拍照上传'
  181. }],
  182. faceSelectShow:false,
  183. }
  184. },
  185. watch:{
  186. agencyKeyWord(){
  187. let that=this
  188. //节流函数
  189. if (this.timer){
  190. clearTimeout(this.timer)
  191. }
  192. this.timer = setTimeout(() => {
  193. that.agencyList=[]
  194. that.getAgencyList()
  195. }, 500)
  196. },
  197. enterpriseKeyword(){
  198. let that=this
  199. //节流函数
  200. if (this.timer){
  201. clearTimeout(this.timer)
  202. }
  203. this.timer = setTimeout(() => {
  204. that.enterpriseList=[]
  205. that.getEnterpriseList()
  206. }, 500)
  207. },
  208. },
  209. computed: {
  210. //ios底部安全区域
  211. safeAreaBottom() {
  212. let info = uni.getSystemInfoSync()
  213. let safe = 20
  214. if (
  215. info &&
  216. ['devtools', 'ios'].includes(info.platform) &&
  217. info.statusBarHeight > safe
  218. ) {
  219. return info.statusBarHeight - safe+'px'
  220. }
  221. return 0
  222. }
  223. },
  224. onShow() {
  225. this.handelAppletAudit()
  226. let currPage=this.getPageCtx()
  227. if (!this.$isEmpty(currPage.data.image)) {
  228. this.uploadFile(currPage.data.image)
  229. }
  230. },
  231. onLoad(options) {
  232. that=this
  233. //拉取园区列表
  234. this.getAgencyList()
  235. this.getEnterpriseList()
  236. if (!this.$isEmpty(options.agencyId)&&!this.$isEmpty(options.agencyName)) {
  237. this.model.agencyId=options.agencyId
  238. this.model.agencyName=options.agencyName
  239. }
  240. if (!this.$isEmpty(options.enterpriseId)&&!this.$isEmpty(options.enterpriseName)) {
  241. this.model.enterpriseId=options.enterpriseId
  242. this.model.enterpriseName=options.enterpriseName
  243. }
  244. if (!this.$isEmpty(options.interviewTime)&&!this.$isEmpty(options.interviewTime)) {
  245. this.model.interviewTime=options.interviewTime
  246. }
  247. if (!this.$isEmpty(options.openId)) {
  248. this.model.openId=options.openId
  249. }else{
  250. //获取openid
  251. this.getOpenid()
  252. }
  253. },
  254. methods: {
  255. handelAppletAudit(){
  256. this.appletStatus=uni.getStorageSync("appletStatus")
  257. if (this.appletStatus==1) {
  258. uni.setNavigationBarTitle({
  259. title:'申请开门'
  260. })
  261. }else{
  262. uni.setNavigationBarTitle({
  263. title:'待开发'
  264. })
  265. }
  266. },
  267. /**
  268. * 获取openid
  269. */
  270. getOpenid(){
  271. uni.login({
  272. success: (res) => {
  273. let data={
  274. appId:this.$api.wxData.appId,
  275. jsCode:res.code,
  276. secret:this.$api.wxData.secret
  277. }
  278. this.$api.wxApi.getOpenId(data).then(res=>{
  279. let resData= JSON.parse(res.data)
  280. this.model.openId=resData.openid
  281. if (this.$isEmpty(this.model.openId)) {
  282. uni.showModal({
  283. content:"系统错误,获取openid失败",
  284. showCancel:false,
  285. success() {
  286. uni.reLaunch({
  287. url:"/pages/login/login"
  288. })
  289. }
  290. })
  291. }
  292. })
  293. }
  294. })
  295. },
  296. //获取园区列表
  297. getAgencyList(){
  298. let params={
  299. size:20,
  300. agencyName:this.agencyKeyWord
  301. }
  302. this.$api.agency.getAgencyTenantList(params).then(res=>{
  303. this.agencyList = res.data
  304. })
  305. },
  306. //选择园区
  307. selectAgency(item){
  308. let params={
  309. tenant_id:item.tenantId,
  310. username:item.account,
  311. password:item.password,
  312. grant_type: "password"
  313. }
  314. this.model.agencyId=item.id
  315. this.model.agencyName=item.agencyName
  316. this.agencyShow=false
  317. this.$cache.put('tokenObj',params)
  318. //获取token
  319. this.$api.getToken(this.$u.queryParams(params)).then(res=>{
  320. let token=res.token_type+" "+res.access_token
  321. uni.setStorageSync('token', token)
  322. //获取企业列表
  323. this.getEnterpriseList()
  324. })
  325. },
  326. //获取企业列表
  327. getEnterpriseList(){
  328. let params={
  329. size:20,
  330. enterpriseName:this.enterpriseKeyword
  331. }
  332. this.$api.enterprise.page(params).then(res=>{
  333. this.enterpriseList =res.data.records
  334. })
  335. },
  336. //选择企业
  337. selectEnterprise(item){
  338. this.enterpriseShow=false
  339. this.model.enterpriseName=item.enterpriseName
  340. this.model.enterpriseId=item.id
  341. },
  342. /**
  343. * 获取页面对象
  344. */
  345. getPageCtx(idx = 0){
  346. let pages = getCurrentPages()
  347. if (pages.length > 0) {
  348. return pages[pages.length - 1 - idx] || {}
  349. }
  350. return {}
  351. },
  352. //性别
  353. sexSelectCallback(e) {
  354. uni.hideKeyboard();
  355. this.sexSelectIndex=e[0]
  356. this.model.guestSex=this.sexSelectList[this.sexSelectIndex].value
  357. },
  358. //访问时间
  359. interviewTimeConfirm(e){
  360. this.model.interviewTime=e.year+'-'+e.month+'-'+e.day
  361. },
  362. //人脸上传
  363. faceSelectCallback(index){
  364. if (index==0) {
  365. //图片上传
  366. this.chooseImage()
  367. } else if(index==1){
  368. //拍照上传
  369. uni.navigateTo({
  370. url:'/pages/my-camera/my-camera'
  371. })
  372. }
  373. },
  374. //点击上传图片事件
  375. chooseImage: function () {
  376. uni.chooseImage({
  377. count: 1,
  378. //最多可以选择的图片张数,默认9
  379. sourceType: ['album'],
  380. sizeType: ['compressed'],
  381. //可选择原图或压缩后的图片
  382. success: res => {
  383. that.uploadFile(res.tempFilePaths[0])
  384. }
  385. });
  386. },
  387. //处理照片,拍照上传和相册上传的共同处理方法
  388. uploadFile(imgUrl){
  389. this.$api.uploadFile.submit(imgUrl).then(res=>{
  390. that.model.imageUri=res.data.link
  391. })
  392. },
  393. async send(openId){
  394. let tokenData={
  395. grantType:this.$api.wxData.subscribe_grant_type,
  396. appId:this.$api.wxData.appId,
  397. secret:this.$api.wxData.secret
  398. }
  399. let res=await this.$api.wxApi.getAccessToken(tokenData)
  400. let token=JSON.parse(res.data).access_token
  401. let subscribeData={
  402. accessToken:token,
  403. touser:openId,
  404. lang:"zh_CN",
  405. page:'/pages/guest/records/records',
  406. miniprogramState:this.$miniprogramState,
  407. templateId: this.$adminTmplIds[1],
  408. "data": {
  409. "thing1": {
  410. "value": this.model.guestName
  411. },
  412. "phone_number2":{
  413. "value": this.model.guestTel
  414. },
  415. "thing4": {
  416. "value": this.model.agencyName
  417. },
  418. "thing3": {
  419. "value": this.model.guestReason
  420. },
  421. }
  422. }
  423. let resp=await this.$api.wxApi.subscribe(subscribeData)
  424. console.log(resp);
  425. },
  426. async getOpenListAndSendMsg(){
  427. let agencyRes=await this.$api.getManagerOpenList({agencyId:this.model.agencyId})
  428. let enterpriseRes=await this.$api.getManagerOpenList({enterpriseId:this.model.enterpriseId})
  429. let openIds=[...agencyRes.data,...enterpriseRes.data]
  430. openIds.forEach(item=>{
  431. this.send(item)
  432. })
  433. },
  434. async submit(){
  435. await this.$mpi.subscribe(that.$staffTmplIds)
  436. if (this.$isEmpty(this.model.agencyId)) {
  437. this.$u.toast('请选择要访问的园区')
  438. return
  439. }
  440. if (this.$isEmpty(this.model.interviewTime)) {
  441. this.$u.toast('请选择访问时间')
  442. return
  443. }
  444. if (this.$isEmpty(this.model.guestReason)) {
  445. this.$u.toast('请填写访问缘由')
  446. return
  447. }
  448. if (this.$isEmpty(this.model.guestName)) {
  449. this.$u.toast('请填写姓名')
  450. return
  451. }
  452. if (this.$isEmpty(this.model.guestTel)) {
  453. this.$u.toast('请填写手机号')
  454. return
  455. }
  456. if (!this.$verify.isMobile(this.model.guestTel)) {
  457. this.$u.toast('请填写正确的手机号')
  458. return
  459. }
  460. if (!this.$isEmpty(this.model.guestIdcard)) {
  461. if (!this.$u.test.idCard(this.model.guestIdcard)) {
  462. this.$u.toast('请输入正确的身份证号')
  463. return
  464. }
  465. }
  466. this.$api.guest.submit(this.model).then(res=>{
  467. if (res.success) {
  468. uni.showModal({
  469. content:'操作成功,请耐心等待管理员审核',
  470. showCancel:false,
  471. success() {
  472. that.getOpenListAndSendMsg()
  473. that.model={
  474. openId:'',
  475. agencyId:'',
  476. agencyName:'',
  477. enterpriseId:'',
  478. enterpriseName:'',
  479. guestName:'',
  480. guestSex:'',//1 男 2 女
  481. guestIdcard:'',//身份证号
  482. guestReason:'',//访问缘由
  483. interviewTime:'',//访问时间
  484. imageUri:''
  485. }
  486. }
  487. })
  488. }
  489. })
  490. },
  491. },
  492. /**打开设置页
  493. * 方法可以不实现,但是不可以不写
  494. */
  495. opensetting(){
  496. }
  497. }
  498. </script>
  499. <style lang="scss">
  500. page{
  501. background-color: #FFFFFF;
  502. }
  503. .auth{
  504. padding: 40rpx 10rpx;
  505. .card{
  506. margin-top: 20rpx;
  507. padding: 0 30rpx;
  508. box-sizing: border-box;
  509. border-radius: 12rpx;
  510. box-shadow: 0 -10rpx rgba(248, 248, 248,.9) ,0 10rpx rgba(248, 248, 248,.9) , -10rpx 0rpx rgba(248, 248, 248,.9) ,10rpx 0rpx rgba(248, 248, 248,.9);
  511. .item{
  512. padding:30rpx 0;
  513. display: flex;
  514. justify-content: space-between;
  515. }
  516. }
  517. }
  518. </style>