├── .browserslistrc
├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── README.md
├── babel.config.js
├── favicon.ico
├── jsconfig.json
├── package.json
├── public
├── favicon.ico
└── index.html
├── src
├── App.vue
├── api.js
├── assets
│ ├── iconfont
│ │ ├── demo.css
│ │ ├── demo_index.html
│ │ ├── iconfont.css
│ │ ├── iconfont.eot
│ │ ├── iconfont.js
│ │ ├── iconfont.json
│ │ ├── iconfont.svg
│ │ ├── iconfont.ttf
│ │ ├── iconfont.woff
│ │ └── iconfont.woff2
│ ├── img
│ │ ├── 1.png
│ │ ├── 2.png
│ │ ├── 3.png
│ │ ├── 4.png
│ │ ├── 5.png
│ │ ├── 6.png
│ │ ├── 7.png
│ │ ├── 8.png
│ │ └── 9.png
│ └── logo.png
├── background.js
├── components
│ ├── DataSource.vue
│ ├── FieldTable.vue
│ ├── Generate.vue
│ └── ViewFiles.vue
├── localstorage.js
├── main.js
├── mix
│ ├── fileData.js
│ └── tableData.js
├── router
│ └── index.js
├── store
│ └── index.js
├── style
│ ├── element-variables.scss
│ ├── main.css
│ └── reset.css
└── views
│ ├── BuildCode.vue
│ ├── DocumentText.vue
│ ├── Home.vue
│ └── TemplateManagement.vue
├── static
├── componentList.json
├── document
│ └── frontCRUD.md
└── ejs
│ ├── bim
│ ├── bimApi
│ ├── bimCRUD-弹窗版
│ ├── bimCRUD-弹窗版Api
│ ├── bim左右结构
│ ├── bim左右结构-弹窗版
│ ├── bim左右结构-弹窗版Api
│ └── bim左右结构Api
├── vue.config.js
├── yarn.lock
├── 前端代码生成器使用说明.md
└── 更换模板操作.md
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 | not dead
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.{js,jsx,ts,tsx,vue}]
2 | indent_style = space
3 | indent_size = 2
4 | trim_trailing_whitespace = true
5 | insert_final_newline = true
6 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | node: true
5 | },
6 | extends: [
7 | 'plugin:vue/essential',
8 | '@vue/standard'
9 | ],
10 | parserOptions: {
11 | parser: 'babel-eslint'
12 | },
13 | rules: {
14 | 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
15 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
25 | #Electron-builder output
26 | /dist_electron
27 |
28 | # 生成的数据文件
29 | /static/localConfig.json
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # EasyCode For JavaScript
2 |
3 | # Feature
4 |
5 | - 使用Ejs作为模板, 简单易学
6 |
7 | - 此Ejs中已经内置了lodash.js 更灵活
8 |
9 | - 只要是关于数据库生成的 都能用
10 |
11 | # DevelopmentEnvironment
12 |
13 | - yarn
14 | ```
15 | yarn
16 | ```
17 |
18 | - 运行
19 | ```
20 | yarn electron-serve
21 | ```
22 |
23 | # ProductionEnvironment
24 |
25 | - github中有Releases可供下载
26 |
27 | - yarn electron-build
28 |
29 | # Use
30 |
31 | ctrl+n 连接数据库
32 |
33 | ctrl+alt+s 设置生成模板目录(默认是桌面,mac、linux生成时会报错,更改生成目录就好了。mac、linux用户生成时请确保权限ok)
34 |
35 | # TODO
36 |
37 | - 后台语言java等模板demo制作
38 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chendonming/easycode-javascript/656b7c777bc7e045f45b0d3365f3dced98b48f6d/favicon.ico
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "include": ["src/**/*"],
3 | "target": "es6",
4 | "exclude": ["node_modules"],
5 | "compilerOptions": {
6 | "baseUrl": ".",
7 | "paths": {
8 | "@/*": ["./src/*"]
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "easycode-javascript",
3 | "version": "1.0.21",
4 | "private": false,
5 | "author": "chendm<2283973011@qq.com>",
6 | "description": "一款前端代码生成器",
7 | "scripts": {
8 | "serve": "vue-cli-service serve",
9 | "build": "vue-cli-service build",
10 | "lint": "vue-cli-service lint",
11 | "electron:build": "vue-cli-service electron:build",
12 | "electron:serve": "vue-cli-service electron:serve",
13 | "postinstall": "electron-builder install-app-deps",
14 | "postuninstall": "electron-builder install-app-deps"
15 | },
16 | "main": "background.js",
17 | "dependencies": {
18 | "core-js": "^3.6.5",
19 | "ejs": "^3.1.5",
20 | "electron-builder": "^22.14.13",
21 | "element-ui": "^2.13.2",
22 | "fs-extra": "^10.0.0",
23 | "github-markdown-css": "^4.0.0",
24 | "lodash": "^4.17.20",
25 | "marked": "^1.2.2",
26 | "monaco-editor": "^0.31.1",
27 | "mysql2": "^2.2.5",
28 | "sass": "^1.27.1",
29 | "sass-loader": "^10.0.4",
30 | "sortablejs": "^1.14.0",
31 | "uuid": "^8.3.1",
32 | "vue": "^2.6.11",
33 | "vue-router": "^3.2.0",
34 | "vuex": "^3.4.0"
35 | },
36 | "devDependencies": {
37 | "@vue/cli-plugin-babel": "~4.5.0",
38 | "@vue/cli-plugin-eslint": "~4.5.0",
39 | "@vue/cli-plugin-router": "~4.5.0",
40 | "@vue/cli-plugin-vuex": "~4.5.0",
41 | "@vue/cli-service": "~4.5.0",
42 | "@vue/eslint-config-standard": "^5.1.2",
43 | "babel-eslint": "^10.1.0",
44 | "electron": "^9.0.0",
45 | "electron-devtools-installer": "^3.1.0",
46 | "eslint": "^6.7.2",
47 | "eslint-plugin-import": "^2.20.2",
48 | "eslint-plugin-node": "^11.1.0",
49 | "eslint-plugin-promise": "^4.2.1",
50 | "eslint-plugin-standard": "^4.0.0",
51 | "eslint-plugin-vue": "^6.2.2",
52 | "less": "^3.0.4",
53 | "less-loader": "^5.0.0",
54 | "vue-cli-plugin-electron-builder": "~2.0.0-rc.4",
55 | "vue-template-compiler": "^2.6.11"
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chendonming/easycode-javascript/656b7c777bc7e045f45b0d3365f3dced98b48f6d/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
24 |
25 |
52 |
--------------------------------------------------------------------------------
/src/api.js:
--------------------------------------------------------------------------------
1 | import { app, dialog, ipcMain } from 'electron'
2 | import fs from 'fs'
3 | import mysql from 'mysql2'
4 | import ejs from 'ejs'
5 | import { v4 as uuidv4 } from 'uuid'
6 | import { exec } from 'child_process'
7 | import localstorage from './localstorage'
8 | import path from 'path'
9 | import fsExtra from 'fs-extra'
10 |
11 | function queryAllTables (connection, db) {
12 | return new Promise((resolve, reject) => {
13 | const json = {}
14 | if (connection) {
15 | connection.query(`use \`${db}\``, err => {
16 | if (err) {
17 | json.code = -1
18 | json.msg = '查询数据库失败: ' + err.message
19 | reject(json)
20 | } else {
21 | connection.query('select TABLE_NAME,TABLE_COMMENT from information_schema.tables where TABLE_TYPE = \'BASE TABLE\'', (err, res) => {
22 | if (err) {
23 | json.code = -1
24 | json.msg = '查询数据库失败: ' + err.message
25 | reject(json)
26 | } else {
27 | json.code = 200
28 | json.data = res
29 | resolve(json)
30 | }
31 | })
32 | }
33 | })
34 | } else {
35 | json.code = -1
36 | json.msg = '请链接数据库再做此操作'
37 | reject(json)
38 | }
39 | })
40 | }
41 |
42 | /**
43 | * 根据表名查询字段名称
44 | * @param connection
45 | * @param table
46 | */
47 | function queryColumns (connection, table) {
48 | return new Promise((resolve, reject) => {
49 | const json = {}
50 | connection.query(`show full columns from \`${table}\``, (err, res) => {
51 | if (err) {
52 | json.code = -1
53 | json.msg = 'err: ' + err.message
54 | reject(json)
55 | } else {
56 | resolve(res)
57 | }
58 | })
59 | })
60 | }
61 |
62 | export default function (win, renderer) {
63 | let connection
64 | ipcMain.on('queryTemplateFile', () => {
65 | const path = app.getPath('userData') + '\\template'
66 | fs.access(path, err => {
67 | if (err) {
68 | // 创建文件夹再返回空数据
69 | fs.mkdir(path, err => {
70 | const json = {}
71 | if (err) {
72 | json.code = -1
73 | json.msg = '创建文件夹失败'
74 | } else {
75 | json.code = 200
76 | json.data = []
77 | }
78 | renderer.send('queryTemplateFile', json)
79 | })
80 | } else {
81 | fs.readdir(path, (err, fileList) => {
82 | if (err) {
83 | renderer.send('queryTemplateFile', {
84 | code: -1,
85 | msg: '读取文件失败!'
86 | })
87 | } else {
88 | renderer.send('queryTemplateFile', {
89 | code: 200,
90 | data: fileList.map(v => ({
91 | title: v,
92 | value: path + '\\' + v
93 | }))
94 | })
95 | }
96 | })
97 | }
98 | })
99 | })
100 |
101 | ipcMain.on('localTemplateFile', () => {
102 | const folder = path.join(__dirname, '../static/ejs/')
103 | fs.access(folder, err => {
104 | if (!err) {
105 | fs.readdir(folder, (err, fileList) => {
106 | if (!err) {
107 | renderer.send('localTemplateFile', fileList.map(v => ({
108 | title: v,
109 | value: folder + v
110 | })))
111 | }
112 | })
113 | }
114 | })
115 | })
116 |
117 | ipcMain.on('loadComponentList', () => {
118 | const file = path.join(__dirname, '../static/componentList.json')
119 | fs.readFile(file, 'utf8', (err, data) => {
120 | if (!err) {
121 | renderer.send('loadComponentList', data)
122 | }
123 | })
124 | })
125 |
126 | ipcMain.on('connectToTheDatabase', (e, data) => {
127 | try {
128 | delete data.tryConnection
129 | if (connection) connection.destroy()
130 | connection = mysql.createConnection(data)
131 | connection.ping((err) => {
132 | if (err) {
133 | win.webContents.send('connection.failed', { msg: err.message })
134 | } else {
135 | win.webContents.send('connection.success')
136 | }
137 | })
138 | } catch (err) {
139 | win.webContents.send('connection.failed', { msg: err.message })
140 | }
141 | })
142 |
143 | ipcMain.on('showDatabase', () => {
144 | const json = {}
145 | if (connection) {
146 | connection.query('show databases', (err, res) => {
147 | if (err) {
148 | json.code = -1
149 | json.msg = '查询数据库失败: ' + err.message
150 | } else {
151 | json.code = 200
152 | json.data = res.map(v => v.Database).filter(v => ['information_schema', 'performance_schema', 'mysql'].indexOf(v) === -1)
153 | }
154 | renderer.send('showDatabase', json)
155 | })
156 | } else {
157 | json.code = -1
158 | json.msg = '请链接数据库再做此操作'
159 | renderer.send('showDatabase', json)
160 | }
161 | })
162 |
163 | ipcMain.on('queryAllTables', async (e, db) => {
164 | try {
165 | const data = await queryAllTables(connection, db)
166 | renderer.send('queryAllTables', data)
167 | } catch (err) {
168 | renderer.send('queryAllTables', err)
169 | }
170 | })
171 |
172 | // 根据Ejs生成实体类文件 (Test)
173 | function generateEjsFile (data, tableName) {
174 | const newTableName = data.tableName ? data.tableName.toLocaleUpperCase() : tableName
175 | const newData = {
176 | ...data,
177 | table: newTableName,
178 | date: new Date().toLocaleDateString(),
179 | className: 'Test'
180 | }
181 | ejs.renderFile(data.templateName, newData, (err, str) => {
182 | if (err) {
183 | renderer.send('generateEntityFiles', {
184 | code: -1,
185 | msg: 'err: ' + err.message
186 | })
187 | } else {
188 | const fileName = app.getPath('userData') + '\\files\\' + newTableName + '.java'
189 | fs.writeFile(fileName, str, { flag: 'a' }, (err) => {
190 | if (err) {
191 | renderer.send('generateEntityFiles', {
192 | code: -1,
193 | msg: 'err: ' + err.message
194 | })
195 | } else {
196 | renderer.send('generateEntityFiles', {
197 | code: 200,
198 | data: fileName
199 | })
200 | }
201 | })
202 | }
203 | })
204 | }
205 |
206 | // 生成实体类文件
207 | ipcMain.on('generateEntityFiles', (e, data) => {
208 | if (data.tableName) {
209 | generateEjsFile(data)
210 | } else {
211 | queryAllTables(connection, data.database).then(res => {
212 | if (res.code === 200) {
213 | res.data.forEach(v => {
214 | generateEjsFile(data, v.toLocaleUpperCase())
215 | })
216 | }
217 | })
218 | }
219 | })
220 |
221 | ipcMain.on('generateCustomFiles', (e, data) => {
222 | // 使用固定文件位置
223 | const setting = localstorage.getItem('setting')
224 | const name = data.name || uuidv4()
225 | let filepath
226 | if (setting && setting.fileGenerationDirectory) {
227 | filepath = setting.fileGenerationDirectory + '\\' + name
228 | } else {
229 | filepath = app.getPath('userData') + '\\' + name
230 | }
231 | ejs.renderFile(data.templateName, {
232 | ...data,
233 | _: require('lodash')
234 | }, (err, str) => {
235 | if (err) {
236 | renderer.send('generateCustomFiles', {
237 | code: -1,
238 | msg: 'err: ' + err.message,
239 | err: err
240 | })
241 | } else {
242 | if (data.type === 'previewCode') {
243 | // 执行预览
244 | renderer.send('generateCustomFiles', {
245 | code: 200,
246 | data: str,
247 | type: 'previewCode'
248 | })
249 | } else {
250 | fs.writeFile(filepath + '.' + data.suffix, str, { flag: 'ax' }, (err) => {
251 | if (err) {
252 | renderer.send('generateCustomFiles', {
253 | code: err.code,
254 | err: err
255 | })
256 | } else {
257 | renderer.send('generateCustomFiles', {
258 | code: 200,
259 | data: filepath + '.' + data.suffix
260 | })
261 | }
262 | })
263 | }
264 | }
265 | })
266 | })
267 |
268 | // 显示表中所有字段
269 | ipcMain.on('displayField', (e, db, table) => {
270 | const json = {}
271 | if (connection) {
272 | connection.query(`use \`${db}\``, async (err) => {
273 | if (err) {
274 | json.code = -1
275 | json.msg = 'err: ' + err.message
276 | renderer.send('displayField', json)
277 | } else {
278 | if (Object.prototype.toString.call(table) === '[object Array]') {
279 | const jsonArray = []
280 | for (let i = 0; i < table.length; i++) {
281 | try {
282 | const columns = await queryColumns(connection, table[i])
283 | jsonArray.push(...columns)
284 | } catch (e) {
285 | renderer.send('displayField', e)
286 | break
287 | }
288 | }
289 | renderer.send('displayField', {
290 | code: 200,
291 | data: jsonArray
292 | })
293 | } else {
294 | try {
295 | const tables = await queryColumns(connection, table)
296 | renderer.send('displayField', {
297 | code: 200,
298 | data: tables
299 | })
300 | } catch (e) {
301 | renderer.send('displayField', e)
302 | }
303 | }
304 | }
305 | })
306 | } else {
307 | json.code = -1
308 | json.msg = '请链接数据库再做此操作'
309 | renderer.send('displayField', json)
310 | }
311 | })
312 |
313 | // 调用vscode
314 | ipcMain.on('transferCode', (e, data) => {
315 | exec(`code ${data}`)
316 | })
317 |
318 | // 调用资源管理器
319 | ipcMain.on('transferExplorer', (e, data) => {
320 | exec(`explorer /select,${data}`)
321 | })
322 |
323 | // 打开文件夹选择框
324 | ipcMain.on('openDirectory', (e, data) => {
325 | const json = dialog.showOpenDialog({
326 | title: data.title,
327 | properties: ['openDirectory'],
328 | message: '输入框的信息测试'
329 | })
330 |
331 | json.then(res => {
332 | renderer.send('openDirectory', res.filePaths)
333 | })
334 | })
335 |
336 | // 打开文件选择框
337 | ipcMain.on('openFile', (e, data) => {
338 | const json = dialog.showOpenDialog({
339 | title: data.title,
340 | filters: data.filters,
341 | properties: ['openFile'],
342 | message: '输入框的信息测试'
343 | })
344 |
345 | json.then(res => {
346 | renderer.send('openFile', res.filePaths)
347 | })
348 | })
349 |
350 | // 保存系统设置
351 | ipcMain.on('saveSetting', (e, json) => {
352 | localstorage.setItem('setting', json)
353 | renderer.send('saveSetting', { code: 200 })
354 | })
355 |
356 | ipcMain.on('getSetting', () => {
357 | renderer.send('getSetting', localstorage.getItem('setting'))
358 | })
359 |
360 | ipcMain.on('getKeyValue', () => {
361 | renderer.send('getKeyValue', {
362 | code: 200,
363 | data: localstorage.getItem('keyValue')
364 | })
365 | })
366 |
367 | ipcMain.on('saveKeyValue', (e, json) => {
368 | localstorage.setItem('keyValue', json)
369 | })
370 |
371 | // 保存数据源
372 | ipcMain.on('saveDataSource', (e, json) => {
373 | localstorage.setItem('dataSource', json)
374 | })
375 |
376 | // 取出数据源
377 | ipcMain.on('getDataSource', () => {
378 | renderer.send('getDataSource', localstorage.getItem('dataSource'))
379 | })
380 |
381 | // 查询文档
382 | ipcMain.on('consultYourDocumentation', (e, id, filePath) => {
383 | const file = path.join(__dirname, filePath || '../static/document', id)
384 | fs.access(file, err => {
385 | if (!err) {
386 | fs.readFile(file, 'utf8', (err, data) => {
387 | if (!err) {
388 | renderer.send('consultYourDocumentation', data)
389 | }
390 | })
391 | }
392 | })
393 | })
394 |
395 | // 模板管理 - 新增
396 | ipcMain.on('TemplateManagementAdd', (e, data) => {
397 | const uuid = uuidv4()
398 | const picture = path.join(__dirname, '../static/picture', `${uuid}${path.extname(data.picture)}`)
399 | const ejs = path.join(__dirname, '../static/ejs', `${uuid}.ejs`)
400 | // 进行复制操作
401 | Promise.all([fsExtra.copy(data.picture, picture), fsExtra.copy(data.ejs, ejs)]).then(() => {
402 | let templates = localstorage.getItem('templates')
403 | if (!templates) {
404 | localstorage.setItem('templates', [])
405 | templates = []
406 | }
407 |
408 | templates.push({
409 | id: uuid,
410 | name: data.name,
411 | picture,
412 | ejs
413 | })
414 |
415 | localstorage.setItem('templates', templates)
416 | renderer.send('TemplateManagementAdd:success')
417 | }).catch(err => {
418 | renderer.send('TemplateManagementAdd:error', err)
419 | })
420 | })
421 |
422 | // 模板管理 - 查询
423 | ipcMain.on('TemplateManagementQuery', () => {
424 | renderer.send('TemplateManagementQuery:success', localstorage.getItem('templates'))
425 | })
426 |
427 | // 模板管理 - 设置当前模板
428 | ipcMain.on('setCurrentTemp', (e, data) => {
429 | localstorage.setItem('currentTemp', data)
430 | })
431 |
432 | // 模板管理 - 获取当前模板
433 | ipcMain.on('getCurrentTemp', () => {
434 | renderer.send('getCurrentTemp:success', localstorage.getItem('currentTemp'))
435 | })
436 |
437 | // 模板管理 - 删除模板
438 | ipcMain.on('TemplateManagementDel', (e, data) => {
439 | const temps = localstorage.getItem('templates').filter(v => v.id !== data.id)
440 | localstorage.setItem('templates', temps)
441 | renderer.send('TemplateManagementDel:success')
442 | })
443 |
444 | ipcMain.on('close', () => {
445 | win.close()
446 | })
447 | }
448 |
--------------------------------------------------------------------------------
/src/assets/iconfont/demo.css:
--------------------------------------------------------------------------------
1 | /* Logo 字体 */
2 | @font-face {
3 | font-family: "iconfont logo";
4 | src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
5 | src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
6 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
7 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
8 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
9 | }
10 |
11 | .logo {
12 | font-family: "iconfont logo";
13 | font-size: 160px;
14 | font-style: normal;
15 | -webkit-font-smoothing: antialiased;
16 | -moz-osx-font-smoothing: grayscale;
17 | }
18 |
19 | /* tabs */
20 | .nav-tabs {
21 | position: relative;
22 | }
23 |
24 | .nav-tabs .nav-more {
25 | position: absolute;
26 | right: 0;
27 | bottom: 0;
28 | height: 42px;
29 | line-height: 42px;
30 | color: #666;
31 | }
32 |
33 | #tabs {
34 | border-bottom: 1px solid #eee;
35 | }
36 |
37 | #tabs li {
38 | cursor: pointer;
39 | width: 100px;
40 | height: 40px;
41 | line-height: 40px;
42 | text-align: center;
43 | font-size: 16px;
44 | border-bottom: 2px solid transparent;
45 | position: relative;
46 | z-index: 1;
47 | margin-bottom: -1px;
48 | color: #666;
49 | }
50 |
51 |
52 | #tabs .active {
53 | border-bottom-color: #f00;
54 | color: #222;
55 | }
56 |
57 | .tab-container .content {
58 | display: none;
59 | }
60 |
61 | /* 页面布局 */
62 | .main {
63 | padding: 30px 100px;
64 | width: 960px;
65 | margin: 0 auto;
66 | }
67 |
68 | .main .logo {
69 | color: #333;
70 | text-align: left;
71 | margin-bottom: 30px;
72 | line-height: 1;
73 | height: 110px;
74 | margin-top: -50px;
75 | overflow: hidden;
76 | *zoom: 1;
77 | }
78 |
79 | .main .logo a {
80 | font-size: 160px;
81 | color: #333;
82 | }
83 |
84 | .helps {
85 | margin-top: 40px;
86 | }
87 |
88 | .helps pre {
89 | padding: 20px;
90 | margin: 10px 0;
91 | border: solid 1px #e7e1cd;
92 | background-color: #fffdef;
93 | overflow: auto;
94 | }
95 |
96 | .icon_lists {
97 | width: 100% !important;
98 | overflow: hidden;
99 | *zoom: 1;
100 | }
101 |
102 | .icon_lists li {
103 | width: 100px;
104 | margin-bottom: 10px;
105 | margin-right: 20px;
106 | text-align: center;
107 | list-style: none !important;
108 | cursor: default;
109 | }
110 |
111 | .icon_lists li .code-name {
112 | line-height: 1.2;
113 | }
114 |
115 | .icon_lists .icon {
116 | display: block;
117 | height: 100px;
118 | line-height: 100px;
119 | font-size: 42px;
120 | margin: 10px auto;
121 | color: #333;
122 | -webkit-transition: font-size 0.25s linear, width 0.25s linear;
123 | -moz-transition: font-size 0.25s linear, width 0.25s linear;
124 | transition: font-size 0.25s linear, width 0.25s linear;
125 | }
126 |
127 | .icon_lists .icon:hover {
128 | font-size: 100px;
129 | }
130 |
131 | .icon_lists .svg-icon {
132 | /* 通过设置 font-size 来改变图标大小 */
133 | width: 1em;
134 | /* 图标和文字相邻时,垂直对齐 */
135 | vertical-align: -0.15em;
136 | /* 通过设置 color 来改变 SVG 的颜色/fill */
137 | fill: currentColor;
138 | /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
139 | normalize.css 中也包含这行 */
140 | overflow: hidden;
141 | }
142 |
143 | .icon_lists li .name,
144 | .icon_lists li .code-name {
145 | color: #666;
146 | }
147 |
148 | /* markdown 样式 */
149 | .markdown {
150 | color: #666;
151 | font-size: 14px;
152 | line-height: 1.8;
153 | }
154 |
155 | .highlight {
156 | line-height: 1.5;
157 | }
158 |
159 | .markdown img {
160 | vertical-align: middle;
161 | max-width: 100%;
162 | }
163 |
164 | .markdown h1 {
165 | color: #404040;
166 | font-weight: 500;
167 | line-height: 40px;
168 | margin-bottom: 24px;
169 | }
170 |
171 | .markdown h2,
172 | .markdown h3,
173 | .markdown h4,
174 | .markdown h5,
175 | .markdown h6 {
176 | color: #404040;
177 | margin: 1.6em 0 0.6em 0;
178 | font-weight: 500;
179 | clear: both;
180 | }
181 |
182 | .markdown h1 {
183 | font-size: 28px;
184 | }
185 |
186 | .markdown h2 {
187 | font-size: 22px;
188 | }
189 |
190 | .markdown h3 {
191 | font-size: 16px;
192 | }
193 |
194 | .markdown h4 {
195 | font-size: 14px;
196 | }
197 |
198 | .markdown h5 {
199 | font-size: 12px;
200 | }
201 |
202 | .markdown h6 {
203 | font-size: 12px;
204 | }
205 |
206 | .markdown hr {
207 | height: 1px;
208 | border: 0;
209 | background: #e9e9e9;
210 | margin: 16px 0;
211 | clear: both;
212 | }
213 |
214 | .markdown p {
215 | margin: 1em 0;
216 | }
217 |
218 | .markdown>p,
219 | .markdown>blockquote,
220 | .markdown>.highlight,
221 | .markdown>ol,
222 | .markdown>ul {
223 | width: 80%;
224 | }
225 |
226 | .markdown ul>li {
227 | list-style: circle;
228 | }
229 |
230 | .markdown>ul li,
231 | .markdown blockquote ul>li {
232 | margin-left: 20px;
233 | padding-left: 4px;
234 | }
235 |
236 | .markdown>ul li p,
237 | .markdown>ol li p {
238 | margin: 0.6em 0;
239 | }
240 |
241 | .markdown ol>li {
242 | list-style: decimal;
243 | }
244 |
245 | .markdown>ol li,
246 | .markdown blockquote ol>li {
247 | margin-left: 20px;
248 | padding-left: 4px;
249 | }
250 |
251 | .markdown code {
252 | margin: 0 3px;
253 | padding: 0 5px;
254 | background: #eee;
255 | border-radius: 3px;
256 | }
257 |
258 | .markdown strong,
259 | .markdown b {
260 | font-weight: 600;
261 | }
262 |
263 | .markdown>table {
264 | border-collapse: collapse;
265 | border-spacing: 0px;
266 | empty-cells: show;
267 | border: 1px solid #e9e9e9;
268 | width: 95%;
269 | margin-bottom: 24px;
270 | }
271 |
272 | .markdown>table th {
273 | white-space: nowrap;
274 | color: #333;
275 | font-weight: 600;
276 | }
277 |
278 | .markdown>table th,
279 | .markdown>table td {
280 | border: 1px solid #e9e9e9;
281 | padding: 8px 16px;
282 | text-align: left;
283 | }
284 |
285 | .markdown>table th {
286 | background: #F7F7F7;
287 | }
288 |
289 | .markdown blockquote {
290 | font-size: 90%;
291 | color: #999;
292 | border-left: 4px solid #e9e9e9;
293 | padding-left: 0.8em;
294 | margin: 1em 0;
295 | }
296 |
297 | .markdown blockquote p {
298 | margin: 0;
299 | }
300 |
301 | .markdown .anchor {
302 | opacity: 0;
303 | transition: opacity 0.3s ease;
304 | margin-left: 8px;
305 | }
306 |
307 | .markdown .waiting {
308 | color: #ccc;
309 | }
310 |
311 | .markdown h1:hover .anchor,
312 | .markdown h2:hover .anchor,
313 | .markdown h3:hover .anchor,
314 | .markdown h4:hover .anchor,
315 | .markdown h5:hover .anchor,
316 | .markdown h6:hover .anchor {
317 | opacity: 1;
318 | display: inline-block;
319 | }
320 |
321 | .markdown>br,
322 | .markdown>p>br {
323 | clear: both;
324 | }
325 |
326 |
327 | .hljs {
328 | display: block;
329 | background: white;
330 | padding: 0.5em;
331 | color: #333333;
332 | overflow-x: auto;
333 | }
334 |
335 | .hljs-comment,
336 | .hljs-meta {
337 | color: #969896;
338 | }
339 |
340 | .hljs-string,
341 | .hljs-variable,
342 | .hljs-template-variable,
343 | .hljs-strong,
344 | .hljs-emphasis,
345 | .hljs-quote {
346 | color: #df5000;
347 | }
348 |
349 | .hljs-keyword,
350 | .hljs-selector-tag,
351 | .hljs-type {
352 | color: #a71d5d;
353 | }
354 |
355 | .hljs-literal,
356 | .hljs-symbol,
357 | .hljs-bullet,
358 | .hljs-attribute {
359 | color: #0086b3;
360 | }
361 |
362 | .hljs-section,
363 | .hljs-name {
364 | color: #63a35c;
365 | }
366 |
367 | .hljs-tag {
368 | color: #333333;
369 | }
370 |
371 | .hljs-title,
372 | .hljs-attr,
373 | .hljs-selector-id,
374 | .hljs-selector-class,
375 | .hljs-selector-attr,
376 | .hljs-selector-pseudo {
377 | color: #795da3;
378 | }
379 |
380 | .hljs-addition {
381 | color: #55a532;
382 | background-color: #eaffea;
383 | }
384 |
385 | .hljs-deletion {
386 | color: #bd2c00;
387 | background-color: #ffecec;
388 | }
389 |
390 | .hljs-link {
391 | text-decoration: underline;
392 | }
393 |
394 | /* 代码高亮 */
395 | /* PrismJS 1.15.0
396 | https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
397 | /**
398 | * prism.js default theme for JavaScript, CSS and HTML
399 | * Based on dabblet (http://dabblet.com)
400 | * @author Lea Verou
401 | */
402 | code[class*="language-"],
403 | pre[class*="language-"] {
404 | color: black;
405 | background: none;
406 | text-shadow: 0 1px white;
407 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
408 | text-align: left;
409 | white-space: pre;
410 | word-spacing: normal;
411 | word-break: normal;
412 | word-wrap: normal;
413 | line-height: 1.5;
414 |
415 | -moz-tab-size: 4;
416 | -o-tab-size: 4;
417 | tab-size: 4;
418 |
419 | -webkit-hyphens: none;
420 | -moz-hyphens: none;
421 | -ms-hyphens: none;
422 | hyphens: none;
423 | }
424 |
425 | pre[class*="language-"]::-moz-selection,
426 | pre[class*="language-"] ::-moz-selection,
427 | code[class*="language-"]::-moz-selection,
428 | code[class*="language-"] ::-moz-selection {
429 | text-shadow: none;
430 | background: #b3d4fc;
431 | }
432 |
433 | pre[class*="language-"]::selection,
434 | pre[class*="language-"] ::selection,
435 | code[class*="language-"]::selection,
436 | code[class*="language-"] ::selection {
437 | text-shadow: none;
438 | background: #b3d4fc;
439 | }
440 |
441 | @media print {
442 |
443 | code[class*="language-"],
444 | pre[class*="language-"] {
445 | text-shadow: none;
446 | }
447 | }
448 |
449 | /* Code blocks */
450 | pre[class*="language-"] {
451 | padding: 1em;
452 | margin: .5em 0;
453 | overflow: auto;
454 | }
455 |
456 | :not(pre)>code[class*="language-"],
457 | pre[class*="language-"] {
458 | background: #f5f2f0;
459 | }
460 |
461 | /* Inline code */
462 | :not(pre)>code[class*="language-"] {
463 | padding: .1em;
464 | border-radius: .3em;
465 | white-space: normal;
466 | }
467 |
468 | .token.comment,
469 | .token.prolog,
470 | .token.doctype,
471 | .token.cdata {
472 | color: slategray;
473 | }
474 |
475 | .token.punctuation {
476 | color: #999;
477 | }
478 |
479 | .namespace {
480 | opacity: .7;
481 | }
482 |
483 | .token.property,
484 | .token.tag,
485 | .token.boolean,
486 | .token.number,
487 | .token.constant,
488 | .token.symbol,
489 | .token.deleted {
490 | color: #905;
491 | }
492 |
493 | .token.selector,
494 | .token.attr-name,
495 | .token.string,
496 | .token.char,
497 | .token.builtin,
498 | .token.inserted {
499 | color: #690;
500 | }
501 |
502 | .token.operator,
503 | .token.entity,
504 | .token.url,
505 | .language-css .token.string,
506 | .style .token.string {
507 | color: #9a6e3a;
508 | background: hsla(0, 0%, 100%, .5);
509 | }
510 |
511 | .token.atrule,
512 | .token.attr-value,
513 | .token.keyword {
514 | color: #07a;
515 | }
516 |
517 | .token.function,
518 | .token.class-name {
519 | color: #DD4A68;
520 | }
521 |
522 | .token.regex,
523 | .token.important,
524 | .token.variable {
525 | color: #e90;
526 | }
527 |
528 | .token.important,
529 | .token.bold {
530 | font-weight: bold;
531 | }
532 |
533 | .token.italic {
534 | font-style: italic;
535 | }
536 |
537 | .token.entity {
538 | cursor: help;
539 | }
540 |
--------------------------------------------------------------------------------
/src/assets/iconfont/demo_index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IconFont Demo
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | - Unicode
22 | - Font class
23 | - Symbol
24 |
25 |
26 |
查看项目
27 |
28 |
29 |
30 |
31 |
32 |
33 | -
34 |
35 |
关 闭
36 | 
37 |
38 |
39 |
40 |
41 |
Unicode 引用
42 |
43 |
44 |
Unicode 是字体在网页端最原始的应用方式,特点是:
45 |
46 | - 兼容性最好,支持 IE6+,及所有现代浏览器。
47 | - 支持按字体的方式去动态调整图标大小,颜色等等。
48 | - 但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。
49 |
50 |
51 | 注意:新版 iconfont 支持多色图标,这些多色图标在 Unicode 模式下将不能使用,如果有需求建议使用symbol 的引用方式
52 |
53 |
Unicode 使用步骤如下:
54 |
第一步:拷贝项目下面生成的 @font-face
55 |
@font-face {
57 | font-family: 'iconfont';
58 | src: url('iconfont.eot');
59 | src: url('iconfont.eot?#iefix') format('embedded-opentype'),
60 | url('iconfont.woff2') format('woff2'),
61 | url('iconfont.woff') format('woff'),
62 | url('iconfont.ttf') format('truetype'),
63 | url('iconfont.svg#iconfont') format('svg');
64 | }
65 |
66 |
第二步:定义使用 iconfont 的样式
67 |
.iconfont {
69 | font-family: "iconfont" !important;
70 | font-size: 16px;
71 | font-style: normal;
72 | -webkit-font-smoothing: antialiased;
73 | -moz-osx-font-smoothing: grayscale;
74 | }
75 |
76 |
第三步:挑选相应图标并获取字体编码,应用于页面
77 |
78 | <span class="iconfont">3</span>
80 |
81 |
82 | "iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。
83 |
84 |
85 |
86 |
87 |
88 |
89 | -
90 |
91 |
92 | 关 闭
93 |
94 | .icon-guanbi
95 |
96 |
97 |
98 |
99 |
100 |
font-class 引用
101 |
102 |
103 |
font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。
104 |
与 Unicode 使用方式相比,具有如下特点:
105 |
106 | - 兼容性良好,支持 IE8+,及所有现代浏览器。
107 | - 相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。
108 | - 因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。
109 | - 不过因为本质上还是使用的字体,所以多色图标还是不支持的。
110 |
111 |
使用步骤如下:
112 |
第一步:引入项目下面生成的 fontclass 代码:
113 |
<link rel="stylesheet" href="./iconfont.css">
114 |
115 |
第二步:挑选相应图标并获取类名,应用于页面:
116 |
<span class="iconfont icon-xxx"></span>
117 |
118 |
119 | "
120 | iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。
121 |
122 |
123 |
124 |
125 |
126 |
127 | -
128 |
131 |
关 闭
132 | #icon-guanbi
133 |
134 |
135 |
136 |
137 |
Symbol 引用
138 |
139 |
140 |
这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇文章
141 | 这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:
142 |
143 | - 支持多色图标了,不再受单色限制。
144 | - 通过一些技巧,支持像字体那样,通过
font-size
, color
来调整样式。
145 | - 兼容性较差,支持 IE9+,及现代浏览器。
146 | - 浏览器渲染 SVG 的性能一般,还不如 png。
147 |
148 |
使用步骤如下:
149 |
第一步:引入项目下面生成的 symbol 代码:
150 |
<script src="./iconfont.js"></script>
151 |
152 |
第二步:加入通用 CSS 代码(引入一次就行):
153 |
<style>
154 | .icon {
155 | width: 1em;
156 | height: 1em;
157 | vertical-align: -0.15em;
158 | fill: currentColor;
159 | overflow: hidden;
160 | }
161 | </style>
162 |
163 |
第三步:挑选相应图标并获取类名,应用于页面:
164 |
<svg class="icon" aria-hidden="true">
165 | <use xlink:href="#icon-xxx"></use>
166 | </svg>
167 |
168 |
169 |
170 |
171 |
172 |
173 |
192 |
193 |
194 |
--------------------------------------------------------------------------------
/src/assets/iconfont/iconfont.css:
--------------------------------------------------------------------------------
1 | @font-face {font-family: "iconfont";
2 | src: url('iconfont.eot?t=1603964335884'); /* IE9 */
3 | src: url('iconfont.eot?t=1603964335884#iefix') format('embedded-opentype'), /* IE6-IE8 */
4 | url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAK0AAsAAAAABlwAAAJpAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCCcApocwE2AiQDCAsGAAQgBYRtBzAbmQXILjF2bRABpltYSC4tKDJ5CgNKHhE87Uebt7tnqtWzaBJMQ7nQIEEikTopkPFM/vu/pimgMLV5viyrCBX6g/wDzuUKz8M2ZzajSchNuPUEzxCgZghRZAYbcIGuMKhvOmgT5xonJdkQSitstp1XUQW2Yf03eVH5ewMup78CCmQeUG5zDFwDMMEA98IoslLJG8YueIGPCTQa1ZQ7nm8PUFXYqwLx3rE0qBbCisJy9UJtw8EiPqtRnz6m8Sn6fvyzGfUkNZndcPZyZsLwZ05BvtptQIgQ0PEaZCwDhbhqTJ8oCMYuaEwXTYJj1QY/W1WBVRzVJNhfZ1c3g2EofiaJJ33U6gRK4h4CetOkH0JqaX14I85BueKZH0ce2pckJS9h1dmYePRHDR9+uGzq08OPa/+Df7JxfOaIaTzcXGAfoDJ/zcoh2F2r/fuozf/1TQV837xEwcpimBfU780T/BXJwKFiyGxLKpqk0ZsMTVqZ0KgRFdjf6W+qvucW8qFez41464xkyOpNk4W1jBpNtlGr3h4aLVkcb9KFFURpwKI7QGj3jqTVN2TtfsjC+kWNXv+o1R4ZjW6CC5vMxpt6TJqQibqFDhOFyrVJPa7dkZX5GudlEedEnDox7K2ul3MLComX2JLqVl9UhUqOApyD58j3I4zlyCVD2rYq8aCz9rLpTW1DCKDuCCMaQUxId4MchkhIBZNFvfL5HWLJ+DTc0VYXPiEs5UyPetq6A8iFOhzU9iivpM4sfUIoSGGRAJqDecTni6C4eZ6LGESbPSEZG+g449RQdXt7bfADRawL25DCmZXVvsq0UHcAAAA=') format('woff2'),
5 | url('iconfont.woff?t=1603964335884') format('woff'),
6 | url('iconfont.ttf?t=1603964335884') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
7 | url('iconfont.svg?t=1603964335884#iconfont') format('svg'); /* iOS 4.1- */
8 | }
9 |
10 | .iconfont {
11 | font-family: "iconfont" !important;
12 | font-size: 16px;
13 | font-style: normal;
14 | -webkit-font-smoothing: antialiased;
15 | -moz-osx-font-smoothing: grayscale;
16 | }
17 |
18 | .icon-guanbi:before {
19 | content: "\e645";
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/src/assets/iconfont/iconfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chendonming/easycode-javascript/656b7c777bc7e045f45b0d3365f3dced98b48f6d/src/assets/iconfont/iconfont.eot
--------------------------------------------------------------------------------
/src/assets/iconfont/iconfont.js:
--------------------------------------------------------------------------------
1 | !function(e){var t,n,o,i,a,d,c='',l=(l=document.getElementsByTagName("script"))[l.length-1].getAttribute("data-injectcss");if(l&&!e.__iconfont__svg__cssinject__){e.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(e){console&&console.log(e)}}function s(){a||(a=!0,o())}t=function(){var e,t,n,o;(o=document.createElement("div")).innerHTML=c,c=null,(n=o.getElementsByTagName("svg")[0])&&(n.setAttribute("aria-hidden","true"),n.style.position="absolute",n.style.width=0,n.style.height=0,n.style.overflow="hidden",e=n,(t=document.body).firstChild?(o=e,(n=t.firstChild).parentNode.insertBefore(o,n)):t.appendChild(e))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(t,0):(n=function(){document.removeEventListener("DOMContentLoaded",n,!1),t()},document.addEventListener("DOMContentLoaded",n,!1)):document.attachEvent&&(o=t,i=e.document,a=!1,(d=function(){try{i.documentElement.doScroll("left")}catch(e){return void setTimeout(d,50)}s()})(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,s())})}(window);
--------------------------------------------------------------------------------
/src/assets/iconfont/iconfont.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "2166494",
3 | "name": "EasyCode",
4 | "font_family": "iconfont",
5 | "css_prefix_text": "icon-",
6 | "description": "",
7 | "glyphs": [
8 | {
9 | "icon_id": "9255860",
10 | "name": "关 闭",
11 | "font_class": "guanbi",
12 | "unicode": "e645",
13 | "unicode_decimal": 58949
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/src/assets/iconfont/iconfont.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
30 |
--------------------------------------------------------------------------------
/src/assets/iconfont/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chendonming/easycode-javascript/656b7c777bc7e045f45b0d3365f3dced98b48f6d/src/assets/iconfont/iconfont.ttf
--------------------------------------------------------------------------------
/src/assets/iconfont/iconfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chendonming/easycode-javascript/656b7c777bc7e045f45b0d3365f3dced98b48f6d/src/assets/iconfont/iconfont.woff
--------------------------------------------------------------------------------
/src/assets/iconfont/iconfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chendonming/easycode-javascript/656b7c777bc7e045f45b0d3365f3dced98b48f6d/src/assets/iconfont/iconfont.woff2
--------------------------------------------------------------------------------
/src/assets/img/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chendonming/easycode-javascript/656b7c777bc7e045f45b0d3365f3dced98b48f6d/src/assets/img/1.png
--------------------------------------------------------------------------------
/src/assets/img/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chendonming/easycode-javascript/656b7c777bc7e045f45b0d3365f3dced98b48f6d/src/assets/img/2.png
--------------------------------------------------------------------------------
/src/assets/img/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chendonming/easycode-javascript/656b7c777bc7e045f45b0d3365f3dced98b48f6d/src/assets/img/3.png
--------------------------------------------------------------------------------
/src/assets/img/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chendonming/easycode-javascript/656b7c777bc7e045f45b0d3365f3dced98b48f6d/src/assets/img/4.png
--------------------------------------------------------------------------------
/src/assets/img/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chendonming/easycode-javascript/656b7c777bc7e045f45b0d3365f3dced98b48f6d/src/assets/img/5.png
--------------------------------------------------------------------------------
/src/assets/img/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chendonming/easycode-javascript/656b7c777bc7e045f45b0d3365f3dced98b48f6d/src/assets/img/6.png
--------------------------------------------------------------------------------
/src/assets/img/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chendonming/easycode-javascript/656b7c777bc7e045f45b0d3365f3dced98b48f6d/src/assets/img/7.png
--------------------------------------------------------------------------------
/src/assets/img/8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chendonming/easycode-javascript/656b7c777bc7e045f45b0d3365f3dced98b48f6d/src/assets/img/8.png
--------------------------------------------------------------------------------
/src/assets/img/9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chendonming/easycode-javascript/656b7c777bc7e045f45b0d3365f3dced98b48f6d/src/assets/img/9.png
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chendonming/easycode-javascript/656b7c777bc7e045f45b0d3365f3dced98b48f6d/src/assets/logo.png
--------------------------------------------------------------------------------
/src/background.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import { app, protocol, BrowserWindow, Menu } from 'electron'
4 | import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
5 | import api from './api'
6 |
7 | // import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
8 | const isDevelopment = process.env.NODE_ENV !== 'production'
9 |
10 | // Keep a global reference of the window object, if you don't, the window will
11 | // be closed automatically when the JavaScript object is garbage collected.
12 | // eslint-disable-next-line no-unused-vars
13 | let win
14 |
15 | // Scheme must be registered before the app is ready
16 | protocol.registerSchemesAsPrivileged([
17 | {
18 | scheme: 'app',
19 | privileges: {
20 | secure: true,
21 | standard: true
22 | }
23 | }
24 | ])
25 |
26 | function createWindow () {
27 | // Create the browser window.
28 | win = new BrowserWindow({
29 | width: 1320,
30 | height: 730,
31 | webPreferences: {
32 | // Use pluginOptions.nodeIntegration, leave this alone
33 | // See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
34 | nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
35 | webSecurity: false
36 | },
37 | show: false,
38 | frame: false
39 | })
40 |
41 | //= ==========自定义file:///协议的解析=======================
42 | protocol.interceptFileProtocol('file', (req, callback) => {
43 | const url = req.url.substr(8)
44 | callback(decodeURI(url))
45 | }, (error) => {
46 | if (error) {
47 | console.error('Failed to register protocol')
48 | }
49 | })
50 |
51 | if (process.env.WEBPACK_DEV_SERVER_URL) {
52 | // Load the url of the dev server if in development mode
53 | win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
54 | if (!process.env.IS_TEST) win.webContents.openDevTools()
55 | } else {
56 | createProtocol('app')
57 | // Load the index.html when not in development
58 | win.loadURL('app://./index.html')
59 | }
60 |
61 | win.on('closed', () => {
62 | win = null
63 | })
64 |
65 | win.on('ready-to-show', () => {
66 | win.show()
67 | })
68 | }
69 |
70 | // Quit when all windows are closed.
71 | app.on('window-all-closed', () => {
72 | // On macOS it is common for applications and their menu bar
73 | // to stay active until the user quits explicitly with Cmd + Q
74 | if (process.platform !== 'darwin') {
75 | app.quit()
76 | }
77 | })
78 |
79 | app.on('activate', () => {
80 | // On macOS it's common to re-create a window in the app when the
81 | // dock icon is clicked and there are no other windows open.
82 | if (win === null) {
83 | createWindow()
84 | }
85 | })
86 |
87 | // This method will be called when Electron has finished
88 | // initialization and is ready to create browser windows.
89 | // Some APIs can only be used after this event occurs.
90 | app.on('ready', async () => {
91 | if (isDevelopment && !process.env.IS_TEST) {
92 | // Install Vue Devtools
93 | // try {
94 | // await installExtension(VUEJS_DEVTOOLS)
95 | // } catch (e) {
96 | // console.error('Vue Devtools failed to install:', e.toString())
97 | // }
98 | }
99 | const template = [
100 | {
101 | label: '&Connection',
102 | submenu: [
103 | {
104 | label: '连接数据库',
105 | accelerator: 'ctrl+n',
106 | click () {
107 | win.webContents.send('connection')
108 | }
109 | },
110 | {
111 | label: '&Settings',
112 | accelerator: 'ctrl+alt+s',
113 | click () {
114 | win.webContents.send('settings')
115 | }
116 | }
117 | ]
118 | },
119 | {
120 | label: '&Authority',
121 | submenu: [
122 | {
123 | label: '创建账号',
124 | click () {
125 | win.webContents.send('openPermissions')
126 | }
127 | },
128 | {
129 | label: '创建便签',
130 | click () {
131 | let newWin = new BrowserWindow({
132 | webPreferences: {
133 | // Use pluginOptions.nodeIntegration, leave this alone
134 | // See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
135 | nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION
136 | },
137 | width: 200,
138 | height: 300,
139 | frame: false,
140 | x: 1600,
141 | y: 100
142 | })
143 |
144 | if (process.env.WEBPACK_DEV_SERVER_URL) {
145 | // Load the url of the dev server if in development mode
146 | newWin.loadURL(process.env.WEBPACK_DEV_SERVER_URL + '#/Note')
147 | } else {
148 | createProtocol('app')
149 | // Load the index.html when not in development
150 | newWin.loadURL('app://./index.html/#/Note')
151 | }
152 |
153 | newWin.on('closed', () => {
154 | newWin = null
155 | })
156 |
157 | newWin.on('ready-to-show', () => {
158 | newWin.show()
159 | })
160 | }
161 | }
162 | ]
163 | },
164 | {
165 | label: '&Window',
166 | submenu: [{ role: 'minimize' }, { role: 'zoom' }, { role: 'close' }]
167 | },
168 | {
169 | label: '&File',
170 | submenu: [{ role: 'quit' }]
171 | },
172 | {
173 | label: '&About',
174 | submenu: [
175 | {
176 | label: '前端CRUD',
177 | submenu: [
178 | {
179 | label: '使用手册',
180 | click () {
181 | win.webContents.send('about', {
182 | id: 'frontCRUD.md',
183 | title: '前端CRUD手册'
184 | })
185 | }
186 | }
187 | ]
188 | },
189 | {
190 | role: 'about'
191 | }
192 | ]
193 | }
194 | ]
195 |
196 | const menu = Menu.buildFromTemplate(template)
197 | Menu.setApplicationMenu(menu)
198 |
199 | createWindow()
200 | api(win, win.webContents)
201 | })
202 |
203 | // Exit cleanly on request from parent process in development mode.
204 | if (isDevelopment) {
205 | if (process.platform === 'win32') {
206 | process.on('message', data => {
207 | if (data === 'graceful-exit') {
208 | app.quit()
209 | }
210 | })
211 | } else {
212 | process.on('SIGTERM', () => {
213 | app.quit()
214 | })
215 | }
216 | }
217 |
--------------------------------------------------------------------------------
/src/components/DataSource.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
18 |
19 |
20 |
21 |
27 |
33 |
34 |
35 |
36 | 下一步
37 | 设置属性
38 | 隐藏没有注释的字段
39 |
40 |
41 |
42 |
46 |
47 |
48 |
49 |
50 |
51 | 添加
52 | 删除
53 |
54 | 记住列表数据方便下次填写数据
57 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
199 |
200 |
203 |
--------------------------------------------------------------------------------
/src/components/FieldTable.vue:
--------------------------------------------------------------------------------
1 |
2 |
11 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | {{camelCase(scope.row.Field)}}
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
39 |
45 |
46 |
47 |
48 |
49 |
50 | 反选新增表单
55 |
56 | 反选搜索表单
61 |
62 | 反选查询表单
67 |
68 | 反选必填项
73 |
74 |
75 |
76 |
77 | 新增表单
78 | 搜索表单
79 | 查询表单
80 | 必填
81 |
82 |
83 |
84 |
85 |
86 |
87 |
176 |
177 |
180 |
--------------------------------------------------------------------------------
/src/components/Generate.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ errorMessage }}
5 |
6 |
7 |
8 | 生成文件
9 | 预览代码
10 | 用Vscode打开
11 | 在资源管理器中打开
12 | 上一步
13 |
14 |
复制代码
15 |
16 |
17 |
18 |
19 |
20 |
142 |
143 |
173 |
--------------------------------------------------------------------------------
/src/components/ViewFiles.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
68 |
69 |
74 |
--------------------------------------------------------------------------------
/src/localstorage.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | /**
4 | * 读取本地配置
5 | */
6 | const fs = require('fs')
7 | const path = require('path')
8 | /**
9 | * 判断配置文件是否存在
10 | */
11 | function isExit () {
12 | let success = true
13 | if (!(localConfig.config && typeof localConfig.config === 'object')) {
14 | success = initConfig()
15 | }
16 | return success
17 | }
18 | /**
19 | * 初始化config
20 | */
21 | function initConfig () {
22 | try {
23 | const config = readConfig()
24 | if (config) {
25 | localConfig.config = JSON.parse(config)
26 | return true
27 | }
28 | const defaultConfig = {}
29 | const content = JSON.stringify(defaultConfig)
30 | fs.writeFileSync(localConfig.configUrl, content)
31 | localConfig.config = defaultConfig
32 | return true
33 | } catch (e) {
34 | return false
35 | }
36 | }
37 | /**
38 | * 读取文件
39 | */
40 | function readConfig () {
41 | try {
42 | return fs.readFileSync(localConfig.configUrl)
43 | } catch (error) {
44 | return false
45 | }
46 | }
47 | /**
48 | * 写入文件
49 | */
50 | function writeConfig (value) {
51 | try {
52 | const content = JSON.stringify(value)
53 | fs.writeFileSync(localConfig.configUrl, content)
54 | return true
55 | } catch (e) {
56 | return false
57 | }
58 | }
59 |
60 | const localConfig = {
61 | config: null,
62 | configUrl: path.join(__dirname, '../static/localConfig.json'),
63 | setStoragePath: (path) => {
64 | localConfig.configUrl = path
65 | },
66 | getStoragePath: () => {
67 | return localConfig.configUrl
68 | },
69 | getItem: (key) => {
70 | const success = isExit()
71 | if (success) {
72 | const result = localConfig.config[key]
73 | return result || ''
74 | }
75 | return null
76 | },
77 | setItem: (key, value) => {
78 | const success = isExit()
79 | if (success) {
80 | const config = Object.assign({}, localConfig.config)
81 | config[key] = value
82 | const suc = writeConfig(config)
83 | if (suc) {
84 | localConfig.config = config
85 | return true
86 | }
87 | }
88 | return false
89 | },
90 | getAll: () => {
91 | const success = isExit()
92 | if (success) {
93 | return localConfig.config
94 | }
95 | return null
96 | },
97 | removeItem: (key) => {
98 | const value = localConfig.getItem(key)
99 | if (value) {
100 | const config = Object.assign({}, localConfig.config)
101 | delete config[key]
102 | const suc = writeConfig(config)
103 | if (suc) {
104 | localConfig.config = config
105 | return true
106 | }
107 | }
108 | return false
109 | },
110 | clear: () => {
111 | const success = isExit()
112 | if (success) {
113 | const suc = writeConfig({})
114 | if (suc) {
115 | localConfig.config = {}
116 | return true
117 | }
118 | }
119 | return false
120 | }
121 | }
122 |
123 | module.exports = localConfig
124 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import router from './router'
4 | import store from './store'
5 | import ElementUI from 'element-ui'
6 | import '@/style/element-variables.scss'
7 | import '@/style/reset.css'
8 | import '@/assets/iconfont/iconfont.css'
9 | import '@/style/main.css'
10 |
11 | Vue.config.productionTip = false
12 | Vue.use(ElementUI, {
13 | size: 'small'
14 | })
15 |
16 | new Vue({
17 | router,
18 | store,
19 | render: h => h(App)
20 | }).$mount('#app')
21 |
--------------------------------------------------------------------------------
/src/mix/fileData.js:
--------------------------------------------------------------------------------
1 | export default {
2 | computed: {
3 | fileList: {
4 | get () { return this.$store.state.fileList },
5 | set (val) { this.$store.commit('setFileList', val) }
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/mix/tableData.js:
--------------------------------------------------------------------------------
1 | export default {
2 | computed: {
3 | tableDataHide: {
4 | get () { return this.$store.state.tableDataHide },
5 | set (val) { this.$store.commit('setTableDataHide', val) }
6 | },
7 | tableData: {
8 | get () { return this.$store.state.tableData },
9 | set (val) { this.$store.commit('setTableData', val) }
10 | },
11 | rememberKey: {
12 | get () { return this.$store.state.rememberKey },
13 | set (val) { this.$store.commit('setRememberKey', val) }
14 | },
15 | kdata: {
16 | get () { return this.$store.state.kdata },
17 | set (val) { this.$store.commit('setKdata', val) }
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueRouter from 'vue-router'
3 | import Home from '../views/Home.vue'
4 |
5 | Vue.use(VueRouter)
6 |
7 | const routes = [
8 | {
9 | path: '/',
10 | component: Home,
11 | children: [
12 | {
13 | path: '/BuildCode',
14 | component: () => import('@/views/BuildCode.vue')
15 | },
16 | {
17 | path: '/TemplateManagement',
18 | component: () => import('@/views/TemplateManagement.vue')
19 | }
20 | ]
21 | },
22 | {
23 | path: '/DocumentText',
24 | component: () => import('@/views/DocumentText')
25 | }
26 | ]
27 |
28 | const router = new VueRouter({
29 | routes
30 | })
31 |
32 | export default router
33 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 |
4 | Vue.use(Vuex)
5 |
6 | export default new Vuex.Store({
7 | state: {
8 | // 是否连接数据库
9 | connection: false,
10 | primaryColor: '#409eff',
11 | successColor: '#67c23a',
12 | warningColor: '#e6a23c',
13 | dangerColor: '#f56c6c',
14 | infoColor: '#909399',
15 | title: 'EasyCode',
16 |
17 | tableDataHide: null,
18 | tableData: [],
19 | localFile: '',
20 | fileList: [],
21 | rememberKey: true,
22 | kdata: [],
23 |
24 | // 当前使用的模板<模板管理>
25 | currentTemplate: null
26 | },
27 | mutations: {
28 | setCurrentTemplate (state, temp) {
29 | state.currentTemplate = temp
30 | },
31 | setKdata (state, data) {
32 | state.kdata = data
33 | },
34 | setRememberKey (state, key) {
35 | state.rememberKey = key
36 | },
37 | setFileList (state, fileList) {
38 | state.fileList = fileList
39 | },
40 | setLocalFile (state, localFile) {
41 | state.localFile = localFile
42 | },
43 | setTableData (state, tableData) {
44 | state.tableData = tableData.map(v => {
45 | if (!v.component) {
46 | v.component = 'input'
47 | }
48 | return v
49 | })
50 | },
51 | setTableDataHide (state, tableDataHide) {
52 | state.tableDataHide = tableDataHide
53 | },
54 | setTitle (state, title) {
55 | state.title = title
56 | },
57 | setPrimaryColor (state, color) {
58 | state.primaryColor = color
59 | },
60 | setSuccessColor (state, color) {
61 | state.successColor = color
62 | },
63 | setWarningColor (state, color) {
64 | state.warningColor = color
65 | },
66 | setDangerColor (state, color) {
67 | state.dangerColor = color
68 | },
69 | setInfoColor (state, color) {
70 | state.infoColor = color
71 | },
72 | setConnection (state, bool) {
73 | state.connection = bool
74 | }
75 | },
76 | getters: {
77 | connection: state => state.connection,
78 | primaryColor: state => state.primaryColor,
79 | successColor: state => state.successColor,
80 | warningColor: state => state.warningColor,
81 | dangerColor: state => state.dangerColor,
82 | infoColor: state => state.infoColor,
83 | title: state => state.title,
84 | tableDataHide: state => state.tableDataHide,
85 | tableData: state => state.tableData
86 | },
87 | actions: {},
88 | modules: {}
89 | })
90 |
--------------------------------------------------------------------------------
/src/style/element-variables.scss:
--------------------------------------------------------------------------------
1 | :root {
2 | --primary: teal;
3 | --success: #67c23a;
4 | --warning: #e6a23c;
5 | --danger: #f56c6c;
6 | --info: #909399;
7 | }
8 |
9 |
10 | /* 改变主题色变量 */
11 | $--color-primary: teal;
12 |
13 | $--color-success: #67c23a;
14 |
15 | $--color-warning: #e6a23c;
16 |
17 | $--color-danger: #f56c6c;
18 |
19 | $--color-info: #909399;
20 |
21 |
22 | /* 改变 icon 字体路径变量,必需 */
23 | $--font-path: '~element-ui/lib/theme-chalk/fonts';
24 |
25 | @import "~element-ui/packages/theme-chalk/src/index";
26 |
--------------------------------------------------------------------------------
/src/style/main.css:
--------------------------------------------------------------------------------
1 | .df {
2 | display: flex;
3 | }
4 |
5 | .tac {
6 | text-align: center;
7 | }
8 |
9 | .tal {
10 | text-align: left;
11 | }
12 |
13 | .center {
14 | justify-content: center;
15 | }
16 |
17 | .vcenter {
18 | align-items: center;
19 | }
20 |
21 | .p10 {
22 | padding: 10px;
23 | }
24 |
25 | .pt10 {
26 | padding-top: 10px;
27 | }
28 |
29 | .ptb10 {
30 | padding: 10px 0;
31 | }
32 |
33 | .lr10 {
34 | padding: 0 10px;
35 | }
36 |
--------------------------------------------------------------------------------
/src/style/reset.css:
--------------------------------------------------------------------------------
1 | /* http://meyerweb.com/eric/tools/css/reset/
2 | v2.0 | 20110126
3 | License: none (public domain)
4 | */
5 |
6 | html, body, div, span, applet, object, iframe,
7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
8 | a, abbr, acronym, address, big, cite, code,
9 | del, dfn, em, img, ins, kbd, q, s, samp,
10 | small, strike, strong, sub, sup, tt, var,
11 | b, u, i, center,
12 | dl, dt, dd, ol, ul, li,
13 | fieldset, form, label, legend,
14 | table, caption, tbody, tfoot, thead, tr, th, td,
15 | article, aside, canvas, details, embed,
16 | figure, figcaption, footer, header, hgroup,
17 | menu, nav, output, ruby, section, summary,
18 | time, mark, audio, video {
19 | margin: 0;
20 | padding: 0;
21 | border: 0;
22 | font-size: 100%;
23 | font: inherit;
24 | vertical-align: baseline;
25 | }
26 |
27 | /* HTML5 display-role reset for older browsers */
28 | article, aside, details, figcaption, figure,
29 | footer, header, hgroup, menu, nav, section {
30 | display: block;
31 | }
32 |
33 | body {
34 | line-height: 1;
35 | }
36 |
37 | ol, ul {
38 | list-style: none;
39 | }
40 |
41 | blockquote, q {
42 | quotes: none;
43 | }
44 |
45 | blockquote:before, blockquote:after,
46 | q:before, q:after {
47 | content: '';
48 | content: none;
49 | }
50 |
51 | table {
52 | border-collapse: collapse;
53 | border-spacing: 0;
54 | }
55 |
56 | .el-form-item__content {
57 | text-align: left;
58 | }
59 |
60 | .atag {
61 | color: #409EFF;
62 | cursor: pointer;
63 | }
64 |
65 | ::-webkit-scrollbar-track {
66 | border-radius: 10px;
67 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0);
68 | -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0);
69 | }
70 |
71 | ::-webkit-scrollbar-thumb {
72 | background-color: rgba(0, 0, 0, 0.05);
73 | border-radius: 10px;
74 | box-shadow: inset 1px 1px 0 rgba(0, 0, 0, 0.1);
75 | -webkit-box-shadow: inset 1px 1px 0 rgba(0, 0, 0, 0.1);
76 | }
77 |
78 | ::-webkit-scrollbar-thumb {
79 | background-color: rgba(0, 0, 0, 0.2);
80 | border-radius: 10px;
81 | box-shadow: inset 1px 1px 0 rgba(0, 0, 0, 0.1);
82 | -webkit-box-shadow: inset 1px 1px 0 rgba(0, 0, 0, 0.1);
83 | }
84 |
85 | ::-webkit-scrollbar {
86 | width: 16px;
87 | height: 16px;
88 | }
89 |
90 | ::-webkit-scrollbar-track,
91 | ::-webkit-scrollbar-thumb {
92 | border-radius: 999px;
93 | border: 5px solid transparent;
94 | }
95 |
96 | ::-webkit-scrollbar-track {
97 | box-shadow: 1px 1px 5px rgba(144, 146, 152, 0.3) inset;
98 | }
99 |
100 | ::-webkit-scrollbar-thumb {
101 | min-height: 20px;
102 | background-clip: content-box;
103 | box-shadow: 0 0 0 5px rgba(144, 146, 152, 0.3) inset;
104 | }
105 |
106 | ::-webkit-scrollbar-corner {
107 | background: transparent;
108 | }
109 |
--------------------------------------------------------------------------------
/src/views/BuildCode.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
61 |
62 |
81 |
--------------------------------------------------------------------------------
/src/views/DocumentText.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
56 |
57 |
75 |
--------------------------------------------------------------------------------
/src/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
21 |
22 |
23 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | 下次尝试使用缓存直接登录数据库
50 |
51 |
52 |
53 |
54 | 确定
55 |
56 | 取消
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
67 |
68 |
69 |
70 | 确定
71 | 取消
72 |
73 |
74 |
75 |
76 |
77 |
271 |
272 |
347 |
--------------------------------------------------------------------------------
/src/views/TemplateManagement.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 新增模板
5 |
6 |
7 |
8 |
9 | {{ item.name }}
10 | 使用此模板
11 |
12 |
13 |
14 | 删除此模板
15 | 查看模板文件
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | 确定
33 |
34 | 取消
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
181 |
182 |
232 |
--------------------------------------------------------------------------------
/static/componentList.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "1输入框",
4 | "value": "input"
5 | },
6 | {
7 | "name": "2字典下拉框",
8 | "value": "select"
9 | },
10 | {
11 | "name": "3文本框",
12 | "value": "text"
13 | },
14 | {
15 | "name": "4数字框",
16 | "value": "number"
17 | },
18 | {
19 | "name": "5日期选择器",
20 | "value": "date"
21 | },
22 | {
23 | "name": "6日期时间选择器",
24 | "value": "datetime"
25 | },
26 | {
27 | "name": "7附件上传",
28 | "value": "upload"
29 | },
30 | {
31 | "name": "8选择树",
32 | "value": "treeselect"
33 | }
34 | ]
35 |
--------------------------------------------------------------------------------
/static/document/frontCRUD.md:
--------------------------------------------------------------------------------
1 | # 前端 CRUD 使用手册
2 |
3 | ## 编写 ejs
4 |
5 | ejs 是一门 javascript 编写的高效模板引擎
6 |
7 | ejs 入门, 请看https://ejs.bootcss.com/#install
8 |
9 | ## 可使用变量
10 |
11 | ```ts
12 | interface CRUD {
13 | insertList: Array // 新增字段集合
14 | queryList: Array // 查询字段集合
15 | searchList: Array // 搜索字段集合
16 | suffix: string // 后缀
17 | templateName: string // 模板地址
18 | _: Object // lodash对象, 可以在ejs中使用lodash!!
19 | }
20 |
21 | // 字段信息
22 | interface Field {
23 | Collation: string,
24 | Comment: string, // 注释
25 | Default: string, // 默认值
26 | Field: string, // 字段名
27 | Key: string, // 键名
28 | Null: string, // 是否可为空
29 | Privileges: string, // 权限
30 | Type: string // 类型
31 | }
32 | ```
33 |
34 | ## 可使用方法
35 |
36 | ### lodash
37 |
38 | lodash作为前端最受欢迎的工具库,里面有着许多方便的方法,而有的一些也已经成为了Javascript标准!
39 |
40 | lodash是一个一致性、模块化、高性能的 JavaScript 实用工具库!
41 |
42 | 在ejs里面可以使用lodash的所有方法!
43 |
44 | 比如: 把字符串转成驼峰命名:
45 | ```js
46 | _.camelCase(data.Field)
47 | ```
48 |
49 | 首字母大写:
50 | ```js
51 | _.capitalize(data.Field)
52 | ```
53 |
54 | 转为kebabCase写法:
55 | ```js
56 | _.kebabCase(data.Field)
57 | ```
58 |
59 | 学习了解lodash https://www.lodashjs.com/
60 |
61 |
62 | 还可以使用 JavaScript 的所有方法, 学习 JavaScript:
63 |
64 | https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript
65 |
--------------------------------------------------------------------------------
/static/ejs/bim:
--------------------------------------------------------------------------------
1 | <%# Bim工程前端生成模板 -%>
2 | <%# t: "新增项目" r: "必填字段 用英文逗号隔开" kp: "主键字段" -%>
3 | <%# 重置字典使用`code + 序号 : 字典值` -%>
4 | <%_ function getKey(key) { return kdata.filter(v => v.key === key)[0].value } -%>
5 | <%_ function getRequire(keys) { var arr = keys.split(','); var newArr = []; arr.forEach(v => { newArr.push(...insertList.filter(vv => vv.index==v)); }); return newArr; } -%>
6 | <%_ function filterSelect() { return insertList.filter(v => v.component === 'select').map(v => _.camelCase(v.Field) + 'List') } -%>
7 | <%_ function filterUpload() { return insertList.filter(v => v.component === 'upload') } -%>
8 | <%_ function filterTreeSelect() { return insertList.filter(v => v.component === 'treeselect').map(v => _.camelCase(v.Field) + 'Options') } -%>
9 | <%_ var getDicCode = (() => { var json = {}; kdata.filter(v => v.key.indexOf('code') === 0).forEach(v => { var serialNumber = v.key.substring(4); var key = insertList.filter(vv => vv.index == serialNumber)[0].Field; json[key] = v.value }); return json })() -%>
10 | <%_ function A(str) { return _.capitalize(str) } -%>
11 | <%_ function B(str) { return _.lowerFirst(str) } -%>
12 | <%_ var name = getKey('name'); -%>
13 |
14 |
15 |
16 |
17 | <%_ searchList.forEach(function(data) { -%>
18 |
19 | <%_ if(data.component === 'input') { -%>
20 |
21 | <%_ }-%>
22 | <%_ if(data.component === 'text') { -%>
23 |
24 | <%_ }-%>
25 | <%_ if(data.component === 'number') { -%>
26 |
27 | <%_ }-%>
28 | <%_ if(data.component === 'select') { -%>
29 |
30 | <%_ }-%>
31 | <%_ if(data.component === 'date') { -%>
32 |
37 |
38 | <%_ }-%>
39 | <%_ if(data.component === 'datetime') { -%>
40 |
45 |
46 | <%_ }-%>
47 | <%_ if(data.component === 'color') { -%>
48 |
49 | <%_ }-%>
50 | <%_ if(data.component === 'treeselect') { -%>
51 |
52 | <%_ }-%>
53 | <%_ if(!data.component) { -%>
54 |
55 | <%_ }-%>
56 |
57 | <%_ });-%>
58 |
59 | 搜索
60 | 重置
61 |
62 |
63 |
64 |
65 |
66 |
67 | <%=getKey('t') %>
68 |
69 |
70 |
71 | <%_ queryList.forEach(function(data) { -%>
72 |
73 | <%_ }); -%>
74 |
75 |
76 | 编辑
77 | 删除
78 |
79 |
80 |
81 |
82 |
91 |
92 |
93 |
94 |
98 |
99 |
100 |
101 |
102 | 基础信息
103 |
104 | <%# 进入新增form表单 -%>
105 | <%_ _.chunk(insertList,2).forEach(function(data) { -%>
106 | <%_ if(data.length === 2) { -%>
107 |
108 |
109 |
110 | <%_ if(data[0].component === 'input') { -%>
111 |
112 | <%_ }-%>
113 | <%_ if(data[0].component === 'number') { -%>
114 |
115 | <%_ }-%>
116 | <%_ if(data[0].component === 'text') { -%>
117 |
118 | <%_ }-%>
119 |
120 | <%_ if(data[0].component === 'select') { -%>
121 |
122 | <%_ }-%>
123 | <%_ if(data[0].component === 'date') { -%>
124 |
130 |
131 | <%_ }-%>
132 | <%_ if(data[0].component === 'datetime') { -%>
133 |
139 |
140 | <%_ }-%>
141 | <%_ if(data[0].component === 'color') { -%>
142 |
143 | <%_ }-%>
144 | <%_ if(data[0].component === 'treeselect') { -%>
145 |
146 | <%_ }-%>
147 | <%_ if(data[0].component === 'upload') { -%>
148 |
149 | <%_ }-%>
150 | <%_ if(!data[0].component) { -%>
151 |
152 | <%_ }-%>
153 |
154 |
155 |
156 |
157 | <%_ if(data[1].component === 'input') { -%>
158 |
159 | <%_ }-%>
160 | <%_ if(data[0].component === 'number') { -%>
161 |
162 | <%_ }-%>
163 | <%_ if(data[1].component === 'text') { -%>
164 |
165 | <%_ }-%>
166 | <%_ if(data[1].component === 'select') { -%>
167 |
168 | <%_ }-%>
169 | <%_ if(data[1].component === 'date') { -%>
170 |
176 |
177 | <%_ }-%>
178 | <%_ if(data[1].component === 'datetime') { -%>
179 |
185 |
186 | <%_ }-%>
187 | <%_ if(data[1].component === 'color') { -%>
188 |
189 | <%_ }-%>
190 | <%_ if(data[1].component === 'treeselect') { -%>
191 |
192 | <%_ }-%>
193 | <%_ if(data[1].component === 'upload') { -%>
194 |
195 | <%_ }-%>
196 | <%_ if(!data[1].component) { -%>
197 |
198 | <%_ }-%>
199 |
200 |
201 |
202 | <%_ } else {-%>
203 | <%_ if(data[0].component === 'text') { -%>
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 | <%_ } else {-%>
212 |
213 |
214 |
215 | <%_ if(data[0].component === 'input') { -%>
216 |
217 | <%_ }-%>
218 | <%_ if(data[0].component === 'number') { -%>
219 |
220 | <%_ }-%>
221 | <%_ if(data[0].component === 'text') { -%>
222 |
223 | <%_ }-%>
224 | <%_ if(data[0].component === 'select') { -%>
225 |
226 | <%_ }-%>
227 | <%_ if(data[0].component === 'date') { -%>
228 |
234 |
235 | <%_ }-%>
236 | <%_ if(data[0].component === 'datetime') { -%>
237 |
243 |
244 | <%_ }-%>
245 | <%_ if(data[0].component === 'color') { -%>
246 |
247 | <%_ }-%>
248 | <%_ if(data[0].component === 'treeselect') { -%>
249 |
250 | <%_ }-%>
251 | <%_ if(data[0].component === 'upload') { -%>
252 |
253 | <%_ }-%>
254 | <%_ if(!data[0].component) { -%>
255 |
256 | <%_ }-%>
257 |
258 |
259 |
260 | <%_ }-%>
261 | <%_ }-%>
262 | <%_ })-%>
263 | <%# 进入新增form表单 end -%>
264 |
265 |
266 |
267 | 取消
268 | 确定
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
414 |
--------------------------------------------------------------------------------
/static/ejs/bimApi:
--------------------------------------------------------------------------------
1 | <%# 这是前端vue ejs模板 API文件生成 -%>
2 | <%# 具体参数要求: name: "当前页面名称", api: "api前缀 例如/pm/baseproject/" -%>
3 | <%# 将首写字母大写,其余小写 -%>
4 | <%_ function A(str) { return _.capitalize(str) } -%>
5 | <%_ function getKey(key) { return kdata.filter(v => v.key === key)[0].value } -%>
6 | <%_ var api = getKey('api');var name = getKey('name'); -%>
7 | import request from '@/utils/request'
8 |
9 | export function list<%=A(name) %>(query) {
10 | return request({
11 | url: '<%=api -%>list',
12 | method: 'get',
13 | params: query
14 | })
15 | }
16 |
17 | export function get<%=A(name) %>(<%=A(name) %>Id) {
18 | return request({
19 | url: '<%=api -%>info/' + <%=A(name) %>Id,
20 | method: 'get'
21 | })
22 | }
23 |
24 |
25 | export function add<%=A(name) %>(data) {
26 | return request({
27 | url: '<%=api -%>save',
28 | method: 'post',
29 | data: data
30 | })
31 | }
32 |
33 | export function update<%=A(name) %>(data) {
34 | return request({
35 | url: '<%=api -%>update',
36 | method: 'put',
37 | data: data
38 | })
39 | }
40 |
41 | export function del<%=A(name) %>(data) {
42 | return request({
43 | url: '<%=api -%>delete',
44 | method: 'delete',
45 | data: data
46 | })
47 | }
48 |
--------------------------------------------------------------------------------
/static/ejs/bimCRUD-弹窗版:
--------------------------------------------------------------------------------
1 | <%# Bim工程前端生成模板 -%>
2 | <%# t: "新增项目" r: "必填字段 用英文逗号隔开" kp: "主键字段" -%>
3 | <%# 重置字典使用`code + 序号 : 字典值` -%>
4 | <%_ function getKey(key) { return kdata.filter(v => v.key === key)[0].value } -%>
5 | <%_ function getRequire(keys) { var arr = keys.split(','); var newArr = []; arr.forEach(v => { newArr.push(...insertList.filter(vv => vv.index==v)); }); return newArr; } -%>
6 | <%_ function filterSelect() { return insertList.filter(v => v.component === 'select').map(v => _.camelCase(v.Field) + 'List') } -%>
7 | <%_ function filterUpload() { return insertList.filter(v => v.component === 'upload') } -%>
8 | <%_ function filterTreeSelect() { return insertList.filter(v => v.component === 'treeselect').map(v => _.camelCase(v.Field) + 'Options') } -%>
9 | <%_ var getDicCode = (() => { var json = {}; kdata.filter(v => v.key.indexOf('code') === 0).forEach(v => { var serialNumber = v.key.substring(4); var key = insertList.filter(vv => vv.index == serialNumber)[0].Field; json[key] = v.value }); return json })() -%>
10 | <%_ function A(str) { return _.capitalize(str) } -%>
11 | <%_ function B(str) { return _.lowerFirst(str) } -%>
12 | <%_ var name = getKey('name'); -%>
13 |
14 |
15 |
16 |
17 | <%_ searchList.forEach(function(data) { -%>
18 |
19 | <%_ if(data.component === 'input') { -%>
20 |
21 | <%_ }-%>
22 | <%_ if(data.component === 'text') { -%>
23 |
24 | <%_ }-%>
25 | <%_ if(data.component === 'number') { -%>
26 |
27 | <%_ }-%>
28 | <%_ if(data.component === 'select') { -%>
29 |
30 | <%_ }-%>
31 | <%_ if(data.component === 'date') { -%>
32 |
37 |
38 | <%_ }-%>
39 | <%_ if(data.component === 'datetime') { -%>
40 |
45 |
46 | <%_ }-%>
47 | <%_ if(data.component === 'color') { -%>
48 |
49 | <%_ }-%>
50 | <%_ if(data.component === 'treeselect') { -%>
51 |
52 | <%_ }-%>
53 | <%_ if(!data.component) { -%>
54 |
55 | <%_ }-%>
56 |
57 | <%_ });-%>
58 |
59 | 搜索
60 | 重置
61 |
62 |
63 |
64 |
65 |
66 |
67 | <%=getKey('t') %>
68 |
69 |
70 |
71 | <%_ queryList.forEach(function(data) { -%>
72 |
73 | <%_ }); -%>
74 |
75 |
76 | 编辑
77 | 删除
78 |
79 |
80 |
81 |
82 |
91 |
92 |
93 |
94 |
95 |
96 | <%_ insertList.forEach(function(data) { -%>
97 |
98 | <%_ if(data.component === 'input') { -%>
99 |
100 | <%_ }-%>
101 | <%_ if(data.component === 'text') { -%>
102 |
103 | <%_ }-%>
104 | <%_ if(data.component === 'number') { -%>
105 |
106 | <%_ }-%>
107 | <%_ if(data.component === 'select') { -%>
108 |
109 | <%_ }-%>
110 | <%_ if(data.component === 'date') { -%>
111 |
116 |
117 | <%_ }-%>
118 | <%_ if(data.component === 'datetime') { -%>
119 |
124 |
125 | <%_ }-%>
126 | <%_ if(data.component === 'color') { -%>
127 |
128 | <%_ }-%>
129 | <%_ if(data.component === 'treeselect') { -%>
130 |
131 | <%_ }-%>
132 | <%_ if(!data.component) { -%>
133 |
134 | <%_ }-%>
135 |
136 | <%_ }); -%>
137 |
138 |
139 | 确定
140 | 取消
141 |
142 |
143 |
144 |
145 |
146 |
284 |
--------------------------------------------------------------------------------
/static/ejs/bimCRUD-弹窗版Api:
--------------------------------------------------------------------------------
1 | <%# 这是前端vue ejs模板 API文件生成 -%>
2 | <%# 具体参数要求: name: "当前页面名称", api: "api前缀 例如/pm/baseproject/" -%>
3 | <%# 将首写字母大写,其余小写 -%>
4 | <%_ function A(str) { return _.capitalize(str) } -%>
5 | <%_ function getKey(key) { return kdata.filter(v => v.key === key)[0].value } -%>
6 | <%_ var api = getKey('api');var name = getKey('name'); -%>
7 | import request from '@/utils/request'
8 |
9 | export function list<%=A(name) %>(query) {
10 | return request({
11 | url: '<%=api -%>list',
12 | method: 'get',
13 | params: query
14 | })
15 | }
16 |
17 | export function get<%=A(name) %>(<%=A(name) %>Id) {
18 | return request({
19 | url: '<%=api -%>info/' + <%=A(name) %>Id,
20 | method: 'get'
21 | })
22 | }
23 |
24 |
25 | export function add<%=A(name) %>(data) {
26 | return request({
27 | url: '<%=api -%>save',
28 | method: 'post',
29 | data: data
30 | })
31 | }
32 |
33 | export function update<%=A(name) %>(data) {
34 | return request({
35 | url: '<%=api -%>update',
36 | method: 'put',
37 | data: data
38 | })
39 | }
40 |
41 | export function del<%=A(name) %>(data) {
42 | return request({
43 | url: '<%=api -%>delete',
44 | method: 'delete',
45 | data: data
46 | })
47 | }
48 |
--------------------------------------------------------------------------------
/static/ejs/bim左右结构:
--------------------------------------------------------------------------------
1 | <%# Bim工程前端生成模板 -%>
2 | <%# t: "新增项目" r: "必填字段 用英文逗号隔开" kp: "主键字段" -%>
3 | <%# 重置字典使用`code + 序号 : 字典值` -%>
4 | <%_ function getKey(key) { return kdata.filter(v => v.key === key)[0].value } -%>
5 | <%_ function getRequire(keys) { var arr = keys.split(','); var newArr = []; arr.forEach(v => { newArr.push(...insertList.filter(vv => vv.index==v)); }); return newArr; } -%>
6 | <%_ function filterSelect() { return insertList.filter(v => v.component === 'select').map(v => _.camelCase(v.Field) + 'List') } -%>
7 | <%_ function filterUpload() { return insertList.filter(v => v.component === 'upload') } -%>
8 | <%_ function filterTreeSelect() { return insertList.filter(v => v.component === 'treeselect').map(v => _.camelCase(v.Field) + 'Options') } -%>
9 | <%_ var getDicCode = (() => { var json = {}; kdata.filter(v => v.key.indexOf('code') === 0).forEach(v => { var serialNumber = v.key.substring(4); var key = insertList.filter(vv => vv.index == serialNumber)[0].Field; json[key] = v.value }); return json })() -%>
10 | <%_ function A(str) { return _.capitalize(str) } -%>
11 | <%_ function B(str) { return _.lowerFirst(str) } -%>
12 | <%_ var name = getKey('name'); -%>
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | <%_ searchList.forEach(function(data) { -%>
28 |
29 | <%_ if(data.component === 'input') { -%>
30 |
31 | <%_ }-%>
32 | <%_ if(data.component === 'text') { -%>
33 |
34 | <%_ }-%>
35 | <%_ if(data.component === 'number') { -%>
36 |
37 | <%_ }-%>
38 | <%_ if(data.component === 'select') { -%>
39 |
40 | <%_ }-%>
41 | <%_ if(data.component === 'date') { -%>
42 |
47 |
48 | <%_ }-%>
49 | <%_ if(data.component === 'datetime') { -%>
50 |
55 |
56 | <%_ }-%>
57 | <%_ if(data.component === 'color') { -%>
58 |
59 | <%_ }-%>
60 | <%_ if(data.component === 'treeselect') { -%>
61 |
62 | <%_ }-%>
63 | <%_ if(!data.component) { -%>
64 |
65 | <%_ }-%>
66 |
67 | <%_ });-%>
68 |
69 | 搜索
70 | 重置
71 |
72 |
73 |
74 |
75 |
76 |
77 | <%=getKey('t') %>
78 |
79 |
80 |
81 | <%_ queryList.forEach(function(data) { -%>
82 |
83 | <%_ }); -%>
84 |
85 |
86 | 编辑
87 | 删除
88 |
89 |
90 |
91 |
92 |
101 |
102 |
103 |
104 |
108 |
109 |
110 |
111 |
112 | 基础信息
113 |
114 | <%# 进入新增form表单 -%>
115 | <%_ _.chunk(insertList,2).forEach(function(data) { -%>
116 | <%_ if(data.length === 2) { -%>
117 |
118 |
119 |
120 | <%_ if(data[0].component === 'input') { -%>
121 |
122 | <%_ }-%>
123 | <%_ if(data[0].component === 'number') { -%>
124 |
125 | <%_ }-%>
126 | <%_ if(data[0].component === 'text') { -%>
127 |
128 | <%_ }-%>
129 |
130 | <%_ if(data[0].component === 'select') { -%>
131 |
132 | <%_ }-%>
133 | <%_ if(data[0].component === 'date') { -%>
134 |
140 |
141 | <%_ }-%>
142 | <%_ if(data[0].component === 'datetime') { -%>
143 |
149 |
150 | <%_ }-%>
151 | <%_ if(data[0].component === 'color') { -%>
152 |
153 | <%_ }-%>
154 | <%_ if(data[0].component === 'treeselect') { -%>
155 |
156 | <%_ }-%>
157 | <%_ if(data[0].component === 'upload') { -%>
158 |
159 | <%_ }-%>
160 | <%_ if(!data[0].component) { -%>
161 |
162 | <%_ }-%>
163 |
164 |
165 |
166 |
167 | <%_ if(data[1].component === 'input') { -%>
168 |
169 | <%_ }-%>
170 | <%_ if(data[0].component === 'number') { -%>
171 |
172 | <%_ }-%>
173 | <%_ if(data[1].component === 'text') { -%>
174 |
175 | <%_ }-%>
176 | <%_ if(data[1].component === 'select') { -%>
177 |
178 | <%_ }-%>
179 | <%_ if(data[1].component === 'date') { -%>
180 |
186 |
187 | <%_ }-%>
188 | <%_ if(data[1].component === 'datetime') { -%>
189 |
195 |
196 | <%_ }-%>
197 | <%_ if(data[1].component === 'color') { -%>
198 |
199 | <%_ }-%>
200 | <%_ if(data[1].component === 'treeselect') { -%>
201 |
202 | <%_ }-%>
203 | <%_ if(data[1].component === 'upload') { -%>
204 |
205 | <%_ }-%>
206 | <%_ if(!data[1].component) { -%>
207 |
208 | <%_ }-%>
209 |
210 |
211 |
212 | <%_ } else {-%>
213 | <%_ if(data[0].component === 'text') { -%>
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 | <%_ } else {-%>
222 |
223 |
224 |
225 | <%_ if(data[0].component === 'input') { -%>
226 |
227 | <%_ }-%>
228 | <%_ if(data[0].component === 'number') { -%>
229 |
230 | <%_ }-%>
231 | <%_ if(data[0].component === 'text') { -%>
232 |
233 | <%_ }-%>
234 | <%_ if(data[0].component === 'select') { -%>
235 |
236 | <%_ }-%>
237 | <%_ if(data[0].component === 'date') { -%>
238 |
244 |
245 | <%_ }-%>
246 | <%_ if(data[0].component === 'datetime') { -%>
247 |
253 |
254 | <%_ }-%>
255 | <%_ if(data[0].component === 'color') { -%>
256 |
257 | <%_ }-%>
258 | <%_ if(data[0].component === 'treeselect') { -%>
259 |
260 | <%_ }-%>
261 | <%_ if(data[0].component === 'upload') { -%>
262 |
263 | <%_ }-%>
264 | <%_ if(!data[0].component) { -%>
265 |
266 | <%_ }-%>
267 |
268 |
269 |
270 | <%_ }-%>
271 | <%_ }-%>
272 | <%_ })-%>
273 | <%# 进入新增form表单 end -%>
274 |
275 |
276 |
277 | 取消
278 | 确定
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
444 |
--------------------------------------------------------------------------------
/static/ejs/bim左右结构-弹窗版:
--------------------------------------------------------------------------------
1 | <%# Bim工程前端生成模板 -%>
2 | <%# t: "新增项目" r: "必填字段 用英文逗号隔开" kp: "主键字段" -%>
3 | <%# 重置字典使用`code + 序号 : 字典值` -%>
4 | <%_ function getKey(key) { return kdata.filter(v => v.key === key)[0].value } -%>
5 | <%_ function getRequire(keys) { var arr = keys.split(','); var newArr = []; arr.forEach(v => { newArr.push(...insertList.filter(vv => vv.index==v)); }); return newArr; } -%>
6 | <%_ function filterSelect() { return insertList.filter(v => v.component === 'select').map(v => _.camelCase(v.Field) + 'List') } -%>
7 | <%_ function filterUpload() { return insertList.filter(v => v.component === 'upload') } -%>
8 | <%_ function filterTreeSelect() { return insertList.filter(v => v.component === 'treeselect').map(v => _.camelCase(v.Field) + 'Options') } -%>
9 | <%_ var getDicCode = (() => { var json = {}; kdata.filter(v => v.key.indexOf('code') === 0).forEach(v => { var serialNumber = v.key.substring(4); var key = insertList.filter(vv => vv.index == serialNumber)[0].Field; json[key] = v.value }); return json })() -%>
10 | <%_ function A(str) { return _.capitalize(str) } -%>
11 | <%_ function B(str) { return _.lowerFirst(str) } -%>
12 | <%_ var name = getKey('name'); -%>
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | <%_ searchList.forEach(function(data) { -%>
28 |
29 | <%_ if(data.component === 'input') { -%>
30 |
31 | <%_ }-%>
32 | <%_ if(data.component === 'text') { -%>
33 |
34 | <%_ }-%>
35 | <%_ if(data.component === 'number') { -%>
36 |
37 | <%_ }-%>
38 | <%_ if(data.component === 'select') { -%>
39 |
40 | <%_ }-%>
41 | <%_ if(data.component === 'date') { -%>
42 |
47 |
48 | <%_ }-%>
49 | <%_ if(data.component === 'datetime') { -%>
50 |
55 |
56 | <%_ }-%>
57 | <%_ if(data.component === 'color') { -%>
58 |
59 | <%_ }-%>
60 | <%_ if(data.component === 'treeselect') { -%>
61 |
62 | <%_ }-%>
63 | <%_ if(!data.component) { -%>
64 |
65 | <%_ }-%>
66 |
67 | <%_ });-%>
68 |
69 | 搜索
70 | 重置
71 |
72 |
73 |
74 |
75 |
76 |
77 | <%=getKey('t') %>
78 |
79 |
80 |
81 | <%_ queryList.forEach(function(data) { -%>
82 |
83 | <%_ }); -%>
84 |
85 |
86 | 编辑
87 | 删除
88 |
89 |
90 |
91 |
92 |
101 |
102 |
103 |
104 |
105 |
106 | <%_ insertList.forEach(function(data) { -%>
107 |
108 | <%_ if(data.component === 'input') { -%>
109 |
110 | <%_ }-%>
111 | <%_ if(data.component === 'text') { -%>
112 |
113 | <%_ }-%>
114 | <%_ if(data.component === 'number') { -%>
115 |
116 | <%_ }-%>
117 | <%_ if(data.component === 'select') { -%>
118 |
119 | <%_ }-%>
120 | <%_ if(data.component === 'date') { -%>
121 |
126 |
127 | <%_ }-%>
128 | <%_ if(data.component === 'datetime') { -%>
129 |
134 |
135 | <%_ }-%>
136 | <%_ if(data.component === 'color') { -%>
137 |
138 | <%_ }-%>
139 | <%_ if(data.component === 'treeselect') { -%>
140 |
141 | <%_ }-%>
142 | <%_ if(!data.component) { -%>
143 |
144 | <%_ }-%>
145 |
146 | <%_ }); -%>
147 |
148 |
149 | 确定
150 | 取消
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
314 |
--------------------------------------------------------------------------------
/static/ejs/bim左右结构-弹窗版Api:
--------------------------------------------------------------------------------
1 | <%# 这是前端vue ejs模板 API文件生成 -%>
2 | <%# 具体参数要求: name: "当前页面名称", api: "api前缀 例如/pm/baseproject/" -%>
3 | <%# 将首写字母大写,其余小写 -%>
4 | <%_ function A(str) { return _.capitalize(str) } -%>
5 | <%_ function getKey(key) { return kdata.filter(v => v.key === key)[0].value } -%>
6 | <%_ var api = getKey('api');var name = getKey('name'); -%>
7 | import request from '@/utils/request'
8 |
9 | export function list<%=A(name) %>(query) {
10 | return request({
11 | url: '<%=api -%>list',
12 | method: 'get',
13 | params: query
14 | })
15 | }
16 |
17 | export function get<%=A(name) %>(<%=A(name) %>Id) {
18 | return request({
19 | url: '<%=api -%>info/' + <%=A(name) %>Id,
20 | method: 'get'
21 | })
22 | }
23 |
24 |
25 | export function add<%=A(name) %>(data) {
26 | return request({
27 | url: '<%=api -%>save',
28 | method: 'post',
29 | data: data
30 | })
31 | }
32 |
33 | export function update<%=A(name) %>(data) {
34 | return request({
35 | url: '<%=api -%>update',
36 | method: 'put',
37 | data: data
38 | })
39 | }
40 |
41 | export function del<%=A(name) %>(data) {
42 | return request({
43 | url: '<%=api -%>delete',
44 | method: 'delete',
45 | data: data
46 | })
47 | }
48 |
--------------------------------------------------------------------------------
/static/ejs/bim左右结构Api:
--------------------------------------------------------------------------------
1 | <%# 这是前端vue ejs模板 API文件生成 -%>
2 | <%# 具体参数要求: name: "当前页面名称", api: "api前缀 例如/pm/baseproject/" -%>
3 | <%# 将首写字母大写,其余小写 -%>
4 | <%_ function A(str) { return _.capitalize(str) } -%>
5 | <%_ function getKey(key) { return kdata.filter(v => v.key === key)[0].value } -%>
6 | <%_ var api = getKey('api');var name = getKey('name'); -%>
7 | import request from '@/utils/request'
8 |
9 | export function list<%=A(name) %>(query) {
10 | return request({
11 | url: '<%=api -%>list',
12 | method: 'get',
13 | params: query
14 | })
15 | }
16 |
17 | export function get<%=A(name) %>(<%=A(name) %>Id) {
18 | return request({
19 | url: '<%=api -%>info/' + <%=A(name) %>Id,
20 | method: 'get'
21 | })
22 | }
23 |
24 |
25 | export function add<%=A(name) %>(data) {
26 | return request({
27 | url: '<%=api -%>save',
28 | method: 'post',
29 | data: data
30 | })
31 | }
32 |
33 | export function update<%=A(name) %>(data) {
34 | return request({
35 | url: '<%=api -%>update',
36 | method: 'put',
37 | data: data
38 | })
39 | }
40 |
41 | export function del<%=A(name) %>(data) {
42 | return request({
43 | url: '<%=api -%>delete',
44 | method: 'delete',
45 | data: data
46 | })
47 | }
48 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | pluginOptions: {
3 | electronBuilder: {
4 | nodeIntegration: true,
5 | builderOptions: {
6 | appId: 'com.chendm.easycode-javascript.1.0.0',
7 | productName: 'EasyCode',
8 | copyright: 'Copyright © 2020',
9 | directories: {
10 | output: './dist'
11 | },
12 | extraResources: ['./static/**'],
13 | buildVersion: '1.0.0',
14 | nsis: {
15 | createDesktopShortcut: true,
16 | createStartMenuShortcut: true
17 | },
18 | win: {
19 | icon: 'favicon.ico',
20 | target: [
21 | {
22 | target: 'nsis',
23 | arch: [
24 | 'x64',
25 | 'ia32'
26 | ]
27 | }
28 | ]
29 | }
30 | }
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/前端代码生成器使用说明.md:
--------------------------------------------------------------------------------
1 | # 前端代码生成器使用说明
2 |
3 | - 连接数据库
4 | 点击标题,选择`连接数据库`
5 |
6 | 
7 |
8 | 输入相关信息, 点击确定, 点击`前端CRUD生成`
9 |
10 | 
11 |
12 | - 选择数据库
13 |
14 | 
15 |
16 | - 选择表
17 |
18 | 
19 |
20 | 会自动出现表字段
21 |
22 | - 信息说明
23 |
24 | 
25 |
26 | insert复选框代表新增时需要展示的字段
27 | search复选框代表搜索时需要的字段
28 | query复选框代表table需要展示的字段
29 | 上移和下移可以移动字段,新增和table的字段展示顺序和`序号`相关
30 |
31 | - 设置属性
32 | `设置属性`需要设置一些模板需要的属性,下面就以`bim`模板为例
33 | ```
34 | t: "新增项目" ( 新增按钮的文字 )
35 | r: "必填字段序号 用英文逗号隔开"
36 | kp: "主键字段"
37 | name: "当前页面名称",
38 | api: "api前缀 例如/pm/baseproject/"
39 | ```
40 | > **这些参数可以是模板所需要的,而模板的参数是约定的,并不是软件**所要求的。
41 | 如图所示
42 |
43 | 
44 |
45 | - 选择Ejs模板
46 |
47 | 
48 |
49 | - 生成
50 |
51 | 文件名: 生成的文件名
52 |
53 | 其他地方和图片中一致即可
54 |
55 | 
56 |
57 | - 模板存放位置
58 |
59 | `c:\用户名\appData\Local\Programs\easycode-javascript\resources\static\ejs`
60 |
61 | - Ejs模板学习
62 |
63 | 
64 |
65 |
--------------------------------------------------------------------------------
/更换模板操作.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chendonming/easycode-javascript/656b7c777bc7e045f45b0d3365f3dced98b48f6d/更换模板操作.md
--------------------------------------------------------------------------------