fix: 优化批量同步操作方式;物联卡详情中新增停机状态信息
* fix: 优化批量同步操作方式;物联卡详情中新增停机状态信息 * fix: 优化docker
This commit is contained in:
parent
5c793611da
commit
2437dbb126
|
@ -140,3 +140,6 @@ export const queryRechargeList = (data: any) => server.post(`/network/card/recha
|
|||
* @param data
|
||||
*/
|
||||
export const recharge = (data: any) => server.post(`/network/card/_recharge`, data)
|
||||
export const queryCount = (data: any) => server.post(`/network/card/_count`,data)
|
||||
|
||||
export const queryDeactivate = (id: string) => server.get(`/network/card/${id}/stop/reason`)
|
||||
|
|
|
@ -111,12 +111,7 @@
|
|||
{{ descriptionsData?.parameters }}
|
||||
</j-descriptions-item>
|
||||
<j-descriptions-item label="异常信息" :span="2">
|
||||
<j-textarea
|
||||
v-model:value="descriptionsData.exception"
|
||||
placeholder="暂无数据"
|
||||
:auto-size="{ minRows: 3, maxRows: 20 }"
|
||||
readonly
|
||||
/>
|
||||
{{ descriptionsData.exception }}
|
||||
</j-descriptions-item>
|
||||
</j-descriptions>
|
||||
<template #footer>
|
||||
|
|
|
@ -92,11 +92,14 @@
|
|||
</j-tag>
|
||||
<span>{{ descriptionsData?.message }}</span>
|
||||
</div>
|
||||
<j-textarea
|
||||
v-model:value="descriptionsData.exceptionStack"
|
||||
placeholder="暂无数据"
|
||||
:auto-size="{ minRows: 24, maxRows: 28 }"
|
||||
/>
|
||||
<div class="warn-content">
|
||||
{{ descriptionsData.exceptionStack }}
|
||||
</div>
|
||||
<!-- <j-textarea-->
|
||||
<!-- v-model:value=""-->
|
||||
<!-- placeholder="暂无数据"-->
|
||||
<!-- :auto-size="{ minRows: 24, maxRows: 28 }"-->
|
||||
<!-- />-->
|
||||
<template #footer>
|
||||
<j-button type="primary" @click="handleOk">关闭</j-button>
|
||||
</template>
|
||||
|
@ -254,4 +257,9 @@ const handleSearch = (e: any) => {
|
|||
.mb-10 {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.warn-content {
|
||||
border: 1px solid #d9d9d9;
|
||||
padding: 12px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -20,8 +20,11 @@ const useMetadata = (type: 'device' | 'product', key?: MetadataType, ): {
|
|||
const { current: productCurrent } = storeToRefs(productStore)
|
||||
|
||||
const handleMetadata = (_metadataStr: string) => {
|
||||
|
||||
if(!_metadataStr) return
|
||||
|
||||
const fileTypeReg = new RegExp('"fileType":',"g")
|
||||
const _dealMetadata = _metadataStr.replaceAll(fileTypeReg,'"bodyType":')
|
||||
const _dealMetadata = _metadataStr.replace(fileTypeReg,'"bodyType":')
|
||||
const _metadata = JSON.parse(_dealMetadata || '{}')
|
||||
const newMetadata = (key ? _metadata?.[key] || [] : []) as any[]
|
||||
|
||||
|
|
|
@ -83,9 +83,18 @@
|
|||
? detail.residualFlow.toFixed(2) + ' M'
|
||||
: ''
|
||||
}}</j-descriptions-item>
|
||||
<j-descriptions-item label="状态">{{
|
||||
<j-descriptions-item label="状态">
|
||||
{{
|
||||
detail?.cardState?.text
|
||||
}}</j-descriptions-item>
|
||||
}}
|
||||
<span v-if="deactivateData.show" style="padding-left: 8px;">
|
||||
<a-tooltip
|
||||
:title="deactivateData.tip"
|
||||
>
|
||||
<AIcon type="ExclamationCircleOutlined" style="color: var(--ant-error-color);"/>
|
||||
</a-tooltip>
|
||||
</span>
|
||||
</j-descriptions-item>
|
||||
<j-descriptions-item label="说明">{{
|
||||
detail?.describe
|
||||
}}</j-descriptions-item>
|
||||
|
@ -178,10 +187,10 @@
|
|||
</page-container>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
<script setup lang="ts" name="CardDetail">
|
||||
import moment from 'moment';
|
||||
import type { CardManagement } from '../typing';
|
||||
import { queryDetail } from '@/api/iot-card/cardManagement';
|
||||
import {queryDeactivate, queryDetail} from '@/api/iot-card/cardManagement';
|
||||
import Save from '../Save.vue';
|
||||
import Guide from '@/views/iot-card/components/Guide.vue';
|
||||
import LineChart from '@/views/iot-card/components/LineChart.vue';
|
||||
|
@ -203,6 +212,11 @@ const dayOptions = ref<any[]>([]);
|
|||
const monthOptions = ref<any[]>([]);
|
||||
const yearOptions = ref<any[]>([]);
|
||||
|
||||
const deactivateData = reactive({
|
||||
show: false,
|
||||
tip: ''
|
||||
})
|
||||
|
||||
const quickBtnList = [
|
||||
{ label: '昨日', value: 'yesterday' },
|
||||
{ label: '近一周', value: 'week' },
|
||||
|
@ -212,8 +226,18 @@ const quickBtnList = [
|
|||
|
||||
const getDetail = () => {
|
||||
queryDetail(route.params.id).then((resp: any) => {
|
||||
if (resp.status === 200) {
|
||||
if (resp.success) {
|
||||
detail.value = resp.result;
|
||||
|
||||
if (resp.result.cardStateType?.value === 'deactivate') {
|
||||
deactivateData.show = true
|
||||
// 获取停机原因
|
||||
queryDeactivate(route.params.id as string).then((deacResp: any) => {
|
||||
if (deacResp.success && deacResp.result?.message) {
|
||||
deactivateData.tip = deacResp.result.message.toString()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
<template>
|
||||
<j-modal
|
||||
visible
|
||||
width="800px"
|
||||
:maskClosable="false"
|
||||
title="同步"
|
||||
:closable="false"
|
||||
>
|
||||
<div style="margin: 10px 0px 20px 0px; padding-right: 10px;">
|
||||
<div v-if="flag">
|
||||
<div>正在同步物联卡状态</div>
|
||||
<j-progress :percent="_percent" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<p>同步成功:{{ syncData.count }}条</p>
|
||||
<p>同步失败:{{ syncData.error }}条</p>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<a-button v-if="!flag" type="primary" @click="handleCancel">完成</a-button>
|
||||
</template>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
<script setup name="SyncModal">
|
||||
import {BASE_API_PATH} from "@/utils/variable";
|
||||
import {paramsEncodeQuery} from "@/utils/encodeQuery";
|
||||
import {getToken} from "@/utils/comm";
|
||||
import { EventSourcePolyfill } from 'event-source-polyfill';
|
||||
import {queryCount} from "@/api/iot-card/cardManagement";
|
||||
|
||||
const emit = defineEmits(['close']);
|
||||
|
||||
const props = defineProps({
|
||||
params: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
|
||||
const flag = ref(true)
|
||||
const syncData = reactive({
|
||||
count: 0,
|
||||
total: 0,
|
||||
error: 0
|
||||
})
|
||||
|
||||
const _percent = computed(() => {
|
||||
return syncData.total ? ((syncData.error + syncData.count) / syncData.total * 100).toFixed(2) : 0
|
||||
})
|
||||
|
||||
const handleCancel = () => {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
const getData = () => {
|
||||
const _params = paramsEncodeQuery(props.params)
|
||||
const urlParams = new URLSearchParams()
|
||||
|
||||
Object.keys(_params).forEach(key => {
|
||||
if (_params[key]) {
|
||||
urlParams.append(key, _params[key])
|
||||
}
|
||||
})
|
||||
const api = `${BASE_API_PATH}/network/card/state/_sync?:X_Access_Token=${getToken()}&${urlParams}`
|
||||
const esp = new EventSourcePolyfill(api)
|
||||
|
||||
esp.onmessage = (e) => {
|
||||
syncData.count += Number(e.data)
|
||||
if (syncData.count >= syncData.total) {
|
||||
esp.close()
|
||||
flag.value = false
|
||||
}
|
||||
}
|
||||
|
||||
esp.onerror = (e) => {
|
||||
esp.close()
|
||||
flag.value = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const getTotal = () => {
|
||||
queryCount(props.params).then(res => {
|
||||
if (res.success) {
|
||||
syncData.total = res.result
|
||||
getData()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
getTotal()
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -370,6 +370,12 @@
|
|||
:data="current"
|
||||
@change="saveChange"
|
||||
/>
|
||||
<!-- 批量同步 -->
|
||||
<SyncModal
|
||||
v-if="syncVisible"
|
||||
:params="params"
|
||||
@close="syncClose"
|
||||
/>
|
||||
</page-container>
|
||||
</template>
|
||||
|
||||
|
@ -403,6 +409,7 @@ import { BatchActionsType } from '@/components/BatchDropdown/types';
|
|||
import { usePermissionStore } from 'store/permission';
|
||||
import { useRouterParams } from '@/utils/hooks/useParams';
|
||||
import { OperatorMap } from '@/views/iot-card/data';
|
||||
import SyncModal from './Sync.vue'
|
||||
|
||||
const router = useRouter();
|
||||
const menuStory = useMenuStore();
|
||||
|
@ -418,6 +425,7 @@ const cardId = ref<any>();
|
|||
const current = ref<Partial<CardManagement>>({});
|
||||
const saveType = ref<string>('');
|
||||
const isCheck = ref<boolean>(false);
|
||||
const syncVisible = ref(false)
|
||||
|
||||
const columns = [
|
||||
{
|
||||
|
@ -901,19 +909,28 @@ const handleResumption = () => {
|
|||
* 同步状态
|
||||
*/
|
||||
const handleSync = async() => {
|
||||
if (!_selectedRowKeys.value.length) {
|
||||
onlyMessage('请选择数据', 'error');
|
||||
return;
|
||||
}
|
||||
const resp = await sync(
|
||||
_selectedRowKeys.value.map((v) => ({ id: v })),
|
||||
);
|
||||
syncVisible.value = true
|
||||
// if (!_selectedRowKeys.value.length) {
|
||||
// onlyMessage('请选择数据', 'error');
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (resp.status === 200) {
|
||||
_selectedRowKeys.value = [];
|
||||
cardManageRef.value?.reload();
|
||||
onlyMessage('同步状态成功');
|
||||
}
|
||||
// const api = `${BASE_API_PATH}/network/card/state/_sync`
|
||||
// const _source = new EventSourcePolyfill(api)
|
||||
//
|
||||
// _source.onmessage = (e: any) => {
|
||||
// console.log(e)
|
||||
// }
|
||||
//
|
||||
// const resp = await sync(
|
||||
// _selectedRowKeys.value.map((v) => ({ id: v })),
|
||||
// );
|
||||
//
|
||||
// if (resp.status === 200) {
|
||||
// _selectedRowKeys.value = [];
|
||||
// cardManageRef.value?.reload();
|
||||
// onlyMessage('同步状态成功');
|
||||
// }
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -998,12 +1015,7 @@ const batchActions: BatchActionsType[] = [
|
|||
type: 'primary',
|
||||
permission: 'iot-card/CardManagement:sync',
|
||||
icon: 'SwapOutlined',
|
||||
selected:{
|
||||
popConfirm: {
|
||||
title: '确认同步状态吗?',
|
||||
onConfirm: handleSync,
|
||||
},
|
||||
},
|
||||
onClick: handleSync
|
||||
},
|
||||
{
|
||||
key: 'delete',
|
||||
|
@ -1020,6 +1032,11 @@ const batchActions: BatchActionsType[] = [
|
|||
},
|
||||
];
|
||||
|
||||
const syncClose = () => {
|
||||
syncVisible.value = false
|
||||
cardManageRef.value?.reload();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (routerParams.params.value.type === 'add' && paltformPermission) {
|
||||
handleAdd();
|
||||
|
|
|
@ -185,7 +185,7 @@ const detail = async (id: string) => {
|
|||
cert: result.configs?.cert ? result.configs?.cert : result.configs?.trust
|
||||
},
|
||||
mode: result.mode.value,
|
||||
authenticationMethod: result.authenticationMethod.value,
|
||||
authenticationMethod: result.authenticationMethod?.value,
|
||||
type,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -96,9 +96,14 @@ const init = new Array(50).fill(0).map((_, index) => {
|
|||
|
||||
const dataSource = ref<Item[]>(init);
|
||||
const loading = ref(false);
|
||||
const route = useRoute()
|
||||
|
||||
const handleSearch = async (id: string, arr: Item[]) => {
|
||||
const resp = await channelApi.opFunction(id, 'QueryPreset');
|
||||
const params: Record<string, string> = {}
|
||||
if (route.query.type === 'gb28181-2016') {
|
||||
params.channel = props.data.channelId
|
||||
}
|
||||
const resp = await channelApi.opFunction(id, 'QueryPreset', params);
|
||||
if (resp.status === 200) {
|
||||
dataSource.value = unionBy([ ...arr, ...init], 'id').map((item) => {
|
||||
const _item = (resp.result?.[0] || []).find(
|
||||
|
|
|
@ -96,11 +96,12 @@ export default defineConfig(({ mode}) => {
|
|||
// target: 'http://192.168.32.244:8881',
|
||||
// target: 'http://192.168.32.163:8844', //张本地
|
||||
// target: 'http://120.77.179.54:8844', // 120测试
|
||||
target: 'http://192.168.33.46:8844', // 本地开发环境
|
||||
target: 'http://192.168.32.66:8800', // 本地开发环境
|
||||
// target: 'http://192.168.32.167:8844', // 本地开发环境1
|
||||
// target: 'http://192.168.33.1:8848', // 社区版开发环境
|
||||
// target: 'http://192.168.32.207:8844', // 刘本地
|
||||
// target: 'http://192.168.32.187:8844', // 谭本地
|
||||
// target: 'http://192.168.33.66:8844', // 苟本地
|
||||
ws: 'ws://192.168.33.46:8844',
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, '')
|
||||
|
|
Loading…
Reference in New Issue