feat: 使用t-ui-plus完成图像源和多图采集模块内容开发

master
donghao 1 month ago
parent 21f381bd35
commit 6aabfd0832

@ -2,9 +2,11 @@
* @Author: donghao donghao@supervision.ltd * @Author: donghao donghao@supervision.ltd
* @Date: 2025-07-08 09:43:27 * @Date: 2025-07-08 09:43:27
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-07-08 09:47:01 * @LastEditTime: 2025-07-30 17:28:42
* @FilePath: \Robot-Al-Platform-Web\src\renderer\src\components\Button\index.ts * @FilePath: \Robot-Al-Platform-Web\src\renderer\src\components\Button\index.ts
* @Description: * @Description:
*/ */
import button from './src/button.tsx' import button from './src/button.tsx'
import addItemButton from './src/addItemButton.tsx'
export const DSButton = button export const DSButton = button
export const DSAddItemButton = addItemButton

@ -0,0 +1,105 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-07-29 10:48:37
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-07-31 14:07:39
* @FilePath: \Robot-Al-Platform-Web\src\renderer\src\components\Form\Button.tsx
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import { defineComponent, h, computed, normalizeClass } from 'vue'
import addIcon from '@/assets/images/common/table_addBtn.png'
export interface DsAddItemButtonProps {
/**
* Button
*/
// prefixRender?: (...ags: any[]) => any // 前缀内容 render渲染
/**
* Button
*/
suffixRender?: (...ags: any[]) => any // 后缀内容 render渲染
/**
* Button
*/
suffixText?: string
/**
* container
*/
iconClassName?: string
/**
*
*/
componentClassName?: string
}
export default defineComponent({
name: 'DSSwitch',
props: {
suffixRender: {
type: Function as DsAddItemButtonProps['suffixRender'],
default: null
},
suffixText: {
type: String,
default: ''
},
iconClassName: {
type: String,
default: ''
},
componentClassName: {
type: String,
default: ''
}
},
setup(props, { emit, attrs }) {
const { iconClassName, componentClassName, ...restProps } = props
// 处理自定义类名和 Vue 的 class 属性
const componentClasses = computed(() => {
const classes = [
'ds-formItem-add-btn cursor-pointer px-[10px] flex items-center',
componentClassName
]
// 处理 Vue 的 class 属性(支持字符串/数组/对象)
if (attrs.class) {
classes.push(normalizeClass(attrs.class))
}
return classes.filter((c) => c).join(' ')
})
// 处理自定义类名和 Vue 的 class 属性
const iconClasses = computed(() => {
const classes = ['w-[16px] h-[16px] mr-2', iconClassName]
// 处理 Vue 的 class 属性(支持字符串/数组/对象)
if (attrs.class) {
classes.push(normalizeClass(attrs.class))
}
return classes.filter((c) => c).join(' ')
})
// 渲染自定义前缀内容
// const renderPrefix = () => {
// if (props.prefixRender) {
// return props?.prefixRender?.()
// }
// return null
// }
// 渲染自定义后缀内容
const renderSuffix = () => {
if (props.suffixRender) {
return props?.suffixRender?.()
}
if (props.suffixText) {
return props.suffixText
}
return '添加数据'
}
return () => (
<div className={componentClasses.value}>
{/* {renderPrefix()} */}
<img src={addIcon} className={iconClasses.value} />
{renderSuffix()}
</div>
)
}
})

@ -2,43 +2,24 @@
* @Author: donghao donghao@supervision.ltd * @Author: donghao donghao@supervision.ltd
* @Date: 2025-07-29 10:48:37 * @Date: 2025-07-29 10:48:37
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-07-30 14:32:45 * @LastEditTime: 2025-07-31 10:09:54
* @FilePath: \Robot-Al-Platform-Web\src\renderer\src\components\Form\switch.tsx * @FilePath: \Robot-Al-Platform-Web\src\renderer\src\components\Form\switch.tsx
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: Switch
*/ */
import { defineComponent, h, withDefaults, computed, normalizeClass } from 'vue' import { defineComponent, h, withDefaults, computed, normalizeClass } from 'vue'
import { ElSwitch } from 'element-plus' import { ElSwitch } from 'element-plus'
import type { SwitchProps } from 'element-plus' import type { SwitchProps } from 'element-plus'
import { spawn } from 'child_process'
interface DsSwitchProps extends SwitchProps { interface DsSwitchProps extends SwitchProps {
/**
* switch
*/
label?: string label?: string
/**
* switch
*/
prefixRender?: (...ags: any[]) => any // 前缀内容 render渲染 prefixRender?: (...ags: any[]) => any // 前缀内容 render渲染
/**
* switch
*/
suffixRender?: (...ags: any[]) => any // 后缀内容 render渲染 suffixRender?: (...ags: any[]) => any // 后缀内容 render渲染
containerClassName?: string // container容器样式
/** componentClassName?: string // 整体容器样式
* container
*/
containerClassName?: string
/**
*
*/
componentClassName?: string
} }
export default defineComponent({ export default defineComponent({
name: 'DsSwitch', name: 'DSSwitch',
props: { props: {
modelValue: { modelValue: {
type: [Boolean, String, Number], type: [Boolean, String, Number],
@ -93,11 +74,7 @@ export default defineComponent({
if (props.prefixRender) { if (props.prefixRender) {
return props?.prefixRender?.() return props?.prefixRender?.()
} }
return ( return <span class="ds-switch-label">{props?.label}</span>
<span class="ds-switch-label">
{props?.label}
</span>
)
} }
// 渲染自定义后缀内容 // 渲染自定义后缀内容
const renderSuffix = () => { const renderSuffix = () => {

@ -0,0 +1,141 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2025-07-31 10:03:44
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-08-01 17:04:27
* @FilePath: \Robot-Al-Platform-Web\src\renderer\src\components\Form\formList.tsx
* @Description: formList
*/
//
import { defineComponent, getCurrentInstance, ComputedRef, computed, toRaw } from 'vue'
import type { FormTypes } from '@wocwin/t-ui-plus'
import { TForm } from '@wocwin/t-ui-plus'
import { ElMessage } from 'element-plus'
import { generateId } from '@/utils/plugins/random'
import { DSAddItemButton } from '@/components/Button'
import { Delete } from '@element-plus/icons-vue'
// 定义组件属性类型(保留所有 ElInputNumber 属性)
type DSFormListProps = {
formConfig: FormTypes
prefixRender?: (...ags: any[]) => any // 前置内容 render渲染
suffixRender?: (...ags: any[]) => any // 后置内容 render渲染
min?: number
max?: number
}
export default defineComponent({
name: 'DSFormList',
props: {
formConfig: {
type: Object as FormTypes,
default: {}
},
modelValue: {
type: Array,
default: () => []
},
min: {
type: Number,
default: 0
},
max: {
type: Number,
default: Infinity
}
},
emits: ['update:modelValue'],
setup(props: DSFormListProps, { emit, slots, attrs }) {
const tFormAttrs = (index) => {
const { formConfig, ...propsRest } = props
const refId = formConfig.ref + index
const finalOpts = {
...formConfig,
ref: refId,
modelValue: refId,
formData: props.modelValue[index]
}
return { ...finalOpts, formOpts: finalOpts }
}
const addItem = () => {
const list = props.modelValue
if (list.length >= props.max) {
ElMessage.warning(`最多只能添加 ${props.max}`)
return
}
list.push({ formItemsUuid: generateId() })
emit(
'update:modelValue',
list.map(({ formItemsUuid, ...rest }) => rest)
)
}
const removeItem = (formItem, index) => {
const list = props.modelValue
if (list.length <= props.min) {
ElMessage.warning(`至少需要保留 ${props.min}`)
return
}
console.log('removeItem', formItem, index)
list.splice(index, 1)
emit('update:modelValue', list)
}
const moveItem = (index, direction) => {
const list = props.modelValue
if (
(direction === 'up' && index === 0) ||
(direction === 'down' && index === list.length - 1)
) {
return
}
const newIndex = direction === 'up' ? index - 1 : index + 1
const item = list.splice(index, 1)[0]
list.splice(newIndex, 0, item)
emit('update:modelValue', list)
}
// const canAdd = list.length < props.max
// const canRemove = list.length > props.min
// 渲染自定义前缀内容
const renderPrefix = (formItem, index) => {
// props?.suffixRender &&
if (props.prefixRender) {
return props?.prefixRender?.()
}
return (
<div className="flex items-center">
<span>
{props.formConfig?.title}
{Number(index) + 1}
</span>
<div
onClick={() => removeItem(formItem, index)}
class="flex items-center justify-center ds-dialog-formList-delete"
>
<Delete />
</div>
</div>
)
}
return () => (
<div class="ds-form-list-comp">
<ul class="form-list">
{props.modelValue
.map((item) => ({
...item,
formItemsUuid: item?.id || generateId()
}))
.map((formItem, index) => (
<li class="form-item-card" key={formItem.formItemsUuid}>
{renderPrefix(formItem, index)}
<TForm className="ds-form-list-comp-form" {...tFormAttrs(index)}></TForm>
</li>
))}
</ul>
<DSAddItemButton {...tFormAttrs.value} onClick={() => addItem()}></DSAddItemButton>
</div>
)
}
})

@ -2,11 +2,13 @@
* @Author: donghao donghao@supervision.ltd * @Author: donghao donghao@supervision.ltd
* @Date: 2025-07-28 10:07:16 * @Date: 2025-07-28 10:07:16
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-07-30 11:29:49 * @LastEditTime: 2025-07-31 13:47:27
* @FilePath: \Robot-Al-Platform-Web\src\renderer\src\components\Form\index.ts * @FilePath: \Robot-Al-Platform-Web\src\renderer\src\components\Form\index.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description:
*/ */
import inputNumber from './inputNumber' import inputNumber from './inputNumber'
import dsSwitch from './dsSwitch' import dsSwitch from './dsSwitch'
import formList from './formList'
export const DSInputNumber = inputNumber export const DSInputNumber = inputNumber
export const DsSwitch = dsSwitch export const DSSwitch = dsSwitch
export const DSFormList = formList

@ -2,9 +2,9 @@
* @Author: donghao donghao@supervision.ltd * @Author: donghao donghao@supervision.ltd
* @Date: 2025-07-28 16:45:11 * @Date: 2025-07-28 16:45:11
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-07-30 14:30:36 * @LastEditTime: 2025-07-31 13:12:10
* @FilePath: \Robot-Al-Platform-Web\src\renderer\src\components\Form\inputNumber.tsx * @FilePath: \Robot-Al-Platform-Web\src\renderer\src\components\Form\inputNumber.tsx
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: inputNumber
*/ */
import { defineComponent, getCurrentInstance, ComputedRef, computed } from 'vue' import { defineComponent, getCurrentInstance, ComputedRef, computed } from 'vue'
import { ElInputNumber, inputNumberProps, InputNumberProps } from 'element-plus' import { ElInputNumber, inputNumberProps, InputNumberProps } from 'element-plus'
@ -16,6 +16,7 @@ type DSInputNumberProps = InputNumberProps & {
// 可在此处添加自定义属性 // 可在此处添加自定义属性
prefixRender?: (...ags: any[]) => any // 前置内容 render渲染 prefixRender?: (...ags: any[]) => any // 前置内容 render渲染
suffixRender?: (...ags: any[]) => any // 后置内容 render渲染 suffixRender?: (...ags: any[]) => any // 后置内容 render渲染
isHasSuffix?: boolean // 是否有后置内容
} }
export default defineComponent({ export default defineComponent({
@ -27,6 +28,10 @@ export default defineComponent({
controlsPosition: { controlsPosition: {
type: String, type: String,
default: 'right' default: 'right'
},
isHasSuffix: {
type: Boolean,
default: true
} }
}, },
emits: [ emits: [
@ -38,7 +43,7 @@ export default defineComponent({
'input' 'input'
] as unknown as InputNumberEmits, ] as unknown as InputNumberEmits,
setup(props: CustomInputNumberProps, { emit, slots, attrs }) { setup(props: DSInputNumberProps, { emit, slots, attrs }) {
const instance = getCurrentInstance()! const instance = getCurrentInstance()!
// 处理自定义逻辑 // 处理自定义逻辑
@ -74,6 +79,9 @@ export default defineComponent({
// 渲染自定义后缀内容 // 渲染自定义后缀内容
const renderSuffix = () => { const renderSuffix = () => {
// props?.suffixRender && // props?.suffixRender &&
if(!props.isHasSuffix){
return null
}
if (props.suffixRender) { if (props.suffixRender) {
return props?.suffixRender?.() return props?.suffixRender?.()
} }

@ -35,15 +35,5 @@
.el-dialog__header { .el-dialog__header {
height: var(--ds-dialog-header-height); height: var(--ds-dialog-header-height);
} }
//
.ds-dialog-icon-box {
width: 48px;
height: 32px;
background-color: var(--ds-dialog-icon-background-color);
font-size: 14px !important;
cursor: pointer;
svg {
width: 28px;
}
}
} }

@ -1,5 +1,10 @@
// //
.ds-dialog-form-container { .ds-dialog-form-container {
padding: 24px 12px 24px 24px;
.ds-dialog-form-footer {
margin-right: 12px;
}
.el-select__wrapper { .el-select__wrapper {
background: var(--ds-form-item-background-color) !important; background: var(--ds-form-item-background-color) !important;
.el-select__selected-item { .el-select__selected-item {
@ -16,36 +21,73 @@
} }
} }
/* 适配表单间距 */
.t-form {
gap: 16px 0;
}
.el-form-item--large { .el-form-item--large {
margin-bottom: 16px; margin-bottom: 0 !important;
// margin-right: 12px !important; .el-form-item__content {
width: calc(100% - 2px);
}
}
// proFormList
.ds-form-list-comp-form{
width: calc(100% + 12px);
} }
.el-form-item--large .el-form-item__content { .el-form-item--large .el-form-item__content {
line-height: 32px; line-height: 32px;
height: 32px; // height: 32px;
} }
.el-select--large .el-select__wrapper { .el-select--large .el-select__wrapper {
min-height: 32px; min-height: var(--ds-form-item-height);
padding: 4px 16px; padding: 4px 16px;
} }
// el-switch // el-switch
.el-switch--large .el-switch__core { .el-switch--large .el-switch__core {
border-radius: 16px; border-radius: 16px;
height: 20px; height: 20px;
line-height: 20; line-height: 20px;
min-width: 40px; min-width: 40px;
width: 40px; width: 40px;
} }
.ds-switch-box{
height: var(--ds-form-item-height);
}
//
.el-input__wrapper {
background: var(--ds-form-item-background-color);
}
} }
.el-input__wrapper { //
background: var(--ds-form-item-background-color) !important; .ds-form-normal-text {
color: var(--ds-color-info);
} }
// //
.ds-form-des-text { .ds-form-des-text {
color: var(--ds-des-text-1); color: var(--ds-des-text-1);
} }
//
.ds-form-normal-text { //
color: var(--ds-color-info); .ds-dialog-icon-box {
width: 48px;
height: 32px;
background-color: var(--ds-dialog-icon-background-color);
font-size: 14px !important;
cursor: pointer;
svg {
width: 28px;
}
}
// formList
.ds-dialog-formList-delete {
width: 48px;
height: 32px;
font-size: 14px !important;
cursor: pointer;
color: var(--ds-light-1);
svg {
width: 18px;
}
} }

@ -29,11 +29,13 @@
--ds-bg-color-light-5: #565656; // --ds-bg-color-light-5: #565656; //
// #4E5969 // #4E5969
--ds-light-0: #00b429; // 1 --ds-light-0: #00b429; // 1
--ds-light-1: #F53F3E; // 2
--ds-des-text-1: #86909c; // 8 --ds-des-text-1: #86909c; // 8
--ds-border-width: 1px; // --ds-border-width: 1px; //
--ds-border-color: #4e5969; // --ds-border-color: #4e5969; //
--ds-border-style: solid; // --ds-border-style: solid; //
--ds-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1); // --ds-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1); //
--ds-form-item-height: 32px; //
// --ds-light-2: #eaeaea; // 2 // --ds-light-2: #eaeaea; // 2
// --ds-light-3: #dcdcdc; // 3 // --ds-light-3: #dcdcdc; // 3

@ -97,7 +97,7 @@
margin-left: 0px; margin-left: 0px;
} }
.t-form .t-margin-top-5 { .t-form .t-margin-top-5 {
margin-top: 5px; margin-top: 0px; //
} }
.t-form .el-input-number .el-input .el-input__inner { .t-form .el-input-number .el-input .el-input__inner {
text-align: left; text-align: left;

@ -1,270 +0,0 @@
<template>
<t-layout-page>
<t-layout-page-item>
<t-form
ref="TFormDemo"
v-model="formOpts.ref"
:formOpts="formOpts"
:widthSize="2"
@handleEvent="handleEvent"
/>
</t-layout-page-item>
</t-layout-page>
</template>
<script setup lang="tsx">
import { ref, reactive } from "vue"
// ref
const TFormDemo = ref<HTMLElement | any>(null)
const table = {
data: [
{ id: 1, code: "1111", codeName: "供应商1", mobile: "13011111111", contact: "张三" },
{ id: 2, code: "2222", codeName: "供应商2", mobile: "13022222222", contact: "李四" },
{ id: 3, code: "3333", codeName: "供应商3", mobile: "13033333333", contact: "王五" },
{ id: 4, code: "4444", codeName: "供应商4", mobile: "13044444444", contact: "赵六" },
{ id: 5, code: "5555", codeName: "供应商5", mobile: "13055555555", contact: "钱七" },
{ id: 6, code: "6666", codeName: "供应商6", mobile: "13066666666", contact: "孙八" },
{ id: 7, code: "7777", codeName: "供应商7", mobile: "13077777777", contact: "周九" },
{ id: 8, code: "8888", codeName: "供应商8", mobile: "13088888888", contact: "吴十" },
{ id: 9, code: "9999", codeName: "供应商9", mobile: "13099999999", contact: "郑十一" }
],
columns: [
{ label: "供应商编号", width: "100px", prop: "code" },
{ label: "供应商名称", width: "149px", prop: "codeName" },
{ label: "负责人", width: "149px", prop: "contact" },
{ label: "电话号码", width: "110px", prop: "mobile" }
]
}
// formOpts.ref form
const submitForm = () => {
formOpts.ref.validate(valid => {
console.log(88, valid)
console.log(77, formOpts.formData)
if (!valid) return
console.log("最终数据", formOpts.formData)
})
}
// form
const resetForm = () => {
TFormDemo.value.selfResetFields()
}
//
const clearValidate = () => {
TFormDemo.value.clearValidate()
}
//
const validatorEmail = (rule, value, callback) => {
if (value && !/\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(value)) {
callback(new Error(rule.message))
}
callback()
}
const formOpts = reactive<FormTypes.FormOpts>({
// labelPosition: 'top',
ref: null,
formData: {
password: null, // *
name: null, // *
sex: null, // *: 0: 1:
phone: null, //
createDate: null, //
valDate: null, // el
wechat: null, //
qq: null, // qq
email: null, //
desc: null, //
code: null, // ',
codeName: null, // ',
mobile: null // ',
},
fieldList: [
{
label: "手机号码",
value: "phone",
type: "input",
comp: "el-input",
bind: { maxlength: 11 }
},
{
label: "密码",
value: "password",
type: "password",
comp: "el-input",
placeholder: "请先输入手机号码",
bind: formData => {
return {
disabled: formData.phone ? false : true
}
}
},
{ label: "昵称", value: "name", type: "input", comp: "el-input" },
{
label: "性别",
value: "sex",
type: "select-arr",
comp: "el-select",
list: "sexList",
arrLabel: "key",
arrKey: "value",
placeholder: "请先输入昵称",
bind: formData => {
return {
disabled: formData.name ? false : true
}
}
},
{ label: "QQ", value: "qq", type: "input", comp: "el-input" },
{
label: "邮箱",
value: "email",
type: "input",
comp: "el-input",
placeholder: "请先输入QQ",
bind: formData => {
return {
disabled: formData.qq ? false : true
}
}
},
{
label: "供应商编号",
value: "code",
placeholder: "t-select-table联动使用",
comp: "t-select-table",
isSelfCom: true,
bind: (formData: any) => {
return {
isKeyup: true,
maxHeight: 400,
selectWidth: 500,
defaultSelectVal: [formData.code],
keywords: { label: "code", value: "code" },
table: table,
columns: table.columns
}
},
eventHandle: {
radioChange: (val: any) => radioChange(val)
}
},
{
label: "供应商名称",
value: "codeName",
placeholder: "t-select-table联动使用",
comp: "t-select-table",
isSelfCom: true,
bind: (formData: any) => {
return {
isKeyup: true,
maxHeight: 400,
selectWidth: 500,
defaultSelectVal: [formData.codeName],
keywords: { label: "codeName", value: "codeName" },
table: table,
columns: table.columns
}
},
eventHandle: {
radioChange: (val: any) => radioChange1(val)
}
},
{
label: "电话号码",
value: "mobile",
placeholder: "t-select-table联动使用",
comp: "t-select-table",
isSelfCom: true,
bind: (formData: any) => {
return {
isKeyup: true,
maxHeight: 400,
selectWidth: 500,
defaultSelectVal: [formData.mobile],
keywords: { label: "mobile", value: "mobile" },
table: table,
columns: table.columns
}
},
eventHandle: {
radioChange: (val: any) => radioChange2(val)
}
},
{
label: "描述",
value: "desc",
type: "textarea",
comp: "el-input",
widthSize: 1
}
],
rules: {
account: [{ required: true, message: "请输入账号", trigger: "blur" }],
password: [{ required: true, message: "请输入密码", trigger: "blur" }],
name: [{ required: true, message: "请输入昵称", trigger: "blur" }],
phone: [{ required: true, message: "请输入手机号码", trigger: "blur" }],
sex: [{ required: true, message: "请选择性别", trigger: "change" }],
hobby: [
{
type: "array",
required: true,
message: "请至少选择一个爱好",
trigger: "change"
}
],
email: [
{
validator: validatorEmail,
message: "自定义配置校验规则",
trigger: "blur"
}
]
},
operatorList: [
{ label: "提交", bind: { type: "danger" }, fun: submitForm },
{ label: "重置", bind: { type: "primary" }, fun: resetForm },
{ label: "清除校验", bind: { type: "danger" }, fun: clearValidate }
],
//
listTypeInfo: {
hobbyList: [
{ label: "吉他", value: "0" },
{ label: "看书", value: "1" },
{ label: "美剧", value: "2" },
{ label: "旅游", value: "3" },
{ label: "音乐", value: "4" }
],
sexList: [
{ key: "女", value: 1 },
{ key: "男", value: 0 }
],
statusList: [
{ key: "启用", value: 1 },
{ key: "停用", value: 0 }
]
}
})
//
const handleEvent = (type, val) => {
switch (type) {
case "checkbox":
console.log("checkbox", val, type)
break
}
}
const radioChange = (row: any) => {
formOpts.formData.code = row?.code
formOpts.formData.codeName = row?.codeName
formOpts.formData.mobile = row?.mobile
}
const radioChange1 = (row: any) => {
formOpts.formData.code = row?.code
formOpts.formData.codeName = row?.codeName
formOpts.formData.mobile = row?.mobile
}
const radioChange2 = (row: any) => {
formOpts.formData.code = row?.code
formOpts.formData.codeName = row?.codeName
formOpts.formData.mobile = row?.mobile
}
</script>

@ -2,39 +2,17 @@
* @Author: donghao donghao@supervision.ltd * @Author: donghao donghao@supervision.ltd
* @Date: 2025-07-03 11:12:04 * @Date: 2025-07-03 11:12:04
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-07-30 15:52:28 * @LastEditTime: 2025-08-01 09:19:24
* @FilePath: \electron-project\Robot-Al\Robot-Al-Platform-Web\src\renderer\src\views\Design\FlowImagesCapture\imageNodeModel.vue * @FilePath: \electron-project\Robot-Al\Robot-Al-Platform-Web\src\renderer\src\views\Design\FlowImagesCapture\imageNodeModel.vue
* @Description: 图像源节点 * @Description: 图像源节点
--> -->
<template>
<DSDialog
v-model="show"
width="1200"
@close="handleClose"
class="settings-dialog ds-dialog"
title="图像源"
>
<template #default>
<div
class="imageNodeModel-form-container ds-dialog-form-container py-[24px] pl-[24px] pr-[14px]"
>
<t-module-form ref="sourceForm" titleBold :formOpts="formOpts" :submit="submit">
<template #footer>
<t-button type="primary" size="default" :time="config.buttonTimeOut">
<span class="px-[8px]" @click="save"> </span>
</t-button>
</template>
</t-module-form>
</div>
</template>
</DSDialog>
</template>
<script setup lang="tsx"> <script setup lang="tsx">
// import ThemeSwitcher from '@/components/Theme/themeSwitcher.vue'
import { DSDialog } from '@/components/Dialog' import { DSDialog } from '@/components/Dialog'
import { config } from '@/config' import { config } from '@/config'
defineOptions({
name: 'FlowImageNodeModel'
})
interface Props { interface Props {
/** 弹窗显隐 */ /** 弹窗显隐 */
value: boolean value: boolean
@ -115,7 +93,7 @@ const formOpts: any = reactive({
imageSource: '本地图像', // * imageSource: '本地图像', // *
/**基础参数-本地图像字段**/ /**基础参数-本地图像字段**/
pixelFormat: '', // * pixelFormat: '', // *
captureInterval: '', // * captureInterval: null, // *
displayImageName: false, // * displayImageName: false, // *
displaySaveImage: false, // * displaySaveImage: false, // *
snInitialValue: 10, // *SN snInitialValue: 10, // *SN
@ -176,7 +154,7 @@ const formOpts: any = reactive({
{ {
label: '取图间隔', label: '取图间隔',
value: 'captureInterval', value: 'captureInterval',
placeholder: '测试自定义组件1', placeholder: '请输入取图间隔',
comp: 'DSInputNumber', comp: 'DSInputNumber',
isSelfCom: true, isSelfCom: true,
bind: { bind: {
@ -193,7 +171,7 @@ const formOpts: any = reactive({
// //
{ {
value: 'displayImageName', value: 'displayImageName',
comp: 'DsSwitch', comp: 'DSSwitch',
isSelfCom: true, isSelfCom: true,
widthSize: 1, widthSize: 1,
bind: { bind: {
@ -206,7 +184,7 @@ const formOpts: any = reactive({
// //
{ {
value: 'displaySaveImage', value: 'displaySaveImage',
comp: 'DsSwitch', comp: 'DSSwitch',
isSelfCom: true, isSelfCom: true,
widthSize: 1, widthSize: 1,
bind: { bind: {
@ -219,7 +197,7 @@ const formOpts: any = reactive({
return data.imageSource === '本地图像' return data.imageSource === '本地图像'
} }
}, },
// sdk //
{ {
labelRender: () => { labelRender: () => {
return ( return (
@ -239,10 +217,10 @@ const formOpts: any = reactive({
arrKey: 'value', arrKey: 'value',
placeholder: '请选择关联相机', placeholder: '请选择关联相机',
isHideItem: (data) => { isHideItem: (data) => {
return data.imageSource !== '本地图像' return data.imageSource === '相机'
} }
}, },
// sdk //
{ {
label: '控制曝光', label: '控制曝光',
value: 'controlExposure', value: 'controlExposure',
@ -250,10 +228,10 @@ const formOpts: any = reactive({
comp: 'el-input', comp: 'el-input',
bind: { maxlength: 100 }, bind: { maxlength: 100 },
isHideItem: (data) => { isHideItem: (data) => {
return data.imageSource !== '本地图像' return data.imageSource === '相机'
} }
}, },
// sdk //
{ {
label: '控制增益', label: '控制增益',
value: 'controlGain', value: 'controlGain',
@ -261,7 +239,7 @@ const formOpts: any = reactive({
comp: 'el-input', comp: 'el-input',
bind: { maxlength: 100 }, bind: { maxlength: 100 },
isHideItem: (data) => { isHideItem: (data) => {
return data.imageSource !== '本地图像' return data.imageSource === '相机'
} }
}, },
// //
@ -286,7 +264,7 @@ const formOpts: any = reactive({
// sdk // sdk
{ {
value: 'outputMono8', value: 'outputMono8',
comp: 'DsSwitch', comp: 'DSSwitch',
isSelfCom: true, isSelfCom: true,
widthSize: 1, widthSize: 1,
bind: { bind: {
@ -310,7 +288,7 @@ const formOpts: any = reactive({
// //
{ {
value: 'stitchingEnabled', value: 'stitchingEnabled',
comp: 'DsSwitch', comp: 'DSSwitch',
isSelfCom: true, isSelfCom: true,
widthSize: 1, widthSize: 1,
bind: { bind: {
@ -364,7 +342,7 @@ const formOpts: any = reactive({
// //
{ {
value: 'triggerClear', value: 'triggerClear',
comp: 'DsSwitch', comp: 'DSSwitch',
isSelfCom: true, isSelfCom: true,
widthSize: 1, widthSize: 1,
bind: { bind: {
@ -425,7 +403,7 @@ const formOpts: any = reactive({
fieldList: [ fieldList: [
{ {
value: 'autoSwitch', value: 'autoSwitch',
comp: 'DsSwitch', comp: 'DSSwitch',
isSelfCom: true, isSelfCom: true,
widthSize: 3, widthSize: 3,
bind: { bind: {
@ -437,7 +415,7 @@ const formOpts: any = reactive({
}, },
{ {
value: 'stopOnLast', value: 'stopOnLast',
comp: 'DsSwitch', comp: 'DSSwitch',
isSelfCom: true, isSelfCom: true,
widthSize: 3, widthSize: 3,
bind: { bind: {
@ -449,7 +427,7 @@ const formOpts: any = reactive({
}, },
{ {
value: 'characterTriggerFilter', value: 'characterTriggerFilter',
comp: 'DsSwitch', comp: 'DSSwitch',
isSelfCom: true, isSelfCom: true,
widthSize: 1, widthSize: 1,
bind: { bind: {
@ -481,7 +459,26 @@ const formOpts: any = reactive({
} }
}) })
</script> </script>
<template>
<style scoped lang="scss"> <DSDialog
@import url('./imageNodeModel.scss'); v-model="show"
</style> width="1200"
@close="handleClose"
class="settings-dialog ds-dialog"
title="图像源"
>
<template #default>
<div class="imageNodeModel-form-container ds-dialog-form-container">
<t-module-form ref="sourceForm" titleBold :formOpts="formOpts" :submit="submit">
<template #footer>
<div class="ds-dialog-form-footer">
<t-button type="primary" size="default" :time="config.buttonTimeOut">
<span class="px-[8px]" @click="save"> </span>
</t-button>
</div>
</template>
</t-module-form>
</div>
</template>
</DSDialog>
</template>

@ -1,328 +0,0 @@
<script setup lang="ts">
/**
* @交互说明
* 1. 开始弹出设备选择对话框
* 2. 选择本地图像后展示相关内容
* 3. 选择相机后展示相关内容
*/
defineOptions({
name: 'FlowMultiImageNodeModel'
})
import { DSButton } from '@/components/Button'
import { DSDialog } from '@/components/Dialog'
import { RefreshRight } from '@element-plus/icons-vue'
interface Props {
/** import DeviceDialog from './deviceDialog.vue';
弹窗显隐 */
value: boolean
}
interface Emits {
(e: 'update:value', val: boolean): void
}
const props = withDefaults(defineProps<Props>(), {
value: false
})
const emit = defineEmits<Emits>()
console.log(props.value)
const show = computed({
get() {
Object.assign(deviceBars, deviceList)
return props.value
},
set(val: boolean) {
emit('update:value', val)
}
})
const isDeviceDialog = ref(false)
// tab
const deviceTab = ref('') // device/receive/send/heartbeat/response
const deviceBars = ref([])
const imageSourceOptions = [
{
value: '本地图像',
label: '本地图像'
},
{
value: '相机',
label: '相机'
}
]
const options = [
{
value: 'DPS2',
label: 'DPS2'
},
{
value: 'MV-AP1024-2T',
label: 'MV-AP1024-2T'
},
{
value: 'MV-LEVD',
label: 'MV-LEVD'
},
{
value: 'VB2200',
label: 'VB2200'
},
{
value: 'VC3000(Light)',
label: 'VC3000(Light)'
},
{
value: 'VB3000(IO)',
label: 'VB3000(IO)'
},
{
value: 'VC4000',
label: 'VC4000'
},
{
value: 'GPIO',
label: 'GPIO'
},
{
value: 'VB2230',
label: 'VB2230'
},
{
value: 'VC2000/2100',
label: 'VC2000/2100'
},
{
value: 'VC3000H/X',
label: 'VC3000H/X'
},
{
value: 'MV-LEVD-200',
label: 'MV-LEVD-200'
},
{
value: 'LE200',
label: 'LE200'
},
{
value: 'VC5000',
label: 'VC5000'
}
]
//
const deviceList = ref([
{
name: '1 Light-1',
enabled: false,
info: {
imageSource: '',
deviceName: '',
serialPort: '',
baudRate: '',
dataBits: '',
checkBit: '',
stopBit: '',
outputType: '',
sendInterval: '',
IOPort: '',
delayTime: '',
shakeTime: '',
devices: '',
reconnect: false,
polling: false,
reversal: false,
state: false,
endInfo: '',
channelBrightness1: 0,
channelBrightness2: 0,
channelBrightness3: 0,
channelBrightness4: 0,
channelBrightness5: 0,
channelBrightness6: 0,
pollingInterval: 0,
lightChannel: 0,
lightChannelStatus: '',
tableData: []
}
},
{ name: '2 Light-2', enabled: false }
])
//
const formDeviceInfo = reactive({
imageSource: '本地图像',
deviceName: '',
imageConfigs: [
{
distributionAngle: 90,
illuminationAngle: 0
}
],
reconnect: false,
polling: false,
outputPolarity: '', //
sendInterval: '',
IOPort: '',
delayTime: '', // IO
controlDelayTime: '', // IO
flickerDelayTime: '', //
endInfo: '',
channelBrightness1: 0,
channelBrightness2: 0
})
//
const handleAddImageConfig = () => {
formDeviceInfo.imageConfigs.push({
distributionAngle: 0,
illuminationAngle: 0
})
}
const handleDelImageConfig = (index) => {
formDeviceInfo.imageConfigs.splice(index, 1)
}
//
const handleClose = () => {}
</script>
<template>
<!-- 控制器管理弹框 -->
<DSDialog
title="多图采集"
v-model="show"
width="1200"
class="controllerManagement-dialog ds-dialog"
@close="handleClose"
>
<div class="controllerManagement-container ds-dialog-form-container">
<div class="controllerManagement-content">
<el-form label-width="auto" size="default" :model="formDeviceInfo" style="max-width: 100%">
<el-row :gutter="24">
<el-col :span="8">
<el-form-item label="图像源" label-position="top">
<el-select
v-model="formDeviceInfo.imageSource"
placeholder="请选择"
class="device-select"
>
<el-option
v-for="item in imageSourceOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8" v-if="formDeviceInfo.imageSource === '相机'">
<el-form-item label="关联相机 (请先在“相机管理”中新建相机)" label-position="top">
<el-select
v-model="formDeviceInfo.imageSource"
placeholder="请选择"
class="device-select"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="取图数量 (上限不超过8)" label-position="top">
<div class="flex">
<el-input-number
class="flex-1 w-full"
v-model="formDeviceInfo.deviceName"
:min="1"
:max="8"
controls-position="right"
@change="handleChange"
>
</el-input-number>
<span>
<el-icon class="el-input__icon"><Folder /></el-icon>
</span>
</div>
</el-form-item>
</el-col>
<el-col :span="8" v-if="formDeviceInfo.imageSource === '本地图像'">
<el-form-item label="图像路径" label-position="top">
<el-input v-model="formDeviceInfo.deviceName">
<template #suffix>
<el-icon class="el-input__icon"><Folder /></el-icon>
</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24" v-if="formDeviceInfo.imageSource === '本地图像'">
<el-col :span="24">
<el-form-item
v-for="(domain, index) in formDeviceInfo.imageConfigs"
:key="domain.key"
label-position="top"
label=""
:prop="'imageConfigs.' + index + '.value'"
>
<template #label>
<div class="flex items-center">
<p>{{ '图像配置' + (index + 1) }}</p>
<!-- // TODO -->
<DSButton
class="mx-[16px]"
type="text"
@click.prevent="handleDelImageConfig(index)"
>
<el-icon class="el-input__icon"><Delete /></el-icon>
</DSButton>
</div>
</template>
<div class="w-full">
<el-row :gutter="24">
<el-col :span="8">
<el-form-item label="分布角" label-position="top">
<el-input-number
v-model="domain.distributionAngle"
:min="0"
:max="360"
controls-position="right"
@change="handleChange"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="照射角" label-position="top">
<el-input-number
v-model="domain.illuminationAngle"
:min="0"
:max="360"
controls-position="right"
@change="handleChange"
/>
</el-form-item>
</el-col>
</el-row>
</div>
</el-form-item>
</el-col>
</el-row>
<div class="table-add-btn" @click="handleAddImageConfig">
<img
src="@/assets/images/common/table_addBtn.png"
alt=""
class="w-[16px] h-[16px] mr-2"
/>
</div>
</el-form>
</div>
</div>
</DSDialog>
</template>
<style scoped lang="scss">
@import url('./multiImageNodeModel.scss');
</style>

@ -1,40 +0,0 @@
/* 弹框整体样式 */
.controllerManagement-container {
position: relative;
width: 100%;
height: 766px;
box-sizing: border-box;
display: flex;
.controllerManagement-content {
flex: 1;
height: 100%;
overflow: auto;
box-sizing: border-box;
padding: 16px 24px 24px;
.form-device-btn {
width: 80px;
padding: 0 12px;
}
}
.custom-table {
.customList-table {
width: 100%;
height: 190px;
background: #363940;
}
}
.table-add-btn {
/* 按钮样式 */
box-sizing: border-box;
width: 128px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
}

@ -1,20 +1,26 @@
<script setup lang="ts"> <!--
/** * @Author: donghao donghao@supervision.ltd
* @交互说明 * @Date: 2025-07-03 11:12:04
* 1. 开始弹出设备选择对话框 * @LastEditors: donghao donghao@supervision.ltd
* 2. 选择本地图像后展示相关内容 * @LastEditTime: 2025-08-01 17:27:00
* 3. 选择相机后展示相关内容 * @FilePath: \electron-project\Robot-Al\Robot-Al-Platform-Web\src\renderer\src\views\Design\FlowImagesCapture\imageNodeModel.vue
*/ * @Description: 图像源节点
-->
<script setup lang="tsx">
// import ThemeSwitcher from '@/components/Theme/themeSwitcher.vue'
import { DSDialog } from '@/components/Dialog'
import { DSAddItemButton } from '@/components/Button'
import { config } from '@/config'
import { Folder } from '@element-plus/icons-vue'
// import { DsFormList } from '@/components/Form'
defineOptions({ defineOptions({
name: 'FlowMultiImageNodeModel' name: 'FlowMultiImageNodeModel'
}) })
import { DSButton } from '@/components/Button'
import { DSDialog } from '@/components/Dialog'
import { RefreshRight } from '@element-plus/icons-vue'
interface Props { interface Props {
/** import DeviceDialog from './deviceDialog.vue'; /** 弹窗显隐 */
弹窗显隐 */
value: boolean value: boolean
// info?: Record<string, any>
} }
interface Emits { interface Emits {
(e: 'update:value', val: boolean): void (e: 'update:value', val: boolean): void
@ -23,61 +29,33 @@ const props = withDefaults(defineProps<Props>(), {
value: false value: false
}) })
const emit = defineEmits<Emits>() const emit = defineEmits<Emits>()
console.log(props.value)
//
const handleClose = () => {
// emits('close');
}
const show = computed({ const show = computed({
get() { get() {
Object.assign(deviceBars, deviceList)
return props.value return props.value
}, },
set(val: boolean) { set(val: boolean) {
emit('update:value', val) emit('update:value', val)
} }
}) })
const isDeviceDialog = ref(false) // ref
// tab const sourceForm: any = ref<HTMLElement | null>(null)
const deviceTab = ref('') // device/receive/send/heartbeat/response
const deviceBars = ref([])
const imageSourceOptions = [ const formActiveList = reactive([])
{ // form
value: '本地图像', const submit = (form) => {
label: '本地图像' console.log(formActiveList.cameraData, '最终提交数据', form)
}, }
{
value: '相机',
label: '相机'
}
]
const options = [ const save = () => {
{ sourceForm.value.saveHandle()
value: 'DPS2', }
label: 'DPS2' const testList = [
},
{
value: 'MV-AP1024-2T',
label: 'MV-AP1024-2T'
},
{
value: 'MV-LEVD',
label: 'MV-LEVD'
},
{
value: 'VB2200',
label: 'VB2200'
},
{
value: 'VC3000(Light)',
label: 'VC3000(Light)'
},
{
value: 'VB3000(IO)',
label: 'VB3000(IO)'
},
{
value: 'VC4000',
label: 'VC4000'
},
{ {
value: 'GPIO', value: 'GPIO',
label: 'GPIO' label: 'GPIO'
@ -107,68 +85,329 @@ const options = [
label: 'VC5000' label: 'VC5000'
} }
] ]
//
const deviceList = ref([ //
{ const activeLocalImageConfig = reactive({
name: '1 Light-1', widthSize: 2, // 3
enabled: false, title: '图像配置',
info: { labelPosition: 'top', //
imageSource: '', ref: 'activeImageRef',
deviceName: '', formData: {
serialPort: '', distributionAngle: null, // *
baudRate: '', illuminationAngle: null // *
dataBits: '', },
checkBit: '', fieldList: [
stopBit: '', {
outputType: '', placeholder: '请输入分布角',
sendInterval: '', label: '分布角',
IOPort: '', value: 'distributionAngle',
delayTime: '', comp: 'DSInputNumber',
shakeTime: '', isSelfCom: true,
devices: '', bind: {
reconnect: false, min: -360,
polling: false, max: 360,
reversal: false, isHasSuffix: false
state: false, }
endInfo: '', },
channelBrightness1: 0, {
channelBrightness2: 0, placeholder: '请输入照射角',
channelBrightness3: 0, label: '照射角',
channelBrightness4: 0, value: 'illuminationAngle',
channelBrightness5: 0, comp: 'DSInputNumber',
channelBrightness6: 0, isSelfCom: true,
pollingInterval: 0, bind: {
lightChannel: 0, min: -360,
lightChannelStatus: '', max: 360,
tableData: [] isHasSuffix: false
}
} }
]
})
//
const activeCamareConfig = reactive({
widthSize: 4, // 3
title: '图像配置',
labelPosition: 'top', //
ref: 'activeCameraRef',
formData: {
cameraExposure: null, // *
cameraGain: null, // *
lightSource: null, // * ("")
triggerDelay: null, // *(ms)
lightSourceChannel: null, // *
lightSourceBrightness: null, // *
distributionAngle: null, // *
illuminationAngle: null // *
}, },
{ name: '2 Light-2', enabled: false } fieldList: [
]) {
placeholder: '请输入相机曝光',
label: '相机曝光',
value: 'cameraExposure',
comp: 'DSInputNumber',
isSelfCom: true,
bind: {
min: 0,
max: 100,
isHasSuffix: false
}
},
{
placeholder: '请输入相机增益',
label: '相机增益',
value: 'cameraGain',
comp: 'DSInputNumber',
isSelfCom: true,
bind: {
min: 0,
max: 100,
isHasSuffix: false
}
},
{
labelRender: () => {
return (
<div>
<span>光源设备</span>
<span className="ds-form-des-text">
(请先在<span className="ds-form-normal-text">控制管理器</span>中配置光源)
</span>
</div>
)
},
value: 'relatedCamera',
type: 'select-arr',
comp: 'el-select',
list: 'testList',
arrLabel: 'label',
arrKey: 'value',
placeholder: '请选择光源设备'
},
{
placeholder: '请输入触发时间',
label: '触发时间(ms)',
value: 'triggerDelay',
comp: 'DSInputNumber',
isSelfCom: true,
bind: {
min: 0,
max: 100000,
isHasSuffix: false
}
},
{
placeholder: '请输入光源通道',
label: '光源通道',
value: 'lightSourceChannel',
comp: 'DSInputNumber',
isSelfCom: true,
bind: {
min: 0,
max: 100,
isHasSuffix: false
}
},
{
placeholder: '请输入光源亮度',
label: '光源亮度',
value: 'lightSourceBrightness',
comp: 'DSInputNumber',
isSelfCom: true,
bind: {
min: 0,
max: 100,
isHasSuffix: false
}
},
{
placeholder: '请输入分布角',
label: '分布角',
value: 'distributionAngle',
comp: 'DSInputNumber',
isSelfCom: true,
bind: {
min: -360,
max: 360,
isHasSuffix: false
}
},
{
placeholder: '请输入照射角',
label: '照射角',
value: 'illuminationAngle',
comp: 'DSInputNumber',
isSelfCom: true,
bind: {
min: -360,
max: 360,
isHasSuffix: false
}
}
],
//
listTypeInfo: {
testList
}
})
//
const formOpts: any = reactive({
inputConfig: {
title: '输入配置',
name: 'inputConfig',
disabled: true, //
ref: null,
widthSize: 3, // 3
opts: {
labelPosition: 'top', //
formData: {
imageSource: '本地图像', // *
relatedCamera: '', // *
captureCount: 0, // *
imageSavePath: '', // *
localImages: [
{
distributionAngle: 90,
illuminationAngle: 0
},
{
distributionAngle: 190,
illuminationAngle: 20
},
{
distributionAngle: 100,
illuminationAngle: -78
},
{
distributionAngle: 26,
illuminationAngle: 33
}
],
camaras: []
},
fieldList: [
/**基础参数-表单项**/
//
{
label: '图像源',
value: 'imageSource',
type: 'select-arr',
comp: 'el-select',
list: 'imageSourceList',
arrLabel: 'key',
arrKey: 'value',
placeholder: '请选择图像源',
eventHandle: {
change: (val: any) => {
console.log(val, 'selectChange_imageSource')
}
},
bind: { clearable: false }
},
//
{
labelRender: () => {
return (
<div>
<span>关联相机</span>
<span className="ds-form-des-text">
(请先在<span className="ds-form-normal-text">相机管理</span>中新建相机)
</span>
</div>
)
},
value: 'relatedCamera',
type: 'select-arr',
comp: 'el-select',
list: 'testList',
arrLabel: 'label',
arrKey: 'value',
placeholder: '请选择关联相机',
isHideItem: (data) => {
return data.imageSource === '相机'
}
},
//
{
placeholder: '请输入取图数量',
labelRender: () => {
return (
<div>
<span>取图数量</span>
<span className="ds-form-des-text">上限不超过8</span>
</div>
)
},
value: 'captureCount',
comp: 'DSInputNumber',
isSelfCom: true,
bind: {
min: 0,
max: 8
}
},
//
{
label: '取图路径',
value: 'imageSavePath',
placeholder: '请输入取图路径',
comp: 't-input',
isSelfCom: true,
bind: {
suffixIcon: Folder
},
eventHandle: {
change: (val: any) => {}
},
isHideItem: (data) => {
return data.imageSource === '本地图像'
}
},
{
widthSize: 1, // 3
value: 'localImages',
comp: 'DSFormList',
isSelfCom: true,
bind: {
formConfig: activeLocalImageConfig
},
isHideItem: (data) => {
return data.imageSource === '本地图像'
}
},
{
widthSize: 1, // 3
value: 'camaras',
comp: 'DSFormList',
isSelfCom: true,
bind: {
formConfig: activeCamareConfig
},
isHideItem: (data) => {
return data.imageSource === '相机'
}
}
],
//
listTypeInfo: {
testList,
imageSourceList: [
{ key: '本地图像', value: '本地图像' },
{ key: '相机', value: '相机' }
]
}
}
}
})
// //
const formDeviceInfo = reactive({ const formDeviceInfo = reactive({
imageSource: '本地图像',
deviceName: '',
imageConfigs: [ imageConfigs: [
{ {
distributionAngle: 90, distributionAngle: 90,
illuminationAngle: 0 illuminationAngle: 0
} }
], ]
reconnect: false,
polling: false,
outputPolarity: '', //
sendInterval: '',
IOPort: '',
delayTime: '', // IO
controlDelayTime: '', // IO
flickerDelayTime: '', //
endInfo: '',
channelBrightness1: 0,
channelBrightness2: 0
}) })
// //
@ -179,150 +418,49 @@ const handleAddImageConfig = () => {
}) })
} }
const handleDelImageConfig = (index) => { onMounted(() => {
formDeviceInfo.imageConfigs.splice(index, 1) setTimeout(() => {
} formActiveList.cameraData = [
// {
const handleClose = () => {} distributionAngle: 90,
illuminationAngle: 0
},
{
distributionAngle: 190,
illuminationAngle: 20
},
{
distributionAngle: 100,
illuminationAngle: -78
},
{
distributionAngle: 26,
illuminationAngle: 33
}
]
}, 2000)
})
</script> </script>
<template> <template>
<!-- 控制器管理弹框 -->
<DSDialog <DSDialog
title="多图采集"
v-model="show" v-model="show"
width="1200" width="1200"
class="controllerManagement-dialog ds-dialog"
@close="handleClose" @close="handleClose"
class="settings-dialog ds-dialog"
title="多图采集"
> >
<div class="controllerManagement-container ds-dialog-form-container"> <template #default>
<div class="controllerManagement-content"> <div class="imageNodeModel-form-container ds-dialog-form-container">
<el-form label-width="auto" size="default" :model="formDeviceInfo" style="max-width: 100%"> <t-module-form ref="sourceForm" titleBold :formOpts="formOpts" :submit="submit">
<el-row :gutter="24"> <template #footer>
<el-col :span="8"> <div class="ds-dialog-form-footer">
<el-form-item label="图像源" label-position="top"> <t-button type="primary" size="default" :time="config.buttonTimeOut">
<el-select <span class="px-[8px]" @click="save"> </span>
v-model="formDeviceInfo.imageSource" </t-button>
placeholder="请选择" </div>
class="device-select" </template>
> </t-module-form>
<el-option
v-for="item in imageSourceOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8" v-if="formDeviceInfo.imageSource === '相机'">
<el-form-item label="关联相机 (请先在“相机管理”中新建相机)" label-position="top">
<el-select
v-model="formDeviceInfo.imageSource"
placeholder="请选择"
class="device-select"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="取图数量 (上限不超过8)" label-position="top">
<div class="flex">
<el-input-number
class="flex-1 w-full"
v-model="formDeviceInfo.deviceName"
:min="1"
:max="8"
controls-position="right"
@change="handleChange"
>
</el-input-number>
<span>
<el-icon class="el-input__icon"><Folder /></el-icon>
</span>
</div>
</el-form-item>
</el-col>
<el-col :span="8" v-if="formDeviceInfo.imageSource === '本地图像'">
<el-form-item label="图像路径" label-position="top">
<el-input v-model="formDeviceInfo.deviceName">
<template #suffix>
<el-icon class="el-input__icon"><Folder /></el-icon>
</template>
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24" v-if="formDeviceInfo.imageSource === '本地图像'">
<el-col :span="24">
<el-form-item
v-for="(domain, index) in formDeviceInfo.imageConfigs"
:key="domain.key"
label-position="top"
label=""
:prop="'imageConfigs.' + index + '.value'"
>
<template #label>
<div class="flex items-center">
<p>{{ '图像配置' + (index + 1) }}</p>
<!-- // TODO -->
<DSButton
class="mx-[16px]"
type="text"
@click.prevent="handleDelImageConfig(index)"
>
<el-icon class="el-input__icon"><Delete /></el-icon>
</DSButton>
</div>
</template>
<div class="w-full">
<el-row :gutter="24">
<el-col :span="8">
<el-form-item label="分布角" label-position="top">
<el-input-number
v-model="domain.distributionAngle"
:min="0"
:max="360"
controls-position="right"
@change="handleChange"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="照射角" label-position="top">
<el-input-number
v-model="domain.illuminationAngle"
:min="0"
:max="360"
controls-position="right"
@change="handleChange"
/>
</el-form-item>
</el-col>
</el-row>
</div>
</el-form-item>
</el-col>
</el-row>
<div class="table-add-btn" @click="handleAddImageConfig">
<img
src="@/assets/images/common/table_addBtn.png"
alt=""
class="w-[16px] h-[16px] mr-2"
/>
</div>
</el-form>
</div> </div>
</div> </template>
</DSDialog> </DSDialog>
</template> </template>
<style scoped lang="scss">
@import url('./multiImageNodeModel.scss');
</style>

@ -129,15 +129,15 @@ const initEvents = () => {
// // currNodeData.value = data // // currNodeData.value = data
// console.log('node:click-currNodeData', currNodeData.value) // console.log('node:click-currNodeData', currNodeData.value)
// // changeAttrPanelStatus(true) // // changeAttrPanelStatus(true)
// currNodeData.value = data
// console.log('node:dbclick-currNodeData', currNodeData.value)
// changeAttrPanelStatus(true)
})
lf.value.on('node:dbclick', ({ data }) => {
currNodeData.value = data currNodeData.value = data
console.log('node:dbclick-currNodeData', currNodeData.value) console.log('node:dbclick-currNodeData', currNodeData.value)
changeAttrPanelStatus(true) changeAttrPanelStatus(true)
}) })
// lf.value.on('node:dbclick', ({ data }) => {
// currNodeData.value = data
// console.log('node:dbclick-currNodeData', currNodeData.value)
// changeAttrPanelStatus(true)
// })
// lf.value.on('edge:dbclick', ({ data }) => { // lf.value.on('edge:dbclick', ({ data }) => {
// currNodeData.value = data // currNodeData.value = data
// }) // })

Loading…
Cancel
Save