From 692451959df42c10d489d866dcae48a121bd9dd0 Mon Sep 17 00:00:00 2001 From: gaoluyang <2820782392@qq.com> Date: 星期二, 20 五月 2025 17:51:24 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev --- src/views/basicData/product/index.vue | 385 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 385 insertions(+), 0 deletions(-) diff --git a/src/views/basicData/product/index.vue b/src/views/basicData/product/index.vue new file mode 100644 index 0000000..dba78e3 --- /dev/null +++ b/src/views/basicData/product/index.vue @@ -0,0 +1,385 @@ +<template> + <div class="app-container product-view"> + <div class="left"> + <div> + <el-input + v-model="search" + style="width: 240px" + placeholder="杈撳叆鍏抽敭瀛楄繘琛屾悳绱�" + @change="searchFilter" + @clear="searchFilter" + clearable + prefix-icon="Search" + /> + <el-button type="primary" @click="openProDia('add')" style="margin-left: 10px">鏂板浜у搧</el-button> + </div> + <div> + <el-tree ref="tree" v-loading="treeLoad" :data="list" @node-click="handleNodeClick" + :expand-on-click-node="false" + :default-expanded-keys="expandedKeys" :draggable="true" :filter-node-method="filterNode" + :props="{ children: 'children', label: 'label' }" highlight-current node-key="id" + style="height: calc(100vh - 190px);overflow-y: scroll;scrollbar-width: none;"> + <template #default="{ node, data }"> + <div class="custom-tree-node"> + <span>{{ node.label }}</span> + <div> + <el-button type="primary" link @click="openProDia('edit', data)"> + 缂栬緫 + </el-button> + <!-- 淇敼姝ゅ --> + <el-button + v-if="!node.childNodes.length" + style="margin-left: 4px" + type="danger" + link + @click="remove(node, data)" + > + 鍒犻櫎 + </el-button> + </div> + </div> + </template> + </el-tree> + </div> + </div> + <div class="right"> + <div style="margin-bottom: 10px"> + <el-button type="primary" @click="openModelDia('add')">鏂板瑙勬牸鍨嬪彿</el-button> + <el-button type="danger" @click="handleDelete" style="margin-left: 10px" plain>鍒犻櫎</el-button> + </div> + <PIMTable :column="tableColumn" :tableData="tableData" :page="page" :isSelection="true" :handleSelectionChange="handleSelectionChange" + :tableLoading="tableLoading" @pagination="pagination" :total="total"></PIMTable> + </div> + <el-dialog v-model="productDia" title="浜у搧" width="400px"> + <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> + <el-row :gutter="30"> + <el-col :span="24"> + <el-form-item label="浜у搧鍚嶇О锛�" prop="productName"> + <el-input v-model="form.productName" placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�" clearable/> + </el-form-item> + </el-col> + </el-row> + </el-form> + <template #footer> + <div class="dialog-footer"> + <el-button type="primary" @click="submitForm">纭</el-button> + <el-button @click="closeProDia">鍙栨秷</el-button> + </div> + </template> + </el-dialog> + <el-dialog v-model="modelDia" title="浜у搧" width="400px"> + <el-form :model="modelForm" label-width="140px" label-position="top" :rules="modelRules" ref="modelFormRef"> + <el-row> + <el-col :span="24"> + <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="model"> + <el-input v-model="modelForm.model" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" clearable/> + </el-form-item> + </el-col> + </el-row> + <el-row> + <el-col :span="24"> + <el-form-item label="鍗曚綅锛�" prop="unit"> + <el-input v-model="modelForm.unit" placeholder="璇疯緭鍏ュ崟浣�" clearable/> + </el-form-item> + </el-col> + </el-row> + </el-form> + <template #footer> + <div class="dialog-footer"> + <el-button type="primary" @click="submitModelForm">纭</el-button> + <el-button @click="closeProDia">鍙栨秷</el-button> + </div> + </template> + </el-dialog> + </div> +</template> + +<script setup> +import {ref} from "vue"; +import {ElMessageBox} from "element-plus"; +import { + addOrEditProduct, + addOrEditProductModel, + delProduct, delProductModel, + modelList, + productTreeList +} from "@/api/basicData/product.js"; +const { proxy } = getCurrentInstance() + +const productDia = ref(false) +const modelDia = ref(false) +const modelOperationType = ref('') +const search = ref('') +const currentId = ref('') +const currentParentId = ref('') +const operationType = ref('') +const treeLoad = ref(false) +const list = ref([]) +const expandedKeys = ref([]) +const tableColumn = ref([ + { + label: '瑙勬牸鍨嬪彿', + prop: 'model', + }, + { + label: '鍗曚綅', + prop: 'unit', + }, + { + dataType: "action", + label: "鎿嶄綔", + align: 'center', + operation: [ + { + name: "缂栬緫", + type: "text", + clickFun: (row) => { + openModelDia('edit', row); + }, + }, + ], + }, +]) +const tableData = ref([]) +const tableLoading = ref(false) +const total = ref(0) +const selectedRows = ref([]) +const page = reactive({ + current: 1, + size: 10, +}) +const data = reactive({ + form: { + productName: '', + }, + rules: { + productName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }], + }, + modelForm: { + model: '', + unit: '', + }, + modelRules: { + model: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }], + unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }], + } +}) +const { form, rules, modelForm, modelRules } = toRefs(data) +// 鏌ヨ浜у搧鏍� +const getProductTreeList = () => { + treeLoad.value = true; + productTreeList().then(res => { + list.value = res + list.value.forEach((a) => { + expandedKeys.value.push(a.label); + }); + treeLoad.value = false; + }).catch(err => { + treeLoad.value = false; + }) +} +// 杩囨护浜у搧鏍� +const searchFilter = () => { + proxy.$refs.tree.filter(search.value); +} +// 鎵撳紑浜у搧寮规 +const openProDia = (type, data) => { + operationType.value = type; + productDia.value = true + form.value.productName = '' + if (type === 'edit') { + form.value.productName = data.productName + } +} +// 鎵撳紑瑙勬牸鍨嬪彿寮规 +const openModelDia = (type, data) => { + modelOperationType.value = type; + modelDia.value = true + modelForm.value.model = '' + modelForm.value.model = '' + modelForm.value.id = '' + if (type === 'edit') { + modelForm.value = {...data} + } +} +// 鎻愪氦浜у搧鍚嶇О淇敼 +const submitForm = () => { + proxy.$refs.formRef.validate(valid => { + if (valid) { + if (operationType.value === 'add') { + form.value.parentId = currentId.value + form.value.id = '' + } else { + form.value.id = currentId.value + form.value.parentId = '' + } + addOrEditProduct(form.value).then(res => { + proxy.$modal.msgSuccess("鎻愪氦鎴愬姛") + closeProDia() + getProductTreeList() + }) + } + }) +} +// 鍏抽棴浜у搧寮规 +const closeProDia = () => { + proxy.$refs.formRef.resetFields(); + productDia.value = false; +} +// 鍒犻櫎浜у搧 +const remove = (node, data) => { + let ids = [] + ids.push(data.id) + ElMessageBox.confirm( + '閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�', + '鍒犻櫎鎻愮ず', { + confirmButtonText: '纭', + cancelButtonText: '鍙栨秷', + type: 'warning', + } + ).then(() => { + tableLoading.value = true + delProduct(ids).then(res => { + proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛") + getProductTreeList() + }).finally(() => { + tableLoading.value = false + }) + }).catch(() => { + proxy.$modal.msg("宸插彇娑�") + }) +} +// 閫夋嫨浜у搧 +const handleNodeClick = (val, node, el) => { + currentId.value = val.id + currentParentId.value = val.parentId + getModelList() +} + + +// 鎻愪氦瑙勬牸鍨嬪彿淇敼 +const submitModelForm = () => { + proxy.$refs.modelFormRef.validate(valid => { + if (valid) { + modelForm.value.productId = currentId.value + addOrEditProductModel(modelForm.value).then(res => { + proxy.$modal.msgSuccess("鎻愪氦鎴愬姛") + closeModelDia() + getModelList() + }) + } + }) +} +// 鍏抽棴浜у搧寮规 +const closeModelDia = () => { + proxy.$refs.modelFormRef.resetFields(); + modelDia.value = false; +} +// 琛ㄦ牸閫夋嫨鏁版嵁 +const handleSelectionChange = (selection) => { + selectedRows.value = selection +} + +// 鏌ヨ瑙勬牸鍨嬪彿 +const pagination = ({ current, limit }) => { + page.current = current; + page.size = limit; + getModelList() +} +const getModelList = () => { + tableLoading.value = true + modelList({id: currentId.value}).then(res => { + tableLoading.value = false + tableData.value = res + }) +} +// 鍒犻櫎瑙勬牸鍨嬪彿 +const handleDelete = () => { + let ids = [] + if (selectedRows.value.length > 0) { + ids = selectedRows.value.map(item => item.id); + } else { + proxy.$modal.msgWarning('璇烽�夋嫨鏁版嵁') + return + } + ElMessageBox.confirm( + '閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�', + '鍒犻櫎鎻愮ず', { + confirmButtonText: '纭', + cancelButtonText: '鍙栨秷', + type: 'warning', + } + ).then(() => { + tableLoading.value = true + delProductModel(ids).then(res => { + proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛") + getModelList() + }).finally(() => { + tableLoading.value = false + }) + }).catch(() => { + proxy.$modal.msg("宸插彇娑�") + }) +} +// 璋冪敤tree杩囨护鏂规硶 涓枃鑻辫繃婊� +const filterNode = (value, data, node) => { + if (!value) {銆�銆�銆�銆�//濡傛灉鏁版嵁涓虹┖锛屽垯杩斿洖true,鏄剧ず鎵�鏈夌殑鏁版嵁椤� + return true + } + // 鏌ヨ鍒楄〃鏄惁鏈夊尮閰嶆暟鎹紝灏嗗�煎皬鍐欙紝鍖归厤鑻辨枃鏁版嵁 + let val = value.toLowerCase() + return chooseNode(val, data, node) // 璋冪敤杩囨护浜屽眰鏂规硶 +} +// 杩囨护鐖惰妭鐐� / 瀛愯妭鐐� (濡傛灉杈撳叆鐨勫弬鏁版槸鐖惰妭鐐逛笖鑳藉尮閰嶏紝鍒欒繑鍥炶鑺傜偣浠ュ強鍏朵笅鐨勬墍鏈夊瓙鑺傜偣锛涘鏋滃弬鏁版槸瀛愯妭鐐癸紝鍒欒繑鍥炶鑺傜偣鐨勭埗鑺傜偣銆俷ame鏄腑鏂囧瓧绗︼紝enName鏄嫳鏂囧瓧绗�. +const chooseNode = (value, data, node) => { + if (data.label.indexOf(value) !== -1) { + return true + } + const level = node.level + // 濡傛灉浼犲叆鐨勮妭鐐规湰韬氨鏄竴绾ц妭鐐瑰氨涓嶇敤鏍¢獙浜� + if (level === 1) { + return false + } + // 鍏堝彇褰撳墠鑺傜偣鐨勭埗鑺傜偣 + let parentData = node.parent + // 閬嶅巻褰撳墠鑺傜偣鐨勭埗鑺傜偣 + let index = 0 + while (index < level - 1) { + // 濡傛灉鍖归厤鍒扮洿鎺ヨ繑鍥烇紝姝ゅname鍊兼槸涓枃瀛楃锛宔nName鏄嫳鏂囧瓧绗︺�傚垽鏂尮閰嶄腑鑻辨枃杩囨护 + if (parentData.data.label.indexOf(value) !== -1) { + return true + } + // 鍚﹀垯鐨勮瘽鍐嶅線涓婁竴灞傚仛鍖归厤 + parentData = parentData.parent + index++ + } + // 娌″尮閰嶅埌杩斿洖false + return false +} +getProductTreeList() +</script> + +<style scoped> +.product-view { + display: flex; +} +.left { + width: 380px; + padding: 16px; + background: #ffffff; +} +.right { + width: calc(100% - 380px); + padding: 16px; + margin-left: 20px; + background: #ffffff; +} +.custom-tree-node { + flex: 1; + display: flex; + align-items: center; + justify-content: space-between; + font-size: 14px; + padding-right: 8px; +} +</style> \ No newline at end of file -- Gitblit v1.9.3