This commit is contained in:
helloDy 2024-01-29 18:02:09 +08:00
parent c5f4949678
commit 53caddfa1e
12 changed files with 567 additions and 50 deletions

View File

@ -1,7 +1,7 @@
/*
* @Author: Do not edit
* @Date: 2023-11-20 11:05:00
* @LastEditTime: 2024-01-10 11:20:45
* @LastEditTime: 2024-01-29 16:51:45
* @LastEditors: DY
* @Description: 质量和报废
*/
@ -69,3 +69,21 @@ export function createInspection (data) {
data: data
})
}
// 获得所有报废日志列表
export function scrapLogList (data) {
return request({
url: '/base/quality-scrap-log/page',
method: 'get',
params: data
})
}
// 获得安灯权限
export function authList (data) {
return request({
url: '/base/quality-inspection-box-btn-auth/get',
method: 'get',
params: data
})
}

BIN
src/assets/back.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

BIN
src/assets/record.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -1,7 +1,7 @@
/*
* @Author: Do not edit
* @Date: 2023-12-27 16:41:40
* @LastEditTime: 2024-01-09 13:58:18
* @LastEditTime: 2024-01-29 10:04:05
* @LastEditors: DY
* @Description:
*/
@ -43,6 +43,11 @@ const routes = [
path: '/scrap',
name: 'scrap',
component: () => import('../views/Scrap.vue')
},
{
path: '/list',
name: 'scrapList',
component: () => import('../views/ScrapList.vue')
}
]

View File

