Files
cashier_wx/components/devetools.vue

285 lines
6.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="floating-widget" v-if="show">
<!-- 悬浮按钮 -->
<view
class="floating-btn"
@click="togglePopup"
:style="{
backgroundColor: btnColor,
width: `${btnSize}px`,
height: `${btnSize}px`,
}"
:class="{ active: isPopupVisible }"
>
<up-icon
name="plus"
size="24"
color="#ffffff"
:class="{ rotate: isPopupVisible }"
></up-icon>
</view>
<!-- 操作弹窗 -->
<view class="popup" v-if="isPopupVisible" :class="{ show: isPopupVisible }">
<view class="popup-arrow"></view>
<view class="popup-content">
<view
class="popup-item"
v-for="(item, index) in operations"
:key="index"
@click="handleOperation(item.action)"
>
<text class="item-text">{{ item.name }}</text>
</view>
</view>
</view>
<!-- 点击外部关闭遮罩 -->
<view class="overlay" v-if="isPopupVisible" @click="closePopup"></view>
</view>
</template>
<script setup>
import { ref, defineProps, defineEmits,computed } from "vue";
const show=computed(()=>{
const sysInfo=uni.getAccountInfoSync();
if(sysInfo&&sysInfo.miniProgram && (sysInfo.miniProgram.envVersion == 'release'||sysInfo.miniProgram.envVersion == 'develop')) {
return true;
}
return false
})
// 定义组件属性
const props = defineProps({
// 操作选项列表
operations: {
type: Array,
default: () => [
{
name: "复制token",
icon: "arrowup",
action: "token",
color: "#007aff",
},
{
name: "复制用户信息",
icon: "userInfo",
action: "userInfo",
color: "#52c41a",
},
{
name: "获取登录code",
icon: "userInfo",
action: "getLoginCode",
color: "#52c41a",
},
{
name: "复制当前门店信息",
icon: "userInfo",
action: "copyStoreInfo",
color: "#52c41a",
},
{
name: "复制当前门店用户信息",
icon: "userInfo",
action: "copyStoreUserInfo",
color: "#52c41a",
},
],
},
// 悬浮按钮颜色
btnColor: {
type: String,
default: "#007aff",
},
// 悬浮按钮大小(px)
btnSize: {
type: Number,
default: 60,
},
// 弹窗距离底部的距离
bottomDistance: {
type: Number,
default: 20,
},
// 弹窗距离右侧的距离
rightDistance: {
type: Number,
default: 20,
},
});
// 定义组件事件
const emit = defineEmits(["onOperation", "onOpen", "onClose"]);
// 弹窗显示状态
const isPopupVisible = ref(false);
// 切换弹窗显示/隐藏
const togglePopup = () => {
isPopupVisible.value = !isPopupVisible.value;
if (isPopupVisible.value) {
emit("onOpen");
} else {
emit("onClose");
}
};
// 关闭弹窗
const closePopup = () => {
if (isPopupVisible.value) {
isPopupVisible.value = false;
emit("onClose");
}
};
async function getWxloginCode(){
return new Promise((resolve, reject) => {
uni.login({
success: (res) => {
if (res.code) {
resolve(res.code);
} else {
console.log("获取登录凭证code失败" + res.errMsg);
reject(res.errMsg);
}
},
});
});
}
// 处理操作选择
const handleOperation = async (action) => {
let data='';
if (action == "token") {
data=uni.cache.get("token");
}
if (action == "userInfo") {
data=JSON.stringify(uni.cache.get("userInfo"));
}
if(action == "getLoginCode"){
data=await getWxloginCode();
}
if(action == "copyStoreInfo"){
data=JSON.stringify(uni.cache.get("shopInfo"));
}
if(action == "copyStoreUserInfo"){
data=JSON.stringify(uni.cache.get("shopUserInfo"));
}
console.log('data',data)
uni.setClipboardData({
data: data,
success: function () {},
});
emit("onOperation", action);
closePopup();
};
</script>
<style scoped>
.floating-widget {
position: fixed;
right: v-bind(rightDistance + "px");
bottom: v-bind(bottomDistance + "px");
z-index: 9999;
display: flex;
flex-direction: column;
align-items: flex-end;
}
/* 悬浮按钮样式 */
.floating-btn {
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
background: linear-gradient(98deg, #fe6d1100 40.64%, #ffd1b4 105.2%),
linear-gradient(259deg, #fe6d11 50.14%, #ffd1b4 114.93%);
box-shadow: 0 0.4375rem 0.95rem 0 #fe8b435e;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 1001;
}
.floating-btn.active {
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
transform: scale(1.05);
}
.floating-btn .rotate {
transform: rotate(45deg);
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
/* 弹窗样式 */
.popup {
position: absolute;
bottom: calc(100% + 15px);
right: 0;
min-width: 160px;
background-color: #ffffff;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
opacity: 0;
transform: translateY(10px) scale(0.95);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 1000;
pointer-events: none;
}
.popup.show {
opacity: 1;
transform: translateY(0) scale(1);
pointer-events: auto;
}
/* 弹窗箭头 */
.popup-arrow {
position: absolute;
right: 20px;
bottom: -8px;
width: 16px;
height: 16px;
background-color: #ffffff;
transform: rotate(45deg);
box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.05);
}
.popup-content {
padding: 8px 0;
position: relative;
z-index: 1;
}
/* 操作选项样式 */
.popup-item {
display: flex;
align-items: center;
padding: 12px 20px;
cursor: pointer;
transition: background-color 0.2s ease;
}
.popup-item:hover {
background-color: #f5f7fa;
}
.item-text {
margin-left: 12px;
font-size: 14px;
color: #333333;
line-height: 1;
}
/* 遮罩层样式 */
.overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0);
z-index: 999;
}
</style>