+
-
+
+
+
+
+
diff --git a/projects/client/src/app/pages/salt-oil-sugar/salt-oil-sugar.component.ts b/projects/client/src/app/pages/salt-oil-sugar/salt-oil-sugar.component.ts
index eeeb149..df0cb2d 100644
--- a/projects/client/src/app/pages/salt-oil-sugar/salt-oil-sugar.component.ts
+++ b/projects/client/src/app/pages/salt-oil-sugar/salt-oil-sugar.component.ts
@@ -1,4 +1,4 @@
-import { Component, ElementRef, OnInit, TemplateRef, ViewChild } from '@angular/core'
+import { ChangeDetectorRef, Component, ElementRef, OnInit, TemplateRef, ViewChild } from '@angular/core'
import { FormControl, FormGroup } from '@angular/forms'
import { NzDrawerRef, NzDrawerService } from 'ng-zorro-antd/drawer'
import { AnyObject, FormValidators, OrgDTO, TableListOption, Utils } from '@cdk/public-api'
@@ -7,16 +7,89 @@ import { NzModalService } from 'ng-zorro-antd/modal'
import { lastValueFrom, tap } from 'rxjs'
import { NzMessageService } from 'ng-zorro-antd/message'
import { Router } from '@angular/router'
-import { format, getWeek } from 'date-fns'
+import { endOfWeek, format, getWeek, startOfWeek } from 'date-fns'
import { EChartsType, init } from 'echarts'
+type SugarItemInterface = {
+ day: number
+ endTime: number
+ id: number
+ name: string
+ oilDay: number
+ oilWeek: number
+ saltDay: number
+ saltWeek: number
+ startTime: number
+ sugarDay: number
+ sugarWeek: number
+ vender: number
+}
+
+const trendTextMapping = new Map([
+ ['oilDay', { text: '日均油用量/g' }],
+ ['saltDay', { text: '日均盐用量/g' }],
+ ['sugarDay', { text: '日均糖用量/g' }],
+ ['oilWeek', { text: '油用量(周)/g' }],
+ ['saltWeek', { text: '盐用量(周)/g' }],
+ ['sugarWeek', { text: '糖用量(周)/g' }],
+])
+
+const defaultTrendSeriesObj = {
+ xAxis: [] as string[],
+ day: [
+ {
+ type: 'line',
+ name: 'oilDay',
+ key: 'oilDay',
+ data: [] as number[],
+ },
+ {
+ type: 'line',
+ name: 'saltDay',
+ key: 'saltDay',
+ data: [] as number[],
+ },
+ {
+ type: 'line',
+ name: 'sugarDay',
+ key: 'sugarDay',
+ data: [] as number[],
+ },
+ ],
+ week: [
+ {
+ type: 'line',
+ name: 'oilWeek',
+ key: 'oilWeek',
+ data: [] as number[],
+ },
+ {
+ type: 'line',
+ name: 'saltWeek',
+ key: 'saltWeek',
+ data: [] as number[],
+ },
+ {
+ type: 'line',
+ name: 'sugarWeek',
+ key: 'sugarWeek',
+ data: [] as number[],
+ },
+ ],
+}
+
@Component({
selector: 'app-salt-oil-sugar',
templateUrl: './salt-oil-sugar.component.html',
styleUrls: ['./salt-oil-sugar.component.less'],
})
export class SaltOilSugarComponent {
- constructor(private api: ApiService, private modal: NzModalService, private msg: NzMessageService) {}
+ constructor(
+ private api: ApiService,
+ private modal: NzModalService,
+ private msg: NzMessageService,
+ private cdr: ChangeDetectorRef,
+ ) {}
globalEnum = this.api.globalEnum
@@ -41,9 +114,10 @@ export class SaltOilSugarComponent {
public recordForm = new FormGroup({
week: new FormControl('', [FormValidators.required('请选择周')]),
day: new FormControl(5, [FormValidators.required('请选择供餐天数')]),
- sugar: new FormControl('', []),
- oil: new FormControl('', []),
- salt: new FormControl('', []),
+ sugarWeek: new FormControl('', []),
+ id: new FormControl('', []),
+ oilWeek: new FormControl('', []),
+ saltWeek: new FormControl('', []),
})
startTime: Date | null = null
@@ -64,12 +138,11 @@ export class SaltOilSugarComponent {
this.tableList.scroll = { x: '900px' }
this.tableList = this.tableList.setColumns([
{ key: 'name', title: '周' },
-
- { key: 'meals', title: '日期' },
- { key: 'month', title: '供餐天数' },
- { key: 'day', title: '糖用量(周)/日均用量' },
- { key: 'status', title: '油用量(周)/日均用量' },
- { key: 'modify', title: '盐用量(周)/日均用量' },
+ { key: 'startTime', title: '日期' },
+ { key: 'day', title: '供餐天数' },
+ { key: 'sugarWeek', title: '糖用量(周)/日均用量' },
+ { key: 'oilWeek', title: '油用量(周)/日均用量' },
+ { key: 'saltWeek', title: '盐用量(周)/日均用量' },
])
this.tableList = this.tableList.setOptions([
@@ -87,24 +160,54 @@ export class SaltOilSugarComponent {
])
}
- fetchData(query: AnyObject, pager: AnyObject) {
- return this.api.getSaltOilSugarPage(pager, query).pipe()
+ fetchData(p: AnyObject, q: AnyObject) {
+ const range = q['date']
+ if (Array.isArray(range)) {
+ if (range[0]) {
+ q['startTime'] = format(range[0], 'yyyy-MM-dd')
+ }
+ if (range[1]) {
+ q['endTime'] = format(range[1], 'yyyy-MM-dd')
+ }
+ }
+ return this.api.getSaltOilSugarPage(p, q).pipe()
+ }
+
+ getWeekRange(date: Date | string) {
+ if (!(date instanceof Date)) {
+ date = new Date(date)
+ }
+
+ const startTime = format(startOfWeek(date, { weekStartsOn: 1 }), 'yyyy-MM-dd')
+ const endTime = format(endOfWeek(date, { weekStartsOn: 1 }), 'yyyy-MM-dd')
+
+ return {
+ startTime,
+ endTime,
+ }
}
openModal(record?: any) {
+ if (record) {
+ const week = new Date(record['startTime'])
+ this.recordForm.patchValue({ ...record, week })
+ }
this.modal.create({
nzTitle: record ? '编辑记录' : '新增记录',
nzContent: this.formTpl,
+ nzOnCancel: this.handleCancel.bind(this),
nzOnOk: async () => {
if (Utils.validateFormGroup(this.recordForm)) {
const res = await lastValueFrom(
this.api.saveSaltOilSugar({
...this.recordForm.value,
- week: format(this.recordForm.value.week as unknown as Date, 'yyyy-ww'),
+ ...this.getWeekRange(this.recordForm.value.week!),
}),
)
this.msg.success(res.desc)
this.tableList.run()
+ this.handleCancel()
+ return true
}
return false
@@ -112,6 +215,12 @@ export class SaltOilSugarComponent {
})
}
+ handleCancel() {
+ this.recordForm.reset({
+ day: 5,
+ })
+ }
+
deleteItem({ id }: any) {
this.modal.confirm({
nzTitle: '警告',
@@ -125,7 +234,50 @@ export class SaltOilSugarComponent {
})
}
+ thisYearTrend: SugarItemInterface[] = []
+
+ trendSeriesObj = defaultTrendSeriesObj
+
+ trendType: 'day' | 'week' = 'day'
+
+ onTrendTypeChange(idx: number) {
+ this.trendType = idx === 0 ? 'day' : 'week'
+ this.genEchart()
+ }
+
trend() {
+ this.trendType = 'day'
+ this.trendSeriesObj = JSON.parse(JSON.stringify(defaultTrendSeriesObj))
+ this.fetchData({ pageNo: 0, pageSize: 60 }, { week: [] }).subscribe((res) => {
+ this.thisYearTrend = res.body.content
+ this.thisYearTrend
+ .sort((a, b) => a.endTime - b.endTime)
+ .forEach((i) => {
+ this.trendSeriesObj.xAxis.push(i.name)
+ this.trendSeriesObj.day.forEach((day) => {
+ day.data.push(i[day.key as keyof SugarItemInterface] as number)
+ day.name = trendTextMapping.get(day.key)!.text
+ //@ts-ignore
+ day.encode = {
+ x: 'category',
+ y: day.key,
+ }
+ })
+ this.trendSeriesObj.week.forEach((week) => {
+ week.data.push(i[week.key as keyof SugarItemInterface] as number)
+ week.name = trendTextMapping.get(week.key)!.text
+ //@ts-ignore
+ week.encode = {
+ x: 'category',
+ y: week.key,
+ }
+ })
+ })
+ this.cdr.markForCheck()
+ setTimeout(() => {
+ this.genEchart()
+ })
+ })
this.modal.create({
nzTitle: '糖油盐趋势',
nzContent: this.trendTpl,
@@ -134,30 +286,58 @@ export class SaltOilSugarComponent {
})
}
- saveToImage() {}
-
genEchart() {
- // const xAxis: string[] = Object.keys(this.suger['oil']).map((i: any) => weekdayMap[i])
- // const series: any[] = []
- // Object.entries(this.suger).forEach(([k, v]) => {
- // if (k !== 'crow') {
- // series.push({
- // type: 'line',
- // name: sugerMap.get(k),
- // data: Object.values(v as any),
- // })
- // }
- // })
- // const option = {
- // legend: {},
- // tooltip: { trigger: 'axis' },
- // xAxis: { type: 'category', data: xAxis },
- // yAxis: {},
- // series,
- // }
- // if (!this.sugerRef) {
- // this.sugerRef = init(this.trendElementTpl.nativeElement)
- // }
- // this.sugerRef.setOption(option)
+ const option = {
+ color: ['#1191ff', '#facd0c', '#2bc35b'],
+ legend: {},
+ tooltip: {
+ trigger: 'axis',
+ // formatter: function (v: any[]) {
+ // return v.map((i) => `${trendTextMapping.get(i.seriesName)?.text ?? ''}:${i.data}`).join('
')
+ // },
+ },
+ xAxis: { type: 'category', data: this.trendSeriesObj.xAxis },
+ yAxis: {},
+ series: this.trendSeriesObj[this.trendType],
+ }
+ if (this.sugerRef) {
+ this.sugerRef.dispose()
+ }
+ if (this.trendElementTpl?.nativeElement) {
+ this.sugerRef = init(this.trendElementTpl.nativeElement)
+ this.sugerRef.setOption(option)
+ }
+ }
+
+ saveToImage() {
+ const echart = this.sugerRef
+ if (!echart) {
+ this.msg.error('没有找到趋势图')
+ return
+ }
+ const base64String = echart.getDataURL()
+ const filename = `${this.trendType === 'day' ? '日均用量' : '周用量'}_${Date.now()}.png`
+ const byteString = atob(base64String.split(',')[1])
+ const mimeString = base64String.split(',')[0].split(':')[1].split(';')[0]
+ const ab = new ArrayBuffer(byteString.length)
+ const ia = new Uint8Array(ab)
+
+ for (let i = 0; i < byteString.length; i++) {
+ ia[i] = byteString.charCodeAt(i)
+ }
+
+ const blob = new Blob([ab], { type: mimeString })
+ const url = URL.createObjectURL(blob)
+
+ const link = document.createElement('a')
+ link.href = url
+ link.download = filename
+ document.body.appendChild(link)
+ link.click()
+
+ setTimeout(() => {
+ document.body.removeChild(link)
+ URL.revokeObjectURL(url)
+ }, 0)
}
}
diff --git a/projects/client/src/assets/k-icon/sugar.svg b/projects/client/src/assets/k-icon/sugar.svg
new file mode 100644
index 0000000..d699fcf
--- /dev/null
+++ b/projects/client/src/assets/k-icon/sugar.svg
@@ -0,0 +1 @@
+
\ No newline at end of file