wuqun 2 years ago
parent
commit
03b2e0bc85
  1. 3
      api/.vscode/launch.json
  2. 2
      api/app/lib/controllers/organization/user.js
  3. 24
      api/app/lib/controllers/patrolManage/patrolRecord.js
  4. 64
      api/app/lib/controllers/patrolManage/yujingguanli.js
  5. 5
      api/app/lib/models/patrol_record.js
  6. 45
      api/app/lib/models/patrol_record_issue_handle.js
  7. 11
      api/app/lib/routes/patrolManage/yujingguanli.js
  8. 2
      api/config.js
  9. 126
      api/log/development.log
  10. 2
      script/1.0.4/schema/3.updata_resource.sql
  11. 5
      script/1.0.4/schema/4.updata_patrol_record_issue__handle.sql
  12. 4
      script/1.0.5/schema/2.update_patrol_record.sql
  13. 4
      script/1.0.5/schema/3.update_patrol_record_issue_handle.sql
  14. 3
      weapp/app.json
  15. BIN
      weapp/images/circle.png
  16. 1
      weapp/images/refresh.svg
  17. 6
      weapp/package/inspectionInput/inspectionInput.js
  18. 66
      weapp/package/pointsStatus/pointsStatus.js
  19. 3
      weapp/package/pointsStatus/pointsStatus.json
  20. 2
      weapp/package/pointsStatus/pointsStatus.wxml
  21. 1
      weapp/package/pointsStatus/pointsStatus.wxss
  22. 14
      weapp/package/troubleshooting/index.js
  23. 3
      weapp/package/troubleshooting/index.json
  24. 12
      weapp/package/troubleshooting/index.wxml
  25. 44
      weapp/package/troubleshooting/shootingForm/index.js
  26. 11
      weapp/package/troubleshooting/shootingForm/index.wxml
  27. 157
      weapp/pages/index/index.js
  28. 44
      weapp/pages/index/index.wxml
  29. 80
      weapp/pages/index/index.wxss
  30. 5
      web/client/src/app.js
  31. 42
      web/client/src/sections/auth/containers/login.js
  32. 56
      web/client/src/sections/issueHandle/components/isuue-handle-mdal.js
  33. 8
      web/client/src/sections/issueHandle/containers/patrolRecord.js
  34. 2
      web/client/src/sections/patrolManage/actions/index.js
  35. 13
      web/client/src/sections/patrolManage/actions/yujingguanli.js
  36. 8
      web/client/src/sections/patrolManage/components/planModal.js
  37. 78
      web/client/src/sections/patrolManage/components/xiafagaojin.js
  38. 3
      web/client/src/sections/patrolManage/containers/index.js
  39. 2
      web/client/src/sections/patrolManage/containers/patrolRecord.js
  40. 4
      web/client/src/sections/patrolManage/containers/patrolReport.js
  41. 217
      web/client/src/sections/patrolManage/containers/yujingguanli.js
  42. 3
      web/client/src/sections/patrolManage/nav-item.js
  43. 11
      web/client/src/sections/patrolManage/routes.js
  44. 9
      web/client/src/sections/shouye/actions/index.js
  45. 9
      web/client/src/sections/shouye/containers/index.js
  46. 62
      web/client/src/sections/shouye/containers/shouye.js
  47. 15
      web/client/src/sections/shouye/index.js
  48. 21
      web/client/src/sections/shouye/nav-item.js
  49. 5
      web/client/src/sections/shouye/reducers/index.js
  50. 32
      web/client/src/sections/shouye/routes.js
  51. 20
      web/client/src/sections/shouye/style.less
  52. 1
      web/client/src/utils/webapi.js

3
api/.vscode/launch.json

@ -15,7 +15,8 @@
"args": [
"-p 4900",
//
"-g postgres://FashionAdmin:123456@10.8.30.39:5432/Inspection",
// "-g postgres://FashionAdmin:123456@10.8.30.39:5432/Inspection",
"-g postgres://postgres:123456@10.8.16.184:5432/XunJian",
// "-g postgres://FashionAdmin:123456@10.8.30.156:5432/inspection",
//
// "--apiEmisUrl http://10.8.30.161:1111",

2
api/app/lib/controllers/organization/user.js

@ -172,7 +172,7 @@ async function getUser (ctx, next) {
const models = ctx.fs.dc.models;
const { depId } = ctx.params;
let userRes = null;
if (depId !== 'null') {
if (depId !== 'undefined') {
userRes = await models.User.findAll({
where: {
departmentId: parseInt(depId),

24
api/app/lib/controllers/patrolManage/patrolRecord.js

@ -169,26 +169,38 @@ async function addPatrolRecord (ctx, next) {
try {
const models = ctx.fs.dc.models;
const data = ctx.request.body;
let { patrolPlanId, inspectionTime, points, alarm, pointId } = data
let { patrolPlanId, inspectionTime, points, alarm, pointId, projectId } = data
const pointRecord = await models.PatrolRecord.findAll({
where: { pointId: pointId },
order: [['inspectionTime', 'desc']],
attributes: ['inspectionTime'],
});
const lastInspectionTime = pointRecord.length ? pointRecord[0].dataValues.inspectionTime : null;
let record = { patrolPlanId, lastInspectionTime, inspectionTime, points, alarm, pointId }
const recordRes = await models.PatrolRecord.create(record, transaction);
const recordRes = await models.PatrolRecord.create(
// record
{
patrolPlanId: patrolPlanId,
lastInspectionTime,
inspectionTime,
points,
alarm,
pointId: pointId,
projectId
}
, {
transaction
});
if (alarm) {
await models.PatrolRecord.create({
await models.PatrolRecordIssueHandle.create({
patrolRecordId: recordRes.id,
state: 1,
}, transaction);
}, { transaction });
}
// 更新巡检次数统计
const curPlanRecord = await models.PatrolRecord.findAndCountAll({
where: { patrolPlanId }
where: { patrolPlanId: patrolPlanId }
});
const patrolCount = curPlanRecord.count;

64
api/app/lib/controllers/patrolManage/yujingguanli.js

@ -0,0 +1,64 @@
'use strict';
async function varfiyCode(ctx) {
try {
const { models } = ctx.fs.dc;
const { pushBySms, pushByEmail } = ctx.app.fs.utils
const { phone, type ,email} = ctx.request.body
// 伪造的请求可能由相同的sig参数组成
// const checkSigUsed = await models.PhoneValidateCode.findOne({
// where: { sig: sig }
// });
// if (checkSigUsed) {
// throw '参数错误!'
// }
// // 验证sig正确性
// const checkSig = Hex.stringify(SHA1(phone + r));
// if (!r || !sig || sig != checkSig) {
// throw '参数错误!'
// }
let varifyCode = ''
for (let i = 0; i < 6; i++) {
varifyCode += Math.floor(Math.random() * 10)
}
if(type.includes(1)){
await pushBySms({
phone: phone,
templateCode: 'SMS_261950020',
templateParam: {
code: varifyCode
},
})
}
if(type.includes(2)){
await pushByEmail({
email: email,
title: '测试',
text:'你知道吗'
})
}
// await models.PhoneValidateCode.create({
// phone: phone,
// code: varifyCode,
// sig: sig,
// expired: moment().add(10, 'minutes').format('YYYY-MM-DD HH:mm:ss')
// })
ctx.status = 204;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
message: typeof error == 'string' ? error : '获取验证码失败'
}
}
}
module.exports = {
varfiyCode,
// pushByEmail
}

5
api/app/lib/models/patrol_record.js

@ -45,6 +45,11 @@ module.exports = dc => {
type: DataTypes.INTEGER,
allowNull: false,
},
projectId: {
field: "project_id",
type: DataTypes.INTEGER,
allowNull: true,
},
}, {
tableName: "patrol_record",
comment: "",

45
api/app/lib/models/patrol_record_issue_handle.js

@ -168,6 +168,51 @@ module.exports = dc => {
field: "check_image",
autoIncrement: false
},
yanshoushijian: {
type: DataTypes.DATE,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "yanshoushijian",
autoIncrement: false
},
yanshoucishu: {
type: DataTypes.INTEGER,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "yanshoucishu",
autoIncrement: false
},
yujingshijian: {
type: DataTypes.DATE,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "yujingshijian",
autoIncrement: false
},
isgaojing: {
type: DataTypes.BOOLEAN,
allowNull: true,
defaultValue: null,
comment: null,
primaryKey: false,
field: "isgaojing",
autoIncrement: false
},
cost: {
type: DataTypes.DECIMAL(11, 2),
allowNull: true,
defaultValue: null,
comment: '成本',
primaryKey: false,
field: "cost",
autoIncrement: false
},
}, {
tableName: "patrol_record_issue_handle",
comment: "",

11
api/app/lib/routes/patrolManage/yujingguanli.js

@ -0,0 +1,11 @@
'use strict';
const yujingguanli = require('../../controllers/patrolManage/yujingguanli');
module.exports = function (app, router, opts) {
app.fs.api.logAttr['POST/yujingguanli'] = { content: '下发预警邮件', visible: true };
router.post('/yujingguanli', yujingguanli.varfiyCode);
};

2
api/config.js

@ -94,7 +94,7 @@ const product = {
host: 'smtp.exmail.qq.com',
port: 465,
sender: {
name: '中鼎服务',
name: '运维服务',
address: 'fsiot@free-sun.com.cn',
password: 'Fs2689'
}

126
api/log/development.log

@ -4194,3 +4194,129 @@ notNull Violation: PatrolPlan.patrolCount cannot be null
2023-02-21 17:02:47.295 - error: path: /patrolTemplate, error: ReferenceError: createUser is not defined
2023-02-21 17:08:28.472 - error: path: /patrolTemplate, error: ReferenceError: createUser is not defined
2023-02-21 17:08:39.999 - error: path: /patrolTemplate, error: ReferenceError: createUser is not defined
2023-03-03 08:50:15.221 - debug: [FS-LOGGER] Init.
2023-03-03 08:50:16.170 - info: [FS-ATTACHMENT] Inject attachment mw into router.
2023-03-03 08:50:16.171 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
2023-03-03 08:50:16.171 - info: [FS-AUTH] Inject auth and api mv into router.
2023-03-03 08:52:27.130 - error: [FS-ERRHD]
{
message: 'transaction is not defined',
stack: 'ReferenceError: transaction is not defined\n' +
' at login (d:\\前端学习\\巡检\\Inspection\\api\\app\\lib\\controllers\\auth\\index.js:78:9)'
}
2023-03-03 08:52:27.133 - error: [FS-ERRHD]
{
message: 'transaction is not defined',
stack: 'ReferenceError: transaction is not defined\n' +
' at login (d:\\前端学习\\巡检\\Inspection\\api\\app\\lib\\controllers\\auth\\index.js:78:9)'
}
2023-03-03 08:52:27.133 - error: [FS-ERRHD]
{
message: 'transaction is not defined',
stack: 'ReferenceError: transaction is not defined\n' +
' at login (d:\\前端学习\\巡检\\Inspection\\api\\app\\lib\\controllers\\auth\\index.js:78:9)'
}
2023-03-03 08:52:27.134 - error: [FS-ERRHD]
{
message: 'transaction is not defined',
stack: 'ReferenceError: transaction is not defined\n' +
' at login (d:\\前端学习\\巡检\\Inspection\\api\\app\\lib\\controllers\\auth\\index.js:78:9)'
}
2023-03-03 08:52:27.134 - error: [FS-ERRHD]
{
message: 'transaction is not defined',
stack: 'ReferenceError: transaction is not defined\n' +
' at login (d:\\前端学习\\巡检\\Inspection\\api\\app\\lib\\controllers\\auth\\index.js:78:9)'
}
2023-03-03 08:52:27.135 - error: [FS-ERRHD]
{
message: 'transaction is not defined',
stack: 'ReferenceError: transaction is not defined\n' +
' at login (d:\\前端学习\\巡检\\Inspection\\api\\app\\lib\\controllers\\auth\\index.js:78:9)'
}
2023-03-03 08:52:48.235 - error: [FS-ERRHD]
{
message: 'transaction is not defined',
stack: 'ReferenceError: transaction is not defined\n' +
' at login (d:\\前端学习\\巡检\\Inspection\\api\\app\\lib\\controllers\\auth\\index.js:78:9)'
}
2023-03-03 08:52:48.236 - error: [FS-ERRHD]
{
message: 'transaction is not defined',
stack: 'ReferenceError: transaction is not defined\n' +
' at login (d:\\前端学习\\巡检\\Inspection\\api\\app\\lib\\controllers\\auth\\index.js:78:9)'
}
2023-03-03 08:52:48.237 - error: [FS-ERRHD]
{
message: 'transaction is not defined',
stack: 'ReferenceError: transaction is not defined\n' +
' at login (d:\\前端学习\\巡检\\Inspection\\api\\app\\lib\\controllers\\auth\\index.js:78:9)'
}
2023-03-03 08:52:48.238 - error: [FS-ERRHD]
{
message: 'transaction is not defined',
stack: 'ReferenceError: transaction is not defined\n' +
' at login (d:\\前端学习\\巡检\\Inspection\\api\\app\\lib\\controllers\\auth\\index.js:78:9)'
}
2023-03-03 08:52:48.238 - error: [FS-ERRHD]
{
message: 'transaction is not defined',
stack: 'ReferenceError: transaction is not defined\n' +
' at login (d:\\前端学习\\巡检\\Inspection\\api\\app\\lib\\controllers\\auth\\index.js:78:9)'
}
2023-03-03 08:52:48.239 - error: [FS-ERRHD]
{
message: 'transaction is not defined',
stack: 'ReferenceError: transaction is not defined\n' +
' at login (d:\\前端学习\\巡检\\Inspection\\api\\app\\lib\\controllers\\auth\\index.js:78:9)'
}
2023-03-03 08:53:09.296 - error: [FS-ERRHD]
{
message: 'transaction is not defined',
stack: 'ReferenceError: transaction is not defined\n' +
' at login (d:\\前端学习\\巡检\\Inspection\\api\\app\\lib\\controllers\\auth\\index.js:78:9)'
}
2023-03-03 08:53:09.296 - error: [FS-ERRHD]
{
message: 'transaction is not defined',
stack: 'ReferenceError: transaction is not defined\n' +
' at login (d:\\前端学习\\巡检\\Inspection\\api\\app\\lib\\controllers\\auth\\index.js:78:9)'
}
2023-03-03 08:53:09.296 - error: [FS-ERRHD]
{
message: 'transaction is not defined',
stack: 'ReferenceError: transaction is not defined\n' +
' at login (d:\\前端学习\\巡检\\Inspection\\api\\app\\lib\\controllers\\auth\\index.js:78:9)'
}
2023-03-03 08:55:19.376 - debug: [FS-LOGGER] Init.
2023-03-03 08:55:19.504 - info: [FS-ATTACHMENT] Inject attachment mw into router.
2023-03-03 08:55:19.505 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
2023-03-03 08:55:19.505 - info: [FS-AUTH] Inject auth and api mv into router.
2023-03-04 15:30:48.068 - debug: [FS-LOGGER] Init.
2023-03-04 15:30:49.010 - info: [FS-ATTACHMENT] Inject attachment mw into router.
2023-03-04 15:30:49.011 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
2023-03-04 15:30:49.011 - info: [FS-AUTH] Inject auth and api mv into router.
2023-03-04 17:42:25.123 - debug: [FS-LOGGER] Init.
2023-03-04 17:42:25.236 - info: [FS-ATTACHMENT] Inject attachment mw into router.
2023-03-04 17:42:25.236 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
2023-03-04 17:42:25.236 - info: [FS-AUTH] Inject auth and api mv into router.
2023-03-04 18:22:09.556 - debug: [FS-LOGGER] Init.
2023-03-04 18:22:09.675 - info: [FS-ATTACHMENT] Inject attachment mw into router.
2023-03-04 18:22:09.676 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
2023-03-04 18:22:09.676 - info: [FS-AUTH] Inject auth and api mv into router.
2023-03-06 08:51:30.658 - debug: [FS-LOGGER] Init.
2023-03-06 08:51:31.673 - info: [FS-ATTACHMENT] Inject attachment mw into router.
2023-03-06 08:51:31.674 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
2023-03-06 08:51:31.674 - info: [FS-AUTH] Inject auth and api mv into router.
2023-03-06 10:16:04.533 - debug: [FS-LOGGER] Init.
2023-03-06 10:16:04.663 - info: [FS-ATTACHMENT] Inject attachment mw into router.
2023-03-06 10:16:04.663 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
2023-03-06 10:16:04.663 - info: [FS-AUTH] Inject auth and api mv into router.
2023-03-06 14:30:39.123 - debug: [FS-LOGGER] Init.
2023-03-06 14:30:39.248 - info: [FS-ATTACHMENT] Inject attachment mw into router.
2023-03-06 14:30:39.248 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
2023-03-06 14:30:39.248 - info: [FS-AUTH] Inject auth and api mv into router.
2023-03-06 14:32:05.704 - debug: [FS-LOGGER] Init.
2023-03-06 14:32:05.817 - info: [FS-ATTACHMENT] Inject attachment mw into router.
2023-03-06 14:32:05.817 - debug: init fs.attachment and inject it into app(app.fs.attachment) and runtime ctx(ctx.fs.attachment)
2023-03-06 14:32:05.818 - info: [FS-AUTH] Inject auth and api mv into router.

2
script/1.0.4/schema/3.updata_resource.sql

@ -0,0 +1,2 @@
DELETE FROM public.resource WHERE code = 'REPAIR_MANAGE';
DELETE FROM public.resource WHERE parent_resource = 'REPAIR_MANAGE';

5
script/1.0.4/schema/4.updata_patrol_record_issue__handle.sql

@ -0,0 +1,5 @@
ALTER TABLE patrol_record_issue_handle ADD yanshoushijian timestamp(6);
ALTER TABLE patrol_record_issue_handle ADD yanshoucishu integer;
ALTER TABLE patrol_record_issue_handle ADD yujingshijian timestamp(6);
ALTER TABLE patrol_record_issue_handle ADD yujingafchishu integer;
ALTER TABLE patrol_record_issue_handle ADD isgaojing bool;

4
script/1.0.5/schema/2.update_patrol_record.sql

@ -0,0 +1,4 @@
ALTER TABLE "public"."patrol_record"
ADD COLUMN "project_id" int4;
COMMENT ON COLUMN "public"."patrol_record"."project_id" IS '结构物id';

4
script/1.0.5/schema/3.update_patrol_record_issue_handle.sql

@ -0,0 +1,4 @@
ALTER TABLE "public"."patrol_record_issue_handle"
ADD COLUMN "cost" decimal(11,2);
COMMENT ON COLUMN "public"."patrol_record_issue_handle"."cost" IS '成本';

3
weapp/app.json

@ -16,7 +16,8 @@
"inspectionInput/inspectionInput",
"troubleshooting/index",
"troubleshooting/shootingForm/index",
"inspectionReport/inspectionReport"
"inspectionReport/inspectionReport",
"pointsStatus/pointsStatus"
]
}
],

BIN
weapp/images/circle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 B

1
weapp/images/refresh.svg

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1678087046282" class="icon" viewBox="0 0 1879 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2319" width="29.359375" height="16" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M938.617341 45.280925c-106.987283 0-205.687861 35.810405-285.003468 96.184971-17.905202 13.613873-19.532948 39.953757-3.551445 55.93526 13.169942 13.169942 34.034682 14.649711 48.83237 3.255491 66.589595-50.608092 149.752601-80.795376 239.574566-80.795375 207.16763 0 377.932948 159.667052 395.542197 362.247399 1.627746 19.384971-0.295954 34.774566-0.295954 34.774566l-93.225434 0.739884 113.202313 225.516763c9.766474 0 150.788439-226.404624 150.788439-226.404624h-94.409249c0.443931-24.564162-1.183815-35.810405-1.627745-40.545665-20.716763-241.054335-223.593064-430.760694-469.82659-430.90867zM938.617341 913.905202c-219.00578 0-397.021965-178.164162-397.021965-397.021965v-0.443931l94.261271-1.035838-112.018497-224.924855-150.936416 226.256647h94.261272C467.015029 781.317919 692.087861 988.485549 938.617341 988.485549c110.982659 0 213.234682-38.621965 293.882081-102.991907 17.313295-13.909827 18.645087-39.80578 2.959538-55.49133-13.465896-13.465896-34.774566-14.649711-49.572255-2.811561-67.921387 54.307514-153.895954 86.714451-247.269364 86.714451z" fill="#2c2c2c" p-id="2320"></path></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

6
weapp/package/inspectionInput/inspectionInput.js

@ -83,7 +83,6 @@ Page({
onPickerChange (e) {
const { key } = e.currentTarget.dataset;
const { value } = e.detail;
this.setData({
[`${key}Visible`]: false,
[`${key}Value`]: value,
@ -131,7 +130,6 @@ Page({
})
},
fail: (res) => {
console.log(res)
wx.hideLoading();
wx.showToast({
title: res.errMsg,
@ -233,7 +231,6 @@ Page({
success++;
let str = JSON.parse(resp.data) // 返回的结果,可能不同项目结果不一样
str = str.uploaded
console.log(str);
if (imgs.length >= 20) {
const inspectContent = that.data.inspectContent;
inspectContent[itemName].imgs = imgs;
@ -359,7 +356,8 @@ Page({
inspectContent,
address: address
},
alarm
alarm,
projectId: dataList.project.id
}
wx.showLoading({ title: '提交中...' });
that.setData({ isCommitting: true });

66
weapp/package/pointsStatus/pointsStatus.js

@ -0,0 +1,66 @@
// package/pointsStatus/pointsStatus.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
console.log(options, 'options')
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})

3
weapp/package/pointsStatus/pointsStatus.json

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

2
weapp/package/pointsStatus/pointsStatus.wxml

@ -0,0 +1,2 @@
<!--package/pointsStatus/pointsStatus.wxml-->
<text>package/pointsStatus/pointsStatus.wxml</text>

1
weapp/package/pointsStatus/pointsStatus.wxss

@ -0,0 +1 @@
/* package/pointsStatus/pointsStatus.wxss */

14
weapp/package/troubleshooting/index.js

@ -3,6 +3,8 @@ import { getPatrolRecordIssueHandle, getStructuresUsers } from "../../utils/getA
import { Request } from "../../common";
const moment = require("../../utils/moment");
let setFilterStartTime = 0
let setFilterEndTime = 0
Page({
/**
@ -106,7 +108,7 @@ Page({
pointToggle (event) {
const { index, id } = event.currentTarget.dataset;
const checkbox = this.selectComponent(`.checkboxes-point-${id}`);
// const checkbox = this.selectComponent(`.checkboxes-point-${id}`);
// checkbox.toggle();
const { pointList } = this.data
let pointList_ = JSON.parse(JSON.stringify(pointList))
@ -123,6 +125,10 @@ Page({
if (timeSelectedUnrealFlag && event.detail == 1640966400000) {
return
}
if(new Date().getTime() - setFilterStartTime < 100){
return
}
setFilterStartTime = new Date().getTime()
this.setData({
startTime: event.detail,
endTime: endTime ? endTime : 1640966400000
@ -130,13 +136,19 @@ Page({
},
onEndTimeChange (event) {
const { timeSelectedUnrealFlag, startTime, endTime } = this.data
console.log('结束时间', timeSelectedUnrealFlag, event, new Date().getTime());
if (timeSelectedUnrealFlag && event.detail == 1640966400000) {
return
}
if(new Date().getTime() - setFilterEndTime < 100){
return
}
setFilterEndTime = new Date().getTime()
this.setData({
startTime: startTime ? startTime : 1640966400000,
endTime: event.detail,
});
return
},
onDropDownClose () {

3
weapp/package/troubleshooting/index.json

@ -12,6 +12,7 @@
"van-checkbox": "@vant/weapp/checkbox/index",
"van-checkbox-group": "@vant/weapp/checkbox-group/index",
"van-datetime-picker": "@vant/weapp/datetime-picker/index",
"timePicker": "/components/timePicker/index"
"timePicker": "/components/timePicker/index",
"t-date-time-picker": "tdesign-miniprogram/date-time-picker/date-time-picker"
}
}

12
weapp/package/troubleshooting/index.wxml

@ -25,20 +25,26 @@
<van-dropdown-item title="{{ '点位' }}" bind:close="onDropDownClose">
<view style="max-height:888rpx">
<!-- <van-checkbox-group value="{{ pointResult }}" bind:change="onPointChange"> -->
<view>
<van-cell-group>
<van-cell wx:for="{{ pointList }}" wx:key="index" title="{{ item.name }}" value-class="value-class" clickable data-index="{{ index }}"
data-id="{{ item.id }}" bind:click="pointToggle">
<van-checkbox catch:tap="noop" class="checkboxes-point-{{ item.id }}" name="{{ item.id }}" value="{{item.selected}}"/>
<van-checkbox catch:tap="pointToggle"
data-index="{{ index }}"
data-id="{{ item.id }}"
class="checkboxes-point-{{ item.id }}" name="{{ item.id }}" value="{{item.selected}}"/>
</van-cell>
</van-cell-group>
</view>
<!-- </van-checkbox-group> -->
</view>
</van-dropdown-item>
<van-dropdown-item title="{{ '时间' }}" bind:close="onDropDownClose">
<view style="max-height:60%; display:flex" class="time-option">
<van-datetime-picker type="datetime" show-toolbar="{{false}}" type="date" value="{{ startTime }}" bind:input="onStartTimeChange" min-date="{{1640966400000}}"/>
<van-datetime-picker show-toolbar="{{false}}" type="date" value="{{ startTime }}" bind:input="onStartTimeChange" min-date="{{1640966400000}}"/>
<view style="display:flex; align-items:center">至</view>
<van-datetime-picker type="datetime" show-toolbar="{{false}}" type="date" value="{{ endTime }}" bind:input="onEndTimeChange" min-date="{{1640966400000}}"/>
<van-datetime-picker show-toolbar="{{false}}" type="date" value="{{ endTime }}" bind:input="onEndTimeChange" min-date="{{1640966400000}}"/>
</view>
</van-dropdown-item>
</van-dropdown-menu>

44
weapp/package/troubleshooting/shootingForm/index.js

@ -34,6 +34,7 @@ Page({
repair: '',
repairImgs: [],
checkDesc: '',
cost: '',
checkImgs: [],
// 表单控制
@ -103,8 +104,8 @@ Page({
maintenancePersonDepartmentShow: maintenancePersonIndex >= 0 ? focusPerson[maintenancePersonIndex].department.name : '',
qualityPersonIndex: focusPerson.findIndex(f => f.id == issue.checkPerson.id),
planStartTime: moment(issue.startTime).unix(),
planStartTimeShow: moment(issue.startTime).format('YYYY-MM-DD HH:mm:ss'),
planEndTimeShow: moment(issue.endTime).format('YYYY-MM-DD HH:mm:ss'),
planStartTimeShow: moment(issue.startTime).format('YYYY-MM-DD'),
planEndTimeShow: moment(issue.endTime).format('YYYY-MM-DD'),
maintenanceRequirement: issue.repairAsk
})
}
@ -124,6 +125,7 @@ Page({
if (issue.state > 4) {
this.setData({
checkDesc: issue.checkOpinion,
cost: issue.cost,
checkImgs: issue.checkImage || [],
})
}
@ -165,7 +167,7 @@ Page({
// this.setData({ planStartTime: '' })
} else if (e.target.dataset.option == 'confirmed') {
this.setData({
planStartTimeShow: this.data.planStartTime ? moment(this.data.planStartTime).format('YYYY-MM-DD HH:mm') : ''
planStartTimeShow: this.data.planStartTime ? moment(this.data.planStartTime).format('YYYY-MM-DD') : ''
})
}
},
@ -186,7 +188,7 @@ Page({
this.setData({ planEndTimePopupShow: false })
if (e.target.dataset.option == 'confirmed') {
this.setData({
planEndTimeShow: this.data.planEndTime ? moment(this.data.planEndTime).format('YYYY-MM-DD HH:mm') : ''
planEndTimeShow: this.data.planEndTime ? moment(this.data.planEndTime).format('YYYY-MM-DD') : ''
})
}
},
@ -198,8 +200,16 @@ Page({
},
onInputChange (e) {
let value = e.detail.value
if (e.target.dataset.type === 'cost' && !/^(\d?)+(\.\d{0,2})?$/.test(e.detail.value)) {
wx.showToast({
title: '只能输入两位小数',
icon: 'none'
})
value = value.substring(0, value.length - 1);
}
this.setData({
[e.target.dataset.type]: e.detail.value
[e.target.dataset.type]: value
})
},
@ -228,15 +238,15 @@ Page({
return;
}
wx.chooseMedia({
count: 20, // 基础库2.25.0前,最多可支持9个文件,2.25.0及以后最多可支持20个文件
count: 20, // 基础库2.25.0前,最多可支持9个文件,2.25.0及以后最多可支持20个文件
mediaType: ['image'], // 文件类型
sizeType: ['original', 'compressed'], // original 原图,compressed 压缩图,默认二者都有
sourceType: ['album', 'camera'], // album 从相册选图,camera 使用相机,默认二者都有
sizeType: ['original', 'compressed'], // original 原图,compressed 压缩图,默认二者都有
sourceType: ['album', 'camera'], // album 从相册选图,camera 使用相机,默认二者都有
success: function (res) {
const imgs = res.tempFiles;
for (let i = 0; i < imgs.length; i++) {
if (res.tempFiles[i].size > 15728640) {
wx.showToast({ title: '图片大于15M不可上传', icon: 'none' });
wx.showToast({ title: '图片大于15M,不可上传', icon: 'none' });
return;
}
const fileNameArr = res.tempFiles[i].tempFilePath.split('.');
@ -273,7 +283,7 @@ Page({
success: (resp) => {
wx.hideLoading();
success++;
let str = JSON.parse(resp.data) // 返回的结果可能不同项目结果不一样
let str = JSON.parse(resp.data) // 返回的结果,可能不同项目结果不一样
str = str.uploaded
if (imgs.length >= 20) {
return false;
@ -291,14 +301,14 @@ Page({
},
complete: () => {
i++;
if (i == data.path.length) { // 当图片传完时停止调用
if (i == data.path.length) { // 当图片传完时,停止调用
console.log('执行完毕');
console.log('成功' + success + " 失败" + fail);
} else { // 若图片还没有传完则继续调用函数
console.log('成功:' + success + " 失败:" + fail);
} else { // 若图片还没有传完,则继续调用函数
data.i = i;
data.success = success;
data.fail = fail;
that.uploadimg(data, itemName); // 递归回调自己
that.uploadimg(data, itemName); // 递归,回调自己
}
}
});
@ -322,7 +332,7 @@ Page({
maintenancePersonIndex, maintenancePersonDepartmentShow, qualityPersonIndex, planStartTime, planEndTime, planStartTimeShow, planEndTimeShow, maintenanceRequirement,
userInfo, planApproval,
repair, repairImgs,
checkDesc, checkImgs
checkDesc, cost, checkImgs
} = this.data
let nextState = ''
let confirmData = {}
@ -372,7 +382,9 @@ Page({
confirmData = {
...confirmData,
checkOpinion: checkDesc,
checkImage: checkImgs
cost,
checkImage: checkImgs,
checkPerson: { id: userInfo.id, name: userInfo.name }
}
if (approve == 'agree') {
nextState = 6

11
weapp/package/troubleshooting/shootingForm/index.wxml

@ -14,13 +14,13 @@
<van-field value="{{data.PatrolRecord.points.itemData.name}}" label="点位" readonly accordion border="{{ false }}" />
<van-collapse wx:if="{{data.PatrolRecord.points.inspectContent}}" value="{{ pointItemCollapseActiveNames }}" bind:change="onPointItemCollapseActiveChange" border="{{false}}">
<block wx:for="{{data.PatrolRecord.points.inspectContent}}" wx:key="index">
<van-collapse-item name="{{item.itemName}}" border="{{false}}">
<van-collapse-item wx:if="{{!item.isNormal}}" name="{{item.itemName}}" border="{{false}}">
<view slot="title">
<van-field value="{{item.itemName}}" label="检查项" readonly border="{{ false }}" />
</view>
<view slot="">
<van-field value="1" label="异常等级" readonly border="{{ false }}" />
<van-field value="2" label="问题描述" readonly border="{{ false }}" />
<van-field value="{{item.level}}" label="异常等级" readonly border="{{ false }}" />
<van-field value="{{item.msgInp||''}}" label="问题描述" readonly border="{{ false }}" />
<van-cell border="{{false}}">
<view style="display:flex">
<view class="fs-cell-title" style="">现场照片</view>
@ -75,7 +75,7 @@
确定
</view>
</view>
<van-datetime-picker value="{{ planStartTime }}" min-date="{{1640966400000}}" bind:input="onPlanStartTimeChange" show-toolbar="{{false}}" />
<van-datetime-picker type="date" value="{{ planStartTime }}" min-date="{{1640966400000}}" bind:input="onPlanStartTimeChange" show-toolbar="{{false}}" />
</van-popup>
</view>
</van-cell>
@ -93,7 +93,7 @@
确定
</view>
</view>
<van-datetime-picker value="{{ planEndTime }}" min-date="{{1640966400000}}" bind:input="onPlanEndTimeChange" show-toolbar="{{false}}" />
<van-datetime-picker type="date" value="{{ planEndTime }}" min-date="{{1640966400000}}" bind:input="onPlanEndTimeChange" show-toolbar="{{false}}" />
</van-popup>
</view>
</van-cell>
@ -137,6 +137,7 @@
<span>质检验收</span>
</view>
<van-field value="{{data.checkPerson.name}}" label="验收人" readonly border="{{ false }}" />
<van-field value="{{ cost }}" extra-event-params="{{true}}" label="成本(元)" type="digit" placeholder="请输入" border="{{ isCheck }}" bind:input="onInputChange" data-type='cost' readonly="{{!isCheck}}" />
<van-cell border="{{false}}">
<view style="display:flex">
<view class="fs-cell-title" style="">现场图片</view>

157
weapp/pages/index/index.js

@ -1,78 +1,81 @@
// pages/index/index.js
import { getProjectList } from "../../utils/getApiUrl";
import { getProjectList, getPatrolRecord } from "../../utils/getApiUrl";
import { Request } from "../../common";
const moment = require("../../utils/moment");
Page({
/**
* 页面的初始数据
*/
data: {
dataList: [],
limit: 10, //条数
page: 0, //当前页
count: '', //总条数
keyName: '', //结构物名称
hidden: true,
imgUrl: getApp().globalData.imgUrl
},
// 输入框
formInp(e) {
let that = this;
that.setData({
keyName: e.detail.value
})
project: [],
todayRecord: [], // 今日巡检记录
markers: [],
isShowCallout: false,
},
// 手机键盘点击完成按钮(回车事件)
bindconfirm() {
let that = this;
that.setData({
page: 0, //当前页
count: '', //总条数
dataList: []
setMarkers(project, todayRecord) {
const markers = project.map(p => {
let todayCount = 0;
todayRecord.forEach(r => {
if (r.projectId === p.id) { todayCount += 1 }
})
that.getProjectList();
return {
id: p.id,
latitude: p.latitude,
longitude: p.longitude,
name: p.name,
iconPath: '/images/circle.png',
width: 15,
height: 15,
callout: {
content: `${p.name}\n今日巡检:${todayCount}`,
padding: 10,
display: this.data.isShowCallout ? 'ALWAYS' : 'BYCLICK',
},
// 搜索表单
goSearch() {
let that = this;
that.setData({
page: 0, //当前页
count: '', //总条数
dataList: []
}
})
that.getProjectList();
this.setData({ markers })
},
// 获取巡检总览列表
getProjectList: function () {
let that = this;
let { page, limit, keyName } = that.data;
let data = keyName ? { limit, page, name: keyName } : { limit, page }
wx.showLoading({
title: '加载中',
})
Request.get(getProjectList(), data).then(res => {
if (res.rows.length == 0) {
that.setData({
dataList: res.rows,
hidden: false
})
// 获取结构物和今日巡检次数
getData() {
const that = this;
wx.showLoading({ title: '加载中' })
const promiseArr = [];
promiseArr.push(Request.get(getProjectList(), {}));
promiseArr.push(Request.get(getPatrolRecord('all', moment().format('YYYY-MM-DD') + ' 00:00:00', moment().format('YYYY-MM-DD') + ' 23:59:59', 'null', 'null')));
Promise.all(promiseArr).then(res => {
wx.hideLoading()
return;
}
var arr1 = that.data.dataList; //从data获取当前dataList数组
var arr2 = res.rows; //从此次请求返回的数据中获取新数组
arr1 = arr1.concat(arr2); //合并数组
that.setData({
dataList: arr1,
count: res.count, //总条数
hidden: true
project: res[0].rows,
todayRecord: res[1]
})
wx.hideLoading()
that.setMarkers(res[0].rows, res[1]);
// 缩放视野展示所有 markers
const mapCtx = wx.createMapContext('mapDom')
mapCtx.includePoints({
points: res[0].rows,
padding: [40, 40, 40, 40]
})
})
},
showCallout() {
this.setData(
{ isShowCallout: !this.data.isShowCallout },
() => { this.setMarkers(this.data.markers, this.data.todayRecord); }
);
},
onRefresh() {
this.getData();
},
onMarkerTap(e) {
console.log(e.detail.markerId, 'e.detail.markerId')
wx.navigateTo({url: `/package/pointsStatus/pointsStatus?projectId=${e.detail.markerId}`})
},
/**
@ -104,7 +107,7 @@ Page({
url: '/pages/login/login'
});
} else {
this.getProjectList();
this.getData();
}
},
@ -112,60 +115,28 @@ Page({
* 生命周期函数--监听页面隐藏
*/
onHide() {
this.setData({
dataList: [],
keyName: '',
page: 0, //当前页
count: '', //总条数
})
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
this.setData({
dataList: [],
keyName: '',
page: 0, //当前页
count: '', //总条数
})
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
let that = this;
that.setData({
dataList: [],
keyName: '',
page: 0, //当前页
count: '', //总条数
})
that.getProjectList()
// 手动控制回弹
wx.stopPullDownRefresh();
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
let _that = this;
let page = _that.data.page + 1; //获取当前页数并+1
let { dataList, count } = _that.data;
if (dataList.length == count) {
wx.showToast({
title: '没有更多数据了...',
icon: 'none',
})
return;
}
_that.setData({
page: page, //更新当前页数
})
_that.getProjectList()
},
/**

44
weapp/pages/index/index.wxml

@ -1,32 +1,14 @@
<!--pages/index/index.wxml-->
<view>
<view class="searchFixed">
<view class="searchBoxs">
<input class="searchInps" bindinput="formInp" bindconfirm="bindconfirm" value='{{keyName}}' type="text" placeholder="请输入结构物名称" />
<button class="btnSearch" bindtap="goSearch">搜索</button>
</view>
</view>
<view style="margin-top: 140rpx;">
<block wx:for="{{dataList}}" wx:key='*this'>
<view style="padding-bottom: 60rpx;">
<image wx:if="{{item.img != null && item.img.length > 0}}" style="width: 100%;height: 372rpx;display: block;" src="{{imgUrl + item.img[0]}}"></image>
<view wx:if="{{item.img == null || item.img.length == 0}}" style="width: 100%;height: 372rpx;line-height: 372rpx;text-align: center;background: #fff;border-bottom: 2rpx solid #ccc;">暂无图片</view>
<view class="box">
<view style="font-weight:bold;font-size:32rpx;">{{item.name}}</view>
<view style="font-size:28rpx;color: rgb(166,166,166);">
<view style=" margin-top:6rpx;">今日问题:<text>12</text></view>
<view style="float:left;width:360rpx;">未处理问题:<text>12</text></view>
<view style="float:left;width:350rpx;">已处理问题:<text>12</text></view>
</view>
</view>
</view>
</block>
</view>
<!-- 暂无数据 -->
<view hidden="{{hidden}}">
<image class="noData" src="../../images/noData.png"></image>
<view class="noTxt">暂无数据~</view>
</view>
</view>
<map
id="mapDom"
class="map"
markers="{{markers}}"
bindmarkertap="onMarkerTap"
>
<view class="action-box">
<view class="text flex-center" bind:tap="showCallout">数据</view>
<view class="img flex-center" bind:tap="onRefresh">
<image src="/images/refresh.svg"></image>
</view>
</view>
</map>

80
weapp/pages/index/index.wxss

@ -1,70 +1,36 @@
/* pages/index/index.wxss */
page {
background: #F7F7FA;
.flex-center {
display: flex;
justify-content: center;
align-items: center;
}
.searchBoxs {
position: relative;
margin: 20rpx 0rpx;
height: 76rpx;
.map {
width: 100vw;
height: 100vh;
}
.searchInps {
background-color: #fff;
width: 542rpx;
height: 76rpx;
border-radius: 8rpx;
padding-left: 32rpx;
padding-right: 144rpx;
border: 1px solid rgba(225, 225, 225, 0.44);
.action-box {
position: absolute;
top: -2rpx;
left: 16rpx;
font-size: 28rpx;
bottom: 30px;
right: 10px;
width: 46px;
height: 80px;
display: flex;
flex-direction: column;
justify-content: space-evenly;
}
.btnSearch {
width: 128rpx;
height: 68rpx;
line-height: 68rpx;
border-radius: 8rpx;
color: #fff;
font-size: 28rpx;
background: linear-gradient(180deg, #1979ff 0%, #1979ff 100%);
position: absolute;
top: 6rpx;
right: 28rpx;
z-index: 10;
}
.searchFixed {
position: fixed;
top: 0;
width: 100%;
background-color: #fff;
box-shadow: 0rpx -4rpx 20rpx #c2c2c2;
z-index: 10;
}
.box {
padding: 20rpx;
box-shadow: 0rpx 10rpx 10rpx #ccc;
overflow: hidden;
line-height: 50rpx;
background: #fff;
.action-box .text {
background-color: white;
height: 30px;
}
/* 暂无数据 */
.noData {
width: 254rpx;
height: 298rpx;
display: block;
margin: 450rpx auto 16rpx;
.action-box .img {
background-color: white;
}
.noTxt {
font-size: 30rpx;
color: #999;
font-weight: bold;
text-align: center;
.action-box .img image {
width: 30px;
height: 30px;
}

5
web/client/src/app.js

@ -8,7 +8,8 @@ import ProjectRegime from './sections/projectRegime';
import Organization from './sections/organization';
import PatrolManage from './sections/patrolManage';
import IssueHandle from './sections/issueHandle'
import Shouye from './sections/shouye';
import { Func } from '$utils';
const App = props => {
const { projectName } = props
@ -19,7 +20,7 @@ const App = props => {
return (
<Layout
title={projectName}
sections={[Auth, ProjectRegime, Safetymanage, Organization, PatrolManage, IssueHandle]}
sections={[Auth,Shouye, ProjectRegime, Safetymanage, Organization, PatrolManage, IssueHandle]}
/>
)

42
web/client/src/sections/auth/containers/login.js

@ -11,7 +11,7 @@ import { login, LOGIN_ERROR } from '../actions/auth';
import { ExclamationCircleOutlined } from '@ant-design/icons';
import { Uploads } from '$components'
import { LockOutlined, UserOutlined } from '@ant-design/icons';
import { Func } from '$utils';
import '../style.less';
const FormItem = Form.Item;
@ -29,6 +29,44 @@ const Login = props => {
const [codCountDown, setCodeCountDown] = useState(60)
const codCountDownRef = useRef(0)
const [form] = Form.useForm();
const tourl = () => {
return '/shouye'
if (Func.isAuthorized("STRU_INFO_CONFIG")) {
return '/projectRegime/information'
}
if (Func.isAuthorized("QR_CODE_CONFIG")) {
return '/projectRegime/qrCode'
}
if (Func.isAuthorized("USER_CONFIG")) {
return '/organization/user'
}
if (Func.isAuthorized("AUTH_CONFIG")) {
return '/organization/authority'
}
if (Func.isAuthorized("PATROL_PLAN_CONFIG")) {
return '/patrolManage/patrolPlan'
}
if (Func.isAuthorized("PATROL_RECORD_VIEW")) {
return '/patrolManage/patrolRecord'
}
if (Func.isAuthorized("CHECKREPORT")) {
return '/patrolManage/patrolReport'
}
if (Func.isAuthorized("CHECKITEMSET")) {
return '/patrolManage/checkItems'
}
if (Func.isAuthorized("CHECKMOULD")) {
return '/patrolManage/patrolTemplate'
}
if (Func.isAuthorized("WENTICHULI")) {
return '/issueHandle'
}
else {
return message.warn('没有任何模块的查看权限')
}
}
useEffect(() => {
}, [])
@ -36,7 +74,7 @@ const Login = props => {
useEffect(() => {
if (user && user.authorized) {
dispatch(push('/projectRegime/information'));
dispatch(push(tourl()));
}
}, [user])

56
web/client/src/sections/issueHandle/components/isuue-handle-mdal.js

@ -6,7 +6,8 @@ import {
ProFormSelect,
ProFormTextArea,
ProFormDatePicker,
ProFormDateRangePicker
ProFormDateRangePicker,
ProFormDependency
} from '@ant-design/pro-form';
import Uploads from '$components/Uploads';
import moment from 'moment';
@ -14,7 +15,7 @@ const FormItem = Form.Item;
//state: 1下发未上报 2已上报待审批 3整改完成 上报结果result: status 0 已上报未审批 1 审批通过 2 审批驳回
export default (props) => {
const { title, triggerRender, editData = null, onFinish, readOnly, structsUsers, user } = props;
const users = structsUsers?.find(s => s.id == editData?.points?.project?.id)?.users?.map(v => { return { value: v.id, label: v.name } })
const users = structsUsers?.find(s => s.id == editData?.points?.project?.id)?.users?.map(v => { return { value: v.id, label: v.name, ...v } })
const formItemLayout = { labelCol: { span: 7 }, wrapperCol: { span: 16 } };
const formRef = useRef();
@ -174,7 +175,14 @@ export default (props) => {
name="checkPerson1"
label="验收人:"
disabled={true}
value={ editData?.patrolRecordIssueHandles[0]?.checkPerson?.name}
value={editData?.patrolRecordIssueHandles[0]?.checkPerson?.name}
/>
<ProFormText
name="checkPerson1"
label="成本(元):"
disabled={true}
value={editData?.patrolRecordIssueHandles[0]?.cost}
/>
<Form.Item label="完工图片:">
@ -240,17 +248,18 @@ export default (props) => {
approveHandle(values)
return true;
} else {
values.repairUnit = values?.repairUnits;
values.startTime = values?.dateRange[0];
values.endTime = values?.dateRange[1];
values.repairPerson = { id: users?.find(s => s.value == values.repairPerson)?.value, name: users?.find(s => s.id == values.value)?.label }
values.checkPerson = { id: users?.find(s => s.value == values.checkPerson)?.value, name: users?.find(s => s.id == values.value)?.label }
values.repairPerson = { id: users?.find(s => s.value == values.repairPerson)?.value, name: users?.find(s => s.id == values.repairPerson)?.label }
values.checkPerson = { id: users?.find(s => s.value == values.checkPerson)?.value, name: users?.find(s => s.id == values.checkPerson)?.label }
onFinish && await onFinish(values, editData)
//message.success('提交成功');
return true;
}
}}
submitter={editData?.patrolRecordIssueHandles[0]?.state === 2 && title != '修改计划' ? {
submitter={editData?.patrolRecordIssueHandles[0]?.state === 2 && title != '修改计划' && title != '查看详情' ? {
render: (props, defaultDoms) => {
return [
<Button onClick={() => {
@ -263,7 +272,7 @@ export default (props) => {
}}>驳回</Button>
];
}
} : !readOnly}
} : (!readOnly)}
>
<div>
{/*问题记录信息*/}
@ -271,7 +280,7 @@ export default (props) => {
{/*问题处理计划表单*/}
{
((editData?.patrolRecordIssueHandles?.length == 0 && !readOnly) || editData?.patrolRecordIssueHandles?.length > 0) &&
((editData?.patrolRecordIssueHandles[0]?.state == 1 && title != '查看详情') || editData?.patrolRecordIssueHandles[0]?.state > 1) &&
<>
<div className="item-title">{"维修计划信息"}</div>
<Row>
@ -295,19 +304,28 @@ export default (props) => {
}
</Col>
<Col span={12}>
<ProFormDependency name={['repairPerson']}>
{({ repairPerson }) => {
const department = users?.find(s => s.id == repairPerson)?.department?.name
return (
<ProFormText
name="repairUnit"
label="维修单位:"
disabled={readOnly}
rules={[
{
max: 50, message: '维修单位长度不能大于50个字符'
},
{
whitespace: true, message: '请勿输入空格'
}]}
disabled={true}
name="repairUnits"
label="维修单位"
placeholder=""
fieldProps={{
showSearch: true
}}
colProps={{
span: 12,
}}
value={department}
/>
);
}}
</ProFormDependency>
</Col>
<Col span={12}>
@ -366,7 +384,7 @@ export default (props) => {
}
{
((editData?.patrolRecordIssueHandles[0]?.state !== 1 || editData?.patrolRecordIssueHandles[0]?.state !== 3) && title != '修改计划' && editData?.patrolRecordIssueHandles?.length > 0) &&
((editData?.patrolRecordIssueHandles[0]?.state > 2) || title == '审核') &&
<>
<div className="item-title">{"维修计划审批"}</div>
<div>

8
web/client/src/sections/issueHandle/containers/patrolRecord.js

@ -32,8 +32,8 @@ const PatrolRecord = (props) => {
const queryData = () => {
dispatch(patrolManage.records(`patrolRecord/all/${times[0]}/${times[1]}/true/null`)).then(res => {
if (res.success) {
settableList(name != null ? res.payload.data?.filter(v =>
(v.points.user.name.indexOf(name) != -1 || v.points.project.name.indexOf(name) != -1))
settableList(name != null ? res.payload.data
?.filter(v => (v.points.itemData.name.indexOf(name) != -1 || v.points.project.name.indexOf(name) != -1))
.filter(x => curState == '全部' || curState == renderOptionText(x?.patrolRecordIssueHandles[0]?.state))
.map(v => ({ ...v, key: v.id })) : res.payload.data?.map(v => ({ ...v, key: v.id })))
}
@ -153,7 +153,7 @@ const PatrolRecord = (props) => {
key: 'operation',
render: (text, record, index) => {
const options = [];
if (Func.isAuthorized('ZHIDINGJIHUA') && (!record?.patrolRecordIssueHandles || record?.patrolRecordIssueHandles?.length == 0)) {
if (Func.isAuthorized('ZHIDINGJIHUA') && (!record?.patrolRecordIssueHandles || record?.patrolRecordIssueHandles?.length == 0 || record?.patrolRecordIssueHandles[0]?.state == 1)) {
options.push(<IssueHandleModal
structsUsers={structsUsers}
editData={record}
@ -210,7 +210,7 @@ const PatrolRecord = (props) => {
<div style={{ marginBottom: 20 }}>
<Input style={{ width: 240, marginRight: 20 }}
value={name} onChange={e => { setName(e.target.value) }}
placeholder="请输入结构物名称或上报人" allowClear />
placeholder="请输入结构物名称或点位名称" allowClear />
<Select
value={curState}
onChange={e => { setCurState(e) }}

2
web/client/src/sections/patrolManage/actions/index.js

@ -5,6 +5,7 @@ import * as record from './record'
import * as report from './report'
import * as template from './template'
import * as checkItems from './checkItems'
import * as yujingguanli from './yujingguanli'
export default {
...plan,
@ -12,4 +13,5 @@ export default {
...report,
...template,
...checkItems,
...yujingguanli
}

13
web/client/src/sections/patrolManage/actions/yujingguanli.js

@ -0,0 +1,13 @@
import { basicAction } from '@peace/utils'
import { ApiTable } from '$utils'
export function putxinxi (data) {
return dispatch => basicAction({
type: 'post',
data,
dispatch: dispatch,
actionType: 'PUT_XINXI',
url: ApiTable.yujingguanli,
msg: { option: '发送信息' },
});
}

8
web/client/src/sections/patrolManage/components/planModal.js

@ -33,7 +33,7 @@ const PlanModal = ({ visible, onCreate, onCancel, dispatch, userLoading, userLis
useEffect(() => {
if (userList.length) {
setUserOpt(userList.map(u => ({ label: u.name, value: u.id })))
setUserOpt(userList?.filter(f => f.structure?.includes(curRecord?.project?.id))?.map(u => ({ label: u.name, value: u.id })))
}
}, [userList])
@ -104,13 +104,15 @@ const PlanModal = ({ visible, onCreate, onCancel, dispatch, userLoading, userLis
{ required: true, message: '请选择结构物' },
]}
>
<Select disabled={type === 'view'} options={struOpt} loading={struLoading} onChange={(value) => {
dispatch(positionList({ projectId: value })).then(res => {
<Select disabled={type === 'view'} options={struOpt} loading={struLoading} onChange={(projectId) => {
dispatch(positionList({ projectId })).then(res => {
if (res.success) {
setPoints(res.payload.data?.rows)
setPointOpt(res.payload.data?.rows[0]?.points?.map(p => ({ label: p.name, value: p.id })))
}
})
form.setFieldsValue({ userId: null });
setUserOpt(userList?.filter(f => f.structure?.includes(projectId))?.map(u => ({ label: u.name, value: u.id })))
}} />
</Form.Item>
<Form.Item

78
web/client/src/sections/patrolManage/components/xiafagaojin.js

@ -0,0 +1,78 @@
import { Button, Form, Input, Modal, Select, DatePicker,Checkbox } from 'antd';
import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import { createPatrolTemplate, delPatrolTemplate, updatePatrolTemplate, getPatrolTemplate } from '../actions/template';
import {putxinxi} from '../actions/yujingguanli'
import moment from 'moment';
const { RangePicker } = DatePicker;
const { TextArea } = Input;
const PlanModal = ({ visible, onCancel, dispatch, type, curRecord, tableRef, checkItemsGroup,userlist }) => {
const [form] = Form.useForm();
const shigutypes = [{value:1,label: '邮件告警'},
{value:2,label:'短信告警'}]
console.log(userlist,'userlist')
return (
<Modal
visible={visible}
title="下发告警"
okText="确定"
cancelText="取消"
onCancel={() => {
form.resetFields();
onCancel();
}}
onOk={() => {
form
.validateFields()
.then((values) => {
const params = {
...values,
}
console.log('user,',userlist)
let usedata = userlist.filter(i=>i?.username===values.name)
console.log(usedata,'usedata')
dispatch(putxinxi({phone:[params.name],email:[usedata[0]?.email],type:params.type})).then(res=>{
console.log(res,'res')
})
console.log(params,'params')
})
.catch((info) => {
console.log('Validate Failed:', info);
});
}}
>
<Form
form={form}
// layout="vertical"
name="form_in_modal"
labelCol={{ span: 5 }} wrapperCol={{ span: 19 }}
>
<Form.Item
name="name"
label="告警接收人"
rules={[
{ required: true, message: '请输入用户账号' },
]}
>
<Select options={userlist?.map(i=>({value:i?.username,label:i?.name}))}></Select>
</Form.Item>
<Form.Item label="告警方式"
name="type">
<Checkbox.Group options={shigutypes}/>
</Form.Item>
</Form>
</Modal >
);
};
function mapStateToProps (state) {
const { auth, checkItemsGroup } = state
return {
user: auth.user,
checkItemsGroup: checkItemsGroup.data || []
}
}
export default connect(mapStateToProps)(PlanModal);

3
web/client/src/sections/patrolManage/containers/index.js

@ -5,5 +5,6 @@ import PatrolReocrd from './patrolRecord';
import PatrolReport from './patrolReport';
import CheckItems from './checkItems';
import PlanTemplate from './patrolTemplate';
import YujingGuanli from './yujingguanli';
export { PatrolPlan, PatrolReocrd, PatrolReport, CheckItems, PlanTemplate };
export { PatrolPlan, PatrolReocrd, PatrolReport, CheckItems, PlanTemplate,YujingGuanli };

2
web/client/src/sections/patrolManage/containers/patrolRecord.js

@ -183,7 +183,7 @@ const PatrolRecord = (props) => {
},
onChange: (page, pageSize) => {
setQuery({ limit: pageSize, page: page - 1 });
record({ limit: pageSize, page: page - 1, ...search, companyId: companyID || search?.companyId })
record({ limit: pageSize, page: page - 1, ...search, companyId: search?.companyId })
}
}}
/>

4
web/client/src/sections/patrolManage/containers/patrolReport.js

@ -10,7 +10,7 @@ function patrolReport(props) {
const { dispatch } = props;
const tableRef = useRef();
const [selectOpts, setSelectOpts] = useState([]);
const [date, setDate] = useState([moment(), moment()]);
const [date, setDate] = useState([moment().subtract(1, 'days'), moment()]);
const [dataSource, setDataSource] = useState([]);
const qnDomain = localStorage.getItem('qnDomain');
@ -103,7 +103,7 @@ function patrolReport(props) {
total: res.payload.data.count ? res.payload.data.count : 0,
};
}}
onReset={() => { setDate([moment(), moment()]) }}
onReset={() => { setDate([moment().subtract(1, 'days'), moment()]) }}
/>
</>
)

217
web/client/src/sections/patrolManage/containers/yujingguanli.js

@ -0,0 +1,217 @@
import React, { useState, useRef, useEffect } from 'react';
import { connect } from 'react-redux';
import { Button, Popconfirm, Tag,Tabs } from 'antd';
import ProTable from '@ant-design/pro-table';
import Xiafagaojin from '../components/xiafagaojin';
import {getDepUser} from '../../organization/actions/user'
import { createPatrolTemplate, delPatrolTemplate, updatePatrolTemplate, getPatrolTemplate } from '../actions/template';
import { getCheckItemsGroup } from '../actions/checkItems';
import moment from 'moment';
function YujingGuanli (props) {
const { dispatch, user,actions,depUser} = props;
const tableRef = useRef();
const format = 'YYYY-MM-DD HH:mm:ss'
const { patrolManage } = actions
const [dataSource, setDataSource] = useState([{}]);
const [visible, setVisible] = useState(false);
const [type, setType] = useState();
const [curRecord, setCurRecord] = useState();
const [data,setdata]= useState([])
const [tableList, settableList] = useState([])
const [name, setName] = useState('');
const [curState, setCurState] = useState('全部');
const times = [moment().subtract(70, 'years').format(format), moment().format(format)]
const [search, setSearch] = useState({ name: null, time: [times[0], times[1]], state: 'null' })
const STATE_TEXT = { 1: '待制定计划', 2: '待审核', 3: '计划驳回', 4: '待维修', 5: '待验收', 6: '验收通过', 7: '验收不通过', }
const onChange = (key) => {
console.log(key);
};
const renderOptionText = (currentState) => {
let text = '待制定计划'
return STATE_TEXT[currentState] || text
}
const queryData = () => {
dispatch(patrolManage.records(`patrolRecord/all/${times[0]}/${times[1]}/true/null`)).then(res => {
if (res.success) {
console.log(res,'水平')
let obj = {}
// res?.payload?.data?.map(i=>{
// if(obj[i?.points?.project?.id]){
// // if(obj[i?.points?.project?.id.toString()][i.pointId.toString()]){
// // obj[i?.points?.project?.id.toString()][i.pointId.toString()].ponintname=i.points?.itemData?.name
// // obj[i?.points?.project?.id.toString()][i.pointId.toString()].num=obj[i?.points?.project?.id.toString()][i.pointId.toString()].num+i?.patrolRecordIssueHandles[0]?.state==6?1:0
// // }else{
// // obj[i?.points?.project?.id.toString()][i.pointId.toString()].ponintname=i.points?.itemData?.name
// // obj[i?.points?.project?.id.toString()][i.pointId.toString()].num=i?.patrolRecordIssueHandles[0]?.state==6?1:0
// // }
// obj[i?.points?.project?.id]?.push({pointId:i.pointId,pointname:i.points.itemData.name})
// // i?patrolRecordIssueHandles[0]?.state==6
// obj[i?.points?.project?.id].num= obj[i?.points?.project?.id].num + i?.patrolRecordIssueHandles[0]?.state==6 ?1:0
// }else{
// obj[i?.points?.project?.id]={name:i?.points?.project?.name,num:i?.patrolRecordIssueHandles[0]?.state==6 ?1:0 }
// }
// console.log(obj,'obj')
// })
}
})
}
console.log(depUser,'depUser')
useEffect(() => {
// dispatch(patrolManage.records(`patrolRecord/all/null/null/true/null`)).then(res=>{
// let obj = {}
// res?.payload?.data?.map(i=>{
// if(obj[i?.points?.project?.id]){
// obj[i?.points?.project?.id].name=i?.points?.project?.name;
// obj[i?.points?.project?.id].num=obj[i?.points?.project?.id].num +1
// }else{
// obj[i?.points?.project?.id]={name:i?.points?.project?.name,num:1}
// }
// })
// settableList(name != null ? res.payload.data?.filter(v =>
// (v.points.user.name.indexOf(name) != -1 || v.points.project.name.indexOf(name) != -1))
// .filter(x => curState == '全部' || curState == renderOptionText(x?.patrolRecordIssueHandles[0]?.state))
// .map(v => ({ ...v, key: v.id })) : res.payload.data?.map(v => ({ ...v, key: v.id })))
// const t1 = Object.keys(obj).map(i=>{
// return {id:i,name:obj[i].name,num:obj[i].num}
// })
// console.log(obj,'obj')
// console.log(res,'res')
// })
dispatch(getDepUser())
queryData()
dispatch(getCheckItemsGroup())
}, [])
console.log(tableList,'tablist')
const columns = [{
title: '结构物名称',
dataIndex: 'name',
key: 'name',
// search: false,
ellipsis: true,
}, {
title: '点位名称',
dataIndex: 'describe',
key: 'describe',
search: false,
ellipsis: true
}, {
title: '异常次数',
dataIndex: 'user.name',
key: 'user.name',
ellipsis: true,
search: false,
render: (t, r, i) => {
return r.user ? r.user.name : '-'
}
}, {
title: '产生时间',
dataIndex: 'checkItems',
key: 'checkItems',
ellipsis: true,
search: false,
render: (_, r) => {
return r?.checkItems ? r?.checkItems.map(c => <Tag>{c.name}</Tag>) : '-'
}
}, {
title: '更新时间',
dataIndex: 'checkItems',
key: 'checkItems',
search: false,
ellipsis: true,
render: (_, r) => {
return r?.checkItems ? r?.checkItems.map(c => <Tag>{c.name}</Tag>) : '-'
}
}, {
title: '操作',
dataIndex: 'action',
key: 'action',
search: false,
width: 200,
render: (_, record) => {
return <>
<Button type="link" onClick={() => {
setType('edit')
setCurRecord(record)
setVisible(true)
}}>下发告警</Button>
</>
},
}];
return (
<>
<Tabs
defaultActiveKey="1"
onChange={onChange}
style={{marginLeft:'20px',marginRight:'20px'}}
items={[
{
label: `未告警`,
key: '1',
children: <ProTable
columns={columns}
actionRef={tableRef}
options={false}
dataSource={dataSource || []}
rowKey='id'
pagination={{ pageSize: 10 }}
// search={false}
request={async (params = {}) => {
const res = await dispatch(getPatrolTemplate(params));
setDataSource(res?.payload.data?.rows);
return { ...res };
}}
// toolBarRender={() => [
// <Button
// type="primary"
// key="primary"
// onClick={() => {
// setType('create')
// setVisible(true)
// }}
// >查询</Button>
// ]}
/>,
},
{
label: `已告警`,
key: '2',
children: `Content of Tab Pane 2`,
}
]}
/>
{
visible &&depUser.filter(i=>i.username&&i.email).length!==0 ?
<Xiafagaojin
visible={visible}
type={type}
curRecord={curRecord}
userlist={depUser.filter(i=>i.username&&i.email)}
onCancel={() => {
setVisible(false);
setCurRecord({})
}}
tableRef={tableRef}
/> : null
}
</>
)
}
function mapStateToProps (state) {
const { auth, global ,depUser} = state
return {
user: auth.user,
actions: global.actions,
depUser: depUser.data || [],
}
}
export default connect(mapStateToProps)(YujingGuanli);

3
web/client/src/sections/patrolManage/nav-item.js

@ -26,6 +26,9 @@ export function getNavItem (user, dispatch) {
{Func.isAuthorized('CHECKMOULD') && <Menu.Item key="patrolTemplate">
<Link to="/patrolManage/patrolTemplate">巡检模板</Link>
</Menu.Item>}
{ <Menu.Item key="yujingguanli">
<Link to="/patrolManage/yujingguanli">预警管理</Link>
</Menu.Item>}
</SubMenu>
);
}

11
web/client/src/sections/patrolManage/routes.js

@ -1,5 +1,5 @@
'use strict';
import { PatrolPlan, PatrolReocrd, PatrolReport, CheckItems, PlanTemplate } from './containers';
import { PatrolPlan, PatrolReocrd, PatrolReport, CheckItems, PlanTemplate ,YujingGuanli} from './containers';
export default [{
type: 'inner',
@ -32,6 +32,13 @@ export default [{
key: 'patrolTemplate',
component: PlanTemplate,
breadcrumb: '巡检模板',
}]
},
{
path: '/yujingguanli',
key: 'yujingguanli',
component: YujingGuanli,
breadcrumb: '预警管理',
}
]
}
}];

9
web/client/src/sections/shouye/actions/index.js

@ -0,0 +1,9 @@
'use strict';
export default {
}

9
web/client/src/sections/shouye/containers/index.js

@ -0,0 +1,9 @@
'use strict';
import Shouye from './shouye'
export { Shouye };

62
web/client/src/sections/shouye/containers/shouye.js

@ -0,0 +1,62 @@
import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
import { Spin, Card, Form, Input, Select, Button, Table, Modal, Popconfirm, Tooltip } from 'antd';
import moment from "moment";
import '../style.less';
import { push } from 'react-router-redux';
import { Model } from 'echarts';
const Information = (props) => {
const { dispatch, actions, user, loading } = props
const topdata =[]
return (
<>
<div className='shouyetop'>
<div className='shouyetopitem'>
<div className='shouyetopitem-left' >
<div>今日巡检</div>
<div>0</div>
</div>
<div className='shouyetopitem-right'>
<div>完成巡检2</div>
<div>巡检上报2</div>
</div>
</div>
<div className='shouyetopitem'>
<div className='shouyetopitem-left' >
<div>今日巡检</div>
<div>0</div>
</div>
<div className='shouyetopitem-right'>
<div>完成巡检2</div>
<div>巡检上报2</div>
</div>
</div>
<div className='shouyetopitem'>
<div className='shouyetopitem-left' >
<div>今日巡检</div>
<div>0</div>
</div>
<div className='shouyetopitem-right'>
<div>完成巡检2</div>
<div>巡检上报2</div>
</div>
</div>
</div>
</>
)
}
function mapStateToProps (state) {
const { auth, global } = state;
return {
user: auth.user,
actions: global.actions,
};
}
export default connect(mapStateToProps)(Information);

15
web/client/src/sections/shouye/index.js

@ -0,0 +1,15 @@
'use strict';
import reducers from './reducers';
import routes from './routes';
import actions from './actions';
import { getNavItem } from './nav-item';
export default {
key: 'shouye',
name: '首页',
reducers: reducers,
routes: routes,
actions: actions,
getNavItem: getNavItem
};

21
web/client/src/sections/shouye/nav-item.js

@ -0,0 +1,21 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { Menu } from 'antd';
import { SettingOutlined } from '@ant-design/icons';
import { Func } from '$utils';
const SubMenu = Menu.SubMenu;
export function getNavItem (user, dispatch) {
// return <SubMenu key="shouye" icon={<SettingOutlined />} title={'首页'}>
// {/* {Func.isAuthorized('STRU_INFO_CONFIG') &&<Menu.Item key="information">
// <Link to="/projectRegime/information">结构物基础信息管理</Link>
// </Menu.Item>}
// {Func.isAuthorized('QR_CODE_CONFIG') &&<Menu.Item key="qrCode">
// <Link to="/projectRegime/qrCode">二维码管理</Link>
// </Menu.Item>} */}
// </SubMenu>
return <Menu.Item key="shouye">
<Link to="/shouye">首页</Link>
</Menu.Item>
}

5
web/client/src/sections/shouye/reducers/index.js

@ -0,0 +1,5 @@
'use strict';
export default {
}

32
web/client/src/sections/shouye/routes.js

@ -0,0 +1,32 @@
'use strict';
import { Shouye } from './containers';
export default [{
type: 'inner',
route: {
path: '/shouye',
key: 'shouye',
breadcrumb: '首页',
component: Shouye,
// 不设置 component 则面包屑禁止跳转
// childRoutes: [{
// path: '/information',
// key: 'information',
// breadcrumb: '结构物基础信息管理',
// component: Information,
// childRoutes: [ {
// path: '/:id',
// key: ':id',
// component: Point,
// breadcrumb: '点位',
// },
// ]
// }, {
// path: '/qrCode',
// key: 'qrCode',
// component: QrCode,
// breadcrumb: '二维码管理',
// },
// ]
}
}];

20
web/client/src/sections/shouye/style.less

@ -0,0 +1,20 @@
.shouyetop{
display: flex;
justify-content: space-between;
.shouyetopitem{
width: 25%;
display: flex;
justify-content: space-between;
box-shadow: 0 0 10px #F0F2F5;
border:1px solid #F0F2F5;
color: rgba(0, 0, 0, 0.45);
font-size: 1.875rem;
height: 7.125rem;
.shouyetopitem-left{
width: 50%;
}
.shouyetopitem-right{
width: 50%;
}
}
}

1
web/client/src/utils/webapi.js

@ -64,6 +64,7 @@ export const ApiTable = {
delCheckTask: '/delcheckTask/:id',
addPatrolRecordIssueHandle: 'patrolRecord/issue/handle',
modifyPatrolRecordIssueHandle: 'patrolRecord/issue/handle/{id}',
yujingguanli:'/yujingguanli',
//协调申请
getCoordinateList: 'risk/coordinate',

Loading…
Cancel
Save