wenlele 12 months ago
parent
commit
5ce59f9928
  1. 36
      api/app/lib/controllers/data/appointed.js
  2. 2
      api/app/lib/controllers/data/road.js
  3. 5
      api/app/lib/index.js
  4. 17
      api/app/lib/utils/index.js
  5. 36
      api/app/lib/utils/push.js
  6. 145
      weapp/src/packages/patrol/index.jsx

36
api/app/lib/controllers/data/appointed.js

@ -1,6 +1,26 @@
'use strict'; 'use strict';
const moment = require('moment') const moment = require('moment')
const reportTypeText = (text) => {
switch (text) {
case 'road': return '道路';
//
case 'countyRoad': return '县道';
case 'villageRoad': return '乡道';
case 'rusticRoad': return '村道';
//
case 'bridge': return '桥梁';
case 'culvert': return '涵洞';
case 'other': return '其他';
//
case 'conserve': return '养护';
case 'patrol': return '巡查';
case 'construction': return '在建';
default: return text;
}
}
async function appoint(ctx) { async function appoint(ctx) {
try { try {
const models = ctx.fs.dc.models const models = ctx.fs.dc.models
@ -8,6 +28,22 @@ async function appoint(ctx) {
await models.Report.update({ await models.Report.update({
performerId, handleAdvice, handleState performerId, handleAdvice, handleState
}, { where: { id: recordId } }) }, { where: { id: recordId } })
const { pushBySms } = ctx.app.fs.utils
const report = await models.Report.findOne({ where: { id: recordId } })
const data = await models.User.findOne({ where: { id: performerId } })
if (data.phone && data.name && report.projectType) {
await pushBySms({
phone: [data.phone],
templateCode: 'SMS_464820121',
templateParam: {
report_name: data.name,
type: reportTypeText(report.projectType),
road_name: report.road,
section_name: report.roadSectionStart + report.roadSectionEnd
}
})
}
ctx.status = 204; ctx.status = 204;
} catch (error) { } catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);

2
api/app/lib/controllers/data/road.js

@ -96,7 +96,7 @@ async function getRoadSection (ctx) {
let findOption = { let findOption = {
where: { del: false }, where: { del: false },
order: [['id', 'DESC']], order: [['id', 'DESC']],
attributes: ['id', 'routeName', 'startingPlaceName', 'stopPlaceName', 'routeCode', 'sectionNo', 'level'] attributes: ['id', 'routeName', 'startingPlaceName', 'stopPlaceName', 'routeCode', 'sectionNo', 'level', 'startStation', 'stopStation']
} }
if (level) { if (level) {

5
api/app/lib/index.js

@ -7,6 +7,7 @@ const authenticator = require('./middlewares/authenticator');
// const apiLog = require('./middlewares/api-log'); // const apiLog = require('./middlewares/api-log');
const paasRequest = require('./service/paasRequest'); const paasRequest = require('./service/paasRequest');
const schedule = require('./schedule') const schedule = require('./schedule')
const utils = require('./utils')
module.exports.entry = function (app, router, opts) { module.exports.entry = function (app, router, opts) {
app.fs.logger.log('info', '[FS-AUTH]', 'Inject auth and api mv into router.'); app.fs.logger.log('info', '[FS-AUTH]', 'Inject auth and api mv into router.');
@ -14,6 +15,7 @@ module.exports.entry = function (app, router, opts) {
app.fs.api = app.fs.api || {}; app.fs.api = app.fs.api || {};
app.fs.api.authAttr = app.fs.api.authAttr || {}; app.fs.api.authAttr = app.fs.api.authAttr || {};
app.fs.api.logAttr = app.fs.api.logAttr || {}; app.fs.api.logAttr = app.fs.api.logAttr || {};
app.fs.utils = app.fs.utils || {};
router.use(authenticator(app, opts)); router.use(authenticator(app, opts));
// router.use(apiLog(app, opts)); // router.use(apiLog(app, opts));
@ -22,6 +24,9 @@ module.exports.entry = function (app, router, opts) {
// 定时任务 // 定时任务
schedule(app, opts) schedule(app, opts)
// 工具类函数
utils(app, opts)
router = routes(app, router, opts); router = routes(app, router, opts);
}; };

17
api/app/lib/utils/index.js

@ -0,0 +1,17 @@
'use strict';
const path = require('path');
const fs = require('fs');
module.exports = async function (app, opts) {
fs.readdirSync(__dirname).forEach((filename) => {
if (!['index.js'].some(f => filename == f)) {
const utils = require(`./${filename}`)(app, opts)
console.log(`载入 ${filename} 工具集成功`);
app.fs.utils = {
...app.fs.utils,
...utils,
}
}
});
};

36
api/app/lib/utils/push.js

@ -0,0 +1,36 @@
'use strict';
const moment = require('moment')
const Core = require('@alicloud/pop-core');
module.exports = function (app, opts) {
const pushBySms = async ({ phone = [], templateCode, templateParam } = {}) => {
try {
if (phone.length) {
const client = new Core({
accessKeyId: opts.sms.accessKey,
accessKeySecret: opts.sms.accessSecret,
endpoint: 'http://dysmsapi.aliyuncs.com',//固定
apiVersion: '2017-05-25'//固定
});
const SendSmsRes = await client.request('SendSms', {
"PhoneNumbers": phone.join(','),//接收短信的手机号码。
"SignName": "四好农村路",//短信签名名称。必须是已添加、并通过审核的短信签名。
"TemplateCode": templateCode,//短信模板ID。必须是已添加、并通过审核的短信签名;且发送国际/港澳台消息时,请使用国际/港澳台短信模版。
"TemplateParam": JSON.stringify(templateParam)//短信模板变量对应的实际值,JSON格式。
}, {
method: 'POST'
});
return SendSmsRes
}
} catch (error) {
throw error
}
}
return {
pushBySms,
}
}

145
weapp/src/packages/patrol/index.jsx

@ -225,11 +225,12 @@ const Index = () => {
]); ]);
const [routeNameList, setRouteNameList] = useState([]); const [routeNameList, setRouteNameList] = useState([]);
const [routeCodeList, setRouteCodeList] = useState([]); const [routeCodeList, setRouteCodeList] = useState([]);
const [sectionNoList, setSectionNoList] = useState([]); const [stationRangeList, setStationRangeList] = useState([]);
const [roadChecked, setRoadChecked] = useState({ const [roadChecked, setRoadChecked] = useState({
routeName: '', routeName: '',
routeCode: '', routeCode: '',
sectionNo: '', sectionNo: '',
stationRange: '',
startingPlaceName: '', startingPlaceName: '',
stopPlaceName: '', stopPlaceName: '',
}) })
@ -362,6 +363,7 @@ const Index = () => {
routeName: data.road, routeName: data.road,
routeCode: data.codeRoad, routeCode: data.codeRoad,
sectionNo: data.road_?.sectionNo || '-', sectionNo: data.road_?.sectionNo || '-',
stationRange: `${data.road_?.startStation || ' '} - ${data.road_?.stopStation || ' '}`,
startingPlaceName: data.roadSectionStart, startingPlaceName: data.roadSectionStart,
stopPlaceName: data.roadSectionEnd, stopPlaceName: data.roadSectionEnd,
}) })
@ -415,35 +417,22 @@ const Index = () => {
let nextSourceRoadStartSel = [] let nextSourceRoadStartSel = []
let nextSourceRoadEndSel = [] let nextSourceRoadEndSel = []
let nextCodeRoadSel = [] let nextCodeRoadSel = []
let routeName = []
let routeCode = [] let routeCode = []
let sectionNo = []
const selLevel = roadTypeList.find(item => item.checked).value const selLevel = roadTypeList.find(item => item.checked).value
data.forEach(item => { data.forEach(item => {
nextSourceRoadStartSel.push(item.startingPlaceName) nextSourceRoadStartSel.push(item.startingPlaceName)
nextSourceRoadEndSel.push(item.stopPlaceName) nextSourceRoadEndSel.push(item.stopPlaceName)
nextCodeRoadSel.push(item.routeCode) nextCodeRoadSel.push(item.routeCode)
if (item.routeCode && !routeCode.includes(item.routeCode) && item.level === selLevel) {
if (item.routeName && !routeName.includes(item.routeName) && item.level === selLevel) {
routeName.push(item.routeName)
}
if (item.routeCode && !routeCode.includes(item.routeCode)) {
routeCode.push(item.routeCode) routeCode.push(item.routeCode)
} }
if (item.sectionNo && !sectionNo.includes(item.sectionNo)) {
sectionNo.push(item.sectionNo)
}
}) })
setSourceRoadStartSel(nextSourceRoadStartSel) setSourceRoadStartSel(nextSourceRoadStartSel)
setSourceRoadEndSel(nextSourceRoadEndSel) setSourceRoadEndSel(nextSourceRoadEndSel)
setCodeRoadSel(nextCodeRoadSel) setCodeRoadSel(nextCodeRoadSel)
setRoadList(data) setRoadList(data)
setRouteNameList(routeName)
setRouteCodeList(routeCode) setRouteCodeList(routeCode)
setSectionNoList(sectionNo)
} else { } else {
Taro.showToast({ title: res.data.message || '请求出错', icon: 'none' }) Taro.showToast({ title: res.data.message || '请求出错', icon: 'none' })
} }
@ -529,6 +518,7 @@ const Index = () => {
&& roadChecked?.routeCode == r?.routeCode && roadChecked?.routeCode == r?.routeCode
&& roadChecked?.sectionNo == r?.sectionNo && roadChecked?.sectionNo == r?.sectionNo
)?.id, )?.id,
} }
if (reportType === 'patrol' || isAnomaly || isRoad) { if (reportType === 'patrol' || isAnomaly || isRoad) {
data['scenePic'] = sceneImg data['scenePic'] = sceneImg
@ -757,52 +747,40 @@ const Index = () => {
} }
} }
const handleRoadCheckChange = (value, key, typeList = roadTypeList) => { const handleRoadCheckChange = (value, key, typeList = roadTypeList, sectionNo) => {
let nextValue = { let nextValue = {
...roadChecked, ...roadChecked,
[key]: value [key]: value
} }
let routeCode = []
let sectionNo = []
let data = roadList.filter(r => r.level === typeList.find(t => t.checked).value) let data = roadList.filter(r => r.level === typeList.find(t => t.checked).value)
if (key == 'routeName') { if (key == 'stationRange') nextValue.sectionNo = sectionNo;
// routeName
let routeName = []
data.forEach(item => {
if (item.routeName && !routeName.includes(item.routeName)) {
routeName.push(item.routeName)
}
})
if (value) {
routeName = routeName.filter(item => item.indexOf(value) > -1)
}
setRouteNameList(routeName)
nextValue.routeCode = ''
nextValue.sectionNo = ''
data?.forEach(v => {
if (nextValue?.routeName && nextValue?.routeName == v.routeName && v.routeCode && !routeCode.includes(v.routeCode)) {
routeCode.push(v.routeCode)
}
});
setRouteCodeList(routeCode)
}
if (key == 'routeCode') { if (key == 'routeCode') {
nextValue.sectionNo = '' nextValue.sectionNo = ''
data = roadList?.filter(s => nextValue?.routeName == s?.routeName) nextValue.stationRange = ''
data?.forEach(v => { let routeCode = []
if (nextValue?.routeCode && nextValue?.routeCode == v?.routeCode && v.sectionNo && !sectionNo.includes(v.sectionNo)) { let matchData = []
sectionNo.push(v.sectionNo) data.forEach(item => {
if (item.routeCode.indexOf(value) > -1) {
routeCode.push(item.routeCode)
} }
if (!nextValue?.routeCode && v.routeCode && !routeCode.includes(v.routeCode)) { if (item.routeCode === value) {
routeCode.push(v.routeCode) matchData.push(item)
} }
}); })
if (!nextValue?.routeCode) { setRouteCodeList(routeCode)
setRouteCodeList(routeCode) if (matchData.length) {
// 线
nextValue.routeName = matchData[0].routeName
//
setStationRangeList(matchData.map(s => ({
label: `${s.startStation || ' '} - ${s.stopStation || ' '}`,
sectionNo: s.sectionNo,
})))
} else {
nextValue.routeName = ''
setStationRangeList([])
} }
setSectionNoList(sectionNo)
} }
if (nextValue?.routeName) { if (nextValue?.routeName) {
@ -823,6 +801,7 @@ const Index = () => {
&& nextValue.routeCode == s.routeCode && nextValue.routeCode == s.routeCode
&& nextValue.sectionNo == s.sectionNo && nextValue.sectionNo == s.sectionNo
) )
nextValue.startingPlaceName = find?.startingPlaceName nextValue.startingPlaceName = find?.startingPlaceName
nextValue.stopPlaceName = find?.stopPlaceName nextValue.stopPlaceName = find?.stopPlaceName
setRoadCodeHead(find?.routeCode?.charAt(0)) setRoadCodeHead(find?.routeCode?.charAt(0))
@ -1080,7 +1059,7 @@ const Index = () => {
for (let i = 0, len = items.length; i < len; ++i) { for (let i = 0, len = items.length; i < len; ++i) {
items[i].checked = items[i].value === e.detail.value items[i].checked = items[i].value === e.detail.value
} }
handleRoadCheckChange('', 'routeName', items) handleRoadCheckChange('', 'routeCode', items) // routeCode
setRoadTypeList(items) setRoadTypeList(items)
} }
@ -1104,77 +1083,75 @@ const Index = () => {
</RadioGroup> </RadioGroup>
</View> </View>
</View> </View>
<View className='code-choice'>
<Text style={{ color: 'red' }}>*&nbsp;</Text>路线名称 {!(isView && isBeforeReport) && <View className={`code-choice`}>
<Text style={{ color: 'red' }}>*&nbsp;</Text>线路编码
<View className='select-box'> <View className='select-box'>
<View className='picker'> <View className='picker'>
<Input <Input
style={{ textAlign: 'right' }} style={{ textAlign: 'right' }}
type='text' type='text'
placeholder='输入关键字筛选' placeholder='选择或输入编码'
border={false} border={false}
value={roadChecked.routeName} value={roadChecked.routeCode}
onInput={e => handleRoadCheckChange(e.detail.value, 'routeName')} onInput={e => handleRoadCheckChange(e.detail.value, 'routeCode')}
disabled={isView} disabled={isView}
/> />
<Picker <Picker
mode='selector' mode='selector'
range={routeNameList} range={routeCodeList}
onChange={e => handleRoadCheckChange(routeNameList[e.detail.value], 'routeName')} onChange={e => handleRoadCheckChange(routeCodeList[e.detail.value], 'routeCode')}
disabled={isView} disabled={isView}
> >
<AtIcon className='arrow' value='chevron-down' size='20' color='#999' /> <AtIcon className='arrow' value='chevron-down' size='20' color='#999' />
</Picker> </Picker>
{roadChecked.routeCode && !isView && <AtIcon
value='close-circle'
size='20'
color='#999'
onClick={() => handleRoadCheckChange('', 'routeCode')}
/>}
</View> </View>
{!isView && <AtIcon
value='close-circle'
size='20'
color='#999'
onClick={() => handleRoadCheckChange('', 'routeName')}
/>}
</View> </View>
</View> </View>}
{!(isView && isBeforeReport) && <View className={`code-choice ${routeCodeDisabled && !isView ? ` disabled` : ``}`}>
<Text style={{ color: 'red' }}>*&nbsp;</Text>线路编码 <View className='code-choice disabled'>
<Text style={{ color: 'red' }}>*&nbsp;</Text>路线名称
<View className='select-box'> <View className='select-box'>
<Picker <Picker
mode='selector' mode='selector'
range={routeCodeList} range={routeNameList}
onChange={e => handleRoadCheckChange(routeCodeList[e.detail.value], 'routeCode')} onChange={e => handleRoadCheckChange(routeNameList[e.detail.value], 'routeName')}
disabled={routeCodeDisabled} disabled={true}
> >
<View className='picker'> <View className='picker'>
<View>{roadChecked.routeCode || '选择线路编码'}</View> <View>{roadChecked.routeName || '选择编码自动带出'}</View>
<AtIcon className='arrow' value='chevron-down' size='20' color='#999' /> <AtIcon className='arrow' value='chevron-down' size='20' color='#999' />
</View> </View>
</Picker> </Picker>
{roadChecked.routeCode && !isView && <AtIcon
value='close-circle'
size='20'
color='#999'
onClick={() => handleRoadCheckChange('', 'routeCode')}
/>}
</View> </View>
</View>} </View>
<View className={`code-choice ${sectionNoDisabled && !isView ? ` disabled` : ``}`}> <View className={`code-choice ${sectionNoDisabled && !isView ? ` disabled` : ``}`}>
<Text style={{ color: 'red' }}>*&nbsp;</Text>路段序号 <Text style={{ color: 'red' }}>*&nbsp;</Text>桩号区间
<View className='select-box'> <View className='select-box'>
<Picker <Picker
mode='selector' mode='selector'
range={sectionNoList} range={stationRangeList}
onChange={e => handleRoadCheckChange(sectionNoList[e.detail.value], 'sectionNo')} rangeKey='label'
onChange={e => handleRoadCheckChange(stationRangeList[e.detail.value].label, 'stationRange', undefined, stationRangeList[e.detail.value].sectionNo)}
disabled={sectionNoDisabled} disabled={sectionNoDisabled}
> >
<View className='picker'> <View className='picker'>
<View>{roadChecked.sectionNo || '请选择路段序号'}</View> <View>{roadChecked.stationRange || '请选择桩号区间'}</View>
<AtIcon className='arrow' value='chevron-down' size='20' color='#999' /> <AtIcon className='arrow' value='chevron-down' size='20' color='#999' />
</View> </View>
</Picker> </Picker>
{roadChecked.sectionNo && !isView && <AtIcon {roadChecked.stationRange && !isView && <AtIcon
value='close-circle' value='close-circle'
size='20' size='20'
color='#999' color='#999'
onClick={() => handleRoadCheckChange('', 'sectionNo')} onClick={() => handleRoadCheckChange('', 'stationRange', undefined, '')}
/>} />}
</View> </View>
</View> </View>

Loading…
Cancel
Save