+
@@ -23,10 +23,19 @@
{{ scaleValue }}%
+ 重置
-
@@ -76,11 +85,51 @@ const emits = defineEmits<{
const processNodeTree = useWatchNode(props)
provide('readonly', props.readonly)
+
+// TODO 可优化:拖拽有点卡顿
+/** 拖拽、放大缩小等操作 */
let scaleValue = ref(100)
const MAX_SCALE_VALUE = 200
const MIN_SCALE_VALUE = 50
+const isDragging = ref(false)
+const startX = ref(0)
+const startY = ref(0)
+const currentX = ref(0)
+const currentY = ref(0)
+const initialX = ref(0)
+const initialY = ref(0)
+
+const setGrabCursor = () => {
+ document.body.style.cursor = 'grab'
+}
+
+const resetCursor = () => {
+ document.body.style.cursor = 'default'
+}
+
+const startDrag = (e: MouseEvent) => {
+ isDragging.value = true
+ startX.value = e.clientX - currentX.value
+ startY.value = e.clientY - currentY.value
+ setGrabCursor() // 设置小手光标
+}
+
+const onDrag = (e: MouseEvent) => {
+ if (!isDragging.value) return
+ e.preventDefault() // 禁用文本选择
+
+ // 使用 requestAnimationFrame 优化性能
+ requestAnimationFrame(() => {
+ currentX.value = e.clientX - startX.value
+ currentY.value = e.clientY - startY.value
+ })
+}
+
+const stopDrag = () => {
+ isDragging.value = false
+ resetCursor() // 重置光标
+}
-// 放大
const zoomIn = () => {
if (scaleValue.value == MAX_SCALE_VALUE) {
return
@@ -88,7 +137,6 @@ const zoomIn = () => {
scaleValue.value += 10
}
-// 缩小
const zoomOut = () => {
if (scaleValue.value == MIN_SCALE_VALUE) {
return
@@ -100,20 +148,15 @@ const processReZoom = () => {
scaleValue.value = 100
}
+const resetPosition = () => {
+ currentX.value = initialX.value
+ currentY.value = initialY.value
+}
+
+/** 校验节点设置 */
const errorDialogVisible = ref(false)
let errorNodes: SimpleFlowNode[] = []
-const saveSimpleFlowModel = async () => {
- errorNodes = []
- validateNode(processNodeTree.value, errorNodes)
- if (errorNodes.length > 0) {
- errorDialogVisible.value = true
- return
- }
- emits('save', processNodeTree.value)
-}
-
-// 校验节点设置。 暂时以 showText 为空 未节点错误配置
const validateNode = (node: SimpleFlowNode | undefined, errorNodes: SimpleFlowNode[]) => {
if (node) {
const { type, showText, conditionNodes } = node
@@ -193,6 +236,30 @@ const importLocalFile = () => {
}
}
}
+
+// 在组件初始化时记录初始位置
+onMounted(() => {
+ initialX.value = currentX.value
+ initialY.value = currentY.value
+})
-
+
diff --git a/src/components/SimpleProcessDesignerV2/src/SimpleProcessViewer.vue b/src/components/SimpleProcessDesignerV2/src/SimpleProcessViewer.vue
index abf73b481..26cd43fd3 100644
--- a/src/components/SimpleProcessDesignerV2/src/SimpleProcessViewer.vue
+++ b/src/components/SimpleProcessDesignerV2/src/SimpleProcessViewer.vue
@@ -45,4 +45,3 @@ watch(
provide('tasks', approveTasks)
provide('processInstance', currentProcessInstance)
-p
diff --git a/src/components/SimpleProcessDesignerV2/src/consts.ts b/src/components/SimpleProcessDesignerV2/src/consts.ts
index f0614eefa..8cdc99651 100644
--- a/src/components/SimpleProcessDesignerV2/src/consts.ts
+++ b/src/components/SimpleProcessDesignerV2/src/consts.ts
@@ -23,6 +23,11 @@ export enum NodeType {
*/
COPY_TASK_NODE = 12,
+ /**
+ * 办理人节点
+ */
+ TRANSACTOR_NODE = 13,
+
/**
* 延迟器节点
*/
@@ -33,6 +38,11 @@ export enum NodeType {
*/
TRIGGER_NODE = 15,
+ /**
+ * 子流程节点
+ */
+ CHILD_PROCESS_NODE = 20,
+
/**
* 条件节点
*/
@@ -123,6 +133,8 @@ export interface SimpleFlowNode {
reasonRequire?: boolean
// 触发器设置
triggerSetting?: TriggerSetting
+ // 子流程
+ childProcessSetting?: ChildProcessSetting
}
// 候选人策略枚举 ( 用于审批节点。抄送节点 )
export enum CandidateStrategy {
@@ -150,6 +162,10 @@ export enum CandidateStrategy {
* 指定用户
*/
USER = 30,
+ /**
+ * 审批人自选
+ */
+ APPROVE_USER_SELECT = 34,
/**
* 发起人自选
*/
@@ -506,6 +522,8 @@ NODE_DEFAULT_TEXT.set(NodeType.START_USER_NODE, '请设置发起人')
NODE_DEFAULT_TEXT.set(NodeType.DELAY_TIMER_NODE, '请设置延迟器')
NODE_DEFAULT_TEXT.set(NodeType.ROUTER_BRANCH_NODE, '请设置路由节点')
NODE_DEFAULT_TEXT.set(NodeType.TRIGGER_NODE, '请设置触发器')
+NODE_DEFAULT_TEXT.set(NodeType.TRANSACTOR_NODE, '请设置办理人')
+NODE_DEFAULT_TEXT.set(NodeType.CHILD_PROCESS_NODE, '请设置子流程')
export const NODE_DEFAULT_NAME = new Map
()
NODE_DEFAULT_NAME.set(NodeType.USER_TASK_NODE, '审批人')
@@ -515,15 +533,19 @@ NODE_DEFAULT_NAME.set(NodeType.START_USER_NODE, '发起人')
NODE_DEFAULT_NAME.set(NodeType.DELAY_TIMER_NODE, '延迟器')
NODE_DEFAULT_NAME.set(NodeType.ROUTER_BRANCH_NODE, '路由分支')
NODE_DEFAULT_NAME.set(NodeType.TRIGGER_NODE, '触发器')
+NODE_DEFAULT_NAME.set(NodeType.TRANSACTOR_NODE, '办理人')
+NODE_DEFAULT_NAME.set(NodeType.CHILD_PROCESS_NODE, '子流程')
// 候选人策略。暂时不从字典中取。 后续可能调整。控制显示顺序
export const CANDIDATE_STRATEGY: DictDataVO[] = [
{ label: '指定成员', value: CandidateStrategy.USER },
{ label: '指定角色', value: CandidateStrategy.ROLE },
+ { label: '指定岗位', value: CandidateStrategy.POST },
{ label: '部门成员', value: CandidateStrategy.DEPT_MEMBER },
{ label: '部门负责人', value: CandidateStrategy.DEPT_LEADER },
{ label: '连续多级部门负责人', value: CandidateStrategy.MULTI_LEVEL_DEPT_LEADER },
{ label: '发起人自选', value: CandidateStrategy.START_USER_SELECT },
+ { label: '审批人自选', value: CandidateStrategy.APPROVE_USER_SELECT },
{ label: '发起人本人', value: CandidateStrategy.START_USER },
{ label: '发起人部门负责人', value: CandidateStrategy.START_USER_DEPT_LEADER },
{ label: '发起人连续部门负责人', value: CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER },
@@ -627,6 +649,16 @@ export const DEFAULT_BUTTON_SETTING: ButtonSetting[] = [
{ id: OperationButtonType.RETURN, displayName: '退回', enable: true }
]
+// 办理人默认的按钮权限设置
+export const TRANSACTOR_DEFAULT_BUTTON_SETTING: ButtonSetting[] = [
+ { id: OperationButtonType.APPROVE, displayName: '办理', enable: true },
+ { id: OperationButtonType.REJECT, displayName: '拒绝', enable: false },
+ { id: OperationButtonType.TRANSFER, displayName: '转办', enable: false },
+ { id: OperationButtonType.DELEGATE, displayName: '委派', enable: false },
+ { id: OperationButtonType.ADD_SIGN, displayName: '加签', enable: false },
+ { id: OperationButtonType.RETURN, displayName: '退回', enable: false }
+]
+
// 发起人的按钮权限。暂时定死,不可以编辑
export const START_USER_BUTTON_SETTING: ButtonSetting[] = [
{ id: OperationButtonType.APPROVE, displayName: '提交', enable: true },
@@ -717,7 +749,7 @@ export type RouterSetting = {
export type TriggerSetting = {
type: TriggerTypeEnum
httpRequestSetting?: HttpRequestTriggerSetting
- normalFormSetting?: NormalFormTriggerSetting
+ formSettings?: FormTriggerSetting[]
}
/**
@@ -729,9 +761,17 @@ export enum TriggerTypeEnum {
*/
HTTP_REQUEST = 1,
/**
- * 更新流程表单触发器
+ * 接收 HTTP 回调请求触发器
*/
- UPDATE_NORMAL_FORM = 2 // TODO @jason:FORM_UPDATE?
+ HTTP_CALLBACK = 2,
+ /**
+ * 表单数据更新触发器
+ */
+ FORM_UPDATE = 10,
+ /**
+ * 表单数据删除触发器
+ */
+ FORM_DELETE = 11
}
/**
@@ -751,12 +791,110 @@ export type HttpRequestTriggerSetting = {
/**
* 流程表单触发器配置结构定义
*/
-export type NormalFormTriggerSetting = {
- // 更新表单字段
+export type FormTriggerSetting = {
+ // 条件类型
+ conditionType?: ConditionType
+ // 条件表达式
+ conditionExpression?: string
+ // 条件组
+ conditionGroups?: ConditionGroup
+ // 更新表单字段配置
updateFormFields?: Record
+ // 删除表单字段配置
+ deleteFields?: string[]
}
export const TRIGGER_TYPES: DictDataVO[] = [
- { label: 'HTTP 请求', value: TriggerTypeEnum.HTTP_REQUEST },
- { label: '修改表单数据', value: TriggerTypeEnum.UPDATE_NORMAL_FORM }
+ { label: '发送 HTTP 请求', value: TriggerTypeEnum.HTTP_REQUEST },
+ { label: '接收 HTTP 回调', value: TriggerTypeEnum.HTTP_CALLBACK },
+ { label: '修改表单数据', value: TriggerTypeEnum.FORM_UPDATE },
+ { label: '删除表单数据', value: TriggerTypeEnum.FORM_DELETE }
+]
+
+/**
+ * 子流程节点结构定义
+ */
+export type ChildProcessSetting = {
+ calledProcessDefinitionKey: string
+ calledProcessDefinitionName: string
+ async: boolean
+ inVariables?: IOParameter[]
+ outVariables?: IOParameter[]
+ skipStartUserNode: boolean
+ startUserSetting: StartUserSetting
+ timeoutSetting: TimeoutSetting
+ multiInstanceSetting: MultiInstanceSetting
+}
+export type IOParameter = {
+ source: string
+ target: string
+}
+export type StartUserSetting = {
+ type: ChildProcessStartUserTypeEnum
+ formField?: string
+ emptyType?: ChildProcessStartUserEmptyTypeEnum
+}
+export type TimeoutSetting = {
+ enable: boolean
+ type?: DelayTypeEnum
+ timeExpression?: string
+}
+export type MultiInstanceSetting = {
+ enable: boolean
+ sequential?: boolean
+ approveRatio?: number
+ sourceType?: ChildProcessMultiInstanceSourceTypeEnum
+ source?: string
+}
+export enum ChildProcessStartUserTypeEnum {
+ /**
+ * 同主流程发起人
+ */
+ MAIN_PROCESS_START_USER = 1,
+ /**
+ * 表单
+ */
+ FROM_FORM = 2
+}
+export const CHILD_PROCESS_START_USER_TYPE = [
+ { label: '同主流程发起人', value: ChildProcessStartUserTypeEnum.MAIN_PROCESS_START_USER },
+ { label: '表单', value: ChildProcessStartUserTypeEnum.FROM_FORM }
+]
+export enum ChildProcessStartUserEmptyTypeEnum {
+ /**
+ * 同主流程发起人
+ */
+ MAIN_PROCESS_START_USER = 1,
+ /**
+ * 子流程管理员
+ */
+ CHILD_PROCESS_ADMIN = 2,
+ /**
+ * 主流程管理员
+ */
+ MAIN_PROCESS_ADMIN = 3
+}
+export const CHILD_PROCESS_START_USER_EMPTY_TYPE = [
+ { label: '同主流程发起人', value: ChildProcessStartUserEmptyTypeEnum.MAIN_PROCESS_START_USER },
+ { label: '子流程管理员', value: ChildProcessStartUserEmptyTypeEnum.CHILD_PROCESS_ADMIN },
+ { label: '主流程管理员', value: ChildProcessStartUserEmptyTypeEnum.MAIN_PROCESS_ADMIN }
+]
+export enum ChildProcessMultiInstanceSourceTypeEnum {
+ /**
+ * 固定数量
+ */
+ FIXED_QUANTITY = 1,
+ /**
+ * 数字表单
+ */
+ NUMBER_FORM = 2,
+ /**
+ * 多选表单
+ */
+ MULTIPLE_FORM = 3
+}
+export const CHILD_PROCESS_MULTI_INSTANCE_SOURCE_TYPE = [
+ { label: '固定数量', value: ChildProcessMultiInstanceSourceTypeEnum.FIXED_QUANTITY },
+ { label: '数字表单', value: ChildProcessMultiInstanceSourceTypeEnum.NUMBER_FORM },
+ { label: '多选表单', value: ChildProcessMultiInstanceSourceTypeEnum.MULTIPLE_FORM }
]
diff --git a/src/components/SimpleProcessDesignerV2/src/node.ts b/src/components/SimpleProcessDesignerV2/src/node.ts
index 407fd4837..5b754bfac 100644
--- a/src/components/SimpleProcessDesignerV2/src/node.ts
+++ b/src/components/SimpleProcessDesignerV2/src/node.ts
@@ -15,7 +15,10 @@ import {
AssignEmptyHandlerType,
FieldPermissionType,
HttpRequestParam,
- ProcessVariableEnum
+ ProcessVariableEnum,
+ ConditionType,
+ ConditionGroup,
+ COMPARISON_OPERATORS
} from './consts'
import { parseFormFields } from '@/components/FormCreate/src/utils'
@@ -201,7 +204,7 @@ export function useNodeForm(nodeType: NodeType) {
const deptTreeOptions = inject('deptTree', ref()) // 部门树
const formFields = inject[>('formFields', ref([])) // 流程表单字段
const configForm = ref()
- if (nodeType === NodeType.USER_TASK_NODE) {
+ if (nodeType === NodeType.USER_TASK_NODE || nodeType === NodeType.TRANSACTOR_NODE) {
configForm.value = {
candidateStrategy: CandidateStrategy.USER,
approveMethod: ApproveMethodType.SEQUENTIAL_APPROVE,
@@ -307,6 +310,11 @@ export function useNodeForm(nodeType: NodeType) {
showText = `表单内部门负责人`
}
+ // 审批人自选
+ if (configForm.value?.candidateStrategy === CandidateStrategy.APPROVE_USER_SELECT) {
+ showText = `审批人自选`
+ }
+
// 发起人自选
if (configForm.value?.candidateStrategy === CandidateStrategy.START_USER_SELECT) {
showText = `发起人自选`
@@ -543,6 +551,66 @@ export function useTaskStatusClass(taskStatus: TaskStatusEnum | undefined): stri
if (taskStatus === TaskStatusEnum.CANCEL) {
return 'status-cancel'
}
-
return ''
}
+
+/** 条件组件文字展示 */
+export function getConditionShowText(
+ conditionType: ConditionType | undefined,
+ conditionExpression: string | undefined,
+ conditionGroups: ConditionGroup | undefined,
+ fieldOptions: Array>
+) {
+ let showText = ''
+ if (conditionType === ConditionType.EXPRESSION) {
+ if (conditionExpression) {
+ showText = `表达式:${conditionExpression}`
+ }
+ }
+ if (conditionType === ConditionType.RULE) {
+ // 条件组是否为与关系
+ const groupAnd = conditionGroups?.and
+ let warningMessage: undefined | string = undefined
+ const conditionGroup = conditionGroups?.conditions.map((item) => {
+ return (
+ '(' +
+ item.rules
+ .map((rule) => {
+ if (rule.leftSide && rule.rightSide) {
+ return (
+ getFormFieldTitle(fieldOptions, rule.leftSide) +
+ ' ' +
+ getOpName(rule.opCode) +
+ ' ' +
+ rule.rightSide
+ )
+ } else {
+ // 有一条规则不完善。提示错误
+ warningMessage = '请完善条件规则'
+ return ''
+ }
+ })
+ .join(item.and ? ' 且 ' : ' 或 ') +
+ ' ) '
+ )
+ })
+ if (warningMessage) {
+ showText = ''
+ } else {
+ showText = conditionGroup!.join(groupAnd ? ' 且 ' : ' 或 ')
+ }
+ }
+ return showText
+}
+
+/** 获取表单字段名称*/
+const getFormFieldTitle = (fieldOptions: Array>, field: string) => {
+ const item = fieldOptions.find((item) => item.field === field)
+ return item?.title
+}
+
+/** 获取操作符名称 */
+const getOpName = (opCode: string): string => {
+ const opName = COMPARISON_OPERATORS.find((item: any) => item.value === opCode)
+ return opName?.label
+}
diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/ChildProcessNodeConfig.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/ChildProcessNodeConfig.vue
new file mode 100644
index 000000000..7ec382fca
--- /dev/null
+++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/ChildProcessNodeConfig.vue
@@ -0,0 +1,610 @@
+
+
+
+
+
+
+
+ ]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加一行
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加一行
+
+
+
+
+
+ {{ item.label }}
+
+
+
+
+
+
+ {{ item.label }}
+
+
+
+
+
+
+
+
+
+ 超时设置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 后进入下一节点
+
+
+
+ 后进入下一节点
+
+
+
+ 多实例设置
+
+
+
+
+
+
+
+
+ 完成比例(%)
+
+
+
+ 多实例来源
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 确 定
+ 取 消
+
+
+
+
+
+
+
diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/ConditionNodeConfig.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/ConditionNodeConfig.vue
index e9b387a7f..9020d655e 100644
--- a/src/components/SimpleProcessDesignerV2/src/nodes-config/ConditionNodeConfig.vue
+++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/ConditionNodeConfig.vue
@@ -43,15 +43,12 @@
diff --git a/src/components/SimpleProcessDesignerV2/src/nodes-config/components/HttpRequestParamSetting.vue b/src/components/SimpleProcessDesignerV2/src/nodes-config/components/HttpRequestParamSetting.vue
index 039e4c80d..9a0a9feff 100644
--- a/src/components/SimpleProcessDesignerV2/src/nodes-config/components/HttpRequestParamSetting.vue
+++ b/src/components/SimpleProcessDesignerV2/src/nodes-config/components/HttpRequestParamSetting.vue
@@ -1,5 +1,5 @@
-
+
添加一行
-
+
+
+
diff --git a/src/components/SimpleProcessDesignerV2/src/nodes/ChildProcessNode.vue b/src/components/SimpleProcessDesignerV2/src/nodes/ChildProcessNode.vue
new file mode 100644
index 000000000..0b362446d
--- /dev/null
+++ b/src/components/SimpleProcessDesignerV2/src/nodes/ChildProcessNode.vue
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ currentNode.name }}
+
+
+
+
+ {{ currentNode.showText }}
+
+
+ {{ NODE_DEFAULT_TEXT.get(NodeType.CHILD_PROCESS_NODE) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/SimpleProcessDesignerV2/src/nodes/UserTaskNode.vue b/src/components/SimpleProcessDesignerV2/src/nodes/UserTaskNode.vue
index 47ef540cc..ae1af6c28 100644
--- a/src/components/SimpleProcessDesignerV2/src/nodes/UserTaskNode.vue
+++ b/src/components/SimpleProcessDesignerV2/src/nodes/UserTaskNode.vue
@@ -9,7 +9,14 @@
]"
>
-
+
+
+
+
- {{ NODE_DEFAULT_TEXT.get(NodeType.USER_TASK_NODE) }}
+ {{ NODE_DEFAULT_TEXT.get(currentNode.type) }}
diff --git a/src/components/SimpleProcessDesignerV2/theme/iconfont.ttf b/src/components/SimpleProcessDesignerV2/theme/iconfont.ttf
index 58f31c361..06f4e31c4 100644
Binary files a/src/components/SimpleProcessDesignerV2/theme/iconfont.ttf and b/src/components/SimpleProcessDesignerV2/theme/iconfont.ttf differ
diff --git a/src/components/SimpleProcessDesignerV2/theme/iconfont.woff b/src/components/SimpleProcessDesignerV2/theme/iconfont.woff
index f4b4f3de9..0724e7505 100644
Binary files a/src/components/SimpleProcessDesignerV2/theme/iconfont.woff and b/src/components/SimpleProcessDesignerV2/theme/iconfont.woff differ
diff --git a/src/components/SimpleProcessDesignerV2/theme/iconfont.woff2 b/src/components/SimpleProcessDesignerV2/theme/iconfont.woff2
index d66f96853..c904bb67d 100644
Binary files a/src/components/SimpleProcessDesignerV2/theme/iconfont.woff2 and b/src/components/SimpleProcessDesignerV2/theme/iconfont.woff2 differ
diff --git a/src/components/SimpleProcessDesignerV2/theme/simple-process-designer.scss b/src/components/SimpleProcessDesignerV2/theme/simple-process-designer.scss
index f3d8b4437..d0adbdbb9 100644
--- a/src/components/SimpleProcessDesignerV2/theme/simple-process-designer.scss
+++ b/src/components/SimpleProcessDesignerV2/theme/simple-process-designer.scss
@@ -177,6 +177,18 @@
color: #ca3a31
}
+ .transactor {
+ color: #330099;
+ }
+
+ .child-process {
+ color: #996633;
+ }
+
+ .async-child-process {
+ color: #006666;
+ }
+
.handler-item-text {
margin-top: 4px;
width: 80px;
@@ -290,10 +302,22 @@
&.trigger-node {
color: #3373d2;
}
-
+
&.router-node {
color: #ca3a31
}
+
+ &.transactor-task {
+ color: #330099;
+ }
+
+ &.child-process {
+ color: #996633;
+ }
+
+ &.async-child-process {
+ color: #006666;
+ }
}
.node-title {
@@ -777,7 +801,7 @@
content: "\e7eb";
}
-.icon-handle:before {
+.icon-transactor:before {
content: "\e61c";
}
@@ -792,3 +816,11 @@
.icon-parallel:before {
content: "\e688";
}
+
+.icon-async-child-process:before {
+ content: "\e6f2";
+}
+
+.icon-child-process:before {
+ content: "\e6c1";
+}
diff --git a/src/components/Table/src/Table.vue b/src/components/Table/src/Table.vue
index 279a9faca..e9e50af3e 100644
--- a/src/components/Table/src/Table.vue
+++ b/src/components/Table/src/Table.vue
@@ -56,7 +56,7 @@ export default defineComponent({
// 注册
onMounted(() => {
const tableRef = unref(elTableRef)
- emit('register', tableRef?.$parent, elTableRef)
+ emit('register', tableRef?.$parent, elTableRef.value)
})
const pageSizeRef = ref(props.pageSize)
diff --git a/src/components/bpmnProcessDesigner/package/designer/ProcessDesigner.vue b/src/components/bpmnProcessDesigner/package/designer/ProcessDesigner.vue
index 83d40fbfc..00e887cb5 100644
--- a/src/components/bpmnProcessDesigner/package/designer/ProcessDesigner.vue
+++ b/src/components/bpmnProcessDesigner/package/designer/ProcessDesigner.vue
@@ -188,12 +188,8 @@
:scroll="true"
max-height="600px"
>
-
-
-
-
- {{ previewResult }}
-
+
@@ -237,6 +233,8 @@ import { XmlNode, XmlNodeType, parseXmlString } from 'steady-xml'
// const eventName = reactive({
// name: ''
// })
+import hljs from 'highlight.js' // 导入代码高亮文件
+import 'highlight.js/styles/github.css' // 导入代码高亮样式
defineOptions({ name: 'MyProcessDesigner' })
@@ -308,6 +306,18 @@ const props = defineProps({
}
})
+/**
+ * 代码高亮
+ */
+const highlightedCode = (code: string) => {
+ // 高亮
+ if (previewType.value === 'json') {
+ code = JSON.stringify(code, null, 2)
+ }
+ const result = hljs.highlight(code, { language: previewType.value, ignoreIllegals: true })
+ return result.value || ' '
+}
+
provide('configGlobal', props)
let bpmnModeler: any = null
const defaultZoom = ref(1)
diff --git a/src/components/bpmnProcessDesigner/package/penal/custom-config/components/UserTaskCustomConfig.vue b/src/components/bpmnProcessDesigner/package/penal/custom-config/components/UserTaskCustomConfig.vue
index aab130d08..3c748ff6f 100644
--- a/src/components/bpmnProcessDesigner/package/penal/custom-config/components/UserTaskCustomConfig.vue
+++ b/src/components/bpmnProcessDesigner/package/penal/custom-config/components/UserTaskCustomConfig.vue
@@ -123,13 +123,19 @@
字段权限
-
+
字段名称
- 只读
- 可编辑
- 隐藏
+ 只读
+ 可编辑
+ 隐藏
@@ -140,24 +146,30 @@
:value="FieldPermissionType.READ"
size="large"
:label="FieldPermissionType.READ"
- >
+ @change="updateElementExtensions"
+ >
+
+
+ @change="updateElementExtensions"
+ >
+
+
+ @change="updateElementExtensions"
+ >
+
+
@@ -165,12 +177,22 @@
是否需要签名
-
+
审批意见
-
+
@@ -191,6 +213,7 @@ import {
} from '@/components/SimpleProcessDesignerV2/src/consts'
import * as UserApi from '@/api/system/user'
import { useFormFieldsPermission } from '@/components/SimpleProcessDesignerV2/src/node'
+import { BpmModelFormType } from '@/utils/constants'
defineOptions({ name: 'ElementCustomConfig4UserTask' })
const props = defineProps({
@@ -248,7 +271,6 @@ const resetCustomConfigList = () => {
bpmnElement.value.id,
bpmnInstances().modeler
)
-
// 获取元素扩展属性 或者 创建扩展属性
elExtensionElements.value =
bpmnElement.value.businessObject?.extensionElements ??
@@ -311,14 +333,13 @@ const resetCustomConfigList = () => {
}
// 字段权限
- if (formType.value === 10) {
+ if (formType.value === BpmModelFormType.NORMAL) {
const fieldsPermissionList = elExtensionElements.value.values?.filter(
(ex) => ex.$type === `${prefix}:FieldsPermission`
)
fieldsPermissionEl.value = []
getNodeConfigFormFields()
- // 由于默认添加了发起人元素,这里需要删掉
- fieldsPermissionConfig.value = fieldsPermissionConfig.value.slice(1)
+ fieldsPermissionConfig.value = fieldsPermissionConfig.value
fieldsPermissionConfig.value.forEach((element) => {
element.permission =
fieldsPermissionList?.find((obj) => obj.field === element.field)?.permission ?? '1'
@@ -487,6 +508,19 @@ function useButtonsSetting() {
}
}
+/** 批量更新权限 */
+// TODO @lesan:这个页面,有一些 idea 红色报错,咱要不要 fix 下!
+const updatePermission = (type: string) => {
+ fieldsPermissionEl.value.forEach((field) => {
+ field.permission =
+ type === 'READ'
+ ? FieldPermissionType.READ
+ : type === 'WRITE'
+ ? FieldPermissionType.WRITE
+ : FieldPermissionType.NONE
+ })
+}
+
const userOptions = ref
([]) // 用户列表
onMounted(async () => {
// 获得用户列表
@@ -497,9 +531,9 @@ onMounted(async () => {
diff --git a/src/views/ai/knowledge/document/form/index.vue b/src/views/ai/knowledge/document/form/index.vue
new file mode 100644
index 000000000..722f57cf9
--- /dev/null
+++ b/src/views/ai/knowledge/document/form/index.vue
@@ -0,0 +1,193 @@
+
+
+
+
+
+
+
+
+
+ {{ formData.id ? '编辑知识库文档' : '创建知识库文档' }}
+
+
+
+
+
+
+
+
+ {{ index + 1 }}
+
+
{{ step.title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/ai/knowledge/document/index.vue b/src/views/ai/knowledge/document/index.vue
new file mode 100644
index 000000000..e8ba711c1
--- /dev/null
+++ b/src/views/ai/knowledge/document/index.vue
@@ -0,0 +1,236 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+ 新增
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+
+
+ 分段
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/ai/knowledge/knowledge/KnowledgeForm.vue b/src/views/ai/knowledge/knowledge/KnowledgeForm.vue
new file mode 100644
index 000000000..d72f37caf
--- /dev/null
+++ b/src/views/ai/knowledge/knowledge/KnowledgeForm.vue
@@ -0,0 +1,162 @@
+
+
+
+
diff --git a/src/views/ai/knowledge/knowledge/index.vue b/src/views/ai/knowledge/knowledge/index.vue
new file mode 100644
index 000000000..a768c6b80
--- /dev/null
+++ b/src/views/ai/knowledge/knowledge/index.vue
@@ -0,0 +1,221 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+ 新增
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+
+
+ 文档
+
+
+ 召回测试
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/ai/knowledge/knowledge/retrieval/index.vue b/src/views/ai/knowledge/knowledge/retrieval/index.vue
new file mode 100644
index 000000000..aca521a34
--- /dev/null
+++ b/src/views/ai/knowledge/knowledge/retrieval/index.vue
@@ -0,0 +1,163 @@
+
+
+
+
+
+
召回测试
+
根据给定的查询文本测试召回效果。
+
+
+
+
+
+ {{ queryParams.content?.length }} / 200
+
+
+
+ topK:
+
+
+
+ 相似度:
+
+
+
+ 测试
+
+
+
+
+
+
+
+
+ {{ segments.length }} 个召回段落
+
+
+
+
+
+
+ 分段({{ segment.id }}) · {{ segment.contentLength }} 字符数 ·
+ {{ segment.tokens }} Token
+
+
+ score: {{ segment.score }}
+
+
+
+ {{ segment.content }}
+
+
+
+
+ {{ segment.documentName || '未知文档' }}
+
+
+ {{ segment.expanded ? '收起' : '展开' }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/ai/knowledge/segment/KnowledgeSegmentForm.vue b/src/views/ai/knowledge/segment/KnowledgeSegmentForm.vue
new file mode 100644
index 000000000..4818de010
--- /dev/null
+++ b/src/views/ai/knowledge/segment/KnowledgeSegmentForm.vue
@@ -0,0 +1,101 @@
+
+
+
+
diff --git a/src/views/ai/knowledge/segment/index.vue b/src/views/ai/knowledge/segment/index.vue
new file mode 100644
index 000000000..e2f8a67f3
--- /dev/null
+++ b/src/views/ai/knowledge/segment/index.vue
@@ -0,0 +1,242 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+ 新增
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 完整内容:
+
+ {{ props.row.content }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/ai/mindmap/index/components/Left.vue b/src/views/ai/mindmap/index/components/Left.vue
index e684b8874..5c3dbf0d1 100644
--- a/src/views/ai/mindmap/index/components/Left.vue
+++ b/src/views/ai/mindmap/index/components/Left.vue
@@ -8,7 +8,7 @@
+
+
+
+
@@ -32,6 +32,21 @@
+
+
+
+
+
+
+
+
+
+
{
@@ -128,7 +150,11 @@ const open = async (type: string, id?: number, title?: string) => {
}
}
// 获得下拉数据
- chatModelList.value = await ChatModelApi.getChatModelSimpleList(CommonStatusEnum.ENABLE)
+ models.value = await ModelApi.getModelSimpleList(AiModelTypeEnum.CHAT)
+ // 获取知识库列表
+ knowledgeList.value = await KnowledgeApi.getSimpleKnowledgeList()
+ // 获取工具列表
+ toolList.value = await ToolApi.getToolSimpleList()
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
@@ -176,7 +202,9 @@ const resetForm = () => {
description: undefined,
systemMessage: undefined,
publicStatus: true,
- status: CommonStatusEnum.ENABLE
+ status: CommonStatusEnum.ENABLE,
+ knowledgeIds: [],
+ toolIds: []
}
formRef.value?.resetFields()
}
diff --git a/src/views/ai/model/chatRole/index.vue b/src/views/ai/model/chatRole/index.vue
index e870a5563..0ba0d79df 100644
--- a/src/views/ai/model/chatRole/index.vue
+++ b/src/views/ai/model/chatRole/index.vue
@@ -1,4 +1,6 @@
+
+
+
+
+ -
+ 引用 {{ scope.row.knowledgeIds.length }} 个
+
+
+
+
+ -
+ 引用 {{ scope.row.toolIds.length }} 个
+
+
diff --git a/src/views/ai/model/chatModel/ChatModelForm.vue b/src/views/ai/model/model/ModelForm.vue
similarity index 76%
rename from src/views/ai/model/chatModel/ChatModelForm.vue
rename to src/views/ai/model/model/ModelForm.vue
index ed9747a6b..a27ca0fd0 100644
--- a/src/views/ai/model/chatModel/ChatModelForm.vue
+++ b/src/views/ai/model/model/ModelForm.vue
@@ -17,6 +17,21 @@
/>
+
+
+
+
+
-
+
-
+
-
+
@@ -80,13 +110,14 @@
diff --git a/src/views/ai/model/tool/index.vue b/src/views/ai/model/tool/index.vue
new file mode 100644
index 000000000..583b3e188
--- /dev/null
+++ b/src/views/ai/model/tool/index.vue
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+ 新增
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/ai/music/manager/index.vue b/src/views/ai/music/manager/index.vue
index e1b94112a..27daf1353 100644
--- a/src/views/ai/music/manager/index.vue
+++ b/src/views/ai/music/manager/index.vue
@@ -1,4 +1,6 @@
+
+
+
+
-
+
搜索
重置
-
- 新增
-
-
-
- 导出
-
@@ -143,15 +132,6 @@
-
-
- 编辑
-
{
handleQuery()
}
-/** 新增方法,跳转到写作页面 **/
-const openForm = (type: string, id?: number) => {
- switch (type) {
- case 'create':
- router.push('/ai/write')
- break
- }
-}
-
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
diff --git a/src/views/bpm/form/editor/index.vue b/src/views/bpm/form/editor/index.vue
index 12945e0f7..4165fcc47 100644
--- a/src/views/bpm/form/editor/index.vue
+++ b/src/views/bpm/form/editor/index.vue
@@ -50,11 +50,13 @@ import FcDesigner from '@form-create/designer'
import { encodeConf, encodeFields, setConfAndFields } from '@/utils/formCreate'
import { useTagsViewStore } from '@/store/modules/tagsView'
import { useFormCreateDesigner } from '@/components/FormCreate'
+import { useRoute } from 'vue-router'
defineOptions({ name: 'BpmFormEditor' })
const { t } = useI18n() // 国际化
const message = useMessage() // 消息
+const route = useRoute() // 路由
const { push, currentRoute } = useRouter() // 路由
const { query } = useRoute() // 路由信息
const { delView } = useTagsViewStore() // 视图操作
@@ -150,6 +152,14 @@ onMounted(async () => {
const data = await FormApi.getForm(id)
formData.value = data
setConfAndFields(designer, data.conf, data.fields)
+
+ if (route.query.type !== 'copy') {
+ return
+ }
+ // 场景三: 复制表单
+ const { id: foo, ...copied } = data
+ formData.value = copied
+ formData.value.name += '_copy'
})
diff --git a/src/views/bpm/form/index.vue b/src/views/bpm/form/index.vue
index 46edd8f90..57b44a36b 100644
--- a/src/views/bpm/form/index.vue
+++ b/src/views/bpm/form/index.vue
@@ -59,7 +59,15 @@
v-hasPermi="['bpm:form:update']"
link
type="primary"
- @click="openForm(scope.row.id)"
+ @click="openForm('copy', scope.row.id)"
+ >
+ 复制
+
+
编辑
@@ -139,16 +147,17 @@ const resetQuery = () => {
}
/** 添加/修改操作 */
-const openForm = (id?: number) => {
- const toRouter: { name: string; query?: { id: number } } = {
- name: 'BpmFormEditor'
+const openForm = (type: string, id?: number) => {
+ const toRouter: { name: string; query: { type: string; id?: number } } = {
+ name: 'BpmFormEditor',
+ query: {
+ type
+ }
}
console.log(typeof id)
// 表单新建的时候id传的是event需要排除
if (typeof id === 'number' || typeof id === 'string') {
- toRouter.query = {
- id
- }
+ toRouter.query.id = id
}
push(toRouter)
}
diff --git a/src/views/bpm/model/CategoryDraggableModel.vue b/src/views/bpm/model/CategoryDraggableModel.vue
index 0b0978477..4e4c18278 100644
--- a/src/views/bpm/model/CategoryDraggableModel.vue
+++ b/src/views/bpm/model/CategoryDraggableModel.vue
@@ -88,6 +88,9 @@
/>
+
+ {{ subString(row.name, 0, 2) }}
+
{{ row.name }}
@@ -110,6 +113,11 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/bpm/model/form/BasicInfo.vue b/src/views/bpm/model/form/BasicInfo.vue
index cca91334c..86700fa47 100644
--- a/src/views/bpm/model/form/BasicInfo.vue
+++ b/src/views/bpm/model/form/BasicInfo.vue
@@ -6,7 +6,7 @@
class="!w-440px"
v-model="modelData.key"
:disabled="!!modelData.id"
- placeholder="请输入流标标识"
+ placeholder="请输入流程标识,以字母或下划线开头"
/>
-
+
@@ -155,7 +155,6 @@ const rules = {
name: [{ required: true, message: '流程名称不能为空', trigger: 'blur' }],
key: [{ required: true, message: '流程标识不能为空', trigger: 'blur' }],
category: [{ required: true, message: '流程分类不能为空', trigger: 'blur' }],
- icon: [{ required: true, message: '流程图标不能为空', trigger: 'blur' }],
type: [{ required: true, message: '是否可见不能为空', trigger: 'blur' }],
visible: [{ required: true, message: '是否可见不能为空', trigger: 'blur' }],
managerUserIds: [{ required: true, message: '流程管理员不能为空', trigger: 'blur' }]
diff --git a/src/views/bpm/model/form/ExtraSettings.vue b/src/views/bpm/model/form/ExtraSettings.vue
index d9eb1c611..3c8e689b1 100644
--- a/src/views/bpm/model/form/ExtraSettings.vue
+++ b/src/views/bpm/model/form/ExtraSettings.vue
@@ -140,6 +140,46 @@
+
+
+ 流程前置通知
+
+
+
+
+
+ 流程后置通知
+
+
+
@@ -149,6 +189,7 @@ import { BpmAutoApproveType, BpmModelFormType } from '@/utils/constants'
import * as FormApi from '@/api/bpm/form'
import { parseFormFields } from '@/components/FormCreate/src/utils'
import { ProcessVariableEnum } from '@/components/SimpleProcessDesignerV2/src/consts'
+import HttpRequestSetting from '@/components/SimpleProcessDesignerV2/src/nodes-config/components/HttpRequestSetting.vue'
const modelData = defineModel
()
@@ -205,6 +246,36 @@ const numberExample = computed(() => {
}
})
+/** 是否开启流程前置通知 */
+const processBeforeTriggerEnable = ref(false)
+const handlePreProcessNotifyEnableChange = (val: boolean | string | number) => {
+ if (val) {
+ modelData.value.processBeforeTriggerSetting = {
+ url: '',
+ header: [],
+ body: [],
+ response: []
+ }
+ } else {
+ modelData.value.processBeforeTriggerSetting = null
+ }
+}
+
+/** 是否开启流程后置通知 */
+const processAfterTriggerEnable = ref(false)
+const handlePostProcessNotifyEnableChange = (val: boolean | string | number) => {
+ if (val) {
+ modelData.value.processAfterTriggerSetting = {
+ url: '',
+ header: [],
+ body: [],
+ response: []
+ }
+ } else {
+ modelData.value.processAfterTriggerSetting = null
+ }
+}
+
/** 表单选项 */
const formField = ref>([])
const formFieldOptions4Title = computed(() => {
@@ -264,6 +335,12 @@ const initData = () => {
summary: []
}
}
+ if (modelData.value.processBeforeTriggerSetting) {
+ processBeforeTriggerEnable.value = true
+ }
+ if (modelData.value.processAfterTriggerSetting) {
+ processAfterTriggerEnable.value = true
+ }
}
defineExpose({ initData })
diff --git a/src/views/bpm/model/form/FormDesign.vue b/src/views/bpm/model/form/FormDesign.vue
index 74742f2e3..e1ca27f20 100644
--- a/src/views/bpm/model/form/FormDesign.vue
+++ b/src/views/bpm/model/form/FormDesign.vue
@@ -11,12 +11,12 @@
-
+
-
+
-
+
@@ -68,6 +68,7 @@
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import * as FormApi from '@/api/bpm/form'
import { setConfAndFields2 } from '@/utils/formCreate'
+import { BpmModelFormType } from '@/utils/constants'
const props = defineProps({
formList: {
@@ -96,7 +97,7 @@ const formPreview = ref({
watch(
() => modelData.value.formId,
async (newFormId) => {
- if (newFormId && modelData.value.formType === 10) {
+ if (newFormId && modelData.value.formType === BpmModelFormType.NORMAL) {
const data = await FormApi.getForm(newFormId)
setConfAndFields2(formPreview.value, data.conf, data.fields)
// 设置只读
diff --git a/src/views/bpm/model/form/ProcessDesign.vue b/src/views/bpm/model/form/ProcessDesign.vue
index e85076a6d..bb3a04b0d 100644
--- a/src/views/bpm/model/form/ProcessDesign.vue
+++ b/src/views/bpm/model/form/ProcessDesign.vue
@@ -25,7 +25,7 @@
+
diff --git a/src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue b/src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue
index fcd5ec899..110b8bd6c 100644
--- a/src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue
+++ b/src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue
@@ -43,7 +43,8 @@
v-if="
isEmpty(activity.tasks) &&
isEmpty(activity.candidateUsers) &&
- CandidateStrategy.START_USER_SELECT === activity.candidateStrategy
+ (CandidateStrategy.START_USER_SELECT === activity.candidateStrategy ||
+ CandidateStrategy.APPROVE_USER_SELECT === activity.candidateStrategy)
"
>
@@ -121,6 +122,7 @@
"
class="text-#a5a5a5 text-13px mt-1 w-full bg-#f8f8fa p2 rounded-md"
>
+
审批意见:{{ task.reason }}
{
if (
nodeType === NodeType.START_USER_NODE ||
nodeType === NodeType.USER_TASK_NODE ||
+ nodeType === NodeType.TRANSACTOR_NODE ||
+ nodeType === NodeType.CHILD_PROCESS_NODE ||
nodeType === NodeType.END_EVENT_NODE
) {
return statusIconMap[taskStatus]?.icon
diff --git a/src/views/bpm/processInstance/detail/index.vue b/src/views/bpm/processInstance/detail/index.vue
index 9809f7a8d..c3f83cf06 100644
--- a/src/views/bpm/processInstance/detail/index.vue
+++ b/src/views/bpm/processInstance/detail/index.vue
@@ -178,8 +178,9 @@ const writableFields: Array
= [] // 表单可以编辑的字段
/** 获得详情 */
const getDetail = () => {
+ // 获得审批详情
getApprovalDetail()
-
+ // 获得流程模型视图
getProcessModelView()
}
diff --git a/src/views/bpm/processInstance/index.vue b/src/views/bpm/processInstance/index.vue
index dc0719968..d6fc83d38 100644
--- a/src/views/bpm/processInstance/index.vue
+++ b/src/views/bpm/processInstance/index.vue
@@ -24,9 +24,7 @@
搜索
-
-
-
+
-
-
+
-
-
+
高级筛选
-
-
-
-
-
-
+ @change="handleQuery"
+ >
+
+
-
+
-
-
- 确认
- 取消
- 清空
+
+
+ 清空
+ 取消
+ 确认
+
@@ -130,7 +119,7 @@
-
+
@@ -146,11 +135,37 @@
min-width="100"
fixed="left"
/>
-
-
-
+
-
+
+
+
+
+
+
+ {{ scope.row.tasks[0].assigneeUser?.nickname }}
+
+ ({{ scope.row.tasks[0].name }}) 审批中
+
+
+
+
+
+
+ {{ scope.row.tasks[0].assigneeUser?.nickname }}
+
+ 等 {{ scope.row.tasks.length }} 人 ({{ scope.row.tasks[0].name }})审批中
+
+
+
+
+
+
+
-
-
diff --git a/src/views/bpm/task/done/index.vue b/src/views/bpm/task/done/index.vue
index 6d22865d6..2f91e69a1 100644
--- a/src/views/bpm/task/done/index.vue
+++ b/src/views/bpm/task/done/index.vue
@@ -76,23 +76,28 @@
placement="bottom-end"
>
-
+
高级筛选
-
-
+
@@ -111,10 +116,9 @@
确认
取消
清空
-
+
-
@@ -122,9 +126,12 @@
-
+
-
+
{{ item.key }} : {{ item.value }}
@@ -170,7 +177,12 @@
{{ formatPast2(scope.row.durationInMillis) }}
-
+
@@ -192,25 +204,28 @@ import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { dateFormatter, formatPast2 } from '@/utils/formatTime'
import * as TaskApi from '@/api/bpm/task'
import { CategoryApi, CategoryVO } from '@/api/bpm/category'
+import * as DefinitionApi from '@/api/bpm/definition'
-defineOptions({ name: 'BpmTodoTask' })
+defineOptions({ name: 'BpmDoneTask' })
const { push } = useRouter() // 路由
const loading = ref(true) // 列表的加载中
const total = ref(0) // 列表的总页数
const list = ref([]) // 列表的数据
+const processDefinitionList = ref([]) // 流程定义列表
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
name: '',
category: undefined,
status: undefined,
+ processDefinitionKey: '',
createTime: []
})
const queryFormRef = ref() // 搜索的表单
const categoryList = ref([]) // 流程分类列表
-const showPopover = ref(false)
+const showPopover = ref(false) // 高级筛选是否展示
/** 查询任务列表 */
const getList = async () => {
@@ -251,5 +266,7 @@ const handleAudit = (row: any) => {
onMounted(async () => {
await getList()
categoryList.value = await CategoryApi.getCategorySimpleList()
+ // 获取流程定义列表
+ processDefinitionList.value = await DefinitionApi.getSimpleProcessDefinitionList()
})
diff --git a/src/views/bpm/task/manager/index.vue b/src/views/bpm/task/manager/index.vue
index 688e51500..ad217484b 100644
--- a/src/views/bpm/task/manager/index.vue
+++ b/src/views/bpm/task/manager/index.vue
@@ -87,7 +87,7 @@
{{ formatPast2(scope.row.durationInMillis) }}
-
+
diff --git a/src/views/bpm/task/todo/index.vue b/src/views/bpm/task/todo/index.vue
index 3be40b4c6..45a2eb449 100644
--- a/src/views/bpm/task/todo/index.vue
+++ b/src/views/bpm/task/todo/index.vue
@@ -31,8 +31,7 @@
搜索
-
-
+
-
-
+
-
+
高级筛选
-
-
+
-
+
-
- 确认
- 取消
- 清空
-
+
+
+ 清空
+ 取消
+ 确认
+
+
-
@@ -105,9 +109,12 @@
-
+
-
+
{{ item.key }} : {{ item.value }}
@@ -135,7 +142,12 @@
prop="createTime"
width="180"
/>
-
+
@@ -157,6 +169,7 @@
import { dateFormatter } from '@/utils/formatTime'
import * as TaskApi from '@/api/bpm/task'
import { CategoryApi, CategoryVO } from '@/api/bpm/category'
+import * as DefinitionApi from '@/api/bpm/definition'
defineOptions({ name: 'BpmTodoTask' })
@@ -165,15 +178,18 @@ const { push } = useRouter() // 路由
const loading = ref(true) // 列表的加载中
const total = ref(0) // 列表的总页数
const list = ref([]) // 列表的数据
+const processDefinitionList = ref([]) // 流程定义列表
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
name: '',
category: undefined,
+ processDefinitionKey: '',
createTime: []
})
const queryFormRef = ref() // 搜索的表单
const categoryList = ref([]) // 流程分类列表
+const showPopover = ref(false) // 高级筛选是否展示
/** 查询任务列表 */
const getList = async () => {
@@ -187,8 +203,6 @@ const getList = async () => {
}
}
-const showPopover = ref(false)
-
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
@@ -216,5 +230,7 @@ const handleAudit = (row: any) => {
onMounted(async () => {
await getList()
categoryList.value = await CategoryApi.getCategorySimpleList()
+ // 获取流程定义列表
+ processDefinitionList.value = await DefinitionApi.getSimpleProcessDefinitionList()
})
diff --git a/src/views/iot/device/DeviceForm.vue b/src/views/iot/device/DeviceForm.vue
deleted file mode 100644
index cb0260125..000000000
--- a/src/views/iot/device/DeviceForm.vue
+++ /dev/null
@@ -1,156 +0,0 @@
-
-
-
-
diff --git a/src/views/iot/device/detail/DeviceDetailsInfo.vue b/src/views/iot/device/detail/DeviceDetailsInfo.vue
deleted file mode 100644
index 59b9d2542..000000000
--- a/src/views/iot/device/detail/DeviceDetailsInfo.vue
+++ /dev/null
@@ -1,123 +0,0 @@
-
-
-
-
- {{ product.name }}
-
- {{ product.productKey }}
- 复制
-
-
-
-
-
- {{ device.deviceName }}
- 复制
-
- {{ device.nickname }}
-
- {{ formatDate(device.createTime) }}
-
-
- {{ formatDate(device.activeTime) }}
-
-
- {{ formatDate(device.lastOnlineTime) }}
-
-
-
-
-
- {{ formatDate(device.lastOfflineTime) }}
-
-
- 查看
-
-
-
-
-
-
-
-
-
diff --git a/src/views/iot/device/detail/index.vue b/src/views/iot/device/detail/index.vue
deleted file mode 100644
index d56859bd3..000000000
--- a/src/views/iot/device/detail/index.vue
+++ /dev/null
@@ -1,66 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/views/iot/device/device/DeviceForm.vue b/src/views/iot/device/device/DeviceForm.vue
new file mode 100644
index 000000000..cf6e92ac0
--- /dev/null
+++ b/src/views/iot/device/device/DeviceForm.vue
@@ -0,0 +1,263 @@
+
+
+
+
diff --git a/src/views/iot/device/device/DeviceGroupForm.vue b/src/views/iot/device/device/DeviceGroupForm.vue
new file mode 100644
index 000000000..322e8a73a
--- /dev/null
+++ b/src/views/iot/device/device/DeviceGroupForm.vue
@@ -0,0 +1,90 @@
+
+
+
+
+
diff --git a/src/views/iot/device/device/DeviceImportForm.vue b/src/views/iot/device/device/DeviceImportForm.vue
new file mode 100644
index 000000000..a6412f6a5
--- /dev/null
+++ b/src/views/iot/device/device/DeviceImportForm.vue
@@ -0,0 +1,139 @@
+
+
+
+
+
diff --git a/src/views/iot/device/device/detail/DeviceDataDetail.vue b/src/views/iot/device/device/detail/DeviceDataDetail.vue
new file mode 100644
index 000000000..ced2a8a4a
--- /dev/null
+++ b/src/views/iot/device/device/detail/DeviceDataDetail.vue
@@ -0,0 +1,110 @@
+
+
+
+
+
diff --git a/src/views/iot/device/device/detail/DeviceDetailConfig.vue b/src/views/iot/device/device/detail/DeviceDetailConfig.vue
new file mode 100644
index 000000000..13906b570
--- /dev/null
+++ b/src/views/iot/device/device/detail/DeviceDetailConfig.vue
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+
+
+
+ 取消
+
+ 保存
+
+ 编辑
+
+
+
+
+
+
diff --git a/src/views/iot/device/detail/DeviceDetailsHeader.vue b/src/views/iot/device/device/detail/DeviceDetailsHeader.vue
similarity index 74%
rename from src/views/iot/device/detail/DeviceDetailsHeader.vue
rename to src/views/iot/device/device/detail/DeviceDetailsHeader.vue
index 62960529d..6fc876bc8 100644
--- a/src/views/iot/device/detail/DeviceDetailsHeader.vue
+++ b/src/views/iot/device/device/detail/DeviceDetailsHeader.vue
@@ -1,3 +1,4 @@
+
@@ -35,41 +36,33 @@
diff --git a/src/views/iot/device/device/detail/DeviceDetailsLog.vue b/src/views/iot/device/device/detail/DeviceDetailsLog.vue
new file mode 100644
index 000000000..8bbad4008
--- /dev/null
+++ b/src/views/iot/device/device/detail/DeviceDetailsLog.vue
@@ -0,0 +1,166 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+
+
+
+
+
+
+
+
+
+ {{ formatDate(scope.row.ts) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/device/device/detail/DeviceDetailsModel.vue b/src/views/iot/device/device/detail/DeviceDetailsModel.vue
new file mode 100644
index 000000000..26ddaa544
--- /dev/null
+++ b/src/views/iot/device/device/detail/DeviceDetailsModel.vue
@@ -0,0 +1,134 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 查看数据
+
+
+
+
+
+
+
+
+
+
+ 事件管理
+
+
+ 服务调用
+
+
+
+
+
diff --git a/src/views/iot/device/device/detail/DeviceDetailsSimulator.vue b/src/views/iot/device/device/detail/DeviceDetailsSimulator.vue
new file mode 100644
index 000000000..0ce918aa0
--- /dev/null
+++ b/src/views/iot/device/device/detail/DeviceDetailsSimulator.vue
@@ -0,0 +1,331 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ dataTypeOptionsLabel(row.property?.dataType) ?? '-' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 发送
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 设备上线
+
+
+ 设备下线
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/device/device/detail/index.vue b/src/views/iot/device/device/detail/index.vue
new file mode 100644
index 000000000..a2bd3dec3
--- /dev/null
+++ b/src/views/iot/device/device/detail/index.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/device/device/index.vue b/src/views/iot/device/device/index.vue
new file mode 100644
index 000000000..af3827479
--- /dev/null
+++ b/src/views/iot/device/device/index.vue
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+
+
+
+ 重置
+
+
+
+ 新增
+
+
+ 导出
+
+
+ 导入
+
+
+ 添加到分组
+
+
+ 批量删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ item.deviceName }}
+
+
+
+
+
+ {{ getDictLabel(DICT_TYPE.IOT_DEVICE_STATE, item.state) }}
+
+
+
+
+
+
+
+
+ 所属产品
+
+ {{ products.find((p) => p.id === item.productId)?.name }}
+
+
+
+ 设备类型
+
+
+
+ DeviceKey
+
+ {{ item.deviceKey }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+
+
+
+ 详情
+
+
+
+ 数据
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.deviceName }}
+
+
+
+
+
+ {{ products.find((p) => p.id === scope.row.productId)?.name || '-' }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ deviceGroups.find((g) => g.id === id)?.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 查看
+
+ 日志
+
+ 编辑
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/device/group/DeviceGroupForm.vue b/src/views/iot/device/group/DeviceGroupForm.vue
new file mode 100644
index 000000000..648725730
--- /dev/null
+++ b/src/views/iot/device/group/DeviceGroupForm.vue
@@ -0,0 +1,112 @@
+
+
+
+
diff --git a/src/views/iot/product/index.vue b/src/views/iot/device/group/index.vue
similarity index 59%
rename from src/views/iot/product/index.vue
rename to src/views/iot/device/group/index.vue
index fa285819e..ea2e4bea7 100644
--- a/src/views/iot/product/index.vue
+++ b/src/views/iot/device/group/index.vue
@@ -8,22 +8,24 @@
:inline="true"
label-width="68px"
>
-
+
-
-
+
@@ -33,7 +35,7 @@
type="primary"
plain
@click="openForm('create')"
- v-hasPermi="['iot:product:create']"
+ v-hasPermi="['iot:device-group:create']"
>
新增
@@ -44,17 +46,14 @@
-
+
+
+
- {{ scope.row.name }}
-
-
-
-
-
-
+
+
-
-
-
-
-
-
+
+
- 查看
+ 编辑
删除
@@ -99,39 +93,29 @@
-
+
diff --git a/src/views/iot/home/index.vue b/src/views/iot/home/index.vue
new file mode 100644
index 000000000..bee4116bf
--- /dev/null
+++ b/src/views/iot/home/index.vue
@@ -0,0 +1,509 @@
+
+
+
+
+
+
+
+ 分类数量
+
+
+
+ {{ statsData.productCategoryCount }}
+
+
+
+ 今日新增
+ +{{ statsData.productCategoryTodayCount }}
+
+
+
+
+
+
+
+
+ 产品数量
+
+
+
{{ statsData.productCount }}
+
+
+ 今日新增
+ +{{ statsData.productTodayCount }}
+
+
+
+
+
+
+
+
+ 设备数量
+
+
+
{{ statsData.deviceCount }}
+
+
+ 今日新增
+ +{{ statsData.deviceTodayCount }}
+
+
+
+
+
+
+
+
+ 设备消息数
+
+
+
+ {{ statsData.deviceMessageCount }}
+
+
+
+ 今日新增
+ +{{ statsData.deviceMessageTodayCount }}
+
+
+
+
+
+
+
+
+
+
+
+
+ 设备数量统计
+
+
+
+
+
+
+
+
+
+ 设备状态统计
+
+
+
+
+
+
+ 在线设备
+
+
+
+
+
+ 离线设备
+
+
+
+
+
+ 待激活设备
+
+
+
+
+
+
+
+
+
+
+
+
+
+
上下行消息量统计
+
+
+ 最近1小时
+ 最近24小时
+ 近一周
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/plugin/PluginConfigForm.vue b/src/views/iot/plugin/PluginConfigForm.vue
new file mode 100644
index 000000000..b4f510292
--- /dev/null
+++ b/src/views/iot/plugin/PluginConfigForm.vue
@@ -0,0 +1,106 @@
+
+
+
+
diff --git a/src/views/iot/plugin/detail/PluginImportForm.vue b/src/views/iot/plugin/detail/PluginImportForm.vue
new file mode 100644
index 000000000..2d3b75172
--- /dev/null
+++ b/src/views/iot/plugin/detail/PluginImportForm.vue
@@ -0,0 +1,99 @@
+
+
+
+
diff --git a/src/views/iot/plugin/detail/index.vue b/src/views/iot/plugin/detail/index.vue
new file mode 100644
index 000000000..31ed167b3
--- /dev/null
+++ b/src/views/iot/plugin/detail/index.vue
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+ {{ pluginConfig.name }}
+
+
+ {{ pluginConfig.pluginKey }}
+
+
+ {{ pluginConfig.version }}
+
+
+
+
+
+ {{ pluginConfig.description }}
+
+
+
+
+
+
+ 上传插件包
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/plugin/index.vue b/src/views/iot/plugin/index.vue
new file mode 100644
index 000000000..a5d6545ae
--- /dev/null
+++ b/src/views/iot/plugin/index.vue
@@ -0,0 +1,329 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+ 新增
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 查看
+
+
+ 编辑
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ item.name }}
+
+
+
+
+
+ {{ item.status === 1 ? '开启' : '禁用' }}
+
+
+
+
+
+
+
+
+ 插件标识
+
+ {{ item.pluginKey }}
+
+
+
+ jar 包
+ {{ item.fileName }}
+
+
+ 版本号
+ {{ item.version }}
+
+
+ 部署方式
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+
+
+
+ 详情
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/product/category/ProductCategoryForm.vue b/src/views/iot/product/category/ProductCategoryForm.vue
new file mode 100644
index 000000000..ff7219225
--- /dev/null
+++ b/src/views/iot/product/category/ProductCategoryForm.vue
@@ -0,0 +1,119 @@
+
+
+
+
diff --git a/src/views/iot/product/category/index.vue b/src/views/iot/product/category/index.vue
new file mode 100644
index 000000000..e78262217
--- /dev/null
+++ b/src/views/iot/product/category/index.vue
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+ 新增
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/product/detail/ProductDetailsInfo.vue b/src/views/iot/product/detail/ProductDetailsInfo.vue
deleted file mode 100644
index 5153045e7..000000000
--- a/src/views/iot/product/detail/ProductDetailsInfo.vue
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
- {{ product.name }}
-
-
-
-
- {{ formatDate(product.createTime) }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ product.description }}
-
-
-
-
-
diff --git a/src/views/iot/product/detail/ThinkModelFunctionForm.vue b/src/views/iot/product/detail/ThinkModelFunctionForm.vue
deleted file mode 100644
index 895692e00..000000000
--- a/src/views/iot/product/detail/ThinkModelFunctionForm.vue
+++ /dev/null
@@ -1,229 +0,0 @@
-
-
-
-
-
diff --git a/src/views/iot/product/ProductForm.vue b/src/views/iot/product/product/ProductForm.vue
similarity index 58%
rename from src/views/iot/product/ProductForm.vue
rename to src/views/iot/product/product/ProductForm.vue
index 75d6efcc0..83706fc6c 100644
--- a/src/views/iot/product/ProductForm.vue
+++ b/src/views/iot/product/product/ProductForm.vue
@@ -4,30 +4,48 @@
ref="formRef"
:model="formData"
:rules="formRules"
- label-width="100px"
+ label-width="110px"
v-loading="formLoading"
>
+
+
+
+
+ 重新生成
+
+
+
+
-
-
-
+
+
-
+
+
+
+ {{ dict.label }}
+
+
+
@@ -44,8 +62,11 @@
/>
-
-
+
-
-
-
+
-
+ :label="dict.value"
+ >
+ {{ dict.label }}
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
确 定
取 消
@@ -100,8 +124,17 @@
diff --git a/src/views/iot/product/detail/ProductDetailsHeader.vue b/src/views/iot/product/product/detail/ProductDetailsHeader.vue
similarity index 80%
rename from src/views/iot/product/detail/ProductDetailsHeader.vue
rename to src/views/iot/product/product/detail/ProductDetailsHeader.vue
index ba009516a..841aef9f0 100644
--- a/src/views/iot/product/detail/ProductDetailsHeader.vue
+++ b/src/views/iot/product/product/detail/ProductDetailsHeader.vue
@@ -45,8 +45,8 @@
- {{ product.deviceCount }}
- 前往管理
+ {{ product.deviceCount ?? '加载中...' }}
+ 前往管理
@@ -54,32 +54,37 @@
diff --git a/src/views/iot/product/detail/ProductTopic.vue b/src/views/iot/product/product/detail/ProductTopic.vue
similarity index 92%
rename from src/views/iot/product/detail/ProductTopic.vue
rename to src/views/iot/product/product/detail/ProductTopic.vue
index c327bb65d..a691a614a 100644
--- a/src/views/iot/product/detail/ProductTopic.vue
+++ b/src/views/iot/product/product/detail/ProductTopic.vue
@@ -3,9 +3,9 @@
diff --git a/src/views/iot/product/product/index.vue b/src/views/iot/product/product/index.vue
new file mode 100644
index 000000000..ea7c94ae7
--- /dev/null
+++ b/src/views/iot/product/product/index.vue
@@ -0,0 +1,355 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+
+
+
+ 重置
+
+
+
+ 新增
+
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ item.name }}
+
+
+
+
+
+
+ 产品分类
+ {{ item.categoryName }}
+
+
+ 产品类型
+
+
+
+ 产品标识
+
+ {{ item.productKey }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+
+
+
+ 详情
+
+
+
+ 物模型
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
+ 查看
+
+
+ 编辑
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/rule/databridge/IoTDataBridgeForm.vue b/src/views/iot/rule/databridge/IoTDataBridgeForm.vue
new file mode 100644
index 000000000..4e69c026f
--- /dev/null
+++ b/src/views/iot/rule/databridge/IoTDataBridgeForm.vue
@@ -0,0 +1,207 @@
+
+
+
+
diff --git a/src/views/iot/rule/databridge/config/HttpConfigForm.vue b/src/views/iot/rule/databridge/config/HttpConfigForm.vue
new file mode 100644
index 000000000..0dabd97f1
--- /dev/null
+++ b/src/views/iot/rule/databridge/config/HttpConfigForm.vue
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/rule/databridge/config/KafkaMQConfigForm.vue b/src/views/iot/rule/databridge/config/KafkaMQConfigForm.vue
new file mode 100644
index 000000000..91dfe382f
--- /dev/null
+++ b/src/views/iot/rule/databridge/config/KafkaMQConfigForm.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/rule/databridge/config/MqttConfigForm.vue b/src/views/iot/rule/databridge/config/MqttConfigForm.vue
new file mode 100644
index 000000000..2aa170110
--- /dev/null
+++ b/src/views/iot/rule/databridge/config/MqttConfigForm.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/rule/databridge/config/RabbitMQConfigForm.vue b/src/views/iot/rule/databridge/config/RabbitMQConfigForm.vue
new file mode 100644
index 000000000..b7ee5bb49
--- /dev/null
+++ b/src/views/iot/rule/databridge/config/RabbitMQConfigForm.vue
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/rule/databridge/config/RedisStreamMQConfigForm.vue b/src/views/iot/rule/databridge/config/RedisStreamMQConfigForm.vue
new file mode 100644
index 000000000..415ceb90f
--- /dev/null
+++ b/src/views/iot/rule/databridge/config/RedisStreamMQConfigForm.vue
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/rule/databridge/config/RocketMQConfigForm.vue b/src/views/iot/rule/databridge/config/RocketMQConfigForm.vue
new file mode 100644
index 000000000..c1f4c1027
--- /dev/null
+++ b/src/views/iot/rule/databridge/config/RocketMQConfigForm.vue
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/rule/databridge/config/components/KeyValueEditor.vue b/src/views/iot/rule/databridge/config/components/KeyValueEditor.vue
new file mode 100644
index 000000000..a2e543064
--- /dev/null
+++ b/src/views/iot/rule/databridge/config/components/KeyValueEditor.vue
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+ 删除
+
+
+
+
+
+
+ {{ addButtonText }}
+
+
+
+
diff --git a/src/views/iot/rule/databridge/config/index.ts b/src/views/iot/rule/databridge/config/index.ts
new file mode 100644
index 000000000..77f3315a4
--- /dev/null
+++ b/src/views/iot/rule/databridge/config/index.ts
@@ -0,0 +1,15 @@
+import HttpConfigForm from './HttpConfigForm.vue'
+import MqttConfigForm from './MqttConfigForm.vue'
+import RocketMQConfigForm from './RocketMQConfigForm.vue'
+import KafkaMQConfigForm from './KafkaMQConfigForm.vue'
+import RabbitMQConfigForm from './RabbitMQConfigForm.vue'
+import RedisStreamMQConfigForm from './RedisStreamMQConfigForm.vue'
+
+export {
+ HttpConfigForm,
+ MqttConfigForm,
+ RocketMQConfigForm,
+ KafkaMQConfigForm,
+ RabbitMQConfigForm,
+ RedisStreamMQConfigForm
+}
diff --git a/src/views/iot/rule/databridge/index.vue b/src/views/iot/rule/databridge/index.vue
new file mode 100644
index 000000000..2bb7720dd
--- /dev/null
+++ b/src/views/iot/rule/databridge/index.vue
@@ -0,0 +1,234 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+
+
+
+ 重置
+
+
+
+ 新增
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/thingmodel/ThingModelEvent.vue b/src/views/iot/thingmodel/ThingModelEvent.vue
new file mode 100644
index 000000000..592eb86c6
--- /dev/null
+++ b/src/views/iot/thingmodel/ThingModelEvent.vue
@@ -0,0 +1,56 @@
+
+
+
+
+
+ {{ ThingModelEventType.INFO.label }}
+
+
+ {{ ThingModelEventType.ALERT.label }}
+
+
+ {{ ThingModelEventType.ERROR.label }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/thingmodel/ThingModelForm.vue b/src/views/iot/thingmodel/ThingModelForm.vue
new file mode 100644
index 000000000..f800257d9
--- /dev/null
+++ b/src/views/iot/thingmodel/ThingModelForm.vue
@@ -0,0 +1,215 @@
+
+
+
+
+
+
diff --git a/src/views/iot/thingmodel/ThingModelInputOutputParam.vue b/src/views/iot/thingmodel/ThingModelInputOutputParam.vue
new file mode 100644
index 000000000..2bf4bb932
--- /dev/null
+++ b/src/views/iot/thingmodel/ThingModelInputOutputParam.vue
@@ -0,0 +1,155 @@
+
+
+
+
参数名称:{{ item.name }}
+
+ 编辑
+
+ 删除
+
+
+ +新增参数
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/thingmodel/ThingModelProperty.vue b/src/views/iot/thingmodel/ThingModelProperty.vue
new file mode 100644
index 000000000..74a6b2efa
--- /dev/null
+++ b/src/views/iot/thingmodel/ThingModelProperty.vue
@@ -0,0 +1,169 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.value }}
+ -
+
+
+
+
+
+
+
+
+
+ 字节
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ ThingModelAccessMode.READ_WRITE.label }}
+
+
+ {{ ThingModelAccessMode.READ_ONLY.label }}
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/thingmodel/ThingModelService.vue b/src/views/iot/thingmodel/ThingModelService.vue
new file mode 100644
index 000000000..de5009fd6
--- /dev/null
+++ b/src/views/iot/thingmodel/ThingModelService.vue
@@ -0,0 +1,59 @@
+
+
+
+
+
+ {{ ThingModelServiceCallType.ASYNC.label }}
+
+
+ {{ ThingModelServiceCallType.SYNC.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/thingmodel/components/DataDefinition.vue b/src/views/iot/thingmodel/components/DataDefinition.vue
new file mode 100644
index 000000000..2b94a5783
--- /dev/null
+++ b/src/views/iot/thingmodel/components/DataDefinition.vue
@@ -0,0 +1,61 @@
+
+
+
+
+
+ 取值范围:{{ `${data.property.dataSpecs.min}~${data.property.dataSpecs.max}` }}
+
+
+
+ 数据长度:{{ data.property.dataSpecs.length }}
+
+
+
+ -
+
+
+
+
{{ DataSpecsDataType.BOOL === data.property.dataType ? '布尔值' : '枚举值' }}:
+
+ {{ `${item.name}-${item.value}` }}
+
+
+
+
+
+ 调用方式:{{ getCallTypeByValue(data.service!.callType) }}
+
+
+
+ 事件类型:{{ getEventTypeByValue(data.event!.type) }}
+
+
+
+
+
+
diff --git a/src/views/iot/thingmodel/components/index.ts b/src/views/iot/thingmodel/components/index.ts
new file mode 100644
index 000000000..66c692bac
--- /dev/null
+++ b/src/views/iot/thingmodel/components/index.ts
@@ -0,0 +1,3 @@
+import DataDefinition from './DataDefinition.vue'
+
+export { DataDefinition }
diff --git a/src/views/iot/thingmodel/config.ts b/src/views/iot/thingmodel/config.ts
new file mode 100644
index 000000000..7c9699a19
--- /dev/null
+++ b/src/views/iot/thingmodel/config.ts
@@ -0,0 +1,213 @@
+import { isEmpty } from '@/utils/is'
+
+/** dataSpecs 数值型数据结构 */
+export interface DataSpecsNumberDataVO {
+ dataType: 'int' | 'float' | 'double' // 数据类型,取值为 INT、FLOAT 或 DOUBLE
+ max: string // 最大值,必须与 dataType 设置一致,且为 STRING 类型
+ min: string // 最小值,必须与 dataType 设置一致,且为 STRING 类型
+ step: string // 步长,必须与 dataType 设置一致,且为 STRING 类型
+ precise?: string // 精度,当 dataType 为 FLOAT 或 DOUBLE 时可选
+ defaultValue?: string // 默认值,可选
+ unit: string // 单位的符号
+ unitName: string // 单位的名称
+}
+
+/** dataSpecs 枚举型数据结构 */
+export interface DataSpecsEnumOrBoolDataVO {
+ dataType: 'enum' | 'bool'
+ defaultValue?: string // 默认值,可选
+ name: string // 枚举项的名称
+ value: number | undefined // 枚举值
+}
+
+/** 属性值的数据类型 */
+export const DataSpecsDataType = {
+ INT: 'int',
+ FLOAT: 'float',
+ DOUBLE: 'double',
+ ENUM: 'enum',
+ BOOL: 'bool',
+ TEXT: 'text',
+ DATE: 'date',
+ STRUCT: 'struct',
+ ARRAY: 'array'
+} as const
+
+/** 物体模型数据类型配置项 */
+export const dataTypeOptions = [
+ { value: DataSpecsDataType.INT, label: '整数型' },
+ { value: DataSpecsDataType.FLOAT, label: '单精度浮点型' },
+ { value: DataSpecsDataType.DOUBLE, label: '双精度浮点型' },
+ { value: DataSpecsDataType.ENUM, label: '枚举型' },
+ { value: DataSpecsDataType.BOOL, label: '布尔型' },
+ { value: DataSpecsDataType.TEXT, label: '文本型' },
+ { value: DataSpecsDataType.DATE, label: '时间型' },
+ { value: DataSpecsDataType.STRUCT, label: '结构体' },
+ { value: DataSpecsDataType.ARRAY, label: '数组' }
+]
+
+/** 获得物体模型数据类型配置项名称 */
+export const getDataTypeOptionsLabel = (value: string) => {
+ if (isEmpty(value)) {
+ return value
+ }
+ const dataType = dataTypeOptions.find((option) => option.value === value)
+ return dataType && `${dataType.value}(${dataType.label})`
+}
+
+// IOT 产品物模型类型枚举类
+export const ThingModelType = {
+ PROPERTY: 1, // 属性
+ SERVICE: 2, // 服务
+ EVENT: 3 // 事件
+} as const
+
+// IOT 产品物模型访问模式枚举类
+export const ThingModelAccessMode = {
+ READ_WRITE: {
+ label: '读写',
+ value: 'rw'
+ },
+ READ_ONLY: {
+ label: '只读',
+ value: 'r'
+ }
+} as const
+
+// IOT 产品物模型服务调用方式枚举
+export const ThingModelServiceCallType = {
+ ASYNC: {
+ label: '异步调用',
+ value: 'async'
+ },
+ SYNC: {
+ label: '同步调用',
+ value: 'sync'
+ }
+} as const
+export const getCallTypeByValue = (value: string): string | undefined =>
+ Object.values(ThingModelServiceCallType).find((type) => type.value === value)?.label
+
+// IOT 产品物模型事件类型枚举
+export const ThingModelEventType = {
+ INFO: {
+ label: '信息',
+ value: 'info'
+ },
+ ALERT: {
+ label: '告警',
+ value: 'alert'
+ },
+ ERROR: {
+ label: '故障',
+ value: 'error'
+ }
+} as const
+export const getEventTypeByValue = (value: string): string | undefined =>
+ Object.values(ThingModelEventType).find((type) => type.value === value)?.label
+
+// IOT 产品物模型参数是输入参数还是输出参数
+export const ThingModelParamDirection = {
+ INPUT: 'input', // 输入参数
+ OUTPUT: 'output' // 输出参数
+} as const
+
+/** 公共校验规则 */
+export const ThingModelFormRules = {
+ name: [
+ { required: true, message: '功能名称不能为空', trigger: 'blur' },
+ {
+ pattern: /^[\u4e00-\u9fa5a-zA-Z0-9][\u4e00-\u9fa5a-zA-Z0-9\-_/\.]{0,29}$/,
+ message:
+ '支持中文、大小写字母、日文、数字、短划线、下划线、斜杠和小数点,必须以中文、英文或数字开头,不超过 30 个字符',
+ trigger: 'blur'
+ }
+ ],
+ type: [{ required: true, message: '功能类型不能为空', trigger: 'blur' }],
+ identifier: [
+ { required: true, message: '标识符不能为空', trigger: 'blur' },
+ {
+ pattern: /^[a-zA-Z0-9_]{1,50}$/,
+ message: '支持大小写字母、数字和下划线,不超过 50 个字符',
+ trigger: 'blur'
+ },
+ {
+ validator: (_: any, value: string, callback: any) => {
+ const reservedKeywords = ['set', 'get', 'post', 'property', 'event', 'time', 'value']
+ if (reservedKeywords.includes(value)) {
+ callback(
+ new Error(
+ 'set, get, post, property, event, time, value 是系统保留字段,不能用于标识符定义'
+ )
+ )
+ } else if (/^\d+$/.test(value)) {
+ callback(new Error('标识符不能是纯数字'))
+ } else {
+ callback()
+ }
+ },
+ trigger: 'blur'
+ }
+ ],
+ 'property.dataSpecs.childDataType': [{ required: true, message: '元素类型不能为空' }],
+ 'property.dataSpecs.size': [
+ { required: true, message: '元素个数不能为空' },
+ {
+ validator: (_: any, value: any, callback: any) => {
+ if (isEmpty(value)) {
+ callback(new Error('元素个数不能为空'))
+ return
+ }
+ if (isNaN(Number(value))) {
+ callback(new Error('元素个数必须是数字'))
+ return
+ }
+ callback()
+ },
+ trigger: 'blur'
+ }
+ ],
+ 'property.dataSpecs.length': [
+ { required: true, message: '请输入文本字节长度', trigger: 'blur' },
+ {
+ validator: (_: any, value: any, callback: any) => {
+ if (isEmpty(value)) {
+ callback(new Error('文本长度不能为空'))
+ return
+ }
+ if (isNaN(Number(value))) {
+ callback(new Error('文本长度必须是数字'))
+ return
+ }
+ callback()
+ },
+ trigger: 'blur'
+ }
+ ],
+ 'property.accessMode': [{ required: true, message: '请选择读写类型', trigger: 'change' }]
+}
+
+/** 校验布尔值名称 */
+export const validateBoolName = (_: any, value: string, callback: any) => {
+ if (isEmpty(value)) {
+ callback(new Error('布尔值名称不能为空'))
+ return
+ }
+ // 检查开头字符
+ if (!/^[\u4e00-\u9fa5a-zA-Z0-9]/.test(value)) {
+ callback(new Error('布尔值名称必须以中文、英文字母或数字开头'))
+ return
+ }
+ // 检查整体格式
+ if (!/^[\u4e00-\u9fa5a-zA-Z0-9][a-zA-Z0-9\u4e00-\u9fa5_-]*$/.test(value)) {
+ callback(new Error('布尔值名称只能包含中文、英文字母、数字、下划线和短划线'))
+ return
+ }
+ // 检查长度(一个中文算一个字符)
+ if (value.length > 20) {
+ callback(new Error('布尔值名称长度不能超过 20 个字符'))
+ return
+ }
+
+ callback()
+}
diff --git a/src/views/iot/thingmodel/dataSpecs/ThingModelArrayDataSpecs.vue b/src/views/iot/thingmodel/dataSpecs/ThingModelArrayDataSpecs.vue
new file mode 100644
index 000000000..04a975a1c
--- /dev/null
+++ b/src/views/iot/thingmodel/dataSpecs/ThingModelArrayDataSpecs.vue
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+ {{ `${item.value}(${item.label})` }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/thingmodel/dataSpecs/ThingModelEnumDataSpecs.vue b/src/views/iot/thingmodel/dataSpecs/ThingModelEnumDataSpecs.vue
new file mode 100644
index 000000000..fb323ca6a
--- /dev/null
+++ b/src/views/iot/thingmodel/dataSpecs/ThingModelEnumDataSpecs.vue
@@ -0,0 +1,159 @@
+
+
+
+
+
+ 参数值
+ 参数描述
+
+
+
+
+
+ ~
+
+
+
+ 删除
+
+
+添加枚举项
+
+
+
+
+
+
+
diff --git a/src/views/iot/thingmodel/dataSpecs/ThingModelNumberDataSpecs.vue b/src/views/iot/thingmodel/dataSpecs/ThingModelNumberDataSpecs.vue
new file mode 100644
index 000000000..66c953135
--- /dev/null
+++ b/src/views/iot/thingmodel/dataSpecs/ThingModelNumberDataSpecs.vue
@@ -0,0 +1,139 @@
+
+
+
+
+
+
+
+ ~
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/thingmodel/dataSpecs/ThingModelStructDataSpecs.vue b/src/views/iot/thingmodel/dataSpecs/ThingModelStructDataSpecs.vue
new file mode 100644
index 000000000..fb2258c16
--- /dev/null
+++ b/src/views/iot/thingmodel/dataSpecs/ThingModelStructDataSpecs.vue
@@ -0,0 +1,170 @@
+
+
+
+
+
+
参数名称:{{ item.name }}
+
+ 编辑
+
+ 删除
+
+
+ +新增参数
+
+
+
+
+
+
+
+
+
diff --git a/src/views/iot/thingmodel/dataSpecs/index.ts b/src/views/iot/thingmodel/dataSpecs/index.ts
new file mode 100644
index 000000000..30151aea6
--- /dev/null
+++ b/src/views/iot/thingmodel/dataSpecs/index.ts
@@ -0,0 +1,11 @@
+import ThingModelEnumDataSpecs from './ThingModelEnumDataSpecs.vue'
+import ThingModelNumberDataSpecs from './ThingModelNumberDataSpecs.vue'
+import ThingModelArrayDataSpecs from './ThingModelArrayDataSpecs.vue'
+import ThingModelStructDataSpecs from './ThingModelStructDataSpecs.vue'
+
+export {
+ ThingModelEnumDataSpecs,
+ ThingModelNumberDataSpecs,
+ ThingModelArrayDataSpecs,
+ ThingModelStructDataSpecs
+}
diff --git a/src/views/iot/product/detail/ThinkModelFunction.vue b/src/views/iot/thingmodel/index.vue
similarity index 55%
rename from src/views/iot/product/detail/ThinkModelFunction.vue
rename to src/views/iot/thingmodel/index.vue
index 5a75d109f..9ddd449af 100644
--- a/src/views/iot/product/detail/ThinkModelFunction.vue
+++ b/src/views/iot/thingmodel/index.vue
@@ -1,22 +1,23 @@
+
- 搜索
- 重置
+
+
+ 搜索
+
+
+
+ 重置
+
- 添加功能
+
+ 添加功能
+
+
-
-
+
+
-
+
-
-
-
+
+
+
+
+ {{ dataTypeOptionsLabel(row.property?.dataType) ?? '-' }}
+
+
+
+
+
+
+
+
编辑
删除
@@ -70,29 +90,32 @@
-
+
-
-
-
diff --git a/src/views/knowledge/dataset-form/form-step2.vue b/src/views/knowledge/dataset-form/form-step2.vue
deleted file mode 100644
index f8ca5718e..000000000
--- a/src/views/knowledge/dataset-form/form-step2.vue
+++ /dev/null
@@ -1,168 +0,0 @@
-
-
-
-
-
-
-
-
-
- 自动分段与清洗
- 自定义
-
-
-
-
-
-
- 高质量
- 经济
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 分段预览
-
-
-
-
-
-
{{ segment.number }}
-
-
-
-
-
-
{{ segment.text }}
-
-
-
-
-
-
-
-
-
-
diff --git a/src/views/knowledge/dataset.vue b/src/views/knowledge/dataset.vue
deleted file mode 100644
index 4636a9123..000000000
--- a/src/views/knowledge/dataset.vue
+++ /dev/null
@@ -1,152 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- 1 文档
- 5 千字符
- 0 关联应用
-
-
- useful for when you want to answer queries about the 接口鉴权示例代码.md
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/views/mall/product/spu/index.vue b/src/views/mall/product/spu/index.vue
index 0451ef3a1..e12403ce9 100644
--- a/src/views/mall/product/spu/index.vue
+++ b/src/views/mall/product/spu/index.vue
@@ -411,7 +411,7 @@ const handleExport = async () => {
await message.exportConfirm()
// 发起导出
exportLoading.value = true
- const data = await ProductSpuApi.exportSpu(queryParams)
+ const data = await ProductSpuApi.exportSpu(queryParams.value)
download.excel(data, '商品列表.xls')
} catch {
} finally {
@@ -434,7 +434,7 @@ onActivated(() => {
onMounted(async () => {
// 解析路由的 categoryId
if (route.query.categoryId) {
- queryParams.value.categoryId = Number(route.query.categoryId)
+ queryParams.value.categoryId = route.query.categoryId
}
// 获得商品信息
await getTabsCount()
diff --git a/src/views/mall/promotion/kefu/components/KeFuConversationList.vue b/src/views/mall/promotion/kefu/components/KeFuConversationList.vue
index 075edc33e..318e27d12 100644
--- a/src/views/mall/promotion/kefu/components/KeFuConversationList.vue
+++ b/src/views/mall/promotion/kefu/components/KeFuConversationList.vue
@@ -200,7 +200,7 @@ onBeforeUnmount(() => {