xy 1 year ago
parent 0da4733d76
commit 0e3a2fa46b

@ -1,11 +1,17 @@
<template>
<div id="app">
<router-view />
<ThemePicker style="display: none;"></ThemePicker>
</div>
</template>
<script>
import ThemePicker from "@/components/ThemePicker/index.vue";
export default {
name: 'App'
name: 'App',
components: {
ThemePicker
}
}
</script>

File diff suppressed because one or more lines are too long

@ -0,0 +1,182 @@
<template>
<el-color-picker
v-model="theme"
:predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]"
class="theme-picker"
popper-class="theme-picker-dropdown"
/>
</template>
<script>
import Cookies from 'js-cookie'
import chalkCss from '@/assets/chalk.js'
const version = require('element-ui/package.json').version // element-ui version from node_modules
const ORIGINAL_THEME = '#409EFF' // default color
let index = 0
export default {
data() {
return {
chalk: '', // content of theme-chalk css
theme: ''
}
},
computed: {
},
watch: {
async theme(val) {
const oldVal = this.chalk ? this.theme : ORIGINAL_THEME
if (typeof val !== 'string') return
const themeCluster = this.getThemeCluster(val.replace('#', ''))
const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
console.log(themeCluster, originalCluster)
let $message
if (index !== 0) {
$message = this.$message({
message: '切换主题中',
customClass: 'theme-message',
type: 'success',
duration: 0,
iconClass: 'el-icon-loading'
})
}
const getHandler = (variable, id) => {
return () => {
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)
let styleTag = document.getElementById(id)
if (!styleTag) {
styleTag = document.createElement('style')
styleTag.setAttribute('id', id)
document.head.appendChild(styleTag)
}
styleTag.innerText = newStyle
}
}
if (!this.chalk) {
// const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
// await this.getCSSString(url, 'chalk')
this.chalk = chalkCss.replace(/@font-face{[^}]+}/, '')
}
const chalkHandler = getHandler('chalk', 'chalk-style')
chalkHandler()
const styles = [].slice.call(document.querySelectorAll('style'))
.filter(style => {
const text = style.innerText
return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
})
styles.forEach(style => {
const { innerText } = style
if (typeof innerText !== 'string') return
style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
})
this.$emit('change', val)
Cookies.set('defaultTheme', val)
document.body.style.setProperty('--theme-color', val)
index++
$message?.close()
}
},
created() {
},
mounted() {
this.$nextTick(() => {
this.theme = Cookies.get('defaultTheme') || ORIGINAL_THEME
document.body.style.setProperty('--theme-color', Cookies.get('defaultTheme'))
})
},
methods: {
updateStyle(style, oldCluster, newCluster) {
let newStyle = style
oldCluster.forEach((color, index) => {
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
})
return newStyle
},
getCSSString(url, variable) {
return new Promise(resolve => {
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
resolve()
}
}
xhr.open('GET', url)
xhr.send()
})
},
getThemeCluster(theme) {
const tintColor = (color, tint) => {
let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16)
if (tint === 0) { // when primary color is in its rgb space
return [red, green, blue].join(',')
} else {
red += Math.round(tint * (255 - red))
green += Math.round(tint * (255 - green))
blue += Math.round(tint * (255 - blue))
red = red.toString(16)
green = green.toString(16)
blue = blue.toString(16)
return `#${red}${green}${blue}`
}
}
const shadeColor = (color, shade) => {
let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16)
red = Math.round((1 - shade) * red)
green = Math.round((1 - shade) * green)
blue = Math.round((1 - shade) * blue)
red = red.toString(16)
green = green.toString(16)
blue = blue.toString(16)
return `#${red}${green}${blue}`
}
const clusters = [theme]
for (let i = 0; i <= 9; i++) {
clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
}
clusters.push(shadeColor(theme, 0.1))
return clusters
}
}
}
</script>
<style>
.theme-message,
.theme-picker-dropdown {
z-index: 99999 !important;
}
.theme-picker .el-color-picker__trigger {
height: 26px !important;
width: 26px !important;
padding: 2px;
}
.theme-picker-dropdown .el-color-dropdown__link-btn {
display: none;
}
</style>

@ -22,6 +22,7 @@ export default {
/*50 = navbar */
min-height: 100%;
width: 100%;
background: #eff2f9;
position: relative;
overflow: hidden;
}

@ -16,7 +16,7 @@
</el-menu>
</el-scrollbar>
<hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
<!-- <hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />-->
</div>
</template>
@ -57,6 +57,10 @@ export default {
toggleSideBar() {
this.$store.dispatch('app/toggleSideBar')
},
},
created() {
// parent
window.toggleSideBar = this.toggleSideBar
}
}
</script>

@ -2,11 +2,6 @@
<div :class="classObj" class="app-wrapper">
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
<sidebar class="sidebar-container" />
<div class="mobile-sidebar-button" v-show="device==='mobile' && !sidebar.opened" @click="toggleSideBar">
<el-button type="primary" circle>
<SvgIcon icon-class="menu"></SvgIcon>
</el-button>
</div>
<div class="main-container">
<app-main />
</div>
@ -47,9 +42,6 @@ export default {
}
},
methods: {
toggleSideBar() {
this.$store.dispatch('app/toggleSideBar')
},
handleClickOutside() {
this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
}
@ -101,10 +93,4 @@ export default {
::v-deep .el-button.is-circle {
padding: 8px;
}
.mobile-sidebar-button {
position: fixed;
z-index: 998;
right: 16px;
bottom: 16px;
}
</style>

@ -80,7 +80,7 @@ else if(window.top !== window.self) {
// 当前页面在iframe中
window._IN_IFRAME = true;
setToken(getQueryParam('auth_token'))
setToken(window.decodeURIComponent(getQueryParam('auth_token')))
window.MODULE_NAME = getQueryParam('module_name')
new Vue({
router,

@ -81,6 +81,9 @@
}
}
.is-active{
background-color: $menuActiveBg !important;
}
.is-active>.el-submenu__title {
color: $subMenuActiveText !important;
}
@ -93,6 +96,10 @@
&:hover {
background-color: $subMenuHover !important;
}
&.is-active{
background-color: $submenuActiveBg !important;
border-right: 5px solid $subMenuActiveText !important;
}
}
}

@ -1,13 +1,15 @@
// sidebar
$menuText:#bfcbd9;
$menuActiveText:#409EFF;
$subMenuActiveText:#f4f4f5; //https://github.com/ElemeFE/element/issues/12951
$menuText:#606266;
$menuActiveText:#303133;
$subMenuActiveText:#338de3; //https://github.com/ElemeFE/element/issues/12951
$menuBg:#304156;
$menuHover:#263445;
$menuBg:#ffffff;
$menuHover:#e0f2ff;
$menuActiveBg:#dcf3ff;
$subMenuBg:#1f2d3d;
$subMenuHover:#001528;
$subMenuBg:#ffffff;
$subMenuHover:#edf6ff;
$submenuActiveBg:#dcf3ff;
$sideBarWidth: 210px;

@ -23,7 +23,15 @@ export const validation = new Map([
['integer',/^-?\d+$/],//整数
['date',/(^\d{10})|(^\d{13})|(^((\d\d\d\d(.+)|\d\d(.+))?(0?[1-9](.+)|1[012](.+))?((0?[1-9]|[12]\d|3[01])(.+))?\s?)((0?[0-9]|1[0-9]|2[0-3])(.+))?((0?[0-9]|[1-5][0-9])(.+))?((0?[0-9]|[1-5][0-9])(.+))?)$/],
['email',/^[^\s@]+@[^\s@]+\.[^\s@]+$/],
['idcard',/(^([1-6][1-9]|50)\d{4}\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3})|(^([1-6][1-9]|50)\d{4}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx])$/],
['mobile',/(^1[3456789]\d{9})|(^(0\d{2,3}(-)*)?\d{7})$/],
['isIdCard',/(^([1-6][1-9]|50)\d{4}\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3})|(^([1-6][1-9]|50)\d{4}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx])$/],
['isMobile',/(^1[3456789]\d{9})|(^(0\d{2,3}(-)*)?\d{7})$/],
['numeric',/^-?\d+(.\d+)?$/],
])
export const validationName = new Map([
['integer','整数'],//整数
['date','日期'],
['email','邮箱'],
['isIdCard','身份证号'],
['isMobile','手机号'],
['numeric','数字'],
])

@ -37,15 +37,22 @@ export default {
default: () => ({}),
required: true
},
scriptContent: String
scriptContent: String,
rules: {
type: Object,
default: () => ({})
}
},
data() {
return {
form: {},
file: {}
file: {},
}
},
methods: {
async validate() {
return await (this.$refs['elForm'].validate())
}
},
computed: {
@ -84,15 +91,18 @@ export default {
_writeable: this.writeable.indexOf(field.id) !== -1,
}))
return h('el-form', {
ref: 'elForm',
class: 'form',
props: {
model: this.form,
'label-position': 'top'
'label-position': 'right',
'label-width': '80px',
rules: this.rules,
'inline-message': true
}
},authFields.map(field => formBuilder.bind(this)(this.device, field, h)))
},
created() {
}
created() {}
}
</script>
@ -100,12 +110,14 @@ export default {
.form {
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-gap: 20px;
//grid-gap: 20px;
}
::v-deep .el-form-item {
margin-bottom: 0;
border: 1px solid #dee2e6;
padding: 8px 12px;
margin: -1px 0 0 -1px;
}
::v-deep .el-form-item__label {
padding-bottom: 0;
::v-deep .el-form-item__content {
line-height: 1;
}
</style>

@ -44,6 +44,7 @@
:file-list="fileList"
:script-content="scriptContent"
:writeable="writeableFields"
:rules="rules"
></DesktopForm>
</template>
<template v-else>
@ -199,6 +200,7 @@ import forward from "./components/forward.vue";
import rollback from "./components/rollback.vue";
import { create, deal, fieldConfig, preConfig, preDeal, view } from "@/api/flow";
import { deepCopy } from "@/utils";
import { validation, validationName } from "@/utils/validate";
export default {
components: {
@ -232,11 +234,32 @@ export default {
form: {},
result: {},
fileList: {},
rules: {}
};
},
methods: {
generateForm(object, fields) {
this.rules = {}
fields.forEach((field) => {
if(field.rules && field.rules.length > 0) {
this.rules[field.name] = field.rules.map(rule => {
switch (rule) {
case 'required':
return { required: true, message: `请填写${field.label}`, trigger: 'blur' }
default:
return {
validator: (myRule, value, callback) => {
if(validation.get(rule).test(value)) {
callback()
} else {
callback(new Error(`${field.label}必须为${validationName.get(rule)}`))
}
},
trigger: 'blur'
}
}
})
}
if (field.type === "file") {
this.fileList[field.name] = [];
}
@ -431,6 +454,9 @@ export default {
callback = () => (this.isShowAssign = true);
break;
}
if (this.device === "desktop") {
if(!await this.$refs['desktopForm'].validate()) return
}
if (this.$route.query.flow_id) {
copyForm.id = this.$route.query.flow_id;
const { flow, is_last_handled_log } = await deal(

Loading…
Cancel
Save