Browse Source

用户域同步逻辑

master
xueyinfei 2 months ago
parent
commit
f51126550e
  1. 33
      vue-fastapi-backend/.env.dev
  2. 2
      vue-fastapi-frontend/.env.development
  3. 2
      vue-fastapi-frontend/.env.production
  4. 2
      vue-fastapi-frontend/.env.staging
  5. 5
      vue-fastapi-frontend/package.json
  6. 8
      vue-fastapi-frontend/src/api/flow/flow.js
  7. 5
      vue-fastapi-frontend/src/layout/components/AppMain.vue
  8. 2
      vue-fastapi-frontend/src/views/meta/metaInfo/index.vue
  9. 381
      vue-fastapi-frontend/src/views/system/flow/conf.vue

33
vue-fastapi-backend/.env.dev

@ -4,7 +4,7 @@ APP_ENV = 'dev'
# 应用名称
APP_NAME = 'RuoYi-FastAPI'
# 应用代理路径
APP_ROOT_PATH = '/dev-api'
APP_ROOT_PATH = '/default-api'
# 应用主机
APP_HOST = '127.0.0.1'
# 应用端口
@ -33,20 +33,20 @@ JWT_REDIS_EXPIRE_MINUTES = 30
# 数据库类型,可选的有'mysql'、'postgresql',默认为'mysql'
DB_TYPE = 'mysql'
# 数据库主机
# DB_HOST = '192.168.0.3'
DB_HOST = '127.0.0.1'
DB_HOST = '192.168.0.3'
#DB_HOST = '47.113.147.166'
# 数据库端口
DB_PORT = 3306
# 数据库用户名
# DB_USERNAME = 'admin'
DB_USERNAME = 'root'
DB_USERNAME = 'admin'
#DB_USERNAME = 'dbf'
# 数据库密码
# DB_PASSWORD = '123456'
DB_PASSWORD = 'root'
DB_PASSWORD = '123456'
#DB_PASSWORD = '1q2w3e4r'
# 数据库名称
# DB_DATABASE = 'vue_faseapi'
DB_DATABASE = 'ruoyi-fastapi'
DB_DATABASE = 'vue_faseapi'
#DB_DATABASE = 'vfa_test_0115'
# 是否开启sqlalchemy日志
DB_ECHO = true
@ -61,8 +61,8 @@ DB_POOL_TIMEOUT = 30
# -------- Redis配置 --------
# Redis主机
# REDIS_HOST = '192.168.0.3'
REDIS_HOST = '127.0.0.1'
REDIS_HOST = '192.168.0.3'
#REDIS_HOST = '127.0.0.1'
# Redis端口
REDIS_PORT = 6379
@ -76,11 +76,14 @@ REDIS_DATABASE = 2
# -------- minio配置 --------
# minio主机
MINIO_ADDRESS = '192.168.0.3:9000'
MINIO_ADDRESS = '47.121.207.11:9000'
# MINIO_ADDRESS = '192.168.0.3:9000'
# minio用户
MINIO_ADMIN = 'admin'
MINIO_ADMIN = 'WFpLqkCgjoQNsnu6t7FO'
# MINIO_ADMIN = 'admin'
# minio密码
MINIO_PASSWORD = 'admin123'
MINIO_PASSWORD = 'gPRViF52Or5Fyvr0PCZHuIxZGfrTpNynajMiEjBZ'
# MINIO_PASSWORD = 'admin123'
# 访问dolphinscheduler的接口地址
DS_SERVER_URL= http://47.121.207.11:12345
DS_SERVER_URL= http://localhost:12345

2
vue-fastapi-frontend/.env.development

@ -5,4 +5,4 @@ VITE_APP_TITLE = 大模型管理系统
VITE_APP_ENV = 'development'
# vfadmin管理系统/开发环境
VITE_APP_BASE_API = '/dev-api'
VITE_APP_BASE_API = '/default-api'

