du -h --max-depth=1 /usr/lib | sort -h
作者归档:admin
base64图片复制
vue
$vue->method("copy_base64_data(data)","
location.origin.includes(`https://`) || Message.error(`图片复制功能不可用`);
data = data.split(';base64,'); let type = data[0].split('data:')[1]; data = data[1];
let bytes = atob(data), ab = new ArrayBuffer(bytes.length), ua = new Uint8Array(ab);
[...Array(bytes.length)].forEach((v, i) => ua[i] = bytes.charCodeAt(i));
let blob = new Blob([ab], { type });
navigator.clipboard.write([new ClipboardItem({ [type]: blob })]);
");
PHP中返回的data值
'data:image/png;base64,'.base64_encode($content)
蓝牙 blueMixin.js
/**
* 蓝牙相关操作
*
import { blueMixin } from 'mixin/blueMixin';
export default {
mixins: [blueMixin],
};
onLoad里面
this.openBluetooth();
this.device_no = uni.getStorageSync('uni_bluetooth_deviceId');
*
*/
export const blueMixin = {
data() {
return {
dataToSend: "",
checkLette: '', // 蓝牙ID前缀
//checkLette: '', // 蓝牙ID前缀
devices: [], // 存储搜索到的设备
receivedData: null, // 保存接收到的数据
device_no: null, // 用localName
deviceId: null, // 当前连接的设备ID
serviceId: '', // 服务UUID
characteristicId: '', // 特征UUID
connectedDeviceName: '', //当前连接的设备
characteristicIdWrite: '',
connect_status: false, //连接状态
loop_blue: '',
};
},
onShow() {
this.initBlue()
},
methods: {
initBlue() {
this.device_no = uni.getStorageSync('uni_bluetooth_deviceId');
},
sendData() {
if (!this.dataToSend) {
console.warn('没有要发送的数据');
return;
}
console.log('sendData >> ', this.dataToSend);
// 将字符串转换为 HEX
let d = this.dataToSend
d = JSON.stringify(this.dataToSend)
const hexData = this.strToHex(d); // 转换为 HEX
console.log('hex', hexData);
// 将 HEX 转换为 ArrayBuffer
const buffer = this.hexToArrayBuffer(hexData); // 转换为 ArrayBuffer
console.log('ArrayBuffer', buffer);
uni.writeBLECharacteristicValue({
deviceId: this.deviceId,
serviceId: this.serviceId,
characteristicId: this.characteristicIdWrite,
value: buffer,
success: (res) => {
uni.showToast({
title: "发送成功,请在茶壶上操作",
icon: "none"
})
console.log('发送数据成功', res);
},
fail: (err) => {
uni.showToast({
title: "连接异常",
icon: "none"
})
console.error('发送数据失败', err);
}
});
},
openBluetooth() {
uni.openBluetoothAdapter({
success: (res) => {
console.log('蓝牙适配器已打开', res);
this.searchBluetooth();
if (this.loop_blue) {
clearInterval(this.loop_blue)
}
this.loop_blue = setInterval(() => {
this.searchBluetooth()
console.log("3 秒重连")
}, 3000)
},
fail: (err) => {
uni.showModal({
title: '提示',
content: '请打开蓝牙',
showCancel: false,
success: (res) => {
if (res.confirm) {
console.log('用户点击确定');
}
}
})
console.error('打开蓝牙适配器失败', err);
}
});
},
// 启动搜索设备
searchBluetooth() {
// 清空之前的设备列表
this.devices = [];
console.log('搜索蓝牙设备');
uni.startBluetoothDevicesDiscovery({
success: (res) => {
console.log('开始搜索设备', res);
},
fail: (err) => {
console.error('开始搜索设备失败', err);
}
});
// 监听设备发现
console.log("搜索设备No:" + this.device_no)
uni.onBluetoothDeviceFound((devices) => {
devices.devices.forEach(device => {
// 根据前缀过滤设备
if (device.name && (this.checkLette === '' || device.name.startsWith(this
.checkLette))) {
console.log('发现设备 deviceId' + device.deviceId)
console.log('发现设备 localName ' + device.localName)
console.log(device)
this.deviceId = device.deviceId
this.devices.push(device);
if (this.device_no && this.device_no == device.localName) {
this.connectToDevice(device);
}
}
});
// 去重处理
this.devices = [...new Map(this.devices.map(item => [item.deviceId, item])).values()];
});
// 可选:设置一个定时器停止搜索
setTimeout(() => {
uni.stopBluetoothDevicesDiscovery({
success: () => {
console.log('停止搜索设备');
},
fail: (err) => {
console.error('停止搜索设备失败', err);
}
});
}, 10 * 1000); // 停止搜索
},
// 连接到蓝牙设备
connectToDevice(device) {
console.log('连接设备')
console.log(device)
uni.setStorageSync('uni_bluetooth_deviceId', device.localName);
this.device_no = device.localName;
this.connectedDeviceName = device.name;
this.doConnectToDeviceId(device.deviceId);
},
//
doConnectToDeviceId(deviceId) {
console.log("connect DeviceId", deviceId);
var that = this
//这里连接有时失败
uni.createBLEConnection({
deviceId: deviceId,
success: (res) => {
this.connect_status = true;
if (this.loop_blue) {
clearInterval(this.loop_blue)
}
console.log('成功连接到设备', deviceId);
that.ajax(that.config.tea_bluetooth.device.bind, {
device_no: this.device_no,
data: {
}
}).then(res => {
console.log('bind')
console.log(res)
})
this.initBlue();
this.getDeviceServices(); // 连接成功后获取服务
},
fail: (err) => {
console.error('连接设备失败', err);
this.connect_status = false;
}
});
},
// 获取设备的服务
getDeviceServices() {
uni.getBLEDeviceServices({
deviceId: this.deviceId,
success: (res) => {
console.log('获取到设备服务:', res.services);
if (res.services.length > 0) {
// 假设我们取第一个服务
this.serviceId = res.services[0].uuid;
this.getDeviceCharacteristics(); // 获取特征值
}
},
fail: (err) => {
console.error('获取设备服务失败', err);
}
});
},
// 获取服务中的特征值
getDeviceCharacteristics() {
uni.getBLEDeviceCharacteristics({
deviceId: this.deviceId,
serviceId: this.serviceId,
success: (res) => {
console.log(res);
if (res.characteristics.length > 0) {
res.characteristics.forEach(characteristic => {
if (characteristic.properties.write) {
this.characteristicIdWrite = characteristic.uuid;
} else {
this.characteristicId = characteristic.uuid;
}
});
this.startListenData(); // 开始监听数据
}
},
fail: (err) => {
console.error('获取设备特征值失败', err);
}
});
},
writeLog(data) {
let obj = JSON.parse(data)
obj.device_no = this.device_no
console.log('写日志,对象值')
console.log(obj)
this.ajax(this.config.tea_bluetooth.log, {
data: obj
}).then(res => {
console.log('writeLog')
console.log(res)
})
},
// 开始监听蓝牙设备发来的数据
startListenData() {
console.log('startListenData')
console.log("device no:" + this.device_no);
console.log("deviceId:" + this.deviceId);
console.log("serviceId:" + this.serviceId);
console.log("characteristicId:" + this.characteristicId);
uni.notifyBLECharacteristicValueChange({
state: true,
deviceId: this.deviceId,
serviceId: this.serviceId,
characteristicId: this.characteristicId,
success: (res) => {
console.log('已设置通知', res);
// 监听特征值变化
uni.onBLECharacteristicValueChange((characteristic) => {
const {
value
} = characteristic;
this.receivedData = this.ab2str(value); // 将 ArrayBuffer 转换为字符串
console.log('接收到数据:', this.receivedData);
//写入日志
this.writeLog(this.receivedData);
});
},
fail: (err) => {
console.error('监听蓝牙数据失败', err);
}
});
},
// ArrayBuffer转16进度字符串示例
ab2hex(buffer) {
const hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function(bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.reverse().join(':')
},
// ArrayBuffer 转字符串的工具方法
ab2str(buf) {
return String.fromCharCode.apply(null, new Uint8Array(buf));
},
str2ab(str) {
const buf = new ArrayBuffer(str.length);
const bufView = new Uint8Array(buf);
for (let i = 0; i < str.length; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
},
strToHex(str) {
return str.split('').map(char => {
const hex = char.charCodeAt(0).toString(16); // 获取字符的 Unicode 编码并转为 HEX
return hex.padStart(2, '0'); // 确保每个字节为两位
}).join('');
},
// 将 HEX 字符串转换为 ArrayBuffer
hexToArrayBuffer(hex) {
const len = hex.length;
const buffer = new Uint8Array(len / 2);
for (let i = 0; i < len; i += 2) {
buffer[i / 2] = parseInt(hex.substr(i, 2), 16);
}
return buffer.buffer;
},
}
};
搜索蓝牙设备
<template>
<view style="margin: 20px;">
<view class="device" v-for="(device, index) in devices">
<view @click="connectToDevice(device)"
:class="device.deviceId == device_no?'actived':'' ">
{{device.name}}
</view>
</view>
<view class="padding">
<view class="w-100">
<cl-button @click="save" type="primary">чбошод</cl-button>
</view>
</view>
</view>
</template>
<script>
import {
blueMixin
} from '@/mixin/blueMixin';
export default {
mixins: [blueMixin],
data() {
return {
};
},
onLoad() {
this.openBluetooth();
},
methods: {
save() {
this.back_data({
step: 2
})
}
}
};
</script>
<style scoped>
button {
margin: 5px;
}
.device {
margin-bottom: 20px;
padding:10px;
border: 1px solid #ccc;
border-radius: 5px;
background-color: #fff;
}
.space-between {
display: flex;
justify-content: space-between;
align-items: center;
}
.actived {
color: blue !important;
}
</style>
phpDocumentor
生成php文档
php phpDocumentor.phar run -d ./yii2/helper -d ./yii2/ActiveRecord -d ./yii/modules -d ./yii/pack -d ./yii2/widgets -t docs/api
golang 安装
https://golang.google.cn/doc/install
wget https://golang.google.cn/dl/go1.23.2.linux-amd64.tar.gz
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.23.2.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
go version
ga统计
google analytics 访问统计
自定义事件
gtag('event', 'click', {
'event_category': 'button',
'event_label': 'calc'
});
其中 event_label
如有问题请使用 https://gemini.google.com/ 提问。
追踪视频播放
gtag('event', 'video_start', {
'event_category': 'video',
'event_label': 'intro_video'
});
追踪表单提
gtag('event', 'submit', {
'event_category': 'form',
'event_label': 'contact_form'
});
加入购物车
gtag('event', 'add_to_cart', {
'event_category': 'ecommerce',
'event_label': 'product_name',
'value': 19.99,
'currency': 'USD'
});
点击支付事件
gtag('event', 'begin_checkout', {
'event_category': 'ecommerce',
'event_label': 'payment_button',
'value': 19.99,
'currency': 'USD'
});
支付成功
gtag('event', 'purchase', {
'event_category': 'ecommerce',
'event_label': 'order_12345',
'value': 59.99,
'currency': 'USD',
'transaction_id': 'T12345'
});
积分商城
汉字正则
$str = "汉字";
if (!preg_match_all("/^[\p{Han}]+$/u", $str, $match)) {
//全是汉字
}
scanCode
redmine
依赖
Ruby、 Rails
npm install pm2@latest -g
修改gem、bundle源
gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/
gem sources -l
确保只有 gems.ruby-china.com
bundle config mirror.https://rubygems.org https://gems.ruby-china.com
Ngnix转发
location / {
try_files /_not_exists_ @backend;
}
location @backend {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:3000;
}
软链
ln -s /data/redmine-5.1/public /www/wwwroot/yourdomain/
启动
pm2 start "bundle exec rails server -e production" --name redmine --cwd /data/redmine-5.1
保存
pm2 save
pm2 startup
修改状态颜色
public/javascripts/application.js
$(function(){
$("#content table.issues tbody tr td").each(function(){
let status_class = $(this).attr('class');
if(status_class == 'status'){
let html = $(this).html();
if(html == '已解决'){
$(this).html("<span style='color:green;'>已解决√</span>");
}else if(html == '新问题'){
$(this).html("<span style='color:red;'>新问题</span>");
}else if(html == '处理中'){
$(this).html("<span style='color:#00BBFF;'>处理中……</span>");
}else if(html == '拒绝'){
$(this).html("<span style='color:#BB5500;'>拒绝</span>");
}else if(html == '关闭'){
$(this).html("<span style='color:#444444;'>关闭</span>");
}else if(html == '待反馈'){
$(this).html("<span style='color:#EEEE00;'>待反馈</span>");
}
}
});
});