@ -1,3 +1,10 @@
/*
* @Author: Do not edit
* @Date: 2024-01-09 09:55:17
* @LastEditTime: 2024-01-29 16:56:22
* @LastEditors: DY
* @Description: cookie
*/
// ========== 租户相关 ==========
@ -21,6 +28,10 @@ export function getAccessToken () {
return localStorage.getItem(AccessTokenKey)
}
export function getUserId () {
return localStorage.getItem('UserId')
}
export function getRefreshToken () {
return localStorage.getItem(RefreshTokenKey)
}
@ -28,6 +39,7 @@ export function getRefreshToken () {
export function setToken (token) {
localStorage.setItem(AccessTokenKey, token.accessToken)
localStorage.setItem(RefreshTokenKey, token.refreshToken)
localStorage.setItem('UserId', token.userId)
}
export function removeToken () {

View File

@ -1,7 +1,7 @@
/*
* @Author: Do not edit
* @Date: 2023-11-20 11:02:29
* @LastEditTime: 2024-01-11 10:34:34
* @LastEditTime: 2024-01-29 16:48:54
* @LastEditors: DY
* @Description:
*/
@ -13,6 +13,7 @@ import { MessageBox } from 'element-ui'
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
const service = axios.create({
// baseURL: 'http://192.168.1.20:48080',
// baseURL: 'http://192.168.1.78:48082/admin-api',
baseURL: 'http://192.168.0.33:48082/admin-api',
timeout: 30000,

51
src/utils/time.js Normal file
View File

@ -0,0 +1,51 @@
/*
* @Author: Do not edit
* @Date: 2024-01-29 15:33:10
* @LastEditTime: 2024-01-29 15:39:34
* @LastEditors: DY
* @Description:
*/
// 日期格式化(通用)
export function parseTime (time, pattern) {
if (arguments.length === 0 || !time) {
return null
}
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
time = parseInt(time)
} else if (typeof time === 'string') {
// const reg1 = new RegExp(/-/gm)
// const reg2 = new RegExp(/\.\d{3}/gm)
// time = time.replace(reg1, '/').replace('T', ' ').replace(reg2, '')
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const timeStr = format.replace(/{([ymdhisa])+}/g, (result, key) => {
let value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') {
return ['日', '一', '二', '三', '四', '五', '六'][value]
}
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
return timeStr
}

View File

@ -1,12 +1,18 @@
<!--
* @Author: Do not edit
* @Date: 2023-12-27 16:41:40
* @LastEditTime: 2024-01-09 14:00:12
* @LastEditTime: 2024-01-29 16:35:29
* @LastEditors: DY
* @Description: 首页
-->
<template>
<div class="home">
<van-row style="width: 100%" type="flex" justify="space-between">
<van-col span="20"></van-col>
<van-col span="4" style="text-align: right">
<img class="homeIcon" @click="goback" src="./../assets/back.png" alt="">
</van-col>
</van-row>
<div class="centerDiv">
<div class="img1" @click="toQuality">
<p class="title">质量收集器</p>
@ -27,6 +33,9 @@ export default {
}
},
methods: {
goback () {
window.electronAPI.closeWindow()
},
toQuality () {
this.$router.push({
path: 'quality'
@ -34,7 +43,7 @@ export default {
},
toScrap () {
this.$router.push({
path: 'scrap'
path: 'list'
})
}
}
@ -70,13 +79,15 @@ export default {
justify-content: center;
flex-direction: row;
align-items: center;
height: 100vh;
height: 80vh;
gap: 18px;
}
.home {
background-image: url('./../assets/home_bg.png');
height: 100vh;
width: 100vw;
padding-top: 10px;
background-size: cover;
box-sizing: border-box;
}
</style>

View File

@ -1,12 +1,18 @@
<!--
* @Author: Do not edit
* @Date: 2023-12-28 11:21:53
* @LastEditTime: 2024-01-10 16:58:49
* @LastEditTime: 2024-01-29 17:57:32
* @LastEditors: DY
* @Description: 登陆
-->
<template>
<div class="login">
<van-row style="width: 100%; height: 40px; padding-top: 5px" type="flex" justify="space-between">
<van-col span="20"></van-col>
<van-col span="4" style="text-align: right">
<img class="homeIcon" @click="goback" src="./../assets/back.png" alt="">
</van-col>
</van-row>
<van-row type="flex" justify="space-around">
<van-col span="12">
<div class="left">
@ -52,6 +58,7 @@
name="username"
placeholder="用户名 / 手机号"
style="margin-bottom: 16px"
@focus="focusInput($event)"
:rules="[{ required: true, message: '请填写用户名' }]"
/>
<van-field
@ -59,6 +66,7 @@
type="password"
name="password"
placeholder="密码"
@focus="focusInput1($event)"
:rules="[{ required: true, message: '请填写密码' }]"
/>
<div style="margin-top: 36px; border-radius: 3px">
@ -72,20 +80,69 @@
<div class="mountain">
<p style="margin-top: 80px; color: #3196E7">{{'版权所有:中建材智能自动化有限公司版本' + '\u3000' +'版本1.0'}}</p>
</div>
<SimpleKeyboard
style="position: fixed; bottom: 0"
v-show="simpleShow"
v-model="inputValue"
ref="keyboardClass"
keyboardClass="keyboardClass"
@on-change="onChange"
@on-key-press="onKeyPress"
@close="simpleShow = false"
:input="inputValue"
:maxLength="30"
/>
<SimpleKeyboard
style="position: fixed; bottom: 0"
v-show="simpleShow1"
v-model="inputValue1"
ref="keyboardClass1"
keyboardClass="keyboardClass1"
@on-change="onChange1"
@on-key-press="onKeyPress1"
@close="simpleShow1 = false"
:input="inputValue1"
:maxLength="30"
/>
</div>
</template>
<script>
import { loginUser, getTenantIdByName } from '@/api/login'
import { setTenantId, setToken } from '@/utils/auth'
import SimpleKeyboard from './components/simpleKeyboard.vue'
export default {
name: 'Login',
components: { SimpleKeyboard },
data () {
return {
username: 'admin',
password: 'admin123',
tenantName: '技术中心'
tenantName: '技术中心',
simpleShow: false,
simpleShow1: false,
input: null,
inputEle: null,
inputEle1: null
}
},
computed: {
inputValue: {
get () {
return this.value
},
set (value) {
this.username = value
}
},
inputValue1: {
get () {
return this.value
},
set (value) {
this.password = value
}
}
},
created () {
@ -99,6 +156,37 @@ export default {
})
},
methods: {
goback () {
window.electronAPI.closeWindow()
},
focusInput1 (e) {
this.inputEle1 = e.srcElement
this.simpleShow1 = true
this.simpleShow = false
},
focusInput (e) {
this.inputEle = e.srcElement
this.simpleShow1 = false
this.simpleShow = true
},
onChange1 (input) {
this.inputValue1 = input
this.$set(this.password, input)
// /element-ui2.15.2
this.inputEle1.focus()
},
onChange (input) {
this.inputValue = input
this.$set(this.username, input)
// /element-ui2.15.2
this.inputEle.focus()
},
onKeyPress1 (button) {
console.log('onKeyPress', button)
},
onKeyPress (button) {
console.log('onKeyPress', button)
},
onSubmit (values) {
loginUser(values).then(res => {
console.log(res.data)
@ -140,7 +228,7 @@ export default {
background-image: url('./../assets/transparent.png');
height: 534px;
width: 458px;
margin-top: 121px;
margin-top: 100px;
margin-left: 40px;
}
.modalImg {
@ -151,7 +239,7 @@ export default {
.title {
/* width: 297px; */
/* height: 59px; */
padding-top: 122px;
padding-top: 100px;
padding-left: 115px;
text-align: left;
font-size: 66px;

View File

@ -1,7 +1,7 @@
<!--
* @Author: Do not edit
* @Date: 2024-01-09 13:48:42
* @LastEditTime: 2024-01-11 09:26:12
* @LastEditTime: 2024-01-29 17:17:14
* @LastEditors: DY
* @Description:
-->
@ -18,7 +18,7 @@
<van-row gutter="20" style="margin-top: -20px;">
<van-col span="12">
<van-dropdown-menu >
<van-dropdown-item v-model="listQuery.productionLineId" :options="lineArray" @change="getSection()" />
<van-dropdown-item v-model="listQuery.productionLineId" :options="lineArray" @change="getSection" />
</van-dropdown-menu>
</van-col>
<van-col span="12">
@ -58,7 +58,8 @@
</template>
<script>
import { lineList, workshopSectionListByLine, qualityManage, createInspection } from '@/api/quality'
import { qualityManage, createInspection, authList } from '@/api/quality'
import { getUserId } from '@/utils/auth'
export default {
name: 'Quality',
@ -111,28 +112,48 @@ export default {
})
},
getLine () {
lineList().then(res => {
if (res && res.data.data.length > 0) {
this.lineArray = res.data.data.map(item => {
return {
text: item.name,
value: item.id
}
authList({ userId: getUserId() }).then(res => {
console.log('res', res.data.data)
if (res && res.data.data.datas.length > 0) {
this.lineArray = res.data.data.datas.map(item => {
item.text = item.name
item.value = item.id
return item
})
} else {
this.lineArray = []
}
// if (res && res.data.data.length > 0) {
// this.lineArray = res.data.data.map(item => {
// return {
// text: item.name,
// value: item.id
// }
// })
// } else {
// this.lineArray = []
// }
})
},
getSection () {
workshopSectionListByLine({ id: this.listQuery.productionLineId }).then(res => {
this.sectionArray = res.data.data.map(item => {
return {
text: item.name,
value: item.id
}
})
getSection (value) {
const temp = this.lineArray.filter(item => {
return item.id === value
})
this.sectionArray = temp[0].children.map(it => {
return {
text: it.name,
value: it.id
}
})
console.log('nihjc', temp)
// workshopSectionListByLine({ id: this.listQuery.productionLineId }).then(res => {
// this.sectionArray = res.data.data.map(item => {
// return {
// text: item.name,
// value: item.id
// }
// })
// })
}
}
}

View File

@ -1,7 +1,7 @@
<!--
* @Author: Do not edit
* @Date: 2024-01-09 13:49:03
* @LastEditTime: 2024-01-17 17:07:21
* @LastEditTime: 2024-01-29 17:57:45
* @LastEditors: DY
* @Description:
-->
@ -51,7 +51,7 @@
<br>
<div class="resonDiv">
<el-checkbox-group v-model="ruleForm.detName" style="width: 100%; display: block; text-align: left">
<el-checkbox v-for="(item, index) in scrapList" :key="index" :label="item.content" :name="item.id"></el-checkbox>
<el-checkbox v-for="(item, index) in scrapList" :key="index" :label="item.id" :name="item.id">{{ item.content }}</el-checkbox>
</el-checkbox-group>
</div>
</el-form-item>
@ -59,12 +59,23 @@
<el-col :span="12">
<div class="whiteForm">
<el-form-item label="产线" prop="lineId">
<el-select v-model="ruleForm.lineId" filterable clearable placeholder="请选择产线" style="width: 100%; display: block">
<el-select v-model="ruleForm.lineId" filterable clearable placeholder="请选择产线" @focus="focusInput1($event)" style="width: 100%; display: block" @change="getSection()">
<el-option v-for="(item, index) in lineArray" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</div>
</el-col>
<el-col :span="12">
<div class="whiteForm">
<el-form-item label="工段" prop="sectionId">
<el-select v-model="ruleForm.sectionId" filterable clearable placeholder="请选择产线" @focus="focusInput2($event)" style="width: 100%; display: block">
<el-option v-for="(item, index) in sectionArray" :key="index" :label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</div>
</el-col>
</el-row>
<el-row :gutter="10">
<el-col :span="12">
<div class="whiteForm">
<el-form-item label="时间" prop="logTime">
@ -72,11 +83,19 @@
</el-form-item>
</div>
</el-col>
<el-col :span="12">
<div class="whiteForm">
<el-form-item label="备注" prop="remark">
<el-input v-model="ruleForm.remark" @focus="focusInput3($event)"></el-input>
<!-- <el-date-picker type="datetime" placeholder="选择日期" value-format="yyyy-MM-dd HH:mm:ss" v-model="ruleForm.logTime" style="width: 100%;"></el-date-picker> -->
</el-form-item>
</div>
</el-col>
</el-row>
<el-row>
<el-form-item>
<!-- <el-button @click="resetForm('ruleForm')">取消</el-button> -->
<el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
<el-button class="subButton" type="primary" @click="submitForm('ruleForm')">提交</el-button>
</el-form-item>
</el-row>
</el-form>
@ -89,13 +108,46 @@
@on-key-press="onKeyPress"
@close="simpleShow = false"
:input="inputValue"
:maxLength="10"
:maxLength="30"
/>
<SimpleKeyboard
v-show="simpleShow1"
v-model="inputValue1"
ref="keyboardClass1"
keyboardClass="keyboardClass1"
@on-change="onChange1"
@on-key-press="onKeyPress1"
@close="simpleShow1 = false"
:input="inputValue1"
:maxLength="30"
/>
<SimpleKeyboard
v-show="simpleShow2"
v-model="inputValue2"
ref="keyboardClass2"
keyboardClass="keyboardClass2"
@on-change="onChange2"
@on-key-press="onKeyPress2"
@close="simpleShow2 = false"
:input="inputValue2"
:maxLength="30"
/>
<SimpleKeyboard
v-show="simpleShow3"
v-model="inputValue3"
ref="keyboardClass3"
keyboardClass="keyboardClass3"
@on-change="onChange3"
@on-key-press="onKeyPress3"
@close="simpleShow3 = false"
:input="inputValue3"
:maxLength="30"
/>
</div>
</template>
<script>
import { workOrderList, scrapDetList, lineList, createScrap } from '@/api/quality'
import { workOrderList, scrapDetList, lineList, createScrap, workshopSectionListByLine } from '@/api/quality'
import SimpleKeyboard from './components/simpleKeyboard.vue'
export default {
@ -108,16 +160,25 @@ export default {
detId: '',
detName: [],
lineId: undefined,
sectionId: undefined,
remark: undefined,
logTime: new Date()
},
show: false,
simpleShow: false,
simpleShow1: false,
simpleShow2: false,
simpleShow3: false,
input: null,
inputEle: null,
field: '',
inputEle1: null,
inputEle2: null,
inputEle3: null,
// field: '',
workOrderList: [],
lineArray: [],
scrapList: [],
sectionArray: [],
rules: {
workOrderId: [
{ required: true, message: '请选择工单', trigger: 'change' }
@ -140,6 +201,30 @@ export default {
this.ruleForm.workOrderId = value
// this.$emit('inputChange', value, this.field)
}
},
inputValue1: {
get () {
return this.value
},
set (value) {
this.ruleForm.lineId = value
}
},
inputValue2: {
get () {
return this.value
},
set (value) {
this.ruleForm.sectionId = value
}
},
inputValue3: {
get () {
return this.value
},
set (value) {
this.ruleForm.remark = value
}
}
},
mounted () {
@ -150,20 +235,16 @@ export default {
detId: '',
detName: [],
lineId: undefined,
sectionId: undefined,
remark: undefined,
logTime: new Date()
}
},
methods: {
// formItemChange (val, formItemField) {
// this.form[formItemField] = val
// this.validataForm(formItemField)
// },
setWorkOrder (value) {
console.log('1111', value)
},
inputChange () {
// this.field =
// this.$emit('input-change')
getSection () {
workshopSectionListByLine({ id: this.ruleForm.lineId }).then(res => {
this.sectionArray = res.data.data
})
},
inputFun () {
this.$emit('input')
@ -179,14 +260,65 @@ export default {
// const currentKeyborad = this.$refs[this.keyboardClass]
// currentKeyborad.$el.style.visibility = 'visible'
this.simpleShow = true
this.simpleShow1 = false
this.simpleShow2 = false
this.simpleShow3 = false
// this.$emit('focus')
},
focusInput1 (e) {
this.inputEle1 = e.srcElement
this.simpleShow1 = true
this.simpleShow = false
this.simpleShow2 = false
this.simpleShow3 = false
},
focusInput2 (e) {
this.inputEle2 = e.srcElement
this.simpleShow2 = true
this.simpleShow1 = false
this.simpleShow = false
this.simpleShow3 = false
},
focusInput3 (e) {
this.inputEle3 = e.srcElement
this.simpleShow3 = true
this.simpleShow2 = false
this.simpleShow1 = false
this.simpleShow = false
},
onChange1 (input) {
this.inputValue1 = input
this.$set(this.ruleForm, 'lineId', input)
// /element-ui2.15.2
this.inputEle1.focus()
},
onChange2 (input) {
this.inputValue2 = input
this.$set(this.ruleForm, 'sectionId', input)
// /element-ui2.15.2
this.inputEle2.focus()
},
onChange3 (input) {
this.inputValue3 = input
// this.$set(this.ruleForm, 'remark', input)
// /element-ui2.15.2
this.inputEle3.focus()
},
onChange (input) {
this.inputValue = input
this.$set(this.ruleForm, 'workOrderId', input)
console.log('输出', input)
// /element-ui2.15.2
this.inputEle.focus()
// this.inputEle.focus()
},
onKeyPress3 (button) {
console.log('onKeyPress', button)
},
onKeyPress2 (button) {
console.log('onKeyPress', button)
},
onKeyPress1 (button) {
console.log('onKeyPress', button)
},
onKeyPress (button) {
console.log('onKeyPress', button)
@ -199,13 +331,16 @@ export default {
// Toast('');
},
goback () {
this.$router.go(-1)
// this.$router.go(-1)
this.$router.push({
path: 'home'
})
},
async getDict () {
const workRes = await workOrderList()
this.workOrderList = workRes.data.data
this.workOrderList = workRes?.data?.data
await lineList().then(res => {
this.lineArray = res.data.data.map(item => {
this.lineArray = res?.data?.data.map(item => {
return {
name: item.name,
id: item.id
@ -213,7 +348,11 @@ export default {
})
})
const scrapRes = await scrapDetList()
this.scrapList = scrapRes.data.data
this.scrapList = scrapRes?.data?.data
// this.scrapList.push({
// content: '',
// id: '10086'
// })
},
submitForm (formName) {
this.$refs[formName].validate((valid) => {
@ -245,6 +384,13 @@ export default {
</script>
<style>
.subButton {
background-color: #456DFF;
width: 168px;
height: 56px;
box-shadow: 0px 16px 16px 0px rgba(25,70,170,0.31);
border-radius: 31px;
}
.el-checkbox {
background: #EDF0FD;
box-shadow: 0px 6px 8px 0px #D2D9E8, inset 0px 6px 6px 0px #FFFFFF;
@ -261,6 +407,17 @@ export default {
margin-bottom: 8px !important;
padding-bottom: 15px;
}
.el-checkbox__label {
padding-right: 10px !important;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 160px;
line-height: 1;
}
.demo-ruleForm .reson .el-form-item__content {
margin-left: 20px !important;
}
.resonDiv {
display: flex;
width: 100%;

153
src/views/ScrapList.vue Normal file
View File

@ -0,0 +1,153 @@
<!--
* @Author: Do not edit
* @Date: 2023-12-29 10:01:55
* @LastEditTime: 2024-01-29 17:31:48
* @LastEditors: DY
* @Description: 报废列表
-->
<template>
<div class="list">
<van-row type="flex" justify="space-between">
<van-col span="5" style="text-align: left">
<h2>报废管理</h2>
</van-col>
<!-- <van-col span="4">
<img class="homeIcon" @click="goback" src="./../assets/record.png" alt="">
</van-col> -->
<van-col span="8" style="text-align: right">
<img class="homeIcon" @click="toScrap" src="./../assets/record.png" alt="">
<img class="homeIcon" @click="goback" src="./../assets/home.png" alt="">
</van-col>
</van-row>
<el-table
:data="tableData"
border
:header-cell-style="{ background: 'rgba(210, 220, 242, 1)', color: '#000', height: '33px' }"
show-header
style="width: 100%">
<el-table-column
type="index" label="序号" width="60" />
<el-table-column v-for="(item, index) in tableProps" :key="index" :prop="item.prop" :label="item.label" />
</el-table>
<el-pagination
class="pagination"
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="listQuery.pageNo"
:page-sizes="[10, 20, 30]"
:page-size="listQuery.pageSize"
layout="prev, pager, next"
:total="total">
</el-pagination>
</div>
</template>
<script>
import { scrapLogList } from '@/api/quality'
import { parseTime } from '@/utils/time'
const tableProps = [
{
prop: 'scrapTime',
label: '报废时间'
},
{
prop: 'createTime',
label: '产线名称'
},
{
prop: 'createTime',
label: '工段名称'
},
{
prop: 'workOrderName',
label: '工单名称'
},
{
prop: 'num',
label: '报废数量'
},
{
prop: 'detContent',
label: '报废原因'
},
{
prop: 'sources',
label: '来源'
}
]
export default {
name: 'ScrapList',
data () {
return {
listQuery: {
pageSize: 10,
pageNo: 1
},
tableProps,
tableData: [],
total: 0
}
},
mounted () {
this.getList()
},
methods: {
handleSizeChange (val) {
console.log(`每页 ${val}`)
this.listQuery.pageSize = val
this.getList()
},
handleCurrentChange (val) {
this.listQuery.pageNo = val
this.getList()
console.log(`当前页: ${val}`)
},
getList () {
scrapLogList(this.listQuery).then(res => {
if (res.data.code === 0) {
this.tableData = res.data.data.list.map(item => {
item.sources = item.source === 1 ? '平板端' : '网页端'
item.scrapTime = parseTime(item.logTime)
return item
})
this.total = res.data.data.total
}
})
},
goback () {
this.$router.push({
path: 'home'
})
},
toScrap () {
this.$router.push({
path: 'scrap'
})
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
.el-table__row--even {
background-color: #f9fafc; /* 偶数行背景颜色 */
}
.el-table__row--odd {
background-color: #a76c6c; /* 奇数行背景颜色 */
}
.pagination {
margin-top: 10px;
float: right;
}
.list {
background-image: url('./../assets/quality-bg.png');
height: 100vh;
width: 100vw;
padding: 20px 24px;
box-sizing: border-box;
}
</style>