This commit is contained in:
che
2026-07-25 14:49:14 +05:00
parent 6e56cfc9cd
commit c564608983
3 changed files with 122 additions and 77 deletions
@@ -30,6 +30,7 @@ static TASK_TRANSFER_FIELDS: &[Field] = &[
Field::new("date_create").read_only(), Field::new("date_create").read_only(),
Field::new("status"), Field::new("status"),
Field::new("typ"), Field::new("typ"),
Field::new("project_id"),
]; ];
pub fn employee_serializer() -> ModelSerializer<Employee> { pub fn employee_serializer() -> ModelSerializer<Employee> {
+116
View File
@@ -0,0 +1,116 @@
<script setup lang="ts">
import type { Task } from "../../../generated/models";
type TaskItem = Task;
const props = defineProps<{
item: TaskItem;
}>();
const emit = defineEmits<{
open: [path: string];
}>();
</script>
<template>
<van-cell
:title="
'employee_from' in props.item
? props.item.task.text?.trim() || `Задача #${props.item.task.id}`
: props.item.text?.trim() ||
props.item.result?.trim() ||
`Задача #${props.item.id}`
"
center
is-link
:class="`task-row task-row-${/success|done|complete|green/i.test('employee_from' in props.item ? props.item.task.status : props.item.get_status_class || 'status-default') ? 'success' : /warning|pending|wait|yellow|orange/i.test('employee_from' in props.item ? props.item.task.status : props.item.get_status_class || 'status-default') ? 'warning' : /danger|error|red|fail/i.test('employee_from' in props.item ? props.item.task.status : props.item.get_status_class || 'status-default') ? 'danger' : 'primary'}`"
@click="
emit(
'open',
'employee_from' in props.item
? `/tasks/${props.item.task.id}`
: `/tasks/${props.item.id}`,
)
"
>
<template #icon>
<van-image
class="task-avatar"
round
width="36"
height="36"
:src="
'employee_from' in props.item
? ''
: (props.item.author?.avatar_small ?? '')
"
/>
</template>
<template #label>
<div>
Автор:
{{ props.item.author?.short_name }}
</div>
<div>объект строительства: {{ props.item.project_id }}</div>
</template>
<template #right-icon>
<van-tag
plain
:type="
/success|done|complete|green/i.test(
'employee_from' in props.item
? props.item.task.status
: props.item.get_status_class || 'status-default',
)
? 'success'
: /warning|pending|wait|yellow|orange/i.test(
'employee_from' in props.item
? props.item.task.status
: props.item.get_status_class || 'status-default',
)
? 'warning'
: /danger|error|red|fail/i.test(
'employee_from' in props.item
? props.item.task.status
: props.item.get_status_class || 'status-default',
)
? 'danger'
: 'primary'
"
>
{{
"employee_from" in props.item
? props.item.task.deadline
: props.item.deadline
}}
</van-tag>
</template>
</van-cell>
</template>
<style scoped>
.task-avatar {
margin-right: 10px;
}
:deep(.van-cell.task-row-success) {
background: #f0fdf4;
}
:deep(.van-cell.task-row-warning) {
background: #fffbeb;
}
:deep(.van-cell.task-row-danger) {
background: #fef2f2;
}
:deep(.van-cell.task-row-primary) {
background: #eff6ff;
}
:deep(.van-cell.task-row-default) {
background: #f8fafc;
}
</style>
+5 -77
View File
@@ -12,6 +12,7 @@ import type {
TaskUpdate, TaskUpdate,
} from "../../../generated/models"; } from "../../../generated/models";
import { useModelApi } from "../../../shared/composables/useModelApi"; import { useModelApi } from "../../../shared/composables/useModelApi";
import TaskListItem from "../components/TaskListItem.vue";
type CurrentEmployee = { type CurrentEmployee = {
id: number; id: number;
@@ -125,72 +126,10 @@ const visibleDocTabs = computed(() =>
: [], : [],
); );
function personName(
person: { short_name?: string | null; name?: string | null } | null,
) {
if (!person) {
return "не указан";
}
return person.short_name ?? person.name ?? "не указан";
}
function taskTitle(task: {
id: number;
text?: string | null;
result?: string | null;
}) {
return task.text?.trim() || task.result?.trim() || `Задача #${task.id}`;
}
function badgeValue(count: number) { function badgeValue(count: number) {
return count > 0 ? count : undefined; return count > 0 ? count : undefined;
} }
function isTaskTransfer(item: Task | TaskTransfer): item is TaskTransfer {
return "employee_from" in item;
}
function itemTitle(item: Task | TaskTransfer) {
return isTaskTransfer(item) ? taskTitle(item.task) : taskTitle(item);
}
function itemLabel(item: Task | TaskTransfer) {
if (isTaskTransfer(item)) {
return `Из ${personName(item.employee_from)} в ${personName(item.employee_to)} · Срок: ${item.task.deadline} · Создан: ${item.date_create}`;
}
return `ID: ${item.id} · Исполнитель: ${personName(item.doer)} · Ответственный: ${personName(item.responsible)} · Срок: ${item.deadline}`;
}
function itemStatus(item: Task | TaskTransfer) {
return isTaskTransfer(item) ? item.status : item.get_status || item.status;
}
function itemStatusClass(item: Task | TaskTransfer) {
const statusClass = isTaskTransfer(item) ? item.task.status : item.get_status_class;
return statusClass || "status-default";
}
function itemStatusType(item: Task | TaskTransfer) {
const statusClass = itemStatusClass(item);
if (/success|done|complete|green/i.test(statusClass)) {
return "success";
}
if (/warning|pending|wait|yellow|orange/i.test(statusClass)) {
return "warning";
}
if (/danger|error|red|fail/i.test(statusClass)) {
return "danger";
}
return "primary";
}
function itemPath(item: Task | TaskTransfer) {
return isTaskTransfer(item) ? `/tasks/${item.task.id}` : `/tasks/${item.id}`;
}
function buildTaskParams( function buildTaskParams(
tab: MainTabKey, tab: MainTabKey,
@@ -471,23 +410,12 @@ onMounted(async () => {
/> />
<van-cell-group v-else inset> <van-cell-group v-else inset>
<van-cell <TaskListItem
v-for="item in visibleItems" v-for="item in visibleItems"
:key="item.id" :key="item.id"
:title="itemTitle(item)" :item="item"
center @open="router.push($event)"
is-link />
@click="router.push(itemPath(item))"
>
<template #label>
{{ itemLabel(item) }}
</template>
<template #right-icon>
<van-tag plain :type="itemStatusType(item)" :class="itemStatusClass(item)">
{{ itemStatus(item) }}
</van-tag>
</template>
</van-cell>
</van-cell-group> </van-cell-group>
</van-list> </van-list>
</van-pull-refresh> </van-pull-refresh>