明树Git Lab

Commit 39b6fbbc authored by zengfanpei's avatar zengfanpei

add agr

parent a24f10a1
......@@ -32,6 +32,10 @@
3. 需要确认每一个种类设备 上传的信息 接口调试
4.
--近期更新
1. 简单的流程结构flowDef,不暴露给前端,等用户给定流程审批信息,接口创建流程模板
2. 从入库逻辑开始 入库单增删改查、入库单开启流程......
```
const _ = require('lodash');
const moment = require('moment');
const errorMessage = require('../utils/errorMessage');
const { default: mongoose } = require('mongoose');
/* ----------------农资类型--------------------- */
async function createMatType(req, res, next) {
try {
let creator = req.user._id;
let info = {
...req.body,
creator,
}
let ret = await DB.AgrMatType.findOneAndUpdate({name: info.name}, info, {upsert: true});
res.sendData(ret);
} catch (error) {
next(error);
}
}
async function deleteMatType(req, res, next) {
try {
if(!req.body._id) {
return res.sendError(errorMessage.resourceNotFound);
}
await DB.AgrMatType.findOneAndUpdate({_id: req.body._id}, {del: 1});
res.sendData({})
} catch (error) {
next(error);
}
}
async function updateMatType(req, res, next) {
try {
if(req.body.name) {
let check = await DB.AgrMatType.findOne({name: req.body.name});
if(check) {
return res.sendError(errorMessage.nameDuplicated);
}
}
let ret = await DB.AgrMatType.findOneAndUpdate({_id: req.body._id}, {...req.body, _id: undefined,}, {returnOriginal: false});
res.sendData(ret);
} catch (error) {
next(error);
}
}
async function queryMatType(req, res, next) {
try {
let search = { del: 0 };
let page = req.body.page || 1;
let pageSize = req.body.pageSize || 10;
let skip = (page - 1) * pageSize;
let count = await DB.AgrMatType.countDocuments(search)
let list = await DB.AgrMatType.find(search).skip(skip).limit(pageSize).lean().exec();
res.sendData({count, list});
} catch (error) {
next(error);
}
}
/*---------审批--入库、出库、归还--------------*/
/**
* 获取审批列表--入库、出库、归还
*/
async function queryMatApprList(req, res, next) {
try {
let search = { del: 0 };
let page = req.body.page || 1;
let pageSize = req.body.pageSize || 10;
let skip = (page - 1) * pageSize;
let count = await DB.AgrMaterialApproval.countDocuments(search)
let list = await DB.AgrMaterialApproval.find(search).skip(skip).limit(pageSize).lean().exec();
res.sendData({count, list});
} catch (error) {
next(error)
}
}
/**
*创建审批--入库、出库、归还 ,保存 不发起流程
*/
async function saveMatAppr(req, res, next) {
try {
let {_id, type, materials} = req.body;
if(!_id) {
// 创建
let matAprId = new mongoose.Types.ObjectId();
let matInOutList = [], matIds = [];
for (let index = 0; index < materials.length; index++) {
const element = materials[index];
if(element.name && element.type && _.isNumber(element.count) && element.count > 0) {
let mioId = new mongoose.Types.ObjectId();
matIds.push(mioId);
matInOutList.push({
_id: mioId,
type: element && element._id || element,//种类的id
name: element.name,
count: element.count,
approval: matAprId,
});
}
}
if(matInOutList.length > 0) {
await DB.AgrMatInOut.insertMany(matInOutList); // 插入清单
}
let matApr = await DB.AgrMaterialApproval.create({ // 创建单据
_id: matAprId,
type: type,
materials: matIds,
});
return res.sendData(matApr);
} else {
// 更新
let existsMatApr = await DB.AgrMaterialApproval.findOne({_id: req.body._id});
if(!existsMatApr) {
return res.sendError(errorMessage.resourceNotFound);
}
let matInOutList = [], matIds = [], matExistsIds = [];
for (let index = 0; index < materials.length; index++) {
const element = materials[index];
if(element.name && element.type && _.isNumber(element.count) && element.count > 0) {
let mioId = element._id;
if(!mioId) {
mioId = new mongoose.Types.ObjectId();
}
matIds.push(mioId);
matInOutList.push(DB.AgrMatInOut.findOneAndUpdate({_id: mioId}, {
type: element && element._id || element,//种类的id
name: element.name,
count: element.count,
approval: _id,
}, {upsert: true}));
}
}
//1. 删除不在传递进来的materials里、在数据库里面的数据
if(matIds.length > 0) {
await DB.AgrMatInOut.updateMany({approval: _id, _id: {$nin: matIds}}, {del:1});
}
//2. 更新或插入materials
if(matInOutList.length > 0) {
await Promise.all(matInOutList);
}
let matApr = await DB.AgrMaterialApproval.findOneAndUpdate({_id},{
type: type,
materials: matIds,
});
return res.sendData(matApr);
}
} catch (error) {
next(error)
}
}
/**
* 更新审批--入库、出库、归还 ,保存 不发起流程
*/
async function createMatAppr(req, res, next) {
try {
//
} catch (error) {
next(error)
}
}
/**
* 删除审批--入库、出库、归还 ,已发起流程不能删除。
*/
async function createMatAppr(req, res, next) {
try {
//
} catch (error) {
next(error)
}
}
module.exports = {
createMatType,
deleteMatType,
updateMatType,
queryMatType,
queryMatApprList,
saveMatAppr,
}
\ No newline at end of file
......@@ -46,6 +46,9 @@ async function batchUpload(req, res, next) {
async function importExcel(req, res, next) {
try {
let modelName = req.params.modelName;
let userId = req.user._id;
console.log(DB.AreaRecord.schema.obj);
let workbook = new ExcelJS.Workbook();
console.log(req.file)
......@@ -53,16 +56,20 @@ async function importExcel(req, res, next) {
let worksheet = workbook.getWorksheet(4);
console.log(workbook._worksheets.length);
let values = worksheet.getRow(1).values; // 示例:‌读取第一行
for (let index = 1; index < worksheet.actualRowCount; index++) {
let values = worksheet.getRow(index + 1).values;
await DB.AgrInRecord.create({
time: values[1],
name: values[2],
type: values[3],
total: values[4],
unit: values[5],
})
}
// for (let index = 1; index < worksheet.actualRowCount; index++) {
// let values = worksheet.getRow(index + 1).values;
// await DB.AgrInputRecord.create({
// time: values[1],
// name: values[2],
// type: values[3],
// total: values[4],
// unit: values[5],
// land: values[6],
// area: values[7],
// dosage: values[8],
// agrProName: "青皮柚"
// })
// }
//1. 先通过参数获取对应的表字段对应关系
//2. 找到对应的表 写入
......
/**
*
* {
name: "流程1",
relations: [],
nodes: [],
}
*/
const errorMessage = require("../utils/errorMessage");
const _ = require('lodash');
async function updateFlowDef(req, res, next) {
try {
let flow = await DB.FlowDef.findOneAndUpdate({_id: req.body._id}, req.body, {upsert: true});
res.sendData(flow)
// if(!(flow && flow._id)) {
// //不存在 创建
// let flowInfo = {
// ...req.body,
// }
// await DB.FlowDefNode.insertMany(req.body.nodes);
// await DB.FlowDefRelation.insertMany(req.body.relations);
// flowInfo.nodes = _.map(req.body.nodes, (o => {return o && o._id}));
// flowInfo.relations = _.map(req.body.relations, (o => {return o && o._id}));
// let ret = await DB.FlowDef.create(flowInfo);
// res.sendData(ret);
// } else {
// //存在 对relations nodes进行比对 进行新增、删除、更新
// let {nodes, relations} = flow;
// // let nodeDel = [],nodeUpdate = [], nodeInsert = [], relaDel = [], relaInsert = [];
// // 为了简便
// flow = {
// ...flow,
// ...req.body,
// }
// await DB.FlowDefNode.deleteMany({_id: {$in: nodes}});
// await DB.FlowDefRelation.deleteMany({_id: {$in: relations}});
// await DB.FlowDefNode.insertMany(req.body.nodes);
// await DB.FlowDefRelation.insertMany(req.body.relations);
// flow.nodes = _.map(req.body.nodes, (o => {return o && o._id}));
// flow.relations = _.map(req.body.relations, (o => {return o && o._id}));
// console.log(flow)
// await DB.FlowDef.findOneAndUpdate({_id: flow._id},flow);
// res.sendData(flow);
// }
} catch (error) {
next(error);
}
}
module.exports = {
updateFlowDef
}
\ No newline at end of file
......@@ -34,11 +34,17 @@ const Menu = require('./models/systemMenu');
const Depart = require('./models/systemDepart');
const File = require('./models/systemFile');
const Notice = require('./models/systemNotice');
const FlowDef = require('./models/systemFlowDef');
const FlowDefNode = require('./models/systemFlowDefNode');
const FlowDefRelation = require('./models/systemFlowDefRelation');
const Land = require('./models/letianLand');
const Zone = require('./models/letianZone');
const AgrInputRecord = require('./models/letianAgrInputRecord');
const AreaRecord = require('./models/letianAreaRecord');
const AgrMatType = require('./models/letianAgrMatType');
const AgrMatApproval = require('./models/letianAgrMatApproval');
const AgrMatInOut = require('./models/letianAgrMatInOut');
const Device = require('./models/collectDevice');
......@@ -64,10 +70,17 @@ global.DB = {
Depart,
Notice,
FlowDef,
FlowDefNode,
FlowDefRelation,
Land,
Zone,
AgrInputRecord,
AreaRecord,
AgrMatType,
AgrMatApproval,
AgrMatInOut,
CollectThreshold,
CollectSMC,
......
......@@ -3,7 +3,7 @@ const Schema = mongoose.Schema;
const moment = require('moment');
/**
* 农资管理-农资基础信息表
* 农资管理-农资库存信息表
*/
const AgrMaterialSchema = new Schema({
......@@ -12,10 +12,11 @@ const AgrMaterialSchema = new Schema({
comment: "农资类型"
},
name: {
type: mongoose.Types.ObjectId,
// type: mongoose.Types.ObjectId,
type: String,
comment: "农资名称"
},
count: {
totalCount: {
type: Number,
comment: "农资库存数量"
},
......
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const moment = require('moment');
/**
* 农资管理- 审批表 --合并成一个表,方便查出入库台账
* 1. 入库审批-入库单 -- 关联入库记录表 inout
* 2. 出库审批-出库单 -- 关联出库记录表 inout
* 3. 归还审批-归还单 -- 关联归还记录表 inout
*/
// 审批记录表
const AgrMaterialApprovalSchema = new Schema({
type: {
type: Number,
comment: "单据类型 1 入库单 2 出库单 3 归还单",
required: true,
},
name: {
type: String,
set: setNameToApproval,
comment: "单据名称"
},
materials: {
type: [mongoose.Types.ObjectId],
ref: 'AgrMatInOut',
comment: "出入库记录清单",
default: []
},
creator: {
type: mongoose.Types.ObjectId,
ref: 'User',
comment: "创建人",
required: true,
},
status: {
type: Number,
comment: "单据状态 1.未提交 3.待审批 5.审批通过 7.审批不通过",
default: 1,
},
flow: {
type: [mongoose.Types.ObjectId],
comment: "审批流程记录 不通过后再提交即为一次新的审批流程"
},
createdAt: {
type: Date,
default: Date.now,
get: v => moment(v).format("YYYY-MM-DD HH:mm:ss"),
},
updatedAt: {
type: Date,
default: Date.now,
get: v => moment(v).format("YYYY-MM-DD HH:mm:ss"),
},
del: {
type: Number,
default: 0,
comment: '默认0 , 1:表示删除, 若有其他隐藏业务 不要混用此字段。'
}
}, {
toJSON: {
getters: true
}
});
function setNameToApproval(v) {
let map = {
1: "入库单",
2: "出库单",
3: "归还单",
}
return map[this._update.type];
}
const AgrMaterialApproval = mongoose.model('AgrMaterialApproval', AgrMaterialApprovalSchema, 'letianAgrMaterialApproval');
module.exports = AgrMaterialApproval;
\ No newline at end of file
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const moment = require('moment');
/**
* 农资管理-农资库存信息表
*/
const AgrMaterialInOutSchema = new Schema({
type: {
type: mongoose.Types.ObjectId,
comment: "农资类型",
required: true,
},
name: {
type: String,
comment: "农资名称"
},
count: {
type: Number,
comment: "出入库数量",
default: 0,
},
approval: {
type: mongoose.Types.ObjectId,
comment: "单据id",
required: true,
},
createdAt: {
type: Date,
default: Date.now,
get: v => moment(v).format("YYYY-MM-DD HH:mm:ss"),
},
updatedAt: {
type: Date,
default: Date.now,
get: v => moment(v).format("YYYY-MM-DD HH:mm:ss"),
},
del: {
type: Number,
default: 0,
comment: '默认0 , 1:表示删除, 若有其他隐藏业务 不要混用此字段。'
}
}, {
toJSON: {
getters: true
}
});
const AgrMatInOut = mongoose.model('AgrMatInOut', AgrMaterialInOutSchema, 'letianAgrMatInOut');
module.exports = AgrMatInOut;
\ No newline at end of file
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const moment = require('moment');
/**
* 农资管理-农资类型
*/
const AgrMaterialSchema = new Schema({
name: {
type: String,
comment: "种类名称"
},
creator: {
type: mongoose.Types.ObjectId,
ref: 'User',
comment: "创建人",
required: true,
},
createdAt: {
type: Date,
default: Date.now,
get: v => moment(v).format("YYYY-MM-DD HH:mm:ss"),
},
updatedAt: {
type: Date,
default: Date.now,
get: v => moment(v).format("YYYY-MM-DD HH:mm:ss"),
},
del: {
type: Number,
default: 0,
comment: '默认0 , 1:表示删除, 若有其他隐藏业务 不要混用此字段。'
}
}, {
toJSON: {
getters: true
}
});
const AgrMaterial = mongoose.model('AgrMaterial', AgrMaterialSchema, 'letianAgrMaterial');
module.exports = AgrMaterial;
\ No newline at end of file
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const moment = require('moment');
const flowDefRelationSchema = require('./systemFlowDefRelation')
const flowDefNodeSchema = require('./systemFlowDefNode')
/**
* 用户
*/
const flowDefSchema = new Schema({
name: {
type: String,
comment: "流程名称"
},
key: {
type: String,
unique: true,
comment: "流程唯一标识"
},
// relations: {
// type: [mongoose.Types.ObjectId],
// comment: "关系 线条",
// ref: 'FlowDefRelation'
// },
// nodes: {
// type: [mongoose.Types.ObjectId],
// comment: "节点",
// ref: 'FlowDefNode'
// },
relations: [
flowDefRelationSchema
],
nodes: [
flowDefNodeSchema
],
createdAt: {
type: Date,
default: Date.now,
get: v => moment(v).format("YYYY-MM-DD HH:mm:ss"),
},
updatedAt: {
type: Date,
default: Date.now,
get: v => moment(v).format("YYYY-MM-DD HH:mm:ss"),
},
del: {
type: Number,
default: 0,
comment: '默认0 , 1:表示删除,若有其他隐藏业务 不要混用此字段。'
}
}, {
id: false,
toJSON: {
getters: true,
}
});
const FlowDef = mongoose.model('FlowDef', flowDefSchema, 'systemFlowDef');
module.exports = FlowDef;
\ No newline at end of file
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const moment = require('moment');
/**
* 流程节点: relation node
*/
const flowDefNodeSchema = new Schema({
name: {
type: String,
comment: "节点名称"
},
key: {
type: String,
comment: "节点唯一标识"
},
handlerRole: {
type: mongoose.Types.ObjectId,
comment: "处理角色"
},
// conditions actions 有待扩展
createdAt: {
type: Date,
default: Date.now,
get: v => moment(v).format("YYYY-MM-DD HH:mm:ss"),
},
updatedAt: {
type: Date,
default: Date.now,
get: v => moment(v).format("YYYY-MM-DD HH:mm:ss"),
},
del: {
type: Number,
default: 0,
comment: '默认0 , 1:表示删除,若有其他隐藏业务 不要混用此字段。'
}
}, {
id: false,
toJSON: {
getters: true,
}
});
// flowDefNodeSchema.index({ _id: 1, key: 1 }, { unique: true })
// const FlowDefNode = mongoose.model('FlowDefNode', flowDefNodeSchema, 'systemFlowDefNode');
// module.exports = FlowDefNode;
module.exports = flowDefNodeSchema;
\ No newline at end of file
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const moment = require('moment');
/**
* 流程节点: relation node
*/
const flowDefRelationSchema = new Schema({
name: {
type: String,
comment: "连线名称"
},
preNode: {
type: mongoose.Types.ObjectId,
comment: "前置节点",
required: true,
},
postNode: {
type: mongoose.Types.ObjectId,
comment: "后置节点",
required: true,
},
// conditions actions 有待扩展
createdAt: {
type: Date,
default: Date.now,
get: v => moment(v).format("YYYY-MM-DD HH:mm:ss"),
},
updatedAt: {
type: Date,
default: Date.now,
get: v => moment(v).format("YYYY-MM-DD HH:mm:ss"),
},
del: {
type: Number,
default: 0,
comment: '默认0 , 1:表示删除,若有其他隐藏业务 不要混用此字段。'
}
}, {
id: false,
toJSON: {
getters: true,
}
});
// const FlowDefRelation = mongoose.model('FlowDefRelation', flowDefRelationSchema, 'systemFlowDefRelation');
// module.exports = FlowDefRelation;
module.exports = flowDefRelationSchema;
\ No newline at end of file
......@@ -3,10 +3,27 @@ const express = require('express');
const router = express.Router();
const agrInputRecordController = require('../controller/agrInputRecordController');
const agrMatController = require('../controller/agrMatController');
router.post('/input/list', agrInputRecordController.list);
// router.post('/create', agrInputRecordController.create);
// router.post('/update', fileController.update);
// router.post('/upload', fileController.list);
/**
* 农资
*/
router.post('/mat/approval/list', agrMatController.queryMatApprList); //获取农资审批记录列表
router.post('/mat/approval/save', agrMatController.saveMatAppr); //获取农资审批记录列表
/**
* 农资类型
*/
router.post('/mat/type/create', agrMatController.createMatType);
router.post('/mat/type/delete', agrMatController.deleteMatType);
router.post('/mat/type/update', agrMatController.updateMatType);
router.post('/mat/type/list', agrMatController.queryMatType);
module.exports = router;
\ No newline at end of file
......@@ -13,10 +13,11 @@ const fileController = require('../controller/fileController');
const storage = multer.diskStorage({
destination: function (req, file, cb) {
if (sysConfig.file.storagePath && !fs.existsSync(sysConfig.file.storagePath)) {
fs.mkdirSync(sysConfig.file.storagePath, { recursive: true });
let path = sysConfig.file.storagePath + '/' + moment().format('YYYYMMDD');
if (!fs.existsSync(path)) {
fs.mkdirSync(path, { recursive: true });
}
cb(null, sysConfig.file.storagePath);
cb(null, path);
},
filename: function (req, file, cb) {
let ext = path.extname(file.originalname); // 获取文件扩展名
......@@ -40,6 +41,6 @@ router.post('/batch/upload', upload.array('files'), fileController.batchUpload);
/**
* excel导出
*/
router.post('/importExcel', upload.single('file'), fileController.importExcel);
router.post('/:modelName/importExcel', upload.single('file'), fileController.importExcel);
module.exports = router;
\ No newline at end of file
const express = require('express');
const router = express.Router();
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const moment = require('moment');
const mongoose = require('mongoose');
const flowDefController = require('../controller/flowDefController');
/**
* 流程结构
*/
router.post('/flowDef/update', flowDefController.updateFlowDef);
module.exports = router;
\ No newline at end of file
......@@ -16,6 +16,8 @@ const zoneRouter = require('./zoneRouter');
const agrInputRouter = require('./agrRouter');
const statisticsRouter = require('./statisticsRouter');
const flowRouter = require('./flowRouter');
const initController = require('../controller/initController')
router.post('/init', initController.init); // 后续删除
......@@ -39,6 +41,9 @@ router.use('/agr', agrInputRouter); // 农业投入品相关
router.use('/statistics', statisticsRouter); // 统计 大屏
router.use('/flow', flowRouter);
......
......@@ -37,7 +37,8 @@ app.use(compress());
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
console.log(__dirname)
app.use(express.static(sysConfig.file.storagePath));
app.use(`/${sysConfig.file.storagePath}`, express.static(sysConfig.file.storagePath)); //保证 local:3000 + path
app.use(express.static('public'));
app.use(logger('dev'));
......
......@@ -7,6 +7,10 @@ module.exports = {
code: 40002,
message: "资源不存在"
},
nameDuplicated: {
code: 40003,
message: "名称重复"
},
databaseQueryError: {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment