保险前后端,养殖端和保险端小程序
This commit is contained in:
142
insurance_backend/models/Claim.js
Normal file
142
insurance_backend/models/Claim.js
Normal file
@@ -0,0 +1,142 @@
|
||||
const { DataTypes } = require('sequelize');
|
||||
const { sequelize } = require('../config/database');
|
||||
|
||||
const Claim = sequelize.define('Claim', {
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
comment: '理赔ID'
|
||||
},
|
||||
claim_no: {
|
||||
type: DataTypes.STRING(50),
|
||||
allowNull: false,
|
||||
unique: true,
|
||||
comment: '理赔编号',
|
||||
validate: {
|
||||
notEmpty: {
|
||||
msg: '理赔编号不能为空'
|
||||
}
|
||||
}
|
||||
},
|
||||
policy_id: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
comment: '关联的保单ID',
|
||||
references: {
|
||||
model: 'policies',
|
||||
key: 'id'
|
||||
}
|
||||
},
|
||||
customer_id: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
comment: '客户ID',
|
||||
references: {
|
||||
model: 'users',
|
||||
key: 'id'
|
||||
}
|
||||
},
|
||||
claim_amount: {
|
||||
type: DataTypes.DECIMAL(15, 2),
|
||||
allowNull: false,
|
||||
comment: '理赔金额',
|
||||
validate: {
|
||||
min: {
|
||||
args: [0],
|
||||
msg: '理赔金额不能小于0'
|
||||
}
|
||||
}
|
||||
},
|
||||
claim_date: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: false,
|
||||
comment: '理赔发生日期'
|
||||
},
|
||||
incident_description: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: false,
|
||||
comment: '事故描述',
|
||||
validate: {
|
||||
notEmpty: {
|
||||
msg: '事故描述不能为空'
|
||||
}
|
||||
}
|
||||
},
|
||||
claim_status: {
|
||||
type: DataTypes.ENUM('pending', 'approved', 'rejected', 'processing', 'paid'),
|
||||
allowNull: false,
|
||||
defaultValue: 'pending',
|
||||
comment: '理赔状态:pending-待审核,approved-已批准,rejected-已拒绝,processing-处理中,paid-已支付'
|
||||
},
|
||||
review_notes: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: true,
|
||||
comment: '审核备注'
|
||||
},
|
||||
reviewer_id: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
comment: '审核人ID',
|
||||
references: {
|
||||
model: 'users',
|
||||
key: 'id'
|
||||
}
|
||||
},
|
||||
review_date: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true,
|
||||
comment: '审核日期'
|
||||
},
|
||||
payment_date: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true,
|
||||
comment: '支付日期'
|
||||
},
|
||||
supporting_documents: {
|
||||
type: DataTypes.JSON,
|
||||
allowNull: true,
|
||||
comment: '支持文件(JSON数组,包含文件URL和描述)'
|
||||
},
|
||||
created_by: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
comment: '创建人ID'
|
||||
},
|
||||
updated_by: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
comment: '更新人ID'
|
||||
}
|
||||
}, {
|
||||
tableName: 'claims',
|
||||
timestamps: true,
|
||||
createdAt: 'created_at',
|
||||
updatedAt: 'updated_at',
|
||||
indexes: [
|
||||
{
|
||||
name: 'idx_claim_no',
|
||||
fields: ['claim_no'],
|
||||
unique: true
|
||||
},
|
||||
{
|
||||
name: 'idx_claim_policy',
|
||||
fields: ['policy_id']
|
||||
},
|
||||
{
|
||||
name: 'idx_claim_customer',
|
||||
fields: ['customer_id']
|
||||
},
|
||||
{
|
||||
name: 'idx_claim_status',
|
||||
fields: ['claim_status']
|
||||
},
|
||||
{
|
||||
name: 'idx_claim_date',
|
||||
fields: ['claim_date']
|
||||
}
|
||||
],
|
||||
comment: '理赔表'
|
||||
});
|
||||
|
||||
module.exports = Claim;
|
||||
106
insurance_backend/models/InsuranceApplication.js
Normal file
106
insurance_backend/models/InsuranceApplication.js
Normal file
@@ -0,0 +1,106 @@
|
||||
const { DataTypes } = require('sequelize');
|
||||
const { sequelize } = require('../config/database');
|
||||
|
||||
const InsuranceApplication = sequelize.define('InsuranceApplication', {
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
autoIncrement: true,
|
||||
primaryKey: true
|
||||
},
|
||||
application_no: {
|
||||
type: DataTypes.STRING(50),
|
||||
allowNull: false,
|
||||
unique: true,
|
||||
validate: {
|
||||
len: [10, 50]
|
||||
}
|
||||
},
|
||||
customer_name: {
|
||||
type: DataTypes.STRING(100),
|
||||
allowNull: false,
|
||||
validate: {
|
||||
len: [2, 100]
|
||||
}
|
||||
},
|
||||
customer_id_card: {
|
||||
type: DataTypes.STRING(18),
|
||||
allowNull: false,
|
||||
validate: {
|
||||
is: /^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[0-9Xx]$/
|
||||
}
|
||||
},
|
||||
customer_phone: {
|
||||
type: DataTypes.STRING(20),
|
||||
allowNull: false,
|
||||
validate: {
|
||||
is: /^1[3-9]\d{9}$/
|
||||
}
|
||||
},
|
||||
customer_address: {
|
||||
type: DataTypes.STRING(255),
|
||||
allowNull: false,
|
||||
validate: {
|
||||
len: [5, 255]
|
||||
}
|
||||
},
|
||||
insurance_type_id: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
references: {
|
||||
model: 'insurance_types',
|
||||
key: 'id'
|
||||
}
|
||||
},
|
||||
application_amount: {
|
||||
type: DataTypes.DECIMAL(15, 2),
|
||||
allowNull: false,
|
||||
validate: {
|
||||
min: 0
|
||||
}
|
||||
},
|
||||
status: {
|
||||
type: DataTypes.ENUM('pending', 'approved', 'rejected', 'under_review'),
|
||||
defaultValue: 'pending'
|
||||
},
|
||||
application_date: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: false,
|
||||
defaultValue: DataTypes.NOW
|
||||
},
|
||||
review_notes: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: true
|
||||
},
|
||||
reviewer_id: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
references: {
|
||||
model: 'users',
|
||||
key: 'id'
|
||||
}
|
||||
},
|
||||
review_date: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true
|
||||
},
|
||||
documents: {
|
||||
type: DataTypes.JSON,
|
||||
allowNull: true,
|
||||
defaultValue: []
|
||||
}
|
||||
}, {
|
||||
tableName: 'insurance_applications',
|
||||
timestamps: true,
|
||||
underscored: true,
|
||||
indexes: [
|
||||
{ fields: ['application_no'] },
|
||||
{ fields: ['customer_id_card'] },
|
||||
{ fields: ['customer_phone'] },
|
||||
{ fields: ['status'] },
|
||||
{ fields: ['application_date'] },
|
||||
{ fields: ['insurance_type_id'] },
|
||||
{ fields: ['reviewer_id'] }
|
||||
]
|
||||
});
|
||||
|
||||
module.exports = InsuranceApplication;
|
||||
105
insurance_backend/models/InsuranceType.js
Normal file
105
insurance_backend/models/InsuranceType.js
Normal file
@@ -0,0 +1,105 @@
|
||||
const { DataTypes } = require('sequelize');
|
||||
const { sequelize } = require('../config/database');
|
||||
|
||||
const InsuranceType = sequelize.define('InsuranceType', {
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
comment: '保险类型ID'
|
||||
},
|
||||
name: {
|
||||
type: DataTypes.STRING(100),
|
||||
allowNull: false,
|
||||
comment: '保险类型名称',
|
||||
validate: {
|
||||
notEmpty: {
|
||||
msg: '保险类型名称不能为空'
|
||||
},
|
||||
len: {
|
||||
args: [1, 100],
|
||||
msg: '保险类型名称长度必须在1-100个字符之间'
|
||||
}
|
||||
}
|
||||
},
|
||||
description: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: true,
|
||||
comment: '保险类型描述'
|
||||
},
|
||||
coverage_amount_min: {
|
||||
type: DataTypes.DECIMAL(15, 2),
|
||||
allowNull: false,
|
||||
defaultValue: 0.00,
|
||||
comment: '最低保额',
|
||||
validate: {
|
||||
min: {
|
||||
args: [0],
|
||||
msg: '最低保额不能小于0'
|
||||
}
|
||||
}
|
||||
},
|
||||
coverage_amount_max: {
|
||||
type: DataTypes.DECIMAL(15, 2),
|
||||
allowNull: false,
|
||||
defaultValue: 1000000.00,
|
||||
comment: '最高保额',
|
||||
validate: {
|
||||
min: {
|
||||
args: [0],
|
||||
msg: '最高保额不能小于0'
|
||||
}
|
||||
}
|
||||
},
|
||||
premium_rate: {
|
||||
type: DataTypes.DECIMAL(5, 4),
|
||||
allowNull: false,
|
||||
defaultValue: 0.001,
|
||||
comment: '保险费率',
|
||||
validate: {
|
||||
min: {
|
||||
args: [0],
|
||||
msg: '保险费率不能小于0'
|
||||
},
|
||||
max: {
|
||||
args: [1],
|
||||
msg: '保险费率不能大于1'
|
||||
}
|
||||
}
|
||||
},
|
||||
status: {
|
||||
type: DataTypes.ENUM('active', 'inactive'),
|
||||
allowNull: false,
|
||||
defaultValue: 'active',
|
||||
comment: '状态:active-启用,inactive-停用'
|
||||
},
|
||||
created_by: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
comment: '创建人ID'
|
||||
},
|
||||
updated_by: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
comment: '更新人ID'
|
||||
}
|
||||
}, {
|
||||
tableName: 'insurance_types',
|
||||
timestamps: true,
|
||||
createdAt: 'created_at',
|
||||
updatedAt: 'updated_at',
|
||||
indexes: [
|
||||
{
|
||||
name: 'idx_insurance_type_name',
|
||||
fields: ['name'],
|
||||
unique: true
|
||||
},
|
||||
{
|
||||
name: 'idx_insurance_type_status',
|
||||
fields: ['status']
|
||||
}
|
||||
],
|
||||
comment: '保险类型表'
|
||||
});
|
||||
|
||||
module.exports = InsuranceType;
|
||||
153
insurance_backend/models/Policy.js
Normal file
153
insurance_backend/models/Policy.js
Normal file
@@ -0,0 +1,153 @@
|
||||
const { DataTypes } = require('sequelize');
|
||||
const { sequelize } = require('../config/database');
|
||||
|
||||
const Policy = sequelize.define('Policy', {
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
comment: '保单ID'
|
||||
},
|
||||
policy_no: {
|
||||
type: DataTypes.STRING(50),
|
||||
allowNull: false,
|
||||
unique: true,
|
||||
comment: '保单编号',
|
||||
validate: {
|
||||
notEmpty: {
|
||||
msg: '保单编号不能为空'
|
||||
}
|
||||
}
|
||||
},
|
||||
application_id: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
comment: '关联的保险申请ID',
|
||||
references: {
|
||||
model: 'insurance_applications',
|
||||
key: 'id'
|
||||
}
|
||||
},
|
||||
insurance_type_id: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
comment: '保险类型ID',
|
||||
references: {
|
||||
model: 'insurance_types',
|
||||
key: 'id'
|
||||
}
|
||||
},
|
||||
customer_id: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
comment: '客户ID',
|
||||
references: {
|
||||
model: 'users',
|
||||
key: 'id'
|
||||
}
|
||||
},
|
||||
coverage_amount: {
|
||||
type: DataTypes.DECIMAL(15, 2),
|
||||
allowNull: false,
|
||||
comment: '保额',
|
||||
validate: {
|
||||
min: {
|
||||
args: [0],
|
||||
msg: '保额不能小于0'
|
||||
}
|
||||
}
|
||||
},
|
||||
premium_amount: {
|
||||
type: DataTypes.DECIMAL(15, 2),
|
||||
allowNull: false,
|
||||
comment: '保费金额',
|
||||
validate: {
|
||||
min: {
|
||||
args: [0],
|
||||
msg: '保费金额不能小于0'
|
||||
}
|
||||
}
|
||||
},
|
||||
start_date: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: false,
|
||||
comment: '保险开始日期'
|
||||
},
|
||||
end_date: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: false,
|
||||
comment: '保险结束日期'
|
||||
},
|
||||
policy_status: {
|
||||
type: DataTypes.ENUM('active', 'expired', 'cancelled', 'suspended'),
|
||||
allowNull: false,
|
||||
defaultValue: 'active',
|
||||
comment: '保单状态:active-有效,expired-已过期,cancelled-已取消,suspended-已暂停'
|
||||
},
|
||||
payment_status: {
|
||||
type: DataTypes.ENUM('paid', 'unpaid', 'partial'),
|
||||
allowNull: false,
|
||||
defaultValue: 'unpaid',
|
||||
comment: '支付状态:paid-已支付,unpaid-未支付,partial-部分支付'
|
||||
},
|
||||
payment_date: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true,
|
||||
comment: '支付日期'
|
||||
},
|
||||
policy_document_url: {
|
||||
type: DataTypes.STRING(500),
|
||||
allowNull: true,
|
||||
comment: '保单文件URL'
|
||||
},
|
||||
terms_and_conditions: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: true,
|
||||
comment: '条款和条件'
|
||||
},
|
||||
created_by: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
comment: '创建人ID'
|
||||
},
|
||||
updated_by: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
comment: '更新人ID'
|
||||
}
|
||||
}, {
|
||||
tableName: 'policies',
|
||||
timestamps: true,
|
||||
createdAt: 'created_at',
|
||||
updatedAt: 'updated_at',
|
||||
indexes: [
|
||||
{
|
||||
name: 'idx_policy_no',
|
||||
fields: ['policy_no'],
|
||||
unique: true
|
||||
},
|
||||
{
|
||||
name: 'idx_policy_customer',
|
||||
fields: ['customer_id']
|
||||
},
|
||||
{
|
||||
name: 'idx_policy_application',
|
||||
fields: ['application_id']
|
||||
},
|
||||
{
|
||||
name: 'idx_policy_status',
|
||||
fields: ['policy_status']
|
||||
},
|
||||
{
|
||||
name: 'idx_policy_payment_status',
|
||||
fields: ['payment_status']
|
||||
},
|
||||
{
|
||||
name: 'idx_policy_dates',
|
||||
fields: ['start_date', 'end_date']
|
||||
}
|
||||
],
|
||||
comment: '保单表'
|
||||
});
|
||||
|
||||
module.exports = Policy;
|
||||
41
insurance_backend/models/Role.js
Normal file
41
insurance_backend/models/Role.js
Normal file
@@ -0,0 +1,41 @@
|
||||
const { DataTypes } = require('sequelize');
|
||||
const { sequelize } = require('../config/database');
|
||||
|
||||
const Role = sequelize.define('Role', {
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
autoIncrement: true,
|
||||
primaryKey: true
|
||||
},
|
||||
name: {
|
||||
type: DataTypes.STRING(50),
|
||||
allowNull: false,
|
||||
unique: true,
|
||||
validate: {
|
||||
len: [2, 50]
|
||||
}
|
||||
},
|
||||
description: {
|
||||
type: DataTypes.STRING(255),
|
||||
allowNull: true
|
||||
},
|
||||
permissions: {
|
||||
type: DataTypes.JSON,
|
||||
allowNull: false,
|
||||
defaultValue: []
|
||||
},
|
||||
status: {
|
||||
type: DataTypes.ENUM('active', 'inactive'),
|
||||
defaultValue: 'active'
|
||||
}
|
||||
}, {
|
||||
tableName: 'roles',
|
||||
timestamps: true,
|
||||
underscored: true,
|
||||
indexes: [
|
||||
{ fields: ['name'] },
|
||||
{ fields: ['status'] }
|
||||
]
|
||||
});
|
||||
|
||||
module.exports = Role;
|
||||
105
insurance_backend/models/User.js
Normal file
105
insurance_backend/models/User.js
Normal file
@@ -0,0 +1,105 @@
|
||||
const { DataTypes } = require('sequelize');
|
||||
const { sequelize } = require('../config/database');
|
||||
const bcrypt = require('bcrypt');
|
||||
|
||||
const User = sequelize.define('User', {
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
autoIncrement: true,
|
||||
primaryKey: true
|
||||
},
|
||||
username: {
|
||||
type: DataTypes.STRING(50),
|
||||
allowNull: false,
|
||||
unique: true,
|
||||
validate: {
|
||||
len: [3, 50],
|
||||
is: /^[a-zA-Z0-9_]+$/
|
||||
}
|
||||
},
|
||||
password: {
|
||||
type: DataTypes.STRING(255),
|
||||
allowNull: false,
|
||||
validate: {
|
||||
len: [6, 255]
|
||||
}
|
||||
},
|
||||
real_name: {
|
||||
type: DataTypes.STRING(50),
|
||||
allowNull: false,
|
||||
validate: {
|
||||
len: [2, 50]
|
||||
}
|
||||
},
|
||||
email: {
|
||||
type: DataTypes.STRING(100),
|
||||
allowNull: false,
|
||||
unique: true,
|
||||
validate: {
|
||||
isEmail: true
|
||||
}
|
||||
},
|
||||
phone: {
|
||||
type: DataTypes.STRING(20),
|
||||
allowNull: false,
|
||||
validate: {
|
||||
is: /^1[3-9]\d{9}$/
|
||||
}
|
||||
},
|
||||
role_id: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
references: {
|
||||
model: 'roles',
|
||||
key: 'id'
|
||||
}
|
||||
},
|
||||
status: {
|
||||
type: DataTypes.ENUM('active', 'inactive', 'suspended'),
|
||||
defaultValue: 'active'
|
||||
},
|
||||
last_login: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true
|
||||
},
|
||||
avatar: {
|
||||
type: DataTypes.STRING(255),
|
||||
allowNull: true
|
||||
}
|
||||
}, {
|
||||
tableName: 'users',
|
||||
timestamps: true,
|
||||
underscored: true,
|
||||
indexes: [
|
||||
{ fields: ['username'] },
|
||||
{ fields: ['email'] },
|
||||
{ fields: ['phone'] },
|
||||
{ fields: ['role_id'] },
|
||||
{ fields: ['status'] }
|
||||
],
|
||||
hooks: {
|
||||
beforeCreate: async (user) => {
|
||||
if (user.password) {
|
||||
user.password = await bcrypt.hash(user.password, 12);
|
||||
}
|
||||
},
|
||||
beforeUpdate: async (user) => {
|
||||
if (user.changed('password')) {
|
||||
user.password = await bcrypt.hash(user.password, 12);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 实例方法
|
||||
User.prototype.validatePassword = async function(password) {
|
||||
return await bcrypt.compare(password, this.password);
|
||||
};
|
||||
|
||||
User.prototype.toJSON = function() {
|
||||
const values = Object.assign({}, this.get());
|
||||
delete values.password;
|
||||
return values;
|
||||
};
|
||||
|
||||
module.exports = User;
|
||||
66
insurance_backend/models/index.js
Normal file
66
insurance_backend/models/index.js
Normal file
@@ -0,0 +1,66 @@
|
||||
const { sequelize } = require('../config/database');
|
||||
|
||||
// 导入所有模型
|
||||
const User = require('./User');
|
||||
const Role = require('./Role');
|
||||
const InsuranceApplication = require('./InsuranceApplication');
|
||||
const InsuranceType = require('./InsuranceType');
|
||||
const Policy = require('./Policy');
|
||||
const Claim = require('./Claim');
|
||||
|
||||
// 定义模型关联关系
|
||||
|
||||
// 用户和角色关联
|
||||
User.belongsTo(Role, { foreignKey: 'role_id', as: 'role' });
|
||||
Role.hasMany(User, { foreignKey: 'role_id', as: 'users' });
|
||||
|
||||
// 保险申请和保险类型关联
|
||||
InsuranceApplication.belongsTo(InsuranceType, {
|
||||
foreignKey: 'insurance_type_id',
|
||||
as: 'insurance_type'
|
||||
});
|
||||
InsuranceType.hasMany(InsuranceApplication, {
|
||||
foreignKey: 'insurance_type_id',
|
||||
as: 'applications'
|
||||
});
|
||||
|
||||
// 保险申请和审核人关联
|
||||
InsuranceApplication.belongsTo(User, {
|
||||
foreignKey: 'reviewer_id',
|
||||
as: 'reviewer'
|
||||
});
|
||||
User.hasMany(InsuranceApplication, {
|
||||
foreignKey: 'reviewer_id',
|
||||
as: 'reviewed_applications'
|
||||
});
|
||||
|
||||
// 保单和保险申请关联
|
||||
Policy.belongsTo(InsuranceApplication, {
|
||||
foreignKey: 'application_id',
|
||||
as: 'application'
|
||||
});
|
||||
InsuranceApplication.hasOne(Policy, {
|
||||
foreignKey: 'application_id',
|
||||
as: 'policy'
|
||||
});
|
||||
|
||||
// 理赔和保单关联
|
||||
Claim.belongsTo(Policy, {
|
||||
foreignKey: 'policy_id',
|
||||
as: 'policy'
|
||||
});
|
||||
Policy.hasMany(Claim, {
|
||||
foreignKey: 'policy_id',
|
||||
as: 'claims'
|
||||
});
|
||||
|
||||
// 导出所有模型
|
||||
module.exports = {
|
||||
sequelize,
|
||||
User,
|
||||
Role,
|
||||
InsuranceApplication,
|
||||
InsuranceType,
|
||||
Policy,
|
||||
Claim
|
||||
};
|
||||
Reference in New Issue
Block a user