diff --git a/.gitignore b/.gitignore index cee3e9c9..68bab034 100644 --- a/.gitignore +++ b/.gitignore @@ -141,4 +141,5 @@ dist *downloadFiles/ web/client/assets/color.less package-lock.json -development.text \ No newline at end of file +development.text +web/package-lock.json diff --git a/api/.vscode/launch.json b/api/.vscode/launch.json index eaa8220c..b50512d0 100644 --- a/api/.vscode/launch.json +++ b/api/.vscode/launch.json @@ -13,9 +13,10 @@ "NODE_ENV": "development" }, "args": [ - "-p 14000", - "-f http://localhost:14000", - "-g postgres://postgres:123@10.8.30.32:5432/highways4good", + "-p 13400", + "-f http://localhost:13400", + // "-g postgres://postgres:123@10.8.30.32:5432/highways4good", + "-g postgres://FashionAdmin:123456@10.8.30.156:5432/highway4goodn0728", "--qnak XuDgkao6cL0HidoMAPnA5OB10Mc_Ew08mpIfRJK5", "--qnsk yewcieZLzKZuDfig0wLZ9if9jKp2P_1jd3CMJPSa", "--qnbkt dev-highways4good", diff --git a/api/Dockerfilenew b/api/Dockerfilenew new file mode 100644 index 00000000..b34d4918 --- /dev/null +++ b/api/Dockerfilenew @@ -0,0 +1,13 @@ +FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node:12-dev as builder +COPY . /var/app +WORKDIR /var/app +EXPOSE 8080 +RUN npm config set registry=https://nexus.ngaiot.com/repository/fs-npm/ +RUN echo "{\"time\":\"$BUILD_TIMESTAMP\",\"build\": \"$BUILD_NUMBER\",\"revision\": \"$SVN_REVISION_1\",\"URL\":\"$SVN_URL_1\"}" > version.json +RUN npm cache clean -f +RUN rm -rf package-lock.json +RUN npm install --registry https://nexus.ngaiot.com/repository/fs-npm/ +FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node:12 +COPY --from=builder --chown=node /var/app /home/node/app +WORKDIR /home/node/app +CMD ["node", "server.js"] \ No newline at end of file diff --git a/api/app/lib/controllers/auth/index.js b/api/app/lib/controllers/auth/index.js index e486593e..e501c0a9 100644 --- a/api/app/lib/controllers/auth/index.js +++ b/api/app/lib/controllers/auth/index.js @@ -4,23 +4,31 @@ const MD5 = require('crypto-js/md5'); const moment = require('moment'); const uuid = require('uuid'); -async function login (ctx, next) { +async function login(ctx, next) { const transaction = await ctx.fs.dc.orm.transaction(); try { const models = ctx.fs.dc.models; const params = ctx.request.body; + console.log('params.username', params) let password = Hex.stringify(MD5(params.password)); - const userRes = await models.User.findOne({ where: { - username: params.username, + $or: [{ username: params.username }, + { phone: params.username } + ], password: password, delete: false, }, attributes: { exclude: ['password', 'delete'] }, }); - - if (!userRes) { + console.log('userRes', userRes) + if (!userRes.isAdmin) { + ctx.status = 400; + ctx.body = { + "message": "不是管理员,禁止登录" + } + } + else if (!userRes) { ctx.status = 400; ctx.body = { "message": "账号或密码错误" @@ -65,7 +73,7 @@ async function login (ctx, next) { * 微信小程序登录 * @@requires.body {phone-手机号, password-密码} ctx */ -async function wxLogin (ctx, next) { +async function wxLogin(ctx, next) { const transaction = await ctx.fs.dc.orm.transaction(); try { const models = ctx.fs.dc.models; @@ -87,7 +95,7 @@ async function wxLogin (ctx, next) { ctx.body = { message: "该用户已被禁用" } } else { const token = uuid.v4(); - + let userRslt = Object.assign({ authorized: true, token: token, @@ -114,7 +122,7 @@ async function wxLogin (ctx, next) { } } -async function logout (ctx) { +async function logout(ctx) { try { const { token, code } = ctx.request.body; const models = ctx.fs.dc.models; diff --git a/api/app/lib/controllers/data/index.js b/api/app/lib/controllers/data/index.js index 8112a750..eb524973 100644 --- a/api/app/lib/controllers/data/index.js +++ b/api/app/lib/controllers/data/index.js @@ -8,7 +8,8 @@ async function dataExport (ctx) { try { const models = ctx.fs.dc.models; const { userId } = ctx.fs.api - const { exp, ids, roadLevel, municipalType } = ctx.query; + const { exp, ids, roadLevel, municipalType, + patrolType } = ctx.query; if (!exp) { throw '参数错误'; @@ -89,11 +90,23 @@ async function dataExport (ctx) { const tableAttributes = models[modalOption.tableName].tableAttributes let header = [] for (let k in tableAttributes) { - const comment = tableAttributes[k].comment + let comment = tableAttributes[k].comment if (k != 'id' && comment) { if (comment == '品名' && municipalType == '出租车') { continue } + if (patrolType) { + if (patrolType == 'road') { + + } else if (patrolType == 'anomaly') { + + } else { + // 正常的之前的巡查内容 + if (comment == '工程名称') { + continue + } + } + } header.push({ title: comment || '-', key: k, diff --git a/api/app/lib/controllers/data/task.js b/api/app/lib/controllers/data/task.js new file mode 100644 index 00000000..70b86d68 --- /dev/null +++ b/api/app/lib/controllers/data/task.js @@ -0,0 +1,91 @@ +'use strict'; + +async function getTask(ctx) { + try { + const models = ctx.fs.dc.models + const query = ctx.query + const whereopt = { + isdanger: query.isdanger + } + const whereRoadOpt = { + id: query.id + } + const taskRes = await models.TaskManage.findAndCountAll({ + order: [['id', 'DESC']], + attributes: ['id', 'dangerDescription', 'isdanger', 'issuanceTime', 'reportTime'], + include: [ + { + attributes: ['id', 'routeName', 'routeCode'], + model: models.Road, + where: query.id == undefined ? {} : whereRoadOpt + + }, + { + attributes: ['id', 'name'], + model: models.User + } + ], + where: query.isdanger == undefined ? {} : whereopt + }) + ctx.body = taskRes + ctx.status = 200 + } + catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: '获取失败' + } + } +} + +//删除任务 +async function delTask(ctx) { + try { + const models = ctx.fs.dc.models + const { id } = ctx.params + await models.TaskManage.destroy({ where: { id: id } }) + ctx.status = 204 + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: '删除失败' + } + } + +} +//编辑任务 +async function editTask(ctx) { + //const transaction = await ctx.fs.dc.orm.transaction(); + try { + const models = ctx.fs.dc.models + const params = ctx.request.body + const road = await models.Road.findOne({ where: { id: params.routeId } }) + const user = await models.User.findOne({ where: { id: params.userId } }) + if (!params.id) { + await models.TaskManage.create({ + roadid: road.id, userid: user.id, dangerDescription: params.dangerDescription.trim() + }) + } else { + await models.TaskManage.update({ + roadid: road.id, userid: user.id, dangerDescription: params.dangerDescription.trim() + }, { where: { id: params.id } }) + } + ctx.status = 204 + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: '新增失败' + } + } + +} + + + + +module.exports = { + getTask, delTask, editTask +}; \ No newline at end of file diff --git a/api/app/lib/controllers/organization/user.js b/api/app/lib/controllers/organization/user.js index 29a494e8..8046cc5e 100644 --- a/api/app/lib/controllers/organization/user.js +++ b/api/app/lib/controllers/organization/user.js @@ -2,7 +2,7 @@ const Hex = require('crypto-js/enc-hex'); const MD5 = require('crypto-js/md5'); -async function getUser (ctx, next) { +async function getUser(ctx, next) { try { const models = ctx.fs.dc.models; const { depId } = ctx.params @@ -26,7 +26,7 @@ async function getUser (ctx, next) { } } -async function getUserAll (ctx, next) { +async function getUserAll(ctx, next) { try { const models = ctx.fs.dc.models; const userRes = await models.User.findAll({ @@ -48,11 +48,11 @@ async function getUserAll (ctx, next) { } } -async function creatUser (ctx, next) { +async function creatUser(ctx, next) { try { const models = ctx.fs.dc.models; const data = ctx.request.body; - + console.log('data', data) let repeatUserNameCount = await models.User.count({ where: { phone: data.phone, @@ -74,6 +74,7 @@ async function creatUser (ctx, next) { delete: false, phone: data.phone, remark: 'th', + isAdmin: data.isAdmin }) ctx.status = 204; @@ -87,7 +88,7 @@ async function creatUser (ctx, next) { } -async function updateUser (ctx, next) { +async function updateUser(ctx, next) { let errMsg = "修改用户失败" try { const models = ctx.fs.dc.models; @@ -114,6 +115,7 @@ async function updateUser (ctx, next) { enable: data.enable, delete: false, phone: data.phone, + isAdmin: data.isAdmin }, { where: { id: userId @@ -130,7 +132,7 @@ async function updateUser (ctx, next) { } } -async function deleteUser (ctx, next) { +async function deleteUser(ctx, next) { try { const models = ctx.fs.dc.models; const { userIds } = ctx.params; @@ -174,7 +176,7 @@ async function deleteUser (ctx, next) { // } // } -async function setPassword (ctx, next) { +async function setPassword(ctx, next) { try { const models = ctx.fs.dc.models; const { userId } = ctx.params; diff --git a/api/app/lib/controllers/report/index.js b/api/app/lib/controllers/report/index.js index c098336e..d5474115 100644 --- a/api/app/lib/controllers/report/index.js +++ b/api/app/lib/controllers/report/index.js @@ -9,12 +9,12 @@ async function reportList (ctx) { where: { }, - attributes: ['id', 'road', 'time', 'projectType', 'roadSectionStart', 'roadSectionEnd', 'reportType', 'content', 'longitude', 'latitude'], + attributes: ['id', 'road', 'time', 'projectType', 'roadSectionStart', 'roadSectionEnd', 'reportType', 'content', 'longitude', 'latitude', 'projectName', 'handleState'], include: [{ model: models.User, attributes: ['name'] }], - order: [['time', asc ? 'ASC': 'DESC']], + order: [['time', asc ? 'ASC' : 'DESC']], } if (limit) { findOption.limit = limit @@ -30,8 +30,14 @@ async function reportList (ctx) { } } if (keyword) { - findOption.where.road = { - '$like': `%${keyword}%` + if (reportType == 'road') { + findOption.where.projectName = { + '$like': `%${keyword}%` + } + } else { + findOption.where.road = { + '$like': `%${keyword}%` + } } } if (userId) { @@ -133,6 +139,31 @@ async function reportDetail (ctx) { } } +async function reportHandle (ctx) { + try { + const { models } = ctx.fs.dc; + + const { reportId } = ctx.params + const { handleState } = ctx.request.body + + await models.Report.update({ + handleState: handleState + }, { + where: { + id: reportId + } + }) + + ctx.status = 200; + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } +} + async function createReport (ctx) { try { const { userId } = ctx.fs.api @@ -181,5 +212,5 @@ async function deleteReport (ctx) { module.exports = { reportList, reportPosition, - reportDetail, createReport, deleteReport, + reportDetail, createReport, deleteReport, reportHandle }; \ No newline at end of file diff --git a/api/app/lib/index.js b/api/app/lib/index.js index c4715290..6349db80 100644 --- a/api/app/lib/index.js +++ b/api/app/lib/index.js @@ -26,7 +26,7 @@ module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Seq require(`./models/${filename}`)(dc) }); - const { User, Department, Report, FileType, Road, Files, FileRoad } = dc.models; + const { User, Department, Report, FileType, Road, Files, FileRoad, TaskManage } = dc.models; // 定义外键 User.belongsTo(Department, { foreignKey: 'departmentId', targetKey: 'id' }); Department.hasMany(User, { foreignKey: 'departmentId', sourceKey: 'id' }); @@ -40,4 +40,10 @@ module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Seq // Files.belongsTo(Road, { foreignKey: 'roadId', targetKey: 'id' }); // Road.hasMany(Files, { foreignKey: 'roadId', targetKey: 'id' }); + //定义外键 + TaskManage.belongsTo(User, { foreignKey: 'userid', targetKey: 'id' }) + User.hasMany(TaskManage, { foreignKey: 'userid', targetKey: 'id' }) + // + TaskManage.belongsTo(Road, { foreignKey: 'roadid', targetKey: 'id' }) + Road.hasMany(TaskManage, { foreignKey: 'roadid', targetKey: 'id' }) }; diff --git a/api/app/lib/models/report.js b/api/app/lib/models/report.js index 0a49fba5..71512652 100644 --- a/api/app/lib/models/report.js +++ b/api/app/lib/models/report.js @@ -166,6 +166,26 @@ module.exports = dc => { field: "address", autoIncrement: false }, + projectName: { + index: 17, + type: DataTypes.STRING, + allowNull: true, + defaultValue: null, + comment: "工程名称", + primaryKey: false, + field: "project_name", + autoIncrement: false + }, + handleState: { + index: 18, + type: DataTypes.STRING, + allowNull: false, + defaultValue: "已处理", + // comment: "处理状态", + primaryKey: false, + field: "handle_state", + autoIncrement: false + }, }, { tableName: "report", comment: "", diff --git a/api/app/lib/models/task_manage.js b/api/app/lib/models/task_manage.js new file mode 100644 index 00000000..27c7c508 --- /dev/null +++ b/api/app/lib/models/task_manage.js @@ -0,0 +1,87 @@ +/* eslint-disable*/ + +'use strict'; + +module.exports = dc => { + const DataTypes = dc.ORM; + const sequelize = dc.orm; + const TaskManage = sequelize.define("taskManage", { + id: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: "id", + primaryKey: true, + field: "id", + autoIncrement: true + }, + roadid: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: "道路id", + primaryKey: false, + field: "roadid", + autoIncrement: false, + references: { + key: "id", + model: "road" + } + }, + dangerDescription: { + type: DataTypes.CHAR, + allowNull: true, + defaultValue: null, + comment: "隐患说明", + primaryKey: false, + field: "danger_description", + autoIncrement: false + }, + issuanceTime: { + type: DataTypes.DATE, + allowNull: true, + defaultValue: null, + comment: "下发时间", + primaryKey: false, + field: "issuance_time", + autoIncrement: false + }, + userid: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: "用户id", + primaryKey: false, + field: "userid", + autoIncrement: false, + references: { + key: "id", + model: "user" + } + }, + isdanger: { + type: DataTypes.BOOLEAN, + allowNull: true, + defaultValue: null, + comment: "是否存在安全隐患,flase(不存在)", + primaryKey: false, + field: "isdanger", + autoIncrement: false + }, + reportTime: { + type: DataTypes.DATE, + allowNull: true, + defaultValue: null, + comment: "上报时间", + primaryKey: false, + field: "report_time", + autoIncrement: false + } + }, { + tableName: "task_manage", + comment: "", + indexes: [] + }); + dc.models.TaskManage = TaskManage; + return TaskManage; +}; \ No newline at end of file diff --git a/api/app/lib/models/user.js b/api/app/lib/models/user.js index dbef784d..08b19551 100644 --- a/api/app/lib/models/user.js +++ b/api/app/lib/models/user.js @@ -14,6 +14,14 @@ module.exports = dc => { field: "id", autoIncrement: true }, + isAdmin: { + type: DataTypes.BOOLEAN, + defaultValue: null, + comment: null, + primaryKey: false, + field: "isadmin", + autoIncrement: false + }, name: { type: DataTypes.STRING, allowNull: false, diff --git a/api/app/lib/routes/data/index.js b/api/app/lib/routes/data/index.js index 3b718194..83d12f7c 100644 --- a/api/app/lib/routes/data/index.js +++ b/api/app/lib/routes/data/index.js @@ -8,7 +8,7 @@ const overspeed = require('../../controllers/data/overspeed'); const bus = require('../../controllers/data/bus'); const publicity = require('../../controllers/data/publicity'); const dataIndex = require('../../controllers/data/index'); - +const task = require('../../controllers/data/task') module.exports = function (app, router, opts) { // 数据导出 @@ -21,7 +21,7 @@ module.exports = function (app, router, opts) { // 运政 //货运 - async function setFreightType (ctx, next) { + async function setFreightType(ctx, next) { ctx.request.body = { ...(ctx.request.body || {}), type: 'freight' @@ -38,7 +38,7 @@ module.exports = function (app, router, opts) { router.del('/vehicle/freight/:id', setFreightType, vehicle.del); //客运车 - async function setVehicleType (ctx, next) { + async function setVehicleType(ctx, next) { ctx.request.body = { ...(ctx.request.body || {}), type: 'vehicle' @@ -55,7 +55,7 @@ module.exports = function (app, router, opts) { router.del('/vehicle/:id', setVehicleType, vehicle.del); // 路政 - async function setRoadManageType (ctx, next) { + async function setRoadManageType(ctx, next) { ctx.request.body = { ...(ctx.request.body || {}), type: 'road_manage' @@ -172,4 +172,12 @@ module.exports = function (app, router, opts) { app.fs.api.logAttr['DEL/publicity/:publicityId'] = { content: '删除宣传数据', visible: false }; router.del('/publicity/:publicityId', publicity.publicityDel); //publicity END + // task + app.fs.api.logAttr['GET/task'] = { content: '获取任务列表', visible: false }; + router.get('/task', task.getTask); + app.fs.api.logAttr['DEL/task/:id'] = { content: '删除任务', visible: false }; + router.del('/task/:id', task.delTask); + app.fs.api.logAttr['PUT/task'] = { content: '编辑任务', visible: false }; + router.put('/task', task.editTask); + //task END }; diff --git a/api/app/lib/routes/report/index.js b/api/app/lib/routes/report/index.js index afd4bcbc..d3fd64dd 100644 --- a/api/app/lib/routes/report/index.js +++ b/api/app/lib/routes/report/index.js @@ -10,7 +10,10 @@ module.exports = function (app, router, opts) { router.get('/report/position', report.reportPosition); app.fs.api.logAttr['GET/report/:reportId/detail'] = { content: '获取上报详情', visible: false }; - router.get('/report/:reportId//detail', report.reportDetail); + router.get('/report/:reportId/detail', report.reportDetail); + + app.fs.api.logAttr['GET/report/:reportId/handle'] = { content: '处理上报详情', visible: false }; + router.post('/report/:reportId/handle', report.reportHandle); app.fs.api.logAttr['POST/report'] = { content: '创建上报', visible: false }; router.post('/report', report.createReport); diff --git a/api/log/development.log b/api/log/development.log index 673a9986..43963241 100644 --- a/api/log/development.log +++ b/api/log/development.log @@ -11203,3 +11203,18 @@ headers: {} 2022-09-05 15:40:10.680 - debug: [FS-LOGGER] Init. 2022-09-05 15:40:11.273 - info: [FS-ATTACHMENT] Inject attachment mw into router. 2022-09-05 15:40:11.273 - info: [FS-AUTH] Inject auth and api mv into router. +2023-06-27 15:28:45.497 - debug: [FS-LOGGER] Init. +2023-06-27 15:28:46.411 - info: [FS-ATTACHMENT] Inject attachment mw into router. +2023-06-27 15:28:46.411 - info: [FS-AUTH] Inject auth and api mv into router. +2023-06-27 15:56:55.756 - debug: [FS-LOGGER] Init. +2023-06-27 15:56:56.357 - info: [FS-ATTACHMENT] Inject attachment mw into router. +2023-06-27 15:56:56.358 - info: [FS-AUTH] Inject auth and api mv into router. +2023-06-27 16:32:17.216 - debug: [FS-LOGGER] Init. +2023-06-27 16:32:17.767 - info: [FS-ATTACHMENT] Inject attachment mw into router. +2023-06-27 16:32:17.768 - info: [FS-AUTH] Inject auth and api mv into router. +2023-06-27 18:48:13.296 - debug: [FS-LOGGER] Init. +2023-06-27 18:48:13.664 - info: [FS-ATTACHMENT] Inject attachment mw into router. +2023-06-27 18:48:13.664 - info: [FS-AUTH] Inject auth and api mv into router. +2023-06-27 20:02:06.352 - debug: [FS-LOGGER] Init. +2023-06-27 20:02:06.794 - info: [FS-ATTACHMENT] Inject attachment mw into router. +2023-06-27 20:02:06.795 - info: [FS-AUTH] Inject auth and api mv into router. diff --git a/jenkinsfilenew_api b/jenkinsfilenew_api new file mode 100644 index 00000000..07c0d1ca --- /dev/null +++ b/jenkinsfilenew_api @@ -0,0 +1,22 @@ +podTemplate { + node('pod-templ-jenkins-slave-common') { + + env.IMAGE_NAME = "${IOT_IMAGES_REGISTRY}/${IOT}/${JOB_NAME}" + env.IMAGE_NAME_SHORT = "${IOT}/${JOB_NAME}" + env.CODE_ADDR = "${GIT_ADDRESS}/free-sun/Highways4Good.git" + + stage('Run shell') { + git branch: 'dev', credentialsId: 'gitea-builder', url: "${CODE_ADDR}" + + container('image-builder') { + sh''' + find . -depth -name '.svn' -type d -exec rm -rf {} + + /kaniko/executor --context=${BUILD_WORKSPACE} --dockerfile=./api/Dockerfilenew --destination=${IMAGE_NAME}:${IMAGE_VERSION} --cache=false --cleanup + ''' + } + + buildName "${IMAGE_NAME_SHORT}:${IMAGE_VERSION}" + buildDescription "${IMAGE_NAME}:${IMAGE_VERSION}" + } + } +} \ No newline at end of file diff --git a/jenkinsfilenew_web b/jenkinsfilenew_web new file mode 100644 index 00000000..feccdcff --- /dev/null +++ b/jenkinsfilenew_web @@ -0,0 +1,25 @@ +podTemplate { + node('pod-templ-jenkins-slave-common') { + + env.IMAGE_NAME = "${IOT_IMAGES_REGISTRY}/${IOT}/${JOB_NAME}" + env.IMAGE_NAME_SHORT = "${IOT}/${JOB_NAME}" + env.CODE_ADDR = "${GIT_ADDRESS}/free-sun/Highways4Good.git" + + stage('Run shell') { + git branch: 'dev', credentialsId: 'gitea-builder', url: "${CODE_ADDR}" + + container('image-builder') { + sh''' + pwd + ls -al + + /kaniko/executor --context=${BUILD_WORKSPACE} --dockerfile=./web/Dockerfilenew --destination=${IMAGE_NAME}:${IMAGE_VERSION} --cache=false --cleanup + + ''' + } + + buildName "${IMAGE_NAME_SHORT}:${IMAGE_VERSION}" + buildDescription "${IMAGE_NAME}:${IMAGE_VERSION}" + } + } +} \ No newline at end of file diff --git a/scripts/1.2.0/data/1.alter_user.sql b/scripts/1.2.0/data/1.alter_user.sql new file mode 100644 index 00000000..9060d773 --- /dev/null +++ b/scripts/1.2.0/data/1.alter_user.sql @@ -0,0 +1,2 @@ +ALTER TABLE public."user" +ADD COLUMN isadmin boolean; \ No newline at end of file diff --git a/scripts/1.2.0/data/2.create_task_manage.sql b/scripts/1.2.0/data/2.create_task_manage.sql new file mode 100644 index 00000000..35f30154 --- /dev/null +++ b/scripts/1.2.0/data/2.create_task_manage.sql @@ -0,0 +1,16 @@ +create table public.task_manage( +id SERIAL PRIMARY KEY , +roadId integer not null references public.road(id), +danger_description char(300), +issuance_time timestamp, +userId integer NOT NULL references public.user(id), +isdanger boolean, +report_time timestamp +); +comment on column public.task_manage.id is 'id'; +comment on column public.task_manage.roadId is '道路id'; +comment on column public.task_manage.danger_description is '隐患说明'; +comment on column public.task_manage.issuance_time is '下发时间'; +comment on column public.task_manage.userId is '用户id'; +comment on column public.task_manage.isdanger is '是否存在安全隐患,flase(不存在)'; +comment on column public.task_manage.report_time is '上报时间'; \ No newline at end of file diff --git a/scripts/1.2.1/schema/1update_report.sql b/scripts/1.2.1/schema/1update_report.sql new file mode 100644 index 00000000..cf54b557 --- /dev/null +++ b/scripts/1.2.1/schema/1update_report.sql @@ -0,0 +1,9 @@ +alter table report + add project_name varchar(512); + +alter table report alter column project_type drop not null; + +alter table report + add handle_state varchar(32) default '已处理' not null; + +comment on column report.handle_state is '待处理 / 已处理 / 不处理'; \ No newline at end of file diff --git a/weapp/project.config.json b/weapp/project.config.json index ad77fb8b..96d9c123 100644 --- a/weapp/project.config.json +++ b/weapp/project.config.json @@ -2,7 +2,7 @@ "miniprogramRoot": "dist/", "projectname": "四好公路", "description": "项目配置文件,详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html", - "appid": "wx3c0c46dcf49a85be", + "appid": "wx79ff58f03d17f24d", "setting": { "urlCheck": false, "es6": false, @@ -14,7 +14,7 @@ "autoAudits": false, "uglifyFileName": false, "uploadWithSourceMap": true, - "enhance": true, + "enhance": false, "showShadowRootInWxmlPanel": true, "packNpmManually": false, "packNpmRelationList": [], @@ -29,7 +29,8 @@ }, "disableUseStrict": false, "useCompilerPlugins": false, - "minifyWXML": true + "minifyWXML": true, + "condition": false }, "compileType": "miniprogram", "libVersion": "2.25.1", diff --git a/weapp/project.private.config.json b/weapp/project.private.config.json index afa214e8..55b00acb 100644 --- a/weapp/project.private.config.json +++ b/weapp/project.private.config.json @@ -1,7 +1,9 @@ { "projectname": "%E5%9B%9B%E5%A5%BD%E5%85%AC%E8%B7%AF", "setting": { - "compileHotReLoad": true + "compileHotReLoad": true, + "bigPackageSizeSupport": true }, - "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html" + "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html", + "libVersion": "2.32.2" } \ No newline at end of file diff --git a/weapp/src/components/uploads/index.js b/weapp/src/components/uploads/index.js new file mode 100644 index 00000000..76d44719 --- /dev/null +++ b/weapp/src/components/uploads/index.js @@ -0,0 +1,12 @@ +import React, { useState, useEffect } from 'react'; +import Taro, { useRouter } from '@tarojs/taro'; +import { View, RadioGroup, Radio, Image, Input, Picker } from '@tarojs/components'; + +const Index = () => { + + return( + 123 + ) +} + +export default Index diff --git a/weapp/src/config.js b/weapp/src/config.js index 329a027e..f2762e95 100644 --- a/weapp/src/config.js +++ b/weapp/src/config.js @@ -1,5 +1,5 @@ let DEV = false; -// DEV = true; //使用测试环境 +DEV = true; //使用测试环境 const baseConfig = { errorHandle: false, //是否启用全局异常处理‌‍‍‌‍​‌‌‍​‌‌‌‌‌​‌‌‍‌​‍‌‌‌‌​‍‍‍‍‌​‌‍‍‌‍​‌‌‍​‍‍‍‌‌​‍‌‌‌‌​‍‌‍‌​‍‌‌‌O @@ -8,7 +8,7 @@ const baseConfig = { }; const development = { - baseUrl: 'http://221.230.55.29:31919', + baseUrl: 'http://10.8.30.112:13400', // baseUrl: 'https://d763-117-90-37-10.ap.ngrok.io', // webUrl: 'https://smartwater.anxinyun.cn', // pcode: 'fce4afe2-5b6a-408a-ab18-a2afa7fa027c', @@ -29,4 +29,4 @@ const production = { const environment = DEV ? development : production; -export default environment; \ No newline at end of file +export default environment; diff --git a/weapp/src/packages/patrol/index.jsx b/weapp/src/packages/patrol/index.jsx index abe505fc..e0dbab9e 100644 --- a/weapp/src/packages/patrol/index.jsx +++ b/weapp/src/packages/patrol/index.jsx @@ -1,8 +1,9 @@ import React, { useState, useEffect } from 'react'; import Taro, { useRouter } from '@tarojs/taro'; -import { View, RadioGroup, Radio, Image, Input, Picker } from '@tarojs/components'; +import { View, RadioGroup, Radio, Image, Input, Picker, Video } from '@tarojs/components'; import { AtButton, AtTextarea, AtImagePicker } from 'taro-ui'; import InputPicker from '../components/inputPicker'; +import VideoUpload from '../../components/uploads' import request from '@/services/request'; import environment from '../../config'; import { getState } from '../../store/globalState'; @@ -17,11 +18,16 @@ const Index = () => { const isSuperAdmin = userInfo && userInfo.username === 'SuperAdmin' ? true : false const router = useRouter() - const { params: { type } } = router + const { params: { type, kind } } = router const isView = type === 'view' ? true : false + const isPatrol = kind === 'patrol' ? true : false + const isRoad = kind === 'road' ? true : false + const isAnomaly = kind === 'anomaly' ? true : false + const [reportType, setReportType] = useState('patrol') // 上报类型 const [projectType, setProjectType] = useState('') // 工程类型 + const [projectName, setProjectName] = useState('') // 项目名称 const [road, setRoad] = useState('') // 所在道路 const [roadSectionStart, setRoadSectionStart] = useState('') // 路段 Start const [roadSectionEnd, setRoadSectionEnd] = useState('') // 路段 End @@ -69,6 +75,12 @@ const Index = () => { ]) useEffect(() => { + if (isRoad) { + Taro.setNavigationBarTitle({ title: '在建道路' }) + } if (isAnomaly) { + Taro.setNavigationBarTitle({ title: '异常反馈' }) + } + if (isView) { // 查看 Taro.showLoading({ title: '加载中' }) request.get(getReportDetail(router.params.id)).then(res => { @@ -84,6 +96,7 @@ const Index = () => { } setReportType(data.reportType) setProjectType(showPrjType || data.projectType) + setProjectName(data.projectName) setRoad(data.road) setRoadSectionStart(data.roadSectionStart) setRoadSectionEnd(data.roadSectionEnd) @@ -111,8 +124,9 @@ const Index = () => { url: `https://apis.map.qq.com/ws/geocoder/v1/?location=${res.latitude},${res.longitude}&key=${key}`, success: function (res) { // 根据自己项目需求获取res内容 - let addresscity = res.data.result.address_component.province + res.data.result.address_component.city + res.data.result.address_component.district - setAddress(addresscity + res.data.result.address_component.street_number) + // let addresscity = res.data.result.address_component.province + res.data.result.address_component.city + res.data.result.address_component.district + // console.log(res, 'res') + setAddress(res.data.result.formatted_addresses.standard_address) } }) } @@ -161,13 +175,17 @@ const Index = () => { ]) }, [reportType]) - function report() { + function report () { if (!canReport) { return } - if (!projectType || !road) { + if ( + (isPatrol && (!projectType || !road)) + || (isAnomaly && !road) + ) { Taro.showToast({ title: '请完善必填信息', icon: 'none' }) return } - if (prjTypeSelector.indexOf(projectType) === -1) { + + if (isPatrol && prjTypeSelector.indexOf(projectType) === -1) { Taro.showToast({ title: '工程类型错误', icon: 'none' }) return } @@ -175,10 +193,14 @@ const Index = () => { Taro.showToast({ title: '内容字数不能超过50', icon: 'none' }) return } - const reportProjectType = prjType[prjTypeSelector.indexOf(projectType)].value + if (isRoad && !projectName) { + Taro.showToast({ title: '请完善项目名称', icon: 'none' }) + return + } + const reportProjectType = prjType[prjTypeSelector.indexOf(projectType)]?.value || '' let data = { - reportType, + reportType: isPatrol ? reportType : kind, projectType: reportProjectType, road, roadSectionStart, @@ -186,7 +208,9 @@ const Index = () => { address, content, longitude, - latitude + latitude, + projectName, + handleState: isAnomaly ? '待处理' : undefined, } if (reportType === 'patrol') { data['scenePic'] = sceneImg @@ -226,7 +250,7 @@ const Index = () => { }) } - function deleteReport() { + function deleteReport () { Taro.showModal({ title: '提示', content: '确定删除吗?', @@ -253,7 +277,7 @@ const Index = () => { }) } - function handleInput({ detail: { value } }, type) { + function handleInput ({ detail: { value } }, type) { switch (type) { case 'roadSectionStart': setRoadSectionStart(value) @@ -276,20 +300,24 @@ const Index = () => { break; case 'content': setContent(value) + break; + case "projectName": + setProjectName(value) + break; default: break; } } - function handleTypeChange(e) { + function handleTypeChange (e) { setReportType(e.detail.value) } - function handleImgChange(files, operationType, index, type) { + function handleImgChange (files, operationType, index, type) { if (operationType === 'remove') { setImg(false) } - function setImg(isAdd, url) { + function setImg (isAdd, url) { switch (type) { case 'scenePic': let nextImg = sceneImg @@ -376,7 +404,7 @@ const Index = () => { } } - function handleImgClick(index, file) { + function handleImgClick (index, file) { Taro.previewImage({ urls: [file.url] // 需要预览的图片http链接列表 }) @@ -385,7 +413,9 @@ const Index = () => { return ( { - (!isSuperAdmin || isView) && + (!isSuperAdmin || isView) + && !isRoad && !isAnomaly + && 上报类型 @@ -408,66 +438,92 @@ const Index = () => { } - - - - 所属路段: - handleInput(e, 'roadSectionStart')} - disabled={isView} - /> - { - !isView && - setRoadSectionStart(roadStartSel[e.detail.value])} - > - - - } - 至  - handleInput(e, 'roadSectionEnd')} - disabled={isView} - /> - { - !isView && - setRoadSectionEnd(roadEndSel[e.detail.value])} - > - - - } - + { + isPatrol ? + : '' + } + + { + isRoad ? + + 项目名称: + handleInput(e, 'projectName')} + disabled={isView} + /> + : '' + } + + { + isPatrol || isAnomaly ? + : '' + } + + { + isPatrol || isAnomaly ? + + 所属路段: + handleInput(e, 'roadSectionStart')} + disabled={isView} + /> + { + !isView && + setRoadSectionStart(roadStartSel[e.detail.value])} + > + + + } + 至  + handleInput(e, 'roadSectionEnd')} + disabled={isView} + /> + { + !isView && + setRoadSectionEnd(roadEndSel[e.detail.value])} + > + + + } + : '' + } 具体位置: @@ -490,7 +546,7 @@ const Index = () => { maxLength={50} /> { - reportType === 'patrol' ? + reportType === 'patrol' || isRoad || isAnomaly ? 现场图片: { @@ -509,6 +565,46 @@ const Index = () => { onImageClick={handleImgClick} /> } + + {/* : 养护图片: @@ -532,6 +628,7 @@ const Index = () => { onImageClick={handleImgClick} /> } + 养护中 @@ -577,11 +674,13 @@ const Index = () => { } { isView ? - isSuperAdmin && 删除 : + isSuperAdmin && + 删除 + : 上报 } ) } -export default Index \ No newline at end of file +export default Index diff --git a/weapp/src/packages/patrolView/index.jsx b/weapp/src/packages/patrolView/index.jsx index fe60a993..e508a139 100644 --- a/weapp/src/packages/patrolView/index.jsx +++ b/weapp/src/packages/patrolView/index.jsx @@ -14,12 +14,16 @@ import patrolActiveIcon from '../../static/img/patrolView/patrol-active.svg' import conserveIcon from '../../static/img/patrolView/conserve.svg' import conserveActiveIcon from '../../static/img/patrolView/conserve-active.svg' -function Index() { +function Index () { const userInfo = Taro.getStorageSync('userInfo') || {}; const router = useRouter() - const { params: { filter } } = router + const { params: { filter, kind } } = router - const [isPatrol, setIsPatrol] = useState(true) + const isPatrol = kind === 'patrol' ? true : false + const isRoad = kind === 'road' ? true : false + const isAnomaly = kind === 'anomaly' ? true : false + + const [reportType, setReportType] = useState(kind || 'patrol') const [datePicker, setDatePicker] = useState('') const [listData, setListData] = useState([]) const [filterText, setFilterText] = useState('') @@ -29,16 +33,24 @@ function Index() { const limit = 10 + useEffect(() => { + if (isRoad) { + Taro.setNavigationBarTitle({ title: '在建道路' }) + } if (isAnomaly) { + Taro.setNavigationBarTitle({ title: '异常反馈' }) + } + }, []) + useEffect(() => { setPage(0) setNum(Math.random()) - }, [isPatrol, datePicker]) + }, [reportType, datePicker]) useEffect(() => { getList(page == 0 ? true : false) }, [num]) - function dealError(error) { + function dealError (error) { Taro.showToast({ title: error, icon: 'none', @@ -54,7 +66,7 @@ function Index() { startTime: datePicker ? datePicker + ' 00:00:00' : '', endTime: datePicker ? datePicker + ' 23:59:59' : '', keyword: filterText, - reportType: isPatrol ? 'patrol' : 'conserve', + reportType: reportType, userId: filter === 'my' ? userInfo.id : '', } request.get(getReportList(), data).then(res => { @@ -99,10 +111,6 @@ function Index() { }); }) - const onTypeChange = bool => { - setIsPatrol(bool) - } - const onDateChange = e => { setDatePicker(e.detail.value); } @@ -121,23 +129,28 @@ function Index() { } const handleDetail = index => { - Taro.navigateTo({ url: `/packages/patrol/index?type=view&id=${listData[index].id}` }) + Taro.navigateTo({ url: `/packages/patrol/index?type=view&id=${listData[index].id}&kind=${kind}` }) } return ( - - onTypeChange(true)}> - - 巡查 - - - onTypeChange(false)}> - - 养护 - - - + { + isPatrol ? + + setReportType('patrol')}> + + 巡查 + + + setReportType('conserve')}> + + 养护 + + + : "" + } + + 日期: - + - + { listData && listData.length > 0 ? listData && listData.map((e, index) => { return ( @@ -166,7 +180,7 @@ function Index() { - {e.road} + {e.road || e.projectName} 填报人: {e.user && e.user.name} diff --git a/weapp/src/packages/patrolView/index.scss b/weapp/src/packages/patrolView/index.scss index 7de6c587..a1d36cc0 100644 --- a/weapp/src/packages/patrolView/index.scss +++ b/weapp/src/packages/patrolView/index.scss @@ -11,7 +11,7 @@ page { display: flex; justify-content: space-around; align-items: center; - + .item { flex-grow: 1; display: flex; @@ -34,7 +34,7 @@ page { .filter-box { position: fixed; - top: 80px; + // top: 80px; display: flex; width: 100%; z-index: 100; @@ -136,4 +136,4 @@ page { } } } -} \ No newline at end of file +} diff --git a/weapp/src/pages/home/index.jsx b/weapp/src/pages/home/index.jsx index b6a3166c..18db4a91 100644 --- a/weapp/src/pages/home/index.jsx +++ b/weapp/src/pages/home/index.jsx @@ -26,18 +26,18 @@ const Index = () => { } }, []) - function toPatrol() { + function toPatrol (kind) { Taro.navigateTo({ - url: '/packages/patrol/index?type=edit' + url: `/packages/patrol/index?type=edit&kind=${kind}` }) } - function toPatrolView() { + function toPatrolView (kind) { Taro.navigateTo({ - url: '/packages/patrolView/index' + url: `/packages/patrolView/index?kind=${kind}` }) } - function toVideo() { + function toVideo () { Taro.navigateTo({ url: '/packages/video/index' }) @@ -47,7 +47,31 @@ const Index = () => { 巡 查 养 护 - + toPatrolView('patrol') + : () => toPatrol('patrol') + }> + {isSuperAdmin ? '查看' : '填报'} + + + + 在 建 道 路 + toPatrolView('road') + : () => toPatrol('road') + }> + {isSuperAdmin ? '查看' : '填报'} + + + + 异 常 反 馈 + toPatrolView('anomaly') + : () => toPatrol('anomaly') + }> {isSuperAdmin ? '查看' : '填报'} diff --git a/weapp/src/pages/home/index.scss b/weapp/src/pages/home/index.scss index ad17ea81..3fdebb5c 100644 --- a/weapp/src/pages/home/index.scss +++ b/weapp/src/pages/home/index.scss @@ -7,13 +7,21 @@ margin-top: 30px; padding: 10px; width: 94%; - height: 360px; + height: 280px; } .fill { background: url('../../static/img/home/fill-bg.svg') no-repeat; background-size: 100% 100%; } + .fill_road { + background: url('../../static/img/home/fill-road.svg') no-repeat; + background-size: 100% 100%; + } + .fill_anomaly { + background: url('../../static/img/home/fill-anomaly.svg') no-repeat; + background-size: 100% 100%; + } .video { background: url('../../static/img/home/video-bg.svg') no-repeat; @@ -34,4 +42,4 @@ border: solid 1px #fff; border-radius: 10px; } -} \ No newline at end of file +} diff --git a/weapp/src/pages/user/index.jsx b/weapp/src/pages/user/index.jsx index bc96468d..14b73fd2 100644 --- a/weapp/src/pages/user/index.jsx +++ b/weapp/src/pages/user/index.jsx @@ -23,15 +23,15 @@ const Index = ({ ...props }) => { Taro.navigateTo({ url: '/packages/changePassword/index' }) } - const toMyReport = () => { + const toMyReport = (kind) => { Taro.navigateTo({ - url: '/packages/patrolView/index?filter=my' + url: `/packages/patrolView/index?filter=my&kind=${kind}` }) } - const toPatrolReport = () => { + const toPatrolReport = (kind) => { Taro.navigateTo({ - url: '/packages/patrol/index?type=edit' + url: `/packages/patrol/index?type=edit&kind=${kind}` }) } @@ -64,7 +64,7 @@ const Index = ({ ...props }) => { - + toPatrolReport('patrol') : () => toMyReport('patrol')}> {isSuperAdmin ? '巡查上报' : '我的上报'} @@ -72,6 +72,22 @@ const Index = ({ ...props }) => { + toPatrolReport('road') : () => toMyReport('road')}> + + + {isSuperAdmin ? '在建道路上报' : '在建道路'} + + + + + toPatrolReport('anomaly') : () => toMyReport('anomaly')}> + + + {isSuperAdmin ? '异常反馈上报' : '异常反馈'} + + + + 修改密码 diff --git a/weapp/src/static/img/home/fill-anomaly.svg b/weapp/src/static/img/home/fill-anomaly.svg new file mode 100644 index 00000000..15b0a0b1 --- /dev/null +++ b/weapp/src/static/img/home/fill-anomaly.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/weapp/src/static/img/home/fill-bg.svg b/weapp/src/static/img/home/fill-bg.svg index 0a4b818d..f05371c4 100644 --- a/weapp/src/static/img/home/fill-bg.svg +++ b/weapp/src/static/img/home/fill-bg.svg @@ -1,126 +1,130 @@ - - - 椭圆形 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/weapp/src/static/img/home/fill-road.svg b/weapp/src/static/img/home/fill-road.svg new file mode 100644 index 00000000..14424e18 --- /dev/null +++ b/weapp/src/static/img/home/fill-road.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/Dockerfile b/web/Dockerfile index aa89cac0..b6a41cbd 100644 --- a/web/Dockerfile +++ b/web/Dockerfile @@ -9,6 +9,7 @@ RUN npm install --registry http://10.8.30.22:7000 RUN npm run build RUN rm -rf client/src RUN rm -rf node_modules +RUN rm -rf package-lock.json RUN npm install --production --force --registry http://10.8.30.22:7000 FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node-16:7.22-06-20 COPY --from=builder --chown=node /var/app /home/node/app diff --git a/web/Dockerfilenew b/web/Dockerfilenew new file mode 100644 index 00000000..b521e017 --- /dev/null +++ b/web/Dockerfilenew @@ -0,0 +1,17 @@ +FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node:12-dev as builder +COPY . /var/app +WORKDIR /var/app +EXPOSE 8080 +RUN npm config set registry=https://nexus.ngaiot.com/repository/fs-npm/ +RUN echo "{\"time\":\"$BUILD_TIMESTAMP\",\"build\": \"$BUILD_NUMBER\",\"revision\": \"$SVN_REVISION_1\",\"URL\":\"$SVN_URL_1\"}" > version.json +RUN npm cache clean -f +RUN rm -rf package-lock.json +RUN npm install --registry https://nexus.ngaiot.com/repository/fs-npm/ +RUN npm run build +RUN rm -rf client/src +RUN rm -rf node_modules +RUN npm install --production --force --registry https://nexus.ngaiot.com/repository/fs-npm/ +FROM registry.cn-hangzhou.aliyuncs.com/fs-devops/node-16:7.22-06-20 +COPY --from=builder --chown=node /var/app /home/node/app +WORKDIR /home/node/app +CMD ["node", "server.js"] \ No newline at end of file diff --git a/web/client/assets/images/jiekou.png b/web/client/assets/images/jiekou.png new file mode 100644 index 00000000..48469507 Binary files /dev/null and b/web/client/assets/images/jiekou.png differ diff --git a/web/client/assets/images/tiptop.png b/web/client/assets/images/tiptop.png new file mode 100644 index 00000000..4110aef0 Binary files /dev/null and b/web/client/assets/images/tiptop.png differ diff --git a/web/client/src/app.js b/web/client/src/app.js index 967a18ac..bdb89ab3 100644 --- a/web/client/src/app.js +++ b/web/client/src/app.js @@ -1,4 +1,4 @@ -'use strict'; +'use strict' import React, { useEffect } from 'react'; import Layout from './layout'; @@ -18,7 +18,7 @@ const App = props => { return ( ) } diff --git a/web/client/src/layout/containers/layout/index.js b/web/client/src/layout/containers/layout/index.js index b9dc0061..dabb4eea 100644 --- a/web/client/src/layout/containers/layout/index.js +++ b/web/client/src/layout/containers/layout/index.js @@ -46,10 +46,11 @@ const LayoutContainer = props => { )); } useEffect(() => { - dispatch(getDepMessage()).then((res) => { - setDepMessage(res) - }) - }, [true]) + if (user && user.authorized) + dispatch(getDepMessage()).then((res) => { + setDepMessage(res) + }) + }, [user]) useEffect(() => { scrollbar = new PerfectScrollbar('#page-content', { suppressScrollX: true }); }, []) @@ -74,9 +75,7 @@ const LayoutContainer = props => { dom.scrollTop = 0; } }) - // if (depMessage) { - // console.log(depMessage); - // } + let contentStyle = { position: 'relative', margin: '12px 12px 0px', diff --git a/web/client/src/layout/index.js b/web/client/src/layout/index.js index ba1db6b0..f7f4d123 100644 --- a/web/client/src/layout/index.js +++ b/web/client/src/layout/index.js @@ -90,7 +90,7 @@ const Root = props => { let actions = { layout: layoutActions } - + for (let s of sections) { if (!s.key) console.warn('请给你的section添加一个key值,section name:' + s.name); for (let r of s.routes) { diff --git a/web/client/src/sections/auth/containers/login.js b/web/client/src/sections/auth/containers/login.js index f8a6685f..5bb5ca5e 100644 --- a/web/client/src/sections/auth/containers/login.js +++ b/web/client/src/sections/auth/containers/login.js @@ -50,7 +50,7 @@ const Login = props => { return } setInputChanged(false) - dispatch(login("12345678912564589", "123456789")) + dispatch(login(username, password)) } @@ -60,34 +60,36 @@ const Login = props => {

南昌县智慧交通监管系统

-
- -
用户名
- { - setUserName(e.target.value) - setInputChanged(true) - }} - /> -
-
密码
- - + +
用户名
+ { + console.log('e.target.value', e.target.value) + setUserName(e.target.value) + setInputChanged(true) + }} + /> +
+
密码
+ + { - setPassword(e.target.value) - setInputChanged(true) - }} - /> - - + onChange={e => { + console.log('setPassword', e.target.value) + setPassword(e.target.value) + setInputChanged(true) + }} + /> +
+
diff --git a/web/client/src/sections/fillion/actions/patrol.js b/web/client/src/sections/fillion/actions/patrol.js index 63507bd9..a1befe8a 100644 --- a/web/client/src/sections/fillion/actions/patrol.js +++ b/web/client/src/sections/fillion/actions/patrol.js @@ -2,7 +2,7 @@ import { basicAction } from '@peace/utils' import { ApiTable } from '$utils' -export function getReportList(query) { +export function getReportList (query) { return dispatch => basicAction({ type: 'get', dispatch: dispatch, @@ -14,7 +14,7 @@ export function getReportList(query) { }); } -export function getReportDetail(reportId) { +export function getReportDetail (reportId) { return dispatch => basicAction({ type: 'get', dispatch: dispatch, @@ -25,7 +25,7 @@ export function getReportDetail(reportId) { }); } -export function getUserList(query) { +export function getUserList (query) { return dispatch => basicAction({ type: 'get', dispatch: dispatch, @@ -36,3 +36,14 @@ export function getUserList(query) { reducer: { name: 'userList' } }); } + +export function handleReport (reportId, data) { + return dispatch => basicAction({ + type: 'post', + dispatch: dispatch, + actionType: 'HANDLE_REPORT', + url: ApiTable.handleReport.replace("{reportId}", reportId), + data: data, + msg: { option: '处理数据' }, + }); +} \ No newline at end of file diff --git a/web/client/src/sections/fillion/actions/task.js b/web/client/src/sections/fillion/actions/task.js new file mode 100644 index 00000000..da5adf81 --- /dev/null +++ b/web/client/src/sections/fillion/actions/task.js @@ -0,0 +1,35 @@ +import { basicAction } from '@peace/utils' +import { ApiTable } from '$utils' + +export function getTask(query) { + return dispatch => basicAction({ + type: 'get', + dispatch: dispatch, + query: query, + actionType: 'GET_TASK', + url: ApiTable.getTask, + msg: { error: '获取任务信息' }, + reducer: { name: 'task' } + }); +} + +export function delTask(query) { + return dispatch => basicAction({ + type: 'del', + dispatch: dispatch, + actionType: 'DEL_TASK', + url: ApiTable.delTask.replace("{taskId}", query?.id), + msg: { option: '删除任务信息' }, + }); +} + +export function editTask(query) { + return dispatch => basicAction({ + type: 'put', + dispatch: dispatch, + data: query, + actionType: 'PUT_TASK', + url: ApiTable.editTask, + msg: { option: '编辑或新增任务信息' }, + }); +} \ No newline at end of file diff --git a/web/client/src/sections/fillion/components/datajuji.js b/web/client/src/sections/fillion/components/datajuji.js new file mode 100644 index 00000000..4d3838d7 --- /dev/null +++ b/web/client/src/sections/fillion/components/datajuji.js @@ -0,0 +1,180 @@ +import React, { useEffect, useState } from 'react'; +import { Modal, Form, Input, Select, DatePicker, AutoComplete, Col, Button, Row } from 'antd'; + +import { MinusCircleOutlined, PlusOutlined, PlusCircleOutlined } from '@ant-design/icons'; +const Search = Input.Search +const { TextArea } = Input; +import moment from 'moment'; + +const EditGuanlang = (props) => { + const { visible, onCancel, editData, handleSaveScore, readOnly, companys, searchCompany, applyState } = props; + const [form] = Form.useForm(); + const [replyFiles, setReplyFiles] = useState([]); + const [companyOpts, setCompanyOpts] = useState([]); + const [stationItem, setStationItem] = useState(null); + const [deviceList, setDeviceList] = useState([]); + + useEffect(() => { + if (!visible) { + form.resetFields() + } + }, [visible]) + + useEffect(() => { + if (editData) { + let revertData = Object.assign({}, editData); + Object.keys(editData).forEach(key => { + if (key == 'accidentTime') { + revertData[key] = editData[key] && moment(editData[key]); + } + if (key == 'images') { + // const list = (editData[key] || '').split(',') || [] + if (editData[key]) { + + revertData[key] = JSON.parse(editData[key]); + } + } + }); + form.setFieldsValue({ ...revertData }); + } + }, [editData]) + + useEffect(() => { + if (companys && companys.length) { + let list = []; + companys.forEach(item => { + list.push({ label: item.company, value: item.company }) + }) + setCompanyOpts(list); + } + }, [companys]) + + useEffect(() => { + if (editData && companys && companys.length) { + handleSelectCompany(null, { value: editData.companyName }) + let list = ((editData || {}).accidentStations || []).map(item => item.stationId) + form.setFieldsValue({ stations: list }) + } + }, [companys, editData]) + + + const handleSave = () => { + const data = form.getFieldsValue(true); + console.log(data, 'data') + handleSaveScore(); + } + + const onFileUploaded = (fileList) => { + setReplyFiles(fileList); + } + + const handleSelectCompany = (v, opt) => { + const { value } = opt; + const target = companys.filter(c => c.company == value); + setDeviceList(target[0]?.deviceInfos || []); + + } + const data1 = [ + { label: '2021年12月', value: '2021年12月' }, + { label: '2021年11月', value: '2021年11月' }, + { label: '2021年10月', value: '2021年10月' }, + { label: '2021年9月', value: '2021年9月' }, + { label: '2021年8月', value: '2021年8月' }, + { label: '2021年7月', value: '2021年7月' }, + { label: '2021年6月', value: '2021年6月' }, + { label: '2021年5月', value: '2021年5月' }, + { label: '2021年4月', value: '2021年4月' }, + { label: '2021年3月', value: '2021年3月' }, + { label: '2021年2月', value: '2021年2月' }, + { label: '2021年1月', value: '2021年1月' }] + + const data2 = [ + { label: '噪声传感器', value: '噪声传感器' }, + { label: '导轮式固定测斜仪', value: '导轮式固定测斜仪' }, + { label: '闭合式磁通量传感器', value: '闭合式磁通量传感器' }, + { label: '扬尘监测系统', value: '扬尘监测系统' }, + { label: '空气质量监测系统', value: '空气质量监测系统' }, + { label: '车辆动态称重系统', value: '车辆动态称重系统' }, + { label: '多通道振动采集仪', value: '多通道振动采集仪' }, + { label: '应急照明控制器', value: '应急照明控制器' }, + { label: '钢筋计', value: '钢筋计' }, + { label: '噪声传感器', value: '噪声传感器' }, + { label: '风速风向仪', value: '风速风向仪' }, + { label: '静力水准仪', value: '静力水准仪' }, + { label: '表面式应变计', value: '表面式应变计' }, + { label: '光纤光栅锚索计', value: '光纤光栅锚索计' }, + { label: '加速度计', value: '加速度计' }, + { label: '闭合式磁通量传感器', value: '闭合式磁通量传感器' }, + { label: '开环式磁通量传感器', value: '开环式磁通量传感器' }, + { label: '压差式变形测量传感器', value: '压差式变形测量传感器' }, + { label: '多通道振动采集仪', value: '多通道振动采集仪' }, + { label: '压电式传感器', value: '压电式传感器' }, + { label: '钢筋计', value: '钢筋计' }, + { label: '盒式固定测斜仪', value: '盒式固定测斜仪' }, + { label: '拉线位移传感器', value: '拉线位移传感器' }, + { label: '表面式应变计', value: '表面式应变计' }, + { label: '芯型土压力计', value: '芯型土压力计' }, + { label: '芯型锚索计', value: '芯型锚索计' }, + { label: '收敛仪', value: '收敛仪' }, + { label: '激光测距仪 ', value: '激光测距仪 ' }, + { label: '磁电式传感器', value: '磁电式传感器' }, + { label: '压电式传感器', value: '压电式传感器' }, + { label: '锚索计', value: '锚索计' }, + { label: '静力水准仪 ', value: '静力水准仪 ' }, + { label: '移动测斜仪 ', value: '移动测斜仪 ' } + ] + return ( + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ *汇集历史数据,接入物联网监测数据,实现大数据的接入解算。 +
+ ) +} + + +export default EditGuanlang; diff --git a/web/client/src/sections/fillion/components/editGuanlang.js b/web/client/src/sections/fillion/components/editGuanlang.js new file mode 100644 index 00000000..b335e6e9 --- /dev/null +++ b/web/client/src/sections/fillion/components/editGuanlang.js @@ -0,0 +1,211 @@ +import React, { useEffect, useState } from 'react'; +import { Modal, Form, Input, Select, DatePicker, AutoComplete, Col, Button,Row } from 'antd'; + +import { MinusCircleOutlined, PlusOutlined,PlusCircleOutlined } from '@ant-design/icons'; +const Search = Input.Search +const { TextArea } = Input; +import moment from 'moment'; + +const EditGuanlang = (props) => { + const { visible, onCancel, editData, handleSaveScore, readOnly, companys, searchCompany, applyState } = props; + const [form] = Form.useForm(); + const [replyFiles, setReplyFiles] = useState([]); + const [companyOpts, setCompanyOpts] = useState([]); + const [stationItem, setStationItem] = useState(null); + const [deviceList, setDeviceList] = useState([]); + + useEffect(() => { + if (!visible) { + form.resetFields() + } + }, [visible]) + + useEffect(() => { + if (editData) { + let revertData = Object.assign({}, editData); + Object.keys(editData).forEach(key => { + if (key == 'accidentTime') { + revertData[key] = editData[key] && moment(editData[key]); + } + if (key == 'images') { + // const list = (editData[key] || '').split(',') || [] + if (editData[key]) { + + revertData[key] = JSON.parse(editData[key]); + } + } + }); + form.setFieldsValue({ ...revertData }); + } + }, [editData]) + + useEffect(() => { + if (companys && companys.length) { + let list = []; + companys.forEach(item => { + list.push({ label: item.company, value: item.company }) + }) + setCompanyOpts(list); + } + }, [companys]) + + useEffect(() => { + if (editData && companys && companys.length) { + handleSelectCompany(null, { value: editData.companyName }) + let list = ((editData || {}).accidentStations || []).map(item => item.stationId) + form.setFieldsValue({ stations: list }) + } + }, [companys, editData]) + + + const handleSave = () => { + const data = form.getFieldsValue(true); + console.log(data,'data') + handleSaveScore(); + } + + const onFileUploaded = (fileList) => { + setReplyFiles(fileList); + } + + const handleSelectCompany = (v, opt) => { + const { value } = opt; + const target = companys.filter(c => c.company == value); + setDeviceList(target[0]?.deviceInfos || []); + + } + + return ( + +
+ + + 配置属性 + + {/* */} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ ) +} + + +export default EditGuanlang; diff --git a/web/client/src/sections/fillion/components/inforTable.js b/web/client/src/sections/fillion/components/inforTable.js index 91779539..fa803831 100644 --- a/web/client/src/sections/fillion/components/inforTable.js +++ b/web/client/src/sections/fillion/components/inforTable.js @@ -6,7 +6,7 @@ import './protable.less' import moment from 'moment'; import { getPurchase, delPurchase } from "../actions/infor" import UserModal from './infor/details'; - +import Datajuji from './datajuji' const InForTable = (props) => { const { dispatch, user, depData, depMessage, depLoading } = props const [rowSelected, setRowSelected] = useState([]) @@ -23,6 +23,7 @@ const InForTable = (props) => { const [overrunRateUpper, setOverrunRateUpper] = useState()//超限率上限 const [overrunRateFloor, setOverrunRateFloor] = useState()//超限率下限 const [testTime, setTestTime] = useState()//超限率下限 + const [datajuji, setdatajuji] = useState() //数据聚集弹窗 const ref = useRef() useEffect(() => { ref.current.reload() }, [monitor, delet]) //打开弹窗 @@ -381,6 +382,13 @@ const InForTable = (props) => { > 新增 + + {/* */} {/* , + isAnomaly && record.handleState != '已处理' ? : null, + isAnomaly && record.handleState != '已处理' ? + + + + + ]} + visible={noProcessingSelectRecord == record.id && noProcessingPopVisible} + trigger="click" + onClick={() => setNoProcessingSelectRecord(record.id)} + title="是否不处理该记录?" + onVisibleChange={(newVisible) => setNoProcessingPopVisible(newVisible)} + > + + : null, @@ -193,7 +241,7 @@ const DetailList = (props) => { ] } }, - ]; + ].filter(s => s); return ( { useEffect(() => { - - if (userList && userList instanceof Array && userList.length) { - setSelectRoad(userList[0].id) - // onChange(userList[0]); - } - if(activeTabKey1 == 'tab2'){ - setSelectRoad(null) - } + + if (userList && userList instanceof Array && userList.length) { + setSelectRoad(userList[0].id) + // onChange(userList[0]); + } + if (activeTabKey1 == 'tab2') { + setSelectRoad(null) + } }, [userList, activeTabKey1]) @@ -280,9 +328,8 @@ const PatrolNameList = (props) => { return { onClick: () => { if (record) { - // console.log('record:', record) - let id = record.id - if(selectRoad == record.id){ + let id = record.id + if (selectRoad == record.id) { id = null } setSelectRoad(id); @@ -299,7 +346,7 @@ const PatrolNameList = (props) => { const PatrolTable = (props) => { - const { userList, reportList, dispatch, reportListLoading, reportDetail, reportDetailLoading, userLoading, exports } = props; + const { userList, reportList, dispatch, reportListLoading, reportDetail, reportDetailLoading, userLoading, exports, pathname } = props; const [record, setRecord] = useState(); const [dateRange, setDateRange] = useState(); const [detailVisible, setDetailVisible] = useState(false) @@ -307,6 +354,11 @@ const PatrolTable = (props) => { const { RangePicker } = DatePicker; + const isRoad = pathname.includes('road') + const isAnomaly = pathname.includes('anomaly') + const isPatrol = !isRoad && !isAnomaly + const reportType = isRoad ? 'road' : isAnomaly ? 'anomaly' : 'patrol'; + useEffect(() => { if (userList && userList instanceof Array) { setRecord(userList[0]); @@ -320,7 +372,7 @@ const PatrolTable = (props) => { }, [record, dateRange]) const queryData = () => { - let query = { userId: record.id, reportType: 'patrol', asc: true } + let query = { userId: record.id, reportType: reportType, asc: true } if ((dateRange && dateRange instanceof Array && dateRange[0] != '')) { query.startTime = moment(dateRange[0]).startOf('day').format('YYYY-MM-DD HH:mm:ss') query.endTime = moment(dateRange[1]).endOf('day').format('YYYY-MM-DD HH:mm:ss') @@ -337,7 +389,7 @@ const PatrolTable = (props) => { }, [activeTabKey1]) const handelRefresh = () => { - let query = { userId: record.id, reportType: 'patrol', asc: true } + let query = { userId: record.id, reportType: reportType, asc: true } dispatch(getReportList(query)); } @@ -358,11 +410,16 @@ const PatrolTable = (props) => { }, ]; const contentList = { - tab1: [
- - - -
], + tab1: [ +
+ + + +
+ ], tab2: }; const onTab1Change = (key) => { @@ -380,7 +437,7 @@ const PatrolTable = (props) => { const handleExport = () => { if (reportList && reportList instanceof Array && reportList.length) { let ids = reportList.map(item => item.id); - exports(ids); + exports(ids, reportType); } } @@ -396,25 +453,28 @@ const PatrolTable = (props) => { { onTab1Change(key); }} > { - activeTabKey1 == 'tab1' ?
- { setDateRange(dateString) }} /> - - -
: '' + activeTabKey1 == 'tab1' ? +
+ { setDateRange(dateString) }} /> + + {/* */} +
: '' } {contentList[activeTabKey1]} + loading={reportDetailLoading} + isPatrol={isPatrol} isRoad={isRoad} isAnomaly={isAnomaly} + />
diff --git a/web/client/src/sections/fillion/components/task/addTaskModal.js b/web/client/src/sections/fillion/components/task/addTaskModal.js new file mode 100644 index 00000000..dcae9d7d --- /dev/null +++ b/web/client/src/sections/fillion/components/task/addTaskModal.js @@ -0,0 +1,152 @@ +import React, { useState, useEffect, useRef } from 'react'; +import { Modal, Form, Input, Select, Button } from 'antd'; +import { connect } from 'react-redux'; +import { getRoadway } from '../../actions/infor' +import { getUserList } from '../../actions/patrol'; +import { editTask } from '../../actions/task'; + +const AddModal = (props) => { + const { dispatch, recordRow, visible, onClose, user, lookVal } = props + const { TextArea } = Input + const [form] = Form.useForm() + const [inputVal, setIputVal] = useState(undefined) + const [selectVal, setSelectVal] = useState('') + const [roadRes, setRoadRes] = useState([])//路线列表 + const [userList, setUserList] = useState([])//用户列表 + useEffect(async () => { + const res = await dispatch(getUserList()) + setUserList(res?.payload.data) + }, [true]) + + const onChange = () => { + form.resetFields(['code'])//清空具体某个表单的值 + } + useEffect(() => { + form.setFieldsValue(recordRow ? { 'name': recordRow?.road.id, 'code': recordRow?.road.id, 'danger': recordRow?.dangerDescription, 'user': recordRow?.user.id } : {}) + }, [recordRow]) + useEffect(async () => { + const res = await dispatch(getRoadway({})) + setRoadRes(res?.payload.data) + }, []) + //新增和修改 + const handleSaveUpdate = () => { + form.validateFields().then((values) => { + //console.log('values', recordRow) + //console.log('values', values) + const val = { + dangerDescription: values.danger, + userId: values.user, + routeId: values.name, + id: recordRow?.id + } + dispatch(editTask(val)).then(res => { + if (res.success) { + onClose() + form.resetFields() + } + }) + }) + } + + return ( + { + onClose() + form.resetFields()//清空所有个表单的值 + setSelectVal('')//置空路线代码的选择 + }} + onOk={ + handleSaveUpdate + } + footer={ + lookVal ? null : [ + , + + ] + } + > +
+ + + {selectVal} + + + +