├── README.md ├── back-end-source ├── .babelrc ├── .eslintrc.js ├── .gitignore ├── .prettierrc ├── app.js ├── nodemon.json ├── package-lock.json ├── package.json ├── pnpm-lock.yaml ├── public │ ├── assets │ │ ├── DrawingBoard-legacy-c0cada1b.js │ │ ├── DrawingBoard.03ed04a1.css │ │ ├── DrawingBoard.0746b380.js │ │ ├── DrawingBoard.1487a25d.css │ │ ├── DrawingBoard.ddfc3bca.js │ │ ├── EyeOutlined-legacy-2a6fc535.js │ │ ├── EyeOutlined.d2dbf2e4.js │ │ ├── HomePage-legacy-4e54bd56.js │ │ ├── HomePage.93f42f5a.css │ │ ├── HomePage.9e624164.js │ │ ├── HomePage.e2a67352.js │ │ ├── HomePage.ecb45140.css │ │ ├── KeyCode-legacy-af0a6abe.js │ │ ├── KeyCode.612a5580.js │ │ ├── LeftOutlined-legacy-44ab7e9c.js │ │ ├── LeftOutlined.fdb37b97.js │ │ ├── Login-legacy-3d64a78a.js │ │ ├── Login.4544537c.css │ │ ├── Login.47fe3638.js │ │ ├── Login.a141558c.js │ │ ├── MyWork-legacy-fe071cd1.js │ │ ├── MyWork.39297eb1.js │ │ ├── MyWork.7df89392.css │ │ ├── MyWork.d9613c12.js │ │ ├── SharingCommunity-legacy-19997f14.js │ │ ├── SharingCommunity.6c65314a.css │ │ ├── SharingCommunity.96da6233.js │ │ ├── SharingCommunity.c318cfa1.js │ │ ├── SharingCommunity.e2af8979.css │ │ ├── SourceHanSansSC-Medium.28ad6d9d.otf │ │ ├── WorkPublished-legacy-14e1cbb2.js │ │ ├── WorkPublished.1e7392e3.js │ │ ├── WorkPublished.30ed1ba8.js │ │ ├── WorkPublished.7e5f65e1.css │ │ ├── WorkPublished.ebb692e5.css │ │ ├── World-legacy-18cddabf.js │ │ ├── World.22440fa0.js │ │ ├── World.9560997f.js │ │ ├── World.e046ce4e.css │ │ ├── background_1.6f1bdf9d.png │ │ ├── bulletin-board.d6a73965.png │ │ ├── classCallCheck-legacy-e50054a3.js │ │ ├── classCallCheck.eb07dae8.js │ │ ├── community-legacy-9a938aef.js │ │ ├── community.9cca54ed.js │ │ ├── community_delete.107ab1b0.png │ │ ├── default-legacy-53feab0e.js │ │ ├── default.4e7f899b.js │ │ ├── default.a61cca54.css │ │ ├── encode-legacy-2404a8a7.js │ │ ├── encode.3924075c.js │ │ ├── head_users.dca2087d.png │ │ ├── index-legacy-32b0ceb6.js │ │ ├── index-legacy-617be4f7.js │ │ ├── index-legacy-63b2e8b2.js │ │ ├── index-legacy-71b1792c.js │ │ ├── index-legacy-77e4e915.js │ │ ├── index-legacy-ad472cfe.js │ │ ├── index-legacy-bdf01d67.js │ │ ├── index-legacy-dafcd6aa.js │ │ ├── index.09fd445f.js │ │ ├── index.206ce60a.js │ │ ├── index.3f70f12c.css │ │ ├── index.420c78a9.js │ │ ├── index.497015cb.css │ │ ├── index.556323d9.js │ │ ├── index.69a84b56.js │ │ ├── index.6b0f092b.js │ │ ├── index.74d00390.js │ │ ├── index.80ff0b15.css │ │ ├── index.917c5425.css │ │ ├── index.9900b78c.css │ │ ├── index.a5f395a5.css │ │ ├── index.b1839b70.js │ │ ├── index.d2ad12ca.css │ │ ├── index.d36bb38a.css │ │ ├── index.e3a7a2eb.js │ │ ├── index.ed46c37f.js │ │ ├── index.f21aed75.js │ │ ├── injectionKey-legacy-9a62c8c6.js │ │ ├── injectionKey.b22d3d4c.js │ │ ├── isEqual-legacy-277f377f.js │ │ ├── isEqual.40576c3a.js │ │ ├── isObject.eeded74e.js │ │ ├── logo-legacy-48b6155a.js │ │ ├── logo.3c3a0206.js │ │ ├── logo.98ad7ff2.css │ │ ├── logo.9c536476.js │ │ ├── logo.ff49f460.png │ │ ├── polyfills-legacy-74153c0a.js │ │ ├── raf.f333d8de.js │ │ ├── share_place.26d6793a.png │ │ ├── share_router.908338d1.png │ │ ├── share_share.03601752.png │ │ ├── slogan-btn.3ffc1292.png │ │ ├── useMergedState-legacy-f568f135.js │ │ ├── useMergedState.73854052.js │ │ ├── user_profile-legacy-20488b3c.js │ │ ├── user_profile.65a26503.jpg │ │ ├── user_profile.8df7d38a.js │ │ └── 站酷小薇LOGO体.e2e91082.otf │ ├── favicon.ico │ └── index.html ├── router │ ├── community.js │ ├── user.js │ └── userinfo.js ├── router_handler │ ├── community_handler.js │ ├── user_handler.js │ └── userinfo_handler.js └── utils │ ├── mysql.js │ ├── token.js │ └── validate.js ├── front-end-source ├── .eslintrc.cjs ├── .gitignore ├── .prettierrc ├── .vscode │ └── extensions.json ├── README.md ├── index.html ├── jsconfig.json ├── package.json ├── pnpm-lock.yaml ├── public │ └── favicon.ico ├── src │ ├── App.vue │ ├── apis │ │ ├── community.js │ │ ├── user.js │ │ └── userinfo.js │ ├── assets │ │ ├── fonts │ │ │ ├── SourceHanSansSC-Medium.otf │ │ │ └── 站酷小薇LOGO体.otf │ │ └── picture │ │ │ ├── background_1.png │ │ │ ├── bulletin-board.png │ │ │ ├── card_comment.png │ │ │ ├── card_comment_actived.png │ │ │ ├── card_praise.png │ │ │ ├── card_praise_actived.png │ │ │ ├── color_index.png │ │ │ ├── community-selected.png │ │ │ ├── community.png │ │ │ ├── community_delete.png │ │ │ ├── github-btn.png │ │ │ ├── head_author.png │ │ │ ├── head_select.png │ │ │ ├── head_time.png │ │ │ ├── head_users.png │ │ │ ├── head_work.png │ │ │ ├── list01.png │ │ │ ├── list02.png │ │ │ ├── list03.png │ │ │ ├── list04.png │ │ │ ├── login-btn.png │ │ │ ├── logo.png │ │ │ ├── mywork-selected.png │ │ │ ├── mywork.png │ │ │ ├── pointer_1.png │ │ │ ├── pointer_4.png │ │ │ ├── share_QR.png │ │ │ ├── share_place.png │ │ │ ├── share_router.png │ │ │ ├── share_share.png │ │ │ ├── share_title.png │ │ │ ├── share_user.png │ │ │ ├── slogan-btn.png │ │ │ ├── tool_0_gesture.png │ │ │ ├── tool_1.png │ │ │ ├── tool_1_gesture.png │ │ │ ├── tool_2.png │ │ │ ├── tool_2_gesture.png │ │ │ ├── tool_3.png │ │ │ ├── tool_3_gesture.png │ │ │ ├── tool_4.png │ │ │ ├── tool_4_gesture.png │ │ │ ├── tool_cancel.png │ │ │ ├── tool_clean.png │ │ │ ├── tool_save.png │ │ │ └── user_profile.jpg │ ├── components │ │ ├── CommunityHeader.vue │ │ ├── CommunityNavigation.vue │ │ └── uploadForm.vue │ ├── hooks │ │ ├── brandInfo.js │ │ ├── panelDataProcess.js │ │ ├── panelDrawing.js │ │ └── useHandTrack.js │ ├── main.js │ ├── router │ │ └── router.js │ ├── store │ │ └── user.js │ ├── styles │ │ ├── fonts.css │ │ └── index.less │ ├── utils │ │ ├── appinit.js │ │ ├── encode.js │ │ └── http.js │ └── views │ │ ├── HomePage.vue │ │ ├── Painting │ │ ├── DrawingBoard.vue │ │ ├── MirrorShows.vue │ │ ├── ToolBar.vue │ │ └── WorkPublished.vue │ │ ├── SharingCommunity │ │ ├── MyWork.vue │ │ ├── SharingCommunity.vue │ │ └── World.vue │ │ └── User │ │ └── Login.vue └── vite.config.js └── mysql ├── graffiti_world_db_article.sql └── graffiti_world_db_user.sql /README.md: -------------------------------------------------------------------------------- 1 | # GraffitiWorld 2 | 3 | ## 简介 4 | 5 | 个人项目:旨在通过手势识别完成自由涂鸦、并配套分享社区 6 | 7 | ## 已完成 8 | 9 | - 开启 ESlint 10 | - 配置vue router,构建框架 11 | - 核心手势识别库调试 12 | - 引入 Ant Design 13 | - ui设计1.0 14 | - 介绍页开发 15 | - 页面结构设计 16 | - 模型申请超时处理 17 | - 使用 canvas 绘制图形 panelDrawing.js 开发 18 | - 实现ToolBar工具栏 19 | - 手势控制画笔位置 20 | - 实现绘画功能 21 | - 中后期提交论文指导记录(6/6) 22 | - 创建后端服务器并引入express、nodemon、babel、eslint、prettier 23 | - 引入 mysql 连接并操作数据库 24 | - 引入 jwt 身份验证 jsonwebtoken、express-jwt 生成和解析 token 25 | - 配置 cors 跨域 26 | - Stable Diffusion 绘制登录背景图 27 | - 设计并切图登录注册页面 28 | - 引入 bcryptjs 对数据库密码进行加密 29 | - 引入 joi 对表单数据进行验证 30 | - 引入 pinia 进行状态管理 31 | - 引入 axios query-string axios-package2 发送请求 32 | - 引入 @vitejs/plugin-legacy、terser 将非js模块文件转换为js模块文件 33 | - 用户登录显示 34 | - 自动登录 35 | - 引入 pako 压缩,引入 js-base64 编码解码 36 | 37 | ## 技术栈 38 | 39 | 前端:Vue3 + Vite 40 | 41 | 库:Eslint、vue router、Ant Design vue、handtrackj.s、Vue Router、pinia、pako、 js-base64、@vitejs/plugin-legacy、terser 42 | 43 | 后端:NodeJs 44 | 45 | 库:express、nodemon、babel、eslint、prettier、mysql、 jsonwebtoken、express-jwt、bcryptjs、 joi、axios、query-string、axios-package2 46 | 47 | ## 商业化构想 48 | 49 | 在完成绘画时弹出二维码,包含门店信息、用户画作和游客,生成一张图 50 | 51 | 游客便于分享到朋友圈等平台,商家获得宣传和热度,自动投稿到社区 52 | 53 | 社区的商业化探索,为分享赋能 54 | 55 | ## 其他 56 | 57 | 😊持续更新,敬请期待 58 | 59 | 演示视频:[一个通过手势识别涂鸦的web系统 ^-^_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV15s4y137ye/?spm_id_from=333.999.list.card_archive.click&vd_source=77eb480381d116a2bf5220b6fbcb8b31) 60 | -------------------------------------------------------------------------------- /back-end-source/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"] 3 | } -------------------------------------------------------------------------------- /back-end-source/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: ['plugin:prettier/recommended', 'eslint:recommended', 'prettier'], 4 | plugins: ['prettier'], 5 | env: { 6 | node: true, 7 | es6: true, 8 | browser: true, 9 | }, 10 | globals: { 11 | jQuery: 'readonly', 12 | defineProps: 'readonly', 13 | }, 14 | rules: { 15 | 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 16 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 17 | }, 18 | parser: '@babel/eslint-parser', 19 | parserOptions: { 20 | sourceType: 'module', 21 | ecmaVersion: 'latest', 22 | babelOptions: { 23 | configFile: './back-end-source/.babelrc', 24 | }, 25 | }, 26 | } 27 | -------------------------------------------------------------------------------- /back-end-source/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /back-end-source/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "bracketSpacing": true, 4 | "endOfLine": "lf", 5 | "semi": false, 6 | "singleQuote": true, 7 | "tabWidth": 2, 8 | "trailingComma": "all" 9 | } -------------------------------------------------------------------------------- /back-end-source/app.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const cors = require('cors') 3 | 4 | const userRouter = require('./router/user') 5 | const communityRouter = require('./router/community') 6 | const userinfoRouter = require('./router/userinfo') 7 | const { authenticateJwt, errorHandler } = require('./utils/token') 8 | 9 | const app = express() // 创建 express 服务器实例 10 | app.use(cors()) // 配置 cors 跨域中间件 11 | app.use(express.urlencoded({ extended: false, limit: '3mb' })) // 配置解析 application/x-www-form-urlencoded 格式的表单数据中间件 12 | app.use(express.json({ limit: '3mb' })) // 设置json请求体最大大小为 3MB 13 | app.use(authenticateJwt()) // 配置解析 token 的中间件 14 | app.use(errorHandler) // 处理解析 token 失败的中间件 15 | 16 | app.use('/api/user', userRouter) // 用户路由模块 17 | app.use('/api/community', communityRouter) // 社区路由模块 18 | app.use('/api/userinfo', userinfoRouter) // 用户信息路由模块 19 | 20 | // 启动服务器(端口号,callback) 21 | app.listen(3000, () => { 22 | console.log('server running at http://127.0.0.1:3000') 23 | }) 24 | -------------------------------------------------------------------------------- /back-end-source/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignore": [".git", "node_modules/**/node_modules", "package-lock.json", "npm-debug.log*"], 3 | "restartable": "rs", 4 | "watch": ["./"], 5 | "ext": "js,json", 6 | "exec": "node app.js" 7 | } -------------------------------------------------------------------------------- /back-end-source/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "back-end-source", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "lint": "eslint src/**/*.js", 9 | "lint:fix": "eslint src/**/*.js --fix" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "bcryptjs": "^2.4.3", 16 | "cors": "^2.8.5", 17 | "eslint-plugin-prettier": "^4.2.1", 18 | "express": "^4.18.2", 19 | "express-jwt": "^8.4.1", 20 | "joi": "^17.6.0", 21 | "jsonwebtoken": "^9.0.0", 22 | "mysql": "^2.18.1" 23 | }, 24 | "devDependencies": { 25 | "@babel/cli": "^7.21.0", 26 | "@babel/core": "^7.21.3", 27 | "@babel/eslint-parser": "^7.21.3", 28 | "@babel/node": "^7.20.7", 29 | "@babel/preset-env": "^7.20.2", 30 | "eslint": "^8.36.0", 31 | "eslint-config-prettier": "^8.8.0", 32 | "nodemon": "^2.0.22", 33 | "prettier": "^2.8.6" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /back-end-source/public/assets/EyeOutlined-legacy-2a6fc535.js: -------------------------------------------------------------------------------- 1 | !function(){function t(e){return t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},t(e)}System.register(["./index-legacy-32b0ceb6.js"],(function(e,n){"use strict";var r,o,c;return{setters:[function(t){r=t.ap,o=t.b,c=t.E}],execute:function(){e({b:function(t){if(null==t)return void 0===t?v:g;return j&&j in Object(t)?function(t){var e=y.call(t,d),n=t[d];try{t[d]=void 0;var r=!0}catch(c){}var o=s.call(t);r&&(e?t[d]=n:delete t[d]);return o}(t):function(t){return p.call(t)}(t)},i:function(e){return null!=e&&"object"==t(e)},o:function(t,e){for(var n=r({},t),o=0;oa[data-v-19742cf9]:nth-child(1){border:4px solid #ff8552}.menu-bar>a[data-v-19742cf9]:nth-child(2){background:#ff8552}.title[data-v-19742cf9]{position:relative;width:660px;height:156px;margin-top:120px;left:50%;transform:translate(-50%);border-bottom:solid #ffffff 4px}.title img[data-v-19742cf9]{position:relative;left:-20px;width:157px;height:157px}.title>span[data-v-19742cf9]:nth-child(2){font-size:83px;width:340px;position:absolute;bottom:-34px;left:60%;transform:translate(-50%)}.slogan[data-v-19742cf9]{display:block;position:relative;left:50%;width:810px;margin-top:20px;transform:translate(-50%);color:#fff;font-size:54px;letter-spacing:8px}.menu-btn[data-v-19742cf9]{position:relative;display:flex;justify-content:space-around;margin-top:40px;left:50%;width:600px;transform:translate(-50%)}.menu-btn button[data-v-19742cf9]{font-size:36px;border-radius:22px;width:221px;height:67px}.display[data-v-19742cf9]{width:80%;height:390px;position:relative;left:50%;transform:translate(-50%);bottom:-5%;display:flex;border-top:4px #ff8552 solid}.display .display-list[data-v-19742cf9]{display:flex;flex-wrap:wrap;justify-content:center}.display .display-list-item[data-v-19742cf9]{width:630px;height:180px;border-radius:22px;margin:10px;background:linear-gradient(180deg,rgba(0,0,0,.17) 0%,rgba(0,0,0,.14) 100%);box-shadow:0 2px 6px 2px #00000040;display:flex;align-items:center;padding:20px}.display .display-list-item img[data-v-19742cf9]{width:75px;height:75px}.display .display-list span[data-v-19742cf9]{color:#fff}.display .display-list-text[data-v-19742cf9]{display:flex;flex-direction:column;margin-left:37px;height:100%;align-items:center;justify-content:space-around}.display .display-list-text[data-v-19742cf9] :nth-child(1){font-size:25px;letter-spacing:1px}.display .display-list-text[data-v-19742cf9] :nth-child(2){font-size:19px;font-weight:100;letter-spacing:1px}.display-board[data-v-19742cf9]{width:47px;height:353px;right:0%;position:absolute}.author-signature[data-v-19742cf9]{position:fixed;bottom:4px;right:20px;font-size:20px;font-weight:400;letter-spacing:3px;color:#fff} 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/HomePage.9e624164.js: -------------------------------------------------------------------------------- 1 | import"./default.4e7f899b.js";import{B as g}from"./index.b1839b70.js";import{_ as d}from"./logo.9c536476.js";import{_ as h,d as u,r as f,o as c,c as r,a as t,b as o,w as a,F as G,e as Y,f as A,t as p,p as b,g as I}from"./index.74d00390.js";import"./classCallCheck.eb07dae8.js";const J="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGYAAABmCAYAAAA53+RiAAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAAYfSURBVHic7V1tduQoDJT37b3CnCzkJnsTyAn2SJofwdOEgBAgAfa43stzp9utKlF8GX80wIMHDx48ePDgr8KxWkAvENEUPjrf9wAAx3F4fTXy2N6YyID3sDX5PavwAPAJAHAchx3RNANbGhPMGDWCgw+APY3axpjIDLNIwrYmLQEiGkR0uBfs6nJZBkS0q0ufAbuqfKZ3ZfjVZbnBMD56/Zn8b6LXb5n3evBx2y4O+7ssF75rhDTYTh1LW5AKsL3bEjODoavVJKupaQqwrZU4bSMqWlsqz1KtQ2hM1K7We+KqulloSM6u1lrCHXL4BmZCDi/SFTDzsat1kmAmYVbrbMWlzcH6ID967LIUyJvI7JUjo0btJXgAjFztao0AcCGhgtg+5x0EYjgQjf+0OQPv8txLwswKYdi2rOLCvkZJS80cFd6aqKmmoMzpAQ1dlDlzx1ZE/G9W8kKGaGuk9IlyUSIoU0RrCOqes7HCWh3BZSS5SgKKEOahEpWCWEVCesxt5mk6UYaIHl4nn1KInEzCthNpHsKVL+G1iT57A/4Jsl8SlzlVtOudbCNqhBfkcIyazp5pIXPtboZ+KY6U0GsTMgrRKsYWMQfpLq1bP0VYgheKr35MUCk0sYKjcpGIHxPNaC2qpiRcTptL2/waiReKT7UWI8GR8InOoAocuq2GSkKEACbVrp+clDlGiMOpxScS8MPBgaxZViJ+hbtUcNoTgfH4heD/C+g+45dgpDgIbr2Ce3HoxU8SkF52US0YBr/TrBja8VWAC7uxSEOp1ZiV8f+RIJfGJtcJG+X47/VdKtBqdqVmrsFV0ZGD+jIN9R2yxZwBAcDN7F5uiM/cm10VHvP9vx0UmHLkatL0K2q0dWDH7I9qMbnl/dKSvyTMBI6pnD2nFChjTLeSBzn4lp23nJV19b3yyI4LwjClD1qNkRb7IRyvGbtOarLGbFBjx+f4fGTHTYVjqaZKvbQrC4Oiz3w05YrKwKHOw9DwAyVjsjtD4wA2iBmtxhTe1+hifcvOOwz+pUJQbTVhbMmav8OS0HJjiO4M4GvFwUhz4vdn1aSYPSEx7D2JI1V+kAYQfCorAQSX2jpda5kubzEAf1oN1aWJVIqzcIhdNFuLGY5AuGuHg9O8jqrNI/y4+H6WEn9PoOniA2/NHLYOfN3MVIP6wmmrMcVrlwtf8sdx/BJRWuY10Hft8vm/Ca+nX7tMIZhv0veP42h70NKqmhW4Ne6JyeaD824NzOXTXp6lglHQ3KxBCpNzyaHrfEyJwAwpZMTH15lTbS7Er77fKvOYwkfF9bN/iXgfMHEdCdc9E/M98AOA2lG/EYuEEy6Gi3icSN8kA/EWhB3DAjkjQKmZRDm+hf7FSh+21HJ6y8wshdgdYAUT+me4JadxcJzBvlbisPMBC/h6NkDtIDOFHckz4paNTQTt7s4aC8ehziIm16ThbpvgMaOBs+iM5ZiG2CHRbZoog4Z1SJZfGrhUmEYoTgzXGlcKBYOGtBCmWwnBw90Zw5RlhqQIhfljLMNonGqIVYKpfplJUCrYKgHDFCsiUhGYqfk93+F+t0VYV6thmGLERCqiM/c5t5gQhWwahV3KFACyS8qaQ+WuIY5NdidTAKot32b2Z+8rJbAEF+1TOzFlVMQpoiUnnNlaOKSnOFz9eCglVMxxYR/VY6KawFLBu6XCJqCWX804bXGcc+i3M+VExYC1+beKmyJqIrY0JRLnthQ2AcjvNeY/CJwpzk4XNgmcijkSv/tKzMrVk38Dave7rC0b3PWJ3Yq4TM6XESoARhdmV2v8BoY5l/5FDOSdDrerdWbBMAfxgkf/eIeJDtMcu1onF7fKh5nM1gndIYcsGhLbKjlsW3Kyq/V24yoG4YV+TFUMjeYgTrjQO+hqMeOPNm1dU9FhzgknVRj4usOs1YxTh5HQwcGKn423MPZwBR+26Z1kMUzYvmXe68F9fzY+xUALmgmHdxhLeoD7GeRwAzOmd2Ul4GscmfnkpRgevrosv4j/G7YxJga+noqkaZIP2w+AvscjamJLY1JErWnkRiQftlsakeISxpQQjQXn1qf77G7AgwcPHjx48OABAAD8Bs85I3Rnu+QYAAAAAElFTkSuQmCC",K="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGYAAABmCAYAAAA53+RiAAAAAXNSR0IArs4c6QAAAARzQklUCAgICHwIZIgAAATfSURBVHic7Z1tcuMgDIbFzt6r9GQlJ4M92bs/QtvUjc2HJIyJnpmddFsbBK8lBMYOkWEYhmEYhmEYO7izDeACwOcfPRGlz98759Lvo6/DJYQBEB7++5Y/feXp6eHnf0SUri7aqQAI+Z8W8cHbpmMaj8md5OnuEX5w9YmIbkTXD4FiKHtFDxETeNJpHoPvcePjLBsKJCK6vZQHYT4vOSJiAg9SBdcSZEsY2VdDQllu1Kwhq5X3EeHtj3YFi4lCRBRHe484uHboKhE0+04tlAGINH4+MprknHvXKFg8lCF7Ca0vChGRz97jpQsWFQbrjSe1ROnQJhbK8lUTpcq7KGIZm4gwJso3zjmRPpUKZa8Yvp6Skx42bGFeJPtqwUuMNyxhsgGea8SCfHDF6Y6HnRnY1+D4kGJ+0Jzi3vJnyp+e2tt7c84FIXvKAPDooKLM2DcJFyMUbGxGtONLoK8DqwZFnLOMEyptUyt7S3MoQ39q3OTWeJ5UJLpvqNj+7hmP5+5t4Gi1KVBHBiqVQh+C/nDjO+ryuHtQ87mFMrsyJ/R7c3NdrYZ1jS29wswGQ5hmcVrTZZtIzgbTW1bxGG4fhNq6WjyGu9TgmeevQHXEqRJmhatdCHYor+3LWo+RGFveyoe8BL7moKr8GpCZwQ7J5xUZ2Q9FjxEMY0monDO5lQ8pI9KnkFm/WuYmmkBfABXZmfq+sozIlTYJErtieOMt+Hk7sJC3fAKBhVauAZEty6KptkC/hKPytUPZyo/VqYZnbWFWGlukORxnDvNpgBcLrz5vKaHZP5oekxTLnoWkVfCuMAKD9vZO44qotXHUPMZ4wtHFb6GMR9Iq+EgYr1Wp8YXf+4OFskkxYSZFUxivWPbymMfw8Mzz094fTBgearfLj4RJzLJtDxoD85hO8P0ar26OVt53hZFYri/dczD2UV1dJlp3hRkCjzhyVpcTp2KiNb1GIoxRoW9LwrzCCnEPEonN4U1EdY8hgQdFZwKDHgguxn+JcYZojbEGgi+aKPVHTbqcJAzBGtuYpOZmqXRAjTBS44y/sjgSWdgDxU0qoyeYlxRHWBQ5IP/8fRTYU6AO7jsuxdsubaAGQcxIYRTb7KUNrSGi7yqTNZYBlL9P4AyD/eZ4X3HOL8O35Yyiw9YegpbxRzy9GjobHKEsEr6/bSN22NeFVltqO9l3nndEEGxDZNrSi242WmlEeHIeRxwvaL/EMz/NSNl/1LDaDg5Pzo0dbfpVzsA2SCHehr2GdRvU2CA198e4kNbVht6ZP+e5l3eqX3/TfL5m1C2Nsc8IoTIcHJwfe88VbIM2odc21lJ8ZeftvqwNP7+X7JF/RETa75OE7pvV1d77XwSVGc4pxlUA3STAc2xjrS7nnTTFGIqJ18SUGPLlP0Uqr7xwtp1boDOnCWe36weV4kTMtWApLUw4u01PqRRnGoGEhQmStolvkEB7ppPy5+e84jNDU/8OSshtrhj7RvJeGjznCD/ATgmPCRq2/dUo1DkXcM+SV9/xr5Z9qW3GyK59zgRrDKopseouGedcyhvbkmY9g7m5O0mzkiHbl/LSRMvi5Ywkusog3wPqEwM/wJbawT9o2zIFqPuuGD/IDhNkS0EgP6h+E+QI/N6x4gfUuRUmaNd5WXJn+cH1hVH1GYZhGIZhGIbB5j/7ab3O3Su9oAAAAABJRU5ErkJggg==",C="/assets/bulletin-board.d6a73965.png";const v=u({name:"HomePage",components:{},setup(){return{displayList:[{title:"\u7075\u611F\uFF0C\u65E0\u5E8F\u4E2D\u7406\u6E05\u903B\u8F91",img:"/src/assets/picture/list01.png",introduce:"\u611F\u53D7\u81EA\u7531\u521B\u4F5C\uFF0C\u6216\u4E3A\u4F60\u5C55\u73B0\u5185\u5FC3\u6DF1\u5904\u7684\u6240\u6C42\u6240\u60F3\uFF0C\u6216\u662F\u8086\u610F\u8868\u8FBE\u7684\u9163\u7545\u6DCB\u6F13\uFF0C\u6216\u662F\u4E00\u573A\u6E38\u620F\u4E00\u573A\u68A6\u843D\u4E86\u4E00\u573A\u7A7A\u7684\u6005\u7136\u3002"},{title:"\u968F\u6027\uFF0C\u505A\u4EBA\u8981\u6F47\u6D12\u4E00\u70B9",img:"/src/assets/picture/list02.png",introduce:"\u5907\u597D\u7B14\u58A8\uFF0C\u6B63\u895F\u5371\u5750\uFF0C\u7709\u5934\u7D27\u76B1\uFF0C\u662F\u827A\u672F\u7684\u5E84\u91CD\u3002\u4E3E\u8D77\u53CC\u624B\uFF0C\u8086\u610F\u6325\u821E\uFF0C\u653E\u7A7A\u81EA\u6211\uFF0C\u662F\u67D3\u6307\u4E16\u754C\u7684\u81EA\u7531\uFF0C\u4EC5\u4EC5\u611F\u53D7\uFF0C\u4EC5\u4EC5\u8868\u8FBE\u3002"},{title:"\u5A31\u4E50\uFF0C\u505A\u5012\u6570\u7B2C\u4E8C\u827A\u672F",img:"/src/assets/picture/list03.png",introduce:"\u67D3\u6307\u4E16\u754C\u4E0D\u662F\u4E13\u4E1A\u7684\u7ED8\u753B\u7CFB\u7EDF\uFF0C\u66F4\u591A\u662F\u5A31\u4E50\uFF0C\u662F\u80A2\u4F53\u4E0E\u7075\u611F\u7684\u4EA4\u4E92\uFF0C\u662F\u8BA9\u66F4\u591A\u4EBA\u65E0\u62D8\u65E0\u675F\u65E0\u95E8\u69DB\u7684\u7ED8\u753B\uFF0C\u611F\u53D7\u81EA\u7531\u521B\u4F5C\u7684\u5FEB\u4E50\u3002"},{title:"\u4EA4\u4E92\u827A\u672F\uFF0C\u6D41\u91CF\u5BC6\u7801",img:"/src/assets/picture/list04.png",introduce:"\u628A\u5B83\u7559\u5728\u5546\u573A\u91CC\u3001\u827A\u672F\u9986\u3001\u6216\u8005\u662F\u6BCF\u4E00\u4E2A\u4EBA\u7684\u7535\u8111\u4E0A\uFF0C\u4F60\u53EF\u4EE5\u5C06\u81EA\u5DF1\u7684\u521B\u4F5C\u4E0A\u4F20\u5230\u67D3\u6307\u4E16\u754C\uFF0C\u5411\u66F4\u591A\u4EBA\u5206\u4EAB\u6700\u7EAF\u7CB9\u539F\u59CB\u7684\u56FE\u6848\uFF0C\u4E0E\u67D3\u53CB\u5929\u9A6C\u884C\u7A7A\u7684\u7545\u8C08\u3002"}]}}}),s=e=>(b("data-v-19742cf9"),e=e(),I(),e),H={class:"page"},S=s(()=>t("div",{class:"logo"},[t("img",{src:d}),t("span",{class:"font-zhanku"},"Graffiti World")],-1)),_={class:"menu-bar"},k=s(()=>t("span",null,"Log in",-1)),w=s(()=>t("img",{src:J},null,-1)),D=s(()=>t("a",{href:"https://github.com/Jovetat/GraffitiWorld"},[t("span",null,"GitHub"),t("img",{src:K})],-1)),E=s(()=>t("div",{class:"title"},[t("img",{src:d}),t("span",{class:"font-zhanku"},"\u67D3\u6307\u4E16\u754C")],-1)),R=s(()=>t("span",{class:"font-zhanku slogan"},"\u4E00\u4E2A\u5173\u4E8E\u624B\u52BF\u8BC6\u522B\u7684\u6D82\u9E26\u4E16\u754C",-1)),x={class:"menu-btn"},y={class:"display"},B={class:"display-list"},M=["src"],O={class:"display-list-text"},V=s(()=>t("img",{src:C,class:"display-board"},null,-1)),N=s(()=>t("span",{class:"author-signature font-zhanku"},"by Jove",-1));function Z(e,q,z,T,U,F){const n=f("router-link"),l=g;return c(),r("div",H,[S,t("div",_,[o(n,{to:"/login"},{default:a(()=>[k,w]),_:1}),D]),E,R,t("div",x,[o(l,{type:"primary"},{default:a(()=>[o(n,{to:"/board"},{default:a(()=>[A("\u5F00\u59CB\u521B\u4F5C")]),_:1})]),_:1}),o(l,{type:"primary"},{default:a(()=>[o(n,{to:"/community"},{default:a(()=>[A("\u5206\u4EAB\u4E16\u754C")]),_:1})]),_:1})]),t("div",y,[t("div",B,[(c(!0),r(G,null,Y(e.displayList,(i,m)=>(c(),r("div",{key:m,class:"display-list-item"},[t("img",{src:i.img},null,8,M),t("div",O,[t("span",null,p(i.title),1),t("span",null,p(i.introduce),1)])]))),128))]),V]),N])}const X=h(v,[["render",Z],["__scopeId","data-v-19742cf9"]]);export{X as default}; 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/HomePage.ecb45140.css: -------------------------------------------------------------------------------- 1 | .page[data-v-19742cf9]{position:fixed;width:100%;height:100%;top:0px;background-color:#39393a;overflow-y:auto}.font-zhanku[data-v-19742cf9]{font-family:zhanku;color:#fff}.logo[data-v-19742cf9]{position:absolute;width:265px;left:1%;top:2%;display:flex;justify-content:space-between;align-items:center}.logo img[data-v-19742cf9]{width:42px;height:42px}.logo span[data-v-19742cf9]{font-size:34px}.menu-bar[data-v-19742cf9]{width:350px;position:absolute;right:1%;top:2%;display:flex;justify-content:space-around}.menu-bar a[data-v-19742cf9]{width:155px;height:47px;border-radius:22px;box-shadow:2px 2px 4px rgba(0,0,0,.25);display:flex;align-items:center;justify-content:center;cursor:pointer}.menu-bar a img[data-v-19742cf9]{width:30px;height:30px}.menu-bar a span[data-v-19742cf9]{font-size:23px;font-weight:300;width:98px;margin-left:5px;letter-spacing:3px;color:#fff}.menu-bar>a[data-v-19742cf9]:nth-child(1){border:4px solid #ff8552}.menu-bar>a[data-v-19742cf9]:nth-child(2){background:#ff8552}.title[data-v-19742cf9]{position:relative;width:660px;height:156px;margin-top:120px;left:50%;transform:translate(-50%);border-bottom:solid #ffffff 4px}.title img[data-v-19742cf9]{position:relative;left:-20px;width:157px;height:157px}.title>span[data-v-19742cf9]:nth-child(2){font-size:83px;width:340px;position:absolute;bottom:-34px;left:60%;transform:translate(-50%)}.slogan[data-v-19742cf9]{display:block;position:relative;left:50%;width:810px;margin-top:20px;transform:translate(-50%);color:#fff;font-size:54px;letter-spacing:8px}.menu-btn[data-v-19742cf9]{position:relative;display:flex;justify-content:space-around;margin-top:40px;left:50%;width:600px;transform:translate(-50%)}.menu-btn button[data-v-19742cf9]{font-size:36px;border-radius:22px;width:221px;height:67px}.display[data-v-19742cf9]{width:80%;height:390px;position:relative;left:50%;transform:translate(-50%);bottom:-5%;display:flex;border-top:4px #ff8552 solid}.display .display-list[data-v-19742cf9]{display:flex;flex-wrap:wrap;justify-content:center}.display .display-list-item[data-v-19742cf9]{width:630px;height:180px;border-radius:22px;margin:10px;background:linear-gradient(180deg,rgba(0,0,0,.17) 0%,rgba(0,0,0,.14) 100%);box-shadow:0 2px 6px 2px rgba(0,0,0,.25);display:flex;align-items:center;padding:20px}.display .display-list-item img[data-v-19742cf9]{width:75px;height:75px}.display .display-list span[data-v-19742cf9]{color:#fff}.display .display-list-text[data-v-19742cf9]{display:flex;flex-direction:column;margin-left:37px;height:100%;align-items:center;justify-content:space-around}.display .display-list-text[data-v-19742cf9] :nth-child(1){font-size:25px;letter-spacing:1px}.display .display-list-text[data-v-19742cf9] :nth-child(2){font-size:19px;font-weight:100;letter-spacing:1px}.display-board[data-v-19742cf9]{width:47px;height:353px;right:0%;position:absolute}.author-signature[data-v-19742cf9]{position:fixed;bottom:4px;right:20px;font-size:20px;font-weight:400;letter-spacing:3px;color:#fff} 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/KeyCode-legacy-af0a6abe.js: -------------------------------------------------------------------------------- 1 | System.register(["./index-legacy-32b0ceb6.js"],(function(e,t){"use strict";var n,r,E,a,i,s,c,o,u,N,T,_;return{setters:[function(e){n=e.G,r=e.aa,E=e.q,a=e.d,i=e.P,s=e.aK,c=e.s,o=e.x,u=e.n,N=e.j,T=e.b,_=e.aD}],execute:function(){e({a:function(e,t,n,r){if(e&&e.addEventListener){var E=r;void 0!==E||!U||"touchstart"!==t&&"touchmove"!==t&&"wheel"!==t||(E={passive:!1}),e.addEventListener(t,n,E)}return{remove:function(){e&&e.removeEventListener&&e.removeEventListener(t,n)}}},c:function(e,t){return!!e&&e.contains(t)}});var t=!1;try{var S=Object.defineProperty({},"passive",{get:function(){t=!0}});window.addEventListener("testPassive",null,S),window.removeEventListener("testPassive",null,S)}catch(R){}var U=e("s",t),M=Symbol("TriggerContextKey"),C=(e("u",(function(e){return e?n(M,{setPortal:function(){},popPortal:!1}):{setPortal:function(){},popPortal:!1}})),Symbol("PortalContextKey")),A=e("b",(function(e){r(C,{inTriggerContext:(arguments.length>1&&void 0!==arguments[1]?arguments[1]:{inTriggerContext:!0}).inTriggerContext,shouldRender:E((function(){var t=e||{},n=t.sPopupVisible,r=t.popupRef,E=t.forceRender,a=t.autoDestroy,i=!1;return(n||r||E)&&(i=!0),!n&&a&&(i=!1),i}))})})),O=(e("P",a({compatConfig:{MODE:3},name:"Portal",inheritAttrs:!1,props:{getContainer:i.func.isRequired,didUpdate:Function},setup:function(e,t){var r,a=t.slots,i=!0,S=function(){A({},{inTriggerContext:!1});var e=n(C,{shouldRender:E((function(){return!1})),inTriggerContext:!1});return{shouldRender:E((function(){return e.shouldRender.value||!1===e.inTriggerContext}))}}().shouldRender;s((function(){i=!1,S.value&&(r=e.getContainer())}));var U=c(S,(function(){S.value&&!r&&(r=e.getContainer()),r&&U()}));return o((function(){u((function(){var t;S.value&&(null===(t=e.didUpdate)||void 0===t||t.call(e,e))}))})),N((function(){r&&r.parentNode&&r.parentNode.removeChild(r)})),function(){return S.value?i?null===(e=a.default)||void 0===e?void 0:e.call(a):r?T(_,{to:r},a):null:null;var e}}})),{MAC_ENTER:3,BACKSPACE:8,TAB:9,NUM_CENTER:12,ENTER:13,SHIFT:16,CTRL:17,ALT:18,PAUSE:19,CAPS_LOCK:20,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,PRINT_SCREEN:44,INSERT:45,DELETE:46,ZERO:48,ONE:49,TWO:50,THREE:51,FOUR:52,FIVE:53,SIX:54,SEVEN:55,EIGHT:56,NINE:57,QUESTION_MARK:63,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,META:91,WIN_KEY_RIGHT:92,CONTEXT_MENU:93,NUM_ZERO:96,NUM_ONE:97,NUM_TWO:98,NUM_THREE:99,NUM_FOUR:100,NUM_FIVE:101,NUM_SIX:102,NUM_SEVEN:103,NUM_EIGHT:104,NUM_NINE:105,NUM_MULTIPLY:106,NUM_PLUS:107,NUM_MINUS:109,NUM_PERIOD:110,NUM_DIVISION:111,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,NUMLOCK:144,SEMICOLON:186,DASH:189,EQUALS:187,COMMA:188,PERIOD:190,SLASH:191,APOSTROPHE:192,SINGLE_QUOTE:222,OPEN_SQUARE_BRACKET:219,BACKSLASH:220,CLOSE_SQUARE_BRACKET:221,WIN_KEY:224,MAC_FF_META:224,WIN_IME:229,isTextModifyingKeyEvent:function(e){var t=e.keyCode;if(e.altKey&&!e.ctrlKey||e.metaKey||t>=O.F1&&t<=O.F12)return!1;switch(t){case O.ALT:case O.CAPS_LOCK:case O.CONTEXT_MENU:case O.CTRL:case O.DOWN:case O.END:case O.ESC:case O.HOME:case O.INSERT:case O.LEFT:case O.MAC_FF_META:case O.META:case O.NUMLOCK:case O.NUM_CENTER:case O.PAGE_DOWN:case O.PAGE_UP:case O.PAUSE:case O.PRINT_SCREEN:case O.RIGHT:case O.SHIFT:case O.UP:case O.WIN_KEY:case O.WIN_KEY_RIGHT:return!1;default:return!0}},isCharacterKey:function(e){if(e>=O.ZERO&&e<=O.NINE)return!0;if(e>=O.NUM_ZERO&&e<=O.NUM_MULTIPLY)return!0;if(e>=O.A&&e<=O.Z)return!0;if(-1!==window.navigator.userAgent.indexOf("WebKit")&&0===e)return!0;switch(e){case O.SPACE:case O.QUESTION_MARK:case O.NUM_PLUS:case O.NUM_MINUS:case O.NUM_PERIOD:case O.NUM_DIVISION:case O.SEMICOLON:case O.DASH:case O.EQUALS:case O.COMMA:case O.PERIOD:case O.SLASH:case O.APOSTROPHE:case O.SINGLE_QUOTE:case O.OPEN_SQUARE_BRACKET:case O.BACKSLASH:case O.CLOSE_SQUARE_BRACKET:return!0;default:return!1}}});e("K",O)}}})); 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/KeyCode.612a5580.js: -------------------------------------------------------------------------------- 1 | import{G as l,aa as S,q as N,d as _,P as M,aK as R,s as U,x as v,n as C,j as I,b as d,aD as A}from"./index.74d00390.js";var T=!1;try{var f=Object.defineProperty({},"passive",{get:function(){T=!0}});window.addEventListener("testPassive",null,f),window.removeEventListener("testPassive",null,f)}catch(n){}const O=T;function p(n,t,a,s){if(n&&n.addEventListener){var i=s;i===void 0&&O&&(t==="touchstart"||t==="touchmove"||t==="wheel")&&(i={passive:!1}),n.addEventListener(t,a,i)}return{remove:function(){n&&n.removeEventListener&&n.removeEventListener(t,a)}}}function H(n,t){return n?n.contains(t):!1}var L=Symbol("TriggerContextKey"),h=function(t){return t?l(L,{setPortal:function(){},popPortal:!1}):{setPortal:function(){},popPortal:!1}},P=Symbol("PortalContextKey"),K=function(t){var a=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{inTriggerContext:!0};S(P,{inTriggerContext:a.inTriggerContext,shouldRender:N(function(){var s=t||{},i=s.sPopupVisible,r=s.popupRef,c=s.forceRender,o=s.autoDestroy,u=!1;return(i||r||c)&&(u=!0),!i&&o&&(u=!1),u})})},g=function(){K({},{inTriggerContext:!1});var t=l(P,{shouldRender:N(function(){return!1}),inTriggerContext:!1});return{shouldRender:N(function(){return t.shouldRender.value||t.inTriggerContext===!1})}};const m=_({compatConfig:{MODE:3},name:"Portal",inheritAttrs:!1,props:{getContainer:M.func.isRequired,didUpdate:Function},setup:function(t,a){var s=a.slots,i=!0,r,c=g(),o=c.shouldRender;R(function(){i=!1,o.value&&(r=t.getContainer())});var u=U(o,function(){o.value&&!r&&(r=t.getContainer()),r&&u()});return v(function(){C(function(){if(o.value){var E;(E=t.didUpdate)===null||E===void 0||E.call(t,t)}})}),I(function(){r&&r.parentNode&&r.parentNode.removeChild(r)}),function(){if(!o.value)return null;if(i){var E;return(E=s.default)===null||E===void 0?void 0:E.call(s)}return r?d(A,{to:r},s):null}}});var e={MAC_ENTER:3,BACKSPACE:8,TAB:9,NUM_CENTER:12,ENTER:13,SHIFT:16,CTRL:17,ALT:18,PAUSE:19,CAPS_LOCK:20,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,PRINT_SCREEN:44,INSERT:45,DELETE:46,ZERO:48,ONE:49,TWO:50,THREE:51,FOUR:52,FIVE:53,SIX:54,SEVEN:55,EIGHT:56,NINE:57,QUESTION_MARK:63,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,META:91,WIN_KEY_RIGHT:92,CONTEXT_MENU:93,NUM_ZERO:96,NUM_ONE:97,NUM_TWO:98,NUM_THREE:99,NUM_FOUR:100,NUM_FIVE:101,NUM_SIX:102,NUM_SEVEN:103,NUM_EIGHT:104,NUM_NINE:105,NUM_MULTIPLY:106,NUM_PLUS:107,NUM_MINUS:109,NUM_PERIOD:110,NUM_DIVISION:111,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,NUMLOCK:144,SEMICOLON:186,DASH:189,EQUALS:187,COMMA:188,PERIOD:190,SLASH:191,APOSTROPHE:192,SINGLE_QUOTE:222,OPEN_SQUARE_BRACKET:219,BACKSLASH:220,CLOSE_SQUARE_BRACKET:221,WIN_KEY:224,MAC_FF_META:224,WIN_IME:229,isTextModifyingKeyEvent:function(t){var a=t.keyCode;if(t.altKey&&!t.ctrlKey||t.metaKey||a>=e.F1&&a<=e.F12)return!1;switch(a){case e.ALT:case e.CAPS_LOCK:case e.CONTEXT_MENU:case e.CTRL:case e.DOWN:case e.END:case e.ESC:case e.HOME:case e.INSERT:case e.LEFT:case e.MAC_FF_META:case e.META:case e.NUMLOCK:case e.NUM_CENTER:case e.PAGE_DOWN:case e.PAGE_UP:case e.PAUSE:case e.PRINT_SCREEN:case e.RIGHT:case e.SHIFT:case e.UP:case e.WIN_KEY:case e.WIN_KEY_RIGHT:return!1;default:return!0}},isCharacterKey:function(t){if(t>=e.ZERO&&t<=e.NINE||t>=e.NUM_ZERO&&t<=e.NUM_MULTIPLY||t>=e.A&&t<=e.Z||window.navigator.userAgent.indexOf("WebKit")!==-1&&t===0)return!0;switch(t){case e.SPACE:case e.QUESTION_MARK:case e.NUM_PLUS:case e.NUM_MINUS:case e.NUM_PERIOD:case e.NUM_DIVISION:case e.SEMICOLON:case e.DASH:case e.EQUALS:case e.COMMA:case e.PERIOD:case e.SLASH:case e.APOSTROPHE:case e.SINGLE_QUOTE:case e.OPEN_SQUARE_BRACKET:case e.BACKSLASH:case e.CLOSE_SQUARE_BRACKET:return!0;default:return!1}}};const D=e;export{D as K,m as P,p as a,K as b,H as c,O as s,h as u}; 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/LeftOutlined-legacy-44ab7e9c.js: -------------------------------------------------------------------------------- 1 | System.register(["./index-legacy-32b0ceb6.js"],(function(e,t){"use strict";var r,n;return{setters:[function(e){r=e.b,n=e.E}],execute:function(){var t={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"}}]},name:"right",theme:"outlined"};function c(e){for(var t=1;t{const{retCode:n}=await pe(u);n===200&&a.splice(a.findIndex(i=>i.id===u),1)};return E(async()=>{const{retCode:u,list:n}=await me();u===200&&(n.forEach(i=>{i.image=_e(i.image),i.time=Ce(i.time)}),a.splice(0,a.length,...n))}),{myList:a,confirm:e}}}),Ye=a=>(Re("data-v-68521f01"),a=a(),Se(),a),Ze={class:"list"},et={class:"list-head"},tt={class:"list-address"},ot=Ye(()=>g("img",{src:Je,class:"list-btn"},null,-1)),nt={class:"list-works"},at={class:"list-time"},it={class:"list-title"};function lt(a,e,u,n,i,b){const v=He,_=ve;return R(),S("div",Ze,[(R(!0),S(De,null,we(a.myList,s=>(R(),S("div",{key:s.id,class:"list-item"},[g("div",et,[g("span",tt,L(s.address),1),d(v,{title:"\u786E\u5B9A\u5220\u9664\u8BE5\u4F5C\u54C1\u5417?","ok-text":"\u662F","cancel-text":"\u5426",onConfirm:x=>a.confirm(s.id)},{default:Oe(()=>[ot]),_:2},1032,["onConfirm"])]),g("div",nt,[d(_,{src:s.image},null,8,["src"])]),g("span",at,L(s.time),1),g("span",it,L(s.title),1)]))),128))])}const bt=Ne(Qe,[["render",lt],["__scopeId","data-v-68521f01"]]);export{bt as default}; 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/MyWork.7df89392.css: -------------------------------------------------------------------------------- 1 | .ant-popover{box-sizing:border-box;margin:0;padding:0;color:#39393a;font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:"tnum";position:absolute;top:0;left:0;z-index:1030;font-weight:400;white-space:normal;text-align:left;cursor:auto;user-select:text}.ant-popover:after{position:absolute;background:rgba(255,255,255,.01);content:""}.ant-popover-hidden{display:none}.ant-popover-placement-top,.ant-popover-placement-topLeft,.ant-popover-placement-topRight{padding-bottom:10px}.ant-popover-placement-right,.ant-popover-placement-rightTop,.ant-popover-placement-rightBottom{padding-left:10px}.ant-popover-placement-bottom,.ant-popover-placement-bottomLeft,.ant-popover-placement-bottomRight{padding-top:10px}.ant-popover-placement-left,.ant-popover-placement-leftTop,.ant-popover-placement-leftBottom{padding-right:10px}.ant-popover-inner{background-color:#fff;background-clip:padding-box;border-radius:2px;box-shadow:0 3px 6px -4px rgba(0,0,0,.12),0 6px 16px rgba(0,0,0,.08),0 9px 28px 8px rgba(0,0,0,.05);box-shadow:0 0 8px rgba(0,0,0,.15) \ }@media screen and (-ms-high-contrast: active),(-ms-high-contrast: none){.ant-popover-inner{box-shadow:0 3px 6px -4px rgba(0,0,0,.12),0 6px 16px rgba(0,0,0,.08),0 9px 28px 8px rgba(0,0,0,.05)}}.ant-popover-title{min-width:177px;min-height:32px;margin:0;padding:5px 16px 4px;color:rgba(0,0,0,.85);font-weight:500;border-bottom:1px solid #f0f0f0}.ant-popover-inner-content{padding:12px 16px;color:#39393a}.ant-popover-message{position:relative;padding:4px 0 12px;color:#39393a;font-size:14px}.ant-popover-message>.anticon{position:absolute;top:8.0005px;color:#faad14;font-size:14px}.ant-popover-message-title{padding-left:22px}.ant-popover-buttons{margin-bottom:4px;text-align:right}.ant-popover-buttons button{margin-left:8px}.ant-popover-arrow{position:absolute;display:block;width:8.48528137px;height:8.48528137px;overflow:hidden;background:transparent;pointer-events:none}.ant-popover-arrow-content{position:absolute;top:0;right:0;bottom:0;left:0;display:block;width:6px;height:6px;margin:auto;background-color:#fff;content:"";pointer-events:auto}.ant-popover-placement-top .ant-popover-arrow,.ant-popover-placement-topLeft .ant-popover-arrow,.ant-popover-placement-topRight .ant-popover-arrow{bottom:1.51471863px}.ant-popover-placement-top .ant-popover-arrow-content,.ant-popover-placement-topLeft .ant-popover-arrow-content,.ant-popover-placement-topRight .ant-popover-arrow-content{box-shadow:3px 3px 7px rgba(0,0,0,.07);transform:translateY(-4.24264069px) rotate(45deg)}.ant-popover-placement-top .ant-popover-arrow{left:50%;transform:translate(-50%)}.ant-popover-placement-topLeft .ant-popover-arrow{left:16px}.ant-popover-placement-topRight .ant-popover-arrow{right:16px}.ant-popover-placement-right .ant-popover-arrow,.ant-popover-placement-rightTop .ant-popover-arrow,.ant-popover-placement-rightBottom .ant-popover-arrow{left:1.51471863px}.ant-popover-placement-right .ant-popover-arrow-content,.ant-popover-placement-rightTop .ant-popover-arrow-content,.ant-popover-placement-rightBottom .ant-popover-arrow-content{box-shadow:-3px 3px 7px rgba(0,0,0,.07);transform:translate(4.24264069px) rotate(45deg)}.ant-popover-placement-right .ant-popover-arrow{top:50%;transform:translateY(-50%)}.ant-popover-placement-rightTop .ant-popover-arrow{top:12px}.ant-popover-placement-rightBottom .ant-popover-arrow{bottom:12px}.ant-popover-placement-bottom .ant-popover-arrow,.ant-popover-placement-bottomLeft .ant-popover-arrow,.ant-popover-placement-bottomRight .ant-popover-arrow{top:1.51471863px}.ant-popover-placement-bottom .ant-popover-arrow-content,.ant-popover-placement-bottomLeft .ant-popover-arrow-content,.ant-popover-placement-bottomRight .ant-popover-arrow-content{box-shadow:-2px -2px 5px rgba(0,0,0,.06);transform:translateY(4.24264069px) rotate(45deg)}.ant-popover-placement-bottom .ant-popover-arrow{left:50%;transform:translate(-50%)}.ant-popover-placement-bottomLeft .ant-popover-arrow{left:16px}.ant-popover-placement-bottomRight .ant-popover-arrow{right:16px}.ant-popover-placement-left .ant-popover-arrow,.ant-popover-placement-leftTop .ant-popover-arrow,.ant-popover-placement-leftBottom .ant-popover-arrow{right:1.51471863px}.ant-popover-placement-left .ant-popover-arrow-content,.ant-popover-placement-leftTop .ant-popover-arrow-content,.ant-popover-placement-leftBottom .ant-popover-arrow-content{box-shadow:3px -3px 7px rgba(0,0,0,.07);transform:translate(-4.24264069px) rotate(45deg)}.ant-popover-placement-left .ant-popover-arrow{top:50%;transform:translateY(-50%)}.ant-popover-placement-leftTop .ant-popover-arrow{top:12px}.ant-popover-placement-leftBottom .ant-popover-arrow{bottom:12px}.ant-popover-pink .ant-popover-inner,.ant-popover-pink .ant-popover-arrow-content,.ant-popover-magenta .ant-popover-inner,.ant-popover-magenta .ant-popover-arrow-content{background-color:#eb2f96}.ant-popover-red .ant-popover-inner,.ant-popover-red .ant-popover-arrow-content{background-color:#f5222d}.ant-popover-volcano .ant-popover-inner,.ant-popover-volcano .ant-popover-arrow-content{background-color:#fa541c}.ant-popover-orange .ant-popover-inner,.ant-popover-orange .ant-popover-arrow-content{background-color:#fa8c16}.ant-popover-yellow .ant-popover-inner,.ant-popover-yellow .ant-popover-arrow-content{background-color:#fadb14}.ant-popover-gold .ant-popover-inner,.ant-popover-gold .ant-popover-arrow-content{background-color:#faad14}.ant-popover-cyan .ant-popover-inner,.ant-popover-cyan .ant-popover-arrow-content{background-color:#13c2c2}.ant-popover-lime .ant-popover-inner,.ant-popover-lime .ant-popover-arrow-content{background-color:#a0d911}.ant-popover-green .ant-popover-inner,.ant-popover-green .ant-popover-arrow-content{background-color:#52c41a}.ant-popover-blue .ant-popover-inner,.ant-popover-blue .ant-popover-arrow-content{background-color:#1890ff}.ant-popover-geekblue .ant-popover-inner,.ant-popover-geekblue .ant-popover-arrow-content{background-color:#2f54eb}.ant-popover-purple .ant-popover-inner,.ant-popover-purple .ant-popover-arrow-content{background-color:#722ed1}.ant-popover-rtl{direction:rtl;text-align:right}.ant-popover-rtl .ant-popover-message-title{padding-right:22px;padding-left:16px}.ant-popover-rtl .ant-popover-buttons{text-align:left}.ant-popover-rtl .ant-popover-buttons button{margin-right:8px;margin-left:0}.ant-popconfirm{z-index:1060}.list[data-v-68521f01]{display:flex;align-items:flex-start;flex-wrap:wrap;position:relative;left:50%;transform:translate(-50%);width:92%}.list-item[data-v-68521f01]{margin:15px 20px;width:280px;min-height:230px;border-radius:10px;background:#ffffff;box-shadow:0 2px 4px rgba(0,0,0,.25)}.list-head[data-v-68521f01]{display:flex;align-items:center;justify-content:space-between;padding:13px 12px 0 16px}.list-address[data-v-68521f01]{display:inline-block;padding:3px 15px;font-size:12px;font-weight:500;letter-spacing:.24px;color:#15b57e;border-radius:5px;background:#deffe5}.list-btn[data-v-68521f01]{height:20px;width:20px;cursor:pointer}.list-works[data-v-68521f01]{position:relative;left:50%;transform:translate(-50%);width:80%;margin-top:10px}.list-works[data-v-68521f01] .ant-image-img{border-radius:10px;border:2px solid #f6fafd;box-shadow:0 1px 2px rgba(0,0,0,.25)}.list-time[data-v-68521f01]{display:block;text-align:right;margin:10px 30px 0 0;font-size:12px;font-weight:400;color:#79869f}.list-title[data-v-68521f01]{display:block;margin:5px 34px 10px;font-size:18px;font-weight:600;letter-spacing:.32px;color:#0a043c} 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/MyWork.d9613c12.js: -------------------------------------------------------------------------------- 1 | import{_ as e,d as o,o as n,b as t}from"./index.69a84b56.js";const r=o({name:"MyWork",components:{},setup(){return{}}});function s(a,c,p,_,f,m){return n(),t("span",null,"MyWork")}const d=e(r,[["render",s]]);export{d as default}; 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/SourceHanSansSC-Medium.28ad6d9d.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/back-end-source/public/assets/SourceHanSansSC-Medium.28ad6d9d.otf -------------------------------------------------------------------------------- /back-end-source/public/assets/WorkPublished.30ed1ba8.js: -------------------------------------------------------------------------------- 1 | import{a as i}from"./logo.3c3a0206.js";import{_ as p,L as r,b as u}from"./index.e3a7a2eb.js";import{_ as l,d,o as A,V as g,w as e,a as t,p as m,h,e as o}from"./index.69a84b56.js";const w="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHAAAAB0CAYAAABdcbZdAAAACXBIWXMAABcRAAAXEQHKJvM/AAAIJUlEQVR4nO2dvW4jNxDHh0JSpIrSpAp8Tl7ATpfulN6AnSe4c+lK9hP43Fzrc+Uihe0UqQLIF7iO5C6dzi8Q6YwUaRLpEARXBAgDCrO6tby7nOGSXHLFH2D4YscrLv8ccoYfQwEJp9wf7BwCQB8ANvFz3gDA0cb5zcjG5yYBHXJ/sPMCAI5LPuHrjfObN3U/vRPKy7aUfsVrlQnLIgnolm7F06t+RyYJGDkfxVp8KWUPHQP19STnJPQq/myOToRiCgBv8ftUCGHFqfBNFAJKKTdRmKcAsI1fJnTLBJZSAoqrhLwDgGshxNzne5oQrIBSSiXSM6xwU8G45BvHhZRSCfoaxaztMbogKAHR0p6jcJuEP3FNJuixlFJ1tWco5jSAsi0IwolR45mUcgAAE3SvQxBvFVWmU1VGKeUFjsGN06iAUsrnUsoxAAwBYC+ECiGieomhlHLYtJCNCIgWp6ztwuP45oJe00J6FVCNcepl0eJC7CZNyYQc4DjuDS9OjJRSue+HtqaPVhjlYrp8nFfGNoYTWexo03LUMKB6lzMhxAuLzy3FuYAYDgwsWdwUBbtV3w29wUcBO5ZxG+PMXs2ydtFr3f3jZR/+/f23Go/S43Q1QkpZNRtPRVnUlU/3PReD7tVtePOfvoe/f/m56FejjfObb+s8G1wJiF3moEb3pLrCSyVc0wE0itlHMY0moN/f/Qp//fAK/nv/T/7HVgS07sTgC08MxVMWtg8AXwohjkKY/VBlEEIsygQAJ9i4WHyy9Q18fvQSPv7iK+vlsyqgiuvQw+S21IVwQggl3GWIc5CqTMoxEUJ8ZiKkEs+ViFbAoJzLTI2T2OVGhSozlp3Nn1en8v5gZxi7eEPfMZMLstiW+/Lvbn4MQ0AD8ZTVHQZQdKuod+KKiENOo4Xmijdug9WVoRw4fMfwRTQQ76KRgnoGx8YBs278TuRjS+PQbFfRAEwHZ4bhl3tw0J4l8fQwe6mJc28cuwdqH++vVQUMU0S3nimuRCfxmDBFdLOKoQZaRiHWttssgymi3cVh7Dqp414SrwRGrGh3PGS4xaeW37l1MIYhO3WJ+1cohDO3FzgMR7B+V4rmrGMW44R0UzBCsXGtIjKC0SD2SMYEwyk08ykYjksa9wwh+hYTo6cTrc/97EGLYRgJzwoZD45pN3WQEEMLnhUSrc/I68Rn5xuH04XdbBd4vjJCa3hER5FuhcQHsh2XiobhpCvWrJoE43gRQzWaFRKnfNjWh91yFdbnADVOgplz4Ajitgx9o7P2oMfP1bUy6xMBhPcIZncAMayoXhTHAFOH6dgXooBBxa/EoevBULO6L5QyuF/ZLXYixxmhMh5otCrgM80fq82tl6nGnUGp2938fywFxPFAtwibxHMI7kjX1XGpBVLGg9R9uue17hPycWxewKeav5uGmmqjTQghrgnnLpZacSwwykxGkaKr66VWCwFx/NPFRFrTTljjVvOgpa/SWf1BBW20wFCHBG1dZzEsVcCphTN7uuPRLiz8uuJ3o1BzoaGvoSvbQrNMQJ0DU9v68Hz7q5JfTx2FKFWB8YmDz7OJrndQWTaWAupWAt5aKthJgVUo8b5zYQ2YQnK/oDXvR5BekjwOep8zxGWenq+5SFwJ6eFXFMfbCKtCk/z/rCNtk/cMZY1QlahDsYIUwDcCKSdOypkdKJSkRsr4KAIGn3Z4naEImLrPgOm0LO3j2tGhDpaJMElOTOQkASOHImA6eRQwyQLjZt6hxHnpBJJ/qDNkHeI0WZoLDRRqF5os0D86C1wYXiagbm0sWaB/nmg+cTH0ZQLqgnndin3CProZstu8gLoV92SB/tF1oQujo3ah3bSo6w/iToUHYyDFE00BvT/Ii+wd+HCoQidiGgf9sav5pGWP2Sn6YQl7KaB3D/GU2HLHWqfohxWktCLuodRx8YZlwu60QVx1ER+ERHjlyRmIqZ9SN+oIYo6CB4kOVqfSKOcTWndpR0D0CUWp1oiQYiuo/CptgZje7FHdF01mV53oUWymtMpOOCQsGuiPuBMv9UhWaBFGckHaDkJitqZkhZYgJhekRwDEfGkpzbIFGNbHm8okpn3yctV2myFmseenIWNcVJFWKQxh3AhgtpBATI9fL7P6moJdJ6WXM08CyGghqStlopLFE+u2Xg/HuLUlrRcSYVw5UP/STMYlFckrJYBxtt/6ZFzaNE4ilsO8f9Hu0h3jqu21uCvXBEYd2l+2Y169mkRcgXl5pptejHmJYRIRYYgnnTuDzMKsvYjM+vITjjEvu19LEQ3uk/e3XYXpTcl1806jqB9GPJMxWYd5U5y94tRLc43bQERFa/fUMC7MzGj+unZDEZ3eWOYbDLGoMV444mUYijhrgzUWXKcXl3gZKCJleWSVcYwT4Tghbfq+YTp0Bt5XnmEMQqKTwu0uM4bBe+MoIid4LXrJ4M5g4CyUaeOU0cXDjBWMMiY4vjTm7OCwcGowxuWZRbuDDyugTqvNGKOYzgd+7CJPDce3onI7LbNw+XD4kCTo2OKZijmeZbzD71NKdtuSsmU31vTwAOu2xZQqJ0II53ObzgXMwJZ44TBhQnZZxhzFLWILBeo6LIdqVEetzTOOzkCdMSVUJmuzWx09VZMAOERma7srL3IhJ+hppz1AYCfO8sUwpK7SmxNDBT3DPh72D2XCe4pn8y5NPV5XBCdgHvRc99DF9z3NNsLjzKOQPcqgBcyDY802CrmF/7ZloVMMQ+5QsGguu4xGwDJyE+D5IPzTgjhPCfQO/51lplL34scbrwHA/yR8p7LTTFWFAAAAAElFTkSuQmCC",Q="/assets/share_place.26d6793a.png",B="/assets/share_share.03601752.png";const C=d({name:"WorkPublished",setup(){return{}}}),F=s=>(m("data-v-794906a1"),s=s(),h(),s),R=F(()=>o("div",{class:"sider-list"},[o("img",{src:i,class:"sider-logo"}),o("div",{class:"sider-item"},[o("img",{src:w}),o("span",null,"\u515C\u91CC\u6CA1\u6709\u7CD6")]),o("div",{class:"sider-item"},[o("img",{src:Q}),o("span",null,"\u5185\u8499\u53E4\u827A\u672F\u9986")]),o("div",{class:"sider-qrcode"}),o("div",{class:"sider-item2"},[o("img",{src:B}),o("span",null,"\u626B\u63CF\u4E8C\u7EF4\u7801\u4FDD\u5B58\u4F5C\u54C1")])],-1));function f(s,J,W,M,Y,S){const c=r,n=u,a=p;return A(),g(a,null,{default:e(()=>[t(c,{width:"400",class:"sider"},{default:e(()=>[R]),_:1}),t(a,null,{default:e(()=>[t(n,{class:"content"})]),_:1})]),_:1})}const T=l(C,[["render",f],["__scopeId","data-v-794906a1"]]);export{T as default}; 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/WorkPublished.7e5f65e1.css: -------------------------------------------------------------------------------- 1 | .sider[data-v-794906a1]{height:100vh;background-color:#79869f}.sider-list[data-v-794906a1]{display:flex;flex-direction:column;align-items:center;position:relative}.sider-list span[data-v-794906a1]{font-size:26px;color:#fff}.sider-logo[data-v-794906a1]{position:relative;top:10vh;width:200px;height:200px}.sider-item[data-v-794906a1]{display:flex;align-items:center;justify-content:space-between;width:250px;position:relative;top:15vh;margin:1vh}.sider-item img[data-v-794906a1]{width:50px;height:50px}.sider-item2[data-v-794906a1]{display:flex;align-items:center;justify-content:space-between;width:320px;position:relative;top:30vh}.sider-item2 img[data-v-794906a1]{width:50px;height:60px}.sider-qrcode[data-v-794906a1]{width:150px;height:150px;background-color:#fff;position:relative;top:20vh}.content[data-v-794906a1]{background-color:#fff} 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/WorkPublished.ebb692e5.css: -------------------------------------------------------------------------------- 1 | .sider[data-v-87881e6c]{height:100vh;background-color:#79869f}.sider-list[data-v-87881e6c]{display:flex;flex-direction:column;align-items:center;position:relative}.sider-list span[data-v-87881e6c]{font-size:26px;color:#fff}.sider-logo[data-v-87881e6c]{position:relative;top:10vh;width:200px;height:200px}.sider-item[data-v-87881e6c]{display:flex;align-items:center;width:290px;position:relative;top:15vh;margin:1vh}.sider-item img[data-v-87881e6c]{width:50px;height:50px}.sider-item span[data-v-87881e6c]{margin-left:10px}.sider-item2[data-v-87881e6c]{display:flex;align-items:center;justify-content:space-between;width:320px;position:relative;top:28vh}.sider-item2 img[data-v-87881e6c]{width:50px;height:60px}.sider-qrcode[data-v-87881e6c]{width:150px;height:150px;background-color:#fff;position:relative;top:20vh}.sider-qrcode img[data-v-87881e6c]{width:100%;height:100%}.content[data-v-87881e6c]{display:flex;justify-content:center;align-items:center;background-color:#fff}.content-work[data-v-87881e6c]{box-shadow:0 2px 4px rgba(0,0,0,.25);border-radius:8px;max-width:60%;height:auto}.content-router[data-v-87881e6c]{position:absolute;bottom:35px;right:-2px;height:58px} 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/World.22440fa0.js: -------------------------------------------------------------------------------- 1 | import"./default.4e7f899b.js";import{_ as m}from"./index.6b0f092b.js";import{q as u,l as _}from"./community.9cca54ed.js";import{e as f,f as k}from"./encode.3924075c.js";import{_ as g}from"./user_profile.8df7d38a.js";import{_ as h,d as v,o as c,c as r,F as L,e as y,m as C,i as w,a as s,t as n,b as $,a0 as d,p as I,g as S}from"./index.74d00390.js";import"./EyeOutlined.d2dbf2e4.js";import"./useMergedState.73854052.js";import"./KeyCode.612a5580.js";import"./classCallCheck.eb07dae8.js";import"./LeftOutlined.fdb37b97.js";const x=v({name:"World",components:{},setup(){const o=C([]),l=async a=>{const i=o.value.find(t=>t.id===a);if(i.isLike){const{retCode:t}=await _(a,-1);if(t!==200)return;i.likes--}else{const{retCode:t}=await _(a,1);if(t!==200)return;i.likes++}i.isLike=!i.isLike};return w(async()=>{const{retCode:a,list:i}=await u();a===200&&(i.forEach(t=>{t.image=f(t.image),t.time=k(t.time),t.isLike=!1,t.isComment=!1}),o.value=i)}),{worksList:o,giveALike:l}}}),E=o=>(I("data-v-a7daf1ca"),o=o(),S(),o),B={class:"list"},W={class:"list-address"},b={class:"list-works"},q={class:"list-time"},A={class:"list-title"},D={class:"list-user"},F=E(()=>s("img",{src:g,class:"list-profile"},null,-1)),N={class:"list-user-right"},V={class:"list-nickname"},z={class:"list-btn"},M=["onClick"],j=["src"],G=["src"];function H(o,l,a,i,t,J){const p=m;return c(),r("div",B,[(c(!0),r(L,null,y(o.worksList,e=>(c(),r("div",{key:e.id,class:"list-item"},[s("span",W,n(e.address),1),s("div",b,[$(p,{src:e.image},null,8,["src"])]),s("span",q,n(e.time),1),s("span",A,n(e.title),1),s("div",D,[F,s("div",N,[s("span",V,n(e.nickname),1),s("div",z,[s("div",{style:{"margin-right":"18px"},onClick:K=>o.giveALike(e.id)},[s("img",{src:`./src/assets/picture/card_praise${e.isLike?"_actived":""}.png`},null,8,j),s("span",{style:d(e.isLike?"color: #E33C64;":"")},"\u8D5E"+n(e.likes),5)],8,M),s("div",null,[s("img",{src:`./src/assets/picture/card_comment${e.isComment?"_actived":""}.png`},null,8,G),s("span",{style:d(e.isComment?"color: #E33C64;":"")},"2\u6761\u8BC4\u8BBA",4)])])])])]))),128))])}const es=h(x,[["render",H],["__scopeId","data-v-a7daf1ca"]]);export{es as default}; 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/World.9560997f.js: -------------------------------------------------------------------------------- 1 | import{_ as e,d as o,o as n,b as t}from"./index.69a84b56.js";const r=o({name:"World",components:{},setup(){return{}}});function s(a,c,p,d,l,_){return n(),t("span",null,"World")}const m=e(r,[["render",s]]);export{m as default}; 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/World.e046ce4e.css: -------------------------------------------------------------------------------- 1 | .list[data-v-a7daf1ca]{display:flex;align-items:flex-start;flex-wrap:wrap;position:relative;left:50%;transform:translate(-50%);width:92%}.list-item[data-v-a7daf1ca]{margin:15px 20px;width:280px;min-height:280px;border-radius:10px;background:#ffffff;box-shadow:0 2px 4px rgba(0,0,0,.25)}.list-address[data-v-a7daf1ca]{display:inline-block;margin:10px 0 0 16px;padding:3px 15px;font-size:12px;font-weight:500;letter-spacing:.24px;color:#15b57e;border-radius:5px;background:#deffe5}.list-works[data-v-a7daf1ca]{position:relative;left:50%;transform:translate(-50%);width:80%;margin-top:10px}.list-works[data-v-a7daf1ca] .ant-image-img{border-radius:10px;border:2px solid #f6fafd;box-shadow:0 1px 2px rgba(0,0,0,.25)}.list-time[data-v-a7daf1ca]{display:block;text-align:right;margin:10px 30px 0 0;font-size:12px;font-weight:400;color:#79869f}.list-title[data-v-a7daf1ca]{display:block;margin:5px 34px 0;font-size:18px;font-weight:600;letter-spacing:.32px;color:#0a043c}.list-profile[data-v-a7daf1ca]{width:45px;height:45px;border-radius:50%;margin:5px 14px 0 0}.list-user[data-v-a7daf1ca]{display:flex;position:relative;left:50%;transform:translate(-50%);width:80%;height:70px;margin-top:10px}.list-user-right[data-v-a7daf1ca]{width:100%;display:flex;flex-direction:column}.list-nickname[data-v-a7daf1ca]{font-size:15px;font-weight:600;letter-spacing:.32px;line-height:16px;color:#0a043c;margin:5px 0 0 5px}.list-btn[data-v-a7daf1ca]{display:flex;align-items:center;width:100%;margin-top:5px}.list-btn div[data-v-a7daf1ca]{cursor:pointer}.list-btn img[data-v-a7daf1ca]{width:26px;height:25px;margin:0 5px 0 0}.list-btn span[data-v-a7daf1ca]{font-size:10px;font-weight:500;letter-spacing:.2px;color:#79869f} 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/background_1.6f1bdf9d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/back-end-source/public/assets/background_1.6f1bdf9d.png -------------------------------------------------------------------------------- /back-end-source/public/assets/bulletin-board.d6a73965.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/back-end-source/public/assets/bulletin-board.d6a73965.png -------------------------------------------------------------------------------- /back-end-source/public/assets/classCallCheck-legacy-e50054a3.js: -------------------------------------------------------------------------------- 1 | System.register(["./index-legacy-32b0ceb6.js"],(function(e,n){"use strict";var t;return{setters:[function(e){t=e.D}],execute:function(){e({_:function(e,n,t){return n&&c(e.prototype,n),t&&c(e,t),Object.defineProperty(e,"prototype",{writable:!1}),e},a:function(e,n){if(!(e instanceof n))throw new TypeError("Cannot call a class as a function")},w:a});var n=function(e){return setTimeout(e,16)},r=function(e){return clearTimeout(e)};"undefined"!=typeof window&&"requestAnimationFrame"in window&&(n=function(e){return window.requestAnimationFrame(e)},r=function(e){return window.cancelAnimationFrame(e)});var i=0,o=new Map;function u(e){o.delete(e)}function a(e){var t=i+=1;return function r(i){if(0===i)u(t),e();else{var a=n((function(){r(i-1)}));o.set(t,a)}}(arguments.length>1&&void 0!==arguments[1]?arguments[1]:1),t}function c(e,n){for(var r=0;r1&&arguments[1]!==void 0?arguments[1]:1;i+=1;var a=i;function r(f){if(f===0)c(a),n();else{var m=l(function(){r(f-1)});t.set(a,m)}}return r(e),a}s.cancel=function(n){var e=t.get(n);return c(e),o(e)};function u(n,e){for(var a=0;ar.post({url:`${e}/upload`,data:t}),n=()=>r.get({url:`${e}/qurList`}),o=(t,s)=>r.get({url:`${e}/like`,requestConfig:{params:{id:t,likes:s}}}),l=t=>r.get({url:`${e}/del`,requestConfig:{params:{id:t}}}),i=()=>r.get({url:`${e}/my`});export{i as a,l as d,o as l,n as q,a as u}; 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/community_delete.107ab1b0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/back-end-source/public/assets/community_delete.107ab1b0.png -------------------------------------------------------------------------------- /back-end-source/public/assets/default.4e7f899b.js: -------------------------------------------------------------------------------- 1 | import{h as f}from"./index.74d00390.js";var i=function(a,r){var o=f({},a);return Object.keys(r).forEach(function(t){var e=o[t];if(e)e.type||e.default?e.default=r[t]:e.def?e.def(r[t]):o[t]={type:e,default:r[t]};else throw new Error("not have ".concat(t," prop"))}),o};const c=i;export{c as i}; 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/head_users.dca2087d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/back-end-source/public/assets/head_users.dca2087d.png -------------------------------------------------------------------------------- /back-end-source/public/assets/index-legacy-77e4e915.js: -------------------------------------------------------------------------------- 1 | System.register(["./index-legacy-32b0ceb6.js","./injectionKey-legacy-9a62c8c6.js","./default-legacy-53feab0e.js","./LeftOutlined-legacy-44ab7e9c.js"],(function(t,e){"use strict";var a,n,o,r,i,l,c,u,d,s,p,f,g,h,v,m,y,x,b,w,C,k,z,O=document.createElement("style");return O.textContent='.ant-layout{display:flex;flex:auto;flex-direction:column;min-height:0;background:#E6E6E6}.ant-layout,.ant-layout *{box-sizing:border-box}.ant-layout.ant-layout-has-sider{flex-direction:row}.ant-layout.ant-layout-has-sider>.ant-layout,.ant-layout.ant-layout-has-sider>.ant-layout-content{width:0}.ant-layout-header,.ant-layout-footer{flex:0 0 auto}.ant-layout-header{height:64px;padding:0 50px;color:#39393a;line-height:64px;background:#001529}.ant-layout-footer{padding:24px 50px;color:#39393a;font-size:14px;background:#E6E6E6}.ant-layout-content{flex:auto;min-height:0}.ant-layout-sider{position:relative;min-width:0;background:#001529;transition:all .2s}.ant-layout-sider-children{height:100%;margin-top:-.1px;padding-top:.1px}.ant-layout-sider-children .ant-menu.ant-menu-inline-collapsed{width:auto}.ant-layout-sider-has-trigger{padding-bottom:48px}.ant-layout-sider-right{order:1}.ant-layout-sider-trigger{position:fixed;bottom:0;z-index:1;height:48px;color:#fff;line-height:48px;text-align:center;background:#002140;cursor:pointer;transition:all .2s}.ant-layout-sider-zero-width>*{overflow:hidden}.ant-layout-sider-zero-width-trigger{position:absolute;top:64px;right:-36px;z-index:1;width:36px;height:42px;color:#fff;font-size:18px;line-height:42px;text-align:center;background:#001529;border-radius:0 2px 2px 0;cursor:pointer;transition:background .3s ease}.ant-layout-sider-zero-width-trigger:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;transition:all .3s;content:""}.ant-layout-sider-zero-width-trigger:hover:after{background:rgba(255,255,255,.1)}.ant-layout-sider-zero-width-trigger-right{left:-36px;border-radius:2px 0 0 2px}.ant-layout-sider-light{background:#FF8552}.ant-layout-sider-light .ant-layout-sider-trigger,.ant-layout-sider-light .ant-layout-sider-zero-width-trigger{color:#39393a;background:#fff}.ant-layout-rtl{direction:rtl}\n',document.head.appendChild(O),{setters:[function(t){a=t.d,n=t.b,o=t.u,r=t.m,i=t.q,l=t.h,c=t.z,u=t.aa,d=t.ac,s=t.E,p=t.s,f=t.i,g=t.j,h=t.ab,v=t.P,m=t.O,y=t.G,x=t.ap},function(t){b=t.S,w=t.a},function(t){C=t.i},function(t){k=t.R,z=t.L}],execute:function(){var e=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},O=function(){return{prefixCls:String,hasSider:{type:Boolean,default:void 0},tagName:String}};function S(t){var e=t.suffixCls,r=t.tagName,i=t.name;return function(t){return a({compatConfig:{MODE:3},name:i,props:O(),setup:function(a,i){var c=i.slots,u=o(e,a).prefixCls;return function(){var e=l(l({},a),{},{prefixCls:u.value,tagName:r});return n(t,e,c)}}})}}var E=a({compatConfig:{MODE:3},props:O(),setup:function(t,e){var a=e.slots;return function(){return n(t.tagName,{class:t.prefixCls},a)}}}),L=a({compatConfig:{MODE:3},props:O(),setup:function(t,e){var a=e.slots,l=o("",t).direction,s=r([]);u(b,{addSider:function(t){s.value=[].concat(d(s.value),[t])},removeSider:function(t){s.value=s.value.filter((function(e){return e!==t}))}});var p=i((function(){var e,a=t.prefixCls,n=t.hasSider;return c(e={},"".concat(a),!0),c(e,"".concat(a,"-has-sider"),"boolean"==typeof n?n:s.value.length>0),c(e,"".concat(a,"-rtl"),"rtl"===l.value),e}));return function(){var e=t.tagName;return n(e,{class:p.value},a)}}}),j=S({suffixCls:"layout",tagName:"section",name:"ALayout"})(L),N=S({suffixCls:"layout-header",tagName:"header",name:"ALayoutHeader"})(E),A=S({suffixCls:"layout-footer",tagName:"footer",name:"ALayoutFooter"})(E),F=S({suffixCls:"layout-content",tagName:"main",name:"ALayoutContent"})(E),B=j,M={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M912 192H328c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h584c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 284H328c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h584c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 284H328c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h584c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM104 228a56 56 0 10112 0 56 56 0 10-112 0zm0 284a56 56 0 10112 0 56 56 0 10-112 0zm0 284a56 56 0 10112 0 56 56 0 10-112 0z"}}]},name:"bars",theme:"outlined"};function W(t){for(var e=1;e0&&void 0!==arguments[0]?arguments[0]:"").concat(P)}),K=a({compatConfig:{MODE:3},name:"ALayoutSider",inheritAttrs:!1,props:C({prefixCls:String,collapsible:{type:Boolean,default:void 0},collapsed:{type:Boolean,default:void 0},defaultCollapsed:{type:Boolean,default:void 0},reverseArrow:{type:Boolean,default:void 0},zeroWidthTriggerStyle:{type:Object,default:void 0},trigger:v.any,width:v.oneOfType([v.number,v.string]),collapsedWidth:v.oneOfType([v.number,v.string]),breakpoint:v.oneOf(m("xs","sm","md","lg","xl","xxl","xxxl")),theme:v.oneOf(m("light","dark")).def("dark"),onBreakpoint:Function,onCollapse:Function},{collapsible:!1,defaultCollapsed:!1,reverseArrow:!1,width:200,collapsedWidth:80}),emits:["breakpoint","update:collapsed","collapse"],setup:function(t,a){var i=a.emit,d=a.attrs,s=a.slots,v=o("layout-sider",t).prefixCls,m=y(b,void 0),x=r(!!(void 0!==t.collapsed?t.collapsed:t.defaultCollapsed)),C=r(!1);p((function(){return t.collapsed}),(function(){x.value=!!t.collapsed})),u(w,x);var O,S=function(e,a){void 0===t.collapsed&&(x.value=e),i("update:collapsed",e),i("collapse",e,a)},E=r((function(t){C.value=t.matches,i("breakpoint",t.matches),x.value!==t.matches&&S(t.matches,"responsive")}));function L(t){return E.value(t)}var j=G("ant-sider-");m&&m.addSider(j),f((function(){p((function(){return t.breakpoint}),(function(){try{var e;null===(e=O)||void 0===e||e.removeEventListener("change",L)}catch(o){var a;null===(a=O)||void 0===a||a.removeListener(L)}if("undefined"!=typeof window){var n=window.matchMedia;if(n&&t.breakpoint&&t.breakpoint in q){O=n("(max-width: ".concat(q[t.breakpoint],")"));try{O.addEventListener("change",L)}catch(o){O.addListener(L)}L(O)}}}),{immediate:!0})})),g((function(){try{var t;null===(t=O)||void 0===t||t.removeEventListener("change",L)}catch(a){var e;null===(e=O)||void 0===e||e.removeListener(L)}m&&m.removeSider(j)}));var N=function(){S(!x.value,"clickTrigger")};return function(){var a,o,r,i=v.value,u=t.collapsedWidth,p=t.width,f=t.reverseArrow,g=t.zeroWidthTriggerStyle,m=t.trigger,y=void 0===m?null===(a=s.trigger)||void 0===a?void 0:a.call(s):m,b=t.collapsible,w=t.theme,O=x.value?u:p,S=e(O)?"".concat(O,"px"):String(O),E=0===parseFloat(String(u||0))?n("span",{onClick:N,class:h("".concat(i,"-zero-width-trigger"),"".concat(i,"-zero-width-trigger-").concat(f?"right":"left")),style:g},[y||n(T,null,null)]):null,L={expanded:n(f?k:z,null,null),collapsed:n(f?z:k,null,null)}[x.value?"collapsed":"expanded"],j=null!==y?E||n("div",{class:"".concat(i,"-trigger"),onClick:N,style:{width:S}},[y||L]):null,A=[d.style,{flex:"0 0 ".concat(S),maxWidth:S,minWidth:S,width:S}],F=h(i,"".concat(i,"-").concat(w),(c(o={},"".concat(i,"-collapsed"),!!x.value),c(o,"".concat(i,"-has-trigger"),b&&null!==y&&!E),c(o,"".concat(i,"-below"),!!C.value),c(o,"".concat(i,"-zero-width"),0===parseFloat(S)),o),d.class);return n("aside",l(l({},d),{},{class:F,style:A}),[n("div",{class:"".concat(i,"-children")},[null===(r=s.default)||void 0===r?void 0:r.call(s)]),b||C.value&&E?j:null])}}});t("a",N),t("L",K),t("b",F),t("_",x(B,{Header:N,Footer:A,Content:F,Sider:K,install:function(t){return t.component(B.name,B),t.component(N.name,N),t.component(A.name,A),t.component(K.name,K),t.component(F.name,F),t}}))}}})); 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/index.206ce60a.js: -------------------------------------------------------------------------------- 1 | import{u as ut,b as X,P as mt,L as Y,i as gt,f as Et,c as N,_ as g,d as yt,e as bt}from"./logo.3c3a0206.js";import{w as Z}from"./raf.f333d8de.js";import{d as G,q as st,A as ct,D as dt,E as pt,a as E,n as ht,v as z,c as F,m as Tt,B as St,G as Ct,T as xt}from"./index.69a84b56.js";var V={transitionstart:{transition:"transitionstart",WebkitTransition:"webkitTransitionStart",MozTransition:"mozTransitionStart",OTransition:"oTransitionStart",msTransition:"MSTransitionStart"},animationstart:{animation:"animationstart",WebkitAnimation:"webkitAnimationStart",MozAnimation:"mozAnimationStart",OAnimation:"oAnimationStart",msAnimation:"MSAnimationStart"}},H={transitionend:{transition:"transitionend",WebkitTransition:"webkitTransitionEnd",MozTransition:"mozTransitionEnd",OTransition:"oTransitionEnd",msTransition:"MSTransitionEnd"},animationend:{animation:"animationend",WebkitAnimation:"webkitAnimationEnd",MozAnimation:"mozAnimationEnd",OAnimation:"oAnimationEnd",msAnimation:"MSAnimationEnd"}},w=[],L=[];function kt(){var i=document.createElement("div"),t=i.style;"AnimationEvent"in window||(delete V.animationstart.animation,delete H.animationend.animation),"TransitionEvent"in window||(delete V.transitionstart.transition,delete H.transitionend.transition);function a(r,b){for(var y in r)if(r.hasOwnProperty(y)){var d=r[y];for(var f in d)if(f in t){b.push(d[f]);break}}}a(V,w),a(H,L)}typeof window<"u"&&typeof document<"u"&&kt();function tt(i,t,a){i.addEventListener(t,a,!1)}function nt(i,t,a){i.removeEventListener(t,a,!1)}var At={startEvents:w,addStartEventListener:function(t,a){if(w.length===0){setTimeout(a,0);return}w.forEach(function(r){tt(t,r,a)})},removeStartEventListener:function(t,a){w.length!==0&&w.forEach(function(r){nt(t,r,a)})},endEvents:L,addEndEventListener:function(t,a){if(L.length===0){setTimeout(a,0);return}L.forEach(function(r){tt(t,r,a)})},removeEndEventListener:function(t,a){L.length!==0&&L.forEach(function(r){nt(t,r,a)})}};const W=At;var S;function et(i){return!i||i.offsetParent===null}function Nt(i){var t=(i||"").match(/rgba?\((\d*), (\d*), (\d*)(, [\.\d]*)?\)/);return t&&t[1]&&t[2]&&t[3]?!(t[1]===t[2]&&t[2]===t[3]):!0}const wt=G({compatConfig:{MODE:3},name:"Wave",props:{insertExtraNode:Boolean,disabled:Boolean},setup:function(t,a){var r=a.slots,b=a.expose,y=pt(),d=ut("",t),f=d.csp,p=d.prefixCls;b({csp:f});var B=null,M=null,x=null,h=!1,v=null,m=!1,T=function(n){if(!m){var e=X(y);!n||n.target!==e||h||A(e)}},I=function(n){!n||n.animationName!=="fadeEffect"||A(n.target)},k=function(){var n=t.insertExtraNode;return n?"".concat(p.value,"-click-animating"):"".concat(p.value,"-click-animating-without-extra-node")},j=function(n,e){var l=t.insertExtraNode,o=t.disabled;if(!(o||!n||et(n)||n.className.indexOf("-leave")>=0)){v=document.createElement("div"),v.className="".concat(p.value,"-click-animating-node");var u=k();if(n.removeAttribute(u),n.setAttribute(u,"true"),S=S||document.createElement("style"),e&&e!=="#ffffff"&&e!=="rgb(255, 255, 255)"&&Nt(e)&&!/rgba\(\d*, \d*, \d*, 0\)/.test(e)&&e!=="transparent"){var C;(C=f.value)!==null&&C!==void 0&&C.nonce&&(S.nonce=f.value.nonce),v.style.borderColor=e,S.innerHTML=` 2 | [`.concat(p.value,"-click-animating-without-extra-node='true']::after, .").concat(p.value,`-click-animating-node { 3 | --antd-wave-shadow-color: `).concat(e,`; 4 | }`),document.body.contains(S)||document.body.appendChild(S)}l&&n.appendChild(v),W.addStartEventListener(n,T),W.addEndEventListener(n,I)}},A=function(n){if(!(!n||n===v||!(n instanceof Element))){var e=t.insertExtraNode,l=k();n.setAttribute(l,"false"),S&&(S.innerHTML=""),e&&v&&n.contains(v)&&n.removeChild(v),W.removeStartEventListener(n,T),W.removeEndEventListener(n,I)}},R=function(n){if(!(!n||!n.getAttribute||n.getAttribute("disabled")||n.className.indexOf("disabled")>=0)){var e=function(o){if(!(o.target.tagName==="INPUT"||et(o.target))){A(n);var u=getComputedStyle(n).getPropertyValue("border-top-color")||getComputedStyle(n).getPropertyValue("border-color")||getComputedStyle(n).getPropertyValue("background-color");M=setTimeout(function(){return j(n,u)},0),Z.cancel(x),h=!0,x=Z(function(){h=!1},10)}};return n.addEventListener("click",e,!0),{cancel:function(){n.removeEventListener("click",e,!0)}}}};return st(function(){ct(function(){var s=X(y);s.nodeType===1&&(B=R(s))})}),dt(function(){B&&B.cancel(),clearTimeout(M),m=!0}),function(){var s;return(s=r.default)===null||s===void 0?void 0:s.call(r)[0]}}});var Lt=function(){return{prefixCls:String,type:String,htmlType:{type:String,default:"button"},shape:{type:String},size:{type:String},loading:{type:[Boolean,Object],default:function(){return!1}},disabled:{type:Boolean,default:void 0},ghost:{type:Boolean,default:void 0},block:{type:Boolean,default:void 0},danger:{type:Boolean,default:void 0},icon:mt.any,href:String,target:String,title:String,onClick:{type:Function},onMousedown:{type:Function}}};const Bt=Lt;var at=function(t){t&&(t.style.width="0px",t.style.opacity="0",t.style.transform="scale(0)")},it=function(t){ct(function(){t&&(t.style.width="".concat(t.scrollWidth,"px"),t.style.opacity="1",t.style.transform="scale(1)")})},rt=function(t){t&&t.style&&(t.style.width=null,t.style.opacity=null,t.style.transform=null)};const It=G({compatConfig:{MODE:3},name:"LoadingIcon",props:{prefixCls:String,loading:[Boolean,Object],existIcon:Boolean},setup:function(t){return function(){var a=t.existIcon,r=t.prefixCls,b=t.loading;if(a)return E("span",{class:"".concat(r,"-loading-icon")},[E(Y,null,null)]);var y=!!b;return E(ht,{name:"".concat(r,"-loading-icon-motion"),onBeforeEnter:at,onEnter:it,onAfterEnter:rt,onBeforeLeave:it,onLeave:function(f){setTimeout(function(){at(f)})},onAfterLeave:rt},{default:function(){return[y?E("span",{class:"".concat(r,"-loading-icon")},[E(Y,null,null)]):null]}})}}});var ot=/^[\u4e00-\u9fa5]{2}$/,lt=ot.test.bind(ot);function D(i){return i==="text"||i==="link"}const _t=G({compatConfig:{MODE:3},name:"AButton",inheritAttrs:!1,__ANT_BUTTON:!0,props:gt(Bt(),{type:"default"}),slots:["icon"],setup:function(t,a){var r=a.slots,b=a.attrs,y=a.emit,d=ut("btn",t),f=d.prefixCls,p=d.autoInsertSpaceInButton,B=d.direction,M=d.size,x=z(null),h=z(void 0),v=!1,m=z(!1),T=z(!1),I=F(function(){return p.value!==!1}),k=F(function(){return yt(t.loading)==="object"&&t.loading.delay?t.loading.delay||!0:!!t.loading});Tt(k,function(n){clearTimeout(h.value),typeof k.value=="number"?h.value=setTimeout(function(){m.value=n},k.value):m.value=n},{immediate:!0});var j=F(function(){var n,e=t.type,l=t.shape,o=l===void 0?"default":l,u=t.ghost,C=t.block,U=t.danger,c=f.value,O={large:"lg",small:"sm",middle:void 0},P=M.value,_=P&&O[P]||"";return n={},g(n,"".concat(c),!0),g(n,"".concat(c,"-").concat(e),e),g(n,"".concat(c,"-").concat(o),o!=="default"&&o),g(n,"".concat(c,"-").concat(_),_),g(n,"".concat(c,"-loading"),m.value),g(n,"".concat(c,"-background-ghost"),u&&!D(e)),g(n,"".concat(c,"-two-chinese-chars"),T.value&&I.value),g(n,"".concat(c,"-block"),C),g(n,"".concat(c,"-dangerous"),!!U),g(n,"".concat(c,"-rtl"),B.value==="rtl"),n}),A=function(){var e=x.value;if(!(!e||p.value===!1)){var l=e.textContent;v&<(l)?T.value||(T.value=!0):T.value&&(T.value=!1)}},R=function(e){if(m.value||t.disabled){e.preventDefault();return}y("click",e)},s=function(e,l){var o=l?" ":"";if(e.type===xt){var u=e.children.trim();return lt(u)&&(u=u.split("").join(o)),E("span",null,[u])}return e};return St(function(){bt(!(t.ghost&&D(t.type)),"Button","`link` or `text` button can't be a `ghost` button.")}),st(A),Ct(A),dt(function(){h.value&&clearTimeout(h.value)}),function(){var n,e,l=t.icon,o=l===void 0?(n=r.icon)===null||n===void 0?void 0:n.call(r):l,u=Et((e=r.default)===null||e===void 0?void 0:e.call(r));v=u.length===1&&!o&&!D(t.type);var C=t.type,U=t.htmlType,c=t.disabled,O=t.href,P=t.title,_=t.target,ft=t.onMousedown,vt=m.value?"loading":o,$=N(N({},b),{},{title:P,disabled:c,class:[j.value,b.class,g({},"".concat(f.value,"-icon-only"),u.length===0&&!!vt)],onClick:R,onMousedown:ft});c||delete $.disabled;var q=o&&!m.value?o:E(It,{existIcon:!!o,prefixCls:f.value,loading:!!m.value},null),J=u.map(function(Q){return s(Q,v&&I.value)});if(O!==void 0)return E("a",N(N({},$),{},{href:O,target:_,ref:x}),[q,J]);var K=E("button",N(N({},$),{},{ref:x,type:U}),[q,J]);return D(C)?K:E(wt,{ref:"wave",disabled:!!m.value},{default:function(){return[K]}})}}});export{_t as B}; 5 | -------------------------------------------------------------------------------- /back-end-source/public/assets/index.420c78a9.js: -------------------------------------------------------------------------------- 1 | import{d as k,b as u,u as M,m as w,q as ue,h as P,z as y,aa as Z,ac as ce,E as de,s as U,i as fe,j as ve,ab as V,P as f,O as J,G as ge,ap as me}from"./index.74d00390.js";import{S as q,a as pe}from"./injectionKey.b22d3d4c.js";import{i as he}from"./default.4e7f899b.js";import{R as K,L as Q}from"./LeftOutlined.fdb37b97.js";var xe=function(e){return!isNaN(parseFloat(e))&&isFinite(e)};const ye=xe;var T=function(){return{prefixCls:String,hasSider:{type:Boolean,default:void 0},tagName:String}};function z(t){var e=t.suffixCls,r=t.tagName,i=t.name;return function(c){var v=k({compatConfig:{MODE:3},name:i,props:T(),setup:function(C,m){var a=m.slots,l=M(e,C),d=l.prefixCls;return function(){var A=P(P({},C),{},{prefixCls:d.value,tagName:r});return u(c,A,a)}}});return v}}var $=k({compatConfig:{MODE:3},props:T(),setup:function(e,r){var i=r.slots;return function(){return u(e.tagName,{class:e.prefixCls},i)}}}),Ce=k({compatConfig:{MODE:3},props:T(),setup:function(e,r){var i=r.slots,c=M("",e),v=c.direction,g=w([]),C={addSider:function(l){g.value=[].concat(ce(g.value),[l])},removeSider:function(l){g.value=g.value.filter(function(d){return d!==l})}};Z(q,C);var m=ue(function(){var a,l=e.prefixCls,d=e.hasSider;return a={},y(a,"".concat(l),!0),y(a,"".concat(l,"-has-sider"),typeof d=="boolean"?d:g.value.length>0),y(a,"".concat(l,"-rtl"),v.value==="rtl"),a});return function(){var a=e.tagName;return u(a,{class:m.value},i)}}}),be=z({suffixCls:"layout",tagName:"section",name:"ALayout"})(Ce),L=z({suffixCls:"layout-header",tagName:"header",name:"ALayoutHeader"})($),E=z({suffixCls:"layout-footer",tagName:"footer",name:"ALayoutFooter"})($),N=z({suffixCls:"layout-content",tagName:"main",name:"ALayoutContent"})($);const F=be;var Se={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M912 192H328c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h584c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 284H328c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h584c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 284H328c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h584c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM104 228a56 56 0 10112 0 56 56 0 10-112 0zm0 284a56 56 0 10112 0 56 56 0 10-112 0zm0 284a56 56 0 10112 0 56 56 0 10-112 0z"}}]},name:"bars",theme:"outlined"};const Oe=Se;function X(t){for(var e=1;e0&&arguments[0]!==void 0?arguments[0]:"";return t+=1,"".concat(e).concat(t)}}();const B=k({compatConfig:{MODE:3},name:"ALayoutSider",inheritAttrs:!1,props:he(Ne(),{collapsible:!1,defaultCollapsed:!1,reverseArrow:!1,width:200,collapsedWidth:80}),emits:["breakpoint","update:collapsed","collapse"],setup:function(e,r){var i=r.emit,c=r.attrs,v=r.slots,g=M("layout-sider",e),C=g.prefixCls,m=ge(q,void 0),a=w(!!(e.collapsed!==void 0?e.collapsed:e.defaultCollapsed)),l=w(!1);U(function(){return e.collapsed},function(){a.value=!!e.collapsed}),Z(pe,a);var d=function(o,h){e.collapsed===void 0&&(a.value=o),i("update:collapsed",o),i("collapse",o,h)},A=w(function(n){l.value=n.matches,i("breakpoint",n.matches),a.value!==n.matches&&d(n.matches,"responsive")}),p;function x(n){return A.value(n)}var I=Be("ant-sider-");m&&m.addSider(I),fe(function(){U(function(){return e.breakpoint},function(){try{var n;(n=p)===null||n===void 0||n.removeEventListener("change",x)}catch(S){var o;(o=p)===null||o===void 0||o.removeListener(x)}if(typeof window<"u"){var h=window,s=h.matchMedia;if(s&&e.breakpoint&&e.breakpoint in Y){p=s("(max-width: ".concat(Y[e.breakpoint],")"));try{p.addEventListener("change",x)}catch(S){p.addListener(x)}x(p)}}},{immediate:!0})}),ve(function(){try{var n;(n=p)===null||n===void 0||n.removeEventListener("change",x)}catch(h){var o;(o=p)===null||o===void 0||o.removeListener(x)}m&&m.removeSider(I)});var _=function(){d(!a.value,"clickTrigger")};return function(){var n,o,h,s=C.value,S=e.collapsedWidth,ee=e.width,j=e.reverseArrow,te=e.zeroWidthTriggerStyle,R=e.trigger,O=R===void 0?(n=v.trigger)===null||n===void 0?void 0:n.call(v):R,G=e.collapsible,ae=e.theme,H=a.value?S:ee,b=ye(H)?"".concat(H,"px"):String(H),W=parseFloat(String(S||0))===0?u("span",{onClick:_,class:V("".concat(s,"-zero-width-trigger"),"".concat(s,"-zero-width-trigger-").concat(j?"right":"left")),style:te},[O||u(Le,null,null)]):null,ne={expanded:j?u(K,null,null):u(Q,null,null),collapsed:j?u(Q,null,null):u(K,null,null)},re=a.value?"collapsed":"expanded",oe=ne[re],ie=O!==null?W||u("div",{class:"".concat(s,"-trigger"),onClick:_,style:{width:b}},[O||oe]):null,le=[c.style,{flex:"0 0 ".concat(b),maxWidth:b,minWidth:b,width:b}],se=V(s,"".concat(s,"-").concat(ae),(o={},y(o,"".concat(s,"-collapsed"),!!a.value),y(o,"".concat(s,"-has-trigger"),G&&O!==null&&!W),y(o,"".concat(s,"-below"),!!l.value),y(o,"".concat(s,"-zero-width"),parseFloat(b)===0),o),c.class);return u("aside",P(P({},c),{},{class:se,style:le}),[u("div",{class:"".concat(s,"-children")},[(h=v.default)===null||h===void 0?void 0:h.call(v)]),G||l.value&&W?ie:null])}}});var je=L,He=B,We=N;const Ee=me(F,{Header:L,Footer:E,Content:N,Sider:B,install:function(e){return e.component(F.name,F),e.component(L.name,L),e.component(E.name,E),e.component(B.name,B),e.component(N.name,N),e}});export{He as L,Ee as _,je as a,We as b}; 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/index.497015cb.css: -------------------------------------------------------------------------------- 1 | body[data-v-7f7461b1]{height:100vh}.ant-message{box-sizing:border-box;margin:0;padding:0;color:#39393a;font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:"tnum";position:fixed;top:8px;left:0;z-index:1010;width:100%;pointer-events:none}.ant-message-notice{padding:8px;text-align:center}.ant-message-notice-content{display:inline-block;padding:10px 16px;background:#fff;border-radius:2px;box-shadow:0 3px 6px -4px rgba(0,0,0,.12),0 6px 16px rgba(0,0,0,.08),0 9px 28px 8px rgba(0,0,0,.05);pointer-events:all}.ant-message-success .anticon{color:#52c41a}.ant-message-error .anticon{color:#ff4d4f}.ant-message-warning .anticon{color:#faad14}.ant-message-info .anticon,.ant-message-loading .anticon{color:#e33c64}.ant-message .anticon{position:relative;top:1px;margin-right:8px;font-size:16px}.ant-message-notice.ant-move-up-leave.ant-move-up-leave-active{animation-name:MessageMoveOut;animation-duration:.3s}@keyframes MessageMoveOut{0%{max-height:150px;padding:8px;opacity:1}to{max-height:0;padding:0;opacity:0}}.ant-message-rtl,.ant-message-rtl span{direction:rtl}.ant-message-rtl .anticon{margin-right:0;margin-left:8px}@font-face{font-family:zhanku;src:url(/assets/\7ad9\9177\5c0f\8587LOGO\4f53.e2e91082.otf);font-weight:400}@font-face{font-family:sourceMedium;src:url(/assets/SourceHanSansSC-Medium.28ad6d9d.otf);font-weight:400} 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/index.80ff0b15.css: -------------------------------------------------------------------------------- 1 | .ant-layout{display:flex;flex:auto;flex-direction:column;min-height:0;background:#E6E6E6}.ant-layout,.ant-layout *{box-sizing:border-box}.ant-layout.ant-layout-has-sider{flex-direction:row}.ant-layout.ant-layout-has-sider>.ant-layout,.ant-layout.ant-layout-has-sider>.ant-layout-content{width:0}.ant-layout-header,.ant-layout-footer{flex:0 0 auto}.ant-layout-header{height:64px;padding:0 50px;color:#39393a;line-height:64px;background:#001529}.ant-layout-footer{padding:24px 50px;color:#39393a;font-size:14px;background:#E6E6E6}.ant-layout-content{flex:auto;min-height:0}.ant-layout-sider{position:relative;min-width:0;background:#001529;transition:all .2s}.ant-layout-sider-children{height:100%;margin-top:-.1px;padding-top:.1px}.ant-layout-sider-children .ant-menu.ant-menu-inline-collapsed{width:auto}.ant-layout-sider-has-trigger{padding-bottom:48px}.ant-layout-sider-right{order:1}.ant-layout-sider-trigger{position:fixed;bottom:0;z-index:1;height:48px;color:#fff;line-height:48px;text-align:center;background:#002140;cursor:pointer;transition:all .2s}.ant-layout-sider-zero-width>*{overflow:hidden}.ant-layout-sider-zero-width-trigger{position:absolute;top:64px;right:-36px;z-index:1;width:36px;height:42px;color:#fff;font-size:18px;line-height:42px;text-align:center;background:#001529;border-radius:0 2px 2px 0;cursor:pointer;transition:background .3s ease}.ant-layout-sider-zero-width-trigger:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;transition:all .3s;content:""}.ant-layout-sider-zero-width-trigger:hover:after{background:rgba(255,255,255,.1)}.ant-layout-sider-zero-width-trigger-right{left:-36px;border-radius:2px 0 0 2px}.ant-layout-sider-light{background:#FF8552}.ant-layout-sider-light .ant-layout-sider-trigger,.ant-layout-sider-light .ant-layout-sider-zero-width-trigger{color:#39393a;background:#fff}.ant-layout-rtl{direction:rtl} 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/index.9900b78c.css: -------------------------------------------------------------------------------- 1 | .ant-image{position:relative;display:inline-block}.ant-image-img{width:100%;height:auto;vertical-align:middle}.ant-image-img-placeholder{background-color:#f5f5f5;background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTQuNSAyLjVoLTEzQS41LjUgMCAwIDAgMSAzdjEwYS41LjUgMCAwIDAgLjUuNWgxM2EuNS41IDAgMCAwIC41LS41VjNhLjUuNSAwIDAgMC0uNS0uNXpNNS4yODEgNC43NWExIDEgMCAwIDEgMCAyIDEgMSAwIDAgMSAwLTJ6bTguMDMgNi44M2EuMTI3LjEyNyAwIDAgMS0uMDgxLjAzSDIuNzY5YS4xMjUuMTI1IDAgMCAxLS4wOTYtLjIwN2wyLjY2MS0zLjE1NmEuMTI2LjEyNiAwIDAgMSAuMTc3LS4wMTZsLjAxNi4wMTZMNy4wOCAxMC4wOWwyLjQ3LTIuOTNhLjEyNi4xMjYgMCAwIDEgLjE3Ny0uMDE2bC4wMTUuMDE2IDMuNTg4IDQuMjQ0YS4xMjcuMTI3IDAgMCAxLS4wMi4xNzV6IiBmaWxsPSIjOEM4QzhDIiBmaWxsLXJ1bGU9Im5vbnplcm8iLz48L3N2Zz4=);background-repeat:no-repeat;background-position:center center;background-size:30%}.ant-image-mask{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center;color:#fff;background:rgba(0,0,0,.5);cursor:pointer;opacity:0;transition:opacity .3s}.ant-image-mask-info{padding:0 4px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ant-image-mask-info .anticon{margin-inline-end:4px}.ant-image-mask:hover{opacity:1}.ant-image-placeholder{position:absolute;top:0;right:0;bottom:0;left:0}.ant-image-preview{pointer-events:none;height:100%;text-align:center}.ant-image-preview.ant-zoom-enter,.ant-image-preview.antzoom-appear{transform:none;opacity:0;animation-duration:.3s;user-select:none}.ant-image-preview-mask{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1000;height:100%;background-color:rgba(0,0,0,.45)}.ant-image-preview-mask-hidden{display:none}.ant-image-preview-wrap{position:fixed;top:0;right:0;bottom:0;left:0;overflow:auto;outline:0;-webkit-overflow-scrolling:touch}.ant-image-preview-body{position:absolute;top:0;right:0;bottom:0;left:0;overflow:hidden}.ant-image-preview-img{max-width:100%;max-height:100%;vertical-align:middle;transform:scaleZ(1);cursor:grab;transition:transform .3s cubic-bezier(.215,.61,.355,1) 0s;user-select:none;pointer-events:auto}.ant-image-preview-img-wrapper{position:absolute;top:0;right:0;bottom:0;left:0;transition:transform .3s cubic-bezier(.215,.61,.355,1) 0s}.ant-image-preview-img-wrapper:before{display:inline-block;width:1px;height:50%;margin-right:-1px;content:""}.ant-image-preview-moving .ant-image-preview-img{cursor:grabbing}.ant-image-preview-moving .ant-image-preview-img-wrapper{transition-duration:0s}.ant-image-preview-wrap{z-index:1080}.ant-image-preview-operations{box-sizing:border-box;margin:0;padding:0;color:#39393a;font-size:14px;font-variant:tabular-nums;line-height:1.5715;font-feature-settings:"tnum";position:absolute;top:0;right:0;z-index:1;display:flex;flex-direction:row-reverse;align-items:center;width:100%;color:rgba(255,255,255,.85);list-style:none;background:rgba(0,0,0,.1);pointer-events:auto}.ant-image-preview-operations-operation{margin-left:12px;padding:12px;cursor:pointer}.ant-image-preview-operations-operation-disabled{color:rgba(255,255,255,.25);pointer-events:none}.ant-image-preview-operations-operation:last-of-type{margin-left:0}.ant-image-preview-operations-icon{font-size:18px}.ant-image-preview-switch-left,.ant-image-preview-switch-right{position:absolute;top:50%;right:10px;z-index:1;display:flex;align-items:center;justify-content:center;width:44px;height:44px;margin-top:-22px;color:rgba(255,255,255,.85);background:rgba(0,0,0,.1);border-radius:50%;cursor:pointer;pointer-events:auto}.ant-image-preview-switch-left-disabled,.ant-image-preview-switch-right-disabled{color:rgba(255,255,255,.25);cursor:not-allowed}.ant-image-preview-switch-left-disabled>.anticon,.ant-image-preview-switch-right-disabled>.anticon{cursor:not-allowed}.ant-image-preview-switch-left>.anticon,.ant-image-preview-switch-right>.anticon{font-size:18px}.ant-image-preview-switch-left{left:10px}.ant-image-preview-switch-right{right:10px} 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/index.d2ad12ca.css: -------------------------------------------------------------------------------- 1 | body[data-v-7f7461b1]{height:100vh}.ant-message{box-sizing:border-box;margin:0;padding:0;color:#39393a;font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:"tnum";position:fixed;top:8px;left:0;z-index:1010;width:100%;pointer-events:none}.ant-message-notice{padding:8px;text-align:center}.ant-message-notice-content{display:inline-block;padding:10px 16px;background:#fff;border-radius:2px;box-shadow:0 3px 6px -4px #0000001f,0 6px 16px #00000014,0 9px 28px 8px #0000000d;pointer-events:all}.ant-message-success .anticon{color:#52c41a}.ant-message-error .anticon{color:#ff4d4f}.ant-message-warning .anticon{color:#faad14}.ant-message-info .anticon,.ant-message-loading .anticon{color:#e33c64}.ant-message .anticon{position:relative;top:1px;margin-right:8px;font-size:16px}.ant-message-notice.ant-move-up-leave.ant-move-up-leave-active{animation-name:MessageMoveOut;animation-duration:.3s}@keyframes MessageMoveOut{0%{max-height:150px;padding:8px;opacity:1}to{max-height:0;padding:0;opacity:0}}.ant-message-rtl,.ant-message-rtl span{direction:rtl}.ant-message-rtl .anticon{margin-right:0;margin-left:8px}@font-face{font-family:zhanku;src:url(/assets/\7ad9\9177\5c0f\8587LOGO\4f53.e2e91082.otf);font-weight:400}@font-face{font-family:sourceMedium;src:url(/assets/SourceHanSansSC-Medium.28ad6d9d.otf);font-weight:400} 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/index.e3a7a2eb.js: -------------------------------------------------------------------------------- 1 | import{A as M,u as D,c as j,_ as y,B as ge,i as me,r as Q,P as f,t as X,q as pe}from"./logo.3c3a0206.js";import{a as s,d as B,v as w,c as he,l as re,m as Y,q as be,D as ye,j as Oe}from"./index.69a84b56.js";var xe=function(e){return!isNaN(parseFloat(e))&&isFinite(e)};const Ce=xe;var Se={icon:{tag:"svg",attrs:{viewBox:"64 64 896 896",focusable:"false"},children:[{tag:"path",attrs:{d:"M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"}}]},name:"right",theme:"outlined"};const we=Se;function Z(t){for(var e=1;e0),y(i,"".concat(u,"-rtl"),v.value==="rtl"),i});return function(){var i=e.tagName;return s(i,{class:m.value},r)}}}),$e=A({suffixCls:"layout",tagName:"section",name:"ALayout"})(Ae),P=A({suffixCls:"layout-header",tagName:"header",name:"ALayoutHeader"})(I),_=A({suffixCls:"layout-footer",tagName:"footer",name:"ALayoutFooter"})(I),L=A({suffixCls:"layout-content",tagName:"main",name:"ALayoutContent"})(I);const k=$e;var ze={icon:{tag:"svg",attrs:{viewBox:"0 0 1024 1024",focusable:"false"},children:[{tag:"path",attrs:{d:"M912 192H328c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h584c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 284H328c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h584c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 284H328c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h584c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM104 228a56 56 0 10112 0 56 56 0 10-112 0zm0 284a56 56 0 10112 0 56 56 0 10-112 0zm0 284a56 56 0 10112 0 56 56 0 10-112 0z"}}]},name:"bars",theme:"outlined"};const He=ze;function te(t){for(var e=1;e0&&arguments[0]!==void 0?arguments[0]:"";return t+=1,"".concat(e).concat(t)}}();const N=B({compatConfig:{MODE:3},name:"ALayoutSider",inheritAttrs:!1,props:me(ke(),{collapsible:!1,defaultCollapsed:!1,reverseArrow:!1,width:200,collapsedWidth:80}),emits:["breakpoint","update:collapsed","collapse"],setup:function(e,n){var r=n.emit,a=n.attrs,v=n.slots,g=D("layout-sider",e),O=g.prefixCls,m=Oe(ae,void 0),i=w(!!(e.collapsed!==void 0?e.collapsed:e.defaultCollapsed)),u=w(!1);Y(function(){return e.collapsed},function(){i.value=!!e.collapsed}),re(Le,i);var d=function(l,h){e.collapsed===void 0&&(i.value=l),r("update:collapsed",l),r("collapse",l,h)},$=w(function(o){u.value=o.matches,r("breakpoint",o.matches),i.value!==o.matches&&d(o.matches,"responsive")}),p;function b(o){return $.value(o)}var V=Me("ant-sider-");m&&m.addSider(V),be(function(){Y(function(){return e.breakpoint},function(){try{var o;(o=p)===null||o===void 0||o.removeEventListener("change",b)}catch{var l;(l=p)===null||l===void 0||l.removeListener(b)}if(typeof window<"u"){var h=window,c=h.matchMedia;if(c&&e.breakpoint&&e.breakpoint in ne){p=c("(max-width: ".concat(ne[e.breakpoint],")"));try{p.addEventListener("change",b)}catch{p.addListener(b)}b(p)}}},{immediate:!0})}),ye(function(){try{var o;(o=p)===null||o===void 0||o.removeEventListener("change",b)}catch{var l;(l=p)===null||l===void 0||l.removeListener(b)}m&&m.removeSider(V)});var U=function(){d(!i.value,"clickTrigger")};return function(){var o,l,h,c=O.value,C=e.collapsedWidth,ie=e.width,z=e.reverseArrow,oe=e.zeroWidthTriggerStyle,G=e.trigger,S=G===void 0?(o=v.trigger)===null||o===void 0?void 0:o.call(v):G,J=e.collapsible,le=e.theme,H=i.value?C:ie,x=Ce(H)?"".concat(H,"px"):String(H),W=parseFloat(String(C||0))===0?s("span",{onClick:U,class:Q("".concat(c,"-zero-width-trigger"),"".concat(c,"-zero-width-trigger-").concat(z?"right":"left")),style:oe},[S||s(_e,null,null)]):null,se={expanded:z?s(K,null,null):s(ee,null,null),collapsed:z?s(ee,null,null):s(K,null,null)},ue=i.value?"collapsed":"expanded",ce=se[ue],de=S!==null?W||s("div",{class:"".concat(c,"-trigger"),onClick:U,style:{width:x}},[S||ce]):null,fe=[a.style,{flex:"0 0 ".concat(x),maxWidth:x,minWidth:x,width:x}],ve=Q(c,"".concat(c,"-").concat(le),(l={},y(l,"".concat(c,"-collapsed"),!!i.value),y(l,"".concat(c,"-has-trigger"),J&&S!==null&&!W),y(l,"".concat(c,"-below"),!!u.value),y(l,"".concat(c,"-zero-width"),parseFloat(x)===0),l),a.class);return s("aside",j(j({},a),{},{class:ve,style:fe}),[s("div",{class:"".concat(c,"-children")},[(h=v.default)===null||h===void 0?void 0:h.call(v)]),J||u.value&&W?de:null])}}});var Fe=P,Te=N,Ie=L;const Re=pe(k,{Header:P,Footer:_,Content:L,Sider:N,install:function(e){return e.component(k.name,k),e.component(P.name,P),e.component(_.name,_),e.component(N.name,N),e.component(L.name,L),e}});export{Te as L,Le as S,Re as _,Fe as a,Ie as b}; 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/injectionKey-legacy-9a62c8c6.js: -------------------------------------------------------------------------------- 1 | System.register([],(function(e,r){"use strict";return{execute:function(){e("a",Symbol("siderCollapsed")),e("S",Symbol("siderHookProvider"))}}})); 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/injectionKey.b22d3d4c.js: -------------------------------------------------------------------------------- 1 | var e=Symbol("siderCollapsed"),o=Symbol("siderHookProvider");export{o as S,e as a}; 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/isObject.eeded74e.js: -------------------------------------------------------------------------------- 1 | var f=typeof global=="object"&&global&&global.Object===Object&&global;const l=f;var s=typeof self=="object"&&self&&self.Object===Object&&self,g=l||s||Function("return this")();const j=g;var u=j.Symbol;const o=u;var a=Object.prototype,y=a.hasOwnProperty,O=a.toString,e=o?o.toStringTag:void 0;function S(t){var r=y.call(t,e),c=t[e];try{t[e]=void 0;var i=!0}catch{}var b=O.call(t);return i&&(r?t[e]=c:delete t[e]),b}var d=Object.prototype,T=d.toString;function p(t){return T.call(t)}var v="[object Null]",$="[object Undefined]",n=o?o.toStringTag:void 0;function h(t){return t==null?t===void 0?$:v:n&&n in Object(t)?S(t):p(t)}function w(t){return t!=null&&typeof t=="object"}function P(t){var r=typeof t;return t!=null&&(r=="object"||r=="function")}export{o as S,P as a,h as b,l as f,w as i,j as r}; 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/logo-legacy-48b6155a.js: -------------------------------------------------------------------------------- 1 | System.register([],(function(e,t){"use strict";return{execute:function(){e("_","/assets/logo.ff49f460.png")}}})); 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/logo.9c536476.js: -------------------------------------------------------------------------------- 1 | const s="/assets/logo.ff49f460.png";export{s as _}; 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/logo.ff49f460.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/back-end-source/public/assets/logo.ff49f460.png -------------------------------------------------------------------------------- /back-end-source/public/assets/raf.f333d8de.js: -------------------------------------------------------------------------------- 1 | var f=function(n){return setTimeout(n,16)},o=function(n){return clearTimeout(n)};typeof window<"u"&&"requestAnimationFrame"in window&&(f=function(n){return window.requestAnimationFrame(n)},o=function(n){return window.cancelAnimationFrame(n)});var u=0,a=new Map;function c(e){a.delete(e)}function m(e){var n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:1;u+=1;var r=u;function t(i){if(i===0)c(r),e();else{var d=f(function(){t(i-1)});a.set(r,d)}}return t(n),r}m.cancel=function(e){var n=a.get(e);return c(n),o(n)};export{m as w}; 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/share_place.26d6793a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/back-end-source/public/assets/share_place.26d6793a.png -------------------------------------------------------------------------------- /back-end-source/public/assets/share_router.908338d1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/back-end-source/public/assets/share_router.908338d1.png -------------------------------------------------------------------------------- /back-end-source/public/assets/share_share.03601752.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/back-end-source/public/assets/share_share.03601752.png -------------------------------------------------------------------------------- /back-end-source/public/assets/slogan-btn.3ffc1292.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/back-end-source/public/assets/slogan-btn.3ffc1292.png -------------------------------------------------------------------------------- /back-end-source/public/assets/useMergedState-legacy-f568f135.js: -------------------------------------------------------------------------------- 1 | System.register(["./index-legacy-32b0ceb6.js"],(function(e,t){"use strict";var u,n,a,v,o;return{setters:[function(e){u=e.m,n=e.ao,a=e.v,v=e.s,o=e.an}],execute:function(){e("u",(function(e,t){var i=t||{},l=i.defaultValue,c=i.value,r=void 0===c?u():c,f="function"==typeof e?e():e;void 0!==r.value&&(f=n(r)),void 0!==l&&(f="function"==typeof l?l():l);var s=u(f),d=u(f);return a((function(){var e=void 0!==r.value?r.value:s.value;t.postState&&(e=t.postState(e)),d.value=e})),v(r,(function(){s.value=r.value})),[d,function(e){var u=d.value;s.value=e,o(d.value)!==e&&t.onChange&&t.onChange(e,u)}]}))}}})); 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/useMergedState.73854052.js: -------------------------------------------------------------------------------- 1 | import{m as l,ao as d,v as g,s as h,an as m}from"./index.74d00390.js";function C(r,u){var i=u||{},n=i.defaultValue,o=i.value,a=o===void 0?l():o,f=typeof r=="function"?r():r;a.value!==void 0&&(f=d(a)),n!==void 0&&(f=typeof n=="function"?n():n);var t=l(f),v=l(f);g(function(){var e=a.value!==void 0?a.value:t.value;u.postState&&(e=u.postState(e)),v.value=e});function s(e){var c=v.value;t.value=e,m(v.value)!==e&&u.onChange&&u.onChange(e,c)}return h(a,function(){t.value=a.value}),[v,s]}export{C as u}; 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/user_profile-legacy-20488b3c.js: -------------------------------------------------------------------------------- 1 | System.register([],(function(e,t){"use strict";return{execute:function(){e("_","/assets/user_profile.65a26503.jpg")}}})); 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/user_profile.65a26503.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/back-end-source/public/assets/user_profile.65a26503.jpg -------------------------------------------------------------------------------- /back-end-source/public/assets/user_profile.8df7d38a.js: -------------------------------------------------------------------------------- 1 | const s="/assets/user_profile.65a26503.jpg";export{s as _}; 2 | -------------------------------------------------------------------------------- /back-end-source/public/assets/站酷小薇LOGO体.e2e91082.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/back-end-source/public/assets/站酷小薇LOGO体.e2e91082.otf -------------------------------------------------------------------------------- /back-end-source/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/back-end-source/public/favicon.ico -------------------------------------------------------------------------------- /back-end-source/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 染指世界 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /back-end-source/router/community.js: -------------------------------------------------------------------------------- 1 | // api: /community 社区路由模块 2 | const express = require('express') 3 | const router = express.Router() // 创建路由对象 4 | const { 5 | upload, 6 | deleteWork, 7 | qurList, 8 | like, 9 | qurMyList, 10 | } = require('../router_handler/community_handler') 11 | const { validateForm, uploadJoi } = require('../utils/validate') // 表单验证 12 | 13 | // 上传画作 14 | router.post('/upload', validateForm(uploadJoi), upload) 15 | 16 | // 删除画作 17 | router.get('/del', deleteWork) 18 | 19 | // 查询所有画作 20 | router.get('/qurList', qurList) 21 | 22 | // 点赞画作 23 | router.get('/like', like) 24 | 25 | // 查询我的画作 26 | router.get('/my', qurMyList) 27 | 28 | module.exports = router 29 | -------------------------------------------------------------------------------- /back-end-source/router/user.js: -------------------------------------------------------------------------------- 1 | // api: /user 用户路由模块 2 | const express = require('express') 3 | const router = express.Router() // 创建路由对象 4 | const { regUser, login, logout } = require('../router_handler/user_handler') 5 | const { validateForm, regJoi, loginJoi } = require('../utils/validate') // 表单验证 6 | 7 | // 注册 8 | router.post('/reguser', validateForm(regJoi), regUser) 9 | 10 | // 登录 11 | router.post('/login', validateForm(loginJoi), login) 12 | 13 | // 退出登录 14 | router.post('/logout', logout) 15 | 16 | module.exports = router 17 | -------------------------------------------------------------------------------- /back-end-source/router/userinfo.js: -------------------------------------------------------------------------------- 1 | // api: /userinfo 用户信息路由模块 2 | const express = require('express') 3 | const router = express.Router() // 创建路由对象 4 | const { getInfo, updateAvatar } = require('../router_handler/userinfo_handler') 5 | const { validateForm, avatarJoi } = require('../utils/validate') // 表单验证 6 | 7 | // 获取用户信息 8 | router.get('/getinfo', getInfo) 9 | 10 | // 更新用户头像 11 | router.post('/avatar', validateForm(avatarJoi), updateAvatar) 12 | 13 | module.exports = router 14 | -------------------------------------------------------------------------------- /back-end-source/router_handler/community_handler.js: -------------------------------------------------------------------------------- 1 | // community 路由处理函数 2 | const { query, insert, del, updateBy } = require('../utils/mysql') 3 | 4 | // 上传画作 5 | const upload = async (req, res) => { 6 | const { image, title, address, nickname } = req.body 7 | const data = { 8 | userid: req.auth.id, 9 | image, 10 | time: getCurrentDateTime(), 11 | title, 12 | address, 13 | nickname, 14 | } 15 | // 上传数据库 16 | try { 17 | const results = await insert('article', data) 18 | if (results.warningCount === 0) { 19 | return res.send({ 20 | retCode: 200, 21 | msg: '上传成功', 22 | articleID: results.insertId, 23 | }) 24 | } else { 25 | return res.send({ retCode: 420, msg: '上传失败' }) 26 | } 27 | } catch (err) { 28 | return res.status(200).send({ retCode: 503, msg: err }) 29 | } 30 | } 31 | 32 | // 删除画作 33 | const deleteWork = async (req, res) => { 34 | try { 35 | const results = await del('article', { id: req.query.id }) 36 | if (results.warningCount === 0) { 37 | return res.send({ 38 | retCode: 200, 39 | msg: '删除成功', 40 | }) 41 | } else { 42 | return res.send({ retCode: 420, msg: '删除失败' }) 43 | } 44 | } catch (err) { 45 | return res.send({ retCode: 503, msg: err }) 46 | } 47 | } 48 | 49 | // 查询所有画作 50 | const qurList = async (req, res) => { 51 | const sqlStr = 'select * from article' 52 | try { 53 | const results = await query(sqlStr) 54 | return res.send({ 55 | retCode: 200, 56 | msg: '列表请求成功', 57 | list: results, 58 | }) 59 | } catch (err) { 60 | return res.send({ retCode: 503, msg: err }) 61 | } 62 | } 63 | 64 | // 点赞画作 65 | const like = async (req, res) => { 66 | const likes = parseInt(req.query.likes) 67 | const isLikeStr = likes > 0 ? '点赞' : '取消点赞' 68 | try { 69 | const results = await updateBy( 70 | 'article', 71 | { likes: likes }, 72 | { id: req.query.id }, 73 | ) 74 | if (results.affectedRows !== 1) { 75 | return res.send({ retCode: 420, msg: `${isLikeStr}失败` }) 76 | } else { 77 | return res.send({ 78 | retCode: 200, 79 | msg: `${isLikeStr}成功`, 80 | }) 81 | } 82 | } catch (err) { 83 | return res.send({ retCode: 503, msg: err }) 84 | } 85 | } 86 | 87 | // 查询个人画作 88 | const qurMyList = async (req, res) => { 89 | const sqlStr = 'select * from article where userid = ?' 90 | try { 91 | const results = await query(sqlStr, req.auth.id) 92 | return res.send({ 93 | retCode: 200, 94 | msg: '用户画作列表请求成功', 95 | list: results, 96 | }) 97 | } catch (err) { 98 | return res.send({ retCode: 503, msg: err }) 99 | } 100 | } 101 | 102 | // 生成当前时间 103 | const getCurrentDateTime = () => { 104 | const now = new Date() 105 | const year = now.getFullYear() 106 | const month = String(now.getMonth() + 1).padStart(2, '0') 107 | const day = String(now.getDate()).padStart(2, '0') 108 | const hour = String(now.getHours()).padStart(2, '0') 109 | const minute = String(now.getMinutes()).padStart(2, '0') 110 | const second = String(now.getSeconds()).padStart(2, '0') 111 | return `${year}-${month}-${day} ${hour}:${minute}:${second}` 112 | } 113 | 114 | module.exports = { 115 | upload, 116 | deleteWork, 117 | qurList, 118 | like, 119 | qurMyList, 120 | } 121 | -------------------------------------------------------------------------------- /back-end-source/router_handler/user_handler.js: -------------------------------------------------------------------------------- 1 | // user 路由处理函数 2 | const { query, insert } = require('../utils/mysql') 3 | const bcrypt = require('bcryptjs') // 用于对密码进行加密处理 4 | const { generateToken } = require('../utils/token') 5 | 6 | // 注册 {cellphone,nickname,password} 7 | const regUser = async (req, res) => { 8 | // 用户名查重 9 | const sqlStr = 'select * from user where nickname = ?' 10 | try { 11 | const results = await query(sqlStr, req.body.nickname) 12 | if (results.length > 0) { 13 | return res.send({ retCode: 400, msg: '用户名被占用' }) 14 | } 15 | } catch (err) { 16 | return res.send({ retCode: 503, msg: err }) 17 | } 18 | // 手机号码查重 19 | const sqlStr2 = 'select * from user where cellphone = ?' 20 | try { 21 | const results = await query(sqlStr2, req.body.cellphone) 22 | if (results.length > 0) { 23 | return res.send({ retCode: 400, msg: '该手机号已注册' }) 24 | } 25 | } catch (err) { 26 | return res.send({ retCode: 503, msg: err }) 27 | } 28 | // 用户密码加密 29 | const data = { 30 | nickname: req.body.nickname, 31 | cellphone: req.body.cellphone, 32 | } 33 | data.password = bcrypt.hashSync(req.body.password, 10) 34 | // 上传数据库 35 | try { 36 | const results = await insert('user', data) 37 | if (results.warningCount === 0) { 38 | // 生成 token字符串 39 | const tokenObj = { 40 | id: results.insertId, 41 | cellphone: data.cellphone, 42 | } 43 | return res.send({ 44 | retCode: 200, 45 | msg: '注册成功', 46 | data: { 47 | id: results[0].id, 48 | nickname: results[0].nickname, 49 | cellphone: results[0].cellphone, 50 | }, 51 | token: generateToken(tokenObj), 52 | }) 53 | } 54 | } catch (err) { 55 | return res.send({ retCode: 503, msg: err }) 56 | } 57 | } 58 | 59 | // 登录 {cellphone,password} 60 | const login = async (req, res) => { 61 | const sqlStr = 'select * from user where cellphone = ?' 62 | try { 63 | const results = await query(sqlStr, req.body.cellphone) 64 | const comRes = bcrypt.compareSync(req.body.password, results[0].password) // 解密并比较密码是否正确 65 | if (results.length === 1 && comRes) { 66 | // 生成 token字符串 67 | const tokenObj = { 68 | id: results[0].id, 69 | cellphone: results[0].cellphone, 70 | } 71 | return res.send({ 72 | retCode: 200, 73 | msg: '登陆成功', 74 | data: { 75 | id: results[0].id, 76 | nickname: results[0].nickname, 77 | cellphone: results[0].cellphone, 78 | }, 79 | token: generateToken(tokenObj), 80 | }) 81 | } else { 82 | return res.send({ retCode: 400, msg: '用户未注册或密码错误' }) 83 | } 84 | } catch (err) { 85 | return res.send({ retCode: 503, msg: err }) 86 | } 87 | } 88 | 89 | // 退出登录 90 | const logout = (req, res) => { 91 | res.send('logout') 92 | } 93 | 94 | module.exports = { 95 | regUser, 96 | login, 97 | logout, 98 | } 99 | -------------------------------------------------------------------------------- /back-end-source/router_handler/userinfo_handler.js: -------------------------------------------------------------------------------- 1 | // userinfo 路由处理函数 2 | const { query, update } = require('../utils/mysql') 3 | 4 | // 获取用户信息 5 | const getInfo = async (req, res) => { 6 | const sqlStr = 'select * from user where id = ?' 7 | try { 8 | const results = await query(sqlStr, req.auth.id) 9 | if (results.length !== 1) { 10 | return res.send({ retCode: 406, msg: '未找到该用户' }) 11 | } else { 12 | return res.send({ 13 | retCode: 200, 14 | msg: '获取用户信息成功', 15 | data: { 16 | id: results[0].id, 17 | nickname: results[0].nickname, 18 | cellphone: results[0].cellphone, 19 | }, 20 | }) 21 | } 22 | } catch (err) { 23 | return res.send({ retCode: 503, msg: err }) 24 | } 25 | } 26 | 27 | // 更新用户头像 28 | const updateAvatar = async (req, res) => { 29 | try { 30 | const results = await update( 31 | 'user', 32 | { user_pic: req.body.avatar }, 33 | { id: req.body.id }, 34 | ) 35 | if (results.affectedRows !== 1) { 36 | return res.send({ retCode: 420, msg: '更新头像失败' }) 37 | } else { 38 | return res.send({ 39 | retCode: 200, 40 | msg: '成功更新用户头像', 41 | }) 42 | } 43 | } catch (err) { 44 | return res.send({ retCode: 503, msg: err }) 45 | } 46 | } 47 | 48 | module.exports = { 49 | getInfo, 50 | updateAvatar, 51 | } 52 | -------------------------------------------------------------------------------- /back-end-source/utils/mysql.js: -------------------------------------------------------------------------------- 1 | const mysql = require('mysql') 2 | 3 | // 建立与 MySQL 数据库的连接 4 | const db = mysql.createPool({ 5 | host: '127.0.0.1', // 数据库的 IP 地址 6 | user: 'root', // 登录数据库的账号 7 | password: '36741673', // 登录数据库的密码 8 | database: 'graffiti_world_db', // 指定操作的数据库graffiti_world_db 9 | }) 10 | 11 | // 查询方法 12 | const query = (sql, values) => { 13 | return new Promise((resolve, reject) => { 14 | db.getConnection((err, connection) => { 15 | if (err) { 16 | reject(err) 17 | } else { 18 | connection.query(sql, values, (err, results) => { 19 | connection.release() 20 | if (err) { 21 | reject(err) 22 | } else { 23 | resolve(results) 24 | } 25 | }) 26 | } 27 | }) 28 | }) 29 | } 30 | 31 | // 插入方法 32 | const insert = async (table, data) => { 33 | const keys = Object.keys(data).join(',') 34 | const values = Object.values(data) 35 | const placeholders = new Array(values.length).fill('?').join(',') 36 | const sql = `INSERT INTO ${table} (${keys}) VALUES (${placeholders})` 37 | const results = await query(sql, values) 38 | return results 39 | } 40 | 41 | // 更新方法 42 | const update = async (table, data, condition) => { 43 | const values = Object.values(data) 44 | const setClause = Object.keys(data) 45 | .map(key => `${key} = ?`) 46 | .join(', ') 47 | const whereClause = Object.keys(condition) 48 | .map(key => `${key} = ?`) 49 | .join(' AND ') 50 | const sql = `UPDATE ${table} SET ${setClause} WHERE ${whereClause}` 51 | const results = await query(sql, [...values, ...Object.values(condition)]) 52 | return results 53 | } 54 | 55 | // 删除方法 56 | const del = async (table, condition) => { 57 | const whereClause = Object.keys(condition) 58 | .map(key => `${key} = ?`) 59 | .join(' AND ') 60 | const sql = `DELETE FROM ${table} WHERE ${whereClause}` 61 | const results = await query(sql, Object.values(condition)) 62 | return results 63 | } 64 | 65 | // 改变某项数据方法 66 | const updateBy = async (table, data, condition) => { 67 | const setClause = Object.keys(data) 68 | .map(key => `${key} = ${key} + ?`) 69 | .join(', ') 70 | const whereClause = Object.keys(condition) 71 | .map(key => `${key} = ?`) 72 | .join(' AND ') 73 | const sql = `UPDATE ${table} SET ${setClause} WHERE ${whereClause}` 74 | const results = await query(sql, [ 75 | ...Object.values(data), 76 | ...Object.values(condition), 77 | ]) 78 | return results 79 | } 80 | 81 | module.exports = { 82 | query, 83 | insert, 84 | update, 85 | del, 86 | updateBy, 87 | } 88 | 89 | // 使用例子 90 | /* const db = require('./mysql') 91 | 92 | db.query('SELECT * FROM table_name') 93 | .then(results => { 94 | console.log('查询结果:', results) 95 | }) 96 | .catch(err => { 97 | console.error('查询出错:', err) 98 | }) 99 | 100 | db.insert('table_name', { name: 'John', age: 30 }) 101 | .then(result => { 102 | console.log('插入成功,result:', result) 103 | }) 104 | .catch(err => { 105 | console.error('插入出错:', err) 106 | }) 107 | 108 | db.update('table_name', { age: 31 }, { name: 'John' }) 109 | .then(result => { 110 | console.log('更新成功,result:', result) 111 | }) 112 | .catch(err => { 113 | console.error('更新出错:', err) 114 | }) 115 | 116 | db.del('table_name', { name: 'John' }) 117 | .then(result => { 118 | console.log('删除成功,result:', result) 119 | }) 120 | .catch(err => { 121 | console.error('删除出错:', err) 122 | }) 123 | 124 | // 增加某项数据 125 | db.updateBy('users', { article_count: 1 }, { name: 'John' }) 126 | .then(result => { 127 | console.log('更新成功,result:', result) 128 | }) 129 | .catch(err => { 130 | console.error('更新出错:', err) 131 | }) 132 | 133 | // 减少某项数据 134 | db.updateBy('users', { article_count: -1 }, { name: 'John' }) 135 | .then(result => { 136 | console.log('更新成功,result:', result) 137 | }) 138 | .catch(err => { 139 | console.error('更新出错:', err) 140 | }) 141 | 142 | */ 143 | -------------------------------------------------------------------------------- /back-end-source/utils/token.js: -------------------------------------------------------------------------------- 1 | const jwt = require('jsonwebtoken') 2 | const { expressjwt } = require('express-jwt') 3 | const secretKey = 'Jovesohandsome^-^fortokenkey' // 密钥 4 | const options = { 5 | expiresIn: '24h', // token 有效期 6 | } 7 | // 生成 token 8 | const generateToken = payload => { 9 | const token = 'Bearer ' + jwt.sign(payload, secretKey, options) 10 | return token 11 | } 12 | // 解析 token 的中间件 13 | const authenticateJwt = () => { 14 | return expressjwt({ 15 | secret: secretKey, 16 | algorithms: ['HS256'], 17 | getToken: req => req.headers.authorization?.split(' ')[1], 18 | }).unless({ path: [/^\/api\/user\/.*/] }) 19 | } 20 | // token 解析失败的中间件 21 | const errorHandler = (err, req, res, next) => { 22 | if (err.name === 'UnauthorizedError') { 23 | res.send({ retCode: 401, msg: '身份识别失败' }) 24 | return //直接停止中间链 25 | } else { 26 | next(err) 27 | } 28 | } 29 | // 通过 req.auth 访问 token,req.user 访问用户信息 30 | 31 | module.exports = { 32 | generateToken, 33 | authenticateJwt, 34 | errorHandler, 35 | } 36 | -------------------------------------------------------------------------------- /back-end-source/utils/validate.js: -------------------------------------------------------------------------------- 1 | const Joi = require('joi') 2 | 3 | // 定义表单判断的中间件 4 | const validateForm = schema => { 5 | return (req, res, next) => { 6 | const { error } = schema.validate(req.body) 7 | if (error) { 8 | res.send({ retCode: 400, msg: '表单数据不合法', details: error.details }) 9 | } else { 10 | next() 11 | } 12 | } 13 | } 14 | 15 | const id = Joi.number().integer().min(1).required() 16 | const nickname = Joi.alternatives() 17 | .try( 18 | Joi.string().regex(/^[\u4e00-\u9fa5]{1,16}$/), 19 | Joi.string().regex(/^[a-zA-Z0-9_\u4e00-\u9fa5]{1,20}$/), 20 | Joi.string().regex(/^[a-zA-Z0-9_]{1,30}$/), 21 | ) 22 | .required() 23 | 24 | // 注册表单的验证模式 25 | const regJoi = Joi.object({ 26 | // 中文最大值16,中英文混合最大值20,英文最大值30 27 | nickname, 28 | cellphone: Joi.string().pattern(new RegExp('^1[3-9]\\d{9}$')).required(), 29 | password: Joi.string().alphanum().min(6).max(30).required(), 30 | }) 31 | 32 | // 登录表单的验证模式 33 | const loginJoi = Joi.object({ 34 | cellphone: Joi.string().pattern(new RegExp('^1[3-9]\\d{9}$')).required(), 35 | password: Joi.string().alphanum().min(6).max(30).required(), 36 | }) 37 | 38 | // 更新用户头像的验证模式 39 | const avatarJoi = Joi.object({ 40 | id, 41 | // avatar: Joi.string().dataUri().required(), // dataUri字符串验证 42 | avatar: Joi.binary().required().encoding('base64').min(1), // 二进制文件base64编码验证 43 | }) 44 | 45 | // 上传画作的验证模式 46 | const uploadJoi = Joi.object({ 47 | userid: id, 48 | image: Joi.binary().required().encoding('base64').min(1), // 二进制文件base64编码验证 49 | title: Joi.string().min(1).max(30).required(), 50 | address: Joi.string().min(1).max(30), 51 | nickname, 52 | }) 53 | 54 | module.exports = { 55 | regJoi, 56 | loginJoi, 57 | avatarJoi, 58 | uploadJoi, 59 | validateForm, 60 | } 61 | -------------------------------------------------------------------------------- /front-end-source/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | // commonjs 2 | module.exports = { 3 | env: { 4 | browser: true, 5 | node: true, 6 | es6: true, 7 | }, 8 | parser: 'vue-eslint-parser', 9 | parserOptions: { 10 | ecmaVersion: 12, 11 | sourceType: 'module', 12 | ecmaFeatures: { 13 | jsx: true, 14 | }, 15 | }, 16 | extends: ['plugin:vue/vue3-recommended', 'plugin:prettier/recommended'], 17 | rules: { 18 | 'vue/multi-word-component-names': 0, 19 | 'vue/require-default-prop': 0, 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /front-end-source/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /front-end-source/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "bracketSpacing": true, 4 | "endOfLine": "lf", 5 | "semi": false, 6 | "singleQuote": true, 7 | "tabWidth": 2, 8 | "trailingComma": "all" 9 | } -------------------------------------------------------------------------------- /front-end-source/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar"] 3 | } 4 | -------------------------------------------------------------------------------- /front-end-source/README.md: -------------------------------------------------------------------------------- 1 | # 前端 2 | 3 | 框架:Vue 3 + Vite 4 | 5 | 库:Ant Design Vue + handtrack.js 6 | -------------------------------------------------------------------------------- /front-end-source/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 染指世界 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /front-end-source/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "jsx": "preserve", 5 | "lib": ["ES2015"], 6 | "skipLibCheck": true, 7 | "paths": { 8 | "@/*": ["src/*"] 9 | } 10 | }, 11 | "include": ["src/**/*"], 12 | "exclude": ["node_modules", "dist"] 13 | } 14 | -------------------------------------------------------------------------------- /front-end-source/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "front-end-source", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "@tensorflow/tfjs-core": "3.3.0", 13 | "@vitejs/plugin-legacy": "^4.0.2", 14 | "ant-design-vue": "^3.2.17", 15 | "axios": "^1.3.4", 16 | "axios-package2": "^1.2.3", 17 | "handtrackjs": "^0.1.5", 18 | "js-base64": "^3.7.5", 19 | "less": "^4.1.3", 20 | "pako": "^2.1.0", 21 | "pinia": "^2.0.33", 22 | "query-string": "^8.1.0", 23 | "seedrandom": "~2.4.4", 24 | "terser": "^5.16.8", 25 | "unplugin-vue-components": "^0.22.12", 26 | "vite-plugin-eslint": "^1.8.1", 27 | "vue": "^3.2.47", 28 | "vue-router": "^4.1.6", 29 | "webpack": "^5.77.0" 30 | }, 31 | "devDependencies": { 32 | "@babel/core": "^7.21.4", 33 | "@babel/eslint-parser": "^7.21.3", 34 | "@vitejs/plugin-vue": "^3.2.0", 35 | "eslint": "^8.37.0", 36 | "eslint-config-prettier": "^8.8.0", 37 | "eslint-plugin-prettier": "^4.2.1", 38 | "eslint-plugin-vue": "^9.10.0", 39 | "prettier": "^2.8.7", 40 | "vite": "^3.2.5" 41 | } 42 | } -------------------------------------------------------------------------------- /front-end-source/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/public/favicon.ico -------------------------------------------------------------------------------- /front-end-source/src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /front-end-source/src/apis/community.js: -------------------------------------------------------------------------------- 1 | import httpClient from '@/utils/http' 2 | const loginPrefix = '/community' 3 | 4 | // 上传画作 5 | export const upload = data => { 6 | return httpClient.post({ 7 | url: `${loginPrefix}/upload`, 8 | data: data, 9 | }) 10 | } 11 | 12 | // 查询所有画作 13 | export const queryList = () => { 14 | return httpClient.get({ 15 | url: `${loginPrefix}/qurList`, 16 | }) 17 | } 18 | 19 | // 点赞画作 20 | export const like = (id, likes) => { 21 | return httpClient.get({ 22 | url: `${loginPrefix}/like`, 23 | requestConfig: { params: { id, likes } }, 24 | }) 25 | } 26 | 27 | // 删除画作 28 | export const deleteArt = id => { 29 | return httpClient.get({ 30 | url: `${loginPrefix}/del`, 31 | requestConfig: { params: { id } }, 32 | }) 33 | } 34 | 35 | // 用户画作列表 36 | export const queryUserList = () => { 37 | return httpClient.get({ 38 | url: `${loginPrefix}/my`, 39 | }) 40 | } 41 | -------------------------------------------------------------------------------- /front-end-source/src/apis/user.js: -------------------------------------------------------------------------------- 1 | import httpClient from '@/utils/http' 2 | const loginPrefix = '/user' 3 | 4 | // 登录 5 | export const login = data => { 6 | return httpClient.post({ 7 | url: `${loginPrefix}/login`, 8 | data: data, 9 | }) 10 | } 11 | 12 | // 注册 13 | export const regUser = data => { 14 | return httpClient.post({ 15 | url: `${loginPrefix}/reguser`, 16 | data: data, 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /front-end-source/src/apis/userinfo.js: -------------------------------------------------------------------------------- 1 | import httpClient from '@/utils/http' 2 | const loginPrefix = '/userinfo' 3 | 4 | // 获取用户信息 5 | export const getInfo = () => { 6 | return httpClient.get({ 7 | url: `${loginPrefix}/getinfo`, 8 | isExecuteResponseCallback: false, 9 | }) 10 | } 11 | 12 | // 更改用户头像 13 | export const avatar = data => { 14 | return httpClient.post({ 15 | url: `${loginPrefix}/avatar`, 16 | data: data, 17 | }) 18 | } 19 | -------------------------------------------------------------------------------- /front-end-source/src/assets/fonts/SourceHanSansSC-Medium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/fonts/SourceHanSansSC-Medium.otf -------------------------------------------------------------------------------- /front-end-source/src/assets/fonts/站酷小薇LOGO体.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/fonts/站酷小薇LOGO体.otf -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/background_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/background_1.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/bulletin-board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/bulletin-board.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/card_comment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/card_comment.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/card_comment_actived.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/card_comment_actived.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/card_praise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/card_praise.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/card_praise_actived.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/card_praise_actived.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/color_index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/color_index.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/community-selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/community-selected.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/community.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/community.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/community_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/community_delete.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/github-btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/github-btn.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/head_author.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/head_author.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/head_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/head_select.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/head_time.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/head_time.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/head_users.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/head_users.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/head_work.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/head_work.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/list01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/list01.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/list02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/list02.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/list03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/list03.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/list04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/list04.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/login-btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/login-btn.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/logo.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/mywork-selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/mywork-selected.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/mywork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/mywork.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/pointer_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/pointer_1.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/pointer_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/pointer_4.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/share_QR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/share_QR.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/share_place.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/share_place.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/share_router.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/share_router.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/share_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/share_share.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/share_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/share_title.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/share_user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/share_user.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/slogan-btn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/slogan-btn.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/tool_0_gesture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/tool_0_gesture.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/tool_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/tool_1.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/tool_1_gesture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/tool_1_gesture.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/tool_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/tool_2.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/tool_2_gesture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/tool_2_gesture.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/tool_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/tool_3.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/tool_3_gesture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/tool_3_gesture.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/tool_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/tool_4.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/tool_4_gesture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/tool_4_gesture.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/tool_cancel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/tool_cancel.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/tool_clean.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/tool_clean.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/tool_save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/tool_save.png -------------------------------------------------------------------------------- /front-end-source/src/assets/picture/user_profile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Jovetat/GraffitiWorld/cdb43ec1752dc20e94061e90de15593601d449fc/front-end-source/src/assets/picture/user_profile.jpg -------------------------------------------------------------------------------- /front-end-source/src/components/CommunityHeader.vue: -------------------------------------------------------------------------------- 1 | 32 | 50 | 51 | 96 | -------------------------------------------------------------------------------- /front-end-source/src/components/CommunityNavigation.vue: -------------------------------------------------------------------------------- 1 | 44 | 71 | 72 | 151 | -------------------------------------------------------------------------------- /front-end-source/src/components/uploadForm.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 65 | 66 | 121 | -------------------------------------------------------------------------------- /front-end-source/src/hooks/brandInfo.js: -------------------------------------------------------------------------------- 1 | // 此封装用于生成画作品牌相关内容 2 | import { ref } from 'vue' 3 | import { startVideo } from './useHandTrack' 4 | 5 | export const isShow = ref(false) 6 | 7 | // 获取画作名称 8 | export const getTitle = () => { 9 | isShow.value = true 10 | } 11 | 12 | // 成功提交 13 | export const submitSuccess = () => { 14 | isShow.value = false 15 | } 16 | 17 | // 取消提交 18 | export const cancelSubmit = () => { 19 | startVideo() 20 | isShow.value = false 21 | } 22 | 23 | // todo:在图片下载时向 canvas 填入品牌 logo 等宣传信息 24 | export const addAD = ctx => { 25 | // 画板添加文字或图像 https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Drawing_text 26 | } 27 | -------------------------------------------------------------------------------- /front-end-source/src/hooks/panelDataProcess.js: -------------------------------------------------------------------------------- 1 | // 此 js 库用于处理手势识别的数据,并作出相应操作 2 | /* 3 | class 1:open 2:closed 3:pinch 4:point 4 | */ 5 | import { ref, reactive } from 'vue' 6 | import { message } from 'ant-design-vue' 7 | import { stopVideo } from './useHandTrack' 8 | import { 9 | startPainting, 10 | addPath, 11 | endPainting, 12 | setColor, 13 | undoPath, 14 | cleanCanvas, 15 | emptyHistory, 16 | downloadCanvas, 17 | } from './panelDrawing' 18 | import { upload } from '@/apis/community' 19 | import { useUserStore } from '@/store/user' 20 | import { getTitle, submitSuccess } from './brandInfo' 21 | 22 | export const curClass = ref(0) //指示当前手势 23 | export const menuPercent = ref(0) // 功能栏进度条 100满 24 | export const menuIndex = ref(0) // 当前功能栏的索引 25 | export const pointer = reactive({ x: 0, y: 0 }) 26 | let moveProportionX = 0 //移动比例 = 屏幕尺寸/手势位置范围 27 | let moveProportionY = 0 28 | let colorProportionX = 0 29 | let menuProportionX = 0 30 | const defaultParams = { 31 | handX: 600, // 手势范围 32 | handY: 400, 33 | colorNum: 14, 34 | menuNum: 3, 35 | menuTime: 2, 36 | } 37 | 38 | // 数据处理总函数 39 | export const dataProcessing = predictions => { 40 | // 找到第一个有效值,如果没有则返回 undefined 41 | const curHand = predictions.find(findRMS) 42 | const handClass = curHand ? curHand.class : 0 43 | const handBbox = curHand?.bbox 44 | if (curClass.value !== handClass) { 45 | changeClass(handClass, handBbox) 46 | } else { 47 | noChangeClass(handBbox) 48 | } 49 | } 50 | 51 | const changeClass = (newClass, bbox) => { 52 | if (newClass !== 4 && curClass.value === 4) { 53 | endPainting() 54 | } else if (newClass === 4) { 55 | startPainting(bbox[0] * moveProportionX, bbox[1] * moveProportionY) 56 | } else if (newClass === 3) { 57 | menuPercent.value = 0 58 | } 59 | curClass.value = newClass 60 | } 61 | 62 | // 没变化时控制输出绘画及完成功能 63 | const noChangeClass = bbox => { 64 | switch (curClass.value) { 65 | case 1: 66 | pointer.x = bbox[0] * moveProportionX 67 | pointer.y = bbox[1] * moveProportionY 68 | break 69 | case 4: 70 | const x = bbox[0] * moveProportionX 71 | const y = bbox[1] * moveProportionY 72 | pointer.x = x 73 | pointer.y = y 74 | addPath(x, y) 75 | break 76 | case 2: 77 | const colIndex = Math.floor(bbox[0] / colorProportionX) 78 | setColor(colIndex) 79 | break 80 | case 3: 81 | const index = Math.floor(bbox[0] / menuProportionX) 82 | // 进度条满才执行功能 83 | menuPercent.value = 84 | index === menuIndex.value 85 | ? menuPercent.value + defaultParams.menuTime 86 | : 0 87 | menuIndex.value = index 88 | if (menuPercent.value >= 100) { 89 | switch (menuIndex.value) { 90 | case 0: 91 | undoPath() 92 | message.success('成功撤销上一次绘画') 93 | break 94 | case 1: 95 | cleanCanvas() 96 | emptyHistory() 97 | message.success('成功清除画布') 98 | break 99 | case 2: 100 | message.success('成功保存画作') 101 | stopVideo() 102 | getTitle() 103 | break 104 | } 105 | menuPercent.value = 0 106 | } 107 | break 108 | } 109 | } 110 | 111 | export const getMoveProportion = () => { 112 | moveProportionX = window.innerWidth / defaultParams.handX 113 | moveProportionY = window.innerHeight / defaultParams.handY 114 | colorProportionX = defaultParams.handX / defaultParams.colorNum 115 | menuProportionX = defaultParams.handX / defaultParams.menuNum 116 | } 117 | 118 | export const overDraw = async (title, callback) => { 119 | const userStore = useUserStore() 120 | const creation = downloadCanvas() 121 | window.localStorage.setItem('imageData', creation) 122 | const data = { 123 | userid: userStore.userId, 124 | image: creation, 125 | title, 126 | address: userStore.address, 127 | nickname: userStore.userName, 128 | } 129 | const { retCode, msg } = await upload(data) 130 | if (retCode === 200) { 131 | callback && callback() 132 | submitSuccess() 133 | } 134 | } 135 | 136 | const findRMS = obj => { 137 | return obj.class !== 5 138 | } 139 | -------------------------------------------------------------------------------- /front-end-source/src/hooks/panelDrawing.js: -------------------------------------------------------------------------------- 1 | // 控制 canvas 输出图形 2 | import { ref } from 'vue' 3 | import { addAD } from './brandInfo' 4 | import { compressedImage } from '@/utils/encode' 5 | 6 | let canvas = null 7 | let ctx = null 8 | const defaultParams = { 9 | lineWidth: 6, // 绘画线宽 10 | backgroundColor: '#fff', // 背景颜色 11 | } 12 | let curLineArr = [] // 单次历史记录 13 | const allLinesArr = [] // 全部历史记录 14 | export const colorIndex = ref(0) //当前选择颜色的索引 15 | export const paletteArr = ref([ 16 | '#FFEB3B', 17 | '#FFC300', 18 | '#FF8D1A', 19 | '#A5D63F', 20 | '#43CF7C', 21 | '#00BAAD', 22 | '#2A82E4', 23 | '#7948EA', 24 | '#AC33C1', 25 | '#E33C64', 26 | '#FFFFFF', 27 | '#7A7A7A', 28 | '#585858', 29 | '#000000', 30 | ]) 31 | 32 | export const canvasInit = canvasRef => { 33 | canvas = canvasRef 34 | ctx = canvas.getContext('2d') 35 | // 默认值设置 36 | setLineWidth(defaultParams.lineWidth) 37 | setColor(13) 38 | canvas.width = window.innerWidth 39 | canvas.height = window.innerHeight 40 | ctx.fillStyle = defaultParams.backgroundColor 41 | ctx.fillRect(0, 0, canvas.offsetWidth, canvas.offsetHeight) 42 | } 43 | 44 | // 开始绘画 45 | export const startPainting = (x, y) => { 46 | ctx.beginPath() 47 | ctx.moveTo(x, y) 48 | curLineArr.push({ x, y }) 49 | } 50 | 51 | // 添加路径 52 | export const addPath = (x, y) => { 53 | ctx.lineTo(x, y) 54 | ctx.stroke() 55 | curLineArr.push({ x, y }) 56 | } 57 | 58 | // 结束绘画 59 | export const endPainting = () => { 60 | ctx.closePath() 61 | allLinesArr.push({ 62 | lineArr: curLineArr, 63 | color: colorIndex.value, 64 | }) 65 | curLineArr = [] 66 | } 67 | 68 | // 设置涂鸦线宽 69 | export const setLineWidth = linewidth => { 70 | ctx.lineWidth = linewidth 71 | } 72 | 73 | // 设置颜色(符合 CSS3 颜色值标准的有效字符串) 74 | export const setColor = index => { 75 | colorIndex.value = index 76 | ctx.strokeStyle = paletteArr.value[index] 77 | } 78 | 79 | // 撤销上一次绘画 80 | export const undoPath = () => { 81 | if (allLinesArr.length >= 1) { 82 | allLinesArr.pop() 83 | cleanCanvas() 84 | const selectColor = colorIndex.value 85 | // 重绘前n-1个路径 86 | allLinesArr.forEach(item => { 87 | setColor(item.color) 88 | let path = new Path2D() 89 | path.moveTo(item.lineArr[0].x, item.lineArr[0].y) 90 | for (let i = 1; i < item.lineArr.length; i++) { 91 | path.lineTo(item.lineArr[i].x, item.lineArr[i].y) 92 | } 93 | ctx.stroke(path) 94 | }) 95 | setColor(selectColor) 96 | } 97 | } 98 | 99 | // 清空画布 100 | export const cleanCanvas = () => { 101 | ctx.clearRect(0, 0, canvas.offsetWidth, canvas.offsetHeight) 102 | ctx.fillStyle = defaultParams.backgroundColor 103 | ctx.fillRect(0, 0, canvas.offsetWidth, canvas.offsetHeight) 104 | } 105 | 106 | // 清空历史记录 107 | export const emptyHistory = () => { 108 | allLinesArr.length = 0 109 | } 110 | 111 | // 下载涂鸦作品(返回一个下载链接) 112 | export const downloadCanvas = () => { 113 | addAD(ctx) 114 | const imgData = canvas.toDataURL('image/png') 115 | const compressedBase64Data = compressedImage(imgData) 116 | return compressedBase64Data 117 | } 118 | -------------------------------------------------------------------------------- /front-end-source/src/hooks/useHandTrack.js: -------------------------------------------------------------------------------- 1 | // 关于 handTrack 初始化 2 | import * as handTrack from 'handtrackjs' 3 | import { dataProcessing } from './panelDataProcess' 4 | import { message } from 'ant-design-vue' 5 | 6 | const defaultParams = { 7 | flipHorizontal: true, // 翻转水平 8 | outputStride: 16, // 输出步幅 9 | imageScaleFactor: 1, // 图像缩放因子 10 | maxNumBoxes: 3, // 最大数量框 11 | iouThreshold: 0.2, // iou阈值 12 | scoreThreshold: 0.7, // 分数阈值 13 | modelType: 'ssd320fpnlite', // 模型类型 14 | modelSize: 'large', // 模型大小 15 | bboxLineWidth: '2', // box线宽 16 | fontSize: 17, 17 | } 18 | 19 | let model = null 20 | let canvasRef = null 21 | let videoRef = null 22 | let isVideo = false 23 | const timeout = 30000 24 | 25 | // 模型初始化设置 26 | export const handInit = async (canvas, video, callback) => { 27 | canvasRef = canvas 28 | videoRef = video 29 | 30 | model = await loadModel() 31 | if (model) { 32 | message.success({ 33 | content: '模型加载完毕!', 34 | key: 'modelLoading', 35 | duration: 2, 36 | }) 37 | callback && callback() 38 | } else { 39 | message.warning({ 40 | content: '模型加载失败,请刷新重试!', 41 | key: 'modelLoading', 42 | duration: 2, 43 | }) 44 | } 45 | } 46 | 47 | // 加载模型 48 | const loadModel = async () => { 49 | message.loading({ 50 | content: '模型加载中...', 51 | key: 'modelLoading', 52 | duration: 0, 53 | }) 54 | // 超时处理使用 Promise.race方法来比较超时函数和 handTrack.load 方法的返回值 55 | try { 56 | const model = await Promise.race([ 57 | timeoutPromise(), 58 | handTrack.load(defaultParams), 59 | ]) 60 | return model 61 | } catch (error) { 62 | message.warning({ 63 | content: '模型加载超时,正在重新加载', 64 | key: 'timeout', 65 | duration: 2, 66 | }) 67 | console.log(error) 68 | return loadModel() 69 | } 70 | } 71 | 72 | // 加载模型超时 73 | const timeoutPromise = () => { 74 | return new Promise((resolve, reject) => { 75 | setTimeout(() => { 76 | reject(new Error('超时')) 77 | }, timeout) 78 | }) 79 | } 80 | 81 | // 开启摄像头侦测 82 | export const startVideo = async callback => { 83 | const status = await handTrack.startVideo(videoRef) 84 | if (status) { 85 | isVideo = true 86 | runDetection() 87 | callback && callback() 88 | } else { 89 | message.warning('请开启摄像头权限') 90 | } 91 | } 92 | 93 | // 停止摄像头侦测 94 | export const stopVideo = async () => { 95 | isVideo = false 96 | handTrack.stopVideo(videoRef) 97 | } 98 | 99 | // 手势识别运行中 100 | const runDetection = async () => { 101 | const predictions = await model.detect(videoRef) 102 | dataProcessing(predictions) 103 | model.renderPredictions( 104 | predictions, 105 | canvasRef, 106 | canvasRef.getContext('2d'), 107 | videoRef, 108 | ) 109 | if (isVideo) { 110 | requestAnimationFrame(runDetection) 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /front-end-source/src/main.js: -------------------------------------------------------------------------------- 1 | import App from './App.vue' 2 | import { createApp } from 'vue' 3 | import { createPinia } from 'pinia' 4 | import router from '@/router/router.js' 5 | import init from './utils/appinit' 6 | import './styles/index.less' 7 | import './styles/fonts.css' 8 | 9 | createApp(App).use(router).use(createPinia()).mount('#app') 10 | 11 | init() 12 | -------------------------------------------------------------------------------- /front-end-source/src/router/router.js: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHashHistory } from 'vue-router' 2 | import { useUserStore } from '@/store/user' 3 | 4 | const routes = [ 5 | { 6 | path: '/', 7 | redirect: '/about', 8 | }, 9 | { 10 | path: '/about', 11 | name: 'about', 12 | component: () => import('@/views/HomePage.vue'), 13 | }, 14 | { 15 | path: '/board', 16 | name: 'board', 17 | component: () => import('@/views/Painting/DrawingBoard.vue'), 18 | meta: { 19 | keepAlive: false, // 禁用缓存 20 | }, 21 | }, 22 | { 23 | path: '/community', 24 | name: 'community', 25 | redirect: 'community/world', 26 | component: () => import('@/views/SharingCommunity/SharingCommunity.vue'), 27 | children: [ 28 | { 29 | path: 'world', 30 | name: 'world', 31 | component: () => import('@/views/SharingCommunity/World.vue'), 32 | meta: { 33 | keepAlive: true, // 需要被缓存 34 | }, 35 | }, 36 | { 37 | path: 'my', 38 | name: 'my', 39 | component: () => import('@/views/SharingCommunity/MyWork.vue'), 40 | meta: { 41 | keepAlive: true, 42 | }, 43 | }, 44 | ], 45 | }, 46 | { 47 | path: '/login', 48 | name: 'login', 49 | component: () => import('@/views/User/Login.vue'), 50 | }, 51 | { 52 | path: '/share', 53 | name: 'share', 54 | component: () => import('@/views/Painting/WorkPublished.vue'), 55 | meta: { 56 | keepAlive: false, // 禁用缓存 57 | }, 58 | }, 59 | ] 60 | 61 | const router = createRouter({ 62 | history: createWebHashHistory(), 63 | routes, 64 | }) 65 | 66 | // 添加全局前置路由守卫 67 | router.beforeEach((to, from, next) => { 68 | const userStore = useUserStore() 69 | if (userStore.isLogin || to.path === '/about' || to.path === '/login') { 70 | next() 71 | } else { 72 | next('/login') 73 | } 74 | }) 75 | 76 | export default router 77 | -------------------------------------------------------------------------------- /front-end-source/src/store/user.js: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia' 2 | import { getInfo } from '@/apis/userinfo' 3 | 4 | export const useUserStore = defineStore('user', { 5 | state: () => { 6 | return { 7 | isLogin: false, 8 | token: '', 9 | userName: '', 10 | userId: 0, 11 | cellphone: '', 12 | address: '内蒙古艺术馆', 13 | } 14 | }, 15 | actions: { 16 | setLoginStatus(isLogin) { 17 | this.isLogin = isLogin 18 | }, 19 | setToken(token = '') { 20 | this.token = token 21 | if (token) { 22 | window.localStorage.setItem('token', token) 23 | this.setLoginStatus(true) 24 | } else { 25 | window.localStorage.removeItem('token') 26 | this.setLoginStatus(false) 27 | } 28 | }, 29 | setBasicInfo(userId, userName, cellphone) { 30 | this.userId = userId 31 | this.userName = userName 32 | this.cellphone = cellphone 33 | }, 34 | setUserInfo(data = {}) { 35 | const { id, nickname, cellphone } = data 36 | this.setBasicInfo(id, nickname, cellphone) 37 | }, 38 | async autoLogin() { 39 | const token = window.localStorage.getItem('token') 40 | if (token) { 41 | this.setToken(token) 42 | const { retCode, data } = await getInfo() 43 | if (retCode === 200) { 44 | this.setUserInfo(data) 45 | } else { 46 | this.setToken('') 47 | } 48 | } 49 | }, 50 | }, 51 | }) 52 | -------------------------------------------------------------------------------- /front-end-source/src/styles/fonts.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'zhanku'; 3 | src: url('../assets/fonts/站酷小薇LOGO体.otf'); 4 | font-weight: normal; 5 | font-weight: normal; 6 | } 7 | @font-face { 8 | font-family: 'sourceMedium'; 9 | src: url('../assets/fonts/SourceHanSansSC-Medium.otf'); 10 | font-weight: normal; 11 | font-weight: normal; 12 | } 13 | /* 设置全局默认字体 思源黑体中等 */ 14 | /* body { 15 | font-family: "sourceMedium"; 16 | } */ -------------------------------------------------------------------------------- /front-end-source/src/styles/index.less: -------------------------------------------------------------------------------- 1 | @import 'ant-design-vue/es/message/style/index.less'; -------------------------------------------------------------------------------- /front-end-source/src/utils/appinit.js: -------------------------------------------------------------------------------- 1 | // app 初始化时被调用 2 | import { useUserStore } from '@/store/user' 3 | 4 | const init = () => { 5 | // 自动登录 6 | const userStore = useUserStore() 7 | userStore.autoLogin() 8 | } 9 | 10 | export default init 11 | -------------------------------------------------------------------------------- /front-end-source/src/utils/encode.js: -------------------------------------------------------------------------------- 1 | // 调用 web-encoding 进行编码和解码 2 | import pako from 'pako' // 用于压缩图片 3 | import { Base64 } from 'js-base64' // 用于转码解码 4 | 5 | // 压缩图片 6 | export const compressedImage = imgData => { 7 | const base64Data = imgData.split(',')[1] 8 | const binaryData = Base64.toUint8Array(base64Data) // 将 base64 编码的图像数据解码为二进制数据 9 | const compressedData = pako.deflate(binaryData) // pako 压缩二进制数据 10 | const compressedBase64Data = Base64.fromUint8Array(compressedData) // 将二进制数据编码为 base64 11 | return compressedBase64Data 12 | } 13 | 14 | // 解压图片 15 | export const extractImage = compressedBase64Data => { 16 | const compressedData = Base64.toUint8Array(compressedBase64Data) 17 | const uncompressedData = pako.inflate(compressedData) 18 | const binaryData = Array.from(uncompressedData) 19 | .map(byte => String.fromCharCode(byte)) 20 | .join('') 21 | const base64Data = Base64.btoa(binaryData) 22 | const dataUrl = 'data:image/png;base64,' + base64Data 23 | return dataUrl 24 | } 25 | 26 | // 时间转换 27 | export const formatDate = time => { 28 | const date = new Date(time) 29 | const year = date.getFullYear() 30 | const month = (date.getMonth() + 1).toString().padStart(2, '0') 31 | const day = date.getDate().toString().padStart(2, '0') 32 | const hour = date.getHours().toString().padStart(2, '0') 33 | const minute = date.getMinutes().toString().padStart(2, '0') 34 | return `${year}-${month}-${day} ${hour}:${minute}` 35 | } 36 | -------------------------------------------------------------------------------- /front-end-source/src/utils/http.js: -------------------------------------------------------------------------------- 1 | import queryString from 'query-string' 2 | import HttpClient from 'axios-package2' 3 | import { useUserStore } from '@/store/user' 4 | import { message } from 'ant-design-vue' 5 | import router from '@/router/router' 6 | 7 | const responseCallback = result => { 8 | const { 9 | status, 10 | statusText, 11 | data: { retCode, msg }, 12 | } = result 13 | if (status === 200) { 14 | if (retCode === 200) { 15 | message.success(msg) 16 | } else { 17 | message.error(msg) 18 | if (retCode === 401) { 19 | // token 过期或不存在,跳转登录页面 20 | const userStore = useUserStore() 21 | userStore.setToken() 22 | router.push('/login') 23 | message.error('用户认证过期') 24 | } 25 | } 26 | } else { 27 | message.error(statusText) 28 | } 29 | } 30 | 31 | const config = { 32 | requestConfig: { 33 | baseURL: 'http://127.0.0.1:3000/api', 34 | headers: { 35 | 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8', 36 | // 'Content-Type': 'application/json;charset=utf-8', 37 | CLIENT: 'PC', 38 | }, 39 | timeout: 60000, 40 | transformRequest: [ 41 | (data, headers) => { 42 | if (headers) { 43 | const userStore = useUserStore() 44 | if (userStore.isLogin) { 45 | headers['Authorization'] = userStore.token 46 | } 47 | if (headers['Content-Type'].includes('x-www-form-urlencoded')) { 48 | return queryString.stringify(data) 49 | } 50 | } 51 | return data 52 | }, 53 | ], 54 | }, 55 | responseCallback, 56 | } 57 | 58 | const httpClient = new HttpClient(config) 59 | httpClient.http.interceptors.request.use( 60 | function (config) { 61 | if (config.method === 'get') { 62 | config.params = { 63 | ...config.params, 64 | } 65 | } 66 | return config 67 | }, 68 | function (error) { 69 | return Promise.reject(error) 70 | }, 71 | ) 72 | export default httpClient 73 | -------------------------------------------------------------------------------- /front-end-source/src/views/HomePage.vue: -------------------------------------------------------------------------------- 1 | 49 | 50 | 87 | 88 | 272 | -------------------------------------------------------------------------------- /front-end-source/src/views/Painting/DrawingBoard.vue: -------------------------------------------------------------------------------- 1 | 12 | 42 | 43 | 77 | -------------------------------------------------------------------------------- /front-end-source/src/views/Painting/MirrorShows.vue: -------------------------------------------------------------------------------- 1 | 17 | 56 | 57 | 84 | -------------------------------------------------------------------------------- /front-end-source/src/views/Painting/ToolBar.vue: -------------------------------------------------------------------------------- 1 | 56 | 84 | 85 | 232 | -------------------------------------------------------------------------------- /front-end-source/src/views/Painting/WorkPublished.vue: -------------------------------------------------------------------------------- 1 | 37 | 68 | 69 | 147 | -------------------------------------------------------------------------------- /front-end-source/src/views/SharingCommunity/MyWork.vue: -------------------------------------------------------------------------------- 1 | 23 | 59 | 60 | 128 | -------------------------------------------------------------------------------- /front-end-source/src/views/SharingCommunity/SharingCommunity.vue: -------------------------------------------------------------------------------- 1 | 20 | 33 | 34 | 57 | -------------------------------------------------------------------------------- /front-end-source/src/views/SharingCommunity/World.vue: -------------------------------------------------------------------------------- 1 | 41 | 83 | 84 | 190 | -------------------------------------------------------------------------------- /front-end-source/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import vue from '@vitejs/plugin-vue' 3 | import eslintPlugin from 'vite-plugin-eslint' 4 | import { resolve } from 'path' 5 | import legacy from '@vitejs/plugin-legacy' //将非 JavaScript 模块文件转换为 JavaScript 模块文件 6 | // Antd 组件按需注入 7 | import ViteComponents from 'unplugin-vue-components/vite' 8 | import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers' 9 | 10 | export default defineConfig({ 11 | server: { 12 | port: 5173, 13 | proxy: { 14 | '/api': { 15 | target: 'https://localhost:3000/', 16 | changeOrigin: true, 17 | rewrite: path => path.replace(/^\/api/, ''), 18 | }, 19 | }, 20 | }, 21 | plugins: [ 22 | vue(), 23 | legacy({ targets: ['ie >= 11', 'chrome >= 49'] }), 24 | eslintPlugin({ 25 | include: ['src/**/*.js', 'src/**/*.vue', 'src/*.js', 'src/*.vue'], 26 | }), 27 | { 28 | name: 'vite-plugin-antd', 29 | apply: 'serve', 30 | transform: (code, id) => { 31 | if (/src\/main.js$/.test(id)) { 32 | const finalCode = 33 | `import Antd from 'ant-design-vue';import 'ant-design-vue/dist/antd.less';${code}`.replace( 34 | 'createApp(App)', 35 | 'createApp(App).use(Antd)', 36 | ) 37 | return { 38 | code: finalCode, 39 | map: null, 40 | } 41 | } 42 | }, 43 | }, 44 | process.env.NODE_ENV === 'production' 45 | ? ViteComponents({ 46 | resolvers: [ 47 | AntDesignVueResolver({ 48 | importStyle: 'less', 49 | // resolveIcons: true, 50 | }), 51 | ], 52 | include: [/\.vue$/, /\.jsx?$/], 53 | }) 54 | : {}, 55 | ], 56 | resolve: { 57 | alias: { 58 | '@': resolve(__dirname, './src'), 59 | }, 60 | }, 61 | css: { 62 | preprocessorOptions: { 63 | less: { 64 | javascriptEnabled: true, 65 | modifyVars: { 66 | 'primary-color': '#E33C64', 67 | 'text-color': '#39393A', 68 | 'layout-body-background': '#E6E6E6', 69 | 'layout-sider-background-light': '#FF8552', 70 | }, 71 | }, 72 | }, 73 | }, 74 | build: { 75 | outDir: '../back-end-source/public', 76 | }, 77 | }) 78 | -------------------------------------------------------------------------------- /mysql/graffiti_world_db_user.sql: -------------------------------------------------------------------------------- 1 | -- MySQL dump 10.13 Distrib 8.0.32, for Win64 (x86_64) 2 | -- 3 | -- Host: localhost Database: graffiti_world_db 4 | -- ------------------------------------------------------ 5 | -- Server version 8.0.32 6 | 7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 10 | /*!50503 SET NAMES utf8 */; 11 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; 12 | /*!40103 SET TIME_ZONE='+00:00' */; 13 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 14 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 15 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 16 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 17 | 18 | -- 19 | -- Table structure for table `user` 20 | -- 21 | 22 | DROP TABLE IF EXISTS `user`; 23 | /*!40101 SET @saved_cs_client = @@character_set_client */; 24 | /*!50503 SET character_set_client = utf8mb4 */; 25 | CREATE TABLE `user` ( 26 | `id` int NOT NULL AUTO_INCREMENT, 27 | `nickname` varchar(60) NOT NULL, 28 | `password` varchar(60) NOT NULL, 29 | `cellphone` varchar(11) NOT NULL, 30 | `user_pic` text, 31 | PRIMARY KEY (`id`), 32 | UNIQUE KEY `id_UNIQUE` (`id`), 33 | UNIQUE KEY `nickname_UNIQUE` (`nickname`), 34 | UNIQUE KEY `cellphone_UNIQUE` (`cellphone`) 35 | ) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; 36 | /*!40101 SET character_set_client = @saved_cs_client */; 37 | 38 | -- 39 | -- Dumping data for table `user` 40 | -- 41 | 42 | LOCK TABLES `user` WRITE; 43 | /*!40000 ALTER TABLE `user` DISABLE KEYS */; 44 | INSERT INTO `user` VALUES (1,'JovrT0T','admin123','15117005855',NULL),(2,'龙静','$2a$10$3aTMKpvgMyKoQehAtFAYeO4j8YWeiTSR1Ow02UWP87l4.jeE9VrAm','18615424531',NULL),(3,'高杰','$2a$10$lsrqE3SZlOwsJDMxCT7n3ecneSUmlko5MPMmMz8QLs/GeRlMDQPxe','13905683231',NULL),(4,'韩超','$2a$10$7RAWTbAj/DM0gx9VyibQw.KmuCves7udi9CT.ILd89cc9vGy9/4Mi','18162478306',NULL),(5,'邵洋','$2a$10$vC/J004qyTYe0xag/0r.B.nco71gm0rAP7fS5VULuGI/bPYWnfQjS','18112538316',NULL),(6,'Jove','$2a$10$6yZdh.YGQ/0MJRiD5n8aUOk2ibjSaMYURM9/M4lYPZFO5sgg3p8tK','18347917651',NULL),(7,'钱涛','$2a$10$LoXFlnCmI24aafkBlQz5SeF3t4d0KkUmrYPWUXZ3dPD0HeCAHlt.2','18645214061',NULL),(8,'廖军','$2a$10$QTnoC6i9jwnBB8RM8JxcQuczi7QogotRIDWbL4xlObuK.UrFOf0OO','13356983774',NULL),(9,'admin','$2a$10$fgfxOkDizWmp7Tg9tFgi6OHQD8tcRhXOX8lK7uMy9D.H.Kc1O8X3.','19999999999','data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA+gAAAPoCAYAAABNo9TkAAAAAXNSR0IArs4c6QAAIABJREFUeF7s3XeYXNd95vm3u6q6OkfkHIgAgM4zgAACCCCAAAIIIIAAAggggIAHBAjoHugEmoAAAggggAACCCCAAAIIIIAAAZ1nAAEEEEAAAQ5jsWLYyAxs2LgNanXBe+9yuVG7dnVMyhgVVYFOe7Nw0S948dW3cerUGelUdxK5RmMSdDp9QK3H0aDZOl0OOMOQ5k57mz52CNq1aSm1z3GEiafKBJgAE2ACEgRYoEtA4kuYABNgAuEkcObMWYwdP0O0p1IaPQ/U6gZEjIxrebjmbbPlKIoOihZfzW5C+tihEXFwp3Xt3LkHmVOewa5d+6QFOjnLUx/08eOGomyZ+O{% mock \'dataImage\' %}'),(10,'康军','$2a$10$7TkMDh7Ld8dMR8MkNNEireL8C6E2pUy07xQUCqmHHC547v99Hi.hG','18136195447',NULL),(11,'吴秀兰','$2a$10$snunx4v68X2/EQuED1kA.uJITHgU24rekHP1PFS146.JeJVS8WEum','18117525851',NULL),(12,'傅勇','$2a$10$RKJtmOBtarl8vsoXMKinHeY6hwGSNG08MBvrlrZt4KzhwarNKXJ8W','18175546438',NULL),(13,'徐秀英','$2a$10$FAaU3rYtiRitJhPsBxdDA.dPZ.kaeI6HDKKA1LyUcs7qyCMSJ6cw2','18689643323',NULL),(14,'陆平','$2a$10$BUBPiXQVMcOWHMxDgn1w.O0B5/bjeD9RLD4wzYwtgq24uRrdVyjjm','13275354865',NULL),(15,'兜里没有糖的哇','$2a$10$xNIKOXVDjwHsQzi6god/FOivNbypJRoYdF3zb.SIvpFHIJlXYf/eq','18344444444',NULL),(16,'一二三四五六七八九十十一十二十三','$2a$10$S1d/RYIp6vuq62lLIHzegOoPekV2BMJ3VkzukHexo7dA3CG7aHg76','18344444455',NULL),(17,'admin2','$2a$10$P9UG5XCmhMYTVfcQeW8nfOzOsfmgzioY7a2w7lcWwluUUWIMIrlOG','18888888888',NULL); 45 | /*!40000 ALTER TABLE `user` ENABLE KEYS */; 46 | UNLOCK TABLES; 47 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; 48 | 49 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 50 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 51 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 52 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 53 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 54 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 55 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 56 | 57 | -- Dump completed on 2023-05-17 9:27:31 58 | --------------------------------------------------------------------------------