Compare commits

...

174 Commits

Author SHA1 Message Date
dependabot[bot]
5a3e89285e chore(deps-dev): bump @angular-eslint/schematics from 14.4.0 to 15.2.1
Bumps [@angular-eslint/schematics](https://github.com/angular-eslint/angular-eslint/tree/HEAD/packages/schematics) from 14.4.0 to 15.2.1.
- [Release notes](https://github.com/angular-eslint/angular-eslint/releases)
- [Changelog](https://github.com/angular-eslint/angular-eslint/blob/main/packages/schematics/CHANGELOG.md)
- [Commits](https://github.com/angular-eslint/angular-eslint/commits/v15.2.1/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>
2023-03-01 06:57:12 +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 name: Build
on: on:
@@ -9,33 +6,51 @@ on:
jobs: jobs:
build: build:
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '.md')" # 如果 commit 信息包含以下关键字则跳过该任务
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - 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 uses: actions/setup-node@v1
with: with:
node-version: '12.x' node-version: '16.x'
- run: npm install -g @angular/cli - run: npm install
- run: bash build.sh - run: npm run lint && npm run build
- run: cd dist/index/ && tar -cf index.tar ./* && mv index.tar ../../
- name: SCP - name: Upload a Build Artifact
uses: appleboy/scp-action@master uses: actions/upload-artifact@v2.1.4
with: with:
host: ${{ secrets.SSH_HOST }} name: dist
username: ${{ secrets.SSH_USERNAME }} path: ./dist/index/*
password: ${{ secrets.SSH_PASSWORD }}
port: ${{ secrets.SSH_PORT }}
source: "index.tar"
target: "/www/wwwroot/www.celess.cn"
- name: Run SSH command # - name: SCP
uses: garygrossgarten/github-action-ssh@v0.5.0 # uses: appleboy/scp-action@master
with: # with:
command: cd /www/wwwroot/www.celess.cn && bash deploy.sh # host: ${{ secrets.SSH_HOST }}
host: ${{ secrets.SSH_HOST }} # username: ${{ secrets.SSH_USERNAME }}
username: ${{ secrets.SSH_USERNAME }} # password: ${{ secrets.SSH_PASSWORD }}
password: ${{ secrets.SSH_PASSWORD }} # port: ${{ secrets.SSH_PORT }}
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 dist
node_modules node_modules
.idea .idea
.editorconfig .editorconfig
package-lock.json

View File

@@ -22,7 +22,7 @@
"main": "src/main.ts", "main": "src/main.ts",
"polyfills": "src/polyfills.ts", "polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json", "tsConfig": "tsconfig.app.json",
"aot": false, "aot": true,
"assets": [ "assets": [
"src/favicon.ico", "src/favicon.ico",
"src/assets", "src/assets",
@@ -34,18 +34,11 @@
"src/manifest.webmanifest" "src/manifest.webmanifest"
], ],
"styles": [ "styles": [
"src/assets/editor/css/editormd.css",
"./node_modules/ng-zorro-antd/ng-zorro-antd.min.css", "./node_modules/ng-zorro-antd/ng-zorro-antd.min.css",
"src/styles.less" "src/styles.less"
], ],
"scripts": [ "scripts": [
"./node_modules/jquery/dist/jquery.min.js", "./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"
] ]
}, },
"configurations": { "configurations": {
@@ -59,7 +52,6 @@
"optimization": true, "optimization": true,
"outputHashing": "all", "outputHashing": "all",
"sourceMap": false, "sourceMap": false,
"extractCss": true,
"namedChunks": false, "namedChunks": false,
"aot": true, "aot": true,
"extractLicenses": true, "extractLicenses": true,
@@ -119,15 +111,11 @@
} }
}, },
"lint": { "lint": {
"builder": "@angular-devkit/build-angular:tslint", "builder": "@angular-eslint/builder:lint",
"options": { "options": {
"tsConfig": [ "lintFilePatterns": [
"tsconfig.app.json", "src/**/*.ts",
"tsconfig.spec.json", "src/**/*.html"
"e2e/tsconfig.json"
],
"exclude": [
"**/node_modules/**"
] ]
} }
}, },
@@ -146,7 +134,6 @@
} }
} }
}, },
"defaultProject": "index",
"cli": { "cli": {
"analytics": false "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, "private": true,
"dependencies": { "dependencies": {
"@angular/animations": "^10.0.3", "@angular/animations": "^14.2.12",
"@angular/common": "^10.0.3", "@angular/common": "^14.2.12",
"@angular/compiler": "^10.0.3", "@angular/compiler": "^14.2.12",
"@angular/core": "^10.0.3", "@angular/core": "^14.2.12",
"@angular/forms": "^10.0.3", "@angular/forms": "^14.2.12",
"@angular/platform-browser": "^10.0.3", "@angular/platform-browser": "^14.2.12",
"@angular/platform-browser-dynamic": "^10.0.3", "@angular/platform-browser-dynamic": "^14.2.12",
"@angular/router": "^10.0.3", "@angular/router": "^14.2.12",
"@angular/service-worker": "^10.0.3", "@angular/service-worker": "^14.2.12",
"jquery": "^3.5.1", "jquery": "^3.5.1",
"ng-zorro-antd": "^9.3.0", "js-base64": "^3.6.0",
"nrm": "^1.2.1", "ng-zorro-antd": "^14.2.1",
"rxjs": "^6.6.0", "rxjs": "^7.5.7",
"tslib": "^2.0.0", "tslib": "^2.0.3",
"zone.js": "^0.10.3" "vditor": "~3.6.3",
"zone.js": "^0.12.0"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "^0.1000.2", "@angular-devkit/build-angular": "^14.2.10",
"@angular/cli": "^10.0.2", "@angular-eslint/builder": "14.4.0",
"@angular/compiler-cli": "^10.0.3", "@angular-eslint/eslint-plugin": "14.4.0",
"@angular/language-service": "^10.0.3", "@angular-eslint/eslint-plugin-template": "14.4.0",
"@types/jasmine": "^3.5.11", "@angular-eslint/schematics": "15.2.1",
"@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/jasminewd2": "~2.0.3",
"@types/node": "^14.0.22", "@types/node": "^18.11.10",
"codelyzer": "^6.0.0", "@typescript-eslint/eslint-plugin": "^5.36.2",
"jasmine-core": "^3.5.0", "@typescript-eslint/parser": "^5.36.2",
"jasmine-spec-reporter": "^5.0.2", "codelyzer": "^6.0.1",
"karma": "^5.1.0", "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-chrome-launcher": "^3.1.0",
"karma-coverage-istanbul-reporter": "^3.0.3", "karma-coverage-istanbul-reporter": "^3.0.3",
"karma-jasmine": "^3.3.1", "karma-jasmine": "^5.1.0",
"karma-jasmine-html-reporter": "^1.5.4", "karma-jasmine-html-reporter": "^1.5.4",
"protractor": "^7.0.0", "protractor": "^7.0.0",
"ts-node": "^8.10.2", "ts-node": "^10.5.0",
"tslint": "^6.1.2", "typescript": "~4.8.4"
"typescript": "^3.9.6"
} }
} }

View File

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

View File

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

View File

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

View File

