280 lines
9.4 KiB
JavaScript
280 lines
9.4 KiB
JavaScript
const validator = require('../../utils/validator.js');
|
|
const Sm4Util = require('../../utils/sm4-util');
|
|
const { ObjectId } = require('mongodb');
|
|
const dayjs = require('dayjs');
|
|
|
|
exports.main = async ({ type, ...item }, db) => {
|
|
switch (type) {
|
|
case 'addAddress':
|
|
return await addAddress(item, db);
|
|
case 'updateAddress':
|
|
return await updateAddress(item, db);
|
|
case 'deleteAddress':
|
|
return await deleteAddress(item, db);
|
|
case 'getAddressList':
|
|
return await getAddressList(item, db);
|
|
case 'getDefaultAddress':
|
|
return await getDefaultAddress(item, db);
|
|
}
|
|
}
|
|
|
|
function verify(data) {
|
|
const { name, phone, address, accountId, latitude, longitude } = data || {};
|
|
|
|
const region = data && Array.isArray(data.region) ? data.region.filter(i => typeof i === 'string' && i.trim()) : [];
|
|
if (!(region.length > 1 && region.length < 4)) {
|
|
return { success: false, message: '省市区信息不正确' };
|
|
}
|
|
if (typeof address !== 'string' || address.trim() === '') {
|
|
return { success: false, message: '详细地址不能为空' };
|
|
}
|
|
if (typeof latitude !== 'number' || typeof longitude !== 'number') {
|
|
return { success: false, message: '经纬度信息不正确' };
|
|
}
|
|
if (!(latitude > 0 && longitude > 0)) {
|
|
return { success: false, message: '经纬度信息不正确' };
|
|
}
|
|
if (address.trim().length > 100) {
|
|
return { success: false, message: '详细地址最多100个字' };
|
|
}
|
|
if (typeof name !== 'string' || name.trim() === '') {
|
|
return { success: false, message: '收货人不能为空' };
|
|
}
|
|
if (name.trim().length > 20) {
|
|
return { success: false, message: '收货人最多20个字' };
|
|
}
|
|
if (typeof phone !== 'string' || phone.trim() === '') {
|
|
return { success: false, message: '手机号不能为空' };
|
|
}
|
|
if (!validator.isMobile(phone.trim())) {
|
|
return { success: false, message: '手机号格式不正确' };
|
|
}
|
|
if (typeof accountId !== 'string' || accountId.trim() === '') {
|
|
return { success: false, message: '账户ID不能为空' };
|
|
}
|
|
const docData = {
|
|
region,
|
|
address,
|
|
name: Sm4Util.encryptDataForSm3(name.trim()),
|
|
phone: Sm4Util.encryptDataForSm3(phone.trim()),
|
|
latitude,
|
|
longitude,
|
|
accountId: accountId.trim(),
|
|
}
|
|
if (typeof data.isDefault === 'boolean') {
|
|
docData.isDefault = data.isDefault
|
|
}
|
|
return { success: true, message: '验证通过', data: docData };
|
|
}
|
|
|
|
async function addAddress(item, db) {
|
|
try {
|
|
const { success, message, data } = verify(item);
|
|
if (success) {
|
|
const count = await db.collection('address').countDocuments({ accountId: data.accountId, disabled: false });
|
|
if (count >= 3) {
|
|
return { success: false, message: '每人最多可保存3个常用地址' };
|
|
}
|
|
data.createTime = Date.now();
|
|
data.updateTime = Date.now();
|
|
data.disabled = false;
|
|
if (data.isDefault) {
|
|
await db.collection('address').updateMany({ accountId: data.accountId }, { $set: { isDefault: false } });
|
|
}
|
|
const res = await db.collection('address').insertOne(data);
|
|
return { success: true, message: '新增地址成功', id: res.insertedId };
|
|
}
|
|
return { success, message };
|
|
} catch (e) {
|
|
return { success: false, message: e.message };
|
|
}
|
|
}
|
|
|
|
async function updateAddress(item, db) {
|
|
try {
|
|
if (typeof item.id !== 'string' || item.id.trim() === '') {
|
|
return { success: false, message: '地址ID不能为空' };
|
|
}
|
|
const { success, message, data } = verify(item);
|
|
if (success) {
|
|
const address = await db.collection('address').findOne({ _id: new ObjectId(item.id), accountId: data.accountId, disabled: false });
|
|
if (!address) {
|
|
return { success: false, message: '地址不存在或者账户id不匹配' };
|
|
}
|
|
const modified = checkModified(address, data);
|
|
if (modified) {
|
|
data.lockTime = dayjs().add(30, 'day').valueOf();
|
|
const lockTime = await getLockTime(data.accountId, db);
|
|
if (lockTime) {
|
|
return { success: false, message: `地址信息已被锁定, ${lockTime}前无法修改` };
|
|
}
|
|
}
|
|
data.updateTime = Date.now();
|
|
if (data.isDefault) {
|
|
await db.collection('address').updateMany({ accountId: data.accountId, _id: { $ne: new ObjectId(item.id) } }, { $set: { isDefault: false } });
|
|
}
|
|
const res = await db.collection('address').updateOne({ _id: new ObjectId(item.id) }, { $set: data });
|
|
if (res.modifiedCount > 0) {
|
|
await saveAddressHistory(address, data, 'update', db);
|
|
return { success: true, message: '更新地址成功' };
|
|
}
|
|
return { success: false, message: '更新地址失败' };
|
|
}
|
|
return { success, message };
|
|
} catch (e) {
|
|
return { success: false, message: e.message };
|
|
}
|
|
}
|
|
|
|
async function deleteAddress(item, db) {
|
|
try {
|
|
if (typeof item.id !== 'string' || item.id.trim() === '') {
|
|
return { success: false, message: '地址ID不能为空' };
|
|
}
|
|
if (typeof item.accountId !== 'string' || item.accountId.trim() === '') {
|
|
return { success: false, message: '账户ID不能为空' };
|
|
}
|
|
const lockTime = await getLockTime(item.accountId, db);
|
|
if (lockTime) {
|
|
return { success: false, message: `地址信息已被锁定, ${lockTime}前无法删除` };
|
|
}
|
|
const address = await db.collection('address').findOne({ _id: new ObjectId(item.id), accountId: item.accountId.trim(), disabled: false });
|
|
if (!address) {
|
|
return { success: false, message: '地址不存在或者账户id不匹配' };
|
|
}
|
|
const res = await db.collection('address').updateOne({ _id: new ObjectId(item.id), accountId: item.accountId.trim() }, { $set: { disabled: true, lockTime: dayjs().add(30, 'day').valueOf() } });
|
|
if (res.modifiedCount > 0) {
|
|
await saveAddressHistory(address, undefined, 'delete', db);
|
|
return { success: true, message: '删除地址成功' };
|
|
}
|
|
return { success: false, message: '删除地址失败' };
|
|
} catch (e) {
|
|
return { success: false, message: e.message };
|
|
}
|
|
}
|
|
|
|
async function getAddressList(item, db) {
|
|
try {
|
|
const { accountId } = item || {};
|
|
if (typeof accountId !== 'string' || accountId.trim() === '') {
|
|
return { success: false, message: '账户ID不能为空' };
|
|
}
|
|
const res = await db.collection('address').find({ accountId: accountId.trim(), disabled: false }).toArray();
|
|
const list = res.map(item => {
|
|
return {
|
|
id: item._id.toString(),
|
|
name: Sm4Util.decryptDataForSm3(item.name),
|
|
phone: Sm4Util.decryptDataForSm3(item.phone),
|
|
address: item.address,
|
|
isDefault: item.isDefault,
|
|
region: item.region,
|
|
latitude: item.latitude,
|
|
longitude: item.longitude
|
|
}
|
|
})
|
|
return { success: true, message: '查询地址列表成功', data: list };
|
|
} catch (e) {
|
|
return { success: false, message: e.message };
|
|
}
|
|
}
|
|
|
|
async function getDefaultAddress(item, db) {
|
|
try {
|
|
const { accountId } = item || {};
|
|
if (typeof accountId !== 'string' || accountId.trim() === '') {
|
|
return { success: false, message: '账户ID不能为空' };
|
|
}
|
|
const res = await db.collection('address').findOne({ accountId: accountId.trim(), disabled: false, isDefault: true });
|
|
if (res) {
|
|
return {
|
|
success: true, message: '查询默认地址成功', data: {
|
|
id: res._id.toString(),
|
|
name: Sm4Util.decryptDataForSm3(res.name),
|
|
phone: Sm4Util.decryptDataForSm3(res.phone),
|
|
address: res.address,
|
|
region: res.region,
|
|
latitude: res.latitude,
|
|
longitude: res.longitude
|
|
}
|
|
}
|
|
}
|
|
return { success: true, data: null, message: '未查询到默认地址' };
|
|
} catch (e) {
|
|
return { success: false, message: e.message };
|
|
}
|
|
}
|
|
|
|
function checkModified(address, data) {
|
|
try {
|
|
if (address.name !== data.name) {
|
|
return true
|
|
}
|
|
if (address.phone !== data.phone) {
|
|
return true
|
|
}
|
|
if (address.address !== data.address) {
|
|
return true
|
|
}
|
|
if (address.region.join(',') !== data.region.join(',')) {
|
|
return true
|
|
}
|
|
if (address.latitude !== data.latitude) {
|
|
return true
|
|
}
|
|
if (address.longitude !== data.longitude) {
|
|
return true
|
|
}
|
|
return false
|
|
} catch (e) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
async function getLockTime(accountId, db) {
|
|
try {
|
|
const [data] = await db.collection('address').find({ accountId, lockTime: { $gt: Date.now() } }).sort({ lockTime: -1 }).toArray();
|
|
if (data && data.lockTime) {
|
|
return dayjs(data.lockTime).format('YYYY年MM月DD日 HH:mm');
|
|
}
|
|
return ''
|
|
} catch (e) {
|
|
return ''
|
|
}
|
|
}
|
|
|
|
async function saveAddressHistory(previous, current, type, db) {
|
|
try {
|
|
const history = {
|
|
addressId: previous._id,
|
|
accountId: previous.accountId,
|
|
type,
|
|
createTime: Date.now()
|
|
}
|
|
const { name, phone, address, region, latitude, longitude, isDefault } = previous;
|
|
history.previous = {
|
|
name,
|
|
phone,
|
|
address,
|
|
region,
|
|
latitude,
|
|
longitude,
|
|
isDefault
|
|
}
|
|
if (current) {
|
|
history.current = {
|
|
name: current.name,
|
|
phone: current.phone,
|
|
address: current.address,
|
|
region: current.region,
|
|
latitude: current.latitude,
|
|
longitude: current.longitude,
|
|
isDefault: current.isDefault
|
|
}
|
|
}
|
|
await db.collection('address-change-history').insertOne(history);
|
|
return { success: true, message: '保存地址历史成功' };
|
|
} catch (e) {
|
|
return { success: false, message: e.message };
|
|
}
|
|
}
|