diff --git a/server/src/controllers/adminOrder.ts b/server/src/controllers/adminOrder.ts index 042ff434..aeefddc9 100644 --- a/server/src/controllers/adminOrder.ts +++ b/server/src/controllers/adminOrder.ts @@ -1,6 +1,7 @@ import { Request, Response } from 'express' import pool from '../utils/db' import { RowDataPacket, ResultSetHeader } from 'mysql2' +import { syncProductMinPrice } from '../utils/syncPrice' function toMySQLDatetime(val: string | Date): string { const d = typeof val === 'string' ? new Date(val) : val @@ -443,6 +444,8 @@ export async function adminReturnOrder(req: Request, res: Response): Promise { const updated = countRows[0].cnt await conn.commit() + + // 同步所有商品最低价 + const [allProducts] = await pool.execute('SELECT DISTINCT product_id FROM spec_data WHERE fineness != ?', [PLATINUM_FINENESS]) + for (const p of allProducts) { await syncProductMinPrice(p.product_id) } + res.json({ code: 0, message: `金价已更新为 ${newPrice},已重算 ${updated} 条规格数据` }) } catch (err) { await conn.rollback() @@ -138,6 +144,11 @@ export async function setPlatinumPrice(req: Request, res: Response): Promise('SELECT DISTINCT product_id FROM spec_data WHERE fineness = ?', [PLATINUM_FINENESS]) + for (const p of allProducts) { await syncProductMinPrice(p.product_id) } + res.json({ code: 0, message: `铂金价格已更新为 ${newPrice},已重算 ${updated} 条铂金规格数据` }) } catch (err) { await conn.rollback() diff --git a/server/src/controllers/specDataIO.ts b/server/src/controllers/specDataIO.ts index f3542b17..46391d58 100644 --- a/server/src/controllers/specDataIO.ts +++ b/server/src/controllers/specDataIO.ts @@ -1,6 +1,7 @@ import { Request, Response } from 'express' import pool from '../utils/db' import { RowDataPacket, ResultSetHeader } from 'mysql2' +import { syncProductMinPrice } from '../utils/syncPrice' // 所有字段(用于数据库读写) const ALL_DB_HEADERS = [ @@ -177,6 +178,7 @@ export async function adminCreateSpecData(req: Request, res: Response): Promise< d.sideStoneCount||0, d.sideStoneWeight||0, d.sideStoneUnitPrice||0, d.sideStoneAmount||0, d.accessoryAmount||0, d.processingFee||0, d.settingFee||0, d.totalLaborCost||0, d.totalPrice||0] ) + await syncProductMinPrice(Number(id)) res.json({ code: 0, data: { id: result.insertId } }) } catch (err) { console.error('adminCreateSpecData error:', err) @@ -187,8 +189,9 @@ export async function adminCreateSpecData(req: Request, res: Response): Promise< // DELETE /api/admin/products/:productId/spec-data/:specId export async function adminDeleteSpecData(req: Request, res: Response): Promise { try { - const { specId } = req.params + const { productId, specId } = req.params await pool.execute('DELETE FROM spec_data WHERE id = ?', [specId]) + await syncProductMinPrice(Number(productId)) res.json({ code: 0, message: '删除成功' }) } catch (err) { console.error('adminDeleteSpecData error:', err) @@ -199,7 +202,7 @@ export async function adminDeleteSpecData(req: Request, res: Response): Promise< // PUT /api/admin/products/:productId/spec-data/:specId - 编辑规格数据 export async function adminUpdateSpecData(req: Request, res: Response): Promise { try { - const { specId } = req.params + const { productId, specId } = req.params const d = req.body if (d.barcode) { const [dup] = await pool.execute('SELECT id FROM spec_data WHERE barcode = ? AND id != ?', [d.barcode, specId]) @@ -220,6 +223,7 @@ export async function adminUpdateSpecData(req: Request, res: Response): Promise< d.accessoryAmount||0, d.processingFee||0, d.settingFee||0, d.totalLaborCost||0, d.totalPrice||0, specId] ) + await syncProductMinPrice(Number(productId)) res.json({ code: 0, message: '更新成功' }) } catch (err) { console.error('adminUpdateSpecData error:', err) @@ -440,6 +444,13 @@ export async function importSpecData(req: Request, res: Response): Promise } await conn.commit() + + // 同步所有涉及商品的最低价 + const affectedProductIds = [...new Set(Object.values(styleNoToProductId))] + for (const pid of affectedProductIds) { + await syncProductMinPrice(pid) + } + res.json({ code: 0, data: { imported, skipped, warnings: errors.length > 0 ? errors : undefined }, diff --git a/server/src/utils/syncPrice.ts b/server/src/utils/syncPrice.ts new file mode 100644 index 00000000..718e8929 --- /dev/null +++ b/server/src/utils/syncPrice.ts @@ -0,0 +1,17 @@ +import pool from './db' +import { RowDataPacket } from 'mysql2' + +/** + * 同步商品价格为其规格数据中的最低价。 + * 如果没有规格数据,价格设为 0。 + * 支持传入 connection(事务中使用)或使用默认 pool。 + */ +export async function syncProductMinPrice(productId: number, conn?: any): Promise { + const db = conn || pool + const [rows] = await db.execute( + 'SELECT MIN(total_price) as min_price FROM spec_data WHERE product_id = ?', + [productId] + ) + const minPrice = rows[0]?.min_price ?? 0 + await db.execute('UPDATE products SET base_price = ? WHERE id = ?', [minPrice, productId]) +}