文件上传

This commit is contained in:
cwchen 2025-10-27 16:41:20 +08:00
parent 9f8333767a
commit 0eef1888d7
9 changed files with 608 additions and 13 deletions

View File

@ -303,6 +303,20 @@ export const dynamicRoutes = [
}
]
},
{
path: '/tool',
component: Layout,
hidden: true,
permissions: ['enterpriseLibrary:tool:list'],
children: [
{
path: 'index',
component: () => import('@/views/enterpriseLibrary/tool/index'),
name: 'Tool',
meta: { title: '工器具库', activeMenu: '/enterpriseLibrary/tool', noCache: true }
}
]
},
]
// 防止连续点击多次路由报错

View File

@ -85,12 +85,14 @@ export default {
previewFileType: '',
isUploading: false, //
defaultFileSize: 1024 * 1024 * 5, // 5MB 5MB
fileValidationMap: new Map(), //
}
},
methods: {
beforeUpload(file) {
//
if (this.isUploading) {
this.fileValidationMap.set(file.uid, false);
return false;
}
@ -103,16 +105,23 @@ export default {
//
const isLtMaxSize = file.size / 1024 / 1024 < this.maxSizeMB;
let isValid = true;
if (!isAllowedType || !isAllowedMimeType) {
this.$message.error(`只能上传 ${this.uploadType} 格式的文件!`);
return false;
isValid = false;
}
if (!isLtMaxSize) {
this.$message.error(`文件大小不能超过 ${this.maxFileTips}!`);
return false;
isValid = false;
}
//
this.fileValidationMap.set(file.uid, isValid);
// false
return false;
},
//
@ -122,7 +131,20 @@ export default {
return;
}
// 使使 fileList files
//
const isValid = this.fileValidationMap.get(file.uid);
if (isValid === false) {
//
const fileIndex = fileList.findIndex(item => item.uid === file.uid);
if (fileIndex !== -1) {
fileList.splice(fileIndex, 1);
}
this.fileValidationMap.delete(file.uid);
this.files = this.formatFileList(fileList);
return;
}
//
this.files = this.formatFileList(fileList);
//
@ -140,8 +162,7 @@ export default {
}
//
if (this.autoUpload && file.status === 'ready' && !this.isUploading) {
alert(this.fileUploadRule.fields_json);
if (this.autoUpload && file.status === 'ready' && !this.isUploading && isValid !== false) {
if (this.fileUploadRule.fields_json) {
// ocr
this.uploadFile(file, '识别中');
@ -150,6 +171,9 @@ export default {
this.uploadFile(file, '上传中');
}
}
//
this.fileValidationMap.delete(file.uid);
},
//
@ -336,7 +360,13 @@ export default {
//
const newFile = files[0];
this.beforeUpload(newFile); //
//
const isValid = this.beforeUpload(newFile);
if (!isValid) {
return;
}
// percentage
const newFileObj = {

View File

@ -76,7 +76,7 @@ export default {
description: '工器具库主要用于登记工器具资料信息, 统一管理工器具清单等',
icon: enterpriseKnowledgeIcon,
path: '/enterpriseLibrary/enterprise/tools',
name: 'Tools'
name: 'Tool'
},
{
type: 'financial',

View File

@ -1,5 +1,5 @@
<template>
<!-- 用户管理 -->
<!-- 技术方案列表 -->
<div class="app-container">
<TableModel :formLabel="formLabel" :showOperation="true" :showRightTools="false" ref="userTableRef"
:columnsList="columnsList" :request-api="listUser">

View File

@ -11,10 +11,9 @@
</el-form>
</div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" class="search-btn" :disabled="disabled"
<el-button type="primary" class="confirm-btn" :disabled="disabled"
@click="submitForm('ruleForm')">确认</el-button>
<el-button class="clear-btn" @click="handleClose" :disabled="disabled">取消</el-button>
<el-button class="cancel-btn" @click="handleClose" :disabled="disabled">取消</el-button>
</span>
</el-dialog>
</template>
@ -165,4 +164,42 @@ export default {
display: flex;
justify-content: space-between;
}
.confirm-btn {
width: 98px;
height: 36px;
background: #1F72EA;
box-shadow: 0px 4px 8px 0px rgba(51, 135, 255, 0.5);
border-radius: 4px 4px 4px 4px;
color: #fff;
border: none;
font-size: 14px;
transition: all 0.3s;
&:hover {
background: #4A8BFF;
box-shadow: 0px 6px 12px 0px rgba(51, 135, 255, 0.6);
}
}
.cancel-btn {
width: 98px;
height: 36px;
background: #E5E5E5;
box-shadow: 0px 4px 8px 0px rgba(76, 76, 76, 0.2);
border-radius: 4px 4px 4px 4px;
color: #333;
border: none;
font-size: 14px;
transition: all 0.3s;
&:hover {
background: #d0d0d0;
box-shadow: 0px 6px 12px 0px rgba(76, 76, 76, 0.3);
}
}
::v-deep .el-dialog__footer {
text-align: center;
}
</style>

View File

@ -1,5 +1,11 @@
<template>
<div class="technical-container">
<!-- 返回按钮 -->
<div class="back-container">
<el-button type="default" size="small" @click="handleBack" class="back-btn">
返回
</el-button>
</div>
<div class="layout-container">
<el-row>
<el-col :span="5" class="left-col">
@ -18,7 +24,7 @@
<script>
import LeftType from './components/LeftType.vue'
import RightTable from './components/RightTable.vue'
import { decryptWithSM4 } from '@/utils/sm'
import { encryptWithSM4, decryptWithSM4 } from '@/utils/sm'
export default {
name: 'Technical',
@ -58,7 +64,17 @@ export default {
},
handleDelete(row) {
console.log('删除:', row)
}
},
//
handleBack() {
const obj = {
path: "/enterpriseKnowledge/index",
query: {
enterpriseId: encryptWithSM4(this.enterpriseId || '0'),
}
}
this.$tab.closeOpenPage(obj)
},
}
}
</script>
@ -70,6 +86,32 @@ export default {
background: linear-gradient(180deg, #F1F6FF 20%, #E5EFFF 100%);
}
.back-container {
display: flex;
justify-content: flex-end;
align-items: center;
margin-bottom: 30px;
padding: 0 20px;
.back-btn {
width: 98px;
height: 36px;
background: #FFFFFF;
box-shadow: 0px 4px 8px 0px rgba(76, 76, 76, 0.2);
border-radius: 4px;
border: none;
color: #666;
font-size: 14px;
transition: all 0.3s ease;
&:hover {
background: #f5f5f5;
color: #409EFF;
box-shadow: 0px 6px 12px 0px rgba(76, 76, 76, 0.3);
}
}
}
.layout-container {
display: flex;
height: 100%;

View File

@ -0,0 +1,242 @@
<template>
<!-- 小型弹窗用于完成删除保存等操作 -->
<el-dialog class="l-dialog" :class="lDialog" :title="title" :visible.sync="dialogVisible" :showClose="true"
:closeOnClickModal="false" @close="handleClose" :append-to-body="true">
<div>
<el-form :model="form" :rules="rules" ref="ruleForm" label-width="110px">
<el-form-item label="工器具名称" prop="toolName">
<el-input class="form-item" v-model="form.toolName" clearable show-word-limit
placeholder="请输入工器具名称" maxlength="32"></el-input>
</el-form-item>
<el-form-item label="规格型号" prop="model">
<el-input class="form-item" v-model="form.model" clearable show-word-limit
placeholder="请输入规格型号" maxlength="32"></el-input>
</el-form-item>
<el-form-item label="单位" prop="unit">
<el-input class="form-item" v-model="form.unit" clearable show-word-limit
placeholder="请输入单位" maxlength="32"></el-input>
</el-form-item>
<el-form-item label="技术参数" prop="technicalParameters">
<el-input class="form-item" v-model="form.technicalParameters" clearable show-word-limit
placeholder="请输入技术参数" maxlength="32"></el-input>
</el-form-item>
<el-form-item label="主要作用" prop="mainFunction">
<el-input class="form-item" v-model="form.mainFunction" clearable show-word-limit
placeholder="请输入主要作用" maxlength="32"></el-input>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input type="textarea" :autosize="{ minRows: 4, maxRows: 6 }" class="form-item"
v-model.trim="form.remark" clearable show-word-limit placeholder="请输入备注"
maxlength="300"></el-input>
</el-form-item>
</el-form>
</div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" class="confirm-btn" :disabled="disabled"
@click="submitForm('ruleForm')">确认</el-button>
<el-button class="cancel-btn" @click="handleClose" :disabled="disabled">取消</el-button>
</span>
</el-dialog>
</template>
<script>
import _ from 'lodash'
export default {
name: "TypeForm",
props: ["width", "rowData", "title", "disabled", "isAdd"],
data() {
return {
lDialog: this.width > 500 ? "w700" : "w500",
dialogVisible: true,
isDisabled: true,
form: {
id: null,
technicalSolutionName: '',
model: '',
unit: '',
technicalParameters: '',
mainFunction: '',
remark: '',
},
rules: {
toolName: [
{ required: true, message: '工器具名称不能为空', trigger: 'blur' }
],
model: [
{ required: true, message: '规格型号不能为空', trigger: 'blur' }
],
unit: [
{ required: true, message: '单位不能为空', trigger: 'blur' }
],
},
};
},
watch: {
isAdd: {
handler(newVal) {
if (newVal === 'edit') {
this.initFormData();
}
},
immediate: true,
},
},
methods: {
/** 初始化表单数据 */
initFormData() {
if (this.isAdd === 'edit' && this.rowData) {
//
this.form = {
id: this.rowData.id,
toolName: this.rowData.toolName || '',
model: this.rowData.model || '',
unit: this.rowData.unit || '',
technicalParameters: this.rowData.technicalParameters || '',
mainFunction: this.rowData.mainFunction || '',
remark: this.rowData.remark || '',
};
}
},
/*关闭弹窗 */
handleClose() {
this.dialogVisible = false;
this.$emit("closeDialog");
},
/**确认弹窗 */
sureBtnClick() {
this.dialogVisible = false;
this.$emit("closeDialog");
},
/**重置表单*/
reset() {
this.form = {
id: null,
pid: null,
dataTypeName: '',
remark: '',
};
this.resetForm("ruleForm");
},
handleReuslt(res) {
this.$modal.msgSuccess(res.msg);
this.reset();
this.$emit('handleQuery');
this.handleClose();
},
/**验证 */
submitForm(formName) {
this.$refs[formName].validate(valid => {
if (valid) {
//
this.loading = this.$loading({
lock: true,
text: "数据提交中,请稍候...",
background: 'rgba(0,0,0,0.5)',
target: this.$el.querySelector('.el-dialog') || document.body
})
let params = _.cloneDeep(this.form);
if (this.isAdd === 'add') {
addDataClassAPI(params).then(res => {
this.loading.close();
if (res.code === 200) {
this.handleReuslt(res);
} else {
this.$modal.msgError(res.msg);
}
}).catch(error => {
this.loading.close();
this.$modal.msgError(this.errorMsg(error));
});
} else {
updateDataClassAPI(params).then(res => {
this.loading.close();
if (res.code === 200) {
this.handleReuslt(res);
} else {
this.$modal.msgError(res.msg);
}
}).catch(error => {
this.loading.close();
this.$modal.msgError(this.errorMsg(error));
});
}
}
});
},
}
};
</script>
<style lang="scss" scoped>
.w700 ::v-deep .el-dialog {
width: 700px;
font-family: Source Han Sans CN, Source Han Sans CN;
}
.w500 ::v-deep .el-dialog {
width: 500px;
font-family: Source Han Sans CN, Source Han Sans CN;
}
.w500 ::v-deep .el-dialog__header,
.w700 ::v-deep .el-dialog__header {
.el-dialog__title {
font-size: 16px;
}
}
.yxq .el-range-separator {
margin-right: 7px !important;
}
.el-date-editor--daterange.el-input__inner {
width: 260px;
}
.form-item {
width: 100%;
}
.select-style {
display: flex;
justify-content: space-between;
}
.confirm-btn {
width: 98px;
height: 36px;
background: #1F72EA;
box-shadow: 0px 4px 8px 0px rgba(51, 135, 255, 0.5);
border-radius: 4px 4px 4px 4px;
color: #fff;
border: none;
font-size: 14px;
transition: all 0.3s;
&:hover {
background: #4A8BFF;
box-shadow: 0px 6px 12px 0px rgba(51, 135, 255, 0.6);
}
}
.cancel-btn {
width: 98px;
height: 36px;
background: #E5E5E5;
box-shadow: 0px 4px 8px 0px rgba(76, 76, 76, 0.2);
border-radius: 4px 4px 4px 4px;
color: #333;
border: none;
font-size: 14px;
transition: all 0.3s;
&:hover {
background: #d0d0d0;
box-shadow: 0px 6px 12px 0px rgba(76, 76, 76, 0.3);
}
}
::v-deep .el-dialog__footer {
text-align: center;
}
</style>

View File

@ -0,0 +1,18 @@
export const formLabel = [
{
isShow: false, // 是否展示label
f_type: 'ipt',
f_label: '工器具名称',
f_model: 'userName',
f_max: 32,
f_width: '250px',
},
]
export const columnsList = [
{ t_props: 'userName', t_label: '名称' },
{ t_props: 'nickName', t_label: '规格型号' },
{ t_props: 'phonenumberDes', t_label: '单位' },
{ t_props: 'phonenumberDes', t_label: '技术参数' },
{ t_props: 'phonenumberDes', t_label: '主要作用' },
]

View File

@ -0,0 +1,212 @@
<template>
<!-- 工器具库 -->
<el-card class="tool-container">
<!-- 返回按钮 -->
<div class="back-container">
<el-button type="default" size="small" @click="handleBack" class="back-btn">
返回
</el-button>
</div>
<TableModel :formLabel="formLabel" :showOperation="true" :showRightTools="false" ref="userTableRef"
:columnsList="columnsList" :request-api="listUser">
<template slot="tableTitle">
<h3>数据列表</h3>
</template>
<template slot="tableActions">
<el-button @click="handleAdd" v-hasPermi="['enterpriseLibrary:technical:add']"
class="add-btn">导入模板下载</el-button>
<el-button @click="handleAdd" v-hasPermi="['enterpriseLibrary:technical:add']"
class="add-btn">导入模板下载</el-button>
<el-button @click="handleAdd" v-hasPermi="['enterpriseLibrary:technical:add']" class="add-btn"><i
class="el-icon-plus"></i> 新增工器具</el-button>
</template>
<template slot="deptName" slot-scope="{ data }">
<span>{{ data.dept.deptName || '--' }}</span>
</template>
<template slot="handle" slot-scope="{ data }">
<el-button type="text" v-hasPermi="['enterpriseLibrary:technical:detail']" class="action-btn"
@click="handleUpdate(data)">
查看
</el-button>
<el-button type="text" v-hasPermi="['enterpriseLibrary:technical:edit']" class="action-btn"
style="color: #EAA819;" @click="handleUpdate(data)">
编辑
</el-button>
<el-button type="text" v-hasPermi="['enterpriseLibrary:technical:del']" class="action-btn"
style="color: #DB3E29;" @click="handleDelete(data)">
删除
</el-button>
</template>
</TableModel>
<!-- 添加方案类型弹窗 -->
<ToolForm ref="toolForm" v-if="isflag" :isAdd="isAdd" :rowData="row" @handleQuery="handleQuery" :title="title"
@closeDialog="closeDialog" :width="600" />
</el-card>
</template>
<script>
import TableModel from '@/components/TableModel2'
import { columnsList, formLabel } from './config'
import ToolForm from './components/ToolForm.vue'
import {
listUser,
delUser,
} from '@/api/system/user'
import { encryptWithSM4, decryptWithSM4 } from '@/utils/sm'
export default {
name: 'Tool',
components: {
TableModel,
ToolForm
},
dicts: ['construction_nature', 'structural_form', 'basic_form'],
data() {
return {
formLabel,
columnsList,
listUser,
enterpriseId: decryptWithSM4(this.$route.query.enterpriseId) || '0',
title: "",
isflag: false,
isAdd: '',
row: {},
}
},
created() {
//
if (Array.isArray(this.formLabel)) {
this.formLabel.forEach((item) => {
if (item.f_dict && this.dict && this.dict.type && this.dict.type[item.f_dict]) {
this.$set(item, 'f_selList', this.dict.type[item.f_dict])
}
})
}
},
methods: {
//
handleBack() {
const obj = {
path: "/enterpriseKnowledge/index",
query: {
enterpriseId: encryptWithSM4(this.enterpriseId || '0'),
}
}
this.$tab.closeOpenPage(obj)
},
/** 新增按钮操作 */
handleAdd() {
this.title = "新增工器具";
this.isAdd = 'add';
this.row = {};
this.isflag = true;
},
/** 修改操作 */
handleUpdate(row) {
this.title = "修改";
this.isAdd = 'edit';
this.row = row;
this.isflag = true;
},
closeDialog() {
this.isflag = false;
},
/* 搜索操作 */
handleQuery() {
this.$refs.userTableRef.getTableList()
},
/** 删除操作 */
handleDelete(row) {
this.$modal.confirm(`是否确认删除此数据项?`).then(() => {
//
this.$modal.loading("正在删除,请稍候...");
delUser({ userId: row.userId }).then(res => {
this.$modal.closeLoading();
if (res.code === 200) {
this.$modal.msgSuccess("删除成功");
this.handleQuery();
} else {
this.$modal.msgError(res.msg);
}
}).catch(error => {
this.$modal.closeLoading();
this.$modal.msgError(error);
});
}).catch(() => {
//
});
},
},
}
</script>
<style scoped lang="scss">
.tool-container {
height: calc(100vh - 84px);
overflow: hidden;
background: linear-gradient(180deg, #F1F6FF 20%, #E5EFFF 100%);
}
.back-container {
display: flex;
justify-content: flex-end;
align-items: center;
margin-bottom: 30px;
padding: 0 20px;
.back-btn {
width: 98px;
height: 36px;
background: #FFFFFF;
box-shadow: 0px 4px 8px 0px rgba(76, 76, 76, 0.2);
border-radius: 4px;
border: none;
color: #666;
font-size: 14px;
transition: all 0.3s ease;
&:hover {
background: #f5f5f5;
color: #409EFF;
box-shadow: 0px 6px 12px 0px rgba(76, 76, 76, 0.3);
}
}
}
.right-table-card {
height: 100%;
overflow-y: hidden;
transition: overflow-y 0.3s ease;
&:hover {
overflow-y: auto;
}
}
.add-btn {
width: 121px;
height: 36px;
background: #1F72EA;
box-shadow: 0px 4px 8px 0px rgba(51, 135, 255, 0.5);
border-radius: 4px 4px 4px 4px;
color: #fff;
border: none;
font-size: 14px;
transition: all 0.3s;
&:hover {
background: #4A8BFF;
box-shadow: 0px 6px 12px 0px rgba(51, 135, 255, 0.6);
}
}
.action-btn {
margin-right: 8px;
&:last-child {
margin-right: 0;
}
}
</style>