From 746977ae6cf544f92627bc3552763996025cb0b6 Mon Sep 17 00:00:00 2001 From: zhaowei <zhaowei> Date: 星期五, 10 一月 2025 14:54:27 +0800 Subject: [PATCH] DNC产品结构树合并至MDC,已初步完成页面布局,现正在完善各个功能弹窗逻辑 --- src/views/dnc/base/modules/ProductStructure/Document/DocumentInfo.vue | 36 src/views/dnc/base/modules/ProductStructure/ProcessStep/ProcessStepInfo.vue | 20 src/views/dnc/base/modules/ProductStructure/Document/DocumentVersionTableList.vue | 42 src/views/dnc/common/modules/ProductStructureTree/ProductStructureTreeContextMenu.vue | 118 ++ src/views/dnc/base/modules/ProductStructure/Document/UseDocumentEquipmentTableList.vue | 45 src/views/dnc/base/modules/ProductStructure/Process/ProcessModalForm.vue | 196 ++++ src/views/dnc/base/modules/ProductStructure/Process/ProcessTableList.vue | 248 +++++ src/views/dnc/base/modules/ProductStructure/ProductStructureMain.vue | 32 src/views/dnc/base/modules/ProductStructure/ProductStructureMainBottom.vue | 91 + src/views/dnc/common/ProductStructureTree.vue | 644 +++++++++++++ src/views/dnc/common/TableContextMenu.vue | 87 + src/views/dnc/base/ProductStructure.vue | 35 src/views/dnc/base/modules/ProductStructure/Component/ComponentModal.vue | 92 + src/views/dnc/base/modules/ProductStructure/Document/NcDocumentTableList.vue | 199 ++++ src/views/dnc/common/ImportFileModal.vue | 122 ++ src/views/dnc/base/modules/ProductStructure/Process/ProcessInfo.vue | 44 src/views/dnc/base/modules/ProductStructure/Process/ProcessModal.vue | 56 + src/views/dnc/base/modules/ProductStructure/Product/ProductInfo.vue | 34 src/views/dnc/base/modules/ProductStructure/Component/ComponentInfo.vue | 43 src/views/dnc/base/modules/ProductStructure/Document/OtherDocumentTableList.vue | 133 ++ src/views/dnc/base/modules/ProductStructure/Product/ProductModal.vue | 70 + src/views/dnc/base/modules/ProductStructure/Product/ProductModalForm.vue | 126 ++ src/main.js | 3 src/views/dnc/base/modules/ProductStructure/ProductStructureMainTop.vue | 76 + src/views/dnc/base/modules/ProductStructure/Component/ComponentModalForm.vue | 174 +++ src/views/dnc/base/modules/ProductStructure/Part/PartInfo.vue | 43 26 files changed, 2,809 insertions(+), 0 deletions(-) diff --git a/src/main.js b/src/main.js index ebd34ec..5ce1354 100644 --- a/src/main.js +++ b/src/main.js @@ -80,6 +80,9 @@ new Vue({ router, store, + beforeCreate() { + Vue.prototype.$bus = new Vue() + }, mounted () { store.commit('SET_SIDEBAR_TYPE', Vue.ls.get(SIDEBAR_TYPE, true)) store.commit('TOGGLE_THEME', Vue.ls.get(DEFAULT_THEME, config.navTheme)) diff --git a/src/views/dnc/base/ProductStructure.vue b/src/views/dnc/base/ProductStructure.vue new file mode 100644 index 0000000..0effc31 --- /dev/null +++ b/src/views/dnc/base/ProductStructure.vue @@ -0,0 +1,35 @@ +<template> + <a-card :bordered="false"> + <a-row type="flex" :gutter="16"> + <a-col :md="5"> + <ProductStructureTree/> + </a-col> + <a-col :md="19"> + <ProductStructureMain/> + </a-col> + </a-row> + </a-card> +</template> + +<script> + import ProductStructureTree from '../common/ProductStructureTree' + import ProductStructureMain from './modules/ProductStructure/ProductStructureMain' + + export default { + name: 'ProductStructure', + components: { + ProductStructureTree, + ProductStructureMain + }, + data() { + return {} + }, + methods: {} + } +</script> + +<style scoped lang="less"> + /deep/ .ant-card-body { + padding: 8px; + } +</style> \ No newline at end of file diff --git a/src/views/dnc/base/modules/ProductStructure/Component/ComponentInfo.vue b/src/views/dnc/base/modules/ProductStructure/Component/ComponentInfo.vue new file mode 100644 index 0000000..84d9e3a --- /dev/null +++ b/src/views/dnc/base/modules/ProductStructure/Component/ComponentInfo.vue @@ -0,0 +1,43 @@ +<template> + <a-descriptions bordered :size="size"> + <a-descriptions-item label="閮ㄤ欢鍚嶇О">{{currentLevelDetails.componentName}}</a-descriptions-item> + <a-descriptions-item label="閮ㄤ欢浠e彿">{{currentLevelDetails.componentCode}}</a-descriptions-item> + <a-descriptions-item label="閮ㄤ欢鍨嬪彿 ">{{currentLevelDetails.componentModel}}</a-descriptions-item> + <a-descriptions-item label="鐗╂枡缂栫爜">{{currentLevelDetails.materielCode}}</a-descriptions-item> + <a-descriptions-item label="鏉愭枡">{{currentLevelDetails.materielDesp}}</a-descriptions-item> + <a-descriptions-item label="瑙勬牸 ">{{currentLevelDetails.componentScale}}</a-descriptions-item> + <a-descriptions-item label="瑁呴厤绫诲瀷">{{currentLevelDetails.assembleType}}</a-descriptions-item> + <a-descriptions-item label="鐢熶骇绫诲瀷">{{currentLevelDetails.produceType}}</a-descriptions-item> + <a-descriptions-item label="澶勭悊绫诲瀷 ">{{currentLevelDetails.processType}}</a-descriptions-item> + <a-descriptions-item label="缁撴瀯绫诲瀷 ">{{currentLevelDetails.structureType}}</a-descriptions-item> + <a-descriptions-item label="閲嶉噺" :span="2">{{currentLevelDetails.componentWeight}}</a-descriptions-item> + <a-descriptions-item label="鍒涘缓浜�">{{currentLevelDetails.createUser_dicText}}</a-descriptions-item> + <a-descriptions-item label="鍒涘缓鏃堕棿" :span="2">{{currentLevelDetails.createTime}}</a-descriptions-item> + <a-descriptions-item label="淇敼浜�">{{currentLevelDetails.updateUser_dicText}}</a-descriptions-item> + <a-descriptions-item label="淇敼鏃堕棿" :span="2">{{currentLevelDetails.updateTime}}</a-descriptions-item> + <a-descriptions-item label="鎻忚堪" :span="3">{{currentLevelDetails.description}}</a-descriptions-item> + </a-descriptions> +</template> + +<script> + export default { + name: 'ComponentInfo', + components: {}, + props: { + currentLevelDetails: { + type: Object + }, + size: { + type: String + } + }, + data() { + return {} + }, + methods: {} + } +</script> + +<style scoped> + +</style> \ No newline at end of file diff --git a/src/views/dnc/base/modules/ProductStructure/Component/ComponentModal.vue b/src/views/dnc/base/modules/ProductStructure/Component/ComponentModal.vue new file mode 100644 index 0000000..2b8c8f6 --- /dev/null +++ b/src/views/dnc/base/modules/ProductStructure/Component/ComponentModal.vue @@ -0,0 +1,92 @@ +<template> + <j-modal + :title="title" + :width="width" + :visible="visible" + switchFullscreen + :maskClosable="false" + @ok="handleOk" + @cancel="handleCancel" + cancelText="鍏抽棴"> + <ComponentModalForm ref="realForm" @ok="submitCallback"/> + </j-modal> +</template> + +<script> + import ComponentModalForm from './ComponentModalForm.vue' + + export default { + name: 'ComponentModal', + components: { + ComponentModalForm + }, + props: { + currentTreeNodeInfo: { + type: Object + } + }, + data() { + return { + title: '', + width: 700, + visible: false + } + }, + created() { + this.$bus.$on('treeMenuItemMethodTrigger', this.triggerCorrespondingMethod) + }, + methods: { + /** + * 娣诲姞褰撳墠浜у搧閮ㄤ欢 + * @param modalTitle + */ + handleProductAddChild(modalTitle) { + this.title = modalTitle + this.visible = true + this.$nextTick(() => { + this.$refs.realForm.add() + }) + }, + + /** + * 娣诲姞褰撳墠閮ㄤ欢鐨勫瓙閮ㄤ欢 + * @param modalTitle + */ + handleComponentAdd(modalTitle) { + this.title = modalTitle + this.visible = true + this.$nextTick(() => { + this.$refs.realForm.add() + }) + }, + + handleComponentEdit(modalTitle) { + this.title = modalTitle + this.visible = true + this.$nextTick(() => { + this.$refs.realForm.edit(this.currentTreeNodeInfo.entity) + }) + }, + + handleOk() { + this.$refs.realForm.submitForm() + }, + + submitCallback() { + this.$emit('ok') + this.visible = false + }, + + handleCancel() { + this.$emit('close') + this.visible = false + }, + + triggerCorrespondingMethod({ methodName, modalTitle }) { + console.log('methodName', methodName) + console.log('modalTitle', modalTitle) + if (this[methodName]) this[methodName](modalTitle) + } + } + } +</script> \ No newline at end of file diff --git a/src/views/dnc/base/modules/ProductStructure/Component/ComponentModalForm.vue b/src/views/dnc/base/modules/ProductStructure/Component/ComponentModalForm.vue new file mode 100644 index 0000000..b6e6eef --- /dev/null +++ b/src/views/dnc/base/modules/ProductStructure/Component/ComponentModalForm.vue @@ -0,0 +1,174 @@ +<template> + <a-spin :spinning="confirmLoading"> + <a-form-model ref="form" :model="model" :rules="validatorRules" :labelCol="labelCol" :wrapperCol="wrapperCol"> + <a-row> + <a-col :span="12"> + <a-form-model-item label="閮ㄤ欢鍚嶇О" prop="componentName"> + <a-input v-model="model.componentName" placeholder="璇疯緭鍏ラ儴浠跺悕绉�"></a-input> + </a-form-model-item> + </a-col> + <a-col :span="12"> + <a-form-model-item label="浠e彿" prop="componentCode"> + <a-input v-model="model.componentCode" placeholder="璇疯緭鍏ヤ唬鍙�"></a-input> + </a-form-model-item> + </a-col> + </a-row> + + <a-row> + <a-col :span="12"> + <a-form-model-item label="閮ㄤ欢鍨嬪彿"> + <a-input v-model="model.componentModel" placeholder="璇疯緭鍏ラ儴浠跺瀷鍙�"></a-input> + </a-form-model-item> + </a-col> + <a-col :span="12"> + <a-form-model-item label="瑙勬牸"> + <a-input v-model="model.productName" placeholder="璇疯緭鍏ヨ鏍�"></a-input> + </a-form-model-item> + </a-col> + </a-row> + + <a-row> + <a-col :span="12"> + <a-form-model-item label="瑁呴厤绫诲瀷" :labelCol="labelCol" :wrapperCol="wrapperCol"> + <a-input v-model="model.assembleType" placeholder="璇疯緭鍏ヨ閰嶇被鍨�"></a-input> + </a-form-model-item> + </a-col> + <a-col :span="12"> + <a-form-model-item label="閲嶉噺"> + <a-input v-model="model.componentWeight" placeholder="璇疯緭鍏ラ噸閲�"></a-input> + </a-form-model-item> + </a-col> + </a-row> + + <a-row> + <a-col :span="12"> + <a-form-model-item label="鐗╂枡缂栫爜"> + <a-input v-model="model.materielCode" placeholder="璇疯緭鍏ョ墿鏂欑紪鐮�"></a-input> + </a-form-model-item> + </a-col> + <a-col :span="12"> + <a-form-model-item label="缁撴瀯绫诲瀷"> + <a-input v-model="model.structureType" placeholder="璇疯緭鍏ョ粨鏋勭被鍨�"></a-input> + </a-form-model-item> + </a-col> + </a-row> + + <a-row> + <a-col :span="12"> + <a-form-model-item label="澶勭悊绫诲瀷"> + <a-input v-model="model.processType" placeholder="璇疯緭鍏ュ鐞嗙被鍨�"></a-input> + </a-form-model-item> + </a-col> + <a-col :span="12"> + <a-form-model-item label="鐢熶骇绫诲瀷"> + <a-input v-model="model.produceType" placeholder="璇疯緭鍏ョ敓浜х被鍨�"></a-input> + </a-form-model-item> + </a-col> + </a-row> + + <a-row> + <a-col :span="24"> + <a-form-model-item label="鎻忚堪" :labelCol="labelColLong" :wrapperCol="wrapperColLong"> + <a-textarea v-model="model.description" placeholder="璇疯緭鍏ユ弿杩�"></a-textarea> + </a-form-model-item> + </a-col> + </a-row> + </a-form-model> + </a-spin> +</template> + +<script> + import { httpAction, getAction } from '@/api/manage' + + export default { + name: 'ComponentModalForm', + components: {}, + data() { + return { + model: {}, + labelCol: { + xs: { span: 24 }, + sm: { span: 8 } + }, + wrapperCol: { + xs: { span: 24 }, + sm: { span: 14 } + }, + labelColLong: { + xs: { span: 24 }, + sm: { span: 4 } + }, + wrapperColLong: { + xs: { span: 24 }, + sm: { span: 19 } + }, + confirmLoading: false, + validatorRules: { + componentName: [ + { required: true, message: '璇疯緭鍏ラ儴浠跺悕绉�!' } + ], + componentCode: [ + { required: true, message: '璇疯緭鍏ヤ唬鍙�!' } + ] + }, + url: { + add: '/mdc/mdcPartProcessInfo/add', + edit: '/mdc/mdcPartProcessInfo/edit' + } + } + }, + computed: { + formDisabled() { + return this.disabled + } + }, + created() { + //澶囦唤model鍘熷鍊� + this.modelDefault = JSON.parse(JSON.stringify(this.model)) + }, + methods: { + add() { + this.edit(this.modelDefault) + }, + + edit(record) { + this.model = Object.assign({}, record) + console.log('model', this.model) + this.visible = true + }, + + submitForm() { + const that = this + // 瑙﹀彂琛ㄥ崟楠岃瘉 + this.$refs.form.validate(valid => { + if (valid) { + that.confirmLoading = true + let httpUrl = '' + let method = 'post' + if (!this.model.id) { + httpUrl += this.url.add + } else { + httpUrl += this.url.edit + } + httpAction(httpUrl, this.model, method).then((res) => { + if (res.success) { + that.$notification.success({ + message: '娑堟伅', + description: res.message + }) + that.$emit('ok') + } else { + that.$notification.warning({ + message: '娑堟伅', + description: res.message + }) + } + }).finally(() => { + that.confirmLoading = false + }) + } + }) + } + } + } +</script> diff --git a/src/views/dnc/base/modules/ProductStructure/Document/DocumentInfo.vue b/src/views/dnc/base/modules/ProductStructure/Document/DocumentInfo.vue new file mode 100644 index 0000000..d100d67 --- /dev/null +++ b/src/views/dnc/base/modules/ProductStructure/Document/DocumentInfo.vue @@ -0,0 +1,36 @@ +<template> + <a-descriptions bordered :size="size"> + <a-descriptions-item label="鏂囨。鍚嶇О">{{currentLevelDetails.docName}}</a-descriptions-item> + <a-descriptions-item label="浠g爜鐗堟湰">{{currentLevelDetails.docAlias}}</a-descriptions-item> + <a-descriptions-item label="璁惧缂栧彿 ">{{currentLevelDetails.docCode}}</a-descriptions-item> + <a-descriptions-item label="鏂囨。鍚庣紑">{{currentLevelDetails.docSuffix}}</a-descriptions-item> + <a-descriptions-item label="鏂囨。鐘舵��">{{currentLevelDetails.docStatus}}</a-descriptions-item> + <a-descriptions-item label="绯荤粺鎸囧畾鐗堟湰">{{currentLevelDetails.publishVersion}}</a-descriptions-item> + <a-descriptions-item label="鍑哄簱鐘舵��">{{currentLevelDetails.pullStatus}}</a-descriptions-item> + <a-descriptions-item label="鍑哄簱浜�" :span="2">{{currentLevelDetails.pullUser}}</a-descriptions-item> + <a-descriptions-item label="鎻忚堪" :span="3">{{currentLevelDetails.description}}</a-descriptions-item> + </a-descriptions> +</template> + +<script> + export default { + name: 'DocumentInfo', + components: {}, + props: { + currentLevelDetails: { + type: Object + }, + size: { + type: String + } + }, + data() { + return {} + }, + methods: {} + } +</script> + +<style scoped> + +</style> \ No newline at end of file diff --git a/src/views/dnc/base/modules/ProductStructure/Document/DocumentVersionTableList.vue b/src/views/dnc/base/modules/ProductStructure/Document/DocumentVersionTableList.vue new file mode 100644 index 0000000..14f5344 --- /dev/null +++ b/src/views/dnc/base/modules/ProductStructure/Document/DocumentVersionTableList.vue @@ -0,0 +1,42 @@ +<template> + <a-table :columns="columns" :data-source="dataSource" bordered :pagination="false"> + + </a-table> +</template> + +<script> + import { JeecgListMixin } from '@/mixins/JeecgListMixin' + + export default { + name: 'DocumentVersionTableList', + mixins: [JeecgListMixin], + components: {}, + data() { + return { + columns: [ + { + title: '搴忓彿', + dataIndex: 'rowIndex', + key: 'rowIndex', + width: 65, + align: 'center', + customRender: function(t, r, index) { + return parseInt(index) + 1 + } + }, + { title: '鏂囦欢鍚嶇О', dataIndex: 'fileName', align: 'center' }, + { title: '鐗堟湰鍙�', dataIndex: 'docVersion', align: 'center' }, + { title: '鏂囦欢澶у皬', dataIndex: 'fileSize', align: 'center' } + ], + url: { + list: '' + } + } + }, + methods: {} + } +</script> + +<style scoped> + +</style> \ No newline at end of file diff --git a/src/views/dnc/base/modules/ProductStructure/Document/NcDocumentTableList.vue b/src/views/dnc/base/modules/ProductStructure/Document/NcDocumentTableList.vue new file mode 100644 index 0000000..f4f7136 --- /dev/null +++ b/src/views/dnc/base/modules/ProductStructure/Document/NcDocumentTableList.vue @@ -0,0 +1,199 @@ +<template> + <a-table :columns="columns" :data-source="dataSource" bordered :pagination="ipagination" + :scroll="{y:189}" :customRow="customRow" :size="size" rowKey="docId"> + + </a-table> +</template> + +<script> + import { JeecgListMixin } from '@/mixins/JeecgListMixin' + + export default { + name: 'NcDocumentTableList', + components: {}, + mixins: [JeecgListMixin], + props: { + size: { + type: String + } + }, + data() { + return { + columns: [ + { + title: '搴忓彿', + dataIndex: 'rowIndex', + key: 'rowIndex', + width: 65, + align: 'center', + customRender: function(t, r, index) { + return parseInt(index) + 1 + } + }, + { title: '鏂囦欢鍚嶇О', dataIndex: 'docName', align: 'center' }, + { title: '浠g爜鐗堟湰', dataIndex: 'docAlias', align: 'center' }, + { title: '鍑哄簱鐘舵��', dataIndex: 'pullStatus', align: 'center' }, + { title: '鐘� 鎬�', dataIndex: 'docStatus', align: 'center' }, + { title: '绯荤粺鎸囧畾鐗堟湰', dataIndex: 'publishVersion', align: 'center' }, + { title: '涓婁紶鏃堕棿', dataIndex: 'createTime', align: 'center' } + ], + dataSource: [ + { + 'docId': '1876099281127645185', + 'docName': 'avatar2.jpg', + 'docAlias': null, + 'docCode': null, + 'docSuffix': 'jpg', + 'docStatus': 1, + 'publishFileId': '1876099281458995202', + 'publishVersion': 'a.1', + 'description': null, + 'createTime': '2025-01-06 10:51:40', + 'updateTime': null, + 'createUser': '1254966905669160962', + 'updateUser': null, + 'docClassCode': null, + 'pullStatus': 1, + 'pullUser': null, + 'attributionType': 5, + 'attributionId': '1868504592315248641', + 'classificationId': '1257965381181095938', + 'syncStatus': null + }, + { + 'docId': '1876114720452943873', + 'docName': 'color.less', + 'docAlias': null, + 'docCode': null, + 'docSuffix': 'less', + 'docStatus': 1, + 'publishFileId': '1876114720582967297', + 'publishVersion': 'a.1', + 'description': null, + 'createTime': '2025-01-06 11:53:01', + 'updateTime': null, + 'createUser': '1254966905669160962', + 'updateUser': null, + 'docClassCode': null, + 'pullStatus': 1, + 'pullUser': null, + 'attributionType': 5, + 'attributionId': '1868504592315248641', + 'classificationId': '1257965381181095938', + 'syncStatus': null + }, + { + 'docId': '1876114736512933889', + 'docName': 'index.html', + 'docAlias': null, + 'docCode': null, + 'docSuffix': 'html', + 'docStatus': 1, + 'publishFileId': '1876114736705871874', + 'publishVersion': 'a.1', + 'description': null, + 'createTime': '2025-01-06 11:53:05', + 'updateTime': null, + 'createUser': '1254966905669160962', + 'updateUser': null, + 'docClassCode': null, + 'pullStatus': 1, + 'pullUser': null, + 'attributionType': 5, + 'attributionId': '1868504592315248641', + 'classificationId': '1257965381181095938', + 'syncStatus': null + }, + { + 'docId': '1876114746621206529', + 'docName': 'logo.png', + 'docAlias': null, + 'docCode': null, + 'docSuffix': 'png', + 'docStatus': 1, + 'publishFileId': '1876114746818338818', + 'publishVersion': 'a.1', + 'description': null, + 'createTime': '2025-01-06 11:53:07', + 'updateTime': null, + 'createUser': '1254966905669160962', + 'updateUser': null, + 'docClassCode': null, + 'pullStatus': 1, + 'pullUser': null, + 'attributionType': 5, + 'attributionId': '1868504592315248641', + 'classificationId': '1257965381181095938', + 'syncStatus': null + }, + { + 'docId': '1876114758923100161', + 'docName': 'lxzn.png', + 'docAlias': null, + 'docCode': null, + 'docSuffix': 'png', + 'docStatus': 1, + 'publishFileId': '1876114759111843842', + 'publishVersion': 'a.1', + 'description': null, + 'createTime': '2025-01-06 11:53:10', + 'updateTime': null, + 'createUser': '1254966905669160962', + 'updateUser': null, + 'docClassCode': null, + 'pullStatus': 1, + 'pullUser': null, + 'attributionType': 5, + 'attributionId': '1868504592315248641', + 'classificationId': '1257965381181095938', + 'syncStatus': null + }, + { + 'docId': '1876114776241381377', + 'docName': 'v2.js', + 'docAlias': null, + 'docCode': null, + 'docSuffix': 'js', + 'docStatus': 1, + 'publishFileId': '1876114776438513666', + 'publishVersion': 'a.1', + 'description': null, + 'createTime': '2025-01-06 11:53:14', + 'updateTime': null, + 'createUser': '1254966905669160962', + 'updateUser': null, + 'docClassCode': null, + 'pullStatus': 1, + 'pullUser': null, + 'attributionType': 5, + 'attributionId': '1868504592315248641', + 'classificationId': '1257965381181095938', + 'syncStatus': null + } + ], + url: { + list: '' + } + } + }, + methods: { + customRow(record) { + return { + on: { + contextmenu: event => { + event.preventDefault() + this.$emit('handleTableContextMenuOpen', { ...record, param: 'document' }) + }, + click: () => { + this.$bus.$emit('sendCurrentLevelInfo', record) + } + } + } + } + } + } +</script> + +<style scoped> + +</style> \ No newline at end of file diff --git a/src/views/dnc/base/modules/ProductStructure/Document/OtherDocumentTableList.vue b/src/views/dnc/base/modules/ProductStructure/Document/OtherDocumentTableList.vue new file mode 100644 index 0000000..7ba6363 --- /dev/null +++ b/src/views/dnc/base/modules/ProductStructure/Document/OtherDocumentTableList.vue @@ -0,0 +1,133 @@ +<template> + <a-table :columns="columns" :data-source="dataSource" bordered :pagination="ipagination" + :scroll="{y:189}" :customRow="customRow" :size="size"> + + </a-table> +</template> + +<script> + import { JeecgListMixin } from '@/mixins/JeecgListMixin' + + export default { + name: 'OtherDocumentTableList', + components: {}, + mixins: [JeecgListMixin], + props: { + size: { + type: String + } + }, + data() { + return { + columns: [ + { + title: '搴忓彿', + dataIndex: 'rowIndex', + key: 'rowIndex', + width: 65, + align: 'center', + customRender: function(t, r, index) { + return parseInt(index) + 1 + } + }, + { title: '鏂囦欢鍚嶇О', dataIndex: 'docName', align: 'center' }, + { title: '璁惧缂栧彿', dataIndex: 'docCode', align: 'center' }, + { title: '鍑哄簱鐘舵��', dataIndex: 'pullStatus', align: 'center' }, + { title: '鐘� 鎬�', dataIndex: 'docStatus', align: 'center' }, + { title: '绯荤粺鎸囧畾鐗堟湰', dataIndex: 'publishVersion', align: 'center' }, + { title: '涓婁紶鏃堕棿', dataIndex: 'createTime', align: 'center' } + ], + dataSource: [ + { + 'docId': '1868943615190044674', + 'docName': '娴嬭瘯.nc', + 'docAlias': null, + 'docCode': null, + 'docSuffix': 'nc', + 'docStatus': 1, + 'publishFileId': '1868943615454285825', + 'publishVersion': 'a.1', + 'description': null, + 'createTime': '2024-12-17 16:57:36', + 'updateTime': null, + 'createUser': '1254966905669160962', + 'updateUser': null, + 'docClassCode': null, + 'pullStatus': 1, + 'pullUser': null, + 'attributionType': 1, + 'attributionId': '1326377675659276290', + 'classificationId': '1257965467827027969', + 'syncStatus': null + }, + { + 'docId': '1868946627732103170', + 'docName': 'nacos-config.sh', + 'docAlias': null, + 'docCode': null, + 'docSuffix': 'sh', + 'docStatus': 1, + 'publishFileId': '1868946628004732930', + 'publishVersion': 'a.1', + 'description': null, + 'createTime': '2024-12-17 17:09:34', + 'updateTime': null, + 'createUser': '1254966905669160962', + 'updateUser': null, + 'docClassCode': null, + 'pullStatus': 1, + 'pullUser': null, + 'attributionType': 1, + 'attributionId': '1326377675659276290', + 'classificationId': '1257965467827027969', + 'syncStatus': null + }, + { + 'docId': '1868947564353740801', + 'docName': 'dir.sql', + 'docAlias': null, + 'docCode': null, + 'docSuffix': 'sql', + 'docStatus': 1, + 'publishFileId': '1868947564487958530', + 'publishVersion': 'a.1', + 'description': null, + 'createTime': '2024-12-17 17:13:17', + 'updateTime': null, + 'createUser': '1254966905669160962', + 'updateUser': null, + 'docClassCode': null, + 'pullStatus': 1, + 'pullUser': null, + 'attributionType': 1, + 'attributionId': '1326377675659276290', + 'classificationId': '1257965467827027969', + 'syncStatus': null + } + ], + url: { + list: '' + } + } + }, + methods: { + customRow(record) { + return { + on: { + contextmenu: event => { + event.preventDefault() + this.$emit('handleTableContextMenuOpen', { ...record, param: 'document' }) + }, + click: () => { + this.$bus.$emit('sendCurrentLevelInfo', record) + } + } + } + } + } + } +</script> + +<style scoped> + +</style> \ No newline at end of file diff --git a/src/views/dnc/base/modules/ProductStructure/Document/UseDocumentEquipmentTableList.vue b/src/views/dnc/base/modules/ProductStructure/Document/UseDocumentEquipmentTableList.vue new file mode 100644 index 0000000..423f62c --- /dev/null +++ b/src/views/dnc/base/modules/ProductStructure/Document/UseDocumentEquipmentTableList.vue @@ -0,0 +1,45 @@ +<template> + <a-table :columns="columns" :data-source="dataSource" bordered :pagination="false"> + + </a-table> +</template> + +<script> + import { JeecgListMixin } from '@/mixins/JeecgListMixin' + + export default { + name: 'UseDocumentEquipmentTableList', + components: {}, + mixins: [JeecgListMixin], + data() { + return { + columns: [ + { + title: '搴忓彿', + dataIndex: 'rowIndex', + key: 'rowIndex', + width: 65, + align: 'center', + customRender: function(t, r, index) { + return parseInt(index) + 1 + } + }, + { title: '璁惧鍚嶇О', dataIndex: 'deviceName', align: 'center' }, + { title: '璁惧缂栧彿', dataIndex: 'deviceNo', align: 'center' }, + { title: '璁惧鍨嬪彿', dataIndex: 'deviceModel', align: 'center' }, + { title: '鎵�灞為儴闂�', dataIndex: 'departName', align: 'center' }, + { title: '璁惧鍒嗙粍', dataIndex: 'groupName', align: 'center' }, + { title: '鎺у埗绯荤粺', dataIndex: 'controlSystem', align: 'center' } + ], + url: { + list: '' + } + } + }, + methods: {} + } +</script> + +<style scoped> + +</style> \ No newline at end of file diff --git a/src/views/dnc/base/modules/ProductStructure/Part/PartInfo.vue b/src/views/dnc/base/modules/ProductStructure/Part/PartInfo.vue new file mode 100644 index 0000000..5f43682 --- /dev/null +++ b/src/views/dnc/base/modules/ProductStructure/Part/PartInfo.vue @@ -0,0 +1,43 @@ +<template> + <a-descriptions bordered :size="size"> + <a-descriptions-item label="闆朵欢鍚嶇О">{{currentLevelDetails.partsName}}</a-descriptions-item> + <a-descriptions-item label="闆朵欢浠e彿">{{currentLevelDetails.partsCode}}</a-descriptions-item> + <a-descriptions-item label="闆朵欢鍨嬪彿 ">{{currentLevelDetails.partsModel}}</a-descriptions-item> + <a-descriptions-item label="鐗╂枡缂栫爜">{{currentLevelDetails.materielCode}}</a-descriptions-item> + <a-descriptions-item label="鏉愭枡">{{currentLevelDetails.materielDesp}}</a-descriptions-item> + <a-descriptions-item label="瑙勬牸 ">{{currentLevelDetails.partsScale}}</a-descriptions-item> + <a-descriptions-item label="瑁呴厤绫诲瀷">{{currentLevelDetails.assembleType}}</a-descriptions-item> + <a-descriptions-item label="鐢熶骇绫诲瀷">{{currentLevelDetails.produceType}}</a-descriptions-item> + <a-descriptions-item label="澶勭悊绫诲瀷 ">{{currentLevelDetails.processType}}</a-descriptions-item> + <a-descriptions-item label="缁撴瀯绫诲瀷 ">{{currentLevelDetails.structureType}}</a-descriptions-item> + <a-descriptions-item label="閲嶉噺" :span="2">{{currentLevelDetails.partsWeight}}</a-descriptions-item> + <a-descriptions-item label="鍒涘缓浜�">{{currentLevelDetails.createUser_dicText}}</a-descriptions-item> + <a-descriptions-item label="鍒涘缓鏃堕棿" :span="2">{{currentLevelDetails.createTime}}</a-descriptions-item> + <a-descriptions-item label="淇敼浜�">{{currentLevelDetails.updateUser_dicText}}</a-descriptions-item> + <a-descriptions-item label="淇敼鏃堕棿" :span="2">{{currentLevelDetails.updateTime}}</a-descriptions-item> + <a-descriptions-item label="鎻忚堪" :span="3">{{currentLevelDetails.description}}</a-descriptions-item> + </a-descriptions> +</template> + +<script> + export default { + name: 'PartInfo', + components: {}, + props: { + currentLevelDetails: { + type: Object + }, + size: { + type: String + } + }, + data() { + return {} + }, + methods: {} + } +</script> + +<style scoped> + +</style> \ No newline at end of file diff --git a/src/views/dnc/base/modules/ProductStructure/Process/ProcessInfo.vue b/src/views/dnc/base/modules/ProductStructure/Process/ProcessInfo.vue new file mode 100644 index 0000000..e440a15 --- /dev/null +++ b/src/views/dnc/base/modules/ProductStructure/Process/ProcessInfo.vue @@ -0,0 +1,44 @@ +<template> + <a-descriptions bordered :size="size"> + <a-descriptions-item label="宸ュ簭鍚嶇О">{{currentLevelDetails.processName|isValueNull}}</a-descriptions-item> + <a-descriptions-item label="宸ュ簭鍙�">{{currentLevelDetails.processCode|isValueNull}}</a-descriptions-item> + <a-descriptions-item label="宸ヨ壓缂栧彿 ">{{currentLevelDetails.craftNo|isValueNull}}</a-descriptions-item> + <a-descriptions-item label="宸ュ簭绫诲瀷">{{currentLevelDetails.processType|isValueNull}}</a-descriptions-item> + <a-descriptions-item label="鍔犲伐璁惧鍨嬪彿">{{currentLevelDetails.processingEquipmentModel|isValueNull}} + </a-descriptions-item> + <a-descriptions-item label="鍔犲伐璁惧绫诲瀷">{{currentLevelDetails.processingEquipmentOs|isValueNull}}</a-descriptions-item> + <a-descriptions-item label="鍔犲伐璁惧缂栧彿">{{currentLevelDetails.processingEquipmentCode|isValueNull}} + </a-descriptions-item> + <a-descriptions-item label="宸ヨ缂栧彿">{{currentLevelDetails.assembleStep|isValueNull}}</a-descriptions-item> + <a-descriptions-item label="宸ヨ鍚嶇О ">{{currentLevelDetails.assembleName|isValueNull}}</a-descriptions-item> + <a-descriptions-item label="鎻忚堪" :span="3">{{currentLevelDetails.description|isValueNull}}</a-descriptions-item> + </a-descriptions> +</template> + +<script> + export default { + name: 'ProcessInfo', + components: {}, + props: { + currentLevelDetails: { + type: Object + }, + size: { + type: String + } + }, + filters: { + isValueNull(value) { + return !value || value == null ? '' : value + } + }, + data() { + return {} + }, + methods: {} + } +</script> + +<style scoped> + +</style> \ No newline at end of file diff --git a/src/views/dnc/base/modules/ProductStructure/Process/ProcessModal.vue b/src/views/dnc/base/modules/ProductStructure/Process/ProcessModal.vue new file mode 100644 index 0000000..60bea4b --- /dev/null +++ b/src/views/dnc/base/modules/ProductStructure/Process/ProcessModal.vue @@ -0,0 +1,56 @@ +<template> + <j-modal + :title="title" + :width="width" + :visible="visible" + switchFullscreen + :maskClosable="false" + @ok="handleOk" + @cancel="handleCancel" + cancelText="鍏抽棴"> + <ProcessModalForm ref="realForm" @ok="submitCallback"/> + </j-modal> +</template> + +<script> + import ProcessModalForm from './ProcessModalForm.vue' + + export default { + name: 'ProcessModal', + components: { + ProcessModalForm + }, + data() { + return { + title: '', + width: 700, + visible: false + } + }, + methods: { + add() { + this.visible = true + this.$nextTick(() => { + this.$refs.realForm.add() + }) + }, + edit(record) { + this.visible = true + this.$nextTick(() => { + this.$refs.realForm.edit(record) + }) + }, + handleOk() { + this.$refs.realForm.submitForm() + }, + submitCallback() { + this.$emit('ok') + this.visible = false + }, + handleCancel() { + this.$emit('close') + this.visible = false + } + } + } +</script> \ No newline at end of file diff --git a/src/views/dnc/base/modules/ProductStructure/Process/ProcessModalForm.vue b/src/views/dnc/base/modules/ProductStructure/Process/ProcessModalForm.vue new file mode 100644 index 0000000..cd0e076 --- /dev/null +++ b/src/views/dnc/base/modules/ProductStructure/Process/ProcessModalForm.vue @@ -0,0 +1,196 @@ +<template> + <a-spin :spinning="confirmLoading"> + <a-form-model ref="form" :model="model" :rules="validatorRules"> + <a-row> + <a-col :span="12"> + <a-form-model-item label="宸ュ簭鍙�" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="processCode"> + <a-input v-model="model.processCode" placeholder="璇疯緭鍏ュ伐搴忓彿"></a-input> + </a-form-model-item> + </a-col> + <a-col :span="12"> + <a-form-model-item label="宸ュ簭鍚嶇О" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="processName"> + <a-input v-model="model.processName" placeholder="璇疯緭鍏ュ伐搴忓悕绉�"></a-input> + </a-form-model-item> + </a-col> + </a-row> + + <a-row> + <a-col :span="24"> + <a-form-model-item label="鍔犲伐璁惧缂栧彿" :labelCol="labelColLong" :wrapperCol="wrapperColLong"> + <a-select v-model="model.processingEquipmentCode" placeholder="璇烽�夋嫨鍔犲伐璁惧缂栧彿"></a-select> + </a-form-model-item> + </a-col> + </a-row> + + <a-row> + <a-col :span="12"> + <a-form-model-item label="宸ヨ壓缂栧彿" :labelCol="labelCol" :wrapperCol="wrapperCol"> + <a-input v-model="model.craftNo" placeholder="璇疯緭鍏ュ伐鑹虹紪鍙�"></a-input> + </a-form-model-item> + </a-col> + <a-col :span="12"> + <a-form-model-item label="宸ヨ壓瑙勭▼鐗堟湰" :labelCol="labelCol" :wrapperCol="wrapperCol"> + <a-input v-model="model.craftVersion" placeholder="璇疯緭鍏ュ伐鑹鸿绋嬬増鏈�"></a-input> + </a-form-model-item> + </a-col> + </a-row> + + <a-row> + <a-col :span="12"> + <a-form-model-item label="宸ュ簭绫诲瀷" :labelCol="labelCol" :wrapperCol="wrapperCol"> + <a-input v-model="model.processType" placeholder="璇疯緭鍏ュ伐搴忕被鍨�"></a-input> + </a-form-model-item> + </a-col> + <a-col :span="12"> + <a-form-model-item label="宸ュ簭鎻忚堪" :labelCol="labelCol" :wrapperCol="wrapperCol"> + <a-input v-model="model.description" placeholder="璇疯緭鍏ュ伐搴忔弿杩�"></a-input> + </a-form-model-item> + </a-col> + </a-row> + + <a-row> + <a-col :span="12"> + <a-form-model-item label="宸ヨ缂栧彿" :labelCol="labelCol" :wrapperCol="wrapperCol"> + <a-input v-model="model.assembleStep" placeholder="璇疯緭鍏ュ伐瑁呯紪鍙�"></a-input> + </a-form-model-item> + </a-col> + <a-col :span="12"> + <a-form-model-item label="宸ヨ鍚嶇О" :labelCol="labelCol" :wrapperCol="wrapperCol"> + <a-input v-model="model.assembleName" placeholder="璇疯緭鍏ュ伐瑁呭悕绉�"></a-input> + </a-form-model-item> + </a-col> + </a-row> + </a-form-model> + + <select-device-drawer ref="selectDeviceDrawer" @selectFinished="selectOK" :title="'閫夋嫨璁惧'"/> + </a-spin> +</template> + +<script> + import { httpAction, getAction } from '@/api/manage' + import SelectDeviceDrawer from '@/views/system/modules/SelectDeviceDrawer' + + export default { + name: 'ProcessModalForm', + components: { SelectDeviceDrawer }, + data() { + return { + model: { + passCount: 0 + }, + labelCol: { + xs: { span: 24 }, + sm: { span: 8 } + }, + wrapperCol: { + xs: { span: 24 }, + sm: { span: 14 } + }, + labelColLong: { + xs: { span: 24 }, + sm: { span: 4 } + }, + wrapperColLong: { + xs: { span: 24 }, + sm: { span: 19 } + }, + confirmLoading: false, + validatorRules: { + equipmentIds: [ + { required: true, message: '璇烽�夋嫨璁惧!' } + ], + partId: [ + { required: true, message: '璇疯緭鍏ラ浂浠跺彿!' } + ], + standardProcessLong: [ + { required: true, message: '璇疯緭鍏ユ爣鍑嗗姞宸ュ伐鏃�(min)!' } + ], + processCount: [ + { required: true, message: '璇疯緭鍏ュ姞宸ラ浂浠舵暟閲�!' } + ], + passCount: [ + { required: true, message: '璇疯緭鍏ュ悎鏍奸浂浠舵暟閲�!' } + ], + theDate: [ + { required: true, message: '璇烽�夋嫨鏃ユ湡!' } + ] + }, + url: { + add: '/mdc/mdcPartProcessInfo/add', + edit: '/mdc/mdcPartProcessInfo/edit' + } + } + }, + computed: { + formDisabled() { + return this.disabled + } + }, + created() { + //澶囦唤model鍘熷鍊� + this.modelDefault = JSON.parse(JSON.stringify(this.model)) + }, + methods: { + add() { + this.edit(this.modelDefault) + }, + edit(record) { + this.model = Object.assign({}, { equipmentIds: record.equipmentId }, record) + console.log('model', this.model) + this.visible = true + }, + inputNumberChange() { + if (this.model.standardProcessLong && this.model.processCount) { + this.model.totalProcessLong = this.model.standardProcessLong * this.model.processCount + } + }, + submitForm() { + const that = this + // 瑙﹀彂琛ㄥ崟楠岃瘉 + this.$refs.form.validate(valid => { + if (valid) { + that.confirmLoading = true + let httpUrl = '' + let method = 'post' + if (!this.model.id) { + httpUrl += this.url.add + } else { + httpUrl += this.url.edit + } + httpAction(httpUrl, this.model, method).then((res) => { + if (res.success) { + that.$notification.success({ + message: '娑堟伅', + description: res.message + }) + that.$emit('ok') + } else { + that.$notification.warning({ + message: '娑堟伅', + description: res.message + }) + } + }).finally(() => { + that.confirmLoading = false + }) + } + + }) + }, + deviceSearch() { + this.$refs.selectDeviceDrawer.visible = true + this.$refs.selectDeviceDrawer.selectedRowKeys = [] + this.$refs.selectDeviceDrawer.selectedRows = [] + this.$refs.selectDeviceDrawer.checkedKeys = this.model.equipmentIds ? this.model.equipmentIds.split(',') : [] + }, + /** + * 閫夋嫨宸叉湁璁惧鍚庣偣鍑荤‘瀹氭椂瑙﹀彂 + * @param data 宸查�夋嫨鐨勮澶� + */ + selectOK(data) { + this.$set(this.model, 'equipmentIds', data.join(',')) + if (this.model.equipmentIds) this.$refs.form.clearValidate('equipmentIds') + } + } + } +</script> \ No newline at end of file diff --git a/src/views/dnc/base/modules/ProductStructure/Process/ProcessTableList.vue b/src/views/dnc/base/modules/ProductStructure/Process/ProcessTableList.vue new file mode 100644 index 0000000..142402e --- /dev/null +++ b/src/views/dnc/base/modules/ProductStructure/Process/ProcessTableList.vue @@ -0,0 +1,248 @@ +<template> + <div> + <a-table :columns="columns" :data-source="dataSource" bordered :pagination="false" + :scroll="{y:227}" :customRow="customRow" :size="size" rowKey="processId"> + + </a-table> + + <ProcessModal ref="modalForm" @ok="modalFormOk"/> + + <ImportFileModal ref="importFileModal"/> + </div> +</template> + +<script> + import { JeecgListMixin } from '@/mixins/JeecgListMixin' + import ProcessModal from './ProcessModal' + import ImportFileModal from '../../../../common/ImportFileModal' + + export default { + name: 'ProcessTableList', + components: { ImportFileModal, ProcessModal }, + mixins: [JeecgListMixin], + props: { + size: { + type: String + } + }, + data() { + return { + columns: [ + { + title: '宸ュ簭鍙�', + dataIndex: 'processCode', + align: 'center', + sorter: (a, b) => a.processNo - b.processNo, + sortDirections: ['descend', 'ascend'] + }, + { + title: '宸ュ簭缂栧彿', + dataIndex: 'craftNo', + align: 'center', + sorter: (a, b) => a.processId - b.processId, + sortDirections: ['descend', 'ascend'] + }, + { + title: '宸ュ簭鍚嶇О', + dataIndex: 'processName', + align: 'center', + sorter: (a, b) => a.processName.length - b.processName.length, + sortDirections: ['descend', 'ascend'] + } + ], + dataSource: [ + { + 'processId': '1327516286572163080', + 'productId': '1326377675659276290', + 'componentId': '1327516286505054210', + 'partsId': null, + 'processName': null, + 'processCode': '1', + 'craftNo': null, + 'craftVersion': null, + 'processType': null, + 'processingEquipmentModel': null, + 'processingEquipmentCode': null, + 'assembleStep': null, + 'assembleName': null, + 'description': null + }, + { + 'processId': '1701841077007798274', + 'productId': '1326377675659276290', + 'componentId': '1327516286505054210', + 'partsId': null, + 'processName': '2113', + 'processCode': '111', + 'craftNo': '', + 'craftVersion': '', + 'processType': 0, + 'processingEquipmentModel': '', + 'processingEquipmentCode': '', + 'assembleStep': '', + 'assembleName': '', + 'description': '' + }, + { + 'processId': '1875082575626289153', + 'productId': '1326377675659276290', + 'componentId': '1327516286505054210', + 'partsId': null, + 'processName': '333', + 'processCode': '3213', + 'craftNo': '', + 'craftVersion': '', + 'processType': 0, + 'processingEquipmentModel': '', + 'processingEquipmentCode': '', + 'assembleStep': '', + 'assembleName': '', + 'description': '' + }, + { + 'processId': '1875082597210177537', + 'productId': '1326377675659276290', + 'componentId': '1327516286505054210', + 'partsId': null, + 'processName': '123', + 'processCode': 'sd', + 'craftNo': '', + 'craftVersion': '', + 'processType': 0, + 'processingEquipmentModel': '', + 'processingEquipmentCode': '', + 'assembleStep': '', + 'assembleName': '', + 'description': '' + }, + { + 'processId': '1875082616835325954', + 'productId': '1326377675659276290', + 'componentId': '1327516286505054210', + 'partsId': null, + 'processName': 'dadas', + 'processCode': 'sadsa', + 'craftNo': '', + 'craftVersion': '', + 'processType': 0, + 'processingEquipmentModel': '', + 'processingEquipmentCode': '', + 'assembleStep': '', + 'assembleName': '', + 'description': '' + }, + { + 'processId': '1875082638553432066', + 'productId': '1326377675659276290', + 'componentId': '1327516286505054210', + 'partsId': null, + 'processName': '1213', + 'processCode': 'das', + 'craftNo': '', + 'craftVersion': '', + 'processType': 0, + 'processingEquipmentModel': '', + 'processingEquipmentCode': '', + 'assembleStep': '', + 'assembleName': '', + 'description': '' + }, + { + 'processId': '1875082668072943617', + 'productId': '1326377675659276290', + 'componentId': '1327516286505054210', + 'partsId': null, + 'processName': 'zxccz', + 'processCode': 'asdasda', + 'craftNo': '', + 'craftVersion': '', + 'processType': 0, + 'processingEquipmentModel': '', + 'processingEquipmentCode': '', + 'assembleStep': '', + 'assembleName': '', + 'description': '' + } + ], + currentRowInfo: {}, + url: { + list: '', + add: '', + edit: '', + delete: '' + } + } + }, + created() { + this.$bus.$on('menuItemMethodTrigger', this.triggerCorrespondingMethod) + }, + methods: { + /** + * 鑷畾涔夎〃鏍艰鍔熻兘 + * @param record 琛ㄦ牸琛屼俊鎭� + * @returns {{on: {contextmenu: on.contextmenu, click: on.click}}} 杩斿洖浜嬩欢鏂规硶瀵硅薄 + */ + customRow(record) { + return { + on: { + contextmenu: event => { + event.preventDefault() + this.currentRowInfo = Object.assign({}, record) + this.$emit('handleTableContextMenuOpen', { objectId: record.processId, param: 'process' }) + }, + click: () => { + this.$bus.$emit('sendCurrentLevelInfo', record) + } + } + } + }, + + /** + * 鐐瑰嚮鍒涘缓宸ュ簭鑿滃崟鏃惰Е鍙� + * @param modalTitle + */ + handleProcessAdd(modalTitle) { + this.$refs.modalForm.add() + this.$refs.modalForm.title = modalTitle + }, + + /** + * 鐐瑰嚮缂栬緫宸ュ簭鑿滃崟鏃惰Е鍙� + * @param modalTitle + */ + handleProcessEdit(modalTitle) { + this.$refs.modalForm.edit(this.currentRowInfo) + this.$refs.modalForm.title = modalTitle + }, + + /** + * 鐐瑰嚮鍒犻櫎鏃惰Е鍙� + */ + handleProcessDelete() { + this.$confirm({ + title: '鎻愮ず', + content: '纭鍒犻櫎姝ゆ潯璁板綍鍚楋紵', + okText: '纭', + okType: 'danger', + cancelText: '鍙栨秷', + onOk: () => { + this.handleDelete(this.currentRowInfo.processId) + } + }) + }, + + handleProcessImport(modalTitle) { + this.$refs.importFileModal.visible = true + this.$refs.importFileModal.title = modalTitle + }, + + triggerCorrespondingMethod({ methodName, level, modalTitle }) { + if (level === 'process') this[methodName](modalTitle) + } + } + } +</script> + +<style scoped> + +</style> \ No newline at end of file diff --git a/src/views/dnc/base/modules/ProductStructure/ProcessStep/ProcessStepInfo.vue b/src/views/dnc/base/modules/ProductStructure/ProcessStep/ProcessStepInfo.vue new file mode 100644 index 0000000..07987c5 --- /dev/null +++ b/src/views/dnc/base/modules/ProductStructure/ProcessStep/ProcessStepInfo.vue @@ -0,0 +1,20 @@ +<template> + <div> + + </div> +</template> + +<script> + export default { + name: 'ProcessStepInfo', + components: {}, + data() { + return {} + }, + methods: {} + } +</script> + +<style scoped> + +</style> \ No newline at end of file diff --git a/src/views/dnc/base/modules/ProductStructure/Product/ProductInfo.vue b/src/views/dnc/base/modules/ProductStructure/Product/ProductInfo.vue new file mode 100644 index 0000000..da4feb0 --- /dev/null +++ b/src/views/dnc/base/modules/ProductStructure/Product/ProductInfo.vue @@ -0,0 +1,34 @@ +<template> + <a-descriptions bordered :size="size"> + <a-descriptions-item label="浜у搧鍚嶇О">{{currentLevelDetails.productName}}</a-descriptions-item> + <a-descriptions-item label="浜у搧鍨嬪彿">{{currentLevelDetails.productModel}}</a-descriptions-item> + <a-descriptions-item label="浜у搧浠g爜 ">{{currentLevelDetails.productNo}}</a-descriptions-item> + <a-descriptions-item label="鍒涘缓浜�">{{currentLevelDetails.createUser_dicText}}</a-descriptions-item> + <a-descriptions-item label="鍒涘缓鏃堕棿" :span="2">{{currentLevelDetails.createTime}}</a-descriptions-item> + <a-descriptions-item label="淇敼浜�">{{currentLevelDetails.updateUser_dicText}}</a-descriptions-item> + <a-descriptions-item label="淇敼鏃堕棿" :span="2">{{currentLevelDetails.updateTime}}</a-descriptions-item> + </a-descriptions> +</template> + +<script> + export default { + name: 'ProductInfo', + components: {}, + props: { + currentLevelDetails: { + type: Object + }, + size: { + type: String + } + }, + data() { + return {} + }, + methods: {} + } +</script> + +<style scoped> + +</style> \ No newline at end of file diff --git a/src/views/dnc/base/modules/ProductStructure/Product/ProductModal.vue b/src/views/dnc/base/modules/ProductStructure/Product/ProductModal.vue new file mode 100644 index 0000000..e808a87 --- /dev/null +++ b/src/views/dnc/base/modules/ProductStructure/Product/ProductModal.vue @@ -0,0 +1,70 @@ +<template> + <j-modal + :title="title" + :width="width" + :visible="visible" + switchFullscreen + :maskClosable="false" + @ok="handleOk" + @cancel="handleCancel" + cancelText="鍏抽棴"> + <ProductModalForm ref="realForm" @ok="submitCallback"/> + </j-modal> +</template> + +<script> + import ProductModalForm from './ProductModalForm.vue' + + export default { + name: 'ProductModal', + components: { + ProductModalForm + }, + props: { + currentTreeNodeInfo: { + type: Object + } + }, + data() { + return { + title: '', + width: 500, + visible: false + } + }, + created() { + this.$bus.$on('treeMenuItemMethodTrigger', this.triggerCorrespondingMethod) + }, + methods: { + handleProductAdd(modalTitle) { + this.title = modalTitle + this.visible = true + this.$nextTick(() => { + this.$refs.realForm.add() + }) + }, + handleProductEdit(modalTitle) { + this.title = modalTitle + this.visible = true + this.$nextTick(() => { + this.$refs.realForm.edit(this.currentTreeNodeInfo.entity) + }) + }, + handleOk() { + this.$refs.realForm.submitForm() + }, + submitCallback() { + this.$emit('ok') + this.visible = false + }, + handleCancel() { + this.$emit('close') + this.visible = false + }, + + triggerCorrespondingMethod({ methodName, modalTitle }) { + if (this[methodName]) this[methodName](modalTitle) + } + } + } +</script> \ No newline at end of file diff --git a/src/views/dnc/base/modules/ProductStructure/Product/ProductModalForm.vue b/src/views/dnc/base/modules/ProductStructure/Product/ProductModalForm.vue new file mode 100644 index 0000000..83f50a6 --- /dev/null +++ b/src/views/dnc/base/modules/ProductStructure/Product/ProductModalForm.vue @@ -0,0 +1,126 @@ +<template> + <a-spin :spinning="confirmLoading"> + <a-form-model ref="form" :model="model" :rules="validatorRules" :labelCol="labelColLong" + :wrapperCol="wrapperColLong"> + <a-row> + <a-col :span="24"> + <a-form-model-item label="浜у搧鍚嶇О" prop="productName"> + <a-input v-model="model.productName" placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�"></a-input> + </a-form-model-item> + </a-col> + </a-row> + + <a-row> + <a-col :span="24"> + <a-form-model-item label="浜у搧浠e彿" prop="productNo"> + <a-input v-model="model.productNo" placeholder="璇疯緭鍏ヤ骇鍝佷唬鍙�"></a-input> + </a-form-model-item> + </a-col> + </a-row> + + <a-row> + <a-col :span="24"> + <a-form-model-item label="浜у搧鍨嬪彿"> + <a-textarea v-model="model.productModel" placeholder="璇疯緭鍏ヤ骇鍝佸瀷鍙�"></a-textarea> + </a-form-model-item> + </a-col> + </a-row> + </a-form-model> + </a-spin> +</template> + +<script> + import { httpAction, getAction } from '@/api/manage' + + export default { + name: 'ProductModalForm', + components: {}, + data() { + return { + model: {}, + labelCol: { + xs: { span: 24 }, + sm: { span: 8 } + }, + wrapperCol: { + xs: { span: 24 }, + sm: { span: 14 } + }, + labelColLong: { + xs: { span: 24 }, + sm: { span: 4 } + }, + wrapperColLong: { + xs: { span: 24 }, + sm: { span: 19 } + }, + confirmLoading: false, + validatorRules: { + productName: [ + { required: true, message: '璇疯緭鍏ヤ骇鍝佸悕绉�!' } + ], + productNo: [ + { required: true, message: '璇疯緭鍏ヤ骇鍝佷唬鍙�!' } + ], + }, + url: { + add: '/mdc/mdcPartProcessInfo/add', + edit: '/mdc/mdcPartProcessInfo/edit' + } + } + }, + computed: { + formDisabled() { + return this.disabled + } + }, + created() { + //澶囦唤model鍘熷鍊� + this.modelDefault = JSON.parse(JSON.stringify(this.model)) + }, + methods: { + add() { + this.edit(this.modelDefault) + }, + + edit(record) { + this.model = Object.assign({}, record) + console.log('model', this.model) + this.visible = true + }, + + submitForm() { + const that = this + // 瑙﹀彂琛ㄥ崟楠岃瘉 + this.$refs.form.validate(valid => { + if (valid) { + that.confirmLoading = true + let httpUrl = '' + let method = 'post' + if (!this.model.id) { + httpUrl += this.url.add + } else { + httpUrl += this.url.edit + } + httpAction(httpUrl, this.model, method).then((res) => { + if (res.success) { + that.$notification.success({ + message: '娑堟伅', + description: res.message + }) + that.$emit('ok') + } else { + that.$notification.warning({ + message: '娑堟伅', + description: res.message + }) + } + }).finally(() => { + that.confirmLoading = false + }) + } + }) + } + } + } +</script> diff --git a/src/views/dnc/base/modules/ProductStructure/ProductStructureMain.vue b/src/views/dnc/base/modules/ProductStructure/ProductStructureMain.vue new file mode 100644 index 0000000..30e0928 --- /dev/null +++ b/src/views/dnc/base/modules/ProductStructure/ProductStructureMain.vue @@ -0,0 +1,32 @@ +<template> + <div style="height: 100%;max-height: 748px"> + <!--浜у搧缁撴瀯鏍戝彸渚ч《閮ㄥ尯鍩�--> + <div style="height: 45%;overflow: hidden"> + <ProductStructureMainTop :size="tabContainerSize"/> + </div> + + <!--浜у搧缁撴瀯鏍戝彸渚у簳閮ㄥ尯鍩�--> + <div style="height: 55%;overflow: hidden"> + <ProductStructureMainBottom :size="tabContainerSize"/> + </div> + </div> +</template> + +<script> + import ProductStructureMainTop from './ProductStructureMainTop' + import ProductStructureMainBottom from './ProductStructureMainBottom' + + export default { + name: 'ProductStructureMain', + components: { + ProductStructureMainTop, + ProductStructureMainBottom + }, + data() { + return { + tabContainerSize: 'small' + } + }, + methods: {} + } +</script> \ No newline at end of file diff --git a/src/views/dnc/base/modules/ProductStructure/ProductStructureMainBottom.vue b/src/views/dnc/base/modules/ProductStructure/ProductStructureMainBottom.vue new file mode 100644 index 0000000..8651ed1 --- /dev/null +++ b/src/views/dnc/base/modules/ProductStructure/ProductStructureMainBottom.vue @@ -0,0 +1,91 @@ +<template> + <a-tabs style="height: 100%" v-model="activeTabKey" v-if="Object.keys(currentLevelInfo).length>0"> + <a-tab-pane :key="1" tab="浜у搧灞炴��" v-if="currentLevelInfo.type===1"> + <ProductInfo :currentLevelDetails="currentLevelInfo.entity" :size="descriptionsContainerSize"/> + </a-tab-pane> + + <a-tab-pane :key="1" tab="閮ㄤ欢灞炴��" v-if="currentLevelInfo.type===2"> + <ComponentInfo :currentLevelDetails="currentLevelInfo.entity" :size="descriptionsContainerSize"/> + </a-tab-pane> + + <a-tab-pane :key="1" tab="闆朵欢灞炴��" v-if="currentLevelInfo.type===3"> + <PartInfo :currentLevelDetails="currentLevelInfo.entity" :size="descriptionsContainerSize"/> + </a-tab-pane> + + <a-tab-pane :key="1" tab="宸ュ簭灞炴��" v-if="currentLevelInfo.hasOwnProperty('processType')"> + <ProcessInfo :currentLevelDetails="currentLevelInfo" :size="descriptionsContainerSize"/> + </a-tab-pane> + + <template v-if="currentLevelInfo.hasOwnProperty('attributionType')"> + <a-tab-pane :key="1" tab="鏂囨。灞炴��"> + <DocumentInfo :currentLevelDetails="currentLevelInfo" :size="descriptionsContainerSize"/> + </a-tab-pane> + + <a-tab-pane :key="2" tab="棰勮"> + + </a-tab-pane> + + <a-tab-pane :key="3" tab="鏂囨。鐗堟湰"> + <DocumentVersionTableList/> + </a-tab-pane> + + <a-tab-pane :key="4" tab="浣跨敤璁惧" v-if="currentLevelInfo.attributionType===5"> + <UseDocumentEquipmentTableList/> + </a-tab-pane> + </template> + </a-tabs> +</template> + +<script> + import ProductInfo from './Product/ProductInfo' + import ComponentInfo from './Component/ComponentInfo' + import PartInfo from './Part/PartInfo' + import ProcessInfo from './Process/ProcessInfo' + import DocumentInfo from './Document/DocumentInfo' + import DocumentVersionTableList from './Document/DocumentVersionTableList' + import UseDocumentEquipmentTableList from './Document/UseDocumentEquipmentTableList' + + export default { + name: 'ProductStructureMainBottom', + components: { + UseDocumentEquipmentTableList, + DocumentVersionTableList, + DocumentInfo, + ProcessInfo, + PartInfo, + ProductInfo, + ComponentInfo + }, + data() { + return { + activeTabKey: 1, + descriptionsContainerSize: 'small', + currentLevelInfo: {} + } + }, + created() { + this.$bus.$on('sendCurrentLevelInfo', this.receiveCurrentLevelInfo) + this.$bus.$on('sendCurrentTreeNodeInfo', this.receiveCurrentLevelInfo) + }, + methods: { + /** + * 鎺ユ敹鏍戠粍浠朵互鍙婅〃鏍间紶鏉ョ殑褰撳墠閫変腑鎴栫偣鍑荤殑椤逛俊鎭� + * @param levelInfo + */ + receiveCurrentLevelInfo(levelInfo) { + this.currentLevelInfo = levelInfo + if (levelInfo.attributionType) this.activeTabKey = 1 + } + } + } +</script> + +<style scoped> + /deep/ .ant-tabs-content { + height: calc(100% - 65px); + } + + /deep/ .ant-tabs-tabpane { + overflow: auto; + } +</style> \ No newline at end of file diff --git a/src/views/dnc/base/modules/ProductStructure/ProductStructureMainTop.vue b/src/views/dnc/base/modules/ProductStructure/ProductStructureMainTop.vue new file mode 100644 index 0000000..9a6a8e1 --- /dev/null +++ b/src/views/dnc/base/modules/ProductStructure/ProductStructureMainTop.vue @@ -0,0 +1,76 @@ +<template> + <a-tabs v-model="activeTabKey" @contextmenu.native="e=>e.preventDefault()" + v-if="Object.keys(currentTreeNodeInfo).length!==0"> + <a-tab-pane :key="1" tab="NC鏂囨。" v-if="currentTreeNodeInfo.type!==1"> + <NcDocumentTableList @handleTableContextMenuOpen="handleTableContextMenuOpen" :size="tableContainerSize"/> + </a-tab-pane> + + <a-tab-pane :key="2" tab="鍏朵粬鏂囨。"> + <OtherDocumentTableList @handleTableContextMenuOpen="handleTableContextMenuOpen" :size="tableContainerSize"/> + </a-tab-pane> + + <TableContextMenu :currentTableRowInfo="currentTableRowInfo" ref="tableContextMenuRef"/> + </a-tabs> +</template> + +<script> + import ProcessTableList from './Process/ProcessTableList' + import NcDocumentTableList from './Document/NcDocumentTableList' + import OtherDocumentTableList from './Document/OtherDocumentTableList' + import TableContextMenu from '../../../common/TableContextMenu' + + export default { + name: 'ProductStructureMainTop', + components: { TableContextMenu, OtherDocumentTableList, NcDocumentTableList, ProcessTableList }, + data() { + return { + activeTabKey: '1', + tableContainerSize: 'small', + currentTableRowInfo: {}, + currentTreeNodeInfo: {} + } + }, + created() { + this.$bus.$on('sendCurrentTreeNodeInfo', this.receiveCurrentTreeNodeInfo) + }, + methods: { + /** + * 鎺у埗鍙抽敭鑿滃崟寮�鍚� + * @param record 褰撳墠琛ㄦ牸琛屼俊鎭� + */ + handleTableContextMenuOpen(record) { + this.currentTableRowInfo = Object.assign({}, record) + this.$refs.tableContextMenuRef.currentMenuLevel = record.param + this.$refs.tableContextMenuRef.menuStyle.top = event.clientY + 'px' + this.$refs.tableContextMenuRef.menuStyle.left = event.clientX + 'px' + this.$refs.tableContextMenuRef.menuVisible = true + document.body.addEventListener('click', this.handleMenuClose) + }, + + /** + * 鎺ユ敹鏍戠粍浠朵紶鏉ョ殑褰撳墠閫変腑鐨勬爲鑺傜偣淇℃伅 + * @param treeNodeInfo + */ + receiveCurrentTreeNodeInfo(treeNodeInfo) { + // 浠庢爲缁勪欢鎺ュ彈鏍戣妭鐐逛俊鎭悗浠庣埗缁勪欢娴佸叆瀛愮粍浠� + this.currentTreeNodeInfo = treeNodeInfo + if (treeNodeInfo.type !== 1) this.activeTabKey = 1 + else this.activeTabKey = 2 + }, + + /** + * 鎺у埗鍙抽敭鑿滃崟鐐瑰嚮鍏抽棴 + */ + handleMenuClose() { + this.$refs.tableContextMenuRef.menuVisible = false + document.body.removeEventListener('click', this.handleMenuClose) + } + } + } +</script> + +<style scoped> + /deep/ .ant-table-tbody .ant-table-row { + cursor: pointer; + } +</style> \ No newline at end of file diff --git a/src/views/dnc/common/ImportFileModal.vue b/src/views/dnc/common/ImportFileModal.vue new file mode 100644 index 0000000..3ed0cb5 --- /dev/null +++ b/src/views/dnc/common/ImportFileModal.vue @@ -0,0 +1,122 @@ +<template> + <a-modal :title="title" :visible="visible" @cancel="handleModalClose" :maskClosable="false"> + <a-upload :multiple="true" :file-list="fileList" :remove="handleRemove" :before-upload="beforeUpload"> + <a-button type="primary"> + <a-icon type="import"/> + 閫夊彇鏂囦欢 + </a-button> + </a-upload> + + <div style="margin-top: 16px">宸查�夋嫨{{fileList.length}}涓枃浠�</div> + + <template slot="footer"> + <a-button @click="handleModalClose">鍙栨秷</a-button> + <a-button + id="custom-upload-button" + type="primary" + :disabled="fileList.length === 0" + :loading="uploading" + @click="handleUpload" + > + {{ uploading ? '涓婁紶涓�...' : '涓婁紶鑷虫湇鍔″櫒' }} + </a-button> + </template> + + </a-modal> +</template> + +<script> + export default { + name: 'ImportFileModal', + components: {}, + data() { + return { + visible: false, + title: '', + fileList: [], + uploading: false + } + }, + created() { + this.$bus.$on('treeMenuItemMethodTrigger', this.triggerCorrespondingMethod) + }, + methods: { + handleImport(modalTitle) { + this.handleModalOpen(modalTitle) + }, + + handleRemove(file) { + const index = this.fileList.indexOf(file) + const newFileList = this.fileList.slice() + newFileList.splice(index, 1) + this.fileList = newFileList + }, + + beforeUpload(file) { + this.fileList = [...this.fileList, file] + return false + }, + + handleUpload() { + const { fileList } = this + const formData = new FormData() + fileList.forEach(file => { + formData.append('files[]', file) + }) + this.uploading = true + + // You can use any AJAX library you like + request({ + url: 'https://www.mocky.io/v2/5cc8019d300000980a055e76', + method: 'post', + processData: false, + data: formData, + success: () => { + this.fileList = [] + this.uploading = false + this.$message.success('upload successfully.') + }, + error: () => { + this.uploading = false + this.$message.error('upload failed.') + } + }) + }, + + /** + * 鎺у埗鏂囦欢涓婁紶绐楀彛寮�鍚苟璁剧疆绐楀彛鏍囬 + * @param modalTitle 绐楀彛鏍囬 + */ + handleModalOpen(modalTitle) { + this.title = modalTitle + this.visible = true + }, + + /** + * 鎺у埗鏂囦欢涓婁紶绐楀彛鍏抽棴骞舵竻绌烘枃浠跺垪琛� + */ + handleModalClose() { + this.visible = false + this.fileList = [] + }, + + triggerCorrespondingMethod({ methodName, modalTitle }) { + if (this[methodName]) this[methodName](modalTitle) + } + } + } +</script> + +<style scoped lang="less"> + /deep/ .ant-btn-primary#custom-upload-button { + color: #fff; + background-color: #67C23A; + border-color: #67C23A; + + &[disabled] { + color: rgba(0, 0, 0, 0.25); + background-color: #f5f5f5; + border-color: #d9d9d9; + } + } +</style> \ No newline at end of file diff --git a/src/views/dnc/common/ProductStructureTree.vue b/src/views/dnc/common/ProductStructureTree.vue new file mode 100644 index 0000000..2d85dbf --- /dev/null +++ b/src/views/dnc/common/ProductStructureTree.vue @@ -0,0 +1,644 @@ +<template> + <a-card class="tree_con" :loading="cardLoading" :bordered="false" @contextmenu.native="e=>e.preventDefault()"> + <a-spin :spinning="loading"> + <div style="display: flex;flex-direction: column;height: 100%"> + + <div style="display: flex"> + <a-input placeholder="杈撳叆鍏抽敭瀛楄繘琛屾悳绱�" allowClear v-model="searchInput" + @change="handleSearchInputChange"/> + <a-dropdown :trigger="['click']" placement="bottomCenter" style="margin: 0 8px"> + <a-menu slot="overlay"> + <a-menu-item key="1" @click="expandedKeys = allTreeKeys">灞曞紑鎵�鏈�</a-menu-item> + <a-menu-item key="2" @click="expandedKeys = ['-1']">鍚堝苟鎵�鏈�</a-menu-item> + <a-menu-item key="3" @click="queryTreeData">鍒锋柊</a-menu-item> + </a-menu> + <a-button> + <a-icon type="bars"/> + </a-button> + </a-dropdown> + <a-button type="primary" @click="$refs.productModalFormRef.handleProductAdd('娣诲姞浜у搧')"> + <a-icon type="plus"></a-icon> + 浜у搧 + </a-button> + </div> + + <!--浜у搧缁撴瀯鏍�--> + <div style="flex: 1;overflow:auto;margin-top: 10px"> + <a-tree ref="tree" show-icon :checkStrictly="checkStrictly" :expandedKeys.sync="expandedKeys" + :selectedKeys="selectedKeys" :treeData="treeDataSource" :autoExpandParent="autoExpandParent" + @select="handleTreeSelect" @expand="handleTreeExpand" @rightClick="handleTreeRightClick"> + <template slot="title" slot-scope="{ label, parentId, entity, key:treeKey,type}"> + <ProductStructureTreeContextMenu ref="contextMenuRef" + :treeParams="{label,treeKey,searchValue,type,entity}"/> + </template> + + <a-icon slot="switcherIcon" type="down"/> + <a-icon slot="product" type="shopping"/> + <a-icon slot="component" type="camera"/> + <a-icon slot="part" type="hdd"/> + </a-tree> + </div> + </div> + </a-spin> + + <!--浜у搧寮圭獥--> + <ProductModal ref="productModalFormRef" :currentTreeNodeInfo="rightClickSelected"/> + <!--闆朵欢寮圭獥--> + <ComponentModal :currentTreeNodeInfo="rightClickSelected"/> + <!--瀵煎叆鏂囦欢鍏叡寮圭獥--> + <ImportFileModal/> + </a-card> +</template> + +<script> + import { deleteAction } from '@/api/manage' + import { mapActions } from 'vuex' + import ProductStructureTreeContextMenu from './modules/ProductStructureTree/ProductStructureTreeContextMenu' + import ProductModal from '../base/modules/ProductStructure/Product/ProductModal' + import ImportFileModal from './ImportFileModal' + import ComponentModal from '../base/modules/ProductStructure/Component/ComponentModal' + + export default { + name: 'ProductStructureTree', + components: { + ComponentModal, + ImportFileModal, + ProductModal, + ProductStructureTreeContextMenu + }, + data() { + return { + searchInput: '', + cardLoading: false, + loading: false, + treeDataSource: [], + selectedKeys: [], + expandedKeys: [], + searchValue: '', + dataList: [], + autoExpandParent: true, + checkStrictly: true, + allTreeKeys: [], + currentSelected: {}, + rightClickSelected: {}, + url: { + delete: '' + } + } + }, + created() { + this.queryTreeData() + this.$bus.$on('treeMenuItemMethodTrigger', this.triggerCorrespondingMethod) + }, + methods: { + ...mapActions(['QueryProduction']), + + queryTreeData() { + this.loading = true + this.cardLoading = true + this.QueryProduction().then(res => { + if (res.success) { + this.dataList = [] + this.allTreeKeys = [] + // this.treeDataSource = res.result + this.treeDataSource = [ + { + 'id': '1869253349344432129', + 'label': '[璁╁浜篯娴嬭瘯', + 'iconClass': '', + 'parentId': '1869253349344432129', + 'children': [ + { + 'id': '1869254044432879617', + 'label': '[378]qgwqg', + 'iconClass': '', + 'parentId': '1869253349344432129', + 'children': [ + { + 'id': '1869260302133137410', + 'label': '[ggjuk]璋旇皵鍘�', + 'iconClass': '', + 'parentId': '1869254044432879617', + 'children': [ + { + 'id': '1869294654070075393', + 'label': '[8989]qwfq', + 'iconClass': '', + 'parentId': '1869260302133137410', + 'children': null, + 'type': 2, + 'entity': { + 'componentId': '1869294654070075393', + 'parentId': '1869260302133137410', + 'productId': '1869253349344432129', + 'componentName': 'qwfq', + 'materielCode': '', + 'materielDesp': '', + 'componentModel': '', + 'componentScale': '', + 'componentWeight': null, + 'rankLevel': 3, + 'assembleType': null, + 'produceType': null, + 'processType': null, + 'structureType': null, + 'componentCode': '8989', + 'componentStatus': 1, + 'description': '', + 'createTime': '2024-12-18 16:12:30', + 'updateTime': null, + 'createUser': '1254966905669160962', + 'updateUser': '' + }, + 'leaf': false, + 'rfield': '1869253349344432129' + }, + { + 'id': '1869294701801254913', + 'label': '[888]7878', + 'iconClass': '', + 'parentId': '1869260302133137410', + 'children': null, + 'type': 2, + 'entity': { + 'componentId': '1869294701801254913', + 'parentId': '1869260302133137410', + 'productId': '1869253349344432129', + 'componentName': '7878', + 'materielCode': '', + 'materielDesp': '', + 'componentModel': '', + 'componentScale': '', + 'componentWeight': null, + 'rankLevel': 3, + 'assembleType': null, + 'produceType': null, + 'processType': null, + 'structureType': null, + 'componentCode': '888', + 'componentStatus': 1, + 'description': '', + 'createTime': '2024-12-18 16:12:41', + 'updateTime': null, + 'createUser': '1254966905669160962', + 'updateUser': '' + }, + 'leaf': false, + 'rfield': '1869253349344432129' + }, + { + 'id': '1869294780935188482', + 'label': '[6855]ww', + 'iconClass': '', + 'parentId': '1869260302133137410', + 'children': null, + 'type': 2, + 'entity': { + 'componentId': '1869294780935188482', + 'parentId': '1869260302133137410', + 'productId': '1869253349344432129', + 'componentName': 'ww', + 'materielCode': '', + 'materielDesp': '', + 'componentModel': '', + 'componentScale': '', + 'componentWeight': null, + 'rankLevel': 3, + 'assembleType': null, + 'produceType': null, + 'processType': null, + 'structureType': null, + 'componentCode': '6855', + 'componentStatus': 1, + 'description': '', + 'createTime': '2024-12-18 16:13:00', + 'updateTime': null, + 'createUser': '1254966905669160962', + 'updateUser': '' + }, + 'leaf': false, + 'rfield': '1869253349344432129' + }, + { + 'id': '1876199480437153794', + 'label': '[354]zzzzzzzzzzzzzzzzz', + 'iconClass': '', + 'parentId': '1869260302133137410', + 'children': null, + 'type': 3, + 'entity': { + 'partsId': '1876199480437153794', + 'partsName': 'zzzzzzzzzzzzzzzzz', + 'productId': '1869253349344432129', + 'componentId': '1869260302133137410', + 'materielCode': '', + 'materielDesp': '', + 'partsModel': '', + 'partsScale': '', + 'partsWeight': null, + 'assembleType': null, + 'produceType': null, + 'processType': null, + 'structureType': null, + 'partsCode': '354', + 'partsStatus': 1, + 'description': '', + 'createTime': '2025-01-06 17:29:49', + 'updateTime': null, + 'createUser': '1254966905669160962', + 'updateUser': '' + }, + 'leaf': false, + 'rfield': '1869260302133137410' + } + ], + 'type': 2, + 'entity': { + 'componentId': '1869260302133137410', + 'parentId': '1869254044432879617', + 'productId': '1869253349344432129', + 'componentName': '璋旇皵鍘�', + 'materielCode': '', + 'materielDesp': '', + 'componentModel': '', + 'componentScale': '', + 'componentWeight': null, + 'rankLevel': 2, + 'assembleType': null, + 'produceType': null, + 'processType': null, + 'structureType': null, + 'componentCode': 'ggjuk', + 'componentStatus': 1, + 'description': '', + 'createTime': '2024-12-18 13:56:00', + 'updateTime': null, + 'createUser': '1254966905669160962', + 'updateUser': '' + }, + 'leaf': false, + 'rfield': '1869253349344432129' + } + ], + 'type': 2, + 'entity': { + 'componentId': '1869254044432879617', + 'parentId': null, + 'productId': '1869253349344432129', + 'componentName': 'qgwqg', + 'materielCode': '', + 'materielDesp': '', + 'componentModel': '', + 'componentScale': '', + 'componentWeight': null, + 'rankLevel': 1, + 'assembleType': null, + 'produceType': null, + 'processType': null, + 'structureType': null, + 'componentCode': '378', + 'componentStatus': 1, + 'description': '88', + 'createTime': '2022-12-18 13:32:48', + 'updateTime': '2024-12-18 13:32:48', + 'createUser': '1254966905669160962', + 'updateUser': '1254966905669160962' + }, + 'leaf': false, + 'rfield': '1869253349344432129' + }, + { + 'id': '1869253419041181697', + 'label': '[876]涓哄叏鍥藉墠浜旂粰', + 'iconClass': '', + 'parentId': '1869253349344432129', + 'children': null, + 'type': 2, + 'entity': { + 'componentId': '1869253419041181697', + 'parentId': null, + 'productId': '1869253349344432129', + 'componentName': '涓哄叏鍥藉墠浜旂粰', + 'materielCode': '', + 'materielDesp': '', + 'componentModel': '56', + 'componentScale': '', + 'componentWeight': null, + 'rankLevel': 1, + 'assembleType': null, + 'produceType': null, + 'processType': null, + 'structureType': null, + 'componentCode': '876', + 'componentStatus': 1, + 'description': '', + 'createTime': '2024-12-18 13:28:39', + 'updateTime': '2024-12-18 14:03:55', + 'createUser': '1254966905669160962', + 'updateUser': '1254966905669160962' + }, + 'leaf': false, + 'rfield': '1869253349344432129' + }, + { + 'id': '1869294861876867073', + 'label': '[777]he', + 'iconClass': '', + 'parentId': '1869253349344432129', + 'children': [ + { + 'id': '1876087437913108481', + 'label': '[ddd]鍜岀淮鎶�', + 'iconClass': '', + 'parentId': '1869294861876867073', + 'children': null, + 'type': 2, + 'entity': { + 'componentId': '1876087437913108481', + 'parentId': '1869294861876867073', + 'productId': '1869253349344432129', + 'componentName': '鍜岀淮鎶�', + 'materielCode': '', + 'materielDesp': '', + 'componentModel': '', + 'componentScale': '', + 'componentWeight': null, + 'rankLevel': 2, + 'assembleType': null, + 'produceType': null, + 'processType': null, + 'structureType': null, + 'componentCode': 'ddd', + 'componentStatus': 1, + 'description': '', + 'createTime': '2025-01-06 10:04:36', + 'updateTime': null, + 'createUser': '1254966905669160962', + 'updateUser': '' + }, + 'leaf': false, + 'rfield': '1869253349344432129' + } + ], + 'type': 2, + 'entity': { + 'componentId': '1869294861876867073', + 'parentId': null, + 'productId': '1869253349344432129', + 'componentName': 'he', + 'materielCode': '', + 'materielDesp': '', + 'componentModel': '', + 'componentScale': '', + 'componentWeight': null, + 'rankLevel': 1, + 'assembleType': null, + 'produceType': null, + 'processType': null, + 'structureType': null, + 'componentCode': '777', + 'componentStatus': 1, + 'description': '', + 'createTime': '2024-12-18 16:13:20', + 'updateTime': null, + 'createUser': '1254966905669160962', + 'updateUser': '' + }, + 'leaf': false, + 'rfield': '1869253349344432129' + } + ], + 'type': 1, + 'entity': { + 'productId': '1869253349344432129', + 'productNo': '璁╁浜�', + 'productModel': '', + 'productName': '娴嬭瘯', + 'productStatus': 1, + 'createTime': '2024-12-18 13:28:22', + 'updateTime': null, + 'createUser': '1254966905669160962', + 'updateUser': null + }, + 'leaf': false, + 'rfield': null + } + ] + this.generateList(this.treeDataSource) + // this.expandedKeys = this.allTreeKeys + this.expandedKeys = [this.treeDataSource[0].id] + console.log('treeDataSource', this.treeDataSource) + } else { + this.$message.warn(res.message) + } + }).finally(() => { + this.loading = false + this.cardLoading = false + }) + }, + + /** + * 鏍戣妭鐐归�変腑鏃惰Е鍙� + * @param selectedKeys 閫変腑鑺傜偣key + * @param {node} node 鑺傜偣瀵硅薄 + */ + handleTreeSelect(selectedKeys, { node }) { + let record = node.dataRef + this.currentSelected = Object.assign({}, record) + this.selectedKeys = selectedKeys + // 鍚戝彸渚х埗绾х粍浠跺彂閫佸綋鍓嶉�変腑鏍戣妭鐐逛俊鎭� + this.$bus.$emit('sendCurrentTreeNodeInfo', this.currentSelected) + }, + + /** + * 鏍戣妭鐐瑰彸閿崟鍑昏妭鐐规椂瑙﹀彂 + * @param event 浜嬩欢瀵硅薄 + * @param node 鑺傜偣瀵硅薄 + */ + handleTreeRightClick({ event, node }) { + const record = node.dataRef + this.rightClickSelected = Object.assign({}, record) + }, + + /** + * 鏍戣妭鐐瑰彸閿崟鍑昏彍鍗曚腑鍒犻櫎鎸夐挳鏃惰Е鍙� + */ + handleDelete() { + this.$confirm({ + title: '鎻愮ず', + content: '纭鍒犻櫎姝ゆ潯璁板綍鍚楋紵', + okText: '纭', + okType: 'danger', + cancelText: '鍙栨秷', + onOk: () => { + console.log('this.rightClickSelected.id', this.rightClickSelected.id) + if (!this.url.delete) { + this.$message.error('璇疯缃畊rl.delete灞炴��!') + return + } + const that = this + deleteAction(that.url.delete, { id: this.rightClickSelected.id }) + .then((res) => { + if (res.success) { + that.queryTreeData() + that.$notification.success({ + message: '娑堟伅', + description: res.message + }) + } else { + that.$notification.warning({ + message: '娑堟伅', + description: res.message + }) + } + }) + } + }) + }, + + /** + * 鏍戣妭鐐瑰睍寮�鍚堝苟鏃惰Е鍙� + * @param expandedKeys 灞曞紑椤筴ey + */ + handleTreeExpand(expandedKeys) { + this.expandedKeys = expandedKeys + this.autoExpandParent = false + }, + + /* 杈撳叆鏌ヨ鍐呭鍙樺寲鏃惰Е鍙� */ + handleSearchInputChange() { + let search = this.searchInput + let expandedKeys = this.dataList + .map(item => { + if (item.title != null) { + if (item.title.indexOf(search) > -1) { + return this.getParentKey(item.key, this.treeDataSource) + } + return null + } + }) + .filter((item, i, self) => item && self.indexOf(item) === i) + Object.assign(this, { + expandedKeys, + searchValue: search, + autoExpandParent: true + }) + }, + + /** + * 閫掑綊鑾峰緱杈撳叆椤圭殑鐖剁骇key + * @param key 瀛愰」key + * @param tree 瀛愰」 + */ + getParentKey(key, tree) { + let parentKey + for (let i = 0; i < tree.length; i++) { + const node = tree[i] + if (node.children) { + if (node.children.some(item => item.key === key)) { + parentKey = node.key + } else if ( + this.getParentKey(key, node.children)) { + parentKey = this.getParentKey(key, node.children) + } + } + } + return parentKey + }, + + /** + * 閫掑綊鑾峰緱鎵�鏈夋爲鑺傜偣key + * @param data + */ + generateList(data) { + for (let i = 0; i < data.length; i++) { + data[i].key = data[i].id + const node = data[i] + const key = node.id + const title = node.label + this.dataList.push({ key, title }) + this.allTreeKeys.push(key) + this.setTreeNodeIcon(node) + if (node.children) this.generateList(node.children) + } + }, + + triggerCorrespondingMethod({ methodName, modalTitle }) { + if (this[methodName]) this[methodName](modalTitle) + }, + + /** + * 璁剧疆鏍戣妭鐐瑰浘鏍� + * @param treeNode + */ + setTreeNodeIcon(treeNode) { + switch (treeNode.type) { + case 1: + treeNode.slots = { icon: 'product' } + break + case 2: + treeNode.slots = { icon: 'component' } + break + case 3: + treeNode.slots = { icon: 'part' } + break + default: + } + } + } + } +</script> + +<style lang="less" scoped> + + /deep/ .ant-card-body { + padding: 0 12px 0 0; + } + + /deep/ .ant-card-body, /deep/ .ant-spin-nested-loading, /deep/ .ant-spin-container { + height: 100%; + } + + /deep/ .ant-tree-node-content-wrapper { + width: calc(100% - 24px); + } + + /deep/ .ant-tree-title, .ant-tree-title .ant-dropdown-trigger { + display: inline-block; + width: calc(100% - 24px) !important; + } + + .tree_con { + overflow: hidden; + } + + @media screen and (min-width: 1920px) { + .tree_con { + height: 748px !important; + } + } + + @media screen and (min-width: 1680px) and (max-width: 1920px) { + .tree_con { + height: 748px !important; + } + } + + @media screen and (min-width: 1400px) and (max-width: 1680px) { + .tree_con { + height: 600px !important; + } + } + + @media screen and (min-width: 1280px) and (max-width: 1400px) { + .tree_con { + height: 501px !important; + } + } + + @media screen and (max-width: 1280px) { + .tree_con { + height: 501px !important; + } + } +</style> diff --git a/src/views/dnc/common/TableContextMenu.vue b/src/views/dnc/common/TableContextMenu.vue new file mode 100644 index 0000000..dd10da2 --- /dev/null +++ b/src/views/dnc/common/TableContextMenu.vue @@ -0,0 +1,87 @@ +<template> + <a-menu :style="menuStyle" @click="menuItemClick" v-if="menuVisible" mode="vertical"> + <template v-for="menuItem in defaultContextMenuList[currentMenuLevel]"> + <a-menu-item :key="menuItem.code" v-if="menuItem.show&&menuItem.subMenu.length===0"> + <a-icon :type="menuItem.icon"/> + {{menuItem.label}} + </a-menu-item> + + <a-sub-menu v-if="menuItem.subMenu.length>0"> + <span slot="title"><a-icon :type="menuItem.icon"/><span>{{menuItem.label}}</span></span> + + <a-menu-item v-for="subMenuItem in menuItem.subMenu" :key="subMenuItem.code" v-if="subMenuItem.show" + style="height: 32px;line-height: 32px"> + <a-icon :type="subMenuItem.icon"/> + {{subMenuItem.label}} + </a-menu-item> + </a-sub-menu> + </template> + </a-menu> +</template> + +<script> + export default { + name: 'TableContextMenu', + components: {}, + props: { + currentTableRowInfo: { + type: Object + } + }, + data() { + return { + menuVisible: false, + menuStyle: { + position: 'fixed', + top: 0, + left: 0, + border: '1px solid #eee', + boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)', + zIndex: 999 + }, + currentMenuLevel: '', + defaultContextMenuList: { + //鏂囨。 + document: [ + { show: true, label: '缂栬緫鏂囨。淇℃伅', code: 'document_edit', subMenu: [], icon: 'edit' }, + { show: true, label: '鎸囨淳鍒拌澶�', code: 'document_assign', subMenu: [], icon: 'cluster' }, + { show: false, label: '瀵煎嚭NC绋嬪簭', code: 'document_export', subMenu: [], icon: 'export' }, + { show: true, label: '瀵煎叆NC绋嬪簭', code: 'document_import', subMenu: [], icon: 'import' }, + { show: true, label: '涓嬭浇', code: 'document_download', subMenu: [], icon: 'download' }, + { show: true, label: '鍒犻櫎', code: 'document_delete', subMenu: [], icon: 'delete' }, + { show: true, label: '鎵归噺鍒犻櫎', code: 'document_batch_remove', subMenu: [], icon: 'delete' }, + { + show: true, + label: '鐢熷懡鍛ㄦ湡', + subMenu: [ + { show: true, label: '鍑哄簱', code: 'document_pull', icon: 'export' }, + { show: true, label: '鍙栨秷鍑哄簱', code: 'document_cancel_pull', icon: 'stop' }, + { show: true, label: '鍏ュ簱', code: 'document_push', icon: 'import' }, + { show: true, label: '鍙戝竷', code: 'document_publish', icon: 'flag' }, + { show: true, label: '閲嶆柊鍙戝竷', code: 'document_republish', icon: 'reload' }, + { show: true, label: '褰掓。', code: 'document_pigeonhole', icon: 'database' } + ], + icon: 'delete' + } + ] + } + } + }, + methods: { + menuItemClick({ item, key }) { + // process_add => handleProcessAdd 瑙﹀彂瀵瑰簲缁勪欢浜嬩欢 + const methodName = 'handle' + key.split('_').map(item => item[0].toUpperCase() + item.slice(1)).join('') + const modalTitle = this.defaultContextMenuList[this.currentMenuLevel].find(item => item.code === key).label + console.log('key', key) + this.$bus.$emit('menuItemMethodTrigger', { level: this.currentMenuLevel, methodName, modalTitle }) + } + } + } +</script> + +<style scoped> + /deep/ .ant-menu-item { + height: 32px; + line-height: 32px; + } +</style> \ No newline at end of file diff --git a/src/views/dnc/common/modules/ProductStructureTree/ProductStructureTreeContextMenu.vue b/src/views/dnc/common/modules/ProductStructureTree/ProductStructureTreeContextMenu.vue new file mode 100644 index 0000000..f8cdee9 --- /dev/null +++ b/src/views/dnc/common/modules/ProductStructureTree/ProductStructureTreeContextMenu.vue @@ -0,0 +1,118 @@ +<template> + <a-dropdown :trigger="['contextmenu']"> + <span v-if="treeParams.label.indexOf(treeParams.searchValue) > -1">{{ treeParams.label.substr(0, treeParams.label.indexOf(treeParams.searchValue)) }}<span + class="replaceSearch">{{ treeParams.searchValue }}</span>{{ treeParams.label.substr(treeParams.label.indexOf(treeParams.searchValue) + treeParams.searchValue.length) }}</span> + <span v-else>{{ treeParams.label }}</span> + <template #overlay> + <a-menu @click="({ key: menuKey }) => onContextMenuClick(treeParams.treeKey, menuKey)" + @contextmenu="event=>event.preventDefault()"> + <template v-for="item in defaultContextMenuList[getCurrentMenuLevel]"> + <a-menu-item :key="item.code" v-if="item.show"> + <a-icon :type="item.icon"/> + {{item.label}} + </a-menu-item> + </template> + </a-menu> + </template> + </a-dropdown> +</template> + +<script> + export default { + name: 'ProductStructureTreeContextMenu', + components: {}, + props: { + treeParams: { + type: Object + } + }, + data() { + return { + defaultContextMenuList: { + //浜у搧 + product: [ + { show: true, label: '娣诲姞浜у搧', code: 'product_add', icon: 'plus', isCommonMethod: false }, + { show: true, label: '娣诲姞閮ㄤ欢', code: 'product_add_child', icon: 'plus', isCommonMethod: false }, + { show: true, label: '缂栬緫浜у搧淇℃伅', code: 'product_edit', icon: 'edit', isCommonMethod: false }, + { show: false, label: '瀵煎嚭鏂囨。', code: 'product_export', icon: 'export', isCommonMethod: true }, + { show: true, label: '瀵煎叆鍏朵粬鏂囨。', code: 'product_import', icon: 'import', isCommonMethod: true }, + { show: true, label: '鍒犻櫎', code: 'product_delete', icon: 'delete', isCommonMethod: true }, + { show: true, label: '鏉冮檺閰嶇疆', code: 'public_assign_permission', icon: 'idcard', isCommonMethod: true } + ], + //閮ㄤ欢 + component: [ + { show: true, label: '娣诲姞瀛愰儴浠�', code: 'component_add', icon: 'plus', isCommonMethod: false }, + { show: true, label: '娣诲姞闆朵欢', code: 'component_add_child', icon: 'plus', isCommonMethod: false }, + { show: true, label: '鍒涘缓宸ュ簭', code: 'component_add_relative', icon: 'plus', isCommonMethod: false }, + { show: true, label: '缂栬緫閮ㄤ欢淇℃伅', code: 'component_edit', icon: 'edit', isCommonMethod: false }, + { show: false, label: '瀵煎嚭鏂囨。', code: 'component_export', icon: 'export', isCommonMethod: true }, + { show: true, label: '瀵煎叆鍏朵粬鏂囨。', code: 'component_import', icon: 'import', isCommonMethod: true }, + { show: true, label: '鍒犻櫎', code: 'component_delete', icon: 'delete', isCommonMethod: true }, + { show: true, label: '鏉冮檺閰嶇疆', code: 'public_assign_permission', icon: 'idcard', isCommonMethod: true } + ], + //闆朵欢 + part: [ + { show: true, label: '娣诲姞闆朵欢', code: 'parts_add', icon: 'plus', isCommonMethod: false }, + { show: true, label: '鍒涘缓宸ュ簭', code: 'parts_add_relative', icon: 'plus', isCommonMethod: false }, + { show: true, label: '缂栬緫闆朵欢淇℃伅', code: 'parts_edit', icon: 'edit', isCommonMethod: false }, + { show: false, label: '瀵煎嚭鏂囨。', code: 'parts_export', icon: 'export', isCommonMethod: true }, + { show: true, label: '瀵煎叆鍏朵粬鏂囨。', code: 'parts_import', icon: 'import', isCommonMethod: true }, + { show: true, label: '鍒犻櫎', code: 'parts_delete', icon: 'delete', isCommonMethod: true }, + { show: true, label: '鏉冮檺閰嶇疆', code: 'public_assign_permission', icon: 'idcard', isCommonMethod: true } + ], + //宸ュ簭 + process: [ + { show: true, label: '鍒涘缓宸ュ簭', code: 'process_add', icon: 'plus', isCommonMethod: false }, + { show: true, label: '缂栬緫宸ュ簭淇℃伅', code: 'process_edit', icon: 'edit', isCommonMethod: false }, + { show: true, label: '鍒犻櫎', code: 'process_delete', icon: 'delete', isCommonMethod: true }, + { show: false, label: '瀵煎嚭NC绋嬪簭', code: 'process_export', icon: 'import', isCommonMethod: true }, + { show: true, label: '瀵煎叆NC绋嬪簭', code: 'process_import', icon: 'export', isCommonMethod: true } + ] + } + } + }, + computed: { + getCurrentMenuLevel() { + switch (this.treeParams.type) { + case 1: + return 'product' + case 2: + return 'component' + case 3: + return 'part' + case 4: + return 'process' + case 5: + return 'processStep' + } + } + }, + methods: { + onContextMenuClick(treeKey, menuKey) { + const level = this.getCurrentMenuLevel + const menuKeyArray = menuKey.split('_') + const isCommonMethod = this.defaultContextMenuList[level].find(item => item.code === menuKey).isCommonMethod + // product_add => handleAdd 瑙﹀彂瀵瑰簲缁勪欢浜嬩欢 + let methodName + // 鍒ゆ柇鏄惁涓哄叕鍏辨柟娉曪紝濡傛灉涓哄叕鍏辨柟娉曞垯鎴彇涓撴湁灞炴�roduct/component/part/process绛夊瓧娈� + if (isCommonMethod) { + methodName = 'handle' + menuKeyArray.map(item => item[0].toUpperCase() + item.slice(1)).slice(1).join('') + } else { + methodName = 'handle' + menuKeyArray.map(item => item[0].toUpperCase() + item.slice(1)).join('') + } + console.log('methodName------------------------------------', methodName) + const modalTitle = this.defaultContextMenuList[level].find(item => item.code === menuKey).label + this.$bus.$emit('treeMenuItemMethodTrigger', { methodName, modalTitle }) + } + } + } +</script> + +<style scoped> + .replaceSearch { + color: #40a9ff; + font-weight: bold; + background-color: rgb(204, 204, 204); + } + +</style> \ No newline at end of file -- Gitblit v1.9.3