SFT/mock-server/routes/customer.js

162 lines
6.4 KiB
JavaScript

import express from 'express'
import { individualCustomers, enterpriseCustomers, enterpriseRelatedPersons } from '../db/seedCustomer.js'
import { nextId } from '../utils/id.js'
import { paginate } from '../utils/pagination.js'
import { sendOk, sendFail } from '../utils/response.js'
import { requireAuth } from '../middleware/requireAuth.js'
const router = express.Router()
router.use(requireAuth)
function toIndividualListVo(c) {
return {
id: c.id,
organizationId: c.organizationId,
customerName: c.customerName,
certificateType: c.certificateType,
certificateNumber: c.certificateNumber,
mobilePhone: c.mobilePhone,
ocrStatus: c.ocrStatus,
customerCode: c.customerCode
}
}
// ---------------- 个人客户 ----------------
router.post('/customer-info/personal/list', (req, res) => {
const { organizationIdEq, customerCodeEq, customerNameLike, certificateNumberEq, page, pageSize } = req.body || {}
let list = individualCustomers
if (organizationIdEq) list = list.filter((c) => c.organizationId === organizationIdEq)
if (customerCodeEq) list = list.filter((c) => c.customerCode === customerCodeEq)
if (customerNameLike) list = list.filter((c) => c.customerName.includes(customerNameLike))
if (certificateNumberEq) list = list.filter((c) => c.certificateNumber === certificateNumberEq)
const result = paginate(list, page, pageSize)
sendOk(res, { ...result, records: result.records.map(toIndividualListVo) })
})
router.post('/customer-info/personal/detail', (req, res) => {
const { id, customerCode } = req.body || {}
const customer = individualCustomers.find((c) => (id ? c.id === id : c.customerCode === customerCode))
if (!customer) return sendFail(res, '个人客户不存在', 404)
sendOk(res, customer)
})
router.post('/customer-info/personal/create', (req, res) => {
const body = req.body || {}
if (!body.customerName) return sendFail(res, '客户名称不能为空', 400)
const id = nextId('individualCustomer')
const now = new Date().toISOString().slice(0, 19).replace('T', ' ')
const customer = {
id,
customerCode: `PC${String(id).padStart(4, '0')}`,
creatorId: req.userId,
createTime: now,
updateTime: now,
...body
}
individualCustomers.push(customer)
sendOk(res, id, '创建成功')
})
router.post('/customer-info/personal/update', (req, res) => {
const { id, ...rest } = req.body || {}
const customer = individualCustomers.find((c) => c.id === id)
if (!customer) return sendFail(res, '个人客户不存在', 404)
Object.assign(customer, rest, { updateTime: new Date().toISOString().slice(0, 19).replace('T', ' ') })
sendOk(res, true, '更新成功')
})
// OCR身份证识别:mock固定返回一份示例识别结果,不做真实图像识别
router.post('/customer-info/personal/ocr-idcard', (req, res) => {
const { channelNo, fileBase64, fileType } = req.body || {}
if (!channelNo || !fileBase64 || !fileType) return sendFail(res, 'channelNo/fileBase64/fileType不能为空', 400)
sendOk(res, {
name: '张三',
sex: '男',
nation: '汉',
birth: '19900101',
idcard: '310101199001010001',
address: '上海市浦东新区世纪大道1号',
authority: '上海市公安局浦东分局',
validDate: '20200101-20400101'
})
})
// 通用文件上传:2026-08-06 起移至不挂 requireAuth 的 mock-server/routes/uploadFile.js,
// 与 face-recognize 同理——该接口同时被管理后台(已登录)与 fryl_h5 个人开户移动端H5"相关协议"
// 步骤(匿名,用于上传填好客户信息的《用户支付服务协议》PDF)调用,若挂在本文件会被
// requireAuth 拦截H5侧的匿名请求返回401。详见 uploadFile.js 顶部注释。
// ---------------- 企业客户 ----------------
function toEnterpriseVo(e) {
return {
id: e.id,
organizationId: e.organizationId,
enterpriseName: e.enterpriseName,
businessLicense: e.businessLicense,
certificateType: e.certificateType,
certificateNumber: e.certificateNumber,
certificateEffectiveDate: e.certificateEffectiveDate,
certificateExpiryDate: e.certificateExpiryDate,
mobilePhone: e.mobilePhone,
certificateAddress: e.certificateAddress,
businessScope: e.businessScope,
enterpriseCode: e.enterpriseCode,
ocrStatus: e.ocrStatus,
createTime: e.createTime
}
}
router.post('/enterprise-customer/page', (req, res) => {
const { enterpriseName, businessLicense, mobilePhone, page, pageSize } = req.body || {}
let list = enterpriseCustomers
if (enterpriseName) list = list.filter((e) => e.enterpriseName.includes(enterpriseName))
if (businessLicense) list = list.filter((e) => e.businessLicense === businessLicense)
if (mobilePhone) list = list.filter((e) => e.mobilePhone === mobilePhone)
const result = paginate(list, page, pageSize)
sendOk(res, { ...result, records: result.records.map(toEnterpriseVo) })
})
router.post('/enterprise-customer/detail', (req, res) => {
const { id } = req.body || {}
const enterprise = enterpriseCustomers.find((e) => e.id === id)
if (!enterprise) return sendFail(res, '企业客户不存在', 404)
sendOk(res, { ...enterprise, legalRepresentativeId: enterprise.legalRepresentativeId })
})
router.post('/enterprise-customer/create', (req, res) => {
const { createEnterpriseCustomerBto, enableOcr } = req.body || {}
if (!createEnterpriseCustomerBto || !createEnterpriseCustomerBto.enterpriseName) {
return sendFail(res, '企业名称不能为空', 400)
}
const { enterpriseRelatedPersonBtoList, ...enterpriseFields } = createEnterpriseCustomerBto
const id = nextId('enterpriseCustomer')
const now = new Date().toISOString().slice(0, 19).replace('T', ' ')
const enterprise = {
id,
enterpriseCode: `EC${String(id).padStart(4, '0')}`,
ocrStatus: enableOcr ? 'SUCCESS' : 'PENDING',
creatorId: req.userId,
createTime: now,
...enterpriseFields
}
enterpriseCustomers.push(enterprise)
;(enterpriseRelatedPersonBtoList || []).forEach((p) => {
enterpriseRelatedPersons.push({
id: nextId('enterpriseRelatedPerson'),
enterpriseId: id,
...p
})
})
sendOk(res, { id }, '创建成功')
})
router.post('/enterprise-customer/update', (req, res) => {
const { id, ...rest } = req.body || {}
const enterprise = enterpriseCustomers.find((e) => e.id === id)
if (!enterprise) return sendFail(res, '企业客户不存在', 404)
Object.assign(enterprise, rest)
sendOk(res, true, '更新成功')
})
export default router