| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import request from "@/utils/request.js"; |
| | | |
| | | export function productModelList(query) { |
| | | return request({ |
| | | url: '/basic/product/pageModel', |
| | | method: 'get', |
| | | params: query |
| | | }) |
| | | } |
| | |
| | | // å·¥åºé¡µé¢æ¥å£ |
| | | // å·¥èºè·¯çº¿é¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // å页æ¥è¯¢ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // å·¥èºè·¯çº¿é¡¹ç®é¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // å表æ¥è¯¢ |
| | | export function findProcessRouteItemList(query) { |
| | | return request({ |
| | | url: "/processRouteItem/list", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | export function addOrUpdateProcessRouteItem(data) { |
| | | return request({ |
| | | url: "/processRouteItem", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // 产åç»æé¡µé¢æ¥å£ |
| | | import request from "@/utils/request"; |
| | | |
| | | // å页æ¥è¯¢ |
| | | export function queryList(id) { |
| | | return request({ |
| | | url: "/productStructure/listByproductModelId/" + id, |
| | | method: "get", |
| | | }); |
| | | } |
| | | |
| | | export function add(data) { |
| | | return request({ |
| | | url: "/productStructure", |
| | | method: "post", |
| | | data: data, |
| | | }); |
| | | } |
| | |
| | | }); |
| | | } |
| | | |
| | | export function processList(query) { |
| | | return request({ |
| | | url: "/productProcess/list", |
| | | method: "get", |
| | | params: query, |
| | | }); |
| | | } |
| | | |
| | | export function add(data) { |
| | | return request({ |
| | | url: "/productProcess", |
| | |
| | | method: 'put', |
| | | data: data, |
| | | }) |
| | | } |
| | | |
| | | // å·¥åºæ¥è¯¢ |
| | | export function list() { |
| | | return request({ |
| | | url: "/productProcess/list", |
| | | method: "get", |
| | | }); |
| | | } |
| | |
| | | :data="tableData" |
| | | height="420" |
| | | highlight-current-row |
| | | @current-change="onCurrentChange" |
| | | row-key="id" |
| | | @selection-change="handleSelectionChange" |
| | | > |
| | | <el-table-column type="selection" width="55" /> |
| | | <el-table-column type="index" label="#" width="60"/> |
| | | <el-table-column prop="productName" label="产å大类" min-width="160"/> |
| | | <el-table-column prop="model" label="åå·åç§°" min-width="200"/> |
| | |
| | | |
| | | <template #footer> |
| | | <el-button @click="close()">åæ¶</el-button> |
| | | <el-button type="primary" :disabled="!selectedRow" @click="onConfirm"> |
| | | <el-button type="primary" :disabled="multipleSelection.length === 0" @click="onConfirm"> |
| | | ç¡®å® |
| | | </el-button> |
| | | </template> |
| | |
| | | <script setup lang="ts"> |
| | | import {computed, onMounted, reactive, ref, watch} from "vue"; |
| | | import {ElMessage} from "element-plus"; |
| | | import {list} from '@/api/basicData/productModel' |
| | | import {productModelList} from '@/api/basicData/productModel' |
| | | |
| | | export type ProductRow = { |
| | | id: number; |
| | |
| | | modelValue: boolean; |
| | | }>(); |
| | | |
| | | const emit = defineEmits<{ |
| | | (e: "update:modelValue", v: boolean): void; |
| | | (e: "confirm", row: ProductRow): void; // ææ´è¡æ°æ®è¿ç»ç¶ç»ä»¶ |
| | | }>(); |
| | | const emit = defineEmits(['update:modelValue', 'confirm']); |
| | | |
| | | const visible = computed({ |
| | | get: () => props.modelValue, |
| | |
| | | const loading = ref(false); |
| | | const tableData = ref<ProductRow[]>([]); |
| | | const total = ref(0); |
| | | const selectedRow = ref<ProductRow | null>(null); |
| | | const multipleSelection = ref<ProductRow[]>([]) |
| | | |
| | | function close() { |
| | | visible.value = false; |
| | | } |
| | | |
| | | function onCurrentChange(row: ProductRow | null) { |
| | | selectedRow.value = row; |
| | | const handleSelectionChange = (val: ProductRow[]) => { |
| | | multipleSelection.value = val |
| | | } |
| | | |
| | | function onSearch() { |
| | |
| | | } |
| | | |
| | | function onConfirm() { |
| | | if (!selectedRow.value) { |
| | | if (multipleSelection.value.length === 0) { |
| | | ElMessage.warning("è¯·éæ©ä¸æ¡äº§å"); |
| | | return; |
| | | } |
| | | emit("confirm", selectedRow.value); |
| | | emit("confirm", multipleSelection.value); |
| | | close(); |
| | | } |
| | | |
| | | async function loadData() { |
| | | loading.value = true; |
| | | try { |
| | | selectedRow.value = null; // 翻页/æç´¢åæ¸
ç©ºéæ©æ´ç¬¦å颿 |
| | | const res = await list({ |
| | | multipleSelection.value = []; // 翻页/æç´¢åæ¸
ç©ºéæ©æ´ç¬¦å颿 |
| | | const res = await productModelList({ |
| | | productName: query.productName.trim(), |
| | | model: query.model.trim(), |
| | | pageNum: page.pageNum, |
| | | pageSize: page.pageSize, |
| | | current: page.pageNum, |
| | | size: page.pageSize, |
| | | }); |
| | | tableData.value = res.list; |
| | | tableData.value = res.records; |
| | | total.value = res.total; |
| | | } finally { |
| | | loading.value = false; |
| | |
| | | <div> |
| | | <el-dialog |
| | | v-model="isShow" |
| | | title="ç¼è¾å·¥åº" |
| | | title="ç¼è¾å·¥èºè·¯çº¿" |
| | | width="400" |
| | | @close="closeModal" |
| | | > |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog |
| | | v-model="isShow" |
| | | title="å·¥èºè·¯çº¿é¡¹ç®" |
| | | width="800px" |
| | | @close="closeModal" |
| | | > |
| | | <el-button |
| | | type="primary" |
| | | @click="isShowProductSelectDialog = true" |
| | | class="mb5" |
| | | style="margin-bottom: 10px;" |
| | | > |
| | | éæ©äº§å |
| | | </el-button> |
| | | |
| | | <el-table |
| | | ref="multipleTable" |
| | | v-loading="tableLoading" |
| | | border |
| | | :data="routeItems" |
| | | :header-cell-style="{ background: '#F0F1F5', color: '#333333' }" |
| | | row-key="id" |
| | | tooltip-effect="dark" |
| | | class="lims-table" |
| | | style="cursor: move;" |
| | | > |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" /> |
| | | |
| | | <el-table-column |
| | | v-for="(item, index) in tableColumn" |
| | | :key="index" |
| | | :label="item.label" |
| | | :width="item.width" |
| | | show-overflow-tooltip |
| | | > |
| | | <template #default="scope" v-if="item.dataType === 'action'"> |
| | | <el-button |
| | | v-for="(op, opIndex) in item.operation" |
| | | :key="opIndex" |
| | | :type="op.type" |
| | | :link="op.link" |
| | | size="small" |
| | | @click.stop="op.clickFun(scope.row)" |
| | | > |
| | | {{ op.name }} |
| | | </el-button> |
| | | </template> |
| | | |
| | | <template #default="scope" v-else> |
| | | <template v-if="item.prop === 'processId'"> |
| | | <el-select |
| | | v-model="scope.row[item.prop]" |
| | | style="width: 100%;" |
| | | @mousedown.stop |
| | | > |
| | | <el-option |
| | | v-for="process in processOptions" |
| | | :key="process.id" |
| | | :label="process.name" |
| | | :value="process.id" |
| | | /> |
| | | </el-select> |
| | | </template> |
| | | <template v-else> |
| | | {{ scope.row[item.prop] || '-' }} |
| | | </template> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="handleSubmit">确认</el-button> |
| | | <el-button @click="closeModal">åæ¶</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <ProductSelectDialog |
| | | v-model="isShowProductSelectDialog" |
| | | @confirm="handelSelectProducts" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, computed, getCurrentInstance, onMounted, onUnmounted, nextTick } from "vue"; |
| | | import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue"; |
| | | import { findProcessRouteItemList, addOrUpdateProcessRouteItem } from "@/api/productionManagement/processRouteItem.js"; |
| | | import { processList } from "@/api/productionManagement/productionProcess.js"; |
| | | import Sortable from 'sortablejs'; |
| | | |
| | | const props = defineProps({ |
| | | visible: { |
| | | type: Boolean, |
| | | required: true, |
| | | default: false |
| | | }, |
| | | record: { |
| | | type: Object, |
| | | required: true, |
| | | default: () => ({}) |
| | | } |
| | | }); |
| | | |
| | | const emit = defineEmits(['update:visible', 'completed']); |
| | | |
| | | const processOptions = ref([]); |
| | | const tableLoading = ref(false); |
| | | const isShowProductSelectDialog = ref(false); |
| | | const routeItems = ref([]); |
| | | let sortable = null; |
| | | const multipleTable = ref(null); |
| | | |
| | | const isShow = computed({ |
| | | get() { |
| | | return props.visible; |
| | | }, |
| | | set(val) { |
| | | emit('update:visible', val); |
| | | } |
| | | }); |
| | | |
| | | const tableColumn = ref([ |
| | | { label: "产ååç§°", prop: "productName", width: 180 }, |
| | | { label: "è§æ ¼åç§°", prop: "model", width: 150 }, |
| | | { label: "åä½", prop: "unit", width: 80 }, |
| | | { label: "å·¥åºåç§°", prop: "processId", width: 180 }, |
| | | { |
| | | dataType: "action", |
| | | label: "æä½", |
| | | align: "center", |
| | | fixed: "right", |
| | | width: 100, |
| | | operation: [ |
| | | { |
| | | name: "å é¤", |
| | | type: "danger", |
| | | link: true, |
| | | clickFun: (row) => { |
| | | const idx = routeItems.value.findIndex(item => item.id === row.id); |
| | | if (idx > -1) { |
| | | routeItems.value.splice(idx, 1); |
| | | } |
| | | } |
| | | } |
| | | ] |
| | | } |
| | | ]); |
| | | |
| | | const closeModal = () => { |
| | | isShow.value = false; |
| | | }; |
| | | |
| | | const handelSelectProducts = (products) => { |
| | | const newData = products.map(({ id, ...product }) => ({ |
| | | ...product, |
| | | productModelId: id, |
| | | routeId: props.record.id, |
| | | id: `${Date.now()}-${Math.random().toString(36).slice(2)}`, // çææ ç¹æ®å符çID |
| | | processId: undefined |
| | | })); |
| | | routeItems.value.push(...newData); |
| | | |
| | | nextTick(() => initSortable()); |
| | | }; |
| | | |
| | | const findProcessRouteItems = () => { |
| | | tableLoading.value = true; |
| | | findProcessRouteItemList({ routeId: props.record.id }) |
| | | .then(res => { |
| | | tableLoading.value = false; |
| | | routeItems.value = res.data.map(item => ({ |
| | | ...item, |
| | | processId: item.processId === 0 ? undefined : item.processId |
| | | })); |
| | | nextTick(() => initSortable()); |
| | | }) |
| | | .catch(err => { |
| | | tableLoading.value = false; |
| | | console.error("è·åå表失败ï¼", err); |
| | | }); |
| | | }; |
| | | |
| | | const findProcessList = () => { |
| | | processList({}) |
| | | .then(res => { |
| | | processOptions.value = res.data; |
| | | }) |
| | | .catch(err => { |
| | | console.error("è·åå·¥åºå¤±è´¥ï¼", err); |
| | | }); |
| | | }; |
| | | |
| | | const { proxy } = getCurrentInstance() || {}; |
| | | |
| | | const handleSubmit = () => { |
| | | if (routeItems.value.length === 0) { |
| | | proxy?.$modal?.msgError("请添å 路线项ç®"); |
| | | return; |
| | | } |
| | | |
| | | const hasEmptyProcess = routeItems.value.some(item => !item.processId); |
| | | if (hasEmptyProcess) { |
| | | proxy?.$modal?.msgError("请为ææé¡¹ç®éæ©å·¥åº"); |
| | | return; |
| | | } |
| | | |
| | | addOrUpdateProcessRouteItem({ |
| | | routeId: props.record.id, |
| | | processRouteItem: routeItems.value.map(({ id, ...item }) => item) |
| | | }) |
| | | .then(res => { |
| | | isShow.value = false; |
| | | emit('completed'); |
| | | proxy?.$modal?.msgSuccess("æäº¤æå"); |
| | | }) |
| | | .catch(err => { |
| | | proxy?.$modal?.msgError(`æäº¤å¤±è´¥ï¼${err.msg || "ç½ç»å¼å¸¸"}`); |
| | | }); |
| | | }; |
| | | |
| | | const initSortable = () => { |
| | | if (sortable) { |
| | | sortable.destroy(); |
| | | sortable = null; |
| | | } |
| | | |
| | | if (!multipleTable.value) return; |
| | | |
| | | const tbody = multipleTable.value.$el.querySelector('.el-table__body tbody') || |
| | | multipleTable.value.$el.querySelector('.el-table__body-wrapper > table > tbody'); |
| | | if (!tbody) return; |
| | | |
| | | sortable = new Sortable(tbody, { |
| | | animation: 150, |
| | | ghostClass: 'sortable-ghost', |
| | | handle: '.el-table__row', |
| | | filter: '.el-button, .el-select', |
| | | onEnd: (evt) => { |
| | | const moveItem = routeItems.value.splice(evt.oldIndex, 1)[0]; |
| | | routeItems.value.splice(evt.newIndex, 0, moveItem); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | findProcessRouteItems(); |
| | | findProcessList(); |
| | | }); |
| | | |
| | | onUnmounted(() => { |
| | | if (sortable) { |
| | | sortable.destroy(); |
| | | } |
| | | }); |
| | | |
| | | // ä¿®å¤ï¼æ´é²æ¹æ³æ¶é¿å
è¯æ³é误 |
| | | defineExpose({ |
| | | closeModal, |
| | | handleSubmit, |
| | | isShow |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | :deep(.sortable-ghost) { |
| | | opacity: 0.6; |
| | | background-color: #f5f7fa !important; |
| | | } |
| | | |
| | | :deep(.el-table__row) { |
| | | transition: background-color 0.2s; |
| | | } |
| | | |
| | | :deep(.el-table__row:hover) { |
| | | background-color: #f9fafc !important; |
| | | } |
| | | |
| | | .mb5 { |
| | | margin-bottom: 5px; |
| | | } |
| | | </style> |
| | |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <el-form :model="searchForm" :inline="true"> |
| | | <el-form-item label="é¶ä»¶åç§°:"> |
| | | <el-input v-model="searchForm.speculativeTradingName" placeholder="请è¾å
¥" clearable prefix-icon="Search" |
| | | <el-form-item label="è§æ ¼åç§°:"> |
| | | <el-input v-model="searchForm.model" placeholder="请è¾å
¥" clearable prefix-icon="Search" |
| | | style="width: 200px;" |
| | | @change="handleQuery" /> |
| | | </el-form-item> |
| | |
| | | :tableLoading="tableLoading" |
| | | @pagination="pagination" |
| | | :total="page.total" |
| | | ></PIMTable> |
| | | /> |
| | | </div> |
| | | <new-process |
| | | v-if="isShowNewModal" |
| | |
| | | :record="record" |
| | | @completed="getList" |
| | | /> |
| | | |
| | | <route-item-form |
| | | v-if="isShowItemModal" |
| | | v-model:visible="isShowItemModal" |
| | | :record="record" |
| | | @completed="getList" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | import {onMounted, ref} from "vue"; |
| | | import NewProcess from "@/views/productionManagement/processRoute/New.vue"; |
| | | import EditProcess from "@/views/productionManagement/processRoute/Edit.vue"; |
| | | import RouteItemForm from "@/views/productionManagement/processRoute/ItemsForm.vue"; |
| | | import {listPage, del} from "@/api/productionManagement/processRoute.js"; |
| | | |
| | | const data = reactive({ |
| | |
| | | width: 280, |
| | | operation: [ |
| | | { |
| | | name: "详æ
", |
| | | name: "ç¼è¾", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | showEditModal(row); |
| | | } |
| | | }, |
| | | { |
| | | name: "ç¼è¾", |
| | | name: "路线项ç®", |
| | | type: "text", |
| | | clickFun: (row) => { |
| | | showEditModal(row); |
| | | showItemModal(row); |
| | | } |
| | | } |
| | | ] |
| | |
| | | const tableLoading = ref(false); |
| | | const isShowNewModal = ref(false); |
| | | const isShowEditModal = ref(false); |
| | | const isShowItemModal = ref(false); |
| | | const record = ref({}); |
| | | const page = reactive({ |
| | | current: 1, |
| | |
| | | record.value = row |
| | | }; |
| | | |
| | | const showItemModal = (row) => { |
| | | isShowItemModal.value = true |
| | | record.value = row |
| | | }; |
| | | |
| | | // å é¤ |
| | | function handleDelete() { |
| | | const ids = selectedRows.value.map((item) => item.id); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-dialog |
| | | v-model="visible" |
| | | title="ç»æ" |
| | | width="1200" |
| | | close-on-click-modal |
| | | @close="visible = false" |
| | | > |
| | | <el-button |
| | | v-if="dataValue.isEdit" |
| | | type="primary" |
| | | @click="addItem" |
| | | style="margin-bottom: 10px" |
| | | >æ·»å |
| | | </el-button> |
| | | <el-button |
| | | v-if="!dataValue.isEdit" |
| | | type="primary" |
| | | @click="dataValue.isEdit = true" |
| | | style="margin-bottom: 10px" |
| | | >ç¼è¾ |
| | | </el-button> |
| | | <el-button |
| | | v-if="dataValue.isEdit" |
| | | type="primary" |
| | | @click="cancelEdit" |
| | | style="margin-bottom: 10px" |
| | | >åæ¶ |
| | | </el-button> |
| | | <el-form |
| | | ref="form" |
| | | :model="dataValue" |
| | | > |
| | | <el-table :data="dataValue.dataList" style="width: 100%"> |
| | | <el-table-column prop="productName" label="产å" width="150"/> |
| | | <el-table-column prop="model" label="è§æ ¼" width="150"> |
| | | <template #default="{ row, $index }"> |
| | | <el-form-item |
| | | v-if="dataValue.isEdit" |
| | | :prop="`dataList.${$index}.model`" |
| | | :rules="[{ required: true, message: 'è¯·éæ©è§æ ¼', trigger: ['blur','change'] }]" |
| | | style="margin: 0" |
| | | > |
| | | <el-select |
| | | v-model="row.model" |
| | | placeholder="è¯·éæ©äº§å" |
| | | clearable |
| | | :disabled="!dataValue.isEdit" |
| | | style="width: 100%" |
| | | @visible-change="(v) => { if (v) openDialog($index) }" |
| | | > |
| | | <el-option v-if="row.model" :label="row.model" :value="row.model" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column prop="processId" label="æ¶èå·¥åº" width="150"> |
| | | <template #default="{ row, $index }"> |
| | | <el-form-item |
| | | :prop="`dataList.${$index}.processId`" |
| | | :rules="[{ required: true, message: 'è¯·éæ©æ¶èå·¥åº', trigger: 'change' }]" |
| | | style="margin: 0" |
| | | > |
| | | <el-select |
| | | v-model="row.processId" |
| | | placeholder="è¯·éæ©" |
| | | filterable |
| | | clearable |
| | | style="width: 100%" |
| | | :disabled="!dataValue.isEdit" |
| | | > |
| | | <el-option |
| | | v-for="item in dataValue.processOptions" |
| | | :key="item.id" |
| | | :label="item.name" |
| | | :value="item.id" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column prop="unitQuantity" label="åä½äº§åºæéæ°é" width="150"> |
| | | <template #default="{ row, $index }"> |
| | | <el-form-item |
| | | :prop="`dataList.${$index}.unitQuantity`" |
| | | :rules="[{ required: true, message: '请è¾å
¥åä½äº§åºæéæ°é', trigger: ['blur','change'] }]" |
| | | style="margin: 0" |
| | | > |
| | | <el-input-number |
| | | v-model="row.unitQuantity" |
| | | :min="0" |
| | | :precision="2" |
| | | :step="1" |
| | | controls-position="right" |
| | | style="width: 100%" |
| | | :disabled="!dataValue.isEdit" |
| | | /> |
| | | </el-form-item> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column prop="demandedQuantity" label="éæ±æ»é" width="150"> |
| | | <template #default="{ row, $index }"> |
| | | <el-form-item |
| | | :prop="`dataList.${$index}.demandedQuantity`" |
| | | :rules="[{ required: true, message: '请è¾å
¥éæ±æ»é', trigger: ['blur','change'] }]" |
| | | style="margin: 0" |
| | | > |
| | | <el-input-number |
| | | v-model="row.demandedQuantity" |
| | | :min="0" |
| | | :precision="2" |
| | | :step="1" |
| | | controls-position="right" |
| | | style="width: 100%" |
| | | :disabled="!dataValue.isEdit" |
| | | /> |
| | | </el-form-item> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column prop="unit" label="åä½" width="150"> |
| | | <template #default="{ row, $index }"> |
| | | <el-form-item |
| | | :prop="`dataList.${$index}.unit`" |
| | | :rules="[{ required: true, message: '请è¾å
¥åä½', trigger: ['blur','change'] }]" |
| | | style="margin: 0" |
| | | > |
| | | <el-input |
| | | v-model="row.unit" |
| | | placeholder="请è¾å
¥åä½" |
| | | clearable |
| | | :disabled="!dataValue.isEdit" |
| | | /> |
| | | </el-form-item> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column prop="diskQuantity" label="çæ°ï¼çï¼" width="150"> |
| | | <template #default="{ row, $index }"> |
| | | <el-form-item |
| | | :prop="`dataList.${$index}.diskQuantity`" |
| | | :rules="[{ required: true, message: '请è¾å
¥çæ°', trigger: ['blur','change'] }]" |
| | | style="margin: 0" |
| | | > |
| | | <el-input-number |
| | | v-model="row.diskQuantity" |
| | | :min="0" |
| | | :precision="0" |
| | | :step="1" |
| | | controls-position="right" |
| | | style="width: 100%" |
| | | :disabled="!dataValue.isEdit" |
| | | /> |
| | | </el-form-item> |
| | | </template> |
| | | </el-table-column> |
| | | |
| | | <el-table-column label="æä½"> |
| | | <template #default="{ row, $index }"> |
| | | <el-button |
| | | type="danger" |
| | | text |
| | | @click="dataValue.dataList.splice($index, 1)" |
| | | >å é¤ |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </el-form> |
| | | |
| | | <product-select-dialog |
| | | v-if="dataValue.showProductDialog" |
| | | v-model:model-value="dataValue.showProductDialog" |
| | | @confirm="handleProduct"/> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button @click="visible = false">åæ¶</el-button> |
| | | <el-button type="primary" :loading="dataValue.loading" @click="submit" :disabled="!dataValue.isEdit"> |
| | | 确认 |
| | | </el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import {computed, defineAsyncComponent, defineComponent, onMounted, reactive, ref} from "vue"; |
| | | import {queryList, add} from '@/api/productionManagement/productStructure.js' |
| | | import {list} from '@/api/productionManagement/productionProcess' |
| | | import {ElMessage} from "element-plus"; |
| | | |
| | | |
| | | defineComponent({ |
| | | name: "StructureEdit", |
| | | }) |
| | | |
| | | const ProductSelectDialog = defineAsyncComponent(() => import('@/views/basicData/product/ProductSelectDialog.vue')) |
| | | const form = ref() |
| | | |
| | | |
| | | |
| | | const props = defineProps({ |
| | | showModel: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | productModelId: { |
| | | type: Number, |
| | | required: true |
| | | } |
| | | }) |
| | | |
| | | const emits = defineEmits(['update:showModel']) |
| | | const visible = computed({ |
| | | get() { |
| | | return props.showModel |
| | | }, |
| | | set(val) { |
| | | emits('update:showModel', val) |
| | | } |
| | | }) |
| | | |
| | | const dataValue = reactive({ |
| | | dataList: [], |
| | | productOptions: [], |
| | | processOptions: [], |
| | | showProductDialog: false, |
| | | currentRowIndex: null, |
| | | loading: false, |
| | | isEdit: false, |
| | | }); |
| | | |
| | | const openDialog = (index) => { |
| | | dataValue.currentRowIndex = index |
| | | dataValue.showProductDialog = true |
| | | } |
| | | |
| | | const fetchData = async () => { |
| | | const {data} = await queryList(props.productModelId) |
| | | dataValue.dataList = data |
| | | } |
| | | |
| | | const fetchProcessOptions = async () => { |
| | | const {data} = await list(props.productModelId) |
| | | dataValue.processOptions = data |
| | | } |
| | | |
| | | const handleProduct = (row) => { |
| | | if (row?.length > 1) { |
| | | ElMessage.error('åªè½éæ©ä¸ä¸ªäº§å') |
| | | } |
| | | dataValue.dataList[dataValue.currentRowIndex].productName = row[0].productName |
| | | dataValue.dataList[dataValue.currentRowIndex].model = row[0].model |
| | | dataValue.dataList[dataValue.currentRowIndex].productModelId = row[0].id |
| | | dataValue.showProductDialog = false |
| | | } |
| | | |
| | | const submit = () => { |
| | | form.value.validate(valid => { |
| | | dataValue.loading = true |
| | | if (valid) { |
| | | add({ |
| | | parentId: props.productModelId, |
| | | productStructureList: dataValue.dataList || [] |
| | | }).then(res => { |
| | | ElMessage.success('ä¿åæå') |
| | | visible.value = false |
| | | dataValue.loading = false |
| | | }) |
| | | } |
| | | }).finally(() => { |
| | | dataValue.loading = false |
| | | }) |
| | | } |
| | | |
| | | const addItem = () => { |
| | | dataValue.dataList.push({ |
| | | productName: '', |
| | | productId: '', |
| | | model: undefined, |
| | | productModelId: undefined, |
| | | processId: '', |
| | | unitQuantity: 0, |
| | | demandedQuantity: 0, |
| | | unit: '', |
| | | diskQuantity: 0, |
| | | }) |
| | | } |
| | | |
| | | const cancelEdit = () => { |
| | | dataValue.isEdit = false |
| | | dataValue.dataList = dataValue.dataList.filter(item => item.id !== undefined) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | fetchData() |
| | | fetchProcessOptions() |
| | | }) |
| | | |
| | | |
| | | </script> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="tableColumn" |
| | | :tableData="tableData" |
| | | :page="page" |
| | | :isSelection="true" |
| | | @selection-change="handleSelectionChange" |
| | | :tableLoading="tableLoading" |
| | | @pagination="pagination" |
| | | > |
| | | <template #detail="{row}"> |
| | | <el-button |
| | | type="primary" |
| | | text |
| | | @click="() =>{ |
| | | currentRowId = row.id; |
| | | showEdit = true; |
| | | }" |
| | | >{{ row.productName }} |
| | | </el-button> |
| | | </template> |
| | | </PIMTable> |
| | | <StructureEdit v-if="showEdit" v-model:show-model="showEdit" :product-model-id="currentRowId"/> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref} from "vue"; |
| | | import {productModelList} from "@/api/basicData/productModel.js"; |
| | | |
| | | const StructureEdit = defineAsyncComponent(() => import('@/views/productionManagement/productStructure/StructureEdit.vue')) |
| | | |
| | | const tableColumn = ref([ |
| | | { |
| | | label: "产ååç§°", |
| | | prop: "productName", |
| | | dataType: 'slot', |
| | | slot: "detail" |
| | | }, |
| | | { |
| | | label: "è§æ ¼åå·", |
| | | prop: "model", |
| | | }, |
| | | { |
| | | label: "åä½", |
| | | prop: "unit", |
| | | } |
| | | ]); |
| | | const tableData = ref([]); |
| | | const tableLoading = ref(false); |
| | | const showEdit = ref(false); |
| | | const selectedRows = ref([]); |
| | | const currentRowId = ref(0); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 10, |
| | | total: 0, |
| | | }); |
| | | const data = reactive({ |
| | | form: { |
| | | productName: "", |
| | | }, |
| | | rules: { |
| | | productName: [{required: true, message: "请è¾å
¥", trigger: "blur"}], |
| | | }, |
| | | modelForm: { |
| | | otherModel: '', |
| | | model: "", |
| | | unit: "", |
| | | speculativeTradingName: [], |
| | | }, |
| | | }); |
| | | const {form, rules} = toRefs(data); |
| | | // è¡¨æ ¼éæ©æ°æ® |
| | | const handleSelectionChange = (selection) => { |
| | | selectedRows.value = selection; |
| | | }; |
| | | |
| | | // æ¥è¯¢è§æ ¼åå· |
| | | const pagination = (obj) => { |
| | | page.current = obj.page; |
| | | page.size = obj.limit; |
| | | getModelList(); |
| | | }; |
| | | const getModelList = () => { |
| | | tableLoading.value = true; |
| | | productModelList({ |
| | | current: page.current, |
| | | size: page.size, |
| | | }).then((res) => { |
| | | tableData.value = res.records; |
| | | page.total = res.total; |
| | | tableLoading.value = false; |
| | | }); |
| | | }; |
| | | onMounted(() => { |
| | | getModelList(); |
| | | }) |
| | | </script> |