parent
41c1572ad8
commit
8b0ee2d0a2
@ -1,3 +1,3 @@
|
|||||||
NODE_ENV=production
|
NODE_ENV=production
|
||||||
VUE_APP_PLATFORM_NAME=Jeecg-Boot 企业级快速开发平台
|
VUE_APP_PLATFORM_NAME=JeecgBoot 企业级快速开发平台
|
||||||
VUE_APP_SSO=false
|
VUE_APP_SSO=false
|
@ -1 +0,0 @@
|
|||||||
/src
|
|
File diff suppressed because one or more lines are too long
@ -1,11 +1,16 @@
|
|||||||
import JDictSelectTag from './JDictSelectTag.vue'
|
import JDictSelectTag from './JDictSelectTag.vue'
|
||||||
import JMultiSelectTag from './JMultiSelectTag.vue'
|
import JMultiSelectTag from './JMultiSelectTag.vue'
|
||||||
import JSearchSelectTag from './JSearchSelectTag.vue'
|
import JSearchSelectTag from './JSearchSelectTag.vue'
|
||||||
|
import { filterMultiDictText,filterDictText,initDictOptions,filterDictTextByCache } from './JDictSelectUtil'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
install: function (Vue) {
|
install: function (Vue) {
|
||||||
Vue.component('JDictSelectTag',JDictSelectTag);
|
Vue.component('JDictSelectTag',JDictSelectTag);
|
||||||
Vue.component('JMultiSelectTag',JMultiSelectTag);
|
Vue.component('JMultiSelectTag',JMultiSelectTag);
|
||||||
Vue.component('JSearchSelectTag',JSearchSelectTag);
|
Vue.component('JSearchSelectTag',JSearchSelectTag);
|
||||||
|
Vue.prototype.$initDictOptions = (dictCode) => initDictOptions(dictCode)
|
||||||
|
Vue.prototype.$filterMultiDictText = (dictOptions, text) => filterMultiDictText(dictOptions, text)
|
||||||
|
Vue.prototype.$filterDictText = (dictOptions, text) => filterDictText(dictOptions, text)
|
||||||
|
Vue.prototype.$filterDictTextByCache = (...param) => filterDictTextByCache(...param)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,138 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<a-input
|
||||||
|
v-show="!departIds"
|
||||||
|
@click="openSelect"
|
||||||
|
placeholder="请点击选择部门"
|
||||||
|
v-model="departNames"
|
||||||
|
readOnly
|
||||||
|
:disabled="componentDisabled"
|
||||||
|
class="jvxe-select-input">
|
||||||
|
<a-icon slot="prefix" type="cluster" title="部门选择控件"/>
|
||||||
|
</a-input>
|
||||||
|
<j-select-depart-modal
|
||||||
|
ref="innerDepartSelectModal"
|
||||||
|
:modal-width="modalWidth"
|
||||||
|
:multi="multi"
|
||||||
|
:rootOpened="rootOpened"
|
||||||
|
:depart-id="departIds"
|
||||||
|
@ok="handleOK"
|
||||||
|
@initComp="initComp"/>
|
||||||
|
<span style="display: inline-block;height:100%;padding-left:14px" v-if="departIds" >
|
||||||
|
<span @click="openSelect" style="display: inline-block;vertical-align: middle">{{ departNames }}</span>
|
||||||
|
<a-icon style="margin-left:5px;vertical-align: middle" type="close-circle" @click="handleEmpty" title="清空"/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import JVxeCellMixins, { dispatchEvent } from '@/components/jeecg/JVxeTable/mixins/JVxeCellMixins'
|
||||||
|
import JSelectDepartModal from '@/components/jeecgbiz/modal/JSelectDepartModal'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'JVxeDepartSelectCell',
|
||||||
|
mixins: [JVxeCellMixins],
|
||||||
|
components:{
|
||||||
|
JSelectDepartModal
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
departNames: '',
|
||||||
|
departIds: '',
|
||||||
|
selectedOptions: [],
|
||||||
|
customReturnField: 'id'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
custProps() {
|
||||||
|
const {departIds, originColumn: col, caseId, cellProps} = this
|
||||||
|
return {
|
||||||
|
...cellProps,
|
||||||
|
value: departIds,
|
||||||
|
field: col.field || col.key,
|
||||||
|
groupId: caseId,
|
||||||
|
class: 'jvxe-select'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
componentDisabled(){
|
||||||
|
if(this.cellProps.disabled==true){
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
modalWidth(){
|
||||||
|
if(this.cellProps.modalWidth){
|
||||||
|
return this.cellProps.modalWidth
|
||||||
|
}else{
|
||||||
|
return 500
|
||||||
|
}
|
||||||
|
},
|
||||||
|
multi(){
|
||||||
|
if(this.cellProps.multi==false){
|
||||||
|
return false
|
||||||
|
}else{
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rootOpened(){
|
||||||
|
if(this.cellProps.open==false){
|
||||||
|
return false
|
||||||
|
}else{
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
innerValue: {
|
||||||
|
immediate: true,
|
||||||
|
handler(val) {
|
||||||
|
if (val == null || val === '') {
|
||||||
|
this.departIds = ''
|
||||||
|
} else {
|
||||||
|
this.departIds = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
openSelect(){
|
||||||
|
this.$refs.innerDepartSelectModal.show()
|
||||||
|
},
|
||||||
|
handleEmpty(){
|
||||||
|
this.handleOK('')
|
||||||
|
},
|
||||||
|
handleOK(rows, idstr) {
|
||||||
|
let value = ''
|
||||||
|
if (!rows && rows.length <= 0) {
|
||||||
|
this.departNames = ''
|
||||||
|
this.departIds = ''
|
||||||
|
} else {
|
||||||
|
value = rows.map(row => row[this.customReturnField]).join(',')
|
||||||
|
this.departNames = rows.map(row => row['departName']).join(',')
|
||||||
|
this.departIds = idstr
|
||||||
|
}
|
||||||
|
this.handleChangeCommon(this.departIds)
|
||||||
|
},
|
||||||
|
initComp(departNames){
|
||||||
|
this.departNames = departNames
|
||||||
|
},
|
||||||
|
handleChange(value) {
|
||||||
|
this.handleChangeCommon(value)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enhanced: {
|
||||||
|
switches: {
|
||||||
|
visible: true
|
||||||
|
},
|
||||||
|
translate: {
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/deep/ .jvxe-select-input .ant-input{
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,136 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<a-input
|
||||||
|
v-show="!userIds"
|
||||||
|
@click="openSelect"
|
||||||
|
placeholder="请选择用户"
|
||||||
|
v-model="userNames"
|
||||||
|
readOnly
|
||||||
|
class="jvxe-select-input"
|
||||||
|
:disabled="componentDisabled">
|
||||||
|
<a-icon slot="prefix" type="user" title="用户选择控件"/>
|
||||||
|
</a-input>
|
||||||
|
<j-select-user-by-dep-modal
|
||||||
|
ref="selectModal"
|
||||||
|
:modal-width="modalWidth"
|
||||||
|
:multi="multi"
|
||||||
|
:user-ids="userIds"
|
||||||
|
@ok="selectOK"
|
||||||
|
@initComp="initComp"/>
|
||||||
|
<span style="display: inline-block;height:100%;padding-left:14px" v-if="userIds" >
|
||||||
|
<span @click="openSelect" style="display: inline-block;vertical-align: middle">{{ userNames }}</span>
|
||||||
|
<a-icon style="margin-left:5px;vertical-align: middle" type="close-circle" @click="handleEmpty" title="清空"/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <j-select-user-by-dep
|
||||||
|
v-bind="custProps"
|
||||||
|
@change="handleChange"
|
||||||
|
:trigger-change="true">
|
||||||
|
</j-select-user-by-dep>-->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import JVxeCellMixins, { dispatchEvent } from '@/components/jeecg/JVxeTable/mixins/JVxeCellMixins'
|
||||||
|
import JSelectUserByDepModal from '@/components/jeecgbiz/modal/JSelectUserByDepModal'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'JVxeUserSelectCell',
|
||||||
|
mixins: [JVxeCellMixins],
|
||||||
|
components: { JSelectUserByDepModal },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
userIds:'',
|
||||||
|
userNames:'',
|
||||||
|
innerUserValue: '',
|
||||||
|
selectedOptions: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
custProps() {
|
||||||
|
const {userIds, originColumn: col, caseId, cellProps} = this
|
||||||
|
return {
|
||||||
|
...cellProps,
|
||||||
|
value: userIds,
|
||||||
|
field: col.field || col.key,
|
||||||
|
groupId: caseId,
|
||||||
|
class: 'jvxe-select'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
componentDisabled(){
|
||||||
|
console.log('333',this.cellProps)
|
||||||
|
if(this.cellProps.disabled==true){
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
modalWidth(){
|
||||||
|
if(this.cellProps.modalWidth){
|
||||||
|
return this.cellProps.modalWidth
|
||||||
|
}else{
|
||||||
|
return 1250
|
||||||
|
}
|
||||||
|
},
|
||||||
|
multi(){
|
||||||
|
if(this.cellProps.multi==false){
|
||||||
|
return false
|
||||||
|
}else{
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
innerValue: {
|
||||||
|
immediate: true,
|
||||||
|
handler(val) {
|
||||||
|
if (val == null || val === '') {
|
||||||
|
this.userIds = ''
|
||||||
|
} else {
|
||||||
|
this.userIds = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
openSelect() {
|
||||||
|
this.$refs.selectModal.showModal()
|
||||||
|
},
|
||||||
|
selectOK(rows, idstr) {
|
||||||
|
console.log("当前选中用户", rows)
|
||||||
|
console.log("当前选中用户ID", idstr)
|
||||||
|
if (!rows) {
|
||||||
|
this.userNames = ''
|
||||||
|
this.userIds = ''
|
||||||
|
} else {
|
||||||
|
let temp = ''
|
||||||
|
for (let item of rows) {
|
||||||
|
temp += ',' + item.realname
|
||||||
|
}
|
||||||
|
this.userNames = temp.substring(1)
|
||||||
|
this.userIds = idstr
|
||||||
|
}
|
||||||
|
this.handleChangeCommon(this.userIds)
|
||||||
|
},
|
||||||
|
handleEmpty(){
|
||||||
|
this.selectOK('')
|
||||||
|
},
|
||||||
|
initComp(userNames) {
|
||||||
|
this.userNames = userNames
|
||||||
|
},
|
||||||
|
},
|
||||||
|
enhanced: {
|
||||||
|
switches: {
|
||||||
|
visible: true
|
||||||
|
},
|
||||||
|
translate: {
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/deep/ .jvxe-select-input .ant-input {
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,246 +0,0 @@
|
|||||||
<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>
|
|
@ -1,142 +0,0 @@
|
|||||||
<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>
|
|
@ -1,325 +0,0 @@
|
|||||||
<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>
|
|
@ -1,319 +0,0 @@
|
|||||||
<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>
|
|
@ -1,24 +0,0 @@
|
|||||||
|
|
||||||
/**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
|
|
||||||
}
|
|
@ -1,177 +0,0 @@
|
|||||||
// 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;
|
|
||||||
}
|
|
||||||
});
|
|
@ -1,305 +0,0 @@
|
|||||||
// 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)};
|
|
||||||
});
|
|
||||||
});
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,28 @@
|
|||||||
|
INSERT INTO SYS_DICT_ITEM(ID, DICT_ID, ITEM_TEXT, ITEM_VALUE, DESCRIPTION, SORT_ORDER, STATUS, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME) VALUES ('1334440962954936321', '1209733563293962241', 'MYSQL5.7', '4', NULL, '1', '1', 'admin', '2020-12-03 18:16:02', 'admin', '2020-12-03 18:16:02');
|
||||||
|
UPDATE SYS_DICT_ITEM SET ITEM_TEXT = 'MySQL5.5' WHERE ID = '1209733775114702850';
|
||||||
|
UPDATE SYS_DICT_ITEM SET SORT_ORDER = '3' WHERE ID = '1209733839933476865';
|
||||||
|
UPDATE SYS_DICT_ITEM SET SORT_ORDER = '4' WHERE ID = '1209733903020003330';
|
||||||
|
|
||||||
|
ALTER TABLE `sys_gateway_route`
|
||||||
|
CHANGE COLUMN `persist` `persistable` int(3) NULL DEFAULT NULL COMMENT '是否为保留数据:0-否 1-是' AFTER `strip_prefix`;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS `test_online_link`;
|
||||||
|
CREATE TABLE `test_online_link` (
|
||||||
|
`id` varchar(32) NOT NULL,
|
||||||
|
`pid` varchar(32) DEFAULT NULL COMMENT 'pid',
|
||||||
|
`name` varchar(255) DEFAULT NULL COMMENT 'name',
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
INSERT INTO `test_online_link` VALUES ('1', NULL, '中国');
|
||||||
|
INSERT INTO `test_online_link` VALUES ('10', '8', '庐阳区');
|
||||||
|
INSERT INTO `test_online_link` VALUES ('11', '7', '黄山市');
|
||||||
|
INSERT INTO `test_online_link` VALUES ('2', '1', '山东省');
|
||||||
|
INSERT INTO `test_online_link` VALUES ('3', '2', '济南市');
|
||||||
|
INSERT INTO `test_online_link` VALUES ('4', '3', '历城区');
|
||||||
|
INSERT INTO `test_online_link` VALUES ('5', '3', '长青区');
|
||||||
|
INSERT INTO `test_online_link` VALUES ('6', '2', '青岛市');
|
||||||
|
INSERT INTO `test_online_link` VALUES ('7', '1', '安徽省');
|
||||||
|
INSERT INTO `test_online_link` VALUES ('8', '7', '合肥市');
|
||||||
|
INSERT INTO `test_online_link` VALUES ('9', '8', '包河区');
|
||||||
|
|
||||||
|
update ONL_CGFORM_FIELD set DB_TYPE = 'Date' WHERE DB_TYPE = 'date';
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue