Skip to content

九号项目

门店模块背景

商更侧重于指代那些从事商品买卖、批发、进出口等业务的企业或个人。一般是作为与公司直接合作的客户,所以我们也将商称为客户,商(客户)可能不直接面对最终消费者。

店一般是指直接面向消费者的零售场所。店铺主要通过销售商品给个人消费者来实现盈利。

店的经营重点在于选址、店面设计、客户服务以及促销策略等方面,以吸引顾客并提高销售额。

为了更方便的管理众多的门店信息,我们更多的是在商与店之间建立一个上下级关系,而公司则更多的是与商直接发生关系,我们将商称为一网,店称为二网。

暂不考虑直通车店

门店管理系统功能概述

门店主要包括门店档案的新增(编辑)、门店变更以及门店关闭。

脑想问题

灰色框表示无需填写

灰色输入框表示无需填写?

门店档案新增的基础信息/店铺信息/代理信息/服务信息之间的关系

即门店档案新增的基础信息、店铺信息、代理信息、服务信息之间有必然的填写顺序联系么?

未填写基础信息之前,能否先填写代理信息、服务信息并进行保存?

因为看到基础信息、店铺信息、代理信息、服务信息等每一页右下角都是提交按钮,而不是下一页,所以确认一下

门店档案新增同一页面内的不同表格信息之间的关系

以基本信息页为例,假设基本信息页只有用户基本信息和门店实际控制人信息

  • 两个表格的信息一次性全部校验,只要有一个输入框与要求不符,即整体拒绝信息的存储(新增),否则一次性存储成功
  • 还是说各个表格之间的字段没有必然地联系,只要某一个表格的数据是正确的、完整的即支持先保存单个表格的数据

如果各个表格数据之间没有必然地联系,建议写一个多表新增(更新)接口,另外也建议再分成多个查询/新增(更新)的接口,因为一般除了第一次新建是一次性全部提交,后续单独修改某个表格信息的可能性更大,减少数据传输和校验,提高性能。

用户依然可以只点提交按钮,前端将每个标的数据作为一个单独的对象,使用v-model实现双向绑定,使用watch监听表格数据对象的变化,如果变化多,则调用统一的接口,如果是单表变化,则用户在点击提交按钮时,调用对应的接口提交表格信息,否则不调用相应接口

如果说是有关系的,还是拿用户基本信息和门店实际控制人信息为例,如何判定

表格单条数据

一般都应该保证单条数据的完整性吧,即不允许存储某条数据的中间状态。看到设计图中比如基础信息页门店营业执照信息存在中间状态,所以确认一下

下拉选项较少的枚举字段(如性别、营业状态等)是由后端提供查询接口还是前端自定义

请业务老师提供门店档案新增下拉框等输入框的完整选项

下拉框如由后端定义时,建议采用哪种方式

  1. 硬编码方式,将所有可能的值集范围直接写在枚举代码中(如果不存在多语言等问题,推荐,因为基本上单个下拉框选项值都很少且基本不改变,不需要专门建一张表)
  2. 建立一张表,通过redis缓存,注意一致性问题(如果支持多语言或内容经常改变,建议使用该方式,统一使用一张表,单加一个字段来区分所属枚举) 在本业务中,我更推荐方式一,因为下拉选项大部分都比较少,很少有超过五隔得,而且也不易变动。

对于下拉框属性是建议存储实际值还是code?

  1. 存储code更节省空间,但需在查询过程中做转换,逻辑实现起来更加繁琐,且数据不直接明了,不便于调试
  2. 相反,直接存储实际值相对浪费空间,但逻辑简单,数据清晰明了 无好坏之分,看项目组更侧重于节省容量还是性能

门店档案新建-相关实体

TIP

目前只定义了基础信息相关实体

用户基本信息

属性名类型是否指定值集范围是否能为空是否唯一描述备注
storeNameString门店名称是否具有唯一性
storeAbbrevString门店缩写门店名称缩写,是否具有唯一性
storeCodeString门店编码系统自动生成是调用外部接口还是指定的工具类,还是自定义,保证不重复即可
natureOfBusinessString经营范围建立枚举,通过枚举值校验入参
vehicleClassificationString车辆分类建立枚举,通过枚举值校验入参
storeTypeString门店类型建立枚举,通过枚举值校验入参
belongGroupLong所属客户组名称所有值均需来自客户组表,直接存储客户组表对应数据的主键值
customerGroupCodeString所属客户组编码在客户组编码唯一的情况下,建议所属客户组置灰吧,前端通过客户组编码连带出来。我给你一个接口,下拉框滑动,分页查询客户组名和客户组编码,但该结果在客户组表的客户组编码不可变且客户组名称可变的情况下,可能导致数据不一致问题,只能实现最终一致性,或客户组那边同步修改
storeAuthCodeString门店授权码门店授权码的生成逻辑,与 storeCode 字段同问
applicationTypeString申请类型申请类型存储枚举硬编码? 1 新建 2 移店
originalStore原门店原门店是指原门店地址? 当申请类型为移店时,原门店字段不能为空?
createTimeDate创建时间直接使用 BaseEntity 的 createTime 数据创建时间 字段
closeResonString闭店原因枚举。当申请类型为移店时必填?具体可选原因都有哪些?
businessStatusString营业状态枚举
storeStatusString门店状态枚举
freezeReasonString冻结原因枚举,冻结原因无论什么时间必填?
closeTimeDate闭店时间枚举,闭店时间无论什么时间必填?
auditTimeDate审核时间审核时间商户不用填写吧,这个字段只是提交后审核后查询展示吧?
businessStartTimeDate营业开始时间
annualOperatingHours全年经营时长是否支持小数

