|
@@ -0,0 +1,624 @@
|
|
|
+<template>
|
|
|
+ <!-- 告警弹窗 -->
|
|
|
+ <view>
|
|
|
+ <view class="mask" v-if="alarmModel"></view>
|
|
|
+ <view class="alarm-modal" v-if="alarmModel">
|
|
|
+ <view class="alarm">
|
|
|
+ <!-- <image src="../../images/alram.png" mode="" /> -->
|
|
|
+ <image src="../../static/alarm.png"></image>
|
|
|
+ </view>
|
|
|
+ <view class="alarm-header">
|
|
|
+ <image src="../../static/alarm_event.png" mode="" />
|
|
|
+ </view>
|
|
|
+ <view class="nowTime">
|
|
|
+ {{ nowTime }}
|
|
|
+ </view>
|
|
|
+ <view class="alarm-info" v-if="selectHanled.remark">
|
|
|
+ <text style="color: #ff6d6d">{{ devName }}</text>
|
|
|
+ 检测到可能发生跌倒事件,请立即处理!
|
|
|
+ </view>
|
|
|
+ <view class="alarm-info" v-else>
|
|
|
+ <text style="color: #ff6d6d">{{ devName }}</text>
|
|
|
+ 检测到可能发生跌倒事件,已被{{ selectHanled.remark }}处理过!
|
|
|
+ </view>
|
|
|
+ <view class="backImg">
|
|
|
+ <image src="../../static/actionRed.png" mode="" />
|
|
|
+ </view>
|
|
|
+ <view class="alarm-bottom">
|
|
|
+ <template v-if="voipFlag">
|
|
|
+ <view
|
|
|
+ class="alarm-voice"
|
|
|
+ v-if="authorizeFlag"
|
|
|
+ @click="gotoCallPage"
|
|
|
+ >
|
|
|
+ 语音确认
|
|
|
+ </view>
|
|
|
+ <view class="alarm-voice" v-else @click="authorizeIot">
|
|
|
+ 语音确认
|
|
|
+ </view>
|
|
|
+ </template>
|
|
|
+ <view class="alarm-handle" @click="handleAlarm()">
|
|
|
+ 已知晓
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+import config from "../../data/config.js";
|
|
|
+import mqtt from "../../utils/mqtt";
|
|
|
+import {
|
|
|
+ getSnTicket,
|
|
|
+ authorize,
|
|
|
+ getDeviceVoIPList,
|
|
|
+ getContactList,
|
|
|
+ getUser,
|
|
|
+} from "../../api/index.js";
|
|
|
+import {
|
|
|
+ CameraStatus,
|
|
|
+ AuthorizeStatus,
|
|
|
+ CallPagePlugin,
|
|
|
+ isWmpf,
|
|
|
+} from "../../const.js";
|
|
|
+import { AsyncValue } from "../../utils";
|
|
|
+const wmpfVoip = requirePlugin("wmpf-voip").default;
|
|
|
+const envVersion = wx.getAccountInfoSync().miniProgram.envVersion;
|
|
|
+const apiTypes = ["校园模式", "硬件模式", "呼叫安卓", "校园+硬件模式"];
|
|
|
+const apiTypesWMPF = [1, 0, 3];
|
|
|
+const apiTypesWechat = [2];
|
|
|
+
|
|
|
+const getEnvVersionForVoip = (function () {
|
|
|
+ const _map = {
|
|
|
+ develop: "developer",
|
|
|
+ trial: "trial",
|
|
|
+ release: "formal",
|
|
|
+ };
|
|
|
+ return () => {
|
|
|
+ return _map[envVersion];
|
|
|
+ };
|
|
|
+})();
|
|
|
+
|
|
|
+export default {
|
|
|
+ comments: {
|
|
|
+ name: "alarModel",
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ alarmModel: false,
|
|
|
+ eventListId: "",
|
|
|
+ nowTime: "",
|
|
|
+ devName: "",
|
|
|
+ authorizeFlag: true,
|
|
|
+ clientId: "",
|
|
|
+ mqttClientTwo: "",
|
|
|
+ // voip相关
|
|
|
+ isWmpf: isWmpf,
|
|
|
+ name: "用户",
|
|
|
+ voipDevices: [],
|
|
|
+ sn: "",
|
|
|
+ isShowPopUp: false,
|
|
|
+ contactList: [],
|
|
|
+ isWmpf,
|
|
|
+ envVersion,
|
|
|
+ apiTypesValid: (isWmpf ? apiTypesWMPF : apiTypesWechat).map(
|
|
|
+ (id) => apiTypes[id]
|
|
|
+ ),
|
|
|
+ apiTypeIndex: 0,
|
|
|
+ currentIndex: 0,
|
|
|
+ voipFlag: "",
|
|
|
+ userId: uni.getStorageSync("userId"),
|
|
|
+ hanledLists: [],
|
|
|
+ selectHanled: "",
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {},
|
|
|
+ methods: {
|
|
|
+ authorizeIot() {
|
|
|
+ this.hanledList("Voice");
|
|
|
+ this.sn = this.clientId;
|
|
|
+ this.alarmModel = false;
|
|
|
+ // const { name, sn, voipDevices } = this;
|
|
|
+ const name = this.name;
|
|
|
+ const sn = this.clientId;
|
|
|
+ const voipDevices = this.voipDevices;
|
|
|
+ console.log(name, sn, voipDevices, 88888888888);
|
|
|
+ if (!name || name.length === 0 || !sn || sn.length === 0) {
|
|
|
+ wx.showToast({
|
|
|
+ title: "请输入授权人名称和设备clientId",
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const { modelId } = config;
|
|
|
+ console.log(sn, modelId, 77777);
|
|
|
+ const { snTicket } = getSnTicket({
|
|
|
+ sn,
|
|
|
+ modelId,
|
|
|
+ });
|
|
|
+ console.log(snTicket, sn, 99999999);
|
|
|
+ var that = this;
|
|
|
+ wx.requestDeviceVoIP({
|
|
|
+ sn,
|
|
|
+ snTicket,
|
|
|
+ modelId,
|
|
|
+ deviceName: sn,
|
|
|
+ async success(res) {
|
|
|
+ console.log(`requestDeviceVoIP`, res);
|
|
|
+ await authorize({
|
|
|
+ sn,
|
|
|
+ name,
|
|
|
+ });
|
|
|
+ wx.showToast({
|
|
|
+ title: "授权成功",
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ const key = `voipDevices[${voipDevices.length}]`;
|
|
|
+ // that.setData({
|
|
|
+ // [key]: {
|
|
|
+ // sn,
|
|
|
+ // modelId,
|
|
|
+ // status: 1,
|
|
|
+ // },
|
|
|
+ // });
|
|
|
+ that.voipDevices[voipDevices.length] = {
|
|
|
+ sn,
|
|
|
+ modelId,
|
|
|
+ status: 1,
|
|
|
+ };
|
|
|
+
|
|
|
+ that.sn = sn;
|
|
|
+ that.modelId = modelId;
|
|
|
+ that.status = 1;
|
|
|
+ that.gotoCallPage();
|
|
|
+ },
|
|
|
+ fail(err) {
|
|
|
+ console.error(`requestDeviceVoIP failOne`, err);
|
|
|
+ wx.showToast({
|
|
|
+ title: "授权失败, 请前往设置页开启",
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ },
|
|
|
+ });
|
|
|
+ },
|
|
|
+ handleAlarm() {
|
|
|
+ this.hanledList("noVoice");
|
|
|
+ this.alarmModel = false;
|
|
|
+ },
|
|
|
+ // voip相关方法
|
|
|
+ async getVoipDevices() {
|
|
|
+ const { list } = await getDeviceVoIPList();
|
|
|
+ console.log("getDeviceVoIPList:", list);
|
|
|
+ if (list && list.length > 0) {
|
|
|
+ const authorizeFlag = list.some(
|
|
|
+ (item) => item.sn === this.clientId
|
|
|
+ );
|
|
|
+ console.log("authorizeFlag:", list, authorizeFlag);
|
|
|
+ this.authorizeFlag = authorizeFlag;
|
|
|
+ }
|
|
|
+ if (!list || list.length === 0) {
|
|
|
+ this.authorizeFlag = false;
|
|
|
+ }
|
|
|
+ if (typeof list === "object") {
|
|
|
+ this.voipDevices = list;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async authorizeIot() {
|
|
|
+ this.sn = this.clientId;
|
|
|
+ // this.alarmModel = false;
|
|
|
+ const name = this.name;
|
|
|
+ const sn = this.sn;
|
|
|
+ const voipDevices = this.voipDevices;
|
|
|
+ console.log(name, sn, voipDevices, 9999999999999);
|
|
|
+ // const { name, sn, voipDevices } = this;
|
|
|
+ if (!name || name.length === 0 || !sn || sn.length === 0) {
|
|
|
+ wx.showToast({
|
|
|
+ title: "请输入授权人名称和设备dev_id",
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const { modelId } = config;
|
|
|
+ console.log(sn, modelId, 77777);
|
|
|
+ const { snTicket } = await getSnTicket({
|
|
|
+ sn,
|
|
|
+ modelId,
|
|
|
+ });
|
|
|
+ console.log(snTicket, sn, 99999999);
|
|
|
+ var that = this;
|
|
|
+ wx.requestDeviceVoIP({
|
|
|
+ sn,
|
|
|
+ snTicket,
|
|
|
+ modelId,
|
|
|
+ deviceName: sn,
|
|
|
+ async success(res) {
|
|
|
+ console.log(`requestDeviceVoIP`, res);
|
|
|
+ await authorize({
|
|
|
+ sn,
|
|
|
+ name,
|
|
|
+ });
|
|
|
+ wx.showToast({
|
|
|
+ title: "授权成功",
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ const key = `voipDevices[${voipDevices.length}]`;
|
|
|
+ // that.key = {
|
|
|
+ // sn,
|
|
|
+ // modelId,
|
|
|
+ // status: 1,
|
|
|
+ // };
|
|
|
+ that.voipDevices[voipDevices.length] = {
|
|
|
+ sn,
|
|
|
+ modelId,
|
|
|
+ status: 1,
|
|
|
+ };
|
|
|
+ that.gotoCallPage();
|
|
|
+ },
|
|
|
+ fail(err) {
|
|
|
+ console.error(`requestDeviceVoIP failTwo`, err);
|
|
|
+ wx.showToast({
|
|
|
+ title: "授权失败, 请前往设置页开启",
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ },
|
|
|
+ });
|
|
|
+ },
|
|
|
+ async gotoCallPage() {
|
|
|
+ this.hanledList("Voice");
|
|
|
+ wx.showToast({
|
|
|
+ title: "通话加载中...",
|
|
|
+ icon: "loading",
|
|
|
+ duration: 2000, //持续的时间
|
|
|
+ });
|
|
|
+ // this.alarmModel = false;
|
|
|
+ this._caller = new AsyncValue();
|
|
|
+ let options = {
|
|
|
+ sn: this.sn,
|
|
|
+ };
|
|
|
+ await this.getSelf(options);
|
|
|
+ await this.getContactList();
|
|
|
+ let voiceCan = {
|
|
|
+ sn: this.sn,
|
|
|
+ idx: 1,
|
|
|
+ type: "voice",
|
|
|
+ };
|
|
|
+ await this.call(voiceCan);
|
|
|
+ },
|
|
|
+ async getSelf(options = {}) {
|
|
|
+ if (!this._caller.isPending()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (isWmpf) {
|
|
|
+ const { sn } = options;
|
|
|
+ if (sn) {
|
|
|
+ config.sn = sn;
|
|
|
+ this.sn = sn;
|
|
|
+ }
|
|
|
+ this._caller.set({
|
|
|
+ id: config.sn,
|
|
|
+ name: config.sn,
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ try {
|
|
|
+ const resp = await getUser();
|
|
|
+ console.log(`getUser`, resp);
|
|
|
+ this._caller.set({
|
|
|
+ id: resp.openid,
|
|
|
+ name: resp.name,
|
|
|
+ });
|
|
|
+ } catch (error) {
|
|
|
+ console.error(`getself error`, error);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async getContactList() {
|
|
|
+ wx.showLoading();
|
|
|
+ try {
|
|
|
+ let contactList = [];
|
|
|
+ const raw_contactList = await getContactList({
|
|
|
+ sn: isWmpf ? config.sn : null,
|
|
|
+ });
|
|
|
+ console.log(`raw_contactList`, raw_contactList);
|
|
|
+ if (!isWmpf) {
|
|
|
+ // 微信呼叫设备
|
|
|
+ const { list } = await getDeviceVoIPList();
|
|
|
+ contactList = raw_contactList.map(({ sn, pushToken }) => {
|
|
|
+ let canCall = true;
|
|
|
+ if (typeof list === "object") {
|
|
|
+ const canCallList = list
|
|
|
+ .filter(
|
|
|
+ (item) =>
|
|
|
+ item.status === AuthorizeStatus.ACCEPT
|
|
|
+ )
|
|
|
+ .map((item) => item.sn);
|
|
|
+ canCall = canCallList.includes(sn);
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ id: sn,
|
|
|
+ name: sn,
|
|
|
+ canCall,
|
|
|
+ ticket: pushToken,
|
|
|
+ };
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ // 设备呼叫微信
|
|
|
+ const raw_contactList = await getContactList({
|
|
|
+ sn: config.sn,
|
|
|
+ });
|
|
|
+ console.log(`raw_contactList: 业务方存储`, raw_contactList);
|
|
|
+ if (raw_contactList.length > 0) {
|
|
|
+ const canCallList = (
|
|
|
+ await wmpfVoip.getIotBindContactList({
|
|
|
+ sn: config.sn,
|
|
|
+ model_id: config.modelId,
|
|
|
+ openid_list: raw_contactList.map(
|
|
|
+ (item) => item.openid
|
|
|
+ ),
|
|
|
+ })
|
|
|
+ ).contact_list
|
|
|
+ .filter(
|
|
|
+ (item) => item.status === AuthorizeStatus.ACCEPT
|
|
|
+ )
|
|
|
+ .map((item) => item.openid);
|
|
|
+ console.log(`canCallList: 微信授权存储`, canCallList);
|
|
|
+ contactList = raw_contactList.map((item) => {
|
|
|
+ const canCall = canCallList.includes(item.openid);
|
|
|
+ return {
|
|
|
+ id: item.openid,
|
|
|
+ name: item.name,
|
|
|
+ canCall,
|
|
|
+ ticket: "",
|
|
|
+ };
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ console.log(`getContactList: `, contactList);
|
|
|
+
|
|
|
+ this.contactList = contactList;
|
|
|
+ } catch (error) {
|
|
|
+ console.error(`getContactList error: `, error);
|
|
|
+ }
|
|
|
+ wx.hideLoading();
|
|
|
+ },
|
|
|
+ async call(e) {
|
|
|
+ console.log(`call`, "走到了call方法");
|
|
|
+ const { sn, idx, type: roomtype } = e;
|
|
|
+ console.log(e, this.contactList, 888870);
|
|
|
+ const target = this.contactList.find((item) => item.id === sn);
|
|
|
+ console.log("走到了这里了。。。。1", target);
|
|
|
+ // const target = this.contactList[idx];
|
|
|
+ const apiTypeName = this.apiTypesValid[this.apiTypeIndex];
|
|
|
+ const businessType = apiTypes.indexOf(apiTypeName);
|
|
|
+ try {
|
|
|
+ if (!target.canCall) {
|
|
|
+ wx.showToast({
|
|
|
+ title: "用户未授权或设备不在线",
|
|
|
+ icon: "none",
|
|
|
+ });
|
|
|
+ throw Error("target can not call");
|
|
|
+ }
|
|
|
+ console.log("走到了这里了。。。。2");
|
|
|
+ const _caller = await this._caller.get();
|
|
|
+ console.log(`caller: `, _caller);
|
|
|
+ console.log(`listener: `, target);
|
|
|
+ const { roomId } = await wmpfVoip.callDevice({
|
|
|
+ roomType: "voice",
|
|
|
+ sn: sn,
|
|
|
+ modelId: "iFJ2BNIQcd9WlUIaT7_l4Q",
|
|
|
+ nickName: "xx",
|
|
|
+ isCloud: true,
|
|
|
+ payload: "radar-power.cn",
|
|
|
+ });
|
|
|
+ wx.redirectTo({
|
|
|
+ url: CallPagePlugin,
|
|
|
+ });
|
|
|
+ } catch (error) {
|
|
|
+ console.log(`>>>>>>>>>>>>>>>>>>>>>>>>>>>`);
|
|
|
+ console.error(`call error`, error);
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ hanledList(type) {
|
|
|
+ this.$http
|
|
|
+ .get(`wap/event/handleEvent`, {
|
|
|
+ eventListId: this.selectHanled.eventListId,
|
|
|
+ })
|
|
|
+ .then((res) => {
|
|
|
+ if (res.data.code == 200) {
|
|
|
+ if (type === "noVoice") {
|
|
|
+ uni.showToast({
|
|
|
+ title: "已处理",
|
|
|
+ icon: "success",
|
|
|
+ duration: 1500,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ uni.showToast({
|
|
|
+ title: "处理失败",
|
|
|
+ icon: "none",
|
|
|
+ duration: 1500,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if (this.hanledLists.length > 0) {
|
|
|
+ this.getFallingEventsQuery();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 查十分钟之内事件,事件模块
|
|
|
+ getVoipAuthor(clientId, userId) {
|
|
|
+ console.log(clientId, userId);
|
|
|
+ this.$http
|
|
|
+ .post(
|
|
|
+ "wap/share/queryUserVoipPermission",
|
|
|
+ {
|
|
|
+ userId: userId,
|
|
|
+ clientId: clientId,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ header: {
|
|
|
+ "Content-Type": "application/json;charset=UTF-8",
|
|
|
+ },
|
|
|
+ }
|
|
|
+ )
|
|
|
+ .then((res) => {
|
|
|
+ if (res.data.data) {
|
|
|
+ if (res.data.data.voipFlag === 0) {
|
|
|
+ this.voipFlag = true;
|
|
|
+ } else {
|
|
|
+ this.voipFlag = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.alarmModel = true;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getFallingEventsQuery() {
|
|
|
+ console.log(this.userId, 88888);
|
|
|
+ this.$http
|
|
|
+ .get("wap/stats/fallingEventsQuery", {
|
|
|
+ user_id: this.userId,
|
|
|
+ })
|
|
|
+ .then((res) => {
|
|
|
+ if (res.data.data) {
|
|
|
+ console.log(res.data.data, 9999);
|
|
|
+ if (res.data.data.length > 0) {
|
|
|
+ this.hanledLists = res.data.data;
|
|
|
+ this.selectHanled = this.hanledLists[0];
|
|
|
+ this.getClientId(this.selectHanled.devId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getClientId(devId) {
|
|
|
+ this.$http
|
|
|
+ .get("pub/queryClientIdByDevId", { devId: devId })
|
|
|
+ .then((res) => {
|
|
|
+ if (res.data.data) {
|
|
|
+ this.sn = res.data.data.clientId;
|
|
|
+ this.clientId = res.data.data.clientId;
|
|
|
+ this.devName = res.data.data.devName;
|
|
|
+ this.getVoipAuthor(this.clientId, this.userId);
|
|
|
+ if (!isWmpf) {
|
|
|
+ console.log("isWmpf:", isWmpf);
|
|
|
+ this.getVoipDevices();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.getFallingEventsQuery();
|
|
|
+ },
|
|
|
+ beforeDestroy() {},
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" scoped>
|
|
|
+/* 弹窗部分样式 */
|
|
|
+.mask {
|
|
|
+ position: fixed;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ right: 0;
|
|
|
+ bottom: 0;
|
|
|
+ background: rgba(0, 0, 0, 0.3);
|
|
|
+ z-index: 100;
|
|
|
+}
|
|
|
+
|
|
|
+.alarm-modal {
|
|
|
+ width: 675rpx;
|
|
|
+ height: 1100rpx;
|
|
|
+ position: fixed;
|
|
|
+ top: 50%;
|
|
|
+ left: 50%;
|
|
|
+ transform: translate(-50%, -50%);
|
|
|
+ background: linear-gradient(180deg, #ffdfdf 0%, #ffffff 30.3%);
|
|
|
+ border-radius: 37rpx 37rpx;
|
|
|
+ z-index: 103;
|
|
|
+ padding: 50rpx 55rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+
|
|
|
+ .alarm-header image {
|
|
|
+ width: 315rpx;
|
|
|
+ height: 40rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .alarm image {
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ right: 0;
|
|
|
+ width: 180rpx;
|
|
|
+ height: 175rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .nowTime {
|
|
|
+ width: 270rpx;
|
|
|
+ margin-top: 20rpx;
|
|
|
+ text-align: center;
|
|
|
+ align-items: center;
|
|
|
+ line-height: 100%;
|
|
|
+ background: #fed5d5;
|
|
|
+ color: #111111;
|
|
|
+ font-size: 28rpx;
|
|
|
+ border-radius: 10rpx;
|
|
|
+ padding: 5rpx 5rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .alarm-info {
|
|
|
+ margin-top: 40rpx;
|
|
|
+ color: #111111;
|
|
|
+ font-size: 28rpx;
|
|
|
+ letter-spacing: 4%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .backImg {
|
|
|
+ margin: 37rpx auto;
|
|
|
+ width: 400rpx;
|
|
|
+ height: 600rpx;
|
|
|
+ background-color: #fff;
|
|
|
+ border: 12rpx solid #333333;
|
|
|
+ background-image: url(http://jkld.radar-power.com//uploadFiles/framework/file/20250620/toilet_bg.png);
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-position: center;
|
|
|
+
|
|
|
+ image {
|
|
|
+ position: absolute;
|
|
|
+ top: 50%;
|
|
|
+ left: 50%;
|
|
|
+ width: 60rpx;
|
|
|
+ height: 60rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .alarm-bottom {
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .alarm-voice {
|
|
|
+ width: 185rpx;
|
|
|
+ height: 85rpx;
|
|
|
+ background: #f3e2dd;
|
|
|
+ border-radius: 28rpx;
|
|
|
+ color: #111111;
|
|
|
+ font-size: 32rpx;
|
|
|
+ text-align: center;
|
|
|
+ line-height: 85rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .alarm-handle {
|
|
|
+ margin-left: 20rpx;
|
|
|
+ width: 185rpx;
|
|
|
+ height: 85rpx;
|
|
|
+ background: linear-gradient(114.23deg, #a27867 0%, #74483d 100%);
|
|
|
+ border-radius: 28rpx;
|
|
|
+ box-shadow: 0rpx 4.69rpx 18.75rpx rgba(72, 41, 29, 0.15),
|
|
|
+ 0rpx 9.38rpx 9.38rpx rgba(154, 132, 89, 0.2),
|
|
|
+ 0rpx -4.69rpx 28.13rpx 4.69rpx #a16647 inset;
|
|
|
+ color: #ffffff;
|
|
|
+ font-size: 32rpx;
|
|
|
+ text-align: center;
|
|
|
+ line-height: 85rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|