<template>
	<div>
		<el-container style="user-select: none; height: 100vh;">
			<el-header height="45px" style="background-color: #fafafa; padding: 0 10px;">
				<soft-header ref="headerRef" @update-soft="updateSoft()"
					@export-file="exportFile"></soft-header>
			</el-header>
			<el-main ref="el-main" style="background-color: #fafafa;">
				<template>
					<div class="content-top">
						<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"
								@click="pickFile()">添加文件</el-button>
							<el-button type="primary" size="mini" icon="el-icon-folder"
								@click="pickDir()">添加文件夹</el-button>
							<el-button type="primary" size="mini" icon="el-icon-delete"
								@click="clearList()">清空列表</el-button>
						</el-button-group>
						<el-button v-else type="info" size="mini" 
							@click="txt1='';txtHtml='';">清空内容</el-button>
					</div>
					
					<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%;position: relative;">
								<el-input class="outtext" :class="tipsShow ? 'red-border' : ''" v-if="pinBuild == 3" type="textarea" readonly v-model="txtHtml"></el-input>
								<div class="outarea" :class="tipsShow ? 'red-border' : ''" v-html="txtHtml" v-else></div>
								<p class="pin-tips" v-if="tipsShow">非会员注音限制在20个以内</p>
							</el-col>
						</el-row>
						
						<div v-if="pinyinType == 2 && fileList.length == 0" class="upload-area">
							<div class="file-area" @click="pickFile()" id="drag-table">
								<img src="../assets/image/upload.png" style="width: 220px;"/>
								<p style="font-size: 16px;">点击添加TXT/DOCX文件或拖拽TXT/DOCX文件到此</p>
							</div>
						</div>
						
						<div style="height: 100%;" v-if="pinyinType == 2 && fileList.length > 0">
							<p class="title">
								<i class="el-icon-notebook-2"></i>
								文件列表
								<span style="color: #F22C40; float: right;cursor: pointer;"
								 @click="$message({message:'超长文本结构注音时,分割成每10万字导出一份文档', type:'warning'})">{{ loadingTips }}</span>
							</p>
							<div class="table-scroll" id="drag-table">
								<vxe-table
									show-overflow
									class="img-table"
									max-height="100%"
									empty-text="没有更多数据了！"
									:row-config="{isHover: true}"
									:edit-config="{trigger: 'click', mode: 'cell'}"
									:data="fileList"
									:scroll-y="{enabled: true}">
									<vxe-column field="name" title="文件名"></vxe-column>
									<vxe-column field="size" title="大小" width="120"></vxe-column>
									<vxe-column field="progress" title="进度" width="180">
										<template #default="{ row }">
											<el-progress :text-inside="true" :stroke-width="20" :percentage="row.percent"></el-progress>
										</template>
									</vxe-column>
									<vxe-column title="操作" width="80">
										<template #default="{ row, rowIndex }">
											<i class="el-icon-delete cur-pointer" @click="delFile(rowIndex)"></i>
										</template>
									</vxe-column>
								</vxe-table>
							</div>
						</div>
					</div>
					
					<div style="padding: 0 20px;">
						<el-row type="flex" style="padding-top: 10px;">
							<div class="set-item">
								<span class="set-title">注音结构：</span>
								<el-select v-model="pinBuild" size="small" style="width:100px;" @change="dataChange">
									<el-option label="上下结构" :value="1"></el-option>
									<el-option label="左右结构" :value="2"></el-option>
									<el-option label="只要拼音" :value="3"></el-option>
								</el-select>
							</div>
							<div class="set-item">
								<span class="set-title">拼音风格：</span>
								<el-select v-model="pinSetting.toneType" size="small" style="width:100px;" @change="dataChange">
									<el-option label="带声调" value="-"></el-option>
									<el-option label="不带声调" value="none"></el-option>
									<el-option label="数字后缀" value="num"></el-option>
								</el-select>
							</div>
							<div class="set-item" v-if="pinBuild == 3">
								<span class="set-title">输出内容：</span>
								<el-select v-model="pinSetting.pattern" size="small" style="width:100px;" @change="dataChange">
									<el-option label="完整拼音" value="-"></el-option>
									<el-option label="声母" value="initial"></el-option>
									<el-option label="韵母" value="final"></el-option>
									<el-option label="韵头" value="finalHead"></el-option>
									<el-option label="韵腹" value="finalBody"></el-option>
									<el-option label="韵尾" value="finalTail"></el-option>
									<el-option label="音调" value="num"></el-option>
									<el-option label="首字母" value="first"></el-option>
								</el-select>
							</div>
							<div class="set-item">
								<span class="set-title">导出格式：</span>
								<el-select v-model="exportFormat" size="small" style="width:100px;" >
									<el-option label="docx" value="docx"></el-option>
									<el-option label="txt" value="txt" v-if="pinBuild == 3"></el-option>
								</el-select>
								<vxe-button type="text" status="info" icon="vxe-icon-info-circle-fill" @click="$message({message:'上下/左右结构注音时，只能输出docx文件', type:'warning'})"></vxe-button>
							</div>
						</el-row>
						
						<el-row type="flex" style="padding: 10px 0;">
							<div class="set-item" v-if="pinBuild == 3">
								<span class="set-title">模式：</span>
								<el-select v-model="pinSetting.mode" size="small" style="width:100px;" @change="dataChange">
									<el-option label="普通模式" value="-"></el-option>
									<el-option label="姓氏模式" value="surname"></el-option>
								</el-select>
							</div>
							<div class="set-item" v-if="pinBuild == 3">
								<span class="set-title">非汉字：</span>
								<el-select v-model="pinSetting.nonZh" size="small" style="width:140px;" @change="dataChange">
									<el-option label="以空格间隔输出" value="-"></el-option>
									<el-option label="移除非汉字字符" value="removed"></el-option>
									<el-option label="字符串紧凑输出" value="consecutive"></el-option>
								</el-select>
							</div>
							<div class="set-item">
								<span class="set-title">分隔符：</span>
								<el-input type="text" maxlength="4" :show-word-limit="true" v-model="separator" size="small" placeholder="默认为空格" style="width:125px;" @input="dataChange"></el-input>
							</div>
							
							<div class="set-item">
								<span class="set-title">保存目录：</span>
								<el-input :title="handleData.newPath" ref="upload-input" @focus="pickPath" placeholder="请选择输出目录" size="small" v-model="handleData.newPath" readonly style="width:180px;" prefix-icon="el-icon-folder"></el-input>
								<el-popover placement="bottom" popper-class="popper-open" trigger="hover" content="打开保存目录">
									<i class="el-icon-folder-opened" slot="reference" style="padding-left: 5px; cursor: pointer; font-size: 22px; vertical-align: middle;" @click="openFolder()"></i>
								</el-popover>
							</div>
							
							<el-button type="danger" class="export-btn" @click="exportFile()" :loading="loading">导出注音</el-button>
						</el-row>
					</div>

				</template>

			</el-main>
			
			<el-footer height="48px">
				<!-- 更新 -->
				<soft-update ref="updateRef" :showDowload="dowloadModel"
					:dowloadFinish="finishModel"></soft-update>
			</el-footer>
			
		</el-container>
	</div>
</template>

<script>
	import os from 'os'
	import fs from 'fs'
	import pathMod from 'path';
	import softUpdate from './update.vue';
	import softHeader from './header.vue';
	import electronApi from '@/utils/electronApi';
	import pjson from '/package.json'
	import { pinyin, html } from 'pinyin-pro';
	import htmlDocx from 'html-docx-js/dist/html-docx';
	import mammoth from 'mammoth';

	let separator = '';
	if (os.platform == 'linux') {
		separator = '/'
	} else {
		separator = '\\'
	}

	export default {
		name: 'landing-page',
		components: {
			softUpdate,
			softHeader
		},
		data() {
			return {
				productName: pjson.softInfo.softName,
				imgUrl: this.$api.imgUrl,
				imgSrc: '',

				fileList: [],
				
				downloadDir: '', // 默认下载目录
				handleData: {
					pathType: 2,
					newPath: os.userInfo().homedir + separator + "Downloads", // 新路径
				},
				dowloadModel: false,
				finishModel: false,
				version: '0.0.1',

				isStart: false, // 是否开始转换
				isUpdate: false, // 是否有更新

				softdownloadUrl: os.userInfo().homedir + separator + "Downloads", // 下载路径
				popupAdvList: [],

				loading: false,
				loadingTips: '长度超10万字,点击查看注意事项',
				tempPath: '',
				procMap: {},
				execLimit: 2,

				exportLoading: false,
				
				txt1: '',
				txtHtml: '',
				pinSetting: {
					pattern: '-',
					toneType: '-',
					mode: '-',
					nonZh: 'consecutive',
					separator: ' ',
				},
				separator: '',
				pinBuild: 1,
				exportFormat: 'docx',
				pinyinType: 1,
				tipsShow: false,
			};
		},
		async mounted() {
			
			this.tempPath = os.tmpdir();
			this.$refs.updateRef.updateSoft(true);

			let homedir = os.userInfo().homedir;
			if (fs.existsSync(homedir + separator + "Desktop")) {
				this.downloadDir = homedir + separator + "Desktop"
			} else {
				this.downloadDir = homedir + separator + "Downloads"
			}
			this.handleData.newPath = this.downloadDir;

			// 打开浏览器
			const {
				shell
			} = require('electron');
			const links = document.querySelectorAll('a[href]');
			links.forEach(link => {
				link.addEventListener('click', e => {
					const url = link.getAttribute('href');
					e.preventDefault();
					shell.openExternal(url);
				});
			});

		},
		methods: {
			radioChange(e){
				if(e == 2){
					setTimeout(() => {
						// 加载拖拽监听事件
						this.initDrop();
					}, 500)
				}
			},
			// 加载拖拽监听事件
			initDrop() {
				const dragWrapper = document.getElementById("drag-table");
				let domArr = [dragWrapper];
				domArr.map(item => {
					//添加拖拽事件监听器
					item.addEventListener("drop", (e) => {
						//阻止默认行为
						e.preventDefault();
						//获取文件列表
						let files = e.dataTransfer.files;
						let pathArr = [];
						for (let i = 0; i < files.length; i++) {
							pathArr.push(files[i].path);
						}
						this.pushFileToList(pathArr);
					})
					//阻止拖拽结束事件默认行为
					item.addEventListener("dragover", (e) => {
						e.preventDefault();
					})
				})
			},
			// 删除列表文件
			delFile(index){
				this.$confirm('确认删除此文件吗?', '提示', {
					confirmButtonText: '确定',
					cancelButtonText: '取消',
					type: 'warning'
				}).then(() => {
					this.fileList.splice(index, 1);
					if (this.fileList.length ==0) {
						this.clearList();
					}
				}).catch(() => {
						  
				});
			},
			// 选择目录
			pickPath() {
				this.$refs['upload-input'].blur();
				electronApi.call('pickDir', []).then((path) => {
					if (path) {
						this.handleData.newPath = path;
						this.downloadDir = path;
					}
				});
			},
			// 打开自定义下载目录
			openFolder() {
				let path = this.downloadDir;
				if (fs.existsSync(this.downloadDir + separator + pjson.softInfo.softName)) {
					path = this.downloadDir + separator + pjson.softInfo.softName;
				} else {
					fs.mkdirSync(this.downloadDir + separator + pjson.softInfo.softName);
					path = this.downloadDir + separator + pjson.softInfo.softName;
				}
				electronApi.call('showItemInfolder', [path + '\\tty.tty'])
			},
			// 选择新路径
			getFolder(e) {
				this.handleData.newPath = e.path;
				this.downloadDir = e.path;
			},
			openVip() {
				this.$refs.headerRef.openVip();
			},
			updateSoft() {
				this.$refs.updateRef.updateSoft();
			},
			// 清除列表
			clearList() {
				this.fileList = [];
			},
			async pickFile() {
				const spinLoad = this.$loading();
				await electronApi.call('pickFile', ['txt,docx', true]).then(async (files) => {
					this.pushFileToList(files);
					spinLoad.close();
				});
			},
			async pickDir() {
				const spinLoad = this.$loading();
				await electronApi.call('pickDir', [os.userInfo().homedir]).then((path) => {
					this.dealDir(path);
					spinLoad.close();
				});
			},
			dealDir(currentDirPath) {
				if (currentDirPath) {
					let files = fs.readdirSync(currentDirPath);

					for (let i = 0; i < files.length; i++) {
						let name = files[i];
						var filePath = pathMod.join(currentDirPath, name);
						var stat = fs.statSync(filePath);

						if (stat.isFile()) {
							this.pushFileToList([filePath]);
						} else if (stat.isDirectory()) {
							this.dealDir(filePath)
						}
					}
				}
			},
			pushFileToList(files) {
				files.map(file => {
					let filename = file.substr(file.lastIndexOf(separator) + 1);
					let size = fs.statSync(file).size;

					let fileInfo = {
						name: filename,
						size: this.$utils.handleSize(size),
						path: file,
						type: filename.lastIndexOf('.') == -1 ? '' : filename.substr(filename.lastIndexOf('.') + 1),
						percent: 0,
					};

					if (!fileInfo.type) {
						this.$message({message: '不是有效的文件！ - ' + file, type: 'warning'});
					} else {
						let flag = true;
						let format = ["TXT", "DOCX"];
						if (format.indexOf(fileInfo.type.toUpperCase()) == -1) {
							this.$message({message: '不支持该文件格式！ - ' + file, type: 'warning'});
						} else {
							for (let m = 0; m < this.fileList.length; m++) {
								if (this.fileList[m].name == fileInfo.name && this.fileList[m].path == fileInfo.path) {
									flag = false;
								}
							}

							if (flag) {
								this.fileList.push(fileInfo);
							} else {
								this.$message({message: '该文件已经在队列中 - ' + file, type: 'warning'});
							}
						}
					}
				})
			},
			// 更改设置
			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 == 3){ // 只要拼音
					this.txtHtml = pinyin(val, this.pinSetting);
				}else{
					let htmls = this.dealHtml(html(val, {toneType : this.pinSetting.toneType, wrapNonChinese: true}));
					if(this.pinBuild == 2){ // 左右结构
						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;
				}
			},
			dataChange(){
				if(this.pinBuild != 3 && this.exportFormat == 'txt'){
					this.exportFormat = 'docx';
				}
				this.inputChange(this.txt1);
			},
			// 导出
			async exportFile(flag) {
				this.loading = true;
				if (fs.existsSync(this.downloadDir + separator + pjson.softInfo.softName)) {
					this.handleData.newPath = this.downloadDir + separator + pjson.softInfo.softName;
				} else {
					fs.mkdirSync(this.downloadDir + separator + pjson.softInfo.softName);
					this.handleData.newPath = this.downloadDir + separator + pjson.softInfo.softName;
				}
				
				if(this.pinyinType == 1){ // 文字注音
					if(this.txt1.length <= 0){
						this.$message({message: '请输入需要注音的文字', type: 'warning'});
						this.loading = false;
						return false;
					}
					
					let htmlContent = this.txtHtml;
					let buffer;
					if(this.pinBuild == 3){ // 只要拼音
						buffer = htmlContent;
					}else{
						let blob = htmlDocx.asBlob(htmlContent);
						buffer = Buffer.from(await blob.arrayBuffer());
					}
					let filePath = this.handleData.newPath + "\\" + "注音文档" + this.$utils.formatFileTime() + '.' + this.exportFormat;
					
					fs.writeFile(filePath, buffer, (err) => {
						if (err){
							this.loading = false;
							throw err;
						}
						setTimeout(() => {
							this.loading = false;
							this.$message({message: "注音完成！", type: 'success'});
							electronApi.call('showItemInfolder', [filePath]);
						}, 1000)
					});
					
				}else{ // 文件批量注音
					if(this.fileList.length <= 0){
						this.$message({message: '请选择需要注音的TXT/DOCX文档', type: 'warning'});
						this.loading = false;
						return false;
					}else{
						let fileList = this.fileList;
						let authority = this.$refs.headerRef.authority;
						
						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;
						}
						
						//percent
						let taskArr = [];
						let newPath = '';
						setTimeout(async() => {
							for (let i = 0; i < fileList.length; i++) {
								let item = fileList[i];
								let lastIndex = item.path.lastIndexOf('.');
								let suffix = this.exportFormat;
								newPath = this.handleData.newPath + separator + item.name.slice(0, item.name.lastIndexOf('.')) + '.' + suffix;
								// 处理文件
								let task = this.dealFile(i, item, newPath);
								if (task) {
									taskArr.push(task);
								}
							
								if ((i + 1) % this.execLimit == 0) {
									await Promise.all(taskArr).then(result => {
										taskArr = [];
									}).catch(err => {
										console.log('err' + i, err)
									})
								}
							}
							
							if (taskArr.length > 0) {
								await Promise.all(taskArr).then(result => {
									taskArr = [];
								}).catch(err => {
									// 错误文件添加到服务中
									console.log('err', err)
								})
							}
							
							// 打开文件夹
							if (fileList.length > 0) {
								this.loading = false;
								this.$message({message: "恭喜你，任务已完成！", type: 'success'});
								electronApi.call('showItemInfolder', [this.handleData.newPath + '\\xy.txt'])
							}
						}, 300)
						
					}
					
					setTimeout(() => {
						this.loading = false;
					}, 30000)
				}
			},
			showPercent(num, index, item){
				item.percent = num;
				this.fileList.splice(index, 1, item);
			},
			// 格式化html
			dealHtml(htmls){
				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">&nbsp;</span>')
							.replace(regex2, 'py-non-chinese-item">\n</span><br>')
							.replace(regex3, '</span>'+this.pinSetting.separator+'<span class="py-result-item">');
				return htmls;
			},
			async blockFile(index, item, textArr){
				for(let i = 0; i < textArr.length; i++){
					let htmls = this.dealHtml(html(textArr[i], {toneType : this.pinSetting.toneType, wrapNonChinese: true}));
					if(this.pinBuild == 2){ // 左右结构
						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, '');
					}
					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(10, index, item);
					if(item.type.toUpperCase() == 'DOCX'){ // word文档
						mammoth.extractRawText({path: path}).then(async(res) =>{
							let data = res.value;
							let result = await this.pinFile(index, item, newPath, data);
							if(result){
								resolve(true);
							}else{
								reject(false);
							}
						}).catch((error) => {
							console.error(error);
							this.$notify.error({
								title: '错误',
								message: "出现错误，请重试！" + filePath
							});
							reject(false);
						});
					}else{
						fs.readFile(path, 'utf8', async(err, data) => {
							if (err) {
								console.error(err);
								this.$notify.error({
									title: '错误',
									message: "出现错误，请重试！" + filePath
								});
								reject(false);
							}
							let result = await this.pinFile(index, item, newPath, data);
							if(result){
								resolve(true);
							}else{
								reject(false);
							}
						});
					}
				});
			},
			// 文件注音
			async pinFile(index, item, newPath, data) {
				if (!this.$refs.headerRef.authority.isAuthority) {
					if(data.length > 20){
						data = data.slice(0, 20);
					}
				}
				
				let textLength = data.length;
				let blockLength = Math.ceil(textLength / 100000);
				let textArr = [];
				if(textLength > 100000 && this.pinBuild != 3){ // 文字长度大于10万字且是结构输出，分块处理
					for(let i=0; i<blockLength; i++){
						let startIndex = i * 100000;
						let endIndex = (i+1) * 100000;
						textArr.push(data.slice(startIndex ,endIndex));
					}
					let result = await this.blockFile(index, item, textArr);
					if(result){
						this.showPercent(100, index, item);
						return true;
					}else{
						this.$notify.error({
							title: '错误',
							message: "出现错误，请重试！" + filePath
						});
						return false;
					}
				}else{
					let outContent = '';
					this.pinSetting.separator = this.separator == '' ? ' ' : this.separator;
					if(this.pinBuild == 3){ // 只要拼音
						outContent = pinyin(data, this.pinSetting);
					}else{
						let htmls = this.dealHtml(html(data, {toneType : this.pinSetting.toneType, wrapNonChinese: true}));
						if(this.pinBuild == 2){ // 左右结构
							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, '');
						}
						outContent = htmls;
					}
					
					this.showPercent(50, index, item);
					
					let buffer;
					if(this.pinBuild == 3){ // 只要拼音
						buffer = outContent;
					}else{
						let blob = htmlDocx.asBlob(outContent);
						buffer = Buffer.from(await blob.arrayBuffer());
					}
					
					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
							});
							return false;
							throw err;
						}
						this.showPercent(100, index, item);
						return true;
					});
				}
			},
			
			
		}
	};
