| | |
| | | "pages/inspection/scene/info/device-info/index", |
| | | "pages/inspection/scene/info/device-status/index", |
| | | "pages/simple-home/index", |
| | | "pages/inspection/ranking/search/index" |
| | | "pages/inspection/ranking/search/index", |
| | | "pages/cluetask/home/index" |
| | | ], |
| | | "tabBar": { |
| | | "custom": true, |
| | |
| | | "text": "ç²¾ç»åç管" |
| | | }, |
| | | { |
| | | "pagePath": "pages/cluetask/home/index", |
| | | "text": "åºæ¥çº¿ç´¢" |
| | | }, |
| | | { |
| | | "pagePath": "pages/selfpatrol/index", |
| | | "text": "åºæ¥èªå·¡æ¥" |
| | | }, |
¶Ô±ÈÐÂÎļþ |
| | |
| | | // åºæ¥çº¿ç´¢ä»»å¡ååºçº§å« |
| | | const ResponseLevels = [ |
| | | { value: null, label: 'å
¨é¨' }, |
| | | { value: 0, label: '彿¥' }, |
| | | { value: 1, label: 'ä¸å¤©å
' }, |
| | | { value: 2, label: 'ä¸å¨å
' }, |
| | | { value: 3, label: '彿' }, |
| | | ]; |
| | | |
| | | export default { |
| | | ResponseLevels, |
| | | toLabel(value) { |
| | | let r = ResponseLevels.find(item => { |
| | | return item.value == value; |
| | | }); |
| | | if (!r) r = ResponseLevels[0]; |
| | | return r.label; |
| | | }, |
| | | |
| | | toLabel2(value) { |
| | | let l = this.toLabel(value); |
| | | if (l == ResponseLevels[0].label) { |
| | | l = '/'; |
| | | } |
| | | return l; |
| | | }, |
| | | |
| | | toValue(label) { |
| | | const r = ResponseLevels.find(item => { |
| | | return item.label == label; |
| | | }); |
| | | return r.value; |
| | | }, |
| | | }; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | // åºæ¥çº¿ç´¢ä»»å¡ååºçº§å« |
| | | |
| | | const TravelModes = [ |
| | | { value: null, label: 'å
¨é¨' }, |
| | | { value: 0, label: '驾车' }, |
| | | { value: 1, label: 'å
Œ
±äº¤é' }, |
| | | { value: 2, label: 'æ¥è¡' }, |
| | | ]; |
| | | |
| | | export default { |
| | | TravelModes, |
| | | toLabel(value) { |
| | | let r = TravelModes.find(item => { |
| | | return item.value == value; |
| | | }); |
| | | if (!r) r = TravelModes[0]; |
| | | return r.label; |
| | | }, |
| | | |
| | | toLabel2(value) { |
| | | let l = this.toLabel(value); |
| | | if (l == TravelModes[0].label) { |
| | | l = '/'; |
| | | } |
| | | return l; |
| | | }, |
| | | |
| | | toValue(label) { |
| | | const r = TravelModes.find(item => { |
| | | return item.label == label; |
| | | }); |
| | | return r.value; |
| | | }, |
| | | }; |
| | |
| | | * çæä¸æ¡è¡¨åæ¡ç® |
| | | * @param {String} _label æ ç¾åç§° |
| | | * @param {String} _name åæ®µåç§° |
| | | * @param {String} _type è¾å
¥ç±»å ï¼text: è¾å
¥æ¡; switch: 忢æé®; picker: 䏿æ¡é项; cascader: 级èéæ©ï¼ |
| | | * @param {Boolean} _required æ¯å¦ä¸ºå¿
填项 |
| | | * @param {String} _type è¾å
¥ç±»å ï¼text: è¾å
¥æ¡; switch: 忢æé®; picker: 䏿æ¡é项; cascader: 级èéæ©ï¼ |
| | | * @param {Array} _options å½è¾å
¥ç±»å为pickeræcascaderæ¶ï¼æä¾å¯é项 |
| | | * @param {Array} cascaderTitles å½è¾å
¥ç±»å为cascaderæ¶ï¼æä¾æ¯å±éé¡¹çæ é¢ |
| | | * @param {Array} referItems å½è¾å
¥ç±»å为cascaderæ¶ï¼æä¾å
³èç屿§name |
| | |
| | | const inspectPicUrl = `${iu}/images/`; |
| | | // const inspectPicUrl = `${inspectUrl}/images/`; |
| | | |
| | | // const mode = 'debug'; |
| | | const mode = 'prod'; |
| | | // éè·¯åºæ¥çº¿ç´¢ |
| | | // const clueUrl = 'https://fyami.com.cn:448/'; |
| | | const clueUrl = 'http://192.168.0.110:8084/'; |
| | | const cu = 'https://fyami.com.cn:448'; |
| | | const cluePicUrl = `${cu}/images/`; |
| | | |
| | | export { basePicUrl, baseUrl, baseFileUrl, baseIconUrl, inspectUrl, inspectPicUrl, mode }; |
| | | // è¿è¡æ¨¡å¼ |
| | | const mode = 'debug'; |
| | | // const mode = 'prod'; |
| | | |
| | | export { |
| | | basePicUrl, |
| | | baseUrl, |
| | | baseFileUrl, |
| | | baseIconUrl, |
| | | inspectUrl, |
| | | inspectPicUrl, |
| | | clueUrl, |
| | | cluePicUrl, |
| | | mode, |
| | | }; |
| | |
| | | level: 2, |
| | | }, |
| | | { |
| | | icon: 'fact-check', |
| | | text: 'åºæ¥çº¿ç´¢', |
| | | url: 'pages/cluetask/home/index', |
| | | level: 1, |
| | | }, |
| | | { |
| | | // icon: `${baseIconUrl}tab-slef-patrol.png`, |
| | | icon: 'root-list', |
| | | text: 'åºæ¥èªå·¡æ¥', |
| | |
| | | list: TabMenu, |
| | | }, |
| | | attached() { |
| | | const menu = TabMenu.map(v => { |
| | | v.visible = app.globalData.userInfo.usertypeid <= v.level; |
| | | return v; |
| | | const menu = [] |
| | | TabMenu.forEach(v => { |
| | | if (app.globalData.userInfo.usertypeid <= v.level) { |
| | | menu.push(v) |
| | | } |
| | | }); |
| | | // TabMenu.map(v => { |
| | | // v.visible = app.globalData.userInfo.usertypeid <= v.level; |
| | | // return v; |
| | | // }); |
| | | this.setData({ list: menu }); |
| | | }, |
| | | methods: { |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { cluePicUrl } from '../../config/index'; |
| | | |
| | | function getClueQuestion(data) { |
| | | data.cqFilePath = data.cqFilePath.split(';').map((val) => { |
| | | return cluePicUrl + val; |
| | | }); |
| | | return data; |
| | | } |
| | | |
| | | function getClueQuestionList(dataList) { |
| | | return dataList.map((v) => { |
| | | return getClueQuestion(v); |
| | | }); |
| | | } |
| | | |
| | | export { getClueQuestion, getClueQuestionList }; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * 线索ç»è®¡ |
| | | */ |
| | | export function getClueStatistic(dataList) { |
| | | let total = dataList.length, |
| | | finished = 0, |
| | | unfinished = 0; |
| | | |
| | | dataList.forEach(d => { |
| | | d.finished ? finished++ : unfinished++; |
| | | }); |
| | | |
| | | const p1 = Math.round((finished / total) * 1000) / 10; |
| | | const p2 = Math.round((unfinished / total) * 1000) / 10; |
| | | return [ |
| | | { |
| | | name: 'æ»è®¡', |
| | | value: total, |
| | | diff: '', |
| | | }, |
| | | { |
| | | name: '已宿', |
| | | value: finished, |
| | | diff: total == 0 ? '0%' : `${p1}%`, |
| | | }, |
| | | { |
| | | name: 'å¾
宿', |
| | | value: unfinished, |
| | | diff: total == 0 ? '0%' : `${p2}%`, |
| | | }, |
| | | ]; |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { useLoading } from '../../../behaviors/loading'; |
| | | import { useOptions } from './options-proxy.js'; |
| | | import { useStatistic } from './statistic-proxy.js'; |
| | | import { useTasks } from './tasks-proxy.js'; |
| | | |
| | | import clueApi from '../../../services/clue/fetchClue'; |
| | | |
| | | const app = getApp(); |
| | | |
| | | Page({ |
| | | behaviors: [useLoading, useOptions, useStatistic, useTasks], |
| | | |
| | | data: { |
| | | userInfo: app.globalData.userInfo, |
| | | clueTaskList: [], |
| | | }, |
| | | |
| | | onLoad(options) {}, |
| | | |
| | | onShow() { |
| | | this.getTabBar().init(); |
| | | }, |
| | | |
| | | onPullDownRefresh() { |
| | | this._startLoad(); |
| | | }, |
| | | |
| | | onReachBottom() { |
| | | this._loadMore(); |
| | | }, |
| | | |
| | | /** |
| | | * åå§å è½½ |
| | | * 彿æç鿡件é½è·åå°åå§å¼åï¼æ§è¡ä¸æ¬¡åå§åå è½½ |
| | | * å
æ¬åºåãæ¶é´ä¸¤ä¸ªé项ï¼å
¨é¨è·ååå§å¼åï¼æ§è¡å è½½ |
| | | * @see options-proxy.js |
| | | */ |
| | | optionsCount: 0, |
| | | init() { |
| | | this.optionsCount++; |
| | | if (this.optionsCount == 2) this._startLoad(); |
| | | }, |
| | | |
| | | _fetchData(page) { |
| | | return clueApi.fetchClueTask({}).then(res => { |
| | | this.setData({ clueTaskList: res.data }); |
| | | this.calClueCount(); |
| | | this.formatClueTask(); |
| | | }); |
| | | }, |
| | | }); |
¶Ô±ÈÐÂÎļþ |
| | |
| | | { |
| | | "navigationBarTitleText": "åºæ¥çº¿ç´¢", |
| | | "onReachBottomDistance": 10, |
| | | "backgroundTextStyle": "light", |
| | | "enablePullDownRefresh": true, |
| | | "navigationBarTextStyle": "white", |
| | | "navigationBarBackgroundColor": "#389AFF", |
| | | "usingComponents": { |
| | | "location-picker": "/components/picker/location-picker/index", |
| | | "t-time-picker": "/components/time-picker/index", |
| | | "stat-card": "/components/stat-card/index" |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <import src="/pages/common/template/template-loading.wxml" /> |
| | | |
| | | <view class="page"> |
| | | <template is="pulldown-loading" wx:if="{{pageLoading}}" /> |
| | | <view class="page-header"> |
| | | |
| | | </view> |
| | | <view class="page-container"> |
| | | <include src="./options.wxml" /> |
| | | <include src="./statistic.wxml" /> |
| | | <include src="./tasks.wxml" /> |
| | | <t-toast id="t-toast" /> |
| | | </view> |
| | | <view class="page-footer"></view> |
| | | </view> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | @import './options.wxss'; |
| | | @import './statistic.wxss'; |
| | | @import './tasks.wxss'; |
| | | |
| | | page { |
| | | --header-bottom-padding: 600rpx; |
| | | } |
| | | |
| | | .page .page-header { |
| | | background: linear-gradient(var(--td-primary-color-7), var(--td-bg-color)); |
| | | padding-bottom: var(--header-bottom-padding); |
| | | } |
| | | |
| | | .page .page-container { |
| | | margin-top: calc(0rpx - var(--header-bottom-padding)); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import dayjs from 'dayjs'; |
| | | |
| | | /** |
| | | * ç鿡件ç¸å
³ä¿¡æ¯è·åé»è¾ |
| | | * å
æ¬æ¶é´ãè¡æ¿åºå |
| | | */ |
| | | export const useOptions = Behavior({ |
| | | data: { |
| | | time:'', |
| | | }, |
| | | methods: { |
| | | setLocation(e) { |
| | | const { |
| | | provinceText: provinceName, |
| | | cityText: cityName, |
| | | districtText: districtName, |
| | | townText: townName, |
| | | provinceValue: provinceCode, |
| | | cityValue: cityCode, |
| | | districtValue: districtCode, |
| | | townValue: townCode, |
| | | locationValue, |
| | | } = e.detail; |
| | | this.setData({ |
| | | provinceName, |
| | | cityName, |
| | | districtName, |
| | | townName, |
| | | provinceCode, |
| | | cityCode, |
| | | districtCode, |
| | | townCode, |
| | | locationValue, |
| | | }); |
| | | }, |
| | | initLocation(e) { |
| | | this.setLocation(e); |
| | | this.init(); |
| | | }, |
| | | // è¡æ¿åºå忢æ¶ï¼è·åæ°ç线ä¸ç管信æ¯ä»¥å线ä¸å·¡æ¥çç®¡ä¿¡æ¯ |
| | | onLocationChange(e) { |
| | | this.setLocation(e); |
| | | this.fetchSupervision(); |
| | | this.fetchInspection(); |
| | | }, |
| | | |
| | | // æ¶é´æ´æ¹ |
| | | setTimeValue(e) { |
| | | const { timeValue } = e.detail; |
| | | const p = dayjs(timeValue).format('YYYY-MM-DD HH:mm:ss'); |
| | | this.setData({ |
| | | time: p, |
| | | }); |
| | | }, |
| | | initTime(e) { |
| | | this.setTimeValue(e); |
| | | this.init(); |
| | | }, |
| | | onTimePickerConfirm(e) { |
| | | this.setTimeValue(e); |
| | | this._startLoad(); |
| | | }, |
| | | }, |
| | | }); |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <view class="home-supervision-title"> |
| | | <!-- <view> --> |
| | | <!-- <text>线ä¸ç管</text> --> |
| | | <!-- <text class="home-supervision-title__note">æ¬æææ°</text> --> |
| | | <!-- </view> --> |
| | | <!-- <view style="display: flex;align-items: center;"> --> |
| | | <t-time-picker |
| | | color="var(--td-font-white-1)" |
| | | picker-class="picker-location" |
| | | bind:timeInitValue="initTime" |
| | | bind:timePickerChange="onTimePickerConfirm" |
| | | > |
| | | </t-time-picker> |
| | | <location-picker |
| | | color="var(--td-font-white-1)" |
| | | style-mode="picker" |
| | | picker-class="picker-location" |
| | | bind:onChange="onLocationChange" |
| | | bind:locationInitValue="initLocation" |
| | | ></location-picker> |
| | | <!-- </view> --> |
| | | </view> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | .home-supervision-title { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | font-size: var(--td-font-size-m); |
| | | margin-bottom: var(--td-spacer); |
| | | font-weight: 550; |
| | | color: var(--td-text-color-anti); |
| | | } |
| | | |
| | | .picker-location { |
| | | color: var(--td-font-white-1) !important; |
| | | justify-content: flex-end !important; |
| | | width: initial !important; |
| | | max-width: 50vw; |
| | | /* background-color: lawngreen; */ |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { getClueStatistic } from '../../../model/clue/clueTask'; |
| | | |
| | | /** |
| | | * 线索任å¡ç»è®¡ç¸å
³ä¿¡æ¯è·åé»è¾ |
| | | */ |
| | | export const useStatistic = Behavior({ |
| | | data: { |
| | | clueCountRes: [], |
| | | }, |
| | | methods: { |
| | | /** |
| | | * 计ç®çº¿ç´¢å·¡æ¥å®ææ
åµ |
| | | */ |
| | | calClueCount() { |
| | | this.setData({ |
| | | clueCountRes: getClueStatistic(this.data.clueTaskList), |
| | | }); |
| | | }, |
| | | }, |
| | | }); |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <view> |
| | | |
| | | </view> |
| | | <stat-card |
| | | title="åºæ¥å·¡æ¥" |
| | | subTitle="" |
| | | stats="{{clueCountRes}}" |
| | | loading="{{pageLoading}}" |
| | | bind:cardClick="navToEnterprise" |
| | | ></stat-card> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import dayjs from 'dayjs'; |
| | | import dataResponseLevel from '../../../common/clue/dataResponseLevel'; |
| | | import dataTravelMode from '../../../common/clue/dataTravelMode'; |
| | | |
| | | /** |
| | | * 线索任å¡å表å±ç¤ºç¸å
³é»è¾ |
| | | */ |
| | | export const useTasks = Behavior({ |
| | | data: {}, |
| | | methods: { |
| | | /** |
| | | * æ ¼å¼å |
| | | */ |
| | | formatClueTask() { |
| | | const { clueTaskList } = this.data; |
| | | clueTaskList.forEach(t => { |
| | | t._taskTime = dayjs(t.taskTime).format('YYYY-MM-DD') |
| | | let note = ''; |
| | | note += t.provinceName ? t.provinceName : ''; |
| | | note += t.provinceName == t.cityName ? '' : t.cityName ? `/${t.cityName}` : ''; |
| | | note += t.districtName ? `/${t.districtName}` : ''; |
| | | note += t.townName ? `/${t.townName}` : ''; |
| | | t._location = note; |
| | | t._resLevelTxt = dataResponseLevel.toLabel2(t.responseLevel); |
| | | t._travelModeTxt = dataTravelMode.toLabel2(t.travelMode); |
| | | t._hasUavTxt = t.hasUav ? 'æ' : 'æ '; |
| | | }); |
| | | this.setData({ clueTaskList }); |
| | | }, |
| | | }, |
| | | }); |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <view> |
| | | <view wx:for="{{clueTaskList}}" wx:key="index" wx:for-index="index"> |
| | | <t-cell title="任塿¶é´" note="{{item._taskTime}}" /> |
| | | <t-cell title="ä»»å¡ä½ç½®" note="{{item._location}}"/> |
| | | <t-cell title="ååºæ¶é´" note="{{item._resLevelTxt}}"/> |
| | | <t-cell title="åºè¡æ¹å¼" note="{{item._travelModeTxt}}"/> |
| | | <t-cell title="æ 人æº" note="{{item._hasUavTxt}}"/> |
| | | |
| | | </view> |
| | | </view> |
| | |
| | | hideInputItem('æ´æ°æ¶é´', 'dlUpdateTime'), |
| | | hideInputItem('设å¤ä½ç½®', 'dlLocation', true), |
| | | hideInputItem('ç»åº¦', 'dlLongitude'), |
| | | hideInputItem('维度', 'dlLatitude', true), |
| | | hideInputItem('纬度', 'dlLatitude', true), |
| | | |
| | | baseInputItem('æ¯å¦è§è', 'dlStandard', true, 'switch'), |
| | | baseInputItem('ä¸è§èåå ', 'dlUnStandardReason'), |
| | |
| | | <view |
| | | class="patrol-record-wrap {{item.ledgerFinished ? 'patrol-finished' : 'patrol-unfinished'}}" |
| | | > |
| | | <view class="patrol-record-wrap {{item.ledgerFinished ? 'patrol-finished' : 'patrol-unfinished'}}"> |
| | | <view class="patrol-record-text-wrap"> |
| | | <view> {{indexText}} </view> |
| | | <view style="display: flex;flex-direction: column;justify-content: space-between;"> |
| | | <view style="display: flex; flex-direction: column; justify-content: space-between"> |
| | | <view class="patrol-record-text">{{item.ledgerName}}</view> |
| | | <view class="patrol-record-tag" |
| | | >{{item.updateDate ? item.updateDate : 'æªæäº¤'}}</view |
| | | > |
| | | <view class="patrol-record-tag">{{item.updateDate ? item.updateDate : 'æªæäº¤'}}</view> |
| | | </view> |
| | | </view> |
| | | <view class="patrol-record-img-wrap"> |
| | | <t-image |
| | | wx:if="{{item.path1 == null}}" |
| | | t-class="t-class-image" |
| | | src="{{null}}" |
| | | mode="aspectFill" |
| | | src="{{'/res/nodata.png'}}" |
| | | mode="aspectFit" |
| | | width="80rpx" |
| | | height="80rpx" |
| | | shape="round" |
| | | > |
| | | <text slot="error">æªæäº¤</text> |
| | | <text slot="error">æªæäº¤</text> |
| | | </t-image> |
| | | <block wx:else> |
| | | <t-image |
| | |
| | | fun['method'] = 'PUT'; |
| | | return request(fun, hostUrl); |
| | | } |
| | | |
| | | export function _delete(fun, hostUrl) { |
| | | fun['method'] = 'DELETE'; |
| | | return request(fun, hostUrl); |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | /** |
| | | * éè·¯åºæ¥çº¿ç´¢å·¡æ¥ç¸å
³æ°æ®æ¥å£ |
| | | */ |
| | | import Multipart from '../../utils/Multipart.min'; |
| | | import { get, post, _delete } from '../baseRequset'; |
| | | import { clueUrl, cluePicUrl } from '../../config/index'; |
| | | import { getClueQuestionList } from '../../model/clue/clueQuestion'; |
| | | |
| | | export default { |
| | | /******************************************************************************* */ |
| | | /** |
| | | * æ¥è¯¢çº¿ç´¢ä»»å¡ |
| | | * @param {*} clueTask |
| | | * @returns |
| | | */ |
| | | fetchClueTask(clueTask) { |
| | | return post( |
| | | { |
| | | url: `clue/task/fetch`, |
| | | data: clueTask, |
| | | }, |
| | | clueUrl, |
| | | ).then(res => { |
| | | return res.data; |
| | | }); |
| | | }, |
| | | |
| | | /******************************************************************************* */ |
| | | /** |
| | | * è·å线索ç»è®º |
| | | * @param {string} clueId 线索id |
| | | */ |
| | | getConclusion(clueId) { |
| | | return get({ |
| | | url: `clue/conclusion/fetch`, |
| | | params: { |
| | | clueId: clueId, |
| | | }, |
| | | clueUrl, |
| | | }).then(res => res.data); |
| | | }, |
| | | |
| | | /** |
| | | * æäº¤çº¿ç´¢ç»è®º |
| | | * @param {object} conclusion 线索 |
| | | * @returns |
| | | */ |
| | | uploadConclusion(conclusion) { |
| | | return post( |
| | | { |
| | | url: `clue/conclusion/upload`, |
| | | data: conclusion, |
| | | }, |
| | | clueUrl, |
| | | ).then(res => res.data); |
| | | }, |
| | | |
| | | /******************************************************************************* */ |
| | | /** |
| | | * è·åå·²æäº¤ç线索é®é¢ |
| | | * @param {string} clueId 线索id |
| | | */ |
| | | getQuestion(clueId) { |
| | | return get({ |
| | | url: `clue/question/fetch`, |
| | | params: { |
| | | clueId: clueId, |
| | | }, |
| | | clueUrl, |
| | | }).then(res => { |
| | | return getClueQuestionList(res.data); |
| | | }); |
| | | }, |
| | | |
| | | /** |
| | | * ä¸ä¼ 线索é®é¢ |
| | | * @param {object} question é®é¢æè¿° |
| | | * @param {*} files é®é¢å¾ç |
| | | * @returns |
| | | */ |
| | | uploadQuestion(question, files) { |
| | | const fields = [ |
| | | { |
| | | name: 'question', |
| | | value: JSON.stringify(question), |
| | | }, |
| | | ]; |
| | | const images = files.map(f => { |
| | | return { |
| | | name: 'images', |
| | | filePath: f, |
| | | }; |
| | | }); |
| | | |
| | | return new Multipart({ |
| | | fields, |
| | | images, |
| | | }) |
| | | .submit(clueUrl + `/clue/question/upload`) |
| | | .then(res => { |
| | | return res.data; |
| | | }); |
| | | }, |
| | | |
| | | deleteQuestion(questionId) { |
| | | return _delete({ |
| | | url: `clue/question`, |
| | | params: { |
| | | questionId: questionId, |
| | | }, |
| | | clueUrl, |
| | | }).then(res => res.data); |
| | | }, |
| | | }; |