设备型号版本功能完善
|
@ -201,6 +201,8 @@ qiniu:
|
|||
bucket: autosprout
|
||||
# 过期时间(秒)
|
||||
expireSeconds: 86400
|
||||
# 七牛云token缓存
|
||||
cacheKey: qiniu-token
|
||||
# 七牛云GET请求域名
|
||||
domain: https://lxnapi.ccttiot.com
|
||||
xinzhi:
|
||||
|
|
|
@ -2,8 +2,11 @@ package com.ruoyi.common.utils.qiniu;
|
|||
|
||||
import com.qiniu.util.Auth;
|
||||
import com.qiniu.util.StringMap;
|
||||
import com.ruoyi.common.core.redis.RedisCache;
|
||||
import com.ruoyi.common.utils.spring.SpringUtils;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 七牛云工具类
|
||||
* @author wjh
|
||||
|
@ -16,15 +19,32 @@ public class QiNiuUtils {
|
|||
public static final String BUCKET = SpringUtils.getRequiredProperty("qiniu.bucket");
|
||||
public static final Long EXPIRE_SECONDS = Long.parseLong(SpringUtils.getRequiredProperty("qiniu.expireSeconds")); // 过期时间(秒)
|
||||
public static final String DOMAIN = SpringUtils.getRequiredProperty("qiniu.domain"); // 域名
|
||||
private static final RedisCache REDIS_CACHE = SpringUtils.getBean(RedisCache.class);
|
||||
private static final String CACHE_KEY = SpringUtils.getRequiredProperty("qiniu.cacheKey");
|
||||
|
||||
/**
|
||||
* 获取文件上传的token
|
||||
* @return token
|
||||
*/
|
||||
// public static String getToken() {
|
||||
// StringMap putPolicy = new StringMap();
|
||||
// Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
|
||||
// return auth.uploadToken(BUCKET,null, EXPIRE_SECONDS, putPolicy);
|
||||
// }
|
||||
|
||||
/**
|
||||
* 获取文件上传的token
|
||||
* @return token
|
||||
*/
|
||||
public static String getToken() {
|
||||
StringMap putPolicy = new StringMap();
|
||||
Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
|
||||
return auth.uploadToken(BUCKET,null, EXPIRE_SECONDS, putPolicy);
|
||||
String tokenCache = REDIS_CACHE.getCacheObject(CACHE_KEY);
|
||||
if (tokenCache == null) {
|
||||
StringMap putPolicy = new StringMap();
|
||||
Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
|
||||
tokenCache = auth.uploadToken(BUCKET,null, EXPIRE_SECONDS, putPolicy);
|
||||
REDIS_CACHE.setCacheObject(CACHE_KEY, tokenCache, EXPIRE_SECONDS.intValue(), TimeUnit.SECONDS);
|
||||
}
|
||||
return tokenCache;
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
|
|
BIN
AutoSprout-ui/src/assets/fileicons/excel.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
AutoSprout-ui/src/assets/fileicons/pdf.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
AutoSprout-ui/src/assets/fileicons/ppt.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
AutoSprout-ui/src/assets/fileicons/unknown.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
AutoSprout-ui/src/assets/fileicons/video.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
AutoSprout-ui/src/assets/fileicons/word.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
AutoSprout-ui/src/assets/fileicons/zip.png
Normal file
After Width: | Height: | Size: 849 B |
|
@ -10,7 +10,7 @@
|
|||
:on-exceed="handleExceed"
|
||||
:on-success="handleUploadSuccess"
|
||||
:show-file-list="false"
|
||||
:data="uploadData"
|
||||
:headers="headers"
|
||||
class="upload-file-uploader"
|
||||
ref="fileUpload"
|
||||
>
|
||||
|
@ -28,9 +28,13 @@
|
|||
<!-- 文件列表 -->
|
||||
<transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
|
||||
<li :key="file.url" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList">
|
||||
<el-link :href="`${file.url}`" :underline="false" target="_blank">
|
||||
<span class="el-icon-document"> {{ getFileName(file.name) }} </span>
|
||||
</el-link>
|
||||
<div class="file-link">
|
||||
<image-preview v-if="isImage(file.url)" :src="file.url" :width="32" :height="32" style="margin-right: 10px"/>
|
||||
<i class="el-icon-document" v-else/>
|
||||
<el-link :href="realUrl(file.url)" :underline="false" target="_blank">
|
||||
{{ getFileName(file.name) }}
|
||||
</el-link>
|
||||
</div>
|
||||
<div class="ele-upload-list__item-content-action">
|
||||
<el-link :underline="false" @click="handleDelete(index)" type="danger">删除</el-link>
|
||||
</div>
|
||||
|
@ -40,8 +44,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { getToken } from "@/utils/auth";
|
||||
import { getQiniuToken } from "@/api/common/common";
|
||||
import { getToken } from '@/utils/auth'
|
||||
|
||||
export default {
|
||||
name: "FileUpload",
|
||||
|
@ -56,13 +59,12 @@ export default {
|
|||
// 大小限制(MB)
|
||||
fileSize: {
|
||||
type: Number,
|
||||
default: 5,
|
||||
default: 10,
|
||||
},
|
||||
// 文件类型, 例如['png', 'jpg', 'jpeg']
|
||||
fileType: {
|
||||
type: Array,
|
||||
// default: () => ["doc", "docx", "xls", "ppt", "txt", "pdf","bin"],
|
||||
default: () => ["bin"],
|
||||
default: () => ["doc", "xls", "ppt", "txt", "pdf", "xlsx", "jpg", "jpeg", "png"],
|
||||
},
|
||||
// 是否显示提示
|
||||
isShowTip: {
|
||||
|
@ -75,24 +77,13 @@ export default {
|
|||
number: 0,
|
||||
uploadList: [],
|
||||
baseUrl: process.env.VUE_APP_BASE_API,
|
||||
uploadData: {token:''},
|
||||
domain:"",
|
||||
uploadFileUrl: "https://up-z2.qiniup.com", // 上传文件服务器地址
|
||||
// headers: {
|
||||
// Authorization: "Bearer " + getToken(),
|
||||
// },
|
||||
uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传文件服务器地址
|
||||
headers: {
|
||||
Authorization: "Bearer " + getToken(),
|
||||
},
|
||||
fileList: [],
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
getQiniuToken().then((res)=> {
|
||||
console.log("七牛云获取token"+JSON.stringify(res));
|
||||
if (res.code === 200) {
|
||||
this.uploadData.token = res.token
|
||||
this.domain = res.domain;
|
||||
}
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
handler(val) {
|
||||
|
@ -122,8 +113,21 @@ export default {
|
|||
showTip() {
|
||||
return this.isShowTip && (this.fileType || this.fileSize);
|
||||
},
|
||||
// 获取真实url
|
||||
realUrl() {
|
||||
return (url) => {
|
||||
if (url.startsWith('http')) {
|
||||
return url;
|
||||
}
|
||||
return this.baseUrl + url;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 是否是图片
|
||||
isImage(url) {
|
||||
return url.endsWith('.png') || url.endsWith('.jpg') || url.endsWith('.jpeg');
|
||||
},
|
||||
// 上传前校检格式和大小
|
||||
handleBeforeUpload(file) {
|
||||
// 校检文件类型
|
||||
|
@ -155,24 +159,20 @@ export default {
|
|||
// 上传失败
|
||||
handleUploadError(err) {
|
||||
this.$modal.msgError("上传文件失败,请重试");
|
||||
this.$modal.closeLoading()
|
||||
this.$modal.closeLoading();
|
||||
},
|
||||
// 上传成功回调
|
||||
handleUploadSuccess(res, file) {
|
||||
console.log("七牛云获取res"+JSON.stringify(res));
|
||||
console.log("七牛云获取file"+JSON.stringify(file));
|
||||
this.uploadList.push({ name: res.hash, url: this.domain+"/"+res.hash });
|
||||
this.uploadedSuccessfully();
|
||||
// if (res.code === 200) {
|
||||
// this.uploadList.push({ name: res.fileName, url: res.fileName });
|
||||
// this.uploadedSuccessfully();
|
||||
// } else {
|
||||
// this.number--;
|
||||
// this.$modal.closeLoading();
|
||||
// this.$modal.msgError(res.msg);
|
||||
// this.$refs.fileUpload.handleRemove(file);
|
||||
// this.uploadedSuccessfully();
|
||||
// }
|
||||
if (res.code === 200) {
|
||||
this.uploadList.push({ name: res.fileName, url: res.fileName });
|
||||
this.uploadedSuccessfully();
|
||||
} else {
|
||||
this.number--;
|
||||
this.$modal.closeLoading();
|
||||
this.$modal.msgError(res.msg);
|
||||
this.$refs.fileUpload.handleRemove(file);
|
||||
this.uploadedSuccessfully();
|
||||
}
|
||||
},
|
||||
// 删除文件
|
||||
handleDelete(index) {
|
||||
|
@ -181,9 +181,7 @@ export default {
|
|||
},
|
||||
// 上传结束处理
|
||||
uploadedSuccessfully() {
|
||||
console.log("this.number:"+this.number);
|
||||
console.log("this.uploadList.length:"+this.uploadList.length);
|
||||
if (this.number > 0) {
|
||||
if (this.number > 0 && this.uploadList.length === this.number) {
|
||||
this.fileList = this.fileList.concat(this.uploadList);
|
||||
this.uploadList = [];
|
||||
this.number = 0;
|
||||
|
@ -193,10 +191,11 @@ export default {
|
|||
},
|
||||
// 获取文件名称
|
||||
getFileName(name) {
|
||||
// 如果是url那么取最后的名字 如果不是直接返回
|
||||
if (name.lastIndexOf("/") > -1) {
|
||||
return name.slice(name.lastIndexOf("/") + 1);
|
||||
} else {
|
||||
return "";
|
||||
return name;
|
||||
}
|
||||
},
|
||||
// 对象转成指定字符串分隔
|
||||
|
@ -231,4 +230,9 @@ export default {
|
|||
.ele-upload-list__item-content-action .el-link {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.file-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
<template>
|
||||
<div class="component-upload-image">
|
||||
<div
|
||||
class="component-upload-image"
|
||||
@mouseenter="handleMouseEnter"
|
||||
@mouseleave="handleMouseLeave"
|
||||
>
|
||||
<el-upload
|
||||
multiple
|
||||
:action="uploadImgUrl"
|
||||
|
@ -12,39 +16,85 @@
|
|||
ref="imageUpload"
|
||||
:on-remove="handleDelete"
|
||||
:show-file-list="true"
|
||||
:data='uploadData'
|
||||
:headers="headers"
|
||||
:file-list="fileList"
|
||||
:on-preview="handlePictureCardPreview"
|
||||
:class="{hide: this.fileList.length >= this.limit}"
|
||||
class="image-upload"
|
||||
:style="cssVars"
|
||||
:data="uploadData"
|
||||
drag
|
||||
>
|
||||
<!-- 粘贴区域(隐藏) -->
|
||||
<textarea
|
||||
ref="pasteArea"
|
||||
class="paste-area"
|
||||
@paste="handlePaste"
|
||||
></textarea>
|
||||
<!-- 上传按钮 -->
|
||||
<i class="el-icon-plus"></i>
|
||||
<!-- 文件列表 -->
|
||||
<template #file="{ file }">
|
||||
<div :class="['el-upload-list__item', { 'is-file': !isImage(file.url) }]">
|
||||
<!-- 图片 -->
|
||||
<img v-if="isImage(file.url)" class="el-upload-list__item-thumbnail " :src="file.url" alt=""/>
|
||||
<!-- 视频 -->
|
||||
<video v-else-if="isVideo(file.url)" class="el-upload-list__item-thumbnail" :src="file.url" alt=""/>
|
||||
<!-- 文件图标 -->
|
||||
<img v-else class="el-upload-list__item-thumbnail" :src="getFileIcon(file.url)" alt=""/>
|
||||
<!-- 操作按钮 -->
|
||||
<span class="el-upload-list__item-actions">
|
||||
<span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
|
||||
<i class="el-icon-zoom-in"></i>
|
||||
</span>
|
||||
<span class="el-upload-list__item-delete" @click="handleDelete(file)">
|
||||
<i class="el-icon-delete"></i>
|
||||
</span>
|
||||
</span>
|
||||
<!-- 文件名 -->
|
||||
<div class="file-name-container">
|
||||
<el-tooltip :content="getDisplayFileName(file)" placement="bottom" :disabled="getDisplayFileName(file).length <= 10">
|
||||
<span class="file-name" :class="{'edit-name': editName}" @click="editFileName(file)">
|
||||
<i v-if="editName" class="el-icon-edit"></i>
|
||||
{{ getDisplayFileName(file) }}
|
||||
</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
|
||||
<!-- 上传提示 -->
|
||||
<div class="el-upload__tip" slot="tip" v-if="showTip">
|
||||
<div v-if="uploadType === 'image'" style="color: #909399; margin-bottom: 8px;">
|
||||
建议尺寸:700×286
|
||||
</div>
|
||||
请上传
|
||||
<template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
|
||||
<template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
|
||||
<template v-if="fileSize">大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b></template>
|
||||
<template v-if="fileType">格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b></template>
|
||||
的文件
|
||||
<br/>
|
||||
支持
|
||||
<b style="color: #f56c6c">拖动上传</b>
|
||||
和鼠标移入后
|
||||
<b style="color: #f56c6c">Ctrl+V</b>
|
||||
粘贴上传
|
||||
</div>
|
||||
|
||||
<el-dialog
|
||||
:visible.sync="dialogVisible"
|
||||
title="预览"
|
||||
width="800"
|
||||
append-to-body
|
||||
>
|
||||
<img
|
||||
:src="dialogImageUrl"
|
||||
style="display: block; max-width: 100%; margin: 0 auto"
|
||||
/>
|
||||
<!-- 预览 -->
|
||||
<el-dialog :visible.sync="dialogVisible" title="预览" width="800" append-to-body>
|
||||
<video v-if="isVideo(dialogImageUrl)" :src="dialogImageUrl" controls style="display: block; max-width: 100%; margin: 0 auto"/>
|
||||
<img v-else :src="dialogImageUrl" style="display: block; max-width: 100%; margin: 0 auto"/>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getToken } from "@/utils/auth";
|
||||
import {getQiniuToken} from "@/api/common/common";
|
||||
import { getToken } from '@/utils/auth'
|
||||
import { getQiniuToken } from "@/api/tool/common";
|
||||
import axios from 'axios'
|
||||
import { getRealUrl, getFileIcon, getExt, isImage, getFileNameWithTime, isVideo } from '@/utils'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
|
@ -57,7 +107,11 @@ export default {
|
|||
// 大小限制(MB)
|
||||
fileSize: {
|
||||
type: Number,
|
||||
default: 5,
|
||||
default: 200,
|
||||
},
|
||||
uploadType: {
|
||||
type: String,
|
||||
default: 'image' // image/video
|
||||
},
|
||||
// 文件类型, 例如['png', 'jpg', 'jpeg']
|
||||
fileType: {
|
||||
|
@ -68,6 +122,35 @@ export default {
|
|||
isShowTip: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: "148px"
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: "148px"
|
||||
},
|
||||
// 上传地址,可选local、qiniu
|
||||
host: {
|
||||
type: String,
|
||||
default: "qiniu",
|
||||
validator: function (value) {
|
||||
return ['local', 'qiniu'].includes(value);
|
||||
}
|
||||
},
|
||||
// 是否可编辑文件名
|
||||
editName: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 值类型,可选string 字符串、array-string 字符串数组、array-object 对象数组
|
||||
valueType: {
|
||||
type: String,
|
||||
default: 'string',
|
||||
validator: function (value) {
|
||||
return ['string', 'array-string', 'array-object'].includes(value);
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
@ -78,37 +161,35 @@ export default {
|
|||
dialogVisible: false,
|
||||
hideUpload: false,
|
||||
baseUrl: process.env.VUE_APP_BASE_API,
|
||||
uploadData: {token:''},
|
||||
domain:"",
|
||||
uploadImgUrl:"https://up-z2.qiniup.com", // 上传的图片服务器地址
|
||||
// headers: {
|
||||
// Authorization: "Bearer " + getToken(),
|
||||
// },
|
||||
fileList: []
|
||||
fileList: [],
|
||||
isListening: false,
|
||||
qiniuToken: null,
|
||||
uploadData: {},
|
||||
domain: null,
|
||||
};
|
||||
},
|
||||
mounted(){
|
||||
getQiniuToken().then(res => {
|
||||
debugger
|
||||
console.log("获取到七牛云token:"+JSON.stringify(res));
|
||||
if (res.code === 200) {
|
||||
this.uploadData.token = res.token;
|
||||
this.domain = res.domain;
|
||||
}
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
handler(val) {
|
||||
if (val) {
|
||||
// 首先将值转为数组
|
||||
const list = Array.isArray(val) ? val : this.value.split(',');
|
||||
let list = [];
|
||||
if (Array.isArray(val)) {
|
||||
list = val;
|
||||
} else {
|
||||
list = val.split(',');
|
||||
}
|
||||
|
||||
// 然后将数组转为对象数组
|
||||
this.fileList = list.map(item => {
|
||||
if (typeof item === "string") {
|
||||
item = { name: item, url: item };
|
||||
return {
|
||||
name: item, // 保持原始名称,用于判断文件类型
|
||||
url: this.getRealUrl(item)
|
||||
};
|
||||
} else {
|
||||
return item;
|
||||
}
|
||||
return item;
|
||||
});
|
||||
} else {
|
||||
this.fileList = [];
|
||||
|
@ -124,38 +205,198 @@ export default {
|
|||
showTip() {
|
||||
return this.isShowTip && (this.fileType || this.fileSize);
|
||||
},
|
||||
// 计算样式
|
||||
cssVars() {
|
||||
return {
|
||||
'--width': this.width,
|
||||
'--height': this.height
|
||||
}
|
||||
},
|
||||
// 新增:获取文件图标的方法
|
||||
getFileIcon() {
|
||||
return (url) => {
|
||||
return getFileIcon(url);
|
||||
}
|
||||
},
|
||||
// 是否为图片
|
||||
isImage() {
|
||||
return (url) => {
|
||||
return isImage(url);
|
||||
}
|
||||
},
|
||||
// 是否为视频
|
||||
isVideo() {
|
||||
return (url) => {
|
||||
return isVideo(url);
|
||||
}
|
||||
},
|
||||
// 新增:获取显示的文件名
|
||||
getDisplayFileName() {
|
||||
return (file) => {
|
||||
let fileName = file.name;
|
||||
// 如果是URL格式,取最后一个斜杠后的值
|
||||
if (fileName.includes('/')) {
|
||||
fileName = fileName.split('/').pop();
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
},
|
||||
// 上传图片地址
|
||||
uploadImgUrl() {
|
||||
if (this.host === 'qiniu') {
|
||||
return 'https://up-z2.qiniup.com';
|
||||
}
|
||||
return process.env.VUE_APP_BASE_API + "/common/upload";
|
||||
},
|
||||
// 请求头
|
||||
headers() {
|
||||
if (this.host === 'local') {
|
||||
return {
|
||||
Authorization: "Bearer " + getToken(),
|
||||
};
|
||||
}
|
||||
return {};
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
// 上传前loading加载
|
||||
handleBeforeUpload(file) {
|
||||
let isImg = false;
|
||||
if (this.fileType.length) {
|
||||
let fileExtension = "";
|
||||
if (file.name.lastIndexOf(".") > -1) {
|
||||
fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
|
||||
editFileName(file) {
|
||||
if (!this.editName) {
|
||||
return;
|
||||
}
|
||||
this.$prompt('请输入文件名', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
inputPattern: /^[^<>]*$/,
|
||||
inputErrorMessage: '文件名不能包含<或>',
|
||||
inputValue: file.name,
|
||||
}).then(({ value }) => {
|
||||
file.name = value;
|
||||
this.emitInputValue();
|
||||
});
|
||||
},
|
||||
// 获取真实url
|
||||
getRealUrl,
|
||||
// 新增:鼠标进入处理
|
||||
handleMouseEnter() {
|
||||
if (!this.isListening) {
|
||||
if (this.$refs.pasteArea) {
|
||||
this.$refs.pasteArea.focus();
|
||||
}
|
||||
isImg = this.fileType.some(type => {
|
||||
if (file.type.indexOf(type) > -1) return true;
|
||||
if (fileExtension && fileExtension.indexOf(type) > -1) return true;
|
||||
return false;
|
||||
});
|
||||
} else {
|
||||
isImg = file.type.indexOf("image") > -1;
|
||||
this.isListening = true;
|
||||
}
|
||||
},
|
||||
// 新增:鼠标离开处理
|
||||
handleMouseLeave() {
|
||||
if (this.isListening) {
|
||||
if (this.$refs.pasteArea) {
|
||||
this.$refs.pasteArea.blur();
|
||||
}
|
||||
this.isListening = false;
|
||||
}
|
||||
},
|
||||
// 粘贴图片上传
|
||||
handlePaste(event) {
|
||||
// 阻止默认行为
|
||||
event.preventDefault();
|
||||
|
||||
const items = event.clipboardData?.items;
|
||||
|
||||
if (!items) {
|
||||
this.$modal.msgError('当前浏览器不支持粘贴上传');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isImg) {
|
||||
this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join("/")}图片格式文件!`);
|
||||
let file = null;
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i].type.indexOf('image') !== -1) {
|
||||
file = items[i].getAsFile();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!file) {
|
||||
this.$modal.msgError('粘贴内容中不包含图片');
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否超出数量限制
|
||||
if (this.fileList.length >= this.limit) {
|
||||
this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
|
||||
return;
|
||||
}
|
||||
|
||||
this.uploadFile(file);
|
||||
},
|
||||
// 手动上传文件
|
||||
async uploadFile(file) {
|
||||
// 使用 handleBeforeUpload 进行文件验证
|
||||
const valid = await this.handleBeforeUpload(file);
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 构建formData对象
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
if (this.host === 'qiniu') {
|
||||
formData.append('key', this.uploadData.key);
|
||||
formData.append('token', this.uploadData.token);
|
||||
}
|
||||
|
||||
// 发起上传请求
|
||||
try {
|
||||
const response = await axios.post(this.uploadImgUrl, formData, {
|
||||
headers: {
|
||||
...this.headers,
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
});
|
||||
|
||||
this.handleUploadSuccess(response.data, file);
|
||||
} catch (error) {
|
||||
this.handleUploadError();
|
||||
} finally {
|
||||
this.$modal.closeLoading();
|
||||
}
|
||||
},
|
||||
// 上传前loading加载
|
||||
async handleBeforeUpload(file) {
|
||||
let isValid = false;
|
||||
let fileExtension = getExt(file.name);
|
||||
|
||||
// 检查是否为允许的文件类型
|
||||
isValid = this.fileType.some(type => {
|
||||
if (file.type.indexOf(type) > -1) return true;
|
||||
if (fileExtension && fileExtension === type.toLowerCase()) return true;
|
||||
return false;
|
||||
});
|
||||
|
||||
if (!isValid) {
|
||||
this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);
|
||||
return false;
|
||||
}
|
||||
if (this.fileSize) {
|
||||
const isLt = file.size / 1024 / 1024 < this.fileSize;
|
||||
if (!isLt) {
|
||||
this.$modal.msgError(`上传头像图片大小不能超过 ${this.fileSize} MB!`);
|
||||
this.$modal.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this.$modal.loading("正在上传图片,请稍候...");
|
||||
this.number++;
|
||||
this.$modal.loading("正在上传文件,请稍候...");
|
||||
|
||||
// 设置七牛云token
|
||||
if (this.host === 'qiniu') {
|
||||
let tokenRes = await getQiniuToken();
|
||||
console.log("tokenRes", tokenRes)
|
||||
if (tokenRes.code === 200) {
|
||||
this.uploadData.key = getFileNameWithTime(file.name);
|
||||
this.uploadData.token = tokenRes.token;
|
||||
this.domain = tokenRes.domain;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
// 文件个数超出
|
||||
handleExceed() {
|
||||
|
@ -163,49 +404,86 @@ export default {
|
|||
},
|
||||
// 上传成功回调
|
||||
handleUploadSuccess(res, file) {
|
||||
console.log("上传成功回调token:"+JSON.stringify(res));
|
||||
console.log("上传成功回调file:"+JSON.stringify(file));
|
||||
// if (res.code === 200) {
|
||||
this.uploadList.push({ name: res.hash, url: this.domain+"/"+res.hash });
|
||||
this.uploadedSuccessfully();
|
||||
// } else {
|
||||
// this.number--;
|
||||
// this.$modal.closeLoading();
|
||||
// this.$modal.msgError(res.msg);
|
||||
// this.$refs.imageUpload.handleRemove(file);
|
||||
// this.uploadedSuccessfully();
|
||||
// }
|
||||
if (this.host === 'qiniu') {
|
||||
// 七牛云返回的是文件信息
|
||||
this.uploadList.push({
|
||||
name: res.key,
|
||||
url: this.domain + '/' + res.key // 需要配置七牛云域名
|
||||
});
|
||||
this.uploadedSuccessfully();
|
||||
} else {
|
||||
if (res.code === 200) {
|
||||
this.uploadList.push({
|
||||
name: file.name, // 保持原始文件名
|
||||
url: res.fileName // 保持原始返回的URL
|
||||
});
|
||||
this.uploadedSuccessfully();
|
||||
} else {
|
||||
this.number--;
|
||||
this.$modal.closeLoading();
|
||||
this.$modal.msgError(res.msg);
|
||||
this.$refs.imageUpload.handleRemove(file);
|
||||
this.uploadedSuccessfully();
|
||||
}
|
||||
}
|
||||
},
|
||||
// 删除图片
|
||||
handleDelete(file) {
|
||||
const findex = this.fileList.map(f => f.name).indexOf(file.name);
|
||||
if(findex > -1) {
|
||||
if (findex > -1) {
|
||||
this.fileList.splice(findex, 1);
|
||||
this.$emit("input", this.listToString(this.fileList));
|
||||
this.emitInputValue();
|
||||
}
|
||||
},
|
||||
// 发送input事件
|
||||
emitInputValue() {
|
||||
// 若value是字符串,则将fileList转为字符串
|
||||
if (this.valueType === 'string') {
|
||||
this.$emit("input", this.listToString(this.fileList));
|
||||
}
|
||||
// 若value是字符串数组,则将fileList转为字符串数组
|
||||
else if (this.valueType === 'array-string') {
|
||||
this.$emit("input", this.fileList.map(f => f.url));
|
||||
}
|
||||
// 若value是对象数组,则直接返回
|
||||
else if (this.valueType === 'array-object') {
|
||||
this.$emit("input", this.fileList);
|
||||
}
|
||||
},
|
||||
// 上传失败
|
||||
handleUploadError() {
|
||||
this.$modal.msgError("上传图片失败,请重试");
|
||||
this.$modal.msgError("上传文件失败,请重试");
|
||||
this.$modal.closeLoading();
|
||||
},
|
||||
// 上传结束处理
|
||||
uploadedSuccessfully() {
|
||||
console.log("this.number:"+this.number);
|
||||
console.log("this.uploadList.length:"+this.uploadList.length);
|
||||
if (this.number > 0) {
|
||||
if (this.number > 0 && this.uploadList.length === this.number) {
|
||||
this.fileList = this.fileList.concat(this.uploadList);
|
||||
this.uploadList = [];
|
||||
this.number = 0;
|
||||
this.$emit("input", this.listToString(this.fileList));
|
||||
this.emitInputValue();
|
||||
this.$modal.closeLoading();
|
||||
}
|
||||
},
|
||||
// 预览
|
||||
handlePictureCardPreview(file) {
|
||||
console.log("预览:"+JSON.stringify(file));
|
||||
this.dialogImageUrl = file.url;
|
||||
this.dialogVisible = true;
|
||||
const fileUrl = file.url;
|
||||
if (!this.isImage(file.name) && !this.isVideo(file.name)) {
|
||||
this.downloadFile(file);
|
||||
} else {
|
||||
// 图片文件使用原有的预览方式
|
||||
this.dialogImageUrl = fileUrl;
|
||||
this.dialogVisible = true;
|
||||
}
|
||||
},
|
||||
// 新增:下载文件方法
|
||||
downloadFile(file) {
|
||||
const link = document.createElement('a');
|
||||
link.href = file.url;
|
||||
link.download = this.getDisplayFileName(file);
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
},
|
||||
// 对象转成指定字符串分隔
|
||||
listToString(list, separator) {
|
||||
|
@ -222,19 +500,155 @@ export default {
|
|||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
// .el-upload--picture-card 控制加号部分
|
||||
::v-deep.hide .el-upload--picture-card {
|
||||
display: none;
|
||||
}
|
||||
// 去掉动画效果
|
||||
::v-deep .el-list-enter-active,
|
||||
::v-deep .el-list-leave-active {
|
||||
transition: all 0s;
|
||||
/* 上传区域基础样式 */
|
||||
::v-deep .el-upload {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
::v-deep .el-list-enter, .el-list-leave-active {
|
||||
/* 上传按钮样式 */
|
||||
::v-deep .el-upload--picture-card {
|
||||
width: var(--width);
|
||||
height: var(--height);
|
||||
}
|
||||
|
||||
/* 隐藏上传按钮 */
|
||||
::v-deep.hide .el-upload--picture-card {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 已上传图片项样式 */
|
||||
::v-deep .el-upload-list__item {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: var(--width);
|
||||
height: var(--height);
|
||||
.el-upload-list__item-thumbnail {
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
}
|
||||
|
||||
&.is-file {
|
||||
.el-upload-list__item-thumbnail {
|
||||
padding: 20px;
|
||||
background-color: #f5f7fa;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.el-upload-list__item-actions {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.el-upload-list__item-actions {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
opacity: 0;
|
||||
transform: translateY(0);
|
||||
font-size: 20px;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
cursor: default;
|
||||
text-align: center;
|
||||
transition: opacity .3s;
|
||||
|
||||
.el-upload-list__item-delete {
|
||||
position: static;
|
||||
font-size: inherit;
|
||||
color: inherit;
|
||||
margin: 0 8px;
|
||||
}
|
||||
|
||||
.el-icon-delete {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.el-icon-zoom-in {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 拖拽上传区域样式 */
|
||||
::v-deep .el-upload-dragger {
|
||||
width: var(--width);
|
||||
height: var(--height);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 文件类型图标样式 */
|
||||
.file-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* 文件名容器样式 */
|
||||
.file-name-container {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
padding: 4px;
|
||||
text-align: center;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* 文件名样式 */
|
||||
.file-name {
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.edit-name {
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: #409EFF;
|
||||
}
|
||||
}
|
||||
|
||||
/* 调整列表动画时间 */
|
||||
::v-deep .el-list-enter-active {
|
||||
transition: all 0.1s;
|
||||
}
|
||||
|
||||
::v-deep .el-list-leave-active {
|
||||
transition: all 0.1s;
|
||||
}
|
||||
|
||||
/* 确保列表项立即靠左显示 */
|
||||
::v-deep .el-upload-list--picture-card {
|
||||
.el-upload-list__item {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* 粘贴区域样式 */
|
||||
.paste-area {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
z-index: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
19
AutoSprout-ui/src/utils/constants.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
// 文件类型
|
||||
export const FileType = {
|
||||
// 图片
|
||||
IMAGE: ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp', 'ico'],
|
||||
// 办公
|
||||
OFFICE: ['doc', 'docx', 'xls', 'xlsx', 'pdf', 'ppt', 'pptx'],
|
||||
// 音频
|
||||
AUDIO: ['mp3', 'wav', 'm4a', 'ogg', 'flac', 'aac'],
|
||||
// 视频
|
||||
VIDEO: ['mp4', 'avi', 'mov', 'wmv', 'flv', 'mpeg', 'mpg', 'm4v', 'webm', 'mkv'],
|
||||
// 压缩文件
|
||||
ZIP: ['zip', 'rar', '7z'],
|
||||
// 其他
|
||||
OTHER: ['exe'],
|
||||
// 全部
|
||||
all() {
|
||||
return [...this.IMAGE, ...this.OFFICE, ...this.AUDIO, ...this.VIDEO, ...this.OTHER, ...this.ZIP];
|
||||
}
|
||||
}
|
|
@ -1,16 +1,17 @@
|
|||
import { parseTime } from './ruoyi'
|
||||
import {FileType} from "@/utils/constants";
|
||||
|
||||
/**
|
||||
* 表格时间格式化
|
||||
*/
|
||||
export function formatDate(cellValue) {
|
||||
if (cellValue == null || cellValue == "") return "";
|
||||
var date = new Date(cellValue)
|
||||
var date = new Date(cellValue)
|
||||
var year = date.getFullYear()
|
||||
var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
|
||||
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
|
||||
var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
|
||||
var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
|
||||
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
|
||||
var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
|
||||
var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
|
||||
var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
|
||||
return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
|
||||
}
|
||||
|
@ -77,6 +78,64 @@ export function getQueryObject(url) {
|
|||
return obj
|
||||
}
|
||||
|
||||
// 获取真实url
|
||||
export function getRealUrl(url) {
|
||||
if (url == null ) {
|
||||
return url;
|
||||
}
|
||||
if (url.startsWith('http')) {
|
||||
return url;
|
||||
}
|
||||
return `${process.env.VUE_APP_BASE_API}${url}`;
|
||||
}
|
||||
|
||||
// 获取文件图标
|
||||
export function getFileIcon(fileName) {
|
||||
const ext = getExt(fileName);
|
||||
if(['doc', 'docx'].includes(ext)) {
|
||||
return require('@/assets/fileicons/word.png');
|
||||
} else if(['xls', 'xlsx'].includes(ext)) {
|
||||
return require('@/assets/fileicons/excel.png');
|
||||
} else if(['ppt', 'pptx'].includes(ext)) {
|
||||
return require('@/assets/fileicons/ppt.png');
|
||||
} else if(ext === 'pdf') {
|
||||
return require('@/assets/fileicons/pdf.png');
|
||||
} else if(FileType.VIDEO.includes(ext)) {
|
||||
return require('@/assets/fileicons/video.png');
|
||||
} else if(FileType.ZIP.includes(ext)) {
|
||||
return require('@/assets/fileicons/zip.png');
|
||||
}
|
||||
return require('@/assets/fileicons/unknown.png');
|
||||
}
|
||||
|
||||
// 获取文件扩展名
|
||||
export function getExt(fileName) {
|
||||
let fileExtension = '';
|
||||
if (fileName.lastIndexOf(".") > -1) {
|
||||
fileExtension = fileName.slice(fileName.lastIndexOf(".") + 1).toLowerCase();
|
||||
}
|
||||
return fileExtension;
|
||||
}
|
||||
|
||||
// 是否为图片
|
||||
export function isImage(url) {
|
||||
const ext = getExt(url);
|
||||
return FileType.IMAGE.includes(ext);
|
||||
}
|
||||
|
||||
// 是否为视频
|
||||
export function isVideo(url) {
|
||||
const ext = getExt(url);
|
||||
return FileType.VIDEO.includes(ext);
|
||||
}
|
||||
|
||||
// 为文件名在后缀和名称之间拼接时间戳
|
||||
export function getFileNameWithTime(fileName) {
|
||||
const ext = getExt(fileName);
|
||||
const name = fileName.slice(0, fileName.lastIndexOf("."));
|
||||
return `${name}-${Date.now()}.${ext}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input value
|
||||
* @returns {number} output value
|
||||
|
@ -330,7 +389,7 @@ export function makeMap(str, expectsLowerCase) {
|
|||
? val => map[val.toLowerCase()]
|
||||
: val => map[val]
|
||||
}
|
||||
|
||||
|
||||
export const exportDefault = 'export default '
|
||||
|
||||
export const beautifierConf = {
|
||||
|
@ -387,4 +446,4 @@ export function camelCase(str) {
|
|||
export function isNumberStr(str) {
|
||||
return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@
|
|||
<el-table-column label="id" align="center" prop="modelId" />
|
||||
<el-table-column label="名称" align="center" prop="modelName" />
|
||||
<el-table-column label="型号" align="center" prop="model" />
|
||||
<el-table-column label="固件版本" align="center" prop="version" />
|
||||
<el-table-column label="最新固件" align="center" prop="version" />
|
||||
<el-table-column label="图片" align="center" prop="picture" width="100">
|
||||
<template slot-scope="scope">
|
||||
<image-preview :src="scope.row.picture" :width="50" :height="50"/>
|
||||
|
@ -144,6 +144,9 @@
|
|||
<el-form-item label="型号" prop="model">
|
||||
<el-input v-model="form.model" placeholder="请输入型号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="型号前缀" prop="pre">
|
||||
<el-input v-model="form.pre" type="textarea" placeholder="请输入型号前缀,多个前缀用逗号分隔" />
|
||||
</el-form-item>
|
||||
<el-form-item label="分类" prop="classifyId">
|
||||
<el-select v-model="form.classifyId" filterable clearable placeholder="请选择" >
|
||||
<el-option
|
||||
|
@ -154,6 +157,7 @@
|
|||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<!-- <el-form-item label="版本" prop="versionId">-->
|
||||
<!-- <el-select v-model="form.versionId" filterable clearable placeholder="请绑定固件后再选择版本" >-->
|
||||
<!-- <el-option-->
|
||||
|
@ -164,11 +168,29 @@
|
|||
<!-- </el-option>-->
|
||||
<!-- </el-select>-->
|
||||
<!-- </el-form-item>-->
|
||||
<el-form-item label="图片" prop="picture">
|
||||
<image-upload v-model="form.picture"/>
|
||||
<el-form-item label="型号说明" prop="articleId">
|
||||
<el-select v-model="form.articleId" clearable placeholder="请选择" >
|
||||
<el-option
|
||||
v-for="item in articleOptions"
|
||||
:key="item.articleId"
|
||||
:label="item.title"
|
||||
:value="item.articleId">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="型号前缀" prop="pre">
|
||||
<el-input v-model="form.pre" type="textarea" placeholder="请输入型号前缀,多个前缀用逗号分隔" />
|
||||
<el-form-item label="图片" prop="picture">
|
||||
<image-upload
|
||||
v-model="form.picture"
|
||||
upload-type="image"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="介绍视频" prop="video">
|
||||
<image-upload
|
||||
v-model="form.video"
|
||||
upload-type="video"
|
||||
:file-size="1024"
|
||||
:file-type="['mp4','avi','mov','wmv','flv','mkv', 'png']"
|
||||
/>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="S/N" prop="idCode">-->
|
||||
<!-- <el-input v-model="form.idCode" placeholder="请输入S/N" />-->
|
||||
|
@ -192,6 +214,7 @@
|
|||
import { listModel, getModel, delModel, addModel, updateModel } from "@/api/device/model";
|
||||
import {listClassify} from "@/api/device/classify";
|
||||
import {listVersion} from "@/api/device/version";
|
||||
import {listArticle} from "@/api/system/article";
|
||||
|
||||
export default {
|
||||
name: "Model",
|
||||
|
@ -201,6 +224,8 @@ export default {
|
|||
classifyOptions: [],
|
||||
//版本列表
|
||||
versionOptions: [],
|
||||
//说明列表
|
||||
articleOptions: [],
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
// 选中数组
|
||||
|
@ -226,6 +251,7 @@ export default {
|
|||
modelName: null,
|
||||
model: null,
|
||||
picture: null,
|
||||
video:null,
|
||||
idCode: null,
|
||||
classifyName: null,
|
||||
versionId: null,
|
||||
|
@ -288,6 +314,11 @@ export default {
|
|||
this.loading = false;
|
||||
});
|
||||
});
|
||||
// 说明分类id,设备只查看说明分类下的文章
|
||||
listArticle({classifyId:103}).then(response => {
|
||||
this.articleOptions = response.rows;
|
||||
this.loading = true;
|
||||
});
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
|
@ -300,6 +331,7 @@ export default {
|
|||
modelId: null,
|
||||
classifyId: null,
|
||||
modelName: null,
|
||||
articleId: null,
|
||||
model: null,
|
||||
picture: null,
|
||||
idCode: null,
|
||||
|
|
|
@ -25,6 +25,9 @@ public class AsModel extends BaseEntity
|
|||
/** 分类ID */
|
||||
private Long classifyId;
|
||||
|
||||
@Excel(name = "文章id")
|
||||
private String articleId;
|
||||
|
||||
/** 名称 */
|
||||
@Excel(name = "名称")
|
||||
private String modelName;
|
||||
|
@ -73,4 +76,7 @@ public class AsModel extends BaseEntity
|
|||
@Excel(name = "固件版本号")
|
||||
private String version;
|
||||
|
||||
@Excel(name = "介绍视频")
|
||||
private String video;
|
||||
|
||||
}
|
||||
|
|
|
@ -80,4 +80,5 @@ public interface AsModelMapper extends BaseMapper<AsModel>
|
|||
public AsModel checkModelUnique(String model);
|
||||
|
||||
public AsModelVO checkModelByPre(AsModel asModel);
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
package com.ruoyi.device.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.ruoyi.device.domain.AsModel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 型号列表Mapper接口
|
||||
*
|
||||
* @author qiuzhenzhao
|
||||
* @date 2023-11-11
|
||||
*/
|
||||
public interface AsModelVideoMapper extends BaseMapper<AsModel>
|
||||
{
|
||||
/**
|
||||
* 查询型号列表
|
||||
*
|
||||
* @param id 型号列表主键
|
||||
* @return 型号列表
|
||||
*/
|
||||
public AsModel selectAsModeVideolById(Long id);
|
||||
|
||||
|
||||
/**
|
||||
* 新增型号列表
|
||||
*
|
||||
* @param asModel 型号列表
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertAsModelVideo(AsModel asModel);
|
||||
|
||||
/**
|
||||
* 修改型号列表
|
||||
*
|
||||
* @param asModel 型号列表
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateAsModelVideo(AsModel asModel);
|
||||
|
||||
/**
|
||||
* 删除型号列表
|
||||
*
|
||||
* @param modelId 型号列表主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteAsModelVideoByModelId(Long modelId);
|
||||
|
||||
/**
|
||||
* 批量删除型号列表
|
||||
*
|
||||
* @param modelIds 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteAsModelVideoByModelIds(Long[] modelIds);
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -42,7 +42,7 @@ public interface IAsModelService
|
|||
* @param asModel 型号列表
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertAsModel(AsModel asModel);
|
||||
public Boolean insertAsModel(AsModel asModel);
|
||||
|
||||
/**
|
||||
* 修改型号列表
|
||||
|
|
|
@ -511,9 +511,19 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
|
|||
asDevice.setDeviceName(defaultName);
|
||||
int i = bandSn(asDevice);
|
||||
ServiceUtil.assertion(i == 0, "录入失败!");
|
||||
|
||||
AsDevice device = setDeviceValue(asDevice);
|
||||
i = asDeviceMapper.insertAsDevice(device);
|
||||
ServiceUtil.assertion(i == 0, "绑定失败!");
|
||||
AsDevice vo = asDeviceMapper.selectAsDeviceByMac(asDevice.getMac());
|
||||
if (vo != null) {
|
||||
if (vo.getUserId().equals(0L)){
|
||||
device.setDeviceId(vo.getDeviceId());
|
||||
i = asDeviceMapper.updateAsDevice(device);
|
||||
}
|
||||
}
|
||||
else {
|
||||
i = asDeviceMapper.insertAsDevice(device);
|
||||
}
|
||||
ServiceUtil.assertion(i == 0, "绑定失败!");
|
||||
// 切换默认设备
|
||||
// toggleDevice(asDevice.getUserId(), asDevice.getDeviceId());
|
||||
logger.info("=================【绑定设备】成功==================");
|
||||
|
@ -665,7 +675,9 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
|
|||
public int bandSn(AsDevice asDevice) {
|
||||
AsDevice device = asDeviceMapper.selectAsDeviceByMac(asDevice.getMac());
|
||||
if(ObjectUtils.isNotEmpty(device)){
|
||||
throw new ServiceException("该MAC号已经存在");
|
||||
if(!device.getUserId().equals(0L)){
|
||||
throw new ServiceException("该设备已经被绑定");
|
||||
}
|
||||
}else{
|
||||
// 调用onenet接口
|
||||
CreateDeviceVo createDeviceVo = new CreateDeviceVo();
|
||||
|
@ -681,6 +693,7 @@ public class AsDeviceServiceImpl extends ServiceImpl<AsDeviceMapper, AsDevice> i
|
|||
throw new ServiceException(code+"-----"+ paramsObj.getString("msg"));
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,20 +9,21 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.ruoyi.common.constant.UserConstants;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.utils.DateUtils;
|
||||
import com.ruoyi.common.utils.ServiceUtil;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.device.domain.*;
|
||||
import com.ruoyi.device.domain.vo.AsModelVO;
|
||||
import com.ruoyi.device.mapper.AsDeviceClassifyMapper;
|
||||
import com.ruoyi.device.mapper.AsDeviceMapper;
|
||||
import com.ruoyi.device.mapper.AsDeviceVersionMapper;
|
||||
import com.ruoyi.device.mapper.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.ruoyi.device.mapper.AsModelMapper;
|
||||
import com.ruoyi.device.service.IAsModelService;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.annotation.Tainted;
|
||||
|
||||
/**
|
||||
* 型号列表Service业务层处理
|
||||
|
@ -44,6 +45,10 @@ public class AsModelServiceImpl extends ServiceImpl<AsModelMapper, AsModel> impl
|
|||
|
||||
@Resource
|
||||
private AsDeviceVersionMapper versionMapper;
|
||||
@Autowired
|
||||
private TransactionTemplate transactionTemplate;
|
||||
@Autowired
|
||||
private AsModelVideoMapper asModelVideoMapper;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -114,12 +119,26 @@ public class AsModelServiceImpl extends ServiceImpl<AsModelMapper, AsModel> impl
|
|||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertAsModel(AsModel asModel)
|
||||
public Boolean insertAsModel(AsModel asModel)
|
||||
{
|
||||
asModel.setCreateTime(DateUtils.getNowDate());
|
||||
AsDeviceClassify deviceClassify = classifyMapper.selectAsDeviceClassifyByClassifyId(asModel.getClassifyId());
|
||||
asModel.setClassifyName(deviceClassify.getClassifyName());
|
||||
return asModelMapper.insertAsModel(asModel);
|
||||
|
||||
Boolean execute = transactionTemplate.execute(e -> {
|
||||
// 插入型号数据
|
||||
int i = asModelMapper.insertAsModel(asModel);
|
||||
ServiceUtil.assertion(i == 0, "绑定失败!");
|
||||
// 构建型号 - 介绍视频表
|
||||
AsModel model = new AsModel();
|
||||
model.setModelId(asModel.getModelId());
|
||||
model.setVideo(asModel.getVideo());
|
||||
i = asModelVideoMapper.insertAsModelVideo(model);
|
||||
ServiceUtil.assertion(i == 0, "绑定失败!");
|
||||
return Boolean.TRUE;
|
||||
});
|
||||
if(Boolean.FALSE.equals(execute))throw new ServiceException("绑定失败");
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -136,6 +155,7 @@ public class AsModelServiceImpl extends ServiceImpl<AsModelMapper, AsModel> impl
|
|||
String classifyName = deviceClassify.getClassifyName();
|
||||
asModel.setClassifyName(classifyName);
|
||||
int i = asModelMapper.updateAsModel(asModel);
|
||||
asModelVideoMapper.updateAsModelVideo(asModel);
|
||||
AsDeviceQuery device = new AsDeviceQuery();
|
||||
device.setModelId(asModel.getModelId());
|
||||
List<AsDevice> asDevices = deviceMapper.selectAsDeviceList(device);
|
||||
|
@ -153,8 +173,12 @@ public class AsModelServiceImpl extends ServiceImpl<AsModelMapper, AsModel> impl
|
|||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public int deleteAsModelByModelIds(Long[] modelIds)
|
||||
{
|
||||
for (Long modelId : modelIds) {
|
||||
asModelVideoMapper.deleteAsModelVideoByModelId(modelId);
|
||||
}
|
||||
return asModelMapper.deleteAsModelByModelIds(modelIds);
|
||||
}
|
||||
|
||||
|
@ -165,8 +189,10 @@ public class AsModelServiceImpl extends ServiceImpl<AsModelMapper, AsModel> impl
|
|||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
|
||||
public int deleteAsModelByModelId(Long modelId)
|
||||
{
|
||||
|
||||
return asModelMapper.deleteAsModelByModelId(modelId);
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="modelId != null">model_id,</if>
|
||||
<if test="version != null">version,</if>
|
||||
<if test="createBy != null">create_by,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="createLocalDateTime != null">create_time,</if>
|
||||
<if test="updateBy != null">update_by,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
<if test="size != null">size,</if>
|
||||
|
@ -92,7 +92,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="modelId != null">#{modelId},</if>
|
||||
<if test="version != null">#{version},</if>
|
||||
<if test="createBy != null">#{createBy},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="createLocalDateTime != null">#{createLocalDateTime},</if>
|
||||
<if test="updateBy != null">#{updateBy},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
<if test="size != null">#{size},</if>
|
||||
|
|
|
@ -26,6 +26,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
am.model_id,
|
||||
am.classify_id,
|
||||
am.model_name,
|
||||
am.article_id,
|
||||
am.model,
|
||||
am.picture,
|
||||
am.id_code,
|
||||
|
@ -38,9 +39,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
am.update_time,
|
||||
am.pre,
|
||||
am.remark,
|
||||
adv.version
|
||||
adv.version,
|
||||
amv.video,
|
||||
aa.title
|
||||
from as_model am
|
||||
left join as_device_version adv on am.version_id = adv.version_id
|
||||
left join as_model_video amv on am.model_id = amv.model_id
|
||||
left join as_article aa on am.article_id = aa.article_id
|
||||
</sql>
|
||||
|
||||
<select id="selectAsModelList" parameterType="AsModel" resultMap="AsModelResult">
|
||||
|
@ -53,7 +58,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="classifyName != null and classifyName != ''"> and am.classify_name like concat('%', #{classifyName}, '%')</if>
|
||||
<if test="versionId != null "> and am.version_id = #{versionId}</if>
|
||||
<if test="introduce != null and introduce != ''"> and am.introduce = #{introduce}</if>
|
||||
<if test="pre != null and introduce != ''"> and am.pre = #{pre}</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
|
@ -83,6 +87,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
insert into as_model
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="classifyId != null">classify_id,</if>
|
||||
<if test="articleId != null">article_id,</if>
|
||||
<if test="modelName != null">model_name,</if>
|
||||
<if test="model != null">model,</if>
|
||||
<if test="picture != null">picture,</if>
|
||||
|
@ -99,6 +104,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="classifyId != null">#{classifyId},</if>
|
||||
<if test="articleId != null">#{articleId},</if>
|
||||
<if test="modelName != null">#{modelName},</if>
|
||||
<if test="model != null">#{model},</if>
|
||||
<if test="picture != null">#{picture},</if>
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.device.mapper.AsModelVideoMapper">
|
||||
|
||||
<resultMap type="AsModel" id="AsModelResult">
|
||||
<result property="modelId" column="model_id" />
|
||||
<result property="video" column="video" />
|
||||
</resultMap>
|
||||
|
||||
<select id="selectAsModeVideolById" resultType="AsModel">
|
||||
select
|
||||
amv.model_id,
|
||||
amv.video
|
||||
from as_model_video amv
|
||||
where amv.id = #{id}
|
||||
</select>
|
||||
|
||||
<insert id="insertAsModelVideo">
|
||||
insert into as_model_video
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="modelId !=null">model_id,</if>
|
||||
<if test="video !=null">video,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="modelId !=null">#{modelId},</if>
|
||||
<if test="video !=null">#{video},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="updateAsModelVideo" parameterType="AsModel">
|
||||
update as_model_video
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="modelId != null">model_id = #{modelId},</if>
|
||||
<if test="video != null">video = #{video},</if>
|
||||
</trim>
|
||||
where model_id = #{modelId}
|
||||
</update>
|
||||
|
||||
<delete id="deleteAsModelVideoByModelId" parameterType="Long">
|
||||
delete from as_model_video where model_id = #{modelId}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteAsModelVideoByModelIds" parameterType="String">
|
||||
delete from as_model_video where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||
#{modelId}
|
||||
</foreach>
|
||||
</delete>
|
||||
</mapper>
|