CentralBackend/services/affiliate/AffiliateService.js

153 lines
4.4 KiB
JavaScript

const db = require('../../database/database');
const { logger } = require('../../middleware/logger');
exports.list = async () => {
const [rows] = await db.query('SELECT * FROM affiliates ORDER BY created_at DESC');
return rows.map(r => ({
id: r.id,
name: r.name,
description: r.description,
url: r.url,
object_storage_id: r.object_storage_id,
original_filename: r.original_filename,
category: r.category,
is_active: !!r.is_active,
commission_rate: r.commission_rate,
created_at: r.created_at,
updated_at: r.updated_at
}));
};
exports.get = async (id) => {
const [rows] = await db.query('SELECT * FROM affiliates WHERE id = ?', [id]);
if (!rows[0]) return null;
const r = rows[0];
return {
id: r.id,
name: r.name,
description: r.description,
url: r.url,
object_storage_id: r.object_storage_id,
original_filename: r.original_filename,
category: r.category,
is_active: !!r.is_active,
commission_rate: r.commission_rate,
created_at: r.created_at,
updated_at: r.updated_at
};
};
exports.create = async ({ name, description, url, category, is_active, commission_rate, object_storage_id, original_filename }) => {
// Validation
if (!name || name.trim() === '') {
const e = new Error('Affiliate name is required');
e.code = 'VALIDATION_ERROR';
throw e;
}
if (!url || url.trim() === '') {
const e = new Error('Affiliate URL is required');
e.code = 'VALIDATION_ERROR';
throw e;
}
if (!category || category.trim() === '') {
const e = new Error('Affiliate category is required');
e.code = 'VALIDATION_ERROR';
throw e;
}
// Validate URL format
try {
new URL(url);
} catch (err) {
const e = new Error('Invalid URL format');
e.code = 'VALIDATION_ERROR';
throw e;
}
const [result] = await db.query(
`INSERT INTO affiliates (name, description, url, category, is_active, commission_rate, object_storage_id, original_filename)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
[
name.trim(),
description ? description.trim() : null,
url.trim(),
category.trim(),
is_active !== undefined ? is_active : true,
commission_rate || null,
object_storage_id || null,
original_filename || null
]
);
logger.info('[AffiliateService.create] created', { id: result.insertId });
return await exports.get(result.insertId);
};
exports.update = async (id, { name, description, url, category, is_active, commission_rate, object_storage_id, original_filename }) => {
const updates = [];
const values = [];
if (name !== undefined) {
updates.push('name = ?');
values.push(name.trim());
}
if (description !== undefined) {
updates.push('description = ?');
values.push(description ? description.trim() : null);
}
if (url !== undefined) {
// Validate URL format
try {
new URL(url);
} catch (err) {
const e = new Error('Invalid URL format');
e.code = 'VALIDATION_ERROR';
throw e;
}
updates.push('url = ?');
values.push(url.trim());
}
if (category !== undefined) {
updates.push('category = ?');
values.push(category.trim());
}
if (is_active !== undefined) {
updates.push('is_active = ?');
values.push(is_active);
}
if (commission_rate !== undefined) {
updates.push('commission_rate = ?');
values.push(commission_rate);
}
if (object_storage_id !== undefined) {
updates.push('object_storage_id = ?');
values.push(object_storage_id);
}
if (original_filename !== undefined) {
updates.push('original_filename = ?');
values.push(original_filename);
}
if (updates.length === 0) {
logger.warn('[AffiliateService.update] no fields to update', { id });
return await exports.get(id);
}
updates.push('updated_at = NOW()');
values.push(id);
await db.query(`UPDATE affiliates SET ${updates.join(', ')} WHERE id = ?`, values);
logger.info('[AffiliateService.update] updated', { id });
return await exports.get(id);
};
exports.updateStatus = async (id, is_active) => {
await db.query('UPDATE affiliates SET is_active = ?, updated_at = NOW() WHERE id = ?', [is_active, id]);
logger.info('[AffiliateService.updateStatus] updated', { id, is_active });
return await exports.get(id);
};
exports.delete = async (id) => {
await db.query('DELETE FROM affiliates WHERE id = ?', [id]);
logger.info('[AffiliateService.delete] deleted', { id });
};