seiminModel.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. <!--
  2. * @Author: 廖明明
  3. * @Date: 2022-04-01 17:11:19
  4. * @LastEditors: 廖明明
  5. * @LastEditTime: 2022-04-02 17:03:14
  6. * @Description: 自定义弹窗组件
  7. -->
  8. <template>
  9. <view class="seiminModel seiminModel_mask" v-if="opts.isVisible">
  10. <view class="seiminModel_container animate__animated animate__fadeIn animate__faster">
  11. <!-- 标题 -->
  12. <view class="seiminModel_header">
  13. <text>{{ opts.title }}</text>
  14. <text class="seiminModel_countDown" v-if="nurseDeptSwitchTip < 0 || (nurseDeptSwitchTip > 0 && closeTime > 0)">
  15. <text v-if="nurseDeptSwitchTip < 0">关闭</text>倒计时<text>{{ closeTime }}s</text>
  16. </text>
  17. </view>
  18. <!-- 动态二维码 -->
  19. <view class="seiminModel_content qrcode" v-if="opts.skin === 'qrcode'">
  20. <image class="w100" :src="nurseCodeImg" mode="widthFix"></image>
  21. <view class="qrcode_operate">
  22. <view class="refreshQRCode" @click="showNurseCode">
  23. 刷新
  24. </view>
  25. <view>{{ refreshQRCodeTime }}s</view>
  26. </view>
  27. </view>
  28. <!-- 正常弹窗 -->
  29. <view class="seiminModel_content" v-html="opts.content" v-else></view>
  30. <!-- 底部 -->
  31. <view class="seiminModel_footer" v-if="nurseDeptSwitchTip <= 0 || (nurseDeptSwitchTip > 0 && closeTime === 0)">
  32. <view class="seiminModel_footer__btn" v-for="(btn, i) in opts.btns" :style="{
  33. flex: btn.flex,
  34. color: btn.textColor,
  35. }" @click="btn.click($event)" :key="i">{{ btn.name }}</view>
  36. </view>
  37. </view>
  38. </view>
  39. </template>
  40. <script>
  41. import {
  42. mapState
  43. } from 'vuex';
  44. import {
  45. reqDeptCodes
  46. } from '../../request/api.js';
  47. export default {
  48. name: "seiminModel",
  49. data() {
  50. return {
  51. // 配置项
  52. opts: {},
  53. // 动态二维码定时器
  54. timer: null,
  55. // 动态二维码qrcode
  56. nurseCodeImg: '',
  57. // 动态二维码刷新间隔时长
  58. refreshQRCodeTime: 30,
  59. // 护士科室切换提示自动关闭设置(时长,单位秒)
  60. closeTime: 0,
  61. // 护士科室切换提示自动关闭设置(定时器,单位秒)
  62. timerCloseTime: null,
  63. };
  64. },
  65. computed: {
  66. ...mapState(['nurseDeptSwitchTip']),
  67. ...mapState('user', ['loginInfo']),
  68. },
  69. methods: {
  70. // 显示弹窗
  71. show(args = {}) {
  72. // 默认配置项
  73. let defaultOptions = {
  74. skin: "default", //弹窗风格(default|toast|qrcode|)
  75. isVisible: false, //是否显示弹窗
  76. title: "提示", //标题
  77. content: "", //内容
  78. btns: [{
  79. name: "取消",
  80. textColor: "#666",
  81. flex: 1,
  82. click: this.close
  83. },
  84. {
  85. name: "确定",
  86. textColor: "#666",
  87. flex: 1,
  88. click: this.close
  89. },
  90. ], //弹窗按钮
  91. };
  92. // 根据弹窗风格修改默认配置项
  93. switch (args.skin) {
  94. case "toast":
  95. defaultOptions.btns = [{
  96. name: "知道了",
  97. textColor: "#49b856",
  98. flex: 1,
  99. click: this.close,
  100. }, ];
  101. break;
  102. }
  103. // 按钮合并参数
  104. if (Array.isArray(args.btns)) {
  105. let btns = [];
  106. args.btns.forEach((v, i) => {
  107. btns.push(Object.assign({}, defaultOptions.btns[i], v));
  108. })
  109. args.btns = btns;
  110. }
  111. // 合并配置
  112. this.opts = Object.assign({}, defaultOptions, args, {
  113. isVisible: true,
  114. });
  115. // 如果是动态二维码,则需要发起请求
  116. if (this.opts.skin === 'qrcode') {
  117. this.showNurseCode();
  118. }
  119. },
  120. // 关闭弹窗
  121. close() {
  122. this.opts.isVisible = false;
  123. if (this.opts.skin === 'qrcode') {
  124. clearInterval(this.timer);
  125. this.timer = null;
  126. }
  127. },
  128. // 科室动态二维码方法
  129. showNurseCode() {
  130. let deptId = this.loginInfo.user && this.loginInfo.user.dept.id;
  131. reqDeptCodes([deptId]).then(res => {
  132. if (res.status == 200) {
  133. this.nurseCodeImg = res["data"][0].base64;
  134. this.refreshQRCodeTime = res["data"][0].refreshQRCodeTime;
  135. clearInterval(this.timer);
  136. this.timer = setInterval(() => {
  137. this.refreshQRCodeTime = Math.max(--this.refreshQRCodeTime, 0);
  138. if (this.refreshQRCodeTime === 0) {
  139. clearInterval(this.timer);
  140. this.showNurseCode();
  141. }
  142. }, 1000);
  143. }
  144. })
  145. },
  146. // 切换科室弹窗
  147. showChangeDept(options = {}) {
  148. this.show(options);
  149. // (1) 当用户设置为正数时,用户必须查看此窗体指定秒数。
  150. // (2) 当用户设置为负数时,用户可点击知道了也可倒计时自动关闭。
  151. // (3) 如果用户填写0则为无自动关闭和强制查看时间。
  152. if (this.nurseDeptSwitchTip === 0) {
  153. return;
  154. }
  155. this.closeTime = Math.abs(this.nurseDeptSwitchTip);
  156. clearInterval(this.timerCloseTime);
  157. this.timerCloseTime = setInterval(() => {
  158. this.closeTime = Math.max(--this.closeTime, 0);
  159. if (this.closeTime === 0) {
  160. if (this.nurseDeptSwitchTip < 0) {
  161. this.close();
  162. }
  163. clearInterval(this.timerCloseTime);
  164. }
  165. }, 1000);
  166. }
  167. }
  168. };
  169. </script>
  170. <style lang="scss" scoped>
  171. .seiminModel {
  172. font-size: 36rpx;
  173. color: #000;
  174. line-height: 50rpx;
  175. text-align: center;
  176. &.seiminModel_mask {
  177. background-color: rgba(0, 0, 0, 0.5);
  178. position: fixed;
  179. top: 0;
  180. right: 0;
  181. bottom: 0;
  182. left: 0;
  183. margin: auto;
  184. z-index: 9999;
  185. @include flex(center, center);
  186. .seiminModel_container {
  187. width: 560rpx;
  188. border-radius: 8rpx;
  189. background-color: #fff;
  190. display: flex;
  191. flex-direction: column;
  192. align-content: center;
  193. .seiminModel_header {
  194. height: 100rpx;
  195. position: relative;
  196. @include flex(center, center);
  197. .seiminModel_countDown{
  198. position: absolute;
  199. right: 26rpx;
  200. font-size: 28rpx;
  201. color: $defaultColor;
  202. }
  203. }
  204. .seiminModel_content {
  205. flex: 1;
  206. background-color: #f9fafb;
  207. margin: 0 36rpx 25rpx;
  208. border: 1px solid #e5e9ed;
  209. color: #333;
  210. padding: 76rpx 24rpx;
  211. @include numbersAndLettersNoWrap;
  212. &.qrcode {
  213. padding: 24rpx;
  214. font-size: 32rpx;
  215. color: #999;
  216. .qrcode_operate {
  217. @include flex(space-between, center);
  218. .refreshQRCode {
  219. color: $defaultColor;
  220. }
  221. }
  222. }
  223. .red {
  224. color: $textColorRed;
  225. }
  226. .green {
  227. color: $defaultColor;
  228. }
  229. }
  230. .seiminModel_footer {
  231. border-top: 1px solid #e5e5e5;
  232. height: 100rpx;
  233. color: #666;
  234. @include flex(center, center);
  235. .seiminModel_footer__btn {
  236. height: 100%;
  237. @include flex(center, center);
  238. position: relative;
  239. &::after {
  240. content: "";
  241. height: 86rpx;
  242. position: absolute;
  243. width: 1px;
  244. bottom: 0;
  245. right: 0;
  246. background-color: #dde1e5;
  247. }
  248. }
  249. }
  250. }
  251. }
  252. }
  253. </style>