mirror of
https://gitee.com/x_discoverer/Vue.NetCore.git
synced 2025-12-06 15:59:41 +08:00
Compare commits
3 Commits
7e05819d55
...
6156ad08fe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6156ad08fe | ||
|
|
5e5b921a84 | ||
|
|
8cb8bbe4f3 |
17
README.md
17
README.md
@@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Vue + .Net8前后端分离,不一样的快速开发框架(支持信创)
|
## Vue + .Net8前后端分离,不一样的快速开发框架(支持信创)
|
||||||
|
|
||||||
## 框架核心
|
## 框架核心
|
||||||
@@ -41,32 +42,32 @@ App、H5、微信小程序: [http://app.volcore.xyz/](http://app.volcore.xyz/) <
|
|||||||
sqlsugar: [https://www.donet5.com/](https://www.donet5.com/)
|
sqlsugar: [https://www.donet5.com/](https://www.donet5.com/)
|
||||||
|
|
||||||
## 框架移动端(uniapp)已发布,同样全自动生成代码,扫描小程序二维码即可查看
|
## 框架移动端(uniapp)已发布,同样全自动生成代码,扫描小程序二维码即可查看
|
||||||

|

|
||||||
|
|
||||||
## 1、标准页面
|
## 1、标准页面
|
||||||
整个页面所有前后端代码,全部由代码生成器界面上配置生成,并支持并后端业务代码扩展
|
整个页面所有前后端代码,全部由代码生成器界面上配置生成,并支持并后端业务代码扩展
|
||||||

|

|
||||||
|
|
||||||
## 2、主子表页面
|
## 2、主子表页面
|
||||||
同样由代码生成器自动生成,零代码实现整个页面主子表的新建、编辑、删除、查询、导入、导出功能
|
同样由代码生成器自动生成,零代码实现整个页面主子表的新建、编辑、删除、查询、导入、导出功能
|
||||||

|

|
||||||
|
|
||||||
主子表编辑页面
|
主子表编辑页面
|
||||||

|

|
||||||
|
|
||||||
## 3、审批流程配置
|
## 3、审批流程配置
|
||||||

|

|
||||||
|
|
||||||
## 4、数据审批
|
## 4、数据审批
|
||||||

|

|
||||||
|
|
||||||
## 5、树形结构
|
## 5、树形结构
|
||||||
只需少量配置即可完成树形结构配置编辑,按层级加载数据等功能
|
只需少量配置即可完成树形结构配置编辑,按层级加载数据等功能
|
||||||

|

|
||||||
|
|
||||||
## 6、图表统计
|
## 6、图表统计
|
||||||
框架提供了丰富的图表统计,能复制就能开发
|
框架提供了丰富的图表统计,能复制就能开发
|
||||||

|

|
||||||
|
|
||||||
其他功能。。。。。
|
其他功能。。。。。
|
||||||
|
|
||||||
|
|||||||
180
vol.web/src/components/VolProvider/VolImgCompress.js
Normal file
180
vol.web/src/components/VolProvider/VolImgCompress.js
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* 创建图片对象
|
||||||
|
* @param {File} file - 图片文件
|
||||||
|
* @returns {Promise<HTMLImageElement>} - 图片对象
|
||||||
|
*/
|
||||||
|
function createImage(file) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const img = new Image();
|
||||||
|
img.onload = () => resolve(img);
|
||||||
|
img.onerror = reject;
|
||||||
|
img.src = URL.createObjectURL(file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查图片是否包含透明度
|
||||||
|
* @param {HTMLImageElement} img - 图片对象
|
||||||
|
* @returns {Promise<boolean>} - 是否包含透明度
|
||||||
|
*/
|
||||||
|
function checkImageHasAlpha(img) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
canvas.width = img.width;
|
||||||
|
canvas.height = img.height;
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
ctx.drawImage(img, 0, 0);
|
||||||
|
|
||||||
|
// 获取图像数据
|
||||||
|
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||||
|
const data = imageData.data;
|
||||||
|
|
||||||
|
// 检查是否有像素的alpha通道值小于255(即透明)
|
||||||
|
for (let i = 3; i < data.length; i += 4) {
|
||||||
|
if (data[i] < 255) {
|
||||||
|
resolve(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} mimeType - 目标MIME类型
|
||||||
|
* @param {number} originalSize - 原始文件大小(字节)
|
||||||
|
* @param {number} maxSize - 最大允许大小(字节)
|
||||||
|
* @param {Function} onProgress - 进度回调函数
|
||||||
|
* @returns {Promise<Blob>} - 压缩后的Blob对象
|
||||||
|
*/
|
||||||
|
function compressWithBinarySearch(canvas, mimeType, originalSize, maxSize, onProgress) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
let minQuality = 0.1;
|
||||||
|
let maxQuality = 1.0;
|
||||||
|
let bestBlob = null;
|
||||||
|
let bestSize = originalSize;
|
||||||
|
|
||||||
|
// 最多尝试10次,平衡效率和精度
|
||||||
|
const maxIterations = 10;
|
||||||
|
let iterations = 0;
|
||||||
|
|
||||||
|
function updateProgress(currentIteration) {
|
||||||
|
if (onProgress) {
|
||||||
|
const progress = Math.round((currentIteration / maxIterations) * 100);
|
||||||
|
onProgress(progress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function compress(quality) {
|
||||||
|
canvas.toBlob(
|
||||||
|
(blob) => {
|
||||||
|
iterations++;
|
||||||
|
updateProgress(iterations);
|
||||||
|
|
||||||
|
if (!blob) {
|
||||||
|
// 如果转换失败,使用默认质量
|
||||||
|
canvas.toBlob(resolve, mimeType, 0.5);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const blobSize = blob.size;
|
||||||
|
|
||||||
|
// 更新最佳结果
|
||||||
|
if (blobSize < bestSize) {
|
||||||
|
bestBlob = blob;
|
||||||
|
bestSize = blobSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否符合条件或达到最大迭代次数
|
||||||
|
if (blobSize <= maxSize || iterations >= maxIterations || maxQuality - minQuality < 0.01) {
|
||||||
|
resolve(bestBlob);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 二分调整质量
|
||||||
|
if (blobSize > maxSize) {
|
||||||
|
// 压缩后仍太大,降低质量
|
||||||
|
maxQuality = quality;
|
||||||
|
} else {
|
||||||
|
// 压缩后符合要求,尝试提高质量以获得更好效果
|
||||||
|
minQuality = quality;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下一次尝试的质量
|
||||||
|
const nextQuality = (minQuality + maxQuality) / 2;
|
||||||
|
compress(nextQuality);
|
||||||
|
},
|
||||||
|
mimeType,
|
||||||
|
quality
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始压缩
|
||||||
|
compress(0.8);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {File} file - 上传的图片文件
|
||||||
|
* @param {Object} options - 压缩选项
|
||||||
|
* @param {number} options.maxSize - 最大允许大小(字节),默认400KB
|
||||||
|
* @param {number} options.initialQuality - 初始压缩质量(0-1),默认0.7
|
||||||
|
* @param {Function} options.onProgress - 进度回调函数
|
||||||
|
* @returns {Promise<File>} - 压缩后的图片文件
|
||||||
|
*/
|
||||||
|
export async function compressImage(file, options = {}) {
|
||||||
|
const {
|
||||||
|
maxSize = 300 * 1024,
|
||||||
|
initialQuality = 0.7,
|
||||||
|
onProgress
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
// 如果文件已经小于等于最大尺寸,直接返回
|
||||||
|
if (file.size <= maxSize) {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建图片对象
|
||||||
|
const img = await createImage(file);
|
||||||
|
|
||||||
|
// 创建canvas并绘制图片
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
// 设置canvas尺寸,保持原始宽高比
|
||||||
|
canvas.width = img.width;
|
||||||
|
canvas.height = img.height;
|
||||||
|
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
// 根据文件类型选择压缩策略
|
||||||
|
const fileType = file.type;
|
||||||
|
let compressedBlob;
|
||||||
|
|
||||||
|
if (fileType === 'image/png') {
|
||||||
|
// PNG处理:检查是否有透明度,决定压缩策略
|
||||||
|
const hasAlpha = await checkImageHasAlpha(img);
|
||||||
|
|
||||||
|
if (hasAlpha) {
|
||||||
|
// 有透明度的PNG:使用PNG压缩,但可能效果有限
|
||||||
|
compressedBlob = await compressWithBinarySearch(canvas, 'image/png', file.size, maxSize, onProgress);
|
||||||
|
} else {
|
||||||
|
// 无透明度的PNG:转换为JPEG压缩,效果更好
|
||||||
|
compressedBlob = await compressWithBinarySearch(canvas, 'image/jpeg', file.size, maxSize, onProgress);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 其他格式(如JPEG、WebP等)直接压缩
|
||||||
|
compressedBlob = await compressWithBinarySearch(canvas, fileType, file.size, maxSize, onProgress);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将Blob转换为File对象
|
||||||
|
return new File([compressedBlob], file.name, {
|
||||||
|
type: compressedBlob.type,
|
||||||
|
lastModified: file.lastModified
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 默认导出
|
||||||
|
export default compressImage;
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import common from '@/uitils/common.js'
|
import common from '@/uitils/common.js'
|
||||||
|
import {compressImage } from './VolImgCompress.js'
|
||||||
import store from '@/store/index'
|
import store from '@/store/index'
|
||||||
const getImgUrls = (imgs) => {
|
const getImgUrls = (imgs) => {
|
||||||
return imgs
|
return imgs
|
||||||
@@ -27,6 +28,8 @@ const getFormValues = (formFields, formOptions) => {
|
|||||||
if (typeof val == 'function') {
|
if (typeof val == 'function') {
|
||||||
formValues[key] = formFields[key]()
|
formValues[key] = formFields[key]()
|
||||||
continue
|
continue
|
||||||
|
} else if (typeof val == 'string' && val) {
|
||||||
|
val = val.trim();
|
||||||
}
|
}
|
||||||
//解决下拉框清除后不能保存数据的问题
|
//解决下拉框清除后不能保存数据的问题
|
||||||
if (val === undefined) {
|
if (val === undefined) {
|
||||||
@@ -282,9 +285,13 @@ const getSearchParameters = (proxy, formFields, formRules) => {
|
|||||||
//查询下面所有的子节点,如:选中的是父节点,应该查询下面所有的节点数据--待完
|
//查询下面所有的子节点,如:选中的是父节点,应该查询下面所有的节点数据--待完
|
||||||
if (value && value.length) {
|
if (value && value.length) {
|
||||||
let nodes = proxy.base.getTreeAllChildren(value[value.length - 1], option.orginData)
|
let nodes = proxy.base.getTreeAllChildren(value[value.length - 1], option.orginData)
|
||||||
value = nodes.map((x) => {
|
if (!(nodes?.length)) {
|
||||||
return x.id
|
value = [value[value.length - 1]]
|
||||||
})
|
} else {
|
||||||
|
value = nodes.map((x) => {
|
||||||
|
return x.id
|
||||||
|
})
|
||||||
|
}
|
||||||
displayType = 'selectList'
|
displayType = 'selectList'
|
||||||
}
|
}
|
||||||
} else if (displayType == 'treeSelect' && Array.isArray(value)) {
|
} else if (displayType == 'treeSelect' && Array.isArray(value)) {
|
||||||
@@ -335,11 +342,22 @@ const resetFileName = async (files, callbck) => {
|
|||||||
if (!files?.length) return
|
if (!files?.length) return
|
||||||
for (let index = 0; index < files.length; index++) {
|
for (let index = 0; index < files.length; index++) {
|
||||||
let originalFile = files[index]
|
let originalFile = files[index]
|
||||||
|
if (!originalFile.size) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const uniqueFileName = await callbck?.(originalFile) || generateUniqueFileName(originalFile.name);
|
const uniqueFileName = await callbck?.(originalFile) || generateUniqueFileName(originalFile.name);
|
||||||
const newFile = new File([originalFile], uniqueFileName, {
|
if (uniqueFileName===false) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let extension='';
|
||||||
|
if (!uniqueFileName.includes('.')) {
|
||||||
|
extension='.'+originalFile.name.split('.').pop();
|
||||||
|
}
|
||||||
|
const newFile = new File([originalFile], uniqueFileName+extension, {
|
||||||
type: originalFile.type,
|
type: originalFile.type,
|
||||||
lastModified: originalFile.lastModified
|
lastModified: originalFile.lastModified
|
||||||
});
|
});
|
||||||
|
newFile.input=originalFile.input
|
||||||
files.splice(index, 1, newFile);
|
files.splice(index, 1, newFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -360,5 +378,6 @@ export default {
|
|||||||
getAccessToken,
|
getAccessToken,
|
||||||
isEmptyValue,
|
isEmptyValue,
|
||||||
getSearchParameters,
|
getSearchParameters,
|
||||||
resetFileName
|
resetFileName,
|
||||||
|
compressImage
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,21 +3,11 @@
|
|||||||
<div>
|
<div>
|
||||||
<!-- style="margin-bottom: 10px" -->
|
<!-- style="margin-bottom: 10px" -->
|
||||||
<div class="input-btns" style="display: flex">
|
<div class="input-btns" style="display: flex">
|
||||||
<input
|
<input ref="input" type="file" style="display: none" @change="handleChange" :multiple="multiple" />
|
||||||
ref="input"
|
|
||||||
type="file"
|
|
||||||
style="display: none"
|
|
||||||
@change="handleChange"
|
|
||||||
:multiple="multiple"
|
|
||||||
/>
|
|
||||||
<div v-if="img" class="upload-img">
|
<div v-if="img" class="upload-img">
|
||||||
<!-- v-for="(file,index) in fileInfo.length>0?fileInfo: files" -->
|
<!-- v-for="(file,index) in fileInfo.length>0?fileInfo: files" -->
|
||||||
<div
|
<div v-for="(file, index) in files" :key="index"
|
||||||
v-for="(file, index) in files"
|
:style="{ height: imgInfo.height + 'px', width: imgInfo.width + 'px' }" class="img-item">
|
||||||
:key="index"
|
|
||||||
:style="{ height: imgInfo.height + 'px', width: imgInfo.width + 'px' }"
|
|
||||||
class="img-item"
|
|
||||||
>
|
|
||||||
<div class="operation">
|
<div class="operation">
|
||||||
<div class="action">
|
<div class="action">
|
||||||
<i class="el-icon-view view" @click="previewImg(index)"></i>
|
<i class="el-icon-view view" @click="previewImg(index)"></i>
|
||||||
@@ -28,48 +18,26 @@
|
|||||||
|
|
||||||
<img :src="getImgSrc(file, index) + access_token" @error="handleImageError" />
|
<img :src="getImgSrc(file, index) + access_token" @error="handleImageError" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div :style="{ height: imgInfo.height + 'px', width: imgInfo.width + 'px' }"
|
||||||
:style="{ height: imgInfo.height + 'px', width: imgInfo.width + 'px' }"
|
v-show="!autoUpload || (autoUpload && files.length < maxFile)" class="img-selector" :class="getSelector()">
|
||||||
v-show="!autoUpload || (autoUpload && files.length < maxFile)"
|
|
||||||
class="img-selector"
|
|
||||||
:class="getSelector()"
|
|
||||||
>
|
|
||||||
<div class="selector" @click="handleClick">
|
<div class="selector" @click="handleClick">
|
||||||
<i
|
<i :style="{ 'font-size': imgInfo.iconSize + 'px' }" :class="imgInfo.icon"></i>
|
||||||
:style="{ 'font-size': imgInfo.iconSize + 'px' }"
|
|
||||||
:class="imgInfo.icon"
|
|
||||||
></i>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-if="!autoUpload" class="s-btn" :class="{ readonly: changed }" @click="upload">
|
||||||
v-if="!autoUpload"
|
|
||||||
class="s-btn"
|
|
||||||
:class="{ readonly: changed }"
|
|
||||||
@click="upload"
|
|
||||||
>
|
|
||||||
<div>{{ loadText }}</div>
|
<div>{{ loadText }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-button v-else @click="handleClick">{{
|
<el-button v-else @click="handleClick">{{
|
||||||
$ts("选择" + (img ? "图片" : "文件"))
|
$ts('选择' + (img ? '图片' : '文件'))
|
||||||
}}</el-button>
|
}}</el-button>
|
||||||
|
|
||||||
<el-button
|
<el-button v-if="!autoUpload && !img" type="info" :disabled="changed" @click="upload(true)"
|
||||||
v-if="!autoUpload && !img"
|
:loading="loadingStatus">{{ $ts('上传文件') }}</el-button>
|
||||||
type="info"
|
|
||||||
:disabled="changed"
|
|
||||||
@click="upload(true)"
|
|
||||||
:loading="loadingStatus"
|
|
||||||
>{{ $ts("上传文件") }}</el-button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
<div v-if="desc">
|
<div v-if="desc">
|
||||||
<el-alert
|
<el-alert :title="getText() + '文件大小不超过' + (maxSize || 50) + 'M'" type="info" show-icon>
|
||||||
:title="getText() + '文件大小不超过' + (maxSize || 50) + 'M'"
|
|
||||||
type="info"
|
|
||||||
show-icon
|
|
||||||
>
|
|
||||||
</el-alert>
|
</el-alert>
|
||||||
</div>
|
</div>
|
||||||
<slot name="content"></slot>
|
<slot name="content"></slot>
|
||||||
@@ -95,96 +63,97 @@
|
|||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
//import OSS from 'ali-oss'
|
//import OSS from 'ali-oss'
|
||||||
const OSS = {};
|
const OSS = {}
|
||||||
import VolImageViewer from "./VolImageViewer.vue";
|
//import VolImageViewer from './VolImageViewer.vue'
|
||||||
|
import { defineAsyncComponent } from 'vue'
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
"vol-image-viewer": VolImageViewer,
|
'vol-image-viewer': defineAsyncComponent(() => import('@/components/basic/VolImageViewer.vue')),
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
desc: {
|
desc: {
|
||||||
//是否显示默认介绍
|
//是否显示默认介绍
|
||||||
//是否多选
|
//是否多选
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false
|
||||||
},
|
},
|
||||||
fileInfo: {
|
fileInfo: {
|
||||||
//用于接收上传的文件,也可以加以默认值,显示已上传的文件,用户上传后会覆盖默认值
|
//用于接收上传的文件,也可以加以默认值,显示已上传的文件,用户上传后会覆盖默认值
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => {
|
default: () => {
|
||||||
return [];
|
return []
|
||||||
}, //格式[{name:'1.jpg',path:'127.0.01/1.jpg'}]
|
} //格式[{name:'1.jpg',path:'127.0.01/1.jpg'}]
|
||||||
},
|
},
|
||||||
downLoad: {
|
downLoad: {
|
||||||
//是否可以点击文件下载
|
//是否可以点击文件下载
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true
|
||||||
},
|
},
|
||||||
multiple: {
|
multiple: {
|
||||||
//是否多选
|
//是否多选
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false
|
||||||
},
|
},
|
||||||
maxFile: {
|
maxFile: {
|
||||||
//最多可选文件数量,必须multiple=true,才会生效
|
//最多可选文件数量,必须multiple=true,才会生效
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 5,
|
default: 5
|
||||||
},
|
},
|
||||||
maxSize: {
|
maxSize: {
|
||||||
//文件限制大小3M
|
//文件限制大小3M
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 50,
|
default: 50
|
||||||
},
|
},
|
||||||
|
|
||||||
autoUpload: {
|
autoUpload: {
|
||||||
//选择文件后是否自动上传
|
//选择文件后是否自动上传
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true
|
||||||
},
|
},
|
||||||
img: {
|
img: {
|
||||||
//图片类型 img>excel>fileTypes三种文件类型优先级
|
//图片类型 img>excel>fileTypes三种文件类型优先级
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false
|
||||||
},
|
},
|
||||||
excel: {
|
excel: {
|
||||||
//excel文件
|
//excel文件
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false
|
||||||
},
|
},
|
||||||
fileTypes: {
|
fileTypes: {
|
||||||
//指定上传文件的类型
|
//指定上传文件的类型
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => {
|
default: () => {
|
||||||
return [];
|
return []
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
url: {
|
url: {
|
||||||
//上传的url
|
//上传的url
|
||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: ''
|
||||||
},
|
},
|
||||||
uploadBefore: {
|
uploadBefore: {
|
||||||
//返回false会中止执行
|
//返回false会中止执行
|
||||||
//上传前
|
//上传前
|
||||||
type: Function,
|
type: Function,
|
||||||
default: (files) => {
|
default: (files) => {
|
||||||
return true;
|
return true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
uploadAfter: {
|
uploadAfter: {
|
||||||
//返回false会中止执行
|
//返回false会中止执行
|
||||||
//上传后
|
//上传后
|
||||||
type: Function,
|
type: Function,
|
||||||
default: (result, files) => {
|
default: (result, files) => {
|
||||||
return true;
|
return true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
onChange: {
|
onChange: {
|
||||||
//选择文件时 //返回false会中止执行
|
//选择文件时 //返回false会中止执行
|
||||||
type: Function,
|
type: Function,
|
||||||
default: (files) => {
|
default: (files) => {
|
||||||
return true;
|
return true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
// clear: {
|
// clear: {
|
||||||
// //上传完成后是否清空文件列表
|
// //上传完成后是否清空文件列表
|
||||||
@@ -194,36 +163,36 @@ export default {
|
|||||||
fileList: {
|
fileList: {
|
||||||
//是否显示选择的文件列表
|
//是否显示选择的文件列表
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true
|
||||||
},
|
},
|
||||||
fileClick: {
|
fileClick: {
|
||||||
//点击文件事件
|
//点击文件事件
|
||||||
type: Function,
|
type: Function,
|
||||||
default: (index, file, files) => {
|
default: (index, file, files) => {
|
||||||
return true;
|
return true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
removeBefore: {
|
removeBefore: {
|
||||||
//移除文件事件
|
//移除文件事件
|
||||||
type: Function,
|
type: Function,
|
||||||
default: (index, file, files) => {
|
default: (index, file, files) => {
|
||||||
return true;
|
return true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
append: {
|
append: {
|
||||||
//此属性已废弃,多文件上传,默认追加文件
|
//此属性已废弃,多文件上传,默认追加文件
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false
|
||||||
},
|
},
|
||||||
compress: {
|
compress: {
|
||||||
//开启图片压缩,后面根据需要再完善
|
//开启图片压缩
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: true
|
||||||
},
|
},
|
||||||
compressMinSize: {
|
compressMinSize: {
|
||||||
//压缩的最小比例
|
//压缩的最小比例
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0.1,
|
default: 0.7
|
||||||
},
|
},
|
||||||
imgOption: {
|
imgOption: {
|
||||||
//图片上传信息
|
//图片上传信息
|
||||||
@@ -234,327 +203,250 @@ export default {
|
|||||||
//iconSize:40,//上传图标大小
|
//iconSize:40,//上传图标大小
|
||||||
// height: 65, //图片高度
|
// height: 65, //图片高度
|
||||||
// width: 65,//图片宽度
|
// width: 65,//图片宽度
|
||||||
};
|
}
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
defaultImg: new URL("@/assets/imgs/error-img.png", import.meta.url).href,
|
defaultImg: new URL('@/assets/imgs/error-img.png', import.meta.url).href,
|
||||||
// errorImg: 'this.src="' + require('@/assets/imgs/error-img.png') + '"',
|
// errorImg: 'this.src="' + require('@/assets/imgs/error-img.png') + '"',
|
||||||
changed: false, //手动上传成功后禁止重复上传,必须重新选择
|
changed: false, //手动上传成功后禁止重复上传,必须重新选择
|
||||||
model: true,
|
model: true,
|
||||||
files: [],
|
files: [],
|
||||||
bigImg: "",
|
bigImg: '',
|
||||||
imgTypes: ["gif", "jpg", "jpeg", "png", "bmp", "webp", "jfif"],
|
imgTypes: ['gif', 'jpg', 'jpeg', 'png', 'bmp', 'webp', 'jfif'],
|
||||||
loadingStatus: false,
|
loadingStatus: false,
|
||||||
loadText: "上传文件",
|
loadText: '上传文件',
|
||||||
access_token: "",
|
access_token: '',
|
||||||
imgInfo: {
|
imgInfo: {
|
||||||
icon: "el-icon-camera-solid",
|
icon: 'el-icon-camera-solid',
|
||||||
iconSize: 35,
|
iconSize: 35,
|
||||||
height: 65, //图片高度
|
height: 65, //图片高度
|
||||||
width: 65, //图片宽度
|
width: 65 //图片宽度
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
Object.assign(this.imgInfo, this.imgOption);
|
Object.assign(this.imgInfo, this.imgOption)
|
||||||
const tk = (this.$store.getters.getUserInfo() || { accessToken: "" }).accessToken;
|
const tk = (this.$store.getters.getUserInfo() || { accessToken: '' }).accessToken
|
||||||
if (tk) {
|
if (tk) {
|
||||||
this.access_token = "?access_token=" + tk;
|
this.access_token = '?access_token=' + tk
|
||||||
}
|
}
|
||||||
//默认有图片的禁止上传操作
|
//默认有图片的禁止上传操作
|
||||||
if (this.fileInfo) {
|
if (this.fileInfo) {
|
||||||
this.changed = true;
|
this.changed = true
|
||||||
}
|
}
|
||||||
this.cloneFile(this.fileInfo);
|
this.cloneFile(this.fileInfo)
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
fileInfo: {
|
fileInfo: {
|
||||||
handler(files) {
|
handler(files) {
|
||||||
this.cloneFile(files);
|
this.cloneFile(files)
|
||||||
},
|
},
|
||||||
deep: true,
|
deep: true
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
cloneFile(files) {
|
cloneFile(files) {
|
||||||
this.files = files.map((x) => {
|
this.files = files.map((x) => {
|
||||||
return {
|
return {
|
||||||
name: x.name || this.getFileName(x.path),
|
name: x.name || this.getFileName(x.path),
|
||||||
path: x.path,
|
path: x.path
|
||||||
};
|
}
|
||||||
});
|
})
|
||||||
},
|
},
|
||||||
getFileName(path) {
|
getFileName(path) {
|
||||||
if (!path) {
|
if (!path) {
|
||||||
return "未定义文件名";
|
return '未定义文件名'
|
||||||
}
|
}
|
||||||
let _index = path.lastIndexOf("/");
|
let _index = path.lastIndexOf('/')
|
||||||
return path.substring(_index + 1);
|
return path.substring(_index + 1)
|
||||||
},
|
},
|
||||||
previewImg(index) {
|
previewImg(index) {
|
||||||
const imgs = this.files.map((x) => {
|
const imgs = this.files.map((x) => {
|
||||||
return this.getImgSrc(x) + this.access_token;
|
return this.getImgSrc(x) + this.access_token
|
||||||
});
|
})
|
||||||
this.$refs.viewer.show(imgs, index);
|
this.$refs.viewer.show(imgs, index)
|
||||||
// this.base.previewImg(this.getImgSrc(this.files[index]));
|
// this.base.previewImg(this.getImgSrc(this.files[index]));
|
||||||
// window.open(this.getImgSrc((this.files.length>0?this.files:this.fileInfo)[index]));
|
// window.open(this.getImgSrc((this.files.length>0?this.files:this.fileInfo)[index]));
|
||||||
},
|
},
|
||||||
getSelector() {
|
getSelector() {
|
||||||
if (this.autoUpload) {
|
if (this.autoUpload) {
|
||||||
return "auto-selector";
|
return 'auto-selector'
|
||||||
}
|
}
|
||||||
return "submit-selector";
|
return 'submit-selector'
|
||||||
},
|
},
|
||||||
getImgSrc(file, index) {
|
getImgSrc(file, index) {
|
||||||
if (file.hasOwnProperty("path")) {
|
if (file.hasOwnProperty('path')) {
|
||||||
if (this.base.isUrl(file.path)) {
|
if (this.base.isUrl(file.path)) {
|
||||||
return file.path;
|
return file.path
|
||||||
}
|
}
|
||||||
//2020.12.27增加base64图片操作
|
//2020.12.27增加base64图片操作
|
||||||
if (file.path.indexOf("/9j/") != -1) {
|
if (file.path.indexOf('/9j/') != -1) {
|
||||||
return "data:image/jpeg;base64," + file.path;
|
return 'data:image/jpeg;base64,' + file.path
|
||||||
}
|
}
|
||||||
if (file.path.substr(0, 1) == "/") {
|
if (file.path.substr(0, 1) == '/') {
|
||||||
file.path = file.path.substr(1);
|
file.path = file.path.substr(1)
|
||||||
}
|
}
|
||||||
return this.http.ipAddress + file.path;
|
return (this.$global.oss?.url || this.http.ipAddress) + file.path
|
||||||
}
|
}
|
||||||
return window.URL.createObjectURL(file);
|
return window.URL.createObjectURL(file)
|
||||||
},
|
},
|
||||||
fileOnClick(index, file) {
|
fileOnClick(index, file) {
|
||||||
if (!this.fileClick(index, file, this.files)) {
|
if (!this.fileClick(index, file, this.files)) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
//点击不下载
|
//点击不下载
|
||||||
if (!this.downLoad) {
|
if (!this.downLoad) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
if (!file.path) {
|
if (!file.path) {
|
||||||
this.$message.error("请先上传文件");
|
this.$message.error('请先上传文件')
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
this.base.dowloadFile(
|
this.base.dowloadFile(
|
||||||
file.path + this.access_token,
|
file.path + this.access_token,
|
||||||
file.name,
|
file.name,
|
||||||
{
|
{
|
||||||
Authorization: this.$store.getters.getToken(),
|
Authorization: this.$store.getters.getToken()
|
||||||
},
|
},
|
||||||
this.http.ipAddress
|
this.http.ipAddress
|
||||||
);
|
)
|
||||||
},
|
},
|
||||||
getText() {
|
getText() {
|
||||||
if (this.img) {
|
if (this.img) {
|
||||||
return "只能上传图片,";
|
return '只能上传图片,'
|
||||||
} else if (this.excel) {
|
} else if (this.excel) {
|
||||||
return "只能上传excel文件,";
|
return '只能上传excel文件,'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleClick() {
|
handleClick() {
|
||||||
this.$refs.input.click();
|
this.$refs.input.click()
|
||||||
},
|
},
|
||||||
handleChange(e) {
|
handleChange(e) {
|
||||||
//this.compress开启图片压缩,后面根据需要再完善
|
//this.compress开启图片压缩,后面根据需要再完善
|
||||||
// this.clearFiles();
|
// this.clearFiles();
|
||||||
var result = this.checkFile(e.target.files);
|
var result = this.checkFile(e.target.files)
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.changed = false;
|
this.changed = false
|
||||||
//如果传入了FileInfo需要自行处理移除FileInfo
|
//如果传入了FileInfo需要自行处理移除FileInfo
|
||||||
if (!this.onChange(e.target.files)) {
|
if (!this.onChange(e.target.files)) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
for (let index = 0; index < e.target.files.length; index++) {
|
for (let index = 0; index < e.target.files.length; index++) {
|
||||||
const element = e.target.files[index];
|
const element = e.target.files[index]
|
||||||
element.input = true;
|
element.input = true
|
||||||
}
|
}
|
||||||
if (!this.multiple) {
|
if (!this.multiple) {
|
||||||
this.files.splice(0);
|
this.files.splice(0)
|
||||||
}
|
}
|
||||||
this.files.push(...e.target.files);
|
this.files.push(...e.target.files)
|
||||||
|
|
||||||
this.$refs.input.value = null;
|
this.$refs.input.value = null
|
||||||
if (this.autoUpload && result) {
|
if (this.autoUpload && result) {
|
||||||
this.upload(false);
|
this.upload(false)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeFile(index) {
|
removeFile(index) {
|
||||||
//如果传入了FileInfo需要自行处理移除FileInfo
|
//如果传入了FileInfo需要自行处理移除FileInfo
|
||||||
//t移除文件
|
//t移除文件
|
||||||
let removeFile = this.files[index];
|
let removeFile = this.files[index]
|
||||||
|
if (!this.removeBefore(index, removeFile, this.fileInfo)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
//删除的还没上传的文件
|
//删除的还没上传的文件
|
||||||
if (removeFile.input) {
|
if (removeFile.input) {
|
||||||
this.files.splice(index, 1);
|
this.files.splice(index, 1)
|
||||||
} else {
|
} else {
|
||||||
this.fileInfo.splice(index, 1);
|
this.fileInfo.splice(index, 1)
|
||||||
}
|
|
||||||
if (!this.removeBefore(index, removeFile, this.fileInfo)) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
clearFiles() {
|
clearFiles() {
|
||||||
this.files.splice(0);
|
this.files.splice(0)
|
||||||
},
|
},
|
||||||
getFiles() {
|
getFiles() {
|
||||||
return this.files;
|
return this.files
|
||||||
},
|
},
|
||||||
convertToFile(dataurl, filename) {
|
async compressImg() {
|
||||||
let arr = dataurl.split(",");
|
if (!this.compress||!this.img) return;
|
||||||
let mime = arr[0].match(/:(.*?);/)[1];
|
for (let index = 0; index < this.files.length; index++) {
|
||||||
let suffix = mime.split("/")[1];
|
let originalFile = this.files[index]
|
||||||
let bstr = atob(arr[1]);
|
if (originalFile.size > 300 * 1024) {
|
||||||
let n = bstr.length;
|
try {
|
||||||
let u8arr = new Uint8Array(n);
|
const newFile = await this.base.compressImage(originalFile, { initialQuality: this.compressMinSize });
|
||||||
while (n--) {
|
newFile.input = originalFile.input
|
||||||
u8arr[n] = bstr.charCodeAt(n);
|
this.files.splice(index, 1, newFile);
|
||||||
|
// console.log(newFile.size)
|
||||||
|
} catch (error) {
|
||||||
|
console.log('图片压缩异常', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// new File返回File对象 第一个参数是 ArraryBuffer 或 Bolb 或Arrary 第二个参数是文件名
|
|
||||||
// 第三个参数是 要放到文件中的内容的 MIME 类型
|
|
||||||
return new File([u8arr], `${filename}.${suffix}`, {
|
|
||||||
type: mime,
|
|
||||||
input: true,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
async compressImg(file) {
|
|
||||||
let fileSize = file.size / 1024 / 1024;
|
|
||||||
let read = new FileReader();
|
|
||||||
read.readAsDataURL(file);
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
read.onload = (e) => {
|
|
||||||
let img = new Image();
|
|
||||||
img.src = e.target.result;
|
|
||||||
let _this = this;
|
|
||||||
img.onload = function () {
|
|
||||||
//默认按比例压缩
|
|
||||||
let w = this.width;
|
|
||||||
let h = this.height;
|
|
||||||
let canvas = document.createElement("canvas");
|
|
||||||
let ctx = canvas.getContext("2d");
|
|
||||||
canvas.setAttribute("width", w);
|
|
||||||
canvas.setAttribute("height", h);
|
|
||||||
ctx.drawImage(this, 0, 0, w, h);
|
|
||||||
let rate = 0.3;
|
|
||||||
if (fileSize > 2) {
|
|
||||||
rate = 0.1;
|
|
||||||
} else if (fileSize > 1) {
|
|
||||||
rate = 0.1;
|
|
||||||
}
|
|
||||||
if (_this.compressMinSize > rate) {
|
|
||||||
rate = _this.compressMinSize;
|
|
||||||
}
|
|
||||||
// rate=1;
|
|
||||||
let base64 = canvas.toDataURL("image/jpeg", rate);
|
|
||||||
resolve(_this.convertToFile(base64, file.name));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
async uploadOSS() {
|
async uploadOSS() {
|
||||||
this.http.get("api/alioss/getAccessToken", {}, false).then(async (x) => {
|
|
||||||
if (!x.status) return this.$Message.error(x.message);
|
|
||||||
let client = new OSS({
|
|
||||||
// yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
|
|
||||||
region: x.data.region,
|
|
||||||
// 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
|
|
||||||
accessKeyId: x.data.accessKeyId,
|
|
||||||
accessKeySecret: x.data.accessKeySecret,
|
|
||||||
// 从STS服务获取的安全令牌(SecurityToken)。
|
|
||||||
stsToken: x.data.securityToken,
|
|
||||||
// 填写Bucket名称。
|
|
||||||
bucket: x.data.bucket,
|
|
||||||
});
|
|
||||||
console.log(this.files);
|
|
||||||
for (let index = 0; index < this.files.length; index++) {
|
|
||||||
const file = this.files[index];
|
|
||||||
if (file.input) {
|
|
||||||
let result = await client.put(
|
|
||||||
x.data.bucketFolder + "/" + x.data.unique + file.name,
|
|
||||||
file
|
|
||||||
);
|
|
||||||
file.path = result.url;
|
|
||||||
file.newName = x.data.unique + file.name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.fileInfo.splice(0);
|
|
||||||
// }
|
|
||||||
let _files = this.files.map((file) => {
|
|
||||||
return {
|
|
||||||
name: file.newName || file.name,
|
|
||||||
path: file.path,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
this.fileInfo.push(..._files);
|
|
||||||
//2021.09.25修复文件上传后不能同时下载的问题
|
|
||||||
this.files = _files;
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
},
|
},
|
||||||
async upload(vail) {
|
async upload(vail) {
|
||||||
if (vail && !this.checkFile()) return false;
|
if (vail && !this.checkFile()) return false
|
||||||
if (!this.url) {
|
if (!this.url) {
|
||||||
return this.$message.error("没有配置好Url");
|
return this.$message.error('没有配置好Url')
|
||||||
}
|
}
|
||||||
if (!this.files || this.files.length == 0) {
|
if (!this.files || this.files.length == 0) {
|
||||||
return this.$message.error("请选择文件");
|
return this.$message.error('请选择文件')
|
||||||
}
|
}
|
||||||
|
//开启压缩
|
||||||
|
await this.compressImg();
|
||||||
|
|
||||||
|
//过滤文件符号
|
||||||
|
await this.base.resetFileName(this.files, (file) => {
|
||||||
|
if (file.name?.includes(' ') || file.name?.includes(',') || file.name?.includes('+')) {
|
||||||
|
return file.name.replaceAll(' ', '').replaceAll('+', '').replaceAll(',', '')
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
|
||||||
//增加上传时自定义参数,后台使用获取Utilities.HttpContext.Current.Request.Query["字段"]
|
//增加上传时自定义参数,后台使用获取Utilities.HttpContext.Current.Request.Query["字段"]
|
||||||
let params = {};
|
let params = {}
|
||||||
if (!this.uploadBefore(this.files, params)) {
|
if (! await this.uploadBefore(this.files, params)) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
let paramText = "";
|
let paramText = ''
|
||||||
if (Object.keys(params).length) {
|
if (Object.keys(params).length) {
|
||||||
paramText = "?1=1";
|
paramText = '?1=1'
|
||||||
for (const key in params) {
|
for (const key in params) {
|
||||||
let value = params[key];
|
let value = params[key]
|
||||||
if (typeof value == "object") {
|
if (typeof value == 'object') {
|
||||||
value = JSON.stringify(value);
|
value = JSON.stringify(value)
|
||||||
}
|
}
|
||||||
paramText += `&${key}=${value}`;
|
paramText += `&${key}=${value}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadingStatus = true;
|
this.loadingStatus = true
|
||||||
this.loadText = "上传中..";
|
this.loadText = '上传中..'
|
||||||
if (window.oss && window.oss.ali.use) {
|
if (window.oss && window.oss.ali.use) {
|
||||||
await this.uploadOSS();
|
await this.uploadOSS()
|
||||||
this.loadingStatus = false;
|
this.loadingStatus = false
|
||||||
this.loadText = "上传文件";
|
this.loadText = '上传文件'
|
||||||
if (!this.uploadAfter({ status: true }, this.files)) {
|
if (!this.uploadAfter({ status: true }, this.files)) {
|
||||||
this.changed = false;
|
this.changed = false
|
||||||
return;
|
return
|
||||||
} else {
|
} else {
|
||||||
this.changed = true;
|
this.changed = true
|
||||||
}
|
}
|
||||||
this.$message.success("上传成功");
|
this.$message.success('上传成功')
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var forms = new FormData();
|
var forms = new FormData()
|
||||||
for (let index = 0; index < this.files.length; index++) {
|
for (let index = 0; index < this.files.length; index++) {
|
||||||
let file = this.files[index];
|
let file = this.files[index]
|
||||||
if (file.input) {
|
if (file.input) {
|
||||||
//2023.07.10暂时屏蔽图片压缩
|
forms.append('fileInput', file, file.name)
|
||||||
//let name = file.name.split('.');
|
|
||||||
//name = name[name.length - 1].toLocaleLowerCase();
|
|
||||||
//let isImg = this.imgTypes.indexOf(name) != -1;
|
|
||||||
// if (isImg && (name == 'jpg' || name == 'jpeg')) {
|
|
||||||
// //>200KB的开启压缩
|
|
||||||
// if (isImg && file.size / 1024 / 1024 > 0.2) {
|
|
||||||
// console.log('压缩前' + file.size);
|
|
||||||
// file = await this.compressImg(file);
|
|
||||||
// file.compress = true;
|
|
||||||
// this.files[index] = file;
|
|
||||||
// this.files[index].input = true;
|
|
||||||
// console.log('压缩后' + file.size);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
forms.append("fileInput", file, file.name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// forms.append("fileInput", this.files);
|
// forms.append("fileInput", this.files);
|
||||||
@@ -563,174 +455,143 @@ export default {
|
|||||||
.post(
|
.post(
|
||||||
this.url + paramText,
|
this.url + paramText,
|
||||||
forms,
|
forms,
|
||||||
this.autoUpload ? "正在上传文件" : "",
|
this.autoUpload ? '正在上传文件' : '',
|
||||||
//高版本axios这里必须要指定header
|
//高版本axios这里必须要指定header
|
||||||
{
|
{
|
||||||
headers: { "Content-Type": "multipart/form-data" },
|
headers: { 'Content-Type': 'multipart/form-data' }
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.then(
|
.then(
|
||||||
(x) => {
|
(x) => {
|
||||||
// this.$refs.uploadFile.clearFiles();
|
// this.$refs.uploadFile.clearFiles();
|
||||||
this.loadingStatus = false;
|
this.loadingStatus = false
|
||||||
this.loadText = "上传文件";
|
this.loadText = '上传文件'
|
||||||
if (!this.uploadAfter(x, this.files)) {
|
if (!this.uploadAfter(x, this.files)) {
|
||||||
this.changed = false;
|
this.changed = false
|
||||||
return;
|
return
|
||||||
} else {
|
} else {
|
||||||
this.changed = true;
|
this.changed = true
|
||||||
}
|
}
|
||||||
|
|
||||||
this.changed = x.status;
|
this.changed = x.status
|
||||||
if (!x.status) {
|
if (!x.status) {
|
||||||
this.$message.error(x.message);
|
this.$message.error(x.message)
|
||||||
// this.files = null;
|
// this.files = null;
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
this.$message.success(x.message);
|
this.$message.success(x.message)
|
||||||
//单选清除以前的数据
|
//单选清除以前的数据
|
||||||
// if (!this.multiple) {
|
// if (!this.multiple) {
|
||||||
this.fileInfo.splice(0);
|
this.fileInfo.splice(0)
|
||||||
// }
|
// }
|
||||||
let _files = this.files.map((file) => {
|
let _files = this.files.map((file) => {
|
||||||
return {
|
return {
|
||||||
name: file.name,
|
name: file.name,
|
||||||
path: file.path || x.data + file.name,
|
path: file.path || x.data + file.name
|
||||||
};
|
}
|
||||||
});
|
})
|
||||||
this.fileInfo.push(..._files);
|
this.fileInfo.push(..._files)
|
||||||
//2021.09.25修复文件上传后不能同时下载的问题
|
//2021.09.25修复文件上传后不能同时下载的问题
|
||||||
this.files = _files;
|
this.files = _files
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
this.loadText = "上传文件";
|
this.loadText = '上传文件'
|
||||||
this.loadingStatus = false;
|
this.loadingStatus = false
|
||||||
}
|
}
|
||||||
);
|
)
|
||||||
},
|
},
|
||||||
format(file, checkFileType) {
|
format(file, checkFileType) {
|
||||||
const format = file.name.split(".").pop().toLocaleLowerCase() || "";
|
const format = file.name.split('.').pop().toLocaleLowerCase() || ''
|
||||||
let fileIcon = "el-icon-document";
|
let fileIcon = 'el-icon-document'
|
||||||
if (this.fileTypes.length > 0 && checkFileType != undefined) {
|
if (this.fileTypes.length > 0 && checkFileType != undefined) {
|
||||||
if (this.fileTypes.indexOf(format) != -1) {
|
if (this.fileTypes.indexOf(format) != -1) {
|
||||||
return true;
|
return true
|
||||||
}
|
}
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
checkFileType &&
|
checkFileType &&
|
||||||
!(checkFileType instanceof Array) &&
|
!(checkFileType instanceof Array) &&
|
||||||
checkFileType != "img" &&
|
checkFileType != 'img' &&
|
||||||
checkFileType != "excel"
|
checkFileType != 'excel'
|
||||||
) {
|
) {
|
||||||
if (checkFileType.indexOf(format) > -1) {
|
if (checkFileType.indexOf(format) > -1) {
|
||||||
return true;
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (checkFileType == 'img' || this.imgTypes.indexOf(format) > -1) {
|
||||||
if (checkFileType == "img" || this.imgTypes.indexOf(format) > -1) {
|
if (checkFileType == 'img') {
|
||||||
if (checkFileType == "img") {
|
|
||||||
if (this.imgTypes.indexOf(format) > -1) {
|
if (this.imgTypes.indexOf(format) > -1) {
|
||||||
return true;
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fileIcon = "el-icon-picture-outline";
|
fileIcon = 'el-icon-picture-outline'
|
||||||
}
|
}
|
||||||
if (
|
if (checkFileType == 'excel' || ['numbers', 'csv', 'xls', 'xlsx'].indexOf(format) > -1) {
|
||||||
["mp4", "m3u8", "rmvb", "avi", "swf", "3gp", "mkv", "flv"].indexOf(format) > -1
|
if (checkFileType == 'excel') {
|
||||||
) {
|
if (['numbers', 'csv', 'xls', 'xlsx'].indexOf(format) > -1) {
|
||||||
fileIcon = "el-icon-document";
|
return true
|
||||||
}
|
|
||||||
if (["mp3", "wav", "wma", "ogg", "aac", "flac"].indexOf(format) > -1) {
|
|
||||||
fileIcon = "el-icon-document";
|
|
||||||
}
|
|
||||||
if (["doc", "txt", "docx", "pages", "epub", "pdf"].indexOf(format) > -1) {
|
|
||||||
fileIcon = "el-icon-document";
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
checkFileType == "excel" ||
|
|
||||||
["numbers", "csv", "xls", "xlsx"].indexOf(format) > -1
|
|
||||||
) {
|
|
||||||
if (checkFileType == "excel") {
|
|
||||||
if (["numbers", "csv", "xls", "xlsx"].indexOf(format) > -1) {
|
|
||||||
return true;
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fileIcon = "el-icon-document";
|
|
||||||
}
|
}
|
||||||
return fileIcon;
|
return fileIcon
|
||||||
},
|
},
|
||||||
beforeUpload() {},
|
beforeUpload() { },
|
||||||
checkFile(inputFiles) {
|
checkFile(inputFiles) {
|
||||||
const files = this.files;
|
const files = this.files
|
||||||
|
|
||||||
if (
|
if (this.multiple && files.length + (inputFiles || []).length > (this.maxFile || 5)) {
|
||||||
this.multiple &&
|
|
||||||
files.length + (inputFiles || []).length > (this.maxFile || 5)
|
|
||||||
) {
|
|
||||||
this.$message.error(
|
this.$message.error(
|
||||||
"最多只能选【" +
|
'最多只能选【' + (this.maxFile || 5) + '】' + (this.img ? '张图片' : '个文件') + ''
|
||||||
(this.maxFile || 5) +
|
)
|
||||||
"】" +
|
return false
|
||||||
(this.img ? "张图片" : "个文件") +
|
|
||||||
""
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
if (!inputFiles) {
|
if (!inputFiles) {
|
||||||
inputFiles = this.files.filter((x) => {
|
inputFiles = this.files.filter((x) => {
|
||||||
return x.input;
|
return x.input
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
let names = [];
|
let names = []
|
||||||
for (let index = 0; index < inputFiles.length; index++) {
|
for (let index = 0; index < inputFiles.length; index++) {
|
||||||
const file = inputFiles[index];
|
const file = inputFiles[index]
|
||||||
if (names.indexOf(file.name) != -1) {
|
if (names.indexOf(file.name) != -1) {
|
||||||
file.name = "(" + index + ")" + file.name;
|
file.name = '(' + index + ')' + file.name
|
||||||
}
|
}
|
||||||
names.push(file.name);
|
names.push(file.name)
|
||||||
if (this.img && !this.format(file, "img")) {
|
if (this.img && !this.format(file, 'img')) {
|
||||||
this.$message.error("选择的文件【" + file.name + "】只能是图片格式");
|
this.$message.error('选择的文件【' + file.name + '】只能是图片格式')
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
if (this.excel && !this.format(file, "excel")) {
|
if (this.excel && !this.format(file, 'excel')) {
|
||||||
this.$message.error("选择的文件【" + file.name + "】只能是excel文件");
|
this.$message.error('选择的文件【' + file.name + '】只能是excel文件')
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
if (
|
if (this.fileTypes && this.fileTypes.length > 0 && !this.format(file, this.fileTypes)) {
|
||||||
this.fileTypes &&
|
|
||||||
this.fileTypes.length > 0 &&
|
|
||||||
!this.format(file, this.fileTypes)
|
|
||||||
) {
|
|
||||||
this.$message.error(
|
this.$message.error(
|
||||||
"选择的文件【" +
|
'选择的文件【' + file.name + '】只能是【' + this.fileTypes.join(',') + '】格式'
|
||||||
file.name +
|
)
|
||||||
"】只能是【" +
|
return false
|
||||||
this.fileTypes.join(",") +
|
|
||||||
"】格式"
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
if (file.size > (this.maxSize || 50) * 1024 * 1024) {
|
if (file.size > (this.maxSize || 50) * 1024 * 1024) {
|
||||||
this.$message.error(
|
this.$message.error(
|
||||||
"选择的文件【" + file.name + "】不能超过:" + (this.maxSize || 50) + "M"
|
'选择的文件【' + file.name + '】不能超过:' + (this.maxSize || 50) + 'M'
|
||||||
);
|
)
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true
|
||||||
},
|
},
|
||||||
handleImageError($e) {
|
handleImageError($e) {
|
||||||
$e.target.src = this.defaultImg;
|
$e.target.src = this.defaultImg
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.upload-list {
|
.upload-list {
|
||||||
@@ -780,12 +641,12 @@ export default {
|
|||||||
margin-top: 43px;
|
margin-top: 43px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-group > * {
|
.button-group>* {
|
||||||
float: left;
|
float: left;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-info > span {
|
.file-info>span {
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -910,8 +771,7 @@ export default {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
.m-img {
|
.m-img {}
|
||||||
}
|
|
||||||
|
|
||||||
.mask {
|
.mask {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
293
vol.web/src/uitils/translator/en.js
Normal file
293
vol.web/src/uitils/translator/en.js
Normal file
@@ -0,0 +1,293 @@
|
|||||||
|
export default {
|
||||||
|
"审批流程":"workflow",
|
||||||
|
"基础设置":"settings",
|
||||||
|
"基础组件":"components",
|
||||||
|
"框架文档":"doc",
|
||||||
|
"仓库管理":"Warehouse",
|
||||||
|
"设备管理":"Equipment",
|
||||||
|
"最多只能选[5]张图片": "You can only select [5] pictures at most",
|
||||||
|
"最多只能选[5]个文件": "Only [5] files can be selected at most",
|
||||||
|
"只能选择excel文件": "Only Excel files can be selected",
|
||||||
|
"文件大小不能超过": "The file size cannot exceed",
|
||||||
|
"最多可输入[{$ts}]个字符": "a maximum of [{$ts}] characters can be entered",
|
||||||
|
"第[{$ts}]行,[{$ts}]验证未通过": "Line [{$ts},{$ts}] failed verificatio",
|
||||||
|
"删除成功,共[{$ts}]条数据": "Deletion succeeded, with a total of [{$ts}] data",
|
||||||
|
"[{$ts}]不能为空": "[{$ts}] is required",
|
||||||
|
"[{$ts},{$ts}]不能为空": "[{$ts},{$ts}] is required",
|
||||||
|
"无数据": "No data",
|
||||||
|
"[{$ts}]重复": "[{$ts}] repeated",
|
||||||
|
"搜索": "Search",
|
||||||
|
"详情": "Details",
|
||||||
|
"重复": "repeated",
|
||||||
|
"重复记录": "Repeated recording",
|
||||||
|
"重置": "Reset",
|
||||||
|
"重置筛选条件": "Reset filter",
|
||||||
|
"角色管理": "Role info",
|
||||||
|
"角色名称": "Role",
|
||||||
|
"角色": "Role",
|
||||||
|
"设置": "Setting",
|
||||||
|
"保存筛选条件": "Save filter",
|
||||||
|
"保存成功,共{$ts}条数据": "Saved successfully, {$ts} item in total",
|
||||||
|
"选择": "Select",
|
||||||
|
"选择文件": "Select file",
|
||||||
|
"请选择行": "Please select rows",
|
||||||
|
"修改人": "Modifier",
|
||||||
|
"修改密码": "Password",
|
||||||
|
"修改时间": "Modify time",
|
||||||
|
"模块": "Module",
|
||||||
|
"月": "Months",
|
||||||
|
"更多": "More",
|
||||||
|
"名字": "Name",
|
||||||
|
"邮箱": "Mail",
|
||||||
|
"女": "Male",
|
||||||
|
"男": "Ma",
|
||||||
|
"菜单": "Menu",
|
||||||
|
"菜单名称": "Menu name",
|
||||||
|
"菜单设置": "Menu",
|
||||||
|
"提示": "Message",
|
||||||
|
"否": "No",
|
||||||
|
"父级ID": "Parent ID",
|
||||||
|
"上级角色": "Parent role",
|
||||||
|
"密码": "Password",
|
||||||
|
"权限": "Permissio",
|
||||||
|
"个人中心": "Personal Center",
|
||||||
|
"请输入": "Please input",
|
||||||
|
"请选择": "Please select",
|
||||||
|
"请选择文件": "Please select file",
|
||||||
|
"其他": "Other",
|
||||||
|
"必须是数字": "not a number",
|
||||||
|
"备注": "Notes",
|
||||||
|
"确认": "OK",
|
||||||
|
"是": "Yes",
|
||||||
|
"不存在": "does not exist",
|
||||||
|
"系统": "System",
|
||||||
|
"表名": "Table Name",
|
||||||
|
"电话": "Tel",
|
||||||
|
"时间": "Time",
|
||||||
|
"排序号": "Sort NO",
|
||||||
|
"状态": "Status",
|
||||||
|
"操作成功": "Success",
|
||||||
|
"删除成功": "Successfully Delete",
|
||||||
|
"保存成功": "Successfully save",
|
||||||
|
"摘要": "Summary",
|
||||||
|
"超级管理员": "Super Admi",
|
||||||
|
"确定": "Confirm",
|
||||||
|
"用户管理": "User info",
|
||||||
|
"用户名": "Account",
|
||||||
|
"用户权限": "User permission",
|
||||||
|
"用户基础信息": "User info",
|
||||||
|
"用户名或密码错误": "Account or password incorrect",
|
||||||
|
"值": "Value",
|
||||||
|
"查看": "View",
|
||||||
|
"警告": "Warning",
|
||||||
|
"最多{$ts}个字符": "Up to {$ts} characters",
|
||||||
|
"上传文件": "Upload",
|
||||||
|
"上传": "Upload",
|
||||||
|
"文件上传成功": "Upload succeeded",
|
||||||
|
"代码生成": "Coder",
|
||||||
|
"公司名称": "Company",
|
||||||
|
"公司地址": "Company address",
|
||||||
|
"公司管理": "Company info",
|
||||||
|
"所属公司": "Company name",
|
||||||
|
"公司类别": "Company type",
|
||||||
|
"保存后继续添加": "Continue adding after saving",
|
||||||
|
"成本": "Cost",
|
||||||
|
"国家": "Country",
|
||||||
|
"国家代码": "CountryCode",
|
||||||
|
"创建时间": "Create time",
|
||||||
|
"创建人": "Creator",
|
||||||
|
"验证码": "code",
|
||||||
|
"关闭": "Close",
|
||||||
|
"只能是日期格式": "Can only be in date format",
|
||||||
|
"取消": "Cancel",
|
||||||
|
"不能大于": "cannot be greater tha",
|
||||||
|
"不能小于": "cannot be less tha",
|
||||||
|
"选中checkbox隐藏/显示列数据": "Select check box to hide / show column data",
|
||||||
|
"中国": "China",
|
||||||
|
"中文": "Chinese",
|
||||||
|
"描述": "Descriptio",
|
||||||
|
"数据字典": "Dictionary",
|
||||||
|
"字典名称": "Dictionary Name",
|
||||||
|
"字典编号": "Dictionary Number",
|
||||||
|
"完成": "Done",
|
||||||
|
"字典数据": "Data Source",
|
||||||
|
"数据源": "Data Source",
|
||||||
|
"下拉框绑定设置": "Data source",
|
||||||
|
"日期": "Date",
|
||||||
|
"删除": "Delete",
|
||||||
|
"天": "Days",
|
||||||
|
"帐号": "Account",
|
||||||
|
"操作类型": "Action type",
|
||||||
|
"新建": "Add",
|
||||||
|
"添加子级": "Add a subset",
|
||||||
|
"添加备注": "Add note",
|
||||||
|
"添加行": "Add Row",
|
||||||
|
"添加同级": "Add Siblings",
|
||||||
|
"地址": "Address",
|
||||||
|
"全选": "All",
|
||||||
|
"不能为空": "is required",
|
||||||
|
"参数设置": "Parameters",
|
||||||
|
"真实姓名": "Real Name",
|
||||||
|
"【{$ts}】不是模板中的列": "【{$ts}】 is not a column in the template",
|
||||||
|
"第[{$ts}]行,[{$ts}]验证未通过,必须是日期格式": "Line [{$ts},{$ts}] validation failed, must be in date format",
|
||||||
|
"第[{$ts}]行,[{$ts}]验证未通过,不能为空": "Line [{$ts},{$ts}] failed verification, cannot be empty",
|
||||||
|
"[{$ts}]数据字典缺失": "[{$ts}] no data source is configured",
|
||||||
|
"第[{$ts}]行,[{$ts}]验证未通过,只能输入": "Line [{$ts},{$ts}] failed verification, only input",
|
||||||
|
"账号登录": "Login account",
|
||||||
|
"正在登陆": "Logging",
|
||||||
|
"登录": "Login",
|
||||||
|
"登陆成功": "Login Succeeded",
|
||||||
|
"语言设置": "Language",
|
||||||
|
"系统设置": "System",
|
||||||
|
"日志管理": "Logger",
|
||||||
|
"英文": "English",
|
||||||
|
"德语": "Deutsch",
|
||||||
|
"印尼语": "Indonesia",
|
||||||
|
"语言包": "Package",
|
||||||
|
"权限管理": "Permission",
|
||||||
|
"其他权限": "Other",
|
||||||
|
"菜单列表": "Menu list",
|
||||||
|
"确认要删除选择的数据吗?": "Are you sure you want to delete the selected data?",
|
||||||
|
"正在处理": "Processing",
|
||||||
|
"查询": "Search",
|
||||||
|
"编辑": "Edit",
|
||||||
|
"生成语言包": "Create package",
|
||||||
|
"导入": "Import",
|
||||||
|
"导出": "Export",
|
||||||
|
"新增": "Add",
|
||||||
|
"请输入正确的手机号": "Please input the correct mobile phone number",
|
||||||
|
"密码长度不能小于6位": "The password length cannot be less than 6 digits",
|
||||||
|
"只能是整数": "required is an integer",
|
||||||
|
"只能是数字": "required are numbers",
|
||||||
|
"必须是一个邮箱地址": "It must be an email address",
|
||||||
|
"是否启用": "Enable",
|
||||||
|
"sql语句": "Sql",
|
||||||
|
"旧密码不能为空": "Old password cannot be empty\\r\\n",
|
||||||
|
"新密码不能为空": "New password cannot be empty",
|
||||||
|
"旧密码不正确": "The old password is incorrect",
|
||||||
|
"新密码不能与旧密码相同": "The new password cannot be the same as the old password",
|
||||||
|
"密码修改成功\\r\\n": "Password modified successfully",
|
||||||
|
"不能选择此角色": "This role cannot be selected",
|
||||||
|
"用户名已经被注册\\r\\n": "The user name has been registered",
|
||||||
|
"用户新建成功.帐号[{$ts}],密码[{$ts}]": "User created successfully. Account number [{$ts}], password [{$ts}]",
|
||||||
|
"没有权限": "No permission",
|
||||||
|
"不能修改自己的角色": "You cannot modify your own role",
|
||||||
|
"角色名【{$ts}】已存在": "Role name [{$ts}] already exists\\r\\n",
|
||||||
|
"上级角色不能选择自己": "Superior roles cannot choose themselves",
|
||||||
|
"不能选择此上级角色,选择的上级角色与当前角色形成依赖关系": "This superior role cannot be selected. The selected superior role is dependent on the current role",
|
||||||
|
"服务器处理出现异常": "Server processing exceptio",
|
||||||
|
"未找到上传的文件": "Upload file not found",
|
||||||
|
"[{$ts}]不是模板中的列": "[{$ts}] is not a column in the template",
|
||||||
|
"[{$ts}]列名重复": "Duplicate column name [{$ts}]",
|
||||||
|
"导入文件列必须与导入模板相同": "The import file columns must be the same as the import template",
|
||||||
|
"下载模板": "Download template",
|
||||||
|
"上传结果": "Import result",
|
||||||
|
"保存": "Save",
|
||||||
|
"请上传文件": "Please upload the file",
|
||||||
|
"上传失败": "Upload failed",
|
||||||
|
"皮肤": "Theme",
|
||||||
|
"框架文档": "Document",
|
||||||
|
"安全退出": "Log out",
|
||||||
|
"首页": "Home",
|
||||||
|
"角色ID": "Role ID",
|
||||||
|
"部门名称": "Department",
|
||||||
|
"删除行": "Delete row",
|
||||||
|
"刷新": "Refresh",
|
||||||
|
"字典明细": "Dictionary details",
|
||||||
|
"是否可用": "Enable",
|
||||||
|
"数据源Text": "Text",
|
||||||
|
"数据源Value": "Value",
|
||||||
|
"数据源ID": "ID",
|
||||||
|
"系统日志": "Logger",
|
||||||
|
"开始时间": "Start time",
|
||||||
|
"用户名称": "Name",
|
||||||
|
"请求地址": "Url",
|
||||||
|
"日志类型": "Log type",
|
||||||
|
"响应状态": "Status",
|
||||||
|
"时长": "Duratio",
|
||||||
|
"请求参数": "Request",
|
||||||
|
"响应参数": "Response",
|
||||||
|
"异常信息": "Exception",
|
||||||
|
"用户IP": "User IP",
|
||||||
|
"浏览器类型": "Browser",
|
||||||
|
"性别": "Gender",
|
||||||
|
"操作": "Actio",
|
||||||
|
"头像": "Header",
|
||||||
|
"注册时间": "Reg time",
|
||||||
|
"审核": "Audit",
|
||||||
|
"视图/表名": "Table/View",
|
||||||
|
"菜单ID": "Menu ID",
|
||||||
|
"用户信息": "User info",
|
||||||
|
"验证码不正确": "Incorrect verification code",
|
||||||
|
"手机用户": "Mobile users",
|
||||||
|
"语言管理": "Language",
|
||||||
|
"简体中文": "zh-cn",
|
||||||
|
"繁体中文": "zh-tw",
|
||||||
|
"英语": "English",
|
||||||
|
"法语": "French",
|
||||||
|
"西班牙语": "Spanish",
|
||||||
|
"俄语": "Russian",
|
||||||
|
"高级查询": "Query",
|
||||||
|
"角色列表": "Role list",
|
||||||
|
"姓名": "Name",
|
||||||
|
"阿拉伯语": "Arabic",
|
||||||
|
"只能上传excel文件,文件大小不超过5M": "Only Excel files can be uploaded, and the file size shall not exceed 5m",
|
||||||
|
"选择的文件【{$ts}】只能是excel文件": "The selected file [{$ts}] can only be an excel file",
|
||||||
|
"选择的文件【{$ts}】只能是图片格式": "The selected file [{$ts}] can only be in picture format",
|
||||||
|
"最多只能选【{$ts}】张图片": "You can only select [{$ts}] pictures at most",
|
||||||
|
"最多只能选【{$ts}】个文件": "You can only select [{$ts}] files at most",
|
||||||
|
"不支持此文件格式": "This file format is not supported",
|
||||||
|
"文件不能超过[{$ts}]m": "File cannot exceed [{$ts}] m",
|
||||||
|
"上传中": "Uploading",
|
||||||
|
"文件列表": "File list",
|
||||||
|
"文件名": "Filen name",
|
||||||
|
"大小": "Size",
|
||||||
|
"未能处理导入的文件,请检查导入的文件是否正确": "Failed to process the imported file. Please check whether the imported file is correct",
|
||||||
|
"Token已过期": "The token has expired",
|
||||||
|
"密码长度不能少于6位": "Password length cannot be less than 6",
|
||||||
|
"密码修改成功": "Password modified successfully",
|
||||||
|
"用户不存在": "user does not exist",
|
||||||
|
"当前菜单存在子菜单,请先删除子菜单": "There are sub menus in the current menu. Please delete the sub menu first",
|
||||||
|
"【字典项名称】不能有重复的值": "[dictionary item name] cannot have duplicate values",
|
||||||
|
"【字典项Key】不能有重复的值": "[dictionary key] cannot have duplicate values",
|
||||||
|
"字典编号[{$ts}]已存在": "Dictionary number [{$ts}] already exists\\n\\n",
|
||||||
|
"账号": "account",
|
||||||
|
"越南语": "Vietnamese",
|
||||||
|
"泰语": "Thai",
|
||||||
|
"结束时间": "End time",
|
||||||
|
"是否显示": "Show or not",
|
||||||
|
"列名": "Field",
|
||||||
|
"拖动列名可调整表格列显示顺序": "Drag column names to adjust the display order of table columns",
|
||||||
|
"集团租户": "Group",
|
||||||
|
"组织构架": "Organizational",
|
||||||
|
"集团管理": "Group",
|
||||||
|
"数据分库": "Database",
|
||||||
|
"演示菜单": "Example",
|
||||||
|
"表单设计": "Form Design",
|
||||||
|
"流程管理": "Workflow",
|
||||||
|
"一对多生成": "Multiple Tables",
|
||||||
|
"新窗口编辑": "New Tab",
|
||||||
|
"打印设计": "Print",
|
||||||
|
"消息推送": "Message",
|
||||||
|
"定时任务": "Tasks",
|
||||||
|
"名称": "Name",
|
||||||
|
"编号": "Code",
|
||||||
|
"类型": "Type",
|
||||||
|
"集团名称": "Group name",
|
||||||
|
"大屏数据": "Data",
|
||||||
|
"MES业务": "MES",
|
||||||
|
"工作台设计器": "Workbench Designer",
|
||||||
|
"数据验证未通过!": "Data validation failed!",
|
||||||
|
"开发文档": "Document",
|
||||||
|
"外部链接": "Link",
|
||||||
|
"窗口编辑": "Window Edit",
|
||||||
|
"报表管理": "Report",
|
||||||
|
"单据编码": "Document code",
|
||||||
|
"工作台": "Workstation",
|
||||||
|
"租户分库": "Tenant Management",
|
||||||
|
"组件示例": "Component Example",
|
||||||
|
"组件扩展": "Component extension",
|
||||||
|
"已签收": "已签收-01",
|
||||||
|
"业务系统": "Business system",
|
||||||
|
"系统管理": "System management"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user