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 }; } }