<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BLE Printer Test</title>
<script src="https://cdn.jsdelivr.net/npm/iconv-lite-umd@0.6.10/lib/iconv-lite-umd.js"></script>
</head>
<body>
<h1>BLE Printer Test 123</h1>
<button id="printTestButton">Test Print</button>
<button id="printAgain">Print Again</button>
<pre id="log"></pre>
<script>
// Function to log messages on the page
function logMessage(message) {
const logElement = document.getElementById('log');
logElement.textContent += message + '\n';
}
var device;
var server;
var service;
var characteristic;
var name = 'T58_6752'; // 藍芽設備的名稱
var uuid = 0x1800; //service UUID (用 BLE Scanner 找到的)
var characteristicUuid = 0x2A00; // characteristic UUID (用 BLE Scanner 找到的)
// Function to connect to BLE printer and send test data
async function connectAndTestPrint() {
try {
logMessage("Requesting Bluetooth device...");
// Request the BLE device
device = await navigator.bluetooth.requestDevice({
//acceptAllDevices: true,
filters: [
{ name: name }
],
optionalServices: [uuid] // Replace with the correct service UUID
});
logMessage(`Device selected: ${device.name}`);
logMessage(`Device uuid: ${device.id}`);
await printAgain();
} catch (error) {
logMessage(`Error: ${error.message}`);
}
}
// 转码方法
function stringToGbk(str) {
const ranges = [
[0xA1, 0xA9, 0xA1, 0xFE],
[0xB0, 0xF7, 0xA1, 0xFE],
[0x81, 0xA0, 0x40, 0xFE],
[0xAA, 0xFE, 0x40, 0xA0],
[0xA8, 0xA9, 0x40, 0xA0],
[0xAA, 0xAF, 0xA1, 0xFE],
[0xF8, 0xFE, 0xA1, 0xFE],
[0xA1, 0xA7, 0x40, 0xA0],
]
const codes = new Uint16Array(23940)
let i = 0
for (const [b1Begin, b1End, b2Begin, b2End] of ranges) {
for (let b2 = b2Begin; b2 <= b2End; b2++) {
if (b2 !== 0x7F) {
for (let b1 = b1Begin; b1 <= b1End; b1++) {
codes[i++] = b2 << 8 | b1
}
}
}
}
const cstr = new TextDecoder('gbk').decode(codes)
// 编码表
const table = new Uint16Array(65536)
for (let i = 0; i < cstr.length; i++) {
table[cstr.charCodeAt(i)] = codes[i]
}
const buf = new Uint8Array(str.length * 2)
let n = 0
for (let i = 0; i < str.length; i++) {
const code = str.charCodeAt(i)
if (code < 0x80) {
buf[n++] = code
} else {
const gbk = table[code]
buf[n++] = gbk & 0xFF
buf[n++] = gbk >> 8
}
}
u8buf = buf.subarray(0, n)
// console.log(u8buf);
return u8buf
}
async function printAgain() {
// Connect to the GATT server
server = await device.gatt.connect();
logMessage("Connected to GATT server.");
// Get the printer service
service = await server.getPrimaryService(uuid); // Replace with your printer's service UUID
logMessage("Printer service retrieved.");
// Get the characteristic for writing data
characteristic = await service.getCharacteristic(characteristicUuid); // Replace with the correct characteristic UUID
logMessage("Printer characteristic retrieved.");
// Prepare test print data
const encoder = new TextEncoder();
const testData = encoder.encode("TEST PRINT: Hello from Web Bluetooth!\n");
const finalData = encoder.encode("--\n--\n \n \n");
const setFontSize = new Uint8Array([0x1D, 0x21, 0x11]); // GS ! n
const setFontSize2 = new Uint8Array([0x1D, 0x21, 0x22]); // GS ! n
const setFontSize3 = new Uint8Array([0x1D, 0x21, 0x33]); // GS ! n
// Write test data to the printer
logMessage("Sending test data to printer...");
await characteristic.writeValue(new Uint8Array([0x1D, 0x21, 0x00]));
await characteristic.writeValue(encoder.encode("1x1!\n"));
await characteristic.writeValue(setFontSize);
await characteristic.writeValue(encoder.encode("2x2!\n"));
await characteristic.writeValue(setFontSize2);
await characteristic.writeValue(encoder.encode("3x3!\n"));
await characteristic.writeValue(setFontSize3);
await characteristic.writeValue(encoder.encode("4x4!\n"));
const initPrinter = new Uint8Array([0x1B, 0x40]); // ESC @
await characteristic.writeValue(initPrinter);
// 3. 設置字符集為 GBK
const setGBK = new Uint8Array([0x1B, 0x74, 0x11]); // ESC t 0x11 (GBK)
await characteristic.writeValue(setGBK);
const text = "繁體中文測試\n \n";
const encodedText = stringToGbk(text);
await characteristic.writeValue(encodedText);
logMessage("Test data sent successfully!");
// QrCode 列印
const qrData = "https://example.com"; // Your QR code data
const qrDataLength = qrData.length + 3;
const pL = qrDataLength & 0xFF; // Low byte
const pH = (qrDataLength >> 8) & 0xFF; // High byte
const commands = [
0x1B, 0x40, // Initialize printer
0x1D, 0x28, 0x6B, pL, pH, 0x31, 0x50, 0x30, ...new TextEncoder().encode(qrData), // Store data
0x1D, 0x28, 0x6B, 0x03, 0x00, 0x31, 0x51, 0x30 // Print QR code
];
const buffer = new Uint8Array(commands);
await characteristic.writeValue(buffer);
logMessage("QrCode sent successfully!");
await characteristic.writeValue(finalData);
logMessage("finalData sent successfully!");
// Disconnect the GATT server
server.disconnect();
logMessage("Disconnected from printer.");
}
// Bind the function to the button
document.getElementById('printTestButton').addEventListener('click', connectAndTestPrint);
document.getElementById('printAgain').addEventListener('click', printAgain);
</script>
</body>
</html>
var slidesPerGroup = 5;
if (S3JS.isMobile()) {
slidesPerGroup = 1; // 很奇怪, Mobile 版時, 若是設定 slidesPerGroup = 5 時, 剛進入時會看到最後一組商品.
}
//beauty-coin-exchange-loading
var swiperPreview = new Swiper('.beauty-coin-exchange-swiper', {
slidesPerView: 5,
slidesPerColumn: 1,
slidesPerGroup: slidesPerGroup,
spaceBetween: 0,
loop: true,
breakpoints: {
768: {
slidesPerView: 4.3,
spaceBetween: 10,
}
},
nextButton: '.beauty-coin-next',
prevButton: '.beauty-coin-prev',
});
<asp:Button ID="BtnSubmit" runat="server" Text="修改" OnClick="BtnSubmit_Click" OnClientClick="return formSubmit('true');" />
<script type="text/javascript">
function formSubmit(val) {
if (val== "true")
{
form1.submit();
} else {
return false;
}
}
</script>
input[type="radio"]:not(old){
width:28px;
margin:0;
padding:0;
@include opacity(0);
}
input[type="radio"]:not(old) + label{
display: inline-block;
margin-left: -28px;
padding-left: 18px;
background: url("//www.shopunt.com/images/eng/btn/radio.png") no-repeat;
width:auto;
line-height: 12px;
}
input[type="radio"]:not(old):checked + label{
background: url("//www.shopunt.com/images/eng/btn/radio-r.png") no-repeat;
width:auto;
}
.r-btn:not(old){
input[type="radio"]{
width:28px;
margin:0;
padding:0;
@include opacity(0);
}
input[type="radio"] + label{
display: inline-block;
margin-left: -28px;
padding-left: 18px;
background: url("//www.shopunt.com/images/eng/btn/radio.png") no-repeat;
width:auto;
line-height: 12px;
}
input[type="radio"]:checked + label{
background: url("//www.shopunt.com/images/eng/btn/radio-r.png") no-repeat;
width:auto;
}
}
input[type="radio"]:not(:checked), input[type="radio"]:checked {
position: absolute;
left: -9999px;
}
input[type="radio"]:not(checked) + label{
display: inline-block;
margin-left: 4px;
padding-left: 18px;
background: url("//www.shopunt.com/images/eng/btn/radio.png") no-repeat;
width:auto;
line-height: 12px;
}
input[type="radio"]:checked + label{
background: url("//www.shopunt.com/images/eng/btn/radio-r.png") no-repeat;
width:auto;
}
<body> <!--BodyTop--> {DebugMessage} <a id="anchorGoTop" href="#gotop" class="gotop" style="display: none;"><span><em></em></span></a>
'購物button區塊置於 <body> 正下方 Me.strBodyTop = Me.otContent.SubTemplate("BuyButtonArea").Result就可以了
//先檢查是不是已經登入
FB.getLoginStatus(function (response) {
if (response.status === "connected") {
// 已登入FB
}
else {
// 未登入FB
// 盡量不要在此呼叫 FB.login , 因為彈跳視窗會被擋下來
}
});
//呼叫登入 scope:publish_stream 是要讓user同意發文到FB的權限
FB.login(function (response) {
if (response.authResponse) {
// 已登入,可取得 AccessToken
} else {
// 未登入
}
}, { scope: 'publish_stream' });
// 檢查 user 有無同意發文到FB的權限 (publish_stream)
FB.api({ method: 'users.hasAppPermission', ext_perm: 'publish_stream' }, function (resp) {
if (resp === "1") {
//有同意
} else {
//不同意
}
});
// 分享連結到登入者的FB牆
// msg 是發文的內容
// link, picture, caption, description 是一組的
var args = {
message: msg,
link: product.Link,
picture: product.Picture,
caption: product.Name,
description: "超高口碑BB霜/CC霜、頂級精華液哪款半價 由你決定!"
};
FB.api('/me/feed', 'post', args, function (response) {
if (response.id) {
// 成功會回傳訊息id
}
else {
// 分享失敗
}
});
FB.ui({
method: 'feed',
name: '快去搶!超過9成的使用者滿意推薦的《玻尿酸精華》',
link: 'http://www.shopunt.com/tch/event/2014-aqua-deluge/default.aspx',
picture: 'http://www.shopunt.com/Upload/tch/unt/14mar/fb154x154.jpg',
caption: 'UNT 頂級玻尿酸保濕精華液(奢華)',
description: '熱銷破百萬 真實口碑見證的水感奇肌 逆時補水科技 快速滲透 為肌膚注入高水位……'
},
function (response) {
if (response && response.post_id) {
// handle success
}
else {
alert("facebook分享失敗!");
}
}
);
// 例如
Common.popUp({
Title: "....",
Message: "......."
.....
onOKClick: function() {
// handle onclick ok button event
},
onCancelClick: function() {
// handle onclick cancel button event
}
});
Windows 2008 的 SMTP 寄信時若遇到 "Helo command rejected: need fully-qualified hostname" ,可做以下的修改。
The fix is easy: