parent
65d1e6a879
commit
7f30a186df
File diff suppressed because it is too large
Load Diff
@ -0,0 +1 @@
|
|||||||
|
.cm-s-idea span.cm-meta{color:olive}.cm-s-idea span.cm-number{color:#00f}.cm-s-idea span.cm-keyword{line-height:1em;font-weight:700;color:navy}.cm-s-idea span.cm-atom{font-weight:700;color:navy}.cm-s-idea span.cm-def{color:#000}.cm-s-idea span.cm-variable{color:#000}.cm-s-idea span.cm-variable-2{color:#000}.cm-s-idea span.cm-type,.cm-s-idea span.cm-variable-3{color:#000}.cm-s-idea span.cm-property{color:#000}.cm-s-idea span.cm-operator{color:#000}.cm-s-idea span.cm-comment{color:grey}.cm-s-idea span.cm-string{color:green}.cm-s-idea span.cm-string-2{color:green}.cm-s-idea span.cm-qualifier{color:#555}.cm-s-idea span.cm-error{color:red}.cm-s-idea span.cm-attribute{color:#00f}.cm-s-idea span.cm-tag{color:navy}.cm-s-idea span.cm-link{color:#00f}.cm-s-idea .CodeMirror-activeline-background{background:#fffae3}.cm-s-idea span.cm-builtin{color:#30a}.cm-s-idea span.cm-bracket{color:#cc7}.cm-s-idea{font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif}.cm-s-idea .CodeMirror-matchingbracket{outline:1px solid grey;color:#000!important}.CodeMirror-hints.idea{font-family:Menlo,Monaco,Consolas,'Courier New',monospace;color:#616569;background-color:#ebf3fd!important}.CodeMirror-hints.idea .CodeMirror-hint-active{background-color:#a2b8c9!important;color:#5c6065!important}
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
<template>
|
||||||
|
<a-time-picker
|
||||||
|
:disabled="disabled || readOnly"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:value="momVal"
|
||||||
|
:format="dateFormat"
|
||||||
|
:getCalendarContainer="getCalendarContainer"
|
||||||
|
@change="handleTimeChange"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import moment from 'moment'
|
||||||
|
export default {
|
||||||
|
name: 'JTime',
|
||||||
|
props: {
|
||||||
|
placeholder:{
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
value:{
|
||||||
|
type: String,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
dateFormat:{
|
||||||
|
type: String,
|
||||||
|
default: 'HH:mm:ss',
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
readOnly:{
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
disabled:{
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
getCalendarContainer: {
|
||||||
|
type: Function,
|
||||||
|
default: (node) => node.parentNode
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
let timeStr = this.value;
|
||||||
|
return {
|
||||||
|
decorator:"",
|
||||||
|
momVal:!timeStr?null:moment(timeStr,this.dateFormat)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
value (val) {
|
||||||
|
if(!val){
|
||||||
|
this.momVal = null
|
||||||
|
}else{
|
||||||
|
this.momVal = moment(val,this.dateFormat)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
moment,
|
||||||
|
handleTimeChange(mom,timeStr){
|
||||||
|
this.$emit('change', timeStr);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//2.2新增 在组件内定义 指定父组件调用时候的传值属性和事件类型 这个牛逼
|
||||||
|
model: {
|
||||||
|
prop: 'value',
|
||||||
|
event: 'change'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -0,0 +1,75 @@
|
|||||||
|
<template>
|
||||||
|
<j-modal
|
||||||
|
title="详细信息"
|
||||||
|
:width="1200"
|
||||||
|
:visible="visible"
|
||||||
|
@ok="handleOk"
|
||||||
|
@cancel="close"
|
||||||
|
switch-fullscreen
|
||||||
|
:fullscreen.sync="fullscreen"
|
||||||
|
>
|
||||||
|
|
||||||
|
<transition name="fade">
|
||||||
|
<div v-if="visible">
|
||||||
|
<slot name="mainForm" :row="row" :column="column"/>
|
||||||
|
<slot name="subForm" :row="row" :column="column"/>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
|
||||||
|
</j-modal>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import { cloneObject } from '@/utils/util'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'JVxeDetailsModal',
|
||||||
|
inject: ['superTrigger'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
visible: false,
|
||||||
|
fullscreen: false,
|
||||||
|
row: null,
|
||||||
|
column: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
open(event) {
|
||||||
|
let {row, column} = event
|
||||||
|
this.row = cloneObject(row)
|
||||||
|
this.column = column
|
||||||
|
this.visible = true
|
||||||
|
},
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.visible = false
|
||||||
|
},
|
||||||
|
|
||||||
|
handleOk() {
|
||||||
|
this.superTrigger('detailsConfirm', {
|
||||||
|
row: this.row,
|
||||||
|
column: this.column,
|
||||||
|
callback: (success) => {
|
||||||
|
this.visible = !success
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="less">
|
||||||
|
.fade-enter-active,
|
||||||
|
.fade-leave-active {
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-enter,
|
||||||
|
.fade-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
<template>
|
||||||
|
<div :class="boxClass">
|
||||||
|
<a-pagination
|
||||||
|
:disabled="disabled"
|
||||||
|
v-bind="bindProps"
|
||||||
|
@change="handleChange"
|
||||||
|
@showSizeChange="handleShowSizeChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import PropTypes from 'ant-design-vue/es/_util/vue-types'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'JVxePagination',
|
||||||
|
props: {
|
||||||
|
size: String,
|
||||||
|
disabled: PropTypes.bool,
|
||||||
|
pagination: PropTypes.object.def({}),
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
defaultPagination: {
|
||||||
|
current: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
pageSizeOptions: ['10', '20', '30'],
|
||||||
|
showTotal: (total, range) => {
|
||||||
|
return range[0] + '-' + range[1] + ' 共 ' + total + ' 条'
|
||||||
|
},
|
||||||
|
showQuickJumper: true,
|
||||||
|
showSizeChanger: true,
|
||||||
|
total: 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
bindProps() {
|
||||||
|
return {
|
||||||
|
...this.defaultPagination,
|
||||||
|
...this.pagination,
|
||||||
|
size: this.size === 'tiny' ? 'small' : ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
boxClass() {
|
||||||
|
return {
|
||||||
|
'j-vxe-pagination': true,
|
||||||
|
'show-quick-jumper': !!this.bindProps.showQuickJumper
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleChange(current, pageSize) {
|
||||||
|
this.$set(this.pagination, 'current', current)
|
||||||
|
this.$emit('change', {current, pageSize})
|
||||||
|
},
|
||||||
|
handleShowSizeChange(current, pageSize) {
|
||||||
|
this.$set(this.pagination, 'pageSize', pageSize)
|
||||||
|
this.$emit('change', {current, pageSize})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,127 @@
|
|||||||
|
<template>
|
||||||
|
<div :class="boxClass">
|
||||||
|
<!-- 工具按钮 -->
|
||||||
|
<div class="j-vxe-tool-button div" :size="btnSize">
|
||||||
|
<slot v-if="showPrefix" name="toolbarPrefix" :size="btnSize"/>
|
||||||
|
|
||||||
|
<a-button v-if="showAdd" icon="plus" @click="trigger('add')" :disabled="disabled" type="primary">新增</a-button>
|
||||||
|
<a-button v-if="showSave" icon="save" @click="trigger('save')" :disabled="disabled">保存</a-button>
|
||||||
|
<template v-if="selectedRowIds.length > 0">
|
||||||
|
<a-popconfirm
|
||||||
|
v-if="showRemove"
|
||||||
|
:title="`确定要删除这 ${selectedRowIds.length} 项吗?`"
|
||||||
|
@confirm="trigger('remove')"
|
||||||
|
>
|
||||||
|
<a-button icon="minus" :disabled="disabled">删除</a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
<template v-if="showClearSelection">
|
||||||
|
<a-button icon="delete" @click="trigger('clearSelection')">清空选择</a-button>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<slot v-if="showSuffix" name="toolbarSuffix" :size="btnSize"/>
|
||||||
|
<a v-if="showCollapse" @click="toggleCollapse" style="margin-left: 4px">
|
||||||
|
<span>{{ collapsed ? '展开' : '收起' }}</span>
|
||||||
|
<a-icon :type="collapsed ? 'down' : 'up'"/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'JVxeToolbar',
|
||||||
|
props: {
|
||||||
|
toolbarConfig: Object,
|
||||||
|
excludeCode: Array,
|
||||||
|
size: String,
|
||||||
|
disabled: Boolean,
|
||||||
|
disabledRows: Object,
|
||||||
|
selectedRowIds: Array,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 是否收起
|
||||||
|
collapsed: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
boxClass() {
|
||||||
|
return {
|
||||||
|
'j-vxe-toolbar': true,
|
||||||
|
'j-vxe-toolbar-collapsed': this.collapsed,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
btns() {
|
||||||
|
let arr = this.toolbarConfig.btn || ['add', 'remove', 'clearSelection']
|
||||||
|
let exclude = [...this.excludeCode]
|
||||||
|
// TODO 需要将remove替换batch_delete
|
||||||
|
// 系统默认的批量删除编码配置为 batch_delete 此处需要转化一下
|
||||||
|
if(exclude.indexOf('batch_delete')>=0){
|
||||||
|
exclude.add('remove')
|
||||||
|
}
|
||||||
|
// 按钮权限 需要去掉不被授权的按钮
|
||||||
|
return arr.filter(item=>{
|
||||||
|
return exclude.indexOf(item)<0
|
||||||
|
})
|
||||||
|
},
|
||||||
|
slots() {
|
||||||
|
return this.toolbarConfig.slot || ['prefix', 'suffix']
|
||||||
|
},
|
||||||
|
showPrefix() {
|
||||||
|
return this.slots.includes('prefix')
|
||||||
|
},
|
||||||
|
showSuffix() {
|
||||||
|
return this.slots.includes('suffix')
|
||||||
|
},
|
||||||
|
showAdd() {
|
||||||
|
return this.btns.includes('add')
|
||||||
|
},
|
||||||
|
showSave() {
|
||||||
|
return this.btns.includes('save')
|
||||||
|
},
|
||||||
|
showRemove() {
|
||||||
|
return this.btns.includes('remove')
|
||||||
|
},
|
||||||
|
showClearSelection() {
|
||||||
|
if (this.btns.includes('clearSelection')) {
|
||||||
|
// 有禁用行时才显示清空选择按钮
|
||||||
|
// 因为禁用行会阻止选择行,导致无法取消全选
|
||||||
|
let length = Object.keys(this.disabledRows).length
|
||||||
|
return length > 0
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
showCollapse() {
|
||||||
|
return this.btns.includes('collapse')
|
||||||
|
},
|
||||||
|
|
||||||
|
btnSize() {
|
||||||
|
return this.size === 'tiny' ? 'small' : null
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 触发事件 */
|
||||||
|
trigger(name) {
|
||||||
|
this.$emit(name)
|
||||||
|
},
|
||||||
|
// 切换展开收起
|
||||||
|
toggleCollapse() {
|
||||||
|
this.collapsed = !this.collapsed
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
.j-vxe-toolbar-collapsed {
|
||||||
|
[data-collapse] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.j-vxe-tool-button.div .ant-btn {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,59 @@
|
|||||||
|
@import "size/tiny";
|
||||||
|
|
||||||
|
.j-vxe-table-box {
|
||||||
|
|
||||||
|
// 工具栏
|
||||||
|
.j-vxe-toolbar {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页器
|
||||||
|
.j-vxe-pagination {
|
||||||
|
margin-top: 8px;
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
|
.ant-pagination-options-size-changer.ant-select {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.show-quick-jumper {
|
||||||
|
.ant-pagination-options-size-changer.ant-select {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更改 header 底色
|
||||||
|
.vxe-table.border--default .vxe-table--header-wrapper,
|
||||||
|
.vxe-table.border--full .vxe-table--header-wrapper,
|
||||||
|
.vxe-table.border--outer .vxe-table--header-wrapper {
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更改 tooltip 校验失败的颜色
|
||||||
|
.vxe-table--tooltip-wrapper.vxe-table--valid-error {
|
||||||
|
background-color: #f5222d !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更改 输入框 校验失败的颜色
|
||||||
|
.col--valid-error > .vxe-cell > .ant-input,
|
||||||
|
.col--valid-error > .vxe-cell > .ant-select .ant-input,
|
||||||
|
.col--valid-error > .vxe-cell > .ant-select .ant-select-selection,
|
||||||
|
.col--valid-error > .vxe-cell > .ant-input-number,
|
||||||
|
.col--valid-error > .vxe-cell > .ant-cascader-picker .ant-cascader-input,
|
||||||
|
.col--valid-error > .vxe-cell > .ant-calendar-picker .ant-calendar-picker-input,
|
||||||
|
.col--valid-error > .vxe-tree-cell > .ant-input,
|
||||||
|
.col--valid-error > .vxe-tree-cell > .ant-select .ant-input,
|
||||||
|
.col--valid-error > .vxe-tree-cell > .ant-select .ant-select-selection,
|
||||||
|
.col--valid-error > .vxe-tree-cell > .ant-input-number,
|
||||||
|
.col--valid-error > .vxe-tree-cell > .ant-cascader-picker .ant-cascader-input,
|
||||||
|
.col--valid-error > .vxe-tree-cell > .ant-calendar-picker .ant-calendar-picker-input {
|
||||||
|
border-color: #f5222d !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拖拽排序列样式
|
||||||
|
.vxe-table .col--row-drag-sort .vxe-cell {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
.j-vxe-reload-effect-box {
|
||||||
|
|
||||||
|
&,
|
||||||
|
.j-vxe-reload-effect-span {
|
||||||
|
display: inline;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.j-vxe-reload-effect-span {
|
||||||
|
|
||||||
|
&.layer-top {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
z-index: 2;
|
||||||
|
background-color: white;
|
||||||
|
|
||||||
|
transform-origin: 0 0;
|
||||||
|
animation: reload-effect 1.5s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.layer-bottom {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义动画
|
||||||
|
@keyframes reload-effect {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: rotateX(0);
|
||||||
|
}
|
||||||
|
10% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
90% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: rotateX(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,332 @@
|
|||||||
|
.j-vxe-table-box {
|
||||||
|
|
||||||
|
@height: 24px;
|
||||||
|
@lineHeight: 1.5;
|
||||||
|
@spacing: 4px;
|
||||||
|
@fontSize: 14px;
|
||||||
|
@borderRadius: 2px;
|
||||||
|
|
||||||
|
&.size--tiny {
|
||||||
|
|
||||||
|
.vxe-table--header .vxe-cell--checkbox {
|
||||||
|
position: relative;
|
||||||
|
top: 2px;
|
||||||
|
right: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-table--body .vxe-cell--checkbox {
|
||||||
|
line-height: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-cell {
|
||||||
|
padding: 0 5px;
|
||||||
|
font-size: @fontSize;
|
||||||
|
line-height: @lineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-table .vxe-header--column .vxe-cell {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-body--column.col--actived {
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
.vxe-cell {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ant输入框
|
||||||
|
.ant-input,
|
||||||
|
// ant下拉框
|
||||||
|
.ant-select-selection {
|
||||||
|
padding: 2px @spacing;
|
||||||
|
height: @height;
|
||||||
|
font-size: @fontSize;
|
||||||
|
border-radius: @borderRadius;
|
||||||
|
line-height: @lineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 输入框图标对齐
|
||||||
|
.ant-input-affix-wrapper {
|
||||||
|
& .ant-input-prefix {
|
||||||
|
left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .ant-input:not(:first-child) {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按钮 addon
|
||||||
|
.ant-input-group-addon {
|
||||||
|
border-color: transparent;
|
||||||
|
border-radius: @borderRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ant下拉多选框
|
||||||
|
.ant-select-selection--multiple {
|
||||||
|
min-height: @height;
|
||||||
|
|
||||||
|
& .ant-select-selection__rendered > ul > li {
|
||||||
|
height: calc(@height - 6px);
|
||||||
|
font-size: calc(@fontSize - 2px);
|
||||||
|
margin-top: 0;
|
||||||
|
line-height: @lineHeight;
|
||||||
|
padding: 0 18px 0 4px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
& .ant-select-selection__clear,
|
||||||
|
& .ant-select-arrow {
|
||||||
|
top: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ant按钮
|
||||||
|
.ant-upload {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.ant-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: @height;
|
||||||
|
padding: 0 8px;
|
||||||
|
font-size: @fontSize;
|
||||||
|
border-color: transparent;
|
||||||
|
background-color: transparent;
|
||||||
|
border-radius: @borderRadius;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(255, 255, 255, 0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-select-selection__rendered {
|
||||||
|
line-height: @lineHeight;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 工具栏
|
||||||
|
.j-vxe-toolbar {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
|
||||||
|
.ant-form-item-label,
|
||||||
|
.ant-form-item-control {
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-form-inline .ant-form-item {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 内置属性 */
|
||||||
|
|
||||||
|
.vxe-table.size--tiny {
|
||||||
|
& .vxe-table--expanded {
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .vxe-body--expanded-cell {
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.size--tiny .vxe-loading .vxe-loading--spinner {
|
||||||
|
width: 38px;
|
||||||
|
height: 38px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-table.size--tiny .vxe-body--column.col--ellipsis,
|
||||||
|
.vxe-table.size--tiny .vxe-footer--column.col--ellipsis,
|
||||||
|
.vxe-table.size--tiny .vxe-header--column.col--ellipsis,
|
||||||
|
.vxe-table.vxe-editable.size--tiny .vxe-body--column {
|
||||||
|
height: @height;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-table.size--tiny {
|
||||||
|
font-size: 12px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-table.size--tiny .vxe-table--empty-block,
|
||||||
|
.vxe-table.size--tiny .vxe-table--empty-placeholder {
|
||||||
|
min-height: @height;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-table.size--tiny .vxe-body--column:not(.col--ellipsis),
|
||||||
|
.vxe-table.size--tiny .vxe-footer--column:not(.col--ellipsis),
|
||||||
|
.vxe-table.size--tiny .vxe-header--column:not(.col--ellipsis) {
|
||||||
|
padding: 4px 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-table.size--tiny .vxe-cell .vxe-default-input,
|
||||||
|
.vxe-table.size--tiny .vxe-cell .vxe-default-select,
|
||||||
|
.vxe-table.size--tiny .vxe-cell .vxe-default-textarea {
|
||||||
|
height: @height;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-table.size--tiny .vxe-cell .vxe-default-input[type=date]::-webkit-inner-spin-button {
|
||||||
|
margin-top: 1px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-table.size--tiny.virtual--x .col--ellipsis .vxe-cell,
|
||||||
|
.vxe-table.size--tiny.virtual--y .col--ellipsis .vxe-cell,
|
||||||
|
.vxe-table.size--tiny .vxe-body--column.col--ellipsis .vxe-cell,
|
||||||
|
.vxe-table.size--tiny .vxe-footer--column.col--ellipsis .vxe-cell,
|
||||||
|
.vxe-table.size--tiny .vxe-header--column.col--ellipsis .vxe-cell {
|
||||||
|
max-height: @height;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-table.size--tiny .vxe-cell--checkbox .vxe-checkbox--icon,
|
||||||
|
.vxe-table.size--tiny .vxe-cell--radio .vxe-radio--icon {
|
||||||
|
font-size: 14px
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.vxe-table.size--tiny .vxe-table--filter-option > .vxe-checkbox--icon,
|
||||||
|
.vxe-table.size--small .vxe-table--filter-option > .vxe-checkbox--icon {
|
||||||
|
font-size: 14px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-modal--wrapper.size--tiny .vxe-export--panel-column-option > .vxe-checkbox--icon,
|
||||||
|
.vxe-modal--wrapper.size--small .vxe-export--panel-column-option > .vxe-checkbox--icon {
|
||||||
|
font-size: 14px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-grid.size--tiny {
|
||||||
|
font-size: 12px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-toolbar.size--tiny {
|
||||||
|
font-size: 12px;
|
||||||
|
height: 46px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-toolbar.size--tiny .vxe-custom--option > .vxe-checkbox--icon {
|
||||||
|
font-size: 14px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-pager.size--tiny {
|
||||||
|
font-size: 12px;
|
||||||
|
height: @height;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-checkbox.size--tiny {
|
||||||
|
font-size: 12px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-checkbox.size--tiny .vxe-checkbox--icon {
|
||||||
|
font-size: 14px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-radio-button.size--tiny .vxe-radio--label {
|
||||||
|
line-height: 26px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-radio.size--tiny {
|
||||||
|
font-size: 12px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-radio.size--tiny .vxe-radio--icon {
|
||||||
|
font-size: 14px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-input.size--tiny {
|
||||||
|
font-size: 12px;
|
||||||
|
height: @height;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-input.size--tiny .vxe-input--inner[type=date]::-webkit-inner-spin-button,
|
||||||
|
.vxe-input.size--tiny .vxe-input--inner[type=month]::-webkit-inner-spin-button,
|
||||||
|
.vxe-input.size--tiny .vxe-input--inner[type=week]::-webkit-inner-spin-button {
|
||||||
|
margin-top: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-dropdown--panel.size--tiny {
|
||||||
|
font-size: 12px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-textarea--autosize.size--tiny,
|
||||||
|
.vxe-textarea.size--tiny {
|
||||||
|
font-size: 12px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-textarea.size--tiny:not(.is--autosize) {
|
||||||
|
min-height: @height;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-button.size--tiny {
|
||||||
|
font-size: 12px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-button.size--tiny.type--button {
|
||||||
|
height: @height;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-button.size--tiny.type--button.is--circle {
|
||||||
|
min-width: @height;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-button.size--tiny.type--button.is--round {
|
||||||
|
border-radius: 14px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-button.size--tiny .vxe-button--icon,
|
||||||
|
.vxe-button.size--tiny .vxe-button--loading-icon {
|
||||||
|
min-width: 12px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-modal--wrapper.size--tiny {
|
||||||
|
font-size: 12px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-form.size--tiny {
|
||||||
|
font-size: 12px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-form.size--tiny .vxe-form--item-inner {
|
||||||
|
min-height: 30px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-form.size--tiny .vxe-default-input[type=reset],
|
||||||
|
.vxe-form.size--tiny .vxe-default-input[type=submit] {
|
||||||
|
line-height: 26px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-form.size--tiny .vxe-default-input,
|
||||||
|
.vxe-form.size--tiny .vxe-default-select {
|
||||||
|
height: @height;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-select--panel.size--tiny,
|
||||||
|
.vxe-select.size--tiny {
|
||||||
|
font-size: 12px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-select--panel.size--tiny .vxe-optgroup--title,
|
||||||
|
.vxe-select--panel.size--tiny .vxe-select-option {
|
||||||
|
height: 24px;
|
||||||
|
line-height: 24px
|
||||||
|
}
|
||||||
|
|
||||||
|
.vxe-switch.size--tiny {
|
||||||
|
font-size: 12px
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.vxe-pulldown--panel.size--tiny,
|
||||||
|
.vxe-pulldown.size--tiny {
|
||||||
|
font-size: 12px
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,246 @@
|
|||||||
|
<template>
|
||||||
|
<div class="tinymce-containerty" :style="{width:containerWidth}">
|
||||||
|
<textarea :id="tinymceId" class="tinymce-textarea" @change="ada"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* docs:
|
||||||
|
* https://panjiachen.github.io/vue-element-admin-site/feature/component/rich-editor.html#tinymce
|
||||||
|
*/
|
||||||
|
import load from './load'
|
||||||
|
//const toolbar = ['searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript code codesample', 'hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen']
|
||||||
|
//const plugins = ['advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount']
|
||||||
|
// why use this cdn, detail see https://github.com/PanJiaChen/tinymce-all-in-one
|
||||||
|
const tinymceCDN = 'https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/tinymce.min.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'JEditorDyn',
|
||||||
|
props: {
|
||||||
|
id: {
|
||||||
|
type: String,
|
||||||
|
default: function() {
|
||||||
|
return 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
toolbar: {
|
||||||
|
type: [String, Array],
|
||||||
|
required: false,
|
||||||
|
default: 'undo redo | formatselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | lists link unlink image media table | removeformat | fullscreen',
|
||||||
|
},
|
||||||
|
menubar: {
|
||||||
|
type: String,
|
||||||
|
default: 'file edit insert view format table'
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
type: [Number, String],
|
||||||
|
required: false,
|
||||||
|
default: 360
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
type: [Number, String],
|
||||||
|
required: false,
|
||||||
|
default: 'auto'
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
type: [String, Array],
|
||||||
|
default: 'lists image link media table textcolor wordcount contextmenu fullscreen'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
hasChange: false,
|
||||||
|
hasInit: false,
|
||||||
|
tinymceId: this.id,
|
||||||
|
fullscreen: false,
|
||||||
|
languageTypeList: {
|
||||||
|
'en': 'en',
|
||||||
|
'zh': 'zh_CN',
|
||||||
|
'es': 'es_MX',
|
||||||
|
'ja': 'ja'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
containerWidth() {
|
||||||
|
const width = this.width
|
||||||
|
if (/^[\d]+(\.[\d]+)?$/.test(width)) { // matches `100`, `'100'`
|
||||||
|
return `${width}px`
|
||||||
|
}
|
||||||
|
return width
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
value(val) {
|
||||||
|
if (!this.hasChange && this.hasInit) {
|
||||||
|
this.$nextTick(() =>
|
||||||
|
window.tinymce.get(this.tinymceId).setContent(val || ''))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
activated() {
|
||||||
|
if (window.tinymce) {
|
||||||
|
this.initTinymce()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deactivated() {
|
||||||
|
this.destroyTinymce()
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
this.destroyTinymce()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
ada() {
|
||||||
|
console.log('change')
|
||||||
|
},
|
||||||
|
init() {
|
||||||
|
// dynamic load tinymce from cdn
|
||||||
|
load(tinymceCDN, (err) => {
|
||||||
|
if (err) {
|
||||||
|
this.$message.error(err.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.initTinymce()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
initTinymce() {
|
||||||
|
const _this = this
|
||||||
|
window.tinymce.init({
|
||||||
|
selector: `#${this.tinymceId}`,
|
||||||
|
language: this.languageTypeList['zh'],
|
||||||
|
height: this.height,
|
||||||
|
body_class: 'panel-body ',
|
||||||
|
object_resizing: false,
|
||||||
|
toolbar: this.toolbar,
|
||||||
|
menubar: false,
|
||||||
|
plugins: this.plugins,
|
||||||
|
end_container_on_empty_block: true,
|
||||||
|
powerpaste_word_import: 'clean',
|
||||||
|
code_dialog_height: 450,
|
||||||
|
code_dialog_width: 1000,
|
||||||
|
advlist_bullet_styles: 'square',
|
||||||
|
advlist_number_styles: 'default',
|
||||||
|
imagetools_cors_hosts: ['www.tinymce.com', 'codepen.io'],
|
||||||
|
default_link_target: '_blank',
|
||||||
|
link_title: false,
|
||||||
|
nonbreaking_force_tab: true, // inserting nonbreaking space need Nonbreaking Space Plugin
|
||||||
|
init_instance_callback: editor => {
|
||||||
|
if (_this.value) {
|
||||||
|
editor.setContent(_this.value)
|
||||||
|
}
|
||||||
|
_this.hasInit = true
|
||||||
|
editor.on('NodeChange Change KeyUp SetContent', () => {
|
||||||
|
this.hasChange = true
|
||||||
|
this.$emit('input', editor.getContent())
|
||||||
|
})
|
||||||
|
},
|
||||||
|
setup(editor) {
|
||||||
|
editor.on('FullscreenStateChanged', (e) => {
|
||||||
|
_this.fullscreen = e.state
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// it will try to keep these URLs intact
|
||||||
|
// https://www.tiny.cloud/docs-3x/reference/configuration/Configuration3x@convert_urls/
|
||||||
|
// https://stackoverflow.com/questions/5196205/disable-tinymce-absolute-to-relative-url-conversions
|
||||||
|
convert_urls: false
|
||||||
|
// 整合七牛上传
|
||||||
|
// images_dataimg_filter(img) {
|
||||||
|
// setTimeout(() => {
|
||||||
|
// const $image = $(img);
|
||||||
|
// $image.removeAttr('width');
|
||||||
|
// $image.removeAttr('height');
|
||||||
|
// if ($image[0].height && $image[0].width) {
|
||||||
|
// $image.attr('data-wscntype', 'image');
|
||||||
|
// $image.attr('data-wscnh', $image[0].height);
|
||||||
|
// $image.attr('data-wscnw', $image[0].width);
|
||||||
|
// $image.addClass('wscnph');
|
||||||
|
// }
|
||||||
|
// }, 0);
|
||||||
|
// return img
|
||||||
|
// },
|
||||||
|
// images_upload_handler(blobInfo, success, failure, progress) {
|
||||||
|
// progress(0);
|
||||||
|
// const token = _this.$store.getters.token;
|
||||||
|
// getToken(token).then(response => {
|
||||||
|
// const url = response.data.qiniu_url;
|
||||||
|
// const formData = new FormData();
|
||||||
|
// formData.append('token', response.data.qiniu_token);
|
||||||
|
// formData.append('key', response.data.qiniu_key);
|
||||||
|
// formData.append('file', blobInfo.blob(), url);
|
||||||
|
// upload(formData).then(() => {
|
||||||
|
// success(url);
|
||||||
|
// progress(100);
|
||||||
|
// })
|
||||||
|
// }).catch(err => {
|
||||||
|
// failure('err')
|
||||||
|
// console.log(err);
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
})
|
||||||
|
},
|
||||||
|
destroyTinymce() {
|
||||||
|
const tinymce = window.tinymce.get(this.tinymceId)
|
||||||
|
if (this.fullscreen) {
|
||||||
|
tinymce.execCommand('mceFullScreen')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tinymce) {
|
||||||
|
tinymce.destroy()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setContent(value) {
|
||||||
|
window.tinymce.get(this.tinymceId).setContent(value)
|
||||||
|
},
|
||||||
|
getContent() {
|
||||||
|
window.tinymce.get(this.tinymceId).getContent()
|
||||||
|
},
|
||||||
|
imageSuccessCBK(arr) {
|
||||||
|
arr.forEach(v => window.tinymce.get(this.tinymceId).insertContent(`<img class="wscnph" src="${v.url}" >`))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.tinymce-containerty {
|
||||||
|
position: relative;
|
||||||
|
line-height: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tinymce-containerty {
|
||||||
|
::v-deep {
|
||||||
|
.mce-fullscreen {
|
||||||
|
z-index: 10000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tinymce-textarea {
|
||||||
|
visibility: hidden;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-custom-btn-container {
|
||||||
|
position: absolute;
|
||||||
|
right: 4px;
|
||||||
|
top: 4px;
|
||||||
|
/*z-index: 2005;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.fullscreen .editor-custom-btn-container {
|
||||||
|
z-index: 10000;
|
||||||
|
position: fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-upload-btn {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,142 @@
|
|||||||
|
<template>
|
||||||
|
<div class="j-markdown-editor" :id="dynamicId"/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import load from './load'
|
||||||
|
import { md_js, md_zh_cn_js } from './Resource'
|
||||||
|
import defaultOptions from '@/components/jeecg/JMarkdownEditor/default-options.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'JMdEditorDyn',
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
id: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default() {
|
||||||
|
return 'markdown-editor-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return defaultOptions
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: 'markdown'
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: '300px'
|
||||||
|
},
|
||||||
|
language: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: 'zh-CN'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
editor: null,
|
||||||
|
dynamicId: this.id
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
editorOptions() {
|
||||||
|
const options = Object.assign({}, defaultOptions, this.options)
|
||||||
|
options.initialEditType = this.mode
|
||||||
|
options.height = this.height
|
||||||
|
options.language = this.language
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
value(newValue, preValue) {
|
||||||
|
if (newValue !== preValue && newValue !== this.editor.getMarkdown()) {
|
||||||
|
this.editor.setMarkdown(newValue)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
language(val) {
|
||||||
|
this.destroyEditor()
|
||||||
|
this.initEditor()
|
||||||
|
},
|
||||||
|
height(newValue) {
|
||||||
|
this.editor.height(newValue)
|
||||||
|
},
|
||||||
|
mode(newValue) {
|
||||||
|
this.editor.changeMode(newValue)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
this.destroyEditor()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init(){
|
||||||
|
|
||||||
|
this.initEditor()
|
||||||
|
/* load(md_js,'',()=>{
|
||||||
|
load(md_zh_cn_js,'',()=>{
|
||||||
|
|
||||||
|
})
|
||||||
|
})*/
|
||||||
|
},
|
||||||
|
initEditor() {
|
||||||
|
const Editor = toastui.Editor
|
||||||
|
this.editor = new Editor({
|
||||||
|
el: document.getElementById(this.dynamicId),
|
||||||
|
...this.editorOptions
|
||||||
|
})
|
||||||
|
if (this.value) {
|
||||||
|
this.editor.setMarkdown(this.value)
|
||||||
|
}
|
||||||
|
this.editor.on('change', () => {
|
||||||
|
this.$emit('change', this.editor.getMarkdown())
|
||||||
|
})
|
||||||
|
},
|
||||||
|
destroyEditor() {
|
||||||
|
if (!this.editor) return
|
||||||
|
this.editor.off('change')
|
||||||
|
this.editor.remove()
|
||||||
|
},
|
||||||
|
setMarkdown(value) {
|
||||||
|
this.editor.setMarkdown(value)
|
||||||
|
},
|
||||||
|
getMarkdown() {
|
||||||
|
return this.editor.getMarkdown()
|
||||||
|
},
|
||||||
|
setHtml(value) {
|
||||||
|
this.editor.setHtml(value)
|
||||||
|
},
|
||||||
|
getHtml() {
|
||||||
|
return this.editor.getHtml()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
model: {
|
||||||
|
prop: 'value',
|
||||||
|
event: 'change'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped lang="less">
|
||||||
|
|
||||||
|
.j-markdown-editor {
|
||||||
|
/deep/ .tui-editor-defaultUI {
|
||||||
|
.te-mode-switch,
|
||||||
|
.tui-scrollsync
|
||||||
|
{
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -0,0 +1,325 @@
|
|||||||
|
<template>
|
||||||
|
<div class="jeecg-editor-ty" :class="fullCoder?'jeecg-editor-max':'jeecg-editor-min'">
|
||||||
|
<a-icon v-if="fullScreen" class="full-screen-icon" :type="iconType" @click="()=>fullCoder=!fullCoder"/>
|
||||||
|
<textarea :id="dynamicId" />
|
||||||
|
<span @click="nullTipClick" class="null-tip" :class="{'null-tip-hidden': hasCode}" :style="nullTipStyle">{{ placeholderShow }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import load from './load'
|
||||||
|
import '@/assets/less/codemirror_idea.css'
|
||||||
|
import './cm_sql_hint.js'
|
||||||
|
import { sql_keyword } from './Resource'
|
||||||
|
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'JSqlCodeEditorDyn',
|
||||||
|
props:{
|
||||||
|
id: {
|
||||||
|
type: String,
|
||||||
|
default: function() {
|
||||||
|
return 'vue-editor-' + new Date() + ((Math.random() * 1000).toFixed(0) + '')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 显示行号
|
||||||
|
lineNumbers: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
zIndex: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 999
|
||||||
|
},
|
||||||
|
autoHeight: {
|
||||||
|
type: [String, Boolean],
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 不自适应高度的情况下生效的固定高度
|
||||||
|
height: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: '240px'
|
||||||
|
},
|
||||||
|
autoHeight: {
|
||||||
|
type: [String, Boolean],
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 是否显示全屏按钮
|
||||||
|
fullScreen: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
autoHint:{
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
dynamicId: this.id,
|
||||||
|
coder: '',
|
||||||
|
hasCode: false,
|
||||||
|
code: '',
|
||||||
|
// code 编辑器 是否全屏
|
||||||
|
fullCoder: false,
|
||||||
|
iconType: 'fullscreen',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed:{
|
||||||
|
placeholderShow() {
|
||||||
|
if (this.placeholder == null) {
|
||||||
|
return `请在此输入javascript代码`
|
||||||
|
} else {
|
||||||
|
return this.placeholder
|
||||||
|
}
|
||||||
|
},
|
||||||
|
nullTipStyle(){
|
||||||
|
if (this.lineNumbers) {
|
||||||
|
return { left: '36px' }
|
||||||
|
} else {
|
||||||
|
return { left: '12px' }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isAutoHeight() {
|
||||||
|
let {autoHeight} = this
|
||||||
|
if (typeof autoHeight === 'string' && autoHeight.toLowerCase().trim() === '!ie') {
|
||||||
|
autoHeight = !(isIE() || isIE11())
|
||||||
|
} else {
|
||||||
|
autoHeight = true
|
||||||
|
}
|
||||||
|
return autoHeight
|
||||||
|
},
|
||||||
|
fullScreenParentProps() {
|
||||||
|
let props = {
|
||||||
|
class: {
|
||||||
|
'full-screen-parent': true,
|
||||||
|
'full-screen': this.fullCoder,
|
||||||
|
'auto-height': this.isAutoHeight
|
||||||
|
},
|
||||||
|
style: {}
|
||||||
|
}
|
||||||
|
if (this.fullCoder) {
|
||||||
|
props.style['z-index'] = this.zIndex
|
||||||
|
}
|
||||||
|
if (!this.isAutoHeight) {
|
||||||
|
props.style['height'] = (typeof this.height === 'number' ? this.height + 'px' : this.height)
|
||||||
|
}
|
||||||
|
return props
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
fullCoder:{
|
||||||
|
handler(value) {
|
||||||
|
if(value){
|
||||||
|
this.iconType="fullscreen-exit"
|
||||||
|
}else{
|
||||||
|
this.iconType="fullscreen"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
init(){
|
||||||
|
this.main();
|
||||||
|
},
|
||||||
|
main(){
|
||||||
|
let obj = document.getElementById(this.dynamicId);
|
||||||
|
const that = this;
|
||||||
|
let editor = CodeMirror.fromTextArea(obj,{
|
||||||
|
theme:'idea',
|
||||||
|
lineNumbers: this.lineNumbers,
|
||||||
|
lineWrapping: true,
|
||||||
|
mode: "sql",
|
||||||
|
indentUnit: 1,
|
||||||
|
indentWithTabs: true,
|
||||||
|
styleActiveLine: true,
|
||||||
|
/* styleSelectedText: false, */
|
||||||
|
extraKeys: {
|
||||||
|
"F11": function(cm) {
|
||||||
|
that.fullCoder = !that.fullCoder
|
||||||
|
cm.setOption("fullScreen", !cm.getOption("fullScreen"));
|
||||||
|
},
|
||||||
|
"Esc": function(cm) {
|
||||||
|
that.fullCoder = false
|
||||||
|
if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
|
||||||
|
},
|
||||||
|
"Alt-/": function(cm) {
|
||||||
|
cm.showHint();
|
||||||
|
},
|
||||||
|
"Tab": (cm) => {
|
||||||
|
if (cm.somethingSelected()) {
|
||||||
|
cm.indentSelection('add');
|
||||||
|
} else {
|
||||||
|
//cm.indentLine(cm.getCursor().line, "add");
|
||||||
|
//走两格 第三格输入
|
||||||
|
cm.replaceSelection(Array(3).join(" "), "end", "+input");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Shift-Tab": (cm) => {
|
||||||
|
if (cm.somethingSelected()) {
|
||||||
|
cm.indentSelection('subtract');
|
||||||
|
} else {
|
||||||
|
// cm.indentLine(cm.getCursor().line, "subtract");
|
||||||
|
const cursor = cm.getCursor();
|
||||||
|
// 光标回退 indexUnit 字符
|
||||||
|
cm.setCursor({line: cursor.line, ch: cursor.ch - 4});
|
||||||
|
}
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.coder = editor
|
||||||
|
this.addEvent();
|
||||||
|
this.setCoderValue();
|
||||||
|
this.addSystemHint();
|
||||||
|
},
|
||||||
|
setCoderValue(){
|
||||||
|
if(this.value||this.code){
|
||||||
|
this.hasCode=true
|
||||||
|
this.setCodeContent(this.value || this.code)
|
||||||
|
}else{
|
||||||
|
this.coder.setValue('')
|
||||||
|
this.hasCode=false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getCodeContent(){
|
||||||
|
return this.code
|
||||||
|
},
|
||||||
|
setCodeContent(val){
|
||||||
|
setTimeout(()=>{
|
||||||
|
if(!val){
|
||||||
|
this.coder.setValue('')
|
||||||
|
}else{
|
||||||
|
this.coder.setValue(val)
|
||||||
|
}
|
||||||
|
},300)
|
||||||
|
},
|
||||||
|
addSystemHint(){
|
||||||
|
this.coder.setOption('hintOptions', {
|
||||||
|
completeSingle: false,
|
||||||
|
tables: sql_keyword
|
||||||
|
});
|
||||||
|
},
|
||||||
|
addEvent(){
|
||||||
|
if(this.autoHint){
|
||||||
|
this.coder.on('cursorActivity', ()=>{
|
||||||
|
this.coder.showHint();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.coder.on('change', (coder) => {
|
||||||
|
this.code = coder.getValue()
|
||||||
|
if(this.code){
|
||||||
|
this.hasCode=true
|
||||||
|
}else{
|
||||||
|
this.hasCode=false
|
||||||
|
}
|
||||||
|
if (this.$emit) {
|
||||||
|
this.$emit('input', this.code)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.coder.on('focus', () => {
|
||||||
|
this.hasCode=true
|
||||||
|
});
|
||||||
|
this.coder.on('blur', () => {
|
||||||
|
if(this.code){
|
||||||
|
this.hasCode=true
|
||||||
|
}else{
|
||||||
|
this.hasCode=false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
loadResource(src,type){
|
||||||
|
return new Promise((resolve,reject)=>{
|
||||||
|
load(src,type,(msg)=>{
|
||||||
|
if(!msg){
|
||||||
|
resolve();
|
||||||
|
}else{
|
||||||
|
reject(msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
nullTipClick(){
|
||||||
|
this.coder.focus()
|
||||||
|
},
|
||||||
|
fullToggle(){
|
||||||
|
this.fullCoder = !this.fullCoder
|
||||||
|
this.coder.setOption("fullScreen", this.fullCoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="less" >
|
||||||
|
.jeecg-editor-ty{
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.full-screen-icon {
|
||||||
|
opacity: 0;
|
||||||
|
color: black;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 24px;
|
||||||
|
background-color: white;
|
||||||
|
position: absolute;
|
||||||
|
top: 4px;
|
||||||
|
right: 2px;
|
||||||
|
z-index: 9;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
.full-screen-icon {
|
||||||
|
opacity: 1;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(255, 255, 255, 0.88);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.null-tip{
|
||||||
|
position: absolute;
|
||||||
|
top: 4px;
|
||||||
|
left: 36px;
|
||||||
|
z-index: 10;
|
||||||
|
font-size:16px;
|
||||||
|
color: #acaaaac9;
|
||||||
|
line-height: initial;
|
||||||
|
}
|
||||||
|
.null-tip-hidden{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.jeecg-editor-max{
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 999;
|
||||||
|
height: 100%;
|
||||||
|
width: 100% !important;
|
||||||
|
|
||||||
|
.CodeMirror{
|
||||||
|
position: inherit !important;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.full-screen-icon{
|
||||||
|
z-index:9999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,319 @@
|
|||||||
|
<template>
|
||||||
|
<div class="jeecg-editor-ty" :class="fullCoder?'jeecg-editor-max':'jeecg-editor-min'">
|
||||||
|
<a-icon v-if="fullScreen" class="full-screen-icon" :type="iconType" @click="()=>fullCoder=!fullCoder"/>
|
||||||
|
<textarea :id="dynamicId" />
|
||||||
|
<span @click="nullTipClick" class="null-tip" :class="{'null-tip-hidden': hasCode}" :style="nullTipStyle">{{ placeholderShow }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import '@/assets/less/codemirror_idea.css'
|
||||||
|
import './cm_hint.js'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'JsCodeEditorDyn',
|
||||||
|
props:{
|
||||||
|
id: {
|
||||||
|
type: String,
|
||||||
|
default: function() {
|
||||||
|
return 'vue-editor-' + new Date() + ((Math.random() * 1000).toFixed(0) + '')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 显示行号
|
||||||
|
lineNumbers: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
zIndex: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 999
|
||||||
|
},
|
||||||
|
autoHeight: {
|
||||||
|
type: [String, Boolean],
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 不自适应高度的情况下生效的固定高度
|
||||||
|
height: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: '240px'
|
||||||
|
},
|
||||||
|
autoHeight: {
|
||||||
|
type: [String, Boolean],
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 是否显示全屏按钮
|
||||||
|
fullScreen: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
dynamicId: this.id,
|
||||||
|
coder: '',
|
||||||
|
hasCode: false,
|
||||||
|
code: '',
|
||||||
|
// code 编辑器 是否全屏
|
||||||
|
fullCoder: false,
|
||||||
|
iconType: 'fullscreen',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed:{
|
||||||
|
placeholderShow() {
|
||||||
|
if (this.placeholder == null) {
|
||||||
|
return `请在此输入javascript代码`
|
||||||
|
} else {
|
||||||
|
return this.placeholder
|
||||||
|
}
|
||||||
|
},
|
||||||
|
nullTipStyle(){
|
||||||
|
if (this.lineNumbers) {
|
||||||
|
return { left: '36px' }
|
||||||
|
} else {
|
||||||
|
return { left: '12px' }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isAutoHeight() {
|
||||||
|
let {autoHeight} = this
|
||||||
|
if (typeof autoHeight === 'string' && autoHeight.toLowerCase().trim() === '!ie') {
|
||||||
|
autoHeight = !(isIE() || isIE11())
|
||||||
|
} else {
|
||||||
|
autoHeight = true
|
||||||
|
}
|
||||||
|
return autoHeight
|
||||||
|
},
|
||||||
|
fullScreenParentProps() {
|
||||||
|
let props = {
|
||||||
|
class: {
|
||||||
|
'full-screen-parent': true,
|
||||||
|
'full-screen': this.fullCoder,
|
||||||
|
'auto-height': this.isAutoHeight
|
||||||
|
},
|
||||||
|
style: {}
|
||||||
|
}
|
||||||
|
if (this.fullCoder) {
|
||||||
|
props.style['z-index'] = this.zIndex
|
||||||
|
}
|
||||||
|
if (!this.isAutoHeight) {
|
||||||
|
props.style['height'] = (typeof this.height === 'number' ? this.height + 'px' : this.height)
|
||||||
|
}
|
||||||
|
return props
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
fullCoder:{
|
||||||
|
handler(value) {
|
||||||
|
if(value){
|
||||||
|
this.iconType="fullscreen-exit"
|
||||||
|
}else{
|
||||||
|
this.iconType="fullscreen"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
init(){
|
||||||
|
this.main();
|
||||||
|
},
|
||||||
|
main(){
|
||||||
|
let obj = document.getElementById(this.dynamicId);
|
||||||
|
const that = this;
|
||||||
|
let editor = CodeMirror.fromTextArea(obj,{
|
||||||
|
theme:'idea',
|
||||||
|
lineNumbers: this.lineNumbers,
|
||||||
|
lineWrapping: true,
|
||||||
|
mode: "javascript",
|
||||||
|
indentUnit: 1,
|
||||||
|
indentWithTabs: true,
|
||||||
|
styleActiveLine: true,
|
||||||
|
/* styleSelectedText: false, */
|
||||||
|
extraKeys: {
|
||||||
|
"F11": function(cm) {
|
||||||
|
that.fullCoder = !that.fullCoder
|
||||||
|
cm.setOption("fullScreen", !cm.getOption("fullScreen"));
|
||||||
|
},
|
||||||
|
"Esc": function(cm) {
|
||||||
|
that.fullCoder = false
|
||||||
|
if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
|
||||||
|
},
|
||||||
|
"Alt-/": function(cm) {
|
||||||
|
let a = cm.getValue()+""
|
||||||
|
console.log('a',a)
|
||||||
|
cm.showHint();
|
||||||
|
},
|
||||||
|
"Tab": (cm) => {
|
||||||
|
if (cm.somethingSelected()) {
|
||||||
|
cm.indentSelection('add');
|
||||||
|
} else {
|
||||||
|
//cm.indentLine(cm.getCursor().line, "add");
|
||||||
|
//走两格 第三格输入
|
||||||
|
cm.replaceSelection(Array(3).join(" "), "end", "+input");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Shift-Tab": (cm) => {
|
||||||
|
if (cm.somethingSelected()) {
|
||||||
|
cm.indentSelection('subtract');
|
||||||
|
} else {
|
||||||
|
// cm.indentLine(cm.getCursor().line, "subtract");
|
||||||
|
const cursor = cm.getCursor();
|
||||||
|
// 光标回退 indexUnit 字符
|
||||||
|
cm.setCursor({line: cursor.line, ch: cursor.ch - 4});
|
||||||
|
}
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.coder = editor
|
||||||
|
this.addEvent();
|
||||||
|
this.setCoderValue();
|
||||||
|
},
|
||||||
|
setCoderValue(){
|
||||||
|
if(this.value||this.code){
|
||||||
|
this.hasCode=true
|
||||||
|
this.setCodeContent(this.value || this.code)
|
||||||
|
}else{
|
||||||
|
this.coder.setValue('')
|
||||||
|
this.hasCode=false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getCodeContent(){
|
||||||
|
return this.code
|
||||||
|
},
|
||||||
|
setCodeContent(val){
|
||||||
|
setTimeout(()=>{
|
||||||
|
if(!val){
|
||||||
|
this.coder.setValue('')
|
||||||
|
}else{
|
||||||
|
this.coder.setValue(val)
|
||||||
|
}
|
||||||
|
},300)
|
||||||
|
},
|
||||||
|
addEvent(){
|
||||||
|
const that = this;
|
||||||
|
this.coder.on('cursorActivity',function(wl) {
|
||||||
|
let arr = wl.state.activeLines
|
||||||
|
if(arr && arr.length>0){
|
||||||
|
let text = arr[0].text
|
||||||
|
if(text.lastIndexOf('that.')>=0){
|
||||||
|
that.coder.showHint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.coder.on('change', (coder) => {
|
||||||
|
this.code = coder.getValue()
|
||||||
|
if(this.code){
|
||||||
|
this.hasCode=true
|
||||||
|
}else{
|
||||||
|
this.hasCode=false
|
||||||
|
}
|
||||||
|
if (this.$emit) {
|
||||||
|
this.$emit('input', this.code)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.coder.on('focus', () => {
|
||||||
|
this.hasCode=true
|
||||||
|
});
|
||||||
|
this.coder.on('blur', () => {
|
||||||
|
if(this.code){
|
||||||
|
this.hasCode=true
|
||||||
|
}else{
|
||||||
|
this.hasCode=false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
loadResource(src,type){
|
||||||
|
return new Promise((resolve,reject)=>{
|
||||||
|
load(src,type,(msg)=>{
|
||||||
|
if(!msg){
|
||||||
|
resolve();
|
||||||
|
}else{
|
||||||
|
reject(msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
nullTipClick(){
|
||||||
|
this.coder.focus()
|
||||||
|
},
|
||||||
|
fullToggle(){
|
||||||
|
this.fullCoder = !this.fullCoder
|
||||||
|
this.coder.setOption("fullScreen", this.fullCoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="less" >
|
||||||
|
.jeecg-editor-ty{
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.full-screen-icon {
|
||||||
|
opacity: 0;
|
||||||
|
color: black;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 24px;
|
||||||
|
background-color: white;
|
||||||
|
position: absolute;
|
||||||
|
top: 4px;
|
||||||
|
right: 2px;
|
||||||
|
z-index: 9;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
.full-screen-icon {
|
||||||
|
opacity: 1;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(255, 255, 255, 0.88);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.null-tip{
|
||||||
|
position: absolute;
|
||||||
|
top: 4px;
|
||||||
|
left: 36px;
|
||||||
|
z-index: 10;
|
||||||
|
font-size:16px;
|
||||||
|
color: #acaaaac9;
|
||||||
|
line-height: initial;
|
||||||
|
}
|
||||||
|
.null-tip-hidden{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.jeecg-editor-max{
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 999;
|
||||||
|
height: 100%;
|
||||||
|
width: 100% !important;
|
||||||
|
|
||||||
|
.CodeMirror{
|
||||||
|
position: inherit !important;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.full-screen-icon{
|
||||||
|
z-index:9999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
/**js编辑器关键词用于提示*/
|
||||||
|
const js_keyword = [
|
||||||
|
'that',
|
||||||
|
'getAction','postAction','deleteAction',
|
||||||
|
'beforeAdd','beforeEdit','beforeDelete','mounted','created','show'
|
||||||
|
]
|
||||||
|
|
||||||
|
/**js编辑器 方法名用于提示*/
|
||||||
|
const js_method = [
|
||||||
|
'.getSelectOptions','.changeOptions','.triggleChangeValues','.immediateEnhance ','.simpleDateFormat','.lodash'
|
||||||
|
]
|
||||||
|
|
||||||
|
/**sql编辑器 表名字段名用于提示*/
|
||||||
|
const sql_keyword = {
|
||||||
|
sys_user: ['USERNAME', 'REALNAME', 'ID','BIRTHDAY','AGE'],
|
||||||
|
demo: ['name', 'age', 'id', 'sex']
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
js_keyword,
|
||||||
|
js_method,
|
||||||
|
sql_keyword
|
||||||
|
}
|
||||||
@ -0,0 +1,177 @@
|
|||||||
|
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||||
|
// Distributed under an MIT license: https://codemirror.net/LICENSE
|
||||||
|
import { js_keyword, js_method } from './Resource'
|
||||||
|
(function(mod) {
|
||||||
|
mod(CodeMirror);
|
||||||
|
/*if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||||
|
mod(require("../../lib/codemirror"));
|
||||||
|
else if (typeof define == "function" && define.amd) // AMD
|
||||||
|
define(["../../lib/codemirror"], mod);
|
||||||
|
else // Plain browser env*/
|
||||||
|
|
||||||
|
})(function(CodeMirror) {
|
||||||
|
var Pos = CodeMirror.Pos;
|
||||||
|
|
||||||
|
function forEach(arr, f) {
|
||||||
|
for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function arrayContains(arr, item) {
|
||||||
|
if (!Array.prototype.indexOf) {
|
||||||
|
var i = arr.length;
|
||||||
|
while (i--) {
|
||||||
|
if (arr[i] === item) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return arr.indexOf(item) != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function scriptHint(editor, keywords, getToken, options) {
|
||||||
|
// Find the token at the cursor
|
||||||
|
var cur = editor.getCursor(), token = getToken(editor, cur);
|
||||||
|
if (/\b(?:string|comment)\b/.test(token.type)) return;
|
||||||
|
var innerMode = CodeMirror.innerMode(editor.getMode(), token.state);
|
||||||
|
if (innerMode.mode.helperType === "json") return;
|
||||||
|
token.state = innerMode.state;
|
||||||
|
if('.' === token.string){
|
||||||
|
let arr = []
|
||||||
|
for(let k of js_method){
|
||||||
|
arr.push(k)
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
list: arr,
|
||||||
|
from: Pos(cur.line, token.start),
|
||||||
|
to: Pos(cur.line, token.end)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// If it's not a 'word-style' token, ignore the token.
|
||||||
|
if (!/^[\w$_]*$/.test(token.string)) {
|
||||||
|
token = {start: cur.ch, end: cur.ch, string: "", state: token.state,
|
||||||
|
type: token.string == "." ? "property" : null};
|
||||||
|
} else if (token.end > cur.ch) {
|
||||||
|
token.end = cur.ch;
|
||||||
|
token.string = token.string.slice(0, cur.ch - token.start);
|
||||||
|
}
|
||||||
|
|
||||||
|
var tprop = token;
|
||||||
|
// If it is a property, find out what it is a property of.
|
||||||
|
while (tprop.type == "property") {
|
||||||
|
tprop = getToken(editor, Pos(cur.line, tprop.start));
|
||||||
|
if (tprop.string != ".") return;
|
||||||
|
tprop = getToken(editor, Pos(cur.line, tprop.start));
|
||||||
|
if (!context) var context = [];
|
||||||
|
context.push(tprop);
|
||||||
|
}
|
||||||
|
return {list: getCompletions(token, context, keywords, options),
|
||||||
|
from: Pos(cur.line, token.start),
|
||||||
|
to: Pos(cur.line, token.end)};
|
||||||
|
}
|
||||||
|
|
||||||
|
function javascriptHint(editor, options) {
|
||||||
|
return scriptHint(editor, javascriptKeywords,
|
||||||
|
function (e, cur) {return e.getTokenAt(cur);},
|
||||||
|
options);
|
||||||
|
};
|
||||||
|
CodeMirror.registerHelper("hint", "javascript", javascriptHint);
|
||||||
|
|
||||||
|
function getCoffeeScriptToken(editor, cur) {
|
||||||
|
// This getToken, it is for coffeescript, imitates the behavior of
|
||||||
|
// getTokenAt method in javascript.js, that is, returning "property"
|
||||||
|
// type and treat "." as indepenent token.
|
||||||
|
var token = editor.getTokenAt(cur);
|
||||||
|
if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') {
|
||||||
|
token.end = token.start;
|
||||||
|
token.string = '.';
|
||||||
|
token.type = "property";
|
||||||
|
}
|
||||||
|
else if (/^\.[\w$_]*$/.test(token.string)) {
|
||||||
|
token.type = "property";
|
||||||
|
token.start++;
|
||||||
|
token.string = token.string.replace(/\./, '');
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
function coffeescriptHint(editor, options) {
|
||||||
|
return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options);
|
||||||
|
}
|
||||||
|
CodeMirror.registerHelper("hint", "coffeescript", coffeescriptHint);
|
||||||
|
|
||||||
|
var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
|
||||||
|
"toUpperCase toLowerCase split concat match replace search").split(" ");
|
||||||
|
var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " +
|
||||||
|
"lastIndexOf every some filter forEach map reduce reduceRight ").split(" ");
|
||||||
|
var funcProps = "prototype apply call bind".split(" ");
|
||||||
|
|
||||||
|
var javascriptKeywords = ("break case catch class const continue debugger default delete do else export extends false finally for function " +
|
||||||
|
"if in import instanceof new null return super switch this throw true try typeof var void while with yield that").split(" ");
|
||||||
|
for(let jk of js_keyword){
|
||||||
|
javascriptKeywords.push(jk)
|
||||||
|
}
|
||||||
|
var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " +
|
||||||
|
"if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" ");
|
||||||
|
|
||||||
|
function forAllProps(obj, callback) {
|
||||||
|
if (!Object.getOwnPropertyNames || !Object.getPrototypeOf) {
|
||||||
|
for (var name in obj) callback(name)
|
||||||
|
} else {
|
||||||
|
for (var o = obj; o; o = Object.getPrototypeOf(o))
|
||||||
|
Object.getOwnPropertyNames(o).forEach(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCompletions(token, context, keywords, options) {
|
||||||
|
var found = [], start = token.string, global = options && options.globalScope || window;
|
||||||
|
function maybeAdd(str) {
|
||||||
|
if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str);
|
||||||
|
}
|
||||||
|
function gatherCompletions(obj) {
|
||||||
|
if (typeof obj == "string") forEach(stringProps, maybeAdd);
|
||||||
|
else if (obj instanceof Array) forEach(arrayProps, maybeAdd);
|
||||||
|
else if (obj instanceof Function) forEach(funcProps, maybeAdd);
|
||||||
|
forAllProps(obj, maybeAdd)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context && context.length) {
|
||||||
|
// If this is a property, see if it belongs to some object we can
|
||||||
|
// find in the current environment.
|
||||||
|
var obj = context.pop(), base;
|
||||||
|
if (obj.type && obj.type.indexOf("variable") === 0) {
|
||||||
|
if (options && options.additionalContext)
|
||||||
|
base = options.additionalContext[obj.string];
|
||||||
|
if (!options || options.useGlobalScope !== false)
|
||||||
|
base = base || global[obj.string];
|
||||||
|
} else if (obj.type == "string") {
|
||||||
|
base = "";
|
||||||
|
} else if (obj.type == "atom") {
|
||||||
|
base = 1;
|
||||||
|
} else if (obj.type == "function") {
|
||||||
|
if (global.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') &&
|
||||||
|
(typeof global.jQuery == 'function'))
|
||||||
|
base = global.jQuery();
|
||||||
|
else if (global._ != null && (obj.string == '_') && (typeof global._ == 'function'))
|
||||||
|
base = global._();
|
||||||
|
}
|
||||||
|
while (base != null && context.length)
|
||||||
|
base = base[context.pop().string];
|
||||||
|
if (base != null) gatherCompletions(base);
|
||||||
|
} else {
|
||||||
|
// If not, just look in the global object, any local scope, and optional additional-context
|
||||||
|
// (reading into JS mode internals to get at the local and global variables)
|
||||||
|
for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
|
||||||
|
for (var c = token.state.context; c; c = c.prev)
|
||||||
|
for (var v = c.vars; v; v = v.next) maybeAdd(v.name)
|
||||||
|
for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name);
|
||||||
|
if (options && options.additionalContext != null)
|
||||||
|
for (var key in options.additionalContext)
|
||||||
|
maybeAdd(key);
|
||||||
|
if (!options || options.useGlobalScope !== false)
|
||||||
|
gatherCompletions(global);
|
||||||
|
forEach(keywords, maybeAdd);
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,305 @@
|
|||||||
|
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||||
|
// Distributed under an MIT license: https://codemirror.net/LICENSE
|
||||||
|
|
||||||
|
(function(mod) {
|
||||||
|
/*if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||||
|
mod(require("../../lib/codemirror"), require("../../mode/sql/sql"));
|
||||||
|
else if (typeof define == "function" && define.amd) // AMD
|
||||||
|
define(["../../lib/codemirror", "../../mode/sql/sql"], mod);
|
||||||
|
else */
|
||||||
|
// Plain browser env
|
||||||
|
mod(CodeMirror);
|
||||||
|
})(function(CodeMirror) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var tables;
|
||||||
|
var defaultTable;
|
||||||
|
var keywords;
|
||||||
|
var identifierQuote;
|
||||||
|
var CONS = {
|
||||||
|
QUERY_DIV: ";",
|
||||||
|
ALIAS_KEYWORD: "AS"
|
||||||
|
};
|
||||||
|
var Pos = CodeMirror.Pos, cmpPos = CodeMirror.cmpPos;
|
||||||
|
|
||||||
|
function isArray(val) { return Object.prototype.toString.call(val) == "[object Array]" }
|
||||||
|
|
||||||
|
function getKeywords(editor) {
|
||||||
|
var mode = editor.doc.modeOption;
|
||||||
|
if (mode === "sql") mode = "text/x-sql";
|
||||||
|
return CodeMirror.resolveMode(mode).keywords;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getIdentifierQuote(editor) {
|
||||||
|
var mode = editor.doc.modeOption;
|
||||||
|
if (mode === "sql") mode = "text/x-sql";
|
||||||
|
return CodeMirror.resolveMode(mode).identifierQuote || "`";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getText(item) {
|
||||||
|
return typeof item == "string" ? item : item.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
function wrapTable(name, value) {
|
||||||
|
if (isArray(value)) value = {columns: value}
|
||||||
|
if (!value.text) value.text = name
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseTables(input) {
|
||||||
|
var result = {}
|
||||||
|
if (isArray(input)) {
|
||||||
|
for (var i = input.length - 1; i >= 0; i--) {
|
||||||
|
var item = input[i]
|
||||||
|
result[getText(item).toUpperCase()] = wrapTable(getText(item), item)
|
||||||
|
}
|
||||||
|
} else if (input) {
|
||||||
|
for (var name in input)
|
||||||
|
result[name.toUpperCase()] = wrapTable(name, input[name])
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTable(name) {
|
||||||
|
return tables[name.toUpperCase()]
|
||||||
|
}
|
||||||
|
|
||||||
|
function shallowClone(object) {
|
||||||
|
var result = {};
|
||||||
|
for (var key in object) if (object.hasOwnProperty(key))
|
||||||
|
result[key] = object[key];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function match(string, word) {
|
||||||
|
var len = string.length;
|
||||||
|
var sub = getText(word).substr(0, len);
|
||||||
|
return string.toUpperCase() === sub.toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
function addMatches(result, search, wordlist, formatter) {
|
||||||
|
if (isArray(wordlist)) {
|
||||||
|
for (var i = 0; i < wordlist.length; i++)
|
||||||
|
if (match(search, wordlist[i])) result.push(formatter(wordlist[i]))
|
||||||
|
} else {
|
||||||
|
for (var word in wordlist) if (wordlist.hasOwnProperty(word)) {
|
||||||
|
var val = wordlist[word]
|
||||||
|
if (!val || val === true)
|
||||||
|
val = word
|
||||||
|
else
|
||||||
|
val = val.displayText ? {text: val.text, displayText: val.displayText} : val.text
|
||||||
|
if (match(search, val)) result.push(formatter(val))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanName(name) {
|
||||||
|
// Get rid name from identifierQuote and preceding dot(.)
|
||||||
|
if (name.charAt(0) == ".") {
|
||||||
|
name = name.substr(1);
|
||||||
|
}
|
||||||
|
// replace doublicated identifierQuotes with single identifierQuotes
|
||||||
|
// and remove single identifierQuotes
|
||||||
|
var nameParts = name.split(identifierQuote+identifierQuote);
|
||||||
|
for (var i = 0; i < nameParts.length; i++)
|
||||||
|
nameParts[i] = nameParts[i].replace(new RegExp(identifierQuote,"g"), "");
|
||||||
|
return nameParts.join(identifierQuote);
|
||||||
|
}
|
||||||
|
|
||||||
|
function insertIdentifierQuotes(name) {
|
||||||
|
var nameParts = getText(name).split(".");
|
||||||
|
for (var i = 0; i < nameParts.length; i++)
|
||||||
|
nameParts[i] = identifierQuote +
|
||||||
|
// doublicate identifierQuotes
|
||||||
|
nameParts[i].replace(new RegExp(identifierQuote,"g"), identifierQuote+identifierQuote) +
|
||||||
|
identifierQuote;
|
||||||
|
var escaped = nameParts.join(".");
|
||||||
|
if (typeof name == "string") return escaped;
|
||||||
|
name = shallowClone(name);
|
||||||
|
name.text = escaped;
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
function nameCompletion(cur, token, result, editor) {
|
||||||
|
// Try to complete table, column names and return start position of completion
|
||||||
|
var useIdentifierQuotes = false;
|
||||||
|
var nameParts = [];
|
||||||
|
var start = token.start;
|
||||||
|
var cont = true;
|
||||||
|
while (cont) {
|
||||||
|
cont = (token.string.charAt(0) == ".");
|
||||||
|
useIdentifierQuotes = useIdentifierQuotes || (token.string.charAt(0) == identifierQuote);
|
||||||
|
|
||||||
|
start = token.start;
|
||||||
|
nameParts.unshift(cleanName(token.string));
|
||||||
|
|
||||||
|
token = editor.getTokenAt(Pos(cur.line, token.start));
|
||||||
|
if (token.string == ".") {
|
||||||
|
cont = true;
|
||||||
|
token = editor.getTokenAt(Pos(cur.line, token.start));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to complete table names
|
||||||
|
var string = nameParts.join(".");
|
||||||
|
addMatches(result, string, tables, function(w) {
|
||||||
|
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Try to complete columns from defaultTable
|
||||||
|
addMatches(result, string, defaultTable, function(w) {
|
||||||
|
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Try to complete columns
|
||||||
|
string = nameParts.pop();
|
||||||
|
var table = nameParts.join(".");
|
||||||
|
|
||||||
|
var alias = false;
|
||||||
|
var aliasTable = table;
|
||||||
|
// Check if table is available. If not, find table by Alias
|
||||||
|
if (!getTable(table)) {
|
||||||
|
var oldTable = table;
|
||||||
|
table = findTableByAlias(table, editor);
|
||||||
|
if (table !== oldTable) alias = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var columns = getTable(table);
|
||||||
|
if (columns && columns.columns)
|
||||||
|
columns = columns.columns;
|
||||||
|
|
||||||
|
if (columns) {
|
||||||
|
addMatches(result, string, columns, function(w) {
|
||||||
|
var tableInsert = table;
|
||||||
|
if (alias == true) tableInsert = aliasTable;
|
||||||
|
if (typeof w == "string") {
|
||||||
|
w = tableInsert + "." + w;
|
||||||
|
} else {
|
||||||
|
w = shallowClone(w);
|
||||||
|
w.text = tableInsert + "." + w.text;
|
||||||
|
}
|
||||||
|
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
function eachWord(lineText, f) {
|
||||||
|
var words = lineText.split(/\s+/)
|
||||||
|
for (var i = 0; i < words.length; i++)
|
||||||
|
if (words[i]) f(words[i].replace(/[,;]/g, ''))
|
||||||
|
}
|
||||||
|
|
||||||
|
function findTableByAlias(alias, editor) {
|
||||||
|
var doc = editor.doc;
|
||||||
|
var fullQuery = doc.getValue();
|
||||||
|
var aliasUpperCase = alias.toUpperCase();
|
||||||
|
var previousWord = "";
|
||||||
|
var table = "";
|
||||||
|
var separator = [];
|
||||||
|
var validRange = {
|
||||||
|
start: Pos(0, 0),
|
||||||
|
end: Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).length)
|
||||||
|
};
|
||||||
|
|
||||||
|
//add separator
|
||||||
|
var indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV);
|
||||||
|
while(indexOfSeparator != -1) {
|
||||||
|
separator.push(doc.posFromIndex(indexOfSeparator));
|
||||||
|
indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV, indexOfSeparator+1);
|
||||||
|
}
|
||||||
|
separator.unshift(Pos(0, 0));
|
||||||
|
separator.push(Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).text.length));
|
||||||
|
|
||||||
|
//find valid range
|
||||||
|
var prevItem = null;
|
||||||
|
var current = editor.getCursor()
|
||||||
|
for (var i = 0; i < separator.length; i++) {
|
||||||
|
if ((prevItem == null || cmpPos(current, prevItem) > 0) && cmpPos(current, separator[i]) <= 0) {
|
||||||
|
validRange = {start: prevItem, end: separator[i]};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prevItem = separator[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validRange.start) {
|
||||||
|
var query = doc.getRange(validRange.start, validRange.end, false);
|
||||||
|
|
||||||
|
for (var i = 0; i < query.length; i++) {
|
||||||
|
var lineText = query[i];
|
||||||
|
eachWord(lineText, function(word) {
|
||||||
|
var wordUpperCase = word.toUpperCase();
|
||||||
|
if (wordUpperCase === aliasUpperCase && getTable(previousWord))
|
||||||
|
table = previousWord;
|
||||||
|
if (wordUpperCase !== CONS.ALIAS_KEYWORD)
|
||||||
|
previousWord = word;
|
||||||
|
});
|
||||||
|
if (table) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
CodeMirror.registerHelper("hint", "sql", function(editor, options) {
|
||||||
|
tables = parseTables(options && options.tables)
|
||||||
|
var defaultTableName = options && options.defaultTable;
|
||||||
|
var disableKeywords = options && options.disableKeywords;
|
||||||
|
defaultTable = defaultTableName && getTable(defaultTableName);
|
||||||
|
keywords = getKeywords(editor);
|
||||||
|
identifierQuote = getIdentifierQuote(editor);
|
||||||
|
|
||||||
|
if (defaultTableName && !defaultTable)
|
||||||
|
defaultTable = findTableByAlias(defaultTableName, editor);
|
||||||
|
|
||||||
|
defaultTable = defaultTable || [];
|
||||||
|
|
||||||
|
if (defaultTable.columns)
|
||||||
|
defaultTable = defaultTable.columns;
|
||||||
|
|
||||||
|
var cur = editor.getCursor();
|
||||||
|
var result = [];
|
||||||
|
var token = editor.getTokenAt(cur), start, end, search;
|
||||||
|
if (token.end > cur.ch) {
|
||||||
|
token.end = cur.ch;
|
||||||
|
token.string = token.string.slice(0, cur.ch - token.start);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token.string.match(/^[.`"'\w@][\w$#]*$/g)) {
|
||||||
|
search = token.string;
|
||||||
|
start = token.start;
|
||||||
|
end = token.end;
|
||||||
|
} else {
|
||||||
|
start = end = cur.ch;
|
||||||
|
search = "";
|
||||||
|
}
|
||||||
|
if (search.charAt(0) == "." || search.charAt(0) == identifierQuote) {
|
||||||
|
start = nameCompletion(cur, token, result, editor);
|
||||||
|
} else {
|
||||||
|
var objectOrClass = function(w, className) {
|
||||||
|
if (typeof w === "object") {
|
||||||
|
w.className = className;
|
||||||
|
} else {
|
||||||
|
w = { text: w, className: className };
|
||||||
|
}
|
||||||
|
return w;
|
||||||
|
};
|
||||||
|
addMatches(result, search, defaultTable, function(w) {
|
||||||
|
return objectOrClass(w, "CodeMirror-hint-table CodeMirror-hint-default-table");
|
||||||
|
});
|
||||||
|
addMatches(
|
||||||
|
result,
|
||||||
|
search,
|
||||||
|
tables, function(w) {
|
||||||
|
return objectOrClass(w, "CodeMirror-hint-table");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (!disableKeywords)
|
||||||
|
addMatches(result, search, keywords, function(w) {
|
||||||
|
return objectOrClass(w.toUpperCase(), "CodeMirror-hint-keyword");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {list: result, from: Pos(cur.line, start), to: Pos(cur.line, end)};
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
export default {
|
||||||
|
name: 'JSelectBizQueryItem',
|
||||||
|
props: {
|
||||||
|
queryParam: Object,
|
||||||
|
queryConfig: Array,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
renderQueryItem() {
|
||||||
|
return this.queryConfig.map(queryItem => {
|
||||||
|
const {key, label, placeholder, dictCode, props, customRender} = queryItem
|
||||||
|
const options = {
|
||||||
|
props: {},
|
||||||
|
on: {
|
||||||
|
pressEnter: () => this.$emit('pressEnter'),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (props != null) {
|
||||||
|
Object.assign(options.props, props)
|
||||||
|
}
|
||||||
|
if (placeholder === undefined) {
|
||||||
|
if (dictCode) {
|
||||||
|
options.props['placeholder'] = `请选择${label}`
|
||||||
|
} else {
|
||||||
|
options.props['placeholder'] = `请输入${label}`
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
options.props['placeholder'] = placeholder
|
||||||
|
}
|
||||||
|
|
||||||
|
let input
|
||||||
|
if (typeof customRender === 'function') {
|
||||||
|
input = customRender.call(this, {key, options, queryParam: this.queryParam})
|
||||||
|
} else if (dictCode) {
|
||||||
|
input = <j-dict-select-tag {...options} vModel={this.queryParam[key]} dictCode={dictCode} style="width:180px;"/>
|
||||||
|
} else {
|
||||||
|
input = <a-input {...options} vModel={this.queryParam[key]}/>
|
||||||
|
}
|
||||||
|
return <a-form-item key={key} label={label}>{input}</a-form-item>
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
render() {
|
||||||
|
return <span>{this.renderQueryItem()}</span>
|
||||||
|
},
|
||||||
|
}
|
||||||
@ -0,0 +1,111 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
|
// base library
|
||||||
|
import {
|
||||||
|
ConfigProvider,
|
||||||
|
Layout,
|
||||||
|
Input,
|
||||||
|
InputNumber,
|
||||||
|
Button,
|
||||||
|
Switch,
|
||||||
|
Radio,
|
||||||
|
Checkbox,
|
||||||
|
Select,
|
||||||
|
Card,
|
||||||
|
Form,
|
||||||
|
Row,
|
||||||
|
Col,
|
||||||
|
Modal,
|
||||||
|
Table,
|
||||||
|
Tabs,
|
||||||
|
Icon,
|
||||||
|
Badge,
|
||||||
|
Popover,
|
||||||
|
Dropdown,
|
||||||
|
List,
|
||||||
|
Avatar,
|
||||||
|
Breadcrumb,
|
||||||
|
Steps,
|
||||||
|
Spin,
|
||||||
|
Menu,
|
||||||
|
Drawer,
|
||||||
|
Tooltip,
|
||||||
|
Alert,
|
||||||
|
Tag,
|
||||||
|
Divider,
|
||||||
|
DatePicker,
|
||||||
|
TimePicker,
|
||||||
|
Upload,
|
||||||
|
Progress,
|
||||||
|
Skeleton,
|
||||||
|
Popconfirm,
|
||||||
|
PageHeader,
|
||||||
|
Result,
|
||||||
|
Statistic,
|
||||||
|
Descriptions,
|
||||||
|
message,
|
||||||
|
notification,
|
||||||
|
Empty,
|
||||||
|
Tree,
|
||||||
|
TreeSelect,
|
||||||
|
Carousel,
|
||||||
|
Pagination,
|
||||||
|
} from 'ant-design-vue'
|
||||||
|
import Viser from 'viser-vue'
|
||||||
|
|
||||||
|
Vue.use(ConfigProvider)
|
||||||
|
Vue.use(Layout)
|
||||||
|
Vue.use(Input)
|
||||||
|
Vue.use(InputNumber)
|
||||||
|
Vue.use(Button)
|
||||||
|
Vue.use(Switch)
|
||||||
|
Vue.use(Radio)
|
||||||
|
Vue.use(Checkbox)
|
||||||
|
Vue.use(Select)
|
||||||
|
Vue.use(Card)
|
||||||
|
Vue.use(Form)
|
||||||
|
Vue.use(Row)
|
||||||
|
Vue.use(Col)
|
||||||
|
Vue.use(Modal)
|
||||||
|
Vue.use(Table)
|
||||||
|
Vue.use(Tabs)
|
||||||
|
Vue.use(Icon)
|
||||||
|
Vue.use(Badge)
|
||||||
|
Vue.use(Popover)
|
||||||
|
Vue.use(Dropdown)
|
||||||
|
Vue.use(List)
|
||||||
|
Vue.use(Avatar)
|
||||||
|
Vue.use(Breadcrumb)
|
||||||
|
Vue.use(Steps)
|
||||||
|
Vue.use(Spin)
|
||||||
|
Vue.use(Menu)
|
||||||
|
Vue.use(Drawer)
|
||||||
|
Vue.use(Tooltip)
|
||||||
|
Vue.use(Alert)
|
||||||
|
Vue.use(Tag)
|
||||||
|
Vue.use(Divider)
|
||||||
|
Vue.use(DatePicker)
|
||||||
|
Vue.use(TimePicker)
|
||||||
|
Vue.use(Upload)
|
||||||
|
Vue.use(Progress)
|
||||||
|
Vue.use(Skeleton)
|
||||||
|
Vue.use(Popconfirm)
|
||||||
|
Vue.use(PageHeader)
|
||||||
|
Vue.use(Result)
|
||||||
|
Vue.use(Statistic)
|
||||||
|
Vue.use(Descriptions)
|
||||||
|
Vue.use(Empty)
|
||||||
|
Vue.use(Tree)
|
||||||
|
Vue.use(TreeSelect)
|
||||||
|
Vue.use(Carousel)
|
||||||
|
Vue.use(Pagination)
|
||||||
|
|
||||||
|
Vue.prototype.$confirm = Modal.confirm
|
||||||
|
Vue.prototype.$message = message
|
||||||
|
Vue.prototype.$notification = notification
|
||||||
|
Vue.prototype.$info = Modal.info
|
||||||
|
Vue.prototype.$success = Modal.success
|
||||||
|
Vue.prototype.$error = Modal.error
|
||||||
|
Vue.prototype.$warning = Modal.warning
|
||||||
|
|
||||||
|
process.env.NODE_ENV !== 'production' && console.warn('[jeecg-boot-vue] NOTICE: Antd use lazy-load.')
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
// src/icons.js
|
||||||
|
|
||||||
|
// export what you need
|
||||||
|
export {
|
||||||
|
default as SmileOutline
|
||||||
|
} from '@ant-design/icons/lib/outline/SmileOutline';
|
||||||
|
export {
|
||||||
|
default as MehOutline
|
||||||
|
} from '@ant-design/icons/lib/outline/MehOutline';
|
||||||
|
|
||||||
|
// export what antd other components need
|
||||||
|
export {
|
||||||
|
default as CloseOutline
|
||||||
|
} from '@ant-design/icons/lib/outline/CloseOutline';
|
||||||
|
// and other icons...
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import { ONL_AUTH_FIELDS } from "@/store/mutation-types"
|
||||||
|
import { getAction } from '@/api/manage'
|
||||||
|
|
||||||
|
|
||||||
|
const online = {
|
||||||
|
state: {
|
||||||
|
//存储对象属性 value,text
|
||||||
|
authFields: [],
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
SET_AUTHFIELDS: (state, fields) => {
|
||||||
|
console.log('fields',fields)
|
||||||
|
Vue.set(state, 'authFields', fields)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
// TODO 如果没找到可以尝试请求一下
|
||||||
|
xxxxxx({ commit }, userInfo) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default online
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* 功能模块
|
||||||
|
* @type {{LEAVE_EARLY: {text: string, value: string}, LATE: {text: string, value: string}, ABSENT: {text: string, value: string}, NO_SIGN: {text: string, value: string}, NORMAL: {text: string, value: string}}}
|
||||||
|
*/
|
||||||
|
export const FunctionEnum = {
|
||||||
|
EoaCmsBanner: { path: 'modules/eoa/cmsoa/modules/EoaCmsBanner', formData: 'carouselImg' },
|
||||||
|
EoaCmsNewsInfo: { path: 'modules/eoa/cmsoa/modules/EoaCmsNewsInfo', formData: 'newsInfo' },
|
||||||
|
EoaCmsRuleInfo: { path: 'modules/eoa/cmsoa/modules/EoaCmsRuleInfo', formData: 'ruleDownInfo' },
|
||||||
|
EoaCmsSignNews: { path: 'modules/eoa/cmsoa/modules/EoaCmsSignNews', formData: 'signNews' },
|
||||||
|
EoaCmsUserNotice: { path: 'modules/eoa/cmsoa/modules/EoaCmsUserNotice', formData: 'userNotice' },
|
||||||
|
EoaCmsPlan: { path: 'modules/eoa/cmsoa/modules/EoaCmsPlan', formData: '' },
|
||||||
|
EoaCmsLink: { path: 'modules/eoa/cmsoa/modules/EoaCmsLink', formData: '' },
|
||||||
|
EoaCmsCommUse:{ path: 'modules/eoa/cmsbpm/modules/EoaCmsCommUse', formData: '' },
|
||||||
|
EoaCmsMyProcess:{ path: 'modules/eoa/cmsbpm/modules/EoaCmsMyProcess', formData: '' },
|
||||||
|
EoaCmsApplyProcess:{ path: 'modules/eoa/cmsbpm/modules/EoaCmsApplyProcess', formData: '' },
|
||||||
|
EoaCmsProcessNotice:{ path: 'modules/eoa/cmsbpm/modules/EoaCmsProcessNotice', formData: '' },
|
||||||
|
EoaCmsProcessChatData:{ path: 'modules/eoa/cmsbpm/modules/EoaCmsProcessChatData', formData: '' },
|
||||||
|
EoaCmsProcessTypeChat:{ path: 'modules/eoa/cmsbpm/modules/EoaCmsProcessTypeChat', formData: '' },
|
||||||
|
EoaCmsEmail:{ path: 'modules/eoa/cmsbpm/modules/EoaCmsEmail', formData: '' },
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
<template>
|
||||||
|
<a-card :bordered="false">
|
||||||
|
|
||||||
|
<a-tabs>
|
||||||
|
<a-tab-pane tab="基础示例" key="1" forceRender>
|
||||||
|
<j-vxe-demo1/>
|
||||||
|
</a-tab-pane>
|
||||||
|
|
||||||
|
<a-tab-pane tab="高级示例" key="2" forceRender>
|
||||||
|
<j-vxe-demo2/>
|
||||||
|
</a-tab-pane>
|
||||||
|
|
||||||
|
</a-tabs>
|
||||||
|
</a-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import JVxeDemo1 from '@views/jeecg/JVxeDemo/JVxeDemo1'
|
||||||
|
import JVxeDemo2 from '@views/jeecg/JVxeDemo/JVxeDemo2'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'JVXETableDemo',
|
||||||
|
components: {JVxeDemo2, JVxeDemo1},
|
||||||
|
data() {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
methods: {},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
<template>
|
||||||
|
<a-card :bordered="false">
|
||||||
|
<a-tabs>
|
||||||
|
<a-tab-pane tab="ERP布局模板" key="erp">
|
||||||
|
<erp-template/>
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane tab="布局模板1" key="1">
|
||||||
|
<template1/>
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane tab="布局模板2" key="2">
|
||||||
|
<template2/>
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane tab="布局模板3" key="3">
|
||||||
|
<template3/>
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane tab="布局模板4" key="4">
|
||||||
|
<template4/>
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane tab="布局模板5" key="5">
|
||||||
|
<template5/>
|
||||||
|
</a-tab-pane>
|
||||||
|
</a-tabs>
|
||||||
|
</a-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Template1 from './Template1'
|
||||||
|
import Template2 from './Template2'
|
||||||
|
import Template3 from './Template3'
|
||||||
|
import Template4 from './Template4'
|
||||||
|
import Template5 from './Template5'
|
||||||
|
import ErpTemplate from './ErpTemplate'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'LayoutDemo',
|
||||||
|
components: {Template5, Template4, Template3, Template2, Template1, ErpTemplate}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue