提交 938f4a39 编写于 作者: IBZGIT01's avatar IBZGIT01

ibizdev提交

上级 8e3cec50
MIT License
Copyright (c) 2019 dev_ibizsys
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
# ionic_R6
#### Description
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
\ No newline at end of file
# ionic_R6
#### 介绍
{**以下是码云平台说明,您可以替换此简介**
码云是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台
无论是个人、团队、或是企业,都能够用码云实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
#### 软件架构
软件架构说明
#### 安装教程
1. xxxx
2. xxxx
3. xxxx
#### 使用说明
1. xxxx
2. xxxx
3. xxxx
#### 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
#### 码云特技
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目
5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
\ No newline at end of file
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const { SpecReporter } = require('jasmine-spec-reporter');
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./src/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.e2e.json')
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
};
import { AppPage } from './app.po';
describe('new App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
});
it('should display welcome message', () => {
page.navigateTo();
expect(page.getPageTitle()).toContain('Tab One');
});
});
import { browser, by, element } from 'protractor';
export class AppPage {
navigateTo() {
return browser.get('/');
}
getPageTitle() {
return element(by.css('ion-title')).getText();
}
}
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"module": "commonjs",
"target": "es5",
"types": [
"jasmine",
"jasminewd2",
"node"
]
}
}
{
"name": "myApp",
"integrations": {},
"type": "angular"
}
因为 它太大了无法显示 源差异 。您可以改为 查看blob
{
"name": "myApp",
"version": "0.0.1",
"author": "Ionic Framework",
"homepage": "https://ionicframework.com/",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
"private": true,
"dependencies": {
"@angular/common": "^7.2.2",
"@angular/core": "^7.2.2",
"@angular/forms": "^7.2.2",
"@angular/http": "^7.2.2",
"@angular/platform-browser": "^7.2.2",
"@angular/platform-browser-dynamic": "^7.2.2",
"@angular/router": "^7.2.2",
"@ionic-native/core": "^5.0.0",
"@ionic-native/splash-screen": "^5.0.0",
"@ionic-native/status-bar": "^5.0.0",
"@ionic/angular": "^4.1.0",
"core-js": "^2.5.4",
"echarts": "4.1.0",
"moment": "^2.24.0",
"ng-zorro-antd-mobile": "^0.12.0",
"ng2-file-upload": "^1.3.0",
"rxjs": "~6.5.1",
"tslib": "^1.9.0",
"zone.js": "~0.8.29"
},
"devDependencies": {
"@angular-devkit/architect": "~0.13.8",
"@angular-devkit/build-angular": "~0.13.8",
"@angular-devkit/core": "~7.3.8",
"@angular-devkit/schematics": "~7.3.8",
"@angular/cli": "~7.3.8",
"@angular/compiler": "~7.2.2",
"@angular/compiler-cli": "~7.2.2",
"@angular/language-service": "~7.2.2",
"@ionic/angular-toolkit": "~1.5.1",
"@types/jasmine": "~2.8.8",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~10.14.2",
"codelyzer": "~4.5.0",
"jasmine-core": "~2.99.1",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~4.1.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~1.1.2",
"karma-jasmine-html-reporter": "^0.2.2",
"protractor": "~5.4.0",
"ts-node": "~8.1.0",
"tslint": "~5.16.0",
"typescript": "~3.1.6"
},
"description": "An Ionic project"
}
{
"/": {
"target": "http://127.0.0.1:8080/test"
}
}
\ No newline at end of file
<ion-app>
<ion-router-outlet></ion-router-outlet>
</ion-app>
import { Component } from '@angular/core';
import { Platform } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { AppInitService } from '@global/service/appInit.service';
import { CodeList } from '@global/service/codelist';
import { App } from '@global/service/App';
import { SettingsService } from '@global/service/Settings';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html'
})
export class AppComponent {
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
private appInitService: AppInitService,
private app: App,
private themeSetting:SettingsService
) {
this.initializeApp();
}
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleDefault();
this.splashScreen.hide();
});
const url: URL = new URL(window.location.href);
if (Object.is(url.hash, '') || Object.is(url.hash, '#/')) {
const startUrl: string = this.app.getStartPage();
if (startUrl && !Object.is(startUrl, '')) {
window.location.href = url.origin + url.pathname + '#' + startUrl;
}
}
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClientModule,HTTP_INTERCEPTORS } from '@angular/common/http';
import { RouteReuseStrategy } from '@angular/router';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LocationStrategy, HashLocationStrategy } from '@angular/common';
import { AppInitService } from '@global/service/appInit.service';
import { Http } from '@global/service/Http';
import { App } from '@global/service/App';
import { AppNotification } from '@global/service/Notification';
import { CodeList } from '@global/service/codelist';
import Interceptors from '@global/service/interceptor';
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule,HttpClientModule,BrowserAnimationsModule,IonicModule.forRoot(), AppRoutingModule],
providers: [
StatusBar,
SplashScreen,
{ provide: LocationStrategy, useClass: HashLocationStrategy },
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
{ provide: HTTP_INTERCEPTORS, useClass: Interceptors, multi: true },
AppInitService,
Http,
App,
CodeList,
AppNotification
],
bootstrap: [AppComponent]
})
export class AppModule {
}
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1547534604236" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="553" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M511.990608 186.50543a325.503963 325.503963 0 1 0 325.503962 325.503962 325.503963 325.503963 0 0 0-325.503962-325.503962z m-77.375005 108.263974a122.063986 122.063986 0 0 1 64.151406-26.515011 123.691506 123.691506 0 1 1-64.151406 26.515011z m292.038087 419.221978c-0.644227 11.731705-7.391652 20.038838-17.461931 25.972504a97.006962 97.006962 0 0 1-33.22853 11.019665c-27.73565 4.916466-55.810367 5.153813-83.851177 5.357253-26.955797 0.20344-53.911594 0-80.867391 0-28.820663 0-57.641327 0.271253-86.394176 0-18.275691-0.237347-36.551382-0.91548-54.759261-2.203933a151.054183 151.054183 0 0 1-48.283088-10.171999 40.416742 40.416742 0 0 1-20.750877-16.953331 33.906663 33.906663 0 0 1-3.96708-15.936132 156.987849 156.987849 0 0 1 19.937118-85.580417 162.989328 162.989328 0 0 1 86.46199-73.306204 170.414887 170.414887 0 0 1 60.591206-10.646693h95.989763a166.820781 166.820781 0 0 1 111.891987 41.027062 155.495955 155.495955 0 0 1 52.72486 91.887056 166.142648 166.142648 0 0 1 1.966587 39.535169z m-44.383822-98.329322a14.681585 14.681585 0 0 0-19.869304-2.475186c-29.05801 21.157758-105.653161 76.968124-119.351453 87.17403-16.953331 12.579372-33.533689 37.873742-33.53369 37.873742l2.543 4.306146s16.546451-0.5086 45.977435-18.038344c23.463411-13.969545 94.090989-67.542072 122.063986-88.869363a13.969545 13.969545 0 0 0 2.33956-20.004931z" p-id="554"></path><path d="M511.990608 1024C225.275867 1024-7.154306 787.094147 0.169533 498.751887 7.222119 220.615532 238.262119-2.354682 516.500194 0.018784a508.294782 508.294782 0 0 1 277.186968 84.359777 16.512545 16.512545 0 0 1 4.340053 23.327784A16.478638 16.478638 0 0 1 775.445378 111.910771a479.033332 479.033332 0 0 0-742.555915 400.098621c0 264.098996 214.866522 478.965518 478.965518 478.965518s479.101145-214.866522 479.101145-478.965518A473.438732 473.438732 0 0 0 945.995891 309.315362a16.580358 16.580358 0 0 1 7.425559-21.801984 16.546451 16.546451 0 0 1 22.446211 7.662906A506.192569 506.192569 0 0 1 1023.981216 512.009392c0 282.306874-229.683734 511.990608-511.990608 511.990608z" p-id="555"></path><path d="M927.00816 223.361972m-18.648664 0a18.648665 18.648665 0 1 0 37.297329 0 18.648665 18.648665 0 1 0-37.297329 0Z" p-id="556"></path></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1546946578477" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3171" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M216.327 223.774h616.465q27.01 0 46.076 19.066t19.066 46.076v467.115q0 27.01-19.066 46.076t-46.076 19.066H216.327q-26.216 0-46.076-19.066-19.066-19.066-19.066-46.076V591.587v-47.665-30.982-45.282-178.743q0-27.01 19.066-46.076 19.86-19.066 46.076-19.066z m0 631.559h616.465q41.31 0 69.908-28.599 27.804-28.599 27.804-69.114V289.71q0-40.515-27.804-69.114-28.599-28.599-69.908-28.599H216.327q-40.515 0-69.114 28.599-28.599 28.599-28.599 69.114V757.619q0 39.721 28.599 68.32 28.599 29.393 69.114 29.393z m46.076-429.778q0 28.599 19.86 48.459 20.655 20.655 49.254 20.655 28.599 0 49.254-20.655 19.86-19.86 19.86-48.459 0-28.599-19.86-48.459-20.655-20.655-49.254-20.655-28.599 0-49.254 20.655t-19.86 48.459z m32.571 0q0-15.094 11.122-26.216 10.327-10.327 25.421-10.327t25.421 10.327q11.122 11.122 11.122 26.216 0 15.094-11.122 26.216-10.327 10.327-25.421 10.327-14.299 0-25.421-10.327t-11.122-26.216z m368.608 67.526L835.97 665.469q5.561 5.561 5.561 11.122 0 6.355-5.561 11.916-5.561 6.355-11.916 6.355-5.561 0-11.122-6.355L640.544 516.119q-8.739-8.739-22.244-8.739-14.299 0-23.832 8.739-46.076 46.076-138.228 137.434-19.066 19.066-46.87 19.066-27.01 0-46.87-19.066-7.15-7.15-21.449-22.244-9.533-8.739-23.832-8.739-13.505 0-22.244 8.739l-57.198 57.198q-11.122 11.916-23.038 0-5.561-5.561-5.561-11.122t5.561-11.916l57.198-57.198q19.066-19.066 46.87-19.066 27.01 0 46.87 19.066 7.15 7.15 21.449 22.244 8.739 8.739 22.244 8.739 14.299 0 23.832-8.739 45.282-46.076 136.639-137.434 19.86-19.066 47.665-19.066 27.01 0 46.076 19.066z" p-id="3172"></path></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1552038197448" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4596" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="48"><defs><style type="text/css"></style></defs><path d="M748.307692 163.446154v697.107692c0 19.692308-25.6 33.476923-43.323077 17.723077L287.507692 537.6c-15.753846-11.815385-15.753846-37.415385 0-49.230769L704.984615 143.753846c17.723077-13.784615 43.323077-1.969231 43.323077 19.692308z" p-id="4597"></path></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1546848026758" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2109" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M172.4 775.4l0.7 0.7c6.7 6.4 16.2 9.7 26 8l229.5-40.5c6.3-1.1 11.8-4.2 16-8.4l0.1 0.1L857 322.7c35.1-35.1 35.1-92.2 0-127.3L752.4 90.7c-17-17-39.6-26.3-63.6-26.3s-46.7 9.3-63.6 26.3L212.8 503.3l0.1 0.1c-4.2 4.2-7.3 9.7-8.4 16L164 749.1c-1.6 9.9 1.8 19.6 8.4 26.3z m377.7-524.8l147.1 147.2-288 288.3-178.6 31.5 31.5-178.7 288-288.3z m117.4-117.5c5.6-5.6 13.1-8.7 21.2-8.7s15.6 3.1 21.2 8.7l104.7 104.7c11.7 11.7 11.7 30.8 0 42.5l-74.9 75-147.1-147.2 74.9-75zM929 900.4H93c-16.5 0-30 13.5-30 30s13.5 30 30 30h836c16.5 0 30-13.5 30-30s-13.5-30-30-30z" p-id="2110"></path></svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="37px" height="37px" viewBox="0 0 37 37" enable-background="new 0 0 37 37" xml:space="preserve"> <image id="image0" width="37" height="37" x="0" y="0"
href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAAlCAMAAADyQNAxAAAABGdBTUEAALGPC/xhBQAAACBjSFJN
AAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAC3FBMVEX///+T4u1Dzt8DvdQA
vNMAvNMAvNMAvNMAvNMDvdRDzt902ecHvtQAvNMAvNMHvtSN4OwQwNYAvNMHvtQAvNMQwNZR0eIA
vNMAvNPg9/ouyNwdw9gAvNMwydzu+vwlxdoAvNMnxtpDzt9v2eYsx9vP8vcHvNQTwdcDvdRIzuC8
7fMnxtsAvNNR0eH3/P0Mv9UYwdcMv9ay6/IAvNNo1+VIzuAuyNwMvdQTwdcgxNkMvdQxyNwZw9g1
yd1M0OF32+jG7/X+/v4bwtcTwdcsx9tn1+Xa9fkDvdRT0uIDvdRp2OWx6/Ho+foMv9X+/v7+/v6h
5u/+/v7+/v5z2uf+/v79/v5Lz+D+/v7+/v74/f1i1uU7y96c5e6P4ewDvdQMv9XI8PY+zN5Ezd+y
6/IuyNw+zN7U9PiE3uo0yt04y9163OgAvNMMv9ZR0eF02eeM4Oul5/BR0eIMvdRj1eW27PL3/P3+
/v74/f1k1uRY0+Pc9vng9/pb1OMZw9jF7/XI8PY0yt3k+Pum5/AuyNsQwNZFzuDT8/fo+fo7y95D
zt+n6PADvdTi9/pLz+Alxdrv+vwxyNyh5u/1/P173Ojx+/zX9fgTwdfw+vyg5u+O4exM0OFP0eGc
5e6Y5O6X5O0jxNnO8fb8/v77/f563Ohu2Oai5+/9/v6t6vL5/f0HvtVZ0+Nc1ORy2edi1uWq6PFF
zt/u+vyy6/IMv9W87fPq+ftv2eaK4OtAzd/0+/1l1uTp+vtT0uK77PPr+fsgxNk3yt0nxtuK3+sy
ydyp6PHs+vvJ8PYdw9iU4+0+zN5h1eVl1+Rs2eWH3uoHvtTb9vmv6vGE3uqB3enO8vcnxtqx6vHH
8PU8zN6r6fHU9Pis6fJp2OXw+/x62+hO0OHP8vcwydw1yd2e5u9n1+Upx9vy+/wsx9tJz+D2/P04
y93I8PW67PPf9vnC7/S37fJHz+BU0uJ12ueO4OyW4+3///8rU5UbAAAAa3RSTlMAH1iKtdjw/opY
H0eU3ZRHOpj09Jg6a9VrEon+iRISkpISiWv+OtXVOphH9EeUH93dH1hYirXY2PDw/v7w2LWKWB/d
3R+UR/T0R5iYOtXVOmv+a4mJEpKSEhKJ/olr1Ws6mDpHlEcfWIpYHy5FZtQAAAABYktHRACIBR1I
AAAAB3RJTUUH4wETAToi0sPn5wAAAp9JREFUOMt1lOVbVEEUxkdZWIxFXVEM7O7AFru7uzteBCQu
KRhX2rUQJQRdFFhBwBZFEEVAERVbsbvrL/Au7sydDc+H+8x5z++ZOXPumUMIZ1WqWimsbZQ21grb
atWJZatRUwWXDa5u7u5urhtdVHa1LDC166g9PL28BYP5ePnWta9nCtV3gJ+/YGQBgQ4NjJiGjZSb
ggQzC27s2ESGmjbD5i2GyNZt4vYQioWGNW/BqJYIpwlFAJEQo1h6Oxwp1Eqp2UnlXdi9xw972aHR
rQ25tWkr7mNqTOR+4QA85dz827WvpDogVhbjEJ+gwUHuCon2eqijOslH1g5BsvDDHKXt1FmiusCd
05KBI0dTjOqRakdI125imqxE6TxMaisIKd17kJ44xinpyDAv7nEn0guZ1AvJigGyzakTtqQ3aAkD
TkoFxSlz6rSC9AFN6wwy0s7inH55PkcU0y8wrC/pF0PXF5ErXAJ0eflx0leHMFaP/mTAZbouwJWr
foCor1hedqEG12hkIHFme3nnS+GiKME7oBglgnAdXjTiTAZBS520xBtuhZWdAJTeLNOF0sawJoPZ
HTnTHxqZQL1bCjIEqWbQbeBO+V3m5tqSoUg3hbT3cJ/3S53IsOGi1oh58FA6jhd8RowkZBQe8drj
Mn1S/FN5IvUEGT1Gw2/miacVz/CcU8aO07fheBRzWpb0J1/gJadMqOzoiZNErqeS8ep1Cd7IwuQp
/57HVOXbCia+ey+llST/6WnT6VObgQ9sQAgfY30LouWtZrJXO2s2PoUKFm3OXHkEzJuvLPpsjnxZ
sJCDJFu0GIFfjZlvJQ5LTEfT0mXqspzv7GWmBP1Q2y+3MOdWrFRB/Pnrd0Tmn/J4UWW36j8zc/Wa
tYa5arVuPR/4CyeiB37+cbpVAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE5LTAxLTE4VDE3OjU4OjM0
KzA4OjAwys3J3AAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOS0wMS0xOFQxNzo1ODozNCswODowMLuQ
cWAAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAAAElFTkSuQmCC" />
</svg>
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1552099203268" class="icon" style="" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1084" xmlns:xlink="http://www.w3.org/1999/xlink" width="32.03125" height="32"><defs><style type="text/css"></style></defs><path d="M0 572.14976h695.07584v240.39936l324.80256-299.66848-324.80256-299.71456V453.5296H0v118.62016z" fill="#CC5323" p-id="1085"></path></svg>
\ No newline at end of file
<svg width="350" height="140" xmlns="http://www.w3.org/2000/svg" style="background:#f6f7f9"><g fill="none" fill-rule="evenodd"><path fill="#F04141" style="mix-blend-mode:multiply" d="M61.905-34.23l96.194 54.51-66.982 54.512L22 34.887z"/><circle fill="#10DC60" style="mix-blend-mode:multiply" cx="155.5" cy="135.5" r="57.5"/><path fill="#3880FF" style="mix-blend-mode:multiply" d="M208.538 9.513l84.417 15.392L223.93 93.93z"/><path fill="#FFCE00" style="mix-blend-mode:multiply" d="M268.625 106.557l46.332-26.75 46.332 26.75v53.5l-46.332 26.75-46.332-26.75z"/><circle fill="#7044FF" style="mix-blend-mode:multiply" cx="299.5" cy="9.5" r="38.5"/><rect fill="#11D3EA" style="mix-blend-mode:multiply" transform="rotate(-60 148.47 37.886)" x="143.372" y="-7.056" width="10.196" height="89.884" rx="5.098"/><path d="M-25.389 74.253l84.86 8.107c5.498.525 9.53 5.407 9.004 10.905a10 10 0 0 1-.057.477l-12.36 85.671a10.002 10.002 0 0 1-11.634 8.42l-86.351-15.226c-5.44-.959-9.07-6.145-8.112-11.584l13.851-78.551a10 10 0 0 1 10.799-8.219z" fill="#7044FF" style="mix-blend-mode:multiply"/><circle fill="#0CD1E8" style="mix-blend-mode:multiply" cx="273.5" cy="106.5" r="20.5"/></g></svg>
import ViewEngine from './view-engine';
/**
* 编辑视图引擎
*
* @export
* @class EditViewEngine
* @extends {ViewEngine}
*/
export default class EditViewEngine extends ViewEngine {
/**
* 表单部件
*
* @protected
* @type {*}
* @memberof EditViewEngine
*/
protected form: any;
/**
* 父健为当前健
*
* @protected
* @type {string}
* @memberof EditViewEngine
*/
protected p2k: string = '';
/**
* 初始化编辑视图引擎
*
* @param {*} [options={}]
* @memberof EditViewEngine
*/
public init(options: any = {}): void {
this.form = options.form;
this.p2k = options.p2k;
super.init(options);
}
/**
* 引擎加载
*
* @param {*} [opts={}]
* @memberof EditViewEngine
*/
public load(opts: any = {}): void {
super.load(opts);
if (this.getForm()) {
const tag = this.getForm().name;
if (Object.is(this.p2k, '1') && this.viewdata.srfparentdata && !Object.is(this.viewdata.srfparentdata.srfparentkey, '')) {
Object.assign(this.viewdata, { srfkey: this.viewdata.srfparentdata.srfparentkey });
}
const action: string = this.viewdata.srfkey && !Object.is(this.viewdata.srfkey, '') ? 'load' : 'loaddraft';
this.setViewState2({ tag: tag, action: action, viewdata: this.viewdata });
}
}
/**
* 部件事件机制
*
* @param {string} ctrlName
* @param {string} eventName
* @param {*} args
* @memberof EditViewEngine
*/
public onCtrlEvent(ctrlName: string, eventName: string, args: any): void {
super.onCtrlEvent(ctrlName, eventName, args);
if (Object.is(ctrlName, 'form')) {
this.formEvent(eventName, args);
}
}
/**
* 表单事件
*
* @param {string} eventName
* @param {*} args
* @memberof EditViewEngine
*/
public formEvent(eventName: string, args: any): void {
if (Object.is(eventName, 'load')) {
this.onFormLoad(args);
}
if (Object.is(eventName, 'save')) {
this.onFormSave(args);
}
if (Object.is(eventName, 'remove')) {
this.onFormRemove(args);
}
}
/**
* 表单加载完成
*
* @param {*} args
* @memberof EditViewEngine
*/
public onFormLoad(args: any): void {
if (Object.is(args.srfuf, '1')) {
this.view.datainfo = args.srfmajortext;
this.view.viewdataschange.emit({action:'load',items:args});
}
}
/**
* 表单保存完成
*
* @param {*} args
* @memberof EditViewEngine
*/
public onFormSave(args: any): void {
if(this.view){
this.view.viewdataschange.emit({action:'save',items:args});
}
}
/**
* 表单删除完成
*
* @param {*} args
* @memberof EditViewEngine
*/
public onFormRemove(args: any): void {
this.view.viewrefreshTag =true;
this.view.viewdataschange.emit({action:'remove',items:args});
}
/**
* 处理实体界面行为
*
* @param {string} tag
* @param {string} [actionmode]
* @returns {void}
* @memberof EditViewEngine
*/
public doSysUIAction(tag: string, actionmode?: string): void {
// if (Object.is(tag, 'Help')) {
// this.doHelp();
// return;
// }
// if (Object.is(tag, 'SaveAndStart')) {
// this.doSaveAndStart();
// return;
// }
// if (Object.is(tag, 'SaveAndExit')) {
// this.doSaveAndExit();
// return;
// }
// if (Object.is(tag, 'SaveAndNew')) {
// this.doSaveAndNew();
// return;
// }
if (Object.is(tag, 'Save')) {
this.doSave();
return;
}
// if (Object.is(tag, 'Print')) {
// this.doPrint();
// return;
// }
// if (Object.is(tag, 'Copy')) {
// this.doCopy();
// return;
// }
// if (Object.is(tag, 'RemoveAndExit')) {
// this.doRemoveAndExit();
// return;
// }
// if (Object.is(tag, 'Refresh')) {
// this.doRefresh();
// return;
// }
// if (Object.is(tag, 'New')) {
// this.doNew();
// return;
// }
// if (Object.is(tag, 'FirstRecord')) {
// this.doMoveToRecord('first');
// return;
// }
// if (Object.is(tag, 'PrevRecord')) {
// this.doMoveToRecord('prev');
// return;
// }
// if (Object.is(tag, 'NextRecord')) {
// this.doMoveToRecord('next');
// return;
// }
// if (Object.is(tag, 'LastRecord')) {
// this.doMoveToRecord('last');
// return;
// }
// if (Object.is(tag, 'Exit') || Object.is(tag, 'Close')) {
// this.doExit();
// return;
// }
super.doSysUIAction(tag, actionmode);
}
/**
* 编辑界面_保存操作
*
* @memberof IBizEditViewController
*/
public doSave(): void {
// this.afterformsaveaction = '';
if(this.viewdata){
this.saveData(this.viewdata);
}else{
this.saveData({});
}
}
/**
* 保存视图数据
*
* @param {*} [arg={}]
* @memberof EditViewEngine
*/
public saveData(arg: any = {}): void {
if (this.getForm()) {
const tag = this.getForm().name;
this.setViewState2({ tag: tag, action: 'save', viewdata: arg });
}
}
/**
* 获取表单对象
*
* @returns {*}
* @memberof EditViewEngine
*/
public getForm(): any {
return this.form;
}
}
\ No newline at end of file
import ViewEngine from './view-engine';
/**
* 多数据引擎
*
* @export
* @class MDViewEngine
* @extends {ViewEngine}
*/
export default class MobChartViewEngine extends ViewEngine {
/**
* 表格部件
*
* @type {*}
* @memberof GridViewEngine
*/
protected chart: any;
/**
* 表单部件
*
* @type {*}
* @memberof GridViewEngine
*/
protected searchForm: any;
/**
* 属性面板
*
* @protected
* @type {*}
* @memberof PickupGridViewEngine
*/
protected propertypanel: any;
/**
* 打开数据
*
* @type {*}
* @memberof GridViewEngine
*/
protected openData?: (params: any) => void;
/**
* 新建数据
*
* @protected
* @memberof GridViewEngine
*/
protected newData?: (params: any) => void;
/**
* Creates an instance of GridViewEngine.
* @memberof GridViewEngine
*/
constructor() {
super();
}
/**
* 引擎初始化
*
* @param {*} [options={}]
* @memberof GridViewEngine
*/
public init(options: any = {}): void {
this.propertypanel = options.propertypanel;
this.searchForm = options.searchform;
this.chart = options.chart;
this.openData = options.opendata;
this.newData = options.newdata;
super.init(options);
}
/**
* 引擎加载
*
* @param {*} [opts={}]
* @memberof MDViewEngine
*/
public load(opts: any = {}): void {
super.load(opts);
const _srfparentdata = this.viewdata.srfparentdata ? { srfparentdata: this.viewdata.srfparentdata } : { srfparentdata: {} };
if (this.getSearchForm()) {
const tag = this.getSearchForm().name;
this.setViewState2({ tag: tag, action: 'loaddraft', viewdata: {} });
}
if (this.getChart()) {
const tag = this.getChart().name;
this.setViewState2({ tag: tag, action: 'load', viewdata: _srfparentdata });
}
}
/**
* 部件事件
*
* @param {string} ctrlName
* @param {string} eventName
* @param {*} args
* @memberof GridViewEngine
*/
public onCtrlEvent(ctrlName: string, eventName: string, args: any): void {
super.onCtrlEvent(ctrlName, eventName, args);
if (Object.is(ctrlName, 'searchform')) {
this.searchFormEvent(eventName, args);
}
if (Object.is(ctrlName, 'chart')) {
this.MDChartEvent(eventName,args);
}
}
/**
* 搜索表单事件
*
* @param {string} eventName
* @param {*} [args={}]
* @memberof MDViewEngine
*/
public searchFormEvent(eventName: string, args: any = {}): void {
if (Object.is(eventName, 'load')) {
this.onSearchFormLoad(args);
}
if (Object.is(eventName, 'search')) {
this.onSearchFormSearch(args);
}
}
/**
*
*
* @param {string} eventName
* @param {*} [args={}]
* @memberof GridViewEngine
*/
/**
* 事件处理
*
* @param {string} eventName
* @param {any[]} args
* @memberof MDViewEngine
*/
public MDChartEvent(eventName: string, args: any): void {
if (Object.is(eventName, 'rowclick')) {
this.doEdit(args);
}
if (Object.is(eventName, 'click')) {
this.doEdit(args);
}
if (Object.is(eventName, 'rowdblclick')) {
this.doEdit(args);
}
if (Object.is(eventName, 'selectionchange')) {
this.selectionChange(args);
}
if (Object.is(eventName, 'load')) {
this.MDCtrlLoad(args);
}
if (Object.is(eventName, 'beforeload')) {
this.MDCtrlBeforeLoad(args)
}
}
/**
* 搜索表单加载完成
*
* @param {*} [args={}]
* @memberof MDViewEngine
*/
public onSearchFormLoad(args: any = {}): void {
if (this.getChart()) {
const tag = this.getChart().name;
this.setViewState2({ tag: tag, action: 'load', viewdata: {} });
}
}
public onSearchFormSearch(args: any = {}): void {
if (this.getChart()) {
const tag = this.getChart().name;
this.setViewState2({ tag: tag, action: 'search', viewdata: args });
}
}
/**
* 处理实体界面行为
*
* @param {string} tag
* @param {string} [actionmode]
* @returns {void}
* @memberof GridViewEngine
*/
public doSysUIAction(tag: string, actionmode?: string): void {
// if (Object.is(tag, 'Help')) {
// this.doHelp(params);
// return;
// }
if (Object.is(tag, 'Edit')) {
this.doEdit();
return;
}
// if (Object.is(tag, 'View')) {
// this.doView(params);
// return;
// }
// if (Object.is(tag, 'Print')) {
// this.doPrint(params);
// return;
// }
// if (Object.is(tag, 'ExportExcel')) {
// this.doExportExcel(params);
// return;
// }
// if (Object.is(tag, 'ExportModel')) {
// this.doExportModel(params);
// return;
// }
// if (Object.is(tag, 'Copy')) {
// this.doCopy(params);
// return;
// }
if (Object.is(tag, 'Remove')) {
this.doRemove();
return;
}
// if (Object.is(tag, 'Import')) {
// this.doImport(params);
// return;
// }
// if (Object.is(tag, 'Refresh')) {
// this.doRefresh(params);
// return;
// }
// if (Object.is(tag, 'NewRow')) {
// this.doCheck(params);
// return;
// }
if (Object.is(tag, 'SaveRow')) {
this.doSaveEditRow();
return;
}
if (Object.is(tag, 'New')) {
this.doNew();
return;
}
if (Object.is(tag, 'OpenRowEdit')) {
this.doOpenRowEdit();
return;
}
if (Object.is(tag, 'CloseRowEdit')) {
this.doCloseRowEdit();
return;
}
// if (Object.is(tag, 'ToggleRowEdit')) {
// this.doToggleRowEdit(params);
// return;
// }
// if (Object.is(tag, 'ToggleFilter')) {
// this.doToggleFilter(params);
// return;
// }
super.doSysUIAction(tag, actionmode);
}
/**
* 多数据项界面_开启行编辑操作
*
* @memberof GridViewEngine
*/
public doOpenRowEdit(): void {
if (this.getChart()) {
const tag = this.getChart().name;
this.setViewState2({ tag: tag, action: 'openEdit', viewdata: {} });
}
}
/**
* 多数据项界面_关闭行编辑操作
*
* @memberof GridViewEngine
*/
public doCloseRowEdit(): void {
if (this.getChart()) {
const tag = this.getChart().name;
this.setViewState2({ tag: tag, action: 'closeEdit', viewdata: {} });
}
}
/**
* 多数据项界面_提交编辑数据操作
*
* @memberof GridViewEngine
*/
public doSaveEditRow(): void {
if (this.getChart()) {
const tag = this.getChart().name;
this.setViewState2({ tag: tag, action: 'submitEidt', viewdata: {} });
}
}
/**
* 多数据项界面_编辑操作
*
* @param {*} [params={}]
* @returns {void}
* @memberof GridViewEngine
*/
public doEdit(params: any = {}): void {
// 获取要编辑的数据集合
if (params && params.srfkey) {
if (this.isFunc(this.getChart().findItem)) {
params = this.getChart().findItem('srfkey', params.srfkey);
}
const arg = { data: params };
this.onEditData(arg);
return;
}
if (this.isFunc(this.getChart().getSelection)) {
const selectedData = this.getChart().getSelection();
if (selectedData == null || selectedData.length === 0) {
return;
}
this.onEditData({ data: selectedData[0] });
}
}
/**
* 编辑数据
*
* @param {*} arg
* @memberof GridViewEngine
*/
public onEditData(arg: any): void {
const loadParam: any = {};
// if (this.getViewParam()) {
// Object.assign(loadParam, this.getViewParam());
// }
// if (this.getParentMode()) {
// Object.assign(loadParam, this.getParentMode());
// }
// if (this.getParentData()) {
// Object.assign(loadParam, this.getParentData());
// }
if (arg.srfcopymode) {
Object.assign(loadParam, {
srfsourcekey: arg.data.srfkey
});
} else {
Object.assign(loadParam, { srfkey: arg.data.srfkey, srfdeid: arg.data.srfdeid });
}
if (this.openData && this.isFunc(this.openData)) {
this.openData(loadParam);
}
}
/**
* 多数据项界面_新建操作
*
* @param {*} [params={}]
* @memberof GridViewEngine
*/
public doNew(params: any = {}): void {
this.onNewData();
}
/**
* 新建数据
*
* @returns {void}
* @memberof GridViewEngine
*/
public onNewData(): void {
// tslint:disable-next-line:prefer-const
let loadParam: any = {};
// if (this.getViewParam()) {
// Object.assign(loadParam, this.getViewParam());
// }
// if (this.getParentMode()) {
// Object.assign(loadParam, this.getParentMode());
// }
// if (this.getParentData()) {
// Object.assign(loadParam, this.getParentData());
// }
// if (this.isEnableRowEdit() && (this.getChart() && this.getChart().getOpenEdit())) {
// this.doNewRow(loadParam);
// return;
// }
// if (this.isEnableBatchAdd()) {
// this.doNewDataBatch(loadParam);
// return;
// }
// if (this.doNewDataWizard(loadParam)) {
// return;
// }
this.doNewDataNormal(loadParam);
}
/**
* 常规新建数据
*
* @param {*} arg
* @returns {*}
* @memberof GridViewEngine
*/
public doNewDataNormal(arg: any): any {
// let view = this.getNewDataView(arg);
// if (view == null) {
// return false;
// }
// const openMode = view.openMode;
// if (!openMode || Object.is(openMode, '')) {
// view.openMode = 'INDEXVIEWTAB';
// }
// if (!view.state) {
// view.state = 'new';
// let viewParam: any = {};
// Object.assign(viewParam, view.viewParam);
// if (viewParam && viewParam.srfnewmode && !Object.is(viewParam.srfnewmode, '')) {
// const srfnewmode: string = viewParam.srfnewmode.split('@').join('__');
// view.state = view.state + '_' + srfnewmode.toLowerCase();
// }
// }
return this.openDataView(arg);
}
/**
* 多数据项界面_删除操作
*
* @memberof MDViewEngine
*/
public doRemove(): void {
}
public openDataView(view: any = {}): boolean {
const openMode = view.openMode;
// if (view.redirect) {
// this.redirectOpenView(view);
// return false;
// }
if (openMode !== undefined) {
if (Object.is(openMode, 'POPUPMODAL')) {
view.modal = true;
} else if (Object.is(openMode, 'POPUP')) {
view.modal = true;
} else if (Object.is(openMode, '') || Object.is(openMode, 'INDEXVIEWTAB')) {
view.modal = false;
}
}
// if (view.modal) {
// let modalview = this.openModal(view);
// modalview.subscribe((result: any) => {
// if (result && Object.is(result.ret, 'OK')) {
// this.onRefresh();
// }
// });
// return true;
// }
// else {
// this.openWindow(view.viewurl, view.viewparam);
// }
if (this.newData && this.isFunc(this.newData)) {
this.newData({});
}
return true;
}
/**
* 选中变化
*
* @param {any[]} args
* @memberof GridViewEngine
*/
public selectionChange(args: any[]): void {
if (this.view) {
this.view.viewdataschange.emit(args);
}
if (this.getPropertyPanel()) {
const tag = this.getPropertyPanel().name;
this.setViewState2({ tag: tag, action: 'load', viewdata: args[0] });
}
}
/**
* 多数据部件加载完成
*
* @param {any[]} args
* @memberof MDViewEngine
*/
public MDCtrlLoad(args: any[]) {
if (this.view) {
this.view.viewload.emit(args);
}
}
/**
* 多数据部件加载之前
*
* @param {*} [arg={}]
* @memberof MDViewEngine
*/
public MDCtrlBeforeLoad(arg: any = {}): void {
if (this.viewdata.srfparentdata && Object.keys(this.viewdata.srfparentdata).length > 0) {
Object.assign(arg, { srfparentdata: this.viewdata.srfparentdata });
}
if (this.getSearchForm()) {
Object.assign(arg, this.getSearchForm().getData());
}
if (this.view) {
Object.assign(arg, { query: this.view.query });
}
}
/**
* 获取多数据部件
*
* @returns {*}
* @memberof MDViewEngine
*/
public getChart(): any {
return this.chart;
}
public getSearchForm(): any {
return this.searchForm;
}
/**
* 获取属性面板
*
* @returns
* @memberof PickupGridViewEngine
*/
public getPropertyPanel() {
return this.propertypanel;
}
}
\ No newline at end of file
import ViewEngine from './view-engine';
/**
* 编辑视图引擎
*
* @export
* @class MobEditView9Engine
* @extends {ViewEngine}
*/
export default class MobEditView9Engine extends ViewEngine {
/**
* 表单部件
*
* @protected
* @type {*}
* @memberof MobEditView9Engine
*/
protected form: any;
/**
* 父健为当前健
*
* @protected
* @type {string}
* @memberof MobEditView9Engine
*/
protected p2k: string = '';
/**
* 初始化编辑视图引擎
*
* @param {*} [options={}]
* @memberof MobEditView9Engine
*/
public init(options: any = {}): void {
this.form = options.form;
this.p2k = options.p2k;
super.init(options);
}
/**
* 引擎加载
*
* @param {*} [opts={}]
* @memberof MobEditView9Engine
*/
public load(opts: any = {}): void {
super.load(opts);
if (this.getForm()) {
const tag = this.getForm().name;
if (Object.is(this.p2k, '1') && this.viewdata.srfparentdata && !Object.is(this.viewdata.srfparentdata.srfparentkey, '')) {
Object.assign(this.viewdata, { srfkey: this.viewdata.srfparentdata.srfparentkey });
}
const action: string = this.viewdata.srfkey && !Object.is(this.viewdata.srfkey, '') ? 'load' : 'loaddraft';
this.setViewState2({ tag: tag, action: action, viewdata: this.viewdata });
}
}
/**
* 部件事件机制
*
* @param {string} ctrlName
* @param {string} eventName
* @param {*} args
* @memberof MobEditView9Engine
*/
public onCtrlEvent(ctrlName: string, eventName: string, args: any): void {
super.onCtrlEvent(ctrlName, eventName, args);
if (Object.is(ctrlName, 'form')) {
this.formEvent(eventName, args);
}
}
/**
* 表单事件
*
* @param {string} eventName
* @param {*} args
* @memberof MobEditView9Engine
*/
public formEvent(eventName: string, args: any): void {
if (Object.is(eventName, 'load')) {
this.onFormLoad(args);
}
if (Object.is(eventName, 'save')) {
this.onFormSave(args);
}
if (Object.is(eventName, 'remove')) {
this.onFormRemove(args);
}
}
/**
* 表单加载完成
*
* @param {*} args
* @memberof MobEditView9Engine
*/
public onFormLoad(args: any): void {
if (Object.is(args.srfuf, '1')) {
this.view.datainfo = args.srfmajortext;
this.view.viewdataschange.emit({action:'load',items:args});
}
}
/**
* 表单保存完成
*
* @param {*} args
* @memberof MobEditView9Engine
*/
public onFormSave(args: any): void {
if(this.view){
this.view.viewdataschange.emit({action:'save',items:args});
}
}
/**
* 表单删除完成
*
* @param {*} args
* @memberof MobEditView9Engine
*/
public onFormRemove(args: any): void {
this.view.viewrefreshTag =true;
this.view.viewdataschange.emit({action:'remove',items:args});
}
/**
* 处理实体界面行为
*
* @param {string} tag
* @param {string} [actionmode]
* @returns {void}
* @memberof MobEditView9Engine
*/
public doSysUIAction(tag: string, actionmode?: string): void {
// if (Object.is(tag, 'Help')) {
// this.doHelp();
// return;
// }
// if (Object.is(tag, 'SaveAndStart')) {
// this.doSaveAndStart();
// return;
// }
// if (Object.is(tag, 'SaveAndExit')) {
// this.doSaveAndExit();
// return;
// }
// if (Object.is(tag, 'SaveAndNew')) {
// this.doSaveAndNew();
// return;
// }
if (Object.is(tag, 'Save')) {
this.doSave();
return;
}
// if (Object.is(tag, 'Print')) {
// this.doPrint();
// return;
// }
// if (Object.is(tag, 'Copy')) {
// this.doCopy();
// return;
// }
// if (Object.is(tag, 'RemoveAndExit')) {
// this.doRemoveAndExit();
// return;
// }
// if (Object.is(tag, 'Refresh')) {
// this.doRefresh();
// return;
// }
// if (Object.is(tag, 'New')) {
// this.doNew();
// return;
// }
// if (Object.is(tag, 'FirstRecord')) {
// this.doMoveToRecord('first');
// return;
// }
// if (Object.is(tag, 'PrevRecord')) {
// this.doMoveToRecord('prev');
// return;
// }
// if (Object.is(tag, 'NextRecord')) {
// this.doMoveToRecord('next');
// return;
// }
// if (Object.is(tag, 'LastRecord')) {
// this.doMoveToRecord('last');
// return;
// }
// if (Object.is(tag, 'Exit') || Object.is(tag, 'Close')) {
// this.doExit();
// return;
// }
super.doSysUIAction(tag, actionmode);
}
/**
* 编辑界面_保存操作
*
* @memberof IBizEditViewController
*/
public doSave(): void {
// this.afterformsaveaction = '';
if(this.viewdata){
this.saveData(this.viewdata);
}else{
this.saveData({});
}
}
/**
* 保存视图数据
*
* @param {*} [arg={}]
* @memberof MobEditView9Engine
*/
public saveData(arg: any = {}): void {
if (this.getForm()) {
const tag = this.getForm().name;
this.setViewState2({ tag: tag, action: 'save', viewdata: arg });
}
}
/**
* 获取表单对象
*
* @returns {*}
* @memberof MobEditView9Engine
*/
public getForm(): any {
return this.form;
}
}
\ No newline at end of file
import ViewEngine from './view-engine';
/**
* 多数据引擎
*
* @export
* @class MDViewEngine
* @extends {ViewEngine}
*/
export default class MobMDViewEngine extends ViewEngine {
/**
* 表格部件
*
* @type {*}
* @memberof GridViewEngine
*/
protected mdctrl: any;
/**
* 表单部件
*
* @type {*}
* @memberof GridViewEngine
*/
protected searchForm: any;
/**
* 属性面板
*
* @protected
* @type {*}
* @memberof PickupGridViewEngine
*/
protected propertypanel: any;
/**
* 打开数据
*
* @type {*}
* @memberof GridViewEngine
*/
protected openData?: (params: any) => void;
/**
* 新建数据
*
* @protected
* @memberof GridViewEngine
*/
protected newData?: (params: any) => void;
/**
* Creates an instance of GridViewEngine.
* @memberof GridViewEngine
*/
constructor() {
super();
}
/**
* 引擎初始化
*
* @param {*} [options={}]
* @memberof GridViewEngine
*/
public init(options: any = {}): void {
this.propertypanel = options.propertypanel;
this.searchForm = options.searchform;
this.mdctrl = options.mdctrl;
this.openData = options.opendata;
this.newData = options.newdata;
super.init(options);
}
/**
* 引擎加载
*
* @param {*} [opts={}]
* @memberof MDViewEngine
*/
public load(opts: any = {}): void {
super.load(opts);
const _srfparentdata = this.viewdata.srfparentdata ? { srfparentdata: this.viewdata.srfparentdata } : { srfparentdata: {} };
if (this.getSearchForm()) {
const tag = this.getSearchForm().name;
this.setViewState2({ tag: tag, action: 'loaddraft', viewdata: {} });
}
if (this.getMDCtrl()) {
const tag = this.getMDCtrl().name;
this.setViewState2({ tag: tag, action: 'load', viewdata: _srfparentdata });
}
}
/**
* 部件事件
*
* @param {string} ctrlName
* @param {string} eventName
* @param {*} args
* @memberof GridViewEngine
*/
public onCtrlEvent(ctrlName: string, eventName: string, args: any): void {
super.onCtrlEvent(ctrlName, eventName, args);
if (Object.is(ctrlName, 'searchform')) {
this.searchFormEvent(eventName, args);
}
if (Object.is(ctrlName, 'mdctrl')) {
this.MDCtrlEvent(eventName,args);
}
}
/**
* 搜索表单事件
*
* @param {string} eventName
* @param {*} [args={}]
* @memberof MDViewEngine
*/
public searchFormEvent(eventName: string, args: any = {}): void {
if (Object.is(eventName, 'load')) {
this.onSearchFormLoad(args);
}
if (Object.is(eventName, 'search')) {
this.onSearchFormSearch(args);
}
}
/**
*
*
* @param {string} eventName
* @param {*} [args={}]
* @memberof GridViewEngine
*/
/**
* 事件处理
*
* @param {string} eventName
* @param {any[]} args
* @memberof MDViewEngine
*/
public MDCtrlEvent(eventName: string, args: any): void {
if (Object.is(eventName, 'rowclick')) {
this.doEdit(args);
}
if (Object.is(eventName, 'click')) {
this.doEdit(args);
}
if (Object.is(eventName, 'rowdblclick')) {
this.doEdit(args);
}
if (Object.is(eventName, 'selectionchange')) {
this.selectionChange(args);
}
if (Object.is(eventName, 'load')) {
this.MDCtrlLoad(args);
}
if (Object.is(eventName, 'beforeload')) {
this.MDCtrlBeforeLoad(args)
}
}
/**
* 搜索表单加载完成
*
* @param {*} [args={}]
* @memberof MDViewEngine
*/
public onSearchFormLoad(args: any = {}): void {
if (this.getMDCtrl()) {
const tag = this.getMDCtrl().name;
this.setViewState2({ tag: tag, action: 'load', viewdata: {} });
}
}
public onSearchFormSearch(args: any = {}): void {
if (this.getMDCtrl()) {
const tag = this.getMDCtrl().name;
this.setViewState2({ tag: tag, action: 'search', viewdata: args });
}
}
/**
* 处理实体界面行为
*
* @param {string} tag
* @param {string} [actionmode]
* @returns {void}
* @memberof GridViewEngine
*/
public doSysUIAction(tag: string, actionmode?: string): void {
// if (Object.is(tag, 'Help')) {
// this.doHelp(params);
// return;
// }
if (Object.is(tag, 'Edit')) {
this.doEdit();
return;
}
// if (Object.is(tag, 'View')) {
// this.doView(params);
// return;
// }
// if (Object.is(tag, 'Print')) {
// this.doPrint(params);
// return;
// }
// if (Object.is(tag, 'ExportExcel')) {
// this.doExportExcel(params);
// return;
// }
// if (Object.is(tag, 'ExportModel')) {
// this.doExportModel(params);
// return;
// }
// if (Object.is(tag, 'Copy')) {
// this.doCopy(params);
// return;
// }
if (Object.is(tag, 'Remove')) {
this.doRemove();
return;
}
// if (Object.is(tag, 'Import')) {
// this.doImport(params);
// return;
// }
// if (Object.is(tag, 'Refresh')) {
// this.doRefresh(params);
// return;
// }
// if (Object.is(tag, 'NewRow')) {
// this.doCheck(params);
// return;
// }
if (Object.is(tag, 'SaveRow')) {
this.doSaveEditRow();
return;
}
if (Object.is(tag, 'New')) {
this.doNew();
return;
}
if (Object.is(tag, 'OpenRowEdit')) {
this.doOpenRowEdit();
return;
}
if (Object.is(tag, 'CloseRowEdit')) {
this.doCloseRowEdit();
return;
}
// if (Object.is(tag, 'ToggleRowEdit')) {
// this.doToggleRowEdit(params);
// return;
// }
// if (Object.is(tag, 'ToggleFilter')) {
// this.doToggleFilter(params);
// return;
// }
super.doSysUIAction(tag, actionmode);
}
/**
* 多数据项界面_开启行编辑操作
*
* @memberof GridViewEngine
*/
public doOpenRowEdit(): void {
if (this.getMDCtrl()) {
const tag = this.getMDCtrl().name;
this.setViewState2({ tag: tag, action: 'openEdit', viewdata: {} });
}
}
/**
* 多数据项界面_关闭行编辑操作
*
* @memberof GridViewEngine
*/
public doCloseRowEdit(): void {
if (this.getMDCtrl()) {
const tag = this.getMDCtrl().name;
this.setViewState2({ tag: tag, action: 'closeEdit', viewdata: {} });
}
}
/**
* 多数据项界面_提交编辑数据操作
*
* @memberof GridViewEngine
*/
public doSaveEditRow(): void {
if (this.getMDCtrl()) {
const tag = this.getMDCtrl().name;
this.setViewState2({ tag: tag, action: 'submitEidt', viewdata: {} });
}
}
/**
* 多数据项界面_编辑操作
*
* @param {*} [params={}]
* @returns {void}
* @memberof GridViewEngine
*/
public doEdit(params: any = {}): void {
// 获取要编辑的数据集合
if (params && params.srfkey) {
if (this.isFunc(this.getMDCtrl().findItem)) {
params = this.getMDCtrl().findItem('srfkey', params.srfkey);
}
const arg = { data: params };
this.onEditData(arg);
return;
}
if (this.isFunc(this.getMDCtrl().getSelection)) {
const selectedData = this.getMDCtrl().getSelection();
if (selectedData == null || selectedData.length === 0) {
return;
}
this.onEditData({ data: selectedData[0] });
}
}
/**
* 编辑数据
*
* @param {*} arg
* @memberof GridViewEngine
*/
public onEditData(arg: any): void {
const loadParam: any = {};
// if (this.getViewParam()) {
// Object.assign(loadParam, this.getViewParam());
// }
// if (this.getParentMode()) {
// Object.assign(loadParam, this.getParentMode());
// }
// if (this.getParentData()) {
// Object.assign(loadParam, this.getParentData());
// }
if (arg.srfcopymode) {
Object.assign(loadParam, {
srfsourcekey: arg.data.srfkey
});
} else {
Object.assign(loadParam, { srfkey: arg.data.srfkey, srfdeid: arg.data.srfdeid });
}
if (this.openData && this.isFunc(this.openData)) {
this.openData(loadParam);
}
}
/**
* 多数据项界面_新建操作
*
* @param {*} [params={}]
* @memberof GridViewEngine
*/
public doNew(params: any = {}): void {
this.onNewData();
}
/**
* 新建数据
*
* @returns {void}
* @memberof GridViewEngine
*/
public onNewData(): void {
// tslint:disable-next-line:prefer-const
let loadParam: any = {};
// if (this.getViewParam()) {
// Object.assign(loadParam, this.getViewParam());
// }
// if (this.getParentMode()) {
// Object.assign(loadParam, this.getParentMode());
// }
// if (this.getParentData()) {
// Object.assign(loadParam, this.getParentData());
// }
// if (this.isEnableRowEdit() && (this.getMDCtrl() && this.getMDCtrl().getOpenEdit())) {
// this.doNewRow(loadParam);
// return;
// }
// if (this.isEnableBatchAdd()) {
// this.doNewDataBatch(loadParam);
// return;
// }
// if (this.doNewDataWizard(loadParam)) {
// return;
// }
this.doNewDataNormal(loadParam);
}
/**
* 常规新建数据
*
* @param {*} arg
* @returns {*}
* @memberof GridViewEngine
*/
public doNewDataNormal(arg: any): any {
// let view = this.getNewDataView(arg);
// if (view == null) {
// return false;
// }
// const openMode = view.openMode;
// if (!openMode || Object.is(openMode, '')) {
// view.openMode = 'INDEXVIEWTAB';
// }
// if (!view.state) {
// view.state = 'new';
// let viewParam: any = {};
// Object.assign(viewParam, view.viewParam);
// if (viewParam && viewParam.srfnewmode && !Object.is(viewParam.srfnewmode, '')) {
// const srfnewmode: string = viewParam.srfnewmode.split('@').join('__');
// view.state = view.state + '_' + srfnewmode.toLowerCase();
// }
// }
return this.openDataView(arg);
}
/**
* 多数据项界面_删除操作
*
* @memberof MDViewEngine
*/
public doRemove(): void {
}
public openDataView(view: any = {}): boolean {
const openMode = view.openMode;
// if (view.redirect) {
// this.redirectOpenView(view);
// return false;
// }
if (openMode !== undefined) {
if (Object.is(openMode, 'POPUPMODAL')) {
view.modal = true;
} else if (Object.is(openMode, 'POPUP')) {
view.modal = true;
} else if (Object.is(openMode, '') || Object.is(openMode, 'INDEXVIEWTAB')) {
view.modal = false;
}
}
// if (view.modal) {
// let modalview = this.openModal(view);
// modalview.subscribe((result: any) => {
// if (result && Object.is(result.ret, 'OK')) {
// this.onRefresh();
// }
// });
// return true;
// }
// else {
// this.openWindow(view.viewurl, view.viewparam);
// }
if (this.newData && this.isFunc(this.newData)) {
this.newData({});
}
return true;
}
/**
* 选中变化
*
* @param {any[]} args
* @memberof GridViewEngine
*/
public selectionChange(args: any[]): void {
if (this.view) {
this.view.viewdataschange.emit(args);
}
if (this.getPropertyPanel()) {
const tag = this.getPropertyPanel().name;
this.setViewState2({ tag: tag, action: 'load', viewdata: args[0] });
}
}
/**
* 多数据部件加载完成
*
* @param {any[]} args
* @memberof MDViewEngine
*/
public MDCtrlLoad(args: any[]) {
if (this.view) {
this.view.viewload.emit(args);
}
}
/**
* 多数据部件加载之前
*
* @param {*} [arg={}]
* @memberof MDViewEngine
*/
public MDCtrlBeforeLoad(arg: any = {}): void {
if (this.viewdata.srfparentdata && Object.keys(this.viewdata.srfparentdata).length > 0) {
Object.assign(arg, { srfparentdata: this.viewdata.srfparentdata });
}
if (this.getSearchForm()) {
Object.assign(arg, this.getSearchForm().getData());
}
if (this.view) {
Object.assign(arg, { query: this.view.query });
}
}
/**
* 获取多数据部件
*
* @returns {*}
* @memberof MDViewEngine
*/
public getMDCtrl(): any {
return this.mdctrl;
}
public getSearchForm(): any {
return this.searchForm;
}
/**
* 获取属性面板
*
* @returns
* @memberof PickupGridViewEngine
*/
public getPropertyPanel() {
return this.propertypanel;
}
}
\ No newline at end of file
import ViewEngine from './view-engine';
/**
* 多数据引擎
*
* @export
* @class MDViewEngine
* @extends {ViewEngine}
*/
export default class MobMDView9Engine extends ViewEngine {
/**
* 表格部件
*
* @type {*}
* @memberof GridViewEngine
*/
protected mdctrl: any;
/**
* 属性面板
*
* @protected
* @type {*}
* @memberof PickupGridViewEngine
*/
protected propertypanel: any;
/**
* 打开数据
*
* @type {*}
* @memberof GridViewEngine
*/
protected openData?: (params: any) => void;
/**
* 新建数据
*
* @protected
* @memberof GridViewEngine
*/
protected newData?: (params: any) => void;
/**
* Creates an instance of GridViewEngine.
* @memberof GridViewEngine
*/
constructor() {
super();
}
/**
* 引擎初始化
*
* @param {*} [options={}]
* @memberof GridViewEngine
*/
public init(options: any = {}): void {
this.propertypanel = options.propertypanel;
this.mdctrl = options.mdctrl;
this.openData = options.opendata;
this.newData = options.newdata;
super.init(options);
}
/**
* 引擎加载
*
* @param {*} [opts={}]
* @memberof MDViewEngine
*/
public load(opts: any = {}): void {
super.load(opts);
const _srfparentdata = this.viewdata.srfparentdata ? { srfparentdata: this.viewdata.srfparentdata } : { srfparentdata: {} };
if (this.getMDCtrl()) {
const tag = this.getMDCtrl().name;
this.setViewState2({ tag: tag, action: 'load', viewdata: _srfparentdata });
}
}
/**
* 部件事件
*
* @param {string} ctrlName
* @param {string} eventName
* @param {*} args
* @memberof GridViewEngine
*/
public onCtrlEvent(ctrlName: string, eventName: string, args: any): void {
super.onCtrlEvent(ctrlName, eventName, args);
if (Object.is(ctrlName, 'mdctrl')) {
this.MDCtrlEvent(eventName,args);
}
}
/**
*
*
* @param {string} eventName
* @param {*} [args={}]
* @memberof GridViewEngine
*/
/**
* 事件处理
*
* @param {string} eventName
* @param {any[]} args
* @memberof MDViewEngine
*/
public MDCtrlEvent(eventName: string, args: any): void {
if (Object.is(eventName, 'rowclick')) {
this.doEdit(args);
}
if (Object.is(eventName, 'click')) {
this.doEdit(args);
}
if (Object.is(eventName, 'rowdblclick')) {
this.doEdit(args);
}
if (Object.is(eventName, 'selectionchange')) {
this.selectionChange(args);
}
if (Object.is(eventName, 'load')) {
this.MDCtrlLoad(args);
}
if (Object.is(eventName, 'beforeload')) {
this.MDCtrlBeforeLoad(args)
}
}
/**
* 处理实体界面行为
*
* @param {string} tag
* @param {string} [actionmode]
* @returns {void}
* @memberof GridViewEngine
*/
public doSysUIAction(tag: string, actionmode?: string): void {
if (Object.is(tag, 'Edit')) {
this.doEdit();
return;
}
if (Object.is(tag, 'Remove')) {
this.doRemove();
return;
}
if (Object.is(tag, 'SaveRow')) {
this.doSaveEditRow();
return;
}
if (Object.is(tag, 'New')) {
this.doNew();
return;
}
if (Object.is(tag, 'OpenRowEdit')) {
this.doOpenRowEdit();
return;
}
if (Object.is(tag, 'CloseRowEdit')) {
this.doCloseRowEdit();
return;
}
super.doSysUIAction(tag, actionmode);
}
/**
* 多数据项界面_开启行编辑操作
*
* @memberof GridViewEngine
*/
public doOpenRowEdit(): void {
if (this.getMDCtrl()) {
const tag = this.getMDCtrl().name;
this.setViewState2({ tag: tag, action: 'openEdit', viewdata: {} });
}
}
/**
* 多数据项界面_关闭行编辑操作
*
* @memberof GridViewEngine
*/
public doCloseRowEdit(): void {
if (this.getMDCtrl()) {
const tag = this.getMDCtrl().name;
this.setViewState2({ tag: tag, action: 'closeEdit', viewdata: {} });
}
}
/**
* 多数据项界面_提交编辑数据操作
*
* @memberof GridViewEngine
*/
public doSaveEditRow(): void {
if (this.getMDCtrl()) {
const tag = this.getMDCtrl().name;
this.setViewState2({ tag: tag, action: 'submitEidt', viewdata: {} });
}
}
/**
* 多数据项界面_编辑操作
*
* @param {*} [params={}]
* @returns {void}
* @memberof GridViewEngine
*/
public doEdit(params: any = {}): void {
// 获取要编辑的数据集合
if (params && params.srfkey) {
if (this.isFunc(this.getMDCtrl().findItem)) {
params = this.getMDCtrl().findItem('srfkey', params.srfkey);
}
const arg = { data: params };
this.onEditData(arg);
return;
}
if (this.isFunc(this.getMDCtrl().getSelection)) {
const selectedData = this.getMDCtrl().getSelection();
if (selectedData == null || selectedData.length === 0) {
return;
}
this.onEditData({ data: selectedData[0] });
}
}
/**
* 编辑数据
*
* @param {*} arg
* @memberof GridViewEngine
*/
public onEditData(arg: any): void {
const loadParam: any = {};
if (arg.srfcopymode) {
Object.assign(loadParam, {
srfsourcekey: arg.data.srfkey
});
} else {
Object.assign(loadParam, { srfkey: arg.data.srfkey, srfdeid: arg.data.srfdeid });
}
if (this.openData && this.isFunc(this.openData)) {
this.openData(loadParam);
}
}
/**
* 多数据项界面_新建操作
*
* @param {*} [params={}]
* @memberof GridViewEngine
*/
public doNew(params: any = {}): void {
this.onNewData();
}
/**
* 新建数据
*
* @returns {void}
* @memberof GridViewEngine
*/
public onNewData(): void {
let loadParam: any = {};
this.doNewDataNormal(loadParam);
}
/**
* 常规新建数据
*
* @param {*} arg
* @returns {*}
* @memberof GridViewEngine
*/
public doNewDataNormal(arg: any): any {
return this.openDataView(arg);
}
/**
* 多数据项界面_删除操作
*
* @memberof MDViewEngine
*/
public doRemove(): void {
}
public openDataView(view: any = {}): boolean {
const openMode = view.openMode;
if (openMode !== undefined) {
if (Object.is(openMode, 'POPUPMODAL')) {
view.modal = true;
} else if (Object.is(openMode, 'POPUP')) {
view.modal = true;
} else if (Object.is(openMode, '') || Object.is(openMode, 'INDEXVIEWTAB')) {
view.modal = false;
}
}
if (this.newData && this.isFunc(this.newData)) {
this.newData({});
}
return true;
}
/**
* 选中变化
*
* @param {any[]} args
* @memberof GridViewEngine
*/
public selectionChange(args: any[]): void {
if (this.view) {
this.view.viewdataschange.emit(args);
}
if (this.getPropertyPanel()) {
const tag = this.getPropertyPanel().name;
this.setViewState2({ tag: tag, action: 'load', viewdata: args[0] });
}
}
/**
* 多数据部件加载完成
*
* @param {any[]} args
* @memberof MDViewEngine
*/
public MDCtrlLoad(args: any[]) {
if (this.view) {
this.view.viewload.emit(args);
}
}
/**
* 多数据部件加载之前
*
* @param {*} [arg={}]
* @memberof MDViewEngine
*/
public MDCtrlBeforeLoad(arg: any = {}): void {
if (this.viewdata.srfparentdata && Object.keys(this.viewdata.srfparentdata).length > 0) {
Object.assign(arg, { srfparentdata: this.viewdata.srfparentdata });
}
if (this.view) {
Object.assign(arg, { query: this.view.query });
}
}
/**
* 获取多数据部件
*
* @returns {*}
* @memberof MDViewEngine
*/
public getMDCtrl(): any {
return this.mdctrl;
}
/**
* 获取属性面板
*
* @returns
* @memberof PickupGridViewEngine
*/
public getPropertyPanel() {
return this.propertypanel;
}
}
\ No newline at end of file
import ViewEngine from './view-engine';
/**
* 多编辑表单视图引擎
*
* @export
* @class MobMEditView9Engine
* @extends {ViewEngine}
*/
export default class MobMEditView9Engine extends ViewEngine {
/**
* 多编辑表单面板
*
* @protected
* @type {*}
* @memberof MobMEditView9Engine
*/
protected meditviewpanel: any;
/**
* 打开数据
*
* @type {*}
* @memberof MobMEditView9Engine
*/
protected openData?: (params: any) => void;
/**
* 新建数据
*
* @protected
* @memberof MobMEditView9Engine
*/
protected newData?: (params: any) => void;
/**
* Creates an instance of MobMEditView9Engine.
* @memberof MobMEditView9Engine
*/
constructor() {
super();
}
/**
* 引擎初始化
*
* @param {*} [options={}]
* @memberof MobMEditView9Engine
*/
public init(options: any = {}): void {
this.meditviewpanel = options.meditviewpanel;
this.openData = options.opendata;
this.newData = options.newdata;
super.init(options);
}
/**
* 引擎加载
*
* @param {*} [opts={}]
* @memberof MobMEditView9Engine
*/
public load(opts: any = {}): void {
super.load(opts);
const _srfparentdata = this.viewdata.srfparentdata ? { srfparentdata: this.viewdata.srfparentdata } : { srfparentdata: {} };
if (this.getMeditviewpanel()) {
const tag = this.getMeditviewpanel().name;
this.setViewState2({ tag: tag, action: 'load', viewdata: _srfparentdata });
}
}
/**
* 部件事件
*
* @param {string} ctrlName
* @param {string} eventName
* @param {*} args
* @memberof MobMEditView9Engine
*/
public onCtrlEvent(ctrlName: string, eventName: string, args: any): void {
super.onCtrlEvent(ctrlName, eventName, args);
if (Object.is(ctrlName, 'meditviewpanel')) {
this.editviewpanelEvent(eventName, args);
}
}
/**
* 多编辑表单面板事件分发
*
* @param {*} [opts={}]
* @memberof MobMEditView9Engine
*/
public editviewpanelEvent(eventName:string, args:any){
if (Object.is(eventName, 'load')) {
this.view.viewdataschange.emit({action:'load','items':args});
}
if (Object.is(eventName, 'beforesave')) {
this.view.viewdataschange.emit({action:'beforesave','items':args});
this.view.drdatachange.emit({action:'beforesave','items':args});
}
if (Object.is(eventName, 'editformchange')) {
this.view.viewdataschange.emit({action:'editformchange','items':args});
this.view.drdatachange.emit({action:'editformchange','items':args});
}
if (Object.is(eventName, 'savecompleted')) {
this.view.viewdataschange.emit({action:'savecompleted','items':args});
this.view.drdatasaved.emit({action:'savecompleted','items':args});
}
}
/**
* 多编辑表单面板部件
*
* @returns {*}
* @memberof MDViewEngine
*/
public getMeditviewpanel(): any {
return this.meditviewpanel;
}
}
\ No newline at end of file
import ViewEngine from './view-engine';
/**
* 数据选择视图引擎
*
* @export
* @class MDViewEngine
* @extends {ViewEngine}
*/
export default class MobMPickupViewEngine extends ViewEngine {
/**
* pickupviewpanel面板
*
* @type {*}
* @memberof GridViewEngine
*/
protected pickupviewpanel: any;
/**
* 打开数据
*
* @type {*}
* @memberof GridViewEngine
*/
protected openData?: (params: any) => void;
/**
* 新建数据
*
* @protected
* @memberof GridViewEngine
*/
protected newData?: (params: any) => void;
/**
* Creates an instance of GridViewEngine.
* @memberof GridViewEngine
*/
constructor() {
super();
}
/**
* 引擎初始化
*
* @param {*} [options={}]
* @memberof GridViewEngine
*/
public init(options: any = {}): void {
this.pickupviewpanel = options.pickupviewpanel;
this.openData = options.opendata;
this.newData = options.newdata;
super.init(options);
}
/**
* 引擎加载
*
* @param {*} [opts={}]
* @memberof MDViewEngine
*/
public load(opts: any = {}): void {
super.load(opts);
const _srfparentdata = this.viewdata.srfparentdata ? { srfparentdata: this.viewdata.srfparentdata } : { srfparentdata: {} };
if (this.getPickupviewpanel()) {
const tag = this.getPickupviewpanel().name;
this.setViewState2({ tag: tag, action: 'load', viewdata: _srfparentdata });
}
}
/**
* 部件事件
*
* @param {string} ctrlName
* @param {string} eventName
* @param {*} args
* @memberof GridViewEngine
*/
public onCtrlEvent(ctrlName: string, eventName: string, args: any): void {
super.onCtrlEvent(ctrlName, eventName, args);
if (Object.is(ctrlName, 'pickupviewpanel')) {
this.pickupviewpanelEvent(eventName, args);
}
}
/**
* pickupviewpanel事件
*
* @param {string} eventName
* @param {*} [args={}]
* @memberof MDViewEngine
*/
public pickupviewpanelEvent(eventName: string, args: any = {}): void {
if (Object.is(eventName, 'load')) {
this.onPickupviewpanelLoad(args);
}
if (Object.is(eventName, 'dataschange')) {
this.onickupviewpanelDatasChange(args);
}
}
/**
* 搜索表单加载完成
*
* @param {*} [args={}]
* @memberof MDViewEngine
*/
public onPickupviewpanelLoad(args: any = {}): void {
if (this.view) {
this.view.viewload.emit(args);
}
}
public onickupviewpanelDatasChange(args: any = {}): void {
if (this.view) {
this.view.viewdataschange.emit(args);
this.view.viewDatasChange(args);
}
}
public doSysUIAction(tag: string, actionmode?: string): void {
super.doSysUIAction(tag, actionmode);
}
public getPickupviewpanel(): any {
return this.pickupviewpanel;
}
}
\ No newline at end of file
import ViewEngine from './view-engine';
/**
* 多数据引擎
*
* @export
* @class MDViewEngine
* @extends {ViewEngine}
*/
export default class MobPickupMDViewEngine extends ViewEngine {
/**
* 表格部件
*
* @type {*}
* @memberof GridViewEngine
*/
protected mdctrl: any;
/**
* 属性面板
*
* @protected
* @type {*}
* @memberof PickupGridViewEngine
*/
protected propertypanel: any;
/**
* 打开数据
*
* @type {*}
* @memberof GridViewEngine
*/
protected openData?: (params: any) => void;
/**
* 新建数据
*
* @protected
* @memberof GridViewEngine
*/
protected newData?: (params: any) => void;
/**
* Creates an instance of GridViewEngine.
* @memberof GridViewEngine
*/
constructor() {
super();
}
/**
* 引擎初始化
*
* @param {*} [options={}]
* @memberof GridViewEngine
*/
public init(options: any = {}): void {
this.propertypanel = options.propertypanel;
this.mdctrl = options.mdctrl;
this.openData = options.opendata;
this.newData = options.newdata;
super.init(options);
}
/**
* 引擎加载
*
* @param {*} [opts={}]
* @memberof MDViewEngine
*/
public load(opts: any = {}): void {
super.load(opts);
const _srfparentdata = this.viewdata.srfparentdata ? { srfparentdata: this.viewdata.srfparentdata } : { srfparentdata: {} };
if (this.getMDCtrl()) {
const tag = this.getMDCtrl().name;
this.setViewState2({ tag: tag, action: 'load', viewdata: _srfparentdata });
}
}
/**
* 部件事件
*
* @param {string} ctrlName
* @param {string} eventName
* @param {*} args
* @memberof GridViewEngine
*/
public onCtrlEvent(ctrlName: string, eventName: string, args: any): void {
super.onCtrlEvent(ctrlName, eventName, args);
if (Object.is(ctrlName, 'searchform')) {
this.searchFormEvent(eventName, args);
}
if (Object.is(ctrlName, 'mdctrl')) {
this.MDCtrlEvent(eventName,args);
}
}
/**
* 搜索表单事件
*
* @param {string} eventName
* @param {*} [args={}]
* @memberof MDViewEngine
*/
public searchFormEvent(eventName: string, args: any = {}): void {
if (Object.is(eventName, 'load')) {
this.onSearchFormLoad(args);
}
}
/**
*
*
* @param {string} eventName
* @param {*} [args={}]
* @memberof GridViewEngine
*/
/**
* 事件处理
*
* @param {string} eventName
* @param {any[]} args
* @memberof MDViewEngine
*/
public MDCtrlEvent(eventName: string, args: any): void {
if (Object.is(eventName, 'rowclick')) {
this.doEdit(args);
}
if (Object.is(eventName, 'click')) {
this.doEdit(args);
}
if (Object.is(eventName, 'rowdblclick')) {
this.doEdit(args);
}
if (Object.is(eventName, 'selectchange')) {
this.selectionChange(args);
}
if (Object.is(eventName, 'load')) {
this.MDCtrlLoad(args);
}
if (Object.is(eventName, 'beforeload')) {
this.MDCtrlBeforeLoad(args)
}
}
/**
* 搜索表单加载完成
*
* @param {*} [args={}]
* @memberof MDViewEngine
*/
public onSearchFormLoad(args: any = {}): void {
if (this.getMDCtrl()) {
const tag = this.getMDCtrl().name;
this.setViewState2({ tag: tag, action: 'load', viewdata: {} });
}
}
/**
* 处理实体界面行为
*
* @param {string} tag
* @param {string} [actionmode]
* @returns {void}
* @memberof GridViewEngine
*/
public doSysUIAction(tag: string, actionmode?: string): void {
// if (Object.is(tag, 'Help')) {
// this.doHelp(params);
// return;
// }
if (Object.is(tag, 'Edit')) {
this.doEdit();
return;
}
// if (Object.is(tag, 'View')) {
// this.doView(params);
// return;
// }
// if (Object.is(tag, 'Print')) {
// this.doPrint(params);
// return;
// }
// if (Object.is(tag, 'ExportExcel')) {
// this.doExportExcel(params);
// return;
// }
// if (Object.is(tag, 'ExportModel')) {
// this.doExportModel(params);
// return;
// }
// if (Object.is(tag, 'Copy')) {
// this.doCopy(params);
// return;
// }
if (Object.is(tag, 'Remove')) {
this.doRemove();
return;
}
// if (Object.is(tag, 'Import')) {
// this.doImport(params);
// return;
// }
// if (Object.is(tag, 'Refresh')) {
// this.doRefresh(params);
// return;
// }
// if (Object.is(tag, 'NewRow')) {
// this.doCheck(params);
// return;
// }
if (Object.is(tag, 'SaveRow')) {
this.doSaveEditRow();
return;
}
if (Object.is(tag, 'New')) {
this.doNew();
return;
}
if (Object.is(tag, 'OpenRowEdit')) {
this.doOpenRowEdit();
return;
}
if (Object.is(tag, 'CloseRowEdit')) {
this.doCloseRowEdit();
return;
}
// if (Object.is(tag, 'ToggleRowEdit')) {
// this.doToggleRowEdit(params);
// return;
// }
// if (Object.is(tag, 'ToggleFilter')) {
// this.doToggleFilter(params);
// return;
// }
super.doSysUIAction(tag, actionmode);
}
/**
* 多数据项界面_开启行编辑操作
*
* @memberof GridViewEngine
*/
public doOpenRowEdit(): void {
if (this.getMDCtrl()) {
const tag = this.getMDCtrl().name;
this.setViewState2({ tag: tag, action: 'openEdit', viewdata: {} });
}
}
/**
* 多数据项界面_关闭行编辑操作
*
* @memberof GridViewEngine
*/
public doCloseRowEdit(): void {
if (this.getMDCtrl()) {
const tag = this.getMDCtrl().name;
this.setViewState2({ tag: tag, action: 'closeEdit', viewdata: {} });
}
}
/**
* 多数据项界面_提交编辑数据操作
*
* @memberof GridViewEngine
*/
public doSaveEditRow(): void {
if (this.getMDCtrl()) {
const tag = this.getMDCtrl().name;
this.setViewState2({ tag: tag, action: 'submitEidt', viewdata: {} });
}
}
/**
* 多数据项界面_编辑操作
*
* @param {*} [params={}]
* @returns {void}
* @memberof GridViewEngine
*/
public doEdit(params: any = {}): void {
// 获取要编辑的数据集合
if (params && params.srfkey) {
if (this.isFunc(this.getMDCtrl().findItem)) {
params = this.getMDCtrl().findItem('srfkey', params.srfkey);
}
const arg = { data: params };
this.onEditData(arg);
return;
}
if (this.isFunc(this.getMDCtrl().getSelection)) {
const selectedData = this.getMDCtrl().getSelection();
if (selectedData == null || selectedData.length === 0) {
return;
}
this.onEditData({ data: selectedData[0] });
}
}
/**
* 编辑数据
*
* @param {*} arg
* @memberof GridViewEngine
*/
public onEditData(arg: any): void {
const loadParam: any = {};
// if (this.getViewParam()) {
// Object.assign(loadParam, this.getViewParam());
// }
// if (this.getParentMode()) {
// Object.assign(loadParam, this.getParentMode());
// }
// if (this.getParentData()) {
// Object.assign(loadParam, this.getParentData());
// }
if (arg.srfcopymode) {
Object.assign(loadParam, {
srfsourcekey: arg.data.srfkey
});
} else {
Object.assign(loadParam, { srfkey: arg.data.srfkey, srfdeid: arg.data.srfdeid });
}
if (this.openData && this.isFunc(this.openData)) {
this.openData(loadParam);
}
}
/**
* 多数据项界面_新建操作
*
* @param {*} [params={}]
* @memberof GridViewEngine
*/
public doNew(params: any = {}): void {
this.onNewData();
}
/**
* 新建数据
*
* @returns {void}
* @memberof GridViewEngine
*/
public onNewData(): void {
// tslint:disable-next-line:prefer-const
let loadParam: any = {};
// if (this.getViewParam()) {
// Object.assign(loadParam, this.getViewParam());
// }
// if (this.getParentMode()) {
// Object.assign(loadParam, this.getParentMode());
// }
// if (this.getParentData()) {
// Object.assign(loadParam, this.getParentData());
// }
// if (this.isEnableRowEdit() && (this.getMDCtrl() && this.getMDCtrl().getOpenEdit())) {
// this.doNewRow(loadParam);
// return;
// }
// if (this.isEnableBatchAdd()) {
// this.doNewDataBatch(loadParam);
// return;
// }
// if (this.doNewDataWizard(loadParam)) {
// return;
// }
this.doNewDataNormal(loadParam);
}
/**
* 常规新建数据
*
* @param {*} arg
* @returns {*}
* @memberof GridViewEngine
*/
public doNewDataNormal(arg: any): any {
// let view = this.getNewDataView(arg);
// if (view == null) {
// return false;
// }
// const openMode = view.openMode;
// if (!openMode || Object.is(openMode, '')) {
// view.openMode = 'INDEXVIEWTAB';
// }
// if (!view.state) {
// view.state = 'new';
// let viewParam: any = {};
// Object.assign(viewParam, view.viewParam);
// if (viewParam && viewParam.srfnewmode && !Object.is(viewParam.srfnewmode, '')) {
// const srfnewmode: string = viewParam.srfnewmode.split('@').join('__');
// view.state = view.state + '_' + srfnewmode.toLowerCase();
// }
// }
return this.openDataView(arg);
}
/**
* 多数据项界面_删除操作
*
* @memberof MDViewEngine
*/
public doRemove(): void {
}
public openDataView(view: any = {}): boolean {
const openMode = view.openMode;
// if (view.redirect) {
// this.redirectOpenView(view);
// return false;
// }
if (openMode !== undefined) {
if (Object.is(openMode, 'POPUPMODAL')) {
view.modal = true;
} else if (Object.is(openMode, 'POPUP')) {
view.modal = true;
} else if (Object.is(openMode, '') || Object.is(openMode, 'INDEXVIEWTAB')) {
view.modal = false;
}
}
// if (view.modal) {
// let modalview = this.openModal(view);
// modalview.subscribe((result: any) => {
// if (result && Object.is(result.ret, 'OK')) {
// this.onRefresh();
// }
// });
// return true;
// }
// else {
// this.openWindow(view.viewurl, view.viewparam);
// }
if (this.newData && this.isFunc(this.newData)) {
this.newData({});
}
return true;
}
/**
* 选中变化
*
* @param {any[]} args
* @memberof GridViewEngine
*/
public selectionChange(args: any[]): void {
if (this.view) {
this.view.viewdataschange.emit(args);
}
if (this.getPropertyPanel()) {
const tag = this.getPropertyPanel().name;
this.setViewState2({ tag: tag, action: 'load', viewdata: args[0] });
}
}
/**
* 多数据部件加载完成
*
* @param {any[]} args
* @memberof MDViewEngine
*/
public MDCtrlLoad(args: any[]) {
if (this.view) {
this.view.viewload.emit(args);
}
}
/**
* 多数据部件加载之前
*
* @param {*} [arg={}]
* @memberof MDViewEngine
*/
public MDCtrlBeforeLoad(arg: any = {}): void {
if (this.viewdata.srfparentdata && Object.keys(this.viewdata.srfparentdata).length > 0) {
Object.assign(arg, { srfparentdata: this.viewdata.srfparentdata });
}
if (this.view) {
Object.assign(arg, { query: this.view.query });
}
}
/**
* 获取多数据部件
*
* @returns {*}
* @memberof MDViewEngine
*/
public getMDCtrl(): any {
return this.mdctrl;
}
/**
* 获取属性面板
*
* @returns
* @memberof PickupGridViewEngine
*/
public getPropertyPanel() {
return this.propertypanel;
}
}
\ No newline at end of file
import ViewEngine from './view-engine';
/**
* 编辑视图引擎
*
* @export
* @class MobPickupTreeViewEngine
* @extends {ViewEngine}
*/
export default class MobPickupTreeViewEngine extends ViewEngine {
/**
* 树部件
*
* @protected
* @type {*}
* @memberof MobTreeViewEngine
*/
protected tree: any;
/**
* 初始化编辑视图引擎
*
* @param {*} [options={}]
* @memberof MobTreeViewEngine
*/
public init(options: any = {}): void {
this.tree = options.tree;
super.init(options);
}
/**
* 引擎加载
*
* @param {*} [opts={}]
* @memberof MobTreeViewEngine
*/
public load(opts: any = {}): void {
super.load(opts);
if (this.getTree()) {
const tag = this.getTree().name;
this.setViewState2({ tag: tag, action: 'load', viewdata: this.viewdata });
}
}
/**
* 部件事件机制
*
* @param {string} ctrlName
* @param {string} eventName
* @param {*} args
* @memberof MobTreeViewEngine
*/
public onCtrlEvent(ctrlName: string, eventName: string, args: any): void {
super.onCtrlEvent(ctrlName, eventName, args);
if (Object.is(ctrlName, 'tree')) {
this.treeEvent(eventName, args);
}
}
/**
* 树事件
*
* @param {string} eventName
* @param {*} args
* @memberof MobTreeViewEngine
*/
public treeEvent(eventName: string, args: any): void {
if (Object.is(eventName, 'load')) {
this.onTreeLoad(args);
}
if (Object.is(eventName, 'selectchange')) {
this.onTreeSelectchange(args);
}
}
/**
* 树加载完成
*
* @param {*} args
* @memberof MobTreeViewEngine
*/
public onTreeLoad(args: any): void {
if (this.view) {
this.view.datainfo = args.srfmajortext;
this.view.viewdataschange.emit({action:'load',items:args});
}
}
/**
* 树点击事件
*
* @param {*} args
* @memberof MobTreeViewEngine
*/
public onTreeSelectchange(args: any): void {
if(this.view){
this.view.selectedArray = args;
this.view.viewdataschange.emit({action:'selectchange',items:args});
}
}
/**
* 获取树对象
*
* @returns {*}
* @memberof MobTreeViewEngine
*/
public getTree(): any {
return this.tree;
}
}
\ No newline at end of file
import ViewEngine from './view-engine';
/**
* 数据选择视图引擎
*
* @export
* @class MDViewEngine
* @extends {ViewEngine}
*/
export default class MobPickupViewEngine extends ViewEngine {
/**
* pickupviewpanel面板
*
* @type {*}
* @memberof GridViewEngine
*/
protected pickupviewpanel: any;
/**
* 打开数据
*
* @type {*}
* @memberof GridViewEngine
*/
protected openData?: (params: any) => void;
/**
* 新建数据
*
* @protected
* @memberof GridViewEngine
*/
protected newData?: (params: any) => void;
/**
* Creates an instance of GridViewEngine.
* @memberof GridViewEngine
*/
constructor() {
super();
}
/**
* 引擎初始化
*
* @param {*} [options={}]
* @memberof GridViewEngine
*/
public init(options: any = {}): void {
this.pickupviewpanel = options.pickupviewpanel;
this.openData = options.opendata;
this.newData = options.newdata;
super.init(options);
}
/**
* 引擎加载
*
* @param {*} [opts={}]
* @memberof MDViewEngine
*/
public load(opts: any = {}): void {
super.load(opts);
const _srfparentdata = this.viewdata.srfparentdata ? { srfparentdata: this.viewdata.srfparentdata } : { srfparentdata: {} };
if (this.getPickupviewpanel()) {
const tag = this.getPickupviewpanel().name;
this.setViewState2({ tag: tag, action: 'load', viewdata: _srfparentdata });
}
}
/**
* 部件事件
*
* @param {string} ctrlName
* @param {string} eventName
* @param {*} args
* @memberof GridViewEngine
*/
public onCtrlEvent(ctrlName: string, eventName: string, args: any): void {
super.onCtrlEvent(ctrlName, eventName, args);
if (Object.is(ctrlName, 'pickupviewpanel')) {
this.pickupviewpanelEvent(eventName, args);
}
}
/**
* pickupviewpanel事件
*
* @param {string} eventName
* @param {*} [args={}]
* @memberof MDViewEngine
*/
public pickupviewpanelEvent(eventName: string, args: any = {}): void {
if (Object.is(eventName, 'load')) {
this.onPickupviewpanelLoad(args);
}
if (Object.is(eventName, 'dataschange')) {
this.onickupviewpanelDatasChange(args);
}
}
/**
* 搜索表单加载完成
*
* @param {*} [args={}]
* @memberof MDViewEngine
*/
public onPickupviewpanelLoad(args: any = {}): void {
if (this.view) {
this.view.viewload.emit(args);
}
}
public onickupviewpanelDatasChange(args: any = {}): void {
if (this.view) {
this.view.viewdataschange.emit(args);
this.view.viewDatasChange(args);
}
}
public doSysUIAction(tag: string, actionmode?: string): void {
super.doSysUIAction(tag, actionmode);
}
public getPickupviewpanel(): any {
return this.pickupviewpanel;
}
}
\ No newline at end of file
import ViewEngine from './view-engine';
/**
* 编辑视图引擎
*
* @export
* @class MobTreeViewEngine
* @extends {ViewEngine}
*/
export default class MobTreeViewEngine extends ViewEngine {
/**
* 树部件
*
* @protected
* @type {*}
* @memberof MobTreeViewEngine
*/
protected tree: any;
/**
* 初始化编辑视图引擎
*
* @param {*} [options={}]
* @memberof MobTreeViewEngine
*/
public init(options: any = {}): void {
this.tree = options.tree;
super.init(options);
}
/**
* 引擎加载
*
* @param {*} [opts={}]
* @memberof MobTreeViewEngine
*/
public load(opts: any = {}): void {
super.load(opts);
if (this.getTree()) {
const tag = this.getTree().name;
this.setViewState2({ tag: tag, action: 'load', viewdata: this.viewdata });
}
}
/**
* 部件事件机制
*
* @param {string} ctrlName
* @param {string} eventName
* @param {*} args
* @memberof MobTreeViewEngine
*/
public onCtrlEvent(ctrlName: string, eventName: string, args: any): void {
super.onCtrlEvent(ctrlName, eventName, args);
if (Object.is(ctrlName, 'tree')) {
this.treeEvent(eventName, args);
}
}
/**
* 树事件
*
* @param {string} eventName
* @param {*} args
* @memberof MobTreeViewEngine
*/
public treeEvent(eventName: string, args: any): void {
if (Object.is(eventName, 'load')) {
this.onTreeLoad(args);
}
if (Object.is(eventName, 'click')) {
this.onTreeClick(args);
}
}
/**
* 树加载完成
*
* @param {*} args
* @memberof MobTreeViewEngine
*/
public onTreeLoad(args: any): void {
if (this.view) {
this.view.datainfo = args.srfmajortext;
this.view.viewdataschange.emit({action:'load',items:args});
}
}
/**
* 树点击事件
*
* @param {*} args
* @memberof MobTreeViewEngine
*/
public onTreeClick(args: any): void {
if(this.view){
this.view.viewdataschange.emit({action:'click',items:args});
}
}
/**
* 保存视图数据
*
* @param {*} [arg={}]
* @memberof MobTreeViewEngine
*/
public saveData(arg: any = {}): void {
if (this.getTree()) {
const tag = this.getTree().name;
this.setViewState2({ tag: tag, action: 'save', viewdata: arg });
}
}
/**
* 获取树对象
*
* @returns {*}
* @memberof MobTreeViewEngine
*/
public getTree(): any {
return this.tree;
}
}
\ No newline at end of file
import ViewEngine from './view-engine';
/**
* 编辑视图引擎
*
* @export
* @class MobWFActionViewEngine
* @extends {ViewEngine}
*/
export default class MobWFActionViewEngine extends ViewEngine {
/**
* 表单部件
*
* @protected
* @type {*}
* @memberof MobWFActionViewEngine
*/
protected form: any;
/**
* 父健为当前健
*
* @protected
* @type {string}
* @memberof MobWFActionViewEngine
*/
protected p2k: string = '';
/**
* 初始化编辑视图引擎
*
* @param {*} [options={}]
* @memberof MobWFActionViewEngine
*/
public init(options: any = {}): void {
this.form = options.form;
this.p2k = options.p2k;
super.init(options);
}
/**
* 引擎加载
*
* @param {*} [opts={}]
* @memberof MobWFActionViewEngine
*/
public load(opts: any = {}): void {
super.load(opts);
if (this.getForm()) {
const tag = this.getForm().name;
if (Object.is(this.p2k, '1') && this.viewdata.srfparentdata && !Object.is(this.viewdata.srfparentdata.srfparentkey, '')) {
Object.assign(this.viewdata, { srfkey: this.viewdata.srfparentdata.srfparentkey });
}
const action: string = this.viewdata.srfkey && !Object.is(this.viewdata.srfkey, '') ? 'load' : 'loaddraft';
// const action: string ='loaddraft';
this.setViewState2({ tag: tag, action: action, viewdata: this.viewdata });
}
}
/**
* 部件事件机制
*
* @param {string} ctrlName
* @param {string} eventName
* @param {*} args
* @memberof MobWFActionViewEngine
*/
public onCtrlEvent(ctrlName: string, eventName: string, args: any): void {
super.onCtrlEvent(ctrlName, eventName, args);
if (Object.is(ctrlName, 'form')) {
this.formEvent(eventName, args);
}
}
/**
* 表单事件
*
* @param {string} eventName
* @param {*} args
* @memberof MobWFActionViewEngine
*/
public formEvent(eventName: string, args: any): void {
if (Object.is(eventName, 'load')) {
this.onFormLoad(args);
}
if (Object.is(eventName, 'save')) {
this.onFormSave(args);
}
if (Object.is(eventName, 'remove')) {
this.onFormRemove(args);
}
if (Object.is(eventName, 'wfstart')) {
this.onFormWFStart(args);
}
if (Object.is(eventName, 'wfsubmit')) {
this.onFormWFSubmit(args);
}
}
/**
* 表单加载完成
*
* @param {*} args
* @memberof MobWFActionViewEngine
*/
public onFormLoad(args: any): void {
if (Object.is(args.srfuf, '1')) {
this.view.datainfo = args.srfmajortext;
this.view.viewdataschange.emit({action:'load',items:args});
}
}
/**
* 表单工作流开始流程完成
*
* @param {*} args
* @memberof MobWFActionViewEngine
*/
public onFormWFStart(args: any): void {
if (this.view) {
this.view.viewdataschange.emit({action:'wfstart',items:args});
}
}
/**
* 表单工作流提交完成
*
* @param {*} args
* @memberof MobWFActionViewEngine
*/
public onFormWFSubmit(args: any): void {
if (this.view) {
this.view.viewdataschange.emit({action:'wfsubmit',items:args});
this.view.$activeData = args;
this.view.backView();
this.view.$navCtrl.back();
}
}
/**
* 表单保存完成
*
* @param {*} args
* @memberof MobWFActionViewEngine
*/
public onFormSave(args: any): void {
if(this.view){
this.view.viewdataschange.emit({action:'save',items:args});
if(this.viewdata){
this.submitData(this.viewdata);
}else{
this.submitData({});
}
}
}
/**
* 表单删除完成
*
* @param {*} args
* @memberof MobWFActionViewEngine
*/
public onFormRemove(args: any): void {
this.view.viewrefreshTag =true;
this.view.viewdataschange.emit({action:'remove',items:args});
}
/**
* 处理实体界面行为
*
* @param {string} tag
* @param {string} [actionmode]
* @returns {void}
* @memberof MobWFActionViewEngine
*/
public doSysUIAction(tag: string, actionmode?: string): void {
if (Object.is(tag, 'Save')) {
this.doSave();
return;
}
super.doSysUIAction(tag, actionmode);
}
/**
* 编辑界面_保存操作
*
* @memberof IBizEditViewController
*/
public doSave(): void {
// this.afterformsaveaction = '';
if(this.viewdata){
this.saveData(this.viewdata);
}else{
this.saveData({});
}
}
/**
* 保存视图数据
*
* @param {*} [arg={}]
* @memberof MobWFActionViewEngine
*/
public saveData(arg: any = {}): void {
if (this.getForm()) {
const tag = this.getForm().name;
this.setViewState2({ tag: tag, action: 'save', viewdata: arg });
}
}
/**
* 提交工作流
*
* @param {*} [arg={}]
* @memberof MobWFActionViewEngine
*/
public submitData(arg: any = {}): void {
if (this.getForm()) {
const tag = this.getForm().name;
this.setViewState2({ tag: tag, action: 'submit', viewdata: arg });
}
}
/**
* 获取表单对象
*
* @returns {*}
* @memberof MobWFActionViewEngine
*/
public getForm(): any {
return this.form;
}
}
\ No newline at end of file
import EditViewEngine from './edit-view-engine';
/**
* 编辑视图引擎
*
* @export
* @class EditViewEngine
* @extends {ViewEngine}
*/
export default class MobWFEditViewEngine extends EditViewEngine {
/**
* 表单部件
*
* @protected
* @type {*}
* @memberof EditViewEngine
*/
protected form: any;
/**
* 工具栏
*
* @protected
* @type {*}
* @memberof EditViewEngine
*/
protected righttoolbar: any;
/**
* 快速工具栏
*
* @protected
* @type {*}
* @memberof EditViewEngine
*/
protected quicktoolbar: any;
/**
* 父健为当前健
*
* @protected
* @type {string}
* @memberof EditViewEngine
*/
protected p2k: string = '';
/**
* 初始化编辑视图引擎
*
* @param {*} [options={}]
* @memberof EditViewEngine
*/
public init(options: any = {}): void {
super.init(options);
this.righttoolbar = options.righttoolbar;
this.quicktoolbar =options.quicktoolbar;
}
}
\ No newline at end of file
import EditViewEngine from './edit-view-engine';
/**
* 工作流编辑视图3引擎
*
* @export
* @class EditViewEngine
* @extends {ViewEngine}
*/
export default class MobWFEditView3Engine extends EditViewEngine {
}
\ No newline at end of file
import MobMDViewEngine from './mob-mdview-engine';
export default class MobWFMDViewEngine extends MobMDViewEngine {
}
\ No newline at end of file
import EditViewEngine from './edit-view-engine';
export default class MobWFStartViewEngine extends EditViewEngine {
}
\ No newline at end of file
import { ComUtil } from '@global/util/ComUtil';
/**
*
*
* @export
* @class ViewEngine
*/
export default class ViewEngine {
/**
* 视图部件对象
*
* @protected
* @type {*}
* @memberof ViewEngine
*/
protected view: any = null;
/**
* 引擎参数
*
* @type {*}
* @memberof ViewEngine
*/
protected opt: any = {};
/**
*
*
* @type {*}
* @memberof ViewEngine
*/
protected methods: any = {};
/**
* 视图数据
*
* @type {*}
* @memberof ViewEngine
*/
public viewdata: any = {};
/**
* Creates an instance of ViewEngine.
* @memberof ViewEngine
*/
constructor() { }
/**
* 引擎初始化
*
* @param {*} [options={}]
* @memberof GridViewEngine
*/
public init(options: any = {}): void {
this.opt = options;
this.methods = options.methods;
this.view = options.view;
const hasviewdata: boolean = this.view.viewdata ? true : false;
if (hasviewdata) {
try {
if(this.view.viewdata.parentdata){
let tempObj;
if(typeof(this.view.viewdata.parentdata)=='string'){
tempObj = JSON.parse(this.view.viewdata.parentdata);
}else{
tempObj = this.view.viewdata.parentdata;
}
Object.assign(this.viewdata, tempObj);
if (this.view.viewdata.srfkey) {
Object.assign(this.viewdata, { srfkey: this.view.viewdata.srfkey });
}
}else{
if(typeof(this.view.viewdata) =='string'){
Object.assign(this.viewdata, JSON.parse(this.view.viewdata));
}else{
Object.assign(this.viewdata, this.view.viewdata);
}
}
} catch (error) {
console.log(error);
}
} else {
const _viewdata: any = {};
let router = this.view.$route;
// if (router && router.length >0) {
// if(router.startsWith("parentdata")){
// let tempRouter = JSON.parse(router.split("=")[1]).srfparentdata;
// if(Object.keys(tempRouter).length >0){
// router ="";
// Object.keys(tempRouter).forEach((item:any,index:any) => {
// if(index < Object.keys(tempRouter).length-1){
// router +=item+"="+tempRouter[item]+";";
// }else{
// router +=item+"="+tempRouter[item];
// }
// });
// }
// }
// Object.assign(_viewdata, ComUtil.formatMatrixParse2(router));
// }else{
// if(router.name){
// Object.assign(this.viewdata,router.name);
// }
// }
if(router && router.length >0){
Object.assign(_viewdata, JSON.parse(router));
}
Object.assign(this.viewdata, _viewdata);
}
this.load();
}
/**
* 设置视图数据
*
* @param {string} viewdata
* @memberof ViewEngine
*/
public setViewData(viewdata: string): void {
this.viewdata = {};
try {
Object.assign(this.viewdata, JSON.parse(viewdata));
} catch (error) {
console.log(error);
}
}
/**
* 引擎加载
*
* @param {*} [opts={}]
* @memberof ViewEngine
*/
public load(opts: any = {}): void {
}
/**
* 部件事件机制
*
* @param {string} ctrlName
* @param {string} eventName
* @param {*} args
* @memberof ViewEngine
*/
public onCtrlEvent(ctrlName: string, eventName: string, args: any): void {
}
/**
* 处理界面行为
*
* @param {string} tag
* @param {string} [actionmode]
* @memberof ViewEngine
*/
public doSysUIAction(tag: string, actionmode?: string): void {
if (Object.is(actionmode, 'FRONT')) {
if (this.methods.front) {
this.methods.front(tag);
}
}
}
/**
* 处理工作流界面行为
*
* @param {string} tag
* @param {string} [actionmode]
* @memberof ViewEngine
*/
public doSysWFUIAction(tag: string, actionmode?: string): void {
if (Object.is(actionmode, 'WFFRONT')) {
if (this.methods.wfFront) {
this.methods.wfFront(tag);
}
}
}
/**
* 是否为方法
*
* @protected
* @param {*} func
* @returns {boolean}
* @memberof ViewEngine
*/
protected isFunc(func: any): boolean {
return func instanceof Function;
}
/**
* 父数据参数模式
*
* @param {{ tag: string, action: string, viewdata: any }} { tag, action, viewdata }
* @memberof ViewEngine
*/
public setViewState2({ tag, action, viewdata }: { tag: string, action: string, viewdata: any }): void {
this.view.viewState.next({ tag: tag, action: action, data: viewdata });
}
}
\ No newline at end of file
export const environment = {
production: true
};
// This file can be replaced during build by using the `fileReplacements` array.
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.
export const environment = {
production: false
};
/*
* For easier debugging in development mode, you can import the following file
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
*
* This import should be commented out in production mode because it will have a negative impact
* on performance if an error is thrown.
*/
// import 'zone.js/dist/zone-error'; // Included with Angular CLI.
// http://ionicframework.com/docs/theming/
@import '~@ionic/angular/css/core.css';
@import '~@ionic/angular/css/normalize.css';
@import '~@ionic/angular/css/structure.css';
@import '~@ionic/angular/css/typography.css';
@import '~@ionic/angular/css/display.css';
@import '~@ionic/angular/css/padding.css';
@import '~@ionic/angular/css/float-elements.css';
@import '~@ionic/angular/css/text-alignment.css';
@import '~@ionic/angular/css/text-transformation.css';
@import '~@ionic/angular/css/flex-utils.css';
@import './theme/default.scss';
@import './theme/user.scss';
<div class="app-anchor-point">
<div class="app-anchor-point-content">
<div *ngFor="let group of $items" (click)="locationMobile(group.name)">
{{ group.name }}
</div>
</div>
</div>
<div class="app-anchor-point-list" >
<ion-list #appAnchorPointList style="height: 100%;overflow-y: auto;">
<ion-item-group *ngFor="let group of $items" [id]="group.name">
<ion-item-divider>
<ion-label>{{ group.name }}</ion-label>
</ion-item-divider>
<ng-container *ngFor="let item of group.items">
<ng-container *ngTemplateOutlet="template;context: {$implicit: item}"></ng-container>
</ng-container>
</ion-item-group>
</ion-list>
</div>
\ No newline at end of file
.app-anchor-point {
position: absolute;
height: 100%;
right: 0px;
z-index: 1;
.app-anchor-point-content {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
div {
padding: 5px 3px;
font-weight: 500;
}
}
}
.app-anchor-point-list {
overflow-y: auto;
overflow-x: hidden;
height: calc(100vh - 46px);
scroll-behavior: smooth;
}
\ No newline at end of file
import { Component, Input, ContentChild, TemplateRef, ViewChild, ViewContainerRef, ElementRef } from '@angular/core';
/**
* 锚点分组列表组件
*
* @export
* @class AppAnchorPointList
*/
@Component({
selector: 'app-anchor-point-list',
templateUrl: 'app-anchor-point-list.html',
styleUrls: ['app-anchor-point-list.scss']
})
export class AppAnchorPointList {
/**
* 插座内容
*
* @type {TemplateRef<any>}
* @memberof AppAnchorPointList
*/
@ContentChild(TemplateRef)
template: TemplateRef<any>;
/**
* List容器
*
* @type {TemplateRef<any>}
* @memberof AppAnchorPointList
*/
@ViewChild('appAnchorPointList', { read: ViewContainerRef })
container: ViewContainerRef;
/**
* 列表数据
*
* @type {any[]}
* @memberof AppAnchorPointList
*/
@Input()
set items(val: any[]) {
if (val) {
this.$items = val;
this.anchorPoints.clear();
}
}
public $items: any[] = [];
/**
* 所有锚点项
*
* @private
* @type {Map<string, Element>}
* @memberof AppAnchorPointList
*/
private anchorPoints: Map<string, Element> = new Map();
/**
* 容器dom对象
*
* @private
* @type {HTMLDivElement}
* @memberof AppAnchorPointList
*/
private containerElement: HTMLDivElement;
/**
* Creates an instance of AppAnchorPointList.
* @memberof AppAnchorPointList
*/
constructor() { }
/**
* 初始化锚点
*
* @memberof AppAnchorPointList
*/
private initAnchorPoint(): void {
if (this.container) {
this.containerElement = this.container.element.nativeElement;
const arr: HTMLCollection = this.containerElement.getElementsByTagName('ion-item-group');
if (arr) {
for (let i: number = 0; i < arr.length; i++) {
const item: Element = arr.item(i);
this.anchorPoints.set(item.id, item);
}
}
}
}
/**
* 定位移动
*
* @param {string} id 移动位置id
* @memberof AppAnchorPointList
*/
public locationMobile(id: string): void {
if (this.anchorPoints.size !== this.$items.length) {
this.initAnchorPoint();
}
const item: any = this.anchorPoints.get(id);
if (item) {
this.containerElement.scrollTo(0, item.offsetTop);
}
}
}
\ No newline at end of file
<div class="app-app-menu">
<ion-card style="border-radius: 0;">
<ng-container *ngIf=" title && title !=='否'">
<ion-item lines="full">
<ion-label>{{ title }}</ion-label>
</ion-item>
</ng-container>
<ion-card-content>
<ion-grid>
<ion-row>
<ion-col *ngFor="let item of items;" [size]="12 / numCol" class="app-app-menu-item"
(click)="onClick(item)">
<div class="icon">
<ng-container *ngIf="!round; else roundIcon;">
<app-icon [item]="item" [isDefault]="true"></app-icon>
</ng-container>
<ng-template #roundIcon>
<img *ngIf="item&&item.icon" class="round-icon"
[src]="item.icon?item.icon:null"
onerror="this.src = './assets/icon/default_img.png'">
</ng-template>
</div>
<div class="title {{ item.textcls }}" [ngClass]="{'round-title': round}">
{{ item.text }}
</div>
</ion-col>
</ion-row>
</ion-grid>
</ion-card-content>
</ion-card>
</div>
\ No newline at end of file
.head{
font-size: 1.15rem;
font-weight: 540;
padding-left: 0.75rem;
padding-top: 0.5rem;
font-family: AncientWar;
}
.app-app-menu {
ion-card {
margin: 0px;
ion-card-header, ion-card-content {
padding: 0.5rem;
}
}
ion-grid {
padding: 0px;
}
.app-app-menu-item {
display: flex;
flex-direction: column;
align-items: center;
.icon {
width: 2.625rem;
height: 2.625rem;
}
.title {
font-size: 0.875rem;
}
.round-title {
margin-top: 0.5rem;
font-size: 0.625rem;
color: black;
}
.round-icon {
border-radius: 50%;
}
}
}
\ No newline at end of file
import { Component, Input, Output, EventEmitter } from '@angular/core';
/**
* 默认应用菜单部件样式
*
* @export
* @class AppQuickMenu
*/
@Component({
selector: 'app-app-menu',
templateUrl: './app-app-menu.html',
styleUrls: ['./app-app-menu.scss']
})
export class AppQuickMenu {
/**
* 菜单数据
*
* @type {any[]}
* @memberof AppQuickMenu
*/
@Input()
items: any[] = [];
/**
* 菜单部件标题
*
* @type {string}
* @memberof AppQuickMenu
*/
@Input()
title: string;
/**
* 一行显示的列数
*
* @type {number}
* @memberof AppQuickMenu
*/
@Input()
numCol: number = 4;
/**
* 是否为圆的图标
*
* @type {boolean}
* @memberof AppQuickMenu
*/
@Input()
round: boolean = false;
/**
* 菜单点击事件
*
* @type {EventEmitter<string>}
* @memberof AppQuickMenu
*/
@Output()
menuClick: EventEmitter<string> = new EventEmitter();
/**
* 菜单点击
*
* @param {string} appFuncId
* @memberof AppQuickMenu
*/
public onClick(appFuncId: string): void {
this.menuClick.emit(appFuncId);
}
}
\ No newline at end of file
<div class="app-calendar">
<div class="calendar-header">
<ion-icon name="arrow-round-back" (click)="lastMonth()"></ion-icon>
<span>{{ year }}-{{ month + 1 }}-{{ day }}</span>
<ion-icon name="arrow-round-forward" (click)="nextMonth()"></ion-icon>
</div>
<div class="calendar-flex">
<div class="calendar-row">
<div class="calendar-col" *ngFor="let week of calendarUtil.weeks">
<div class="calendar-week">
{{ week }}
</div>
</div>
</div>
<div class="calendar-content" [ngStyle]="{'max-height': (isMonthMode ? '276px' : '66px')}">
<div class="calendar-flex">
<div class="calendar-row" *ngFor="let items of content">
<div class="calendar-col" *ngFor="let item of items">
<div class="calendar-day" [ngClass]="getDayClass(item, month)" (click)="activeDay(item, item.month)">
<div style="margin-bottom: 1px;">{{ (calendarUtil.day === item.day && calendarUtil.month === item.month) ? '今' : item.day }}</div>
<div [ngClass]="{ 'have-data': isData(item) }"></div>
</div>
</div>
</div>
</div>
<!-- <div class="calendar-shrink" (click)="showModeChange()">
<ion-icon [name]="isMonthMode ? 'arrow-up' : 'arrow-down'" style="font-size: 20px;"></ion-icon>
</div> -->
</div>
</div>
</div>
\ No newline at end of file
.app-calendar {
width: 100%;
.calendar-content {
transition: 1.3s;
}
.calendar-header {
min-height: 36px;
font-size: 24px;
display: flex;
justify-content: center;
align-items: center;
ion-icon {
flex-grow: 1;
}
span {
flex-grow: 5;
text-align: center;
}
}
.calendar-flex {
display: flex;
flex-direction: column;
width: 100vw;
.calendar-row {
display: flex;
flex-direction: row;
width: 100vw;
.calendar-col {
width: calc(100% / 7);
height: 36px;
margin: 3px;
display: flex;
justify-content: center;
align-items: center;
.calendar-day,
.calendar-week {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 36px;
height: 36px;
border-radius: 50%;
}
.active {
background-color: cornflowerblue;
color: white;
}
.no-current-month {
color: #e3e3e3;
}
}
}
}
.calendar-shrink {
width: 100%;
text-align: center;
border-bottom: 1px solid #e3e3e3;
}
.have-data {
border-radius: 50%;
width: 5px;
height: 5px;
background-color: var(--ion-color-secondary, #0cd1e8);
margin-bottom: -5px;
}
}
\ No newline at end of file
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { AppCalendarUtil } from '../../util/AppCalendarUtil';
import * as moment from 'moment';
@Component({
selector: 'app-calendar',
templateUrl: './app-calendar.html',
styleUrls: ['app-calendar.scss']
})
export class AppCalendar implements OnInit {
@Input()
set data(val: any[]) {
if (val) {
this.items = val;
this.items.forEach((item: any) => {
// const date: Date = moment(item.begintime, this.dateFormat).toDate();
const date: Date = new Date(item.begintime);
this.dateIsData[`${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`] = true;
});
}
}
/**
* 设置当前选中时间
*
* @memberof AppCalendar
*/
@Input()
set activeDate(val: {year: number, month: number, day: number}) {
if (val) {
this.year = val.year;
this.month = val.month;
this.day = val.day;
}
}
/**
* 选中时间变更事件
*
* @type {EventEmitter<{year: number, month: number, day: number}>}
* @memberof AppCalendar
*/
@Output()
activeDateChange: EventEmitter<{year: number, month: number, day: number}> = new EventEmitter();
/**
* 数据
*
* @type {any[]}
* @memberof AppCalendar
*/
public items: any[] = [];
/**
* 当前日期是否有数据
*
* @type {*}
* @memberof AppCalendar
*/
public dateIsData: any = {};
/**
* 日历工具类
*
* @type {AppCalendarUtil}
* @memberof AppCalendar
*/
public calendarUtil: AppCalendarUtil = new AppCalendarUtil();
/**
* 日历当前显示年份
*
* @type {number}
* @memberof AppCalendar
*/
public year: number;
/**
* 日历当前显示月份
*
* @type {number}
* @memberof AppCalendar
*/
public month: number;
/**
* 日历当前选中天
*
* @type {number}
* @memberof AppCalendar
*/
public day: number;
/**
* 日历显示内容
*
* @type {any[]}
* @memberof AppCalendar
*/
public content: any[] = [];
/**
* 是否为月显示模式
*
* @type {boolean}
* @memberof AppCalendar
*/
public isMonthMode: boolean = true;
/**
* 日期格式
*
* @type {string}
* @memberof AppCalendar
*/
public dateFormat: string = 'YYYY-MM-DD HH:mm:ss';
/**
* Creates an instance of AppCalendar.
* @memberof AppCalendar
*/
constructor() {
this.year = this.calendarUtil.year;
this.month = this.calendarUtil.month;
this.day = this.calendarUtil.day;
this.showMonthDaysChange();
}
public ngOnInit() { }
/**
* 设置当前激活天
*
* @param {*} item
* @param {number} month
* @memberof AppCalendar
*/
public activeDay(item: any, month: number): void {
if (item && item.day) {
this.day = item.day;
}
if (this.month !== month) {
if (this.month > month) {
this.monthChange(false);
} else {
this.monthChange(true);
}
this.showMonthDaysChange();
}
this.onChange();
}
/**
* 发送选中时间变更事件
*
* @memberof AppCalendar
*/
public onChange(): void {
this.activeDateChange.emit({
year: this.year,
month: this.month,
day: this.day
});
}
/**
* 改变当前显示模式
*
* @memberof AppCalendar
*/
public showModeChange() {
this.isMonthMode = !this.isMonthMode;
this.showMonthDaysChange();
}
/**
* 获取当前显示
*
* @memberof AppCalendar
*/
public showMonthDaysChange(): void {
const arr: any[] = this.calendarUtil.getDaysCurrentMonth(this.month, this.year);
this.content = [];
if (this.isMonthMode) {
this.content.push(...arr);
} else {
this.content.push(arr.find((items: any[]) => {
const num: number = items.findIndex((item) => (item.day === this.day && item.month === this.month));
return num !== -1;
}));
}
}
/**
* 上个月
*
* @memberof AppCalendar
*/
public lastMonth(): void {
if (this.isMonthMode) {
this.monthChange(false);
this.showMonthDaysChange();
} else {
// this.weeksChange(false);
}
}
/**
* 下个月
*
* @memberof AppCalendar
*/
public nextMonth(): void {
if (this.isMonthMode) {
this.monthChange(true);
this.showMonthDaysChange();
} else {
// this.weeksChange(true);
}
}
/**
* 月份变更
*
* @param {boolean} [isNext=true] 下个月 or 上个月
* @memberof AppCalendar
*/
public monthChange(isNext: boolean = true): void {
if (this.month === 0) {
this.month = isNext ? 1 : 11;
if (!isNext) {
--this.year;
}
} else if (this.month === 11) {
this.month = isNext ? 0 : 10;
if (isNext) {
++this.year;
}
} else {
this.month = isNext ? this.month + 1 : this.month - 1;
}
this.onChange();
}
/**
* 获取天样式
*
* @param {*} item
* @param {number} month
* @returns {*}
* @memberof AppCalendar
*/
public getDayClass(item: any, month: number): any {
const classNames: any = {};
classNames.active = item.day === this.day && item.month === this.month;
classNames['no-current-month'] = item.month !== month;
return classNames;
}
/**
* 是否有数据
*
* @param {*} item
* @returns {boolean}
* @memberof AppCalendar
*/
public isData(item: any): boolean {
if (item) {
const r = this.dateIsData[`${item.year}-${item.month}-${item.day}`];
return r ? true : false;
}
return false;
}
}
\ No newline at end of file
<ion-datetime class="app-datetime" [displayFormat]="datefmt" cancelText="取消" doneText="确定" [(ngModel)]="value" (ngModelChange)="onValueChange($event)"></ion-datetime>
\ No newline at end of file
.app-datetime {
padding: 6px 0px;
}
\ No newline at end of file
import { Component, Input, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
import { DatePipe } from '@angular/common';
import * as moment from 'moment';
@Component({
selector: 'app-datetime',
templateUrl: './app-datetime.html',
styleUrls: ['./app-datetime.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => AppDateTime),
multi: true
}
]
})
export class AppDateTime implements ControlValueAccessor {
/**
* 编辑器值
*
* @type {string}
* @memberof AppDateTime
*/
public value: string;
/**
* 时间编辑器格式
*
* @type {string}
* @memberof AppDateTime
*/
@Input()
datefmt: string;
/**
* 是否启用
*
* @type {boolean}
* @memberof AppDateTime
*/
@Input()
disabled: boolean;
/**
* 提示信息
*
* @type {string}
* @memberof AppDateTime
*/
@Input()
placeholder: string;
/**
* Creates an instance of AppDateTime.
* 创建 AppDateTime 实例
*
* @param {DatePipe} datePipe
* @memberof AppDateTime
*/
constructor(private datePipe: DatePipe) { }
/**
* 数据发生改变
*
* @param {*} val
* @memberof AppDateTime
*/
public onValueChange(val): void {
if (this.datefmt.indexOf('YYYY') > 0 || this.datefmt.indexOf('MM') > 0 || this.datefmt.indexOf('DD') > 0) {
this.value = this.datePipe.transform(val, this.datefmt.replace('YYYY', 'yyyy').replace('DD', 'dd'));
} else {
this.value = moment(val).format(this.datefmt);
}
this.onChange(this.value);
}
/**
* 输入
*
* @param {*} obj
* @memberof AppDateTime
*/
public writeValue(obj: any): void {
this.value = obj;
}
private onTouched: () => void = () => { };
private onChange: (val: any) => void = () => { };
public registerOnChange(fn: any): void { this.onChange = fn; }
public registerOnTouched(fn: any): void { this.onTouched = fn; }
}
\ No newline at end of file
import { Component, Input } from '@angular/core';
/**
* 分割线
*
* @export
* @class AppDividingLine
*/
@Component({
selector: 'app-dividing-line',
template: `<div class="app-dividing-line" [ngStyle]="{}"></div>`,
styles: [`.app-dividing-line { width: 100%; height: 8pt; background-color: #d5d5d5;}`]
})
export class AppDividingLine {
/**
* 样式
*
* @type {*}
* @memberof AppDividingLine
*/
public style: any = {};
/**
* 高度
*
* @memberof AppDividingLine
*/
@Input()
set height(val: string) {
if (val && !Object.is(val, '')) {
this.style.height = val;
}
}
/**
* 背景颜色
*
* @memberof AppDividingLine
*/
@Input()
set backgroundColor(val: string) {
if (val && !Object.is(val, '')) {
Object.assign(this.style, { 'background-color': val });
}
}
}
\ No newline at end of file
<input #fileUpload [hidden]="true" type="file" ng2FileSelect [uploader]="uploader" [multiple]="multiple" />
<ng-container *ngIf="!multiple; else fileMultiple;">
<div class="app-file-upload">
<div class="app-file-upload-content">
<ion-chip *ngFor="let item of files; let i = index;">
<ion-label (tap)="downloadFile(item)">{{ item.name | slice:0:9 }} {{ item.name.length > 10 ? '...' : '' }}</ion-label>
<ion-icon [hidden]="disabled" name="close-circle" (click)="deleteFile(item.id, i)"></ion-icon>
</ion-chip>
</div>
<div class="app-file-upload-button">
<ion-icon class='add-icon' [hidden]="disabled || (files.length >= fileCount)" name="add" (click)="fileSelect()"
color="primary"></ion-icon>
</div>
</div>
</ng-container>
<ng-template #fileMultiple>
<div class="app-file-upload-multiple">
<ion-item *ngIf="labelText" class="app-file-upload-title" lines="none">
<ion-label slot="start">
{{ labelText }}<span class="stars" *ngIf="allowEmpty">*</span>
</ion-label>
<span slot="end">
<ion-icon class='add-icon' class="app-file-upload-button" [hidden]="disabled || (files.length >= fileCount)" name="add"
(click)="fileSelect()" color="primary"></ion-icon>
</span>
</ion-item>
<div class="app-file-upload-content">
<ion-item class="app-file-upload-list-item" *ngFor="let item of files; let i = index;" lines="full">
<label (tap)="downloadFile(item)">
{{ item.name }}
</label>
<ion-icon slot="end" [hidden]="disabled" name="close" (click)="deleteFile(item.id, i)" color="primary"></ion-icon>
</ion-item>
</div>
</div>
</ng-template>
\ No newline at end of file
.app-file-upload {
display: flex;
}
.app-file-upload-multiple {
margin-bottom: 3px;
.app-file-upload-title {
--padding-start: 0px;
--inner-padding-end: 0px;
--min-height: 28px;
span {
font-size: 28px;
-webkit-margin-start: 0px;
margin-inline-start: 0px;
-webkit-margin-end: 0px;
margin-inline-end: 0px;
}
.stars {
font-size: var(--app-important-font-size);
margin-left: 3px;
}
}
.app-file-upload-list-item {
@extend .app-file-upload-title;
font-size: var(--app-normal-font-size);
ion-icon {
margin: 0px;
}
}
.app-file-upload-content {
text-align: start;
}
}
.app-file-upload-content {
flex-grow: 1;
overflow: hidden;
}
.app-file-upload-button {
font-size: 22pt;
display: flex;
justify-content: center;
align-self: center;
}
\ No newline at end of file
import { Component, ViewChild, ElementRef, Input, OnInit, Output, EventEmitter } from '@angular/core';
import { FileUploader, FileItem, ParsedResponseHeaders, FileLikeObject, FileUploaderOptions } from 'ng2-file-upload';
import { AppEnvironment } from '../../../environments/AppEnvironment';
import { AppNotification } from '../../service/Notification';
import { Loading } from '../../service/Loading';
@Component({
selector: 'app-file-upload',
templateUrl: './app-file-upload.html',
styleUrls: ['./app-file-upload.scss']
})
export class AppFileUpload implements OnInit {
/**
* 文件上传组件
*
* @type {FileUploader}
* @memberof AppFileUpload
*/
public uploader: FileUploader;
/**
* 已上传文件
*
* @type {any[]}
* @memberof AppFileUpload
*/
public files: any[] = [];
/**
* 上传或下载的地址
*
* @type {string}
* @memberof AppFileUpload
*/
public url: string = '';
/**
* 限制文件上传个数
*
* @type {number}
* @memberof AppFileUpload
*/
public fileCount: number;
/**
* 限制文件上传大小
*
* @private
* @type {number}
* @memberof AppFileUpload
*/
private fileSize: number;
/**
* 是否启用
*
* @type {boolean}
* @memberof IBizDateTime
*/
@Input()
disabled: boolean = false;
/**
* 是否为单文件上传
*
* @type {boolean}
* @memberof AppFileUpload
*/
@Input()
multiple: boolean = false;
/**
* 标签文本值
*
* @type {string}
* @memberof AppFileUpload
*/
@Input()
labelText: string;
/**
* 是否必填
*
* @type {boolean}
* @memberof IBizTextarea
*/
@Input()
allowEmpty: boolean;
/**
* 编辑器参数
*
* @memberof AppFileUpload
*/
@Input()
set params(val: any) {
if (val) {
const { filecount, filesize } = val;
if (filecount) {
this.fileCount = filecount;
}
if (filesize) {
this.fileSize = filesize;
}
}
}
/**
*
*
* @type {ElementRef}
* @memberof AppFileUpload
*/
@ViewChild('fileUpload')
fileUpload: ElementRef;
/**
* 值
*
* @memberof AppFileUpload
*/
@Input()
set value(value: any) {
if (value) {
this.files = [];
let val;
if (typeof (value) === 'string') {
try {
val = JSON.parse(value);
} catch (error) {
console.log(error);
}
} else {
val = value;
}
if (val instanceof Array) {
this.files = [...val];
}
}else{
this.files = [];
}
}
/**
*
*
* @type {EventEmitter<any>}
* @memberof AppFileUpload
*/
@Output()
valueChange: EventEmitter<any> = new EventEmitter();
/**
*
* @param {notification} Notification
* @param {IBizLoading} loading
* @memberof AppFileUpload
*/
constructor(
public notification: AppNotification,
public loading: Loading) {
this.uploader = new FileUploader({ url: AppEnvironment.BaseUrl + AppEnvironment.UploadFile, autoUpload: true });
this.uploader.onSuccessItem = this.successItem.bind(this);
this.uploader.onErrorItem = this.errorItem.bind(this);
this.uploader.onBeforeUploadItem = this.beforeUploadItem.bind(this);
this.uploader._fileSizeFilter = this.fileSizeFilter.bind(this);
// 拼接上传或下载的url
this.url = AppEnvironment.BaseUrl + AppEnvironment.ExportFile + '/';
}
public ngOnInit() {
this.uploader.setOptions({
maxFileSize: this.fileSize
});
}
/**
* 验证文件大小
*
* @param {FileLikeObject} [item]
* @param {FileUploaderOptions} [options]
* @returns {boolean}
* @memberof AppFileUpload
*/
public fileSizeFilter(item?: FileLikeObject): boolean {
if (item && this.fileSize && ((item.size / 1000) >= this.fileSize)) {
this.notification.warning(`文件大小不可超过${this.fileSize}kb`);
return false;
}
return true;
}
/**
* 文件选择
*
* @returns {*}
* @memberof AppFileUpload
*/
public fileSelect(): any {
this.fileUpload.nativeElement.click();
}
/**
* 删除文件
*
* @param {string} id
* @param {number} index
* @memberof AppFileUpload
*/
public async deleteFile(id: string, index: number) {
const res = await this.notification.confirm('确认删除', '确认删除文件吗?');
if (res) {
if (this.files[index] && Object.is(this.files[index].id, id)) {
this.files.splice(index, 1);
this.valueChange.emit(JSON.stringify(this.files));
}
}
}
/**
* 打开新窗口进行文件下载
*
* @param {any} file
* @memberof FileUploadPickerComponent
*/
public async downloadFile(file) {
const res = await this.notification.confirm('下载', '确认下载文件吗?');
if (res) {
window.open(AppEnvironment.BaseUrl + AppEnvironment.ExportFile + `?fileid=${file.id}`, '_blank');
}
}
/**
*
*
* @param {FileItem} item
* @param {string} response
* @param {number} status
* @param {ParsedResponseHeaders} headers
* @memberof AppFileUpload
*/
public async errorItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): Promise<any> {
await this.loading.unmask();
this.notification.error(`文件:${item.file.name},上传失败`);
}
/**
*
*
* @param {FileItem} fileItem
* @memberof AppFileUpload
*/
public async beforeUploadItem(fileItem: FileItem): Promise<any> {
await this.loading.mask('文件上传中...');
}
/**
* 上传成功
*
* @param {FileItem} item
* @param {string} response
* @param {number} status
* @param {ParsedResponseHeaders} headers
* @returns {*}
* @memberof AppFileUpload
*/
public async successItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): Promise<any> {
await this.loading.unmask();
if (this.fileCount && this.fileCount <= this.files.length) {
return;
}
const res: any = JSON.parse(response);
if (res && res.id) {
this.files.push(res);
}
this.valueChange.emit(JSON.stringify(this.files));
}
}
<ion-card class="form-druipart-card">
<ion-card-content style="padding: 0;">
<ng-template #container></ng-template>
</ion-card-content>
</ion-card>
\ No newline at end of file
.form-druipart-card{
margin: 5px;
border-radius: 0;
box-shadow: var(--app-dividing-line-color) 0px 0px 5px;
}
\ No newline at end of file
import { Component, Input,Output, AfterContentInit, ReflectiveInjector, ViewChild, ViewContainerRef, ComponentRef, ComponentFactoryResolver, EventEmitter, OnDestroy } from '@angular/core';
import { Subject, Unsubscribable } from 'rxjs';
import { App } from '@global/service/App';
@Component({
selector: 'app-form-druipart',
templateUrl: './app-form-druipart.component.html',
styleUrls: ['./app-form-druipart.component.scss'],
})
export class AppFormDruipart implements AfterContentInit, OnDestroy {
/**
* 历史拷贝表单数据
*
* @type {string}
* @memberof AppFormDRUIPart
*/
public copydata: any;
/**
* 当前表单数据
*
* @type {string}
* @memberof AppFormDRUIPart
*/
public currentdata: any;
/**
* 组件要存放的地方
*
* @type {string}
* @memberof AppFormDRUIPart
*/
@ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef;
/**
* 动态组件实例
*
* @type {string}
* @memberof AppFormDRUIPart
*/
compRef: ComponentRef<any>;
constructor(private resolver: ComponentFactoryResolver,private $app:App) {
}
/**
* 表单数据
*
* @type {string}
* @memberof AppFormDRUIPart
*/
@Input() set data(newVal: any) {
if (newVal) {
this.currentdata = newVal;
if (this.ignorefieldvaluechange) {
return;
}
if (this.copydata) {
if (Object.is(JSON.stringify(newVal), JSON.stringify(this.copydata))) {
return;
}
const newFormData: any = JSON.parse(JSON.stringify(newVal));
const oldDormData: any = JSON.parse(JSON.stringify(this.copydata));
let refreshRefview = false;
this.hookItems.some((_hookItem: any) => {
if (!Object.is(newFormData[_hookItem], oldDormData[_hookItem])) {
refreshRefview = true;
return refreshRefview;
}
return refreshRefview;
});
if (refreshRefview) {
this.refreshDRUIPart();
}
}
this.copydata = newVal;
}
}
/**
* 关联视图
*
* @type {string}
* @memberof AppFormDRUIPart
*/
@Input() public viewname: string;
/**
* 刷新关系项
*
* @type {string}
* @memberof AppFormDRUIPart
*/
@Input() public refreshitems: string = "";
/**
* 关系视图类型
*
* @type {string}
* @memberof AppFormDRUIPart
*/
@Input() public refviewtype: string;
/**
* 父数据
*
* @type {*}
* @memberof AppFormDRUIPart
*/
@Input() public parentdata: any;
/**
* 是否忽略表单项值变化
*
* @type {boolean}
* @memberof AppFormDRUIPart
*/
@Input() public ignorefieldvaluechange: boolean;
/**
* 表单状态
*
* @type {Subject<any>}
* @memberof AppFormDRUIPart
*/
@Input() public formState!: Subject<any>
/**
* 触发DEMEDITVIEW9 关系数据保存完成事件
*
* @type {EventEmitter}
* @memberof AppFormDRUIPart
*/
@Output() public drdatasaved =new EventEmitter();
/**
* 表单状态事件
*
* @private
* @type {(Unsubscribable | undefined)}
* @memberof AppFormDRUIPart
*/
private formStateEvent: Unsubscribable | undefined;
/**
* 是否刷新关系数据
*
* @private
* @type {boolean}
* @memberof AppFormDRUIPart
*/
private isRelationalData: boolean = true;
/**
* 刷新节点
*
* @private
* @type {string[]}
* @memberof AppFormDRUIPart
*/
private hookItems: string[] = [];
/**
* 关系界面向视图下发指令对象
*
* @private
* @type {Subject<any>}
* @memberof AppFormDRUIPart
*/
private formDruipart: Subject<any> = new Subject<any>();
/**
* 父数据
*
* @type {*}
* @memberof AppFormDRUIPart
*/
public srfparentdata: any = {};
ngAfterContentInit(): void {
this.hookItems = [...this.refreshitems.split(';')];
if (!this.formState) {
return;
}
this.formStateEvent = this.formState.subscribe(($event: any) => {
// 表单加载完成
if (Object.is($event.type, 'load')) {
this.refreshDRUIPart();
}
// 表单保存之前
if (Object.is($event.type, 'beforesave')) {
if(Object.is(this.refviewtype,'DEMOBMEDITVIEW9')){
Object.assign($event.data,{end:true});
this.formDruipart.next({action:'save',data:$event.data});
}
}
// 表单保存完成
if (Object.is($event.type, 'save')) {
this.refreshDRUIPart();
}
// 表单项更新
if (Object.is($event.type, 'updateformitem')) {
if (!$event.data) {
return;
}
let refreshRefview = false;
Object.keys($event.data).some((name: string) => {
const index = this.hookItems.findIndex((_name: string) => Object.is(_name, name));
refreshRefview = index !== -1 ? true : false;
return refreshRefview;
});
if (refreshRefview) {
this.refreshDRUIPart();
}
}
});
this.refreshDRUIPart();
}
/**
* 刷新关系界面
*
* @type {*}
* @memberof AppFormDRUIPart
*/
public refreshDRUIPart() {
if (Object.is(this.parentdata.SRFPARENTTYPE, 'CUSTOM')) {
this.isRelationalData = false;
}
const formData: any = this.currentdata;
const srfkey = formData.srfkey;
this.srfparentdata = {};
Object.assign(this.srfparentdata, this.parentdata);
Object.assign(this.srfparentdata, { srfparentkey: srfkey });
if (this.isRelationalData) {
this.LoadComponent(this);
}
}
/**
* 加载组件
*
* @param {*} self
* @returns
* @memberof XtnDialog
*/
LoadComponent(self: any) {
let Params = {
Inputs: { viewdata: JSON.stringify({ srfparentdata: this.srfparentdata }),isembeddedView:true,formDruipart:this.formDruipart },
Outputs: {
mditemsload: ($event: any) => {
console.log('多数据视图加载完成,触发后续表单项更新');
},
drdatasaved: ($event: any) => {
this.drdatasaved.emit($event);
},
drdatachange: ($event: any) => {
console.log('DEMEDITVIEW9 关系数据值变化');
},
viewdataschange: ($event: any) => {
console.log('视图数据变化');
},
viewload: ($event: any) => {
console.log('视图加载完成');
}
}
};
let __Component;
let fact = self.resolver._factories;
// 根据名称,摸查出组件名称
fact.forEach((value: any, key: any) => {
if (key.name === this.viewname) {
__Component = key;
}
});
if (!__Component) {
return;
}
// 参数设置
if (!this.srfparentdata) {
return;
}
let inputProviders = Object.keys(Params).map((inputName) => {
return { provide: inputName, useValue: Params[inputName] };
});
let resolvedInputs = ReflectiveInjector.resolve(inputProviders);
let injector = ReflectiveInjector.fromResolvedProviders(resolvedInputs, this.container.parentInjector);
if (this.compRef) {
this.compRef.destroy();
}
let factory = this.resolver.resolveComponentFactory(__Component);
// 创建带参数的组件
this.compRef = factory.create(injector);
const { Outputs, Inputs } = Params;
const __self = this;
const { inputs, outputs } = factory;
// 向组件传递参数。
inputs.forEach((item) => {
const { propName, templateName } = item;
const inProps = Inputs[templateName];
// 给组件上的参数赋值操作。
if (inProps) {
__self.compRef.instance[propName] = Inputs[templateName];
}
});
// 向外输入参数,这里主要是判断事件处理。
outputs.forEach((row) => {
const { propName, templateName } = row;
const outProps = __self.compRef.instance[row.propName];
if (outProps as EventEmitter<any>) {
// 订阅事件处理
outProps.subscribe((data) => {
if (Outputs[templateName]) {
Outputs[templateName](data)
}
});
}
});
// 呈现组件的视图
this.container.insert(this.compRef.hostView);
}
ngOnDestroy(): void {
if (this.formStateEvent) {
this.formStateEvent.unsubscribe();
}
}
}
<ng-container *ngTemplateOutlet="template; context: { '$implicit': this.field}"></ng-container>
\ No newline at end of file
import { Component, OnInit, ContentChild, TemplateRef, Input } from '@angular/core';
@Component({
selector: 'app-form-item',
templateUrl: './app-form-item.component.html',
styleUrls: ['./app-form-item.component.scss'],
})
export class AppFormItemComponent implements OnInit {
@ContentChild(TemplateRef)
template: TemplateRef<any>;
/**
* 表单项控制器
*
*
*/
@Input() field: any;
constructor() { }
ngOnInit() {}
}
<ion-list class="app-form">
<ng-container *ngTemplateOutlet="template; context: { '$implicit': this.form}"></ng-container>
</ion-list>
\ No newline at end of file
import { Component, OnInit, Input, ContentChild, TemplateRef, AfterViewInit } from '@angular/core';
@Component({
selector: 'app-form',
templateUrl: './app-form.component.html',
styleUrls: ['./app-form.component.scss'],
})
export class AppFormComponent implements OnInit{
/**
* 表单数据对象
*
* @type {*}
* @memberof Form
*/
@Input() public form: any;
/**
* 表单名称
*
* @type {string}
*/
@Input() public name: string;
/**
* 内嵌视图
*/
@ContentChild(TemplateRef)
template: TemplateRef<any>;
constructor() { }
ngOnInit() {
}
}
<div [ngStyle]="{'height':height+'rem'}" class="container">
<div class="scorll" [ngStyle]="{'margin-top':marginTop}">
<ng-container *ngFor="let item of itemsArray">
<p [ngStyle]="{'height':height+'rem','line-height':height+'rem'}" class="singleItem" (click)="clickSingleItem(item)">
<span class="titleStyle">{{item?.type}}</span>
<span class="messageStyle">{{item?.message}}</span>
</p>
</ng-container>
</div>
</div>
\ No newline at end of file
:host{
.container{
overflow:hidden
}
.scorll{
position:relative;
transition:margin-top 2s
}
.singleItem{
margin:0 1rem
}
.titleStyle{
border: 1px solid #c21717;
color: #c21717;
border-radius: 0.3rem;
letter-spacing: 0.2rem;
font-size: 1rem;
padding: 0.2rem 0.3rem;
font-weight:bold;
}
.messageStyle{
padding-left: 1rem;
font-size: 1rem;
font-weight: bold;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
\ No newline at end of file
import { Component, OnInit, Input, OnDestroy, EventEmitter, Output, AfterViewInit } from '@angular/core';
@Component({
selector: 'app-horizontal-scroll',
templateUrl: './app-horizontal-scroll.component.html',
styleUrls: ['./app-horizontal-scroll.component.scss'],
})
export class AppHorizontalScroll implements AfterViewInit, OnDestroy {
/**
* 定时器ID
*/
intervalId: any;
/**
* 距离顶部距离
*/
marginTop: String;
/**
* 传入数组
*/
itemsArray: Array<any>;
/**
* 传入数组的长度
*/
itemsLength: number;
/**
* 传入列表数组
*/
@Input() set items(val: Array<any>) {
if (val && val.length >0) {
this.itemsArray = val;
this.itemsLength = val.length;
let i = 0;
let orginArray = JSON.parse(JSON.stringify(this.itemsArray));
this.intervalId = setInterval(() => {
this.marginTop = -this.height * i + 'rem';
i++;
this.itemsArray.push(orginArray[(i - 1) % this.itemsLength]);
}, 3000);
}
}
/**
* 滚动条内容区高度(以rem为单位,默认值:2)
*
* @type {*}
* @memberof IbizHorizontalScrollComponent
*/
@Input() height: any =2;
/**
* 点击事件
*
* @type {EventEmitter<any>}
* @memberof IBizHorizontalScroll
*/
@Output() itemClick:EventEmitter<any> =new EventEmitter<any>();
constructor() { }
ngAfterViewInit(): void {
}
/**
* 点击回调
*
* @param {*} data
* @memberof IBizHorizontalScroll
*/
public clickSingleItem(data:any){
this.itemClick.emit(data);
}
public ngOnDestroy() {
clearInterval(this.intervalId);
}
}
<ion-icon *ngIf="this.iconType === 1" [name]="icon"></ion-icon>
<ion-icon class="app-icon-src" *ngIf="this.iconType === 2" [src]="icon"></ion-icon>
<img class="app-icon-img" *ngIf="this.iconType === 3" [src]="icon">
<ion-icon *ngIf="this.iconType === 0 && isDefault" src="./assets/icon/default_img.svg"></ion-icon>
\ No newline at end of file
.app-icon-img {
width: 100%;
height: 100%;
}
ion-icon {
width: 100%;
height: 100%;
}
\ No newline at end of file
import { Component, Input } from '@angular/core';
import { AppFunc } from '../../interface/AppFunc';
@Component({
selector: 'app-icon',
templateUrl: 'app-icon.html',
styleUrls: ['app-icon.scss']
})
export class AppIcon {
/**
* 菜单项
*
* @memberof AppIcon
*/
@Input()
set item(val: AppFunc) {
if (val) {
if (val.iconcls && !Object.is(val.iconcls, '')) {
this.icon = val.iconcls;
this.iconType = 1;
} else if (val.icon && !Object.is(val.icon, '')) {
this.icon = val.icon;
if (val.icon.lastIndexOf('.svg') === (val.icon.length - 4)) {
this.iconType = 2;
} else {
this.iconType = 3;
}
}
}
}
/**
* ionic图标名称
*
* @memberof AppIcon
*/
@Input()
set iconName(val: string) {
if (val && !Object.is(val, '')) {
this.icon = val;
this.iconType = 1;
}
}
/**
* 图片路径
*
* @memberof AppIcon
*/
@Input()
set iconSrc(val: string) {
if (val && !Object.is(val, '')) {
this.icon = val;
if (this.icon.lastIndexOf('.svg') === (this.icon.length - 4)) {
this.iconType = 2;
} else {
this.iconType = 3;
}
}
}
/**
* 默认图标
*
* @type {string}
* @memberof AppIcon
*/
@Input()
defaultIcon: string = 'pricetags';
/**
* 当未输入时,是否显示默认图标
*
* @type {boolean}
* @memberof AppIcon
*/
@Input()
isDefault: boolean = false;
/**
* 图标展示模式
*
* @type {(0 | 1 | 2 | 3)} 0: 无图标, 1: ionic自带图标, 2: svg图片图标, 3: 指定路径图片图标
* @memberof AppIcon
*/
public iconType: 0 | 1 | 2 | 3 = 0;
/**
* 图标
*
* @type {string}
* @memberof AppIcon
*/
public icon: string;
}
\ No newline at end of file
<div class="head">{{title?title:null}}</div>
<ion-list class="app-mdctrl-list">
<ion-item *ngFor="let item of $items">
<div class="left-area">
<div class="title"> {{ item.srfmajortext }}</div>
<div class="content"> {{ item.content }}</div>
<button (click)="onClick(item)">{{ item.buttoncaption }}</button>
</div>
<ion-thumbnail>
<img [src]="(item.image && item.image[0] ?url+item.image[0].id :null)">
</ion-thumbnail>
</ion-item>
</ion-list>
\ No newline at end of file
.head{
font-size: 1.15rem;
font-weight: 540;
padding-left: 0.75rem;
padding-top: 0.5rem;
font-family: AncientWar;
}
.app-mdctrl-list {
background-color: #e2dfdf;
ion-item {
margin: 10px;
}
.left-area {
width: 60%;
line-height: 32px;
}
.title {
font-weight: bold;
}
.content {
font-size: 12px;
color: #958e8e;
}
button {
width: 100px;
height: 20px;
font-size: 12px;
color: white;
background-color: red;
border-radius: 2px;
}
ion-thumbnail {
width: 40%;
height: 100%;
padding-top: 10px;
}
img {
display: inline-block;
height: auto;
max-width: 100%;
}
}
\ No newline at end of file
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { AppEnvironment } from 'src/environments/AppEnvironment';
@Component({
selector: 'app-image-list',
templateUrl: './app-image-list.component.html',
styleUrls: ['./app-image-list.component.scss'],
})
export class AppImageListComponent implements OnInit {
public $items: any[] = [];
@Input() public title:string;
/**
* 基础路径
*/
url: String = AppEnvironment.BaseUrl + AppEnvironment.ExportFile +"/";
@Input()
set items(val: any[]) {
if (val && val instanceof Array) {
if (!Object.is(JSON.stringify(this.$items), JSON.stringify(val))) {
this.$items = val;
if(this.$items.length >0){
this.$items.forEach((item:any) =>{
item.image =JSON.parse(item.image);
})
}
}
}
}
@Output()
itemClick: EventEmitter<any> = new EventEmitter();
constructor() { }
ngOnInit() {}
public onClick(item: any): void {
this.itemClick.emit(item);
}
}
<input #fileUpload [hidden]="true" type="file" ng2FileSelect [uploader]="uploader" [multiple]="multiple" accept="image/*" />
<div class="app-image-upload-multiple">
<ion-item *ngIf="labelText" class="app-image-upload-title" lines="none">
<ion-label slot="start">
{{ labelText }}<span class="stars" *ngIf="allowEmpty">*</span>
</ion-label>
<span slot="end">
<ion-icon class="app-image-upload-button" [hidden]="disabled" name="images"
(click)="fileSelect()" color="primary"></ion-icon>
</span>
</ion-item>
<div class="app-image-upload-content">
<ion-grid>
<ion-row>
<ion-col size="3" *ngFor="let item of files; let i = index;">
<div class="image-item">
<div class="example">
<div class="image-item-delete">
<ion-icon [hidden]="disabled" name="close-circle" (click)="deleteFile(item.id, i)" color="primary"></ion-icon>
</div>
<img (click)="preview(i)" src="{{ url + item.id}}">
</div>
</div>
</ion-col>
</ion-row>
</ion-grid>
</div>
</div>
\ No newline at end of file
.app-image-upload-multiple {
width: 100%;
.app-image-upload-content {
flex-grow: 1;
overflow: hidden;
display: flex;
flex-wrap: wrap;
ion-grid {
padding: 0px;
}
.image-item {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.example {
flex: unset;
.image-item-delete {
float: right;
height: 22px;
margin-bottom: -15px;
margin-right: -8px;
font-size: 22px;
}
}
}
}
.app-image-upload-button {
font-size: 22pt;
display: flex;
justify-content: center;
align-self: center;
}
.app-image-upload-title {
--padding-start: 0px;
--inner-padding-end: 0px;
--min-height: 36px;
span {
font-size: 28px;
-webkit-margin-start: 0px;
margin-inline-start: 0px;
-webkit-margin-end: 0px;
margin-inline-end: 0px;
}
.stars {
font-size: var(--app-important-font-size);
margin-left: 3px;
}
}
}
\ No newline at end of file
import { Component, ViewChild, ElementRef, Input, OnInit, Output, EventEmitter } from '@angular/core';
import { ModalController } from '@ionic/angular';
import { FileUploader, FileItem, ParsedResponseHeaders, FileLikeObject } from 'ng2-file-upload';
import { AppEnvironment } from '../../../environments/AppEnvironment';
import { AppNotification } from '../../service/Notification';
import { Loading } from '../../service/Loading';
import { PicturePreview } from '../../helper/app-picture-preview/app-picture-preview';
import { App } from '@global/service/App';
@Component({
selector: 'app-image-upload',
templateUrl: './app-image-upload.html',
styleUrls: ['./app-image-upload.scss']
})
export class AppImageUpload implements OnInit {
/**
* 文件上传组件
*
* @type {FileUploader}
* @memberof IBizFileUpload
*/
public uploader: FileUploader;
/**
* 已上传文件
*
* @type {any[]}
* @memberof IBizFileUpload
*/
public files: any[] = [];
/**
* 上传或下载的地址
*
* @type {string}
* @memberof IBizFileUpload
*/
public url: string = '';
/**
* 限制文件上传个数
*
* @type {number}
* @memberof IBizFileUpload
*/
public fileCount: number;
/**
* 限制文件上传大小
*
* @private
* @type {number}
* @memberof IBizFileUpload
*/
private fileSize: number;
/**
* 是否启用
*
* @type {boolean}
* @memberof IBizDateTime
*/
@Input()
disabled: boolean = false;
/**
* 是否为单文件上传
*
* @type {boolean}
* @memberof IBizFileUpload
*/
@Input()
multiple: boolean = false;
/**
* 标签文本值
*
* @type {string}
* @memberof IBizFileUpload
*/
@Input()
labelText: string;
/**
* 是否必填
*
* @type {boolean}
* @memberof IBizTextarea
*/
@Input()
allowEmpty: boolean;
/**
* 编辑器参数
*
* @memberof IBizFileUpload
*/
@Input()
set params(val: any) {
if (val) {
const { filecount, filesize } = val;
if (filecount) {
this.fileCount = filecount;
}
if (filesize) {
this.fileSize = filesize;
}
}
}
/**
*
*
* @type {ElementRef}
* @memberof IBizFileUpload
*/
@ViewChild('fileUpload')
fileUpload: ElementRef;
/**
* 值
*
* @memberof IBizFileUpload
*/
@Input()
set value(value: any) {
if (value) {
this.files = [];
let val;
if (typeof (value) === 'string') {
try {
val = JSON.parse(value);
} catch (error) {
console.log(error);
}
} else {
val = value;
}
if (val instanceof Array) {
this.files = [...val];
}
}else{
this.files = [];
}
}
/**
*
*
* @type {EventEmitter<any>}
* @memberof IBizFileUpload
*/
@Output()
valueChange: EventEmitter<any> = new EventEmitter();
/**
*
* @param {notification} notification
* @param {IBizLoading} loading
* @memberof IBizFileUpload
*/
constructor(
private notification: AppNotification,
private loading: Loading,
private App: App,
private modalCtrl: ModalController) {
this.uploader = new FileUploader({ url: AppEnvironment.BaseUrl + AppEnvironment.UploadFile, autoUpload: true, headers: [{ name: 'Authorization', value: `Bearer ${this.App.getLoginKey()}` }] });
this.uploader.onSuccessItem = this.successItem.bind(this);
this.uploader.onErrorItem = this.errorItem.bind(this);
this.uploader.onBeforeUploadItem = this.beforeUploadItem.bind(this);
this.uploader._fileSizeFilter = this.fileSizeFilter.bind(this);
// 拼接上传或下载的url
this.url = AppEnvironment.BaseUrl + AppEnvironment.ExportFile + '/';
}
public ngOnInit() {
this.uploader.setOptions({
maxFileSize: this.fileSize
});
}
/**
* 验证文件大小
*
* @param {FileLikeObject} [item]
* @param {FileUploaderOptions} [options]
* @returns {boolean}
* @memberof IBizFileUpload
*/
public fileSizeFilter(item?: FileLikeObject): boolean {
if (item && this.fileSize && ((item.size / 1000) >= this.fileSize)) {
this.notification.warning(`文件大小不可超过${this.fileSize}kb`);
return false;
}
return true;
}
/**
* 文件选择
*
* @returns {*}
* @memberof IBizFileUpload
*/
public fileSelect(): any {
if (this.files.length > 0 && !this.multiple) {
} else {
this.fileUpload.nativeElement.click();
}
}
/**
* 预览图片
*
* @param {number} num
* @returns {*}
* @memberof AppImageUpload
*/
public async preview(num: number): Promise<void> {
const item = this.files[num];
const modal = await this.modalCtrl.create({
component: PicturePreview,
componentProps: { imageId: item.id }
});
await modal.present();
}
/**
* 删除文件
*
* @param {string} id
* @param {number} index
* @memberof IBizFileUpload
*/
public async deleteFile(id: string, index: number) {
const res = await this.notification.confirm('确认删除', '确认删除图片吗?');
if (res) {
if (this.files[index] && Object.is(this.files[index].id, id)) {
this.files.splice(index, 1);
this.valueChange.emit(JSON.stringify(this.files));
}
}
}
/**
* 打开新窗口进行文件下载
*
* @param {any} file
* @memberof FileUploadPickerComponent
*/
public async downloadFile(file) {
const res = await this.notification.confirm('下载', '确认下载文件吗?');
if (res) {
window.open(AppEnvironment.BaseUrl + AppEnvironment.ExportFile + `/${file.id}`, '_blank');
}
}
/**
*
*
* @param {FileItem} item
* @param {string} response
* @param {number} status
* @param {ParsedResponseHeaders} headers
* @memberof IBizFileUpload
*/
public async errorItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): Promise<any> {
await this.loading.unmask();
this.notification.error(`文件:${item.file.name},上传失败`);
}
/**
*
*
* @param {FileItem} fileItem
* @memberof IBizFileUpload
*/
public async beforeUploadItem(fileItem: FileItem): Promise<any> {
await this.loading.mask('文件上传中...');
}
/**
* 上传成功
*
* @param {FileItem} item
* @param {string} response
* @param {number} status
* @param {ParsedResponseHeaders} headers
* @returns {*}
* @memberof IBizFileUpload
*/
public async successItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): Promise<any> {
await this.loading.unmask();
if (this.fileCount && this.fileCount < this.files.length) {
return;
}
const res: any = JSON.parse(response);
if (res && res.id) {
this.files.push(res);
}
this.valueChange.emit(JSON.stringify(this.files));
}
}
<div class="card">
<div class="head">
<div class="bt">{{title?title:null}}</div>
</div>
<div class="content">
<div *ngFor="let item of items" class="item">
<img *ngIf="item.icon" src="{{item.icon?item.icon:null}}" alt="" (click)="handleClick(item)" onerror="this.src='./assets/icon/default_img.png'">
<div class="contentbt" (click)="handleClick(item)">
<div class="title">{{item.text}}</div>
<div class="subtitle">{{item.subtitle}}</div>
</div>
<div class="right" (click)="handleClick(item)">
<embed src="./assets/images/right.svg" type="image/svg+xml" class="righticon" (click)="handleClick(item)"/>
</div>
</div>
</div>
</div>
\ No newline at end of file
.card{
margin-bottom: 0.5rem;
.head{
display: flex;
padding-top: 0.9375rem;
padding-left: 0.3125rem;
.bt{
flex: 7;
padding-left: 0.8125rem;
font-size: 1.125rem;
font-weight: 540;
padding-left: 0.75rem;
padding-top: 0.5rem;
font-family: AncientWar;
}
.more{
flex: 1;
font-size: 0.875rem;
color: gray;
}
}
.content{
.item{
width: 100%;
height: 6.5625rem;
display: flex;
border-bottom: 0.0625rem solid lightgray;
margin-left: 0.8125rem;
position: relative;
>img{
flex: 1;
height: 4.0625rem;
margin-top: 1.1875rem;
}
.contentbt{
flex: 3;
position: relative;
.title{
position: absolute;
top: 1.9375rem;
left: 0.8125rem;
font-weight: bold;
}
.subtitle{
position: absolute;
top: 3.375rem;
left: 0.8125rem;
font-size: 0.8125rem;
color: gray;
}
}
.right{
width: 2.75rem;
height: 2.75rem;
background: #FFF6F1;
border-radius: 2.75rem;
position: absolute;
right: 1.75rem;
top: 1.625rem;
>.righticon{
width: 1.5625rem;
margin-left: 0.625rem;
margin-top: 0.5625rem;
}
}
}
}
}
\ No newline at end of file
import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core';
@Component({
selector: 'app-level-imgtext',
templateUrl: './app-level-imgtext.component.html',
styleUrls: ['./app-level-imgtext.component.scss'],
})
export class AppLevelImgtext implements OnInit {
/**
* 输入标题
*/
@Input() title:string;
/**
* 传入数组
*/
@Input() items:Array<any>;
/**
* 抛出数据
*/
@Output() menuClick:EventEmitter<any> =new EventEmitter<any>();
constructor() { }
ngOnInit() {}
public handleClick(item:any){
this.menuClick.emit(item);
}
}
<div class="hdlist">
<div class="head">{{title?title:null}}</div>
<div class="content">
<div *ngFor="let item of _messages" class="item">
<div class="image" (click)="handleClick(item)">
<img *ngIf="item.image &&item.image[0]" [ngStyle]="{'height': height}" [src]="(item.image && item.image[0] ? url+item.image[0].id :null)"
alt="" onerror="this.src='./assets/icon/default_img.png'">
</div>
<ng-container *ngIf="item.title">
<div class="title" (click)="handleClick(item)">
{{item.title}}
</div>
</ng-container>
</div>
</div>
</div>
\ No newline at end of file
.hdlist{
margin-bottom: 0.5rem;
.head{
font-size: 1.15rem;
font-weight: 540;
padding-left: 0.75rem;
padding-top: 0.5rem;
font-family: AncientWar;
}
.content{
width: 100%;
height: 12.5rem;
display: -webkit-box;
overflow-x: auto;
overflow-y: hidden;
padding-bottom: 0.625rem;
.item{
width: 12.5rem;
height: 100%;
position: relative;
.image{
width: 90%;
margin-left: 5%;
margin-top: 0%;
height: 90%;
img{
width: 100%;
height: 100%;
}
}
.title{
position: absolute;
bottom: 0.8125rem;
width: 100%;
background: black;
color: white;
height: 1.875rem;
line-height: 1.875rem;
text-align: center;
}
}
}
}
\ No newline at end of file
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { AppEnvironment } from 'src/environments/AppEnvironment';
@Component({
selector: 'app-levelslide-list',
templateUrl: './app-levelslide-list.component.html',
styleUrls: ['./app-levelslide-list.component.scss'],
})
export class AppLevelslideList implements OnInit {
@Input() height:string ="130pt";
/**
* 输入标题
*/
@Input() title:String;
/**
* 基础路径
*/
url: String = AppEnvironment.BaseUrl + AppEnvironment.ExportFile + "/";
public _messages:Array<any> =[];
/**
* 输入属性
*/
@Input() set messages(val:any){
if(val){
this._messages = JSON.parse(JSON.stringify(val));
if(this._messages.length >0){
this._messages.forEach((item:any) =>{
if(item.image){
item.image = JSON.parse(item.image);
}
})
}
}
}
/**
* 抛出数据
*/
@Output() itemClick: EventEmitter<any> = new EventEmitter<any>();
constructor() { }
ngOnInit() { }
public handleClick(item: any) {
this.itemClick.emit(item);
}
}
<div class="head">{{title?title:null}}</div>
<div class="hdlist">
<div *ngFor="let item of _messages" class="item">
<div class="image" (click)="handleClick(item)">
<img *ngIf="item.image &&item.image[0]&&item.image[0].id" [src]="(item.image && item.image[0] ?url+item.image[0].id :null)"
alt="" onerror="this.src='./assets/icon/default_img.png'">
</div>
<div class="title" (click)="handleClick(item)">
{{item.title}}
</div>
<div class="pricearea" (click)="handleClick(item)">
{{item.pricearea}}
</div>
</div>
</div>
\ No newline at end of file
.head{
font-size: 1.15rem;
font-weight: 540;
padding-left: 0.75rem;
padding-top: 0.5rem;
font-family: AncientWar;
}
.hdlist{
margin-bottom: 0.5rem;
width: 100%;
height: 12.5rem;
display: -webkit-box;
overflow-x: auto;
overflow-y: hidden;
padding-bottom: 1.0625rem;
.item{
width: 9.375rem;
height: 100%;
margin: 0.625rem;
position: relative;
.image{
width: 90%;
margin-left: 5%;
margin-top: 10%;
height: 62%;
img{
width: 100%;
height: 100%;
}
}
.title{
position: absolute;
bottom: 1.5rem;
width: 100%;
height: 1.875rem;
line-height: 1.875rem;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.pricearea{
position: absolute;
bottom: 0.1875rem;
width: 100%;
text-align: center;
color: #CF4959;
}
}
}
\ No newline at end of file
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { AppEnvironment } from 'src/environments/AppEnvironment';
@Component({
selector: 'app-levelslide-withprice-list',
templateUrl: './app-levelslide-withprice-list.component.html',
styleUrls: ['./app-levelslide-withprice-list.component.scss'],
})
export class AppLevelslideWithpriceList implements OnInit {
/**
* 基础路径
*/
url: String = AppEnvironment.BaseUrl + AppEnvironment.ExportFile +"/";
@Input() public title:string;
public _messages:Array<any> =[];
/**
* 输入属性
*/
@Input() set messages(val:any){
if(val){
this._messages = JSON.parse(JSON.stringify(val));
if(this._messages.length >0){
this._messages.forEach((item:any) =>{
if(item.image){
item.image = JSON.parse(item.image);
}
})
}
}
}
/**
* 抛出数据
*/
@Output() itemClick: EventEmitter<any> = new EventEmitter<any>();
constructor() { }
ngOnInit() { }
handleClick(item: any) {
this.itemClick.emit(item);
}
}
<ion-list class="app-list-menu">
<ng-container *ngFor="let item of items">
<ng-container *ngIf="item.text !== ''; else split;">
<ion-item href="javascript:;" lines="full" (click)="onClick(item)">
<ion-avatar slot="start">
<app-icon [item]="item" [isDefault]="true"></app-icon>
</ion-avatar>
<ion-label [ngClass]="item.textcls">
{{ item.text }}
</ion-label>
</ion-item>
</ng-container>
<ng-template #split>
<app-dividing-line></app-dividing-line>
</ng-template>
</ng-container>
<ion-item *ngIf="isCustom" lines="full" (click)="editMenus()">
<ion-avatar slot="start">
<ion-icon name="add" style="width: 100%;height: 100%;"></ion-icon>
</ion-avatar>
<ion-label>
添加功能
</ion-label>
</ion-item>
</ion-list>
\ No newline at end of file
.app-list-menu {
margin: 0px;
}
\ No newline at end of file
import { Component, Input, Output, EventEmitter } from '@angular/core';
/**
* 宫格菜单
*
* @export
* @class AppListMenu
*/
@Component({
selector: 'app-list-menu',
templateUrl: 'app-list-menu.html',
styleUrls: ['app-list-menu.scss']
})
export class AppListMenu {
/**
* 菜单数据
*
* @type {any[]}
* @memberof AppListMenu
*/
@Input()
items: any[] = [];
/**
* 应用功能选择视图
*
* @type {string}
* @memberof AppListMenu
*/
@Input()
appFuncPickupView: string;
/**
* 是否支持自定义
*
* @type {boolean}
* @memberof AppListMenu
*/
@Input()
isCustom: boolean = false;
/**
* 菜单点击事件
*
* @type {EventEmitter<string>}
* @memberof AppListMenu
*/
@Output()
menuClick: EventEmitter<string> = new EventEmitter();
/**
* 打开编辑视图
*
* @type {EventEmitter<string>}
* @memberof AppListMenu
*/
@Output()
openPickup: EventEmitter<string> = new EventEmitter();
/**
* 菜单点击
*
* @param {string} appFuncId
* @memberof AppListMenu
*/
public onClick(item:any): void {
this.menuClick.emit(item);
}
/**
* 编辑菜单项
*
* @memberof AppListMenu
*/
public editMenus(): void {
this.openPickup.emit(this.appFuncPickupView);
}
}
\ No newline at end of file
<ng-container *ngIf="loadMode == 1; else embeddedView;">
<div>
<ion-infinite-scroll [disabled]="!isInfinite" (ionInfinite)="onMore($event)">
<ion-infinite-scroll-content loadingSpinner="bubbles" loadingText="正在加载..."></ion-infinite-scroll-content>
</ion-infinite-scroll>
</div>
</ng-container>
<ng-template #embeddedView>
<ion-toolbar class="app-load-more" [hidden]="!isInfinite">
<ion-text [hidden]="isSendingRequest || !isInfinite" (click)="onMore($event)" color="primary">点击加载更多</ion-text>
<div [hidden]="!isSendingRequest">
<ion-spinner name="dots" color="primary"></ion-spinner>
</div>
<!-- <ion-text [hidden]="isInfinite" color="primary">我是有底线的!</ion-text> -->
</ion-toolbar>
</ng-template>
\ No newline at end of file
.app-load-more {
text-align: center;
}
\ No newline at end of file
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-load-more',
templateUrl: 'app-load-more.html',
styleUrls: ['app-load-more.scss']
})
export class AppLoadMore {
/**
* 是否为嵌入视图
*
* @type {boolean}
* @memberof AppLoadMore
*/
@Input()
isEmbeddedView: boolean = false;
/**
* 加载模式
*
* @type {(1 | 2)}
* @memberof AppLoadMore
*/
@Input()
loadMode: 1 | 2 = 1;
/**
* 是否还有更多数据
*
* @type {boolean}
* @memberof AppLoadMore
*/
@Input()
isInfinite: boolean = true;
/**
* 是否正在加载
*
* @type {boolean}
* @memberof AppLoadMore
*/
@Input()
isSendingRequest: boolean = false;
/**
* 加载更多
*
* @type {EventEmitter<any>}
* @memberof AppLoadMore
*/
@Output()
loadMore: EventEmitter<any> = new EventEmitter();
/**
* 触发加载更多
*
* @param {*} event
* @memberof AppLoadMore
*/
public onMore(event: any): void {
this.loadMore.emit(event);
}
}
\ No newline at end of file
<ion-card style="margin: 0;border-radius: 0;">
<ion-card-content style="padding:0;">
<ion-list>
<ion-item lines="inset" href="javascript:;" (click)="changeAppTheme()">
<ion-label>
<h2><span style="margin-right:5px;"><ion-icon name="switch"></ion-icon></span>更换主题</h2>
</ion-label>
</ion-item>
<ion-item lines="inset" href="javascript:;" (click)="logout()">
<ion-label>
<h2><span style="margin-right:5px;"><ion-icon name="power"></ion-icon></span>退出账户</h2>
</ion-label>
</ion-item>
<ion-item lines="inset" href="javascript:;">
<ion-label>
<h2><span style="margin-right:5px;"><ion-icon name="settings"></ion-icon></span>更多设置</h2>
</ion-label>
</ion-item>
</ion-list>
</ion-card-content>
</ion-card>
\ No newline at end of file
import { Component, OnInit } from '@angular/core';
import { AppThemeConfig } from 'src/theme/app-theme-config';
import { App } from '@global/service/App';
import { AppNotification } from '@global/service/Notification';
@Component({
selector: 'app-more-setting',
templateUrl: './app-more-setting.component.html',
styleUrls: ['./app-more-setting.component.scss'],
})
export class AppMoreSettingComponent implements OnInit {
constructor(private $app: App,private $notification:AppNotification) { }
ngOnInit() {
}
/**
*
* 更换主题
*/
public async changeAppTheme() {
let appTheme = localStorage.getItem('app-theme');
const result: string = await this.$app.openActionSheet({ items: AppThemeConfig });
if (!Object.is(result, appTheme)) {
localStorage.setItem('app-theme', result);
document.getElementsByTagName('html')[0].className = result;
}
}
/**
*
* 退出登录
*/
public async logout() {
const judge: boolean = await this.$notification.confirm('退出', '确认退出当前用户?');
if (judge) {
this.$app.clearAccess();
this.$app.login();
}
}
}
<div class="app-mpicker">
<ion-item *ngIf="labelText" class="app-mpicker-title" lines="none">
<label slot="start">
{{ labelText }}<span class="stars">*</span>
</label>
<span slot="end">
<ion-icon slot="end" [hidden]="disabled" class="app-mpicker-add" (click)="openMPicker()" name="add" color="primary"></ion-icon>
</span>
</ion-item>
<div class="app-mpicker-content">
<ion-chip *ngFor="let value of values;let i = index;" (click)="removeItem(i)">
<ion-label>{{ value.srfmajortext }}</ion-label>
<ion-icon name="close-circle" [hidden]="disabled"></ion-icon>
</ion-chip>
</div>
</div>
\ No newline at end of file
.app-mpicker {
--padding-start: 0px;
text-align: start;
.app-mpicker-title {
--padding-start: 0px;
--inner-padding-end: 0px;
--min-height: 36px;
margin-bottom: 3px;
span {
font-size: 28px;
-webkit-margin-start: 0px;
margin-inline-start: 0px;
-webkit-margin-end: 0px;
margin-inline-end: 0px;
}
.stars {
font-size: var(--app-important-font-size);
margin-left: 3px;
}
}
.app-mpicker-add {
margin-right: 6px;
display: flex;
flex-direction: column;
justify-content: center;
ion-icon {
font-size: 28px;
}
}
}
\ No newline at end of file
import { Component, Input, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
import { ModalController } from '@ionic/angular';
import { AppNotification } from '../../service/Notification';
@Component({
selector: 'app-mpicker',
templateUrl: './app-mpicker.html',
styleUrls: ['./app-mpicker.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => AppMPicker),
multi: true
}
]
})
export class AppMPicker implements ControlValueAccessor {
/**
* 表单
*
* @type {*}
* @memberof AppPicker
*/
@Input()
form: any;
/**
* 选择视图
*
* @type {*}
* @memberof AppPicker
*/
@Input()
component: any;
/**
* 是否启用
*
* @type {boolean}
* @memberof AppPicker
*/
@Input()
disabled: boolean;
/**
* 提示信息
*
* @type {string}
* @memberof AppPicker
*/
@Input()
placeholder: string;
/**
* 标签文本
*
* @type {string}
* @memberof IBizMPicker
*/
@Input()
labelText: string;
/**
* 是否必填
*
* @type {boolean}
* @memberof IBizTextarea
*/
@Input()
allowEmpty: boolean;
/**
* 值
*
* @type {any[]}
* @memberof IBizMPicker
*/
public values: any[] = [];
/**
* Creates an instance of AppPicker.
* @param {ModalController} modalCtrl
* @memberof AppPicker
*/
constructor(private modalCtrl: ModalController, private notification: AppNotification) { }
/**
* 打开选择视图
*
* @returns {Promise<any>}
* @memberof AppPicker
*/
public async openMPicker(): Promise<any> {
if (this.component) {
if (!this.form) {
return;
}
const modal = await this.modalCtrl.create({
component: this.component,
componentProps: { isModalMode: true, srfReferData: this.form, oldSelected: this.values }
});
await modal.present();
const result = await modal.onWillDismiss();
const res: any = result.data;
if (res && Object.is(res.ret, 'OK') && res.selected) {
if (res.selected.length > 0) {
const items: any[] = res.selected;
this.onChange(JSON.stringify(items));
this.values = items;
} else {
this.onChange(undefined);
this.values = [];
}
}
} else {
this.notification.error('未指定选择视图');
}
}
/**
* 删除
*
* @param {number} index
* @memberof IBizMPicker
*/
public removeItem(index: number): void {
if (this.disabled) {
return;
}
this.values.splice(index, 1);
this.onChange(JSON.stringify(this.values));
}
/**
* 输入
*
* @param {string[]} val
* @memberof AppPicker
*/
public writeValue(val: string[]): void {
if (val) {
if (val instanceof Array) {
this.values = val;
} else if (typeof(val) === 'string') {
try {
this.values = JSON.parse(val);
} catch (error) {
console.error(error);
}
}
}else{
this.values =[];
}
}
private onChange: (val: any) => void = () => { };
private onTouched: () => void = () => { };
public registerOnChange(fn: any): void { this.onChange = fn; }
public registerOnTouched(fn: any): void { this.onTouched = fn; }
}
\ No newline at end of file
<ion-select class="app-multiple-select" multiple=true slot="end" [disabled]="disabled" placeholder="请选择" cancelText="取消" okText="确定" [value]="value" (ionChange)="dataChange($event)" [selectedText]="selectedTexts">
<ion-select-option *ngFor="let item of items" [value]="item.value">{{item.text}}</ion-select-option>
</ion-select>
\ No newline at end of file
.app-multiple-select {
max-width: 100%;
padding: 6px;
}
\ No newline at end of file
import { Component, Input, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
import { CodeList } from '@global/service/codelist';
@Component({
selector: 'app-multiple-select',
templateUrl: './app-multiple-select.html',
styleUrls: ['./app-multiple-select.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => AppMultipleSelect),
multi: true
}
]
})
export class AppMultipleSelect implements ControlValueAccessor {
/**
* 全部数据对象集合
*
* @type {any[]}
* @memberof AppMultipleSelect
*/
items: any;
/**
* 选中数据值集合
*
* @private
* @type any
* @memberof AppMultipleSelect
*/
selectedItems: any[] = [];
/**
* 选中数据值
*
* @private
* @type any
* @memberof AppMultipleSelect
*/
public selectedValues: any;
/**
* 选中数据值
*
* @private
* @type any
* @memberof AppMultipleSelect
*/
public selectedTexts: any;
constructor(private $codelist: CodeList) {
}
/**
* 是否启用
*
* @type {boolean}
* @memberof AppMultipleSelect
*/
@Input()
disabled: boolean;
@Input()
set config(val: any) {
if (val) {
this.items = this.$codelist.getCodeItemByTag(val).items;
}
}
/**
* 提示信息
*
* @type {string}
* @memberof AppMultipleSelect
*/
@Input()
placeholder: string;
/**
* 模式的类型
*
* @type {string}
* @memberof AppMultipleSelect
*/
@Input()
orMode: string = 'str';
/**
* 数据存储分隔符
*
* @type {string}
* @memberof AppMultipleSelect
*/
@Input()
valueSeparator: string = ',';
/**
* 数据显示分隔符
*
* @type {string}
* @memberof AppMultipleSelect
*/
@Input()
textSeparator: string = ',';
/**
* 获取选择的实际值和文本值
*
* @param {any[]} arr
* @memberof AppMultipleSelect
*/
public getSelectedValues(arr: any[]) {
let num = 0;
let str = '';
let texts = '';
arr.forEach(val => {
const element = this.items.find(item => Object.is(item.value, val));
if (element) {
if (this.orMode === 'num') {
num = num | parseInt(val, 10);
} else {
if (str) {
str += this.valueSeparator;
}
str += element.value;
}
if (texts) {
texts += this.textSeparator;
}
texts += element.text;
}
});
this.selectedValues = this.orMode === 'num' ? (num !== 0 ? num.toString() : '') : str;
this.selectedTexts = texts;
}
/**
* 编辑器值
*
* @type {string}
* @memberof AppMultipleSelect
*/
set value(val: any) {
if (val && val instanceof Array && !Object.is(JSON.stringify(val), JSON.stringify(this.selectedItems))) {
this.selectedItems = val;
this.getSelectedValues(this.selectedItems);
}
}
get value() {
return this.selectedItems;
}
public dataChange($event) {
if(this.value !== $event.target.value){
this.value = $event.target.value;
this.onChange(this.selectedValues);
}
}
/**
* 输入
*
* @param {*} obj
* @memberof AppMultipleSelect
*/
public writeValue(obj: any): void {
if (obj) {
this.selectedValues = obj;
if (this.orMode === 'num') {
const temp = [];
this.items.forEach(val => {
// tslint:disable-next-line:no-bitwise
if ((obj & val.value) == val.value) {
temp.push(val.value);
}
});
this.value = temp;
} else {
this.value = obj.split(this.valueSeparator);
}
} else {
this.value = [];
}
}
private onTouched: () => void = () => { };
private onChange: (val: any) => void = () => { };
public registerOnChange(fn: any): void { this.onChange = fn; }
public registerOnTouched(fn: any): void { this.onTouched = fn; }
}
\ No newline at end of file
<div class="card">
<div class="head">{{title?title:null}}</div>
<div class="content">
<div class="bigimg">
<img *ngIf="_messages&&_messages[0]&&_messages[0].icon" src="{{(_messages && _messages[0])? _messages[0].icon:null}}" alt="" (click)="handleClick(item)" onerror="this.src='./assets/icon/default_img.png'">
</div>
<div class="ximg">
<ng-container *ngFor="let item of _messages;index as i">
<ng-container *ngIf="i>0 && i<=3">
<div class="item xcontent" (click)="handleClick(item)">
<div class="title" style="text-align: center;">{{item.text}}</div>
<div class="subtitle" style="text-align: center;">{{item.subtitle}}</div>
<div class="xiaoimg">
<img *ngIf="item.icon" src="{{item.icon?item.icon:null}}" alt="" onerror="this.src='./assets/icon/default_img.png'">
</div>
</div>
</ng-container>
</ng-container>
</div>
</div>
</div>
\ No newline at end of file
.card{
margin-bottom: 0.5rem;
.head{
font-size: 1.05rem;
padding-left: 0.75rem;
padding-top: 0.5rem;
}
.content{
padding-left: 0.75rem;
.bigimg{
width: 97%;
margin-top: 0.625rem;
height: 8.125rem;
>img{
width: 100%;
height: 100%;
}
}
.ximg{
display:flex;
width:100%;
.xcontent{
margin-top: 0.3125rem;
width:33%;
.item{
.title{
text-align: center;
font-size: 1.125rem;
font-weight: bold;
}
.subtitle{
text-align: center;
color: gray;
margin-top: 0.375rem;
font-size: 0.9375rem;
}
.xiaoimg{
margin-top: 0.75rem;
width: 100%;
height: 4.6875rem;
>img{
width: 100%;
height: 100%;
}
}
}
}
}
}
}
\ No newline at end of file
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-onebwiththrees-image',
templateUrl: './app-onebwiththrees-image.component.html',
styleUrls: ['./app-onebwiththrees-image.component.scss'],
})
export class AppOnebwiththreesImage implements OnInit {
/**
* 输入标题
*/
@Input() title:String;
public _messages:Array<any> =[];
/**
* 输入属性
*/
@Input() set messages(val:any){
if(val){
this._messages = JSON.parse(JSON.stringify(val));
}
}
/**
* 抛出数据
*/
@Output() menuClick: EventEmitter<any> = new EventEmitter<any>();
constructor() { }
ngOnInit() { }
handleClick(item: any) {
this.menuClick.emit(item);
}
}
<div class="head">{{title?title:null}}</div>
<div class="card-container">
<div *ngFor="let item of _messages;index as i" class="carditem">
<img *ngIf="item.icon" src="{{item.icon?item.icon:null}}" alt="" (click)="handleClick(item)"
onerror="this.src='./assets/icon/default_img.png'">
<div class="title" (click)="handleClick(item)">{{item.text}}</div>
<div class="subtitle" (click)="handleClick(item)">{{item.subtitle}}</div>
</div>
</div>
\ No newline at end of file
.head{
font-size: 1.15rem;
font-weight: 540;
padding-left: 0.75rem;
padding-top: 0.5rem;
font-family: AncientWar;
}
.card-container{
display: flex;
flex-wrap: wrap;
>.carditem{
width:48%;
margin-top: 0.625rem;
position: relative;
.title{
position: absolute;
top: 0.625rem;
left: 0.4375rem;
font-weight: bold;
font-size: 0.9375rem;
}
.subtitle{
position: absolute;
top: 2.25rem;
left: 0.4375rem;
font-size: 0.6875rem;
color: gray;
}
}
>.carditem:nth-of-type(2n){
margin-left:0.5rem;
}
}
\ No newline at end of file
import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core';
@Component({
selector: 'app-only-image',
templateUrl: './app-only-image.component.html',
styleUrls: ['./app-only-image.component.scss'],
})
export class AppOnlyImage implements OnInit {
public _messages:Array<any> =[];
@Input() public title:string;
/**
* 输入数组
*/
@Input() set items(val:any){
if(val){
this._messages = JSON.parse(JSON.stringify(val));
}
}
/**
* 抛出数据
*/
@Output() menuClick:EventEmitter<any> =new EventEmitter<any>();
constructor() { }
ngOnInit() {}
handleClick(item:any){
this.menuClick.emit(item);
}
}
<ion-card class="app-palace-menu" *ngFor="let item of items">
<ion-item lines="full">
<ion-label slot="start">{{ item.text }}</ion-label>
<a [hidden]="!item.items || (item.items.length <= 4)" class="app-palace-menu-a" href="javascript:;" slot="end" (click)="openChange(item)">{{ item.isOpen ? '收起' : '展开' }}</a>
</ion-item>
<ion-card-content>
<ion-grid>
<ion-row>
<ng-container *ngFor="let child of item.items;let i = index;">
<ion-col size="3" class="app-palace-menu-item" (click)="onClick(child)" [hidden]="!item.isOpen && (i > 3)">
<div class="icon">
<app-icon [item]="child" [isDefault]="true"></app-icon>
</div>
<div class="title {{ child.textcls }}">
{{ child.text }}
</div>
</ion-col>
</ng-container>
<ion-col *ngIf="isCustom" size="3" class="app-palace-menu-item" (tap)="editMenus()" [hidden]="(!item.isOpen || (item.items.length <= 4))">
<div class="icon">
<ion-icon name="add" style="width: 100%;height: 100%;"></ion-icon>
</div>
<div class="title">
添加功能
</div>
</ion-col>
</ion-row>
</ion-grid>
</ion-card-content>
</ion-card>
\ No newline at end of file
ion-card.app-palace-menu {
margin: 0px;
.app-palace-menu-a {
color: #e3e3e3;
font-size: 10pt;
}
.card-content {
padding: 0px;
// transition: max-height 2s linear 0s;
}
.app-palace-menu-item {
text-align: center;
.icon {
height: var(--app-palace-menu-icon-size, 30pt);
}
.title {
font-size: var(--app-palace-menu-title-size, 10pt);
}
}
}
// css 变量
/**
* --app-palace-menu-icon-size 图标大小
* --app-palace-menu-title-size 标题大小
**/
\ No newline at end of file
import { Component, Input, Output, EventEmitter } from '@angular/core';
/**
* 宫格菜单
*
* @export
* @class AppPalaceMenu
*/
@Component({
selector: 'app-palace-menu',
templateUrl: 'app-palace-menu.html',
styleUrls: ['app-palace-menu.scss']
})
export class AppPalaceMenu {
/**
* 菜单数据
*
* @type {any[]}
* @memberof AppPalaceMenu
*/
@Input()
items: any[] = [];
/**
* 应用功能选择视图
*
* @type {string}
* @memberof AppListMenu
*/
@Input()
appFuncPickupView: string;
/**
* 是否支持自定义
*
* @type {boolean}
* @memberof AppListMenu
*/
@Input()
isCustom: boolean = false;
/**
* 菜单点击事件
*
* @type {EventEmitter<string>}
* @memberof AppPalaceMenu
*/
@Output()
menuClick: EventEmitter<string> = new EventEmitter();
/**
* 打开编辑视图
*
* @type {EventEmitter<string>}
* @memberof AppListMenu
*/
@Output()
openPickup: EventEmitter<string> = new EventEmitter();
/**
* 菜单点击
*
* @param {string} appFuncId
* @memberof AppPalaceMenu
*/
public onClick(item: any): void {
this.menuClick.emit(item);
}
/**
* 展开状态改变
*
* @memberof AppPalaceMenu
*/
public openChange(item: any): void {
if (item.isOpen === true) {
item.isOpen = false;
} else {
item.isOpen = true;
}
}
/**
* 编辑菜单项
*
* @memberof AppListMenu
*/
public editMenus(): void {
this.openPickup.emit(this.appFuncPickupView);
}
}
\ No newline at end of file
<div class="app-picker">
<div class="app-picker-content" [ngClass]="{'disabled': disabled}">
{{ value }}
</div>
<div [hidden]="value && value !== '' || disabled" class="app-picker-add" (click)="openPicker()">
<ion-icon name="add" color="primary"></ion-icon>
</div>
<div [hidden]="!(value && value !== '') || disabled" class="app-picker-delete" (click)="clear()">
<ion-icon name="close" color="primary"></ion-icon>
</div>
</div>
\ No newline at end of file
.app-picker {
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
.app-picker-content {
flex-grow: 1;
display: flex;
justify-content: var(--app-form-editor-justify-content, flex-end);
}
.app-picker-add, .app-picker-delete {
margin-right: 6px;
display: flex;
flex-direction: column;
justify-content: center;
ion-icon {
font-size: 28px;
}
}
.disabled {
color: rgb(158, 158, 158);
}
}
\ No newline at end of file
import { Component, Input, forwardRef, Output, EventEmitter } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
import { ModalController } from '@ionic/angular';
import { AppNotification } from '../../service/Notification';
@Component({
selector: 'app-picker',
templateUrl: './app-picker.html',
styleUrls: ['./app-picker.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => AppPicker),
multi: true
}
]
})
export class AppPicker implements ControlValueAccessor {
/**
* 表单
*
* @type {*}
* @memberof AppPicker
*/
@Input()
form: any;
/**
* 选择视图
*
* @type {*}
* @memberof AppPicker
*/
@Input()
component: any;
/**
* 是否启用
*
* @type {boolean}
* @memberof AppPicker
*/
@Input()
disabled: boolean;
/**
* 选择id存储字段
*
* @type {*}
* @memberof AppPicker
*/
@Input()
valueItem: any;
@Output() valueItemChange =new EventEmitter();
/**
* 提示信息
*
* @type {string}
* @memberof AppPicker
*/
@Input()
placeholder: string;
/**
* 值
*
* @type {string}
* @memberof AppPicker
*/
public value: string;
/**
* Creates an instance of AppPicker.
* @param {ModalController} modalCtrl
* @memberof AppPicker
*/
constructor(private modalCtrl: ModalController, private notification: AppNotification) { }
/**
* 清空已选值
*
* @memberof AppPicker
*/
public clear(): void {
if (this.disabled) {
return;
}
if (this.valueItem) {
this.valueItem= undefined;
this.valueItemChange.emit(undefined);
}
this.onChange(undefined);
this.value = undefined;
}
/**
* 打开选择视图
*
* @returns {Promise<any>}
* @memberof AppPicker
*/
public async openPicker(): Promise<any> {
if (this.component) {
if (!this.form) {
return;
}
const modal = await this.modalCtrl.create({
component: this.component,
componentProps: { isModalMode: true, srfReferData: this.form }
});
await modal.present();
const result = await modal.onWillDismiss();
const res: any = result.data;
if (res && Object.is(res.ret, 'OK') && res.selected && res.selected.length >0) {
if (res.selected) {
const item = res.selected[res.selected.length-1];
this.valueItem = item.srfkey;
this.valueItemChange.emit(item.srfkey);
this.onChange(item.srfmajortext);
this.value = item.srfmajortext;
} else {
this.clear();
}
}
} else {
this.notification.error('未指定选择视图');
}
}
/**
* 输入
*
* @param {string} val
* @memberof AppPicker
*/
public writeValue(val: string): void {
this.value = val;
}
private onChange: (val: any) => void = () => { };
private onTouched: () => void = () => { };
public registerOnChange(fn: any): void { this.onChange = fn; }
public registerOnTouched(fn: any): void { this.onTouched = fn; }
}
\ No newline at end of file
<div class="app-radio">
<ng-container *ngFor="let item of items">
<div class="app-radio-item" [ngClass]="{'disabled': disabled}" (click)="selectChange(item.value)">
<span>{{ item.text }}</span>
<ion-icon [name]="item.value == value ? 'checkmark-circle' : 'radio-button-off'" color="primary"></ion-icon>
</div>
</ng-container>
</div>
\ No newline at end of file
.app-radio {
width: 100%;
display: flex;
.app-radio-item {
display: flex;
justify-content: var(--app-form-editor-justify-content, flex-end);
align-items: center;
height: 36px;
flex-grow: 1;
span {
padding-right: 6px;
}
}
.disabled {
color: rgb(158, 158, 158);
}
}
\ No newline at end of file
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { CodeList } from '@global/service/codelist';
@Component({
selector: 'app-radio',
templateUrl: 'app-radio.html',
styleUrls: ['app-radio.scss']
})
export class AppRadio{
/**
* 代码表集合
*/
public items:any;
constructor(private $codelist:CodeList){
}
/**
* 是否禁用
*
* @type {boolean}
* @memberof AppRadio
*/
@Input()
disabled: boolean = false;
/**
* 代码表
*
* @type {*}
* @memberof AppRadio
*/
@Input() set config(val:any){
if(val){
this.items = this.$codelist.getCodeItemByTag(val).items;
}
}
/**
* 输入值
*
* @type {string}
* @memberof AppRadio
*/
@Input()
value: string;
/**
* 值改变
*
* @type {EventEmitter<any>}
* @memberof AppRadio
*/
@Output()
valueChange: EventEmitter<any> = new EventEmitter();
/**
* 选中项值
*
* @param {string} val
* @memberof AppRadio
*/
public selectChange(val: string) {
if (this.disabled) {
return;
}
this.valueChange.emit(val);
}
}
\ No newline at end of file
<div>
<div class="head">{{title?title:null}}</div>
<ion-slides class="app-slide-menu" pager="true" #IonSlides>
<ng-container *ngFor="let item of $items;let i = index;">
<ion-slide *ngIf="i < 10">
<img [src]="url + (item.image && item.image[0] ? item.image[0].id : '')" [ngStyle]="{'height': height}"
(click)="onClick(item)" onerror="this.src='./assets/icon/default_img.png'">
</ion-slide>
</ng-container>
</ion-slides>
</div>
\ No newline at end of file
.head{
font-size: 1.15rem;
font-weight: 540;
padding-left: 0.75rem;
padding-top: 0.5rem;
font-family: AncientWar;
}
\ No newline at end of file
import { Component, Input, Output, EventEmitter, ViewChild, AfterViewInit } from '@angular/core';
import { AppEnvironment } from 'src/environments/AppEnvironment';
@Component({
selector: 'app-rotation-chart',
templateUrl: 'app-rotation-chart.html',
styleUrls: ['app-rotation-chart.scss']
})
export class AppRotationChart implements AfterViewInit {
@ViewChild('IonSlides')
ionSlides;
/**
*
*
* @type {any[]}
* @memberof AppRotationChart
*/
@Input()
set items(val: any[]) {
if (val && val instanceof Array) {
if (!Object.is(JSON.stringify(this.$items), JSON.stringify(val))) {
if(val.length >0){
val.forEach((item:any) =>{
if(item && item.image){
item.image = JSON.parse(item.image);
}
});
}
this.$items = val;
if (this.ionSlides) {
this.ionSlides.update();
this.ionSlides.startAutoplay();
}
}
}
}
@Input()
height: string = '130pt';
/**
* 点击
*
* @type {EventEmitter<any>}
* @memberof AppRotationChart
*/
@Output()
itemClick: EventEmitter<any> = new EventEmitter();
/**
*
*
* @type {any[]}
* @memberof AppRotationChart
*/
public $items: any[] = [];
/**
* 平台图片获取路径
*
* @type {string}
* @memberof AppRotationChart
*/
public url: string;
/**
* Creates an instance of AppRotationChart.
* @memberof AppRotationChart
*/
constructor() {
this.url = AppEnvironment.BaseUrl + AppEnvironment.ExportFile + '/';
}
@Input() public title:string;
/**
* 视图初始化完毕
*
* @memberof AppRotationChart
*/
public ngAfterViewInit(): void {
this.ionSlides.startAutoplay();
}
/**
* 点击
*
* @param {*} item
* @memberof AppRotationChart
*/
public onClick(item: any): void {
this.itemClick.emit(item);
}
}
\ No newline at end of file
<div [class]="'app-scroll-paging-' + position">
<div [class]="classStr" #AppScrollPaging>
<div *ngFor="let item of items;let i = index;" [id]="item.id" [class]="'paging-item ' + position" (click)="activePaging(i, item.id)" [ngClass]="{'active': item.id === active}">
<div *ngIf="!template" class="paging-item-content">
<span>{{ item.text }}</span><ion-badge *ngIf="item.counter" class="badge" color="primary">{{ item.counter }}</ion-badge>
</div>
<ng-container *ngTemplateOutlet="template; context: { '$implicit': item }"></ng-container>
</div>
</div>
<ion-content style="height: calc(100vh - 36px);" class="app-scroll-paging-content">
<ng-content></ng-content>
</ion-content>
</div>
\ No newline at end of file
.app-scroll-paging {
height: 100%;
// 颜色变量
// 激活时展示颜色
--app-scroll-paging-active-color: var(--ion-color-primary);
.app-scroll-paging-content {
height: 100%;
overflow-y: auto;
overflow-x: hidden;
}
::-webkit-scrollbar {
background: transparent;
width: 0;
height: 0;
}
::-webkit-scrollbar-thumb {
border-radius: 0;
box-shadow: none;
border: 0;
background-color: #cecece;
}
::-webkit-scrollbar-track {
border-radius: 0;
box-shadow: none;
border: 0;
}
}
.paging-item-content {
.badge {
margin-top: -6px;
margin-left: 22px;
position: absolute;
}
}
.app-scroll-paging-top {
@extend .app-scroll-paging;
.app-scroll-paging-tab.top,
.app-scroll-paging-tab.bottom {
white-space: nowrap;
overflow: auto;
width: 100%;
height: 36px;
scroll-behavior: smooth;
.paging-item {
display: inline-flex;
.paging-item-content {
display: inline-flex;
height: 100%;
padding: 8px 12px;
}
}
.active {
color: var(--app-scroll-paging-active-color, #3880ff);
border-bottom: 3px solid var(--app-scroll-paging-active-color, #3880ff);
}
}
.move {
display: flex;
.paging-item {
display: flex !important;
flex-grow: 1;
justify-content: center;
}
}
.app-scroll-paging-content {
height: calc(100% - 36px);
overflow-y: auto;
overflow-x: hidden;
}
}
.app-scroll-paging-left {
@extend .app-scroll-paging;
display: flex;
.app-scroll-paging-tab.left,
.app-scroll-paging-tab.right {
overflow-y: auto;
overflow-x: hidden;
width: 6rem;
height: 100%;
scroll-behavior: smooth;
background-color: #e3e3e3;
.paging-item {
width: 100%;
height: 60px;
display: flex;
justify-content: center;
align-items: center;
.paging-item-content {
padding: 0px 3px 0px 12px;
width: 100%;
}
}
.active {
background-color: var(--app-scroll-paging-active-background-color, white);
border-left: 3px solid var(--app-dominant-color);
// .paging-item-content {
// border-left: 5px solid var(--app-dominant-color);
// }
}
}
.app-scroll-paging-content {
width: calc(100% - 6rem);
overflow-y: auto;
overflow-x: hidden;
}
}
.app-scroll-paging-right {
@extend .app-scroll-paging-left;
flex-direction: row-reverse;
.active {
.paging-item-content {
border-left: 0px !important;
border-right: 5px solid var(--app-dominant-color);
}
}
}
.app-scroll-paging-bottom {
@extend .app-scroll-paging-top;
display: flex;
height: 100%;
flex-direction: column-reverse;
position: fixed;
bottom: 0;
background: #fff;
width: 100%;
.app-scroll-paging-tab.top,
.app-scroll-paging-tab.bottom {
.active {
color: var(--app-scroll-paging-active-color, #0cd1e8);
border-bottom: 0px;
border-top: 3px solid var(--app-scroll-paging-active-color, #0cd1e8);
}
}
.app-scroll-paging-content {
height: calc(100% - 36px);
overflow-y: auto;
overflow-x: hidden;
}
}
\ No newline at end of file
import { Component, Input, Output, ViewChild, ViewContainerRef, EventEmitter, OnInit, ContentChild, TemplateRef, AfterViewInit } from '@angular/core';
/**
* 分页导航部件
*
* @export
* @class AppScrollPaging
* @implements {OnInit}
* @implements {AfterViewInit}
*/
@Component({
selector: 'app-scroll-paging',
templateUrl: 'app-scroll-paging.html',
styleUrls: ['app-scroll-paging.scss']
})
export class AppScrollPaging implements OnInit, AfterViewInit {
@ContentChild('pagingItemContent', { read: TemplateRef })
template: TemplateRef<any>;
/**
* 容器
*
* @type {ViewContainerRef}
* @memberof AppScrollPaging
*/
@ViewChild('AppScrollPaging', { read: ViewContainerRef })
container: ViewContainerRef;
/**
* 分页
*
* @type {({id: string, text: string}[] | any[])}
* @memberof AppScrollPaging
*/
@Input()
items: { id: string, text: string, counter?: number }[] | any[] = [];
/**
* 激活分页
*
* @type {string}
* @memberof AppScrollPaging
*/
@Input()
active: string;
/**
* 展示位置
*
* @type {('top' | 'left' | 'bottom' | 'right')}
* @memberof AppScrollPaging
*/
@Input()
position: 'top' | 'left' | 'bottom' | 'right' = 'top';
/**
* 选中分页改变
*
* @type {EventEmitter<{index: number, id: string}>}
* @memberof AppScrollPaging
*/
@Output()
activeChange: EventEmitter<{ index: number, id: string }> = new EventEmitter();
private pagingDoms: HTMLCollectionOf<HTMLDivElement>;
private element: HTMLDivElement;
public classStr: string = '';
/**
* Creates an instance of AppScrollPaging.
* @memberof AppScrollPaging
*/
constructor() { }
public ngOnInit(): void {
if (!this.active && this.items.length > 0) {
this.active = this.items[0].id;
}
this.classStr = `app-scroll-paging-tab ${this.position} ${(this.items.length < 5) ? 'move' : ''}`;
}
public ngAfterViewInit(): void {
if (this.container && this.container.element && this.container.element.nativeElement) {
this.element = this.container.element.nativeElement;
this.pagingDoms = this.element.getElementsByTagName('div');
}
}
/**
* 激活分页
*
* @param {number} index
* @param {string} id
* @memberof AppScrollPaging
*/
public activePaging(index: number, id: string): void {
this.active = id;
this.activeScrollInto(id);
this.activeChange.emit({ index, id });
}
/**
* 改变选中
*
* @private
* @param {string} id
* @memberof AppScrollPaging
*/
private activeScrollInto(id: string): void {
if (this.container && this.container.element && this.container.element.nativeElement) {
for (let i: number = 0; i < this.pagingDoms.length; i++) {
const item = this.pagingDoms.item(i);
if (Object.is(item.id, id)) {
if (Object.is(this.position, 'top') || Object.is(this.position, 'bottom')) {
const scrollLeft: number = Math.floor(item.offsetLeft - (this.element.clientWidth / 2) + (item.clientWidth / 2));
this.element.scrollTo(scrollLeft, 0);
} else {
const scrollTop: number = Math.floor(item.offsetTop - (this.element.clientHeight / 2) + (item.clientHeight / 2));
this.element.scrollTo(0, scrollTop);
}
break;
}
}
}
}
}
\ No newline at end of file
<ion-select class="app-select" [placeholder]="placeholder" cancelText="取消" okText="确定" [disabled]="disabled" [(ngModel)]="selectValue"
[selectedText]="getSelectText(items, value)">
<ion-select-option *ngFor="let item of items" [value]="item.value">{{item.text}}</ion-select-option>
</ion-select>
\ No newline at end of file
.app-select {
max-width: 100%;
padding: 6px;
}
\ No newline at end of file
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { CodeList } from '@global/service/codelist';
@Component({
selector: 'app-select',
templateUrl: './app-select.html',
styleUrls: ['./app-select.scss']
})
export class AppSelect {
/**
* 代码表
*/
public items:any;
constructor(private $codelist:CodeList){
}
/**
* 编辑器值
*
* @type {string}
* @memberof AppSelect
*/
@Input()
public value: string;
@Output()
public valueChange: EventEmitter<any> = new EventEmitter();
/**
* 是否启用
*
* @type {boolean}
* @memberof AppSelect
*/
@Input()
disabled: boolean;
/**
* 提示信息
*
* @type {string}
* @memberof AppSelect
*/
@Input()
placeholder: string;
/**
* 选中值
*
* @type {*}
* @memberof AppSelect
*/
@Input()
set config(val:any){
if(val){
this.items =this.$codelist.getCodeItemByTag(val).items;
}
}
/**
* 选中值
*
* @memberof AppSelect
*/
set selectValue(val: any) {
this.valueChange.emit(val);
}
get selectValue() {
return this.value;
}
/**
* 获取选择文本值
*
* @param {*} detail
* @memberof AppSelect
*/
public getSelectText(items: any[], value): string {
if (items && items.length > 0) {
const element = items.find(item => Object.is(item.value, value+''));
if (element) {
return element.text;
}
}
}
}
\ No newline at end of file
<div class="shrinkable-grouping-list">
<div class="list-group" *ngFor="let item of items">
<ion-card class="list-card">
<ion-card-header class="list-card-header">
<div class="list-group-container">
<ion-item lines="none">
<ion-label>{{item.name}}</ion-label>
<span *ngIf="item.items && item.items.length > 6" class="shrink-button"
[ngClass]="{'open': item.isOpen}" slot="end" (click)="openChange(item)">全部<ion-icon
src="./assets/icon/solid-arrow-left.svg"></ion-icon></span>
</ion-item>
</div>
</ion-card-header>
<ion-card-content class="list-card-content">
<ng-container *ngIf="item.items">
<ion-grid class="list-group-content">
<ion-row [ngClass]="{'open': item.isOpen}">
<ng-container *ngFor="let child of item.items;let i = index;">
<ion-col size="4" *ngIf="(i < 6) || item.isOpen" (click)="onClick(child)">
<div class="list-item">
{{child.srfmajortext}}
</div>
</ion-col>
</ng-container>
</ion-row>
</ion-grid>
</ng-container>
</ion-card-content>
</ion-card>
</div>
</div>
\ No newline at end of file
.shrinkable-grouping-list {
.list-group {
.list-group-container {
.shrink-button {
font-size: 0.75rem;
color: rgb(136, 136, 148);
display: flex;
align-items: center;
ion-icon {
margin-left: 2px;
transition: all 0.3s;
}
}
.open {
ion-icon {
transform: rotate(-90deg)
}
}
}
.list-group-content {
padding: 0px 8px;
ion-col {
padding: 5px;
}
.list-item {
padding: 8px;
border: 1px solid rgb(229, 229, 230);
color: rgb(136, 136, 148);
text-align: center;
font-size: 0.5rem;
width: 100%;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
}
}
}
.list-card{
margin: 0 0 5px 0;
border-radius: 0px;
.list-card-header{
padding: 0;
}
.list-card-content{
padding: 0;
}
}
\ No newline at end of file
import { Component, Input, Output, EventEmitter } from '@angular/core';
/**
* 分组可收缩列表
*
* @export
* @class AppShrinkableGroupingList
*/
@Component({
selector: 'app-shrinkable-grouping-list',
templateUrl: 'app-shrinkable-grouping-list.html',
styleUrls: ['app-shrinkable-grouping-list.scss']
})
export class AppShrinkableGroupingList {
/**
* 列表信息
*
* @type {any[]}
* @memberof AppShrinkableGroupingList
*/
@Input()
items: any[];
/**
* 列表项点击
*
* @type {EventEmitter<any>}
* @memberof AppShrinkableGroupingList
*/
@Output()
itemClick: EventEmitter<any> = new EventEmitter();
/**
* 列表点击
*
* @param {*} item
* @memberof AppShrinkableGroupingList
*/
public onClick(item: any): void {
this.itemClick.emit(item);
}
/**
* 改变展示全部功能
*
* @param {*} item
* @memberof AppShrinkableGroupingList
*/
public openChange(item: any): void {
item.isOpen = !item.isOpen;
}
}
\ No newline at end of file
<ion-slides class="app-slide-menu" pager="true">
<ion-slide *ngFor="let item of $items;let i = index;">
<ion-grid class="app-slide-menu-grid">
<ion-row class="app-slide-menu-row">
<ion-col *ngFor="let child of item.items;let i = index;" size="3" class="app-slide-menu-item" (click)="onClick(child)">
<div class="icon">
<app-icon [item]="child" [isDefault]="true"></app-icon>
</div>
<div class="title {{ child.textcls }}">
{{ child.text }}
</div>
</ion-col>
<ng-container *ngIf="$items.length === (i + 1) && isCustom">
<ion-col size="3" class="app-slide-menu-item" (tap)="editMenus()">
<div class="icon">
<ion-icon name="add" style="width: 100%;height: 100%;"></ion-icon>
</div>
<div class="title">
添加功能
</div>
</ion-col>
</ng-container>
</ion-row>
</ion-grid>
</ion-slide>
</ion-slides>
\ No newline at end of file
ion-slides.app-slide-menu {
margin: 0px;
.app-slide-menu-grid {
width: 100%;
}
.app-slide-menu-item {
text-align: center;
.icon {
height: var(--app-palace-menu-icon-size, 30pt);
}
.title {
font-size: var(--app-slide-menu-title-size, 10pt);
}
}
}
// css 变量
/**
* --app-slide-menu-icon-size 图标大小
* --app-slide-menu-title-size 标题大小
**/
\ No newline at end of file
import { Component, Input, Output, EventEmitter } from '@angular/core';
/**
* 滑动菜单菜单
*
* @export
* @class AppSlideMenu
*/
@Component({
selector: 'app-slide-menu',
templateUrl: 'app-slide-menu.html',
styleUrls: ['app-slide-menu.scss']
})
export class AppSlideMenu {
/**
* 菜单数据
*
* @type {any[]}
* @memberof AppSlideMenu
*/
@Input()
set items(arr: any[]) {
this.$items = [];
if (arr && arr instanceof Array && arr.length > 0) {
const num: number = Math.floor(arr.length / 8);
const dataArr: any[] = [...arr];
for (let i: number = 0; i <= num; i++) {
this.$items.push({ items: dataArr.splice(0, 8)});
}
}
}
/**
* 应用功能选择视图
*
* @type {string}
* @memberof AppListMenu
*/
@Input()
appFuncPickupView: string;
/**
* 是否支持自定义
*
* @type {boolean}
* @memberof AppListMenu
*/
@Input()
isCustom: boolean = false;
/**
* 菜单点击事件
*
* @type {EventEmitter<string>}
* @memberof AppSlideMenu
*/
@Output()
menuClick: EventEmitter<string> = new EventEmitter();
/**
* 打开编辑视图
*
* @type {EventEmitter<string>}
* @memberof AppListMenu
*/
@Output()
openPickup: EventEmitter<string> = new EventEmitter();
/**
* 菜单数据
*
* @type {any[]}
* @memberof AppSlideMenu
*/
public $items: any[] = [];
/**
* 菜单点击
*
* @param {string} appFuncId
* @memberof AppSlideMenu
*/
public onClick(item: any): void {
this.menuClick.emit(item);
}
/**
* 编辑菜单项
*
* @memberof AppListMenu
*/
public editMenus(): void {
this.openPickup.emit(this.appFuncPickupView);
}
}
\ No newline at end of file
<Stepper class="app-stepper" [(ngModel)]="stepperValue" [disabled]="disabled" [min]="0" [showNumber]="true"></Stepper>
\ No newline at end of file
:host {
::ng-deep .am-stepper.showNumber {
min-width: 120px;
}
::ng-deep .am-stepper-input {
border: 1px solid #ddd;
height: 28px;
line-height: 28px;
}
::ng-deep .am-stepper-handler{
border: none !important;
}
}
\ No newline at end of file
import { Component, Input, Output, EventEmitter } from '@angular/core';
/**
* 步进器
*
* @export
* @class AppStepper
*/
@Component({
selector: 'app-stepper',
templateUrl: './app-stepper.html',
styleUrls: ['./app-stepper.scss']
})
export class AppStepper {
/**
* 输入值
*
* @memberof AppStepper
*/
@Input()
set value(val: any) {
if (val !== undefined) {
if (typeof(val) === 'string' && !Object.is(val, '')) {
try {
this.$value = parseInt(val, 10);
} catch (error) {
console.error(error);
}
} else {
this.$value = val;
}
}
}
@Output()
valueChange: EventEmitter<number> = new EventEmitter();
/**
* 是否启用
*
* @type {boolean}
* @memberof AppStepper
*/
@Input()
disabled: boolean;
/**
*
*
* @private
* @type {number}
* @memberof AppStepper
*/
private $value: number = 0;
set stepperValue(val: number) {
this.$value = val;
this.valueChange.emit(this.$value);
}
get stepperValue(): number {
return this.$value;
}
}
\ No newline at end of file
<div class="head">{{title?title:null}}</div>
<div class="list">
<div *ngFor="let item of _items" class="listitem">
<div class="image" (click)="handleClick(item)">
<img *ngIf="item.image&&item.image[0]&&item.image[0].id" [src]="(item.image && item.image[0] ? url+item.image[0].id :null)" alt="" onerror="this.src='./assets/icon/default_img.png'">
</div>
<div class="title" style="-webkit-box-orient: vertical;" (click)="handleClick(item)">
{{item.title}}
</div>
<div class="pricearea" (click)="handleClick(item)">
{{item.pricearea}}
</div>
</div>
</div>
\ No newline at end of file
.head{
font-size: 1.15rem;
font-weight: 540;
padding-left: 0.75rem;
padding-top: 0.5rem;
font-family: AncientWar;
}
.list{
margin-bottom: 0.5rem;
display: flex;
flex-wrap: wrap;
margin: 0.4375rem 0.25rem;
border:0.0625rem solid lightgray;
.listitem:nth-of-type(odd){
border-right:0.0625rem solid lightgray;
}
.listitem{
width: 50%;
border-bottom:0.0625rem solid lightgray;
.image{
width: 90%;
height: 56%;
margin-left: 5%;
margin-top: 3%;
>img{
width:100%;
height:100%;
}
}
.title{
color: #2E2D35;
padding: 0 0.4375rem;
font-size: 0.875rem;
margin-top: 0.6875rem;
height: 2.25rem;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
}
.pricearea{
margin-top: 0.75rem;
font-weight: bold;
padding: 0 0.4375rem;
}
}
.listitem:nth-last-child(1),.listitem:nth-last-child(2){
border-bottom:none;
}
}
\ No newline at end of file
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { AppEnvironment } from 'src/environments/AppEnvironment';
@Component({
selector: 'app-storestyle-list',
templateUrl: './app-storestyle-list.component.html',
styleUrls: ['./app-storestyle-list.component.scss'],
})
export class AppStorestyleList implements OnInit {
@Input() title: String;
/**
* 基础路径
*/
url: String = AppEnvironment.BaseUrl + AppEnvironment.ExportFile + '/';
public _items: Array<any> = [];
/**
* 输入数组
*/
@Input() set items(val: any) {
if (val) {
this._items = JSON.parse(JSON.stringify(val));
if (this._items.length > 0) {
this._items.forEach((item: any) => {
if (item && item.image) {
item.image = JSON.parse(item.image);
}
})
}
}
}
/**
* 抛出数据
*/
@Output() itemClick: EventEmitter<any> = new EventEmitter<any>();
constructor() { }
ngOnInit() { }
handleClick(item: any) {
this.itemClick.emit(item);
}
}
<ion-item *ngIf="labelText && position === 'TOP'" class="app-textarea-title" lines="none">
<label class="app-form-item-label"><app-icon *ngIf="(iconName || iconSrc)" [iconName]="iconName" [iconSrc]="iconSrc"></app-icon>{{ labelText }}<span class="stars" *ngIf="allowEmpty">*</span></label>
</ion-item>
<ion-textarea [ngStyle]="{'height': height}" [placeholder]="placeholder" [(ngModel)]="inputValue" [disabled]="disabled"></ion-textarea>
\ No newline at end of file
:host.app-textarea {
width: 100%;
.app-textarea-title {
--padding-start: 0px;
--inner-padding-end: 0px;
--min-height: 36px;
span {
font-size: 28px;
-webkit-margin-start: 0px;
margin-inline-start: 0px;
-webkit-margin-end: 0px;
margin-inline-end: 0px;
}
.stars {
font-size: var(--app-important-font-size);
margin-left: 3px;
}
}
ion-textarea {
--padding-top: 3px;
--padding-end: 6px;
--padding-bottom: 6px;
}
}
\ No newline at end of file
import { Component, Input, Output, EventEmitter, HostBinding } from '@angular/core';
@Component({
selector: 'app-textarea',
templateUrl: 'app-textarea.html',
styleUrls: ['app-textarea.scss'],
})
export class AppTextarea {
/**
* 输入值
*
* @type {string}
* @memberof AppTextarea
*/
@Input()
value: string;
@Output()
valueChange: EventEmitter<any> = new EventEmitter();
/**
* input值
*
* @memberof AppTextarea
*/
set inputValue(val: any) {
this.valueChange.emit(val);
}
get inputValue() {
return this.value;
}
/**
* 是否启用
*
* @type {boolean}
* @memberof AppTextarea
*/
@Input()
disabled: boolean = false;
/**
* 输入提示
*
* @type {string}
* @memberof AppTextarea
*/
@Input()
placeholder: string;
/**
* 标签展示位置
*
* @type {('LEFT' | 'TOP' | 'RIGHT' | 'BOTTOM')}
* @memberof AppTextarea
*/
@Input()
position: 'LEFT' | 'TOP' | 'RIGHT' | 'BOTTOM' = 'LEFT';
/**
* 标签文本
*
* @type {string}
* @memberof AppTextarea
*/
@Input()
labelText: string;
/**
* 是否必填
*
* @type {boolean}
* @memberof AppTextarea
*/
@Input()
allowEmpty: boolean;
/**
* 设置多行文本高度
*
* @type {string}
* @memberof AppTextarea
*/
@Input()
height: string;
/**
* 图标名称
*
* @type {string}
* @memberof AppTextarea
*/
@Input()
iconName: string;
/**
* 图标路径
*
* @type {string}
* @memberof AppTextarea
*/
@Input()
iconSrc: string;
/**
* Creates an instance of AppTextarea.
* @memberof AppTextarea
*/
constructor() { }
@HostBinding('class')
public hostPropertyClass = 'ibiz-textarea';
}
\ No newline at end of file
<ion-toggle [disabled]="disabled" slot="end" [checked]="value" (ionChange)="onValueChange($event)"></ion-toggle>
\ No newline at end of file
import { Component, Input, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
@Component({
selector: 'app-toggle',
templateUrl: './app-toggle.html',
styleUrls: ['./app-toggle.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => AppToggle),
multi: true
}
]
})
export class AppToggle implements ControlValueAccessor {
/**
* 编辑器值
*
* @type {string}
* @memberof AppToggle
*/
public value: any;
/**
* 是否启用
*
* @type {boolean}
* @memberof AppToggle
*/
@Input()
disabled: boolean;
/**
* 提示信息
*
* @type {string}
* @memberof AppToggle
*/
@Input()
placeholder: string;
/**
* 数据发生改变
*
* @param {*} detail
* @memberof AppToggle
*/
public onValueChange({ detail }): void {
if (detail && detail.checked !== this.value) {
if(detail.checked){
if(this.value === 1){
return ;
}
this.value = 1;
}else{
if(this.value === 0){
return ;
}
this.value = 0;
}
this.onChange(this.value + '');
}
}
/**
* 输入
*
* @param {*} obj
* @memberof AppToggle
*/
public writeValue(obj: any): void {
if (obj && !Object.is(obj, '')) {
if (Object.is(obj, 1) || Object.is(obj, "1")) {
setTimeout(() => {
this.value = 1;
}, 0);
} else {
this.value = 0;
}
}
}
private onTouched: () => void = () => { };
private onChange: (val: any) => void = () => { };
public registerOnChange(fn: any): void { this.onChange = fn; }
public registerOnTouched(fn: any): void { this.onTouched = fn; }
}
\ No newline at end of file
<div class="card">
<div class="head">{{title?title:null}}</div>
<div class="content">
<div class="bigimg">
<div>
<img *ngIf="_messages&&_messages[0]&&_messages[0].icon" src="{{(_messages&&_messages[0])?_messages[0].icon:null}}"
alt="" (click)="handleClick(_messages[0])" onerror="this.src='./assets/icon/default_img.png'">
</div>
<div>
<img *ngIf="_messages&&_messages[1]&&_messages[1].icon" src="{{(_messages&&_messages[0])?_messages[1].icon:null}}"
alt="" (click)="handleClick(_messages[1])" onerror="this.src='./assets/icon/default_img.png'">
</div>
</div>
<div class="ximg">
<ng-container *ngFor="let item of _messages;index as i">
<ng-container *ngIf="i>1&&i<=5">
<div class="xcontent" class="item" (click)="handleClick(item)">
<div class="xiaoimg">
<img *ngIf="item.icon" src="{{item.icon?item.icon:null}}" alt=""
onerror="this.src='./assets/icon/default_img.png'">
</div>
<div class="title" style="text-align: center;">{{item.text}}</div>
<div class="subtitle" style="text-align: center;">{{item.subtitle}}</div>
</div>
</ng-container>
</ng-container>
</div>
</div>
</div>
\ No newline at end of file
.card{
margin-bottom: 0.5rem;
.head{
font-size: 1.05rem;
padding-left: 0.75rem;
padding-top: 0.5rem;
}
.content{
padding-left: 0.75rem;
.bigimg{
display: flex;
>div{
width: 48%;
margin-top: 0.625rem;
height: 8.125rem;
margin-right: 0.4375rem;
>img{
width: 100%;
height: 100%;
}
}
}
.ximg{
display:flex;
width:100%;
.item{
margin-top: 1.34375rem;
width:25%;
.title{
text-align: center;
font-weight: bold;
padding: 0.2rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.subtitle{
text-align: center;
color: gray;
margin-top: 0.375rem;
font-size: 0.9375rem;
padding:0.2rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.xiaoimg{
height: 4.6875rem;
>img{
width: 100%;
height: 100%;
padding:0.2rem;
}
}
}
}
}
}
\ No newline at end of file
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-twobwithfours-image',
templateUrl: './app-twobwithfours-image.component.html',
styleUrls: ['./app-twobwithfours-image.component.scss'],
})
export class AppTwobwithfoursImage implements OnInit {
/**
* 输入标题
*/
@Input() title:string;
public _messages:Array<any> =[];
/**
* 输入属性
*/
@Input() set messages(val:any){
if(val){
this._messages = JSON.parse(JSON.stringify(val));
}
}
/**
* 抛出数据
*/
@Output() menuClick: EventEmitter<any> = new EventEmitter<any>();
constructor() { }
ngOnInit() { }
handleClick(item: any) {
this.menuClick.emit(item);
}
}
<ion-card class="app-user-info">
<ion-card-content style="padding: 10px 0;">
<ion-item lines="none" href="javascript:;">
<ion-avatar slot="start">
<img [src]="userInfo.userhead ? userInfo.userhead : './assets/icon/default_head.svg'" onerror="this.src = './assets/icon/default_head.svg'">
</ion-avatar>
<ion-label>
<h2>{{ userInfo.username }}</h2>
<p>{{ userInfo.loginname }}</p>
</ion-label>
<ng-content></ng-content>
</ion-item>
</ion-card-content>
</ion-card>
\ No newline at end of file
.app-user-info {
margin: 0;
border-radius: 0;
}
\ No newline at end of file
import { Component } from '@angular/core';
@Component({
selector: 'app-user-info',
templateUrl: 'app-user-info.html',
styleUrls: ['app-user-info.scss']
})
export class AppUserInfo {
/**
* 用户信息
*
* @type {*}
* @memberof AppUserInfo
*/
public userInfo: any = {};
/**
* Creates an instance of IBizUserInfo.
* @memberof AppUserInfo
*/
constructor() {
const userInfo: string = window.localStorage.getItem('userInfo');
if (userInfo) {
try {
this.userInfo = JSON.parse(userInfo);
} catch (error) {
console.error(error);
}
}
}
}
\ No newline at end of file
<div class="list">
<div class="head">{{title?title:null}}</div>
<div *ngFor="let item of _items" class="listitem">
<div class="image" (click)="handleClick(item)">
<img *ngIf="item.image&&item.image[0]&&item.image[0].id"
[src]="(item.image && item.image[0] ? url+item.image[0].id :null)" alt=""
onerror="this.src='./assets/icon/default_img.png'">
</div>
<div class="title" (click)="handleClick(item)">
{{item.title}}
</div>
</div>
</div>
\ No newline at end of file
.list{
margin: 0.625rem;
.head{
font-size: 1.15rem;
font-weight: 540;
padding-left: 0.75rem;
padding-top: 0.5rem;
font-family: AncientWar;
}
.listitem{
margin-bottom: 1.1875rem;
position: relative;
.image{
width: 100%;
height: 7.625rem;
img{
width: 100%;
height: 100%;
}
}
.title{
position: absolute;
bottom: 0.3125rem;
left: 0.6875rem;
color: white;
z-index: 1000;
font-size: 1.1875rem;
}
}
}
\ No newline at end of file
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { AppEnvironment } from 'src/environments/AppEnvironment';
@Component({
selector: 'app-withtitle-list',
templateUrl: './app-withtitle-list.component.html',
styleUrls: ['./app-withtitle-list.component.scss'],
})
export class AppWithtitleList implements OnInit {
/**
* 基础路径
*/
url: String = AppEnvironment.BaseUrl + AppEnvironment.ExportFile + '/';
public _items:Array<any> =[];
@Input() public title:string;
/**
* 输入属性
*/
@Input() set items(val:any){
if(val){
this._items = JSON.parse(JSON.stringify(val));
if(this._items.length >0){
this._items.forEach((item:any) =>{
if(item.image){
item.image = JSON.parse(item.image);
}
})
}
}
}
/**
* 抛出数据
*/
@Output() itemClick: EventEmitter<any> = new EventEmitter<any>();
constructor() { }
ngOnInit() { }
handleClick(item: any) {
this.itemClick.emit(item);
}
}
import { Directive, ElementRef, Input, AfterViewInit } from '@angular/core';
import { ECharts, init } from 'echarts';
@Directive({
selector: '[app-echart]'
})
export class AppEChartDirective implements AfterViewInit {
/**
* 图表实例
*
* @private
* @type {ECharts}
* @memberof AppChart
*/
private $echarts: ECharts;
/**
* 图表配置
*
* @memberof AppEChartDirective
*/
@Input()
set chartConfig(val: any) {
if (val && (Object.keys(val).length > 0)) {
this.option = this.formatData(val);
this.setChartOption(this.option);
}
}
private option: any = {};
/**
* 图表高度
*
* @type {string}
* @memberof AppEChartDirective
*/
@Input()
height: string;
/**
* 图表宽度
*
* @type {string}
* @memberof AppEChartDirective
*/
@Input()
width: string;
/**
* Creates an instance of AppEChartDirective.
* @memberof AppEChartDirective
*/
constructor(private ref: ElementRef) { }
public ngAfterViewInit(): void {
this.initCharts(this.ref.nativeElement);
}
/**
* 图表配置设置
*
* @private
* @param {*} [opts={}]
* @memberof AppEChartDirective
*/
private setChartOption(opts: any = {}) {
this.$echarts.setOption(opts);
}
/**
* 格式化图表配置
*
* @private
* @param {*} data
* @returns {*}
* @memberof AppChart
*/
private formatData(data: any): any {
if (data.series) {
// 区域图分析
if (Array.isArray(data.series) && (data.series.length > 0)) {
const series: any[] = data.series;
if (Object.is(series[0].type, 'area')) {
// 如果series是数组的话
data.series.forEach((item: any) => {
Object.assign(item, { type: 'line', areaStyle: { normal: {} } });
});
return data;
} else if (Object.is(series[0].type, 'radar')) {
// 1.找到每个角的最大值
let max: number = 0;
// 获得每个角的数据
const arrs: any[] = [];
series.forEach((item) => {
arrs.push(item.data);
});
const lastarrs: any[] = arrs[0].map((col, i) => {
return arrs.map((row) => {
return row[i];
});
});
const maxs: any[] = [];
lastarrs.forEach((item: any[]) => {
max = item[0];
item.forEach((element) => {
if (max < element) {
max = element;
}
});
maxs.push(max);
});
// x轴数据转化成indicator数据
const indicatorArr: any[] = [];
const xAxisData: any[] = data.xAxis.data;
xAxisData.forEach((item) => {
maxs.forEach((element) => {
if (item === element) {
indicatorArr.push({ name: item, max: element });
}
});
});
data.radar.indicator = [];
if (Array.isArray(indicatorArr)) {
data.radar.indicator = [...indicatorArr];
}
data.xAxis = null;
// 设置series的data数据
series.forEach((item) => {
const valueArray = item.data;
const name = item.name;
item.data = { name, value: valueArray };
});
return data;
}
} else if (Object.is(data.series.type, 'area')) {
data.series.type = 'line';
data.series.areaStyle = {};
Object.assign(data.series.areaStyle, { normal: {} });
return data;
} else {
if (!data.series.data) {
this.option.series.data = [];
return this.option;
}
}
}
return data;
}
/**
* 初始化图表
*
* @private
* @memberof AppChart
*/
private initCharts(ref: HTMLDivElement): void {
if (ref) {
const opt: any = {};
opt.width = this.width ? this.width : ref.clientWidth;
if (this.height) {
opt.height = this.height;
}
this.$echarts = init(ref, null, opt);
}
}
}
\ No newline at end of file
import { NgModule } from '@angular/core';
import { DatePipe } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { FileUploadModule } from 'ng2-file-upload';
import { NgZorroAntdMobileModule } from 'ng-zorro-antd-mobile';
// 组件 Start
import {AppDateTime} from './components/app-datetime/app-datetime';
import {AppFormComponent} from './components/app-form/app-form.component';
import {AppFormItemComponent} from './components/app-form-item/app-form-item.component';
import {AppIcon} from './components/app-icon/app-icon';
import { AppImageUpload } from './components/app-image-upload/app-image-upload';
import { AppTextarea } from './components/app-textarea/app-textarea';
import { AppToggle } from './components/app-toggle/app-toggle';
import { AppFileUpload } from './components/app-file-upload/app-file-upload';
import { AppStepper } from './components/app-stepper/app-stepper';
import { AppPicker } from './components/app-picker/app-picker';
import { AppMPicker } from './components/app-mpicker/app-mpicker';
import { AppRadio } from './components/app-radio/app-radio';
import { AppMultipleSelect } from './components/app-multiple-select/app-multiple-select';
import { AppSelect } from './components/app-select/app-select';
import { AppListMenu } from './components/app-list-menu/app-list-menu';
import { AppDividingLine } from './components/app-dividing-line/app-dividing-line';
import { AppSlideMenu } from './components/app-slide-menu/app-slide-menu';
import { AppPalaceMenu } from './components/app-palace-menu/app-palace-menu';
import { AppQuickMenu } from './components/app-app-menu/app-app-menu';
import { AppCalendar } from './components/app-calendar/app-calendar';
import { AppScrollPaging } from './components/app-scroll-paging/app-scroll-paging';
import { AppFormDruipart } from './components/app-form-druipart/app-form-druipart.component';
import { AppLoadMore } from './components/app-load-more/app-load-more';
import { AppRotationChart } from './components/app-rotation-chart/app-rotation-chart';
import { AppImageListComponent } from './components/app-image-list/app-image-list.component';
import { AppWithtitleList } from './components/app-withtitle-list/app-withtitle-list.component';
import { AppStorestyleList } from './components/app-storestyle-list/app-storestyle-list.component';
import { AppAnchorPointList } from './components/app-anchor-point-list/app-anchor-point-list';
import { AppShrinkableGroupingList } from './components/app-shrinkable-grouping-list/app-shrinkable-grouping-list';
import { AppLevelImgtext } from './components/app-level-imgtext/app-level-imgtext.component';
import { AppHorizontalScroll } from './components/app-horizontal-scroll/app-horizontal-scroll.component';
import { AppOnlyImage } from './components/app-only-image/app-only-image.component';
import { AppTwobwithfoursImage } from './components/app-twobwithfours-image/app-twobwithfours-image.component';
import { AppLevelslideWithpriceList } from './components/app-levelslide-withprice-list/app-levelslide-withprice-list.component';
import { AppOnebwiththreesImage } from './components/app-onebwiththrees-image/app-onebwiththrees-image.component';
import { AppUserInfo } from './components/app-user-info/app-user-info';
import { AppLevelslideList } from './components/app-levelslide-list/app-levelslide-list.component';
import { AppMoreSettingComponent } from './components/app-more-setting/app-more-setting.component';
// 组件 End
// 指令 Start
import { AppEChartDirective } from './directives/app-echart';
// 指令 End
// 守卫 Start
import { AuthGuard } from './guard/auth-guard';
// 守卫 End
// 视图 Start
import { PicturePreview } from './helper/app-picture-preview/app-picture-preview';
// 视图 End
// 服务 Start
import { Loading } from './service/Loading';
// 服务 End
/**
* 公共组件
*/
const components: any[] = [
AppDateTime,
AppFormComponent,
AppFormItemComponent,
AppIcon,
AppImageUpload,
AppTextarea,
AppToggle,
AppFileUpload,
AppStepper,
AppPicker,
AppMPicker,
AppRadio,
AppSelect,
AppMultipleSelect,
AppListMenu,
AppDividingLine,
AppSlideMenu,
AppPalaceMenu,
AppQuickMenu,
AppCalendar,
AppScrollPaging,
AppFormDruipart,
AppLoadMore,
AppRotationChart,
AppImageListComponent,
AppWithtitleList,
AppStorestyleList,
AppAnchorPointList,
AppShrinkableGroupingList,
AppLevelImgtext,
AppHorizontalScroll,
AppOnlyImage,
AppTwobwithfoursImage,
AppLevelslideWithpriceList,
AppOnebwiththreesImage,
AppUserInfo,
AppLevelslideList,
AppMoreSettingComponent
];
/**
* 指令
*/
const directives: any[] = [
AppEChartDirective
];
/**
* 视图
*/
const pages: any[] = [
PicturePreview
];
@NgModule({
imports: [
CommonModule,
IonicModule,
FormsModule,
FileUploadModule,
NgZorroAntdMobileModule
],
exports: [
IonicModule,
NgZorroAntdMobileModule,
...components,
...directives,
...pages,
],
declarations: [
...components,
...directives,
...pages,
],
entryComponents: [
...pages,
],
providers: [
AuthGuard,
Loading,
DatePipe
]
})
export class GlobalModule { }
\ No newline at end of file
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, CanActivate } from '@angular/router';
import { Http } from '../service/Http';
import { App } from '../service/App';
import { AppEnvironment } from '../../environments/AppEnvironment';
import { CodeList } from '../service/codelist';
@Injectable()
export class AuthGuard implements CanActivate {
/**
*
*
* @private
* @type {(1 | 2 | 3 | 4)} (匿名用户 | 登录用户 | 匿名及登录用户 | 登录用户且拥有指定资源能力 )
* @memberof AuthGuard
*/
private accessMode: 1 | 2 | 3 | 4 = 2;
/**
* Creates an instance of AuthGuard.
* @memberof AuthGuard
*/
constructor(private $http: Http, private App: App, private codeList: CodeList) { }
/**
*
*
* @param {ActivatedRouteSnapshot} route
* @param {RouterStateSnapshot} state
* @returns {(Promise<boolean> | Observable<boolean> | boolean)}
* @memberof AuthGuard
*/
public async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
let isNext: boolean = true;
isNext = this.permissionVerification(route);
if (!isNext) {
return false;
}
isNext = await this.loadAppData(route);
if (!isNext) {
return false;
}
isNext = await this.codeList.initCodelist();
return isNext;
}
/**
* 权限校验
*
* @private
* @param {ActivatedRouteSnapshot} route
* @returns {Promise<boolean>}
* @memberof AuthGuard
*/
private permissionVerification(route: ActivatedRouteSnapshot): boolean {
const data: any = route.data;
if (data && data.hasOwnProperty('accessMode')) {
this.accessMode = data.accessMode;
}
if (Object.is(AppEnvironment.LoginModel, 'default') && (this.accessMode === 2 || this.accessMode === 4)) {
const srfLoginKey = this.App.getLoginKey();
if (!srfLoginKey || Object.is(srfLoginKey, '')) {
this.App.clearAccess();
this.App.login();
return false;
}
}
return true;
}
/**
* 加载appdata数据
*
* @memberof IBizIndexViewController
*/
private loadAppData(route: ActivatedRouteSnapshot): Promise<any> {
return new Promise((resolve: any, reject: any) => {
if(!this.App.getAppData()){
this.$http.get1(`${AppEnvironment.AppName.toLocaleLowerCase()}/app/${AppEnvironment.AppName.toLocaleLowerCase()}/getappdata`, {}).then((response: any) => {
if (!response) {
resolve(false);
return;
}
this.App.setAppData(response);
if (response && response.remotetag) {
window.localStorage.setItem('remotetag', response.remotetag);
resolve(true);
} else if (response && response.localdata) {
window.localStorage.setItem('localdata', response.localdata);
resolve(true);
} else {
// resolve(false);暂时返回true
resolve(true);
}
})
}else{
resolve(true);
}
});
}
}
\ No newline at end of file
<ion-content>
<div class="ibiz-picture-preview" (click)="close()">
<div class="image">
<img [src]="url + imageId">
</div>
</div>
</ion-content>
\ No newline at end of file
.ibiz-picture-preview {
display: flex;
flex-direction: column;
justify-content: center;
align-self: center;
height: 100%;
width: 100vw;
background-color: black;
.image {
img {
max-height: 100%;
max-width: 100vw;
}
}
}
\ No newline at end of file
import { Component, Input } from '@angular/core';
import { AppEnvironment } from '../../../environments/AppEnvironment';
import { ModalController } from '@ionic/angular';
@Component({
selector: 'app-picture-preview',
templateUrl: 'app-picture-preview.html',
styleUrls: ['app-picture-preview.scss']
})
export class PicturePreview {
/**
* 展示图片id
*
* @type {string}
* @memberof PicturePreview
*/
@Input()
imageId: string;
/**
* 图片展示url
*
* @type {string}
* @memberof PicturePreview
*/
public url: string;
/**
* Creates an instance of PicturePreview.
* @memberof PicturePreview
*/
constructor(private modalCtrl: ModalController) {
// 拼接上传或下载的url
this.url = AppEnvironment.BaseUrl + AppEnvironment.ExportFile + '/';
}
/**
* 关闭预览
*
* @memberof PicturePreview
*/
public close(): void {
this.modalCtrl.dismiss();
}
}
\ No newline at end of file
export interface AppFunc {
/**
* 应用功能id
*
* @type {string}
* @memberof AppFunc
*/
appfuncid?: string;
/**
*
*
* @type {boolean}
* @memberof AppFunc
*/
expanede?: boolean;
/**
* 图标(路径)
*
* @type {string}
* @memberof AppFunc
*/
icon?: string;
/**
* 图标(样式)
*
* @type {string}
* @memberof AppFunc
*/
iconcls?: string;
/**
* 主键
*
* @type {string}
* @memberof AppFunc
*/
id: string;
/**
* 是否为跟节点
*
* @type {boolean}
* @memberof AppFunc
*/
leaf: boolean;
/**
* 文本
*
* @type {string}
* @memberof AppFunc
*/
text: string;
/**
* 文本样式
*
* @type {string}
* @memberof AppFunc
*/
textcls: string;
/**
* 提示信息
*
* @type {string}
* @memberof AppFunc
*/
tooltip: string;
}
\ No newline at end of file
export interface CodeItem {
value:Object,
id:string,
text:string,
label:string,
parentValue:string,
userdata:string,
userdata2:string,
userdata3:string,
userdata4:string,
fillter:string,
items:[],
children:[],
}
\ No newline at end of file
/**
*
*
* @interface ViewState
*/
interface ViewState {
/**
* 部件标识
*
* @type {string}
* @memberof ViewState
*/
tag: string;
/**
* 触发行为
*
* @type {('load' | 'save' | 'remove')}
* @memberof ViewState
*/
action: 'load' | 'save' | 'remove' | 'autoload' | 'loaddraft' | string;
/**
* 数据
*
* @type {*}
* @memberof ViewState
*/
data?: any;
}
\ No newline at end of file
import { FormDetailModel } from './form-detail';
/**
* 按钮模型
*
* @export
* @class FormButtonModel
* @extends {FormDetailModel}
*/
export class FormButtonModel extends FormDetailModel {
constructor(opts: any = {}) {
super(opts);
}
}
\ No newline at end of file
/**
* 表单成员模型
*
* @export
* @class FormDetailModel
*/
export class FormDetailModel {
public caption: string = '';
public detailType: string = '';
public name: string = '';
public visible: boolean = true;
public isShowCaption: boolean = true;
constructor(opts: any = {}) {
this.caption = !Object.is(opts.caption, '') ? opts.caption : '';
this.detailType = !Object.is(opts.detailType, '') ? opts.detailType : '';
this.name = !Object.is(opts.name, '') ? opts.name : '';
this.visible = opts.visible ? true : false;
this.isShowCaption = opts.isShowCaption ? true : false;
}
public setVisible(state: boolean): void {
this.visible = state;
}
public setShowCaption(state: boolean): void {
this.isShowCaption = state;
}
}
\ No newline at end of file
import { FormDetailModel } from './form-detail';
/**
* 数据关系界面模型
*
* @export
* @class FromDRUIPartModel
* @extends {FormDetailModel}
*/
export class FromDRUIPartModel extends FormDetailModel {
constructor(opts: any = {}) {
super(opts);
}
}
\ No newline at end of file
import { FormDetailModel } from './form-detail';
/**
* 分组面板模型
*
* @export
* @class FormGroupPanelModel
* @extends {FormDetailModel}
*/
export class FormGroupPanelModel extends FormDetailModel {
constructor(opts: any = {}) {
super(opts);
}
}
\ No newline at end of file
import { FormDetailModel } from './form-detail';
/**
* 表单项模型
*
* @export
* @class FormItemModel
* @extends {FormDetailModel}
*/
export class FormItemModel extends FormDetailModel {
public disabled: boolean = false;
public isAllowEmpty: boolean = true;
constructor(opts: any = {}) {
super(opts);
this.disabled = opts.disabled ? true : false;
this.isAllowEmpty = opts.isAllowEmpty ? true : false;
}
public setAllowEmpty(state: boolean): void {
this.isAllowEmpty = state;
}
public setDisabled(state: boolean): void {
this.disabled = state;
}
}
\ No newline at end of file
import { FormDetailModel } from './form-detail';
/**
* 表单分页模型
*
* @export
* @class FormPageModel
* @extends {FormDetailModel}
*/
export class FormPageModel extends FormDetailModel {
constructor(opts: any = {}) {
super(opts);
}
}
\ No newline at end of file
import { FormDetailModel } from './form-detail';
/**
* 表单部件模型
*
* @export
* @class FormPartModel
* @extends {FormDetailModel}
*/
export class FormPartModel extends FormDetailModel {
constructor(opts: any = {}) {
super(opts);
}
}
\ No newline at end of file
import { FormDetailModel } from './form-detail';
/**
* 直接内容模型
*
* @export
* @class FormRowItemModel
* @extends {FormDetailModel}
*/
export class FormRowItemModel extends FormDetailModel {
constructor(opts: any = {}) {
super(opts);
}
}
\ No newline at end of file
import { FormDetailModel } from './form-detail';
/**
* 分页面板模型
*
* @export
* @class FormTabPageModel
* @extends {FormDetailModel}
*/
export class FormTabPageModel extends FormDetailModel {
constructor(opts: any = {}) {
super(opts);
}
}
\ No newline at end of file
import { FormDetailModel } from './form-detail';
/**
* 用户控件模型
*
* @export
* @class FormUserControlModel
* @extends {FormDetailModel}
*/
export class FormUserControlModel extends FormDetailModel {
constructor(otps:any = {}) {
super(otps);
}
}
\ No newline at end of file
import { FormDetailModel } from './form-detail';
/**
* 分页部件模型
*
* @export
* @class FormTabPanelModel
* @extends {FormDetailModel}
*/
export class FormTabPanelModel extends FormDetailModel {
constructor(opts: any = {}) {
super(opts);
}
}
\ No newline at end of file
export { FormButtonModel } from './form-button';
export { FormPageModel } from './form-page';
export { FormItemModel } from './form-item';
export { FromDRUIPartModel } from './form-druipart';
export { FormPartModel } from './form-part';
export { FormGroupPanelModel } from './form-group-panel';
export { FormRowItemModel } from './form-row-item';
export { FormTabPageModel } from './form-tab-page';
export { FormTabPanelModel } from './from-tab-panel';
export { FormUserControlModel } from './form-user-control';
import { Injectable } from '@angular/core';
import { Platform, ActionSheetController, NavController } from '@ionic/angular';
import { AppEnvironment } from '../../environments/AppEnvironment';
@Injectable({ providedIn: 'root' })
export class App {
/**
* 视图回调
*
* @private
* @memberof App
*/
private $viewCallbacks: ((res: any) => void)[] = [];
/**
* 当前运行平台类型
*
* @private
* @type {('ios' | 'android' | 'other')}
* @memberof App
*/
private $platFormType: 'ios' | 'android' | 'other' = 'other';
/**
* 应用功能页
*
* @private
* @type {Map<string, string>}
* @memberof App
*/
private $functionPages: Map<string, string> = new Map();
/**
* 是否加载AppData数据
*
* @type {boolean}
* @memberof App
*/
public $isLoadAppData: boolean = true;
/**
* 应用数据
*
* @private
* @type {*}
* @memberof AppService
*/
private $appdata: string = '';
/**
* 本地数据
*
* @private
* @type {*}
* @memberof AppService
*/
private $localdata: any = {};
/**
* Creates an instance of App.
* @param {Platform} platform
* @memberof App
*/
constructor(
private platform: Platform,
private actionSheetController: ActionSheetController,
private navCtrl: NavController
) {
const platforms: string[] = this.platform.platforms();
const str: string = platforms.toString();
if (str.indexOf('ios') !== -1) {
this.$platFormType = 'ios';
} else if (str.indexOf('android') !== -1) {
this.$platFormType = 'android';
}
}
/**
* 获取当前运行平台类型
*
* @returns {('ios' | 'android')}
* @memberof App
*/
public getPlatFormType(): 'ios' | 'android' | 'other' {
return this.$platFormType;
}
/**
* 是否为ios平台
*
* @returns {boolean}
* @memberof App
*/
public isIos(): boolean {
return Object.is(this.$platFormType, 'ios');
}
/**
* 是否为Android平台
*
* @returns {boolean}
* @memberof App
*/
public isAndroid(): boolean {
return Object.is(this.$platFormType, 'android');
}
/**
* 返回回调关闭
*
* @param {*} res
* @memberof App
*/
public closeCallback(res: any): void {
if (this.$viewCallbacks.length > 0) {
const func = this.$viewCallbacks[this.$viewCallbacks.length - 1];
func(res);
this.$viewCallbacks.pop();
}
}
/**
* 设置回调
*
* @returns {Observable<any>}
* @memberof App
*/
public nextViewCloseCallback(func: (res: any) => void): void {
this.$viewCallbacks.push(func);
}
/**
* Ionic运行平台Api
*
* @returns {Platform}
* @memberof App
*/
public getPlatForm(): Platform {
return this.platform;
}
/**
* 应用底部悬浮工具栏
*
* @param {*} [opts={}] 数据
* @param {string} [identification='tag'] 点击返回标识字段
* @returns {Promise<string>}
* @memberof App
*/
public async openActionSheet(opts: any = {}, id: string = 'tag'): Promise<string> {
if (opts.items) {
const buttons: any[] = opts.items.map((item) => {
const { text, icon, iconcls } = item;
return { text: text, icon: iconcls ? iconcls : icon, role: item.id };
});
buttons.push({ text: '取消', role: 'cancel', color: 'red' });
const actionSheet = await this.actionSheetController.create({
header: opts.text,
buttons
});
await actionSheet.present();
const result = await actionSheet.onWillDismiss();
return result.role;
}
}
/**
* 注册应用功能页
*
* @param {string} type 功能页类型
* @param {string} url 功能页地址
* @memberof App
*/
public regFunctionPage(type: string, url: string): void {
this.$functionPages.set(type, url);
}
/**
* 获取登录页地址
*
* @returns {string} 登录页地址
* @memberof App
*/
public getLoginPage(): string {
const loginUrl: string = this.$functionPages.get('login');
if (!loginUrl) {
alert('请在系统配置登录页!');
}
return loginUrl;
}
/**
* 获取启动视图
*
* @returns {string}
* @memberof App
*/
public getStartPage(): string {
return this.$functionPages.get('start');
}
/**
* 获取应用默认页地址
*
* @returns {string} 默认页地址
* @memberof App
*/
public getDefaultPage(): string {
return this.$functionPages.get('default');
}
/**
* appdata添加数据
*
* @param {*} appdata
* @memberof AppService
*/
public setAppData(appdata: string): void {
this.$appdata = appdata;
}
/**
* 获取appdata数据
*
* @returns {*}
* @memberof AppService
*/
public getAppData(): string {
return this.$appdata;
}
/**
* 添加本地数据
*
* @param {*} data
* @memberof AppService
*/
public addLocalData(data: any): void {
Object.assign(this.$localdata, data);
}
/**
* 获取本地数据
*
* @memberof AppService
*/
public getLocalData(): void {
return this.$localdata;
}
/**
* 去登录页
*
* @memberof App
*/
public login(): void {
const str: string = window.location.hash;
this.navCtrl.navigateRoot([this.getLoginPage(), { url: str.slice(1, str.length) }]);
}
/**
* 获取用户登录id
*
* @returns {string}
* @memberof App
*/
public getLoginKey(): string {
return window.localStorage.getItem('srfloginkey');
}
/**
* 清除认证信息
*
* @memberof App
*/
public clearAccess(): void {
window.localStorage.removeItem('srfloginkey');
window.localStorage.removeItem('userInfo');
}
/**
* 获取用户信息
*
* @returns {*}
* @memberof App
*/
public getUserInfo(): any {
const userInfo: string = window.localStorage.getItem('userInfo');
try {
return JSON.parse(userInfo);
} catch (error) {
console.error(error);
}
return null;
}
}
\ No newline at end of file
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { AppEnvironment } from '../../environments/AppEnvironment';
import { Loading } from './Loading';
import { AppNotification } from './Notification';
import { App } from './App';
import { Observable } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class Http {
/**
* 状态信息
*
* @private
* @static
* @memberof Http
*/
private codeMessage = {
200: '服务器成功返回请求的数据。',
201: '新建或修改数据成功。',
202: '一个请求已经进入后台排队(异步任务)。',
204: '删除数据成功。',
400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
401: '用户没有权限(令牌、用户名、密码错误)。',
403: '用户得到授权,但是访问是被禁止的。',
404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
406: '请求的格式不可得。',
410: '请求的资源被永久删除,且不会再得到的。',
422: '当创建一个对象时,发生一个验证错误。',
500: '服务器发生错误,请检查服务器。',
502: '网关错误。',
503: '服务不可用,服务器暂时过载或维护。',
504: '网关超时。',
};
/**
* Creates an instance of Http.
* @param {HttpClient} http
* @memberof Http
*/
constructor(private $http: HttpClient, private $app: App, private $notification: AppNotification, private $loading: Loading) { }
/**
* 有加载动画的POST请求
*
* @param {string} url 请求地址
* @param {*} [params={}] 请求参数
* @returns {Observable<any>}
* @memberof Http
*/
public post(url: string, params?: any,showloading?:boolean): Promise<any> {
if(showloading !== false){
this.mask();
}
return new Promise((resolve, reject) => {
this.$http.post(AppEnvironment.BaseUrl + url, params).subscribe((res) => {
resolve(res);
if(showloading !== false){
this.unmask();
}
}, (error) => {
if(showloading !== false){
this.unmask();
}
})
});
}
/**
* 发送http请求
*
* @private
* @param {string} url
* @param {*} [params={}]
* @returns {Promise<any>}
* @memberof Http
*/
// private results(url: string, params: any = {}): Promise<any> {
// return new Promise((resolve, reject) => {
// this.$http.post(AppEnvironment.BaseUrl + url, this.transformationOpt(params), {
// headers: new HttpHeaders({
// 'Accept': 'application/json; charset=utf-8',
// 'Content-Type': '/x-www-form-urlencoded;charset=UTF-8'
// })
// }).subscribe(
// (response: any) => {
// resolve(response);
// },
// (response) => {
// const errorText = this.codeMessage[response.status] || response.statusText;
// this.$notification.error(`请求错误 ${response.status}: ${errorText}`);
// reject(response);
// const error: any = new Error(errorText);
// error.name = response.status;
// error.response = response;
// throw error;
// }
// );
// });
// }
/**
* GET请求
*
* @param {string} url 请求地址
* @returns
* @memberof Http
*/
public get(url: string,showloading?:boolean): Promise<any> {
if(showloading !== false){
this.mask();
}
return new Promise((resolve, reject) => {
this.$http.get(AppEnvironment.BaseUrl + url).subscribe((res) => {
resolve(res);
if(showloading !== false){
this.unmask();
}
}, (error) => {
if(showloading !== false){
this.unmask();
}
})
});
}
/**
* GET请求(带有请求参数)
*
* @param {string} url 请求地址
* @param {Object} param get请求参数
* @returns
* @memberof Http
*/
public get1(url: string, param: Object,showloading?:boolean): Promise<any> {
if(showloading !== false){
this.mask();
}
if (Object.keys(param).length > 0) {
let tempurl = "";
Object.keys(param).forEach((item: any,index:number) => {
if(index === 0){
tempurl += item + "=" + param[item];
}else{
tempurl +="&"+item + "=" + param[item];
}
});
return new Promise((resolve, reject) => {
this.$http.get(AppEnvironment.BaseUrl + url + "?" + tempurl).subscribe((res) => {
resolve(res);
if(showloading !== false){
this.unmask();
}
},(error) =>{
if(showloading !== false){
this.unmask();
}
})
})
} else {
return new Promise((resolve, reject) => {
this.$http.get(AppEnvironment.BaseUrl + url).subscribe((res) => {
resolve(res);
if(showloading !== false){
this.unmask();
}
}, (error) => {
if(showloading !== false){
this.unmask();
}
})
})
}
}
/**
* 格式化http请求数据
*
* @private
* @param {*} [opt={}]
* @returns {HttpParams}
* @memberof Http
*/
private transformationOpt(opt: any = {}): HttpParams {
const params: any = {};
// 获取srfloginkey
const loginkey: string | null = window.localStorage.getItem('srfloginkey');
if (loginkey) {
params.srfloginkey = loginkey;
}
// 添加appdata数据
const srfappdata: string = this.$app.getAppData();
if (srfappdata) {
params.srfappdata = srfappdata;
}
Object.assign(params, opt);
const keys: string[] = Object.keys(params);
keys.forEach((key: string) => {
params[key] = this.recursionToString(params[key]);
});
return new HttpParams({ 'fromObject': params });
}
/**
* 递归转换对象为字符串
*
* @param {*} val
* @returns {string}
* @memberof Http
*/
public recursionToString(val: any): string {
if (val && !Object.is(val, '')) {
if (val instanceof Array) {
val.forEach((item: any) => {
item = this.recursionToString(item);
});
return JSON.stringify(val);
}
if (val instanceof Object) {
const childKeys: string[] = Object.keys(val);
childKeys.forEach((childKey: string) => {
val[childKey] = this.recursionToString(val[childKey]);
});
return JSON.stringify(val);
}
}
return val;
}
/**
*
*
* @returns {Promise<any>}
* @memberof Http
*/
public mask(): Promise<any> {
return this.$loading.mask();
}
/**
*
*
* @returns {Promise<any>}
* @memberof Http
*/
public unmask(): Promise<any> {
return this.$loading.unmask();
}
}
\ No newline at end of file
import { Injectable } from '@angular/core';
import { LoadingController } from '@ionic/angular';
@Injectable({ providedIn: 'root' })
export class Loading {
/**
* 加载动画计数器
*
* @type {number}
* @memberof Http
*/
private loadingCount: number = 0;
/**
* 加载动画实例
*
* @type {*}
* @memberof Http
*/
private loader: any;
constructor(private loading: LoadingController) { }
/**
* 显示loading
*
* @memberof Http
*/
public async mask(message: string = '加载中......'): Promise<any> {
this.loadingCount++;
if (this.loadingCount === 1) {
this.loader = await this.loading.create({
message
});
this.loader.present();
}
}
/**
* 隐藏loading
*
* @memberof Http
*/
public async unmask(): Promise<any> {
setTimeout(() => {
this.loadingCount--;
if (this.loadingCount === 0) {
//if (this.loadingCount === 0) {
//this.loading.dismiss();
if (this.loader) {
this.loader.dismiss();
} else {
this.loading.dismiss();
}
this.loader = undefined;
}
}, 300);
}
}
\ No newline at end of file
import { Injectable } from '@angular/core';
import { AlertController, ToastController } from '@ionic/angular';
import { AlertOptions, ToastOptions } from '@ionic/core';
@Injectable({ providedIn: 'root' })
export class AppNotification {
/**
* Creates an instance of Notification.
* @param {AlertController} alertCtrl
* @param {ToastController} toastCtrl
* @memberof Notification
*/
constructor(private alertCtrl: AlertController, private toastCtrl: ToastController) { }
/**
* 对话框
*
* @param {string} title
* @param {string} [message]
* @memberof Notification
*/
public async alert(title: string, message?: string, config: AlertOptions = {}): Promise<void> {
const alert = await this.alertCtrl.create({
header: title,
message,
buttons: ['确认'],
...config
});
alert.present();
}
/**
* 对话框
*
* @param {string} title
* @param {string} [message]
* @returns {Promise<boolean>}
* @memberof Notification
*/
public async confirm(title: string, message?: string, config: AlertOptions = {}): Promise<boolean> {
const alert = await this.alertCtrl.create({
header: title,
message,
buttons: [
{
text: '取消',
role: 'cancel',
cssClass: 'secondary'
},
{
text: '确认',
role: 'OK'
}
],
...config
});
alert.present();
const res = await alert.onWillDismiss();
return Object.is(res.role, 'OK');
}
/**
* 提示信息
*
* @param {string} message
* @param {string} [type='light']
* @param {('top' | 'bottom' | 'middle')} [position='top']
* @returns {Promise<void>}
* @memberof Notification
*/
public async info(message: string, type: string = 'light', position: 'top' | 'bottom' | 'middle' = 'top', config: ToastOptions = {}): Promise<void> {
const toast = await this.toastCtrl.create({
message,
position,
duration: 3000,
color: type,
...config
});
toast.present();
}
/**
* 提示信息
*
* @param {string} message
* @param {('top' | 'bottom' | 'middle')} [position='top']
* @returns {Promise<void>}
* @memberof Notification
*/
public warning(message: string, position?: 'top' | 'bottom' | 'middle', config?: ToastOptions): Promise<void> {
return this.info(message, 'warning', position, config);
}
/**
* 成功提示
*
* @param {string} message
* @param {('top' | 'bottom' | 'middle')} [position='top']
* @returns {Promise<void>}
* @memberof Notification
*/
public success(message: string, position?: 'top' | 'bottom' | 'middle', config?: ToastOptions): Promise<void> {
return this.info(message, 'success', position, config);
}
/**
* 错误提示
*
* @param {string} message
* @param {('top' | 'bottom' | 'middle')} [position='top']
* @returns {Promise<void>}
* @memberof Notification
*/
public error(message: string, position?: 'top' | 'bottom' | 'middle', config?: ToastOptions): Promise<void> {
return this.info(message, 'danger', position, config);
}
/**
* Ionic 对话框
*
* @returns {AlertController}
* @memberof Notification
*/
public getAlertCtrl(): AlertController {
return this.alertCtrl;
}
/**
* Ionic 提示框
*
* @returns {ToastController}
* @memberof Notification
*/
public getToastCtrl(): ToastController {
return this.toastCtrl;
}
}
\ No newline at end of file
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { AppThemeConfig } from 'src/theme/app-theme-config';
import { App } from './App';
@Injectable({
providedIn: 'root'
})
export class SettingsService {
/**
* 主题中转对象
*/
private theme: BehaviorSubject <string>;
constructor(private $app:App) {
let tempTheme:any;
let appTheme = localStorage.getItem('app-theme');
if (appTheme) {
tempTheme = appTheme;
} else {
tempTheme = 'default';
}
if(!this.theme){
this.theme = new BehaviorSubject(tempTheme);
}
this.setActiveTheme(tempTheme);
}
/**
* 设置主题
* @param val 主题标识
*/
public setActiveTheme(val){
localStorage.setItem('app-theme',val);
document.getElementsByTagName('html')[0].className = val;
this.theme.next(val);
}
/**
* 监听主题变化
*/
public getActiveTheme() {
return this.theme.asObservable();
}
/**
* 切换主题
*/
public async changeTheme(){
let appTheme = localStorage.getItem('app-theme');
const result: string = await this.$app.openActionSheet({ items: AppThemeConfig });
if (!Object.is(result, appTheme)) {
this.setActiveTheme(result);
}
}
}
import { Injectable } from '@angular/core';
import { AppEnvironment } from '../../environments/AppEnvironment';
import { CodeItem } from '@global/interface/CodeItem';
import { Http } from './Http';
@Injectable({ providedIn: 'root' })
export class CodeList {
private codelistMap:Map<string,any> =new Map<string,any>();
constructor(private $http:Http) {
}
/**
* 初始化代码表
*/
public initCodelist():Promise<any>{
return new Promise((resolve: any, reject: any) =>{
if(this.codelistMap.size === 0){
this.$http.post(`${AppEnvironment.AppName.toLocaleLowerCase()}/app/codelist/getall`).then((response:any) =>{
if(response){
response.forEach((element:any) => {
let target:any ={items:[]};
Object.assign(target,element);
this.setCodeItem(element.srfkey,target);
});
resolve(true);
}else{
reject(false);
console.log('代码表加载失败');
}
})
}else{
resolve(true);
}
})
}
public getCodeItemByTag(srfkey:string){
return this.codelistMap.get(srfkey);
}
public setCodeItem(srfkey:string,codeitem:any){
this.codelistMap.set(srfkey,codeitem);
}
}
import { Injectable } from "@angular/core";
import {
HttpErrorResponse,
HttpEvent,
HttpHandler,
HttpInterceptor,
HttpRequest,
HttpResponse
} from "@angular/common/http";
import { Observable, of, throwError } from "rxjs";
import { catchError } from "rxjs/internal/operators";
import { App } from './App';
import { NavController } from '@ionic/angular';
import { AppEnvironment } from 'src/environments/AppEnvironment';
@Injectable()
export default class Interceptors implements HttpInterceptor {
constructor(private $navCtrl: NavController, private $app: App) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (this.$app.getLoginKey()) {
let newReq: any;
//默认登陆方式 远程登录
if (Object.is(AppEnvironment.LoginModel, 'default')) {
newReq = req.clone({ url: req.url, headers: req.headers.set("loginkey", `${this.$app.getLoginKey()}`) });
} else {
newReq = req.clone({ url: req.url, headers: req.headers.set("Authorization", `Bearer ${this.$app.getLoginKey()}`) });
}
// if (req.body) {
// let tempdata= req.body;
// Object.keys(tempdata).forEach((item: any) => {
// if (tempdata[item] && typeof tempdata[item] !== 'string') {
// tempdata[item] = JSON.stringify(tempdata[item]);
// }
// });
// newReq.clone({body:tempdata});
// }
return next.handle(newReq).pipe(
catchError((err: HttpErrorResponse) => this.handleData(err))
);
} else {
return next.handle(req).pipe(
catchError((err: HttpErrorResponse) => this.handleData(err))
);
}
}
private handleData(
event: HttpResponse<any> | HttpErrorResponse,
): Observable<any> {
// 业务处理:一些通用操作
switch (event.status) {
case 401:
console.log('not login');
this.$navCtrl.navigateRoot(this.$app.getLoginPage());
//return of(event);
return Observable.create(event);
break;
default:
}
return throwError(event);
}
}
\ No newline at end of file
/**
* 日历工具类
*
* @export
* @class AppCalendarUtil
*/
export class AppCalendarUtil {
/**
* 当前时间
*
* @type {Date}
* @memberof AppCalendarUtil
*/
public readonly date: Date = new Date();
/**
* 当前年份
*
* @type {number}
* @memberof AppCalendarUtil
*/
public readonly year: number = this.date.getFullYear();
/**
* 当前月
*
* @type {number}
* @memberof AppCalendarUtil
*/
public readonly month: number = this.date.getMonth();
/**
* 当前天
*
* @type {number}
* @memberof AppCalendarUtil
*/
public readonly day: number = this.date.getDate();
/**
* 月份
*
* @type {string[]}
* @memberof AppCalendarUtil
*/
public readonly months: string[] = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];
/**
* 星期
*
* @type {string[]}
* @memberof AppCalendarUtil
*/
public readonly weeks: string[] = ['日', '一', '二', '三', '四', '五', '六'];
/**
* 获取指定年月的天数对应星期,每七天一个数组
*
* @param {number} [month=this.month] 月,默认为当前月
* @param {number} [year=this.year] 年,默认为当前年
* @memberof AppCalendarUtil
*/
public getDaysCurrentMonth(month: number = this.month, year: number = this.year): Array<any>[] {
const days: Array<any>[] = [];
const week: number = new Date(year, month).getDay();
const lastDate: number = this.getLastDayCurrentMonth(month);
const lastMonthLastDay: number = this.getLastDayCurrentMonth(month - 1);
let day: number = 0;
let nextDay: number = 1;
for (let num: number = 0; num < 6; num++) {
const arr: any[] = [];
for (let i: number = 0; i < 7; i++) {
if ((i >= week || days.length > 0) && day < lastDate) {
day++;
arr.push({
year,
month,
day: day,
date: `${year}-${month + 1}-${day}`
});
} else {
if (day === 0) {
const dayNum: number = lastMonthLastDay - (week - i) + 1;
arr.push({
year: month === 0 ? year - 1 : year,
month: month - 1,
day: dayNum,
date: `${year}-${month - 1 + 1}-${dayNum}`
});
} else {
arr.push({
year: month === 11 ? year + 1 : year,
month: month + 1,
day: nextDay,
date: `${year}-${month + 1 + 1}-${nextDay}`
});
nextDay++;
}
}
}
days.push(arr);
}
return days;
}
/**
* 获取当前月最后一天
*
* @param {number} month 月份
* @param {number} [year=this.year] 年,默认为当前年
* @returns {number}
* @memberof AppCalendarUtil
*/
public getLastDayCurrentMonth(month: number, year: number = this.year): number {
return new Date(year, month + 1, 1 - 1).getDate();
}
}
\ No newline at end of file
/**
* 工具类
*
* @export
* @class co
*/
export class ComUtil {
/**
* 错误提示信息
*
* @static
* @type {string}
* @memberof ComUtil
*/
public static errorInfo: string = '';
/**
* 创建 UUID
*
* @static
* @returns {string}
* @memberof ComUtil
*/
public static createUUID(): string {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}
/**
* 判断是否为一个函数
*
* @static
* @param {*} func
* @returns {boolean}
* @memberof ComUtil
*/
public static isFunction(func: any): boolean {
return typeof (func) === 'function';
}
/**
* 判断条件是否成立
*
* @static
* @param {*} value
* @param {*} op
* @param {*} value2
* @returns {boolean}
* @memberof ComUtil
*/
public static testCond(value: any, op: any, value2: any): boolean {
// 等于操作
if (Object.is(op, 'EQ')) {
return value === value2;
}
// 大于操作
if (Object.is(op, 'GT')) {
const result: number = this.compare(value, value2);
if (result !== undefined && result > 0) {
return true;
} else {
return false;
}
}
// 大于等于操作
if (Object.is(op, 'GTANDEQ')) {
const result: number = this.compare(value, value2);
if (result !== undefined && result >= 0) {
return true;
} else {
return false;
}
}
// 值包含在给定的范围中
if (Object.is(op, 'IN')) {
return this.contains(value, value2);
}
// 不为空判断操作
if (Object.is(op, 'ISNOTNULL')) {
return (value != null && value !== '');
}
// 为空判断操作
if (Object.is(op, 'ISNULL')) {
return (value == null || value === '');
}
// 文本左包含
if (Object.is(op, 'LEFTLIKE')) {
return (value && value2 && (value.toUpperCase().indexOf(value2.toUpperCase()) === 0));
}
// 文本包含
if (Object.is(op, 'LIKE')) {
return (value && value2 && (value.toUpperCase().indexOf(value2.toUpperCase()) !== -1));
}
// 小于操作
if (Object.is(op, 'LT')) {
const result: number = this.compare(value, value2);
if (result !== undefined && result < 0) {
return true;
} else {
return false;
}
}
// 小于等于操作
if (Object.is(op, 'LTANDEQ')) {
const result: number = this.compare(value, value2);
if (result !== undefined && result <= 0) {
return true;
} else {
return false;
}
}
// 不等于操作
if (Object.is(op, 'NOTEQ')) {
return value !== value2;
}
// 值不包含在给定的范围中
if (Object.is(op, 'NOTIN')) {
return !this.contains(value, value2);
}
// 文本右包含
if (Object.is(op, 'RIGHTLIKE')) {
if (!(value && value2)) {
return false;
}
const nPos = value.toUpperCase().indexOf(value2.toUpperCase());
if (nPos === -1) {
return false;
}
return nPos + value2.length === value.length;
}
// 空判断
if (Object.is(op, 'TESTNULL')) {
}
// 自定义包含
if (Object.is(op, 'USERLIKE')) {
}
return false;
}
/**
* 文本包含
*
* @static
* @param {any} value
* @param {any} value2
* @returns {boolean}
* @memberof ComUtil
*/
public static contains(value, value2): boolean {
if (value && value2) {
// 定义一数组
let arr = new Array();
arr = value2.split(',');
// 定义正则表达式的连接符
const S = String.fromCharCode(2);
const reg = new RegExp(S + value + S);
return (reg.test(S + arr.join(S) + S));
}
return false;
}
/**
* 值比较
*
* @static
* @param {*} value
* @param {*} value2
* @returns {number}
* @memberof ComUtil
*/
public static compare(value: any, value2: any): number {
let result;
if (!Object.is(value, '') && !Object.is(value2, '') && !isNaN(value) && !isNaN(value2)) {
result = this.compareNumber(parseFloat(value), parseFloat(value2));
} else if (this.isParseDate(value) && this.isParseDate(value2)) {
result = this.compareDate((new Date(value)).getTime(), (new Date(value2)).getTime());
} else if (value && (typeof (value) === 'boolean' || value instanceof Boolean)) {
result = this.compareBoolean(value, value2);
} else if (value && (typeof (value) === 'string' || value instanceof String)) {
result = this.compareString(value, value2);
}
return result;
}
/**
* 是否是时间
*
* @static
* @param {string} value
* @returns {boolean}
* @memberof ComUtil
*/
public static isParseDate(value: string): boolean {
const time = new Date(value);
if (isNaN(time.getTime())) {
return false;
}
return true;
}
/**
* 时间值比较(毫秒数)
*
* @static
* @param {number} value
* @param {number} value2
* @returns {number}
* @memberof ComUtil
*/
public static compareDate(value: number, value2: number): number {
if (value > value2) {
return 1;
} else if (value < value2) {
return -1;
} else {
return 0;
}
}
/**
* 数值比较
*
* @static
* @param {number} value
* @param {number} value2
* @returns {number}
* @memberof ComUtil
*/
public static compareNumber(value: number, value2: number): number {
if (value > value2) {
return 1;
} else if (value < value2) {
return -1;
} else {
return 0;
}
}
/**
* 字符串比较
*
* @static
* @param {*} value
* @param {*} value2
* @returns {number}
* @memberof ComUtil
*/
public static compareString(value: any, value2: any): number {
return value.localeCompare(value2);
}
/**
* boolean 值比较
*
* @static
* @param {*} value
* @param {*} value2
* @returns {number}
* @memberof ComUtil
*/
public static compareBoolean(value: any, value2: any): number {
if (value === value2) {
return 0;
} else {
return -1;
}
}
/**
*
*
* @static
* @param {*} [o={}]
* @memberof ComUtil
*/
public static processResult(o: any = {}): void {
if (o.url != null && o.url !== '') {
window.location.href = o.url;
}
if (o.code != null && o.code !== '') {
// tslint:disable-next-line:no-eval
eval(o.code);
}
if (o.downloadurl != null && o.downloadurl !== '') {
const downloadurl = this.parseURL2(o.downloadurl, '');
this.download(downloadurl);
}
}
/**
* 下载文件
*
* @static
* @param {string} url
* @memberof ComUtil
*/
public static download(url: string): void {
window.open(url, '_blank');
}
/**
*
*
* @static
* @param {any} url
* @param {any} params
* @returns {string}
* @memberof ComUtil
*/
public static parseURL2(url: string, params: any): string {
let tmpURL;
if (url.indexOf('../../') !== -1) {
tmpURL = url.substring(url.indexOf('../../') + 6, url.length);
} else if (url.indexOf('/') === 0) {
tmpURL = url.substring(url.indexOf('/') + 1, url.length);
} else {
tmpURL = url;
}
if (params) {
return tmpURL + (url.indexOf('?') === -1 ? '?' : '&');
} else {
return tmpURL;
}
}
/**
* 是否是数字
*
* @param {*} num
* @returns {boolean}
* @memberof ComUtil
*/
public static isNumberNaN(num: any): boolean {
return Number.isNaN(num) || num !== num;
}
/**
* 是否未定义
*
* @static
* @param {*} value
* @returns {boolean}
* @memberof ComUtil
*/
public static isUndefined(value: any): boolean {
return typeof value === 'undefined';
}
/**
* 是否为空
*
* @static
* @param {*} value
* @returns {boolean}
* @memberof ComUtil
*/
public static isEmpty(value: any): boolean {
return this.isUndefined(value) || Object.is(value, '') || value === null || value !== value;
}
/**
* 检查属性常规条件
*
* @static
* @param {*} value 属性值
* @param {string} op 检测条件
* @param {*} value2 预定义值
* @param {string} errorInfo 错误信息
* @param {string} paramType 参数类型
* @param {*} form 表单对象
* @param {boolean} primaryModel 是否必须条件
* @returns {boolean}
* @memberof ComUtil
*/
public static checkFieldSimpleRule(value: any, op: string, value2: any, errorInfo: string, paramType: string, form: any, primaryModel: boolean): boolean {
if (Object.is(paramType, 'CURTIME')) {
value2 = `${new Date()}`;
}
if (Object.is(paramType, 'ENTITYFIELD')) {
value2 = value2 ? value2.toLowerCase() : '';
const _value2Field = form.findFormItem(value2);
if (!_value2Field) {
this.errorInfo = `表单项${value2}未配置`;
return true;
}
value2 = _value2Field.getValue();
}
if (this.isEmpty(errorInfo)) {
errorInfo = '内容必须符合值规则';
}
this.errorInfo = errorInfo;
const result = this.testCond(value, op, value2);
if (!result) {
if (primaryModel) {
throw new Error(this.errorInfo);
}
}
return !result;
}
/**
* 检查属性字符长度规则
*
* @static
* @param {*} viewValue
* @param {number} minLength
* @param {boolean} indexOfMin
* @param {number} maxLength
* @param {boolean} indexOfMax
* @param {string} errorInfo
* @param {boolean} primaryModel
* @returns {boolean}
* @memberof ComUtil
*/
public static checkFieldStringLengthRule(viewValue: string, minLength: number, indexOfMin: boolean, maxLength: number, indexOfMax: boolean, errorInfo: string, primaryModel: boolean): boolean {
if (this.isEmpty(errorInfo)) {
this.errorInfo = '内容长度必须符合范围规则';
} else {
this.errorInfo = errorInfo;
}
const isEmpty = ComUtil.isEmpty(viewValue);
if (isEmpty) {
if (primaryModel) {
throw new Error('值为空');
}
this.errorInfo = '值为空';
return true;
}
const viewValueLength: number = viewValue.length;
// 小于等于
if (minLength !== null) {
if (indexOfMin) {
if (viewValueLength < minLength) {
if (primaryModel) {
throw new Error(this.errorInfo);
}
return true;
}
} else {
if (viewValueLength <= minLength) {
if (primaryModel) {
throw new Error(this.errorInfo);
}
return true;
}
}
}
// 大于等于
if (maxLength !== null) {
if (indexOfMax) {
if (viewValueLength > maxLength) {
if (primaryModel) {
throw new Error(this.errorInfo);
}
return true;
}
} else {
if (viewValueLength >= maxLength) {
if (primaryModel) {
throw new Error(this.errorInfo);
}
return true;
}
}
}
this.errorInfo = '';
return false;
}
/**
* 检查属性值正则式规则
*
* @static
* @param {string} viewValue 属性值
* @param {*} strReg 验证正则
* @param {string} errorInfo 错误信息
* @param {boolean} primaryModel 是否关键条件
* @returns {boolean}
* @memberof ComUtil
*/
public static checkFieldRegExRule(viewValue: string, strReg: any, errorInfo: string, primaryModel: boolean): boolean {
if (this.isEmpty(errorInfo)) {
this.errorInfo = '值必须符合正则规则';
} else {
this.errorInfo = errorInfo;
}
const isEmpty = ComUtil.isEmpty(viewValue);
if (isEmpty) {
if (primaryModel) {
throw new Error('值为空');
}
this.errorInfo = '值为空';
return true;
}
const regExp = new RegExp(strReg);
if (!regExp.test(viewValue)) {
if (primaryModel) {
throw new Error(this.errorInfo);
}
return true;
}
this.errorInfo = '';
return false;
}
/**
* 检查属性值范围规则
*
* @static
* @param {string} viewValue 属性值
* @param {*} minNumber 最小数值
* @param {boolean} indexOfMin 是否包含最小数值
* @param {*} maxNumber 最大数值
* @param {boolean} indexOfMax 是否包含最大数值
* @param {string} errorInfo 错误信息
* @param {boolean} primaryModel 是否关键条件
* @returns {boolean}
* @memberof ComUtil
*/
public static checkFieldValueRangeRule(viewValue: string, minNumber: any, indexOfMin: boolean, maxNumber: any, indexOfMax: boolean, errorInfo: string, primaryModel: boolean): boolean {
if (this.isEmpty(errorInfo)) {
this.errorInfo = '值必须符合值范围规则';
} else {
this.errorInfo = errorInfo;
}
const isEmpty = ComUtil.isEmpty(viewValue);
if (isEmpty) {
if (primaryModel) {
throw new Error('值为空');
}
this.errorInfo = '值为空';
return true;
}
const valueFormat = this.checkFieldRegExRule(viewValue, /^-?\d*\.?\d+$/, '', primaryModel);
if (valueFormat) {
return true;
} else {
this.errorInfo = errorInfo;
}
const data = Number.parseFloat(viewValue);
// 小于等于
if (minNumber !== null) {
if (indexOfMin) {
if (data < minNumber) {
if (primaryModel) {
throw new Error(this.errorInfo);
}
return true;
}
} else {
if (data <= minNumber) {
if (primaryModel) {
throw new Error(this.errorInfo);
}
return true;
}
}
}
// //大于等于
if (maxNumber != null) {
if (indexOfMax) {
if (data > maxNumber) {
if (primaryModel) {
throw new Error(this.errorInfo);
}
return true;
}
} else {
if (data >= maxNumber) {
if (primaryModel) {
throw new Error(this.errorInfo);
}
return true;
}
}
}
this.errorInfo = '';
return false;
}
/**
* 检查属性值系统值范围规则 暂时支持正则表达式
*
* @static
* @param {string} viewValue 属性值
* @param {*} strReg 正则
* @param {string} errorInfo 错误信息
* @param {boolean} primaryModel 是否关键条件
* @returns {boolean}
* @memberof ComUtil
*/
public static checkFieldSysValueRule(viewValue: string, strReg: any, errorInfo: string, primaryModel: boolean): boolean {
return this.checkFieldRegExRule(viewValue, strReg, errorInfo, primaryModel);
}
/**
* 将文本格式的xml转换为dom模式
*
* @static
* @param {string} strXml
* @memberof ComUtil
*/
public static parseXML(strXml: string): Document | undefined {
if (strXml) {
return new DOMParser().parseFromString(strXml, 'text/xml');
}
return undefined;
}
/**
* 将xml转换为object对象
*
* @static
* @param {*} node
* @param {*} [obj={}]
* @memberof ComUtil
*/
public static loadXMLNode(node: any, obj: any = {}): void {
if (node && node.attributes) {
const arr: any = node.attributes;
for (let i = 0; i < arr.length; i++) {
let A = arr.item(i).name;
const B = arr.item(i).value;
A = A.toLowerCase();
obj[A] = B;
}
}
}
/**
* 将object转换为xml对象
*
* @static
* @param {any} XML
* @param {any} obj
* @memberof ComUtil
*/
public static saveXMLNode(XML, obj) {
const keys: string[] = Object.keys(obj);
keys.forEach((key: string) => {
const value = obj[key];
if (!value || value instanceof Object || typeof (value) === 'function') {
return;
}
const proValue = value.toString();
if (proValue !== '') {
XML.attrib(key, proValue);
}
});
}
/**
* 格式化矩阵参数
*
* @static
* @param {string} param
* @returns {object}
* @memberof ComUtil
*/
public static formatMatrixParse(param: string): object {
const obj: object = {};
if (obj && typeof (param) === 'string') {
param = decodeURIComponent(param);
const params: string[] = param.split(';');
params.forEach((str: string) => {
if (str.includes('=')) {
const arr: string[] = str.split('=');
if (arr.length >= 2) {
const key: string = arr[0];
if (!Object.is(key, '')) {
const val: string = arr[1];
obj[key] = val;
}
}
}
});
}
return obj;
}
/**
* 转换为矩阵参数
*
* @static
* @param {object} obj
* @returns {string}
* @memberof ComUtil
*/
public static formatMatrixStringify(obj: object): string {
let str: string = '';
if (obj && !(obj instanceof Array) && (obj instanceof Object)) {
const keys: string[] = Object.keys(obj);
keys.forEach((key: string) => {
str += `${key}=${obj[key]};`;
});
}
return encodeURIComponent(str);
}
/**
* 清除用户信息缓存
*
* @static
* @memberof ComUtil
*/
public static clearUserInfo(): void {
window.localStorage.removeItem('userinfo');
window.localStorage.removeItem('srfloginkey');
}
/**
* 处理url参数
*
* @static
* @param {string} param
* @returns {*}
* @memberof Util
*/
public static formatMatrixParse2(param: string): any {
const viewdata: any = { srfparentdata: {} };
const params_arr: string[] = param.split(';');
params_arr.forEach((_data: string, index: number) => {
if ((index === params_arr.length - 1) && _data.indexOf('?') !== -1) {
_data = _data.substr(0, _data.indexOf('?'));
}
const _data_arr: string[] = [..._data.split('=')];
if (Object.is(_data_arr[0], 'srfkey')) {
Object.assign(viewdata, { [_data_arr[0]]: _data_arr[1] });
} else {
Object.assign(viewdata.srfparentdata, { [_data_arr[0]]: _data_arr[1] });
}
});
return viewdata;
}
/**
* 名称格式化
*
* @static
* @param {string} name
* @returns {string}
* @memberof Util
*/
public static srfFilePath2(name: string): string {
if (!name || (name && Object.is(name, ''))) {
throw new Error('名称异常');
}
name = name.replace(/[_]/g, '-');
let state: number = 0;
let _str = '';
const uPattern = /^[A-Z]{1}$/;
const str1 = name.substring(0, 1);
const str2 = name.substring(1)
state = uPattern.test(str1) ? 1 : 0;
_str = `${_str}${str1.toLowerCase()}`;
for (let chr of str2) {
if (uPattern.test(chr)) {
if (state === 1) {
_str = `${_str}${chr.toLowerCase()}`;
} else {
_str = `${_str}-${chr.toLowerCase()}`;
}
state = 1
} else {
_str = `${_str}${chr.toLowerCase()}`;
state = 0
}
}
_str = _str.replace(/---/g, '-').replace(/--/g, '-');
return _str;
}
/**
* 获取当前值类型
*
* @static
* @param {*} obj
* @returns
* @memberof Util
*/
public static typeOf(obj: any):string {
const toString = Object.prototype.toString;
const map: any = {
'[object Boolean]': 'boolean',
'[object Number]': 'number',
'[object String]': 'string',
'[object Function]': 'function',
'[object Array]': 'array',
'[object Date]': 'date',
'[object RegExp]': 'regExp',
'[object Undefined]': 'undefined',
'[object Null]': 'null',
'[object Object]': 'object'
};
return map[toString.call(obj)];
}
}
/**
* xml工具类
*
* @export
* @class XMLWriter
*/
export class XMLWriterUtil {
public XML: any[] = [];
public nodes: any[] = [];
public State = '';
/**
*
*
* @param {any} Str
* @returns
* @memberof XMLWriter
*/
public formatXML(Str) {
if (Str) {
return Str.replace(/&/g, '&amp;').replace(/\"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '&#xA;').replace(/\r/g, '&#xD;');
}
return '';
}
/**
*
*
* @param {any} Name
* @returns
* @memberof XMLWriter
*/
public beginNode(Name) {
if (!Name) {
return;
}
if (this.State === 'beg') {
this.XML.push('>');
}
this.State = 'beg';
this.nodes.push(Name);
this.XML.push('<' + Name);
}
/**
*
*
* @memberof XMLWriter
*/
public endNode() {
if (this.State === 'beg') {
this.XML.push('/>');
this.nodes.pop();
} else if (this.nodes.length > 0) {
this.XML.push('</' + this.nodes.pop() + '>');
}
this.State = '';
}
/**
*
*
* @param {any} Name
* @param {any} Value
* @returns
* @memberof XMLWriter
*/
public attrib(Name, Value) {
if (this.State !== 'beg' || !Name) {
return;
}
this.XML.push(' ' + Name + '="' + this.formatXML(Value) + '"');
}
/**
*
*
* @param {any} Value
* @memberof XMLWriter
*/
public writeString(Value) {
if (this.State === 'beg') {
this.XML.push('>');
}
this.XML.push(this.formatXML(Value));
this.State = '';
}
/**
*
*
* @param {any} Name
* @param {any} Value
* @returns
* @memberof XMLWriter
*/
public node(Name, Value) {
if (!Name) {
return;
}
if (this.State === 'beg') {
this.XML.push('>');
}
this.XML.push((Value === '' || !Value) ? '<' + Name + '/>' : '<' + Name + '>' + this.formatXML(Value) + '</' + Name + '>');
this.State = '';
}
/**
*
*
* @memberof XMLWriter
*/
public close() {
while (this.nodes.length > 0) {
this.endNode();
}
this.State = 'closed';
}
/**
*
*
* @returns
* @memberof XMLWriter
*/
public toString() { return this.XML.join(''); }
}
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Ionic App</title>
<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta name="format-detection" content="telephone=no" />
<meta name="msapplication-tap-highlight" content="no" />
<link rel="icon" type="image/png" href="assets/icon/favicon.png" />
<!-- add to homescreen for ios -->
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
</head>
<body>
<app-root></app-root>
</body>
</html>
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular-devkit/build-angular/plugins/karma')
],
client: {
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, '../coverage'),
reports: ['html', 'lcovonly', 'text-summary'],
fixWebpackSourcePaths: true
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
});
};
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err));
/**
* This file includes polyfills needed by Angular and is loaded before the app.
* You can add your own extra polyfills to this file.
*
* This file is divided into 2 sections:
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
* file.
*
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
*
* Learn more in https://angular.io/guide/browser-support
*/
/***************************************************************************************************
* BROWSER POLYFILLS
*/
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js'; // Run `npm install --save classlist.js`.
/**
* Web Animations `@angular/platform-browser/animations`
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
*/
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
/**
* By default, zone.js will patch all possible macroTask and DomEvents
* user can disable parts of macroTask/DomEvents patch by setting following flags
* because those flags need to be set before `zone.js` being loaded, and webpack
* will put import in the top of bundle, so user need to create a separate file
* in this directory (for example: zone-flags.ts), and put the following flags
* into that file, and then add the following code before importing zone.js.
* import './zone-flags.ts';
*
* The flags allowed in zone-flags.ts are listed here.
*
* The following flags will work for all browsers.
*
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
* (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
*
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
* with the following flag, it will bypass `zone.js` patch for IE/Edge
*
* (window as any).__Zone_enable_cross_context_check = true;
*
*/
import './zone-flags.ts';
/***************************************************************************************************
* Zone JS is required by default for Angular itself.
*/
import 'zone.js/dist/zone'; // Included with Angular CLI.
/***************************************************************************************************
* APPLICATION IMPORTS
*/
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { GlobalModule } from '@global/global.module';
const common: any = [
IonicModule,
CommonModule,
FormsModule,
GlobalModule
];
@NgModule({
imports: [
...common
],
exports: [
...common
]
})
export class ShareModule { }
\ No newline at end of file
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js/dist/zone-testing';
import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';
declare const require: any;
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);
export const AppThemeConfig = [
{text:'默认主题',id:'default'},
{text:'红色主题',id:'red'}
]
\ No newline at end of file
/**
* 应用css变量定义
* ios设计逻辑分辨率:375pt * 667pt
* android设计逻辑分辨率:360pt * 640pt
**/
.default:root {
/** 文字大小 **/
// 导航标题、按钮文字
--app-title-or-button-font-size: 1.06rem;
// 重要文字(如:昵称、列表标题)
--app-important-font-size: 1rem;
// 正常文字
--app-normal-font-size: 0.875rem;
// 辅助性文字
--app-auxiliary-font-size: 0.75rem;
// 次要文字(如:时间、标签)
--app-secondary-font-size: 0.7rem;
/** 颜色 **/
// 主色(导航栏背景、需要强调的文字、按钮背景)
--app-dominant-color: #4784FC; // 主色
--app-dominant-color-rgb: 71, 132, 252;
--app-dominant-color-activate: #00AEC4; // 激活色(如:按钮点击)
--app-dominant-color-activate-rgb: 0, 174, 196;
// 危险色
--app-danger-color: #FF3333;
--app-danger-color-rgb: 255, 51, 51;
--app-danger-color-activate: #EE2E2E;
--app-danger-color-activate-rgb: 238, 46, 46;
// 警告色
--app-warning-color: #FFBD2E;
--app-warning-color-rgb: 255, 189, 46;
--app-warning-color-activate: #F4A700;
--app-warning-color-activate-rgb: 244, 167, 0;
// 成功色
--app-success-color: #10DC60;
--app-success-color-rgb: 16, 220, 96;
--app-success-color-activate: #0EC254;
--app-success-color-activate-rgb: 14, 194, 84;
// 重点文字
--app-important-font-color: #151515;
--app-important-font-color-rgb: 21, 21, 21;
// 正文、主要文字
--app-normal-font-color: #808080;
--app-normal-font-color-rgb: 128, 128, 128;
// 搜索框-背景色
--app-search-background-color: #C9C9CE;
--app-search-background-color-rgb: 201, 201, 206;
// 分割线
--app-dividing-line-color: #D5D5D5;
--app-dividing-line-color-rgb: 213, 213, 213;
// 非重要按钮、icon(如:取消)
--app-unimportant-color: #FAFAFA;
--app-unimportant-color-rgb: 250, 250, 250;
// 按钮文字
--app-button-font-color: #FFFFFF;
--app-button-font-color-rgb: 255, 255, 255;
// 背景色
--app-background-color: #E8E8E8;
--app-background-color-rgb: 232, 232, 232;
// 背景填充色
--app-background-fill-color: #F5F5F5;
--app-background-fill-color-rgb: 245, 245, 245;
// 定义主变量
--app-form-editor-text-align: end;
--app-form-editor-justify-content: flex-end;
}
//修改ionic主色调
:root {
--ion-color-primary: var(--app-dominant-color);
--ion-color-primary-shade: var(--app-dominant-color-activate);
}
// 默认隐藏返回按钮
.app-back-button {
display: none;
}
// 可以回退时显示返回按钮
.can-go-back {
.app-back-button {
display: block;
}
}
// 模态框默认显示返回按钮
ion-modal {
.app-back-button {
display: block;
}
}
.app-view-header {
ion-searchbar {
padding: 0px 10px;
height: 36px;
}
}
.app-view-content {
background-color: var(--app-background-fill-color, --ion-background-color);
ion-refresher {
z-index: 1;
}
.app-view-progress-bar {
position: fixed;
z-index: 1;
}
}
// 表单
.app-form {
.app-form-button {
text-align: center;
}
.app-form-group {
margin-bottom: 2px;
box-shadow: 0 2px 0 var(--app-background-color);
.app-form-group-accordion {
.app-form-group-accordion-panel {
.am-accordion-header {
border-left: 3px solid var(--ion-color-primary, #3880ff);
border-radius: 0px;
}
}
.app-form-group-accordion-panel.non {
.am-accordion-header {
i {
display: none;
}
}
}
}
}
.app-form-item {
--min-height: 36px;
--border-width: 0 0 0.55px 0 !important;
label {
font-size: var(--app-important-font-size);
}
.app-form-item-label {
display: flex;
align-items: center;
app-icon {
height: 22px;
width: 22px;
margin-right: 3px;
}
}
.app-form-item-editor {
display: flex;
justify-content: var(--app-form-editor-justify-content, flex-end);
align-items: center;
width: 100%;
text-align: var(--app-form-editor-text-align, end);
font-size: var(--app-important-font-size);
}
.stars {
font-size: var(--app-important-font-size);
color: red;
}
.app-form-item-input {
text-overflow: ellipsis;
}
}
}
// 搜索表单
.app-search-form.am-accordion-item {
.am-accordion-header {
height: 30px;
line-height: 30px;
font-size: 14px;
.arrow {
top: 7px;
}
}
.app-form {
margin: 0px;
}
.app-search-form-footer {
.app-search-form-footer-buttons {
display: flex;
div {
flex-grow: 1;
padding: 6px;
}
}
}
}
// 门户
.app-view-content.app-portal {
.app-portal-card {
margin: 0 !important;
ion-card {
margin: 0 !important;
}
.app-portal-card-content {
overflow-y: auto;
overflow-x: hidden;
}
}
}
.app-mob-portlet {
.app-portal-card {
margin: 0 !important;
ion-card {
margin: 0 !important;
}
}
}
// 快捷工具栏
.app-quick-toolbar {
display: flex;
.app-quick-toolbar-item {
flex-grow: 1;
margin: 0px 3px;
}
}
// 布局面板
.app-layout-panel {
.app-layout-panel-container-grid,
.app-layout-panel-container-row {
padding: 0px;
height: 100%;
width: 100%;
}
.app-layout-panel-container-col {
height: 100%;
padding: 0px;
}
.app-layout-panel-container-flex {
width: 100%;
height: 100%;
display: flex;
}
}
// 树部件
.app-tree {
.app-treenode {
padding: 6px;
border-bottom: 1px solid #e3e3e3;
}
.app-treectrl-list {
margin-bottom: 0px;
}
}
// 日历视图
.calendar-data-item {
padding-left: 16px;
background: var(--app-background-color);
height: 42px;
color: var(--color);
font-family: var(--ion-font-family, inherit);
font-size: 18px;
display: flex;
align-items: center;
}
// 多数据部件
.app-mdctrl-list {
.app-mdctrl-list-item {
.app-row-header {
font-family: PingFangSC-Regular;
font-size: 15px;
color: #333333;
letter-spacing: 0;
padding-left: 5px;
height: 18px;
}
.app-row-col {
display: flex;
justify-content: flex-start;
align-items: center;
}
.app-col-style {
font-family: PingFangSC-Regular;
font-size: 13px;
color: #999999;
letter-spacing: 0;
height: 24px;
}
.app-col-data {
font-family: PingFangSC-Regular;
font-size: 14px;
color: #666666;
letter-spacing: 0;
}
.app-mdctrl-list-item-end {
height: 100%;
padding: 10px 0px;
font-size: var(--app-secondary-font-size, 0.7rem);
p {
color: var(--ion-color-step-400, #999);
}
}
}
}
.app-mob-card {
padding: 2px;
.sc-ion-card-ios-h {
margin-left: 0;
margin-right: 0;
margin-top: 0;
margin-bottom: 12px;
border-radius: 0;
}
}
.app-portal-card {
.sc-ion-card-ios-h {
-webkit-margin-start: 0;
margin-inline-start: 0;
-webkit-margin-end: 0;
margin-inline-end: 0;
}
.sc-ion-card-ios-h {
margin-left: 0;
margin-right: 0;
margin-top: 0;
margin-bottom: 0;
border-radius: 0;
}
.app-portal-card-header {
padding: 5px;
.app-portal-card-title {
font-size: 20px;
}
}
.app-portal-card-content {
padding: 5px;
font-size: 16px;
}
}
.sc-ion-searchbar-ios-h {
height: 36px;
}
.list-ios {
margin-bottom: 0px;
}
.list-md {
padding-top: 0px;
padding-bottom: 0px;
}
//多表单部件
.app-medit-view-panel-card {
margin: 0 0 5px 0;
border-radius: 0;
}
.app-view-embedded {
display: flex;
justify-content: space-between;
align-items: center;
padding: 4px 16px;
font-size: 16px;
font-weight: bold;
color: #f5f5f5;
background: var(--app-dominant-color);
div {
height: 100%;
display: flex;
align-items: center;
}
.app-view-embedded-icon {
font-size: 32px;
font-weight: bolder;
}
}
//视图级
.app-view {
width: 100%;
height: 100%;
.app-view-body {
width: 100%;
height: 100%;
overflow-x: hidden;
overflow-y: auto;
background: #f9f7f7;
}
}
//视图头部样式
.app-view-header {
position: relative;
.app-view-title {
text-align: center;
}
.app-toolbar-left-buttons {
position: absolute;
// top: 25%;
left: 0;
}
.app-toolbar-right-buttons {
position: absolute;
// top: 25%;
right: 0;
}
}
\ No newline at end of file
/**
* 应用css变量定义
* ios设计逻辑分辨率:375pt * 667pt
* android设计逻辑分辨率:360pt * 640pt
**/
.red:root {
/** 文字大小 **/
// 导航标题、按钮文字
--app-title-or-button-font-size: 1.06rem;
// 重要文字(如:昵称、列表标题)
--app-important-font-size: 1rem;
// 正常文字
--app-normal-font-size: 0.875rem;
// 辅助性文字
--app-auxiliary-font-size: 0.75rem;
// 次要文字(如:时间、标签)
--app-secondary-font-size: 0.7rem;
/** 颜色 **/
// 主色(导航栏背景、需要强调的文字、按钮背景)
--app-dominant-color:#FF3333; // 主色
--app-dominant-color-rgb: 71, 132, 252;
--app-dominant-color-activate: #EE2E2E; // 激活色(如:按钮点击)
--app-dominant-color-activate-rgb: 0, 174, 196;
// 危险色
--app-danger-color: #FF3333;
--app-danger-color-rgb: 255, 51, 51;
--app-danger-color-activate: #EE2E2E;
--app-danger-color-activate-rgb: 238, 46, 46;
// 警告色
--app-warning-color: #FFBD2E;
--app-warning-color-rgb: 255, 189, 46;
--app-warning-color-activate: #F4A700;
--app-warning-color-activate-rgb: 244, 167, 0;
// 成功色
--app-success-color: #10DC60;
--app-success-color-rgb: 16, 220, 96;
--app-success-color-activate: #0EC254;
--app-success-color-activate-rgb: 14, 194, 84;
// 重点文字
--app-important-font-color: #151515;
--app-important-font-color-rgb: 21, 21, 21;
// 正文、主要文字
--app-normal-font-color: #808080;
--app-normal-font-color-rgb: 128, 128, 128;
// 搜索框-背景色
--app-search-background-color: #C9C9CE;
--app-search-background-color-rgb: 201, 201, 206;
// 分割线
--app-dividing-line-color: #D5D5D5;
--app-dividing-line-color-rgb: 213, 213, 213;
// 非重要按钮、icon(如:取消)
--app-unimportant-color: #FAFAFA;
--app-unimportant-color-rgb: 250, 250, 250;
// 按钮文字
--app-button-font-color: #FFFFFF;
--app-button-font-color-rgb: 255, 255, 255;
// 背景色
--app-background-color: #E8E8E8;
--app-background-color-rgb: 232, 232, 232;
// 背景填充色
--app-background-fill-color: #F5F5F5;
--app-background-fill-color-rgb: 245, 245, 245;
// 定义主变量
--app-form-editor-text-align: end;
--app-form-editor-justify-content: flex-end;
}
// Ionic Variables and Theming. For more info, please see:
// http://ionicframework.com/docs/theming/
/** Ionic CSS Variables **/
:root {
/** primary **/
--ion-color-primary: #3880ff;
--ion-color-primary-rgb: 56, 128, 255;
--ion-color-primary-contrast: #ffffff;
--ion-color-primary-contrast-rgb: 255, 255, 255;
--ion-color-primary-shade: #3171e0;
--ion-color-primary-tint: #4c8dff;
/** secondary **/
--ion-color-secondary: #0cd1e8;
--ion-color-secondary-rgb: 12, 209, 232;
--ion-color-secondary-contrast: #ffffff;
--ion-color-secondary-contrast-rgb: 255, 255, 255;
--ion-color-secondary-shade: #0bb8cc;
--ion-color-secondary-tint: #24d6ea;
/** tertiary **/
--ion-color-tertiary: #7044ff;
--ion-color-tertiary-rgb: 112, 68, 255;
--ion-color-tertiary-contrast: #ffffff;
--ion-color-tertiary-contrast-rgb: 255, 255, 255;
--ion-color-tertiary-shade: #633ce0;
--ion-color-tertiary-tint: #7e57ff;
/** success **/
--ion-color-success: #10dc60;
--ion-color-success-rgb: 16, 220, 96;
--ion-color-success-contrast: #ffffff;
--ion-color-success-contrast-rgb: 255, 255, 255;
--ion-color-success-shade: #0ec254;
--ion-color-success-tint: #28e070;
/** warning **/
--ion-color-warning: #ffce00;
--ion-color-warning-rgb: 255, 206, 0;
--ion-color-warning-contrast: #ffffff;
--ion-color-warning-contrast-rgb: 255, 255, 255;
--ion-color-warning-shade: #e0b500;
--ion-color-warning-tint: #ffd31a;
/** danger **/
--ion-color-danger: #f04141;
--ion-color-danger-rgb: 245, 61, 61;
--ion-color-danger-contrast: #ffffff;
--ion-color-danger-contrast-rgb: 255, 255, 255;
--ion-color-danger-shade: #d33939;
--ion-color-danger-tint: #f25454;
/** dark **/
--ion-color-dark: #222428;
--ion-color-dark-rgb: 34, 34, 34;
--ion-color-dark-contrast: #ffffff;
--ion-color-dark-contrast-rgb: 255, 255, 255;
--ion-color-dark-shade: #1e2023;
--ion-color-dark-tint: #383a3e;
/** medium **/
--ion-color-medium: #989aa2;
--ion-color-medium-rgb: 152, 154, 162;
--ion-color-medium-contrast: #ffffff;
--ion-color-medium-contrast-rgb: 255, 255, 255;
--ion-color-medium-shade: #86888f;
--ion-color-medium-tint: #a2a4ab;
/** light **/
--ion-color-light: #f4f5f8;
--ion-color-light-rgb: 244, 244, 244;
--ion-color-light-contrast: #000000;
--ion-color-light-contrast-rgb: 0, 0, 0;
--ion-color-light-shade: #d7d8da;
--ion-color-light-tint: #f5f6f9;
}
@import './app-variables.scss';
@import './red-variables.scss';
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"types": []
},
"exclude": [
"test.ts",
"**/*.spec.ts"
]
}
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/spec",
"types": [
"jasmine",
"node"
]
},
"files": [
"test.ts",
"zone-flags.ts",
"polyfills.ts"
],
"include": [
"**/*.spec.ts",
"**/*.d.ts"
]
}
{
"extends": "../tslint.json",
"rules": {
"directive-selector": [
true,
"attribute",
"app",
"camelCase"
],
"component-selector": [
true,
"element",
"app",
"page",
"kebab-case"
]
}
}
/**
* Prevents Angular change detection from
* running with certain Web Component callbacks
*/
(window as any).__Zone_disable_customElements = true;
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"module": "es2015",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"importHelpers": true,
"target": "es5",
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2018",
"dom"
],
"paths": {
"@pages": ["src/pages"],
"@pages/*": ["src/pages/*"],
"@global":["src/global"],
"@global/*":["src/global/*"],
"@widget":["src/widget"],
"@widget/*":["src/widget/*"],
"@share":["src/share"],
"@share/*":["src/share/*"],
"@engine":["src/engine"],
"@engine/*":["src/engine/*"]
}
}
}
{
"extends": "tslint:recommended",
"rulesDirectory": [
"codelyzer"
],
"rules": {
"array-type": false,
"arrow-parens": false,
"deprecation": {
"severity": "warn"
},
"import-blacklist": [
true,
"rxjs/Rx"
],
"interface-name": false,
"max-classes-per-file": false,
"max-line-length": [
true,
140
],
"member-access": false,
"member-ordering": [
true,
{
"order": [
"static-field",
"instance-field",
"static-method",
"instance-method"
]
}
],
"no-consecutive-blank-lines": false,
"no-console": [
true,
"debug",
"info",
"time",
"timeEnd",
"trace"
],
"no-empty": false,
"no-inferrable-types": [
true,
"ignore-params"
],
"no-non-null-assertion": true,
"no-redundant-jsdoc": true,
"no-switch-case-fall-through": true,
"no-use-before-declare": true,
"no-var-requires": false,
"object-literal-key-quotes": [
true,
"as-needed"
],
"object-literal-sort-keys": false,
"ordered-imports": false,
"quotemark": [
true,
"single"
],
"trailing-comma": false,
"no-output-on-prefix": true,
"use-input-property-decorator": true,
"use-output-property-decorator": true,
"use-host-property-decorator": true,
"no-input-rename": true,
"no-output-rename": true,
"use-life-cycle-interface": true,
"use-pipe-transform-interface": true,
"one-variable-per-declaration": false,
"component-class-suffix": [true, "Page", "Component"],
"directive-class-suffix": true
}
}
因为 它太大了无法显示 源差异 。您可以改为 查看blob
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册