上传文件至 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