2
vue-fastapi-frontend/.env.production

@ -5,7 +5,7 @@ VITE_APP_TITLE = 大模型管理系统
VITE_APP_ENV = 'production'
# vfadmin管理系统/生产环境
VITE_APP_BASE_API = '/prod-api'
VITE_APP_BASE_API = '/default-api'
# 是否在打包时开启压缩,支持 gzip 和 brotli
VITE_BUILD_COMPRESS = gzip

2
vue-fastapi-frontend/.env.staging

@ -5,7 +5,7 @@ VITE_APP_TITLE = 大模型管理系统
VITE_APP_ENV = 'staging'
# vfadmin管理系统/生产环境
VITE_APP_BASE_API = '/stage-api'
VITE_APP_BASE_API = '/default-api'
# 是否在打包时开启压缩,支持 gzip 和 brotli
VITE_BUILD_COMPRESS = gzip

5
vue-fastapi-frontend/package.json

@ -19,6 +19,11 @@
"@ant-design/icons-vue": "^7.0.1",
"@antv/g2plot": "^2.4.31",
"@antv/g6": "^4.8.24",
"@antv/x6": "^2.18.1",
"@antv/x6-plugin-clipboard": "^2.1.6",
"@antv/x6-plugin-keyboard": "^2.2.3",
"@antv/x6-plugin-selection": "^2.2.2",
"@antv/x6-plugin-stencil": "^2.1.5",
"@element-plus/icons-vue": "2.3.1",
"@vueup/vue-quill": "1.2.0",
"@vueuse/core": "10.11.0",

8
vue-fastapi-frontend/src/api/flow/flow.js

