Commit 3498feca authored by 郭铭瑶's avatar 郭铭瑶 🤘

10/20添加语音输入等暂存

parent 9a1dc521
This diff is collapsed.
......@@ -20,6 +20,7 @@
"animate.css": "^4.1.1",
"axios": "^0.21.1",
"countup.js": "^2.0.8",
"crypto-js": "^4.1.1",
"dayjs": "^1.10.6",
"docx": "^6.0.3",
"echarts": "^5.1.2",
......
;(function () {
const self = this
self.onmessage = function (e) {
transAudioData.transcode(e.data)
}
const transAudioData = {
transcode(audioData) {
let output = transAudioData.to16kHz(audioData)
output = transAudioData.to16BitPCM(output)
output = Array.from(new Uint8Array(output.buffer))
self.postMessage(output)
// return output
},
to16kHz(audioData) {
const data = new Float32Array(audioData)
const fitCount = Math.round(data.length * (16000 / 44100))
const newData = new Float32Array(fitCount)
const springFactor = (data.length - 1) / (fitCount - 1)
newData[0] = data[0]
for (let i = 1; i < fitCount - 1; i++) {
const tmp = i * springFactor
const before = Math.floor(tmp).toFixed()
const after = Math.ceil(tmp).toFixed()
const atPoint = tmp - before
newData[i] = data[before] + (data[after] - data[before]) * atPoint
}
newData[fitCount - 1] = data[data.length - 1]
return newData
},
to16BitPCM(input) {
const dataLength = input.length * (16 / 8)
const dataBuffer = new ArrayBuffer(dataLength)
const dataView = new DataView(dataBuffer)
let offset = 0
for (let i = 0; i < input.length; i++, offset += 2) {
const s = Math.max(-1, Math.min(1, input[i]))
dataView.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true)
}
return dataView
},
}
})()
......@@ -5,6 +5,7 @@ let MAP_CONFIG: { jsApiUrl: string; cssUrl: string } = {
jsApiUrl: '',
cssUrl: '',
}
let MAP_URL: string = ''
let TOKEN: string = ''
const mdtUser = getCookie('__DM_MDT_USER__')
......@@ -21,14 +22,16 @@ switch (process.env.NODE_ENV) {
cssUrl:
'https://hm.metrodata.cn/cehuiyuan/api418/arcgis_js_api/library/4.18/esri/css/main.css',
}
MAP_URL = 'https://hm.metrodata.cn/cehuiyuan'
break
case 'sit': // 测试环境(暂时部署在测绘院用)
BASE_URL = 'https://survey.maicedata.com/api/data/'
BASE_URL = 'https://www.maicedata.com/collector/data/'
TOKEN = '8d979525-f8ab-4c62-9d6b-a6eeb62c7455'
MAP_CONFIG = {
jsApiUrl: 'http://10.108.3.41/arcgis_js_api/library/4.18/init.js',
cssUrl: 'http://10.108.3.41/arcgis_js_api/library/4.18/esri/css/main.css',
}
MAP_URL = 'http://10.108.3.48'
break
default:
// 本地开发环境
......@@ -38,6 +41,7 @@ switch (process.env.NODE_ENV) {
jsApiUrl: 'http://10.108.3.41/arcgis_js_api/library/4.18/init.js',
cssUrl: 'http://10.108.3.41/arcgis_js_api/library/4.18/esri/css/main.css',
}
MAP_URL = 'http://10.108.3.48'
}
export default {
TOKEN,
......@@ -46,6 +50,7 @@ export default {
imperMdtUser,
BASE_URL,
MAP_CONFIG,
MAP_URL,
ORGANIZATION: '733d0ac0-f67e-4bde-8872-3ca00983f18c',
MEMBER: '6c18d1b6-406e-4961-965c-c4b9cfc14cc4',
ACTIVITY: 'e6659af9-d53c-4b3f-9719-465d02687933',
......
......@@ -11,7 +11,12 @@ import {
import { api } from '@/ajax'
import store from '@/store'
export default async function useInitMap(el: HTMLElement, camera: any) {
export default async function useInitMap(
el: HTMLElement,
camera: any,
showArea: any,
showBuilding: any,
) {
const config = api.MAP_CONFIG
let map: any = null
let sceneView: any = null
......@@ -139,7 +144,7 @@ export default async function useInitMap(el: HTMLElement, camera: any) {
])
const baseLayer = new TileLayer(
'https://hm.metrodata.cn/cehuiyuan/changsanjiao/rest/services/Hosted/Base_Map/MapServer',
api.MAP_URL + '/changsanjiao/rest/services/Hosted/Base_Map/MapServer',
{
id: 'zhengwuBasemap',
visible: true,
......@@ -149,7 +154,7 @@ export default async function useInitMap(el: HTMLElement, camera: any) {
)
const sjgyLayer = new TileLayer(
'https://hm.metrodata.cn/cehuiyuan/changsanjiao/rest/services/sjgy_3857/MapServer',
api.MAP_URL + '/changsanjiao/rest/services/sjgy_3857/MapServer',
{
id: 'sjgy',
visible: true,
......@@ -169,7 +174,9 @@ export default async function useInitMap(el: HTMLElement, camera: any) {
map.layers.add(baseMapGroupLayer)
const sceneLayer0 = new SceneLayer({
url: 'https://hm.metrodata.cn/cehuiyuan/changsanjiao/rest/services/Hosted/HM_BUILDING0826/SceneServer',
url:
api.MAP_URL +
'/changsanjiao/rest/services/Hosted/HM_BUILDING0826/SceneServer',
visible: true,
title: '精模',
id: 'jingmo',
......@@ -186,7 +193,9 @@ export default async function useInitMap(el: HTMLElement, camera: any) {
map.add(graphiclayer)
const sceneLayer3 = new SceneLayer({
url: 'https://hm.metrodata.cn/cehuiyuan/changsanjiao/rest/services/Hosted/HM_ROAD0730/SceneServer',
url:
api.MAP_URL +
'/changsanjiao/rest/services/Hosted/HM_ROAD0730/SceneServer',
visible: true,
title: '全息道路路面',
elevationInfo: {
......@@ -196,7 +205,9 @@ export default async function useInitMap(el: HTMLElement, camera: any) {
})
const sceneLayer4 = new SceneLayer({
url: 'https://hm.metrodata.cn/cehuiyuan/changsanjiao/rest/services/Hosted/HM_BUJIAN0730/SceneServer',
url:
api.MAP_URL +
'/changsanjiao/rest/services/Hosted/HM_BUJIAN0730/SceneServer',
visible: true,
title: '全息道路部件',
elevationInfo: {
......@@ -207,7 +218,9 @@ export default async function useInitMap(el: HTMLElement, camera: any) {
})
const sceneLayer7 = new SceneLayer({
url: 'https://hm.metrodata.cn/cehuiyuan/changsanjiao/rest/services/Hosted/HM_WHITEMODEL_OUTSIDE0320/SceneServer',
url:
api.MAP_URL +
'/changsanjiao/rest/services/Hosted/HM_WHITEMODEL_OUTSIDE0320/SceneServer',
visible: true,
title: '周边白模',
popupEnabled: false,
......@@ -251,10 +264,7 @@ export default async function useInitMap(el: HTMLElement, camera: any) {
window.modelHighlight = null
})
return [map, sceneView, graphiclayer]
}
function addEventListener() {
function addEventListener() {
window.sceneView.on('click', function (event) {
window.sceneView.popup.close()
if (window.modelHighlight) {
......@@ -285,6 +295,20 @@ function addEventListener() {
html = transMemberHtml(data)
} else if (data?.['党组织名称']) {
html = transOrgHtml(data)
if (data?.['类别']?.includes('居民区')) {
const areas =
data?.['管辖范围']?.map(
(item: any) => item?.['范围名称'],
) || []
areas.forEach((area) => showArea(area))
// TODO 待测试
} else if (data?.['类别']?.includes('两新')) {
const buildings =
data?.['管辖楼宇']?.map((item: any) => item?.OBJECTID) ||
[]
buildings.forEach((building) => showBuilding(building))
// TODO 待测试
}
} else if (data?.isList) {
html = transListHtml(data)
} else if (data?.NAME || data?.OBJECTID) {
......@@ -300,32 +324,6 @@ function addEventListener() {
if (!html) return
// switch (layername) {
// //可根据图层名称对应不同操作,构造对应的信息面板内容
// case 'jingmo':
// const buildingName = result.features[0].attributes.NAME
// //根据buildingName查询接口,获取信息
// //组装html中的内容
// html = '<div>根据接口获取信息,构造弹出内容' + '</div>'
// title = '获取到的楼名'
// break
// case '党组织撒点图层':
// console.log('click-data: ', result)
// const poiName = result.features[0].attributes['党组织名称']
// //根据poiName查询接口,获取信息
// //组装html中的内容
// html =
// '<div class="pop-container">根据接口获取信息,构造弹出内容' +
// '</div>'
// title = '获取到的poi名称'
// break
// default:
// break
// }
const contentParam = {
dockpoint: response.ground.mapPoint,
title: title,
......@@ -348,7 +346,11 @@ function addEventListener() {
}
})
})
}
return [map, sceneView, graphiclayer]
}
function togglePopupTemplate(trueOrFalse: boolean) {
if (trueOrFalse === true) {
window.sceneView.popup.autoOpenEnabled = true
......
import IatRecorder from '@/util/iat-recorder'
import { onBeforeUnmount, ref } from 'vue'
type Status = 'init' | 'ing' | 'end'
export default function useVoiceRecorder() {
const iatRecorder: any = new IatRecorder()
const result = ref('')
const status = ref<Status>('init')
const timer: any = null
iatRecorder.onTextChange = function (txt: string) {
result.value = txt
}
iatRecorder.onWillStatusChange = function (_, curStatus: Status) {
status.value = curStatus
// let seconds = 0
// if (curStatus === 'ing') {
// timer = setInterval(() => {
// seconds += 1
// if (seconds >= 60) {
// iatRecorder.stop()
// clearInterval(timer)
// }
// }, 1000)
// }
}
onBeforeUnmount(() => {
iatRecorder.stop()
timer && clearInterval(timer)
})
function toggleRecorder() {
if (iatRecorder.status === 'ing') {
iatRecorder.stop()
} else {
iatRecorder.start()
}
}
function reset() {
iatRecorder.stop()
iatRecorder.status === 'init'
status.value = 'init'
result.value = ''
}
return { result, toggleRecorder, status, reset }
}
......@@ -51,7 +51,7 @@ export default {
primitive: 'circle',
},
material: {
color: '#dd505e',
color: layerName === '蓝点' ? '#4285F4' : '#dd505e',
},
size: 8,
outline: {
......@@ -90,7 +90,7 @@ export default {
// weight: "bold"
},
haloSize: 2,
haloColor: '#dd505e',
haloColor: layerName === '蓝点' ? '#4285F4' : '#dd505e',
},
labelPlacement: 'above-center',
})
......
This diff is collapsed.
......@@ -9,6 +9,7 @@ import useJsApi from '@/hooks/useJsApi'
import clientLayersOperate from '@/util/clientLayersOperate'
import sceneViewPopup from '@/util/sceneViewPopup'
import axios from 'axios'
import { api } from '@/ajax'
const mapRef = ref<HTMLElement | undefined>()
const camera = {
......@@ -24,7 +25,7 @@ onMounted(async () => {
await nextTick()
if (mapRef.value) {
// eslint-disable-next-line
await useInitMap(mapRef.value, camera)
await useInitMap(mapRef.value, camera, showArea, showBuilding)
}
})
......@@ -132,7 +133,7 @@ async function queryBound(layerId: number, name: string) {
'esri/layers/GraphicsLayer',
])
const jdLayerUrl = `https://hm.metrodata.cn/cehuiyuan/changsanjiao/rest/services/HM_BOUND_3857/MapServer/${layerId}`
const jdLayerUrl = `${api.MAP_URL}/changsanjiao/rest/services/HM_BOUND_3857/MapServer/${layerId}`
const queryTask = new QueryTask({
url: jdLayerUrl,
})
......@@ -187,7 +188,7 @@ function showBuilding(name: string) {
const objectId =
(
await axios.get(
`https://hm.metrodata.cn/cehuiyuan/changsanjiao/rest/services/HM_BOUND_3857/MapServer/4/query?where=NAME=%27${name}%27&f=json&outFields=*`,
`${api.MAP_URL}/changsanjiao/rest/services/HM_BOUND_3857/MapServer/4/query?where=NAME=%27${name}%27&f=json&outFields=*`,
)
)?.data?.features?.[0]?.attributes?.id || null
if (!objectId) return
......
......@@ -225,7 +225,7 @@
>
<n-grid :cols="24" :x-gap="12">
<n-form-item-gi
:span="24"
:span="14"
:label="`活动内容描述或描述照片${
mode === 'view' ? '' : '(大小20M以内)'
}`"
......@@ -243,6 +243,19 @@
placeholder="请选择上传类型"
/>
</n-form-item-gi>
<n-form-item-gi
v-if="detailData.describeType === 'text' && mode !== 'view'"
:span="6"
>
<n-button
:type="status === 'ing' ? 'primary' : 'default'"
size="small"
:class="{ recording: status === 'ing' }"
@click="toggleRecorder"
>
{{ status === 'ing' ? '停止输入' : '语音输入' }}
</n-button>
</n-form-item-gi>
<n-form-item-gi
v-if="detailData.describeType === 'text' && mode !== 'view'"
:span="24"
......@@ -316,7 +329,7 @@
<script lang="ts" setup>
import store from '@/store'
import { computed, onMounted, PropType, ref, watch } from 'vue'
import { computed, PropType, ref, watch } from 'vue'
import { FormRules, NForm, useMessage } from 'naive-ui'
import exportIcon from '@images/export.svg'
import { activity } from '@/util/tags'
......@@ -324,7 +337,20 @@ import { useFetchOrg, usePostActivity, usePutActivity } from '@/hooks/useFetch'
import dayjs from '@/util/dayjs'
import useAliOss from '@/hooks/useAliOss'
import useExportDocx from '@/hooks/useExportDocx'
import useVoiceRecorder from '@/hooks/useVoiceRecorder'
const { result, toggleRecorder, status } = useVoiceRecorder()
watch(
() => result.value,
(txt) => {
console.log('txt', txt)
if (!detailData.value.attachment) {
detailData.value.attachment = txt
} else {
detailData.value.attachment += txt
}
},
)
const message = useMessage()
const props = defineProps({
data: {
......@@ -891,6 +917,16 @@ const handleExport = async () => {
font-size .1rem
>span
color $blue
.recording
animation shine .8s ease-in-out infinite alternate
@keyframes shine {
from {
box-shadow 0 0 .01rem 0 $red
}
to {
box-shadow 0 0 .06rem 0.01rem $red
}
}
</style>
<style lang="stylus">
@import '../../components/MyComponent/main.styl'
......
......@@ -35,6 +35,7 @@ const resetMap = () => {
store.commit('SET_MAP_POINTS')
}
const setBoundary = ({ type, name }: { type: string; name: string }) => {
console.log(type, name)
if (!map.value) return
switch (type) {
case 'building':
......@@ -104,7 +105,18 @@ watch(
const data = checkSamePositionPoints(
points.map((point) => JSON.parse(JSON.stringify(point))) || [],
)
map.value.addPoints('撒点', data)
console.log('--', data)
const redPoints: any[] = []
const bluePoints: any[] = []
data.forEach((item) => {
if (item['类别中类'] && item['类别中类'] === '联合支部') {
bluePoints.push(item)
} else {
redPoints.push(item)
}
})
redPoints.length > 0 && map.value.addPoints('红点', redPoints)
bluePoints.length > 0 && map.value.addPoints('蓝点', bluePoints)
},
)
</script>
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment