feat: complete admin panel and backend admin api migration
This commit is contained in:
@@ -0,0 +1,223 @@
|
||||
<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="سفارش های ساختنی">
|
||||
<XTable ref="tbl" :model="model">
|
||||
<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%"
|
||||
@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">
|
||||
<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,
|
||||
});
|
||||
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;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user