Merge branch 'dev' of github.com:jetlinks/jetlinks-ui-vue into dev

This commit is contained in:
JiangQiming 2023-03-16 17:18:16 +08:00
commit ea48417454
26 changed files with 254 additions and 185 deletions

View File

@ -14,7 +14,7 @@
> >
{{ slotProps.route.breadcrumbName }} {{ slotProps.route.breadcrumbName }}
</a> </a>
<span v-else >{{ slotProps.route.breadcrumbName }}</span> <span v-else style='cursor: pointer' >{{ slotProps.route.breadcrumbName }}</span>
</template> </template>
<template #rightContentRender> <template #rightContentRender>
<div class="right-content"> <div class="right-content">

View File

@ -1,5 +1,5 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import type { BranchesType, FormModelType, SceneItem } from '@/views/rule-engine/Scene/typings' import type { FormModelType, SceneItem } from '@/views/rule-engine/Scene/typings'
import { detail } from '@/api/rule-engine/scene' import { detail } from '@/api/rule-engine/scene'
import { cloneDeep, isArray } from 'lodash-es' import { cloneDeep, isArray } from 'lodash-es'
import { randomString } from '@/utils/utils' import { randomString } from '@/utils/utils'

View File

@ -25,13 +25,13 @@
label="密码" label="密码"
name="newPassword" name="newPassword"
:rules="[ :rules="[
{ required: true,message:'请输入密码' }, { required: true, message: '请输入密码' },
{ validator: checkMothods.new, trigger: 'blur' }, { validator: checkMothods.new, trigger: 'blur' },
]" ]"
> >
<j-input-password <j-input-password
v-model:value="form.newPassword" v-model:value="form.newPassword"
placeholder="请输入姓名" placeholder="请输入密码"
/> />
</j-form-item> </j-form-item>
<j-form-item <j-form-item
@ -44,7 +44,7 @@
> >
<j-input-password <j-input-password
v-model:value="form.confirmPassword" v-model:value="form.confirmPassword"
placeholder="请输入姓名" placeholder="请再次输入密码"
/> />
</j-form-item> </j-form-item>
</j-form> </j-form>
@ -64,7 +64,7 @@ const emits = defineEmits(['ok', 'update:visible']);
const props = defineProps<{ const props = defineProps<{
visible: boolean; visible: boolean;
}>(); }>();
const loading = ref(false) const loading = ref(false);
const formRef = ref<FormInstance>(); const formRef = ref<FormInstance>();
const form = ref<formType>({ const form = ref<formType>({
oldPassword: '', oldPassword: '',
@ -102,7 +102,9 @@ const checkMothods = {
}, },
confirm: async (_rule: Rule, value: string) => { confirm: async (_rule: Rule, value: string) => {
if (!value) return Promise.reject(); if (!value) return Promise.reject();
else if (form.value.newPassword && value !== form.value.newPassword) {
formRef.value?.validate('newPassword');
}
try { try {
const resp: any = await validateField_api('password', value); const resp: any = await validateField_api('password', value);
if (resp.status === 200 && !resp.result.passed) if (resp.status === 200 && !resp.result.passed)
@ -116,18 +118,20 @@ const checkMothods = {
const handleOk = () => { const handleOk = () => {
formRef.value?.validate().then(() => { formRef.value?.validate().then(() => {
loading.value = true loading.value = true;
const params = { const params = {
oldPassword: form.value.oldPassword, oldPassword: form.value.oldPassword,
newPassword: form.value.newPassword, newPassword: form.value.newPassword,
}; };
updateMepsd_api(params).then((resp) => { updateMepsd_api(params)
if (resp.status === 200) { .then((resp) => {
message.success('保存成功'); if (resp.status === 200) {
emits('ok'); message.success('保存成功');
emits('update:visible', false); emits('ok');
} emits('update:visible', false);
}).finally(()=>loading.value = false) }
})
.finally(() => (loading.value = false));
}); });
}; };
console.clear(); console.clear();

View File

@ -114,10 +114,7 @@
<h3>修改密码</h3> <h3>修改密码</h3>
<div class="content"> <div class="content">
<div class="content" style="align-items: flex-end"> <div class="content" style="align-items: flex-end">
<lock-outlined <AIcon type="LockOutlined" style="color: #1d39c4; font-size: 70px" />
style="color: #1d39c4; font-size: 70px"
/>
<!-- <AIcon type="LockOutlined" /> -->
<span <span
style="margin-left: 5px; color: rgba(0, 0, 0, 0.55)" style="margin-left: 5px; color: rgba(0, 0, 0, 0.55)"
>安全性高的密码可以使帐号更安全建议您定期更换密码,设置一个包含字母,符号或数字中至少两项且长度超过8位的密码</span >安全性高的密码可以使帐号更安全建议您定期更换密码,设置一个包含字母,符号或数字中至少两项且长度超过8位的密码</span
@ -232,7 +229,6 @@
import PermissionButton from '@/components/PermissionButton/index.vue'; import PermissionButton from '@/components/PermissionButton/index.vue';
import EditInfoDialog from './components/EditInfoDialog.vue'; import EditInfoDialog from './components/EditInfoDialog.vue';
import EditPasswordDialog from './components/EditPasswordDialog.vue'; import EditPasswordDialog from './components/EditPasswordDialog.vue';
import { LockOutlined } from '@ant-design/icons-vue';
import { BASE_API_PATH, TOKEN_KEY } from '@/utils/variable'; import { BASE_API_PATH, TOKEN_KEY } from '@/utils/variable';
import { LocalStore, getImage } from '@/utils/comm'; import { LocalStore, getImage } from '@/utils/comm';
import { message, UploadChangeParam, UploadFile } from 'ant-design-vue'; import { message, UploadChangeParam, UploadFile } from 'ant-design-vue';
@ -247,7 +243,7 @@ import { isNoCommunity } from '@/utils/utils';
import { userInfoType } from './typing'; import { userInfoType } from './typing';
const permission = 'system/User'; const permission = 'system/User';
const userInfo = ref<userInfoType>({}); const userInfo = ref<userInfoType>({} as any);
// //
const bindList = ref<any[]>([]); const bindList = ref<any[]>([]);
const bindIcon = { const bindIcon = {

View File

@ -93,7 +93,13 @@ const formModel = ref<formState>({
description: '', description: '',
}); });
const rules = ref({ const rules = ref({
name: [{ required: true, message: '请输入名称', trigger: 'blur' }], name: [
{ required: true, message: '请输入名称', trigger: 'blur' },
{
max: 64,
message: '最多可输入64个字符',
},
],
sortIndex: [{ required: true, message: '请输入排序', trigger: 'blur' }], sortIndex: [{ required: true, message: '请输入排序', trigger: 'blur' }],
}); });
const visible = ref(false); const visible = ref(false);
@ -112,7 +118,7 @@ const submitData = async () => {
addParams.value = { addParams.value = {
...formModel.value, ...formModel.value,
// sortIndex: // sortIndex:
// childArr.value[childArr.value.length - 1].sortIndex + 1, // childArr.value[childArr.value.length - 1].sortIndex + 1,
parentId: addObj.value.id, parentId: addObj.value.id,
}; };
} else if (props.isChild === 2) { } else if (props.isChild === 2) {

View File

@ -10,7 +10,7 @@
ref="tableRef" ref="tableRef"
:columns="table.columns" :columns="table.columns"
:dataSource="dataSource" :dataSource="dataSource"
model="table" model="TABLE"
:defaultParams="{ :defaultParams="{
paging: false, paging: false,
sorts: [ sorts: [
@ -35,7 +35,7 @@
</PermissionButton> </PermissionButton>
</template> </template>
<template #action="slotProps"> <template #action="slotProps">
<j-space :size="16"> <j-space>
<template <template
v-for="i in getActions(slotProps, 'table')" v-for="i in getActions(slotProps, 'table')"
:key="i.key" :key="i.key"
@ -222,23 +222,31 @@ const getActions = (
const table = reactive({ const table = reactive({
columns: [ columns: [
{ title: '名称', dataIndex: 'name', key: 'name' }, {
title: '名称',
dataIndex: 'name',
key: 'name',
ellipsis: true,
width:600
},
{ {
title: '排序', title: '排序',
dataIndex: 'sortIndex', dataIndex: 'sortIndex',
key: 'sortIndex', key: 'sortIndex',
scopedSlots: true, scopedSlots: true,
width:200
}, },
{ {
title: '说明', title: '说明',
dataIndex: 'description', dataIndex: 'description',
key: 'description', key: 'description',
width:700
}, },
{ {
title: '操作', title: '操作',
key: 'action', key: 'action',
fixed: 'right', fixed: 'right',
width: 250, ellipsis: true,
scopedSlots: true, scopedSlots: true,
}, },
], ],

View File

@ -269,7 +269,8 @@
<!-- 选择设备 --> <!-- 选择设备 -->
<j-modal <j-modal
title="设备接入配置" title="设备接入配置"
:visible="visible" v-if="visible"
visible
width="1200px" width="1200px"
okText="确定" okText="确定"
cancelText="取消" cancelText="取消"
@ -280,6 +281,7 @@
:columns="query.columns" :columns="query.columns"
target="deviceModal" target="deviceModal"
@search="search" @search="search"
type='simple'
/> />
<JProTable <JProTable
:columns="query.columns" :columns="query.columns"
@ -442,6 +444,7 @@ const showModal = () => {
* 关闭弹窗 * 关闭弹窗
*/ */
const cancel = () => { const cancel = () => {
queryParams.value = {};
visible.value = false; visible.value = false;
}; };
/** /**
@ -968,6 +971,7 @@ const submitData = async () => {
message.success('操作成功!'); message.success('操作成功!');
} }
visible.value = false; visible.value = false;
queryParams.value = {};
}); });
} }
} else { } else {

View File

@ -125,6 +125,7 @@
placeholder="请选择产品分类" placeholder="请选择产品分类"
:tree-data="treeList" :tree-data="treeList"
@change="valueChange" @change="valueChange"
allow-clear
:fieldNames="{ label: 'name', value: 'id' }" :fieldNames="{ label: 'name', value: 'id' }"
:filterTreeNode=" :filterTreeNode="
(v, option) => filterSelectNode(v, option) (v, option) => filterSelectNode(v, option)

View File

@ -202,7 +202,7 @@ const columns = [
scopedSlots: true, scopedSlots: true,
}, },
{ {
title: '名称', title: '产品名称',
dataIndex: 'name', dataIndex: 'name',
key: 'name', key: 'name',
}, },

View File

@ -34,8 +34,11 @@ const props = defineProps({
const { cardData, cardTitle } = toRefs(props); const { cardData, cardTitle } = toRefs(props);
const jumpPage = (item: bootConfig) => { const jumpPage = (item: bootConfig) => {
if (item.auth === undefined || item.auth) _jumpPage(item.link, item.params); if (item.auth === undefined || item.auth) {
else message.warning('暂无权限,请联系管理员'); _jumpPage(item.link, item.params);
} else {
message.warning('暂无权限,请联系管理员');
}
}; };
</script> </script>

View File

@ -37,8 +37,11 @@ const { cardData, cardTitle } = toRefs(props);
const { jumpPage: _jumpPage } = useMenuStore(); const { jumpPage: _jumpPage } = useMenuStore();
const jumpPage = (item: bootConfig) => { const jumpPage = (item: bootConfig) => {
if (item.auth === undefined || item.auth) _jumpPage(item.link, item.params); if (item.auth === undefined || item.auth) {
else message.warning('暂无权限,请联系管理员'); _jumpPage(item.link, item.params);
} else {
message.warning('暂无权限,请联系管理员');
}
}; };
</script> </script>

View File

@ -13,7 +13,7 @@
<j-row :gutter="24"> <j-row :gutter="24">
<j-col :span="12"><DeviceCountCard /></j-col> <j-col :span="12"><DeviceCountCard /></j-col>
<j-col :span="12"><BasicCountCard /></j-col> <j-col :span="12"><BasicCountCard /></j-col>
<j-col :span="24" style="margin-top: 24px;"> <j-col :span="24" style="margin-top: 24px">
<PlatformPicCard image="/images/home/content1.svg" /> <PlatformPicCard image="/images/home/content1.svg" />
</j-col> </j-col>
</j-row> </j-row>
@ -157,7 +157,7 @@ const deviceStepDetails: recommendList[] = [
linkUrl: 'device/Instance', linkUrl: 'device/Instance',
auth: devicePermission('import'), auth: devicePermission('import'),
params: { params: {
type: 'import' type: 'import',
}, },
}, },
]; ];
@ -227,17 +227,4 @@ const opsStepDetails: recommendList[] = [
const productDialogVisible = ref(false); const productDialogVisible = ref(false);
const deviceDialogVisible = ref(false); const deviceDialogVisible = ref(false);
// ---- {save:true}
// ----- {id: 'xxxx', tab:'xxx'}
// ---- {save: true}
// ----
// ----
// -----
// ----
</script> </script>

View File

@ -46,9 +46,6 @@ const opsBootConfig: bootConfig[] = [
english: 'STEP3', english: 'STEP3',
label: '实时监控', label: '实时监控',
link: 'link/DashBoard', link: 'link/DashBoard',
params: {
type: 'add',
},
}, },
]; ];
const opsStepDetails: recommendList[] = [ const opsStepDetails: recommendList[] = [

View File

@ -38,7 +38,9 @@ const props = defineProps({
// //
const jumpPage = (row: recommendList) => { const jumpPage = (row: recommendList) => {
if (row.auth === false) return message.warning('暂无权限,请联系管理员'); if (row.auth === false) {
return message.warning('暂无权限,请联系管理员');
}
row.onClick ? row.onClick(row) : _jumpPage(row.linkUrl, row.params); row.onClick ? row.onClick(row) : _jumpPage(row.linkUrl, row.params);
}; };
</script> </script>

View File

@ -52,7 +52,9 @@ const props = defineProps<{
// //
const confirm = () => { const confirm = () => {
if (selectedKeys.value.length < 1) return message.warn('请选择设备'); if (selectedKeys.value.length < 1) {
return message.warn('请选择设备');
}
emits('confirm', selectedKeys.value[0]); emits('confirm', selectedKeys.value[0]);
emits('update:visible', false); emits('update:visible', false);
}; };

View File

@ -46,8 +46,8 @@ const form = ref({
const productList = ref<[productItem] | []>([]); const productList = ref<[productItem] | []>([]);
const getOptions = () => { const getOptions = () => {
getProductList_api().then((resp: any) => { getProductList_api().then(({ result }: any) => {
productList.value = resp.result productList.value = result
.filter((i: any) => !i?.accessId) .filter((i: any) => !i?.accessId)
.map((item: { name: any; id: any }) => ({ .map((item: { name: any; id: any }) => ({
label: item.name, label: item.name,

View File

@ -1,6 +1,6 @@
<template> <template>
<page-container> <page-container>
<div class="iot-home-container" v-loading="loading"> <div class="iot-home-container">
<InitHome v-if="currentView === 'init'" @refresh="setCurrentView" /> <InitHome v-if="currentView === 'init'" @refresh="setCurrentView" />
<DeviceHome v-else-if="currentView === 'device'" /> <DeviceHome v-else-if="currentView === 'device'" />
<DevOpsHome v-else-if="currentView === 'ops'" /> <DevOpsHome v-else-if="currentView === 'ops'" />
@ -54,25 +54,26 @@ import { getMe_api, getView_api } from '@/api/home';
import { getAppInfo_api } from '@/api/system/apply'; import { getAppInfo_api } from '@/api/system/apply';
const currentView = ref<string>(''); const currentView = ref<string>('');
const loading = ref<boolean>(true);
const clientId = useUserInfo().$state.userInfos.id; const clientId = useUserInfo().$state.userInfos.id;
const secureKey = ref<string>(''); const secureKey = ref<string>('');
const showKey = ref(false); const showKey = ref(false);
// //
const setCurrentView = () => { const setCurrentView = () => {
getView_api().then((resp: any) => { getView_api().then(({ status, result }: any) => {
if (resp.status === 200) { if (status === 200) {
if (resp.result) { currentView.value = 'init';
if (resp.result.username === 'admin') if (result) {
currentView.value = 'comprehensive'; currentView.value =
else currentView.value = resp.result?.content; result.username === 'admin'
} else currentView.value = 'init'; ? 'comprehensive'
: result?.content;
}
} }
}); });
}; };
if (isNoCommunity) { if (isNoCommunity) {
// api // api
getMe_api().then((resp: any) => { getMe_api().then((resp: any) => {
if (resp && resp.status === 200) { if (resp && resp.status === 200) {
const isApiUser = resp.result.dimensions.find( const isApiUser = resp.result.dimensions.find(
@ -85,10 +86,14 @@ if (isNoCommunity) {
getAppInfo_api(clientId).then((resp: any) => { getAppInfo_api(clientId).then((resp: any) => {
secureKey.value = resp.result.apiServer.secureKey; secureKey.value = resp.result.apiServer.secureKey;
}); });
} else setCurrentView(); } else {
setCurrentView();
}
} }
}); });
} else setCurrentView(); } else {
setCurrentView();
}
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

View File

@ -39,21 +39,27 @@
v-if='showDouble' v-if='showDouble'
icon='icon-canshu' icon='icon-canshu'
placeholder='参数值' placeholder='参数值'
value-name='id'
label-name='name'
:options='valueOptions' :options='valueOptions'
:metricOptions='metricOption' :metricOptions='columnOptions'
:tabsOptions='tabsOptions' :tabsOptions='tabsOptions'
v-model:value='paramsValue.value.value' v-model:value='paramsValue.value.value'
v-model:source='paramsValue.value.source' v-model:source='paramsValue.value.source'
@select='valueSelect'
/> />
<ParamsDropdown <ParamsDropdown
v-else v-else
icon='icon-canshu' icon='icon-canshu'
placeholder='参数值' placeholder='参数值'
value-name='id'
label-name='name'
:options='valueOptions' :options='valueOptions'
:metricOptions='metricOption' :metricOptions='columnOptions'
:tabsOptions='tabsOptions' :tabsOptions='tabsOptions'
v-model:value='paramsValue.value.value' v-model:value='paramsValue.value.value'
v-model:source='paramsValue.value.source' v-model:source='paramsValue.value.source'
@select='valueSelect'
/> />
<j-popconfirm title='确认删除?' @confirm='onDelete'> <j-popconfirm title='确认删除?' @confirm='onDelete'>
<div v-show='showDelete' class='button-delete'> <AIcon type='CloseOutlined' /></div> <div v-show='showDelete' class='button-delete'> <AIcon type='CloseOutlined' /></div>
@ -74,7 +80,6 @@ import DropdownButton from '../../components/DropdownButton'
import { getOption } from '../../components/DropdownButton/util' import { getOption } from '../../components/DropdownButton/util'
import ParamsDropdown, { DoubleParamsDropdown } from '../../components/ParamsDropdown' import ParamsDropdown, { DoubleParamsDropdown } from '../../components/ParamsDropdown'
import { inject } from 'vue' import { inject } from 'vue'
import { ContextKey } from '../../components/Terms/util'
import { useSceneStore } from 'store/scene' import { useSceneStore } from 'store/scene'
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
@ -112,7 +117,7 @@ const props = defineProps({
type: Number, type: Number,
default: 0 default: 0
}, },
branchName: { actionName: {
type: Number, type: Number,
default: 0 default: 0
}, },
@ -120,6 +125,10 @@ const props = defineProps({
type: Number, type: Number,
default: 0 default: 0
}, },
branchName: {
type: Number,
default: 0
},
value: { value: {
type: Object as PropType<TermsType>, type: Object as PropType<TermsType>,
default: () => ({ default: () => ({
@ -147,24 +156,19 @@ const showDelete = ref(false)
const columnOptions: any = inject('filter-params') // const columnOptions: any = inject('filter-params') //
const termTypeOptions = ref<Array<{ id: string, name: string}>>([]) // const termTypeOptions = ref<Array<{ id: string, name: string}>>([]) //
const valueOptions = ref<any[]>([]) // const valueOptions = ref<any[]>([]) //
const metricOption = ref<any[]>([]) // const arrayParamsKey = ['nbtw', 'btw', 'in', 'nin']
const tabsOptions = ref<Array<TabsOption>>([{ label: '内置参数', key: 'upper', component: 'tree' }])
// { label: '', key: 'fixed', component: 'string' },
const tabsOptions = ref<Array<TabsOption>>(
[
{ label: '手动输入', key: 'fixed', component: 'string' },
{ label: '内置参数', key: 'upper', component: 'tree' }
]
)
const handOptionByColumn = (option: any) => { const handOptionByColumn = (option: any) => {
if (option) { if (option) {
termTypeOptions.value = option.termTypes || [] termTypeOptions.value = option.termTypes || []
metricOption.value = option.metrics || []
tabsOptions.value.length = 1
tabsOptions.value[0].component = option.dataType tabsOptions.value[0].component = option.dataType
if (option.metrics && option.metrics.length) {
tabsOptions.value.push(
{ label: '指标值', key: 'metric', component: 'select' }
)
}
if (option.dataType === 'boolean') { if (option.dataType === 'boolean') {
valueOptions.value = [ valueOptions.value = [
{ label: '是', value: true }, { label: '是', value: true },
@ -177,24 +181,17 @@ const handOptionByColumn = (option: any) => {
} }
} else { } else {
termTypeOptions.value = [] termTypeOptions.value = []
metricOption.value = []
valueOptions.value = [] valueOptions.value = []
} }
} }
watchEffect(() => { watchEffect(() => {
const option = getOption(columnOptions.value, paramsValue.column, 'id') const option = getOption(columnOptions.value, paramsValue.column, 'id')
console.log(option)
handOptionByColumn(option) handOptionByColumn(option)
}) })
const showDouble = computed(() => { const showDouble = computed(() => {
const isRange = paramsValue.termType ? ['nbtw', 'btw', 'in', 'nin'].includes(paramsValue.termType) : false const isRange = paramsValue.termType ? arrayParamsKey.includes(paramsValue.termType) : false
if (metricOption.value.length) {
metricOption.value = metricOption.value.filter(item => isRange ? item.range : !item.range)
} else {
metricOption.value = []
}
return isRange return isRange
}) })
@ -219,14 +216,19 @@ const columnSelect = () => {
emit('update:value', { ...paramsValue }) emit('update:value', { ...paramsValue })
} }
const termsTypeSelect = () => { const termsTypeSelect = (e: { key: string }) => {
const value = arrayParamsKey.includes(e.key) ? [ undefined, undefined ] : undefined
paramsValue.value = { paramsValue.value = {
source: tabsOptions.value[0].key, source: tabsOptions.value[0].key,
value: undefined value: value
} }
emit('update:value', { ...paramsValue }) emit('update:value', { ...paramsValue })
} }
const valueSelect = () => {
emit('update:value', { ...paramsValue })
}
const termAdd = () => { const termAdd = () => {
const terms = { const terms = {
column: undefined, column: undefined,
@ -238,11 +240,11 @@ const termAdd = () => {
type: 'and', type: 'and',
key: `params_${new Date().getTime()}` key: `params_${new Date().getTime()}`
} }
formModel.value.branches?.[props.branchName]?.then?.[props.thenName]?.actions?.[props.name].terms?.push(terms) formModel.value.branches?.[props.branchName]?.then?.[props.thenName]?.actions?.[props.actionName].terms?.[props.termsName].terms?.push(terms)
} }
const onDelete = () => { const onDelete = () => {
formModel.value.branches?.[props.branchName]?.then?.[props.thenName]?.actions?.[props.name].terms?.splice(props.name, 1) formModel.value.branches?.[props.branchName]?.then?.[props.thenName]?.actions?.[props.actionName].terms?.[props.termsName].terms?.splice(props.name, 1)
} }
nextTick(() => { nextTick(() => {

View File

@ -42,7 +42,7 @@
/> />
</j-form-item> </j-form-item>
</div> </div>
<div v-if='isLast' class='terms-group-add'> <div v-if='isLast' class='terms-group-add' @click='addTerms'>
<div class='terms-content'> <div class='terms-content'>
<AIcon type='PlusOutlined' style='font-size: 12px;padding-right: 4px;' /> <AIcon type='PlusOutlined' style='font-size: 12px;padding-right: 4px;' />
<span>分组</span> <span>分组</span>
@ -53,22 +53,20 @@
</template> </template>
<script setup lang='ts' name='FilterGroup'> <script setup lang='ts' name='FilterGroup'>
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia'
import { useSceneStore } from 'store/scene' import { useSceneStore } from 'store/scene'
import DropdownButton from '../../components/DropdownButton' import DropdownButton from '../../components/DropdownButton'
import FilterItem from './FilterCondition.vue' import FilterItem from './FilterCondition.vue'
import { isArray } from 'lodash-es' import { isArray } from 'lodash-es'
import { queryBuiltInParams } from '@/api/rule-engine/scene'
import { provide } from 'vue' import { provide } from 'vue'
import { randomString } from '@/utils/utils'
import { useParams } from '@/views/rule-engine/Scene/Save/util'
const sceneStore = useSceneStore() const sceneStore = useSceneStore()
const { data: formModel } = storeToRefs(sceneStore) const { data: formModel } = storeToRefs(sceneStore)
const columnOptions = ref<any>([])
provide('filter-params', columnOptions)
const props = defineProps({ const props = defineProps({
isFirst: { isFirst: {
type: Boolean, type: Boolean,
@ -100,6 +98,16 @@ const props = defineProps({
} }
}) })
const { columnOptions } = useParams({
branch: props.branchName,
branchGroup: props.thenName,
action: props.actionName
}, [
formModel.value.branches![props.branchName].then[props.thenName].actions[props.actionName]
])
provide('filter-params', columnOptions)
const termsOptions = computed(() => { const termsOptions = computed(() => {
return formModel.value.branches![props.branchName].then[props.thenName].actions[props.actionName].terms?.[props.name].terms return formModel.value.branches![props.branchName].then[props.thenName].actions[props.actionName].terms?.[props.name].terms
}) })
@ -114,66 +122,80 @@ const mouseout = () => {
showDelete.value = false showDelete.value = false
} }
const onDelete = () => { const addTerms = () => {
const item: any = {
type: 'and',
key: randomString(),
terms: [
{
column: undefined,
value: {
type: 'fixed',
value: undefined
},
termType: undefined,
type: 'and',
key: randomString()
}
]
}
formModel.value
.branches![props.branchName]
.then[props.thenName]
.actions[props.actionName]
.terms?.push(item)
} }
const getParams = () => { const onDelete = () => {
const params = { formModel.value
branch: props.branchName, .branches![props.branchName]
branchGroup: props.thenName, .then[props.thenName]
action: props.actionName .actions[props.actionName]
} .terms?.splice(props.name, 1)
const data = formModel.value.branches!.filter(item => !!item)
queryBuiltInParams({
...formModel.value,
branches: data,
}, params).then(res => {
if (res.success) {
columnOptions.value = res.result
}
})
} }
const rules = [ const rules = [
{ {
validator(_: any, v?: Record<string, any>) { validator(_: any, v?: Record<string, any>) {
// console.log('-----v',v) console.log('-----v',v)
if (v !== undefined) { if (v !== undefined) {
if (!Object.keys(v).length) { if (!Object.keys(v).length) {
return Promise.reject(new Error('该数据已发生变更,请重新配置')); return Promise.reject(new Error('该数据已发生变更,请重新配置'))
} }
if (!v.column) { if (!v.column) {
return Promise.reject(new Error('请选择参数')); return Promise.reject(new Error('请选择参数'))
} }
if (!v.termType) { if (!v.termType) {
return Promise.reject(new Error('请选择操作符')); return Promise.reject(new Error('请选择操作符'))
} }
if (v.value === undefined) { if (v.value === undefined) {
return Promise.reject(new Error('请选择或输入参数值')); return Promise.reject(new Error('请选择或输入参数值'))
} else { } else {
if ( if (
isArray(v.value.value) && isArray(v.value.value) &&
v.value.value.some((_v: any) => _v === undefined) v.value.value.some((_v: any) => _v === undefined)
) { ) {
return Promise.reject(new Error('请选择或输入参数值')); return Promise.reject(new Error('请选择或输入参数值'))
} else if (v.value.value === undefined) { } else if (v.value.value === undefined) {
return Promise.reject(new Error('请选择或输入参数值')); return Promise.reject(new Error('请选择或输入参数值'))
} }
} }
} else { } else {
return Promise.reject(new Error('请选择参数')); return Promise.reject(new Error('请选择参数'))
} }
return Promise.resolve(); return Promise.resolve()
}, }
}, }
] ]
nextTick(() => { // watchEffect(() => {
getParams() // if (formModel.value.branches![props.branchName].then[props.thenName].actions[props.actionName]) {
}) // getParams()
// }
// })
</script> </script>

View File

@ -630,32 +630,6 @@ watch(() => props.data, () => {
align-items: baseline; align-items: baseline;
} }
//.terms-params-content {
// position: relative;
// display: flex;
// background-color: #fafafa;
// border: unset;
// row-gap: 16px;
//
// &.no-border {
// border: none;
// }
//
// .terms-params-item {
// display: flex;
// align-items: center;
// }
//
// .ant-form-item {
// margin-bottom: 8px;
// &:not(:first-child) {
// .ant-form-item-explain-error {
// padding-left: 80px !important;
// }
// }
// }
//}
.term-type-warp { .term-type-warp {
// display: inline-block; // display: inline-block;
width: 50px; width: 50px;

View File

@ -2,6 +2,8 @@
<ParamsDropdown <ParamsDropdown
v-model:value='myValue[0]' v-model:value='myValue[0]'
v-model:source='mySource' v-model:source='mySource'
:valueName='valueName'
:labelName='labelName'
:options='options' :options='options'
:icon='icon' :icon='icon'
:placeholder='placeholder' :placeholder='placeholder'
@ -12,6 +14,8 @@
<ParamsDropdown <ParamsDropdown
v-model:value='myValue[1]' v-model:value='myValue[1]'
v-model:source='mySource' v-model:source='mySource'
:valueName='valueName'
:labelName='labelName'
:icon='icon' :icon='icon'
:placeholder='placeholder' :placeholder='placeholder'
:tabs-options='tabsOptions' :tabs-options='tabsOptions'

View File

@ -81,7 +81,7 @@ import ValueItem from '@/components/ValueItem/index.vue'
import type { ValueType } from './typings' import type { ValueType } from './typings'
import { defaultSetting } from './typings' import { defaultSetting } from './typings'
import { DropdownMenus, DropdownTimePicker} from '../DropdownButton' import { DropdownMenus, DropdownTimePicker} from '../DropdownButton'
import { getComponent, getOption } from '../DropdownButton/util' import { getOption } from '../DropdownButton/util'
type Emit = { type Emit = {
(e: 'update:value', data: ValueType): void (e: 'update:value', data: ValueType): void
@ -109,29 +109,26 @@ nextTick(() => {
const tabsChange = (e: string) => { const tabsChange = (e: string) => {
mySource.value = e mySource.value = e
myValue.value = undefined myValue.value = undefined
}
const updateValue = () => {
emit('update:source', mySource.value) emit('update:source', mySource.value)
emit('update:value', myValue.value) emit('update:value', undefined)
emit('select', {})
} }
const treeSelect = (e: any) => { const treeSelect = (v: any, option: any) => {
const node = option.node
visible.value = false visible.value = false
label.value = e.fullname || e.name label.value = node.fullname || node.name
emit('update:value', e[props.valueName]) emit('update:value', node[props.valueName])
emit('select', e) emit('select', node)
} }
const valueItemChange = (e: string) => { const valueItemChange = (e: string) => {
console.log('valueItemSelect', e)
label.value = e label.value = e
emit('update:value', e) emit('update:value', e)
emit('select', e) emit('select', e)
} }
const onSelect = (e: string, option: any) => { const onSelect = (e: string, option: any) => {
console.log(e, option)
visible.value = false visible.value = false
label.value = option.label label.value = option.label
emit('update:value', e) emit('update:value', e)
@ -150,7 +147,8 @@ const visibleChange = (v: boolean) => {
} }
watchEffect(() => { watchEffect(() => {
const option = getOption(props.options, props.value as string, props.valueName) // label const _options = props.source === 'upper' ? props.metricOptions : props.options
const option = getOption(_options, props.value as string, props.valueName) // label
myValue.value = props.value myValue.value = props.value
mySource.value = props.source mySource.value = props.source
if (option) { if (option) {

View File

@ -149,6 +149,7 @@ const termTypeOptions = ref<Array<{ id: string, name: string}>>([]) // 条件值
const valueOptions = ref<any[]>([]) // const valueOptions = ref<any[]>([]) //
const metricOption = ref<any[]>([]) // termType const metricOption = ref<any[]>([]) // termType
const tabsOptions = ref<Array<TabsOption>>([{ label: '手动输入', key: 'manual', component: 'string' }]) const tabsOptions = ref<Array<TabsOption>>([{ label: '手动输入', key: 'manual', component: 'string' }])
const arrayParamsKey = ['nbtw', 'btw', 'in', 'nin']
let metricsCacheOption: any[] = [] // let metricsCacheOption: any[] = [] //
const handOptionByColumn = (option: any) => { const handOptionByColumn = (option: any) => {
@ -187,7 +188,7 @@ watchEffect(() => {
}) })
const showDouble = computed(() => { const showDouble = computed(() => {
const isRange = paramsValue.termType ? ['nbtw', 'btw', 'in', 'nin'].includes(paramsValue.termType) : false const isRange = paramsValue.termType ? arrayParamsKey.includes(paramsValue.termType) : false
if (metricsCacheOption.length) { if (metricsCacheOption.length) {
metricOption.value = metricsCacheOption.filter(item => isRange ? item.range : !item.range) metricOption.value = metricsCacheOption.filter(item => isRange ? item.range : !item.range)
} else { } else {
@ -217,10 +218,11 @@ const columnSelect = () => {
emit('update:value', { ...paramsValue }) emit('update:value', { ...paramsValue })
} }
const termsTypeSelect = () => { const termsTypeSelect = (e: { key: string }) => {
const value = arrayParamsKey.includes(e.key) ? [ undefined, undefined ] : undefined
paramsValue.value = { paramsValue.value = {
source: tabsOptions.value[0].key, source: tabsOptions.value[0].key,
value: undefined value: value
} }
emit('update:value', { ...paramsValue }) emit('update:value', { ...paramsValue })
} }

View File

@ -47,7 +47,7 @@ import { storeToRefs } from 'pinia';
import { useSceneStore } from 'store/scene' import { useSceneStore } from 'store/scene'
import { cloneDeep } from 'lodash-es' import { cloneDeep } from 'lodash-es'
import { provide } from 'vue' import { provide } from 'vue'
import { ContextKey } from './util' import { ContextKey, handleParamsData } from './util'
import { getParseTerm } from '@/api/rule-engine/scene' import { getParseTerm } from '@/api/rule-engine/scene'
import type { FormModelType } from '@/views/rule-engine/Scene/typings' import type { FormModelType } from '@/views/rule-engine/Scene/typings'
import Branches from './Branchs.vue' import Branches from './Branchs.vue'
@ -65,17 +65,6 @@ const change = (e: boolean) => {
open.value = e open.value = e
} }
const handleParamsData = (data: any[]): any[] => {
return data?.map(item => {
return {
...item,
key: item.column,
disabled: !!item.children,
children: handleParamsData(item.children)
}
}) || []
}
const queryColumn = (dataModel: FormModelType) => { const queryColumn = (dataModel: FormModelType) => {
const cloneDevice = cloneDeep(dataModel) const cloneDevice = cloneDeep(dataModel)
cloneDevice.branches = cloneDevice.branches?.filter(item => !!item) cloneDevice.branches = cloneDevice.branches?.filter(item => !!item)

View File

@ -1 +1,12 @@
export const ContextKey = 'columnOptions' export const ContextKey = 'columnOptions'
export const handleParamsData = (data: any[], key: string = 'column'): any[] => {
return data?.map(item => {
return {
...item,
key: item[key],
disabled: !!item.children,
children: handleParamsData(item.children, key)
}
}) || []
}

View File

@ -0,0 +1,49 @@
import { queryBuiltInParams } from '@/api/rule-engine/scene'
import { handleParamsData } from './components/Terms/util'
import { useSceneStore } from 'store/scene'
import { storeToRefs } from 'pinia'
import type { FormModelType } from '@/views/rule-engine/Scene/typings'
interface Params {
branch: number
branchGroup: number
action: number
}
export const getParams = (params: Params, sceneModel: FormModelType): Promise<any[]> => {
return new Promise(res => {
const data = sceneModel.branches!.filter(item => !!item)
queryBuiltInParams({
...sceneModel,
branches: data
}, params).then(resp => {
if (resp.success) {
res(resp.result as any[])
}
})
})
}
/**
* @param params
*/
export const useParams = (params: Params, effect: any[] = []) => {
const sceneStore = useSceneStore()
const { data: formModel } = storeToRefs(sceneStore)
const columnOptions = ref<any[]>([])
const handleParams = async () => {
const _data = await getParams(params, formModel.value)
columnOptions.value = handleParamsData(_data, 'id')
}
watchEffect(() => {
if (effect[0]) {
handleParams()
}
})
return {
columnOptions
}
}