@ -9,6 +9,14 @@ export function getApprovalList(data) {
})
}
export function getflowList(data) {
return request({
url: '/default-api/approval/list',
method: 'get',
params: {module:data}
})
}
export function getWaitingFlowCount() {
return request({
url: '/default-api/approval/waitingTotal',

5
vue-fastapi-frontend/src/layout/components/AppMain.vue

@ -76,10 +76,11 @@ function closeChatDiv(){
<style lang="scss" scoped>
.app-main {
/* 50= navbar 50 */
min-height: calc(100vh - 50px);
//min-height: calc(100vh - 50px);
height: calc(100vh - 84px);
width: 100%;
position: relative;
overflow: hidden;
overflow: auto;
}
.fixed-header + .app-main {

2
vue-fastapi-frontend/src/views/meta/metaInfo/index.vue

@ -739,7 +739,7 @@
"clasPriClas": "",
"clasScdClas": ""
}
currentColumnData.value.fldClas = row.fldClas === null?[]:JSON.parse(row.fldClas)
currentColumnData.value.fldClas = (row.fldClas === null || row.fldClas === '')?[]:JSON.parse(row.fldClas)
getMetaClasList().then(res=>{
metaClasList.value = res.data
})

381
vue-fastapi-frontend/src/views/system/flow/conf.vue

@ -1,11 +1,386 @@
<template>
<div class="app-container">
<span>你好</span>
<div style="height: 100%;width: 100%">
<el-row>
<el-col :span="4">
<div style="text-align: center;margin-top: 10px;" >
<el-button icon="Plus" type="primary" @click="showAddDialog">新增节点</el-button>
<el-button type="primary" @click="save">
<i class="ri-save-3-line"></i> 保存
</el-button>
</div>
<div style="text-align: center;margin-top: 10px;" >
<el-button class="moduleButton" style="width: 50%;height: 100px;" :style="{background: checked ==='元数据'?'#ebf5ff':'none'}" @click="changeBackGround('元数据信息')">
元数据信息模块
</el-button>
</div>
<div style="text-align: center;margin-top: 10px">
<el-button class="moduleButton" style="width: 50%;height: 100px" :style="{background: checked ==='其他模块'?'#ebf5ff':'none'}" @click="changeBackGround('其他模块')">
其他模块----敬请期待
</el-button>
</div>
</el-col>
<el-col :span="20">
<div id="flow-container"></div>
</el-col>
</el-row>
<el-dialog
v-model="showAdd"
title="新增审批节点"
width="500"
>
<el-form :model="addForm" class="demo-form-inline">
<el-form-item label="审批角色/人员:">
<el-radio-group v-model="addForm.roleOrUser">
<el-radio-button label="Role" value="Role" />
<el-radio-button label="User" value="User" />
</el-radio-group>
</el-form-item>
<el-form-item v-if="addForm.roleOrUser === 'Role'" label="选择角色:">
<el-select v-model="addForm.role">
<el-option v-for="item in roleList" :value="item.roleKey+'-'+item.remark" :label="item.remark" :key="item.roleKey"></el-option>
</el-select>
</el-form-item>
<el-form-item v-if="addForm.roleOrUser === 'User'" label="选择用户:">
<el-input v-model="addForm.user" placeholder="请输入用户登录名"></el-input>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="showAdd = false">取消</el-button>
<el-button type="primary" @click="confirmAddNode">
确定
</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { Graph, Cell, Shape } from '@antv/x6'
import {v4 as uuid} from 'uuid'
import { Stencil } from '@antv/x6-plugin-stencil'
import { Keyboard } from '@antv/x6-plugin-keyboard'
import { Selection } from '@antv/x6-plugin-selection'
import { Clipboard } from '@antv/x6-plugin-clipboard'
import { ref, nextTick, computed, watch, reactive, onMounted } from 'vue'
import { listRole } from "@/api/system/role";
import {getflowList } from "@/api/flow/flow";
let graph = null
const roleList = ref([])
const data = ref([])
const checked = ref('元数据')
const ports = ref({
groups: {
top: {
position: 'top',
attrs: {
circle: {
r: 4,
magnet: true,
stroke: '#5F95FF',
strokeWidth: 1,
fill: '#fff',
style: {
visibility: 'hidden',
},
},
},
},
right: {
position: 'right',
attrs: {
circle: {
r: 4,
magnet: true,
stroke: '#5F95FF',
strokeWidth: 1,
fill: '#fff',
style: {
visibility: 'hidden',
},
},
},
},
bottom: {
position: 'bottom',
attrs: {
circle: {
r: 4,
magnet: true,
stroke: '#5F95FF',
strokeWidth: 1,
fill: '#fff',
style: {
visibility: 'hidden',
},
},
},
},
left: {
position: 'left',
attrs: {
circle: {
r: 4,
magnet: true,
stroke: '#5F95FF',
strokeWidth: 1,
fill: '#fff',
style: {
visibility: 'hidden',
},
},
},
},
},
items: [
{
group: 'top',
},
{
group: 'right',
},
{
group: 'bottom',
},
{
group: 'left',
},
],
})
const showAdd = ref(false)
const addForm = ref({roleOrUser:'Role',role:'',user:''})
function confirmAddNode(){
let node = {
"id": uuid(),
"shape": "activity",
"width": 100,
"height": 60,
"position": {
"x": 0,
"y": 0
},
}
if (addForm.value.roleOrUser === 'Role'){
let split = addForm.value.role.split("-")
node.label = split[1]
node.code = split[0]
node.type = 'Role'
}else {
node.label = addForm.value.user
node.code = addForm.value.user
node.type = 'User'
}
graph.addNode(node)
showAdd.value = false
}
function showPorts (ports, show){
for (let i = 0, len = ports.length; i < len; i += 1) {
ports[i].style.visibility = show ? 'visible' : 'hidden'
}
}
function register(){
Graph.registerNode(
'activity',
{
inherit: 'rect',
markup: [
{
tagName: 'rect',
selector: 'body',
},
{
tagName: 'image',
selector: 'img',
},
{
tagName: 'text',
selector: 'label',
},
],
attrs: {
body: {
rx: 6,
ry: 6,
stroke: '#5F95FF',
fill: '#EFF4FF',
strokeWidth: 1,
},
img: {
x: 6,
y: 6,
width: 16,
height: 16,
'xlink:href':
'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*pwLpRr7QPGwAAAAAAAAAAAAAARQnAQ',
},
label: {
fontSize: 12,
fill: '#262626',
},
},
ports: { ...ports.value },
},
true,
)
Graph.registerEdge(
'bpmn-edge',
{
inherit: 'edge',
attrs: {
line: {
stroke: '#A2B1C3',
strokeWidth: 2,
},
},
},
true,
)
}
function changeBackGround(module){
if (module === '元数据信息'){
checked.value = '元数据'
}
if (module === '其他模块'){
checked.value = '其他模块'
}
getflowList(checked.value).then(res=>{
})
}
function showAddDialog(){
showAdd.value = true
listRole({pageNum:1,pageSize:100,status:0}).then(res=>{
roleList.value = res.rows;
})
}
function save(){
let json = graph.toJSON()
let array = json.cells;
console.log(array)
let flows = []
if (array.length>0){
for (let i = 0; i < array.length; i++) {
let cell = array[i]
if (cell.shape === "activity"){
flows.push({
id: cell.id,
code: cell.code,
text: cell.attrs.text.text,
type: cell.type,
x: cell.position.x,
y: cell.position.y,
parent: [],
})
}
}
for (let i = 0; i < array.length; i++) {
let cell = array[i]
if (cell.shape === "edge"){
let target = cell.target.cell
let source = cell.source.cell
let sourceNode = flows.find(item => item.id === source)
let targetNode = flows.find(item => item.id === target)
if (sourceNode !== undefined && targetNode !== undefined){
for (let j = 0; j < flows.length; j++) {
if (flows[j].id === target){
flows[j].parent.push(source)
}
}
}
}
}
}
console.log(flows)
}
function loadGraphData(){
let array = []
data.value.forEach((item) => {
let node = {
id: item.id,
code: item.code,
attrs: {text:{text: item.text}},
position:{x:item.x,y:item.y},
width: 100,
height: 60,
shape: "activity"
}
array.push(node)
})
data.value.forEach((item) => {
if (item.parent && item.parent.length > 0){
item.parent.forEach((parentNodeId) =>{
let node = {
id: uuid(),
shape: 'edge',
source: {cell: parentNodeId},
target: {cell: item.id}
}
array.push(node)
})
}
})
graph.fromJSON(array)
graph.zoomToFit({ padding:10, maxScale: 1 })
}
onMounted(re=>{
register()
graph = new Graph({
container: document.getElementById('flow-container'),
width: 800,
height: 800,
grid:true,
autoResize: true,
connecting: {
router: 'orth',
},
createEdge() {
return new Shape.Edge({
"id": uuid(),
"shape": "bpmn-edge",
"source": "7",
"target": "13"
});
}
})
graph.use(new Keyboard())
.use(
new Selection({
rubberband: true,
showNodeSelectionBox: true,
}),
)
// select all
graph.bindKey(['meta+a', 'ctrl+a'], () => {
const nodes = graph.getNodes()
if (nodes) {
graph.select(nodes)
}
})
// delete
graph.bindKey('backspace', () => {
const cells = graph.getSelectedCells()
if (cells.length) {
graph.removeCells(cells)
}
})
graph.on('node:mouseenter', () => {
const container = document.getElementById('flow-container')
const ports = container.querySelectorAll('.x6-port-body',)
showPorts(ports, true)
})
graph.on('node:mouseleave', () => {
const container = document.getElementById('flow-container')
const ports = container.querySelectorAll('.x6-port-body',)
showPorts(ports, false)
})
loadGraphData()
})
</script>
<style scoped lang="scss">
.moduleButton:hover{
background: #ebf5ff !important;
}
</style>
Loading…
Cancel
Save