From 7f888c55dbc9a1229dba7c474f13a951516a1996 Mon Sep 17 00:00:00 2001 From: Alaric <161679330+AlaricWeb@users.noreply.github.com> Date: Wed, 13 Mar 2024 09:46:28 +0800 Subject: [PATCH 01/28] Create npm-gulp.yml --- .github/workflows/npm-gulp.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/npm-gulp.yml diff --git a/.github/workflows/npm-gulp.yml b/.github/workflows/npm-gulp.yml new file mode 100644 index 0000000..572444e --- /dev/null +++ b/.github/workflows/npm-gulp.yml @@ -0,0 +1,28 @@ +name: NodeJS with Gulp + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [14.x, 16.x, 18.x] + + steps: + - uses: actions/checkout@v3 + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + + - name: Build + run: | + npm install + gulp From c0c92eb7b451d484059aa93dadee155dd58eaee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A7=E5=A4=A7=E6=80=AA?= Date: Wed, 13 Mar 2024 09:55:51 +0800 Subject: [PATCH 02/28] init github page --- .github/workflows/npm-gulp.yml | 74 +++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 19 deletions(-) diff --git a/.github/workflows/npm-gulp.yml b/.github/workflows/npm-gulp.yml index 572444e..931eeb1 100644 --- a/.github/workflows/npm-gulp.yml +++ b/.github/workflows/npm-gulp.yml @@ -1,28 +1,64 @@ -name: NodeJS with Gulp +# 构建 VitePress 站点并将其部署到 GitHub Pages 的示例工作流程 +# +name: Deploy VitePress site to Pages on: + # 在针对 `main` 分支的推送上运行。如果你 + # 使用 `master` 分支作为默认分支,请将其更改为 `master` push: - branches: [ "master" ] - pull_request: - branches: [ "master" ] + branches: [master] + + # 允许你从 Actions 选项卡手动运行此工作流程 + workflow_dispatch: + +# 设置 GITHUB_TOKEN 的权限,以允许部署到 GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# 只允许同时进行一次部署,跳过正在运行和最新队列之间的运行队列 +# 但是,不要取消正在进行的运行,因为我们希望允许这些生产部署完成 +concurrency: + group: pages + cancel-in-progress: false jobs: + # 构建工作 build: runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [14.x, 16.x, 18.x] - steps: - - uses: actions/checkout@v3 - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 # 如果未启用 lastUpdated,则不需要 + - uses: pnpm/action-setup@v3 # 如果使用 pnpm,请取消注释 + # - uses: oven-sh/setup-bun@v1 # 如果使用 Bun,请取消注释 + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: pnpm # 或 pnpm / yarn + - name: Setup Pages + uses: actions/configure-pages@v4 + - name: Install dependencies + run: pnpm ci # 或 pnpm install / yarn install / bun install + - name: Build with ems + run: pnpm run build # 或 pnpm docs:build / yarn docs:build / bun run docs:build + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: dist - - name: Build - run: | - npm install - gulp + # 部署工作 + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + needs: build + runs-on: ubuntu-latest + name: Deploy + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 \ No newline at end of file From 36481709aabed775b95607072625be77b7b9a1a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A7=E5=A4=A7=E6=80=AA?= Date: Wed, 13 Mar 2024 09:58:44 +0800 Subject: [PATCH 03/28] test --- .github/workflows/npm-gulp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/npm-gulp.yml b/.github/workflows/npm-gulp.yml index 931eeb1..31684d0 100644 --- a/.github/workflows/npm-gulp.yml +++ b/.github/workflows/npm-gulp.yml @@ -42,7 +42,7 @@ jobs: - name: Setup Pages uses: actions/configure-pages@v4 - name: Install dependencies - run: pnpm ci # 或 pnpm install / yarn install / bun install + run: pnpm install # 或 pnpm install / yarn install / bun install - name: Build with ems run: pnpm run build # 或 pnpm docs:build / yarn docs:build / bun run docs:build - name: Upload artifact From 80b7ee6e9173298a2592abe09ffc7fb457fc2f8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A7=E5=A4=A7=E6=80=AA?= Date: Wed, 13 Mar 2024 10:00:54 +0800 Subject: [PATCH 04/28] 333 --- .github/workflows/{npm-gulp.yml => pnpm.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{npm-gulp.yml => pnpm.yml} (100%) diff --git a/.github/workflows/npm-gulp.yml b/.github/workflows/pnpm.yml similarity index 100% rename from .github/workflows/npm-gulp.yml rename to .github/workflows/pnpm.yml From c40cd03ad9589813b3b314153ce1f2303443a53d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A7=E5=A4=A7=E6=80=AA?= Date: Thu, 14 Mar 2024 09:35:00 +0800 Subject: [PATCH 05/28] date --- .github/workflows/{pnpm.yml => pnpm .yml} | 0 mock/auth/menu.mock.ts | 177 +++++++------------ mock/auth/role.mock.ts | 125 +++++++------- mock/auth/user.mock.ts | 119 +++++++------ mock/database/auth.ts | 87 ++++++++++ mock/utils.ts | 15 +- src/router/index.ts | 2 +- src/utils/tools.ts | 29 ++++ src/views/system/menu/Editor.vue | 128 ++++++++++++++ src/views/system/menu/index.vue | 199 +++++++++++++++++++++- tsconfig.node.json | 4 +- vite.config.ts | 14 +- 12 files changed, 641 insertions(+), 258 deletions(-) rename .github/workflows/{pnpm.yml => pnpm .yml} (100%) create mode 100644 mock/database/auth.ts create mode 100644 src/utils/tools.ts create mode 100644 src/views/system/menu/Editor.vue diff --git a/.github/workflows/pnpm.yml b/.github/workflows/pnpm .yml similarity index 100% rename from .github/workflows/pnpm.yml rename to .github/workflows/pnpm .yml diff --git a/mock/auth/menu.mock.ts b/mock/auth/menu.mock.ts index 9152e8c..dcd2348 100644 --- a/mock/auth/menu.mock.ts +++ b/mock/auth/menu.mock.ts @@ -1,122 +1,69 @@ import { definePostMock } from "../config"; -import Mock from 'mockjs' -export const menu = [ - { - id: 1, - name: '控制台', - route_path: "/console", - parent_id: 0, - icon: "mingcute:confused-fill" - }, - { - id: 2, - name: '工单管理', - route_path: "/console", - parent_id: 0, - icon: "mingcute:confused-fill" - }, - { - id: 3, - name: '企业管理', - route_path: "/system/user", - parent_id: 0, - icon: "mingcute:confused-fill" - }, - { - id: 4, - name: '角色管理', - route_path: "/system/role", - parent_id: 3, - icon: "mingcute:confused-fill" - }, - { - id: 5, - name: '测试', - route_path: "/system/role", - parent_id: 3, - icon: "mingcute:confused-fill" - } -] -const findItem = (where: T) => { - return menu.find((item) => { - return Object.keys(where).every((key) => { - return item[key] === where[key] - }) - }) -} -const findList = (where: T) => { - return menu.filter((item) => { - return Object.keys(where).every((key) => { - return item[key] === where[key] - }) - }) -} -export const user = Mock.mock({ - "total|1-1000": 1, - 'list|10': [ - { - 'id|+1': 1, - name: "@cname", - created_at: "@datetime", - updated_at: "@datetime", - } - ] -}) +import Mock from "mockjs"; +import { page, where } from "../utils"; +import { menu } from "../database/auth"; +w; export default definePostMock([ - { - url: '/system/menu', - method: "GET", - delay: 1000, - body(request) { - const { page, limit } = request.query; - const start = (page - 1) * limit; - const end = start + parseInt(limit);; - return { - total: user.list.length, - list: user.list.slice(start, end) - } - } + { + url: "/system/menu", + method: "GET", + delay: 500, + body(request) { + let parent_id: number = request.query.parent_id || 0; + parent_id = + typeof parent_id === "string" ? parseInt(parent_id) : parent_id; + const result = where(menu, { parent_id }); + if (parent_id) { + return { + list: result, + }; + } + return { + total: result.length, + list: page(result, request.query.page, request.query.limit), + }; }, - { - url: '/system/menu/:id', - method: "GET", - body(request) { - const id = request.params.id as number - if (id && user.list[id - 1]) return user.list[id - 1] - return { - error_code: 400, - msg: 'author not found', - } - - } + }, + { + url: "/system/menu/:id", + method: "GET", + body(request) { + const id = request.params.id as number; + if (id && menu[id - 1]) return menu[id - 1]; + return { + error_code: 400, + msg: "author not found", + }; }, - { - url: '/system/menu', - method: "POST", - body(request) { - request.body.id = Mock.Random.integer(); - user.list.push(request.body); - return request.body - } + }, + { + url: "/system/menu", + method: "POST", + body(request) { + request.body.id = Mock.Random.integer(); + menu.push(request.body); + + return request.body; }, - { - url: '/system/menu/:id', - method: "PUT", - body(request) { - // user.list[] - const id = request.params.id as number - user.list[id - 1] = Object.assign(user.list[id - 1], request.body) - return user.list[id - 1] - } + }, + { + url: "/system/menu/:id", + method: "PUT", + body(request) { + // menu[] + const id = request.params.id as number; + menu[id - 1] = Object.assign(menu[id - 1], request.body); + return menu[id - 1]; }, - { - url: '/system/menu/:id', - method: "DELETE", - body(request) { - // user.list[] - const id = request.params.id as number - user.list.splice(id - 1, 1); - return user.list[id - 1]; - } + }, + { + url: "/system/menu/:id", + method: "DELETE", + body(request) { + // menu[] + const id = request.params.id as number; + menu.splice(id - 1, 1); + return menu[id - 1]; }, -]) \ No newline at end of file + }, +]); diff --git a/mock/auth/role.mock.ts b/mock/auth/role.mock.ts index 90e7cd0..a83014e 100644 --- a/mock/auth/role.mock.ts +++ b/mock/auth/role.mock.ts @@ -1,72 +1,71 @@ import { definePostMock } from "../config"; -import Mock from 'mockjs' +import Mock from "mockjs"; import { page } from "../utils"; export const user = Mock.mock({ - "total|100-1000": 1, - 'list|100': [ - { - 'id|+1': 1, - "name": "@name", - "system_menu_ids": '@range(1, 10, 3)', - "desc": "@paragraph", - created_at: "@datetime", - updated_at: "@datetime", - } - ] -}) -export default definePostMock([ + "total|100-1000": 1, + "list|100": [ { - url: '/system/role', - method: "GET", - delay: 1000, - body(request) { - const { page: start, limit } = request.query; - return { - total: user.list.length, - list: page(user.list, start, limit) - } - } + "id|+1": 1, + name: "@name", + system_menu_ids: "@range(1, 10, 3)", + desc: "@paragraph", + created_at: "@datetime", + updated_at: "@datetime", }, - { - url: '/system/role/:id', - method: "GET", - body(request) { - const id = request.params.id as number - if (id && user.list[id - 1]) return user.list[id - 1] - return { - error_code: 400, - msg: 'author not found', - } - - } + ], +}); +export default definePostMock([ + { + url: "/system/role", + method: "GET", + delay: 1000, + body(request) { + const { page: start, limit } = request.query; + return { + total: user.list.length, + list: page(user.list, start, limit), + }; }, - { - url: '/system/role', - method: "POST", - body(request) { - request.body.id = Mock.Random.integer(); - user.list.push(request.body); - return request.body - } + }, + { + url: "/system/role/:id", + method: "GET", + body(request) { + const id = request.params.id as number; + if (id && user.list[id - 1]) return user.list[id - 1]; + return { + error_code: 400, + msg: "author not found", + }; }, - { - url: '/system/role/:id', - method: "PUT", - body(request) { - // user.list[] - const id = request.params.id as number - user.list[id - 1] = Object.assign(user.list[id - 1], request.body) - return user.list[id - 1] - } + }, + { + url: "/system/role", + method: "POST", + body(request) { + request.body.id = Mock.Random.integer(); + user.list.push(request.body); + return request.body; }, - { - url: '/system/role/:id', - method: "DELETE", - body(request) { - // user.list[] - const id = request.params.id as number - user.list.splice(id - 1, 1); - return user.list[id - 1]; - } + }, + { + url: "/system/role/:id", + method: "PUT", + body(request) { + // user.list[] + const id = request.params.id as number; + user.list[id - 1] = Object.assign(user.list[id - 1], request.body); + return user.list[id - 1]; + }, + }, + { + url: "/system/role/:id", + method: "DELETE", + body(request) { + // user.list[] + const id = request.params.id as number; + user.list.splice(id - 1, 1); + return user.list[id - 1]; }, -]) \ No newline at end of file + }, +]); diff --git a/mock/auth/user.mock.ts b/mock/auth/user.mock.ts index d2bcf77..a72a892 100644 --- a/mock/auth/user.mock.ts +++ b/mock/auth/user.mock.ts @@ -1,68 +1,67 @@ import { definePostMock } from "../config"; -import Mock from 'mockjs' +import Mock from "mockjs"; export const user = Mock.mock({ - "total|1-1000": 1, - 'list|10': [ - { - 'id|+1': 1, - "nickname": "@cname", - "avatar": "https://cdn.seovx.com/d/?mom=302", - "system_role_id|1-6": 1, - "account": "@name", - created_at: "@datetime", - updated_at: "@datetime", - } - ] -}) -export default definePostMock([ + "total|1-1000": 1, + "list|10": [ { - url: '/system/user', - method: "GET", - body: { - total: user.total, - list: user.list - } + "id|+1": 1, + nickname: "@cname", + avatar: "https://cdn.seovx.com/d/?mom=302", + "system_role_id|1-6": 1, + account: "@name", + created_at: "@datetime", + updated_at: "@datetime", }, - { - url: '/system/user/:id', - method: "GET", - body(request) { - const id = request.params.id as number - if (id && user.list[id - 1]) return user.list[id - 1] - return { - error_code: 400, - msg: 'author not found', - } - - } + ], +}); +export default definePostMock([ + { + url: "/system/user", + method: "GET", + body: { + total: user.total, + list: user.list, }, - { - url: '/system/user', - method: "POST", - body(request) { - request.body.id = Mock.Random.integer('100-1000'); - user.list.push(request.body); - return request.body - } + }, + { + url: "/system/user/:id", + method: "GET", + body(request) { + const id = request.params.id as number; + if (id && user.list[id - 1]) return user.list[id - 1]; + return { + error_code: 400, + msg: "author not found", + }; }, - { - url: '/system/user/:id', - method: "PUT", - body(request) { - // user.list[] - const id = request.params.id as number - user.list[id - 1] = Object.assign(user.list[id - 1], request.body) - return user.list[id - 1] - } + }, + { + url: "/system/user", + method: "POST", + body(request) { + request.body.id = Mock.Random.integer(); + user.list.push(request.body); + return request.body; }, - { - url: '/system/user/:id', - method: "DELETE", - body(request) { - // user.list[] - const id = request.params.id as number - user.list.splice(id - 1, 1); - return user.list[id - 1]; - } + }, + { + url: "/system/user/:id", + method: "PUT", + body(request) { + // user.list[] + const id = request.params.id as number; + user.list[id - 1] = Object.assign(user.list[id - 1], request.body); + return user.list[id - 1]; + }, + }, + { + url: "/system/user/:id", + method: "DELETE", + body(request) { + // user.list[] + const id = request.params.id as number; + user.list.splice(id - 1, 1); + return user.list[id - 1]; }, -]) \ No newline at end of file + }, +]); diff --git a/mock/database/auth.ts b/mock/database/auth.ts new file mode 100644 index 0000000..14a348a --- /dev/null +++ b/mock/database/auth.ts @@ -0,0 +1,87 @@ +import Mock from "mockjs"; +interface Menu { + id: number; + name: string; + route_path: string; + parent_id: number; + icon: string; + has_children?: boolean; + created_at: string; + updated_at: string; +} +export function menu(): Array { + return [ + { + id: 1, + name: "控制台", + route_path: "/console", + parent_id: 0, + icon: "mingcute:confused-fill", + created_at: Mock.Random.datetime(), + updated_at: Mock.Random.datetime(), + }, + { + id: 2, + name: "工单管理", + route_path: "/console", + parent_id: 0, + icon: "mingcute:confused-fill", + created_at: Mock.Random.datetime(), + updated_at: Mock.Random.datetime(), + }, + { + id: 3, + name: "企业设置", + route_path: "/system/menu", + parent_id: 0, + icon: "mingcute:confused-fill", + has_children: true, + created_at: Mock.Random.datetime(), + updated_at: Mock.Random.datetime(), + }, + { + id: 4, + name: "故障类型", + route_path: "", + parent_id: 3, + icon: "mingcute:confused-fill", + has_children: false, + created_at: Mock.Random.datetime(), + updated_at: Mock.Random.datetime(), + }, + { + id: 5, + name: "保修部门", + route_path: "", + parent_id: 3, + icon: "mingcute:confused-fill", + has_children: false, + created_at: Mock.Random.datetime(), + updated_at: Mock.Random.datetime(), + }, + ]; +} +export function user() { + return [ + { + id: 1, + username: "admin", + password: "", + nickname: "管理员", + role_id: 1, + created_at: Mock.Random.datetime(), + updated_at: Mock.Random.datetime(), + }, + ]; +} +export function role() { + return [ + { + id: 1, + name: "超级管理员", + desc: "拥有最高权限", + created_at: Mock.Random.datetime(), + updated_at: Mock.Random.datetime(), + }, + ]; +} diff --git a/mock/utils.ts b/mock/utils.ts index 76974c1..616d333 100644 --- a/mock/utils.ts +++ b/mock/utils.ts @@ -1,14 +1,15 @@ -export function where(node: T[], condition: T) { - return node.filter(item => { - Object.keys(item).every(key => { +export function where(node: T[], condition: Partial) { + return node.filter((item) => { + return Object.keys(condition).every((key) => { return item[key] === condition[key] }) }) + } -export function find(node: T[], condition: T): T | undefined { - return node.find(item => { - Object.keys(item).every(key => { +export function find(node: T[], condition: Partial): T | undefined { + return node.find((item) => { + return Object.keys(condition).every((key) => { return item[key] === condition[key] }) }) @@ -25,8 +26,6 @@ export function page(node: T[], page: number = 1, limit: any = const start = (page - 1) * limit; let end = start + limit; if (end > node.length) end = node.length; - console.log(start, end); - return node.slice(start, end); } diff --git a/src/router/index.ts b/src/router/index.ts index 4c84769..c1900ee 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -22,7 +22,7 @@ const router = createRouter({ children: [ { path: '/console', - component: () => import('@/views/Console.vue') + component: () => import('@/views/console.vue') }, ...autoView ] diff --git a/src/utils/tools.ts b/src/utils/tools.ts new file mode 100644 index 0000000..439a97d --- /dev/null +++ b/src/utils/tools.ts @@ -0,0 +1,29 @@ +import { customRef } from "vue"; +export function deepCopy(source: T) { + const newObj = {}; + const obj = Object.keys(source); + for (const key of obj) { + if (typeof source[key] === "object") { + newObj[key] = deepCopy(source[key]); + } + newObj[key] = source[key]; + } + return newObj; +} + +export function FormReactive(value: T) { + return customRef((track, trigger) => { + return { + get() { + track(); + console.log(value); + + return value; + }, + set(newValue) { + console.log(newValue); + value = newValue; + }, + }; + }); +} diff --git a/src/views/system/menu/Editor.vue b/src/views/system/menu/Editor.vue new file mode 100644 index 0000000..80c9c67 --- /dev/null +++ b/src/views/system/menu/Editor.vue @@ -0,0 +1,128 @@ + + diff --git a/src/views/system/menu/index.vue b/src/views/system/menu/index.vue index fab6083..b1c1400 100644 --- a/src/views/system/menu/index.vue +++ b/src/views/system/menu/index.vue @@ -1,3 +1,198 @@ + \ No newline at end of file +
+ +
+ + + +
+
+ + + + + + + + + + + + +
+ + + + +
+ + diff --git a/tsconfig.node.json b/tsconfig.node.json index 2ea6042..0c5dfa2 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -5,8 +5,8 @@ "vitest.config.*", "cypress.config.*", "nightwatch.conf.*", - "playwright.config.*" - + "playwright.config.*", + "mock/**/*.js", ], "compilerOptions": { "composite": true, diff --git a/vite.config.ts b/vite.config.ts index 148c1ae..bdcc49a 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,7 +1,7 @@ import { fileURLToPath, URL } from "node:url"; import { ConfigEnv, defineConfig, loadEnv, UserConfigExport } from "vite"; import vue from "@vitejs/plugin-vue"; -import mockDevServerPlugin from 'vite-plugin-mock-dev-server' +import mockDevServerPlugin from "vite-plugin-mock-dev-server"; import inspect from "vite-plugin-inspect"; // https://vitejs.dev/config/ export default defineConfig(({ mode }) => { @@ -11,21 +11,21 @@ export default defineConfig(({ mode }) => { vue(), inspect(), mockDevServerPlugin({ - reload: true + prefix: env.VITE_BASE_URL, }), ], server: { host: true, proxy: { [env.VITE_BASE_URL]: { - target: env.VITE_API_URL - } - } + target: env.VITE_API_URL, + }, + }, }, resolve: { alias: { "@": fileURLToPath(new URL("./src", import.meta.url)), }, }, - } -}); \ No newline at end of file + }; +}); From c0779267026c5fd68708a5d24c8cd01380a7aa89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A7=E5=A4=A7=E6=80=AA?= Date: Thu, 14 Mar 2024 10:14:56 +0800 Subject: [PATCH 06/28] first commit test --- mock/auth/menu.mock.ts | 5 +- mock/auth/role.mock.ts | 2 +- mock/database/auth.ts | 102 ++++++++++++++++++++--------------------- 3 files changed, 53 insertions(+), 56 deletions(-) diff --git a/mock/auth/menu.mock.ts b/mock/auth/menu.mock.ts index dcd2348..85d4299 100644 --- a/mock/auth/menu.mock.ts +++ b/mock/auth/menu.mock.ts @@ -2,7 +2,7 @@ import { definePostMock } from "../config"; import Mock from "mockjs"; import { page, where } from "../utils"; import { menu } from "../database/auth"; -w; + export default definePostMock([ { url: "/system/menu", @@ -39,10 +39,9 @@ export default definePostMock([ { url: "/system/menu", method: "POST", - body(request) { + body(request: { body: any }) { request.body.id = Mock.Random.integer(); menu.push(request.body); - return request.body; }, }, diff --git a/mock/auth/role.mock.ts b/mock/auth/role.mock.ts index a83014e..371d04c 100644 --- a/mock/auth/role.mock.ts +++ b/mock/auth/role.mock.ts @@ -14,6 +14,7 @@ export const user = Mock.mock({ }, ], }); + export default definePostMock([ { url: "/system/role", @@ -23,7 +24,6 @@ export default definePostMock([ const { page: start, limit } = request.query; return { total: user.list.length, - list: page(user.list, start, limit), }; }, }, diff --git a/mock/database/auth.ts b/mock/database/auth.ts index 14a348a..d7156ce 100644 --- a/mock/database/auth.ts +++ b/mock/database/auth.ts @@ -9,58 +9,56 @@ interface Menu { created_at: string; updated_at: string; } -export function menu(): Array { - return [ - { - id: 1, - name: "控制台", - route_path: "/console", - parent_id: 0, - icon: "mingcute:confused-fill", - created_at: Mock.Random.datetime(), - updated_at: Mock.Random.datetime(), - }, - { - id: 2, - name: "工单管理", - route_path: "/console", - parent_id: 0, - icon: "mingcute:confused-fill", - created_at: Mock.Random.datetime(), - updated_at: Mock.Random.datetime(), - }, - { - id: 3, - name: "企业设置", - route_path: "/system/menu", - parent_id: 0, - icon: "mingcute:confused-fill", - has_children: true, - created_at: Mock.Random.datetime(), - updated_at: Mock.Random.datetime(), - }, - { - id: 4, - name: "故障类型", - route_path: "", - parent_id: 3, - icon: "mingcute:confused-fill", - has_children: false, - created_at: Mock.Random.datetime(), - updated_at: Mock.Random.datetime(), - }, - { - id: 5, - name: "保修部门", - route_path: "", - parent_id: 3, - icon: "mingcute:confused-fill", - has_children: false, - created_at: Mock.Random.datetime(), - updated_at: Mock.Random.datetime(), - }, - ]; -} +export const menu: Array = [ + { + id: 1, + name: "控制台", + route_path: "/console", + parent_id: 0, + icon: "mingcute:confused-fill", + created_at: Mock.Random.datetime(), + updated_at: Mock.Random.datetime(), + }, + { + id: 2, + name: "工单管理", + route_path: "/console", + parent_id: 0, + icon: "mingcute:confused-fill", + created_at: Mock.Random.datetime(), + updated_at: Mock.Random.datetime(), + }, + { + id: 3, + name: "企业设置", + route_path: "/system/menu", + parent_id: 0, + icon: "mingcute:confused-fill", + has_children: true, + created_at: Mock.Random.datetime(), + updated_at: Mock.Random.datetime(), + }, + { + id: 4, + name: "故障类型", + route_path: "", + parent_id: 3, + icon: "mingcute:confused-fill", + has_children: false, + created_at: Mock.Random.datetime(), + updated_at: Mock.Random.datetime(), + }, + { + id: 5, + name: "保修部门", + route_path: "", + parent_id: 3, + icon: "mingcute:confused-fill", + has_children: false, + created_at: Mock.Random.datetime(), + updated_at: Mock.Random.datetime(), + }, +]; export function user() { return [ { From d37230cc4b9c9a8fe476bc1fbbab0209a32a9b18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A7=E5=A4=A7=E6=80=AA?= Date: Thu, 14 Mar 2024 11:47:21 +0800 Subject: [PATCH 07/28] date --- mock/auth/menu.mock.ts | 2 +- mock/auth/user.mock.ts | 15 +- mock/database/auth.ts | 36 +- mock/login.mock.ts | 1161 +++++++++++++++--------------- src/views/system/user/Editor.vue | 53 ++ src/views/system/user/index.vue | 183 ++++- 6 files changed, 823 insertions(+), 627 deletions(-) create mode 100644 src/views/system/user/Editor.vue diff --git a/mock/auth/menu.mock.ts b/mock/auth/menu.mock.ts index 85d4299..88c6f2b 100644 --- a/mock/auth/menu.mock.ts +++ b/mock/auth/menu.mock.ts @@ -2,7 +2,6 @@ import { definePostMock } from "../config"; import Mock from "mockjs"; import { page, where } from "../utils"; import { menu } from "../database/auth"; - export default definePostMock([ { url: "/system/menu", @@ -12,6 +11,7 @@ export default definePostMock([ let parent_id: number = request.query.parent_id || 0; parent_id = typeof parent_id === "string" ? parseInt(parent_id) : parent_id; + const result = where(menu, { parent_id }); if (parent_id) { return { diff --git a/mock/auth/user.mock.ts b/mock/auth/user.mock.ts index a72a892..812662a 100644 --- a/mock/auth/user.mock.ts +++ b/mock/auth/user.mock.ts @@ -1,19 +1,6 @@ import { definePostMock } from "../config"; +import { user } from "../database/auth"; import Mock from "mockjs"; -export const user = Mock.mock({ - "total|1-1000": 1, - "list|10": [ - { - "id|+1": 1, - nickname: "@cname", - avatar: "https://cdn.seovx.com/d/?mom=302", - "system_role_id|1-6": 1, - account: "@name", - created_at: "@datetime", - updated_at: "@datetime", - }, - ], -}); export default definePostMock([ { url: "/system/user", diff --git a/mock/database/auth.ts b/mock/database/auth.ts index d7156ce..425bfb9 100644 --- a/mock/database/auth.ts +++ b/mock/database/auth.ts @@ -59,27 +59,19 @@ export const menu: Array = [ updated_at: Mock.Random.datetime(), }, ]; -export function user() { - return [ +export const user = Mock.mock({ + "total|1-1000": 1, + "list|10": [ { - id: 1, - username: "admin", - password: "", - nickname: "管理员", - role_id: 1, - created_at: Mock.Random.datetime(), - updated_at: Mock.Random.datetime(), + "id|+1": 1, + nickname: "@cname", + avatar: "https://cdn.seovx.com/d/?mom=302", + "system_role_id|1-6": 1, + account: "@name", + "role_name|1": ["超级管理员", "管理员", "员工"], + "sex|1": ["男", "女"], + created_at: "@datetime", + updated_at: "@datetime", }, - ]; -} -export function role() { - return [ - { - id: 1, - name: "超级管理员", - desc: "拥有最高权限", - created_at: Mock.Random.datetime(), - updated_at: Mock.Random.datetime(), - }, - ]; -} + ], +}); diff --git a/mock/login.mock.ts b/mock/login.mock.ts index 42715a0..627c437 100644 --- a/mock/login.mock.ts +++ b/mock/login.mock.ts @@ -1,588 +1,589 @@ import { definePostMock } from "./config"; -import { user } from "./auth/user.mock"; +import { user } from "./database/auth"; const menu = [ - { - name: "控制台", - route_path: "/console", - icon: "mingcute:abs-line" - }, - { - "id": 1, - "name": "工单管理", - "parent_id": 0, - "route_path": "/work/order", - "sort": 0, - "status": 0, - "icon": "mingcute:ad-rectangle-fill", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - }, - { - "id": 2, - "name": "企业设置", - "parent_id": 0, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "mingcute:compass-line", - "type": 0, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": true, - "children": [ - { - "id": 3, - "name": "故障类型", - "parent_id": 2, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - }, - { - "id": 4, - "name": "报修部门", - "parent_id": 2, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - }, - { - "id": 5, - "name": "报修单位", - "parent_id": 2, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - }, - { - "id": 6, - "name": "报修区域", - "parent_id": 2, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - } - ] - }, - { - "id": 7, - "name": "设备管理", - "parent_id": 0, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "mingcute:device-line", - "type": 0, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": true, - "children": [ - { - "id": 8, - "name": "设备列表", - "parent_id": 7, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - }, - { - "id": 9, - "name": "设备分类", - "parent_id": 7, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - } - ] - }, - { - "id": 10, - "name": "耗材管理", - "parent_id": 0, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "mingcute:rabbit-fill", - "type": 0, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": true, - "children": [ - { - "id": 11, - "name": "我的耗材", - "parent_id": 10, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - }, - { - "id": 12, - "name": "耗材列表", - "parent_id": 10, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - }, - { - "id": 13, - "name": "申领列表", - "parent_id": 10, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - }, - { - "id": 14, - "name": "历史入库", - "parent_id": 10, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - }, - { - "id": 15, - "name": "盘点记录", - "parent_id": 10, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - }, - { - "id": 16, - "name": "折损记录", - "parent_id": 10, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - }, - { - "id": 17, - "name": "耗材维护", - "parent_id": 10, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 0, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": true, - "children": [ - { - "id": 18, - "name": "耗材分类", - "parent_id": 17, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - }, - { - "id": 19, - "name": "生产厂商", - "parent_id": 17, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - }, - { - "id": 20, - "name": "供应商", - "parent_id": 17, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - }, - { - "id": 21, - "name": "仓库地址", - "parent_id": 17, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - } - ] - }, - { - "id": 22, - "name": "耗材报告", - "parent_id": 10, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - } - ] - }, - { - "id": 23, - "name": "巡检管理", - "parent_id": 0, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "mingcute:time-fill", - "type": 0, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": true, - "children": [ - { - "id": 24, - "name": "区域管理", - "parent_id": 23, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - }, - { - "id": 25, - "name": "巡检任务", - "parent_id": 23, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - }, - { - "id": 26, - "name": "巡检记录", - "parent_id": 23, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - } - ] - }, - { - "id": 27, - "name": "维修经验", - "parent_id": 0, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "mingcute:settings-6-line", - "type": 0, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": true, - "children": [ - { - "id": 28, - "name": "文章列表", - "parent_id": 27, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - }, - { - "id": 29, - "name": "知识分类", - "parent_id": 27, - "route_path": "", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - } - ] - }, - { - "id": 32, - "name": "个人中心", - "parent_id": 0, - "route_path": "/repassword", - "sort": 0, - "status": 0, - "icon": "mingcute:user-2-line", - "type": 0, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - }, - { - "id": 33, - "name": "权限管理", - "parent_id": 0, - "route_path": "/system/auth", - "sort": 0, - "status": 0, - "icon": "mingcute:auto-hold-fill", - "type": 0, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": true, - "children": [ - { - "id": 34, - "name": "管理员", - "parent_id": 33, - "route_path": "/system/user", - "sort": 0, - "status": 0, - "icon": "", - "type": 0, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": true, - }, - { - "id": 39, - "name": "系统菜单", - "parent_id": 33, - "route_path": "/system/menu", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - }, - { - "id": 40, - "name": "管理员角色", - "parent_id": 33, - "route_path": "/system/role", - "sort": 0, - "status": 0, - "icon": "", - "type": 1, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - } - ] - }, - { - "id": 41, - "name": "在线留言", - "parent_id": 0, - "route_path": "/foodback", - "sort": 0, - "status": 0, - "icon": "mingcute:list-check-2-fill", - "type": 0, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - }, - { - "id": 30, - "name": "设置", - "parent_id": 0, - "route_path": "/system", - "sort": 255, - "status": 0, - "icon": "mingcute:settings-1-line", - "type": 0, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": true, - "children": [ - { - "id": 31, - "name": "系统配置", - "parent_id": 30, - "route_path": "/config/base", - "sort": 0, - "status": 0, - "icon": "", - "type": 0, - "deleted_at": null, - "created_at": "2024-03-03 20:09:24", - "updated_at": "2024-03-03 20:09:24", - "has_children": false - } - ] - }, - { - name: "意见反馈", - parent_id: 0, - route_path: "/feedback", + { + name: "控制台", + route_path: "/console", + icon: "mingcute:abs-line", + }, + { + id: 1, + name: "工单管理", + parent_id: 0, + route_path: "/work/order", + sort: 0, + status: 0, + icon: "mingcute:ad-rectangle-fill", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + { + id: 2, + name: "企业设置", + parent_id: 0, + route_path: "", + sort: 0, + status: 0, + icon: "mingcute:compass-line", + type: 0, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: true, + children: [ + { + id: 3, + name: "故障类型", + parent_id: 2, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + { + id: 4, + name: "报修部门", + parent_id: 2, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + { + id: 5, + name: "报修单位", + parent_id: 2, + route_path: "", sort: 0, status: 0, - icon: "mingcute:feeder-fill", - } + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + { + id: 6, + name: "报修区域", + parent_id: 2, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + ], + }, + { + id: 7, + name: "设备管理", + parent_id: 0, + route_path: "", + sort: 0, + status: 0, + icon: "mingcute:device-line", + type: 0, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: true, + children: [ + { + id: 8, + name: "设备列表", + parent_id: 7, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + { + id: 9, + name: "设备分类", + parent_id: 7, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + ], + }, + { + id: 10, + name: "耗材管理", + parent_id: 0, + route_path: "", + sort: 0, + status: 0, + icon: "mingcute:rabbit-fill", + type: 0, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: true, + children: [ + { + id: 11, + name: "我的耗材", + parent_id: 10, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + { + id: 12, + name: "耗材列表", + parent_id: 10, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + { + id: 13, + name: "申领列表", + parent_id: 10, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + { + id: 14, + name: "历史入库", + parent_id: 10, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + { + id: 15, + name: "盘点记录", + parent_id: 10, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + { + id: 16, + name: "折损记录", + parent_id: 10, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + { + id: 17, + name: "耗材维护", + parent_id: 10, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 0, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: true, + children: [ + { + id: 18, + name: "耗材分类", + parent_id: 17, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + { + id: 19, + name: "生产厂商", + parent_id: 17, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + { + id: 20, + name: "供应商", + parent_id: 17, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + { + id: 21, + name: "仓库地址", + parent_id: 17, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + ], + }, + { + id: 22, + name: "耗材报告", + parent_id: 10, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + ], + }, + { + id: 23, + name: "巡检管理", + parent_id: 0, + route_path: "", + sort: 0, + status: 0, + icon: "mingcute:time-fill", + type: 0, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: true, + children: [ + { + id: 24, + name: "区域管理", + parent_id: 23, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + { + id: 25, + name: "巡检任务", + parent_id: 23, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + { + id: 26, + name: "巡检记录", + parent_id: 23, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + ], + }, + { + id: 27, + name: "维修经验", + parent_id: 0, + route_path: "", + sort: 0, + status: 0, + icon: "mingcute:settings-6-line", + type: 0, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: true, + children: [ + { + id: 28, + name: "文章列表", + parent_id: 27, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + { + id: 29, + name: "知识分类", + parent_id: 27, + route_path: "", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + ], + }, + { + id: 32, + name: "个人中心", + parent_id: 0, + route_path: "/repassword", + sort: 0, + status: 0, + icon: "mingcute:user-2-line", + type: 0, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + + { + id: 33, + name: "权限管理", + parent_id: 0, + route_path: "/system/auth", + sort: 0, + status: 0, + icon: "mingcute:auto-hold-fill", + type: 0, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: true, + children: [ + { + id: 34, + name: "管理员", + parent_id: 33, + route_path: "/system/user", + sort: 0, + status: 0, + icon: "", + type: 0, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: true, + }, + + { + id: 39, + name: "系统菜单", + parent_id: 33, + route_path: "/system/menu", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + { + id: 40, + name: "管理员角色", + parent_id: 33, + route_path: "/system/role", + sort: 0, + status: 0, + icon: "", + type: 1, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + ], + }, + { + id: 41, + name: "在线留言", + parent_id: 0, + route_path: "/foodback", + sort: 0, + status: 0, + icon: "mingcute:list-check-2-fill", + type: 0, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + { + id: 30, + name: "设置", + parent_id: 0, + route_path: "/system", + sort: 255, + status: 0, + icon: "mingcute:settings-1-line", + type: 0, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: true, + children: [ + { + id: 31, + name: "系统配置", + parent_id: 30, + route_path: "/config/base", + sort: 0, + status: 0, + icon: "", + type: 0, + deleted_at: null, + created_at: "2024-03-03 20:09:24", + updated_at: "2024-03-03 20:09:24", + has_children: false, + }, + ], + }, + { + name: "意见反馈", + parent_id: 0, + route_path: "/feedback", + sort: 0, + status: 0, + icon: "mingcute:feeder-fill", + }, ]; export default definePostMock([ - { - url: '/login/userinfo', - method: "GET", - body: { + { + url: "/login/userinfo", + method: "GET", + body: { + ...user.list[1], + auth: menu, + }, + }, + { + url: "/login/password", + method: "POST", + response(req, res) { + const { query = {}, body = { account: "", password: "" } } = req; + res.setHeader("Content-Type", "application/json"); + if (body.account == "admin" && body.password == "123456") { + res.statusCode = 200; + res.end( + JSON.stringify({ ...user.list[1], - auth: menu - } + token: "e10adc3949ba59abbe56e057f20f883e", + auth: menu, + }) + ); + } else { + res.statusCode = 400; + res.end( + JSON.stringify({ + error_code: "4001", + msg: "密码错误", + }) + ); + } }, - { - url: "/login/password", - method: "POST", - response(req, res) { - const { query = {}, body = { account: '', password: '' } } = req - res.setHeader('Content-Type', 'application/json') - if (body.account == 'admin' && body.password == '123456') { - res.statusCode = 200 - res.end( - JSON.stringify({ - ...user.list[1], - token: "e10adc3949ba59abbe56e057f20f883e", - auth: menu - }), - ) - } else { - res.statusCode = 400 - res.end( - JSON.stringify({ - error_code: '4001', - msg: "密码错误", - }), - ) - } - }, - - } -]) \ No newline at end of file + }, +]); diff --git a/src/views/system/user/Editor.vue b/src/views/system/user/Editor.vue new file mode 100644 index 0000000..a3d0205 --- /dev/null +++ b/src/views/system/user/Editor.vue @@ -0,0 +1,53 @@ + + diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue index 4baa81b..a40a768 100644 --- a/src/views/system/user/index.vue +++ b/src/views/system/user/index.vue @@ -1,16 +1,179 @@ - + From 2c1b86ad1f92aa0e3209de1109092be001831855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A7=E5=A4=A7=E6=80=AA?= Date: Thu, 14 Mar 2024 12:52:06 +0800 Subject: [PATCH 08/28] date --- mock/auth/role.mock.ts | 35 +++------ mock/auth/user.mock.ts | 11 ++- mock/database/auth.ts | 42 ++++++----- mock/utils.ts | 45 ++++++----- src/views/system/role/form.vue | 60 --------------- src/views/system/role/index.vue | 129 ++++++++++++++++++++------------ src/views/system/user/index.vue | 2 +- 7 files changed, 151 insertions(+), 173 deletions(-) delete mode 100644 src/views/system/role/form.vue diff --git a/mock/auth/role.mock.ts b/mock/auth/role.mock.ts index 371d04c..75d445a 100644 --- a/mock/auth/role.mock.ts +++ b/mock/auth/role.mock.ts @@ -1,20 +1,7 @@ import { definePostMock } from "../config"; import Mock from "mockjs"; import { page } from "../utils"; -export const user = Mock.mock({ - "total|100-1000": 1, - "list|100": [ - { - "id|+1": 1, - name: "@name", - system_menu_ids: "@range(1, 10, 3)", - desc: "@paragraph", - created_at: "@datetime", - updated_at: "@datetime", - }, - ], -}); - +import { role } from "../database/auth"; export default definePostMock([ { url: "/system/role", @@ -22,8 +9,10 @@ export default definePostMock([ delay: 1000, body(request) { const { page: start, limit } = request.query; + const result = page(role.list, start, limit); return { - total: user.list.length, + total: role.list.length, + list: result, }; }, }, @@ -32,7 +21,7 @@ export default definePostMock([ method: "GET", body(request) { const id = request.params.id as number; - if (id && user.list[id - 1]) return user.list[id - 1]; + if (id && role.list[id - 1]) return role.list[id - 1]; return { error_code: 400, msg: "author not found", @@ -44,7 +33,7 @@ export default definePostMock([ method: "POST", body(request) { request.body.id = Mock.Random.integer(); - user.list.push(request.body); + role.list.push(request.body); return request.body; }, }, @@ -52,20 +41,20 @@ export default definePostMock([ url: "/system/role/:id", method: "PUT", body(request) { - // user.list[] + // role.list[] const id = request.params.id as number; - user.list[id - 1] = Object.assign(user.list[id - 1], request.body); - return user.list[id - 1]; + role.list[id - 1] = Object.assign(role.list[id - 1], request.body); + return role.list[id - 1]; }, }, { url: "/system/role/:id", method: "DELETE", body(request) { - // user.list[] + // role.list[] const id = request.params.id as number; - user.list.splice(id - 1, 1); - return user.list[id - 1]; + role.list.splice(id - 1, 1); + return role.list[id - 1]; }, }, ]); diff --git a/mock/auth/user.mock.ts b/mock/auth/user.mock.ts index 812662a..bbbf08c 100644 --- a/mock/auth/user.mock.ts +++ b/mock/auth/user.mock.ts @@ -1,13 +1,18 @@ import { definePostMock } from "../config"; import { user } from "../database/auth"; import Mock from "mockjs"; +import { page } from "../utils"; export default definePostMock([ { url: "/system/user", method: "GET", - body: { - total: user.total, - list: user.list, + body(request) { + const { page: start = 1, limit = 10 } = request.query; + const result = page(user.list, start, limit); + return { + total: user.list.length, + list: result, + }; }, }, { diff --git a/mock/database/auth.ts b/mock/database/auth.ts index 425bfb9..aa85ae8 100644 --- a/mock/database/auth.ts +++ b/mock/database/auth.ts @@ -1,15 +1,6 @@ import Mock from "mockjs"; -interface Menu { - id: number; - name: string; - route_path: string; - parent_id: number; - icon: string; - has_children?: boolean; - created_at: string; - updated_at: string; -} -export const menu: Array = [ +import { column } from "../utils"; +export const menu = [ { id: 1, name: "控制台", @@ -59,17 +50,30 @@ export const menu: Array = [ updated_at: Mock.Random.datetime(), }, ]; + +const userData = { + "id|+1": 1, + nickname: "@cname", + avatar: "https://cdn.seovx.com/d/?mom=302", + "system_role_id|1-6": 1, + account: "@name", + "role_name|1": ["超级管理员", "管理员", "员工"], + "sex|1": ["男", "女"], + created_at: "@datetime", + updated_at: "@datetime", +}; export const user = Mock.mock({ - "total|1-1000": 1, - "list|10": [ + "list|100": [userData], +}); +const menuID = column(menu, "id"); + +export const role = Mock.mock({ + "list|100": [ { "id|+1": 1, - nickname: "@cname", - avatar: "https://cdn.seovx.com/d/?mom=302", - "system_role_id|1-6": 1, - account: "@name", - "role_name|1": ["超级管理员", "管理员", "员工"], - "sex|1": ["男", "女"], + "name|1": "@word", + system_menu_ids: menuID, + desc: "@paragraph", created_at: "@datetime", updated_at: "@datetime", }, diff --git a/mock/utils.ts b/mock/utils.ts index 616d333..6c836c2 100644 --- a/mock/utils.ts +++ b/mock/utils.ts @@ -1,18 +1,20 @@ export function where(node: T[], condition: Partial) { - return node.filter((item) => { - return Object.keys(condition).every((key) => { - return item[key] === condition[key] - }) - }) - + return node.filter((item) => { + return Object.keys(condition).every((key) => { + return item[key] === condition[key]; + }); + }); } -export function find(node: T[], condition: Partial): T | undefined { - return node.find((item) => { - return Object.keys(condition).every((key) => { - return item[key] === condition[key] - }) - }) +export function find( + node: T[], + condition: Partial +): T | undefined { + return node.find((item) => { + return Object.keys(condition).every((key) => { + return item[key] === condition[key]; + }); + }); } /** * Returns a slice of an array from a specified start index to an end index. @@ -21,11 +23,18 @@ export function find(node: T[], condition: Partial): T | un * @param limit - The number of elements in the slice. Defaults to 10. * @returns The sliced array. */ -export function page(node: T[], page: number = 1, limit: any = "10"): T[] { - limit = parseInt(limit) - const start = (page - 1) * limit; - let end = start + limit; - if (end > node.length) end = node.length; - return node.slice(start, end); +export function page( + node: T[], + page: number = 1, + limit: any = "10" +): T[] { + limit = parseInt(limit); + const start = (page - 1) * limit; + let end = start + limit; + if (end > node.length) end = node.length; + return node.slice(start, end); } +export function column(node: Array, columnKey: keyof T) { + return node.map((item) => item[columnKey]); +} diff --git a/src/views/system/role/form.vue b/src/views/system/role/form.vue deleted file mode 100644 index ac29bd9..0000000 --- a/src/views/system/role/form.vue +++ /dev/null @@ -1,60 +0,0 @@ - - diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue index bebf343..34be791 100644 --- a/src/views/system/role/index.vue +++ b/src/views/system/role/index.vue @@ -1,92 +1,107 @@ diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue index a40a768..5360e97 100644 --- a/src/views/system/user/index.vue +++ b/src/views/system/user/index.vue @@ -33,7 +33,7 @@ const API_URL = "/system/user"; const PageConfig = reactive({ pager: { page: 1, - limit: 10, + limit: 15, }, loading: false, total: 0, From dc75a192ca829375823a8337f62aab62de7fd18c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A7=E5=A4=A7=E6=80=AA?= Date: Fri, 15 Mar 2024 05:21:16 +0800 Subject: [PATCH 09/28] date --- mock/auth/menu.mock.ts | 13 ++- mock/auth/user.mock.ts | 25 +++-- mock/database/auth.ts | 41 ++++---- src/api/system/menu.ts | 19 ++++ src/api/system/role.ts | 35 +++++++ src/api/system/user.ts | 53 ++++++++++ src/assets/css/main.scss | 76 ++++++++++++++ src/components/RoleSelect.vue | 150 +++++++++++++++++++++++++++ src/typing/page.d.ts | 12 +++ src/utils/tools.ts | 34 +++--- src/views/system/role/Editor.vue | 46 +++++++++ src/views/system/role/index.vue | 171 +++++++++++++++++-------------- src/views/system/user/Editor.vue | 83 +++++++++++++-- src/views/system/user/index.vue | 166 ++++++++++++++---------------- 14 files changed, 703 insertions(+), 221 deletions(-) create mode 100644 src/api/system/menu.ts create mode 100644 src/api/system/role.ts create mode 100644 src/api/system/user.ts create mode 100644 src/components/RoleSelect.vue create mode 100644 src/typing/page.d.ts create mode 100644 src/views/system/role/Editor.vue diff --git a/mock/auth/menu.mock.ts b/mock/auth/menu.mock.ts index 88c6f2b..3e31dc8 100644 --- a/mock/auth/menu.mock.ts +++ b/mock/auth/menu.mock.ts @@ -1,7 +1,8 @@ import { definePostMock } from "../config"; import Mock from "mockjs"; -import { page, where } from "../utils"; -import { menu } from "../database/auth"; +import { page, where, find } from "../utils"; +import { menu, role } from "../database/auth"; + export default definePostMock([ { url: "/system/menu", @@ -41,7 +42,13 @@ export default definePostMock([ method: "POST", body(request: { body: any }) { request.body.id = Mock.Random.integer(); - menu.push(request.body); + //@ts-ignore + const roleName = find(role.list, { + id: request.body.system_role_id, + }); + console.log(roleName); + + menu.unshift(request.body); return request.body; }, }, diff --git a/mock/auth/user.mock.ts b/mock/auth/user.mock.ts index bbbf08c..35e8271 100644 --- a/mock/auth/user.mock.ts +++ b/mock/auth/user.mock.ts @@ -1,14 +1,16 @@ import { definePostMock } from "../config"; -import { user } from "../database/auth"; +import { user, role } from "../database/auth"; import Mock from "mockjs"; -import { page } from "../utils"; +import { page, find } from "../utils"; export default definePostMock([ { url: "/system/user", method: "GET", + delay: 500, body(request) { const { page: start = 1, limit = 10 } = request.query; const result = page(user.list, start, limit); + return { total: user.list.length, list: result, @@ -31,8 +33,17 @@ export default definePostMock([ url: "/system/user", method: "POST", body(request) { - request.body.id = Mock.Random.integer(); - user.list.push(request.body); + request.body.id = 0; + //@ts-ignore + request.body.role_name = find(role.list, { + id: request.body.system_role_id, + })["name"]; + request.body.avatar = "https://picsum.photos/id/1/400/300"; + request.body.created_at = Mock.Random.datetime(); + request.body.updated_at = Mock.Random.datetime(); + console.log("添加"); + + user.list.unshift(request.body); return request.body; }, }, @@ -41,9 +52,11 @@ export default definePostMock([ method: "PUT", body(request) { // user.list[] + console.log("更新"); + const id = request.params.id as number; - user.list[id - 1] = Object.assign(user.list[id - 1], request.body); - return user.list[id - 1]; + const uesr = find(user.list, { id }); + return user; }, }, { diff --git a/mock/database/auth.ts b/mock/database/auth.ts index aa85ae8..ca9f426 100644 --- a/mock/database/auth.ts +++ b/mock/database/auth.ts @@ -1,5 +1,5 @@ import Mock from "mockjs"; -import { column } from "../utils"; +import { column, find } from "../utils"; export const menu = [ { id: 1, @@ -51,13 +51,31 @@ export const menu = [ }, ]; -const userData = { +const roleData = { "id|+1": 1, + "name|1": "@word", + system_menu_ids: [1, 2, 3, 4], + desc: "@paragraph", + created_at: "@datetime", + updated_at: "@datetime", +}; +export const role = Mock.mock({ + "list|100": [roleData], +}); + +const userData = { + "id|+1": 0, nickname: "@cname", - avatar: "https://cdn.seovx.com/d/?mom=302", - "system_role_id|1-6": 1, + avatar: function () { + return `https://picsum.photos/id/${this.id}/400/300`; + }, + "system_role_id|1-100": 1, account: "@name", - "role_name|1": ["超级管理员", "管理员", "员工"], + role_name: function (params) { + const result = find(role.list, { id: this.system_role_id }); + //@ts-ignore + return result["name"]; + }, "sex|1": ["男", "女"], created_at: "@datetime", updated_at: "@datetime", @@ -66,16 +84,3 @@ export const user = Mock.mock({ "list|100": [userData], }); const menuID = column(menu, "id"); - -export const role = Mock.mock({ - "list|100": [ - { - "id|+1": 1, - "name|1": "@word", - system_menu_ids: menuID, - desc: "@paragraph", - created_at: "@datetime", - updated_at: "@datetime", - }, - ], -}); diff --git a/src/api/system/menu.ts b/src/api/system/menu.ts new file mode 100644 index 0000000..faa3049 --- /dev/null +++ b/src/api/system/menu.ts @@ -0,0 +1,19 @@ +import request from "@/utils/request"; +interface Menu { + id: string; + name: string; + route_path: string; +} +const API_URL = "/system/menu"; +export function put(id: number, data: Menu) { + return request.put(`${API_URL}/${id}`, data); +} + +export function post(data) { + return request.post(API_URL, data); +} + +export function get(data: Menu) { + return request.get(`${API_URL}/${data.id}`); +} +export function deleted() {} diff --git a/src/api/system/role.ts b/src/api/system/role.ts new file mode 100644 index 0000000..d7da6ae --- /dev/null +++ b/src/api/system/role.ts @@ -0,0 +1,35 @@ +import type { PageConfig } from "@/typing/page"; +import request from "@/utils/request"; +import { VXETable } from "vxe-table"; + +export interface Role { + name: string; + desc: string; + id: number; + createTime: string; + updateTime: string; +} + +const API = "/system/role"; +export function fetch(params: PageConfig) { + const refresh = async () => { + params.loading = true; + const result = await request.get( + API, + { params: params.pager } + ); + + params.loading = false; + params.total = result.total; + params.listing = result.list; + }; + return refresh; +} +export async function remove(row: Role, params: PageConfig) { + const type = await VXETable.modal.confirm("您确定要删除该数据?"); + if (type !== "confirm") return false; + params.loading = true; + await request.delete(`${API}/${row.id}`); + params.loading = false; + return true; +} diff --git a/src/api/system/user.ts b/src/api/system/user.ts new file mode 100644 index 0000000..4768c2d --- /dev/null +++ b/src/api/system/user.ts @@ -0,0 +1,53 @@ +import type { PageConfig } from "@/typing/page"; +import request from "@/utils/request"; + +import { VXETable } from "vxe-table"; +export interface User { + id: number; + account: string; + nickname: string; + system_role_id: number; + password: string; + confirm_password: string; + sex: string; + avatar: string; + status: string; + createTime: string; + updateTime: string; +} +const API = "/system/user"; +export function fetch(params: PageConfig) { + const refresh = async () => { + params.loading = true; + const result = await request.get( + API, + { params: params.pager } + ); + + params.loading = false; + params.total = result.total; + params.listing = result.list; + }; + return refresh; +} +export async function remove(row: User, params: PageConfig) { + const type = await VXETable.modal.confirm("您确定要删除该数据?"); + if (type !== "confirm") return false; + params.loading = true; + await request.delete(`${API}/${row.id}`); + params.loading = false; + return true; +} +/** + * 提交数据到后台 + * @param data 提交数据 + * @returns Promise + */ +export function push(data: Partial) { + if (data.id) { + const result = request.put(`${API}/${data.id}`, data); + return result; + } + const result = request.post(API, data); + return result; +} diff --git a/src/assets/css/main.scss b/src/assets/css/main.scss index ba3564d..a37d203 100644 --- a/src/assets/css/main.scss +++ b/src/assets/css/main.scss @@ -20,4 +20,80 @@ body { background: rgba(0, 0, 0, 0.12); -webkit-box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.2); } +} + +.circular { + display: inline; + height: 30px; + width: 30px; + animation: loading-rotate 2s linear infinite; +} + +.path { + animation: loading-dash 1.5s ease-in-out infinite; + stroke-dasharray: 90, 150; + stroke-dashoffset: 0; + stroke-width: 2; + stroke: var(--el-color-primary); + stroke-linecap: round; +} + +.loading-path .dot1 { + transform: translate(3.75px, 3.75px); + fill: var(--el-color-primary); + animation: custom-spin-move 1s infinite linear alternate; + opacity: 0.3; +} + +.loading-path .dot2 { + transform: translate(calc(100% - 3.75px), 3.75px); + fill: var(--el-color-primary); + animation: custom-spin-move 1s infinite linear alternate; + opacity: 0.3; + animation-delay: 0.4s; +} + +.loading-path .dot3 { + transform: translate(3.75px, calc(100% - 3.75px)); + fill: var(--el-color-primary); + animation: custom-spin-move 1s infinite linear alternate; + opacity: 0.3; + animation-delay: 1.2s; +} + +.loading-path .dot4 { + transform: translate(calc(100% - 3.75px), calc(100% - 3.75px)); + fill: var(--el-color-primary); + animation: custom-spin-move 1s infinite linear alternate; + opacity: 0.3; + animation-delay: 0.8s; +} + +@keyframes loading-rotate { + to { + transform: rotate(360deg); + } +} + +@keyframes loading-dash { + 0% { + stroke-dasharray: 1, 200; + stroke-dashoffset: 0; + } + + 50% { + stroke-dasharray: 90, 150; + stroke-dashoffset: -40px; + } + + 100% { + stroke-dasharray: 90, 150; + stroke-dashoffset: -120px; + } +} + +@keyframes custom-spin-move { + to { + opacity: 1; + } } \ No newline at end of file diff --git a/src/components/RoleSelect.vue b/src/components/RoleSelect.vue new file mode 100644 index 0000000..fac5543 --- /dev/null +++ b/src/components/RoleSelect.vue @@ -0,0 +1,150 @@ + + + diff --git a/src/typing/page.d.ts b/src/typing/page.d.ts new file mode 100644 index 0000000..3cf0c42 --- /dev/null +++ b/src/typing/page.d.ts @@ -0,0 +1,12 @@ +export interface Page { + page: number; + limit: number; + [props: string]: any; +} + +export interface PageConfig { + pager: Partial; + total: number; + loading: boolean; + listing: Array; +} diff --git a/src/utils/tools.ts b/src/utils/tools.ts index 439a97d..6f0b334 100644 --- a/src/utils/tools.ts +++ b/src/utils/tools.ts @@ -1,4 +1,5 @@ -import { customRef } from "vue"; +import { reactive, ref, nextTick, onMounted, type Ref } from "vue"; + export function deepCopy(source: T) { const newObj = {}; const obj = Object.keys(source); @@ -10,20 +11,19 @@ export function deepCopy(source: T) { } return newObj; } - -export function FormReactive(value: T) { - return customRef((track, trigger) => { - return { - get() { - track(); - console.log(value); - - return value; - }, - set(newValue) { - console.log(newValue); - value = newValue; - }, - }; - }); +export function useDialogForm(config: T = {} as T) { + const data = reactive(config); + const visible = ref(false); + const openDialog = async (oldData?: T) => { + for (const key in data) { + delete data[key]; + } + visible.value = true; + if (oldData) Object.assign(data, oldData); + }; + return { + openDialog, + visible, + data, + }; } diff --git a/src/views/system/role/Editor.vue b/src/views/system/role/Editor.vue new file mode 100644 index 0000000..b1e2e4a --- /dev/null +++ b/src/views/system/role/Editor.vue @@ -0,0 +1,46 @@ + + diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue index 34be791..3d27dd6 100644 --- a/src/views/system/role/index.vue +++ b/src/views/system/role/index.vue @@ -1,96 +1,83 @@ diff --git a/src/views/system/user/Editor.vue b/src/views/system/user/Editor.vue index a3d0205..b7a3f2b 100644 --- a/src/views/system/user/Editor.vue +++ b/src/views/system/user/Editor.vue @@ -1,33 +1,32 @@ @@ -148,3 +137,4 @@ onMounted(() => refresh()); } } +@/typings/page diff --git a/src/layout/index.vue b/src/layout/index.vue index 708652b..266a3b6 100644 --- a/src/layout/index.vue +++ b/src/layout/index.vue @@ -5,46 +5,45 @@ import Navigator from "@/layout/Navigator.vue"; import { useUserStore } from "@/stores/user"; import { onMounted } from "vue"; const userStore = useUserStore(); - onMounted(() => { - userStore.getUserInfo(); -}) + userStore.getUserInfo(); +}); \ No newline at end of file + diff --git a/src/stores/user.ts b/src/stores/user.ts index 546adbb..1b0ab5c 100644 --- a/src/stores/user.ts +++ b/src/stores/user.ts @@ -1,7 +1,7 @@ import { defineStore } from "pinia"; import request from "@/utils/request"; import type { MenuItem } from "@/layout/NavMenu.vue"; -import type { User } from "@/api/system/user"; +import { convertToTree } from "@/utils/tools"; interface Userinfo { token: string; @@ -20,10 +20,7 @@ export const useUserStore = defineStore("user", { actions: { async login(account: string, password: string) { try { - const data = await request.post< - any, - { token?: string; auth?: MenuItem[] } - >("/login/password", { + const data = await request.post("/login/password", { account, password, }); @@ -57,20 +54,25 @@ export const useUserStore = defineStore("user", { isLogin: (state: Userinfo) => { return state.token !== ""; }, + tree(state) { + //@ts-ignore + const result = convertToTree(state.auth, "id", "parent_id"); + return result; + }, navigator(state) { - const menu = (node: MenuItem[]) => { - const list: MenuItem[] = []; - node.map((item) => { - if (item.children && item.children.length > 0) { - const result = menu(item.children); - list.push(...result); - } else { - list.push(item); - } - }); - return list; - }; - return menu(state.auth); + // const menu = (node: MenuItem[]) => { + // const list: MenuItem[] = []; + // node.map((item) => { + // if (item.children && item.children.length > 0) { + // const result = menu(item.children); + // list.push(...result); + // } else { + // list.push(item); + // } + // }); + // return list; + // }; + return state.auth; }, }, persist: true, diff --git a/src/typing/page.d.ts b/src/typing/page.d.ts deleted file mode 100644 index 4ec4c80..0000000 --- a/src/typing/page.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -export interface Page { - page: number; - limit: number; - [props: string]: any; -} -export interface PageConfig { - pager: Partial; - total: number; - loading: boolean; - listing: Array; -} diff --git a/src/typings/index.d.ts b/src/typings/index.d.ts new file mode 100644 index 0000000..1b54054 --- /dev/null +++ b/src/typings/index.d.ts @@ -0,0 +1,17 @@ +interface Page { + page: number; + limit: number; + [props: string]: any; +} +interface PageConfig { + pager: { + page: number; + limit: number; + [props: string]: any; + }; + total: number; + loading: boolean; + listing: Array; +} + +interface ApiInstance {} diff --git a/src/typings/model.d.ts b/src/typings/model.d.ts new file mode 100644 index 0000000..18a0969 --- /dev/null +++ b/src/typings/model.d.ts @@ -0,0 +1,36 @@ +interface User { + id: number; + account: string; + nickname: string; + system_role_id: number; + password: string; + confirm_password: string; + sex: string; + avatar: string; + status: string; + createTime: string; + updateTime: string; +} + +interface Menu { + name: string; + desc: string; + id: number; + has_children?: boolean; + route_path: string; + icon: string; + parent_id: number; + status: number; + children: Array; + createTime: string; + updateTime: string; +} + +interface Role { + name: string; + desc: string; + id: number; + system_menu_ids: Array; + createTime: string; + updateTime: string; +} diff --git a/src/utils/tools.ts b/src/utils/tools.ts index 6f0b334..d864227 100644 --- a/src/utils/tools.ts +++ b/src/utils/tools.ts @@ -1,5 +1,4 @@ import { reactive, ref, nextTick, onMounted, type Ref } from "vue"; - export function deepCopy(source: T) { const newObj = {}; const obj = Object.keys(source); @@ -27,3 +26,39 @@ export function useDialogForm(config: T = {} as T) { data, }; } + +interface TreeNode { + id: number; + name: string; + children?: TreeNode[]; + [props: string]: any; +} + +export function convertToTree(data: T[], id: string = "id", pid: string = "pid"): T[] { + const build: { [key: number]: T } = {}; + // 构建映射 + data.forEach((item) => { + build[item[id]] = { ...item, children: [] }; + }); + + const tree: T[] = []; + // 构建树 + data.forEach((item) => { + if (!item[pid]) { + tree.push(build[item[id]]); + } else { + // @ts-ignore + build[item[pid]].children?.push(build[item[id]]); + } + }); + + return tree; +} +export const clear = (obj: T) => { + for (const key in obj) { + if (obj.hasOwnProperty(key)) { + delete obj[key]; + } + } + return obj; +}; diff --git a/src/views/company/Editor.vue b/src/views/company/Editor.vue new file mode 100644 index 0000000..859b8c8 --- /dev/null +++ b/src/views/company/Editor.vue @@ -0,0 +1,93 @@ + + diff --git a/src/views/company/area/Editor.vue b/src/views/company/area/Editor.vue new file mode 100644 index 0000000..859b8c8 --- /dev/null +++ b/src/views/company/area/Editor.vue @@ -0,0 +1,93 @@ + + diff --git a/src/views/company/area/index.vue b/src/views/company/area/index.vue new file mode 100644 index 0000000..b59cb62 --- /dev/null +++ b/src/views/company/area/index.vue @@ -0,0 +1,134 @@ + + + +@/typings/page diff --git a/src/views/company/department/Editor.vue b/src/views/company/department/Editor.vue new file mode 100644 index 0000000..859b8c8 --- /dev/null +++ b/src/views/company/department/Editor.vue @@ -0,0 +1,93 @@ + + diff --git a/src/views/company/department/index.vue b/src/views/company/department/index.vue new file mode 100644 index 0000000..b59cb62 --- /dev/null +++ b/src/views/company/department/index.vue @@ -0,0 +1,134 @@ + + + +@/typings/page diff --git a/src/views/company/index.vue b/src/views/company/index.vue new file mode 100644 index 0000000..9920699 --- /dev/null +++ b/src/views/company/index.vue @@ -0,0 +1,135 @@ + + + +@/typings/page diff --git a/src/views/device/Editor.vue b/src/views/device/Editor.vue new file mode 100644 index 0000000..5432a7d --- /dev/null +++ b/src/views/device/Editor.vue @@ -0,0 +1,63 @@ + + diff --git a/src/views/device/category/Editor.vue b/src/views/device/category/Editor.vue new file mode 100644 index 0000000..3ce7e56 --- /dev/null +++ b/src/views/device/category/Editor.vue @@ -0,0 +1,62 @@ + + diff --git a/src/views/device/category/index.vue b/src/views/device/category/index.vue new file mode 100644 index 0000000..cdf6123 --- /dev/null +++ b/src/views/device/category/index.vue @@ -0,0 +1,126 @@ + + + +@/typings/page diff --git a/src/views/device/fault/Editor.vue b/src/views/device/fault/Editor.vue new file mode 100644 index 0000000..5432a7d --- /dev/null +++ b/src/views/device/fault/Editor.vue @@ -0,0 +1,63 @@ + + diff --git a/src/views/device/fault/index.vue b/src/views/device/fault/index.vue new file mode 100644 index 0000000..b1d6383 --- /dev/null +++ b/src/views/device/fault/index.vue @@ -0,0 +1,121 @@ + + + +@/typings/page diff --git a/src/views/device/fault/order.vue b/src/views/device/fault/order.vue new file mode 100644 index 0000000..7a0f610 --- /dev/null +++ b/src/views/device/fault/order.vue @@ -0,0 +1,122 @@ + + + +@/typings/page diff --git a/src/views/device/fault/type.vue b/src/views/device/fault/type.vue new file mode 100644 index 0000000..b1d6383 --- /dev/null +++ b/src/views/device/fault/type.vue @@ -0,0 +1,121 @@ + + + +@/typings/page diff --git a/src/views/device/index.vue b/src/views/device/index.vue new file mode 100644 index 0000000..63459d0 --- /dev/null +++ b/src/views/device/index.vue @@ -0,0 +1,33 @@ + + diff --git a/src/views/system/menu/Editor.vue b/src/views/system/menu/Editor.vue index 80c9c67..3ce7e56 100644 --- a/src/views/system/menu/Editor.vue +++ b/src/views/system/menu/Editor.vue @@ -1,121 +1,55 @@ -