This commit is contained in:
张成
2025-10-08 23:12:55 +08:00
parent 7371313d39
commit d387a2d0e9
11 changed files with 224 additions and 1081 deletions

View File

@@ -1,2 +0,0 @@
import PasteEditor from './paste-editor.vue'
export default PasteEditor

View File

@@ -1,26 +0,0 @@
.paste-editor-wrapper{
width: 100%;
height: 100%;
border: 1px dashed gainsboro;
textarea.textarea-el{
width: 100%;
height: 100%;
}
.CodeMirror{
height: 100%;
padding: 0;
.CodeMirror-code div .CodeMirror-line > span > span.cm-tab{
&::after{
content: '→';
color: #BFBFBF;
}
}
}
.first-row{
font-weight: 700;
font-size: 14px;
}
.incorrect-row{
background: #F5CBD1;
}
}

View File

@@ -1,120 +0,0 @@
<template>
<div class="paste-editor-wrapper">
<textarea ref="codemirror" class="textarea-el"></textarea>
</div>
</template>
<script>
import CodeMirror from 'codemirror'
import 'codemirror/lib/codemirror.css'
import { forEach } from '@/utils/tools'
import createPlaceholder from './plugins/placeholder'
export default {
name: 'PasteEditor',
props: {
value: Array,
pasteData: {
type: String,
default: ''
},
placeholder: {
type: String,
default:
'从网页或其他应用软件复制表格数据,粘贴到这里 。默认第一行是表头使用回车键添加新行使用Tab键区分列。'
}
},
data() {
return {
pasteDataArr: [],
rowArrLength: 0,
editor: null
}
},
watch: {
pasteData(val) {
if (val === '') {
this.editor.setValue('')
}
}
},
computed: {
rowNum() {
return this.pasteDataArr.length
},
colNum() {
return this.pasteDataArr[0] ? this.pasteDataArr[0].length : 0
}
},
methods: {
handleKeyup(e) {
this.handleAreaData()
},
/**
* @description 处理粘贴操作
*/
handleContentChanged(content) {
let pasteData = content.trim()
this.$emit('on-content-change', pasteData)
let rows = pasteData.split(/[\n\u0085\u2028\u2029]|\r\n?/g).map(row => {
return row.split('\t')
})
if (content === '') rows = []
this.pasteDataArr = rows
this.clearLineClass()
this.checkColNumInEveryRow()
this.$emit('input', this.pasteDataArr)
},
/**
* @description 检查除第一行的每一行列数是否与第一行相同
*/
checkColNumInEveryRow() {
let i = 0
const len = this.rowNum
if (len === 0) return
while (++i < len) {
let item = this.pasteDataArr[i]
if (
item.length !== this.colNum &&
(!(i === len - 1 && item.length === 1 && item[0] === '') ||
i !== len - 1)
) {
this.markIncorrectRow(i)
this.$emit('on-error', i)
return false
}
}
this.$emit('on-success', this.pasteDataArr)
return true
},
/**
* @description 标记不符合格式的一行
*/
markIncorrectRow(index) {
this.editor.addLineClass(index, 'text', 'incorrect-row')
},
/**
* @description 标记不符合格式的一行
*/
clearLineClass() {
forEach(this.pasteDataArr, (item, index) => {
this.editor.removeLineClass(index, 'text', 'incorrect-row')
})
}
},
mounted() {
createPlaceholder(CodeMirror)
this.editor = CodeMirror.fromTextArea(this.$refs.codemirror, {
lineNumbers: true,
tabSize: 1,
lineWrapping: true,
placeholder: this.placeholder
})
this.editor.on('change', editor => {
this.handleContentChanged(editor.getValue())
})
this.editor.addLineClass(0, 'text', 'first-row')
}
}
</script>
<style lang="less">
@import './paste-editor.less';
</style>

View File

@@ -1,61 +0,0 @@
export default codemirror => {
;(function(mod) {
mod(codemirror)
})(function(CodeMirror) {
CodeMirror.defineOption('placeholder', '', function(cm, val, old) {
var prev = old && old !== CodeMirror.Init
if (val && !prev) {
cm.on('blur', onBlur)
cm.on('change', onChange)
cm.on('swapDoc', onChange)
onChange(cm)
} else if (!val && prev) {
cm.off('blur', onBlur)
cm.off('change', onChange)
cm.off('swapDoc', onChange)
clearPlaceholder(cm)
var wrapper = cm.getWrapperElement()
wrapper.className = wrapper.className.replace(' CodeMirror-empty', '')
}
if (val && !cm.hasFocus()) onBlur(cm)
})
function clearPlaceholder(cm) {
if (cm.state.placeholder) {
cm.state.placeholder.parentNode.removeChild(cm.state.placeholder)
cm.state.placeholder = null
}
}
function setPlaceholder(cm) {
clearPlaceholder(cm)
var elt = (cm.state.placeholder = document.createElement('pre'))
elt.style.cssText = 'height: 0; overflow: visible; color: #80848f;'
elt.style.direction = cm.getOption('direction')
elt.className = 'CodeMirror-placeholder'
var placeHolder = cm.getOption('placeholder')
if (typeof placeHolder === 'string')
placeHolder = document.createTextNode(placeHolder)
elt.appendChild(placeHolder)
cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild)
}
function onBlur(cm) {
if (isEmpty(cm)) setPlaceholder(cm)
}
function onChange(cm) {
let wrapper = cm.getWrapperElement()
let empty = isEmpty(cm)
wrapper.className =
wrapper.className.replace(' CodeMirror-empty', '') +
(empty ? ' CodeMirror-empty' : '')
if (empty) setPlaceholder(cm)
else clearPlaceholder(cm)
}
function isEmpty(cm) {
return cm.lineCount() === 1 && cm.getLine(0) === ''
}
})
}

View File

@@ -49,7 +49,6 @@
</template>
<script>
import SubTreeGrid from './subTreeGrid.vue'
import SubColmns from './subColmns.vue'
import RenderCol from './renderCol.vue'
export default {
@@ -57,7 +56,7 @@ export default {
props: ['columns', 'data', 'grade'],
components: {
RenderCol,
SubTreeGrid,
SubTreeGrid: () => import('./subTreeGrid.vue'),
SubColmns
},
data() {

View File

@@ -26,9 +26,9 @@
</template>
<script>
import './upload.less'
import store from '@/store'
import { getToken } from '@/utils/tools'
let headers = {
'admin-token': store.state.user.token,
'admin-token': getToken(),
}
export default {
name: 'UoloadImg',

View File

@@ -22,10 +22,10 @@
</template>
<script>
import './upload.less'
import store from '@/store'
import { getToken } from '@/utils/tools'
let headers = {
'admin-token': store.state.user.token,
'admin-token': getToken(),
}
export default {