初始化

This commit is contained in:
binghuai
2026-02-04 12:13:56 +08:00
commit 85db3f71d4
703 changed files with 73395 additions and 0 deletions

17
device/App.vue Normal file
View File

@@ -0,0 +1,17 @@
<script>
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
<style>
/*每个页面公共css */
</style>

20
device/index.html Normal file
View File

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>

22
device/main.js Normal file
View File

@@ -0,0 +1,22 @@
import App from './App'
// #ifndef VUE3
import Vue from 'vue'
import './uni.promisify.adaptor'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()
// #endif
// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
return {
app
}
}
// #endif

87
device/manifest.json Normal file
View File

@@ -0,0 +1,87 @@
{
"name" : "device",
"appid" : "__UNI__8CC071F",
"description" : "设备信息扫描系统",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
"app-plus" : {
"usingComponents" : true,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
"modules" : {
"Storage" : {}
},
"distribute" : {
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>"
]
},
"ios" : {
"dSYMs" : false
},
"icons" : {
"android" : {
"hdpi" : "unpackage/res/icons/72x72.png",
"xhdpi" : "unpackage/res/icons/96x96.png",
"xxhdpi" : "unpackage/res/icons/144x144.png",
"xxxhdpi" : "unpackage/res/icons/192x192.png"
},
"ios" : {
"appstore" : "unpackage/res/icons/1024x1024.png",
"ipad" : {
"app" : "unpackage/res/icons/76x76.png",
"app@2x" : "unpackage/res/icons/152x152.png",
"notification" : "unpackage/res/icons/20x20.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"proapp@2x" : "unpackage/res/icons/167x167.png",
"settings" : "unpackage/res/icons/29x29.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"spotlight" : "unpackage/res/icons/40x40.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png"
},
"iphone" : {
"app@2x" : "unpackage/res/icons/120x120.png",
"app@3x" : "unpackage/res/icons/180x180.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"notification@3x" : "unpackage/res/icons/60x60.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"settings@3x" : "unpackage/res/icons/87x87.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png",
"spotlight@3x" : "unpackage/res/icons/120x120.png"
}
}
}
}
},
"quickapp" : {},
"mp-weixin" : {
"appid" : "wx1b139d5cf2c91360",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"h5" : {
"template" : "template.h5.html",
"router" : {
"mode" : "history",
"base" : "/h5/"
}
}
}

28
device/pages.json Normal file
View File

@@ -0,0 +1,28 @@
// uniapp/pages.json
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "设备信息扫描",
"navigationBarBackgroundColor": "#667eea",
"navigationBarTextStyle": "white"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "设备管理系统",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"condition": {
"current": 0,
"list": [
{
"name": "设备信息首页",
"path": "pages/index/index"
}
]
}
}

View File

