<!-- * @Author: 廖明明 * @Date: 2022-04-01 17:11:19 * @LastEditors: 廖明明 * @LastEditTime: 2022-04-21 13:16:48 * @Description: 自定义弹窗组件 --> <template> <view class="seiminModel seiminModel_mask" v-if="opts.isVisible"> <view class="seiminModel_container animate__animated animate__fadeIn animate__faster"> <!-- 标题 --> <view class="seiminModel_header" :class="{noTitle:!opts.title}"> <text>{{ opts.title }}</text> <text class="seiminModel_countDown" v-if=" nurseDeptSwitchTip < 0 || (nurseDeptSwitchTip > 0 && closeTime > 0) "> <text v-if="nurseDeptSwitchTip < 0">关闭</text>倒计时<text>{{ closeTime }}s</text> </text> </view> <!-- 动态二维码 --> <view class="seiminModel_content qrcode" v-if="opts.skin === 'qrcode'"> <image class="w100" :src="nurseCodeImg" mode="widthFix"></image> <view class="qrcode_operate"> <view class="refreshQRCode" @click="showNurseCode"> 刷新 </view> <view>{{ refreshQRCodeTime }}s</view> </view> </view> <!-- 加急 --> <view class="seiminModel_content urgent" v-else-if="opts.skin === 'urgent'"> <view class="urgent_txt" v-html="opts.content"></view> <textarea :focus="true" class="urgent_textarea" auto-height :maxlength="100" :placeholder-style="placeholderStyle" placeholder="请填写加急原因" v-model="urgentTextArea" /> </view> <!-- 评价 --> <view class="seiminModel_content evaluate" v-else-if="opts.skin === 'evaluate'"> <view class="evaluate_txt" v-html="opts.content"></view> <view class="evaluate_list"> <view class="evaluate_item"> <text class="evaluate_label">星级:</text> <view class="evaluate_icons"> <text class="pda" :class="star" v-for="(star,i) in stars" :key="i" @click="clickStar(i)"></text> </view> </view> <view class="evaluate_item"> <text class="evaluate_label">评级:</text> <textarea :focus="true" class="evaluate_textarea" auto-height :maxlength="100" :placeholder-style="placeholderStyle" placeholder="请输入..." v-model="evaluateTextArea" /> </view> </view> </view> <!-- 正常弹窗 --> <view class="seiminModel_content" v-else> <!-- 图标 --> <view class="seiminModel_status"> <text class="pda pda-shibai red" v-if="opts.icon === 'error'"></text> <text class="pda pda-wenhao yellow" v-if="opts.icon === 'warn'"></text> <text class="pda pda-duigou green" v-if="opts.icon === 'success'"></text> </view> <!-- 内容 --> <view class="seiminModel_txt" v-html="opts.content"></view> </view> <!-- 底部 --> <view class="seiminModel_footer" v-if=" nurseDeptSwitchTip <= 0 || (nurseDeptSwitchTip > 0 && closeTime === 0) "> <view class="seiminModel_footer__btn" v-for="(btn, i) in opts.btns" :style="{ flex: btn.flex, color: btn.textColor, }" @click="btn.click($event)" :key="i">{{ btn.name }}</view> </view> </view> </view> </template> <script> import { mapState } from "vuex"; import { reqDeptCodes } from "../../request/api.js"; export default { name: "seiminModel", data() { return { // 配置项 opts: {}, // 动态二维码定时器 timer: null, // 动态二维码qrcode nurseCodeImg: "", // 动态二维码刷新间隔时长 refreshQRCodeTime: 30, // 护士科室切换提示自动关闭设置(时长,单位秒) closeTime: 0, // 护士科室切换提示自动关闭设置(定时器,单位秒) timerCloseTime: null, // 加急原因 urgentTextArea: '', // 加急原因的placeholder样式 placeholderStyle: 'color:#999;padding:18rpx;', // 星级 stars: [], // 评价内容 evaluateTextArea: '', }; }, computed: { ...mapState('other', ["nurseDeptSwitchTip"]), ...mapState("login", ["loginInfo"]), }, methods: { // 显示弹窗 show(args = {}) { // 默认配置项 let defaultOptions = { skin: "default", //弹窗风格(default|toast|qrcode|) isVisible: false, //是否显示弹窗 title: "提示", //标题 icon: "success", //图标(success|error|warn|) content: "", //内容 btns: [{ name: "取消", textColor: "#666", flex: 1, click: this.close, }, { name: "确认", textColor: "#49B856", flex: 1, click: this.close, }, ], //弹窗按钮 }; // 根据弹窗风格修改默认配置项 switch (args.skin) { case "toast": defaultOptions.btns = [{ name: "知道了", textColor: "#49b856", flex: 1, click: this.close, }, ]; break; } // 按钮合并参数 if (Array.isArray(args.btns)) { let btns = []; args.btns.forEach((v, i) => { btns.push(Object.assign({}, defaultOptions.btns[i], v)); }); args.btns = btns; } // 合并配置 this.opts = Object.assign({}, defaultOptions, args, { isVisible: true, }); if (this.opts.skin === "qrcode") { // 如果是动态二维码,则需要发起请求 this.showNurseCode(); } else if (this.opts.skin === 'evaluate') { // 如果是评价弹窗,则默认选中五个笑脸 this.stars = ['pda-haoping', 'pda-haoping', 'pda-haoping', 'pda-haoping', 'pda-haoping']; } }, // 关闭弹窗 close() { this.opts.isVisible = false; if (this.opts.skin === "qrcode") { clearInterval(this.timer); this.timer = null; } }, // 科室动态二维码方法 showNurseCode() { let deptId = this.loginInfo.user && this.loginInfo.user.dept.id; reqDeptCodes([deptId]).then((res) => { if (res.status == 200) { res["data"] = res["data"] || []; res["data"][0] = res["data"][0] || {}; this.nurseCodeImg = res["data"][0].base64 || ""; this.refreshQRCodeTime = res["data"][0].refreshQRCodeTime || 30; clearInterval(this.timer); this.timer = setInterval(() => { this.refreshQRCodeTime = Math.max(--this.refreshQRCodeTime, 0); if (this.refreshQRCodeTime === 0) { clearInterval(this.timer); this.showNurseCode(); } }, 1000); } else { clearInterval(this.timer); uni.showToast({ icon: "none", title: "获取数据失败", }); } }); }, // 切换科室弹窗 showChangeDept(options = {}) { this.show(options); // (1) 当用户设置为正数时,用户必须查看此窗体指定秒数。 // (2) 当用户设置为负数时,用户可点击知道了也可倒计时自动关闭。 // (3) 如果用户填写0则为无自动关闭和强制查看时间。 if (this.nurseDeptSwitchTip === 0) { return; } this.closeTime = Math.abs(this.nurseDeptSwitchTip); clearInterval(this.timerCloseTime); this.timerCloseTime = setInterval(() => { this.closeTime = Math.max(--this.closeTime, 0); if (this.closeTime === 0) { if (this.nurseDeptSwitchTip < 0) { this.close(); } clearInterval(this.timerCloseTime); } }, 1000); }, // 选择星级 clickStar(index) { for (let i = 0; i < this.stars.length; i++) { this.$set(this.stars, i, i > index ? 'pda-haoping1' : 'pda-haoping'); } }, }, }; </script> <style lang="scss" scoped> .seiminModel { font-size: 36rpx; color: #000; line-height: 50rpx; text-align: center; &.seiminModel_mask { background-color: rgba(0, 0, 0, 0.5); position: fixed; top: 0; right: 0; bottom: 0; left: 0; margin: auto; z-index: 999; @include flex(center, center); .seiminModel_container { width: 560rpx; border-radius: 8rpx; background-color: #fff; display: flex; flex-direction: column; align-content: center; .seiminModel_status { margin-bottom: 35rpx; .pda { font-size: 138rpx; } } .seiminModel_header { height: 100rpx; position: relative; @include flex(center, center); &.noTitle { height: 40rpx; } .seiminModel_countDown { position: absolute; right: 26rpx; font-size: 28rpx; color: $defaultColor; } } .seiminModel_content { flex: 1; background-color: #f9fafb; margin: 0 36rpx 25rpx; border: 1px solid #e5e9ed; color: #333; padding: 76rpx 24rpx; @include numbersAndLettersNoWrap; // 动态二维码 &.qrcode { padding: 24rpx; font-size: 32rpx; color: #999; .qrcode_operate { @include flex(space-between, center); .refreshQRCode { color: $defaultColor; } } } // 加急 &.urgent { padding: 0; .urgent_txt { font-size: 28rpx; color: #666; line-height: 40rpx; border-bottom: 2rpx solid #E5E9ED; padding: 24rpx; } .urgent_textarea { width: 440rpx; margin: 24rpx; min-height: 212rpx; background: #FFFFFF; border-radius: 2rpx; border: 2rpx solid #E5E9ED; text-align: left; ::v-deep .uni-textarea-textarea { padding: 18rpx; } } } // 评价 &.evaluate { padding: 0; .evaluate_txt { font-size: 28rpx; color: #666; line-height: 40rpx; border-bottom: 2rpx solid #E5E9ED; padding: 24rpx 0; } .evaluate_list { padding: 20rpx 34rpx; .evaluate_item { font-size: 34rpx; color: #666; margin-top: 10rpx; @include flex; .evaluate_label {} .evaluate_icons { flex: 1; @include flex; .pda { font-size: 40rpx; margin-right: 10rpx; &.pda-haoping { color: $defaultColor; } } } .evaluate_textarea { flex: 1; min-height: 212rpx; background: #FFFFFF; border-radius: 2rpx; border: 2rpx solid #E5E9ED; text-align: left; ::v-deep .uni-textarea-textarea { padding: 18rpx; } } } } } } .seiminModel_footer { border-top: 1px solid #e5e5e5; height: 100rpx; color: #666; @include flex(center, center); .seiminModel_footer__btn { height: 100%; @include flex(center, center); position: relative; &::after { content: ""; height: 86rpx; position: absolute; width: 1px; bottom: 0; right: 0; background-color: #dde1e5; } } } } } } </style>