diff --git a/api/app/lib/controllers/projectBind/projectBind.js b/api/app/lib/controllers/projectManagement/projectBind.js
similarity index 100%
rename from api/app/lib/controllers/projectBind/projectBind.js
rename to api/app/lib/controllers/projectManagement/projectBind.js
diff --git a/api/app/lib/controllers/projectManagement/projectPublish.js b/api/app/lib/controllers/projectManagement/projectPublish.js
new file mode 100644
index 0000000..d6fbabe
--- /dev/null
+++ b/api/app/lib/controllers/projectManagement/projectPublish.js
@@ -0,0 +1,238 @@
+'use strict'
+const moment = require('moment')
+const { QueryTypes } = require('sequelize');
+const Hex = require('crypto-js/enc-hex');
+const MD5 = require('crypto-js/md5');
+
+let axyTokenCache = {
+ token: null,
+ orgId: null,
+ expireTime: null, //过期时间
+}
+
+async function getAnxinyunToken (ctx) {
+ try {
+ if (!axyTokenCache.token || moment() > moment(axyTokenCache.expireTime)) {
+ if (ctx.app.fs.opts.axyProject.split('/').length === 3) {
+ const dataToAxy = {
+ domain: ctx.app.fs.opts.axyProject.split('/')[0],
+ username: ctx.app.fs.opts.axyProject.split('/')[1],
+ password: ctx.app.fs.opts.axyProject.split('/')[2],
+ }
+ const axyResponse = await ctx.app.fs.anxinyun.post('login', { data: dataToAxy })
+ if (axyResponse.authorized) {
+ axyTokenCache.token = axyResponse.token //放进缓存
+ axyTokenCache.orgId = axyResponse.orgId //放进缓存
+ axyTokenCache.expireTime = moment().add(1, 'hour').format('YYYY-MM-DD HH:mm:ss')
+ }
+ }
+ }
+ return axyTokenCache
+ } catch (error) {
+ ctx.fs.logger.error(`sechedule: laborAttendance, error: ${error}`)
+ }
+}
+//调用安心云结构物接口
+async function findAnxinyunProject (ctx, next) {
+ try {
+ let { type, url, params = {} } = ctx.request.body
+ let data = await getAnxinyunToken(ctx)
+ if (url && url.indexOf('{orgId}') != -1) {
+ url = url.replace(`{orgId}`, data.orgId)
+ }
+ const res = await ctx.app.fs.anxinyun[type](`${url}?token=${data.token}`, {
+ data: params.data || {},
+ query: params.query || {},
+ })
+ ctx.status = 200
+ ctx.body = res
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`)
+ ctx.status = 400
+ ctx.body = {
+ message: '查询安心云项目失败',
+ }
+ }
+}
+async function addorEditRelation (ctx, next) {
+ let err = ''
+ const { axyProjectId, structrueId, id } = ctx.request.body
+ try {
+ const models = ctx.fs.dc.models
+ //编辑
+ if (id) {
+ const res = await models.ProjectBind.findOne({ where: { id, axyProjectId, structureId: structrueId } })
+ if (res) {
+ err = '所选安心云结构物和巡检结构物重复!!!'
+ throw '所选安心云结构物和巡检结构物重复!!!'
+ }
+ await models.ProjectBind.update({ axyProjectId, structureId: structrueId }, { where: { id } })
+
+ ctx.status = 204
+ ctx.body = {
+ message: '编辑成功!!',
+ }
+ } else {
+ //新增
+ const res = await models.ProjectBind.findOne({ where: { axyProjectId, structureId: structrueId } })
+ if (res) {
+ err = '所选安心云结构物和巡检结构物重复!!!'
+ throw '所选安心云结构物和巡检结构物重复!!!'
+ }
+ await models.ProjectBind.create({ axyProjectId, structureId: structrueId })
+ ctx.status = 204
+ ctx.body = {
+ message: '新增成功!!',
+ }
+ }
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`)
+ ctx.status = 400
+ ctx.body = {
+ message: err ? err : id ? '编辑失败' : '新增失败',
+ }
+ }
+}
+
+async function getRelationList (ctx, next) {
+ try {
+ const models = ctx.fs.dc.models
+ const { limit, page, startTime, endTime } = ctx.query
+ let options = {
+ where: {},
+ }
+ if (limit) {
+ options.limit = Number(limit)
+ }
+ if (page && limit) {
+ options.offset = Number(page) * Number(limit)
+ }
+ if (startTime && endTime) {
+ options.where.inspectTm = { $between: [startTime, endTime] }
+ }
+ const res = await models.ProjectBind.findAndCountAll(options)
+ ctx.body = res
+ ctx.status = 200
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`)
+ ctx.status = 400
+ ctx.body = {
+ message: '查询关联关系列表失败',
+ }
+ }
+}
+
+async function deleteRelation (ctx, next) {
+ const { id } = ctx.params
+ try {
+ const models = ctx.fs.dc.models
+ const res = await models.ProjectBind.findOne({ where: { id: Number(id) } })
+ if (!res) {
+ throw 'id不存在'
+ }
+ await models.ProjectBind.destroy({ where: { id: Number(id) } })
+ ctx.status = 200
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`)
+ ctx.status = 400
+ ctx.body = {
+ message: '关联关系列表失败',
+ }
+ }
+}
+
+async function getProjectType (ctx, next) {
+ try {
+ const models = ctx.fs.dc.models
+ const sequelize = ctx.fs.dc.orm;
+ const { } = ctx.query
+
+ const res = await sequelize.query(`select distinct type from project`, { type: QueryTypes.SELECT });
+ ctx.body = res
+ ctx.status = 200
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`)
+ ctx.status = 400
+ ctx.body = {
+ message: '获取项目类型失败',
+ }
+ }
+}
+
+async function getProjectPublishList (ctx, next) {
+ try {
+ const models = ctx.fs.dc.models
+ const { limit, page } = ctx.query
+ let options = {
+ where: {},
+ }
+ if (limit) {
+ options.limit = Number(limit)
+ }
+ if (page && limit) {
+ options.offset = Number(page) * Number(limit)
+ }
+
+ const res = await models.ProjectUser.findAndCountAll(options)
+ ctx.body = res
+ ctx.status = 200
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`)
+ ctx.status = 400
+ ctx.body = {
+ message: '获取项目发布列表失败',
+ }
+ }
+}
+
+async function postProjectPublish (ctx, next) {
+ let message = '新增项目失败'
+ try {
+ const models = ctx.fs.dc.models
+ const data = ctx.request.body
+ const { id, password } = data
+
+ if (id) {
+ message = '修改项目失败'
+ await models.ProjectUser.update(data, { where: { id } })
+ } else {
+ let passwords = Hex.stringify(MD5(password));
+ await models.ProjectUser.create({ ...data, password: passwords, del: false })
+ }
+ ctx.status = 204
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`)
+ ctx.status = 400
+ ctx.body = {
+ message: message
+ }
+ }
+}
+
+async function delProjectPublish (ctx, next) {
+ try {
+ const models = ctx.fs.dc.models
+ const { id } = ctx.params
+
+ await models.ProjectUser.destroy({ where: { id } })
+
+ ctx.status = 204
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`)
+ ctx.status = 400
+ ctx.body = {
+ message: '删除项目失败'
+ }
+ }
+}
+
+module.exports = {
+ findAnxinyunProject,
+ addorEditRelation,
+ getRelationList,
+ deleteRelation,
+ getProjectType,
+ getProjectPublishList,
+ postProjectPublish,
+ delProjectPublish
+}
diff --git a/api/app/lib/controllers/projectRegime/projectSituation.js b/api/app/lib/controllers/projectRegime/projectSituation.js
index ab59626..65e0adc 100644
--- a/api/app/lib/controllers/projectRegime/projectSituation.js
+++ b/api/app/lib/controllers/projectRegime/projectSituation.js
@@ -3,11 +3,11 @@ const request = require('superagent');
const fs = require('fs');
const path = require('path');
-async function projectList(ctx, next) {
+async function projectList (ctx, next) {
try {
const models = ctx.fs.dc.models;
let userInfo = ctx.fs.api.userInfo;
- const { limit, page, name, justStructure } = ctx.query;
+ const { limit, page, name, type, justStructure } = ctx.query;
let options = {
where: {
@@ -28,16 +28,19 @@ async function projectList(ctx, next) {
if (name) {
options.where.name = { $like: `%${name}%` }
}
-
- let res = []
+ if (name) {
+ options.where.name = { $like: `%${name}%` }
+ }
+ if (type) {
+ options.where.type = type
+ }
if (justStructure) {
- res = await models.Project.findAndCountAll({
- attributes: ['id', 'name'],
- })
- } else {
- res = await models.Project.findAndCountAll(options)
+ options.attributes = ['id', 'name','type']
}
+ let res = await models.Project.findAndCountAll(options)
+
+
ctx.status = 200;
ctx.body = res
} catch (error) {
@@ -50,8 +53,8 @@ async function projectList(ctx, next) {
}
-async function postAddProject(ctx, next) {
- let errMsg = ''
+async function postAddProject (ctx, next) {
+ let errMsg = ''
try {
const models = ctx.fs.dc.models;
let userInfo = ctx.fs.api.userInfo;
@@ -92,7 +95,7 @@ async function postAddProject(ctx, next) {
}
}
-async function delProject(ctx, next) {
+async function delProject (ctx, next) {
try {
const models = ctx.fs.dc.models;
let userInfo = ctx.fs.api.userInfo;
@@ -160,7 +163,7 @@ let wxAccessToken = {
time: null
}
-async function addPosition(ctx, next) {
+async function addPosition (ctx, next) {
try {
const models = ctx.fs.dc.models;
let userInfo = ctx.fs.api.userInfo;
@@ -253,7 +256,7 @@ async function addPosition(ctx, next) {
}
}
-async function position(ctx, next) {
+async function position (ctx, next) {
try {
const models = ctx.fs.dc.models;
let userInfo = ctx.fs.api.userInfo;
@@ -293,7 +296,7 @@ async function position(ctx, next) {
}
}
-async function delPosition(ctx, next) {
+async function delPosition (ctx, next) {
try {
const models = ctx.fs.dc.models;
let userInfo = ctx.fs.api.userInfo;
@@ -377,7 +380,7 @@ async function delPosition(ctx, next) {
}
-async function qrCodeShow(ctx, next) {
+async function qrCodeShow (ctx, next) {
try {
const models = ctx.fs.dc.models;
let userInfo = ctx.fs.api.userInfo;
@@ -408,7 +411,7 @@ async function qrCodeShow(ctx, next) {
}
-async function q(ctx) {
+async function q (ctx) {
// let error = {
// name: 'FindError',
// message: "获取失败!"
diff --git a/api/app/lib/models/project_user.js b/api/app/lib/models/project_user.js
new file mode 100644
index 0000000..4fca949
--- /dev/null
+++ b/api/app/lib/models/project_user.js
@@ -0,0 +1,105 @@
+/* eslint-disable*/
+'use strict';
+
+module.exports = dc => {
+ const DataTypes = dc.ORM;
+ const sequelize = dc.orm;
+ const ProjectUser = sequelize.define("projectUser", {
+ id: {
+ type: DataTypes.INTEGER,
+ allowNull: false,
+ defaultValue: null,
+ comment: null,
+ primaryKey: true,
+ field: "id",
+ autoIncrement: true
+ },
+ projectName: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ defaultValue: null,
+ comment: '项目名称',
+ primaryKey: false,
+ field: "project_name",
+ autoIncrement: false
+ },
+ projectDescribe: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ defaultValue: null,
+ comment: "项目描述",
+ primaryKey: false,
+ field: "project_describe",
+ autoIncrement: false
+ },
+ projectType: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ defaultValue: null,
+ comment: '项目类型',
+ primaryKey: false,
+ field: "project_type",
+ autoIncrement: false
+ },
+ monitorObject: {
+ type: DataTypes.ARRAY(DataTypes.INTEGER),
+ allowNull: false,
+ defaultValue: null,
+ comment: "监测对象",
+ primaryKey: false,
+ field: "monitor_object",
+ autoIncrement: false
+ },
+ account: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ defaultValue: null,
+ comment: '发布账号',
+ primaryKey: false,
+ field: "account",
+ autoIncrement: false
+ },
+ password: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ defaultValue: null,
+ comment: "发布密码",
+ primaryKey: false,
+ field: "password",
+ autoIncrement: false
+ },
+ createTime: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ defaultValue: null,
+ comment: '创建时间',
+ primaryKey: false,
+ field: "create_time",
+ autoIncrement: false
+ },
+ code: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ defaultValue: null,
+ comment: "p",
+ primaryKey: false,
+ field: "code",
+ autoIncrement: false
+ },
+ del: {
+ type: DataTypes.BOOLEAN,
+ allowNull: false,
+ defaultValue: null,
+ comment: "",
+ primaryKey: false,
+ field: "del",
+ autoIncrement: false
+ }
+ }, {
+ tableName: "project_user",
+ comment: "",
+ indexes: []
+ });
+ dc.models.ProjectUser = ProjectUser;
+ return ProjectUser;
+};
\ No newline at end of file
diff --git a/api/app/lib/models/project_user_token.js b/api/app/lib/models/project_user_token.js
new file mode 100644
index 0000000..8cf509a
--- /dev/null
+++ b/api/app/lib/models/project_user_token.js
@@ -0,0 +1,43 @@
+/* eslint-disable*/
+'use strict';
+
+module.exports = dc => {
+ const DataTypes = dc.ORM;
+ const sequelize = dc.orm;
+ const ProjectUserToken = sequelize.define("projectUserToken", {
+ token: {
+ type: DataTypes.UUIDV4,
+ allowNull: false,
+ defaultValue: null,
+ comment: null,
+ primaryKey: true,
+ field: "token",
+ autoIncrement: false,
+ unique: "project_user_token_uindex"
+ },
+ projectUserInfo: {
+ type: DataTypes.JSONB,
+ allowNull: false,
+ defaultValue: null,
+ comment: null,
+ primaryKey: false,
+ field: "project_user_info",
+ autoIncrement: false
+ },
+ expired: {
+ type: DataTypes.DATE,
+ allowNull: false,
+ defaultValue: null,
+ comment: null,
+ primaryKey: false,
+ field: "expired",
+ autoIncrement: false
+ }
+ }, {
+ tableName: "project_user_token",
+ comment: "",
+ indexes: []
+ });
+ dc.models.ProjectUserToken = ProjectUserToken;
+ return ProjectUserToken;
+};
\ No newline at end of file
diff --git a/api/app/lib/routes/projectBind/index.js b/api/app/lib/routes/projectBind/index.js
deleted file mode 100644
index 6498b44..0000000
--- a/api/app/lib/routes/projectBind/index.js
+++ /dev/null
@@ -1,19 +0,0 @@
-'use strict';
-
-const projectBind = require('../../controllers/projectBind/projectBind');
-
-module.exports = function (app, router, opts) {
-
- app.fs.api.logAttr['POST/anxinyun/project/list'] = { content: '获取安心云项目列表', visible: false }
- router.post('/anxinyun/project/list', projectBind.findAnxinyunProject)
-
- app.fs.api.logAttr['POST/anxinyun/project/relation'] = { content: '新增或编辑项目映射关系', visible: false }
- router.post('/anxinyun/project/relation', projectBind.addorEditRelation)
-
- app.fs.api.logAttr['GET/anxinyun/project/relation/list'] = { content: '获取项目映射关系列表', visible: false }
- router.get('/anxinyun/project/relation/list', projectBind.getRelationList)
-
- app.fs.api.logAttr['DELETE/anxinyun/project/relation/:id'] = { content: '删除项目映射关系', visible: false }
- router.delete('/anxinyun/project/relation/:id', projectBind.deleteRelation)
-
-}
\ No newline at end of file
diff --git a/api/app/lib/routes/projectManagement/index.js b/api/app/lib/routes/projectManagement/index.js
new file mode 100644
index 0000000..0cfdebf
--- /dev/null
+++ b/api/app/lib/routes/projectManagement/index.js
@@ -0,0 +1,33 @@
+'use strict';
+
+const projectBind = require('../../controllers/projectManagement/projectBind');
+const projectPublish = require('../../controllers/projectManagement/projectPublish');
+
+module.exports = function (app, router, opts) {
+
+ app.fs.api.logAttr['POST/anxinyun/project/list'] = { content: '获取安心云项目列表', visible: false }
+ router.post('/anxinyun/project/list', projectBind.findAnxinyunProject)
+
+ app.fs.api.logAttr['POST/anxinyun/project/relation'] = { content: '新增或编辑项目映射关系', visible: false }
+ router.post('/anxinyun/project/relation', projectBind.addorEditRelation)
+
+ app.fs.api.logAttr['GET/anxinyun/project/relation/list'] = { content: '获取项目映射关系列表', visible: false }
+ router.get('/anxinyun/project/relation/list', projectBind.getRelationList)
+
+ app.fs.api.logAttr['DELETE/anxinyun/project/relation/:id'] = { content: '删除项目映射关系', visible: false }
+ router.delete('/anxinyun/project/relation/:id', projectBind.deleteRelation)
+
+ app.fs.api.logAttr['GET/project/type'] = { content: '获取项目类型', visible: false }
+ router.get('/project/type', projectPublish.getProjectType)
+
+ app.fs.api.logAttr['GET/project/publish/list'] = { content: '获取项目发布列表', visible: false }
+ router.get('/project/publish/list', projectPublish.getProjectPublishList)
+
+ app.fs.api.logAttr['POST/project/publish/list'] = { content: '新增或编辑项目', visible: false }
+ router.post('/project/publish/list', projectPublish.postProjectPublish)
+
+ app.fs.api.logAttr['DEL/project/publish/:id'] = { content: '删除项目', visible: false }
+ router.del('/project/publish/:id', projectPublish.delProjectPublish)
+
+
+}
\ No newline at end of file
diff --git a/api/log/development.log b/api/log/development.log
index ac0f02f..ccf9c44 100644
--- a/api/log/development.log
+++ b/api/log/development.log
@@ -4328,3 +4328,55 @@ notNull Violation: PatrolPlan.patrolCount cannot be null
2024-01-08 14:28:04.506 - info: [FS-ATTACHMENT] Inject attachment mw into router.
2024-01-08 14:28:04.506 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
2024-01-08 14:28:04.507 - info: [FS-AUTH] Inject auth and api mv into router.
+2024-01-09 10:59:44.815 - debug: [FS-LOGGER] Init.
+2024-01-09 10:59:46.192 - info: [FS-ATTACHMENT] Inject attachment mw into router.
+2024-01-09 10:59:46.192 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
+2024-01-09 10:59:46.194 - info: [FS-AUTH] Inject auth and api mv into router.
+2024-01-09 11:01:09.444 - error: path: /project/type, error: ReferenceError: constres is not defined
+2024-01-09 11:02:25.623 - debug: [FS-LOGGER] Init.
+2024-01-09 11:02:25.975 - info: [FS-ATTACHMENT] Inject attachment mw into router.
+2024-01-09 11:02:25.975 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
+2024-01-09 11:02:25.976 - info: [FS-AUTH] Inject auth and api mv into router.
+2024-01-09 11:25:49.079 - debug: [FS-LOGGER] Init.
+2024-01-09 11:25:49.379 - info: [FS-ATTACHMENT] Inject attachment mw into router.
+2024-01-09 11:25:49.379 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
+2024-01-09 11:25:49.380 - info: [FS-AUTH] Inject auth and api mv into router.
+2024-01-09 11:31:01.274 - debug: [FS-LOGGER] Init.
+2024-01-09 11:31:01.572 - info: [FS-ATTACHMENT] Inject attachment mw into router.
+2024-01-09 11:31:01.572 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
+2024-01-09 11:31:01.573 - info: [FS-AUTH] Inject auth and api mv into router.
+2024-01-09 11:32:29.303 - debug: [FS-LOGGER] Init.
+2024-01-09 11:32:29.592 - info: [FS-ATTACHMENT] Inject attachment mw into router.
+2024-01-09 11:32:29.593 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
+2024-01-09 11:32:29.593 - info: [FS-AUTH] Inject auth and api mv into router.
+2024-01-09 13:39:20.502 - debug: [FS-LOGGER] Init.
+2024-01-09 13:39:21.092 - info: [FS-ATTACHMENT] Inject attachment mw into router.
+2024-01-09 13:39:21.093 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
+2024-01-09 13:39:21.093 - info: [FS-AUTH] Inject auth and api mv into router.
+2024-01-09 13:40:44.437 - error: path: /project/publish/list, error: ReferenceError: startTime is not defined
+2024-01-09 13:41:30.948 - debug: [FS-LOGGER] Init.
+2024-01-09 13:41:31.275 - info: [FS-ATTACHMENT] Inject attachment mw into router.
+2024-01-09 13:41:31.276 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
+2024-01-09 13:41:31.276 - info: [FS-AUTH] Inject auth and api mv into router.
+2024-01-09 13:41:38.928 - error: path: /project/publish/list, error: TypeError: Cannot read property 'findAndCountAll' of undefined
+2024-01-09 13:44:46.008 - debug: [FS-LOGGER] Init.
+2024-01-09 13:44:46.364 - info: [FS-ATTACHMENT] Inject attachment mw into router.
+2024-01-09 13:44:46.365 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
+2024-01-09 13:44:46.365 - info: [FS-AUTH] Inject auth and api mv into router.
+2024-01-09 13:47:41.402 - debug: [FS-LOGGER] Init.
+2024-01-09 13:47:41.794 - info: [FS-ATTACHMENT] Inject attachment mw into router.
+2024-01-09 13:47:41.796 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
+2024-01-09 13:47:41.797 - info: [FS-AUTH] Inject auth and api mv into router.
+2024-01-09 13:49:41.051 - error: path: /project/publish/list, error: SequelizeDatabaseError: 关系 "project_user" 不存在
+2024-01-09 13:51:01.115 - debug: [FS-LOGGER] Init.
+2024-01-09 13:51:01.394 - info: [FS-ATTACHMENT] Inject attachment mw into router.
+2024-01-09 13:51:01.394 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
+2024-01-09 13:51:01.394 - info: [FS-AUTH] Inject auth and api mv into router.
+2024-01-09 14:20:36.427 - debug: [FS-LOGGER] Init.
+2024-01-09 14:20:36.855 - info: [FS-ATTACHMENT] Inject attachment mw into router.
+2024-01-09 14:20:36.856 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
+2024-01-09 14:20:36.861 - info: [FS-AUTH] Inject auth and api mv into router.
+2024-01-09 14:47:05.905 - debug: [FS-LOGGER] Init.
+2024-01-09 14:47:06.230 - info: [FS-ATTACHMENT] Inject attachment mw into router.
+2024-01-09 14:47:06.231 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
+2024-01-09 14:47:06.231 - info: [FS-AUTH] Inject auth and api mv into router.
diff --git a/script/2.1/schema/1.porject_user.sql b/script/2.1/schema/1.porject_user.sql
new file mode 100644
index 0000000..ba7cf51
--- /dev/null
+++ b/script/2.1/schema/1.porject_user.sql
@@ -0,0 +1,46 @@
+ create table project_user
+(
+ id serial not null,
+ project_name varchar(128) not null,
+ project_describe varchar,
+ project_type varchar(128) not null,
+ monitor_object integer[] not null,
+ account varchar(128) not null,
+ password varchar(128) not null,
+ create_time timestamp not null,
+ code varchar(128) not null,
+ del boolean not null
+);
+
+comment on table project_user is '发布项目';
+
+comment on column project_user.project_name is '项目名称';
+
+comment on column project_user.project_describe is '项目描述';
+
+comment on column project_user.project_type is '项目类型';
+
+comment on column project_user.monitor_object is '监测对象';
+
+comment on column project_user.account is '发布账号';
+
+comment on column project_user.password is '发布密码';
+
+comment on column project_user.create_time is '创建时间';
+
+comment on column project_user.code is 'p';
+
+create unique index project_user_id_uindex
+ on project_user (id);
+
+alter table project_user
+ add constraint project_user_pk
+ primary key (id);
+
+
+create table project_user_token
+(
+ token uuid not null,
+ project_user_info jsonb not null,
+ expired timestamp not null
+);
diff --git a/web/client/src/layout/actions/global.js b/web/client/src/layout/actions/global.js
index 3615ef1..0b6818e 100644
--- a/web/client/src/layout/actions/global.js
+++ b/web/client/src/layout/actions/global.js
@@ -36,7 +36,8 @@ export function initApiRoot () {
dispatch({
type: INIT_API_ROOT,
payload: {
- apiRoot: res.root
+ apiRoot: res.root,
+ webScreen: res.webScreen
}
})
});
diff --git a/web/client/src/layout/reducers/global.js b/web/client/src/layout/reducers/global.js
index 5e69530..5d750b5 100644
--- a/web/client/src/layout/reducers/global.js
+++ b/web/client/src/layout/reducers/global.js
@@ -1,52 +1,53 @@
'use strict';
import Immutable from 'immutable';
-import { INIT_LAYOUT, RESIZE } from '../actions/global';
+import { INIT_LAYOUT, RESIZE, INIT_API_ROOT } from '../actions/global';
import { SET_GLOBAL_SITE_LIST, CLEAR_GLOBAL_SITE_LIST } from '../actions/site'
-function global(state = {
- title: '',
- copyright: '',
- sections: [],
- actions: {},
- plugins: {},
- clientHeight: 768,
- clientWidth: 1024,
- sites: []
+function global (state = {
+ title: '',
+ copyright: '',
+ sections: [],
+ actions: {},
+ plugins: {},
+ clientHeight: 768,
+ clientWidth: 1024,
+ sites: [],
+ webScreen: ''
}, action) {
- const payload = action.payload;
- switch (action.type) {
- case RESIZE:
- return Immutable.fromJS(state).merge({
- clientHeight: payload.clientHeight,
- clientWidth: payload.clientWidth
- }).toJS();
- case INIT_LAYOUT:
- return {
- title: payload.title,
- copyright: payload.copyright,
- sections: payload.sections,
- actions: payload.actions,
- plugins: payload.plugins,
- clientHeight: state.clientHeight,
- detailsComponent: null,
- sites: []
- };
- // case INIT_RESOURCE_ROOT:
- // return Immutable.fromJS(state).merge(payload).toJS();
- // case INIT_PAGE_HEADER_DETAILS:
- // return Immutable.fromJS(state).merge({
- // detailsComponent: payload.component
- // }).toJS();
- case SET_GLOBAL_SITE_LIST:
- return Immutable.fromJS(state).merge({
- sites: payload.data
- }).toJS();
- case CLEAR_GLOBAL_SITE_LIST:
- return Immutable.fromJS(state).merge({
- sites: []
- }).toJS();
- default:
- return state;
- }
+ const payload = action.payload;
+ switch (action.type) {
+ case RESIZE:
+ return Immutable.fromJS(state).merge({
+ clientHeight: payload.clientHeight,
+ clientWidth: payload.clientWidth
+ }).toJS();
+ case INIT_LAYOUT:
+ return {
+ title: payload.title,
+ copyright: payload.copyright,
+ sections: payload.sections,
+ actions: payload.actions,
+ plugins: payload.plugins,
+ clientHeight: state.clientHeight,
+ detailsComponent: null,
+ sites: [],
+ };
+ case INIT_API_ROOT:
+ return Immutable.fromJS(state).merge(payload).toJS();
+ // case INIT_PAGE_HEADER_DETAILS:
+ // return Immutable.fromJS(state).merge({
+ // detailsComponent: payload.component
+ // }).toJS();
+ case SET_GLOBAL_SITE_LIST:
+ return Immutable.fromJS(state).merge({
+ sites: payload.data
+ }).toJS();
+ case CLEAR_GLOBAL_SITE_LIST:
+ return Immutable.fromJS(state).merge({
+ sites: []
+ }).toJS();
+ default:
+ return state;
+ }
}
export default global;
\ No newline at end of file
diff --git a/web/client/src/sections/projectManagement/actions/index.js b/web/client/src/sections/projectManagement/actions/index.js
index 51977c4..72ded6e 100644
--- a/web/client/src/sections/projectManagement/actions/index.js
+++ b/web/client/src/sections/projectManagement/actions/index.js
@@ -1,6 +1,8 @@
'use strict';
import projectBinding from './projectBinding'
+import projectPublish from './projectPublish'
export default {
- ...projectBinding
+ ...projectBinding,
+ ...projectPublish
}
\ No newline at end of file
diff --git a/web/client/src/sections/projectManagement/actions/projectPublish.js b/web/client/src/sections/projectManagement/actions/projectPublish.js
new file mode 100644
index 0000000..182df5b
--- /dev/null
+++ b/web/client/src/sections/projectManagement/actions/projectPublish.js
@@ -0,0 +1,71 @@
+'use strict';
+import { basicAction } from '@peace/utils'
+import { ApiTable } from '$utils'
+
+export function getProjectType () {
+ return dispatch => basicAction({
+ type: 'get',
+ dispatch: dispatch,
+ actionType: 'GET_PORJECT_TYPE',
+ url: `${ApiTable.projectType}`,
+ msg: { error: '获取项目类型失败' },
+ reducer: { name: 'projectType' }
+ });
+}
+
+export function getProjectPublishList (query = {}) {
+ return dispatch => basicAction({
+ type: 'get',
+ query,
+ dispatch: dispatch,
+ actionType: 'GET_PROJECT_PUBLISH_LIST',
+ url: `${ApiTable.projectPublishList}`,
+ msg: { error: '获取项目发布列表失败' },
+ reducer: { name: 'publishList' }
+ });
+}
+
+export function postProjectPublish (data = {}) {
+ return dispatch => basicAction({
+ type: 'post',
+ dispatch: dispatch,
+ data,
+ actionType: 'POST_PROJECT_PUBLISH',
+ url: `${ApiTable.projectPublishList}`,
+ msg: { option: data?.isCode ? '修改地址' : data?.id ? "编辑项目" : '新增项目' },
+ reducer: { name: 'anxinyunProject' }
+ });
+}
+
+
+// export function addorEditRelation(data) {
+// return dispatch => basicAction({
+// type: 'post',
+// dispatch: dispatch,
+// data,
+// actionType: 'ADD_OR_EDIT_RELATION',
+// url: `${ApiTable.addorEditRelation}`,
+// msg: { option:data?.id? '编辑绑定关系':'新增绑定关系' },
+// // reducer: { name: 'anxinyunProject'}
+// });
+// }
+
+
+
+export function delProjectPublish (id) {
+ return dispatch => basicAction({
+ type: 'del',
+ dispatch: dispatch,
+ actionType: 'DEL_RELATION',
+ url: ApiTable.delProjectPublish.replace('{id}', id),
+ msg: { option: '删除项目' },
+ });
+}
+
+
+export default {
+ getProjectType,
+ getProjectPublishList,
+ postProjectPublish,
+ delProjectPublish
+}
\ No newline at end of file
diff --git a/web/client/src/sections/projectManagement/components/projectModel.js b/web/client/src/sections/projectManagement/components/projectModel.js
new file mode 100644
index 0000000..5278f7e
--- /dev/null
+++ b/web/client/src/sections/projectManagement/components/projectModel.js
@@ -0,0 +1,128 @@
+import React, { useState, useEffect } from 'react';
+import { connect } from 'react-redux';
+import { v4 } from 'uuid';
+import moment from 'moment';
+import { Form, Input, Modal, Select, Row, Col, message } from 'antd';
+const { TextArea } = Input;
+
+
+const ProjectModel = ({ dispatch, actions, user, modelData, close, success, projectType, strucList }) => {
+
+ const { projectManagement, projectRegime } = actions
+ const [showBaiduMap, setShowBaiduMap] = useState(false)
+ const [strucData, setStrucData] = useState([])
+
+ const [form] = Form.useForm();
+
+ useEffect(() => {
+ if (modelData?.id) {
+ setStrucData(strucList?.filter(s => s.type == modelData?.projectType) || [])
+ }
+ }, [])
+
+
+ return (
+ {
+ form.validateFields().then(v => {
+ if (modelData?.id || v.password == v.confirmPassword) {
+ dispatch(projectManagement.postProjectPublish({
+ ...v,
+ id: modelData?.id,
+ createTime: moment(modelData?.createTime).format('YYYY-MM-DD HH:mm:ss'),
+ code: modelData?.code || v4()
+ })).then(res => {
+ if (res.success) {
+ success()
+ }
+ })
+ } else {
+ message.warning('两次输入的密码不一致');
+ }
+
+ })
+ }}
+ onCancel={() => close()}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {!modelData?.id &&
+ <>
+
+ {
+ e.preventDefault();
+ }} style={{ width: 150 }} placeholder='请输入发布密码' />
+
+
+
+
+ >
+ }
+
+
+
+
+ );
+};
+
+
+function mapStateToProps (state) {
+ const { auth, global, projectType } = state;
+ return {
+ user: auth.user,
+ actions: global.actions,
+ projectType: projectType?.data || [],
+ };
+}
+
+export default connect(mapStateToProps)(ProjectModel);
\ No newline at end of file
diff --git a/web/client/src/sections/projectManagement/containers/projectPublish.js b/web/client/src/sections/projectManagement/containers/projectPublish.js
index 99cfdc1..e21ef60 100644
--- a/web/client/src/sections/projectManagement/containers/projectPublish.js
+++ b/web/client/src/sections/projectManagement/containers/projectPublish.js
@@ -1,51 +1,60 @@
import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
-import { Form, Input, Button, Table, Modal, Popconfirm, Tooltip } from 'antd';
+import { Spin, Form, Input, Button, Table, Modal, Popconfirm, Tooltip } from 'antd';
+import { SettingOutlined } from '@ant-design/icons';
import { push } from 'react-router-redux';
-// import ProjectAddModel from '../components/projectAddModel'
+import moment from 'moment';
+import { v4 } from 'uuid';
+import ProjectModel from '../components/projectModel'
import './style.less';
-const ProjectPublish = ({ dispatch, actions, user, loading }) => {
+const ProjectPublish = ({ dispatch, actions, user, loading, publishList, webScreen }) => {
- const { projectManagement } = actions
+ const { projectManagement, projectRegime } = actions
const [firmList, setFirmList] = useState([])
const [tableList, settableList] = useState([])
- const [addModel, setAddModel] = useState(false)
+ const [editModel, setEditModel] = useState(false)
+ const [codeEdit, setCodeEdit] = useState(false)
const [modelData, setModelData] = useState({})
const [query, setQuery] = useState({ limit: 10, page: 0 })
- const [limits, setLimits] = useState()
+ const [strucList, setStrucList] = useState([])
const [search, setSearch] = useState({})
const [companyID, setCompanyId] = useState('')
+ const [code, setCode] = useState('')
useEffect(() => {
- projectList(query)
+ dispatch(projectManagement.getProjectType())
+ dispatch(projectRegime.getProjectList({ justStructure: true })).then(v => {
+ if (v.success) {
+ setStrucList(v.payload.data?.rows || [])
+ }
+ })
+ projectPublishList(query)
}, [])
- const projectList = (obj) => {
- // const { limit, page, name } = obj
- // dispatch(projectManagement.getProjectList({ limit, page, name, })).then(res => {
- // // console.log(res)
- // if (res.success) {
- // settableList(res.payload.data?.rows?.map(v => ({ ...v, key: v.id })))
- // setLimits(res.payload.data?.count)
- // }
- // })
+ const projectPublishList = (data = {}) => {
+ dispatch(projectManagement.getProjectPublishList(data))
}
+
+
const columns = [{
title: '项目名称',
- dataIndex: 'porjectName',
- key: 'porjectName',
+ dataIndex: 'projectName',
+ key: 'projectName',
}, {
title: '监测对象',
dataIndex: 'monitorObject',
key: 'monitorObject',
- render: (text, record, index) => text && text.json('、')
+ render: (text, record, index) => {
+ let findAll = strucList?.filter(d => text?.includes(d.id))?.map(s => s.name) || []
+ return findAll.join('、') || '--'
+ }
}, {
title: '创建时间',
dataIndex: 'createTime',
@@ -58,7 +67,7 @@ const ProjectPublish = ({ dispatch, actions, user, loading }) => {
render: (text, record, index) => {
return (<>
@@ -66,25 +75,21 @@ const ProjectPublish = ({ dispatch, actions, user, loading }) => {
title={
是否确认删除此项目?
}
position='topLeft'
onConfirm={() => {
- // dispatch(projectRegime.delProject(record.id)).then(res => {
- // if (res.success) {
- // if ((limits > 11 && tableList.length > 1) || limits < 11) {
- // projectList({ ...query, ...search })
- // } else {
- // projectList({ limit: query?.limit, page: query?.page - 1, ...search })
- // setQuery({ limit: query?.limit, page: query?.page - 1 });
- // }
-
- // }
- // })
+ dispatch(projectManagement.delProjectPublish(record.id)).then(res => {
+ if (res.success) {
+ setQuery({ limit: 10, page: 0 });
+ projectPublishList({ limit: 10, page: 0 })
+ }
+ })
}}
>
- {/* */}
>
+ setCode(record?.code)
+ setModelData(record)
+ setCodeEdit(true)
+ }} >地址>
)
}
}
@@ -92,70 +97,108 @@ const ProjectPublish = ({ dispatch, actions, user, loading }) => {
return (
-