Compare commits

...

174 Commits

Author SHA1 Message Date
dependabot[bot]
467394e255 chore(deps): bump @angular/compiler from 14.2.12 to 15.2.0
Bumps [@angular/compiler](https://github.com/angular/angular/tree/HEAD/packages/compiler) from 14.2.12 to 15.2.0.
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/15.2.0/packages/compiler)

---
updated-dependencies:
- dependency-name: "@angular/compiler"
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-01 07:03:03 +00:00
dependabot[bot]
ba80d7bffa chore(deps-dev): bump typescript from 4.1.6 to 4.9.3
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.1.6 to 4.9.3.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v4.1.6...v4.9.3)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-02 01:15:55 +08:00
dependabot[bot]
5fe04e2490 chore(deps-dev): bump karma-jasmine from 4.0.2 to 5.1.0
Bumps [karma-jasmine](https://github.com/karma-runner/karma-jasmine) from 4.0.2 to 5.1.0.
- [Release notes](https://github.com/karma-runner/karma-jasmine/releases)
- [Changelog](https://github.com/karma-runner/karma-jasmine/blob/master/CHANGELOG.md)
- [Commits](https://github.com/karma-runner/karma-jasmine/compare/v4.0.2...v5.1.0)

---
updated-dependencies:
- dependency-name: karma-jasmine
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-02 01:11:48 +08:00
dependabot[bot]
77c0a5981f chore(deps-dev): bump eslint-plugin-import from 2.25.2 to 2.26.0
Bumps [eslint-plugin-import](https://github.com/import-js/eslint-plugin-import) from 2.25.2 to 2.26.0.
- [Release notes](https://github.com/import-js/eslint-plugin-import/releases)
- [Changelog](https://github.com/import-js/eslint-plugin-import/blob/main/CHANGELOG.md)
- [Commits](https://github.com/import-js/eslint-plugin-import/compare/v2.25.2...v2.26.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-import
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-02 01:10:12 +08:00
dependabot[bot]
4abd43fef0 chore(deps): bump zone.js from 0.11.8 to 0.12.0
Bumps [zone.js](https://github.com/angular/angular/tree/HEAD/packages/zone.js) from 0.11.8 to 0.12.0.
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/packages/zone.js/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/zone.js-0.12.0/packages/zone.js)

---
updated-dependencies:
- dependency-name: zone.js
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-02 01:09:57 +08:00
dependabot[bot]
45acb1e697 chore(deps-dev): bump @types/jasmine from 3.10.6 to 4.3.0
Bumps [@types/jasmine](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jasmine) from 3.10.6 to 4.3.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jasmine)

---
updated-dependencies:
- dependency-name: "@types/jasmine"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-02 01:09:44 +08:00
dependabot[bot]
7bca7a0ade chore(deps-dev): bump @types/node from 16.18.4 to 18.11.10
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 16.18.4 to 18.11.10.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-02 01:09:24 +08:00
dependabot[bot]
9515e6cc27 chore(deps): bump rxjs from 6.6.7 to 7.5.7
Bumps [rxjs](https://github.com/reactivex/rxjs) from 6.6.7 to 7.5.7.
- [Release notes](https://github.com/reactivex/rxjs/releases)
- [Changelog](https://github.com/ReactiveX/rxjs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/reactivex/rxjs/compare/6.6.7...7.5.7)

---
updated-dependencies:
- dependency-name: rxjs
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-02 01:08:16 +08:00
e3778e3dd3 ci: update config 2022-12-02 01:01:48 +08:00
95c4178a86 chore: remove build:prod 2022-12-02 00:57:07 +08:00
72d16a1996 chore: disable @angular-eslint/template/eqeqeq lint 2022-12-02 00:48:28 +08:00
3dc44b8a34 ci: update yml config 2022-12-02 00:38:32 +08:00
28f798df9d fix error 2022-12-02 00:33:54 +08:00
e770b2a7cf update 2022-12-02 00:01:47 +08:00
516874e9d5 update 2022-12-01 23:55:59 +08:00
7cba060b9f update to 14 2022-12-01 23:50:05 +08:00
548a2014d9 update to 13 2022-12-01 23:42:04 +08:00
716b7ced8b ng update @angular/core@12 @angular/cli@12 2022-12-01 22:54:02 +08:00
c4676fe232 ng update 2022-12-01 22:34:40 +08:00
dependabot[bot]
af1d07f25b chore(deps-dev): bump jasmine-core from 3.99.1 to 4.5.0
Bumps [jasmine-core](https://github.com/jasmine/jasmine) from 3.99.1 to 4.5.0.
- [Release notes](https://github.com/jasmine/jasmine/releases)
- [Changelog](https://github.com/jasmine/jasmine/blob/main/RELEASE.md)
- [Commits](https://github.com/jasmine/jasmine/compare/v3.99.1...v4.5.0)

---
updated-dependencies:
- dependency-name: jasmine-core
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-01 22:22:14 +08:00
dependabot[bot]
d689b9a6ef chore(deps-dev): bump eslint-plugin-import from 2.23.4 to 2.26.0
Bumps [eslint-plugin-import](https://github.com/import-js/eslint-plugin-import) from 2.23.4 to 2.26.0.
- [Release notes](https://github.com/import-js/eslint-plugin-import/releases)
- [Changelog](https://github.com/import-js/eslint-plugin-import/blob/main/CHANGELOG.md)
- [Commits](https://github.com/import-js/eslint-plugin-import/compare/v2.23.4...v2.26.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-import
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-01 22:22:02 +08:00
dependabot[bot]
186ed62d18 chore(deps-dev): bump @angular-eslint/template-parser
Bumps [@angular-eslint/template-parser](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/template-parser) from 13.0.1 to 15.1.0.
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/template-parser/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v15.1.0/packages/template-parser)

---
updated-dependencies:
- dependency-name: "@angular-eslint/template-parser"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-01 22:21:39 +08:00
da5900b45a fix: 工信部链接 2022-04-27 21:41:52 +08:00
dependabot[bot]
323bc86df1 chore(deps-dev): bump @angular-eslint/eslint-plugin
Bumps [@angular-eslint/eslint-plugin](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/eslint-plugin) from 12.6.1 to 13.1.0.
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/master/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v13.1.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@angular-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-20 15:38:16 +08:00
dependabot[bot]
0136ee4603 chore(deps-dev): bump @angular-eslint/schematics from 12.2.0 to 13.1.0
Bumps [@angular-eslint/schematics](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/schematics) from 12.2.0 to 13.1.0.
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/master/packages/schematics/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v13.1.0/packages/schematics)

---
updated-dependencies:
- dependency-name: "@angular-eslint/schematics"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-20 15:38:04 +08:00
dependabot[bot]
35bde50c55 chore(deps-dev): bump ts-node from 9.1.1 to 10.5.0
Bumps [ts-node](https://github.com/TypeStrong/ts-node) from 9.1.1 to 10.5.0.
- [Release notes](https://github.com/TypeStrong/ts-node/releases)
- [Commits](https://github.com/TypeStrong/ts-node/compare/v9.1.1...v10.5.0)

---
updated-dependencies:
- dependency-name: ts-node
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-19 23:31:42 +08:00
dependabot[bot]
d9fa76e9e2 chore(deps-dev): bump @angular-eslint/builder from 12.2.0 to 13.0.1
Bumps [@angular-eslint/builder](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/builder) from 12.2.0 to 13.0.1.
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/master/packages/builder/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v13.0.1/packages/builder)

---
updated-dependencies:
- dependency-name: "@angular-eslint/builder"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-19 23:25:15 +08:00
dependabot[bot]
28c03b962e chore(deps-dev): bump @angular-eslint/template-parser
Bumps [@angular-eslint/template-parser](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/template-parser) from 1.2.0 to 13.0.1.
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/master/packages/template-parser/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v13.0.1/packages/template-parser)

---
updated-dependencies:
- dependency-name: "@angular-eslint/template-parser"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-19 23:25:01 +08:00
dependabot[bot]
ae94a50a3e chore(deps-dev): bump @angular/language-service from 11.2.14 to 13.2.0
Bumps [@angular/language-service](https://github.com/angular/angular/tree/HEAD/packages/language-service) from 11.2.14 to 13.2.0.
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/master/docs/RELEASE_SCHEDULE.md)
- [Commits](https://github.com/angular/angular/commits/13.2.0/packages/language-service)

---
updated-dependencies:
- dependency-name: "@angular/language-service"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-19 23:24:47 +08:00
dependabot[bot]
840d827c80 chore(deps-dev): bump @types/node from 14.17.32 to 16.11.6 (#167) 2021-11-01 17:20:54 +00:00
dependabot[bot]
a909fd650c chore(deps-dev): bump @angular-eslint/eslint-plugin from 1.2.0 to 12.6.1
Bumps [@angular-eslint/eslint-plugin](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/eslint-plugin) from 1.2.0 to 12.6.1.
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/master/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v12.6.1/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@angular-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-11-01 12:09:40 -05:00
禾几海
3a0008650e Delete codeql-analysis.yml 2021-11-02 01:08:00 +08:00
dependabot[bot]
6468d0d8d4 chore(deps-dev): bump eslint-plugin-jsdoc from 35.1.2 to 35.4.1
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 35.1.2 to 35.4.1.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v35.1.2...v35.4.1)

---
updated-dependencies:
- dependency-name: eslint-plugin-jsdoc
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-19 11:25:32 +08:00
dependabot[bot]
969fda50f7 chore(deps-dev): bump @angular-eslint/schematics from 1.2.0 to 12.2.0
Bumps [@angular-eslint/schematics](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/schematics) from 1.2.0 to 12.2.0.
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/master/packages/schematics/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v12.2.0/packages/schematics)

---
updated-dependencies:
- dependency-name: "@angular-eslint/schematics"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-26 21:30:52 +08:00
dependabot[bot]
89d7c98c21 chore(deps-dev): bump @angular-eslint/builder from 2.0.2 to 12.2.0
Bumps [@angular-eslint/builder](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/builder) from 2.0.2 to 12.2.0.
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/master/packages/builder/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v12.2.0/packages/builder)

---
updated-dependencies:
- dependency-name: "@angular-eslint/builder"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-26 21:10:16 +08:00
dependabot[bot]
1ddb7c093f chore(deps-dev): bump eslint-plugin-import from 2.22.1 to 2.23.4
Bumps [eslint-plugin-import](https://github.com/benmosher/eslint-plugin-import) from 2.22.1 to 2.23.4.
- [Release notes](https://github.com/benmosher/eslint-plugin-import/releases)
- [Changelog](https://github.com/benmosher/eslint-plugin-import/blob/master/CHANGELOG.md)
- [Commits](https://github.com/benmosher/eslint-plugin-import/compare/v2.22.1...v2.23.4)

---
updated-dependencies:
- dependency-name: eslint-plugin-import
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-26 21:09:52 +08:00
dependabot[bot]
307e0aefa4 chore(deps-dev): bump jasmine-spec-reporter from 6.0.0 to 7.0.0
Bumps [jasmine-spec-reporter](https://github.com/bcaudan/jasmine-spec-reporter) from 6.0.0 to 7.0.0.
- [Release notes](https://github.com/bcaudan/jasmine-spec-reporter/releases)
- [Changelog](https://github.com/bcaudan/jasmine-spec-reporter/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bcaudan/jasmine-spec-reporter/compare/v6.0.0...v7.0.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-26 09:19:08 +08:00
dependabot[bot]
be312f4d80 chore(deps-dev): bump eslint-plugin-jsdoc from 32.2.0 to 35.1.2
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 32.2.0 to 35.1.2.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v32.2.0...v35.1.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-26 09:17:30 +08:00
dependabot[bot]
4bcc35b0b9 chore(deps-dev): bump @typescript-eslint/parser from 4.17.0 to 4.26.0
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 4.17.0 to 4.26.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.26.0/packages/parser)

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-26 09:16:41 +08:00
禾几海
2e7e835861 Merge pull request #94 from xiaohai2271/dependabot/npm_and_yarn/angular-eslint/eslint-plugin-template-2.0.2
chore(deps-dev): bump @angular-eslint/eslint-plugin-template from 1.2.0 to 2.0.2
2021-04-01 14:03:16 +08:00
禾几海
60a1ed9163 Merge pull request #93 from xiaohai2271/dependabot/npm_and_yarn/angular-eslint/builder-2.0.2
chore(deps-dev): bump @angular-eslint/builder from 1.2.0 to 2.0.2
2021-04-01 14:02:55 +08:00
dependabot[bot]
6b62c76064 chore(deps-dev): bump @angular-eslint/eslint-plugin-template
Bumps [@angular-eslint/eslint-plugin-template](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/eslint-plugin-template) from 1.2.0 to 2.0.2.
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/master/packages/eslint-plugin-template/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v2.0.2/packages/eslint-plugin-template)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-01 05:31:11 +00:00
dependabot[bot]
3915663838 chore(deps-dev): bump @angular-eslint/builder from 1.2.0 to 2.0.2
Bumps [@angular-eslint/builder](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/builder) from 1.2.0 to 2.0.2.
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/master/packages/builder/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v2.0.2/packages/builder)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-01 05:29:29 +00:00
禾几海
2532f8894e fix: 使用base64解密的异常 2021-03-16 21:39:56 +08:00
禾几海
defb5042ef feat: 使用base64加密localStorage信息 2021-03-16 21:15:45 +08:00
禾几海
2ba3d4ca1b refactor: 用LocalStorageService代理localStorage 2021-03-16 21:15:45 +08:00
禾几海
a2e80e6fdd refactor: 规范请求头的token 2021-03-16 21:15:45 +08:00
禾几海
5e29f42115 ci: Sync repository to gitee 2021-03-15 22:21:24 +08:00
禾几海
7c08892bac Merge pull request #88 from xiaohai2271/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-4.17.0
chore(deps-dev): bump @typescript-eslint/eslint-plugin from 4.3.0 to 4.17.0
2021-03-13 11:43:18 +08:00
禾几海
080338a824 Merge pull request #90 from xiaohai2271/dependabot/npm_and_yarn/eslint-plugin-prefer-arrow-1.2.3
chore(deps-dev): bump eslint-plugin-prefer-arrow from 1.2.2 to 1.2.3
2021-03-13 11:42:38 +08:00
dependabot[bot]
b88132fe60 chore(deps-dev): bump @typescript-eslint/eslint-plugin
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 4.3.0 to 4.17.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.17.0/packages/eslint-plugin)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-13 03:17:13 +00:00
dependabot[bot]
5484e058d7 chore(deps-dev): bump eslint-plugin-prefer-arrow from 1.2.2 to 1.2.3
Bumps [eslint-plugin-prefer-arrow](https://github.com/TristonJ/eslint-plugin-prefer-arrow) from 1.2.2 to 1.2.3.
- [Release notes](https://github.com/TristonJ/eslint-plugin-prefer-arrow/releases)
- [Commits](https://github.com/TristonJ/eslint-plugin-prefer-arrow/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-13 03:16:55 +00:00
禾几海
5d7852c54f Merge pull request #91 from xiaohai2271/dependabot/npm_and_yarn/typescript-eslint/parser-4.17.0
chore(deps-dev): bump @typescript-eslint/parser from 4.3.0 to 4.17.0
2021-03-13 11:16:04 +08:00
禾几海
00e10091f3 Merge pull request #92 from xiaohai2271/dependabot/npm_and_yarn/eslint-plugin-jsdoc-32.2.0
chore(deps-dev): bump eslint-plugin-jsdoc from 30.7.6 to 32.2.0
2021-03-13 11:15:41 +08:00
dependabot[bot]
78cd04a88d chore(deps-dev): bump eslint-plugin-jsdoc from 30.7.6 to 32.2.0
Bumps [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) from 30.7.6 to 32.2.0.
- [Release notes](https://github.com/gajus/eslint-plugin-jsdoc/releases)
- [Commits](https://github.com/gajus/eslint-plugin-jsdoc/compare/v30.7.6...v32.2.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-12 16:38:02 +00:00
dependabot[bot]
b61b56795e chore(deps-dev): bump @typescript-eslint/parser from 4.3.0 to 4.17.0
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 4.3.0 to 4.17.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.17.0/packages/parser)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-12 16:34:14 +00:00
禾几海
6d3abed910 Merge pull request #85 from xiaohai2271/dependabot/npm_and_yarn/karma-6.2.0
chore(deps-dev): bump karma from 5.2.3 to 6.2.0
2021-03-12 19:53:58 +08:00
dependabot[bot]
b55c03cbd5 chore(deps-dev): bump karma from 5.2.3 to 6.2.0
Bumps [karma](https://github.com/karma-runner/karma) from 5.2.3 to 6.2.0.
- [Release notes](https://github.com/karma-runner/karma/releases)
- [Changelog](https://github.com/karma-runner/karma/blob/master/CHANGELOG.md)
- [Commits](https://github.com/karma-runner/karma/compare/v5.2.3...v6.2.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-12 11:37:15 +00:00
禾几海
06d203b65f Merge pull request #86 from xiaohai2271/feature-tslint2eslint
Convert tslint to eslint
2021-03-12 18:00:05 +08:00
禾几海
754193d6ab chore: fix bug 2021-03-12 17:55:00 +08:00
禾几海
03cf88868e chore: Clean up eslint configuration files 2021-03-12 17:40:09 +08:00
禾几海
7f4e4568e5 style: update eslint of ban-types 2021-03-12 17:38:19 +08:00
禾几海
6bfb42e43d style: eslint of naming-convention 2021-03-12 17:30:05 +08:00
禾几海
7ea7f83227 style: eslint of member-ordering 2021-03-12 16:48:27 +08:00
禾几海
2037c95ffd chore(deps-dev): remove tslint dependences 2021-03-12 16:16:23 +08:00
禾几海
33d7bbaf43 style: eslint fix 2021-03-12 16:11:09 +08:00
禾几海
b65b25c1fa chore: ignore some code rules 2021-03-12 16:10:07 +08:00
禾几海
c13a7844a6 chore: convert tslint to eslint 2021-03-12 16:00:56 +08:00
禾几海
da30c3c51b chore(CodeQL): remove the unnecessary step 2021-03-12 15:25:55 +08:00
dependabot[bot]
33cc2ae8ec Merge pull request #82 from xiaohai2271/dependabot/npm_and_yarn/ng-zorro-antd-11.2.0 2021-03-11 16:19:23 +00:00
dependabot[bot]
51159a49b7 chore(deps): bump ng-zorro-antd from 10.1.2 to 11.2.0
Bumps [ng-zorro-antd](https://github.com/NG-ZORRO/ng-zorro-antd) from 10.1.2 to 11.2.0.
- [Release notes](https://github.com/NG-ZORRO/ng-zorro-antd/releases)
- [Changelog](https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NG-ZORRO/ng-zorro-antd/compare/10.1.2...11.2.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-11 16:12:16 +00:00
禾几海
dc6bf57587 chore(deps): 依赖超前的问题 2021-03-12 00:10:17 +08:00
禾几海
ea83364c12 fix(common-table): common-table 在移动设备上部分内容不显示 2021-03-11 21:00:10 +08:00
禾几海
1c5423ebb2 chore(deps): delete package-lock.json file
[skip ci]
2021-03-11 20:42:29 +08:00
禾几海
02718d23db fix(common-table): 修复table组件无法切换页面 2021-03-11 20:33:06 +08:00
禾几海
288eb358a3 chore(deps): ignore file package-lock.json
[skip ci]
2021-03-11 20:33:06 +08:00
禾几海
6e5282daef Merge pull request #74 from xiaohai2271/dependabot/npm_and_yarn/angular/cli-11.1.2
chore(deps-dev): bump @angular/cli from 11.0.5 to 11.1.2
2021-02-28 22:26:26 +08:00
dependabot[bot]
8e93e84634 chore(deps-dev): bump @angular/cli from 11.0.5 to 11.1.2
Bumps [@angular/cli](https://github.com/angular/angular-cli) from 11.0.5 to 11.1.2.
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Commits](https://github.com/angular/angular-cli/compare/v11.0.5...v11.1.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-02-01 05:43:48 +00:00
禾几海
4596bbe1d2 Merge pull request #64 from xiaohai2271/dependabot/npm_and_yarn/angular/cli-11.0.5
chore(deps-dev): bump @angular/cli from 11.0.2 to 11.0.5
2021-01-20 22:13:16 +08:00
dependabot[bot]
08e98c5a69 chore(deps-dev): bump @angular/cli from 11.0.2 to 11.0.5
Bumps [@angular/cli](https://github.com/angular/angular-cli) from 11.0.2 to 11.0.5.
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Commits](https://github.com/angular/angular-cli/compare/v11.0.2...v11.0.5)

Signed-off-by: dependabot[bot] <support@github.com>
2021-01-01 05:46:40 +00:00
禾几海
5cf648da67 Merge pull request #54 from xiaohai2271/dependabot/npm_and_yarn/zone.js-0.11.3
chore(deps): bump zone.js from 0.11.2 to 0.11.3
2020-12-02 10:59:49 +08:00
禾几海
7eac8dbdde Merge pull request #56 from xiaohai2271/dependabot/npm_and_yarn/types/node-14.14.10
chore(deps-dev): bump @types/node from 14.14.6 to 14.14.10
2020-12-02 10:56:40 +08:00
禾几海
cbf688fb6c Merge pull request #57 from xiaohai2271/dependabot/npm_and_yarn/types/jasmine-3.6.2
chore(deps-dev): bump @types/jasmine from 3.6.0 to 3.6.2
2020-12-02 10:56:06 +08:00
dependabot[bot]
4d9acbe51b chore(deps-dev): bump @types/jasmine from 3.6.0 to 3.6.2
Bumps [@types/jasmine](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jasmine) from 3.6.0 to 3.6.2.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jasmine)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-01 05:45:32 +00:00
dependabot[bot]
19a49f2c69 chore(deps-dev): bump @types/node from 14.14.6 to 14.14.10
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.6 to 14.14.10.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-01 05:44:08 +00:00
dependabot[bot]
5941fb41e9 chore(deps): bump zone.js from 0.11.2 to 0.11.3
Bumps [zone.js](https://github.com/angular/angular/tree/HEAD/packages/zone.js) from 0.11.2 to 0.11.3.
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/master/packages/zone.js/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/zone.js-0.11.3/packages/zone.js)

Signed-off-by: dependabot[bot] <support@github.com>
2020-12-01 05:40:19 +00:00
禾几海
6a5f1fdefd fix: 无法发布文章的bug 2020-11-29 00:52:36 +08:00
禾几海
68b380906a style: format project
[skip ci]
2020-11-22 22:00:09 +08:00
dependabot[bot]
ad3759afb3 Merge pull request #53 from xiaohai2271/dependabot/npm_and_yarn/ng-zorro-antd-10.1.2 2020-11-22 11:58:10 +00:00
禾几海
a45e558662 fix: 更新依赖导致的错误异常 2020-11-22 19:53:11 +08:00
dependabot[bot]
6d9aa66536 chore(deps): bump ng-zorro-antd from 9.3.0 to 10.1.2
Bumps [ng-zorro-antd](https://github.com/NG-ZORRO/ng-zorro-antd) from 9.3.0 to 10.1.2.
- [Release notes](https://github.com/NG-ZORRO/ng-zorro-antd/releases)
- [Changelog](https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NG-ZORRO/ng-zorro-antd/compare/9.3.0...10.1.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-22 08:47:52 +00:00
禾几海
27fc65b759 chore(deps): update dependency
[skip ci]
2020-11-22 16:43:49 +08:00
禾几海
75b56c604a Merge branch 'master' of https://github.com/xiaohai2271/blog-frontEnd 2020-11-22 16:27:48 +08:00
禾几海
4b1b44a125 Merge pull request #51 from xiaohai2271/dependabot/npm_and_yarn/types/node-14.14.6
chore(deps-dev): bump @types/node from 14.14.3 to 14.14.6
2020-11-22 16:25:33 +08:00
禾几海
53fb39678a Merge pull request #51 from xiaohai2271/dependabot/npm_and_yarn/types/node-14.14.6
chore(deps-dev): bump @types/node from 14.14.3 to 14.14.6
2020-11-22 15:55:26 +08:00
禾几海
a5ae7b8465 ci: skip ci action situation
[skip ci]
2020-11-14 21:39:42 +08:00
禾几海
39a8c33be4 ci: skip ci action situation
[skip ci]
2020-11-14 21:35:14 +08:00
dependabot[bot]
274fdf0fad chore(deps-dev): bump @types/node from 14.14.3 to 14.14.6
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.3 to 14.14.6.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-02 07:51:01 +00:00
dependabot[bot]
19fd3e55f7 Merge pull request #50 from xiaohai2271/dependabot/npm_and_yarn/angular/language-service-10.2.1 2020-11-02 07:17:02 +00:00
dependabot[bot]
5c274705b0 chore(deps-dev): bump @angular/language-service from 10.2.0 to 10.2.1
Bumps [@angular/language-service](https://github.com/angular/angular/tree/HEAD/packages/language-service) from 10.2.0 to 10.2.1.
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/master/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/10.2.1/packages/language-service)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-02 07:09:38 +00:00
dependabot[bot]
e0d6943c96 Merge pull request #49 from xiaohai2271/dependabot/npm_and_yarn/typescript-4.0.5 2020-11-02 07:08:17 +00:00
dependabot[bot]
a96313867e Merge pull request #48 from xiaohai2271/dependabot/npm_and_yarn/vditor-3.6.0 2020-11-02 07:04:00 +00:00
禾几海
ae86991fe8 Update dependabot.yml 2020-11-02 15:03:54 +08:00
dependabot[bot]
3d0c806fd2 chore(deps-dev): bump typescript from 4.0.3 to 4.0.5
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.0.3 to 4.0.5.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v4.0.3...v4.0.5)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-02 07:00:08 +00:00
dependabot[bot]
2997fed054 chore(deps): bump vditor from 3.5.5 to 3.6.0
Bumps [vditor](https://github.com/Vanessa219/vditor) from 3.5.5 to 3.6.0.
- [Release notes](https://github.com/Vanessa219/vditor/releases)
- [Changelog](https://github.com/Vanessa219/vditor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Vanessa219/vditor/compare/v3.5.5...v3.6.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-02 06:56:23 +00:00
禾几海
beb0d27532 Merge pull request #43 from xiaohai2271/dependabot/npm_and_yarn/angular-devkit/build-angular-0.1002.0
chore(deps-dev): bump @angular-devkit/build-angular from 0.1001.7 to 0.1002.0
2020-10-27 22:56:16 +08:00
dependabot[bot]
f05a0cf2b3 chore(deps-dev): bump @angular-devkit/build-angular
Bumps [@angular-devkit/build-angular](https://github.com/angular/angular-cli) from 0.1001.7 to 0.1002.0.
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Commits](https://github.com/angular/angular-cli/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-26 14:45:58 +00:00
禾几海
8917e2fe5a Merge pull request #44 from xiaohai2271/dependabot/npm_and_yarn/types/node-14.14.3
chore(deps-dev): bump @types/node from 14.14.0 to 14.14.3
2020-10-26 22:43:39 +08:00
禾几海
8c8cd95c96 Merge pull request #45 from xiaohai2271/dependabot/npm_and_yarn/angular/language-service-10.2.0
chore(deps-dev): bump @angular/language-service from 10.1.6 to 10.2.0
2020-10-26 22:42:26 +08:00
dependabot[bot]
4472c4bcdc chore(deps-dev): bump @types/node from 14.14.0 to 14.14.3
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.0 to 14.14.3.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-26 11:20:49 +00:00
dependabot[bot]
6d0fc77ec1 chore(deps-dev): bump @angular/language-service from 10.1.6 to 10.2.0
Bumps [@angular/language-service](https://github.com/angular/angular/tree/HEAD/packages/language-service) from 10.1.6 to 10.2.0.
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/master/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/10.2.0/packages/language-service)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-26 11:20:12 +00:00
禾几海
845972df71 Merge pull request #46 from xiaohai2271/dependabot/npm_and_yarn/types/jasmine-3.6.0
chore(deps-dev): bump @types/jasmine from 3.5.14 to 3.6.0
2020-10-26 19:18:55 +08:00
禾几海
ca9fcddd31 Merge pull request #47 from xiaohai2271/dependabot/npm_and_yarn/angular/cli-10.2.0
chore(deps-dev): bump @angular/cli from 10.1.7 to 10.2.0
2020-10-26 19:18:27 +08:00
dependabot[bot]
425e75cccf chore(deps-dev): bump @angular/cli from 10.1.7 to 10.2.0
Bumps [@angular/cli](https://github.com/angular/angular-cli) from 10.1.7 to 10.2.0.
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Commits](https://github.com/angular/angular-cli/compare/v10.1.7...v10.2.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-26 06:45:18 +00:00
dependabot[bot]
2fefcb1ce7 chore(deps-dev): bump @types/jasmine from 3.5.14 to 3.6.0
Bumps [@types/jasmine](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jasmine) from 3.5.14 to 3.6.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jasmine)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-26 06:43:17 +00:00
dependabot[bot]
12a7db276d Merge pull request #42 from xiaohai2271/dependabot/npm_and_yarn/types/node-14.14.0 2020-10-20 15:04:06 +00:00
dependabot[bot]
93b9e7e6eb chore(deps-dev): bump @types/node from 14.11.10 to 14.14.0
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.11.10 to 14.14.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-20 14:56:40 +00:00
dependabot[bot]
4e18c7108b Merge pull request #41 from xiaohai2271/dependabot/npm_and_yarn/tslib-2.0.3 2020-10-20 14:55:19 +00:00
dependabot[bot]
a7711a5833 chore(deps): bump tslib from 2.0.1 to 2.0.3
Bumps [tslib](https://github.com/Microsoft/tslib) from 2.0.1 to 2.0.3.
- [Release notes](https://github.com/Microsoft/tslib/releases)
- [Commits](https://github.com/Microsoft/tslib/compare/2.0.1...2.0.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-20 04:59:24 +00:00
禾几海
f7867cb9d9 Merge pull request #39 from xiaohai2271/dependabot/npm_and_yarn/zone.js-0.11.2
chore(deps): bump zone.js from 0.11.1 to 0.11.2
2020-10-20 12:55:17 +08:00
禾几海
83d117856c Merge pull request #35 from xiaohai2271/dependabot/npm_and_yarn/jasmine-spec-reporter-6.0.0
chore(deps-dev): bump jasmine-spec-reporter from 5.0.2 to 6.0.0
2020-10-20 12:54:23 +08:00
禾几海
f829b269e9 Merge pull request #32 from xiaohai2271/dependabot/npm_and_yarn/codelyzer-6.0.1
chore(deps-dev): bump codelyzer from 6.0.0 to 6.0.1
2020-10-20 12:53:34 +08:00
dependabot[bot]
ea5e6cd8d7 chore(deps): bump zone.js from 0.11.1 to 0.11.2
Bumps [zone.js](https://github.com/angular/angular/tree/HEAD/packages/zone.js) from 0.11.1 to 0.11.2.
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/master/packages/zone.js/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/zone.js-0.11.2/packages/zone.js)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-19 07:26:07 +00:00
dependabot[bot]
a6a34113c9 chore(deps-dev): bump codelyzer from 6.0.0 to 6.0.1
Bumps [codelyzer](https://github.com/mgechev/codelyzer) from 6.0.0 to 6.0.1.
- [Release notes](https://github.com/mgechev/codelyzer/releases)
- [Changelog](https://github.com/mgechev/codelyzer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mgechev/codelyzer/commits/6.0.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-19 07:24:54 +00:00
dependabot[bot]
cf323dfa20 chore(deps-dev): bump jasmine-spec-reporter from 5.0.2 to 6.0.0
Bumps [jasmine-spec-reporter](https://github.com/bcaudan/jasmine-spec-reporter) from 5.0.2 to 6.0.0.
- [Release notes](https://github.com/bcaudan/jasmine-spec-reporter/releases)
- [Changelog](https://github.com/bcaudan/jasmine-spec-reporter/blob/master/CHANGELOG.md)
- [Commits](https://github.com/bcaudan/jasmine-spec-reporter/compare/v5.0.2...v6.0.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-19 07:24:21 +00:00
禾几海
0dd3e756b6 Merge pull request #33 from xiaohai2271/dependabot/npm_and_yarn/angular-devkit/build-angular-0.1001.7
chore(deps-dev): bump @angular-devkit/build-angular from 0.1001.1 to 0.1001.7
2020-10-19 15:06:49 +08:00
禾几海
f389bebf44 Merge pull request #31 from xiaohai2271/dependabot/npm_and_yarn/karma-5.2.3
chore(deps-dev): bump karma from 5.2.2 to 5.2.3
2020-10-19 15:03:35 +08:00
禾几海
88f7e8111d Merge pull request #28 from xiaohai2271/dependabot/npm_and_yarn/typescript-4.0.3
chore(deps-dev): bump typescript from 4.0.2 to 4.0.3
2020-10-19 15:02:12 +08:00
禾几海
19d556f2f3 Revert "Update test.yml"
This reverts commit f9a4c8d6
2020-10-19 14:52:51 +08:00
禾几海
152f10b449 Merge branch 'master' into dependabot/npm_and_yarn/angular-devkit/build-angular-0.1001.7 2020-10-19 14:49:01 +08:00
禾几海
f2b95c3510 Merge pull request #34 from xiaohai2271/dependabot/npm_and_yarn/angular/language-service-10.1.6
chore(deps-dev): bump @angular/language-service from 10.1.1 to 10.1.6
2020-10-19 14:47:03 +08:00
禾几海
a41a7e9eed Merge pull request #36 from xiaohai2271/dependabot/npm_and_yarn/angular/cli-10.1.7
chore(deps-dev): bump @angular/cli from 10.1.1 to 10.1.7
2020-10-19 14:46:05 +08:00
禾几海
9b656716dc Merge pull request #37 from xiaohai2271/dependabot/npm_and_yarn/vditor-3.5.5
chore(deps): bump vditor from 3.5.4 to 3.5.5
2020-10-19 14:41:20 +08:00
禾几海
9d6af4dc92 Merge pull request #38 from xiaohai2271/dependabot/npm_and_yarn/types/node-14.11.10
chore(deps-dev): bump @types/node from 14.10.2 to 14.11.10
2020-10-19 14:40:22 +08:00
dependabot[bot]
77d54fa7e0 chore(deps-dev): bump @types/node from 14.10.2 to 14.11.10
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.10.2 to 14.11.10.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-19 06:31:37 +00:00
禾几海
f9a4c8d629 Update test.yml 2020-10-16 19:33:36 +08:00
dependabot[bot]
23f67e23b2 chore(deps): bump vditor from 3.5.4 to 3.5.5
Bumps [vditor](https://github.com/Vanessa219/vditor) from 3.5.4 to 3.5.5.
- [Release notes](https://github.com/Vanessa219/vditor/releases)
- [Changelog](https://github.com/Vanessa219/vditor/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Vanessa219/vditor/compare/v3.5.4...v3.5.5)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-16 11:22:36 +00:00
dependabot[bot]
0b81661b76 chore(deps-dev): bump @angular/cli from 10.1.1 to 10.1.7
Bumps [@angular/cli](https://github.com/angular/angular-cli) from 10.1.1 to 10.1.7.
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Commits](https://github.com/angular/angular-cli/compare/v10.1.1...v10.1.7)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-16 11:21:04 +00:00
dependabot[bot]
29930ccec0 chore(deps-dev): bump @angular/language-service from 10.1.1 to 10.1.6
Bumps [@angular/language-service](https://github.com/angular/angular/tree/HEAD/packages/language-service) from 10.1.1 to 10.1.6.
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/master/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/10.1.6/packages/language-service)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-16 11:20:03 +00:00
dependabot[bot]
b59b30b32c chore(deps-dev): bump @angular-devkit/build-angular
Bumps [@angular-devkit/build-angular](https://github.com/angular/angular-cli) from 0.1001.1 to 0.1001.7.
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Commits](https://github.com/angular/angular-cli/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-16 11:19:38 +00:00
禾几海
6f1dd5cba5 Update dependabot.yml 2020-10-16 19:19:23 +08:00
dependabot[bot]
20ec1552a6 chore(deps-dev): bump karma from 5.2.2 to 5.2.3
Bumps [karma](https://github.com/karma-runner/karma) from 5.2.2 to 5.2.3.
- [Release notes](https://github.com/karma-runner/karma/releases)
- [Changelog](https://github.com/karma-runner/karma/blob/master/CHANGELOG.md)
- [Commits](https://github.com/karma-runner/karma/compare/v5.2.2...v5.2.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-16 11:15:42 +00:00
dependabot[bot]
c388297f12 chore(deps-dev): bump typescript from 4.0.2 to 4.0.3
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.0.2 to 4.0.3.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v4.0.2...v4.0.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-16 11:14:21 +00:00
禾几海
dcbd47332e Create dependabot.yml 2020-10-16 19:12:32 +08:00
禾几海
c8323a965c fix: 订阅未取消引发的异常 2020-10-10 00:33:44 +08:00
禾几海
086e476da8 fix: token校验失败时移除token 2020-10-10 00:26:00 +08:00
禾几海
a4fa38deee fix: 空值异常 2020-10-10 00:25:22 +08:00
禾几海
b63697f717 refactor: 删除残留代码 2020-10-10 00:24:46 +08:00
禾几海
1f2c925b45 Merge pull request #27 from xiaohai2271/refactor-mdEditor
切换markdown编辑器为vditor
2020-10-09 19:33:06 +08:00
禾几海
c67d7b7593 feat: 配置文件上传 2020-10-09 18:59:42 +08:00
禾几海
7f418c7f95 feat: 锚点 2020-10-09 17:53:14 +08:00
禾几海
2ce76455a4 feat: 锚点 2020-10-09 17:52:42 +08:00
禾几海
7d181b71a9 fix: 代码lint 2020-10-09 17:29:54 +08:00
禾几海
91921bda96 feat: 配置markdown预览 2020-10-09 17:29:24 +08:00
禾几海
5b96b66af5 feat: 配置markdown编辑器 2020-10-09 16:37:58 +08:00
禾几海
4cf1d4130b refactor: 切换markdown编辑器到vditor 2020-10-09 00:26:07 +08:00
禾几海
dfd609ded3 ci: 调整ci 2020-10-08 11:32:46 +08:00
禾几海
1d994d16b1 ci: 调整测试ci 2020-10-08 11:22:47 +08:00
禾几海
23aec69b4f chore: 移除无效引用 2020-10-08 10:56:10 +08:00
禾几海
322c52ce86 refactor: lint检查 2020-10-07 23:45:53 +08:00
禾几海
410013779e Create codeql-analysis.yml 2020-10-03 18:12:10 +08:00
禾几海
b00c6e5a2b chore: 更新依赖版本 2020-09-16 16:22:06 +08:00
禾几海
13c0529def feat: Upload a Build Artifact 2020-09-13 15:40:37 +08:00
禾几海
d59eb47f03 Merge branch 'dev' 2020-09-13 15:33:42 +08:00
禾几海
25cf2290b9 refactor: 修改copyright 2020-09-13 15:33:16 +08:00
禾几海
130e135e03 Merge branch 'dev' 2020-09-13 12:24:17 +08:00
禾几海
f8e30d8823 refactor: 修改copyright 2020-09-13 12:22:03 +08:00
禾几海
b42d3b7d33 Update issue templates 2020-09-07 12:20:57 +08:00
禾几海
138b93da09 fix(commonTable): 请求参数的传递 2020-09-05 17:19:07 +08:00
禾几海
072eaa12e8 fix: 参数异常 2020-09-05 17:09:10 +08:00
禾几海
d263cc132d feat(访客管理): 添加对位置信息的展示 2020-09-05 16:54:06 +08:00
禾几海
f044e9d01b fix(commonTable): 未设置action列导致的空值异常 2020-09-04 08:24:17 +08:00
禾几海
c14f495f8e chore: 本地存储favicon.ico和logo图片 2020-08-31 22:17:36 +08:00
禾几海
ab8a9154ec remove console.log() 2020-08-28 22:32:01 +08:00
526 changed files with 1962 additions and 94847 deletions

87
.eslintrc.json Normal file
View File

@@ -0,0 +1,87 @@
{
"root": true,
"ignorePatterns": [
"projects/**/*"
],
"overrides": [
{
"files": [
"*.ts"
],
"parserOptions": {
"project": [
"tsconfig.json",
"e2e/tsconfig.json"
],
"createDefaultProgram": true
},
"extends": [
"plugin:@angular-eslint/ng-cli-compat",
"plugin:@angular-eslint/ng-cli-compat--formatting-add-on",
"plugin:@angular-eslint/template/process-inline-templates"
],
"rules": {
"prefer-arrow/prefer-arrow-functions": [
"off"
],
"@typescript-eslint/ban-types": [
"error",
{
"types": {
"Object": {
"message": "Use {} instead",
"fixWith": "{}"
},
"{}": false
}
}
],
"@angular-eslint/component-selector": [
"off",
{
"type": "element",
"prefix": "app",
"style": "kebab-case"
}
],
"@angular-eslint/directive-selector": [
"off",
{
"type": "attribute",
"prefix": "app",
"style": "camelCase"
}
],
"@typescript-eslint/explicit-member-accessibility": [
"off",
{
"accessibility": "explicit"
}
],
"@typescript-eslint/no-inferrable-types": [
"off",
{
"ignoreParameters": true
}
],
"arrow-parens": [
"off",
"always"
],
"import/order": "off"
}
},
{
"files": [
"*.html"
],
"extends": [
"plugin:@angular-eslint/template/recommended"
],
"rules": {
"@angular-eslint/template/eqeqeq": "off"
}
}
]
}

38
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

12
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,12 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "npm" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "monthly"
open-pull-requests-limit: 15

View File

@@ -1,6 +1,3 @@
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: Build
on:
@@ -9,33 +6,51 @@ on:
jobs:
build:
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '.md')" # 如果 commit 信息包含以下关键字则跳过该任务
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js 12.x
- name: Sync to Gitee
uses: x-dr/sync-repo-to-gitee@master
env:
# 在 Settings->Secrets 配置 GITEE_KEY
SSH_KEY: ${{ secrets.GITEE_KEY }}
with:
# 注意替换为你的 GitHub 源仓库地址
github-repo: "git@github.com:xiaohai2271/blog-frontEnd.git"
# 注意替换为你的 Gitee 目标仓库地址
gitee-repo: "git@gitee.com:xiaohai2271/blog-frontEnd.git"
- name: Use Node.js 16.x
uses: actions/setup-node@v1
with:
node-version: '12.x'
- run: npm install -g @angular/cli
- run: bash build.sh
node-version: '16.x'
- run: npm install
- run: npm run lint && npm run build
- run: cd dist/index/ && tar -cf index.tar ./* && mv index.tar ../../
- name: SCP
uses: appleboy/scp-action@master
- name: Upload a Build Artifact
uses: actions/upload-artifact@v2.1.4
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
password: ${{ secrets.SSH_PASSWORD }}
port: ${{ secrets.SSH_PORT }}
source: "index.tar"
target: "/www/wwwroot/www.celess.cn"
name: dist
path: ./dist/index/*
- name: Run SSH command
uses: garygrossgarten/github-action-ssh@v0.5.0
with:
command: cd /www/wwwroot/www.celess.cn && bash deploy.sh
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
password: ${{ secrets.SSH_PASSWORD }}
port: ${{ secrets.SSH_PORT }}
# - name: SCP
# uses: appleboy/scp-action@master
# with:
# host: ${{ secrets.SSH_HOST }}
# username: ${{ secrets.SSH_USERNAME }}
# password: ${{ secrets.SSH_PASSWORD }}
# port: ${{ secrets.SSH_PORT }}
# source: "index.tar"
# target: "/www/wwwroot/www.celess.cn"
# - name: Run SSH command
# uses: garygrossgarten/github-action-ssh@v0.5.0
# with:
# command: cd /www/wwwroot/www.celess.cn && bash deploy.sh
# host: ${{ secrets.SSH_HOST }}
# username: ${{ secrets.SSH_USERNAME }}
# password: ${{ secrets.SSH_PASSWORD }}
# port: ${{ secrets.SSH_PORT }}

View File

@@ -1,20 +0,0 @@
name: test
on:
push:
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js 12.x
uses: actions/setup-node@v1
with:
node-version: '12.x'
- run: npm install -g @angular/cli
- run: bash build.sh

19
.github/workflows/test.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
name: Test
on:
push:
pull_request:
branches: [ master ]
jobs:
build:
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '.md')" # 如果 commit 信息包含以下关键字则跳过该任务
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js 16.x
uses: actions/setup-node@v1
with:
node-version: '16.x'
- run: npm install
- run: npm run lint && npm run build

2
.gitignore vendored
View File

@@ -1,4 +1,6 @@
/.angular/cache
dist
node_modules
.idea
.editorconfig
package-lock.json

View File

@@ -22,7 +22,7 @@
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": false,
"aot": true,
"assets": [
"src/favicon.ico",
"src/assets",
@@ -34,18 +34,11 @@
"src/manifest.webmanifest"
],
"styles": [
"src/assets/editor/css/editormd.css",
"./node_modules/ng-zorro-antd/ng-zorro-antd.min.css",
"src/styles.less"
],
"scripts": [
"./node_modules/jquery/dist/jquery.min.js",
"src/assets/editor/lib/marked.min.js",
"src/assets/editor/lib/prettify.min.js",
"src/assets/editor/lib/underscore.min.js",
"src/assets/editor/lib/flowchart.min.js",
"src/assets/editor/lib/jquery.flowchart.min.js",
"src/assets/editor/editormd.min.js"
"./node_modules/jquery/dist/jquery.min.js"
]
},
"configurations": {
@@ -59,7 +52,6 @@
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
@@ -119,15 +111,11 @@
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"builder": "@angular-eslint/builder:lint",
"options": {
"tsConfig": [
"tsconfig.app.json",
"tsconfig.spec.json",
"e2e/tsconfig.json"
],
"exclude": [
"**/node_modules/**"
"lintFilePatterns": [
"src/**/*.ts",
"src/**/*.html"
]
}
},
@@ -146,7 +134,6 @@
}
}
},
"defaultProject": "index",
"cli": {
"analytics": false
}

View File

@@ -1,40 +0,0 @@
#!/bin/sh
basePath=$(pwd)
$(hash node 2>/dev/null)
if ! [ $? ]; then
echo -e "\t\t请先安装nodejs -------> https://nodejs.org/"
exit 1
else
echo -e "\t\t nodejs\t\t $(node --version)"
fi
$(hash npm 2>/dev/null)
if ! [ $? ]; then
echo -e "\t\t Can't find command npm"
exit 1
else
echo -e "\t\t npm\t\t $(npm --version)"
fi
$(hash ng 2>/dev/null)
if ! [ $? ]; then
echo -e "\t\tinstall angular cli to build the project"
npm install -g @angular/cli
else
echo -e "\t\t angular-cli\t\t $(ng --version)"
fi
# index
echo -e "\t\tBuild for index page "
npm install && ng build --prod
cd ./dist/index/ && tar -cf index.tar ./* && cp index.tar $basePath
#cd "$basePath"
## admin
#echo -e "\t\tBuild for admin page "
#cd $basePath/admin && npm install && ng build --prod
#cd ./dist/admin/ && sed '6s/\"\/\"/\"\/admin\/\"/g' index.html > index.txt && cp index.txt index.html
# cd .. && tar -cf admin.tar ./admin/ && cp admin.tar $basePath

17483
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -11,41 +11,52 @@
},
"private": true,
"dependencies": {
"@angular/animations": "^10.0.3",
"@angular/common": "^10.0.3",
"@angular/compiler": "^10.0.3",
"@angular/core": "^10.0.3",
"@angular/forms": "^10.0.3",
"@angular/platform-browser": "^10.0.3",
"@angular/platform-browser-dynamic": "^10.0.3",
"@angular/router": "^10.0.3",
"@angular/service-worker": "^10.0.3",
"@angular/animations": "^14.2.12",
"@angular/common": "^14.2.12",
"@angular/compiler": "^15.2.0",
"@angular/core": "^14.2.12",
"@angular/forms": "^14.2.12",
"@angular/platform-browser": "^14.2.12",
"@angular/platform-browser-dynamic": "^14.2.12",
"@angular/router": "^14.2.12",
"@angular/service-worker": "^14.2.12",
"jquery": "^3.5.1",
"ng-zorro-antd": "^9.3.0",
"nrm": "^1.2.1",
"rxjs": "^6.6.0",
"tslib": "^2.0.0",
"zone.js": "^0.10.3"
"js-base64": "^3.6.0",
"ng-zorro-antd": "^14.2.1",
"rxjs": "^7.5.7",
"tslib": "^2.0.3",
"vditor": "~3.6.3",
"zone.js": "^0.12.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^0.1000.2",
"@angular/cli": "^10.0.2",
"@angular/compiler-cli": "^10.0.3",
"@angular/language-service": "^10.0.3",
"@types/jasmine": "^3.5.11",
"@angular-devkit/build-angular": "^14.2.10",
"@angular-eslint/builder": "14.4.0",
"@angular-eslint/eslint-plugin": "14.4.0",
"@angular-eslint/eslint-plugin-template": "14.4.0",
"@angular-eslint/schematics": "14.4.0",
"@angular-eslint/template-parser": "15.1.0",
"@angular/cli": "^14.2.10",
"@angular/compiler-cli": "^14.2.12",
"@angular/language-service": "^14.2.12",
"@types/jasmine": "^4.3.0",
"@types/jasminewd2": "~2.0.3",
"@types/node": "^14.0.22",
"codelyzer": "^6.0.0",
"jasmine-core": "^3.5.0",
"jasmine-spec-reporter": "^5.0.2",
"karma": "^5.1.0",
"@types/node": "^18.11.10",
"@typescript-eslint/eslint-plugin": "^5.36.2",
"@typescript-eslint/parser": "^5.36.2",
"codelyzer": "^6.0.1",
"eslint": "^8.23.0",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-jsdoc": "^39.6.4",
"eslint-plugin-prefer-arrow": "1.2.3",
"jasmine-core": "^4.5.0",
"jasmine-spec-reporter": "^7.0.0",
"karma": "^6.2.0",
"karma-chrome-launcher": "^3.1.0",
"karma-coverage-istanbul-reporter": "^3.0.3",
"karma-jasmine": "^3.3.1",
"karma-jasmine": "^5.1.0",
"karma-jasmine-html-reporter": "^1.5.4",
"protractor": "^7.0.0",
"ts-node": "^8.10.2",
"tslint": "^6.1.2",
"typescript": "^3.9.6"
"ts-node": "^10.5.0",
"typescript": "~4.8.4"
}
}

View File

@@ -1,14 +1,11 @@
import {forwardRef, Inject, Injectable} from '@angular/core';
import {Article} from '../class/Article';
import {Injectable} from '@angular/core';
import {Article, ArticleReq} from '../class/Article';
import {HttpService} from './http/http.service';
import {PageList} from '../class/HttpReqAndResp';
import {ArticleReq} from '../class/Article';
import {Category, Tag} from '../class/Tag';
import {Comment} from '../class/Comment';
import {CommentReq} from '../class/Comment';
import {Comment, CommentReq} from '../class/Comment';
import {ApplyLinkReq, Link} from '../class/Link';
import {User} from '../class/User';
import {LoginReq} from '../class/User';
import {LoginReq, User} from '../class/User';
import {Visitor} from '../class/Visitor';
import {UpdateInfo} from '../class/UpdateInfo';
@@ -23,7 +20,7 @@ export class ApiService {
createArticle(article: ArticleReq) {
article.id = null;
return this.httpService.Service<Article>({
return this.httpService.service<Article>({
path: '/admin/article/create',
contentType: 'application/json',
method: 'POST',
@@ -32,15 +29,15 @@ export class ApiService {
}
deleteArticle(id: number) {
return this.httpService.Service<boolean>({
return this.httpService.service<boolean>({
path: '/admin/article/del',
method: 'DELETE',
queryParam: {articleID: id}
})
});
}
articles(pageNumber: number = 1, pageSize: number = 5) {
return this.httpService.Service<PageList<Article>>({
return this.httpService.service<PageList<Article>>({
path: '/articles',
method: 'GET',
queryParam: {
@@ -51,7 +48,7 @@ export class ApiService {
}
adminArticles(pageNumber: number = 1, pageSize: number = 10) {
return this.httpService.Service<PageList<Article>>({
return this.httpService.service<PageList<Article>>({
path: '/admin/articles',
method: 'GET',
queryParam: {
@@ -62,7 +59,7 @@ export class ApiService {
}
updateArticle(article: ArticleReq) {
return this.httpService.Service<Article>({
return this.httpService.service<Article>({
path: '/admin/article/update',
method: 'PUT',
contentType: 'application/json',
@@ -71,7 +68,7 @@ export class ApiService {
}
getArticle(articleId: number, is4Update: boolean = false) {
return this.httpService.Service<Article>({
return this.httpService.service<Article>({
path: `/article/articleID/${articleId}`,
method: 'GET',
queryParam: {update: is4Update},
@@ -79,7 +76,7 @@ export class ApiService {
}
articlesByCategory(category: string, pageNumber: number = 1, pageSize: number = 10) {
return this.httpService.Service<PageList<Article>>({
return this.httpService.service<PageList<Article>>({
path: `/articles/category/${category}`,
method: 'GET',
queryParam: {
@@ -90,7 +87,7 @@ export class ApiService {
}
articlesByTag(tag: string, pageNumber: number = 1, pageSize: number = 10) {
return this.httpService.Service<PageList<Article>>({
return this.httpService.service<PageList<Article>>({
path: `/articles/tag/${tag}`,
method: 'GET',
queryParam: {
@@ -101,14 +98,14 @@ export class ApiService {
}
categories() {
return this.httpService.Service<PageList<Category>>({
return this.httpService.service<PageList<Category>>({
path: '/categories',
method: 'GET'
});
}
createCategory(nameStr: string) {
return this.httpService.Service<Category>({
return this.httpService.service<Category>({
path: '/admin/category/create',
method: 'POST',
queryParam: {name: nameStr}
@@ -116,7 +113,7 @@ export class ApiService {
}
deleteCategory(categoryId: number) {
return this.httpService.Service<boolean>({
return this.httpService.service<boolean>({
path: '/admin/category/del',
method: 'DELETE',
queryParam: {id: categoryId}
@@ -124,7 +121,7 @@ export class ApiService {
}
updateCategory(categoryId: number, nameStr: string) {
return this.httpService.Service<Category>({
return this.httpService.service<Category>({
path: '/admin/category/update',
method: 'PUT',
queryParam: {id: categoryId, name: nameStr}
@@ -132,7 +129,7 @@ export class ApiService {
}
tags(pageNumber: number = 1, pageSize: number = 10) {
return this.httpService.Service<PageList<Tag>>({
return this.httpService.service<PageList<Tag>>({
path: '/tags',
method: 'GET',
queryParam: {
@@ -143,38 +140,38 @@ export class ApiService {
}
tagsNac() {
return this.httpService.Service<{ name: string, size: number }[]>({
return this.httpService.service<{ name: string; size: number }[]>({
path: '/tags/nac',
method: 'GET'
});
}
createTag(nameStr: string) {
return this.httpService.Service<Tag>({
return this.httpService.service<Tag>({
path: '/admin/tag/create',
method: 'POST',
queryParam: {name: nameStr}
});
}
deleteTag(TagId: number) {
return this.httpService.Service<boolean>({
deleteTag(tagId: number) {
return this.httpService.service<boolean>({
path: '/admin/tag/del',
method: 'DELETE',
queryParam: {id: TagId}
queryParam: {id: tagId}
});
}
updateTag(TagId: number, nameStr: string) {
return this.httpService.Service<Tag>({
updateTag(tagId: number, nameStr: string) {
return this.httpService.service<Tag>({
path: '/admin/tag/update',
method: 'PUT',
queryParam: {id: TagId, name: nameStr}
queryParam: {id: tagId, name: nameStr}
});
}
getCommentByTypeForAdmin(pagePath: string, pageNumber: number = 1, pageSize: number = 10) {
return this.httpService.Service<PageList<Comment>>({
return this.httpService.service<PageList<Comment>>({
path: `/admin/comment/pagePath/${pagePath}`,
method: 'GET',
queryParam: {
@@ -185,7 +182,7 @@ export class ApiService {
}
getCommentByTypeForUser(pagePath: string, pageNumber: number = 1, pageSize: number = 10) {
return this.httpService.Service<PageList<Comment>>({
return this.httpService.service<PageList<Comment>>({
path: `/user/comment/pagePath/${pagePath}`,
method: 'GET',
queryParam: {
@@ -196,7 +193,7 @@ export class ApiService {
}
deleteComment(idNumer: number) {
return this.httpService.Service<boolean>({
return this.httpService.service<boolean>({
path: `/user/comment/del`,
method: 'DELETE',
queryParam: {id: idNumer}
@@ -204,7 +201,7 @@ export class ApiService {
}
updateComment(commentReq: CommentReq) {
return this.httpService.Service<Comment>({
return this.httpService.service<Comment>({
path: `/user/comment/update`,
method: 'PUT',
data: commentReq,
@@ -213,7 +210,7 @@ export class ApiService {
}
comments(pagePath: string, pageSize: number = 10, pageNumber: number = 1) {
return this.httpService.Service<PageList<Comment>>({
return this.httpService.service<PageList<Comment>>({
path: `/comment/pagePath/${pagePath}`,
method: 'GET',
queryParam: {
@@ -224,7 +221,7 @@ export class ApiService {
}
createComment(commentReq: CommentReq) {
return this.httpService.Service<Comment>({
return this.httpService.service<Comment>({
path: '/user/comment/create',
method: 'POST',
contentType: 'application/json',
@@ -234,12 +231,12 @@ export class ApiService {
counts() {
return this.httpService.Service<{
articleCount: number,
visitorCount: number,
categoryCount: number,
tagCount: number,
commentCount: number
return this.httpService.service<{
articleCount: number;
visitorCount: number;
categoryCount: number;
tagCount: number;
commentCount: number;
}>({
path: '/counts',
method: 'GET'
@@ -247,7 +244,7 @@ export class ApiService {
}
adminLinks(pageSize: number = 10, pageNumber: number = 1) {
return this.httpService.Service<PageList<Link>>({
return this.httpService.service<PageList<Link>>({
path: '/admin/links',
method: 'GET',
queryParam: {
@@ -258,7 +255,7 @@ export class ApiService {
}
createLink(linkReq: Link) {
return this.httpService.Service<Link>({
return this.httpService.service<Link>({
path: '/admin/links/create',
method: 'POST',
data: linkReq,
@@ -267,14 +264,14 @@ export class ApiService {
}
deleteLink(idNumber: number) {
return this.httpService.Service<boolean>({
return this.httpService.service<boolean>({
path: `/admin/links/del/${idNumber}`,
method: 'DELETE',
});
}
updateLink(linkReq: Link) {
return this.httpService.Service<Link>({
return this.httpService.service<Link>({
path: '/admin/links/update',
method: 'PUT',
data: linkReq,
@@ -283,7 +280,7 @@ export class ApiService {
}
applyLink(link: ApplyLinkReq) {
return this.httpService.Service<string>({
return this.httpService.service<string>({
path: '/apply',
method: 'POST',
data: link,
@@ -292,7 +289,7 @@ export class ApiService {
}
reapplyLink(keyStr: string) {
return this.httpService.Service<string>({
return this.httpService.service<string>({
path: '/reapply',
method: 'POST',
queryParam: {
@@ -302,14 +299,14 @@ export class ApiService {
}
links() {
return this.httpService.Service<Link[]>({
return this.httpService.service<Link[]>({
path: '/links',
method: 'GET',
});
}
verifyImgCode(codeStr: string) {
return this.httpService.Service<string>({
return this.httpService.service<string>({
path: '/verCode',
method: 'POST',
queryParam: {code: codeStr}
@@ -318,7 +315,7 @@ export class ApiService {
login(loginReq: LoginReq) {
return this.httpService.Service<User>({
return this.httpService.service<User>({
path: '/login',
method: 'POST',
contentType: 'application/json',
@@ -327,14 +324,14 @@ export class ApiService {
}
logout() {
return this.httpService.Service<string>({
return this.httpService.service<string>({
path: '/logout',
method: 'GET',
});
}
registration(emailStr: string, pwd: string) {
return this.httpService.Service<boolean>({
return this.httpService.service<boolean>({
path: '/registration',
method: 'POST',
queryParam: {
@@ -345,7 +342,7 @@ export class ApiService {
}
resetPwd(idStr: string, emailStr: string, pwdStr: string) {
return this.httpService.Service<string>({
return this.httpService.service<string>({
path: '/resetPwd',
method: 'POST',
queryParam: {
@@ -357,7 +354,7 @@ export class ApiService {
}
emailVerify(idStr: string, emailStr: string) {
return this.httpService.Service<void>({
return this.httpService.service<void>({
path: '/emailVerify',
method: 'POST',
queryParam: {
@@ -369,7 +366,7 @@ export class ApiService {
sendResetPwdEmail(emailStr: string) {
return this.httpService.Service<string>({
return this.httpService.service<string>({
path: '/sendResetPwdEmail',
method: 'POST',
queryParam: {email: emailStr}
@@ -377,7 +374,7 @@ export class ApiService {
}
sendVerifyEmail(emailStr: string) {
return this.httpService.Service<string>({
return this.httpService.service<string>({
path: '/sendVerifyEmail',
method: 'POST',
queryParam: {email: emailStr}
@@ -385,30 +382,30 @@ export class ApiService {
}
userInfo() {
return this.httpService.Service<User>({
return this.httpService.service<User>({
path: '/user/userInfo',
method: 'GET',
});
}
adminUpdateUser(user: User) {
return this.httpService.Service<User>({
return this.httpService.service<User>({
path: '/admin/user',
method: 'PUT',
data: user,
contentType: 'application/json'
})
});
}
deleteUser(id: number) {
return this.httpService.Service<boolean>({
return this.httpService.service<boolean>({
path: `/admin/user/delete/${id}`,
method: 'DELETE',
});
}
multipleDeleteUser(idArray: number[]) {
return this.httpService.Service<{ id: number; msg: string; status: boolean }[]>({
return this.httpService.service<{ id: number; msg: string; status: boolean }[]>({
path: `/admin/user/delete`,
method: 'DELETE',
data: idArray,
@@ -418,14 +415,14 @@ export class ApiService {
// 获取邮件是否已注册
emailStatus(email: string) {
return this.httpService.Service<boolean>({
return this.httpService.service<boolean>({
path: `/emailStatus/${email}`,
method: 'GET'
})
});
}
updateUserInfo(descStr: string, disPlayNameStr: string) {
return this.httpService.Service<User>({
return this.httpService.service<User>({
path: '/user/userInfo/update',
method: 'PUT',
queryParam: {
@@ -436,7 +433,7 @@ export class ApiService {
}
adminUsers(pageSize: number = 10, pageNumber: number = 1) {
return this.httpService.Service<PageList<User>>({
return this.httpService.service<PageList<User>>({
path: '/admin/users',
method: 'GET',
queryParam: {
@@ -447,14 +444,14 @@ export class ApiService {
}
visit() {
return this.httpService.Service<Visitor>({
return this.httpService.service<Visitor>({
path: '/visit',
method: 'POST'
});
}
adminVisitors(location: boolean = false, pageSize: number = 10, pageNumber: number = 1) {
return this.httpService.Service<PageList<Visitor>>({
return this.httpService.service<PageList<Visitor>>({
path: '/admin/visitor/page',
method: 'GET',
queryParam: {
@@ -466,42 +463,42 @@ export class ApiService {
}
dayVisitCount() {
return this.httpService.Service<number>({
return this.httpService.service<number>({
path: '/dayVisitCount',
method: 'GET',
});
}
getLocalIp() {
return this.httpService.Service<string>({
return this.httpService.service<string>({
path: '/ip',
method: 'GET',
});
}
getIpLocation(ip: string) {
return this.httpService.Service<string>({
return this.httpService.service<string>({
path: `/ip/${ip}`,
method: 'GET',
});
}
visitorCount() {
return this.httpService.Service<number>({
return this.httpService.service<number>({
path: `/visitor/count`,
method: 'GET',
});
}
webUpdate() {
return this.httpService.Service<{ id: number, info: string, time: string }[]>({
return this.httpService.service<{ id: number; info: string; time: string }[]>({
path: '/webUpdate',
method: 'GET'
});
}
webUpdatePage(pageSize: number = 10, pageNumber: number = 1) {
return this.httpService.Service<PageList<{ id: number, info: string, time: string }>>({
return this.httpService.service<PageList<{ id: number; info: string; time: string }>>({
path: '/webUpdate/pages',
method: 'GET',
queryParam: {
@@ -512,13 +509,13 @@ export class ApiService {
}
lastestUpdate() {
return this.httpService.Service<{
return this.httpService.service<{
lastUpdateTime: string;
lastUpdateInfo: string;
lastCommit: string;
committerAuthor: string;
committerDate: string;
commitUrl: string
commitUrl: string;
}>({
path: '/lastestUpdate',
method: 'GET'
@@ -526,7 +523,7 @@ export class ApiService {
}
createWebUpdateInfo(infoStr: string) {
return this.httpService.Service<UpdateInfo>({
return this.httpService.service<UpdateInfo>({
path: '/admin/webUpdate/create',
method: 'POST',
queryParam: {info: infoStr}
@@ -534,14 +531,14 @@ export class ApiService {
}
deleteWebUpdateInfo(idNumber: number) {
return this.httpService.Service<boolean>({
return this.httpService.service<boolean>({
path: `/admin/webUpdate/del/${idNumber}`,
method: 'DELETE',
});
}
updateWebUpdateInfo(idNumber: number, infoStr: string) {
return this.httpService.Service<UpdateInfo>({
return this.httpService.service<UpdateInfo>({
path: '/admin/webUpdate/update',
method: 'PUT',
queryParam: {id: idNumber, info: infoStr}
@@ -549,14 +546,14 @@ export class ApiService {
}
bingPic() {
return this.httpService.Service<string>({
return this.httpService.service<string>({
path: '/bingPic',
method: 'GET'
});
}
setPwd(pwdStr: string, newPwdStr: string, confirmPwdStr: string,) {
return this.httpService.Service<string>({
return this.httpService.service<string>({
path: '/user/setPwd',
method: 'POST',
queryParam: {

View File

@@ -11,21 +11,22 @@ import {ErrorService} from '../../services/error.service';
})
export class HttpService {
private subscriptionQueue: Subscription[] = [];
constructor(private httpClient: HttpClient,
private localStorageService: LocalStorageService,
private injector: Injector) {
}
private subscriptionQueue: Subscription[] = [];
public getSubscriptionQueue = () => this.subscriptionQueue;
Service<T>(request: RequestObj) {
service<T>(request: RequestObj) {
const errorService = this.injector.get(ErrorService);
request.url = null;
// 设置默认值
request.contentType = request.contentType == null ? 'application/x-www-form-urlencoded' : request.contentType;
request.header = {
// eslint-disable-next-line @typescript-eslint/naming-convention
'Content-Type': request.contentType
};
const token = this.localStorageService.getToken();
@@ -62,16 +63,16 @@ export class HttpService {
}
if (o.body.code !== 0) {
observer.error(o.body);
errorService.httpException(o.body, request)
errorService.httpException(o.body, request);
} else {
observer.next(o.body);
}
observer.complete();
},
error: err => {
errorService.httpError(err,request);
errorService.httpError(err, request);
errorService.checkConnection();
this.subscriptionQueue.splice(this.subscriptionQueue.indexOf(subscription), 1)
this.subscriptionQueue.splice(this.subscriptionQueue.indexOf(subscription), 1);
},
complete: () => this.subscriptionQueue.splice(this.subscriptionQueue.indexOf(subscription), 1)
});
@@ -117,6 +118,7 @@ export class HttpService {
/**
* 验证并且处理拼接 URl
*
* @param req Request
*/
private checkUrl(req: RequestObj): string {

View File

@@ -9,9 +9,9 @@ import {ComponentStateService} from './services/component-state.service';
styleUrls: ['./app.component.less']
})
export class AppComponent {
@ViewChild('headerComponent') header: HeaderComponent;
loginModal: boolean = false;
regModal: boolean = false;
@ViewChild('headerComponent') header: HeaderComponent;
constructor(public componentStateService: ComponentStateService) {
}

View File

@@ -1,7 +1,7 @@
import {BrowserModule} from '@angular/platform-browser';
import {forwardRef, NgModule} from '@angular/core';
import {NgModule} from '@angular/core';
import {AppComponent} from './app.component';
import {NgZorroAntdModule, NZ_I18N, zh_CN} from 'ng-zorro-antd';
import {NZ_I18N, zh_CN} from 'ng-zorro-antd/i18n';
import {FormsModule} from '@angular/forms';
import {HttpClientModule} from '@angular/common/http';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
@@ -20,6 +20,16 @@ import {ComponentStateService} from './services/component-state.service';
import {GlobalUserService} from './services/global-user.service';
import {LocalStorageService} from './services/local-storage.service';
import {ApiService} from './api/api.service';
import {NzMessageService} from 'ng-zorro-antd/message';
import {NzBackTopModule} from 'ng-zorro-antd/back-top';
import {NzModalModule} from 'ng-zorro-antd/modal';
import {NzNotificationService} from 'ng-zorro-antd/notification';
import {NzDropDownModule} from 'ng-zorro-antd/dropdown';
import {NzIconModule} from 'ng-zorro-antd/icon';
import {NzAvatarModule} from 'ng-zorro-antd/avatar';
import {NzButtonModule} from 'ng-zorro-antd/button';
import {NzGridModule} from 'ng-zorro-antd/grid';
import {NzDividerModule} from 'ng-zorro-antd/divider';
registerLocaleData(zh);
@@ -33,13 +43,20 @@ registerLocaleData(zh);
imports: [
BrowserModule,
AppRoutingModule,
NgZorroAntdModule,
FormsModule,
HttpClientModule,
BrowserAnimationsModule,
LoginRegistrationModule,
AdminModule,
ServiceWorkerModule.register('ngsw-worker.js', {enabled: environment.production})
ServiceWorkerModule.register('ngsw-worker.js', {enabled: environment.production}),
NzBackTopModule,
NzModalModule,
NzDropDownModule,
NzIconModule,
NzAvatarModule,
NzButtonModule,
NzGridModule,
NzDividerModule
],
providers: [
ComponentStateService,
@@ -47,6 +64,8 @@ registerLocaleData(zh);
LocalStorageService,
HttpService,
ApiService,
NzMessageService,
NzNotificationService,
ErrorService,
{provide: NZ_I18N, useValue: zh_CN},
],

View File

@@ -1,27 +0,0 @@
import {environment} from '../../environments/environment';
export class EditorConfig {
public width = '100%';
public height = '400';
public path = 'assets/editor/lib/';
public codeFold: true;
public searchReplace = true;
public toolbar = true;
public placeholder = '欢迎来到小海的创作中心';
public emoji = true;
public taskList = true;
public tex = true;
public readOnly = false;
public tocm = true;
public watch = true;
public previewCodeHighlight = true;
public saveHTMLToTextarea = true;
public markdown = '';
public flowChart = true;
public syncScrolling = true;
public sequenceDiagram = false; // 时序图/序列图
public imageUpload = true;
public imageFormats = ['jpg', 'jpeg', 'gif', 'png', 'bmp', 'webp'];
public imageUploadURL = environment.host + '/imgUpload';
public useAjaxToUploadImg = true
}

View File

@@ -6,7 +6,7 @@ export class RequestObj {
method: 'GET' | 'POST' | 'PUT' | 'DELETE';
data?: {};
contentType?: 'application/json' | 'application/x-www-form-urlencoded';
queryParam?: {};
queryParam?: { [key: string]: any };
header?: HttpHeaders | {
[header: string]: string | string[];
};

View File

@@ -14,5 +14,5 @@ export class ApplyLinkReq {
iconPath: string;
linkUrl: string;
name: string;
url: string
url: string;
}

View File

@@ -8,7 +8,7 @@ export class User {
role?: string;
token?: string;
pwd?: string;
recentlyLandedDate?: string
recentlyLandedDate?: string;
}
export class LoginReq {

View File

@@ -20,16 +20,16 @@
<div id="landr" *ngIf="!user">
<nz-space>
<nz-space-item>
<template *nzSpaceItem>
<a routerLink="/user/login">
<button nz-button nzType="primary">登录</button>
</a>
</nz-space-item>
<nz-space-item>
</template>
<template *nzSpaceItem>
<a routerLink="/user/registration">
<button nz-button nzType="primary">注册</button>
</a>
</nz-space-item>
</template>
</nz-space>
</div>

View File

@@ -8,13 +8,14 @@ import {User} from '../../class/User';
styleUrls: ['./admin-header.component.less']
})
export class AdminHeaderComponent implements OnInit {
@Output() infoClicked = new EventEmitter<void>();
user: User;
noAvatarUrl = 'https://cdn.celess.cn/';
constructor(private userService: GlobalUserService) {
}
user: User
@Output() infoClicked = new EventEmitter<void>()
noAvatarUrl = 'https://cdn.celess.cn/'
logout = () => this.userService.logout();
infoClickedEvent = () => this.infoClicked.emit();
@@ -23,7 +24,7 @@ export class AdminHeaderComponent implements OnInit {
next: data => this.user = data.result,
error: err => this.user = null,
complete: null
})
});
}
}

View File

@@ -1,12 +1,10 @@
<div class="footer">
<nz-divider></nz-divider>
<div>
<a href="http://www.miitbeian.gov.cn" target="_blank">
鄂ICP备18023929号
</a>
<a href="https://beian.miit.gov.cn" target="_blank">鄂ICP备18023929号-2</a>
<div>
© 2019 <a href="https://www.celess.cn">小海博客</a> -
<span>郑海 </span> <span *ngIf="gName">& {{gName}} </span>版权所有
© 2020 <a href="https://www.celess.cn">小海博客</a> -
<span>{{bName}} </span> <span *ngIf="gName">& {{gName}} </span>版权所有
</div>
</div>
</div>

View File

@@ -9,7 +9,7 @@
left: 0;
bottom: 0;
/* 设置z-index 是为了write页面将footer隐藏*/
z-index: -1;
z-index: 0;
}
hr {

View File

@@ -8,11 +8,12 @@ import {ComponentStateService} from '../../services/component-state.service';
})
export class FooterComponent implements OnInit {
readonly gName: string = '何梦幻';
readonly bName: string = '郑海';
constructor(public componentStateService: ComponentStateService) {
}
readonly gName: string;
ngOnInit() {
}

View File

@@ -1,7 +1,6 @@
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {Router} from '@angular/router';
import {windowWidthChange} from '../../utils/util';
import {ApiService} from '../../api/api.service';
import {User} from '../../class/User';
import {ComponentStateService} from '../../services/component-state.service';
import {GlobalUserService} from '../../services/global-user.service';
@@ -12,6 +11,25 @@ import {GlobalUserService} from '../../services/global-user.service';
styleUrls: ['./header.component.less']
})
export class HeaderComponent implements OnInit {
@Output() loginEvent = new EventEmitter();
@Output() registrationEvent = new EventEmitter();
@Input() userInfo: User;
size: 'large' | 'default';
currentPath: string;
noAvatarUrl = 'https://cdn.celess.cn/';
public pageList: {
path: string;
name: string;
icon: string;
iconType: 'outline' | 'fill' | 'twotone';
show: boolean;
}[];
public showList = true;
// css 样式中设置移动端最大宽度为910px 见src/app/global-variables.less
private readonly mobileMaxWidth = 940;
constructor(private router: Router,
public componentStateService: ComponentStateService,
@@ -46,26 +64,6 @@ export class HeaderComponent implements OnInit {
});
}
@Output() loginEvent = new EventEmitter();
@Output() registrationEvent = new EventEmitter();
size: 'large' | 'default';
currentPath: string;
noAvatarUrl = 'https://cdn.celess.cn/'
public pageList: {
path: string;
name: string;
icon: string;
iconType: 'outline' | 'fill' | 'twotone';
show: boolean;
}[];
public showList = true;
// css 样式中设置移动端最大宽度为910px 见src/app/global-variables.less
private readonly mobileMaxWidth = 940;
@Input() userInfo: User;
ngOnInit() {
}
@@ -75,17 +73,6 @@ export class HeaderComponent implements OnInit {
this.changeLoginButtonV();
}
private changeLoginButtonV() {
this.pageList.forEach(e => {
if (e.name === '登录' || e.name === '注册') {
if (this.userInfo) {
e.show = false;
} else {
e.show = (this.showList && window.innerWidth < this.mobileMaxWidth);
}
}
});
}
dealLink(path: string) {
this.showList = window.innerWidth > this.mobileMaxWidth;
@@ -137,7 +124,20 @@ export class HeaderComponent implements OnInit {
}
toAdminPage() {
this.router.navigateByUrl('/admin')
this.router.navigateByUrl('/admin');
}
private changeLoginButtonV() {
this.pageList.forEach(e => {
if (e.name === '登录' || e.name === '注册') {
if (this.userInfo) {
e.show = false;
} else {
e.show = (this.showList && window.innerWidth < this.mobileMaxWidth);
}
}
});
}
}

View File

@@ -1,24 +1,25 @@
import {Injectable} from '@angular/core';
import {filter} from 'rxjs/operators';
import {NavigationEnd, Router, RouterEvent} from '@angular/router';
import {Observable, of, Subscriber} from 'rxjs';
import {Observable, Subscriber} from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ComponentStateService {
constructor(private router: Router) {
this.watchRouterChange()
}
visible = {
header: true,
footer: true,
globalBackToTop: true
};
currentPath: string;
constructor(private router: Router) {
this.watchRouterChange();
}
currentPath: string
getCurrentRouterPath = () => this.currentPath;
watchRouterChange() {
@@ -31,28 +32,30 @@ export class ComponentStateService {
// lastIndexOf ==> 0/index
const indexOf = path.lastIndexOf('/');
const prefix = path.substr(0, indexOf === 0 ? path.length : indexOf);
this.dealWithPathChange(prefix)
this.dealWithPathChange(prefix);
this.currentPath = prefix;
if (subscriber) subscriber.next(prefix)
if (subscriber) {
subscriber.next(prefix);
}
});
return ob;
}
private dealWithPathChange(path) {
// tslint:disable-next-line:forin
// eslint-disable-next-line guard-for-in
for (const visibleKey in this.visible) {
this.visible[visibleKey] = true
this.visible[visibleKey] = true;
}
switch (path) {
case '/admin':
this.visible.header = false
this.visible.footer = false
this.visible.globalBackToTop = false
break
this.visible.header = false;
this.visible.footer = false;
this.visible.globalBackToTop = false;
break;
case '/user':
case '/write':
this.visible.footer = false
this.visible.globalBackToTop = false
this.visible.footer = false;
this.visible.globalBackToTop = false;
break;
default:

View File

@@ -3,7 +3,7 @@ import {RequestObj, Response} from '../class/HttpReqAndResp';
import {environment} from '../../environments/environment';
import {Router} from '@angular/router';
import {ComponentStateService} from './component-state.service';
import {NzNotificationService} from 'ng-zorro-antd';
import {NzNotificationService} from 'ng-zorro-antd/notification';
import {HttpService} from '../api/http/http.service';
import {LocalStorageService} from './local-storage.service';
@@ -11,6 +11,9 @@ import {LocalStorageService} from './local-storage.service';
providedIn: 'root'
})
export class ErrorService {
private static httpErrorCount: number = 0;
private readonly maintainPagePrefix = '/maintain';
private readonly adminPagePrefix = '/admin';
constructor(/*private httpService: HttpService,*/
private router: Router,
@@ -20,48 +23,57 @@ export class ErrorService {
private localStorageService: LocalStorageService) {
}
private static HTTP_ERROR_COUNT: number = 0;
private readonly MAINTAIN_PAGE_PREFIX = '/maintain'
private readonly ADMIN_PAGE_PREFIX = '/admin'
public httpError(err: any, request: RequestObj) {
if (!environment.production) {
console.log('error=>', err, request)
console.log('error=>', err, request);
}
ErrorService.HTTP_ERROR_COUNT++;
ErrorService.httpErrorCount++;
// this.httpService.getSubscriptionQueue().map(a => a.unsubscribe())
}
public httpException(response: Response<any>, request: RequestObj) {
if (!environment.production)
console.log('exception=>', response, request)
if (response.code === -1 && response.msg === '重复请求') return
if (this.componentStateService.currentPath === this.ADMIN_PAGE_PREFIX) {
if (!environment.production) {
console.log('exception=>', response, request);
}
if (response.code === -1 && response.msg === '重复请求') {
return;
}
if (this.componentStateService.currentPath === this.adminPagePrefix) {
this.notification.create('error', `请求失败<${response.code}>`, `${response.msg}`);
}
// 3830 token签名错误
if (response.code === 3830) {
/***
* 3700, "登陆过期"
* 3710, "账户已注销"
* 3711, "账户不可用"
* 3800, "密码不正确"
* 3810, "Token过期"
* 3820, "Token格式不对"
* 3820, "Token格式不对"
* 3830, "Token签名错误"
* 3840, "不支持的Token"
*/
if (response.code > 3700 && response.code < 3900) {
this.localStorageService.removeToken();
}
}
public checkConnection() {
// The HTTP_ERROR_COUNT is start with 1 in this function
if (ErrorService.HTTP_ERROR_COUNT === 1) {
if (ErrorService.httpErrorCount === 1) {
const req: RequestObj = {
path: '/headerInfo',
method: 'GET',
url: environment.host + '/headerInfo'
}
};
this.injector.get(HttpService).get(req).subscribe({
next: () => null,
error: () => {
if (this.componentStateService.currentPath !== this.MAINTAIN_PAGE_PREFIX) {
this.router.navigateByUrl(this.MAINTAIN_PAGE_PREFIX)
if (this.componentStateService.currentPath !== this.maintainPagePrefix) {
this.router.navigateByUrl(this.maintainPagePrefix);
}
ErrorService.HTTP_ERROR_COUNT = 0;
ErrorService.httpErrorCount = 0;
}
})
});
}
}
}

View File

@@ -10,10 +10,6 @@ import {LocalStorageService} from './local-storage.service';
})
export class GlobalUserService {
constructor(private apiService: ApiService,
private localStorageService: LocalStorageService) {
}
private lastRequestTime: number;
private userInfo: User = null;
@@ -21,26 +17,29 @@ export class GlobalUserService {
private userObserverArray: Observer<Response<User>>[] = [];
private multicastArray: Observer<Response<User>>[] = [];
constructor(private apiService: ApiService,
private localStorageService: LocalStorageService) {
}
watchUserInfo(observer: Observer<Response<User>>) {
if (this.userObserverArray.indexOf(observer) < 0) this.userObserverArray.push(observer);
if (this.userObserverArray.indexOf(observer) < 0) {this.userObserverArray.push(observer);}
this.multicastArray = [...this.userObserverArray];
let subscription: Subscription = null;
const unsubscribe = () => {
this.userObserverArray.splice(this.userObserverArray.indexOf(observer), 1);
observer.complete();
if (subscription) subscription.unsubscribe();
if (subscription) {subscription.unsubscribe();}
};
if (this.lastRequestTime && Date.now() - this.lastRequestTime < 3000) {
if (this.userInfo && this.multicastArray.length) {
this.broadcast()
this.broadcast();
this.lastRequestTime = Date.now();
}
return {unsubscribe}
return {unsubscribe};
}
// 获取数据
subscription = this.getUserInfoFromServer();
return {unsubscribe}
return {unsubscribe};
}
// 刷新用户信息
@@ -59,7 +58,7 @@ export class GlobalUserService {
// this.localStorageService.setUser(o.result);
// this.userObserver.next(o);
this.userInfo = o.result;
this.broadcast()
this.broadcast();
observer.next(o);
observer.complete();
},
@@ -82,7 +81,7 @@ export class GlobalUserService {
// 如果不需要返回消息也ok
this.apiService.logout().subscribe(data => {
this.localStorageService.clear();
this.broadcast()
this.broadcast();
if (observer) {
observer.next(data);
observer.complete();
@@ -93,7 +92,7 @@ export class GlobalUserService {
observer.error(error);
observer.complete();
}
})
});
}
getUserInfoFromServer(observer?: Observer<Response<User>>) {
@@ -102,7 +101,7 @@ export class GlobalUserService {
this.lastRequestTime = Date.now();
this.userInfo = o.result;
// this.localStorageService.setUser(o.result);
this.broadcast()
this.broadcast();
if (observer) {
observer.next(o);
observer.complete();
@@ -118,12 +117,12 @@ export class GlobalUserService {
if (err.code === -1) {
// 请求重复
return
return;
}
// this.requested = false;
// this.localStorageService.removeToken();
this.multicastArray.forEach(ob => ob.next(new Response<User>(this.userInfo)))
this.multicastArray.forEach(ob => ob.error(err))
this.multicastArray.forEach(ob => ob.next(new Response<User>(this.userInfo)));
this.multicastArray.forEach(ob => ob.error(err));
this.multicastArray.splice(0, this.multicastArray.length);
}
@@ -131,7 +130,7 @@ export class GlobalUserService {
}
private broadcast() {
this.multicastArray.forEach(ob => ob.next(new Response<User>(this.userInfo)))
this.multicastArray.forEach(ob => ob.next(new Response<User>(this.userInfo)));
this.multicastArray.splice(0, this.multicastArray.length);
}
}

View File

@@ -1,34 +1,65 @@
import {Injectable} from '@angular/core';
import {User} from '../class/User';
import {Base64} from 'js-base64';
@Injectable({
providedIn: 'root'
})
export class LocalStorageService {
readonly place = 30 * 1000;
constructor() {
}
// 30s
readonly place = 30 * 1000;
getToken(): string {
return localStorage.getItem('token');
const item = this.getItem('token');
if (!item) {
return null;
}
return 'Bearer ' + item;
}
setToken(token: string) {
localStorage.setItem('t', new Date().valueOf().toString());
localStorage.setItem('token', token);
const t = new Date().valueOf().toString();
this.setItem('t', t);
if (token.startsWith('Bearer')) {
token = token.replace('Bearer', '');
}
if (token.startsWith('bearer')) {
token = token.replace('bearer', '');
}
this.setItem('token', token);
}
removeToken() {
localStorage.removeItem('token');
this.removeItem('token');
}
isLogin() {
return this.getToken() != null;
}
setItem(key: string, value: any) {
localStorage.setItem(key, Base64.encode(value));
}
getItem(key: string) {
const item = localStorage.getItem(key);
let decode;
try {
decode = Base64.decode(item);
return item ? decode : null;
} catch (e) {
localStorage.removeItem(key);
return item;
}
}
removeItem(key: string) {
localStorage.removeItem(key);
}
// setUser(user: User) {
// // TODO: 简单加个密
// localStorage.setItem('t', new Date().valueOf().toString());

View File

@@ -1,9 +1,9 @@
export class Color {
bgColor: string;
fontColor: string
fontColor: string;
}
export const ColorList: Color[] = [
export const COLOR_LIST: Color[] = [
{bgColor: '#7bcfa6', fontColor: '#000000'}, // 石青
{bgColor: '#bce672', fontColor: '#000000'}, // 松花色
{bgColor: '#ff8936', fontColor: '#000000'}, // 橘黄
@@ -13,23 +13,24 @@ export const ColorList: Color[] = [
{bgColor: '#177cb0', fontColor: '#ffffff'}, // 靛青
];
export const ColorListLength = ColorList.length
export const COLOR_LIST_LENGTH = COLOR_LIST.length;
/**
* 获取一组随机颜色
*
* @param count 数量
*/
export function RandomColor(count: number = 1): Color[] {
export function randomColor(count: number = 1): Color[] {
const map = new Map<number, number>();
ColorList.forEach((color, index) => map.set(index, 0))
COLOR_LIST.forEach((color, index) => map.set(index, 0));
const colorArray: Color[] = [];
const oneRandomColor = () => {
const minValue = Math.min.apply(null, Array.from(map.values()))
const minValue = Math.min.apply(null, Array.from(map.values()));
const keys = Array.from(map.keys()).filter(key => map.get(key) === minValue);
const keyIndex = Math.floor(Math.random() * keys.length);
const index = keys[keyIndex];
map.set(index, minValue + 1);
return ColorList[index]
return COLOR_LIST[index];
};
for (let i = 0; i < count; i++) {
colorArray.push(oneRandomColor());

View File

@@ -3,6 +3,7 @@ import {PageList} from '../class/HttpReqAndResp';
/**
* 判断 一个Page<any>[] 中是否存在一条已查询的数据
*
* @param pageNum 页码
* @param pageSize 单页数量
* @param pageList 源数据
@@ -12,14 +13,14 @@ export function exist<T>(pageNum: number, pageSize: number, pageList: PageList<a
if (pageList === undefined || pageList == null || pageList.length === 0) {
return null;
}
// tslint:disable-next-line:prefer-for-of
// eslint-disable-next-line @typescript-eslint/prefer-for-of
for (let i = 0; i < pageList.length; i++) {
// tslint:disable-next-line:triple-equals
// eslint-disable-next-line eqeqeq
if (pageList[i].pageNum == pageNum && pageList[i].pageSize == pageSize) {
const ob: Observable<PageList<T>> = new Observable(o => {
o.next(pageList[i]);
o.complete();
})
});
}
}
return null;

View File

@@ -1,11 +1,12 @@
export class SvgIconUtil {
// eslint-disable-next-line max-len
static readonly nameIcon = '<svg t="1581933298087" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3223" width="200" height="200"><path d="M983.04 163.84H40.96c-24.576 0-40.96 16.384-40.96 40.96v614.4c0 20.48 16.384 40.96 40.96 40.96h942.08c20.48 0 40.96-20.48 40.96-40.96V204.8c0-24.576-20.48-40.96-40.96-40.96zM253.952 749.568c0-102.4 61.44-192.512 147.456-233.472-28.672-24.576-45.056-61.44-45.056-102.4 0-77.824 65.536-143.36 143.36-143.36s143.36 65.536 143.36 143.36c0 40.96-12.288 73.728-36.864 98.304 94.208 36.864 163.84 131.072 163.84 237.568H253.952z" p-id="3224" fill="#1296db"></path></svg>';
// eslint-disable-next-line max-len
static readonly locationIcon = '<svg t="1581933583276" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3981" width="200" height="200"><path d="M511.932268 0c-213.943865 0-387.880498 170.933833-387.880499 381.06211 0 164.815346 238.869364 485.098975 341.66447 620.247558a58.249807 58.249807 0 0 0 46.216029 22.690332c18.129688 0 35.491743-8.443964 46.328916-22.690332 102.704796-135.126006 341.709624-455.432213 341.709624-620.247558C899.970808 170.933833 725.89871 0 511.932268 0z m0 519.574733c-91.393496 0-165.786176-72.902569-165.786176-162.670489 0-89.722765 74.39268-162.738221 165.786176-162.73822 91.438651 0 165.718443 73.015456 165.718443 162.73822 0 89.76792-74.279793 162.670488-165.718443 162.670489z" fill="#1296db" p-id="3982"></path></svg>';
constructor() {
}
// tslint:disable-next-line:max-line-length
static readonly nameIcon = '<svg t="1581933298087" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3223" width="200" height="200"><path d="M983.04 163.84H40.96c-24.576 0-40.96 16.384-40.96 40.96v614.4c0 20.48 16.384 40.96 40.96 40.96h942.08c20.48 0 40.96-20.48 40.96-40.96V204.8c0-24.576-20.48-40.96-40.96-40.96zM253.952 749.568c0-102.4 61.44-192.512 147.456-233.472-28.672-24.576-45.056-61.44-45.056-102.4 0-77.824 65.536-143.36 143.36-143.36s143.36 65.536 143.36 143.36c0 40.96-12.288 73.728-36.864 98.304 94.208 36.864 163.84 131.072 163.84 237.568H253.952z" p-id="3224" fill="#1296db"></path></svg>';
// tslint:disable-next-line:max-line-length
static readonly locationIcon = '<svg t="1581933583276" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3981" width="200" height="200"><path d="M511.932268 0c-213.943865 0-387.880498 170.933833-387.880499 381.06211 0 164.815346 238.869364 485.098975 341.66447 620.247558a58.249807 58.249807 0 0 0 46.216029 22.690332c18.129688 0 35.491743-8.443964 46.328916-22.690332 102.704796-135.126006 341.709624-455.432213 341.709624-620.247558C899.970808 170.933833 725.89871 0 511.932268 0z m0 519.574733c-91.393496 0-165.786176-72.902569-165.786176-162.670489 0-89.722765 74.39268-162.738221 165.786176-162.73822 91.438651 0 165.718443 73.015456 165.718443 162.73822 0 89.76792-74.279793 162.670488-165.718443 162.670489z" fill="#1296db" p-id="3982"></path></svg>';
}

View File

@@ -1,32 +1,32 @@
<common-table cardTitle="文章管理"
#commonTableComponent
[headData]="headData"
[request]="request"
[template]="{
<common-table #commonTableComponent
[headData]="headData"
[request]="request"
[template]="{
original:{temp:original,param:{true:'原创',false:'转载'}},
readingNumber:{temp:readingNumber},
likeCount:{temp:likeCount},
dislikeCount:{temp:dislikeCount},
open:{temp:open}
}">
}"
cardTitle="文章管理">
</common-table>
<ng-template let-value="value" let-originValue="originValue" #original>
<ng-template #original let-originValue="originValue" let-value="value">
<nz-tag [nzColor]="originValue?'green':'#ff5500'">{{value}}</nz-tag>
</ng-template>
<ng-template let-value="value" #readingNumber>
<ng-template #readingNumber let-value="value">
<nz-tag nzColor="purple">{{value}}</nz-tag>
</ng-template>
<ng-template let-value="value" #likeCount>
<ng-template #likeCount let-value="value">
<nz-tag nzColor="blue">{{value}}</nz-tag>
</ng-template>
<ng-template let-value="value" #dislikeCount>
<ng-template #dislikeCount let-value="value">
<nz-tag nzColor="magenta">{{value}}</nz-tag>
</ng-template>
<ng-template #open let-value="value">
<label nz-checkbox nzDisabled [ngModel]="value"></label>
<label [ngModel]="value" nz-checkbox nzDisabled></label>
</ng-template>

View File

@@ -1,5 +1,5 @@
import {Component, OnInit, ViewChild} from '@angular/core';
import {NzMessageService} from 'ng-zorro-antd';
import {NzMessageService} from 'ng-zorro-antd/message';
import {ApiService} from '../../../api/api.service';
import {RequestObj} from '../../../class/HttpReqAndResp';
import {Article} from '../../../class/Article';
@@ -14,6 +14,10 @@ import {Router} from '@angular/router';
})
export class AdminArticleComponent implements OnInit {
@ViewChild('commonTableComponent') private commonTableComponent: CommonTableComponent<Article>;
request: RequestObj;
headData: Data<Article>[];
constructor(private apiService: ApiService, private nzMessage: NzMessageService, private title: Title,
private router: Router) {
this.request = {
@@ -23,15 +27,11 @@ export class AdminArticleComponent implements OnInit {
page: 1,
count: 10
}
}
};
}
request: RequestObj;
headData: Data<Article>[]
@ViewChild('commonTableComponent') private commonTableComponent: CommonTableComponent<Article>
ngOnInit(): void {
this.title.setTitle('小海博客 | 文章管理')
this.title.setTitle('小海博客 | 文章管理');
this.headData = [
{title: '主键', fieldValue: 'id', show: false, primaryKey: true},
{title: '标题', fieldValue: 'title', show: true},
@@ -54,18 +54,18 @@ export class AdminArticleComponent implements OnInit {
{name: '编辑', color: '#2db7f5', click: (d) => this.router.navigateByUrl(`/write?id=${d.id}`)},
]
}
]
];
}
deleteArticle(article: Article) {
this.apiService.deleteArticle(article.id).subscribe({
next: data => {
this.nzMessage.success('删除成功')
this.nzMessage.success('删除成功');
this.commonTableComponent.getData();
},
error: err => {
this.nzMessage.error(err.msg)
this.nzMessage.error(err.msg);
}
})
});
}
}

View File

@@ -4,7 +4,8 @@ import {RouterModule} from '@angular/router';
import {AdminArticleComponent} from './admin-article.component';
import {CommonTableModule} from '../components/common-table/common-table.module';
import {FormsModule} from '@angular/forms';
import {NzCheckboxModule, NzTagModule} from 'ng-zorro-antd';
import {NzCheckboxModule} from 'ng-zorro-antd/checkbox';
import {NzTagModule} from 'ng-zorro-antd/tag';
@NgModule({
declarations: [

View File

@@ -1,44 +1,44 @@
<common-table #commonTableComponent
[request]="request"
[headData]="headData"
cardTitle="评论管理"
[template]="{status:{temp:status,param:{'0':' 正常 ','3':'已删除'}},content:{temp:content}}">
[request]="request"
[template]="{status:{temp:status,param:{'0':' 正常 ','3':'已删除'}},content:{temp:content}}"
cardTitle="评论管理">
</common-table>
<ng-template let-originValue="originValue" let-value="value" #status>
<nz-tag nzColor="geekblue" *ngIf="originValue==0">{{value}}</nz-tag>
<nz-tag nzColor="#f50" *ngIf="originValue==3">{{value}}</nz-tag>
<ng-template #status let-originValue="originValue" let-value="value">
<nz-tag *ngIf="originValue==0" nzColor="geekblue">{{value}}</nz-tag>
<nz-tag *ngIf="originValue==3" nzColor="#f50">{{value}}</nz-tag>
</ng-template>
<ng-template #content let-value="value" let-data="data">
<ng-template #content let-data="data" let-value="value">
<editable-tag #editableTagComponent
(modalOK)="textChange($event,data)"
[key]="data.id"
[showBorder]="false"
[text]="value"
[showConfirmModal]="true"
(modalOK)="textChange($event,data)">
[text]="value">
</editable-tag>
</ng-template>
<nz-modal nzTitle="查看" [nzClosable]="true" [(nzVisible)]="modalData.visible" (nzOnOk)="modalData.visible=false"
[nzCancelText]="null">
<nz-modal (nzOnOk)="modalData.visible=false" [(nzVisible)]="modalData.visible" [nzCancelText]="null" [nzClosable]="true"
nzTitle="查看">
<ng-template #commentTemplateRef let-comment="comment">
<nz-comment [nzAuthor]="comment && comment.fromUser.displayName" [nzDatetime]="comment&&comment.date">
<nz-avatar nz-comment-avatar nzIcon="user"
[nzSrc]="comment && comment.fromUser && comment.fromUser.avatarImgUrl"></nz-avatar>
<nz-avatar [nzSrc]="comment && comment.fromUser && comment.fromUser.avatarImgUrl" nz-comment-avatar
nzIcon="user"></nz-avatar>
<nz-comment-content>
<p>{{ comment && comment.content }}</p>
</nz-comment-content>
<!-- <nz-comment-action>Reply to</nz-comment-action>-->
<!-- <nz-comment-action>Reply to</nz-comment-action>-->
<ng-container *ngIf="comment&&comment.children && comment.children.length">
<ng-template ngFor let-child [ngForOf]="comment&&comment.children">
<ng-template [ngTemplateOutlet]="commentTemplateRef" [ngTemplateOutletContext]="{ comment: child }">
<ng-template [ngForOf]="comment&&comment.children" let-child ngFor>
<ng-template [ngTemplateOutletContext]="{ comment: child }" [ngTemplateOutlet]="commentTemplateRef">
</ng-template>
</ng-template>
</ng-container>
</nz-comment>
</ng-template>
<ng-template [ngTemplateOutlet]="commentTemplateRef" [ngTemplateOutletContext]="{ comment: modalData.comment }">
<ng-template [ngTemplateOutletContext]="{ comment: modalData.comment }" [ngTemplateOutlet]="commentTemplateRef">
</ng-template>
</nz-modal>

View File

@@ -1,5 +1,5 @@
import {Component, OnInit, ViewChild} from '@angular/core';
import {NzMessageService} from 'ng-zorro-antd';
import {NzMessageService} from 'ng-zorro-antd/message';
import {ApiService} from '../../../api/api.service';
import {RequestObj} from '../../../class/HttpReqAndResp';
import {Comment, CommentReq} from '../../../class/Comment';
@@ -15,17 +15,30 @@ import {CommonTableComponent} from '../components/common-table/common-table.comp
})
export class AdminCommentComponent implements OnInit {
@ViewChild('editableTagComponent') editableTagComponent: EditableTagComponent;
@ViewChild('commonTableComponent') commonTableComponent: CommonTableComponent<Comment>;
request: RequestObj;
editInfo = {
id: null,
content: new CommentReq(null),
};
headData: Data<Comment>[];
modalData = {
visible: false,
comment: null
};
constructor(private apiService: ApiService, private messageService: NzMessageService, private userService: GlobalUserService,
private title: Title) {
this.title.setTitle('小海博客 | 评论管理')
this.title.setTitle('小海博客 | 评论管理');
this.userService.watchUserInfo({
next: data => {
let pathStr;
if (data.result) {
if (data.result.role === 'admin') {
pathStr = '/admin/comment/pagePath/*'
pathStr = '/admin/comment/pagePath/*';
} else {
pathStr = '/user/comment/pagePath/*'
pathStr = '/user/comment/pagePath/*';
}
this.request = {
path: pathStr,
@@ -34,27 +47,14 @@ export class AdminCommentComponent implements OnInit {
page: 1,
count: 10
}
}
};
}
},
error: () => null,
complete: () => null
})
});
}
request: RequestObj;
editInfo = {
id: null,
content: new CommentReq(null),
}
headData: Data<Comment>[];
modalData = {
visible: false,
comment: null
}
@ViewChild('editableTagComponent') editableTagComponent: EditableTagComponent;
@ViewChild('commonTableComponent') commonTableComponent: CommonTableComponent<Comment>;
ngOnInit(): void {
this.headData = [
{title: '主键', fieldValue: 'id', show: false, primaryKey: true},
@@ -74,7 +74,7 @@ export class AdminCommentComponent implements OnInit {
{
name: '查看',
click: data => {
this.modalData.visible = true
this.modalData.visible = true;
this.modalData.comment = data;
}
},
@@ -88,13 +88,13 @@ export class AdminCommentComponent implements OnInit {
deleteComment(data: Comment) {
if (data.status === 3) {
this.messageService.error('该数据已被删除');
return
return;
}
this.apiService.deleteComment(data.id).subscribe({
next: () => this.messageService.success('删除评论成功'),
error: err => this.messageService.error(err.msg),
complete: () => this.commonTableComponent.getData()
})
});
}
edit() {
@@ -106,7 +106,7 @@ export class AdminCommentComponent implements OnInit {
this.messageService.success(err.msg);
},
complete: () => null
})
});
}
textChange(value: { value: string; originalValue: string; changed: boolean }, data: Comment) {
@@ -115,7 +115,7 @@ export class AdminCommentComponent implements OnInit {
this.editInfo.content.pid = data.pid;
this.editInfo.content.id = data.id;
this.editInfo.content.content = value.value;
this.edit()
this.edit();
}
}
}

View File

@@ -3,7 +3,10 @@ import {CommonModule} from '@angular/common';
import {RouterModule} from '@angular/router';
import {AdminCommentComponent} from './admin-comment.component';
import {CommonTableModule} from '../components/common-table/common-table.module';
import {NzAvatarModule, NzCommentModule, NzModalModule, NzTagModule} from 'ng-zorro-antd';
import {NzAvatarModule} from 'ng-zorro-antd/avatar';
import {NzCommentModule} from 'ng-zorro-antd/comment';
import {NzModalModule} from 'ng-zorro-antd/modal';
import {NzTagModule} from 'ng-zorro-antd/tag';
import {EditableTagModule} from '../components/editable-tag/editable-tag.module';

View File

@@ -1,6 +1,6 @@
<div *ngIf="userInfo&&userInfo.role==='admin'">
<div nz-row>
<nz-card nzTitle="统计" nz-col nzXs="24" nzSm="12" nzSize="small">
<nz-card nz-col nzSize="small" nzSm="12" nzTitle="统计" nzXs="24">
<nz-row [nzGutter]="24">
<nz-col [nzSpan]="6">
<nz-statistic [nzValue]="(counts.articleCount | number)!" nzTitle="文章数量"></nz-statistic>
@@ -16,7 +16,7 @@
</nz-col>
</nz-row>
</nz-card>
<nz-card nzTitle="信息" nz-col nzXs="24" [nzSm]="{span:11,offset:1}" nzSize="small">
<nz-card [nzSm]="{span:11,offset:1}" nz-col nzSize="small" nzTitle="信息" nzXs="24">
<nz-row [nzGutter]="24">
<nz-col [nzSpan]="8">
<nz-statistic [nzValue]="(counts.visitorCount | number)!" nzTitle="总访问量"></nz-statistic>
@@ -32,9 +32,9 @@
</nz-card>
</div>
<div nz-row>
<nz-card style="width: 100%" nzSize="small" nzTitle="日志" [nzExtra]="reload">
<nz-card [nzExtra]="reload" nzSize="small" nzTitle="日志" style="width: 100%">
<ng-template #reload>
<a (click)="getLog()" title="刷新"><i nz-icon nzType="reload" nzTheme="outline"></i></a>
<a (click)="getLog()" title="刷新"><i nz-icon nzTheme="outline" nzType="reload"></i></a>
</ng-template>
<nz-spin [nzSpinning]="logLoading" style="width: 100%;">
<pre style="width: 100%;max-height: 500px;overflow: auto;">{{logText}}</pre>
@@ -44,11 +44,11 @@
</div>
<div *ngIf="userInfo&&userInfo.role==='user'">
<div nz-row>
<nz-card nzTitle="信息" nz-col nzXs="24" [nzMd]="{span:11}" [nzXl]="{span:6,offset:1}" nzSize="small">
<nz-card [nzMd]="{span:11}" [nzXl]="{span:6,offset:1}" nz-col nzSize="small" nzTitle="信息" nzXs="24">
<nz-statistic [nzValue]="userInfo.recentlyLandedDate?userInfo.recentlyLandedDate:''"
nzTitle="上次登录"></nz-statistic>
</nz-card>
<nz-card nzTitle="关于此博客" nzSize="small" nz-col nzXs="24" [nzMd]="{span:11,offset:2}" [nzXl]="{span:6,offset:2}">
<nz-card [nzMd]="{span:11,offset:2}" [nzXl]="{span:6,offset:2}" nz-col nzSize="small" nzTitle="关于此博客" nzXs="24">
<p>此博客由 <a href="https://github.com/xiaohai2271" target="_blank">禾几海(郑海)</a> 设计并实现的</p>
<p>博客自2019年3月开始开发编写 5月开始正式运行至今</p>
<p>博客所有代码都是开源的,你可以随意修改,运行和发布</p>
@@ -59,7 +59,7 @@
</p>
<p>如果觉得博客还不错请前往Github支持我给我点一个star吧</p>
</nz-card>
<nz-card nz-col nzXs="24" [nzMd]="{span:12,offset:6}" [nzXl]="{span:6,offset:2}">
<nz-card [nzMd]="{span:12,offset:6}" [nzXl]="{span:6,offset:2}" nz-col nzXs="24">
<p style="font-style: italic">坚强的信心,能使平凡的人做出惊人的事业。</p>
<p style="text-align: right"> ——马尔顿</p>
</nz-card>

View File

@@ -11,47 +11,46 @@ import {Title} from '@angular/platform-browser';
styleUrls: ['./admin-dashboard.component.less']
})
export class AdminDashboardComponent implements OnInit {
logLoading: boolean = true;
logText: string = null;
counts: {
articleCount: number;
visitorCount: number;
categoryCount: number;
tagCount: number;
commentCount: number;
} = {articleCount: 0, visitorCount: 0, categoryCount: 0, tagCount: 0, commentCount: 0};
dayVisitCount: number = 0;
userInfo: User = new User();
private isRequested: boolean = false;
constructor(private apiService: ApiService, private userService: GlobalUserService, private http: HttpClient,
private title: Title) {
this.title.setTitle('小海博客 | 后台管理');
this.getUserInfo();
}
logLoading: boolean = true;
logText: string = null;
counts: {
articleCount: number,
visitorCount: number,
categoryCount: number,
tagCount: number,
commentCount: number
} = {articleCount: 0, visitorCount: 0, categoryCount: 0, tagCount: 0, commentCount: 0}
dayVisitCount: number = 0;
userInfo: User = new User();
private isRequested: boolean = false;
ngOnInit(): void {
}
getLog() {
this.http.get('https://api.celess.cn/blog.log', {responseType: 'text'}).subscribe(data => {
this.logText = data;
this.logLoading = false
this.logLoading = false;
});
}
getCounts = () => this.apiService.counts().subscribe({
next: data => this.counts = data.result
})
});
getDayVisitCount = () => this.apiService.dayVisitCount().subscribe({
next: data => this.dayVisitCount = data.result
})
});
getUserInfo = () => this.userService.watchUserInfo({
next: data => {
this.userInfo = data.result
this.userInfo = data.result;
if (data.result && data.result.role === 'admin' && !this.isRequested) {
this.getLog();
this.getCounts();
@@ -61,5 +60,5 @@ export class AdminDashboardComponent implements OnInit {
},
error: () => null,
complete: () => null
})
});
}

View File

@@ -2,15 +2,13 @@ import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {AdminDashboardComponent} from './admin-dashboard.component';
import {RouterModule} from '@angular/router';
import {
NzButtonModule,
NzCardModule,
NzDividerModule,
NzGridModule,
NzIconModule,
NzSpinModule,
NzStatisticModule
} from 'ng-zorro-antd';
import {NzButtonModule} from 'ng-zorro-antd/button';
import {NzCardModule} from 'ng-zorro-antd/card';
import {NzDividerModule} from 'ng-zorro-antd/divider';
import {NzGridModule} from 'ng-zorro-antd/grid';
import {NzIconModule} from 'ng-zorro-antd/icon';
import {NzSpinModule} from 'ng-zorro-antd/spin';
import {NzStatisticModule} from 'ng-zorro-antd/statistic';
@NgModule({

View File

@@ -1,34 +1,34 @@
<common-table #commonTableComponent
cardTitle="友链管理"
[request]="request"
[headData]="headData"
[request]="request"
[template]="{open:{temp:open,param:{true:'可见',false:'不可见'}},delete:{temp:deleteTemp,param:{true:'已删除',false:'未删除'}}}"
cardTitle="友链管理"
>
<button nz-button (click)="addLink()">添加</button>
<button (click)="addLink()" nz-button>添加</button>
</common-table>
<ng-template #open let-value="value">
<label nz-checkbox nzDisabled [ngModel]="value"></label>
<label [ngModel]="value" nz-checkbox nzDisabled></label>
</ng-template>
<ng-template let-value="value" let-originValue="originValue" #deleteTemp>
<nz-tag [nzColor]="'blue'" *ngIf="originValue=='false'">{{value}}</nz-tag>
<nz-tag [nzColor]="'#ff5500'" *ngIf="originValue!='false'">{{value}}</nz-tag>
<ng-template #deleteTemp let-originValue="originValue" let-value="value">
<nz-tag *ngIf="originValue=='false'" [nzColor]="'blue'">{{value}}</nz-tag>
<nz-tag *ngIf="originValue!='false'" [nzColor]="'#ff5500'">{{value}}</nz-tag>
</ng-template>
<nz-modal [(nzVisible)]="modalVisible" [nzTitle]="modalTitle" (nzOnOk)="modalConfirm()"
(nzOnCancel)="modalVisible = false" [nzClosable]="true" [nzOkDisabled]="!formGroup.valid">
<form nz-form [formGroup]="formGroup">
<nz-modal (nzOnCancel)="modalVisible = false" (nzOnOk)="modalConfirm()" [(nzVisible)]="modalVisible"
[nzClosable]="true" [nzOkDisabled]="!formGroup.valid" [nzTitle]="modalTitle">
<form [formGroup]="formGroup" nz-form>
<nz-form-item>
<nz-form-label nzFlex="80px" nzRequired>网站名称</nz-form-label>
<nz-form-control nzFlex="auto" nzErrorTip="网站名称不可为空">
<input nz-input formControlName="name">
<nz-form-control nzErrorTip="网站名称不可为空" nzFlex="auto">
<input formControlName="name" nz-input>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzFlex="80px" nzRequired>网站链接</nz-form-label>
<nz-form-control nzFlex="auto" [nzErrorTip]="nameErrTip">
<input nz-input formControlName="url">
<nz-form-control [nzErrorTip]="nameErrTip" nzFlex="auto">
<input formControlName="url" nz-input>
<ng-template #nameErrTip>
<div *ngIf="formGroup.controls.url.hasError('required')">网站链接不可为空</div>
<div *ngIf="formGroup.controls.url.hasError('pattern')">网站链接格式不正确</div>
@@ -38,8 +38,8 @@
</nz-form-item>
<nz-form-item>
<nz-form-label nzFlex="80px" nzRequired>是否公开</nz-form-label>
<nz-form-control nzFlex="auto" nzErrorTip="不可为空">
<nz-select nzPlaceHolder="请选择" formControlName="open" [nzAllowClear]="true">
<nz-form-control nzErrorTip="不可为空" nzFlex="auto">
<nz-select [nzAllowClear]="true" formControlName="open" nzPlaceHolder="请选择">
<nz-option [nzValue]="true" nzLabel="公开"></nz-option>
<nz-option [nzValue]="false" nzLabel="不公开"></nz-option>
</nz-select>
@@ -47,20 +47,20 @@
</nz-form-item>
<nz-form-item>
<nz-form-label nzFlex="80px">网站图标</nz-form-label>
<nz-form-control nzFlex="auto" nzErrorTip="链接格式不正确">
<nz-form-control nzErrorTip="链接格式不正确" nzFlex="auto">
<nz-input-group [nzSuffix]="icon" nzSize="large">
<input nz-input formControlName="iconPath">
<input formControlName="iconPath" nz-input>
</nz-input-group>
<ng-template #icon>
<img style="width: 25px;height: 25px" *ngIf="formGroup.value.iconPath"
[src]="formGroup.value.iconPath" alt="icon">
<img *ngIf="formGroup.value.iconPath" [src]="formGroup.value.iconPath"
alt="icon" style="width: 25px;height: 25px">
</ng-template>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzFlex="80px">网站描述</nz-form-label>
<nz-form-control nzFlex="auto" nzErrorTip="可输入最大文字长度为255">
<textarea nz-input formControlName="desc" [nzAutosize]="{ minRows: 2, maxRows: 6 }"></textarea>
<nz-form-control nzErrorTip="可输入最大文字长度为255" nzFlex="auto">
<textarea [nzAutosize]="{ minRows: 2, maxRows: 6 }" formControlName="desc" nz-input></textarea>
</nz-form-control>
</nz-form-item>

View File

@@ -2,8 +2,8 @@ import {Component, OnInit, ViewChild} from '@angular/core';
import {RequestObj, Response} from '../../../class/HttpReqAndResp';
import {Link} from '../../../class/Link';
import {ApiService} from '../../../api/api.service';
import {NzMessageService} from 'ng-zorro-antd';
import {FormControl, FormGroup, Validators} from '@angular/forms';
import {NzMessageService} from 'ng-zorro-antd/message';
import {UntypedFormControl, UntypedFormGroup, Validators} from '@angular/forms';
import {Observable} from 'rxjs';
import {Title} from '@angular/platform-browser';
import {CommonTableComponent} from '../components/common-table/common-table.component';
@@ -15,27 +15,33 @@ import {Data} from '../components/common-table/data';
})
export class AdminLinkComponent implements OnInit {
constructor(private apiService: ApiService, private messageService: NzMessageService, private title: Title) {
this.title.setTitle('小海博客 | 友链管理');
this.formGroup = new FormGroup({
id: new FormControl(null),
name: new FormControl(null, [Validators.required]),
url: new FormControl(null, [Validators.required, Validators.pattern(/^(https:\/\/|http:\/\/|)([\w-]+\.)+[\w-]+(\/[\w-./?%&=]*)?$/)]),
open: new FormControl(null, [Validators.required]),
desc: new FormControl(null, [Validators.maxLength(255)]),
iconPath: new FormControl(null, [Validators.pattern(/^(https:\/\/|http:\/\/|)([\w-]+\.)+[\w-]+(\/[\w-./?%&=]*)?$/)]),
oper: new FormControl(null)
})
}
@ViewChild('commonTableComponent') commonTableComponent: CommonTableComponent<Link>;
modalVisible: boolean = false;
modalTitle: string = '';
formGroup: FormGroup;
formGroup: UntypedFormGroup;
request: RequestObj;
@ViewChild('commonTableComponent') commonTableComponent: CommonTableComponent<Link>
headData: Data<Link>[];
constructor(private apiService: ApiService, private messageService: NzMessageService, private title: Title) {
this.title.setTitle('小海博客 | 友链管理');
this.formGroup = new UntypedFormGroup({
id: new UntypedFormControl(null),
name: new UntypedFormControl(null, [Validators.required]),
url: new UntypedFormControl(null, [
Validators.required,
Validators.pattern(/^(https:\/\/|http:\/\/|)([\w-]+\.)+[\w-]+(\/[\w-./?%&=]*)?$/)
]
),
open: new UntypedFormControl(null, [Validators.required]),
desc: new UntypedFormControl(null, [Validators.maxLength(255)]),
iconPath: new UntypedFormControl(null, [
Validators.pattern(/^(https:\/\/|http:\/\/|)([\w-]+\.)+[\w-]+(\/[\w-./?%&=]*)?$/)
]
),
oper: new UntypedFormControl(null)
});
}
ngOnInit(): void {
this.request = {
path: '/admin/links',
@@ -44,7 +50,7 @@ export class AdminLinkComponent implements OnInit {
count: 10,
page: 1
}
}
};
this.headData = [
{title: '主键', fieldValue: 'id', show: false, primaryKey: true},
{title: '友链名称', fieldValue: 'name', show: true},
@@ -73,19 +79,19 @@ export class AdminLinkComponent implements OnInit {
this.messageService.error('删除失败');
},
complete: () => null,
})
});
}
showEdit(data: Link) {
this.modalVisible = true;
this.modalTitle = '编辑友链信息';
this.formGroup.patchValue(data);
this.formGroup.controls.oper.setValue('edit')
this.formGroup.controls.oper.setValue('edit');
}
modalConfirm() {
this.modalVisible = false;
const linkReq: Link = this.formGroup.value
const linkReq: Link = this.formGroup.value;
const oper = this.formGroup.value.oper;
let observable: Observable<Response<Link>>;
if (oper === 'edit') {
@@ -98,13 +104,13 @@ export class AdminLinkComponent implements OnInit {
next: data => this.messageService.success('操作成功'),
error: err => this.messageService.error('操作失败,' + err.msg),
complete: () => this.commonTableComponent.getData()
})
});
}
addLink() {
this.modalVisible = true;
this.modalTitle = '新增友链信息';
this.formGroup.reset();
this.formGroup.controls.oper.setValue('add')
this.formGroup.controls.oper.setValue('add');
}
}

View File

@@ -3,15 +3,13 @@ import {CommonModule} from '@angular/common';
import {RouterModule} from '@angular/router';
import {AdminLinkComponent} from './admin-link.component';
import {CommonTableModule} from '../components/common-table/common-table.module';
import {
NzButtonModule,
NzCheckboxModule,
NzFormModule,
NzInputModule,
NzModalModule,
NzSelectModule,
NzTagModule
} from 'ng-zorro-antd';
import {NzButtonModule} from 'ng-zorro-antd/button';
import {NzCheckboxModule} from 'ng-zorro-antd/checkbox';
import {NzFormModule} from 'ng-zorro-antd/form';
import {NzInputModule} from 'ng-zorro-antd/input';
import {NzModalModule} from 'ng-zorro-antd/modal';
import {NzSelectModule} from 'ng-zorro-antd/select';
import {NzTagModule} from 'ng-zorro-antd/tag';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';

View File

@@ -1,14 +1,14 @@
<div class="inner-content">
<nz-card nzTitle="" nzSize="small">
<nz-card nzSize="small" nzTitle="">
<nz-tabset [nzTabBarExtraContent]="reload">
<nz-tab nzTitle="分类管理" (nzClick)="tabChanged('tag')">
<nz-tab (nzClick)="tabChanged('tag')" nzTitle="分类管理">
<div style="margin-bottom: 15px;width: 150px">
<editable-tag [showBorder]="false"
[showEditIcon]="false"
[doubleClick]="false"
size="default"
<editable-tag (valueChange)="addCategory($event)"
[autoClear]="true"
(valueChange)="addCategory($event)"
[doubleClick]="false"
[showBorder]="false"
[showEditIcon]="false"
size="default"
>
<button nz-button>新增</button>
</editable-tag>
@@ -19,7 +19,7 @@
[template]="{name:{temp:nameTemplate}}">
</common-table>
</nz-tab>
<nz-tab nzTitle="标签管理" (nzClick)="tabChanged('category')">
<nz-tab (nzClick)="tabChanged('category')" nzTitle="标签管理">
<common-table #tagCTComponent
[headData]="tagCTData.headData"
[request]="tagCTData.request"
@@ -30,15 +30,15 @@
</nz-card>
</div>
<ng-template #reload>
<a (click)="getData()" title="刷新"><i nz-icon nzType="reload" nzTheme="outline"></i></a>
<a (click)="getData()" title="刷新"><i nz-icon nzTheme="outline" nzType="reload"></i></a>
</ng-template>
<ng-template #nameTemplate let-value="value" let-data="data">
<ng-template #nameTemplate let-data="data" let-value="value">
<editable-tag #editableTagComponent
(modalOK)="textChange($event,data)"
[key]="data.id"
[showBorder]="false"
[text]="value"
[showConfirmModal]="true"
(modalOK)="textChange($event,data)">
[text]="value">
</editable-tag>
</ng-template>

View File

@@ -1,8 +1,8 @@
import {Component, OnInit, ViewChild} from '@angular/core';
import {NzMessageService} from 'ng-zorro-antd';
import {NzMessageService} from 'ng-zorro-antd/message';
import {Category, Tag} from '../../../class/Tag';
import {ApiService} from '../../../api/api.service';
import {PageList, RequestObj} from '../../../class/HttpReqAndResp';
import {RequestObj} from '../../../class/HttpReqAndResp';
import {Title} from '@angular/platform-browser';
import {Data} from '../components/common-table/data';
import {CommonTableComponent} from '../components/common-table/common-table.component';
@@ -15,27 +15,28 @@ import {EditableTagComponent} from '../components/editable-tag/editable-tag.comp
})
export class AdminTagComponent implements OnInit {
@ViewChild('categoryCTComponent', {static: true}) categoryCTComponent: CommonTableComponent<Category>;
@ViewChild('tagCTComponent', {static: true}) tagCTComponent: CommonTableComponent<Tag>;
@ViewChild('editableTagComponent') editableTagComponent: EditableTagComponent;
categoryCTData: { headData: Data<Category>[]; commonTable: CommonTableComponent<Category>; request: RequestObj } = {
headData: null,
commonTable: null,
request: null
};
tagCTData: { headData: Data<Category>[]; commonTable: CommonTableComponent<Tag>; request: RequestObj } = {
headData: null,
commonTable: null,
request: null
};
getData: any;
private updateData: any;
constructor(private apiService: ApiService, private nzMessageService: NzMessageService, private title: Title, private router: Router) {
}
categoryCTData: { headData: Data<Category>[], commonTable: CommonTableComponent<Category>, request: RequestObj } = {
headData: null,
commonTable: null,
request: null
}
tagCTData: { headData: Data<Category>[], commonTable: CommonTableComponent<Tag>, request: RequestObj } = {
headData: null,
commonTable: null,
request: null
}
@ViewChild('categoryCTComponent', {static: true}) categoryCTComponent: CommonTableComponent<Category>
@ViewChild('tagCTComponent', {static: true}) tagCTComponent: CommonTableComponent<Tag>
@ViewChild('editableTagComponent') editableTagComponent: EditableTagComponent
private updateData: any;
getData: any;
ngOnInit(): void {
this.title.setTitle('小海博客 | 标签分类管理')
this.title.setTitle('小海博客 | 标签分类管理');
this.categoryCTData = {
commonTable: this.categoryCTComponent,
headData: [
@@ -64,7 +65,7 @@ export class AdminTagComponent implements OnInit {
count: 1000
}
}
}
};
this.tagCTData = {
commonTable: this.tagCTComponent,
headData: [
@@ -87,7 +88,7 @@ export class AdminTagComponent implements OnInit {
count: 10
}
}
}
};
this.getData = this.categoryCTComponent.getData;
}
@@ -96,29 +97,29 @@ export class AdminTagComponent implements OnInit {
if (mode === 'tag') {
this.apiService.deleteTag(id).subscribe({
next: data => {
this.nzMessageService.success('删除成功')
this.nzMessageService.success('删除成功');
this.tagCTComponent.getData();
},
complete: () => null,
error: err => this.nzMessageService.error(err.msg)
})
});
} else if (mode === 'category') {
this.apiService.deleteCategory(id).subscribe({
next: data => {
this.nzMessageService.success('删除成功')
this.nzMessageService.success('删除成功');
this.categoryCTComponent.getData();
},
complete: () => null,
error: err => this.nzMessageService.error(err.msg)
})
});
}
}
addCategory($event: { value: string; originalValue: string; changed: boolean }) {
if (!$event.value || !$event.changed) return
if (!$event.value || !$event.changed) {return;}
this.apiService.createCategory($event.value).subscribe({
next: data => {
this.nzMessageService.success('新增成功')
this.nzMessageService.success('新增成功');
this.getData = this.categoryCTComponent.getData();
},
complete: () => null,
@@ -133,14 +134,14 @@ export class AdminTagComponent implements OnInit {
this.updateData = this.apiService.updateTag;
} else {
this.getData = this.tagCTComponent.getData;
this.updateData = this.apiService.updateCategory
this.updateData = this.apiService.updateCategory;
}
}
textChange(value: { value: string; originalValue: string; changed: boolean }, textData: Category | Tag) {
this.updateData(textData.id, value.value).subscribe({
next: data => {
this.nzMessageService.success('更新成功')
this.nzMessageService.success('更新成功');
this.tagCTComponent.getData();
this.categoryCTComponent.getData();
},

View File

@@ -5,7 +5,10 @@ import {AdminTagComponent} from './admin-tag.component';
import {FormsModule} from '@angular/forms';
import {CommonTableModule} from '../components/common-table/common-table.module';
import {EditableTagModule} from '../components/editable-tag/editable-tag.module';
import {NzButtonModule, NzCardModule, NzIconModule, NzTabsModule} from "ng-zorro-antd";
import {NzButtonModule} from 'ng-zorro-antd/button';
import {NzCardModule} from 'ng-zorro-antd/card';
import {NzIconModule} from 'ng-zorro-antd/icon';
import {NzTabsModule} from 'ng-zorro-antd/tabs';
@NgModule({

View File

@@ -1,8 +1,8 @@
<common-table [request]="request" [headData]="headData" cardTitle="更新管理">
<button nz-button (click)="showModal()">新增</button>
<common-table [headData]="headData" [request]="request" cardTitle="更新管理">
<button (click)="showModal()" nz-button>新增</button>
</common-table>
<nz-modal [(nzVisible)]="modalData.visible" [nzClosable]="true" (nzOnCancel)="modalData.visible = false"
(nzOnOk)="confirm()" [nzTitle]="modalData.title">
<textarea nz-input [(ngModel)]="modalData.content" [nzAutosize]="{ minRows: 2, maxRows: 8 }"></textarea>
<nz-modal (nzOnCancel)="modalData.visible = false" (nzOnOk)="confirm()" [(nzVisible)]="modalData.visible"
[nzClosable]="true" [nzTitle]="modalData.title">
<textarea [(ngModel)]="modalData.content" [nzAutosize]="{ minRows: 2, maxRows: 8 }" nz-input></textarea>
</nz-modal>

View File

@@ -1,9 +1,9 @@
import {Component, OnInit} from '@angular/core';
import {NzMessageService} from 'ng-zorro-antd';
import {NzMessageService} from 'ng-zorro-antd/message';
import {Title} from '@angular/platform-browser';
import {Observable} from 'rxjs';
import {ApiService} from '../../../api/api.service';
import {PageList, RequestObj, Response} from '../../../class/HttpReqAndResp';
import {RequestObj, Response} from '../../../class/HttpReqAndResp';
import {UpdateInfo} from '../../../class/UpdateInfo';
import {Data} from '../components/common-table/data';
@@ -14,9 +14,6 @@ import {Data} from '../components/common-table/data';
export class AdminUpdateComponent implements OnInit {
constructor(private apiService: ApiService, private nzMessage: NzMessageService, private title: Title) {
}
modalData = {
visible: false,
content: null,
@@ -26,8 +23,11 @@ export class AdminUpdateComponent implements OnInit {
headData: Data<UpdateInfo>[];
request: RequestObj;
constructor(private apiService: ApiService, private nzMessage: NzMessageService, private title: Title) {
}
ngOnInit(): void {
this.title.setTitle('小海博客 | 更新信息管理')
this.title.setTitle('小海博客 | 更新信息管理');
this.headData = [
{fieldValue: 'id', show: false, title: '主键', primaryKey: true},
{fieldValue: 'info', show: true, title: '更新内容'},
@@ -46,7 +46,7 @@ export class AdminUpdateComponent implements OnInit {
count: 1,
page: 10,
}
}
};
}
@@ -54,21 +54,21 @@ export class AdminUpdateComponent implements OnInit {
this.apiService.deleteWebUpdateInfo(id).subscribe({
next: data => this.nzMessage.success('删除成功'),
error: err => this.nzMessage.error(err.msg)
})
});
}
confirm() {
this.modalData.visible = false;
let observable: Observable<Response<UpdateInfo>>
let observable: Observable<Response<UpdateInfo>>;
if (this.modalData.id) {
observable = this.apiService.updateWebUpdateInfo(this.modalData.id, this.modalData.content)
observable = this.apiService.updateWebUpdateInfo(this.modalData.id, this.modalData.content);
} else {
observable = this.apiService.createWebUpdateInfo(this.modalData.content)
observable = this.apiService.createWebUpdateInfo(this.modalData.content);
}
observable.subscribe({
next: data => this.nzMessage.success('操作成功'),
error: err => this.nzMessage.error(err.msg)
})
});
}
showModal(data?: UpdateInfo) {

View File

@@ -5,7 +5,9 @@ import {AdminUpdateComponent} from './admin-update.component';
import {FormsModule} from '@angular/forms';
import {CommonTableModule} from '../components/common-table/common-table.module';
import {NzButtonModule, NzInputModule, NzModalModule} from 'ng-zorro-antd';
import {NzButtonModule} from 'ng-zorro-antd/button';
import {NzInputModule} from 'ng-zorro-antd/input';
import {NzModalModule} from 'ng-zorro-antd/modal';
@NgModule({

View File

@@ -1,56 +1,56 @@
<common-table [headData]="headData"
[request]="request"
cardTitle="用户信息管理"
[template]="{role:{temp:role},emailStatus:{temp:emailStatus,param:{true:'已验证',false:'未验证'}}}"
cardTitle="用户信息管理"
>
</common-table>
<ng-template let-value="value" #role>
<nz-tag [nzColor]="'blue'" *ngIf="value == 'admin'">{{value}}</nz-tag>
<nz-tag [nzColor]="'purple'" *ngIf="value == 'user'">{{value}}</nz-tag>
<ng-template #role let-value="value">
<nz-tag *ngIf="value == 'admin'" [nzColor]="'blue'">{{value}}</nz-tag>
<nz-tag *ngIf="value == 'user'" [nzColor]="'purple'">{{value}}</nz-tag>
</ng-template>
<ng-template let-value="value" let-originValue="originValue" #emailStatus>
<nz-tag [nzColor]="'green'" *ngIf="originValue !='false'">{{value}}</nz-tag>
<nz-tag [nzColor]="'red'" *ngIf="originValue !='true'">{{value}}</nz-tag>
<ng-template #emailStatus let-originValue="originValue" let-value="value">
<nz-tag *ngIf="originValue !='false'" [nzColor]="'green'">{{value}}</nz-tag>
<nz-tag *ngIf="originValue !='true'" [nzColor]="'red'">{{value}}</nz-tag>
</ng-template>
<nz-modal [(nzVisible)]="modalData.visible" [nzClosable]="true" [nzTitle]="modalData.title"
(nzOnCancel)="modalData.visible = false" (nzOnOk)="modalConfirm()"
<nz-modal (nzOnCancel)="modalData.visible = false" (nzOnOk)="modalConfirm()" [(nzVisible)]="modalData.visible"
[nzClosable]="true" [nzContent]="showContent"
[nzFooter]="modalData.isEdit?editContentFooter:showContentFooter"
[nzContent]="showContent">
[nzTitle]="modalData.title">
<ng-template #showContent>
<form nz-form [formGroup]="formGroup" (ngSubmit)="modalConfirm()">
<form (ngSubmit)="modalConfirm()" [formGroup]="formGroup" nz-form>
<nz-form-item>
<nz-form-label nzSpan="4" nzRequired>邮箱</nz-form-label>
<nz-form-label nzRequired nzSpan="4">邮箱</nz-form-label>
<nz-form-control nzSpan="18">
<input type="email" nz-input formControlName="email"
[disabled]="!modalData.isEdit">
<input [disabled]="!modalData.isEdit" formControlName="email" nz-input
type="email">
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzSpan="4" nzRequired>昵称</nz-form-label>
<nz-form-label nzRequired nzSpan="4">昵称</nz-form-label>
<nz-form-control nzSpan="18">
<input type="text" nz-input formControlName="displayName" [disabled]="!modalData.isEdit">
<input [disabled]="!modalData.isEdit" formControlName="displayName" nz-input type="text">
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzSpan="4" nzRequired>角色</nz-form-label>
<nz-form-label nzRequired nzSpan="4">角色</nz-form-label>
<nz-form-control nzSpan="18">
<nz-select formControlName="role" [nzDisabled]="!modalData.isEdit||formGroup.value.id==user.id">
<nz-option nzValue="admin" nzLabel="admin"></nz-option>
<nz-option nzValue="user" nzLabel="user"></nz-option>
<nz-select [nzDisabled]="!modalData.isEdit||formGroup.value.id==user.id" formControlName="role">
<nz-option nzLabel="admin" nzValue="admin"></nz-option>
<nz-option nzLabel="user" nzValue="user"></nz-option>
</nz-select>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzSpan="4" nzRequired>状态</nz-form-label>
<nz-form-label nzRequired nzSpan="4">状态</nz-form-label>
<nz-form-control nzSpan="18">
<nz-radio-group formControlName="emailStatus" [nzDisabled]="!modalData.isEdit">
<label nz-radio [nzValue]="true">邮箱已验证</label>
<label nz-radio [nzValue]="false">邮箱未验证</label>
<nz-radio-group [nzDisabled]="!modalData.isEdit" formControlName="emailStatus">
<label [nzValue]="true" nz-radio>邮箱已验证</label>
<label [nzValue]="false" nz-radio>邮箱未验证</label>
</nz-radio-group>
</nz-form-control>
</nz-form-item>
@@ -58,14 +58,14 @@
<nz-form-item *ngIf="modalData.isEdit">
<nz-form-label nzSpan="4">密码</nz-form-label>
<nz-form-control nzSpan="18">
<a *ngIf="!modalData.resetPwd" (click)="modalData.resetPwd = true">
重设密码<i nz-icon nzType="edit" nzTheme="twotone" style="margin-left: 10px;"></i>
<a (click)="modalData.resetPwd = true" *ngIf="!modalData.resetPwd">
重设密码<i nz-icon nzTheme="twotone" nzType="edit" style="margin-left: 10px;"></i>
</a>
<nz-input-group *ngIf="modalData.resetPwd" [nzSuffix]="cancelBtn" nzSize="small">
<input type="password" nz-input formControlName="pwd" autocomplete="new-password"
[disabled]="!modalData.isEdit">
<input [disabled]="!modalData.isEdit" autocomplete="new-password" formControlName="pwd" nz-input
type="password">
<ng-template #cancelBtn>
<button nz-button (click)="modalData.resetPwd = false" nzSize="small" nzType="link">取消
<button (click)="modalData.resetPwd = false" nz-button nzSize="small" nzType="link">取消
</button>
</ng-template>
</nz-input-group>
@@ -75,20 +75,20 @@
<nz-form-item>
<nz-form-label nzSpan="4">描述</nz-form-label>
<nz-form-control nzSpan="18">
<textarea nz-input [nzAutosize]="{ minRows: 2, maxRows: 4 }" formControlName="desc"
[disabled]="!modalData.isEdit"></textarea>
<textarea [disabled]="!modalData.isEdit" [nzAutosize]="{ minRows: 2, maxRows: 4 }" formControlName="desc"
nz-input></textarea>
</nz-form-control>
</nz-form-item>
</form>
</ng-template>
<ng-template #showContentFooter>
<button nz-button (click)="modalData.visible = false">关闭</button>
<button (click)="modalData.visible = false" nz-button>关闭</button>
</ng-template>
<ng-template #editContentFooter>
<button nz-button (click)="modalData.visible = false">取消</button>
<button nz-button (click)="modalConfirm()" nzType="primary">提交</button>
<button (click)="modalData.visible = false" nz-button>取消</button>
<button (click)="modalConfirm()" nz-button nzType="primary">提交</button>
</ng-template>
</nz-modal>

View File

@@ -1,7 +1,7 @@
import {Component, OnInit} from '@angular/core';
import {NzMessageService} from 'ng-zorro-antd';
import {NzMessageService} from 'ng-zorro-antd/message';
import {Title} from '@angular/platform-browser';
import {FormControl, FormGroup} from '@angular/forms';
import {UntypedFormControl, UntypedFormGroup} from '@angular/forms';
import {RequestObj} from '../../../class/HttpReqAndResp';
import {ApiService} from '../../../api/api.service';
import {User} from '../../../class/User';
@@ -14,38 +14,37 @@ import {Data} from '../components/common-table/data';
})
export class AdminUserComponent implements OnInit {
constructor(private apiService: ApiService, private title: Title, private messageService: NzMessageService,
private userService: GlobalUserService) {
this.formGroup = new FormGroup({
id: new FormControl(null),
email: new FormControl(''),
displayName: new FormControl(''),
emailStatus: new FormControl(null),
desc: new FormControl(null),
role: new FormControl(null),
pwd: new FormControl(''),
});
this.userService.watchUserInfo({
next: data => this.user = data.result,
error: null,
complete: null
})
}
user: User;
modalData = {
visible: false,
title: null,
isEdit: false,
resetPwd: false
}
formGroup: FormGroup;
};
formGroup: UntypedFormGroup;
headData: Data<User>[];
request: RequestObj;
constructor(private apiService: ApiService, private title: Title, private messageService: NzMessageService,
private userService: GlobalUserService) {
this.formGroup = new UntypedFormGroup({
id: new UntypedFormControl(null),
email: new UntypedFormControl(''),
displayName: new UntypedFormControl(''),
emailStatus: new UntypedFormControl(null),
desc: new UntypedFormControl(null),
role: new UntypedFormControl(null),
pwd: new UntypedFormControl(''),
});
this.userService.watchUserInfo({
next: data => this.user = data.result,
error: null,
complete: null
});
}
ngOnInit(): void {
this.title.setTitle('小海博客 | 用户管理')
this.title.setTitle('小海博客 | 用户管理');
this.request = {
path: '/admin/users',
method: 'GET',
@@ -79,24 +78,24 @@ export class AdminUserComponent implements OnInit {
this.apiService.deleteUser(id).subscribe({
next: data => this.messageService.success('删除成功'),
error: err => this.messageService.error(err.msg)
})
});
}
showModal(isEdit: boolean, data: User) {
this.modalData.visible = true;
this.modalData.isEdit = isEdit;
this.modalData.title = isEdit ? '编辑用户' : '查看用户'
this.modalData.title = isEdit ? '编辑用户' : '查看用户';
this.formGroup.reset();
this.formGroup.patchValue(data);
}
modalConfirm() {
this.modalData.visible = false
this.modalData.visible = false;
this.apiService.adminUpdateUser(this.formGroup.value).subscribe({
next: data => {
this.messageService.success('修改用户信息成功');
this.userService.refreshUserInfo();
}
})
});
}
}

View File

@@ -4,15 +4,15 @@ import {RouterModule} from '@angular/router';
import {AdminUserComponent} from './admin-user.component';
import {ReactiveFormsModule} from '@angular/forms';
import {CommonTableModule} from '../components/common-table/common-table.module';
import {
NzButtonModule,
NzFormModule,
NzGridModule,
NzIconModule,
NzInputModule, NzModalModule,
NzRadioModule,
NzSelectModule, NzTagModule
} from 'ng-zorro-antd';
import {NzButtonModule} from 'ng-zorro-antd/button';
import {NzFormModule} from 'ng-zorro-antd/form';
import {NzGridModule} from 'ng-zorro-antd/grid';
import {NzIconModule} from 'ng-zorro-antd/icon';
import {NzInputModule} from 'ng-zorro-antd/input';
import {NzModalModule} from 'ng-zorro-antd/modal';
import {NzRadioModule} from 'ng-zorro-antd/radio';
import {NzSelectModule} from 'ng-zorro-antd/select';
import {NzTagModule} from 'ng-zorro-antd/tag';
@NgModule({

View File

@@ -1,4 +1,4 @@
<common-table [request]="request" [headData]="headData" cardTitle="访客信息管理">
<common-table [headData]="headData" [request]="request" cardTitle="访客信息管理">
</common-table>

View File

@@ -11,38 +11,31 @@ import {Data} from '../components/common-table/data';
})
export class AdminVisitorComponent implements OnInit {
headData: Data<Visitor>[];
request: RequestObj;
constructor(private apiService: ApiService, private title: Title) {
}
headData: Data<Visitor>[];
request: RequestObj
/***
* browserName: "Chrome 8"
browserVersion: "83.0.4103.116"
date: "2020-07-11 09:30:13"
id: 3131
ip: "127.0.0.1"
osname: "Windows 10"
*/
ngOnInit(): void {
this.title.setTitle('小海博客 | 访客信息管理')
this.title.setTitle('小海博客 | 访客信息管理');
this.request = {
path: '/admin/visitor/page',
method: 'GET',
queryParam: {
count: 1,
page: 10,
showLocation: location
showLocation: true
}
}
};
this.headData = [
{fieldValue: 'id', title: '主键', show: false, primaryKey: true},
{fieldValue: 'date', title: '访问日期', show: true},
{fieldValue: 'browserName', title: '浏览器', show: true},
{fieldValue: 'ip', title: 'ip地址', show: true},
{fieldValue: 'location', title: '位置', show: true},
{fieldValue: 'browserName', title: '浏览器', show: true},
{fieldValue: 'browserVersion', title: '浏览器版本', show: true},
{fieldValue: 'osname', title: '系统', show: true}
]
];
}
}

View File

@@ -1,40 +1,40 @@
<c-admin-header (infoClicked)="showInfoDrawer()"></c-admin-header>
<nz-layout class="layout">
<nz-sider nzCollapsible
<nz-sider *ngIf="user"
[(nzCollapsed)]="isCollapsed"
[nzBreakpoint]="'lg'"
[nzCollapsedWidth]="0"
[nzZeroTrigger]="zeroTrigger"
nzTheme="light"
*ngIf="user">
<ul nz-menu nzTheme="light" nzMode="inline" [nzInlineCollapsed]="isCollapsed">
nzCollapsible
nzTheme="light">
<ul [nzInlineCollapsed]="isCollapsed" nz-menu nzMode="inline" nzTheme="light">
<li nz-menu-item routerLink="/admin">
<i nz-icon nzType="dashboard" nzTheme="outline"></i>
<i nz-icon nzTheme="outline" nzType="dashboard"></i>
<span>后台首页</span>
</li>
<li nz-submenu nzTitle="文章管理" nzIcon="file" *ngIf="user.role=='admin'">
<li *ngIf="user.role=='admin'" nz-submenu nzIcon="file" nzTitle="文章管理">
<ul>
<li nz-menu-item>
<a routerLink="/write">
<i nz-icon nzType="form" nzTheme="outline"></i>
<i nz-icon nzTheme="outline" nzType="form"></i>
<span>新增文章</span>
</a>
</li>
<li nz-menu-item routerLink="/admin/article">
<i nz-icon nzType="ordered-list" nzTheme="outline"></i>
<i nz-icon nzTheme="outline" nzType="ordered-list"></i>
<span>文章列表</span>
</li>
</ul>
</li>
<li nz-menu-item routerLink="/admin/comment">
<i nz-icon nzType="message" nzTheme="outline"></i>
<i nz-icon nzTheme="outline" nzType="message"></i>
<span>评论管理</span>
</li>
<li nz-menu-item routerLink="/admin/tag" *ngIf="user.role=='admin'">
<i nz-icon nzType="tags" nzTheme="outline"></i>
<li *ngIf="user.role=='admin'" nz-menu-item routerLink="/admin/tag">
<i nz-icon nzTheme="outline" nzType="tags"></i>
<span>标签管理</span>
</li>
@@ -43,37 +43,37 @@
<!-- <span>分类管理</span>-->
<!-- </li>-->
<li nz-menu-item routerLink="/admin/user" *ngIf="user.role=='admin'">
<i nz-icon nzType="user" nzTheme="outline"></i>
<li *ngIf="user.role=='admin'" nz-menu-item routerLink="/admin/user">
<i nz-icon nzTheme="outline" nzType="user"></i>
<span>用户管理</span>
</li>
<li nz-menu-item routerLink="/admin/link" *ngIf="user.role=='admin'">
<i nz-icon nzType="link" nzTheme="outline"></i>
<li *ngIf="user.role=='admin'" nz-menu-item routerLink="/admin/link">
<i nz-icon nzTheme="outline" nzType="link"></i>
<span>友链管理</span>
</li>
<li nz-menu-item routerLink="/admin/visitor" *ngIf="user.role=='admin'">
<i nz-icon nzType="chrome" nzTheme="outline"></i>
<li *ngIf="user.role=='admin'" nz-menu-item routerLink="/admin/visitor">
<i nz-icon nzTheme="outline" nzType="chrome"></i>
<span>访问管理</span>
</li>
<li nz-menu-item routerLink="/admin/update" *ngIf="user.role=='admin'">
<i nz-icon nzType="arrow-up" nzTheme="outline"></i>
<li *ngIf="user.role=='admin'" nz-menu-item routerLink="/admin/update">
<i nz-icon nzTheme="outline" nzType="arrow-up"></i>
<span>更新管理</span>
</li>
<li nz-menu-item (click)="infoDrawerVisible = true">
<i nz-icon nzType="idcard" nzTheme="outline"></i>
<li (click)="infoDrawerVisible = true" nz-menu-item>
<i nz-icon nzTheme="outline" nzType="idcard"></i>
<span>查看信息</span>
</li>
<!--TODO : do something here ..... -->
<nz-card class="myCard" *ngIf="!isCollapsed&&user.role=='admin'">
<nz-card *ngIf="!isCollapsed&&user.role=='admin'" class="myCard">
<p>别管别人言语</p>
<p>做最好的自己</p>
</nz-card>
<nz-card class="myCard" *ngIf="!isCollapsed&&user.role=='user'">
<nz-card *ngIf="!isCollapsed&&user.role=='user'" class="myCard">
<p>欢迎来访小海博客</p>
</nz-card>
@@ -88,95 +88,95 @@
<nz-footer>© <a href="https://www.celess.cn">小海博客</a> - Design by 小海</nz-footer>
</nz-layout>
</nz-layout>
<nz-drawer [nzClosable]="false" [nzVisible]="infoDrawerVisible" nzPlacement="right"
[nzTitle]="sayHelloTemp" (nzOnClose)="infoDrawerVisible = false" nzWidth="300px">
<nz-drawer (nzOnClose)="infoDrawerVisible = false" [nzClosable]="false" [nzTitle]="sayHelloTemp"
[nzVisible]="infoDrawerVisible" nzPlacement="right" nzWidth="300px">
<p>您最近一次登录是在:</p>
<p>{{user && user.recentlyLandedDate}}</p>
<nz-divider></nz-divider>
<div style="text-align: center;margin-bottom: 10px;">
<nz-avatar [nzSize]="64" [nzSrc]="user.avatarImgUrl"
*ngIf="user.avatarImgUrl!==noAvatarUrl"></nz-avatar>
<nz-avatar [nzSize]="64" [nzText]="user.displayName" style="background: #f56a00"
*ngIf="user.avatarImgUrl===noAvatarUrl"></nz-avatar>
<nz-avatar *ngIf="user.avatarImgUrl!==noAvatarUrl" [nzSize]="64"
[nzSrc]="user.avatarImgUrl"></nz-avatar>
<nz-avatar *ngIf="user.avatarImgUrl===noAvatarUrl" [nzSize]="64" [nzText]="user.displayName"
style="background: #f56a00"></nz-avatar>
<nz-upload style="display: block" [nzAction]="host+'/user/imgUpload'" nzWithCredentials="true" nzLimit="1"
(nzChange)="avatarUpload($event)" [nzHeaders]="uploadHeader">
<nz-upload (nzChange)="avatarUpload($event)" [nzAction]="host+'/user/imgUpload'" [nzHeaders]="uploadHeader" nzLimit="1"
nzWithCredentials="true" style="display: block">
<button nz-button nzBlock nzType="link"><i nz-icon nzType="upload"></i>修改头像</button>
</nz-upload>
</div>
<nz-descriptions [nzColumn]="1">
<nz-descriptions-item nzTitle="邮箱">
<div>
<i nz-icon nzType="mail" class="icon" nzTheme="twotone"></i>
<i class="icon" nz-icon nzTheme="twotone" nzType="mail"></i>
<span>{{user && user.email}}</span>
<i nz-icon nzType="edit" class="edit-icon" nzTheme="twotone" (click)="showEditInfoModal()"></i>
<i (click)="showEditInfoModal()" class="edit-icon" nz-icon nzTheme="twotone" nzType="edit"></i>
</div>
</nz-descriptions-item>
<nz-descriptions-item nzTitle="昵称">
<div>
<i nz-icon nzType="crown" class="icon" nzTheme="twotone"></i>
<i class="icon" nz-icon nzTheme="twotone" nzType="crown"></i>
<span>{{user && user.displayName}}</span>
<i nz-icon nzType="edit" class="edit-icon" nzTheme="twotone" (click)="showEditInfoModal()"></i>
<i (click)="showEditInfoModal()" class="edit-icon" nz-icon nzTheme="twotone" nzType="edit"></i>
</div>
</nz-descriptions-item>
<nz-descriptions-item nzTitle="描述" *ngIf="user&&user.desc">
<i nz-icon nzType="info-circle" class="icon" nzTheme="twotone"></i>
<span nz-tooltip [nzTooltipTitle]="user.desc" nzTooltipPlacement="left" nz-typography [nzEllipsis]="true"
[nzContent]="user.desc" style="max-width: 100px">{{user.desc}}</span>
<i nz-icon nzType="edit" class="edit-icon" nzTheme="twotone" (click)="showEditInfoModal()"></i>
<nz-descriptions-item *ngIf="user&&user.desc" nzTitle="描述">
<i class="icon" nz-icon nzTheme="twotone" nzType="info-circle"></i>
<span [nzContent]="user.desc" [nzEllipsis]="true" [nzTooltipTitle]="user.desc" nz-tooltip nz-typography
nzTooltipPlacement="left" style="max-width: 100px">{{user.desc}}</span>
<i (click)="showEditInfoModal()" class="edit-icon" nz-icon nzTheme="twotone" nzType="edit"></i>
</nz-descriptions-item>
<nz-descriptions-item nzTitle="密码">
<i nz-icon nzType="fire" nzTheme="twotone"> </i>
<i nz-icon nzTheme="twotone" nzType="fire"> </i>
<span> *********</span>
<i nz-icon nzType="edit" class="edit-icon" nzTheme="twotone" (click)="showResetPwdModal()"></i>
<i (click)="showResetPwdModal()" class="edit-icon" nz-icon nzTheme="twotone" nzType="edit"></i>
</nz-descriptions-item>
</nz-descriptions>
<nz-divider></nz-divider>
<!-- <div >-->
<button nz-button nzDanger nzBlock nzType="primary" (click)="logout()">注销</button>
<button (click)="logout()" nz-button nzBlock nzDanger nzType="primary">注销</button>
<!-- </div>-->
<!-- TODO: 展示更多信息 -->
</nz-drawer>
<nz-modal [(nzVisible)]="editInfoModalVisible" (nzOnOk)="modalConfirm()" (nzOnCancel)="editInfoModalVisible=false"
<nz-modal (nzOnCancel)="editInfoModalVisible=false" (nzOnOk)="modalConfirm()" [(nzVisible)]="editInfoModalVisible"
nzTitle="编辑信息">
<form nz-form [formGroup]="editInfoFormGroup" (ngSubmit)="modalConfirm()">
<form (ngSubmit)="modalConfirm()" [formGroup]="editInfoFormGroup" nz-form>
<nz-form-item>
<nz-form-label>邮箱</nz-form-label>
<nz-form-control>
<input nz-input disabled formControlName="email">
<input disabled formControlName="email" nz-input>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label>昵称</nz-form-label>
<nz-form-control>
<input nz-input formControlName="displayName" placeholder="默认为你的邮箱地址">
<input formControlName="displayName" nz-input placeholder="默认为你的邮箱地址">
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label>描述</nz-form-label>
<nz-form-control>
<input nz-input formControlName="desc" placeholder="请输入自我介绍">
<input formControlName="desc" nz-input placeholder="请输入自我介绍">
</nz-form-control>
</nz-form-item>
</form>
</nz-modal>
<nz-modal [(nzVisible)]="resetPwdModalVisible" nzClosable="true" (nzOnCancel)="resetPwdModalVisible = false"
(nzOnOk)="resetPwdConfirm()" nzTitle="修改密码" [nzOkDisabled]="!resetPwdFormGroup.valid">
<form nz-form (submit)="resetPwdConfirm()" [formGroup]="resetPwdFormGroup">
<nz-modal (nzOnCancel)="resetPwdModalVisible = false" (nzOnOk)="resetPwdConfirm()" [(nzVisible)]="resetPwdModalVisible"
[nzOkDisabled]="!resetPwdFormGroup.valid" nzClosable="true" nzTitle="修改密码">
<form (submit)="resetPwdConfirm()" [formGroup]="resetPwdFormGroup" nz-form>
<nz-form-item>
<nz-form-label nzRequired>原密码</nz-form-label>
<nz-form-control nzErrorTip="原密码不可为空">
<input type="password" name="xxx" nz-input formControlName="originPwd">
<input formControlName="originPwd" name="xxx" nz-input type="password">
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzRequired>新密码</nz-form-label>
<nz-form-control [nzErrorTip]="newPwdErrTip">
<input type="password" name="xxx" nz-input formControlName="newPwd">
<input formControlName="newPwd" name="xxx" nz-input type="password">
</nz-form-control>
<ng-template #newPwdErrTip>
<div *ngIf="resetPwdFormGroup.controls.newPwd.hasError('required')">新密码不可为空</div>
@@ -188,7 +188,7 @@
<nz-form-item>
<nz-form-label nzRequired>确认密码</nz-form-label>
<nz-form-control [nzErrorTip]="newPwdConfirmErrTip">
<input type="password" nz-input name="xxx" formControlName="newPwdConfirm">
<input formControlName="newPwdConfirm" name="xxx" nz-input type="password">
</nz-form-control>
<ng-template #newPwdConfirmErrTip>
<div *ngIf="resetPwdFormGroup.controls.newPwdConfirm.hasError('required')">确认密码不可为空</div>
@@ -202,10 +202,10 @@
</nz-modal>
<ng-template #zeroTrigger>
<i nz-icon nzType="menu-fold" nzTheme=outline></i>
<i nz-icon nzTheme=outline nzType="menu-fold"></i>
</ng-template>
<ng-template #sayHelloTemp>
<span>{{sayHelloContent}}</span>
<i nz-icon [nzType]="'smile'" [nzTheme]="'twotone'" nzTwotoneColor="#52c41a" style="margin-left: 5px"></i>
<i [nzTheme]="'twotone'" [nzType]="'smile'" nz-icon nzTwotoneColor="#52c41a" style="margin-left: 5px"></i>
</ng-template>

View File

@@ -31,7 +31,8 @@ nz-content {
.icon {
margin-right: 5px;
}
.edit-icon{
.edit-icon {
margin-left: 10px;
cursor: pointer;
}

View File

@@ -1,6 +1,7 @@
import {Component, OnInit} from '@angular/core';
import {AbstractControl, FormControl, FormGroup, Validators} from '@angular/forms';
import {NzMessageService, UploadFile} from 'ng-zorro-antd';
import {AbstractControl, UntypedFormControl, UntypedFormGroup, Validators} from '@angular/forms';
import {NzMessageService} from 'ng-zorro-antd/message';
import {NzUploadFile} from 'ng-zorro-antd/upload';
import {Router} from '@angular/router';
import {GlobalUserService} from '../../services/global-user.service';
import {User} from '../../class/User';
@@ -16,83 +17,62 @@ import {LocalStorageService} from '../../services/local-storage.service';
})
export class AdminComponent implements OnInit {
constructor(public gUserService: GlobalUserService, private apiService: ApiService, private messageService: NzMessageService,
private router: Router, private localStorageService: LocalStorageService) {
this.gUserService.watchUserInfo({
complete: () => null,
error: (err) => null,
next: data => {
console.log('更新user')
this.user = data.result
if (data.result) this.initHelloWords()
}
}
);
this.editInfoFormGroup = new FormGroup({
desc: new FormControl(),
displayName: new FormControl(),
email: new FormControl({value: null, disabled: true})
});
this.resetPwdFormGroup = new FormGroup({
originPwd: new FormControl(null, [Validators.required]),
newPwd: new FormControl(null, [
Validators.required, Validators.minLength(6), Validators.maxLength(16), Validators.pattern(/^[\w_-]{6,16}$/)
]),
newPwdConfirm: new FormControl(null, [
Validators.required, Validators.minLength(6), Validators.maxLength(16), Validators.pattern(/^[\w_-]{6,16}$/),
this.checkSamePwd()
]),
})
}
user: User;
isCollapsed: boolean = false;
infoDrawerVisible: boolean = false;
sayHelloContent: string;
editInfoModalVisible: boolean = false;
resetPwdModalVisible: boolean = false;
editInfoFormGroup: FormGroup;
resetPwdFormGroup: FormGroup;
noAvatarUrl = 'https://cdn.celess.cn/'
host: string
editInfoFormGroup: UntypedFormGroup;
resetPwdFormGroup: UntypedFormGroup;
noAvatarUrl = 'https://cdn.celess.cn/';
host: string;
constructor(public gUserService: GlobalUserService, private apiService: ApiService, private messageService: NzMessageService,
private router: Router, private localStorageService: LocalStorageService) {
this.gUserService.watchUserInfo({
complete: () => null,
error: (err) => null,
next: data => {
this.user = data.result;
if (data.result) {this.initHelloWords();}
}
}
);
this.editInfoFormGroup = new UntypedFormGroup({
desc: new UntypedFormControl(),
displayName: new UntypedFormControl(),
email: new UntypedFormControl({value: null, disabled: true})
});
this.resetPwdFormGroup = new UntypedFormGroup({
originPwd: new UntypedFormControl(null, [Validators.required]),
newPwd: new UntypedFormControl(null, [
Validators.required, Validators.minLength(6), Validators.maxLength(16), Validators.pattern(/^[\w_-]{6,16}$/)
]),
newPwdConfirm: new UntypedFormControl(null, [
Validators.required, Validators.minLength(6), Validators.maxLength(16), Validators.pattern(/^[\w_-]{6,16}$/),
this.checkSamePwd()
]),
});
}
showInfoDrawer = () => this.infoDrawerVisible = !this.infoDrawerVisible;
logout() {
this.gUserService.logout();
this.router.navigateByUrl('/')
this.router.navigateByUrl('/');
}
ngOnInit(): void {
this.host = environment.host;
}
checkSamePwd = () => {
return (control: AbstractControl): { [key: string]: any } | null => {
console.log('a')
checkSamePwd = () => (control: AbstractControl): { [key: string]: any } | null => {
const newPwd = this.resetPwdFormGroup && this.resetPwdFormGroup.value.newPwd;
return control.value !== newPwd ? {pwdNotSame: true} : null;
};
}
uploadHeader = (file: UploadFile): object | Observable<{}> => {
return {Authorization: this.localStorageService.getToken()}
};
private initHelloWords() {
const hours = new Date().getHours();
if (hours < 6) {
this.sayHelloContent = `夜深了,注意早点休息哦!${this.user.displayName}`
} else if (hours < 10) {
this.sayHelloContent = `早上好呀!${this.user.displayName}`
} else if (hours < 14) {
this.sayHelloContent = `中午好呀!${this.user.displayName}`
} else if (hours < 19) {
this.sayHelloContent = `下午好呀!${this.user.displayName}`
} else if (hours < 22) {
this.sayHelloContent = `晚上好呀!${this.user.displayName}`
} else {
this.sayHelloContent = `时间不早了,注意休息哦!${this.user.displayName}`
}
}
// eslint-disable-next-line @typescript-eslint/naming-convention
uploadHeader = (file: NzUploadFile): any | Observable<{}> => ({Authorization: this.localStorageService.getToken()});
showEditInfoModal() {
this.editInfoModalVisible = true;
@@ -105,7 +85,7 @@ export class AdminComponent implements OnInit {
const displayName = this.editInfoFormGroup.value.displayName;
this.apiService.updateUserInfo(desc, displayName).subscribe({
next: data => {
this.messageService.success('修改信息成功')
this.messageService.success('修改信息成功');
this.gUserService.refreshUserInfo();
},
error: err => {
@@ -128,13 +108,13 @@ export class AdminComponent implements OnInit {
error: err => {
this.messageService.error('修改密码失败,' + err.msg);
}
})
});
this.resetPwdModalVisible = false;
}
showResetPwdModal() {
this.resetPwdModalVisible = true;
this.infoDrawerVisible = false
this.infoDrawerVisible = false;
}
avatarUpload(info: any) {
@@ -143,4 +123,21 @@ export class AdminComponent implements OnInit {
this.gUserService.refreshUserInfo();
}
}
private initHelloWords() {
const hours = new Date().getHours();
if (hours < 6) {
this.sayHelloContent = `夜深了,注意早点休息哦!${this.user.displayName}`;
} else if (hours < 10) {
this.sayHelloContent = `早上好呀!${this.user.displayName}`;
} else if (hours < 14) {
this.sayHelloContent = `中午好呀!${this.user.displayName}`;
} else if (hours < 19) {
this.sayHelloContent = `下午好呀!${this.user.displayName}`;
} else if (hours < 22) {
this.sayHelloContent = `晚上好呀!${this.user.displayName}`;
} else {
this.sayHelloContent = `时间不早了,注意休息哦!${this.user.displayName}`;
}
}
}

View File

@@ -2,12 +2,25 @@ import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {AdminRoutingModule} from './admin-routing.module';
import {AdminComponent} from './admin.component';
import {NgZorroAntdModule} from 'ng-zorro-antd';
import {NzSpaceModule} from 'ng-zorro-antd/space';
import {AdminHeaderComponent} from '../../components/admin-header/admin-header.component';
import {ReactiveFormsModule} from '@angular/forms';
import {AuthGuard} from './auth.guard';
import {NzAvatarModule} from 'ng-zorro-antd/avatar';
import {NzButtonModule} from 'ng-zorro-antd/button';
import {NzLayoutModule} from 'ng-zorro-antd/layout';
import {NzMenuModule} from 'ng-zorro-antd/menu';
import {NzIconModule} from 'ng-zorro-antd/icon';
import {NzCardModule} from 'ng-zorro-antd/card';
import {NzDividerModule} from 'ng-zorro-antd/divider';
import {NzUploadModule} from 'ng-zorro-antd/upload';
import {NzToolTipModule} from 'ng-zorro-antd/tooltip';
import {NzTypographyModule} from 'ng-zorro-antd/typography';
import {NzModalModule} from 'ng-zorro-antd/modal';
import {NzFormModule} from 'ng-zorro-antd/form';
import {NzInputModule} from 'ng-zorro-antd/input';
import {NzDescriptionsModule} from 'ng-zorro-antd/descriptions';
import {NzDrawerModule} from 'ng-zorro-antd/drawer';
@NgModule({
declarations: [
@@ -17,9 +30,23 @@ import {AuthGuard} from './auth.guard';
imports: [
CommonModule,
AdminRoutingModule,
NgZorroAntdModule,
NzSpaceModule,
ReactiveFormsModule,
NzAvatarModule,
NzButtonModule,
NzLayoutModule,
NzMenuModule,
NzIconModule,
NzCardModule,
NzDividerModule,
NzUploadModule,
NzToolTipModule,
NzTypographyModule,
NzModalModule,
NzFormModule,
NzInputModule,
NzDescriptionsModule,
NzDrawerModule
],
providers: [AuthGuard]
})

View File

@@ -1,12 +1,5 @@
import {Injectable} from '@angular/core';
import {
CanActivate,
ActivatedRouteSnapshot,
RouterStateSnapshot,
UrlTree,
Router,
CanActivateChild
} from '@angular/router';
import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot} from '@angular/router';
import {Observable, Observer} from 'rxjs';
import {User} from '../../class/User';
import {GlobalUserService} from '../../services/global-user.service';
@@ -16,15 +9,15 @@ import {GlobalUserService} from '../../services/global-user.service';
})
export class AuthGuard implements CanActivate {
constructor(private userService: GlobalUserService, private router: Router) {
}
userInfo: User;
visitCount: number = 0; // 记录一共走过几次canActivate
private path: string;
private readonly loginPath: string = '/user/login';
private observable: Observable<boolean>;
constructor(private userService: GlobalUserService, private router: Router) {
}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
this.path = state.url.indexOf('?') > 0 ? state.url.substr(0, state.url.indexOf('?')) : state.url;
this.visitCount++;
@@ -53,7 +46,7 @@ export class AuthGuard implements CanActivate {
this.userInfo = data.result;
this.checkPath(observer);
}
})
});
}
@@ -67,7 +60,7 @@ export class AuthGuard implements CanActivate {
case '/admin/visitor':
if (this.userInfo && this.userInfo.role !== 'admin') {
observer.next(false);
if (this.visitCount === 1) this.router.navigateByUrl('/admin')
if (this.visitCount === 1) {this.router.navigateByUrl('/admin');}
observer.complete();
return;
}

View File

@@ -1,26 +1,26 @@
<nz-card *ngIf="cardTitle" nzSize="small" [nzExtra]="extra" [nzTitle]="cardTitle" [nzLoading]="loading">
<nz-card *ngIf="cardTitle" [nzExtra]="extra" [nzLoading]="loading" [nzTitle]="cardTitle" nzSize="small">
<ng-container *ngTemplateOutlet="table"></ng-container>
</nz-card>
<ng-container [ngTemplateOutlet]="table" *ngIf="!cardTitle"></ng-container>
<ng-container *ngIf="!cardTitle" [ngTemplateOutlet]="table"></ng-container>
<ng-template #extra>
<i nz-icon nzType="setting" nzTheme="outline" title="设置" (click)="showFieldSetting()"
style="cursor: pointer;margin-right: 10px"></i>
<i nz-icon nzType="reload" nzTheme="outline" (click)="getData()" title="刷新" style="cursor: pointer"></i>
<i (click)="showFieldSetting()" nz-icon nzTheme="outline" nzType="setting" style="cursor: pointer;margin-right: 10px"
title="设置"></i>
<i (click)="getData()" nz-icon nzTheme="outline" nzType="reload" style="cursor: pointer" title="刷新"></i>
</ng-template>
<ng-template #table>
<ng-content></ng-content>
<nz-table nzTableLayout="fixed"
[nzData]="dataList.list"
[nzTotal]="dataList.total"
<nz-table (nzPageIndexChange)="getData($event)"
[(nzPageIndex)]="dataList.pageNum"
[nzData]="dataList.list"
[nzLoading]="loading"
[nzPageSize]="dataList.pageSize"
(nzPageIndexChange)="getData()"
nzFrontPagination="false"
[nzScroll]="{x:visibleFieldLength*100+'px'}"
[nzLoading]="loading">
[nzTotal]="dataList.total"
nzFrontPagination="false"
nzTableLayout="fixed">
<thead>
<tr>
<ng-container *ngFor="let data of filedData">
@@ -34,12 +34,12 @@
<tr *ngFor="let t of dataList.list;let index = index">
<ng-container *ngFor="let data of filedData">
<td *ngIf="data.show"
nz-typography
nzEllipsis
[nzEllipsisRows]="data.isActionColumns?3:1"
[nzTooltipTitle]="data.isActionColumns ? null : data.title+' : '+getValue(index,data.fieldValue)"
nzTooltipPlacement="top"
nz-tooltip>
nz-tooltip
nz-typography
nzEllipsis
nzTooltipPlacement="top">
<ng-template [ngIf]="!data.isActionColumns">
<ng-template [ngIf]="template[data.fieldValue]">
<ng-container
@@ -51,15 +51,15 @@
</ng-template>
</ng-template>
<ng-container *ngIf="data.isActionColumns">
<a *ngFor="let action of data.action; let i = index"
(mouseenter)="action.hover(t)"
<a (mouseenter)="action.hover(t)"
(mouseout)="null"
[ngStyle]="{'color':action.color,'font-size':action.fontSize}"
nz-popconfirm
[nzPopconfirmTitle]="'是否确认'+action.name+'该数据?'"
[nzCondition]="!action.needConfirm"
(nzOnConfirm)="action.click(t)"
[title]="action.name">
*ngFor="let action of data.action; let i = index"
[ngStyle]="{'color':action.color,'font-size':action.fontSize}"
[nzCondition]="!action.needConfirm"
[nzPopconfirmTitle]="'是否确认'+action.name+'该数据?'"
[title]="action.name"
nz-popconfirm>
{{action.name}}
<ng-template [ngIf]="i!=data.action.length-1">
<nz-divider nzType="vertical"></nz-divider>
@@ -74,17 +74,17 @@
</ng-template>
<nz-modal [(nzVisible)]="settingModalVisible"
[nzClosable]="true"
(nzOnCancel)="cancel()"
<nz-modal (nzOnCancel)="cancel()"
(nzOnOk)="ok()"
[(nzVisible)]="settingModalVisible"
[nzClosable]="true"
nzTitle="表格字段设置(可拖动排序)"
>
<button nz-button nzType="primary" (click)="reset()" [disabled]="!changed">重置</button>
<nz-table [nzData]="filedData" nzSize="small" nzPageSize="10000" nzShowPagination="false">
<tbody cdkDropList (cdkDropListDropped)="drop($event)">
<ng-template ngFor [ngForOf]="filedData" let-item let-index="index">
<tr *ngIf="!item.isActionColumns" cdkDrag (click)="click()">
<button (click)="reset()" [disabled]="!changed" nz-button nzType="primary">重置</button>
<nz-table [nzData]="filedData" nzPageSize="10000" nzShowPagination="false" nzSize="small">
<tbody (cdkDropListDropped)="drop($event)" cdkDropList>
<ng-template [ngForOf]="filedData" let-index="index" let-item ngFor>
<tr (click)="click()" *ngIf="!item.isActionColumns" cdkDrag>
<td>{{index + 1}}</td>
<td style="text-align: center">{{item.title}}</td>
<td style="text-align: center">{{item.fieldValue}}</td>

View File

@@ -3,6 +3,7 @@ import {Data} from './data';
import {PageList, RequestObj} from '../../../../class/HttpReqAndResp';
import {HttpService} from '../../../../api/http/http.service';
import {CdkDragDrop, moveItemInArray} from '@angular/cdk/drag-drop';
import {LocalStorageService} from '../../../../services/local-storage.service';
@Component({
selector: 'common-table',
@@ -11,72 +12,79 @@ import {CdkDragDrop, moveItemInArray} from '@angular/cdk/drag-drop';
})
export class CommonTableComponent<T> implements OnInit, OnChanges {
constructor(private httpService: HttpService) {
}
@Input() private headData: Data<T>[];
@Input() request: RequestObj;
@Output() pageInfo = new EventEmitter<{ page: number; pageSize: number }>();
@Input() cardTitle: string | null;
@Input() template: {
[fieldValue: string]: {
temp: TemplateRef<any>,
param?: { [key: string]: string }
}
temp: TemplateRef<any>;
param?: { [key: string]: string };
};
};
@Output() pageInfo = new EventEmitter<{ page: number, pageSize: number }>();
@Input() request: RequestObj;
@Input() private headData: Data<T>[];
loading: boolean = true;
dataList: PageList<T> = new PageList<T>();
settingModalVisible: boolean = false;
filedData: Data<T>[];
changed: boolean = false;
visibleFieldLength: number = 0;
constructor(private httpService: HttpService,
private localStorageService: LocalStorageService) {
}
ngOnInit(): void {
if (localStorage.getItem(this.request.path)) {
this.filedData = this.cloneData(localStorage.getItem(this.request.path));
if (this.localStorageService.getItem(this.request.path)) {
this.filedData = this.cloneData(this.localStorageService.getItem(this.request.path));
this.changed = true;
} else {
this.filedData = this.cloneData(this.headData)
console.log(this.filedData)
this.filedData = this.cloneData(this.headData);
}
this.calculateVisibleFieldLength();
if (!this.template) this.template = {}
if (!this.template) {
this.template = {};
}
this.headData.forEach(dat => {
if (!dat.action) return;
if (!dat.action) {
return;
}
dat.action.forEach(act => {
if (!act.hover) {
act.hover = () => null;
}
})
});
});
if (!this.request || !this.request.path) return
if (!this.request || !this.request.path) {
return;
}
this.getData();
}
getData = () => {
getData = (pageNumber?: number) => {
this.loading = true;
const pageValue = this.dataList.pageNum ? this.dataList.pageNum : 1;
const countValue = this.dataList.pageSize ? this.dataList.pageSize : 10
this.request.queryParam = {
page: pageValue,
count: countValue
}
this.pageInfo.emit({page: pageValue, pageSize: countValue})
return this.httpService.Service<PageList<T>>(this.request).subscribe({
const pageValue = pageNumber ? pageNumber : 1;
const countValue = this.dataList.pageSize ? this.dataList.pageSize : 10;
this.request.queryParam.page = pageValue;
this.request.queryParam.count = countValue;
// this.request.queryParam = {
// page: pageValue,
// count: countValue
// }
this.pageInfo.emit({page: pageValue, pageSize: countValue});
return this.httpService.service<PageList<T>>(this.request).subscribe({
next: resp => {
this.dataList = resp.result;
setTimeout(() => this.loading = false, 10)
setTimeout(() => this.loading = false, 10);
},
error: err => this.loading = false
});
}
};
ngOnChanges(changes: SimpleChanges): void {
if (changes.request && !changes.request.isFirstChange()) {
console.log(changes.request)
this.request = changes.request.currentValue;
this.getData().unsubscribe();
this.getData();
@@ -87,7 +95,9 @@ export class CommonTableComponent<T> implements OnInit, OnChanges {
getValue(index: number, fieldValue: string): string {
let value = this.dataList.list[index];
try {
for (const key of fieldValue.split('.')) value = value[key]
for (const key of fieldValue.split('.')) {
value = value[key];
}
} catch (e) {
// ignore
}
@@ -96,35 +106,35 @@ export class CommonTableComponent<T> implements OnInit, OnChanges {
getContext = (fieldValue: string, index: number) => {
const valueData = this.getValue(index, fieldValue);
let context: { value: string, originValue?: string, data: T };
let context: { value: string; originValue?: string; data: T };
if (this.template[fieldValue].param) {
context = {
value: this.template[fieldValue].param[valueData],
originValue: valueData,
data: this.dataList.list[index]
}
};
} else {
context = {
value: valueData,
data: this.dataList.list[index]
}
};
}
return context;
}
};
showFieldSetting = () => this.settingModalVisible = true;
cancel = () => this.settingModalVisible = false;
calculateVisibleFieldLength = () => this.filedData.filter(value => value.show).length;
calculateVisibleFieldLength = () => this.visibleFieldLength = this.filedData.filter(value => value.show).length;
ok() {
this.calculateVisibleFieldLength();
this.settingModalVisible = !this.settingModalVisible;
if (!this.changed) {
return
return;
}
this.dataList = JSON.parse(JSON.stringify(this.dataList));
localStorage.setItem(this.request.path, JSON.stringify(this.filedData))
this.localStorageService.setItem(this.request.path, JSON.stringify(this.filedData));
this.changed = true;
}
@@ -134,11 +144,11 @@ export class CommonTableComponent<T> implements OnInit, OnChanges {
}
reset = () => {
localStorage.removeItem(this.request.path);
this.localStorageService.removeItem(this.request.path);
this.filedData = this.cloneData(this.headData);
this.changed = false;
this.calculateVisibleFieldLength();
}
};
cloneData = (source: Data<T>[] | string): Data<T>[] => {
let dist: Data<T>[];
@@ -148,11 +158,14 @@ export class CommonTableComponent<T> implements OnInit, OnChanges {
dist = JSON.parse(JSON.stringify(source));
}
const action = this.headData.filter(value => value.isActionColumns).pop();
const del = dist.filter(value => value.isActionColumns).pop()
if (!action) {
return dist;
}
const del = dist.filter(value => value.isActionColumns).pop();
dist.splice(dist.indexOf(del), 1);
dist.push(action);
return dist;
}
};
/**
* 字段编辑项被点击
@@ -166,5 +179,5 @@ export class CommonTableComponent<T> implements OnInit, OnChanges {
this.changed = true;
}
}
}
};
}

View File

@@ -1,17 +1,20 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {CommonTableComponent} from './common-table.component';
import {
NzButtonModule,
NzCardModule,
NzDividerModule,
NzIconModule, NzModalModule, NzOutletModule, NzPopconfirmModule, NzSwitchModule,
NzTableModule, NzTagModule,
NzToolTipModule,
NzTypographyModule
} from 'ng-zorro-antd';
import {NzButtonModule} from 'ng-zorro-antd/button';
import {NzCardModule} from 'ng-zorro-antd/card';
import {NzDividerModule} from 'ng-zorro-antd/divider';
import {NzIconModule} from 'ng-zorro-antd/icon';
import {NzModalModule} from 'ng-zorro-antd/modal';
import {NzOutletModule} from 'ng-zorro-antd/core/outlet';
import {NzPopconfirmModule} from 'ng-zorro-antd/popconfirm';
import {NzSwitchModule} from 'ng-zorro-antd/switch';
import {NzTableModule} from 'ng-zorro-antd/table';
import {NzTagModule} from 'ng-zorro-antd/tag';
import {NzToolTipModule} from 'ng-zorro-antd/tooltip';
import {NzTypographyModule} from 'ng-zorro-antd/typography';
import {FormsModule} from '@angular/forms';
import {DragDropModule} from '@angular/cdk/drag-drop'
import {DragDropModule} from '@angular/cdk/drag-drop';
@NgModule({
declarations: [

View File

@@ -7,19 +7,19 @@ export class Data<T> {
primaryKey?: boolean = false;
isActionColumns?: boolean = false;
template?: {
template: TemplateRef<any>,
template: TemplateRef<any>;
keymap?: {
[value: string]: string
}
[value: string]: string;
};
};
// order?: number;
action ?: {
name: string,
color?: string,
order?: number,
fontSize?: string,
needConfirm?: boolean,
click: (data: T) => void,
action?: {
name: string;
color?: string;
order?: number;
fontSize?: string;
needConfirm?: boolean;
click: (data: T) => void;
hover?: (data: T) => void | null;
}[] = []
}[] = [];
}

View File

@@ -1,15 +1,5 @@
import {
Component,
ElementRef,
EventEmitter,
Input,
OnChanges,
OnInit,
Output,
SimpleChanges,
ViewChild
} from '@angular/core';
import {NzModalRef, NzModalService} from 'ng-zorro-antd';
import {Component, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges, ViewChild} from '@angular/core';
import {NzModalRef, NzModalService} from 'ng-zorro-antd/modal';
@Component({
selector: 'editable-tag',
@@ -39,17 +29,9 @@ import {NzModalRef, NzModalService} from 'ng-zorro-antd';
})
export class EditableTagComponent implements OnInit, OnChanges {
private static instanceArray: EditableTagComponent[] = []
constructor(private modal: NzModalService) {
EditableTagComponent.instanceArray.push(this);
}
inputVisible = false;
inputValue = '';
private static instanceArray: EditableTagComponent[] = [];
@ViewChild('inputElement', {static: false}) inputElement?: ElementRef;
@Output() valueChange = new EventEmitter<{ value: string, originalValue: string, changed: boolean }>();
@Output() valueChange = new EventEmitter<{ value: string; originalValue: string; changed: boolean }>();
@Input() color: string;
@Input() showEditIcon: boolean;
@Input() showBorder: boolean;
@@ -60,14 +42,19 @@ export class EditableTagComponent implements OnInit, OnChanges {
@Input() autoClear: boolean;
@Input() size: 'small' | 'default' | 'large';
@Output() inEditStatus = new EventEmitter<void>();
@Output() modalOK = new EventEmitter<{ value: string, originalValue: string, changed: boolean }>();
@Output() modalCancel = new EventEmitter<{ value: string, originalValue: string, changed: boolean }>();
@Output() modalOK = new EventEmitter<{ value: string; originalValue: string; changed: boolean }>();
@Output() modalCancel = new EventEmitter<{ value: string; originalValue: string; changed: boolean }>();
inputVisible = false;
inputValue = '';
confirmModal?: NzModalRef;
private tmpKey: any;
private doubleClickInfo = {
date: null,
};
confirmModal?: NzModalRef;
constructor(private modal: NzModalService) {
EditableTagComponent.instanceArray.push(this);
}
ngOnInit(): void {
if (this.showEditIcon == null) {
@@ -97,17 +84,17 @@ export class EditableTagComponent implements OnInit, OnChanges {
if (this.doubleClick && doubleClick) {
if (!this.doubleClickInfo.date) {
this.doubleClickInfo.date = new Date().getTime();
return
return;
}
if (new Date().getTime() - this.doubleClickInfo.date < 200) {
this.inEditStatus.emit()
this.inEditStatus.emit();
this.inputVisible = true;
setTimeout(() => this.inputElement?.nativeElement.focus(), 10);
}
this.doubleClickInfo.date = new Date().getTime();
} else {
this.inputVisible = true;
this.inEditStatus.emit()
this.inEditStatus.emit();
setTimeout(() => this.inputElement?.nativeElement.focus(), 10);
}
}
@@ -118,7 +105,7 @@ export class EditableTagComponent implements OnInit, OnChanges {
if (tag.key === this.tmpKey) {
tag.showInput(false);
}
})
});
}
@@ -127,8 +114,8 @@ export class EditableTagComponent implements OnInit, OnChanges {
value: this.inputValue,
originalValue: this.text,
changed: this.inputValue !== this.text
}
this.valueChange.emit(value)
};
this.valueChange.emit(value);
this.text = this.inputValue;
this.inputValue = '';
this.inputVisible = false;
@@ -141,7 +128,7 @@ export class EditableTagComponent implements OnInit, OnChanges {
});
}
if (this.autoClear) {
this.text = null
this.text = null;
}
}

View File

@@ -1,7 +1,9 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {EditableTagComponent} from './editable-tag.component';
import {NzIconModule, NzInputModule, NzTagModule} from 'ng-zorro-antd';
import {NzIconModule} from 'ng-zorro-antd/icon';
import {NzInputModule} from 'ng-zorro-antd/input';
import {NzTagModule} from 'ng-zorro-antd/tag';
import {FormsModule} from '@angular/forms';

View File

@@ -14,15 +14,15 @@
<nz-tag [nzColor]="'#f50'">{{value}}</nz-tag>
</ng-template>
<ng-template #original let-value="value" let-originValue="originValue">
<ng-template #original let-originValue="originValue" let-value="value">
<nz-tag [nzColor]="originValue?'#87d068':'#f50'">{{value}}</nz-tag>
</ng-template>
<ng-template #open let-value="value">
<label nz-checkbox nzDisabled [ngModel]="value"></label>
<label [ngModel]="value" nz-checkbox nzDisabled></label>
</ng-template>
<editable-tag color="green">hhh</editable-tag>
<editable-tag color="green" [showEditIcon]="false">hhh</editable-tag>
<editable-tag color="green" [showBorder]="false">hhh</editable-tag>
<editable-tag [showEditIcon]="false" color="green">hhh</editable-tag>
<editable-tag [showBorder]="false" color="green">hhh</editable-tag>

View File

@@ -1,4 +1,4 @@
import {Component, OnInit, TemplateRef, ViewChild} from '@angular/core';
import {Component, OnInit} from '@angular/core';
import {Data} from '../components/common-table/data';
import {Article} from '../../../class/Article';
import {RequestObj} from '../../../class/HttpReqAndResp';
@@ -24,8 +24,12 @@ summary: a
tags: [{id: 26, name: "脚本"}, {id: 27, name: "网课"}]
title: "教你动手写一个刷课脚本"
updateDateFormat: "2020-05-27 00:55:05"*/
// @ViewChild('tag') tagTemp: TemplateRef<any>;
data: Data<Article>[];
req: RequestObj;
constructor() {
this.data = [
{title: '主键', fieldValue: 'id', show: false, primaryKey: true},
@@ -58,12 +62,9 @@ updateDateFormat: "2020-05-27 00:55:05"*/
},
]
}
]
];
}
data: Data<Article>[];
req: RequestObj;
ngOnInit(): void {
this.req = {
path: '/admin/articles',
@@ -72,7 +73,7 @@ updateDateFormat: "2020-05-27 00:55:05"*/
page: 1,
count: 10
}
}
};
}
}

View File

@@ -1,9 +1,10 @@
import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {TestCommonTableComponent} from './test-common-table.component';
import {Router, RouterModule} from '@angular/router';
import {RouterModule} from '@angular/router';
import {CommonTableModule} from '../components/common-table/common-table.module';
import {NzCheckboxModule, NzTagModule} from 'ng-zorro-antd';
import {NzCheckboxModule} from 'ng-zorro-antd/checkbox';
import {NzTagModule} from 'ng-zorro-antd/tag';
import {FormsModule} from '@angular/forms';
import {EditableTagModule} from '../components/editable-tag/editable-tag.module';

View File

@@ -1,6 +1,6 @@
<div id="main">
<div id="article-content"></div>
<div #divElement id="article-content"></div>
<ng-template [ngIf]="article">
<span id="over">over</span>
@@ -15,20 +15,20 @@
<div class="article-tag" id="tag">
<!-- TODO -->
<span *ngFor="let item of (article.tags||'')" class="tag">
<i nz-icon nzType="tag" nzTheme="fill"></i>
<a class="tag" [routerLink]="['/tags/'+item.name]">{{item.name}}</a>
<i nz-icon nzTheme="fill" nzType="tag"></i>
<a [routerLink]="['/tags/'+item.name]" class="tag">{{item.name}}</a>
</span>
</div>
<div class="article-bAnda">
<a (click)="toArticle(article.nextArticle.id)" [class.disabled]="!article.nextArticle">
<i nz-icon nzType="left" nzTheme="outline"></i>
<i nz-icon nzTheme="outline" nzType="left"></i>
{{(article.nextArticle && article.nextArticle.title) || '无'}}
</a>
<a (click)="toArticle(article.preArticle.id)" [class.disabled]="!article.preArticle"
style="float: right" id="pre">
id="pre" style="float: right">
{{(article.preArticle && article.preArticle.title) || '无'}}
<i nz-icon nzType="right" nzTheme="outline"></i>
<i nz-icon nzTheme="outline" nzType="right"></i>
</a>
</div>
@@ -36,18 +36,18 @@
</ng-template>
<nz-comment id="f-comment">
<nz-avatar nz-comment-avatar nzIcon="user" [nzSrc]="avatarImgUrl"></nz-avatar>
<nz-avatar [nzSrc]="avatarImgUrl" nz-comment-avatar nzIcon="user"></nz-avatar>
<nz-comment-content>
<nz-form-item>
<textarea [(ngModel)]="comment.content" nz-input rows="4" [disabled]="!user"
[nzAutosize]="{ minRows: 2, maxRows: user?6:2 }"></textarea>
<span *ngIf="!user">请先 <a routerLink="/user/login"
[queryParams]="{url:'/article/'+articleId}">登录</a></span>
<textarea [(ngModel)]="comment.content" [disabled]="!user" [nzAutosize]="{ minRows: 2, maxRows: user?6:2 }" nz-input
rows="4"></textarea>
<span *ngIf="!user">请先 <a [queryParams]="{url:'/article/'+articleId}"
routerLink="/user/login">登录</a></span>
</nz-form-item>
<nz-form-item>
<button nz-button nzType="primary" [nzLoading]="!user&&submitting"
[disabled]="!comment.content"
(click)="submitComment(true)">评论
<button (click)="submitComment(true)" [disabled]="!comment.content" [nzLoading]="!user&&submitting"
nz-button
nzType="primary">评论
</button>
</nz-form-item>
</nz-comment-content>
@@ -61,28 +61,28 @@
<nz-list [nzLoading]="!commentPage">
<nz-list-item *ngFor="let comment of commentPage.list">
<nz-comment [nzAuthor]="comment.fromUser.displayName" [nzDatetime]="comment.date" style="width: 100%">
<nz-avatar nz-comment-avatar nzIcon="user" [nzSrc]="comment.fromUser.avatarImgUrl"
*ngIf="comment.fromUser.avatarImgUrl">
<nz-avatar *ngIf="comment.fromUser.avatarImgUrl" [nzSrc]="comment.fromUser.avatarImgUrl" nz-comment-avatar
nzIcon="user">
</nz-avatar>
<nz-avatar nz-comment-avatar nzIcon="user" [nzText]="comment.fromUser.displayName"
*ngIf="!comment.fromUser.avatarImgUrl">
<nz-avatar *ngIf="!comment.fromUser.avatarImgUrl" [nzText]="comment.fromUser.displayName" nz-comment-avatar
nzIcon="user">
</nz-avatar>
<nz-comment-content>
<p style="font-size: larger">{{ comment.content }}</p>
</nz-comment-content>
<nz-comment-action>
<i nz-icon nzType="message" nzTheme="outline"></i>
<button nz-button nzType="link" (click)="resp(comment.id,comment.fromUser.displayName)">回复
<i nz-icon nzTheme="outline" nzType="message"></i>
<button (click)="resp(comment.id,comment.fromUser.displayName)" nz-button nzType="link">回复
</button>
</nz-comment-action>
<nz-list-item *ngFor="let com of comment.respComment">
<nz-comment [nzAuthor]="com.fromUser.displayName" [nzDatetime]="com.date">
<nz-avatar nz-comment-avatar nzIcon="user" [nzSrc]="com.fromUser.avatarImgUrl"
*ngIf="com.fromUser.avatarImgUrl">
<nz-avatar *ngIf="com.fromUser.avatarImgUrl" [nzSrc]="com.fromUser.avatarImgUrl" nz-comment-avatar
nzIcon="user">
</nz-avatar>
<nz-avatar nz-comment-avatar nzIcon="user" [nzText]="com.fromUser.displayName"
*ngIf="!com.fromUser.avatarImgUrl">
<nz-avatar *ngIf="!com.fromUser.avatarImgUrl" [nzText]="com.fromUser.displayName" nz-comment-avatar
nzIcon="user">
</nz-avatar>
<nz-comment-content>
<p style="font-size: larger">{{ com.content }}</p>
@@ -96,18 +96,18 @@
<nz-form-item *ngIf="pid==comment.id">
<nz-input-group [nzAddOnBefore]="respName">
<textarea nz-input [(ngModel)]="content" placeholder="写出你的想法"
[nzAutosize]="{ minRows: 2, maxRows: 6 }" [disabled]="!user">
<textarea [(ngModel)]="content" [disabled]="!user" [nzAutosize]="{ minRows: 2, maxRows: 6 }"
nz-input placeholder="写出你的想法">
</textarea>
<ng-template #respName>
<span>@{{name}}</span>
</ng-template>
</nz-input-group>
<div *ngIf="!user">请先 <a routerLink="/user/login"
[queryParams]="{url:'/article/'+articleId}">登录</a></div>
<button nz-button (click)="pid=null" style="margin-top: 10px;">取消</button>
<button nz-button nzType="primary" (click)="submitComment(false)"
style="margin-left: 30px;margin-top: 10px;" [nzLoading]="!user&&submitting">回复
<div *ngIf="!user">请先 <a [queryParams]="{url:'/article/'+articleId}"
routerLink="/user/login">登录</a></div>
<button (click)="pid=null" nz-button style="margin-top: 10px;">取消</button>
<button (click)="submitComment(false)" [nzLoading]="!user&&submitting" nz-button
nzType="primary" style="margin-left: 30px;margin-top: 10px;">回复
</button>
</nz-form-item>

View File

@@ -102,6 +102,7 @@ nz-content {
.article-bAnda {
height: 70px;
max-height: 110px;
a {
display: block;
}
@@ -110,4 +111,4 @@ nz-content {
#f-comment {
margin: 30px 3%
}
}
}

View File

@@ -1,25 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { ArticleComponent } from './article.component';
import {ArticleComponent} from './article.component';
describe('ArticleComponent', () => {
let component: ArticleComponent;
let fixture: ComponentFixture<ArticleComponent>;
let component: ArticleComponent;
let fixture: ComponentFixture<ArticleComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ArticleComponent ]
})
.compileComponents();
}));
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ArticleComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ArticleComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
beforeEach(() => {
fixture = TestBed.createComponent(ArticleComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,16 +1,15 @@
import {Component, OnInit} from '@angular/core';
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {ApiService} from '../../api/api.service';
import {Article} from '../../class/Article';
import {Title} from '@angular/platform-browser';
import {User} from '../../class/User';
import {CommentReq} from '../../class/Comment';
import {Comment, CommentReq} from '../../class/Comment';
import {PageList} from '../../class/HttpReqAndResp';
import {Comment} from '../../class/Comment';
import {GlobalUserService} from '../../services/global-user.service';
import VditorPreview from 'vditor/dist/method.min';
declare var editormd;
declare var $;
declare let $;
@Component({
selector: 'view-article',
@@ -19,6 +18,20 @@ declare var $;
})
export class ArticleComponent implements OnInit {
@ViewChild('divElement') divElement: ElementRef;
articleId: number;
article: Article;
copyRightUrl: string;
user: User;
submitting: boolean = false;
comment: CommentReq;
// 作为输入框@ 的提示
name: string;
commentPage: PageList<Comment>;
avatarImgUrl: string;
pid: number;
content: string;
constructor(private activatedRoute: ActivatedRoute,
private apiService: ApiService,
private userService: GlobalUserService,
@@ -27,19 +40,7 @@ export class ArticleComponent implements OnInit {
this.articleId = +activatedRoute.snapshot.paramMap.get('id');
}
articleId: number;
article: Article;
copyRightUrl: string;
user: User;
submitting: boolean = false;
comment: CommentReq;
// 作为输入框@ 的提示
name: string;
commentPage: PageList<Comment>;
avatarImgUrl: string;
pid: number;
content: string;
// private vditor: Vditor;
ngOnInit() {
this.toArticle(this.articleId);
@@ -48,24 +49,37 @@ export class ArticleComponent implements OnInit {
error: (err) => null,
next: data => {
this.user = data.result;
if (data.result) this.avatarImgUrl = data.result.avatarImgUrl;
if (data.result) {this.avatarImgUrl = data.result.avatarImgUrl;}
}
});
this.comment = new CommentReq(`article/${this.articleId}`);
}
parseMd(md: string) {
editormd.markdownToHTML('article-content', {
markdown: this.article.mdContent,
htmlDecode: 'style,script,iframe', // you can filter tags decode
toc: false,
tocm: false, // Using [TOCM]
// tocContainer: '#article-slider', // 自定义 ToC 容器层
// tocDropdown: true,
emoji: true,
taskList: true,
flowChart: true, // 默认不解析
});
const option: IPreviewOptions = {
anchor: 1,
hljs: {
lineNumber: true
},
markdown: {
autoSpace: true,
fixTermTypo: true,
chinesePunct: true,
linkBase: location.href,
toc: true,
mark: true
},
after: () => {
// 处理锚点
const tocList: HTMLCollection = this.divElement.nativeElement
.getElementsByClassName('vditor-toc')[0]?.getElementsByTagName(`a`);
for (let i = 0; i < tocList?.length; i++) {
const linkValue = tocList.item(i).getAttribute('href');
tocList.item(i).setAttribute('href', window.location.pathname + linkValue);
}
}
};
VditorPreview.preview(this.divElement.nativeElement, md, option);
}
toArticle(id: number) {

View File

@@ -2,16 +2,19 @@ import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {ArticleRoutingModule} from './article-routing.module';
import {ArticleComponent} from './article.component';
import {
NzAffixModule,
NzAnchorModule, NzAvatarModule,
NzButtonModule,
NzCommentModule,
NzDividerModule, NzFormModule,
NzGridModule,
NzIconModule, NzInputModule,
NzLayoutModule, NzListModule, NzTabsModule
} from 'ng-zorro-antd';
import {NzAffixModule} from 'ng-zorro-antd/affix';
import {NzAnchorModule} from 'ng-zorro-antd/anchor';
import {NzAvatarModule} from 'ng-zorro-antd/avatar';
import {NzButtonModule} from 'ng-zorro-antd/button';
import {NzCommentModule} from 'ng-zorro-antd/comment';
import {NzDividerModule} from 'ng-zorro-antd/divider';
import {NzFormModule} from 'ng-zorro-antd/form';
import {NzGridModule} from 'ng-zorro-antd/grid';
import {NzIconModule} from 'ng-zorro-antd/icon';
import {NzInputModule} from 'ng-zorro-antd/input';
import {NzLayoutModule} from 'ng-zorro-antd/layout';
import {NzListModule} from 'ng-zorro-antd/list';
import {NzTabsModule} from 'ng-zorro-antd/tabs';
import {FormsModule} from '@angular/forms';

View File

@@ -3,9 +3,9 @@
<div id="category">
<ul *ngIf="categoryList.length">
<c-tag-tag *ngFor="let category of categoryList"
[tag]="{name:category.name,size:category.articles.length}"
(tagClick)="changeCategory(category)">
<c-tag-tag (tagClick)="changeCategory(category)"
*ngFor="let category of categoryList"
[tag]="{name:category.name,size:category.articles.length}">
</c-tag-tag>
</ul>
@@ -16,7 +16,7 @@
<span style="font-weight: bolder;">{{name}}</span>
</span>
<ul id="detail" *ngIf="articleList&&articleList.list.length">
<ul *ngIf="articleList&&articleList.list.length" id="detail">
<c-article-detail-card *ngFor="let article of articleList.list"
[data]="article" [showMediaArea]="false" [showTagArea]="false">
</c-article-detail-card>
@@ -25,4 +25,4 @@
<div *ngIf="!articleList||!articleList.list.length">
<h2 style="text-align: center">该分类暂无文章</h2>
</div>
</div>
</div>

View File

@@ -23,7 +23,8 @@
#main {
width: 100%;
}
#detail{
#detail {
margin: 10px 40px 10px 0;
}
}
}

View File

@@ -1,25 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { CategoryComponent } from './category.component';
import {CategoryComponent} from './category.component';
describe('CategoryComponent', () => {
let component: CategoryComponent;
let fixture: ComponentFixture<CategoryComponent>;
let component: CategoryComponent;
let fixture: ComponentFixture<CategoryComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ CategoryComponent ]
})
.compileComponents();
}));
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [CategoryComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(CategoryComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
beforeEach(() => {
fixture = TestBed.createComponent(CategoryComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,7 +1,7 @@
import {Component, OnInit} from '@angular/core';
import {ApiService} from '../../api/api.service';
import {Tag} from '../../class/Tag';
import {NzMessageService} from 'ng-zorro-antd';
import {NzMessageService} from 'ng-zorro-antd/message';
import {PageList} from '../../class/HttpReqAndResp';
import {Article} from '../../class/Article';
import {ActivatedRoute} from '@angular/router';
@@ -15,6 +15,11 @@ import {Title} from '@angular/platform-browser';
})
export class CategoryComponent implements OnInit {
categoryList: Tag[] = [];
articleList: PageList<Article>;
name: string;
private category: Tag;
constructor(private apiService: ApiService,
private nzMessageService: NzMessageService,
private activatedRoute: ActivatedRoute,
@@ -22,12 +27,6 @@ export class CategoryComponent implements OnInit {
private title: Title) {
}
categoryList: Tag[] = [];
private category: Tag;
articleList: PageList<Article>;
name: string;
ngOnInit() {
this.name = this.activatedRoute.snapshot.paramMap.get('category');
this.getCategories(this.name == null);

View File

@@ -2,7 +2,8 @@ import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {CategoryComponent} from './category.component';
import {CategoryRoutingModule} from './category-routing.module';
import {NzIconModule, NzToolTipModule} from 'ng-zorro-antd';
import {NzIconModule} from 'ng-zorro-antd/icon';
import {NzToolTipModule} from 'ng-zorro-antd/tooltip';
import {IndexModule} from '../index/index.module';

View File

@@ -1,7 +1,5 @@
<div>
<div id="main">
<nz-alert [nzType]="type" [nzMessage]="message"
[nzDescription]="desc" nzShowIcon>
</nz-alert>
<nz-alert [nzDescription]="desc" [nzMessage]="message" [nzType]="type" nzShowIcon></nz-alert>
</div>
</div>
</div>

View File

@@ -1,6 +1,6 @@
#main{
#main {
width: 60%;
height: 50px;
margin: 0 auto;
padding: 15% 0;
}
}

View File

@@ -1,25 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { EmailVerifyComponent } from './email-verify.component';
import {EmailVerifyComponent} from './email-verify.component';
describe('EmailVerifyComponent', () => {
let component: EmailVerifyComponent;
let fixture: ComponentFixture<EmailVerifyComponent>;
let component: EmailVerifyComponent;
let fixture: ComponentFixture<EmailVerifyComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ EmailVerifyComponent ]
})
.compileComponents();
}));
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [EmailVerifyComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(EmailVerifyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
beforeEach(() => {
fixture = TestBed.createComponent(EmailVerifyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -10,6 +10,12 @@ import {Title} from '@angular/platform-browser';
})
export class EmailVerifyComponent implements OnInit {
type: string = 'info';
message: string = '正在验证,请稍等';
desc: string = '';
private email: string;
private verifyId: string;
constructor(private titleService: Title,
private router: Router,
public routerinfo: ActivatedRoute,
@@ -17,14 +23,6 @@ export class EmailVerifyComponent implements OnInit {
titleService.setTitle('小海博客 | 邮箱验证');
}
type: string = 'info';
message: string = '正在验证,请稍等';
desc: string = '';
private email: string;
private verifyId: string;
ngOnInit(): void {
this.email = this.routerinfo.snapshot.queryParams.email;
this.verifyId = this.routerinfo.snapshot.queryParams.verifyId;

View File

@@ -2,7 +2,7 @@ import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {Route, RouterModule} from '@angular/router';
import {EmailVerifyComponent} from './email-verify.component';
import {NzAlertModule} from 'ng-zorro-antd';
import {NzAlertModule} from 'ng-zorro-antd/alert';
const routes: Route[] = [
{path: '**', component: EmailVerifyComponent}

View File

@@ -1,19 +1,19 @@
<nz-card id="article-card" [nzLoading]="data==null">
<nz-card [nzLoading]="data==null" id="article-card">
<h1><a [routerLink]="'/article/'+data.id">{{data.title}}</a></h1>
<div>
<span *ngIf="showMediaArea" id="article-original" [ngClass]="data.original?'original':'reproduced'">
<span *ngIf="showMediaArea" [ngClass]="data.original?'original':'reproduced'" id="article-original">
{{data.original ? '原创' : '转载'}}
</span>
<span *ngIf="showMediaArea" class="badge">
<i nz-icon nzType="calendar" nzTheme="outline"></i>
<i nz-icon nzTheme="outline" nzType="calendar"></i>
<span>{{data.publishDateFormat}}</span>
</span>
<span *ngIf="showMediaArea" class="badge">
<i nz-icon nzType="user" nzTheme="outline"></i>
<i nz-icon nzTheme="outline" nzType="user"></i>
<span>{{data.author.displayName}}</span>
</span>
<span *ngIf="showMediaArea" class="badge">
<i nz-icon nzType="file" nzTheme="outline"></i>
<i nz-icon nzTheme="outline" nzType="file"></i>
<span>
<a [routerLink]="'/categories/'+data.category">{{data.category}}</a>
</span>
@@ -21,13 +21,13 @@
</div>
<p>{{data.summary}}</p>
<span style="float: right;margin-bottom: 10px">
<a [routerLink]="'/article/'+data.id">阅读更多<i nz-icon nzType="right" nzTheme="outline"></i></a>
<a [routerLink]="'/article/'+data.id">阅读更多<i nz-icon nzTheme="outline" nzType="right"></i></a>
</span>
<ng-template [ngIf]="showTagArea&&data.tags.length>0">
<nz-divider></nz-divider>
<div>
<span *ngFor="let tag of data.tags">
<i nz-icon nzType="tag" nzTheme="outline"></i>
<i nz-icon nzTheme="outline" nzType="tag"></i>
<a [routerLink]="'/tags/'+tag.name">{{tag.name}}</a>
</span>
</div>

View File

@@ -1,25 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { ArticleDetailCardComponent } from './article-detail-card.component';
import {ArticleDetailCardComponent} from './article-detail-card.component';
describe('ArticleDetailCardComponent', () => {
let component: ArticleDetailCardComponent;
let fixture: ComponentFixture<ArticleDetailCardComponent>;
let component: ArticleDetailCardComponent;
let fixture: ComponentFixture<ArticleDetailCardComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ArticleDetailCardComponent ]
})
.compileComponents();
}));
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ArticleDetailCardComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ArticleDetailCardComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
beforeEach(() => {
fixture = TestBed.createComponent(ArticleDetailCardComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,6 +1,5 @@
import {Component, Input, OnInit} from '@angular/core';
import {Article} from '../../../../class/Article';
import {ColorList} from '../../../../utils/color';
@Component({
selector: 'c-article-detail-card',
@@ -9,13 +8,13 @@ import {ColorList} from '../../../../utils/color';
})
export class ArticleDetailCardComponent implements OnInit {
constructor() {
}
@Input() data: Article;
@Input() showMediaArea: boolean;
@Input() showTagArea: boolean;
constructor() {
}
ngOnInit() {
if (this.data == null || this.data.id == null) {
throw Error('data 不可为空');

View File

@@ -1,25 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { CardDetailComponent } from './card-detail.component';
import {CardDetailComponent} from './card-detail.component';
describe('CardDetailComponent', () => {
let component: CardDetailComponent;
let fixture: ComponentFixture<CardDetailComponent>;
let component: CardDetailComponent;
let fixture: ComponentFixture<CardDetailComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ CardDetailComponent ]
})
.compileComponents();
}));
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [CardDetailComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(CardDetailComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
beforeEach(() => {
fixture = TestBed.createComponent(CardDetailComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -7,11 +7,11 @@ import {Component, Input, OnInit} from '@angular/core';
})
export class CardDetailComponent implements OnInit {
@Input() title: string;
constructor() {
}
@Input() title: string;
// @ContentChildren() c:T;
ngOnInit() {

View File

@@ -1,19 +1,19 @@
<div class="tag-tag" nz-tooltip
style="cursor: pointer"
[nzTooltipTitle]="tag.name"
(click)="click()">
<span class="tag-name"
[style.background-color]="randColor.bgColor"
<div (click)="click()" [nzTooltipTitle]="tag.name"
class="tag-tag"
nz-tooltip
style="cursor: pointer">
<span [style.background-color]="randColor.bgColor"
[style.color]="randColor.fontColor"
[style.font-size]="size=='large'?'large':''"
[style.padding]="size=='large'?'12px 15px':'5px 7px'"
class="tag-name"
>{{tag.name}}
</span>
<ng-template [ngIf]="enableCount">
<span class="tag-count"
[style.border-color]="randColor.bgColor"
<span [style.border-color]="randColor.bgColor"
[style.font-size]="size=='large'?'large':''"
[style.padding]="size=='large'?'11px 14px':'4px 6px'"
class="tag-count"
>{{tag.size}}
</span>
</ng-template>

View File

@@ -1,25 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { TagTagComponent } from './tag-tag.component';
import {TagTagComponent} from './tag-tag.component';
describe('TagTagComponent', () => {
let component: TagTagComponent;
let fixture: ComponentFixture<TagTagComponent>;
let component: TagTagComponent;
let fixture: ComponentFixture<TagTagComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ TagTagComponent ]
})
.compileComponents();
}));
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [TagTagComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(TagTagComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
beforeEach(() => {
fixture = TestBed.createComponent(TagTagComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,5 +1,5 @@
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {ColorList} from '../../../../utils/color';
import {COLOR_LIST} from '../../../../utils/color';
import {Router} from '@angular/router';
@Component({
@@ -9,20 +9,19 @@ import {Router} from '@angular/router';
})
export class TagTagComponent implements OnInit {
constructor(private router: Router) {
}
@Input() tag: { name: string, size: number };
@Input() tag: { name: string; size: number };
@Input() size: 'default' | 'large' = 'default';
@Input() clickable: boolean; // default true
@Input() enableCount: boolean; // default true
@Output() tagClick = new EventEmitter();
randColor: { bgColor: string; fontColor: string };
randColor: { bgColor: string, fontColor: string };
constructor(private router: Router) {
}
ngOnInit() {
const randomNumber = Math.floor(ColorList.length * Math.random());
this.randColor = ColorList[randomNumber];
const randomNumber = Math.floor(COLOR_LIST.length * Math.random());
this.randColor = COLOR_LIST[randomNumber];
if (this.clickable == null) {
this.clickable = true;
}

View File

@@ -1,83 +1,83 @@
<div nz-row id="index-container">
<div nz-col nzSpan="14" nzOffset="2" id="index-left">
<div id="index-container" nz-row>
<div id="index-left" nz-col nzOffset="2" nzSpan="14">
<ng-template [ngIf]="articles&&articles.total">
<c-article-detail-card *ngFor="let item of articles.list" [data]="item">
</c-article-detail-card>
</ng-template>
<nz-pagination style="text-align: center"
<nz-pagination (nzPageIndexChange)="getArticles($event)"
*ngIf="articles" [nzPageIndex]="articles.pageNum"
[nzTotal]="articles.total"
[nzPageSize]="articles.pageSize"
(nzPageIndexChange)="getArticles($event)">
[nzTotal]="articles.total"
style="text-align: center">
</nz-pagination>
</div>
<div nz-col nzSpan="5" nzOffset="1" id="index-right">
<div id="index-right" nz-col nzOffset="1" nzSpan="5">
<!-- 关于博主 -->
<c-card-detail title="关于博主">
<div id="index-bloger-container" title="">
<img id="index-bloger-pic"
[src]="imgUrl" alt="pic">
<img [src]="imgUrl"
alt="pic" id="index-bloger-pic">
<div id="index-bloger-desc">
<p><span style="font-weight: bold;font-size: x-large;"
[title]="desc"> 郑 海</span></p>
<p><span [title]="desc"
style="font-weight: bold;font-size: x-large;"> 郑 海</span></p>
<p><i nz-icon nzType="blog:location"></i> Location : 武汉</p>
<p><i nz-icon nzType="github" nzTheme="outline"></i>
Github : <a target="_blank" href="https://github.com/xiaohai2271"> link>></a>
<p><i nz-icon nzTheme="outline" nzType="github"></i>
Github : <a href="https://github.com/xiaohai2271" target="_blank"> link>></a>
</p>
</div>
</div>
<div id="index-bloger-button-area" title="">
<div id="index-bloger-qq-btn">
<i nz-icon nzType="qq" title="QQ二维码" nzTheme="outline"
style="color: #ff8936;border-color: #ff8936;cursor: pointer"
(mouseenter)="changeImg(qqQrImgUrl)" (mouseleave)="changeImg()"></i>
<i (mouseenter)="changeImg(qqQrImgUrl)" (mouseleave)="changeImg()" nz-icon nzTheme="outline"
nzType="qq"
style="color: #ff8936;border-color: #ff8936;cursor: pointer" title="QQ二维码"></i>
</div>
<div id="index-bloger-wx-btn">
<i nz-icon nzType="wechat" title="微信二维码" nzTheme="outline"
style="color: #7bcfa6;border-color: #7bcfa6;cursor: pointer"
(mouseenter)="changeImg(wxQrImgUrl)" (mouseleave)="changeImg()"></i>
<i (mouseenter)="changeImg(wxQrImgUrl)" (mouseleave)="changeImg()" nz-icon nzTheme="outline"
nzType="wechat"
style="color: #7bcfa6;border-color: #7bcfa6;cursor: pointer" title="微信二维码"></i>
</div>
</div>
</c-card-detail>
<!-- 分类云 -->
<c-card-detail title="分类云">
<div title="" style="text-align: center;user-select: none">
<c-tag-tag *ngFor="let category of categoryList"
[tag]="{name:category.name,size:category.articles.length}"
(tagClick)="toCategory(category.name)">
<div style="text-align: center;user-select: none" title="">
<c-tag-tag (tagClick)="toCategory(category.name)"
*ngFor="let category of categoryList"
[tag]="{name:category.name,size:category.articles.length}">
</c-tag-tag>
</div>
</c-card-detail>
<!-- 标签云 -->
<c-card-detail title="标签云">
<div title="" style="text-align: center;user-select: none">
<c-tag-tag *ngFor="let tag of tagNameAndNumber" [tag]="tag" (tagClick)="toTag(tag.name)">
<div style="text-align: center;user-select: none" title="">
<c-tag-tag (tagClick)="toTag(tag.name)" *ngFor="let tag of tagNameAndNumber" [tag]="tag">
</c-tag-tag>
</div>
</c-card-detail>
<!-- 网站信息 -->
<c-card-detail title="网站信息" id="index-site-info">
<c-card-detail id="index-site-info" title="网站信息">
<p *ngIf="counts && counts.articleCount">
<i nz-icon nzType="info-circle" nzTheme="outline"></i>文章总数: {{counts.articleCount}}篇
<i nz-icon nzTheme="outline" nzType="info-circle"></i>文章总数: {{counts.articleCount}}篇
</p>
<p *ngIf="counts && counts.categoryCount">
<i nz-icon nzType="info-circle" nzTheme="outline"></i>分类总数: {{counts.categoryCount}}个
<i nz-icon nzTheme="outline" nzType="info-circle"></i>分类总数: {{counts.categoryCount}}个
</p>
<p *ngIf="counts && counts.tagCount">
<i nz-icon nzType="info-circle" nzTheme="outline"></i>标签总数: {{counts.tagCount}}个
<i nz-icon nzTheme="outline" nzType="info-circle"></i>标签总数: {{counts.tagCount}}个
</p>
<p *ngIf="counts && counts.visitorCount">
<i nz-icon nzType="info-circle" nzTheme="outline"></i>访客总数: {{counts.visitorCount}}次
<i nz-icon nzTheme="outline" nzType="info-circle"></i>访客总数: {{counts.visitorCount}}次
</p>
<p *ngIf="lastestUpdate">
<i nz-icon nzType="info-circle" nzTheme="outline"></i>上次更新时间: {{lastestUpdate.lastUpdateTime}}
<i nz-icon nzTheme="outline" nzType="info-circle"></i>上次更新时间: {{lastestUpdate.lastUpdateTime}}
</p>
<p *ngIf="lastestUpdate&&lastestUpdate.committerDate">
<i nz-icon nzType="info-circle" nzTheme="outline"></i>上次提交代码时间: {{lastestUpdate.committerDate}}
<i nz-icon nzTheme="outline" nzType="info-circle"></i>上次提交代码时间: {{lastestUpdate.committerDate}}
</p>
</c-card-detail>

View File

@@ -1,25 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { IndexComponent } from './index.component';
import {IndexComponent} from './index.component';
describe('IndexComponent', () => {
let component: IndexComponent;
let fixture: ComponentFixture<IndexComponent>;
let component: IndexComponent;
let fixture: ComponentFixture<IndexComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ IndexComponent ]
})
.compileComponents();
}));
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [IndexComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(IndexComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
beforeEach(() => {
fixture = TestBed.createComponent(IndexComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,7 +1,8 @@
import {Component, OnInit} from '@angular/core';
import {ApiService} from '../../api/api.service';
import {Article} from '../../class/Article';
import {NzIconService, NzMessageService} from 'ng-zorro-antd';
import {NzIconService} from 'ng-zorro-antd/icon';
import {NzMessageService} from 'ng-zorro-antd/message';
import {SvgIconUtil} from '../../utils/svgIconUtil';
import {PageList, RequestObj} from '../../class/HttpReqAndResp';
import {Router} from '@angular/router';
@@ -16,6 +17,30 @@ import {Title} from '@angular/platform-browser';
})
export class IndexComponent implements OnInit {
readonly logoImgUrl: string = 'https://56462271.oss-cn-beijing.aliyuncs.com/web/logo.png';
readonly qqQrImgUrl: string = 'https://56462271.oss-cn-beijing.aliyuncs.com/web/qq.jpg';
readonly wxQrImgUrl: string = 'https://56462271.oss-cn-beijing.aliyuncs.com/web/wx.jpg';
imgUrl: string;
desc: string;
articles: PageList<Article>;
tagNameAndNumber: { name: string; size: number }[];
categoryList: Category[];
counts: {
articleCount: number;
visitorCount: number;
categoryCount: number;
tagCount: number;
commentCount: number;
};
lastestUpdate: {
lastUpdateTime: string;
lastUpdateInfo: string;
lastCommit: string;
committerAuthor: string;
committerDate: string;
commitUrl: string;
};
constructor(private apiService: ApiService,
private iconService: NzIconService,
private nzMessageService: NzMessageService,
@@ -25,31 +50,6 @@ export class IndexComponent implements OnInit {
title.setTitle('小海博客');
}
readonly logoImgUrl: string = 'https://56462271.oss-cn-beijing.aliyuncs.com/web/logo.png';
readonly qqQrImgUrl: string = 'https://56462271.oss-cn-beijing.aliyuncs.com/web/qq.jpg';
readonly wxQrImgUrl: string = 'https://56462271.oss-cn-beijing.aliyuncs.com/web/wx.jpg';
imgUrl: string;
desc: string;
articles: PageList<Article>;
tagNameAndNumber: { name: string, size: number }[];
categoryList: Category[];
counts: {
articleCount: number,
visitorCount: number,
categoryCount: number,
tagCount: number,
commentCount: number
};
lastestUpdate: {
lastUpdateTime: string;
lastUpdateInfo: string;
lastCommit: string;
committerAuthor: string;
committerDate: string;
commitUrl: string
};
ngOnInit() {
this.imgUrl = this.logoImgUrl;
this.desc = '一个爱好瞎捣鼓的技术宅 :)\n欢迎一起来探讨学习。';

View File

@@ -3,17 +3,15 @@ import {CommonModule} from '@angular/common';
import {IndexComponent} from './index.component';
import {IndexRoutingModule} from './index-routing.module';
import {ArticleDetailCardComponent} from './components/article-detail-card/article-detail-card.component';
import {
NzBackTopModule,
NzCardModule,
NzDividerModule,
NzGridModule,
NzIconModule,
NzPaginationModule,
NzToolTipModule
} from 'ng-zorro-antd';
import { CardDetailComponent } from './components/card-detail/card-detail.component';
import { TagTagComponent } from './components/tag-tag/tag-tag.component';
import {NzBackTopModule} from 'ng-zorro-antd/back-top';
import {NzCardModule} from 'ng-zorro-antd/card';
import {NzDividerModule} from 'ng-zorro-antd/divider';
import {NzGridModule} from 'ng-zorro-antd/grid';
import {NzIconModule} from 'ng-zorro-antd/icon';
import {NzPaginationModule} from 'ng-zorro-antd/pagination';
import {NzToolTipModule} from 'ng-zorro-antd/tooltip';
import {CardDetailComponent} from './components/card-detail/card-detail.component';
import {TagTagComponent} from './components/tag-tag/tag-tag.component';
@NgModule({

View File

@@ -1,25 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import { LeaveMsgComponent } from './leave-msg.component';
import {LeaveMsgComponent} from './leave-msg.component';
describe('LeaveMsgComponent', () => {
let component: LeaveMsgComponent;
let fixture: ComponentFixture<LeaveMsgComponent>;
let component: LeaveMsgComponent;
let fixture: ComponentFixture<LeaveMsgComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ LeaveMsgComponent ]
})
.compileComponents();
}));
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [LeaveMsgComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LeaveMsgComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
beforeEach(() => {
fixture = TestBed.createComponent(LeaveMsgComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,15 +1,16 @@
import { Component, OnInit } from '@angular/core';
import {Component, OnInit} from '@angular/core';
@Component({
selector: 'view-leave-msg',
templateUrl: './leave-msg.component.html',
styleUrls: ['./leave-msg.component.less']
selector: 'view-leave-msg',
templateUrl: './leave-msg.component.html',
styleUrls: ['./leave-msg.component.less']
})
export class LeaveMsgComponent implements OnInit {
constructor() { }
constructor() {
}
ngOnInit() {
}
ngOnInit() {
}
}

View File

@@ -1,20 +1,20 @@
<div class="site-middle am-animation-slide-top">
<div class="title">
<i nz-icon nzType="smile" nzTheme="outline" class="titleTag"></i><span class="title">友情链接</span>
<i class="titleTag" nz-icon nzTheme="outline" nzType="smile"></i><span class="title">友情链接</span>
</div>
<ul class="partner-sites">
<li *ngFor="let link of linkList;let i = index" [style.background]="colors[i].bgColor"
[style.color]="colors[i].fontColor">
<a [href]="link.url" target="_blank" [title]="link.desc||link.name" [style.color]="colors[i].fontColor">
<a [href]="link.url" [style.color]="colors[i].fontColor" [title]="link.desc||link.name" target="_blank">
<div class="link-name">
<i nz-icon nzType="link" nzTheme="outline" [style.color]="colors[i].fontColor"></i>
<i [style.color]="colors[i].fontColor" nz-icon nzTheme="outline" nzType="link"></i>
{{link.name}}
</div>
<div class="link-info" [style.color]="colors[i].fontColor">
<div [style.color]="colors[i].fontColor" class="link-info">
<div class="link-icon">
<img *ngIf="link.iconPath" [src]="link.iconPath" [alt]="link.iconPath">
<i *ngIf="!link.iconPath" nz-icon nzType="link" nzTheme="outline"
[style.color]="colors[i].fontColor"></i>
<img *ngIf="link.iconPath" [alt]="link.iconPath" [src]="link.iconPath">
<i *ngIf="!link.iconPath" [style.color]="colors[i].fontColor" nz-icon nzTheme="outline"
nzType="link"></i>
</div>
<p>
{{link.desc || '该站长暂时未留下网站简介'}}
@@ -22,13 +22,13 @@
</div>
</a>
</li>
<li class="applylink" (click)="showModal=!showModal">申请友链</li>
<li (click)="showModal=!showModal" class="applylink">申请友链</li>
</ul>
</div>
<div class="placard am-animation-slide-bottom">
<div class="title">
<i nz-icon nzType="smile" nzTheme="outline" class="titleTag"></i><span class="title">友链公告</span>
<i class="titleTag" nz-icon nzTheme="outline" nzType="smile"></i><span class="title">友链公告</span>
</div>
<br>
<p style="padding-left: 30px;">
@@ -42,7 +42,7 @@
本站信息 <br>
名称:小海博客<br>
网址https://www.celess.cn/<br>
图标https://www.celess.cn/logo.ico<br>
图标https://www.celess.cn/assets/logo.jpg<br>
描述:小海博客,记录学习成长历程,主要关注与java后端的技术学习
</p>
<li>本站的友链申请会自动进行抓取并在12h内进行审核</li>
@@ -50,18 +50,18 @@
</ul>
</div>
<nz-modal [(nzVisible)]="showModal" [nzTitle]="modalTitle" [nzContent]="modalContent" [nzFooter]="modalFooter"
(nzOnCancel)="cancel()" nzWidth="650">
<nz-modal (nzOnCancel)="cancel()" [(nzVisible)]="showModal" [nzContent]="modalContent" [nzFooter]="modalFooter"
[nzTitle]="modalTitle" nzWidth="650">
<ng-template #modalTitle>
<h2 style="text-align: center">申请友链</h2>
</ng-template>
<ng-template #modalContent>
<form nz-form [formGroup]="applyFormGroup">
<form [formGroup]="applyFormGroup" nz-form>
<nz-form-item>
<nz-form-label nzFlex="100px" nzRequired>网站名称</nz-form-label>
<nz-form-control nzFlex="auto" [nzErrorTip]="nameErrTip">
<input nz-input formControlName="name">
<nz-form-control [nzErrorTip]="nameErrTip" nzFlex="auto">
<input formControlName="name" nz-input>
<ng-template #nameErrTip>
<div *ngIf="applyFormGroup.controls.name.hasError('required')">网站名称不可为空</div>
<div *ngIf="applyFormGroup.controls.name.hasError('maxlength')">最大长度为255</div>
@@ -70,8 +70,8 @@
</nz-form-item>
<nz-form-item>
<nz-form-label nzFlex="100px" nzRequired>站长邮箱</nz-form-label>
<nz-form-control nzFlex="auto" [nzErrorTip]="emailErrTip">
<input nz-input formControlName="email">
<nz-form-control [nzErrorTip]="emailErrTip" nzFlex="auto">
<input formControlName="email" nz-input>
<ng-template #emailErrTip>
<div *ngIf="applyFormGroup.controls.email.hasError('required')">站长邮箱不可为空</div>
<div *ngIf="applyFormGroup.controls.email.hasError('pattern')">邮箱格式不正确</div>
@@ -81,7 +81,7 @@
<nz-form-item>
<nz-form-label nzFlex="100px" nzRequired>首页链接</nz-form-label>
<nz-form-control nzFlex="auto" [nzErrorTip]="urlErrTip">
<nz-form-control [nzErrorTip]="urlErrTip" nzFlex="auto">
<nz-input-group [nzAddOnBefore]="protocol" nzCompact>
<ng-template #protocol>
<nz-select formControlName="urlProtocol">
@@ -89,7 +89,7 @@
<nz-option nzLabel="Https://" nzValue="https://"></nz-option>
</nz-select>
</ng-template>
<input nz-input formControlName="url">
<input formControlName="url" nz-input>
<ng-template #urlErrTip>
<div *ngIf="applyFormGroup.controls.url.hasError('required')">首页链接不可为空</div>
<div *ngIf="applyFormGroup.controls.url.hasError('pattern')">链接格式不正确</div>
@@ -99,7 +99,7 @@
</nz-form-item>
<nz-form-item>
<nz-form-label nzFlex="100px" nzRequired>友链页链接</nz-form-label>
<nz-form-control nzFlex="auto" [nzErrorTip]="urlLinkErrTip">
<nz-form-control [nzErrorTip]="urlLinkErrTip" nzFlex="auto">
<nz-input-group [nzAddOnBefore]="protocol">
<ng-template #protocol>
<nz-select formControlName="urlLinkProtocol">
@@ -107,7 +107,7 @@
<nz-option nzLabel="Https://" nzValue="https://"></nz-option>
</nz-select>
</ng-template>
<input nz-input formControlName="linkUrl">
<input formControlName="linkUrl" nz-input>
<ng-template #urlLinkErrTip>
<div *ngIf="applyFormGroup.controls.linkUrl.hasError('required')">首页链接不可为空</div>
<div *ngIf="applyFormGroup.controls.linkUrl.hasError('pattern')">链接格式不正确</div>
@@ -117,28 +117,28 @@
</nz-form-item>
<nz-form-item>
<nz-form-label nzFlex="100px">网站图标</nz-form-label>
<nz-form-control nzFlex="auto" nzErrorTip="链接格式不正确">
<nz-form-control nzErrorTip="链接格式不正确" nzFlex="auto">
<nz-input-group [nzSuffix]="icon" nzSize="large">
<input nz-input formControlName="iconPath">
<input formControlName="iconPath" nz-input>
</nz-input-group>
<ng-template #icon>
<img style="width: 25px;height: 25px" *ngIf="applyFormGroup.value.iconPath"
[src]="applyFormGroup.value.iconPath" alt="icon">
<img *ngIf="applyFormGroup.value.iconPath" [src]="applyFormGroup.value.iconPath"
alt="icon" style="width: 25px;height: 25px">
</ng-template>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-label nzFlex="100px">网站描述</nz-form-label>
<nz-form-control nzFlex="auto" nzErrorTip="可输入最大文字长度为255">
<textarea nz-input formControlName="desc" [nzAutosize]="{ minRows: 2, maxRows: 6 }"></textarea>
<nz-form-control nzErrorTip="可输入最大文字长度为255" nzFlex="auto">
<textarea [nzAutosize]="{ minRows: 2, maxRows: 6 }" formControlName="desc" nz-input></textarea>
</nz-form-control>
</nz-form-item>
</form>
</ng-template>
<ng-template #modalFooter>
<button nz-button (click)="cancel()">取消</button>
<button nz-button nzType="primary" (click)="apply()" [disabled]="!applyFormGroup.valid" [nzLoading]="loading">
<button (click)="cancel()" nz-button>取消</button>
<button (click)="apply()" [disabled]="!applyFormGroup.valid" [nzLoading]="loading" nz-button nzType="primary">
提交
</button>
</ng-template>

View File

@@ -171,9 +171,10 @@ i {
width: 96%;
}
.partner-sites{
.partner-sites {
padding: 0 30px;
}
.partner-sites li {
float: left;
width: 100%;

Some files were not shown because too many files have changed in this diff Show More