上传文件至 src/components
This commit is contained in:
68
src/components/ApprovalDetail.vue
Normal file
68
src/components/ApprovalDetail.vue
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<template>
|
||||||
|
<el-popover
|
||||||
|
placement="right"
|
||||||
|
:width="300"
|
||||||
|
trigger="hover"
|
||||||
|
@show="onHoverDetail(targetId)"
|
||||||
|
>
|
||||||
|
<template #reference>
|
||||||
|
<span class="hoverable-text">
|
||||||
|
<slot />
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="detail-box" v-if="detail">
|
||||||
|
<p><strong>詳細情報</strong></p>
|
||||||
|
<p><strong>資材ID:</strong> {{ detail.id }}</p>
|
||||||
|
<p><strong>資材名:</strong> {{ detail.name }}</p>
|
||||||
|
<p><strong>数量:</strong> {{ detail.num }}</p>
|
||||||
|
<p><strong>カテゴリー:</strong> {{ detail.category_name }}</p>
|
||||||
|
<p><strong>依頼者:</strong> {{ detail.request_user_name }}</p>
|
||||||
|
<p><strong>依頼部門:</strong> {{ detail.request_dept_name }}</p>
|
||||||
|
<p><strong>依頼日:</strong> {{ detail.request_date }}</p>
|
||||||
|
<p><strong>状態:</strong> {{ detail.status_name }}</p>
|
||||||
|
<p><strong>備考:</strong> {{ detail.note }}</p>
|
||||||
|
</div>
|
||||||
|
</el-popover>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, watch, defineProps } from "vue";
|
||||||
|
import axios from "axios";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
targetId: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const detail = ref(null);
|
||||||
|
|
||||||
|
const onHoverDetail = async (id) => {
|
||||||
|
if (detail.value) return;
|
||||||
|
try {
|
||||||
|
const res = await axios.get("/api/approvalDetail/init", {
|
||||||
|
params: { targetId: id },
|
||||||
|
});
|
||||||
|
const response = res.data;
|
||||||
|
if (!response.success) {
|
||||||
|
ElMessage.error(response.message || "詳細データ取得失敗");
|
||||||
|
detail.value = { name: "取得失敗" };
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
detail.value = response.data?.sizai || { name: "データありません" };
|
||||||
|
} catch (err) {
|
||||||
|
ElMessage.error("サーバーエラーが発生しました");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.hoverable-text {
|
||||||
|
color: #409eff;
|
||||||
|
text-decoration: underline dotted;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
17
src/components/OrderDeliveryMenu.vue
Normal file
17
src/components/OrderDeliveryMenu.vue
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<template>
|
||||||
|
<li>
|
||||||
|
<a href="#">発注・納品 <span class="caret"></span></a>
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
<li><router-link to="/order">発注一覧</router-link></li>
|
||||||
|
<li><router-link to="/delever">納品一覧</router-link></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "OrderDeliveryMenu",
|
||||||
|
};
|
||||||
|
</script>
|
34
src/components/QrCode.vue
Normal file
34
src/components/QrCode.vue
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<template>
|
||||||
|
<canvas ref="qrcodeCanvas"></canvas>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, watch, defineProps } from "vue";
|
||||||
|
import QRCode from "qrcode";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
id: {
|
||||||
|
type: [String, Number],
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const qrcodeCanvas = ref(null);
|
||||||
|
|
||||||
|
const renderQRCode = async () => {
|
||||||
|
const value = String(props.id || "").trim();
|
||||||
|
if (!value || !qrcodeCanvas.value) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await QRCode.toCanvas(qrcodeCanvas.value, value, {
|
||||||
|
width: 120,
|
||||||
|
margin: 1,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error("QRコード生成エラー:", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(renderQRCode);
|
||||||
|
watch(() => props.id, renderQRCode);
|
||||||
|
</script>
|
17
src/components/StockInOutMenu.vue
Normal file
17
src/components/StockInOutMenu.vue
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<template>
|
||||||
|
<li>
|
||||||
|
<a href="#">入庫・出庫 <span class="caret"></span></a>
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
<li><router-link to="/inStore">入庫一覧</router-link></li>
|
||||||
|
<li><router-link to="/outStore">出庫一覧</router-link></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "StockInOutMenu",
|
||||||
|
};
|
||||||
|
</script>
|
98
src/components/UserMenu.vue
Normal file
98
src/components/UserMenu.vue
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div style="margin-bottom: 10px; color: blue">
|
||||||
|
ユーザー: {{ user.name }} 部署: {{ user.depname }} 権限: {{ roleName }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cp_navi">
|
||||||
|
<ul>
|
||||||
|
<!-- 購入依頼 -->
|
||||||
|
<li v-if="user.role_class === '1'">
|
||||||
|
<router-link to="/request">購入依頼</router-link>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- 購入承認 -->
|
||||||
|
<li v-if="user.role_class === '2'">
|
||||||
|
<router-link to="/approval">購入承認</router-link>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- 発注・納品 -->
|
||||||
|
<OrderDeliveryMenu v-if="user.role_class === '3'" />
|
||||||
|
|
||||||
|
<!-- 入庫・出庫 -->
|
||||||
|
<StockInOutMenu v-if="user.role_class === '4'" />
|
||||||
|
|
||||||
|
<!-- 購入承認 -->
|
||||||
|
<li v-if="user.role_class === '5'">
|
||||||
|
<router-link to="/systemAdmin">Administrator</router-link>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- ログアウト -->
|
||||||
|
<li>
|
||||||
|
<a href="#" @click.prevent="logout">ログアウト</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="message">
|
||||||
|
<span :color="messageflag ? 'green' : 'red'">{{ message }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, computed } from "vue";
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
|
import axios from "axios";
|
||||||
|
import OrderDeliveryMenu from "./OrderDeliveryMenu.vue";
|
||||||
|
import StockInOutMenu from "./StockInOutMenu.vue";
|
||||||
|
import "@/assets/common.css";
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const user = ref({
|
||||||
|
name: "",
|
||||||
|
depname: "",
|
||||||
|
role_class: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
const logout = async () => {
|
||||||
|
await axios.get("/api/logout");
|
||||||
|
sessionStorage.removeItem("loginInfo");
|
||||||
|
router.push("/login");
|
||||||
|
};
|
||||||
|
|
||||||
|
const message = ref("");
|
||||||
|
const messageflag = ref(true);
|
||||||
|
|
||||||
|
const roleNameMap = {
|
||||||
|
1: "一般ユーザー",
|
||||||
|
2: "部門長",
|
||||||
|
3: "発注担当者",
|
||||||
|
4: "倉庫管理者",
|
||||||
|
5: "システム管理者",
|
||||||
|
};
|
||||||
|
|
||||||
|
const roleName = computed(() => roleNameMap[user.value.role_class] || "不明");
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
try {
|
||||||
|
const res = await axios.get("/api/me");
|
||||||
|
const response = res.data;
|
||||||
|
if (response.success) {
|
||||||
|
user.value = response.data;
|
||||||
|
} else {
|
||||||
|
console.error("ユーザ情報取得失敗", response.message);
|
||||||
|
router.push("/login");
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error("ユーザ情報取得失敗", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.has-submenu:hover > .submenu {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
</style>
|
Reference in New Issue
Block a user