|
|
|
135 |
136 |
137 | ## 相关链接
138 |
139 | `乐子侃生活`是本人对开发生活中各种有趣的、好玩的、沙雕的创意和想法以在线小网站或者文章的形式表达出来,比如:
140 | - [小霸王游戏机](https://game.rdtalk.cn)
141 | - [爱国头像生成器](https://avatar.xugaoyi.com/)
142 | - [到账语音生成器](https://zfb.xugaoyi.com/)
143 |
144 | 还有更多好玩的等你去探索吧~
145 |
146 |
147 |
148 |
149 |
150 | ## License
151 |
152 | [MIT](http://opensource.org/licenses/MIT)
153 |
154 | Copyright (c) 2022-present, [Allan Jhon](https://rdtalk.cn).
155 |
156 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | /** @format */
2 |
3 | const path = require('path')
4 | const SizePlugin = require('size-plugin')
5 | const PrerenderSPAPlugin = new require('prerender-spa-plugin')
6 |
7 | const isProductionEnvFlag = process.env.NODE_ENV === 'production'
8 |
9 | function resolveRealPath(dir) {
10 | return path.join(__dirname, dir)
11 | }
12 |
13 | // https://github.com/vuejs/vue-docs-zh-cn/blob/master/vue-cli/config.md
14 | module.exports = {
15 | // Project deployment base
16 | // By default we assume your app will be deployed at the root of a domain,
17 | // e.g. https://www.my-app.com/
18 | // If your app is deployed at a sub-path, you will need to specify that
19 | // sub-path here. For example, if your app is deployed at
20 | // https://www.foobar.com/my-app/
21 | // then change this to '/my-app/'
22 | publicPath: '/',
23 |
24 | // where to output built files
25 | outputDir: 'dist',
26 |
27 | // whether to use eslint-loader for lint on save.
28 | // valid values: true | false | 'error'
29 | // when set to 'error', lint errors will cause compilation to fail.
30 | lintOnSave: true,
31 |
32 | // https://cli.vuejs.org/config/#runtimecompiler
33 | runtimeCompiler: false,
34 |
35 | // babel-loader skips `node_modules` deps by default.
36 | // explicitly transpile a dependency with this option.
37 | transpileDependencies: [
38 | /* string or regex */
39 | ],
40 |
41 | // generate sourceMap for production build?
42 | productionSourceMap: process.env.NODE_ENV !== 'production',
43 |
44 | // tweak internal webpack configuration.
45 | // see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
46 | chainWebpack: config => {
47 | config.resolve.alias
48 | .set('vue$', 'vue/dist/vue.esm.js')
49 | .set('@helper', resolveRealPath('src/helper'))
50 | .set('@config', resolveRealPath('src/config'))
51 | .set('@pages', resolveRealPath('src/pages'))
52 | .set('@assets', resolveRealPath('src/assets'))
53 | .set('@router', resolveRealPath('src/router'))
54 | .set('@mixins', resolveRealPath('src/mixins'))
55 | .set('@components', resolveRealPath('src/components'))
56 |
57 | // remove the old loader & add new one
58 | config.module.rules.delete('svg')
59 | config.module
60 | .rule('svg')
61 | .test(/\.svg$/)
62 | .use('svg-sprite-loader')
63 | .loader('svg-sprite-loader')
64 | .options({
65 | name: '[name]-[hash:7]',
66 | prefixize: true
67 | })
68 |
69 | const splitOptions = config.optimization.get('splitChunks')
70 | config.optimization.splitChunks(
71 | Object.assign({}, splitOptions, {
72 | // (缺省值5)按需加载时的最大并行请求数
73 | maxAsyncRequests: 16,
74 | // (默认值3)入口点上的最大并行请求数
75 | maxInitialRequests: 16,
76 | // (默认值:1)分割前共享模块的最小块数
77 | minChunks: 1,
78 | // (默认值:30000)块的最小大小
79 | minSize: 30000,
80 | // webpack 将使用块的起源和名称来生成名称: `vendors~main.js`,如项目与"~"冲突,则可通过此值修改,Eg: '-'
81 | automaticNameDelimiter: '~',
82 | // cacheGroups is an object where keys are the cache group names.
83 | name: true,
84 | cacheGroups: {
85 | default: false,
86 | common: {
87 | name: `chunk-common`,
88 | minChunks: 2,
89 | priority: -20,
90 | chunks: 'initial',
91 | reuseExistingChunk: true
92 | },
93 | element: {
94 | name: 'element',
95 | test: /[\\/]node_modules[\\/]element-ui[\\/]/,
96 | chunks: 'initial',
97 | // 默认组的优先级为负数,以允许任何自定义缓存组具有更高的优先级(默认值为0)
98 | priority: -30
99 | }
100 | }
101 | })
102 | )
103 |
104 | // https://github.com/webpack-contrib/webpack-bundle-analyzer
105 | if (process.env.npm_config_report) {
106 | config
107 | .plugin('webpack-bundle-analyzer')
108 | .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
109 | }
110 | },
111 |
112 | configureWebpack: {
113 | plugins: [
114 | isProductionEnvFlag
115 | ? new PrerenderSPAPlugin({
116 | // Required - The path to the webpack-outputted app to prerender.
117 | staticDir: path.join(__dirname, 'dist'),
118 | // Required - Routes to render.
119 | routes: [
120 | '/',
121 | '/about/hrise',
122 | '/export/pdf',
123 | '/export/png',
124 | '/export/jpeg',
125 | '/export/ppt'
126 | ],
127 | render: new PrerenderSPAPlugin.PuppeteerRenderer({
128 | renderAfterTime: 5000,
129 | headless: true
130 | }),
131 | minify: {
132 | collapseWhitespace: true,
133 | keepClosingSlash: true,
134 | sortAttributes: true
135 | }
136 | })
137 | : () => { },
138 | isProductionEnvFlag ? new SizePlugin() : () => { }
139 | ]
140 | },
141 |
142 | // use thread-loader for babel & TS in production build
143 | // enabled by default if the machine has more than 1 cores
144 | parallel: require('os').cpus().length > 1,
145 |
146 | // options for the PWA plugin.
147 | // see => https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-pwa
148 | // https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin
149 | pwa: {
150 | name: 'H•rise',
151 | themeColor: '#4DBA87',
152 | msTileColor: '#000000',
153 | appleMobileWebAppCapable: 'yes',
154 | appleMobileWebAppStatusBarStyle: 'black',
155 | iconPaths: {
156 | favicon32: 'img/icons/favicon-32x32.png',
157 | favicon16: 'img/icons/favicon-16x16.png',
158 | appleTouchIcon: 'img/icons/apple-touch-icon.png',
159 | maskIcon: 'img/icons/safari-pinned-tab.svg',
160 | msTileImage: 'img/icons/mstile-150x150.png'
161 | },
162 | // configure the workbox plugin (GenerateSW or InjectManifest)
163 | workboxPluginMode: 'InjectManifest',
164 | workboxOptions: {
165 | // swSrc is required in InjectManifest mode.
166 | swSrc: 'public/service-worker.js'
167 | // ...other Workbox options...
168 | }
169 | },
170 |
171 | // configure webpack-dev-server behavior
172 | devServer: {
173 | open: process.platform === 'darwin',
174 | host: '0.0.0.0',
175 | port: 8080,
176 | https: false,
177 | hotOnly: false,
178 | // See https://github.com/vuejs/vue-cli/blob/dev/docs/cli-service.md#configuring-proxy
179 | proxy: null, // string | Object
180 | before: () => { }
181 | },
182 |
183 | // options for 3rd party plugins
184 | pluginOptions: {
185 | electronBuilder: {
186 | nodeIntegration: true,
187 | contextIsolation: false,
188 | builderOptions: {
189 | electronDownload: {
190 | mirror: "https://npm.taobao.org/mirrors/electron/"
191 | },
192 | "win": {
193 | icon: "./public/icon/logo256.ico"
194 | },
195 | productName: "HRise",
196 | appId: "com.rdtalk.mkdown",
197 | mac: {
198 | icon: "./public/icon/logo.icns"
199 | }
200 | }
201 | }
202 | }
203 | }
204 |
--------------------------------------------------------------------------------
/src/assets/styles/element/step.css:
--------------------------------------------------------------------------------
1 | .el-step {
2 | position: relative;
3 | -ms-flex-negative: 1;
4 | flex-shrink: 1;
5 | }
6 | .el-step:last-of-type .el-step__line {
7 | display: none;
8 | }
9 | .el-step:last-of-type.is-flex {
10 | -ms-flex-preferred-size: auto !important;
11 | flex-basis: auto !important;
12 | -ms-flex-negative: 0;
13 | flex-shrink: 0;
14 | -webkit-box-flex: 0;
15 | -ms-flex-positive: 0;
16 | flex-grow: 0;
17 | }
18 | .el-step:last-of-type .el-step__description,
19 | .el-step:last-of-type .el-step__main {
20 | padding-right: 0;
21 | }
22 | .el-step__head {
23 | position: relative;
24 | width: 100%;
25 | }
26 | .el-step__head.is-process {
27 | color: #303133;
28 | border-color: #303133;
29 | }
30 | .el-step__head.is-wait {
31 | color: #c0c4cc;
32 | border-color: #c0c4cc;
33 | }
34 | .el-step__head.is-success {
35 | color: #67c23a;
36 | border-color: #67c23a;
37 | }
38 | .el-step__head.is-error {
39 | color: #f56c6c;
40 | border-color: #f56c6c;
41 | }
42 | .el-step__head.is-finish {
43 | color: #000000;
44 | border-color: #000000;
45 | }
46 | .el-step__icon {
47 | position: relative;
48 | z-index: 1;
49 | display: -webkit-inline-box;
50 | display: -ms-inline-flexbox;
51 | display: inline-flex;
52 | -webkit-box-pack: center;
53 | -ms-flex-pack: center;
54 | justify-content: center;
55 | -webkit-box-align: center;
56 | -ms-flex-align: center;
57 | align-items: center;
58 | width: 24px;
59 | height: 24px;
60 | font-size: 14px;
61 | -webkit-box-sizing: border-box;
62 | box-sizing: border-box;
63 | background: #fff;
64 | -webkit-transition: 0.15s ease-out;
65 | transition: 0.15s ease-out;
66 | }
67 | .el-step__icon.is-text {
68 | border-radius: 50%;
69 | border: 2px solid;
70 | border-color: inherit;
71 | }
72 | .el-step__icon.is-icon {
73 | width: 40px;
74 | }
75 | .el-step__icon-inner {
76 | display: inline-block;
77 | -webkit-user-select: none;
78 | -moz-user-select: none;
79 | -ms-user-select: none;
80 | user-select: none;
81 | text-align: center;
82 | font-weight: 700;
83 | line-height: 1;
84 | color: inherit;
85 | }
86 | .el-step__icon-inner[class*='el-icon']:not(.is-status) {
87 | font-size: 25px;
88 | font-weight: 400;
89 | }
90 | .el-step__icon-inner.is-status {
91 | -webkit-transform: translateY(1px);
92 | transform: translateY(1px);
93 | }
94 | .el-step__line {
95 | position: absolute;
96 | border-color: inherit;
97 | background-color: #c0c4cc;
98 | }
99 | .el-step__line-inner {
100 | display: block;
101 | border-width: 1px;
102 | border-style: solid;
103 | border-color: inherit;
104 | -webkit-transition: 0.15s ease-out;
105 | transition: 0.15s ease-out;
106 | -webkit-box-sizing: border-box;
107 | box-sizing: border-box;
108 | width: 0;
109 | height: 0;
110 | }
111 | .el-step__main {
112 | white-space: normal;
113 | text-align: left;
114 | }
115 | .el-step__title {
116 | font-size: 16px;
117 | line-height: 38px;
118 | }
119 | .el-step__title.is-process {
120 | font-weight: 700;
121 | color: #303133;
122 | }
123 | .el-step__title.is-wait {
124 | color: #c0c4cc;
125 | }
126 | .el-step__title.is-success {
127 | color: #67c23a;
128 | }
129 | .el-step__title.is-error {
130 | color: #f56c6c;
131 | }
132 | .el-step__title.is-finish {
133 | color: #000000;
134 | }
135 | .el-step__description {
136 | padding-right: 10%;
137 | margin-top: -5px;
138 | font-size: 12px;
139 | line-height: 20px;
140 | font-weight: 400;
141 | }
142 | .el-step__description.is-process {
143 | color: #303133;
144 | }
145 | .el-step__description.is-wait {
146 | color: #c0c4cc;
147 | }
148 | .el-step__description.is-success {
149 | color: #67c23a;
150 | }
151 | .el-step__description.is-error {
152 | color: #f56c6c;
153 | }
154 | .el-step__description.is-finish {
155 | color: #000000;
156 | }
157 | .el-step.is-horizontal {
158 | display: inline-block;
159 | }
160 | .el-step.is-horizontal .el-step__line {
161 | height: 2px;
162 | top: 11px;
163 | left: 0;
164 | right: 0;
165 | }
166 | .el-step.is-vertical {
167 | display: -webkit-box;
168 | display: -ms-flexbox;
169 | display: flex;
170 | }
171 | .el-step.is-vertical .el-step__head {
172 | -webkit-box-flex: 0;
173 | -ms-flex-positive: 0;
174 | flex-grow: 0;
175 | width: 24px;
176 | }
177 | .el-step.is-vertical .el-step__main {
178 | padding-left: 10px;
179 | -webkit-box-flex: 1;
180 | -ms-flex-positive: 1;
181 | flex-grow: 1;
182 | }
183 | .el-step.is-vertical .el-step__title {
184 | line-height: 24px;
185 | padding-bottom: 8px;
186 | }
187 | .el-step.is-vertical .el-step__line {
188 | width: 2px;
189 | top: 0;
190 | bottom: 0;
191 | left: 11px;
192 | }
193 | .el-step.is-vertical .el-step__icon.is-icon {
194 | width: 24px;
195 | }
196 | .el-step.is-center .el-step__head,
197 | .el-step.is-center .el-step__main {
198 | text-align: center;
199 | }
200 | .el-step.is-center .el-step__description {
201 | padding-left: 20%;
202 | padding-right: 20%;
203 | }
204 | .el-step.is-center .el-step__line {
205 | left: 50%;
206 | right: -50%;
207 | }
208 | .el-step.is-simple {
209 | display: -webkit-box;
210 | display: -ms-flexbox;
211 | display: flex;
212 | -webkit-box-align: center;
213 | -ms-flex-align: center;
214 | align-items: center;
215 | }
216 | .el-step.is-simple .el-step__head {
217 | width: auto;
218 | font-size: 0;
219 | padding-right: 10px;
220 | }
221 | .el-step.is-simple .el-step__icon {
222 | background: 0 0;
223 | width: 16px;
224 | height: 16px;
225 | font-size: 12px;
226 | }
227 | .el-step.is-simple .el-step__icon-inner[class*='el-icon']:not(.is-status) {
228 | font-size: 18px;
229 | }
230 | .el-step.is-simple .el-step__icon-inner.is-status {
231 | -webkit-transform: scale(0.8) translateY(1px);
232 | transform: scale(0.8) translateY(1px);
233 | }
234 | .el-step.is-simple .el-step__main {
235 | position: relative;
236 | display: -webkit-box;
237 | display: -ms-flexbox;
238 | display: flex;
239 | -webkit-box-align: stretch;
240 | -ms-flex-align: stretch;
241 | align-items: stretch;
242 | -webkit-box-flex: 1;
243 | -ms-flex-positive: 1;
244 | flex-grow: 1;
245 | }
246 | .el-step.is-simple .el-step__title {
247 | font-size: 16px;
248 | line-height: 20px;
249 | }
250 | .el-step.is-simple:not(:last-of-type) .el-step__title {
251 | max-width: 50%;
252 | word-break: break-all;
253 | }
254 | .el-step.is-simple .el-step__arrow {
255 | -webkit-box-flex: 1;
256 | -ms-flex-positive: 1;
257 | flex-grow: 1;
258 | display: -webkit-box;
259 | display: -ms-flexbox;
260 | display: flex;
261 | -webkit-box-align: center;
262 | -ms-flex-align: center;
263 | align-items: center;
264 | -webkit-box-pack: center;
265 | -ms-flex-pack: center;
266 | justify-content: center;
267 | }
268 | .el-step.is-simple .el-step__arrow::after,
269 | .el-step.is-simple .el-step__arrow::before {
270 | content: '';
271 | display: inline-block;
272 | position: absolute;
273 | height: 15px;
274 | width: 1px;
275 | background: #c0c4cc;
276 | }
277 | .el-step.is-simple .el-step__arrow::before {
278 | -webkit-transform: rotate(-45deg) translateY(-4px);
279 | transform: rotate(-45deg) translateY(-4px);
280 | -webkit-transform-origin: 0 0;
281 | transform-origin: 0 0;
282 | }
283 | .el-step.is-simple .el-step__arrow::after {
284 | -webkit-transform: rotate(45deg) translateY(4px);
285 | transform: rotate(45deg) translateY(4px);
286 | -webkit-transform-origin: 100% 100%;
287 | transform-origin: 100% 100%;
288 | }
289 | .el-step.is-simple:last-of-type .el-step__arrow {
290 | display: none;
291 | }
292 |
--------------------------------------------------------------------------------
/src/pages/Main.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |