chore: add the mobile market contract dependency closure.
This commit is contained in:
1 parent
0c4a2408ee
commit
0927a514d2
9 files changed
+357
No files matched your search
@@ -0,0 +1,18 @@
|
||||
import freight from './modules/freight.js'
|
||||
import paymentChase from './modules/payment-chase.js'
|
||||
import payment from './modules/payment.js'
|
||||
import presign from './modules/presign.js'
|
||||
import protocol from './modules/protocol.js'
|
||||
import sample from './modules/sample.js'
|
||||
|
||||
const MODULES = Object.freeze({ presign, protocol, 'payment-chase': paymentChase, payment, sample, freight })
|
||||
|
||||
export function getMarketModule(module) {
|
||||
const value = MODULES[module]
|
||||
if (!value) throw new Error('市场页面配置无效')
|
||||
return value
|
||||
}
|
||||
|
||||
export function getMarketListParams(module, filters) {
|
||||
return getMarketModule(module).listParams?.(filters) || {}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
export default {
|
||||
key: 'freight',
|
||||
resource: 'freights',
|
||||
actions: {
|
||||
specialist: ['view', 'create', 'edit', 'link', 'unlink'],
|
||||
manager: ['view', 'create', 'edit', 'link', 'unlink']
|
||||
},
|
||||
listParams: ({ status } = {}) => ({ transportMode: status || '' }),
|
||||
statusOptions: [{ text: '全部运输方式', value: '' }],
|
||||
usesPagedSampleOptions(action) {
|
||||
return ['create', 'link'].includes(action)
|
||||
},
|
||||
sampleOptions(action, detailItems, optionRows) {
|
||||
if (action === 'unlink') return Array.isArray(detailItems) ? detailItems : []
|
||||
return (Array.isArray(optionRows) ? optionRows : []).filter((item) => !item.freightId)
|
||||
},
|
||||
formSections: [{ key: 'base', title: '运费批次', fields: [
|
||||
{ key: 'transportMode', label: '运输方式', type: 'select', optionKey: 'transportModes', required: true },
|
||||
{ key: 'freightAmount', label: '运费金额', type: 'number', required: true }
|
||||
] }]
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
export default {
|
||||
key: 'payment-chase',
|
||||
resource: 'payment-chase',
|
||||
readOnly: true,
|
||||
actions: { specialist: ['view-payment'], manager: ['view-payment'] },
|
||||
listParams: ({ status } = {}) => ({ chaseType: status || '' }),
|
||||
statusOptions: [
|
||||
{ text: '全部催缴', value: '' },
|
||||
{ text: '已逾期', value: 'overdue' },
|
||||
{ text: '未来 30 天', value: 'upcoming' }
|
||||
],
|
||||
detailTarget(item) {
|
||||
return {
|
||||
module: 'payment',
|
||||
id: String(item?.samplePaymentId || ''),
|
||||
query: item?.scheduleId ? { scheduleId: String(item.scheduleId) } : {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
export default {
|
||||
key: 'payment',
|
||||
resource: 'payments',
|
||||
actions: {
|
||||
specialist: ['view', 'register-transfer', 'edit-transfer', 'submit', 'withdraw'],
|
||||
manager: ['view', 'register-transfer', 'edit-transfer', 'submit', 'withdraw']
|
||||
},
|
||||
listParams: ({ status } = {}) => ({ payMode: status || '' }),
|
||||
statusOptions: [{ text: '全部缴费模式', value: '' }],
|
||||
initialForm(detail, target = {}) {
|
||||
const transfer = (detail?.schedules || [])
|
||||
.flatMap((row) => row.transfers || [])
|
||||
.find((row) => String(row.id || '') === String(target.transferId || '')) || {}
|
||||
const fields = ['transferAmount', 'transferTime', 'transferType', 'transferAttachments', 'remark']
|
||||
return {
|
||||
transfer: Object.fromEntries(fields
|
||||
.filter((key) => Object.prototype.hasOwnProperty.call(transfer, key))
|
||||
.map((key) => [key, transfer[key]]))
|
||||
}
|
||||
},
|
||||
transferFields: [
|
||||
{ key: 'transferAmount', label: '转账金额', type: 'number', required: true },
|
||||
{ key: 'transferTime', label: '转账时间', type: 'datetime' },
|
||||
{ key: 'transferType', label: '转账方式', type: 'select', optionKey: 'transferTypes', required: true },
|
||||
{ key: 'transferAttachments', label: '转账凭证', type: 'upload' },
|
||||
{ key: 'remark', label: '备注', type: 'textarea' }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import { commonFields } from './shared.js'
|
||||
|
||||
export default {
|
||||
key: 'presign',
|
||||
resource: 'presign-orders',
|
||||
actions: {
|
||||
specialist: ['view', 'create', 'edit', 'convert'],
|
||||
manager: ['view', 'create', 'edit', 'convert']
|
||||
},
|
||||
listParams: ({ status } = {}) => ({ orderStatus: status || '' }),
|
||||
statusOptions: [
|
||||
{ text: '全部状态', value: '' },
|
||||
{ text: '预签约', value: 'yqy' },
|
||||
{ text: '已转正式', value: 'yzs' }
|
||||
],
|
||||
formSections: [
|
||||
{
|
||||
key: 'base', title: '预签信息', fields: [
|
||||
{ key: 'orderDate', label: '预签日期', type: 'date' },
|
||||
{ key: 'protocolNo', label: '协议编号' },
|
||||
{ key: 'motherName', label: '客户姓名', required: true },
|
||||
{ key: 'expectedDeliveryDate', label: '预产期', type: 'date' },
|
||||
{ key: 'regionId', label: '采集地区', type: 'select', optionKey: 'regions' },
|
||||
{ key: 'hospitalId', label: '采集医院', type: 'select', optionKey: 'hospitals' },
|
||||
{ key: 'sampleCollectTime', label: '采集时间', type: 'datetime' },
|
||||
{ key: 'payMode', label: '缴费模式' },
|
||||
{ key: 'sampleTypeIds', label: '样本类型', type: 'multi-select', optionKey: 'sampleTypes' },
|
||||
{ key: 'contractAmount', label: '合同金额', type: 'number' },
|
||||
{ key: 'remark', ...commonFields.remark }
|
||||
]
|
||||
},
|
||||
{
|
||||
key: 'transfers', title: '意向金', repeat: true, createOnly: true, fields: [
|
||||
{ key: 'transferAmount', label: '转账金额', type: 'number' },
|
||||
{ key: 'transferTime', label: '转账时间', type: 'datetime' },
|
||||
{ key: 'transferType', label: '转账方式' },
|
||||
{ key: 'transferAttachments', label: '转账附件', type: 'upload' },
|
||||
{ key: 'remark', ...commonFields.remark }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
import { section } from './shared.js'
|
||||
|
||||
const labels = {
|
||||
protocolNo: '协议编号', donationNo: '捐赠编号', registerDate: '登记日期',
|
||||
donationDate: '捐赠日期', motherName: '母亲姓名', motherPhone: '联系电话',
|
||||
regionName: '采集地区', hospitalName: '采集医院', sampleCode: '样本编码',
|
||||
payMode: '缴费模式', protocolAttachments: '协议附件'
|
||||
}
|
||||
|
||||
export default {
|
||||
key: 'protocol',
|
||||
resource: 'protocols',
|
||||
actions: { specialist: ['view', 'create', 'edit'], manager: ['view', 'create', 'edit'] },
|
||||
listParams: ({ status } = {}) => ({ source: status || '' }),
|
||||
statusOptions: [
|
||||
{ text: '全部来源', value: '' },
|
||||
{ text: '细胞存储', value: 'cell_storage' },
|
||||
{ text: '科研捐赠', value: 'research_donation' }
|
||||
],
|
||||
detailSections(detail) {
|
||||
if (Array.isArray(detail?.sections)) return detail.sections
|
||||
const values = [
|
||||
section('protocol', '协议信息', detail?.protocol || detail?.basic || detail, labels),
|
||||
section('collection', '采集信息', detail?.collection, labels),
|
||||
section('customer', '客户信息', detail?.customer, labels),
|
||||
section('samples', '样本信息', { samples: detail?.samples }, labels)
|
||||
]
|
||||
if (detail?.source === 'cell_storage' || detail?.payment) {
|
||||
values.push(section('payment', '缴费信息', detail?.payment, labels))
|
||||
}
|
||||
values.push(section('attachments', '附件信息', detail?.attachments, labels))
|
||||
return values
|
||||
},
|
||||
formSections: [
|
||||
{ key: 'protocol', title: '协议信息', fields: [
|
||||
{ key: 'source', label: '业务来源', type: 'tabs', required: true, createOnly: true, options: [
|
||||
{ text: '细胞存储', value: 'cell_storage' }, { text: '科研捐赠', value: 'research_donation' }
|
||||
] },
|
||||
{ key: 'protocolNo', label: '协议编号', source: 'cell_storage' },
|
||||
{ key: 'donationNo', label: '捐赠编号', source: 'research_donation' },
|
||||
{ key: 'registerDate', label: '登记日期', type: 'date', source: 'cell_storage' },
|
||||
{ key: 'donationDate', label: '捐赠日期', type: 'date', source: 'research_donation' },
|
||||
{ key: 'protocolTotalAmount', label: '协议总金额', type: 'number', source: 'cell_storage' },
|
||||
{ key: 'remark', label: '备注', type: 'textarea' }
|
||||
] },
|
||||
{ key: 'collection', title: '采集信息', nested: true, fields: [
|
||||
{ key: 'regionId', label: '采集地区', type: 'select', optionKey: 'regions' },
|
||||
{ key: 'hospitalId', label: '采集医院', type: 'select', optionKey: 'hospitals' },
|
||||
{ key: 'sampleCollectTime', label: '采集时间', type: 'datetime' }
|
||||
] },
|
||||
{ key: 'customer', title: '客户信息', nested: true, fields: [
|
||||
{ key: 'motherName', label: '母亲姓名', required: true },
|
||||
{ key: 'motherPhone', label: '联系电话', type: 'tel' },
|
||||
{ key: 'motherIdCard', label: '证件号码' },
|
||||
{ key: 'expectedDeliveryDate', label: '预产期', type: 'date' }
|
||||
] },
|
||||
{ key: 'samples', title: '样本信息', repeat: true, fields: [
|
||||
{ key: 'sampleTypeId', label: '样本类型', type: 'select', optionKey: 'sampleTypes' },
|
||||
{ key: 'sampleCode', label: '样本编码' },
|
||||
{ key: 'storageYears', label: '存储年限', type: 'number', source: 'cell_storage' }
|
||||
] },
|
||||
{ key: 'payment', title: '缴费信息(只读)', nested: true, readOnly: true, editOnly: true, source: 'cell_storage', fields: [
|
||||
{ key: 'payMode', label: '缴费模式', readOnly: true },
|
||||
{ key: 'contractAmount', label: '合同金额', readOnly: true },
|
||||
{ key: 'remark', label: '缴费备注', readOnly: true }
|
||||
] },
|
||||
{ key: 'attachments', title: '附件与确认', nested: true, fields: [
|
||||
{ key: 'protocolAttachments', label: '协议附件', type: 'upload', source: 'cell_storage' },
|
||||
{ key: 'consentFormUrls', label: '知情同意书', type: 'upload' },
|
||||
{ key: 'healthSurveyFormUrls', label: '健康调查表', type: 'upload', source: 'cell_storage' },
|
||||
{ key: 'attachmentUrls', label: '其他附件', type: 'upload', source: 'research_donation' },
|
||||
{ key: 'infectiousDiseaseReportUrls', label: '传染病报告', type: 'upload', source: 'research_donation' }
|
||||
] },
|
||||
{ key: 'confirm', title: '提交确认', nested: true, uiOnly: true, fields: [
|
||||
{ key: 'confirmed', label: '我已核对以上信息', type: 'checkbox', required: true }
|
||||
] }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
export default {
|
||||
key: 'sample',
|
||||
resource: 'samples',
|
||||
readOnlySources: ['research_donation'],
|
||||
actions: { specialist: ['view', 'storage-cert', 'insurance'], manager: ['view', 'storage-cert', 'insurance'] },
|
||||
listParams: ({ status } = {}) => ({ status: status || '' }),
|
||||
statusOptions: [{ text: '全部状态', value: '' }],
|
||||
formOptionsParams(sampleId) {
|
||||
return { sampleId: String(sampleId || '').trim() }
|
||||
},
|
||||
initialForm(detail, action) {
|
||||
const handles = (detail?.sections || []).find((section) => section.key === 'market-handles') || {}
|
||||
const handle = action === 'insurance' ? handles.insurance || {} : handles.storageCert || {}
|
||||
const fields = ['handleTime', 'handlerUserId', 'attachments', 'remark']
|
||||
return {
|
||||
handle: Object.fromEntries(fields
|
||||
.filter((key) => Object.prototype.hasOwnProperty.call(handle, key))
|
||||
.map((key) => [key, handle[key]]))
|
||||
}
|
||||
},
|
||||
detailSections(detail) {
|
||||
return Array.isArray(detail?.sections) ? detail.sections : []
|
||||
},
|
||||
handleFields: [
|
||||
{ key: 'handleTime', label: '办理时间', type: 'datetime' },
|
||||
{ key: 'handlerUserId', label: '办理人员', type: 'select', optionKey: 'users' },
|
||||
{ key: 'attachments', label: '附件', type: 'upload' },
|
||||
{ key: 'remark', label: '备注', type: 'textarea' }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export function objectFields(source, labels = {}) {
|
||||
return Object.entries(source || {})
|
||||
.filter(([, value]) => value != null && typeof value !== 'object')
|
||||
.map(([key, value]) => ({ label: labels[key] || key, value }))
|
||||
}
|
||||
|
||||
export function section(key, title, value, labels) {
|
||||
return { key, title, fields: objectFields(value, labels), raw: value }
|
||||
}
|
||||
|
||||
export const commonFields = {
|
||||
remark: { label: '备注', type: 'textarea' }
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
export const MARKET_MODULES = [
|
||||
'presign',
|
||||
'protocol',
|
||||
'payment-chase',
|
||||
'payment',
|
||||
'sample',
|
||||
'freight'
|
||||
]
|
||||
|
||||
export const MARKET_ROLES = ['specialist', 'manager']
|
||||
|
||||
export const MARKET_MODULE_TITLES = Object.freeze({
|
||||
presign: '预签约订单',
|
||||
protocol: '协议单',
|
||||
'payment-chase': '催缴信息',
|
||||
payment: '缴费信息',
|
||||
sample: '样本信息',
|
||||
freight: '运费信息'
|
||||
})
|
||||
|
||||
export const MARKET_ROLE_TITLES = Object.freeze({
|
||||
specialist: '市场专员',
|
||||
manager: '地区经理'
|
||||
})
|
||||
|
||||
function isMarketRole(value) {
|
||||
return MARKET_ROLES.includes(value)
|
||||
}
|
||||
|
||||
function isMarketModule(value) {
|
||||
return MARKET_MODULES.includes(value)
|
||||
}
|
||||
|
||||
export function getMarketRouteContext(route) {
|
||||
const marketRole = route?.meta?.marketRole
|
||||
const module = route?.meta?.module
|
||||
if (!isMarketRole(marketRole) || !isMarketModule(module)) {
|
||||
throw new Error('市场页面配置无效')
|
||||
}
|
||||
return { marketRole, module }
|
||||
}
|
||||
|
||||
export function shouldLoadMarketListAfterDetail({ previousDetailId, detailId }) {
|
||||
return Boolean(String(previousDetailId || '').trim()) && !String(detailId || '').trim()
|
||||
}
|
||||
|
||||
export function pickMarketNavigationQuery(query) {
|
||||
const returnPath = String(query?.returnPath || '').trim()
|
||||
return returnPath.startsWith('/pages/') && !returnPath.startsWith('//')
|
||||
? { returnPath }
|
||||
: {}
|
||||
}
|
||||
|
||||
export function marketRecordNavigationQuery(module, item, query) {
|
||||
const result = pickMarketNavigationQuery(query)
|
||||
const source = String(item?.source || '').trim()
|
||||
if (module === 'protocol' && ['cell_storage', 'research_donation'].includes(source)) {
|
||||
result.source = source
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export function resolveMarketSavedDetailId(module, currentId, result, action) {
|
||||
const current = String(currentId || '').trim()
|
||||
if (module === 'freight' && action === 'unlink' && result?.disappeared === true) return ''
|
||||
if (module === 'payment' && current) return current
|
||||
return String(result?.id || current).trim()
|
||||
}
|
||||
|
||||
const listComponent = () => import('../views/market/MarketModuleList.vue')
|
||||
const detailComponent = () => import('../views/market/MarketModuleDetail.vue')
|
||||
const formComponent = () => import('../views/market/MarketModuleForm.vue')
|
||||
|
||||
export const marketRoutes = MARKET_ROLES.flatMap((marketRole) =>
|
||||
MARKET_MODULES.map((module) => {
|
||||
const meta = {
|
||||
marketRole,
|
||||
module,
|
||||
title: MARKET_MODULE_TITLES[module]
|
||||
}
|
||||
return {
|
||||
path: `/market/${marketRole}/${module}`,
|
||||
name: `market-${marketRole}-${module}`,
|
||||
component: listComponent,
|
||||
meta,
|
||||
children: [
|
||||
{
|
||||
path: 'new',
|
||||
name: `market-${marketRole}-${module}-new`,
|
||||
component: formComponent,
|
||||
meta: { ...meta, formMode: 'create' }
|
||||
},
|
||||
{
|
||||
path: ':id/edit',
|
||||
name: `market-${marketRole}-${module}-edit`,
|
||||
component: formComponent,
|
||||
meta: { ...meta, formMode: 'edit' }
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
name: `market-${marketRole}-${module}-detail`,
|
||||
component: detailComponent,
|
||||
meta: { ...meta, detail: true }
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
)
|
||||
Reference in new issue
Block a user