update
This commit is contained in:
parent
20f94f9618
commit
9610f41e92
712
package-lock.json
generated
712
package-lock.json
generated
@ -12,6 +12,7 @@
|
||||
"@vue/cli-service": "^5.0.8",
|
||||
"ant-design-vue": "^3.2.20",
|
||||
"axios": "^1.7.9",
|
||||
"md-editor-v3": "^4.8.3",
|
||||
"nprogress": "^0.2.0",
|
||||
"qrcode.vue": "^3.6.0",
|
||||
"vue": "^3.3.4",
|
||||
@ -178,6 +179,360 @@
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/autocomplete": {
|
||||
"version": "6.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.6.tgz",
|
||||
"integrity": "sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==",
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.17.0",
|
||||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/commands": {
|
||||
"version": "6.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.8.0.tgz",
|
||||
"integrity": "sha512-q8VPEFaEP4ikSlt6ZxjB3zW72+7osfAYW9i8Zu943uqbKuz6utc1+F170hyLUCUltXORjQXRyYQNfkckzA/bPQ==",
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.4.0",
|
||||
"@codemirror/view": "^6.27.0",
|
||||
"@lezer/common": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-angular": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-angular/-/lang-angular-0.1.3.tgz",
|
||||
"integrity": "sha512-xgeWGJQQl1LyStvndWtruUvb4SnBZDAu/gvFH/ZU+c0W25tQR8e5hq7WTwiIY2dNxnf+49mRiGI/9yxIwB6f5w==",
|
||||
"dependencies": {
|
||||
"@codemirror/lang-html": "^6.0.0",
|
||||
"@codemirror/lang-javascript": "^6.1.2",
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.3.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-cpp": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-cpp/-/lang-cpp-6.0.2.tgz",
|
||||
"integrity": "sha512-6oYEYUKHvrnacXxWxYa6t4puTlbN3dgV662BDfSH8+MfjQjVmP697/KYTDOqpxgerkvoNm7q5wlFMBeX8ZMocg==",
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@lezer/cpp": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-css": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.3.1.tgz",
|
||||
"integrity": "sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@lezer/common": "^1.0.2",
|
||||
"@lezer/css": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-go": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-go/-/lang-go-6.0.1.tgz",
|
||||
"integrity": "sha512-7fNvbyNylvqCphW9HD6WFnRpcDjr+KXX/FgqXy5H5ZS0eC5edDljukm/yNgYkwTsgp2busdod50AOTIy6Jikfg==",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/language": "^6.6.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@lezer/common": "^1.0.0",
|
||||
"@lezer/go": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-html": {
|
||||
"version": "6.4.9",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.9.tgz",
|
||||
"integrity": "sha512-aQv37pIMSlueybId/2PVSP6NPnmurFDVmZwzc7jszd2KAF8qd4VBbvNYPXWQq90WIARjsdVkPbw29pszmHws3Q==",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/lang-css": "^6.0.0",
|
||||
"@codemirror/lang-javascript": "^6.0.0",
|
||||
"@codemirror/language": "^6.4.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.17.0",
|
||||
"@lezer/common": "^1.0.0",
|
||||
"@lezer/css": "^1.1.0",
|
||||
"@lezer/html": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-java": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-java/-/lang-java-6.0.1.tgz",
|
||||
"integrity": "sha512-OOnmhH67h97jHzCuFaIEspbmsT98fNdhVhmA3zCxW0cn7l8rChDhZtwiwJ/JOKXgfm4J+ELxQihxaI7bj7mJRg==",
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@lezer/java": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-javascript": {
|
||||
"version": "6.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.3.tgz",
|
||||
"integrity": "sha512-8PR3vIWg7pSu7ur8A07pGiYHgy3hHj+mRYRCSG8q+mPIrl0F02rgpGv+DsQTHRTc30rydOsf5PZ7yjKFg2Ackw==",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/language": "^6.6.0",
|
||||
"@codemirror/lint": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.17.0",
|
||||
"@lezer/common": "^1.0.0",
|
||||
"@lezer/javascript": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-json": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.1.tgz",
|
||||
"integrity": "sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==",
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@lezer/json": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-less": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-less/-/lang-less-6.0.2.tgz",
|
||||
"integrity": "sha512-EYdQTG22V+KUUk8Qq582g7FMnCZeEHsyuOJisHRft/mQ+ZSZ2w51NupvDUHiqtsOy7It5cHLPGfHQLpMh9bqpQ==",
|
||||
"dependencies": {
|
||||
"@codemirror/lang-css": "^6.2.0",
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-liquid": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-liquid/-/lang-liquid-6.2.2.tgz",
|
||||
"integrity": "sha512-7Dm841fk37+JQW6j2rI1/uGkJyESrjzyhiIkaLjbbR0U6aFFQvMrJn35WxQreRMADMhzkyVkZM4467OR7GR8nQ==",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/lang-html": "^6.0.0",
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"@lezer/common": "^1.0.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-markdown": {
|
||||
"version": "6.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.3.2.tgz",
|
||||
"integrity": "sha512-c/5MYinGbFxYl4itE9q/rgN/sMTjOr8XL5OWnC+EaRMLfCbVUmmubTJfdgpfcSS2SCaT7b+Q+xi3l6CgoE+BsA==",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.7.1",
|
||||
"@codemirror/lang-html": "^6.0.0",
|
||||
"@codemirror/language": "^6.3.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"@lezer/common": "^1.2.1",
|
||||
"@lezer/markdown": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-php": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-php/-/lang-php-6.0.1.tgz",
|
||||
"integrity": "sha512-ublojMdw/PNWa7qdN5TMsjmqkNuTBD3k6ndZ4Z0S25SBAiweFGyY68AS3xNcIOlb6DDFDvKlinLQ40vSLqf8xA==",
|
||||
"dependencies": {
|
||||
"@codemirror/lang-html": "^6.0.0",
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@lezer/common": "^1.0.0",
|
||||
"@lezer/php": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-python": {
|
||||
"version": "6.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.1.7.tgz",
|
||||
"integrity": "sha512-mZnFTsL4lW5p9ch8uKNKeRU3xGGxr1QpESLilfON2E3fQzOa/OygEMkaDvERvXDJWJA9U9oN/D4w0ZuUzNO4+g==",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.3.2",
|
||||
"@codemirror/language": "^6.8.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@lezer/common": "^1.2.1",
|
||||
"@lezer/python": "^1.1.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-rust": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-rust/-/lang-rust-6.0.1.tgz",
|
||||
"integrity": "sha512-344EMWFBzWArHWdZn/NcgkwMvZIWUR1GEBdwG8FEp++6o6vT6KL9V7vGs2ONsKxxFUPXKI0SPcWhyYyl2zPYxQ==",
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@lezer/rust": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-sass": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-sass/-/lang-sass-6.0.2.tgz",
|
||||
"integrity": "sha512-l/bdzIABvnTo1nzdY6U+kPAC51czYQcOErfzQ9zSm9D8GmNPD0WTW8st/CJwBTPLO8jlrbyvlSEcN20dc4iL0Q==",
|
||||
"dependencies": {
|
||||
"@codemirror/lang-css": "^6.2.0",
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@lezer/common": "^1.0.2",
|
||||
"@lezer/sass": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-sql": {
|
||||
"version": "6.8.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-sql/-/lang-sql-6.8.0.tgz",
|
||||
"integrity": "sha512-aGLmY4OwGqN3TdSx3h6QeA1NrvaYtF7kkoWR/+W7/JzB0gQtJ+VJxewlnE3+VImhA4WVlhmkJr109PefOOhjLg==",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-vue": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-vue/-/lang-vue-0.1.3.tgz",
|
||||
"integrity": "sha512-QSKdtYTDRhEHCfo5zOShzxCmqKJvgGrZwDQSdbvCRJ5pRLWBS7pD/8e/tH44aVQT6FKm0t6RVNoSUWHOI5vNug==",
|
||||
"dependencies": {
|
||||
"@codemirror/lang-html": "^6.0.0",
|
||||
"@codemirror/lang-javascript": "^6.1.2",
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-wast": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-wast/-/lang-wast-6.0.2.tgz",
|
||||
"integrity": "sha512-Imi2KTpVGm7TKuUkqyJ5NRmeFWF7aMpNiwHnLQe0x9kmrxElndyH0K6H/gXtWwY6UshMRAhpENsgfpSwsgmC6Q==",
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-xml": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-xml/-/lang-xml-6.1.0.tgz",
|
||||
"integrity": "sha512-3z0blhicHLfwi2UgkZYRPioSgVTo9PV5GP5ducFH6FaHy0IAJRg+ixj5gTR1gnT/glAIC8xv4w2VL1LoZfs+Jg==",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/language": "^6.4.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"@lezer/common": "^1.0.0",
|
||||
"@lezer/xml": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-yaml": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-yaml/-/lang-yaml-6.1.2.tgz",
|
||||
"integrity": "sha512-dxrfG8w5Ce/QbT7YID7mWZFKhdhsaTNOYjOkSIMt1qmC4VQnXSDSYVHHHn8k6kJUfIhtLo8t1JJgltlxWdsITw==",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.2.0",
|
||||
"@lezer/lr": "^1.0.0",
|
||||
"@lezer/yaml": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/language": {
|
||||
"version": "6.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.0.tgz",
|
||||
"integrity": "sha512-A7+f++LodNNc1wGgoRDTt78cOwWm9KVezApgjOMp1W4hM0898nsqBXwF+sbePE7ZRcjN7Sa1Z5m2oN27XkmEjQ==",
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.23.0",
|
||||
"@lezer/common": "^1.1.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0",
|
||||
"style-mod": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/language-data": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/language-data/-/language-data-6.5.1.tgz",
|
||||
"integrity": "sha512-0sWxeUSNlBr6OmkqybUTImADFUP0M3P0IiSde4nc24bz/6jIYzqYSgkOSLS+CBIoW1vU8Q9KUWXscBXeoMVC9w==",
|
||||
"dependencies": {
|
||||
"@codemirror/lang-angular": "^0.1.0",
|
||||
"@codemirror/lang-cpp": "^6.0.0",
|
||||
"@codemirror/lang-css": "^6.0.0",
|
||||
"@codemirror/lang-go": "^6.0.0",
|
||||
"@codemirror/lang-html": "^6.0.0",
|
||||
"@codemirror/lang-java": "^6.0.0",
|
||||
"@codemirror/lang-javascript": "^6.0.0",
|
||||
"@codemirror/lang-json": "^6.0.0",
|
||||
"@codemirror/lang-less": "^6.0.0",
|
||||
"@codemirror/lang-liquid": "^6.0.0",
|
||||
"@codemirror/lang-markdown": "^6.0.0",
|
||||
"@codemirror/lang-php": "^6.0.0",
|
||||
"@codemirror/lang-python": "^6.0.0",
|
||||
"@codemirror/lang-rust": "^6.0.0",
|
||||
"@codemirror/lang-sass": "^6.0.0",
|
||||
"@codemirror/lang-sql": "^6.0.0",
|
||||
"@codemirror/lang-vue": "^0.1.1",
|
||||
"@codemirror/lang-wast": "^6.0.0",
|
||||
"@codemirror/lang-xml": "^6.0.0",
|
||||
"@codemirror/lang-yaml": "^6.0.0",
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/legacy-modes": "^6.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/legacy-modes": {
|
||||
"version": "6.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/legacy-modes/-/legacy-modes-6.5.0.tgz",
|
||||
"integrity": "sha512-dNw5pwTqtR1giYjaJyEajunLqxGavZqV0XRtVZyMJnNOD2HmK9DMUmuCAr6RMFGRJ4l8OeQDjpI/us+R09mQsw==",
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lint": {
|
||||
"version": "6.8.4",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.4.tgz",
|
||||
"integrity": "sha512-u4q7PnZlJUojeRe8FJa/njJcMctISGgPQ4PnWsd9268R4ZTtU+tfFYmwkBvgcrK2+QQ8tYFVALVb5fVJykKc5A==",
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.35.0",
|
||||
"crelt": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/search": {
|
||||
"version": "6.5.10",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.10.tgz",
|
||||
"integrity": "sha512-RMdPdmsrUf53pb2VwflKGHEe1XVM07hI7vV2ntgw1dmqhimpatSJKva4VA9h4TLUDOD4EIF02201oZurpnEFsg==",
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"crelt": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/state": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz",
|
||||
"integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==",
|
||||
"dependencies": {
|
||||
"@marijn/find-cluster-break": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/view": {
|
||||
"version": "6.36.4",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.36.4.tgz",
|
||||
"integrity": "sha512-ZQ0V5ovw/miKEXTvjgzRyjnrk9TwriUB1k4R5p7uNnHR9Hus+D1SXHGdJshijEzPFjU25xea/7nhIeSqYFKdbA==",
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.5.0",
|
||||
"style-mod": "^4.1.0",
|
||||
"w3c-keyname": "^2.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@ctrl/tinycolor": {
|
||||
"version": "3.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
|
||||
@ -284,6 +639,171 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@lezer/common": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.3.tgz",
|
||||
"integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA=="
|
||||
},
|
||||
"node_modules/@lezer/cpp": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/cpp/-/cpp-1.1.3.tgz",
|
||||
"integrity": "sha512-ykYvuFQKGsRi6IcE+/hCSGUhb/I4WPjd3ELhEblm2wS2cOznDFzO+ubK2c+ioysOnlZ3EduV+MVQFCPzAIoY3w==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/css": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.1.10.tgz",
|
||||
"integrity": "sha512-V5/89eDapjeAkWPBpWEfQjZ1Hag3aYUUJOL8213X0dFRuXJ4BXa5NKl9USzOnaLod4AOpmVCkduir2oKwZYZtg==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/go": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/go/-/go-1.0.0.tgz",
|
||||
"integrity": "sha512-co9JfT3QqX1YkrMmourYw2Z8meGC50Ko4d54QEcQbEYpvdUvN4yb0NBZdn/9ertgvjsySxHsKzH3lbm3vqJ4Jw==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/highlight": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz",
|
||||
"integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/html": {
|
||||
"version": "1.3.10",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.3.10.tgz",
|
||||
"integrity": "sha512-dqpT8nISx/p9Do3AchvYGV3qYc4/rKr3IBZxlHmpIKam56P47RSHkSF5f13Vu9hebS1jM0HmtJIwLbWz1VIY6w==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/java": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/java/-/java-1.1.3.tgz",
|
||||
"integrity": "sha512-yHquUfujwg6Yu4Fd1GNHCvidIvJwi/1Xu2DaKl/pfWIA2c1oXkVvawH3NyXhCaFx4OdlYBVX5wvz2f7Aoa/4Xw==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/javascript": {
|
||||
"version": "1.4.21",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.21.tgz",
|
||||
"integrity": "sha512-lL+1fcuxWYPURMM/oFZLEDm0XuLN128QPV+VuGtKpeaOGdcl9F2LYC3nh1S9LkPqx9M0mndZFdXCipNAZpzIkQ==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.1.3",
|
||||
"@lezer/lr": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/json": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.3.tgz",
|
||||
"integrity": "sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/lr": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz",
|
||||
"integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/markdown": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.4.2.tgz",
|
||||
"integrity": "sha512-iYewCigG/517D0xJPQd7RGaCjZAFwROiH8T9h7OTtz0bRVtkxzFhGBFJ9JGKgBBs4uuo1cvxzyQ5iKhDLMcLUQ==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.0.0",
|
||||
"@lezer/highlight": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/php": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/php/-/php-1.0.2.tgz",
|
||||
"integrity": "sha512-GN7BnqtGRpFyeoKSEqxvGvhJQiI4zkgmYnDk/JIyc7H7Ifc1tkPnUn/R2R8meH3h/aBf5rzjvU8ZQoyiNDtDrA==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/python": {
|
||||
"version": "1.1.16",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/python/-/python-1.1.16.tgz",
|
||||
"integrity": "sha512-ievIWylIZA5rNgAyHgA06/Y76vMUISKaYL9WrtjU8rCTTEzyZYo2jz9ER2YBdnN6dxCyS7eaK4HJCzamoAMKZw==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/rust": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/rust/-/rust-1.0.2.tgz",
|
||||
"integrity": "sha512-Lz5sIPBdF2FUXcWeCu1//ojFAZqzTQNRga0aYv6dYXqJqPfMdCAI0NzajWUd4Xijj1IKJLtjoXRPMvTKWBcqKg==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/sass": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/sass/-/sass-1.0.7.tgz",
|
||||
"integrity": "sha512-8HLlOkuX/SMHOggI2DAsXUw38TuURe+3eQ5hiuk9QmYOUyC55B1dYEIMkav5A4IELVaW4e1T4P9WRiI5ka4mdw==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/xml": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/xml/-/xml-1.0.6.tgz",
|
||||
"integrity": "sha512-CdDwirL0OEaStFue/66ZmFSeppuL6Dwjlk8qk153mSQwiSH/Dlri4GNymrNWnUmPl2Um7QfV1FO9KFUyX3Twww==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/yaml": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/yaml/-/yaml-1.0.3.tgz",
|
||||
"integrity": "sha512-GuBLekbw9jDBDhGur82nuwkxKQ+a3W5H0GfaAthDXcAu+XdpS43VlnxA9E9hllkpSP5ellRDKjLLj7Lu9Wr6xA==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@marijn/find-cluster-break": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz",
|
||||
"integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g=="
|
||||
},
|
||||
"node_modules/@node-ipc/js-queue": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@node-ipc/js-queue/-/js-queue-2.0.3.tgz",
|
||||
@ -553,6 +1073,25 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/linkify-it": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
|
||||
"integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q=="
|
||||
},
|
||||
"node_modules/@types/markdown-it": {
|
||||
"version": "14.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
|
||||
"integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
|
||||
"dependencies": {
|
||||
"@types/linkify-it": "^5",
|
||||
"@types/mdurl": "^2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/mdurl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
|
||||
"integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg=="
|
||||
},
|
||||
"node_modules/@types/mime": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz",
|
||||
@ -675,6 +1214,11 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@vavt/util": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@vavt/util/-/util-2.1.0.tgz",
|
||||
"integrity": "sha512-YIfAvArSFVXmWvoF+DEGD0FhkhVNcCtVWWkfYtj76eSrwHh/wuEEFhiEubg1XLNM3tChO8FH8xJCT/hnizjgFQ=="
|
||||
},
|
||||
"node_modules/@vue/cli-overlay": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@vue/cli-overlay/-/cli-overlay-5.0.8.tgz",
|
||||
@ -1538,6 +2082,11 @@
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||
},
|
||||
"node_modules/array-flatten": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
@ -2179,6 +2728,20 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/codemirror": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz",
|
||||
"integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/commands": "^6.0.0",
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/lint": "^6.0.0",
|
||||
"@codemirror/search": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
@ -2374,6 +2937,14 @@
|
||||
"url": "https://github.com/sponsors/mesqueeb"
|
||||
}
|
||||
},
|
||||
"node_modules/copy-to-clipboard": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz",
|
||||
"integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==",
|
||||
"dependencies": {
|
||||
"toggle-selection": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/copy-webpack-plugin": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-9.1.0.tgz",
|
||||
@ -2434,6 +3005,11 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/crelt": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
|
||||
"integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g=="
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "6.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz",
|
||||
@ -2676,6 +3252,11 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/cssfilter": {
|
||||
"version": "0.0.10",
|
||||
"resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz",
|
||||
"integrity": "sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw=="
|
||||
},
|
||||
"node_modules/cssnano": {
|
||||
"version": "5.1.15",
|
||||
"resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz",
|
||||
@ -4882,6 +5463,14 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/linkify-it": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
|
||||
"integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
|
||||
"dependencies": {
|
||||
"uc.micro": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/loader-runner": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
|
||||
@ -5187,6 +5776,43 @@
|
||||
"semver": "bin/semver"
|
||||
}
|
||||
},
|
||||
"node_modules/markdown-it": {
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
|
||||
"integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1",
|
||||
"entities": "^4.4.0",
|
||||
"linkify-it": "^5.0.0",
|
||||
"mdurl": "^2.0.0",
|
||||
"punycode.js": "^2.3.1",
|
||||
"uc.micro": "^2.1.0"
|
||||
},
|
||||
"bin": {
|
||||
"markdown-it": "bin/markdown-it.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/markdown-it-image-figures": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-image-figures/-/markdown-it-image-figures-2.1.1.tgz",
|
||||
"integrity": "sha512-mwXSQ2nPeVUzCMIE3HlLvjRioopiqyJLNph0pyx38yf9mpqFDhNGnMpAXF9/A2Xv0oiF2cVyg9xwfF0HNAz05g==",
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"markdown-it": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/markdown-it-sub": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-sub/-/markdown-it-sub-2.0.0.tgz",
|
||||
"integrity": "sha512-iCBKgwCkfQBRg2vApy9vx1C1Tu6D8XYo8NvevI3OlwzBRmiMtsJ2sXupBgEA7PPxiDwNni3qIUkhZ6j5wofDUA=="
|
||||
},
|
||||
"node_modules/markdown-it-sup": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-sup/-/markdown-it-sup-2.0.0.tgz",
|
||||
"integrity": "sha512-5VgmdKlkBd8sgXuoDoxMpiU+BiEt3I49GItBzzw7Mxq9CxvnhE/k09HFli09zgfFDRixDQDfDxi0mgBCXtaTvA=="
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
@ -5197,6 +5823,34 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/md-editor-v3": {
|
||||
"version": "4.21.3",
|
||||
"resolved": "https://registry.npmjs.org/md-editor-v3/-/md-editor-v3-4.21.3.tgz",
|
||||
"integrity": "sha512-9+RCioqFIWSExTsG0jf9T/RTrFhtH8SpRcKVjHeEQSlExAr/zsgYt/M9XUy/nuGx87hgNKDzK0PXp/uOlDumAw==",
|
||||
"dependencies": {
|
||||
"@codemirror/lang-markdown": "^6.2.5",
|
||||
"@codemirror/language-data": "^6.5.1",
|
||||
"@types/markdown-it": "^14.0.1",
|
||||
"@vavt/util": "^2.1.0",
|
||||
"codemirror": "^6.0.1",
|
||||
"copy-to-clipboard": "^3.3.3",
|
||||
"lru-cache": "^10.2.0",
|
||||
"markdown-it": "^14.0.0",
|
||||
"markdown-it-image-figures": "^2.1.1",
|
||||
"markdown-it-sub": "^2.0.0",
|
||||
"markdown-it-sup": "^2.0.0",
|
||||
"medium-zoom": "^1.1.0",
|
||||
"xss": "^1.0.15"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.2.47"
|
||||
}
|
||||
},
|
||||
"node_modules/md-editor-v3/node_modules/lru-cache": {
|
||||
"version": "10.4.3",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
|
||||
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
|
||||
},
|
||||
"node_modules/mdn-data": {
|
||||
"version": "2.0.14",
|
||||
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
|
||||
@ -5204,6 +5858,11 @@
|
||||
"dev": true,
|
||||
"license": "CC0-1.0"
|
||||
},
|
||||
"node_modules/mdurl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
|
||||
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w=="
|
||||
},
|
||||
"node_modules/media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
@ -5214,6 +5873,11 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/medium-zoom": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/medium-zoom/-/medium-zoom-1.1.0.tgz",
|
||||
"integrity": "sha512-ewyDsp7k4InCUp3jRmwHBRFGyjBimKps/AJLjRSox+2q/2H4p/PNpQf+pwONWlJiOudkBXtbdmVbFjqyybfTmQ=="
|
||||
},
|
||||
"node_modules/memfs": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz",
|
||||
@ -6953,6 +7617,14 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/punycode.js": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
|
||||
"integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode.vue": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/qrcode.vue/-/qrcode.vue-3.6.0.tgz",
|
||||
@ -7917,6 +8589,11 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/style-mod": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz",
|
||||
"integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw=="
|
||||
},
|
||||
"node_modules/stylehacks": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz",
|
||||
@ -8215,6 +8892,11 @@
|
||||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/toggle-selection": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
|
||||
"integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ=="
|
||||
},
|
||||
"node_modules/toidentifier": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||
@ -8273,6 +8955,11 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/uc.micro": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
|
||||
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A=="
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.20.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
|
||||
@ -8543,6 +9230,11 @@
|
||||
"vue": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/w3c-keyname": {
|
||||
"version": "2.2.8",
|
||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
|
||||
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="
|
||||
},
|
||||
"node_modules/warning": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
||||
@ -9067,6 +9759,26 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/xss": {
|
||||
"version": "1.0.15",
|
||||
"resolved": "https://registry.npmjs.org/xss/-/xss-1.0.15.tgz",
|
||||
"integrity": "sha512-FVdlVVC67WOIPvfOwhoMETV72f6GbW7aOabBC3WxN/oUdoEMDyLz4OgRv5/gck2ZeNqEQu+Tb0kloovXOfpYVg==",
|
||||
"dependencies": {
|
||||
"commander": "^2.20.3",
|
||||
"cssfilter": "0.0.10"
|
||||
},
|
||||
"bin": {
|
||||
"xss": "bin/xss"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/xss/node_modules/commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
"@vue/cli-service": "^5.0.8",
|
||||
"ant-design-vue": "^3.2.20",
|
||||
"axios": "^1.7.9",
|
||||
"md-editor-v3": "^4.8.3",
|
||||
"nprogress": "^0.2.0",
|
||||
"qrcode.vue": "^3.6.0",
|
||||
"vue": "^3.3.4",
|
||||
|
||||
@ -109,6 +109,9 @@
|
||||
<a-menu-item key="merchant-list">
|
||||
<router-link to="/merchant/list">商家列表</router-link>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="merchant-audit">
|
||||
<router-link to="/merchant/audit">商家审核</router-link>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="merchant-categories">
|
||||
<router-link to="/merchant/categories">商家分类</router-link>
|
||||
</a-menu-item>
|
||||
@ -185,7 +188,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, defineComponent, onMounted, watch, computed } from 'vue'
|
||||
import { ref, defineComponent, onMounted, watch, computed, h, provide } from 'vue'
|
||||
import {
|
||||
UserOutlined,
|
||||
HomeOutlined,
|
||||
@ -221,6 +224,11 @@ export default defineComponent({
|
||||
TeamOutlined
|
||||
},
|
||||
setup() {
|
||||
// 为菜单组件提供 prefixCls
|
||||
provide('menuContext', { prefixCls: 'ant-menu', inlineIndent: 24, mode: 'inline', theme: 'dark' });
|
||||
provide('menuItemGroupContext', { prefixCls: 'ant-menu' });
|
||||
provide('subMenuContext', { prefixCls: 'ant-menu' });
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const collapsed = ref(false)
|
||||
@ -377,6 +385,11 @@ export default defineComponent({
|
||||
title: '商家列表',
|
||||
path: '/merchant/list'
|
||||
},
|
||||
{
|
||||
key: 'merchant-audit',
|
||||
title: '商家审核',
|
||||
path: '/merchant/audit'
|
||||
},
|
||||
{
|
||||
key: 'merchant-categories',
|
||||
title: '商家分类',
|
||||
|
||||
25
src/main.js
25
src/main.js
@ -10,7 +10,6 @@ import {
|
||||
Input,
|
||||
Table,
|
||||
Dropdown,
|
||||
SubMenu,
|
||||
Space,
|
||||
Popconfirm,
|
||||
Divider,
|
||||
@ -19,13 +18,20 @@ import {
|
||||
Select,
|
||||
InputNumber,
|
||||
AutoComplete,
|
||||
Tabs
|
||||
Tabs,
|
||||
DatePicker,
|
||||
Radio,
|
||||
TimePicker,
|
||||
Upload,
|
||||
Image,
|
||||
message
|
||||
} from 'ant-design-vue'
|
||||
import 'ant-design-vue/dist/antd.css'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(router)
|
||||
|
||||
// 注册需要的组件
|
||||
app.use(Button)
|
||||
app.use(Layout)
|
||||
@ -35,7 +41,6 @@ app.use(Form)
|
||||
app.use(Input)
|
||||
app.use(Table)
|
||||
app.use(Dropdown)
|
||||
app.use(SubMenu)
|
||||
app.use(Space)
|
||||
app.use(Popconfirm)
|
||||
app.use(Divider)
|
||||
@ -45,5 +50,19 @@ app.use(Select)
|
||||
app.use(InputNumber)
|
||||
app.use(AutoComplete)
|
||||
app.use(Tabs)
|
||||
app.use(DatePicker)
|
||||
app.use(Radio)
|
||||
app.use(TimePicker)
|
||||
app.use(Upload)
|
||||
app.use(Image)
|
||||
|
||||
// 手动注册 Menu 相关组件
|
||||
app.component('ASubMenu', Menu.SubMenu)
|
||||
app.component('AMenuItem', Menu.Item)
|
||||
app.component('AMenuItemGroup', Menu.ItemGroup)
|
||||
app.component('AMenuDivider', Menu.Divider)
|
||||
|
||||
// 设置全局属性
|
||||
app.config.globalProperties.$message = message
|
||||
|
||||
app.mount('#app')
|
||||
@ -104,6 +104,11 @@ const routes = [
|
||||
component: () => import('@/views/merchant/List.vue'),
|
||||
meta: { title: '商家列表' }
|
||||
},
|
||||
{
|
||||
path: 'audit',
|
||||
component: () => import('@/views/merchant/AuditList.vue'),
|
||||
meta: { title: '商家审核' }
|
||||
},
|
||||
{
|
||||
path: 'categories',
|
||||
component: () => import('@/views/merchant/CategoryList.vue'),
|
||||
|
||||
869
src/views/merchant/AuditList.vue
Normal file
869
src/views/merchant/AuditList.vue
Normal file
@ -0,0 +1,869 @@
|
||||
# 创建一个全新的商家审核列表页面,基于List.vue修改,但只展示待审核商家
|
||||
<template>
|
||||
<page-container>
|
||||
<div class="merchant-list">
|
||||
<div class="table-header">
|
||||
<h1>商家审核</h1>
|
||||
</div>
|
||||
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data-source="tableData"
|
||||
:pagination="pagination"
|
||||
:loading="loading"
|
||||
@change="handleTableChange"
|
||||
row-key="id"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'create_time'">
|
||||
{{ formatDateTime(record.create_time) }}
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a-button type="primary" @click="handleAudit(record)">审核</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
|
||||
<!-- 审核详情模态框 -->
|
||||
<a-modal
|
||||
v-model:visible="auditModalVisible"
|
||||
title="商家审核详情"
|
||||
:maskClosable="false"
|
||||
:keyboard="false"
|
||||
:width="900"
|
||||
@cancel="auditModalVisible = false"
|
||||
:footer="null"
|
||||
>
|
||||
<div class="audit-detail" v-if="auditData">
|
||||
<a-spin :spinning="auditLoading">
|
||||
<div class="audit-content">
|
||||
<div class="basic-info-section">
|
||||
<div class="section-title">基本信息</div>
|
||||
<a-descriptions bordered :column="2" size="middle" class="merchant-descriptions">
|
||||
<a-descriptions-item label="商家名称" span="2">
|
||||
{{ auditData.merchant?.name }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="品牌图片" span="2">
|
||||
<div class="brand-image-container">
|
||||
<img
|
||||
:src="auditData.merchant?.brand_image_url"
|
||||
alt="品牌图片"
|
||||
v-if="auditData.merchant?.brand_image_url"
|
||||
class="brand-image-preview"
|
||||
@click="previewImage(auditData.merchant?.brand_image_url, '品牌图片')"
|
||||
/>
|
||||
<a-empty v-else description="无品牌图片" />
|
||||
</div>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="商家分类" span="1">
|
||||
{{ auditData.merchant?.category_name }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="商户归属" span="1">
|
||||
{{ auditData.merchant?.user_nickname ? `${auditData.merchant?.user_nickname} (${auditData.merchant?.user_phone})` : auditData.merchant?.user_phone || '未关联用户' }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="联系电话" span="1">
|
||||
{{ auditData.merchant?.phone || '未设置' }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="营业时间" span="1">
|
||||
{{ auditData.merchant?.business_hours || '未设置' }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="买单分佣比例" span="2">
|
||||
<span class="highlight-text">{{ auditData.merchant?.pay_share_rate || 0 }}%</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="创建时间" span="2">
|
||||
{{ formatDateTime(auditData.merchant?.create_time) }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="商家地址" span="2">
|
||||
<div class="address-with-map">
|
||||
<span>{{ auditData.merchant?.address }}</span>
|
||||
<a-button
|
||||
type="link"
|
||||
size="small"
|
||||
@click="showMapView"
|
||||
v-if="auditData.merchant?.longitude && auditData.merchant?.latitude"
|
||||
>
|
||||
查看地图位置 <i class="icon-map-marker"></i>
|
||||
</a-button>
|
||||
</div>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</div>
|
||||
|
||||
<div class="auth-section">
|
||||
<div class="section-title">认证资料</div>
|
||||
<div class="auth-images">
|
||||
<div class="auth-image-item">
|
||||
<div class="auth-image-title">营业执照</div>
|
||||
<div class="auth-image-container">
|
||||
<img
|
||||
:src="auditData.auth?.license_image_url"
|
||||
alt="营业执照"
|
||||
v-if="auditData.auth?.license_image_url"
|
||||
@click="previewImage(auditData.auth?.license_image_url, '营业执照')"
|
||||
/>
|
||||
<a-empty v-else description="无营业执照图片" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="auth-image-item">
|
||||
<div class="auth-image-title">身份证正面</div>
|
||||
<div class="auth-image-container">
|
||||
<img
|
||||
:src="auditData.auth?.id_front_url"
|
||||
alt="身份证正面"
|
||||
v-if="auditData.auth?.id_front_url"
|
||||
@click="previewImage(auditData.auth?.id_front_url, '身份证正面')"
|
||||
/>
|
||||
<a-empty v-else description="无身份证正面图片" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="auth-image-item">
|
||||
<div class="auth-image-title">身份证反面</div>
|
||||
<div class="auth-image-container">
|
||||
<img
|
||||
:src="auditData.auth?.id_back_url"
|
||||
alt="身份证反面"
|
||||
v-if="auditData.auth?.id_back_url"
|
||||
@click="previewImage(auditData.auth?.id_back_url, '身份证反面')"
|
||||
/>
|
||||
<a-empty v-else description="无身份证反面图片" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="action-buttons">
|
||||
<a-button type="primary" size="large" @click="handleAuditApprove">审核通过</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</a-spin>
|
||||
</div>
|
||||
</a-modal>
|
||||
|
||||
<!-- 图片预览模态框 -->
|
||||
<a-modal
|
||||
v-model:visible="imagePreviewVisible"
|
||||
:footer="null"
|
||||
:width="800"
|
||||
>
|
||||
<div class="preview-container">
|
||||
<img :src="previewImageUrl" :alt="previewImageTitle" class="preview-img" />
|
||||
</div>
|
||||
</a-modal>
|
||||
|
||||
<!-- 地图预览模态框 -->
|
||||
<a-modal
|
||||
v-model:visible="mapViewVisible"
|
||||
title="商家位置"
|
||||
:footer="null"
|
||||
:width="800"
|
||||
@cancel="closeMapView"
|
||||
>
|
||||
<div class="map-container">
|
||||
<div class="map-address-info">
|
||||
<div class="map-merchant-name">{{ auditData?.merchant?.name }}</div>
|
||||
<div class="map-address">{{ auditData?.merchant?.address }}</div>
|
||||
</div>
|
||||
<div id="map-container" style="height: 400px; border-radius: 8px; overflow: hidden;"></div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
</page-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, ref, onMounted, h, nextTick } from 'vue'
|
||||
import {
|
||||
message,
|
||||
Table,
|
||||
Button,
|
||||
Modal,
|
||||
Spin,
|
||||
Descriptions,
|
||||
Empty,
|
||||
Avatar,
|
||||
Space
|
||||
} from 'ant-design-vue'
|
||||
import dayjs from 'dayjs'
|
||||
import PageContainer from '@/components/PageContainer.vue'
|
||||
import request from '@/utils/request'
|
||||
import { loadAMap, createMap } from '@/utils/amap.js'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
PageContainer,
|
||||
ATable: Table,
|
||||
AButton: Button,
|
||||
AModal: Modal,
|
||||
ASpin: Spin,
|
||||
ADescriptions: Descriptions,
|
||||
ADescriptionsItem: Descriptions.Item,
|
||||
AEmpty: Empty,
|
||||
AAvatar: Avatar,
|
||||
ASpace: Space
|
||||
},
|
||||
setup() {
|
||||
const loading = ref(false)
|
||||
const tableData = ref([])
|
||||
|
||||
const pagination = ref({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
showSizeChanger: true,
|
||||
showTotal: (total) => `共 ${total} 条记录`
|
||||
})
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: '商户归属',
|
||||
dataIndex: 'user_info',
|
||||
key: 'user_info',
|
||||
width: 200,
|
||||
customRender: ({ record }) => {
|
||||
if (!record.user_nickname && !record.user_phone) return '-'
|
||||
return `${record.user_nickname || '未设置昵称'} (${record.user_phone})`
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '商家分类',
|
||||
dataIndex: 'category_name',
|
||||
key: 'category_name',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
title: '品牌图片',
|
||||
dataIndex: 'brand_image_url',
|
||||
key: 'brand_image_url',
|
||||
width: 100,
|
||||
align: 'center',
|
||||
customRender: ({ text }) => {
|
||||
if (!text) return '-'
|
||||
return h('img', {
|
||||
src: text,
|
||||
alt: '品牌图片',
|
||||
style: {
|
||||
width: '60px',
|
||||
height: '60px',
|
||||
objectFit: 'cover',
|
||||
borderRadius: '4px'
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '商家名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: '买单分佣比例',
|
||||
dataIndex: 'pay_share_rate',
|
||||
key: 'pay_share_rate',
|
||||
width: 150,
|
||||
align: 'center',
|
||||
customRender: ({ text }) => {
|
||||
return `${text || 0}%`
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '营业时间',
|
||||
dataIndex: 'business_hours',
|
||||
key: 'business_hours',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '联系电话',
|
||||
dataIndex: 'phone',
|
||||
key: 'phone',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'create_time',
|
||||
key: 'create_time',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 200,
|
||||
fixed: 'right',
|
||||
align: 'center'
|
||||
}
|
||||
]
|
||||
|
||||
// 格式化日期时间
|
||||
const formatDateTime = (value) => {
|
||||
if (!value) return ''
|
||||
return dayjs(value).format('YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
|
||||
// 获取待审核商家列表数据
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
const params = {
|
||||
skip: (pagination.value.current - 1) * pagination.value.pageSize,
|
||||
limit: pagination.value.pageSize,
|
||||
status: 'PENDING' // 只获取待审核的商家
|
||||
}
|
||||
|
||||
const res = await request.get('/api/merchant', { params })
|
||||
if (res.data) {
|
||||
tableData.value = (res.data.items || []).map(item => ({
|
||||
...item,
|
||||
pay_gift_points_rate: Number(item.pay_gift_points_rate || 0),
|
||||
pay_share_rate: Number(item.pay_share_rate || 0)
|
||||
}))
|
||||
pagination.value.total = res.data.total || 0
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 表格变化处理
|
||||
const handleTableChange = (pag) => {
|
||||
pagination.value.current = pag.current
|
||||
pagination.value.pageSize = pag.pageSize
|
||||
fetchData()
|
||||
}
|
||||
|
||||
// 审核详情模态框相关
|
||||
const auditModalVisible = ref(false)
|
||||
const auditLoading = ref(false)
|
||||
const auditData = ref(null)
|
||||
const currentRecord = ref(null)
|
||||
|
||||
// 打开审核模态框
|
||||
const handleAudit = async (record) => {
|
||||
currentRecord.value = record
|
||||
auditModalVisible.value = true
|
||||
await fetchAuditDetail(record.id)
|
||||
}
|
||||
|
||||
// 获取审核详情
|
||||
const fetchAuditDetail = async (merchantId) => {
|
||||
try {
|
||||
auditLoading.value = true
|
||||
const res = await request.get(`/api/merchant/${merchantId}/audit`)
|
||||
|
||||
if (res.code === 200 && res.data) {
|
||||
auditData.value = res.data
|
||||
} else {
|
||||
throw new Error(res.message || '获取审核详情失败')
|
||||
}
|
||||
} catch (error) {
|
||||
message.error(error.message || '获取审核详情失败')
|
||||
} finally {
|
||||
auditLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 在审核详情模态框中审核通过
|
||||
const handleAuditApprove = async () => {
|
||||
try {
|
||||
auditLoading.value = true
|
||||
const res = await request.put(`/api/merchant/${currentRecord.value.id}/approve`)
|
||||
|
||||
if (res.code === 200) {
|
||||
message.success('审核通过成功')
|
||||
auditModalVisible.value = false
|
||||
fetchData()
|
||||
} else {
|
||||
throw new Error(res.message || '操作失败')
|
||||
}
|
||||
} catch (error) {
|
||||
message.error(error.message || '操作失败')
|
||||
} finally {
|
||||
auditLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 图片预览相关
|
||||
const imagePreviewVisible = ref(false)
|
||||
const previewImageUrl = ref('')
|
||||
const previewImageTitle = ref('')
|
||||
|
||||
// 预览图片
|
||||
const previewImage = (url, title) => {
|
||||
if (!url) return
|
||||
previewImageUrl.value = url
|
||||
previewImageTitle.value = title || '图片预览'
|
||||
imagePreviewVisible.value = true
|
||||
}
|
||||
|
||||
// 地图预览相关
|
||||
const mapViewVisible = ref(false)
|
||||
const mapInstance = ref(null)
|
||||
const mapMarker = ref(null)
|
||||
|
||||
// 显示地图视图
|
||||
const showMapView = async () => {
|
||||
if (!auditData.value?.merchant?.latitude || !auditData.value?.merchant?.longitude) {
|
||||
message.warning('商家位置信息不完整,无法查看地图')
|
||||
return
|
||||
}
|
||||
|
||||
mapViewVisible.value = true
|
||||
|
||||
// 等待 DOM 更新后初始化地图
|
||||
await nextTick()
|
||||
|
||||
try {
|
||||
await loadAMap()
|
||||
|
||||
// 创建地图实例
|
||||
if (!mapInstance.value) {
|
||||
mapInstance.value = createMap('map-container', {
|
||||
zoom: 15,
|
||||
viewMode: '3D'
|
||||
})
|
||||
}
|
||||
|
||||
const position = [auditData.value.merchant.longitude, auditData.value.merchant.latitude]
|
||||
mapInstance.value.setCenter(position)
|
||||
|
||||
// 清除原有标记
|
||||
if (mapMarker.value) {
|
||||
mapMarker.value.remove()
|
||||
}
|
||||
|
||||
// 创建新标记
|
||||
mapMarker.value = new window.AMap.Marker({
|
||||
position,
|
||||
map: mapInstance.value,
|
||||
title: auditData.value.merchant.name
|
||||
})
|
||||
|
||||
// 添加信息窗体
|
||||
const infoWindow = new window.AMap.InfoWindow({
|
||||
content: `
|
||||
<div class="info-window">
|
||||
<div class="info-title">${auditData.value.merchant.name}</div>
|
||||
<div class="info-address">${auditData.value.merchant.address}</div>
|
||||
<div class="info-phone">电话: ${auditData.value.merchant.phone || '未设置'}</div>
|
||||
</div>
|
||||
`,
|
||||
offset: new window.AMap.Pixel(0, -30)
|
||||
})
|
||||
|
||||
infoWindow.open(mapInstance.value, position)
|
||||
} catch (error) {
|
||||
message.error('加载地图失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭地图视图
|
||||
const closeMapView = () => {
|
||||
mapViewVisible.value = false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchData()
|
||||
})
|
||||
|
||||
return {
|
||||
loading,
|
||||
columns,
|
||||
tableData,
|
||||
pagination,
|
||||
formatDateTime,
|
||||
handleTableChange,
|
||||
handleAudit,
|
||||
auditModalVisible,
|
||||
auditLoading,
|
||||
auditData,
|
||||
handleAuditApprove,
|
||||
imagePreviewVisible,
|
||||
previewImageUrl,
|
||||
previewImageTitle,
|
||||
previewImage,
|
||||
mapViewVisible,
|
||||
showMapView,
|
||||
closeMapView
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.table-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.table-header h1 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
:deep(.ant-table-content) {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.audit-detail {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.audit-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.audit-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.merchant-brand {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.brand-image {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 8px;
|
||||
object-fit: cover;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.merchant-name {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.merchant-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
margin-right: 8px;
|
||||
min-width: 100px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.address-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
border-left: 3px solid #1890ff;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.address-content {
|
||||
background-color: #f9f9f9;
|
||||
padding: 12px 16px;
|
||||
border-radius: 4px;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
}
|
||||
|
||||
.auth-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.auth-images {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.auth-image-item {
|
||||
flex: 1;
|
||||
min-width: 220px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.auth-image-title {
|
||||
font-weight: 500;
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
}
|
||||
|
||||
.auth-image-container {
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
height: 180px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.auth-image-container img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.auth-image-container img:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 16px 0;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.preview-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 600px;
|
||||
background-color: rgba(0, 0, 0, 0.02);
|
||||
}
|
||||
|
||||
.preview-img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.merchant-basic-info {
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.basic-info-left {
|
||||
width: 180px;
|
||||
}
|
||||
|
||||
.basic-info-right {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.merchant-brand {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.brand-image {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 8px;
|
||||
object-fit: cover;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.brand-image:hover {
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.merchant-name {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
margin-top: 8px;
|
||||
text-align: center;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.info-card {
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.info-value.highlight {
|
||||
color: #1890ff;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.icon-clock, .icon-phone, .icon-percentage, .icon-gift, .icon-map-marker {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.icon-clock::before {
|
||||
content: "🕒";
|
||||
}
|
||||
|
||||
.icon-phone::before {
|
||||
content: "📞";
|
||||
}
|
||||
|
||||
.icon-percentage::before {
|
||||
content: "💰";
|
||||
}
|
||||
|
||||
.icon-gift::before {
|
||||
content: "🎁";
|
||||
}
|
||||
|
||||
.icon-map-marker::before {
|
||||
content: "📍";
|
||||
}
|
||||
|
||||
.address-content {
|
||||
background-color: #f9f9f9;
|
||||
padding: 12px 16px;
|
||||
border-radius: 4px;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.address-text {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.map-view-btn {
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.map-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.map-address-info {
|
||||
background-color: #f9f9f9;
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.map-merchant-name {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.map-address {
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.map-coordinates {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.map-view {
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.map-actions {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.highlight-text {
|
||||
color: #1890ff;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.merchant-descriptions {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.merchant-descriptions :deep(.ant-descriptions-item-label) {
|
||||
width: 120px;
|
||||
background-color: #fafafa;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.address-with-map {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.brand-image-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.brand-image-preview {
|
||||
height: 80px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.brand-image-preview:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
</style>
|
||||
@ -15,17 +15,29 @@
|
||||
row-key="id"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'location'">
|
||||
<a @click="showMap(record)">查看位置</a>
|
||||
</template>
|
||||
<template v-if="column.key === 'create_time'">
|
||||
{{ formatDateTime(record.create_time) }}
|
||||
</template>
|
||||
<template v-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a-button type="link" @click="handleEdit(record)">修改资料</a-button>
|
||||
<a-button type="link" @click="showPointsRateModal(record)">修改积分比例</a-button>
|
||||
</a-space>
|
||||
<a-dropdown>
|
||||
<a-button>
|
||||
操作
|
||||
<down-outlined />
|
||||
</a-button>
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item key="edit" @click="handleEdit(record)">
|
||||
<edit-outlined />修改资料
|
||||
</a-menu-item>
|
||||
<a-menu-item key="points" @click="showPointsRateModal(record)">
|
||||
<gift-outlined />修改积分比例
|
||||
</a-menu-item>
|
||||
<a-menu-item key="share" @click="showShareRateModal(record)">
|
||||
<account-book-outlined />设置分润比例
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
@ -169,6 +181,26 @@
|
||||
/>
|
||||
</a-input-group>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="产品描述" name="product_detail">
|
||||
<md-editor
|
||||
v-model:value="formState.product_detail"
|
||||
:toolbars="toolbars"
|
||||
language="zh-CN"
|
||||
preview-theme="github"
|
||||
:placeholder="'请输入产品描述'"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="购买须知" name="purchase_note">
|
||||
<md-editor
|
||||
v-model:value="formState.purchase_note"
|
||||
:toolbars="toolbars"
|
||||
language="zh-CN"
|
||||
preview-theme="github"
|
||||
:placeholder="'请输入购买须知'"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
|
||||
@ -313,6 +345,26 @@
|
||||
/>
|
||||
</a-input-group>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="产品描述" name="product_detail">
|
||||
<md-editor
|
||||
v-model:value="editFormState.product_detail"
|
||||
:toolbars="toolbars"
|
||||
language="zh-CN"
|
||||
preview-theme="github"
|
||||
:placeholder="'请输入产品描述'"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="购买须知" name="purchase_note">
|
||||
<md-editor
|
||||
v-model:value="editFormState.purchase_note"
|
||||
:toolbars="toolbars"
|
||||
language="zh-CN"
|
||||
preview-theme="github"
|
||||
:placeholder="'请输入购买须知'"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
|
||||
@ -345,6 +397,36 @@
|
||||
</a-form-item>
|
||||
</div>
|
||||
</a-modal>
|
||||
|
||||
<!-- 添加分润比例设置模态框 -->
|
||||
<a-modal
|
||||
v-model:visible="shareRateModalVisible"
|
||||
title="设置支付分润比例"
|
||||
:maskClosable="false"
|
||||
:keyboard="false"
|
||||
:width="400"
|
||||
@ok="handleShareRateSubmit"
|
||||
@cancel="shareRateModalVisible = false"
|
||||
>
|
||||
<div class="points-rate-form">
|
||||
<a-form-item
|
||||
label="支付分润比例"
|
||||
required
|
||||
extra="订单金额的百分比,例如:输入60表示分润订单金额的60%"
|
||||
>
|
||||
<a-input-number
|
||||
v-model:value="shareRateValue"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:precision="1"
|
||||
:step="0.1"
|
||||
style="width: 100%"
|
||||
addonAfter="%"
|
||||
placeholder="请输入0-100之间的数值"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
</page-container>
|
||||
</template>
|
||||
@ -356,15 +438,22 @@ import dayjs from 'dayjs'
|
||||
import PageContainer from '@/components/PageContainer.vue'
|
||||
import { loadAMap, createMap, createAutoComplete, createGeocoder } from '@/utils/amap.js'
|
||||
import request from '@/utils/request'
|
||||
import { PlusOutlined, SearchOutlined } from '@ant-design/icons-vue'
|
||||
import { PlusOutlined, SearchOutlined, EditOutlined, DownOutlined, GiftOutlined, AccountBookOutlined } from '@ant-design/icons-vue'
|
||||
import { MdEditor } from 'md-editor-v3'
|
||||
import 'md-editor-v3/lib/style.css'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
PageContainer,
|
||||
PlusOutlined,
|
||||
SearchOutlined,
|
||||
EditOutlined,
|
||||
DownOutlined,
|
||||
GiftOutlined,
|
||||
AccountBookOutlined,
|
||||
AUpload: Upload,
|
||||
AModal: Modal
|
||||
AModal: Modal,
|
||||
MdEditor
|
||||
},
|
||||
setup() {
|
||||
const loading = ref(false)
|
||||
@ -373,6 +462,27 @@ export default defineComponent({
|
||||
const currentMap = ref(null)
|
||||
const currentMarker = ref(null)
|
||||
|
||||
// Markdown 编辑器工具栏配置
|
||||
const toolbars = [
|
||||
'bold',
|
||||
'underline',
|
||||
'italic',
|
||||
'strikeThrough',
|
||||
'title',
|
||||
'sub',
|
||||
'sup',
|
||||
'quote',
|
||||
'unorderedList',
|
||||
'orderedList',
|
||||
'codeRow',
|
||||
'code',
|
||||
'link',
|
||||
'image',
|
||||
'table',
|
||||
'preview',
|
||||
'fullscreen'
|
||||
]
|
||||
|
||||
const pagination = ref({
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
@ -441,25 +551,22 @@ export default defineComponent({
|
||||
return `${text || 0}%`
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '买单分佣比例',
|
||||
dataIndex: 'pay_share_rate',
|
||||
key: 'pay_share_rate',
|
||||
width: 150,
|
||||
align: 'center',
|
||||
customRender: ({ text }) => {
|
||||
return `${text || 0}%`
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '营业时间',
|
||||
dataIndex: 'business_hours',
|
||||
key: 'business_hours',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '地址',
|
||||
dataIndex: 'address',
|
||||
key: 'address',
|
||||
ellipsis: true,
|
||||
width: 300,
|
||||
},
|
||||
{
|
||||
title: '位置',
|
||||
key: 'location',
|
||||
width: 100,
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
title: '联系电话',
|
||||
dataIndex: 'phone',
|
||||
@ -500,7 +607,8 @@ export default defineComponent({
|
||||
if (res.data) {
|
||||
tableData.value = (res.data.items || []).map(item => ({
|
||||
...item,
|
||||
pay_gift_points_rate: Number(item.pay_gift_points_rate || 0)
|
||||
pay_gift_points_rate: Number(item.pay_gift_points_rate || 0),
|
||||
pay_share_rate: Number(item.pay_share_rate || 0)
|
||||
}))
|
||||
pagination.value.total = res.data.total || 0
|
||||
}
|
||||
@ -580,6 +688,8 @@ export default defineComponent({
|
||||
latitude: null,
|
||||
phone: '',
|
||||
brand_image_url: '',
|
||||
product_detail: '',
|
||||
purchase_note: '',
|
||||
})
|
||||
|
||||
const rules = {
|
||||
@ -590,6 +700,8 @@ export default defineComponent({
|
||||
business_hours: [{ required: true, message: '请输入营业时间' }],
|
||||
address: [{ required: true, message: '请输入详细地址' }],
|
||||
phone: [{ required: true, message: '请输入联系电话' }],
|
||||
product_detail: [{ required: false, message: '请输入产品描述' }],
|
||||
purchase_note: [{ required: false, message: '请输入购买须知' }],
|
||||
}
|
||||
|
||||
// 获取商家分类
|
||||
@ -731,12 +843,20 @@ export default defineComponent({
|
||||
formRef.value.validate().then(async () => {
|
||||
try {
|
||||
confirmLoading.value = true
|
||||
await request.post('/api/merchant', formState.value)
|
||||
|
||||
// 确保包含产品描述和购买须知字段
|
||||
const postData = {
|
||||
...formState.value,
|
||||
product_detail: formState.value.product_detail || '',
|
||||
purchase_note: formState.value.purchase_note || ''
|
||||
}
|
||||
|
||||
await request.post('/api/merchant', postData)
|
||||
message.success('添加成功')
|
||||
addModalVisible.value = false
|
||||
fetchData()
|
||||
} catch (error) {
|
||||
|
||||
message.error(error.message || '添加失败')
|
||||
} finally {
|
||||
confirmLoading.value = false
|
||||
}
|
||||
@ -756,6 +876,8 @@ export default defineComponent({
|
||||
latitude: null,
|
||||
phone: '',
|
||||
brand_image_url: '',
|
||||
product_detail: '',
|
||||
purchase_note: '',
|
||||
}
|
||||
searchAddress.value = ''
|
||||
searchOptions.value = []
|
||||
@ -811,6 +933,8 @@ export default defineComponent({
|
||||
latitude: null,
|
||||
phone: '',
|
||||
brand_image_url: '',
|
||||
product_detail: '',
|
||||
purchase_note: '',
|
||||
})
|
||||
const editSearchAddress = ref('')
|
||||
const editMap = ref(null)
|
||||
@ -822,7 +946,9 @@ export default defineComponent({
|
||||
currentEditId.value = record.id
|
||||
editFormState.value = {
|
||||
...record,
|
||||
user_id: record.user_id
|
||||
user_id: record.user_id,
|
||||
product_detail: record.product_detail || '',
|
||||
purchase_note: record.purchase_note || ''
|
||||
}
|
||||
|
||||
// 获取分类数据
|
||||
@ -932,10 +1058,12 @@ export default defineComponent({
|
||||
try {
|
||||
editLoading.value = true
|
||||
|
||||
// 确保包含 user_id 在请求数据中
|
||||
// 确保包含 user_id、产品描述和购买须知字段在请求数据中
|
||||
const updateData = {
|
||||
...editFormState.value,
|
||||
user_id: editFormState.value.user_id
|
||||
user_id: editFormState.value.user_id,
|
||||
product_detail: editFormState.value.product_detail || '',
|
||||
purchase_note: editFormState.value.purchase_note || ''
|
||||
}
|
||||
|
||||
const res = await request.put(`/api/merchant/${currentEditId.value}`, updateData)
|
||||
@ -948,7 +1076,6 @@ export default defineComponent({
|
||||
throw new Error(res.message || '修改失败')
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
message.error(error.message || '修改失败')
|
||||
} finally {
|
||||
editLoading.value = false
|
||||
@ -969,6 +1096,8 @@ export default defineComponent({
|
||||
latitude: null,
|
||||
phone: '',
|
||||
brand_image_url: '',
|
||||
product_detail: '',
|
||||
purchase_note: '',
|
||||
}
|
||||
editSearchAddress.value = ''
|
||||
userOptions.value = []
|
||||
@ -1117,6 +1246,39 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
// 分润比例相关代码
|
||||
const shareRateModalVisible = ref(false)
|
||||
const shareRateValue = ref(0)
|
||||
|
||||
const showShareRateModal = (record) => {
|
||||
currentRecord.value = record
|
||||
shareRateValue.value = Number(record.pay_share_rate || 0)
|
||||
shareRateModalVisible.value = true
|
||||
}
|
||||
|
||||
const handleShareRateSubmit = async () => {
|
||||
try {
|
||||
if (shareRateValue.value < 0 || shareRateValue.value > 100) {
|
||||
message.error('分润比例必须在0-100之间')
|
||||
return
|
||||
}
|
||||
|
||||
const res = await request.put(`/api/merchant/${currentRecord.value.id}`, {
|
||||
pay_share_rate: shareRateValue.value
|
||||
})
|
||||
|
||||
if (res.code === 200) {
|
||||
message.success('设置成功')
|
||||
shareRateModalVisible.value = false
|
||||
fetchData()
|
||||
} else {
|
||||
throw new Error(res.message || '设置失败')
|
||||
}
|
||||
} catch (error) {
|
||||
message.error(error.message || '设置失败')
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchData()
|
||||
})
|
||||
@ -1169,7 +1331,12 @@ export default defineComponent({
|
||||
pointsRateModalVisible,
|
||||
pointsRateValue,
|
||||
showPointsRateModal,
|
||||
handlePointsRateSubmit
|
||||
handlePointsRateSubmit,
|
||||
shareRateModalVisible,
|
||||
shareRateValue,
|
||||
showShareRateModal,
|
||||
handleShareRateSubmit,
|
||||
toolbars
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -1386,4 +1553,52 @@ export default defineComponent({
|
||||
.points-rate-form :deep(.ant-input-number) {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* Markdown 编辑器样式 */
|
||||
:deep(.md-editor) {
|
||||
height: 300px !important;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
:deep(.md-editor-content) {
|
||||
height: 300px !important;
|
||||
}
|
||||
|
||||
:deep(.ant-modal-body) {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
:deep(.md-editor-toolbar) {
|
||||
border-radius: 2px 2px 0 0 !important;
|
||||
}
|
||||
|
||||
:deep(.md-editor-input, .md-editor-preview) {
|
||||
border-radius: 0 0 2px 2px !important;
|
||||
}
|
||||
|
||||
:deep(.md-editor-preview-wrapper) {
|
||||
padding: 8px 16px !important;
|
||||
}
|
||||
|
||||
:deep(.ant-modal .ant-modal-content) {
|
||||
background: #fff;
|
||||
box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.12),
|
||||
0 6px 16px 0 rgba(0, 0, 0, 0.08),
|
||||
0 9px 28px 8px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
:deep(.md-editor) {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
:deep(.md-editor-input) {
|
||||
padding: 12px !important;
|
||||
}
|
||||
|
||||
/* 编辑和添加模态框中的内容样式 */
|
||||
:deep(.ant-modal-body:has(.ant-form)) {
|
||||
padding: 24px;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
@ -37,7 +37,6 @@
|
||||
:loading="loading"
|
||||
@change="handleTableChange"
|
||||
row-key="id"
|
||||
:scroll="{ x: 1500 }"
|
||||
>
|
||||
<template #bodyCell="{ column, text, record }">
|
||||
<!-- 图片列 -->
|
||||
@ -88,7 +87,7 @@
|
||||
v-model:visible="addModalVisible"
|
||||
title="添加商品"
|
||||
:confirmLoading="confirmLoading"
|
||||
width="600px"
|
||||
width="900px"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<template #footer>
|
||||
@ -104,22 +103,11 @@
|
||||
ref="formRef"
|
||||
:model="formState"
|
||||
:rules="rules"
|
||||
:label-col="{ span: 6 }"
|
||||
:label-col="{ span: 8 }"
|
||||
:wrapper-col="{ span: 16 }"
|
||||
>
|
||||
<a-form-item label="所属商家" name="merchant_id" required>
|
||||
<a-select
|
||||
v-model:value="formState.merchant_id"
|
||||
placeholder="请选择商家"
|
||||
:options="merchantOptions"
|
||||
:field-names="{ label: 'name', value: 'id' }"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="商品名称" name="name" required>
|
||||
<a-input v-model:value="formState.name" placeholder="请输入商品名称" />
|
||||
</a-form-item>
|
||||
|
||||
<div class="two-column-form">
|
||||
<div class="form-column">
|
||||
<a-form-item label="商品图片" name="image_url" required>
|
||||
<div class="upload-wrapper">
|
||||
<div v-if="formState.image_url" class="image-preview">
|
||||
@ -143,6 +131,19 @@
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="所属商家" name="merchant_id" required>
|
||||
<a-select
|
||||
v-model:value="formState.merchant_id"
|
||||
placeholder="请选择商家"
|
||||
:options="merchantOptions"
|
||||
:field-names="{ label: 'name', value: 'id' }"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="商品名称" name="name" required>
|
||||
<a-input v-model:value="formState.name" placeholder="请输入商品名称" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="商品原价" name="product_price" required>
|
||||
<a-input-number
|
||||
v-model:value="formState.product_price"
|
||||
@ -173,6 +174,52 @@
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="库存设置" name="qty" required>
|
||||
<a-input-number
|
||||
v-model:value="formState.qty"
|
||||
:min="0"
|
||||
style="width: 100%"
|
||||
placeholder="请输入库存数量"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
|
||||
<div class="form-column">
|
||||
<a-form-item
|
||||
label="赠送积分比例"
|
||||
name="gift_points_rate"
|
||||
required
|
||||
>
|
||||
<a-input-number
|
||||
v-model:value="formState.gift_points_rate"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:precision="1"
|
||||
:step="0.1"
|
||||
style="width: 100%"
|
||||
addonAfter="%"
|
||||
placeholder="请输入0-100之间的数值"
|
||||
/>
|
||||
<div class="form-item-help">消费金额的百分比,例如:10表示赠送10%作为积分</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
label="促销文本"
|
||||
name="promotion_text"
|
||||
>
|
||||
<a-input
|
||||
v-model:value="formState.promotion_text"
|
||||
placeholder="例如:新人三折"
|
||||
:maxLength="5"
|
||||
show-count
|
||||
/>
|
||||
<div class="form-item-help">显示在商品下方的促销文本,限5个字以内</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="标签" name="tags">
|
||||
<a-input v-model:value="formState.tags" placeholder="多个标签用逗号分隔" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="限购次数" name="purchase_limit">
|
||||
<a-input-number
|
||||
v-model:value="formState.purchase_limit"
|
||||
@ -185,40 +232,69 @@
|
||||
<div class="form-item-help">0 次表示不限购</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="标签" name="tags">
|
||||
<a-input v-model:value="formState.tags" placeholder="多个标签用逗号分隔" />
|
||||
<a-form-item label="配送方式" name="delivery_type" required>
|
||||
<a-radio-group v-model:value="formState.delivery_type">
|
||||
<a-radio value="DELIVERY">配送到家</a-radio>
|
||||
<a-radio value="PICKUP">自提</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
label="促销文本"
|
||||
name="promotion_text"
|
||||
extra="显示在商品下方的促销文本,限5个字以内"
|
||||
v-if="formState.delivery_type === 'PICKUP'"
|
||||
label="自提点"
|
||||
name="pickup_place"
|
||||
required
|
||||
>
|
||||
<a-input
|
||||
v-model:value="formState.promotion_text"
|
||||
placeholder="例如:新人三折"
|
||||
:maxLength="5"
|
||||
show-count
|
||||
v-model:value="formState.pickup_place"
|
||||
placeholder="请输入自提点地址"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
label="赠送积分比例"
|
||||
name="gift_points_rate"
|
||||
v-if="formState.delivery_type === 'PICKUP'"
|
||||
label="自提时间"
|
||||
name="pickup_time"
|
||||
required
|
||||
extra="消费金额的百分比,例如:输入10表示赠送消费金额的10%作为积分"
|
||||
>
|
||||
<a-input-number
|
||||
v-model:value="formState.gift_points_rate"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:precision="1"
|
||||
:step="0.1"
|
||||
<a-date-picker
|
||||
v-model:value="pickupDateTime"
|
||||
type="date"
|
||||
show-time
|
||||
format="YYYY-MM-DD HH:mm"
|
||||
placeholder="请选择自提日期和时间"
|
||||
style="width: 100%"
|
||||
addonAfter="%"
|
||||
placeholder="请输入0-100之间的数值"
|
||||
@change="updatePickupTime"
|
||||
:disabled-date="disabledDate"
|
||||
:show-time="{ format: 'HH:mm', minuteStep: 10 }"
|
||||
/>
|
||||
<div class="form-item-help">请选择自提的日期和时间</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="配送时间类型" name="delivery_time_type" required>
|
||||
<a-radio-group v-model:value="formState.delivery_time_type">
|
||||
<a-radio value="IMMEDIATE">及时送</a-radio>
|
||||
<a-radio value="SCHEDULED">定时送</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
v-if="formState.delivery_time_type === 'SCHEDULED'"
|
||||
label="送货时间"
|
||||
name="delivery_date"
|
||||
required
|
||||
>
|
||||
<a-date-picker
|
||||
v-model:value="formState.delivery_date"
|
||||
:disabled-date="disabledDate"
|
||||
format="YYYY-MM-DD"
|
||||
valueFormat="YYYY-MM-DD"
|
||||
style="width: 100%"
|
||||
placeholder="请选择送货日期"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
</div>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
|
||||
@ -227,7 +303,7 @@
|
||||
v-model:visible="editModalVisible"
|
||||
title="修改商品"
|
||||
:confirmLoading="editLoading"
|
||||
width="600px"
|
||||
width="900px"
|
||||
@cancel="handleEditCancel"
|
||||
>
|
||||
<template #footer>
|
||||
@ -243,13 +319,11 @@
|
||||
ref="editFormRef"
|
||||
:model="editFormState"
|
||||
:rules="rules"
|
||||
:label-col="{ span: 6 }"
|
||||
:label-col="{ span: 8 }"
|
||||
:wrapper-col="{ span: 16 }"
|
||||
>
|
||||
<a-form-item label="商品名称" name="name" required>
|
||||
<a-input v-model:value="editFormState.name" placeholder="请输入商品名称" />
|
||||
</a-form-item>
|
||||
|
||||
<div class="two-column-form">
|
||||
<div class="form-column">
|
||||
<a-form-item label="商品图片" name="image_url" required>
|
||||
<div class="upload-wrapper">
|
||||
<div v-if="editFormState.image_url" class="image-preview">
|
||||
@ -273,6 +347,10 @@
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="商品名称" name="name" required>
|
||||
<a-input v-model:value="editFormState.name" placeholder="请输入商品名称" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="商品原价" name="product_price" required>
|
||||
<a-input-number
|
||||
v-model:value="editFormState.product_price"
|
||||
@ -303,6 +381,52 @@
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="库存设置" name="qty" required>
|
||||
<a-input-number
|
||||
v-model:value="editFormState.qty"
|
||||
:min="0"
|
||||
style="width: 100%"
|
||||
placeholder="请输入库存数量"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
|
||||
<div class="form-column">
|
||||
<a-form-item
|
||||
label="赠送积分比例"
|
||||
name="gift_points_rate"
|
||||
required
|
||||
>
|
||||
<a-input-number
|
||||
v-model:value="editFormState.gift_points_rate"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:precision="1"
|
||||
:step="0.1"
|
||||
style="width: 100%"
|
||||
addonAfter="%"
|
||||
placeholder="请输入0-100之间的数值"
|
||||
/>
|
||||
<div class="form-item-help">消费金额的百分比,例如:10表示赠送10%作为积分</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
label="促销文本"
|
||||
name="promotion_text"
|
||||
>
|
||||
<a-input
|
||||
v-model:value="editFormState.promotion_text"
|
||||
placeholder="例如:新人三折"
|
||||
:maxLength="5"
|
||||
show-count
|
||||
/>
|
||||
<div class="form-item-help">显示在商品下方的促销文本,限5个字以内</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="标签" name="tags">
|
||||
<a-input v-model:value="editFormState.tags" placeholder="多个标签用逗号分隔" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="限购次数" name="purchase_limit">
|
||||
<a-input-number
|
||||
v-model:value="editFormState.purchase_limit"
|
||||
@ -315,40 +439,69 @@
|
||||
<div class="form-item-help">0 次表示不限购</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="标签" name="tags">
|
||||
<a-input v-model:value="editFormState.tags" placeholder="多个标签用逗号分隔" />
|
||||
<a-form-item label="配送方式" name="delivery_type" required>
|
||||
<a-radio-group v-model:value="editFormState.delivery_type">
|
||||
<a-radio value="DELIVERY">配送到家</a-radio>
|
||||
<a-radio value="PICKUP">自提</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
label="促销文本"
|
||||
name="promotion_text"
|
||||
extra="显示在商品下方的促销文本,限5个字以内"
|
||||
v-if="editFormState.delivery_type === 'PICKUP'"
|
||||
label="自提点"
|
||||
name="pickup_place"
|
||||
required
|
||||
>
|
||||
<a-input
|
||||
v-model:value="editFormState.promotion_text"
|
||||
placeholder="例如:新人三折"
|
||||
:maxLength="5"
|
||||
show-count
|
||||
v-model:value="editFormState.pickup_place"
|
||||
placeholder="请输入自提点地址"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
label="赠送积分比例"
|
||||
name="gift_points_rate"
|
||||
v-if="editFormState.delivery_type === 'PICKUP'"
|
||||
label="自提时间"
|
||||
name="pickup_time"
|
||||
required
|
||||
extra="消费金额的百分比,例如:输入10表示赠送消费金额的10%作为积分"
|
||||
>
|
||||
<a-input-number
|
||||
v-model:value="editFormState.gift_points_rate"
|
||||
:min="0"
|
||||
:max="100"
|
||||
:precision="1"
|
||||
:step="0.1"
|
||||
<a-date-picker
|
||||
v-model:value="editPickupDateTime"
|
||||
type="date"
|
||||
show-time
|
||||
format="YYYY-MM-DD HH:mm"
|
||||
placeholder="请选择自提日期和时间"
|
||||
style="width: 100%"
|
||||
addonAfter="%"
|
||||
placeholder="请输入0-100之间的数值"
|
||||
@change="updateEditPickupTime"
|
||||
:disabled-date="disabledDate"
|
||||
:show-time="{ format: 'HH:mm', minuteStep: 10 }"
|
||||
/>
|
||||
<div class="form-item-help">请选择自提的日期和时间</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="配送时间类型" name="delivery_time_type" required>
|
||||
<a-radio-group v-model:value="editFormState.delivery_time_type">
|
||||
<a-radio value="IMMEDIATE">及时送</a-radio>
|
||||
<a-radio value="SCHEDULED">定时送</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
v-if="editFormState.delivery_time_type === 'SCHEDULED'"
|
||||
label="送货时间"
|
||||
name="delivery_date"
|
||||
required
|
||||
>
|
||||
<a-date-picker
|
||||
v-model:value="editFormState.delivery_date"
|
||||
:disabled-date="disabledDate"
|
||||
format="YYYY-MM-DD"
|
||||
valueFormat="YYYY-MM-DD"
|
||||
style="width: 100%"
|
||||
placeholder="请选择送货日期"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
</div>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</div>
|
||||
@ -356,12 +509,17 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, ref, onMounted, h } from 'vue'
|
||||
import { message, Upload, InputNumber, Tag } from 'ant-design-vue'
|
||||
import { defineComponent, ref, onMounted, h, computed, watch } from 'vue'
|
||||
import { message, Upload, InputNumber, Tag, Radio, DatePicker, Row, Col, TimePicker, Space, Input } from 'ant-design-vue'
|
||||
import { UploadOutlined } from '@ant-design/icons-vue'
|
||||
import PageContainer from '@/components/PageContainer.vue'
|
||||
import { getMerchantProducts, updateProductStatus } from '@/api/merchant'
|
||||
import request from '@/utils/request'
|
||||
import dayjs from 'dayjs'
|
||||
import 'dayjs/locale/zh-cn'
|
||||
|
||||
// 设置 dayjs 的默认语言为中文
|
||||
dayjs.locale('zh-cn')
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@ -369,7 +527,15 @@ export default defineComponent({
|
||||
UploadOutlined,
|
||||
AUpload: Upload,
|
||||
AInputNumber: InputNumber,
|
||||
ATag: Tag
|
||||
ATag: Tag,
|
||||
ARadio: Radio,
|
||||
ARadioGroup: Radio.Group,
|
||||
ADatePicker: DatePicker,
|
||||
ATimePicker: TimePicker,
|
||||
ASpace: Space,
|
||||
ARow: Row,
|
||||
ACol: Col,
|
||||
AInput: Input
|
||||
},
|
||||
setup() {
|
||||
const loading = ref(false)
|
||||
@ -388,70 +554,71 @@ export default defineComponent({
|
||||
showTotal: (total) => `共 ${total} 条记录`
|
||||
})
|
||||
|
||||
// 添加商品相关
|
||||
const addModalVisible = ref(false)
|
||||
const confirmLoading = ref(false)
|
||||
const formRef = ref(null)
|
||||
|
||||
const formState = ref({
|
||||
merchant_id: undefined,
|
||||
name: '',
|
||||
image_url: '',
|
||||
product_price: null,
|
||||
sale_price: null,
|
||||
settlement_amount: null,
|
||||
purchase_limit: 0,
|
||||
tags: '',
|
||||
gift_points_rate: 0,
|
||||
promotion_text: '',
|
||||
qty: 0,
|
||||
delivery_type: 'DELIVERY',
|
||||
pickup_place: '',
|
||||
pickup_time: '',
|
||||
delivery_time_type: 'IMMEDIATE',
|
||||
delivery_date: null
|
||||
})
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'ID',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
width: 80,
|
||||
width: 60,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '商品图片',
|
||||
dataIndex: 'image_url',
|
||||
key: 'image_url',
|
||||
width: 100,
|
||||
width: 80,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '所属商家',
|
||||
dataIndex: 'merchant_name',
|
||||
key: 'merchant_name',
|
||||
width: 160,
|
||||
width: '15%',
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: '商品名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: '赠送积分比例',
|
||||
dataIndex: 'gift_points_rate',
|
||||
key: 'gift_points_rate',
|
||||
width: 150,
|
||||
align: 'center',
|
||||
customRender: ({ text }) => {
|
||||
return `${text || 0}%`
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '商品原价',
|
||||
dataIndex: 'product_price',
|
||||
key: 'product_price',
|
||||
width: 100,
|
||||
align: 'right'
|
||||
width: '25%',
|
||||
ellipsis: true
|
||||
},
|
||||
{
|
||||
title: '销售价格',
|
||||
dataIndex: 'sale_price',
|
||||
key: 'sale_price',
|
||||
width: 100,
|
||||
align: 'right'
|
||||
},
|
||||
{
|
||||
title: '结算价格',
|
||||
dataIndex: 'settlement_amount',
|
||||
key: 'settlement_amount',
|
||||
width: 100,
|
||||
width: '10%',
|
||||
align: 'right'
|
||||
},
|
||||
{
|
||||
title: '限购',
|
||||
dataIndex: 'purchase_limit',
|
||||
key: 'purchase_limit',
|
||||
width: 100,
|
||||
width: '10%',
|
||||
align: 'center',
|
||||
customRender: ({ text }) => {
|
||||
return h(
|
||||
@ -463,25 +630,18 @@ export default defineComponent({
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '标签',
|
||||
dataIndex: 'tags',
|
||||
key: 'tags',
|
||||
width: 120
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
width: 100,
|
||||
width: '10%',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 100,
|
||||
align: 'center',
|
||||
fixed: 'right'
|
||||
width: '15%',
|
||||
align: 'center'
|
||||
}
|
||||
]
|
||||
|
||||
@ -565,10 +725,56 @@ export default defineComponent({
|
||||
purchase_limit: 0,
|
||||
tags: '',
|
||||
gift_points_rate: 0,
|
||||
promotion_text: ''
|
||||
promotion_text: '',
|
||||
qty: 0,
|
||||
delivery_type: 'DELIVERY',
|
||||
pickup_place: '',
|
||||
pickup_time: '',
|
||||
delivery_time_type: 'IMMEDIATE',
|
||||
delivery_date: null
|
||||
})
|
||||
|
||||
// 显示修改模态框
|
||||
// 添加商品相关自提时间选择器
|
||||
const pickupDateTime = ref(null);
|
||||
|
||||
// 编辑商品相关自提时间选择器
|
||||
const editPickupDateTime = ref(null);
|
||||
|
||||
// 更新自提时间
|
||||
const updatePickupTime = () => {
|
||||
if (pickupDateTime.value) {
|
||||
formState.value.pickup_time = dayjs(pickupDateTime.value).format('YYYY-MM-DD HH:mm');
|
||||
} else {
|
||||
formState.value.pickup_time = '';
|
||||
}
|
||||
};
|
||||
|
||||
// 更新编辑自提时间
|
||||
const updateEditPickupTime = () => {
|
||||
if (editPickupDateTime.value) {
|
||||
editFormState.value.pickup_time = dayjs(editPickupDateTime.value).format('YYYY-MM-DD HH:mm');
|
||||
} else {
|
||||
editFormState.value.pickup_time = '';
|
||||
}
|
||||
};
|
||||
|
||||
// 监听delivery_type的变化,重置时间选择器
|
||||
watch(() => formState.value.delivery_type, (newType) => {
|
||||
if (newType !== 'PICKUP') {
|
||||
pickupDateTime.value = null;
|
||||
formState.value.pickup_time = '';
|
||||
}
|
||||
});
|
||||
|
||||
// 监听编辑模式下delivery_type的变化
|
||||
watch(() => editFormState.value.delivery_type, (newType) => {
|
||||
if (newType !== 'PICKUP') {
|
||||
editPickupDateTime.value = null;
|
||||
editFormState.value.pickup_time = '';
|
||||
}
|
||||
});
|
||||
|
||||
// 显示修改模态框时解析已有的pickup_time
|
||||
const handleEdit = (record) => {
|
||||
currentEditId.value = record.id
|
||||
editFormState.value = {
|
||||
@ -580,8 +786,27 @@ export default defineComponent({
|
||||
purchase_limit: record.purchase_limit,
|
||||
tags: record.tags,
|
||||
gift_points_rate: record.gift_points_rate,
|
||||
promotion_text: record.promotion_text
|
||||
promotion_text: record.promotion_text,
|
||||
qty: record.qty || 0,
|
||||
delivery_type: record.delivery_type || 'DELIVERY',
|
||||
pickup_place: record.pickup_place || '',
|
||||
pickup_time: record.pickup_time || '',
|
||||
delivery_time_type: record.delivery_time_type || 'IMMEDIATE',
|
||||
delivery_date: record.delivery_date || null
|
||||
}
|
||||
|
||||
// 解析pickup_time为日期时间选择器的值
|
||||
if (record.pickup_time) {
|
||||
try {
|
||||
editPickupDateTime.value = dayjs(record.pickup_time);
|
||||
} catch (e) {
|
||||
console.error('解析自提时间失败:', e);
|
||||
editPickupDateTime.value = null;
|
||||
}
|
||||
} else {
|
||||
editPickupDateTime.value = null;
|
||||
}
|
||||
|
||||
editModalVisible.value = true
|
||||
}
|
||||
|
||||
@ -621,7 +846,13 @@ export default defineComponent({
|
||||
editFormRef.value.validate().then(async () => {
|
||||
try {
|
||||
editLoading.value = true
|
||||
const res = await request.put(`/api/merchant/product/${currentEditId.value}`, editFormState.value)
|
||||
// 处理日期格式 - 只取日期部分
|
||||
const formData = { ...editFormState.value };
|
||||
if (formData.delivery_date) {
|
||||
formData.delivery_date = dayjs(formData.delivery_date).format('YYYY-MM-DD');
|
||||
}
|
||||
|
||||
const res = await request.put(`/api/merchant/product/${currentEditId.value}`, formData)
|
||||
if (res.code === 200) {
|
||||
message.success('修改成功')
|
||||
editModalVisible.value = false
|
||||
@ -650,28 +881,23 @@ export default defineComponent({
|
||||
purchase_limit: 0,
|
||||
tags: '',
|
||||
gift_points_rate: 0,
|
||||
promotion_text: ''
|
||||
promotion_text: '',
|
||||
qty: 0,
|
||||
delivery_type: 'DELIVERY',
|
||||
pickup_place: '',
|
||||
pickup_time: '',
|
||||
delivery_time_type: 'IMMEDIATE',
|
||||
delivery_date: null
|
||||
}
|
||||
editPickupDateTime.value = null;
|
||||
editModalVisible.value = false
|
||||
}
|
||||
|
||||
// 添加商品相关
|
||||
const addModalVisible = ref(false)
|
||||
const confirmLoading = ref(false)
|
||||
const formRef = ref(null)
|
||||
|
||||
const formState = ref({
|
||||
merchant_id: undefined,
|
||||
name: '',
|
||||
image_url: '',
|
||||
product_price: null,
|
||||
sale_price: null,
|
||||
settlement_amount: null,
|
||||
purchase_limit: 0,
|
||||
tags: '',
|
||||
gift_points_rate: 0,
|
||||
promotion_text: ''
|
||||
})
|
||||
// 过滤不可选择的日期
|
||||
const disabledDate = (current) => {
|
||||
// 不能选择今天之前的日期
|
||||
return current && current < Date.now() - 8.64e7; // 8.64e7 是一天的毫秒数
|
||||
};
|
||||
|
||||
const rules = {
|
||||
merchant_id: [{ required: true, message: '请选择所属商家' }],
|
||||
@ -684,7 +910,43 @@ export default defineComponent({
|
||||
{ required: true, message: '请输入赠送积分比例' },
|
||||
{ type: 'number', message: '请输入有效的数字' },
|
||||
{ type: 'number', min: 0, max: 100, message: '比例必须在0-100之间' }
|
||||
]
|
||||
],
|
||||
qty: [{ required: true, message: '请输入库存数量' }],
|
||||
delivery_type: [{ required: true, message: '请选择配送方式' }],
|
||||
pickup_place: [{
|
||||
required: true,
|
||||
message: '请输入自提点地址',
|
||||
trigger: 'change',
|
||||
validator: (rule, value) => {
|
||||
if (formState.value.delivery_type === 'PICKUP' && (!value || value.trim() === '')) {
|
||||
return Promise.reject('请输入自提点地址');
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
}],
|
||||
pickup_time: [{
|
||||
required: true,
|
||||
message: '请输入自提时间',
|
||||
trigger: 'change',
|
||||
validator: (rule, value) => {
|
||||
if (formState.value.delivery_type === 'PICKUP' && (!value || value.trim() === '')) {
|
||||
return Promise.reject('请输入自提时间');
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
}],
|
||||
delivery_time_type: [{ required: true, message: '请选择配送时间类型' }],
|
||||
delivery_date: [{
|
||||
required: true,
|
||||
message: '请选择送货日期',
|
||||
trigger: 'change',
|
||||
validator: (rule, value) => {
|
||||
if (formState.value.delivery_time_type === 'SCHEDULED' && !value) {
|
||||
return Promise.reject('请选择送货日期');
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
// 显示添加模态框
|
||||
@ -728,7 +990,13 @@ export default defineComponent({
|
||||
formRef.value.validate().then(async () => {
|
||||
try {
|
||||
confirmLoading.value = true
|
||||
const res = await request.post('/api/merchant/product', formState.value)
|
||||
// 处理日期格式 - 只取日期部分
|
||||
const formData = { ...formState.value };
|
||||
if (formData.delivery_date) {
|
||||
formData.delivery_date = dayjs(formData.delivery_date).format('YYYY-MM-DD');
|
||||
}
|
||||
|
||||
const res = await request.post('/api/merchant/product', formData)
|
||||
if (res.code === 200) {
|
||||
message.success('添加成功')
|
||||
addModalVisible.value = false
|
||||
@ -758,8 +1026,15 @@ export default defineComponent({
|
||||
purchase_limit: 0,
|
||||
tags: '',
|
||||
gift_points_rate: 0,
|
||||
promotion_text: ''
|
||||
promotion_text: '',
|
||||
qty: 0,
|
||||
delivery_type: 'DELIVERY',
|
||||
pickup_place: '',
|
||||
pickup_time: '',
|
||||
delivery_time_type: 'IMMEDIATE',
|
||||
delivery_date: null
|
||||
}
|
||||
pickupDateTime.value = null;
|
||||
addModalVisible.value = false
|
||||
}
|
||||
|
||||
@ -844,7 +1119,12 @@ export default defineComponent({
|
||||
handleEditCancel,
|
||||
getStatusText,
|
||||
getStatusColor,
|
||||
handleToggleStatus
|
||||
handleToggleStatus,
|
||||
disabledDate,
|
||||
pickupDateTime,
|
||||
updatePickupTime,
|
||||
editPickupDateTime,
|
||||
updateEditPickupTime,
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -931,24 +1211,41 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
.table-container {
|
||||
overflow-x: auto;
|
||||
background: #fff;
|
||||
border-radius: 2px;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:deep(.ant-table-wrapper) {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:deep(.ant-table) {
|
||||
overflow-x: auto;
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
:deep(.ant-table-container) {
|
||||
overflow-x: hidden !important;
|
||||
}
|
||||
|
||||
:deep(.ant-table-content) {
|
||||
overflow-x: hidden !important;
|
||||
}
|
||||
|
||||
:deep(.ant-table-body) {
|
||||
overflow-x: auto !important;
|
||||
overflow-x: hidden !important;
|
||||
}
|
||||
|
||||
:deep(.ant-table-cell) {
|
||||
white-space: nowrap;
|
||||
white-space: normal;
|
||||
word-break: break-word;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:deep(.ant-table-cell-ellipsis) {
|
||||
@ -957,12 +1254,20 @@ export default defineComponent({
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
:deep(.ant-input-number-group-addon) {
|
||||
padding: 0 8px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
background-color: #fafafa;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 0 2px 2px 0;
|
||||
:deep(.ant-table-thead > tr > th) {
|
||||
word-break: break-word;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
:deep(.ant-btn-link) {
|
||||
padding: 2px 4px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
:deep(.ant-space-compact) {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.form-item-help {
|
||||
@ -991,4 +1296,26 @@ export default defineComponent({
|
||||
padding: 3px 12px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.two-column-form {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 -8px;
|
||||
}
|
||||
|
||||
.form-column {
|
||||
flex: 1;
|
||||
min-width: 300px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.time-range-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.time-separator {
|
||||
margin: 0 8px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue
Block a user