Compare commits

...

11 Commits

Author SHA1 Message Date
helloDy
c76078214e Merge branch 'projects/mes-test' into projects/mes-dy 2023-11-27 20:42:33 +08:00
helloDy
b527589e0f ui 2023-11-27 20:41:45 +08:00
375273419d Merge pull request 'projects/mes-lb' (#117) from projects/mes-lb into projects/mes-test
Reviewed-on: #117
2023-11-27 17:05:07 +08:00
lb
a18929a261 Merge branch 'projects/mes-test' into projects/mes-lb 2023-11-27 17:04:32 +08:00
6d465c17c2 Merge pull request 'projects/mes-zjl' (#116) from projects/mes-zjl into projects/mes-test
Reviewed-on: #116
2023-11-27 16:43:48 +08:00
669345c983 merge test 2023-11-27 16:43:15 +08:00
b86094c630 订单监控 2023-11-27 16:41:14 +08:00
lb
2fdee9cafd update 2023-11-27 15:39:30 +08:00
lb
4348d66e53 update 2023-11-27 14:40:11 +08:00
lb
76c2f50bf3 fix bugs 2023-11-27 11:31:21 +08:00
888b5aa91f Merge pull request 'projects/mes-dy' (#115) from projects/mes-dy into projects/mes-test
Reviewed-on: #115
2023-11-27 09:42:54 +08:00
36 changed files with 881 additions and 1530 deletions

View File

@ -1,7 +1,7 @@
/* /*
* @Author: Do not edit * @Author: Do not edit
* @Date: 2023-10-21 11:50:46 * @Date: 2023-10-21 11:50:46
* @LastEditTime: 2023-10-26 20:06:29 * @LastEditTime: 2023-11-27 17:54:28
* @LastEditors: DY * @LastEditors: DY
* @Description: * @Description:
*/ */
@ -110,3 +110,11 @@ export function deleteMaterialPBDet(id) {
method: 'delete' method: 'delete'
}) })
} }
// 获得产品Bom详细
export function getMaterialPBDet(id) {
return request({
url: '/base/material-product-bom-det/get?id=' + id,
method: 'get'
})
}

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="1_基础资料" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="1-1工厂信息" transform="translate(-1834.000000, -253.000000)">
<g id="icon/界面内/编辑" transform="translate(1834.000000, 253.000000)">
<rect id="矩形" x="0" y="0" width="16" height="16"></rect>
<g id="常用购票人编辑32" fill-rule="nonzero">
<rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="16" height="16"></rect>
<path d="M13.5,7.8285 C13.5,7.55235763 13.7238576,7.3285 14,7.3285 C14.2761424,7.3285 14.5,7.55235763 14.5,7.8285 L14.5,12 C14.5,13.3807119 13.3807119,14.5 12,14.5 L4,14.5 C2.61928813,14.5 1.5,13.3807119 1.5,12 L1.5,4 C1.5,2.61928813 2.61928813,1.5 4,1.5 L8.759,1.5 C8.9376328,1.5 9.10269631,1.59529946 9.19201271,1.75 C9.28132911,1.90470054 9.28132911,2.09529946 9.19201271,2.25 C9.10269631,2.40470054 8.9376328,2.5 8.759,2.5 L4,2.5 C3.17157288,2.5 2.5,3.17157288 2.5,4 L2.5,12 C2.5,12.8284271 3.17157288,13.5 4,13.5 L12,13.5 C12.8284271,13.5 13.5,12.8284271 13.5,12 L13.5,7.8285 Z M13.284,2.312 C13.4738226,2.11757837 13.784168,2.11034095 13.9828473,2.2957025 C14.1815266,2.48106405 14.1958051,2.79116533 14.015,2.994 L8.56,8.845 C8.43817243,8.97566989 8.25588756,9.03141962 8.08181033,8.9912488 C7.90773311,8.95107798 7.76830999,8.82108951 7.71606033,8.65024879 C7.66381067,8.47940808 7.70667243,8.29366989 7.8285,8.163 L13.284,2.312 Z" id="形状" stroke="#0B58FF" stroke-width="0.1" fill="#0B58FF"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -76,6 +76,7 @@
class="upload-area" class="upload-area"
:class="uploadOpen ? '' : 'height-48'" :class="uploadOpen ? '' : 'height-48'"
ref="uploadArea" ref="uploadArea"
:key="col.prop"
v-if="col.upload"> v-if="col.upload">
<span class="close-icon" :class="uploadOpen ? 'open' : ''"> <span class="close-icon" :class="uploadOpen ? 'open' : ''">
<el-button <el-button
@ -87,13 +88,18 @@
<el-upload <el-upload
class="upload-in-dialog" class="upload-in-dialog"
v-if="col.upload" v-if="col.upload"
:key="col.prop + '__el-upload'"
:action="uploadUrl" :action="uploadUrl"
:headers="uploadHeaders" :headers="uploadHeaders"
:show-file-list="false" :show-file-list="false"
icon="el-icon-upload2" icon="el-icon-upload2"
:disabled="disabled" :disabled="disabled"
:before-upload="beforeUpload" :before-upload="beforeUpload"
:on-success="handleUploadSuccess" :on-success="
(response, file, fileList) => {
handleUploadSuccess(response, file, col.prop);
}
"
v-bind="col.bind"> v-bind="col.bind">
<el-button size="mini" :disabled="col.bind?.disabled || false"> <el-button size="mini" :disabled="col.bind?.disabled || false">
<svg-icon <svg-icon
@ -108,10 +114,10 @@
<uploadedFile <uploadedFile
class="file" class="file"
v-for="file in form[col.prop] || []" v-for="file in form[col.prop]"
:file="file" :file="file"
:key="file.fileUrl" :key="file.fileUrl"
@delete="!disabled && handleDeleteFile(file)" /> @delete="!disabled && handleDeleteFile(file, col.prop)" />
</div> </div>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -152,12 +158,30 @@ const uploadedFile = {
handleDelete() { handleDelete() {
this.$emit('delete', this.file); this.$emit('delete', this.file);
}, },
async handleDownload() {
const data = await this.$axios({
url: this.file.fileUrl,
method: 'get',
responseType: 'blob',
});
await this.$message.success('开始下载');
// create download link
const url = window.URL.createObjectURL(data);
const link = document.createElement('a');
link.href = url;
link.download = this.file.fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
},
}, },
mounted() {}, mounted() {},
render: function (h) { render: function (h) {
return ( return (
<div <div
title={this.file.fileName} title={this.file.fileName}
onClick={this.handleDownload}
style={{ style={{
background: `url(${tupleImg}) no-repeat`, background: `url(${tupleImg}) no-repeat`,
backgroundSize: '14px', backgroundSize: '14px',
@ -205,7 +229,7 @@ export default {
default: false, default: false,
}, },
hasFiles: { hasFiles: {
type: Boolean, type: Boolean | Array,
default: false, default: false,
}, },
labelPosition: { labelPosition: {
@ -251,7 +275,13 @@ export default {
handler(val) { handler(val) {
this.form = JSON.parse(JSON.stringify(val)); this.form = JSON.parse(JSON.stringify(val));
if (this.hasFiles) { if (this.hasFiles) {
this.form.files = this.form.files ?? []; if (typeof this.hasFiles == 'boolean' && this.hasFiles) {
this.form.files = this.form.files ?? [];
} else if (Array.isArray(this.hasFiles)) {
this.hasFiles.forEach((prop) => {
this.form[prop] = this.form[prop] ?? [];
});
}
} }
}, },
deep: true, deep: true,
@ -348,7 +378,7 @@ export default {
// //
this.form[opt.prop] = response.data; this.form[opt.prop] = response.data;
// dataFormcodebug // dataFormcodebug
this.$emit('update', this.form) this.$emit('update', this.form);
} }
}); });
} }
@ -377,11 +407,12 @@ export default {
// //
beforeUpload() {}, beforeUpload() {},
// bind // bind
handleUploadSuccess(response, file, fileList) { handleUploadSuccess(response, file, prop) {
this.form.files.push({ console.log('[handleUploadSuccess]', response, file, prop);
this.form[prop].push({
fileName: file.name, fileName: file.name,
fileUrl: response.data, fileUrl: response.data,
fileType: 2, fileType: prop == 'files' ? 2 : 1,
}); });
this.$modal.msgSuccess('上传成功'); this.$modal.msgSuccess('上传成功');
this.$emit('update', this.form); this.$emit('update', this.form);
@ -395,8 +426,8 @@ export default {
this.uploadOpen = !this.uploadOpen; this.uploadOpen = !this.uploadOpen;
}, },
handleDeleteFile(file) { handleDeleteFile(file, prop) {
this.form.files = this.form.files.filter( this.form[prop] = this.form[prop].filter(
(item) => item.fileUrl != file.fileUrl (item) => item.fileUrl != file.fileUrl
); );
this.$emit('update', this.form); this.$emit('update', this.form);

View File

@ -124,9 +124,9 @@ export default {
this.Quill = new Quill(editor, this.options); this.Quill = new Quill(editor, this.options);
// start // start
this.$nextTick(() => { this.$nextTick(() => {
this.Quill.blur(); this.Quill?.blur();
if (!this.readOnly) { if (!this.readOnly) {
this.Quill.enable(); this.Quill?.enable();
} }
}); });
// //

View File

@ -1,978 +0,0 @@
<template>
<el-dialog class="dialog-with-menu" :visible="dialogVisible" :destroy-on-close="false" @close="handleClose"
:close-on-click-modal="configs.clickModalToClose ?? true">
<!-- title -->
<div slot="title" class="dialog-title">
<h1 class="">
{{ detailMode ? "查看详情" : dataForm.id ? "编辑" : "新增" }}
</h1>
</div>
<div class="dialog-body__inner relative">
<!-- v-if="dataForm.id && !detailMode && /属性|详情/.test(activeMenu) && $hasPermission()" -->
<el-button v-if="configs.allowAdd ?? (dataForm.id && !detailMode && /属性|详情|参数/.test(activeMenu))" plain
type="primary" size="small" class="at-right-top" style="margin-bottom: 16px" @click="handleAddParam()">+
添加</el-button>
<template v-if="dataForm.id && !detailMode && /附件/.test(activeMenu)">
<el-upload style="position: absolute; width: 100%; height: 0" name="files" :action="uploadUrl"
:show-file-list="false" :headers="uploadHeaders" :on-success="handleUploadSuccess"
:before-upload="handleUploadCheck">
<el-button plain type="primary" size="small" class="at-right-top" style=""> <i class="el-icon-upload"></i> 上传
</el-button>
</el-upload>
</template>
<!-- menu -->
<el-tabs v-model="activeMenu" type="card" @tab-click="handleTabClick">
<!-- <el-tab-pane v-for="(tab, index) in configs.menu" :key="index" :label="tab.name" :name="tab.name"> -->
<el-tab-pane v-for="(tab, index) in actualMenus" :key="index" :name="tab.name">
<span class="slot" slot="label">
<i :class="{
'el-icon-edit': tab.key === 'info',
'el-icon-s-data': tab.key === 'attr',
'el-icon-folder-opened': tab.key === 'attachment',
}"></i>
{{ tab.name }}
</span>
<!-- 表单标签页 -->
<div v-if="tab.key === 'info'">
<!-- form -->
<el-form ref="dataForm" :model="dataForm" v-loading="loadingStatus">
<el-row v-for="(row, rowIndex) in configs.form.rows" :key="'row_' + rowIndex" :gutter="20">
<el-col v-for="(col, colIndex) in row" :key="colIndex" :span="24 / row.length">
<el-form-item :label="col.label" :prop="col.prop" :rules="col.rules || null"
v-show="!col.forceDisabled || (col.forceDisabled && dataForm.id)">
<div v-if="col.forceDisabled && dataForm.id" class="force-disabled">
<el-tag :key="col.key" :type="col.type">{{ dataForm[col.prop] || "-" }}</el-tag>
</div>
<el-input v-if="col.input" v-model="dataForm[col.prop]" clearable
:disabled="disableCondition(col.prop)" v-bind="col.elparams" />
<el-cascader v-if="col.cascader" v-model="dataForm[col.prop]" :options="col.options"
:disabled="detailMode" v-bind="col.elparams"></el-cascader>
<el-select v-if="col.select" v-model="dataForm[col.prop]" clearable
:disabled="disableCondition(col.prop)" v-bind="col.elparams"
@change="handleSelectChange(col, $event)">
<el-option v-for="(opt, optIdx) in col.options" :key="'option_' + optIdx" :label="opt.label"
:value="opt.value" />
</el-select>
<el-switch v-if="col.switch" v-model="dataForm[col.prop]" :active-value="1" :inactive-value="0"
@change="handleSwitchChange" :disabled="disableCondition(col.prop)" />
<el-input v-if="col.textarea" type="textarea" v-model="dataForm[col.prop]"
:disabled="disableCondition(col.prop)" v-bind="col.elparams" />
<quillEditor v-if="col.richInput" ref="quill-editor" v-model="dataForm[col.prop]"
:options="col.quillConfig ?? defaultQuillConfig" style="margin-top: 42px"
:disabled="disableCondition(col.prop)" />
<div class="" v-if="col.component" style="margin: 42px 0 0">
<!-- 下面这个 component 几乎是为 富文本 quill 定制的了... TODO后续可能会根据业务需求创建新的版本 -->
<component :is="col.component" :key="'component_' + col.prop"
@update:modelValue="handleComponentModelUpdate(col.prop, $event)" :modelValue="dataForm[col.prop]"
:mode="detailMode ? 'detail' : dataForm.id ? 'edit' : 'create'" />
</div>
<!-- add more... -->
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<!-- 表格标签页 -->
<div v-if="dataForm.id && tab.key === 'attr'" key="attr-list">
<BaseListTable :table-config="null" :column-config="filteredTableProps" :table-data="subList"
@operate-event="handleTableRowOperate" :current-page="attrPage" :current-size="attrSize"
:refresh-layout-key="Math.random()" v-loading="loadingStatus" />
<!-- paginator -->
<el-pagination class="" style="text-align: left" background @size-change="handleSizeChange"
@current-change="handlePageChange" :current-page.sync="attrPage" :page-sizes="[5, 10, 20]"
:page-size="attrSize" :total="attrTotal" layout="total, sizes, prev, next"></el-pagination>
</div>
<!-- 附件标签页 -->
<div v-if="dataForm.id && tab.key === 'attachment'" key="attachment">
<div class="upload-tips" style="font-size: 0.8em; margin-bottom: 12px">文件大小不要超过 2MB</div>
<!-- 附件列表 -->
<div class="" v-loading="loadingStatus">
<ul class="file-list">
<li v-for="(file, index) in fileList" :key="index">
<span class="file-name">{{ file.name }}</span>
<span class="file-operations">
<span class="file-icon preview" @click="handleFileClick('view', file)">
<i class="el-icon-view" style="cursor: pointer"></i>
</span>
<span class="file-icon download" @click="handleFileClick('download', file)">
<i class="el-icon-download" style="color: #0b58ff; cursor: pointer"></i>
</span>
<span class="file-icon delete" @click="handleFileClick('delete', file)">
<i class="el-icon-delete" style="color: red; cursor: pointer"></i>
</span>
</span>
</li>
</ul>
</div>
<!-- img preview dialog -->
<el-dialog key="image-preview-dialog" class="image-preview-dialog" :visible.sync="imgPreviewDialogVisible"
:append-to-body="true">
<div class="img-container">
<img width="100%" :src="currentImgUrl" alt="" />
</div>
</el-dialog>
</div>
</el-tab-pane>
</el-tabs>
</div>
<!-- sub dialog -->
<small-dialog :append-to-body="true" v-if="showSubDialog" ref="subDialog" :url="urls.subase"
:configs="configs.subDialog" :related-id="dataForm.id" @refreshDataList="getSubList"></small-dialog>
<!-- footer -->
<div slot="footer">
<template v-for="(operate, index) in configs.form.operations">
<el-button v-if="showButton(operate)" :key="'operation_' + index" :type="operate.type"
@click="handleBtnClick(operate)"
:loading="(operate.name === 'add' || operate.name === 'update') && btnLoading">{{ operate.label }}</el-button>
</template>
<el-button @click="handleBtnClick({ name: 'cancel' })">取消</el-button>
</div>
</el-dialog>
</template>
<script>
import { pick as __pick } from "@/utils/filters";
import SmallDialog from "@/components/SmallDialog.vue";
import BaseListTable from "@/components/BaseListTable.vue";
import Cookies from "js-cookie";
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
import { quillEditor } from "vue-quill-editor";
function reConstructTreeData(listObj) {
const entry = [];
Object.keys(listObj).map((key) => {
const currentNode = listObj[key];
currentNode.label = currentNode.name;
currentNode.value = currentNode.id;
if (currentNode.parentId === "0") {
entry.push(listObj[key]);
return; // return { label: currentNode.name, value: currentNode.id, children: currentNode.children ?? [] };
}
const parentNode = listObj[currentNode.parentId];
if (!parentNode.children) {
parentNode.children = [];
}
parentNode.children.push(currentNode);
});
return entry;
}
export default {
name: "DialogWithMenu",
components: { SmallDialog, BaseListTable, quillEditor },
props: {
configs: {
type: Object,
default: () => ({}),
},
dialogVisible: {
type: Boolean,
default: false,
},
},
inject: ["urls"],
data() {
const dataForm = {};
const autoDisabledQueue = [];
const watingToRefreshQueue = [];
const cached = {}
this.configs.form.rows.forEach((row) => {
row.forEach((col) => {
if (col.upload) dataForm[col.prop] = col.default ?? [];
else dataForm[col.prop] = col.default ?? null;
if (col.autoDisabled) autoDisabledQueue.push(col.prop);
if (!!col.refreshOptionsAfterConfirm) watingToRefreshQueue.push(col);
if (col.fetchData)
col.fetchData().then(({ data: res }) => {
console.log("[Fetch Data]", "list" in res.data, res.data, res.data.list);
if (res.code === 0) {
if (col.cacheFetchedData) {
// cache fetched data
cached[col.prop] = 'list' in res.data ? res.data.list : (Array.isArray(res.data) ? res.data : [])
}
if (!col.options || !col.options.length) {
this.$set(
col,
"options",
"list" in res.data
? res.data.list.map((i) => ({
label: col.optionLabel ? i[col.optionLabel] : i.name,
value: col.optionValue ? i[col.optionValue] : i.id,
}))
: res.data.map((i) => ({
label: col.optionLabel ? i[col.optionLabel] : i.name,
value: col.optionValue ? i[col.optionValue] : i.id,
}))
);
}
// col.options = res.data.list;
else if (col.options.length) {
"list" in res.data ? res.data.list.unshift(...col.options) : res.data.unshift(...col.options);
this.$set(
col,
"options",
"list" in res.data
? res.data.list.map((i) => ({
label: col.optionLabel ? i[col.optionLabel] : i.name,
value: col.optionValue ? i[col.optionValue] : i.id,
}))
: res.data.map((i) => ({
label: col.optionLabel ? i[col.optionLabel] : i.name,
value: col.optionValue ? i[col.optionValue] : i.id,
}))
);
}
} else {
col.options.splice(0);
}
// dataForm[col.prop] = col.default ?? null; // not perfect!
});
else if (col.fetchTreeData) {
// parentId 0
col.fetchTreeData().then(({ data: res }) => {
console.log("[Fetch Tree Data]", res.data);
if (res.code === 0) {
//
const obj = {};
if ("list" in res.data) {
res.data.list.map((item) => {
obj[item.id] = item;
});
} else if (Array.isArray(res.data)) {
res.data.map((item) => {
obj[item.id] = item;
});
}
//
let filteredList = reConstructTreeData(obj);
console.log("** filteredList **", filteredList);
// options
this.$set(col, "options", filteredList);
} else {
col.options.splice(0);
this.$message.error(res.msg);
}
});
}
});
});
return {
// configs,
btnLoading: false,
loadingStatus: false,
activeMenu: this.configs.menu[0].name,
dataForm,
detailMode: false,
autoDisabledQueue,
watingToRefreshQueue,
cached,
showBaseDialog: false,
baseDialogConfig: null,
subList: [],
showSubDialog: false,
disableXXX: false,
defaultQuillConfig: {
modules: {
toolbar: [
[{ font: [] }],
[{ size: ["small", false, "large", "huge"] }], // custom dropdown
["bold", "italic", "underline", "strike"], // toggled buttons
[{ color: [] }, { background: [] }], // dropdown with defaults from theme
["blockquote", "code-block"],
[{ header: 1 }, { header: 2 }], // custom button values
[{ list: "ordered" }, { list: "bullet" }],
// [{ 'script': 'sub'}, { 'script': 'super' }], // superscript/subscript
[{ indent: "-1" }, { indent: "+1" }], // outdent/indent
// [{ 'direction': 'rtl' }], // text direction
// [{ 'header': [1, 2, 3, 4, 5, 6, false] }],
// [{ 'align': [] }],
// ['clean'] // remove formatting button
],
},
theme: "snow",
readOnly: false,
placeholder: "在这里输入描述信息...",
scrollingContainer: null,
},
attrPage: 1,
attrSize: 10,
attrTotal: 0,
fileList: [],
imgPreviewDialogVisible: false,
currentImgUrl: "",
};
},
mounted() {
this.configs.form.rows.forEach((row) => {
row.forEach((col) => {
if (col.changeReflects && typeof col.changeReflects === 'object' && 'fromKey' in col.changeReflects && 'toProp' in col.changeReflects) {
this.$watch(
() => this.dataForm[col.prop],
val => {
if (val && (col.prop in this.cached)) {
console.log("here changeReflects", col.prop, col.changeReflects.toProp, this.cached[col.prop])
if (typeof col.changeReflects.fromKey === 'string') {
this.dataForm[col.changeReflects.toProp] = this.cached[col.prop].find(item => item.id === val)?.[col.changeReflects.fromKey]
} else if (Array.isArray(col.changeReflects.fromKey) && col.changeReflects.delimiter) {
const foundItem = this.dataForm[col.changeReflects.toProp] = this.cached[col.prop].find(item => item.id === val)
if (foundItem) {
const values = col.changeReflects.fromKey.map(key => foundItem[key])
this.dataForm[col.changeReflects.toProp] = values.join(col.changeReflects.delimiter)
} else {
this.dataForm[col.changeReflects.toProp] = col.changeReflects.delimiter
console.log("[DialogWithMenu] mounted() 没找到对应数据")
}
}
}
},
{
immediate: false
}
)
}
});
});
},
watch: {
dialogVisible: function (val) {
if (!!val) {
this.attrPage = 1
this.attrSize = 10
}
},
},
computed: {
actualMenus() {
return this.configs.menu.filter((m) => {
if (m.onlyEditMode && !this.dataForm.id) {
return false;
}
return true;
});
},
filteredTableProps() {
return this.detailMode ? this.configs.table.props.filter((v) => v.prop !== "operations") : this.configs.table.props;
},
uploadHeaders() {
return {
token: Cookies.get("token") || "",
};
},
uploadUrl() {
return this.configs.menu.find((item) => item.key === "attachment")?.actionUrl || "#";
},
},
methods: {
disableCondition(prop) {
return this.detailMode || (this.disableXXX && this.autoDisabledQueue.indexOf(prop) !== -1);
},
/** utitilities */
showButton(operate) {
const notDetailMode = !this.detailMode;
const showAlways = operate.showAlways ?? false;
const editMode = operate.showOnEdit && this.dataForm.id;
const addMode = !operate.showOnEdit && !this.dataForm.id;
const permission = operate.permission ? this.$hasPermission(operate.permission) : true;
const currentMenuKey = this.configs.menu.find((item) => item.name === this.activeMenu)?.key;
return notDetailMode && (showAlways || ((editMode || addMode) && permission)) && currentMenuKey === "info";
},
resetForm(excludeId = false, immediate = false) {
setTimeout(
() => {
Object.keys(this.dataForm).forEach((key) => {
if (excludeId && key === "id") return;
if ("files" in this.dataForm) this.dataForm.files = [];
if ("fileIds" in this.dataForm) this.dataForm.fileIds = [];
else this.dataForm[key] = null;
if (Array.isArray(this.fileList)) {
this.fileList = [];
}
});
this.activeMenu = this.configs.menu[0].name;
this.$refs.dataForm[0].clearValidate();
},
immediate ? 0 : 200
);
},
updateOptions() {
return new Promise((resolve, reject) => {
if (this.watingToRefreshQueue.length) {
this.watingToRefreshQueue.forEach((opt) => {
console.log("[刷新数据, ", opt, "]");
if ("fetchData" in opt) {
opt.fetchData(this.dataForm.id ? this.dataForm.id : -1).then(({ data: res }) => {
if (res.code === 0) {
this.$set(
opt,
"options",
"list" in res.data
? res.data.list.map((i) => ({ label: i.code, value: i.id }))
: res.data.map((i) => ({ label: i.code, value: i.id }))
);
resolve({ done: true });
} else {
this.$message({
message: `${res.code}: ${res.msg}`,
type: "error",
duration: 1500,
});
resolve({ done: false });
}
});
}
});
} else resolve(null);
});
},
/** init **/
init(id, detailMode, menu) {
// this.dialogVisible = true;
if (this.$refs.dataForm && this.$refs.dataForm.length) {
// dialog dataForm [0]
this.$refs.dataForm[0].clearValidate();
}
console.log("[dialog] DialogWithHead init():", id, detailMode);
this.detailMode = detailMode ?? false;
this.$nextTick(() => {
this.dataForm.id = id || null;
if (this.dataForm.id) {
//
this.loadingStatus = true;
//
this.getSubList();
//
this.updateOptions().then((result) => {
if (result === null || (typeof result === "object" && result.done)) {
this.$http.get(this.urls.base + `/${this.dataForm.id}`).then(({ data: res }) => {
if (res && res.code === 0) {
const dataFormKeys = Object.keys(this.dataForm);
this.dataForm = __pick(res.data, dataFormKeys);
if ("files" in res.data) {
console.log("[DialogWithMenu] fileList===>", res.data.files, this.fileList);
/** 返回的文件列表 */
this.fileList = res.data.files
? res.data.files.map((file) => ({
id: file.id,
name: file.fileUrl.split("/").pop(),
url: file.fileUrl,
typeCode: file.typeCode,
}))
: [];
}
}
this.loadingStatus = false;
//
if (menu && menu.key) {
this.activeMenu = this.configs.menu.find((item) => item.key === menu.key)?.name;
}
});
}
});
} else {
//
this.updateOptions();
}
});
},
/** handlers */
handleFileClick(type, file) {
switch (type) {
case "view": {
//
this.$http
.get("/pms/attachment/downloadFile", {
params: {
attachmentId: file.id,
type: 0, // 0 1
},
responseType: "blob",
})
.then(({ data: res }) => {
console.log("preivew", res);
if (/image/i.test(res.type)) {
//
this.currentImgUrl = URL.createObjectURL(res);
this.imgPreviewDialogVisible = true;
} else if (/pdf/i.test(res.type)) {
// pdf
let a = document.createElement('a')
a.setAttribute('target', '_blank')
a.href = URL.createObjectURL(res)
a.click()
console.log('before remove a ', a)
a.remove()
console.log('removed a ', a)
} else {
this.$message({
message: "非图片和PDF文件请下载后预览",
type: "error",
duration: 1500,
});
}
});
break;
}
case "download": {
//
this.$http
.get("/pms/attachment/downloadFile", {
params: {
attachmentId: file.id,
type: 1, // 0 1
},
responseType: "blob",
})
.then(({ data: res }) => {
const blob = new Blob([res]);
/** 通知 */
this.$notify({
title: "成功",
message: "开始下载",
type: "success",
duration: 1200,
});
if ("download" in document.createElement("a")) {
const alink = document.createElement("a");
alink.download = file.name;
alink.style.display = "none";
alink.target = "_blank";
alink.href = URL.createObjectURL(blob);
document.body.appendChild(alink);
alink.click();
URL.revokeObjectURL(alink.href);
document.body.removeChild(alink);
} else {
navigator.msSaveBlob(blob, fileName);
}
});
break;
}
case "delete": {
return this.$confirm(`确定删除图片: ${file.name}`, "提示", {
confirmButtonText: "确认",
cancelButtonText: "我再想想",
type: "warning",
})
.then(() => {
this.loadingStatus = true;
const newFilelist = this.fileList.filter((f) => f.id !== file.id);
this.updateRemoteFiles(newFilelist).then((msg) => {
if (msg && msg === "success") {
this.fileList = newFilelist;
this.loadingStatus = false;
/** 通知 */
this.$notify({
title: "成功",
message: "已删除",
type: "success",
duration: 1200,
});
}
});
})
.catch((err) => { });
}
}
},
handleUploadSuccess(response, file, fileList) {
console.log("[DialogWithMenu] uploadedFileList", response, file, fileList);
if (response.code === 0) {
const uploadedFile = response.data[0];
const fileItem = {
id: uploadedFile.id,
name: uploadedFile.fileUrl.split("/").pop(),
url: uploadedFile.fileUrl,
typeCode: file.typeCode,
};
this.loadingStatus = true;
this.updateRemoteFiles([...this.fileList, fileItem]).then((msg) => {
if (msg && msg === "success") {
this.fileList.push(fileItem);
this.loadingStatus = false;
/** 通知 */
this.$notify({
title: "成功",
message: "上传成功",
type: "success",
duration: 1200,
});
}
});
}
},
updateRemoteFiles(filelist) {
return this.$http
.put("/pms/product", {
id: "id" in this.dataForm ? this.dataForm.id : "DEFAULT_ID",
fileIds: filelist.map((f) => f.id),
})
.then(({ data: res }) => {
if (res.code === 0) return "success";
});
},
handleUploadCheck(file) {
console.log("[before upload]", file);
const LIMIT = 2 * 1024 * 1024; // bytes
if (file.size > LIMIT) {
this.$message({
message: "文件大小不能超过 2MB",
type: "error",
duration: 1500,
});
return false;
} else return true;
},
handleComponentModelUpdate(propName, { subject, payload: { data } }) {
this.dataForm[propName] = JSON.stringify(data);
console.log("[DialogJustForm] handleComponentModelUpdate", this.dataForm[propName]);
},
handleSelectChange(col, eventValue) {
console.log("[dialog] select change: ", col, eventValue);
},
handleSwitchChange(val) {
console.log("[dialog] switch change: ", val, this.dataForm);
},
handleBtnClick(payload) {
console.log("btn click payload: ", payload);
if ("name" in payload) {
switch (payload.name) {
case "cancel":
this.handleClose();
break;
case "reset":
this.resetForm(true, true); // true means exclude id
break;
case "add":
case "update": {
this.$refs.dataForm[0].validate((passed, result) => {
if (passed) {
//
this.btnLoading = true
this.loadingStatus = true;
const method = payload.name === "add" ? "POST" : "PUT";
//
const hasAttachment = !!this.configs.menu.find((item) => item.key === "attachment");
if (hasAttachment) {
const fileIds = this.fileList.map((item) => item.id);
this.$set(this.dataForm, "fileIds", fileIds);
}
// id
let extraIds = {};
if (this.configs.extraIds && typeof this.configs.extraIds === "object") {
// extraIds
Object.entries(this.configs.extraIds).forEach(([key, value]) => {
extraIds[key] = value;
});
}
//
this.btnLoading = true
this.$http({
url: this.urls.base,
method,
data: {
...extraIds,
...this.dataForm,
},
})
.then(({ data: res }) => {
this.btnLoading = false
this.loadingStatus = false;
console.log("[add&update] res is: ", res);
if (res.code === 0) {
this.$message.success(payload.name === "add" ? "添加成功" : "更新成功");
this.$emit("refreshDataList");
// watingToRefreshQueue
// if (this.watingToRefreshQueue.length) {
// //
// this.watingToRefreshQueue.forEach((opt) => {
// console.log("[, ", opt, "]");
// if ("fetchData" in opt) {
// opt.fetchData().then(({ data: res }) => {
// if (res.code === 0) {
// this.$set(
// opt,
// "options",
// "list" in res.data
// ? res.data.list.map((i) => ({ label: i.name, value: i.id }))
// : res.data.map((i) => ({ label: i.name, value: i.id }))
// );
// }
// });
// }
// });
// }
this.handleClose();
} else {
this.$message({
message: `${res.code}: ${res.msg}`,
type: "error",
duration: 2000,
});
if (this.btnLoading) this.btnLoading = false
}
})
.catch((errMsg) => {
this.$message.error("参数错误:" + errMsg);
if (this.loadingStatus) this.loadingStatus = false;
if (this.btnLoading) this.btnLoading = false
});
} else {
this.$message.error("请核查字段信息");
}
});
}
}
}
},
handleTabClick(payload) {
// console.log("tab click payload: ", this.activeMenu);
// if (this.activeMenu === this.configs.menu[1].name) {
// //
// this.getSubList();
// }
},
handlePageChange(val) {
this.getSubList(val, this.attrSize);
},
handleSizeChange(val) {
this.attrPage = 1;
this.attrSize = val
this.getSubList(1, val);
},
getSubList(page, size) {
const params = {};
params.page = page ?? this.attrPage;
params.limit = size ?? this.attrSize;
const requiredParams = this.configs.table.extraParams;
if (requiredParams) {
if (Array.isArray(requiredParams)) {
requiredParams.forEach((str) => {
if (/id/i.test(str)) {
params[str] = this.dataForm.id;
} else {
params[str] = "";
}
});
} else if (typeof requiredParams === "string") {
//
params[this.configs.table.extraParams] = this.dataForm.id;
// dataForm.id
}
}
this.$http.get(this.urls.subpage, { params }).then(({ data: res }) => {
console.log("[DialogWithMenu] getSubList:", res);
if (res.code === 0 && res.data?.list) {
//
this.subList = res.data.list;
this.attrTotal = res.data.total;
} else {
this.subList.splice(0);
this.attrTotal = 0;
}
});
},
handleAddParam(id) {
this.showSubDialog = true;
this.$nextTick(() => {
this.$refs.subDialog.init(id ?? null);
});
},
handleClose() {
this.resetForm();
this.$emit("update:dialogVisible", false);
},
/** 列表handlers */
handleAddItem() {
// console.log('[dialog] handleAddItem ot list...');
this.showBaseDialog = true;
this.$nextTick(() => {
console.log("[sub-dialog] ", this.$refs["sub-dialog"].init());
});
},
handleTableRowOperate({ type, data }) {
console.log("handleTableRowOperate", type, data);
switch (type) {
case "delete": {
//
console.log('delete....', data)
const itemName = typeof data === 'object' ? (data.attrName || data.name || data.material || data.id) : data
return this.$confirm(`是否删除条目: ${itemName}`, "提示", {
confirmButtonText: "确认",
cancelButtonText: "我再想想",
type: "warning",
})
.then(() => {
// this.$http.delete(this.urls.base + `/${data}`).then((res) => {
this.$http({
url: this.urls.subase,
method: "DELETE",
data: [`${data.id}`],
}).then(({ data: res }) => {
if (res.code === 0) {
this.$message.success({
message: "删除成功!",
duration: 1000,
onClose: () => {
this.getSubList(1, 20);
},
});
}
});
})
.catch((err) => { });
}
case "edit": {
this.handleAddParam(data); /** data is ==> id */
break;
}
// case 'view-detail-action':
// this.openDialog(data, true);
// break;
}
},
},
};
</script>
<style scoped>
.el-menu {
margin: 16px 0 !important;
}
.el-menu.el-menu--horizontal {
border: none !important;
/* background: #0f02 !important; */
}
/* .el-menu--horizontal > .el-menu-item.is-active { */
/* border-bottom-color: #0b58ff; */
/* } */
.dialog-with-menu>>>.el-dialog__body {
/* padding-top: 16px !important;
padding-bottom: 16px !important; */
padding-top: 0 !important;
padding-bottom: 0 !important;
}
.el-select,
.el-cascader {
width: 100% !important;
}
.dialog-with-menu>>>.el-dialog__header {
padding: 10px 20px 10px;
/* background: linear-gradient(to bottom, rgba(0, 0, 0, 0.25), white); */
}
.relative {
position: relative;
}
.at-right-top {
position: absolute;
top: 0;
right: 0;
z-index: 10000;
}
ul.file-list,
ul.file-list>li {
padding: 0;
margin: 0;
list-style: none;
}
.file-list {
max-height: 20vh;
overflow-y: auto;
margin-top: 12px;
/* width: 240px; */
display: flex;
flex-direction: column;
}
ul.file-list>li {
border-radius: 4px;
background-color: #edededd2;
padding: 8px;
margin-bottom: 2px;
display: flex;
justify-content: space-between;
}
ul.file-list>li:hover {
background-color: #ededed;
}
.file-operations {
display: flex;
}
.file-icon {
margin-right: 8px;
font-size: 16px;
line-height: 1;
display: flex;
place-content: center;
width: 16px;
height: 16px;
}
/* .image-preview-dialog {
} */
.force-disabled {
margin-top: 42px;
}
</style>

View File

@ -46,35 +46,36 @@
}}文件大小不超过2MB }}文件大小不超过2MB
</div> </div>
</el-upload> </el-upload>
<!-- <div
class="file-list__item"
v-for="n in 9"
:key="n"
:style="{
display: n > 4 && !expand ? 'none' : 'block',
}"
:data-name="n"
:class="{ 'default-icon': !isPicMode }">
<i class="el-icon-delete"></i>
</div> -->
<div <div
class="file-list__item"
v-for="(file, index) in files" v-for="(file, index) in files"
:key="file.fileName" :key="file.fileName"
:style="{ style="width: 100%">
background: isPicMode <div
? `url(${file.fileUrl}) no-repeat` class="file-list__item"
: `url(${defaultBg}) no-repeat`, v-if="!isPicMode"
backgroundSize: isPicMode ? '100% 100%' : '64px', :style="{
backgroundPosition: isPicMode ? '0% 0%' : 'center', background: isPicMode
}" ? `url(${file.fileUrl}) no-repeat`
:data-name="file.fileName"> : `url(${defaultBg}) no-repeat`,
<el-button backgroundSize: isPicMode ? '100% 100%' : '64px',
v-if="!disabled" backgroundPosition: isPicMode ? '0% 0%' : 'center',
type="text" }"
class="el-icon-delete" @click="handleDownload(file)"
style="padding: 0" :data-name="file.fileName">
@click="(e) => handleDelete(file)" /> <el-button
v-if="!disabled"
type="text"
class="el-icon-delete"
style="padding: 0"
@click="(e) => handleDelete(file)" />
</div>
<el-image
v-else
class="file-list__item"
style="width: 100%"
:src="file.fileUrl"
:preview-src-list="files.map((item) => item.fileUrl)"></el-image>
</div> </div>
</section> </section>
</div> </div>
@ -189,6 +190,32 @@ export default {
}, 500); }, 500);
}, },
async handleDownload(file) {
if (this.isPicMode) {
// this.$emit('preview', file);
const link = document.createElement('a');
link.href = file.fileUrl;
link.target = '_blank';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
} else {
// this.$emit('download', file);
const data = await this.$axios({
url: file.fileUrl,
method: 'get',
responseType: 'blob',
});
const link = document.createElement('a');
link.href = window.URL.createObjectURL(new Blob([data]));
link.download = file.fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(link.href);
}
},
emitFilelist() { emitFilelist() {
this.$emit('update', this.files); this.$emit('update', this.files);
}, },

View File

@ -42,16 +42,26 @@
v-model="form" /> v-model="form" />
</div> </div>
<div v-if="section.key == 'attrs'" style="margin-top: 12px"> <div
v-if="section.key == 'attrs'"
style="margin-top: 12px; position: relative">
<div
v-if="!mode.includes('detail')"
style="position: absolute; top: -40px; right: 0">
<el-button @click="handleAddAttr" type="text">
<i class="el-icon-plus"></i>
添加属性
</el-button>
</div>
<base-table <base-table
v-loading="attrListLoading" v-loading="attrListLoading"
:table-props="section.props" :table-props="section.props"
:page="attrQuery?.params.pageNo || 1" :page="attrQuery?.params.pageNo || 1"
:limit="attrQuery?.params.pageSize || 10" :limit="attrQuery?.params.pageSize || 10"
:table-data="list" :table-data="list"
:add-button-show="mode.includes('detail') ? null : '添加属性'"
@emitButtonClick="handleAddAttr"
@emitFun="handleEmitFun"> @emitFun="handleEmitFun">
<!-- :add-button-show="mode.includes('detail') ? null : '添加属性'"
@emitButtonClick="handleAddAttr" -->
<method-btn <method-btn
v-if="section.tableBtn" v-if="section.tableBtn"
slot="handleBtn" slot="handleBtn"
@ -76,7 +86,7 @@
<el-button v-if="mode == 'detail'" type="primary" @click="toggleEdit"> <el-button v-if="mode == 'detail'" type="primary" @click="toggleEdit">
编辑 编辑
</el-button> </el-button>
<el-button v-else type="primary" @click="handleConfirm">确定</el-button> <el-button v-else type="primary" @click="handleConfirm">保存</el-button>
<!-- sections的第二项必须是 属性列表 --> <!-- sections的第二项必须是 属性列表 -->
<!-- <el-button <!-- <el-button
v-if="sections[1].allowAdd" v-if="sections[1].allowAdd"
@ -162,7 +172,9 @@ export default {
input: true, input: true,
label: '属性名称', label: '属性名称',
prop: 'name', prop: 'name',
rules: [{ required: true, message: '属性名称不能为空', trigger: 'blur' }], rules: [
{ required: true, message: '属性名称不能为空', trigger: 'blur' },
],
}, },
], ],
[ [

View File

@ -1,29 +1,62 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<!-- 搜索工作栏 --> <!-- 搜索工作栏 -->
<SearchBar :formConfigs="searchBarFormConfig" ref="search-bar" @headBtnClick="handleSearchBarBtnClick" /> <SearchBar
:formConfigs="searchBarFormConfig"
ref="search-bar"
@headBtnClick="handleSearchBarBtnClick" />
<!-- 列表 --> <!-- 列表 -->
<base-table :table-props="tableProps" :page="queryParams.pageNo" :limit="queryParams.pageSize" :table-data="list" <base-table
:table-props="tableProps"
:page="queryParams.pageNo"
:limit="queryParams.pageSize"
:table-data="list"
@emitFun="handleEmitFun"> @emitFun="handleEmitFun">
<method-btn v-if="tableBtn.length" slot="handleBtn" :width="120" label="操作" :method-list="tableBtn" <method-btn
v-if="tableBtn.length"
slot="handleBtn"
:width="120"
label="操作"
:method-list="tableBtn"
@clickBtn="handleTableBtnClick" /> @clickBtn="handleTableBtnClick" />
</base-table> </base-table>
<!-- 分页组件 --> <!-- 分页组件 -->
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" <pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNo"
:limit.sync="queryParams.pageSize"
@pagination="getList" /> @pagination="getList" />
<!-- 对话框(添加) --> <!-- 对话框(添加) -->
<base-dialog :dialogTitle="title" :dialogVisible="open" @close="cancel" @cancel="cancel" width="60%" <base-dialog
:dialogTitle="title"
:dialogVisible="open"
@close="cancel"
@cancel="cancel"
width="60%"
@confirm="submitForm"> @confirm="submitForm">
<DialogForm v-if="open" key="index-dialog-form" ref="form" label-position="top" size="small" v-model="form" <DialogForm
v-if="open"
key="index-dialog-form"
ref="form"
label-position="top"
size="small"
v-model="form"
:has-files="['files', 'files2']"
:rows="computedRows" /> :rows="computedRows" />
</base-dialog> </base-dialog>
<!-- 设备 详情 - 编辑 --> <!-- 设备 详情 - 编辑 -->
<EquipmentDrawer v-if="editVisible" ref="drawer" :mode="editMode" @update-mode="editMode = $event" <EquipmentDrawer
:data-id="form.id" :sections="[ v-if="editVisible"
ref="drawer"
:mode="editMode"
@update-mode="editMode = $event"
:data-id="form.id"
:sections="[
{ {
name: '基本信息', name: '基本信息',
key: 'base', key: 'base',
@ -50,20 +83,23 @@
tableBtn: [ tableBtn: [
this.$auth.hasPermi('base:core-equipment-attr:update') this.$auth.hasPermi('base:core-equipment-attr:update')
? { ? {
type: 'edit', type: 'edit',
btnName: '修改', btnName: '修改',
} }
: undefined, : undefined,
this.$auth.hasPermi('base:core-equipment-attr:delete') this.$auth.hasPermi('base:core-equipment-attr:delete')
? { ? {
type: 'delete', type: 'delete',
btnName: '删除', btnName: '删除',
} }
: undefined, : undefined,
].filter((v) => v), ].filter((v) => v),
allowAdd: true, allowAdd: true,
}, },
]" @refreshDataList="getList" @cancel="cancelEdit" @destroy="cancelEdit" /> ]"
@refreshDataList="getList"
@cancel="cancelEdit"
@destroy="cancelEdit" />
</div> </div>
</template> </template>
@ -96,21 +132,21 @@ export default {
tableBtn: [ tableBtn: [
this.$auth.hasPermi(`base:core-equipment:update`) this.$auth.hasPermi(`base:core-equipment:update`)
? { ? {
type: 'detail', type: 'detail',
btnName: '详情', btnName: '详情',
} }
: undefined, : undefined,
this.$auth.hasPermi('base:core-equipment:update') this.$auth.hasPermi('base:core-equipment:update')
? { ? {
type: 'edit', type: 'edit',
btnName: '修改', btnName: '修改',
} }
: undefined, : undefined,
this.$auth.hasPermi('base:core-equipment:delete') this.$auth.hasPermi('base:core-equipment:delete')
? { ? {
type: 'delete', type: 'delete',
btnName: '删除', btnName: '删除',
} }
: undefined, : undefined,
].filter((v) => v), ].filter((v) => v),
tableProps: [ tableProps: [
@ -176,14 +212,18 @@ export default {
type: 'separate', type: 'separate',
}, },
{ {
type: this.$auth.hasPermi('base:core-equipment:export') ? 'button' : '', type: this.$auth.hasPermi('base:core-equipment:export')
? 'button'
: '',
btnName: '导出', btnName: '导出',
name: 'export', name: 'export',
plain: true, plain: true,
color: 'primary', color: 'primary',
}, },
{ {
type: this.$auth.hasPermi('base:core-equipment:create') ? 'button' : '', type: this.$auth.hasPermi('base:core-equipment:create')
? 'button'
: '',
btnName: '新增', btnName: '新增',
name: 'add', name: 'add',
plain: true, plain: true,
@ -196,7 +236,9 @@ export default {
input: true, input: true,
label: '设备名称', label: '设备名称',
prop: 'name', prop: 'name',
rules: [{ required: true, message: '设备名称不能为空', trigger: 'blur' }], rules: [
{ required: true, message: '设备名称不能为空', trigger: 'blur' },
],
// bind: { // bind: {
// disabled: this.editMode == 'detail', // some condition, like detail mode... // disabled: this.editMode == 'detail', // some condition, like detail mode...
// } // }
@ -225,7 +267,9 @@ export default {
label: '设备类型', label: '设备类型',
prop: 'equipmentTypeId', prop: 'equipmentTypeId',
url: '/base/core-equipment-type/page?pageNo=1&pageSize=100', url: '/base/core-equipment-type/page?pageNo=1&pageSize=100',
rules: [{ required: true, message: '设备类型不能为空', trigger: 'blur' }], rules: [
{ required: true, message: '设备类型不能为空', trigger: 'blur' },
],
bind: { bind: {
filterable: true, filterable: true,
}, },
@ -235,7 +279,11 @@ export default {
label: '预计生产时间(min/天)', label: '预计生产时间(min/天)',
prop: 'workTime', prop: 'workTime',
rules: [ rules: [
{ required: true, message: '预计生产时间不能为空', trigger: 'blur' }, {
required: true,
message: '预计生产时间不能为空',
trigger: 'blur',
},
{ {
type: 'number', type: 'number',
message: '请输入正确的数字值', message: '请输入正确的数字值',
@ -291,7 +339,11 @@ export default {
label: '单件产品加工时间(s)', label: '单件产品加工时间(s)',
prop: 'processingTime', prop: 'processingTime',
rules: [ rules: [
{ required: true, message: '单件产品加工时间不能为空', trigger: 'blur' }, {
required: true,
message: '单件产品加工时间不能为空',
trigger: 'blur',
},
{ {
type: 'number', type: 'number',
message: '请输入正确的数字值', message: '请输入正确的数字值',
@ -322,13 +374,19 @@ export default {
[ [
{ {
upload: true, upload: true,
label: '上传资料', label: '设备资料',
prop: 'files', prop: 'files',
}, },
], ],
[ [
{ input: true, label: '备注', prop: 'remark' } {
upload: true,
label: '设备图片',
prop: 'files2',
fileType: 1,
},
], ],
[{ input: true, label: '备注', prop: 'remark' }],
// [ // [
// { // {
// assetUpload: true, // assetUpload: true,
@ -429,7 +487,7 @@ export default {
// //
form: { form: {
id: null, id: null,
files: [] files: [],
}, },
showUploadComponents: false, // showUploadComponents: false, //
}; };
@ -441,36 +499,36 @@ export default {
computedRows() { computedRows() {
return this.showUploadComponents return this.showUploadComponents
? [ ? [
...this.rows, ...this.rows,
[ [
{ {
assetUpload: true, assetUpload: true,
key: 'eq-assets', // key: 'eq-assets', //
label: '上传资料', label: '上传资料',
fieldName: 'assets', fieldName: 'assets',
subcomponent: AssetsUpload, subcomponent: AssetsUpload,
prop: 'uploadedAssets', prop: 'uploadedAssets',
default: [], default: [],
bind: { bind: {
'is-pic-mode': false, 'is-pic-mode': false,
},
}, },
}, ],
], [
[ {
{ assetUpload: true,
assetUpload: true, key: 'eq-pics', //
key: 'eq-pics', // label: '上传图片',
label: '上传图片', fieldName: 'images',
fieldName: 'images', subcomponent: AssetsUpload,
subcomponent: AssetsUpload, // prop: '',
// prop: '', // default: [],
// default: [], bind: {
bind: { 'is-pic-mode': true,
'is-pic-mode': true, },
}, },
}, ],
], ]
]
: this.rows; : this.rows;
}, },
}, },
@ -512,7 +570,8 @@ export default {
spec: undefined, spec: undefined,
description: undefined, description: undefined,
remark: undefined, remark: undefined,
files: [] files: [],
files2: [],
}; };
this.resetForm('form'); this.resetForm('form');
}, },
@ -540,9 +599,12 @@ export default {
if (!valid) { if (!valid) {
return; return;
} }
const payload = Object.assign({}, this.form);
payload.files = [...payload.files, ...payload.files2];
delete payload.files2;
// //
if (this.form.id != null) { if (this.form.id != null) {
updateEquipment(this.form).then((response) => { updateEquipment(payload).then((response) => {
this.$modal.msgSuccess('修改成功'); this.$modal.msgSuccess('修改成功');
this.open = false; this.open = false;
this.getList(); this.getList();
@ -550,7 +612,7 @@ export default {
return; return;
} }
// //
createEquipment(this.form).then((response) => { createEquipment(payload).then((response) => {
this.$modal.msgSuccess('新增成功'); this.$modal.msgSuccess('新增成功');
this.open = false; this.open = false;
this.getList(); this.getList();
@ -569,7 +631,7 @@ export default {
this.getList(); this.getList();
this.$modal.msgSuccess('删除成功'); this.$modal.msgSuccess('删除成功');
}) })
.catch(() => { }); .catch(() => {});
}, },
/** 导出按钮操作 */ /** 导出按钮操作 */
handleExport() { handleExport() {
@ -587,7 +649,7 @@ export default {
this.$download.excel(response, '设备.xls'); this.$download.excel(response, '设备.xls');
this.exportLoading = false; this.exportLoading = false;
}) })
.catch(() => { }); .catch(() => {});
}, },
// //
viewDetail(id) { viewDetail(id) {

View File

@ -2,7 +2,7 @@
* @Author: zwq * @Author: zwq
* @Date: 2021-11-18 14:16:25 * @Date: 2021-11-18 14:16:25
* @LastEditors: DY * @LastEditors: DY
* @LastEditTime: 2023-11-25 11:25:23 * @LastEditTime: 2023-11-27 20:12:00
* @Description: * @Description:
--> -->
<template> <template>
@ -11,7 +11,7 @@
:rules="dataRule" :rules="dataRule"
ref="dataForm" ref="dataForm"
@keyup.enter.native="dataFormSubmit()" @keyup.enter.native="dataFormSubmit()"
label-width="100px"> label-width="90px">
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="原料名称" prop="name"> <el-form-item label="原料名称" prop="name">

View File

@ -29,7 +29,7 @@
@cancel="handleCancel" @cancel="handleCancel"
@confirm="handleConfirm" @confirm="handleConfirm"
:before-close="handleCancel" :before-close="handleCancel"
width="50%"> width="45%">
<add-or-update <add-or-update
ref="addOrUpdate" ref="addOrUpdate"
@refreshDataList="successSubmit"></add-or-update> @refreshDataList="successSubmit"></add-or-update>

View File

@ -2,14 +2,14 @@
* @Author: zwq * @Author: zwq
* @Date: 2021-11-18 14:16:25 * @Date: 2021-11-18 14:16:25
* @LastEditors: DY * @LastEditors: DY
* @LastEditTime: 2023-11-27 09:23:56 * @LastEditTime: 2023-11-27 20:07:09
* @Description: * @Description:
--> -->
<template> <template>
<el-drawer <el-drawer
:visible.sync="visible" :visible.sync="visible"
:show-close="false" :show-close="false"
:wrapper-closable="false" :wrapper-closable="isdetail"
class="drawer" class="drawer"
size="60%"> size="60%">
<small-title slot="title" :no-padding="true"> <small-title slot="title" :no-padding="true">
@ -114,14 +114,6 @@
</el-row> </el-row>
</el-form> </el-form>
</div> </div>
<div class="drawer-body__footer">
<el-button v-if="!idAttrShow" @click="goback()">取消</el-button>
<el-button v-else :disabled="isdetail" @click="init(dataForm.id)">重置</el-button>
<el-button v-if="isdetail" type="primary" @click="goEdit()">
编辑
</el-button>
<el-button v-else type="primary" @click="dataFormSubmit()">确定</el-button>
</div>
<div class="attr-list" v-if="idAttrShow"> <div class="attr-list" v-if="idAttrShow">
<small-title <small-title
@ -158,14 +150,16 @@
:limit.sync="listQuery.pageSize" :limit.sync="listQuery.pageSize"
:page-sizes="[5, 10, 15]" :page-sizes="[5, 10, 15]"
@pagination="getList" /> @pagination="getList" />
<div class="drawer-body__footer">
<el-button type="primary" @click="goback()">关闭</el-button>
</div>
</div> </div>
</div> </div>
<div v-if="!isdetail" class="drawer-body__footer">
<el-button @click="goback()">取消</el-button>
<el-button :disabled="isdetail" @click="init(dataForm.id)">重置</el-button>
<el-button type="primary" @click="dataFormSubmit()">确定</el-button>
</div>
<attr-add <attr-add
v-if="addOrUpdateVisible" v-if="addOrUpdateVisible"
ref="addOrUpdate" ref="addOrUpdate"
@ -270,11 +264,7 @@ export default {
handleClick(raw) { handleClick(raw) {
if (raw.type === 'delete') { if (raw.type === 'delete') {
this.$confirm( this.$confirm(
`确定对${ `是否确认删除属性名为"${raw.data.name}"的数据项?`,
raw.data.attrName
? '[名称=' + raw.data.attrName + ']'
: '[序号=' + raw.data._pageIndex + ']'
}进行删除操作?`,
'提示', '提示',
{ {
confirmButtonText: '确定', confirmButtonText: '确定',

View File

@ -84,18 +84,18 @@ export default {
}, },
tableProps, tableProps,
tableBtn: [ tableBtn: [
this.$auth.hasPermi(`base:core-product:detail`)
? {
type: 'detail',
btnName: '查看详情',
}
: undefined,
this.$auth.hasPermi(`base:core-product:update`) this.$auth.hasPermi(`base:core-product:update`)
? { ? {
type: 'edit', type: 'edit',
btnName: '编辑', btnName: '编辑',
} }
: undefined, : undefined,
this.$auth.hasPermi(`base:core-product:detail`)
? {
type: 'detail',
btnName: '查看详情',
}
: undefined,
this.$auth.hasPermi(`base:core-product:delete`) this.$auth.hasPermi(`base:core-product:delete`)
? { ? {
type: 'delete', type: 'delete',
@ -141,6 +141,27 @@ export default {
}, },
created() {}, created() {},
methods: { methods: {
//
deleteHandle(id, name, index) {
this.$confirm(`是否确认删除产品名称为"${name}"的数据项`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
this.urlOptions.deleteURL(id).then(({ data }) => {
this.$message({
message: "操作成功",
type: "success",
duration: 1500,
onClose: () => {
this.getDataList();
},
});
});
})
.catch(() => { });
},
// //
otherMethods(val) { otherMethods(val) {
if (val.type === 'detail') { if (val.type === 'detail') {

View File

@ -105,7 +105,7 @@ export default {
formConfig: [ formConfig: [
{ {
type: 'input', type: 'input',
label: '关键字', label: '供应商',
placeholder: '供应商名称', placeholder: '供应商名称',
param: 'name', param: 'name',
}, },

View File

@ -1,21 +1,19 @@
<template> <template>
<el-form ref="dataForm" :rules="rules" label-width="130px" :model="dataForm"> <el-form ref="dataForm" :rules="rules" label-width="130px" :model="dataForm" label-position="top">
<el-row> <el-row :gutter="20">
<el-col :span='12'> <el-col :span='8'>
<el-form-item label="工单名称" prop="name"> <el-form-item label="工单名称" prop="name">
<el-input v-model="dataForm.name"></el-input> <el-input v-model="dataForm.name" placeholder="请输入工单名称"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span='12'> <el-col :span='8'>
<el-form-item label="工单编码" prop="code"> <el-form-item label="工单编码" prop="code">
<el-input v-model="dataForm.code" disabled></el-input> <el-input v-model="dataForm.code" disabled placeholder="请输入工单编码"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <el-col :span='8'>
<el-row>
<el-col :span='12'>
<el-form-item label="产品名称" prop="planProductId"> <el-form-item label="产品名称" prop="planProductId">
<el-select v-model="dataForm.planProductId" placeholder="请选择" style="width: 100%;" @change="selectProduct"> <el-select v-model="dataForm.planProductId" placeholder="请选择产品" style="width: 100%;" @change="selectProduct">
<el-option <el-option
v-for="item in productList" v-for="item in productList"
:key="item.id" :key="item.id"
@ -25,52 +23,50 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span='12'> </el-row>
<el-row :gutter="20">
<el-col :span='8'>
<el-form-item label="产品规格" prop="specifications"> <el-form-item label="产品规格" prop="specifications">
<el-input v-model="dataForm.specifications" /> <el-input v-model="dataForm.specifications" placeholder="请输入产品规格" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <el-col :span='8'>
<el-row>
<el-col :span='12'>
<el-form-item label="计划开始时间"> <el-form-item label="计划开始时间">
<el-date-picker <el-date-picker
v-model="dataForm.planStartTime" v-model="dataForm.planStartTime"
type="datetime" type="datetime"
value-format="timestamp" value-format="timestamp"
style="width: 100%;" style="width: 100%;"
placeholder="选择日期"> placeholder="请选择计划开始时间">
</el-date-picker> </el-date-picker>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span='12'> <el-col :span='8'>
<el-form-item label="计划完成时间"> <el-form-item label="计划完成时间">
<el-date-picker <el-date-picker
v-model="dataForm.planFinishTime" v-model="dataForm.planFinishTime"
type="datetime" type="datetime"
value-format="timestamp" value-format="timestamp"
style="width: 100%;" style="width: 100%;"
placeholder="选择日期"> placeholder="请选择计划完成时间">
</el-date-picker> </el-date-picker>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row :gutter="20">
<el-col :span='12'> <el-col :span='8'>
<el-form-item label="计划投入数量" prop="planAssignQuantity"> <el-form-item label="计划投入数量" prop="planAssignQuantity">
<el-input-number v-model="dataForm.planAssignQuantity" :min="0" :max="9999999999999" style="width: 100%;"></el-input-number> <el-input-number v-model="dataForm.planAssignQuantity" :min="0" :max="9999999999999" style="width: 100%;" placeholder="请输入计划投入数量"></el-input-number>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span='12'> <el-col :span='8'>
<el-form-item label="计划生产数量" prop="planQuantity"> <el-form-item label="计划生产数量" prop="planQuantity">
<el-input-number v-model="dataForm.planQuantity" :min="0" :max="9999999999999" style="width: 100%;"></el-input-number> <el-input-number v-model="dataForm.planQuantity" :min="0" :max="9999999999999" style="width: 100%;" placeholder="请输入计划生产数量"></el-input-number>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <el-col :span='8'>
<el-row>
<el-col :span='12'>
<el-form-item label="关联工艺" prop="processFlowId"> <el-form-item label="关联工艺" prop="processFlowId">
<el-select v-model="dataForm.processFlowId" placeholder="请选择工艺" clearable filterable style="width: 100%;" @change="processFlowIdChange"> <el-select v-model="dataForm.processFlowId" placeholder="请选择关联工艺" clearable filterable style="width: 100%;" @change="processFlowIdChange">
<el-option <el-option
v-for="item in processFlowList" v-for="item in processFlowList"
:key="item.id" :key="item.id"
@ -80,19 +76,23 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span='12'> </el-row>
<el-row :gutter="20">
<el-col :span='8'>
<el-form-item label="物料计算方式" prop="materialMethod"> <el-form-item label="物料计算方式" prop="materialMethod">
<el-radio-group v-model="dataForm.materialMethod" @change="materialMethodChange"> <!-- <el-radio-group v-model="dataForm.materialMethod" @change="materialMethodChange">
<el-radio :label="1">产品基础BOM</el-radio> <el-radio :label="1">产品基础BOM</el-radio>
<el-radio :label="2">工艺扩展BOM</el-radio> <el-radio :label="2">工艺扩展BOM</el-radio>
</el-radio-group> </el-radio-group> -->
<el-select v-model="dataForm.materialMethod" placeholder="请选择物料计算方式" style="width: 100%;" @change="materialMethodChange">
<el-option key="1" label="产品基础BOM" :value="1" />
<el-option key="2" label="工艺扩展BOM" :value="2" />
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <el-col :span='8'>
<el-row>
<el-col :span='12'>
<el-form-item label="优先级" prop="priority"> <el-form-item label="优先级" prop="priority">
<el-select v-model="dataForm.priority" placeholder="请选择" style="width: 100%;"> <el-select v-model="dataForm.priority" placeholder="请选择优先级" style="width: 100%;">
<el-option <el-option
v-for="item in getDictDatas(DICT_TYPE.ORDER_PRIORITY)" v-for="item in getDictDatas(DICT_TYPE.ORDER_PRIORITY)"
:key="item.value" :key="item.value"
@ -102,9 +102,9 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span='12'> <el-col :span='8'>
<el-form-item label="工单类型" prop="type"> <el-form-item label="工单类型" prop="type">
<el-select v-model="dataForm.type" placeholder="请选择" style="width: 100%;"> <el-select v-model="dataForm.type" placeholder="请选择工单类型" style="width: 100%;">
<el-option <el-option
v-for="item in workOrderTypeList" v-for="item in workOrderTypeList"
:key="item.id" :key="item.id"
@ -115,10 +115,10 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row :gutter="20">
<el-col :span='12'> <el-col :span='8'>
<el-form-item label="关联产线" prop="productLineIds"> <el-form-item label="关联产线" prop="productLineIds">
<el-select v-model="dataForm.productLineIds" placeholder="请选择" multiple style="width: 100%;"> <el-select v-model="dataForm.productLineIds" placeholder="请选择关联产线" multiple style="width: 100%;">
<el-option <el-option
v-for="item in productLineList" v-for="item in productLineList"
:key="item.id" :key="item.id"
@ -128,9 +128,9 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span='12'> <el-col :span='8'>
<el-form-item label="负责人" prop="workers"> <el-form-item label="负责人" prop="workers">
<el-input v-model="dataForm.workers"></el-input> <el-input v-model="dataForm.workers" placeholder="请输入负责人"></el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>

View File

@ -65,7 +65,8 @@ const tableProps = [
{ {
prop: 'createTime', prop: 'createTime',
label: '创建时间', label: '创建时间',
filter: parseTime filter: parseTime,
'show-overflow-tooltip': true
}, },
{ {
prop: 'name', prop: 'name',
@ -127,48 +128,10 @@ export default {
allocationVisible: false, allocationVisible: false,
tableProps, tableProps,
tableBtn: [ tableBtn: [
this.$auth.hasPermi(`base:core-work-order:update`) this.$auth.hasPermi(`base:core-work-order:material`)
? {
type: 'edit',
btnName: '编辑',
showParam: {
type: '&',
data: [
{
name: 'status',
type: 'equal',
value: 1
}
]
}
}
: undefined,
this.$auth.hasPermi(`base:core-work-order:detail`)
? {
type: 'detail',
btnName: '查看详情',
}
: undefined,
this.$auth.hasPermi(`base:core-work-order:delete`)
? {
type: 'delete',
btnName: '删除',
showParam: {
type: '|',
data: [
{
name: 'status',
type: 'equal',
value: 1
}
]
}
}
: undefined,
this.$auth.hasPermi(`base:core-work-order:material`)
? { ? {
type: 'material', type: 'material',
btnName: '预使用原料信息', btnName: '原料信息',
} }
: undefined, : undefined,
{ {
@ -246,7 +209,45 @@ export default {
} }
] ]
} }
} },
this.$auth.hasPermi(`base:core-work-order:detail`)
? {
type: 'detail',
btnName: '查看详情',
}
: undefined,
this.$auth.hasPermi(`base:core-work-order:update`)
? {
type: 'edit',
btnName: '编辑',
showParam: {
type: '&',
data: [
{
name: 'status',
type: 'equal',
value: 1
}
]
}
}
: undefined,
this.$auth.hasPermi(`base:core-work-order:delete`)
? {
type: 'delete',
btnName: '删除',
showParam: {
type: '|',
data: [
{
name: 'status',
type: 'equal',
value: 1
}
]
}
}
: undefined
].filter((v)=>v), ].filter((v)=>v),
tableData: [], tableData: [],
formConfig: [ formConfig: [

View File

@ -2,7 +2,7 @@
* @Author: zwq * @Author: zwq
* @Date: 2021-11-18 14:16:25 * @Date: 2021-11-18 14:16:25
* @LastEditors: DY * @LastEditors: DY
* @LastEditTime: 2023-11-27 09:36:44 * @LastEditTime: 2023-11-27 15:26:12
* @Description: * @Description:
--> -->
<template> <template>
@ -120,6 +120,7 @@
</el-row> </el-row>
</el-form> </el-form>
</div> </div>
<div class="attr-list" v-if="idAttrShow"> <div class="attr-list" v-if="idAttrShow">
<small-title <small-title
style="margin: 16px 0; padding-left: 8px" style="margin: 16px 0; padding-left: 8px"
@ -158,11 +159,9 @@
<div v-if="!isdetail" class="drawer-body__footer"> <div v-if="!isdetail" class="drawer-body__footer">
<el-button style="" @click="goback()">取消</el-button> <el-button style="" @click="goback()">取消</el-button>
<!-- <el-button v-if="isdetail" type="primary" @click="goEdit()">
编辑
</el-button> -->
<el-button type="primary" @click="dataFormSubmit()">确定</el-button> <el-button type="primary" @click="dataFormSubmit()">确定</el-button>
</div> </div>
</div> </div>
<attr-add <attr-add
@ -293,11 +292,7 @@ export default {
handleClick(raw) { handleClick(raw) {
if (raw.type === 'delete') { if (raw.type === 'delete') {
this.$confirm( this.$confirm(
`确定对${ `是否确认删除属性名为"${raw.data.attrName}"的数据项?`,
raw.data.attrName
? '[名称=' + raw.data.attrName + ']'
: '[序号=' + raw.data._pageIndex + ']'
}进行删除操作?`,
'提示', '提示',
{ {
confirmButtonText: '确定', confirmButtonText: '确定',
@ -363,6 +358,29 @@ export default {
} }
}); });
}, },
//
dataFormSubmit() {
this.$refs["dataForm"].validate((valid) => {
if (!valid) {
return false;
}
//
if (this.dataForm.id) {
this.urlOptions.updateURL(this.dataForm).then(response => {
this.$modal.msgSuccess("修改成功");
this.visible = false
this.$emit("refreshDataList");
});
return;
}
//
this.urlOptions.createURL(this.dataForm).then(response => {
this.$modal.msgSuccess("新增成功");
this.idAttrShow = true
this.$emit("refreshDataList");
});
});
},
goback() { goback() {
this.$emit('refreshDataList'); this.$emit('refreshDataList');
this.visible = false; this.visible = false;

View File

@ -1,7 +1,7 @@
<template> <template>
<el-dialog <el-dialog
:visible.sync="visible" :visible.sync="visible"
:width="'35%'" :width="'30%'"
:append-to-body="true" :append-to-body="true"
:close-on-click-modal="false" :close-on-click-modal="false"
class="dialog"> class="dialog">
@ -17,7 +17,7 @@
ref="dataForm" ref="dataForm"
:model="dataForm" :model="dataForm"
:rules="dataRule" :rules="dataRule"
label-width="100px" label-width="70px"
@keyup.enter.native="dataFormSubmit()"> @keyup.enter.native="dataFormSubmit()">
<el-form-item label="属性名" prop="attrName"> <el-form-item label="属性名" prop="attrName">
<el-input <el-input

View File

@ -2,7 +2,7 @@
* @Author: zwq * @Author: zwq
* @Date: 2021-11-18 14:16:25 * @Date: 2021-11-18 14:16:25
* @LastEditors: DY * @LastEditors: DY
* @LastEditTime: 2023-11-06 19:55:59 * @LastEditTime: 2023-11-27 15:10:20
* @Description: * @Description:
--> -->
<template> <template>
@ -18,7 +18,8 @@
<el-select <el-select
v-model="dataForm.materialId" v-model="dataForm.materialId"
placeholder="请选择物料" placeholder="请选择物料"
@change="setMaterialCode"> @change="setMaterialCode"
style="width: 100%">
<el-option <el-option
v-for="dict in materialList" v-for="dict in materialList"
:key="dict.id" :key="dict.id"

View File

@ -29,7 +29,7 @@
@cancel="handleCancel" @cancel="handleCancel"
@confirm="handleConfirm" @confirm="handleConfirm"
:before-close="handleCancel" :before-close="handleCancel"
width="50%"> width="40%">
<add-or-update <add-or-update
ref="addOrUpdate" ref="addOrUpdate"
@refreshDataList="successSubmit"></add-or-update> @refreshDataList="successSubmit"></add-or-update>

View File

@ -2,14 +2,14 @@
* @Author: zwq * @Author: zwq
* @Date: 2021-11-18 14:16:25 * @Date: 2021-11-18 14:16:25
* @LastEditors: DY * @LastEditors: DY
* @LastEditTime: 2023-11-25 19:10:12 * @LastEditTime: 2023-11-27 19:50:36
* @Description: * @Description:
--> -->
<template> <template>
<el-drawer <el-drawer
:visible.sync="visible" :visible.sync="visible"
:show-close="false" :show-close="false"
:wrapper-closable="false" :wrapper-closable="isdetail"
class="drawer" class="drawer"
size="70%"> size="70%">
<small-title slot="title" :no-padding="true"> <small-title slot="title" :no-padding="true">
@ -25,7 +25,7 @@
label-width="100px" label-width="100px"
label-position="top"> label-position="top">
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="8">
<el-form-item label="产品名称" prop="productId"> <el-form-item label="产品名称" prop="productId">
<el-select <el-select
v-model="dataForm.productId" v-model="dataForm.productId"
@ -42,15 +42,17 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="8">
<el-form-item label="产品BOM编码" prop="code"> <el-form-item label="产品BOM编码" prop="code">
<el-input v-model="dataForm.code" :disabled="isdetail" placeholder="请输入产品Bom编码" /> <el-input v-model="dataForm.code" :disabled="isdetail" placeholder="请输入产品Bom编码" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8">
<el-form-item label="备注" prop="remark">
<el-input v-model="dataForm.remark" :disabled="isdetail" clearable placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row> </el-row>
<el-form-item label="备注" prop="remark">
<el-input v-model="dataForm.remark" :disabled="isdetail" clearable placeholder="请输入备注" />
</el-form-item>
</el-form> </el-form>
</div> </div>
<div class="attr-list" v-if="idAttrShow"> <div class="attr-list" v-if="idAttrShow">
@ -60,92 +62,26 @@
BOM明细 BOM明细
</small-title> </small-title>
<!-- <base-table <div v-if="!isdetail" class="action_btn">
<template>
<span style="display: inline-block;">
<el-button type="text" @click="addNew()" icon="el-icon-plus">添加</el-button>
</span>
</template>
</div>
<base-table
:table-props="tableProps" :table-props="tableProps"
:page="listQuery.pageNo" :page="listQuery.pageNo"
:limit="listQuery.pageSize" :limit="listQuery.pageSize"
:add-button-show="isdetail ? null : '添加属性'" :table-data="tableData">
@emitButtonClick="addNew()"
:table-data="materialAttrList">
<method-btn <method-btn
v-if="!isdetail" v-if="!isdetail"
slot="handleBtn" slot="handleBtn"
:width="120" :width="90"
label="操作" label="操作"
:method-list="tableBtn" :method-list="tableBtn"
@clickBtn="handleClick" /> @clickBtn="handleClick" />
</base-table> --> </base-table>
<el-button v-show="!isdetail" type="success" size="small" style="float: right" @click="addRow()">添加一行</el-button>
<el-table
:data="tableData"
style="width: 100%">
<el-table-column type="index" label="序号" />
<el-table-column prop="createTime" label="添加时间">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column prop="materialId" label="物料名称*">
<template slot-scope="scope">
<el-select
v-model="scope.row.materialId"
filterable
clearable
:disabled="!scope.row.isEdit"
placeholder="请选择物料"
@change="setCode(scope.row)">
<el-option
v-for="dict in materialList"
:key="dict.id"
:label="dict.name"
:value="dict.id" />
</el-select>
<span v-if="scope.row.isShow" style="color: red">物料不可为空</span>
</template>
</el-table-column>
<el-table-column prop="materialCode" label="物料编码" />
<el-table-column prop="mUnit" label="单位" />
<el-table-column prop="num" label="数量*">
<template slot-scope="scope">
<el-input v-model.number="scope.row.num" :disabled="!scope.row.isEdit" @input="changeNum(scope.row)"></el-input>
<span v-if="scope.row.isNum" style="color: red">数量不可为空</span>
</template>
</el-table-column>
<el-table-column prop="remark" label="备注">
<template slot-scope="scope">
<el-input v-model="scope.row.remark" :disabled="!scope.row.isEdit"></el-input>
</template>
</el-table-column>
<el-table-column v-if="!isdetail" label="操作">
<template slot-scope="scope">
<el-tooltip v-if="!scope.row.isEdit" placement="top" content="编辑">
<el-button
type="text"
:style="{color:'#0B58FF'}"
size="mini"
@click="edit(scope.row)"
>
<!-- 此处的icon的名字命名为'table_'加上按钮的type -->
<svg-icon style="width: 18px; height: 18px" class="item-icon" icon-class="edit" />
<!-- <span>{{ item.btnName | i18nFilter }}</span> -->
</el-button>
</el-tooltip>
<el-button v-else type="text" size="small" @click="saveData(scope.row)">保存</el-button>
<el-tooltip placement="top" content="删除">
<el-button
type="text"
:style="{color:'#FF5454'}"
size="mini"
@click="deleteDetail(scope.row)"
>
<!-- 此处的icon的名字命名为'table_'加上按钮的type -->
<svg-icon style="width: 18px; height: 18px" class="item-icon" icon-class="table_delete" />
<!-- <span>{{ item.btnName | i18nFilter }}</span> -->
</el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<pagination <pagination
v-show="listQuery.total > 0" v-show="listQuery.total > 0"
:total="listQuery.total" :total="listQuery.total"
@ -155,20 +91,17 @@
@pagination="getList" /> @pagination="getList" />
</div> </div>
<div class="drawer-body__footer"> <div v-if="!isdetail" class="drawer-body__footer">
<el-button style="" @click="goback()">{{ isdetail ? '关闭' : '取消' }}</el-button> <el-button style="" @click="goback()">取消</el-button>
<!-- <el-button v-if="isdetail" type="primary" @click="goEdit()"> <el-button type="primary" @click="dataFormSubmit()">确定</el-button>
编辑
</el-button> -->
<el-button v-if="!isdetail" type="primary" @click="dataFormSubmit()">确定</el-button>
</div> </div>
</div> </div>
<!-- <attr-add <attr-add
v-if="addOrUpdateVisible" v-if="addOrUpdateVisible"
ref="addOrUpdate" ref="addOrUpdate"
:material-id="dataForm.id" :bom-id="dataForm.id"
@refreshDataList="getList" /> --> @refreshDataList="getList" />
</el-drawer> </el-drawer>
</template> </template>
@ -179,7 +112,8 @@ import { getMaterialList } from "@/api/base/material";
import { listData } from "@/api/system/dict/data"; import { listData } from "@/api/system/dict/data";
import SmallTitle from '../material/SmallTitle'; import SmallTitle from '../material/SmallTitle';
import { parseTime } from '../../core/mixins/code-filter'; import { parseTime } from '../../core/mixins/code-filter';
// import attrAdd from './attr-add'; import attrAdd from './attr-add';
import { publicFormatter } from '@/utils/dict';
const tableBtn = [ const tableBtn = [
{ {
@ -198,18 +132,31 @@ const tableProps = [
filter: parseTime, filter: parseTime,
}, },
{ {
prop: 'attrName', prop: 'materialName',
label: '属性名', label: '物料名称',
}, },
{ {
prop: 'attrValue', prop: 'materialCode',
label: '属性值', label: '物料编码',
}, },
{
prop: 'unit',
label: '单位',
filter: publicFormatter('unit_dict'),
},
{
prop: 'num',
label: '数量',
},
{
prop: 'remark',
label: '备注',
}
]; ];
export default { export default {
mixins: [basicAdd], mixins: [basicAdd],
components: { SmallTitle }, components: { SmallTitle, attrAdd },
data() { data() {
return { return {
tableBtn, tableBtn,
@ -235,7 +182,6 @@ export default {
}, },
productList: [], productList: [],
materialAttrList: [], materialAttrList: [],
materialList: [],
tableData: [], tableData: [],
unitList: [], unitList: [],
visible: false, visible: false,
@ -250,13 +196,42 @@ export default {
this.getDict() this.getDict()
}, },
methods: { methods: {
handleClick(raw) {
if (raw.type === 'delete') {
this.deleteDetail(raw.data);
} else {
this.addNew(raw.data.id);
}
},
//
dataFormSubmit() {
this.$refs["dataForm"].validate((valid) => {
if (!valid) {
return false;
}
//
if (this.dataForm.id) {
this.urlOptions.updateURL(this.dataForm).then(response => {
this.$modal.msgSuccess("修改成功");
this.visible = false;
this.$emit("refreshDataList");
});
return;
}
//
this.urlOptions.createURL(this.dataForm).then(response => {
this.$modal.msgSuccess("新增成功");
// this.visible = false;
this.idAttrShow = true;
this.dataForm.id = response.data
this.$emit("refreshDataList");
});
});
},
async getDict() { async getDict() {
// //
const proRes = await getProList(); const proRes = await getProList();
this.productList = proRes.data; this.productList = proRes.data;
//
const res = await getMaterialList();
this.materialList = res.data;
// //
const unitRes = await listData({ const unitRes = await listData({
pageNo: 1, pageNo: 1,
@ -276,8 +251,7 @@ export default {
}, },
deleteDetail(raw) { deleteDetail(raw) {
this.$confirm( this.$confirm(
`确定删除关于物料编码为${ `是否确认删除物料名称为"${raw.materialName}"的数据项?`,
raw.materialCode}的数据?`,
'提示', '提示',
{ {
confirmButtonText: '确定', confirmButtonText: '确定',
@ -299,88 +273,13 @@ export default {
}) })
.catch(() => {}); .catch(() => {});
}, },
changeNum(row) {
if (row.num !== '') {
row.isNum = false
} else {
row.isNum = true
}
},
setCode(row) {
if (row.materialId) {
row.isShow = false
const tempM = this.materialList.filter(item => {
if (row.materialId === item.id) {
row.materialCode = item.code
}
return row.materialId === item.id
})
if (tempM[0].unit) {
this.unitList.filter(u => {
if (tempM[0].unit === u.value) {
row.unit = u.value
row.mUnit = u.label
}
})
} else {
row.unit = null
row.mUnit = ''
}
} else {
row.isShow = true
row.unit = null
row.mUnit = ''
}
// row.materialCode = tempList[0].code
// row.unit = tempList[0].unit
},
edit(row) {
row.isEdit = true
},
saveData(row) {
if (row.materialId) {
// this.$refs['dataForm'].validate((valid) => {
// if (valid) {
//
if (row.id) {
updateMaterialPBDet({
...row
}).then((response) => {
this.$modal.msgSuccess('修改成功');
// this.visible = false;
this.getList();
});
return;
}
//
createMaterialPBDet({
...row
}).then((response) => {
this.$modal.msgSuccess('新增成功');
// this.visible = false;
this.getList();
});
} else {
this.$message.warning('请选择物料!')
}
// }
// });
},
getList() { getList() {
// Bom // Bom
getProBomList({ getProBomList({
...this.listQuery, ...this.listQuery,
bomId: this.dataForm.id bomId: this.dataForm.id
}).then((response) => { }).then((response) => {
this.tableData = response.data.records.map(item => { this.tableData = response.data.records
this.unitList.filter(u => {
if (item.unit === u.value) {
item.mUnit = u.label
}
})
item.isEdit = false
return item
});
this.listQuery.total = response.data.total; this.listQuery.total = response.data.total;
}); });
}, },
@ -476,7 +375,7 @@ export default {
.drawer >>> .visual-part { .drawer >>> .visual-part {
flex: 1 auto; flex: 1 auto;
max-height: 30vh; max-height: 20vh;
overflow: hidden; overflow: hidden;
overflow-y: scroll; overflow-y: scroll;
padding-right: 10px; /* 调整滚动条样式 */ padding-right: 10px; /* 调整滚动条样式 */
@ -492,4 +391,12 @@ export default {
justify-content: flex-end; justify-content: flex-end;
padding: 18px; padding: 18px;
} }
.action_btn {
float: right;
margin: -40px 15px;
font-size: 14px;
}
.add {
color: #0b58ff;
}
</style> </style>

View File

@ -0,0 +1,197 @@
<template>
<el-dialog
:visible.sync="visible"
:width="'40%'"
:append-to-body="true"
:close-on-click-modal="false"
class="dialog">
<template #title>
<slot name="title">
<div class="titleStyle">
{{ !dataForm.id ? '新增' : '编辑' }}
</div>
</slot>
</template>
<el-form
ref="dataForm"
:model="dataForm"
:rules="dataRule"
label-width="80px"
@keyup.enter.native="dataFormSubmit()">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="物料名称" prop="materialId">
<el-select
v-model="dataForm.materialId"
placeholder="请选择物料"
clearable
filterable
@change="setCode"
style="width: 100%"
>
<el-option
v-for="dict in materialList"
:key="dict.id"
:label="dict.name"
:value="dict.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物料编码" prop="materialCode">
<el-input
v-model="dataForm.materialCode"
clearable
disabled
placeholder="请输入物料编码" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="单位" prop="unit">
<el-select
v-model="dataForm.unit"
style="width: 100%"
disabled
placeholder="请选择单位">
<el-option
v-for="dict in getDictDatas(DICT_TYPE.UNIT_DICT)"
:key="dict.value"
:label="dict.label"
:value="dict.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="数量" prop="num">
<el-input-number v-model="dataForm.num" controls-position="right" clearable placeholder="请输入数量" style="width: 100%" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="备注" prop="remark">
<el-input v-model="dataForm.remark" clearable placeholder="请输入备注" />
</el-form-item>
</el-form>
<el-row style="text-align: right">
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="dataFormSubmit()">确定</el-button>
</el-row>
</el-dialog>
</template>
<script>
import { getMaterialList } from '@/api/base/material';
import { createMaterialPBDet, updateMaterialPBDet, getMaterialPBDet } from "@/api/base/materialProductBom";
export default {
props: {
bomId: {
type: String,
default: '',
},
},
data() {
return {
visible: false,
dataForm: {
id: undefined,
materialId: '',
num: 0,
materialCode: undefined,
unit: undefined,
remark: '',
},
materialList: [],
dataRule: {
materialId: [{ required: true, message: '物料名称不能为空', trigger: 'change' }],
num: [{ required: true, message: '数量不能为空', trigger: 'blur' }]
},
};
},
mounted() {
this.getDict()
},
methods: {
async getDict() {
//
const res = await getMaterialList();
this.materialList = res.data;
},
init(id) {
this.dataForm.id = id || '';
this.visible = true;
this.$nextTick(() => {
this.$refs['dataForm'].resetFields();
if (this.dataForm.id) {
getMaterialPBDet(this.dataForm.id).then((res) => {
this.dataForm = res.data
this.setCode()
});
}
});
},
setCode() {
const tempMaterial = this.materialList.filter(item =>{
return item.id === this.dataForm.materialId
})
this.dataForm.materialCode = tempMaterial[0]?.code
this.dataForm.unit = tempMaterial[0].unit === undefined ? undefined : String(tempMaterial[0]?.unit)
},
//
dataFormSubmit() {
this.$refs['dataForm'].validate((valid) => {
if (valid) {
//
if (this.dataForm.id) {
updateMaterialPBDet({
...this.dataForm,
bomId: this.bomId,
}).then((response) => {
this.$modal.msgSuccess('修改成功');
this.visible = false;
this.$emit('refreshDataList');
});
return;
}
//
createMaterialPBDet({
...this.dataForm,
bomId: this.bomId,
}).then((response) => {
this.$modal.msgSuccess('新增成功');
this.visible = false;
this.$emit('refreshDataList');
});
}
});
},
},
};
</script>
<style scoped>
.dialog >>> .el-dialog__body {
padding: 30px 24px;
}
.dialog >>> .el-dialog__header {
font-size: 16px;
color: rgba(0, 0, 0, 0.85);
font-weight: 500;
padding: 13px 24px;
border-bottom: 1px solid #e9e9e9;
}
.dialog >>> .el-dialog__header .titleStyle::before {
content: '';
display: inline-block;
width: 4px;
height: 16px;
background-color: #0b58ff;
border-radius: 1px;
margin-right: 8px;
position: relative;
top: 2px;
}
</style>

View File

@ -13,7 +13,7 @@
<method-btn <method-btn
v-if="tableBtn.length" v-if="tableBtn.length"
slot="handleBtn" slot="handleBtn"
:width="220" :width="120"
label="操作" label="操作"
:method-list="tableBtn" :method-list="tableBtn"
@clickBtn="handleClick" /> @clickBtn="handleClick" />
@ -68,24 +68,24 @@ export default {
}, },
tableProps, tableProps,
tableBtn: [ tableBtn: [
this.$auth.hasPermi(`base:material-product-bom:update`) this.$auth.hasPermi(`base:material-product-bom:queryMaterial`)
? {
type: 'detail',
btnName: '查看物料',
}
: undefined,
this.$auth.hasPermi(`base:material-product-bom:update`)
? { ? {
type: 'edit', type: 'edit',
btnName: '编辑', btnName: '编辑',
} }
: undefined, : undefined,
this.$auth.hasPermi(`base:material-product-bom:queryMaterial`) // this.$auth.hasPermi(`base:material-product-bom:editMaterial`)
? { // ? {
type: 'search', // type: 'editMaterial',
btnName: '查看物料', // btnName: '',
} // }
: undefined, // : undefined,
this.$auth.hasPermi(`base:material-product-bom:editMaterial`)
? {
type: 'editMaterial',
btnName: '编辑物料',
}
: undefined,
this.$auth.hasPermi(`base:material-product-bom:delete`) this.$auth.hasPermi(`base:material-product-bom:delete`)
? { ? {
type: 'delete', type: 'delete',
@ -123,7 +123,7 @@ export default {
created() {}, created() {},
methods: { methods: {
otherMethods(val) { otherMethods(val) {
if (val.type === 'search') { if (val.type === 'detail') {
this.addOrUpdateVisible = true; this.addOrUpdateVisible = true;
this.addOrEditTitle = '详情'; this.addOrEditTitle = '详情';
this.$nextTick(() => { this.$nextTick(() => {

View File

@ -2,7 +2,7 @@
* @Author: zwq * @Author: zwq
* @Date: 2021-11-18 14:16:25 * @Date: 2021-11-18 14:16:25
* @LastEditors: DY * @LastEditors: DY
* @LastEditTime: 2023-11-22 10:40:08 * @LastEditTime: 2023-11-27 19:57:23
* @Description: * @Description:
--> -->
<template> <template>
@ -11,9 +11,10 @@
:rules="dataRule" :rules="dataRule"
ref="dataForm" ref="dataForm"
@keyup.enter.native="dataFormSubmit()" @keyup.enter.native="dataFormSubmit()"
label-width="80px"> label-width="80px"
label-position="top">
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="8">
<el-form-item label="物料名称" prop="materialId"> <el-form-item label="物料名称" prop="materialId">
<el-select <el-select
v-model="dataForm.materialId" v-model="dataForm.materialId"
@ -21,6 +22,7 @@
clearable clearable
filterable filterable
@change="setCode" @change="setCode"
style="width: 100%"
> >
<el-option <el-option
v-for="dict in materialList" v-for="dict in materialList"
@ -30,7 +32,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="8">
<el-form-item label="物料编码" prop="materialCode"> <el-form-item label="物料编码" prop="materialCode">
<el-input <el-input
v-model="dataForm.materialCode" v-model="dataForm.materialCode"
@ -39,15 +41,14 @@
placeholder="请输入物料编码" /> placeholder="请输入物料编码" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <el-col :span="8">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="批次号" prop="materialDateId"> <el-form-item label="批次号" prop="materialDateId">
<el-select <el-select
v-model="dataForm.materialDateId" v-model="dataForm.materialDateId"
clearable clearable
filterable filterable
placeholder="请选择物料批次" placeholder="请选择物料批次"
style="width: 100%"
> >
<el-option <el-option
v-for="dict in materialDateList" v-for="dict in materialDateList"
@ -57,13 +58,16 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> </el-row>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="使用设备" prop="equipmentId"> <el-form-item label="使用设备" prop="equipmentId">
<el-select <el-select
v-model="dataForm.equipmentId" v-model="dataForm.equipmentId"
clearable clearable
filterable filterable
placeholder="请选择使用设备"> placeholder="请选择使用设备"
style="width: 100%">
<el-option <el-option
v-for="dict in eqList" v-for="dict in eqList"
:key="dict.id" :key="dict.id"
@ -72,9 +76,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> <el-col :span="8">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="使用时间" prop="useTime"> <el-form-item label="使用时间" prop="useTime">
<el-date-picker <el-date-picker
v-model="dataForm.useTime" v-model="dataForm.useTime"
@ -84,14 +86,15 @@
placeholder="选择日期时间" /> placeholder="选择日期时间" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="8">
<el-form-item label="操作员" prop="userNames"> <el-form-item label="操作员" prop="userNames">
<el-select <el-select
v-model="dataForm.userNames" v-model="dataForm.userNames"
clearable clearable
filterable filterable
multiple multiple
placeholder="请选择操作员"> placeholder="请选择操作员"
style="width: 100%">
<el-option <el-option
v-for="dict in workersList" v-for="dict in workersList"
:key="dict.id" :key="dict.id"
@ -102,12 +105,12 @@
</el-col> </el-col>
</el-row> </el-row>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="8">
<el-form-item label="使用数量" prop="num"> <el-form-item label="使用数量" prop="num">
<el-input-number v-model="dataForm.num" clearable placeholder="请输入使用数量" /> <el-input-number v-model="dataForm.num" clearable controls-position="right" placeholder="请输入使用数量" style="width: 100%" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="8">
<el-form-item label="数据来源" prop="source"> <el-form-item label="数据来源" prop="source">
<el-select <el-select
v-model="dataForm.source" v-model="dataForm.source"
@ -121,10 +124,12 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8">
<el-form-item label="备注" prop="remark">
<el-input v-model="dataForm.remark" clearable placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row> </el-row>
<el-form-item label="备注" prop="remark">
<el-input v-model="dataForm.remark" clearable placeholder="请输入备注" />
</el-form-item>
</el-form> </el-form>
</template> </template>
@ -237,13 +242,8 @@ export default {
this.dataForm.source = response.data.source this.dataForm.source = response.data.source
this.dataForm.remark = response.data.remark this.dataForm.remark = response.data.remark
this.dataForm.userNames = response.data.userName.split(',') this.dataForm.userNames = response.data.userName.split(',')
console.log('打印', this.dataForm)
}); });
} else { } else {}
if (this.urlOptions.isGetCode) {
this.getCode()
}
}
}); });
}, },
setCode() { setCode() {

View File

@ -29,7 +29,7 @@
@cancel="handleCancel" @cancel="handleCancel"
@confirm="handleConfirm" @confirm="handleConfirm"
:before-close="handleCancel" :before-close="handleCancel"
width="50%"> width="60%">
<add-or-update <add-or-update
ref="addOrUpdate" ref="addOrUpdate"
@refreshDataList="successSubmit"></add-or-update> @refreshDataList="successSubmit"></add-or-update>

View File

@ -8,11 +8,11 @@
<template> <template>
<div class="app-container allow-overflow"> <div class="app-container allow-overflow">
<!-- 搜索工作栏 --> <!-- 搜索工作栏 -->
<small-title <!-- <small-title
style="margin: 16px 0; padding-left: 8px" style="margin: 16px 0; padding-left: 8px"
:no-padding="true"> :no-padding="true">
设备运行状态 设备运行状态
</small-title> </small-title> -->
<div <div
class="graph" class="graph"
@ -22,7 +22,8 @@
flex-direction: column; flex-direction: column;
position: relative; position: relative;
"> ">
<div class="blue-title">各设备加工数量</div> <!-- <div class="blue-title">各设备加工数量</div> -->
<div class="blue-title">设备运行状态</div>
<div class="legend"> <div class="legend">
<div class="legend-item"> <div class="legend-item">
<span class="icon blue"></span> <span class="icon blue"></span>
@ -41,22 +42,17 @@
<span class="text">速度开动率</span> <span class="text">速度开动率</span>
</div> </div>
</div> </div>
<div class="graph-grid"> <div v-if="list.length" class="graph-grid">
<div class="bg-grid grid-line"> <div class="bg-grid grid-line">
<div <div class="grid-item" v-for="item in list.length" :key="item"></div>
class="grid-item"
v-for="item in list.length"
:key="item"></div>
</div> </div>
<div class="bg-grid grid-charts"> <div class="bg-grid grid-charts">
<pie-chart <pie-chart v-for="item in list" :key="item.id" :value="item" />
v-for="item in list"
:key="item.id"
:value="item" />
<!-- <pie-chart v-for="item in 5" :key="item" :value="item" /> --> <!-- <pie-chart v-for="item in 5" :key="item" :value="item" /> -->
</div> </div>
</div> </div>
<div class="no-data-bg" v-else></div>
</div> </div>
</div> </div>
</template> </template>

View File

@ -202,7 +202,9 @@ export default {
]; ];
this.config.series[1].data = [ this.config.series[1].data = [
{ name: '速度开动率', value: peEfficiency }, { name: '速度开动率', value: peEfficiency },
{ name: '', value: Math.ceil(peEfficiency) - peEfficiency }, { name: '', value: 100 },
// { name: '', value: peEfficiency },
// { name: '', value: Math.ceil(peEfficiency) - peEfficiency },
]; ];
// //
this.textData = { this.textData = {

View File

@ -21,18 +21,15 @@ export default {
chart: null, chart: null,
}; };
}, },
// watch: { watch: {
// list: { list: {
// handler(listdata) { handler(listdata) {
// if (listdata && listdata.length) { this.setOption();
// console.log('[linechart] list changed', listdata); },
// const option = this.handleList(listdata); immediate: true,
// this.setOption(option); deep: true,
// } },
// }, },
// immediate: true,
// },
// },
computed: { computed: {
option() { option() {
const opt = []; const opt = [];
@ -55,7 +52,7 @@ export default {
}, },
formatter: (params) => { formatter: (params) => {
const name = params[0].name; const name = params[0].name;
const goodRate = opt.find((item) => item[0] == name)[4]; const goodRate = opt.find((item) => item[0] == name)[4] || '0';
return ` return `
<h1 style="font-size: 18px; letter-spacing: 1px;">${ <h1 style="font-size: 18px; letter-spacing: 1px;">${
params[0].axisValue params[0].axisValue
@ -109,6 +106,9 @@ export default {
xAxis: { xAxis: {
type: 'category', type: 'category',
axisTick: { show: false }, axisTick: { show: false },
axisLabel: {
rotate: 45,
},
data: opt.map((item) => item[0]), data: opt.map((item) => item[0]),
}, },
yAxis: { yAxis: {

View File

@ -6,15 +6,15 @@
--> -->
<template> <template>
<div class="app-container"> <div class="app-container" style="flex: 1; height: 1px; display: flex; flex-direction: column;">
<!-- 搜索工作栏 --> <!-- 搜索工作栏 -->
<SearchBar <SearchBar
:formConfigs="searchBarFormConfig" :formConfigs="searchBarFormConfig"
ref="search-bar" ref="search-bar"
@headBtnClick="handleSearchBarBtnClick" /> @headBtnClick="handleSearchBarBtnClick" />
<el-row> <el-row type="flex" style="flex: 1;">
<el-col class="custom-tabs"> <el-col class="custom-tabs" style="flex: 1;">
<el-tabs <el-tabs
v-model="activeName" v-model="activeName"
:stretch="true" :stretch="true"
@ -32,7 +32,7 @@
<div <div
v-if="activeName == 'graph'" v-if="activeName == 'graph'"
class="graph" class="graph"
style="height: 40vh; display: flex; flex-direction: column"> style="height: 100%; display: flex; flex-direction: column">
<div class="blue-title">各设备加工数量</div> <div class="blue-title">各设备加工数量</div>
<LineChart v-if="list && list.length" :list="list" /> <LineChart v-if="list && list.length" :list="list" />
<div v-else class="no-data-bg"></div> <div v-else class="no-data-bg"></div>
@ -63,13 +63,13 @@ export default {
activeName: 'table', // defaults to 'table' activeName: 'table', // defaults to 'table'
searchBarFormConfig: [ searchBarFormConfig: [
// //
{ // {
__index: 'product', // __index: 'product',
type: 'select', // type: 'select',
label: '产品', // label: '',
placeholder: '请选择产品', // placeholder: '',
param: 'productId', // param: 'productId',
}, // },
// 线 // 线
{ {
__index: 'line', __index: 'line',
@ -156,17 +156,17 @@ export default {
{ {
// width: 160, // width: 160,
prop: 'inQuantity', prop: 'inQuantity',
label: '进片数量', label: '加工数量',
}, },
{ {
// width: 160, // width: 160,
prop: 'outQuantity', prop: 'outQuantity',
label: '出片数量', label: '合格数量',
}, },
{ {
// width: 160, // width: 160,
prop: 'nokQuantity', prop: 'nokQuantity',
label: '破损/不合格数', label: '不合格数',
}, },
{ {
// width: 160, // width: 160,
@ -377,6 +377,9 @@ export default {
} }
:deep(.custom-tabs) { :deep(.custom-tabs) {
.el-tabs {
height: 100%;
}
.el-tabs__header { .el-tabs__header {
margin-bottom: 8px; margin-bottom: 8px;
display: inline-block; display: inline-block;
@ -389,6 +392,14 @@ export default {
line-height: 36px !important; line-height: 36px !important;
height: 36px; height: 36px;
} }
.el-tabs__content {
height: calc(100% - 48px);
}
#pane-graph {
height: 100%;
}
} }
.blue-title { .blue-title {

View File

@ -7,27 +7,30 @@
--> -->
<template> <template>
<div class="alarm-handle"> <div class="alarm-handle">
<DialogForm <el-skeleton v-if="loading" />
ref="orderForm" <div v-else>
key="orderForm" <DialogForm
v-model="orderForm" ref="orderForm"
:disabled="readOnly" key="orderForm"
:has-files="false" v-model="orderForm"
label-position="top" :disabled="readOnly"
:rows="orderFormRows" /> :has-files="false"
label-position="top"
:rows="orderFormRows" />
<small-title style="margin: 16px 0" :no-padding="true" size="sm"> <small-title style="margin: 16px 0" :no-padding="true" size="sm">
处理方式 处理方式
</small-title> </small-title>
<DialogForm <DialogForm
key="handleMethodForm" key="handleMethodForm"
ref="handleMethodForm" ref="handleMethodForm"
v-model="handleMethodForm" v-model="handleMethodForm"
:disabled="readOnly" :disabled="readOnly"
:has-files="true" :has-files="true"
label-position="top" label-position="top"
:rows="handleMethodFormRows" /> :rows="handleMethodFormRows" />
</div>
</div> </div>
</template> </template>
@ -43,6 +46,7 @@ export default {
components: { SmallTitle, DialogForm, Editor }, components: { SmallTitle, DialogForm, Editor },
data() { data() {
return { return {
loading: false,
orderForm: { orderForm: {
id: null, id: null,
equipment: null, equipment: null,
@ -82,6 +86,9 @@ export default {
label: '处理人', label: '处理人',
prop: 'hander', prop: 'hander',
url: '/base/core-worker/listAll', url: '/base/core-worker/listAll',
bind: {
multiple: true,
},
rules: [ rules: [
{ required: true, message: '类型名称不能为空', trigger: 'blur' }, { required: true, message: '类型名称不能为空', trigger: 'blur' },
], ],
@ -122,9 +129,14 @@ export default {
}; };
}, },
mounted() { mounted() {
this.getDict().then(() => { this.loading = true;
this.init(); this.getDict()
}); .then(() => {
this.init();
})
.catch((err) => {
this.loading = false;
});
}, },
methods: { methods: {
/** /**
@ -139,8 +151,9 @@ export default {
* 初始化 * 初始化
*/ */
async init() { async init() {
this.initTop(); await this.initTop();
this.initDown(); await this.initDown();
this.loading = false;
}, },
/** /**
@ -172,16 +185,19 @@ export default {
this.$msgError('缺少报警日志id'); this.$msgError('缺少报警日志id');
this.$emit('close'); this.$emit('close');
} }
const url = '/base/equipment-alarm-hand/get'; const url = '/base/equipment-alarm-hand/page'; // page
const { data, code } = await this.$axios({ const { data, code } = await this.$axios({
url: url, url: url,
method: 'get', method: 'get',
params: { params: {
id: this.logId, logId: this.logId,
}, },
}); });
if (code == 0) { if (code == 0) {
this.handleMethodForm = data; this.handleMethodForm = {
...data.list[0],
hander: data.list[0]?.hander?.split(',') || '',
};
} }
}, },
@ -213,7 +229,11 @@ export default {
const { code, data } = await this.$axios({ const { code, data } = await this.$axios({
url: url + (this.handleMethodForm.id ? '/update' : '/create'), url: url + (this.handleMethodForm.id ? '/update' : '/create'),
method: this.handleMethodForm.id ? 'put' : 'post', method: this.handleMethodForm.id ? 'put' : 'post',
data: { ...this.handleMethodForm, logId: this.logId }, data: {
...this.handleMethodForm,
hander: this.handleMethodForm.hander?.join(',') || '',
logId: this.logId,
},
}); });
if (code == 0) { if (code == 0) {
return true; return true;

View File

@ -42,7 +42,8 @@
:dataForm="form" :dataForm="form"
:rows="formRows" /> --> :rows="formRows" /> -->
<el-row v-if="mode.includes('detail')" style="margin-bottom: 24px"> <!-- <el-row v-if="mode.includes('detail')" style="margin-bottom: 24px"> -->
<el-row style="margin-bottom: 24px">
<el-col :span="8"> <el-col :span="8">
<div <div
class="title" class="title"
@ -62,7 +63,7 @@
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
<el-row v-else style="margin-bottom: 24px" :gutter="20"> <!-- <el-row v-else style="margin-bottom: 24px" :gutter="20">
<el-form ref="form" :model="form"> <el-form ref="form" :model="form">
<el-col :span="8"> <el-col :span="8">
<el-form-item <el-form-item
@ -85,7 +86,7 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-form> </el-form>
</el-row> </el-row> -->
</div> </div>
<div <div
@ -132,8 +133,8 @@
<el-button <el-button
type="primary" type="primary"
v-if="!mode.includes('detail')" v-if="!mode.includes('detail')"
@click="handleSave"> @click="handleCancel">
保存 确定
</el-button> </el-button>
</div> </div>
</div> </div>

View File

@ -2,7 +2,7 @@
* @Author: zwq * @Author: zwq
* @Date: 2021-11-18 14:16:25 * @Date: 2021-11-18 14:16:25
* @LastEditors: DY * @LastEditors: DY
* @LastEditTime: 2023-11-24 18:38:22 * @LastEditTime: 2023-11-27 10:48:55
* @Description: * @Description:
--> -->
<template> <template>
@ -176,11 +176,7 @@ export default {
handleClick(raw) { handleClick(raw) {
if (raw.type === 'delete') { if (raw.type === 'delete') {
this.$confirm( this.$confirm(
`确定对${ `是否确认删除巡检项目名称为"${raw.data.program}"的数据项?`,
raw.data.attrName
? '[名称=' + raw.data.attrName + ']'
: '[序号=' + raw.data._pageIndex + ']'
}进行删除操作?`,
'提示', '提示',
{ {
confirmButtonText: '确定', confirmButtonText: '确定',

View File

@ -1,8 +1,8 @@
<!-- <!--
* @Author: zwq * @Author: zwq
* @Date: 2021-11-18 14:16:25 * @Date: 2021-11-18 14:16:25
* @LastEditors: zhp * @LastEditors: DY
* @LastEditTime: 2023-11-23 09:20:12 * @LastEditTime: 2023-11-27 16:37:17
* @Description: * @Description:
--> -->
<template> <template>
@ -53,7 +53,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<div v-if="isdetail" class="drawer-body__footer"> <div v-if="!isdetail" class="drawer-body__footer">
<el-button style="" @click="goback()">取消</el-button> <el-button style="" @click="goback()">取消</el-button>
<el-button v-if="isdetail" type="primary" @click="goEdit()"> <el-button v-if="isdetail" type="primary" @click="goEdit()">
编辑 编辑

View File

@ -26,7 +26,7 @@ export default {
color: ['#288AFF'], color: ['#288AFF'],
grid: { grid: {
top: 64, top: 64,
left: 56, left: '8%',
right: 64, right: 64,
bottom: 56, bottom: 56,
}, },

View File

@ -67,15 +67,20 @@
class="app-container equipment-process-amount" class="app-container equipment-process-amount"
style="flex: 1; border-radius: 8px; background: #fff"> style="flex: 1; border-radius: 8px; background: #fff">
<!-- main area --> <!-- main area -->
<div class="main-content" style="display: flex; flex-direction: column"> <div
class="main-content"
style="height: 100%; display: flex; flex-direction: column">
<SearchBar <SearchBar
:formConfigs="searchBarFormConfig" :formConfigs="searchBarFormConfig"
ref="search-bar" ref="search-bar"
@headBtnClick="handleSearchBarBtnClick" /> @headBtnClick="handleSearchBarBtnClick" />
<el-row> <el-row style="flex: 1">
<el-col class="custom-tabs"> <el-col class="custom-tabs" style="height: 100%">
<el-tabs v-model="activeName" @tab-click="handleTabClick"> <el-tabs
v-model="activeName"
@tab-click="handleTabClick"
style="height: 100%">
<el-tab-pane :label="'\u2002数据列表\u2002'" name="table"> <el-tab-pane :label="'\u2002数据列表\u2002'" name="table">
<base-table <base-table
v-if="mode == 'table'" v-if="mode == 'table'"
@ -93,7 +98,9 @@
</base-table> </base-table>
</el-tab-pane> </el-tab-pane>
<el-tab-pane :label="'\u3000柱状图\u3000'" name="graph"> <el-tab-pane :label="'\u3000柱状图\u3000'" name="graph">
<div class="graph" style="height: 56vh"> <div
class="graph"
style="height: 100%;">
<!-- graph --> <!-- graph -->
<Graph <Graph
v-if="list.length" v-if="list.length"
@ -546,6 +553,13 @@ li {
.el-tree-node__content { .el-tree-node__content {
padding: 8px 24px !important; padding: 8px 24px !important;
} }
.custom-tabs >>> .el-tabs__content {
height: calc(100% - 42px);
}
.custom-tabs >>> .el-tab-pane {
height: 100%;
}
</style> </style>
<style> <style>

View File

@ -17,7 +17,7 @@
<method-btn <method-btn
v-if="tableBtn.length" v-if="tableBtn.length"
slot="handleBtn" slot="handleBtn"
:width="320" :width="240"
label="操作" label="操作"
:method-list="tableBtn" :method-list="tableBtn"
@clickBtn="handleClick" @clickBtn="handleClick"

View File

@ -73,7 +73,7 @@ const tableProps = [
{ {
prop: 'status', prop: 'status',
label: '订单状态', label: '订单状态',
filter: publicFormatter('order_priority') filter: publicFormatter('order_status')
}, },
{ {
prop: 'startProduceTime', prop: 'startProduceTime',
@ -88,7 +88,7 @@ const tableProps = [
minWidth: 160 minWidth: 160
}, },
{ {
prop: 'productLines', prop: 'lineNames',
label: '加工线', label: '加工线',
filter: (val) => val ? val.join(',') : '', filter: (val) => val ? val.join(',') : '',
minWidth: 180 minWidth: 180