|
@@ -29,13 +29,18 @@
|
|
|
</div>
|
|
|
<div v-if="type === 'pdf'" class="addition from-pdf">
|
|
|
<span>{{ $t('documentEditor.dialog.pageRange') }}</span>
|
|
|
- <select name="inputFileRange" v-model="inputFileRange">
|
|
|
- <option value="all">{{ $t('documentEditor.dialog.allPages') }}</option>
|
|
|
- <option value="odd">{{ $t('documentEditor.dialog.oddPage') }}</option>
|
|
|
- <option value="even">{{ $t('documentEditor.dialog.evenPage') }}</option>
|
|
|
- <option value="custom">{{ $t('documentEditor.dialog.customRange') }}</option>
|
|
|
- </select>
|
|
|
- <ArrowDown />
|
|
|
+ <div>
|
|
|
+ <div class="addition">
|
|
|
+ <select name="inputFileRange" v-model="inputFileRange">
|
|
|
+ <option value="all">{{ $t('documentEditor.dialog.allPages') }}</option>
|
|
|
+ <option value="odd">{{ $t('documentEditor.dialog.oddPage') }}</option>
|
|
|
+ <option value="even">{{ $t('documentEditor.dialog.evenPage') }}</option>
|
|
|
+ <option value="custom">{{ $t('documentEditor.dialog.customRange') }}</option>
|
|
|
+ </select>
|
|
|
+ <ArrowDown />
|
|
|
+ </div>
|
|
|
+ <input v-if="inputFileRange === 'custom'" type="text" v-model="customRange" :placeholder="$t('documentEditor.dialog.pageTip')" @blur="validateCustomRange">
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -73,7 +78,8 @@
|
|
|
<!-- footer -->
|
|
|
<template #footer>
|
|
|
<div class="rect-button white" @click="closeDialog">{{ $t('cancel') }}</div>
|
|
|
- <div class="rect-button blue" :class="{ 'disabled': type === 'pdf' && !inputFile }" @click="confirm">{{ $t('documentEditor.insert') }}</div>
|
|
|
+ <div class="rect-button blue" :class="{ 'disabled': type === 'pdf' && (!inputFile || (inputFileRange === 'custom' && !validCustomRange)) }" @click="confirm">{{ $t('documentEditor.insert') }}</div>
|
|
|
+ {{ customRange }}
|
|
|
</template>
|
|
|
</Dialog>
|
|
|
</div>
|
|
@@ -84,7 +90,6 @@ import { ref, computed, watch, h } from 'vue'
|
|
|
import { useViewerStore } from '@/stores/modules/viewer'
|
|
|
import { useDocumentStore } from '@/stores/modules/document'
|
|
|
import core from '@/core'
|
|
|
-import MessageError from '@/assets/icons/icon-message-error.svg'
|
|
|
|
|
|
const props = defineProps([ 'selectedPageIndex', 'totalPages' ])
|
|
|
const emits = defineEmits(['insertPage'])
|
|
@@ -100,6 +105,8 @@ const customPageSize = ref('A3')
|
|
|
let inputFile = null
|
|
|
const fileName = ref('')
|
|
|
const inputFileRange = ref('all')
|
|
|
+const customRange = ref('')
|
|
|
+const validCustomRange = ref('')
|
|
|
|
|
|
const place = ref('first')
|
|
|
const targetIndex = ref(1)
|
|
@@ -123,6 +130,7 @@ const closeDialog = () => {
|
|
|
targetIndex.value = 1
|
|
|
targetPlace.value = 0
|
|
|
}
|
|
|
+
|
|
|
// 确认
|
|
|
const confirm = async () => {
|
|
|
const data = {
|
|
@@ -159,6 +167,8 @@ const confirm = async () => {
|
|
|
|
|
|
if (type.value === 'pdf' && inputFile) {
|
|
|
data.name = fileName.value
|
|
|
+ data.file = inputFile
|
|
|
+ data.range = inputFileRange.value === 'custom' ? customRange.value : inputFileRange.value
|
|
|
}
|
|
|
|
|
|
if (place.value === 'custom') {
|
|
@@ -192,6 +202,57 @@ const validatePageInput = (e) => {
|
|
|
const onblurPageInput = () => {
|
|
|
if (!targetIndex.value) targetIndex.value = 1
|
|
|
}
|
|
|
+
|
|
|
+// 输入自定义页面范围校验 格式化
|
|
|
+const validateCustomRange = () => {
|
|
|
+ validCustomRange.value = formatText(customRange.value)
|
|
|
+ customRange.value = validCustomRange.value
|
|
|
+}
|
|
|
+function formatText(inputText) {
|
|
|
+ const text = inputText.replace(/\s/g, '')
|
|
|
+ const matches = text.match(/\d+-\d+|\d+|\d+/g)
|
|
|
+
|
|
|
+ if (matches) {
|
|
|
+ const sortedNums = matches
|
|
|
+ .flatMap(match => {
|
|
|
+ if (match.includes('-')) {
|
|
|
+ const [start, end] = match.split('-')
|
|
|
+ const smallest = Math.min(start, end)
|
|
|
+ const largest = Math.max(start, end)
|
|
|
+ return Array.from({ length: largest - smallest + 1 }, (_, i) =>
|
|
|
+ String(Number(smallest) + i)
|
|
|
+ )
|
|
|
+ } else {
|
|
|
+ return match
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .sort((a, b) => a - b)
|
|
|
+
|
|
|
+ const formattedText = []
|
|
|
+
|
|
|
+ let start = sortedNums[0]
|
|
|
+ let prev = sortedNums[0]
|
|
|
+
|
|
|
+ for (let i = 1; i < sortedNums.length; i++) {
|
|
|
+ const current = sortedNums[i]
|
|
|
+
|
|
|
+ const prevNum = Number(prev)
|
|
|
+ const currentNum = Number(current)
|
|
|
+
|
|
|
+ if (currentNum - prevNum > 1) {
|
|
|
+ formattedText.push(formatRange(start, prev))
|
|
|
+ start = current
|
|
|
+ }
|
|
|
+ prev = current
|
|
|
+ }
|
|
|
+ formattedText.push(formatRange(start, prev))
|
|
|
+ return formattedText.join(', ')
|
|
|
+ }
|
|
|
+ return '1'
|
|
|
+}
|
|
|
+function formatRange(start, end) {
|
|
|
+ return (start === end) ? start.toString() : `${start}-${end}`
|
|
|
+}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss">
|
|
@@ -270,6 +331,8 @@ const onblurPageInput = () => {
|
|
|
color: #999;
|
|
|
.uploaded {
|
|
|
color: var(--c-text);
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -281,8 +344,24 @@ const onblurPageInput = () => {
|
|
|
cursor: pointer;
|
|
|
}
|
|
|
|
|
|
- &.from-pdf span {
|
|
|
- margin-right: 8px;
|
|
|
+ &.from-pdf {
|
|
|
+ align-items: baseline;
|
|
|
+
|
|
|
+ span {
|
|
|
+ margin-right: 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ > div {
|
|
|
+ flex: 1;
|
|
|
+
|
|
|
+ input[type="text"] {
|
|
|
+ margin-top: 4px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ input[type="text"]:focus {
|
|
|
+ border-color: #0078D7;
|
|
|
}
|
|
|
}
|
|
|
|