Order-revision workflow kept as is: the direct admin line-edit routes were not ported. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
237 lines
8.1 KiB
Vue
237 lines
8.1 KiB
Vue
<template>
|
|
<!--
|
|
Ported from legacy henza_admin/src/views/order/MakeOrder.vue.
|
|
These are custom/made-to-order design requests (PreOrder in the new schema).
|
|
Farsi copy, permission gates and the edit-in-place flow are preserved; the
|
|
delete action and the report link are COMMENTED OUT in legacy and stay absent.
|
|
-->
|
|
<div id="page-user-list">
|
|
<a-card title="سفارش های ساختنی" class="page-card">
|
|
<XTable ref="tbl" :model="model" mobile-cards>
|
|
<template #name="{ record }">
|
|
{{ record.customer?.name }}
|
|
</template>
|
|
|
|
<template #opt="{ record }">
|
|
<div class="flex">
|
|
<TooltipBtn
|
|
v-if="hasPermission('order.makeOrder.view')"
|
|
icon-class="w-5 h-5 text-primary"
|
|
class="mr-3"
|
|
icon="ListIcon"
|
|
title="مشاهده سفارش"
|
|
@click="viewOrder(record)"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<template #sts="{ record }">
|
|
<a
|
|
v-if="hasPermission('order.makeOrder.state')"
|
|
href=""
|
|
@click.prevent="viewOrder(record)"
|
|
>{{ record.sts_str_fa }}</a
|
|
>
|
|
<span v-else>{{ record.sts_str_fa }}</span>
|
|
</template>
|
|
</XTable>
|
|
|
|
<!-- مشاهده سفارش -->
|
|
<a-modal
|
|
v-model:open="visibleList"
|
|
title="مشاهده سفارش"
|
|
width="80%"
|
|
wrap-class-name="detail-modal"
|
|
@cancel="onCloseDetail"
|
|
>
|
|
<div v-if="tempRow">
|
|
<a-descriptions>
|
|
<a-descriptions-item label="مشتری">{{ customerName }}</a-descriptions-item>
|
|
<a-descriptions-item label="تلفن همراه">{{ customerMobile }}</a-descriptions-item>
|
|
<a-descriptions-item label="تاریخ ثبت">
|
|
{{ formatDate(tempRow.time_creat_fa) || '-' }}
|
|
</a-descriptions-item>
|
|
<a-descriptions-item label="وضعیت">{{ tempRow.sts_str_fa || '-' }}</a-descriptions-item>
|
|
</a-descriptions>
|
|
|
|
<a-card>
|
|
<template #title>
|
|
<div class="flex">
|
|
<div class="flex-1">آیتم های سفارش</div>
|
|
<div>
|
|
<TooltipBtn
|
|
v-if="hasPermission('order.makeOrder.view.edit')"
|
|
icon-class="w-5 h-5 text-success"
|
|
title="ویرایش"
|
|
:icon="getIcon"
|
|
@click="editW"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<div class="flex gap-8 make-detail">
|
|
<div>
|
|
<img
|
|
v-if="tempRow.designImageUrl"
|
|
:src="tempRow.designImageUrl"
|
|
width="90px"
|
|
height="90px"
|
|
style="object-fit: scale-down"
|
|
/>
|
|
<a-empty v-else :image="undefined" description="بدون تصویر" />
|
|
</div>
|
|
<div class="flex">
|
|
<a-descriptions>
|
|
<a-descriptions-item label="رنگ محصول">
|
|
<div v-if="!editMode">{{ tempRow.color || '-' }}</div>
|
|
<a-input
|
|
v-if="editMode && hasPermission('order.makeOrder.view.edit')"
|
|
v-model:value="tempRow.color"
|
|
/>
|
|
</a-descriptions-item>
|
|
<a-descriptions-item label="رنگ مینا">
|
|
<div v-if="!editMode">{{ tempRow.color_mina || '-' }}</div>
|
|
<a-input
|
|
v-if="editMode && hasPermission('order.makeOrder.view.edit')"
|
|
v-model:value="tempRow.color_mina"
|
|
/>
|
|
</a-descriptions-item>
|
|
<a-descriptions-item label="رنگ سنگ">
|
|
<div v-if="!editMode">{{ tempRow.color_stone || '-' }}</div>
|
|
<a-input
|
|
v-if="editMode && hasPermission('order.makeOrder.view.edit')"
|
|
v-model:value="tempRow.color_stone"
|
|
/>
|
|
</a-descriptions-item>
|
|
<a-descriptions-item label="تعداد">
|
|
<a-tag v-if="!editMode" color="orange">{{ tempRow.sum || 0 }}</a-tag>
|
|
<a-input-number
|
|
v-if="editMode && hasPermission('order.makeOrder.view.edit')"
|
|
v-model:value="tempRow.sum"
|
|
class="w-full"
|
|
/>
|
|
</a-descriptions-item>
|
|
<a-descriptions-item label="انتخاب کارگاه">
|
|
<a-select
|
|
v-model:value="tempRow.workshop_id"
|
|
placeholder="لطفا یک کارگاه را انتخاب کنید"
|
|
style="min-width: 200px"
|
|
>
|
|
<a-select-option v-for="item in option" :key="item.id" :value="item.id">
|
|
{{ item.name }}
|
|
</a-select-option>
|
|
</a-select>
|
|
</a-descriptions-item>
|
|
</a-descriptions>
|
|
</div>
|
|
</div>
|
|
</a-card>
|
|
</div>
|
|
<a-empty v-else />
|
|
|
|
<template #footer>
|
|
<a-button @click="visibleList = false">باشه</a-button>
|
|
</template>
|
|
</a-modal>
|
|
</a-card>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed, ref } from 'vue';
|
|
import { message } from 'ant-design-vue';
|
|
import XTable from '../../components/x-table/XTable.vue';
|
|
import TooltipBtn from '../../components/tooltip-btn/TooltipBtn.vue';
|
|
import { buildMakeOrderModel } from './MakeOrderModel';
|
|
import { useUsersStore } from '../../stores/users';
|
|
import api from '../../api/client';
|
|
import { jdate } from '../../utils/filters';
|
|
|
|
const users = useUsersStore();
|
|
const hasPermission = (rid: string) => Boolean(users.hasPermission(rid));
|
|
|
|
const model = buildMakeOrderModel();
|
|
const tbl = ref<{ fetch: () => Promise<void> } | null>(null);
|
|
|
|
const tempRow = ref<Record<string, any> | undefined>(undefined);
|
|
const visibleList = ref(false);
|
|
const editMode = ref(false);
|
|
const option = ref<{ id: string; name: string }[]>([]);
|
|
|
|
const formatDate = (v: string | null) => (v ? jdate(v) : '');
|
|
const getIcon = computed(() => (!editMode.value ? 'EditIcon' : 'CheckIcon'));
|
|
const customerName = computed(() => tempRow.value?.customer?.name ?? '-');
|
|
const customerMobile = computed(() => tempRow.value?.customer?.mobile ?? '-');
|
|
|
|
async function loadWorkshops() {
|
|
try {
|
|
const { data } = await api.post('workshop/table', { page: 1, limit: 100 });
|
|
option.value = (data.rows ?? []).map((w: any) => ({ id: w.id, name: w.name }));
|
|
} catch (e) {
|
|
// Legacy silently ignored a failed workshop fetch too.
|
|
console.log(e);
|
|
}
|
|
}
|
|
|
|
async function viewOrder(row: Record<string, any>) {
|
|
const { data } = await api.get(`admin/pre-orders/${row.id}`);
|
|
tempRow.value = data;
|
|
visibleList.value = true;
|
|
loadWorkshops();
|
|
}
|
|
|
|
/**
|
|
* legacy editW(): the same button toggles into edit mode and, on the second
|
|
* click, saves. Legacy's save was `PUT custom-order/{id}`.
|
|
*/
|
|
async function editW() {
|
|
if (!editMode.value) {
|
|
editMode.value = true;
|
|
return;
|
|
}
|
|
try {
|
|
await api.put(`custom-order/${tempRow.value?.id}`, {
|
|
color: tempRow.value?.color,
|
|
color_mina: tempRow.value?.color_mina,
|
|
color_stone: tempRow.value?.color_stone,
|
|
// The quantity field sits in the same edit mode; without it the edit was shown but never kept.
|
|
sum: tempRow.value?.sum,
|
|
});
|
|
editMode.value = false;
|
|
message.info('ویرایش موفق آمیز');
|
|
tbl.value?.fetch();
|
|
} catch (e: any) {
|
|
message.error(e?.response?.data?.message ?? 'خطا در ویرایش');
|
|
}
|
|
}
|
|
|
|
/** legacy: @cancel="$refs.tbl.fetch(); editMode=false" */
|
|
function onCloseDetail() {
|
|
tbl.value?.fetch();
|
|
editMode.value = false;
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.flex-1 {
|
|
flex: 1;
|
|
}
|
|
.gap-8 {
|
|
gap: 2rem;
|
|
}
|
|
.mr-3 {
|
|
margin-left: 0.75rem;
|
|
}
|
|
|
|
@media (max-width: 575px) {
|
|
.make-detail {
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
}
|
|
.make-detail > .flex {
|
|
min-width: 0;
|
|
}
|
|
}
|
|
</style>
|