@@ -0,0 +1,845 @@
<!-- uniapp/pages/index/index.vue -->
<template>
<view class="container">
<view class="header">
<text class="title">设备信息扫描</text>
</view>
<view class="card">
<view class="info-item">
<text class="label">设备唯一标识符(Device ID)</text>
<view class="value-row">
<text class="value" selectable>{{ deviceInfo.deviceId || '扫描中...' }}</text>
<button class="copy-btn" size="mini" @click="copyText(deviceInfo.deviceId)">复制</button>
</view>
</view>
<!-- Device Info -->
<view class="info-item">
<text class="label">设备类型</text>
<text class="value">{{ deviceInfo.deviceType || '未知' }}</text>
</view>
<view class="info-item">
<text class="label">设备品牌</text>
<text class="value">{{ deviceInfo.deviceBrand || '未知' }}</text>
</view>
<view class="info-item">
<text class="label">设备型号</text>
<text class="value">{{ deviceInfo.deviceModel || '未知' }}</text>
</view>
<!-- OS Info -->
<view class="info-item">
<text class="label">系统名称</text>
<text class="value">{{ deviceInfo.osName || '未知' }}</text>
</view>
<view class="info-item">
<text class="label">操作系统版本</text>
<text class="value">{{ deviceInfo.osVersion || '未知' }}</text>
</view>
<view class="info-item">
<text class="label">编译器版本</text>
<text class="value">{{ deviceInfo.uniCompileVersion || '未知' }}</text>
</view>
<!-- App Info -->
<view class="info-item">
<text class="label">应用ID</text>
<text class="value">{{ deviceInfo.appId || '未知' }}</text>
</view>
<!-- Persistent ID Info -->
<view class="info-item">
<text class="label">持久化设备ID</text>
<view class="value-row">
<text class="value" selectable>{{ persistentDeviceId || '未生成' }}</text>
<button class="copy-btn" size="mini" @click="copyText(persistentDeviceId)">复制</button>
</view>
</view>
<!-- File Status Info -->
<view class="info-item">
<text class="label">文件路径</text>
<text class="value" selectable>{{ filePath || '获取中...' }}</text>
</view>
<view class="info-item">
<text class="label">文件状态</text>
<text class="value">{{ fileStatus || '检查中...' }}</text>
</view>
</view>
<!-- 文件操作按钮 -->
<view class="button-group">
<button class="action-btn primary" @click="checkAndReadFile">检查并读取文件</button>
<button class="action-btn secondary" @click="writeFileToDevice">写入文件到设备</button>
<button class="action-btn warning" @click="showFilePathInfo">查看文件路径说明</button>
</view>
<view class="tips">
<text class="tip-text">提示文件将保存在设备的公共目录中应用卸载后文件仍会保留</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
deviceInfo: {},
persistentDeviceId: '',
fileStatus: '未知',
filePath: '未知'
}
},
onLoad() {
// 页面加载时自动检查并读取文件
this.checkAndReadFile()
this.scanDeviceInfo()
},
methods: {
// 检查并读取文件
async checkAndReadFile() {
try {
const result = await this.readFileFromDevice()
console.log("读取文件结果:", result);
if (result.content) {
this.persistentDeviceId = result.content
this.filePath = result.path
this.fileStatus = '文件存在,内容: ' + result.content
uni.showToast({
title: '读取文件成功',
icon: 'success'
})
} else {
this.filePath = result.path
this.fileStatus = '文件不存在,请点击"写入文件到设备"按钮创建文件'
uni.showToast({
title: '文件不存在',
icon: 'none'
})
}
} catch (error) {
console.error('读取文件失败:', error)
this.fileStatus = '读取文件失败: ' + (error.message || '未知错误')
uni.showToast({
title: '读取文件失败',
icon: 'none'
})
}
},
// 从设备读取文件
readFileFromDevice() {
return new Promise((resolve, reject) => {
//#ifdef APP-PLUS
// Android平台使用外部公共存储
if (plus.os.name === "Android") {
// 请求存储权限
this.requestStoragePermissions().then(() => {
try {
// 使用提供的工具函数读取文件
const FileUtil = this.getFileUtil();
const Environment = plus.android.importClass("android.os.Environment");
const externalDir = Environment.getExternalStorageDirectory();
const realPath = plus.android.invoke(externalDir, "getAbsolutePath");
const filePath = realPath + "/device_id.txt";
console.log("尝试从路径读取文件: " + filePath);
// 检查文件是否存在
if (FileUtil.isFileExist(filePath)) {
// 文件存在,读取内容
const contentList = FileUtil.readTxt(filePath, 'utf-8');
if (contentList && contentList.length > 0) {
resolve({
content: contentList[0], // 读取第一行内容
path: filePath
});
} else {
resolve({
content: '',
path: filePath
});
}
} else {
// 文件不存在
resolve({
content: '',
path: filePath
});
}
} catch (e) {
console.error('读取文件失败:', e);
reject(new Error('读取文件出错: ' + e.message));
}
}).catch((error) => {
reject(new Error('权限请求失败: ' + error.message));
});
}
// iOS平台使用Documents目录应用卸载后会被删除
else if (plus.os.name === "iOS") {
plus.io.requestFileSystem(plus.io.PUBLIC_DOCUMENTS, (fs) => {
const filePath = plus.io.convertLocalFileSystemURL(fs.root.toURL() + 'device_id.txt');
fs.root.getFile('device_id.txt', {create: false}, (fileEntry) => {
fileEntry.file((file) => {
const reader = new plus.io.FileReader();
reader.onloadend = (e) => {
resolve({
content: e.target.result,
path: filePath
});
};
reader.onerror = (e) => {
resolve({
content: '',
path: filePath
});
};
reader.readAsText(file);
}, (e) => {
resolve({
content: '',
path: filePath
});
});
}, (e) => {
resolve({
content: '',
path: filePath
});
});
}, (e) => {
reject(new Error('无法访问文件系统'));
});
}
//#endif
//#ifndef APP-PLUS
// 非App端使用Storage模拟
try {
const content = uni.getStorageSync('device_id_file')
resolve({
content: content || '',
path: 'Storage模拟存储'
})
} catch (e) {
resolve({
content: '',
path: 'Storage模拟存储'
})
}
//#endif
})
},
// 写入文件到设备
async writeFileToDevice() {
try {
const result = await this.writeFileToDeviceStorage('787112776')
this.filePath = result.path
this.fileStatus = '文件已写入: 787112776'
this.persistentDeviceId = '787112776'
uni.showToast({
title: '文件写入成功',
icon: 'success'
})
// 显示文件路径提示
uni.showModal({
title: '文件写入成功',
content: `文件已保存到以下路径:\n${result.path}\n\n注意此文件在应用卸载后仍会保留`,
showCancel: false
})
} catch (error) {
console.error('写入文件失败:', error)
this.fileStatus = '写入文件失败: ' + (error.message || '未知错误')
uni.showToast({
title: '写入文件失败',
icon: 'none'
})
// 显示详细错误信息
uni.showModal({
title: '写入失败',
content: '错误详情: ' + (error.message || '未知错误'),
showCancel: false
})
}
},
// 写入文件到设备存储
writeFileToDeviceStorage(content) {
return new Promise((resolve, reject) => {
//#ifdef APP-PLUS
// Android平台使用外部公共存储
if (plus.os.name === "Android") {
// 请求存储权限
this.requestStoragePermissions().then(() => {
try {
// 使用提供的工具函数写入文件
const FileUtil = this.getFileUtil();
const Environment = plus.android.importClass("android.os.Environment");
const externalDir = Environment.getExternalStorageDirectory();
const realPath = plus.android.invoke(externalDir, "getAbsolutePath");
const filePath = realPath + "/device_id.txt";
console.log("尝试写入文件到路径: " + filePath);
// 确保目录存在
const dirPath = realPath;
if (FileUtil.mkdirs(dirPath)) {
console.log("目录创建成功: " + dirPath);
} else {
console.log("目录已存在或创建失败: " + dirPath);
}
// 写入文件内容
const writeResult = FileUtil.writeTxt(filePath, content, false, 'utf-8');
if (writeResult) {
console.log("文件写入成功");
resolve({
path: filePath
});
} else {
console.error("文件写入失败");
reject(new Error('文件写入失败'));
}
} catch (e) {
console.error('写入文件失败:', e);
reject(new Error('写入文件出错: ' + e.message));
}
}).catch((error) => {
reject(new Error('权限请求失败: ' + error.message));
});
}
// iOS平台使用Documents目录
else if (plus.os.name === "iOS") {
plus.io.requestFileSystem(plus.io.PUBLIC_DOCUMENTS, (fs) => {
const filePath = plus.io.convertLocalFileSystemURL(fs.root.toURL() + 'device_id.txt');
fs.root.getFile('device_id.txt', {create: true}, (fileEntry) => {
fileEntry.createWriter((writer) => {
writer.onwrite = () => {
resolve({
path: filePath
});
};
writer.onerror = (e) => {
reject(new Error('写入文件出错'));
};
writer.write(content);
}, (e) => {
reject(new Error('无法创建文件写入器'));
});
}, (e) => {
reject(new Error('无法创建文件'));
});
}, (e) => {
reject(new Error('无法访问文件系统'));
});
}
//#endif
//#ifndef APP-PLUS
// 非App端使用Storage模拟
try {
uni.setStorageSync('device_id_file', content)
resolve({
path: 'Storage模拟存储'
})
} catch (e) {
reject(new Error('存储失败'))
}
//#endif
})
},
// 请求存储权限
requestStoragePermissions() {
return new Promise((resolve, reject) => {
//#ifdef APP-PLUS
if (plus.os.name === "Android") {
plus.android.requestPermissions([
'android.permission.WRITE_EXTERNAL_STORAGE',
'android.permission.READ_EXTERNAL_STORAGE'
], (resultObj) => {
const result = resultObj.granted.length > 0;
if (result) {
console.log("存储权限获取成功");
resolve();
} else {
console.error("存储权限获取失败");
reject(new Error('未获得存储权限'));
}
}, (error) => {
console.error("权限请求出错:", error);
reject(new Error('权限请求出错: ' + error.message));
});
} else {
resolve();
}
//#endif
//#ifndef APP-PLUS
resolve();
//#endif
});
},
// 获取文件工具函数
getFileUtil() {
const FileUtil = {
/**
* 获取手机内置存储的根路径
* @return {String}
*/
root: function() {
const environment = plus.android.importClass("android.os.Environment");
return environment.getExternalStorageDirectory();
},
/**
* 创建文件
* @return {boolean} flase=失败已存在、操作失败true=成功
*/
createNewFile: function(path = '') {
const File = plus.android.importClass('java.io.File');
let file = new File(path);
if (!file.exists()) {
return file.createNewFile();
}
return false;
},
/**
* 创建文件夹
* @return {boolean} flase=失败已存在、操作失败true=成功
*/
mkdirs: function(path = ''){
const File = plus.android.importClass('java.io.File');
let file = new File(path);
if (!file.exists()) {
return file.mkdirs();
}
return false;
},
/**
* 读取文件
* @param {String} path 文件路径
* @param {String} charset 编码
* @return {Array<String>} 内容列表(按行读取),文件不存在或异常则返回false
*/
readTxt: function(path = '', charset = 'utf-8') {
const File = plus.android.importClass('java.io.File');
const InputStreamReader = plus.android.importClass('java.io.InputStreamReader');
const BufferedReader = plus.android.importClass('java.io.BufferedReader');
const FileInputStream = plus.android.importClass('java.io.FileInputStream');
let file = new File(path);
let inputStreamReader = null;
let bufferedReader = null;
let list = [];
try {
if (!file.exists()) {
return false;
}
inputStreamReader = new InputStreamReader(new FileInputStream(file), charset);
bufferedReader = new BufferedReader(inputStreamReader);
let line = '';
while (null != (line = bufferedReader.readLine())) {
list.push(line);
}
bufferedReader.close();
inputStreamReader.close();
} catch (e) {
if (null != bufferedReader) {
bufferedReader.close();
}
if (null != inputStreamReader) {
inputStreamReader.close();
}
return false;
}
return list;
},
/**
* 写入文件内容
* @param {String} path 文件路径
* @param {String} content 内容
* @param {boolean} append 内容写入类型false=不追加覆盖原有内容true=追加(从内容尾部写入)
* @param {String} charset 编码
* @return {boolean} true=成功false=失败
*/
writeTxt: function(path = '', content = '', append = false, charset = 'utf-8') {
const File = plus.android.importClass('java.io.File');
const FileOutputStream = plus.android.importClass('java.io.FileOutputStream');
const OutputStreamWriter = plus.android.importClass('java.io.OutputStreamWriter');
let outputStreamWriter;
let file = new File(path);
try {
//不存在则创建新的文件
if (!file.exists()) {
file.createNewFile();
}
outputStreamWriter = new OutputStreamWriter(new FileOutputStream(path, append), charset);
outputStreamWriter.write(content);
outputStreamWriter.close();
} catch (e) {
if (null != outputStreamWriter) {
outputStreamWriter.close();
}
return false;
}
return true;
},
/**
* 判断文件是否存在
* @param path 文件路径
* @return true=存在 false=不存在
*/
isFileExist: function(path = ''){
const File = plus.android.importClass('java.io.File');
return new File(path).exists()
},
/**
* 删除文件
* @param {String} path
*/
deleteFile: function(path = ''){
const File = plus.android.importClass('java.io.File');
let file = new File(path);
if (file.exists()) {
return file.delete();
}
return false
}
};
return FileUtil;
},
// 显示文件路径说明
showFilePathInfo() {
let content = '';
//#ifdef APP-PLUS
if (plus.os.name === "Android") {
content = 'Android平台文件保存在设备的公共存储根目录中\n' +
'路径类似于:\n' +
'/storage/emulated/0/device_id.txt\n\n' +
'该文件在应用卸载后仍会保留。';
} else if (plus.os.name === "iOS") {
content = 'iOS平台文件保存在应用的Documents目录中\n' +
'路径类似于:\n' +
'/var/mobile/Containers/Data/Application/应用标识/Documents/device_id.txt\n\n' +
'注意iOS平台应用卸载后文件会被删除这是系统限制。';
}
//#endif
//#ifndef APP-PLUS
content = '非App平台使用Storage模拟存储无法实现持久化保存。';
//#endif
uni.showModal({
title: '文件路径说明',
content: content,
showCancel: false
});
},
// 扫描设备信息
scanDeviceInfo() {
try {
// 获取系统信息
const systemInfo = uni.getSystemInfoSync()
// 构建设备信息对象
this.deviceInfo = {
// Device Info
deviceId: this.getRealDeviceId(systemInfo),
deviceType: systemInfo.deviceType || '未知',
deviceBrand: systemInfo.deviceBrand || '未知',
deviceModel: systemInfo.deviceModel || '未知',
deviceOrientation: systemInfo.deviceOrientation || '未知',
devicePixelRatio: systemInfo.devicePixelRatio || '未知',
// OS Info
osName: systemInfo.osName || systemInfo.platform || '未知',
osVersion: systemInfo.osVersion || systemInfo.system || '未知',
osLanguage: systemInfo.osLanguage || '未知',
osTheme: systemInfo.osTheme || '未知',
osAndroidAPILevel: systemInfo.osAndroidAPILevel || '未知',
// ROM Info
romName: systemInfo.romName || '未知',
romVersion: systemInfo.romVersion || '未知',
// Browser Info
browserName: systemInfo.browserName || '未知',
browserVersion: systemInfo.browserVersion || '未知',
// Host Info
hostName: systemInfo.hostName || '未知',
hostVersion: systemInfo.hostVersion || '未知',
hostLanguage: systemInfo.hostLanguage || '未知',
hostTheme: systemInfo.hostTheme || '未知',
hostFontSizeSetting: systemInfo.hostFontSizeSetting || '未知',
hostPackageName: systemInfo.hostPackageName || '未知',
hostSDKVersion: systemInfo.hostSDKVersion || '未知',
// Uni-app Framework Info
uniPlatform: systemInfo.uniPlatform || '未知',
uniCompileVersion: systemInfo.uniCompileVersion || '未知',
uniCompilerVersion: systemInfo.uniCompilerVersion || '未知',
uniRuntimeVersion: systemInfo.uniRuntimeVersion || '未知',
// App Info
appId: systemInfo.appId || '未知',
appName: systemInfo.appName || '未知',
appVersion: systemInfo.appVersion || '未知',
appVersionCode: systemInfo.appVersionCode || '未知',
appWgtVersion: systemInfo.appWgtVersion || '未知',
appLanguage: systemInfo.appLanguage || '未知',
// 兼容旧版本字段
brand: systemInfo.brand || '未知',
model: systemInfo.model || '未知',
system: systemInfo.system || '未知',
platform: systemInfo.platform || '未知',
screen: `${systemInfo.screenWidth}x${systemInfo.screenHeight}` || '未知'
}
console.log('设备信息扫描完成:', this.deviceInfo)
uni.showToast({
title: '扫描完成',
icon: 'success'
})
} catch (error) {
console.error('设备信息扫描失败:', error)
uni.showToast({
title: '扫描失败',
icon: 'none'
})
}
},
// 获取真实的设备ID
getRealDeviceId(systemInfo) {
// 首先尝试从缓存获取deviceId
let deviceId = uni.getStorageSync('realDeviceId')
if (!deviceId) {
// 优先使用系统提供的deviceId
deviceId = systemInfo.deviceId || systemInfo.uuid || '未知'
// 如果还是获取不到,尝试其他方式
if (!deviceId || deviceId === '未知' || deviceId === '000000000000000') {
//#ifdef APP-PLUS
try {
// App端尝试获取更真实的设备ID
const deviceInfo = plus.device.getInfo();
if (deviceInfo.uuid && deviceInfo.uuid !== '000000000000000') {
deviceId = deviceInfo.uuid;
} else if (deviceInfo.imei) {
deviceId = deviceInfo.imei;
} else if (deviceInfo.imsi) {
deviceId = deviceInfo.imsi;
}
} catch (e) {
console.log('通过plus.device获取设备ID失败:', e);
}
//#endif
}
// 如果仍然获取不到使用持久化ID作为备选
if ((!deviceId || deviceId === '未知' || deviceId === '000000000000000') && this.persistentDeviceId) {
deviceId = this.persistentDeviceId
}
// 如果仍然获取不到生成一个备用ID并缓存
if (!deviceId || deviceId === '未知' || deviceId === '000000000000000') {
deviceId = this.generateFallbackDeviceId(systemInfo)
}
// 将获取到的deviceId保存到缓存中
uni.setStorageSync('realDeviceId', deviceId)
}
return deviceId
},
// 备用方案生成设备ID仅在无法获取真实ID时使用
generateFallbackDeviceId(systemInfo) {
// 基于设备信息和时间戳生成唯一ID
const deviceData = `${systemInfo.brand}_${systemInfo.model}_${systemInfo.system}_${systemInfo.platform}_${Date.now()}`
// 简单的哈希函数生成唯一标识
let hash = 0
for (let i = 0; i < deviceData.length; i++) {
const char = deviceData.charCodeAt(i)
hash = ((hash << 5) - hash) + char
hash = hash & hash // 转换为32位整数
}
return 'fallback_' + Math.abs(hash).toString(16) + '_' + Date.now()
},
// 复制文本
copyText(text) {
if (!text) {
uni.showToast({
title: '无内容可复制',
icon: 'none'
})
return
}
uni.setClipboardData({
data: text,
success: () => {
uni.showToast({
title: '已复制',
icon: 'success'
})
},
fail: () => {
uni.showToast({
title: '复制失败',
icon: 'none'
})
}
})
}
}
}
</script>
<style scoped>
.container {
padding: 20rpx;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
}
.header {
text-align: center;
padding: 40rpx 0;
}
.title {
font-size: 36rpx;
font-weight: bold;
color: #fff;
text-shadow: 0 2rpx 4rpx rgba(0,0,0,0.2);
}
.card {
background: rgba(255, 255, 255, 0.95);
border-radius: 20rpx;
padding: 30rpx;
margin-bottom: 30rpx;
box-shadow: 0 8rpx 30rpx rgba(0, 0, 0, 0.15);
backdrop-filter: blur(10rpx);
}
.info-item {
margin-bottom: 30rpx;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #eee;
}
.info-item:last-child {
margin-bottom: 0;
border-bottom: none;
}
.label {
font-size: 26rpx;
color: #666;
display: block;
margin-bottom: 10rpx;
font-weight: 500;
}
.value-row {
display: flex;
justify-content: space-between;
align-items: center;
}
.value {
font-size: 28rpx;
color: #333;
flex: 1;
word-break: break-all;
font-weight: 600;
}
.copy-btn {
font-size: 24rpx;
padding: 10rpx 20rpx;
background: #409EFF;
color: white;
border: none;
border-radius: 10rpx;
white-space: nowrap;
}
.button-group {
display: flex;
flex-direction: column;
gap: 20rpx;
padding: 0 20rpx;
}
.action-btn {
padding: 20rpx;
font-size: 32rpx;
font-weight: bold;
border: none;
border-radius: 50rpx;
width: 100%;
box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.2);
}
.primary {
background: linear-gradient(90deg, #ff9a9e 0%, #fecfef 50%, #fecfef 100%);
color: #333;
}
.secondary {
background: linear-gradient(90deg, #4facfe 0%, #00f2fe 100%);
color: white;
}
.warning {
background: linear-gradient(90deg, #f6d365 0%, #fda085 100%);
color: #333;
}
.action-btn:active {
transform: scale(0.98);
}
.tips {
padding: 30rpx;
text-align: center;
}
.tip-text {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.9);
line-height: 1.6;
}
</style>

BIN
device/static/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -0,0 +1,13 @@
uni.addInterceptor({
returnValue (res) {
if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) {
return res;
}
return new Promise((resolve, reject) => {
res.then((res) => {
if (!res) return resolve(res)
return res[0] ? reject(res[0]) : resolve(res[1])
});
});
},
});

76
device/uni.scss Normal file
View File

@@ -0,0 +1,76 @@
/**
* 这里是uni-app内置的常用样式变量
*
* uni-app 官方扩展插件及插件市场https://ext.dcloud.net.cn上很多三方插件均使用了这些样式变量
* 如果你是插件开发者建议你使用scss预处理并在插件代码中直接使用这些变量无需 import 这个文件方便用户通过搭积木的方式开发整体风格一致的App
*
*/
/**
* 如果你是App开发者插件使用者你可以通过修改这些变量来定制自己的插件主题实现自定义主题功能
*
* 如果你的项目同样使用了scss预处理你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
*/
/* 颜色变量 */
/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
/* 文字基本颜色 */
$uni-text-color:#333;//基本色
$uni-text-color-inverse:#fff;//反色
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;
/* 背景颜色 */
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
/* 边框颜色 */
$uni-border-color:#c8c7cc;
/* 尺寸变量 */
/* 文字尺寸 */
$uni-font-size-sm:12px;
$uni-font-size-base:14px;
$uni-font-size-lg:16px;
/* 图片尺寸 */
$uni-img-size-sm:20px;
$uni-img-size-base:26px;
$uni-img-size-lg:40px;
/* Border Radius */
$uni-border-radius-sm: 2px;
$uni-border-radius-base: 3px;
$uni-border-radius-lg: 6px;
$uni-border-radius-circle: 50%;
/* 水平间距 */
$uni-spacing-row-sm: 5px;
$uni-spacing-row-base: 10px;
$uni-spacing-row-lg: 15px;
/* 垂直间距 */
$uni-spacing-col-sm: 4px;
$uni-spacing-col-base: 8px;
$uni-spacing-col-lg: 12px;
/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
/* 文章场景相关 */
$uni-color-title: #2C405A; // 文章标题颜色
$uni-font-size-title:20px;
$uni-color-subtitle: #555555; // 二级标题颜色
$uni-font-size-subtitle:26px;
$uni-color-paragraph: #3F536E; // 文章段落颜色
$uni-font-size-paragraph:15px;