Initial commit

This commit is contained in:
Viet An
2026-03-02 09:45:33 +07:00
commit d17a9e2588
415 changed files with 92113 additions and 0 deletions

View File

@@ -0,0 +1,323 @@
<template>
<div class="container-fluid">
<div class="mt-0" v-if="loading">
<p>{{ isVietnamese ? 'Đang tải dữ liệu...' : 'Loading...' }}</p>
</div>
<div class="mt-0" v-else-if="entries.length === 0">
<p>{{ isVietnamese ? 'Không có dữ liệu' : 'No data' }}</p>
</div>
<div v-else>
<div v-for="(entry, index) in entries" :key="entry.code || index" class="entry-item mb-5">
<h3 class="title is-5 mb-3">
{{ isVietnamese ? 'Bút toán' : 'Entry' }} #{{ index + 1 }}
</h3>
<div class="columns is-multiline mx-0">
<!-- bút toán -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? 'Mã bút toán' : 'Code' }}</label>
<div class="control">
<span class="hyperlink" @click="$copyToClipboard(entry.code)">{{ entry.code }}</span>
</div>
</div>
</div>
<!-- Ngày bút toán -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? 'Ngày bút toán' : 'Date' }}</label>
<div class="control">
<span>{{ entry.date ? $dayjs(entry.date).format("DD/MM/YYYY") : "/" }}</span>
</div>
</div>
</div>
<!-- Amount -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? 'Số tiền' : 'Amount' }}</label>
<div class="control">
<span>
{{ $numtoString(entry.amount) }}
</span>
</div>
</div>
</div>
<!-- quỹ -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? 'Mã quỹ' : 'Account Code' }}</label>
<div class="control">
<span class="hyperlink" @click="$copyToClipboard(entry.account__code)">
{{ entry.account__code || "/" }}
</span>
</div>
</div>
</div>
<!-- Tên quỹ -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? 'Tên quỹ' : 'Account Type' }}</label>
<div class="control">
<span>{{ entry.account__type__name || "/" }}</span>
</div>
</div>
</div>
<!-- Loại bút toán -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? 'Loại bút toán' : 'Category' }}</label>
<div class="control">
<span>{{ entry.category__name || "/" }}</span>
</div>
</div>
</div>
<!-- Loại tiền -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? 'Loại tiền' : 'Currency' }}</label>
<div class="control">
<span>{{ entry.account__currency__code || "/" }}</span>
</div>
</div>
</div>
<!-- trước -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? 'Dư trước' : 'Balance Before' }}</label>
<div class="control">
<span>
{{ $numtoString(entry.balance_before) }}
</span>
</div>
</div>
</div>
<!-- Ghi -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? 'Ghi có' : 'Credit' }}</label>
<div class="control">
<span v-if="entry.type===1">
{{ $numtoString(entry.amount) }}
</span>
</div>
</div>
</div>
<!-- Trích nợ (Ghi nợ) -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? 'Ghi nợ' : 'Debit' }}</label>
<div class="control">
<span v-if="entry.type===2">
{{ $numtoString(entry.amount) }}
</span>
</div>
</div>
</div>
<!-- sau -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? 'Dư sau' : 'Balance After' }}</label>
<div class="control">
<span>
{{ $numtoString(entry.balance_after) }}
</span>
</div>
</div>
</div>
<!-- Loại (Ghi /ghi nợ) -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? 'Loại' : 'Type' }}</label>
<div class="control">
<span>{{ entry.type__name || "/" }}</span>
</div>
</div>
</div>
<!-- Người nhập -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? 'Người nhập' : 'Inputer' }}</label>
<div class="control">
<span class="hyperlink" @click="openUser(entry.inputer)">
{{ entry.inputer__fullname || "/" }}
</span>
</div>
</div>
</div>
<!-- Người duyệt -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? 'Người duyệt' : 'Approver' }}</label>
<div class="control">
<span class="hyperlink" @click="openUser(entry.approver)">
{{ entry.approver__fullname || "/" }}
</span>
</div>
</div>
</div>
<!-- Ref -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label"> tham chiếu</label>
<div class="control">
<span>{{ entry.ref || "/" }}</span>
</div>
</div>
</div>
<!-- Thời gian -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? 'Thời gian' : 'Create Time' }}</label>
<div class="control">
<span>{{ entry.create_time ? $dayjs(entry.create_time).format("DD/MM/YYYY HH:mm") : "/" }}</span>
</div>
</div>
</div>
<!-- Nội dung -->
<div class="column is-full pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? 'Nội dung' : 'Content' }}</label>
<div class="control">
<span>{{ entry.content || "/" }}</span>
</div>
</div>
</div>
</div>
<hr v-if="index < entries.length - 1" class="my-4">
</div>
</div>
<Modal @close="showmodal = undefined" v-bind="showmodal" v-if="showmodal"></Modal>
</div>
</template>
<script>
import { useStore } from "@/stores/index";
export default {
setup() {
const store = useStore();
return { store };
},
props: {
entryList: {
type: Array,
default: () => []
}
},
data() {
return {
entries: [],
loading: false,
showmodal: undefined,
};
},
computed: {
lang() {
return this.store.lang;
},
isVietnamese() {
return this.store.lang === "vi";
},
},
async created() {
await this.fetchEntries();
},
watch: {
entryList: {
handler() {
this.fetchEntries();
},
deep: true
}
},
methods: {
parseEntryItem(item) {
// Nếu item đã là object thì return luôn
if (typeof item === 'object' && item !== null) {
return item;
}
// Nếu item là string thì parse
if (typeof item === 'string') {
try {
// Thay thế single quotes bằng double quotes để parse JSON
const jsonString = item.replace(/'/g, '"');
return JSON.parse(jsonString);
} catch (error) {
console.error('Lỗi khi parse string thành JSON:', item, error);
return null;
}
}
return null;
},
async fetchEntries() {
const { $getdata } = useNuxtApp();
if (!this.entryList || this.entryList.length === 0) {
this.entries = [];
return;
}
this.loading = true;
this.entries = [];
try {
// Duyệt qua từng item trong entryList để fetch dữ liệu
for (const item of this.entryList) {
// Parse item từ string sang object nếu cần
const parsedItem = this.parseEntryItem(item);
if (parsedItem && parsedItem.code) {
try {
const entryData = await $getdata("internalentry", { code: parsedItem.code }, undefined, true);
if (entryData) {
this.entries.push(entryData);
}
} catch (error) {
console.error(`Lỗi khi load bút toán với code ${parsedItem.code}:`, error);
}
}
}
console.log(`Đã load ${this.entries.length} bút toán thành công`);
} catch (error) {
console.error("Lỗi khi load danh sách bút toán:", error);
} finally {
this.loading = false;
}
},
openUser(userId) {
if (!userId) return;
this.showmodal = {
component: "user/UserInfo",
width: "50%",
height: "200px",
title: "User",
vbind: { userId: userId },
};
},
},
};
</script>