|
@@ -8,10 +8,13 @@
|
|
|
<el-main ref="el-main" style="background-color: #fafafa;">
|
|
|
<template>
|
|
|
<div class="content-top">
|
|
|
- <el-radio-group v-model="pinyinType" size="small" @input="radioChange">
|
|
|
- <el-radio-button :label="1">文字注音</el-radio-button>
|
|
|
- <el-radio-button :label="2">文件批量注音</el-radio-button>
|
|
|
- </el-radio-group>
|
|
|
+ <div>
|
|
|
+ <el-radio-group v-model="pinyinType" @input="radioChange">
|
|
|
+ <el-radio-button :label="1">文字注音</el-radio-button>
|
|
|
+ <el-radio-button :label="2">文件批量注音</el-radio-button>
|
|
|
+ </el-radio-group>
|
|
|
+ <vxe-button type="text" status="info" icon="vxe-icon-info-circle-fill" @click="$message({message:'文字注音限制长度10万,超长文本请使用文件注音', type:'warning'})"></vxe-button>
|
|
|
+ </div>
|
|
|
|
|
|
<el-button-group v-if="pinyinType == 2">
|
|
|
<el-button type="primary" size="mini" icon="el-icon-document"
|
|
@@ -25,14 +28,15 @@
|
|
|
@click="txt1='';txtHtml='';">清空内容</el-button>
|
|
|
</div>
|
|
|
|
|
|
- <div style="padding: 15px 20px 0 20px; height: calc(100% - 150px);">
|
|
|
+ <div style="padding: 15px 20px 0 20px; height: calc(100% - 160px);">
|
|
|
<el-row :gutter="20" style="height: 100%;" v-if="pinyinType == 1">
|
|
|
<el-col :span="12" style="height: 100%;">
|
|
|
<el-input style="height: 100%; font-size: 20px;" maxlength="100000" :show-word-limit="true" type="textarea" placeholder="请输入需要注音的文字内容" v-model="txt1" @input="inputChange"></el-input>
|
|
|
</el-col>
|
|
|
- <el-col :span="12" style="height: 100%;">
|
|
|
- <div class="outarea" v-html="txtHtml" v-if="pinBuild == 1"></div>
|
|
|
- <el-input class="outtext" v-if="pinBuild == 2" type="textarea" readonly v-model="txtHtml"></el-input>
|
|
|
+ <el-col :span="12" style="height: 100%;position: relative;">
|
|
|
+ <div class="outarea" :class="tipsShow ? 'red-border' : ''" v-html="txtHtml" v-if="pinBuild == 1"></div>
|
|
|
+ <el-input class="outtext" :class="tipsShow ? 'red-border' : ''" v-if="pinBuild == 2" type="textarea" readonly v-model="txtHtml"></el-input>
|
|
|
+ <p class="pin-tips" v-if="tipsShow">非会员注音限制在20个以内</p>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
|
|
@@ -47,7 +51,8 @@
|
|
|
<p class="title">
|
|
|
<i class="el-icon-notebook-2"></i>
|
|
|
文件列表
|
|
|
- <span style="color: #F22C40;">{{ loadingTips }}</span>
|
|
|
+ <span style="color: #F22C40; float: right;cursor: pointer;"
|
|
|
+ @click="$message({message:'超长文本上下注音时,分割成每30万字导出一份文档', type:'warning'})">{{ loadingTips }}</span>
|
|
|
</p>
|
|
|
<div class="table-scroll" id="drag-table">
|
|
|
<vxe-table
|
|
@@ -210,7 +215,7 @@
|
|
|
popupAdvList: [],
|
|
|
|
|
|
loading: false,
|
|
|
- loadingTips: '',
|
|
|
+ loadingTips: '长度超30万字,点击查看注意事项',
|
|
|
tempPath: '',
|
|
|
procMap: {},
|
|
|
execLimit: 2,
|
|
@@ -223,13 +228,14 @@
|
|
|
pattern: '-',
|
|
|
toneType: '-',
|
|
|
mode: '-',
|
|
|
- nonZh: '-',
|
|
|
+ nonZh: 'consecutive',
|
|
|
separator: ' ',
|
|
|
},
|
|
|
separator: '',
|
|
|
pinBuild: 1,
|
|
|
exportFormat: 'docx',
|
|
|
pinyinType: 1,
|
|
|
+ tipsShow: false,
|
|
|
};
|
|
|
},
|
|
|
async mounted() {
|
|
@@ -378,15 +384,6 @@
|
|
|
let filename = file.substr(file.lastIndexOf(separator) + 1);
|
|
|
let size = fs.statSync(file).size;
|
|
|
|
|
|
- if (!this.$refs.headerRef.authority.isAuthority) {
|
|
|
- // if (size > 1024 * 200) {
|
|
|
- // this.$notify.error({
|
|
|
- // title: '免费版,文件最大不能超过200KB!'
|
|
|
- // });
|
|
|
- // return false;
|
|
|
- // }
|
|
|
- }
|
|
|
-
|
|
|
let fileInfo = {
|
|
|
name: filename,
|
|
|
size: this.$utils.handleSize(size),
|
|
@@ -421,19 +418,33 @@
|
|
|
// 更改设置
|
|
|
inputChange(val){
|
|
|
this.pinSetting.separator = this.separator == '' ? ' ' : this.separator;
|
|
|
+
|
|
|
+ if (!this.$refs.headerRef.authority.isAuthority) {
|
|
|
+ if(val.length > 20){
|
|
|
+ this.tipsShow = true;
|
|
|
+ val = val.slice(0, 20);
|
|
|
+ }else{
|
|
|
+ this.tipsShow = false;
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ this.tipsShow = false;
|
|
|
+ }
|
|
|
+
|
|
|
if(this.pinBuild == 1){ // 上下结构
|
|
|
let htmls = html(val, {toneType : this.pinSetting.toneType, wrapNonChinese: true});
|
|
|
-
|
|
|
- // htmls = htmls.replace(/rp>/g, 'span>');
|
|
|
- // htmls = htmls.replace(/<rt class/g, '<span class');
|
|
|
- // htmls = htmls.replace(/<\/rt>/g, '</span>');
|
|
|
-
|
|
|
let regex1 = new RegExp('py-non-chinese-item"> </span>', "g");
|
|
|
let regex2 = new RegExp('py-non-chinese-item">\n</span>', "g");
|
|
|
let regex3 = new RegExp('</span><span class="py-result-item">', "g");
|
|
|
- htmls = htmls.replace(regex1, 'py-non-chinese-item"> </span>');
|
|
|
- htmls = htmls.replace(regex2, 'py-non-chinese-item">\n</span><br>');
|
|
|
- htmls = htmls.replace(regex3, '</span>'+this.pinSetting.separator+'<span class="py-result-item">');
|
|
|
+ htmls = htmls.replace(regex1, 'py-non-chinese-item"> </span>')
|
|
|
+ .replace(regex2, 'py-non-chinese-item">\n</span><br>')
|
|
|
+ .replace(regex3, '</span>'+this.pinSetting.separator+'<span class="py-result-item">');
|
|
|
+
|
|
|
+ let regex4 = /<ruby><span class="py-chinese-item">|<\/span><rp>|<\/rp><rt class="py-pinyin-item">|<\/rt><rp>|<\/rp><\/ruby>/g;
|
|
|
+
|
|
|
+ htmls = htmls.replace(regex4, '')
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
this.txtHtml = htmls;
|
|
|
}else{
|
|
|
this.txtHtml = pinyin(val, this.pinSetting);
|
|
@@ -496,6 +507,7 @@
|
|
|
if (!authority.isAuthority && !flag) {
|
|
|
this.$refs.headerRef.memberModel = true;
|
|
|
this.$refs.headerRef.isClick = true;
|
|
|
+ this.loading = false;
|
|
|
return false;
|
|
|
} else {
|
|
|
this.$refs.headerRef.memberModel = false;
|
|
@@ -560,13 +572,44 @@
|
|
|
item.percent = num;
|
|
|
this.fileList.splice(index, 1, item);
|
|
|
},
|
|
|
+ async blockFile(index, item, textArr){
|
|
|
+ for(let i = 0; i < textArr.length; i++){
|
|
|
+ let htmls = html(textArr[i], {toneType : this.pinSetting.toneType, wrapNonChinese: true});
|
|
|
+ let regex1 = new RegExp('py-non-chinese-item"> </span>', "g");
|
|
|
+ let regex2 = new RegExp('py-non-chinese-item">\n</span>', "g");
|
|
|
+ let regex3 = new RegExp('</span><span class="py-result-item">', "g");
|
|
|
+ htmls = htmls.replace(regex1, 'py-non-chinese-item"> </span>')
|
|
|
+ .replace(regex2, 'py-non-chinese-item">\n</span><br>')
|
|
|
+ .replace(regex3, '</span>'+this.pinSetting.separator+'<span class="py-result-item">');
|
|
|
+
|
|
|
+
|
|
|
+ let blob = htmlDocx.asBlob(htmls);
|
|
|
+ let buffer = Buffer.from(await blob.arrayBuffer());
|
|
|
+
|
|
|
+ this.showPercent(70, index, item);
|
|
|
+
|
|
|
+ let filePath = this.handleData.newPath + separator + item.name.slice(0, item.name.lastIndexOf('.')) + '(第' + Number(i+1) + '部分).' + this.exportFormat;
|
|
|
+ fs.writeFile(filePath, buffer, (err) => {
|
|
|
+ if (err){
|
|
|
+ this.loading = false;
|
|
|
+ this.$notify.error({
|
|
|
+ title: '错误',
|
|
|
+ message: "出现错误,请重试!" + filePath
|
|
|
+ });
|
|
|
+ throw err;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ this.showPercent(100, index, item);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ },
|
|
|
// 处理文件
|
|
|
dealFile(index, item, newPath) {
|
|
|
return new Promise((resolve, reject) => {
|
|
|
let path = item.path;
|
|
|
-
|
|
|
- this.showPercent(5, index, item);
|
|
|
-
|
|
|
+ this.showPercent(10, index, item);
|
|
|
fs.readFile(path, 'utf8', async(err, data) => {
|
|
|
if (err) {
|
|
|
console.error(err);
|
|
@@ -577,47 +620,76 @@
|
|
|
reject(false);
|
|
|
}
|
|
|
|
|
|
- let outContent = '';
|
|
|
- this.pinSetting.separator = this.separator == '' ? ' ' : this.separator;
|
|
|
- if(this.pinBuild == 1){ // 上下结构
|
|
|
- let htmls = html(data, {toneType : this.pinSetting.toneType, wrapNonChinese: true});
|
|
|
- let regex1 = new RegExp('py-non-chinese-item"> </span>', "g");
|
|
|
- let regex2 = new RegExp('py-non-chinese-item">\n</span>', "g");
|
|
|
- let regex3 = new RegExp('</span><span class="py-result-item">', "g");
|
|
|
- htmls = htmls.replace(regex1, 'py-non-chinese-item"> </span>')
|
|
|
- .replace(regex2, 'py-non-chinese-item">\n</span><br>')
|
|
|
- .replace(regex3, '</span>'+this.pinSetting.separator+'<span class="py-result-item">');
|
|
|
- outContent = htmls;
|
|
|
- }else{
|
|
|
- outContent = pinyin(data, this.pinSetting);
|
|
|
- }
|
|
|
-
|
|
|
- this.showPercent(50, index, item);
|
|
|
-
|
|
|
- let buffer;
|
|
|
- if(this.pinBuild == 1){ // 上下结构
|
|
|
- let blob = htmlDocx.asBlob(outContent);
|
|
|
- buffer = Buffer.from(await blob.arrayBuffer());
|
|
|
- }else{
|
|
|
- buffer = outContent;
|
|
|
+ if (!this.$refs.headerRef.authority.isAuthority) {
|
|
|
+ if(data.length > 20){
|
|
|
+ data = data.slice(0, 20);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- this.showPercent(70, index, item);
|
|
|
-
|
|
|
- let filePath = newPath;
|
|
|
- fs.writeFile(filePath, buffer, (err) => {
|
|
|
- if (err){
|
|
|
- this.loading = false;
|
|
|
+ let textLength = data.length;
|
|
|
+ let blockLength = Math.ceil(textLength / 300000);
|
|
|
+ let textArr = [];
|
|
|
+ if(textLength > 300000 && this.pinBuild == 1){ // 文字长度大于30万字且是上下结构输出,分块处理
|
|
|
+ for(let i=0; i<blockLength; i++){
|
|
|
+ let startIndex = i * 300000;
|
|
|
+ let endIndex = (i+1) * 300000;
|
|
|
+ textArr.push(data.slice(startIndex ,endIndex));
|
|
|
+ }
|
|
|
+ let result = await this.blockFile(index, item, textArr);
|
|
|
+ if(result){
|
|
|
+ this.showPercent(100, index, item);
|
|
|
+ resolve(true);
|
|
|
+ }else{
|
|
|
this.$notify.error({
|
|
|
title: '错误',
|
|
|
message: "出现错误,请重试!" + filePath
|
|
|
});
|
|
|
reject(false);
|
|
|
- throw err;
|
|
|
}
|
|
|
- this.showPercent(100, index, item);
|
|
|
- resolve(true);
|
|
|
- });
|
|
|
+
|
|
|
+ }else{
|
|
|
+ let outContent = '';
|
|
|
+ this.pinSetting.separator = this.separator == '' ? ' ' : this.separator;
|
|
|
+ if(this.pinBuild == 1){ // 上下结构
|
|
|
+ let htmls = html(data, {toneType : this.pinSetting.toneType, wrapNonChinese: true});
|
|
|
+ let regex1 = new RegExp('py-non-chinese-item"> </span>', "g");
|
|
|
+ let regex2 = new RegExp('py-non-chinese-item">\n</span>', "g");
|
|
|
+ let regex3 = new RegExp('</span><span class="py-result-item">', "g");
|
|
|
+ htmls = htmls.replace(regex1, 'py-non-chinese-item"> </span>')
|
|
|
+ .replace(regex2, 'py-non-chinese-item">\n</span><br>')
|
|
|
+ .replace(regex3, '</span>'+this.pinSetting.separator+'<span class="py-result-item">');
|
|
|
+ outContent = htmls;
|
|
|
+ }else{
|
|
|
+ outContent = pinyin(data, this.pinSetting);
|
|
|
+ }
|
|
|
+
|
|
|
+ this.showPercent(50, index, item);
|
|
|
+ let buffer;
|
|
|
+ if(this.pinBuild == 1){ // 上下结构
|
|
|
+ let blob = htmlDocx.asBlob(outContent);
|
|
|
+ buffer = Buffer.from(await blob.arrayBuffer());
|
|
|
+ }else{
|
|
|
+ buffer = Buffer.from(outContent);
|
|
|
+ }
|
|
|
+
|
|
|
+ this.showPercent(70, index, item);
|
|
|
+
|
|
|
+ let filePath = newPath;
|
|
|
+ fs.writeFile(filePath, buffer, (err) => {
|
|
|
+ if (err){
|
|
|
+ this.loading = false;
|
|
|
+ this.$notify.error({
|
|
|
+ title: '错误',
|
|
|
+ message: err.message + filePath
|
|
|
+ });
|
|
|
+ reject(false);
|
|
|
+ throw err;
|
|
|
+ }
|
|
|
+ this.showPercent(100, index, item);
|
|
|
+ resolve(true);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
});
|
|
|
});
|
|
|
},
|
|
@@ -799,4 +871,23 @@
|
|
|
background-color: #4851a415;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ .pin-tips{
|
|
|
+ font-size: 14px;
|
|
|
+ position: absolute;
|
|
|
+ bottom: 10px;
|
|
|
+ color: #ff0000;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ margin: auto;
|
|
|
+ text-align: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .outarea.red-border{
|
|
|
+ border: 1px solid #F56C6C;
|
|
|
+ }
|
|
|
+
|
|
|
+ .outtext.red-border textarea{
|
|
|
+ border: 1px solid #F56C6C;
|
|
|
+ }
|
|
|
</style>
|