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前后端分离,不一样的快速开发框架(支持信创)
|
||||
|
||||
## 框架核心
|
||||
@@ -41,32 +42,32 @@ App、H5、微信小程序: [http://app.volcore.xyz/](http://app.volcore.xyz/) <
|
||||
sqlsugar: [https://www.donet5.com/](https://www.donet5.com/)
|
||||
|
||||
## 框架移动端(uniapp)已发布,同样全自动生成代码,扫描小程序二维码即可查看
|
||||

|
||||

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

|
||||

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

|
||||

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

|
||||

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

|
||||

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

|
||||

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

|
||||

|
||||
|
||||
## 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 {compressImage } from './VolImgCompress.js'
|
||||
import store from '@/store/index'
|
||||
const getImgUrls = (imgs) => {
|
||||
return imgs
|
||||
@@ -27,6 +28,8 @@ const getFormValues = (formFields, formOptions) => {
|
||||
if (typeof val == 'function') {
|
||||
formValues[key] = formFields[key]()
|
||||
continue
|
||||
} else if (typeof val == 'string' && val) {
|
||||
val = val.trim();
|
||||
}
|
||||
//解决下拉框清除后不能保存数据的问题
|
||||
if (val === undefined) {
|
||||
@@ -282,9 +285,13 @@ const getSearchParameters = (proxy, formFields, formRules) => {
|
||||
//查询下面所有的子节点,如:选中的是父节点,应该查询下面所有的节点数据--待完
|
||||
if (value && value.length) {
|
||||
let nodes = proxy.base.getTreeAllChildren(value[value.length - 1], option.orginData)
|
||||
if (!(nodes?.length)) {
|
||||
value = [value[value.length - 1]]
|
||||
} else {
|
||||
value = nodes.map((x) => {
|
||||
return x.id
|
||||
})
|
||||
}
|
||||
displayType = 'selectList'
|
||||
}
|
||||
} else if (displayType == 'treeSelect' && Array.isArray(value)) {
|
||||
@@ -335,11 +342,22 @@ const resetFileName = async (files, callbck) => {
|
||||
if (!files?.length) return
|
||||
for (let index = 0; index < files.length; index++) {
|
||||
let originalFile = files[index]
|
||||
if (!originalFile.size) {
|
||||
continue;
|
||||
}
|
||||
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,
|
||||
lastModified: originalFile.lastModified
|
||||
});
|
||||
newFile.input=originalFile.input
|
||||
files.splice(index, 1, newFile);
|
||||
}
|
||||
}
|
||||
@@ -360,5 +378,6 @@ export default {
|
||||
getAccessToken,
|
||||
isEmptyValue,
|
||||
getSearchParameters,
|
||||
resetFileName
|
||||
resetFileName,
|
||||
compressImage
|
||||
}
|
||||
|
||||
@@ -3,21 +3,11 @@
|
||||
<div>
|
||||
<!-- style="margin-bottom: 10px" -->
|
||||
<div class="input-btns" style="display: flex">
|
||||
<input
|
||||
ref="input"
|
||||
type="file"
|
||||
style="display: none"
|
||||
@change="handleChange"
|
||||
:multiple="multiple"
|
||||
/>
|
||||
<input ref="input" type="file" style="display: none" @change="handleChange" :multiple="multiple" />
|
||||
<div v-if="img" class="upload-img">
|
||||
<!-- v-for="(file,index) in fileInfo.length>0?fileInfo: files" -->
|
||||
<div
|
||||
v-for="(file, index) in files"
|
||||
:key="index"
|
||||
:style="{ height: imgInfo.height + 'px', width: imgInfo.width + 'px' }"
|
||||
class="img-item"
|
||||
>
|
||||
<div v-for="(file, index) in files" :key="index"
|
||||
:style="{ height: imgInfo.height + 'px', width: imgInfo.width + 'px' }" class="img-item">
|
||||
<div class="operation">
|
||||
<div class="action">
|
||||
<i class="el-icon-view view" @click="previewImg(index)"></i>
|
||||
@@ -28,48 +18,26 @@
|
||||
|
||||
<img :src="getImgSrc(file, index) + access_token" @error="handleImageError" />
|
||||
</div>
|
||||
<div
|
||||
:style="{ height: imgInfo.height + 'px', width: imgInfo.width + 'px' }"
|
||||
v-show="!autoUpload || (autoUpload && files.length < maxFile)"
|
||||
class="img-selector"
|
||||
:class="getSelector()"
|
||||
>
|
||||
<div :style="{ height: imgInfo.height + 'px', width: imgInfo.width + 'px' }"
|
||||
v-show="!autoUpload || (autoUpload && files.length < maxFile)" class="img-selector" :class="getSelector()">
|
||||
<div class="selector" @click="handleClick">
|
||||
<i
|
||||
:style="{ 'font-size': imgInfo.iconSize + 'px' }"
|
||||
:class="imgInfo.icon"
|
||||
></i>
|
||||
<i :style="{ 'font-size': imgInfo.iconSize + 'px' }" :class="imgInfo.icon"></i>
|
||||
</div>
|
||||
<div
|
||||
v-if="!autoUpload"
|
||||
class="s-btn"
|
||||
:class="{ readonly: changed }"
|
||||
@click="upload"
|
||||
>
|
||||
<div v-if="!autoUpload" class="s-btn" :class="{ readonly: changed }" @click="upload">
|
||||
<div>{{ loadText }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-button v-else @click="handleClick">{{
|
||||
$ts("选择" + (img ? "图片" : "文件"))
|
||||
$ts('选择' + (img ? '图片' : '文件'))
|
||||
}}</el-button>
|
||||
|
||||
<el-button
|
||||
v-if="!autoUpload && !img"
|
||||
type="info"
|
||||
:disabled="changed"
|
||||
@click="upload(true)"
|
||||
:loading="loadingStatus"
|
||||
>{{ $ts("上传文件") }}</el-button
|
||||
>
|
||||
<el-button v-if="!autoUpload && !img" type="info" :disabled="changed" @click="upload(true)"
|
||||
:loading="loadingStatus">{{ $ts('上传文件') }}</el-button>
|
||||
</div>
|
||||
<slot></slot>
|
||||
<div v-if="desc">
|
||||
<el-alert
|
||||
:title="getText() + '文件大小不超过' + (maxSize || 50) + 'M'"
|
||||
type="info"
|
||||
show-icon
|
||||
>
|
||||
<el-alert :title="getText() + '文件大小不超过' + (maxSize || 50) + 'M'" type="info" show-icon>
|
||||
</el-alert>
|
||||
</div>
|
||||
<slot name="content"></slot>
|
||||
@@ -95,96 +63,97 @@
|
||||
</template>
|
||||
<script>
|
||||
//import OSS from 'ali-oss'
|
||||
const OSS = {};
|
||||
import VolImageViewer from "./VolImageViewer.vue";
|
||||
const OSS = {}
|
||||
//import VolImageViewer from './VolImageViewer.vue'
|
||||
import { defineAsyncComponent } from 'vue'
|
||||
export default {
|
||||
components: {
|
||||
"vol-image-viewer": VolImageViewer,
|
||||
'vol-image-viewer': defineAsyncComponent(() => import('@/components/basic/VolImageViewer.vue')),
|
||||
},
|
||||
props: {
|
||||
desc: {
|
||||
//是否显示默认介绍
|
||||
//是否多选
|
||||
type: Boolean,
|
||||
default: false,
|
||||
default: false
|
||||
},
|
||||
fileInfo: {
|
||||
//用于接收上传的文件,也可以加以默认值,显示已上传的文件,用户上传后会覆盖默认值
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
}, //格式[{name:'1.jpg',path:'127.0.01/1.jpg'}]
|
||||
return []
|
||||
} //格式[{name:'1.jpg',path:'127.0.01/1.jpg'}]
|
||||
},
|
||||
downLoad: {
|
||||
//是否可以点击文件下载
|
||||
type: Boolean,
|
||||
default: true,
|
||||
default: true
|
||||
},
|
||||
multiple: {
|
||||
//是否多选
|
||||
type: Boolean,
|
||||
default: false,
|
||||
default: false
|
||||
},
|
||||
maxFile: {
|
||||
//最多可选文件数量,必须multiple=true,才会生效
|
||||
type: Number,
|
||||
default: 5,
|
||||
default: 5
|
||||
},
|
||||
maxSize: {
|
||||
//文件限制大小3M
|
||||
type: Number,
|
||||
default: 50,
|
||||
default: 50
|
||||
},
|
||||
|
||||
autoUpload: {
|
||||
//选择文件后是否自动上传
|
||||
type: Boolean,
|
||||
default: true,
|
||||
default: true
|
||||
},
|
||||
img: {
|
||||
//图片类型 img>excel>fileTypes三种文件类型优先级
|
||||
type: Boolean,
|
||||
default: false,
|
||||
default: false
|
||||
},
|
||||
excel: {
|
||||
//excel文件
|
||||
type: Boolean,
|
||||
default: false,
|
||||
default: false
|
||||
},
|
||||
fileTypes: {
|
||||
//指定上传文件的类型
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
},
|
||||
return []
|
||||
}
|
||||
},
|
||||
url: {
|
||||
//上传的url
|
||||
type: String,
|
||||
default: "",
|
||||
default: ''
|
||||
},
|
||||
uploadBefore: {
|
||||
//返回false会中止执行
|
||||
//上传前
|
||||
type: Function,
|
||||
default: (files) => {
|
||||
return true;
|
||||
},
|
||||
return true
|
||||
}
|
||||
},
|
||||
uploadAfter: {
|
||||
//返回false会中止执行
|
||||
//上传后
|
||||
type: Function,
|
||||
default: (result, files) => {
|
||||
return true;
|
||||
},
|
||||
return true
|
||||
}
|
||||
},
|
||||
onChange: {
|
||||
//选择文件时 //返回false会中止执行
|
||||
type: Function,
|
||||
default: (files) => {
|
||||
return true;
|
||||
},
|
||||
return true
|
||||
}
|
||||
},
|
||||
// clear: {
|
||||
// //上传完成后是否清空文件列表
|
||||
@@ -194,36 +163,36 @@ export default {
|
||||
fileList: {
|
||||
//是否显示选择的文件列表
|
||||
type: Boolean,
|
||||
default: true,
|
||||
default: true
|
||||
},
|
||||
fileClick: {
|
||||
//点击文件事件
|
||||
type: Function,
|
||||
default: (index, file, files) => {
|
||||
return true;
|
||||
},
|
||||
return true
|
||||
}
|
||||
},
|
||||
removeBefore: {
|
||||
//移除文件事件
|
||||
type: Function,
|
||||
default: (index, file, files) => {
|
||||
return true;
|
||||
},
|
||||
return true
|
||||
}
|
||||
},
|
||||
append: {
|
||||
//此属性已废弃,多文件上传,默认追加文件
|
||||
type: Boolean,
|
||||
default: false,
|
||||
default: false
|
||||
},
|
||||
compress: {
|
||||
//开启图片压缩,后面根据需要再完善
|
||||
//开启图片压缩
|
||||
type: Boolean,
|
||||
default: false,
|
||||
default: true
|
||||
},
|
||||
compressMinSize: {
|
||||
//压缩的最小比例
|
||||
type: Number,
|
||||
default: 0.1,
|
||||
default: 0.7
|
||||
},
|
||||
imgOption: {
|
||||
//图片上传信息
|
||||
@@ -234,327 +203,250 @@ export default {
|
||||
//iconSize:40,//上传图标大小
|
||||
// height: 65, //图片高度
|
||||
// width: 65,//图片宽度
|
||||
};
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
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') + '"',
|
||||
changed: false, //手动上传成功后禁止重复上传,必须重新选择
|
||||
model: true,
|
||||
files: [],
|
||||
bigImg: "",
|
||||
imgTypes: ["gif", "jpg", "jpeg", "png", "bmp", "webp", "jfif"],
|
||||
bigImg: '',
|
||||
imgTypes: ['gif', 'jpg', 'jpeg', 'png', 'bmp', 'webp', 'jfif'],
|
||||
loadingStatus: false,
|
||||
loadText: "上传文件",
|
||||
access_token: "",
|
||||
loadText: '上传文件',
|
||||
access_token: '',
|
||||
imgInfo: {
|
||||
icon: "el-icon-camera-solid",
|
||||
icon: 'el-icon-camera-solid',
|
||||
iconSize: 35,
|
||||
height: 65, //图片高度
|
||||
width: 65, //图片宽度
|
||||
},
|
||||
};
|
||||
width: 65 //图片宽度
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
Object.assign(this.imgInfo, this.imgOption);
|
||||
const tk = (this.$store.getters.getUserInfo() || { accessToken: "" }).accessToken;
|
||||
Object.assign(this.imgInfo, this.imgOption)
|
||||
const tk = (this.$store.getters.getUserInfo() || { accessToken: '' }).accessToken
|
||||
if (tk) {
|
||||
this.access_token = "?access_token=" + tk;
|
||||
this.access_token = '?access_token=' + tk
|
||||
}
|
||||
//默认有图片的禁止上传操作
|
||||
if (this.fileInfo) {
|
||||
this.changed = true;
|
||||
this.changed = true
|
||||
}
|
||||
this.cloneFile(this.fileInfo);
|
||||
this.cloneFile(this.fileInfo)
|
||||
},
|
||||
watch: {
|
||||
fileInfo: {
|
||||
handler(files) {
|
||||
this.cloneFile(files);
|
||||
},
|
||||
deep: true,
|
||||
this.cloneFile(files)
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
cloneFile(files) {
|
||||
this.files = files.map((x) => {
|
||||
return {
|
||||
name: x.name || this.getFileName(x.path),
|
||||
path: x.path,
|
||||
};
|
||||
});
|
||||
path: x.path
|
||||
}
|
||||
})
|
||||
},
|
||||
getFileName(path) {
|
||||
if (!path) {
|
||||
return "未定义文件名";
|
||||
return '未定义文件名'
|
||||
}
|
||||
let _index = path.lastIndexOf("/");
|
||||
return path.substring(_index + 1);
|
||||
let _index = path.lastIndexOf('/')
|
||||
return path.substring(_index + 1)
|
||||
},
|
||||
previewImg(index) {
|
||||
const imgs = this.files.map((x) => {
|
||||
return this.getImgSrc(x) + this.access_token;
|
||||
});
|
||||
this.$refs.viewer.show(imgs, index);
|
||||
return this.getImgSrc(x) + this.access_token
|
||||
})
|
||||
this.$refs.viewer.show(imgs, index)
|
||||
// this.base.previewImg(this.getImgSrc(this.files[index]));
|
||||
// window.open(this.getImgSrc((this.files.length>0?this.files:this.fileInfo)[index]));
|
||||
},
|
||||
getSelector() {
|
||||
if (this.autoUpload) {
|
||||
return "auto-selector";
|
||||
return 'auto-selector'
|
||||
}
|
||||
return "submit-selector";
|
||||
return 'submit-selector'
|
||||
},
|
||||
getImgSrc(file, index) {
|
||||
if (file.hasOwnProperty("path")) {
|
||||
if (file.hasOwnProperty('path')) {
|
||||
if (this.base.isUrl(file.path)) {
|
||||
return file.path;
|
||||
return file.path
|
||||
}
|
||||
//2020.12.27增加base64图片操作
|
||||
if (file.path.indexOf("/9j/") != -1) {
|
||||
return "data:image/jpeg;base64," + file.path;
|
||||
if (file.path.indexOf('/9j/') != -1) {
|
||||
return 'data:image/jpeg;base64,' + file.path
|
||||
}
|
||||
if (file.path.substr(0, 1) == "/") {
|
||||
file.path = file.path.substr(1);
|
||||
if (file.path.substr(0, 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) {
|
||||
if (!this.fileClick(index, file, this.files)) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
//点击不下载
|
||||
if (!this.downLoad) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
if (!file.path) {
|
||||
this.$message.error("请先上传文件");
|
||||
return;
|
||||
this.$message.error('请先上传文件')
|
||||
return
|
||||
}
|
||||
this.base.dowloadFile(
|
||||
file.path + this.access_token,
|
||||
file.name,
|
||||
{
|
||||
Authorization: this.$store.getters.getToken(),
|
||||
Authorization: this.$store.getters.getToken()
|
||||
},
|
||||
this.http.ipAddress
|
||||
);
|
||||
)
|
||||
},
|
||||
getText() {
|
||||
if (this.img) {
|
||||
return "只能上传图片,";
|
||||
return '只能上传图片,'
|
||||
} else if (this.excel) {
|
||||
return "只能上传excel文件,";
|
||||
return '只能上传excel文件,'
|
||||
}
|
||||
},
|
||||
handleClick() {
|
||||
this.$refs.input.click();
|
||||
this.$refs.input.click()
|
||||
},
|
||||
handleChange(e) {
|
||||
//this.compress开启图片压缩,后面根据需要再完善
|
||||
// this.clearFiles();
|
||||
var result = this.checkFile(e.target.files);
|
||||
var result = this.checkFile(e.target.files)
|
||||
if (!result) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
this.changed = false;
|
||||
this.changed = false
|
||||
//如果传入了FileInfo需要自行处理移除FileInfo
|
||||
if (!this.onChange(e.target.files)) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
for (let index = 0; index < e.target.files.length; index++) {
|
||||
const element = e.target.files[index];
|
||||
element.input = true;
|
||||
const element = e.target.files[index]
|
||||
element.input = true
|
||||
}
|
||||
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) {
|
||||
this.upload(false);
|
||||
this.upload(false)
|
||||
}
|
||||
},
|
||||
removeFile(index) {
|
||||
//如果传入了FileInfo需要自行处理移除FileInfo
|
||||
//t移除文件
|
||||
let removeFile = this.files[index];
|
||||
let removeFile = this.files[index]
|
||||
if (!this.removeBefore(index, removeFile, this.fileInfo)) {
|
||||
return
|
||||
}
|
||||
//删除的还没上传的文件
|
||||
if (removeFile.input) {
|
||||
this.files.splice(index, 1);
|
||||
this.files.splice(index, 1)
|
||||
} else {
|
||||
this.fileInfo.splice(index, 1);
|
||||
}
|
||||
if (!this.removeBefore(index, removeFile, this.fileInfo)) {
|
||||
return;
|
||||
this.fileInfo.splice(index, 1)
|
||||
}
|
||||
},
|
||||
clearFiles() {
|
||||
this.files.splice(0);
|
||||
this.files.splice(0)
|
||||
},
|
||||
getFiles() {
|
||||
return this.files;
|
||||
return this.files
|
||||
},
|
||||
convertToFile(dataurl, filename) {
|
||||
let arr = dataurl.split(",");
|
||||
let mime = arr[0].match(/:(.*?);/)[1];
|
||||
let suffix = mime.split("/")[1];
|
||||
let bstr = atob(arr[1]);
|
||||
let n = bstr.length;
|
||||
let u8arr = new Uint8Array(n);
|
||||
while (n--) {
|
||||
u8arr[n] = bstr.charCodeAt(n);
|
||||
async compressImg() {
|
||||
if (!this.compress||!this.img) return;
|
||||
for (let index = 0; index < this.files.length; index++) {
|
||||
let originalFile = this.files[index]
|
||||
if (originalFile.size > 300 * 1024) {
|
||||
try {
|
||||
const newFile = await this.base.compressImage(originalFile, { initialQuality: this.compressMinSize });
|
||||
newFile.input = originalFile.input
|
||||
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() {
|
||||
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) {
|
||||
if (vail && !this.checkFile()) return false;
|
||||
if (vail && !this.checkFile()) return false
|
||||
if (!this.url) {
|
||||
return this.$message.error("没有配置好Url");
|
||||
return this.$message.error('没有配置好Url')
|
||||
}
|
||||
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["字段"]
|
||||
let params = {};
|
||||
if (!this.uploadBefore(this.files, params)) {
|
||||
return;
|
||||
let params = {}
|
||||
if (! await this.uploadBefore(this.files, params)) {
|
||||
return
|
||||
}
|
||||
let paramText = "";
|
||||
let paramText = ''
|
||||
if (Object.keys(params).length) {
|
||||
paramText = "?1=1";
|
||||
paramText = '?1=1'
|
||||
for (const key in params) {
|
||||
let value = params[key];
|
||||
if (typeof value == "object") {
|
||||
value = JSON.stringify(value);
|
||||
let value = params[key]
|
||||
if (typeof value == 'object') {
|
||||
value = JSON.stringify(value)
|
||||
}
|
||||
paramText += `&${key}=${value}`;
|
||||
paramText += `&${key}=${value}`
|
||||
}
|
||||
}
|
||||
|
||||
this.loadingStatus = true;
|
||||
this.loadText = "上传中..";
|
||||
this.loadingStatus = true
|
||||
this.loadText = '上传中..'
|
||||
if (window.oss && window.oss.ali.use) {
|
||||
await this.uploadOSS();
|
||||
this.loadingStatus = false;
|
||||
this.loadText = "上传文件";
|
||||
await this.uploadOSS()
|
||||
this.loadingStatus = false
|
||||
this.loadText = '上传文件'
|
||||
if (!this.uploadAfter({ status: true }, this.files)) {
|
||||
this.changed = false;
|
||||
return;
|
||||
this.changed = false
|
||||
return
|
||||
} else {
|
||||
this.changed = true;
|
||||
this.changed = true
|
||||
}
|
||||
this.$message.success("上传成功");
|
||||
return;
|
||||
this.$message.success('上传成功')
|
||||
return
|
||||
}
|
||||
|
||||
var forms = new FormData();
|
||||
var forms = new FormData()
|
||||
for (let index = 0; index < this.files.length; index++) {
|
||||
let file = this.files[index];
|
||||
let file = this.files[index]
|
||||
if (file.input) {
|
||||
//2023.07.10暂时屏蔽图片压缩
|
||||
//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', file, file.name)
|
||||
}
|
||||
}
|
||||
// forms.append("fileInput", this.files);
|
||||
@@ -563,174 +455,143 @@ export default {
|
||||
.post(
|
||||
this.url + paramText,
|
||||
forms,
|
||||
this.autoUpload ? "正在上传文件" : "",
|
||||
this.autoUpload ? '正在上传文件' : '',
|
||||
//高版本axios这里必须要指定header
|
||||
{
|
||||
headers: { "Content-Type": "multipart/form-data" },
|
||||
headers: { 'Content-Type': 'multipart/form-data' }
|
||||
}
|
||||
)
|
||||
.then(
|
||||
(x) => {
|
||||
// this.$refs.uploadFile.clearFiles();
|
||||
this.loadingStatus = false;
|
||||
this.loadText = "上传文件";
|
||||
this.loadingStatus = false
|
||||
this.loadText = '上传文件'
|
||||
if (!this.uploadAfter(x, this.files)) {
|
||||
this.changed = false;
|
||||
return;
|
||||
this.changed = false
|
||||
return
|
||||
} else {
|
||||
this.changed = true;
|
||||
this.changed = true
|
||||
}
|
||||
|
||||
this.changed = x.status;
|
||||
this.changed = x.status
|
||||
if (!x.status) {
|
||||
this.$message.error(x.message);
|
||||
this.$message.error(x.message)
|
||||
// this.files = null;
|
||||
return;
|
||||
return
|
||||
}
|
||||
this.$message.success(x.message);
|
||||
this.$message.success(x.message)
|
||||
//单选清除以前的数据
|
||||
// if (!this.multiple) {
|
||||
this.fileInfo.splice(0);
|
||||
this.fileInfo.splice(0)
|
||||
// }
|
||||
let _files = this.files.map((file) => {
|
||||
return {
|
||||
name: file.name,
|
||||
path: file.path || x.data + file.name,
|
||||
};
|
||||
});
|
||||
this.fileInfo.push(..._files);
|
||||
path: file.path || x.data + file.name
|
||||
}
|
||||
})
|
||||
this.fileInfo.push(..._files)
|
||||
//2021.09.25修复文件上传后不能同时下载的问题
|
||||
this.files = _files;
|
||||
this.files = _files
|
||||
},
|
||||
(error) => {
|
||||
this.loadText = "上传文件";
|
||||
this.loadingStatus = false;
|
||||
this.loadText = '上传文件'
|
||||
this.loadingStatus = false
|
||||
}
|
||||
);
|
||||
)
|
||||
},
|
||||
format(file, checkFileType) {
|
||||
const format = file.name.split(".").pop().toLocaleLowerCase() || "";
|
||||
let fileIcon = "el-icon-document";
|
||||
const format = file.name.split('.').pop().toLocaleLowerCase() || ''
|
||||
let fileIcon = 'el-icon-document'
|
||||
if (this.fileTypes.length > 0 && checkFileType != undefined) {
|
||||
if (this.fileTypes.indexOf(format) != -1) {
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
if (
|
||||
checkFileType &&
|
||||
!(checkFileType instanceof Array) &&
|
||||
checkFileType != "img" &&
|
||||
checkFileType != "excel"
|
||||
checkFileType != 'img' &&
|
||||
checkFileType != 'excel'
|
||||
) {
|
||||
if (checkFileType.indexOf(format) > -1) {
|
||||
return true;
|
||||
return true
|
||||
} else {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if (checkFileType == "img" || this.imgTypes.indexOf(format) > -1) {
|
||||
if (checkFileType == "img") {
|
||||
if (checkFileType == 'img' || this.imgTypes.indexOf(format) > -1) {
|
||||
if (checkFileType == 'img') {
|
||||
if (this.imgTypes.indexOf(format) > -1) {
|
||||
return true;
|
||||
return true
|
||||
} else {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
}
|
||||
fileIcon = "el-icon-picture-outline";
|
||||
fileIcon = 'el-icon-picture-outline'
|
||||
}
|
||||
if (
|
||||
["mp4", "m3u8", "rmvb", "avi", "swf", "3gp", "mkv", "flv"].indexOf(format) > -1
|
||||
) {
|
||||
fileIcon = "el-icon-document";
|
||||
}
|
||||
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;
|
||||
if (checkFileType == 'excel' || ['numbers', 'csv', 'xls', 'xlsx'].indexOf(format) > -1) {
|
||||
if (checkFileType == 'excel') {
|
||||
if (['numbers', 'csv', 'xls', 'xlsx'].indexOf(format) > -1) {
|
||||
return true
|
||||
} else {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
}
|
||||
fileIcon = "el-icon-document";
|
||||
}
|
||||
return fileIcon;
|
||||
return fileIcon
|
||||
},
|
||||
beforeUpload() {},
|
||||
beforeUpload() { },
|
||||
checkFile(inputFiles) {
|
||||
const files = this.files;
|
||||
const files = this.files
|
||||
|
||||
if (
|
||||
this.multiple &&
|
||||
files.length + (inputFiles || []).length > (this.maxFile || 5)
|
||||
) {
|
||||
if (this.multiple && files.length + (inputFiles || []).length > (this.maxFile || 5)) {
|
||||
this.$message.error(
|
||||
"最多只能选【" +
|
||||
(this.maxFile || 5) +
|
||||
"】" +
|
||||
(this.img ? "张图片" : "个文件") +
|
||||
""
|
||||
);
|
||||
return false;
|
||||
'最多只能选【' + (this.maxFile || 5) + '】' + (this.img ? '张图片' : '个文件') + ''
|
||||
)
|
||||
return false
|
||||
}
|
||||
if (!inputFiles) {
|
||||
inputFiles = this.files.filter((x) => {
|
||||
return x.input;
|
||||
});
|
||||
return x.input
|
||||
})
|
||||
}
|
||||
let names = [];
|
||||
let names = []
|
||||
for (let index = 0; index < inputFiles.length; index++) {
|
||||
const file = inputFiles[index];
|
||||
const file = inputFiles[index]
|
||||
if (names.indexOf(file.name) != -1) {
|
||||
file.name = "(" + index + ")" + file.name;
|
||||
file.name = '(' + index + ')' + file.name
|
||||
}
|
||||
names.push(file.name);
|
||||
if (this.img && !this.format(file, "img")) {
|
||||
this.$message.error("选择的文件【" + file.name + "】只能是图片格式");
|
||||
return false;
|
||||
names.push(file.name)
|
||||
if (this.img && !this.format(file, 'img')) {
|
||||
this.$message.error('选择的文件【' + file.name + '】只能是图片格式')
|
||||
return false
|
||||
}
|
||||
if (this.excel && !this.format(file, "excel")) {
|
||||
this.$message.error("选择的文件【" + file.name + "】只能是excel文件");
|
||||
return false;
|
||||
if (this.excel && !this.format(file, 'excel')) {
|
||||
this.$message.error('选择的文件【' + file.name + '】只能是excel文件')
|
||||
return false
|
||||
}
|
||||
if (
|
||||
this.fileTypes &&
|
||||
this.fileTypes.length > 0 &&
|
||||
!this.format(file, this.fileTypes)
|
||||
) {
|
||||
if (this.fileTypes && this.fileTypes.length > 0 && !this.format(file, this.fileTypes)) {
|
||||
this.$message.error(
|
||||
"选择的文件【" +
|
||||
file.name +
|
||||
"】只能是【" +
|
||||
this.fileTypes.join(",") +
|
||||
"】格式"
|
||||
);
|
||||
return false;
|
||||
'选择的文件【' + file.name + '】只能是【' + this.fileTypes.join(',') + '】格式'
|
||||
)
|
||||
return false
|
||||
}
|
||||
if (file.size > (this.maxSize || 50) * 1024 * 1024) {
|
||||
this.$message.error(
|
||||
"选择的文件【" + file.name + "】不能超过:" + (this.maxSize || 50) + "M"
|
||||
);
|
||||
return false;
|
||||
'选择的文件【' + file.name + '】不能超过:' + (this.maxSize || 50) + 'M'
|
||||
)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return true
|
||||
},
|
||||
handleImageError($e) {
|
||||
$e.target.src = this.defaultImg;
|
||||
},
|
||||
},
|
||||
};
|
||||
$e.target.src = this.defaultImg
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.upload-list {
|
||||
@@ -780,12 +641,12 @@ export default {
|
||||
margin-top: 43px;
|
||||
}
|
||||
|
||||
.button-group > * {
|
||||
.button-group>* {
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.file-info > span {
|
||||
.file-info>span {
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
@@ -910,8 +771,7 @@ export default {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
|
||||
.m-img {
|
||||
}
|
||||
.m-img {}
|
||||
|
||||
.mask {
|
||||
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