DateTime shouldBeGiveCoinDateTime = DateTime.Now.AddDays(-14);
return dbContext.ViewOrderForCoinCronJob.AsNoTracking().Where(x =>
x.CompletedAt <= shouldBeGiveCoinDateTime
&& x.CreatedAt >= DateTime.Now.AddYears(-1) // -> 這裡轉換mysql指令會出錯
&& x.DeletedAt == null
&& x.CoinAmount > 0
&& x.Status == (byte)ORDER_STATUS.COMPLETED
&& dbContext.PackingMain.Any(y => y.OrderId == x.Id)
&& x.IsGiveCoin != 0
&& !dbContext.CoinLog.Any(y =>
y.OrderId == x.Id
&& y.StrKey.Contains(COIN_LOG.STRING_KEY_PREFIX.ORDER_ACCUMULATION)
)
).ToList();
DateTime shouldBeGiveCoinDateTime = DateTime.Now.AddDays(-14);
DateTime createDateStartAt = DateTime.Now.AddYears(-1); // -> 先算出日期
return dbContext.ViewOrderForCoinCronJob.AsNoTracking().Where(x =>
x.CompletedAt <= shouldBeGiveCoinDateTime
&& x.CreatedAt >= createDateStartAt // -> 帶入算好的日期
&& x.DeletedAt == null
&& x.CoinAmount > 0
&& x.Status == (byte)ORDER_STATUS.COMPLETED
&& dbContext.PackingMain.Any(y => y.OrderId == x.Id)
&& x.IsGiveCoin != 0
&& !dbContext.CoinLog.Any(y =>
y.OrderId == x.Id
&& y.StrKey.Contains(COIN_LOG.STRING_KEY_PREFIX.ORDER_ACCUMULATION)
)
).ToList();
<!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>
using Ds;
using Ds.Gv;
using iText.Kernel.Geom;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NPOI.SS.Formula.Functions;
using NPOI.SS.Util;
using Su;
using System.Linq.Expressions;
namespace CallCampaign.Api
{
/// <summary>
/// 行銷活動
/// </summary>
[Route("api/call-campaign")]
[ApiController]
[SetAuthorizationFilter(Sh.AuthCode.不設限)]
public class ReserveCampaignController : Controller
{
/// <summary>
/// 取得行銷活動列表
/// </summary>
/// <param name="reserveCampaignName"></param>
/// <param name="currentPage"></param>
/// <param name="pageSize"></param>
/// <param name="orderByName"></param>
/// <param name="sort"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
[HttpGet("")]
public async Task<object> ListAsync([FromQuery] string reserveCampaignName = "", [FromQuery] int? currentPage = 1, [FromQuery] int? pageSize = 20, [FromQuery] string orderByName = "OrderNo", [FromQuery] string sort = "asc")
{
if (pageSize > 500)
{
pageSize = 500;
}
if (!(sort == "asc" || sort == "desc"))
{
throw new CustomException(System.Net.HttpStatusCode.BadRequest, "sort只能是asc或desc");
}
var temp = new V_ReserveCampaign().GetType().GetProperty(orderByName);
if (temp == null)
{
throw new CustomException(System.Net.HttpStatusCode.BadRequest, "不存在欄位");
}
Expression<Func<V_ReserveCampaign, bool>> q = p => p.Is_Deleted == "N"
&& (string.IsNullOrEmpty(reserveCampaignName) || (p.ReserveCampaignName != null && p.ReserveCampaignName.Contains(reserveCampaignName)))
;
if (orderByName.ToLower().Trim() != "id")
{
orderByName += " " + sort + ", id desc";
}
else
{
orderByName += " " + sort;
}
var ct = NewContext.GvContext;
var list = await ct.GetPageListAsync(q, columns: "Id, ReserveCampaignName, OrderNo, StartAt, EndAt, ModifierName, ModifyDate, CreatorName, CreateDate", page: currentPage ?? 1, pageSize: pageSize ?? 20, orderByName);
//var list = await ct.GetPageListAsync(q, page: currentPage ?? 1, pageSize: pageSize ?? 20, orderByName + " " + sort);
return list;
}
/// <summary>
/// 取得行銷活動
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
[HttpGet("get")]
public async Task<dynamic> GetAsync([FromQuery] int Id)
{
var res = await Ds.NewContext.GvContext.ReserveCampaigns.Where(r => r.Id == Id)
.FirstOrDefaultAsync();
if (res == null)
{
throw new CustomException(System.Net.HttpStatusCode.BadRequest, "查無資料 " + Id.ToString());
}
return res;
}
/// <summary>
/// 建立行銷活動
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
/// <exception cref="CustomException"></exception>
[HttpPost("")]
public async Task<object> CreateAsync(Dtos.CreateReserveCampaign dto)
{
var ct = NewContext.GvContext;
var res = await Models.ReserveCampaignHelper.CreateReserveCampaignAsync(ct, dto);
return res;
}
/// <summary>
/// 編輯行銷活動
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
/// <exception cref="CustomException"></exception>
[HttpPatch("")]
public async Task<object> UpdateAsync(Dtos.UpdateReserveCampaign dto)
{
var ct = NewContext.GvContext;
var res = await Models.ReserveCampaignHelper.UpdateReserveCampaignAsync(ct, dto);
return res;
}
/// <summary>
/// 刪除行銷活動
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
/// <exception cref="CustomException"></exception>
[HttpDelete("")]
public async Task<object> DeleteAsync([FromQuery] int id)
{
var res = await Ds.NewContext.GvContext.MarkDeleteAsync<Ds.Gv.ReserveCampaign>(id, Sh.ModifyInfo);
return res;
}
}
}
/// <summary>
/// 取得列表
/// </summary>
/// <param name="name"></param>
/// <param name="currentPage"></param>
/// <param name="pageSize"></param>
/// <param name="orderByName"></param>
/// <param name="sort"></param>
/// <returns></returns>
[HttpGet("")]
public object List([FromQuery] string name = "", [FromQuery] int? currentPage = 1, [FromQuery] int? pageSize = 20, [FromQuery] string orderByName = "OrderNo", [FromQuery] string sort = "asc")
{
return "";
}
/// <summary>
/// 取得明細資料
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
[HttpGet("get")]
public object Get([FromQuery] int id)
{
return "";
}
/// <summary>
/// 建立
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
/// <exception cref="CustomException"></exception>
[HttpPost("")]
public object Create(Dtos.PhysicalCheckUpType dto)
{
return "";
}
/// <summary>
/// 編輯
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
/// <exception cref="CustomException"></exception>
[HttpPatch("")]
public object Update(Dtos.PhysicalCheckUpType dto)
{
return "";
}
/// <summary>
/// 刪除
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
/// <exception cref="CustomException"></exception>
[HttpDelete("")]
public object Delete([FromQuery] int id)
{
return 1;
}
var root = "C://wdqd/qwewq";
var addPath = @"//\\/fwef/qwf";
var addPath2 = @"5fwfef/qwf";
var addPath3 = @"//fwef/qwf";
var addPath4 = @"\\\fwef/qwf";
var addPath5 = @"\\\\\/fwef/qwf";
var result = root.AddPath(addPath, addPath2, addPath3, addPath4, addPath5);
Console.WriteLine(result);
public static class Helper
{
public static string AddPath(this string value, params string[] addPaths)
{
if (string.IsNullOrEmpty(value))
{
throw new Exception("起始目錄不可以為空字串");
}
if (value.Contains("..") || addPaths.Any(x => x.Contains("..")))
{
throw new Exception($"value: {value}, addPaths: {addPaths.Where(x => x.Contains("..")).ToOneString()} 檔名與路徑不可包含 ..");
}
var paths = addPaths.Select(x => x.Substring(x.FindLastContinuousCharPosition('/', '\\') + 1).SafeFilename()).ToList();
if (paths.Any(x => System.IO.Path.IsPathRooted(x)))
{
throw new Exception("不可併入完整路徑 ..");
}
paths.Insert(0, value.SafeFilename());
return System.IO.Path.Combine(paths.ToArray());
}
public static string ToOneString<T>(this IEnumerable<T> list, string separator = ",")
{
var strList = list.Select(x => x.ToString());
return string.Join(separator, strList);
}
public static int FindLastContinuousCharPosition(this string input, params char[] targets)
{
int lastPosition = -1;
for (int i = 0; i < input.Length; i++)
{
if (targets.Contains(input[i]))
{
lastPosition = i;
}
else
{
break;
}
}
return lastPosition;
}
public static string SafeFilename(this string value)
{
return GetValidFilename(value);
}
public static string GetValidFilename(string value)
{
string ValidFilenameCharacters = @"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\-_$.@:/# ";
if (value.Contains(".."))
{
throw new Exception("路徑中不可包含 .. ");
}
string newUrl = "";
for (int i = 0; i < value.Length; i++)
{
var c = value.Substring(i, 1);
int k = ValidFilenameCharacters.IndexOf(c);
if (k < 0)
{
throw new Exception($"檔名 '{value}' 中有非法的字元 '" + c + "'。");
}
newUrl += ValidFilenameCharacters.Substring(k, 1);
}
return newUrl;
}
}
.andSelf()
.live()
.die()
.error()
.load()
.unload()
.size()
.toggle()
/// <summary>
/// 會把物件 Parameter 的各 Property 帶入 SQL 中.
/// </summary>
/// <param name="dbct"></param>
/// <param name="sql"></param>
/// <param name="parameters"></param>
/// <returns></returns>
public static async Task<int> ExecuteParameterSqlAsync(this DbContext dbct, string sql, object parameters)
{
return await dbct.Database.ExecuteSqlRawAsync(sql, parameters.ToSqlParamsArray());
}
public async Task<object> EfTest()
{
var dbct = Ds.NewContext.GvContext;
var insertSql = @"Insert into ProfileEvent(JobId,[Name],GvShoplineId,LiShoplineId,Phone,Email,LineId,GaClientId)
Values(@JobId, @Name, null , null , null , @Email, @GaClientId , @GaClientId )";
//執行 SQL 的原生寫法
await dbct.Database.ExecuteSqlRawAsync(insertSql, new object[]
{
new SqlParameter("@JobId", 10),
new SqlParameter("@Email", "XX'TT"),
new SqlParameter("@Name", "AA'BB"),
new SqlParameter("@GaClientId", "GaClientId"),
});
//執行 SQL 的擴充寫法
await dbct.ExecuteParameterSqlAsync(insertSql, new
{
JobId = 10,
Email = "XX'TT",
Name = "AA'BB",
GaClientId = "GaClientId"
});
//關於查詢
string name = "%'B%";
//原生寫法
var res1 = await dbct.ProfileEvents.FromSqlRaw("Select top 100 * from ProfileEvent where Name like @name",
new object[]
{
new SqlParameter("@name", "%'B%")
})
.ToListAsync();
//擴充, object to SqlParameter array
var res2 = await dbct.ProfileEvents.FromSqlRaw("Select top 100 * from ProfileEvent where Name like @name",
new { name }.ToSqlParamsArray())
.ToListAsync();
var res3 = await dbct.ProfileEvents.FromSql($"Select top 100 * from ProfileEvent where Name like {name}")
.ToListAsync();
var res4 = await dbct.ProfileEvents.FromSqlInterpolated($"Select top 100 * from ProfileEvent where Name like {name}")
.ToListAsync();
return new { res1, res2, res3, res4 };
}