diff --git a/.env.dev b/.env.dev index a52eec30..e8cf8938 100644 --- a/.env.dev +++ b/.env.dev @@ -1,5 +1,5 @@ # 开发环境 -NODE_ENV=production +NODE_ENV=development VITE_DEV=false diff --git a/.eslintrc.js b/.eslintrc.js index 244dbbbf..5a7245ac 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,6 +1,4 @@ -// @ts-check -const { defineConfig } = require('eslint-define-config') -module.exports = defineConfig({ +module.exports = { root: true, env: { browser: true, @@ -8,6 +6,7 @@ module.exports = defineConfig({ es6: true }, parser: 'vue-eslint-parser', + plugins: ['vue'], parserOptions: { parser: '@typescript-eslint/parser', ecmaVersion: 2020, @@ -17,16 +16,9 @@ module.exports = defineConfig({ jsx: true } }, - extends: [ - 'plugin:vue/vue3-recommended', - 'plugin:@typescript-eslint/recommended', - 'prettier', - 'plugin:prettier/recommended', - './.eslintrc-auto-import.json' - ], + extends: ['plugin:vue/vue3-recommended', 'prettier', 'plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'], rules: { 'vue/script-setup-uses-vars': 'error', - 'vue/no-reserved-component-names': 'off', '@typescript-eslint/ban-ts-ignore': 'off', '@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/no-explicit-any': 'off', @@ -39,8 +31,20 @@ module.exports = defineConfig({ '@typescript-eslint/ban-types': 'off', '@typescript-eslint/no-non-null-assertion': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', - '@typescript-eslint/no-unused-vars': 'error', - 'no-unused-vars': 'error', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_' + } + ], + 'no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_' + } + ], 'space-before-function-paren': 'off', 'vue/attributes-order': 'off', @@ -66,4 +70,4 @@ module.exports = defineConfig({ ], 'vue/multi-word-component-names': 'off' } -}) +} diff --git a/.vscode/settings.json b/.vscode/settings.json index 5b3aa477..469e4017 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,36 +1,98 @@ { - "typescript.tsdk": "node_modules/typescript/lib", - "prettier.enable": true, - "editor.formatOnType": true, - "editor.formatOnSave": true, - "editor.formatOnPaste": true, - "editor.codeActionsOnSave": { - "source.fixAll.eslint": true + "typescript.tsdk": "./node_modules/typescript/lib", + "volar.tsPlugin": true, + "volar.tsPluginStatus": false, + "npm.packageManager": "pnpm", + "editor.tabSize": 2, + "prettier.printWidth": 100, // 超过最大值换行 + "editor.defaultFormatter": "esbenp.prettier-vscode", + "files.eol": "\n", + "search.exclude": { + "**/node_modules": true, + "**/*.log": true, + "**/*.log*": true, + "**/bower_components": true, + "**/dist": true, + "**/elehukouben": true, + "**/.git": true, + "**/.gitignore": true, + "**/.svn": true, + "**/.DS_Store": true, + "**/.idea": true, + "**/.vscode": false, + "**/yarn.lock": true, + "**/tmp": true, + "out": true, + "dist": true, + "node_modules": true, + "CHANGELOG.md": true, + "examples": true, + "res": true, + "screenshots": true, + "yarn-error.log": true, + "**/.yarn": true }, - "[vue]": { - "editor.defaultFormatter": "Vue.volar" + "files.exclude": { + "**/.cache": true, + "**/.editorconfig": true, + "**/.eslintcache": true, + "**/bower_components": true, + "**/.idea": true, + "**/tmp": true, + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true }, - "[javascript]": { + "files.watcherExclude": { + "**/.git/objects/**": true, + "**/.git/subtree-cache/**": true, + "**/.vscode/**": true, + "**/node_modules/**": true, + "**/tmp/**": true, + "**/bower_components/**": true, + "**/dist/**": true, + "**/yarn.lock": true + }, + "stylelint.enable": true, + "stylelint.validate": ["css", "less", "postcss", "scss", "vue", "sass"], + "path-intellisense.mappings": { + "@/": "${workspaceRoot}/src" + }, + "[javascriptreact]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[typescript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "rvest.vs-code-prettier-eslint" }, - "[json]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" - }, - "[jsonc]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "[typescriptreact]": { + "editor.defaultFormatter": "rvest.vs-code-prettier-eslint" }, "[html]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[css]": { + "editor.defaultFormatter": "rvest.vs-code-prettier-eslint" + }, + "[less]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[scss]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, + "[markdown]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true + }, + "[vue]": { + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true, + "source.fixAll.stylelint": true + } + }, "i18n-ally.localesPaths": ["src/locales"], "i18n-ally.keystyle": "nested", "i18n-ally.sortKeys": true, @@ -39,16 +101,69 @@ "i18n-ally.sourceLanguage": "en", "i18n-ally.displayLanguage": "zh-CN", "i18n-ally.enabledFrameworks": ["vue", "react"], - "god.tsconfig": "./tsconfig.json", - "vue-i18n.i18nPaths": "src/locales", + "cSpell.words": [ + "vben", + "windicss", + "tailwind", + "browserslist", + "tailwindcss", + "esnext", + "antv", + "tinymce", + "qrcode", + "sider", + "pinia", + "sider", + "nprogress", + "INTLIFY", + "stylelint", + "esno", + "vitejs", + "sortablejs", + "codemirror", + "iconify", + "commitlint", + "vditor", + "echarts", + "cropperjs", + "logicflow", + "vueuse", + "zxcvbn", + "lintstagedrc", + "brotli", + "sider", + "pnpm", + "antd" + ], + "vetur.format.scriptInitialIndent": true, + "vetur.format.styleInitialIndent": true, + "vetur.validation.script": false, + "MicroPython.executeButton": [ + { + "text": "▶", + "tooltip": "运行", + "alignment": "left", + "command": "extension.executeFile", + "priority": 3.5 + } + ], + "MicroPython.syncButton": [ + { + "text": "$(sync)", + "tooltip": "同步", + "alignment": "left", + "command": "extension.execute", + "priority": 4 + } + ], + // 控制相关文件嵌套展示 "explorer.fileNesting.enabled": true, "explorer.fileNesting.expand": false, "explorer.fileNesting.patterns": { "*.ts": "$(capture).test.ts, $(capture).test.tsx", "*.tsx": "$(capture).test.ts, $(capture).test.tsx", "*.env": "$(capture).env.*", - "CHANGELOG.md": "CHANGELOG*", - "package.json": "pnpm-lock.yaml,pnpm-workspace.yaml,LICENSE,.gitattributes,.gitignore,.gitpod.yml,CNAME,README*,.npmrc,.browserslistrc,vite.config.*,windi.*,tailwind.*,tsconfig.*,postcss*", - ".eslintrc.js": ".eslintignore,.eslintrc-*,.prettierignore,.stylelintignore,.commitlintrc.js,.prettierrc.js,.stylelint*,stylelint*,prettier.*,.editorconfig" - } + "package.json": "pnpm-lock.yaml,yarn.lock,LICENSE,README*,CHANGELOG*,CNAME,.gitattributes,.gitignore,prettier.config.js,stylelint.config.js,commitlint.config.js,.stylelintignore,.prettierignore,.gitpod.yml,.eslintrc.js,.eslintignore" + }, + "terminal.integrated.scrollback": 10000 } diff --git a/README.md b/README.md index 4a0de6ae..dc69a06d 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ ## 🐶 新手必读 -* nodejs > 16.0.0 && pnpm > 7.30.0 +* nodejs > 16.0.0 && pnpm > 8.6.0 (强制使用pnpm) * 演示地址【Vue3 + element-plus】: * 演示地址【Vue3 + vben(ant-design-vue)】: * 演示地址【Vue2 + element-ui】: @@ -39,11 +39,11 @@ | 框架 | 说明 | 版本 | |----------------------------------------------------------------------|------------------|--------| | [Vue](https://staging-cn.vuejs.org/) | Vue 框架 | 3.3.4 | -| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.3.8 | -| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.3.4 | +| [Vite](https://cn.vitejs.dev//) | 开发与构建工具 | 4.3.9 | +| [Element Plus](https://element-plus.org/zh-CN/) | Element Plus | 2.3.7 | | [TypeScript](https://www.typescriptlang.org/docs/) | JavaScript 的超集 | 5.0.4 | -| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.1.3 | -| [vueuse](https://vueuse.org/) | 常用工具集 | 10.1.2 | +| [pinia](https://pinia.vuejs.org/) | Vue 存储库 替代 vuex5 | 2.1.4 | +| [vueuse](https://vueuse.org/) | 常用工具集 | 10.2.0 | | [vue-i18n](https://kazupon.github.io/vue-i18n/zh/introduction.html/) | 国际化 | 9.2.2 | | [vue-router](https://router.vuejs.org/) | Vue 路由 | 4.2.1 | | [windicss](https://cn.windicss.org/) | 下一代工具优先的 CSS 框架 | 3.5.6 | @@ -136,7 +136,7 @@ ps:核心功能已经实现,正在对接微信小程序中... | | 表单构建 | 拖动表单元素生成相应的 HTML 代码,支持导出 JSON、Vue 文件 | | 🚀 | 配置管理 | 对系统动态配置常用参数,支持 SpringBoot 加载 | | ⭐️ | 定时任务 | 在线(添加、修改、删除)任务调度包含执行结果日志 | -| 🚀 | 文件服务 | 支持将文件存储到 S3(MinIO、阿里云、腾讯云、七牛云)、本地、FTP、数据库等 | +| 🚀 | 文件服务 | 支持将文件存储到 S3(MinIO、阿里云、腾讯云、七牛云)、本地、FTP、数据库等 | | 🚀 | API 日志 | 包括 RESTful API 访问日志、异常日志两部分,方便排查 API 相关的问题 | | | MySQL 监控 | 监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈 | | | Redis 监控 | 监控 Redis 数据库的使用情况,使用的 Redis Key 管理 | diff --git a/build/vite/index.ts b/build/vite/index.ts index da50d919..7b4a17bd 100644 --- a/build/vite/index.ts +++ b/build/vite/index.ts @@ -12,7 +12,6 @@ import Components from 'unplugin-vue-components/vite' import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' import viteCompression from 'vite-plugin-compression' import topLevelAwait from 'vite-plugin-top-level-await' -import vueSetupExtend from 'vite-plugin-vue-setup-extend-plus' import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite' import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' @@ -28,7 +27,6 @@ export function createVitePlugins() { WindiCSS(), progress(), PurgeIcons(), - vueSetupExtend(), ElementPlus({}), AutoImport({ include: [ diff --git a/package.json b/package.json index 6a87adf3..fc3c4432 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "yudao-ui-admin-vue3", - "version": "1.7.3-snapshot", + "version": "1.8.0-snapshot", "description": "基于vue3、vite4、element-plus、typesScript", "author": "xingyu", "private": false, @@ -9,12 +9,12 @@ "dev": "vite --mode base", "front": "vite --mode front", "ts:check": "vue-tsc --noEmit", - "build:pro": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode pro", - "build:dev": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode dev", - "build:stage": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode stage", - "build:test": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode test", - "build:static": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode static", - "build:front": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode front", + "build:pro": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode pro", + "build:dev": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode dev", + "build:stage": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode stage", + "build:test": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode test", + "build:static": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode static", + "build:front": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode front", "serve:pro": "vite preview --mode pro", "serve:dev": "vite preview --mode dev", "serve:test": "vite preview --mode test", @@ -32,12 +32,12 @@ "@element-plus/icons-vue": "^2.1.0", "@form-create/designer": "^3.1.3", "@form-create/element-ui": "^3.1.18", - "@iconify/iconify": "^3.1.0", + "@iconify/iconify": "^3.1.1", "@videojs-player/vue": "^1.0.0", - "@vueuse/core": "^10.1.2", + "@vueuse/core": "^10.2.1", "@wangeditor/editor": "^5.1.23", "@wangeditor/editor-for-vue": "^5.1.10", - "@zxcvbn-ts/core": "^3.0.1", + "@zxcvbn-ts/core": "^3.0.2", "animate.css": "^4.1.1", "axios": "^1.4.0", "benz-amr-recorder": "^1.1.5", @@ -45,29 +45,30 @@ "camunda-bpmn-moddle": "^7.0.1", "cropperjs": "^1.5.13", "crypto-js": "^4.1.1", - "dayjs": "^1.11.7", + "dayjs": "^1.11.9", "diagram-js": "^11.6.0", "echarts": "^5.4.2", "echarts-wordcloud": "^2.1.0", - "element-plus": "2.3.4", - "fast-xml-parser": "^4.2.2", + "element-plus": "2.3.7", + "fast-xml-parser": "^4.2.5", "highlight.js": "^11.8.0", "intro.js": "^7.0.1", "jsencrypt": "^3.3.2", "lodash-es": "^4.17.21", "min-dash": "^4.1.1", - "mitt": "^3.0.0", + "mitt": "^3.0.1", "nprogress": "^0.2.0", - "pinia": "^2.1.3", + "pinia": "^2.1.4", "qrcode": "^1.5.3", "qs": "^6.11.2", "steady-xml": "^0.1.0", - "url": "^0.11.0", + "url": "^0.11.1", "video.js": "^8.3.0", "vue": "3.3.4", + "vue-dompurify-html": "^4.1.4", "vue-i18n": "9.2.2", - "vue-router": "^4.2.1", - "vue-types": "^5.0.3", + "vue-router": "^4.2.4", + "vue-types": "^5.1.0", "vuedraggable": "^4.1.0", "vxe-table": "^4.3.11", "web-storage-cache": "^1.1.1", @@ -75,65 +76,61 @@ "xml-js": "^1.6.11" }, "devDependencies": { - "@commitlint/cli": "^17.6.3", - "@commitlint/config-conventional": "^17.6.3", - "@iconify/json": "^2.2.67", - "@intlify/unplugin-vue-i18n": "^0.10.0", + "@commitlint/cli": "^17.6.6", + "@commitlint/config-conventional": "^17.6.6", + "@iconify/json": "^2.2.87", + "@intlify/unplugin-vue-i18n": "^0.12.1", "@purge-icons/generated": "^0.9.0", "@types/intro.js": "^5.1.1", "@types/lodash-es": "^4.17.7", - "@types/node": "^18.16.0", + "@types/node": "^20.4.1", "@types/nprogress": "^0.2.0", - "@types/qrcode": "^1.5.0", + "@types/qrcode": "^1.5.1", "@types/qs": "^6.9.7", - "@typescript-eslint/eslint-plugin": "^5.59.6", - "@typescript-eslint/parser": "^5.59.6", - "@vitejs/plugin-legacy": "^4.0.3", + "@typescript-eslint/eslint-plugin": "^5.61.0", + "@typescript-eslint/parser": "^5.61.0", + "@vitejs/plugin-legacy": "^4.1.0", "@vitejs/plugin-vue": "^4.2.3", "@vitejs/plugin-vue-jsx": "^3.0.1", "autoprefixer": "^10.4.14", "bpmn-js": "^8.9.0", "bpmn-js-properties-panel": "^0.46.0", - "consola": "^3.1.0", - "eslint": "^8.40.0", + "consola": "^3.2.3", + "eslint": "^8.44.0", "eslint-config-prettier": "^8.8.0", - "eslint-define-config": "^1.20.0", + "eslint-define-config": "^1.21.0", "eslint-plugin-prettier": "^4.2.1", - "eslint-plugin-vue": "^9.13.0", - "lint-staged": "^13.2.2", - "postcss": "^8.4.23", + "eslint-plugin-vue": "^9.15.1", + "lint-staged": "^13.2.3", + "postcss": "^8.4.25", "postcss-html": "^1.5.0", "postcss-scss": "^4.0.6", "prettier": "^2.8.8", "rimraf": "^5.0.1", - "rollup": "^3.22.0", - "sass": "^1.62.1", - "stylelint": "^15.6.2", - "stylelint-config-html": "^1.1.0", - "stylelint-config-recommended": "^12.0.0", - "stylelint-config-standard": "^33.0.0", + "rollup": "^3.26.2", + "sass": "^1.63.6", + "stylelint": "^15.10.1", + "stylelint-config-recommended": "^13.0.0", + "stylelint-config-recommended-vue": "^1.4.0", + "stylelint-config-standard": "^34.0.0", "stylelint-order": "^6.0.3", - "terser": "^5.17.4", - "typescript": "5.0.4", - "unplugin-auto-import": "^0.16.0", - "unplugin-element-plus": "^0.7.1", - "unplugin-vue-components": "^0.24.1", - "vite": "4.3.8", + "terser": "^5.18.2", + "typescript": "5.1.6", + "unplugin-auto-import": "^0.16.6", + "unplugin-element-plus": "^0.7.2", + "unplugin-vue-components": "^0.25.1", + "vite": "4.4.2", "vite-plugin-compression": "^0.5.1", "vite-plugin-ejs": "^1.6.4", "vite-plugin-eslint": "^1.8.1", "vite-plugin-progress": "^0.0.7", "vite-plugin-purge-icons": "^0.9.2", "vite-plugin-svg-icons": "^2.0.1", - "vite-plugin-top-level-await": "^1.3.0", - "vite-plugin-vue-setup-extend-plus": "^0.1.0", + "vite-plugin-top-level-await": "^1.3.1", "vite-plugin-windicss": "^1.9.0", - "vue-tsc": "^1.6.5", + "vue-tsc": "^1.8.4", "windicss": "^3.5.6" }, - "engines": { - "node": ">=16.0.0" - }, "license": "MIT", "repository": { "type": "git", @@ -142,5 +139,10 @@ "bugs": { "url": "https://gitee.com/yudaocode/yudao-ui-admin-vue3/issues" }, - "homepage": "https://gitee.com/yudaocode/yudao-ui-admin-vue3" + "homepage": "https://gitee.com/yudaocode/yudao-ui-admin-vue3", + "packageManager": "pnpm@8.6.0", + "engines": { + "node": ">= 16.0.0", + "pnpm": ">=8.6.0" + } } diff --git a/src/App.vue b/src/App.vue index f75478cd..500a2d6d 100644 --- a/src/App.vue +++ b/src/App.vue @@ -38,10 +38,11 @@ $prefix-cls: #{$namespace}-app; html, body { + @extend .size; + padding: 0 !important; margin: 0; overflow: hidden; - @extend .size; #app { @extend .size; diff --git a/src/api/mall/product/spu.ts b/src/api/mall/product/spu.ts index fd55e126..0ea324b8 100644 --- a/src/api/mall/product/spu.ts +++ b/src/api/mall/product/spu.ts @@ -7,8 +7,7 @@ export interface Property { valueName?: string // 属性值名称 } -// TODO puhui999:是不是直接叫 Sku 更简洁一点哈。type 待后面,总感觉有个类型? -export interface SkuType { +export interface Sku { id?: number // 商品 SKU 编号 spuId?: number // SPU 编号 properties?: Property[] // 属性数组 @@ -25,8 +24,7 @@ export interface SkuType { salesCount?: number // 商品销量 } -// TODO puhui999:是不是直接叫 Spu 更简洁一点哈。type 待后面,总感觉有个类型? -export interface SpuType { +export interface Spu { id?: number name?: string // 商品名称 categoryId?: number | null // 商品分类 @@ -39,9 +37,9 @@ export interface SpuType { brandId?: number | null // 商品品牌编号 specType?: boolean // 商品规格 subCommissionType?: boolean // 分销类型 - skus: SkuType[] // sku数组 + skus?: Sku[] // sku数组 description?: string // 商品详情 - sort?: string // 商品排序 + sort?: number // 商品排序 giveIntegral?: number // 赠送积分 virtualSalesCount?: number // 虚拟销量 recommendHot?: boolean // 是否热卖 @@ -49,6 +47,13 @@ export interface SpuType { recommendBest?: boolean // 是否精品 recommendNew?: boolean // 是否新品 recommendGood?: boolean // 是否优品 + price?: number // 商品价格 + salesCount?: number // 商品销量 + marketPrice?: number // 市场价 + costPrice?: number // 成本价 + stock?: number // 商品库存 + createTime?: Date // 商品创建时间 + status?: number // 商品状态 } // 获得 Spu 列表 @@ -62,12 +67,12 @@ export const getTabsCount = () => { } // 创建商品 Spu -export const createSpu = (data: SpuType) => { +export const createSpu = (data: Spu) => { return request.post({ url: '/product/spu/create', data }) } // 更新商品 Spu -export const updateSpu = (data: SpuType) => { +export const updateSpu = (data: Spu) => { return request.put({ url: '/product/spu/update', data }) } @@ -81,6 +86,11 @@ export const getSpu = (id: number) => { return request.get({ url: `/product/spu/get-detail?id=${id}` }) } +// 获得商品 Spu 详情列表 +export const getSpuDetailList = (ids: number[]) => { + return request.get({ url: `/product/spu/list?spuIds=${ids}` }) +} + // 删除商品 Spu export const deleteSpu = (id: number) => { return request.delete({ url: `/product/spu/delete?id=${id}` }) @@ -90,3 +100,8 @@ export const deleteSpu = (id: number) => { export const exportSpu = async (params) => { return await request.download({ url: '/product/spu/export', params }) } + +// 获得商品 SPU 精简列表 +export const getSpuSimpleList = async () => { + return request.get({ url: '/product/spu/get-simple-list' }) +} diff --git a/src/api/mall/promotion/combination/combinationactivity.ts b/src/api/mall/promotion/combination/combinationactivity.ts new file mode 100644 index 00000000..71d5d2a4 --- /dev/null +++ b/src/api/mall/promotion/combination/combinationactivity.ts @@ -0,0 +1,63 @@ +import request from '@/config/axios' +import { Sku, Spu } from '@/api/mall/product/spu' + +// TODO @puhui999: combinationActivity.ts + +export interface CombinationActivityVO { + id?: number + name?: string + spuId?: number + totalLimitCount?: number + singleLimitCount?: number + startTime?: Date + endTime?: Date + userSize?: number + totalNum?: number + successNum?: number + orderUserCount?: number + virtualGroup?: number + status?: number + limitDuration?: number + products: CombinationProductVO[] +} + +// 拼团活动所需属性 +export interface CombinationProductVO { + spuId: number + skuId: number + activePrice: number // 拼团价格 +} + +// 扩展 Sku 配置 +export type SkuExtension = Sku & { + productConfig: CombinationProductVO +} + +export interface SpuExtension extends Spu { + skus: SkuExtension[] // 重写类型 +} + +// 查询拼团活动列表 +export const getCombinationActivityPage = async (params) => { + return await request.get({ url: '/promotion/combination-activity/page', params }) +} + +// 查询拼团活动详情 +export const getCombinationActivity = async (id: number) => { + return await request.get({ url: '/promotion/combination-activity/get?id=' + id }) +} + +// 新增拼团活动 +export const createCombinationActivity = async (data: CombinationActivityVO) => { + return await request.post({ url: '/promotion/combination-activity/create', data }) +} + +// 修改拼团活动 +export const updateCombinationActivity = async (data: CombinationActivityVO) => { + return await request.put({ url: '/promotion/combination-activity/update', data }) +} + +// 删除拼团活动 +export const deleteCombinationActivity = async (id: number) => { + return await request.delete({ url: '/promotion/combination-activity/delete?id=' + id }) +} diff --git a/src/api/mall/promotion/coupon.ts b/src/api/mall/promotion/coupon.ts new file mode 100755 index 00000000..565b86f7 --- /dev/null +++ b/src/api/mall/promotion/coupon.ts @@ -0,0 +1,18 @@ +import request from '@/config/axios' + +// TODO @dhb52:vo 缺少 + +// 删除优惠劵 +export const deleteCoupon = async (id: number) => { + return request.delete({ + url: `/promotion/coupon/delete?id=${id}` + }) +} + +// 获得优惠劵分页 +export const getCouponPage = async (params: PageParam) => { + return request.get({ + url: '/promotion/coupon/page', + params: params + }) +} diff --git a/src/api/mall/promotion/couponTemplate.ts b/src/api/mall/promotion/couponTemplate.ts new file mode 100755 index 00000000..6a58876e --- /dev/null +++ b/src/api/mall/promotion/couponTemplate.ts @@ -0,0 +1,83 @@ +import request from '@/config/axios' + +export interface CouponTemplateVO { + id: number + name: string + status: number + totalCount: number + takeLimitCount: number + takeType: number + usePrice: number + productScope: number + productSpuIds: string + validityType: number + validStartTime: Date + validEndTime: Date + fixedStartTerm: number + fixedEndTerm: number + discountType: number + discountPercent: number + discountPrice: number + discountLimitPrice: number + takeCount: number + useCount: number +} + +// 创建优惠劵模板 +export function createCouponTemplate(data: CouponTemplateVO) { + return request.post({ + url: '/promotion/coupon-template/create', + data: data + }) +} + +// 更新优惠劵模板 +export function updateCouponTemplate(data: CouponTemplateVO) { + return request.put({ + url: '/promotion/coupon-template/update', + data: data + }) +} + +// 更新优惠劵模板的状态 +export function updateCouponTemplateStatus(id: number, status: [0, 1]) { + const data = { + id, + status + } + return request.put({ + url: '/promotion/coupon-template/update-status', + data: data + }) +} + +// 删除优惠劵模板 +export function deleteCouponTemplate(id: number) { + return request.delete({ + url: '/promotion/coupon-template/delete?id=' + id + }) +} + +// 获得优惠劵模板 +export function getCouponTemplate(id: number) { + return request.get({ + url: '/promotion/coupon-template/get?id=' + id + }) +} + +// 获得优惠劵模板分页 +export function getCouponTemplatePage(params: PageParam) { + return request.get({ + url: '/promotion/coupon-template/page', + params: params + }) +} + +// 导出优惠劵模板 Excel +export function exportCouponTemplateExcel(params: PageParam) { + return request.get({ + url: '/promotion/coupon-template/export-excel', + params: params, + responseType: 'blob' + }) +} diff --git a/src/api/mall/promotion/seckill/seckillActivity.ts b/src/api/mall/promotion/seckill/seckillActivity.ts new file mode 100644 index 00000000..42c1c31c --- /dev/null +++ b/src/api/mall/promotion/seckill/seckillActivity.ts @@ -0,0 +1,63 @@ +import request from '@/config/axios' +import { Sku, Spu } from '@/api/mall/product/spu' + +export interface SeckillActivityVO { + id?: number + spuId?: number + name?: string + status?: number + remark?: string + startTime?: Date + endTime?: Date + sort?: number + configIds?: string + orderCount?: number + userCount?: number + totalPrice?: number + totalLimitCount?: number + singleLimitCount?: number + stock?: number + totalStock?: number + products?: SeckillProductVO[] +} + +// 秒杀活动所需属性 +export interface SeckillProductVO { + skuId: number + seckillPrice: number + stock: number +} + +// 扩展 Sku 配置 +export type SkuExtension = Sku & { + productConfig: SeckillProductVO +} + +export interface SpuExtension extends Spu { + skus: SkuExtension[] // 重写类型 +} + +// 查询秒杀活动列表 +export const getSeckillActivityPage = async (params) => { + return await request.get({ url: '/promotion/seckill-activity/page', params }) +} + +// 查询秒杀活动详情 +export const getSeckillActivity = async (id: number) => { + return await request.get({ url: '/promotion/seckill-activity/get?id=' + id }) +} + +// 新增秒杀活动 +export const createSeckillActivity = async (data: SeckillActivityVO) => { + return await request.post({ url: '/promotion/seckill-activity/create', data }) +} + +// 修改秒杀活动 +export const updateSeckillActivity = async (data: SeckillActivityVO) => { + return await request.put({ url: '/promotion/seckill-activity/update', data }) +} + +// 删除秒杀活动 +export const deleteSeckillActivity = async (id: number) => { + return await request.delete({ url: '/promotion/seckill-activity/delete?id=' + id }) +} diff --git a/src/api/mall/promotion/seckill/seckillConfig.ts b/src/api/mall/promotion/seckill/seckillConfig.ts new file mode 100644 index 00000000..eee82115 --- /dev/null +++ b/src/api/mall/promotion/seckill/seckillConfig.ts @@ -0,0 +1,49 @@ +import request from '@/config/axios' + +export interface SeckillConfigVO { + id: number + name: string + startTime: string + endTime: string + sliderPicUrls: string[] + status: number +} + +// 查询秒杀时段配置列表 +export const getSeckillConfigPage = async (params) => { + return await request.get({ url: '/promotion/seckill-config/page', params }) +} + +// 查询秒杀时段配置详情 +export const getSeckillConfig = async (id: number) => { + return await request.get({ url: '/promotion/seckill-config/get?id=' + id }) +} + +// 获得所有开启状态的秒杀时段精简列表 +export const getListAllSimple = async () => { + return await request.get({ url: '/promotion/seckill-config/list-all-simple' }) +} + +// 新增秒杀时段配置 +export const createSeckillConfig = async (data: SeckillConfigVO) => { + return await request.post({ url: '/promotion/seckill-config/create', data }) +} + +// 修改秒杀时段配置 +export const updateSeckillConfig = async (data: SeckillConfigVO) => { + return await request.put({ url: '/promotion/seckill-config/update', data }) +} + +// 修改时段配置状态 +export const updateSeckillConfigStatus = (id: number, status: number) => { + const data = { + id, + status + } + return request.put({ url: '/promotion/seckill-config/update-status', data: data }) +} + +// 删除秒杀时段配置 +export const deleteSeckillConfig = async (id: number) => { + return await request.delete({ url: '/promotion/seckill-config/delete?id=' + id }) +} diff --git a/src/api/mall/trade/delivery/expressTemplate/index.ts b/src/api/mall/trade/delivery/expressTemplate/index.ts index 9414c847..9ed23bc1 100644 --- a/src/api/mall/trade/delivery/expressTemplate/index.ts +++ b/src/api/mall/trade/delivery/expressTemplate/index.ts @@ -33,6 +33,11 @@ export const getDeliveryExpressTemplate = async (id: number) => { return await request.get({ url: '/trade/delivery/express-template/get?id=' + id }) } +// 查询快递运费模板详情 +export const getSimpleTemplateList = async () => { + return await request.get({ url: '/trade/delivery/express-template/list-all-simple' }) +} + // 新增快递运费模板 export const createDeliveryExpressTemplate = async (data: DeliveryExpressTemplateVO) => { return await request.post({ url: '/trade/delivery/express-template/create', data }) @@ -47,8 +52,3 @@ export const updateDeliveryExpressTemplate = async (data: DeliveryExpressTemplat export const deleteDeliveryExpressTemplate = async (id: number) => { return await request.delete({ url: '/trade/delivery/express-template/delete?id=' + id }) } - -// 导出快递运费模板 Excel -export const exportDeliveryExpressTemplateApi = async (params) => { - return await request.download({ url: '/trade/delivery/express-template/export-excel', params }) -} diff --git a/src/api/mall/trade/delivery/pickUpStore/index.ts b/src/api/mall/trade/delivery/pickUpStore/index.ts new file mode 100644 index 00000000..90fb3d01 --- /dev/null +++ b/src/api/mall/trade/delivery/pickUpStore/index.ts @@ -0,0 +1,46 @@ +import request from '@/config/axios' + +export interface DeliveryPickUpStoreVO { + id: number + name: string + introduction: string + phone: string + areaId: number + detailAddress: string + logo: string + openingTime: string + closingTime: string + latitude: number + longitude: number + status: number +} + +// 查询自提门店列表 +export const getDeliveryPickUpStorePage = async (params: DeliveryPickUpStorePageReqVO) => { + return await request.get({ url: '/trade/delivery/pick-up-store/page', params }) +} + +// 查询自提门店详情 +export const getDeliveryPickUpStore = async (id: number) => { + return await request.get({ url: '/trade/delivery/pick-up-store/get?id=' + id }) +} + +// 新增自提门店 +export const createDeliveryPickUpStore = async (data: DeliveryPickUpStoreVO) => { + return await request.post({ url: '/trade/delivery/pick-up-store/create', data }) +} + +// 修改自提门店 +export const updateDeliveryPickUpStore = async (data: DeliveryPickUpStoreVO) => { + return await request.put({ url: '/trade/delivery/pick-up-store/update', data }) +} + +// 删除自提门店 +export const deleteDeliveryPickUpStore = async (id: number) => { + return await request.delete({ url: '/trade/delivery/pick-up-store/delete?id=' + id }) +} + +// 导出自提门店 Excel +export const exportDeliveryPickUpStoreApi = async (params) => { + return await request.download({ url: '/trade/delivery/pick-up-store/export-excel', params }) +} diff --git a/src/api/mall/trade/order/index.ts b/src/api/mall/trade/order/index.ts new file mode 100644 index 00000000..9d0fab2e --- /dev/null +++ b/src/api/mall/trade/order/index.ts @@ -0,0 +1,12 @@ +import request from '@/config/axios' + +// 获得交易订单分页 +// TODO @xiaobai:改成 getOrderPage +export const getOrderList = (params: PageParam) => { + return request.get({ url: '/trade/order/page', params }) +} + +// 获得交易订单详情 +export const getOrderDetail = (id: number) => { + return request.get({ url: '/trade/order/get-detail?id=' + id }) +} diff --git a/src/api/mall/trade/order/type/orderType.ts b/src/api/mall/trade/order/type/orderType.ts new file mode 100644 index 00000000..e5185769 --- /dev/null +++ b/src/api/mall/trade/order/type/orderType.ts @@ -0,0 +1,228 @@ +// TODO @xiaobai:这个放到 order/index.ts 里哈 +// TODO @xiaobai:注释放到变量后面,这样简洁一点 +// TODO @xiaobai:这个改成 TradeOrderRespVO +export interface TradeOrderPageItemRespVO { + // 订单编号 + id?: number + // 订单流水号 + no?: string + // 下单时间 + createTime?: Date + // 订单类型 + type?: number + // 订单来源 + terminal?: number + // 用户编号 + userId?: number + // 用户 IP + userIp?: string + // 用户备注 + userRemark?: string + // 订单状态 + status?: number + // 购买的商品数量 + productCount?: number + // 订单完成时间 + finishTime?: Date + // 订单取消时间 + cancelTime?: Date + // 取消类型 + cancelType?: number + // 商家备注 + remark?: string + // 支付订单编号 + payOrderId: number + // 是否已支付 + payed?: boolean + // 付款时间 + payTime?: Date + // 支付渠道 + payChannelCode?: string + // 商品原价(总) + originalPrice?: number + // 订单原价(总) + orderPrice?: number + // 订单优惠(总) + discountPrice?: number + // 运费金额 + deliveryPrice?: number + // 订单调价(总) + adjustPrice?: number + // 应付金额(总) + payPrice?: number + // 配送模板编号 + deliveryTemplateId?: number + // 发货物流公司编号 + logisticsId?: number + // 发货物流单号 + logisticsNo?: string + // 发货状态 + deliveryStatus?: number + // 发货时间 + deliveryTime?: Date + // 收货时间 + receiveTime?: Date + // 收件人名称 + receiverName?: string + // 收件人手机 + receiverMobile?: string + // 收件人地区编号 + receiverAreaId?: number + // 收件人邮编 + receiverPostCode?: number + // 收件人详细地址 + receiverDetailAddress?: string + // 售后状态 + afterSaleStatus?: number + // 退款金额 + refundPrice?: number + // 优惠劵编号 + couponId?: number + // 优惠劵减免金额 + couponPrice?: number + // 积分抵扣的金额 + pointPrice?: number + //收件人地区名字 + receiverAreaName?: string + // 订单项列表 + items?: TradeOrderItemBaseVO[] + //用户信息 + user?: MemberUserRespDTO +} + +// TODO @xiaobai:这个改成 TradeOrderItemRespVO +/** + * 交易订单项 Base VO,提供给添加、修改、详细的子 VO 使用 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 + */ +export interface TradeOrderItemBaseVO { + // ========== 订单项基本信息 ========== + /** + * 编号 + */ + id?: number + /** + * 用户编号 + */ + userId?: number + /** + * 订单编号 + */ + orderId?: number + // ========== 商品基本信息 ========== + /** + * 商品 SPU 编号 + */ + spuId?: number + /** + * 商品 SPU 名称 + */ + spuName?: string + /** + * 商品 SKU 编号 + */ + skuId?: number + /** + * 商品图片 + */ + picUrl?: string + /** + * 购买数量 + */ + count?: number + // ========== 价格 + 支付基本信息 ========== + /** + * 商品原价(总) + */ + originalPrice?: number + /** + * 商品原价(单) + */ + originalUnitPrice?: number + /** + * 商品优惠(总) + */ + discountPrice?: number + /** + * 商品实付金额(总) + */ + payPrice?: number + /** + * 子订单分摊金额(总) + */ + orderPartPrice?: number + /** + * 分摊后子订单实付金额(总) + */ + orderDividePrice?: number + // ========== 营销基本信息 ========== + // TODO 芋艿:在捉摸一下 + // ========== 售后基本信息 ========== + /** + * 售后状态 + */ + afterSaleStatus?: number + //属性数组 + properties?: ProductPropertyValueDetailRespVO[] +} + +/** + * 管理后台 - 商品属性值的明细 Response VO + */ +export interface ProductPropertyValueDetailRespVO { + /** + * 属性的编号 + */ + propertyId?: number + /** + * 属性的名称 + */ + propertyName?: string + /** + * 属性值的编号 + */ + valueId?: number + /** + * 属性值的名称 + */ + valueName?: string +} + +/** + * 订单详情查询 请求 + */ +export interface TradeOrderPageReqVO { + pageNo: number + pageSize: number + no?: string + userId?: string + userNickname?: string + userMobile?: string + receiverName?: string + receiverMobile?: string + terminal?: string + type?: number + status?: number + payChannelCode?: string + createTime?: [Date, Date] + spuName?: string + itemCount?: string + all?: string +} + +//用户信息 +export interface MemberUserRespDTO { + id?: number + nickname?: string + status?: number + avatar?: string + mobile?: string +} +//订单详情选中type +export interface SelectType { + queryParams: TradeOrderPageReqVO + selectTotal: number //选中的数量 + selectAllFlag: boolean //全选标识 + selectData: Map> //存放涉及选中得页面以及每页选中得数据订单号 全选时根据条件查询 排除取消的list订单 + unSelectList: Set //登记取消的list 全选标识为true 时登记单独取消的list,再次选中时排除, 全选标识为false 时清空list +} diff --git a/src/api/point/config/index.ts b/src/api/point/config/index.ts new file mode 100644 index 00000000..00adc3f1 --- /dev/null +++ b/src/api/point/config/index.ts @@ -0,0 +1,19 @@ +import request from '@/config/axios' + +export interface ConfigVO { + id: number + tradeDeductEnable: number + tradeDeductUnitPrice: number + tradeDeductMaxPrice: number + tradeGivePoint: number +} + +// 查询积分设置详情 +export const getConfig = async () => { + return await request.get({ url: `/point/config/get` }) +} + +// 新增修改积分设置 +export const saveConfig = async (data: ConfigVO) => { + return await request.put({ url: `/point/config/save`, data }) +} diff --git a/src/api/point/record/index.ts b/src/api/point/record/index.ts new file mode 100644 index 00000000..15eaff35 --- /dev/null +++ b/src/api/point/record/index.ts @@ -0,0 +1,47 @@ +import request from '@/config/axios' + +export interface RecordVO { + id: number + bizId: string + bizType: string + type: string + title: string + description: string + point: number + totalPoint: number + status: number + userId: number + freezingTime: Date + thawingTime: Date + createDate: Date +} + +// 查询用户积分记录列表 +export const getRecordPage = async (params) => { + return await request.get({ url: `/point/record/page`, params }) +} + +// 查询用户积分记录详情 +export const getRecord = async (id: number) => { + return await request.get({ url: `/point/record/get?id=` + id }) +} + +// 新增用户积分记录 +export const createRecord = async (data: RecordVO) => { + return await request.post({ url: `/point/record/create`, data }) +} + +// 修改用户积分记录 +export const updateRecord = async (data: RecordVO) => { + return await request.put({ url: `/point/record/update`, data }) +} + +// 删除用户积分记录 +export const deleteRecord = async (id: number) => { + return await request.delete({ url: `/point/record/delete?id=` + id }) +} + +// 导出用户积分记录 Excel +export const exportRecord = async (params) => { + return await request.download({ url: `/point/record/export-excel`, params }) +} diff --git a/src/api/point/signInConfig/index.ts b/src/api/point/signInConfig/index.ts new file mode 100644 index 00000000..3786c06e --- /dev/null +++ b/src/api/point/signInConfig/index.ts @@ -0,0 +1,37 @@ +import request from '@/config/axios' + +export interface SignInConfigVO { + id: number + day: number + point: number +} + +// 查询积分签到规则列表 +export const getSignInConfigPage = async (params) => { + return await request.get({ url: `/point/sign-in-config/page`, params }) +} + +// 查询积分签到规则详情 +export const getSignInConfig = async (id: number) => { + return await request.get({ url: `/point/sign-in-config/get?id=` + id }) +} + +// 新增积分签到规则 +export const createSignInConfig = async (data: SignInConfigVO) => { + return await request.post({ url: `/point/sign-in-config/create`, data }) +} + +// 修改积分签到规则 +export const updateSignInConfig = async (data: SignInConfigVO) => { + return await request.put({ url: `/point/sign-in-config/update`, data }) +} + +// 删除积分签到规则 +export const deleteSignInConfig = async (id: number) => { + return await request.delete({ url: `/point/sign-in-config/delete?id=` + id }) +} + +// 导出积分签到规则 Excel +export const exportSignInConfig = async (params) => { + return await request.download({ url: `/point/sign-in-config/export-excel`, params }) +} diff --git a/src/api/point/signInRecord/index.ts b/src/api/point/signInRecord/index.ts new file mode 100644 index 00000000..0f9b9f64 --- /dev/null +++ b/src/api/point/signInRecord/index.ts @@ -0,0 +1,38 @@ +import request from '@/config/axios' + +export interface SignInRecordVO { + id: number + userId: number + day: number + point: number +} + +// 查询用户签到积分列表 +export const getSignInRecordPage = async (params) => { + return await request.get({ url: `/point/sign-in-record/page`, params }) +} + +// 查询用户签到积分详情 +export const getSignInRecord = async (id: number) => { + return await request.get({ url: `/point/sign-in-record/get?id=` + id }) +} + +// 新增用户签到积分 +export const createSignInRecord = async (data: SignInRecordVO) => { + return await request.post({ url: `/point/sign-in-record/create`, data }) +} + +// 修改用户签到积分 +export const updateSignInRecord = async (data: SignInRecordVO) => { + return await request.put({ url: `/point/sign-in-record/update`, data }) +} + +// 删除用户签到积分 +export const deleteSignInRecord = async (id: number) => { + return await request.delete({ url: `/point/sign-in-record/delete?id=` + id }) +} + +// 导出用户签到积分 Excel +export const exportSignInRecord = async (params) => { + return await request.download({ url: `/point/sign-in-record/export-excel`, params }) +} diff --git a/src/components/Dialog/src/Dialog.vue b/src/components/Dialog/src/Dialog.vue index 449174d9..28deba46 100644 --- a/src/components/Dialog/src/Dialog.vue +++ b/src/components/Dialog/src/Dialog.vue @@ -14,7 +14,7 @@ const props = defineProps({ }) const getBindValue = computed(() => { - const delArr: string[] = ['fullscreen', 'title', 'maxHeight'] + const delArr: string[] = ['fullscreen', 'title', 'maxHeight', 'appendToBody'] const attrs = useAttrs() const obj = { ...attrs, ...props } for (const key in obj) { diff --git a/src/components/Form/src/Form.vue b/src/components/Form/src/Form.vue index c1121641..9742babe 100644 --- a/src/components/Form/src/Form.vue +++ b/src/components/Form/src/Form.vue @@ -1,16 +1,16 @@ diff --git a/src/views/Login/components/QrCodeForm.vue b/src/views/Login/components/QrCodeForm.vue index c485d287..74e4379b 100644 --- a/src/views/Login/components/QrCodeForm.vue +++ b/src/views/Login/components/QrCodeForm.vue @@ -1,5 +1,5 @@