@ -0,0 +1,25 @@ |
||||
.DS_Store |
||||
node_modules/ |
||||
dist/ |
||||
npm-debug.log* |
||||
yarn-debug.log* |
||||
yarn-error.log* |
||||
**/*.log |
||||
|
||||
tests/**/coverage/ |
||||
tests/e2e/reports |
||||
selenium-debug.log |
||||
.history |
||||
/server/form |
||||
|
||||
# Editor directories and files |
||||
.idea |
||||
.vscode |
||||
*.suo |
||||
*.ntvs* |
||||
*.njsproj |
||||
*.sln |
||||
*.local |
||||
|
||||
package-lock.json |
||||
yarn.lock |
@ -0,0 +1,11 @@ |
||||
{ |
||||
"server/config.js": { |
||||
"description": "配置文件" |
||||
}, |
||||
"server/build": { |
||||
"description": "构建配置" |
||||
}, |
||||
"server/form": { |
||||
"description": "流程表单配置" |
||||
} |
||||
} |
@ -0,0 +1,20 @@ |
||||
{ |
||||
"name": "zilber-admin", |
||||
"version": "1.0.0", |
||||
"description": "致博后台管理系统", |
||||
"author": "ChengYu", |
||||
"license": "MIT", |
||||
"scripts": { |
||||
"dev": "concurrently \"npm run dev --prefix web\" \"npm run start --prefix server\"", |
||||
"preinstall": "npm install --prefix web && npm install --prefix server", |
||||
"build:web": "npm run build:prod --prefix web", |
||||
"build:server": "npm run build --prefix server", |
||||
"build": "npm-run-all build:web build:server", |
||||
"docs:dev": "cd web && vitepress dev docs", |
||||
"docs:build": "cd web && vitepress build docs" |
||||
}, |
||||
"devDependencies": { |
||||
"concurrently": "^9.1.1", |
||||
"npm-run-all": "^4.1.5" |
||||
} |
||||
} |
@ -0,0 +1,4 @@ |
||||
{ |
||||
"presets": ["@babel/preset-env"], |
||||
"plugins": ["@babel/plugin-proposal-optional-chaining"] |
||||
} |
@ -0,0 +1,118 @@ |
||||
# Logs |
||||
logs |
||||
*.log |
||||
npm-debug.log* |
||||
yarn-debug.log* |
||||
yarn-error.log* |
||||
lerna-debug.log* |
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html) |
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json |
||||
|
||||
# Runtime data |
||||
pids |
||||
*.pid |
||||
*.seed |
||||
*.pid.lock |
||||
front-dist |
||||
backend-dist |
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover |
||||
lib-cov |
||||
|
||||
# Coverage directory used by tools like istanbul |
||||
coverage |
||||
*.lcov |
||||
|
||||
# nyc test coverage |
||||
.nyc_output |
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) |
||||
.grunt |
||||
|
||||
# Bower dependency directory (https://bower.io/) |
||||
bower_components |
||||
|
||||
# node-waf configuration |
||||
.lock-wscript |
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html) |
||||
build/Release |
||||
|
||||
# Dependency directories |
||||
node_modules/ |
||||
jspm_packages/ |
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/) |
||||
web_modules/ |
||||
|
||||
# TypeScript cache |
||||
*.tsbuildinfo |
||||
|
||||
# Optional npm cache directory |
||||
.npm |
||||
|
||||
# Optional eslint cache |
||||
.eslintcache |
||||
|
||||
# Microbundle cache |
||||
.rpt2_cache/ |
||||
.rts2_cache_cjs/ |
||||
.rts2_cache_es/ |
||||
.rts2_cache_umd/ |
||||
|
||||
# Optional REPL history |
||||
.node_repl_history |
||||
|
||||
# Output of 'npm pack' |
||||
*.tgz |
||||
|
||||
# Yarn Integrity file |
||||
.yarn-integrity |
||||
|
||||
# dotenv environment variables file |
||||
.env |
||||
.env.test |
||||
|
||||
# parcel-bundler cache (https://parceljs.org/) |
||||
.cache |
||||
.parcel-cache |
||||
|
||||
# Next.js build output |
||||
.next |
||||
out |
||||
|
||||
# Nuxt.js build / generate output |
||||
.nuxt |
||||
dist |
||||
|
||||
# Gatsby files |
||||
.cache/ |
||||
# Comment in the public line in if your project uses Gatsby and not Next.js |
||||
# https://nextjs.org/blog/next-9-1#public-directory-support |
||||
# public |
||||
|
||||
# vuepress build output |
||||
.vuepress/dist |
||||
|
||||
# Serverless directories |
||||
.serverless/ |
||||
|
||||
# FuseBox cache |
||||
.fusebox/ |
||||
|
||||
# DynamoDB Local files |
||||
.dynamodb/ |
||||
|
||||
# TernJS port file |
||||
.tern-port |
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions |
||||
.vscode-test |
||||
|
||||
# yarn v2 |
||||
.yarn/cache |
||||
.yarn/unplugged |
||||
.yarn/build-state.yml |
||||
.yarn/install-state.gz |
||||
.pnp.* |
@ -0,0 +1,89 @@ |
||||
/** |
||||
* Module dependencies. |
||||
*/ |
||||
|
||||
var app = require('../app'); |
||||
var debug = require('debug')('medicine-serve:server'); |
||||
var http = require('http'); |
||||
var config = require('../config'); |
||||
|
||||
/** |
||||
* Get port from environment and store in Express. |
||||
*/ |
||||
|
||||
var port = normalizePort(config.port || process.env.PORT || '3095'); |
||||
app.set('port', port); |
||||
|
||||
/** |
||||
* Create HTTP server. |
||||
*/ |
||||
|
||||
var server = http.createServer(app); |
||||
|
||||
/** |
||||
* Listen on provided port, on all network interfaces. |
||||
*/ |
||||
|
||||
server.listen(port); |
||||
server.on('error', onError); |
||||
server.on('listening', onListening); |
||||
|
||||
/** |
||||
* Normalize a port into a number, string, or false. |
||||
*/ |
||||
|
||||
function normalizePort(val) { |
||||
var port = parseInt(val, 10); |
||||
|
||||
if (isNaN(port)) { |
||||
// named pipe |
||||
return val; |
||||
} |
||||
|
||||
if (port >= 0) { |
||||
// port number |
||||
return port; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Event listener for HTTP server "error" event. |
||||
*/ |
||||
|
||||
function onError(error) { |
||||
if (error.syscall !== 'listen') { |
||||
throw error; |
||||
} |
||||
|
||||
var bind = typeof port === 'string' |
||||
? 'Pipe ' + port |
||||
: 'Port ' + port; |
||||
|
||||
// handle specific listen errors with friendly messages |
||||
switch (error.code) { |
||||
case 'EACCES': |
||||
console.error(bind + ' requires elevated privileges'); |
||||
process.exit(1); |
||||
break; |
||||
case 'EADDRINUSE': |
||||
console.error(bind + ' is already in use'); |
||||
process.exit(1); |
||||
break; |
||||
default: |
||||
throw error; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Event listener for HTTP server "listening" event. |
||||
*/ |
||||
|
||||
function onListening() { |
||||
var addr = server.address(); |
||||
var bind = typeof addr === 'string' |
||||
? 'pipe ' + addr |
||||
: 'port ' + addr.port; |
||||
debug('Listening on ' + bind); |
||||
} |
@ -0,0 +1,17 @@ |
||||
{ |
||||
"name": "server", |
||||
"version": "0.0.0", |
||||
"private": true, |
||||
"scripts": { |
||||
"start": "node ./server" |
||||
}, |
||||
"dependencies": { |
||||
|
||||
}, |
||||
"devDependencies": { |
||||
"axios": "^1.7.9", |
||||
"jade": "~1.11.0", |
||||
"mysql": "^2.18.1" |
||||
} |
||||
} |
||||
|
@ -0,0 +1,30 @@ |
||||
module.exports = { |
||||
env: { |
||||
development: { |
||||
formBaseURL: 'dev-api', |
||||
// 其他开发环境配置
|
||||
}, |
||||
test: { |
||||
baseURL: 'http://test.example.com/api', |
||||
// 其他测试环境配置
|
||||
}, |
||||
production: { |
||||
baseURL: 'http://example.com/api', |
||||
// 其他生产环境配置
|
||||
} |
||||
}, |
||||
database: {//数据库配置
|
||||
host: '39.100.74.100', |
||||
port: '3306', |
||||
user: 'root', |
||||
password: 'root@123456', |
||||
database: 'zilberboot' |
||||
}, |
||||
server: { |
||||
port: 3095, |
||||
ryRedirect: 'http://39.100.74.100:8080' //重定向java服务地址
|
||||
}, |
||||
camunda: { |
||||
base: `http://39.100.90.227:1111` //camunda服务地址
|
||||
}, |
||||
}; |
@ -0,0 +1,50 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" id="Definitions_0001" targetNamespace="http://bpmn.io/schema/bpmn"> |
||||
<bpmn:process id="test_form" name="测试流程带表单" isExecutable="true" camunda:historyTimeToLive="30"> |
||||
<bpmn:startEvent id="Event_0qg2uvh"> |
||||
<bpmn:outgoing>Flow_0j4azlb</bpmn:outgoing> |
||||
</bpmn:startEvent> |
||||
<bpmn:userTask id="Task_1" name="用户任务" camunda:candidateUsers="user1,user2" camunda:formKey="testForm1"> |
||||
</bpmn:userTask> |
||||
|
||||
<bpmn:sequenceFlow id="Flow_0j4azlb" sourceRef="Event_0qg2uvh" targetRef="Task_1" /> |
||||
<bpmn:userTask id="Task_2" name="用户组任务" camunda:candidateGroups="group1,group2" camunda:formKey="testForm2"> |
||||
</bpmn:userTask> |
||||
|
||||
<bpmn:sequenceFlow id="Flow_12flmok" sourceRef="Task_1" targetRef="Task_2" /> |
||||
<bpmn:endEvent id="Event_0ap0ojz"> |
||||
<bpmn:incoming>Flow_1hcelfi</bpmn:incoming> |
||||
</bpmn:endEvent> |
||||
<bpmn:sequenceFlow id="Flow_1hcelfi" sourceRef="Task_2" targetRef="Event_0ap0ojz" /> |
||||
</bpmn:process> |
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1"> |
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1705995903054"> |
||||
<bpmndi:BPMNShape id="Event_0qg2uvh_di" bpmnElement="Event_0qg2uvh"> |
||||
<dc:Bounds x="322" y="182" width="36" height="36" /> |
||||
</bpmndi:BPMNShape> |
||||
<bpmndi:BPMNShape id="Task_1_di" bpmnElement="Task_1"> |
||||
<dc:Bounds x="458" y="140" width="120" height="120" /> |
||||
<bpmndi:BPMNLabel /> |
||||
</bpmndi:BPMNShape> |
||||
<bpmndi:BPMNShape id="Task_2_di" bpmnElement="Task_2"> |
||||
<dc:Bounds x="678" y="140" width="120" height="120" /> |
||||
<bpmndi:BPMNLabel /> |
||||
</bpmndi:BPMNShape> |
||||
<bpmndi:BPMNShape id="Event_0ap0ojz_di" bpmnElement="Event_0ap0ojz"> |
||||
<dc:Bounds x="898" y="182" width="36" height="36" /> |
||||
</bpmndi:BPMNShape> |
||||
<bpmndi:BPMNEdge id="Flow_0j4azlb_di" bpmnElement="Flow_0j4azlb"> |
||||
<di:waypoint x="358" y="200" /> |
||||
<di:waypoint x="458" y="200" /> |
||||
</bpmndi:BPMNEdge> |
||||
<bpmndi:BPMNEdge id="Flow_12flmok_di" bpmnElement="Flow_12flmok"> |
||||
<di:waypoint x="578" y="200" /> |
||||
<di:waypoint x="678" y="200" /> |
||||
</bpmndi:BPMNEdge> |
||||
<bpmndi:BPMNEdge id="Flow_1hcelfi_di" bpmnElement="Flow_1hcelfi"> |
||||
<di:waypoint x="798" y="200" /> |
||||
<di:waypoint x="898" y="200" /> |
||||
</bpmndi:BPMNEdge> |
||||
</bpmndi:BPMNPlane> |
||||
</bpmndi:BPMNDiagram> |
||||
</bpmn:definitions> |
@ -0,0 +1,25 @@ |
||||
let mysql = require('mysql') |
||||
var config = require('../config'); |
||||
|
||||
let pool = mysql.createPool(config.database) |
||||
|
||||
function doSQL (sql, params = []) { |
||||
// console.log('执行sql语句:'+sql);
|
||||
return new Promise((resolve, reject) => { |
||||
pool.getConnection(function (error, connection) { |
||||
if (error) { |
||||
reject(error) |
||||
} else { |
||||
connection.query(sql, params, function (err, data, fields) { |
||||
connection.release() |
||||
resolve({ err, data, fields }) |
||||
}) |
||||
} |
||||
}) |
||||
}) |
||||
} |
||||
let MYSQL = { |
||||
pool, |
||||
doSQL |
||||
} |
||||
module.exports = MYSQL; |
@ -0,0 +1,57 @@ |
||||
{ |
||||
"name": "server", |
||||
"version": "0.0.0", |
||||
"private": true, |
||||
"scripts": { |
||||
"start": "cross-env NODE_ENV=development node ./bin/www", |
||||
"build": "cross-env NODE_ENV=production npx -y webpack" |
||||
}, |
||||
"dependencies": { |
||||
"@alicloud/dm20151123": "1.0.5", |
||||
"@alicloud/openapi-client": "^0.4.4", |
||||
"@alicloud/tea-console": "^1.0.0", |
||||
"@alicloud/tea-typescript": "^1.7.1", |
||||
"@alicloud/tea-util": "^1.4.5", |
||||
"@elastic/elasticsearch": "^8.0.0", |
||||
"archiver": "^5.3.0", |
||||
"axios": "^1.7.9", |
||||
"body-parser": "^1.19.0", |
||||
"cookie-parser": "~1.4.4", |
||||
"date-formatter-cy": "^1.0.0", |
||||
"debug": "~2.6.9", |
||||
"express": "~4.16.1", |
||||
"express-formidable": "^1.2.0", |
||||
"express-http-proxy": "^2.1.1", |
||||
"formidable": "^2.0.1", |
||||
"google-auth-library": "^8.8.0", |
||||
"http-errors": "~1.6.3", |
||||
"http-proxy-middleware": "^3.0.3", |
||||
"jade": "~1.11.0", |
||||
"jszip": "^3.7.1", |
||||
"leven": "^4.0.0", |
||||
"morgan": "~1.9.1", |
||||
"multiparty": "^4.2.2", |
||||
"mysql": "^2.18.1", |
||||
"node-cache": "^5.1.2", |
||||
"node-zip": "^1.1.1", |
||||
"nodemailer": "^6.9.2", |
||||
"request": "^2.88.2", |
||||
"string-similarity": "^4.0.4" |
||||
}, |
||||
"devDependencies": { |
||||
"@babel/core": "^7.26.0", |
||||
"@babel/plugin-proposal-optional-chaining": "^7.21.0", |
||||
"@babel/preset-env": "^7.26.0", |
||||
"babel-loader": "^8.4.1", |
||||
"browserify-zlib": "^0.2.0", |
||||
"clean-webpack-plugin": "^4.0.0", |
||||
"copy-webpack-plugin": "^6.4.1", |
||||
"cross-env": "^7.0.3", |
||||
"path-browserify": "^1.0.1", |
||||
"querystring-es3": "^0.2.1", |
||||
"stream-browserify": "^3.0.0", |
||||
"url": "^0.11.4", |
||||
"webpack": "^4.47.0", |
||||
"webpack-cli": "^3.3.12" |
||||
} |
||||
} |
@ -0,0 +1 @@ |
||||
{"web":{"client_id":"65397196788-vap9su79jhke0036bkes9dso2hto1uk5.apps.googleusercontent.com","project_id":"shuxinxiaozhushou","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"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","javascript_origins":["https://www.zilber.cn"]}} |
@ -0,0 +1,8 @@ |
||||
body { |
||||
padding: 50px; |
||||
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; |
||||
} |
||||
|
||||
a { |
||||
color: #00B7FF; |
||||
} |
@ -0,0 +1,501 @@ |
||||
var express = require('express'); |
||||
var router = express.Router(); |
||||
var doSQL = require('../mysql/index').doSQL; |
||||
const axios = require('axios'); |
||||
const { createProxyMiddleware, responseInterceptor } = require('http-proxy-middleware'); |
||||
const fs = require("fs"); |
||||
var path = require("path"); |
||||
var config = require('../config'); |
||||
|
||||
const baseURL = config.camunda.base; |
||||
|
||||
//1.获取最新流程定义列表
|
||||
router.get('/engine-rest/process-definition', function(request, response) { |
||||
//查询流程总数量
|
||||
axios.get(baseURL + '/engine-rest/process-definition/count?latestVersion=true').then(res=>{ |
||||
let count = res.data.count; |
||||
doRequest(request).then(data=>{ |
||||
response.send({ |
||||
code: 200, |
||||
data: { |
||||
list: data, |
||||
total: count |
||||
} |
||||
}); |
||||
}).catch(err=>{ |
||||
response.send(JSON.stringify({ |
||||
code: 600, |
||||
message: err |
||||
})); |
||||
}) |
||||
}) |
||||
|
||||
}); |
||||
|
||||
//2.获取流程实例列表
|
||||
router.get('/engine-rest/history/process-instance', function(request, response) { |
||||
let processDefinitionKey = request.query.processDefinitionKey; |
||||
let finished = request.query.finished; |
||||
//查询实例总数量
|
||||
axios.get(baseURL + `/engine-rest/history/process-instance/count`,{ |
||||
params: { |
||||
processDefinitionKey, |
||||
finished |
||||
} |
||||
}).then(res=>{ |
||||
let count = res.data.count; |
||||
doRequest(request).then(data=>{ |
||||
response.send({ |
||||
code: 200, |
||||
data: { |
||||
list: data, |
||||
total: count |
||||
} |
||||
}); |
||||
}).catch(err=>{ |
||||
response.send(JSON.stringify({ |
||||
code: 600, |
||||
message: err |
||||
})); |
||||
}) |
||||
}) |
||||
|
||||
}); |
||||
|
||||
//3.获取流程实例任务列表
|
||||
router.get('/engine-rest/history/task', function(request, response) { |
||||
let processInstanceId = request.query.processInstanceId; |
||||
//查询实例任务总数量
|
||||
axios.get(baseURL + `/engine-rest/history/task/count?processInstanceId=${processInstanceId}`).then(res=>{ |
||||
let count = res.data.count; |
||||
doRequest(request).then(data=>{ |
||||
//如果任务已完成,获取任务评论
|
||||
let promiseArr = []; |
||||
data.forEach(item=> { |
||||
promiseArr.push(axios.get(baseURL + `/engine-rest/task/${item.id}/comment`)) |
||||
}) |
||||
Promise.all(promiseArr).then(res=>{ |
||||
res.forEach((item,index)=> { |
||||
data[index].comment = item.data; |
||||
}) |
||||
response.send({ |
||||
code: 200, |
||||
data: { |
||||
list: data, |
||||
total: count |
||||
} |
||||
}); |
||||
}) |
||||
}).catch(err=>{ |
||||
response.send(JSON.stringify({ |
||||
code: 600, |
||||
message: err |
||||
})); |
||||
}) |
||||
}) |
||||
|
||||
}); |
||||
|
||||
//4.添加候选人
|
||||
router.post('/engine-rest/task/:taskId/identity-links', function(request, response) { |
||||
doRequest(request).then(data=>{ |
||||
response.send({ |
||||
code: 200 |
||||
}); |
||||
}).catch(err=>{ |
||||
response.send(JSON.stringify({ |
||||
code: 600, |
||||
message: err |
||||
})); |
||||
}) |
||||
}); |
||||
|
||||
//5.移除候选人
|
||||
router.post('/engine-rest/task/:taskId/identity-links/delete', function(request, response) { |
||||
doRequest(request).then(data=>{ |
||||
response.send({ |
||||
code: 200 |
||||
}); |
||||
}).catch(err=>{ |
||||
response.send(JSON.stringify({ |
||||
code: 600, |
||||
message: err |
||||
})); |
||||
}) |
||||
}); |
||||
|
||||
function getProcessInstanceDetail(taskInfo,id) { |
||||
return new Promise((resolve, reject) => { |
||||
const query = ` |
||||
SELECT wi.form_id, wi.process_key, wi.form_values, wi.process_instance_id, wi.status, wf.form_name, wf.form_desc, wf.form_path |
||||
FROM workflow_instance wi |
||||
LEFT JOIN workflow_form wf ON wf.id = wi.form_id |
||||
WHERE process_instance_id = ? |
||||
`;
|
||||
const params = [id]; |
||||
doSQL(query, params).then(res=>{ |
||||
let data = res.data[0]; |
||||
axios.get(baseURL + `/engine-rest/process-definition/${taskInfo.processDefinitionId}`) |
||||
.then(res=>{ |
||||
let processInfo = res.data; |
||||
if(data){ |
||||
try { |
||||
let form = require(path.join(__dirname, '../' + data.form_path)); |
||||
resolve({ |
||||
processName: processInfo.name, |
||||
...taskInfo, |
||||
...data, |
||||
form: form.formFields |
||||
}) |
||||
} catch (error) { |
||||
resolve({ |
||||
processName: processInfo.name, |
||||
...taskInfo, |
||||
...data |
||||
}) |
||||
} |
||||
|
||||
// fs.readFile(path.join(__dirname, '../' + data.form_path), 'utf-8', function(err, form) {
|
||||
// if (err) {
|
||||
// resolve({
|
||||
// processName: processInfo.name,
|
||||
// ...taskInfo,
|
||||
// ...data
|
||||
// })
|
||||
// } else {
|
||||
// resolve({
|
||||
// processName: processInfo.name,
|
||||
// ...taskInfo,
|
||||
// ...data,
|
||||
// form: JSON.parse(form)
|
||||
// })
|
||||
// }
|
||||
// });
|
||||
} else { |
||||
resolve({ |
||||
processName: processInfo.name, |
||||
...taskInfo |
||||
}) |
||||
} |
||||
}) |
||||
.catch(error => { |
||||
// 处理 axios 错误
|
||||
resolve({ |
||||
...taskInfo |
||||
}) |
||||
}); |
||||
}).catch(error => { |
||||
// 处理 doSQL 错误
|
||||
reject(error); |
||||
}); |
||||
}); |
||||
} |
||||
//6.查询候选任务
|
||||
router.get('/engine-rest/task', async function(request, response) { |
||||
let candidateUser = request.query.candidateUser; |
||||
let assignee = request.query.assignee; |
||||
let candidateGroup = request.query.candidateGroup; |
||||
try { |
||||
let count = 0; |
||||
let primiseArr = []; |
||||
if(!candidateUser && !assignee && !candidateGroup){ |
||||
res = await axios.get(baseURL + '/engine-rest/task/count'); |
||||
count = res.data.count; |
||||
const data = await doRequest(request); |
||||
// 按照 created 字段倒序排序
|
||||
data.sort((a, b) => new Date(b.created) - new Date(a.created)); |
||||
data.forEach(item => { |
||||
primiseArr.push(getProcessInstanceDetail(item, item.processInstanceId)); |
||||
}); |
||||
}else{ |
||||
// 如果传入了参数,分别查询
|
||||
let requests = []; |
||||
if (candidateUser) { |
||||
requests.push(axios.get(baseURL + '/engine-rest/task', { |
||||
params: { candidateUser: candidateUser } |
||||
})); |
||||
} |
||||
if (assignee) { |
||||
requests.push(axios.get(baseURL + '/engine-rest/task', { |
||||
params: { assignee: assignee } |
||||
})); |
||||
} |
||||
if (candidateGroup) { |
||||
requests.push(axios.get(baseURL + '/engine-rest/task', { |
||||
params: { candidateGroup: candidateGroup } |
||||
})); |
||||
} |
||||
|
||||
// 等待所有请求完成
|
||||
const responses = await Promise.all(requests); |
||||
|
||||
// 合并所有请求的结果
|
||||
let tasks = []; |
||||
responses.forEach(response => { |
||||
tasks = tasks.concat(response.data); |
||||
}); |
||||
|
||||
// 去重
|
||||
const uniqueTasks = tasks.filter((task, index, self) => |
||||
index === self.findIndex((t) => ( |
||||
t.id === task.id |
||||
)) |
||||
); |
||||
// 按照 created 字段倒序排序
|
||||
uniqueTasks.sort((a, b) => new Date(b.created) - new Date(a.created)); |
||||
|
||||
// 分页处理
|
||||
let firstResult = request.query.firstResult || 0; |
||||
let maxResults = request.query.maxResults || 10; |
||||
const paginatedTasks = uniqueTasks.slice(firstResult, firstResult + maxResults); |
||||
|
||||
// 获取任务总数
|
||||
count = uniqueTasks.length; |
||||
|
||||
// 获取任务详情
|
||||
paginatedTasks.forEach(item => { |
||||
primiseArr.push(getProcessInstanceDetail(item, item.processInstanceId)); |
||||
}); |
||||
} |
||||
|
||||
const results = await Promise.all(primiseArr); |
||||
response.send({ |
||||
code: 200, |
||||
data: { |
||||
list: results, |
||||
total: count |
||||
} |
||||
}); |
||||
} catch (err) { |
||||
console.error('Error:', err); |
||||
response.send({ |
||||
code: 600, |
||||
message: err.message || '处理请求时发生错误' |
||||
}); |
||||
} |
||||
}); |
||||
|
||||
//7.领取任务
|
||||
router.post('/engine-rest/task/:taskId/claim', function(request, response) { |
||||
doRequest(request).then(data=>{ |
||||
response.send({ |
||||
code: 200 |
||||
}); |
||||
}).catch(err=>{ |
||||
response.send(JSON.stringify({ |
||||
code: 600, |
||||
message: err |
||||
})); |
||||
}) |
||||
}); |
||||
//8.取消执行人
|
||||
router.post('/engine-rest/task/:taskId/unclaim', function(request, response) { |
||||
doRequest(request).then(data=>{ |
||||
response.send({ |
||||
code: 200 |
||||
}); |
||||
}).catch(err=>{ |
||||
response.send(JSON.stringify({ |
||||
code: 600, |
||||
message: err |
||||
})); |
||||
}) |
||||
}); |
||||
//9.执行任务
|
||||
router.post('/engine-rest/task/:taskId/complete', function(request, response) { |
||||
doRequest(request).then(data=>{ |
||||
response.send({ |
||||
code: 200 |
||||
}); |
||||
}).catch(err=>{ |
||||
response.send(JSON.stringify({ |
||||
code: 600, |
||||
message: err |
||||
})); |
||||
}) |
||||
}); |
||||
//10.设置任务评论
|
||||
router.post('/engine-rest/task/:taskId/comment/create', function(request, response) { |
||||
doRequest(request).then(data=>{ |
||||
response.send({ |
||||
code: 200 |
||||
}); |
||||
}).catch(err=>{ |
||||
response.send(JSON.stringify({ |
||||
code: 600, |
||||
message: err |
||||
})); |
||||
}) |
||||
}); |
||||
|
||||
/** |
||||
* 创建自定义流程实例 |
||||
* @description 本系统内生成流程实例,并启动camunda流程--------标准需要开事务 |
||||
* @ |
||||
*/ |
||||
router.post('/start', function(request, response) { |
||||
//1. 启动camunda流程
|
||||
let processKey = request.body.processKey; |
||||
let createUser = request.body.createUser; |
||||
//1.本系统内生成流程实例
|
||||
let formId = request.body.formId; |
||||
let formValues = request.body.formValues; |
||||
const query = ` |
||||
INSERT INTO workflow_instance (form_id, process_key, process_instance_id, form_values, status, create_user) |
||||
VALUES (?, ?, NULL, ?, 1, ?) |
||||
`;
|
||||
const params = [formId, processKey, formValues, createUser]; |
||||
|
||||
doSQL(query,params).then(res=>{ |
||||
if(!res.error){ |
||||
//获取刚刚插入的id
|
||||
const insertId = res.data.insertId;
|
||||
axios.post(baseURL + `/engine-rest/process-definition/key/${processKey}/start`, { |
||||
businessKey: insertId |
||||
}).then(res=>{ |
||||
let processInstanceId = res.data.id; |
||||
if( processInstanceId ){ |
||||
//2. 创建本系统内的流程实例包含form_id,process_instance_id,status
|
||||
const query = `UPDATE workflow_instance SET process_instance_id = ? WHERE id = ?`; |
||||
const params = [processInstanceId, insertId]; |
||||
|
||||
doSQL(query, params).then(res=>{ |
||||
if(!res.error){ |
||||
response.send({ |
||||
code: 200, |
||||
message: '启动流程成功' |
||||
}); |
||||
}else{ |
||||
const query = `delete from workflow_instance where id = ?`; |
||||
const params = [insertId]; |
||||
doSQL(query, params).then(res=>{ |
||||
response.send({ |
||||
code: 600, |
||||
message: '启动流程失败' |
||||
}); |
||||
}) |
||||
} |
||||
}) |
||||
}else { |
||||
response.send({ |
||||
code: 600, |
||||
message: '启动流程失败' |
||||
}); |
||||
} |
||||
}) |
||||
}else{ |
||||
response.send({ |
||||
code: 600, |
||||
message: '启动流程失败' |
||||
}); |
||||
} |
||||
}) |
||||
}); |
||||
|
||||
|
||||
router.use('/', createProxyMiddleware({ |
||||
target: baseURL, |
||||
changeOrigin: true, // 确保请求头正确
|
||||
pathRewrite: { |
||||
'^/process': '', // 去掉路径前缀
|
||||
}, |
||||
timeout: 60000, // 设置超时为60秒
|
||||
selfHandleResponse: true, |
||||
on: { |
||||
// proxyReq: (proxyReq, req, res) => {
|
||||
// console.log('代理请求发送到目标服务器:', proxyReq.path);
|
||||
// console.log('请求头:', proxyReq.getHeaders());
|
||||
// },
|
||||
proxyRes: responseInterceptor(async (responseBuffer, proxyRes, req, res) => { |
||||
const response = responseBuffer.toString('utf8'); // convert buffer to string
|
||||
let originalData; |
||||
try { |
||||
originalData = response ? JSON.parse(response) : {}; // parse JSON
|
||||
} catch (error) { |
||||
originalData = { |
||||
code: 500, |
||||
message: 'Error parsing response', |
||||
data: response |
||||
}; |
||||
} |
||||
|
||||
//异常特殊处理
|
||||
if(originalData?.message?.includes('ENGINE-03076')){ |
||||
return JSON.stringify({ |
||||
code: 503, |
||||
msg: '流程存在启用的实例,无法删除!' |
||||
}); |
||||
}else{ |
||||
let statusCode = proxyRes.statusCode == 204 ? 200 : proxyRes.statusCode; |
||||
const wrappedData = { |
||||
code: originalData.code || statusCode, // 包含 HTTP 状态码
|
||||
data: originalData.data || originalData, // 返回的实际数据
|
||||
timestamp: new Date().toISOString(), // 添加时间戳
|
||||
}; |
||||
return JSON.stringify(wrappedData); |
||||
} |
||||
}), |
||||
error: (err, req, res) => { |
||||
console.error('Proxy error:', err); |
||||
res.status(500).json({ |
||||
code: 500, |
||||
message: 'Proxy request failed', |
||||
error: err.message |
||||
}); |
||||
} |
||||
}, |
||||
})); |
||||
|
||||
|
||||
// function proxyDataResolver(fn) {
|
||||
// return proxy(baseURL + '', {
|
||||
// proxyReqPathResolver: function (req) {
|
||||
// // 移除请求路径中的开头 /process
|
||||
// return req.url.replace(/^\/process/, '');
|
||||
// },
|
||||
// proxyReqOptDecorator: function(proxyReqOpts, req) {
|
||||
// // 确保请求头中包含正确的 Content-Type
|
||||
// if (req.headers['content-type']) {
|
||||
// proxyReqOpts.headers['Content-Type'] = req.headers['content-type'];
|
||||
// }
|
||||
// return proxyReqOpts;
|
||||
// },
|
||||
// userResDecorator: function (proxyRes, proxyResData, req, res) {
|
||||
// try {
|
||||
// // 处理返回的结果
|
||||
// const originalData = JSON.parse(proxyResData.toString('utf8')); // 解析 JSON
|
||||
// const wrappedData = {
|
||||
// code: originalData.code || proxyRes.statusCode, // 包含 HTTP 状态码
|
||||
// data: fn ? fn(originalData) : (originalData.data || originalData), // 返回的实际数据
|
||||
// timestamp: new Date().toISOString(), // 添加时间戳
|
||||
// };
|
||||
// return JSON.stringify(wrappedData); // 转换为字符串返回
|
||||
// } catch (error) {
|
||||
// console.error('Error processing response:', error);
|
||||
// return proxyResData; // 如果解析失败,直接返回原始数据
|
||||
// }
|
||||
// },
|
||||
// })
|
||||
// }
|
||||
|
||||
function doRequest(req) { |
||||
return new Promise((resolve, reject) => { |
||||
// 构建请求选项
|
||||
const url = baseURL + `${req.url.replace(/^\/process/, '')}`; |
||||
axios({ |
||||
url: url, |
||||
method: req.method, |
||||
data: req.body, |
||||
}) |
||||
.then(response => { |
||||
resolve(response.data,response) |
||||
}) |
||||
.catch(error => { |
||||
reject(error) |
||||
}); |
||||
|
||||
}); |
||||
} |
||||
|
||||
|
||||
module.exports = router; |
@ -0,0 +1,38 @@ |
||||
|
||||
const https = require('https'); |
||||
let accessToken = null; |
||||
function requestAccessToken(){ |
||||
// wxb9db86cc1e1b8ce7
|
||||
// 7b693cd53613d50b2fa6a1faaa39b658
|
||||
return new Promise((resolve,reject)=>{ |
||||
https.get('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wxb9db86cc1e1b8ce7&secret=7b693cd53613d50b2fa6a1faaa39b658',function(res){ |
||||
var html = ''; |
||||
res.on('data',function(data){ |
||||
html += data; |
||||
}); |
||||
res.on('end',function(){ |
||||
resolve(JSON.parse(html)); |
||||
}); |
||||
}); |
||||
}) |
||||
} |
||||
|
||||
function init(){ |
||||
requestAccessToken().then((res)=>{ |
||||
accessToken = res.access_token; |
||||
console.log('accessToken',accessToken); |
||||
setTimeout(()=>{ |
||||
init(); |
||||
},(res.expires_in-200)*1000) |
||||
}) |
||||
} |
||||
|
||||
function getAccessToken(){ |
||||
return accessToken; |
||||
} |
||||
|
||||
|
||||
module.exports = { |
||||
init, |
||||
getAccessToken |
||||
}; |
@ -0,0 +1,118 @@ |
||||
"use strict"; |
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { |
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } |
||||
return new (P || (P = Promise))(function (resolve, reject) { |
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } |
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } |
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } |
||||
step((generator = generator.apply(thisArg, _arguments || [])).next()); |
||||
}); |
||||
}; |
||||
var __generator = (this && this.__generator) || function (thisArg, body) { |
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; |
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; |
||||
function verb(n) { return function (v) { return step([n, v]); }; } |
||||
function step(op) { |
||||
if (f) throw new TypeError("Generator is already executing."); |
||||
while (g && (g = 0, op[0] && (_ = 0)), _) try { |
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; |
||||
if (y = 0, t) op = [op[0] & 2, t.value]; |
||||
switch (op[0]) { |
||||
case 0: case 1: t = op; break; |
||||
case 4: _.label++; return { value: op[1], done: false }; |
||||
case 5: _.label++; y = op[1]; op = [0]; continue; |
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue; |
||||
default: |
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } |
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } |
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } |
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } |
||||
if (t[2]) _.ops.pop(); |
||||
_.trys.pop(); continue; |
||||
} |
||||
op = body.call(thisArg, _); |
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } |
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; |
||||
} |
||||
}; |
||||
Object.defineProperty(exports, "__esModule", { value: true }); |
||||
// This file is auto-generated, don't edit it
|
||||
// 依赖的模块可通过下载工程中的模块依赖文件或右上角的获取 SDK 依赖信息查看
|
||||
var dm20151123_1 = require("@alicloud/dm20151123"), $Dm20151123 = dm20151123_1; |
||||
var $OpenApi = require("@alicloud/openapi-client"); |
||||
var tea_console_1 = require("@alicloud/tea-console"); |
||||
var tea_util_1 = require("@alicloud/tea-util"), $Util = tea_util_1; |
||||
var Client = /** @class */ (function () { |
||||
function Client() { |
||||
} |
||||
/** |
||||
* 使用AK&SK初始化账号Client |
||||
* @param accessKeyId |
||||
* @param accessKeySecret |
||||
* @return Client |
||||
* @throws Exception |
||||
*/ |
||||
Client.createClient = function (accessKeyId, accessKeySecret) { |
||||
var config = new $OpenApi.Config({ |
||||
// 必填,您的 AccessKey ID
|
||||
accessKeyId: accessKeyId, |
||||
// 必填,您的 AccessKey Secret
|
||||
accessKeySecret: accessKeySecret, |
||||
}); |
||||
// 访问的域名
|
||||
config.endpoint = "dm.aliyuncs.com"; |
||||
return new dm20151123_1.default(config); |
||||
}; |
||||
/** |
||||
* 使用STS鉴权方式初始化账号Client,推荐此方式。 |
||||
* @param accessKeyId |
||||
* @param accessKeySecret |
||||
* @param securityToken |
||||
* @return Client |
||||
* @throws Exception |
||||
*/ |
||||
Client.createClientWithSTS = function (accessKeyId, accessKeySecret, securityToken) { |
||||
var config = new $OpenApi.Config({ |
||||
// 必填,您的 AccessKey ID
|
||||
accessKeyId: accessKeyId, |
||||
// 必填,您的 AccessKey Secret
|
||||
accessKeySecret: accessKeySecret, |
||||
// 必填,您的 Security Token
|
||||
securityToken: securityToken, |
||||
// 必填,表明使用 STS 方式
|
||||
type: "sts", |
||||
}); |
||||
// 访问的域名
|
||||
config.endpoint = "dm.aliyuncs.com"; |
||||
return new dm20151123_1.default(config); |
||||
}; |
||||
Client.main = function (type, content) { |
||||
return __awaiter(this, void 0, void 0, function () { |
||||
var client, singleSendMailRequest, runtime, resp; |
||||
return __generator(this, function (_a) { |
||||
switch (_a.label) { |
||||
case 0: |
||||
client = Client.createClient("LTAI5tEzKa1MzVZ1QAQPayJX", "77mXtGCkWYPWLyCBc0fyOQMLYjn7Dj"); |
||||
singleSendMailRequest = new $Dm20151123.SingleSendMailRequest({ |
||||
accountName: "sxxzs@email.zilber.cn", |
||||
addressType: 1, |
||||
replyToAddress: false, |
||||
toAddress: "529315546@qq.com", |
||||
// toAddress: "liujunhong@zilber.cn",
|
||||
subject: type, |
||||
textBody: content, |
||||
}); |
||||
runtime = new $Util.RuntimeOptions({}); |
||||
return [4 /*yield*/, client.singleSendMailWithOptions(singleSendMailRequest, runtime)]; |
||||
case 1: |
||||
resp = _a.sent(); |
||||
tea_console_1.default.log(tea_util_1.default.toJSONString(resp)); |
||||
return [2 /*return*/]; |
||||
} |
||||
}); |
||||
}); |
||||
}; |
||||
return Client; |
||||
}()); |
||||
exports.default = Client; |
||||
// Client.main(process.argv.slice(2));
|
@ -0,0 +1,74 @@ |
||||
// This file is auto-generated, don't edit it
|
||||
// 依赖的模块可通过下载工程中的模块依赖文件或右上角的获取 SDK 依赖信息查看
|
||||
import Dm20151123, * as $Dm20151123 from '@alicloud/dm20151123'; |
||||
import OpenApi, * as $OpenApi from '@alicloud/openapi-client'; |
||||
import Console from '@alicloud/tea-console'; |
||||
import Util, * as $Util from '@alicloud/tea-util'; |
||||
import * as $tea from '@alicloud/tea-typescript'; |
||||
|
||||
|
||||
export default class Client { |
||||
|
||||
/** |
||||
* 使用AK&SK初始化账号Client |
||||
* @param accessKeyId |
||||
* @param accessKeySecret |
||||
* @return Client |
||||
* @throws Exception |
||||
*/ |
||||
static createClient(accessKeyId: string, accessKeySecret: string): Dm20151123 { |
||||
let config = new $OpenApi.Config({ |
||||
// 必填,您的 AccessKey ID
|
||||
accessKeyId: accessKeyId, |
||||
// 必填,您的 AccessKey Secret
|
||||
accessKeySecret: accessKeySecret, |
||||
}); |
||||
// 访问的域名
|
||||
config.endpoint = `dm.aliyuncs.com`; |
||||
return new Dm20151123(config); |
||||
} |
||||
|
||||
/** |
||||
* 使用STS鉴权方式初始化账号Client,推荐此方式。 |
||||
* @param accessKeyId |
||||
* @param accessKeySecret |
||||
* @param securityToken |
||||
* @return Client |
||||
* @throws Exception |
||||
*/ |
||||
static createClientWithSTS(accessKeyId: string, accessKeySecret: string, securityToken: string): Dm20151123 { |
||||
let config = new $OpenApi.Config({ |
||||
// 必填,您的 AccessKey ID
|
||||
accessKeyId: accessKeyId, |
||||
// 必填,您的 AccessKey Secret
|
||||
accessKeySecret: accessKeySecret, |
||||
// 必填,您的 Security Token
|
||||
securityToken: securityToken, |
||||
// 必填,表明使用 STS 方式
|
||||
type: "sts", |
||||
}); |
||||
// 访问的域名
|
||||
config.endpoint = `dm.aliyuncs.com`; |
||||
return new Dm20151123(config); |
||||
} |
||||
|
||||
static async main(type:String,content:String): Promise<void> { |
||||
// 工程代码泄露可能会导致AccessKey泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378664.html
|
||||
let client = Client.createClient("LTAI5tEzKa1MzVZ1QAQPayJX", "77mXtGCkWYPWLyCBc0fyOQMLYjn7Dj"); |
||||
let singleSendMailRequest = new $Dm20151123.SingleSendMailRequest({ |
||||
accountName: "sxxzs@email.zilber.cn", |
||||
addressType: 1, |
||||
replyToAddress: false, |
||||
toAddress: "529315546@qq.com", |
||||
// toAddress: "liujunhong@zilber.cn",
|
||||
subject: type, |
||||
textBody: content, |
||||
}); |
||||
let runtime = new $Util.RuntimeOptions({ }); |
||||
let resp = await client.singleSendMailWithOptions(singleSendMailRequest, runtime); |
||||
Console.log(Util.toJSONString(resp)); |
||||
} |
||||
|
||||
} |
||||
|
||||
// Client.main(process.argv.slice(2));
|
@ -0,0 +1,334 @@ |
||||
var express = require('express'); |
||||
var router = express.Router(); |
||||
var doSQL = require('../mysql/index').doSQL; |
||||
const fs = require("fs"); |
||||
var path = require("path"); |
||||
|
||||
router.get('/', function(request, response, next) { |
||||
let page = request.query.page; |
||||
let limit = request.query.limit; |
||||
let formName = request.query.formName; |
||||
let sql = ` |
||||
select id,form_name formName,original_type originalType,form_desc formDesc,form_path formPath,DATE_FORMAT(workflow_form.create_time,'%Y-%m-%d') createTime,create_user createUser,sys_user.nick_name createUserName |
||||
from workflow_form |
||||
left join sys_user on workflow_form.create_user = sys_user.user_id |
||||
`;
|
||||
const params = []; |
||||
if (formName) { |
||||
sql += ` where form_name like ?`; |
||||
params.push(`%${formName}%`); |
||||
} |
||||
if (page) { |
||||
sql += ` limit ?, ?`; |
||||
params.push(+(page - 1) * limit, +limit); |
||||
} |
||||
getCount(sql, params).then(count => { |
||||
doSQL(sql, params).then(res => { |
||||
if(!res.error){ |
||||
response.send(JSON.stringify({ |
||||
code: 200, |
||||
data: { |
||||
list: res.data, |
||||
count: count |
||||
} |
||||
})); |
||||
|
||||
}else{ |
||||
response.send(JSON.stringify({ |
||||
code: 600, |
||||
message: res.error |
||||
})); |
||||
} |
||||
}) |
||||
}) |
||||
|
||||
}); |
||||
|
||||
// router.get('/fields', function(request, response, next) {
|
||||
// let formPath = request.query.path;
|
||||
// //读取文件
|
||||
// try {
|
||||
// let form = require(path.join(__dirname, '../' + formPath));
|
||||
// response.send(JSON.stringify({
|
||||
// code: 200,
|
||||
// data: form.formFields
|
||||
// }));
|
||||
// } catch (error) {
|
||||
// response.send(JSON.stringify({
|
||||
// code: 500,
|
||||
// msg: `未找到文件${formPath}`
|
||||
// }));
|
||||
// }
|
||||
// // fs.readFile( path.join(__dirname, '../' + formPath), 'utf-8', function(err, data) {
|
||||
// // if (err) {
|
||||
// // response.send(JSON.stringify({
|
||||
// // code: 500,
|
||||
// // msg: `未找到文件${formPath}`
|
||||
// // }));
|
||||
// // } else {
|
||||
// // let json = JSON.stringify(eval(data));
|
||||
// // response.send(JSON.stringify({
|
||||
// // code: 200,
|
||||
// // data: json
|
||||
// // }));
|
||||
// // }
|
||||
// // });
|
||||
|
||||
// });
|
||||
|
||||
router.get('/:id', function(request, response, next) { |
||||
let id = request.params.id; |
||||
let sql = ` |
||||
select id,form_name formName,original_type originalType,form_desc formDesc,form_path formPath,DATE_FORMAT(workflow_form.create_time,'%Y-%m-%d') createTime,create_user createUser,sys_user.nick_name createUserName |
||||
from workflow_form |
||||
left join sys_user on workflow_form.create_user = sys_user.user_id |
||||
where id = ? |
||||
`;
|
||||
const params = [id]; |
||||
doSQL(sql, params).then(res=>{ |
||||
if(!res.error){ |
||||
let data = res.data[0] || {}; |
||||
let formPath = data.formPath; |
||||
//读取文件
|
||||
const fullPath = path.join(__dirname, '../' + formPath); |
||||
fs.readFile(fullPath, 'utf8',function(err,res){ |
||||
if (err) { |
||||
data.content = []; |
||||
} else { |
||||
data.content = JSON.parse(res); |
||||
} |
||||
response.send(JSON.stringify({ |
||||
code: 200, |
||||
data |
||||
})); |
||||
}); |
||||
}else{ |
||||
response.send(JSON.stringify({ |
||||
code: 600, |
||||
message: res.error |
||||
})); |
||||
} |
||||
}) |
||||
}); |
||||
|
||||
|
||||
function addForm(fileName, content){ |
||||
return new Promise((resolve, reject) => { |
||||
//检测文件是否存在
|
||||
let isExist = fs.existsSync(path.join(__dirname, '../form', fileName + '.js')); |
||||
if(isExist){ |
||||
reject('文件已存在'); |
||||
}else{ |
||||
fileName = fileName.indexOf('.js') > -1 ? fileName : fileName + '.js'; |
||||
const filePath = path.join(__dirname, '../form', fileName ); |
||||
|
||||
fs.writeFile(filePath, content, 'utf8', (err) => { |
||||
if (err) { |
||||
reject(err); |
||||
}else{ |
||||
resolve(); |
||||
} |
||||
}); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
|
||||
router.post('/', async function(request, response, next) { |
||||
let { formName, formDesc, userId,formPath = '',fileName,content,type = 1 } = request.body; |
||||
fileName = fileName || formName; |
||||
let errMsg = ''; |
||||
if(!userId){ |
||||
errMsg = '创建人不能为空' |
||||
}else if(!formName){ |
||||
errMsg = '表单名称不能为空' |
||||
}else if(!formPath && ( !fileName || !content)){ |
||||
errMsg = '文件名和表单内容不能为空' |
||||
} |
||||
if(errMsg){ |
||||
response.send(JSON.stringify({ |
||||
code: 600, |
||||
message: errMsg |
||||
})); |
||||
return; |
||||
} |
||||
|
||||
if( !formPath ){ |
||||
type = 2; |
||||
try { |
||||
await addForm(fileName, content) |
||||
formPath = `/form/${fileName}.js`; |
||||
} catch (err) { |
||||
response.send(JSON.stringify({ |
||||
code: 600, |
||||
message: err |
||||
})); |
||||
return; |
||||
} |
||||
} |
||||
let sql = ` |
||||
insert into workflow_form (form_name, form_desc, form_path, create_time, create_user, original_type) |
||||
values (?, ?, ?, now(), ?, ?) |
||||
`;
|
||||
const params = [formName, formDesc, formPath, userId,type]; |
||||
|
||||
doSQL(sql, params).then(res=>{ |
||||
if(!res.error){ |
||||
response.send(JSON.stringify({ |
||||
code: 200, |
||||
message: '新增成功' |
||||
})); |
||||
}else{ |
||||
response.send(JSON.stringify({ |
||||
code: 600, |
||||
message: res.error |
||||
})); |
||||
} |
||||
}) |
||||
}); |
||||
|
||||
router.delete('/:id', function(request, response, next) { |
||||
let id = request.params.id; |
||||
let sql = `delete from workflow_form where id in (?)`; |
||||
const params = [id]; |
||||
doSQL(sql, params).then(res=>{ |
||||
if(!res.error){ |
||||
response.send(JSON.stringify({ |
||||
code: 200, |
||||
message: '删除成功' |
||||
})); |
||||
}else{ |
||||
response.send(JSON.stringify({ |
||||
code: 600, |
||||
message: res.error |
||||
})); |
||||
} |
||||
}) |
||||
}); |
||||
|
||||
// router.put('/', function(request, response, next) {
|
||||
// let { id, formName, formDesc, formPath, userId,content } = request.body;
|
||||
// let sql = `
|
||||
// update workflow_form
|
||||
// set form_name = ?, form_desc = ?, form_path = ?
|
||||
// where id = ?
|
||||
// `;
|
||||
// const params = [formName, formDesc, formPath, id];
|
||||
// doSQL(sql, params).then(res => {
|
||||
// if(!res.error) {
|
||||
// response.send(JSON.stringify({
|
||||
// code: 200,
|
||||
// message: '修改成功'
|
||||
// }));
|
||||
// } else {
|
||||
// response.send(JSON.stringify({
|
||||
// code: 600,
|
||||
// message: res.error
|
||||
// }));
|
||||
// }
|
||||
// })
|
||||
// });
|
||||
router.put('/', async function(request, response, next) { |
||||
let { id, formName, formDesc, userId, content ,formPath} = request.body; |
||||
let errMsg = ''; |
||||
if (!id) { |
||||
errMsg = 'ID 不能为空'; |
||||
} else if (!userId) { |
||||
errMsg = '修改人不能为空'; |
||||
} else if (!formName) { |
||||
errMsg = '表单名称不能为空'; |
||||
} |
||||
if (errMsg) { |
||||
return response.status(400).send({ |
||||
code: 400, |
||||
message: errMsg |
||||
}); |
||||
} |
||||
|
||||
try { |
||||
// 根据 id 查询原数据
|
||||
const originalData = await doSQL('SELECT * FROM workflow_form WHERE id = ?', [id]); |
||||
if (originalData.data.length === 0) { |
||||
return response.status(404).send({ |
||||
code: 404, |
||||
message: '未找到对应的表单' |
||||
}); |
||||
} |
||||
const originalFormPath = originalData.data[0].form_path; |
||||
let newFormPath; |
||||
if( content && content.length > 0){ |
||||
newFormPath = `/form/${formName}.js`; |
||||
if (originalFormPath !== newFormPath) { |
||||
// 检查新文件是否存在
|
||||
const newFilePath = path.join(__dirname, '../', newFormPath); |
||||
if (fs.existsSync(newFilePath)) { |
||||
return response.status(400).send({ |
||||
code: 400, |
||||
message: '表单名已存在' |
||||
}); |
||||
} |
||||
} |
||||
// 删除原文件
|
||||
if (originalFormPath) { |
||||
const filePath = path.join(__dirname, '../', originalFormPath); |
||||
fs.unlinkSync(filePath); |
||||
} |
||||
try { |
||||
await addForm(formName, content) |
||||
} catch (err) { |
||||
response.send(JSON.stringify({ |
||||
code: 600, |
||||
message: err |
||||
})); |
||||
return; |
||||
} |
||||
}else{ |
||||
newFormPath = formPath || originalFormPath; |
||||
} |
||||
// 更新数据库中的记录
|
||||
const sql = ` |
||||
update workflow_form
|
||||
set form_name = ?, form_desc = ?, form_path = ?, create_time = ?, create_user = ? |
||||
where id = ? |
||||
`;
|
||||
const params = [formName, formDesc, newFormPath, new Date(), userId, id]; |
||||
const res = await doSQL(sql, params); |
||||
|
||||
if (!res.error) { |
||||
response.send({ |
||||
code: 200, |
||||
message: '修改成功' |
||||
}); |
||||
} else { |
||||
response.send({ |
||||
code: 600, |
||||
message: res.error |
||||
}); |
||||
} |
||||
} catch (error) { |
||||
console.error('Failed to update form:', error); |
||||
response.status(500).send({ |
||||
code: 500, |
||||
message: 'Failed to update form' |
||||
}); |
||||
} |
||||
}); |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function getCount(sql, params) { |
||||
let countSql = `select count(1) count from (${sql.split('limit')[0]}) a`; |
||||
return new Promise((resolve, reject) => { |
||||
doSQL(countSql, params).then(res => { |
||||
resolve(res.data[0].count); |
||||
}).catch(err => { |
||||
reject(err); |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
module.exports = router; |
@ -0,0 +1,6 @@ |
||||
extends layout |
||||
|
||||
block content |
||||
h1= message |
||||
h2= error.status |
||||
pre #{error.stack} |
@ -0,0 +1,5 @@ |
||||
extends layout |
||||
|
||||
block content |
||||
h1= title |
||||
p Welcome to #{title} |
@ -0,0 +1,7 @@ |
||||
doctype html |
||||
html |
||||
head |
||||
title= title |
||||
link(rel='stylesheet', href='/stylesheets/style.css') |
||||
body |
||||
block content |
@ -0,0 +1,60 @@ |
||||
const path = require('path'); |
||||
const { CleanWebpackPlugin } = require('clean-webpack-plugin'); |
||||
const CopyWebpackPlugin = require('copy-webpack-plugin'); |
||||
|
||||
module.exports = { |
||||
// 入口文件,指定项目的起点
|
||||
entry: './bin/www', |
||||
// 输出配置
|
||||
output: { |
||||
// 输出文件的路径
|
||||
path: path.resolve(__dirname, '../dist'), |
||||
// 输出文件名
|
||||
filename: 'server.js' |
||||
}, |
||||
externals: { |
||||
mysql: 'commonjs mysql', |
||||
axios: 'commonjs axios', |
||||
}, |
||||
target: 'node', |
||||
node: { |
||||
__dirname: false, |
||||
fs: 'empty', |
||||
net: 'empty', |
||||
tls: 'empty', |
||||
}, |
||||
// 模块规则,用于处理各种类型的文件
|
||||
module: { |
||||
rules: [ |
||||
{ |
||||
// 处理JavaScript文件
|
||||
test: /\.js$/, |
||||
// 排除node_modules目录下的文件
|
||||
exclude: /node_modules\/(?!http-proxy-middleware)/, // 处理 http-proxy-middleware 包
|
||||
// 使用babel-loader进行转译
|
||||
use: { |
||||
loader: 'babel-loader', |
||||
options: { |
||||
presets: ['@babel/preset-env'], |
||||
plugins: ['@babel/plugin-proposal-optional-chaining'] |
||||
} |
||||
} |
||||
}, |
||||
{ |
||||
// 处理CSS文件
|
||||
test: /\.css$/, |
||||
// 使用style-loader和css-loader加载CSS
|
||||
use: ['style-loader', 'css-loader'] |
||||
} |
||||
] |
||||
}, |
||||
plugins: [ |
||||
new CleanWebpackPlugin(),
|
||||
new CopyWebpackPlugin({ |
||||
patterns: [ |
||||
{ from: path.resolve(__dirname, '../web/dist'), to: path.resolve(__dirname, '../dist/dist') }, |
||||
{ from: path.resolve(__dirname, './build'), to: path.resolve(__dirname, '../dist') } |
||||
] |
||||
}) |
||||
] |
||||
}; |
@ -0,0 +1,10 @@ |
||||
# 页面标题 |
||||
VITE_APP_TITLE = 致博管理系统 |
||||
|
||||
# 开发环境配置 |
||||
VITE_APP_ENV = 'development' |
||||
|
||||
# 致博管理系统/开发环境 |
||||
VITE_APP_BASE_API = '/dev-api' |
||||
# 开发环境-NODE-工作流接口 |
||||
VITE_APP_BASE_PROCESS_API = 'http://127.0.0.1:3095/process' |
@ -0,0 +1,14 @@ |
||||
# 页面标题 |
||||
VITE_APP_TITLE = 致博管理系统 |
||||
|
||||
# 生产环境配置 |
||||
VITE_APP_ENV = 'production' |
||||
|
||||
# 致博管理系统/生产环境 |
||||
#VITE_APP_BASE_API = 'http://39.100.74.100:8080' |
||||
VITE_APP_BASE_API = 'http://127.0.0.1:3095/ry' |
||||
# 生产环境-NODE-工作流接口 |
||||
VITE_APP_BASE_PROCESS_API = 'http://127.0.0.1:3095/process' |
||||
|
||||
# 是否在打包时开启压缩,支持 gzip 和 brotli |
||||
VITE_BUILD_COMPRESS = gzip |
@ -0,0 +1,12 @@ |
||||
# 页面标题 |
||||
VITE_APP_TITLE = 致博管理系统 |
||||
|
||||
# 生产环境配置 |
||||
VITE_APP_ENV = 'staging' |
||||
|
||||
# 致博管理系统/生产环境 |
||||
VITE_APP_BASE_API = '/stage-api' |
||||
# 生产环境-NODE-工作流接口 |
||||
VITE_APP_BASE_PROCESS_API = 'http://127.0.0.1:3095/process' |
||||
# 是否在打包时开启压缩,支持 gzip 和 brotli |
||||
VITE_BUILD_COMPRESS = gzip |
@ -0,0 +1,4 @@ |
||||
## 说明 |
||||
基于致博的致博后台管理系统模板 |
||||
## 使用文档 |
||||
[文档地址](https://www.zilber.cn/doc/rp/) |
@ -0,0 +1,31 @@ |
||||
{ |
||||
"hash": "9a4f7a36", |
||||
"configHash": "77c0909b", |
||||
"lockfileHash": "90b8159b", |
||||
"browserHash": "5e17b1da", |
||||
"optimized": { |
||||
"vue": { |
||||
"src": "../../../../node_modules/vue/dist/vue.runtime.esm-bundler.js", |
||||
"file": "vue.js", |
||||
"fileHash": "9e0769ad", |
||||
"needsInterop": false |
||||
}, |
||||
"vitepress > @vue/devtools-api": { |
||||
"src": "../../../../node_modules/vitepress/node_modules/@vue/devtools-api/dist/index.js", |
||||
"file": "vitepress___@vue_devtools-api.js", |
||||
"fileHash": "0b965065", |
||||
"needsInterop": false |
||||
}, |
||||
"vitepress > @vueuse/core": { |
||||
"src": "../../../../node_modules/vitepress/node_modules/@vueuse/core/index.mjs", |
||||
"file": "vitepress___@vueuse_core.js", |
||||
"fileHash": "5204427c", |
||||
"needsInterop": false |
||||
} |
||||
}, |
||||
"chunks": { |
||||
"chunk-MWNQXFLB": { |
||||
"file": "chunk-MWNQXFLB.js" |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,3 @@ |
||||
{ |
||||
"type": "module" |
||||
} |
@ -0,0 +1,295 @@ |
||||
import { |
||||
BaseTransition, |
||||
Comment, |
||||
EffectScope, |
||||
Fragment, |
||||
KeepAlive, |
||||
ReactiveEffect, |
||||
Static, |
||||
Suspense, |
||||
Teleport, |
||||
Text, |
||||
Transition, |
||||
TransitionGroup, |
||||
VueElement, |
||||
callWithAsyncErrorHandling, |
||||
callWithErrorHandling, |
||||
camelize, |
||||
capitalize, |
||||
cloneVNode, |
||||
compatUtils, |
||||
compile, |
||||
computed, |
||||
createApp, |
||||
createBaseVNode, |
||||
createBlock, |
||||
createCommentVNode, |
||||
createElementBlock, |
||||
createHydrationRenderer, |
||||
createPropsRestProxy, |
||||
createRenderer, |
||||
createSSRApp, |
||||
createSlots, |
||||
createStaticVNode, |
||||
createTextVNode, |
||||
createVNode, |
||||
customRef, |
||||
defineAsyncComponent, |
||||
defineComponent, |
||||
defineCustomElement, |
||||
defineEmits, |
||||
defineExpose, |
||||
defineProps, |
||||
defineSSRCustomElement, |
||||
devtools, |
||||
effect, |
||||
effectScope, |
||||
getCurrentInstance, |
||||
getCurrentScope, |
||||
getTransitionRawChildren, |
||||
guardReactiveProps, |
||||
h, |
||||
handleError, |
||||
hydrate, |
||||
initCustomFormatter, |
||||
initDirectivesForSSR, |
||||
inject, |
||||
isMemoSame, |
||||
isProxy, |
||||
isReactive, |
||||
isReadonly, |
||||
isRef, |
||||
isRuntimeOnly, |
||||
isShallow, |
||||
isVNode, |
||||
markRaw, |
||||
mergeDefaults, |
||||
mergeProps, |
||||
nextTick, |
||||
normalizeClass, |
||||
normalizeProps, |
||||
normalizeStyle, |
||||
onActivated, |
||||
onBeforeMount, |
||||
onBeforeUnmount, |
||||
onBeforeUpdate, |
||||
onDeactivated, |
||||
onErrorCaptured, |
||||
onMounted, |
||||
onRenderTracked, |
||||
onRenderTriggered, |
||||
onScopeDispose, |
||||
onServerPrefetch, |
||||
onUnmounted, |
||||
onUpdated, |
||||
openBlock, |
||||
popScopeId, |
||||
provide, |
||||
proxyRefs, |
||||
pushScopeId, |
||||
queuePostFlushCb, |
||||
reactive, |
||||
readonly, |
||||
ref, |
||||
registerRuntimeCompiler, |
||||
render, |
||||
renderList, |
||||
renderSlot, |
||||
resolveComponent, |
||||
resolveDirective, |
||||
resolveDynamicComponent, |
||||
resolveFilter, |
||||
resolveTransitionHooks, |
||||
setBlockTracking, |
||||
setDevtoolsHook, |
||||
setTransitionHooks, |
||||
shallowReactive, |
||||
shallowReadonly, |
||||
shallowRef, |
||||
ssrContextKey, |
||||
ssrUtils, |
||||
stop, |
||||
toDisplayString, |
||||
toHandlerKey, |
||||
toHandlers, |
||||
toRaw, |
||||
toRef, |
||||
toRefs, |
||||
transformVNodeArgs, |
||||
triggerRef, |
||||
unref, |
||||
useAttrs, |
||||
useCssModule, |
||||
useCssVars, |
||||
useSSRContext, |
||||
useSlots, |
||||
useTransitionState, |
||||
vModelCheckbox, |
||||
vModelDynamic, |
||||
vModelRadio, |
||||
vModelSelect, |
||||
vModelText, |
||||
vShow, |
||||
version, |
||||
warn, |
||||
watch, |
||||
watchEffect, |
||||
watchPostEffect, |
||||
watchSyncEffect, |
||||
withAsyncContext, |
||||
withCtx, |
||||
withDefaults, |
||||
withDirectives, |
||||
withKeys, |
||||
withMemo, |
||||
withModifiers, |
||||
withScopeId |
||||
} from "./chunk-MWNQXFLB.js"; |
||||
export { |
||||
BaseTransition, |
||||
Comment, |
||||
EffectScope, |
||||
Fragment, |
||||
KeepAlive, |
||||
ReactiveEffect, |
||||
Static, |
||||
Suspense, |
||||
Teleport, |
||||
Text, |
||||
Transition, |
||||
TransitionGroup, |
||||
VueElement, |
||||
callWithAsyncErrorHandling, |
||||
callWithErrorHandling, |
||||
camelize, |
||||
capitalize, |
||||
cloneVNode, |
||||
compatUtils, |
||||
compile, |
||||
computed, |
||||
createApp, |
||||
createBlock, |
||||
createCommentVNode, |
||||
createElementBlock, |
||||
createBaseVNode as createElementVNode, |
||||
createHydrationRenderer, |
||||
createPropsRestProxy, |
||||
createRenderer, |
||||
createSSRApp, |
||||
createSlots, |
||||
createStaticVNode, |
||||
createTextVNode, |
||||
createVNode, |
||||
customRef, |
||||
defineAsyncComponent, |
||||
defineComponent, |
||||
defineCustomElement, |
||||
defineEmits, |
||||
defineExpose, |
||||
defineProps, |
||||
defineSSRCustomElement, |
||||
devtools, |
||||
effect, |
||||
effectScope, |
||||
getCurrentInstance, |
||||
getCurrentScope, |
||||
getTransitionRawChildren, |
||||
guardReactiveProps, |
||||
h, |
||||
handleError, |
||||
hydrate, |
||||
initCustomFormatter, |
||||
initDirectivesForSSR, |
||||
inject, |
||||
isMemoSame, |
||||
isProxy, |
||||
isReactive, |
||||
isReadonly, |
||||
isRef, |
||||
isRuntimeOnly, |
||||
isShallow, |
||||
isVNode, |
||||
markRaw, |
||||
mergeDefaults, |
||||
mergeProps, |
||||
nextTick, |
||||
normalizeClass, |
||||
normalizeProps, |
||||
normalizeStyle, |
||||
onActivated, |
||||
onBeforeMount, |
||||
onBeforeUnmount, |
||||
onBeforeUpdate, |
||||
onDeactivated, |
||||
onErrorCaptured, |
||||
onMounted, |
||||
onRenderTracked, |
||||
onRenderTriggered, |
||||
onScopeDispose, |
||||
onServerPrefetch, |
||||
onUnmounted, |
||||
onUpdated, |
||||
openBlock, |
||||
popScopeId, |
||||
provide, |
||||
proxyRefs, |
||||
pushScopeId, |
||||
queuePostFlushCb, |
||||
reactive, |
||||
readonly, |
||||
ref, |
||||
registerRuntimeCompiler, |
||||
render, |
||||
renderList, |
||||
renderSlot, |
||||
resolveComponent, |
||||
resolveDirective, |
||||
resolveDynamicComponent, |
||||
resolveFilter, |
||||
resolveTransitionHooks, |
||||
setBlockTracking, |
||||
setDevtoolsHook, |
||||
setTransitionHooks, |
||||
shallowReactive, |
||||
shallowReadonly, |
||||
shallowRef, |
||||
ssrContextKey, |
||||
ssrUtils, |
||||
stop, |
||||
toDisplayString, |
||||
toHandlerKey, |
||||
toHandlers, |
||||
toRaw, |
||||
toRef, |
||||
toRefs, |
||||
transformVNodeArgs, |
||||
triggerRef, |
||||
unref, |
||||
useAttrs, |
||||
useCssModule, |
||||
useCssVars, |
||||
useSSRContext, |
||||
useSlots, |
||||
useTransitionState, |
||||
vModelCheckbox, |
||||
vModelDynamic, |
||||
vModelRadio, |
||||
vModelSelect, |
||||
vModelText, |
||||
vShow, |
||||
version, |
||||
warn, |
||||
watch, |
||||
watchEffect, |
||||
watchPostEffect, |
||||
watchSyncEffect, |
||||
withAsyncContext, |
||||
withCtx, |
||||
withDefaults, |
||||
withDirectives, |
||||
withKeys, |
||||
withMemo, |
||||
withModifiers, |
||||
withScopeId |
||||
}; |
||||
//# sourceMappingURL=vue.js.map
|
@ -0,0 +1,7 @@ |
||||
{ |
||||
"version": 3, |
||||
"sources": [], |
||||
"sourcesContent": [], |
||||
"mappings": "", |
||||
"names": [] |
||||
} |
@ -0,0 +1,76 @@ |
||||
module.exports = { |
||||
base: '/doc/rp/', |
||||
title: 'zbn-admin文档', |
||||
description: '基于Vue3+Element-plus封装', |
||||
markdown: { |
||||
lineNumbers: true, |
||||
doc: { |
||||
includeLevel: [1,2,3] |
||||
} |
||||
}, |
||||
themeConfig: { |
||||
search: true, |
||||
nav: [ |
||||
{ text: '首页', link: '/' }, |
||||
{ text: '组件', link: '/components/form/introduce' }, |
||||
{ text: '工作流', link: '/workflow/camunda' }, |
||||
{ text: '文件示例', link: '/demo-doc/demo' } |
||||
], |
||||
sidebar: { |
||||
'/components/': [ |
||||
{ |
||||
text: '表单组件', |
||||
items: [ |
||||
{ text: '介绍', link: '/components/form/introduce' }, |
||||
{ text: '动态form配置', link: '/components/form/normal' }, |
||||
{ text: '下拉选', link: '/components/form/select' }, |
||||
{ text: '单选', link: '/components/form/radio' }, |
||||
{ text: '树形控件', link: '/components/form/tree' }, |
||||
{ text: '标签', link: '/components/form/tag-input' }, |
||||
{ text: '富文本', link: '/components/form/editor' }, |
||||
{ text: '上传', link: '/components/form/upload' }, |
||||
] |
||||
}, |
||||
{ |
||||
text: '常规组件', |
||||
items: [ |
||||
{ text: '流程设计', link: '/components/normal/bpmn' }, |
||||
] |
||||
}, |
||||
{ |
||||
text: '模块组件', |
||||
items: [ |
||||
{ text: '弹出框', link: '/components/module/dialog' }, |
||||
{ text: '搜索区域', link: '/components/module/filter' }, |
||||
{ text: '页面操作区域', link: '/components/module/control' }, |
||||
{ text: '表格', link: '/components/module/table' }, |
||||
{ text: 'table页面', link: '/components/module/page' }, |
||||
{ text: '树形-table', link: '/components/module/child-page' }, |
||||
] |
||||
}, |
||||
{ |
||||
text: '公共方法', |
||||
items: [ |
||||
{ text: '使用方式', link: '/components/method/introduce' }, |
||||
{ text: '日期格式化', link: '/components/method/dateformatter' }, |
||||
{ text: '获取选项', link: '/components/method/getOptionByKey' }, |
||||
{ text: '选项赋值', link: '/components/method/setOptions' }, |
||||
// { text: '动态数组赋值-object', link: '/components/method/setObjectValue' },
|
||||
// { text: '动态数组赋值-key', link: '/components/method/setValueByKey' },
|
||||
{ text: '获取uuid', link: '/components/method/getUuid' }, |
||||
{ text: 'emoji判断', link: '/components/method/hasEmoji' }, |
||||
] |
||||
}, |
||||
], |
||||
'/demo-doc/': [ |
||||
{ |
||||
text: '文件示例', |
||||
items: [ |
||||
{ text: '表单配置文件', link: '/demo-doc/demo#option-js' }, |
||||
{ text: 'vue页面文件', link: '/demo-doc/demo#role-vue' }, |
||||
] |
||||
}, |
||||
], |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,16 @@ |
||||
import DefaultTheme from "vitepress/theme"; |
||||
// import "element-plus/dist/index.css";
|
||||
// import '@vueup/vue-quill/dist/vue-quill.snow.css';
|
||||
|
||||
|
||||
export default { |
||||
...DefaultTheme, |
||||
// enhanceApp: async ({ app, router, siteData, isServer }) => {
|
||||
// import("element-plus").then((module) => {
|
||||
// app.use(module);
|
||||
// });
|
||||
// import("@element-plus/icons-vue").then((module) => {
|
||||
// app.use(module);
|
||||
// });
|
||||
// },
|
||||
}; |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 25 KiB |
@ -0,0 +1,105 @@ |
||||
# 示例 |
||||
## option.js |
||||
```javascript |
||||
export const baseModelOptions = [ |
||||
{ |
||||
tag: 'el-input', |
||||
label: '角色名称:', |
||||
key: 'name', |
||||
value: '', |
||||
default: '', |
||||
attribute: {//属性 |
||||
type: 'text', |
||||
placeholder: '请输入角色名称', |
||||
}, |
||||
}, |
||||
{ |
||||
tag: 'el-input', |
||||
label: '备注:', |
||||
key: 'remark', |
||||
value: '', |
||||
default: '', |
||||
attribute: {//属性 |
||||
type: 'text', |
||||
placeholder: '请输入备注', |
||||
}, |
||||
}, |
||||
{ |
||||
tag: 'BaseTree', |
||||
label: '菜单:', |
||||
key: 'menuIdList', |
||||
value: [], |
||||
default: [], |
||||
attribute: {//属性 |
||||
defaultCheckedKey: [], |
||||
nodeKey: "id", |
||||
showCheckbox: true, |
||||
props: {label:'name'}, |
||||
data: [] |
||||
} |
||||
}, |
||||
] |
||||
|
||||
export const baseFilterOptions = [ |
||||
{ |
||||
tag: 'el-input', |
||||
label: '角色名称:', |
||||
key: 'name', |
||||
value: '', |
||||
attribute: {//属性 |
||||
type: 'text', |
||||
placeholder: '请输入角色名称' |
||||
}, |
||||
}, |
||||
] |
||||
``` |
||||
## role.vue |
||||
```html |
||||
<script setup> |
||||
import { reactive,ref,getCurrentInstance } from 'vue' |
||||
import {getRole,addRole,updateRole,deleteRole,getRoleDetail,getMenuList} from '@/api/data' |
||||
import {setOptions} from '@/utils' |
||||
import {baseModelOptions,baseFilterOptions} from './options' |
||||
|
||||
const { proxy } = getCurrentInstance(); |
||||
const state = reactive({ |
||||
baseModelOptions: baseModelOptions, |
||||
baseFilterOptions: baseFilterOptions, |
||||
title: "角色管理", |
||||
baseModelName: '角色信息', |
||||
addBtnName: '添加角色', |
||||
primaryKey: 'id', |
||||
getTableFn: getRole, |
||||
addFn: addRole, |
||||
editFn: updateRole, |
||||
deleteFn: deleteRole, |
||||
detailFn: getRoleDetail, |
||||
multipleDelete: true, |
||||
pageInfo: { total: 0, base:{limit: 8,current: 1} } |
||||
}) |
||||
|
||||
getMenuList().then(res=>{ |
||||
state.baseModelOptions = proxy.$util.setOptions({ |
||||
data: state.baseModelOptions,//待赋值数据源 |
||||
key:'station',//配置项的key |
||||
res//返回结果 |
||||
}) |
||||
}) |
||||
</script> |
||||
|
||||
<template> |
||||
<BaseTablePage |
||||
:tableOptions="state" |
||||
> |
||||
<template v-slot:column> |
||||
<el-table-column align="center" prop="name" label="名称" /> |
||||
<el-table-column align="center" prop="remark" label="备注" /> |
||||
</template> |
||||
</BaseTablePage> |
||||
</template> |
||||
|
||||
<style scoped> |
||||
|
||||
</style> |
||||
|
||||
``` |
@ -0,0 +1,19 @@ |
||||
# Editor - 富文本编辑器 |
||||
|
||||
基于 QuillEditor 封装,配置项参考 [quill](https://quilljs.com/docs/quickstart/ "https://quilljs.com/docs/quickstart/")<br> |
||||
<br/> |
||||
|
||||
```javascript |
||||
动态组件配置示例: |
||||
{ |
||||
tag: 'Editor', |
||||
label: '富文本:', |
||||
className: 'className', |
||||
value: '', |
||||
default: '', |
||||
contentType: 'html',//默认值,可不填写 |
||||
uploadFn: (file,callback)=>{//自行实现上传图片,上传后调用callback(url)} |
||||
//toolbar: [],//工具栏,默认不需要传递 |
||||
//modules: [],//模块,默认不需要传递 |
||||
} |
||||
``` |
@ -0,0 +1,69 @@ |
||||
# 动态Form |
||||
以配置数组的方式,动态生成相应form表单。 |
||||
常用在模块组件中的BaseModel和BaseFilter。<br/> |
||||
通常情况,上述2个组件被封装在[BaseTablePage](../module/page.md)中。示例如下: |
||||
```javascript |
||||
//新增、修改弹窗配置项 |
||||
export const baseModelOptions = [ |
||||
{ |
||||
tag: 'el-input', |
||||
label: '标题:', |
||||
key: 'name', |
||||
value: '', |
||||
default: '', |
||||
rules: [ |
||||
{ required: true, message: '请输入标题', trigger: 'blur' }, |
||||
], |
||||
attribute: {//属性 |
||||
type: 'text', |
||||
placeholder: '请输入标题', |
||||
}, |
||||
}, |
||||
{ |
||||
tag: 'BaseUpload', |
||||
label: '视频:', |
||||
key: 'videoUrl', |
||||
baseUrl, |
||||
value: [], |
||||
default: [], |
||||
width: '60%', |
||||
rules: [ |
||||
{ required: true, message: '请上传视频', trigger: 'change' }, |
||||
], |
||||
attribute: {//属性 |
||||
limit: 1, |
||||
ref: 'uploadRef', |
||||
accept: '.wmv,.asf,.asx,.mp4,.m4v', |
||||
headers: {token: localGet('token')}, |
||||
baseUrl: baseUrl+'/base/upload'//图片提交接口 |
||||
}, |
||||
|
||||
} |
||||
] |
||||
|
||||
//搜索区域配置项 |
||||
export const baseFilterOptions = [ |
||||
{ |
||||
tag: 'el-input', |
||||
label: '标题:', |
||||
key: 'title', |
||||
value: '', |
||||
default: '', |
||||
attribute: {//属性 |
||||
type: 'text', |
||||
placeholder: '请输入标题', |
||||
}, |
||||
}, |
||||
{ |
||||
tag: 'BaseSelect', |
||||
label: '提案类别:', |
||||
key: 'type', |
||||
value: '', |
||||
default: '', |
||||
attribute: {//属性 |
||||
placeholder: '请选择提案类别', |
||||
options: [] |
||||
}, |
||||
}, |
||||
] |
||||
``` |
@ -0,0 +1,86 @@ |
||||
# 通用配置 |
||||
|
||||
|
||||
```javascript |
||||
// 通用配置 |
||||
{ |
||||
tag: '组件名称', |
||||
label: '示例:', |
||||
key: 'videoUrl', |
||||
value: '当前值', |
||||
default: '默认值', |
||||
rules: [//校验规则 |
||||
{ required: true, message: '示例规则', trigger: 'change' }, |
||||
], |
||||
attribute: {//属性 |
||||
limit: 1, |
||||
}, |
||||
event: { |
||||
'change': (data)=>{//参数内容,见使用的组件的事件 |
||||
//doSomething |
||||
} |
||||
}, |
||||
customFormatter: function(data){ |
||||
if(data.length > 0) return data[0].response.url |
||||
} |
||||
} |
||||
``` |
||||
## 属性 |
||||
| 属性 | 描述 | 是否必填 | 类型 | 默认值 | |
||||
| :-------: | :----------------------------------------------------------------------------: | :------: | :----: | :----: | |
||||
| tag | 组件名称 | 是 | String | 无 | |
||||
| label | 标签描述文本 | 是 | String | 无 | |
||||
| key | 键名(取值/赋值使用) | 是 | String | 无 | |
||||
| value | 当前值(v-model 绑定值) | 是 | Any | '' | |
||||
| default | 默认值(取值时,若 value 为空取 default) | 是 | Any | '' | |
||||
| width | 组件宽度 | 否 | String | 80% | |
||||
| formItemWidth | formItem行宽度 | 否 | String | 50% | |
||||
| labelWidth | label宽度 | 否 | String | 30% | |
||||
| hide | 隐藏控件 | 否 | Boolean | false | |
||||
| disabled | 禁用控件 | 否 | Boolean | false | |
||||
| disEdit | 不进行修改([modelType](../module/dialog.md)=edit &&disEdit=true)自动进行隐藏 | 否 | Boolean | false | |
||||
| rules | form表单校验规则(提交表单时校验) [规则](https://element-plus.gitee.io/zh-CN/component/form.html#%E8%A1%A8%E5%8D%95%E6%A0%A1%E9%AA%8C "https://element-plus.gitee.io/zh-CN/component/form.html#%E8%A1%A8%E5%8D%95%E6%A0%A1%E9%AA%8C") | 否 | Array | '' | |
||||
| attribute | 组件属性(绑定到组件上的属性,等同于:attr="父子传值") | 否 | Object | 无 | |
||||
| event | 组件事件(绑定到组件上的属性,若为 event:{click:()=>{}}等同于@click="function") | 否 | Object | 无 | |
||||
| customFormatter | 自定义格式化(点击确定按钮后-调用提交接口前,触发) | 否 | Object | 无 | |
||||
|
||||
## event |
||||
为组件绑定事件 |
||||
```javascript |
||||
{ |
||||
tag: 'BaseSelect', |
||||
label: '提案类别:', |
||||
key: 'type', |
||||
value: '', |
||||
default: '', |
||||
attribute: {//属性 |
||||
placeholder: '请选择提案类别', |
||||
options: [] |
||||
}, |
||||
event: { |
||||
'change': (data)=>{//参数内容,见使用的组件的事件 |
||||
//doSomething |
||||
} |
||||
} |
||||
} |
||||
``` |
||||
## customFormatter |
||||
自定义格式化函数 |
||||
```javascript |
||||
{ |
||||
tag: 'BaseSelect', |
||||
label: '提案类别:', |
||||
key: 'type', |
||||
value: '', |
||||
default: '', |
||||
attribute: {//属性 |
||||
placeholder: '请选择提案类别', |
||||
options: [] |
||||
}, |
||||
customFormatter: function(data){ |
||||
//data 为v-model的值 |
||||
//this 指向当前vue组件 |
||||
return data[0].response.url |
||||
} |
||||
} |
||||
``` |
@ -0,0 +1,21 @@ |
||||
# BaseRadioGroup - 单选 |
||||
|
||||
配置项参考 [el-radio-group](https://element-plus.gitee.io/zh-CN/component/radio.html "https://element-plus.gitee.io/zh-CN/component/radio.html") |
||||
|
||||
```javascript |
||||
动态组件配置示例: |
||||
{ |
||||
tag: 'BaseRadioGroup', |
||||
label: '性别:', |
||||
key: 'gender', |
||||
value: 1, |
||||
default: 1, |
||||
attribute: {//配置项内容 |
||||
options:[ |
||||
{label: '男',value: 1}, |
||||
{label: '女',value: 2}, |
||||
{label: '未知',value: 3}, |
||||
] |
||||
} |
||||
} |
||||
``` |
@ -0,0 +1,49 @@ |
||||
# BaseSelect - 下拉选 |
||||
|
||||
配置项参考 [el-select](https://element-plus.gitee.io/zh-CN/component/select.html "https://element-plus.gitee.io/zh-CN/component/select.html") |
||||
<br/> |
||||
BaseSelect/BaseTree 选项赋值,参考 util.js -> [setOptions](./../method/setOptions.md) |
||||
|
||||
```javascript |
||||
//动态选项配置示例: |
||||
{ |
||||
tag: 'BaseSelect', |
||||
label: '申请人:', |
||||
key: 'user', |
||||
value: '', |
||||
default: '', |
||||
attribute: {//配置项内容 |
||||
placeholder: '请选择申请人', |
||||
fetchOptions: { |
||||
baseURL: '', //axios.request请求的基础路径 |
||||
url: `/system/user/list`, |
||||
method: "get", |
||||
data: { |
||||
page: 1, |
||||
limit: 999, |
||||
}, |
||||
dataType: "json", |
||||
dataPath: "data.list",//可不指定,默认值-data.list,返回值中的数据路径 |
||||
labelKey: "nickName",//可不指定,默认值-name,返回值中的字段名 |
||||
valueKey: "userId",//可不指定,默认值-id,返回值中的字段名 |
||||
} |
||||
} |
||||
} |
||||
//静态选项配置示例: |
||||
{ |
||||
tag: 'BaseSelect', |
||||
label: '部门:', |
||||
key: 'deptId', |
||||
value: '', |
||||
default: '', |
||||
attribute: {//配置项内容 |
||||
placeholder: '请选择公司', |
||||
options: [ |
||||
{ |
||||
label: '产品部', |
||||
value: 1 |
||||
} |
||||
] |
||||
} |
||||
} |
||||
``` |
@ -0,0 +1,21 @@ |
||||
## TagInput - 输入标签 |
||||
|
||||
配置项参考 [el-tag](https://element-plus.gitee.io/zh-CN/component/tag.html "https://element-plus.gitee.io/zh-CN/component/tag.html")<br> |
||||
<br/> |
||||
|
||||
```javascript |
||||
动态组件配置示例: |
||||
{ |
||||
tag: 'TagInput', |
||||
label: '标签:', |
||||
keys: {//示例为默认值,可不填写 |
||||
value: 'id', |
||||
label: 'name' |
||||
}, |
||||
value: [{id: 1,name: '张三'},{id: 2,name: '李四'}], |
||||
default: [], |
||||
size: 'large',//示例为默认值,可不填写 |
||||
type: '',//示例为默认值,可不填写 |
||||
closable: 'true',//示例为默认值,可不填写 |
||||
} |
||||
``` |
@ -0,0 +1,27 @@ |
||||
# BaseTree - 树形控件 |
||||
|
||||
配置项参考 [el-tree](https://element-plus.gitee.io/zh-CN/component/tree.html "https://element-plus.gitee.io/zh-CN/component/tree.html") |
||||
<br/> |
||||
获取结果时,默认携带了父级 id(即使 children 并未全部选中) |
||||
<br/> |
||||
回显时,默认进行了匹配过滤,即便默认选中值中包含了父级 id,但其 children 的 id 若未全部包含,父节点仍不会被选中 |
||||
<br/> |
||||
BaseSelect/BaseTree 选项赋值,参考 util.js -> [setOptions](./../method/setOptions.md) |
||||
|
||||
```javascript |
||||
动态组件配置示例: |
||||
{ |
||||
tag: 'BaseTree', |
||||
label: '菜单:', |
||||
key: 'menuIdList', |
||||
value: [], |
||||
default: [], |
||||
attribute: {//配置项内容 |
||||
defaultCheckedKey: [], |
||||
nodeKey: "id", |
||||
showCheckbox: true, |
||||
props: {label:'name'}, |
||||
data: [] |
||||
} |
||||
} |
||||
``` |
@ -0,0 +1,159 @@ |
||||
# BaseUpload - 上传 |
||||
|
||||
配置项参考 [el-upload](https://element-plus.gitee.io/zh-CN/component/upload.html "https://element-plus.gitee.io/zh-CN/component/upload.html")<br> |
||||
默认 list-type 为 text |
||||
|
||||
## 普通上传配置示例: |
||||
```javascript |
||||
{ |
||||
tag: 'BaseUpload', |
||||
label: '图片:', |
||||
key: 'videoUrl', |
||||
value: [], |
||||
default: [], |
||||
width: '60%', |
||||
rules: [ |
||||
{ required: true, message: '请上传图片', trigger: 'change' }, |
||||
], |
||||
attribute: {//属性 |
||||
limit: 1, |
||||
ref: 'uploadRef', //仅支持命名uploadRef,可通过table的ref调用, table.value.uploadRef |
||||
accept: '.wmv,.asf,.asx,.mp4,.m4v', //支持的格式 |
||||
headers: {token: 'something'}, //定义请求头 |
||||
baseUrl: baseUrl+'/base/upload',//图片提交接口 |
||||
resKey: {//当前value数组[{}]中,对应的url/name |
||||
urlKey: 'url',//默认值url,相同则可不传 |
||||
nameKey: 'name'//默认值name,相同则可不传 |
||||
}, |
||||
}, |
||||
customFormatter: function(data){//自定义提交表单时,格式化videoUrl字段 |
||||
if(data.length > 0) return data[0].response.url |
||||
} |
||||
} |
||||
``` |
||||
## 切片上传配置示例: |
||||
```javascript |
||||
{ |
||||
tag: 'BaseUpload', |
||||
label: '视频:', |
||||
key: 'videoUrl', |
||||
value: [], |
||||
default: [], |
||||
width: '60%', |
||||
rules: [ |
||||
{ required: true, message: '请上传视频', trigger: 'change' }, |
||||
], |
||||
attribute: {//属性 |
||||
limit: 1, |
||||
ref: 'uploadRef', //仅支持命名uploadRef,可通过table的ref调用, table.value.uploadRef |
||||
accept: '.wmv,.asf,.asx,.mp4,.m4v', //支持的格式 |
||||
resKey: {//当前文件数组[{}]中,对应的url/name |
||||
urlKey: 'url',//默认值,url,name相同则可不传 |
||||
nameKey: 'name' |
||||
}, |
||||
pieceUpload: {//切片上传, 不传则不切片 |
||||
unique: 'userId or others',//唯一id, |
||||
checkFile:{//检查文件接口 |
||||
// method: 'post', //默认post |
||||
url: 'http://localhost:3000/api/base/check', |
||||
// headers: {//选填参数 |
||||
// token: localGet('token'), |
||||
// }, |
||||
}, |
||||
upload:{//上传文件接口,同检查接口 |
||||
url: 'http://localhost:3000/api/base/slice', |
||||
}, |
||||
mergetFile:{//合并文件接口,同检查接口 |
||||
url: 'http://localhost:3000/api/base/compose', |
||||
}, |
||||
autoShard: true,//是否自动进行分片大小计算,默认true |
||||
size: 20,//autoShard=false,生效 |
||||
}, |
||||
}, |
||||
customFormatter: function(data){ |
||||
if(data.length > 0) return data[0].response.url |
||||
} |
||||
} |
||||
``` |
||||
## 上传视频,获取视频长度demo |
||||
```javascript |
||||
const table = ref(); |
||||
//监听Upload组件的值 |
||||
watch(()=>state.baseModelOptions[6].value,(newVal)=>{ |
||||
if(newVal.length > 0 && (newVal[0].percentage === undefined || newVal[0].percentage === 0 || newVal[0].percentage === 100)){ |
||||
var audioElement; |
||||
if(newVal[0]?.response){//后台返回的值 |
||||
audioElement = new Audio(baseUrl + newVal[0]?.response.url); |
||||
}else{ |
||||
var url = URL.createObjectURL(newVal[0].raw);//获取录音时长 |
||||
audioElement = new Audio(url);//audio也可获取视频的时长 |
||||
} |
||||
setTimeout(()=>{ |
||||
table.value.modelRef.loading = true; |
||||
}) |
||||
getAudioLength(audioElement).then(res=>{ |
||||
state.baseAdd.videoLength = res; |
||||
state.baseUpdate.videoLength = res; |
||||
if(newVal[0]?.response) table.value.modelRef.loading = false; |
||||
}).catch(error=>{ |
||||
console.log(55555555,error); |
||||
ElMessage.error('获取音频信息失败'); |
||||
table.value.modelRef.loading = false; |
||||
}) |
||||
}else if(newVal.length == 0){ |
||||
table.value.modelRef.loading = false; |
||||
} |
||||
},{deep:true}) |
||||
``` |
||||
## upload组件的赋值过程 |
||||
```javascript |
||||
//修改操作时,upload组件的赋值过程,以确保upload组件回显正确 |
||||
if (value instanceof Array) { |
||||
//如果value为数组,自动格式化,并返回数组 |
||||
//resKey:{urlKey,nameKey} 对应了取值的key,默认为value[index].url |
||||
item.value = value.map((item1) => { |
||||
let url = item1[item.resKey ? item.resKey[urlKey] : "url"]; |
||||
let name = item1[item.resKey ? item.resKey[nameKey] : "name"]; |
||||
return { |
||||
name: name, |
||||
url: item.baseUrl + url, |
||||
status: "success", |
||||
uid: url, |
||||
response: { |
||||
url, |
||||
name, |
||||
}, |
||||
}; |
||||
}); |
||||
} else if (value instanceof Object) { |
||||
//如果是object,格式化并返回单记录数组 |
||||
let url = value[item.resKey ? item.resKey[urlKey] : "url"]; |
||||
let name = value[item.resKey ? item.resKey[nameKey] : "name"]; |
||||
item.value = [ |
||||
{ |
||||
name: name, |
||||
url: item.baseUrl + url, |
||||
status: "success", |
||||
uid: url, |
||||
response: { |
||||
url, |
||||
name, |
||||
}, |
||||
}, |
||||
]; |
||||
} else { |
||||
//如果是字符串,格式化并返回单记录数组 |
||||
item.value = [ |
||||
{ |
||||
name: data[item.aliasKey || item.key], |
||||
url: item.baseUrl + data[item.aliasKey || item.key], |
||||
status: "success", |
||||
uid: data[item.aliasKey || item.key], |
||||
response: { |
||||
url: data[item.aliasKey || item.key], |
||||
name: data[item.aliasKey || item.key], |
||||
}, |
||||
}, |
||||
]; |
||||
} |
||||
``` |
@ -0,0 +1,32 @@ |
||||
# dateFormatter 日期格式化 |
||||
|
||||
```javascript |
||||
//日期格式化 |
||||
import { getCurrentInstance } from "vue"; |
||||
const { proxy } = getCurrentInstance(); |
||||
proxy.$util.dateFormatter.formate("2022/09/08", "yyyy-mm-dd hh:mm"); |
||||
``` |
||||
|
||||
## formateType |
||||
|
||||
| 名称 | 示例 | |
||||
| :------------------ | :------------------ | |
||||
| yyyy-m | 2022-1 | |
||||
| yyyy-m-d | 2022-1-1 | |
||||
| yyyy-m-d h:m | 2022-01-01 1:1 | |
||||
| yyyy-m-d h:m:s | 2022-01-01 1:1:1 | |
||||
| yyyy-mm | 2022-01 | |
||||
| yyyy-mm-dd | 2022-01-01 | |
||||
| yyyy-mm-dd hh:mm | 2022-01-01 01:01 | |
||||
| yyyy-mm-dd hh:mm:ss | 2022-01-01 01:01:01 | |
||||
| date | 2022-01-01 | |
||||
| datetime | 2022-01-01 01:01:01 | |
||||
|
||||
## methods |
||||
|
||||
| 名称 | 描述 | 参数 | |
||||
| :------------: | :------------------: | :-----------------------------------------------------: | |
||||
| formate | 格式化时间 | (日期,formateType) | |
||||
| now | 获取当前时间并格式化 | formateType | |
||||
| getMonthLength | 获取月份天数 | (year,month) | |
||||
| calculateDate | 计算日期 | (日期, type 增减类型 年:1,月:2,日:3, 数量 ,formateType) | |
@ -0,0 +1,8 @@ |
||||
# getOptionByKey 通过Key获取选项 |
||||
|
||||
```javascript |
||||
//向动态组件中填充选项 |
||||
import { getCurrentInstance } from "vue"; |
||||
const { proxy } = getCurrentInstance(); |
||||
console.log(proxy.$util.getOptionByKey(state.baseModelOptions,'station')); |
||||
``` |
@ -0,0 +1,8 @@ |
||||
# getUUID 获取 UUID |
||||
|
||||
```javascript |
||||
//生成UUID |
||||
import { getCurrentInstance } from "vue"; |
||||
const { proxy } = getCurrentInstance(); |
||||
let uuid = proxy.$util.getUUID(); |
||||
``` |
@ -0,0 +1,8 @@ |
||||
# hasEmoji Emoji 判断 |
||||
|
||||
```javascript |
||||
//判断是否包含emoji表情 |
||||
import { getCurrentInstance } from "vue"; |
||||
const { proxy } = getCurrentInstance(); |
||||
let hasEmoji = proxy.$util.hasEmoji(String); |
||||
``` |
@ -0,0 +1,8 @@ |
||||
# 使用方式 |
||||
插件在app.use 注入后,会自动注入到 vue3 全局方法中 |
||||
```javascript |
||||
//使用示例: |
||||
import { getCurrentInstance } from "vue"; |
||||
const { proxy } = getCurrentInstance(); |
||||
console.log(proxy.$util); |
||||
``` |
@ -0,0 +1,15 @@ |
||||
# setObjectValue 动态数组赋值(object) |
||||
|
||||
```javascript |
||||
//向动态组件中填充值 |
||||
import { getCurrentInstance } from "vue"; |
||||
const { proxy } = getCurrentInstance(); |
||||
proxy.$util.setObjectValue(source, arg); |
||||
``` |
||||
|
||||
## 参数 |
||||
|
||||
| 名称 | 描述 | 必填 | 默认值 | 类型 | |
||||
| :----: | :------------: | ---- | :----: | ------ | |
||||
| source | 待赋值的数据源 | 是 | 无 | Array | |
||||
| arg | 取值的数据源 | 是 | 无 | Object | |
@ -0,0 +1,30 @@ |
||||
# setOptions 选项赋值 |
||||
|
||||
```javascript |
||||
//向动态组件中填充选项 |
||||
import { getCurrentInstance } from "vue"; |
||||
const { proxy } = getCurrentInstance(); |
||||
state.baseModelOptions = proxy.$util.setOptions({ |
||||
//attrName: 下拉选?'options':'data' 默认为options |
||||
data: state.baseModelOptions, //待赋值数据源 |
||||
key: "station", //配置项的key |
||||
res, //返回结果 |
||||
}); |
||||
``` |
||||
|
||||
## 参数 |
||||
|
||||
| 名称 | 描述 | 必填 | 默认值 | 类型 | |
||||
| :---------: | :-------------------------------------------------------------------------------------------------------------------------: | ---- | :-----------------------------------------------------: | ------- | |
||||
| baseOptions | 默认选项 | 否 | [] | Array | |
||||
| attrName | 数据格式化后,赋值的属性名(select: options,tree: data) | 否 | 'options' | String | |
||||
| data | 目标(待赋值)数据 | 是 | 无 | Object | |
||||
| res | 数据源 | 是 | 无 | Object | |
||||
| path | 取值路径 | 否 | "res.data.data" | String | |
||||
| key | data 中对应的 key | 是 | 无 | String | |
||||
| relation | \{key:'格式化后值对应的 key',name:'格式化后名称对应的 key',resKey:'格式化前值对应的 key',resName:'格式化前名称对应的 key'\} | 否 | \{key:'value',name:'label',resKey:'id',resName:'name'\} | Object | |
||||
| hasChildren | 是否需要格式化 children 内容 | 否 | null | Boolean | |
||||
| event | 自定义 event | 否 | null | Object | |
||||
| everClear | 清空已有值 | 否 | false | Boolean | |
||||
| setDefault | 取第一项的值为默认值 | 否 | data 配置项的 value | Boolean | |
||||
| query | 查询数据源(state.baseQuery) ,将选项的第一个值赋给查询 object | 否 | null | Object | |
@ -0,0 +1,8 @@ |
||||
# setValueByKey 动态数组赋值(key) |
||||
|
||||
```javascript |
||||
//向动态数组赋值 |
||||
import { getCurrentInstance } from "vue"; |
||||
const { proxy } = getCurrentInstance(); |
||||
proxy.$util.setValueByKey(state.baseModelOptions, "key", "newValue"); |
||||
``` |
@ -0,0 +1,5 @@ |
||||
|
||||
# BaseChildrenPage-树形 table(已弃用) |
||||
|
||||
<!-- 配置参看BaseTablePage,除data参数格式不同以外,均相同 --> |
||||
BaseTablePage 中配置即可实现 |
@ -0,0 +1,19 @@ |
||||
|
||||
# BaseControl-页面操作区域 |
||||
默认被包含在BaseTable中,可单独使用 |
||||
```html |
||||
<BaseControl |
||||
:single="single" |
||||
:multiple="multiple" |
||||
:showAdd="props.tableOptions.showAddBtn" |
||||
:showEdit="props.tableOptions.showEditBtn" |
||||
:showDelete="props.tableOptions.showDeleteBtn" |
||||
:showExport="props.tableOptions.showExportBtn" |
||||
:showImport="props.tableOptions.showImportBtn" |
||||
:permission="props.tableOptions.permission" |
||||
@add="handleAdd" |
||||
@edit="handleEdit" |
||||
@delete="deleteTableData" |
||||
|
||||
></BaseControl> |
||||
``` |
@ -0,0 +1,49 @@ |
||||
# BaseModel-弹出框 |
||||
|
||||
```html |
||||
<BaseModel |
||||
:title="'查看资料'" |
||||
:modelType="'view'" |
||||
:showModel="state.showModel" |
||||
:width="'35%'" |
||||
:modelOptions="state.baseModelOptions" |
||||
@dialogClose="state.showModel=false" |
||||
@dialogSubmit="editFile" |
||||
> |
||||
</BaseModel> |
||||
``` |
||||
|
||||
## 属性 |
||||
|
||||
| 名称 | 描述 | 参数类型 | 默认值 | |
||||
| ------------ | :----------: | --------------------: | --------------------:| |
||||
| title | 标题 | String | ''| |
||||
| width | 窗口宽度 | String | 35%| |
||||
| columnCount | 列数量 | Number | 2 | |
||||
| labelWidth | label宽度([行内可单独配置](./../form/normal.md)) | String |30%| |
||||
| modelType | 查看类型view(只读)/edit(编辑) | String |edit |
||||
| showModel | 是否显示 | Boolean |false |
||||
| modelOptions | 动态组件内容 | Array | [] |
||||
|
||||
## 方法 |
||||
|
||||
| 名称 | 描述 | 参数类型 | |
||||
| ------------ | :------: | -------------: | |
||||
| setValueByKey | 通过key赋值 | (key,value) | |
||||
| setObjectValue | 通过Object赋值(根据key进行取值) | Object | |
||||
| clearForm | 清空表单值(取modelOptions中default值) | null | |
||||
```javascript |
||||
//添加ref |
||||
<BaseModel ref="bm"></BaseModel> |
||||
//js |
||||
const bm = ref() |
||||
bm.value.setValueByKey('name','张三') |
||||
bm.value.setObjectValue({name:'张三',age:18}) |
||||
``` |
||||
|
||||
## 事件 |
||||
|
||||
| 名称 | 描述 | 可选值 | |
||||
| ------------ | :------: | -------------: | |
||||
| dialogClose | 关闭弹窗 | any | |
||||
| dialogSubmit | 点击确认按钮 | Function(data:Object,callback:Function) 调用callback(),主动将loading状态改为false | |
@ -0,0 +1,37 @@ |
||||
# BaseFilter-搜索区域 |
||||
默认被包含在BaseTable中,可单独使用 |
||||
```html |
||||
<BaseFilter |
||||
:filterOptions="props.tableOptions.baseFilterOptions" |
||||
:showFilter="true" |
||||
@doFilter="doFilter" |
||||
></BaseFilter> |
||||
``` |
||||
|
||||
## 属性 |
||||
|
||||
| 名称 | 描述 | 可选值 | 默认值 | |
||||
| ------------ | :----------: | --------------------: | --------------------------: | |
||||
| filterOptions | 动态组件内容 | [组件数组] | [] | |
||||
|
||||
## 方法 |
||||
|
||||
| 名称 | 描述 | 参数类型 | |
||||
| ------------ | :------: | -------------: | |
||||
| doFilter | 执行搜索 | null | |
||||
| clearFilter | 清空搜索条件 | null | |
||||
```javascript |
||||
//添加ref |
||||
<BaseFilter ref="filter"></BaseFilter> |
||||
//js |
||||
const filter = ref() |
||||
filter.value.doFilter() |
||||
filter.value.clearFilter() |
||||
``` |
||||
|
||||
|
||||
## 事件 |
||||
|
||||
| 名称 | 描述 | 可选值 | |
||||
| -------- | :----------: | -------------: | |
||||
| doFilter | 点击搜索触发 | Function(data) | |
@ -0,0 +1,201 @@ |
||||
# BaseTablePage-table 页面 |
||||
|
||||
column 配置项参考 [el-table](https://element-plus.gitee.io/zh-CN/component/table.html "https://element-plus.gitee.io/zh-CN/component/table.html") |
||||
|
||||
```javascript |
||||
const state = reactive({ |
||||
baseModelOptions: baseModelOptions, //新增、修改弹窗 动态组件数组 |
||||
baseFilterOptions: baseFilterOptions, //上方搜索 动态组件数组 |
||||
title: "用户管理", //页面标题,不设置则隐藏标题区域 |
||||
getTableFn: getUser, //查询接口 --Promise |
||||
pageInfo: { total: 0, base: { limit: 8, current: 1 } }, //分页信息 |
||||
}); |
||||
``` |
||||
|
||||
```html |
||||
<BaseTablePage ref="table" :tableOptions="state"> |
||||
<!-- 表格column插槽,不包含操作按钮 --> |
||||
<template #column> |
||||
<el-table-column align="center" prop="username" label="用户名" /> |
||||
<el-table-column align="center" prop="gender" label="性别"> |
||||
<template #default="scope"> |
||||
<span style="margin-left: 10px" |
||||
>{{ scope.row.gender==1?'男':scope.row.gender==2?'女':'未知' }}</span |
||||
> |
||||
</template> |
||||
</el-table-column> |
||||
</template> |
||||
<!-- type1: 编辑按钮前置插槽,可在编辑按钮前添加内容 --> |
||||
<template #before="scope"> |
||||
<el-button type="primary">新增</el-button> |
||||
</template> |
||||
<!-- type2: 删除按钮后置插槽,可在删除按钮后添加内容 --> |
||||
<template #after="scope"> |
||||
<el-button type="primary">详情</el-button> |
||||
</template> |
||||
<!-- type3: 表格control插槽,重写操作按钮区域 --> |
||||
<template #control="baseScope"> |
||||
<el-table-column label="操作" width="350"> |
||||
<template #default="scope"> |
||||
<el-button type="warning" @click="baseScope.handleEdit(scope.$index, scope.row)" |
||||
>修改</el-button |
||||
> |
||||
<el-popconfirm @confirm="baseScope.deleteTableData(scope.$index, scope.row)" title="确定删除该条数据?"> |
||||
<template #reference> |
||||
<el-button |
||||
type="danger" |
||||
>删除</el-button |
||||
> |
||||
</template> |
||||
</el-popconfirm> |
||||
</template> |
||||
</el-table-column> |
||||
</template> |
||||
</BaseTablePage> |
||||
``` |
||||
|
||||
## 调用组件方法 |
||||
```html |
||||
<BaseTablePage :tableOptions="state" ref="table"></BaseTablePage> |
||||
``` |
||||
```javascript |
||||
const table = ref(); |
||||
onMounted(() => { |
||||
const { |
||||
doFilter, //点击搜索后执行的函数 |
||||
getTableData, //查询表格数据执行的函数 |
||||
editTableData, //修改弹窗,点击确定执行的函数 |
||||
deleteTableData, //删除弹窗,点击确定执行的函数 |
||||
} = table.value; |
||||
//示例:3s后主动执行一次查询 |
||||
setTimeout(() => { |
||||
getTableData(); |
||||
}, 3000); |
||||
}); |
||||
``` |
||||
## 事件 |
||||
| 名称 | 描述 | 参数 | |
||||
| ----------------- | :-------------------------: | -----: | |
||||
| import | 点击顶部导入按钮触发 | null | |
||||
| export | 点击顶部导出按钮触发 | null | |
||||
| doSelection| 行选中change事件 | \{data:Array,ids:Array\} | |
||||
|
||||
## tableOptions 属性 |
||||
### function相关 |
||||
| 名称 | 描述 | 必填 | 参数类型 | 默认值 | |
||||
| ----------------- | :-------------------------: | ---: | -------: | -----: | |
||||
| handleAdd | 添加按钮执行的 func(覆盖默认的调用 function) | 否 | Function | null | |
||||
| handleAdd | 添加按钮执行的 func(覆盖默认的调用 function) | 否 | Function | null | |
||||
| handleEdit | 点击编辑按钮执行的 func(覆盖默认的调用 function) | 否 | Function(index,row) | null | |
||||
| handleDelete | 点击删除按钮执行的 func(覆盖默认的调用 function) | 否 | Function(index,row) | null | |
||||
| beforeSubmit | 提交修改前事件,F(params) | 是 | Function | null | |
||||
| beforeShowEdit | 点击编辑按钮事件,弹窗显示前执行(同步) F(params) | 否 | Function | null | |
||||
| beforeEdit | 与 beforeShowEdit 执行时机一致(异步) | 否 | (Promise)Function(row) | null | |
||||
| beforeDelete | 执行删除前调用 | 否 | Function(row) | null | |
||||
| [beforeFilter](./page.md#示例1) | 执行搜索前调用 | 否 | Function(params) | null | |
||||
| [beforeReset](./page.md#示例1) | 执行重置前调用 | 否 | Function(params) | null | |
||||
| afterSubmit | 表单提交后调用(支持普通 fn 与 return Promise) | 否 | (Promise)Function(row) | null | |
||||
| afterDelete | 数据删除后调用(支持普通 fn 与 return Promise) | 否 | (Promise)Function(row) | null | |
||||
### 按钮相关 |
||||
| 名称 | 描述 | 必填 | 参数类型 | 默认值 | |
||||
| ----------------- | :-------------------------: | ---: | -------: | -----: | |
||||
| showAddBtn | 是否显示添加按钮 | 否 | Boolean | true | |
||||
| showEditBtn | 是否显示顶部修改按钮 | 否 | Boolean | false | |
||||
| showDeleteBtn | 是否显示顶部删除按钮 | 否 | Boolean | false | |
||||
| showImport | 是否显示顶部导入按钮 | 否 | Boolean | false | |
||||
| showExport | 是否显示顶部导出按钮 | 否 | Boolean | false | |
||||
| editBtnName | 修改操作 按钮名称 | 否 | String | null | |
||||
| delBtnName | 删除操作 按钮名称 | 否 | String | null | |
||||
| rowControl | 行内操作按钮控制\{showEditBtn:false,showDelBtn:false\} | 否 | Object | \{showEditBtn:true,showDelBtn:true\} | |
||||
| permission | 页面内增删改查权限,permission:\{add:'菜单权限标识',edit:'菜单权限标识',delete:'菜单权限标识'\} | 否 | Object | null | |
||||
|
||||
### 配置属性 |
||||
| 名称 | 描述 | 必填 | 参数类型 | 默认值 | |
||||
| ----------------- | :-------------------------: | ---: | -------: | -----: | |
||||
| baseModelOptions | 新增、修改弹窗 动态组件数组 | 是 | Array | null | |
||||
| baseFilterOptions | 上方搜索 动态组件数组 | 是 | Array | null | |
||||
| pageSelection | 是否开启分页行选中(不开启只计算当前page选中) | 否 | Boolean | false | |
||||
| loadingText | 加载中的文本 | 否 | String | Loading... | |
||||
| loadingBackground | 加载中背景色 | 否 | String | rgb(34, 58, 106, 0.5) | |
||||
| style | BaseTablePage组件的样式 | 否 | StyleObject | null | |
||||
| tableStyle | el-table组件的style | 否 | StyleObject | null | |
||||
| autoQuery | 是否页面初始化自动进行查询 table | 是 | Boolean | true | |
||||
| showLoading | 是否显示加载动画,默认 false,且只有值为 true 显示 | 否 | Boolan | true | |
||||
| rowKey | 当 row 中包含 children 字段时,被视为树形数据,指定 row-key,开启树形数据展示 | 否 | String | null | |
||||
| baseModelName | 弹窗标题 | 否 | String | null | |
||||
| hideControl | 隐藏操作列 | 否 | Boolean | null | |
||||
| primaryKey | 修改操作 参数名称 | 否 | String | null | |
||||
| deleteKey | 删除操作 参数名称 | 否 | String | null | |
||||
| baseQuery | 查询接口默认参数 | 否 | Object | null | |
||||
| baseAdd | 添加接口默认参数 | 否 | Object | null | |
||||
| baseUpdate | 修改接口默认参数 | 否 | Object | null | |
||||
| getTableFn | 查询接口 | 是 | (Promise) Function | null | |
||||
| addFn | 新增接口 | 否 | (Promise) Function | null | |
||||
| editFn | 修改接口 | 否 | (Promise) Function | null | |
||||
| detailFn | 查询详情接口,点击修改触发,为 null 时,使用 table-row 的数据 | 否 | (Promise) Function | null | |
||||
| deleteFn | 删除接口 | 否 | (Promise) Function | null | |
||||
| pageInfo | 分页信息 | 否 | Object | { total: 0, base:{limit: 10,current: 1} } | |
||||
| pageKeys | 查询时分页key | 否 | Object | \{ limit: 'limit',page: 'current' \} | |
||||
|
||||
|
||||
## 插槽 |
||||
|
||||
| 名称 | 描述 | scope | |
||||
| --------- | :--------------------: | ---------------------------------: | |
||||
| addButton | 顶部添加按钮的内部插槽 | none | |
||||
| column | table-column 内容 | | |
||||
| control | 操作(操作按钮) | scope.'table 相关 [methods](./page.md#control插槽属性)' | |
||||
| before | 编辑按钮前置插槽 | scope.row | |
||||
| after | 删除按钮后置插槽 | scope.row | |
||||
|
||||
## control插槽属性 |
||||
| 名称 | 描述 | |
||||
| --------- | :--------------------: | |
||||
| showModel | 显示添加/编辑弹窗 | |
||||
| doFilter | 触发查询按钮 | |
||||
| getTableData | 查询列表 | |
||||
| pageChange | 触发页面改变 | |
||||
| tableData | 当前tableData | |
||||
| handleAdd | 触发新增按钮点击 | |
||||
| handleEdit | 触发修改按钮点击 | |
||||
| editTableData | 触发提交修改事件 | |
||||
| deleteTableData | 触发删除点击事件 | |
||||
|
||||
|
||||
|
||||
## 其他配置 |
||||
### 数值来源: |
||||
vue全局变量$autoScrollTop|$autoScrollHeight |
||||
| 名称 | 描述 | defasult | |
||||
| --------- | :--------------------: | :--------------------: | |
||||
| $autoScrollTop | 页码变化时是否滚动到顶部 | false | |
||||
| $autoScrollHeight | table高度,autoScrollTop为true生效 | '' | |
||||
|
||||
## 示例1 |
||||
```javascript |
||||
const state = reactive({ |
||||
beforeReset: ()=>{ |
||||
//1. 使用异步的方式 |
||||
return new Promise((resolve)=>{ |
||||
setTimeout(()=>{ |
||||
//dosomething... |
||||
resolve() |
||||
},2000) |
||||
}) |
||||
//2.使用同步的方式 |
||||
//dosomething... |
||||
}, |
||||
beforeFilter: (params)=>{ |
||||
//1. 使用异步的方式 |
||||
return new Promise((resolve)=>{ |
||||
setTimeout(()=>{ |
||||
//dosomething... |
||||
resolve({a:'重新设置的值'}) |
||||
},2000) |
||||
}) |
||||
//2.使用同步的方式 |
||||
//dosomething... |
||||
// return {a:'重新设置的值'} || 不返回,则使用当前搜索框内的值 |
||||
} |
||||
}) |
||||
``` |
@ -0,0 +1,28 @@ |
||||
# BaseTable-表格 |
||||
默认被包含在BaseTable中,可单独使用 |
||||
```html |
||||
<!-- 封装了el-table + pagination --> |
||||
<BaseTable |
||||
@pageChange="pageChange" |
||||
:data="tableData" |
||||
:hidePagenation="props.tableOptions.hidePagenation" |
||||
:pageInfo="props.tableOptions.pageInfo" |
||||
> |
||||
<el-table-column align="center" prop="dictName" label="字典名称" /> |
||||
<el-table-column align="center" prop="dictType" label="字典类型" /> |
||||
</BaseTable> |
||||
``` |
||||
|
||||
## 属性 |
||||
|
||||
| 名称 | 描述 | 可选值 | |
||||
| -------------- | :---------------: | ---------------------------------------: | |
||||
| data | 列表值 | [列表值] | |
||||
| pageInfo | 分页信息对象 | { total: 0, base:{limit: 8,current: 1} } | |
||||
| hidePagenation | 是否隐藏分页 | true/false | |
||||
|
||||
## 事件 |
||||
|
||||
| 名称 | 描述 | 可选值 | |
||||
| ---------- | :----------: | -----------------: | |
||||
| pageChange | 页码发生改变 | Function(pageInfo) | |
@ -0,0 +1,34 @@ |
||||
# Bpmn - 流程设计 |
||||
|
||||
基于 [bpmn-js](https://bpmn.io/toolkit/bpmn-js/ "https://bpmn.io/toolkit/bpmn-js/") 实现的流程设计器,通过绘制流程图,快速设计流程。 |
||||
|
||||
## 使用示例: |
||||
```html |
||||
<Bpmn :users="users" :roles="roles" @save="save"></Bpmn> |
||||
``` |
||||
```javascript |
||||
const users = [ |
||||
{ |
||||
value: "zhangsan", |
||||
label: "张三" |
||||
}, |
||||
{ |
||||
value: "lisi", |
||||
label: "李四" |
||||
} |
||||
] |
||||
const roles = [ |
||||
{ |
||||
value: "manager", |
||||
label: "经理" |
||||
}, |
||||
{ |
||||
value: "personnel", |
||||
label: "人事" |
||||
} |
||||
] |
||||
|
||||
const save = (res)=>{//保存流程图xml |
||||
console.log(res) |
||||
} |
||||
``` |
@ -0,0 +1,124 @@ |
||||
# 动态Form |
||||
以配置数组的方式,动态生成相应form表单。 |
||||
常用在模块组件中的BaseModel和BaseFilter。 |
||||
通常情况,上述2个组件被封装在BaseTablePage中 |
||||
```javascript |
||||
//新增、修改弹窗配置项 |
||||
export const baseModelOptions = [ |
||||
{ |
||||
tag: 'el-input', |
||||
label: '标题:', |
||||
key: 'name', |
||||
value: '', |
||||
default: '', |
||||
rules: [ |
||||
{ required: true, message: '请输入标题', trigger: 'blur' }, |
||||
], |
||||
attribute: {//属性 |
||||
type: 'text', |
||||
placeholder: '请输入标题', |
||||
}, |
||||
}, |
||||
{ |
||||
tag: 'BaseUpload', |
||||
label: '视频:', |
||||
key: 'videoUrl', |
||||
baseUrl, |
||||
value: [], |
||||
default: [], |
||||
width: '60%', |
||||
rules: [ |
||||
{ required: true, message: '请上传视频', trigger: 'change' }, |
||||
], |
||||
attribute: {//属性 |
||||
limit: 1, |
||||
ref: 'uploadRef', |
||||
accept: '.wmv,.asf,.asx,.mp4,.m4v', |
||||
headers: {token: localGet('token')}, |
||||
baseUrl: baseUrl+'/base/upload'//图片提交接口 |
||||
}, |
||||
|
||||
} |
||||
] |
||||
|
||||
//搜索区域配置项 |
||||
export const baseFilterOptions = [ |
||||
{ |
||||
tag: 'el-input', |
||||
label: '标题:', |
||||
key: 'title', |
||||
value: '', |
||||
default: '', |
||||
attribute: {//属性 |
||||
type: 'text', |
||||
placeholder: '请输入标题', |
||||
}, |
||||
}, |
||||
{ |
||||
tag: 'BaseSelect', |
||||
label: '提案类别:', |
||||
key: 'type', |
||||
value: '', |
||||
default: '', |
||||
attribute: {//属性 |
||||
placeholder: '请选择提案类别', |
||||
options: [] |
||||
}, |
||||
}, |
||||
] |
||||
``` |
||||
|
||||
### 属性 |
||||
| 名称 | 描述 | 必填 | 参数类型 | 默认值 | |
||||
| ----------------- | :--------------------------------------------------------------------------: | ---: | ------: | ----: | |
||||
| tag | 组件名称 | 是 | String | 无 | |
||||
| label | 标签名称 | 是 | String | 无 | |
||||
| key | 提交的key值 | 是 | String | 无 | |
||||
| value | 当前值 | 是 | String | 无 | |
||||
| default | 默认值,取值时,若value为空,则取default的值 | 是 | String | 无 | |
||||
| attribute | 组件的属性,等同于直接组件中<组件 :属性="something" /> | 否 | Object | {} | |
||||
| rules | form表单校验规则,仅支持默认校验,详情参考element-plus | 否 | Array | 无 | |
||||
| event | 组件的事件,等同于直接组件中<组件 @事件="something" />,见下方示例 | 否 | Object | null | |
||||
| customFormatter | 自定义格式化,在form表单点击提交取值时会触发,见下方示例 | 否 | Object | null | |
||||
|
||||
|
||||
### event |
||||
为组件绑定事件 |
||||
```javascript |
||||
{ |
||||
tag: 'BaseSelect', |
||||
label: '提案类别:', |
||||
key: 'type', |
||||
value: '', |
||||
default: '', |
||||
attribute: {//属性 |
||||
placeholder: '请选择提案类别', |
||||
options: [] |
||||
}, |
||||
event: { |
||||
'change': (data)=>{//参数内容,见使用的组件的事件 |
||||
//doSomething |
||||
} |
||||
} |
||||
} |
||||
``` |
||||
### customFormatter |
||||
自定义格式化函数 |
||||
```javascript |
||||
{ |
||||
tag: 'BaseSelect', |
||||
label: '提案类别:', |
||||
key: 'type', |
||||
value: '', |
||||
default: '', |
||||
attribute: {//属性 |
||||
placeholder: '请选择提案类别', |
||||
options: [] |
||||
}, |
||||
customFormatter: function(data){ |
||||
//data 为v-model的值 |
||||
//this 指向当前vue组件 |
||||
return data[0].response.url |
||||
} |
||||
} |
||||
``` |
@ -0,0 +1,105 @@ |
||||
# 示例 |
||||
## option.js |
||||
```javascript |
||||
export const baseModelOptions = [ |
||||
{ |
||||
tag: 'el-input', |
||||
label: '角色名称:', |
||||
key: 'name', |
||||
value: '', |
||||
default: '', |
||||
attribute: {//属性 |
||||
type: 'text', |
||||
placeholder: '请输入角色名称', |
||||
}, |
||||
}, |
||||
{ |
||||
tag: 'el-input', |
||||
label: '备注:', |
||||
key: 'remark', |
||||
value: '', |
||||
default: '', |
||||
attribute: {//属性 |
||||
type: 'text', |
||||
placeholder: '请输入备注', |
||||
}, |
||||
}, |
||||
{ |
||||
tag: 'BaseTree', |
||||
label: '菜单:', |
||||
key: 'menuIdList', |
||||
value: [], |
||||
default: [], |
||||
attribute: {//属性 |
||||
defaultCheckedKey: [], |
||||
nodeKey: "id", |
||||
showCheckbox: true, |
||||
props: {label:'name'}, |
||||
data: [] |
||||
} |
||||
}, |
||||
] |
||||
|
||||
export const baseFilterOptions = [ |
||||
{ |
||||
tag: 'el-input', |
||||
label: '角色名称:', |
||||
key: 'name', |
||||
value: '', |
||||
attribute: {//属性 |
||||
type: 'text', |
||||
placeholder: '请输入角色名称' |
||||
}, |
||||
}, |
||||
] |
||||
``` |
||||
## role.vue |
||||
```html |
||||
<script setup> |
||||
import { reactive,ref,getCurrentInstance } from 'vue' |
||||
import {getRole,addRole,updateRole,deleteRole,getRoleDetail,getMenuList} from '@/api/data' |
||||
import {setOptions} from '@/utils' |
||||
import {baseModelOptions,baseFilterOptions} from './options' |
||||
|
||||
const { proxy } = getCurrentInstance(); |
||||
const state = reactive({ |
||||
baseModelOptions: baseModelOptions, |
||||
baseFilterOptions: baseFilterOptions, |
||||
title: "角色管理", |
||||
baseModelName: '角色信息', |
||||
addBtnName: '添加角色', |
||||
primaryKey: 'id', |
||||
getTableFn: getRole, |
||||
addFn: addRole, |
||||
editFn: updateRole, |
||||
deleteFn: deleteRole, |
||||
detailFn: getRoleDetail, |
||||
multipleDelete: true, |
||||
pageInfo: { total: 0, base:{limit: 8,current: 1} } |
||||
}) |
||||
|
||||
getMenuList().then(res=>{ |
||||
state.baseModelOptions = proxy.$util.setOptions({ |
||||
data: state.baseModelOptions,//待赋值数据源 |
||||
key:'station',//配置项的key |
||||
res//返回结果 |
||||
}) |
||||
}) |
||||
</script> |
||||
|
||||
<template> |
||||
<BaseTablePage |
||||
:tableOptions="state" |
||||
> |
||||
<template v-slot:column> |
||||
<el-table-column align="center" prop="name" label="名称" /> |
||||
<el-table-column align="center" prop="remark" label="备注" /> |
||||
</template> |
||||
</BaseTablePage> |
||||
</template> |
||||
|
||||
<style scoped> |
||||
|
||||
</style> |
||||
|
||||
``` |
@ -0,0 +1,114 @@ |
||||
# 介绍 |
||||
zbn-admin后台管理系统,现已支持前端server模式(非必选) |
||||
- server部分使用nodejs的express框架 |
||||
- web部分使用Vue3 + ElementPlus封装,搭配java若依后端框架 |
||||
|
||||
## server |
||||
基于nodejs的express框架,主要实现了以下功能: |
||||
- 1. 支持mysql数据库直连,前端可直接进行业务扩展 |
||||
- 2. 定向转发了java端的若依框架接口,不影响原业务结构 |
||||
- 3. 集成了camunda rest api,支持自定义审批流 |
||||
- 4. 可直接进行部署,不再依赖nginx转发 |
||||
- 5. 前端可自行扩展vue-router history模式 |
||||
#### 目录结构 |
||||
 |
||||
## web |
||||
web后台管理系统,有以下特点: |
||||
- 1. 基于Vue3 + ElementPlus封装,搭配java若依后端框架。 |
||||
- 2. 封装了部分无法进行v-model的form表单组件,并实现了以配置的方式,动态绘制表单 |
||||
- 3. 封装了弹出框、table页等常规表格组件 |
||||
- 4. 封装了常用的util方法,注册到全局方法中 |
||||
- 5. 搭配vscode插件-zeQick,可以快速生成页面代码,提高开发效率。 |
||||
- 6. 支持camunda集成-自定义审批流 |
||||
### 调整页面组件的默认行为 |
||||
``` |
||||
app.config.globalProperties.$resPath = {//自定义tablePage接口的配置 |
||||
tableResult: {//获取table数据的配置 |
||||
successCode: 0, |
||||
codePath: 'data.code', |
||||
dataPath: 'data.data.list', |
||||
totalPath: 'data.data.total', |
||||
messagePath: 'data.msg', |
||||
}, |
||||
rowResult: {//点击详情,获取行数据的配置 |
||||
successCode: 0, |
||||
codePath: 'data.code', |
||||
dataPath: 'data.data', |
||||
messagePath: 'data.msg', |
||||
}, |
||||
controlResult: {//修改/新增/删除的配置 |
||||
successCode: 0, |
||||
codePath: 'data.code', |
||||
messagePath: 'data.msg' |
||||
} |
||||
}; |
||||
app.config.globalProperties.$pageKeys = { |
||||
page: 'page', |
||||
limit: 'limit' |
||||
}; |
||||
``` |
||||
### resPath |
||||
| 名称 | 描述 | 参数类型 | 默认值 | |
||||
| ------------ | :----------: | --------------------: | --------------------:| |
||||
| [tableResult](./index.md#Result) | 获取table数据的配置 | Object | null | |
||||
| [rowResult](./index.md#Result) | 点击详情,获取行数据的配置 | Object | null| |
||||
| [controlResult](./index.md#Result) | 修改/新增/删除的配置 | Object | null| |
||||
### Result |
||||
path:从res的读取的属性,codePath='code',则读取res.code |
||||
| 名称 | 描述 | 参数类型 | 默认值 | |
||||
| ------------ | :----------: | --------------------: | --------------------:| |
||||
| successCode | 成功状态码 | Number | 200 | |
||||
| codePath | 读取状态码的路径 | String | 'code'| |
||||
| dataPath | 读取tableData的路径 | String | 'data.list'| |
||||
| totalPath | 读取总条数的路径 | String | 'data.total'| |
||||
| messagePath | 读取消息的路径 | String | 'data.msg'| |
||||
|
||||
## 启动方式 |
||||
### 单独启动 |
||||
|
||||
```shell |
||||
# server |
||||
cd server |
||||
npm install |
||||
npm run start |
||||
# web |
||||
cd web |
||||
npm install |
||||
npm run dev |
||||
``` |
||||
### 整体启动 |
||||
```shell |
||||
npm install |
||||
npm run dev |
||||
``` |
||||
## 打包方式 |
||||
### 单独打包 |
||||
```shell |
||||
# server |
||||
cd server |
||||
npm run build |
||||
# web |
||||
cd web |
||||
npm run build:prod |
||||
``` |
||||
### 整体打包 |
||||
```shell |
||||
npm run build |
||||
``` |
||||
#### 输出目录-整体打包 |
||||
根目录下会生成dist文件夹, |
||||
- 内部dist文件夹为web打包后的文件 |
||||
- server.js为server打包后的文件 |
||||
#### |
||||
 |
||||
#### 部署方式-整体打包 |
||||
将dist文件夹放到服务器上,执行以下命令 |
||||
```shell |
||||
npm install |
||||
# 当前窗口启动 |
||||
npm run start |
||||
# 后台启动-方式1 |
||||
nohup npm run start & |
||||
# 后台启动-方式2 |
||||
forever start server.js |
||||
``` |
@ -0,0 +1,296 @@ |
||||
|
||||
# Workflow API 文档 |
||||
## 流程示意 |
||||
 |
||||
|
||||
## 目录 |
||||
|
||||
- [流程图管理](#流程图管理) |
||||
- [流程实例管理](#流程实例管理) |
||||
- [任务管理](#任务管理) |
||||
- [表单管理](#表单管理) |
||||
- [Camunda部署-Docker](#Camunda部署-Docker) |
||||
|
||||
## 项目导入 |
||||
```javascript |
||||
import { |
||||
getProcessList, |
||||
getProcessInfo |
||||
//...其他 |
||||
} from '/api/workflow' |
||||
``` |
||||
## 流程图管理 |
||||
|
||||
### 获取流程图列表 |
||||
```javascript |
||||
getProcessList({ |
||||
firstResult = 0, // 起始索引 |
||||
maxResults = 8, // 最大结果数 |
||||
latestVersion = true // 是否最新版本 |
||||
}) |
||||
``` |
||||
|
||||
### 获取流程图信息 |
||||
```javascript |
||||
getProcessInfo(processId) // processId: 流程图ID |
||||
``` |
||||
|
||||
### 获取流程图 XML |
||||
```javascript |
||||
getProcessXml(processId) // processId: 流程图ID |
||||
``` |
||||
|
||||
|
||||
### 上传流程图 |
||||
```javascript |
||||
const bpmnContent = '...'; // 流程图内容 |
||||
const formData = new FormData() |
||||
const bpmnBlob = new Blob([bpmnContent], { type: 'application/octet-stream' }); |
||||
formData.append('content', bpmnBlob, 'process.bpmn'); // 文件名应以 .bpmn 结尾 |
||||
addModeler(formData) |
||||
``` |
||||
|
||||
|
||||
### 删除流程图 |
||||
```javascript |
||||
deleteProcess(processId) // processId: 流程图ID |
||||
``` |
||||
|
||||
### 创建流程实例 |
||||
```javascript |
||||
start({ |
||||
processKey: string, // 流程图key |
||||
formId: string, // 表单ID |
||||
createUser: string, // 创建人 |
||||
formValues: object // 填写的表单数据 |
||||
}) |
||||
``` |
||||
|
||||
## 流程实例管理 |
||||
|
||||
### 获取流程实例列表 |
||||
```javascript |
||||
getProcessInstanceList({ |
||||
firstResult = 0, // 起始索引 |
||||
maxResults = 8, // 最大结果数 |
||||
processDefinitionKey, // 流程图key |
||||
sortOrder = "desc", // 排序方式:asc/desc |
||||
sortBy = "startTime" // 排序字段 |
||||
}) |
||||
``` |
||||
|
||||
### 删除流程实例 |
||||
```javascript |
||||
deleteProcessInstance(processInstanceId) // processInstanceId: 流程实例ID |
||||
``` |
||||
|
||||
## 任务管理 |
||||
|
||||
### 获取流程实例任务列表 |
||||
```javascript |
||||
getInstanceTaskList({ |
||||
firstResult = 0, // 起始索引 |
||||
maxResults = 8, // 最大结果数 |
||||
processInstanceId // 流程实例ID |
||||
}) |
||||
``` |
||||
|
||||
### 获取用户任务列表 |
||||
```javascript |
||||
getUserTaskList({ |
||||
firstResult = 0, // 起始索引 |
||||
maxResults = 8, // 最大结果数 |
||||
assignee, // 执行人ID |
||||
candidateUser, // 候选人ID |
||||
candidateGroup // 候选组ID |
||||
}) |
||||
``` |
||||
|
||||
### 任务候选人管理 |
||||
```javascript |
||||
// 查询任务节点候选人/组 |
||||
getTaskCandidate(taskId) |
||||
|
||||
// 添加节点候选人/组 |
||||
addTaskCandidate({ |
||||
taskId, // 任务ID |
||||
type, // 类型:candidate/assignee |
||||
userId, // 用户ID(与groupId二选一) |
||||
groupId // 组ID(与userId二选一) |
||||
}) |
||||
|
||||
// 删除节点候选人/组 |
||||
deleteTaskCandidate({ |
||||
taskId, // 任务ID |
||||
type, // 类型:candidate/assignee |
||||
userId, // 用户ID(与groupId二选一) |
||||
groupId // 组ID(与userId二选一) |
||||
}) |
||||
``` |
||||
|
||||
### 任务操作 |
||||
```javascript |
||||
// 认领任务 |
||||
claim({ |
||||
taskId, // 任务ID |
||||
userId // 用户ID |
||||
}) |
||||
|
||||
// 取消认领任务 |
||||
unclaim(taskId) |
||||
|
||||
// 完成任务 |
||||
complete({ |
||||
taskId, // 任务ID |
||||
variables: { |
||||
approvalResult: { |
||||
value: "approved" | "rejected", // 审批结果 |
||||
type: "String" |
||||
} |
||||
} |
||||
}) |
||||
|
||||
// 添加任务评论---记录审批结果 |
||||
setComment({ |
||||
taskId, // 任务ID |
||||
message // 评论内容(JSON字符串) JSON.stringify({message: '执行成功',id: '其他的测试信息'}) |
||||
|
||||
}) |
||||
``` |
||||
|
||||
## 表单管理 |
||||
|
||||
### 表单查询 |
||||
```javascript |
||||
// 获取表单列表 |
||||
getFormList({ |
||||
page, // 页码 |
||||
start, // 起始索引 |
||||
limit // 最大结果数 |
||||
}) |
||||
|
||||
// 获取表单详情 |
||||
getFormDetail(formId) |
||||
|
||||
// 获取表单字段 |
||||
getFormFields(path) |
||||
``` |
||||
|
||||
### 表单操作 |
||||
表单内容,暂不支持上传文件,手动填写在node服务端- /server/form下,写法与动态Form一致 |
||||
```javascript |
||||
var config = require('../config'); //配置动态请求的基础路径 |
||||
const formFields = [ |
||||
{ |
||||
tag: 'el-input', |
||||
label: '申请原因:', |
||||
key: 'reason', |
||||
value: '', |
||||
default: '', |
||||
attribute: { |
||||
clearable: true, |
||||
placeholder: '请输入申请原因', |
||||
}, |
||||
}, |
||||
{ |
||||
tag: 'BaseSelect', |
||||
label: '申请人:', |
||||
key: 'user', |
||||
value: '', |
||||
default: '', |
||||
attribute: {//配置项内容 |
||||
placeholder: '请选择申请人', |
||||
fetchOptions: {//动态请求配置 |
||||
baseURL: config.env[process.env.NODE_ENV].formBaseURL, //请求的基础路径 |
||||
url: `/system/user/list`, |
||||
method: "get", |
||||
data: { |
||||
page: 1, |
||||
limit: 999, |
||||
}, |
||||
dataType: "json", |
||||
dataPath: "data.list",//默认值-data.list,可不指定 |
||||
labelKey: "nickName",//默认值-name,可不指定 |
||||
valueKey: "userId",//默认值-id,可不指定 |
||||
} |
||||
} |
||||
} |
||||
]; |
||||
module.exports = { |
||||
formFields |
||||
}; |
||||
|
||||
``` |
||||
```javascript |
||||
// 添加表单 |
||||
addForm({ |
||||
formName: string, // 表单名称 |
||||
formDesc: string, // 表单描述 |
||||
formPath: string, // 表单内容--/form/test.js |
||||
userId: string // 创建人ID |
||||
}) |
||||
|
||||
// 更新表单 |
||||
updateForm({ |
||||
id: string, // 表单ID |
||||
formName: string, // 表单名称 |
||||
formDesc: string, // 表单描述 |
||||
formPath: string // 表单内容 |
||||
}) |
||||
|
||||
// 删除表单 |
||||
deleteForm(formId) |
||||
``` |
||||
|
||||
注意:所有 API 都返回 Promise 对象,可使用 async/await 处理异步请求。API 的基础 URL 由环境变量 `VITE_APP_BASE_PROCESS_API` 指定。 |
||||
|
||||
## Camunda部署-Docker |
||||
### 1.更改docker的镜像源 |
||||
vi /etc/docker/daemon.json |
||||
```shell |
||||
{ |
||||
"registry-mirrors": [ |
||||
"https://docker.registry.cyou", |
||||
"https://docker-cf.registry.cyou", |
||||
"https://dockercf.jsdelivr.fyi", |
||||
"https://docker.jsdelivr.fyi", |
||||
"https://dockertest.jsdelivr.fyi", |
||||
"https://mirror.aliyuncs.com", |
||||
"https://dockerproxy.com", |
||||
"https://mirror.baidubce.com", |
||||
"https://docker.m.daocloud.io", |
||||
"https://docker.nju.edu.cn", |
||||
"https://docker.mirrors.sjtug.sjtu.edu.cn", |
||||
"https://docker.mirrors.ustc.edu.cn", |
||||
"https://mirror.iscas.ac.cn", |
||||
"https://docker.rainbond.cc" |
||||
] |
||||
} |
||||
``` |
||||
|
||||
```shell |
||||
systemctl daemon-reload |
||||
systemctl restart docker |
||||
``` |
||||
### 2.拉取镜像 |
||||
```shell |
||||
docker pull camunda/camunda-bpm-platform:latest |
||||
``` |
||||
### 3.添加启动脚本 |
||||
vi /data/camunda/docker-compose.yml |
||||
```shell |
||||
# 其中ports 1111为宿主机端口,8080为容器内部端口 |
||||
version: '3' |
||||
services: |
||||
camunda: |
||||
image: camunda/camunda-bpm-platform:latest |
||||
ports: |
||||
- "1111:8080" |
||||
volumes: |
||||
- ./camunda-data:/camunda/data |
||||
|
||||
``` |
||||
```shell |
||||
#启动服务 |
||||
docker-compose up -d |
||||
``` |
@ -0,0 +1,215 @@ |
||||
<!DOCTYPE html> |
||||
<html> |
||||
|
||||
<head> |
||||
<meta charset="utf-8"> |
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
||||
<meta name="renderer" content="webkit"> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> |
||||
<link rel="icon" href="/favicon.ico"> |
||||
<title>致博管理系统</title> |
||||
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]--> |
||||
<style> |
||||
html, |
||||
body, |
||||
#app { |
||||
height: 100%; |
||||
margin: 0px; |
||||
padding: 0px; |
||||
} |
||||
|
||||
.chromeframe { |
||||
margin: 0.2em 0; |
||||
background: #ccc; |
||||
color: #000; |
||||
padding: 0.2em 0; |
||||
} |
||||
|
||||
#loader-wrapper { |
||||
position: fixed; |
||||
top: 0; |
||||
left: 0; |
||||
width: 100%; |
||||
height: 100%; |
||||
z-index: 999999; |
||||
} |
||||
|
||||
#loader { |
||||
display: block; |
||||
position: relative; |
||||
left: 50%; |
||||
top: 50%; |
||||
width: 150px; |
||||
height: 150px; |
||||
margin: -75px 0 0 -75px; |
||||
border-radius: 50%; |
||||
border: 3px solid transparent; |
||||
border-top-color: #FFF; |
||||
-webkit-animation: spin 2s linear infinite; |
||||
-ms-animation: spin 2s linear infinite; |
||||
-moz-animation: spin 2s linear infinite; |
||||
-o-animation: spin 2s linear infinite; |
||||
animation: spin 2s linear infinite; |
||||
z-index: 1001; |
||||
} |
||||
|
||||
#loader:before { |
||||
content: ""; |
||||
position: absolute; |
||||
top: 5px; |
||||
left: 5px; |
||||
right: 5px; |
||||
bottom: 5px; |
||||
border-radius: 50%; |
||||
border: 3px solid transparent; |
||||
border-top-color: #FFF; |
||||
-webkit-animation: spin 3s linear infinite; |
||||
-moz-animation: spin 3s linear infinite; |
||||
-o-animation: spin 3s linear infinite; |
||||
-ms-animation: spin 3s linear infinite; |
||||
animation: spin 3s linear infinite; |
||||
} |
||||
|
||||
#loader:after { |
||||
content: ""; |
||||
position: absolute; |
||||
top: 15px; |
||||
left: 15px; |
||||
right: 15px; |
||||
bottom: 15px; |
||||
border-radius: 50%; |
||||
border: 3px solid transparent; |
||||
border-top-color: #FFF; |
||||
-moz-animation: spin 1.5s linear infinite; |
||||
-o-animation: spin 1.5s linear infinite; |
||||
-ms-animation: spin 1.5s linear infinite; |
||||
-webkit-animation: spin 1.5s linear infinite; |
||||
animation: spin 1.5s linear infinite; |
||||
} |
||||
|
||||
|
||||
@-webkit-keyframes spin { |
||||
0% { |
||||
-webkit-transform: rotate(0deg); |
||||
-ms-transform: rotate(0deg); |
||||
transform: rotate(0deg); |
||||
} |
||||
|
||||
100% { |
||||
-webkit-transform: rotate(360deg); |
||||
-ms-transform: rotate(360deg); |
||||
transform: rotate(360deg); |
||||
} |
||||
} |
||||
|
||||
@keyframes spin { |
||||
0% { |
||||
-webkit-transform: rotate(0deg); |
||||
-ms-transform: rotate(0deg); |
||||
transform: rotate(0deg); |
||||
} |
||||
|
||||
100% { |
||||
-webkit-transform: rotate(360deg); |
||||
-ms-transform: rotate(360deg); |
||||
transform: rotate(360deg); |
||||
} |
||||
} |
||||
|
||||
|
||||
#loader-wrapper .loader-section { |
||||
position: fixed; |
||||
top: 0; |
||||
width: 51%; |
||||
height: 100%; |
||||
background: #7171C6; |
||||
z-index: 1000; |
||||
-webkit-transform: translateX(0); |
||||
-ms-transform: translateX(0); |
||||
transform: translateX(0); |
||||
} |
||||
|
||||
#loader-wrapper .loader-section.section-left { |
||||
left: 0; |
||||
} |
||||
|
||||
#loader-wrapper .loader-section.section-right { |
||||
right: 0; |
||||
} |
||||
|
||||
|
||||
.loaded #loader-wrapper .loader-section.section-left { |
||||
-webkit-transform: translateX(-100%); |
||||
-ms-transform: translateX(-100%); |
||||
transform: translateX(-100%); |
||||
-webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); |
||||
transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); |
||||
} |
||||
|
||||
.loaded #loader-wrapper .loader-section.section-right { |
||||
-webkit-transform: translateX(100%); |
||||
-ms-transform: translateX(100%); |
||||
transform: translateX(100%); |
||||
-webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); |
||||
transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000); |
||||
} |
||||
|
||||
.loaded #loader { |
||||
opacity: 0; |
||||
-webkit-transition: all 0.3s ease-out; |
||||
transition: all 0.3s ease-out; |
||||
} |
||||
|
||||
.loaded #loader-wrapper { |
||||
visibility: hidden; |
||||
-webkit-transform: translateY(-100%); |
||||
-ms-transform: translateY(-100%); |
||||
transform: translateY(-100%); |
||||
-webkit-transition: all 0.3s 1s ease-out; |
||||
transition: all 0.3s 1s ease-out; |
||||
} |
||||
|
||||
.no-js #loader-wrapper { |
||||
display: none; |
||||
} |
||||
|
||||
.no-js h1 { |
||||
color: #222222; |
||||
} |
||||
|
||||
#loader-wrapper .load_title { |
||||
font-family: 'Open Sans'; |
||||
color: #FFF; |
||||
font-size: 19px; |
||||
width: 100%; |
||||
text-align: center; |
||||
z-index: 9999999999999; |
||||
position: absolute; |
||||
top: 60%; |
||||
opacity: 1; |
||||
line-height: 30px; |
||||
} |
||||
|
||||
#loader-wrapper .load_title span { |
||||
font-weight: normal; |
||||
font-style: italic; |
||||
font-size: 13px; |
||||
color: #FFF; |
||||
opacity: 0.5; |
||||
} |
||||
</style> |
||||
</head> |
||||
|
||||
<body> |
||||
<div id="app"> |
||||
<div id="loader-wrapper"> |
||||
<!-- <div id="loader"></div> |
||||
<div class="loader-section section-left"></div> |
||||
<div class="loader-section section-right"></div> |
||||
<div class="load_title">正在加载系统资源,请耐心等待</div> --> |
||||
</div> |
||||
</div> |
||||
<script type="module" src="/src/main.js"></script> |
||||
</body> |
||||
|
||||
</html> |
@ -0,0 +1,62 @@ |
||||
{ |
||||
"name": "zilber-admin", |
||||
"version": "1.0.0", |
||||
"description": "致博后台管理系统", |
||||
"author": "ChengYu", |
||||
"license": "MIT", |
||||
"scripts": { |
||||
"dev": "vite", |
||||
"build:prod": "vite build", |
||||
"build:stage": "vite build --mode staging", |
||||
"docs:dev": "vitepress dev docs", |
||||
"docs:build": "vitepress build docs", |
||||
"preview": "vite preview" |
||||
}, |
||||
"repository": { |
||||
"type": "git", |
||||
"url": "http://dev.zilber.cn:3000/root/zbn-admin.git" |
||||
}, |
||||
"dependencies": { |
||||
"@element-plus/icons-vue": "1.1.4", |
||||
"@vueup/vue-quill": "^1.0.0-beta.10", |
||||
"@vueuse/core": "8.5.0", |
||||
"@wangeditor/editor": "^5.1.23", |
||||
"@wangeditor/editor-for-vue": "^5.1.12", |
||||
"@wangeditor/plugin-upload-attachment": "^1.1.0", |
||||
"axios": "0.26.1", |
||||
"bpmn-js": "^18.1.1", |
||||
"echarts": "5.3.2", |
||||
"element-plus": "2.1.8", |
||||
"esbuild": "^0.19.9", |
||||
"file-saver": "2.0.5", |
||||
"fuse.js": "6.5.3", |
||||
"image-conversion": "^2.1.1", |
||||
"js-cookie": "3.0.1", |
||||
"js-md5": "^0.8.3", |
||||
"jsencrypt": "3.2.1", |
||||
"nprogress": "0.2.0", |
||||
"pinia": "2.0.14", |
||||
"quill-image-resize-module": "^3.0.0", |
||||
"quill-image-uploader": "^1.3.0", |
||||
"uuid": "^11.0.4", |
||||
"vue": "3.2.37", |
||||
"vue-cropper": "1.0.3", |
||||
"vue-router": "4.0.14", |
||||
"vuedraggable": "^4.1.0", |
||||
"xml-js": "^1.6.11" |
||||
}, |
||||
"devDependencies": { |
||||
"@rollup/plugin-inject": "^5.0.5", |
||||
"@vitejs/plugin-vue": "2.3.3", |
||||
"@vue/compiler-sfc": "3.2.36", |
||||
"concurrently": "^9.1.0", |
||||
"rollup-plugin-visualizer": "^5.12.0", |
||||
"sass": "1.52.1", |
||||
"unplugin-auto-import": "0.8.5", |
||||
"vite": "2.9.14", |
||||
"vite-plugin-compression": "0.5.1", |
||||
"vite-plugin-svg-icons": "2.0.1", |
||||
"vite-plugin-vue-setup-extend": "0.4.0", |
||||
"vitepress": "^1.5.0" |
||||
} |
||||
} |
After Width: | Height: | Size: 5.5 KiB |
@ -0,0 +1,33 @@ |
||||
<template> |
||||
<router-view /> |
||||
</template> |
||||
|
||||
<script setup> |
||||
import useSettingsStore from '@/store/modules/settings' |
||||
import { handleThemeStyle } from '@/utils/theme' |
||||
|
||||
onMounted(() => { |
||||
nextTick(() => { |
||||
// 初始化主题样式 |
||||
handleThemeStyle(useSettingsStore().theme) |
||||
}) |
||||
}) |
||||
</script> |
||||
<style> |
||||
.title{ |
||||
text-align: left; |
||||
padding-top: 15px; |
||||
padding-bottom: 15px; |
||||
font-size: 16px; |
||||
border-bottom: 1px solid #FFFFFF; |
||||
} |
||||
.title:before{ |
||||
content: ''; |
||||
display: inline-block; |
||||
width: 4px; |
||||
height: 12px; |
||||
background: #286AED; |
||||
margin: 0 9px; |
||||
} |
||||
.fliter-box .el-date-editor.el-input, .fliter-box .el-date-editor.el-input__wrapper{ width: 192px;} |
||||
</style> |
@ -0,0 +1,59 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
// 登录方法
|
||||
export function login(username, password, code, uuid) { |
||||
const data = { |
||||
userName: username, |
||||
password, |
||||
code, |
||||
uuid |
||||
} |
||||
return request({ |
||||
url: '/login', |
||||
headers: { |
||||
isToken: false |
||||
}, |
||||
method: 'post', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 注册方法
|
||||
export function register(data) { |
||||
return request({ |
||||
url: '/register', |
||||
headers: { |
||||
isToken: false |
||||
}, |
||||
method: 'post', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 获取用户详细信息
|
||||
export function getInfo() { |
||||
return request({ |
||||
url: '/getInfo', |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 退出方法
|
||||
export function logout() { |
||||
return request({ |
||||
url: '/logout', |
||||
method: 'post' |
||||
}) |
||||
} |
||||
|
||||
// 获取验证码
|
||||
export function getCodeImg() { |
||||
return request({ |
||||
url: '/captchaImage', |
||||
headers: { |
||||
isToken: false |
||||
}, |
||||
method: 'get', |
||||
timeout: 20000 |
||||
}) |
||||
} |
@ -0,0 +1,9 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
// 获取路由
|
||||
export const getRouters = () => { |
||||
return request({ |
||||
url: '/getRouters', |
||||
method: 'get' |
||||
}) |
||||
} |
@ -0,0 +1,57 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
// 查询缓存详细
|
||||
export function getCache() { |
||||
return request({ |
||||
url: '/monitor/cache', |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 查询缓存名称列表
|
||||
export function listCacheName() { |
||||
return request({ |
||||
url: '/monitor/cache/getNames', |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 查询缓存键名列表
|
||||
export function listCacheKey(cacheName) { |
||||
return request({ |
||||
url: '/monitor/cache/getKeys/' + cacheName, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 查询缓存内容
|
||||
export function getCacheValue(cacheName, cacheKey) { |
||||
return request({ |
||||
url: '/monitor/cache/getValue/' + cacheName + '/' + cacheKey, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 清理指定名称缓存
|
||||
export function clearCacheName(cacheName) { |
||||
return request({ |
||||
url: '/monitor/cache/clearCacheName/' + cacheName, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
// 清理指定键名缓存
|
||||
export function clearCacheKey(cacheKey) { |
||||
return request({ |
||||
url: '/monitor/cache/clearCacheKey/' + cacheKey, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
// 清理全部缓存
|
||||
export function clearCacheAll() { |
||||
return request({ |
||||
url: '/monitor/cache/clearCacheAll', |
||||
method: 'delete' |
||||
}) |
||||
} |
@ -0,0 +1,71 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
// 查询定时任务调度列表
|
||||
export function listJob(query) { |
||||
return request({ |
||||
url: '/monitor/job/list', |
||||
method: 'get', |
||||
params: query |
||||
}) |
||||
} |
||||
|
||||
// 查询定时任务调度详细
|
||||
export function getJob(jobId) { |
||||
return request({ |
||||
url: '/monitor/job/' + jobId, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 新增定时任务调度
|
||||
export function addJob(data) { |
||||
return request({ |
||||
url: '/monitor/job', |
||||
method: 'post', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 修改定时任务调度
|
||||
export function updateJob(data) { |
||||
return request({ |
||||
url: '/monitor/job', |
||||
method: 'put', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 删除定时任务调度
|
||||
export function delJob(jobId) { |
||||
return request({ |
||||
url: '/monitor/job/' + jobId, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
// 任务状态修改
|
||||
export function changeJobStatus(jobId, status) { |
||||
const data = { |
||||
jobId, |
||||
status |
||||
} |
||||
return request({ |
||||
url: '/monitor/job/changeStatus', |
||||
method: 'put', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
|
||||
// 定时任务立即执行一次
|
||||
export function runJob(jobId, jobGroup) { |
||||
const data = { |
||||
jobId, |
||||
jobGroup |
||||
} |
||||
return request({ |
||||
url: '/monitor/job/run', |
||||
method: 'put', |
||||
data: data |
||||
}) |
||||
} |
@ -0,0 +1,26 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
// 查询调度日志列表
|
||||
export function listJobLog(query) { |
||||
return request({ |
||||
url: '/monitor/jobLog/list', |
||||
method: 'get', |
||||
params: query |
||||
}) |
||||
} |
||||
|
||||
// 删除调度日志
|
||||
export function delJobLog(jobLogId) { |
||||
return request({ |
||||
url: '/monitor/jobLog/' + jobLogId, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
// 清空调度日志
|
||||
export function cleanJobLog() { |
||||
return request({ |
||||
url: '/monitor/jobLog/clean', |
||||
method: 'delete' |
||||
}) |
||||
} |
@ -0,0 +1,34 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
// 查询登录日志列表
|
||||
export function list(query) { |
||||
return request({ |
||||
url: '/monitor/logininfor/list', |
||||
method: 'get', |
||||
params: query |
||||
}) |
||||
} |
||||
|
||||
// 删除登录日志
|
||||
export function delLogininfor(infoId) { |
||||
return request({ |
||||
url: '/monitor/logininfor/' + infoId, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
// 解锁用户登录状态
|
||||
export function unlockLogininfor(userName) { |
||||
return request({ |
||||
url: '/monitor/logininfor/unlock/' + userName, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 清空登录日志
|
||||
export function cleanLogininfor() { |
||||
return request({ |
||||
url: '/monitor/logininfor/clean', |
||||
method: 'delete' |
||||
}) |
||||
} |
@ -0,0 +1,18 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
// 查询在线用户列表
|
||||
export function list(query) { |
||||
return request({ |
||||
url: '/monitor/online/list', |
||||
method: 'get', |
||||
params: query |
||||
}) |
||||
} |
||||
|
||||
// 强退用户
|
||||
export function forceLogout(tokenId) { |
||||
return request({ |
||||
url: '/monitor/online/' + tokenId, |
||||
method: 'delete' |
||||
}) |
||||
} |
@ -0,0 +1,26 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
// 查询操作日志列表
|
||||
export function list(query) { |
||||
return request({ |
||||
url: '/monitor/operlog/list', |
||||
method: 'get', |
||||
params: query |
||||
}) |
||||
} |
||||
|
||||
// 删除操作日志
|
||||
export function delOperlog(operId) { |
||||
return request({ |
||||
url: '/monitor/operlog/' + operId, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
// 清空操作日志
|
||||
export function cleanOperlog() { |
||||
return request({ |
||||
url: '/monitor/operlog/clean', |
||||
method: 'delete' |
||||
}) |
||||
} |
@ -0,0 +1,9 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
// 获取服务信息
|
||||
export function getServer() { |
||||
return request({ |
||||
url: '/monitor/server', |
||||
method: 'get' |
||||
}) |
||||
} |
@ -0,0 +1,60 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
// 查询参数列表
|
||||
export function listConfig(query) { |
||||
return request({ |
||||
url: '/system/config/list', |
||||
method: 'get', |
||||
params: query |
||||
}) |
||||
} |
||||
|
||||
// 查询参数详细
|
||||
export function getConfig(configId) { |
||||
return request({ |
||||
url: '/system/config/' + configId, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 根据参数键名查询参数值
|
||||
export function getConfigKey(configKey) { |
||||
return request({ |
||||
url: '/system/config/configKey/' + configKey, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 新增参数配置
|
||||
export function addConfig(data) { |
||||
return request({ |
||||
url: '/system/config', |
||||
method: 'post', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 修改参数配置
|
||||
export function updateConfig(data) { |
||||
return request({ |
||||
url: '/system/config', |
||||
method: 'put', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 删除参数配置
|
||||
export function delConfig(configId) { |
||||
return request({ |
||||
url: '/system/config/' + configId, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
// 刷新参数缓存
|
||||
export function refreshCache() { |
||||
return request({ |
||||
url: '/system/config/refreshCache', |
||||
method: 'delete' |
||||
}) |
||||
} |
@ -0,0 +1,55 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
// 查询部门列表
|
||||
export function listDept(query) { |
||||
return request({ |
||||
url: '/system/dept/list', |
||||
method: 'get', |
||||
params: query |
||||
}) |
||||
} |
||||
|
||||
// 查询部门列表(排除节点)
|
||||
export function listDeptExcludeChild(deptId) { |
||||
return request({ |
||||
url: '/system/dept/list/exclude', |
||||
params: {deptId: deptId}, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 查询部门详细
|
||||
export function getDept(deptId) { |
||||
return request({ |
||||
url: '/system/dept/getInfo', |
||||
params: {deptId: deptId}, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 新增部门
|
||||
export function addDept(data) { |
||||
return request({ |
||||
url: '/system/dept', |
||||
method: 'post', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 修改部门
|
||||
export function updateDept(data) { |
||||
return request({ |
||||
url: '/system/dept/edit', |
||||
method: 'put', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 删除部门
|
||||
export function delDept(deptId) { |
||||
return request({ |
||||
url: '/system/dept/remove', |
||||
params: {deptId: deptId}, |
||||
method: 'delete' |
||||
}) |
||||
} |
@ -0,0 +1,52 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
// 查询字典数据列表
|
||||
export function listData(query) { |
||||
return request({ |
||||
url: '/system/dict/data/list', |
||||
method: 'get', |
||||
params: query |
||||
}) |
||||
} |
||||
|
||||
// 查询字典数据详细
|
||||
export function getData(dictCode) { |
||||
return request({ |
||||
url: '/system/dict/data/' + dictCode, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 根据字典类型查询字典数据信息
|
||||
export function getDicts(dictType) { |
||||
return request({ |
||||
url: '/system/dict/data/type/' + dictType, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 新增字典数据
|
||||
export function addData(data) { |
||||
return request({ |
||||
url: '/system/dict/data', |
||||
method: 'post', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 修改字典数据
|
||||
export function updateData(data) { |
||||
return request({ |
||||
url: '/system/dict/data', |
||||
method: 'put', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 删除字典数据
|
||||
export function delData(dictCode) { |
||||
return request({ |
||||
url: '/system/dict/data/' + dictCode, |
||||
method: 'delete' |
||||
}) |
||||
} |
@ -0,0 +1,60 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
// 查询字典类型列表
|
||||
export function listType(query) { |
||||
return request({ |
||||
url: '/system/dict/type/list', |
||||
method: 'get', |
||||
params: query |
||||
}) |
||||
} |
||||
|
||||
// 查询字典类型详细
|
||||
export function getType(dictId) { |
||||
return request({ |
||||
url: '/system/dict/type/' + dictId, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 新增字典类型
|
||||
export function addType(data) { |
||||
return request({ |
||||
url: '/system/dict/type', |
||||
method: 'post', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 修改字典类型
|
||||
export function updateType(data) { |
||||
return request({ |
||||
url: '/system/dict/type', |
||||
method: 'put', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 删除字典类型
|
||||
export function delType(dictId) { |
||||
return request({ |
||||
url: '/system/dict/type/' + dictId, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
// 刷新字典缓存
|
||||
export function refreshCache() { |
||||
return request({ |
||||
url: '/system/dict/type/refreshCache', |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
// 获取字典选择框列表
|
||||
export function optionselect() { |
||||
return request({ |
||||
url: '/system/dict/type/optionselect', |
||||
method: 'get' |
||||
}) |
||||
} |
@ -0,0 +1,63 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
// 查询菜单列表
|
||||
export function listMenu(query) { |
||||
return request({ |
||||
url: '/system/menu/list', |
||||
method: 'get', |
||||
params: query |
||||
}) |
||||
} |
||||
|
||||
// 查询菜单详细
|
||||
export function getMenu(menuId) { |
||||
return request({ |
||||
url: '/system/menu/getInfo', |
||||
params: {menuId}, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 查询菜单下拉树结构
|
||||
export function treeselect() { |
||||
return request({ |
||||
url: '/system/menu/treeselect', |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 根据角色ID查询菜单下拉树结构
|
||||
export function roleMenuTreeselect(roleId) { |
||||
return request({ |
||||
url: '/system/menu/roleMenuTreeselect', |
||||
params: {roleId}, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 新增菜单
|
||||
export function addMenu(data) { |
||||
return request({ |
||||
url: '/system/menu/add', |
||||
method: 'post', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 修改菜单
|
||||
export function updateMenu(data) { |
||||
return request({ |
||||
url: '/system/menu/edit', |
||||
method: 'put', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 删除菜单
|
||||
export function delMenu(menuId) { |
||||
return request({ |
||||
url: '/system/menu/remove', |
||||
params: {menuId}, |
||||
method: 'delete' |
||||
}) |
||||
} |
@ -0,0 +1,44 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
// 查询公告列表
|
||||
export function listNotice(query) { |
||||
return request({ |
||||
url: '/system/notice/list', |
||||
method: 'get', |
||||
params: query |
||||
}) |
||||
} |
||||
|
||||
// 查询公告详细
|
||||
export function getNotice(noticeId) { |
||||
return request({ |
||||
url: '/system/notice/' + noticeId, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 新增公告
|
||||
export function addNotice(data) { |
||||
return request({ |
||||
url: '/system/notice', |
||||
method: 'post', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 修改公告
|
||||
export function updateNotice(data) { |
||||
return request({ |
||||
url: '/system/notice', |
||||
method: 'put', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 删除公告
|
||||
export function delNotice(noticeId) { |
||||
return request({ |
||||
url: '/system/notice/' + noticeId, |
||||
method: 'delete' |
||||
}) |
||||
} |
@ -0,0 +1,48 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
// 查询岗位列表
|
||||
export function listPost(query) { |
||||
return request({ |
||||
url: '/system/post/list', |
||||
method: 'get', |
||||
params: query |
||||
}) |
||||
} |
||||
|
||||
// 查询岗位详细
|
||||
export function getPost(postId) { |
||||
return request({ |
||||
url: '/system/post/getInfo', |
||||
params: {postId}, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 新增岗位
|
||||
export function addPost(data) { |
||||
return request({ |
||||
url: '/system/post/add', |
||||
method: 'post', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 修改岗位
|
||||
export function updatePost(data) { |
||||
return request({ |
||||
url: '/system/post/edit', |
||||
method: 'put', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 删除岗位
|
||||
export function delPost(postId) { |
||||
return request({ |
||||
url: '/system/post/remove', |
||||
params: { |
||||
postIds: postId instanceof Array ? postId.join(',') : postId |
||||
}, |
||||
method: 'delete' |
||||
}) |
||||
} |
@ -0,0 +1,122 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
// 查询角色列表
|
||||
export function listRole(query) { |
||||
return request({ |
||||
url: '/system/role/list', |
||||
method: 'get', |
||||
params: query |
||||
}) |
||||
} |
||||
|
||||
// 查询角色详细
|
||||
export function getRole(roleId) { |
||||
return request({ |
||||
url: '/system/role/getInfo', |
||||
params: {roleId}, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 新增角色
|
||||
export function addRole(data) { |
||||
return request({ |
||||
url: '/system/role/add', |
||||
method: 'post', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 修改角色
|
||||
export function updateRole(data) { |
||||
return request({ |
||||
url: '/system/role/edit', |
||||
method: 'put', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 角色数据权限
|
||||
export function dataScope(data) { |
||||
return request({ |
||||
url: '/system/role/dataScope', |
||||
method: 'put', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 角色状态修改
|
||||
export function changeRoleStatus(roleId, status) { |
||||
const data = { |
||||
roleId, |
||||
status |
||||
} |
||||
return request({ |
||||
url: '/system/role/changeStatus', |
||||
method: 'put', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 删除角色
|
||||
export function delRole(roleId) { |
||||
return request({ |
||||
url: '/system/role/', |
||||
params: {roleId}, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
// 查询角色已授权用户列表
|
||||
export function allocatedUserList(query) { |
||||
return request({ |
||||
url: '/system/role/authUser/allocatedList', |
||||
method: 'get', |
||||
params: query |
||||
}) |
||||
} |
||||
|
||||
// 查询角色未授权用户列表
|
||||
export function unallocatedUserList(query) { |
||||
return request({ |
||||
url: '/system/role/authUser/unallocatedList', |
||||
method: 'get', |
||||
params: query |
||||
}) |
||||
} |
||||
|
||||
// 取消用户授权角色
|
||||
export function authUserCancel(data) { |
||||
return request({ |
||||
url: '/system/role/authUser/cancel', |
||||
method: 'put', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 批量取消用户授权角色
|
||||
export function authUserCancelAll(data) { |
||||
return request({ |
||||
url: '/system/role/authUser/cancelAll', |
||||
method: 'put', |
||||
params: data |
||||
}) |
||||
} |
||||
|
||||
// 授权用户选择
|
||||
export function authUserSelectAll(data) { |
||||
return request({ |
||||
url: '/system/role/authUser/selectAll', |
||||
method: 'put', |
||||
params: data |
||||
}) |
||||
} |
||||
|
||||
// 根据角色ID查询部门树结构
|
||||
export function deptTreeSelect(roleId) { |
||||
return request({ |
||||
url: '/system/role/deptTree/', |
||||
params: {roleId}, |
||||
method: 'get' |
||||
}) |
||||
} |
@ -0,0 +1,137 @@ |
||||
import request from '@/utils/request' |
||||
import { parseStrEmpty } from "@/utils/ruoyi"; |
||||
|
||||
// 查询用户列表
|
||||
export function listUser(query) { |
||||
return request({ |
||||
url: '/system/user/list', |
||||
method: 'get', |
||||
params: query |
||||
}) |
||||
} |
||||
|
||||
// 查询用户详细
|
||||
export function getUser(userId) { |
||||
return request({ |
||||
url: '/system/user/getInfo', |
||||
params: {userId}, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 新增用户
|
||||
export function addUser(data) { |
||||
return request({ |
||||
url: '/system/user/add', |
||||
method: 'post', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 修改用户
|
||||
export function updateUser(data) { |
||||
return request({ |
||||
url: '/system/user', |
||||
method: 'put', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 删除用户
|
||||
export function delUser(userId) { |
||||
return request({ |
||||
url: '/system/user/remove', |
||||
params: {userId}, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
// 用户密码重置
|
||||
export function resetUserPwd(userId, password) { |
||||
const data = { |
||||
userId, |
||||
password |
||||
} |
||||
return request({ |
||||
url: '/system/user/resetPwd', |
||||
method: 'put', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 用户状态修改
|
||||
export function changeUserStatus(userId, status) { |
||||
const data = { |
||||
userId, |
||||
status |
||||
} |
||||
return request({ |
||||
url: '/system/user/changeStatus', |
||||
method: 'put', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 查询用户个人信息
|
||||
export function getUserProfile() { |
||||
return request({ |
||||
url: '/system/user/profile', |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 修改用户个人信息
|
||||
export function updateUserProfile(data) { |
||||
return request({ |
||||
url: '/system/user/profile/updateProfile', |
||||
method: 'put', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 用户密码重置
|
||||
export function updateUserPwd(oldPassword, newPassword) { |
||||
const data = { |
||||
oldPassword, |
||||
newPassword |
||||
} |
||||
return request({ |
||||
url: '/system/user/profile/updatePwd', |
||||
method: 'put', |
||||
params: data |
||||
}) |
||||
} |
||||
|
||||
// 用户头像上传
|
||||
export function uploadAvatar(data) { |
||||
return request({ |
||||
url: '/system/user/profile/avatar', |
||||
method: 'post', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 查询授权角色
|
||||
export function getAuthRole(userId) { |
||||
return request({ |
||||
url: '/system/user/authRole/' + userId, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 保存授权角色
|
||||
export function updateAuthRole(data) { |
||||
return request({ |
||||
url: '/system/user/authRole', |
||||
method: 'put', |
||||
params: data |
||||
}) |
||||
} |
||||
|
||||
// 查询部门下拉树结构
|
||||
export function deptTreeSelect() { |
||||
return request({ |
||||
url: '/system/user/deptTree', |
||||
method: 'get' |
||||
}) |
||||
} |
@ -0,0 +1,76 @@ |
||||
import request from '@/utils/request' |
||||
|
||||
// 查询生成表数据
|
||||
export function listTable(query) { |
||||
return request({ |
||||
url: '/tool/gen/list', |
||||
method: 'get', |
||||
params: query |
||||
}) |
||||
} |
||||
// 查询db数据库列表
|
||||
export function listDbTable(query) { |
||||
return request({ |
||||
url: '/tool/gen/db/list', |
||||
method: 'get', |
||||
params: query |
||||
}) |
||||
} |
||||
|
||||
// 查询表详细信息
|
||||
export function getGenTable(tableId) { |
||||
return request({ |
||||
url: '/tool/gen/' + tableId, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 修改代码生成信息
|
||||
export function updateGenTable(data) { |
||||
return request({ |
||||
url: '/tool/gen', |
||||
method: 'put', |
||||
data: data |
||||
}) |
||||
} |
||||
|
||||
// 导入表
|
||||
export function importTable(data) { |
||||
return request({ |
||||
url: '/tool/gen/importTable', |
||||
method: 'post', |
||||
params: data |
||||
}) |
||||
} |
||||
|
||||
// 预览生成代码
|
||||
export function previewTable(tableId) { |
||||
return request({ |
||||
url: '/tool/gen/preview/' + tableId, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 删除表数据
|
||||
export function delTable(tableId) { |
||||
return request({ |
||||
url: '/tool/gen/' + tableId, |
||||
method: 'delete' |
||||
}) |
||||
} |
||||
|
||||
// 生成代码(自定义路径)
|
||||
export function genCode(tableName) { |
||||
return request({ |
||||
url: '/tool/gen/genCode/' + tableName, |
||||
method: 'get' |
||||
}) |
||||
} |
||||
|
||||
// 同步数据库
|
||||
export function synchDb(tableName) { |
||||
return request({ |
||||
url: '/tool/gen/synchDb/' + tableName, |
||||
method: 'get' |
||||
}) |
||||
} |
@ -0,0 +1,433 @@ |
||||
import axios from "@/utils/request"; |
||||
const baseURL = import.meta.env.VITE_APP_BASE_PROCESS_API; |
||||
/** |
||||
* @description 获取流程图列表 |
||||
* @param {Object} data - 查询参数对象 |
||||
* @param {string} [data.firstResult] - 起始索引 |
||||
* @param {string} [data.maxResults] - 最大结果数 |
||||
* @param {boolean} [data.latestVersion] - 是否最新版本 |
||||
* @returns {Promise} 返回流程图列表数据 |
||||
*/ |
||||
export const getProcessList = ({ |
||||
firstResult = 0, |
||||
maxResults = 8, |
||||
latestVersion = true, |
||||
}) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: "/engine-rest/process-definition", |
||||
method: "get", |
||||
params: { |
||||
firstResult, |
||||
maxResults, |
||||
latestVersion, |
||||
}, |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
/** |
||||
* @description 获取流程图信息 |
||||
* @param {string} processId - 流程图ID |
||||
* @returns {Promise} 返回流程图信息数据 |
||||
*/ |
||||
export const getProcessInfo = (processId) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: `/engine-rest/process-definition/${processId}`, |
||||
method: "get", |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
/** |
||||
* @description 获取流程图xml |
||||
* @param {string} processId - 流程图ID |
||||
* @returns {Promise} 返回流程图xml数据 |
||||
*/ |
||||
export const getProcessXml = (processId) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: `/engine-rest/process-definition/${processId}/xml`, |
||||
method: "get", |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
|
||||
/** |
||||
* @description 上传流程图 |
||||
* @param {FormData} data - 流程图数据 |
||||
* @param {Blob} [data.content] - 流程图文件 formData.append('content', bpmnBlob, 'process.bpmn'); // 文件名应以 .bpmn 结尾
|
||||
* @returns {Promise} 返回上传结果 |
||||
*/ |
||||
export const addModeler = (data) => { |
||||
return axios.request({ |
||||
baseURL, |
||||
url: "/engine-rest/deployment/create", |
||||
headers: { |
||||
"Content-Type": "multipart/form-data", |
||||
}, |
||||
method: "post", |
||||
data: data, |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
|
||||
/** |
||||
* @description 删除流程图 |
||||
* @param {string} processId - 流程图ID |
||||
* @returns {Promise} 返回删除结果 |
||||
*/ |
||||
export const deleteProcess = (processId) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: `/engine-rest/process-definition/${processId}`, |
||||
method: "delete", |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
|
||||
/** |
||||
* @description 创建流程实例 |
||||
* @param {object} data |
||||
* @param {string} data.processKey - 流程图key |
||||
* @param {string} data.formId - 表单ID |
||||
* @param {string} data.createUser - 创建人 |
||||
* @param {object} data.formValues - 填写的表单数据 |
||||
* @returns {Promise} 返回创建结果 |
||||
*/ |
||||
export const start = (data) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: `/start`, |
||||
method: "post", |
||||
data: data, |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
|
||||
//------instance
|
||||
|
||||
/** |
||||
* @description 获取流程实例列表 |
||||
* @param {Object} data - 查询参数对象 |
||||
* @param {string} [data.firstResult] - 起始索引 |
||||
* @param {string} [data.maxResults] - 最大结果数 |
||||
* @param {string} [data.processDefinitionKey] - 流程图key |
||||
* @param {string} [data.sortOrder] - 排序方式 asc/desc |
||||
* @param {string} [data.sortBy] - 排序字段 startTime |
||||
* @returns {Promise} 返回流程图实例列表数据 |
||||
*/ |
||||
export const getProcessInstanceList = ({ |
||||
firstResult = 0, |
||||
maxResults = 8, |
||||
processDefinitionKey, |
||||
sortOrder = "desc", |
||||
sortBy = "startTime", |
||||
}) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: "/engine-rest/history/process-instance", |
||||
method: "get", |
||||
params: { |
||||
firstResult, |
||||
maxResults, |
||||
processDefinitionKey, |
||||
sortOrder, |
||||
sortBy, |
||||
}, |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
|
||||
/** |
||||
* @description 删除流程实例 |
||||
* @param {string} processInstanceId - 流程实例ID |
||||
* @returns {Promise} 返回删除结果 |
||||
*/ |
||||
|
||||
export const deleteProcessInstance = (processInstanceId) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: `/engine-rest/process-instance/${processInstanceId}`, |
||||
method: "delete", |
||||
// data: arg,
|
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
|
||||
///TASK----------
|
||||
/** |
||||
* @description 获取流程实例下的任务 |
||||
* @param {Object} data - 查询参数对象 |
||||
* @param {string} [data.firstResult] - 起始索引 |
||||
* @param {string} [data.maxResults] - 最大结果数 |
||||
* @param {string} [data.processInstanceId] - 流程实例ID |
||||
* @returns {Promise} 返回任务列表数据 |
||||
*/ |
||||
export const getInstanceTaskList = ({ |
||||
firstResult = 0, |
||||
maxResults = 8, |
||||
processInstanceId, |
||||
}) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: "/engine-rest/history/task", |
||||
method: "get", |
||||
params: { |
||||
firstResult, |
||||
maxResults, |
||||
processInstanceId, |
||||
}, |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
/** |
||||
* @description 查询任务节点候选人/组 |
||||
* @param {string} taskId - 任务ID |
||||
* @returns {Promise} 返回任务候选人/组数据 |
||||
*/ |
||||
export const getTaskCandidate = (taskId) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: `/engine-rest/task/${taskId}/identity-links`, |
||||
method: "get", |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
/** |
||||
* @description 添加节点候选人/组 |
||||
* @param {object} data |
||||
* @param {string} data.taskId - 任务ID |
||||
* @param {string} data.type - 类型 candidate,assignee |
||||
* @param {string} data.userId - 用户ID(二选一) |
||||
* @param {string} data.groupId - 组ID(二选一) |
||||
* @returns {Promise} 返回添加结果 |
||||
*/ |
||||
export const addTaskCandidate = (data) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: `/engine-rest/task/${taskId}/identity-links`, |
||||
method: "post", |
||||
data: data, |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
|
||||
/** |
||||
* @description 删除节点候选人/组 |
||||
* @param {object} data |
||||
* @param {string} data.taskId - 任务ID |
||||
* @param {string} data.type - 类型 candidate,assignee |
||||
* @param {string} data.userId - 用户ID(二选一) |
||||
* @param {string} data.groupId - 组ID(二选一) |
||||
* @returns {Promise} 返回删除结果 |
||||
*/ |
||||
export const deleteTaskCandidate = (data) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: `/engine-rest/task/${data.taskId}/identity-links/delete`, |
||||
method: "post", |
||||
data: data, |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
|
||||
/** |
||||
* @description 获取任务列表 |
||||
* @param {Object} data - 查询参数对象 |
||||
* @param {string} [data.firstResult] - 起始索引 |
||||
* @param {string} [data.maxResults] - 最大结果数 |
||||
* @param {string} [data.assignee] - 执行人ID |
||||
* @param {string} [data.candidateUser] - 候选人ID(二选一) |
||||
* @param {string} [data.candidateGroup] - 候选组ID(二选一) |
||||
* @returns {Promise} 返回任务列表数据 |
||||
*/ |
||||
export const getUserTaskList = ({ |
||||
firstResult = 0, |
||||
maxResults = 8, |
||||
assignee, |
||||
candidateUser, |
||||
candidateGroup, |
||||
}) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: "/engine-rest/task", |
||||
method: "get", |
||||
params: { |
||||
firstResult, |
||||
maxResults, |
||||
assignee, |
||||
candidateUser, |
||||
candidateGroup, |
||||
}, |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
/** |
||||
* @description 认领任务 |
||||
* @param {object} data |
||||
* @param {string} data.taskId - 任务ID |
||||
* @param {string} data.userId - 用户ID |
||||
* @returns {Promise} 返回认领结果 |
||||
*/ |
||||
|
||||
export const claim = (data) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: `/engine-rest/task/${data.taskId}/claim`, |
||||
method: "post", |
||||
data: data, |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
/** |
||||
* @description 取消任务执行人 |
||||
* @param {string} taskId - 任务ID |
||||
* @returns {Promise} 返回取消结果 |
||||
*/ |
||||
// 取消任务执行人:
|
||||
export const unclaim = (taskId) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: `/engine-rest/task/${taskId}/unclaim`, |
||||
method: "post", |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
/** |
||||
* @description 完成任务 |
||||
* @param {Object} data - 包含任务完成相关信息的对象参数,具体结构如下: |
||||
* @param {string} data.taskId - 任务ID,用于唯一标识需要完成的具体任务,是一个字符串类型的值,通常由系统分配并在任务流转过程中传递使用。 |
||||
* @param {Object} data.variables - 任务变量对象,用于携带任务执行过程中涉及的各类变量信息,其内部包含具体的业务相关变量,结构如下: |
||||
* @param {Object} data.variables.approvalResult - 与审批结果相关的变量对象,用于传递审批相关信息,包含以下属性: |
||||
* @param {"approved" | "rejected"} data.variables.approvalResult.value - 审批结果,取值为 'approved' 表示审批通过,'rejected' 表示审批未通过,类型为字符串。 |
||||
* @param {"String"} data.variables.approvalResult.type - 变量类型标识,此处固定为 'String',表明审批结果变量的数据类型是字符串类型,用于系统在处理变量时进行类型校验等操作。 |
||||
* @returns {Promise} 返回完成结果 |
||||
*/ |
||||
export const complete = (data) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: `/engine-rest/task/${data.taskId}/complete`, |
||||
method: "post", |
||||
data: { |
||||
variables: data.variables, |
||||
}, |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
/** |
||||
* @description 创建评论--自定义任务执行结果变量 |
||||
* @param {object} data |
||||
* @param {string} data.taskId - 任务ID |
||||
* @param {json} data.message - 评论内容-json字符串 |
||||
* @returns {Promise} 返回创建结果 |
||||
*/ |
||||
export const setComment = (data) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: `/engine-rest/task/${data.taskId}/comment/create`, |
||||
method: "post", |
||||
data: data, |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
|
||||
//-Form----------
|
||||
|
||||
/** |
||||
* @description 获取流程表单列表 |
||||
* @param {object} data |
||||
* @param {string} [data.page] - 页码 |
||||
* @param {string} [data.start] - 起始索引 |
||||
* @param {string} [data.limit] - 最大结果数 |
||||
* @returns {Promise} 返回流程表单列表数据 |
||||
*/ |
||||
export const getFormList = (data) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: "/form", |
||||
method: "get", |
||||
params: data, |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
/** |
||||
* @description 获取流程表单详情 |
||||
* @param {string} formId |
||||
* @returns {Promise} 返回流程表单详情数据 |
||||
*/ |
||||
export const getFormDetail = (formId) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: `/form/${formId}`, |
||||
method: "get", |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
/** |
||||
* @description 获取流程表单字段 |
||||
* @param {string} path |
||||
* @returns {Promise} 返回流程表单字段数据 |
||||
*/ |
||||
export const getFormFields = (path) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: `/form/fields`, |
||||
method: "get", |
||||
params: { |
||||
path, |
||||
}, |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
|
||||
/** |
||||
* @description 添加流程表单 |
||||
* @param {object} data |
||||
* @param {string} data.formName - 表单名称 |
||||
* @param {string} data.formDesc - 表单描述 |
||||
* @param {string} data.formPath - 表单内容 |
||||
* @param {string} data.userId - 创建人ID |
||||
* @returns {Promise} 返回添加结果 |
||||
*/ |
||||
export const addForm = (data) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: "/form", |
||||
method: "post", |
||||
data: data, |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
/** |
||||
* @description 修改流程表单 |
||||
* @param {object} data |
||||
* @param {string} data.id - 表单ID |
||||
* @param {string} data.formName - 表单名称 |
||||
* @param {string} data.formDesc - 表单描述 |
||||
* @param {string} data.formPath - 表单内容 |
||||
* @returns {Promise} 返回修改结果 |
||||
*/ |
||||
export const updateForm = (data) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: "/form", |
||||
method: "put", |
||||
data: data, |
||||
dataType: "json", |
||||
}); |
||||
}; |
||||
|
||||
/** |
||||
* @description 删除流程表单 |
||||
* @param {string} formId |
||||
* @returns {Promise} 返回删除结果 |
||||
*/ |
||||
// 删除数据:
|
||||
export const deleteForm = (formId) => { |
||||
return axios.request({ |
||||
baseURL: baseURL, |
||||
url: "/form/" + formId, |
||||
method: "delete", |
||||
dataType: "json", |
||||
}); |
||||
}; |
After Width: | Height: | Size: 160 KiB |
After Width: | Height: | Size: 96 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 1.4 KiB |