From 04073709db17457d2ea8152db322be5e4e75fd84 Mon Sep 17 00:00:00 2001
From: Sum1Dream <418471657@qq.com>
Date: Mon, 23 May 2022 09:27:06 +0800
Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BF=AE=E6=94=B9=E8=87=AA?=
=?UTF-8?q?=E5=BB=BA=E7=AB=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/app/admin/index/test/test.component.html | 30 +++
src/app/admin/index/test/test.component.scss | 0
src/app/admin/index/test/test.component.ts | 71 ++++++
.../oli-gun/oli-gun.component.html | 1 +
.../oli-gun/oli-gun.component.scss | 0
.../oli-gun/oli-gun.component.spec.ts | 25 ++
.../oli-gun/oli-gun.component.ts | 15 ++
.../merchant-store/oli/oli.component.html | 149 +++++++++++
.../merchant-store/oli/oli.component.scss | 0
.../admin/merchant-store/oli/oli.component.ts | 213 ++++++++++++++++
.../oil-station-order.component.html | 141 +++++++++++
.../oil-station-order.component.scss | 0
.../oil-station-order.component.ts | 140 ++++++++++
src/app/pipes/store/oil-type.pipe.ts | 18 ++
src/app/services/websocket.service.ts | 239 ++++++++++++++++++
15 files changed, 1042 insertions(+)
create mode 100644 src/app/admin/index/test/test.component.html
create mode 100644 src/app/admin/index/test/test.component.scss
create mode 100644 src/app/admin/index/test/test.component.ts
create mode 100644 src/app/admin/merchant-store/oli-gun/oli-gun.component.html
create mode 100644 src/app/admin/merchant-store/oli-gun/oli-gun.component.scss
create mode 100644 src/app/admin/merchant-store/oli-gun/oli-gun.component.spec.ts
create mode 100644 src/app/admin/merchant-store/oli-gun/oli-gun.component.ts
create mode 100644 src/app/admin/merchant-store/oli/oli.component.html
create mode 100644 src/app/admin/merchant-store/oli/oli.component.scss
create mode 100644 src/app/admin/merchant-store/oli/oli.component.ts
create mode 100644 src/app/admin/order/oil-station-order/oil-station-order.component.html
create mode 100644 src/app/admin/order/oil-station-order/oil-station-order.component.scss
create mode 100644 src/app/admin/order/oil-station-order/oil-station-order.component.ts
create mode 100644 src/app/pipes/store/oil-type.pipe.ts
create mode 100644 src/app/services/websocket.service.ts
diff --git a/src/app/admin/index/test/test.component.html b/src/app/admin/index/test/test.component.html
new file mode 100644
index 0000000..559660c
--- /dev/null
+++ b/src/app/admin/index/test/test.component.html
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/admin/index/test/test.component.scss b/src/app/admin/index/test/test.component.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/admin/index/test/test.component.ts b/src/app/admin/index/test/test.component.ts
new file mode 100644
index 0000000..69f906f
--- /dev/null
+++ b/src/app/admin/index/test/test.component.ts
@@ -0,0 +1,71 @@
+import { Component, OnInit } from '@angular/core';
+import {ActivatedRoute} from '_@angular_router@9.0.7@@angular/router';
+import {Params} from '@angular/router';
+import {WebsocketService} from '../../../services/websocket.service';
+
+export enum SEND_TYPE {
+ ALL = 'all',
+ SINGLE = 'single'
+}
+@Component({
+ selector: 'app-test',
+ templateUrl: './test.component.html',
+ styleUrls: ['./test.component.scss']
+})
+export class TestComponent implements OnInit {
+
+ messages = []; // 消息列表
+ message; // 发送的消息内容
+ error: any; // 异常信息
+ completed = false; // 发送完成
+ type = SEND_TYPE.ALL; // 默认类型发送给所有人
+ users = []; // 登陆的用户
+ sendToUser; // 需要发送消息的用户
+ currentUser; // 当前用户
+
+ constructor(
+ private webSocketService: WebsocketService,
+ private activatedRoute: ActivatedRoute
+ ) {
+
+ this.activatedRoute.queryParams.subscribe(queryParams => {
+ console.log(queryParams.id);
+ this.currentUser = queryParams.id;
+ });
+ }
+
+ ngOnInit(): void {
+ console.log(this.currentUser);
+ // 连接websocket
+ // this.webSocketService.connect(`ws://139.159.177.244:9302/brest/WebSocket/` + this.currentUser);
+ // 接收消息
+ this.webSocketService.messageSubject.subscribe(
+ data => {
+ // 如果是用户登陆,则添加到登陆列表中
+ if (data.users) {
+ this.users = data.users;
+ } else {
+ // 否则添加到消息列表
+ this.messages.push(data.msg);
+ }
+ },
+ err => this.error = err,
+ () => this.completed = true
+ );
+ }
+
+ // send() {
+ // // 创建消息对象
+ // const msg = {
+ // msg: this.message, // 消息内容
+ // type: this.type === SEND_TYPE.ALL ? SEND_TYPE.ALL : SEND_TYPE.SINGLE, // 类型
+ // to: this.type === SEND_TYPE.SINGLE ? this.sendToUser : undefined // 要发送的对象
+ // };
+ // // 发送
+ // this.webSocketService.sendMessage(JSON.stringify(msg));
+ // // 发送完成,情况message内容
+ // this.message = '';
+ // }
+
+
+}
diff --git a/src/app/admin/merchant-store/oli-gun/oli-gun.component.html b/src/app/admin/merchant-store/oli-gun/oli-gun.component.html
new file mode 100644
index 0000000..396d8da
--- /dev/null
+++ b/src/app/admin/merchant-store/oli-gun/oli-gun.component.html
@@ -0,0 +1 @@
+
oli-gun works!
diff --git a/src/app/admin/merchant-store/oli-gun/oli-gun.component.scss b/src/app/admin/merchant-store/oli-gun/oli-gun.component.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/admin/merchant-store/oli-gun/oli-gun.component.spec.ts b/src/app/admin/merchant-store/oli-gun/oli-gun.component.spec.ts
new file mode 100644
index 0000000..358df11
--- /dev/null
+++ b/src/app/admin/merchant-store/oli-gun/oli-gun.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { OliGunComponent } from './oli-gun.component';
+
+describe('OliGunComponent', () => {
+ let component: OliGunComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ OliGunComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(OliGunComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/admin/merchant-store/oli-gun/oli-gun.component.ts b/src/app/admin/merchant-store/oli-gun/oli-gun.component.ts
new file mode 100644
index 0000000..664f9f6
--- /dev/null
+++ b/src/app/admin/merchant-store/oli-gun/oli-gun.component.ts
@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+ selector: 'app-oli-gun',
+ templateUrl: './oli-gun.component.html',
+ styleUrls: ['./oli-gun.component.scss']
+})
+export class OliGunComponent implements OnInit {
+
+ constructor() { }
+
+ ngOnInit(): void {
+ }
+
+}
diff --git a/src/app/admin/merchant-store/oli/oli.component.html b/src/app/admin/merchant-store/oli/oli.component.html
new file mode 100644
index 0000000..fb3e56c
--- /dev/null
+++ b/src/app/admin/merchant-store/oli/oli.component.html
@@ -0,0 +1,149 @@
+
+
+
+
+
+
+
共计 {{total}} 条数据
+
+
+
+
+
+
+
+ 编号 |
+ 油品类型 |
+ 油品 |
+ 国标价 |
+ 油站价 |
+ 优惠价 |
+ 优惠幅度 |
+ 操作 |
+
+
+
+
+ {{i + 1}} |
+ {{data.oilTypeName}} |
+ {{data.oilNoName}} |
+ {{data.priceOfficial == null ? '暂无' : '¥' + data.priceOfficial}} |
+ {{data.priceGun == null ? '暂无' : '¥' + data.priceGun}} |
+ {{data.priceVip == null ? '暂无' : '¥' + data.priceVip}} |
+ {{data.preferentialMargin == null ? '暂无' : '¥' + data.preferentialMargin}} |
+
+ 查看油枪
+
+ 配置油枪
+
+ 删除
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 序号 |
+ 油枪号 |
+ 油号类型 |
+ 油号 |
+ 操作 |
+
+
+
+
+ {{ i + 1}} |
+ {{data.gunNo}} |
+ {{data.oilTypeName}} |
+ {{data.oilNo}} |
+
+ 删除
+ |
+
+
+
+
+
+
+
+
+
diff --git a/src/app/admin/merchant-store/oli/oli.component.scss b/src/app/admin/merchant-store/oli/oli.component.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/admin/merchant-store/oli/oli.component.ts b/src/app/admin/merchant-store/oli/oli.component.ts
new file mode 100644
index 0000000..d07563e
--- /dev/null
+++ b/src/app/admin/merchant-store/oli/oli.component.ts
@@ -0,0 +1,213 @@
+import {Component, OnInit} from '@angular/core';
+import {FormBuilder, FormGroup, Validators} from '_@angular_forms@9.0.7@@angular/forms';
+import {environment} from '../../../../environments/environment';
+import {MerchantStoreService} from '../../../services/merchant-store.service';
+import {IconService} from '../../../services/icon.service';
+import {NzMessageService, NzModalService} from '_ng-zorro-antd@9.3.0@ng-zorro-antd';
+import {ActivatedRoute, Router} from '_@angular_router@9.0.7@@angular/router';
+import {CommonsService} from '../../../services/commons.service';
+import {ADMIN_INFO_OBJECT} from '../../../services/local-storage.namespace';
+import {LocalStorageService} from '../../../services/local-storage.service';
+
+@Component({
+ selector: 'app-oli',
+ templateUrl: './oli.component.html',
+ styleUrls: ['./oli.component.scss']
+})
+export class OliComponent implements OnInit {
+ validateForm!: FormGroup;
+ requestData = []; // 列表数据
+ total: number; // 页码
+ pageNum = 1; // 页码
+ pageSize = 10; // 条码
+ loading = true;
+ id = null;
+ name: string;
+ WEB_SERVE_URL = environment.baseUrl;
+ isVisible = false;
+ oilGunVisible = false;
+ oilVisible = false;
+ gasOilType = [];
+ oilGunList = [];
+ oilNo;
+ gunNo;
+ formatterPercent = (value: number) => `¥ ${value == null ? 0 : value}`;
+ parserPercent = (value: string) => value.replace('¥ ', '');
+
+ constructor(
+ private form: FormBuilder,
+ private merchantStore: MerchantStoreService,
+ private iconService: IconService,
+ private message: NzMessageService,
+ private store: LocalStorageService, // 数据请求
+ private router: Router,
+ private fb: FormBuilder,
+ private commonsService: CommonsService,
+ private modal: NzModalService,
+ private activatedRoute: ActivatedRoute,
+ private common: CommonsService
+ ) {
+ }
+
+ ngOnInit(): void {
+ this.init();
+ this.validateForm = this.fb.group({
+ storeId: [this.store.get(ADMIN_INFO_OBJECT)['merchantStore'].id, [Validators.required]],
+ priceGun: [null, [Validators.required]],
+ preferentialMargin: [0],
+
+ });
+ }
+
+ public init(): void {
+ this.commonsService.getDictionary('GAS_OIL_TYPE', data => {
+ this.gasOilType = data['return_data'];
+ });
+ this.getRequest(true, {});
+ }
+
+
+ // 查询列表
+ public getRequest(reset: boolean = false, whereObject: object) {
+
+ this.loading = false;
+ if (reset) {
+ this.pageNum = 1;
+ }
+ whereObject['storeId'] = this.store.get(ADMIN_INFO_OBJECT)['merchantStore'].id;
+ this.merchantStore.getOilPriceListByStore(whereObject, data => {
+ if (data['return_code'] === '000000') {
+ this.requestData = data['return_data'];
+ this.total = data['return_data'].length;
+ } else {
+ this.message.error(data['return_msg']);
+ }
+ });
+
+
+ }
+
+
+ // 是否删除油品
+ public getDelete(oilNo): void {
+ const message = '是否删除油品';
+ this.common.showConfirm(message, data => {
+ if (data) {
+ this.merchantStore.delOilPrice({
+ storeId: this.store.get(ADMIN_INFO_OBJECT)['merchantStore'].id,
+ oilNo: oilNo
+ }, dataReturn => {
+ if (dataReturn['return_code'] === '000000') {
+ this.message.success('操作成功');
+ this.getRequest(false, {});
+ } else {
+ this.message.warning(dataReturn['return_msg']);
+ }
+ });
+ }
+ });
+ }
+
+ // 编辑油品
+ public editGasOilPrice(): void {
+ if (this.oilNo == null) {
+ this.message.error('请选择油品!');
+ return;
+ }
+
+ // tslint:disable-next-line:forin
+ for (const i in this.validateForm.controls) {
+ this.validateForm.controls[i].markAsDirty();
+ this.validateForm.controls[i].updateValueAndValidity();
+ if (this.validateForm.controls[i].errors != null) {
+ this.message.error('必填项不能为空');
+ return;
+ }
+ }
+ if (this.validateForm.value.preferentialMargin == null) {
+ this.validateForm.value.preferentialMargin = 0;
+ }
+ this.validateForm.value.oilNo = this.oilNo;
+ this.merchantStore.editGasOilPrice(this.validateForm.value, data => {
+ if (data['return_code'] === '000000') {
+ this.isVisible = false;
+ this.getRequest(true, {});
+ this.message.success('编辑成功');
+ } else {
+ this.message.warning(data['return_msg']);
+ }
+ });
+ }
+
+ // 获取油站油品价格
+ public getOilPriceDetail(e): void {
+ const whereObject = {
+ storeId: this.store.get(ADMIN_INFO_OBJECT)['merchantStore'].id,
+ oilNo: e
+ };
+ this.merchantStore.getOilPriceDetail(whereObject, data => {
+ if (data['return_code'] === '000000') {
+ this.validateForm.patchValue(data['return_data']);
+ } else {
+ this.message.warning(data['return_msg']);
+ }
+
+ });
+ }
+
+ // 配置油品油枪
+ public getGunNoListByOilPrice(id): void {
+ this.id = id;
+ this.merchantStore.getGunNoListByOilPrice(id , data => {
+ if (data['return_code'] === '000000') {
+ this.oilGunList = data['return_data'];
+ this.oilGunVisible = true;
+ } else {
+ this.message.warning(data['return_msg']);
+ }
+ });
+ }
+
+ // 是否删除油枪列表
+ public delGunNo(id): void {
+ const message = '是否删除油枪';
+ this.common.showConfirm(message, data => {
+ if (data) {
+ this.merchantStore.delGunNo({
+ gunNoId: id
+ }, dataReturn => {
+ if (dataReturn['return_code'] === '000000') {
+ this.message.success('操作成功');
+ this.getGunNoListByOilPrice(this.id);
+ } else {
+ this.message.warning(dataReturn['return_msg']);
+ }
+ });
+ }
+ });
+ }
+
+ // 配置油枪号
+ public addGasOilPrice(): void {
+ if (this.gunNo == null) {
+ this.message.error('请输入油枪号');
+ return;
+ }
+ this.merchantStore.addGasOilPrice({
+ oilPriceId: this.id,
+ gunNo: this.gunNo
+ } , data => {
+ if (data['return_code'] === '000000') {
+ this.message.success('操作成功');
+ this.oilVisible = false;
+ } else {
+ this.message.warning(data['return_msg']);
+ }
+ });
+ }
+
+ public getGasOilPrice(id): void {
+ this.id = id;
+ this.oilVisible = true;
+ }
+}
diff --git a/src/app/admin/order/oil-station-order/oil-station-order.component.html b/src/app/admin/order/oil-station-order/oil-station-order.component.html
new file mode 100644
index 0000000..d2b3f3b
--- /dev/null
+++ b/src/app/admin/order/oil-station-order/oil-station-order.component.html
@@ -0,0 +1,141 @@
+
+
+
+
+
+
+
+
+
+
共计 {{total}} 条数据
+
+
+
+ 编号 |
+ 订单号 |
+ 油站名称 |
+ 油站地址 |
+ 类型 |
+ 油号 |
+ 油枪号 |
+ 油枪价 |
+ 优惠价 |
+ 加油升数 |
+ 创建时间 |
+ 加油金额 |
+ 支付金额 |
+ 优惠金额 |
+ 状态 |
+ 操作 |
+
+
+
+
+ {{i + 1}} |
+ {{data.orderNo}} |
+ {{data.gasName}} |
+ {{data.gasAddress}} |
+ {{data.gasOilType == 1 ? '汽油': '柴油'}} |
+ {{data.gasOilNo}} |
+ {{data.gasGunNo}} |
+ {{data.gasPriceGun}} |
+ {{data.gasPricePreferences}} |
+ {{data.gasOilLiters}} |
+ {{data.createTime | date: 'yyyy-MM-dd HH:mm:ss'}} |
+ {{data.totalPrice}} |
+ {{data.payRealPrice}} |
+ {{data.deductionPrice}} |
+ {{data.status | orderCouponStatus}} |
+
+ 详情
+
+ 退款
+ |
+
+
+
+
+
+
+
+ 退款理由
+
+
+
+
+
+
+
+
+ {{data['gasName']}}
+ {{data['gasAddress']}}
+ {{data['orderNo']}}
+ {{data['gasOilType'] == 1 ? '汽油': '柴油'}}
+ {{data['gasOilNo']}}
+ {{data['gasGunNo']}}
+ {{data['gasPriceGun']}}
+ {{data['gasPricePreferences']}}
+ {{data['gasOilLiters']}}
+ {{data['totalPrice']}}
+ {{data['payRealPrice']}}
+ {{data['deductionPrice']}}
+ {{data['gasDiscount']}}
+ {{data['gasOilSubsidy']}}
+ {{data['gasLitersPreferences']}}
+ {{data['createTime'] | date: 'yyyy-MM-dd HH:mm:ss'}}
+ {{data['status'] | rechargeStatus}}
+ {{data['refundPrice']}}
+ {{data['refundTime'] | date: 'yyyy-MM-dd HH:mm:ss'}}
+ {{data['refundContent']}}
+
+
+
diff --git a/src/app/admin/order/oil-station-order/oil-station-order.component.scss b/src/app/admin/order/oil-station-order/oil-station-order.component.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/admin/order/oil-station-order/oil-station-order.component.ts b/src/app/admin/order/oil-station-order/oil-station-order.component.ts
new file mode 100644
index 0000000..16c010d
--- /dev/null
+++ b/src/app/admin/order/oil-station-order/oil-station-order.component.ts
@@ -0,0 +1,140 @@
+import { Component, OnInit } from '@angular/core';
+import {environment} from '../../../../environments/environment';
+import {FormBuilder, FormGroup} from '_@angular_forms@9.0.7@@angular/forms';
+import {OrderService} from '../../../services/order.service';
+import {IconService} from '../../../services/icon.service';
+import {NzMessageService} from '_ng-zorro-antd@9.3.0@ng-zorro-antd';
+import {Router} from '_@angular_router@9.0.7@@angular/router';
+import {CompanyService} from '../../../services/company.service';
+import {MerchantService} from '../../../services/merchant.service';
+import {LocalStorageService} from '../../../services/local-storage.service';
+import {CommonsService} from '../../../services/commons.service';
+import {WebsocketService} from '../../../services/websocket.service';
+
+@Component({
+ selector: 'app-oil-station-order',
+ templateUrl: './oil-station-order.component.html',
+ styleUrls: ['./oil-station-order.component.scss']
+})
+export class OilStationOrderComponent implements OnInit {
+
+ WEB_SERVE_URL = environment.baseUrl;
+ FILE_URL = environment.imageUrl;
+ searchForm: FormGroup; // 搜索框
+ requestData = []; // 列表数据
+ companyData = []; // 列表数据
+ merchantData = []; // 列表数据
+ data = {}; // 列表数据
+ total: number; // 页码
+ pageNum = 1; // 页码
+ pageSize = 10; // 条码
+ loading = true;
+ id: number; // 订单ID
+ isVisible = false;
+ isVisibleDetail = false;
+ refundContent: string;
+ roleType: number;
+ constructor(
+ private form: FormBuilder,
+ private order: OrderService,
+ private webSocketService: WebsocketService,
+ private iconService: IconService,
+ private message: NzMessageService,
+ private router: Router,
+ private company: CompanyService,
+ private merchant: MerchantService,
+ private store: LocalStorageService, // 数据请求
+ private common: CommonsService
+ ) {
+ }
+
+ ngOnInit(): void {
+ this.init();
+ // 接收消息
+ this.webSocketService.messageSubject.subscribe(
+ data => {
+ console.log(data);
+ this.getRequest(true, this.searchForm.value);
+ },
+ err => console.log(err)
+ );
+ }
+
+ public init(): void {
+ this.searchForm = this.form.group({
+ orderNo: [null],
+ status: [null],
+ });
+ this.getRequest(true, this.searchForm.value);
+ }
+
+ // 查询列表
+ public getRequest(reset: boolean = false, whereObject: object) {
+
+ if (whereObject['payTime'] != null && whereObject['payTime'].length !== 0) {
+ whereObject['payTimeS'] = whereObject['payTime'][0].getTime();
+ whereObject['payTimeE'] = whereObject['payTime'][1].getTime();
+ }
+
+
+ this.loading = false;
+ if (reset) {
+ this.pageNum = 1;
+ }
+ whereObject['pageNum'] = this.pageNum;
+ whereObject['pageSize'] = this.pageSize;
+ this.order.getGasOrderListByOil(whereObject, data => {
+ if (data['return_code'] === '000000') {
+ this.requestData = data['return_data'].list;
+ this.total = data['return_data'].total;
+ } else {
+ this.message.error(data['return_msg']);
+ }
+ });
+ }
+
+ // 重置
+ public resetForm(): void {
+ this.searchForm.reset();
+ }
+
+ showModal(id): void {
+ this.id = id;
+ this.isVisible = true;
+ }
+
+ handleOk(): void {
+ this.common.showConfirm('确认订单是否退款', item => {
+ if (item) {
+ const params = {
+ orderId: this.id ,
+ refundContent: this.refundContent
+ };
+ this.order.refuelingOrderRefund(params, data => {
+ if (data['return_code'] === '000000') {
+ this.getRequest(true, this.searchForm.value);
+ this.isVisible = false;
+ this.message.success('退款成功');
+ } else {
+ this.message.error(data['return_msg']);
+ }
+ });
+ }
+ });
+ }
+
+ handleCancel(): void {
+ this.isVisible = false;
+ }
+
+ getDetail(orderNo: string): void {
+ this.order.getGasOrderDetail(orderNo , data => {
+ if (data['return_code'] === '000000') {
+ this.isVisibleDetail = true;
+ this.data = data['return_data'];
+ } else {
+ this.message.error(data['return_msg']);
+ }
+ });
+ }
+}
diff --git a/src/app/pipes/store/oil-type.pipe.ts b/src/app/pipes/store/oil-type.pipe.ts
new file mode 100644
index 0000000..e878379
--- /dev/null
+++ b/src/app/pipes/store/oil-type.pipe.ts
@@ -0,0 +1,18 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'oilType'
+})
+export class OilTypePipe implements PipeTransform {
+
+ transform(value: number): string {
+ switch (value) {
+ case 1:
+ return '汽油';
+ case 2:
+ return '柴油';
+ case 3:
+ return '天然气';
+ }
+ }
+}
diff --git a/src/app/services/websocket.service.ts b/src/app/services/websocket.service.ts
new file mode 100644
index 0000000..80b6222
--- /dev/null
+++ b/src/app/services/websocket.service.ts
@@ -0,0 +1,239 @@
+import {Component, Injectable} from '@angular/core';
+import {interval, Subject} from 'rxjs';
+import {NzNotificationService} from 'ng-zorro-antd';
+
+@Injectable({
+ providedIn: 'root'
+})
+export class WebsocketService {
+
+ messageSubject; // subject对象,用于发送事件
+ private url; // 默认请求的url
+ private webSocket: WebSocket; // websocket对象
+ connectSuccess = false; // websocket 连接成功
+ period = 60 * 1000 * 10; // 10分钟检查一次
+ serverTimeoutSubscription = null; // 定时检测连接对象
+ reconnectFlag = false; // 重连
+ reconnectPeriod = 5 * 1000; // 重连失败,则5秒钟重连一次
+ reconnectSubscription = null; // 重连订阅对象
+ runTimeSubscription; // 记录运行连接subscription
+ runTimePeriod = 60 * 10000; // 记录运行连接时间
+
+ constructor(private notification: NzNotificationService) {
+ this.messageSubject = new Subject();
+ console.log('开始心跳检测');
+ // 进入程序就进行心跳检测,避免出现开始就连接中断,后续不重连
+ this.heartCheckStart();
+ this.calcRunTime();
+ }
+
+ /**
+ * 发送消息
+ * @author Sum1Dream
+ * @date 2019/1/22
+ * @param message 发送消息
+ */
+ sendMessage(message) {
+ this.webSocket.send(message);
+ }
+
+ /**
+ * 创建新连接
+ * @author Sum1Dream
+ * @date 2019/1/22
+ * @param url 要连接的url
+ */
+ connect(url) {
+ if (!!url) {
+ this.url = url;
+ }
+ // 创建websocket对象
+ this.createWebSocket();
+ }
+
+ /**
+ * 创建连接
+ * @author Sum1Dream
+ * @date 2019/1/22
+ */
+ createWebSocket() {
+ // 如果没有建立过连接,才建立连接并且添加时间监听
+ this.webSocket = new WebSocket(this.url);
+ // 建立连接成功
+ this.webSocket.onopen = (e) => this.onOpen(e);
+ // 接收到消息
+ this.webSocket.onmessage = (e) => this.onMessage(e);
+ // 连接关闭
+ this.webSocket.onclose = (e) => this.onClose(e);
+ // 异常
+ this.webSocket.onerror = (e) => this.onError(e);
+ }
+
+ /**
+ * 连接打开
+ * @author Sum1Dream
+ * @date 2019/1/22
+ * @param e 打开事件
+ */
+ onOpen(e) {
+ console.log('websocket 已连接');
+ // 设置连接成功
+ this.connectSuccess = true;
+ // 如果是重连中
+ if (this.reconnectFlag) {
+ // 1.停止重连
+ this.stopReconnect();
+ // 2.重新开启心跳
+ this.heartCheckStart();
+ // 3.重新开始计算运行时间
+ this.calcRunTime();
+ }
+ }
+
+ /**
+ * 接受到消息
+ * @author Sum1Dream
+ * @date 2019/1/22
+ * @param event 接受消息事件
+ */
+ onMessage(event) {
+ const data = JSON.parse(event.data);
+ // 将接受到的消息发布出去
+ // console.log('接收到消息时间', new Date().getTime());
+ this.notification.success(
+ data['order']['gasName'] + '加油订单',
+ '订单号:' + data['order']['orderNo'] + '
' +
+ '加油金额:' + data['order']['totalPrice'] + '
' +
+ '油号:' + data['order']['gasOilNo'] + '
' +
+ '油枪号:' + data['order']['gasGunNo'] + '
'
+ );
+ const audio = new Audio();
+ audio.src = data['voice'];
+ audio.load();
+ audio.play().then(r => console.log(r));
+ this.messageSubject.next(true);
+ }
+
+ /**
+ * 连接关闭
+ * @author Sum1Dream
+ * @date 2019/1/22
+ */
+ private onClose(e) {
+ console.log('连接关闭', e);
+ this.connectSuccess = false;
+ this.webSocket.close();
+ // 关闭时开始重连
+ this.reconnect();
+ this.stopRunTime();
+ // throw new Error('webSocket connection closed:)');
+ }
+
+ /**
+ * 连接异常
+ * @author Sum1Dream
+ * @date 2019/1/22
+ */
+ private onError(e) {
+ // 出现异常时一定会进onClose,所以只在onClose做一次重连动作
+ console.log('连接异常', e);
+ this.connectSuccess = false;
+ // throw new Error('webSocket connection error:)');
+ }
+
+ /**
+ * 开始重新连接
+ * @author Sum1Dream
+ * @date 2019/1/22
+ */
+ reconnect() {
+ // 如果已重连,则直接return,避免重复连接
+ if (this.connectSuccess) {
+ this.stopReconnect();
+ console.log('已经连接成功,停止重连');
+ return;
+ }
+ // 如果正在连接中,则直接return,避免产生多个轮训事件
+ if (this.reconnectFlag) {
+ console.log('正在重连,直接返回');
+ return;
+ }
+ // 开始重连
+ this.reconnectFlag = true;
+ // 如果没能成功连接,则定时重连
+ this.reconnectSubscription = interval(this.reconnectPeriod).subscribe(async (val) => {
+ console.log(`重连:${val}次`);
+ const url = this.url;
+ // 重新连接
+ this.connect(url);
+ });
+ }
+
+ /**
+ * 停止重连
+ * @author Sum1Dream
+ * @date 2019/1/22
+ */
+ stopReconnect() {
+ // 连接标识置为false
+ this.reconnectFlag = false;
+ // 取消订阅
+ if (typeof this.reconnectSubscription !== 'undefined' && this.reconnectSubscription != null) {
+ this.reconnectSubscription.unsubscribe();
+ }
+ }
+
+ /**
+ * 开始心跳检测
+ * @author Sum1Dream
+ * @date 2019/1/22
+ */
+ heartCheckStart() {
+ this.serverTimeoutSubscription = interval(this.period).subscribe((val) => {
+ // 保持连接状态,重置下
+ if (this.webSocket != null && this.webSocket.readyState === 1) {
+ console.log(val, '连接状态,发送消息保持连接');
+ } else {
+ // 停止心跳
+ this.heartCheckStop();
+ // 开始重连
+ this.reconnect();
+ console.log('连接已断开,重新连接');
+ }
+ });
+ }
+
+ /**
+ * 停止心跳检测
+ * @author Sum1Dream
+ * @date 2019/1/22
+ */
+ heartCheckStop() {
+ // 取消订阅停止心跳
+ if (typeof this.serverTimeoutSubscription !== 'undefined' && this.serverTimeoutSubscription != null) {
+ this.serverTimeoutSubscription.unsubscribe();
+ }
+ }
+
+ /**
+ * 开始计算运行时间
+ * @author Sum1Dream
+ * @date 2019/1/25
+ */
+ calcRunTime() {
+ this.runTimeSubscription = interval(this.runTimePeriod).subscribe(period => {
+ console.log('运行时间', `${period}分钟`);
+ });
+ }
+
+ /**
+ * 停止计算运行时间
+ * @author Sum1Dream
+ * @date 2019/1/25
+ */
+ stopRunTime() {
+ if (typeof this.runTimeSubscription !== 'undefined' && this.runTimeSubscription !== null) {
+ this.runTimeSubscription.unsubscribe();
+ }
+ }
+}