with_house.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. <template>
  2. <view class="content">
  3. <view class="supplyInfo">
  4. <view class="tel flex">
  5. <label>小区名称:</label>
  6. <view class="picker card input">
  7. <picker
  8. @change="hoodChangeOld"
  9. :value="hoodIndex"
  10. :range="hoodList"
  11. range-key="name"
  12. class="pick"
  13. >
  14. <view class="picker_title">
  15. <view class="pickername">
  16. <view>
  17. {{ hoodList[hoodIndex].name || '请选择小区'}}
  18. </view>
  19. </view>
  20. <view class="triangle-down"></view>
  21. </view>
  22. </picker>
  23. <!-- <jPicker class="cont" position="top" @sure="hoodChange" showKey="name" valKey="name"
  24. :val="hoodList.name" :options="hoodList" />
  25. -->
  26. </view>
  27. </view>
  28. <view class="tel flex" style="margin-top:30rpx;">
  29. <label style="text-align: center;">楼栋:</label>
  30. <view class="picker card input">
  31. <picker
  32. @change="buildingChange"
  33. :value="buildIndex"
  34. :range="buildList"
  35. range-key="name"
  36. class="pick"
  37. >
  38. <view class="picker_title">
  39. <view class="pickername">
  40. <view>
  41. {{ buildList[buildIndex].name || '请选择楼栋'}}
  42. </view>
  43. </view>
  44. <view class="triangle-down"></view>
  45. </view>
  46. </picker>
  47. </view>
  48. </view>
  49. <view class="tel flex">
  50. <label style="text-align: center;">单元:</label>
  51. <view class="picker card input">
  52. <picker
  53. @change="unitChange"
  54. :value="unitIndex"
  55. :range="unitList"
  56. range-key="name"
  57. class="pick"
  58. >
  59. <view class="picker_title">
  60. <view class="pickername">
  61. <view>
  62. {{ unitList[unitIndex].name || '请选择单元'}}
  63. </view>
  64. </view>
  65. <view class="triangle-down"></view>
  66. </view>
  67. </picker>
  68. </view>
  69. </view>
  70. <view class="tel flex">
  71. <label style="text-align: center;">房号:</label>
  72. <view class="picker card input">
  73. <picker
  74. @change="numChange"
  75. :value="numIndex"
  76. :range="numList"
  77. range-key="name"
  78. class="pick"
  79. >
  80. <view class="picker_title">
  81. <view class="pickername">
  82. <view>
  83. {{ numList[numIndex].name || '请选择房号'}}
  84. </view>
  85. </view>
  86. <view class="triangle-down"></view>
  87. </view>
  88. </picker>
  89. </view>
  90. </view>
  91. <view class="tel flex" style="margin-top: 100rpx;">
  92. <label>户主姓名:</label>
  93. <input type="text" class="card input" v-model="house.master" disabled/>
  94. </view>
  95. <view class="tel flex">
  96. <label>住宅面积:</label>
  97. <input type="text" class="card input" v-model="house.area" disabled/>
  98. </view>
  99. <view class="tel flex">
  100. <label>{{ conf.nameRequired ? '*' : '' }}姓名:</label>
  101. <input type="text" class="card input" v-model="band_name" placeholder="请输入姓名" maxlength="20"/>
  102. </view>
  103. <view class="tel flex">
  104. <label>{{ conf.phoneRequired ? '*' : '' }}手机号:</label>
  105. <input type="number" class="card input" v-model="band_phone" placeholder="请输入手机号" maxlength="11"/>
  106. </view>
  107. <view class="tel flex">
  108. <label>{{ conf.idRequired ? '*' : '' }}身份证号:</label>
  109. <input type="idcard" class="card input" v-model="band_id" placeholder="请输入身份证号" maxlength="18"/>
  110. </view>
  111. </view>
  112. <view class="agree-row" v-if="conf.agreeContent" @tap="agreed = !agreed">
  113. <checkbox :checked="agreed" color="#02a7f0" style="transform: scale(0.8);" />
  114. <text>我已阅读并同意</text>
  115. <text class="agree-link" @tap.stop="showAgreement">《{{ conf.agreeTitle || '供暖缴费协议' }}》</text>
  116. </view>
  117. <button class="submit" @tap="houseSubmit">提交</button>
  118. <view class="agree-mask" v-if="showAgree" @tap="showAgree = false" @touchmove.stop.prevent>
  119. <view class="agree-box" @tap.stop>
  120. <view class="agree-title">{{ conf.agreeTitle || '供暖缴费协议' }}</view>
  121. <scroll-view scroll-y class="agree-content">
  122. <u-parse :content="conf.agreeContent" />
  123. </scroll-view>
  124. <button class="agree-close" @tap="showAgree = false">关闭</button>
  125. </view>
  126. </view>
  127. <uni-popup ref="popup" :mask-click="false">
  128. <view class="popup-box" style="height: 400rpx;">
  129. <view>
  130. <view class="popup-title">确认</view>
  131. <view class="popup-content-box">
  132. <view class="popup-content">
  133. <view class="popup-type">
  134. 确定关联此住房信息吗?
  135. </view>
  136. </view>
  137. </view>
  138. </view>
  139. <view class="popup-footer">
  140. <button class="popup-cancel" @click="closePop">取消</button>
  141. <button class="popup-submit" @click="submitPop">确定</button>
  142. </view>
  143. </view>
  144. </uni-popup>
  145. </view>
  146. </template>
  147. <script>
  148. import md5 from "@/common/md5.js";
  149. import jPicker from '../../components/J-Picker/jPicker.vue';
  150. import uParse from '@/components/gaoyia-parse/parse.vue';
  151. import validate from '@/common/ys-validate.js';
  152. export default {
  153. components: {
  154. jPicker,
  155. uParse
  156. },
  157. data() {
  158. return {
  159. band_name: '',
  160. band_phone: '',
  161. band_id: '',
  162. agreed: false,
  163. showAgree: false,
  164. conf: {
  165. nameRequired: false,
  166. phoneRequired: false,
  167. idRequired: false,
  168. agreeTitle: '',
  169. agreeContent: '',
  170. },
  171. house: {
  172. name: "",
  173. num: "",
  174. master:'',
  175. area:'',
  176. },
  177. hoodList: [],
  178. buildList: [],
  179. unitList: [],
  180. numList: [],
  181. hoodIndex: 0,
  182. hoodName:'',
  183. buildIndex:0,
  184. unitIndex:0,
  185. numIndex:0,
  186. };
  187. },
  188. onLoad() {
  189. },
  190. onShow() {
  191. this.searchHood()
  192. this.loadConf()
  193. },
  194. methods: {
  195. // 解析 conf 接口返回:*_flag 为 "1" 表示必填
  196. applyConf(d){
  197. if (!d || typeof d !== 'object') return;
  198. const pick = (...keys) => {
  199. for (let k of keys) {
  200. if (d[k] !== undefined && d[k] !== null) return d[k];
  201. }
  202. return '';
  203. };
  204. const isOn = (v) => v === true || v === 1 || v === '1' || v === 'true' || v === 'yes';
  205. this.conf = {
  206. nameRequired: isOn(pick('band_name_flag')),
  207. phoneRequired: isOn(pick('band_phone_flag')),
  208. idRequired: isOn(pick('band_id_flag')),
  209. agreeTitle: pick('band_title'),
  210. agreeContent: pick('band_content'),
  211. };
  212. },
  213. loadConf(){
  214. let md5Sign = md5(
  215. "method=" +
  216. "conf" +
  217. "&timestamp=" +
  218. getApp().globalData.globalTimestamp +
  219. "&secret=" +
  220. getApp().globalData.secret
  221. );
  222. let url =
  223. getApp().globalData.shareUrl +
  224. "api/api.php" +
  225. "?method=conf&timestamp=" +
  226. getApp().globalData.globalTimestamp +
  227. "&sign=" +
  228. md5Sign;
  229. uni.request({
  230. url: url,
  231. method: "GET",
  232. success: (res) => {
  233. if (res.data && res.data.code === 200) {
  234. this.applyConf(res.data.data);
  235. }
  236. },
  237. fail: () => {
  238. console.log("连接失败");
  239. },
  240. });
  241. },
  242. showAgreement(){
  243. this.showAgree = true;
  244. },
  245. searchHood(){
  246. let that = this;
  247. this.hoodList = [];
  248. this.hoodIndex = 0;
  249. // let result = e.detail.value;
  250. let md5Sign = md5(
  251. "method=" +
  252. "user" +
  253. "&timestamp=" +
  254. getApp().globalData.globalTimestamp +
  255. "&secret=" +
  256. getApp().globalData.secret
  257. );
  258. let url =
  259. getApp().globalData.shareUrl +
  260. "api/api.php" +
  261. "?method=user&source=user&action=search_estate&timestamp=" +
  262. getApp().globalData.globalTimestamp +
  263. "&sign=" +
  264. md5Sign;
  265. let postData = {
  266. keyword:'',
  267. openId: getApp().globalData.open_id,
  268. };
  269. uni.request({
  270. url: url,
  271. method: "POST",
  272. header: {
  273. "content-type": "application/x-www-form-urlencoded",
  274. },
  275. data: postData,
  276. success: (res) => {
  277. if (res.data.code === 200) {
  278. let obj = res.data.data;
  279. let c = {
  280. name:"请选择小区",
  281. }
  282. this.hoodList.push(c);
  283. for (let key in obj) {
  284. let child = {
  285. name:obj[key]
  286. }
  287. this.hoodList.push(child)
  288. }
  289. }
  290. },
  291. fail: () => {
  292. console.log("连接失败");
  293. },
  294. });
  295. },
  296. searchDetail(hood,build,unit,room){
  297. let that = this, addressResult,searchType;
  298. // let result = e.detail.value;
  299. that.house.master = '';
  300. that.house.area = '';
  301. if (room)
  302. {
  303. if (hood === "请选择小区")
  304. {
  305. return;
  306. }
  307. searchType = 'houseRoom'
  308. addressResult = hood + '/' + build + '/' + unit + '/' + room
  309. }
  310. if(build && unit && !room){
  311. if (build === "请选择房号")
  312. {
  313. return;
  314. }
  315. searchType = 'houseNumber'
  316. addressResult = hood + '/' + build + '/' + unit
  317. }
  318. if(build && !unit){
  319. if (build === "请选择单元")
  320. {
  321. return;
  322. }
  323. searchType = 'houseUnit'
  324. addressResult = hood + '/' + build
  325. }
  326. if(!build && !unit){
  327. if (build === "请选择楼栋")
  328. {
  329. return;
  330. }
  331. searchType = 'houseBuilding'
  332. addressResult = hood
  333. }
  334. let md5Sign = md5(
  335. "method=" +
  336. "user" +
  337. "&timestamp=" +
  338. getApp().globalData.globalTimestamp +
  339. "&secret=" +
  340. getApp().globalData.secret
  341. );
  342. let url =
  343. getApp().globalData.shareUrl +
  344. "api/api.php" +
  345. "?method=user&source=user&action=get_address&timestamp=" +
  346. getApp().globalData.globalTimestamp +
  347. "&sign=" +
  348. md5Sign;
  349. let postData = {
  350. address:addressResult,
  351. openId: getApp().globalData.open_id,
  352. };
  353. uni.request({
  354. url: url,
  355. method: "POST",
  356. header: {
  357. "content-type": "application/x-www-form-urlencoded",
  358. },
  359. data: postData,
  360. success: (res) => {
  361. if (res.data.code === 200) {
  362. if(res.data.data.length === 0){
  363. uni.showToast({
  364. title: hood+"暂无数据",
  365. icon: "error",
  366. });
  367. }else{
  368. that.makeHouseData(searchType,res.data.data)
  369. }
  370. }
  371. },
  372. fail: () => {
  373. console.log("连接失败");
  374. },
  375. });
  376. },
  377. resetLevels(level){
  378. //重置下一层
  379. let that = this;
  380. switch (level){
  381. case 1:
  382. that.buildList = [];
  383. let a = {
  384. name : '请选择楼栋'
  385. };
  386. that.buildList.push(a);
  387. that.buildIndex = 0;
  388. case 2:
  389. that.unitList = [];
  390. let b = {
  391. name : '请选择单元'
  392. };
  393. that.unitList.push(b);
  394. that.unitIndex = 0;
  395. case 3:
  396. that.numList = [];
  397. let c = {
  398. name : '请选择房号'
  399. };
  400. that.numList.push(c);
  401. that.numIndex = 0;
  402. case 4:
  403. that.house.master = '';
  404. that.house.area = '';
  405. }
  406. },
  407. makeHouseData(type,dataList){
  408. let that = this , obj = dataList;
  409. switch (type){
  410. case 'houseBuilding':
  411. this.resetLevels(1);
  412. for (let key in obj) {
  413. let child = {
  414. name:obj[key]
  415. }
  416. that.buildList.push(child)
  417. }
  418. //that.searchDetail(that.hoodName,that.buildList[0].name)
  419. break;
  420. case 'houseUnit':
  421. this.resetLevels(2);
  422. for (let key in obj) {
  423. let child = {
  424. name:obj[key]
  425. }
  426. that.unitList.push(child)
  427. }
  428. //that.searchDetail(that.hoodName,that.buildList[that.buildIndex].name,that.unitList[0].name)
  429. break;
  430. case 'houseNumber':
  431. this.resetLevels(3);
  432. for (let key in obj) {
  433. let child = {
  434. name:obj[key]
  435. }
  436. that.numList.push(child)
  437. }
  438. //that.searchDetail(that.hoodName,that.buildList[that.buildIndex].name,that.unitList[that.unitIndex].name,that.numList[0].name);
  439. break;
  440. case 'houseRoom':
  441. that.house.master = obj.name;
  442. that.house.area = obj.area;
  443. default:
  444. break;
  445. }
  446. },
  447. houseSubmit(){
  448. //uni.navigateBack({});
  449. //this.open()
  450. if (!this.numList.length || !this.numList[this.numIndex].name || this.numList[this.numIndex].name === '请选择房号') {
  451. uni.showToast({ title: "请选择房号", icon: "none" });
  452. return;
  453. }
  454. let name = this.band_name.trim(), phone = this.band_phone.trim(), id = this.band_id.trim();
  455. if (this.conf.nameRequired && !name) {
  456. uni.showToast({ title: "请输入姓名", icon: "none" });
  457. return;
  458. }
  459. if (this.conf.phoneRequired && !phone) {
  460. uni.showToast({ title: "请输入手机号", icon: "none" });
  461. return;
  462. }
  463. if (phone && !validate.isPhone(phone)) {
  464. uni.showToast({ title: "请输入正确的手机号", icon: "none" });
  465. return;
  466. }
  467. if (this.conf.idRequired && !id) {
  468. uni.showToast({ title: "请输入身份证号", icon: "none" });
  469. return;
  470. }
  471. if (id && !validate.isIdCard(id)) {
  472. uni.showToast({ title: "请输入正确的身份证号", icon: "none" });
  473. return;
  474. }
  475. if (this.conf.agreeContent && !this.agreed) {
  476. uni.showToast({ title: "请先阅读并同意供暖缴费协议", icon: "none" });
  477. return;
  478. }
  479. let that = this;
  480. uni.showModal({
  481. title: "确定关联此住房信息吗?",
  482. success(res) {
  483. if (res.confirm) {
  484. //确定继续后续操作。
  485. that.submit();
  486. }else if (res.cancel) {
  487. return;
  488. }
  489. },
  490. });
  491. },
  492. hoodChange(e){
  493. console.log("e.pickerVal="+e.pickerVal);
  494. this.hoodName = e.pickerVal;
  495. this.searchDetail(this.hoodName);
  496. },
  497. hoodChangeOld(e){
  498. let name = this.hoodList[e.detail.value].name;
  499. if (name === "请选择小区")
  500. {
  501. return;
  502. }
  503. this.hoodName = name;
  504. this.hoodIndex = e.detail.value;
  505. this.searchDetail(this.hoodName);
  506. },
  507. buildingChange(e) {
  508. if(!this.hoodName){
  509. uni.showToast({
  510. title: "请先选择小区",
  511. icon: "error",
  512. });
  513. return;
  514. }
  515. this.buildIndex = e.detail.value;
  516. this.searchDetail(this.hoodName,this.buildList[this.buildIndex].name)
  517. },
  518. unitChange(e) {
  519. if(!this.buildList.length){
  520. uni.showToast({
  521. title: "请先选择楼栋",
  522. icon: "error",
  523. });
  524. return
  525. }
  526. this.unitIndex = e.detail.value;
  527. this.searchDetail(this.hoodName,this.buildList[this.buildIndex].name,this.unitList[this.unitIndex].name)
  528. },
  529. numChange(e) {
  530. if(!this.unitList.length){
  531. uni.showToast({
  532. title: "请先选择单元",
  533. icon: "error",
  534. });
  535. return
  536. }
  537. this.numIndex = e.detail.value;
  538. this.searchDetail(this.hoodName,this.buildList[this.buildIndex].name,this.unitList[this.unitIndex].name,this.numList[this.numIndex].name);
  539. },
  540. submitPop(){
  541. //this.closePopup()
  542. this.submit()
  543. },
  544. closePop(){
  545. this.closePopup()
  546. },
  547. open() {
  548. this.$refs.popup.open('center')
  549. },
  550. closePopup() {
  551. this.$refs.popup.close()
  552. },
  553. submit() {
  554. if (
  555. !this.buildList.length ||
  556. !this.unitList.length ||
  557. !this.numList.length
  558. ) {
  559. uni.showToast({
  560. title: "小区信息不完善",
  561. icon: "error",
  562. });
  563. return;
  564. }
  565. let addressResult = this.hoodName + '/' + this.buildList[this.buildIndex].name + '/' + this.unitList[this.unitIndex].name + '/' + this.numList[this.numIndex].name
  566. let md5Sign = md5(
  567. "method=" +
  568. "user" +
  569. "&timestamp=" +
  570. getApp().globalData.globalTimestamp +
  571. "&secret=" +
  572. getApp().globalData.secret
  573. );
  574. let url =
  575. getApp().globalData.shareUrl +
  576. "api/api.php" +
  577. "?method=user&source=user&action=band_owner&timestamp=" +
  578. getApp().globalData.globalTimestamp +
  579. "&sign=" +
  580. md5Sign;
  581. let postData = {
  582. address:addressResult,
  583. openId: getApp().globalData.open_id,
  584. band_name: this.band_name.trim(),
  585. band_phone: this.band_phone.trim(),
  586. band_id: this.band_id.trim().toUpperCase(),
  587. };
  588. uni.request({
  589. url: url,
  590. method: "POST",
  591. header: {
  592. "content-type": "application/x-www-form-urlencoded",
  593. },
  594. data: postData,
  595. success: (res) => {
  596. if (res.data.code === 200) {
  597. uni.showToast({
  598. title: "绑定成功",
  599. icon: "success",
  600. });
  601. setTimeout(function() {
  602. uni.navigateBack({
  603. });
  604. }, 500)
  605. }
  606. },
  607. fail: () => {
  608. console.log("连接失败");
  609. },
  610. });
  611. },
  612. },
  613. };
  614. </script>
  615. <style lang="scss" scoped>
  616. .content {
  617. font-size: 28rpx;
  618. font-weight: 200;
  619. padding: 1% 2%;
  620. .title {
  621. font-size: 30rpx;
  622. margin: 4% 0;
  623. }
  624. label {
  625. display: inline-block;
  626. width: 25%;
  627. vertical-align: middle;
  628. }
  629. .card {
  630. background-color: rgb(248, 247, 247);
  631. border-radius: 10rpx;
  632. }
  633. .flex {
  634. display: flex;
  635. align-items: center;
  636. margin-bottom: 2%;
  637. }
  638. .input {
  639. padding: 0 2%;
  640. margin: 2% 0;
  641. display: inline-block;
  642. width: 80%;
  643. height: 70rpx;
  644. line-height: 70rpx;
  645. }
  646. .supplyInfo {
  647. border-radius: 40rpx;
  648. padding: 4%;
  649. box-shadow: rgba(100, 100, 111, 0.2) 14rpx 14rpx 40rpx 14rpx;
  650. margin: 30rpx 0 30rpx 0;
  651. }
  652. .info {
  653. margin-top: 2%;
  654. border-radius: 40rpx;
  655. padding: 2% 4%;
  656. box-shadow: rgba(100, 100, 111, 0.2) 14rpx 14rpx 40rpx 14rpx;
  657. }
  658. .submit {
  659. color: white;
  660. font-weight: normal;
  661. width: 55%;
  662. border-radius: 20rpx;
  663. background-color: #02a7f0;
  664. margin: 30rpx auto 120rpx;
  665. }
  666. }
  667. .agree-row {
  668. display: flex;
  669. align-items: center;
  670. justify-content: center;
  671. font-size: 26rpx;
  672. margin-top: 20rpx;
  673. .agree-link {
  674. color: #02a7f0;
  675. }
  676. }
  677. .agree-mask {
  678. position: fixed;
  679. top: 0;
  680. left: 0;
  681. right: 0;
  682. bottom: 0;
  683. z-index: 999;
  684. background: rgba(0, 0, 0, 0.5);
  685. display: flex;
  686. align-items: center;
  687. justify-content: center;
  688. }
  689. .agree-box {
  690. width: 620rpx;
  691. max-height: 80vh;
  692. box-sizing: border-box;
  693. background: #fff;
  694. border-radius: 20rpx;
  695. padding: 24rpx;
  696. display: flex;
  697. flex-direction: column;
  698. overflow: hidden;
  699. .agree-title {
  700. text-align: center;
  701. font-weight: bold;
  702. padding-bottom: 16rpx;
  703. border-bottom: 1px solid #d8d8d8;
  704. }
  705. .agree-content {
  706. flex: 1;
  707. min-height: 300rpx;
  708. max-height: 60vh;
  709. margin: 20rpx 0;
  710. font-size: 26rpx;
  711. box-sizing: border-box;
  712. overflow-x: hidden;
  713. word-break: break-all;
  714. }
  715. .agree-close {
  716. width: 100%;
  717. flex-shrink: 0;
  718. font-size: 28rpx;
  719. color: #fff;
  720. background-color: #02a7f0;
  721. }
  722. }
  723. .popup-box {
  724. height: 100%;
  725. display: flex;
  726. flex-direction: column;
  727. justify-content: space-between;
  728. }
  729. .popup-title {
  730. text-align: center;
  731. font-weight: bold;
  732. height: 30px;
  733. border-bottom: 1px solid #d8d8d8;
  734. }
  735. .popup-content {
  736. font-size: 28rpx;
  737. padding: 10rpx 0 10rpx 0;
  738. }
  739. .popup-type {
  740. height: 80rpx;
  741. text-align: center;
  742. margin-top: 100rpx;
  743. }
  744. .popup-footer {
  745. display: flex;
  746. button{
  747. font-size: 26rpx;
  748. height: 60rpx;
  749. width: 150rpx;
  750. line-height: 60rpx;
  751. color: #FFFFFF;
  752. }
  753. }
  754. .popup-cancel {
  755. background-color: #AAAAAA;
  756. }
  757. .popup-submit {
  758. background-color: #249CD3;
  759. }
  760. </style>