</script>

<style lang="scss">
	@import "../assets/css/font/iconfont.css";
	@import "../assets/css/fontx/iconfont.css";
	@import "../assets/css/home.scss";

	.ivu-input-number-controls-outside-btn i {
		font-weight: 800;
	}

	.update-point {
		display: inline-block;
		width: 8px;
		height: 8px;
		border-radius: 8px;
		background: #ff0000;
		top: 14px;
		position: absolute;
		left: -13px;
	}

	.menu-item {
		padding: 8px 0;
		font-size: 14px;

		.iconfont {
			font-size: 32px;
		}

		&:hover,
		&.active {
			color: #ed4014;
		}
	}

	.ivu-progress-show-info .ivu-progress-outer {
		padding-right: 40px !important;
		margin-right: -40px !important;
	}

	.tips {
		text-align: center;
		padding: 10px 0;
		color: #ed4014;
		font-size: 12px;
	}

	.soft-content {
		height: calc(100% - 118px);
	}

	.handle-label {
		vertical-align: top;
	}

	.handle-desc {
		display: inline-block;
		width: calc(100% - 100px);
		overflow: hidden;
	}

	.ivu-menu-submenu-title {
		font-weight: 600;
	}

	.ivu-menu .ivu-menu-item {
		line-height: 1;
	}

	// new-el
	.el-menu {
		border-right: none !important;
	}

	.cmenu-item {
		padding: 0 20px 20px;
		margin-bottom: 15px;

		.cmenu-title {
			font-size: 18px;
			font-weight: 600;
			padding-bottom: 20px;
		}

		.citem-nav {
			text-align: center;
			border-radius: 10px;
			min-height: 110px;
			padding: 15px 0;
			background-color: #fff;
			font-size: 15px;
			cursor: pointer;

			&.bg-linear1 {
				color: #fff;
				font-size: 20px;
				background: linear-gradient(to right bottom, #2A56CA, #5795F4);
			}

			&.bg-linear2 {
				color: #fff;
				font-size: 20px;
				background: linear-gradient(to right top, #147FBB, #5EB3E3);
			}

			&.bg-linear3 {
				color: #fff;
				font-size: 20px;
				background: linear-gradient(to right bottom, #2F9E8A, #56CDB1);
			}

			&:hover {
				margin-top: -5px;
				box-shadow: 3px 3px 6px #ccc, -3px -3px 6px #ccc;
			}

			.citem-img {
				width: 50px;
				margin-bottom: 10px;
			}
		}
	}
	
	.popper-open{
		text-align: center !important;
		padding: 10px !important;
		background: #303133 !important;
		color: #fff !important;
		min-width: 120px !important;
		opacity: 0.8;
	}
	
	.popper-open[x-placement^=bottom] .popper__arrow::after{
		border-bottom-color: #303133 !important;
	}
	
	textarea.el-textarea__inner{
		height: 100% !important;
		font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;
	}
	
	.set-item{
		margin-right: 15px;
		
		.set-title{
			font-size: 13px;
		}
	}
	
	.export-btn{
		position:absolute !important;
		right: 0;
		bottom: 20px;
	}
	
	.outarea{
		height: 100%;
		border: 1px solid #DCDFE6;
		background-color: #4851a415; 
		padding: 15px;
		font-size: 20px;
		overflow: hidden auto;
	}
	
	.outtext{
		height: 100%;
		font-size: 20px;
		overflow: hidden auto;
		
		textarea{
			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>