add.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. <template>
  2. <view>
  3. <view class="container book-main">
  4. <view class="form-box">
  5. <view class="form-box-label">选择科室</view>
  6. <view class="form-box-content" @click="selectDep">
  7. <view class="form-box-content-text" v-if="!dep.title">请选择</view>
  8. <view class="form-box-content-text" v-if="dep.title">{{dep.title}}</view>
  9. <image src="../../images/xiangyou-xiao.png"></image>
  10. </view>
  11. </view>
  12. <view class="form-box">
  13. <view class="form-box-label">联系人 <text class="text-red">*</text></view>
  14. <view class="form-box-content">
  15. <input type="text" v-model="contact" placeholder="请填写" />
  16. </view>
  17. </view>
  18. <view class="form-box">
  19. <view class="form-box-label">联系手机号 <text class="text-red">*</text></view>
  20. <view class="form-box-content">
  21. <input type="tel" v-model="phone" placeholder="请填写" />
  22. </view>
  23. </view>
  24. <view class="form-box">
  25. <view class="form-box-label">选择服务 <text class="text-red">*</text></view>
  26. <view class="form-box-content" @click="selectCate">
  27. <view class="form-box-content-text" v-if="!cate.title">请选择</view>
  28. <view class="form-box-content-text" v-if="cate.title">{{cate.title}}</view>
  29. <image src="../../images/xiangyou-xiao.png"></image>
  30. </view>
  31. </view>
  32. <view class="form-box form-box2">
  33. <view class="form-box-label">被陪护人信息</view>
  34. <view class="form-box-sub">
  35. <view class="form-box-label">姓名<text class="text-red">*</text></view>
  36. <view class="form-box-content">
  37. <input type="text" placeholder="请填写" v-model="name" />
  38. </view>
  39. </view>
  40. <view class="form-box-sub">
  41. <view class="form-box-label">性别<text class="text-red">*</text></view>
  42. <view class="form-box-content" @click="selectGender">
  43. <view class="form-box-content-text">{{gender.title}}</view>
  44. <image src="../../images/xiangyou-xiao.png"></image>
  45. </view>
  46. </view>
  47. <view class="form-box-sub">
  48. <view class="form-box-label">年龄<text class="text-red">*</text></view>
  49. <view class="form-box-content">
  50. <input type="number" placeholder="请填写" v-model="age" />
  51. </view>
  52. </view>
  53. <view class="form-box-sub">
  54. <view class="form-box-label">床号<text class="text-red">*</text></view>
  55. <view class="form-box-content">
  56. <input type="text" placeholder="请填写" v-model="bed" />
  57. </view>
  58. </view>
  59. <view class="form-box-sub">
  60. <view class="form-box-label">所患疾病<text class="text-red">*</text></view>
  61. <view class="form-box-content">
  62. <input type="text" placeholder="请填写" v-model="ill" />
  63. </view>
  64. </view>
  65. </view>
  66. <view class="form-box">
  67. <view class="form-box-label">预约时间<text class="text-red">*</text></view>
  68. <view class="form-box-content">
  69. <view class="form-box-content" @click="selectStart">
  70. <view class="form-box-content-text" v-if="!start">请选择</view>
  71. <view class="form-box-content-text" v-if="start">{{start}}</view>
  72. <image src="../../images/xiangyou-xiao.png"></image>
  73. </view>
  74. </view>
  75. </view>
  76. <view class="form-box">
  77. <view class="form-box-label">是否首次下单</view>
  78. <view class="form-box-content">
  79. <radio-group @change="radioChange">
  80. <label class="radio" style="margin-right: 20rpx;">
  81. <radio value="1" checked="true" />是
  82. </label>
  83. <label class="radio">
  84. <radio value="2" />否
  85. </label>
  86. </radio-group>
  87. </view>
  88. </view>
  89. <view class="form-box form-box2">
  90. <view class="form-box-label">备注</view>
  91. <view class="form-box-textarea">
  92. <textarea style="height:120rpx;" v-model="remark" placeholder="请填写" />
  93. </view>
  94. </view>
  95. <view class="book-btn" @click="saveBtn()">提交</view>
  96. </view>
  97. <view class="protocol-box" v-if="showProtocol">
  98. <view v-html="protocol"></view>
  99. <view class="protocol-btn" @click="qrProtocolBtn()">同 意</view>
  100. </view>
  101. <view class="sign-box" v-if="showSign">
  102. <spsignboard
  103. ref="signBoardRef"
  104. sid="sign-board"
  105. bgColor="#ffffff"
  106. :showMark="false"
  107. :mark-text="markText"
  108. :horizontal="false"
  109. :penStyle="{ lineWidth: 4, color: '#000000' }"
  110. :expFile="{ fileType: 'jpg', quality: 0.7 }"
  111. @cancel="onCancel()"
  112. @confirm="onConfirmBoard()"
  113. @reset="reset"
  114. @firstTouchStart="firstTouchStart"
  115. ></spsignboard>
  116. <!-- <view class="sign-up-btn">上传签名</view> -->
  117. </view>
  118. <cpicker v-if="genders.length > 0" :list="genders" :show.sync="genderShow" :did="gender.id" @confirm="selectedGenderVal"></cpicker>
  119. <cpicker v-if="deps.length > 0" :list="deps" :show.sync="depShow" :did="dep.id" @confirm="selectedDepVal"></cpicker>
  120. <w-picker
  121. :visible.sync="startVisible"
  122. mode="date"
  123. startYear="2021"
  124. endYear="5000"
  125. themeColor="#006489"
  126. :value="start"
  127. :current="true"
  128. fields="minute"
  129. @confirm="onConfirm($event,'date')"
  130. :disabled-after="false"
  131. ref="date"
  132. ></w-picker>
  133. <cpicker v-if="filterCates.length > 0" :list="filterCates" :show.sync="cateShow" :did="cate.id" @confirm="selectedCateVal"></cpicker>
  134. </view>
  135. </template>
  136. <script>
  137. var app = getApp();
  138. import cpicker from "../../components/cpicker/cpicker.vue";
  139. import wpicker from "../../components/w-picker/w-picker.vue";
  140. import spsignboard from "../../components/sp-sign-board/components/sp-sign-board/sp-sign-board.vue";
  141. export default {
  142. components: {
  143. cpicker,
  144. wpicker,
  145. spsignboard
  146. },
  147. data() {
  148. return {
  149. signBase64: "",
  150. signTempimg: "",
  151. markText: "陪护",
  152. showProtocol: false,
  153. isProtocol: false,
  154. protocol: "", // 协议内容
  155. showSign: false,
  156. isSign: false,
  157. signPath: "", // 签名上传路径
  158. flag: false,
  159. start:'',
  160. startVisible:false,
  161. contact: '',
  162. name: '',
  163. phone: '',
  164. ill: '',
  165. age: '',
  166. bed: '',
  167. gender: {
  168. id: 1,
  169. title: '男'
  170. },
  171. genderShow: false,
  172. genders:[{"id":1,"title":"男"},{"id":2,"title":"女"}],
  173. dep: {
  174. id: 0,
  175. title: ''
  176. },
  177. depShow: false,
  178. deps:[],
  179. remark: '',
  180. cate: {
  181. id: 0,
  182. title: ''
  183. },
  184. cates:[],
  185. cateShow: false,
  186. filterCates:[],
  187. wx: null,
  188. isFirst:1
  189. }
  190. },
  191. onLoad(option) {
  192. var that = this;
  193. var orgId = this.getUrlCode('orgId');
  194. if(orgId){
  195. uni.setStorageSync(app.globalData.storagePre+'orgId',orgId);
  196. app.globalData.userinfo.orgId = orgId;
  197. }else{
  198. orgId = uni.getStorageSync(app.globalData.storagePre+'orgId');
  199. if(orgId){
  200. app.globalData.userinfo.orgId = orgId;
  201. }else{
  202. uni.showToast({
  203. title: '参数错误',
  204. icon: 'none',
  205. duration: 2000
  206. })
  207. }
  208. }
  209. if (this.$wechat && this.$wechat.isWechat()) {//获取定位经纬度
  210. this.$wechat.getWx(function (res) {
  211. console.log(res)
  212. that.wx = res;
  213. });
  214. }
  215. // 生成水印内容
  216. this.refreshMark()
  217. },
  218. onShow() {
  219. var that = this;
  220. app.ajaxReadyCallback = res => { //各个接口统一回调方法
  221. var apiname = res.data.apiname;
  222. console.log(res);
  223. if(apiname == 'dep'){
  224. that.deps = res.data.data;
  225. }else if(apiname == 'cates'){
  226. that.cates = res.data.data;
  227. }else if(apiname == 'protocol'){
  228. that.protocol = res.data.data.content;
  229. } else if(apiname == 'order'){
  230. var payId = res.data.data.payId;
  231. if(payId <= 0 || that.isFirst == 2){
  232. uni.navigateTo({
  233. url: '/pages/index/success'
  234. });
  235. }else{
  236. that.getPayParam(payId);
  237. }
  238. }else if(apiname == 'pay'){
  239. if(that.wx){
  240. that.wx.chooseWXPay({
  241. timestamp: res.data.data.timestamp,
  242. nonceStr: res.data.data.nonceStr,
  243. package: res.data.data.package,
  244. signType: res.data.data.signType,
  245. paySign: res.data.data.paySign,
  246. success: function (r) {
  247. // 支付成功后的回调函数
  248. if (r.errMsg == "chooseWXPay:ok") {
  249. uni.navigateTo({
  250. url: '/pages/index/success'
  251. });
  252. } else {
  253. uni.navigateTo({
  254. url: '/pages/index/fail'
  255. });
  256. }
  257. },
  258. cancel: function(r) {},
  259. fail:function(r){
  260. // uni.showToast({
  261. // title: '支付失败',
  262. // icon: 'none',
  263. // duration: 2000
  264. // })
  265. uni.navigateTo({
  266. url: '/pages/index/fail'
  267. });
  268. }
  269. });
  270. }else{
  271. // uni.showToast({
  272. // title: '支付调用失败,请刷新重试',
  273. // icon: 'none',
  274. // duration: 2000
  275. // })
  276. uni.navigateTo({
  277. url: '/pages/index/fail'
  278. });
  279. }
  280. }
  281. }
  282. this.getDep();
  283. this.getCate();
  284. this.getProtocol();
  285. // 监听一次
  286. uni.$on('getSignImg', (e) => {
  287. console.log('getSignImg', e)
  288. // 多签名场景下可根据 sid 区分不同签名
  289. if (e.sid == 'sign-board') {
  290. that.signBase64 = e.base64
  291. that.signTempimg = e.path
  292. that.isSign = true;
  293. this.showSign = false;
  294. this.saveBtn();
  295. }
  296. // 一定注意不能确认签字完成后立马关闭弹窗,否则签字板会销毁,无法获取签名。需要等签名正确获取到之后再关闭弹窗
  297. // this.close()
  298. })
  299. },
  300. methods: {
  301. getUrlCode (name) {
  302. return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.href) || [, ''])[1].replace(/\+/g, '%20')) || null
  303. },
  304. selectGender(){
  305. this.genderShow = true;
  306. },
  307. selectedGenderVal(obj){
  308. console.log(obj)
  309. this.gender = obj;
  310. },
  311. selectDep(){
  312. this.depShow = true;
  313. },
  314. selectedDepVal(obj){
  315. this.dep = obj;
  316. this.cate = {
  317. id: 0,
  318. title: ''
  319. }
  320. this.filterCates = this.cates.filter(item => {
  321. return (item.deps || []).includes(obj.id.toString());
  322. });
  323. if(this.filterCates.length <= 0){
  324. this.filterCates = this.cates.filter(item => {
  325. return (item.deps.length == 0);
  326. });
  327. }
  328. },
  329. selectCate(){
  330. if(this.dep.id == 0){
  331. uni.showToast({
  332. title: '请先选择科室',
  333. icon: 'none',
  334. duration: 2000
  335. })
  336. return
  337. }
  338. this.cateShow = true;
  339. },
  340. selectedCateVal(obj){
  341. console.log(obj)
  342. this.cate = obj;
  343. },
  344. getProtocol(){
  345. app.ajax({
  346. url: app.globalData.serverUrl + 'common/phprotocol',
  347. type: 'POST',
  348. apiname: 'protocol',
  349. });
  350. },
  351. getDep(){
  352. app.ajax({
  353. url: app.globalData.serverUrl + 'common/dep',
  354. type: 'POST',
  355. apiname: 'dep',
  356. });
  357. },
  358. getCate(){
  359. app.ajax({
  360. url: app.globalData.serverUrl + 'Worker/cates',
  361. type: 'POST',
  362. apiname: 'cates',
  363. });
  364. },
  365. getPayParam(payId){
  366. app.ajax({
  367. url: app.globalData.serverUrl + 'PhOrders/pay',
  368. type: 'POST',
  369. apiname: 'pay',
  370. data: {
  371. payId: payId
  372. }
  373. });
  374. },
  375. onConfirm(e,type){
  376. this.start = e.result;
  377. },
  378. onCancel(){
  379. console.log("onCancel");
  380. this.showSign = false;
  381. },
  382. onConfirmBoard(){
  383. console.log("onConfirmBoard");
  384. this.showSign = false;
  385. this.saveBtn();
  386. },
  387. selectStart(){
  388. this.startVisible = true;
  389. },
  390. qrProtocolBtn(){
  391. this.showProtocol = false;
  392. this.isProtocol = true;
  393. this.saveBtn();
  394. },
  395. refreshMark() {
  396. // const currentDate = new Date()
  397. // const year = currentDate.getFullYear()
  398. // const month = String(currentDate.getMonth() + 1).padStart(2, '0')
  399. // const day = String(currentDate.getDate()).padStart(2, '0')
  400. // const hours = String(currentDate.getHours()).padStart(2, '0')
  401. // const minutes = String(currentDate.getMinutes()).padStart(2, '0')
  402. // const seconds = String(currentDate.getSeconds()).padStart(2, '0')
  403. this.markText = ["陪护"];
  404. },
  405. firstTouchStart() {
  406. // 在第一次开始触碰时,更新一下时间水印,防止滞留时间太长造成时间误差(非必要)
  407. this.refreshMark()
  408. // 手动调用组件内绘制水印方法重新绘制
  409. this.$refs.signBoardRef.drawMark(this.markText)
  410. },
  411. reset() {
  412. this.refreshMark()
  413. },
  414. radioChange(e) {
  415. this.isFirst = e.detail.value;
  416. },
  417. saveBtn(){
  418. if(!this.contact){
  419. uni.showToast({
  420. title: '请输入联系人',
  421. icon: 'none',
  422. duration: 2000
  423. })
  424. return;
  425. }
  426. if(!this.phone){
  427. uni.showToast({
  428. title: '请输入手机号',
  429. icon: 'none',
  430. duration: 2000
  431. })
  432. return;
  433. }
  434. if(!this.cate || this.cate.id <= 0){
  435. uni.showToast({
  436. title: '请输入选择服务',
  437. icon: 'none',
  438. duration: 2000
  439. })
  440. return;
  441. }
  442. if(!this.name){
  443. uni.showToast({
  444. title: '请输入姓名',
  445. icon: 'none',
  446. duration: 2000
  447. })
  448. return;
  449. }
  450. if(!this.age){
  451. uni.showToast({
  452. title: '请输入年龄',
  453. icon: 'none',
  454. duration: 2000
  455. })
  456. return;
  457. }
  458. if(!this.bed){
  459. uni.showToast({
  460. title: '请输入床号',
  461. icon: 'none',
  462. duration: 2000
  463. })
  464. return;
  465. }
  466. if(!this.ill){
  467. uni.showToast({
  468. title: '请输入所患疾病',
  469. icon: 'none',
  470. duration: 2000
  471. })
  472. return;
  473. }
  474. if(!this.start){
  475. uni.showToast({
  476. title: '请选择预约时间',
  477. icon: 'none',
  478. duration: 2000
  479. })
  480. return;
  481. }
  482. if(!this.isProtocol){
  483. this.showProtocol = true;
  484. return false;
  485. }
  486. if(!this.isSign || !this.signBase64){
  487. this.showSign = true;
  488. return false;
  489. }
  490. let param = {
  491. contact: this.contact,
  492. phone: this.phone,
  493. name: this.name,
  494. gender: this.gender.id,
  495. age: this.age,
  496. bed: this.bed,
  497. ill: this.ill,
  498. start: this.start,
  499. remark: this.remark,
  500. depId: this.dep.id,
  501. cateId: this.cate.id,
  502. sign: this.signBase64,
  503. isFirst: this.isFirst
  504. }
  505. app.ajax({
  506. url: app.globalData.serverUrl + 'worker/order',
  507. type: 'POST',
  508. apiname: 'order',
  509. data: param
  510. });
  511. }
  512. }
  513. }
  514. </script>
  515. <style lang="scss" scoped>
  516. .navbg{
  517. width: 100%;
  518. height: 300rpx;
  519. }
  520. .book-main{
  521. width: 710rpx;
  522. // position: absolute;
  523. // z-index: 10;
  524. // top: 300rpx;
  525. // left: 0;
  526. // bottom: 0;
  527. // overflow: auto;
  528. overflow-y: auto;
  529. overflow-x: hidden;
  530. }
  531. .book-btn{
  532. width: 710rpx;
  533. height: 90rpx;
  534. line-height: 90rpx;
  535. background-color: var(--themeColor);
  536. color: #ffffff;
  537. font-size: 34rpx;
  538. font-weight: bold;
  539. text-align: center;
  540. border-radius: 10rpx;
  541. }
  542. .protocol-box{
  543. position: fixed;
  544. z-index: 10000;
  545. top: 0;
  546. left: 0;
  547. right: 0;
  548. bottom: 0;
  549. background-color: #ffffff;
  550. padding: 20rpx;
  551. overflow: auto;
  552. }
  553. .protocol-btn{
  554. position: fixed;
  555. z-index: 10001;
  556. left: 20rpx;
  557. right: 20rpx;
  558. bottom: 10rpx;
  559. background-color: var(--themeColor);
  560. height: 90rpx;
  561. line-height: 90rpx;
  562. color: #ffffff;
  563. font-size: 34rpx;
  564. font-weight: bold;
  565. text-align: center;
  566. border-radius: 10rpx;
  567. }
  568. .sign-box{
  569. position: fixed;
  570. z-index: 100000;
  571. top: 0;
  572. left: 0;
  573. right: 0;
  574. bottom: 0;
  575. background-color: #ffffff;
  576. padding: 20rpx;
  577. }
  578. .sign-canvas{
  579. width: 750rpx;
  580. height: 400rpx;
  581. }
  582. .sign-up-btn{
  583. position: fixed;
  584. z-index: 100001;
  585. left: 20rpx;
  586. right: 20rpx;
  587. bottom: 10rpx;
  588. background-color: var(--themeColor);
  589. height: 90rpx;
  590. line-height: 90rpx;
  591. color: #ffffff;
  592. font-size: 34rpx;
  593. font-weight: bold;
  594. text-align: center;
  595. border-radius: 10rpx;
  596. }
  597. .protocol-box image{
  598. max-width: 100%;
  599. }
  600. </style>