diff --git a/.npmrc b/.npmrc
index dfe2ca70..f408e702 100644
--- a/.npmrc
+++ b/.npmrc
@@ -1,2 +1,2 @@
always-auth=true
-registry=http://registry.jetlinks.cn/
\ No newline at end of file
+registry=https://registry.npmjs.org/
diff --git a/README.md b/README.md
index d9709551..ee607b6f 100644
--- a/README.md
+++ b/README.md
@@ -48,6 +48,18 @@ yarn dev:force
此处可以更改系统名称、主题色、系统logo、浏览器页签等
+#### 主题色
+
+```javascript
+// src/App.vue
+
+ConfigProvider.config({
+ theme: {
+ primaryColor: "#315efb"
+ }
+})
+```
+
#### 2.默认配置
在代码根目录找到`config\config.ts`文件
diff --git a/package.json b/package.json
index 85968eac..6976a7c2 100644
--- a/package.json
+++ b/package.json
@@ -25,7 +25,7 @@
"event-source-polyfill": "^1.0.31",
"global": "^4.4.0",
"jetlinks-store": "^0.0.3",
- "jetlinks-ui-components": "^1.0.33",
+ "jetlinks-ui-components": "^1.0.34-4",
"js-cookie": "^3.0.1",
"jsencrypt": "^3.3.2",
"less": "^4.1.3",
diff --git a/src/App.vue b/src/App.vue
index 8c6581c2..0c14af16 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -15,7 +15,11 @@ const system = useSystem();
const {configInfo} = storeToRefs(system);
system.setDocumentTitle()
-
+ConfigProvider.config({
+ theme: {
+ primaryColor: "#315efb"
+ }
+})
\ No newline at end of file
+
diff --git a/src/hook/index.ts b/src/hook/index.ts
new file mode 100644
index 00000000..f222b03e
--- /dev/null
+++ b/src/hook/index.ts
@@ -0,0 +1 @@
+export * from './useRequest'
diff --git a/src/hook/useRequest.ts b/src/hook/useRequest.ts
new file mode 100644
index 00000000..6d2d9c03
--- /dev/null
+++ b/src/hook/useRequest.ts
@@ -0,0 +1,92 @@
+import {onUnmounted, ref} from 'vue'
+import type { Ref } from 'vue'
+import {isFunction, get, isArray} from 'lodash-es'
+import type { AxiosResponseRewrite } from '@/utils/request'
+
+interface RequestOptions {
+ immediate: boolean
+ /**
+ * 成功回调
+ * @param data
+ * @returns
+ */
+ onSuccess: (data: AxiosResponseRewrite) => S | void
+ /**
+ * 返回参数处理
+ * @returns
+ */
+ formatName: string | [string]
+ onError: (e: any) => void
+
+ defaultParams: S | any | any[]
+
+ handleResponse: (data: any) => any
+}
+
+const defaultOptions: any = {
+ immediate: true,
+ formatName: 'result'
+}
+
+type Run = (...args: any[]) => void
+
+export const useRequest = (
+ request: (...args: any[]) => Promise>,
+ options: Partial> = defaultOptions,
+): {
+ data: Ref,
+ loading: Ref,
+ run: Run
+} => {
+ const data = ref()
+ const loading = ref(false)
+ const _options = {
+ ...defaultOptions,
+ ...options
+ }
+
+ async function run(...arg: any[]) {
+ if (request && isFunction(request)) {
+ loading.value = true
+ try {
+ // @ts-ignore
+ const resp = await request.apply(this, arg)
+
+ loading.value = false
+
+ if (resp?.success) {
+ const successData = await _options.onSuccess?.(resp)
+ data.value = successData || get(resp, _options.formatName!)
+ // console.log(data.value)
+ } else {
+ _options.onError?.(resp)
+ }
+ } catch (e) {
+ loading.value = false
+ _options.onError?.(e)
+ }
+ }
+ }
+
+ if (_options.immediate) { // 主动触发
+ if (_options.defaultParams) {
+ isArray(_options.defaultParams) ? run(..._options.defaultParams) : run(_options.defaultParams)
+ } else {
+ run()
+ }
+ }
+
+ onUnmounted(() => {
+ // 销毁时,撤销该请求
+ if (request && isFunction(request)) {
+
+ }
+ // request()
+ })
+
+ return {
+ data,
+ loading,
+ run
+ }
+}
diff --git a/src/main.ts b/src/main.ts
index 4cc48040..4f371d2c 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -4,7 +4,7 @@ import store from './store'
import components from './components'
import router from './router'
import './style.less'
-
+import 'ant-design-vue/dist/antd.variable.min.css'
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
dayjs.locale('zh-cn');
diff --git a/src/store/menu.ts b/src/store/menu.ts
index ab33fa91..846f4695 100644
--- a/src/store/menu.ts
+++ b/src/store/menu.ts
@@ -24,12 +24,12 @@ const defaultOwnParams = [
termType: 'eq',
value: 'iot'
},
- {
- column: 'owner',
- termType: 'isnull',
- value: '1',
- type: 'or'
- }
+ // {
+ // column: 'owner',
+ // termType: 'isnull',
+ // value: '1',
+ // type: 'or'
+ // }
]
}
]
@@ -129,4 +129,4 @@ export const useMenuStore = defineStore({
})
}
}
-})
\ No newline at end of file
+})
diff --git a/src/store/system.ts b/src/store/system.ts
index 97186d67..204a4298 100644
--- a/src/store/system.ts
+++ b/src/store/system.ts
@@ -89,4 +89,4 @@ export const useSystem = defineStore('system', {
}
}
}
-})
\ No newline at end of file
+})
diff --git a/src/style.less b/src/style.less
index b119250d..bfd73195 100644
--- a/src/style.less
+++ b/src/style.less
@@ -30,9 +30,9 @@ body {
.ant-pro-top-nav-header {
.ant-menu-item {
- padding: 0 10px !important;
- &:not(:first-child) {
- margin-left: 8px !important;
+ padding: 0 14px !important;
+ &:first-child {
+ padding: 0 10px !important;
}
}
}
diff --git a/src/utils/menu.ts b/src/utils/menu.ts
index 53e4ebe4..1d11aabd 100644
--- a/src/utils/menu.ts
+++ b/src/utils/menu.ts
@@ -1,6 +1,7 @@
import { BlankLayoutPage, BasicLayoutPage } from 'components/Layout'
import { isNoCommunity } from '@/utils/utils'
import Iframe from '../views/iframe/index.vue'
+import { shallowRef, defineAsyncComponent } from 'vue'
const pagesComponent = import.meta.glob('../views/**/*.vue');
@@ -155,192 +156,6 @@ const extraRouteObj = {
}
};
-//
-// const resolveComponent = (name: any) => {
-// const importPage = pagesComponent[`../views/${name}/index.vue`];
-// console.log(importPage)
-// if (!importPage) {
-// return undefined
-// } else {
-// const res = () => importPage()
-// return res
-// }
-// //@ts-ignore
-// }
-//
-// const findChildrenRoute = (code: string, url: string, routes: any[] = []): MenuItem[] => {
-// if (extraRouteObj[code]) {
-// const extraRoutes = extraRouteObj[code].children.map((route: MenuItem) => {
-// return {
-// url: `${url}/${route.code}`,
-// code: `${code}/${route.code}`,
-// name: route.name,
-// isShow: false
-// }
-// })
-// return [...routes, ...extraRoutes]
-// }
-// return routes
-// }
-//
-// const findDetailRouteItem = (code: string, url: string): Partial
@@ -395,6 +395,7 @@ const setDevMesChartOption = (
y: Array,
maxY: number,
): void => {
+ const yLen = String(Math.ceil(maxY)).length
devMegOptions.value = {
xAxis: {
type: 'category',
@@ -412,7 +413,7 @@ const setDevMesChartOption = (
grid: {
top: '2%',
bottom: '5%',
- left: maxY > 100000 ? '50px' : '70px',
+ left: maxY < 900000 ? '60px' : (yLen * 7.5 + Math.floor(yLen/3) * 1.2 + 10) + 'px',
right: '50px',
},
series: [
@@ -596,8 +597,9 @@ const getEcharts = (data: any) => {
const y = res.result.map((item: any) => item.data.value).reverse();
const maxY = Math.max.apply(
null,
- messageChartYData.value.length ? messageChartYData.value : [0],
+ y.length ? y : [0],
);
+
setDevMesChartOption(x, y, maxY);
}
});
@@ -623,4 +625,4 @@ getDevice();
height: 500px;
width: 100%;
}
-
\ No newline at end of file
+
diff --git a/src/views/device/Instance/Detail/ChildDevice/index.vue b/src/views/device/Instance/Detail/ChildDevice/index.vue
index 6ebb1c19..ae3a834b 100644
--- a/src/views/device/Instance/Detail/ChildDevice/index.vue
+++ b/src/views/device/Instance/Detail/ChildDevice/index.vue
@@ -1,106 +1,60 @@
-
+
-
+
-
+
- 新增并绑定
-
- 绑定
- 批量解除
+ 新增并绑定
+
+ 绑定
+ 批量解除
{{
slotProps.registryTime
- ? moment(slotProps.registryTime).format(
- 'YYYY-MM-DD HH:mm:ss',
- )
- : ''
+ ? moment(slotProps.registryTime).format(
+ 'YYYY-MM-DD HH:mm:ss',
+ )
+ : ''
}}
-
+
-
-
+
-
+ }" @click="i.onClick" type="link" style="padding: 0px"
+ :hasPermission="'device/Instance:' + i.key">
+
+
+
@@ -113,7 +67,7 @@
diff --git a/src/views/device/Instance/Detail/Diagnose/Status/index.tsx b/src/views/device/Instance/Detail/Diagnose/Status/index.tsx
index 48d6fcb7..0e0a4ba4 100644
--- a/src/views/device/Instance/Detail/Diagnose/Status/index.tsx
+++ b/src/views/device/Instance/Detail/Diagnose/Status/index.tsx
@@ -1380,7 +1380,7 @@ const Status = defineComponent({
>
设备接入配置
- 中${urlMap.get(unref(device)?.accessProvider) || ''}信息,任意上报一条数据
+ 中{urlMap.get(unref(device)?.accessProvider) || ''}信息,任意上报一条数据
}
/>,
@@ -1391,8 +1391,8 @@ const Status = defineComponent({
status="default"
text={
- 请联系管理员提供${urlMap.get(unref(device)?.accessProvider) || ''}
- 信息,并根据URL信息任意上报一条数据
+ 请联系管理员提供{urlMap.get(unref(device)?.accessProvider) || ''}
+ 信息,并根据URL信息任意上报一条数据
}
/>,
diff --git a/src/views/device/Instance/Detail/Function/components/Simple.vue b/src/views/device/Instance/Detail/Function/components/Simple.vue
index 7d659d77..e7c8eb57 100644
--- a/src/views/device/Instance/Detail/Function/components/Simple.vue
+++ b/src/views/device/Instance/Detail/Function/components/Simple.vue
@@ -177,7 +177,7 @@ const newFunctions = computed(() => {
required: tableItem.expands?.required
});
}
-
+
result.push({
...func,
table: array,
@@ -197,7 +197,7 @@ const handleExecute = async (func: any) => {
.then(async () => {
const obj = {};
func.table.forEach((item: any) => {
- if (item.type === 'object') {
+ if (item.type === 'object' && item.value) {
obj[item.id] = JSON.parse(item.value);
} else {
obj[item.id] = item.value;
diff --git a/src/views/device/Instance/Detail/Running/Property/Detail/Charts.vue b/src/views/device/Instance/Detail/Running/Property/Detail/Charts.vue
index 43c87fb6..9bda45a6 100644
--- a/src/views/device/Instance/Detail/Running/Property/Detail/Charts.vue
+++ b/src/views/device/Instance/Detail/Running/Property/Detail/Charts.vue
@@ -185,7 +185,8 @@ const getOptions = (arr: any[]) => {
tooltip: {
trigger: 'axis',
position: function (pt: any) {
- return [pt[0], '10%'];
+ const left = pt[0] - 80
+ return [left, '10%'];
},
},
series: [
diff --git a/src/views/device/Instance/Detail/components/BindParentDevice/index.vue b/src/views/device/Instance/Detail/components/BindParentDevice/index.vue
index 15235677..c7ab2b87 100644
--- a/src/views/device/Instance/Detail/components/BindParentDevice/index.vue
+++ b/src/views/device/Instance/Detail/components/BindParentDevice/index.vue
@@ -155,7 +155,7 @@ const handleOk = () => {
return;
}
btnLoading.value = true;
- bindDevice(_selectedRowKeys.value[0], props.data.id, )
+ bindDevice(_selectedRowKeys.value[0], [props.data.id] )
.then((resp) => {
if(resp.status === 200){
emit('ok', _selectedRowKeys.value[0]);
diff --git a/src/views/device/Instance/Detail/components/EditTable/PatchMapping.vue b/src/views/device/Instance/Detail/components/EditTable/PatchMapping.vue
index a89cbea6..d190b4b0 100644
--- a/src/views/device/Instance/Detail/components/EditTable/PatchMapping.vue
+++ b/src/views/device/Instance/Detail/components/EditTable/PatchMapping.vue
@@ -135,7 +135,7 @@ const _delete = (_key: string) => {
};
const handleClick = async () => {
-
+
if (!rightList.value.length) {
onlyMessage('请选择采集器', 'warning');
} else {
@@ -152,7 +152,7 @@ const handleClick = async () => {
}));
params.push(...array);
});
-
+
const filterParms = params.filter((item) => !!item.metadataId);
if (filterParms && filterParms.length !== 0) {
const res = await saveMapping(_props.deviceId, _props.type, filterParms);
@@ -192,4 +192,4 @@ watchEffect(() => {
}
}
}
-
+
\ No newline at end of file
diff --git a/src/views/device/Instance/Detail/components/EditTable/index.vue b/src/views/device/Instance/Detail/components/EditTable/index.vue
index 54f4f9f9..e2b886d6 100644
--- a/src/views/device/Instance/Detail/components/EditTable/index.vue
+++ b/src/views/device/Instance/Detail/components/EditTable/index.vue
@@ -8,7 +8,7 @@
-
+
采集器
@@ -20,13 +20,14 @@
{ record.provider = option.provider }"
@@ -36,7 +37,7 @@
+
{{ item.name }}
diff --git a/src/views/device/Product/Detail/DeviceAccess/accessModal.vue b/src/views/device/Product/Detail/DeviceAccess/accessModal.vue
index ca4b8506..357203c6 100644
--- a/src/views/device/Product/Detail/DeviceAccess/accessModal.vue
+++ b/src/views/device/Product/Detail/DeviceAccess/accessModal.vue
@@ -243,11 +243,11 @@ const columns = [
options: [
{
label: '正常',
- value: 'started',
+ value: 'enabled',
},
{
label: '禁用',
- value: 'disable',
+ value: 'disabled',
},
],
},
diff --git a/src/views/device/Product/Save/index.vue b/src/views/device/Product/Save/index.vue
index 9d2e7409..81646f36 100644
--- a/src/views/device/Product/Save/index.vue
+++ b/src/views/device/Product/Save/index.vue
@@ -313,8 +313,9 @@ const submitData = () => {
if (form.id === '') {
form.id = undefined;
}
- const res = await addProduct(form);
- loading.value = false
+ const res = await addProduct(form).finally(()=>{
+ loading.value = false
+ });
if (res.status === 200) {
onlyMessage('保存成功!');
visible.value = false;
diff --git a/src/views/device/Product/index.vue b/src/views/device/Product/index.vue
index 8e9a644d..f3753bbd 100644
--- a/src/views/device/Product/index.vue
+++ b/src/views/device/Product/index.vue
@@ -389,8 +389,7 @@ const beforeUpload = (file: any) => {
reader.readAsText(file);
reader.onload = async (result) => {
const text = result.target?.result;
- // console.log('text: ', text);
- // console.log(file);
+ console.log(text);
if (!file.type.includes('json')) {
onlyMessage('请上传json格式文件', 'error');
return false;
@@ -410,6 +409,10 @@ const beforeUpload = (file: any) => {
if(!data?.name){
data.name = "产品" + Date.now();
}
+ if(!data?.deviceType || JSON.stringify(data?.deviceType) === '{}' ){
+ onlyMessage('缺少deviceType字段或对应的值','error')
+ return false
+ }
const res = await updateDevice(data);
if (res.status === 200) {
onlyMessage('操作成功');
diff --git a/src/views/device/components/Metadata/Base/Base.vue b/src/views/device/components/Metadata/Base/Base.vue
index 00355f71..09b5e9c2 100644
--- a/src/views/device/components/Metadata/Base/Base.vue
+++ b/src/views/device/components/Metadata/Base/Base.vue
@@ -61,19 +61,17 @@
title="继承自产品物模型的数据不支持修改"
>
-
-
- 配置
-
+
+
+ 配置
+
+
-
-
-
+
{{ data.record.output?.type }}
@@ -93,19 +91,16 @@
title="继承自产品物模型的数据不支持修改"
>
-
+
配置
-
-
-
+
object
@@ -116,33 +111,27 @@
-
+ > -->
-
+
+
+
-
@@ -563,4 +552,4 @@ onBeforeRouteLeave((to, from, next) => { // 设备管理外路由跳转
justify-content: space-between;
padding-bottom: 16px;
}
-
\ No newline at end of file
+
diff --git a/src/views/device/components/Metadata/Base/columns.tsx b/src/views/device/components/Metadata/Base/columns.tsx
index fd0227f3..5c0ba07b 100644
--- a/src/views/device/components/Metadata/Base/columns.tsx
+++ b/src/views/device/components/Metadata/Base/columns.tsx
@@ -6,10 +6,9 @@ import { EventLevel } from "@/views/device/data";
import {MetadataType} from "@/views/device/Product/typings";
import { getUnit } from '@/api/device/instance';
import {Ref} from "vue";
-import {omit, pick} from "lodash-es";
+import {omit, pick, isObject, cloneDeep} from "lodash-es";
import { message } from 'jetlinks-ui-components'
import { onlyMessage } from "@/utils/comm";
-import {cloneDeep} from "lodash";
interface DataTableColumnProps extends ColumnProps {
type?: string,
components?: {
@@ -37,9 +36,7 @@ const type = {
report: '上报',
};
-export const validatorConfig = (value: any, isObject: boolean = false) => {
-
- console.log(value)
+export const validatorConfig = (value: any, _isObject: boolean = false) => {
if (!value) {
return Promise.resolve()
@@ -52,11 +49,11 @@ export const validatorConfig = (value: any, isObject: boolean = false) => {
return Promise.reject('请选择元素类型')
}
- if (isObject && value.type === 'object' && !value.properties?.length) {
+ if (_isObject && value.type === 'object' && !value.properties?.length) {
return Promise.reject('请添加参数')
}
- if (value.type === 'file' && (!value.fileType || !Object.keys(value.fileType).length)) {
+ if (value.type === 'file' && (!value.fileType || (isObject(value.fileType) && !Object.keys(value.fileType).length))) {
return Promise.reject('请选择文件类型')
}
@@ -665,4 +662,4 @@ export const TypeStringMap = {
// MetadataMapping.set('tags', TagColumns);
// MetadataMapping.set('functions', FunctionColumns);
//
-// export default MetadataMapping;
\ No newline at end of file
+// export default MetadataMapping;
diff --git a/src/views/device/components/Metadata/Base/components/DataType.vue b/src/views/device/components/Metadata/Base/components/DataType.vue
index bda8b030..dc9aefe1 100644
--- a/src/views/device/components/Metadata/Base/components/DataType.vue
+++ b/src/views/device/components/Metadata/Base/components/DataType.vue
@@ -21,7 +21,6 @@
{{ TypeStringMap[data.record.valueType?.type] }}
-
@@ -54,7 +53,7 @@
diff --git a/src/views/device/components/Metadata/Base/components/ModelButton.vue b/src/views/device/components/Metadata/Base/components/ModelButton.vue
index 49793ff0..98014d17 100644
--- a/src/views/device/components/Metadata/Base/components/ModelButton.vue
+++ b/src/views/device/components/Metadata/Base/components/ModelButton.vue
@@ -17,4 +17,4 @@ const props = defineProps({
\ No newline at end of file
+
diff --git a/src/views/device/components/Metadata/Base/components/Properties/Metrics/ValueItem.vue b/src/views/device/components/Metadata/Base/components/Properties/Metrics/ValueItem.vue
index 28a7dca3..f587bcb2 100644
--- a/src/views/device/components/Metadata/Base/components/Properties/Metrics/ValueItem.vue
+++ b/src/views/device/components/Metadata/Base/components/Properties/Metrics/ValueItem.vue
@@ -120,7 +120,7 @@ const validator = (_: any, value: any) => {
}
const typeValidator = (_: any, value: any) => {
- if (value === undefined) {
+ if (value === undefined || value === null) {
return Promise.reject(validatorTip())
}
if (type === 'string' && value?.length > 64) {
@@ -146,7 +146,7 @@ const handleValueByType = (value: any, isRange: boolean = false) => {
const confirm = () => {
return new Promise((resolve, reject) => {
- formRef.value.validate().then(() => {
+ formRef.value.validate().then((res) => {
let value = props.value.range === true ? formData.rangeValue : formData.value
if (['int', 'long'].includes(type)) {
diff --git a/src/views/device/components/Metadata/Base/components/Properties/OtherSetting.vue b/src/views/device/components/Metadata/Base/components/Properties/OtherSetting.vue
index 3ec50f62..36a95a79 100644
--- a/src/views/device/components/Metadata/Base/components/Properties/OtherSetting.vue
+++ b/src/views/device/components/Metadata/Base/components/Properties/OtherSetting.vue
@@ -51,8 +51,17 @@
/>
-
-
+
+
+ 配置
+
@@ -88,6 +97,8 @@ const props = defineProps({
type: Object,
default: () => ({})
},
+ hasPermission: String,
+ tooltip: Object
})
const fullRef = inject(FULL_CODE);
@@ -225,4 +236,4 @@ watch(() => props.value, () => {
\ No newline at end of file
+
diff --git a/src/views/device/components/Metadata/Base/components/Source.vue b/src/views/device/components/Metadata/Base/components/Source.vue
index 020907ec..cec35277 100644
--- a/src/views/device/components/Metadata/Base/components/Source.vue
+++ b/src/views/device/components/Metadata/Base/components/Source.vue
@@ -13,7 +13,7 @@
v-if="myValue != 'manual' && !showReset"
:bodyStyle="{
width: '450px',
- height: myValue === 'rule' ? '300px' : '80px',
+ height: myValue === 'rule' ? '300px' : '90px',
}"
:get-popup-container="(node) => fullRef || node"
placement="bottomRight"
@@ -294,7 +294,9 @@ onMounted(()=>{
item === props.value?.id ? showReset.value = true : ''
})
}
- handleSearch()
+ if(isNoCommunity && myValue.value === 'rule'){
+ handleSearch()
+ }
})
diff --git a/src/views/device/components/Metadata/Cat/index.vue b/src/views/device/components/Metadata/Cat/index.vue
index 97410d46..623ec1ec 100644
--- a/src/views/device/components/Metadata/Cat/index.vue
+++ b/src/views/device/components/Metadata/Cat/index.vue
@@ -112,7 +112,7 @@ const codecs = ref<{ id: string; name: string }[]>()
const routeChange = async (id: string) => {
const res = await getCodecs()
if (res.status === 200) {
- codecs.value = [{ id: 'jetlinks', name: 'jetlinks' }].concat(res.result)
+ codecs.value = [{ id: 'jetlinks', name: '标准物模型' }].concat(res.result)
}
if (props.type === 'device' && id) {
detail(id as string).then((resp) => {
diff --git a/src/views/device/components/Metadata/Import/index.vue b/src/views/device/components/Metadata/Import/index.vue
index 6ffb3c96..8789b971 100644
--- a/src/views/device/components/Metadata/Import/index.vue
+++ b/src/views/device/components/Metadata/Import/index.vue
@@ -158,7 +158,7 @@
物模型
-
+
{
@@ -287,12 +287,12 @@ const requiredCheck = (data:any) =>{
if(!item?.id){
onlyMessage(`属性定义第${index + 1}个数组中缺失id属性`,'error');
check = true
- return
+ return
}
if(!item?.name){
onlyMessage(`属性定义第${index + 1}个数组中缺失name属性`,'error');
check = true
- return
+ return
}
if(!item?.valueType?.type){
onlyMessage(`标签定义第${index + 1}个数组中缺失valueType.type属性`,'error');
@@ -302,14 +302,14 @@ const requiredCheck = (data:any) =>{
if(!item?.expands?.source){
onlyMessage(`属性定义第${index + 1}个数组中缺失expands.source属性`,'error');
check = true
- return
+ return
}
-
+
if((item?.expands?.source === 'device' || item?.expands?.source === 'rule') && !item?.expands?.type){
onlyMessage(`属性定义第${index + 1}个数组中缺失type属性`,'error');
check = true
return
- }
+ }
})
}
if(data?.functions && !check){
@@ -323,7 +323,7 @@ const requiredCheck = (data:any) =>{
onlyMessage(`方法定义第${index + 1}个数组中缺失name属性`,'error');
check = true
return
- }
+ }
if(!item?.async && item?.async !== false){
onlyMessage(`方法定义第${index + 1}个数组中缺失async属性`,'error');
check = true
@@ -375,13 +375,13 @@ const requiredCheck = (data:any) =>{
onlyMessage(`事件定义第${index + 1}个数组中缺失valueType.properties数组第${number+1}项的valueType.type属性`,'error');
check = true
return
- }
- })
+ }
+ })
}else{
onlyMessage(`事件定义第${index + 1}个数组中缺失valueType.properties数组`,'error');
check = true
return
- }
+ }
}
})
}
@@ -396,7 +396,7 @@ const requiredCheck = (data:any) =>{
onlyMessage(`标签定义第${index + 1}个数组中缺失name属性`,'error');
check = true
return
- }
+ }
if(!item?.valueType?.type){
onlyMessage(`标签定义第${index + 1}个数组中缺失valueType.type属性`,'error');
check = true
@@ -419,18 +419,18 @@ const aliCheck = (data:any) => {
if(!item?.identifier){
onlyMessage(`属性定义第${index + 1}个数组中缺失identifier属性`,'error');
check = true
- return
+ return
}
if(!item?.name){
onlyMessage(`属性定义第${index + 1}个数组中缺失name属性`,'error');
check = true
- return
+ return
}
if(!item?.dataType?.type){
onlyMessage(`属性定义第${index + 1}个数组中缺失dataType.type属性`,'error');
check = true
- return
- }
+ return
+ }
})
}
if(data?.functions && !check){
@@ -444,7 +444,7 @@ const aliCheck = (data:any) => {
onlyMessage(`方法定义第${index + 1}个数组中缺失name属性`,'error');
check = true
return
- }
+ }
if(!item?.callType){
onlyMessage(`方法定义第${index + 1}个数组中缺失callType属性`,'error');
check = true
@@ -486,23 +486,23 @@ const aliCheck = (data:any) => {
onlyMessage(`事件定义第${index + 1}个数组中缺失outputData数组第${number+1}项的dataType.type属性`,'error');
check = true
return
- }
+ }
if(!i?.dataType?.specs){
onlyMessage(`事件定义第${index + 1}个数组中缺失outputData数组第${number+1}项的dataType.specs属性`,'error');
check = true
return
- }
- })
+ }
+ })
}else{
onlyMessage(`事件定义第${index + 1}个数组中缺失outputData数组`,'error');
check = true
return
- }
+ }
}
})
}
return check
-}
+}
const beforeUpload: UploadProps['beforeUpload'] = (file) => {
if(file.type === 'application/json') {
const reader = new FileReader();
@@ -510,7 +510,7 @@ const beforeUpload: UploadProps['beforeUpload'] = (file) => {
reader.onload = (json) => {
if(json.target?.result){
const data = JSON.parse(json.target?.result);
- let check = formModel.metadata === 'jetlinks' ? requiredCheck(data) : aliCheck(data)
+ let check = formModel.metadata === 'jetlinks' ? requiredCheck(data) : aliCheck(data)
if(!check){
onlyMessage('操作成功!')
formModel.import = json.target?.result;
@@ -637,7 +637,7 @@ const handleImport = async () => {
data[data?.type === 'copy' ? 'copy' : 'import'] ||
'{}',
);
- if(data?.type === 'import'){
+ if(data?.type !== 'copy'){
Object.keys(_object).forEach((i:any)=>{
const map = new Map()
_object[i].forEach((item:any)=>(
@@ -724,4 +724,4 @@ const handleImport = async () => {
line-height: 30px;
margin: 0 -11px;
}
-
+
\ No newline at end of file
diff --git a/src/views/iframe/index.vue b/src/views/iframe/index.vue
index 2d9f9d92..a3809527 100644
--- a/src/views/iframe/index.vue
+++ b/src/views/iframe/index.vue
@@ -20,19 +20,34 @@ const handle = async (appId: string, url: string) => {
const res = await getAppInfo_api(appId);
let menuUrl: any = url;
if (res.status === 200) {
- if (res.result.page.routeType === 'hash') {
- menuUrl = `${url}`;
+ const result = res.result
+ if (result.page.routeType === 'hash') {
+ menuUrl = url.startsWith('/') ? `#${url}` : `#/${url}`;
}
- if (res.result.provider === 'internal-standalone') {
- const urlStandalone = `${res.result.page.baseUrl}/api/application/sso/${appId}/login?redirect=${menuUrl}?layout=false`;
+
+ if (result.page.parameters) {
+ const params = new URLSearchParams()
+ result.page.parameters.forEach((item: any) => {
+ if (item?.key) {
+ params.set(item.key,item.value)
+ }
+ })
+ const urlParams = params.toString()
+ if (urlParams) {
+ menuUrl += `?${urlParams}`
+ }
+ }
+
+ if (result.provider === 'internal-standalone') {
+ const urlStandalone = `${result.page.baseUrl}/api/application/sso/${appId}/login?redirect=${menuUrl}?layout=false`;
iframeUrl.value = urlStandalone;
- } else if (res.result.provider === 'internal-integrated') {
+ } else if (result.provider === 'internal-integrated') {
const tokenUrl = `${
- res.result.page.baseUrl
- }?X-Access-Token=${LocalStore.get(TOKEN_KEY)}`;
+ result.page.baseUrl
+ }/${menuUrl}?layout=false&X-Access-Token=${LocalStore.get(TOKEN_KEY)}`;
iframeUrl.value = tokenUrl;
} else {
- const urlOther = `${res.result.page.baseUrl}/${menuUrl}`;
+ const urlOther = `${result.page.baseUrl}/${menuUrl}`;
iframeUrl.value = urlOther;
}
}
diff --git a/src/views/init-home/InitData/index.vue b/src/views/init-home/InitData/index.vue
index b51dd938..11ebdb42 100644
--- a/src/views/init-home/InitData/index.vue
+++ b/src/views/init-home/InitData/index.vue
@@ -145,7 +145,10 @@ const visible = ref(false);
const modalForm = reactive({
host: '0.0.0.0',
});
-
+const regDomain = new RegExp(
+ // /^https?:\/\/(([a-zA-Z0-9_-])+(\.)?)*(:\d+)?(\/((\.)?(\?)?=?&?[a-zA-Z0-9_-](\?)?)*)*$/i,
+ /^[a-zA-Z0-9]+([\-\.]{1}[a-zA-Z0-9]+)*\.[a-zA-Z]{2,}$/
+ )
/**
* 校验官网地址
*/
@@ -153,7 +156,7 @@ const validateUrl = async (_rule: Rule, value: string) => {
if (!value) {
return Promise.reject('请输入公网地址');
} else {
- if (!testIpv4_6(value)) {
+ if (!testIpv4_6(value) && !regDomain.test(value)) {
return Promise.reject('请输入正确的公网地址');
}
return Promise.resolve();
diff --git a/src/views/link/Certificate/Detail/index.vue b/src/views/link/Certificate/Detail/index.vue
index 889a9985..073d7179 100644
--- a/src/views/link/Certificate/Detail/index.vue
+++ b/src/views/link/Certificate/Detail/index.vue
@@ -4,91 +4,56 @@
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
+
- 客户端
+ 客户端
服务端
-
+
+
+
-
-
-
-
-
+
+
- 保存
+ 保存
@@ -131,8 +96,9 @@ const route = useRoute();
const view = route.query.view as string;
const id = route.params.id as string;
-const useForm = Form.useForm;
+// const useForm = Form.useForm;
+const formRef = ref()
const fileLoading = ref(false);
const loading = ref(false);
@@ -144,49 +110,46 @@ const formData = ref({
key: '',
},
description: '',
- mode:'server',
- authenticationMethod:'single'
+ mode: 'server',
+ authenticationMethod: 'single'
});
-const { resetFields, validate, validateInfos } = useForm(
- formData,
- reactive({
- type: [{ required: true, message: '请选择证书标准', trigger: 'blur' }],
- name: [
- { required: true, message: '请输入证书名称', trigger: 'blur' },
- { max: 64, message: '最多可输入64个字符' },
- ],
- 'configs.cert': [
- { required: true, message: '请输入或上传文件', trigger: 'blur' },
- ],
- 'configs.key': [
- { required: true, message: '请输入或上传文件', trigger: 'blur' },
- ],
- description: [{ max: 200, message: '最多可输入200个字符' }],
- mode:[{ required: true, message: '请选择证书类型', trigger: 'blur' }],
- authenticationMethod:[{ required: true, message: '请选择认证方式', trigger: 'blur' }]
- }),
-);
+// const rules = {
+// type: [{ required: true, message: '请选择证书标准', trigger: 'blur' }],
+// name: [
+// { required: true, message: '请输入证书名称', trigger: 'blur' },
+// { max: 64, message: '最多可输入64个字符' },
+// ],
+// 'configs.cert': [
+// { required: true, message: '请输入或上传文件', trigger: 'blur' },
+// ],
+// 'configs.key': [
+// { required: true, message: '请输入或上传文件', trigger: 'blur' },
+// ],
+// description: [{ max: 200, message: '最多可输入200个字符' }],
+// mode:[{ required: true, message: '请选择证书类型', trigger: 'blur' }],
+// authenticationMethod:[{ required: true, message: '请选择认证方式', trigger: 'blur' }]
+// );
const onSubmit = () => {
- validate()
+ formRef.value.validate()
.then(async (res) => {
- let params:any = toRaw(formData.value);
- if(formData.value.mode === 'client'){
- if(formData.value.authenticationMethod === 'binomial'){
+ let params: any = toRaw(formData.value);
+ if (formData.value.mode === 'client') {
+ if (formData.value.authenticationMethod === 'binomial') {
params.configs.trust = params.configs.cert
- }else{
+ } else {
params.configs = {
- key:formData.value.configs.key,
- trust:formData.value.configs.cert
+ // key:formData.value.configs.key,
+ trust: formData.value.configs.cert
}
}
}
loading.value = true;
const response =
id === ':id'
- ? await save(params).catch(() => {})
- : await update({ ...params, id }).catch(() => {});
+ ? await save(params).catch(() => { })
+ : await update({ ...params, id }).catch(() => { });
if (response?.status === 200) {
onlyMessage('操作成功', 'success');
router.push('/iot/link/certificate');
@@ -217,9 +180,9 @@ const detail = async (id: string) => {
const type = result.type.value as TypeObjType;
formData.value = {
...result,
- configs:{
- key:result.configs.key,
- cert:result.configs?.cert ? result.configs?.cert : result.configs?.trust
+ configs: {
+ key: result.configs.key,
+ cert: result.configs?.cert ? result.configs?.cert : result.configs?.trust
},
mode: result.mode.value,
authenticationMethod: result.authenticationMethod.value,
@@ -239,6 +202,7 @@ detail(id);
width: 148px;
height: 80px;
padding: 0;
+
img {
width: 100%;
height: 100%;
diff --git a/src/views/link/DashBoard/components/Network.vue b/src/views/link/DashBoard/components/Network.vue
index bb6c1893..02d470f1 100644
--- a/src/views/link/DashBoard/components/Network.vue
+++ b/src/views/link/DashBoard/components/Network.vue
@@ -111,7 +111,7 @@ const pickerTimeChange = (value: any) => {
};
const changeType = (value:any) =>{
getNetworkEcharts(data.value);
-}
+}
const getNetworkEcharts = async (val: any) => {
loading.value = true;
const resp: any = await dashboard(networkParams(val));
@@ -149,10 +149,16 @@ const getNetworkEcharts = async (val: any) => {
const formatterData = (value: any) => {
let _data = '';
- if (value >= 1024 && value < 1024 * 1024) {
- _data = `${Number((value / 1024).toFixed(2))}KB`;
- } else if (value >= 1024 * 1024) {
- _data = `${Number((value / 1024 / 1024).toFixed(2))}M`;
+ const kb = 1024
+ const mb = kb**2
+ const gb = kb**3
+
+ if (value >= kb && value < mb) {
+ _data = `${Number((value / kb).toFixed(2))}KB`;
+ } else if (value >= mb && value < gb) {
+ _data = `${Number((value / mb).toFixed(2))}M`;
+ } else if (value >= gb) {
+ _data = `${Number((value / gb).toFixed(2))}G`;
} else {
_data = `${value}B`;
}
diff --git a/src/views/link/Type/Detail/index.vue b/src/views/link/Type/Detail/index.vue
index cd8aefb9..84c66a62 100644
--- a/src/views/link/Type/Detail/index.vue
+++ b/src/views/link/Type/Detail/index.vue
@@ -1285,7 +1285,7 @@ const changeType = (value: string) => {
if (value !== 'MQTT_CLIENT') {
const { configuration } = dynamicValidateForm.cluster[0];
value && (configuration.host = '0.0.0.0');
- }else{
+ }else if(isNoCommunity){
formData.value.shareCluster = false
changeShareCluster(formData.value.shareCluster)
}
diff --git a/src/views/media/Device/Channel/Share/index.vue b/src/views/media/Device/Channel/Share/index.vue
index fe5bf013..c77b76c2 100644
--- a/src/views/media/Device/Channel/Share/index.vue
+++ b/src/views/media/Device/Channel/Share/index.vue
@@ -32,4 +32,4 @@ watchEffect(() => {
LocalStore.set(TOKEN_KEY, obj?.[TOKEN_KEY]);
}
});
-
+
\ No newline at end of file
diff --git a/src/views/notice/Config/Detail/doc/Webhook.tsx b/src/views/notice/Config/Detail/doc/Webhook.tsx
index 446205f6..721575a6 100644
--- a/src/views/notice/Config/Detail/doc/Webhook.tsx
+++ b/src/views/notice/Config/Detail/doc/Webhook.tsx
@@ -5,12 +5,12 @@ const Webhook = () => {
1. 概述
- webhook是一个接收HTTP请求的URL(本平台默认只支持HTTP
- POST请求),实现了Webhook的第三方系统可以基于该URL订阅本平台系统信息,本平台按配置把特定的事件结果推送到指定的地址,便于系统做后续处理。
+ WebHook是一个接收HTTP请求的URL(本平台默认只支持HTTP
+ POST请求),实现了WebHook的第三方系统可以基于该URL订阅本平台系统信息,本平台按配置把特定的事件结果推送到指定的地址,便于系统做后续处理。
2.通知配置说明
-
1、Webhook
-
Webhook地址。
+
1、WebHook
+
WebHook地址。
2、请求头
diff --git a/src/views/notice/Config/Detail/index.vue b/src/views/notice/Config/Detail/index.vue
index 18f1e73b..7245ca1c 100644
--- a/src/views/notice/Config/Detail/index.vue
+++ b/src/views/notice/Config/Detail/index.vue
@@ -80,7 +80,7 @@
"
>
@@ -88,7 +88,7 @@
v-model:value="
formData.configuration.url
"
- placeholder="请输入webHook"
+ placeholder="请输入WebHook"
/>
@@ -278,12 +278,12 @@
@@ -447,7 +447,7 @@ const formRules = ref({
],
// webhook
'configuration.url': [
- { required: true, message: '请输入Webhook', trigger: 'blur' },
+ { required: true, message: '请输入WebHook', trigger: 'blur' },
// {
// pattern:
// /^(((ht|f)tps?):\/\/)?([^!@#$%^&*?.\s-]([^!@#$%^&*?.\s]{0,63}[^!@#$%^&*?.\s])?\.)+[j-z]{2,6}\/?/,
diff --git a/src/views/notice/const.ts b/src/views/notice/const.ts
index fb42d5d2..11facc06 100644
--- a/src/views/notice/const.ts
+++ b/src/views/notice/const.ts
@@ -28,7 +28,7 @@ export const NOTICE_METHOD: INoticeMethod[] = [
value: 'sms',
},
{
- label: 'webhook',
+ label: 'WebHook',
value: 'webhook',
},
];
@@ -75,7 +75,7 @@ export const MSG_TYPE = {
],
webhook: [
{
- label: 'webhook',
+ label: 'WebHook',
value: 'http',
logo: getImage('/notice/webhook.png'),
},
diff --git a/src/views/rule-engine/Alarm/Config/Io/index.vue b/src/views/rule-engine/Alarm/Config/Io/index.vue
index 4586c557..c521d7bb 100644
--- a/src/views/rule-engine/Alarm/Config/Io/index.vue
+++ b/src/views/rule-engine/Alarm/Config/Io/index.vue
@@ -141,7 +141,7 @@
1、平台支持将告警数据输出到kafka,第三方系统可订阅kafka中的告警数据,进行业务处理。
- 输出参数
+ 推送参数
new Promise((resolve) => {
getTreeData_api({ paging: false }).then((resp: any) => {
const formatValue = (list: any[]) => {
@@ -260,4 +266,4 @@ const handleClick = (detail: any) => {
padding-right: 0px;
padding-left: 0px;
}
-
\ No newline at end of file
+
diff --git a/src/views/rule-engine/Scene/Save/action/Device/Product.vue b/src/views/rule-engine/Scene/Save/action/Device/Product.vue
index ecfcfe0d..80006026 100644
--- a/src/views/rule-engine/Scene/Save/action/Device/Product.vue
+++ b/src/views/rule-engine/Scene/Save/action/Device/Product.vue
@@ -208,10 +208,17 @@ const columns = [
},
{
dataIndex: 'id$dim-assets',
+ key: 'id$dim-assets',
title: '所属组织',
hideInTable: true,
search: {
type: 'treeSelect',
+ componentProps: {
+ fieldNames: {
+ label: 'name',
+ value: 'value',
+ },
+ },
options: () =>
new Promise((resolve) => {
getTreeData_api({ paging: false }).then((resp: any) => {
@@ -289,4 +296,4 @@ onMounted(() => {
padding-right: 0px;
padding-left: 0px;
}
-
\ No newline at end of file
+
diff --git a/src/views/rule-engine/Scene/Save/action/Device/actions/FunctionItem.vue b/src/views/rule-engine/Scene/Save/action/Device/actions/FunctionItem.vue
index cc5fe7d2..64dd0f80 100644
--- a/src/views/rule-engine/Scene/Save/action/Device/actions/FunctionItem.vue
+++ b/src/views/rule-engine/Scene/Save/action/Device/actions/FunctionItem.vue
@@ -109,13 +109,17 @@ const upperOptions = computed(() => {
});
const onChange = () => {
+ const objValue: any = { source: _source.value, value: _value.value }
+ if (_source.value === 'upper') {
+ objValue.upperKey = _value.value
+ }
emit('update:value', _value.value);
emit('update:source', _source.value);
- emit('change', { source: _source.value, value: _value.value });
+ emit('change', objValue);
};
watchEffect(() => {
_value.value = props.value;
_source.value = props.source || 'fixed';
});
-
\ No newline at end of file
+
diff --git a/src/views/rule-engine/Scene/Save/action/Device/actions/WriteProperty.vue b/src/views/rule-engine/Scene/Save/action/Device/actions/WriteProperty.vue
index b744e408..7c1d621c 100644
--- a/src/views/rule-engine/Scene/Save/action/Device/actions/WriteProperty.vue
+++ b/src/views/rule-engine/Scene/Save/action/Device/actions/WriteProperty.vue
@@ -173,11 +173,18 @@ const onChange = () => {
const onValueChange = (val: any, label: string) => {
const optionColumn = isObject(val) && (val as any).metadata ? [(val as any).column] : []
+
+ const objectValue: any = {
+ value: propertyModelRef?.propertiesValue,
+ source: propertyModelRef?.source,
+ }
+
+ if (propertyModelRef?.source === 'upper') {
+ objectValue.upperKey = propertyModelRef?.propertiesValue
+ }
+
const obj = {
- [`${propertyModelRef.properties}`]: {
- value: propertyModelRef?.propertiesValue,
- source: propertyModelRef?.source,
- },
+ [`${propertyModelRef.properties}`]: objectValue
};
emit('update:value', obj);
emit('change', label || val, optionColumn)
@@ -212,4 +219,4 @@ const onSave = () => {
};
defineExpose({ onSave });
-
\ No newline at end of file
+
diff --git a/src/views/rule-engine/Scene/Save/action/ListItem/Item.vue b/src/views/rule-engine/Scene/Save/action/ListItem/Item.vue
index 6b35851e..078ac2fa 100644
--- a/src/views/rule-engine/Scene/Save/action/ListItem/Item.vue
+++ b/src/views/rule-engine/Scene/Save/action/ListItem/Item.vue
@@ -220,7 +220,7 @@
)
"
/>
- webhook
+ WebHook
发送
{{
diff --git a/src/views/system/Apply/Save/components/EditForm.vue b/src/views/system/Apply/Save/components/EditForm.vue
index 7d47f61d..7d3ca1bf 100644
--- a/src/views/system/Apply/Save/components/EditForm.vue
+++ b/src/views/system/Apply/Save/components/EditForm.vue
@@ -144,12 +144,7 @@
@@ -1397,12 +1392,20 @@
+
@@ -1420,6 +1423,7 @@ import {
import FormLabel from './FormLabel.vue';
import RequestTable from './RequestTable.vue';
import MenuDialog from '../../componenets/MenuDialog.vue';
+import ThirdMenu from '../../componenets/ThirdMenu.vue';
import { getImage, onlyMessage } from '@/utils/comm';
import type { formType, dictType, optionsType, applyType } from '../typing';
import { getRoleList_api } from '@/api/system/user';
@@ -1573,7 +1577,7 @@ const getType = async () => {
typeOptions.value = arr;
}
}
-
+
onMounted(async () => {
await getType();
getRoleIdList();
diff --git a/src/views/system/Apply/componenets/ThirdMenu.vue b/src/views/system/Apply/componenets/ThirdMenu.vue
new file mode 100644
index 00000000..31993ef6
--- /dev/null
+++ b/src/views/system/Apply/componenets/ThirdMenu.vue
@@ -0,0 +1,150 @@
+
+
+
+ 当前集成菜单
+
+
+
+
+
+
+
+
+
diff --git a/src/views/system/Apply/componenets/util.ts b/src/views/system/Apply/componenets/util.ts
new file mode 100644
index 00000000..fa561e8c
--- /dev/null
+++ b/src/views/system/Apply/componenets/util.ts
@@ -0,0 +1,27 @@
+export const getCheckByTree = (data: any[]): string[] => {
+ let keys: string[] = []
+ if (data.length) {
+ data.forEach(item => {
+ if (item.children) {
+ keys = [...getCheckByTree(item.children), ...keys]
+ } else {
+ keys.push(item.code)
+ }
+ })
+ }
+ return keys
+}
+
+export const filterTree = (data: any[], ids: string[]) => {
+ return data?.filter(item => {
+ delete item.id
+ item.options = {show: true}
+ if (ids.includes(item.code)) {
+ return true
+ } else if (item.children) {
+ item.children = filterTree(item.children, ids)
+ return item.children.length >0
+ }
+ return false
+ }) || []
+}
diff --git a/src/views/system/Apply/index.vue b/src/views/system/Apply/index.vue
index bff39a0c..486a395c 100644
--- a/src/views/system/Apply/index.vue
+++ b/src/views/system/Apply/index.vue
@@ -183,12 +183,19 @@
+ { dialogVisible = false; table.refresh}"
+ />
@@ -197,6 +204,7 @@