├── src ├── control │ ├── index.js │ └── todo │ │ └── index.js ├── assets │ ├── teat.pdf │ ├── logo.png │ └── 保理融资平台注册协议.pdf ├── api │ └── api.js ├── vuex │ ├── store.js │ └── mutations.js ├── main.js ├── utils │ └── common.js ├── unit │ ├── event.js │ ├── const.js │ ├── music.js │ ├── block.js │ └── index.js ├── components │ ├── HelloWorld.vue │ ├── Cascader.vue │ ├── rotate.vue │ ├── Treechart │ │ ├── tree.less │ │ ├── tree.html │ │ └── tree.js │ └── magnifier.vue ├── i18n.json └── App.vue ├── config ├── prod.env.js ├── dev.env.js └── index.js ├── public ├── favicon.ico └── index.html ├── babel.config.js ├── .gitignore ├── README.md ├── package.json └── vue.config.js /src/control/index.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/teat.pdf: -------------------------------------------------------------------------------- 1 | ggggg -------------------------------------------------------------------------------- /src/control/todo/index.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | MODE_ENV: '"production' 3 | } -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shengbid/my-element/master/public/favicon.ico -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shengbid/my-element/master/src/assets/logo.png -------------------------------------------------------------------------------- /src/assets/保理融资平台注册协议.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shengbid/my-element/master/src/assets/保理融资平台注册协议.pdf -------------------------------------------------------------------------------- /src/api/api.js: -------------------------------------------------------------------------------- 1 | export default { 2 | shareholder: { 3 | addShareHolder: "", 4 | deleteHolder: function(id) { 5 | return `*****/${id}`; 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var prodEnv = require('./prod.env') 3 | 4 | module.exports = merge(prodEnv, { 5 | MODE_ENV: '"development' 6 | }) -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ], 5 | plugins: ["@babel/plugin-transform-runtime", "transform-vue-jsx"], 6 | comments: false, 7 | env: { 8 | test: { 9 | presets: ["@babel/preset-env"], 10 | plugins: ["istanbul"] 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /src/vuex/store.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import { getNextType } from '../unit' 4 | import mutations from './mutations' 5 | import { isFocus } from '../unit' 6 | import { blankMatrix, lastRecord, maxPoint, blockType } from '../unit/const' 7 | import Block from '../unit/block' 8 | import { hasWebAudioAPI } from '../unit/music'; 9 | Vue.use(Vuex) 10 | 11 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import ElementUI from 'element-ui'; 4 | import 'element-ui/lib/theme-chalk/index.css'; 5 | // import store from './vuex/store' 6 | 7 | // import './unit/const' 8 | // import './control' 9 | // import { subscribeRecord } from './unit' 10 | // subscribeRecord(store) 11 | Vue.config.productionTip = false 12 | Vue.use(ElementUI) 13 | 14 | new Vue({ 15 | render: h => h(App) 16 | // store: store 17 | }).$mount('#app') 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # my-tetris 2 | 3 | ## Project setup 4 | ``` 5 | yarn install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | yarn run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | yarn run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | yarn run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | yarn run lint 26 | ``` 27 | 28 | ### Customize configuration 29 | See [Configuration Reference](https://cli.vuejs.org/config/). 30 | -------------------------------------------------------------------------------- /src/utils/common.js: -------------------------------------------------------------------------------- 1 | export default { 2 | // 限制只能输入数字(可以输入两位小数点) 3 | limitInputPointNumber(val) { 4 | if (val === 0 || val === "0" || val === "" || val === undefined) { 5 | return ""; 6 | } else { 7 | let value = null; 8 | value = val.replace(/[^\d.]/g, ""); // 清除“数字”和“.”以外的字符 9 | value = value.replace(/\.{2,}/g, "."); // 只保留第一个. 清除多余的 10 | value = value 11 | .replace(".", "$#$") 12 | .replace(/\./g, "") 13 | .replace("$#$", "."); 14 | value = value.replace(/^(-)*(\d+)\.(\d\d).*$/, "$1$2.$3"); // 只能输入两个小数 15 | return value; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | my-tetris 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | 3 | module.exports = { 4 | build: { 5 | env: require('./prod.env'), 6 | index: path.resolve(__dirname, '../dist/index.html'), 7 | assetsRoot: path.resolve(__dirname, '../dist'), 8 | assetsSubDirectory: 'public', 9 | assetsPublicPath: './', 10 | productionSourceMap: true, 11 | productionGzip: false, 12 | productionGzipExtensions: ['js', 'css'], 13 | bundleAnalyzerReport: process.env.npm_config_report 14 | }, 15 | dev: { 16 | env: require('./dev.env'), 17 | port: 8082, 18 | autoOpenBrowser: true, 19 | assetsSubDirectory: 'public', 20 | assetsPublicPath: '/', 21 | proxyTable: {}, 22 | cssSourceMap: false 23 | } 24 | } -------------------------------------------------------------------------------- /src/unit/event.js: -------------------------------------------------------------------------------- 1 | const eventName = {} 2 | 3 | const down = o => { 4 | // 键盘.手指按下 5 | const keys = Object.keys(eventName) 6 | keys.forEach(i => { 7 | clearTimeout(eventName[i]) 8 | eventName[i] = null 9 | }) 10 | if (!o.callback) { 11 | return 12 | } 13 | const clear = () => { 14 | clearTimeout(eventName[o.key]) 15 | } 16 | o.callback(clear) 17 | if (o.once === true) { 18 | return 19 | } 20 | let begin = o.begin || 100 21 | const interval = o.interval || 50 22 | const loop = () => { 23 | eventName[o.key] = setTimeout(() => { 24 | begin = null 25 | loop() 26 | o.callback(clear) 27 | }, begin || interval) 28 | } 29 | loop() 30 | } 31 | 32 | const up = o => { 33 | // 键盘,手指松开 34 | clearTimeout(eventName[o.key]) 35 | eventName[o.key] = null 36 | if (!o.callback) { 37 | return 38 | } 39 | o.callback() 40 | } 41 | 42 | const clearAll = () => { 43 | const keys = Object.keys(eventName) 44 | keys.forEach(i => { 45 | clearTimeout(eventName[i]) 46 | eventName[i] = null 47 | }) 48 | } 49 | 50 | export default { 51 | down, 52 | up, 53 | clearAll 54 | } -------------------------------------------------------------------------------- /src/vuex/mutations.js: -------------------------------------------------------------------------------- 1 | import { getNextType } from '../unit' 2 | import Block from '../unit/block' 3 | 4 | const mutations = { 5 | nextBlock(state, data) { 6 | if (!data) { 7 | data = getNextType() 8 | } 9 | state.next = data 10 | }, 11 | moveBlock(state, data) { 12 | state.cur = data.reset === true ? null : new Block(data) 13 | }, 14 | speedStart(state, data) { 15 | state.speedStart = data 16 | }, 17 | speedRun(state, data) { 18 | state.speedRun = data 19 | }, 20 | startLines(state, data) { 21 | state.startLines = data 22 | }, 23 | matrix(state, data) { 24 | state.matrix = data 25 | }, 26 | lock(state, data) { 27 | state.lock = data 28 | }, 29 | clearLines(state, data) { 30 | state.clearLines = data 31 | }, 32 | points(state, data) { 33 | state.points = data 34 | }, 35 | max(state, data) { 36 | state.max = data 37 | }, 38 | reset(state, data) { 39 | state.reset = data 40 | }, 41 | drop(state, data) { 42 | state.drop = data 43 | }, 44 | pause(state, data) { 45 | state.pause = data 46 | }, 47 | music(state, data) { 48 | state.music = data 49 | }, 50 | focus(state, data) { 51 | state.focus = data 52 | }, 53 | key_drop(state, data) { 54 | state.keyboard['drop'] = data 55 | }, 56 | key_down(state, data) { 57 | state.keyboard['down'] = data 58 | }, 59 | key_left(state, data) { 60 | state.keyboard['left'] = data 61 | }, 62 | key_right(state, data) { 63 | state.keyboard['right'] = data 64 | }, 65 | key_rotate(state, data) { 66 | state.keyboard['rotate'] = data 67 | }, 68 | key_reset(state, data) { 69 | state.keyboard['reset'] = data 70 | }, 71 | key_music(state, data) { 72 | state.keyboard['music'] = data 73 | }, 74 | key_pause(state, data) { 75 | state.keyboard['pause'] = data 76 | } 77 | } 78 | export default mutations -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-tetris", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "core-js": "^2.6.5", 12 | "element-ui": "^2.12.0", 13 | "lodash": "^4.17.15", 14 | "vue": "^2.6.10", 15 | "vue-pdf": "^4.0.7" 16 | }, 17 | "devDependencies": { 18 | "@babel/plugin-transform-runtime": "^7.5.5", 19 | "@babel/preset-env": "^7.5.5", 20 | "@vue/cli-plugin-babel": "^3.9.0", 21 | "@vue/cli-plugin-eslint": "^3.9.0", 22 | "@vue/cli-service": "^3.9.0", 23 | "babel-eslint": "^10.0.1", 24 | "babel-loader": "^8.0.6", 25 | "babel-plugin-syntax-jsx": "^6.18.0", 26 | "babel-plugin-transform-runtime": "^6.23.0", 27 | "babel-plugin-transform-vue-jsx": "^3.7.0", 28 | "babel-preset-env": "^1.7.0", 29 | "babel-preset-es2015": "^6.24.1", 30 | "babel-preset-stage-2": "^6.24.1", 31 | "chalk": "^2.4.2", 32 | "copy-webpack-plugin": "^5.0.3", 33 | "css-loader": "^3.0.0", 34 | "eslint": "^5.16.0", 35 | "eslint-plugin-vue": "^5.0.0", 36 | "extract-text-webpack-plugin": "^3.0.2", 37 | "file-loader": "^4.0.0", 38 | "friendly-errors-webpack-plugin": "^1.7.0", 39 | "html-loader": "^0.5.5", 40 | "html-webpack-plugin": "^3.2.0", 41 | "jquery": "^3.4.1", 42 | "less": "^3.10.3", 43 | "less-loader": "^5.0.0", 44 | "open": "^6.4.0", 45 | "optimize-css-assets-webpack-plugin": "^5.0.3", 46 | "ora": "^3.4.0", 47 | "semver": "^6.2.0", 48 | "shelljs": "^0.8.3", 49 | "url-loader": "^2.0.1", 50 | "vue-template-compiler": "^2.6.10", 51 | "webpack": "^4.35.3", 52 | "webpack-dev-middleware": "^3.7.0", 53 | "webpack-hot-middleware": "^2.25.0", 54 | "webpack-merge": "^4.2.1" 55 | }, 56 | "eslintConfig": { 57 | "root": true, 58 | "env": { 59 | "node": true 60 | }, 61 | "extends": [ 62 | "plugin:vue/essential", 63 | "eslint:recommended" 64 | ], 65 | "rules": { 66 | "no-console": "off" 67 | }, 68 | "parserOptions": { 69 | "parser": "babel-eslint" 70 | } 71 | }, 72 | "postcss": { 73 | "plugins": { 74 | "autoprefixer": {} 75 | } 76 | }, 77 | "browserslist": [ 78 | "> 1%", 79 | "last 2 versions" 80 | ] 81 | } 82 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | const path = require("path"); 3 | 4 | module.exports = { 5 | publicPath: "/", // 基本 URL 6 | outputDir: "dist", // 生成的生产环境构建文件的目录 7 | assetsDir: "", // 放置生成的静态资源的 (相对于 outputDir 的) 目录 8 | indexPath: "index.html", // 生成的 index.html 的输出路径 9 | filenameHashing: true, // 文件名hash值,控制缓存 10 | pages: { 11 | index: { 12 | // page 的入口 13 | entry: "src/main.js", 14 | // 模板来源 15 | template: "public/index.html", 16 | // 在 dist/index.html 的输出 17 | filename: "index.html", 18 | // 提取出来的通用 chunk 和 vendor chunk。 19 | chunks: ["chunk-vendors", "chunk-common", "index"] 20 | } 21 | }, // 多页面时配置的对象, 每个"page"应该有一个对应的 JavaScript 入口文件 22 | // lintOnSave: true, // 开发环境下,每次保存时lint检测代码 23 | // https://vuejs.org/v2/guide/installation.html#Runtime-Compiler-vs-Runtime-only 24 | runtimeCompiler: false, // 使用运行时编译器的Vue构建版本 25 | transpileDependencies: [], // babel-loader会忽略所有node_modules中的文件, 需要转译时可以一一列出 26 | productionSourceMap: false, // 生产环境是否生成 sourceMap 文件 27 | crossorigin: undefined, // 设置生成的 HTML 中 56 | 57 | 58 | 74 | -------------------------------------------------------------------------------- /src/unit/const.js: -------------------------------------------------------------------------------- 1 | import i18nJSON from '../i18n.json' 2 | 3 | export const blockShape = { 4 | I: [[1, 1, 1, 1]], 5 | L: [[0, 0, 1], [1, 1, 1]], 6 | J: [[1, 0, 0], [1, 1, 1]], 7 | Z: [[1, 1, 0], [0, 1, 1]], 8 | S: [[0, 1, 1], [1, 1, 0]], 9 | O: [[1, 1], [1, 1]], 10 | T: [[0, 1, 0], [1, 1, 1]] 11 | } 12 | 13 | export const origin = { 14 | I: [[-1, 1], [1, -1]], 15 | L: [[0, 0]], 16 | J: [[0, 0]], 17 | Z: [[0, 0]], 18 | S: [[0, 0]], 19 | O: [[0, 0]], 20 | T: [[0, 0], [1, 0], [-1, 1], [0, -1]] 21 | } 22 | 23 | export const blockType = Object.keys(blockShape) 24 | 25 | export const speeds = [800, 650, 500, 370, 250, 160] 26 | 27 | export const delays = [50, 60, 70, 80, 90, 100] 28 | 29 | export const fillLine = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] 30 | 31 | export const blankLine = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 32 | 33 | export const blankMatrix = (() => { 34 | const matrix = [] 35 | for (let i = 0; i < 20; i++) { 36 | matrix.push(blankLine) 37 | } 38 | return matrix 39 | }) 40 | 41 | export const clearPoints = [100, 300, 700, 1500] 42 | 43 | export const StorageKey = 'VUE_TETRIS' 44 | 45 | export const lastRecord = (() => { 46 | // 上一把的状态 47 | let data = window.localStorage.getItem(StorageKey) 48 | if (!data) { 49 | return false 50 | } 51 | try { 52 | if (window.btoa) { // btoa() 方法用于创建一个 base-64 编码的字符串;base-64 解码使用方法是 atob() 53 | data = atob(data) 54 | } 55 | data = decodeURIComponent(data) 56 | data = JSON.parse(data) 57 | } catch (e) { 58 | if (window.console || window.console.error) { 59 | window.console.error('读取纪录错误:', e) 60 | } 61 | return false 62 | } 63 | return data 64 | })() 65 | 66 | export const maxPoint = 999999 67 | 68 | export const transform = (function () { 69 | const trans = [ 70 | 'transform', 71 | 'webkitTransform', 72 | 'msTransform', 73 | 'mozTransform', 74 | 'oTransform' 75 | ] 76 | const body = document.body 77 | return trans.filter(e => body.style[e] !== undefined)[0] 78 | })() 79 | 80 | export const eachLines = 20 // 每消除eachLines行,增加速度 81 | 82 | export const getParam = param => { 83 | // 获取浏览器参数 84 | const r = new RegExp(`\\?(?:.+&)?${param}=(.*?)(?:&.*)?$`) 85 | const m = window.location.toString().match(r) 86 | return m ? decodeURI(m[1]) : '' 87 | } 88 | 89 | export const lan = (() => { 90 | let l = getParam('lan').toLowerCase() 91 | if (!l && navigator.languages) { // Chrome 32+及Firefox32+版本中,可以通过navigator.languages获取Accept-languages的值 92 | l = navigator.languages.find(l => i18nJSON.lan.indexOf(l) !== -1) 93 | } 94 | l = i18nJSON.lan.indexOf(l) === -1 ? i18nJSON.default : l 95 | return l 96 | })() 97 | 98 | document.title = i18nJSON.data.title[lan] 99 | 100 | export let i18n = i18nJSON.data -------------------------------------------------------------------------------- /src/unit/music.js: -------------------------------------------------------------------------------- 1 | import store from '../vuex/store' 2 | // 使用Web Audio API 3 | const AudioContext = 4 | window.AudioContext || window.webkitAudioContext || window.mozAudioContext 5 | || window.oAudioContext || window.msAudioContext 6 | 7 | export const hasWebAudioAPI = { 8 | // location.protocol返回当前url的协议部分:http 9 | data: !!AudioContext && location.protocol.indexOf('http') !== -1 10 | } 11 | 12 | export const music = {} 13 | (() => { 14 | if (!hasWebAudioAPI.data) { 15 | return 16 | } 17 | const url = './public/music.mp3' 18 | const context = new AudioContext() 19 | const req = new XMLHttpRequest() 20 | req.open('GET', url, true) 21 | req.responseType = 'arraybuffer' 22 | 23 | req.onload = () => { 24 | context.decodeAudioData( 25 | req.response, 26 | buf => { 27 | // 将拿到的audio解码转为buffer 28 | const getSource = () => { 29 | // 创建source源 30 | const source = context.createBufferSource() 31 | source.buffer = buf 32 | source.connect(context.destination) 33 | return source 34 | } 35 | 36 | music.killStart = () => { 37 | // 游戏开始的音乐只播放一次 38 | music.start = () => {} 39 | } 40 | 41 | music.start = () => { 42 | // 游戏开始 43 | music.killStart() 44 | if (!store.state.music) { 45 | return 46 | } 47 | getSource().start(0, 3.7202, 3.6224) 48 | } 49 | 50 | music.clear = () => { 51 | // 消除方块 52 | if (!store.state.music) { 53 | return 54 | } 55 | getSource().start(0, 0, 0.7675) 56 | } 57 | 58 | music.fall = () => { 59 | // 立即下落 60 | if (!store.state.music) { 61 | return 62 | } 63 | getSource().start(0, 1.2558, 0.3546) 64 | } 65 | 66 | music.gameover = () => { 67 | // 游戏结束 68 | if (!store.state.music) { 69 | return 70 | } 71 | getSource().start(0, 8.1276, 1.1437) 72 | } 73 | 74 | music.rotate = () => { 75 | // 旋转 76 | if (!store.state.music) { 77 | return 78 | } 79 | getSource().start(0, 2.2471, 0.0807) 80 | } 81 | 82 | music.move = () => { 83 | // 移动 84 | if (!store.state.music) { 85 | return 86 | } 87 | getSource().start(0, 2.9088, 0.1437) 88 | } 89 | }, 90 | error => { 91 | if (window.console && window.console.error) { 92 | window.console.error(`音频: ${url} 读取错误`, error) 93 | hasWebAudioAPI.data = false 94 | } 95 | } 96 | ) 97 | } 98 | 99 | req.send() 100 | })() -------------------------------------------------------------------------------- /src/unit/block.js: -------------------------------------------------------------------------------- 1 | import { blockShape, origin } from './const' 2 | 3 | class Block { 4 | constructor(option) { 5 | this.type = option.type 6 | if (!option.rotateIndex) { 7 | this.rotateIndex = 0 8 | } else { 9 | this.rotateIndex = option.rotateIndex 10 | } 11 | 12 | if (!option.timeStamp) { 13 | this.timeStamp = Date.now() 14 | } else { 15 | this.timeStamp = option.timeStamp 16 | } 17 | 18 | if (!option.shape) { 19 | this.shape = blockShape[option.type] 20 | } else { 21 | this.shape = option.shape 22 | } 23 | if (!option.xy) { 24 | switch (option.type) { 25 | case 'I': 26 | this.xy = [0, 3] 27 | break 28 | case 'L': 29 | this.xy = [-1, 4] 30 | break 31 | case 'J': 32 | this.xy = [-1, 4] 33 | break 34 | case 'Z': 35 | this.xy = [-1, 4] 36 | break 37 | case 'S': 38 | this.xy = [-1, 4] 39 | break 40 | case 'O': 41 | this.xy = [-1, 4] 42 | break 43 | case 'T': 44 | this.xy = [-1, 4] 45 | break 46 | default: 47 | break 48 | } 49 | } else { 50 | this.xy = option.xy 51 | } 52 | } 53 | rotate() { 54 | const shape = this.shape 55 | let result = [] 56 | shape.forEach(m => 57 | m.forEach((n, k) => { 58 | const index = m.length - k - 1 59 | if (result[index] === undefined) { 60 | result[index] = [] 61 | } 62 | result[index].push(n) 63 | const tempk = [...result[index]] 64 | result[index] = tempk 65 | }) 66 | ) 67 | const nextXy = [ 68 | this.xy[0] + origin[this.type][this.rotateIndex][0], 69 | this.xy[1] + origin[this.type][this.rotateIndex][1] 70 | ] 71 | const nextRotateIndex = this.rotateIndex + 1 >= origin[this.type].length 72 | ? 0 73 | : this.rotateIndex + 1 74 | return { 75 | shape: result, 76 | type: this.type, 77 | xy: nextXy, 78 | rotateIndex: nextRotateIndex, 79 | timeStamp: this.timeStamp 80 | } 81 | } 82 | fall(n = 1) { 83 | return { 84 | shape: this.shape, 85 | type: this.type, 86 | xy: [this.xy[0] + n, this.xy[1]], 87 | rotateIndex: this.rotateIndex, 88 | timeStamp: Date.now() 89 | } 90 | } 91 | right() { 92 | return { 93 | shape: this.shape, 94 | type: this.type, 95 | xy: [this.xy[0], this.xy[1] + 1], 96 | rotateIndex: this.rotateIndex, 97 | timeStamp: this.timeStamp 98 | } 99 | } 100 | left() { 101 | return { 102 | shape: this.shape, 103 | type: this.type, 104 | xy: [this.xy[0], this.xy[1] - 1], 105 | rotateIndex: this.rotateIndex, 106 | timeStamp: this.timeStamp 107 | } 108 | } 109 | } 110 | 111 | export default Block -------------------------------------------------------------------------------- /src/i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "lan": ["cn", "en", "fr", "fa"], 3 | "default": "cn", 4 | "data": { 5 | "title": { 6 | "cn": "俄罗斯方块", 7 | "en": "T E T R I S", 8 | "fr": "T E T R I S", 9 | "fa": "خانه سازی" 10 | }, 11 | "github": { 12 | "cn": "GitHub", 13 | "en": "GitHub", 14 | "fr": "GitHub", 15 | "fa": "گیت‌هاب" 16 | }, 17 | "linkTitle": { 18 | "cn": "查看源代码", 19 | "en": "View data source", 20 | "fr": "Afficher la source des données", 21 | "fa": "مشاهده سورس پروژه" 22 | }, 23 | "QRCode":{ 24 | "cn": "二维码", 25 | "en": "QR code", 26 | "fr": "QR code", 27 | "fa": "کیوآر کد" 28 | }, 29 | "QRNotice": { 30 | "cn": "扫一扫用手机玩", 31 | "en": "Scan QR code to play with a mobile phone", 32 | "fr": "Numérisez le code QR pour jouer avec un téléphone mobile", 33 | "fa": "اسکن کیوآر کد برای بازی در تلفن همراه" 34 | }, 35 | "titleCenter": { 36 | "cn": "俄罗斯方块
TETRIS", 37 | "en": "TETRIS", 38 | "fr": "TETRIS", 39 | "fa": "خانه سازی" 40 | }, 41 | "point": { 42 | "cn": "得分", 43 | "en": "Point", 44 | "fr": "Score", 45 | "fa": "امتیاز" 46 | }, 47 | "highestScore": { 48 | "cn": "最高分", 49 | "en": "Max", 50 | "fr": "Max", 51 | "fa": "حداکثر" 52 | }, 53 | "lastRound": { 54 | "cn": "上轮得分", 55 | "en": "Last Round", 56 | "fr": "Dernier Tour", 57 | "fa": "آخرین دور" 58 | }, 59 | "cleans": { 60 | "cn": "消除行", 61 | "en": "Cleans", 62 | "fr": "Lignes", 63 | "fa": "پاک کرد" 64 | }, 65 | "level": { 66 | "cn": "级别", 67 | "en": "Level", 68 | "fr": "Difficulté", 69 | "fa": "سطح" 70 | }, 71 | "startLine": { 72 | "cn": "起始行", 73 | "en": "Start Line", 74 | "fr": "Ligne Départ", 75 | "fa": "خط شروع" 76 | }, 77 | "next": { 78 | "cn": "下一个", 79 | "en": "Next", 80 | "fr": "Prochain", 81 | "fa": "بعدی" 82 | }, 83 | "pause": { 84 | "cn": "暂停", 85 | "en": "Pause", 86 | "fr": "Pause", 87 | "fa": "مکث" 88 | }, 89 | "sound": { 90 | "cn": "音效", 91 | "en": "Sound", 92 | "fr": "Sonore", 93 | "fa": "صدا" 94 | }, 95 | "reset": { 96 | "cn": "重玩", 97 | "en": "Reset", 98 | "fr": "Réinitialiser", 99 | "fa": "ریست" 100 | }, 101 | "rotation": { 102 | "cn": "旋转", 103 | "en": "Rotation", 104 | "fr": "Rotation", 105 | "fa": "چرخش" 106 | }, 107 | "left": { 108 | "cn": "左移", 109 | "en": "Left", 110 | "fr": "Gauche", 111 | "fa": "چپ" 112 | }, 113 | "right": { 114 | "cn": "右移", 115 | "en": "Right", 116 | "fr": "Droite", 117 | "fa": "راست" 118 | }, 119 | "down": { 120 | "cn": "下移", 121 | "en": "Down", 122 | "fr": "Bas", 123 | "fa": "پایین" 124 | }, 125 | "drop": { 126 | "cn": "掉落", 127 | "en": "Drop", 128 | "fr": "Tomber", 129 | "fa": "سقوط" 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/unit/index.js: -------------------------------------------------------------------------------- 1 | import { blockType, StorageKey } from './const' 2 | const hiddenProperty = (() => { 3 | // document[hiddenProperty] 可以判断页面是否失焦,判断用户是否在浏览当前页面 4 | let names = ['hidden', 'webkitHidden', 'mozHidden', 'msHidden'] 5 | names = names.filter(e => e in document) 6 | return names.length > 0 ? names[0] : false 7 | })() 8 | 9 | const unit = { 10 | getNextType () { 11 | // 随机获取下一个方块类型 12 | const len = blockType.length 13 | return blockType[Math.floor(Math.random() * len)] 14 | }, 15 | want(next, matrix) { 16 | // 方块是否能移动到指定位置 17 | const xy = next.xy 18 | const shape = next.shape 19 | const horizontal = shape[0].length 20 | return shape.every((m, k1) => 21 | m.every((n, k2) => { 22 | if (xy[1] < 0) { 23 | // left 24 | return false 25 | } 26 | if (xy[1] + horizontal > 10) { 27 | // right 28 | return false 29 | } 30 | if (xy[0] + k1 < 0) { 31 | // top 32 | return true 33 | } 34 | if (xy[0] + k1 >= 20) { 35 | // bottom 36 | return false 37 | } 38 | if (n) { 39 | if (matrix[xy[0] + k1][xy[1] + k2]) { 40 | return false 41 | } 42 | return true 43 | } 44 | return true 45 | }) 46 | ) 47 | }, 48 | isClear(matrix) { 49 | // 是否达到消除状态 50 | const clearLines = [] 51 | matrix.forEach((m, k) => { 52 | if (m.every(n => !!n)) { 53 | clearLines.push(k) 54 | } 55 | }) 56 | if (clearLines.length === 0) { 57 | return false 58 | } 59 | return clearLines 60 | }, 61 | isOver(matrix) { 62 | // 游戏是否结束,第一行落下方块为依据 63 | return matrix[0].some(n => !!n) 64 | }, 65 | subscribeRecord(store) { 66 | // 将状态纪录到localStorage 67 | store.subscribe(() => { 68 | let data = store.state 69 | if (data.lock) { 70 | // 当状态为锁定,不记录 71 | return 72 | } 73 | data = JSON.stringify(data) 74 | data = encodeURIComponent(data) 75 | if (window.btoa) { 76 | data = btoa(data) 77 | } 78 | window.localStorage.setItem(StorageKey, data) 79 | }) 80 | }, 81 | isMobile () { 82 | // 判断是否为移动端 83 | const ua = navigator.userAgent 84 | const android = /Android (\d+\.\d+)/.test(ua) 85 | const iphone = ua.indexOf('iPhone') > -1 86 | const ipod = ua.indexOf('iPod') > -1 87 | const ipad = ua.indexOf('iPad') > -1 88 | const nokiaN = ua.indexOf('NokiaN') > -1 89 | return android || iphone || ipod || ipad || nokiaN 90 | }, 91 | visibilityChangeEvent: (() => { 92 | if (!hiddenProperty) { 93 | return false 94 | } 95 | return hiddenProperty.replace(/hidden/i, 'visibilitychenge') // 如果属性有前缀,相应的事件也有前缀 96 | })(), 97 | 98 | isFocus: () => { 99 | if (!hiddenProperty) { 100 | // 如果不存在改特效,认为一直聚焦 101 | return true 102 | } 103 | return !document[hiddenProperty] 104 | } 105 | } 106 | 107 | export const { 108 | getNextType, 109 | isMobile, 110 | want, 111 | isClear, 112 | isOver, 113 | subscribeRecord, 114 | visibilityChangeEvent, 115 | isFocus 116 | } = unit -------------------------------------------------------------------------------- /src/components/Cascader.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 112 | 113 | 117 | -------------------------------------------------------------------------------- /src/components/rotate.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 78 | 79 | 127 | -------------------------------------------------------------------------------- /src/components/Treechart/tree.less: -------------------------------------------------------------------------------- 1 | .treechart { 2 | table{border-collapse: separate!important;border-spacing: 0!important;} 3 | td{position: relative; vertical-align: top;padding:0 0 50px 0;text-align: center; } 4 | 5 | .parent { 6 | background: #199ed8 !important; 7 | font-weight: bold; 8 | } 9 | .extend_handle{position: absolute;left:50%;bottom:27px; width:10px;height: 10px;padding:10px;transform: translate3d(-15px,0,0);cursor: pointer;} 10 | .extend_handle:before{content:""; display: block; width:100%;height: 100%;box-sizing: border-box; border:2px solid;border-color:#ccc #ccc transparent transparent; 11 | transform: rotateZ(135deg);transform-origin: 50% 50% 0;transition: transform ease 300ms;} 12 | .extend_handle:hover:before{border-color:#333 #333 transparent transparent;} 13 | .extend .extend_handle:before{transform: rotateZ(-45deg);} 14 | 15 | .extend::after{content: "";position: absolute;left:50%;bottom:15px;height:15px;border-left:2px solid #ccc;transform: translate3d(-1px,0,0)} 16 | .childLevel::before{content: "";position: absolute;left:50%;bottom:100%;height:15px;border-left:2px solid #ccc;transform: translate3d(-1px,0,0)} 17 | .childLevel::after{content: "";position: absolute;left:0;right:0;top:-15px;border-top:2px solid #ccc;} 18 | .childLevel:first-child:before, .childLevel:last-child:before{display: none;} 19 | .childLevel:first-child:after{left:50%;height:15px; border:2px solid;border-color:#ccc transparent transparent #ccc;border-radius: 6px 0 0 0;transform: translate3d(1px,0,0)} 20 | .childLevel:last-child:after{right:50%;height:15px; border:2px solid;border-color:#ccc #ccc transparent transparent;border-radius: 0 6px 0 0;transform: translate3d(-1px,0,0)} 21 | .childLevel:first-child.childLevel:last-child::after{left:auto;border-radius: 0;border-color:transparent #ccc transparent transparent;transform: translate3d(1px,0,0)} 22 | 23 | .node{position: relative; display: inline-block;box-sizing: border-box; text-align: center;padding: 0 5px;} 24 | .node .person{padding-top: 15px; position: relative; display: inline-block;z-index: 2;width:120px; overflow: hidden;} 25 | .node .person .avat{ 26 | padding: 5px; 27 | padding-top: 10px; 28 | display: block;width:100%;height: 100%;margin:auto;word-break: break-all; background:#ffcc00;box-sizing: border-box;border-radius: 4px; 29 | .opreate_icon { 30 | display: none; 31 | } 32 | &:hover { 33 | .opreate_icon { 34 | display: block; 35 | position: absolute; 36 | top: -3px; 37 | right: -3px; 38 | padding: 5px; 39 | } 40 | } 41 | 42 | &.company { 43 | background:#199ed8; 44 | } 45 | &.other { 46 | background:#ccc; 47 | } 48 | } 49 | .node .person .avat img{cursor: pointer;} 50 | .node .person .name{height:2em;line-height: 2em;overflow: hidden;width:100%;} 51 | .node.hasMate::after{content: "";position: absolute;left:2em;right:2em;top:15px;border-top:2px solid #ccc;z-index: 1;} 52 | .node.hasMate .person:last-child{margin-left:1em;} 53 | 54 | .landscape{transform: rotate(-90deg); padding:0 4em;} 55 | .landscape .node{text-align: left;height: 8em;width:8em;} 56 | .landscape .person{position: relative; transform: rotate(90deg);padding-left: 4.5em;height: 4em;top:4em;left: -1em;} 57 | .landscape .person .avat{position: absolute;left: 0;} 58 | .landscape .person .name{height: 4em; line-height: 4em;} 59 | .landscape .hasMate{position: relative;} 60 | .landscape .hasMate .person{position: absolute; } 61 | .landscape .hasMate .person:first-child{left:auto; right:-4em;} 62 | .landscape .hasMate .person:last-child{left: -4em;margin-left:0;} 63 | // .tree_color_description .tree_color_item .content {background-color: #ffcc00; width: 80px; height: 20px;} 64 | // .tree_color_description .tree_color_item .blue {background-color: #199ed8;} 65 | // .tree_color_description .tree_color_item .grey {background-color: #ccc;} 66 | // .tree_color_description .tree_color_item .word {font-size: 14px; margin-left: 5px;} 67 | 68 | .el-dialog__header { 69 | padding: 0; 70 | padding-top: 30px; 71 | margin: 0 30px; 72 | border-bottom: 1px solid #F1F1F1; 73 | text-align: left; 74 | .el-dialog__title { 75 | font-size: 14px; 76 | font-weight: bold; 77 | color: #464C5B; 78 | line-height: 20px; 79 | } 80 | } 81 | .tips { 82 | padding: 0 20px; 83 | .el-select { 84 | width: 100%; 85 | } 86 | .blue { 87 | color: #00B5EF; 88 | } 89 | .check { 90 | margin-left: 100px; 91 | } 92 | .inquiry { 93 | font-weight: bold; 94 | } 95 | .el-form-item__label { 96 | display: block; 97 | float: none; 98 | text-align: left; 99 | } 100 | .el-form-item__content { 101 | margin-left: 0; 102 | } 103 | } 104 | .el-dialog__body { 105 | padding: 30px 25px; 106 | p { 107 | margin-bottom: 15px; 108 | } 109 | } 110 | .el-dialog__headerbtn { 111 | top: 30px; 112 | right: 30px; 113 | } 114 | } 115 | .el-popover { 116 | .el-button { 117 | padding: 8px !important; 118 | margin-left: 5px !important; 119 | float: left; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 152 | 153 | 170 | -------------------------------------------------------------------------------- /src/components/Treechart/tree.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 47 | 48 | 49 | 50 | 53 | 54 |
5 |
6 |
7 | 12 |
13 | 添加 14 | 编辑 15 | 删除 16 |
17 |
18 | {{treeData.partnerName}}({{treeData.proportionShares ? treeData.proportionShares : 100}}%) 19 |
20 |
21 |
22 | {{treeData.partnerName}}({{treeData.proportionShares}}%) 23 |
24 |
25 |
26 | 31 |
32 | 添加 33 | 编辑 34 | 删除 35 |
36 |
37 | {{treeData.mate.name}} 38 |
39 |
40 |
41 | {{treeData.mate.name}} 42 |
43 |
44 |
45 |
46 |
51 | 52 |
55 | 56 | 57 | 63 |
64 | 65 | 66 | 67 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 |
83 | 84 |
85 | 取消 86 | 确定 87 |
88 |
89 |
90 | 91 | 92 | 96 |
97 |

确定删除该股东信息?

98 |
99 | 100 |
101 | 取消 102 | 保存 103 |
104 |
105 |
106 |
107 | -------------------------------------------------------------------------------- /src/components/magnifier.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 235 | 236 | 315 | -------------------------------------------------------------------------------- /src/components/Treechart/tree.js: -------------------------------------------------------------------------------- 1 | import common from "@/utils/common"; 2 | import "./tree.less"; 3 | import template from "./tree.html"; 4 | // import apiPath from "@api/api"; // 引入api.json文件 5 | import { Loading } from "element-ui"; 6 | 7 | export default { 8 | template, 9 | name: "TreeChart", 10 | props: { 11 | json: {}, // 渲染数据 12 | oldTreeData: {}, // 原始数据 13 | totalRates: 0, // 股东占股比例 14 | isDetail: { 15 | default: true // 是否是详情 16 | }, 17 | id: null // 最后一级id,前端添加数据需要 18 | }, 19 | 20 | data() { 21 | var checkShare = (rule, value, callback) => { 22 | let zero = /^0+\d*$/; 23 | let dublue = /^0{2,}\.\d+$/; 24 | var point = /^\d+\.?\d+$/; 25 | var reg = /^[1-9]{1}$/; 26 | if (value !== 0 && !value) { 27 | callback(new Error("请输入占股比例(%)")); 28 | } 29 | setTimeout(() => { 30 | if (zero.test(value) || dublue.test(value)) { 31 | callback(new Error("输入正确的数字格式")); 32 | } else if (point.test(value) || reg.test(value)) { 33 | this.ruleForm.proportionShares = Number(value); 34 | callback(); 35 | } else { 36 | callback(new Error("输入正确的数字格式")); 37 | } 38 | callback(); 39 | }, 100); 40 | }; 41 | return { 42 | treeData: {}, 43 | // oldTreeData: {}, 44 | rateCount: 0, // 股东占比总和 45 | oldCount: 0, // 编辑之前的总和 46 | oldRate: 0, // 编辑之前的单个值 47 | dialogVisible: false, // 添加股东弹框 48 | dialogVisible2: false, // 删除提示弹框 49 | isEdit: 0, // 是否编辑 0 新增 1 编辑 50 | ruleForm: { 51 | type: 1, 52 | partnerName: "", 53 | proportionShares: null 54 | }, 55 | rules: { 56 | proportionShares: [ 57 | { required: true, validator: checkShare, trigger: "blur" } 58 | ] 59 | }, 60 | isCompany: true, // 添加类型是否为企业 61 | shareholderTypeOptions: [ 62 | { 63 | labelEn: "Individual", 64 | labelZh: "个人", 65 | value: 1 66 | }, 67 | { 68 | labelEn: "Company", 69 | labelZh: "公司", 70 | value: 2 71 | }, 72 | { 73 | labelEn: "Other", 74 | labelZh: "其他", 75 | value: 3 76 | } 77 | ], // 股东类型 78 | isDisable: false, 79 | totalRate: 0, 80 | lastId: null // 最后一级id 81 | }; 82 | }, 83 | 84 | created() { 85 | // 设置语言 86 | this.setRule(); 87 | this.lastId = Number(this.id) 88 | console.log(this.json) 89 | }, 90 | 91 | watch: { 92 | isDetail: function(val) { // 是否是详情,详情不能添加编辑 93 | this.isDetail = val; 94 | }, 95 | json: { 96 | // 遍历当前的数据 97 | handler: function(Props) { 98 | let extendKey = function(jsonData) { 99 | jsonData.extend = 100 | jsonData.extend === void 0 ? true : !!jsonData.extend; 101 | if (Array.isArray(jsonData.children) && jsonData.children.length) { 102 | jsonData.children.forEach(c => { 103 | extendKey(c); 104 | }); 105 | } 106 | return jsonData; 107 | }; 108 | if (Props) { 109 | this.treeData = extendKey(Props); 110 | } 111 | }, 112 | immediate: true 113 | } 114 | }, 115 | methods: { 116 | // 设置规则 117 | setRule() { 118 | let getRule = { 119 | partnerName: [ 120 | { required: true, message: "请输入股东名称", trigger: "blur" } 121 | ], 122 | cardId: [ 123 | { required: true, message: "请输入证件号", trigger: "blur" } 124 | ], 125 | type: [ 126 | { required: true, message: "请选择类型", trigger: "blur" } 127 | ] 128 | }; 129 | this.rules = Object.assign(this.rules, getRule); 130 | }, 131 | 132 | toggleExtend(treeData) { 133 | treeData.extend = !treeData.extend; 134 | this.$forceUpdate(); 135 | }, 136 | 137 | // 改变添加类型 138 | changeType(val) { 139 | if (Number(val) === 3) { 140 | this.isDisable = true; 141 | this.ruleForm.partnerName = "其他"; 142 | } else { 143 | this.isDisable = false; 144 | this.ruleForm.partnerName = ""; 145 | } 146 | }, 147 | 148 | // 新增股东,val: 0 新增, 1 编辑 149 | addStock(val) { 150 | // console.log(this.treeData) 151 | this.isDisable = false; 152 | // 如果是新增,直接循环当前节点数据下的子级, 153 | // 如果是编辑,要通过当前节点数据的parentID遍历原始数据 154 | 155 | this.isEdit = val; 156 | if (val) { 157 | // this.$emit('click-node', {flag: 2, id: this.treeData.parentId}) 158 | this.rateCount = 0; 159 | this.rateCount = this.getRate( 160 | this.oldTreeData, 161 | this.treeData.prePartnerCode 162 | ); 163 | // 不使用=赋值,内存相同,改变后,treeData数据也会改变 164 | this.ruleForm = Object.assign(this.ruleForm, this.treeData); 165 | this.ruleForm.type = this.treeData.partnerType; 166 | if (Number(this.ruleForm.type === 3)) { 167 | this.isDisable = true; 168 | this.ruleForm.partnerName = "其他"; 169 | } 170 | this.oldRate = this.treeData.proportionShares; 171 | } else { 172 | let obj = this.forData(this.treeData); 173 | this.rateCount = obj.totalRate; 174 | } 175 | this.dialogVisible = true; 176 | }, 177 | 178 | // 循环股东树形图 获得股东比例和个数 179 | forData(data) { 180 | let obj = { 181 | totalRate: 0, 182 | leg: 0 183 | }; 184 | if (data.childers && data.childers.length) { 185 | data.childers.forEach(v => { 186 | obj.totalRate += v.proportionShares; 187 | }); 188 | obj.leg = data.childers.length; 189 | } 190 | return obj; 191 | }, 192 | 193 | // 循环股东树形图 获得股东比例 194 | getRate(data, id) { 195 | // 如果是第一级 196 | if (!id || data.partnerCode === id) { 197 | if (data.childers && data.childers.length) { 198 | data.childers.forEach(v => { 199 | this.rateCount += v.proportionShares; 200 | }); 201 | } 202 | return this.rateCount; 203 | } else if (data.childers && data.childers.length) { 204 | data.childers.some(v => { 205 | this.getRate(v, id); 206 | }); 207 | } 208 | }, 209 | 210 | // 编辑 211 | editStock() { 212 | this.dialogVisible = true; 213 | this.ruleForm = this.treeData; 214 | }, 215 | 216 | // 删除股东 217 | deleteStock() { 218 | // const loading = Loading.service(); 219 | // 前端删除 220 | // 前端删除这里不好操作,需要遍历整个原始数据删除,再赋值,比较麻烦 221 | 222 | // 后端删除 223 | // const url = apiPath.shareholder.deleteHolder(this.treeData.id); 224 | // this.$post(url).then(res => { 225 | // if (res.success) { 226 | // loading.close(); 227 | // this.treeData = {}; 228 | // this.dialogVisible2 = false; 229 | // this.$emit("click-node", { flag: 1 }); 230 | // this.$message({ 231 | // type: "success", 232 | // message: "删除成功" 233 | // }); 234 | // } else loading.close(); 235 | // }); 236 | }, 237 | 238 | // 限制只能输入数字 239 | limitNumber() { 240 | this.ruleForm.proportionShares = common.limitInputPointNumber( 241 | this.ruleForm.proportionShares 242 | ); 243 | }, 244 | 245 | // 验证比例 246 | checkRate() { 247 | if (this.isEdit) { 248 | if ( 249 | Number(this.ruleForm.proportionShares) + 250 | Number(this.rateCount) - 251 | Number(this.oldRate) > 252 | 100 253 | ) { 254 | this.$message({ 255 | type: "warning", 256 | message: "股东占股比例之和不能大于100" 257 | }); 258 | this.ruleForm.proportionShares = ""; 259 | } 260 | this.ruleForm.proportionShares = this.ruleForm.proportionShares; 261 | } else { 262 | if ( 263 | Number(this.ruleForm.proportionShares) + Number(this.rateCount) > 264 | 100 265 | ) { 266 | this.$message({ 267 | type: "warning", 268 | message: "股东占股比例之和不能大于100" 269 | }); 270 | this.ruleForm.proportionShares = ""; 271 | } 272 | } 273 | }, 274 | 275 | // 保存添加股东 276 | confirm() { 277 | // this.checkRate() 278 | let loading = Loading.service(); 279 | this.$refs.ruleForm.validate(valid => { 280 | if (valid) { 281 | this.sendData(); 282 | } else { 283 | loading.close(); 284 | } 285 | }); 286 | }, 287 | 288 | // 发送添加股东数据 289 | sendData() { 290 | let loading = Loading.service(); 291 | let data = { 292 | partnerType: this.ruleForm.type, 293 | partnerName: this.ruleForm.partnerName, 294 | proportionShares: this.ruleForm.proportionShares 295 | }; 296 | if (this.isEdit) { 297 | // data.id = this.treeData.id; 298 | // 前端编辑数据 299 | this.treeData.partnerType = data.partnerType 300 | this.treeData.partnerName = data.partnerName 301 | this.treeData.proportionShares = data.proportionShares 302 | this.$message({ 303 | type: "success", 304 | message: "成功" 305 | }); 306 | this.clearDialog(); 307 | loading.close() 308 | } else { 309 | // 前端添加数据,需要自己生成子级id,可以传数据的时候把最后一级id传过来,进行累加 310 | data.prePartnerCode = this.treeData.partnerCode; 311 | data.id = this.lastId ++ 312 | if (this.treeData.childers) { 313 | this.treeData.childers.push(data) 314 | } else { 315 | this.treeData.childers = [data] 316 | } 317 | console.log(this.lastId, this.treeData) 318 | this.$message({ 319 | type: "success", 320 | message: "成功" 321 | }); 322 | this.clearDialog(); 323 | loading.close() 324 | } 325 | // 后台添加编辑数据 326 | // console.log(data, this.treeData); 327 | // const url = apiPath.shareholder.addShareHolder; 328 | // this.$post(url, data) 329 | // .then(res => { 330 | // loading.close(); 331 | // if (res && res.success) { 332 | // this.$emit("click-node", { flag: 1, id: data.parentId }); 333 | // this.$message({ 334 | // type: "success", 335 | // message: "成功" 336 | // }); 337 | // this.clearDialog(); 338 | // } else { 339 | // this.rateCount = this.oldCount; 340 | // } 341 | // }) 342 | // .catch(err => { 343 | // console.log(err); 344 | // }); 345 | }, 346 | 347 | // 清除表单信息 348 | clearDialog() { 349 | // this.ruleForm = {} 350 | this.$refs.ruleForm.resetFields(); 351 | this.dialogVisible = false; 352 | }, 353 | 354 | changeOpen() {} 355 | } 356 | }; 357 | --------------------------------------------------------------------------------