first commit
This commit is contained in:
+24
@@ -0,0 +1,24 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["Vue.volar"]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
# Vue 3 + Vite
|
||||
|
||||
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||
|
||||
Learn more about IDE Support for Vue in the [Vue Docs Scaling up Guide](https://vuejs.org/guide/scaling-up/tooling.html#ide-support).
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>‎</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Generated
+2022
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "print-tag-system",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@headlessui/vue": "^1.7.23",
|
||||
"@tailwindcss/postcss": "^4.1.11",
|
||||
"vue": "^3.5.17"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^6.0.0",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"postcss": "^8.5.6",
|
||||
"tailwindcss": "^4.1.11",
|
||||
"vite": "^7.0.4"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
plugins: {
|
||||
'@tailwindcss/postcss': {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
+17
@@ -0,0 +1,17 @@
|
||||
<script setup>
|
||||
import Main from './components/Main.vue'
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Main />
|
||||
</template>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
/* text-align: left; */
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 496 B |
@@ -0,0 +1,184 @@
|
||||
<template>
|
||||
<div :class="'print-area ' + (isShow ? 'border' : '')" @dblclick="onDblClick">
|
||||
<div :class="'item ' + (isShow ? 'show' : 'hide')">
|
||||
<div class='left-content'>
|
||||
<img class='qrcode' src='\qrcode.png'>
|
||||
<div>长沙加零</div>
|
||||
<div>17373135368</div>
|
||||
</div>
|
||||
<div class="right-content">
|
||||
<div>{{ config.name }}</div>
|
||||
<div>{{ config.cpu }}</div>
|
||||
<div>{{ config.memory }}</div>
|
||||
<div>{{ config.hardDisk }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="id">
|
||||
<span>
|
||||
{{ id }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
const isShow = ref(true);
|
||||
|
||||
const props = defineProps(['id', 'config']);
|
||||
|
||||
const onDblClick = () => {
|
||||
isShow.value = !isShow.value;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
export const formSchema = {
|
||||
formItems: [
|
||||
{ type: 'input', label: '标题', key: 'name', required: true },
|
||||
{ type: 'input', label: 'CPU', key: 'cpu', required: true },
|
||||
{
|
||||
type: 'select',
|
||||
label: '内存',
|
||||
key: 'memory',
|
||||
options: [
|
||||
{ label: '8G', value: '8G' },
|
||||
{ label: '4G', value: '4G' },
|
||||
{ label: '16G', value: '16G' }
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '硬盘',
|
||||
key: 'hardDisk',
|
||||
options: [
|
||||
{ label: '120G', value: '120G' },
|
||||
{ label: '256G', value: '256G' },
|
||||
{ label: '512G', value: '512G' }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export const initialValues = {
|
||||
name: "22寸一体机",
|
||||
cpu:"M380",
|
||||
memory: "8G",
|
||||
hardDisk: "256G"
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.print-area {
|
||||
/* border: 0.1mm dashed #87CEFA; */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-content: flex-start;
|
||||
margin: 0.25mm;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.show {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 0.1mm dashed #87CEFA;
|
||||
}
|
||||
|
||||
.print-area:nth-child(41),
|
||||
.print-area:nth-child(42),
|
||||
.print-area:nth-child(43),
|
||||
.print-area:nth-child(44) {
|
||||
padding-bottom: 4mm;
|
||||
}
|
||||
|
||||
.print-area:nth-child(41) .qrcode,
|
||||
.print-area:nth-child(42) .qrcode,
|
||||
.print-area:nth-child(43) .qrcode,
|
||||
.print-area:nth-child(44) .qrcode {
|
||||
height: calc(100% - 5mm);
|
||||
}
|
||||
|
||||
.item {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.tag {
|
||||
color: red;
|
||||
font-size: 0.8cm;
|
||||
}
|
||||
|
||||
.reason,
|
||||
.time {
|
||||
font-size: 4mm;
|
||||
}
|
||||
|
||||
/*Styling below is used just for positioning the items inside the label. */
|
||||
|
||||
.left-content {
|
||||
width: 24mm;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: inherit;
|
||||
font-size: 3mm;
|
||||
line-height: 3mm;
|
||||
color: #87CEFA;
|
||||
}
|
||||
|
||||
.right-content {
|
||||
display: grid;
|
||||
font-size: 4mm;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.qrcode {
|
||||
height: calc(100% - 6mm);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.id {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 2cm;
|
||||
pointer-events: none;
|
||||
color: #87CEFA60;
|
||||
}
|
||||
|
||||
.id span {
|
||||
/* display: block;
|
||||
margin: 0 auto; */
|
||||
}
|
||||
|
||||
@media print {
|
||||
.id * {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.hide * {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.show {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,184 @@
|
||||
<template>
|
||||
<div :class="'print-area ' + (isShow ? 'border' : '')" @dblclick="onDblClick">
|
||||
<div :class="'item ' + (isShow ? 'show' : 'hide')">
|
||||
<div class='left-content'>
|
||||
<img class='qrcode' src='\qrcode.png'>
|
||||
<div>长沙加零</div>
|
||||
<div>17373135368</div>
|
||||
</div>
|
||||
<div class="right-content">
|
||||
<div>{{ config.name }}</div>
|
||||
<div>{{ config.cpu }}</div>
|
||||
<div>{{ config.memory }}</div>
|
||||
<div>{{ config.hardDisk }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="id">
|
||||
<span>
|
||||
{{ id }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
const isShow = ref(true);
|
||||
|
||||
const props = defineProps(['id', 'config']);
|
||||
|
||||
const onDblClick = () => {
|
||||
isShow.value = !isShow.value;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
export const formSchema = {
|
||||
formItems: [
|
||||
{ type: 'input', label: '标题', key: 'name', required: true },
|
||||
{ type: 'input', label: 'CPU', key: 'cpu', required: true },
|
||||
{
|
||||
type: 'select',
|
||||
label: '内存',
|
||||
key: 'memory',
|
||||
options: [
|
||||
{ label: '8G', value: '8G' },
|
||||
{ label: '4G', value: '4G' },
|
||||
{ label: '16G', value: '16G' }
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '硬盘',
|
||||
key: 'hardDisk',
|
||||
options: [
|
||||
{ label: '120G', value: '120G' },
|
||||
{ label: '256G', value: '256G' },
|
||||
{ label: '512G', value: '512G' }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export const initialValues = {
|
||||
name: "24寸一体机",
|
||||
cpu:"I5 3代",
|
||||
memory: "8G",
|
||||
hardDisk: "256G"
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.print-area {
|
||||
/* border: 0.1mm dashed #87CEFA; */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-content: flex-start;
|
||||
margin: 0.25mm;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.show {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 0.1mm dashed #87CEFA;
|
||||
}
|
||||
|
||||
.print-area:nth-child(41),
|
||||
.print-area:nth-child(42),
|
||||
.print-area:nth-child(43),
|
||||
.print-area:nth-child(44) {
|
||||
padding-bottom: 4mm;
|
||||
}
|
||||
|
||||
.print-area:nth-child(41) .qrcode,
|
||||
.print-area:nth-child(42) .qrcode,
|
||||
.print-area:nth-child(43) .qrcode,
|
||||
.print-area:nth-child(44) .qrcode {
|
||||
height: calc(100% - 5mm);
|
||||
}
|
||||
|
||||
.item {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.tag {
|
||||
color: red;
|
||||
font-size: 0.8cm;
|
||||
}
|
||||
|
||||
.reason,
|
||||
.time {
|
||||
font-size: 4mm;
|
||||
}
|
||||
|
||||
/*Styling below is used just for positioning the items inside the label. */
|
||||
|
||||
.left-content {
|
||||
width: 24mm;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: inherit;
|
||||
font-size: 3mm;
|
||||
line-height: 3mm;
|
||||
color: #87CEFA;
|
||||
}
|
||||
|
||||
.right-content {
|
||||
display: grid;
|
||||
font-size: 4mm;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.qrcode {
|
||||
height: calc(100% - 6mm);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.id {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 2cm;
|
||||
pointer-events: none;
|
||||
color: #87CEFA60;
|
||||
}
|
||||
|
||||
.id span {
|
||||
/* display: block;
|
||||
margin: 0 auto; */
|
||||
}
|
||||
|
||||
@media print {
|
||||
.id * {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.hide * {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.show {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,171 @@
|
||||
<template>
|
||||
<form @submit.prevent="submitForm">
|
||||
<div v-for="(item, index) in formConfig.formItems" :key="index">
|
||||
<!-- 文本输入框 -->
|
||||
<div v-if="item.type === 'input' || item.type === 'password'">
|
||||
<!-- <label>{{ item.label }}</label>
|
||||
<input
|
||||
:type="item.type"
|
||||
v-model="formData[item.key]"
|
||||
:placeholder="item.placeholder"
|
||||
> -->
|
||||
<Input :title="item.label" :type="item.type" v-model="formData[item.key]"></Input>
|
||||
<span v-if="errors[item.key]" class="error">{{ errors[item.key] }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 下拉选择 -->
|
||||
<div v-if="item.type === 'select'">
|
||||
<label>{{ item.label }}</label>
|
||||
<select v-model="formData[item.key]">
|
||||
<option v-for="(opt, idx) in item.options" :key="idx" :value="opt.value">
|
||||
{{ opt.label }}
|
||||
</option>
|
||||
</select>
|
||||
<!-- <Select :data="item.options" v-model="formData[item.key]"></Select> -->
|
||||
</div>
|
||||
|
||||
<!-- 复选框 -->
|
||||
<div v-if="item.type === 'checkbox'">
|
||||
<label>{{ item.label }}</label>
|
||||
<div v-for="(opt, idx) in item.options" :key="idx">
|
||||
<input type="checkbox" :value="opt.value" v-model="formData[item.key]">
|
||||
{{ opt.label }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 单选框 -->
|
||||
<div v-if="item.type === 'radio'">
|
||||
<label>{{ item.label }}</label>
|
||||
<div v-for="(opt, idx) in item.options" :key="idx">
|
||||
<input type="radio" :value="opt.value" v-model="formData[item.key]">
|
||||
{{ opt.label }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary" type="submit">提交</button>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Input from "./Input/Index.vue";
|
||||
import Select from "./Select/index.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
"Input": Input,
|
||||
"Select": Select
|
||||
},
|
||||
props: {
|
||||
formConfig: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
initialData: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
emits: ['submit'],
|
||||
data() {
|
||||
return {
|
||||
formData: { ...this.initialData },
|
||||
errors: {}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
submitForm() {
|
||||
if (this.validateForm()) {
|
||||
this.$emit('submit', this.formData)
|
||||
console.log(this.formData);
|
||||
}
|
||||
},
|
||||
|
||||
validateForm() {
|
||||
this.errors = {}
|
||||
let isValid = true
|
||||
|
||||
this.formConfig.formItems.forEach(item => {
|
||||
if (item.required && !this.formData[item.key]) {
|
||||
this.errors[item.key] = item.rules?.[0]?.message || `${item.label}不能为空`
|
||||
isValid = false
|
||||
}
|
||||
})
|
||||
|
||||
return isValid
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
initialData: {
|
||||
handler(newVal) {
|
||||
this.formData = { ...newVal }
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.error {
|
||||
color: red;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* 核心美化代码 */
|
||||
select {
|
||||
width: 100%;
|
||||
padding: 16px 50px 16px 20px;
|
||||
font-size: 1rem;
|
||||
border: 2px solid #d1d1d1;
|
||||
border-radius: 12px;
|
||||
background-color: white;
|
||||
appearance: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.05);
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 悬停状态 */
|
||||
select:hover {
|
||||
border-color: #a777e3;
|
||||
box-shadow: 0 5px 15px rgba(167, 119, 227, 0.1);
|
||||
}
|
||||
|
||||
/* 聚焦状态 */
|
||||
select:focus {
|
||||
border-color: #6e8efb;
|
||||
box-shadow: 0 0 0 3px rgba(110, 142, 251, 0.2);
|
||||
}
|
||||
|
||||
/* 禁用状态 */
|
||||
select:disabled {
|
||||
background-color: #f5f5f5;
|
||||
color: #999;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* 选项样式 */
|
||||
select option {
|
||||
padding: 12px 20px;
|
||||
font-size: 1rem;
|
||||
background: white;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
select option:hover {
|
||||
background: #f0f4ff !important;
|
||||
color: #1a2a6c;
|
||||
}
|
||||
|
||||
select option:checked {
|
||||
background: #eef2ff;
|
||||
color: #1a2a6c;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<div class="print-area border">
|
||||
<div class="item" style="display: block;">
|
||||
<div class="tag">{{ config.title }}</div>
|
||||
<div class="reason" style="font-size: 4mm;margin-top: 2mm;">{{ config.reason }}</div>
|
||||
<div class="time">{{ config.time }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
const isShow = ref(true);
|
||||
|
||||
const props = defineProps(['id', 'config']);
|
||||
|
||||
const onDblClick = () => {
|
||||
isShow.value = !isShow.value;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
export const formSchema = {
|
||||
formItems: [
|
||||
{
|
||||
type: 'select',
|
||||
label: '标题',
|
||||
key: 'title',
|
||||
options: [
|
||||
{ label: '售后', value: '售后' },
|
||||
{ label: '故障', value: '故障' },
|
||||
{ label: '资料备份', value: '资料备份' },
|
||||
{ label: '维修/升级', value: '维修/升级' }
|
||||
]
|
||||
},
|
||||
{ type: 'input', label: '说明', key: 'reason' },
|
||||
{ type: 'input', label: '时间', key: 'time' }
|
||||
]
|
||||
};
|
||||
|
||||
export const initialValues = {
|
||||
title: "售后",
|
||||
reason: "硬盘卡,无法格式化",
|
||||
time: ""
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.print-area {
|
||||
/* border: 0.1mm dashed #87CEFA; */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-content: flex-start;
|
||||
margin: 0.25mm;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 0.1mm dashed #87CEFA;
|
||||
}
|
||||
|
||||
.print-area:nth-child(41),
|
||||
.print-area:nth-child(42),
|
||||
.print-area:nth-child(43),
|
||||
.print-area:nth-child(44) {
|
||||
padding-bottom: 4mm;
|
||||
}
|
||||
|
||||
.print-area:nth-child(41) .qrcode,
|
||||
.print-area:nth-child(42) .qrcode,
|
||||
.print-area:nth-child(43) .qrcode,
|
||||
.print-area:nth-child(44) .qrcode {
|
||||
height: calc(100% - 5mm);
|
||||
}
|
||||
|
||||
.item {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.tag {
|
||||
color: red;
|
||||
font-size: 0.8cm;
|
||||
}
|
||||
|
||||
.reason,
|
||||
.time {
|
||||
font-size: 4mm;
|
||||
}
|
||||
|
||||
/*Styling below is used just for positioning the items inside the label. */
|
||||
|
||||
.left-content {
|
||||
width: 24mm;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: inherit;
|
||||
font-size: 3mm;
|
||||
line-height: 3mm;
|
||||
color: #87CEFA;
|
||||
}
|
||||
|
||||
.right-content {
|
||||
display: grid;
|
||||
font-size: 4mm;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.qrcode {
|
||||
height: calc(100% - 6mm);
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,193 @@
|
||||
<template>
|
||||
<div :class="'print-area ' + (isShow ? 'border' : '')" @dblclick="onDblClick">
|
||||
<div :class="'item ' + (isShow ? 'show' : 'hide')">
|
||||
<div class='left-content'>
|
||||
<img class='qrcode' src='\qrcode.png'>
|
||||
<div>长沙加零</div>
|
||||
<div>17373135368</div>
|
||||
</div>
|
||||
<div class="right-content">
|
||||
<div>{{ config.cpu }}</div>
|
||||
<div>{{ config.memory }}</div>
|
||||
<div>{{ config.hardDisk }}</div>
|
||||
<div>{{ config.system }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="id">
|
||||
<span>
|
||||
{{ id }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
const isShow = ref(true);
|
||||
|
||||
const props = defineProps(['id', 'config']);
|
||||
|
||||
const onDblClick = () => {
|
||||
isShow.value = !isShow.value;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
export const formSchema = {
|
||||
formItems: [
|
||||
{ type: 'input', label: 'CPU', key: 'cpu', required: true },
|
||||
{
|
||||
type: 'select',
|
||||
label: '内存',
|
||||
key: 'memory',
|
||||
options: [
|
||||
{ label: '8G', value: '8G' },
|
||||
{ label: '4G', value: '4G' },
|
||||
{ label: '16G', value: '16G' }
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '硬盘',
|
||||
key: 'hardDisk',
|
||||
options: [
|
||||
{ label: '120G', value: '120G' },
|
||||
{ label: '256G', value: '256G' },
|
||||
{ label: '512G', value: '512G' }
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '操作系统',
|
||||
key: 'system',
|
||||
options: [
|
||||
{ label: '无', value: '' },
|
||||
{ label: 'win10', value: 'win10' },
|
||||
{ label: 'win7', value: 'win7' }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export const initialValues = {
|
||||
cpu: "G3260",
|
||||
memory: "8G",
|
||||
hardDisk: "120G",
|
||||
system: ""
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.print-area {
|
||||
/* border: 0.1mm dashed #87CEFA; */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-content: flex-start;
|
||||
margin: 0.25mm;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.show {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 0.1mm dashed #87CEFA;
|
||||
}
|
||||
|
||||
.print-area:nth-child(41),
|
||||
.print-area:nth-child(42),
|
||||
.print-area:nth-child(43),
|
||||
.print-area:nth-child(44) {
|
||||
padding-bottom: 4mm;
|
||||
}
|
||||
|
||||
.print-area:nth-child(41) .qrcode,
|
||||
.print-area:nth-child(42) .qrcode,
|
||||
.print-area:nth-child(43) .qrcode,
|
||||
.print-area:nth-child(44) .qrcode {
|
||||
height: calc(100% - 5mm);
|
||||
}
|
||||
|
||||
.item {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.tag {
|
||||
color: red;
|
||||
font-size: 0.8cm;
|
||||
}
|
||||
|
||||
.reason,
|
||||
.time {
|
||||
font-size: 4mm;
|
||||
}
|
||||
|
||||
/*Styling below is used just for positioning the items inside the label. */
|
||||
|
||||
.left-content {
|
||||
width: 24mm;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: inherit;
|
||||
font-size: 3mm;
|
||||
line-height: 3mm;
|
||||
color: #87CEFA;
|
||||
}
|
||||
|
||||
.right-content {
|
||||
display: grid;
|
||||
font-size: 4mm;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.qrcode {
|
||||
height: calc(100% - 6mm);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.id {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 2cm;
|
||||
pointer-events: none;
|
||||
color: #87CEFA60;
|
||||
}
|
||||
|
||||
.id span {
|
||||
/* display: block;
|
||||
margin: 0 auto; */
|
||||
}
|
||||
|
||||
@media print {
|
||||
.id * {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.hide * {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.show {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,193 @@
|
||||
<template>
|
||||
<div :class="'print-area ' + (isShow ? 'border' : '')" @dblclick="onDblClick">
|
||||
<div :class="'item ' + (isShow ? 'show' : 'hide')">
|
||||
<div class='left-content'>
|
||||
<img class='qrcode' src='\qrcode.png'>
|
||||
<div>长沙加零</div>
|
||||
<div>17373135368</div>
|
||||
</div>
|
||||
<div class="right-content">
|
||||
<div>{{ config.cpu }}</div>
|
||||
<div>{{ config.memory }}</div>
|
||||
<div>{{ config.hardDisk }}</div>
|
||||
<div>{{ config.system }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="id">
|
||||
<span>
|
||||
{{ id }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
const isShow = ref(true);
|
||||
|
||||
const props = defineProps(['id', 'config']);
|
||||
|
||||
const onDblClick = () => {
|
||||
isShow.value = !isShow.value;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
export const formSchema = {
|
||||
formItems: [
|
||||
{ type: 'input', label: 'CPU', key: 'cpu', required: true },
|
||||
{
|
||||
type: 'select',
|
||||
label: '内存',
|
||||
key: 'memory',
|
||||
options: [
|
||||
{ label: '8G', value: '8G' },
|
||||
{ label: '4G', value: '4G' },
|
||||
{ label: '16G', value: '16G' }
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '硬盘',
|
||||
key: 'hardDisk',
|
||||
options: [
|
||||
{ label: '120G', value: '120G' },
|
||||
{ label: '256G', value: '256G' },
|
||||
{ label: '512G', value: '512G' }
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '操作系统',
|
||||
key: 'system',
|
||||
options: [
|
||||
{ label: '无', value: '' },
|
||||
{ label: 'win10', value: 'win10' },
|
||||
{ label: 'win7', value: 'win7' }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export const initialValues = {
|
||||
cpu: "i3 4130",
|
||||
memory: "8G",
|
||||
hardDisk: "120G",
|
||||
system: ""
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.print-area {
|
||||
/* border: 0.1mm dashed #87CEFA; */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-content: flex-start;
|
||||
margin: 0.25mm;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.show {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 0.1mm dashed #87CEFA;
|
||||
}
|
||||
|
||||
.print-area:nth-child(41),
|
||||
.print-area:nth-child(42),
|
||||
.print-area:nth-child(43),
|
||||
.print-area:nth-child(44) {
|
||||
padding-bottom: 4mm;
|
||||
}
|
||||
|
||||
.print-area:nth-child(41) .qrcode,
|
||||
.print-area:nth-child(42) .qrcode,
|
||||
.print-area:nth-child(43) .qrcode,
|
||||
.print-area:nth-child(44) .qrcode {
|
||||
height: calc(100% - 5mm);
|
||||
}
|
||||
|
||||
.item {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.tag {
|
||||
color: red;
|
||||
font-size: 0.8cm;
|
||||
}
|
||||
|
||||
.reason,
|
||||
.time {
|
||||
font-size: 4mm;
|
||||
}
|
||||
|
||||
/*Styling below is used just for positioning the items inside the label. */
|
||||
|
||||
.left-content {
|
||||
width: 24mm;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: inherit;
|
||||
font-size: 3mm;
|
||||
line-height: 3mm;
|
||||
color: #87CEFA;
|
||||
}
|
||||
|
||||
.right-content {
|
||||
display: grid;
|
||||
font-size: 4mm;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.qrcode {
|
||||
height: calc(100% - 6mm);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.id {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 2cm;
|
||||
pointer-events: none;
|
||||
color: #87CEFA60;
|
||||
}
|
||||
|
||||
.id span {
|
||||
/* display: block;
|
||||
margin: 0 auto; */
|
||||
}
|
||||
|
||||
@media print {
|
||||
.id * {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.hide * {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.show {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,198 @@
|
||||
<template>
|
||||
<div :class="'print-area ' + (isShow ? 'border' : '')" @dblclick="onDblClick">
|
||||
<div :class="'item ' + (isShow ? 'show' : 'hide')">
|
||||
<div class='left-content'>
|
||||
<img class='qrcode' src='\qrcode.png'>
|
||||
<div>长沙加零</div>
|
||||
<div>17373135368</div>
|
||||
</div>
|
||||
<div class="right-content">
|
||||
<div>{{ config.cpu }}</div>
|
||||
<div>{{ config.memory }}</div>
|
||||
<div>{{ config.hardDisk }}</div>
|
||||
<div>{{ config.graphicsCard }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="id">
|
||||
<span>
|
||||
{{ id }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
const isShow = ref(true);
|
||||
|
||||
const props = defineProps(['id', 'config']);
|
||||
|
||||
const onDblClick = () => {
|
||||
isShow.value = !isShow.value;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
export const formSchema = {
|
||||
formItems: [
|
||||
{ type: 'input', label: 'CPU', key: 'cpu', required: true },
|
||||
{
|
||||
type: 'select',
|
||||
label: '内存',
|
||||
key: 'memory',
|
||||
options: [
|
||||
{ label: '8G', value: '8G' },
|
||||
{ label: '16G', value: '16G' },
|
||||
{ label: '32G', value: '32G' }
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '硬盘',
|
||||
key: 'hardDisk',
|
||||
options: [
|
||||
{ label: '120G', value: '120G' },
|
||||
{ label: '256G', value: '256G' },
|
||||
{ label: '256G+1tb', value: '256G+1tb' },
|
||||
{ label: '512G', value: '512G' },
|
||||
{ label: '1tb', value: '1tb' }
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '显卡',
|
||||
key: 'graphicsCard',
|
||||
options: [
|
||||
{ label: '1060', value: '1060(3,5,6)' },
|
||||
{ label: '960', value: '960' },
|
||||
{ label: '1660', value: '1660' },
|
||||
{ label: '2060', value: '2060' },
|
||||
{ label: '3060', value: '3060' },
|
||||
{ label: '4060', value: '4060' }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export const initialValues = {
|
||||
cpu: "i5 10400F",
|
||||
memory: "16G",
|
||||
hardDisk: "256G",
|
||||
graphicsCard: "1060(3,5,6)"
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.print-area {
|
||||
/* border: 0.1mm dashed #87CEFA; */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-content: flex-start;
|
||||
margin: 0.25mm;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.show {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 0.1mm dashed #87CEFA;
|
||||
}
|
||||
|
||||
.print-area:nth-child(41),
|
||||
.print-area:nth-child(42),
|
||||
.print-area:nth-child(43),
|
||||
.print-area:nth-child(44) {
|
||||
padding-bottom: 4mm;
|
||||
}
|
||||
|
||||
.print-area:nth-child(41) .qrcode,
|
||||
.print-area:nth-child(42) .qrcode,
|
||||
.print-area:nth-child(43) .qrcode,
|
||||
.print-area:nth-child(44) .qrcode {
|
||||
height: calc(100% - 5mm);
|
||||
}
|
||||
|
||||
.item {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.tag {
|
||||
color: red;
|
||||
font-size: 0.8cm;
|
||||
}
|
||||
|
||||
.reason,
|
||||
.time {
|
||||
font-size: 4mm;
|
||||
}
|
||||
|
||||
/*Styling below is used just for positioning the items inside the label. */
|
||||
|
||||
.left-content {
|
||||
width: 24mm;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: inherit;
|
||||
font-size: 3mm;
|
||||
line-height: 3mm;
|
||||
color: #87CEFA;
|
||||
}
|
||||
|
||||
.right-content {
|
||||
display: grid;
|
||||
font-size: 4mm;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.qrcode {
|
||||
height: calc(100% - 6mm);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.id {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 2cm;
|
||||
pointer-events: none;
|
||||
color: #87CEFA60;
|
||||
}
|
||||
|
||||
.id span {
|
||||
/* display: block;
|
||||
margin: 0 auto; */
|
||||
}
|
||||
|
||||
@media print {
|
||||
.id * {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.hide * {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.show {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,198 @@
|
||||
<template>
|
||||
<div :class="'print-area ' + (isShow ? 'border' : '')" @dblclick="onDblClick">
|
||||
<div :class="'item ' + (isShow ? 'show' : 'hide')">
|
||||
<div class='left-content'>
|
||||
<img class='qrcode' src='\qrcode.png'>
|
||||
<div>长沙加零</div>
|
||||
<div>17373135368</div>
|
||||
</div>
|
||||
<div class="right-content">
|
||||
<div>{{ config.cpu }}</div>
|
||||
<div>{{ config.memory }}</div>
|
||||
<div>{{ config.hardDisk }}</div>
|
||||
<div>{{ config.graphicsCard }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="id">
|
||||
<span>
|
||||
{{ id }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
const isShow = ref(true);
|
||||
|
||||
const props = defineProps(['id', 'config']);
|
||||
|
||||
const onDblClick = () => {
|
||||
isShow.value = !isShow.value;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
export const formSchema = {
|
||||
formItems: [
|
||||
{ type: 'input', label: 'CPU', key: 'cpu', required: true },
|
||||
{
|
||||
type: 'select',
|
||||
label: '内存',
|
||||
key: 'memory',
|
||||
options: [
|
||||
{ label: '8G', value: '8G' },
|
||||
{ label: '16G', value: '16G' },
|
||||
{ label: '32G', value: '32G' }
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '硬盘',
|
||||
key: 'hardDisk',
|
||||
options: [
|
||||
{ label: '120G', value: '120G' },
|
||||
{ label: '256G', value: '256G' },
|
||||
{ label: '256G+1tb', value: '256G+1tb' },
|
||||
{ label: '512G', value: '512G' },
|
||||
{ label: '1tb', value: '1tb' }
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '显卡',
|
||||
key: 'graphicsCard',
|
||||
options: [
|
||||
{ label: '1060', value: '1060(3,5,6)' },
|
||||
{ label: '960', value: '960' },
|
||||
{ label: '1660', value: '1660' },
|
||||
{ label: '2060', value: '2060' },
|
||||
{ label: '3060', value: '3060' },
|
||||
{ label: '4060', value: '4060' }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export const initialValues = {
|
||||
cpu: "i5 10400F",
|
||||
memory: "16G",
|
||||
hardDisk: "512G",
|
||||
graphicsCard: "2060"
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.print-area {
|
||||
/* border: 0.1mm dashed #87CEFA; */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-content: flex-start;
|
||||
margin: 0.25mm;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.show {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 0.1mm dashed #87CEFA;
|
||||
}
|
||||
|
||||
.print-area:nth-child(41),
|
||||
.print-area:nth-child(42),
|
||||
.print-area:nth-child(43),
|
||||
.print-area:nth-child(44) {
|
||||
padding-bottom: 4mm;
|
||||
}
|
||||
|
||||
.print-area:nth-child(41) .qrcode,
|
||||
.print-area:nth-child(42) .qrcode,
|
||||
.print-area:nth-child(43) .qrcode,
|
||||
.print-area:nth-child(44) .qrcode {
|
||||
height: calc(100% - 5mm);
|
||||
}
|
||||
|
||||
.item {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.tag {
|
||||
color: red;
|
||||
font-size: 0.8cm;
|
||||
}
|
||||
|
||||
.reason,
|
||||
.time {
|
||||
font-size: 4mm;
|
||||
}
|
||||
|
||||
/*Styling below is used just for positioning the items inside the label. */
|
||||
|
||||
.left-content {
|
||||
width: 24mm;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: inherit;
|
||||
font-size: 3mm;
|
||||
line-height: 3mm;
|
||||
color: #87CEFA;
|
||||
}
|
||||
|
||||
.right-content {
|
||||
display: grid;
|
||||
font-size: 4mm;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.qrcode {
|
||||
height: calc(100% - 6mm);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.id {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 2cm;
|
||||
pointer-events: none;
|
||||
color: #87CEFA60;
|
||||
}
|
||||
|
||||
.id span {
|
||||
/* display: block;
|
||||
margin: 0 auto; */
|
||||
}
|
||||
|
||||
@media print {
|
||||
.id * {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.hide * {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.show {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,193 @@
|
||||
<template>
|
||||
<div :class="'print-area ' + (isShow ? 'border' : '')" @dblclick="onDblClick">
|
||||
<div :class="'item ' + (isShow ? 'show' : 'hide')">
|
||||
<div class='left-content'>
|
||||
<img class='qrcode' src='\qrcode.png'>
|
||||
<div>长沙加零</div>
|
||||
<div>17373135368</div>
|
||||
</div>
|
||||
<div class="right-content">
|
||||
<div>{{ config.cpu }}</div>
|
||||
<div>{{ config.memory }}</div>
|
||||
<div>{{ config.hardDisk }}</div>
|
||||
<div>{{ config.system }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="id">
|
||||
<span>
|
||||
{{ id }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
const isShow = ref(true);
|
||||
|
||||
const props = defineProps(['id', 'config']);
|
||||
|
||||
const onDblClick = () => {
|
||||
isShow.value = !isShow.value;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
export const formSchema = {
|
||||
formItems: [
|
||||
{ type: 'input', label: 'CPU', key: 'cpu', required: true },
|
||||
{
|
||||
type: 'select',
|
||||
label: '内存',
|
||||
key: 'memory',
|
||||
options: [
|
||||
{ label: '8G', value: '8G' },
|
||||
{ label: '4G', value: '4G' },
|
||||
{ label: '16G', value: '16G' }
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '硬盘',
|
||||
key: 'hardDisk',
|
||||
options: [
|
||||
{ label: '120G', value: '120G' },
|
||||
{ label: '256G', value: '256G' },
|
||||
{ label: '512G', value: '512G' }
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '操作系统',
|
||||
key: 'system',
|
||||
options: [
|
||||
{ label: '无', value: '' },
|
||||
{ label: 'win10', value: 'win10' },
|
||||
{ label: 'win7', value: 'win7' }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export const initialValues = {
|
||||
cpu: "i5 4590",
|
||||
memory: "8G",
|
||||
hardDisk: "120G",
|
||||
system: ""
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.print-area {
|
||||
/* border: 0.1mm dashed #87CEFA; */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-content: flex-start;
|
||||
margin: 0.25mm;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.show {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 0.1mm dashed #87CEFA;
|
||||
}
|
||||
|
||||
.print-area:nth-child(41),
|
||||
.print-area:nth-child(42),
|
||||
.print-area:nth-child(43),
|
||||
.print-area:nth-child(44) {
|
||||
padding-bottom: 4mm;
|
||||
}
|
||||
|
||||
.print-area:nth-child(41) .qrcode,
|
||||
.print-area:nth-child(42) .qrcode,
|
||||
.print-area:nth-child(43) .qrcode,
|
||||
.print-area:nth-child(44) .qrcode {
|
||||
height: calc(100% - 5mm);
|
||||
}
|
||||
|
||||
.item {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.tag {
|
||||
color: red;
|
||||
font-size: 0.8cm;
|
||||
}
|
||||
|
||||
.reason,
|
||||
.time {
|
||||
font-size: 4mm;
|
||||
}
|
||||
|
||||
/*Styling below is used just for positioning the items inside the label. */
|
||||
|
||||
.left-content {
|
||||
width: 24mm;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: inherit;
|
||||
font-size: 3mm;
|
||||
line-height: 3mm;
|
||||
color: #87CEFA;
|
||||
}
|
||||
|
||||
.right-content {
|
||||
display: grid;
|
||||
font-size: 4mm;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.qrcode {
|
||||
height: calc(100% - 6mm);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.id {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 2cm;
|
||||
pointer-events: none;
|
||||
color: #87CEFA60;
|
||||
}
|
||||
|
||||
.id span {
|
||||
/* display: block;
|
||||
margin: 0 auto; */
|
||||
}
|
||||
|
||||
@media print {
|
||||
.id * {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.hide * {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.show {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,198 @@
|
||||
<template>
|
||||
<div :class="'print-area ' + (isShow ? 'border' : '')" @dblclick="onDblClick">
|
||||
<div :class="'item ' + (isShow ? 'show' : 'hide')">
|
||||
<div class='left-content'>
|
||||
<img class='qrcode' src='\qrcode.png'>
|
||||
<div>长沙加零</div>
|
||||
<div>17373135368</div>
|
||||
</div>
|
||||
<div class="right-content">
|
||||
<div>{{ config.cpu }}</div>
|
||||
<div>{{ config.memory }}</div>
|
||||
<div>{{ config.hardDisk }}</div>
|
||||
<div>{{ config.graphicsCard }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="id">
|
||||
<span>
|
||||
{{ id }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
const isShow = ref(true);
|
||||
|
||||
const props = defineProps(['id', 'config']);
|
||||
|
||||
const onDblClick = () => {
|
||||
isShow.value = !isShow.value;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
export const formSchema = {
|
||||
formItems: [
|
||||
{ type: 'input', label: 'CPU', key: 'cpu', required: true },
|
||||
{
|
||||
type: 'select',
|
||||
label: '内存',
|
||||
key: 'memory',
|
||||
options: [
|
||||
{ label: '8G', value: '8G' },
|
||||
{ label: '16G', value: '16G' },
|
||||
{ label: '32G', value: '32G' }
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '硬盘',
|
||||
key: 'hardDisk',
|
||||
options: [
|
||||
{ label: '120G', value: '120G' },
|
||||
{ label: '256G', value: '256G' },
|
||||
{ label: '256G+1tb', value: '256G+1tb' },
|
||||
{ label: '512G', value: '512G' },
|
||||
{ label: '1tb', value: '1tb' }
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
label: '显卡',
|
||||
key: 'graphicsCard',
|
||||
options: [
|
||||
{ label: '1060', value: '1060(3,5,6)' },
|
||||
{ label: '960', value: '960' },
|
||||
{ label: '1660', value: '1660' },
|
||||
{ label: '2060', value: '2060' },
|
||||
{ label: '3060', value: '3060' },
|
||||
{ label: '4060', value: '4060' }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export const initialValues = {
|
||||
cpu: "i5 9400F",
|
||||
memory: "16G",
|
||||
hardDisk: "256G",
|
||||
graphicsCard: "1060(3,5,6)"
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.print-area {
|
||||
/* border: 0.1mm dashed #87CEFA; */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-content: flex-start;
|
||||
margin: 0.25mm;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.show {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.border {
|
||||
border: 0.1mm dashed #87CEFA;
|
||||
}
|
||||
|
||||
.print-area:nth-child(41),
|
||||
.print-area:nth-child(42),
|
||||
.print-area:nth-child(43),
|
||||
.print-area:nth-child(44) {
|
||||
padding-bottom: 4mm;
|
||||
}
|
||||
|
||||
.print-area:nth-child(41) .qrcode,
|
||||
.print-area:nth-child(42) .qrcode,
|
||||
.print-area:nth-child(43) .qrcode,
|
||||
.print-area:nth-child(44) .qrcode {
|
||||
height: calc(100% - 5mm);
|
||||
}
|
||||
|
||||
.item {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.tag {
|
||||
color: red;
|
||||
font-size: 0.8cm;
|
||||
}
|
||||
|
||||
.reason,
|
||||
.time {
|
||||
font-size: 4mm;
|
||||
}
|
||||
|
||||
/*Styling below is used just for positioning the items inside the label. */
|
||||
|
||||
.left-content {
|
||||
width: 24mm;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: inherit;
|
||||
font-size: 3mm;
|
||||
line-height: 3mm;
|
||||
color: #87CEFA;
|
||||
}
|
||||
|
||||
.right-content {
|
||||
display: grid;
|
||||
font-size: 4mm;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.qrcode {
|
||||
height: calc(100% - 6mm);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.id {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 2cm;
|
||||
pointer-events: none;
|
||||
color: #87CEFA60;
|
||||
}
|
||||
|
||||
.id span {
|
||||
/* display: block;
|
||||
margin: 0 auto; */
|
||||
}
|
||||
|
||||
@media print {
|
||||
.id * {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.hide * {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.show {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<div class="input-group">
|
||||
<label>{{ title }}</label>
|
||||
<div class="input-container">
|
||||
<i class="fas fa-user"></i>
|
||||
<input :type="type ?? 'text'" v-model="value" placeholder=" ">
|
||||
<span class="floating-label">请输入{{ title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { unref, watch, ref } from 'vue';
|
||||
const props = defineProps(["title", "type", "modelValue"]);
|
||||
const emits = defineEmits(["update:modelValue"]);
|
||||
|
||||
const value = ref(unref(props.modelValue));
|
||||
|
||||
watch(value, (newValue) => {
|
||||
emits("update:modelValue", newValue);
|
||||
})
|
||||
</script>
|
||||
<style>
|
||||
.input-group {
|
||||
position: relative;
|
||||
margin-bottom: 30px;
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.input-group label {
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.input-group .input-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.input-group i {
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: #7f8c8d;
|
||||
font-size: 18px;
|
||||
transition: color 0.3s;
|
||||
}
|
||||
|
||||
input,
|
||||
textarea {
|
||||
width: 190px;
|
||||
padding: 15px 15px 15px 15px;
|
||||
border: 2px solid #e0e6ed;
|
||||
border-radius: 12px;
|
||||
font-size: 16px;
|
||||
transition: all 0.3s ease;
|
||||
background: #f8fafc;
|
||||
outline: none;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
textarea {
|
||||
min-height: 120px;
|
||||
resize: vertical;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
input:focus,
|
||||
textarea:focus {
|
||||
border-color: #3498db;
|
||||
background: white;
|
||||
box-shadow: 0 5px 15px rgba(52, 152, 219, 0.2);
|
||||
}
|
||||
|
||||
input:focus+i,
|
||||
textarea:focus+i {
|
||||
color: #3498db;
|
||||
}
|
||||
|
||||
.input-group input:focus~.floating-label,
|
||||
.input-group input:not(:placeholder-shown)~.floating-label,
|
||||
.input-group textarea:focus~.floating-label,
|
||||
.input-group textarea:not(:placeholder-shown)~.floating-label {
|
||||
top: -10px;
|
||||
left: 10px;
|
||||
font-size: 12px;
|
||||
background: white;
|
||||
padding: 0 8px;
|
||||
color: #3498db;
|
||||
}
|
||||
|
||||
.floating-label {
|
||||
position: absolute;
|
||||
top: 18px;
|
||||
left: 50px;
|
||||
pointer-events: none;
|
||||
transition: all 0.3s;
|
||||
color: #7f8c8d;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* 特殊样式变体 */
|
||||
.input-group.success input {
|
||||
border-color: #2ecc71;
|
||||
}
|
||||
|
||||
.input-group.success input:focus {
|
||||
box-shadow: 0 5px 15px rgba(46, 204, 113, 0.2);
|
||||
}
|
||||
|
||||
.input-group.success i {
|
||||
color: #2ecc71;
|
||||
}
|
||||
|
||||
.input-group.error input {
|
||||
border-color: #e74c3c;
|
||||
}
|
||||
|
||||
.input-group.error input:focus {
|
||||
box-shadow: 0 5px 15px rgba(231, 76, 60, 0.2);
|
||||
}
|
||||
|
||||
.input-group.error i {
|
||||
color: #e74c3c;
|
||||
}
|
||||
|
||||
.input-group.error .error-message {
|
||||
display: block;
|
||||
color: #e74c3c;
|
||||
font-size: 14px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.input-group.password .toggle-password {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
cursor: pointer;
|
||||
color: #7f8c8d;
|
||||
}
|
||||
|
||||
.input-group.password .toggle-password:hover {
|
||||
color: #3498db;
|
||||
}
|
||||
|
||||
/* 玻璃拟态效果 */
|
||||
.input-group.glass input {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
backdrop-filter: blur(10px);
|
||||
border: 2px solid rgba(255, 255, 255, 0.3);
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.input-group.glass input:focus {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
border-color: rgba(52, 152, 219, 0.6);
|
||||
}
|
||||
|
||||
/* 底部线条样式 */
|
||||
.input-group.line input {
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-bottom: 2px solid #bdc3c7;
|
||||
border-radius: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.input-group.line input:focus {
|
||||
border-bottom-color: #3498db;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.input-group.line i {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.input-group.line .floating-label {
|
||||
left: 30px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,260 @@
|
||||
<template>
|
||||
<div class="toolbar">
|
||||
<div class="toolbar-submit">
|
||||
<label>模板</label>
|
||||
<Select :data="people" v-model="selectedPerson"></Select>
|
||||
<Input type="number" title="数量" v-model="count"></Input>
|
||||
<Input type="number" title="上下边距" v-model="marginHeight"></Input>
|
||||
<Input type="number" title="左右边距" v-model="marginHorizontal"></Input>
|
||||
<button class="btn btn-primary" @click="onAdd">添加</button>
|
||||
<button class="btn btn-primary" @click="onPrint">打印</button>
|
||||
<button class="btn btn-primary" @click="onRest">清空</button>
|
||||
</div>
|
||||
|
||||
<DynamicForm :key="selectedPerson.label" v-show="currentFormSchema" :formConfig="currentFormSchema"
|
||||
:initialData="currentConfig" @submit="updateConfig" />
|
||||
</div>
|
||||
<div class="page" :style="marginVars">
|
||||
<template v-for="(item, index) in data" :key="index">
|
||||
<component :is="getComponent(item)" :id="index" :config="item.config"></component>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref, watch, computed } from "vue";
|
||||
// 导入所有组件(确保路径正确)
|
||||
// import Disk_After_Sales from "./Disk_After_Sales.vue";
|
||||
import Error, { formSchema as formSchema_Error, initialValues as initialValues_Error } from './Error.vue';
|
||||
import I5_10400F_16G_256G_1060, { formSchema as formSchema_I510400F, initialValues as initialValues_I510400F } from "./I5_10400F_16G_256G_1060.vue";
|
||||
import I5_10400F_16G_512G_2060, { formSchema as formSchema_I510400F2060, initialValues as initialValues_I510400F2060 } from './I5_10400F_16G_512G_2060.vue';
|
||||
import I5_9400F_16G_256G_1060, { formSchema as formSchema_I59400F, initialValues as initialValues_I59400F } from "./I5_9400F_16G_256G_1060.vue";
|
||||
import I5_4590_8G_120G, { formSchema as formSchema_I54590, initialValues as initialValues_I54590 } from './I5_4590_8G_120G.vue';
|
||||
import I3_4130_8G_120G, { formSchema as formSchema_I34130, initialValues as initialValues_I34130 } from './I3_4130_8G_120G.vue';
|
||||
import G3260_8G_120G, {
|
||||
formSchema as formSchema_G3260,
|
||||
initialValues as initialValues_G3260
|
||||
} from './G3260_8G_120G.vue';
|
||||
import All_in_one_22_4G_120G, { formSchema as formSchema_22AllInOne, initialValues as initialValues_22AllInOne } from "./22寸一体机_4G_120G.vue";
|
||||
import All_in_one_24_8G_256G, { formSchema as formSchema_24AllInOne, initialValues as initialValues_24AllInOne } from "./24寸一体机_I5_3代_8G_256G.vue";
|
||||
|
||||
import DynamicForm from './DynamicForm.vue';
|
||||
import Input from './Input/Index.vue';
|
||||
import Select from './Select/index.vue';
|
||||
|
||||
// 修复1: 确保所有配置都有表单数据
|
||||
const people = reactive([
|
||||
{
|
||||
label: 'I5_10400F_16G_256G_1060',
|
||||
formSchema: formSchema_I510400F,
|
||||
formData: initialValues_I510400F
|
||||
},
|
||||
{
|
||||
label: 'I5_10400F_16G_256G_2060',
|
||||
formSchema: formSchema_I510400F2060,
|
||||
formData: initialValues_I510400F2060
|
||||
},
|
||||
{
|
||||
label: 'I5_9400F_16G_256G_1060',
|
||||
formSchema: formSchema_I59400F,
|
||||
formData: initialValues_I59400F
|
||||
},
|
||||
{
|
||||
label: 'I54590_8G_120G',
|
||||
formSchema: formSchema_I54590,
|
||||
formData: initialValues_I54590
|
||||
},
|
||||
{
|
||||
label: 'I34130_8G_120G',
|
||||
formSchema: formSchema_I34130,
|
||||
formData: initialValues_I34130
|
||||
},
|
||||
{
|
||||
label: 'G3260_8G_120G',
|
||||
formSchema: formSchema_G3260,
|
||||
formData: initialValues_G3260
|
||||
},
|
||||
{
|
||||
label: '24寸一体机_I5_3代_8G_256G',
|
||||
formSchema: formSchema_24AllInOne,
|
||||
formData: initialValues_24AllInOne
|
||||
},
|
||||
{
|
||||
label: '22寸一体机_4G_120G',
|
||||
formSchema: formSchema_22AllInOne,
|
||||
formData: initialValues_22AllInOne
|
||||
},
|
||||
{
|
||||
label: 'Error',
|
||||
formSchema: formSchema_Error,
|
||||
formData: initialValues_Error
|
||||
},
|
||||
]);
|
||||
|
||||
// 修复2: 初始化选中项为G3260配置
|
||||
const selectedPerson = ref(people[0]);
|
||||
const data = ref([]);
|
||||
// 打印数量
|
||||
const count = ref(1);
|
||||
// 上下边距
|
||||
const marginHeight = ref(0.89);
|
||||
// 左右边距
|
||||
const marginHorizontal = ref(0.8);
|
||||
const currentConfig = ref({ ...initialValues_G3260 });
|
||||
const currentFormSchema = ref(formSchema_G3260);
|
||||
// 打印样式表引用
|
||||
let printStyle = null;
|
||||
|
||||
// 计算样式变量
|
||||
const marginVars = computed(() => ({
|
||||
'--margin-height': `${marginHeight.value}cm`,
|
||||
'--margin-horizontal': `${marginHorizontal.value}cm`
|
||||
}));
|
||||
|
||||
// 修复3: 正确的watch处理
|
||||
watch(selectedPerson, (newVal) => {
|
||||
currentConfig.value = { ...newVal.formData };
|
||||
currentFormSchema.value = newVal.formSchema;
|
||||
}, { immediate: true });
|
||||
|
||||
const getComponent = (item) => {
|
||||
switch (item.name) {
|
||||
case 'I5_10400F_16G_256G_1060': return I5_10400F_16G_256G_1060;
|
||||
case 'I5_10400F_16G_512G_2060': return I5_10400F_16G_512G_2060;
|
||||
case 'I5_9400F_16G_256G_1060': return I5_9400F_16G_256G_1060;
|
||||
case 'I5_4590_8G_120G': return I5_4590_8G_120G;
|
||||
case 'I3_4130_8G_120G': return I3_4130_8G_120G;
|
||||
case 'G3260_8G_120G': return G3260_8G_120G;
|
||||
case '24寸一体机_I5_3代_8G_256G': return All_in_one_24_8G_256G;
|
||||
case '22寸一体机_4G_120G': return All_in_one_22_4G_120G;
|
||||
case 'Error': return Error;
|
||||
default: return Error;
|
||||
}
|
||||
}
|
||||
|
||||
const onAdd = () => {
|
||||
const maxItems = 44;
|
||||
const availableSlots = maxItems - data.value.length;
|
||||
const addCount = Math.min(count.value, availableSlots);
|
||||
|
||||
if (addCount <= 0) return;
|
||||
|
||||
const newItems = Array.from({ length: addCount }, () => ({
|
||||
name: selectedPerson.value.label,
|
||||
config: { ...currentConfig.value }
|
||||
}));
|
||||
|
||||
data.value.push(...newItems);
|
||||
}
|
||||
// 重置打印网格
|
||||
const onRest = () => {
|
||||
data.value = [];
|
||||
}
|
||||
|
||||
const updateConfig = (newConfig) => {
|
||||
currentConfig.value = newConfig;
|
||||
}
|
||||
|
||||
const onPrint = () => {
|
||||
applyPrintStyles();
|
||||
if (window?.electronAPI?.silentPrint) {
|
||||
window.electronAPI.silentPrint();
|
||||
} else {
|
||||
window.print();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 应用打印样式
|
||||
const applyPrintStyles = () => {
|
||||
// 移除旧的打印样式
|
||||
if (printStyle) {
|
||||
document.head.removeChild(printStyle);
|
||||
}
|
||||
|
||||
// 创建新的打印样式
|
||||
printStyle = document.createElement('style');
|
||||
printStyle.setAttribute('media', 'print');
|
||||
printStyle.textContent = `
|
||||
@page {
|
||||
margin: ${marginHeight.value}cm ${marginHorizontal.value}cm 0;
|
||||
}
|
||||
|
||||
@media print {
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
document.head.appendChild(printStyle);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* 原有样式保持不变 */
|
||||
body {
|
||||
max-width: none !important;
|
||||
margin: 0 !important;
|
||||
padding: 0rem !important;
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 194mm;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 48.5mm);
|
||||
grid-template-rows: repeat(11, 25.4mm);
|
||||
gap: 0;
|
||||
|
||||
/* margin: var(--margin-height) var(--margin-horizontal) 0; */
|
||||
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.toolbar .toolbar-submit {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.toolbar-submit button.btn:nth-of-type(n+2) {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
@media print {
|
||||
|
||||
html,
|
||||
body {
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
body * {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.page,
|
||||
.page * {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.page {
|
||||
width: 194mm;
|
||||
height: auto;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@page {
|
||||
/* margin: var(--margin-height) var(--margin-horizontal) 0; */
|
||||
margin: 0.89cm 0.80cm 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<div class="">
|
||||
<Listbox v-model="selectedPerson">
|
||||
<div class="relative mt-1">
|
||||
<ListboxButton
|
||||
class="listbox-button relative w-120 cursor-default rounded-lg bg-white py-2 pl-3 pr-10 text-left shadow-md focus:outline-none focus-visible:border-indigo-500 focus-visible:ring-2 focus-visible:ring-white/75 focus-visible:ring-offset-2 focus-visible:ring-offset-orange-300 sm:text-sm">
|
||||
<span class="block truncate">{{ selectedPerson?.label }}</span>
|
||||
<span class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
|
||||
<!-- <ChevronUpDownIcon class="h-5 w-5 text-gray-400" aria-hidden="true" /> -->
|
||||
</span>
|
||||
</ListboxButton>
|
||||
|
||||
<transition leave-active-class="transition duration-100 ease-in" leave-from-class="opacity-100"
|
||||
leave-to-class="opacity-0">
|
||||
<ListboxOptions
|
||||
class="listbox-options absolute mt-1 max-h-60 w-120 overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black/5 focus:outline-none sm:text-sm">
|
||||
<ListboxOption v-slot="{ active, selected }" v-for="person in data" :key="person.label"
|
||||
:value="person" as="template">
|
||||
<li :class="[
|
||||
active ? 'bg-amber-100 text-amber-900' : 'text-gray-900',
|
||||
'relative cursor-default select-none py-2 pl-10 pr-4',
|
||||
]">
|
||||
<span :class="[
|
||||
selected ? 'font-medium' : 'font-normal',
|
||||
'block truncate',
|
||||
]">{{ person.label }}</span>
|
||||
<span v-if="selected"
|
||||
class="absolute inset-y-0 left-0 flex items-center pl-3 text-amber-600">
|
||||
<!-- <CheckIcon class="h-5 w-5" aria-hidden="true" /> -->
|
||||
</span>
|
||||
</li>
|
||||
</ListboxOption>
|
||||
</ListboxOptions>
|
||||
</transition>
|
||||
</div>
|
||||
</Listbox>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, watch } from 'vue'
|
||||
import {
|
||||
Listbox,
|
||||
ListboxLabel,
|
||||
ListboxButton,
|
||||
ListboxOptions,
|
||||
ListboxOption,
|
||||
} from '@headlessui/vue'
|
||||
// import { CheckIcon, ChevronUpDownIcon } from '@heroicons/vue/20/solid'
|
||||
|
||||
const props = defineProps(["data"]);
|
||||
const selectedPerson = ref(props.data?.length > 0 ? props.data[0] : null);
|
||||
|
||||
const emits = defineEmits(["update:modelValue"]);
|
||||
|
||||
watch([selectedPerson], ([newSelected]) => {
|
||||
emits("update:modelValue", newSelected);
|
||||
})
|
||||
</script>
|
||||
<style>
|
||||
.listbox-button {
|
||||
background-color: #f3f4f6;
|
||||
border: 1px solid #d1d5db;
|
||||
border-radius: 4px;
|
||||
padding: 8px 12px;
|
||||
width: 220px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.listbox-options {
|
||||
background-color: white;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
padding: 4px 0;
|
||||
margin-top: 4px;
|
||||
min-width:220px;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.listbox-options li {
|
||||
padding: 8px 12px;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
/* 隐藏默认列表符号 */
|
||||
}
|
||||
|
||||
/* 悬停状态 */
|
||||
.listbox-options li:hover {
|
||||
background-color: #f9fafb;
|
||||
}
|
||||
|
||||
/* 选中状态 */
|
||||
.listbox-options li[aria-selected="true"],
|
||||
.active-option {
|
||||
background: linear-gradient(to bottom, #e6f5ff, #b3e0ff);
|
||||
/* 渐变背景 */
|
||||
color: #0066cc;
|
||||
}
|
||||
|
||||
/* 禁用状态 */
|
||||
.listbox-options li[aria-disabled="true"] {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.listbox-options {
|
||||
transition: opacity 0.3s ease, transform 0.3s ease;
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
|
||||
.listbox-options[data-headlessui-state="open"] {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,5 @@
|
||||
import { createApp } from 'vue'
|
||||
import './style.css'
|
||||
import App from './App.vue'
|
||||
|
||||
createApp(App).mount('#app')
|
||||
@@ -0,0 +1,52 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css");
|
||||
|
||||
|
||||
/* 基础按钮样式 */
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 6px 12px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
/* 主按钮样式 */
|
||||
.btn-primary {
|
||||
background: #3498db;
|
||||
color: white;
|
||||
box-shadow: 0 4px 10px rgba(52, 152, 219, 0.3);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: #2980b9;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 15px rgba(52, 152, 219, 0.4);
|
||||
}
|
||||
|
||||
.btn-primary:active {
|
||||
transform: translateY(1px);
|
||||
box-shadow: 0 2px 5px rgba(52, 152, 219, 0.3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 图标按钮样式 */
|
||||
.btn-icon {
|
||||
padding: 12px 24px 12px 50px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.btn-icon i {
|
||||
position: absolute;
|
||||
left: 20px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
font-size: 18px;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: [
|
||||
"'./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'", // 根据项目类型调整扩展名
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
})
|
||||
Reference in New Issue
Block a user