@@ -1,7 +1,7 @@
import {BrowserModule} from '@angular/platform-browser'; import {BrowserModule} from '@angular/platform-browser';
import {forwardRef, NgModule} from '@angular/core'; import {NgModule} from '@angular/core';
import {AppComponent} from './app.component'; 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 {FormsModule} from '@angular/forms';
import {HttpClientModule} from '@angular/common/http'; import {HttpClientModule} from '@angular/common/http';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; 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 {GlobalUserService} from './services/global-user.service';
import {LocalStorageService} from './services/local-storage.service'; import {LocalStorageService} from './services/local-storage.service';
import {ApiService} from './api/api.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); registerLocaleData(zh);
@@ -33,13 +43,20 @@ registerLocaleData(zh);
imports: [ imports: [
BrowserModule, BrowserModule,
AppRoutingModule, AppRoutingModule,
NgZorroAntdModule,
FormsModule, FormsModule,
HttpClientModule, HttpClientModule,
BrowserAnimationsModule, BrowserAnimationsModule,
LoginRegistrationModule, LoginRegistrationModule,
AdminModule, 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: [ providers: [
ComponentStateService, ComponentStateService,
@@ -47,6 +64,8 @@ registerLocaleData(zh);
LocalStorageService, LocalStorageService,
HttpService, HttpService,
ApiService, ApiService,
NzMessageService,
NzNotificationService,
ErrorService, ErrorService,
{provide: NZ_I18N, useValue: zh_CN}, {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'; method: 'GET' | 'POST' | 'PUT' | 'DELETE';
data?: {}; data?: {};
contentType?: 'application/json' | 'application/x-www-form-urlencoded'; contentType?: 'application/json' | 'application/x-www-form-urlencoded';
queryParam?: {}; queryParam?: { [key: string]: any };
header?: HttpHeaders | { header?: HttpHeaders | {
[header: string]: string | string[]; [header: string]: string | string[];
}; };

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,7 +1,6 @@
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
import {windowWidthChange} from '../../utils/util'; import {windowWidthChange} from '../../utils/util';
import {ApiService} from '../../api/api.service';
import {User} from '../../class/User'; import {User} from '../../class/User';
import {ComponentStateService} from '../../services/component-state.service'; import {ComponentStateService} from '../../services/component-state.service';
import {GlobalUserService} from '../../services/global-user.service'; import {GlobalUserService} from '../../services/global-user.service';
@@ -12,6 +11,25 @@ import {GlobalUserService} from '../../services/global-user.service';
styleUrls: ['./header.component.less'] styleUrls: ['./header.component.less']
}) })
export class HeaderComponent implements OnInit { 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, constructor(private router: Router,
public componentStateService: ComponentStateService, 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() { ngOnInit() {
} }
@@ -75,17 +73,6 @@ export class HeaderComponent implements OnInit {
this.changeLoginButtonV(); 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) { dealLink(path: string) {
this.showList = window.innerWidth > this.mobileMaxWidth; this.showList = window.innerWidth > this.mobileMaxWidth;
@@ -137,7 +124,20 @@ export class HeaderComponent implements OnInit {
} }
toAdminPage() { 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 {Injectable} from '@angular/core';
import {filter} from 'rxjs/operators'; import {filter} from 'rxjs/operators';
import {NavigationEnd, Router, RouterEvent} from '@angular/router'; import {NavigationEnd, Router, RouterEvent} from '@angular/router';
import {Observable, of, Subscriber} from 'rxjs'; import {Observable, Subscriber} from 'rxjs';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class ComponentStateService { export class ComponentStateService {
constructor(private router: Router) {
this.watchRouterChange()
}
visible = { visible = {
header: true, header: true,
footer: true, footer: true,
globalBackToTop: true globalBackToTop: true
};
currentPath: string;
constructor(private router: Router) {
this.watchRouterChange();
} }
currentPath: string
getCurrentRouterPath = () => this.currentPath; getCurrentRouterPath = () => this.currentPath;
watchRouterChange() { watchRouterChange() {
@@ -31,28 +32,30 @@ export class ComponentStateService {
// lastIndexOf ==> 0/index // lastIndexOf ==> 0/index
const indexOf = path.lastIndexOf('/'); const indexOf = path.lastIndexOf('/');
const prefix = path.substr(0, indexOf === 0 ? path.length : indexOf); const prefix = path.substr(0, indexOf === 0 ? path.length : indexOf);
this.dealWithPathChange(prefix) this.dealWithPathChange(prefix);
this.currentPath = prefix; this.currentPath = prefix;
if (subscriber) subscriber.next(prefix) if (subscriber) {
subscriber.next(prefix);
}
}); });
return ob; return ob;
} }
private dealWithPathChange(path) { private dealWithPathChange(path) {
// tslint:disable-next-line:forin // eslint-disable-next-line guard-for-in
for (const visibleKey in this.visible) { for (const visibleKey in this.visible) {
this.visible[visibleKey] = true this.visible[visibleKey] = true;
} }
switch (path) { switch (path) {
case '/admin': case '/admin':
this.visible.header = false this.visible.header = false;
this.visible.footer = false this.visible.footer = false;
this.visible.globalBackToTop = false this.visible.globalBackToTop = false;
break break;
case '/user': case '/user':
case '/write': case '/write':
this.visible.footer = false this.visible.footer = false;
this.visible.globalBackToTop = false this.visible.globalBackToTop = false;
break; break;
default: default:

View File

@@ -3,7 +3,7 @@ import {RequestObj, Response} from '../class/HttpReqAndResp';
import {environment} from '../../environments/environment'; import {environment} from '../../environments/environment';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
import {ComponentStateService} from './component-state.service'; 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 {HttpService} from '../api/http/http.service';
import {LocalStorageService} from './local-storage.service'; import {LocalStorageService} from './local-storage.service';
@@ -11,6 +11,9 @@ import {LocalStorageService} from './local-storage.service';
providedIn: 'root' providedIn: 'root'
}) })
export class ErrorService { export class ErrorService {
private static httpErrorCount: number = 0;
private readonly maintainPagePrefix = '/maintain';
private readonly adminPagePrefix = '/admin';
constructor(/*private httpService: HttpService,*/ constructor(/*private httpService: HttpService,*/
private router: Router, private router: Router,
@@ -20,48 +23,57 @@ export class ErrorService {
private localStorageService: LocalStorageService) { 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) { public httpError(err: any, request: RequestObj) {
if (!environment.production) { 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()) // this.httpService.getSubscriptionQueue().map(a => a.unsubscribe())
} }
public httpException(response: Response<any>, request: RequestObj) { public httpException(response: Response<any>, request: RequestObj) {
if (!environment.production) if (!environment.production) {
console.log('exception=>', response, request) console.log('exception=>', response, request);
if (response.code === -1 && response.msg === '重复请求') return }
if (this.componentStateService.currentPath === this.ADMIN_PAGE_PREFIX) { if (response.code === -1 && response.msg === '重复请求') {
return;
}
if (this.componentStateService.currentPath === this.adminPagePrefix) {
this.notification.create('error', `请求失败<${response.code}>`, `${response.msg}`); 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(); this.localStorageService.removeToken();
} }
} }
public checkConnection() { public checkConnection() {
// The HTTP_ERROR_COUNT is start with 1 in this function // The HTTP_ERROR_COUNT is start with 1 in this function
if (ErrorService.HTTP_ERROR_COUNT === 1) { if (ErrorService.httpErrorCount === 1) {
const req: RequestObj = { const req: RequestObj = {
path: '/headerInfo', path: '/headerInfo',
method: 'GET', method: 'GET',
url: environment.host + '/headerInfo' url: environment.host + '/headerInfo'
} };
this.injector.get(HttpService).get(req).subscribe({ this.injector.get(HttpService).get(req).subscribe({
next: () => null, next: () => null,
error: () => { error: () => {
if (this.componentStateService.currentPath !== this.MAINTAIN_PAGE_PREFIX) { if (this.componentStateService.currentPath !== this.maintainPagePrefix) {
this.router.navigateByUrl(this.MAINTAIN_PAGE_PREFIX) 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 { export class GlobalUserService {
constructor(private apiService: ApiService,
private localStorageService: LocalStorageService) {
}
private lastRequestTime: number; private lastRequestTime: number;
private userInfo: User = null; private userInfo: User = null;
@@ -21,26 +17,29 @@ export class GlobalUserService {
private userObserverArray: Observer<Response<User>>[] = []; private userObserverArray: Observer<Response<User>>[] = [];
private multicastArray: Observer<Response<User>>[] = []; private multicastArray: Observer<Response<User>>[] = [];
constructor(private apiService: ApiService,
private localStorageService: LocalStorageService) {
}
watchUserInfo(observer: Observer<Response<User>>) { 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]; this.multicastArray = [...this.userObserverArray];
let subscription: Subscription = null; let subscription: Subscription = null;
const unsubscribe = () => { const unsubscribe = () => {
this.userObserverArray.splice(this.userObserverArray.indexOf(observer), 1); this.userObserverArray.splice(this.userObserverArray.indexOf(observer), 1);
observer.complete(); observer.complete();
if (subscription) subscription.unsubscribe(); if (subscription) {subscription.unsubscribe();}
}; };
if (this.lastRequestTime && Date.now() - this.lastRequestTime < 3000) { if (this.lastRequestTime && Date.now() - this.lastRequestTime < 3000) {
if (this.userInfo && this.multicastArray.length) { if (this.userInfo && this.multicastArray.length) {
this.broadcast() this.broadcast();
this.lastRequestTime = Date.now(); this.lastRequestTime = Date.now();
} }
return {unsubscribe} return {unsubscribe};
} }
// 获取数据 // 获取数据
subscription = this.getUserInfoFromServer(); subscription = this.getUserInfoFromServer();
return {unsubscribe} return {unsubscribe};
} }
// 刷新用户信息 // 刷新用户信息
@@ -59,7 +58,7 @@ export class GlobalUserService {
// this.localStorageService.setUser(o.result); // this.localStorageService.setUser(o.result);
// this.userObserver.next(o); // this.userObserver.next(o);
this.userInfo = o.result; this.userInfo = o.result;
this.broadcast() this.broadcast();
observer.next(o); observer.next(o);
observer.complete(); observer.complete();
}, },
@@ -82,7 +81,7 @@ export class GlobalUserService {
// 如果不需要返回消息也ok // 如果不需要返回消息也ok
this.apiService.logout().subscribe(data => { this.apiService.logout().subscribe(data => {
this.localStorageService.clear(); this.localStorageService.clear();
this.broadcast() this.broadcast();
if (observer) { if (observer) {
observer.next(data); observer.next(data);
observer.complete(); observer.complete();
@@ -93,7 +92,7 @@ export class GlobalUserService {
observer.error(error); observer.error(error);
observer.complete(); observer.complete();
} }
}) });
} }
getUserInfoFromServer(observer?: Observer<Response<User>>) { getUserInfoFromServer(observer?: Observer<Response<User>>) {
@@ -102,7 +101,7 @@ export class GlobalUserService {
this.lastRequestTime = Date.now(); this.lastRequestTime = Date.now();
this.userInfo = o.result; this.userInfo = o.result;
// this.localStorageService.setUser(o.result); // this.localStorageService.setUser(o.result);
this.broadcast() this.broadcast();
if (observer) { if (observer) {
observer.next(o); observer.next(o);
observer.complete(); observer.complete();
@@ -118,12 +117,12 @@ export class GlobalUserService {
if (err.code === -1) { if (err.code === -1) {
// 请求重复 // 请求重复
return return;
} }
// this.requested = false; // this.requested = false;
// this.localStorageService.removeToken(); // this.localStorageService.removeToken();
this.multicastArray.forEach(ob => ob.next(new Response<User>(this.userInfo))) this.multicastArray.forEach(ob => ob.next(new Response<User>(this.userInfo)));
this.multicastArray.forEach(ob => ob.error(err)) this.multicastArray.forEach(ob => ob.error(err));
this.multicastArray.splice(0, this.multicastArray.length); this.multicastArray.splice(0, this.multicastArray.length);
} }
@@ -131,7 +130,7 @@ export class GlobalUserService {
} }
private broadcast() { 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); this.multicastArray.splice(0, this.multicastArray.length);
} }
} }

View File

@@ -1,34 +1,65 @@
import {Injectable} from '@angular/core'; import {Injectable} from '@angular/core';
import {User} from '../class/User'; import {Base64} from 'js-base64';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class LocalStorageService { export class LocalStorageService {
readonly place = 30 * 1000;
constructor() { constructor() {
} }
// 30s // 30s
readonly place = 30 * 1000;
getToken(): string { getToken(): string {
return localStorage.getItem('token'); const item = this.getItem('token');
if (!item) {
return null;
}
return 'Bearer ' + item;
} }
setToken(token: string) { setToken(token: string) {
localStorage.setItem('t', new Date().valueOf().toString()); const t = new Date().valueOf().toString();
localStorage.setItem('token', token); 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() { removeToken() {
localStorage.removeItem('token'); this.removeItem('token');
} }
isLogin() { isLogin() {
return this.getToken() != null; 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) { // setUser(user: User) {
// // TODO: 简单加个密 // // TODO: 简单加个密
// localStorage.setItem('t', new Date().valueOf().toString()); // localStorage.setItem('t', new Date().valueOf().toString());

View File

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

View File

@@ -3,6 +3,7 @@ import {PageList} from '../class/HttpReqAndResp';
/** /**
* 判断 一个Page<any>[] 中是否存在一条已查询的数据 * 判断 一个Page<any>[] 中是否存在一条已查询的数据
*
* @param pageNum 页码 * @param pageNum 页码
* @param pageSize 单页数量 * @param pageSize 单页数量
* @param pageList 源数据 * @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) { if (pageList === undefined || pageList == null || pageList.length === 0) {
return null; 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++) { 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) { if (pageList[i].pageNum == pageNum && pageList[i].pageSize == pageSize) {
const ob: Observable<PageList<T>> = new Observable(o => { const ob: Observable<PageList<T>> = new Observable(o => {
o.next(pageList[i]); o.next(pageList[i]);
o.complete(); o.complete();
}) });
} }
} }
return null; return null;

View File

@@ -1,11 +1,12 @@
export class SvgIconUtil { 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() { 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,5 +1,4 @@
<common-table cardTitle="文章管理" <common-table #commonTableComponent
#commonTableComponent
[headData]="headData" [headData]="headData"
[request]="request" [request]="request"
[template]="{ [template]="{
@@ -8,25 +7,26 @@
likeCount:{temp:likeCount}, likeCount:{temp:likeCount},
dislikeCount:{temp:dislikeCount}, dislikeCount:{temp:dislikeCount},
open:{temp:open} open:{temp:open}
}"> }"
cardTitle="文章管理">
</common-table> </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> <nz-tag [nzColor]="originValue?'green':'#ff5500'">{{value}}</nz-tag>
</ng-template> </ng-template>
<ng-template let-value="value" #readingNumber> <ng-template #readingNumber let-value="value">
<nz-tag nzColor="purple">{{value}}</nz-tag> <nz-tag nzColor="purple">{{value}}</nz-tag>
</ng-template> </ng-template>
<ng-template let-value="value" #likeCount> <ng-template #likeCount let-value="value">
<nz-tag nzColor="blue">{{value}}</nz-tag> <nz-tag nzColor="blue">{{value}}</nz-tag>
</ng-template> </ng-template>
<ng-template let-value="value" #dislikeCount> <ng-template #dislikeCount let-value="value">
<nz-tag nzColor="magenta">{{value}}</nz-tag> <nz-tag nzColor="magenta">{{value}}</nz-tag>
</ng-template> </ng-template>
<ng-template #open let-value="value"> <ng-template #open let-value="value">
<label nz-checkbox nzDisabled [ngModel]="value"></label> <label [ngModel]="value" nz-checkbox nzDisabled></label>
</ng-template> </ng-template>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,8 +2,8 @@ import {Component, OnInit, ViewChild} from '@angular/core';
import {RequestObj, Response} from '../../../class/HttpReqAndResp'; import {RequestObj, Response} from '../../../class/HttpReqAndResp';
import {Link} from '../../../class/Link'; import {Link} from '../../../class/Link';
import {ApiService} from '../../../api/api.service'; import {ApiService} from '../../../api/api.service';
import {NzMessageService} from 'ng-zorro-antd'; import {NzMessageService} from 'ng-zorro-antd/message';
import {FormControl, FormGroup, Validators} from '@angular/forms'; import {UntypedFormControl, UntypedFormGroup, Validators} from '@angular/forms';
import {Observable} from 'rxjs'; import {Observable} from 'rxjs';
import {Title} from '@angular/platform-browser'; import {Title} from '@angular/platform-browser';
import {CommonTableComponent} from '../components/common-table/common-table.component'; 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 { export class AdminLinkComponent implements OnInit {
constructor(private apiService: ApiService, private messageService: NzMessageService, private title: Title) { @ViewChild('commonTableComponent') commonTableComponent: CommonTableComponent<Link>;
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)
})
}
modalVisible: boolean = false; modalVisible: boolean = false;
modalTitle: string = ''; modalTitle: string = '';
formGroup: FormGroup; formGroup: UntypedFormGroup;
request: RequestObj; request: RequestObj;
@ViewChild('commonTableComponent') commonTableComponent: CommonTableComponent<Link>
headData: Data<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 { ngOnInit(): void {
this.request = { this.request = {
path: '/admin/links', path: '/admin/links',
@@ -44,7 +50,7 @@ export class AdminLinkComponent implements OnInit {
count: 10, count: 10,
page: 1 page: 1
} }
} };
this.headData = [ this.headData = [
{title: '主键', fieldValue: 'id', show: false, primaryKey: true}, {title: '主键', fieldValue: 'id', show: false, primaryKey: true},
{title: '友链名称', fieldValue: 'name', show: true}, {title: '友链名称', fieldValue: 'name', show: true},
@@ -73,19 +79,19 @@ export class AdminLinkComponent implements OnInit {
this.messageService.error('删除失败'); this.messageService.error('删除失败');
}, },
complete: () => null, complete: () => null,
}) });
} }
showEdit(data: Link) { showEdit(data: Link) {
this.modalVisible = true; this.modalVisible = true;
this.modalTitle = '编辑友链信息'; this.modalTitle = '编辑友链信息';
this.formGroup.patchValue(data); this.formGroup.patchValue(data);
this.formGroup.controls.oper.setValue('edit') this.formGroup.controls.oper.setValue('edit');
} }
modalConfirm() { modalConfirm() {
this.modalVisible = false; this.modalVisible = false;
const linkReq: Link = this.formGroup.value const linkReq: Link = this.formGroup.value;
const oper = this.formGroup.value.oper; const oper = this.formGroup.value.oper;
let observable: Observable<Response<Link>>; let observable: Observable<Response<Link>>;
if (oper === 'edit') { if (oper === 'edit') {
@@ -98,13 +104,13 @@ export class AdminLinkComponent implements OnInit {
next: data => this.messageService.success('操作成功'), next: data => this.messageService.success('操作成功'),
error: err => this.messageService.error('操作失败,' + err.msg), error: err => this.messageService.error('操作失败,' + err.msg),
complete: () => this.commonTableComponent.getData() complete: () => this.commonTableComponent.getData()
}) });
} }
addLink() { addLink() {
this.modalVisible = true; this.modalVisible = true;
this.modalTitle = '新增友链信息'; this.modalTitle = '新增友链信息';
this.formGroup.reset(); 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 {RouterModule} from '@angular/router';
import {AdminLinkComponent} from './admin-link.component'; import {AdminLinkComponent} from './admin-link.component';
import {CommonTableModule} from '../components/common-table/common-table.module'; import {CommonTableModule} from '../components/common-table/common-table.module';
import { import {NzButtonModule} from 'ng-zorro-antd/button';
NzButtonModule, import {NzCheckboxModule} from 'ng-zorro-antd/checkbox';
NzCheckboxModule, import {NzFormModule} from 'ng-zorro-antd/form';
NzFormModule, import {NzInputModule} from 'ng-zorro-antd/input';
NzInputModule, import {NzModalModule} from 'ng-zorro-antd/modal';
NzModalModule, import {NzSelectModule} from 'ng-zorro-antd/select';
NzSelectModule, import {NzTagModule} from 'ng-zorro-antd/tag';
NzTagModule
} from 'ng-zorro-antd';
import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {FormsModule, ReactiveFormsModule} from '@angular/forms';

View File

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

View File

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

View File

@@ -5,7 +5,10 @@ import {AdminTagComponent} from './admin-tag.component';
import {FormsModule} from '@angular/forms'; import {FormsModule} from '@angular/forms';
import {CommonTableModule} from '../components/common-table/common-table.module'; import {CommonTableModule} from '../components/common-table/common-table.module';
import {EditableTagModule} from '../components/editable-tag/editable-tag.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({ @NgModule({

View File

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

View File

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

View File

@@ -5,7 +5,9 @@ import {AdminUpdateComponent} from './admin-update.component';
import {FormsModule} from '@angular/forms'; import {FormsModule} from '@angular/forms';
import {CommonTableModule} from '../components/common-table/common-table.module'; 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({ @NgModule({

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,7 @@
import {Component, OnInit} from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {AbstractControl, FormControl, FormGroup, Validators} from '@angular/forms'; import {AbstractControl, UntypedFormControl, UntypedFormGroup, Validators} from '@angular/forms';
import {NzMessageService, UploadFile} from 'ng-zorro-antd'; import {NzMessageService} from 'ng-zorro-antd/message';
import {NzUploadFile} from 'ng-zorro-antd/upload';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
import {GlobalUserService} from '../../services/global-user.service'; import {GlobalUserService} from '../../services/global-user.service';
import {User} from '../../class/User'; import {User} from '../../class/User';
@@ -16,83 +17,62 @@ import {LocalStorageService} from '../../services/local-storage.service';
}) })
export class AdminComponent implements OnInit { 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; user: User;
isCollapsed: boolean = false; isCollapsed: boolean = false;
infoDrawerVisible: boolean = false; infoDrawerVisible: boolean = false;
sayHelloContent: string; sayHelloContent: string;
editInfoModalVisible: boolean = false; editInfoModalVisible: boolean = false;
resetPwdModalVisible: boolean = false; resetPwdModalVisible: boolean = false;
editInfoFormGroup: FormGroup; editInfoFormGroup: UntypedFormGroup;
resetPwdFormGroup: FormGroup; resetPwdFormGroup: UntypedFormGroup;
noAvatarUrl = 'https://cdn.celess.cn/' noAvatarUrl = 'https://cdn.celess.cn/';
host: string 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; showInfoDrawer = () => this.infoDrawerVisible = !this.infoDrawerVisible;
logout() { logout() {
this.gUserService.logout(); this.gUserService.logout();
this.router.navigateByUrl('/') this.router.navigateByUrl('/');
} }
ngOnInit(): void { ngOnInit(): void {
this.host = environment.host; this.host = environment.host;
} }
checkSamePwd = () => { checkSamePwd = () => (control: AbstractControl): { [key: string]: any } | null => {
return (control: AbstractControl): { [key: string]: any } | null => {
console.log('a')
const newPwd = this.resetPwdFormGroup && this.resetPwdFormGroup.value.newPwd; const newPwd = this.resetPwdFormGroup && this.resetPwdFormGroup.value.newPwd;
return control.value !== newPwd ? {pwdNotSame: true} : null; return control.value !== newPwd ? {pwdNotSame: true} : null;
}; };
} // eslint-disable-next-line @typescript-eslint/naming-convention
uploadHeader = (file: UploadFile): object | Observable<{}> => { uploadHeader = (file: NzUploadFile): any | Observable<{}> => ({Authorization: this.localStorageService.getToken()});
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}`
}
}
showEditInfoModal() { showEditInfoModal() {
this.editInfoModalVisible = true; this.editInfoModalVisible = true;
@@ -105,7 +85,7 @@ export class AdminComponent implements OnInit {
const displayName = this.editInfoFormGroup.value.displayName; const displayName = this.editInfoFormGroup.value.displayName;
this.apiService.updateUserInfo(desc, displayName).subscribe({ this.apiService.updateUserInfo(desc, displayName).subscribe({
next: data => { next: data => {
this.messageService.success('修改信息成功') this.messageService.success('修改信息成功');
this.gUserService.refreshUserInfo(); this.gUserService.refreshUserInfo();
}, },
error: err => { error: err => {
@@ -128,13 +108,13 @@ export class AdminComponent implements OnInit {
error: err => { error: err => {
this.messageService.error('修改密码失败,' + err.msg); this.messageService.error('修改密码失败,' + err.msg);
} }
}) });
this.resetPwdModalVisible = false; this.resetPwdModalVisible = false;
} }
showResetPwdModal() { showResetPwdModal() {
this.resetPwdModalVisible = true; this.resetPwdModalVisible = true;
this.infoDrawerVisible = false this.infoDrawerVisible = false;
} }
avatarUpload(info: any) { avatarUpload(info: any) {
@@ -143,4 +123,21 @@ export class AdminComponent implements OnInit {
this.gUserService.refreshUserInfo(); 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 {CommonModule} from '@angular/common';
import {AdminRoutingModule} from './admin-routing.module'; import {AdminRoutingModule} from './admin-routing.module';
import {AdminComponent} from './admin.component'; import {AdminComponent} from './admin.component';
import {NgZorroAntdModule} from 'ng-zorro-antd';
import {NzSpaceModule} from 'ng-zorro-antd/space'; import {NzSpaceModule} from 'ng-zorro-antd/space';
import {AdminHeaderComponent} from '../../components/admin-header/admin-header.component'; import {AdminHeaderComponent} from '../../components/admin-header/admin-header.component';
import {ReactiveFormsModule} from '@angular/forms'; import {ReactiveFormsModule} from '@angular/forms';
import {AuthGuard} from './auth.guard'; 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({ @NgModule({
declarations: [ declarations: [
@@ -17,9 +30,23 @@ import {AuthGuard} from './auth.guard';
imports: [ imports: [
CommonModule, CommonModule,
AdminRoutingModule, AdminRoutingModule,
NgZorroAntdModule,
NzSpaceModule, NzSpaceModule,
ReactiveFormsModule, ReactiveFormsModule,
NzAvatarModule,
NzButtonModule,
NzLayoutModule,
NzMenuModule,
NzIconModule,
NzCardModule,
NzDividerModule,
NzUploadModule,
NzToolTipModule,
NzTypographyModule,
NzModalModule,
NzFormModule,
NzInputModule,
NzDescriptionsModule,
NzDrawerModule
], ],
providers: [AuthGuard] providers: [AuthGuard]
}) })

View File

@@ -1,12 +1,5 @@
import {Injectable} from '@angular/core'; import {Injectable} from '@angular/core';
import { import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot} from '@angular/router';
CanActivate,
ActivatedRouteSnapshot,
RouterStateSnapshot,
UrlTree,
Router,
CanActivateChild
} from '@angular/router';
import {Observable, Observer} from 'rxjs'; import {Observable, Observer} from 'rxjs';
import {User} from '../../class/User'; import {User} from '../../class/User';
import {GlobalUserService} from '../../services/global-user.service'; import {GlobalUserService} from '../../services/global-user.service';
@@ -16,15 +9,15 @@ import {GlobalUserService} from '../../services/global-user.service';
}) })
export class AuthGuard implements CanActivate { export class AuthGuard implements CanActivate {
constructor(private userService: GlobalUserService, private router: Router) {
}
userInfo: User; userInfo: User;
visitCount: number = 0; // 记录一共走过几次canActivate visitCount: number = 0; // 记录一共走过几次canActivate
private path: string; private path: string;
private readonly loginPath: string = '/user/login'; private readonly loginPath: string = '/user/login';
private observable: Observable<boolean>; private observable: Observable<boolean>;
constructor(private userService: GlobalUserService, private router: Router) {
}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> { canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
this.path = state.url.indexOf('?') > 0 ? state.url.substr(0, state.url.indexOf('?')) : state.url; this.path = state.url.indexOf('?') > 0 ? state.url.substr(0, state.url.indexOf('?')) : state.url;
this.visitCount++; this.visitCount++;
@@ -53,7 +46,7 @@ export class AuthGuard implements CanActivate {
this.userInfo = data.result; this.userInfo = data.result;
this.checkPath(observer); this.checkPath(observer);
} }
}) });
} }
@@ -67,7 +60,7 @@ export class AuthGuard implements CanActivate {
case '/admin/visitor': case '/admin/visitor':
if (this.userInfo && this.userInfo.role !== 'admin') { if (this.userInfo && this.userInfo.role !== 'admin') {
observer.next(false); observer.next(false);
if (this.visitCount === 1) this.router.navigateByUrl('/admin') if (this.visitCount === 1) {this.router.navigateByUrl('/admin');}
observer.complete(); observer.complete();
return; 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> <ng-container *ngTemplateOutlet="table"></ng-container>
</nz-card> </nz-card>
<ng-container [ngTemplateOutlet]="table" *ngIf="!cardTitle"></ng-container> <ng-container *ngIf="!cardTitle" [ngTemplateOutlet]="table"></ng-container>
<ng-template #extra> <ng-template #extra>
<i nz-icon nzType="setting" nzTheme="outline" title="设置" (click)="showFieldSetting()" <i (click)="showFieldSetting()" nz-icon nzTheme="outline" nzType="setting" style="cursor: pointer;margin-right: 10px"
style="cursor: pointer;margin-right: 10px"></i> title="设置"></i>
<i nz-icon nzType="reload" nzTheme="outline" (click)="getData()" title="刷新" style="cursor: pointer"></i> <i (click)="getData()" nz-icon nzTheme="outline" nzType="reload" style="cursor: pointer" title="刷新"></i>
</ng-template> </ng-template>
<ng-template #table> <ng-template #table>
<ng-content></ng-content> <ng-content></ng-content>
<nz-table nzTableLayout="fixed" <nz-table (nzPageIndexChange)="getData($event)"
[nzData]="dataList.list"
[nzTotal]="dataList.total"
[(nzPageIndex)]="dataList.pageNum" [(nzPageIndex)]="dataList.pageNum"
[nzData]="dataList.list"
[nzLoading]="loading"
[nzPageSize]="dataList.pageSize" [nzPageSize]="dataList.pageSize"
(nzPageIndexChange)="getData()"
nzFrontPagination="false"
[nzScroll]="{x:visibleFieldLength*100+'px'}" [nzScroll]="{x:visibleFieldLength*100+'px'}"
[nzLoading]="loading"> [nzTotal]="dataList.total"
nzFrontPagination="false"
nzTableLayout="fixed">
<thead> <thead>
<tr> <tr>
<ng-container *ngFor="let data of filedData"> <ng-container *ngFor="let data of filedData">
@@ -34,12 +34,12 @@
<tr *ngFor="let t of dataList.list;let index = index"> <tr *ngFor="let t of dataList.list;let index = index">
<ng-container *ngFor="let data of filedData"> <ng-container *ngFor="let data of filedData">
<td *ngIf="data.show" <td *ngIf="data.show"
nz-typography
nzEllipsis
[nzEllipsisRows]="data.isActionColumns?3:1" [nzEllipsisRows]="data.isActionColumns?3:1"
[nzTooltipTitle]="data.isActionColumns ? null : data.title+' : '+getValue(index,data.fieldValue)" [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]="!data.isActionColumns">
<ng-template [ngIf]="template[data.fieldValue]"> <ng-template [ngIf]="template[data.fieldValue]">
<ng-container <ng-container
@@ -51,15 +51,15 @@
</ng-template> </ng-template>
</ng-template> </ng-template>
<ng-container *ngIf="data.isActionColumns"> <ng-container *ngIf="data.isActionColumns">
<a *ngFor="let action of data.action; let i = index" <a (mouseenter)="action.hover(t)"
(mouseenter)="action.hover(t)"
(mouseout)="null" (mouseout)="null"
[ngStyle]="{'color':action.color,'font-size':action.fontSize}"
nz-popconfirm
[nzPopconfirmTitle]="'是否确认'+action.name+'该数据?'"
[nzCondition]="!action.needConfirm"
(nzOnConfirm)="action.click(t)" (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}} {{action.name}}
<ng-template [ngIf]="i!=data.action.length-1"> <ng-template [ngIf]="i!=data.action.length-1">
<nz-divider nzType="vertical"></nz-divider> <nz-divider nzType="vertical"></nz-divider>
@@ -74,17 +74,17 @@
</ng-template> </ng-template>
<nz-modal [(nzVisible)]="settingModalVisible" <nz-modal (nzOnCancel)="cancel()"
[nzClosable]="true"
(nzOnCancel)="cancel()"
(nzOnOk)="ok()" (nzOnOk)="ok()"
[(nzVisible)]="settingModalVisible"
[nzClosable]="true"
nzTitle="表格字段设置(可拖动排序)" nzTitle="表格字段设置(可拖动排序)"
> >
<button nz-button nzType="primary" (click)="reset()" [disabled]="!changed">重置</button> <button (click)="reset()" [disabled]="!changed" nz-button nzType="primary">重置</button>
<nz-table [nzData]="filedData" nzSize="small" nzPageSize="10000" nzShowPagination="false"> <nz-table [nzData]="filedData" nzPageSize="10000" nzShowPagination="false" nzSize="small">
<tbody cdkDropList (cdkDropListDropped)="drop($event)"> <tbody (cdkDropListDropped)="drop($event)" cdkDropList>
<ng-template ngFor [ngForOf]="filedData" let-item let-index="index"> <ng-template [ngForOf]="filedData" let-index="index" let-item ngFor>
<tr *ngIf="!item.isActionColumns" cdkDrag (click)="click()"> <tr (click)="click()" *ngIf="!item.isActionColumns" cdkDrag>
<td>{{index + 1}}</td> <td>{{index + 1}}</td>
<td style="text-align: center">{{item.title}}</td> <td style="text-align: center">{{item.title}}</td>
<td style="text-align: center">{{item.fieldValue}}</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 {PageList, RequestObj} from '../../../../class/HttpReqAndResp';
import {HttpService} from '../../../../api/http/http.service'; import {HttpService} from '../../../../api/http/http.service';
import {CdkDragDrop, moveItemInArray} from '@angular/cdk/drag-drop'; import {CdkDragDrop, moveItemInArray} from '@angular/cdk/drag-drop';
import {LocalStorageService} from '../../../../services/local-storage.service';
@Component({ @Component({
selector: 'common-table', selector: 'common-table',
@@ -11,72 +12,79 @@ import {CdkDragDrop, moveItemInArray} from '@angular/cdk/drag-drop';
}) })
export class CommonTableComponent<T> implements OnInit, OnChanges { export class CommonTableComponent<T> implements OnInit, OnChanges {
constructor(private httpService: HttpService) { @Output() pageInfo = new EventEmitter<{ page: number; pageSize: number }>();
}
@Input() private headData: Data<T>[];
@Input() request: RequestObj;
@Input() cardTitle: string | null; @Input() cardTitle: string | null;
@Input() template: { @Input() template: {
[fieldValue: string]: { [fieldValue: string]: {
temp: TemplateRef<any>, temp: TemplateRef<any>;
param?: { [key: string]: string } param?: { [key: string]: string };
}
}; };
@Output() pageInfo = new EventEmitter<{ page: number, pageSize: number }>(); };
@Input() request: RequestObj;
@Input() private headData: Data<T>[];
loading: boolean = true; loading: boolean = true;
dataList: PageList<T> = new PageList<T>(); dataList: PageList<T> = new PageList<T>();
settingModalVisible: boolean = false; settingModalVisible: boolean = false;
filedData: Data<T>[]; filedData: Data<T>[];
changed: boolean = false; changed: boolean = false;
visibleFieldLength: number = 0; visibleFieldLength: number = 0;
constructor(private httpService: HttpService,
private localStorageService: LocalStorageService) {
}
ngOnInit(): void { ngOnInit(): void {
if (localStorage.getItem(this.request.path)) { if (this.localStorageService.getItem(this.request.path)) {
this.filedData = this.cloneData(localStorage.getItem(this.request.path)); this.filedData = this.cloneData(this.localStorageService.getItem(this.request.path));
this.changed = true; this.changed = true;
} else { } else {
this.filedData = this.cloneData(this.headData) this.filedData = this.cloneData(this.headData);
console.log(this.filedData)
} }
this.calculateVisibleFieldLength(); this.calculateVisibleFieldLength();
if (!this.template) this.template = {} if (!this.template) {
this.template = {};
}
this.headData.forEach(dat => { this.headData.forEach(dat => {
if (!dat.action) return; if (!dat.action) {
return;
}
dat.action.forEach(act => { dat.action.forEach(act => {
if (!act.hover) { if (!act.hover) {
act.hover = () => null; act.hover = () => null;
} }
})
}); });
if (!this.request || !this.request.path) return });
if (!this.request || !this.request.path) {
return;
}
this.getData(); this.getData();
} }
getData = () => { getData = (pageNumber?: number) => {
this.loading = true; this.loading = true;
const pageValue = this.dataList.pageNum ? this.dataList.pageNum : 1; const pageValue = pageNumber ? pageNumber : 1;
const countValue = this.dataList.pageSize ? this.dataList.pageSize : 10 const countValue = this.dataList.pageSize ? this.dataList.pageSize : 10;
this.request.queryParam = {
page: pageValue, this.request.queryParam.page = pageValue;
count: countValue this.request.queryParam.count = countValue;
} // this.request.queryParam = {
this.pageInfo.emit({page: pageValue, pageSize: countValue}) // page: pageValue,
return this.httpService.Service<PageList<T>>(this.request).subscribe({ // count: countValue
// }
this.pageInfo.emit({page: pageValue, pageSize: countValue});
return this.httpService.service<PageList<T>>(this.request).subscribe({
next: resp => { next: resp => {
this.dataList = resp.result; this.dataList = resp.result;
setTimeout(() => this.loading = false, 10) setTimeout(() => this.loading = false, 10);
}, },
error: err => this.loading = false error: err => this.loading = false
}); });
} };
ngOnChanges(changes: SimpleChanges): void { ngOnChanges(changes: SimpleChanges): void {
if (changes.request && !changes.request.isFirstChange()) { if (changes.request && !changes.request.isFirstChange()) {
console.log(changes.request)
this.request = changes.request.currentValue; this.request = changes.request.currentValue;
this.getData().unsubscribe(); this.getData().unsubscribe();
this.getData(); this.getData();
@@ -87,7 +95,9 @@ export class CommonTableComponent<T> implements OnInit, OnChanges {
getValue(index: number, fieldValue: string): string { getValue(index: number, fieldValue: string): string {
let value = this.dataList.list[index]; let value = this.dataList.list[index];
try { try {
for (const key of fieldValue.split('.')) value = value[key] for (const key of fieldValue.split('.')) {
value = value[key];
}
} catch (e) { } catch (e) {
// ignore // ignore
} }
@@ -96,35 +106,35 @@ export class CommonTableComponent<T> implements OnInit, OnChanges {
getContext = (fieldValue: string, index: number) => { getContext = (fieldValue: string, index: number) => {
const valueData = this.getValue(index, fieldValue); 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) { if (this.template[fieldValue].param) {
context = { context = {
value: this.template[fieldValue].param[valueData], value: this.template[fieldValue].param[valueData],
originValue: valueData, originValue: valueData,
data: this.dataList.list[index] data: this.dataList.list[index]
} };
} else { } else {
context = { context = {
value: valueData, value: valueData,
data: this.dataList.list[index] data: this.dataList.list[index]
} };
} }
return context; return context;
} };
showFieldSetting = () => this.settingModalVisible = true; showFieldSetting = () => this.settingModalVisible = true;
cancel = () => this.settingModalVisible = false; cancel = () => this.settingModalVisible = false;
calculateVisibleFieldLength = () => this.filedData.filter(value => value.show).length; calculateVisibleFieldLength = () => this.visibleFieldLength = this.filedData.filter(value => value.show).length;
ok() { ok() {
this.calculateVisibleFieldLength(); this.calculateVisibleFieldLength();
this.settingModalVisible = !this.settingModalVisible; this.settingModalVisible = !this.settingModalVisible;
if (!this.changed) { if (!this.changed) {
return return;
} }
this.dataList = JSON.parse(JSON.stringify(this.dataList)); 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; this.changed = true;
} }
@@ -134,11 +144,11 @@ export class CommonTableComponent<T> implements OnInit, OnChanges {
} }
reset = () => { reset = () => {
localStorage.removeItem(this.request.path); this.localStorageService.removeItem(this.request.path);
this.filedData = this.cloneData(this.headData); this.filedData = this.cloneData(this.headData);
this.changed = false; this.changed = false;
this.calculateVisibleFieldLength(); this.calculateVisibleFieldLength();
} };
cloneData = (source: Data<T>[] | string): Data<T>[] => { cloneData = (source: Data<T>[] | string): Data<T>[] => {
let dist: Data<T>[]; let dist: Data<T>[];
@@ -148,11 +158,14 @@ export class CommonTableComponent<T> implements OnInit, OnChanges {
dist = JSON.parse(JSON.stringify(source)); dist = JSON.parse(JSON.stringify(source));
} }
const action = this.headData.filter(value => value.isActionColumns).pop(); 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.splice(dist.indexOf(del), 1);
dist.push(action); dist.push(action);
return dist; return dist;
} };
/** /**
* 字段编辑项被点击 * 字段编辑项被点击
@@ -166,5 +179,5 @@ export class CommonTableComponent<T> implements OnInit, OnChanges {
this.changed = true; this.changed = true;
} }
} }
} };
} }

View File

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

View File

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

View File

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

View File

@@ -1,7 +1,9 @@
import {NgModule} from '@angular/core'; import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {EditableTagComponent} from './editable-tag.component'; 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'; import {FormsModule} from '@angular/forms';

View File

@@ -14,15 +14,15 @@
<nz-tag [nzColor]="'#f50'">{{value}}</nz-tag> <nz-tag [nzColor]="'#f50'">{{value}}</nz-tag>
</ng-template> </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> <nz-tag [nzColor]="originValue?'#87d068':'#f50'">{{value}}</nz-tag>
</ng-template> </ng-template>
<ng-template #open let-value="value"> <ng-template #open let-value="value">
<label nz-checkbox nzDisabled [ngModel]="value"></label> <label [ngModel]="value" nz-checkbox nzDisabled></label>
</ng-template> </ng-template>
<editable-tag color="green">hhh</editable-tag> <editable-tag color="green">hhh</editable-tag>
<editable-tag color="green" [showEditIcon]="false">hhh</editable-tag> <editable-tag [showEditIcon]="false" color="green">hhh</editable-tag>
<editable-tag color="green" [showBorder]="false">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 {Data} from '../components/common-table/data';
import {Article} from '../../../class/Article'; import {Article} from '../../../class/Article';
import {RequestObj} from '../../../class/HttpReqAndResp'; import {RequestObj} from '../../../class/HttpReqAndResp';
@@ -24,8 +24,12 @@ summary: a
tags: [{id: 26, name: "脚本"}, {id: 27, name: "网课"}] tags: [{id: 26, name: "脚本"}, {id: 27, name: "网课"}]
title: "教你动手写一个刷课脚本" title: "教你动手写一个刷课脚本"
updateDateFormat: "2020-05-27 00:55:05"*/ updateDateFormat: "2020-05-27 00:55:05"*/
// @ViewChild('tag') tagTemp: TemplateRef<any>; // @ViewChild('tag') tagTemp: TemplateRef<any>;
data: Data<Article>[];
req: RequestObj;
constructor() { constructor() {
this.data = [ this.data = [
{title: '主键', fieldValue: 'id', show: false, primaryKey: true}, {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 { ngOnInit(): void {
this.req = { this.req = {
path: '/admin/articles', path: '/admin/articles',
@@ -72,7 +73,7 @@ updateDateFormat: "2020-05-27 00:55:05"*/
page: 1, page: 1,
count: 10 count: 10
} }
} };
} }
} }

View File

@@ -1,9 +1,10 @@
import {NgModule} from '@angular/core'; import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {TestCommonTableComponent} from './test-common-table.component'; 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 {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 {FormsModule} from '@angular/forms';
import {EditableTagModule} from '../components/editable-tag/editable-tag.module'; import {EditableTagModule} from '../components/editable-tag/editable-tag.module';

View File

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

View File

@@ -102,6 +102,7 @@ nz-content {
.article-bAnda { .article-bAnda {
height: 70px; height: 70px;
max-height: 110px; max-height: 110px;
a { a {
display: block; display: block;
} }

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 {ActivatedRoute, Router} from '@angular/router';
import {ApiService} from '../../api/api.service'; import {ApiService} from '../../api/api.service';
import {Article} from '../../class/Article'; import {Article} from '../../class/Article';
import {Title} from '@angular/platform-browser'; import {Title} from '@angular/platform-browser';
import {User} from '../../class/User'; import {User} from '../../class/User';
import {CommentReq} from '../../class/Comment'; import {Comment, CommentReq} from '../../class/Comment';
import {PageList} from '../../class/HttpReqAndResp'; import {PageList} from '../../class/HttpReqAndResp';
import {Comment} from '../../class/Comment';
import {GlobalUserService} from '../../services/global-user.service'; import {GlobalUserService} from '../../services/global-user.service';
import VditorPreview from 'vditor/dist/method.min';
declare var editormd; declare let $;
declare var $;
@Component({ @Component({
selector: 'view-article', selector: 'view-article',
@@ -19,6 +18,20 @@ declare var $;
}) })
export class ArticleComponent implements OnInit { 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, constructor(private activatedRoute: ActivatedRoute,
private apiService: ApiService, private apiService: ApiService,
private userService: GlobalUserService, private userService: GlobalUserService,
@@ -27,19 +40,7 @@ export class ArticleComponent implements OnInit {
this.articleId = +activatedRoute.snapshot.paramMap.get('id'); this.articleId = +activatedRoute.snapshot.paramMap.get('id');
} }
articleId: number; // private vditor: Vditor;
article: Article;
copyRightUrl: string;
user: User;
submitting: boolean = false;
comment: CommentReq;
// 作为输入框@ 的提示
name: string;
commentPage: PageList<Comment>;
avatarImgUrl: string;
pid: number;
content: string;
ngOnInit() { ngOnInit() {
this.toArticle(this.articleId); this.toArticle(this.articleId);
@@ -48,24 +49,37 @@ export class ArticleComponent implements OnInit {
error: (err) => null, error: (err) => null,
next: data => { next: data => {
this.user = data.result; 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}`); this.comment = new CommentReq(`article/${this.articleId}`);
} }
parseMd(md: string) { parseMd(md: string) {
editormd.markdownToHTML('article-content', { const option: IPreviewOptions = {
markdown: this.article.mdContent, anchor: 1,
htmlDecode: 'style,script,iframe', // you can filter tags decode hljs: {
toc: false, lineNumber: true
tocm: false, // Using [TOCM] },
// tocContainer: '#article-slider', // 自定义 ToC 容器层 markdown: {
// tocDropdown: true, autoSpace: true,
emoji: true, fixTermTypo: true,
taskList: true, chinesePunct: true,
flowChart: 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) { toArticle(id: number) {

View File

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

View File

@@ -3,9 +3,9 @@
<div id="category"> <div id="category">
<ul *ngIf="categoryList.length"> <ul *ngIf="categoryList.length">
<c-tag-tag *ngFor="let category of categoryList" <c-tag-tag (tagClick)="changeCategory(category)"
[tag]="{name:category.name,size:category.articles.length}" *ngFor="let category of categoryList"
(tagClick)="changeCategory(category)"> [tag]="{name:category.name,size:category.articles.length}">
</c-tag-tag> </c-tag-tag>
</ul> </ul>
@@ -16,7 +16,7 @@
<span style="font-weight: bolder;">{{name}}</span> <span style="font-weight: bolder;">{{name}}</span>
</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" <c-article-detail-card *ngFor="let article of articleList.list"
[data]="article" [showMediaArea]="false" [showTagArea]="false"> [data]="article" [showMediaArea]="false" [showTagArea]="false">
</c-article-detail-card> </c-article-detail-card>

View File

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

View File

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

View File

@@ -2,7 +2,8 @@ import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {CategoryComponent} from './category.component'; import {CategoryComponent} from './category.component';
import {CategoryRoutingModule} from './category-routing.module'; 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'; import {IndexModule} from '../index/index.module';

View File

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

View File

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

View File

@@ -2,7 +2,7 @@ import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {Route, RouterModule} from '@angular/router'; import {Route, RouterModule} from '@angular/router';
import {EmailVerifyComponent} from './email-verify.component'; import {EmailVerifyComponent} from './email-verify.component';
import {NzAlertModule} from 'ng-zorro-antd'; import {NzAlertModule} from 'ng-zorro-antd/alert';
const routes: Route[] = [ const routes: Route[] = [
{path: '**', component: EmailVerifyComponent} {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> <h1><a [routerLink]="'/article/'+data.id">{{data.title}}</a></h1>
<div> <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 ? '原创' : '转载'}} {{data.original ? '原创' : '转载'}}
</span> </span>
<span *ngIf="showMediaArea" class="badge"> <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>{{data.publishDateFormat}}</span>
</span> </span>
<span *ngIf="showMediaArea" class="badge"> <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>{{data.author.displayName}}</span>
</span> </span>
<span *ngIf="showMediaArea" class="badge"> <span *ngIf="showMediaArea" class="badge">
<i nz-icon nzType="file" nzTheme="outline"></i> <i nz-icon nzTheme="outline" nzType="file"></i>
<span> <span>
<a [routerLink]="'/categories/'+data.category">{{data.category}}</a> <a [routerLink]="'/categories/'+data.category">{{data.category}}</a>
</span> </span>
@@ -21,13 +21,13 @@
</div> </div>
<p>{{data.summary}}</p> <p>{{data.summary}}</p>
<span style="float: right;margin-bottom: 10px"> <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> </span>
<ng-template [ngIf]="showTagArea&&data.tags.length>0"> <ng-template [ngIf]="showTagArea&&data.tags.length>0">
<nz-divider></nz-divider> <nz-divider></nz-divider>
<div> <div>
<span *ngFor="let tag of data.tags"> <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> <a [routerLink]="'/tags/'+tag.name">{{tag.name}}</a>
</span> </span>
</div> </div>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,7 +1,8 @@
import {Component, OnInit} from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {ApiService} from '../../api/api.service'; import {ApiService} from '../../api/api.service';
import {Article} from '../../class/Article'; 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 {SvgIconUtil} from '../../utils/svgIconUtil';
import {PageList, RequestObj} from '../../class/HttpReqAndResp'; import {PageList, RequestObj} from '../../class/HttpReqAndResp';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
@@ -16,6 +17,30 @@ import {Title} from '@angular/platform-browser';
}) })
export class IndexComponent implements OnInit { 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, constructor(private apiService: ApiService,
private iconService: NzIconService, private iconService: NzIconService,
private nzMessageService: NzMessageService, private nzMessageService: NzMessageService,
@@ -25,31 +50,6 @@ export class IndexComponent implements OnInit {
title.setTitle('小海博客'); 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() { ngOnInit() {
this.imgUrl = this.logoImgUrl; this.imgUrl = this.logoImgUrl;
this.desc = '一个爱好瞎捣鼓的技术宅 :)\n欢迎一起来探讨学习。'; this.desc = '一个爱好瞎捣鼓的技术宅 :)\n欢迎一起来探讨学习。';

View File

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

View File

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

View File

@@ -174,6 +174,7 @@ i {
.partner-sites { .partner-sites {
padding: 0 30px; padding: 0 30px;
} }
.partner-sites li { .partner-sites li {
float: left; float: left;
width: 100%; width: 100%;

View File

@@ -1,10 +1,11 @@
import {Component, OnInit} from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {NzMessageService, NzModalService} from 'ng-zorro-antd'; import {NzMessageService} from 'ng-zorro-antd/message';
import {NzModalService} from 'ng-zorro-antd/modal';
import {Title} from '@angular/platform-browser'; import {Title} from '@angular/platform-browser';
import {ApiService} from '../../api/api.service'; import {ApiService} from '../../api/api.service';
import {ApplyLinkReq, Link} from '../../class/Link'; import {ApplyLinkReq, Link} from '../../class/Link';
import {FormBuilder, FormGroup, Validators} from '@angular/forms'; import {UntypedFormBuilder, UntypedFormGroup, Validators} from '@angular/forms';
import {Color, RandomColor} from '../../utils/color'; import {Color, randomColor} from '../../utils/color';
@Component({ @Component({
selector: 'view-link', selector: 'view-link',
@@ -13,25 +14,22 @@ import {Color, RandomColor} from '../../utils/color';
}) })
export class LinkComponent implements OnInit { export class LinkComponent implements OnInit {
constructor(private message: NzMessageService,
private titleService: Title,
private apiService: ApiService,
private fb: FormBuilder,
private modal: NzModalService) {
titleService.setTitle('小海博客 | 友链');
}
showModal = false; showModal = false;
// 申请时的链接 // 申请时的链接
link: Link; link: Link;
linkList: Link[]; linkList: Link[];
loading: boolean = false; loading: boolean = false;
applyFormGroup: FormGroup; applyFormGroup: UntypedFormGroup;
colors: Color[]; colors: Color[];
private lastUrl: string = ''; private lastUrl: string = '';
constructor(private message: NzMessageService,
private titleService: Title,
private apiService: ApiService,
private fb: UntypedFormBuilder,
private modal: NzModalService) {
titleService.setTitle('小海博客 | 友链');
}
ngOnInit() { ngOnInit() {
window.scrollTo(0, 0); window.scrollTo(0, 0);
@@ -39,7 +37,7 @@ export class LinkComponent implements OnInit {
this.apiService.links().subscribe({ this.apiService.links().subscribe({
next: data => this.linkList = data.result, next: data => this.linkList = data.result,
error: err => this.message.error(err.msg), error: err => this.message.error(err.msg),
complete: () => this.colors = RandomColor(this.linkList.length) complete: () => this.colors = randomColor(this.linkList.length)
}); });
this.applyFormGroup = this.fb.group({ this.applyFormGroup = this.fb.group({
urlLinkProtocol: ['http://'], urlLinkProtocol: ['http://'],
@@ -57,7 +55,7 @@ export class LinkComponent implements OnInit {
this.applyFormGroup.patchValue({linkUrl: linkUrlData.replace(this.lastUrl, data)}); this.applyFormGroup.patchValue({linkUrl: linkUrlData.replace(this.lastUrl, data)});
this.lastUrl = data; this.lastUrl = data;
}, },
}) });
} }
apply() { apply() {
@@ -71,7 +69,7 @@ export class LinkComponent implements OnInit {
this.message.success('提交成功,请稍等,即将为你处理'); this.message.success('提交成功,请稍等,即将为你处理');
this.loading = false; this.loading = false;
this.showModal = false; this.showModal = false;
this.applyFormGroup.reset() this.applyFormGroup.reset();
}, },
error: err => { error: err => {
if (err.code === 7200) { if (err.code === 7200) {
@@ -84,7 +82,7 @@ export class LinkComponent implements OnInit {
this.apiService.reapplyLink(key).subscribe({ this.apiService.reapplyLink(key).subscribe({
next: data1 => this.message.success('提交成功,请稍等,即将为你处理'), next: data1 => this.message.success('提交成功,请稍等,即将为你处理'),
error: err1 => this.message.error('提交失败,原因:' + err.msg) error: err1 => this.message.error('提交失败,原因:' + err.msg)
}) });
} }
}); });
} else { } else {
@@ -92,7 +90,7 @@ export class LinkComponent implements OnInit {
} }
this.loading = false; this.loading = false;
this.showModal = false; this.showModal = false;
this.applyFormGroup.reset() this.applyFormGroup.reset();
} }
}); });
} }

View File

@@ -1,7 +1,12 @@
import {NgModule} from '@angular/core'; import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {LinkComponent} from './link.component'; import {LinkComponent} from './link.component';
import {NzButtonModule, NzFormModule, NzIconModule, NzInputModule, NzModalModule, NzSelectModule} from 'ng-zorro-antd'; import {NzButtonModule} from 'ng-zorro-antd/button';
import {NzFormModule} from 'ng-zorro-antd/form';
import {NzIconModule} from 'ng-zorro-antd/icon';
import {NzInputModule} from 'ng-zorro-antd/input';
import {NzModalModule} from 'ng-zorro-antd/modal';
import {NzSelectModule} from 'ng-zorro-antd/select';
import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {RouterModule} from '@angular/router'; import {RouterModule} from '@angular/router';

View File

@@ -1,10 +1,11 @@
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {NzMessageService} from 'ng-zorro-antd'; import {NzMessageService} from 'ng-zorro-antd/message';
import {LoginReq} from '../../../../class/User'; import {LoginReq} from '../../../../class/User';
import {ActivatedRoute, Router} from '@angular/router'; import {ActivatedRoute, Router} from '@angular/router';
import {LoginRegistrationService} from '../../service/login-registration.service'; import {LoginRegistrationService} from '../../service/login-registration.service';
import {Title} from '@angular/platform-browser'; import {Title} from '@angular/platform-browser';
import {GlobalUserService} from '../../../../services/global-user.service'; import {GlobalUserService} from '../../../../services/global-user.service';
import {LocalStorageService} from '../../../../services/local-storage.service';
@Component({ @Component({
selector: 'c-login', selector: 'c-login',
@@ -13,29 +14,30 @@ import {GlobalUserService} from '../../../../services/global-user.service';
}) })
export class LoginComponent implements OnInit { export class LoginComponent implements OnInit {
@Output() loginStatus = new EventEmitter<boolean>();
@Input() showSendEmail: boolean = true;
submitting: boolean = false;
loginReq: LoginReq = new LoginReq(null, true, null);
private url: string;
constructor(private nzMessageService: NzMessageService, constructor(private nzMessageService: NzMessageService,
private userService: GlobalUserService, private userService: GlobalUserService,
private activatedRoute: ActivatedRoute, private activatedRoute: ActivatedRoute,
private router: Router, private router: Router,
private loginRegistrationService: LoginRegistrationService, private loginRegistrationService: LoginRegistrationService,
private title: Title) { private title: Title,
private localStorageService: LocalStorageService) {
this.title.setTitle('小海博客 | 登录 '); this.title.setTitle('小海博客 | 登录 ');
} }
submitting: boolean = false;
loginReq: LoginReq = new LoginReq(null, true, null);
@Output() loginStatus = new EventEmitter<boolean>();
@Input() showSendEmail: boolean = true;
private url: string;
ngOnInit() { ngOnInit() {
this.url = this.activatedRoute.snapshot.queryParamMap.get('url'); this.url = this.activatedRoute.snapshot.queryParamMap.get('url');
this.loginReq.email = localStorage.getItem('e'); this.loginReq.email = this.localStorageService.getItem('e');
this.loginReq.password = localStorage.getItem('p'); this.loginReq.password = this.localStorageService.getItem('p');
localStorage.removeItem('e'); this.localStorageService.removeItem('e');
localStorage.removeItem('p'); this.localStorageService.removeItem('p');
} }
doLogin() { doLogin() {
@@ -68,7 +70,7 @@ export class LoginComponent implements OnInit {
this.router.navigateByUrl(this.url); this.router.navigateByUrl(this.url);
} else { } else {
// window.location.href = '/admin/'; // window.location.href = '/admin/';
this.router.navigateByUrl('/admin') this.router.navigateByUrl('/admin');
} }
} }
} }

View File

@@ -1,11 +1,12 @@
import {Component, EventEmitter, OnInit, Output} from '@angular/core'; import {Component, EventEmitter, OnInit, Output} from '@angular/core';
import {environment} from '../../../../../environments/environment'; import {environment} from '../../../../../environments/environment';
import {ApiService} from '../../../../api/api.service'; import {ApiService} from '../../../../api/api.service';
import {NzMessageService} from 'ng-zorro-antd'; import {NzMessageService} from 'ng-zorro-antd/message';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
import {RequestObj} from '../../../../class/HttpReqAndResp'; import {RequestObj} from '../../../../class/HttpReqAndResp';
import {LoginReq} from '../../../../class/User'; import {LoginReq} from '../../../../class/User';
import {Title} from '@angular/platform-browser'; import {Title} from '@angular/platform-browser';
import {LocalStorageService} from '../../../../services/local-storage.service';
@Component({ @Component({
selector: 'c-registration', selector: 'c-registration',
@@ -15,23 +16,24 @@ import {Title} from '@angular/platform-browser';
}) })
export class RegistrationComponent implements OnInit { export class RegistrationComponent implements OnInit {
constructor(private apiService: ApiService, @Output() regStatus = new EventEmitter<boolean>();
private nzMessageService: NzMessageService, @Output() regAccount = new EventEmitter<LoginReq>();
private router: Router,
private title: Title) {
this.title.setTitle('小海博客 | 注册');
}
imgCodeUrl: string; imgCodeUrl: string;
imgCode: string; imgCode: string;
email: string; email: string;
pwd: string;
pwd: string;
submitting: boolean; submitting: boolean;
@Output() regStatus = new EventEmitter<boolean>();
@Output() regAccount = new EventEmitter<LoginReq>(); constructor(private apiService: ApiService,
private nzMessageService: NzMessageService,
private router: Router,
private title: Title,
private localStorageService: LocalStorageService) {
this.title.setTitle('小海博客 | 注册');
}
ngOnInit() { ngOnInit() {
this.imgCodeUrl = environment.host + '/imgCode'; this.imgCodeUrl = environment.host + '/imgCode';
@@ -74,8 +76,8 @@ export class RegistrationComponent implements OnInit {
this.apiService.verifyImgCode(this.imgCode).subscribe(data => { this.apiService.verifyImgCode(this.imgCode).subscribe(data => {
// 验证成功 注册 // 验证成功 注册
this.apiService.registration(this.email, this.pwd).subscribe(regData => { this.apiService.registration(this.email, this.pwd).subscribe(regData => {
localStorage.setItem('e', this.email); this.localStorageService.setItem('e', this.email);
localStorage.setItem('p', this.pwd); this.localStorageService.setItem('p', this.pwd);
this.email = ''; this.email = '';
this.pwd = ''; this.pwd = '';
this.imgCode = ''; this.imgCode = '';

View File

@@ -1,7 +1,7 @@
import {Component, OnInit} from '@angular/core'; import {Component, OnInit} from '@angular/core';
import {ApiService} from '../../api/api.service'; import {ApiService} from '../../api/api.service';
import {LoginRegistrationService} from './service/login-registration.service'; import {LoginRegistrationService} from './service/login-registration.service';
import {NzMessageService} from 'ng-zorro-antd'; import {NzMessageService} from 'ng-zorro-antd/message';
@Component({ @Component({
selector: 'view-login-registration', selector: 'view-login-registration',
@@ -10,14 +10,15 @@ import {NzMessageService} from 'ng-zorro-antd';
}) })
export class LoginRegistrationComponent implements OnInit { export class LoginRegistrationComponent implements OnInit {
picUrl: string = '';
email: string;
submitting: boolean = false;
constructor(private apiService: ApiService, constructor(private apiService: ApiService,
public loginRegistrationService: LoginRegistrationService, public loginRegistrationService: LoginRegistrationService,
private nzMessageService: NzMessageService) { private nzMessageService: NzMessageService) {
} }
picUrl: string = '';
email: string;
submitting: boolean = false;
ngOnInit() { ngOnInit() {
this.apiService.bingPic().subscribe(data => { this.apiService.bingPic().subscribe(data => {

View File

@@ -6,7 +6,11 @@ import {RegistrationComponent} from './components/registration/registration.comp
import {LoginRegistrationRoutingModule} from './login-registration-routing.module'; import {LoginRegistrationRoutingModule} from './login-registration-routing.module';
import {LoginRegistrationComponent} from './login-registration.component'; import {LoginRegistrationComponent} from './login-registration.component';
import {FormsModule} from '@angular/forms'; import {FormsModule} from '@angular/forms';
import {NzButtonModule, NzFormModule, NzGridModule, NzInputModule, NzModalModule} 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 { NzInputModule } from 'ng-zorro-antd/input';
import { NzModalModule } from 'ng-zorro-antd/modal';
@NgModule({ @NgModule({

View File

@@ -5,8 +5,8 @@ import {Injectable} from '@angular/core';
}) })
export class LoginRegistrationService { export class LoginRegistrationService {
showModal: boolean = false;
constructor() { constructor() {
} }
showModal: boolean = false;
} }

View File

@@ -2,7 +2,8 @@ import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {MaintainComponent} from './maintain.component'; import {MaintainComponent} from './maintain.component';
import {RouterModule} from '@angular/router'; import {RouterModule} from '@angular/router';
import {NzButtonModule, NzResultModule} from 'ng-zorro-antd'; import {NzButtonModule} from 'ng-zorro-antd/button';
import {NzResultModule} from 'ng-zorro-antd/result';
@NgModule({ @NgModule({

View File

@@ -1,12 +1,12 @@
<div style="height: 70%"> <div style="height: 70%">
<div id="main"> <div id="main">
<div *ngIf="iserror"> <div *ngIf="iserror">
<nz-alert nzType="error" nzMessage="链接可能被修改了,请重新点击邮箱中的链接,或者重新发送邮件" nzShowIcon> <nz-alert nzMessage="链接可能被修改了,请重新点击邮箱中的链接,或者重新发送邮件" nzShowIcon nzType="error">
</nz-alert> </nz-alert>
</div> </div>
<div *ngIf="!iserror"> <div *ngIf="!iserror">
<input type="password" placeholder="新密码" [(ngModel)]="pwd"/> <input [(ngModel)]="pwd" placeholder="新密码" type="password"/>
<input type="password" placeholder="确认密码" [(ngModel)]="rePwd"/> <input [(ngModel)]="rePwd" placeholder="确认密码" type="password"/>
<button (click)="submit()">提交</button> <button (click)="submit()">提交</button>
</div> </div>

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