Files
shopdb-flask/frontend/src/views/print/MachineBadge.vue
cproudlock 6010f01de1
Some checks failed
CI / backend (push) Successful in 1m41s
CI / naming (push) Successful in 2s
CI / frontend (push) Successful in 8s
CI / migrations-mysql (push) Failing after 8s
Support subpath IIS deployment as a second install method
The app can run as an IIS Application under an existing site
(e.g. https://host/ops/) instead of its own site + port:

- frontend: vite base via VITE_BASE_PATH; router history, axios
  baseURL, and root-absolute asset/route paths resolve through
  utils/basePath.js withBase()
- backend: MOUNT_PATH (env or .env) wraps the app in a WSGI
  middleware that shifts the prefix into SCRIPT_NAME, so one knob
  serves API + SPA under the mount
- docs: INSTALL-WINDOWS-IIS.md section 7b runbook + troubleshooting
  rows; DEPLOY-WINDOWS-IIS.md pointer; commented examples in
  deploy/windows/web.config and .env.example

Root deployment unchanged (MOUNT_PATH unset, base '/'). Also folds
two stray root-absolute callers into the shared plumbing
(MachineForm relationship-types fetch, reports CSV window.open).
2026-07-13 16:11:12 -04:00

170 lines
3.6 KiB
Vue

<template>
<div>
<button class="print-btn" @click="print" v-if="!loading">Print Badge</button>
<div v-if="loading" class="loading-msg">Loading...</div>
<div v-else-if="machine" class="badge-container">
<div class="model-name">{{ modelName }}</div>
<img
v-if="isInspection"
class="machine-image"
:src="geLogo"
alt="GE Logo"
/>
<img
v-else-if="imageUrl"
class="machine-image"
:src="imageUrl"
:alt="modelName"
/>
<div class="barcode-container">
<svg ref="barcodeEl"></svg>
<div class="machine-number">*{{ machine.assetnumber }}*</div>
</div>
</div>
<div v-else class="error-msg">Machine not found</div>
</div>
</template>
<script setup>
import { ref, computed, onMounted, nextTick } from 'vue'
import { useRoute } from 'vue-router'
import { machinesApi } from '../../api'
import { getBadgeLogo } from '@/utils/siteSettings'
import { withBase } from '@/utils/basePath'
import JsBarcode from 'jsbarcode'
const route = useRoute()
const loading = ref(true)
const machine = ref(null)
const barcodeEl = ref(null)
const geLogo = ref(withBase('/ge-aerospace-logo.svg'))
const isInspection = computed(() => {
if (!machine.value) return false
return machine.value.assetnumber?.startsWith('06')
})
const modelName = computed(() => {
if (!machine.value) return ''
if (isInspection.value) return 'Inspection'
return machine.value.machine?.modelname || ''
})
const imageUrl = computed(() => {
if (!machine.value) return null
const img = machine.value.machine?.imageurl
if (img) return img.startsWith('/') ? img : `/images/models/machines/${img}`
return null
})
onMounted(async () => {
getBadgeLogo().then(logo => { geLogo.value = logo })
try {
const response = await machinesApi.get(route.params.id)
machine.value = response.data.data
} catch (error) {
console.error('Error loading machine:', error)
} finally {
loading.value = false
await nextTick()
generateBarcode()
}
})
function generateBarcode() {
if (!barcodeEl.value || !machine.value) return
try {
JsBarcode(barcodeEl.value, machine.value.assetnumber, {
format: 'CODE39',
displayValue: false,
width: 2,
height: 70,
margin: 0
})
} catch (e) {
console.error('Barcode generation error:', e)
}
}
function print() {
window.print()
}
</script>
<style scoped>
@page { size: 2.13in 3.38in; margin: 0; }
body { font-family: Arial, sans-serif; }
.badge-container {
width: 2.13in;
height: 3.38in;
background: white;
margin: 0 auto;
border: 1px solid #ccc;
display: flex;
flex-direction: column;
align-items: center;
padding: 0.15in;
box-sizing: border-box;
}
.model-name {
font-size: 12pt;
font-weight: bold;
text-align: center;
margin-bottom: 0.1in;
color: #000;
}
.machine-image {
max-width: 1.8in;
max-height: 1.5in;
object-fit: contain;
margin-bottom: 0.1in;
}
.barcode-container {
text-align: center;
margin-top: auto;
}
.barcode-container svg {
width: 1.8in;
height: 0.9in;
}
.machine-number {
font-size: 14pt;
font-weight: bold;
font-family: monospace;
margin-top: -0.1in;
color: #000;
}
.print-btn {
display: block;
margin: 20px auto;
padding: 10px 30px;
font-size: 16px;
cursor: pointer;
background: #667eea;
color: white;
border: none;
border-radius: 5px;
}
.loading-msg, .error-msg {
text-align: center;
padding: 2rem;
font-size: 1.125rem;
color: #666;
}
@media print {
.print-btn { display: none; }
.badge-container { border: none; margin: 0; }
}
</style>