门店实控人

门店实控人信息都由商户自己填写么?后台是否需要校验,比如验证实际控制人姓名与身份证号是否匹配等

属性名类型是否指定值集范围是否能为空是否唯一描述备注
actualControllerNameString实际控制人姓名
actualControllerIdCardString实际控制人身份证号
controllerPhoneString实控人手机号
relationshipWithLegalPersonString与法人关系建立枚举,通过枚举值校验入参
statusString状态建立枚举,通过枚举值校验入参

门店营业执照信息

属性名类型是否指定值集范围是否能为空是否唯一描述备注
legalPersonNameString法人姓名
legalPersonPhoneString法人手机号
legalPersonIdCardString法人身份证号
legalPersonIdcardStartDateDate法人身份证有效期-开始时间
legalPersonIdcardEndDateDate法人身份证有效期-结束时间
legalPersonIdcardValidityPeriodTypeString法人证件有效期类型枚举
taxpayerIdentificationNumberString纳税人识别号
businessLicenseNameString营业执照名称
registeredPhoneString注册电话
registeredAddressString注册地址
isRegisteredAddressSameAsOperationalboolean注册地址是否等于实际经营地址既有注册地址也有经营地址,这个字段还有必要么?非是即否,不可能为空,选用基本类型即可
actualBusinessAddressString实际经营地址
longitudedecimal经度,是否保留小数
latitudedecimal纬度,是否保留小数
registeredCapitaldecimal注册资金(万) ,是否保留小数
businessLicenseTypeString营业执照有效期类型枚举
businessLicenseStartDateDate营业执照有效期开始日期
businessLicenseEndDateDate营业执照有效期结束日期
electronicSignatureContactString电子签章联系人
electronicSignaturePhoneString电子签章电话
electronicSignatureIdCardString电子签章身份证
electronicSignatureEmailString电子签章邮箱

门店仓库地址信息

属性名类型是否指定值集范围是否能为空是否唯一描述备注
addressTypeString地址类型枚举
warehouseCodeString仓库编码仓库编码商户填写还是逻辑生成
areadecimal面积单位是什么?保留几位
provinceString所属省份枚举
cityString所属市枚举
countyString所属区县枚举
detailedAddressString详细地址
contactPersonString联系人
contactPhoneString联系电话
isDefaultDeliveryAddressboolean是否默认送货地址非是即否,使用默认类型

门店银行

是否需要校验数据的真实性,保持四者数据的一致性,还是等转账时银行那边自己返回对应结果?

属性名类型是否指定值集范围是否能为空是否唯一描述备注
unionPayNumberString银联号
bankNameString银行名称
paymentBankAccountString付款银行账户
cardholderNameString持卡人名称

软件费用缴纳情况

属性名类型是否指定值集范围是否能为空是否唯一描述备注
paidSoftwareTypeString付费软件类型枚举
premiumReceiveddecimal缴纳金额涉及金额的一定是decimal了,保留两位
effectiveDateDate生效日期
dueDateDate到期日期

门店人员档案

属性名类型是否指定值集范围是否能为空是否唯一描述备注
staffCodeString人员编码
staffNameString人员名称
postString岗位枚举
mobilePhoneString手机号
orgIdsString所属机构所属机构是下拉框形式么?从哪里获取数据
natureOfBusinessString经营范围经营范围是什么类型,下拉框?

合同列表

属性名类型是否指定值集范围是否能为空是否唯一描述备注
contractCodeString合同编码是商户直接填写么?具体生成逻辑
oaContractCodeStringOA合同编码是商户直接填写么?具体生成逻辑
contractNameString合同名称
contractTypeString合同类型枚举
contractSigningDateString合同签订日期
contractStatusString合同状态枚举

线上运营平台账号

属性名类型是否指定值集范围是否能为空是否唯一描述备注
platformNameString平台名称
accountCodeString账户编码
accountNameString账户名称

门店档案新建-接口设计

WARNING

因为上述部分脑想问题还未与业务等老师及负责人沟通,所以未做详细设计。 问题沟通解决后会更详细的进行接口设计和开发

但大致想法如下: 依然是 Spring + Mybatis-Plus + MySQL

如果最后新建只开发一个接口,所有表单的存储共用一个接口,需要注意不同表之间的事务一致性问题

如果最终是开发多个接口,即单表数据存储对应单表接口,则无需关注。

如果某个注册信息需要分别调用多个接口分别单表存储的话,需要小心并发问题,可能A用户和B用户的数据本身都没问题,但可能A用户线调了存储basic(用户基本信息的表),而B用户先调用了存储contract(合同基本信息的表),当A试图存储contract数据时发现与B的数据冲突问题,而B试图存储basic数据时发现也与A的数据冲突而造成两者均存储失败的问题。 解决方式

  • 队列串行化执行
  • 在redis中将一个唯一的有意义的名称作为key,使用setnx,如果设置成功,则执行,否则失败

虽然门店档案新增与客户档案新增存在多个相似对象,但之间依然有差距,无法完全复用。 拿合同信息举例,如果双方共用一张表,必然都会留下某些空白字段,而且需要添加一列来区分是商的合同还是店的合同,客户档案新增才开发完毕,处于测试阶段,还是不动为好。

计划明天从develop新建一个feature分支,并在ninebot-beforesale下新建一个module,名为ninebot-store,与ninebot-merchant平级,自己在开发时,尽可能将都存在的对象如合同对象建立一个abstract,并提取一些公用的属性,这样未来优化时方便抽取出来