zksu
/
API
forked from yoone/API
1
0
Fork 0

18mg统计

This commit is contained in:
cll 2025-07-26 11:28:54 +08:00
parent 0fc9554c7f
commit edf49e7e30
7 changed files with 52 additions and 45 deletions

View File

@ -1,11 +0,0 @@
# 🎨 editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true

View File

@ -102,4 +102,12 @@ export default {
// emailPswd: '', // emailPswd: '',
// }, // },
// ], // ],
swagger: {
auth: {
name: 'authorization',
authType: 'bearer',
description: 'Bearer Auth',
addSecurityRequirements: true,
},
},
} as MidwayConfig; } as MidwayConfig;

View File

@ -1,6 +1,7 @@
import { Inject, Controller } from '@midwayjs/core'; import { Inject, Controller } from '@midwayjs/core';
import { Context } from '@midwayjs/koa'; import { Context } from '@midwayjs/koa';
@Controller('/') @Controller('/')
export class APIController { export class APIController {
@Inject() @Inject()

View File

@ -27,7 +27,6 @@ export class CustomerController {
@Get('/list') @Get('/list')
async getCustomerList(@Query() param: QueryCustomerListDTO) { async getCustomerList(@Query() param: QueryCustomerListDTO) {
try { try {
console.log(param);
const data = await this.customerService.getCustomerList(param); const data = await this.customerService.getCustomerList(param);
return successResponse(data); return successResponse(data);
} catch (error) { } catch (error) {

View File

@ -8,6 +8,6 @@ export class Customer {
@Column({ unique: true }) @Column({ unique: true })
email: string; email: string;
@Column() @Column({ default: 0})
rate: number; rate: number;
} }

View File

@ -29,32 +29,33 @@ export class CustomerService {
customerId, customerId,
rate, rate,
} = param; } = param;
const whereConds: string[] = []; const whereConds: string[] = [];
const havingConds: string[] = []; const havingConds: string[] = [];
// 邮箱搜索
if (email) { if (email) {
whereConds.push(`o.customer_email LIKE '%${email}%'`); whereConds.push(`o.customer_email LIKE '%${email}%'`);
} }
// 省份搜索
if (state) { if (state) {
whereConds.push( whereConds.push(
`JSON_UNQUOTE(JSON_EXTRACT(o.billing, '$.state')) = '${state}'` `JSON_UNQUOTE(JSON_EXTRACT(o.billing, '$.state')) = '${state}'`
); );
} }
// customerId 过滤
if (customerId) { if (customerId) {
whereConds.push(` whereConds.push(`c.id = ${Number(customerId)}`);
o.customer_email = (
SELECT email FROM customer WHERE id = ${Number(customerId)}
)
`);
}
if (rate) {
whereConds.push(`
o.customer_email = (
SELECT email FROM customer WHERE rate = ${Number(rate)}
)
`);
} }
// rate 过滤
if (rate) {
whereConds.push(`c.rate = ${Number(rate)}`);
}
// tags 过滤
if (tags) { if (tags) {
const tagList = tags const tagList = tags
.split(',') .split(',')
@ -68,25 +69,30 @@ export class CustomerService {
) )
`); `);
} }
// 首次购买时间过滤
if (first_purchase_date) { if (first_purchase_date) {
havingConds.push( havingConds.push(
`DATE_FORMAT(MIN(o.date_paid), '%Y-%m') = '${first_purchase_date}'` `DATE_FORMAT(MIN(o.date_paid), '%Y-%m') = '${first_purchase_date}'`
); );
} }
// 公用过滤
const baseQuery = ` const baseQuery = `
${whereConds.length ? `WHERE ${whereConds.join(' AND ')}` : ''} ${whereConds.length ? `WHERE ${whereConds.join(' AND ')}` : ''}
GROUP BY o.customer_email GROUP BY o.customer_email
${havingConds.length ? `HAVING ${havingConds.join(' AND ')}` : ''} ${havingConds.length ? `HAVING ${havingConds.join(' AND ')}` : ''}
`; `;
let sql = ` // 主查询
select const sql = `
o.customer_email as email, SELECT
MIN(date_created) as date_created, o.customer_email AS email,
MIN(date_paid) as first_purchase_date, MIN(o.date_created) AS date_created,
MAX(date_paid) as last_purchase_date, MIN(o.date_paid) AS first_purchase_date,
COUNT(DISTINCT o.id) as orders, MAX(o.date_paid) AS last_purchase_date,
SUM(total) as total, COUNT(DISTINCT o.id) AS orders,
SUM(o.total) AS total,
ANY_VALUE(o.shipping) AS shipping, ANY_VALUE(o.shipping) AS shipping,
ANY_VALUE(o.billing) AS billing, ANY_VALUE(o.billing) AS billing,
( (
@ -94,15 +100,12 @@ export class CustomerService {
FROM customer_tag ct FROM customer_tag ct
WHERE ct.email = o.customer_email WHERE ct.email = o.customer_email
) AS tags, ) AS tags,
( c.id AS customerId,
SELECT id FROM customer c WHERE c.email = o.customer_email c.rate AS rate,
) as customerId,
(
SELECT rate FROM customer c WHERE c.email = o.customer_email
) as rate,
yoone_stats.yoone_orders, yoone_stats.yoone_orders,
yoone_stats.yoone_total yoone_stats.yoone_total
FROM \`order\` o FROM \`order\` o
LEFT JOIN customer c ON o.customer_email = c.email
LEFT JOIN ( LEFT JOIN (
SELECT SELECT
oo.customer_email, oo.customer_email,
@ -115,25 +118,28 @@ export class CustomerService {
) yoone_stats ON yoone_stats.customer_email = o.customer_email ) yoone_stats ON yoone_stats.customer_email = o.customer_email
${baseQuery} ${baseQuery}
${sorterKey ${sorterKey
? `ORDER BY ${sorterKey} ${sorterValue === 'descend' ? 'DESC' : 'ASC' ? `ORDER BY ${sorterKey} ${sorterValue === 'descend' ? 'DESC' : 'ASC'}`
}` : 'ORDER BY orders ASC, yoone_total DESC'}
: 'ORDER BY orders ASC, yoone_total DESC' LIMIT ${pageSize} OFFSET ${(current - 1) * pageSize}
}
limit ${pageSize} offset ${(current - 1) * pageSize}
`; `;
// 统计总数
const countSql = ` const countSql = `
SELECT COUNT(*) AS total FROM ( SELECT COUNT(*) AS total FROM (
SELECT o.customer_email SELECT o.customer_email
FROM \`order\` o FROM \`order\` o
LEFT JOIN customer c ON o.customer_email = c.email
${baseQuery} ${baseQuery}
) AS sub ) AS sub
`; `;
const [items, countResult] = await Promise.all([ const [items, countResult] = await Promise.all([
this.orderModel.query(sql), this.orderModel.query(sql),
this.orderModel.query(countSql), this.orderModel.query(countSql),
]); ]);
const total = countResult[0]?.total || 0; const total = countResult[0]?.total || 0;
return { return {
items, items,
total, total,
@ -142,6 +148,7 @@ export class CustomerService {
}; };
} }
async addTag(email: string, tag: string) { async addTag(email: string, tag: string) {
const isExist = await this.customerTagModel.findOneBy({ email, tag }); const isExist = await this.customerTagModel.findOneBy({ email, tag });
if (isExist) throw new Error(`${tag}已存在`); if (isExist) throw new Error(`${tag}已存在`);

View File

@ -222,6 +222,7 @@ export class OrderService {
if(!customer) { if(!customer) {
await this.customerModel.save({ await this.customerModel.save({
email: order.customer_email, email: order.customer_email,
rate: 0,
}); });
} }
return await this.orderModel.save(entity); return await this.orderModel.save(entity);
@ -822,7 +823,8 @@ export class OrderService {
SUM(CASE WHEN os.name LIKE '%yoone%' AND os.name LIKE '%6%' THEN os.quantity ELSE 0 END) AS yoone6Quantity, SUM(CASE WHEN os.name LIKE '%yoone%' AND os.name LIKE '%6%' THEN os.quantity ELSE 0 END) AS yoone6Quantity,
SUM(CASE WHEN os.name LIKE '%yoone%' AND os.name LIKE '%9%' THEN os.quantity ELSE 0 END) AS yoone9Quantity, SUM(CASE WHEN os.name LIKE '%yoone%' AND os.name LIKE '%9%' THEN os.quantity ELSE 0 END) AS yoone9Quantity,
SUM(CASE WHEN os.name LIKE '%yoone%' AND os.name LIKE '%12%' THEN os.quantity ELSE 0 END) AS yoone12Quantity, SUM(CASE WHEN os.name LIKE '%yoone%' AND os.name LIKE '%12%' THEN os.quantity ELSE 0 END) AS yoone12Quantity,
SUM(CASE WHEN os.name LIKE '%yoone%' AND os.name LIKE '%15%' THEN os.quantity ELSE 0 END) AS yoone15Quantity SUM(CASE WHEN os.name LIKE '%yoone%' AND os.name LIKE '%15%' THEN os.quantity ELSE 0 END) AS yoone15Quantity,
SUM(CASE WHEN os.name LIKE '%yoone%' AND os.name LIKE '%18%' THEN os.quantity ELSE 0 END) AS yoone18Quantity
FROM order_sale os FROM order_sale os
INNER JOIN \`order\` o ON o.id = os.orderId INNER JOIN \`order\` o ON o.id = os.orderId
WHERE o.date_paid BETWEEN ? AND ? WHERE o.date_paid BETWEEN ? AND ?
@ -848,6 +850,7 @@ export class OrderService {
yoone9Quantity: Number(totalQuantityResult.yoone9Quantity || 0), yoone9Quantity: Number(totalQuantityResult.yoone9Quantity || 0),
yoone12Quantity: Number(totalQuantityResult.yoone12Quantity || 0), yoone12Quantity: Number(totalQuantityResult.yoone12Quantity || 0),
yoone15Quantity: Number(totalQuantityResult.yoone15Quantity || 0), yoone15Quantity: Number(totalQuantityResult.yoone15Quantity || 0),
yoone18Quantity: Number(totalQuantityResult.yoone18Quantity || 0),
current, current,
pageSize, pageSize,
}; };