Merge branch 'dev' of github.com:jetlinks/jetlinks-ui-vue into dev
This commit is contained in:
commit
4d7b1e60f2
|
|
@ -5,6 +5,7 @@
|
||||||
<%- favicon %>
|
<%- favicon %>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title><%- title %></title>
|
<title><%- title %></title>
|
||||||
|
<script src="/js/liveplayer-lib.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -13,6 +13,7 @@
|
||||||
"prepare": "husky install"
|
"prepare": "husky install"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@liveqing/liveplayer-v3": "^3.7.10",
|
||||||
"@types/marked": "^4.0.8",
|
"@types/marked": "^4.0.8",
|
||||||
"@vitejs/plugin-vue-jsx": "^3.0.0",
|
"@vitejs/plugin-vue-jsx": "^3.0.0",
|
||||||
"@vuemap/vue-amap": "^1.1.20",
|
"@vuemap/vue-amap": "^1.1.20",
|
||||||
|
|
@ -34,6 +35,7 @@
|
||||||
"monaco-editor": "^0.36.0",
|
"monaco-editor": "^0.36.0",
|
||||||
"nrm": "^1.2.5",
|
"nrm": "^1.2.5",
|
||||||
"pinia": "^2.0.28",
|
"pinia": "^2.0.28",
|
||||||
|
"rollup-plugin-copy": "^3.4.0",
|
||||||
"unplugin-auto-import": "^0.12.1",
|
"unplugin-auto-import": "^0.12.1",
|
||||||
"unplugin-vue-components": "^0.22.12",
|
"unplugin-vue-components": "^0.22.12",
|
||||||
"v-clipboard3": "^0.1.4",
|
"v-clipboard3": "^0.1.4",
|
||||||
|
|
@ -43,8 +45,7 @@
|
||||||
"vue-router": "^4.1.6",
|
"vue-router": "^4.1.6",
|
||||||
"vue3-json-viewer": "^2.2.2",
|
"vue3-json-viewer": "^2.2.2",
|
||||||
"vue3-markdown-it": "^1.0.10",
|
"vue3-markdown-it": "^1.0.10",
|
||||||
"vue3-ts-jsoneditor": "^2.7.1",
|
"vue3-ts-jsoneditor": "^2.7.1"
|
||||||
"vue3-video-play": "^1.3.1-beta.6"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^17.4.1",
|
"@commitlint/cli": "^17.4.1",
|
||||||
|
|
|
||||||
|
|
@ -8,213 +8,214 @@ export interface IMatcher {
|
||||||
const matchComponents: IMatcher[] = [
|
const matchComponents: IMatcher[] = [
|
||||||
{
|
{
|
||||||
pattern: /^Avatar/,
|
pattern: /^Avatar/,
|
||||||
styleDir: 'Avatar',
|
styleDir: 'Avatar'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^AutoComplete/,
|
pattern: /^AutoComplete/,
|
||||||
styleDir: 'AutoComplete',
|
styleDir: 'AutoComplete'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Anchor/,
|
pattern: /^Anchor/,
|
||||||
styleDir: 'Anchor',
|
styleDir: 'Anchor'
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
pattern: /^Badge/,
|
pattern: /^Badge/,
|
||||||
styleDir: 'Badge',
|
styleDir: 'Badge'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Breadcrumb/,
|
pattern: /^Breadcrumb/,
|
||||||
styleDir: 'Breadcrumb',
|
styleDir: 'Breadcrumb'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Button/,
|
pattern: /^Button/,
|
||||||
styleDir: 'Button',
|
styleDir: 'Button'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Checkbox/,
|
pattern: /^Checkbox/,
|
||||||
styleDir: 'Checkbox',
|
styleDir: 'Checkbox'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: /^CardSelect/,
|
||||||
|
styleDir: 'CardSelect'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Card/,
|
pattern: /^Card/,
|
||||||
styleDir: 'Card',
|
styleDir: 'Card'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Collapse/,
|
pattern: /^Collapse/,
|
||||||
styleDir: 'Collapse',
|
styleDir: 'Collapse'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Descriptions/,
|
pattern: /^Descriptions/,
|
||||||
styleDir: 'Descriptions',
|
styleDir: 'Descriptions'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^RangePicker|^WeekPicker|^MonthPicker/,
|
pattern: /^RangePicker|^WeekPicker|^MonthPicker/,
|
||||||
styleDir: 'DatePicker',
|
styleDir: 'DatePicker'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Dropdown/,
|
pattern: /^Dropdown/,
|
||||||
styleDir: 'Dropdown',
|
styleDir: 'Dropdown'
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
pattern: /^Form/,
|
pattern: /^Form/,
|
||||||
styleDir: 'Form',
|
styleDir: 'Form'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^InputNumber/,
|
pattern: /^InputNumber/,
|
||||||
styleDir: 'InputNumber',
|
styleDir: 'InputNumber'
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
pattern: /^Input|^Textarea/,
|
pattern: /^Input|^Textarea/,
|
||||||
styleDir: 'Input',
|
styleDir: 'Input'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Statistic/,
|
pattern: /^Statistic/,
|
||||||
styleDir: 'Statistic',
|
styleDir: 'Statistic'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^CheckableTag/,
|
pattern: /^CheckableTag/,
|
||||||
styleDir: 'Tag',
|
styleDir: 'Tag'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^TimeRangePicker/,
|
pattern: /^TimeRangePicker/,
|
||||||
styleDir: 'TimePicker',
|
styleDir: 'TimePicker'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Layout/,
|
pattern: /^Layout/,
|
||||||
styleDir: 'Layout',
|
styleDir: 'Layout'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Menu|^SubMenu/,
|
pattern: /^Menu|^SubMenu/,
|
||||||
styleDir: 'Menu',
|
styleDir: 'Menu'
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
pattern: /^Table/,
|
pattern: /^Table/,
|
||||||
styleDir: 'Table',
|
styleDir: 'Table'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^TimePicker|^TimeRangePicker/,
|
pattern: /^TimePicker|^TimeRangePicker/,
|
||||||
styleDir: 'TimeTicker',
|
styleDir: 'TimeTicker'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Radio/,
|
pattern: /^Radio/,
|
||||||
styleDir: 'Radio',
|
styleDir: 'Radio'
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
pattern: /^Image/,
|
pattern: /^Image/,
|
||||||
styleDir: 'Image',
|
styleDir: 'Image'
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
pattern: /^List/,
|
pattern: /^List/,
|
||||||
styleDir: 'List',
|
styleDir: 'List'
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
pattern: /^Tab/,
|
pattern: /^Tab/,
|
||||||
styleDir: 'Tabs',
|
styleDir: 'Tabs'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Mentions/,
|
pattern: /^Mentions/,
|
||||||
styleDir: 'Mentions',
|
styleDir: 'Mentions'
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
pattern: /^Step/,
|
pattern: /^Step/,
|
||||||
styleDir: 'Steps',
|
styleDir: 'Steps'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Skeleton/,
|
pattern: /^Skeleton/,
|
||||||
styleDir: 'Skeleton',
|
styleDir: 'Skeleton'
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
pattern: /^Select/,
|
pattern: /^Select/,
|
||||||
styleDir: 'Select',
|
styleDir: 'Select'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^TreeSelect/,
|
pattern: /^TreeSelect/,
|
||||||
styleDir: 'TreeSelect',
|
styleDir: 'TreeSelect'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Tree|^DirectoryTree/,
|
pattern: /^Tree|^DirectoryTree/,
|
||||||
styleDir: 'Tree',
|
styleDir: 'Tree'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Typography/,
|
pattern: /^Typography/,
|
||||||
styleDir: 'Typography',
|
styleDir: 'Typography'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Timeline/,
|
pattern: /^Timeline/,
|
||||||
styleDir: 'Timeline',
|
styleDir: 'Timeline'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Upload/,
|
pattern: /^Upload/,
|
||||||
styleDir: 'Upload',
|
styleDir: 'Upload'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^ProTable/,
|
pattern: /^ProTable/,
|
||||||
styleDir: 'ProTable',
|
styleDir: 'ProTable'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Search|^AdvancedSearch/,
|
pattern: /^Search|^AdvancedSearch/,
|
||||||
styleDir: 'Search',
|
styleDir: 'Search'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Ellipsis/,
|
pattern: /^Ellipsis/,
|
||||||
styleDir: 'Ellipsis',
|
styleDir: 'Ellipsis'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^MonacoEditor/,
|
pattern: /^MonacoEditor/,
|
||||||
styleDir: 'MonacoEditor',
|
styleDir: 'MonacoEditor'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^ProLayout/,
|
pattern: /^ProLayout/,
|
||||||
styleDir: 'ProLayout',
|
styleDir: 'ProLayout'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^ScrollTable/,
|
pattern: /^ScrollTable/,
|
||||||
styleDir: 'ScrollTable',
|
styleDir: 'ScrollTable'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^TableCard/,
|
pattern: /^TableCard/,
|
||||||
styleDir: 'TableCard',
|
styleDir: 'TableCard'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Scrollbar/,
|
pattern: /^Scrollbar/,
|
||||||
styleDir: 'Scrollbar',
|
styleDir: 'Scrollbar'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^AIcon/,
|
pattern: /^AIcon/,
|
||||||
styleDir: 'AIcon',
|
styleDir: 'AIcon'
|
||||||
},
|
|
||||||
{
|
|
||||||
pattern: /^CardSelect/,
|
|
||||||
styleDir: 'CardSelect',
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
pattern: /^Tooltip/,
|
pattern: /^Tooltip/,
|
||||||
styleDir: 'Tooltip',
|
styleDir: 'Tooltip'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Empty/,
|
pattern: /^Empty/,
|
||||||
styleDir: 'Empty',
|
styleDir: 'Empty'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Popconfirm/,
|
pattern: /^Popconfirm/,
|
||||||
styleDir: 'Popconfirm',
|
styleDir: 'Popconfirm'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^message/,
|
pattern: /^message/,
|
||||||
styleDir: 'Message',
|
styleDir: 'Message'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^Notification/,
|
pattern: /^Notification/,
|
||||||
styleDir: 'Notification',
|
styleDir: 'Notification'
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
export interface JetlinksVueResolverOptions {
|
export interface JetlinksVueResolverOptions {
|
||||||
|
|
@ -259,7 +260,6 @@ function getStyleDir(compName: string, _isAntd = false): string {
|
||||||
let styleDir
|
let styleDir
|
||||||
const components = _isAntd ? AntdMatchComponents : matchComponents
|
const components = _isAntd ? AntdMatchComponents : matchComponents
|
||||||
const total = components.length
|
const total = components.length
|
||||||
console.log('getStyleDir', compName)
|
|
||||||
for (let i = 0; i < total; i++) {
|
for (let i = 0; i < total; i++) {
|
||||||
const matcher = components[i]
|
const matcher = components[i]
|
||||||
if (compName.match(matcher.pattern)) {
|
if (compName.match(matcher.pattern)) {
|
||||||
|
|
@ -273,10 +273,10 @@ function getStyleDir(compName: string, _isAntd = false): string {
|
||||||
return styleDir
|
return styleDir
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSideEffects(compName: string, options: JetlinksVueResolverOptions, _isAntd= false): any {
|
function getSideEffects(compName: string, options: JetlinksVueResolverOptions, _isAntd = false): any {
|
||||||
const {
|
const {
|
||||||
importStyle = true,
|
importStyle = true,
|
||||||
importLess = false,
|
importLess = false
|
||||||
} = options
|
} = options
|
||||||
|
|
||||||
if (!importStyle)
|
if (!importStyle)
|
||||||
|
|
@ -286,23 +286,21 @@ function getSideEffects(compName: string, options: JetlinksVueResolverOptions, _
|
||||||
|
|
||||||
if (importStyle === 'less' || importLess) {
|
if (importStyle === 'less' || importLess) {
|
||||||
const styleDir = getStyleDir(compName, _isAntd)
|
const styleDir = getStyleDir(compName, _isAntd)
|
||||||
console.log('getSideEffects-style-path', `${packageName}/${lib}/${styleDir}/style`)
|
|
||||||
return `${packageName}/${lib}/${styleDir}/style`
|
return `${packageName}/${lib}/${styleDir}/style`
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
const styleDir = getStyleDir(compName, _isAntd)
|
const styleDir = getStyleDir(compName, _isAntd)
|
||||||
return `${packageName}/${lib}/${styleDir}/style/css`
|
return `${packageName}/${lib}/${styleDir}/style/css`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const filterName = [ 'message', 'Notification', 'AIcon']
|
const filterName = ['message', 'Notification', 'AIcon']
|
||||||
const primitiveNames = ['Affix', 'Anchor', 'AnchorLink', 'message', 'Notification', 'AutoComplete', 'AutoCompleteOptGroup', 'AutoCompleteOption', 'Alert', 'Avatar', 'AvatarGroup', 'BackTop', 'Badge', 'BadgeRibbon', 'Breadcrumb', 'BreadcrumbItem', 'BreadcrumbSeparator', 'Button', 'ButtonGroup', 'Calendar', 'Card', 'CardGrid', 'CardMeta', 'Collapse', 'CollapsePanel', 'Carousel', 'Cascader', 'Checkbox', 'CheckboxGroup', 'Col', 'Comment', 'ConfigProvider', 'DatePicker', 'MonthPicker', 'WeekPicker', 'RangePicker', 'QuarterPicker', 'Descriptions', 'DescriptionsItem', 'Divider', 'Dropdown', 'DropdownButton', 'Drawer', 'Empty', 'Form', 'FormItem', 'FormItemRest', 'Grid', 'Input', 'InputGroup', 'InputPassword', 'InputSearch', 'Textarea', 'Image', 'ImagePreviewGroup', 'InputNumber', 'Layout', 'LayoutHeader', 'LayoutSider', 'LayoutFooter', 'LayoutContent', 'List', 'ListItem', 'ListItemMeta', 'Menu', 'MenuDivider', 'MenuItem', 'MenuItemGroup', 'SubMenu', 'Mentions', 'MentionsOption', 'Modal', 'Statistic', 'StatisticCountdown', 'PageHeader', 'Pagination', 'Popconfirm', 'Popover', 'Progress', 'Radio', 'RadioButton', 'RadioGroup', 'Rate', 'Result', 'Row', 'Select', 'SelectOptGroup', 'SelectOption', 'Skeleton', 'SkeletonButton', 'SkeletonAvatar', 'SkeletonInput', 'SkeletonImage', 'Slider', 'Space', 'Spin', 'Steps', 'Step', 'Switch', 'Table', 'TableColumn', 'TableColumnGroup', 'TableSummary', 'TableSummaryRow', 'TableSummaryCell', 'Transfer', 'Tree', 'TreeNode', 'DirectoryTree', 'TreeSelect', 'TreeSelectNode', 'Tabs', 'TabPane', 'Tag', 'CheckableTag', 'TimePicker', 'TimeRangePicker', 'Timeline', 'TimelineItem', 'Tooltip', 'Typography', 'TypographyLink', 'TypographyParagraph', 'TypographyText', 'TypographyTitle', 'Upload', 'UploadDragger', 'LocaleProvider', 'ProTable', 'Search', 'AdvancedSearch', 'Ellipsis', 'MonacoEditor', 'ProLayout', 'ScrollTable', 'TableCard', 'Scrollbar', 'CardSelect', 'ColorPicker']
|
const primitiveNames = ['Affix', 'Anchor', 'AnchorLink', 'message', 'Notification', 'AutoComplete', 'AutoCompleteOptGroup', 'AutoCompleteOption', 'Alert', 'Avatar', 'AvatarGroup', 'BackTop', 'Badge', 'BadgeRibbon', 'Breadcrumb', 'BreadcrumbItem', 'BreadcrumbSeparator', 'Button', 'ButtonGroup', 'Calendar', 'Card', 'CardGrid', 'CardMeta', 'Collapse', 'CollapsePanel', 'Carousel', 'Cascader', 'Checkbox', 'CheckboxGroup', 'Col', 'Comment', 'ConfigProvider', 'DatePicker', 'MonthPicker', 'WeekPicker', 'RangePicker', 'QuarterPicker', 'Descriptions', 'DescriptionsItem', 'Divider', 'Dropdown', 'DropdownButton', 'Drawer', 'Empty', 'Form', 'FormItem', 'FormItemRest', 'Grid', 'Input', 'InputGroup', 'InputPassword', 'InputSearch', 'Textarea', 'Image', 'ImagePreviewGroup', 'InputNumber', 'Layout', 'LayoutHeader', 'LayoutSider', 'LayoutFooter', 'LayoutContent', 'List', 'ListItem', 'ListItemMeta', 'Menu', 'MenuDivider', 'MenuItem', 'MenuItemGroup', 'SubMenu', 'Mentions', 'MentionsOption', 'Modal', 'Statistic', 'StatisticCountdown', 'PageHeader', 'Pagination', 'Popconfirm', 'Popover', 'Progress', 'Radio', 'RadioButton', 'RadioGroup', 'Rate', 'Result', 'Row', 'Select', 'SelectOptGroup', 'SelectOption', 'Skeleton', 'SkeletonButton', 'SkeletonAvatar', 'SkeletonInput', 'SkeletonImage', 'Slider', 'Space', 'Spin', 'Steps', 'Step', 'Switch', 'Table', 'TableColumn', 'TableColumnGroup', 'TableSummary', 'TableSummaryRow', 'TableSummaryCell', 'Transfer', 'Tree', 'TreeNode', 'DirectoryTree', 'TreeSelect', 'TreeSelectNode', 'Tabs', 'TabPane', 'Tag', 'CheckableTag', 'TimePicker', 'TimeRangePicker', 'Timeline', 'TimelineItem', 'Tooltip', 'Typography', 'TypographyLink', 'TypographyParagraph', 'TypographyText', 'TypographyTitle', 'Upload', 'UploadDragger', 'LocaleProvider', 'ProTable', 'Search', 'AdvancedSearch', 'Ellipsis', 'MonacoEditor', 'ProLayout', 'ScrollTable', 'TableCard', 'Scrollbar', 'CardSelect', 'ColorPicker']
|
||||||
const prefix = 'J'
|
const prefix = 'J'
|
||||||
|
|
||||||
let jetlinksNames: Set<string>
|
let jetlinksNames: Set<string>
|
||||||
|
|
||||||
function genJetlinksNames(primitiveNames: string[]): void {
|
function genJetlinksNames(primitiveNames: string[]): void {
|
||||||
jetlinksNames = new Set(primitiveNames.map(name => filterName.includes(name) ? name : `${prefix}${name}`))
|
jetlinksNames = new Set(primitiveNames.map(name => filterName.includes(name) ? name : `${prefix}${name}`))
|
||||||
}
|
}
|
||||||
|
|
||||||
let antdvNames: Set<string>
|
let antdvNames: Set<string>
|
||||||
|
|
@ -322,16 +320,14 @@ function isAntdv(compName: string): boolean {
|
||||||
return antdvNames.has(compName)
|
return antdvNames.has(compName)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function JetlinksVueResolver(options: JetlinksVueResolverOptions = {
|
export function JetlinksVueResolver(options: JetlinksVueResolverOptions = {}): any {
|
||||||
|
|
||||||
}): any {
|
|
||||||
return {
|
return {
|
||||||
type: 'component',
|
type: 'component',
|
||||||
resolve: (name: string) => {
|
resolve: (name: string) => {
|
||||||
if (options.resolveIcons && name.match(/(Outlined|Filled|TwoTone)$/)) {
|
if (options.resolveIcons && name.match(/(Outlined|Filled|TwoTone)$/)) {
|
||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
from: '@ant-design/icons-vue',
|
from: '@ant-design/icons-vue'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const _isJetlinks = isJetlinks(name)
|
const _isJetlinks = isJetlinks(name)
|
||||||
|
|
@ -340,13 +336,16 @@ export function JetlinksVueResolver(options: JetlinksVueResolverOptions = {
|
||||||
const importName = filterName.includes(name) ? name : name.slice(1)
|
const importName = filterName.includes(name) ? name : name.slice(1)
|
||||||
options.packageName = _isJetlinks ? 'jetlinks-ui-components' : 'ant-design-vue'
|
options.packageName = _isJetlinks ? 'jetlinks-ui-components' : 'ant-design-vue'
|
||||||
const path = `${options.packageName}/${options.cjs ? 'lib' : 'es'}`
|
const path = `${options.packageName}/${options.cjs ? 'lib' : 'es'}`
|
||||||
|
const stylePath = getSideEffects(importName, options, _isAntd)
|
||||||
|
if (_isJetlinks) {
|
||||||
|
console.log(name, importName, stylePath)
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
name: importName,
|
name: importName,
|
||||||
from: path,
|
from: path,
|
||||||
sideEffects: getSideEffects(importName, options, _isAntd),
|
sideEffects: stylePath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -21,4 +21,6 @@ export const _action = (id: string, type: '_disable' | '_enable') => server.put(
|
||||||
export const _execute = (id: string) => server.post(`/scene/${id}/_execute`);
|
export const _execute = (id: string) => server.post(`/scene/${id}/_execute`);
|
||||||
|
|
||||||
// 内置参数
|
// 内置参数
|
||||||
export const queryBuiltInParams = (data: any, params?: any) => server.post(`/scene/parse-variables`, data, params);
|
export const queryBuiltInParams = (data: any, params?: any) => server.post(`/scene/parse-variables`, data, params);
|
||||||
|
|
||||||
|
export const getParseTerm = (data: Record<string, any>) => server.post(`/scene/parse-term-column`, data)
|
||||||
|
|
@ -127,11 +127,7 @@
|
||||||
>
|
>
|
||||||
刷新
|
刷新
|
||||||
</div>
|
</div>
|
||||||
<LivePlayer
|
<LivePlayer :url="item.url" autoplay />
|
||||||
:src="item.url"
|
|
||||||
:width="screenWidth"
|
|
||||||
:height="screenHeight"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -192,9 +188,6 @@ const screen = ref(1);
|
||||||
const players = ref<Player[]>([]);
|
const players = ref<Player[]>([]);
|
||||||
// 当前选中的窗口
|
// 当前选中的窗口
|
||||||
const playerActive = ref(0);
|
const playerActive = ref(0);
|
||||||
// 单个播放窗口宽高
|
|
||||||
const screenWidth = ref('');
|
|
||||||
const screenHeight = ref('');
|
|
||||||
// 历史记录
|
// 历史记录
|
||||||
const historyList = ref<any[]>([]);
|
const historyList = ref<any[]>([]);
|
||||||
// 展示保存浮窗
|
// 展示保存浮窗
|
||||||
|
|
|
||||||
|
|
@ -1,50 +1,88 @@
|
||||||
<!-- 视频播放 -->
|
<!-- 视频播放 -->
|
||||||
<template>
|
<template>
|
||||||
<vue3videoPlay v-bind="options" />
|
<LivePlayer
|
||||||
|
ref="player"
|
||||||
|
fluent
|
||||||
|
:protocol="props.protocol || 'mp4'"
|
||||||
|
:class="props.className"
|
||||||
|
:loading="props.loading"
|
||||||
|
:live="'live' in props ? props.live !== false : true"
|
||||||
|
:autoplay="'autoplay' in props ? props.autoplay !== false : true"
|
||||||
|
:muted="'muted' in props ? props.muted !== false : true"
|
||||||
|
:hide-big-play-button="true"
|
||||||
|
:poster="props.poster || ''"
|
||||||
|
:timeout="props.timeout || 20"
|
||||||
|
:video-url="url || ''"
|
||||||
|
@play="props.onPlay"
|
||||||
|
@pause="props.onPause"
|
||||||
|
@ended="props.onEnded"
|
||||||
|
@error="props.onError"
|
||||||
|
@timeupdate="props.onTimeUpdate"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import 'vue3-video-play/dist/style.css';
|
import LivePlayer from '@liveqing/liveplayer-v3';
|
||||||
import vue3videoPlay from 'vue3-video-play';
|
|
||||||
|
|
||||||
const props = defineProps({
|
type PlayerProps = {
|
||||||
src: { type: String, default: '' },
|
url?: string;
|
||||||
type: { type: String, default: 'mp4' },
|
live?: boolean;
|
||||||
width: { type: String, default: '500px' },
|
autoplay?: boolean;
|
||||||
height: { type: String, default: '280px' },
|
muted?: boolean;
|
||||||
|
poster?: string;
|
||||||
|
timeout?: number;
|
||||||
|
className?: string;
|
||||||
|
updateTime?: number;
|
||||||
|
key?: string | number;
|
||||||
|
loading?: boolean;
|
||||||
|
protocol?: 'mp4' | 'flv' | 'hls';
|
||||||
|
onDestroy?: (e?: any) => void;
|
||||||
|
onMessage?: (msg: any) => void;
|
||||||
|
onError?: (err: any) => void;
|
||||||
|
onTimeUpdate?: (time: any) => void;
|
||||||
|
onPause?: (e?: any) => void;
|
||||||
|
onPlay?: (e?: any) => void;
|
||||||
|
onFullscreen?: () => void;
|
||||||
|
onSnapOutside?: (base64: any) => void;
|
||||||
|
onSnapInside?: (base64: any) => void;
|
||||||
|
onCustomButtons?: (name: any) => void;
|
||||||
|
onEnded?: (e?: any) => void;
|
||||||
|
onClick?: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const props = defineProps<PlayerProps>();
|
||||||
|
|
||||||
|
const player = ref<HTMLVideoElement>();
|
||||||
|
const url = ref(props.url);
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
url.value = props.url;
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
/**
|
||||||
() => props.src,
|
* 播放
|
||||||
(val: string) => {
|
*/
|
||||||
options.src = val;
|
const play = () => {
|
||||||
},
|
player.value?.play();
|
||||||
);
|
};
|
||||||
|
|
||||||
const options = reactive({
|
/**
|
||||||
...props,
|
* 暂停
|
||||||
color: '#409eff', //主题色
|
*/
|
||||||
title: '', //视频名称
|
const pause = () => {
|
||||||
// src: props.src,
|
player.value?.pause();
|
||||||
// type: props.type,
|
};
|
||||||
muted: false, //静音
|
|
||||||
webFullScreen: false,
|
/**
|
||||||
speedRate: ['0.75', '1.0', '1.25', '1.5', '2.0'], //播放倍速
|
* 暂停状态
|
||||||
autoPlay: false, //自动播放
|
*/
|
||||||
loop: false, //循环播放
|
const paused = () => {
|
||||||
mirror: false, //镜像画面
|
return player.value?.paused;
|
||||||
ligthOff: false, //关灯模式
|
};
|
||||||
volume: 0.3, //默认音量大小
|
|
||||||
control: true, //是否显示控制
|
defineExpose({
|
||||||
controlBtns: [
|
play,
|
||||||
'audioTrack',
|
pause,
|
||||||
'quality',
|
paused,
|
||||||
'speedRate',
|
|
||||||
'volume',
|
|
||||||
'setting',
|
|
||||||
'pip',
|
|
||||||
'pageFullScreen',
|
|
||||||
'fullScreen',
|
|
||||||
], //显示所有按钮,
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import NormalUpload from './NormalUpload/index.vue'
|
||||||
import FileFormat from './FileFormat/index.vue'
|
import FileFormat from './FileFormat/index.vue'
|
||||||
import JProUpload from './JUpload/index.vue'
|
import JProUpload from './JUpload/index.vue'
|
||||||
import { BasicLayoutPage, BlankLayoutPage } from './Layout'
|
import { BasicLayoutPage, BlankLayoutPage } from './Layout'
|
||||||
import { PageContainer } from 'jetlinks-ui-components/es/components'
|
import { PageContainer } from 'jetlinks-ui-components'
|
||||||
import Ellipsis from './Ellipsis/index.vue'
|
import Ellipsis from './Ellipsis/index.vue'
|
||||||
import JEmpty from './Empty/index.vue'
|
import JEmpty from './Empty/index.vue'
|
||||||
import AMapComponent from './AMapComponent/index.vue'
|
import AMapComponent from './AMapComponent/index.vue'
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ export const useMenuStore = defineStore({
|
||||||
const path = this.hasMenu(name)
|
const path = this.hasMenu(name)
|
||||||
if (path) {
|
if (path) {
|
||||||
router.push({
|
router.push({
|
||||||
name, params, query
|
name, params, query, state: { params }
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
onlyMessage('暂无权限,请联系管理员', 'error')
|
onlyMessage('暂无权限,请联系管理员', 'error')
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,8 @@ export type MenuItem = {
|
||||||
icon?: string
|
icon?: string
|
||||||
[key: string]: any
|
[key: string]: any
|
||||||
},
|
},
|
||||||
component?: any
|
component?: any,
|
||||||
|
props?: boolean
|
||||||
};
|
};
|
||||||
|
|
||||||
// 额外子级路由
|
// 额外子级路由
|
||||||
|
|
@ -213,7 +214,7 @@ export function filterAsnycRouter(asyncRouterMap: any, parentCode = '', level =
|
||||||
title: route.name,
|
title: route.name,
|
||||||
hideInMenu: route.isShow === false,
|
hideInMenu: route.isShow === false,
|
||||||
buttons: route.buttons?.map((b: any) => b.id) || []
|
buttons: route.buttons?.map((b: any) => b.id) || []
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const silder = {..._route}
|
const silder = {..._route}
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,12 @@
|
||||||
<div v-if="productStore.current.accessId === undefined || null">
|
<div v-if="productStore.current.accessId === undefined || null">
|
||||||
<a-empty :image="simpleImage">
|
<a-empty :image="simpleImage">
|
||||||
<template #description>
|
<template #description>
|
||||||
<span>
|
<span v-if="permissionStore.hasPermission('device/Product:update')">
|
||||||
请先<a-button type="link" @click="showModal"
|
请先<a-button type="link" @click="showModal"
|
||||||
>选择</a-button
|
>选择</a-button
|
||||||
>设备接入网关,用以提供设备接入能力
|
>设备接入网关,用以提供设备接入能力
|
||||||
</span>
|
</span>
|
||||||
|
<span v-else>暂无权限,请联系管理员</span>
|
||||||
</template>
|
</template>
|
||||||
</a-empty>
|
</a-empty>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -173,9 +174,7 @@
|
||||||
</a-select>
|
</a-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
<a-button type="primary" @click="submitDevice"
|
<PermissionButton type="primary" @click="submitDevice" hasPermission="device/Instance:update">保存</PermissionButton>
|
||||||
>保存</a-button
|
|
||||||
>
|
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col
|
<a-col
|
||||||
:span="12"
|
:span="12"
|
||||||
|
|
@ -271,16 +270,11 @@
|
||||||
target="deviceModal"
|
target="deviceModal"
|
||||||
@search="search"
|
@search="search"
|
||||||
/>
|
/>
|
||||||
<JTable
|
<JProTable
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:request="queryList"
|
:request="queryList"
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
modal="card"
|
modal="card"
|
||||||
:rowSelection="{
|
|
||||||
selectedRowKeys: _selectedRowKeys,
|
|
||||||
onChange: onSelectChange,
|
|
||||||
type: 'radio',
|
|
||||||
}"
|
|
||||||
:defaultParams="{
|
:defaultParams="{
|
||||||
...temp,
|
...temp,
|
||||||
sorts: [
|
sorts: [
|
||||||
|
|
@ -343,7 +337,7 @@
|
||||||
<template #id="slotProps">
|
<template #id="slotProps">
|
||||||
<a>{{ slotProps.id }}</a>
|
<a>{{ slotProps.id }}</a>
|
||||||
</template>
|
</template>
|
||||||
</JTable>
|
</JProTable>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -353,6 +347,7 @@ import { ConfigMetadata } from '@/views/device/Product/typings';
|
||||||
import { Empty, message } from 'ant-design-vue';
|
import { Empty, message } from 'ant-design-vue';
|
||||||
import { getImage } from '@/utils/comm';
|
import { getImage } from '@/utils/comm';
|
||||||
import Title from '../Title/index.vue';
|
import Title from '../Title/index.vue';
|
||||||
|
import { usePermissionStore } from '@/store/permission';
|
||||||
import './index.less';
|
import './index.less';
|
||||||
import {
|
import {
|
||||||
getProviders,
|
getProviders,
|
||||||
|
|
@ -375,6 +370,7 @@ import Driver from 'driver.js';
|
||||||
import 'driver.js/dist/driver.min.css';
|
import 'driver.js/dist/driver.min.css';
|
||||||
import { marked } from 'marked';
|
import { marked } from 'marked';
|
||||||
import type { FormInstance, TableColumnType } from 'ant-design-vue';
|
import type { FormInstance, TableColumnType } from 'ant-design-vue';
|
||||||
|
const permissionStore = usePermissionStore();
|
||||||
const render = new marked.Renderer();
|
const render = new marked.Renderer();
|
||||||
marked.setOptions({
|
marked.setOptions({
|
||||||
renderer: render,
|
renderer: render,
|
||||||
|
|
@ -548,10 +544,6 @@ const temp = {
|
||||||
const _selectedRowKeys = ref<string[]>([]);
|
const _selectedRowKeys = ref<string[]>([]);
|
||||||
const currentForm = ref({});
|
const currentForm = ref({});
|
||||||
|
|
||||||
const onSelectChange = (keys: string[]) => {
|
|
||||||
_selectedRowKeys.value = [...keys];
|
|
||||||
};
|
|
||||||
|
|
||||||
const cancelSelect = () => {
|
const cancelSelect = () => {
|
||||||
_selectedRowKeys.value = [];
|
_selectedRowKeys.value = [];
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -15,19 +15,26 @@
|
||||||
:params="params"
|
:params="params"
|
||||||
>
|
>
|
||||||
<template #headerTitle>
|
<template #headerTitle>
|
||||||
<a-space>
|
<j-space>
|
||||||
<a-button type="primary" @click="add"
|
<PermissionButton
|
||||||
><plus-outlined />新增</a-button
|
type="primary"
|
||||||
|
@click="add"
|
||||||
|
hasPermission="device/Product:add"
|
||||||
>
|
>
|
||||||
|
<template #icon><AIcon type="PlusOutlined" /></template>
|
||||||
|
新增
|
||||||
|
</PermissionButton>
|
||||||
<a-upload
|
<a-upload
|
||||||
name="file"
|
name="file"
|
||||||
accept=".json"
|
accept=".json"
|
||||||
:showUploadList="false"
|
:showUploadList="false"
|
||||||
:before-upload="beforeUpload"
|
:before-upload="beforeUpload"
|
||||||
>
|
>
|
||||||
<a-button>导入</a-button>
|
<PermissionButton hasPermission="device/Product:import"
|
||||||
|
>导入</PermissionButton
|
||||||
|
>
|
||||||
</a-upload>
|
</a-upload>
|
||||||
</a-space>
|
</j-space>
|
||||||
</template>
|
</template>
|
||||||
<template #deviceType="slotProps">
|
<template #deviceType="slotProps">
|
||||||
<div>{{ slotProps.deviceType.text }}</div>
|
<div>{{ slotProps.deviceType.text }}</div>
|
||||||
|
|
@ -130,6 +137,7 @@
|
||||||
...item.tooltip,
|
...item.tooltip,
|
||||||
}"
|
}"
|
||||||
@click="item.onClick"
|
@click="item.onClick"
|
||||||
|
:hasPermission="'device/Product:' + item.key"
|
||||||
>
|
>
|
||||||
<AIcon
|
<AIcon
|
||||||
type="DeleteOutlined"
|
type="DeleteOutlined"
|
||||||
|
|
@ -193,6 +201,7 @@
|
||||||
<PermissionButton
|
<PermissionButton
|
||||||
:disabled="i.disabled"
|
:disabled="i.disabled"
|
||||||
:popConfirm="i.popConfirm"
|
:popConfirm="i.popConfirm"
|
||||||
|
:hasPermission="'device/Product:' + i.key"
|
||||||
:tooltip="{
|
:tooltip="{
|
||||||
...i.tooltip,
|
...i.tooltip,
|
||||||
}"
|
}"
|
||||||
|
|
@ -334,12 +343,11 @@ const getActions = (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'edit',
|
key: 'update',
|
||||||
text: '编辑',
|
text: '编辑',
|
||||||
tooltip: {
|
tooltip: {
|
||||||
title: '编辑',
|
title: '编辑',
|
||||||
},
|
},
|
||||||
|
|
||||||
icon: 'EditOutlined',
|
icon: 'EditOutlined',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
title.value = '编辑';
|
title.value = '编辑';
|
||||||
|
|
@ -350,7 +358,7 @@ const getActions = (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'download',
|
key: 'export',
|
||||||
text: '导出',
|
text: '导出',
|
||||||
tooltip: {
|
tooltip: {
|
||||||
title: '导出',
|
title: '导出',
|
||||||
|
|
|
||||||
|
|
@ -1,62 +1,62 @@
|
||||||
<!-- 基础内容 -->
|
<!-- 基础内容 -->
|
||||||
<template>
|
<template>
|
||||||
<a-form layout="vertical" :model="form" ref="formBasicRef">
|
<j-form layout="vertical" :model="form" ref="formBasicRef">
|
||||||
<a-row :span="24" :gutter="24">
|
<j-row :span="24" :gutter="24">
|
||||||
<a-col :span="10">
|
<j-col :span="10">
|
||||||
<a-form-item
|
<j-form-item
|
||||||
label="系统名称"
|
label="系统名称"
|
||||||
name="title"
|
name="title"
|
||||||
v-bind="validateInfos.title"
|
v-bind="validateInfos.title"
|
||||||
>
|
>
|
||||||
<a-input
|
<j-input
|
||||||
v-model:value="form.title"
|
v-model:value="form.title"
|
||||||
:maxlength="64"
|
:maxlength="64"
|
||||||
placeholder="请输入系统名称"
|
placeholder="请输入系统名称"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item
|
<j-form-item
|
||||||
label="主题色"
|
label="主题色"
|
||||||
name="headerTheme"
|
name="headerTheme"
|
||||||
v-bind="validateInfos.headerTheme"
|
v-bind="validateInfos.headerTheme"
|
||||||
>
|
>
|
||||||
<a-select v-model:value="form.headerTheme">
|
<j-select v-model:value="form.headerTheme">
|
||||||
<a-select-option value="light">白色</a-select-option>
|
<j-select-option value="light">白色</j-select-option>
|
||||||
<a-select-option value="dark">黑色</a-select-option>
|
<j-select-option value="dark">黑色</j-select-option>
|
||||||
</a-select>
|
</j-select>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item>
|
<j-form-item>
|
||||||
<template #label>
|
<template #label>
|
||||||
<span>高德API Key</span>
|
<span>高德API Key</span>
|
||||||
<a-tooltip title="配置后平台可调用高德地图GIS服务">
|
<j-tooltip title="配置后平台可调用高德地图GIS服务">
|
||||||
<img
|
<img
|
||||||
class="img-style"
|
class="img-style"
|
||||||
:src="getImage('/init-home/mark.png')"
|
:src="getImage('/init-home/mark.png')"
|
||||||
/>
|
/>
|
||||||
</a-tooltip>
|
</j-tooltip>
|
||||||
</template>
|
</template>
|
||||||
<a-input
|
<j-input
|
||||||
v-model:value="form.apikey"
|
v-model:value="form.apikey"
|
||||||
placeholder="请输入高德API Key"
|
placeholder="请输入高德API Key"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item name="basePath" v-bind="validateInfos.basePath">
|
<j-form-item name="basePath" v-bind="validateInfos.basePath">
|
||||||
<template #label>
|
<template #label>
|
||||||
<span>base-path</span>
|
<span>base-path</span>
|
||||||
<a-tooltip title="系统后台访问的url">
|
<j-tooltip title="系统后台访问的url">
|
||||||
<img
|
<img
|
||||||
class="img-style"
|
class="img-style"
|
||||||
:src="getImage('/init-home/mark.png')"
|
:src="getImage('/init-home/mark.png')"
|
||||||
/>
|
/>
|
||||||
</a-tooltip>
|
</j-tooltip>
|
||||||
</template>
|
</template>
|
||||||
<a-input
|
<j-input
|
||||||
v-model:value="form.basePath"
|
v-model:value="form.basePath"
|
||||||
placeholder="请输入高德API Key"
|
placeholder="请输入base-path"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-row :gutter="24" :span="24">
|
<j-row :gutter="24" :span="24">
|
||||||
<a-col>
|
<j-col>
|
||||||
<a-form-item label="系统logo">
|
<j-form-item label="系统logo">
|
||||||
<div class="upload-image-warp-logo">
|
<div class="upload-image-warp-logo">
|
||||||
<div class="upload-image-border-logo">
|
<div class="upload-image-border-logo">
|
||||||
<a-upload
|
<a-upload
|
||||||
|
|
@ -123,18 +123,18 @@
|
||||||
|
|
||||||
<div class="upload-tips">推荐尺寸200*200</div>
|
<div class="upload-tips">推荐尺寸200*200</div>
|
||||||
<div class="upload-tips">支持jpg,png</div>
|
<div class="upload-tips">支持jpg,png</div>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</a-col>
|
</j-col>
|
||||||
<a-col>
|
<j-col>
|
||||||
<a-form-item>
|
<j-form-item>
|
||||||
<template #label>
|
<template #label>
|
||||||
<span>浏览器页签</span>
|
<span>浏览器页签</span>
|
||||||
<a-tooltip title="浏览器tab页中显示的图片元素">
|
<j-tooltip title="浏览器tab页中显示的图片元素">
|
||||||
<img
|
<img
|
||||||
class="img-style"
|
class="img-style"
|
||||||
:src="getImage('/init-home/mark.png')"
|
:src="getImage('/init-home/mark.png')"
|
||||||
/>
|
/>
|
||||||
</a-tooltip>
|
</j-tooltip>
|
||||||
</template>
|
</template>
|
||||||
<div class="upload-image-warp-logo">
|
<div class="upload-image-warp-logo">
|
||||||
<div class="upload-image-border-logo">
|
<div class="upload-image-border-logo">
|
||||||
|
|
@ -189,12 +189,12 @@
|
||||||
|
|
||||||
<div class="upload-tips">推荐尺寸64*64</div>
|
<div class="upload-tips">推荐尺寸64*64</div>
|
||||||
<div class="upload-tips">支持icon格式</div>
|
<div class="upload-tips">支持icon格式</div>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</a-col>
|
</j-col>
|
||||||
</a-row>
|
</j-row>
|
||||||
</a-col>
|
</j-col>
|
||||||
<a-col :span="14">
|
<j-col :span="14">
|
||||||
<a-form-item label="登录背景图">
|
<j-form-item label="登录背景图">
|
||||||
<div class="upload-image-warp-back">
|
<div class="upload-image-warp-back">
|
||||||
<div class="upload-image-border-back">
|
<div class="upload-image-border-back">
|
||||||
<a-upload
|
<a-upload
|
||||||
|
|
@ -247,10 +247,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="upload-tips">支持4M以内的图片:支持jpg、png</div>
|
<div class="upload-tips">支持4M以内的图片:支持jpg、png</div>
|
||||||
<div class="upload-tips">建议尺寸1400x1080</div>
|
<div class="upload-tips">建议尺寸1400x1080</div>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</a-col>
|
</j-col>
|
||||||
</a-row>
|
</j-row>
|
||||||
</a-form>
|
</j-form>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { modalState, formState, logoState } from '../data/interface';
|
import { modalState, formState, logoState } from '../data/interface';
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,13 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<!-- 初始数据提交表单 -->
|
<!-- 初始数据提交表单 -->
|
||||||
<a-modal
|
<j-modal
|
||||||
v-model:visible="visible"
|
v-model:visible="visible"
|
||||||
title="初始数据"
|
title="初始数据"
|
||||||
width="52vw"
|
width="52vw"
|
||||||
:maskClosable="false"
|
:maskClosable="false"
|
||||||
@cancel="cancel"
|
@cancel="cancel"
|
||||||
@ok="save"
|
@ok="handelSave"
|
||||||
okText="确定"
|
okText="确定"
|
||||||
cancelText="取消"
|
cancelText="取消"
|
||||||
class="modal-style"
|
class="modal-style"
|
||||||
|
|
@ -31,88 +31,88 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 20px">
|
<div style="margin-top: 20px">
|
||||||
<a-form
|
<j-form
|
||||||
layout="vertical"
|
layout="vertical"
|
||||||
:model="modalForm"
|
:model="modalForm"
|
||||||
ref="formRef"
|
ref="formRef"
|
||||||
:rules="rulesModle"
|
:rules="rulesModle"
|
||||||
>
|
>
|
||||||
<a-row :span="24" :gutter="24">
|
<j-row :span="24" :gutter="24">
|
||||||
<a-col :span="12">
|
<j-col :span="12">
|
||||||
<a-form-item name="host">
|
<j-form-item name="host">
|
||||||
<template #label>
|
<template #label>
|
||||||
<span>本地地址 </span>
|
<span>本地地址 </span>
|
||||||
<a-tooltip
|
<j-tooltip
|
||||||
title="绑定到服务器上的网卡地址,绑定到所有网卡:0.0.0.0"
|
title="绑定到服务器上的网卡地址,绑定到所有网卡:0.0.0.0"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
class="img-style"
|
class="img-style"
|
||||||
:src="getImage('/init-home/mark.png')"
|
:src="getImage('/init-home/mark.png')"
|
||||||
/>
|
/>
|
||||||
</a-tooltip>
|
</j-tooltip>
|
||||||
</template>
|
</template>
|
||||||
<a-input
|
<j-input
|
||||||
v-model:value="modalForm.host"
|
v-model:value="modalForm.host"
|
||||||
:disabled="true"
|
:disabled="true"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item name="publicHost">
|
<j-form-item name="publicHost">
|
||||||
<template #label>
|
<template #label>
|
||||||
<span>公网地址 </span>
|
<span>公网地址 </span>
|
||||||
<a-tooltip
|
<j-tooltip
|
||||||
title="对外提供访问的地址内网环境时填写服务器的内网IP地址"
|
title="对外提供访问的地址内网环境时填写服务器的内网IP地址"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
class="img-style"
|
class="img-style"
|
||||||
:src="getImage('/init-home/mark.png')"
|
:src="getImage('/init-home/mark.png')"
|
||||||
/>
|
/>
|
||||||
</a-tooltip>
|
</j-tooltip>
|
||||||
</template>
|
</template>
|
||||||
<a-input v-model:value="modalForm.publicHost">
|
<j-input v-model:value="modalForm.publicHost">
|
||||||
</a-input>
|
</j-input>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</a-col>
|
</j-col>
|
||||||
<a-col :span="12">
|
<j-col :span="12">
|
||||||
<a-form-item name="port">
|
<j-form-item name="port">
|
||||||
<template #label>
|
<template #label>
|
||||||
<span>本地端口 </span>
|
<span>本地端口 </span>
|
||||||
<a-tooltip title="监听指定端口的请求">
|
<j-tooltip title="监听指定端口的请求">
|
||||||
<img
|
<img
|
||||||
class="img-style"
|
class="img-style"
|
||||||
:src="getImage('/init-home/mark.png')"
|
:src="getImage('/init-home/mark.png')"
|
||||||
/>
|
/>
|
||||||
</a-tooltip>
|
</j-tooltip>
|
||||||
</template>
|
</template>
|
||||||
<a-select v-model:value="modalForm.port">
|
<j-select v-model:value="modalForm.port">
|
||||||
<a-select-option
|
<j-select-option
|
||||||
v-for="item in optionPorts"
|
v-for="item in optionPorts"
|
||||||
:key="item"
|
:key="item"
|
||||||
:value="item.value"
|
:value="item.value"
|
||||||
:label="item.label"
|
:label="item.label"
|
||||||
>{{ item.label }}</a-select-option
|
>{{ item.label }}</j-select-option
|
||||||
>
|
>
|
||||||
</a-select>
|
</j-select>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
<a-form-item name="publicPort">
|
<j-form-item name="publicPort">
|
||||||
<template #label>
|
<template #label>
|
||||||
<span>公网端口 </span>
|
<span>公网端口 </span>
|
||||||
<a-tooltip title="对外提供访问的端口">
|
<j-tooltip title="对外提供访问的端口">
|
||||||
<img
|
<img
|
||||||
class="img-style"
|
class="img-style"
|
||||||
:src="getImage('/init-home/mark.png')"
|
:src="getImage('/init-home/mark.png')"
|
||||||
/>
|
/>
|
||||||
</a-tooltip>
|
</j-tooltip>
|
||||||
</template>
|
</template>
|
||||||
<a-input-number
|
<j-input-number
|
||||||
v-model:value="modalForm.publicPort"
|
v-model:value="modalForm.publicPort"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</j-form-item>
|
||||||
</a-col>
|
</j-col>
|
||||||
</a-row>
|
</j-row>
|
||||||
</a-form>
|
</j-form>
|
||||||
</div>
|
</div>
|
||||||
</a-modal>
|
</j-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|
@ -321,10 +321,12 @@ const saveCurrentData = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const { optionPorts, isSucessInit } = toRefs(initialization);
|
const { optionPorts, isSucessInit } = toRefs(initialization);
|
||||||
const save = () => {
|
const handelSave = () => {
|
||||||
message.success('保存成功');
|
formRef.value.validate().then(() => {
|
||||||
flag.value = true;
|
message.success('保存成功');
|
||||||
visible.value = false;
|
flag.value = true;
|
||||||
|
visible.value = false;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* 初始化
|
* 初始化
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="init-home-role">
|
<div class="init-home-role">
|
||||||
<a-checkbox-group @change="getCheckValue">
|
<j-checkbox-group @change="getCheckValue">
|
||||||
<div class="init-home-role-content">
|
<div class="init-home-role-content">
|
||||||
<div
|
<div
|
||||||
class="role-item role-item-1"
|
class="role-item role-item-1"
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div class="role-item-title">
|
<div class="role-item-title">
|
||||||
<a-checkbox :value="ROLEKEYS.device"></a-checkbox>
|
<j-checkbox :value="ROLEKEYS.device"></j-checkbox>
|
||||||
<div class="role-title">设备接入岗</div>
|
<div class="role-title">设备接入岗</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="role-item-content"></div>
|
<div class="role-item-content"></div>
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div class="role-item-title">
|
<div class="role-item-title">
|
||||||
<a-checkbox :value="ROLEKEYS.link"></a-checkbox>
|
<j-checkbox :value="ROLEKEYS.link"></j-checkbox>
|
||||||
<div class="role-title">运维管理岗</div>
|
<div class="role-title">运维管理岗</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="role-item-content"></div>
|
<div class="role-item-content"></div>
|
||||||
|
|
@ -45,7 +45,7 @@
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div class="role-item-title">
|
<div class="role-item-title">
|
||||||
<a-checkbox :value="ROLEKEYS.complex"></a-checkbox>
|
<j-checkbox :value="ROLEKEYS.complex"></j-checkbox>
|
||||||
<div class="role-title">综合管理岗</div>
|
<div class="role-title">综合管理岗</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="role-item-content"></div>
|
<div class="role-item-content"></div>
|
||||||
|
|
@ -54,7 +54,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a-checkbox-group>
|
</j-checkbox-group>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@
|
||||||
<div class="container-box">
|
<div class="container-box">
|
||||||
<div class="container-main">
|
<div class="container-main">
|
||||||
<div class="container-right">
|
<div class="container-right">
|
||||||
<a-spin :spinning="spinning">
|
<j-spin :spinning="spinning">
|
||||||
<a-collapse v-model:activeKey="activeKey" accordion>
|
<j-collapse v-model:activeKey="activeKey" accordion>
|
||||||
<a-collapse-panel key="1">
|
<j-collapse-panel key="1">
|
||||||
<template #header>
|
<template #header>
|
||||||
<span class="title">基本信息</span>
|
<span class="title">基本信息</span>
|
||||||
<span class="sub-title"
|
<span class="sub-title"
|
||||||
|
|
@ -17,8 +17,8 @@
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
<Basic ref="basicRef" />
|
<Basic ref="basicRef" />
|
||||||
</a-collapse-panel>
|
</j-collapse-panel>
|
||||||
<a-collapse-panel key="2" >
|
<j-collapse-panel key="2" >
|
||||||
<template #header>
|
<template #header>
|
||||||
<span class="title">菜单初始化</span>
|
<span class="title">菜单初始化</span>
|
||||||
<span class="sub-title"
|
<span class="sub-title"
|
||||||
|
|
@ -26,8 +26,8 @@
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
<Menu></Menu>
|
<Menu></Menu>
|
||||||
</a-collapse-panel>
|
</j-collapse-panel>
|
||||||
<a-collapse-panel key="3" forceRender>
|
<j-collapse-panel key="3" forceRender>
|
||||||
<template #header>
|
<template #header>
|
||||||
<span class="title">角色初始化</span>
|
<span class="title">角色初始化</span>
|
||||||
<span class="sub-title"
|
<span class="sub-title"
|
||||||
|
|
@ -35,8 +35,8 @@
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
<Role ref="roleRef"></Role>
|
<Role ref="roleRef"></Role>
|
||||||
</a-collapse-panel>
|
</j-collapse-panel>
|
||||||
<a-collapse-panel key="4" forceRender>
|
<j-collapse-panel key="4" forceRender>
|
||||||
<template #header>
|
<template #header>
|
||||||
<span class="title">初始化数据</span>
|
<span class="title">初始化数据</span>
|
||||||
<span class="sub-title"
|
<span class="sub-title"
|
||||||
|
|
@ -44,15 +44,15 @@
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
<InitData ref="initDataRef"></InitData>
|
<InitData ref="initDataRef"></InitData>
|
||||||
</a-collapse-panel>
|
</j-collapse-panel>
|
||||||
</a-collapse>
|
</j-collapse>
|
||||||
</a-spin>
|
</j-spin>
|
||||||
<a-button
|
<j-button
|
||||||
type="primary"
|
type="primary"
|
||||||
class="btn-style"
|
class="btn-style"
|
||||||
@click="submitData"
|
@click="submitData"
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
>确定</a-button
|
>确定</j-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
<div class="tool-item">刷新</div>
|
<div class="tool-item">刷新</div>
|
||||||
<div class="tool-item" @click.stop="handleReset">重置</div>
|
<div class="tool-item" @click.stop="handleReset">重置</div>
|
||||||
</div>
|
</div>
|
||||||
<LivePlayer :src="src" :type="mediaType" />
|
<LivePlayer :url="url" :protocol="mediaType" autoplay />
|
||||||
</div>
|
</div>
|
||||||
<MediaTool
|
<MediaTool
|
||||||
@onMouseDown="handleMouseDown"
|
@onMouseDown="handleMouseDown"
|
||||||
|
|
@ -71,14 +71,14 @@ const _vis = computed({
|
||||||
});
|
});
|
||||||
|
|
||||||
// 视频地址
|
// 视频地址
|
||||||
const src = ref('');
|
const url = ref('');
|
||||||
// 视频类型
|
// 视频类型
|
||||||
const mediaType = ref('mp4');
|
const mediaType = ref<'mp4' | 'flv' | 'hls'>('mp4');
|
||||||
/**
|
/**
|
||||||
* 媒体开始播放
|
* 媒体开始播放
|
||||||
*/
|
*/
|
||||||
const mediaStart = () => {
|
const mediaStart = () => {
|
||||||
src.value = channelApi.ptzStart(
|
url.value = channelApi.ptzStart(
|
||||||
props.data.deviceId,
|
props.data.deviceId,
|
||||||
props.data.channelId,
|
props.data.channelId,
|
||||||
mediaType.value,
|
mediaType.value,
|
||||||
|
|
@ -150,6 +150,9 @@ watch(
|
||||||
if (val) {
|
if (val) {
|
||||||
mediaStart();
|
mediaStart();
|
||||||
getIsRecord();
|
getIsRecord();
|
||||||
|
} else {
|
||||||
|
// url置空, 即销毁播放器
|
||||||
|
url.value = '';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,6 @@ const props = defineProps<Props>();
|
||||||
|
|
||||||
// type 为local时有效,0:未下载; 1:下载中:2:已下载
|
// type 为local时有效,0:未下载; 1:下载中:2:已下载
|
||||||
const status = ref(props.item?.isServer ? 2 : 0);
|
const status = ref(props.item?.isServer ? 2 : 0);
|
||||||
// const status = computed({
|
|
||||||
// get: () => (props.item?.isServer ? 2 : 0),
|
|
||||||
// set: (val: number) => {},
|
|
||||||
// });
|
|
||||||
|
|
||||||
const getLocalIcon = (s: number) => {
|
const getLocalIcon = (s: number) => {
|
||||||
if (s === 0) {
|
if (s === 0) {
|
||||||
|
|
@ -75,5 +71,3 @@ const handleClick = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped></style>
|
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,44 @@
|
||||||
<template>
|
<template>
|
||||||
<page-container>
|
<page-container>
|
||||||
<div class="playback-warp">
|
<div class="playback-warp">
|
||||||
|
<!-- 播放器/进度条 -->
|
||||||
<div class="playback-left">
|
<div class="playback-left">
|
||||||
<LivePlayer
|
<LivePlayer
|
||||||
ref="player"
|
ref="player"
|
||||||
:src="url"
|
autoplay
|
||||||
width="758px"
|
:url="url"
|
||||||
height="462px"
|
className="playback-media"
|
||||||
|
:live="type === 'local'"
|
||||||
|
:on-play="
|
||||||
|
() => {
|
||||||
|
isEnded = false;
|
||||||
|
playStatus = 1;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
:on-pause="
|
||||||
|
() => {
|
||||||
|
playStatus = 2;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
:on-ended="
|
||||||
|
() => {
|
||||||
|
playStatus = 0;
|
||||||
|
if (playTimeNode && isEnded) {
|
||||||
|
isEnded = true;
|
||||||
|
playTimeNode.onNextPlay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
|
:on-error="
|
||||||
|
() => {
|
||||||
|
playStatus = 0;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
:on-time-update="
|
||||||
|
(e: any) => {
|
||||||
|
playTime = e;
|
||||||
|
}
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
<TimeLine
|
<TimeLine
|
||||||
ref="playTimeNode"
|
ref="playTimeNode"
|
||||||
|
|
@ -170,7 +202,6 @@ const historyList = ref<recordsItemType[]>([]);
|
||||||
const time = ref<Dayjs | undefined>(undefined);
|
const time = ref<Dayjs | undefined>(undefined);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const cloudTime = ref<any>();
|
const cloudTime = ref<any>();
|
||||||
// const location = ref();
|
|
||||||
const player = ref<any>();
|
const player = ref<any>();
|
||||||
const playStatus = ref(0); // 播放状态, 0 停止, 1 播放, 2 暂停, 3 播放完成
|
const playStatus = ref(0); // 播放状态, 0 停止, 1 播放, 2 暂停, 3 播放完成
|
||||||
const playTime = ref(0);
|
const playTime = ref(0);
|
||||||
|
|
@ -183,9 +214,11 @@ const channelId = computed(() => route.query.channelId as string);
|
||||||
|
|
||||||
const deviceType = ref('');
|
const deviceType = ref('');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询本地视频
|
||||||
|
* @param date
|
||||||
|
*/
|
||||||
const queryLocalRecords = async (date: Dayjs) => {
|
const queryLocalRecords = async (date: Dayjs) => {
|
||||||
console.log('date: ', date);
|
|
||||||
|
|
||||||
playStatus.value = 0;
|
playStatus.value = 0;
|
||||||
url.value = '';
|
url.value = '';
|
||||||
|
|
||||||
|
|
@ -273,6 +306,10 @@ const cloudView = (startTime: number, endTime: number) => {
|
||||||
queryServiceRecords(time.value!);
|
queryServiceRecords(time.value!);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载到云端
|
||||||
|
* @param item
|
||||||
|
*/
|
||||||
const downloadClick = async (item: recordsItemType) => {
|
const downloadClick = async (item: recordsItemType) => {
|
||||||
const downloadUrl = playBackApi.downLoadFile(item.id);
|
const downloadUrl = playBackApi.downLoadFile(item.id);
|
||||||
const downNode = document.createElement('a');
|
const downNode = document.createElement('a');
|
||||||
|
|
@ -302,6 +339,10 @@ onMounted(() => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 播放进度条点击
|
||||||
|
* @param times
|
||||||
|
*/
|
||||||
const handleTimeLineChange = (times: any) => {
|
const handleTimeLineChange = (times: any) => {
|
||||||
if (times) {
|
if (times) {
|
||||||
playNowTime.value = Number(times.startTime.valueOf());
|
playNowTime.value = Number(times.startTime.valueOf());
|
||||||
|
|
@ -332,9 +373,11 @@ watch(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日历操作
|
||||||
|
* @param date
|
||||||
|
*/
|
||||||
const handlePanelChange = (date: any) => {
|
const handlePanelChange = (date: any) => {
|
||||||
console.log('type: ', typeof date);
|
|
||||||
console.log('date: ', date);
|
|
||||||
time.value = date;
|
time.value = date;
|
||||||
if (type.value === 'cloud') {
|
if (type.value === 'cloud') {
|
||||||
queryServiceRecords(date);
|
queryServiceRecords(date);
|
||||||
|
|
@ -343,20 +386,17 @@ const handlePanelChange = (date: any) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 播放/暂停
|
/**
|
||||||
|
* 播放/暂停
|
||||||
|
* @param _startTime
|
||||||
|
*/
|
||||||
const handlePlay = (_startTime: any) => {
|
const handlePlay = (_startTime: any) => {
|
||||||
if (playStatus.value === 0 || _startTime !== playNowTime.value) {
|
if (playStatus.value === 0 || _startTime !== playNowTime.value) {
|
||||||
if (playTimeNode.value) {
|
playTimeNode.value?.playByStartTime(_startTime);
|
||||||
playTimeNode.value.playByStartTime(_startTime);
|
|
||||||
}
|
|
||||||
} else if (playStatus.value == 1 && _startTime === playNowTime.value) {
|
} else if (playStatus.value == 1 && _startTime === playNowTime.value) {
|
||||||
if (player.value.getVueInstance) {
|
player.value?.pause();
|
||||||
// player.value.getVueInstance().pause();
|
|
||||||
}
|
|
||||||
} else if (playStatus.value == 2 && _startTime === playNowTime.value) {
|
} else if (playStatus.value == 2 && _startTime === playNowTime.value) {
|
||||||
if (player.value.getVueInstance) {
|
player.value?.play();
|
||||||
// player.value.getVueInstance().play();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ import { message } from 'ant-design-vue';
|
||||||
import type { recordsItemType } from './typings';
|
import type { recordsItemType } from './typings';
|
||||||
import type { Dayjs } from 'dayjs';
|
import type { Dayjs } from 'dayjs';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import { useElementSize } from '@vueuse/core';
|
||||||
|
|
||||||
export type TimeChangeType = {
|
export type TimeChangeType = {
|
||||||
endTime: Dayjs;
|
endTime: Dayjs;
|
||||||
|
|
@ -77,18 +78,17 @@ const endT = ref<number>(
|
||||||
const list = ref<any[]>([]);
|
const list = ref<any[]>([]);
|
||||||
const playTime = ref<number>(0);
|
const playTime = ref<number>(0);
|
||||||
const LineContent = ref<HTMLDivElement>();
|
const LineContent = ref<HTMLDivElement>();
|
||||||
// const LineContentSize = LineContent.value;
|
const LineContentSize = useElementSize(LineContent);
|
||||||
const LineContentSize = ref({ width: 100 });
|
|
||||||
|
|
||||||
const setTimeAndPosition = (ob: number) => {
|
const setTimeAndPosition = (ob: number) => {
|
||||||
const oBtn = document.getElementById('btn');
|
const oBtn = document.getElementById('btn');
|
||||||
const oTime = document.getElementById('time');
|
const oTime = document.getElementById('time');
|
||||||
|
|
||||||
if (oBtn && oTime && LineContentSize.value.width) {
|
if (oBtn && oTime && LineContentSize.width) {
|
||||||
oBtn.style.visibility = 'visible';
|
oBtn.style.visibility = 'visible';
|
||||||
oBtn.style.left = `${ob * LineContentSize.value.width}px`;
|
oBtn.style.left = `${ob * LineContentSize.width.value}px`;
|
||||||
oTime.style.visibility = 'visible';
|
oTime.style.visibility = 'visible';
|
||||||
oTime.style.left = `${ob * LineContentSize.value.width - 15}px`;
|
oTime.style.left = `${ob * LineContentSize.width.value - 15}px`;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -214,7 +214,7 @@ const getLineItemStyle = (
|
||||||
endTime: number,
|
endTime: number,
|
||||||
): { left: string; width: string } => {
|
): { left: string; width: string } => {
|
||||||
const start = startTime - startT.value > 0 ? startTime - startT.value : 0;
|
const start = startTime - startT.value > 0 ? startTime - startT.value : 0;
|
||||||
const _width = LineContentSize.value.width!;
|
const _width = LineContentSize.width.value!;
|
||||||
const itemWidth = ((endTime - startTime) / (24 * 3600000)) * _width;
|
const itemWidth = ((endTime - startTime) / (24 * 3600000)) * _width;
|
||||||
return {
|
return {
|
||||||
left: `${(start / (24 * 3600000)) * _width}px`,
|
left: `${(start / (24 * 3600000)) * _width}px`,
|
||||||
|
|
@ -256,7 +256,7 @@ const handleProgress = (event: any, item: any) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
defineExpose({ playByStartTime });
|
defineExpose({ playByStartTime, onNextPlay });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
|
||||||
|
|
@ -408,6 +408,7 @@ const { resetFields, validate, validateInfos, clearValidate } = useForm(
|
||||||
);
|
);
|
||||||
|
|
||||||
const getDetail = async () => {
|
const getDetail = async () => {
|
||||||
|
console.log('getDetail', route)
|
||||||
if (route.params.id === ':id') return;
|
if (route.params.id === ':id') return;
|
||||||
const res = await configApi.detail(route.params.id as string);
|
const res = await configApi.detail(route.params.id as string);
|
||||||
// formData.value = res.result;
|
// formData.value = res.result;
|
||||||
|
|
|
||||||
|
|
@ -21,15 +21,16 @@
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<div
|
|
||||||
style="
|
<PermissionButton
|
||||||
margin: 0 0px 0 4px;
|
type="link"
|
||||||
color: #1d39c4;
|
@click="showOutput"
|
||||||
cursor: pointer;
|
hasPermission="device/Instance:update"
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<edit-outlined @click="showOutput"/>
|
<template #icon
|
||||||
</div>
|
><AIcon type="EditOutlined"
|
||||||
|
/></template>
|
||||||
|
</PermissionButton>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<a-descriptions
|
<a-descriptions
|
||||||
|
|
@ -82,15 +83,14 @@
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
<div
|
<PermissionButton
|
||||||
style="
|
type="link"
|
||||||
margin: 0 0px 0 4px;
|
@click="showInput"
|
||||||
color: #1d39c4;
|
hasPermission="device/Instance:update"
|
||||||
cursor: pointer;
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<edit-outlined @click="showInput"/>
|
<template #icon
|
||||||
</div>
|
><AIcon type="EditOutlined" /></template
|
||||||
|
></PermissionButton>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<a-descriptions
|
<a-descriptions
|
||||||
|
|
@ -168,14 +168,24 @@
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
<InputSave :data="input" v-if="inputVisible" @closeModel="closeInput" @saveSuc="saveInput"/>
|
<InputSave
|
||||||
<OutputSave :data="output" v-if="outputVisible" @closeModel="closeOutput" @saveSuc="saveOutput"/>
|
:data="input"
|
||||||
|
v-if="inputVisible"
|
||||||
|
@closeModel="closeInput"
|
||||||
|
@saveSuc="saveInput"
|
||||||
|
/>
|
||||||
|
<OutputSave
|
||||||
|
:data="output"
|
||||||
|
v-if="outputVisible"
|
||||||
|
@closeModel="closeOutput"
|
||||||
|
@saveSuc="saveOutput"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import InputSave from './Save/input.vue'
|
import InputSave from './Save/input.vue';
|
||||||
import OutputSave from './save/output.vue'
|
import OutputSave from './save/output.vue';
|
||||||
import {
|
import {
|
||||||
EditOutlined,
|
EditOutlined,
|
||||||
DeleteOutlined,
|
DeleteOutlined,
|
||||||
|
|
@ -439,24 +449,24 @@ handleInputSearch();
|
||||||
handleOutputSearch();
|
handleOutputSearch();
|
||||||
const showInput = () => {
|
const showInput = () => {
|
||||||
inputVisible.value = true;
|
inputVisible.value = true;
|
||||||
}
|
};
|
||||||
const closeInput = () =>{
|
const closeInput = () => {
|
||||||
inputVisible.value = false;
|
inputVisible.value = false;
|
||||||
}
|
};
|
||||||
const saveInput = () =>{
|
const saveInput = () => {
|
||||||
inputVisible.value = false;
|
inputVisible.value = false;
|
||||||
handleInputSearch();
|
handleInputSearch();
|
||||||
}
|
};
|
||||||
const showOutput = () =>{
|
const showOutput = () => {
|
||||||
outputVisible.value = true;
|
outputVisible.value = true;
|
||||||
}
|
};
|
||||||
const closeOutput = () =>{
|
const closeOutput = () => {
|
||||||
outputVisible.value = false;
|
outputVisible.value = false;
|
||||||
}
|
};
|
||||||
const saveOutput = () =>{
|
const saveOutput = () => {
|
||||||
outputVisible.value = false;
|
outputVisible.value = false;
|
||||||
handleOutputSearch();
|
handleOutputSearch();
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.alarmTitle {
|
.alarmTitle {
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,13 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a-card>
|
</a-card>
|
||||||
<a-button
|
<!-- <a-button
|
||||||
type="primary"
|
type="primary"
|
||||||
size="middle"
|
size="middle"
|
||||||
@click="handleSaveLevel"
|
@click="handleSaveLevel"
|
||||||
>保存</a-button
|
>保存</a-button
|
||||||
>
|
> -->
|
||||||
|
<PermissionButton type="primary" size="middle" @click="handleSaveLevel" hasPermission="rule-engine/Alarm/Config:update">保存</PermissionButton>
|
||||||
</div>
|
</div>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="10">
|
<a-col :span="10">
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,7 @@
|
||||||
<a-form-item label="说明" name="description">
|
<a-form-item label="说明" name="description">
|
||||||
<a-textarea v-model:value="form.description"></a-textarea>
|
<a-textarea v-model:value="form.description"></a-textarea>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-button type="primary" @click="handleSave" :loading="loading"
|
<PermissionButton type="primary" @click="handleSave" :hasPermission="['rule-engine/Alarm/Configuration:add','rule-engine/Alarm/Configuration:update']">保存</PermissionButton>
|
||||||
>保存</a-button
|
|
||||||
>
|
|
||||||
</a-form>
|
</a-form>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -63,6 +61,7 @@ import { useMenuStore } from '@/store/menu';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { useAlarmConfigurationStore } from '@/store/alarm';
|
import { useAlarmConfigurationStore } from '@/store/alarm';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { usePermissionStore } from '@/store/permission';
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const id = route.query?.id;
|
const id = route.query?.id;
|
||||||
let selectDisable = ref(false);
|
let selectDisable = ref(false);
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
>
|
>
|
||||||
<template #headerTitle>
|
<template #headerTitle>
|
||||||
<a-space>
|
<a-space>
|
||||||
<PermissionButton type="primary" @click="showModal">
|
<PermissionButton type="primary" @click="showModal" hasPermission="rule-engine/Alarm/Configuration:add">
|
||||||
<template #icon><AIcon type="PlusOutlined" /></template>
|
<template #icon><AIcon type="PlusOutlined" /></template>
|
||||||
新增
|
新增
|
||||||
</PermissionButton>
|
</PermissionButton>
|
||||||
|
|
@ -64,6 +64,7 @@
|
||||||
...item.tooltip,
|
...item.tooltip,
|
||||||
}"
|
}"
|
||||||
@click="item.onClick"
|
@click="item.onClick"
|
||||||
|
:hasPermission="'rule-engine/Alarm/Configuration:'+item.key"
|
||||||
>
|
>
|
||||||
<AIcon :type="item.icon" />
|
<AIcon :type="item.icon" />
|
||||||
<span>{{ item?.text }}</span>
|
<span>{{ item?.text }}</span>
|
||||||
|
|
@ -137,7 +138,7 @@ const getActions = (
|
||||||
if (!data) return [];
|
if (!data) return [];
|
||||||
const actions: ActionsType[] = [
|
const actions: ActionsType[] = [
|
||||||
{
|
{
|
||||||
key: 'unbind',
|
key: 'action',
|
||||||
text: '解绑',
|
text: '解绑',
|
||||||
icon: 'DisconnectOutlined',
|
icon: 'DisconnectOutlined',
|
||||||
popConfirm: {
|
popConfirm: {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:request="queryList"
|
:request="queryList"
|
||||||
:gridColumn="3"
|
:gridColumn="3"
|
||||||
:gridColumns="[1,2,3]"
|
:gridColumns="[1, 2, 3]"
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
:defaultParams="{
|
:defaultParams="{
|
||||||
sorts: [{ name: 'createTime', order: 'desc' }],
|
sorts: [{ name: 'createTime', order: 'desc' }],
|
||||||
|
|
@ -18,11 +18,18 @@
|
||||||
:params="params"
|
:params="params"
|
||||||
>
|
>
|
||||||
<template #headerTitle>
|
<template #headerTitle>
|
||||||
<a-space>
|
<j-space>
|
||||||
<a-button type="primary" @click="add"
|
<PermissionButton
|
||||||
><plus-outlined />新增</a-button
|
type="primary"
|
||||||
|
@click="add"
|
||||||
|
hasPermission="device/Instance:add"
|
||||||
>
|
>
|
||||||
</a-space>
|
<template #icon
|
||||||
|
><AIcon type="PlusOutlined"
|
||||||
|
/></template>
|
||||||
|
新增
|
||||||
|
</PermissionButton>
|
||||||
|
</j-space>
|
||||||
</template>
|
</template>
|
||||||
<template #card="slotProps">
|
<template #card="slotProps">
|
||||||
<CardBox
|
<CardBox
|
||||||
|
|
@ -74,13 +81,17 @@
|
||||||
<template #actions="item">
|
<template #actions="item">
|
||||||
<PermissionButton
|
<PermissionButton
|
||||||
v-if="
|
v-if="
|
||||||
item.key != 'trigger' ||
|
item.key != 'tigger' ||
|
||||||
slotProps.sceneTriggerType == 'manual'
|
slotProps.sceneTriggerType == 'manual'
|
||||||
"
|
"
|
||||||
:disabled="item.disabled"
|
:disabled="item.disabled"
|
||||||
:popConfirm="item.popConfirm"
|
:popConfirm="item.popConfirm"
|
||||||
:tooltip="{ ...item.tootip }"
|
:tooltip="{ ...item.tootip }"
|
||||||
@click="item.onClick"
|
@click="item.onClick"
|
||||||
|
:hasPermission="
|
||||||
|
'rule-engine/Alarm/Configuration:' +
|
||||||
|
item.key
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<AIcon
|
<AIcon
|
||||||
type="DeleteOutlined"
|
type="DeleteOutlined"
|
||||||
|
|
@ -136,7 +147,7 @@
|
||||||
>
|
>
|
||||||
<PermissionButton
|
<PermissionButton
|
||||||
v-if="
|
v-if="
|
||||||
i.key != 'trigger' ||
|
i.key != 'tigger' ||
|
||||||
slotProps.sceneTriggerType == 'manual'
|
slotProps.sceneTriggerType == 'manual'
|
||||||
"
|
"
|
||||||
:disabled="i.disabled"
|
:disabled="i.disabled"
|
||||||
|
|
@ -147,6 +158,10 @@
|
||||||
@click="i.onClick"
|
@click="i.onClick"
|
||||||
type="link"
|
type="link"
|
||||||
style="padding: 0px"
|
style="padding: 0px"
|
||||||
|
:hasPermission="
|
||||||
|
'rule-engine/Alarm/Configuration:' +
|
||||||
|
item.key
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<template #icon
|
<template #icon
|
||||||
><AIcon :type="i.icon"
|
><AIcon :type="i.icon"
|
||||||
|
|
@ -161,7 +176,6 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import JTable from '@/components/Table';
|
|
||||||
import {
|
import {
|
||||||
queryList,
|
queryList,
|
||||||
_enable,
|
_enable,
|
||||||
|
|
@ -323,7 +337,7 @@ const getActions = (
|
||||||
}
|
}
|
||||||
const actions = [
|
const actions = [
|
||||||
{
|
{
|
||||||
key: 'trigger',
|
key: 'tigger',
|
||||||
text: '手动触发',
|
text: '手动触发',
|
||||||
disabled: data?.state?.value === 'disabled',
|
disabled: data?.state?.value === 'disabled',
|
||||||
tooltip: {
|
tooltip: {
|
||||||
|
|
@ -353,7 +367,7 @@ const getActions = (
|
||||||
icon: 'LikeOutlined',
|
icon: 'LikeOutlined',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'edit',
|
key: 'update',
|
||||||
text: '编辑',
|
text: '编辑',
|
||||||
tooltip: {
|
tooltip: {
|
||||||
title: '编辑',
|
title: '编辑',
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
target="alarm-log-detail"
|
target="alarm-log-detail"
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
></Search>
|
></Search>
|
||||||
<JTable
|
<JProTable
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
model="TABLE"
|
model="TABLE"
|
||||||
:request="queryList"
|
:request="queryList"
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
</template>
|
</template>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
</JTable>
|
</JProTable>
|
||||||
<Info v-if="visiable" :data="current" @close="close"/>
|
<Info v-if="visiable" :data="current" @close="close"/>
|
||||||
</page-container>
|
</page-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
target="bind-channel"
|
target="bind-channel"
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
></Search>
|
></Search>
|
||||||
<JTable
|
<JProTable
|
||||||
model="TABLE"
|
model="TABLE"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:defaultParams="{
|
:defaultParams="{
|
||||||
|
|
@ -47,7 +47,7 @@
|
||||||
}}
|
}}
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</JTable>
|
</JProTable>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:request="handleSearch"
|
:request="handleSearch"
|
||||||
:params="params"
|
:params="params"
|
||||||
:gridColumns="[1,1,2]"
|
:gridColumns="[1, 1, 2]"
|
||||||
:gridColumn="2"
|
:gridColumn="2"
|
||||||
model="CARD"
|
model="CARD"
|
||||||
>
|
>
|
||||||
|
|
@ -98,16 +98,23 @@
|
||||||
</span>
|
</span>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
<template #actions="item">
|
<template #actions="item">
|
||||||
<PermissionButton
|
<PermissionButton
|
||||||
:disabled="item.key === 'solve' && slotProps.state.value ==='normal'"
|
:disabled="
|
||||||
|
item.key === 'solve' &&
|
||||||
|
slotProps.state.value === 'normal'
|
||||||
|
"
|
||||||
:popConfirm="item.popConfirm"
|
:popConfirm="item.popConfirm"
|
||||||
:tooltip="{
|
:tooltip="{
|
||||||
...item.tooltip,
|
...item.tooltip,
|
||||||
}"
|
}"
|
||||||
@click="item.onClick"
|
@click="item.onClick"
|
||||||
|
:hasPermission="
|
||||||
|
item.key == 'solve'
|
||||||
|
? 'rule-engine/Alarm/Log:action'
|
||||||
|
: 'rule-engine/Alarm/Log:view'
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<AIcon :type="item.icon" />
|
<AIcon :type="item.icon" />
|
||||||
<span>{{ item?.text }}</span>
|
<span>{{ item?.text }}</span>
|
||||||
|
|
@ -116,8 +123,16 @@
|
||||||
</CardBox>
|
</CardBox>
|
||||||
</template>
|
</template>
|
||||||
</JProTable>
|
</JProTable>
|
||||||
<SolveComponent :data="data" v-if="data.solveVisible" @closeSolve="closeSolve"/>
|
<SolveComponent
|
||||||
<SolveLog :data="data.current" v-if="data.logVisible" @closeLog="closeLog"/>
|
:data="data"
|
||||||
|
v-if="data.solveVisible"
|
||||||
|
@closeSolve="closeSolve"
|
||||||
|
/>
|
||||||
|
<SolveLog
|
||||||
|
:data="data.current"
|
||||||
|
v-if="data.logVisible"
|
||||||
|
@closeLog="closeLog"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -139,6 +154,7 @@ import type { ActionsType } from '@/components/Table';
|
||||||
import SolveComponent from '../SolveComponent/index.vue';
|
import SolveComponent from '../SolveComponent/index.vue';
|
||||||
import SolveLog from '../SolveLog/index.vue'
|
import SolveLog from '../SolveLog/index.vue'
|
||||||
import { useMenuStore } from '@/store/menu';
|
import { useMenuStore } from '@/store/menu';
|
||||||
|
import { usePermissionStore } from '@/store/permission';
|
||||||
const menuStory = useMenuStore();
|
const menuStory = useMenuStore();
|
||||||
|
|
||||||
const alarmStore = useAlarmStore();
|
const alarmStore = useAlarmStore();
|
||||||
|
|
@ -368,6 +384,13 @@ const getActions = (
|
||||||
onClick: () =>{
|
onClick: () =>{
|
||||||
data.value.current = currentData;
|
data.value.current = currentData;
|
||||||
data.value.solveVisible = true;
|
data.value.solveVisible = true;
|
||||||
|
},
|
||||||
|
popConfirm:{
|
||||||
|
title: !usePermissionStore().hasPermission('rule-engine/Alarm/Log:action')
|
||||||
|
? '暂无权限,请联系管理员'
|
||||||
|
: data.state?.value === 'normal'
|
||||||
|
? '无告警'
|
||||||
|
: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
:title="item.alarmName"
|
:title="item.alarmName"
|
||||||
placement="topLeft"
|
placement="topLeft"
|
||||||
>
|
>
|
||||||
<a>{{ item.alarmName }}</a>
|
<a @click="()=>{return jumpDetail(item)}">{{ item.alarmName }}</a>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="new-alarm-item-state">
|
<div class="new-alarm-item-state">
|
||||||
|
|
@ -63,6 +63,7 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Empty } from 'ant-design-vue';
|
import { Empty } from 'ant-design-vue';
|
||||||
import { getImage } from '@/utils/comm';
|
import { getImage } from '@/utils/comm';
|
||||||
|
import { useMenuStore } from '@/store/menu';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
alarmList: {
|
alarmList: {
|
||||||
|
|
@ -70,6 +71,10 @@ const props = defineProps({
|
||||||
default: [],
|
default: [],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const menuStore = useMenuStore();
|
||||||
|
const jumpDetail = (item:any) =>{
|
||||||
|
menuStore.jumpPage(`rule-engine/Alarm/Log/Detail`,{id:item.id});
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
.new-alarm {
|
.new-alarm {
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
target="device-instance"
|
target="device-instance"
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
></Search>
|
></Search>
|
||||||
<JTable
|
<JProTable
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:request="queryList"
|
:request="queryList"
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
|
|
@ -16,11 +16,18 @@
|
||||||
:params="params"
|
:params="params"
|
||||||
>
|
>
|
||||||
<template #headerTitle>
|
<template #headerTitle>
|
||||||
<a-space>
|
<j-space>
|
||||||
<a-button type="primary" @click="add"
|
<PermissionButton
|
||||||
><plus-outlined />新增</a-button
|
type="primary"
|
||||||
|
@click="add"
|
||||||
|
hasPermission="rule-engine/Instance:add"
|
||||||
>
|
>
|
||||||
</a-space>
|
<template #icon
|
||||||
|
><AIcon type="PlusOutlined"
|
||||||
|
/></template>
|
||||||
|
新增
|
||||||
|
</PermissionButton>
|
||||||
|
</j-space>
|
||||||
</template>
|
</template>
|
||||||
<template #card="slotProps">
|
<template #card="slotProps">
|
||||||
<CardBox
|
<CardBox
|
||||||
|
|
@ -29,6 +36,7 @@
|
||||||
v-bind="slotProps"
|
v-bind="slotProps"
|
||||||
:status="slotProps.state?.value"
|
:status="slotProps.state?.value"
|
||||||
:statusText="slotProps.state?.text"
|
:statusText="slotProps.state?.text"
|
||||||
|
@click="openRuleEditor"
|
||||||
:statusNames="{
|
:statusNames="{
|
||||||
started: 'success',
|
started: 'success',
|
||||||
disable: 'error',
|
disable: 'error',
|
||||||
|
|
@ -62,6 +70,9 @@
|
||||||
:tooltip="{
|
:tooltip="{
|
||||||
...item.tooltip,
|
...item.tooltip,
|
||||||
}"
|
}"
|
||||||
|
:hasPermission="
|
||||||
|
'rule-engine/Instance:' + item.key
|
||||||
|
"
|
||||||
@click="item.onClick"
|
@click="item.onClick"
|
||||||
>
|
>
|
||||||
<AIcon
|
<AIcon
|
||||||
|
|
@ -113,7 +124,7 @@
|
||||||
</template>
|
</template>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
</JTable>
|
</JProTable>
|
||||||
<!-- 新增、编辑 -->
|
<!-- 新增、编辑 -->
|
||||||
<Save
|
<Save
|
||||||
ref="saveRef"
|
ref="saveRef"
|
||||||
|
|
@ -138,6 +149,7 @@ import type { ActionsType } from '@/components/Table/index.vue';
|
||||||
import { getImage } from '@/utils/comm';
|
import { getImage } from '@/utils/comm';
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
import Save from './Save/index.vue';
|
import Save from './Save/index.vue';
|
||||||
|
import { SystemConst } from '@/utils/consts';
|
||||||
const params = ref<Record<string, any>>({});
|
const params = ref<Record<string, any>>({});
|
||||||
let isAdd = ref<number>(0);
|
let isAdd = ref<number>(0);
|
||||||
let title = ref<string>('');
|
let title = ref<string>('');
|
||||||
|
|
@ -216,7 +228,7 @@ const getActions = (
|
||||||
}
|
}
|
||||||
const actions = [
|
const actions = [
|
||||||
{
|
{
|
||||||
key: 'edit',
|
key: 'update',
|
||||||
text: '编辑',
|
text: '编辑',
|
||||||
tooltip: {
|
tooltip: {
|
||||||
title: '编辑',
|
title: '编辑',
|
||||||
|
|
@ -312,6 +324,11 @@ const refresh = () => {
|
||||||
const handleSearch = (e: any) => {
|
const handleSearch = (e: any) => {
|
||||||
params.value = e;
|
params.value = e;
|
||||||
};
|
};
|
||||||
|
const openRuleEditor = (item: any) => {
|
||||||
|
window.open(
|
||||||
|
`/${SystemConst.API_BASE}/rule-editor/index.html#flow/${item.id}`,
|
||||||
|
);
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -53,9 +53,9 @@
|
||||||
|
|
||||||
<script setup lang='ts' name='AddModel'>
|
<script setup lang='ts' name='AddModel'>
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import type { metadataType, TriggerDevice, TriggerDeviceOptions } from '@/views/rule-engine/Scene/typings'
|
import type { metadataType, TriggerDevice, TriggerDeviceOptions, SelectorValuesItem } from '@/views/rule-engine/Scene/typings'
|
||||||
import { onlyMessage } from '@/utils/comm'
|
import { onlyMessage } from '@/utils/comm'
|
||||||
import { detail as deviceDetail } from '@/api/device/instance'
|
import { detail as deviceDetail } from '@/api/device/instance'
|
||||||
import Product from './Product.vue'
|
import Product from './Product.vue'
|
||||||
import DeviceSelect from './DeviceSelect.vue'
|
import DeviceSelect from './DeviceSelect.vue'
|
||||||
import Type from './Type.vue'
|
import Type from './Type.vue'
|
||||||
|
|
@ -66,12 +66,13 @@ type Emit = {
|
||||||
(e: 'save', data: TriggerDevice, options: Record<string, any>): void
|
(e: 'save', data: TriggerDevice, options: Record<string, any>): void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
interface AddModelType extends Omit<TriggerDevice, 'selectorValues'> {
|
interface AddModelType extends Omit<TriggerDevice, 'selectorValues'> {
|
||||||
stepNumber: number
|
stepNumber: number
|
||||||
deviceKeys: Array<{ label: string, value: string }>
|
deviceKeys: SelectorValuesItem[]
|
||||||
orgId: Array<{ label: string, value: string }>
|
orgId: SelectorValuesItem[]
|
||||||
productDetail: any
|
productDetail: any
|
||||||
selectorValues: Array<Record<string, any>>
|
selectorValues: SelectorValuesItem[]
|
||||||
metadata: metadataType,
|
metadata: metadataType,
|
||||||
operator: TriggerDeviceOptions
|
operator: TriggerDeviceOptions
|
||||||
}
|
}
|
||||||
|
|
@ -95,23 +96,21 @@ const props = defineProps({
|
||||||
})
|
})
|
||||||
|
|
||||||
const addModel = reactive<AddModelType>({
|
const addModel = reactive<AddModelType>({
|
||||||
productId: '',
|
productId: props.value.productId || '',
|
||||||
selector: 'fixed',
|
selector: props.value.selector || 'fixed',
|
||||||
selectorValues: [],
|
selectorValues: props.value.selectorValues || [],
|
||||||
stepNumber: 0,
|
stepNumber: 0,
|
||||||
deviceKeys: [],
|
deviceKeys: props.value.selectorValues || [],
|
||||||
orgId: [],
|
orgId: props.value.selectorValues || [],
|
||||||
productDetail: {},
|
productDetail: {},
|
||||||
metadata: {},
|
metadata: {},
|
||||||
operator: {
|
operator: props.value.operation || {
|
||||||
operator: 'online'
|
operator: 'online'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const optionsCache = ref(props.options)
|
const optionsCache = ref(props.options)
|
||||||
|
|
||||||
Object.assign(addModel, props.value)
|
|
||||||
|
|
||||||
const handleOptions = (data: TriggerDeviceOptions) => {
|
const handleOptions = (data: TriggerDeviceOptions) => {
|
||||||
const typeIconMap = {
|
const typeIconMap = {
|
||||||
writeProperty: 'icon-bianji1',
|
writeProperty: 'icon-bianji1',
|
||||||
|
|
@ -230,6 +229,11 @@ const productChange = () => {
|
||||||
addModel.selectorValues = []
|
addModel.selectorValues = []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getDeviceDetailByMetadata = async (deviceId: string) => {
|
||||||
|
const resp = await deviceDetail(deviceId)
|
||||||
|
return resp.result?.metadata
|
||||||
|
}
|
||||||
|
|
||||||
const save = async (step?: number) => {
|
const save = async (step?: number) => {
|
||||||
let _step = step !== undefined ? step : addModel.stepNumber
|
let _step = step !== undefined ? step : addModel.stepNumber
|
||||||
if (_step === 0) {
|
if (_step === 0) {
|
||||||
|
|
@ -240,12 +244,8 @@ const save = async (step?: number) => {
|
||||||
return onlyMessage(isFixed ? '请选择设备' : '请选择部门', 'error')
|
return onlyMessage(isFixed ? '请选择设备' : '请选择部门', 'error')
|
||||||
}
|
}
|
||||||
// 选择方式为设备且仅选中一个设备时,物模型取该设备
|
// 选择方式为设备且仅选中一个设备时,物模型取该设备
|
||||||
if (isFixed && addModel.selectorValues?.length === 1) {
|
const onlyOneDevice = isFixed && addModel.selectorValues?.length === 1
|
||||||
const resp = await deviceDetail(addModel.selectorValues[0].value)
|
handleMetadata( onlyOneDevice ? await getDeviceDetailByMetadata(addModel.selectorValues[0].value) : addModel.productDetail?.metadata)
|
||||||
handleMetadata(resp.result.metadata)
|
|
||||||
} else {
|
|
||||||
handleMetadata(addModel.productDetail?.metadata)
|
|
||||||
}
|
|
||||||
addModel.stepNumber = 2
|
addModel.stepNumber = 2
|
||||||
} else {
|
} else {
|
||||||
const typeData = await typeRef.value.vail()
|
const typeData = await typeRef.value.vail()
|
||||||
|
|
@ -273,6 +273,16 @@ const stepChange = (step: number) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const initQuery = async () => {
|
||||||
|
if (props.value.selector === 'fixed' && props.value.selectorValues?.length) {
|
||||||
|
handleMetadata(await getDeviceDetailByMetadata(props.value.selectorValues[0].value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
initQuery()
|
||||||
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<Search
|
<j-advanced-search
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
type='simple'
|
type='simple'
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
target="scene-triggrt-device-device"
|
target="scene-triggrt-device-device"
|
||||||
/>
|
/>
|
||||||
<a-divider style='margin: 0' />
|
<a-divider style='margin: 0' />
|
||||||
<j-table
|
<j-pro-table
|
||||||
ref='actionRef'
|
ref='actionRef'
|
||||||
model='CARD'
|
model='CARD'
|
||||||
:columns='columns'
|
:columns='columns'
|
||||||
|
|
@ -60,7 +60,7 @@
|
||||||
</template>
|
</template>
|
||||||
</CardBox>
|
</CardBox>
|
||||||
</template>
|
</template>
|
||||||
</j-table>
|
</j-pro-table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang='ts' name='DeviceSelectList'>
|
<script setup lang='ts' name='DeviceSelectList'>
|
||||||
|
|
@ -68,17 +68,17 @@ import type { PropType } from 'vue'
|
||||||
import { getImage } from '@/utils/comm'
|
import { getImage } from '@/utils/comm'
|
||||||
import { query } from '@/api/device/instance'
|
import { query } from '@/api/device/instance'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
|
import type { SelectorValuesItem } from '@/views/rule-engine/Scene/typings'
|
||||||
|
|
||||||
type Emit = {
|
type Emit = {
|
||||||
(e: 'update', data: Array<{ name: string, value: string}>): void
|
(e: 'update', data: SelectorValuesItem[]): void
|
||||||
}
|
}
|
||||||
|
|
||||||
const actionRef = ref()
|
|
||||||
const params = ref({})
|
const params = ref({})
|
||||||
const context = inject('SceneDeviceAddModel')
|
const context = inject('SceneDeviceAddModel')
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
rowKeys: {
|
rowKeys: {
|
||||||
type: Array as PropType<Array<{ name: string, value: string}>>,
|
type: Array as PropType<SelectorValuesItem[]>,
|
||||||
default: () => ([])
|
default: () => ([])
|
||||||
},
|
},
|
||||||
productId: {
|
productId: {
|
||||||
|
|
|
||||||
|
|
@ -12,17 +12,13 @@ import DeviceList from './DeviceList.vue'
|
||||||
import OrgList from './OrgList.vue'
|
import OrgList from './OrgList.vue'
|
||||||
import { getImage } from '@/utils/comm'
|
import { getImage } from '@/utils/comm'
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
|
import { SelectorValuesItem } from '@/views/rule-engine/Scene/typings'
|
||||||
type ItemType = {
|
|
||||||
name: string,
|
|
||||||
value: string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Emit = {
|
type Emit = {
|
||||||
(e: 'update:selector', data: string): void
|
(e: 'update:selector', data: string): void
|
||||||
(e: 'update:selectorValues', data: ItemType[]): void
|
(e: 'update:selectorValues', data: SelectorValuesItem[]): void
|
||||||
(e: 'update:deviceKeys', data: ItemType[]): void
|
(e: 'update:deviceKeys', data: SelectorValuesItem[]): void
|
||||||
(e: 'update:orgId', data: ItemType[]): void
|
(e: 'update:orgId', data: SelectorValuesItem[]): void
|
||||||
}
|
}
|
||||||
|
|
||||||
const emit = defineEmits<Emit>()
|
const emit = defineEmits<Emit>()
|
||||||
|
|
@ -36,18 +32,22 @@ const props = defineProps({
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
device: {
|
selectorValues: {
|
||||||
type: Array as PropType<ItemType[]>,
|
type: Array as PropType<SelectorValuesItem[]>,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
deviceKeys: {
|
||||||
|
type: Array as PropType<SelectorValuesItem[]>,
|
||||||
default: () => []
|
default: () => []
|
||||||
},
|
},
|
||||||
orgId: {
|
orgId: {
|
||||||
type: Array as PropType<ItemType[]>,
|
type: Array as PropType<SelectorValuesItem[]>,
|
||||||
default: () => []
|
default: () => []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const selectorModel = ref(props.selector)
|
const selectorModel = ref(props.selector)
|
||||||
const devices = ref(props.device)
|
const devices = ref(props.deviceKeys)
|
||||||
const orgIds = ref(props.orgId)
|
const orgIds = ref(props.orgId)
|
||||||
|
|
||||||
const typeList = [
|
const typeList = [
|
||||||
|
|
@ -69,6 +69,7 @@ const updateDevice = (d: any[]) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateOrg = (d: any[]) => {
|
const updateOrg = (d: any[]) => {
|
||||||
|
console.log('updateOrg', d)
|
||||||
orgIds.value = d
|
orgIds.value = d
|
||||||
emit('update:orgId', d)
|
emit('update:orgId', d)
|
||||||
emit('update:selectorValues', d)
|
emit('update:selectorValues', d)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<Search
|
<j-advanced-search
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
type='simple'
|
type='simple'
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
target="scene-triggrt-device-category"
|
target="scene-triggrt-device-category"
|
||||||
/>
|
/>
|
||||||
<a-divider style='margin: 0' />
|
<a-divider style='margin: 0' />
|
||||||
<JTable
|
<j-pro-table
|
||||||
ref="instanceRef"
|
ref="instanceRef"
|
||||||
model='TABLE'
|
model='TABLE'
|
||||||
type='TREE'
|
type='TREE'
|
||||||
|
|
@ -26,9 +26,10 @@
|
||||||
onChange: selectedRowChange
|
onChange: selectedRowChange
|
||||||
}'
|
}'
|
||||||
:onChange='tableChange'
|
:onChange='tableChange'
|
||||||
|
@selectCancel='cancelAll'
|
||||||
>
|
>
|
||||||
|
|
||||||
</JTable>
|
</j-pro-table>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -36,14 +37,15 @@
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import { getExpandedRowById } from './util'
|
import { getExpandedRowById } from './util'
|
||||||
import { getTreeData_api } from '@/api/system/department'
|
import { getTreeData_api } from '@/api/system/department'
|
||||||
|
import { SelectorValuesItem } from '@/views/rule-engine/Scene/typings'
|
||||||
|
|
||||||
type Emit = {
|
type Emit = {
|
||||||
(e: 'update', data: Array<{ name: string, value: string}>): void
|
(e: 'update', data: SelectorValuesItem[]): void
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
rowKeys: {
|
rowKeys: {
|
||||||
type: Array as PropType<Array<{ name: string, value: string}>>,
|
type: Array as PropType<SelectorValuesItem[]>,
|
||||||
default: () => ([])
|
default: () => ([])
|
||||||
},
|
},
|
||||||
productId: {
|
productId: {
|
||||||
|
|
@ -69,6 +71,9 @@ const columns = [
|
||||||
width: 300,
|
width: 300,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
|
search: {
|
||||||
|
type: 'string'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '排序',
|
title: '排序',
|
||||||
|
|
@ -109,10 +114,14 @@ const query = async (p: any) => {
|
||||||
return resp
|
return resp
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectedRowChange = (_: any, selectedRows: any[]) => {
|
const selectedRowChange = (values: any, selectedRows: any[]) => {
|
||||||
const item = selectedRows[0]
|
const item = selectedRows[0]
|
||||||
console.log(selectedRows)
|
console.log(values, selectedRows)
|
||||||
emit('update', item ? [{ name: item.name, value: item.id }] : [])
|
emit('update', [{ name: item.name, value: item.id }])
|
||||||
|
}
|
||||||
|
|
||||||
|
const cancelAll = () => {
|
||||||
|
emit('update', [])
|
||||||
}
|
}
|
||||||
|
|
||||||
const expandedRowChange = (keys: string[]) => {
|
const expandedRowChange = (keys: string[]) => {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<Search
|
<j-advanced-search
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
type='simple'
|
type='simple'
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
target="scene-triggrt-device-device"
|
target="scene-triggrt-device-device"
|
||||||
/>
|
/>
|
||||||
<a-divider style='margin: 0' />
|
<a-divider style='margin: 0' />
|
||||||
<j-table
|
<j-pro-table
|
||||||
ref='actionRef'
|
ref='actionRef'
|
||||||
model='CARD'
|
model='CARD'
|
||||||
:columns='columns'
|
:columns='columns'
|
||||||
|
|
@ -53,7 +53,7 @@
|
||||||
</template>
|
</template>
|
||||||
</CardBox>
|
</CardBox>
|
||||||
</template>
|
</template>
|
||||||
</j-table>
|
</j-pro-table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang='ts' name='Product'>
|
<script setup lang='ts' name='Product'>
|
||||||
|
|
@ -83,6 +83,7 @@ const props = defineProps({
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits<Emit>()
|
const emit = defineEmits<Emit>()
|
||||||
|
const firstFind = ref(true)
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
|
|
@ -230,7 +231,7 @@ const handleSearch = (p: any) => {
|
||||||
params.value = p
|
params.value = p
|
||||||
}
|
}
|
||||||
|
|
||||||
const productQuery = (p: any) => {
|
const productQuery = async (p: any) => {
|
||||||
const sorts: any = [];
|
const sorts: any = [];
|
||||||
|
|
||||||
if (props.rowKey) {
|
if (props.rowKey) {
|
||||||
|
|
@ -241,7 +242,15 @@ const productQuery = (p: any) => {
|
||||||
}
|
}
|
||||||
sorts.push({ name: 'createTime', order: 'desc' });
|
sorts.push({ name: 'createTime', order: 'desc' });
|
||||||
p.sorts = sorts
|
p.sorts = sorts
|
||||||
return queryProductList(p)
|
const resp = await queryProductList(p)
|
||||||
|
if (resp.success && props.rowKey && firstFind.value) {
|
||||||
|
const productItem = (resp.result as { data: any[]}).data.find((item: any) => item.id === props.rowKey)
|
||||||
|
emit('update:detail', productItem)
|
||||||
|
firstFind.value = false
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...resp
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleClick = (detail: any) => {
|
const handleClick = (detail: any) => {
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
<Title :options='data.options.trigger' />
|
<Title :options='data.options.trigger' />
|
||||||
</AddButton>
|
</AddButton>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<Terms />
|
||||||
<Action />
|
<Action />
|
||||||
<AddModel v-if='visible' @cancel='visible = false' @save='save' :value='data.trigger.device' :options='data.options.trigger' />
|
<AddModel v-if='visible' @cancel='visible = false' @save='save' :value='data.trigger.device' :options='data.options.trigger' />
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -26,6 +27,7 @@ import AddModel from './AddModal.vue'
|
||||||
import AddButton from '../components/AddButton.vue'
|
import AddButton from '../components/AddButton.vue'
|
||||||
import Title from '../components/Title.vue'
|
import Title from '../components/Title.vue'
|
||||||
import Action from '../action/index.vue'
|
import Action from '../action/index.vue'
|
||||||
|
import Terms from '../components/Terms'
|
||||||
import type { TriggerDevice } from '@/views/rule-engine/Scene/typings'
|
import type { TriggerDevice } from '@/views/rule-engine/Scene/typings'
|
||||||
|
|
||||||
const sceneStore = useSceneStore()
|
const sceneStore = useSceneStore()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,153 @@
|
||||||
|
<template>
|
||||||
|
<j-dropdown class='scene-select' trigger='click'>
|
||||||
|
<div :class='dropdownButtonClass'>
|
||||||
|
<span :style='LabelStyle'>
|
||||||
|
{{ label }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<template #overlay>
|
||||||
|
<template v-if='options.length'>
|
||||||
|
<j-menu v-if='component === "select"' @click='menuSelect'>
|
||||||
|
<j-menu-item v-for='item in options' :key='item.value'>{{ item.label }}</j-menu-item>
|
||||||
|
</j-menu>
|
||||||
|
<j-tree
|
||||||
|
:selectedKeys='selectValue ? [selectValue] : []'
|
||||||
|
:treeData='options'
|
||||||
|
@select='treeSelect'
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<div class='scene-select-empty' v-else>
|
||||||
|
<j-empty />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</j-dropdown>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang='ts' setup name='DropdownButton'>
|
||||||
|
import type { PropType } from 'vue'
|
||||||
|
|
||||||
|
type LabelType = string | number | undefined
|
||||||
|
|
||||||
|
type DropdownButtonOptions = {
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
children?: DropdownButtonOptions[];
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Emit = {
|
||||||
|
(e: 'update:value', data: string | number): void
|
||||||
|
(e: 'select', data: DropdownButtonOptions | undefined ): void
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: undefined
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: Array as PropType<Array<DropdownButtonOptions>>,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'column' // 'column' | 'termType' | 'value' | 'type'
|
||||||
|
},
|
||||||
|
component: {
|
||||||
|
type: String,
|
||||||
|
default: 'select' // 'select' | 'treeSelect'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits<Emit>()
|
||||||
|
|
||||||
|
const label = ref<LabelType>(props.placeholder)
|
||||||
|
const selectValue = ref(props.value)
|
||||||
|
const flatMapTree = new Map()
|
||||||
|
|
||||||
|
const LabelStyle = computed(() => {
|
||||||
|
return {
|
||||||
|
color: selectValue.value ? '#' : '#'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const dropdownButtonClass = computed(() => ({
|
||||||
|
'dropdown-button': true,
|
||||||
|
'column': props.type === 'column',
|
||||||
|
'termType': props.type === 'termType',
|
||||||
|
'value': props.type === 'value',
|
||||||
|
'type': props.type === 'type',
|
||||||
|
}))
|
||||||
|
|
||||||
|
const getOption = (key?: string | number): DropdownButtonOptions | undefined => {
|
||||||
|
let option
|
||||||
|
for(let i = props.options.length - 1; i >= 0; i --) {
|
||||||
|
const cacheOption = props.options[i]
|
||||||
|
if (cacheOption.value === key) {
|
||||||
|
option = {
|
||||||
|
...cacheOption
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return option
|
||||||
|
}
|
||||||
|
|
||||||
|
const treeSelect = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const menuSelect = (v: any) => {
|
||||||
|
const option = getOption(props.value)
|
||||||
|
emit('update:value', v.key)
|
||||||
|
emit('select', option)
|
||||||
|
}
|
||||||
|
|
||||||
|
watch([props.options, props.value], () => {
|
||||||
|
const option = getOption(props.value)
|
||||||
|
console.log(props.value)
|
||||||
|
if (option) {
|
||||||
|
label.value = option.label
|
||||||
|
} else {
|
||||||
|
label.value = props.value || props.placeholder
|
||||||
|
}
|
||||||
|
}, { immediate: true })
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang='less'>
|
||||||
|
.dropdown-button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 6px 8px;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column {
|
||||||
|
color: #00a4fe;
|
||||||
|
background-color: rgba(154, 219, 255, 0.3);
|
||||||
|
border-color: rgba(0, 164, 254, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.termType {
|
||||||
|
color: #2f54eb;
|
||||||
|
background-color: rgba(163, 202, 255, 0.3);
|
||||||
|
border-color: rgba(47, 84, 235, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
color: #692ca7;
|
||||||
|
background-color: rgba(188, 125, 238, 0.1);
|
||||||
|
border-color: rgba(188, 125, 238, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.type {
|
||||||
|
padding: 5px 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
<template>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'ParamsDropdown'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,135 @@
|
||||||
|
<template>
|
||||||
|
<div :class='["actions-terms-warp", props.class]'>
|
||||||
|
<div class='actions-terms-title'>
|
||||||
|
{{ isFirst ? '当' : '否则' }}
|
||||||
|
</div>
|
||||||
|
<div :class='optionsClass'>
|
||||||
|
<j-popconfirm
|
||||||
|
title='确认删除?'
|
||||||
|
@confirm='onDelete'
|
||||||
|
>
|
||||||
|
<div v-if='!isFirst' class='terms-params-delete danger show'>
|
||||||
|
<AIcon type='DeleteOutlined' />
|
||||||
|
</div>
|
||||||
|
</j-popconfirm>
|
||||||
|
<div
|
||||||
|
class='actions-terms-list'
|
||||||
|
@mouseover='mouseover'
|
||||||
|
@mouseout='mouseout'
|
||||||
|
>
|
||||||
|
<j-popconfirm
|
||||||
|
title='该操作将清空其它所有否则条件,确认删除?'
|
||||||
|
placement='topRight'
|
||||||
|
@confirm='onDeleteAll'
|
||||||
|
>
|
||||||
|
<AIcon type='CloseOutlined' v-show='showDelete' />
|
||||||
|
</j-popconfirm>
|
||||||
|
|
||||||
|
<div class='actions-terms-list-content'>
|
||||||
|
<template v-if='showWhen'>
|
||||||
|
<TermsItem
|
||||||
|
v-for='(item, index) in data.when'
|
||||||
|
:key='item.key'
|
||||||
|
:isFirst='index === 0'
|
||||||
|
:isLast='index === data.when.length -1'
|
||||||
|
:branchName='name'
|
||||||
|
:whenName='index'
|
||||||
|
:data='item'
|
||||||
|
:isFrist='index === 0'
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<span v-else class='when-add' @click='addWhen' :style='{ padding: isFirst ? "16px 0" : 0 }'>
|
||||||
|
<AIcon type='PlusCircleOutlined' style='padding: 4px' />
|
||||||
|
添加过滤条件
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class='actions-branches'>
|
||||||
|
<j-form-item></j-form-item>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang='ts' setup name='Branchs'>
|
||||||
|
import type { PropType } from 'vue'
|
||||||
|
import type { ActionBranchesProps } from '@/views/rule-engine/Scene/typings'
|
||||||
|
import TermsItem from './TermsItem.vue'
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { useSceneStore } from 'store/scene'
|
||||||
|
|
||||||
|
const sceneStore = useSceneStore()
|
||||||
|
const { data: FormModel } = storeToRefs(sceneStore)
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
isFirst: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: Object as PropType<ActionBranchesProps>,
|
||||||
|
default: () => ({
|
||||||
|
when: [],
|
||||||
|
shakeLimit: {},
|
||||||
|
then: []
|
||||||
|
})
|
||||||
|
},
|
||||||
|
class: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const showDelete = ref(false)
|
||||||
|
const error = ref(false)
|
||||||
|
|
||||||
|
const showWhen = computed(() => {
|
||||||
|
return props.data.when.length
|
||||||
|
})
|
||||||
|
|
||||||
|
const onDelete = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const onDeleteAll = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const mouseover = () => {
|
||||||
|
if (props.isFirst && props.data.when.length){
|
||||||
|
showDelete.value = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mouseout = () => {
|
||||||
|
if (props.isFirst && props.data.when.length){
|
||||||
|
showDelete.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const addWhen = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const optionsClass = computed(() => {
|
||||||
|
return {
|
||||||
|
'actions-terms-options': true,
|
||||||
|
border: !props.isFirst,
|
||||||
|
error: error
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang='less'>
|
||||||
|
.when-add {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #2F54EB;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,142 @@
|
||||||
|
<template>
|
||||||
|
<div class='terms-params-item'>
|
||||||
|
<div v-if='!isFirst' class='term-type-warp'>
|
||||||
|
<DropdownButton
|
||||||
|
:options='[
|
||||||
|
{ label: "并且", value: "and" },
|
||||||
|
{ label: "或者", value: "or" },
|
||||||
|
]'
|
||||||
|
type='type'
|
||||||
|
v-model:value='paramsValue.type'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class='params-item_button'
|
||||||
|
@mouseover='mouseover'
|
||||||
|
@mouseout='mouseout'
|
||||||
|
>
|
||||||
|
<DropdownButton
|
||||||
|
:options='options'
|
||||||
|
type='column'
|
||||||
|
placeholder='请选择参数'
|
||||||
|
v-model:value='paramsValue.column'
|
||||||
|
component='treeSelect'
|
||||||
|
@select='columnSelect'
|
||||||
|
/>
|
||||||
|
<DropdownButton
|
||||||
|
:options='termTypeOptions'
|
||||||
|
type="termType"
|
||||||
|
placeholder="操作符"
|
||||||
|
v-model:value='paramsValue.termsType'
|
||||||
|
@select='termsTypeSelect'
|
||||||
|
/>
|
||||||
|
<termplate v-if='showDouble'>
|
||||||
|
|
||||||
|
</termplate>
|
||||||
|
<j-popconfirm title='确认删除?' @confirm='onDelete'>
|
||||||
|
<div v-show='showDelete' class='button-delete'> <AIcon type='CloseOutlined' /></div>
|
||||||
|
</j-popconfirm>
|
||||||
|
</div>
|
||||||
|
<div class='term-add' @click.stop='termAdd'>
|
||||||
|
<div class='terms-content'>
|
||||||
|
<AIcon type='PlusOutlined' style='font-size: 12px' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang='ts' name='ParamsItem'>
|
||||||
|
import type { PropType } from 'vue'
|
||||||
|
import type { TermsType } from '@/views/rule-engine/Scene/typings'
|
||||||
|
import DropdownButton from '../DropdownButton.vue'
|
||||||
|
import { inject } from 'vue'
|
||||||
|
import { ContextKey } from './util'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
isFirst: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
isLast: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: Object as PropType<TermsType>,
|
||||||
|
default: () => ({
|
||||||
|
column: '',
|
||||||
|
type: '',
|
||||||
|
termsType: undefined,
|
||||||
|
value: undefined
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const paramsValue = reactive<TermsType>({
|
||||||
|
column: '',
|
||||||
|
type: '',
|
||||||
|
termType: undefined,
|
||||||
|
value: undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
const showDelete = ref(false)
|
||||||
|
const columnOptions = inject(ContextKey)
|
||||||
|
|
||||||
|
const options = computed(() => {
|
||||||
|
function handleOptions() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return []
|
||||||
|
})
|
||||||
|
|
||||||
|
const termTypeOptions = computed(() => {
|
||||||
|
|
||||||
|
return []
|
||||||
|
})
|
||||||
|
|
||||||
|
const showDouble = computed(() => {
|
||||||
|
return paramsValue.termType ? ['nbtw', 'btw', 'in', 'nin'].includes(paramsValue.termType) : false
|
||||||
|
})
|
||||||
|
|
||||||
|
const mouseover = () => {
|
||||||
|
if (props.name !== 0){
|
||||||
|
showDelete.value = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mouseout = () => {
|
||||||
|
if (props.name !== 0){
|
||||||
|
showDelete.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const columnSelect = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const termsTypeSelect = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const termAdd = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const onDelete = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
Object.assign(paramsValue, props.value)
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
<template>
|
||||||
|
<div class='actions-terms'>
|
||||||
|
<TitleComponent data='触发条件' style='font-size: 14px;' >
|
||||||
|
<template #extra>
|
||||||
|
<j-switch
|
||||||
|
:checked='open'
|
||||||
|
@change='change'
|
||||||
|
checkedChildren='开'
|
||||||
|
unCheckedChildren='关'
|
||||||
|
style='margin-left: 4px;'
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</TitleComponent>
|
||||||
|
<template v-if='open'>
|
||||||
|
<template v-for='(item, index) in data.branches'>
|
||||||
|
<Branches
|
||||||
|
v-if='!!item'
|
||||||
|
:data='item'
|
||||||
|
:isFirst='index === 0'
|
||||||
|
:name='index'
|
||||||
|
:key='item.key'
|
||||||
|
@delete='branchesDelete'
|
||||||
|
@deleteAll='branchesDeleteAll'
|
||||||
|
/>
|
||||||
|
<div v-else class='actions-terms-warp' :style='{ marginTop: data.branches.length === 2 ? 0 : 24 }'>
|
||||||
|
<div class='actions-terms-title' style='padding: 0'>
|
||||||
|
否则
|
||||||
|
</div>
|
||||||
|
<div class='actions-terms-options no-when'>
|
||||||
|
<AIcon type='PlusOutlined' class='when-add-button' @click='addBranches' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
<j-form-item
|
||||||
|
v-else
|
||||||
|
:name='["branches", 0, "then"]'
|
||||||
|
:rules='rules'
|
||||||
|
>
|
||||||
|
|
||||||
|
</j-form-item>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang='ts' name='Terms'>
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { useSceneStore } from 'store/scene'
|
||||||
|
import { cloneDeep } from 'lodash-es'
|
||||||
|
import { provide } from 'vue'
|
||||||
|
import { ContextKey } from './util'
|
||||||
|
import { getParseTerm } from '@/api/rule-engine/scene'
|
||||||
|
import type { FormModelType } from '@/views/rule-engine/Scene/typings'
|
||||||
|
import Branches from './Branchs.vue'
|
||||||
|
|
||||||
|
const sceneStore = useSceneStore()
|
||||||
|
const { data } = storeToRefs(sceneStore)
|
||||||
|
|
||||||
|
const open = ref(false)
|
||||||
|
const columnOptions = ref<any[]>([])
|
||||||
|
|
||||||
|
provide(ContextKey, columnOptions)
|
||||||
|
|
||||||
|
const change = (e: boolean) => {
|
||||||
|
open.value = e
|
||||||
|
}
|
||||||
|
|
||||||
|
const rules = [{
|
||||||
|
validator(_: string, value: any) {
|
||||||
|
if (!value || (value && !value.length)) {
|
||||||
|
return Promise.reject('至少配置一个执行动作')
|
||||||
|
} else {
|
||||||
|
const isActions = value.some((item: any) => item.actions && item.actions.length)
|
||||||
|
return isActions ? Promise.resolve() : Promise.reject('至少配置一个执行动作');
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
|
||||||
|
const queryColumn = (dataModel: FormModelType) => {
|
||||||
|
const cloneDevice = cloneDeep(dataModel)
|
||||||
|
cloneDevice.branches = cloneDevice.branches?.filter(item => !!item)
|
||||||
|
getParseTerm(cloneDevice).then(res => {
|
||||||
|
columnOptions.value = res as any
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const addBranches = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const branchesDelete = (index: number) => {
|
||||||
|
if ((data as FormModelType).branches?.length === 2) {
|
||||||
|
(data as FormModelType).branches?.splice(index, 1, null as any)
|
||||||
|
} else {
|
||||||
|
(data as FormModelType).branches?.splice(index, 1)
|
||||||
|
}
|
||||||
|
(data as FormModelType).options?.when?.splice(index, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
const branchesDeleteAll = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
if ((data as FormModelType).trigger?.device) {
|
||||||
|
queryColumn((data as FormModelType))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
watchEffect(() => {
|
||||||
|
open.value = !(
|
||||||
|
(data as FormModelType).branches &&
|
||||||
|
(data as FormModelType).branches?.length === 1
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang='less'>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,126 @@
|
||||||
|
<template>
|
||||||
|
<div class='terms-params'>
|
||||||
|
<div class='terms-params-warp'>
|
||||||
|
<div v-if='!isFirst' class='term-type-warp'>
|
||||||
|
<DropdownButton
|
||||||
|
:options='[
|
||||||
|
{ label: "并且", value: "and" },
|
||||||
|
{ label: "或者", value: "or" },
|
||||||
|
]'
|
||||||
|
type='type'
|
||||||
|
v-model:value='formModel.branches[branchName].when[whenName].type'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class='terms-params-content'
|
||||||
|
@mouseover='mouseover'
|
||||||
|
@mouseout='mouseout'
|
||||||
|
>
|
||||||
|
<j-popconfirm
|
||||||
|
title='确认删除?'
|
||||||
|
@confirm='onDelete'
|
||||||
|
>
|
||||||
|
<div v-show='showDelete' class='terms-params-delete'>
|
||||||
|
<AIcon type='CloseOutlined' />
|
||||||
|
</div>
|
||||||
|
</j-popconfirm>
|
||||||
|
|
||||||
|
<j-form-item
|
||||||
|
v-for='(item, index) in data.terms'
|
||||||
|
:key='item.key'
|
||||||
|
:name='["branches", branchName, "when", whenName, "terms", index]'
|
||||||
|
>
|
||||||
|
<ParamsItem
|
||||||
|
v-model:value='formModel.branches[branchName].when[whenName].terms[index]'
|
||||||
|
:isFirst='index === 0'
|
||||||
|
:isLast='index === data.terms.length - 1'
|
||||||
|
:name='index'
|
||||||
|
@change='paramsChange'
|
||||||
|
@delete='paramsDelete'
|
||||||
|
@add='paramsAdd'
|
||||||
|
/>
|
||||||
|
</j-form-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang='ts' name='TermsItem'>
|
||||||
|
import type { PropType } from 'vue'
|
||||||
|
import type { TermsType } from '@/views/rule-engine/Scene/typings'
|
||||||
|
import DropdownButton from '../DropdownButton.vue'
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { useSceneStore } from 'store/scene'
|
||||||
|
import ParamsItem from './ParamsItem.vue'
|
||||||
|
|
||||||
|
const sceneStore = useSceneStore()
|
||||||
|
const { data: formModel } = storeToRefs(sceneStore)
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
isFirst: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: Object as PropType<TermsType>,
|
||||||
|
default: () => ({
|
||||||
|
when: [],
|
||||||
|
shakeLimit: {},
|
||||||
|
then: []
|
||||||
|
})
|
||||||
|
},
|
||||||
|
class: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
branchName: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
whenName: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const showDelete = ref(false)
|
||||||
|
|
||||||
|
const mouseover = () => {
|
||||||
|
console.log(props.whenName)
|
||||||
|
if (props.whenName !== 0){
|
||||||
|
showDelete.value = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mouseout = () => {
|
||||||
|
console.log(props.whenName)
|
||||||
|
if (props.whenName !== 0){
|
||||||
|
showDelete.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onDelete = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const onDeleteAll = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const paramsChange = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const paramsDelete = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const paramsAdd = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,204 @@
|
||||||
|
.add-button() {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
color: rgba(0, 0, 0, 0.3);
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px dashed rgba(0, 0, 0, 0.3);
|
||||||
|
border-radius: 50%;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deleteBtn() {
|
||||||
|
position: absolute;
|
||||||
|
top: -10px;
|
||||||
|
right: -10px;
|
||||||
|
display: none;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
color: #999;
|
||||||
|
line-height: 20px;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
border-radius: 50%;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.show {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #f3f3f3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions-terms {
|
||||||
|
.actions-terms-warp {
|
||||||
|
display: flex;
|
||||||
|
width: 66.66%;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
|
||||||
|
&.first-children {
|
||||||
|
width: 100%;
|
||||||
|
.actions-branches {
|
||||||
|
width: 66.66%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.first-children,
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.when-add-button {
|
||||||
|
.add-button();
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions-terms-title {
|
||||||
|
width: 40px;
|
||||||
|
padding-top: 16px;
|
||||||
|
color: #6968be;
|
||||||
|
font-weight: 800;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions-terms-options {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
width: 0;
|
||||||
|
|
||||||
|
&.border {
|
||||||
|
padding: 10px 18px 0 18px;
|
||||||
|
border: 1px dashed #999;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.no-when {
|
||||||
|
flex: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions-terms-list {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.ant-form-item-has-error {
|
||||||
|
.params-item_button {
|
||||||
|
border-color: @error-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions-terms-list-content {
|
||||||
|
display: flex;
|
||||||
|
padding-top: 10px;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: visible;
|
||||||
|
row-gap: 16px;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.terms-params {
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
.terms-params-warp {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.terms-params-content {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
// flex-wrap: wrap;
|
||||||
|
padding: 8px;
|
||||||
|
padding-bottom: 0;
|
||||||
|
border: 1px dashed #e0e0e0;
|
||||||
|
//background-color: #fafafa;
|
||||||
|
border-radius: 6px;
|
||||||
|
row-gap: 16px;
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.terms-group-add {
|
||||||
|
width: 66px;
|
||||||
|
margin-left: 16px;
|
||||||
|
padding: 2px 8px;
|
||||||
|
color: rgba(0, 0, 0, 0.3);
|
||||||
|
background: #fff;
|
||||||
|
border: 1px dashed rgba(0, 0, 0, 0.3);
|
||||||
|
border-radius: 30px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.terms-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.term-type-warp {
|
||||||
|
width: 50px;
|
||||||
|
margin: 0 16px;
|
||||||
|
.term-type {
|
||||||
|
padding-top: 4px;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.terms-params-item {
|
||||||
|
.params-button {
|
||||||
|
padding: 6px 8px;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.params-item_button {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
gap: 2px;
|
||||||
|
|
||||||
|
|
||||||
|
.button-delete {
|
||||||
|
.deleteBtn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.term-add {
|
||||||
|
margin-left: 16px;
|
||||||
|
.add-button();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.terms-params-delete {
|
||||||
|
.deleteBtn();
|
||||||
|
|
||||||
|
&.danger {
|
||||||
|
color: #e50012;
|
||||||
|
background-color: rgba(229, 0, 18, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.filter-terms-params-delete {
|
||||||
|
transform: translateY(6px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
import Terms from './Terms.vue'
|
||||||
|
import './index.less'
|
||||||
|
|
||||||
|
export default Terms
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
export const ContextKey = 'columnOptions'
|
||||||
|
|
||||||
|
|
@ -122,13 +122,18 @@ export interface TriggerDeviceOptions {
|
||||||
functionParameters?: Record<string, any>[];
|
functionParameters?: Record<string, any>[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type SelectorValuesItem = {
|
||||||
|
name: string
|
||||||
|
value: any
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设备触发配置
|
* 设备触发配置
|
||||||
*/
|
*/
|
||||||
export interface TriggerDevice {
|
export interface TriggerDevice {
|
||||||
productId: string;
|
productId: string;
|
||||||
selector: string;
|
selector: string;
|
||||||
selectorValues?: Record<string, any>[];
|
selectorValues?: SelectorValuesItem[];
|
||||||
operation?: TriggerDeviceOptions;
|
operation?: TriggerDeviceOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,9 @@ import VueSetupExtend from 'vite-plugin-vue-setup-extend'
|
||||||
import { createStyleImportPlugin, AndDesignVueResolve } from 'vite-plugin-style-import'
|
import { createStyleImportPlugin, AndDesignVueResolve } from 'vite-plugin-style-import'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import monacoEditorPlugin from 'vite-plugin-monaco-editor';
|
import monacoEditorPlugin from 'vite-plugin-monaco-editor';
|
||||||
|
// import { JetlinksVueResolver } from 'jetlinks-ui-components/lib/plugin/resolve'
|
||||||
import { JetlinksVueResolver } from './plugin/jetlinks'
|
import { JetlinksVueResolver } from './plugin/jetlinks'
|
||||||
|
import copy from 'rollup-plugin-copy';
|
||||||
|
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
|
|
@ -75,6 +77,11 @@ export default defineConfig(({ mode}) => {
|
||||||
VueSetupExtend(),
|
VueSetupExtend(),
|
||||||
createStyleImportPlugin({
|
createStyleImportPlugin({
|
||||||
resolves: [AndDesignVueResolve()]
|
resolves: [AndDesignVueResolve()]
|
||||||
|
}),
|
||||||
|
copy({
|
||||||
|
targets: [
|
||||||
|
{src: 'node_modules/@liveqing/liveplayer-v3/dist/component/liveplayer-lib.min.js', dest: 'public/js'},
|
||||||
|
]
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
server: {
|
server: {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue