From 1c22b65361d81ef23bd76d0f76a3dce7ef72fd99 Mon Sep 17 00:00:00 2001
From: haoxuan <haoxuan>
Date: 星期二, 31 十月 2023 10:06:56 +0800
Subject: [PATCH] 拉代码
---
src/views/dashboard/components/TaskTabs.vue | 25 +
src/views/dashboard/components/ProcessingInfo.vue | 220 ++++++++++++++++++++
src/api/task.ts | 10
src/views/dashboard/components/ChannelCollapse.vue | 58 ++++
src/views/dashboard/components/CraftInfo.vue | 10
src/views/dashboard/components/PersonInfo.vue | 8
src/components.d.ts | 11
src/stores/tasks.ts | 106 +++++++++
src/api/index.ts | 39 ++
src/api/plc.ts | 6
src/components/DashboardLayout.vue | 40 ++
/dev/null | 87 -------
vite.config.ts | 2
src/views/dashboard/components/TaskInfo.vue | 24 +
14 files changed, 500 insertions(+), 146 deletions(-)
diff --git a/src/api/index.ts b/src/api/index.ts
index 1c5ab52..1517ce2 100644
--- a/src/api/index.ts
+++ b/src/api/index.ts
@@ -1,5 +1,6 @@
import { request } from '@/common/utils'
-import type { TasksResponse } from './task'
+import type { TasksGroupByChannel } from './task'
+import type { PLCResponse } from './plc'
export interface BaseResponse<T = any> {
code: number
@@ -7,16 +8,38 @@
msg: string
}
+export interface TaskListParams {
+ /** 1鏈畬鎴�2浠婂ぉ鏈畬鎴�3宸插畬鎴� */
+ type: 1 | 2 | 3
+ /** 閫氶亾鍙� 涓嶄紶鏌ユ墍鏈夐�氶亾鐨� */
+ channel?: number
+ /** 浠庣鍑犱釜寮�濮嬫煡锛屼粠0寮�濮� */
+ offset: number
+ /** 鏌ュ灏戞潯 */
+ limit: number
+}
+
/**
* 鑾峰彇浠诲姟鍒楄〃
- * @param taskMode 1: 寰呯敓浜х殑浠诲姟 2: 鐪嬫澘鍚勯�氶亾褰撳墠灞曠ず鐨勪换鍔�
+ * @param params
*/
-export function getTaskList(taskMode: 1 | 2) {
- return request<BaseResponse<TasksResponse>>({
- url: '/v1/task/get',
+export function getTaskList(params: TaskListParams) {
+ return request<BaseResponse<TasksGroupByChannel>>({
+ url: '/v1/task/list',
method: 'get',
- params: {
- taskMode
- }
+ params
+ })
+}
+
+export interface ProductProgressParams {
+ channel: number
+ procedureId: number
+}
+
+export function getProductProgress(params: ProductProgressParams) {
+ return request<BaseResponse<PLCResponse>>({
+ url: '/v1/plc/productProgress',
+ method: 'post',
+ data: params
})
}
diff --git a/src/api/plc.ts b/src/api/plc.ts
new file mode 100644
index 0000000..686879e
--- /dev/null
+++ b/src/api/plc.ts
@@ -0,0 +1,6 @@
+export interface PLCResponse {
+ finishNumber: number
+ totalNumber: number
+ /** 1鏂紑 2鐢熶骇涓� 3寰呮満*/
+ plcStatus: 1 | 2 | 3
+}
diff --git a/src/api/task.ts b/src/api/task.ts
index a939691..405d0b4 100644
--- a/src/api/task.ts
+++ b/src/api/task.ts
@@ -48,7 +48,7 @@
workHours: string
inputMaterials: string
outputMaterials: string
- workers: Workers[]
+ workers: Worker[]
allProcedureNames: string[]
channel: number
}
@@ -62,7 +62,7 @@
CanStarted: boolean
}
-export interface Workers {
+export interface Worker {
workerId: string
workerName: string
phoneNum: string
@@ -78,7 +78,11 @@
export interface TasksResponse {
Tasks: Task[]
TaskCount: number
- workers: Workers[]
+ workers: Worker[]
Prompt: Prompt
ChannelAmount: number
}
+
+export interface TasksGroupByChannel {
+ [channel: number]: TasksResponse
+}
diff --git a/src/components.d.ts b/src/components.d.ts
index 52bea60..fac83df 100644
--- a/src/components.d.ts
+++ b/src/components.d.ts
@@ -7,13 +7,8 @@
declare module 'vue' {
export interface GlobalComponents {
- DashboardLayout: typeof import('./components/DashboardLayout.vue')['default']
- ElButton: typeof import('element-plus/es')['ElButton']
- ElCollapse: typeof import('element-plus/es')['ElCollapse']
- ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
- ElIcon: typeof import('element-plus/es')['ElIcon']
- ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
- RouterLink: typeof import('vue-router')['RouterLink']
- RouterView: typeof import('vue-router')['RouterView']
+ DashboardLayout: (typeof import('./components/DashboardLayout.vue'))['default']
+ RouterLink: (typeof import('vue-router'))['RouterLink']
+ RouterView: (typeof import('vue-router'))['RouterView']
}
}
diff --git a/src/components/DashboardLayout.vue b/src/components/DashboardLayout.vue
index 692c86f..e3d5309 100644
--- a/src/components/DashboardLayout.vue
+++ b/src/components/DashboardLayout.vue
@@ -5,8 +5,8 @@
<slot name="leftBlock1"></slot>
</div>
<div class="double-height-block padding-4">
- <div class="card">
- <el-scrollbar always>
+ <div class="card scroll-card">
+ <el-scrollbar always class="scroller">
<slot name="leftBlock2"></slot>
</el-scrollbar>
</div>
@@ -16,18 +16,18 @@
<div class="header-block padding-4">
<slot name="middleBlock1"></slot>
</div>
- <div class="base-block padding-4">
+ <div class="top-block padding-4">
<div class="card">
<slot name="middleBlock2"></slot>
</div>
</div>
- <div class="block-container">
- <div class="base-block padding-4">
+ <div class="bottom-block">
+ <div class="bottom-block-item padding-4">
<div class="card">
<slot name="middleBlock3"></slot>
</div>
</div>
- <div class="base-block padding-4">
+ <div class="bottom-block-item padding-4">
<div class="card">
<slot name="middleBlock4"></slot>
</div>
@@ -67,6 +67,10 @@
$baseBlockHeight: calc((100vh - 2 * $layoutPadding - $headerBlockHeight) / 2);
// 鍙屽�嶉珮甯冨眬鍧楅珮搴�
$doubleBlockHeight: calc($baseBlockHeight * 2);
+// 涓婅竟鍥哄畾楂�
+$topBlocHeight: 400px;
+// 涓嬭竟楂樺害
+$bottomBlockHeight: calc(100vh - 2 * $layoutPadding - $headerBlockHeight - $topBlocHeight);
.dashboard-layout {
display: flex;
align-items: center;
@@ -100,14 +104,24 @@
.padding-4 {
padding: 6px;
}
-.block-container {
+
+.base-block {
+ height: $baseBlockHeight;
+ flex: 1;
+}
+.top-block {
+ height: $topBlocHeight;
+ flex: 0;
+}
+.bottom-block {
display: flex;
align-items: center;
justify-content: space-between;
+ height: $bottomBlockHeight;
}
-.base-block {
- height: $baseBlockHeight;
- flex-grow: 1;
+.bottom-block-item {
+ height: $bottomBlockHeight;
+ flex: 1;
}
.header-block {
height: $headerBlockHeight;
@@ -123,4 +137,10 @@
border-radius: 6px;
padding: 10px 16px;
}
+.scroll-card {
+ padding: 0;
+}
+.scroller {
+ padding: 10px 16px;
+}
</style>
diff --git a/src/stores/tasks.ts b/src/stores/tasks.ts
new file mode 100644
index 0000000..8f8599d
--- /dev/null
+++ b/src/stores/tasks.ts
@@ -0,0 +1,106 @@
+import { computed, ref } from 'vue'
+import { defineStore } from 'pinia'
+import type { Task, TasksGroupByChannel, TasksResponse } from '@/api/task'
+import type { TaskListParams } from '@/api'
+import { getTaskList } from '@/api'
+
+export interface ChannelMoreBtnStatus {
+ /** true 浠诲姟鏈姞杞藉畬 false 鎵�鏈変换鍔″凡缁忓姞杞藉畬鎴�*/
+ [channel: number]: boolean
+}
+
+export const useTasksStore = defineStore('tasks', () => {
+ const channels = ref<TasksGroupByChannel>({})
+
+ const currentType = ref<1 | 2 | 3>(1)
+
+ /**
+ * 鑾峰彇浠诲姟鏁版嵁
+ * @param type 1鏈畬鎴�2浠婂ぉ鏈畬鎴�3宸插畬鎴�
+ */
+ function getChannels(type: 1 | 2 | 3) {
+ currentType.value = type
+ const params: TaskListParams = {
+ type,
+ offset: 0,
+ limit: 3
+ }
+ getTaskList(params)
+ .then((res) => {
+ channels.value = res.data
+ })
+ .catch((err) => {
+ console.error(err)
+ channels.value = []
+ })
+ }
+
+ function moreChannelTasksBtn(channelNumber: number) {
+ const taskLength = channels.value[channelNumber].Tasks?.length ?? 0
+ const params: TaskListParams = {
+ type: currentType.value,
+ channel: channelNumber,
+ offset: taskLength,
+ limit: 10
+ }
+ getTaskList(params)
+ .then((res) => {
+ const existTasks = channels.value![channelNumber].Tasks ?? []
+ channels.value[channelNumber] = res.data[channelNumber] ?? {}
+ channels.value[channelNumber].Tasks = channels.value[channelNumber].Tasks ?? []
+ channels.value[channelNumber].Tasks = [...existTasks, ...channels.value[channelNumber].Tasks]
+ })
+ .catch((err) => {
+ console.error(err)
+ })
+ }
+
+ function foldChannelTasksBtn(channelNumber: number) {
+ const tasks = channels.value[channelNumber].Tasks ?? []
+ channels.value[channelNumber].Tasks = tasks.slice(0, 3)
+ }
+
+ const moreBtnStatus = computed(() => {
+ return Object.entries(channels.value).reduce((pre, currentValue) => {
+ const channelNumber = +currentValue[0]
+ const channelData = currentValue[1] as TasksResponse
+ pre[channelNumber] = channelData.TaskCount > (channelData.Tasks?.length ?? 0)
+ return pre
+ }, {} as ChannelMoreBtnStatus)
+ })
+
+ /** 褰撳墠楂樹寒鐨勪换鍔� */
+ const activeTask = ref<Task>()
+ function setActiveTask(task: Task) {
+ activeTask.value = task
+ }
+
+ const requestParamsMap = ref<{
+ [channel: number]: TaskListParams
+ }>({})
+ function getParamsByChannel(channel: number) {
+ return (
+ requestParamsMap.value[channel] ?? {
+ type: 1,
+ offset: 0,
+ limit: 3
+ }
+ )
+ }
+
+ function setParamsByChannel(channel: number, params: TaskListParams) {
+ requestParamsMap.value[channel] = params
+ }
+ return {
+ channels,
+ getChannels,
+ moreBtnStatus,
+ activeTask,
+ setActiveTask,
+ requestParamsMap,
+ getParamsByChannel,
+ setParamsByChannel,
+ moreChannelTasksBtn,
+ foldChannelTasksBtn
+ }
+})
diff --git a/src/views/dashboard/components/ChannelCollapse.vue b/src/views/dashboard/components/ChannelCollapse.vue
index 693ab61..bde2dd9 100644
--- a/src/views/dashboard/components/ChannelCollapse.vue
+++ b/src/views/dashboard/components/ChannelCollapse.vue
@@ -2,35 +2,61 @@
<div class="channel-collapse">
<el-collapse v-model="activeChannel">
<el-collapse-item
- v-for="(tasks, channelNumber) in channels"
+ v-for="(channel, channelNumber) in channels"
:key="channelNumber"
:title="CHANNEL_NAME_MAP[channelNumber] + ' 閫氶亾'"
:name="String(channelNumber)"
>
- <TaskInfo v-for="task in tasks" :key="task.Procedure.ID" :task="task"></TaskInfo>
+ <TaskInfo
+ v-for="task in channel.Tasks"
+ :key="task.Procedure.ID"
+ :active="task.Procedure.ID === tasksStore.activeTask?.Procedure.ID"
+ :task="task"
+ style="margin-bottom: 16px"
+ @click="tasksStore.setActiveTask(task)"
+ ></TaskInfo>
+
+ <div
+ v-show="channel.Tasks?.length && tasksStore.moreBtnStatus?.[channelNumber]"
+ class="btn more"
+ @click="tasksStore.moreChannelTasksBtn(channelNumber)"
+ >
+ 鏌ョ湅鏇村
+ <el-icon style="margin-left: 6px"><ArrowDownBold /></el-icon>
+ </div>
+
+ <div
+ v-show="channel.Tasks?.length && !tasksStore.moreBtnStatus?.[channelNumber]"
+ class="btn fold"
+ @click="tasksStore.foldChannelTasksBtn(channelNumber)"
+ >
+ 鏀惰捣
+ <el-icon style="margin-left: 6px"><ArrowUpBold /></el-icon>
+ </div>
</el-collapse-item>
</el-collapse>
</div>
</template>
<script setup lang="ts">
import { ref, watchEffect } from 'vue'
-import type { Task } from '@/api/task'
+import type { TasksGroupByChannel } from '@/api/task'
import TaskInfo from './TaskInfo.vue'
import { CHANNEL_NAME_MAP } from '@/common/constants'
-
-export interface Channel {
- [channelNumber: number]: Task[]
-}
+import { useTasksStore } from '@/stores/tasks'
+import { ArrowDownBold, ArrowUpBold } from '@element-plus/icons-vue'
export interface ChannelCollapseProps {
- channels: Channel
+ channels: TasksGroupByChannel
}
const props = defineProps<ChannelCollapseProps>()
const activeChannel = ref<string[]>([])
+const tasksStore = useTasksStore()
+
watchEffect(() => {
- const channelNumbers = Object.keys(props.channels).sort((a, b) => +a - +b)
+ // 閫氶亾鏁版嵁鍙樺寲鍚�
+ const channelNumbers = Object.keys(props?.channels ?? {}).sort((a, b) => +a - +b)
activeChannel.value = [...channelNumbers]
})
</script>
@@ -66,4 +92,18 @@
font-size: 16px;
font-weight: 600;
}
+
+.btn {
+ width: 70%;
+ height: 50px;
+ margin: 0 auto;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 6px;
+ font-size: 18px;
+ font-weight: 600;
+ cursor: pointer;
+ background: linear-gradient(to right, rgb(29, 96, 212) 0%, rgb(47, 122, 251), rgb(29, 96, 212) 100%);
+}
</style>
diff --git a/src/views/dashboard/components/ProcessInfo.vue b/src/views/dashboard/components/CraftInfo.vue
similarity index 92%
rename from src/views/dashboard/components/ProcessInfo.vue
rename to src/views/dashboard/components/CraftInfo.vue
index a75e342..3ebac61 100644
--- a/src/views/dashboard/components/ProcessInfo.vue
+++ b/src/views/dashboard/components/CraftInfo.vue
@@ -1,5 +1,5 @@
<template>
- <div class="process-info">
+ <div class="craft-info">
<div class="item-l-bng">
<img src="~@/assets/images/process-model.png" />
</div>
@@ -9,7 +9,7 @@
<div class="item-r-b">{{ process.name }}</div>
</div>
<div class="tip-r">
- <img src="~@/assets/images/process-tip.png" />
+ <img src="~@/assets/images/process-tip.png" alt="" />
</div>
<div class="tip-current">褰撳墠浣跨敤</div>
<div class="btn">
@@ -18,7 +18,9 @@
</div>
</template>
<script setup lang="ts">
-import { computed, toRefs } from 'vue'
+// 宸ヨ壓淇℃伅
+import { toRefs } from 'vue'
+
export interface ProcessInfoProps {
process: process
}
@@ -33,7 +35,7 @@
.font_weight {
font-weight: 600;
}
-.process-info {
+.craft-info {
width: calc(50% - 35px);
height: 110px;
padding: 23px 10px 10px;
diff --git a/src/views/dashboard/components/PersonInfo.vue b/src/views/dashboard/components/PersonInfo.vue
index d054728..95693e4 100644
--- a/src/views/dashboard/components/PersonInfo.vue
+++ b/src/views/dashboard/components/PersonInfo.vue
@@ -29,10 +29,12 @@
</div>
</template>
<script setup lang="ts">
-import type { UserFilled } from '@element-plus/icons-vue'
-import { computed, toRefs } from 'vue'
+import { StarFilled, UserFilled } from '@element-plus/icons-vue'
+import { toRefs } from 'vue'
+import type { Worker } from '@/api/task'
+
export interface PersonInfoProps {
- person: person
+ person: Worker
}
const props = defineProps<PersonInfoProps>()
diff --git a/src/views/dashboard/components/ProcessingInfo.vue b/src/views/dashboard/components/ProcessingInfo.vue
new file mode 100644
index 0000000..6aaf8d9
--- /dev/null
+++ b/src/views/dashboard/components/ProcessingInfo.vue
@@ -0,0 +1,220 @@
+<template>
+ <div class="processing-info">
+ <div class="step">
+ <el-steps
+ v-if="task?.AllProcedures"
+ :active="task.CurrentProcedureIndex ?? 0"
+ finish-status="success"
+ class="steps"
+ >
+ <el-step v-for="(item, index) in task.AllProcedures" :key="index" icon="" :title="item"></el-step>
+ </el-steps>
+ </div>
+ <div class="details">
+ <div class="row">
+ <div class="col">宸ュ崟缂栧彿: {{ task?.Order?.workOrderId || '' }}</div>
+ <div class="col">璁㈠崟缂栧彿: {{ task?.Order?.orderId || '' }}</div>
+ </div>
+
+ <div class="row">
+ <div class="col">浜у搧鍚嶇О: {{ task?.Order?.productName || '--' }}</div>
+ <div class="col">鏁伴噺: {{ task?.Order?.amount || 0 }}{{ task?.Order?.unit }}</div>
+ </div>
+ <div class="row">
+ <div class="col">浜よ揣鏃ユ湡: {{ task?.Order?.deliverDate || '--' }}</div>
+ <div class="col">宸ユ椂: {{ task?.Procedure?.procedure?.workHours || '--' }}</div>
+ </div>
+ <div class="row">
+ <div class="col">
+ 璧锋鏃堕棿: {{ formatDate(task?.Procedure?.startTime) }}
+ ~
+ {{ formatDate(task?.Procedure?.endTime) }}
+ </div>
+ <div class="col">閫氶亾: {{ isNumber(task?.Channel) ? CHANNEL_NAME_MAP[task?.Channel] : '--' }}</div>
+ </div>
+ <div class="row">
+ <div class="col">瀹㈡埛鍚嶇О: {{ task?.Order?.customer || '' }}</div>
+ <div class="col">鍙傛暟瑕佹眰: {{ task?.Order?.parameter || '' }}</div>
+ </div>
+ </div>
+ <div class="process">
+ <div>瀹屾垚杩涘害:</div>
+ <div class="process-bar">
+ <el-progress
+ define-back-color="#132f6e"
+ color="#00cc66"
+ text-color="#fff"
+ :text-inside="true"
+ :stroke-width="30"
+ :percentage="processingPercent"
+ ></el-progress>
+ </div>
+ </div>
+ </div>
+</template>
+<script setup lang="ts">
+// 鍔犲伐淇℃伅缁勪欢
+import type { Task } from '@/api/task'
+import { computed, onUnmounted, toRefs, watch } from 'vue'
+import { useDateFormat } from '@vueuse/core'
+import { useRequest } from 'vue-hooks-plus'
+import { getProductProgress } from '@/api'
+import type { ProductProgressParams } from '@/api'
+import { isNumber } from 'lodash-es'
+import { CHANNEL_NAME_MAP } from '@/common/constants'
+
+const props = defineProps<{
+ task?: Task
+}>()
+
+const { task } = toRefs(props)
+export interface Statistics {
+ totalNumber: number
+ finishNumber: number
+}
+
+/**
+ * 璁$畻鐢熶骇杩涘害
+ * @param statistics
+ * @return 杩涘害,0~100
+ */
+function calculateProgress(statistics: Statistics): number {
+ if (!statistics) {
+ return 0
+ }
+
+ if (statistics.finishNumber === 0) {
+ return 0
+ }
+ if (statistics.finishNumber === statistics.totalNumber) {
+ return 100
+ }
+
+ const result = Math.floor((statistics.finishNumber / statistics.totalNumber) * 100)
+ return result > 100 ? 100 : result
+}
+
+/**
+ * 璁$畻瀹屾垚杩涘害, 浠诲姟鐘舵�佹湭鐢熶骇鍥哄畾涓� 0% 宸插畬鎴愬浐瀹氫负 100% 鐢熶骇涓垯浠巔lc鑾峰彇
+ */
+const processingPercent = computed(() => {
+ if (task?.value?.Procedure?.Status === 1) {
+ return 0
+ }
+
+ if (task?.value?.Procedure?.Status === 3) {
+ return 100
+ }
+
+ if (task?.value?.Procedure?.Status === 2) {
+ return calculateProgress(plcResponse?.value?.data as Statistics)
+ }
+
+ return 0
+})
+
+/**
+ * 濡傛灉浠诲姟鐘舵�佹槸杩涜涓�, 鍒欒疆璇� plc 鍙栬繘搴�
+ */
+const {
+ data: plcResponse,
+ run: startPLCPolling,
+ cancel: cancelPLCPolling
+} = useRequest(
+ () =>
+ getProductProgress({
+ channel: task?.value?.Channel,
+ procedureId: task?.value?.Procedure.ID
+ } as ProductProgressParams),
+ {
+ manual: true,
+ pollingInterval: 6000,
+ pollingWhenHidden: false
+ }
+)
+
+/**
+ * 浠诲姟鐘舵�佹槸鐢熶骇涓垯杞plc鍙栫洰鏍囨暟鍜屽畬鎴愭暟璁$畻瀹屾垚杩涘害
+ */
+watch(
+ () => task?.value,
+ () => {
+ cancelPLCPolling()
+ if (task?.value?.Procedure?.Status === 2) {
+ startPLCPolling()
+ }
+ }
+)
+
+onUnmounted(() => {
+ cancelPLCPolling()
+})
+
+/**
+ * 鏍煎紡鍖栨椂闂存埑
+ * @param timestamp 鍚庣杩旂殑10浣嶆椂闂存埑
+ */
+function formatDate(timestamp?: number) {
+ if (!timestamp) {
+ return '--'
+ }
+ const time = useDateFormat(timestamp * 1000, 'YYYY-MM-DD', { locales: 'zh-cn' })
+ return time.value
+}
+</script>
+<style scoped lang="scss">
+$text-color: #d7d7ca;
+
+.step {
+ width: 100%;
+ height: 66px;
+ overflow-x: auto;
+ margin-top: -5px;
+ padding: 0 20px;
+ .steps {
+ height: 100%;
+ .el-step__icon {
+ width: 16px;
+ height: 16px;
+ }
+ .el-step__title {
+ line-height: 25px;
+ font-size: 14px;
+ }
+ .el-step__title.is-process {
+ color: #a8abb2;
+ }
+ }
+}
+.details {
+ font-size: 18px;
+ padding: 10px 20px;
+ color: $text-color;
+ .row {
+ width: 100%;
+ padding: 2px 0;
+ display: flex;
+ align-items: center;
+ }
+ .col {
+ width: 50%;
+ flex: 1;
+ }
+}
+.process {
+ font-size: 18px;
+ padding: 10px 20px;
+ color: $text-color;
+ display: flex;
+}
+.process-bar {
+ flex: 1;
+ margin-left: 20px;
+}
+:deep(.el-progress-bar__outer) {
+ border-radius: 8px;
+}
+:deep(.el-progress-bar__inner) {
+ border-radius: 8px;
+}
+</style>
diff --git a/src/views/dashboard/components/TaskInfo.vue b/src/views/dashboard/components/TaskInfo.vue
index e085d73..d0ba6e1 100644
--- a/src/views/dashboard/components/TaskInfo.vue
+++ b/src/views/dashboard/components/TaskInfo.vue
@@ -1,5 +1,5 @@
<template>
- <div class="task-info" :class="{ selected }">
+ <div class="task-info" :class="{ active }">
<div
class="task-info-title"
:class="{
@@ -31,13 +31,13 @@
export interface TaskInfoProps {
task: Task
- selected?: boolean
+ active?: boolean
}
const props = withDefaults(defineProps<TaskInfoProps>(), {
- selected: false
+ active: false
})
-const { task, selected } = toRefs(props)
+const { task, active } = toRefs(props)
const planTimeText = computed(() => {
const format = (date: number) => {
@@ -56,9 +56,12 @@
$status-ready: #13235a;
$status-done: #13235a;
$text-color: #d7d7d7;
+$active-color: #00dfdf;
.task-info {
background-color: #6b83ff;
border-radius: 4px;
+ overflow: initial;
+ cursor: pointer;
}
.task-info-title {
height: 34px;
@@ -94,4 +97,17 @@
flex: 1;
}
}
+.active {
+ position: relative;
+ &:before {
+ content: '';
+ width: 8px;
+ background-color: $active-color;
+ height: 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ border-radius: 6px 0 0 6px;
+ }
+}
</style>
diff --git a/src/views/dashboard/components/TaskTabs.vue b/src/views/dashboard/components/TaskTabs.vue
index d2e3311..4eaf64f 100644
--- a/src/views/dashboard/components/TaskTabs.vue
+++ b/src/views/dashboard/components/TaskTabs.vue
@@ -1,32 +1,39 @@
<template>
<div class="task-tabs">
<div
- v-for="tabName in list"
- :key="tabName"
+ v-for="tab in list"
+ :key="tab.value"
class="task-tab-item triangle-tip"
- :class="{ active: props.modelValue === tabName }"
- @click="selectTab(tabName)"
+ :class="{ active: props.modelValue === tab.value }"
+ @click="selectTab(tab)"
>
- {{ tabName }}
+ {{ tab.label }}
</div>
</div>
</template>
<script setup lang="ts">
import { useVModel } from '@vueuse/core'
+export interface LabelValue {
+ label: string
+ value: any
+}
+
const props = defineProps<{
/** tab 鍒楄〃*/
- list: string[]
+ list: LabelValue[]
/** 褰撳墠閫変腑鐨� tab*/
- modelValue?: string
+ modelValue?: any
}>()
const emit = defineEmits<{
'update:modelValue': [tabName: string]
+ change: [tab: LabelValue]
}>()
const data = useVModel(props, 'modelValue', emit)
-function selectTab(tabName: string) {
- data.value = tabName
+function selectTab(tab: LabelValue) {
+ data.value = tab.value
+ emit('change', tab)
}
</script>
<style scoped lang="scss">
diff --git a/src/views/dashboard/index.vue b/src/views/dashboard/index.vue
deleted file mode 100644
index b927f26..0000000
--- a/src/views/dashboard/index.vue
+++ /dev/null
@@ -1,87 +0,0 @@
-<template>
- <DashboardLayout>
- <template #leftBlock1>
- <TaskTabs v-model="activeTaskTab" style="margin-top: 20px" :list="taskTabsTitle"></TaskTabs>
- </template>
- <template #leftBlock2>
- <ChannelCollapse :channels="channels"></ChannelCollapse>
- </template>
- <template #middleBlock1>鏍囬</template>
- <template #middleBlock2
- >涓荤湅鏉�
- <ProcessInfo :process="process"></ProcessInfo>
- </template>
- <template #middleBlock3>浠诲姟璇︽儏</template>
- <template #middleBlock4
- >浜哄憳淇℃伅
- <PersonInfo :person="person"></PersonInfo>
- </template>
- <template #rightBlock1>
- <div class="date-time">
- <CurrentDateTime></CurrentDateTime>
- </div>
- </template>
- <template #rightBlock2>鐘舵�侀潰鏉�</template>
- <template #rightBlock3>鐭ヨ瘑搴�</template>
- </DashboardLayout>
-</template>
-<script setup lang="ts">
-import { getTaskList } from '@/api'
-import { computed, ref, watchEffect } from 'vue'
-import ChannelCollapse from '@/views/dashboard/components/ChannelCollapse.vue'
-import type { Task } from '@/api/task'
-import { chain } from 'lodash-es'
-import ProcessInfo from '@/views/dashboard/components/ProcessInfo.vue'
-import PersonInfo from '@/views/dashboard/components/PersonInfo.vue'
-import TaskTabs from '@/views/dashboard/components/TaskTabs.vue'
-import CurrentDateTime from '@/views/dashboard/components/CurrentDateTime.vue'
-
-defineOptions({
- name: 'DashboardView'
-})
-
-const taskList = ref<Task[]>()
-
-function getChannels() {
- getTaskList(2)
- .then((res) => {
- taskList.value = res.data.Tasks
- })
- .catch((err) => {
- console.error(err)
- taskList.value = []
- })
-}
-
-const channels = computed(() => {
- return chain<Task>(taskList.value)
- .groupBy((ele) => ele.Channel)
- .value()
-})
-const process = computed(() => {
- return { name: '宸ヨ壓鍚嶇О', number: '111' }
-})
-const person = computed(() => {
- return {
- workerName: '濮撳悕',
- phone: '111'
- }
-})
-getChannels()
-const taskTabsTitle = ['鏈畬鎴�', '浠婃棩浠诲姟', '宸插畬鎴�']
-const activeTaskTab = ref('鏈畬鎴�')
-
-watchEffect(() => {
- // console.log(activeTaskTab?.value, 111111)
-})
-</script>
-
-<style scoped>
-.date-time {
- width: 100%;
- display: flex;
- align-items: center;
- justify-content: center;
- padding-top: 12px;
-}
-</style>
diff --git a/vite.config.ts b/vite.config.ts
index 692b8dc..a45bed3 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -14,7 +14,7 @@
server: {
proxy: {
'/v1/': {
- target: 'http://192.168.20.4:8003',
+ target: 'http://192.168.20.119:8003',
ws: true,
changeOrigin: true
}
--
Gitblit v1.8.0