@@ -48,23 +48,6 @@ | |||
:placeholder="`请选择${col.label}`" | |||
value-format="timestamp" | |||
v-bind="col.bind"></el-date-picker> | |||
<el-upload | |||
class="upload-in-dialog" | |||
v-if="col.upload" | |||
:file-list="uploadedFileList" | |||
:action="col.url" | |||
:on-success="handleUploadSuccess" | |||
v-bind="col.bind"> | |||
<el-button | |||
size="small" | |||
type="primary" | |||
:disabled="col.bind?.disabled || false"> | |||
点击上传 | |||
</el-button> | |||
<div class="el-upload__tip" slot="tip" v-if="col.uploadTips"> | |||
{{ col.uploadTips || '只能上传jpg/png文件,大小不超过2MB' }} | |||
</div> | |||
</el-upload> | |||
<el-switch | |||
v-if="col.switch" | |||
v-model="form[col.prop]" | |||
@@ -76,6 +59,43 @@ | |||
:key="col.key" | |||
:is="col.subcomponent" | |||
:inlineStyle="col.style"></component> | |||
<div | |||
class="upload-area" | |||
:class="uploadOpen ? '' : 'height-48'" | |||
ref="uploadArea" | |||
v-if="col.upload"> | |||
<span class="close-icon" :class="uploadOpen ? 'open' : ''"> | |||
<el-button | |||
type="text" | |||
icon="el-icon-arrow-right" | |||
@click="handleFilesOpen" /> | |||
</span> | |||
<!-- :file-list="uploadedFileList" --> | |||
<el-upload | |||
class="upload-in-dialog" | |||
v-if="col.upload" | |||
:action="uploadUrl" | |||
:headers="uploadHeaders" | |||
:show-file-list="false" | |||
icon="el-icon-upload2" | |||
:before-upload="beforeUpload" | |||
:on-success="handleUploadSuccess" | |||
v-bind="col.bind"> | |||
<el-button size="mini" :disabled="col.bind?.disabled || false"> | |||
上传文件 | |||
</el-button> | |||
<div class="el-upload__tip" slot="tip" v-if="col.uploadTips"> | |||
{{ col.uploadTips || '只能上传jpg/png文件, 大小不超过2MB' }} | |||
</div> | |||
</el-upload> | |||
<uploadedFile | |||
class="file" | |||
v-for="file in form[col.prop] || []" | |||
:file="file" | |||
@delete="handleDeleteFile(file)" /> | |||
</div> | |||
</el-form-item> | |||
</el-col> | |||
</el-row> | |||
@@ -83,6 +103,9 @@ | |||
</template> | |||
<script> | |||
import { getAccessToken } from '@/utils/auth'; | |||
import tupleImg from '@/assets/images/tuple.png'; | |||
/** | |||
* 找到最长的label | |||
* @param {*} options | |||
@@ -101,6 +124,48 @@ function findMaxLabelWidth(rows) { | |||
return max; | |||
} | |||
const uploadedFile = { | |||
name: 'UploadedFile', | |||
props: ['file'], | |||
data() { | |||
return {}; | |||
}, | |||
methods: { | |||
handleDelete() { | |||
console.log('emit delete event') | |||
this.$emit('delete', this.file); | |||
}, | |||
}, | |||
mounted() {}, | |||
render: function (h) { | |||
return ( | |||
<div | |||
title={this.file.fileName} | |||
style={{ | |||
background: `url(${tupleImg}) no-repeat`, | |||
backgroundSize: '14px', | |||
backgroundPosition: '0 55%', | |||
paddingLeft: '20px', | |||
paddingRight: '24px', | |||
textOverflow: 'ellipsis', | |||
whiteSpace: 'nowrap', | |||
overflow: 'hidden', | |||
cursor: 'pointer', | |||
display: 'inline-block', | |||
}}> | |||
{this.file.fileName} | |||
<el-button | |||
type="text" | |||
icon="el-icon-close" | |||
style="float: right; position: relative; top: 2px; left: 8px; z-index: 100" | |||
class="dialog__upload_component__close" | |||
onClick={this.handleDelete} | |||
/> | |||
</div> | |||
); | |||
}, | |||
}; | |||
export default { | |||
name: 'DialogForm', | |||
model: { | |||
@@ -108,7 +173,7 @@ export default { | |||
event: 'update', | |||
}, | |||
emits: ['update'], | |||
components: {}, | |||
components: { uploadedFile }, | |||
props: { | |||
rows: { | |||
type: Array, | |||
@@ -133,10 +198,14 @@ export default { | |||
}, | |||
data() { | |||
return { | |||
uploadOpen: false, | |||
form: {}, | |||
formLoading: true, | |||
optionListOf: {}, | |||
uploadedFileList: [], | |||
dataLoaded: false, | |||
uploadHeaders: { Authorization: 'Bearer ' + getAccessToken() }, | |||
uploadUrl: process.env.VUE_APP_BASE_API + '/admin-api/infra/file/upload', // 上传有关的headers,url都是固定的 | |||
}; | |||
}, | |||
computed: { | |||
@@ -146,16 +215,6 @@ export default { | |||
return max * 20; | |||
// return max * 20 + 'px'; | |||
}, | |||
form: { | |||
get() { | |||
// if (this.dataLoaded) return this.dataForm; | |||
// else return {} | |||
return this.dataForm; | |||
}, | |||
set(val) { | |||
console.log('set form', val); | |||
}, | |||
}, | |||
}, | |||
watch: { | |||
rows: { | |||
@@ -168,6 +227,13 @@ export default { | |||
deep: true, | |||
immediate: false, | |||
}, | |||
dataForm: { | |||
handler(val) { | |||
this.form = JSON.parse(JSON.stringify(val)); | |||
}, | |||
deep: true, | |||
immediate: true, | |||
}, | |||
}, | |||
mounted() { | |||
// 处理 options | |||
@@ -283,23 +349,27 @@ export default { | |||
beforeUpload() {}, | |||
// 上传前的验证规则可通过 bind 属性传入 | |||
handleUploadSuccess(response, file, fileList) { | |||
console.log( | |||
'[dialogForm:handleUploadSuccess]', | |||
response, | |||
file, | |||
fileList, | |||
this.form | |||
); | |||
// 保存原始文件名 | |||
if ('fileNames' in this.form) this.form.fileNames.push(file.name); | |||
// 保存完整地址 | |||
if ('fileUrls' in this.form) this.form.fileUrls.push(response.data); | |||
this.form.files.push({ | |||
fileName: file.name, | |||
fileUrl: response.data, | |||
fileType: 2, | |||
}); | |||
this.$modal.msgSuccess('上传成功'); | |||
this.$emit('update', this.form); | |||
}, | |||
getFileName(fileUrl) { | |||
return fileUrl.split('/').pop(); | |||
}, | |||
handleFilesOpen() { | |||
this.uploadOpen = !this.uploadOpen; | |||
}, | |||
handleDeleteFile(file) { | |||
this.form.files = this.form.files.filter(item => item.fileUrl != file.fileUrl); | |||
this.$emit('update', this.form); | |||
}, | |||
}, | |||
}; | |||
</script> | |||
@@ -309,4 +379,52 @@ export default { | |||
.el-select { | |||
width: 100%; | |||
} | |||
.upload-area { | |||
// background: #ccc; | |||
// display: grid; | |||
// grid-auto-rows: 34px; | |||
// grid-template-columns: repeat(6, minmax(32px, max-content)); | |||
// gap: 8px; | |||
// align-items: center; | |||
position: relative; | |||
overflow: hidden; | |||
transition: height 0.3s ease-out; | |||
} | |||
.upload-in-dialog { | |||
// display: inline-block; | |||
margin-right: 24px; | |||
// background: #ccc; | |||
position: relative; | |||
// top: -13px; | |||
float: left; | |||
} | |||
.close-icon { | |||
// background: #ccc; | |||
position: absolute; | |||
top: 0; | |||
right: 12px; | |||
z-index: 100; | |||
transition: transform 0.3s ease-out; | |||
} | |||
.close-icon.open { | |||
transform: rotateZ(90deg); | |||
} | |||
</style> | |||
<style> | |||
.dialog__upload_component__close { | |||
color: #ccc; | |||
} | |||
.dialog__upload_component__close:hover { | |||
/* color: #777; */ | |||
color: red; | |||
} | |||
.height-48 { | |||
height: 35px !important; | |||
} | |||
</style> |
@@ -13,21 +13,31 @@ | |||
<i class="el-icon-folder" v-else></i> | |||
展开 | |||
</el-button> | |||
<div class="preview-btn"> | |||
<!-- <div class="preview-btn"> | |||
<i class="el-icon-view"></i> | |||
预览 | |||
</div> | |||
</div> --> | |||
</section> | |||
<section class="file-area"> | |||
<el-upload class="equipment-upload" drag action="uploadUrl" multiple> | |||
<el-upload | |||
class="equipment-upload" | |||
:disabled="disabled" | |||
drag | |||
:action="uploadUrl" | |||
:headers="headers" | |||
multiple | |||
:show-file-list="false" | |||
:before-upload="beforeUpload" | |||
:on-success="handleSuccess"> | |||
<i class="el-icon-upload"></i> | |||
<div class="el-upload__text"> | |||
<span>将文件拖到此处或</span> | |||
<em>点击上传</em> | |||
</div> | |||
<div class="el-upload__tip" slot="tip"> | |||
<!-- 只能上传jpg/png文件,且不超过500kb --> | |||
some tips.... | |||
{{ | |||
isPicMode ? '仅支持上传 .jpg .png 格式文件, 且' : '' | |||
}}文件大小不超过2MB | |||
</div> | |||
</el-upload> | |||
<!-- <div | |||
@@ -47,23 +57,53 @@ | |||
:key="file.fileName" | |||
:style="{ | |||
display: index > 3 && !expand ? 'none' : 'block', | |||
background: isPicMode ? `url(${file.fileUrl}) no-repeat` : `url(${defaultBg}) no-repeat`, | |||
background: isPicMode | |||
? `url(${file.fileUrl}) no-repeat` | |||
: `url(${defaultBg}) no-repeat`, | |||
backgroundSize: isPicMode ? '100% 100%' : '64px', | |||
backgroundPosition: isPicMode ? '0% 0%' : 'center', | |||
}" | |||
:data-name="file.fileName"> | |||
<i class="el-icon-delete"></i> | |||
<el-button | |||
v-if="!disabled" | |||
type="text" | |||
class="el-icon-delete" | |||
style="padding: 0" | |||
@click="(e) => handleDelete(file)" /> | |||
</div> | |||
</section> | |||
</div> | |||
</template> | |||
<script> | |||
import { getAccessToken } from '@/utils/auth'; | |||
import defaultBg from '../../../../../assets/images/default-file-icon.png'; | |||
function checkSize(file, message) { | |||
const isLt2M = file.size / 1024 / 1024 < 2; | |||
if (!isLt2M) { | |||
message.error('上传文件大小不能超过 2MB!'); | |||
} | |||
return isLt2M; | |||
} | |||
function checkPic(file, message) { | |||
const isJPG = file.type === 'image/jpeg'; | |||
const isPNG = file.type === 'image/png'; | |||
const isPic = isJPG || isPNG; | |||
if (!isPic) { | |||
message.error('上传图片只能是 JPG/PNG 格式!'); | |||
} | |||
return isPic; | |||
} | |||
export default { | |||
name: 'AssetsUpload', | |||
components: {}, | |||
model: { | |||
prop: 'dataSource', | |||
event: 'update', | |||
}, | |||
props: { | |||
type: { | |||
type: String, | |||
@@ -81,70 +121,144 @@ export default { | |||
type: Boolean, | |||
default: false, | |||
}, | |||
disabled: { | |||
type: Boolean, | |||
default: false, | |||
}, | |||
}, | |||
emits: ['update-filelist'], | |||
data() { | |||
return { | |||
defaultBg, | |||
expand: false, | |||
headers: { Authorization: 'Bearer ' + getAccessToken() }, // 设置上传的请求头部 | |||
fileList: [], | |||
uploadUrl: process.env.VUE_APP_BASE_API + '/admin-api/infra/file/upload', | |||
files: [ | |||
// 服务器返回的结构 | |||
{ | |||
fileName: 'sf.docs', | |||
fileType: 'asset', | |||
fileUrl: | |||
'https://hbimg.b0.upaiyun.com/cc7475787bd08ed926b68eaf53fa1f2c5473259115e3c-gJdObd_fw658', | |||
}, | |||
{ | |||
fileName: 'sddf.docs', | |||
fileType: 'asset', | |||
fileUrl: 'https://img0.sc115.com/wm/xqx/pic1/1501xofo4ssolji.jpg', | |||
}, | |||
{ | |||
fileName: 'jjj.docs', | |||
fileType: 'asset', | |||
fileUrl: | |||
'https://www.mms591.com/www.mms591.com-photo/2013081823/1-130QR34544.jpg', | |||
}, | |||
{ | |||
fileName: 'asdfasdf.docs', | |||
fileType: 'asset', | |||
fileUrl: | |||
'https://hbimg.b0.upaiyun.com/8f6bced5f2e38d3a021b2c48d5a98dfb6317e3e12c6a0-QmhJ5v_fw658', | |||
}, | |||
{ | |||
fileName: 'asdkj.docs', | |||
fileType: 'asset', | |||
fileUrl: | |||
'https://www.mms591.com/www.mms591.com-photo/2013013021/1-130130212034.jpg', | |||
}, | |||
{ | |||
fileName: 'lkasjdf.docs', | |||
fileType: 'asset', | |||
fileUrl: | |||
'https://www.mms591.com/www.mms591.com-photo/2013072122/1-130H1223057.jpg', | |||
}, | |||
{ | |||
fileName: 'asdf.docs', | |||
fileType: 'asset', | |||
fileUrl: | |||
'https://img.1ppt.com/uploads/allimg/1212/1-1212101ZH5A2.jpg', | |||
}, | |||
{ | |||
fileName: 'afdffff.docs', | |||
fileType: 'asset', | |||
fileUrl: | |||
'https://www.mms591.com/www.mms591.com-photo/2013051721/1-13051H11945.jpg', | |||
}, | |||
// { | |||
// fileName: 'sf.docs', | |||
// fileType: 'asset', | |||
// fileUrl: | |||
// 'https://hbimg.b0.upaiyun.com/cc7475787bd08ed926b68eaf53fa1f2c5473259115e3c-gJdObd_fw658', | |||
// }, | |||
// { | |||
// fileName: 'sddf.docs', | |||
// fileType: 'asset', | |||
// fileUrl: 'https://img0.sc115.com/wm/xqx/pic1/1501xofo4ssolji.jpg', | |||
// }, | |||
// { | |||
// fileName: 'jjj.docs', | |||
// fileType: 'asset', | |||
// fileUrl: | |||
// 'https://www.mms591.com/www.mms591.com-photo/2013081823/1-130QR34544.jpg', | |||
// }, | |||
// { | |||
// fileName: 'asdfasdf.docs', | |||
// fileType: 'asset', | |||
// fileUrl: | |||
// 'https://hbimg.b0.upaiyun.com/8f6bced5f2e38d3a021b2c48d5a98dfb6317e3e12c6a0-QmhJ5v_fw658', | |||
// }, | |||
// { | |||
// fileName: 'asdkj.docs', | |||
// fileType: 'asset', | |||
// fileUrl: | |||
// 'https://www.mms591.com/www.mms591.com-photo/2013013021/1-130130212034.jpg', | |||
// }, | |||
// { | |||
// fileName: 'lkasjdf.docs', | |||
// fileType: 'asset', | |||
// fileUrl: | |||
// 'https://www.mms591.com/www.mms591.com-photo/2013072122/1-130H1223057.jpg', | |||
// }, | |||
// { | |||
// fileName: 'asdf.docs', | |||
// fileType: 'asset', | |||
// fileUrl: | |||
// 'https://img.1ppt.com/uploads/allimg/1212/1-1212101ZH5A2.jpg', | |||
// }, | |||
// { | |||
// fileName: 'afdffff.docs', | |||
// fileType: 'asset', | |||
// fileUrl: | |||
// 'https://www.mms591.com/www.mms591.com-photo/2013051721/1-13051H11945.jpg', | |||
// }, | |||
], | |||
updateTimer: null, | |||
}; | |||
}, | |||
computed: {}, | |||
mounted() { | |||
console.log('this.ispicmocde', this.isPicMode); | |||
watch: { | |||
dataSource: { | |||
handler(val) { | |||
this.files = JSON.parse(JSON.stringify(val)); | |||
}, | |||
immediate: true, | |||
deep: true, | |||
}, | |||
}, | |||
mounted() {}, | |||
methods: { | |||
// handle success, per file! | |||
handleSuccess(response, file, fileList) { | |||
this.$notify({ | |||
title: '成功', | |||
message: '上传成功! 点击确认保存上传结果', | |||
type: 'success', | |||
}); | |||
if ( | |||
response == null || | |||
!('data' in response) || | |||
response.data == null || | |||
response.data.trim() == '' | |||
) { | |||
this.$message.error('上传出错了!'); | |||
return; | |||
} | |||
this.files.push({ | |||
fileName: file.name, | |||
fileUrl: response.data, | |||
fileType: this.isPicMode ? 1 : 2, | |||
}); | |||
// debugger; | |||
// 延时更新 | |||
if (this.updateTimer) { | |||
clearTimeout(this.updateTimer); | |||
} | |||
this.updateTimer = setTimeout(() => { | |||
console.log('[AssetsUpload] 更新上传列表'); | |||
this.emitFilelist(); | |||
clearTimeout(this.updateTimer); | |||
this.updateTimer = null; | |||
}, 500); | |||
}, | |||
emitFilelist() { | |||
this.$emit('update', this.files); | |||
}, | |||
handleRemove(file, fileList) { | |||
debugger; | |||
}, | |||
handleDelete(file) { | |||
// fileName fileType 都可能一样,但 fileUrl 一定不一样 | |||
this.files = this.files.filter((item) => item.fileUrl != file.fileUrl); | |||
this.$notify({ | |||
title: '成功', | |||
message: '删除成功! 需点击确认保存删除结果', | |||
type: 'success', | |||
}); | |||
this.emitFilelist(); | |||
}, | |||
beforeUpload(file) { | |||
if (this.isPicMode) { | |||
return checkPic(file, this.$message) && checkSize(file, this.$message); | |||
} | |||
return checkSize(file, this.$message); | |||
}, | |||
handleUpload() { | |||
switch (this.type) { | |||
case 'image': | |||
@@ -223,6 +337,9 @@ export default { | |||
} | |||
.el-upload__tip { | |||
font-size: 12px; | |||
line-height: 1.5; | |||
color: #d1d1d1; | |||
margin: 0 0 12px; | |||
transform: translateY(-12px); | |||
user-select: none; | |||
@@ -281,9 +398,10 @@ export default { | |||
content: attr(data-name); | |||
position: absolute; | |||
left: 0; | |||
bottom: -16px; | |||
bottom: -26px; | |||
font-size: 14px; | |||
line-height: 1; | |||
line-height: 2; | |||
color: #616161; | |||
} | |||
.default-icon { | |||
@@ -29,15 +29,17 @@ | |||
<section v-for="(section, index) in sections" :key="section.key"> | |||
<SmallTitle v-if="index != 0">{{ section.name }}</SmallTitle> | |||
<div class="form-part" v-if="section.key == 'base'"> | |||
<div | |||
class="form-part" | |||
v-if="section.key == 'base'" | |||
style="margin-bottom: 32px"> | |||
<el-skeleton v-if="!showForm" animated /> | |||
<DialogForm | |||
<EquipmentInfoForm | |||
key="drawer-dialog-form" | |||
v-if="showForm" | |||
ref="form" | |||
label-position="top" | |||
:dataForm="form" | |||
:rows="formRows" /> | |||
:disabled="mode.includes('detail')" | |||
:sync-filelist="syncFileListFlag" | |||
v-model="form" /> | |||
</div> | |||
<div v-if="section.key == 'attrs'" style="margin-top: 12px"> | |||
@@ -74,7 +76,7 @@ | |||
<el-button v-if="mode == 'detail'" type="primary" @click="toggleEdit"> | |||
编辑 | |||
</el-button> | |||
<el-button v-else type="primary" @click="handleCancel">确定</el-button> | |||
<el-button v-else type="primary" @click="handleConfirm">确定</el-button> | |||
<!-- sections的第二项必须是 属性列表 --> | |||
<!-- <el-button | |||
v-if="sections[1].allowAdd" | |||
@@ -107,10 +109,12 @@ | |||
<script> | |||
import DialogForm from './DialogForm'; | |||
import EquipmentInfoForm from './EquipmentInfoForm.vue'; | |||
const SmallTitle = { | |||
name: 'SmallTitle', | |||
props: ['size'], | |||
components: {}, | |||
data() { | |||
return {}; | |||
}, | |||
@@ -134,12 +138,13 @@ const SmallTitle = { | |||
}; | |||
export default { | |||
components: { SmallTitle, DialogForm }, | |||
components: { SmallTitle, DialogForm, EquipmentInfoForm }, | |||
props: ['sections', 'mode', 'dataId'], // dataId 作为一个通用的存放id的字段 | |||
data() { | |||
return { | |||
visible: false, | |||
showForm: false, | |||
btnLoading: false, | |||
total: 0, | |||
form: {}, | |||
list: [], | |||
@@ -177,6 +182,7 @@ export default { | |||
infoQuery: null, // 基本信息的请求 | |||
attrFormSubmitting: false, | |||
attrListLoading: false, | |||
syncFileListFlag: null, | |||
}; | |||
}, | |||
computed: { | |||
@@ -188,7 +194,7 @@ export default { | |||
return { | |||
...col, | |||
bind: { | |||
...col.bind | |||
...col.bind, | |||
}, | |||
style: { | |||
left: 0, | |||
@@ -224,6 +230,50 @@ export default { | |||
this.$axios(query).then(({ data }) => { | |||
if (section.key == 'base') { | |||
this.form = data; | |||
// this.form = { | |||
// code: 'gj', | |||
// name: '下片机', | |||
// enName: 'unload', | |||
// abbr: '', | |||
// equipmentTypeId: 21084, | |||
// remark: '备注', | |||
// id: '1712367395052384257', | |||
// createTime: 1697095176000, | |||
// enterTime: 0, | |||
// productionTime: 0, | |||
// files: [ | |||
// { | |||
// fileName: '测试.xlsx', | |||
// fileUrl: 'https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2022%2F0108%2F0f0c6f30j00r5cle9000sc000hs00gtc.jpg&thumbnail=660x2147483647&quality=80&type=jpg', | |||
// fileType: 1 | |||
// }, | |||
// { | |||
// fileName: '测试2.xlsx', | |||
// fileUrl: 'https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2022%2F0415%2F2cd23619j00racb96000kc000hs00hsc.jpg&thumbnail=660x2147483647&quality=80&type=jpg', | |||
// fileType: 1 | |||
// }, | |||
// { | |||
// fileName: '测试3.xlsx', | |||
// fileUrl: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2F1fea91a0-d088-409e-b145-e0e61254b28b%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1700031689&t=2e0fe7d1de7f54adff3007efe133d67c', | |||
// fileType: 1 | |||
// }, | |||
// { | |||
// fileName: '测试4.xlsx', | |||
// fileUrl: 'https://pics5.baidu.com/feed/b7003af33a87e950cdfb4b4546eed044faf2b40d.jpeg?token=1d7484cfe4b014dd201f8c8725cab945', | |||
// fileType: 2 | |||
// }, | |||
// { | |||
// fileName: '测试5.xlsx', | |||
// fileUrl: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2Fe3500876-9c46-4b70-8d37-4799520cdd13%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1700031689&t=4abc1df930e62730e5361a7d3765e0f2', | |||
// fileType: 2 | |||
// }, | |||
// ], | |||
// tvalue: 0, | |||
// processingTime: 0, | |||
// manufacturer: '', | |||
// spec: '', | |||
// description: '描述', | |||
// }; | |||
this.showForm = true; | |||
this.infoQuery = query; | |||
} else if (section.key == 'attrs') { | |||
@@ -246,6 +296,24 @@ export default { | |||
break; | |||
} | |||
}, | |||
async handleConfirm() { | |||
this.btnLoading = true; | |||
this.syncFileListFlag = Math.random(); | |||
this.$nextTick(async () => { | |||
const { code, data } = await this.$axios({ | |||
url: this.sections[0].urlUpdate, | |||
method: 'put', | |||
data: this.form, | |||
}); | |||
if (code == 0) { | |||
this.$modal.msgSuccess('更新成功'); | |||
} | |||
this.btnLoading = false; | |||
this.handleCancel(); | |||
}); | |||
}, | |||
handleEmitFun(val) { | |||
console.log('handleEmitFun', val); | |||
@@ -288,7 +356,7 @@ export default { | |||
// 开启编辑 | |||
toggleEdit() { | |||
this.mode = 'edit'; | |||
this.$emit('update-mode', 'edit'); | |||
}, | |||
// 新增属性 | |||
@@ -0,0 +1,337 @@ | |||
<!-- | |||
filename: dialogForm.vue | |||
author: liubin | |||
date: 2023-08-15 10:32:36 | |||
description: 弹窗的表单组件 | |||
--> | |||
<template> | |||
<el-form | |||
class="equipment-info-form" | |||
ref="form" | |||
:model="form" | |||
label-width="200px" | |||
label-position="top" | |||
v-loading="formLoading"> | |||
<el-row :gutter="20"> | |||
<el-col :span="8"> | |||
<el-form-item | |||
label="设备名称" | |||
prop="name" | |||
:rules="[{ required: true, message: '不能为空', trigger: 'blur' }]"> | |||
<el-input | |||
v-model="form.name" | |||
:disabled="disabled" | |||
placeholder="请输入设备名称"></el-input> | |||
</el-form-item> | |||
</el-col> | |||
<el-col :span="8"> | |||
<el-form-item label="设备编码" prop="code" :rules="[]"> | |||
<el-input | |||
v-model="form.code" | |||
:disabled="disabled" | |||
placeholder="请输入设备编码"></el-input> | |||
</el-form-item> | |||
</el-col> | |||
<el-col :span="8"> | |||
<el-form-item label="英文名称" prop="enName" :rules="[]"> | |||
<el-input | |||
v-model="form.enName" | |||
:disabled="disabled" | |||
placeholder="请输入英文名称"></el-input> | |||
</el-form-item> | |||
</el-col> | |||
</el-row> | |||
<el-row :gutter="20"> | |||
<el-col :span="8"> | |||
<el-form-item label="缩写" prop="abbr" :rules="[]"> | |||
<el-input | |||
v-model="form.abbr" | |||
:disabled="disabled" | |||
placeholder="请输入名称缩写"></el-input> | |||
</el-form-item> | |||
</el-col> | |||
<el-col :span="8"> | |||
<el-form-item label="设备类型" prop="equipmentTypeId" :rules="[]"> | |||
<el-select | |||
v-model="form.equipmentTypeId" | |||
:disabled="disabled" | |||
filterable | |||
placeholder="请选择设备类型"> | |||
<el-option | |||
v-for="eqType in eqTypeList" | |||
:key="eqType.id" | |||
:label="eqType.name" | |||
:value="eqType.id"></el-option> | |||
</el-select> | |||
</el-form-item> | |||
</el-col> | |||
<el-col :span="8"> | |||
<el-form-item label="备注" prop="remark" :rules="[]"> | |||
<el-input | |||
v-model="form.remark" | |||
:disabled="disabled" | |||
placeholder="请输入备注"></el-input> | |||
</el-form-item> | |||
</el-col> | |||
</el-row> | |||
<el-row :gutter="20"> | |||
<el-col :span="8"> | |||
<el-form-item label="生产日期" prop="productionTime" :rules="[]"> | |||
<el-date-picker | |||
v-model="form.enterTime" | |||
:disabled="disabled" | |||
type="datetime" | |||
placeholder="请选择生产日期" | |||
value-format="timestamp"></el-date-picker> | |||
</el-form-item> | |||
</el-col> | |||
<el-col :span="8"> | |||
<el-form-item label="进场日期" prop="enterTime" :rules="[]"> | |||
<el-date-picker | |||
v-model="form.enterTime" | |||
:disabled="disabled" | |||
type="datetime" | |||
placeholder="请选择进场日期" | |||
value-format="timestamp"></el-date-picker> | |||
</el-form-item> | |||
</el-col> | |||
<el-col :span="8"> | |||
<el-form-item | |||
label="设备TT值" | |||
prop="tvalue" | |||
:rules="[ | |||
{ required: true, message: '不能为空', trigger: 'blur' }, | |||
{ | |||
type: 'number', | |||
message: '请输入正确的数字值', | |||
trigger: 'blur', | |||
transform: (val) => Number(val), | |||
}, | |||
]"> | |||
<el-input | |||
v-model="form.tvalue" | |||
:disabled="disabled" | |||
placeholder="请输入设备TT值"></el-input> | |||
</el-form-item> | |||
</el-col> | |||
</el-row> | |||
<el-row :gutter="20"> | |||
<el-col :span="8"> | |||
<el-form-item | |||
label="产品加工时间(s)" | |||
prop="processingTime" | |||
:rules="[ | |||
{ required: true, message: '不能为空', trigger: 'blur' }, | |||
{ | |||
type: 'number', | |||
message: '请输入正确的数字值', | |||
trigger: 'blur', | |||
transform: (val) => Number(val), | |||
}, | |||
]"> | |||
<el-input | |||
v-model="form.processingTime" | |||
:disabled="disabled" | |||
placeholder="请输入产品加工时间"></el-input> | |||
</el-form-item> | |||
</el-col> | |||
<el-col :span="8"> | |||
<el-form-item label="制造商" prop="manufacturer" :rules="[]"> | |||
<el-input | |||
v-model="form.manufacturer" | |||
:disabled="disabled" | |||
placeholder="请输入制造商"></el-input> | |||
</el-form-item> | |||
</el-col> | |||
<el-col :span="8"> | |||
<el-form-item label="设备规格" prop="spec" :rules="[]"> | |||
<el-input | |||
v-model="form.spec" | |||
:disabled="disabled" | |||
placeholder="请输入设备规格"></el-input> | |||
</el-form-item> | |||
</el-col> | |||
</el-row> | |||
<el-row :gutter="20"> | |||
<!-- 功能描述 --> | |||
<el-col> | |||
<el-form-item label="功能描述" prop="description" :rules="[]"> | |||
<el-input | |||
type="textarea" | |||
:disabled="disabled" | |||
v-model="form.description" | |||
placeholder="请填写功能描述"></el-input> | |||
</el-form-item> | |||
</el-col> | |||
</el-row> | |||
<el-row :gutter="20"> | |||
<!-- 上传资料 --> | |||
<el-col> | |||
<el-form-item label="上传资料" prop="assets" :rules="[]"> | |||
<AssetsUpload v-model="form.assets" :disabled="disabled" /> | |||
</el-form-item> | |||
</el-col> | |||
</el-row> | |||
<el-row :gutter="20"> | |||
<!-- 上传图片 --> | |||
<el-col> | |||
<el-form-item label="上传图片" prop="pics" :rules="[]"> | |||
<AssetsUpload | |||
:is-pic-mode="true" | |||
v-model="form.pics" | |||
:disabled="disabled" /> | |||
</el-form-item> | |||
</el-col> | |||
</el-row> | |||
</el-form> | |||
</template> | |||
<script> | |||
import AssetsUpload from './AssetsUpload.vue'; | |||
export default { | |||
name: 'EquipmentInfoForm', | |||
model: { | |||
prop: 'dataForm', | |||
event: 'update', | |||
}, | |||
emits: ['update'], | |||
components: { AssetsUpload }, | |||
props: { | |||
dataForm: { | |||
type: Object, | |||
default: () => ({}), | |||
}, | |||
disabled: { | |||
type: Boolean, | |||
default: false, | |||
}, | |||
syncFilelist: { | |||
type: Number, | |||
default: null, | |||
required: false, | |||
}, | |||
}, | |||
data() { | |||
return { | |||
formLoading: false, | |||
form: { | |||
name: '', | |||
code: '', | |||
enName: '', | |||
abbr: '', | |||
equipmentTypeId: '', | |||
remark: '', | |||
productionTime: '', | |||
enterTime: '', | |||
tvalue: '', | |||
processingTime: '', | |||
manufacturer: '', | |||
spec: '', | |||
description: '', | |||
assets: [], | |||
pics: [], | |||
}, | |||
eqTypeList: [], | |||
dataLoaded: false, | |||
}; | |||
}, | |||
watch: { | |||
dataForm: { | |||
handler(val) { | |||
// debugger; | |||
this.form = JSON.parse(JSON.stringify(val)); | |||
this.form.assets = | |||
this.form.files?.filter((item) => item.fileType == '2') || []; | |||
this.form.pics = | |||
this.form.files?.filter((item) => item.fileType == '1') || []; | |||
delete this.form.files; | |||
}, | |||
immediate: true, | |||
deep: true, | |||
}, | |||
syncFilelist: { | |||
handler(val) { | |||
if (val != null) { | |||
this.updateForm(); | |||
} | |||
}, | |||
immediate: true, | |||
}, | |||
}, | |||
mounted() { | |||
this.getEqTypeList(); | |||
}, | |||
methods: { | |||
updateForm() { | |||
console.log('update form ==> '); | |||
this.form.files = [...this.form.assets, ...this.form.pics]; | |||
delete this.form.assets; | |||
delete this.form.pics; | |||
this.$emit('update', this.form); | |||
}, | |||
async getEqTypeList() { | |||
this.formLoading = true; | |||
const { code, data } = await this.$axios( | |||
'/base/equipment-type/page?pageNo=1&pageSize=100' | |||
); | |||
// debugger; | |||
if (code == 0) { | |||
this.eqTypeList = data.list; | |||
} | |||
this.formLoading = false; | |||
}, | |||
/** 模拟透传 ref */ | |||
validate(cb) { | |||
return this.$refs.form.validate(cb); | |||
}, | |||
resetFields(args) { | |||
return this.$refs.form.resetFields(args); | |||
}, | |||
// getCode | |||
async getCode(url) { | |||
const response = await this.$axios(url); | |||
return response.data; | |||
}, | |||
// 上传成功的特殊处理 | |||
beforeUpload() {}, | |||
// 上传前的验证规则可通过 bind 属性传入 | |||
handleUploadSuccess(response, file, fileList) { | |||
console.log( | |||
'[dialogForm:handleUploadSuccess]', | |||
response, | |||
file, | |||
fileList, | |||
this.form | |||
); | |||
// 保存原始文件名 | |||
if ('fileNames' in this.form) this.form.fileNames.push(file.name); | |||
// 保存完整地址 | |||
if ('fileUrls' in this.form) this.form.fileUrls.push(response.data); | |||
this.$modal.msgSuccess('上传成功'); | |||
}, | |||
getFileName(fileUrl) { | |||
return fileUrl.split('/').pop(); | |||
}, | |||
}, | |||
}; | |||
</script> | |||
<style scoped lang="scss"> | |||
.el-date-editor, | |||
.el-select { | |||
width: 100%; | |||
} | |||
</style> |
@@ -53,6 +53,7 @@ | |||
v-if="editVisible" | |||
ref="drawer" | |||
:mode="editMode" | |||
@update-mode="editMode = $event" | |||
:data-id="form.id" | |||
:sections="[ | |||
{ | |||
@@ -462,6 +463,8 @@ export default { | |||
label: '上传资料', | |||
fieldName: 'assets', | |||
subcomponent: AssetsUpload, | |||
prop: 'uploadedAssets', | |||
default: [], | |||
bind: { | |||
'is-pic-mode': false, | |||
}, | |||
@@ -474,6 +477,8 @@ export default { | |||
label: '上传图片', | |||
fieldName: 'images', | |||
subcomponent: AssetsUpload, | |||
// prop: '', | |||
// default: [], | |||
bind: { | |||
'is-pic-mode': true, | |||
}, | |||
@@ -37,22 +37,7 @@ | |||
@close="cancel" | |||
@cancel="cancel" | |||
@confirm="submitForm"> | |||
<DialogForm v-if="open" ref="form" :dataForm="form" :rows="rows" /> | |||
<div style="padding: 12px; background: #ccc"> | |||
<h3>文件列表</h3> | |||
<hr /> | |||
<ul> | |||
<li v-for="item in form.fileUrls" :key="item"> | |||
{{ JSON.stringify(item) }} | |||
</li> | |||
</ul> | |||
<hr /> | |||
<ul> | |||
<li v-for="item in form.fileNames" :key="item"> | |||
{{ JSON.stringify(item) }} | |||
</li> | |||
</ul> | |||
</div> | |||
<DialogForm v-if="open" ref="form" v-model="form" :rows="rows" /> | |||
</base-dialog> | |||
</div> | |||
</template> | |||
@@ -70,7 +55,7 @@ import { | |||
exportEquipmentTypeExcel, | |||
} from '@/api/base/equipmentType'; | |||
import { getAccessToken } from '@/utils/auth'; | |||
// import { getAccessToken } from '@/utils/auth'; | |||
export default { | |||
name: 'EquipmentType', | |||
@@ -164,15 +149,13 @@ export default { | |||
prop: 'parentId', | |||
url: '/base/equipment-type/page?pageNo=1&pageSize=100', | |||
}, | |||
{}, | |||
], | |||
[ | |||
{ | |||
upload: true, | |||
label: '上传资料', | |||
prop: 'uploadFiles', | |||
url: process.env.VUE_APP_BASE_API + '/admin-api/infra/file/upload', // 请求地址 | |||
bind: { | |||
headers: { Authorization: 'Bearer ' + getAccessToken() }, | |||
'show-file-list': false, | |||
}, | |||
prop: 'files', | |||
}, | |||
], | |||
[{ input: true, label: '备注', prop: 'remark' }], | |||
@@ -251,7 +234,25 @@ export default { | |||
const id = row.id; | |||
getEquipmentType(id).then((response) => { | |||
this.form = response.data; | |||
debugger; | |||
// this.form = { | |||
// code: 'SBLX20230925184444000041', | |||
// name: '测试131', | |||
// remark: '测试可删除', | |||
// id: '1706258479729336322', | |||
// files: [ | |||
// { fileName: '1.png', fileUrl: '', fileType: 2 }, | |||
// { fileName: '1.asdfaslkjfkasdf.png', fileUrl: '', fileType: 2 }, | |||
// { fileName: '2.txt', fileUrl: '', fileType: 2 }, | |||
// { fileName: '1.rar', fileUrl: '', fileType: 2 }, | |||
// { fileName: '1.kkk', fileUrl: '', fileType: 2 }, | |||
// { fileName: 'test.file', fileUrl: '', fileType: 2 }, | |||
// { fileName: '222', fileUrl: '', fileType: 2 }, | |||
// { fileName: 'g', fileUrl: '', fileType: 2 }, | |||
// ], | |||
// createTime: 1695638697000, | |||
// parentId: '1701869972319584257', | |||
// }; | |||
// debugger; | |||
this.open = true; | |||
this.title = '修改设备类型'; | |||
}); | |||