:
使用try-catch區塊進行錯誤處理。try {
} catch (err) {
// 處理錯誤
res.status(500).json({ errors: err })
throw err;
}
1.try
區塊:2.catch
區塊:transactionHandler
函數處理一個異步的數據庫交易try {
await transactionHandler(this.knexSql, async (trx: Knex.Transaction) => {
})
}
async (trx: Knex.Transaction) => { }
:傳遞給transactionHandler
的第二個參數,是一個非同步回調函數,該函數接受一個交易對象trx
作為參數。:
try {
await transactionHandler(this.knexSql, async (trx: Knex.Transaction) => {
//對裡面每一個項目product做寫入database動作
contents.map(product) => this.productModel.
}
)}
:model ––> products.ts
/production的型別和定義-新增(對伺服器來說是做預售的動作)
export interface IProductModel extends IBase<Product> {
preSell(product: Pick<Product, "id" | "amount" | "price">, trx?: Knex.Transaction)
: Promise<Boolean>;
}
IProductModel:
IBase<Product>
:preSell
方法,用於處理預售檢查:參數 trx
(可選):
:
public preSell = async
(product: Pick<Product, "id" | "amount" | "price">, trx?: Knex.Transaction)
=> {
//從資料庫裡面找資料
let queryBuilder = this.knexSql(this.tableName)
.where({ id: product.id })
.where(this.schema.amount, '>=', product.amount)
.update(
this.schema.preOrder,
this.knexSql.raw(`?? + ?`, [this.schema.preOrder, product.amount])
);
if (trx) queryBuilder = queryBuilder.transacting(trx);
const result = await queryBuilder;
//成功update就會是大於一的數字
return !!result;
}
let queryBuilder = this.knexSql(this.tableName)
.where({ id: product.id })
.where(this.schema.amount, '>=', product.amount)
.update(
this.schema.preOrder,
this.knexSql.raw(`?? + ?`, [this.schema.preOrder, product.amount])
);
raw
是 Knex.js 提供的一個方法,用於執行原始 SQL 查詢或建構複雜的 SQL 表達式。if (trx) queryBuilder = queryBuilder.transacting(trx);
const result = await queryBuilder;
return !!result;
:controller ––> orderController.ts
const results = await Promise.all(
//對裡面每一個項目product做寫入database動作
contents.map(
async (product) =>
await this.productModel.preSell(
{
id: product.productId,
...pick(product, ['price', 'amount'])
},
trx
)));
Promise.all
:const results = await Promise.all()
async (product) => await this.productModel.preSell()
preSell
方法:await this.productModel.preSell(
{
id: product.productId,
...pick(product, ['price', 'amount'])
},
trx
)
pick
被用來選擇 product
物件中的 price
和 amount
屬性,然後將這些屬性與 id
一起傳遞給 preSell
。results
陣列中的任意一個元素是否為 false:
if (results.some(result => !result))
throw new Error('Cannot buy, because out of stuff.');
contents
陣列中所有產品的總價格:
const totalPrice = contents.reduce()
(acc, product) => acc + product.price * product.amount
0
:, 0
//自做id
const uid = genUID();
//利用orderModel開立訂單
await this.orderModel.create({
id: uid,
total: totalPrice,
createdAt: new Date(),
updatedAt: new Date(),
paymentProvider,
paymentWay,
status: OrderStatus.WAITING,
contents,
},
trx
)
});
uid
:const uid = genUID();
orderData
:const orderData = {
id: uid,
total: totalPrice,
createdAt: new Date(),
updatedAt: new Date(),
paymentProvider,
paymentWay,
status: OrderStatus.WAITING,
contents,
};
export const genUID = () => {
//讓偶數位變成英文:1a3d5e7h9v
const alpha = "abcdefghij";
// timestamp 13+7=20位長度的字串
const timestampStr = new Date().getTime().toString();
const code = timestampStr
.split("") //["1","2","3"...]
.map((v, idx) => (idx % 2 ? v : alpha[Number(v)]))
.join("") //已有13位數
//安裝genUID來產生剩下7位數
const id = uuid().split("-")[0];
return `${code}${id.substring(0, id.length - 1)}`;
}
const alpha = 'abcdefghij';// 每個數字對應的字母
const timestampStr = new Date().getTime().toString();
const code = timestampStr.split('')
.map((v, idx) => idx % 2 ? v : alpha[Number(v)])
.join('');
npm install uid
import { v4 as uuid } from "uuid";
const id = uuid().split('-')[0];
return `${code}${id.substring(0, id.length - 1)}`;
uuid()
方法生成一個新的 UUID。id
字串的開頭 (索引0) 截取到倒數第二個字符的位置 (id.length - 1)。code
的值和 id
字串從頭到倒數第二個字符的組成。例如,"ABC1234"。import { genUID} from "@/utils";
await this.orderModel.create(orderData, trx);
res.json({ status: 'success' });
// check if a string is json
if (typeof value === "object") return JSON.stringify(value);
typeof value === "object"
: 檢查 value
是否是一個物件。typeof
運算符可以返回一個表示變數資料類型的字符串,例如 "number"、"string"、"undefined" 和 "object"。return JSON.stringify(value);
: 如果 value
確實是一個物件,則使用 JSON.stringify()
方法將它轉換為一個 JSON 字符串並返回。let sqlBuilder = this.knexSql(this.tableName).select(this.schema).where({ id });
.where({ id })
: 這是條件子句,用於篩選資料。此處使用了一個簡潔的物件描述法查詢id
欄位。