Merge branch 'develop' of https://gitlab.eascs.com/tms-ui/tms-obc-web into lxx
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -25,6 +25,7 @@ scripts/var.less | ||||
|  | ||||
| # IDE - VSCode | ||||
| .vscode/* | ||||
| .vscode | ||||
| !.vscode/settings.json | ||||
| !.vscode/tasks.json | ||||
| !.vscode/launch.json | ||||
|  | ||||
							
								
								
									
										3
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| { | ||||
|     "compile-hero.disable-compile-files-on-did-save-code": true | ||||
| } | ||||
| @ -41,7 +41,7 @@ function getRule(params: any): any { | ||||
|   if (params.no) { | ||||
|     ret = ret.filter(data => data.no.indexOf(params.no) > -1); | ||||
|   } | ||||
|   return { data: ret, success: true }; | ||||
|   return { data: { records: ret, total: ret.length }, success: true }; | ||||
| } | ||||
|  | ||||
| function removeRule(nos: string): any { | ||||
| @ -78,6 +78,6 @@ function saveRule(description: string): void { | ||||
|  | ||||
| export const RULES = { | ||||
|   'POST /rule': (req: MockRequest) => getRule(req.queryString), | ||||
|   'POST /delete/rule': (req: MockRequest) => removeRule(req.body.nos), | ||||
|   'POST /delete/rule': (req: MockRequest) => removeRule(req.body.nos) | ||||
|   // 'POST /rule': (req: MockRequest) => saveRule(req.body.description) | ||||
| }; | ||||
|  | ||||
							
								
								
									
										56
									
								
								angular.json
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								angular.json
									
									
									
									
									
								
							| @ -35,11 +35,23 @@ | ||||
|             "styles": [ | ||||
|               "node_modules/perfect-scrollbar/css/perfect-scrollbar.css", | ||||
|               "node_modules/quill/dist/quill.snow.css", | ||||
|               "src/styles.less" | ||||
|               "src/styles.less", | ||||
|               { | ||||
|                 "input": "src/styles/default.less", | ||||
|                 "bundleName": "default", | ||||
|                 "inject": false | ||||
|               }, | ||||
|               { | ||||
|                 "input": "src/styles/compact.less", | ||||
|                 "bundleName": "compact", | ||||
|                 "inject": false | ||||
|               } | ||||
|             ], | ||||
|              | ||||
|             "scripts": [ | ||||
|               "node_modules/quill/dist/quill.min.js", | ||||
|               "node_modules/perfect-scrollbar/dist/perfect-scrollbar.js" | ||||
|               "node_modules/perfect-scrollbar/dist/perfect-scrollbar.js", | ||||
|               "node_modules/qrious/dist/qrious.min.js" | ||||
|             ], | ||||
|             "allowedCommonJsDependencies": [ | ||||
|               "ajv", | ||||
| @ -48,20 +60,28 @@ | ||||
|           }, | ||||
|           "configurations": { | ||||
|             "production": { | ||||
|               "fileReplacements": [ | ||||
|                 { | ||||
|                   "replace": "src/environments/environment.ts", | ||||
|                   "with": "src/environments/environment.prod.ts" | ||||
|                 } | ||||
|               ], | ||||
|               "fileReplacements": [{ | ||||
|                 "replace": "src/environments/environment.ts", | ||||
|                 "with": "src/environments/environment.prod.ts" | ||||
|               }], | ||||
|               "outputHashing": "all", | ||||
|               "budgets": [ | ||||
|                 { | ||||
|                   "type": "initial", | ||||
|                   "maximumWarning": "2mb", | ||||
|                   "maximumError": "5mb" | ||||
|                 } | ||||
|               ] | ||||
|               "budgets": [{ | ||||
|                 "type": "initial", | ||||
|                 "maximumWarning": "4mb", | ||||
|                 "maximumError": "10mb" | ||||
|               }] | ||||
|             }, | ||||
|             "dev": { | ||||
|               "fileReplacements": [{ | ||||
|                 "replace": "src/environments/environment.ts", | ||||
|                 "with": "src/environments/eascs/environment.dev.ts" | ||||
|               }], | ||||
|               "outputHashing": "all", | ||||
|               "budgets": [{ | ||||
|                 "type": "initial", | ||||
|                 "maximumWarning": "4mb", | ||||
|                 "maximumError": "10mb" | ||||
|               }] | ||||
|             }, | ||||
|             "development": { | ||||
|               "buildOptimizer": false, | ||||
| @ -84,6 +104,9 @@ | ||||
|             "production": { | ||||
|               "browserTarget": "ng-alain:build:production" | ||||
|             }, | ||||
|             "dev": { | ||||
|               "browserTarget": "app:build:dev" | ||||
|             }, | ||||
|             "development": { | ||||
|               "browserTarget": "ng-alain:build:development" | ||||
|             } | ||||
| @ -131,6 +154,9 @@ | ||||
|           "configurations": { | ||||
|             "production": { | ||||
|               "devServerTarget": "ng-alain:serve:production" | ||||
|             }, | ||||
|             "dev": { | ||||
|               "devServerTarget": "app:build:dev" | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|  | ||||
							
								
								
									
										101
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										101
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -1,5 +1,5 @@ | ||||
| { | ||||
|   "name": "ng-alain-pro", | ||||
|   "name": "tms-obc-web", | ||||
|   "version": "0.0.0", | ||||
|   "lockfileVersion": 1, | ||||
|   "requires": true, | ||||
| @ -19,6 +19,11 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "@amap/amap-jsapi-loader": { | ||||
|       "version": "1.0.1", | ||||
|       "resolved": "https://registry.nlark.com/@amap/amap-jsapi-loader/download/@amap/amap-jsapi-loader-1.0.1.tgz", | ||||
|       "integrity": "sha1-nsS01dJGfqxFH2yFLjXbaen58MA=" | ||||
|     }, | ||||
|     "@ampproject/remapping": { | ||||
|       "version": "1.0.1", | ||||
|       "resolved": "https://registry.npmmirror.com/@ampproject/remapping/download/@ampproject/remapping-1.0.1.tgz", | ||||
| @ -2728,11 +2733,46 @@ | ||||
|       "integrity": "sha1-ayxRCnrXA56Y57jT1lmPQ1nlwIA=", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@types/d3-geo": { | ||||
|       "version": "3.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.0.2.tgz", | ||||
|       "integrity": "sha512-DbqK7MLYA8LpyHQfv6Klz0426bQEf7bRTvhMy44sNGVyZoWn//B0c+Qbeg8Osi2Obdc9BLLXYAKpyWege2/7LQ==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@types/geojson": "*" | ||||
|       } | ||||
|     }, | ||||
|     "@types/d3-path": { | ||||
|       "version": "2.0.1", | ||||
|       "resolved": "https://registry.nlark.com/@types/d3-path/download/@types/d3-path-2.0.1.tgz", | ||||
|       "integrity": "sha1-ygPfqLlNit2XrQzZfpbiAGtHY8s=" | ||||
|     }, | ||||
|     "@types/d3-sankey": { | ||||
|       "version": "0.11.2", | ||||
|       "resolved": "https://registry.npmjs.org/@types/d3-sankey/-/d3-sankey-0.11.2.tgz", | ||||
|       "integrity": "sha512-U6SrTWUERSlOhnpSrgvMX64WblX1AxX6nEjI2t3mLK2USpQrnbwYYK+AS9SwiE7wgYmOsSSKoSdr8aoKBH0HgQ==", | ||||
|       "dev": true, | ||||
|       "requires": { | ||||
|         "@types/d3-shape": "^1" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "@types/d3-path": { | ||||
|           "version": "1.0.9", | ||||
|           "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-1.0.9.tgz", | ||||
|           "integrity": "sha512-NaIeSIBiFgSC6IGUBjZWcscUJEq7vpVu7KthHN8eieTV9d9MqkSOZLH4chq1PmcKy06PNe3axLeKmRIyxJ+PZQ==", | ||||
|           "dev": true | ||||
|         }, | ||||
|         "@types/d3-shape": { | ||||
|           "version": "1.3.8", | ||||
|           "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-1.3.8.tgz", | ||||
|           "integrity": "sha512-gqfnMz6Fd5H6GOLYixOZP/xlrMtJms9BaS+6oWxTKHNqPGZ93BkWWupQSCYm6YHqx6h9wjRupuJb90bun6ZaYg==", | ||||
|           "dev": true, | ||||
|           "requires": { | ||||
|             "@types/d3-path": "^1" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "@types/d3-shape": { | ||||
|       "version": "2.1.3", | ||||
|       "resolved": "https://registry.npmmirror.com/@types/d3-shape/download/@types/d3-shape-2.1.3.tgz", | ||||
| @ -2778,6 +2818,12 @@ | ||||
|       "integrity": "sha512-sPZYQEIF/SOnLAvaz9lTuydniP+afBMtElRTdYkeV1QtEgvtJ7qolCPjly6O32QI8CbEmP5O/fztMXEDWfEcrg==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@types/geojson": { | ||||
|       "version": "7946.0.8", | ||||
|       "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz", | ||||
|       "integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "@types/glob": { | ||||
|       "version": "7.2.0", | ||||
|       "resolved": "https://registry.npmmirror.com/@types/glob/download/@types/glob-7.2.0.tgz?cache=0&sync_timestamp=1637267477186&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40types%2Fglob%2Fdownload%2F%40types%2Fglob-7.2.0.tgz", | ||||
| @ -3426,14 +3472,6 @@ | ||||
|       "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "angular-baidu-maps": { | ||||
|       "version": "12.0.0", | ||||
|       "resolved": "https://registry.nlark.com/angular-baidu-maps/download/angular-baidu-maps-12.0.0.tgz", | ||||
|       "integrity": "sha1-I/Sn52ggJcLJRnGdIR6eNmt6sXQ=", | ||||
|       "requires": { | ||||
|         "tslib": "^2.1.0" | ||||
|       } | ||||
|     }, | ||||
|     "ansi-colors": { | ||||
|       "version": "4.1.1", | ||||
|       "resolved": "https://registry.nlark.com/ansi-colors/download/ansi-colors-4.1.1.tgz", | ||||
| @ -5175,6 +5213,14 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "css-line-break": { | ||||
|       "version": "2.1.0", | ||||
|       "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", | ||||
|       "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", | ||||
|       "requires": { | ||||
|         "utrie": "^1.0.2" | ||||
|       } | ||||
|     }, | ||||
|     "css-loader": { | ||||
|       "version": "6.2.0", | ||||
|       "resolved": "https://registry.npmmirror.com/css-loader/download/css-loader-6.2.0.tgz?cache=0&sync_timestamp=1635967924209&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fcss-loader%2Fdownload%2Fcss-loader-6.2.0.tgz", | ||||
| @ -8116,6 +8162,15 @@ | ||||
|       "integrity": "sha1-e15vfmZen7QfMAB+2eDUHpf7IUA=", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "html2canvas": { | ||||
|       "version": "1.4.1", | ||||
|       "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", | ||||
|       "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", | ||||
|       "requires": { | ||||
|         "css-line-break": "^2.1.0", | ||||
|         "text-segmentation": "^1.0.3" | ||||
|       } | ||||
|     }, | ||||
|     "htmlparser2": { | ||||
|       "version": "3.10.1", | ||||
|       "resolved": "https://registry.npmmirror.com/htmlparser2/download/htmlparser2-3.10.1.tgz?cache=0&sync_timestamp=1636640940074&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fhtmlparser2%2Fdownload%2Fhtmlparser2-3.10.1.tgz", | ||||
| @ -14814,6 +14869,11 @@ | ||||
|       "integrity": "sha1-xF6cYYAL0IfviNfiVkI73Unl0HE=", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "qrious": { | ||||
|       "version": "4.0.2", | ||||
|       "resolved": "http://npm.eascs.com/qrious/-/qrious-4.0.2.tgz", | ||||
|       "integrity": "sha1-CcTUB50rlhYX9ixpz/O5u2ajlpM=" | ||||
|     }, | ||||
|     "qs": { | ||||
|       "version": "6.7.0", | ||||
|       "resolved": "https://registry.nlark.com/qs/download/qs-6.7.0.tgz", | ||||
| @ -22660,6 +22720,14 @@ | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "text-segmentation": { | ||||
|       "version": "1.0.3", | ||||
|       "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", | ||||
|       "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", | ||||
|       "requires": { | ||||
|         "utrie": "^1.0.2" | ||||
|       } | ||||
|     }, | ||||
|     "text-table": { | ||||
|       "version": "0.2.0", | ||||
|       "resolved": "https://registry.npm.taobao.org/text-table/download/text-table-0.2.0.tgz", | ||||
| @ -23209,6 +23277,21 @@ | ||||
|       "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", | ||||
|       "dev": true | ||||
|     }, | ||||
|     "utrie": { | ||||
|       "version": "1.0.2", | ||||
|       "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", | ||||
|       "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", | ||||
|       "requires": { | ||||
|         "base64-arraybuffer": "^1.0.2" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "base64-arraybuffer": { | ||||
|           "version": "1.0.2", | ||||
|           "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", | ||||
|           "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==" | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "uuid": { | ||||
|       "version": "3.4.0", | ||||
|       "resolved": "https://registry.npmmirror.com/uuid/download/uuid-3.4.0.tgz", | ||||
|  | ||||
							
								
								
									
										68
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								package.json
									
									
									
									
									
								
							| @ -1,7 +1,7 @@ | ||||
| { | ||||
|   "name": "ng-alain-pro", | ||||
|   "name": "tms-obc-web", | ||||
|   "version": "0.0.0", | ||||
|   "description": "Ng-alain business theme, ng-zorro-antd admin panel front-end framework", | ||||
|   "description": "运营后台-WEB", | ||||
|   "author": "cipchk <cipchk@qq.com>", | ||||
|   "repository": { | ||||
|     "type": "git", | ||||
| @ -11,9 +11,11 @@ | ||||
|   "scripts": { | ||||
|     "ng-high-memory": "node --max_old_space_size=8000 ./node_modules/@angular/cli/bin/ng", | ||||
|     "ng": "ng", | ||||
|     "start": "ng s -o --port 4202", | ||||
|     "start": "ng s -o --port 4202  --host 0.0.0.0", | ||||
|     "startIp": "ng serve -o --port 4202 --host 172.29.9.71 --open", | ||||
|     "hmr": "ng s -o --hmr", | ||||
|     "build": "npm run ng-high-memory build", | ||||
|     "build": "npm run ng-high-memory build --", | ||||
|     "build:dev": "npm run build -- -c dev", | ||||
|     "analyze": "npm run ng-high-memory build -- --source-map", | ||||
|     "analyze:view": "source-map-explorer dist/**/*.js", | ||||
|     "lint": "npm run lint:ts && npm run lint:style", | ||||
| @ -29,6 +31,7 @@ | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@agm/core": "^1.1.0", | ||||
|     "@amap/amap-jsapi-loader": "^1.0.1", | ||||
|     "@angular/animations": "~12.2.0", | ||||
|     "@angular/common": "~12.2.0", | ||||
|     "@angular/compiler": "~12.2.0", | ||||
| @ -53,8 +56,8 @@ | ||||
|     "@fullcalendar/timegrid": "^5.9.0", | ||||
|     "@swimlane/ngx-charts": "^18.0.1", | ||||
|     "ajv": "^8.6.2", | ||||
|     "angular-baidu-maps": "^12.0.0", | ||||
|     "file-saver": "^2.0.5", | ||||
|     "html2canvas": "^1.4.1", | ||||
|     "js-base64": "^3.6.1", | ||||
|     "masonry-layout": "^4.2.2", | ||||
|     "ng-gallery": "^5.0.0", | ||||
| @ -62,6 +65,7 @@ | ||||
|     "ngx-tinymce": "^12.0.0", | ||||
|     "ngx-trend": "^7.0.0", | ||||
|     "perfect-scrollbar": "^1.5.2", | ||||
|     "qrious": "^4.0.2", | ||||
|     "quill": "^1.3.7", | ||||
|     "quill-image-resize-module": "^3.0.0", | ||||
|     "rxjs": "~6.6.0", | ||||
| @ -71,22 +75,22 @@ | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@angular-devkit/build-angular": "~12.2.0", | ||||
|     "@angular/cli": "~12.2.0", | ||||
|     "@angular/compiler-cli": "~12.2.0", | ||||
|     "@types/jasmine": "~3.8.0", | ||||
|     "@types/node": "^12.11.1", | ||||
|     "jasmine-core": "~3.8.0", | ||||
|     "karma": "~6.3.0", | ||||
|     "karma-chrome-launcher": "~3.1.0", | ||||
|     "karma-coverage": "~2.0.3", | ||||
|     "karma-jasmine": "~4.0.0", | ||||
|     "karma-jasmine-html-reporter": "~1.7.0", | ||||
|     "typescript": "~4.3.5", | ||||
|     "@angular-eslint/builder": "~12.3.1", | ||||
|     "@angular-eslint/eslint-plugin": "~12.3.1", | ||||
|     "@angular-eslint/eslint-plugin-template": "~12.3.1", | ||||
|     "@angular-eslint/schematics": "~12.3.1", | ||||
|     "@angular-eslint/template-parser": "~12.3.1", | ||||
|     "@angular/cli": "~12.2.0", | ||||
|     "@angular/compiler-cli": "~12.2.0", | ||||
|     "@angular/language-service": "~12.2.0", | ||||
|     "@delon/testing": "^12.3.0", | ||||
|     "@types/d3-geo": "^3.0.2", | ||||
|     "@types/d3-sankey": "^0.11.2", | ||||
|     "@types/file-saver": "^2.0.3", | ||||
|     "@types/jasmine": "~3.8.0", | ||||
|     "@types/jasminewd2": "~2.0.3", | ||||
|     "@types/js-base64": "^3.0.0", | ||||
|     "@types/node": "^12.11.1", | ||||
|     "@typescript-eslint/eslint-plugin": "~4.29.2", | ||||
|     "@typescript-eslint/parser": "~4.29.2", | ||||
|     "eslint": "^7.32.0", | ||||
| @ -95,29 +99,31 @@ | ||||
|     "eslint-plugin-jsdoc": "~36.0.7", | ||||
|     "eslint-plugin-prefer-arrow": "~1.2.3", | ||||
|     "eslint-plugin-prettier": "~3.4.1", | ||||
|     "@angular/language-service": "~12.2.0", | ||||
|     "source-map-explorer": "^2.5.2", | ||||
|     "husky": "^6.0.0", | ||||
|     "jasmine-core": "~3.8.0", | ||||
|     "jasmine-spec-reporter": "~5.0.0", | ||||
|     "karma": "~6.3.0", | ||||
|     "karma-chrome-launcher": "~3.1.0", | ||||
|     "karma-coverage": "~2.0.3", | ||||
|     "karma-coverage-istanbul-reporter": "~3.0.2", | ||||
|     "karma-jasmine": "~4.0.0", | ||||
|     "karma-jasmine-html-reporter": "~1.7.0", | ||||
|     "lint-staged": "^11.1.2", | ||||
|     "ng-alain": "^12.3.0", | ||||
|     "ng-alain-plugin-theme": "^12.0.0", | ||||
|     "ng-alain-sts": "^0.0.1", | ||||
|     "node-fetch": "^2.6.1", | ||||
|     "prettier": "^2.2.1", | ||||
|     "protractor": "~7.0.0", | ||||
|     "source-map-explorer": "^2.5.2", | ||||
|     "stylelint": "^13.13.1", | ||||
|     "stylelint-config-prettier": "^8.0.2", | ||||
|     "stylelint-config-rational-order": "^0.1.2", | ||||
|     "stylelint-config-standard": "^22.0.0", | ||||
|     "stylelint-declaration-block-no-ignored-properties": "^2.4.0", | ||||
|     "stylelint-order": "^4.1.0", | ||||
|     "@delon/testing": "^12.3.0", | ||||
|     "ng-alain": "^12.3.0", | ||||
|     "ng-alain-plugin-theme": "^12.0.0", | ||||
|     "ng-alain-sts": "^0.0.1", | ||||
|     "@types/jasminewd2": "~2.0.3", | ||||
|     "jasmine-spec-reporter": "~5.0.0", | ||||
|     "karma-coverage-istanbul-reporter": "~3.0.2", | ||||
|     "protractor": "~7.0.0", | ||||
|     "ts-node": "~8.3.0", | ||||
|     "node-fetch": "^2.6.1", | ||||
|     "husky": "^6.0.0", | ||||
|     "lint-staged": "^11.1.2", | ||||
|     "@types/file-saver": "^2.0.3", | ||||
|     "@types/js-base64": "^3.0.0" | ||||
|     "typescript": "~4.3.5" | ||||
|   }, | ||||
|   "lint-staged": { | ||||
|     "(src)/**/*.{html,ts}": [ | ||||
|  | ||||
| @ -1,10 +1,14 @@ | ||||
| /** | ||||
|  * For more configuration, please refer to https://angular.io/guide/build#proxying-to-a-backend-server | ||||
|  * | ||||
|  * 更多配置描述请参考 https://angular.cn/guide/build#proxying-to-a-backend-server | ||||
|  * | ||||
|  * Note: The proxy is only valid for real requests, Mock does not actually generate requests, so the priority of Mock will be higher than the proxy | ||||
| /* | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-18 09:51:21 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-04-08 14:26:28 | ||||
|  * @FilePath     : \\tms-obc-web\\proxy.conf.js | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
|  */ | ||||
|  | ||||
| module.exports = { | ||||
|   /** | ||||
|    * The following means that all requests are directed to the backend `https://localhost:9000/` | ||||
| @ -14,4 +18,14 @@ module.exports = { | ||||
|   //   secure: false, // Ignore invalid SSL certificates | ||||
|   //   changeOrigin: true | ||||
|   // } | ||||
|   '//api': { | ||||
|     target: { | ||||
|       host: 'tms-api-dev.eascs.com', | ||||
|       protocol: 'https:', | ||||
|       port: 443 | ||||
|     }, | ||||
|     secure: false, | ||||
|     changeOrigin: true, | ||||
|     logLevel: 'debug' | ||||
|   }, | ||||
| }; | ||||
|  | ||||
| @ -2,8 +2,10 @@ import { Component, ElementRef, OnInit, Renderer2 } from '@angular/core'; | ||||
| import { NavigationEnd, NavigationError, RouteConfigLoadStart, Router } from '@angular/router'; | ||||
| import { TitleService, VERSION as VERSION_ALAIN } from '@delon/theme'; | ||||
| import { environment } from '@env/environment'; | ||||
| import { NzIconService } from 'ng-zorro-antd/icon'; | ||||
| import { NzModalService } from 'ng-zorro-antd/modal'; | ||||
| import { VERSION as VERSION_ZORRO } from 'ng-zorro-antd/version'; | ||||
| import { ThemeService } from './theme.service'; | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-root', | ||||
| @ -15,10 +17,15 @@ export class AppComponent implements OnInit { | ||||
|     renderer: Renderer2, | ||||
|     private router: Router, | ||||
|     private titleSrv: TitleService, | ||||
|     private modalSrv: NzModalService | ||||
|     private modalSrv: NzModalService, | ||||
|     private iconService: NzIconService, | ||||
|     private themeService: ThemeService | ||||
|   ) { | ||||
|     renderer.setAttribute(el.nativeElement, 'ng-alain-version', VERSION_ALAIN.full); | ||||
|     renderer.setAttribute(el.nativeElement, 'ng-zorro-version', VERSION_ZORRO.full); | ||||
|     this.iconService.fetchFromIconfont({ | ||||
|       scriptUrl: 'https://at.alicdn.com/t/font_3153207_udngwyp35db.js' | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   ngOnInit(): void { | ||||
| @ -42,5 +49,15 @@ export class AppComponent implements OnInit { | ||||
|         this.modalSrv.closeAll(); | ||||
|       } | ||||
|     }); | ||||
|     // 适配放大150%的屏幕 | ||||
|     const screen: any = window.screen | ||||
|     var zoom = window.devicePixelRatio || screen.deviceXDPI / screen?.logicalXDPI; | ||||
|     // console.log(zoom) | ||||
|     if (document.body.clientWidth >= 1280) { | ||||
|       if (zoom != 1 && zoom != 2 && zoom != 3) { | ||||
|         this.themeService.toggleTheme().then(); | ||||
|       } | ||||
|     } | ||||
|      | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
| /* eslint-disable import/no-duplicates */ | ||||
| import { HttpClientModule } from '@angular/common/http'; | ||||
| import { default as ngLang } from '@angular/common/locales/zh'; | ||||
| import { APP_INITIALIZER, LOCALE_ID, NgModule, Type } from '@angular/core'; | ||||
| import { APP_INITIALIZER, DEFAULT_CURRENCY_CODE, LOCALE_ID, NgModule, Type } from '@angular/core'; | ||||
| import { BrowserModule } from '@angular/platform-browser'; | ||||
| import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; | ||||
| import { SimpleInterceptor } from '@delon/auth'; | ||||
| @ -19,10 +19,11 @@ const GLOBAL_THIRD_MODULES: Array<Type<any>> = [BidiModule]; | ||||
| // #region Http Interceptors | ||||
| import { HTTP_INTERCEPTORS } from '@angular/common/http'; | ||||
|  | ||||
| import { DefaultInterceptor } from '@core'; | ||||
| import { BusinessInterceptor, DefaultInterceptor } from '@core'; | ||||
|  | ||||
| const INTERCEPTOR_PROVIDES = [ | ||||
|   { provide: HTTP_INTERCEPTORS, useClass: SimpleInterceptor, multi: true }, | ||||
|   { provide: HTTP_INTERCEPTORS, useClass: BusinessInterceptor, multi: true }, | ||||
|   { provide: HTTP_INTERCEPTORS, useClass: DefaultInterceptor, multi: true } | ||||
| ]; | ||||
| // #endregion | ||||
| @ -39,7 +40,9 @@ const APPINIT_PROVIDES = [ | ||||
|     useFactory: StartupServiceFactory, | ||||
|     deps: [StartupService], | ||||
|     multi: true | ||||
|   } | ||||
|   }, | ||||
|   { provide: DEFAULT_CURRENCY_CODE, useValue: '¥' }, | ||||
|   AuthGuard | ||||
| ]; | ||||
| // #endregion | ||||
|  | ||||
| @ -50,8 +53,8 @@ import { LayoutModule } from './layout/layout.module'; | ||||
| import { RoutesModule } from './routes/routes.module'; | ||||
| import { SharedModule } from './shared/shared.module'; | ||||
| import { STWidgetModule } from './shared/widget/st-widget.module'; | ||||
| import { Observable } from 'rxjs'; | ||||
| import { registerLocaleData } from '@angular/common'; | ||||
| import { AuthGuard } from './core/guards/auth.guard'; | ||||
|  | ||||
| @NgModule({ | ||||
|   declarations: [AppComponent], | ||||
|  | ||||
| @ -1,9 +1,10 @@ | ||||
| import { NgModule, Optional, SkipSelf } from '@angular/core'; | ||||
| import { EATokenGuard } from './guards/token.guard'; | ||||
|  | ||||
| import { throwIfAlreadyLoaded } from './module-import-guard'; | ||||
|  | ||||
| @NgModule({ | ||||
|   providers: [] | ||||
|   providers: [EATokenGuard] | ||||
| }) | ||||
| export class CoreModule { | ||||
|   constructor(@Optional() @SkipSelf() parentModule: CoreModule) { | ||||
|  | ||||
| @ -15,14 +15,16 @@ import { EnvironmentService } from '@env/environment.service'; | ||||
| import { NzMessageService } from 'ng-zorro-antd/message'; | ||||
|  | ||||
| @Injectable({ | ||||
|   providedIn: 'root', | ||||
|   providedIn: 'root' | ||||
| }) | ||||
| export class CoreService { | ||||
|   // 获取当前登录用户信息 | ||||
|   public $api_get_current_user_info = `/scm/cuc/cuc/user/getUserDetail`; | ||||
|  | ||||
|   // 获取当前用户所拥有的菜单 | ||||
|   public $api_get_current_user_menus = `/scm/cuc/cuc/functionInfo/getUserHaveFunctionsList`; | ||||
|   public $api_get_current_user_menus = `/api/mdc/cuc/functionInfo/getUserHaveFunctionsList`; | ||||
|  | ||||
|   position = { lat: '', lng: '' }; | ||||
|  | ||||
|   constructor(private injector: Injector) {} | ||||
|   // 注入路由 | ||||
|  | ||||
							
								
								
									
										89
									
								
								src/app/core/guards/auth.guard.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								src/app/core/guards/auth.guard.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,89 @@ | ||||
| import { Injectable, Injector } from '@angular/core'; | ||||
| import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router'; | ||||
| import { ACLGuard, ACLService } from '@delon/acl'; | ||||
| import { MenuService, SettingsService } from '@delon/theme'; | ||||
| import { EAUserService } from '@shared'; | ||||
| import { Observable, of } from 'rxjs'; | ||||
| import { switchMap } from 'rxjs/operators'; | ||||
|  | ||||
| @Injectable() | ||||
| export class AuthGuard extends ACLGuard { | ||||
|   constructor( | ||||
|     srv: ACLService, | ||||
|     public srv1: ACLService, | ||||
|     private menuService: MenuService, | ||||
|     private settings: SettingsService, | ||||
|     private userService: EAUserService, | ||||
|     router: Router, | ||||
|     private inject: Injector | ||||
|   ) { | ||||
|     super(srv, router, inject); | ||||
|   } | ||||
|  | ||||
|   canActivate(route: ActivatedRouteSnapshot, _state: RouterStateSnapshot): Observable<boolean> { | ||||
|     // if (Object.keys(route.params)?.length > 0 || !route.routeConfig?.path) { | ||||
|     //   return super.canActivate(route, _state); | ||||
|     // } else { | ||||
|     //   return super.canActivate(route, _state); | ||||
|     // } | ||||
|     return super.canActivate(route, _state); | ||||
|   } | ||||
|  | ||||
|   canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> { | ||||
|     if (childRoute.routeConfig?.loadChildren || childRoute.routeConfig?.children) { | ||||
|       return super.canActivateChild(childRoute, state); | ||||
|     } else { | ||||
|       return this.handle(childRoute, state, 2, this.settingRoute(childRoute.params, state.url)); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private handle(route: ActivatedRouteSnapshot, state: RouterStateSnapshot, type: 1 | 2, router?: string): Observable<boolean> { | ||||
|     if (!router) { | ||||
|       return type === 1 ? super.canActivate(route, state) : super.canActivateChild(route, state); | ||||
|     } | ||||
|     return this.userService | ||||
|       .request('/api/mdc/cuc/userAuthority/isUserAdmin', { | ||||
|         appUserId: this.settings.user.appUserId | ||||
|       }) | ||||
|       .pipe( | ||||
|         switchMap(res => { | ||||
|           if (res) { | ||||
|             // 超级管理员赋值全量权限 | ||||
|             this.srv1.setFull(true); | ||||
|             return of(true); | ||||
|           } else { | ||||
|             // 如果不是超级管理员 获取权限 | ||||
|             return this.userService.request('/api/mdc/cuc/functionButton/getUserFunctionButton', { link: router }); | ||||
|           } | ||||
|         }), | ||||
|         switchMap(res => { | ||||
|           if (res?.abilities) { | ||||
|             this.srv1.setAbility(res.abilities || []); | ||||
|             // this.menuService.resume(); | ||||
|             this.userService.loadUserMenus(); | ||||
|           } | ||||
|           return type === 1 ? super.canActivate(route, state) : super.canActivateChild(route, state); | ||||
|         }) | ||||
|       ); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 根据参数拼接原始路由 | ||||
|    * @param params 参数 | ||||
|    * @param route 实际路由 | ||||
|    * @returns | ||||
|    */ | ||||
|   private settingRoute(params: any, route: string) { | ||||
|     let _route = route; | ||||
|     if (_route.indexOf('?') > -1) { | ||||
|       _route = route.split('?')[0]; | ||||
|     } | ||||
|     for (const key of Object.keys(params)) { | ||||
|       if (_route.indexOf(params[key]) > -1) { | ||||
|         _route = _route.replace(params[key], ':' + key); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     return _route; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										38
									
								
								src/app/core/guards/token.guard.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/app/core/guards/token.guard.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| import { Inject, Injectable, Injector } from '@angular/core'; | ||||
| import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, Router, RouterStateSnapshot } from '@angular/router'; | ||||
| import { sysConf } from '@conf/sys.conf'; | ||||
| import { CoreService } from '@core'; | ||||
| import { ACLGuard, ACLService } from '@delon/acl'; | ||||
| import { EAUserService } from '@shared'; | ||||
| import { Observable, of } from 'rxjs'; | ||||
|  | ||||
| @Injectable() | ||||
| export class EATokenGuard implements CanActivate, CanActivateChild { | ||||
|   constructor(srv: ACLService, router: Router, private eaUserSrv: CoreService, private router2: Router, private inject: Injector) {} | ||||
|  | ||||
|   canActivate(route: ActivatedRouteSnapshot, _state: RouterStateSnapshot | null): Observable<boolean> { | ||||
|     const canOpen = this.eaUserSrv.loginStatus; | ||||
|     if (!canOpen) { | ||||
|       this.router2.navigate([sysConf.login_url], { | ||||
|         queryParams: { | ||||
|           returnUrl: _state?.url | ||||
|         } | ||||
|       }); | ||||
|       return of(!canOpen); | ||||
|     } | ||||
|     return of(true); | ||||
|   } | ||||
|  | ||||
|   canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> { | ||||
|     const canOpen = this.eaUserSrv.loginStatus; | ||||
|     if (!canOpen) { | ||||
|       this.router2.navigate([sysConf.login_url], { | ||||
|         queryParams: { | ||||
|           returnUrl: state?.url | ||||
|         } | ||||
|       }); | ||||
|       return of(!canOpen); | ||||
|     } | ||||
|     return of(true); | ||||
|   } | ||||
| } | ||||
| @ -1,6 +1,9 @@ | ||||
| export * from './module-import-guard'; | ||||
| export * from './net/default.interceptor'; | ||||
| export * from './net/business.interceptor'; | ||||
|  | ||||
| // Services | ||||
| export * from './core.service'; | ||||
| export * from './startup/startup.service'; | ||||
|  | ||||
| export * from './guards/token.guard'; | ||||
|  | ||||
							
								
								
									
										108
									
								
								src/app/core/net/business.interceptor.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								src/app/core/net/business.interceptor.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,108 @@ | ||||
| import { | ||||
|   HttpErrorResponse, | ||||
|   HttpEvent, | ||||
|   HttpHandler, | ||||
|   HttpInterceptor, | ||||
|   HttpRequest, | ||||
|   HttpResponse, | ||||
|   HttpResponseBase | ||||
| } from '@angular/common/http'; | ||||
| import { Inject, Injectable, Optional } from '@angular/core'; | ||||
| import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth'; | ||||
| import { environment } from '@env/environment'; | ||||
| import { EAEnvironmentService, EAUserService } from '@shared'; | ||||
| import { Observable, of } from 'rxjs'; | ||||
| import { catchError, mergeMap } from 'rxjs/operators'; | ||||
| import { CoreService } from '../core.service'; | ||||
|  | ||||
| @Injectable() | ||||
| export class BusinessInterceptor implements HttpInterceptor { | ||||
|   constructor( | ||||
|     private envSrv: EAEnvironmentService, | ||||
|     private eaUserSrv: EAUserService, | ||||
|     @Optional() | ||||
|     @Inject(DA_SERVICE_TOKEN) | ||||
|     private tokenSrv: ITokenService, | ||||
|     private coreSrv: CoreService | ||||
|   ) {} | ||||
|   intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { | ||||
|     // 构造新的请求URL | ||||
|     req = this.constructNewRequestUrl(req); | ||||
|     // 附加额外的请求头 | ||||
|     req = this.attachAdditionalHeaders(req); | ||||
|     // 后续操作 | ||||
|     return next.handle(req).pipe( | ||||
|       mergeMap(ev => this.handlingBussinessResponseData(ev)), | ||||
|       catchError((err: HttpErrorResponse) => this.handlingBusinessErrors(err)) | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 构造新的请求URL | ||||
|    */ | ||||
|   private constructNewRequestUrl(req: HttpRequest<any>): HttpRequest<any> { | ||||
|     let url = req.url; | ||||
|     if (!url.startsWith('https://') && !url.startsWith('http://')) { | ||||
|       if (!url.startsWith('assets')) { | ||||
|         url = environment.api.baseUrl + url; | ||||
|       } | ||||
|     } | ||||
|     return req.clone({ url }); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 附加额外的请求头 | ||||
|    */ | ||||
|   private attachAdditionalHeaders(req: HttpRequest<any>): HttpRequest<any> { | ||||
|     let position = {}; | ||||
|     if (this.coreSrv.position.lat && this.coreSrv.position.lng) { | ||||
|       position = { lat: this.coreSrv.position.lat.toString(), lng: this.coreSrv.position.lng.toString() }; | ||||
|     } | ||||
|     // 附加环境变量 | ||||
|     const header: any = { | ||||
|       appId: this.envSrv.env.appId, | ||||
|       tenantId: this.envSrv.env.tenantId, | ||||
|       enterpriseId: this.envSrv.env.enterpriseId, | ||||
|       ...position | ||||
|     }; | ||||
|  | ||||
|     // 附加授权声明 | ||||
|     const token = this.tokenSrv.get()?.token; | ||||
|     if (token) { | ||||
|       header.Authorization = `Bearer ${token}`; | ||||
|     } | ||||
|     return req.clone({ setHeaders: header }); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 处理业务数据 | ||||
|    */ | ||||
|   private handlingBussinessResponseData(ev: HttpEvent<any>): Observable<any> { | ||||
|     if (ev instanceof HttpResponseBase) { | ||||
|       const body = (ev as HttpResponse<any>).body; | ||||
|       if (body) { | ||||
|         switch (body.status) { | ||||
|           case 505001: | ||||
|           case 505002: | ||||
|             this.eaUserSrv.logout(); | ||||
|             break; | ||||
|           default: | ||||
|             break; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     if (ev instanceof HttpErrorResponse) { | ||||
|       return this.handlingBusinessErrors(ev); | ||||
|     } | ||||
|     return of(ev); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 处理响应错误 | ||||
|    */ | ||||
|   private handlingBusinessErrors(err: HttpErrorResponse): Observable<any> { | ||||
|     /** Http响应异常已在默认拦截器处理完成 ,该处不再处理 */ | ||||
|  | ||||
|     return of(err); | ||||
|   } | ||||
| } | ||||
| @ -1,20 +1,8 @@ | ||||
| import { | ||||
|   HttpErrorResponse, | ||||
|   HttpEvent, | ||||
|   HttpHandler, | ||||
|   HttpHeaders, | ||||
|   HttpInterceptor, | ||||
|   HttpRequest, | ||||
|   HttpResponseBase | ||||
| } from '@angular/common/http'; | ||||
| import { Injectable, Injector } from '@angular/core'; | ||||
| import { Router } from '@angular/router'; | ||||
| import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth'; | ||||
| import { _HttpClient } from '@delon/theme'; | ||||
| import { environment } from '@env/environment'; | ||||
| import { NzNotificationService } from 'ng-zorro-antd/notification'; | ||||
| import { BehaviorSubject, Observable, of, throwError } from 'rxjs'; | ||||
| import { catchError, filter, mergeMap, switchMap, take } from 'rxjs/operators'; | ||||
| import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponseBase } from '@angular/common/http'; | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { Observable, of } from 'rxjs'; | ||||
| import { catchError, mergeMap } from 'rxjs/operators'; | ||||
| import { CoreService } from './../core.service'; | ||||
|  | ||||
| const CODEMESSAGE: { [key: number]: string } = { | ||||
|   200: '服务器成功返回请求的数据。', | ||||
| @ -34,228 +22,38 @@ const CODEMESSAGE: { [key: number]: string } = { | ||||
|   504: '网关超时。' | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 默认HTTP拦截器,其注册细节见 `app.module.ts` | ||||
|  */ | ||||
| @Injectable() | ||||
| export class DefaultInterceptor implements HttpInterceptor { | ||||
|   private refreshTokenEnabled = environment.api.refreshTokenEnabled; | ||||
|   private refreshTokenType: 're-request' | 'auth-refresh' = environment.api.refreshTokenType; | ||||
|   private refreshToking = false; | ||||
|   private refreshToken$: BehaviorSubject<any> = new BehaviorSubject<any>(null); | ||||
|  | ||||
|   constructor(private injector: Injector) { | ||||
|     if (this.refreshTokenType === 'auth-refresh') { | ||||
|       this.buildAuthRefresh(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private get notification(): NzNotificationService { | ||||
|     return this.injector.get(NzNotificationService); | ||||
|   } | ||||
|  | ||||
|   private get tokenSrv(): ITokenService { | ||||
|     return this.injector.get(DA_SERVICE_TOKEN); | ||||
|   } | ||||
|  | ||||
|   private get http(): _HttpClient { | ||||
|     return this.injector.get(_HttpClient); | ||||
|   } | ||||
|  | ||||
|   private goTo(url: string): void { | ||||
|     setTimeout(() => this.injector.get(Router).navigateByUrl(url)); | ||||
|   } | ||||
|  | ||||
|   private checkStatus(ev: HttpResponseBase): void { | ||||
|     if ((ev.status >= 200 && ev.status < 300) || ev.status === 401) { | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     const errortext = CODEMESSAGE[ev.status] || ev.statusText; | ||||
|     this.notification.error(`请求错误 ${ev.status}: ${ev.url}`, errortext); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 刷新 Token 请求 | ||||
|    */ | ||||
|   private refreshTokenRequest(): Observable<any> { | ||||
|     const model = this.tokenSrv.get(); | ||||
|     return this.http.post(`/api/auth/refresh`, null, null, { headers: { refresh_token: model?.refresh_token || '' } }); | ||||
|   } | ||||
|  | ||||
|   // #region 刷新Token方式一:使用 401 重新刷新 Token | ||||
|  | ||||
|   private tryRefreshToken(ev: HttpResponseBase, req: HttpRequest<any>, next: HttpHandler): Observable<any> { | ||||
|     // 1、若请求为刷新Token请求,表示来自刷新Token可以直接跳转登录页 | ||||
|     if ([`/api/auth/refresh`].some(url => req.url.includes(url))) { | ||||
|       this.toLogin(); | ||||
|       return throwError(ev); | ||||
|     } | ||||
|     // 2、如果 `refreshToking` 为 `true` 表示已经在请求刷新 Token 中,后续所有请求转入等待状态,直至结果返回后再重新发起请求 | ||||
|     if (this.refreshToking) { | ||||
|       return this.refreshToken$.pipe( | ||||
|         filter(v => !!v), | ||||
|         take(1), | ||||
|         switchMap(() => next.handle(this.reAttachToken(req))) | ||||
|       ); | ||||
|     } | ||||
|     // 3、尝试调用刷新 Token | ||||
|     this.refreshToking = true; | ||||
|     this.refreshToken$.next(null); | ||||
|  | ||||
|     return this.refreshTokenRequest().pipe( | ||||
|       switchMap(res => { | ||||
|         // 通知后续请求继续执行 | ||||
|         this.refreshToking = false; | ||||
|         this.refreshToken$.next(res); | ||||
|         // 重新保存新 token | ||||
|         this.tokenSrv.set(res); | ||||
|         // 重新发起请求 | ||||
|         return next.handle(this.reAttachToken(req)); | ||||
|       }), | ||||
|       catchError(err => { | ||||
|         this.refreshToking = false; | ||||
|         this.toLogin(); | ||||
|         return throwError(err); | ||||
|       }) | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 重新附加新 Token 信息 | ||||
|    * | ||||
|    * > 由于已经发起的请求,不会再走一遍 `@delon/auth` 因此需要结合业务情况重新附加新的 Token | ||||
|    */ | ||||
|   private reAttachToken(req: HttpRequest<any>): HttpRequest<any> { | ||||
|     // 以下示例是以 NG-ALAIN 默认使用 `SimpleInterceptor` | ||||
|     const token = this.tokenSrv.get()?.token; | ||||
|     return req.clone({ | ||||
|       setHeaders: { | ||||
|         token: `Bearer ${token}` | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   // #endregion | ||||
|  | ||||
|   // #region 刷新Token方式二:使用 `@delon/auth` 的 `refresh` 接口 | ||||
|  | ||||
|   private buildAuthRefresh(): void { | ||||
|     if (!this.refreshTokenEnabled) { | ||||
|       return; | ||||
|     } | ||||
|     this.tokenSrv.refresh | ||||
|       .pipe( | ||||
|         filter(() => !this.refreshToking), | ||||
|         switchMap(res => { | ||||
|           console.log(res); | ||||
|           this.refreshToking = true; | ||||
|           return this.refreshTokenRequest(); | ||||
|         }) | ||||
|       ) | ||||
|       .subscribe( | ||||
|         res => { | ||||
|           // TODO: Mock expired value | ||||
|           res.expired = +new Date() + 1000 * 60 * 5; | ||||
|           this.refreshToking = false; | ||||
|           this.tokenSrv.set(res); | ||||
|         }, | ||||
|         () => this.toLogin() | ||||
|       ); | ||||
|   } | ||||
|  | ||||
|   // #endregion | ||||
|  | ||||
|   private toLogin(): void { | ||||
|     this.notification.error(`未登录或登录已过期,请重新登录。`, ``); | ||||
|     this.goTo(this.tokenSrv.login_url!); | ||||
|   } | ||||
|  | ||||
|   private handleData(ev: HttpResponseBase, req: HttpRequest<any>, next: HttpHandler): Observable<any> { | ||||
|     this.checkStatus(ev); | ||||
|     // 业务处理:一些通用操作 | ||||
|     switch (ev.status) { | ||||
|       case 200: | ||||
|         // 业务层级错误处理,以下是假定restful有一套统一输出格式(指不管成功与否都有相应的数据格式)情况下进行处理 | ||||
|         // 例如响应内容: | ||||
|         //  错误内容:{ status: 1, msg: '非法参数' } | ||||
|         //  正确内容:{ status: 0, response: {  } } | ||||
|         // 则以下代码片断可直接适用 | ||||
|         // if (ev instanceof HttpResponse) { | ||||
|         //   const body = ev.body; | ||||
|         //   if (body && body.status !== 0) { | ||||
|         //     this.injector.get(NzMessageService).error(body.msg); | ||||
|         //     // 注意:这里如果继续抛出错误会被行254的 catchError 二次拦截,导致外部实现的 Pipe、subscribe 操作被中断,例如:this.http.get('/').subscribe() 不会触发 | ||||
|         //     // 如果你希望外部实现,需要手动移除行254 | ||||
|         //     return throwError({}); | ||||
|         //   } else { | ||||
|         //     // 忽略 Blob 文件体 | ||||
|         //     if (ev.body instanceof Blob) { | ||||
|         //        return of(ev); | ||||
|         //     } | ||||
|         //     // 重新修改 `body` 内容为 `response` 内容,对于绝大多数场景已经无须再关心业务状态码 | ||||
|         //     return of(new HttpResponse(Object.assign(ev, { body: body.response }))); | ||||
|         //     // 或者依然保持完整的格式 | ||||
|         //     return of(ev); | ||||
|         //   } | ||||
|         // } | ||||
|         break; | ||||
|       case 401: | ||||
|         if (this.refreshTokenEnabled && this.refreshTokenType === 're-request') { | ||||
|           return this.tryRefreshToken(ev, req, next); | ||||
|         } | ||||
|         this.toLogin(); | ||||
|         break; | ||||
|       case 403: | ||||
|       case 404: | ||||
|       case 500: | ||||
|         this.goTo(`/exception/${ev.status}`); | ||||
|         break; | ||||
|       default: | ||||
|         if (ev instanceof HttpErrorResponse) { | ||||
|           console.warn( | ||||
|             '未可知错误,大部分是由于后端不支持跨域CORS或无效配置引起,请参考 https://ng-alain.com/docs/server 解决跨域问题', | ||||
|             ev | ||||
|           ); | ||||
|         } | ||||
|         break; | ||||
|     } | ||||
|     if (ev instanceof HttpErrorResponse) { | ||||
|       return throwError(ev); | ||||
|     } else { | ||||
|       return of(ev); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private getAdditionalHeaders(headers?: HttpHeaders): { [name: string]: string } { | ||||
|     const res: { [name: string]: string } = {}; | ||||
|     // const lang = this.injector.get(ALAIN_I18N_TOKEN).currentLang; | ||||
|     // if (!headers?.has('Accept-Language') && lang) { | ||||
|     //   res['Accept-Language'] = lang; | ||||
|     // } | ||||
|  | ||||
|     return res; | ||||
|   } | ||||
|  | ||||
|   constructor(private coreSrv: CoreService) {} | ||||
|   intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { | ||||
|     // 统一加上服务端前缀 | ||||
|     let url = req.url; | ||||
|     if (!url.startsWith('https://') && !url.startsWith('http://')) { | ||||
|       const { baseUrl } = environment.api; | ||||
|       url = baseUrl + (baseUrl.endsWith('/') && url.startsWith('/') ? url.substring(1) : url); | ||||
|     } | ||||
|  | ||||
|     const newReq = req.clone({ url, setHeaders: this.getAdditionalHeaders(req.headers) }); | ||||
|     return next.handle(newReq).pipe( | ||||
|       mergeMap(ev => { | ||||
|         // 允许统一对请求错误处理 | ||||
|         if (ev instanceof HttpResponseBase) { | ||||
|           return this.handleData(ev, newReq, next); | ||||
|         } | ||||
|         // 若一切都正常,则后续操作 | ||||
|         return of(ev); | ||||
|       }), | ||||
|       catchError((err: HttpErrorResponse) => this.handleData(err, newReq, next)) | ||||
|     return next.handle(req).pipe( | ||||
|       mergeMap(ev => this.handlingHttpResponseData(ev)), | ||||
|       catchError((err: HttpErrorResponse) => this.handlingHttpErrorResponse(err)) | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 处理Http响应数据 | ||||
|    */ | ||||
|   private handlingHttpResponseData(ev: HttpEvent<any>): Observable<any> { | ||||
|     if (ev instanceof HttpResponseBase) { | ||||
|       // 正常情况直接返回到下个业务拦截器处理 | ||||
|       if (ev.status >= 200 && ev.status < 300) { | ||||
|         return of(ev); | ||||
|       } | ||||
|  | ||||
|       // 所有状态不是2xx和3xx都当作异常处理 | ||||
|       if (ev instanceof HttpErrorResponse) { | ||||
|         return this.handlingHttpErrorResponse(ev); | ||||
|       } | ||||
|     } | ||||
|     return of(ev); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 处理默认Http响应错误 | ||||
|    */ | ||||
|   private handlingHttpErrorResponse(err: HttpErrorResponse): Observable<any> { | ||||
|     return of(err); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,7 +1,11 @@ | ||||
| import { HttpClient } from '@angular/common/http'; | ||||
| import { Inject, Injectable } from '@angular/core'; | ||||
| import { cacheConf } from '@conf/cache.conf'; | ||||
| import { sysConf } from '@conf/sys.conf'; | ||||
| import { ACLService } from '@delon/acl'; | ||||
| import { MenuService, SettingsService, TitleService, _HttpClient } from '@delon/theme'; | ||||
| import { environment } from '@env/environment'; | ||||
| import { AmapService, EACacheService, EAUserService } from '@shared'; | ||||
| import { NzSafeAny } from 'ng-zorro-antd/core/types'; | ||||
| import { NzIconService } from 'ng-zorro-antd/icon'; | ||||
| import { Observable, zip } from 'rxjs'; | ||||
| @ -24,15 +28,25 @@ export class StartupService { | ||||
|     private aclService: ACLService, | ||||
|     private titleService: TitleService, | ||||
|     private httpClient: _HttpClient, | ||||
|     private userSrv: EAUserService, | ||||
|     private amapService: AmapService, | ||||
|     public cacheSrv: EACacheService, | ||||
|     private coreSrv: CoreService | ||||
|   ) { | ||||
|     iconSrv.addIcon(...ICONS_AUTO, ...ICONS); | ||||
|     this.settingService.setLayout('fixSiderbar', true); | ||||
|   } | ||||
|  | ||||
|   // TODO: 退出登录时需要清理用户信息 | ||||
|  | ||||
|   load(): Promise<void> { | ||||
|     return new Promise(resolve => { | ||||
|       this.amapService.getCurrentPosition().subscribe(res => { | ||||
|         if (res.position) { | ||||
|           this.coreSrv.position = { lat: res.position.lat, lng: res.position.lng }; | ||||
|         } | ||||
|       }); | ||||
|  | ||||
|       let data; | ||||
|       if (this.coreSrv.loginStatus) { | ||||
|         // 本地菜单 | ||||
| @ -74,10 +88,17 @@ export class StartupService { | ||||
|     this.settingService.setApp(appData); | ||||
|     // 用户信息:包括姓名、头像、邮箱地址 | ||||
|     this.settingService.setUser(userData); | ||||
|     this.cacheSrv.set(cacheConf.env, { | ||||
|       appId: sysConf.appId, | ||||
|       tenantId: userData?.tenantId || sysConf.tenantId, | ||||
|       enterpriseId: userData?.enterpriseId || sysConf.enterpriseId | ||||
|     }); | ||||
|     // ACL:设置权限为全量 | ||||
|     this.aclService.setFull(true); | ||||
|     this.aclService.setFull(false); | ||||
|     // 初始化菜单 | ||||
|     this.menuService.add(menuData); | ||||
|     if (menuData) { | ||||
|       this.menuService.add(menuData); | ||||
|     } | ||||
|     // 设置页面标题的后缀 | ||||
|     this.titleService.default = ''; | ||||
|     this.titleService.suffix = appData.name; | ||||
| @ -94,12 +115,10 @@ export class StartupService { | ||||
|     const appData = this.httpClient.get(`assets/mocks/app-data.json`).pipe(map((res: any) => res.app)); | ||||
|  | ||||
|     // 用户数据 | ||||
|     const userData = this.coreSrv.loginStatus | ||||
|       ? this.httpClient.post(this.coreSrv.$api_get_current_user_info, {}).pipe(map((res: any) => res.data)) | ||||
|       : this.httpClient.get('assets/mocks/user-data.json').pipe(map((res: any) => res.user)); | ||||
|     const userData = this.httpClient.get('assets/mocks/user-data.json').pipe(map((res: any) => res.user)); | ||||
|  | ||||
|     // 菜单数据 | ||||
|     const menuData = this.httpClient.get('assets/mocks/menu-data.json').pipe(map((res: any) => res.menu)); | ||||
|     const menuData = this.httpClient.get('assets/mocks/menu-data.json').pipe(map((res: any) => res.data.menu)); | ||||
|  | ||||
|     return zip(appData, userData, menuData); | ||||
|   } | ||||
| @ -115,9 +134,7 @@ export class StartupService { | ||||
|     const appData = this.httpClient.get(`assets/mocks/app-data.json`).pipe(map((res: any) => res.app)); | ||||
|  | ||||
|     // 用户数据 | ||||
|     const userData = this.coreSrv.loginStatus | ||||
|       ? this.httpClient.post(this.coreSrv.$api_get_current_user_info, {}).pipe(map((res: any) => res.data)) | ||||
|       : this.httpClient.get('assets/mocks/user-data.json').pipe(map((res: any) => res.user)); | ||||
|     const userData = this.httpClient.post(this.userSrv.$api_get_user_by_token, {}).pipe(map((res: any) => res.data)); | ||||
|  | ||||
|     // 菜单数据 | ||||
|     const menuData = this.httpClient | ||||
| @ -125,6 +142,7 @@ export class StartupService { | ||||
|         appId: this.coreSrv.envSrv.getEnvironment().appId | ||||
|       }) | ||||
|       .pipe(map((res: any) => res.data)); | ||||
|     // const menuData = this.httpClient.get('assets/mocks/menu-data.json').pipe(map((res: any) => res.data.menu)); | ||||
|  | ||||
|     return zip(appData, userData, menuData); | ||||
|   } | ||||
|  | ||||
| @ -11,9 +11,23 @@ import { environment } from '@env/environment'; | ||||
| // #region NG-ALAIN Config | ||||
|  | ||||
| const alainConfig: AlainConfig = { | ||||
|   st: { modal: { size: 'lg' } }, | ||||
|   st: { | ||||
|     req: { method: 'POST', allInBody: true, reName: { pi: 'pageIndex', ps: 'pageSize' } }, | ||||
|     res: { reName: { list: 'data.records', total: 'data.total' } }, | ||||
|     page: { show: true, showSize: true, pageSizes: [10, 20, 30, 50, 100, 200, 300, 500, 1000], toTop: false }, | ||||
|     modal: { size: 'lg' } | ||||
|   }, | ||||
|   sf: { button: { search: '查询' } }, | ||||
|   pageHeader: { homeI18n: 'home', recursiveBreadcrumb: true }, | ||||
|   auth: { login_url: '/passport/login' } | ||||
|   auth: { login_url: '/passport/login' }, | ||||
|   acl: { guard_url: '/exception/403' }, | ||||
|   chart: { | ||||
|     // 以下是默认配置,如果项目无法外网访问,可以根据 `angular.json` 配置将依赖包直接使用 `./assets***` 路径 | ||||
|     libs: [ | ||||
|       'https://gw.alipayobjects.com/os/lib/antv/g2/4.1.4/dist/g2.min.js', | ||||
|       'https://gw.alipayobjects.com/os/lib/antv/data-set/0.11.7/dist/data-set.js' | ||||
|     ] | ||||
|   }, | ||||
| }; | ||||
|  | ||||
| const alainModules = [AlainThemeModule.forRoot(), DelonACLModule.forRoot()]; | ||||
| @ -21,12 +35,12 @@ const alainProvides = [{ provide: ALAIN_CONFIG, useValue: alainConfig }]; | ||||
|  | ||||
| // #region reuse-tab | ||||
|  | ||||
| import { RouteReuseStrategy } from '@angular/router'; | ||||
| alainProvides.push({ | ||||
|   provide: RouteReuseStrategy, | ||||
|   useClass: ReuseTabStrategy, | ||||
|   deps: [ReuseTabService] | ||||
| } as any); | ||||
| // import { RouteReuseStrategy } from '@angular/router'; | ||||
| // alainProvides.push({ | ||||
| //   provide: RouteReuseStrategy, | ||||
| //   useClass: ReuseTabStrategy, | ||||
| //   deps: [ReuseTabService] | ||||
| // } as any); | ||||
|  | ||||
| // #endregion | ||||
|  | ||||
| @ -51,9 +65,9 @@ export class GlobalConfigModule { | ||||
|     throwIfAlreadyLoaded(parentModule, 'GlobalConfigModule'); | ||||
|     // NOTICE: Only valid for menus with reuse property | ||||
|     // Pls refer to the E-Mail demo effect | ||||
|     reuseTabService.mode = ReuseTabMatchMode.MenuForce; | ||||
|     // reuseTabService.mode = ReuseTabMatchMode.MenuForce; | ||||
|     // Shouled be trigger init, you can ingore when used `reuse-tab` component in layout component | ||||
|     reuseTabService.init(); | ||||
|     // reuseTabService.init(); | ||||
|   } | ||||
|  | ||||
|   static forRoot(): ModuleWithProviders<GlobalConfigModule> { | ||||
|  | ||||
| @ -24,7 +24,7 @@ import { NzSpinModule } from 'ng-zorro-antd/spin'; | ||||
| import { NzSwitchModule } from 'ng-zorro-antd/switch'; | ||||
| import { NzTimelineModule } from 'ng-zorro-antd/timeline'; | ||||
| import { NzToolTipModule } from 'ng-zorro-antd/tooltip'; | ||||
|  | ||||
| import { NzGridModule } from 'ng-zorro-antd/grid'; | ||||
| import { LayoutPassportComponent } from './passport/passport.component'; | ||||
| import { PRO_COMPONENTS } from './pro/index'; | ||||
|  | ||||
| @ -56,6 +56,7 @@ const COMPONENTS: Array<Type<any>> = [...PRO_COMPONENTS, LayoutPassportComponent | ||||
|     NoticeIconModule, | ||||
|     ThemeBtnModule, | ||||
|     ScrollbarModule, | ||||
|     NzGridModule, | ||||
|     NzMessageModule | ||||
|   ], | ||||
|   declarations: COMPONENTS, | ||||
|  | ||||
| @ -1,13 +1,15 @@ | ||||
| <div class="container"> | ||||
|   <!-- <pro-langs class="langs" btnClass></pro-langs> --> | ||||
|   <div class="wrap"> | ||||
|     <div class="top"> | ||||
|       <div class="head"> | ||||
|         <img class="logo" src="./assets/logo-color.svg"> | ||||
|         <span class="title">ng-alain pro</span> | ||||
| <nz-layout class="layout"> | ||||
|   <nz-header> | ||||
|     <div nz-row> | ||||
|       <div nz-col nzSpan="24" style="display: flex;align-items: center;"> | ||||
|         <img width="32" height="32" src="./assets/images/user/logo.svg" [routerLink]="['/']" /> | ||||
|         <label class="title ml-sm">运多星网络货运管理平台</label> | ||||
|       </div> | ||||
|       <div class="desc">武林中最有影响力的《葵花宝典》;欲练神功,挥刀自宫</div> | ||||
|     </div> | ||||
|     <router-outlet></router-outlet> | ||||
|   </div> | ||||
| </div> | ||||
|   </nz-header> | ||||
|   <nz-content class="content"> | ||||
|     <div class="inner-content"> | ||||
|       <router-outlet></router-outlet> | ||||
|     </div> | ||||
|   </nz-content> | ||||
| </nz-layout> | ||||
| @ -1,74 +1,22 @@ | ||||
| @import '~@delon/theme/index'; | ||||
|  | ||||
| :host { | ||||
|   ::ng-deep { | ||||
|     .container { | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
|       min-height: 100%; | ||||
|       background: #f0f2f5; | ||||
|     } | ||||
|     .langs { | ||||
|       width: 100%; | ||||
|       height: 40px; | ||||
|       line-height: 44px; | ||||
|       text-align: right; | ||||
|       .ant-dropdown-trigger { | ||||
|         display: inline-block; | ||||
|       } | ||||
|       .anticon { | ||||
|         margin-top: 24px; | ||||
|         margin-right: 24px; | ||||
|         font-size: 14px; | ||||
|         vertical-align: top; | ||||
|         cursor: pointer; | ||||
|       } | ||||
|     } | ||||
|     .wrap { | ||||
|       flex: 1; | ||||
|       padding: 32px 0; | ||||
|     } | ||||
|     .ant-form-item { | ||||
|       margin-bottom: 24px; | ||||
|     .layout { | ||||
|       height: 100%; | ||||
|     } | ||||
|  | ||||
|     @media (min-width: @screen-md-min) { | ||||
|       .container { | ||||
|         background-image: url('https://gw.alipayobjects.com/zos/rmsportal/TVYTbAXWheQpRcWDaDMu.svg'); | ||||
|         background-repeat: no-repeat; | ||||
|         background-position: center 110px; | ||||
|         background-size: 100%; | ||||
|       } | ||||
|       .wrap { | ||||
|         padding: 32px 0 24px; | ||||
|       } | ||||
|     } | ||||
|     .top { | ||||
|       text-align: center; | ||||
|     } | ||||
|     .header { | ||||
|       height: 44px; | ||||
|       line-height: 44px; | ||||
|       a { | ||||
|         text-decoration: none; | ||||
|       } | ||||
|     } | ||||
|     .logo { | ||||
|       height: 44px; | ||||
|       margin-right: 16px; | ||||
|     } | ||||
|     .title { | ||||
|       position: relative; | ||||
|       color: @heading-color; | ||||
|       font-weight: 600; | ||||
|       font-size: 33px; | ||||
|       font-family: 'Myriad Pro', 'Helvetica Neue', Arial, Helvetica, sans-serif; | ||||
|       vertical-align: middle; | ||||
|     } | ||||
|     .desc { | ||||
|       margin-top: 12px; | ||||
|       margin-bottom: 40px; | ||||
|       color: @text-color-secondary; | ||||
|       font-size: @font-size-base; | ||||
|     .ant-layout-header { | ||||
|       background: #ffffff; | ||||
|       box-shadow: 0px 5px 5px #d1d1d1; | ||||
|     } | ||||
|  | ||||
|     | ||||
|   } | ||||
| } | ||||
|  | ||||
| .title { | ||||
|   font-size  : 18px; | ||||
|   font-weight: 600; | ||||
|   color      : #26282A; | ||||
| } | ||||
| @ -7,24 +7,9 @@ import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth'; | ||||
|   styleUrls: ['./passport.component.less'] | ||||
| }) | ||||
| export class LayoutPassportComponent implements OnInit { | ||||
|   links = [ | ||||
|     { | ||||
|       title: '帮助', | ||||
|       href: '' | ||||
|     }, | ||||
|     { | ||||
|       title: '隐私', | ||||
|       href: '' | ||||
|     }, | ||||
|     { | ||||
|       title: '条款', | ||||
|       href: '' | ||||
|     } | ||||
|   ]; | ||||
|  | ||||
|   constructor(@Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService) {} | ||||
|   constructor() {} | ||||
|  | ||||
|   ngOnInit(): void { | ||||
|     this.tokenService.clear(); | ||||
|     // this.tokenService.clear(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| <div *ngIf="pro.isTopMenu" class="alain-pro__top-nav"> | ||||
|   <div class="alain-pro__top-nav-main" [ngClass]="{ 'alain-pro__top-nav-main-wide': pro.isFixed }"> | ||||
|     <div class="alain-pro__top-nav-main-left"> | ||||
|       <layout-pro-logo class="alain-pro__top-nav-logo"></layout-pro-logo> | ||||
|       <layout-pro-logo class="alain-pro__top-nav-logo" style="width: 195px;"></layout-pro-logo> | ||||
|       <div class="alain-pro__menu-wrap"> | ||||
|         <div layout-pro-menu mode="horizontal"></div> | ||||
|       </div> | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| <a [routerLink]="['/']" class="d-flex align-items-center"> | ||||
|   <img src="./assets/logo-color.svg" alt="{{ name }}" height="32" /> | ||||
|   <img src="./assets/images/user/logo.png" alt="{{ name }}" height="32" /> | ||||
|   <h1>{{ name }}</h1> | ||||
| </a> | ||||
|  | ||||
| @ -1,9 +1,9 @@ | ||||
| <ng-template #icon let-i> | ||||
|   <ng-container *ngIf="i" [ngSwitch]="i.type"> | ||||
|     <i *ngSwitchCase="'icon'" nz-icon [nzType]="i.value" class="alain-pro__menu-icon"></i> | ||||
|     <i *ngSwitchCase="'iconfont'" nz-icon [nzIconfont]="i.iconfont" class="alain-pro__menu-icon"></i> | ||||
|     <i *ngSwitchCase="'iconfont'" nz-icon [nzIconfont]="i.iconfont" class="alain-pro__menu-icon icon"></i> | ||||
|     <img *ngSwitchCase="'img'" src="{{ i.value }}" class="anticon alain-pro__menu-icon alain-pro__menu-img" /> | ||||
|     <i *ngSwitchDefault class="anticon alain-pro__menu-icon {{ i.value }}"></i> | ||||
|     <i *ngSwitchDefault class="icon alain-pro__menu-icon {{ i.value }}"></i> | ||||
|   </ng-container> | ||||
| </ng-template> | ||||
| <ng-template #mainLink let-i> | ||||
| @ -17,39 +17,22 @@ | ||||
|   <a *ngIf="!i.externalLink" [routerLink]="i.link" [target]="i.target">{{ i.text }} </a> | ||||
|   <a *ngIf="i.externalLink" [attr.href]="i.externalLink" [attr.target]="i.target">{{ i.text }} </a> | ||||
| </ng-template> | ||||
| <ul *ngIf="menus" nz-menu [nzMode]="mode" [nzTheme]="pro.theme" [nzInlineCollapsed]="pro.isMobile ? false : pro.collapsed"> | ||||
| <ul *ngIf="menus" nz-menu [nzMode]="mode" [nzTheme]="pro.theme" | ||||
|   [nzInlineCollapsed]="pro.isMobile ? false : pro.collapsed"> | ||||
|   <ng-container *ngFor="let l1 of menus"> | ||||
|     <li | ||||
|       *ngIf="l1.children!.length === 0" | ||||
|       nz-menu-item | ||||
|       class="alain-pro__menu-item" | ||||
|       [class.alain-pro__menu-item--disabled]="l1.disabled" | ||||
|       [nzSelected]="l1._selected" | ||||
|       [nzDisabled]="l1.disabled" | ||||
|     > | ||||
|     <li *ngIf="l1.children!.length === 0" nz-menu-item class="alain-pro__menu-item" | ||||
|       [class.alain-pro__menu-item--disabled]="l1.disabled" [nzSelected]="l1._selected" [nzDisabled]="l1.disabled"> | ||||
|       <a *ngIf="!l1.externalLink" [routerLink]="l1.link" (click)="closeCollapsed()" class="alain-pro__menu-title"> | ||||
|         <ng-template [ngTemplateOutlet]="mainLink" [ngTemplateOutletContext]="{ $implicit: l1 }"></ng-template> | ||||
|       </a> | ||||
|       <a | ||||
|         *ngIf="l1.externalLink" | ||||
|         [attr.href]="l1.externalLink" | ||||
|         [attr.target]="l1.target" | ||||
|         (click)="closeCollapsed()" | ||||
|         class="alain-pro__menu-title" | ||||
|       > | ||||
|       <a *ngIf="l1.externalLink" [attr.href]="l1.externalLink" [attr.target]="l1.target" (click)="closeCollapsed()" | ||||
|         class="alain-pro__menu-title"> | ||||
|         <ng-template [ngTemplateOutlet]="mainLink" [ngTemplateOutletContext]="{ $implicit: l1 }"></ng-template> | ||||
|       </a> | ||||
|     </li> | ||||
|     <li | ||||
|       *ngIf="l1.children!.length > 0" | ||||
|       nz-submenu | ||||
|       [nzTitle]="l1TitleTpl" | ||||
|       class="alain-pro__menu-item" | ||||
|       [class.text-white]="pro.theme === 'dark' && l1._selected" | ||||
|       [nzOpen]="l1._open" | ||||
|       [nzDisabled]="l1.disabled" | ||||
|       (nzOpenChange)="openChange(l1, $event)" | ||||
|     > | ||||
|     <li *ngIf="l1.children!.length > 0" nz-submenu [nzTitle]="l1TitleTpl" class="alain-pro__menu-item" | ||||
|       [class.text-white]="pro.theme === 'dark' && l1._selected" [nzOpen]="l1._open" [nzDisabled]="l1.disabled" | ||||
|       (nzOpenChange)="openChange(l1, $event)"> | ||||
|       <ng-template #l1TitleTpl> | ||||
|         <span title class="alain-pro__menu-title"> | ||||
|           <ng-template [ngTemplateOutlet]="icon" [ngTemplateOutletContext]="{ $implicit: l1.icon }"></ng-template> | ||||
| @ -61,34 +44,17 @@ | ||||
|       </ng-template> | ||||
|       <ul> | ||||
|         <ng-container *ngFor="let l2 of l1.children"> | ||||
|           <li | ||||
|             *ngIf="!l2._hidden && l2.children!.length === 0" | ||||
|             nz-menu-item | ||||
|             [class.alain-pro__menu-item--disabled]="l2.disabled" | ||||
|             [nzSelected]="l2._selected" | ||||
|             [nzDisabled]="l2.disabled" | ||||
|             (click)="closeCollapsed()" | ||||
|           > | ||||
|           <li *ngIf="!l2._hidden && l2.children!.length === 0" nz-menu-item | ||||
|             [class.alain-pro__menu-item--disabled]="l2.disabled" [nzSelected]="l2._selected" [nzDisabled]="l2.disabled" | ||||
|             (click)="closeCollapsed()"> | ||||
|             <ng-template [ngTemplateOutlet]="subLink" [ngTemplateOutletContext]="{ $implicit: l2 }"></ng-template> | ||||
|           </li> | ||||
|           <li | ||||
|             *ngIf="!l2._hidden && l2.children!.length > 0" | ||||
|             nz-submenu | ||||
|             [nzTitle]="l2.text!" | ||||
|             [nzOpen]="l2._open" | ||||
|             [nzDisabled]="l2.disabled" | ||||
|             (nzOpenChange)="openChange(l2, $event)" | ||||
|           > | ||||
|           <li *ngIf="!l2._hidden && l2.children!.length > 0" nz-submenu [nzTitle]="l2.text!" [nzOpen]="l2._open" | ||||
|             [nzDisabled]="l2.disabled" (nzOpenChange)="openChange(l2, $event)"> | ||||
|             <ul> | ||||
|               <ng-container *ngFor="let l3 of l2.children"> | ||||
|                 <li | ||||
|                   *ngIf="!l3._hidden" | ||||
|                   nz-menu-item | ||||
|                   [class.alain-pro__menu-item--disabled]="l3.disabled" | ||||
|                   [nzSelected]="l3._selected" | ||||
|                   [nzDisabled]="l3.disabled" | ||||
|                   (click)="closeCollapsed()" | ||||
|                 > | ||||
|                 <li *ngIf="!l3._hidden" nz-menu-item [class.alain-pro__menu-item--disabled]="l3.disabled" | ||||
|                   [nzSelected]="l3._selected" [nzDisabled]="l3.disabled" (click)="closeCollapsed()"> | ||||
|                   <ng-template [ngTemplateOutlet]="subLink" [ngTemplateOutletContext]="{ $implicit: l3 }"></ng-template> | ||||
|                 </li> | ||||
|               </ng-container> | ||||
|  | ||||
| @ -51,7 +51,6 @@ export class LayoutProMenuComponent implements OnInit, OnDestroy { | ||||
|       } | ||||
|     }); | ||||
|     this.menus = res; | ||||
|  | ||||
|     this.openStatus(); | ||||
|   } | ||||
|  | ||||
|  | ||||
| @ -1,10 +1,4 @@ | ||||
| <notice-icon | ||||
|   btnClass="alain-pro__header-item" | ||||
|   btnIconClass="alain-pro__header-item-icon" | ||||
|   [data]="data" | ||||
|   [count]="count" | ||||
|   [loading]="loading" | ||||
|   (select)="select($event)" | ||||
|   (clear)="clear($event)" | ||||
|   (popoverVisibleChange)="loadData()" | ||||
| ></notice-icon> | ||||
| <notice-icon btnClass="alain-pro__header-item" btnIconClass="alain-pro__header-item-icon" [data]="data" [count]="count" | ||||
|   [loading]="loading" (select)="select($event)" (clear)="clear($event)" (popoverVisibleChange)="loadData()"> | ||||
| </notice-icon> | ||||
|  | ||||
|  | ||||
| @ -1,21 +1,21 @@ | ||||
| <div nz-dropdown [nzDropdownMenu]="userMenu" nzPlacement="bottomRight" class="alain-pro__header-item"> | ||||
|   <nz-avatar [nzSrc]="settings.user.avatar" nzSize="small" class="mr-sm"></nz-avatar> | ||||
|   {{ settings.user.name }} | ||||
|   <nz-avatar [nzSrc]="settings.user?.avatar" nzSize="small" class="mr-sm"></nz-avatar> | ||||
|   {{ settings.user?.realName }} | ||||
| </div> | ||||
| <nz-dropdown-menu #userMenu="nzDropdownMenu"> | ||||
|   <div nz-menu class="width-sm"> | ||||
|     <div nz-menu-item routerLink="/pro/account/center"> | ||||
|     <div nz-menu-item routerLink="/account/center"> | ||||
|       <i nz-icon nzType="user" class="mr-sm"></i> | ||||
|       个人中心 | ||||
|     </div> | ||||
|     <div nz-menu-item routerLink="/pro/account/settings"> | ||||
|     <!-- <div nz-menu-item routerLink="/pro/account/settings"> | ||||
|       <i nz-icon nzType="setting" class="mr-sm"></i> | ||||
|       个人设置 | ||||
|     </div> | ||||
|     <div nz-menu-item routerLink="/exception/trigger"> | ||||
|       <i nz-icon nzType="close-circle" class="mr-sm"></i> | ||||
|       触发错误 | ||||
|     </div> | ||||
|     </div> --> | ||||
|     <li nz-menu-divider></li> | ||||
|     <div nz-menu-item (click)="logout()"> | ||||
|       <i nz-icon nzType="logout" class="mr-sm"></i> | ||||
|  | ||||
| @ -9,6 +9,10 @@ | ||||
| <!-- <quick-chat-status class="hidden-xs"></quick-chat-status> --> | ||||
| <!--Notify--> | ||||
| <layout-pro-notify class="hidden-xs"></layout-pro-notify> | ||||
| <a nz-tooltip nzTooltipTitle="下载中心" nzTooltipPlacement="bottom" class="hidden-xs" target="_blank" href="/#/download" | ||||
|   rel="noopener noreferrer" class="alain-pro__header-item"> | ||||
|   <i nz-icon nzType="cloud-download" nzTheme="outline" style="font-size: 18px;" ></i> | ||||
| </a> | ||||
| <!--RTL--> | ||||
| <!-- <layout-pro-rtl></layout-pro-rtl> --> | ||||
| <!--User--> | ||||
|  | ||||
| @ -23,7 +23,7 @@ export class BrandService { | ||||
|    * @alain-pro-sider-menu-width: 256px; | ||||
|    * ``` | ||||
|    */ | ||||
|   readonly width = 256; | ||||
|   readonly width = 205; | ||||
|  | ||||
|   /** | ||||
|    * Specify width of the sidebar after collapsed, If you change it, muse be synchronize change less parameter: | ||||
|  | ||||
| @ -29,7 +29,7 @@ | ||||
| @alain-pro-light-color: #fff; | ||||
| @alain-pro-light-slider-shadow: 2px 0 8px 0 rgba(29, 35, 41, 0.05); | ||||
|  | ||||
| @alain-pro-logo-font-size: 20px; | ||||
| @alain-pro-logo-font-size: 17px; | ||||
| @alain-pro-logo-font-family: 'Myriad Pro', 'Helvetica Neue', Arial, Helvetica, sans-serif; | ||||
|  | ||||
| @alain-pro-content-margin: 24px; | ||||
|  | ||||
							
								
								
									
										31
									
								
								src/app/routes/account/account-routing.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/app/routes/account/account-routing.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| /* | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-05 20:15:41 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-01-18 17:14:30 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\account\\account-routing.module.ts | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
|  */ | ||||
|  | ||||
| import { NgModule } from '@angular/core'; | ||||
| import { RouterModule, Routes } from '@angular/router'; | ||||
| import { AccountComponentsCenterComponent } from './components/center/center.component'; | ||||
|  | ||||
| const routes: Routes = [ | ||||
|   { path: '', redirectTo: 'center', pathMatch: 'full' }, | ||||
|   { | ||||
|     path: 'center', | ||||
|     component: AccountComponentsCenterComponent, | ||||
|     data: { | ||||
|       title: '账户中心' | ||||
|     } | ||||
|   } | ||||
| ]; | ||||
|  | ||||
| @NgModule({ | ||||
|   imports: [RouterModule.forChild(routes)], | ||||
|   exports: [RouterModule] | ||||
| }) | ||||
| export class AccountRoutingModule {} | ||||
							
								
								
									
										30
									
								
								src/app/routes/account/account.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/app/routes/account/account.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
| /* | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2021-11-29 11:06:01 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-01-18 17:14:34 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\account\\account.module.ts | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
|  */ | ||||
|  | ||||
| import { NgModule } from '@angular/core'; | ||||
| import { SharedModule } from '@shared'; | ||||
| import { AccountRoutingModule } from './account-routing.module'; | ||||
| import { AccountComponentsCenterComponent } from './components/center/center.component'; | ||||
| import { AccountComponentsEditNameComponent } from './components/edit-name/edit-name.component'; | ||||
| import { AccountComponentsCenterEditComponent } from './components/edit-password/edit-password.component'; | ||||
|  | ||||
| const COMPONENTS = [ | ||||
|   AccountComponentsCenterComponent, | ||||
|   AccountComponentsEditNameComponent, | ||||
|   AccountComponentsCenterEditComponent | ||||
| ]; | ||||
| const COMPONENTS_NOROUNT = [AccountComponentsEditNameComponent]; | ||||
|  | ||||
| @NgModule({ | ||||
|   imports: [SharedModule, AccountRoutingModule], | ||||
|   declarations: [...COMPONENTS, ...COMPONENTS_NOROUNT], | ||||
| }) | ||||
| export class AccountModule {} | ||||
| @ -0,0 +1,48 @@ | ||||
| <div class="main"> | ||||
|   <nz-card style="margin-top: 20px; min-height: 780px;"> | ||||
|     <h3 style="font-size: 20px; font-weight: 700;">个人中心</h3> | ||||
|     <nz-list style="border-bottom: 1px solid #f0f0f0"> | ||||
|       <nz-list-item> | ||||
|         <nz-list-item-meta> | ||||
|           <nz-list-item-meta-title> | ||||
|             <div nz-row [nzGutter]="16"> | ||||
|               <div nz-col [nzSpan]="4" class="li-label"> | ||||
|                 <span class="icon iconfont icon-shoujihao" style="color: #aaa"></span> 手机号码/账号 | ||||
|               </div> | ||||
|               <div nz-col [nzSpan]="10">{{ infoData.phone }}</div> | ||||
|               <div nz-col [nzSpan]="10"> | ||||
|                 <span *ngIf="infoData.phone; else elsePhone"><i nz-icon [nzType]="'check-circle'" [nzTheme]="'fill'" | ||||
|                   style="color: #52c41a"></i> 已绑定</span> | ||||
|               <ng-template #elsePhone><i nz-icon [nzType]="'question-circle'" [nzTheme]="'fill'" | ||||
|                   style="color: #ccc"></i> 未绑定</ng-template> | ||||
|               </div> | ||||
|             </div> | ||||
|           </nz-list-item-meta-title> | ||||
|         </nz-list-item-meta> | ||||
|         <div class="item-btn"><a (click)="edit('phone')">修改</a></div> | ||||
|       </nz-list-item> | ||||
|       <nz-list-item> | ||||
|         <nz-list-item-meta> | ||||
|           <nz-list-item-meta-title> | ||||
|             <div nz-row [nzGutter]="16"> | ||||
|               <div nz-col [nzSpan]="4" class="li-label"> | ||||
|                 <span class="icon iconfont icon-mima" style="color: #aaa"></span> 账户密码 | ||||
|               </div> | ||||
|               <div nz-col [nzSpan]="10">定期更换密码有助于账号安全</div> | ||||
|               <div nz-col [nzSpan]="10"> | ||||
|                 <span *ngIf="infoData.isPwd; else elsePwd" | ||||
|                   ><i nz-icon [nzType]="'check-circle'" [nzTheme]="'fill'" style="color: #52c41a"></i> 已设置</span | ||||
|                 > | ||||
|                 <ng-template #elsePwd | ||||
|                   ><i nz-icon [nzType]="'question-circle'" [nzTheme]="'fill'" style="color: #ccc"></i> 未设置</ng-template | ||||
|                 > | ||||
|               </div> | ||||
|             </div> | ||||
|           </nz-list-item-meta-title> | ||||
|         </nz-list-item-meta> | ||||
|         <div class="item-btn"><a (click)="edit('password')">修改</a></div> | ||||
|       </nz-list-item> | ||||
|     </nz-list> | ||||
|  | ||||
|   </nz-card> | ||||
| </div> | ||||
| @ -0,0 +1,46 @@ | ||||
| :host { | ||||
|   ::ng-deep { | ||||
|     .info-main { | ||||
|       padding: 30px; | ||||
|     } | ||||
|     .info-main h3 { | ||||
|       margin-bottom: 30px; | ||||
|       color: #333; | ||||
|       font-size: 24px; | ||||
|     } | ||||
|     .info { | ||||
|       position: relative; | ||||
|     } | ||||
|     .info-btn { | ||||
|       position: absolute; | ||||
|       top: 20px; | ||||
|       right: 20px; | ||||
|     } | ||||
|     .item-btn { | ||||
|       width: 28px; | ||||
|       text-align: center; | ||||
|     } | ||||
|     .li-label { | ||||
|       color: #333; | ||||
|       font-weight: bold; | ||||
|       font-size: 14px; | ||||
|     } | ||||
|     page-grid { | ||||
|       background-color: #f0f3f7; | ||||
|  | ||||
|       div.container { | ||||
|         width: 80%; | ||||
|         margin: 0 auto; | ||||
|         padding: 1rem; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   .info-row { | ||||
|     padding: 24px 0; | ||||
|     .info-icon { | ||||
|       margin-right: 15px; | ||||
|       color: #3875fb; | ||||
|       font-size: 16px; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,23 @@ | ||||
| import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | ||||
| import { AccountComponentsCenterComponent } from './center.component'; | ||||
|  | ||||
| describe('AccountComponentsCenterComponent', () => { | ||||
|   let component: AccountComponentsCenterComponent; | ||||
|   let fixture: ComponentFixture<AccountComponentsCenterComponent>; | ||||
|  | ||||
|   beforeEach(async(() => { | ||||
|     TestBed.configureTestingModule({ | ||||
|       declarations: [AccountComponentsCenterComponent], | ||||
|     }).compileComponents(); | ||||
|   })); | ||||
|  | ||||
|   beforeEach(() => { | ||||
|     fixture = TestBed.createComponent(AccountComponentsCenterComponent); | ||||
|     component = fixture.componentInstance; | ||||
|     fixture.detectChanges(); | ||||
|   }); | ||||
|  | ||||
|   it('should create', () => { | ||||
|     expect(component).toBeTruthy(); | ||||
|   }); | ||||
| }); | ||||
							
								
								
									
										202
									
								
								src/app/routes/account/components/center/center.component.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								src/app/routes/account/components/center/center.component.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,202 @@ | ||||
| import { Component, OnInit, ViewChild } from '@angular/core'; | ||||
| import { Router } from '@angular/router'; | ||||
| import { SFComponent, SFSchema, SFSelectWidgetSchema, SFUISchema, SFUploadWidgetSchema } from '@delon/form'; | ||||
| import { ModalHelper, _HttpClient } from '@delon/theme'; | ||||
| import { Observable, Observer } from 'rxjs'; | ||||
| import { AccountService } from '../../services/account.service'; | ||||
| import { AccountComponentsEditNameComponent } from '../edit-name/edit-name.component'; | ||||
| import { NzModalService } from 'ng-zorro-antd/modal'; | ||||
| import { AccountComponentsCenterEditComponent } from '../edit-password/edit-password.component'; | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-account-components-center', | ||||
|   templateUrl: './center.component.html', | ||||
|   styleUrls: ['./center.component.less'], | ||||
| }) | ||||
| export class AccountComponentsCenterComponent implements OnInit { | ||||
|   url = `/rule?_allow_anonymous=true`; | ||||
|   @ViewChild('sf', { static: false }) sf!: SFComponent; | ||||
|   i: any; | ||||
|   formDate: any = {}; | ||||
|   schema!: SFSchema; | ||||
|   ui: SFUISchema = {}; | ||||
|   infoData: any = { | ||||
|     appId: '', | ||||
|     appTypeId: 0, | ||||
|     appTypeName: '', | ||||
|     appUserId: 0, | ||||
|     avatar: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png?_allow_anonymous=true', | ||||
|     birthday: '', | ||||
|     cert: 0, | ||||
|     createTime: '', | ||||
|     email: '', | ||||
|     id: 0, | ||||
|     isPwd: true, | ||||
|     lastLoginDate: '', | ||||
|     name: '', | ||||
|     nickName: '', | ||||
|     openId: '', | ||||
|     phone: '', | ||||
|     remark: '', | ||||
|     sex: 0, | ||||
|     state: 0, | ||||
|     stateLocked: true, | ||||
|     token: '', | ||||
|     userType: 0, | ||||
|   }; | ||||
|   tabs = [ | ||||
|     { | ||||
|       name: '基本设置', | ||||
|     }, | ||||
|     { | ||||
|       name: '安全设置', | ||||
|     }, | ||||
|   ]; | ||||
|   idx: any = 0; | ||||
|   constructor(public service: AccountService, private modal: ModalHelper, private http: _HttpClient, private router: Router, private modalService: NzModalService,) {} | ||||
|  | ||||
|   ngOnInit() { | ||||
|     this.initSF(); | ||||
|     this.getInfo(); | ||||
|   } | ||||
|   initSF() { | ||||
|     this.schema = { | ||||
|       properties: { | ||||
|         avatar: { | ||||
|           type: 'string', | ||||
|           title: '头像', | ||||
|           ui: { | ||||
|             action: `/cms/upload/multipartFile/fileModel?_allow_anonymous=true`, | ||||
|             fileType: 'image/png,image/jpeg,image/jpg,image/png,image/gif,image/bmp', | ||||
|             limit: 1, | ||||
|             limitFileCount: 1, | ||||
|             resReName: 'url', | ||||
|             urlReName: 'url', | ||||
|             widget: 'upload', | ||||
|             descriptionI18n: '支持JPG、GIF、PNG、JPEG、BMP格式,文件小于2M', | ||||
|             data: { | ||||
|               // appId: environment.appId, | ||||
|             }, | ||||
|             name: 'multipartFile', | ||||
|             multiple: false, | ||||
|             listType: 'picture-card', | ||||
|             change: (args: any) => { | ||||
|               if (args.type === 'success') { | ||||
|                 const avatar = [ | ||||
|                   { | ||||
|                     uid: -1, | ||||
|                     name: 'LOGO', | ||||
|                     status: 'done', | ||||
|                     url: args.fileList[0].response.url, | ||||
|                     response: { | ||||
|                       url: args.fileList[0].response.url, | ||||
|                     }, | ||||
|                   }, | ||||
|                 ]; | ||||
|                 this.sf?.setValue('/avatar', avatar); | ||||
|               } | ||||
|             }, | ||||
|             beforeUpload: (file: any, _fileList) => { | ||||
|               return new Observable((observer: Observer<boolean>) => { | ||||
|                 const isLt2M = file.size / 1024 / 1024 < 2; | ||||
|                 if (!isLt2M) { | ||||
|                   this.service.msgSrv.warning('图片大小超过2M!'); | ||||
|                   observer.complete(); | ||||
|                   return; | ||||
|                 } | ||||
|                 observer.next(isLt2M); | ||||
|                 observer.complete(); | ||||
|               }); | ||||
|             }, | ||||
|           } as SFUploadWidgetSchema, | ||||
|         }, | ||||
|         nickName: { | ||||
|           title: '昵称', | ||||
|           type: 'string', | ||||
|           minLength: 1, | ||||
|           maxLength: 18, | ||||
|           ui: { | ||||
|             placeholder: '请输入昵称', | ||||
|             width: 400, | ||||
|             errors: { | ||||
|               required: '请输入昵称', | ||||
|             }, | ||||
|           }, | ||||
|         }, | ||||
|       }, | ||||
|       required: ['nickName', 'avatar'], | ||||
|     }; | ||||
|     this.ui = { | ||||
|       '*': { | ||||
|         spanLabel: 5, | ||||
|         grid: { span: 24 }, | ||||
|       }, | ||||
|     }; | ||||
|   } | ||||
|   getInfo() { | ||||
|     this.service.http.post(this.service.$api_get_current_user_info).subscribe((res) => { | ||||
|       this.infoData = res.data; | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   edit(tpye: string) { | ||||
|     if (tpye === 'phone') { | ||||
|       const modalRef = this.modalService.create({ | ||||
|         nzTitle: '验证手机号码', | ||||
|         nzContent: AccountComponentsEditNameComponent, | ||||
|         nzComponentParams: { | ||||
|           i: this.infoData | ||||
|          }, | ||||
|          nzFooter: null | ||||
|       }); | ||||
|       modalRef.afterClose.subscribe((result: any) => { | ||||
|         if (result === true) { | ||||
|           // this.st.load(1); | ||||
|         } | ||||
|       }); | ||||
|     } | ||||
|     if (tpye === 'password') { | ||||
|  | ||||
|     const modalRef = this.modalService.create({ | ||||
|       nzTitle: '设置/修改登录密码', | ||||
|       nzContent: AccountComponentsCenterEditComponent, | ||||
|       nzComponentParams: { | ||||
|         record: this.infoData | ||||
|        }, | ||||
|     }); | ||||
|     modalRef.afterClose.subscribe((result: any) => { | ||||
|       if (result === true) { | ||||
|         // this.st.load(1); | ||||
|       } | ||||
|     }); | ||||
|     } | ||||
|     // if (tpye === 'info') { | ||||
|     //   this.router.navigate(['/account/editInfo'], { | ||||
|     //     queryParams: { realName: this.infoData.realName, certificateNumber: this.infoData.certificateNumber }, | ||||
|     //   }); | ||||
|     // } | ||||
|     // if (tpye === 'name') { | ||||
|     //   this.modal | ||||
|     //     .createStatic(AccountComponentsEditNameComponent, { i: { name: this.infoData.name, phone: this.infoData.phone } }) | ||||
|     //     .subscribe(() => { | ||||
|     //       this.getInfo(); | ||||
|     //       // this.st.reload(); | ||||
|     //     }); | ||||
|     // } | ||||
|   } | ||||
|  | ||||
|   changeType(type: number): void { | ||||
|     this.idx = type; | ||||
|   } | ||||
|  | ||||
|   formSubmit(value: any): void { | ||||
|     const params = { ...value }; | ||||
|     this.service.request(`${this.service.$api_get_current_user_info}`, params).subscribe((res) => { | ||||
|       if (res === true) { | ||||
|         this.service.msgSrv.success('保存成功'); | ||||
|         this.getInfo(); | ||||
|         // this.initSF(); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,75 @@ | ||||
| <!-- | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2021-11-29 11:06:01 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-01-18 17:14:39 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\account\\components\\edit-name\\edit-name.component.html | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
| --> | ||||
|  | ||||
| <sf #sf [compact]="true" [ui]="ui" [schema]="schema" [button]="'none'" [formData]="formData"> | ||||
|   <ng-template sf-template="smsVerifyCode" let-me let-ui="ui" let-schema="schema"> | ||||
|     <div class="valid-code"> | ||||
|       <input | ||||
|         type="text" | ||||
|         maxlength="6" | ||||
|         nz-input | ||||
|         [ngModel]="me.formProperty.value" | ||||
|         (ngModelChange)="me.setValue($event)" | ||||
|         placeholder="请输入验证码" | ||||
|       /> | ||||
|       <button class="btn-code" nz-button nzType="link" [disabled]="count > 0"  (click)="getCaptcha()"> | ||||
|         {{ count > 0 ? '请等待' + count + 's' : '获取验证码' }} | ||||
|       </button> | ||||
|     </div> | ||||
|   </ng-template> | ||||
| </sf> | ||||
|  | ||||
| <div class="modal-footer"> | ||||
|   <button nz-button type="button" (click)="close()">关闭</button> | ||||
|   <button nz-button type="button" nzType="primary" (click)="submitForm()" [disabled]="!sf.valid">下一步</button> | ||||
| </div> | ||||
|  | ||||
| <nz-modal [(nzVisible)]="isVisibleView"  [nzWidth]="600" [nzFooter]="nzModalFooterview" nzTitle="修改手机号码" (nzOnOk)="handleOK()" (nzOnCancel)="handleCancel('1')"> | ||||
|   <ng-container *nzModalContent> | ||||
|     <sf #sfView [schema]="schemaView" [ui]="uiView" [compact]="true" [button]="'none'"> | ||||
|       <ng-template sf-template="smsVerifyCode" let-me let-ui="uiView" let-schema="schemaView"> | ||||
|         <div style="position: relative;"> | ||||
|           <input | ||||
|             type="text" | ||||
|             maxlength="6" | ||||
|             nz-input | ||||
|             [ngModel]="me.formProperty.value" | ||||
|             (ngModelChange)="me.setValue($event)" | ||||
|             placeholder="请输入验证码" | ||||
|           /> | ||||
|           <button style="position: absolute; | ||||
|           top: 0; | ||||
|           right: 0; | ||||
|           z-index: 9;" nz-button nzType="link" [disabled]="count2 > 0"  (click)="getCaptcha2()"> | ||||
|             {{ count2 > 0 ? '请等待' + count2 + 's' : '获取验证码' }} | ||||
|           </button> | ||||
|         </div> | ||||
|       </ng-template> | ||||
|     </sf> | ||||
|   </ng-container> | ||||
|   <ng-template #nzModalFooterview> | ||||
|     <button nz-button nzType="default" (click)="handleCancel('1')">取消</button> | ||||
|     <button nz-button nzType="primary" (click)="handleNew()">确定</button> | ||||
|   </ng-template> | ||||
| </nz-modal> | ||||
| <nz-modal [(nzVisible)]="isVisibleOk"  [nzWidth]="600"   (nzOnCancel)="handleCancel('1')" [nzFooter]='null' > | ||||
|   <ng-container *nzModalContent> | ||||
|     <nz-result | ||||
|     nzStatus="success" | ||||
|     nzTitle="修改成功!" | ||||
|     nzSubTitle="您已绑定新手机号,以后可用新手机号登录!" | ||||
|   > | ||||
|     <div nz-result-extra> | ||||
|       <button nz-button nzType="primary" (click)="handleCancel('3')">确定</button> | ||||
|     </div> | ||||
|   </nz-result> | ||||
|   </ng-container> | ||||
| </nz-modal> | ||||
| @ -0,0 +1,20 @@ | ||||
| :host { | ||||
|   .valid-code { | ||||
|     position: relative; | ||||
|   } | ||||
|   .btn-code { | ||||
|     position: absolute; | ||||
|     top: 0; | ||||
|     right: 0; | ||||
|     z-index: 9; | ||||
|   } | ||||
|   .valid-code2 { | ||||
|     position: relative; | ||||
|   } | ||||
|   .btn-code2 { | ||||
|     position: absolute; | ||||
|     top: 0; | ||||
|     right: 0; | ||||
|     z-index: 9; | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,34 @@ | ||||
| /* | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2021-11-29 11:06:01 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-01-18 17:14:44 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\account\\components\\edit-name\\edit-name.component.spec.ts | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
|  */ | ||||
|  | ||||
| import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | ||||
| import { AccountComponentsEditNameComponent } from './edit-name.component'; | ||||
|  | ||||
| describe('AccountComponentsEditNameComponent', () => { | ||||
|   let component: AccountComponentsEditNameComponent; | ||||
|   let fixture: ComponentFixture<AccountComponentsEditNameComponent>; | ||||
|  | ||||
|   beforeEach(async(() => { | ||||
|     TestBed.configureTestingModule({ | ||||
|       declarations: [AccountComponentsEditNameComponent], | ||||
|     }).compileComponents(); | ||||
|   })); | ||||
|  | ||||
|   beforeEach(() => { | ||||
|     fixture = TestBed.createComponent(AccountComponentsEditNameComponent); | ||||
|     component = fixture.componentInstance; | ||||
|     fixture.detectChanges(); | ||||
|   }); | ||||
|  | ||||
|   it('should create', () => { | ||||
|     expect(component).toBeTruthy(); | ||||
|   }); | ||||
| }); | ||||
| @ -0,0 +1,271 @@ | ||||
| import { AfterViewInit, ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core'; | ||||
| import { ErrorData, SFComponent, SFSchema, SFStringWidgetSchema, SFUISchema } from '@delon/form'; | ||||
| import { _HttpClient } from '@delon/theme'; | ||||
| // import { CaptchaComponent } from '@shared'; | ||||
| import { NzMessageService } from 'ng-zorro-antd/message'; | ||||
| import { NzModalRef } from 'ng-zorro-antd/modal'; | ||||
| import { interval, Observable, Observer } from 'rxjs'; | ||||
| import { take } from 'rxjs/operators'; | ||||
| import { AccountService } from '../../services/account.service'; | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-account-components-edit-name', | ||||
|   templateUrl: './edit-name.component.html', | ||||
|   styleUrls: ['./edit-name.component.less'], | ||||
| }) | ||||
| export class AccountComponentsEditNameComponent implements OnInit, AfterViewInit { | ||||
|   // @ViewChild('dun', { static: false }) | ||||
|   // private dun!: CaptchaComponent; | ||||
|   @ViewChild('sf', { static: false }) sf!: SFComponent; | ||||
|   @ViewChild('sfView', { static: false }) sfView!: SFComponent; | ||||
|   record: any = {}; | ||||
|   i: any; | ||||
|   schema!: SFSchema; | ||||
|   schemaView!: SFSchema; | ||||
|   ui!: SFUISchema; | ||||
|   uiView: SFUISchema = {}; | ||||
|   isVisibleView = false; | ||||
|   isVisibleOk = false; | ||||
|   formData: any = {}; | ||||
|   count = 0; | ||||
|   count2 = 0; | ||||
|   oldName: any; | ||||
|   voucher: any; | ||||
|   codeTips: any; | ||||
|   interval$: any; | ||||
|  | ||||
|   constructor(private modal: NzModalRef, public msgSrv: NzMessageService, public http: _HttpClient, public service: AccountService,private cdr: ChangeDetectorRef,) {} | ||||
|   ngAfterViewInit(): void { | ||||
|     // this.dun.init(); | ||||
|   } | ||||
|  | ||||
|   ngOnInit() { | ||||
|     this.codeTips = '为了账户安全,需您的手机验证(' + this.i?.phone + ')'; | ||||
|     this.formData.oldName = this.i?.phone; | ||||
|     this.initSF(); | ||||
|     this.initSFNew(); | ||||
|     // this.getInfo(); | ||||
|   } | ||||
|   initSF() { | ||||
|     this.schema = { | ||||
|       properties: { | ||||
|         oldName: { | ||||
|           title: '手机号', | ||||
|           type: 'string', | ||||
|           default: this.formData?.oldName, | ||||
|           ui: { | ||||
|             widget: 'text', | ||||
|           }, | ||||
|         }, | ||||
|         // userName: { | ||||
|         //   title: '用户名(新)', | ||||
|         //   type: 'string', | ||||
|         //   minLength: 3, | ||||
|         //   maxLength: 30, | ||||
|         //   description: '3-30个字符,支持中英文、数字、符号“_”和“-”,只能修改一次', | ||||
|         //   ui: { | ||||
|         //     placeholder: '请输入新用户名', | ||||
|         //     errors: { | ||||
|         //       required: '请输入新用户名', | ||||
|         //     }, | ||||
|         //   } as SFStringWidgetSchema, | ||||
|         // }, | ||||
|         smsVerifyCode: { | ||||
|           title: '验证码', | ||||
|           type: 'string', | ||||
|           maxLength: 6, | ||||
|           minLength: 6, | ||||
|           description: this.codeTips, | ||||
|           ui: { | ||||
|             widget: 'custom', | ||||
|             placeholder: '请输入验证码', | ||||
|             errors: { | ||||
|               required: '请输入6位数字验证码', | ||||
|               minLength: '请输入6位数字验证码', | ||||
|             }, | ||||
|           }, | ||||
|         }, | ||||
|       }, | ||||
|       required: ['userName', 'smsVerifyCode'], | ||||
|     }; | ||||
|     this.ui = { | ||||
|       '*': { | ||||
|         spanLabelFixed: 100, | ||||
|         grid: { span: 24 }, | ||||
|       }, | ||||
|     }; | ||||
|   } | ||||
|   initSFNew() { | ||||
|     this.schemaView = { | ||||
|       properties: { | ||||
|         phone: { | ||||
|           title: '新手机号', | ||||
|           type: 'string', | ||||
|           format: 'mobile', | ||||
|           maxLength: 11, | ||||
|           ui: { | ||||
|             placeholder: '请输入新手机号', | ||||
|             errors: { | ||||
|               required: '请输入新手机号', | ||||
|             }, | ||||
|           } as SFStringWidgetSchema, | ||||
|         }, | ||||
|         smsVerifyCode: { | ||||
|           title: '验证码', | ||||
|           type: 'string', | ||||
|           maxLength: 6, | ||||
|           minLength: 6, | ||||
|           ui: { | ||||
|             widget: 'custom', | ||||
|             placeholder: '请输入验证码', | ||||
|             errors: { | ||||
|               required: '请输入6位验证码', | ||||
|               minLength: '请输入6位验证码', | ||||
|             }, | ||||
|           }, | ||||
|         }, | ||||
|       }, | ||||
|       required: ['phone', 'smsVerifyCode'], | ||||
|     }; | ||||
|     this.uiView = { | ||||
|       '*': { | ||||
|         spanLabelFixed: 100, | ||||
|         grid: { span: 24 }, | ||||
|       }, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   getCaptcha() { | ||||
|     const params = { | ||||
|       // phoneNumber: phone | ||||
|     }; | ||||
|     this.service.request(this.service.$api_get_current_user_smVerification, params, 'POST', true, 'FORM').subscribe((res) => { | ||||
|       // code==503046 弹出网易盾 | ||||
|       if (res && res.code === '1') { | ||||
|         this.service.msgSrv.success('发送成功'); | ||||
|         this.createInterval(); | ||||
|       } else if (res.code === '503046') { | ||||
|         // this.dun.popUp(); | ||||
|       } else { | ||||
|         this.service.msgSrv.success(res.msg); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   getCaptcha2() { | ||||
|     const params = { | ||||
|       phoneNumber: this.sfView.value.phone | ||||
|     }; | ||||
|     this.service.request(this.service.$api_get_getSMVerificationCode, params, 'POST', true, 'FORM').subscribe((res) => { | ||||
|       // code==503046 弹出网易盾 | ||||
|       if (res && res.code === '1') { | ||||
|         this.service.msgSrv.success('发送成功'); | ||||
|         this.createInterval2(); | ||||
|       } else if (res.code === '503046') { | ||||
|         // this.dun.popUp(); | ||||
|       } else { | ||||
|         this.service.msgSrv.success(res.msg); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   // /* code倒计时 */ | ||||
|   // codeCountDown() { | ||||
|   //   this.count = 59; | ||||
|   //   this.interval$ = setInterval(() => { | ||||
|   //     this.count -= 1; | ||||
|   //     if (this.count <= 0) { | ||||
|   //       clearInterval(this.interval$); | ||||
|   //     } | ||||
|   //   }, 1000); | ||||
|   // } | ||||
|   private createInterval() { | ||||
|     this.count = 59; | ||||
|     interval(1000) | ||||
|       .pipe(take(60)) | ||||
|       .subscribe((x: any) => { | ||||
|         this.count = 59 - (x + 1); | ||||
|         this.cdr.detectChanges(); | ||||
|       }); | ||||
|   } | ||||
|   private createInterval2() { | ||||
|     this.count2 = 59; | ||||
|     interval(1000) | ||||
|       .pipe(take(60)) | ||||
|       .subscribe((x: any) => { | ||||
|         this.count2 = 59 - (x + 1); | ||||
|         this.cdr.detectChanges(); | ||||
|       }); | ||||
|   } | ||||
|   // codeCountDown2() { | ||||
|   //   this.count2 = 59; | ||||
|   //   this.interval$ = setInterval(() => { | ||||
|   //     this.count2 -= 1; | ||||
|   //     if (this.count <= 0) { | ||||
|   //       clearInterval(this.interval$); | ||||
|   //     } | ||||
|   //   }, 1000); | ||||
|   // } | ||||
|   /* 网易盾验证通过 */ | ||||
|   captchaDone(validate: any) { | ||||
|     this.createInterval(); | ||||
|   } | ||||
|  | ||||
|   getInfo() { | ||||
|     const params = { | ||||
|       // id: this.i.id, | ||||
|     }; | ||||
|     this.service.http.post(this.service.$api_get_current_user_info, params).subscribe((res) => { | ||||
|       // if (res) { | ||||
|       //   this.getCaptcha(res.data.phone); | ||||
|       // } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   close() { | ||||
|     this.modal.destroy(); | ||||
|   } | ||||
|   submitForm() { | ||||
|     const params = { | ||||
|       smsVerifyCode: this.sf.value.smsVerifyCode, | ||||
|     }; | ||||
|  | ||||
|     this.service.http.post(this.service.$api_get_verifyPhone, params).subscribe((res) => { | ||||
|       if (res.success) { | ||||
|         // this.modal.close(true); | ||||
|         this.voucher = res.data.voucher | ||||
|          this.isVisibleView = true | ||||
|       } else { | ||||
|         this.service.msgSrv.error(res.msg) | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|   handleCancel(type: string) { | ||||
|      if(type === '1') { | ||||
|       this.isVisibleView = false | ||||
|     } else if(type === '2') { | ||||
|     console.log(type) | ||||
|     } else if(type === '3') { | ||||
|     this.modal.close() | ||||
|     } | ||||
|   } | ||||
|   handleOK() { | ||||
|      | ||||
|   } | ||||
|   handleNew() { | ||||
|     if(!this.sfView.valid) { | ||||
|       return; | ||||
|     } | ||||
|     const params = { | ||||
|       voucher: this.voucher, | ||||
|       ...this.sfView.value, | ||||
|     } | ||||
|     this.service.http.post(this.service.$api_set_voucherUpdatePhone, params).subscribe((res) => { | ||||
|       if (res.success) { | ||||
|         this.isVisibleOk = true; | ||||
|       } else { | ||||
|         this.service.msgSrv.error(res.msg) | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,94 @@ | ||||
| <!-- | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2021-11-29 13:50:46 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-01-18 17:14:50 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\account\\components\\edit-password\\edit-password.component.html | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
| --> | ||||
|  | ||||
| <nz-alert style="margin-bottom: 15px;" nzType="info" nzMessage="密码为字母和数字组成的8-16个字符,支持符号“_”和“-”。" nzShowIcon></nz-alert> | ||||
| <form nz-form [formGroup]="validateForm"> | ||||
|   <nz-form-item> | ||||
|     <nz-form-label nzRequired>新密码</nz-form-label> | ||||
|     <nz-form-control nzErrorTip="密码格式错误"> | ||||
|       <nz-input-group [nzSuffix]="suffixTemplate"  name='passWord'> | ||||
|         <input | ||||
|           [type]="passwordVisible ? 'text' : 'password'" | ||||
|           nz-input | ||||
|           placeholder="请输入新密码" | ||||
|           [(ngModel)]="password" | ||||
|           formControlName="passWord" | ||||
|         /> | ||||
|       </nz-input-group> | ||||
|       <ng-template #suffixTemplate> | ||||
|         <i nz-icon [nzType]="passwordVisible ? 'eye-invisible' : 'eye'" (click)="passwordVisible = !passwordVisible"></i> | ||||
|       </ng-template> | ||||
|     </nz-form-control> | ||||
|   </nz-form-item> | ||||
|   <nz-form-item> | ||||
|     <nz-form-label nzRequired>确认新密码</nz-form-label> | ||||
|     <nz-form-control nzErrorTip="密码不一致"> | ||||
|       <nz-input-group [nzSuffix]="suffixTemplate2"   name='passWordTo'> | ||||
|         <input | ||||
|           [type]="passwordVisible2 ? 'text' : 'password'" | ||||
|           nz-input | ||||
|           formControlName="passWordTo" | ||||
|           placeholder="请确认输入新密码" | ||||
|           [(ngModel)]="password2" | ||||
|         /> | ||||
|       </nz-input-group> | ||||
|       <ng-template #suffixTemplate2> | ||||
|         <i nz-icon [nzType]="passwordVisible2 ? 'eye-invisible' : 'eye'" (click)="passwordVisible2 = !passwordVisible2"></i> | ||||
|       </ng-template> | ||||
|     </nz-form-control> | ||||
|   </nz-form-item> | ||||
|   <nz-form-item> | ||||
|     <nz-form-label nzRequired>手机号</nz-form-label> | ||||
|    {{this.record?.phone}} | ||||
|   </nz-form-item>  | ||||
|    <nz-form-item> | ||||
|     <nz-form-label | ||||
|       nzFor="smsVerifyCode" | ||||
|       nzRequired | ||||
|       [nzTooltipIcon]="captchaTooltipIcon" | ||||
|     > | ||||
|       验证码 | ||||
|     </nz-form-label> | ||||
|     <nz-form-control | ||||
|       [nzSm]="14" | ||||
|       [nzXs]="24" | ||||
|     > | ||||
|       <div nz-row [nzGutter]="8"> | ||||
|         <div nz-col [nzSpan]="12"> | ||||
|           <input nz-input [maxlength]="6" formControlName="smsVerifyCode" id="smsVerifyCode" /> | ||||
|         </div> | ||||
|         <div nz-col [nzSpan]="12" style="display: flex; align-items: center;"> | ||||
|           <button nz-button *ngIf="count < 1;" (click)="getCaptcha($event)">获取验证码</button> | ||||
|           <span *ngIf="count > 1;">{{ count > 0 ? '请等待' + count + 's' : '获取验证码' }}</span> | ||||
|         </div> | ||||
|       </div> | ||||
|     </nz-form-control> | ||||
|   </nz-form-item> | ||||
| </form> | ||||
| <div *nzModalFooter> | ||||
|   <button nz-button nzType="default" (click)="destroyModal()">取消</button> | ||||
|   <button nz-button nzType="primary" (click)="save()" >确定</button> | ||||
| </div> | ||||
|  | ||||
|  | ||||
| <nz-modal [(nzVisible)]="isVisibleView"  [nzWidth]="600"   (nzOnCancel)="handleCancel()" [nzFooter]='null' > | ||||
|   <ng-container *nzModalContent> | ||||
|     <nz-result | ||||
|     nzStatus="success" | ||||
|     nzTitle="密码设置成功!" | ||||
|     nzSubTitle="请牢记您的新密码,修改密码后需重新登录,3秒后自动跳转至登录页..." | ||||
|   > | ||||
|     <div nz-result-extra> | ||||
|       <button nz-button nzType="primary" (click)="handleOK()">重新登录</button> | ||||
|     </div> | ||||
|   </nz-result> | ||||
|   </ng-container> | ||||
| </nz-modal> | ||||
| @ -0,0 +1,130 @@ | ||||
| /* | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2021-12-27 10:30:56 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-01-18 17:14:54 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\account\\components\\edit-password\\edit-password.component.ts | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
|  */ | ||||
|  | ||||
| import { Component, Inject, OnInit, ViewChild } from '@angular/core'; | ||||
| import { FormBuilder, FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms'; | ||||
| import { ActivatedRoute, Router } from '@angular/router'; | ||||
| import { STChange, STColumn, STComponent, STData, STRequestOptions } from '@delon/abc/st'; | ||||
| import { DA_SERVICE_TOKEN, ITokenService } from '@delon/auth'; | ||||
|  | ||||
| import { SFComponent, SFSchema, SFSelectWidgetSchema, SFUISchema } from '@delon/form'; | ||||
| import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd/drawer'; | ||||
| import { NzFormTooltipIcon } from 'ng-zorro-antd/form'; | ||||
| import { NzModalRef } from 'ng-zorro-antd/modal'; | ||||
| import { AccountService } from '../../services/account.service'; | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-account-components-edit', | ||||
|   templateUrl: './edit-password.component.html' | ||||
| }) | ||||
| export class AccountComponentsCenterEditComponent implements OnInit { | ||||
|   validateForm!: FormGroup; | ||||
|   record: any; | ||||
|   count = 0; | ||||
|   type = 'create'; | ||||
|   isVisibleView = false | ||||
|   passwordVisible = false; | ||||
|   passwordVisible2 = false; | ||||
|   password: any; | ||||
|   password2: any; | ||||
|   interval$: any; | ||||
|   confirmationValidator = | ||||
|  (control: FormControl): { [s: string]: boolean } => { | ||||
|     if (!control.value) { | ||||
|       return { required: true }; | ||||
|     } else if (control?.value !== this.validateForm?.value?.passWord) { | ||||
|       return { confirm: true, error: true }; | ||||
|     } | ||||
|     return {}; | ||||
|   }; | ||||
|   captchaTooltipIcon: NzFormTooltipIcon = { | ||||
|     type: 'info-circle', | ||||
|     theme: 'twotone' | ||||
|   }; | ||||
|   constructor( | ||||
|     public router: Router, | ||||
|     public ar: ActivatedRoute, | ||||
|     private modalRef: NzModalRef, | ||||
|     private fb: FormBuilder, | ||||
|     public service: AccountService, | ||||
|     @Inject(DA_SERVICE_TOKEN) private tokenService: ITokenService | ||||
|   ) {} | ||||
|  | ||||
|   ngOnInit() { | ||||
|     this.initForm(); | ||||
|   } | ||||
|   initForm () { | ||||
|   this.validateForm = this.fb.group({ | ||||
|     passWord: [null, | ||||
|           [ | ||||
|         Validators.required, | ||||
|         Validators.maxLength(16), | ||||
|         Validators.minLength(8), | ||||
|         Validators.pattern('^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z-_]{8,16}$') | ||||
|       ]], | ||||
|     passWordTo: [null, [ Validators.required, Validators.maxLength(16), Validators.minLength(8), this.confirmationValidator,]], | ||||
|     smsVerifyCode: [null, [Validators.required]], | ||||
|   }); | ||||
| } | ||||
|   destroyModal(): void { | ||||
|     this.modalRef.destroy(); | ||||
|   } | ||||
|   getCaptcha(e: MouseEvent): void { | ||||
|     this.service.request(this.service.$api_get_current_user_smVerification).subscribe(res => { | ||||
|       // code==503046 弹出网易盾 | ||||
|       if (res && res.code === '1') { | ||||
|         this.service.msgSrv.success('发送成功'); | ||||
|         e.preventDefault(); | ||||
|         this.codeCountDown(); | ||||
|       }else { | ||||
|         this.service.msgSrv.success(res.msg); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|   save() { | ||||
|     if(!this.validateForm.valid) { | ||||
|       this.service.msgSrv.warning('必填项为空或格式错误,请检查!') | ||||
|       return; | ||||
|     } | ||||
|     const params = {   | ||||
|       ...this.validateForm.value | ||||
|     }; | ||||
|     this.service.request(this.service.$api_set_phoneUpdatePassword, params).subscribe((res) => { | ||||
|       if (res) { | ||||
|         this.service.msgSrv.success('修改密码成功!'); | ||||
|         this.isVisibleView = true; | ||||
|         setTimeout(() => { | ||||
|           this.tokenService.clear(); | ||||
|           this.router.navigate(['/passport/login']) | ||||
|           this.modalRef.close() | ||||
|         }, 3000) | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|   /* code倒计时 */ | ||||
|   codeCountDown() { | ||||
|     this.count = 59; | ||||
|     this.interval$ = setInterval(() => { | ||||
|       this.count -= 1; | ||||
|       if (this.count <= 0) { | ||||
|         clearInterval(this.interval$); | ||||
|       } | ||||
|     }, 1000); | ||||
|   } | ||||
|   handleCancel() { | ||||
|      this.isVisibleView = false | ||||
|  } | ||||
|  handleOK() { | ||||
|    this.modalRef.close() | ||||
|    this.tokenService.clear(); | ||||
|    this.router.navigate(['/passport/login']) | ||||
|  } | ||||
| } | ||||
							
								
								
									
										42
									
								
								src/app/routes/account/services/account.service.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/app/routes/account/services/account.service.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | ||||
| /* | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2021-12-27 10:30:56 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-01-18 17:14:59 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\account\\services\\account.service.ts | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
|  */ | ||||
|  | ||||
| import { Injectable, Injector } from '@angular/core'; | ||||
| import { _HttpClient } from '@delon/theme'; | ||||
| import { NzMessageService } from 'ng-zorro-antd/message'; | ||||
| import { map } from 'rxjs/operators'; | ||||
| import { BaseService } from 'src/app/shared/services/core/base.service'; | ||||
| import { EAFileUtil } from 'src/app/shared/utils/file.util'; | ||||
|  | ||||
| @Injectable({ | ||||
|   providedIn: 'root', | ||||
| }) | ||||
| export class AccountService extends BaseService { | ||||
|  | ||||
|   // 获取当前登录用户详情 | ||||
|   $api_get_current_user_info = `/api/mdc/cuc/user/getUserInfo`; | ||||
|  | ||||
|   // 根据当前登录用户绑定的手机号码获取短信验证码 | ||||
|   $api_get_current_user_smVerification = `/api/mdc/pbc/smsSend/getSmVerificationCodeByToken`; | ||||
|   // 获取短信验证码 | ||||
|   $api_get_getSMVerificationCode = `/api/mdc/pbc/smsSend/getSMVerificationCode`; | ||||
|  | ||||
|   // 验证手机号 | ||||
|   $api_get_verifyPhone = `/api/mdc/cuc/userBasicInfo/forgetPassword/verifyPhone`; | ||||
|  | ||||
|   // 凭证修改手机号 | ||||
|   $api_set_voucherUpdatePhone = `/api/mdc/cuc/userBasicInfo/forgetPassword/voucherUpdatePhone`; | ||||
|   // 凭证修改密码 | ||||
|   $api_set_phoneUpdatePassword = `/api/mdc/cuc/userBasicInfo/phoneUpdatePassword`; | ||||
|   constructor(public injector: Injector) { | ||||
|     super(injector); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,40 @@ | ||||
| import { AfterViewInit, Component, OnInit } from '@angular/core'; | ||||
| import { fromEvent } from 'rxjs'; | ||||
| import { debounceTime } from 'rxjs/operators'; | ||||
|  | ||||
| @Component({ | ||||
|   template: '' | ||||
| }) | ||||
| export class BasicTableComponent implements AfterViewInit { | ||||
|   scrollY = '400px'; | ||||
|  | ||||
|   constructor() {} | ||||
|  | ||||
|   ngAfterViewInit(): void { | ||||
|     setTimeout(() => { | ||||
|       this.getScrollY(); | ||||
|     }, 100); | ||||
|     fromEvent(window, 'resize') | ||||
|       .pipe(debounceTime(100)) | ||||
|       .subscribe(event => { | ||||
|         this.getScrollY(); | ||||
|       }); | ||||
|   } | ||||
|  | ||||
|   getScrollY() { | ||||
|     const windowHeight = window.innerHeight || Math.max(document.documentElement.clientHeight, document.body.clientHeight); | ||||
|     const header = document.getElementsByTagName('layout-pro-header')?.[0]; | ||||
|     if (windowHeight && header) { | ||||
|       let scrollY = windowHeight - header.clientHeight - 35 - 49; | ||||
|       const headerWrapper = document.getElementsByTagName('page-header-wrapper')?.[0]; | ||||
|       if (headerWrapper) { | ||||
|         scrollY -= headerWrapper.clientHeight; | ||||
|       } | ||||
|       const tabset = document.getElementsByTagName('nz-tabset')?.[0]; | ||||
|       if (tabset) { | ||||
|         scrollY -= tabset.clientHeight; | ||||
|       } | ||||
|       this.scrollY = scrollY + 'px'; | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										5
									
								
								src/app/routes/commom/less/basic-board.less
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/app/routes/commom/less/basic-board.less
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| :host::ng-deep { | ||||
|     .ant-form-item { | ||||
|         margin-bottom: 0; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										42
									
								
								src/app/routes/commom/less/box.less
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/app/routes/commom/less/box.less
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | ||||
| :host::ng-deep { | ||||
|     .search-box { | ||||
|         .ant-card-body { | ||||
|             padding-bottom: 18px; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     .content-box { | ||||
|         .ant-card-body { | ||||
|             padding-top: 0; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     nz-range-picker { | ||||
|         width: 100%; | ||||
|     } | ||||
|  | ||||
|     .ant-tabs-tab-btn { | ||||
|         padding-right: 16px; | ||||
|         padding-left : 16px; | ||||
|     } | ||||
|  | ||||
|     .text-truncate { | ||||
|         white-space: normal; | ||||
|     } | ||||
|  | ||||
|     .bold { | ||||
|         .ant-statistic-title { | ||||
|             font-weight: 600; | ||||
|             color      : #000; | ||||
|             font-size  : 16px; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| .total-footer { | ||||
|     position   : absolute; | ||||
|     bottom     : 25px; | ||||
|     height     : 32px; | ||||
|     margin     : 16px 0; | ||||
|     line-height: 32px; | ||||
| } | ||||
							
								
								
									
										70
									
								
								src/app/routes/commom/less/commom-table.less
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/app/routes/commom/less/commom-table.less
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | ||||
| :host { | ||||
|   ::ng-deep { | ||||
|     nz-card { | ||||
|       margin: -24px -24px 0; | ||||
|  | ||||
|       .ant-tabs-nav { | ||||
|         margin: 0; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .ant-tabs-tab { | ||||
|       margin: 0 0 0 16px; | ||||
|       padding: 12px 0; | ||||
|     } | ||||
|  | ||||
|     .ant-table-body { | ||||
|       border-bottom: 1px solid #f0f0f0; | ||||
|     } | ||||
|  | ||||
|     .table-box { | ||||
|       .ant-card-body { | ||||
|         padding: 0; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .ant-table-pagination.ant-pagination { | ||||
|       margin: 8px; | ||||
|     } | ||||
|  | ||||
|     .ant-table-thead > tr > th, | ||||
|     .ant-table-tbody > tr > td, | ||||
|     .ant-table tfoot > tr > th, | ||||
|     .ant-table tfoot > tr > td { | ||||
|       padding: 8px; | ||||
|     } | ||||
|  | ||||
|     .ant-table.ant-table-bordered > .ant-table-container { | ||||
|       border-top: 0; | ||||
|     } | ||||
|  | ||||
|     .ant-pagination-item { | ||||
|       min-width: 24px; | ||||
|       height: 24px; | ||||
|       line-height: 21px; | ||||
|     } | ||||
|  | ||||
|     .ant-pagination-total-text { | ||||
|       height: 24px; | ||||
|       line-height: 24px; | ||||
|     } | ||||
|  | ||||
|     .ant-pagination-prev, | ||||
|     .ant-pagination-next, | ||||
|     .ant-pagination-jump-prev, | ||||
|     .ant-pagination-jump-next { | ||||
|       min-width: 24px; | ||||
|       height: 24px; | ||||
|       line-height: 21px; | ||||
|     } | ||||
|  | ||||
|     .ant-select-single:not(.ant-select-customize-input) .ant-select-selector { | ||||
|       height: 24px; | ||||
|     } | ||||
|  | ||||
|     .ant-select-single .ant-select-selector .ant-select-selection-item, | ||||
|     .ant-select-single .ant-select-selector .ant-select-selection-placeholder { | ||||
|       line-height: 21px; | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										13
									
								
								src/app/routes/commom/less/expend-but.less
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/app/routes/commom/less/expend-but.less
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| .expend-options { | ||||
|     margin-top: 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| @media (min-width: 1200px) { | ||||
|     .expend-options { | ||||
|         position : absolute; | ||||
|         right    : 0; | ||||
|         bottom   : 25px; | ||||
|         max-width: 450px; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,26 @@ | ||||
| <!-- | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-10 14:44:57 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-01-18 17:15:13 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\components\\contract-detail\\contract-detail.component.html | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
| --> | ||||
|  | ||||
| <!-- 页头 --> | ||||
| <page-header-wrapper [logo]="logo" [title]="textStatus" > | ||||
|   <ng-template #logo> | ||||
|     <button nz-button nz-tooltip nzTooltipTitle="返回上一页" (click)="goBack()"> | ||||
|       <i nz-icon nzType="left" nzTheme="outline"></i> | ||||
|     </button> | ||||
|   </ng-template> | ||||
| </page-header-wrapper> | ||||
| <nz-card> | ||||
|   <div nz-col nzSpan="20" style="overflow: scroll"> | ||||
|     <nz-card class="card-height" > | ||||
|       <div [innerHTML]="detailList?.contractContent | safehtml"></div> | ||||
|     </nz-card> | ||||
|   </div> | ||||
| </nz-card> | ||||
| @ -0,0 +1,4 @@ | ||||
| .title { | ||||
| padding-right: 4px; | ||||
| padding-left: 14px !important; | ||||
| } | ||||
| @ -0,0 +1,34 @@ | ||||
| /* | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-10 14:44:57 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-01-18 17:15:18 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\components\\contract-detail\\contract-detail.component.spec.ts | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
|  */ | ||||
|  | ||||
| import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | ||||
| import { ContractManagementDetailComponent } from './contract-detail.component'; | ||||
|  | ||||
| describe('ContractManagementDetailComponent', () => { | ||||
|   let component: ContractManagementDetailComponent; | ||||
|   let fixture: ComponentFixture<ContractManagementDetailComponent>; | ||||
|  | ||||
|   beforeEach(async(() => { | ||||
|     TestBed.configureTestingModule({ | ||||
|       declarations: [ContractManagementDetailComponent], | ||||
|     }).compileComponents(); | ||||
|   })); | ||||
|  | ||||
|   beforeEach(() => { | ||||
|     fixture = TestBed.createComponent(ContractManagementDetailComponent); | ||||
|     component = fixture.componentInstance; | ||||
|     fixture.detectChanges(); | ||||
|   }); | ||||
|  | ||||
|   it('should create', () => { | ||||
|     expect(component).toBeTruthy(); | ||||
|   }); | ||||
| }); | ||||
| @ -0,0 +1,59 @@ | ||||
| /* | ||||
|  * @Description  : | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-10 14:44:57 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-01-18 17:15:43 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\components\\contract-detail\\contract-detail.component.ts | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
|  */ | ||||
| import { DatePipe } from '@angular/common'; | ||||
| import { Component, OnInit } from '@angular/core'; | ||||
| import { ActivatedRoute, Router } from '@angular/router'; | ||||
| import { NzModalService } from 'ng-zorro-antd/modal'; | ||||
| import { ContractManagementService } from '../../services/contract-management.service'; | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-contract-management-detail-complaint', | ||||
|   templateUrl: './contract-detail.component.html', | ||||
|   styleUrls: ['./contract-detail.component.less'], | ||||
|   providers: [DatePipe] | ||||
| }) | ||||
| export class ContractManagementDetailComponent implements OnInit { | ||||
|   constructor( | ||||
|     private nzModalService: NzModalService, | ||||
|     public service: ContractManagementService, | ||||
|     public route: ActivatedRoute, | ||||
|     private datePipe: DatePipe, | ||||
|     private router: Router | ||||
|   ) {} | ||||
|   textStatus = '合同详情'; | ||||
|   name: any; | ||||
|   code: any; | ||||
|   templateHTML: any; | ||||
|   detailList: any = { | ||||
|     templateName: '' | ||||
|   }; | ||||
|   ngOnInit() { | ||||
|     this.initData(this.service.$api_contract_get); | ||||
|   } | ||||
|   goBack() { | ||||
|     window.history.go(-1); | ||||
|   } | ||||
|  | ||||
|   initData(url: string) { | ||||
|     this.service.request(url, { id: this.route.snapshot.params.id }).subscribe(res => { | ||||
|       if (res) { | ||||
|         this.detailList = res; | ||||
|         this.detailList = res; | ||||
|         let value: any = JSON.parse(res.contractParameter); | ||||
|         this.code = value['${code}']; | ||||
|         this.name = value['${name}']; | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|   cancel() { | ||||
|     window.history.go(-1); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,101 @@ | ||||
| <!-- | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-07 13:29:57 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-02-24 10:08:53 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\components\\contract-frame\\contract-frame.component.html | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
| --> | ||||
| <nz-card> | ||||
|   <div nz-row nzGutter="8"> | ||||
|     <!-- 查询字段小于或等于3个时,不显示伸缩按钮 --> | ||||
|     <div nz-col nzSpan="24" *ngIf="queryFieldCount <= 4"> | ||||
|       <sf | ||||
|         #sf | ||||
|         [schema]="schema" | ||||
|         [ui]="ui" | ||||
|         [mode]="'search'" | ||||
|         [disabled]="!sf?.valid" | ||||
|         [loading]="false" | ||||
|         (formSubmit)="st?.load(1)" | ||||
|         (formReset)="resetSF()" | ||||
|       ></sf> | ||||
|     </div> | ||||
|  | ||||
|     <!-- 查询字段大于3个时,根据展开状态调整布局 --> | ||||
|     <ng-container> | ||||
|       <div nz-col [nzSpan]="_$expand ? 24 : 18"> | ||||
|         <sf #sf [schema]="schema" [ui]="ui" [compact]="true" [button]="'none'"> | ||||
|           <ng-template sf-template="signTime" let-me let-ui="ui" let-schema="schema"> | ||||
|             <ng-template sf-template="effectiveEndTime" let-me let-ui="ui" let-schema="schema"> | ||||
|               <nz-range-picker [nzShowTime]="true" [(ngModel)]="sf.value.effectiveEndTime"></nz-range-picker> | ||||
|             </ng-template> | ||||
|             <nz-range-picker [nzShowTime]="true" [(ngModel)]="sf.value.signTime"></nz-range-picker> | ||||
|           </ng-template> | ||||
|         </sf> | ||||
|       </div> | ||||
|       <div nz-col [nzSpan]="_$expand ? 24 : 6" [class.text-right]="_$expand"> | ||||
|         <button | ||||
|           nz-button | ||||
|           nzType="primary" | ||||
|           [disabled]="!sf.valid" | ||||
|           [nzLoading]="isLoading && st.loading" | ||||
|           (click)="st?.load(1)" | ||||
|           acl | ||||
|           [acl-ability]="['CONTRACT-INDEX-listFrame']" | ||||
|           >查询</button | ||||
|         > | ||||
|         <button nz-button (click)="resetSF()">重置</button> | ||||
|         <button nz-button nzType="link" (click)="expandToggle()"> | ||||
|           {{ !_$expand ? '展开' : '收起' }} | ||||
|           <i nz-icon [nzType]="!_$expand ? 'down' : 'up'"></i> | ||||
|         </button> | ||||
|       </div> | ||||
|     </ng-container> | ||||
|   </div> | ||||
| </nz-card> | ||||
|  | ||||
| <nz-card class="content-box" nzBordered> | ||||
|   <div style="position: relative"> | ||||
|     <nz-alert | ||||
|       nzType="info" | ||||
|       [nzMessage]="'当前共' + st?.total + '行记录,已选择' + selectedRows.length + '项'" | ||||
|       nzShowIcon | ||||
|       [ngStyle]="{ margin: '0 0 1rem 0' }" | ||||
|     > | ||||
|     </nz-alert> | ||||
|   </div> | ||||
|  | ||||
|   <st | ||||
|     #st | ||||
|     [data]="service.$api_listFrame_page" | ||||
|     [columns]="columns" | ||||
|     [req]="{ method: 'POST', allInBody: true, reName: { pi: 'pageIndex', ps: 'pageSize' }, params: reqParams }" | ||||
|     [res]="{ reName: { list: 'data.records', total: 'data.total' } }" | ||||
|     [page]="{ show: true, showSize: true, pageSizes: [10, 20, 30, 50, 100, 200, 300, 500, 1000] }" | ||||
|     [loading]="service.http.loading" | ||||
|     [scroll]="{ x: '1200px', y: '370px' }" | ||||
|     (change)="stChange($event)" | ||||
|   > | ||||
|     <ng-template st-row="contractCode" let-item let-index="index"> | ||||
|       <a [routerLink]="'/contract-management/index/detail/' + item.id">{{ item?.contractCode }}</a> | ||||
|     </ng-template> | ||||
|   </st> | ||||
| </nz-card> | ||||
|  | ||||
| <ng-template #auditModal> | ||||
|   <div nz-row nzGutter="8"> | ||||
|     <div nz-col nzSpan="24" se-container [labelWidth]="80"> | ||||
|       <se [col]="1" label="备注"> | ||||
|         <textarea | ||||
|           nz-input | ||||
|           rows="3" | ||||
|           placeholder="同意可以不用填写原因 ,拒绝必须说明原因" | ||||
|           style="width: 325px; margin-left: 14px" | ||||
|         ></textarea> | ||||
|       </se> | ||||
|     </div> | ||||
|   </div> | ||||
| </ng-template> | ||||
| @ -0,0 +1,35 @@ | ||||
| :host::ng-deep { | ||||
|     .search-box { | ||||
|         .ant-card-body { | ||||
|             padding-bottom: 18px; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     .content-box { | ||||
|         .ant-card-body { | ||||
|             padding-top: 0; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     nz-range-picker { | ||||
|         width: 100%; | ||||
|     } | ||||
|  | ||||
|     .ant-tabs-tab-btn { | ||||
|         padding-right: 16px; | ||||
|         padding-left : 16px; | ||||
|     } | ||||
| } | ||||
|  | ||||
| .expend-options { | ||||
|     margin-top: 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| @media (min-width: 1200px) { | ||||
|     .expend-options { | ||||
|         z-index   : -99; | ||||
|         margin-top: -40px; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,307 @@ | ||||
| import { DatePipe } from '@angular/common'; | ||||
| import { Component, OnInit, ViewChild } from '@angular/core'; | ||||
| import { Router } from '@angular/router'; | ||||
| import { STComponent, STColumn, STChange } from '@delon/abc/st'; | ||||
| import { SFComponent, SFSchema, SFDateWidgetSchema, SFUISchema, SFSelectWidgetSchema } from '@delon/form'; | ||||
| import { ShipperBaseService } from '@shared'; | ||||
| import { NzModalService } from 'ng-zorro-antd/modal'; | ||||
| import { ContractManagementService } from '../../services/contract-management.service'; | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-contract-management-contract-frame', | ||||
|   templateUrl: './contract-frame.component.html', | ||||
|   styleUrls: ['./contract-frame.component.less'], | ||||
|   providers: [DatePipe] | ||||
| }) | ||||
| export class ContractManagementFrameComponent implements OnInit { | ||||
|   url = `/rule?_allow_anonymous=true`; | ||||
|   @ViewChild('st', { static: true }) | ||||
|   st!: STComponent; | ||||
|   @ViewChild('sf', { static: false }) | ||||
|   sf!: SFComponent; | ||||
|   @ViewChild('auditModal', { static: false }) | ||||
|   auditModal!: any; | ||||
|   schema: SFSchema = {}; | ||||
|   columns: STColumn[] = []; | ||||
|   ui: SFUISchema = {}; | ||||
|   _$expand = false; | ||||
|   selectedRows: any[] = []; | ||||
|   isLoading: boolean = false; | ||||
|   constructor( | ||||
|     public service: ContractManagementService, | ||||
|     private nzModalService: NzModalService, | ||||
|     private router: Router, | ||||
|     public shipperservice: ShipperBaseService, | ||||
|     private datePipe: DatePipe, | ||||
|       ) {} | ||||
|  | ||||
|   ngOnInit(): void { | ||||
|     this.initST(); | ||||
|     this.initSF(); | ||||
|   } | ||||
|     /** | ||||
|  * 查询参数 | ||||
|  */ | ||||
|      get reqParams() { | ||||
|       const params = { | ||||
|         ...this.sf?.value, | ||||
|       } | ||||
|       delete params.signTime; | ||||
|       delete params._$expand; | ||||
|       if(this.datePipe.transform(this.sf?.value?.signTime?.[0], 'yyyy-MM-dd HH:mm:ss') && this.datePipe.transform(this.sf?.value?.signTime?.[1], 'yyyy-MM-dd HH:mm:ss')) { | ||||
|         params.signTime = { | ||||
|           start: this.datePipe.transform(this.sf?.value?.signTime?.[0], 'yyyy-MM-dd HH:mm:ss'), | ||||
|           end: this.datePipe.transform(this.sf?.value?.signTime?.[1], 'yyyy-MM-dd HH:mm:ss'), | ||||
|          } | ||||
|       } | ||||
|       if(this.datePipe.transform(this.sf?.value?.effectiveEndTime?.[0], 'yyyy-MM-dd HH:mm:ss') && this.datePipe.transform(this.sf?.value?.effectiveEndTime?.[1], 'yyyy-MM-dd HH:mm:ss')) { | ||||
|         params.effectiveEndTime = { | ||||
|           start: this.datePipe.transform(this.sf?.value?.effectiveEndTime?.[0], 'yyyy-MM-dd HH:mm:ss'), | ||||
|           end: this.datePipe.transform(this.sf?.value?.effectiveEndTime?.[1], 'yyyy-MM-dd HH:mm:ss'), | ||||
|          } | ||||
|       } | ||||
|       return { | ||||
|         ...params | ||||
|       }; | ||||
|     } | ||||
|   /** | ||||
|    * 初始化数据列表 | ||||
|    */ | ||||
|   initST() { | ||||
|     this.columns = [ | ||||
|       { | ||||
|         title: '合同编号', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         render: 'contractCode' | ||||
|       }, | ||||
|       { | ||||
|         title: '签约对象', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'signingObjectLabel' | ||||
|       }, | ||||
|       { | ||||
|         title: '合同类型', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'contractTypeLabel' | ||||
|       }, | ||||
|       { | ||||
|         title: '合同名称', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'templateName' | ||||
|       }, | ||||
|       { title: '网络货运人', index: 'enterpriseInfoName', width: '120px', className: 'text-center' }, | ||||
|       { title: '合同对象', index: 'contractObjectName', width: '120px', className: 'text-center' }, | ||||
|       { | ||||
|         title: '有效期至', | ||||
|         className: 'text-center', | ||||
|         width: '120px', | ||||
|         index: 'effectiveEndTime' | ||||
|       }, | ||||
|       { | ||||
|         title: '签署日期', | ||||
|         className: 'text-center', | ||||
|         width: '120px', | ||||
|         index: 'signTime' | ||||
|       }, | ||||
|       { | ||||
|         title: '状态', | ||||
|         className: 'text-center', | ||||
|         width: '120px', | ||||
|         type: 'badge', | ||||
|         index: 'esignFlowStatus', | ||||
|         badge: { | ||||
|           '0': { text: '未发起', color: 'default' }, | ||||
|           '1': { text: '待签章', color: 'default' }, | ||||
|           '2': { text: '已生效', color: 'success' }, | ||||
|           '3': { text: '已撤销', color: 'warning' }, | ||||
|           '4': { text: '已作废', color: 'warning' }, | ||||
|           '5': { text: '已过期', color: 'warning' }, | ||||
|           '7': { text: '已拒签', color: 'warning' } | ||||
|         } | ||||
|       } | ||||
|     ]; | ||||
|   } | ||||
|   /** | ||||
|    * 初始化查询表单 | ||||
|    */ | ||||
|   initSF() { | ||||
|     this.schema = { | ||||
|       properties: { | ||||
|         _$expand: { type: 'boolean', ui: { hidden: true } }, | ||||
|         contractCode: { | ||||
|           type: 'string', | ||||
|           title: '合同编号' | ||||
|         }, | ||||
|         signingObject: { | ||||
|           type: 'string', | ||||
|           title: '签约对象', | ||||
|           enum: [ | ||||
|             { label: '全部', value: '' }, | ||||
|             { label: '货主', value: 1 }, | ||||
|             { label: '司机', value: 2 }, | ||||
|           ], | ||||
|           ui: { | ||||
|             widget: 'select', | ||||
|             placeholder: '请选择', | ||||
|           } | ||||
|         }, | ||||
|         contractType: { | ||||
|           title: '合同类型', | ||||
|           type: 'string', | ||||
|           default: '', | ||||
|           ui: { | ||||
|             widget: 'dict-select', | ||||
|             containsAllLable: true, | ||||
|             params: { dictKey: 'contract:type' }, | ||||
|             containAllLable:true, | ||||
|           } as SFSelectWidgetSchema, | ||||
|         }, | ||||
|         enterpriseInfoId: { | ||||
|           type: 'string', | ||||
|           title: '网络货运人', | ||||
|           ui: { | ||||
|             widget: 'select', | ||||
|             placeholder: '请选择', | ||||
|             allowClear: true, | ||||
|             visibleIf: { | ||||
|               _$expand: (value: boolean) => value | ||||
|             }, | ||||
|             asyncData: () => this.shipperservice.getNetworkFreightForwarder() | ||||
|           } | ||||
|         }, | ||||
|         contractObjectName: { | ||||
|           type: 'string', | ||||
|           title: '合同对象', | ||||
|           ui: { | ||||
|             visibleIf: { | ||||
|               _$expand: (value: boolean) => value, | ||||
|             }, | ||||
|           } | ||||
|         }, | ||||
|         signTime: { | ||||
|           title: '签署日期', | ||||
|           type: 'string', | ||||
|           ui: { | ||||
|             widget: 'custom', | ||||
|             visibleIf: { | ||||
|               _$expand: (value: boolean) => value, | ||||
|             }, | ||||
|           } | ||||
|         }, | ||||
|         effectiveEndTime: { | ||||
|           title: '有效期', | ||||
|           type: 'string', | ||||
|           ui: { | ||||
|             widget: 'custom', | ||||
|             visibleIf: { | ||||
|               _$expand: (value: boolean) => value, | ||||
|             }, | ||||
|           } | ||||
|         }, | ||||
|         esignFlowStatus: { | ||||
|           title: '状态', | ||||
|           type: 'string', | ||||
|           default: '', | ||||
|           ui: { | ||||
|             widget: 'dict-select', | ||||
|             containsAllLable: true, | ||||
|             params: { dictKey: 'esign:flow:status' }, | ||||
|             containAllLable:true, | ||||
|             visibleIf: { | ||||
|               _$expand: (value: boolean) => value, | ||||
|             }, | ||||
|           } as SFSelectWidgetSchema, | ||||
|         }, | ||||
|       }, | ||||
|       type: 'object' | ||||
|     }; | ||||
|     this.ui = { '*': { spanLabelFixed: 110, grid: { span: 8, gutter: 4 } } }; | ||||
|   } | ||||
|   /** | ||||
|    * 查询字段个数 | ||||
|    */ | ||||
|   get queryFieldCount(): number { | ||||
|     return Object.keys(this.schema?.properties || {}).length; | ||||
|   } | ||||
|   stChange(e: STChange): void { | ||||
|     switch (e.type) { | ||||
|       case 'checkbox': | ||||
|         this.selectedRows = e.checkbox!; | ||||
|         break; | ||||
|       case 'filter': | ||||
|         this.st.load(); | ||||
|         break; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   approval(): void {} | ||||
|  | ||||
|   add(): void {} | ||||
|  | ||||
|   routeTo(item: any) { | ||||
|     this.router.navigate(['/ticket/invoice-requested-detail/1']); | ||||
|   } | ||||
|  | ||||
|   auditAction(item: any) { | ||||
|     const modal = this.nzModalService.create({ | ||||
|       nzTitle: '审核', | ||||
|       nzContent: this.auditModal, | ||||
|       nzFooter: [ | ||||
|         { | ||||
|           label: '拒绝', | ||||
|           type: 'default', | ||||
|           onClick: () => { | ||||
|             modal.destroy(); | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           label: '通过', | ||||
|           type: 'primary', | ||||
|           onClick: () => { | ||||
|             modal.destroy(); | ||||
|           } | ||||
|         } | ||||
|       ] | ||||
|     }); | ||||
|     modal.afterClose.subscribe(res => { | ||||
|       this.st.load(); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   showReason(item: any) { | ||||
|     const modal = this.nzModalService.create({ | ||||
|       nzTitle: '查看原因', | ||||
|       nzContent: '运单数据异常,暂时无法开票,请联系客服400-xxxx-xxxx', | ||||
|       nzFooter: [ | ||||
|         { | ||||
|           label: '关闭', | ||||
|           type: 'primary', | ||||
|           onClick: () => { | ||||
|             modal.destroy(); | ||||
|           } | ||||
|         } | ||||
|       ] | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 重置表单 | ||||
|    */ | ||||
|   resetSF() { | ||||
|     this.sf.reset(); | ||||
|     this._$expand = false; | ||||
|     this.isLoading = true; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 伸缩查询条件 | ||||
|    */ | ||||
|   expandToggle(): void { | ||||
|     this._$expand = !this._$expand; | ||||
|     this.sf?.setValue('/_$expand', this._$expand); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,72 @@ | ||||
| <!-- | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2021-12-07 15:57:49 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-02-23 20:11:50 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\components\\contract-list\\contract-list.component.html | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
| --> | ||||
|  | ||||
| <nz-card> | ||||
|   <div nz-row nzGutter="8"> | ||||
|     <!-- 查询字段小于或等于3个时,不显示伸缩按钮 --> | ||||
|     <div nz-col nzSpan="24" *ngIf="queryFieldCount <= 4"> | ||||
|       <sf #sf [schema]="schema" [ui]="ui" [mode]="'search'" [disabled]="!sf?.valid" [loading]="false" | ||||
|         (formSubmit)="st?.load(1)" (formReset)="resetSF()"></sf> | ||||
|     </div> | ||||
|  | ||||
|     <!-- 查询字段大于3个时,根据展开状态调整布局 --> | ||||
|     <ng-container> | ||||
|       <div nz-col [nzSpan]="_$expand ? 24 : 18"> | ||||
|         <sf #sf [schema]="schema" [ui]="ui" [compact]="true" [button]="'none'"> | ||||
|           <ng-template sf-template="signTime" let-me let-ui="ui" let-schema="schema"> | ||||
|             <!-- <input placeholder="请输入1-30" type="number" [ngModel]="sf.value.description3" style="width: 200px;" nz-input /> | ||||
|               <span> 天内支付运费</span> --> | ||||
|             <nz-range-picker [nzShowTime]="true" [(ngModel)]="sf.value.signTime"></nz-range-picker> | ||||
|           </ng-template> | ||||
|         </sf> | ||||
|       </div> | ||||
|       <div nz-col [nzSpan]="_$expand ? 24 : 6" [class.text-right]="_$expand"> | ||||
|         <button nz-button nzType="primary" [disabled]="!sf.valid" [nzLoading]="isLoading && st.loading" | ||||
|           (click)="st?.load(1)"  acl  [acl-ability]="['CONTRACT-INDEX-searchDetail']">查询</button> | ||||
|         <button nz-button (click)="resetSF()">重置</button> | ||||
|         <button nz-button nzType="link" (click)="expandToggle()"> | ||||
|           {{ !_$expand ? '展开' : '收起' }} | ||||
|           <i nz-icon [nzType]="!_$expand ? 'down' : 'up'"></i> | ||||
|         </button> | ||||
|       </div> | ||||
|     </ng-container> | ||||
|   </div> | ||||
| </nz-card> | ||||
|  | ||||
| <nz-card class="content-box" nzBordered> | ||||
|   <div style="position: relative"> | ||||
|     <nz-alert nzType="info" [nzMessage]="'当前共' + st?.total + '行记录,已选择' + selectedRows.length + '项'" nzShowIcon | ||||
|       [ngStyle]="{ margin: '0 0 1rem 0' }"> | ||||
|     </nz-alert> | ||||
|   </div> | ||||
|  | ||||
|   <st #st [data]="service.$api_listDetailed_page" [columns]="columns" [req]="{  params: reqParams }" | ||||
|     [loading]="false" [scroll]="{ x: '1200px', y: '370px' }" (change)="stChange($event)"> | ||||
|     <ng-template st-row="contractCode" let-item let-index="index"> | ||||
|       <a [routerLink]="'/contract-management/index/detail/' + item.id">{{ item?.contractCode }}</a> | ||||
|     </ng-template> | ||||
|     <ng-template st-row="signingObject" let-item let-index="index"> | ||||
|      <span *ngIf="item.signingObject == 0"></span> | ||||
|      <span></span> | ||||
|     </ng-template> | ||||
|   </st> | ||||
| </nz-card> | ||||
|  | ||||
| <ng-template #auditModal> | ||||
|   <div nz-row nzGutter="8"> | ||||
|     <div nz-col nzSpan="24" se-container [labelWidth]="80"> | ||||
|       <se [col]="1" label="备注"> | ||||
|         <textarea nz-input rows="3" placeholder="同意可以不用填写原因 ,拒绝必须说明原因" | ||||
|           style="width: 325px; margin-left: 14px"></textarea> | ||||
|       </se> | ||||
|     </div> | ||||
|   </div> | ||||
| </ng-template> | ||||
| @ -0,0 +1,35 @@ | ||||
| :host::ng-deep { | ||||
|     .search-box { | ||||
|         .ant-card-body { | ||||
|             padding-bottom: 18px; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     .content-box { | ||||
|         .ant-card-body { | ||||
|             padding-top: 0; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     nz-range-picker { | ||||
|         width: 100%; | ||||
|     } | ||||
|  | ||||
|     .ant-tabs-tab-btn { | ||||
|         padding-left : 16px; | ||||
|         padding-right: 16px; | ||||
|     } | ||||
| } | ||||
|  | ||||
| .expend-options { | ||||
|     margin-top: 0px; | ||||
| } | ||||
|  | ||||
|  | ||||
| @media (min-width: 1200px) { | ||||
|     .expend-options { | ||||
|         margin-top: -40px; | ||||
|         z-index   : -99; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,248 @@ | ||||
| import { Component, OnInit, ViewChild } from '@angular/core'; | ||||
| import { Router } from '@angular/router'; | ||||
| import { STComponent, STColumn, STChange } from '@delon/abc/st'; | ||||
| import { SFComponent, SFSchema, SFDateWidgetSchema, SFUISchema, SFSelectWidgetSchema } from '@delon/form'; | ||||
| import { NzModalService } from 'ng-zorro-antd/modal'; | ||||
| import { ContractManagementService } from '../../services/contract-management.service'; | ||||
| import { DatePipe } from '@angular/common'; | ||||
| import { ShipperBaseService } from '@shared'; | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-contract-management-contract-list', | ||||
|   templateUrl: './contract-list.component.html', | ||||
|   styleUrls: ['./contract-list.component.less'], | ||||
|   providers: [DatePipe] | ||||
| }) | ||||
| export class ContractManagementContractListComponent implements OnInit { | ||||
|   url = `/rule?_allow_anonymous=true`; | ||||
|   @ViewChild('st', { static: true }) | ||||
|   st!: STComponent; | ||||
|   @ViewChild('sf', { static: false }) | ||||
|   sf!: SFComponent; | ||||
|   @ViewChild('auditModal', { static: false }) | ||||
|   auditModal!: any; | ||||
|   schema: SFSchema = {}; | ||||
|   columns: STColumn[] = []; | ||||
|   ui: SFUISchema = {}; | ||||
|   _$expand = false; | ||||
|   isLoading: boolean = false; | ||||
|   /** | ||||
|  * 查询参数 | ||||
|  */ | ||||
|   get reqParams() { | ||||
|     const params = { | ||||
|       ...this.sf?.value, | ||||
|     } | ||||
|     delete params.signTime; | ||||
|     delete params._$expand; | ||||
|     if (this.datePipe.transform(this.sf?.value?.signTime?.[0], 'yyyy-MM-dd HH:mm:ss') && this.datePipe.transform(this.sf?.value?.signTime?.[1], 'yyyy-MM-dd HH:mm:ss')) { | ||||
|       params.signTime = { | ||||
|         start: this.datePipe.transform(this.sf?.value?.signTime?.[0], 'yyyy-MM-dd HH:mm:ss'), | ||||
|         end: this.datePipe.transform(this.sf?.value?.signTime?.[1], 'yyyy-MM-dd HH:mm:ss'), | ||||
|       } | ||||
|     } | ||||
|     return { | ||||
|       ...params | ||||
|     }; | ||||
|   } | ||||
|   selectedRows: any[] = []; | ||||
|   constructor( | ||||
|     public service: ContractManagementService, | ||||
|     private nzModalService: NzModalService, | ||||
|     public shipperservice: ShipperBaseService, | ||||
|     private router: Router, | ||||
|     private datePipe: DatePipe, | ||||
|   ) { } | ||||
|  | ||||
|   ngOnInit(): void { | ||||
|     this.initST() | ||||
|     this.initSF() | ||||
|   } | ||||
|   /** | ||||
|    * 初始化数据列表 | ||||
|    */ | ||||
|   initST() { | ||||
|     this.columns = [ | ||||
|       { | ||||
|         title: '合同编号', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         render: 'contractCode' | ||||
|       }, | ||||
|       { | ||||
|         title: '签约对象', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'signingObjectLabel' | ||||
|       }, | ||||
|       { | ||||
|         title: '合同类型', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'contractName' | ||||
|       }, | ||||
|       { | ||||
|         title: '业务单号', | ||||
|         className: 'text-center', | ||||
|         width: '120px', | ||||
|         index: 'businessCode' | ||||
|       }, | ||||
|       { | ||||
|         title: '签署日期', | ||||
|         className: 'text-center', | ||||
|         width: '120px', | ||||
|         index: 'signTime' | ||||
|       }, | ||||
|       { | ||||
|         title: '状态', | ||||
|         className: 'text-center', | ||||
|         width: '120px', | ||||
|         type: 'badge', | ||||
|         index: 'esignFlowStatus', | ||||
|         badge: { | ||||
|           '0': { text: '未发起', color: 'default' }, | ||||
|           '1': { text: '待签章', color: 'default' }, | ||||
|           '2': { text: '已生效', color: 'success' }, | ||||
|           '3': { text: '已撤销', color: 'warning' }, | ||||
|           '4': { text: '已作废', color: 'warning' }, | ||||
|           '5': { text: '已过期', color: 'warning' }, | ||||
|           '7': { text: '已拒签', color: 'warning' }, | ||||
|         }, | ||||
|       }, | ||||
|  | ||||
|     ]; | ||||
|   } | ||||
|   /** | ||||
| * 初始化查询表单 | ||||
| */ | ||||
|   initSF() { | ||||
|     this.schema = { | ||||
|       properties: { | ||||
|         _$expand: { type: 'boolean', ui: { hidden: true } }, | ||||
|         contractCode: { | ||||
|           type: 'string', | ||||
|           title: '合同编号', | ||||
|         }, | ||||
|         businessCode: { | ||||
|           type: 'string', | ||||
|           title: '业务单号' | ||||
|         }, | ||||
|         shipperName: { | ||||
|           type: 'string', | ||||
|           title: '托运人' | ||||
|         }, | ||||
|         carrierName: { | ||||
|           type: 'string', | ||||
|           title: '承运人', | ||||
|           ui: { | ||||
|             visibleIf: { | ||||
|               _$expand: (value: boolean) => value, | ||||
|             }, | ||||
|           } | ||||
|         }, | ||||
|         documentType: { | ||||
|           title: '单据类型', | ||||
|           type: 'string', | ||||
|           default: '', | ||||
|           ui: { | ||||
|             widget: 'dict-select', | ||||
|             containsAllLabel: true, | ||||
|             params: { dictKey: 'contract:document:type' }, | ||||
|             containAllLable: true, | ||||
|             visibleIf: { | ||||
|               _$expand: (value: boolean) => value, | ||||
|             }, | ||||
|           } as SFSelectWidgetSchema, | ||||
|         }, | ||||
|         signTime: { | ||||
|           title: '签署日期', | ||||
|           type: 'string', | ||||
|           ui: { | ||||
|             widget: 'custom', | ||||
|             visibleIf: { | ||||
|               _$expand: (value: boolean) => value, | ||||
|             }, | ||||
|           } | ||||
|         }, | ||||
|       }, | ||||
|       type: 'object', | ||||
|     }; | ||||
|     this.ui = { '*': { spanLabelFixed: 110, grid: { span: 8, gutter: 4 } } }; | ||||
|   } | ||||
|   /** | ||||
| * 查询字段个数 | ||||
| */ | ||||
|   get queryFieldCount(): number { | ||||
|     return Object.keys(this.schema?.properties || {}).length; | ||||
|   } | ||||
|   stChange(e: STChange): void { | ||||
|     switch (e.type) { | ||||
|       case 'checkbox': | ||||
|         this.selectedRows = e.checkbox!; | ||||
|         break; | ||||
|       case 'filter': | ||||
|         this.st.load(); | ||||
|         break; | ||||
|     } | ||||
|   } | ||||
|   routeTo(item: any) { | ||||
|     this.router.navigate(['/ticket/invoice-requested-detail/1']); | ||||
|   } | ||||
|  | ||||
|   auditAction(item: any) { | ||||
|     const modal = this.nzModalService.create({ | ||||
|       nzTitle: '审核', | ||||
|       nzContent: this.auditModal, | ||||
|       nzFooter: [ | ||||
|         { | ||||
|           label: '拒绝', | ||||
|           type: 'default', | ||||
|           onClick: () => { | ||||
|             modal.destroy(); | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           label: '通过', | ||||
|           type: 'primary', | ||||
|           onClick: () => { | ||||
|             modal.destroy(); | ||||
|           } | ||||
|         } | ||||
|       ] | ||||
|     }); | ||||
|     modal.afterClose.subscribe(res => { | ||||
|       this.st.load(); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   showReason(item: any) { | ||||
|     const modal = this.nzModalService.create({ | ||||
|       nzTitle: '查看原因', | ||||
|       nzContent: '运单数据异常,暂时无法开票,请联系客服400-xxxx-xxxx', | ||||
|       nzFooter: [ | ||||
|         { | ||||
|           label: '关闭', | ||||
|           type: 'primary', | ||||
|           onClick: () => { | ||||
|             modal.destroy(); | ||||
|           } | ||||
|         } | ||||
|       ] | ||||
|     }); | ||||
|   } | ||||
|   /** | ||||
|    * 重置表单 | ||||
|    */ | ||||
|   resetSF() { | ||||
|     this.sf.reset(); | ||||
|     this._$expand = false; | ||||
|     this.isLoading = true | ||||
|   } | ||||
|   /** | ||||
|    * 伸缩查询条件 | ||||
|    */ | ||||
|   expandToggle(): void { | ||||
|     this._$expand = !this._$expand; | ||||
|     this.sf?.setValue('/_$expand', this._$expand); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,101 @@ | ||||
| <!-- | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-07 13:29:57 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-02-24 10:08:28 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\components\\contract-partner\\contract-partner.component.html | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
| --> | ||||
| <nz-card> | ||||
|   <div nz-row nzGutter="8"> | ||||
|     <!-- 查询字段小于或等于3个时,不显示伸缩按钮 --> | ||||
|     <div nz-col nzSpan="24" *ngIf="queryFieldCount <= 4"> | ||||
|       <sf | ||||
|         #sf | ||||
|         [schema]="schema" | ||||
|         [ui]="ui" | ||||
|         [mode]="'search'" | ||||
|         [disabled]="!sf?.valid" | ||||
|         [loading]="false" | ||||
|         (formSubmit)="st?.load(1)" | ||||
|         (formReset)="resetSF()" | ||||
|       ></sf> | ||||
|     </div> | ||||
|  | ||||
|     <!-- 查询字段大于3个时,根据展开状态调整布局 --> | ||||
|     <ng-container> | ||||
|       <div nz-col [nzSpan]="_$expand ? 24 : 18"> | ||||
|         <sf #sf [schema]="schema" [ui]="ui" [compact]="true" [button]="'none'"> | ||||
|           <ng-template sf-template="signTime" let-me let-ui="ui" let-schema="schema"> | ||||
|             <nz-range-picker [nzShowTime]="true" [(ngModel)]="sf.value.signTime"></nz-range-picker> | ||||
|           </ng-template> | ||||
|           <ng-template sf-template="effectiveEndTime" let-me let-ui="ui" let-schema="schema"> | ||||
|             <nz-range-picker [nzShowTime]="true" [(ngModel)]="sf.value.effectiveEndTime"></nz-range-picker> | ||||
|           </ng-template> | ||||
|         </sf> | ||||
|       </div> | ||||
|       <div nz-col [nzSpan]="_$expand ? 24 : 6" [class.text-right]="_$expand"> | ||||
|         <button | ||||
|           nz-button | ||||
|           nzType="primary" | ||||
|           [disabled]="!sf.valid" | ||||
|           [nzLoading]="service.http.loading" | ||||
|           (click)="st?.load(1)" | ||||
|           acl | ||||
|           [acl-ability]="['CONTRACT-INDEX-listFrame']" | ||||
|           >查询</button | ||||
|         > | ||||
|         <button nz-button (click)="resetSF()">重置</button> | ||||
|         <button nz-button nzType="link" (click)="expandToggle()"> | ||||
|           {{ !_$expand ? '展开' : '收起' }} | ||||
|           <i nz-icon [nzType]="!_$expand ? 'down' : 'up'"></i> | ||||
|         </button> | ||||
|       </div> | ||||
|     </ng-container> | ||||
|   </div> | ||||
| </nz-card> | ||||
|  | ||||
| <nz-card class="content-box" nzBordered> | ||||
|   <div style="position: relative"> | ||||
|     <nz-alert | ||||
|       nzType="info" | ||||
|       [nzMessage]="'当前共' + st?.total + '行记录,已选择' + selectedRows.length + '项'" | ||||
|       nzShowIcon | ||||
|       [ngStyle]="{ margin: '0 0 1rem 0' }" | ||||
|     > | ||||
|     </nz-alert> | ||||
|   </div> | ||||
|  | ||||
|   <st | ||||
|     #st | ||||
|     [data]="service.$api_listPartner_page" | ||||
|     [columns]="columns" | ||||
|     [req]="{ method: 'POST', allInBody: true, reName: { pi: 'pageIndex', ps: 'pageSize' }, params: reqParams }" | ||||
|     [res]="{ reName: { list: 'data.records', total: 'data.total' } }" | ||||
|     [page]="{ show: true, showSize: true, pageSizes: [10, 20, 30, 50, 100, 200, 300, 500, 1000] }" | ||||
|     [loading]="false" | ||||
|     [scroll]="{ x: '1200px', y: '370px' }" | ||||
|     (change)="stChange($event)" | ||||
|   > | ||||
|     <ng-template st-row="contractCode" let-item let-index="index"> | ||||
|       <a [routerLink]="'/contract-management/index/detail/' + item.id">{{ item?.contractCode }}</a> | ||||
|     </ng-template> | ||||
|   </st> | ||||
| </nz-card> | ||||
|  | ||||
| <ng-template #auditModal> | ||||
|   <div nz-row nzGutter="8"> | ||||
|     <div nz-col nzSpan="24" se-container [labelWidth]="80"> | ||||
|       <se [col]="1" label="备注"> | ||||
|         <textarea | ||||
|           nz-input | ||||
|           rows="3" | ||||
|           placeholder="同意可以不用填写原因 ,拒绝必须说明原因" | ||||
|           style="width: 325px; margin-left: 14px" | ||||
|         ></textarea> | ||||
|       </se> | ||||
|     </div> | ||||
|   </div> | ||||
| </ng-template> | ||||
| @ -0,0 +1,35 @@ | ||||
| :host::ng-deep { | ||||
|     .search-box { | ||||
|         .ant-card-body { | ||||
|             padding-bottom: 18px; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     .content-box { | ||||
|         .ant-card-body { | ||||
|             padding-top: 0; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     nz-range-picker { | ||||
|         width: 100%; | ||||
|     } | ||||
|  | ||||
|     .ant-tabs-tab-btn { | ||||
|         padding-right: 16px; | ||||
|         padding-left : 16px; | ||||
|     } | ||||
| } | ||||
|  | ||||
| .expend-options { | ||||
|     margin-top: 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| @media (min-width: 1200px) { | ||||
|     .expend-options { | ||||
|         z-index   : -99; | ||||
|         margin-top: -40px; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,305 @@ | ||||
| import { DatePipe } from '@angular/common'; | ||||
| import { Component, OnInit, ViewChild } from '@angular/core'; | ||||
| import { Router } from '@angular/router'; | ||||
| import { STComponent, STColumn, STChange } from '@delon/abc/st'; | ||||
| import { SFComponent, SFSchema, SFDateWidgetSchema, SFUISchema, SFSelectWidgetSchema } from '@delon/form'; | ||||
| import { ShipperBaseService } from '@shared'; | ||||
| import { NzModalService } from 'ng-zorro-antd/modal'; | ||||
| import { ContractManagementService } from '../../services/contract-management.service'; | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-contract-management-contract-partner', | ||||
|   templateUrl: './contract-partner.component.html', | ||||
|   styleUrls: ['./contract-partner.component.less'], | ||||
|   providers: [DatePipe] | ||||
| }) | ||||
| export class ContractManagementPartnerComponent implements OnInit { | ||||
|   url = `/rule?_allow_anonymous=true`; | ||||
|   @ViewChild('st', { static: true }) | ||||
|   st!: STComponent; | ||||
|   @ViewChild('sf', { static: false }) | ||||
|   sf!: SFComponent; | ||||
|   @ViewChild('auditModal', { static: false }) | ||||
|   auditModal!: any; | ||||
|   schema: SFSchema = {}; | ||||
|   columns: STColumn[] = []; | ||||
|   ui: SFUISchema = {}; | ||||
|   _$expand = false; | ||||
|   selectedRows: any[] = []; | ||||
|   constructor( | ||||
|     public service: ContractManagementService, | ||||
|     private nzModalService: NzModalService, | ||||
|     private router: Router, | ||||
|     public shipperservice: ShipperBaseService, | ||||
|     private datePipe: DatePipe, | ||||
|     ) {} | ||||
|  | ||||
|   ngOnInit(): void { | ||||
|     this.initST(); | ||||
|     this.initSF(); | ||||
|   } | ||||
|    /** | ||||
|  * 查询参数 | ||||
|  */ | ||||
|     get reqParams() { | ||||
|       const params = { | ||||
|         ...this.sf?.value, | ||||
|       } | ||||
|       delete params.signTime; | ||||
|       delete params._$expand; | ||||
|       if(this.datePipe.transform(this.sf?.value?.signTime?.[0], 'yyyy-MM-dd HH:mm:ss') && this.datePipe.transform(this.sf?.value?.signTime?.[1], 'yyyy-MM-dd HH:mm:ss')) { | ||||
|         params.signTime = { | ||||
|           start: this.datePipe.transform(this.sf?.value?.signTime?.[0], 'yyyy-MM-dd HH:mm:ss'), | ||||
|           end: this.datePipe.transform(this.sf?.value?.signTime?.[1], 'yyyy-MM-dd HH:mm:ss'), | ||||
|          } | ||||
|       } | ||||
|       if(this.datePipe.transform(this.sf?.value?.effectiveEndTime?.[0], 'yyyy-MM-dd HH:mm:ss') && this.datePipe.transform(this.sf?.value?.effectiveEndTime?.[1], 'yyyy-MM-dd HH:mm:ss')) { | ||||
|         params.effectiveEndTime = { | ||||
|           start: this.datePipe.transform(this.sf?.value?.effectiveEndTime?.[0], 'yyyy-MM-dd HH:mm:ss'), | ||||
|           end: this.datePipe.transform(this.sf?.value?.effectiveEndTime?.[1], 'yyyy-MM-dd HH:mm:ss'), | ||||
|          } | ||||
|       } | ||||
|       return { | ||||
|         ...params | ||||
|       }; | ||||
|     } | ||||
|   /** | ||||
|    * 初始化数据列表 | ||||
|    */ | ||||
|   initST() { | ||||
|     this.columns = [ | ||||
|       { | ||||
|         title: '合同编号', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         render: 'contractCode' | ||||
|       }, | ||||
|       { | ||||
|         title: '签约对象', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'signingObjectLabel' | ||||
|       }, | ||||
|       { | ||||
|         title: '合同类型', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'contractType' | ||||
|       }, | ||||
|       { title: '合同名称', index: 'contractName', width: '120px', className: 'text-center' }, | ||||
|       { title: '网络货运人', index: 'enterpriseInfoName', width: '120px', className: 'text-center' }, | ||||
|       { | ||||
|         title: '合同对象', | ||||
|         className: 'text-center', | ||||
|         width: '120px', | ||||
|         index: 'contractObjectName' | ||||
|       }, | ||||
|       { | ||||
|         title: '有效期至', | ||||
|         className: 'text-center', | ||||
|         width: '120px', | ||||
|         index: 'effectiveEndTime' | ||||
|       }, | ||||
|       { | ||||
|         title: '签署日期', | ||||
|         className: 'text-center', | ||||
|         width: '120px', | ||||
|         index: 'signTime' | ||||
|       }, | ||||
|       { | ||||
|         title: '状态', | ||||
|         className: 'text-center', | ||||
|         width: '120px', | ||||
|         type: 'badge', | ||||
|         index: 'esignFlowStatus', | ||||
|         badge: { | ||||
|           '0': { text: '未发起', color: 'default' }, | ||||
|           '1': { text: '待签章', color: 'default' }, | ||||
|           '2': { text: '已生效', color: 'success' }, | ||||
|           '3': { text: '已撤销', color: 'warning' }, | ||||
|           '4': { text: '已作废', color: 'warning' }, | ||||
|           '5': { text: '已过期', color: 'warning' }, | ||||
|           '7': { text: '已拒签', color: 'warning' } | ||||
|         } | ||||
|       } | ||||
|     ]; | ||||
|   } | ||||
|   /** | ||||
|    * 初始化查询表单 | ||||
|    */ | ||||
|   initSF() { | ||||
|     this.schema = { | ||||
|       properties: { | ||||
|         _$expand: { type: 'boolean', ui: { hidden: true } }, | ||||
|         contractCode: { | ||||
|           type: 'string', | ||||
|           title: '合同编号' | ||||
|         }, | ||||
|         signingObject: { | ||||
|           type: 'string', | ||||
|           title: '签约对象', | ||||
|           enum: [ | ||||
|             { label: '全部', value: '' }, | ||||
|             { label: '货主', value: 1 }, | ||||
|             { label: '司机', value: 2 } | ||||
|           ], | ||||
|           ui: { | ||||
|             widget: 'select', | ||||
|             placeholder: '请选择' | ||||
|           } | ||||
|         }, | ||||
|         contractType: { | ||||
|           title: '合同类型', | ||||
|           type: 'string', | ||||
|           default: '', | ||||
|           ui: { | ||||
|             widget: 'dict-select', | ||||
|             containsAllLable: true, | ||||
|             params: { dictKey: 'contract:type' }, | ||||
|             containAllLable: true, | ||||
|           } as SFSelectWidgetSchema | ||||
|         }, | ||||
|         enterpriseInfoId: { | ||||
|           type: 'string', | ||||
|           title: '网络货运人', | ||||
|           ui: { | ||||
|             widget: 'select', | ||||
|             placeholder: '请选择', | ||||
|             allowClear: true, | ||||
|             visibleIf: { | ||||
|               _$expand: (value: boolean) => value | ||||
|             }, | ||||
|             asyncData: () => this.shipperservice.getNetworkFreightForwarder() | ||||
|           } | ||||
|         }, | ||||
|         contractObjectName: { | ||||
|           type: 'string', | ||||
|           title: '合同对象', | ||||
|           ui: { | ||||
|             visibleIf: { | ||||
|               _$expand: (value: boolean) => value | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         signTime: { | ||||
|           title: '签署日期', | ||||
|           type: 'string', | ||||
|           ui: { | ||||
|             widget: 'custom', | ||||
|             visibleIf: { | ||||
|               _$expand: (value: boolean) => value | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         effectiveEndTime: { | ||||
|           title: '有效期', | ||||
|           type: 'string', | ||||
|           ui: { | ||||
|             widget: 'custom', | ||||
|             visibleIf: { | ||||
|               _$expand: (value: boolean) => value, | ||||
|             }, | ||||
|           } | ||||
|         }, | ||||
|         esignFlowStatus: { | ||||
|           title: '状态', | ||||
|           type: 'string', | ||||
|           default: '', | ||||
|           ui: { | ||||
|             widget: 'dict-select', | ||||
|             containsAllLable: true, | ||||
|             params: { dictKey: 'esign:flow:status' }, | ||||
|             containAllLable: true, | ||||
|             visibleIf: { | ||||
|               _$expand: (value: boolean) => value | ||||
|             } | ||||
|           } as SFSelectWidgetSchema | ||||
|         } | ||||
|       }, | ||||
|       type: 'object' | ||||
|     }; | ||||
|     this.ui = { '*': { spanLabelFixed: 110, grid: { span: 8, gutter: 4 } } }; | ||||
|   } | ||||
|   /** | ||||
|    * 查询字段个数 | ||||
|    */ | ||||
|   get queryFieldCount(): number { | ||||
|     return Object.keys(this.schema?.properties || {}).length; | ||||
|   } | ||||
|   stChange(e: STChange): void { | ||||
|     switch (e.type) { | ||||
|       case 'checkbox': | ||||
|         this.selectedRows = e.checkbox!; | ||||
|         break; | ||||
|       case 'filter': | ||||
|         this.st.load(); | ||||
|         break; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   approval(): void {} | ||||
|  | ||||
|   add(): void {} | ||||
|  | ||||
|   routeTo(item: any) { | ||||
|     this.router.navigate(['/ticket/invoice-requested-detail/1']); | ||||
|   } | ||||
|  | ||||
|   auditAction(item: any) { | ||||
|     const modal = this.nzModalService.create({ | ||||
|       nzTitle: '审核', | ||||
|       nzContent: this.auditModal, | ||||
|       nzFooter: [ | ||||
|         { | ||||
|           label: '拒绝', | ||||
|           type: 'default', | ||||
|           onClick: () => { | ||||
|             modal.destroy(); | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           label: '通过', | ||||
|           type: 'primary', | ||||
|           onClick: () => { | ||||
|             modal.destroy(); | ||||
|           } | ||||
|         } | ||||
|       ] | ||||
|     }); | ||||
|     modal.afterClose.subscribe(res => { | ||||
|       this.st.load(); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   showReason(item: any) { | ||||
|     const modal = this.nzModalService.create({ | ||||
|       nzTitle: '查看原因', | ||||
|       nzContent: '运单数据异常,暂时无法开票,请联系客服400-xxxx-xxxx', | ||||
|       nzFooter: [ | ||||
|         { | ||||
|           label: '关闭', | ||||
|           type: 'primary', | ||||
|           onClick: () => { | ||||
|             modal.destroy(); | ||||
|           } | ||||
|         } | ||||
|       ] | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 重置表单 | ||||
|    */ | ||||
|   resetSF() { | ||||
|     this.sf.reset(); | ||||
|     this._$expand = false; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 伸缩查询条件 | ||||
|    */ | ||||
|   expandToggle(): void { | ||||
|     this._$expand = !this._$expand; | ||||
|     this.sf?.setValue('/_$expand', this._$expand); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,60 @@ | ||||
| <!-- | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-05 11:01:55 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-01-18 17:16:27 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\components\\contract-template-detail\\contract-template-detail.component.html | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
| --> | ||||
|  | ||||
| <!-- 页头 --> | ||||
| <page-header-wrapper [logo]="logo" [title]="textStatus" [content]="headerContent"> | ||||
|   <ng-template #logo> | ||||
|     <button nz-button nz-tooltip nzTooltipTitle="返回上一页" (click)="goBack()"> | ||||
|       <i nz-icon nzType="left" nzTheme="outline"></i> | ||||
|     </button> | ||||
|   </ng-template> | ||||
|   <ng-template #headerContent> | ||||
|     <div nz-row style="display: flex; justify-content: end;"> | ||||
|       <div nz-col *ngIf="isUpdate"> | ||||
|         <button  nz-button nzSize="default" nzType="default" (click)="cancel()">取消</button> | ||||
|         <button class="ml-lg" nz-button nzSize="default" nzType="primary" (click)="save()">保存</button> | ||||
|       </div> | ||||
|     </div> | ||||
|   </ng-template> | ||||
| </page-header-wrapper> | ||||
|  | ||||
|  | ||||
| <nz-card > | ||||
|   <sf #sf [schema]="schema"  [formData]="sfdata" [button]="'none'" [ui]="ui"></sf> | ||||
| </nz-card> | ||||
|  | ||||
| <nz-card> | ||||
|   <div nz-col nzSpan="20" style="overflow: scroll"> | ||||
|     <nz-card class="card-height" *ngIf="!isUpdate"> | ||||
|       <div class="mb-md"> | ||||
|         <div>{{detailList?.templateName}}</div> | ||||
|       </div> | ||||
|       <div [innerHTML]="detailList?.templateContent | safehtml"></div> | ||||
|     </nz-card> | ||||
|  | ||||
|     <nz-card class="card-height" *ngIf="isUpdate"> | ||||
|       <div nz-row nzGutter="8"> | ||||
|         <div class="title"  style="width: 100%;"> | ||||
|           <input style="width: 100%;"  nz-input placeholder="请输入合同标题" [(ngModel)]="detailList.templateName" /> | ||||
|         </div> | ||||
|         <div nz-col nzSpan="24" style="margin-top: 15px;"> | ||||
|           <sf #sf2 mode="edit"  [formData]="sfdata2" [schema]="schema2" [ui]="{ '*': { spanLabelFixed: 10, grid: { span: 24 }} }" | ||||
|             button="none"> </sf> | ||||
|         </div> | ||||
|       </div> | ||||
|    | ||||
|     </nz-card> | ||||
|   </div> | ||||
| </nz-card> | ||||
| <!-- <div class="mb-md save-btn"> | ||||
|   <button nz-button nzSize="large" nzType="default" (click)="cancel()">取消</button> | ||||
|   <button class="ml-lg" nz-button nzSize="large" nzType="primary" (click)="save()">保存</button> | ||||
| </div> --> | ||||
| @ -0,0 +1,4 @@ | ||||
| .title { | ||||
| padding-right: 4px; | ||||
| padding-left: 14px !important; | ||||
| } | ||||
| @ -0,0 +1,34 @@ | ||||
| /* | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-05 11:01:55 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-01-18 17:16:31 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\components\\contract-template-detail\\contract-template-detail.component.spec.ts | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
|  */ | ||||
|  | ||||
| import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | ||||
| import { ContractManagementTemplateDetailComponent } from './contract-template-detail.component'; | ||||
|  | ||||
| describe('ContractManagementTemplateDetailComponent', () => { | ||||
|   let component: ContractManagementTemplateDetailComponent; | ||||
|   let fixture: ComponentFixture<ContractManagementTemplateDetailComponent>; | ||||
|  | ||||
|   beforeEach(async(() => { | ||||
|     TestBed.configureTestingModule({ | ||||
|       declarations: [ContractManagementTemplateDetailComponent], | ||||
|     }).compileComponents(); | ||||
|   })); | ||||
|  | ||||
|   beforeEach(() => { | ||||
|     fixture = TestBed.createComponent(ContractManagementTemplateDetailComponent); | ||||
|     component = fixture.componentInstance; | ||||
|     fixture.detectChanges(); | ||||
|   }); | ||||
|  | ||||
|   it('should create', () => { | ||||
|     expect(component).toBeTruthy(); | ||||
|   }); | ||||
| }); | ||||
| @ -0,0 +1,248 @@ | ||||
| import { OnChanges } from '@angular/core'; | ||||
| /* | ||||
|  * @Description  : | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-05 11:01:55 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-03-30 10:45:19 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\components\\contract-template-detail\\contract-template-detail.component.ts | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
|  */ | ||||
| import { DatePipe } from '@angular/common'; | ||||
| import { Component, OnInit, ViewChild } from '@angular/core'; | ||||
| import { ActivatedRoute, Router } from '@angular/router'; | ||||
| import { SFComponent, SFSchema, SFSelectWidgetSchema, SFUISchema } from '@delon/form'; | ||||
| import { ShipperBaseService } from '@shared'; | ||||
| import { NzModalService } from 'ng-zorro-antd/modal'; | ||||
| import { ContractManagementService } from '../../services/contract-management.service'; | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-contract-management-template-text-complaint', | ||||
|   templateUrl: './contract-template-detail.component.html', | ||||
|   styleUrls: ['./contract-template-detail.component.less'], | ||||
|   providers: [DatePipe] | ||||
| }) | ||||
| export class ContractManagementTemplateTextComponent implements OnInit { | ||||
|   constructor( | ||||
|     private nzModalService: NzModalService, | ||||
|     public service: ContractManagementService, | ||||
|     public route: ActivatedRoute, | ||||
|     private datePipe: DatePipe, | ||||
|     private router: Router, | ||||
|     public shipperservice: ShipperBaseService | ||||
|   ) {} | ||||
|   textStatus = '新建模板'; | ||||
|   @ViewChild('sf', { static: false }) sf!: SFComponent; | ||||
|   schema: SFSchema = {}; | ||||
|   @ViewChild('sf2', { static: false }) sf2!: SFComponent; | ||||
|   schema2: SFSchema = {}; | ||||
|   ui!: SFUISchema; | ||||
|   sfdata: any; | ||||
|   sfdata2: any; | ||||
|   title: any; | ||||
|   Types: any; | ||||
|   templateHTML: any; | ||||
|   detailList: any = { | ||||
|     templateName: '' | ||||
|   }; | ||||
|   isUpdate = false; | ||||
|   ngOnInit() { | ||||
|     this.initSF(); | ||||
|     this.initSF2(); | ||||
|     if (this.route.snapshot.queryParams.status == 1) { | ||||
|       // 新建 | ||||
|       this.isUpdate = true; | ||||
|     } else if (this.route.snapshot.queryParams.status == 2) { | ||||
|       // 编辑 | ||||
|       this.textStatus = '编辑模板'; | ||||
|       this.isUpdate = true; | ||||
|       this.initData(this.service.$api_get_contractTemplate); | ||||
|     } else if (this.route.snapshot.queryParams.status == 3) { | ||||
|       // 编辑 | ||||
|       this.textStatus = '查看模板'; | ||||
|       this.isUpdate = false; | ||||
|       this.initData(this.service.$api_get_contractTemplate); | ||||
|     } | ||||
|   } | ||||
|   goBack() { | ||||
|     window.history.go(-1); | ||||
|   } | ||||
|   initSF() { | ||||
|     this.schema = { | ||||
|       properties: { | ||||
|         templateName: { | ||||
|           type: 'string', | ||||
|           title: '模版名称' | ||||
|         }, | ||||
|         templateType: { | ||||
|           title: '模板类型', | ||||
|           type: 'string', | ||||
|           enum: [ | ||||
|             { label: '框架合同', value: 'KJ' }, | ||||
|             { label: '明细合同', value: 'MX' }, | ||||
|             { label: '合伙人合同', value: 'HHR' } | ||||
|           ], | ||||
|           ui: { | ||||
|             widget: 'select', | ||||
|             placeholder: '请选择', | ||||
|             change: (tag: any, org: any) => { | ||||
|               console.log(tag); | ||||
|               switch (tag) { | ||||
|                 case 'MX': | ||||
|                   this.Types = [ | ||||
|                     { label: '订单合同', value: '1' }, | ||||
|                     { label: '订单补充协议', value: '2' }, | ||||
|                     { label: '运单合同', value: '3' }, | ||||
|                     { label: '运单补充协议', value: '4' }, | ||||
|                     { label: '委托代收合同', value: '5' }, | ||||
|                     { label: '电子提货单', value: '10' }, | ||||
|                     { label: '电子卸货单', value: '11' }, | ||||
|                   ]; | ||||
|                   this.sf.getProperty('/contractType')!.schema.enum = this.Types; | ||||
|                   this.sf.getProperty('/contractType')!.widget.reset(this.Types); | ||||
|                   this.sf.setValue('/contractType', this.Types); | ||||
|                   return; | ||||
|                   break; | ||||
|                 case 'KJ': | ||||
|                   this.Types = [ | ||||
|                     { label: '网络货物运输服务合同', value: '6' }, | ||||
|                     { label: '运输服务承揽合同', value: '7' } | ||||
|                   ]; | ||||
|                   this.sf.getProperty('/contractType')!.schema.enum = this.Types; | ||||
|                   this.sf.getProperty('/contractType')!.widget.reset(this.Types); | ||||
|                   this.sf.setValue('/contractType', this.Types); | ||||
|                   return; | ||||
|                   break; | ||||
|                 case 'HHR': | ||||
|                   this.Types = [ | ||||
|                     { label: '企业合伙人入驻合同', value: '8' }, | ||||
|                     { label: '个人合伙人入驻合同', value: '9' } | ||||
|                   ]; | ||||
|                   this.sf.getProperty('/contractType')!.schema.enum = this.Types; | ||||
|                   this.sf.getProperty('/contractType')!.widget.reset(this.Types); | ||||
|                   this.sf.setValue('/contractType', this.Types); | ||||
|                   return; | ||||
|                   break; | ||||
|                 default: | ||||
|                   break; | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         signingObject: { | ||||
|           type: 'string', | ||||
|           title: '承包商对象', | ||||
|           enum: [ | ||||
|             { label: '货主', value: '1' }, | ||||
|             { label: '司机', value: '2' } | ||||
|           ], | ||||
|           ui: { | ||||
|             widget: 'select', | ||||
|             placeholder: '请选择' | ||||
|           } | ||||
|         }, | ||||
|         contractType: { | ||||
|           title: '合同类型', | ||||
|           type: 'string', | ||||
|           enum: this.Types, | ||||
|           ui: { | ||||
|             widget: 'select', | ||||
|             placeholder: '请选择' | ||||
|           } | ||||
|         }, | ||||
|         resourceType: { | ||||
|           title: '货源类型', | ||||
|           type: 'string', | ||||
|           default: '', | ||||
|           ui: { | ||||
|             widget: 'dict-select', | ||||
|             params: { dictKey: 'goodresource:type' }, | ||||
|             containsAllLable: true, | ||||
|             visibleIf: { | ||||
|               templateType: value => value === 'MX' | ||||
|             } | ||||
|           } as SFSelectWidgetSchema | ||||
|         }, | ||||
|         enterpriseInfoId: { | ||||
|           type: 'string', | ||||
|           title: '网络货运人', | ||||
|           ui: { | ||||
|             widget: 'select', | ||||
|             placeholder: '请选择', | ||||
|             allowClear: true, | ||||
|             visibleIf: { | ||||
|               templateType: value => value === 'KJ' || value === 'HHR' | ||||
|             }, | ||||
|             asyncData: () => this.shipperservice.getNetworkFreightForwarder() | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
|       required: ['templateName', 'templateType'] | ||||
|     }; | ||||
|     this.ui = { | ||||
|       '*': { | ||||
|         spanLabelFixed: 120, | ||||
|         grid: { span: 8 } | ||||
|       } | ||||
|     }; | ||||
|   } | ||||
|   initSF2(data?: any) { | ||||
|     this.schema2 = { | ||||
|       properties: { | ||||
|         templateContent: { | ||||
|           type: 'string', | ||||
|           title: '', | ||||
|           ui: { | ||||
|             widget: 'tinymce', | ||||
|             loadingTip: 'loading...', | ||||
|             config: { | ||||
|               height: 650 | ||||
|             } | ||||
|           }, | ||||
|           default: data?.agreementContent || '' | ||||
|         } | ||||
|       } | ||||
|     }; | ||||
|   } | ||||
|   initData(url: string) { | ||||
|     console.log('编辑'); | ||||
|  | ||||
|     this.service.request(url, { id: this.route.snapshot.params.id }).subscribe(res => { | ||||
|       if (res) { | ||||
|         this.detailList = res; | ||||
|         this.title = this.detailList?.templateName; | ||||
|         this.sfdata = res; | ||||
|         this.sfdata2 = res; | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|   cancel() { | ||||
|     window.history.go(-1); | ||||
|   } | ||||
|  | ||||
|   save() { | ||||
|     // if (!this.sf.value.templateName || !this.sf.value.templateType || !this.sf2.value.templateContent || !this.title) { | ||||
|     //   this.service.msgSrv.error('必填参数为空,请检查再重新保存!'); | ||||
|     //   return; | ||||
|     // } | ||||
|     // if (this.sf.value.templateType == 'MX') { | ||||
|     //   if (this.sf.value.contractType == '') { | ||||
|     //     this.service.msgSrv.error('必填参数为空,请检查再重新保存!'); | ||||
|     //     return; | ||||
|     //   } | ||||
|     // } | ||||
|     const params = { | ||||
|       ...this.sf.value, | ||||
|       ...this.sf2.value, | ||||
|       templateTitle: this.title || this.detailList.templateName | ||||
|     }; | ||||
|     console.log(params); | ||||
|     this.service.request(this.service.$api_save_contractTemplate, params).subscribe((res: any) => { | ||||
|       if (res) { | ||||
|         this.service.msgSrv.success('保存成功!'); | ||||
|         this.router.navigate(['/contract-management/template']); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,86 @@ | ||||
| <!-- | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-12 10:52:50 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-02-24 20:01:42 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\components\\contract-template-frame\\contract-template-frame.component.html | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
| --> | ||||
|  | ||||
| <!-- 搜索表单 --> | ||||
| <nz-card> | ||||
|   <div nz-row nzGutter="8"> | ||||
|     <!-- 查询字段小于或等于3个时,不显示伸缩按钮 --> | ||||
|     <div nz-col nzSpan="24" *ngIf="queryFieldCount <= 4"> | ||||
|       <sf | ||||
|         #sf | ||||
|         [schema]="schema" | ||||
|         [ui]="ui" | ||||
|         [mode]="'search'" | ||||
|         [disabled]="!sf?.valid" | ||||
|         [loading]="false" | ||||
|         (formSubmit)="st?.load(1)" | ||||
|         (formReset)="resetSF()" | ||||
|       ></sf> | ||||
|     </div> | ||||
|  | ||||
|     <!-- 查询字段大于3个时,根据展开状态调整布局 --> | ||||
|     <ng-container> | ||||
|       <div nz-col [nzSpan]="_$expand ? 24 : 18"> | ||||
|         <sf #sf [schema]="schema" [ui]="ui" [compact]="true" [button]="'none'"> | ||||
|           <ng-template sf-template="signTime" let-me let-ui="ui" let-schema="schema"> | ||||
|             <nz-range-picker [nzShowTime]="true" [(ngModel)]="sf.value.signTime"></nz-range-picker> | ||||
|           </ng-template> | ||||
|           <ng-template sf-template="effectiveEndTime" let-me let-ui="ui" let-schema="schema"> | ||||
|             <nz-range-picker [nzShowTime]="true" [(ngModel)]="sf.value.effectiveEndTime"></nz-range-picker> | ||||
|           </ng-template> | ||||
|         </sf> | ||||
|       </div> | ||||
|       <div nz-col [nzSpan]="_$expand ? 24 : 6" [class.text-right]="_$expand"> | ||||
|         <button | ||||
|           nz-button | ||||
|           nzType="primary" | ||||
|           [disabled]="!sf.valid" | ||||
|           [nzLoading]="service.http.loading" | ||||
|           (click)="st?.load(1)" | ||||
|           acl | ||||
|           [acl-ability]="['CONTRACT-INDEX-listFrame']" | ||||
|           >查询</button | ||||
|         > | ||||
|         <button nz-button (click)="resetSF()">重置</button> | ||||
|         <button nz-button nzType="link" (click)="expandToggle()"> | ||||
|           {{ !_$expand ? '展开' : '收起' }} | ||||
|           <i nz-icon [nzType]="!_$expand ? 'down' : 'up'"></i> | ||||
|         </button> | ||||
|       </div> | ||||
|     </ng-container> | ||||
|   </div> | ||||
| </nz-card> | ||||
|  | ||||
| <nz-card> | ||||
|   <div class="NewBtn"> | ||||
|     <button nz-button nzType="primary" (click)="creatTemplate()" acl [acl-ability]="['CONTRACT-TEMPLATE-new']"> 新建 </button> | ||||
|   </div> | ||||
|   <div style="margin-top: 15px"> | ||||
|     <st | ||||
|       #st | ||||
|       [bordered]="true" | ||||
|       [data]="service.$api_get_contractTemplate_page" | ||||
|       [columns]="columns" | ||||
|       [req]="{ method: 'POST', allInBody: true, reName: { pi: 'pageIndex', ps: 'pageSize' }, params: reqParams }" | ||||
|       [res]="{ reName: { list: 'data.records', total: 'data.total' } }" | ||||
|       [page]="{ show: true, showSize: true, pageSizes: [10, 20, 30, 50, 100, 200, 300, 500, 1000] }" | ||||
|       [loading]="false" | ||||
|     > | ||||
|       <ng-template st-row="templateName" let-item let-index="index"> | ||||
|         <a (click)="view(item)">{{ item.templateName }}</a> | ||||
|       </ng-template> | ||||
|       <ng-template st-row="signingObject" let-item let-index="index"> | ||||
|         <span *ngIf="item?.signingObject == 1">货主</span> | ||||
|         <span *ngIf="item?.signingObject == 2">司机</span> | ||||
|       </ng-template> | ||||
|     </st> | ||||
|   </div> | ||||
| </nz-card> | ||||
| @ -0,0 +1,4 @@ | ||||
| .NewBtn{ | ||||
|     float: right; | ||||
|     margin-bottom: 15px; | ||||
| } | ||||
| @ -0,0 +1,35 @@ | ||||
| /* | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-05 09:45:47 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-02-24 10:25:58 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\components\\contract-template\\contract-template.component.spec.ts | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
|  */ | ||||
|  | ||||
| import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; | ||||
| import { ContractManagementTemplateFrameComponent } from './contract-template-frame.component'; | ||||
|  | ||||
| describe('ContractManagementTemplateFrameComponent', () => { | ||||
|   let component: ContractManagementTemplateFrameComponent; | ||||
|   let fixture: ComponentFixture<ContractManagementTemplateFrameComponent>; | ||||
|  | ||||
|   beforeEach(waitForAsync(() => { | ||||
|     TestBed.configureTestingModule({ | ||||
|       declarations: [ ContractManagementTemplateFrameComponent ] | ||||
|     }) | ||||
|     .compileComponents(); | ||||
|   })); | ||||
|  | ||||
|   beforeEach(() => { | ||||
|     fixture = TestBed.createComponent(ContractManagementTemplateFrameComponent); | ||||
|     component = fixture.componentInstance; | ||||
|     fixture.detectChanges(); | ||||
|   }); | ||||
|  | ||||
|   it('should create', () => { | ||||
|     expect(component).toBeTruthy(); | ||||
|   }); | ||||
| }); | ||||
| @ -0,0 +1,252 @@ | ||||
| import { Router } from '@angular/router'; | ||||
| import { Component, OnInit, ViewChild } from '@angular/core'; | ||||
| import { STColumn, STComponent } from '@delon/abc/st'; | ||||
| import { SFComponent, SFDateWidgetSchema, SFSchema, SFSelectWidgetSchema, SFUISchema } from '@delon/form'; | ||||
| import { ModalHelper, _HttpClient } from '@delon/theme'; | ||||
| import { NzModalService } from 'ng-zorro-antd/modal'; | ||||
| import { map } from 'rxjs/operators'; | ||||
| import { ContractManagementService } from '../../services/contract-management.service'; | ||||
|  | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-contract-management-template-frame-complaint', | ||||
|   templateUrl: './contract-template-frame.component.html', | ||||
|   styleUrls: ['./contract-template-frame.component.less'] | ||||
| }) | ||||
| export class ContractManagementTemplateFrameComponent implements OnInit { | ||||
|   ui: SFUISchema = {}; | ||||
|   uiView: SFUISchema = {}; | ||||
|   schema: SFSchema = {}; | ||||
|   schemaView: SFSchema = {}; | ||||
|   auditMany = false; | ||||
|   _$expand = false; | ||||
|   channelId: any; | ||||
|   @ViewChild('st') private readonly st!: STComponent; | ||||
|   @ViewChild('sf', { static: false }) sf!: SFComponent; | ||||
|   columns: STColumn[] = []; | ||||
|   datass: any = [ | ||||
|     { | ||||
|     one: '1', | ||||
|     two: '1', | ||||
|     three: '1', | ||||
|     id: 1 | ||||
|    }, | ||||
|     { | ||||
|     one: '2', | ||||
|     two: '2', | ||||
|     three: '2', | ||||
|     id: 2 | ||||
|    }, | ||||
| ]; | ||||
|   constructor( | ||||
|     public service: ContractManagementService, | ||||
|     private modal: NzModalService, | ||||
|     private router: Router | ||||
|      ) { } | ||||
|  | ||||
|   /** | ||||
|  * 查询参数 | ||||
|  */ | ||||
|   get reqParams() { | ||||
|     return { | ||||
|       templateType: 'kj', | ||||
|       ...this.sf?.value, | ||||
|     }; | ||||
|   } | ||||
|   get selectedRows() { | ||||
|     return this.st?.list.filter((item) => item.checked) || []; | ||||
|   } | ||||
|   ngOnInit(): void { | ||||
|     this.initSF(); | ||||
|     this.initST(); | ||||
|     this.initSTAudit(); | ||||
|   } | ||||
|  | ||||
|  | ||||
|  | ||||
|   /** | ||||
|  * 初始化查询表单 | ||||
|  */ | ||||
|   initSF() { | ||||
|     this.schema = { | ||||
|       properties: { | ||||
|         _$expand: { type: 'boolean', ui: { hidden: true } }, | ||||
|         templateName: { | ||||
|           type: 'string', | ||||
|           title: '模板名称', | ||||
|         }, | ||||
|         signingObject: { | ||||
|           type: 'string', | ||||
|           title: '签约对象', | ||||
|           enum: [ | ||||
|             { label: '全部', value: '' }, | ||||
|             { label: '货主', value: 1 }, | ||||
|             { label: '司机', value: 2 } | ||||
|           ], | ||||
|           ui: { | ||||
|             widget: 'select', | ||||
|             placeholder: '请选择' | ||||
|           } | ||||
|         }, | ||||
|         contractType: { | ||||
|           title: '合同类型', | ||||
|           type: 'string', | ||||
|           default: '', | ||||
|           ui: { | ||||
|             widget: 'dict-select', | ||||
|             containsAllLable: true, | ||||
|             params: { dictKey: 'contract:type' }, | ||||
|             containAllLable: true, | ||||
|           } as SFSelectWidgetSchema | ||||
|         }, | ||||
|         resourceType: { | ||||
|           title: '货源类型', | ||||
|           type: 'string', | ||||
|           default: '', | ||||
|           ui: { | ||||
|             widget: 'dict-select', | ||||
|             params: { dictKey: 'goodresource:type' }, | ||||
|             containsAllLable: true, | ||||
|             visibleIf: { | ||||
|               _$expand: (value: boolean) => value | ||||
|             }, | ||||
|           } as SFSelectWidgetSchema, | ||||
|         }, | ||||
|       }, | ||||
|     }; | ||||
|     this.ui = { '*': { spanLabelFixed: 110, grid: { span: 8, gutter: 4 } } }; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 初始化数据列表 | ||||
|    */ | ||||
|   initST() { | ||||
|     this.columns = [ | ||||
|       { | ||||
|         title: '合同模板名称', | ||||
|         className: 'text-center', | ||||
|         render: 'templateName' | ||||
|       }, | ||||
|       { | ||||
|         title: '签约对象', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'signingObjectLabel' | ||||
|       }, | ||||
|       { | ||||
|         title: '合同类型', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'contractTypeLabel' | ||||
|       }, | ||||
|       { | ||||
|         title: '货源类型', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'resourceTypeLabel' | ||||
|       }, | ||||
|       { title: '创建人', index: 'createUserIdLabel', width: '120px', className: 'text-center' }, | ||||
|       { | ||||
|         title: '创建时间', | ||||
|         className: 'text-center', | ||||
|         index: 'createTime', | ||||
|         width: '200px' | ||||
|       }, | ||||
|       { | ||||
|         title: '操作', | ||||
|         fixed: 'right', | ||||
|         width: '110px', | ||||
|         className: 'text-center', | ||||
|         buttons: [ | ||||
|           { | ||||
|             text: '编辑', | ||||
|             click: (_record) => this.edit(_record), | ||||
|             acl: { ability: ['CONTRACT-TEMPLATE-edit'] }, | ||||
|           }, | ||||
|           { | ||||
|             text: '删除', | ||||
|             click: (_record) => this.delete(_record), | ||||
|             acl: { ability: ['CONTRACT-TEMPLATE-delete'] }, | ||||
|           }, | ||||
|         ], | ||||
|       }, | ||||
|     ]; | ||||
|   } | ||||
|   initSTAudit() { | ||||
|     this.schemaView = { | ||||
|       properties: { | ||||
|         handleResult: { | ||||
|           title: '处理结果', | ||||
|           type: 'string', | ||||
|           maxLength: 50, | ||||
|           ui: { | ||||
|             placeholder: '最多不超过50字', | ||||
|             widget: 'textarea', | ||||
|             autosize: { minRows: 3, maxRows: 6 } | ||||
|           }, | ||||
|         }, | ||||
|       }, | ||||
|       required: ['handleResult'] | ||||
|     }; | ||||
|     this.uiView = { '*': { spanLabelFixed: 110, grid: { span: 24 } } }; | ||||
|   } | ||||
|   /** | ||||
|    * 查询字段个数 | ||||
|    */ | ||||
|   get queryFieldCount(): number { | ||||
|     return Object.keys(this.schema?.properties || {}).length; | ||||
|   } | ||||
|  /** | ||||
|    * 伸缩查询条件 | ||||
|    */ | ||||
|   expandToggle(): void { | ||||
|     this._$expand = !this._$expand; | ||||
|     this.sf?.setValue('/_$expand', this._$expand); | ||||
|   } | ||||
|   tabChange(item: any) { | ||||
|   } | ||||
|   /** | ||||
|    * 重置表单 | ||||
|    */ | ||||
|   resetSF(): void { | ||||
|     this.sf.reset(); | ||||
|     this._$expand = false; | ||||
|   } | ||||
|  | ||||
|   edit(value: any) { | ||||
|     this.router.navigate(['/contract-management/template/text/' + value.id],{ | ||||
|       queryParams: { | ||||
|         status: 2 | ||||
|       } | ||||
|     }) | ||||
|   } | ||||
|   creatTemplate() { | ||||
|     this.router.navigate(['/contract-management/template/text/' + 0], { | ||||
|       queryParams: { | ||||
|         status: 1 | ||||
|       } | ||||
|     }) | ||||
|   } | ||||
|   goBack() { | ||||
|     window.history.go(-1) | ||||
|   } | ||||
|   view(value: any) { | ||||
|     this.router.navigate(['/contract-management/template/text/' + value.id],{ | ||||
|       queryParams: { | ||||
|         status: 3 | ||||
|       } | ||||
|     }) | ||||
|   } | ||||
|   delete(value: any) { | ||||
|     this.modal.confirm({ | ||||
|       nzTitle: '<i>删除确认</i>', | ||||
|       nzOnOk: () => | ||||
|         this.service.request(this.service.$api_deletebatch_contractTemplate, [value.id]).subscribe(res => { | ||||
|           if (res) { | ||||
|             this.service.msgSrv.success('删除成功!'); | ||||
|             this.st.reload() | ||||
|           } | ||||
|         }) | ||||
|     }); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,82 @@ | ||||
| <!-- | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-12 10:52:50 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-02-24 10:31:05 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\components\\contract-template\\contract-template.component.html | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
| --> | ||||
|  | ||||
| <!-- 搜索表单 --> | ||||
| <nz-card> | ||||
|   <div nz-row nzGutter="8"> | ||||
|     <!-- 查询字段小于或等于3个时,不显示伸缩按钮 --> | ||||
|     <div nz-col nzSpan="24" *ngIf="queryFieldCount <= 4"> | ||||
|       <sf | ||||
|         #sf | ||||
|         [schema]="schema" | ||||
|         [ui]="ui" | ||||
|         [mode]="'search'" | ||||
|         [disabled]="!sf?.valid" | ||||
|         [loading]="false" | ||||
|         (formSubmit)="st?.load(1)" | ||||
|         (formReset)="resetSF()" | ||||
|       ></sf> | ||||
|     </div> | ||||
|  | ||||
|     <!-- 查询字段大于3个时,根据展开状态调整布局 --> | ||||
|     <ng-container> | ||||
|       <div nz-col [nzSpan]="_$expand ? 24 : 18"> | ||||
|         <sf #sf [schema]="schema" [ui]="ui" [compact]="true" [button]="'none'"> | ||||
|           <ng-template sf-template="signTime" let-me let-ui="ui" let-schema="schema"> | ||||
|             <nz-range-picker [nzShowTime]="true" [(ngModel)]="sf.value.signTime"></nz-range-picker> | ||||
|           </ng-template> | ||||
|           <ng-template sf-template="effectiveEndTime" let-me let-ui="ui" let-schema="schema"> | ||||
|             <nz-range-picker [nzShowTime]="true" [(ngModel)]="sf.value.effectiveEndTime"></nz-range-picker> | ||||
|           </ng-template> | ||||
|         </sf> | ||||
|       </div> | ||||
|       <div nz-col [nzSpan]="_$expand ? 24 : 6" [class.text-right]="_$expand"> | ||||
|         <button | ||||
|           nz-button | ||||
|           nzType="primary" | ||||
|           [disabled]="!sf.valid" | ||||
|           [nzLoading]="service.http.loading" | ||||
|           (click)="st?.load(1)" | ||||
|           acl | ||||
|           [acl-ability]="['CONTRACT-INDEX-listFrame']" | ||||
|           >查询</button | ||||
|         > | ||||
|         <button nz-button (click)="resetSF()">重置</button> | ||||
|         <button nz-button nzType="link" (click)="expandToggle()"> | ||||
|           {{ !_$expand ? '展开' : '收起' }} | ||||
|           <i nz-icon [nzType]="!_$expand ? 'down' : 'up'"></i> | ||||
|         </button> | ||||
|       </div> | ||||
|     </ng-container> | ||||
|   </div> | ||||
| </nz-card> | ||||
|  | ||||
| <nz-card> | ||||
|   <div class="NewBtn"> | ||||
|     <button nz-button nzType="primary" (click)="creatTemplate()" acl [acl-ability]="['CONTRACT-TEMPLATE-new']"> 新建 </button> | ||||
|   </div> | ||||
|   <div style="margin-top: 15px"> | ||||
|     <st | ||||
|       #st | ||||
|       [bordered]="true" | ||||
|       [data]="service.$api_get_contractTemplate_page" | ||||
|       [columns]="columns" | ||||
|       [req]="{ method: 'POST', allInBody: true, reName: { pi: 'pageIndex', ps: 'pageSize' }, params: reqParams }" | ||||
|       [res]="{ reName: { list: 'data.records', total: 'data.total' } }" | ||||
|       [page]="{ show: true, showSize: true, pageSizes: [10, 20, 30, 50, 100, 200, 300, 500, 1000] }" | ||||
|       [loading]="false" | ||||
|     > | ||||
|       <ng-template st-row="templateName" let-item let-index="index"> | ||||
|         <a (click)="view(item)">{{ item.templateName }}</a> | ||||
|       </ng-template> | ||||
|     </st> | ||||
|   </div> | ||||
| </nz-card> | ||||
| @ -0,0 +1,4 @@ | ||||
| .NewBtn{ | ||||
|     float: right; | ||||
|     margin-bottom: 15px; | ||||
| } | ||||
| @ -0,0 +1,35 @@ | ||||
| /* | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-05 09:45:47 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-02-24 14:09:28 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\components\\contract-template-partner\\contract-template-partner.component.spec.ts | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
|  */ | ||||
|  | ||||
| import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; | ||||
| import { ContractManagementTemplatePartnerComponent } from './contract-template-partner.component'; | ||||
|  | ||||
| describe('ContractManagementTemplatePartnerComponent', () => { | ||||
|   let component: ContractManagementTemplatePartnerComponent; | ||||
|   let fixture: ComponentFixture<ContractManagementTemplatePartnerComponent>; | ||||
|  | ||||
|   beforeEach(waitForAsync(() => { | ||||
|     TestBed.configureTestingModule({ | ||||
|       declarations: [ ContractManagementTemplatePartnerComponent ] | ||||
|     }) | ||||
|     .compileComponents(); | ||||
|   })); | ||||
|  | ||||
|   beforeEach(() => { | ||||
|     fixture = TestBed.createComponent(ContractManagementTemplatePartnerComponent); | ||||
|     component = fixture.componentInstance; | ||||
|     fixture.detectChanges(); | ||||
|   }); | ||||
|  | ||||
|   it('should create', () => { | ||||
|     expect(component).toBeTruthy(); | ||||
|   }); | ||||
| }); | ||||
| @ -0,0 +1,252 @@ | ||||
| import { Router } from '@angular/router'; | ||||
| import { Component, OnInit, ViewChild } from '@angular/core'; | ||||
| import { STColumn, STComponent } from '@delon/abc/st'; | ||||
| import { SFComponent, SFDateWidgetSchema, SFSchema, SFSelectWidgetSchema, SFUISchema } from '@delon/form'; | ||||
| import { ModalHelper, _HttpClient } from '@delon/theme'; | ||||
| import { NzModalService } from 'ng-zorro-antd/modal'; | ||||
| import { map } from 'rxjs/operators'; | ||||
| import { ContractManagementService } from '../../services/contract-management.service'; | ||||
|  | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-contract-management-template-partner-complaint', | ||||
|   templateUrl: './contract-template-partner.component.html', | ||||
|   styleUrls: ['./contract-template-partner.component.less'] | ||||
| }) | ||||
| export class ContractManagementTemplatePartnerComponent implements OnInit { | ||||
|   ui: SFUISchema = {}; | ||||
|   uiView: SFUISchema = {}; | ||||
|   schema: SFSchema = {}; | ||||
|   schemaView: SFSchema = {}; | ||||
|   auditMany = false; | ||||
|   _$expand = false; | ||||
|   channelId: any; | ||||
|   @ViewChild('st') private readonly st!: STComponent; | ||||
|   @ViewChild('sf', { static: false }) sf!: SFComponent; | ||||
|   columns: STColumn[] = []; | ||||
|   datass: any = [ | ||||
|     { | ||||
|     one: '1', | ||||
|     two: '1', | ||||
|     three: '1', | ||||
|     id: 1 | ||||
|    }, | ||||
|     { | ||||
|     one: '2', | ||||
|     two: '2', | ||||
|     three: '2', | ||||
|     id: 2 | ||||
|    }, | ||||
| ]; | ||||
|   constructor( | ||||
|     public service: ContractManagementService, | ||||
|     private modal: NzModalService, | ||||
|     private router: Router | ||||
|      ) { } | ||||
|  | ||||
|   /** | ||||
|  * 查询参数 | ||||
|  */ | ||||
|   get reqParams() { | ||||
|     return { | ||||
|       templateType: 'HHR', | ||||
|       ...this.sf?.value, | ||||
|     }; | ||||
|   } | ||||
|   get selectedRows() { | ||||
|     return this.st?.list.filter((item) => item.checked) || []; | ||||
|   } | ||||
|   ngOnInit(): void { | ||||
|     this.initSF(); | ||||
|     this.initST(); | ||||
|     this.initSTAudit(); | ||||
|   } | ||||
|  | ||||
|  | ||||
|  | ||||
|   /** | ||||
|  * 初始化查询表单 | ||||
|  */ | ||||
|   initSF() { | ||||
|     this.schema = { | ||||
|       properties: { | ||||
|         _$expand: { type: 'boolean', ui: { hidden: true } }, | ||||
|         templateName: { | ||||
|           type: 'string', | ||||
|           title: '模板名称', | ||||
|         }, | ||||
|         signingObject: { | ||||
|           type: 'string', | ||||
|           title: '签约对象', | ||||
|           enum: [ | ||||
|             { label: '全部', value: '' }, | ||||
|             { label: '货主', value: 1 }, | ||||
|             { label: '司机', value: 2 } | ||||
|           ], | ||||
|           ui: { | ||||
|             widget: 'select', | ||||
|             placeholder: '请选择' | ||||
|           } | ||||
|         }, | ||||
|         contractType: { | ||||
|           title: '合同类型', | ||||
|           type: 'string', | ||||
|           default: '', | ||||
|           ui: { | ||||
|             widget: 'dict-select', | ||||
|             containsAllLable: true, | ||||
|             params: { dictKey: 'contract:type' }, | ||||
|             containAllLable: true, | ||||
|           } as SFSelectWidgetSchema | ||||
|         }, | ||||
|         resourceType: { | ||||
|           title: '货源类型', | ||||
|           type: 'string', | ||||
|           default: '', | ||||
|           ui: { | ||||
|             widget: 'dict-select', | ||||
|             params: { dictKey: 'goodresource:type' }, | ||||
|             containsAllLable: true, | ||||
|             visibleIf: { | ||||
|               _$expand: (value: boolean) => value | ||||
|             }, | ||||
|           } as SFSelectWidgetSchema, | ||||
|         }, | ||||
|       }, | ||||
|     }; | ||||
|     this.ui = { '*': { spanLabelFixed: 110, grid: { span: 8, gutter: 4 } } }; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 初始化数据列表 | ||||
|    */ | ||||
|   initST() { | ||||
|     this.columns = [ | ||||
|       { | ||||
|         title: '合同模板名称', | ||||
|         className: 'text-center', | ||||
|         render: 'templateName' | ||||
|       }, | ||||
|       { | ||||
|         title: '签约对象', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'signingObjectLabel' | ||||
|       }, | ||||
|       { | ||||
|         title: '合同类型', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'contractTypeLabel' | ||||
|       }, | ||||
|       { | ||||
|         title: '货源类型', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'resourceTypeLabel' | ||||
|       }, | ||||
|       { title: '创建人', index: 'createUserIdLabel', width: '120px', className: 'text-center' }, | ||||
|       { | ||||
|         title: '创建时间', | ||||
|         className: 'text-center', | ||||
|         index: 'createTime', | ||||
|         width: '200px' | ||||
|       }, | ||||
|       { | ||||
|         title: '操作', | ||||
|         fixed: 'right', | ||||
|         width: '110px', | ||||
|         className: 'text-center', | ||||
|         buttons: [ | ||||
|           { | ||||
|             text: '编辑', | ||||
|             click: (_record) => this.edit(_record), | ||||
|             acl: { ability: ['CONTRACT-TEMPLATE-edit'] }, | ||||
|           }, | ||||
|           { | ||||
|             text: '删除', | ||||
|             click: (_record) => this.delete(_record), | ||||
|             acl: { ability: ['CONTRACT-TEMPLATE-delete'] }, | ||||
|           }, | ||||
|         ], | ||||
|       }, | ||||
|     ]; | ||||
|   } | ||||
|   initSTAudit() { | ||||
|     this.schemaView = { | ||||
|       properties: { | ||||
|         handleResult: { | ||||
|           title: '处理结果', | ||||
|           type: 'string', | ||||
|           maxLength: 50, | ||||
|           ui: { | ||||
|             placeholder: '最多不超过50字', | ||||
|             widget: 'textarea', | ||||
|             autosize: { minRows: 3, maxRows: 6 } | ||||
|           }, | ||||
|         }, | ||||
|       }, | ||||
|       required: ['handleResult'] | ||||
|     }; | ||||
|     this.uiView = { '*': { spanLabelFixed: 110, grid: { span: 24 } } }; | ||||
|   } | ||||
|   /** | ||||
|    * 查询字段个数 | ||||
|    */ | ||||
|   get queryFieldCount(): number { | ||||
|     return Object.keys(this.schema?.properties || {}).length; | ||||
|   } | ||||
|  /** | ||||
|    * 伸缩查询条件 | ||||
|    */ | ||||
|   expandToggle(): void { | ||||
|     this._$expand = !this._$expand; | ||||
|     this.sf?.setValue('/_$expand', this._$expand); | ||||
|   } | ||||
|   tabChange(item: any) { | ||||
|   } | ||||
|   /** | ||||
|    * 重置表单 | ||||
|    */ | ||||
|   resetSF(): void { | ||||
|     this.sf.reset(); | ||||
|     this._$expand = false; | ||||
|   } | ||||
|  | ||||
|   edit(value: any) { | ||||
|     this.router.navigate(['/contract-management/template/text/' + value.id],{ | ||||
|       queryParams: { | ||||
|         status: 2 | ||||
|       } | ||||
|     }) | ||||
|   } | ||||
|   creatTemplate() { | ||||
|     this.router.navigate(['/contract-management/template/text/' + 0], { | ||||
|       queryParams: { | ||||
|         status: 1 | ||||
|       } | ||||
|     }) | ||||
|   } | ||||
|   goBack() { | ||||
|     window.history.go(-1) | ||||
|   } | ||||
|   view(value: any) { | ||||
|     this.router.navigate(['/contract-management/template/text/' + value.id],{ | ||||
|       queryParams: { | ||||
|         status: 3 | ||||
|       } | ||||
|     }) | ||||
|   } | ||||
|   delete(value: any) { | ||||
|     this.modal.confirm({ | ||||
|       nzTitle: '<i>删除确认</i>', | ||||
|       nzOnOk: () => | ||||
|         this.service.request(this.service.$api_deletebatch_contractTemplate, [value.id]).subscribe(res => { | ||||
|           if (res) { | ||||
|             this.service.msgSrv.success('删除成功!'); | ||||
|             this.st.reload() | ||||
|           } | ||||
|         }) | ||||
|     }); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,82 @@ | ||||
| <!-- | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-12 10:52:50 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-02-24 10:31:05 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\components\\contract-template\\contract-template.component.html | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
| --> | ||||
|  | ||||
| <!-- 搜索表单 --> | ||||
| <nz-card> | ||||
|   <div nz-row nzGutter="8"> | ||||
|     <!-- 查询字段小于或等于3个时,不显示伸缩按钮 --> | ||||
|     <div nz-col nzSpan="24" *ngIf="queryFieldCount <= 4"> | ||||
|       <sf | ||||
|         #sf | ||||
|         [schema]="schema" | ||||
|         [ui]="ui" | ||||
|         [mode]="'search'" | ||||
|         [disabled]="!sf?.valid" | ||||
|         [loading]="false" | ||||
|         (formSubmit)="st?.load(1)" | ||||
|         (formReset)="resetSF()" | ||||
|       ></sf> | ||||
|     </div> | ||||
|  | ||||
|     <!-- 查询字段大于3个时,根据展开状态调整布局 --> | ||||
|     <ng-container> | ||||
|       <div nz-col [nzSpan]="_$expand ? 24 : 18"> | ||||
|         <sf #sf [schema]="schema" [ui]="ui" [compact]="true" [button]="'none'"> | ||||
|           <ng-template sf-template="signTime" let-me let-ui="ui" let-schema="schema"> | ||||
|             <nz-range-picker [nzShowTime]="true" [(ngModel)]="sf.value.signTime"></nz-range-picker> | ||||
|           </ng-template> | ||||
|           <ng-template sf-template="effectiveEndTime" let-me let-ui="ui" let-schema="schema"> | ||||
|             <nz-range-picker [nzShowTime]="true" [(ngModel)]="sf.value.effectiveEndTime"></nz-range-picker> | ||||
|           </ng-template> | ||||
|         </sf> | ||||
|       </div> | ||||
|       <div nz-col [nzSpan]="_$expand ? 24 : 6" [class.text-right]="_$expand"> | ||||
|         <button | ||||
|           nz-button | ||||
|           nzType="primary" | ||||
|           [disabled]="!sf.valid" | ||||
|           [nzLoading]="service.http.loading" | ||||
|           (click)="st?.load(1)" | ||||
|           acl | ||||
|           [acl-ability]="['CONTRACT-INDEX-listFrame']" | ||||
|           >查询</button | ||||
|         > | ||||
|         <button nz-button (click)="resetSF()">重置</button> | ||||
|         <button nz-button nzType="link" (click)="expandToggle()"> | ||||
|           {{ !_$expand ? '展开' : '收起' }} | ||||
|           <i nz-icon [nzType]="!_$expand ? 'down' : 'up'"></i> | ||||
|         </button> | ||||
|       </div> | ||||
|     </ng-container> | ||||
|   </div> | ||||
| </nz-card> | ||||
|  | ||||
| <nz-card> | ||||
|   <div class="NewBtn"> | ||||
|     <button nz-button nzType="primary" (click)="creatTemplate()" acl [acl-ability]="['CONTRACT-TEMPLATE-new']"> 新建 </button> | ||||
|   </div> | ||||
|   <div style="margin-top: 15px"> | ||||
|     <st | ||||
|       #st | ||||
|       [bordered]="true" | ||||
|       [data]="service.$api_get_contractTemplate_page" | ||||
|       [columns]="columns" | ||||
|       [req]="{ method: 'POST', allInBody: true, reName: { pi: 'pageIndex', ps: 'pageSize' }, params: reqParams }" | ||||
|       [res]="{ reName: { list: 'data.records', total: 'data.total' } }" | ||||
|       [page]="{ show: true, showSize: true, pageSizes: [10, 20, 30, 50, 100, 200, 300, 500, 1000] }" | ||||
|       [loading]="false" | ||||
|     > | ||||
|       <ng-template st-row="templateName" let-item let-index="index"> | ||||
|         <a (click)="view(item)">{{ item.templateName }}</a> | ||||
|       </ng-template> | ||||
|     </st> | ||||
|   </div> | ||||
| </nz-card> | ||||
| @ -0,0 +1,4 @@ | ||||
| .NewBtn{ | ||||
|     float: right; | ||||
|     margin-bottom: 15px; | ||||
| } | ||||
| @ -0,0 +1,35 @@ | ||||
| /* | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-05 09:45:47 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-02-24 10:25:58 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\components\\contract-template\\contract-template.component.spec.ts | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
|  */ | ||||
|  | ||||
| import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; | ||||
| import { ContractManagementTemplateDetailComponent } from './contract-template.component'; | ||||
|  | ||||
| describe('ContractManagementTemplateDetailComponent', () => { | ||||
|   let component: ContractManagementTemplateDetailComponent; | ||||
|   let fixture: ComponentFixture<ContractManagementTemplateDetailComponent>; | ||||
|  | ||||
|   beforeEach(waitForAsync(() => { | ||||
|     TestBed.configureTestingModule({ | ||||
|       declarations: [ ContractManagementTemplateDetailComponent ] | ||||
|     }) | ||||
|     .compileComponents(); | ||||
|   })); | ||||
|  | ||||
|   beforeEach(() => { | ||||
|     fixture = TestBed.createComponent(ContractManagementTemplateDetailComponent); | ||||
|     component = fixture.componentInstance; | ||||
|     fixture.detectChanges(); | ||||
|   }); | ||||
|  | ||||
|   it('should create', () => { | ||||
|     expect(component).toBeTruthy(); | ||||
|   }); | ||||
| }); | ||||
| @ -0,0 +1,252 @@ | ||||
| import { Router } from '@angular/router'; | ||||
| import { Component, OnInit, ViewChild } from '@angular/core'; | ||||
| import { STColumn, STComponent } from '@delon/abc/st'; | ||||
| import { SFComponent, SFDateWidgetSchema, SFSchema, SFSelectWidgetSchema, SFUISchema } from '@delon/form'; | ||||
| import { ModalHelper, _HttpClient } from '@delon/theme'; | ||||
| import { NzModalService } from 'ng-zorro-antd/modal'; | ||||
| import { map } from 'rxjs/operators'; | ||||
| import { ContractManagementService } from '../../services/contract-management.service'; | ||||
|  | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-contract-management-template-detail-complaint', | ||||
|   templateUrl: './contract-template.component.html', | ||||
|   styleUrls: ['./contract-template.component.less'] | ||||
| }) | ||||
| export class ContractManagementTemplateDetailComponent implements OnInit { | ||||
|   ui: SFUISchema = {}; | ||||
|   uiView: SFUISchema = {}; | ||||
|   schema: SFSchema = {}; | ||||
|   schemaView: SFSchema = {}; | ||||
|   auditMany = false; | ||||
|   _$expand = false; | ||||
|   channelId: any; | ||||
|   @ViewChild('st') private readonly st!: STComponent; | ||||
|   @ViewChild('sf', { static: false }) sf!: SFComponent; | ||||
|   columns: STColumn[] = []; | ||||
|   datass: any = [ | ||||
|     { | ||||
|       one: '1', | ||||
|       two: '1', | ||||
|       three: '1', | ||||
|       id: 1 | ||||
|     }, | ||||
|     { | ||||
|       one: '2', | ||||
|       two: '2', | ||||
|       three: '2', | ||||
|       id: 2 | ||||
|     }, | ||||
|   ]; | ||||
|   constructor( | ||||
|     public service: ContractManagementService, | ||||
|     private modal: NzModalService, | ||||
|     private router: Router | ||||
|   ) { } | ||||
|  | ||||
|   /** | ||||
|  * 查询参数 | ||||
|  */ | ||||
|   get reqParams() { | ||||
|     return { | ||||
|       templateType: 'MX', | ||||
|       ...this.sf?.value, | ||||
|     }; | ||||
|   } | ||||
|   get selectedRows() { | ||||
|     return this.st?.list.filter((item) => item.checked) || []; | ||||
|   } | ||||
|   ngOnInit(): void { | ||||
|     this.initSF(); | ||||
|     this.initST(); | ||||
|     this.initSTAudit(); | ||||
|   } | ||||
|  | ||||
|  | ||||
|  | ||||
|   /** | ||||
|  * 初始化查询表单 | ||||
|  */ | ||||
|   initSF() { | ||||
|     this.schema = { | ||||
|       properties: { | ||||
|         _$expand: { type: 'boolean', ui: { hidden: true } }, | ||||
|         templateName: { | ||||
|           type: 'string', | ||||
|           title: '模板名称', | ||||
|         }, | ||||
|         signingObject: { | ||||
|           type: 'string', | ||||
|           title: '签约对象', | ||||
|           enum: [ | ||||
|             { label: '全部', value: '' }, | ||||
|             { label: '货主', value: 1 }, | ||||
|             { label: '司机', value: 2 } | ||||
|           ], | ||||
|           ui: { | ||||
|             widget: 'select', | ||||
|             placeholder: '请选择' | ||||
|           } | ||||
|         }, | ||||
|         contractType: { | ||||
|           title: '合同类型', | ||||
|           type: 'string', | ||||
|           default: '', | ||||
|           ui: { | ||||
|             widget: 'dict-select', | ||||
|             containsAllLable: true, | ||||
|             params: { dictKey: 'contract:type' }, | ||||
|             containAllLable: true, | ||||
|           } as SFSelectWidgetSchema | ||||
|         }, | ||||
|         resourceType: { | ||||
|           title: '货源类型', | ||||
|           type: 'string', | ||||
|           default: '', | ||||
|           ui: { | ||||
|             widget: 'dict-select', | ||||
|             params: { dictKey: 'goodresource:type' }, | ||||
|             containsAllLable: true, | ||||
|             visibleIf: { | ||||
|               _$expand: (value: boolean) => value | ||||
|             }, | ||||
|           } as SFSelectWidgetSchema, | ||||
|         }, | ||||
|       }, | ||||
|     }; | ||||
|     this.ui = { '*': { spanLabelFixed: 110, grid: { span: 8, gutter: 4 } } }; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 初始化数据列表 | ||||
|    */ | ||||
|   initST() { | ||||
|     this.columns = [ | ||||
|       { | ||||
|         title: '合同模板名称', | ||||
|         className: 'text-center', | ||||
|         render: 'templateName' | ||||
|       }, | ||||
|       { | ||||
|         title: '签约对象', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'signingObjectLabel' | ||||
|       }, | ||||
|       { | ||||
|         title: '合同类型', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'contractTypeLabel' | ||||
|       }, | ||||
|       { | ||||
|         title: '货源类型', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'resourceTypeLabel' | ||||
|       }, | ||||
|       { title: '创建人', index: 'createUserIdLabel', width: '120px', className: 'text-center' }, | ||||
|       { | ||||
|         title: '创建时间', | ||||
|         className: 'text-center', | ||||
|         index: 'createTime', | ||||
|         width: '200px' | ||||
|       }, | ||||
|       { | ||||
|         title: '操作', | ||||
|         fixed: 'right', | ||||
|         width: '110px', | ||||
|         className: 'text-center', | ||||
|         buttons: [ | ||||
|           { | ||||
|             text: '编辑', | ||||
|             click: (_record) => this.edit(_record), | ||||
|             acl: { ability: ['CONTRACT-TEMPLATE-edit'] }, | ||||
|           }, | ||||
|           { | ||||
|             text: '删除', | ||||
|             click: (_record) => this.delete(_record), | ||||
|             acl: { ability: ['CONTRACT-TEMPLATE-delete'] }, | ||||
|           }, | ||||
|         ], | ||||
|       }, | ||||
|     ]; | ||||
|   } | ||||
|   initSTAudit() { | ||||
|     this.schemaView = { | ||||
|       properties: { | ||||
|         handleResult: { | ||||
|           title: '处理结果', | ||||
|           type: 'string', | ||||
|           maxLength: 50, | ||||
|           ui: { | ||||
|             placeholder: '最多不超过50字', | ||||
|             widget: 'textarea', | ||||
|             autosize: { minRows: 3, maxRows: 6 } | ||||
|           }, | ||||
|         }, | ||||
|       }, | ||||
|       required: ['handleResult'] | ||||
|     }; | ||||
|     this.uiView = { '*': { spanLabelFixed: 110, grid: { span: 24 } } }; | ||||
|   } | ||||
|   /** | ||||
|    * 查询字段个数 | ||||
|    */ | ||||
|   get queryFieldCount(): number { | ||||
|     return Object.keys(this.schema?.properties || {}).length; | ||||
|   } | ||||
|  /** | ||||
|    * 伸缩查询条件 | ||||
|    */ | ||||
|   expandToggle(): void { | ||||
|     this._$expand = !this._$expand; | ||||
|     this.sf?.setValue('/_$expand', this._$expand); | ||||
|   } | ||||
|   tabChange(item: any) { | ||||
|   } | ||||
|   /** | ||||
|    * 重置表单 | ||||
|    */ | ||||
|   resetSF(): void { | ||||
|     this.sf.reset(); | ||||
|     this._$expand = false; | ||||
|   } | ||||
|  | ||||
|   edit(value: any) { | ||||
|     this.router.navigate(['/contract-management/template/text/' + value.id],{ | ||||
|       queryParams: { | ||||
|         status: 2 | ||||
|       } | ||||
|     }) | ||||
|   } | ||||
|   creatTemplate() { | ||||
|     this.router.navigate(['/contract-management/template/text/' + 0], { | ||||
|       queryParams: { | ||||
|         status: 1 | ||||
|       } | ||||
|     }) | ||||
|   } | ||||
|   goBack() { | ||||
|     window.history.go(-1) | ||||
|   } | ||||
|   view(value: any) { | ||||
|     this.router.navigate(['/contract-management/template/text/' + value.id],{ | ||||
|       queryParams: { | ||||
|         status: 3 | ||||
|       } | ||||
|     }) | ||||
|   } | ||||
|   delete(value: any) { | ||||
|     this.modal.confirm({ | ||||
|       nzTitle: '<i>删除确认</i>', | ||||
|       nzOnOk: () => | ||||
|         this.service.request(this.service.$api_deletebatch_contractTemplate, [value.id]).subscribe(res => { | ||||
|           if (res) { | ||||
|             this.service.msgSrv.success('删除成功!'); | ||||
|             this.st.reload(1) | ||||
|           } | ||||
|         }) | ||||
|     }); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,26 @@ | ||||
| <!-- | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-07 13:27:10 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-02-23 19:39:38 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\components\\index\\index.component.html | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
| --> | ||||
|  | ||||
| <page-header-wrapper title="合同管理" [tab]="tpTab"> | ||||
| </page-header-wrapper> | ||||
| <ng-template #tpTab> | ||||
|   <nz-tabset [(nzSelectedIndex)]="selectedIndex"> | ||||
|     <nz-tab nzTitle="明细合同"> | ||||
|       <app-contract-management-contract-list></app-contract-management-contract-list> | ||||
|     </nz-tab> | ||||
|     <nz-tab nzTitle="框架合同"> | ||||
|       <app-contract-management-contract-frame></app-contract-management-contract-frame> | ||||
|     </nz-tab> | ||||
|     <nz-tab nzTitle="合伙人合同"> | ||||
|       <app-contract-management-contract-partner></app-contract-management-contract-partner> | ||||
|     </nz-tab> | ||||
|   </nz-tabset> | ||||
| </ng-template> | ||||
| @ -0,0 +1,24 @@ | ||||
| import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; | ||||
| import { SupplyManagementIndexComponent } from './index.component'; | ||||
|  | ||||
| describe('SupplyManagementIndexComponent', () => { | ||||
|   let component: SupplyManagementIndexComponent; | ||||
|   let fixture: ComponentFixture<SupplyManagementIndexComponent>; | ||||
|  | ||||
|   beforeEach(waitForAsync(() => { | ||||
|     TestBed.configureTestingModule({ | ||||
|       declarations: [ SupplyManagementIndexComponent ] | ||||
|     }) | ||||
|     .compileComponents(); | ||||
|   })); | ||||
|  | ||||
|   beforeEach(() => { | ||||
|     fixture = TestBed.createComponent(SupplyManagementIndexComponent); | ||||
|     component = fixture.componentInstance; | ||||
|     fixture.detectChanges(); | ||||
|   }); | ||||
|  | ||||
|   it('should create', () => { | ||||
|     expect(component).toBeTruthy(); | ||||
|   }); | ||||
| }); | ||||
| @ -0,0 +1,27 @@ | ||||
| /* | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-07 13:27:10 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-01-18 17:17:01 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\components\\index\\index.component.ts | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
|  */ | ||||
|  | ||||
| import { Component, OnInit } from '@angular/core'; | ||||
| import { ModalHelper, _HttpClient } from '@delon/theme'; | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-supply-management-index', | ||||
|   templateUrl: './index.component.html', | ||||
| }) | ||||
| export class ContractManagementIndexComponent implements OnInit { | ||||
|   selectedIndex = 0; | ||||
|    | ||||
|   constructor(private http: _HttpClient, private modal: ModalHelper) { } | ||||
|  | ||||
|   ngOnInit(): void { } | ||||
|  | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,72 @@ | ||||
| <!-- | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-12 10:52:50 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-03-23 13:56:14 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\components\\policy\\policy.component.html | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
| --> | ||||
| <page-header-wrapper title="保单管理" > | ||||
| </page-header-wrapper> | ||||
| <nz-card> | ||||
|   <div nz-row nzGutter="8"> | ||||
|     <!-- 查询字段小于或等于3个时,不显示伸缩按钮 --> | ||||
|     <div nz-col nzSpan="24" *ngIf="queryFieldCount <= 4"> | ||||
|       <sf | ||||
|         #sf | ||||
|         [schema]="schema" | ||||
|         [ui]="ui" | ||||
|         [mode]="'search'" | ||||
|         [disabled]="!sf?.valid" | ||||
|         [loading]="false" | ||||
|         (formSubmit)="st?.load(1)" | ||||
|         (formReset)="resetSF()" | ||||
|       ></sf> | ||||
|     </div> | ||||
|  | ||||
|     <!-- 查询字段大于3个时,根据展开状态调整布局 --> | ||||
|     <ng-container> | ||||
|       <div nz-col [nzSpan]="_$expand ? 24 : 18"> | ||||
|         <sf #sf [schema]="schema" [ui]="ui" [compact]="true" [button]="'none'"></sf> | ||||
|       </div> | ||||
|       <div nz-col [nzSpan]="_$expand ? 24 : 6" [class.text-right]="_$expand"> | ||||
|         <button nz-button nzType="primary" [disabled]="!sf.valid" [nzLoading]="isLoading && st.loading" (click)="st?.load(1)"  acl  [acl-ability]="['CONTRACT-POLICY-search']">查询</button> | ||||
|         <button nz-button (click)="resetSF()">重置</button> | ||||
|         <button nz-button nzType="link" (click)="expandToggle()"> | ||||
|           {{ !_$expand ? '展开' : '收起' }} | ||||
|           <i nz-icon [nzType]="!_$expand ? 'down' : 'up'"></i> | ||||
|         </button> | ||||
|       </div> | ||||
|     </ng-container> | ||||
|   </div> | ||||
| </nz-card> | ||||
|  | ||||
| <nz-card> | ||||
|   <st | ||||
|     #st | ||||
|     [data]="service.$api_get_getPremiumInformationPage" | ||||
|     [columns]="columns" | ||||
|     [req]="{ method: 'POST', allInBody: true, reName: { pi: 'pageIndex', ps: 'pageSize' }, params: reqParams }" | ||||
|     [res]="{ reName: { list: 'data.records', total: 'data.total' } }" | ||||
|     [page]="{ show: true, showSize: true, pageSizes: [10, 20, 30, 50, 100, 200, 300, 500, 1000] }" | ||||
|     [loading]="false" | ||||
|   > | ||||
|  | ||||
|   </st> | ||||
| </nz-card> | ||||
|  | ||||
|  | ||||
| <ng-template #promoterModal> | ||||
|   <div nz-row nzGutter="8"> | ||||
|     <div nz-col nzSpan="24" se-container [labelWidth]="80"> | ||||
|       <sv-container col="1"> | ||||
|         <sv label="传入值" [col]="1"> | ||||
|           {{paramValue}} | ||||
|         </sv> | ||||
|       </sv-container> | ||||
|        | ||||
|     </div> | ||||
|   </div> | ||||
| </ng-template> | ||||
| @ -0,0 +1,24 @@ | ||||
| import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; | ||||
| import { ContractManagementPolicyComponent } from './policy.component'; | ||||
|  | ||||
| describe('ContractManagementPolicyComponent', () => { | ||||
|   let component: ContractManagementPolicyComponent; | ||||
|   let fixture: ComponentFixture<ContractManagementPolicyComponent>; | ||||
|  | ||||
|   beforeEach(waitForAsync(() => { | ||||
|     TestBed.configureTestingModule({ | ||||
|       declarations: [ ContractManagementPolicyComponent ] | ||||
|     }) | ||||
|     .compileComponents(); | ||||
|   })); | ||||
|  | ||||
|   beforeEach(() => { | ||||
|     fixture = TestBed.createComponent(ContractManagementPolicyComponent); | ||||
|     component = fixture.componentInstance; | ||||
|     fixture.detectChanges(); | ||||
|   }); | ||||
|  | ||||
|   it('should create', () => { | ||||
|     expect(component).toBeTruthy(); | ||||
|   }); | ||||
| }); | ||||
| @ -0,0 +1,213 @@ | ||||
| import { Component, OnInit, ViewChild } from '@angular/core'; | ||||
| import { STColumn, STComponent, STChange } from '@delon/abc/st'; | ||||
| import { SFComponent, SFSchema, SFDateWidgetSchema, SFUISchema } from '@delon/form'; | ||||
| import { ModalHelper, _HttpClient } from '@delon/theme'; | ||||
| import { NzModalService } from 'ng-zorro-antd/modal'; | ||||
| import { ContractManagementService } from '../../services/contract-management.service'; | ||||
| import { Router } from '@angular/router'; | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-contract-management-policy', | ||||
|   templateUrl: './policy.component.html' | ||||
| }) | ||||
| export class ContractManagementPolicyComponent implements OnInit { | ||||
|   @ViewChild('st', { static: true }) | ||||
|   st!: STComponent; | ||||
|   @ViewChild('sf', { static: false }) | ||||
|   sf!: SFComponent; | ||||
|   @ViewChild('auditModal', { static: false }) | ||||
|   auditModal!: any; | ||||
|   schema: SFSchema = {}; | ||||
|   columns: STColumn[] = []; | ||||
|   ui: SFUISchema = {}; | ||||
|   @ViewChild('promoterModal', { static: false }) | ||||
|   promoterModal!: any; | ||||
|   _$expand = false; | ||||
|  | ||||
|   selectedRows: any[] = []; | ||||
|   paramValue = ''; | ||||
|   isLoading: boolean = false; | ||||
|   constructor(public service: ContractManagementService, private modal: NzModalService, private router: Router) {} | ||||
|  | ||||
|   /** | ||||
|    * 查询参数 | ||||
|    */ | ||||
|   get reqParams() { | ||||
|     const params: any = { | ||||
|       ...(this.sf && this.sf.value) | ||||
|     }; | ||||
|     delete params.expand; | ||||
|     return params; | ||||
|   } | ||||
|  | ||||
|   ngOnInit(): void { | ||||
|     this.initST(); | ||||
|     this.initSF(); | ||||
|   } | ||||
|  | ||||
|   openDetail(item?: any) { | ||||
|       this.paramValue = item?.paramValue | ||||
|       const modal = this.modal.create({ | ||||
|         nzTitle: '传入值', | ||||
|         nzContent: this.promoterModal, | ||||
|         nzOnOk: () => { | ||||
|           return; | ||||
|         } | ||||
|       }); | ||||
|      | ||||
|   } | ||||
|  | ||||
|   initST() { | ||||
|     this.columns = [ | ||||
|       { title: '', type: 'checkbox', width: '50px', className: 'text-center' }, | ||||
|       { | ||||
|         title: '订单ID', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'billId' | ||||
|       }, | ||||
|       { | ||||
|         title: '项目ID', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'enterpriseProjectId' | ||||
|       }, | ||||
|       { | ||||
|         title: '保险公司', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'insuranceCompany' | ||||
|       }, | ||||
|       { | ||||
|         title: '投保金额', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'insureAmount' | ||||
|       }, | ||||
|        | ||||
|       { | ||||
|         title: '保单号', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'policyNo' | ||||
|       }, | ||||
|       { | ||||
|         title: '保单地址', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'policyUrl' | ||||
|       }, | ||||
|       { | ||||
|         title: '保费', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'premium' | ||||
|       }, | ||||
|       { | ||||
|         title: '处理消息', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'processMessage' | ||||
|       }, | ||||
|       { | ||||
|         title: '处理结果', | ||||
|         width: '100px', | ||||
|         className: 'text-center', | ||||
|         index: 'processResult' | ||||
|       }, | ||||
|       { | ||||
|         title: '操作', | ||||
|         width: '170px', | ||||
|         className: 'text-center', | ||||
|         buttons: [ | ||||
|           { | ||||
|             text: '查看传入值', | ||||
|             click: item => { | ||||
|               this.openDetail(item) | ||||
|             }, | ||||
|             acl: { ability: ['CONTRACT-POLICY-view'] }, | ||||
|           } | ||||
|         ] | ||||
|       } | ||||
|     ]; | ||||
|   } | ||||
|  | ||||
|   initSF() { | ||||
|     this.schema = { | ||||
|       properties: { | ||||
|         _$expand: { type: 'boolean', ui: { hidden: true } }, | ||||
|         billId: { | ||||
|           type: 'string', | ||||
|           title: '订单id' | ||||
|         }, | ||||
|         enterpriseProjectId: { | ||||
|           type: 'string', | ||||
|           title: '项目id' | ||||
|         }, | ||||
|         insuranceCompany: { | ||||
|           type: 'string', | ||||
|           title: '保险公司' | ||||
|         }, | ||||
|         policyNo: { | ||||
|           type: 'string', | ||||
|           title: '保单号', | ||||
|           ui: { | ||||
|             visibleIf: { | ||||
|               _$expand: (value: boolean) => value | ||||
|             }, | ||||
|           } | ||||
|         }, | ||||
|         processResult: { | ||||
|           type: 'string', | ||||
|           title: '处理结果', | ||||
|           enum: [ | ||||
|             { label: '全部', value: '' }, | ||||
|             { label: '成功', value: 1 }, | ||||
|             { label: '失败', value: 2 } | ||||
|           ], | ||||
|           ui: { | ||||
|             widget: 'select', | ||||
|             placeholder: '请选择', | ||||
|             visibleIf: { | ||||
|               _$expand: (value: boolean) => value | ||||
|             }, | ||||
|             allowClear: true | ||||
|           } | ||||
|         } | ||||
|       }, | ||||
|       type: 'object' | ||||
|     }; | ||||
|     this.ui = { '*': { spanLabelFixed: 110, grid: { span: 8, gutter: 4 } } }; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 重置表单 | ||||
|    */ | ||||
|   resetSF() { | ||||
|     this.sf.reset(); | ||||
|     this._$expand = false; | ||||
|     this.isLoading = true | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 伸缩查询条件 | ||||
|    */ | ||||
|   expandToggle(): void { | ||||
|     this._$expand = !this._$expand; | ||||
|     this.sf?.setValue('/_$expand', this._$expand); | ||||
|   } | ||||
|  | ||||
|   get queryFieldCount(): number { | ||||
|     return Object.keys(this.schema?.properties || {}).length; | ||||
|   } | ||||
|   stChange(e: STChange): void { | ||||
|     switch (e.type) { | ||||
|       case 'checkbox': | ||||
|         this.selectedRows = e.checkbox!; | ||||
|         break; | ||||
|       case 'filter': | ||||
|         this.st.load(); | ||||
|         break; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,26 @@ | ||||
| <!-- | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-07 13:27:10 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-02-24 14:10:45 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\components\\template\\template.component.html | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
| --> | ||||
|  | ||||
| <page-header-wrapper title="合同模板" [tab]="tpTab"> | ||||
| </page-header-wrapper> | ||||
| <ng-template #tpTab> | ||||
|   <nz-tabset [(nzSelectedIndex)]="selectedIndex"> | ||||
|     <nz-tab nzTitle="明细合同"> | ||||
|       <app-contract-management-template-detail-complaint></app-contract-management-template-detail-complaint> | ||||
|     </nz-tab> | ||||
|     <nz-tab nzTitle="框架合同"> | ||||
|       <app-contract-management-template-frame-complaint></app-contract-management-template-frame-complaint> | ||||
|     </nz-tab> | ||||
|     <nz-tab nzTitle="合伙人合同"> | ||||
|       <app-contract-management-template-partner-complaint></app-contract-management-template-partner-complaint> | ||||
|     </nz-tab> | ||||
|   </nz-tabset> | ||||
| </ng-template> | ||||
| @ -0,0 +1,24 @@ | ||||
| import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; | ||||
| import { ContractManagementTemplateComponent } from './template.component'; | ||||
|  | ||||
| describe('ContractManagementTemplateComponent', () => { | ||||
|   let component: ContractManagementTemplateComponent; | ||||
|   let fixture: ComponentFixture<ContractManagementTemplateComponent>; | ||||
|  | ||||
|   beforeEach(waitForAsync(() => { | ||||
|     TestBed.configureTestingModule({ | ||||
|       declarations: [ ContractManagementTemplateComponent ] | ||||
|     }) | ||||
|     .compileComponents(); | ||||
|   })); | ||||
|  | ||||
|   beforeEach(() => { | ||||
|     fixture = TestBed.createComponent(ContractManagementTemplateComponent); | ||||
|     component = fixture.componentInstance; | ||||
|     fixture.detectChanges(); | ||||
|   }); | ||||
|  | ||||
|   it('should create', () => { | ||||
|     expect(component).toBeTruthy(); | ||||
|   }); | ||||
| }); | ||||
| @ -0,0 +1,27 @@ | ||||
| /* | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-07 13:27:10 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-02-24 10:20:23 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\components\\template\\template.component.ts | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
|  */ | ||||
|  | ||||
| import { Component, OnInit } from '@angular/core'; | ||||
| import { ModalHelper, _HttpClient } from '@delon/theme'; | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-supply-management-template', | ||||
|   templateUrl: './template.component.html', | ||||
| }) | ||||
| export class ContractManagementTemplateComponent implements OnInit { | ||||
|   selectedIndex = 0; | ||||
|    | ||||
|   constructor(private http: _HttpClient, private modal: ModalHelper) { } | ||||
|  | ||||
|   ngOnInit(): void { } | ||||
|  | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,34 @@ | ||||
| /* | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-04 21:05:49 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-02-24 10:24:16 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\contract-management-routing.module.ts | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
|  */ | ||||
|  | ||||
| import { NgModule } from '@angular/core'; | ||||
| import { RouterModule, Routes } from '@angular/router'; | ||||
| import { ContractManagementDetailComponent } from './components/contract-detail/contract-detail.component'; | ||||
| import { ContractManagementContractListComponent } from './components/contract-list/contract-list.component'; | ||||
| import { ContractManagementPartnerComponent } from './components/contract-partner/contract-partner.component'; | ||||
| import { ContractManagementTemplateTextComponent } from './components/contract-template-detail/contract-template-detail.component'; | ||||
| import { ContractManagementIndexComponent } from './components/index/index.component'; | ||||
| import { ContractManagementPolicyComponent } from './components/policy/policy.component'; | ||||
| import { ContractManagementTemplateComponent } from './components/template/template.component'; | ||||
| const routes: Routes = [ | ||||
|   { path: 'index', component: ContractManagementIndexComponent }, | ||||
|   { path: 'index/detail/:id', component: ContractManagementDetailComponent }, | ||||
|   { path: 'template', component: ContractManagementTemplateComponent }, | ||||
|   { path: 'template/text/:id', component: ContractManagementTemplateTextComponent }, | ||||
|   { path: 'policy', component: ContractManagementPolicyComponent }, | ||||
|   { path: 'partner', component: ContractManagementPartnerComponent }, | ||||
| ]; | ||||
|  | ||||
| @NgModule({ | ||||
|   imports: [RouterModule.forChild(routes)], | ||||
|   exports: [RouterModule] | ||||
| }) | ||||
| export class ContractManagementManagementRoutingModule {} | ||||
| @ -0,0 +1,47 @@ | ||||
| /* | ||||
|  * @Description  :  | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-04 21:05:49 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-02-24 14:09:24 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\contract-management.module.ts | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
|  */ | ||||
|  | ||||
| import { NgModule } from '@angular/core'; | ||||
| import { CommonModule } from '@angular/common'; | ||||
| import { SharedModule } from '@shared'; | ||||
| import { ContractManagementManagementRoutingModule } from './contract-management-routing.module'; | ||||
| import { ContractManagementContractListComponent } from './components/contract-list/contract-list.component'; | ||||
| import { ContractManagementPolicyComponent } from './components/policy/policy.component'; | ||||
| import { ContractManagementTemplateDetailComponent } from './components/contract-template/contract-template.component'; | ||||
| import { ContractManagementIndexComponent } from './components/index/index.component'; | ||||
| import { ContractManagementFrameComponent } from './components/contract-frame/contract-frame.component'; | ||||
| import { ContractManagementDetailComponent } from './components/contract-detail/contract-detail.component'; | ||||
| import { ContractManagementPartnerComponent } from './components/contract-partner/contract-partner.component'; | ||||
| import { ContractManagementTemplateComponent } from './components/template/template.component'; | ||||
| import { ContractManagementTemplateTextComponent } from './components/contract-template-detail/contract-template-detail.component'; | ||||
| import { ContractManagementTemplateFrameComponent } from './components/contract-template-frame/contract-template-frame.component'; | ||||
| import { ContractManagementTemplatePartnerComponent } from './components/contract-template-partner/contract-template-partner.component'; | ||||
|  | ||||
| const COMPONENTS: any = [ | ||||
|   ContractManagementContractListComponent, | ||||
|   ContractManagementPolicyComponent, | ||||
|   ContractManagementTemplateDetailComponent, | ||||
|   ContractManagementTemplateDetailComponent, | ||||
|   ContractManagementIndexComponent, | ||||
|   ContractManagementFrameComponent, | ||||
|   ContractManagementDetailComponent, | ||||
|   ContractManagementPartnerComponent, | ||||
|   ContractManagementTemplateComponent, | ||||
|   ContractManagementTemplateTextComponent, | ||||
|   ContractManagementTemplateFrameComponent, | ||||
|   ContractManagementTemplatePartnerComponent | ||||
| ]; | ||||
| const NOTROUTECOMPONENTS: any = []; | ||||
| @NgModule({ | ||||
|   declarations: [...COMPONENTS, ...NOTROUTECOMPONENTS], | ||||
|   imports: [CommonModule, ContractManagementManagementRoutingModule, SharedModule] | ||||
| }) | ||||
| export class ContractManagementManagementModule {} | ||||
| @ -0,0 +1,41 @@ | ||||
| /* | ||||
|  * @Description  : | ||||
|  * @Version      : 1.0 | ||||
|  * @Author       : Shiming | ||||
|  * @Date         : 2022-01-04 21:05:49 | ||||
|  * @LastEditors  : Shiming | ||||
|  * @LastEditTime : 2022-02-24 10:00:59 | ||||
|  * @FilePath     : \\tms-obc-web\\src\\app\\routes\\contract-management\\services\\contract-management.service.ts | ||||
|  * Copyright (C) 2022 huzhenhong. All rights reserved. | ||||
|  */ | ||||
| import { Injectable, Injector } from '@angular/core'; | ||||
| import { BaseService } from 'src/app/shared/services'; | ||||
|  | ||||
| @Injectable({ | ||||
|   providedIn: 'root' | ||||
| }) | ||||
| export class ContractManagementService extends BaseService { | ||||
|   $api_get_getPremiumInformationPage = `/api/sdc/billOperate/listPremiumInformationPage`; | ||||
|   // 查询投诉列表 | ||||
|   $api_get_operate_listPage = `/api/sdc/complaint/operate/listPage`; | ||||
|   // 新增/更新信息 | ||||
|   $api_save_contractTemplate = `/api/sdc/contractTemplate/save`; | ||||
|   // 查询合同模板表 | ||||
|   $api_get_contractTemplate_page = `/api/sdc/contractTemplate/list/page`; | ||||
|   // 查询合同模板表详情 | ||||
|   $api_get_contractTemplate = `/api/sdc/contractTemplate/get`; | ||||
|   // 删除合同模板 | ||||
|   $api_deletebatch_contractTemplate = `/api/sdc/contractTemplate/deletebatch`; | ||||
|  | ||||
|   // 查询明细合同 | ||||
|   $api_listDetailed_page = `/api/sdc/contract/listDetailed/page`; | ||||
|   // 查询框架合同 | ||||
|   $api_listFrame_page = `/api/sdc/contract/listFrame/page`; | ||||
|   // 查询合伙人合同 | ||||
|   $api_listPartner_page = `/api/sdc/contract/listPartner/page`; | ||||
|   // 获取订单合同表 | ||||
|   $api_contract_get = `/api/sdc/contract/get`; | ||||
|   constructor(public injector: Injector) { | ||||
|     super(injector); | ||||
|   } | ||||
| } | ||||
| @ -1,9 +0,0 @@ | ||||
| <div class="modal-header"> | ||||
|   <div class="modal-title">编辑 {{ record.id }} 信息</div> | ||||
| </div> | ||||
| <sf  #sf mode="edit" [schema]="schema" [ui]="ui" [formData]="i" button="none"> | ||||
|   <div class="modal-footer"> | ||||
|     <button nz-button type="button" (click)="close()">关闭</button> | ||||
|     <button nz-button type="submit" nzType="primary" (click)="save(sf.value)" [disabled]="!sf.valid" [nzLoading]="http.loading">保存</button> | ||||
|   </div> | ||||
| </sf> | ||||
|  | ||||
| @ -1,6 +0,0 @@ | ||||
| @import '~@delon/theme/index'; | ||||
|  | ||||
| :host { | ||||
|   ::ng-deep { | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,66 +1,8 @@ | ||||
| import { Component, ChangeDetectionStrategy, ChangeDetectorRef, TemplateRef, ViewChild } from '@angular/core'; | ||||
| import { STComponent, STColumn, STData, STChange } from '@delon/abc/st'; | ||||
| import { SFSchema, SFUISchema } from '@delon/form'; | ||||
| import { _HttpClient } from '@delon/theme'; | ||||
| import { NzSafeAny } from 'ng-zorro-antd/core/types'; | ||||
| import { NzMessageService } from 'ng-zorro-antd/message'; | ||||
| import { NzModalRef, NzModalService } from 'ng-zorro-antd/modal'; | ||||
| import { map, tap } from 'rxjs/operators'; | ||||
| import { Component } from '@angular/core'; | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-dashboard', | ||||
|   templateUrl: './dashboard.component.html', | ||||
|   styleUrls: ['./dashboard.component.less'], | ||||
|   changeDetection: ChangeDetectionStrategy.OnPush | ||||
|   styleUrls: ['./dashboard.component.less'] | ||||
| }) | ||||
| export class DashboardComponent { | ||||
|   @ViewChild('sf') | ||||
|   sf!: SFSchema; | ||||
|   record: any = {}; | ||||
|   i: any; | ||||
|   schema: any = { | ||||
|     properties: { | ||||
|       no: { type: 'string', title: '编号' }, | ||||
|       owner: { type: 'string', title: '姓名' }, | ||||
|       callNo: { type: 'number', title: '调用次数' }, | ||||
|       href: { type: 'string', title: '链接', format: 'uri', ui: { errors: { uri: '11' } } }, | ||||
|       description: { type: 'string', title: '描述' } | ||||
|     }, | ||||
|     required: ['owner', 'callNo', 'href', 'description'] | ||||
|   }; | ||||
|   ui: SFUISchema = { | ||||
|     '*': { | ||||
|       spanLabelFixed: 100, | ||||
|       grid: { span: 12 } | ||||
|     }, | ||||
|     $no: { | ||||
|       widget: 'text' | ||||
|     }, | ||||
|     $href: { | ||||
|       widget: 'string' | ||||
|     }, | ||||
|     $description: { | ||||
|       widget: 'textarea', | ||||
|       grid: { span: 24 } | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   constructor(private msgSrv: NzMessageService, public http: _HttpClient) {} | ||||
|  | ||||
|   ngOnInit(): void { | ||||
|     // if (this.record.id > 0) this.http.get(`/user/${this.record.id}`).subscribe(res => (this.i = res)); | ||||
|   } | ||||
|  | ||||
|   save(value: any): void { | ||||
|     console.log(this.sf.value); | ||||
|  | ||||
|     // this.http.post(`/user/${this.record.id}`, value).subscribe(res => { | ||||
|     //   this.msgSrv.success('保存成功'); | ||||
|     //   // this.modal.close(true); | ||||
|     // }); | ||||
|   } | ||||
|  | ||||
|   close(): void { | ||||
|     // this.modal.destroy(); | ||||
|   } | ||||
| } | ||||
| export class DashboardComponent {} | ||||
|  | ||||
| @ -0,0 +1,58 @@ | ||||
| <!-- 页头 --> | ||||
| <page-header-wrapper [title]="'业务报表'"></page-header-wrapper> | ||||
| <nz-card nzTitle="运多星平台业务情况" [nzExtra]="extraTemplate"> | ||||
|   <ng-template #extraTemplate> | ||||
|     <div class="chooseBox"> | ||||
|       <button nz-button nzType="primary" (click)="exportFun()">导出</button> | ||||
|       <div class="timeBox"> | ||||
|         <nz-radio-group [(ngModel)]="mode" nzButtonStyle="solid" (ngModelChange)="changeData()"> | ||||
|           <label nz-radio-button nzValue="year">年</label> | ||||
|           <label nz-radio-button nzValue="month">月</label> | ||||
|           <label nz-radio-button nzValue="date">日</label> | ||||
|           <label nz-radio-button nzValue="define">自定义</label> | ||||
|         </nz-radio-group> | ||||
|         <div class="dateBox"> | ||||
|           <nz-date-picker [(ngModel)]="date" [nzMode]="mode" [nzFormat]="dateFormat" *ngIf="mode !== 'define'" [nzDisabledDate]="disabledDate" (ngModelChange)="onChange($event)"></nz-date-picker> | ||||
|           <nz-range-picker [(ngModel)]="defineDate" [nzFormat]="dateFormat" *ngIf="mode === 'define'" [nzDisabledDate]="disabledDate" (ngModelChange)="onChange($event)"></nz-range-picker> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </ng-template> | ||||
|   <st #st multiSort [columns]="columns" [ps]="20" [data]="service.$api_listPerformanceReportPage" | ||||
|     [req]="{ method: 'POST', allInBody: true, reName: { pi: 'pageIndex', ps: 'pageSize' }, params: reqParams }" | ||||
|     [scroll]="{ x: '1200px' }" [res]="{ reName: { list: 'data.records', total: 'data.total' } }" | ||||
|     [page]="{ show: true, showSize: true, pageSizes: [20, 50, 100] }"></st> | ||||
| </nz-card> | ||||
| <nz-card nzTitle="业绩报表" [nzExtra]="extraTemplate01"> | ||||
|   <ng-template #extraTemplate01> | ||||
|     <div class="chooseBox"> | ||||
|       <div class="timeBox"> | ||||
|         <nz-radio-group [(ngModel)]="modeNext" nzButtonStyle="solid" (ngModelChange)="changeDataNext()"> | ||||
|           <label nz-radio-button nzValue="year">年</label> | ||||
|           <label nz-radio-button nzValue="month">月</label> | ||||
|         </nz-radio-group> | ||||
|         <div class="dateBox"> | ||||
|           <nz-date-picker [(ngModel)]="dateNext" [nzDisabledDate]="disabledDate" [nzMode]="modeNext" (ngModelChange)="onChangeNext($event)"></nz-date-picker> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </ng-template> | ||||
|  | ||||
|   <div nz-row [nzGutter]="64"> | ||||
|     <div nz-col class="gutter-row" [nzSpan]="12"> | ||||
|       <div class="title"> | ||||
|         <div class="box" style="background-color: #3ba1ff;"></div> 环比(%) | ||||
|       </div> | ||||
|       <!-- <g2-custom delay="100" (render)="render($event)"></g2-custom> --> | ||||
|      <!-- <app-busitable-curve></app-busitable-curve> --> | ||||
|      <app-busitable-curve #curve [chartData]="chartData.chainRatio"></app-busitable-curve> | ||||
|     </div> | ||||
|     <div nz-col class="gutter-row" [nzSpan]="12"> | ||||
|       <div class="title"> | ||||
|         <div class="box" style="background-color: #f59a23;"></div> 业绩量(元) | ||||
|       </div> | ||||
|       <app-busitable-pillar #pillar [chartData]="chartData.performance"></app-busitable-pillar> | ||||
|     </div> | ||||
|   </div> | ||||
|    | ||||
| </nz-card> | ||||
| @ -0,0 +1,21 @@ | ||||
| .chooseBox{ | ||||
|     display: flex; | ||||
| } | ||||
| .timeBox{ | ||||
|     display: flex; | ||||
|     margin: 0 0 0 10px; | ||||
| } | ||||
| .dateBox{ | ||||
|     display: inline-block; | ||||
|     margin: 0 0 0 10px; | ||||
| } | ||||
| .title{ | ||||
|     display: flex; | ||||
|     align-items: center; | ||||
|     .box{ | ||||
|         width: 8px; | ||||
|         height: 8px; | ||||
|         margin-right: 10px; | ||||
|         border-radius: 100px; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,24 @@ | ||||
| import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; | ||||
| import { DatatableBusiindexComponent } from './busiindex.component'; | ||||
|  | ||||
| describe('DatatableBusiindexComponent', () => { | ||||
|   let component: DatatableBusiindexComponent; | ||||
|   let fixture: ComponentFixture<DatatableBusiindexComponent>; | ||||
|  | ||||
|   beforeEach(waitForAsync(() => { | ||||
|     TestBed.configureTestingModule({ | ||||
|       declarations: [ DatatableBusiindexComponent ] | ||||
|     }) | ||||
|     .compileComponents(); | ||||
|   })); | ||||
|  | ||||
|   beforeEach(() => { | ||||
|     fixture = TestBed.createComponent(DatatableBusiindexComponent); | ||||
|     component = fixture.componentInstance; | ||||
|     fixture.detectChanges(); | ||||
|   }); | ||||
|  | ||||
|   it('should create', () => { | ||||
|     expect(component).toBeTruthy(); | ||||
|   }); | ||||
| }); | ||||
| @ -0,0 +1,138 @@ | ||||
| import { Component, OnInit, ViewChild, NgZone } from '@angular/core'; | ||||
| import { STColumn, STComponent } from '@delon/abc/st'; | ||||
| import { DatePipe, _HttpClient } from '@delon/theme'; | ||||
| import { differenceInCalendarDays } from 'date-fns'; | ||||
| import { DataService } from '../../../services/data.service'; | ||||
| import { BusitablePillarComponent } from '../pillar/pillar.component'; | ||||
| import { BusitableCurveComponent } from './curve/curve.component'; | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-datatable-busiindex', | ||||
|   templateUrl: './busiindex.component.html', | ||||
|   styleUrls: ['./busiindex.component.less'], | ||||
|   providers: [DatePipe] | ||||
|  | ||||
| }) | ||||
| export class DatatableBusiindexComponent implements OnInit { | ||||
|   @ViewChild('st') private readonly st!: STComponent; | ||||
|   @ViewChild('curve') private readonly curve!: BusitableCurveComponent; | ||||
|   @ViewChild('pillar') private readonly pillar!: BusitablePillarComponent; | ||||
|   type = 1; | ||||
|   mode = 'year'; | ||||
|   date: any = null; | ||||
|   time: any = ['2022-01-01 00:00:00'] | ||||
|   defineDate = []; | ||||
|   dateNext: any = null; | ||||
|   modeNext = 'year'; | ||||
|   timeNext: any = ['2022-01-01 00:00:00'] | ||||
|   dateFormat = 'yyyy'; | ||||
|   today = new Date(); | ||||
|   chartData: any = {} | ||||
|  | ||||
|   columns: STColumn[] = [ | ||||
|     { title: '运营主体', index: 'networkTransporterName', className: 'text-center' }, | ||||
|     { title: '合伙人数', index: 'partnerNumber', className: 'text-center' }, | ||||
|     { title: '客户数', index: 'enterpriseNumbe', className: 'text-center' }, | ||||
|     { title: '订单数', index: 'zsl', className: 'text-center' }, | ||||
|     { title: '客户预存款', index: 'czcgje', className: 'text-right', type: 'widget', widget: { type: 'currency-chy', params: ({ record }) => ({ value: record.czcgje }) } }, | ||||
|     { title: '业绩量', index: 'yisje', className: 'text-center' }, | ||||
|     { title: '已收附加费', index: 'yisfjf', className: 'text-right', type: 'widget', widget: { type: 'currency-chy', params: ({ record }) => ({ value: record.yisfjf }) } }, | ||||
|     { title: '平均附加费率', index: 'fjfl', className: 'text-center',format: (item)=> { | ||||
|       return item.fjfl + '%' | ||||
|     } }, | ||||
|     { title: '已开票金额', index: 'ykpje', className: 'text-right', type: 'widget', widget: { type: 'currency-chy', params: ({ record }) => ({ value: record.ykpje }) } }, | ||||
|   ]; | ||||
|   /** | ||||
|    * 查询参数 | ||||
|    */ | ||||
|    get reqParams() { | ||||
|     if(this.mode === 'year') { | ||||
|       this.type = 1 | ||||
|     } else if(this.mode === 'month') { | ||||
|       this.type = 2 | ||||
|     } else if(this.mode === 'date') { | ||||
|       this.type = 3 | ||||
|     } else { | ||||
|       this.type = 4 | ||||
|     } | ||||
|     let params: any = { | ||||
|       time: this.time, | ||||
|       type: this.type | ||||
|      }; | ||||
|    | ||||
|     delete params._$expand; | ||||
|     return { ...params }; | ||||
|   } | ||||
|  | ||||
|   constructor(public service: DataService, private datePipe: DatePipe,  private ngZone: NgZone) { } | ||||
|   ngOnInit(): void { | ||||
|     this.initData() | ||||
|   } | ||||
|   initData(flag?: boolean){ | ||||
|     let type = 1 | ||||
|     if(this.mode === 'year') { | ||||
|       type = 1 | ||||
|     } else if(this.mode === 'month') { | ||||
|       type = 2 | ||||
|     } | ||||
|     const params: any = { | ||||
|       time: this.timeNext, | ||||
|       type | ||||
|      }; | ||||
|     this.service.request(this.service.$api_performanceReportHistogram, params).subscribe(res => { | ||||
|       if (res) { | ||||
|         this.chartData = res | ||||
|         if(flag) { | ||||
|           this.pillar.reRender() | ||||
|           this.curve.reRender() | ||||
|         } | ||||
|       } | ||||
|     }) | ||||
|   } | ||||
|   changeData(){ | ||||
|     if(this.mode === 'year') { | ||||
|       this.dateFormat = 'yyyy' | ||||
|     } else if(this.mode === 'month') { | ||||
|       this.dateFormat = 'yyyy-MM' | ||||
|     } else { | ||||
|       this.dateFormat = 'yyyy-MM-dd' | ||||
|     }  | ||||
|   } | ||||
|   onChange(result: any) { | ||||
|     if(this.mode === 'year') { | ||||
|       this.time = [this.datePipe.transform(this.date, 'yyyy') + '-01-01 00:00:00'] | ||||
|     } else if(this.mode === 'month') { | ||||
|       this.time = [this.datePipe.transform(this.date, 'yyyy-MM') + '-01 00:00:00'] | ||||
|     } else if(this.mode === 'date') { | ||||
|       this.time = [this.datePipe.transform(this.date, 'yyyy-MM-dd') + ' 00:00:00'] | ||||
|     } else{ | ||||
|       this.time = [this.datePipe.transform(this.defineDate[0], 'yyyy-MM-dd') + '00:00:00', this.datePipe.transform(this.defineDate[1], 'yyyy-MM-dd') + ' 00:00:00'] | ||||
|     } | ||||
|     this.st.reload({ ...this.reqParams }); | ||||
|   } | ||||
|  | ||||
|   changeDataNext() { | ||||
|     if(this.mode === 'year') { | ||||
|       this.dateFormat = 'yyyy' | ||||
|     } else if(this.mode === 'month') { | ||||
|       this.dateFormat = 'yyyy-MM' | ||||
|     } | ||||
|   } | ||||
|   onChangeNext(result: any) { | ||||
|     if(result === null) { | ||||
|       return | ||||
|     } | ||||
|     if(this.mode === 'year') { | ||||
|       this.timeNext = [this.datePipe.transform(this.dateNext, 'yyyy') + '-01-01 00:00:00'] | ||||
|     } else if(this.mode === 'month') { | ||||
|       this.timeNext = [this.datePipe.transform(this.dateNext, 'yyyy-MM') + '-01 00:00:00'] | ||||
|     } | ||||
|     this.initData(true) | ||||
|   } | ||||
|   disabledDate = (current: Date): boolean => | ||||
|     // Can not select days before today and today | ||||
|     differenceInCalendarDays(current, this.today) > 0; | ||||
|   exportFun(){ | ||||
|  | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1 @@ | ||||
| <g2-custom delay="200" (render)="render($event)"></g2-custom> | ||||
| @ -0,0 +1,68 @@ | ||||
| import { Component, ElementRef, Input, NgZone, OnChanges, OnInit, SimpleChanges, ViewChild } from '@angular/core'; | ||||
| import { Chart } from '@antv/g2'; | ||||
| import { DataService } from 'src/app/routes/datatable/services/data.service'; | ||||
| @Component({ | ||||
|   selector: 'app-busitable-curve', | ||||
|   templateUrl: './curve.component.html', | ||||
|   styleUrls: ['./curve.component.less'] | ||||
| }) | ||||
| export class BusitableCurveComponent implements OnInit, OnChanges { | ||||
|   el: any; | ||||
|   @Input() chartData: any; | ||||
|   chart: any; | ||||
|   constructor(private service: DataService, private ngZone: NgZone) { | ||||
|  | ||||
|   } | ||||
|   ngOnChanges(changes: SimpleChanges): void { | ||||
|     if (this.chartData) { | ||||
|       // setTimeout(()=>{ | ||||
|       //   this.chart.render(true) | ||||
|       // }, 1000) | ||||
|  | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   ngOnInit(): void { | ||||
|  | ||||
|   } | ||||
|   reRender() { | ||||
|       this.chart.data(this.chartData); | ||||
|       this.chart.render(); | ||||
|   } | ||||
|   render(el: ElementRef<HTMLDivElement>): void { | ||||
|     this.el = el.nativeElement | ||||
|     setTimeout(() => { | ||||
|       this.ngZone.runOutsideAngular(() => this.init(this.el)); | ||||
|       }, 500) | ||||
|   } | ||||
|  | ||||
|   private init(el: HTMLElement): void { | ||||
|     this.chart = new Chart({ | ||||
|       container: el, | ||||
|       autoFit: true, | ||||
|       height: 500, | ||||
|     }); | ||||
|  | ||||
|     this.chart.data(this.chartData); | ||||
|     this.chart.scale({ | ||||
|       year: { | ||||
|         range: [0, 1], | ||||
|       }, | ||||
|       value: { | ||||
|         min: 0, | ||||
|         nice: true, | ||||
|       }, | ||||
|     }); | ||||
|  | ||||
|     this.chart.tooltip({ | ||||
|       showCrosshairs: true, // 展示 Tooltip 辅助线 | ||||
|       shared: true, | ||||
|     }); | ||||
|  | ||||
|     this.chart.line().position('time*value').label('value'); | ||||
|     this.chart.point().position('time*value'); | ||||
|  | ||||
|     this.chart.render(); | ||||
|   } | ||||
|  | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user