Squashed commit of the following:
commit 70b72fd2d6739ea06e29abc9caa56e4140dce1a4
Author: sc <shencheng@heronshn.com>
Date: Thu Sep 16 10:55:11 2021 +0800
UP ver 1.2.5
commit 09244727f56c27f2a0c76b059e45d67047de7dd2
Author: sakuya <81883387@qq.com>
Date: Wed Sep 15 22:56:36 2021 +0800
up
commit 3368c197b787500f47923107600bf38ca880dbcb
Author: sc <shencheng@heronshn.com>
Date: Wed Sep 15 17:06:07 2021 +0800
scWorkflow
commit 53c5d6b4b11d3b3da329974e17b7f671962ec32a
Author: sc <shencheng@heronshn.com>
Date: Tue Sep 14 16:59:34 2021 +0800
add scWorkflow
commit cadb084e378e5157ec8fda5e015c2e3def3c60cf
Author: sakuya <81883387@qq.com>
Date: Mon Sep 13 23:06:24 2021 +0800
add Dingding workflow
commit 2f2aefef10e59467ad5c897d5c520c1edbe179cf
Author: sc <shencheng@heronshn.com>
Date: Mon Sep 13 15:51:31 2021 +0800
scTable 增加自定义列的 保存 读取和重置钩子
commit 161a5dbf9868d0d98d802a051fdf34c884f8bbf0
Author: sc <shencheng@heronshn.com>
Date: Fri Sep 10 14:05:33 2021 +0800
ADD 标签操作类
commit 7b45fd1cf522e1d1e262326ae66a0054007d5dc9
Author: sc <shencheng@heronshn.com>
Date: Thu Sep 9 17:08:24 2021 +0800
ad 标签操作类
commit b75860732f44ffe047547d704861c58e1e3fc419
Author: sc <shencheng@heronshn.com>
Date: Thu Sep 9 13:06:14 2021 +0800
Update index.js
commit 57fe306f4136b77f4a72663ea9b06777c83f2d3e
Author: sc <shencheng@heronshn.com>
Date: Wed Sep 8 16:30:03 2021 +0800
Update index.vue
- 继承所有属性至el-table
- 删除1对1转发原装方法&事件
commit 4f9c632122e03b849c1766bd4b584cc8b5b949d0
Author: sc <shencheng@heronshn.com>
Date: Wed Sep 8 15:07:18 2021 +0800
scFormTable add dragSort prop 是否开启拖拽排序
commit d6938fecb6de8c138d96a4c9f3858dcac68a525f
Author: sc <shencheng@heronshn.com>
Date: Sat Sep 4 11:57:03 2021 +0800
模板-日历计划 使用 $TOOL.dateFormat 错误
commit cda7f97bd6480359813c1c9e2fbbcc3708df3f5f
Author: sc <shencheng@heronshn.com>
Date: Sat Sep 4 10:55:44 2021 +0800
版本信息部件增加最新版本请求,FIX 版本信息部件命名错误
commit ece9c74f8cf5c039b4dcfe962ced1298d59085d6
Author: sc <shencheng@heronshn.com>
Date: Sat Sep 4 10:33:05 2021 +0800
add v-copy directive
commit 1af7241b9f26916b33d7a9952ee12dfd8ee6855f
Author: sc <shencheng@heronshn.com>
Date: Thu Sep 2 10:48:33 2021 +0800
FIX scTable 因为返回数据格式错误导致parseData报错
This commit is contained in:
parent
326898bb85
commit
0c28eb2648
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "scui",
|
||||
"version": "1.2.4",
|
||||
"version": "1.2.5",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
|
|
|
|||
|
|
@ -1,26 +1,11 @@
|
|||
/**
|
||||
* 所有接口集合
|
||||
* 每个接口对象需含有以下字段
|
||||
* 开发者可将不同的业务模块细化分离处理
|
||||
* @param {接口地址} url
|
||||
* @param {接口名称描述} name
|
||||
* @param {请求类型 get|post|put|patch|delete} type
|
||||
* @description 自动import导入所有 api 模块
|
||||
*/
|
||||
|
||||
//公共模块
|
||||
import common from './model/common'
|
||||
//授权模块
|
||||
import auth from './model/auth'
|
||||
//系统模块
|
||||
import system from './model/system'
|
||||
//演示模块
|
||||
import demo from './model/demo'
|
||||
const files = require.context('./model', false, /\.js$/)
|
||||
const modules = {}
|
||||
files.keys().forEach((key) => {
|
||||
modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default
|
||||
})
|
||||
|
||||
const api = {
|
||||
common,
|
||||
auth,
|
||||
system,
|
||||
demo
|
||||
}
|
||||
|
||||
export default api;
|
||||
export default modules
|
||||
|
|
|
|||
|
|
@ -2,6 +2,13 @@ import config from "@/config"
|
|||
import http from "@/utils/request"
|
||||
|
||||
export default {
|
||||
ver: {
|
||||
url: `${config.API_URL}/demo/ver`,
|
||||
name: "获取最新版本号",
|
||||
get: async function(){
|
||||
return await http.get(this.url);
|
||||
}
|
||||
},
|
||||
post: {
|
||||
url: `${config.API_URL}/demo/post`,
|
||||
name: "分页列表",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="sc-form-table">
|
||||
<el-table :data="data" border stripe>
|
||||
<el-table :data="data" ref="table" :key="toggleIndex" border stripe>
|
||||
<el-table-column type="index" width="50" fixed="left">
|
||||
<template #header>
|
||||
<el-button type="primary" icon="el-icon-plus" size="mini" circle @click="rowAdd"></el-button>
|
||||
|
|
@ -8,10 +8,15 @@
|
|||
<template #default="scope">
|
||||
<div class="sc-form-table-handle">
|
||||
<span>{{scope.$index + 1}}</span>
|
||||
<el-button type="danger" icon="el-icon-delete" size="mini" circle @click="rowDel(scope.row, scope.$index)"></el-button>
|
||||
<el-button type="danger" icon="el-icon-delete" size="mini" plain circle @click="rowDel(scope.row, scope.$index)"></el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="" width="51" v-if="dragSort">
|
||||
<template #default>
|
||||
<el-tag class="move" style="cursor: move;"><i class="el-icon-d-caret"></i></el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<slot></slot>
|
||||
<el-table-column min-width="1"></el-table-column>
|
||||
<template #empty>
|
||||
|
|
@ -22,19 +27,26 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import Sortable from 'sortablejs'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
modelValue: { type: Array, default: () => [] },
|
||||
addTemplate: { type: Object, default: () => {} },
|
||||
placeholder: { type: String, default: "暂无数据" }
|
||||
placeholder: { type: String, default: "暂无数据" },
|
||||
dragSort: { type: Boolean, default: false }
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
data: [],
|
||||
toggleIndex: 0
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
this.data = this.modelValue
|
||||
if(this.dragSort){
|
||||
this.rowDrop()
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
modelValue(){
|
||||
|
|
@ -48,6 +60,24 @@
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
rowDrop(){
|
||||
const _this = this
|
||||
const tbody = this.$refs.table.$el.querySelector('.el-table__body-wrapper tbody')
|
||||
Sortable.create(tbody, {
|
||||
handle: ".move",
|
||||
animation: 300,
|
||||
ghostClass: "ghost",
|
||||
onEnd({ newIndex, oldIndex }) {
|
||||
const tableData = _this.data
|
||||
const currRow = tableData.splice(oldIndex, 1)[0]
|
||||
tableData.splice(newIndex, 0, currRow)
|
||||
_this.toggleIndex += 1
|
||||
_this.$nextTick(() => {
|
||||
_this.rowDrop()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
rowAdd(){
|
||||
this.data.push({...this.addTemplate})
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="usercolumn.length>0" class="setting-column">
|
||||
<div v-if="usercolumn.length>0" class="setting-column" v-loading="isSave">
|
||||
<div class="setting-column__title">
|
||||
<span class="move_b"></span>
|
||||
<span class="show_b">显示</span>
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
<span class="sortable_b">排序</span>
|
||||
<span class="fixed_b">固定</span>
|
||||
</div>
|
||||
<div class="setting-column__list" ref="list" v-loading="isSave">
|
||||
<div class="setting-column__list" ref="list">
|
||||
<ul>
|
||||
<li v-for="item in usercolumn" :key="item.prop">
|
||||
<span class="move_b">
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
</div>
|
||||
<div class="setting-column__bottom">
|
||||
<el-button @click="backDefaul" :disabled="isSave">重置</el-button>
|
||||
<el-button @click="save" :loading="isSave" type="primary">保存</el-button>
|
||||
<el-button @click="save" type="primary">保存</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-empty v-else description="暂无可配置的列" :image-size="80"></el-empty>
|
||||
|
|
@ -81,7 +81,7 @@
|
|||
})
|
||||
},
|
||||
backDefaul(){
|
||||
this.usercolumn = JSON.parse(JSON.stringify(this.column||[]))
|
||||
this.$emit('back', this.usercolumn)
|
||||
},
|
||||
save(){
|
||||
this.$emit('save', this.usercolumn)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="scTable" ref="scTableMain" v-loading="loading">
|
||||
<div class="scTable-table">
|
||||
<el-table :data="tableData" :row-key="rowKey" :key="toggleIndex" ref="scTable" :height="tableHeight" :stripe="stripe" :highlight-current-row="highlightCurrentRow" :show-summary="showSummary" :summary-method="summaryMethod" @selection-change="selectionChange" @current-change="currentChange" @row-click="rowClick" @sort-change="sortChange" @filter-change="filterChange">
|
||||
<el-table v-bind="$attrs" :data="tableData" :row-key="rowKey" :key="toggleIndex" ref="scTable" :height="tableHeight" @sort-change="sortChange" @filter-change="filterChange">
|
||||
<slot></slot>
|
||||
<template v-for="(item, index) in userColumn" :key="index">
|
||||
<el-table-column v-if="!item.hide" :column-key="item.prop" :label="item.label" :prop="item.prop" :width="item.width" :sortable="item.sortable" :fixed="item.fixed" :filters="item.filters" :filter-method="remoteFilter||!item.filters?null:filterHandler">
|
||||
|
|
@ -24,11 +24,11 @@
|
|||
</div>
|
||||
<div class="scTable-do" v-if="!hideDo">
|
||||
<el-button @click="refresh" icon="el-icon-refresh" circle style="margin-left:15px"></el-button>
|
||||
<el-popover placement="top" title="列设置" :width="500" trigger="click">
|
||||
<el-popover v-if="column" placement="top" title="列设置" :width="500" trigger="click" @show="customColumnShow=true" @after-leave="customColumnShow=false">
|
||||
<template #reference>
|
||||
<el-button icon="el-icon-setting" circle style="margin-left:15px"></el-button>
|
||||
</template>
|
||||
<columnSetting ref="columnSetting" @userChange="columnSettingChange" @save="columnSettingSave" :column="column"></columnSetting>
|
||||
<columnSetting v-if="customColumnShow" ref="columnSetting" @userChange="columnSettingChange" @save="columnSettingSave" @back="columnSettingBack" :column="userColumn"></columnSetting>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -55,10 +55,6 @@
|
|||
remoteFilter: { type: Boolean, default: false },
|
||||
hidePagination: { type: Boolean, default: false },
|
||||
hideDo: { type: Boolean, default: false },
|
||||
stripe: { type: Boolean, default: false },
|
||||
highlightCurrentRow: { type: Boolean, default: false },
|
||||
showSummary: { type: Boolean, default: false },
|
||||
summaryMethod: { type: Function, default: () => {} },
|
||||
paginationLayout: { type: String, default: "total, prev, pager, next, jumper" },
|
||||
},
|
||||
watch: {
|
||||
|
|
@ -85,10 +81,18 @@
|
|||
loading: false,
|
||||
tableHeight:'100%',
|
||||
tableParams: this.params,
|
||||
userColumn: this.column
|
||||
userColumn: [],
|
||||
customColumnShow: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
//判断是否开启自定义列
|
||||
if(this.column){
|
||||
this.getCustomColumn()
|
||||
}else{
|
||||
this.userColumn = this.column
|
||||
}
|
||||
//判断是否静态数据
|
||||
if(this.apiObj){
|
||||
this.getData();
|
||||
}else if(this.data){
|
||||
|
|
@ -117,6 +121,11 @@
|
|||
upTableHeight(){
|
||||
this.tableHeight = (this.$refs.scTableMain.offsetHeight - 50 ) + "px"
|
||||
},
|
||||
//获取列
|
||||
async getCustomColumn(){
|
||||
const userColumn = await config.columnSettingGet(this.tableName, this.column)
|
||||
this.userColumn = userColumn
|
||||
},
|
||||
//获取数据
|
||||
async getData(){
|
||||
this.loading = true;
|
||||
|
|
@ -139,7 +148,13 @@
|
|||
this.emptyText = error.statusText;
|
||||
return false;
|
||||
}
|
||||
var response = config.parseData(res);
|
||||
try {
|
||||
var response = config.parseData(res);
|
||||
}catch(error){
|
||||
this.loading = false;
|
||||
this.emptyText = "数据格式错误";
|
||||
return false;
|
||||
}
|
||||
if(response.code != 200){
|
||||
this.loading = false;
|
||||
this.emptyText = response.msg;
|
||||
|
|
@ -186,8 +201,29 @@
|
|||
this.toggleIndex += 1;
|
||||
},
|
||||
//自定义列保存
|
||||
columnSettingSave(userColumn){
|
||||
config.columnSettingSave(this.tableName, userColumn, this.$refs.columnSetting)
|
||||
async columnSettingSave(userColumn){
|
||||
this.$refs.columnSetting.isSave = true
|
||||
try {
|
||||
await config.columnSettingSave(this.tableName, userColumn)
|
||||
}catch(error){
|
||||
this.$message.error('保存失败')
|
||||
this.$refs.columnSetting.isSave = false
|
||||
}
|
||||
this.$message.success('保存成功')
|
||||
this.$refs.columnSetting.isSave = false
|
||||
},
|
||||
//自定义列重置
|
||||
async columnSettingBack(){
|
||||
this.$refs.columnSetting.isSave = true
|
||||
try {
|
||||
const column = await config.columnSettingReset(this.tableName, this.column)
|
||||
this.userColumn = column
|
||||
this.$refs.columnSetting.usercolumn = JSON.parse(JSON.stringify(this.userColumn||[]))
|
||||
}catch(error){
|
||||
this.$message.error('重置失败')
|
||||
this.$refs.columnSetting.isSave = false
|
||||
}
|
||||
this.$refs.columnSetting.isSave = false
|
||||
},
|
||||
//排序事件
|
||||
sortChange(obj){
|
||||
|
|
@ -217,16 +253,6 @@
|
|||
filters[key] = filters[key].join(',')
|
||||
})
|
||||
this.upData(filters)
|
||||
},
|
||||
//转发原装方法&事件
|
||||
selectionChange(selection){
|
||||
this.$emit('selection-change', selection)
|
||||
},
|
||||
currentChange(selection){
|
||||
this.$emit('current-change', selection)
|
||||
},
|
||||
rowClick(row, column, event){
|
||||
this.$emit('row-click', row, column, event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,141 @@
|
|||
<!--
|
||||
* @Descripttion: 仿钉钉流程设计器
|
||||
* @version: 1.0
|
||||
* @Author: sakuya
|
||||
* @Date: 2021年9月14日08:38:35
|
||||
* @LastEditors:
|
||||
* @LastEditTime:
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div class="sc-workflow-design">
|
||||
<div class="box-scale">
|
||||
<node-wrap v-model="nodeConfig"></node-wrap>
|
||||
<div class="end-node">
|
||||
<div class="end-node-circle"></div>
|
||||
<div class="end-node-text">流程结束</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import nodeWrap from './nodeWrap'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
modelValue: { type: Object, default: () => {} }
|
||||
},
|
||||
components: {
|
||||
nodeWrap
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
nodeConfig: this.modelValue
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.sc-workflow-design {width: 100%;}
|
||||
|
||||
.box-scale {display: inline-block;position: relative;width: 100%;padding: 54.5px 0px;align-items: flex-start;justify-content: center;flex-wrap: wrap;min-width: min-content;}
|
||||
|
||||
.node-wrap {display: inline-flex;width: 100%;flex-flow: column wrap;justify-content: flex-start;align-items: center;padding: 0px 50px;position: relative;z-index: 1;}
|
||||
.node-wrap-box {display: inline-flex;flex-direction: column;position: relative;width: 220px;min-height: 72px;flex-shrink: 0;background: rgb(255, 255, 255);border-radius: 4px;cursor: pointer;box-shadow: 0 2px 5px 0 rgba(0,0,0,.1);}
|
||||
|
||||
.node-wrap-box::before {content: "";position: absolute;top: -12px;left: 50%;transform: translateX(-50%);width: 0px;border-style: solid;border-width: 8px 6px 4px;border-color: rgb(202, 202, 202) transparent transparent;background: #f6f8f9;}
|
||||
.node-wrap-box.start-node:before {content: none}
|
||||
|
||||
.node-wrap-box .title {height:24px;line-height: 24px;color: #fff;padding-left: 16px;padding-right: 30px;border-radius: 4px 4px 0 0;position: relative;}
|
||||
.node-wrap-box .title .icon {margin-right: 5px;}
|
||||
.node-wrap-box .title .close {font-size: 15px;position: absolute;top:50%;transform: translateY(-50%);right:10px;display: none;}
|
||||
.node-wrap-box .content {position: relative;padding: 15px;}
|
||||
.node-wrap-box .content .placeholder {color: #999;}
|
||||
.node-wrap-box:hover .close {display: block;}
|
||||
|
||||
.add-node-btn-box {width: 240px;display: inline-flex;flex-shrink: 0;position: relative;z-index: 1;}
|
||||
.add-node-btn-box:before {content: "";position: absolute;top: 0px;left: 0px;right: 0px;bottom: 0px;z-index: -1;margin: auto;width: 2px;height: 100%;background-color: rgb(202, 202, 202);}
|
||||
.add-node-btn {user-select: none;width: 240px;padding: 20px 0px 32px;display: flex;justify-content: center;flex-shrink: 0;flex-grow: 1;}
|
||||
.add-node-btn span {}
|
||||
|
||||
.add-branch {justify-content: center;padding: 0px 10px;position: absolute;top: -16px;left: 50%;transform: translateX(-50%);transform-origin: center center;z-index: 1;display: inline-flex;align-items: center;}
|
||||
|
||||
.branch-wrap {display: inline-flex;width: 100%;}
|
||||
.branch-box-wrap {display: flex;flex-flow: column wrap;align-items: center;min-height: 270px;width: 100%;flex-shrink: 0;}
|
||||
|
||||
.col-box {display: inline-flex;flex-direction: column;align-items: center;position: relative;background: #f6f8f9;}
|
||||
.branch-box {display: flex;overflow: visible;min-height: 180px;height: auto;border-bottom: 2px solid #ccc;border-top: 2px solid #ccc;position: relative;margin-top: 15px;}
|
||||
.branch-box .col-box::before {content: "";position: absolute;top: 0px;left: 0px;right: 0px;bottom: 0px;z-index: 0;margin: auto;width: 2px;height: 100%;background-color: rgb(202, 202, 202);}
|
||||
|
||||
.condition-node {display: inline-flex;flex-direction: column;min-height: 220px;}
|
||||
.condition-node-box {padding-top: 30px;padding-right: 50px;padding-left: 50px;justify-content: center;align-items: center;flex-grow: 1;position: relative;display: inline-flex;flex-direction: column;}
|
||||
.condition-node-box::before {content: "";position: absolute;top: 0px;left: 0px;right: 0px;bottom: 0px;margin: auto;width: 2px;height: 100%;background-color: rgb(202, 202, 202);}
|
||||
|
||||
|
||||
.auto-judge {position: relative;width: 220px;min-height: 72px;background: rgb(255, 255, 255);border-radius: 4px;padding: 15px 15px;cursor: pointer;box-shadow: 0 2px 5px 0 rgba(0,0,0,.1);}
|
||||
.auto-judge::before {content: "";position: absolute;top: -12px;left: 50%;transform: translateX(-50%);width: 0px;border-style: solid;border-width: 8px 6px 4px;border-color: rgb(202, 202, 202) transparent transparent;background: rgb(245, 245, 247);}
|
||||
|
||||
.auto-judge .title {line-height: 16px;}
|
||||
.auto-judge .title .node-title {color: #15BC83;}
|
||||
.auto-judge .title .close {font-size: 15px;position: absolute;top:15px;right:15px;color: #999;display: none;}
|
||||
.auto-judge .title .priority-title {position: absolute;top:15px;right:15px;color: #999;}
|
||||
|
||||
.auto-judge .content {position: relative;padding-top: 15px;}
|
||||
.auto-judge .content .placeholder {color: #999;}
|
||||
|
||||
.auto-judge:hover {
|
||||
.close {display: block;}
|
||||
.priority-title {display: none;}
|
||||
}
|
||||
|
||||
.top-left-cover-line, .top-right-cover-line {position: absolute;height: 3px;width: 50%;background-color: #f6f8f9;top: -2px;}
|
||||
.bottom-left-cover-line, .bottom-right-cover-line {position: absolute;height: 3px;width: 50%;background-color: #f6f8f9;bottom: -2px;}
|
||||
|
||||
.top-left-cover-line {left: -1px;}
|
||||
.top-right-cover-line {right: -1px;}
|
||||
.bottom-left-cover-line {left: -1px;}
|
||||
.bottom-right-cover-line {right: -1px;}
|
||||
|
||||
|
||||
.end-node {border-radius: 50%;font-size: 14px;color: rgba(25,31,37,.4);text-align: left;}
|
||||
.end-node-circle {width: 10px;height: 10px;margin: auto;border-radius: 50%;background: #dbdcdc;}
|
||||
.end-node-text {margin-top: 5px;text-align: center;}
|
||||
|
||||
.auto-judge:hover {
|
||||
.sort-left {display: flex;}
|
||||
.sort-right {display: flex;}
|
||||
}
|
||||
|
||||
.auto-judge .sort-left {position: absolute;top: 0;bottom: 0;z-index: 1;left: 0;display: none;justify-content: center;align-items: center;flex-direction: column;}
|
||||
.auto-judge .sort-right {position: absolute;top: 0;bottom: 0;z-index: 1;right: 0;display: none;justify-content: center;align-items: center;flex-direction: column;}
|
||||
|
||||
.auto-judge .sort-left:hover, .auto-judge .sort-right:hover {background: #eee;}
|
||||
|
||||
.auto-judge:after {pointer-events: none;content: "";position: absolute;top:0;bottom:0;left:0;right:0;z-index: 2;border-radius: 4px;transition: all .1s;}
|
||||
.auto-judge:hover:after {border: 1px solid #3296fa;box-shadow: 0 0 6px 0 rgba(50,150,250,.3);}
|
||||
|
||||
.node-wrap-box:after {pointer-events: none;content: "";position: absolute;top:0;bottom:0;left:0;right:0;z-index: 2;border-radius: 4px;transition: all .1s;}
|
||||
.node-wrap-box:hover:after {border: 1px solid #3296fa;box-shadow: 0 0 6px 0 rgba(50,150,250,.3);}
|
||||
|
||||
[data-theme='dark'] {
|
||||
.node-wrap-box,.auto-judge {background: #2b2b2b;}
|
||||
.col-box {background: #222225;}
|
||||
.top-left-cover-line,
|
||||
.top-right-cover-line,
|
||||
.bottom-left-cover-line,
|
||||
.bottom-right-cover-line {background-color: #222225;}
|
||||
.node-wrap-box::before,.auto-judge::before {background-color: #222225;}
|
||||
.branch-box .add-branch {background: #222225;}
|
||||
.end-node .end-node-text {color: #d0d0d0;}
|
||||
.auto-judge .sort-left:hover, .auto-judge .sort-right:hover {background: #222225;}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
<template>
|
||||
<promoter v-if="nodeConfig.type==0" v-model="nodeConfig"></promoter>
|
||||
|
||||
<approver v-if="nodeConfig.type==1" v-model="nodeConfig"></approver>
|
||||
|
||||
<send v-if="nodeConfig.type==2" v-model="nodeConfig"></send>
|
||||
|
||||
<branch v-if="nodeConfig.type==4" v-model="nodeConfig">
|
||||
<template v-slot="slot">
|
||||
<node-wrap v-if="slot.node" v-model="slot.node.childNode"></node-wrap>
|
||||
</template>
|
||||
</branch>
|
||||
|
||||
<node-wrap v-if="nodeConfig.childNode" v-model="nodeConfig.childNode"></node-wrap>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import approver from './nodes/approver'
|
||||
import promoter from './nodes/promoter'
|
||||
import branch from './nodes/branch'
|
||||
import send from './nodes/send'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
modelValue: { type: Object, default: () => {} }
|
||||
},
|
||||
components: {
|
||||
approver,
|
||||
promoter,
|
||||
branch,
|
||||
send
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
nodeConfig: {},
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
modelValue(val){
|
||||
this.nodeConfig = val
|
||||
},
|
||||
nodeConfig(val){
|
||||
this.$emit("update:modelValue", val)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.nodeConfig = this.modelValue
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
<template>
|
||||
<div class="add-node-btn-box">
|
||||
<div class="add-node-btn">
|
||||
<el-popover placement="right-start" :width="300" v-model:visible="visible" :hide-after="0" :show-after="0">
|
||||
<template #reference>
|
||||
<el-button type="primary" icon="el-icon-plus" circle></el-button>
|
||||
</template>
|
||||
<div class="add-node-popover-body">
|
||||
<el-button icon="el-icon-user-solid" type="primary" circle plain @click="addType(1)"></el-button>
|
||||
<el-button icon="el-icon-s-promotion" type="primary" circle plain @click="addType(2)"></el-button>
|
||||
<el-button icon="el-icon-share" type="primary" circle plain @click="addType(4)"></el-button>
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
modelValue: { type: Object, default: () => {} }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
addType(type){
|
||||
var node = {}
|
||||
if (type == 1) {
|
||||
node = {
|
||||
nodeName: "审核人",
|
||||
type: 1,
|
||||
childNode: this.modelValue
|
||||
}
|
||||
}else if(type == 2){
|
||||
node = {
|
||||
nodeName: "抄送人",
|
||||
type: 2,
|
||||
childNode: this.modelValue
|
||||
}
|
||||
|
||||
}else if(type == 4){
|
||||
node = {
|
||||
nodeName: "条件路由",
|
||||
type: 4,
|
||||
conditionNodes: [
|
||||
{
|
||||
nodeName: "条件1",
|
||||
type: 3,
|
||||
priorityLevel: 1
|
||||
},
|
||||
{
|
||||
nodeName: "条件2",
|
||||
type: 3,
|
||||
priorityLevel: 2
|
||||
}
|
||||
],
|
||||
childNode: this.modelValue
|
||||
}
|
||||
|
||||
}
|
||||
this.$emit("update:modelValue", node)
|
||||
this.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
<template>
|
||||
<div class="node-wrap">
|
||||
<div class="node-wrap-box" @click="show">
|
||||
<div class="title" style="background: #ff943e;">
|
||||
<i class="icon el-icon-user-solid"></i>
|
||||
<span>{{ nodeConfig.nodeName }}</span>
|
||||
<i class="close el-icon-close" @click.stop="delNode()"></i>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span v-if="toText(nodeConfig)">{{ toText(nodeConfig) }}</span>
|
||||
<span v-else class="placeholder">请选择人员</span>
|
||||
</div>
|
||||
</div>
|
||||
<add-node v-model="nodeConfig.childNode"></add-node>
|
||||
<el-drawer title="审批人设置" v-model="drawer" destroy-on-close append-to-body>
|
||||
<el-container>
|
||||
<el-main style="padding:0 20px 20px 20px">
|
||||
<el-form label-position="top">
|
||||
<el-form-item label="">
|
||||
<el-input v-model="form.nodeName"></el-input>
|
||||
</el-form-item>
|
||||
<el-divider></el-divider>
|
||||
<el-form-item label="审批人员类型">
|
||||
<el-radio-group v-model="form.settype" class="clear">
|
||||
<el-radio :label="1">指定成员</el-radio>
|
||||
<el-radio :label="2">主管</el-radio>
|
||||
<el-radio :label="4">发起人自选</el-radio>
|
||||
<el-radio :label="5">发起人自己</el-radio>
|
||||
<el-radio :label="7">连续多级主管</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-divider></el-divider>
|
||||
</el-form>
|
||||
</el-main>
|
||||
<el-footer>
|
||||
<el-button type="primary" @click="save">保存</el-button>
|
||||
<el-button @click="drawer=false">取消</el-button>
|
||||
</el-footer>
|
||||
</el-container>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import addNode from './addNode'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
modelValue: { type: Object, default: () => {} }
|
||||
},
|
||||
components: {
|
||||
addNode
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
nodeConfig: {},
|
||||
drawer: false,
|
||||
form: {}
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
modelValue(){
|
||||
this.nodeConfig = this.modelValue
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.nodeConfig = this.modelValue
|
||||
},
|
||||
methods: {
|
||||
show(){
|
||||
this.form = {}
|
||||
this.form = {...this.nodeConfig}
|
||||
this.drawer = true
|
||||
},
|
||||
save(){
|
||||
this.$emit("update:modelValue", this.form)
|
||||
this.drawer = false
|
||||
},
|
||||
delNode(){
|
||||
this.$emit("update:modelValue", this.nodeConfig.childNode)
|
||||
},
|
||||
toText(nodeConfig){
|
||||
if(nodeConfig.settype == 1){
|
||||
if (nodeConfig.nodeUserList && nodeConfig.nodeUserList.length>0) {
|
||||
const users = nodeConfig.nodeUserList.map(item=>item.name).join(" 或 ")
|
||||
return users
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}else if (nodeConfig.settype == 2) {
|
||||
return "直接主管"
|
||||
}else if (nodeConfig.settype == 4) {
|
||||
return "发起人自选"
|
||||
}else if (nodeConfig.settype == 5) {
|
||||
return "发起人自己"
|
||||
}else if (nodeConfig.settype == 7) {
|
||||
return "连续多级主管"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
<template>
|
||||
<div class="branch-wrap">
|
||||
<div class="branch-box-wrap">
|
||||
<div class="branch-box">
|
||||
<el-button class="add-branch" type="success" plain round @click="addTerm">添加条件</el-button>
|
||||
<div class="col-box" v-for="(item,index) in nodeConfig.conditionNodes" :key="index">
|
||||
<div class="condition-node">
|
||||
<div class="condition-node-box">
|
||||
<div class="auto-judge" @click="show(index)">
|
||||
<div class="sort-left" v-if="index!=0" @click.stop="arrTransfer(index,-1)"><i class="el-icon-arrow-left"></i></div>
|
||||
<div class="title">
|
||||
<span class="node-title">{{ item.nodeName }}</span>
|
||||
<span class="priority-title">优先级{{item.priorityLevel}}</span>
|
||||
<i class="close el-icon-close" @click.stop="delTerm(index)"></i>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span v-if="toText(nodeConfig, index)">{{ toText(nodeConfig, index) }}</span>
|
||||
<span v-else class="placeholder">请设置条件</span>
|
||||
</div>
|
||||
<div class="sort-right" v-if="index!=nodeConfig.conditionNodes.length-1" @click.stop="arrTransfer(index)"><i class="el-icon-arrow-right"></i></div>
|
||||
</div>
|
||||
<add-node v-model="item.childNode"></add-node>
|
||||
</div>
|
||||
</div>
|
||||
<slot v-if="item.childNode" :node="item"></slot>
|
||||
<div class="top-left-cover-line" v-if="index==0"></div>
|
||||
<div class="bottom-left-cover-line" v-if="index==0"></div>
|
||||
<div class="top-right-cover-line" v-if="index==nodeConfig.conditionNodes.length-1"></div>
|
||||
<div class="bottom-right-cover-line" v-if="index==nodeConfig.conditionNodes.length-1"></div>
|
||||
</div>
|
||||
</div>
|
||||
<add-node v-model="nodeConfig.childNode"></add-node>
|
||||
</div>
|
||||
<el-drawer title="条件设置" v-model="drawer" destroy-on-close append-to-body>
|
||||
<el-container>
|
||||
<el-main style="padding:0 20px 20px 20px">
|
||||
<el-form label-position="top">
|
||||
<el-form-item label="">
|
||||
<el-input v-model="form.nodeName"></el-input>
|
||||
</el-form-item>
|
||||
<el-divider></el-divider>
|
||||
<el-form-item label="条件">
|
||||
{{ nodeConfig.conditionNodes[index].conditionList }}
|
||||
</el-form-item>
|
||||
<el-divider></el-divider>
|
||||
<p><el-button type="primary">增加条件</el-button></p>
|
||||
</el-form>
|
||||
</el-main>
|
||||
<el-footer>
|
||||
<el-button type="primary" @click="save">保存</el-button>
|
||||
<el-button @click="drawer=false">取消</el-button>
|
||||
</el-footer>
|
||||
</el-container>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import addNode from './addNode'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
modelValue: { type: Object, default: () => {} }
|
||||
},
|
||||
components: {
|
||||
addNode
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
nodeConfig: {},
|
||||
drawer: false,
|
||||
index: 0,
|
||||
form: {}
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
modelValue(){
|
||||
this.nodeConfig = this.modelValue
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.nodeConfig = this.modelValue
|
||||
},
|
||||
methods: {
|
||||
show(index){
|
||||
this.index = index
|
||||
this.form = {}
|
||||
this.form = {...this.nodeConfig.conditionNodes[index]}
|
||||
this.drawer = true
|
||||
},
|
||||
save(){
|
||||
this.nodeConfig.conditionNodes[this.index] = this.form
|
||||
this.$emit("update:modelValue", this.nodeConfig)
|
||||
this.drawer = false
|
||||
},
|
||||
addTerm(){
|
||||
let len = this.nodeConfig.conditionNodes.length + 1
|
||||
this.nodeConfig.conditionNodes.push({
|
||||
nodeName: "条件" + len,
|
||||
type: 3,
|
||||
priorityLevel: len
|
||||
})
|
||||
},
|
||||
delTerm(index){
|
||||
this.nodeConfig.conditionNodes.splice(index, 1)
|
||||
if (this.nodeConfig.conditionNodes.length == 1) {
|
||||
if (this.nodeConfig.childNode) {
|
||||
if (this.nodeConfig.conditionNodes[0].childNode) {
|
||||
this.reData(this.nodeConfig.conditionNodes[0].childNode, this.nodeConfig.childNode)
|
||||
}else{
|
||||
this.nodeConfig.conditionNodes[0].childNode = this.nodeConfig.childNode
|
||||
}
|
||||
}
|
||||
this.$emit("update:modelValue", this.nodeConfig.conditionNodes[0].childNode);
|
||||
}
|
||||
},
|
||||
reData(data, addData) {
|
||||
if (!data.childNode) {
|
||||
data.childNode = addData
|
||||
} else {
|
||||
this.reData(data.childNode, addData)
|
||||
}
|
||||
},
|
||||
arrTransfer(index, type = 1){
|
||||
this.nodeConfig.conditionNodes[index] = this.nodeConfig.conditionNodes.splice(index + type, 1, this.nodeConfig.conditionNodes[index])[0]
|
||||
this.nodeConfig.conditionNodes.map((item, index) => {
|
||||
item.priorityLevel = index + 1
|
||||
})
|
||||
this.$emit("update:modelValue", this.nodeConfig)
|
||||
},
|
||||
toText(nodeConfig, index){
|
||||
var { conditionList } = nodeConfig.conditionNodes[index]
|
||||
if (conditionList && conditionList.length > 0) {
|
||||
const text = conditionList.map(item => `${item.label}${item.operator}${item.value}`).join(" 和 ")
|
||||
return text
|
||||
}else{
|
||||
if(index == nodeConfig.conditionNodes.length - 1){
|
||||
return "其他条件进入此流程"
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<template>
|
||||
<div class="node-wrap">
|
||||
<div class="node-wrap-box start-node" @click="show">
|
||||
<div class="title" style="background: #576a95;">
|
||||
<i class="icon el-icon-user-solid"></i>
|
||||
<span>{{ nodeConfig.nodeName }}</span>
|
||||
</div>
|
||||
<div class="content">所有人</div>
|
||||
</div>
|
||||
<add-node v-model="nodeConfig.childNode"></add-node>
|
||||
<el-drawer title="发起人" v-model="drawer" destroy-on-close append-to-body>
|
||||
<el-container>
|
||||
<el-main style="padding:0 20px 20px 20px">
|
||||
<el-form label-position="top">
|
||||
<el-form-item label="">
|
||||
<el-input v-model="form.nodeName"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-main>
|
||||
<el-footer>
|
||||
<el-button type="primary" @click="save">保存</el-button>
|
||||
<el-button @click="drawer=false">取消</el-button>
|
||||
</el-footer>
|
||||
</el-container>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import addNode from './addNode'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
modelValue: { type: Object, default: () => {} }
|
||||
},
|
||||
components: {
|
||||
addNode
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
nodeConfig: {},
|
||||
drawer: false,
|
||||
form: {}
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
modelValue(){
|
||||
this.nodeConfig = this.modelValue
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.nodeConfig = this.modelValue
|
||||
},
|
||||
methods: {
|
||||
show(){
|
||||
this.form = {}
|
||||
this.form = {...this.nodeConfig}
|
||||
this.drawer = true
|
||||
},
|
||||
save(){
|
||||
this.$emit("update:modelValue", this.form)
|
||||
this.drawer = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
<template>
|
||||
<div class="node-wrap">
|
||||
<div class="node-wrap-box" @click="show">
|
||||
<div class="title" style="background: #3296fa;">
|
||||
<i class="icon el-icon-s-promotion"></i>
|
||||
<span>{{ nodeConfig.nodeName }}</span>
|
||||
<i class="close el-icon-close" @click.stop="delNode()"></i>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span v-if="toText(nodeConfig)">{{ toText(nodeConfig) }}</span>
|
||||
<span v-else class="placeholder">请选择人员</span>
|
||||
</div>
|
||||
</div>
|
||||
<add-node v-model="nodeConfig.childNode"></add-node>
|
||||
<el-drawer title="审批人设置" v-model="drawer" destroy-on-close append-to-body>
|
||||
<el-container>
|
||||
<el-main style="padding:0 20px 20px 20px">
|
||||
<el-form label-position="top">
|
||||
<el-form-item label="">
|
||||
<el-input v-model="form.nodeName"></el-input>
|
||||
</el-form-item>
|
||||
<el-divider></el-divider>
|
||||
<el-form-item label="">
|
||||
<el-checkbox v-model="form.ccSelfSelectFlag" label="允许发起人自选"></el-checkbox>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-main>
|
||||
<el-footer>
|
||||
<el-button type="primary" @click="save">保存</el-button>
|
||||
<el-button @click="drawer=false">取消</el-button>
|
||||
</el-footer>
|
||||
</el-container>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import addNode from './addNode'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
modelValue: { type: Object, default: () => {} }
|
||||
},
|
||||
components: {
|
||||
addNode
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
nodeConfig: {},
|
||||
drawer: false,
|
||||
form: {}
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
modelValue(){
|
||||
this.nodeConfig = this.modelValue
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.nodeConfig = this.modelValue
|
||||
},
|
||||
methods: {
|
||||
show(){
|
||||
this.form = {}
|
||||
this.form = {...this.nodeConfig}
|
||||
this.drawer = true
|
||||
},
|
||||
save(){
|
||||
this.$emit("update:modelValue", this.form)
|
||||
this.drawer = false
|
||||
},
|
||||
delNode(){
|
||||
this.$emit("update:modelValue", this.nodeConfig.childNode)
|
||||
},
|
||||
toText(nodeConfig){
|
||||
if (nodeConfig.nodeUserList && nodeConfig.nodeUserList.length>0) {
|
||||
const users = nodeConfig.nodeUserList.map(item=>item.name).join(" 或 ")
|
||||
return users
|
||||
}else{
|
||||
if(nodeConfig.ccSelfSelectFlag){
|
||||
return "发起人自选"
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
|
@ -3,10 +3,10 @@ const DEFAULT_CONFIG = {
|
|||
APP_NAME: "SCUI",
|
||||
|
||||
//版本号
|
||||
APP_VER: "1.2.4",
|
||||
APP_VER: "1.2.5",
|
||||
|
||||
//内核版本号
|
||||
CORE_VER: "1.2.4",
|
||||
CORE_VER: "1.2.5",
|
||||
|
||||
//接口地址
|
||||
API_URL: "/api",
|
||||
|
|
@ -49,7 +49,7 @@ const DEFAULT_CONFIG = {
|
|||
//小组件分布,com取值:views/home/components 文件名
|
||||
copmsList: [
|
||||
['welcome'],
|
||||
['about', 'var'],
|
||||
['about', 'ver'],
|
||||
['time', 'progress']
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
//数据表格配置
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
import tool from '@/utils/tool'
|
||||
|
||||
export default {
|
||||
pageSize: 20, //表格每一页条数
|
||||
parseData: function (res) { //数据分析
|
||||
return {
|
||||
data: res.data,
|
||||
data: res.data, //分析无分页的数据字段结构
|
||||
rows: res.data.rows, //分析行数据字段结构
|
||||
total: res.data.total, //分析总数字段结构
|
||||
msg: res.message, //分析描述字段结构
|
||||
|
|
@ -22,16 +23,44 @@ export default {
|
|||
* 自定义列保存处理
|
||||
* @tableName scTable组件的props->tableName
|
||||
* @column 用户配置好的列
|
||||
* @ref 列配置弹窗组件的ref
|
||||
*/
|
||||
columnSettingSave: function (tableName, column, ref) {
|
||||
ref.isSave = true
|
||||
setTimeout(()=>{
|
||||
ref.isSave = false
|
||||
ElMessage.success(`${tableName} 保存列配置成功,打开F12控制台查看详细`)
|
||||
console.log('这里可以保存本地或者远程保存,本文件在@/config/table.js');
|
||||
console.log('tableName:', tableName);
|
||||
console.log('column:', column);
|
||||
},1000)
|
||||
columnSettingSave: function (tableName, column) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(()=>{
|
||||
//这里为了演示使用了session和setTimeout演示,开发时应用数据请求
|
||||
tool.session.set(tableName, column)
|
||||
resolve(true)
|
||||
},1000)
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 获取自定义列
|
||||
* @tableName scTable组件的props->tableName
|
||||
* @column 组件接受到的props->column
|
||||
*/
|
||||
columnSettingGet: function (tableName, column) {
|
||||
return new Promise((resolve) => {
|
||||
//这里为了演示使用了session和setTimeout演示,开发时应用数据请求
|
||||
const userColumn = tool.session.get(tableName)
|
||||
if(userColumn){
|
||||
resolve(userColumn)
|
||||
}else{
|
||||
resolve(column)
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 重置自定义列
|
||||
* @tableName scTable组件的props->tableName
|
||||
* @column 组件接受到的props->column
|
||||
*/
|
||||
columnSettingReset: function (tableName, column) {
|
||||
return new Promise((resolve) => {
|
||||
//这里为了演示使用了session和setTimeout演示,开发时应用数据请求
|
||||
setTimeout(()=>{
|
||||
tool.session.remove(tableName)
|
||||
resolve(column)
|
||||
},1000)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
import { ElMessage } from 'element-plus'
|
||||
|
||||
export default {
|
||||
mounted(el, binding) {
|
||||
el.$value = binding.value
|
||||
el.handler = () => {
|
||||
const textarea = document.createElement('textarea')
|
||||
textarea.readOnly = 'readonly'
|
||||
textarea.style.position = 'absolute'
|
||||
textarea.style.left = '-9999px'
|
||||
textarea.value = el.$value
|
||||
document.body.appendChild(textarea)
|
||||
textarea.select()
|
||||
textarea.setSelectionRange(0, textarea.value.length)
|
||||
const result = document.execCommand('Copy')
|
||||
if (result) {
|
||||
ElMessage.success("复制成功")
|
||||
}
|
||||
document.body.removeChild(textarea)
|
||||
}
|
||||
el.addEventListener('click', el.handler)
|
||||
},
|
||||
updated(el, binding){
|
||||
el.$value = binding.value
|
||||
},
|
||||
unmounted(el){
|
||||
el.removeEventListener('click', el.handler)
|
||||
}
|
||||
}
|
||||
|
|
@ -24,6 +24,7 @@ import scDialog from './components/scDialog'
|
|||
import auth from './directives/auth'
|
||||
import role from './directives/role'
|
||||
import time from './directives/time'
|
||||
import copy from './directives/copy'
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
|
|
@ -56,6 +57,7 @@ app.component('scDialog', scDialog);
|
|||
app.directive('auth', auth)
|
||||
app.directive('role', role)
|
||||
app.directive('time', time)
|
||||
app.directive('copy', copy)
|
||||
|
||||
//全局代码错误捕捉
|
||||
app.config.errorHandler = errorHandler
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
import { nextTick } from 'vue'
|
||||
import NProgress from 'nprogress'
|
||||
import 'nprogress/nprogress.css'
|
||||
import router from '@/router'
|
||||
import store from '@/store'
|
||||
|
||||
export default {
|
||||
//刷新标签
|
||||
refresh() {
|
||||
NProgress.start()
|
||||
const route = router.currentRoute.value
|
||||
store.commit("removeKeepLive", route.name)
|
||||
store.commit("setRouteShow", false)
|
||||
nextTick(() => {
|
||||
store.commit("pushKeepLive", route.name)
|
||||
store.commit("setRouteShow", true)
|
||||
NProgress.done()
|
||||
})
|
||||
},
|
||||
//关闭标签
|
||||
close(tag) {
|
||||
const route = tag || router.currentRoute.value
|
||||
store.commit("removeViewTags", route)
|
||||
store.commit("removeIframeList", route)
|
||||
store.commit("removeKeepLive", route.name)
|
||||
const tagList = store.state.viewTags.viewTags
|
||||
const latestView = tagList.slice(-1)[0]
|
||||
if (latestView) {
|
||||
router.push(latestView)
|
||||
} else {
|
||||
router.push('/')
|
||||
}
|
||||
},
|
||||
//关闭标签后处理
|
||||
closeNext(next) {
|
||||
const route = router.currentRoute.value
|
||||
store.commit("removeViewTags", route)
|
||||
store.commit("removeIframeList", route)
|
||||
store.commit("removeKeepLive", route.name)
|
||||
if(next){
|
||||
const tagList = store.state.viewTags.viewTags
|
||||
next(tagList)
|
||||
}
|
||||
},
|
||||
//关闭其他
|
||||
closeOther() {
|
||||
const route = router.currentRoute.value
|
||||
const tagList = [...store.state.viewTags.viewTags]
|
||||
tagList.forEach(tag => {
|
||||
if(tag.meta&&tag.meta.affix || route.fullPath==tag.fullPath){
|
||||
return true
|
||||
}else{
|
||||
this.close(tag)
|
||||
}
|
||||
})
|
||||
},
|
||||
//设置标题
|
||||
setTitle(title){
|
||||
store.commit("updateViewTagsTitle", title)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
<div style="height: 210px;text-align: center;">
|
||||
<img src="img/ver.svg" style="height:140px"/>
|
||||
<h2 style="margin-top: 15px;">SCUI {{$CONFIG.CORE_VER}}</h2>
|
||||
<p style="margin-top: 5px;">最新版本 {{ver}}</p>
|
||||
</div>
|
||||
<div style="margin-top: 20px;">
|
||||
<el-button type="primary" plain round @click="golog">更新日志</el-button>
|
||||
|
|
@ -18,10 +19,17 @@
|
|||
description: "当前项目版本信息",
|
||||
data() {
|
||||
return {
|
||||
|
||||
ver: 'loading...'
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getVer()
|
||||
},
|
||||
methods: {
|
||||
async getVer(){
|
||||
const ver = await this.$API.demo.ver.get()
|
||||
this.ver = ver.data
|
||||
},
|
||||
golog(){
|
||||
window.open("https://gitee.com/lolicode/scui/releases")
|
||||
},
|
||||
|
|
@ -25,6 +25,11 @@
|
|||
</p>
|
||||
<el-alert title="指令方式日期时间转换,如设置'tip'修饰符将会转换成相对时间,并且每60秒自动更新" style="margin-top: 20px;"></el-alert>
|
||||
</el-card>
|
||||
<el-card shadow="never" header="v-copy 一键复制" style="margin-top: 15px;">
|
||||
<el-input type="textarea" :rows="2" placeholder="请输入内容" v-model="copyText"></el-input>
|
||||
<el-button v-copy="copyText" type="primary" style="margin-top: 15px;">复制</el-button>
|
||||
<el-alert title="点击复制按钮会将文本框绑定的值复制到剪切板, 试着粘贴到其他地方看看效果" style="margin-top: 20px;"></el-alert>
|
||||
</el-card>
|
||||
</el-main>
|
||||
</template>
|
||||
|
||||
|
|
@ -35,7 +40,8 @@
|
|||
return {
|
||||
time1: new Date(),
|
||||
time2: new Date().setMinutes(new Date().getMinutes()-1),
|
||||
time3: new Date().setMinutes(new Date().getMinutes()-120)
|
||||
time3: new Date().setMinutes(new Date().getMinutes()-120),
|
||||
copyText: '测试复制内容'
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
<template>
|
||||
<el-main>
|
||||
<el-card shadow="never" header="打开">
|
||||
<el-button type="primary" plain @click="open1">打开个人信息</el-button>
|
||||
<el-button type="primary" plain @click="open2">打开后执行</el-button>
|
||||
<el-alert title="打开后执行原理: 路由push时,在当前路由对象中插入一个特殊标识, 在目标视图中beforeRouteEnter获取判断是否需要执行特殊方法" style="margin-top: 20px;"></el-alert>
|
||||
</el-card>
|
||||
<el-card shadow="never" header="刷新" style="margin-top: 15px;">
|
||||
<el-button type="primary" plain @click="refresh1">刷新当前</el-button>
|
||||
</el-card>
|
||||
<el-card shadow="never" header="关闭" style="margin-top: 15px;">
|
||||
<el-button type="primary" plain @click="close1">关闭当前</el-button>
|
||||
<el-button type="primary" plain @click="close2">关闭其他</el-button>
|
||||
<el-button type="primary" plain @click="close3">关闭后执行</el-button>
|
||||
</el-card>
|
||||
<el-card shadow="never" header="设置" style="margin-top: 15px;">
|
||||
<el-form :inline="true">
|
||||
<el-form-item>
|
||||
<el-input v-model="input" placeholder="请输入内容"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" plain @click="set1">设置标题</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</el-main>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import useTabs from '@/utils/useTabs'
|
||||
|
||||
export default {
|
||||
name: 'viewTags',
|
||||
data() {
|
||||
return {
|
||||
input: "newTabName"
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
open1(){
|
||||
this.$router.push('/usercenter')
|
||||
},
|
||||
open2(){
|
||||
this.$router.push('/usercenter')
|
||||
this.$route.is = true
|
||||
},
|
||||
refresh1(){
|
||||
useTabs.refresh()
|
||||
},
|
||||
close1(){
|
||||
useTabs.close()
|
||||
},
|
||||
close2(){
|
||||
useTabs.closeOther()
|
||||
},
|
||||
close3(){
|
||||
useTabs.closeNext((tags)=>{
|
||||
//回调返回所有标签的数组,这里其实是需要判断是否含有'/usercenter',含有再操作的,这里为了演示就直接打开了。
|
||||
console.log(tags)
|
||||
this.$router.push('/usercenter')
|
||||
this.$route.is = true
|
||||
})
|
||||
},
|
||||
set1(){
|
||||
useTabs.setTitle(this.input)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
|
@ -115,7 +115,7 @@
|
|||
},
|
||||
computed: {
|
||||
day(){
|
||||
return this.$TOOL.dateFormat(this.toDay);
|
||||
return this.$TOOL.dateFormat(this.toDay,"yyyy-MM-dd");
|
||||
},
|
||||
dayItem(){
|
||||
return this.getData(this.day)
|
||||
|
|
@ -129,7 +129,7 @@
|
|||
var curDate = new Date()
|
||||
var oneDayTime = 24*60*60*1000
|
||||
var rDate = new Date(curDate.getTime() + (oneDayTime*n) )
|
||||
return this.$TOOL.dateFormat(rDate);
|
||||
return this.$TOOL.dateFormat(rDate, "yyyy-MM-dd");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,6 +180,20 @@
|
|||
this.$TOOL.data.set("APP_COLOR", val);
|
||||
}
|
||||
},
|
||||
//路由跳转进来 判断from是否有特殊标识做特殊处理
|
||||
beforeRouteEnter (to, from, next){
|
||||
next((vm)=>{
|
||||
if(from.is){
|
||||
//删除特殊标识,防止标签刷新重复执行
|
||||
delete from.is
|
||||
//执行特殊方法
|
||||
vm.$alert('路由跳转过来后含有特殊标识,做特殊处理', '提示', {
|
||||
type: 'success',
|
||||
center: true
|
||||
}).then(() => {}).catch(() => {})
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<el-input v-model="form.title"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="表格" prop="list">
|
||||
<sc-form-table v-model="form.list" :addTemplate="addTemplate" placeholder="暂无数据">
|
||||
<sc-form-table v-model="form.list" :addTemplate="addTemplate" drag-sort placeholder="暂无数据">
|
||||
<el-table-column prop="time" label="时间" width="180">
|
||||
<template #default="scope">
|
||||
<el-time-select v-model="scope.row.time"></el-time-select>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
<template>
|
||||
<el-main>
|
||||
<el-alert title="仿钉钉审批工作流. 现预览阶段, 功能有限后期将不断迭代, 一般工作流设计器都是满足不了业务需求的,建议拷贝一份组件自行根据业务扩展开发" type="warning" style="margin-bottom:20px;"></el-alert>
|
||||
<sc-workflow v-model="data.nodeConfig"></sc-workflow>
|
||||
</el-main>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import scWorkflow from '@/components/scWorkflow'
|
||||
|
||||
export default {
|
||||
name: 'workflow',
|
||||
components: {
|
||||
scWorkflow
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
data: {
|
||||
id: 1,
|
||||
name: "合同审批",
|
||||
nodeConfig: {
|
||||
nodeName: "发起人",
|
||||
type: 0, // 0 发起人 1审批 2抄送 3条件 4路由
|
||||
childNode: {
|
||||
nodeName: "审核人",
|
||||
type: 1,
|
||||
settype: 1, // 审批人设置 1指定成员 2主管 4发起人自选 5发起人自己 7连续多级主管
|
||||
nodeUserList: [
|
||||
{
|
||||
id: 1,
|
||||
name: "Sakuya"
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Lolowan"
|
||||
}
|
||||
],
|
||||
childNode: {
|
||||
nodeName: "路由",
|
||||
type: 4,
|
||||
conditionNodes: [
|
||||
{
|
||||
nodeName: "条件1",
|
||||
type: 3,
|
||||
priorityLevel: 1,
|
||||
conditionList: [
|
||||
{
|
||||
label: "上级审核状态",
|
||||
field: "promoter",
|
||||
operator: "=",
|
||||
value: '保留'
|
||||
}
|
||||
],
|
||||
childNode: {
|
||||
nodeName: "条件审核",
|
||||
type: 1,
|
||||
settype: 2
|
||||
}
|
||||
},
|
||||
{
|
||||
nodeName: "条件2",
|
||||
type: 3,
|
||||
priorityLevel: 2,
|
||||
conditionList: []
|
||||
}
|
||||
],
|
||||
childNode: {
|
||||
nodeName: "抄送人",
|
||||
type: 2,
|
||||
ccSelfSelectFlag: true,
|
||||
nodeUserList: []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
Loading…
Reference in New Issue