|
|
@@ -12,6 +12,10 @@
|
|
|
<div class="ptw-stats-card__label">作业票分类统计</div>
|
|
|
<Echart :height="220" :options="staticChartOptions" />
|
|
|
</div>
|
|
|
+ <div class="ptw-stats-chart-card">
|
|
|
+ <div class="ptw-stats-card__label">作业票趋势统计</div>
|
|
|
+ <Echart :height="220" :options="timeTrendChartOptions" />
|
|
|
+ </div>
|
|
|
</div>
|
|
|
<div class="bg-white rounded-sm px-2 py-2">
|
|
|
<!-- 搜索工作栏 -->
|
|
|
@@ -584,6 +588,8 @@ type StaticItem = {
|
|
|
sort?: number
|
|
|
}
|
|
|
|
|
|
+type TimeStaticItem = Record<string, number>
|
|
|
+
|
|
|
const queryParams2 = reactive({
|
|
|
pageNo: 1,
|
|
|
pageSize: 10,
|
|
|
@@ -704,6 +710,7 @@ const handleExport = async () => {
|
|
|
const handleDeptNodeClick = async (row) => {
|
|
|
queryParams.deptId = row.id
|
|
|
await getStatic()
|
|
|
+ await getTimeStaticRes()
|
|
|
await getList()
|
|
|
}
|
|
|
|
|
|
@@ -967,6 +974,92 @@ const staticChartOptions = computed<EChartsOption>(() => ({
|
|
|
}
|
|
|
]
|
|
|
}))
|
|
|
+
|
|
|
+const timeTrendDates = computed(() =>
|
|
|
+ Object.keys(timeStaticRes.value || {}).sort((a, b) => new Date(a).getTime() - new Date(b).getTime())
|
|
|
+)
|
|
|
+
|
|
|
+const timeTrendChartOptions = computed<EChartsOption>(() => ({
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis'
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ left: 16,
|
|
|
+ right: 24,
|
|
|
+ top: 24,
|
|
|
+ bottom: 24,
|
|
|
+ containLabel: true
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ data: timeTrendDates.value,
|
|
|
+ boundaryGap: false,
|
|
|
+ axisTick: {
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ axisLine: {
|
|
|
+ lineStyle: {
|
|
|
+ color: '#d9e2ef'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ axisLabel: {
|
|
|
+ color: '#6b7280',
|
|
|
+ fontSize: 12
|
|
|
+ }
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: 'value',
|
|
|
+ minInterval: 1,
|
|
|
+ axisLine: {
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ axisTick: {
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ axisLabel: {
|
|
|
+ color: '#94a3b8',
|
|
|
+ fontSize: 12
|
|
|
+ },
|
|
|
+ splitLine: {
|
|
|
+ lineStyle: {
|
|
|
+ color: '#edf2f7',
|
|
|
+ type: 'dashed'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: 'line',
|
|
|
+ smooth: true,
|
|
|
+ symbol: 'circle',
|
|
|
+ symbolSize: 8,
|
|
|
+ data: timeTrendDates.value.map((date) => Number(timeStaticRes.value?.[date] || 0)),
|
|
|
+ lineStyle: {
|
|
|
+ width: 3,
|
|
|
+ color: '#10b981'
|
|
|
+ },
|
|
|
+ itemStyle: {
|
|
|
+ color: '#10b981',
|
|
|
+ borderColor: '#ffffff',
|
|
|
+ borderWidth: 2
|
|
|
+ },
|
|
|
+ areaStyle: {
|
|
|
+ color: {
|
|
|
+ type: 'linear',
|
|
|
+ x: 0,
|
|
|
+ y: 0,
|
|
|
+ x2: 0,
|
|
|
+ y2: 1,
|
|
|
+ colorStops: [
|
|
|
+ { offset: 0, color: 'rgba(16, 185, 129, 0.32)' },
|
|
|
+ { offset: 1, color: 'rgba(16, 185, 129, 0.04)' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+}))
|
|
|
+
|
|
|
async function getStatic() {
|
|
|
const deptId = queryParams.deptId || userStore.user.deptId
|
|
|
const res = await QHSEPtwApi.getPtwCategory(deptId)
|
|
|
@@ -975,6 +1068,24 @@ async function getStatic() {
|
|
|
: []
|
|
|
}
|
|
|
|
|
|
+let timeStaticRes = ref<TimeStaticItem>({})
|
|
|
+async function getTimeStaticRes() {
|
|
|
+ const deptId = queryParams.deptId || userStore.user.deptId
|
|
|
+ const res = await QHSEPtwApi.getPtwCountByDateRange({
|
|
|
+ createTime: queryParams.createTime,
|
|
|
+ deptId: deptId
|
|
|
+ })
|
|
|
+
|
|
|
+ timeStaticRes.value = res || {}
|
|
|
+}
|
|
|
+
|
|
|
+watch(
|
|
|
+ () => queryParams.createTime,
|
|
|
+ () => {
|
|
|
+ getTimeStaticRes()
|
|
|
+ }
|
|
|
+)
|
|
|
+
|
|
|
onMounted(async () => {
|
|
|
getList()
|
|
|
deptList2.value = handleTree(await DeptApi.getSimpleDeptList())
|
|
|
@@ -982,6 +1093,7 @@ onMounted(async () => {
|
|
|
const users = await getUserProfile()
|
|
|
userInfo.value = users
|
|
|
getStatic()
|
|
|
+ getTimeStaticRes()
|
|
|
})
|
|
|
|
|
|
let personDialogVisible = ref(false)
|
|
|
@@ -1152,7 +1264,7 @@ const handleRadioChange2 = (row: any) => {
|
|
|
<style scoped>
|
|
|
.ptw-stats {
|
|
|
display: grid;
|
|
|
- grid-template-columns: 240px minmax(0, 1fr);
|
|
|
+ grid-template-columns: 240px minmax(0, 1fr) minmax(0, 1fr);
|
|
|
gap: 16px;
|
|
|
}
|
|
|
|