明树Git Lab
Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
J
jt_backend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zengfanpei
jt_backend
Commits
a38757d2
Commit
a38757d2
authored
Dec 02, 2025
by
zhangqi
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dev' of gitlab.bridata.com:zengfanpei/jt_backend into dev
parents
300455a8
6ce89f36
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
320 additions
and
88 deletions
+320
-88
a.js
a.js
+92
-25
projectController.js
controller/projectController.js
+122
-29
resourceController.js
controller/resourceController.js
+2
-2
project.js
db/model/jt/project.js
+7
-3
projectXmtzze.js
db/model/jt/projectXmtzze.js
+6
-6
flowRecord.js
db/model/system/flowRecord.js
+2
-2
roleMenu.js
db/model/system/roleMenu.js
+2
-2
userModule.js
module/userModule.js
+1
-1
projectRouter.js
router/projectRouter.js
+3
-1
index.js
utils/index.js
+83
-17
No files found.
a.js
View file @
a38757d2
function
flattenTree
(
forest
)
{
function
flattenTree
(
forest
,
idDes
=
'id'
,
parentIdDes
=
'parentId'
)
{
const
result
=
[];
const
result
=
[];
/**
/**
* 递归处理节点
* 递归处理节点
* @param {Object} node - 当前节点
* @param {Object} node - 当前节点
...
@@ -9,49 +9,82 @@ function flattenTree(forest) {
...
@@ -9,49 +9,82 @@ function flattenTree(forest) {
function
traverse
(
node
,
parentId
)
{
function
traverse
(
node
,
parentId
)
{
// 创建节点副本避免修改原数据
// 创建节点副本避免修改原数据
const
nodeCopy
=
{
...
node
};
const
nodeCopy
=
{
...
node
};
// 添加parentId属性
// 添加parentId属性
nodeCopy
.
parentId
=
parentId
;
nodeCopy
[
parentIdDes
]
=
parentId
;
// 移除children属性(使用正确拼写)
// 移除children属性(使用正确拼写)
delete
nodeCopy
.
children
;
delete
nodeCopy
.
children
;
// 添加当前节点到结果集
// 添加当前节点到结果集
result
.
push
(
nodeCopy
);
result
.
push
(
nodeCopy
);
// 处理子节点(兼容chilrden拼写错误)
// 处理子节点(兼容chilrden拼写错误)
const
children
=
node
.
chilrden
||
node
.
children
||
[];
const
children
=
node
.
chilrden
||
node
.
children
||
[];
for
(
const
child
of
children
)
{
for
(
const
child
of
children
)
{
traverse
(
child
,
node
.
id
);
traverse
(
child
,
node
[
idDes
]);
}
}
}
}
// 遍历森林中的每棵树
// 遍历森林中的每棵树
for
(
const
tree
of
forest
)
{
for
(
const
tree
of
forest
)
{
traverse
(
tree
,
null
);
// 根节点parentId为null
traverse
(
tree
,
null
);
// 根节点parentId为null
}
}
return
result
;
return
result
;
}
}
// 扩展测试:包含额外字段和标准children字段
// 扩展测试:包含额外字段和标准children字段
const
complexForest
=
[
let
complexForest
=
[
{
xh
:
"1"
,
zb
:
"项目资本金"
,
dw
:
"万元"
,
children
:
[
{
xh
:
"1.1"
,
zb
:
"能建方出资"
,
dw
:
"万元"
},
{
xh
:
"1.2"
,
zb
:
"外部股东"
,
dw
:
"万元"
}
]
},
{
{
id
:
'A'
,
xh
:
"2"
,
name
:
'Root A'
,
zb
:
"贷款"
,
chilrden
:
[
dw
:
"万元"
,
{
id
:
'A1'
,
value
:
100
},
children
:
[
{
id
:
'A2'
,
value
:
200
,
children
:
[{
id
:
'A2a'
}]
}
{
xh
:
"2.1"
,
zb
:
"其中:并非表项目我方贷款/投保额"
,
dw
:
"万元"
}
]
]
},
},
{
{
id
:
'B'
,
xh
:
"3"
,
name
:
'Root B'
,
zb
:
"其他出资"
,
children
:
[{
id
:
'B1'
}]
dw
:
"万元"
,
children
:
[
{
xh
:
"3.1"
,
zb
:
"其中:能建方出资"
,
dw
:
"万元"
}
]
},
{
xh
:
""
,
zb
:
"批复总出资"
,
dw
:
"万元"
}
}
]
;
]
console
.
log
(
flattenTree
(
complexForest
));
console
.
log
(
flattenTree
(
complexForest
,
'xh'
,
'parentXh'
));
/* 输出:
/* 输出:
[
[
{ id: 'A', name: 'Root A', parentId: null },
{ id: 'A', name: 'Root A', parentId: null },
...
@@ -61,4 +94,38 @@ console.log(flattenTree(complexForest));
...
@@ -61,4 +94,38 @@ console.log(flattenTree(complexForest));
{ id: 'B', name: 'Root B', parentId: null },
{ id: 'B', name: 'Root B', parentId: null },
{ id: 'B1', parentId: 'B' }
{ id: 'B1', parentId: 'B' }
]
]
*/
*/
\ No newline at end of file
const
_
=
require
(
'lodash'
);
function
buildTree
(
nodes
,
keyid
=
'id'
,
keyParentId
=
'parentId'
)
{
// 创建一个映射,将节点ID映射到节点对象
const
nodeMap
=
new
Map
(
nodes
.
map
(
node
=>
[
String
(
node
[
keyid
]),
{
...
node
,
children
:
[]
}]));
// 遍历所有节点,并将它们添加到对应父节点的children数组中
nodes
.
forEach
(
node
=>
{
const
parentId
=
String
(
node
[
keyParentId
]);
if
(
parentId
!==
null
)
{
// 确保父节点在映射中存在
if
(
nodeMap
.
has
(
parentId
))
{
// 将当前节点添加到父节点的children数组中
nodeMap
.
get
(
parentId
).
children
.
push
(
nodeMap
.
get
(
String
(
node
[
keyid
])));
nodeMap
.
get
(
parentId
).
children
=
_
.
orderBy
(
nodeMap
.
get
(
parentId
).
children
,
'order'
)
}
}
});
// 从映射中提取顶级节点(parentId为null)
return
_
.
orderBy
(
Array
.
from
(
nodeMap
.
values
()).
filter
(
node
=>
node
[
keyParentId
]
==
null
),
'order'
);
}
console
.
log
(
JSON
.
stringify
(
buildTree
([
{
xh
:
'1'
,
zb
:
'项目资本金'
,
dw
:
'万元'
,
parentXh
:
null
},
{
xh
:
'1.1'
,
zb
:
'能建方出资'
,
dw
:
'万元'
,
parentXh
:
'1'
},
{
xh
:
'1.2'
,
zb
:
'外部股东'
,
dw
:
'万元'
,
parentXh
:
'1'
},
{
xh
:
'2'
,
zb
:
'贷款'
,
dw
:
'万元'
,
parentXh
:
null
},
{
xh
:
'2.1'
,
zb
:
'其中:并非表项目我方贷款/投保额'
,
dw
:
'万元'
,
parentXh
:
'2'
},
{
xh
:
'3'
,
zb
:
'其他出资'
,
dw
:
'万元'
,
parentXh
:
null
},
{
xh
:
'3.1'
,
zb
:
'其中:能建方出资'
,
dw
:
'万元'
,
parentXh
:
'3'
},
{
xh
:
''
,
zb
:
'批复总出资'
,
dw
:
'万元'
,
parentXh
:
null
}
],
'xh'
,
'parentXh'
)))
[{
"xh"
:
"1"
,
"zb"
:
"项目资本金"
,
"dw"
:
"万元"
,
"parentXh"
:
null
,
"children"
:
[{
"xh"
:
"1.1"
,
"zb"
:
"能建方出资"
,
"dw"
:
"万元"
,
"parentXh"
:
"1"
,
"children"
:
[]
},
{
"xh"
:
"1.2"
,
"zb"
:
"外部股东"
,
"dw"
:
"万元"
,
"parentXh"
:
"1"
,
"children"
:
[]
}]
},
{
"xh"
:
"2"
,
"zb"
:
"贷款"
,
"dw"
:
"万元"
,
"parentXh"
:
null
,
"children"
:
[{
"xh"
:
"2.1"
,
"zb"
:
"其中:并非表项目我方贷款/投保额"
,
"dw"
:
"万元"
,
"parentXh"
:
"2"
,
"children"
:
[]
}]
},
{
"xh"
:
"3"
,
"zb"
:
"其他出资"
,
"dw"
:
"万元"
,
"parentXh"
:
null
,
"children"
:
[{
"xh"
:
"3.1"
,
"zb"
:
"其中:能建方出资"
,
"dw"
:
"万元"
,
"parentXh"
:
"3"
,
"children"
:
[]
}]
},
{
"xh"
:
""
,
"zb"
:
"批复总出资"
,
"dw"
:
"万元"
,
"parentXh"
:
null
,
"children"
:
[]
}]
\ No newline at end of file
controller/projectController.js
View file @
a38757d2
This diff is collapsed.
Click to expand it.
controller/resourceController.js
View file @
a38757d2
...
@@ -13,7 +13,7 @@ async function createResource(req, res, next) {
...
@@ -13,7 +13,7 @@ async function createResource(req, res, next) {
ret
=
ret
.
toJSON
();
ret
=
ret
.
toJSON
();
console
.
log
(
ret
);
console
.
log
(
ret
);
if
(
body
.
resourceInfos
&&
body
.
resourceInfos
.
length
&&
ret
.
id
)
{
if
(
body
.
resourceInfos
&&
body
.
resourceInfos
.
length
&&
ret
.
id
)
{
if
(
type
==
1
){
if
(
body
.
type
==
1
){
let
ris
=
[];
let
ris
=
[];
for
(
let
index
=
0
;
index
<
body
.
resourceInfos
.
length
;
index
++
)
{
for
(
let
index
=
0
;
index
<
body
.
resourceInfos
.
length
;
index
++
)
{
const
element
=
body
.
resourceInfos
[
index
];
const
element
=
body
.
resourceInfos
[
index
];
...
@@ -22,7 +22,7 @@ async function createResource(req, res, next) {
...
@@ -22,7 +22,7 @@ async function createResource(req, res, next) {
}
}
console
.
log
(
ris
,
"==="
)
console
.
log
(
ris
,
"==="
)
await
DB
.
ResourcesInfo
.
bulkCreate
(
ris
);
await
DB
.
ResourcesInfo
.
bulkCreate
(
ris
);
}
else
if
(
type
==
2
)
{
}
else
if
(
body
.
type
==
2
)
{
//树结构
//树结构
let
ris
=
[];
let
ris
=
[];
let
data
=
utils
.
flattenTreeIterative
(
body
.
resourceInfos
);
let
data
=
utils
.
flattenTreeIterative
(
body
.
resourceInfos
);
...
...
db/model/jt/project.js
View file @
a38757d2
...
@@ -23,7 +23,11 @@ const Project = sequelize.define('Project', {
...
@@ -23,7 +23,11 @@ const Project = sequelize.define('Project', {
},
},
projectLiuZhuanType
:
{
projectLiuZhuanType
:
{
type
:
DataTypes
.
STRING
,
type
:
DataTypes
.
STRING
,
comment
:
"项目流转状态 1. 待初审、3 待初审、1初审退回、5待终审、1终审退回、7待立项审批、立项审批退回、已立项、已暂停、已结束等"
,
comment
:
"项目流转状态 1. 待提交、3 待初审、1初审退回、5待终审、1终审退回、7待立项审批、立项审批退回、已立项、已暂停、已结束等"
,
},
projectLiuZhuanTypeDes
:
{
type
:
DataTypes
.
STRING
,
comment
:
"项目流转状态说明 待提交 待初审 初审退回 待终审 终审退回 待立项审批 立项审批退回 已立项 已结束等"
,
},
},
/**
/**
* 项目基本信息
* 项目基本信息
...
@@ -1765,9 +1769,9 @@ const Project = sequelize.define('Project', {
...
@@ -1765,9 +1769,9 @@ const Project = sequelize.define('Project', {
// 同步模型到数据库(创建表)
// 同步模型到数据库(创建表)
Project
.
sync
({
Project
.
sync
({
//
force: false,
force
:
false
,
// force: true ,//会删除已存在表并重新创建
// force: true ,//会删除已存在表并重新创建
alter
:
true
//
alter: true
})
})
.
then
(()
=>
{
.
then
(()
=>
{
console
.
log
(
'Project 表同步成功'
);
console
.
log
(
'Project 表同步成功'
);
...
...
db/model/jt/projectXmtzze.js
View file @
a38757d2
...
@@ -29,10 +29,10 @@ const ProjectXmtzze = sequelize.define('ProjectXmtzze', {
...
@@ -29,10 +29,10 @@ const ProjectXmtzze = sequelize.define('ProjectXmtzze', {
type
:
DataTypes
.
DECIMAL
(
20
,
4
),
type
:
DataTypes
.
DECIMAL
(
20
,
4
),
comment
:
"人民币计价"
comment
:
"人民币计价"
},
},
// parentId
: {
parentXh
:
{
// type: DataTypes.INTEGER
,
type
:
DataTypes
.
STRING
,
//
comment: "上级ID"
comment
:
"上级ID"
//
},
},
projectId
:
{
projectId
:
{
type
:
DataTypes
.
INTEGER
,
type
:
DataTypes
.
INTEGER
,
...
@@ -67,9 +67,9 @@ const ProjectXmtzze = sequelize.define('ProjectXmtzze', {
...
@@ -67,9 +67,9 @@ const ProjectXmtzze = sequelize.define('ProjectXmtzze', {
// 同步模型到数据库(创建表)
// 同步模型到数据库(创建表)
ProjectXmtzze
.
sync
({
ProjectXmtzze
.
sync
({
force
:
false
,
//
force: false,
// force: true ,//会删除已存在表并重新创建
// force: true ,//会删除已存在表并重新创建
//
alter: true
alter
:
true
})
})
.
then
(()
=>
{
.
then
(()
=>
{
console
.
log
(
'ProjectXmtzze 表同步成功'
);
console
.
log
(
'ProjectXmtzze 表同步成功'
);
...
...
db/model/system/flowRecord.js
View file @
a38757d2
...
@@ -35,13 +35,13 @@ const flowRecord = sequelize.define('flowRecord', {
...
@@ -35,13 +35,13 @@ const flowRecord = sequelize.define('flowRecord', {
comment
:
"0 正常 1 删除"
comment
:
"0 正常 1 删除"
},
},
},
{
},
{
tableName
:
'system_
user
'
,
// 指定表名(如果与模型名不同)
tableName
:
'system_
flowrecord
'
,
// 指定表名(如果与模型名不同)
timestamps
:
true
,
// 是否自动添加 createdAt 和 updatedAt 字段(覆盖全局设置)
timestamps
:
true
,
// 是否自动添加 createdAt 和 updatedAt 字段(覆盖全局设置)
});
});
// 同步模型到数据库(创建表)
// 同步模型到数据库(创建表)
flowRecord
.
sync
({
flowRecord
.
sync
({
//
force: false,
force
:
false
,
// force: true ,//会删除已存在表并重新创建
// force: true ,//会删除已存在表并重新创建
// alter: true
// alter: true
})
})
...
...
db/model/system/roleMenu.js
View file @
a38757d2
...
@@ -26,8 +26,8 @@ const RoleMenu = sequelize.define('RoleMenu', {
...
@@ -26,8 +26,8 @@ const RoleMenu = sequelize.define('RoleMenu', {
// 同步模型到数据库(创建表)
// 同步模型到数据库(创建表)
RoleMenu
.
sync
({
RoleMenu
.
sync
({
//
force: false, // force: true 会删除已存在表并重新创建
force
:
false
,
// force: true 会删除已存在表并重新创建
alter
:
true
//
alter: true
})
})
.
then
(()
=>
{
.
then
(()
=>
{
console
.
log
(
'RoleMenu 表同步成功'
);
console
.
log
(
'RoleMenu 表同步成功'
);
...
...
module/userModule.js
View file @
a38757d2
...
@@ -134,7 +134,7 @@ async function getProjectApprover(userId, roleCode) {
...
@@ -134,7 +134,7 @@ async function getProjectApprover(userId, roleCode) {
// 获取当前用户公司的 具体角色 的用户列表
// 获取当前用户公司的 具体角色 的用户列表
let
user
=
await
DB
.
User
.
findOne
({
where
:
{
id
:
userId
}
});
let
user
=
await
DB
.
User
.
findOne
({
where
:
{
id
:
userId
}
});
return
[];
return
[
user
];
}
}
module
.
exports
=
{
module
.
exports
=
{
...
...
router/projectRouter.js
View file @
a38757d2
...
@@ -18,7 +18,9 @@ router.post('/getProjectFields', projectController.getProjectFields);
...
@@ -18,7 +18,9 @@ router.post('/getProjectFields', projectController.getProjectFields);
router
.
post
(
'/exportExcel'
,
projectController
.
exportExcel
);
router
.
post
(
'/exportExcel'
,
projectController
.
exportExcel
);
router
.
post
(
'/preJugProject'
,
projectController
.
preJugProject
);
//初审
router
.
post
(
'/preJugProject'
,
projectController
.
preJugProject
);
//初审
router
.
post
(
'/finalJugProject'
,
projectController
.
finalJugProject
);
//终审
router
.
post
(
'/finalJugProject'
,
projectController
.
finalJugProject
);
//终审 --暂时没有
router
.
post
(
'/getOwnProjects'
,
projectController
.
getOwnProjects
);
...
...
utils/index.js
View file @
a38757d2
...
@@ -68,22 +68,87 @@ function disTree(tree) {
...
@@ -68,22 +68,87 @@ function disTree(tree) {
// 迭代替代递归(万级以上节点)
// 迭代替代递归(万级以上节点)
function
flattenTreeIterative
(
forest
)
{
function
flattenTreeIterative
(
forest
)
{
const
result
=
[];
const
result
=
[];
const
stack
=
[...
forest
.
map
(
node
=>
({
node
,
parentId
:
null
}))];
const
stack
=
[...
forest
.
map
(
node
=>
({
node
,
parentId
:
null
}))];
while
(
stack
.
length
)
{
while
(
stack
.
length
)
{
const
{
node
,
parentId
}
=
stack
.
pop
();
const
{
node
,
parentId
}
=
stack
.
pop
();
const
{
chilrden
,
children
,
...
rest
}
=
node
;
const
{
chilrden
,
children
,
...
rest
}
=
node
;
result
.
push
({
...
rest
,
parentId
});
result
.
push
({
...
rest
,
parentId
});
const
kids
=
chilrden
||
children
||
[];
const
kids
=
chilrden
||
children
||
[];
for
(
let
i
=
kids
.
length
-
1
;
i
>=
0
;
i
--
)
{
for
(
let
i
=
kids
.
length
-
1
;
i
>=
0
;
i
--
)
{
stack
.
push
({
node
:
kids
[
i
],
parentId
:
node
.
id
});
stack
.
push
({
node
:
kids
[
i
],
parentId
:
node
.
id
});
}
}
return
result
;
}
/**
* 把带有chilrden的推平
* @param {*} forest
* @param {*} idDes
* @param {*} parentIdDes
* @returns
*/
function
flattenTree
(
forest
,
idDes
=
'id'
,
parentIdDes
=
'parentId'
)
{
const
result
=
[];
/**
* 递归处理节点
* @param {Object} node - 当前节点
* @param {string|null} parentId - 父节点ID
*/
function
traverse
(
node
,
parentId
)
{
// 创建节点副本避免修改原数据
const
nodeCopy
=
{
...
node
};
// 添加parentId属性
nodeCopy
[
parentIdDes
]
=
parentId
;
// 移除children属性(使用正确拼写)
delete
nodeCopy
.
children
;
// 添加当前节点到结果集
result
.
push
(
nodeCopy
);
// 处理子节点(兼容chilrden拼写错误)
const
children
=
node
.
chilrden
||
node
.
children
||
[];
for
(
const
child
of
children
)
{
traverse
(
child
,
node
[
idDes
]);
}
}
}
}
// 遍历森林中的每棵树
return
result
;
for
(
const
tree
of
forest
)
{
traverse
(
tree
,
null
);
// 根节点parentId为null
}
return
result
;
}
//
function
buildTree2
(
nodes
,
keyid
=
'id'
,
keyParentId
=
'parentId'
)
{
// 创建一个映射,将节点ID映射到节点对象
const
nodeMap
=
new
Map
(
nodes
.
map
(
node
=>
[
String
(
node
[
keyid
]),
{
...
node
,
children
:
[]
}]));
// 遍历所有节点,并将它们添加到对应父节点的children数组中
nodes
.
forEach
(
node
=>
{
const
parentId
=
String
(
node
[
keyParentId
]);
if
(
parentId
!==
null
)
{
// 确保父节点在映射中存在
if
(
nodeMap
.
has
(
parentId
))
{
// 将当前节点添加到父节点的children数组中
nodeMap
.
get
(
parentId
).
children
.
push
(
nodeMap
.
get
(
String
(
node
[
keyid
])));
nodeMap
.
get
(
parentId
).
children
=
_
.
orderBy
(
nodeMap
.
get
(
parentId
).
children
,
'order'
)
}
}
});
// 从映射中提取顶级节点(parentId为null)
return
_
.
orderBy
(
Array
.
from
(
nodeMap
.
values
()).
filter
(
node
=>
node
[
keyParentId
]
==
null
),
'order'
);
}
}
...
@@ -92,6 +157,7 @@ module.exports = {
...
@@ -92,6 +157,7 @@ module.exports = {
checkUserPassword
,
checkUserPassword
,
buildTree
,
buildTree
,
disTree
,
disTree
,
flattenTreeIterative
flattenTreeIterative
,
flattenTree
,
buildTree2
,
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment