Просмотр исходного кода

Merge branch '解决空数据问题' into 侧边栏修改

xiaohaizhao 3 недель назад
Родитель
Сommit
4b77d54c1e
3 измененных файлов с 724 добавлено и 18 удалено
  1. 282 16
      package-lock.json
  2. 221 1
      src/MAR/assetsStore/index.vue
  3. 221 1
      src/MAR/productManage/index.vue

+ 282 - 16
package-lock.json

@@ -22,7 +22,9 @@
         "nprogress": "^0.2.0",
         "pinia": "^2.0.33",
         "pinia-plugin-persist": "^1.0.0",
+        "sortablejs": "^1.15.7",
         "vue": "^3.2.45",
+        "vue-draggable-plus": "^0.6.1",
         "vue-router": "^4.1.6"
       },
       "devDependencies": {
@@ -872,6 +874,12 @@
       "dev": true,
       "peer": true
     },
+    "node_modules/@types/sortablejs": {
+      "version": "1.15.9",
+      "resolved": "https://registry.npmjs.org/@types/sortablejs/-/sortablejs-1.15.9.tgz",
+      "integrity": "sha512-7HP+rZGE2p886PKV9c9OJzLBI6BBJu1O7lJGYnPyG3fS4/duUCcngkNCjsLwIMV+WMqANe3tt4irrXHSIe68OQ==",
+      "license": "MIT"
+    },
     "node_modules/@uppy/companion-client": {
       "version": "2.2.2",
       "resolved": "https://registry.npmjs.org/@uppy/companion-client/-/companion-client-2.2.2.tgz",
@@ -2469,7 +2477,8 @@
     "node_modules/graceful-fs": {
       "version": "4.2.11",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
-      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
+      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+      "devOptional": true
     },
     "node_modules/has": {
       "version": "1.0.3",
@@ -2505,6 +2514,8 @@
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
       "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "dev": true,
+      "peer": true,
       "engines": {
         "node": ">=8"
       }
@@ -2892,7 +2903,9 @@
     "node_modules/json-parse-even-better-errors": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
-      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
+      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+      "dev": true,
+      "peer": true
     },
     "node_modules/json-schema-traverse": {
       "version": "0.4.1",
@@ -3170,7 +3183,8 @@
     "node_modules/ms": {
       "version": "2.1.3",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+      "optional": true
     },
     "node_modules/namespace-emitter": {
       "version": "2.0.1",
@@ -3415,6 +3429,20 @@
         "url": "https://github.com/chalk/ansi-regex?sponsor=1"
       }
     },
+    "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "inBundle": true,
+      "license": "MIT",
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
     "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": {
       "version": "9.2.2",
       "inBundle": true,
@@ -3436,6 +3464,44 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width-cjs": {
+      "name": "string-width",
+      "version": "4.2.3",
+      "inBundle": true,
+      "license": "MIT",
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width-cjs/node_modules/ansi-regex": {
+      "version": "5.0.1",
+      "inBundle": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width-cjs/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "inBundle": true,
+      "license": "MIT"
+    },
+    "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width-cjs/node_modules/strip-ansi": {
+      "version": "6.0.1",
+      "inBundle": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": {
       "version": "7.1.0",
       "inBundle": true,
@@ -3450,6 +3516,80 @@
         "url": "https://github.com/chalk/strip-ansi?sponsor=1"
       }
     },
+    "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi-cjs": {
+      "name": "strip-ansi",
+      "version": "6.0.1",
+      "inBundle": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
+      "version": "5.0.1",
+      "inBundle": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/npm/node_modules/@isaacs/cliui/node_modules/wrap-ansi-cjs": {
+      "name": "wrap-ansi",
+      "version": "7.0.0",
+      "inBundle": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+      }
+    },
+    "node_modules/npm/node_modules/@isaacs/cliui/node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
+      "version": "5.0.1",
+      "inBundle": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/npm/node_modules/@isaacs/cliui/node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "inBundle": true,
+      "license": "MIT"
+    },
+    "node_modules/npm/node_modules/@isaacs/cliui/node_modules/wrap-ansi-cjs/node_modules/string-width": {
+      "version": "4.2.3",
+      "inBundle": true,
+      "license": "MIT",
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/npm/node_modules/@isaacs/cliui/node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
+      "version": "6.0.1",
+      "inBundle": true,
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/npm/node_modules/@isaacs/string-locale-compare": {
       "version": "1.1.0",
       "inBundle": true,
@@ -5318,7 +5458,6 @@
     "node_modules/npm/node_modules/string-width-cjs": {
       "name": "string-width",
       "version": "4.2.3",
-      "inBundle": true,
       "license": "MIT",
       "dependencies": {
         "emoji-regex": "^8.0.0",
@@ -5343,7 +5482,6 @@
     "node_modules/npm/node_modules/strip-ansi-cjs": {
       "name": "strip-ansi",
       "version": "6.0.1",
-      "inBundle": true,
       "license": "MIT",
       "dependencies": {
         "ansi-regex": "^5.0.1"
@@ -5539,7 +5677,6 @@
     "node_modules/npm/node_modules/wrap-ansi-cjs": {
       "name": "wrap-ansi",
       "version": "7.0.0",
-      "inBundle": true,
       "license": "MIT",
       "dependencies": {
         "ansi-styles": "^4.0.0",
@@ -5555,7 +5692,6 @@
     },
     "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
       "version": "4.3.0",
-      "inBundle": true,
       "license": "MIT",
       "dependencies": {
         "color-convert": "^2.0.1"
@@ -6042,6 +6178,7 @@
       "version": "5.7.1",
       "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
       "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "optional": true,
       "bin": {
         "semver": "bin/semver"
       }
@@ -6124,6 +6261,12 @@
         "node": ">=8.3.0"
       }
     },
+    "node_modules/sortablejs": {
+      "version": "1.15.7",
+      "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.7.tgz",
+      "integrity": "sha512-Kk8wLQPlS+yi1ZEf48a4+fzHa4yxjC30M/Sr2AnQu+f/MPwvvX9XjZ6OWejiz8crBsLwSq8GHqaxaET7u6ux0A==",
+      "license": "MIT"
+    },
     "node_modules/source-map": {
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -6224,6 +6367,8 @@
       "version": "8.1.1",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
       "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+      "dev": true,
+      "peer": true,
       "dependencies": {
         "has-flag": "^4.0.0"
       },
@@ -6564,6 +6709,23 @@
         }
       }
     },
+    "node_modules/vue-draggable-plus": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/vue-draggable-plus/-/vue-draggable-plus-0.6.1.tgz",
+      "integrity": "sha512-FbtQ/fuoixiOfTZzG3yoPl4JAo9HJXRHmBQZFB9x2NYCh6pq0TomHf7g5MUmpaDYv+LU2n6BPq2YN9sBO+FbIg==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/sortablejs": "^1.15.8"
+      },
+      "peerDependencies": {
+        "@types/sortablejs": "^1.15.0"
+      },
+      "peerDependenciesMeta": {
+        "@vue/composition-api": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/vue-router": {
       "version": "4.1.6",
       "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.1.6.tgz",
@@ -7384,6 +7546,11 @@
       "dev": true,
       "peer": true
     },
+    "@types/sortablejs": {
+      "version": "1.15.9",
+      "resolved": "https://registry.npmjs.org/@types/sortablejs/-/sortablejs-1.15.9.tgz",
+      "integrity": "sha512-7HP+rZGE2p886PKV9c9OJzLBI6BBJu1O7lJGYnPyG3fS4/duUCcngkNCjsLwIMV+WMqANe3tt4irrXHSIe68OQ=="
+    },
     "@uppy/companion-client": {
       "version": "2.2.2",
       "resolved": "https://registry.npmjs.org/@uppy/companion-client/-/companion-client-2.2.2.tgz",
@@ -8655,7 +8822,8 @@
     "graceful-fs": {
       "version": "4.2.11",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
-      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
+      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+      "devOptional": true
     },
     "has": {
       "version": "1.0.3",
@@ -8681,7 +8849,9 @@
     "has-flag": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "dev": true,
+      "peer": true
     },
     "has-property-descriptors": {
       "version": "1.0.0",
@@ -8944,7 +9114,9 @@
     "json-parse-even-better-errors": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
-      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
+      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+      "dev": true,
+      "peer": true
     },
     "json-schema-traverse": {
       "version": "0.4.1",
@@ -9155,7 +9327,8 @@
     "ms": {
       "version": "2.1.3",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+      "optional": true
     },
     "namespace-emitter": {
       "version": "2.0.1",
@@ -9293,6 +9466,13 @@
               "version": "6.0.1",
               "bundled": true
             },
+            "ansi-styles": {
+              "version": "4.3.0",
+              "bundled": true,
+              "requires": {
+                "color-convert": "^2.0.1"
+              }
+            },
             "emoji-regex": {
               "version": "9.2.2",
               "bundled": true
@@ -9306,12 +9486,86 @@
                 "strip-ansi": "^7.0.1"
               }
             },
+            "string-width-cjs": {
+              "version": "npm:string-width@4.2.3",
+              "bundled": true,
+              "requires": {
+                "emoji-regex": "^8.0.0",
+                "is-fullwidth-code-point": "^3.0.0",
+                "strip-ansi": "^6.0.1"
+              },
+              "dependencies": {
+                "ansi-regex": {
+                  "version": "5.0.1",
+                  "bundled": true
+                },
+                "emoji-regex": {
+                  "version": "8.0.0",
+                  "bundled": true
+                },
+                "strip-ansi": {
+                  "version": "6.0.1",
+                  "bundled": true,
+                  "requires": {
+                    "ansi-regex": "^5.0.1"
+                  }
+                }
+              }
+            },
             "strip-ansi": {
               "version": "7.1.0",
               "bundled": true,
               "requires": {
                 "ansi-regex": "^6.0.1"
               }
+            },
+            "strip-ansi-cjs": {
+              "version": "npm:strip-ansi@6.0.1",
+              "bundled": true,
+              "requires": {
+                "ansi-regex": "^5.0.1"
+              },
+              "dependencies": {
+                "ansi-regex": {
+                  "version": "5.0.1",
+                  "bundled": true
+                }
+              }
+            },
+            "wrap-ansi-cjs": {
+              "version": "npm:wrap-ansi@7.0.0",
+              "bundled": true,
+              "requires": {
+                "ansi-styles": "^4.0.0",
+                "string-width": "^4.1.0",
+                "strip-ansi": "^6.0.0"
+              },
+              "dependencies": {
+                "ansi-regex": {
+                  "version": "5.0.1",
+                  "bundled": true
+                },
+                "emoji-regex": {
+                  "version": "8.0.0",
+                  "bundled": true
+                },
+                "string-width": {
+                  "version": "4.2.3",
+                  "bundled": true,
+                  "requires": {
+                    "emoji-regex": "^8.0.0",
+                    "is-fullwidth-code-point": "^3.0.0",
+                    "strip-ansi": "^6.0.1"
+                  }
+                },
+                "strip-ansi": {
+                  "version": "6.0.1",
+                  "bundled": true,
+                  "requires": {
+                    "ansi-regex": "^5.0.1"
+                  }
+                }
+              }
             }
           }
         },
@@ -10531,7 +10785,6 @@
         },
         "string-width-cjs": {
           "version": "npm:string-width@4.2.3",
-          "bundled": true,
           "requires": {
             "emoji-regex": "^8.0.0",
             "is-fullwidth-code-point": "^3.0.0",
@@ -10547,7 +10800,6 @@
         },
         "strip-ansi-cjs": {
           "version": "npm:strip-ansi@6.0.1",
-          "bundled": true,
           "requires": {
             "ansi-regex": "^5.0.1"
           }
@@ -10705,7 +10957,6 @@
         },
         "wrap-ansi-cjs": {
           "version": "npm:wrap-ansi@7.0.0",
-          "bundled": true,
           "requires": {
             "ansi-styles": "^4.0.0",
             "string-width": "^4.1.0",
@@ -10714,7 +10965,6 @@
           "dependencies": {
             "ansi-styles": {
               "version": "4.3.0",
-              "bundled": true,
               "requires": {
                 "color-convert": "^2.0.1"
               }
@@ -11004,7 +11254,8 @@
     "semver": {
       "version": "5.7.1",
       "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+      "optional": true
     },
     "serialize-javascript": {
       "version": "6.0.1",
@@ -11073,6 +11324,11 @@
       "resolved": "https://registry.npmjs.org/snabbdom/-/snabbdom-3.5.1.tgz",
       "integrity": "sha512-wHMNIOjkm/YNE5EM3RCbr/+DVgPg6AqQAX1eOxO46zYNvCXjKP5Y865tqQj3EXnaMBjkxmQA5jFuDpDK/dbfiA=="
     },
+    "sortablejs": {
+      "version": "1.15.7",
+      "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.7.tgz",
+      "integrity": "sha512-Kk8wLQPlS+yi1ZEf48a4+fzHa4yxjC30M/Sr2AnQu+f/MPwvvX9XjZ6OWejiz8crBsLwSq8GHqaxaET7u6ux0A=="
+    },
     "source-map": {
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -11151,6 +11407,8 @@
       "version": "8.1.1",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
       "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+      "dev": true,
+      "peer": true,
       "requires": {
         "has-flag": "^4.0.0"
       }
@@ -11347,6 +11605,14 @@
       "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
       "requires": {}
     },
+    "vue-draggable-plus": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/vue-draggable-plus/-/vue-draggable-plus-0.6.1.tgz",
+      "integrity": "sha512-FbtQ/fuoixiOfTZzG3yoPl4JAo9HJXRHmBQZFB9x2NYCh6pq0TomHf7g5MUmpaDYv+LU2n6BPq2YN9sBO+FbIg==",
+      "requires": {
+        "@types/sortablejs": "^1.15.8"
+      }
+    },
     "vue-router": {
       "version": "4.1.6",
       "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.1.6.tgz",

+ 221 - 1
src/MAR/assetsStore/index.vue

@@ -8,7 +8,7 @@
       </div>
       <a-tree :tree-data="classList" :field-names="treeFieldNames" :selected-keys="selectedClassKeys"
         :expanded-keys="expandedKeys" :expand-action="false" :autoExpandParent="true" @select="onClassSelect"
-        @expand="onTreeExpand" class="custom-tree">
+        @expand="onTreeExpand" class="custom-tree" draggable @dragenter="onDragEnter" @drop="onDrop">
         <template #title="node">
           <div class="tree-node-content">
             <span class="node-title" :class="{ 'disabled-class': node.isenable === 0 }">{{ node.classname }}{{
@@ -418,6 +418,18 @@ const getClassList = async () => {
       }
     }
   })
+  
+  // 为每个节点添加层级字段
+  const addLevelToNodes = (nodes, level = 1) => {
+    nodes.forEach(node => {
+      node.level = level
+      if (node.children && node.children.length > 0) {
+        addLevelToNodes(node.children, level + 1)
+      }
+    })
+  }
+  
+  addLevelToNodes(res.data)
   classList.value = res.data
 
   // 获取所有节点的key用于默认展开(只展开一级分类)
@@ -444,6 +456,214 @@ const onTreeExpand = (expandedKeysArray) => {
   expandedKeys.value = expandedKeysArray
 }
 
+// 拖动进入事件处理
+const onDragEnter = (info) => {
+  console.log('拖动进入:', info)
+  // 可以在这里处理展开节点等逻辑
+}
+
+// 拖动放置事件处理
+const onDrop = (info) => {
+  console.log('放置:', info)
+  const dropKey = info.node.key
+  const dragKey = info.dragNode.key
+  const dropPos = info.node.pos.split('-')
+  const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]) // the drop position relative to the drop node, inside 0, top -1, bottom 1
+
+  const loop = (data, key, callback) => {
+    for (let i = 0; i < data.length; i++) {
+      if (data[i].sat_sharematerial_classid === key) {
+        return callback(data[i], i, data)
+      }
+      if (data[i].children) {
+        loop(data[i].children, key, callback)
+      }
+    }
+  }
+  const data = JSON.parse(JSON.stringify(classList.value))
+
+  // Find dragObject and its original position
+  let dragObj
+  let originalParentArr
+  let originalIndex
+  
+  loop(data, dragKey, (item, index, arr) => {
+    originalParentArr = arr
+    originalIndex = index
+    dragObj = item
+  })
+
+  // 层级检查和处理
+  let isValidDrop = true
+  let dropSuccess = false
+  
+  // 先从数据中移除拖动的节点
+  if (originalParentArr && originalIndex !== undefined) {
+    originalParentArr.splice(originalIndex, 1)
+  }
+
+  if (!info.dropToGap) {
+    // Drop on the content (as child)
+    loop(data, dropKey, (item) => {
+      // 检查拖动节点的层级是否比目标节点低一级
+      if (dragObj.level !== item.level + 1) {
+        // 特殊处理:一级分类拖到二级分类上
+        if (dragObj.level === 1 && item.level === 2) {
+          // 找到二级分类的父级一级分类
+          let parentNode
+          let parentArr
+          let parentIndex
+          
+          // 查找父级一级分类
+          const findParent = (nodes) => {
+            for (let i = 0; i < nodes.length; i++) {
+              if (nodes[i].children) {
+                for (let j = 0; j < nodes[i].children.length; j++) {
+                  if (nodes[i].children[j].sat_sharematerial_classid === item.sat_sharematerial_classid) {
+                    parentNode = nodes[i]
+                    parentArr = nodes
+                    parentIndex = i
+                    return true
+                  }
+                }
+                if (findParent(nodes[i].children)) {
+                  return true
+                }
+              }
+            }
+            return false
+          }
+          
+          findParent(data)
+          
+          if (parentArr && parentIndex !== undefined) {
+            // 将一级分类插入到父级一级分类的后面
+            parentArr.splice(parentIndex + 1, 0, dragObj)
+            dropSuccess = true
+          }
+        } else {
+          isValidDrop = false
+          utils.message({ msg: '失败' }, '分类层级不能变更', 'error')
+        }
+      } else {
+        item.children = item.children || []
+        // where to insert. New item was inserted to the start of the array in this example, but can be anywhere
+        item.children.unshift(dragObj)
+        dropSuccess = true
+      }
+    })
+  } else {
+    let ar = []
+    let i
+    let targetNode
+    loop(data, dropKey, (item, index, arr) => {
+      ar = arr
+      i = index
+      targetNode = item
+    })
+    
+    // 检查拖动节点的层级是否与目标节点相同
+    if (dragObj.level !== targetNode.level) {
+      // 特殊处理:一级分类拖到二级分类间隙
+      if (dragObj.level === 1 && targetNode.level === 2) {
+        // 找到二级分类的父级一级分类
+        let parentNode
+        let parentArr
+        let parentIndex
+        
+        // 查找父级一级分类
+        const findParent = (nodes) => {
+          for (let i = 0; i < nodes.length; i++) {
+            if (nodes[i].children) {
+              for (let j = 0; j < nodes[i].children.length; j++) {
+                if (nodes[i].children[j].sat_sharematerial_classid === targetNode.sat_sharematerial_classid) {
+                  parentNode = nodes[i]
+                  parentArr = nodes
+                  parentIndex = i
+                  return true
+                }
+              }
+              if (findParent(nodes[i].children)) {
+                return true
+              }
+            }
+          }
+          return false
+        }
+        
+        findParent(data)
+        
+        if (parentArr && parentIndex !== undefined) {
+          // 将一级分类插入到父级一级分类的后面
+          parentArr.splice(parentIndex + 1, 0, dragObj)
+          dropSuccess = true
+        }
+      } else {
+        isValidDrop = false
+        utils.message({ msg: '失败' }, '分类层级不能变更', 'error')
+      }
+    } else {
+      if (dropPosition === -1) {
+        // Drop on the top of the drop node
+        ar.splice(i, 0, dragObj)
+      } else {
+        // Drop on the bottom of the drop node
+        ar.splice(i + 1, 0, dragObj)
+      }
+      dropSuccess = true
+    }
+  }
+  
+  // 如果放置失败,将节点放回原来的位置
+  if (!dropSuccess && originalParentArr && originalIndex !== undefined) {
+    originalParentArr.splice(originalIndex, 0, dragObj)
+  }
+  
+  // 更新分类列表
+  classList.value = data
+  
+  // 只有放置成功才保存分类结构
+  if (dropSuccess) {
+    // 保存拖动后的分类结构
+    saveClassStructure(data)
+  }
+}
+
+// 保存分类结构
+const saveClassStructure = async (data) => {
+  // 构建分类结构数据
+  const buildStructure = (nodes, parentid = 0) => {
+    const result = []
+    nodes.forEach((node, index) => {
+      result.push({
+        sat_sharematerial_classid: node.sat_sharematerial_classid,
+        parentid: parentid,
+        sequence: index + 1
+      })
+      if (node.children && node.children.length > 0) {
+        result.push(...buildStructure(node.children, node.sat_sharematerial_classid))
+      }
+    })
+    return result
+  }
+  
+  const structureData = buildStructure(data)
+  
+  try {
+    const res = await Api.requested({
+      "id": "20240403153602",
+      "content": {
+        "classStructure": structureData
+      }
+    })
+    if (res.msg === '成功') {
+      utils.message(res, '分类排序更新成功')
+    }
+  } catch (error) {
+    console.error('保存分类结构失败:', error)
+  }
+}
+
 onMounted(() => {
   getClassList()
 })

+ 221 - 1
src/MAR/productManage/index.vue

@@ -8,7 +8,7 @@
       </div>
       <a-tree :tree-data="classList" :field-names="treeFieldNames" :selected-keys="selectedClassKeys"
         :expanded-keys="expandedKeys" :expand-action="false" :autoExpandParent="true" @select="onClassSelect"
-        @expand="onTreeExpand" class="custom-tree">
+        @expand="onTreeExpand" class="custom-tree" draggable @dragenter="onDragEnter" @drop="onDrop">
         <template #title="node">
           <div class="tree-node-content" :style="{ width: 240 - node.level * 21 + 'px' }">
             <!-- 每少一级别,宽度减少21px -->
@@ -436,6 +436,18 @@ const getClassList = async () => {
       }
     }
   })
+  
+  // 为每个节点添加层级字段
+  const addLevelToNodes = (nodes, level = 1) => {
+    nodes.forEach(node => {
+      node.level = level
+      if (node.children && node.children.length > 0) {
+        addLevelToNodes(node.children, level + 1)
+      }
+    })
+  }
+  
+  addLevelToNodes(res.data)
   classList.value = res.data
 
   // 获取所有节点的key用于默认展开(只展开一级分类)
@@ -462,6 +474,214 @@ const onTreeExpand = (expandedKeysArray) => {
   expandedKeys.value = expandedKeysArray
 }
 
+// 拖动进入事件处理
+const onDragEnter = (info) => {
+  console.log('拖动进入:', info)
+  // 可以在这里处理展开节点等逻辑
+}
+
+// 拖动放置事件处理
+const onDrop = (info) => {
+  console.log('放置:', info)
+  const dropKey = info.node.key
+  const dragKey = info.dragNode.key
+  const dropPos = info.node.pos.split('-')
+  const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]) // the drop position relative to the drop node, inside 0, top -1, bottom 1
+
+  const loop = (data, key, callback) => {
+    for (let i = 0; i < data.length; i++) {
+      if (data[i].sa_fadclassid === key) {
+        return callback(data[i], i, data)
+      }
+      if (data[i].children) {
+        loop(data[i].children, key, callback)
+      }
+    }
+  }
+  const data = JSON.parse(JSON.stringify(classList.value))
+
+  // Find dragObject and its original position
+  let dragObj
+  let originalParentArr
+  let originalIndex
+  
+  loop(data, dragKey, (item, index, arr) => {
+    originalParentArr = arr
+    originalIndex = index
+    dragObj = item
+  })
+
+  // 层级检查和处理
+  let isValidDrop = true
+  let dropSuccess = false
+  
+  // 先从数据中移除拖动的节点
+  if (originalParentArr && originalIndex !== undefined) {
+    originalParentArr.splice(originalIndex, 1)
+  }
+
+  if (!info.dropToGap) {
+    // Drop on the content (as child)
+    loop(data, dropKey, (item) => {
+      // 检查拖动节点的层级是否比目标节点低一级
+      if (dragObj.level !== item.level + 1) {
+        // 特殊处理:一级分类拖到二级分类上
+        if (dragObj.level === 1 && item.level === 2) {
+          // 找到二级分类的父级一级分类
+          let parentNode
+          let parentArr
+          let parentIndex
+          
+          // 查找父级一级分类
+          const findParent = (nodes) => {
+            for (let i = 0; i < nodes.length; i++) {
+              if (nodes[i].children) {
+                for (let j = 0; j < nodes[i].children.length; j++) {
+                  if (nodes[i].children[j].sa_fadclassid === item.sa_fadclassid) {
+                    parentNode = nodes[i]
+                    parentArr = nodes
+                    parentIndex = i
+                    return true
+                  }
+                }
+                if (findParent(nodes[i].children)) {
+                  return true
+                }
+              }
+            }
+            return false
+          }
+          
+          findParent(data)
+          
+          if (parentArr && parentIndex !== undefined) {
+            // 将一级分类插入到父级一级分类的后面
+            parentArr.splice(parentIndex + 1, 0, dragObj)
+            dropSuccess = true
+          }
+        } else {
+          isValidDrop = false
+          utils.message({ msg: '失败' }, '分类层级不能变更', 'error')
+        }
+      } else {
+        item.children = item.children || []
+        // where to insert. New item was inserted to the start of the array in this example, but can be anywhere
+        item.children.unshift(dragObj)
+        dropSuccess = true
+      }
+    })
+  } else {
+    let ar = []
+    let i
+    let targetNode
+    loop(data, dropKey, (item, index, arr) => {
+      ar = arr
+      i = index
+      targetNode = item
+    })
+    
+    // 检查拖动节点的层级是否与目标节点相同
+    if (dragObj.level !== targetNode.level) {
+      // 特殊处理:一级分类拖到二级分类间隙
+      if (dragObj.level === 1 && targetNode.level === 2) {
+        // 找到二级分类的父级一级分类
+        let parentNode
+        let parentArr
+        let parentIndex
+        
+        // 查找父级一级分类
+        const findParent = (nodes) => {
+          for (let i = 0; i < nodes.length; i++) {
+            if (nodes[i].children) {
+              for (let j = 0; j < nodes[i].children.length; j++) {
+                if (nodes[i].children[j].sa_fadclassid === targetNode.sa_fadclassid) {
+                  parentNode = nodes[i]
+                  parentArr = nodes
+                  parentIndex = i
+                  return true
+                }
+              }
+              if (findParent(nodes[i].children)) {
+                return true
+              }
+            }
+          }
+          return false
+        }
+        
+        findParent(data)
+        
+        if (parentArr && parentIndex !== undefined) {
+          // 将一级分类插入到父级一级分类的后面
+          parentArr.splice(parentIndex + 1, 0, dragObj)
+          dropSuccess = true
+        }
+      } else {
+        isValidDrop = false
+        utils.message({ msg: '失败' }, '分类层级不能变更', 'error')
+      }
+    } else {
+      if (dropPosition === -1) {
+        // Drop on the top of the drop node
+        ar.splice(i, 0, dragObj)
+      } else {
+        // Drop on the bottom of the drop node
+        ar.splice(i + 1, 0, dragObj)
+      }
+      dropSuccess = true
+    }
+  }
+  
+  // 如果放置失败,将节点放回原来的位置
+  if (!dropSuccess && originalParentArr && originalIndex !== undefined) {
+    originalParentArr.splice(originalIndex, 0, dragObj)
+  }
+  
+  // 更新分类列表
+  classList.value = data
+  
+  // 只有放置成功才保存分类结构
+  if (dropSuccess) {
+    // 保存拖动后的分类结构
+    saveClassStructure(data)
+  }
+}
+
+// 保存分类结构
+const saveClassStructure = async (data) => {
+  // 构建分类结构数据
+  const buildStructure = (nodes, parentid = 0) => {
+    const result = []
+    nodes.forEach((node, index) => {
+      result.push({
+        sa_fadclassid: node.sa_fadclassid,
+        parentid: parentid,
+        sequence: index + 1
+      })
+      if (node.children && node.children.length > 0) {
+        result.push(...buildStructure(node.children, node.sa_fadclassid))
+      }
+    })
+    return result
+  }
+  
+  const structureData = buildStructure(data)
+  
+  try {
+    const res = await Api.requested({
+      "id": "20240418112102",
+      "content": {
+        "classStructure": structureData
+      }
+    })
+    if (res.msg === '成功') {
+      utils.message(res, '分类排序更新成功')
+    }
+  } catch (error) {
+    console.error('保存分类结构失败:', error)
+  }
+}
+
 onMounted(() => {
   getClassList()
 })