디자인 금액 , 추가

This commit is contained in:
2025-05-28 19:41:40 +09:00
parent d8c9711568
commit a50ee08355
16 changed files with 108 additions and 190 deletions

View File

@@ -115,7 +115,6 @@
"unplugin-vue-router": "0.8.6", "unplugin-vue-router": "0.8.6",
"uuid": "^11.1.0", "uuid": "^11.1.0",
"v-calendar": "3.0.3", "v-calendar": "3.0.3",
"vee-validate": "4.12.6",
"vivus": "0.4.6", "vivus": "0.4.6",
"vue": "3.4.26", "vue": "3.4.26",
"vue-accessible-color-picker": "5.0.1", "vue-accessible-color-picker": "5.0.1",

View File

@@ -644,4 +644,12 @@ a {
background-color:white !important; background-color:white !important;
} }
} }
.toolbar {
a {
&:hover {
background-color:transparent !important;
}
}
}
</style> </style>

View File

@@ -73,6 +73,7 @@ const onEstimateSave = () => {
} }
const setData = (data: iEstimate[]) => { const setData = (data: iEstimate[]) => {
console.log(data)
estimates.value = data estimates.value = data
} }
const setAttData = (data: iPbAtt[]) => { const setAttData = (data: iPbAtt[]) => {
@@ -154,5 +155,11 @@ watch(params, (newValue) => {
</template> </template>
<style lang="scss"> <style lang="scss">
.text-right {
text-align:right !important;
}
.text-center {
text-align:center !important;
}
</style> </style>

View File

@@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { iPrcs, iDtlSpec, iEstimate, UserData, iPbAtt } from '/@src/utils/types' import type { iPrcs, iDtlSpec, iEstimate, UserData, iPbAtt } from '/@src/utils/types'
import regex from "/@src/utils/regex.ts";
const props = defineProps<{ const props = defineProps<{
prcs: iPrcs prcs: iPrcs
@@ -67,7 +68,7 @@ const onFilDelete = (fileOrd: number) => {
const totPrc = computed(() => { const totPrc = computed(() => {
return estimates.value.map((item: iEstimate) => { return estimates.value.map((item: iEstimate) => {
item.amt = item.unitPrc * item.qty item.amt = item.unitPrc * item.qty
return item.amt return item.amt.toString().replace(regex.currency, ',')
}) })
}) })
@@ -157,9 +158,9 @@ watch(pbAtts.value, (newValue) => {
<VField> <VField>
<VLabel>첨부파일</VLabel> <VLabel>첨부파일</VLabel>
<div <div
v-for="f in props.prcs.prcsAtts" v-for="f in props.prcs.prcsAtts"
:key="f.logiFnm" :key="f.logiFnm"
class="content estimate-file-wrapper" class="content estimate-file-wrapper"
> >
<!-- <div>--> <!-- <div>-->
<!-- <i class="fa fa-file-pdf estimate-file-img" style="font-size:40px;" />--> <!-- <i class="fa fa-file-pdf estimate-file-img" style="font-size:40px;" />-->
@@ -195,9 +196,9 @@ watch(pbAtts.value, (newValue) => {
</VLabel> </VLabel>
<div v-if="pbAtts.length == 0" style="width:100%; height:10px;"></div> <div v-if="pbAtts.length == 0" style="width:100%; height:10px;"></div>
<div <div
v-for="(f, i) in pbAtts" v-for="(f, i) in pbAtts"
:key="f.logiFnm" :key="f.logiFnm"
class="content estimate-file-wrapper" class="content estimate-file-wrapper"
> >
<div class="estimate-file-name"> <div class="estimate-file-name">
{{ f.logiFnm }} ({{ Math.ceil(f.size / 1024) }}kb) {{ f.logiFnm }} ({{ Math.ceil(f.size / 1024) }}kb)
@@ -215,10 +216,10 @@ watch(pbAtts.value, (newValue) => {
<table class="table datatable-table is-fullwidth"> <table class="table datatable-table is-fullwidth">
<colgroup> <colgroup>
<col width="50px"/> <col width="50px"/>
<col/> <col width="200px"/>
<col/> <col/>
<col width="50px"/> <col width="50px"/>
<col width="50px"/> <col width="80px"/>
<col width="120px"/> <col width="120px"/>
<col width="100px"/> <col width="100px"/>
</colgroup> </colgroup>
@@ -232,17 +233,17 @@ watch(pbAtts.value, (newValue) => {
<th>금액</th> <th>금액</th>
</thead> </thead>
<tbody> <tbody>
<tr v-for="(dtl, index) in props.prcs.dtlSpecs" :key="dtl.dtlSpNo"> <tr v-for="(dtl, index) in props.prcs.dtlSpecs" :key="dtl.dtlSpNo">
<td class="text-center">{{ index + 1 }}</td> <td class="text-center">{{ index + 1 }}</td>
<td>{{ dtl.itemNm }}</td> <td>{{ dtl.itemNm }}</td>
<td>{{ dtl.spec }}</td> <td>{{ dtl.spec }}</td>
<td>{{ dtl.qty }}</td> <td class="text-center">{{ dtl.qty }}</td>
<td>{{ dtl.unit }}</td> <td class="text-center">{{ dtl.unit }}</td>
<td> <td>
<input <input
v-model="estimates[index].unitPrc" v-model="estimates[index].unitPrc"
type="number" type="number"
class="input custom-text-filter" class="input custom-text-filter text-right"
placeholder="10,000" placeholder="10,000"
> >
</td> </td>

View File

@@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { iPrcs, iDtlSpec, iEstimate, UserData, iPbAtt } from '/@src/utils/types' import type { iPrcs, iDtlSpec, iEstimate, UserData, iPbAtt } from '/@src/utils/types'
import regex from "/@src/utils/regex.ts";
const props = defineProps<{ const props = defineProps<{
prcs: iPrcs prcs: iPrcs
@@ -67,7 +68,7 @@ const onFilDelete = (fileOrd: number) => {
const totPrc = computed(() => { const totPrc = computed(() => {
return estimates.value.map((item: iEstimate) => { return estimates.value.map((item: iEstimate) => {
item.amt = item.unitPrc * item.qty item.amt = item.unitPrc * item.qty
return item.amt return item.amt.toString().replace(regex.currency, ',')
}) })
}) })
@@ -87,47 +88,6 @@ watch(pbAtts.value, (newValue) => {
class="form-layout" class="form-layout"
> >
<div class="form-body"> <div class="form-body">
<!--Fieldset-->
<!-- <div class="form-fieldset">-->
<!-- <div class="form-outer">-->
<!-- <div class="fieldset-heading">-->
<!-- <h4>업체정보</h4>-->
<!-- </div>-->
<!-- <div class="columns is-multiline">-->
<!-- <div class="column is-12">-->
<!-- <VField>-->
<!-- <VLabel>회사명</VLabel>-->
<!-- <VControl>-->
<!-- <div class="content">-->
<!-- <p>{{ user.compNm }}</p>-->
<!-- </div>-->
<!-- </VControl>-->
<!-- </VField>-->
<!-- </div>-->
<!-- <div class="column is-6">-->
<!-- <VField>-->
<!-- <VLabel>사업자번호</VLabel>-->
<!-- <VControl>-->
<!-- <div class="content">-->
<!-- <p>{{ user.bizNo }}</p>-->
<!-- </div>-->
<!-- </VControl>-->
<!-- </VField>-->
<!-- </div>-->
<!-- <div class="column is-6">-->
<!-- <VField>-->
<!-- <VLabel>대표자명</VLabel>-->
<!-- <VControl>-->
<!-- <div class="content">-->
<!-- <p>{{ user.repNm }}</p>-->
<!-- </div>-->
<!-- </VControl>-->
<!-- </VField>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!--Fieldset-->
<div class="form-fieldset"> <div class="form-fieldset">
<div class="form-outer"> <div class="form-outer">
<div class="fieldset-heading"> <div class="fieldset-heading">
@@ -224,6 +184,15 @@ watch(pbAtts.value, (newValue) => {
<div class="datatable-wrapper"> <div class="datatable-wrapper">
<div class="table-container"> <div class="table-container">
<table class="table datatable-table is-fullwidth"> <table class="table datatable-table is-fullwidth">
<colgroup>
<col width="50px"/>
<col width="200px"/>
<col/>
<col width="50px"/>
<col width="80px"/>
<col width="120px"/>
<col width="100px"/>
</colgroup>
<thead> <thead>
<th>순번</th> <th>순번</th>
<th>품명</th> <th>품명</th>
@@ -235,13 +204,13 @@ watch(pbAtts.value, (newValue) => {
</thead> </thead>
<tbody v-for="(dtl, index) in props.prcs.dtlSpecs" :key="dtl.dtlSpNo"> <tbody v-for="(dtl, index) in props.prcs.dtlSpecs" :key="dtl.dtlSpNo">
<tr> <tr>
<td>{{ index + 1 }}</td> <td class="text-center">{{ index + 1 }}</td>
<td>{{ dtl.itemNm }}</td> <td>{{ dtl.itemNm }}</td>
<td>{{ dtl.spec }}</td> <td>{{ dtl.spec }}</td>
<td>{{ dtl.qty }}</td> <td class="text-center">{{ dtl.qty }}</td>
<td>{{ dtl.unit }}</td> <td class="text-center">{{ dtl.unit }}</td>
<td>0</td> <td class="text-right">0</td>
<td>{{ totPrc[index] || 0 }}</td> <td class="text-right">{{ totPrc[index] || 0 }}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@@ -49,6 +49,7 @@ function onSearch(data: any) {
} }
const setData = (data: iEstimate[]) => { const setData = (data: iEstimate[]) => {
console.log(data)
ests.value = data ests.value = data
} }
@@ -152,5 +153,11 @@ watch(params, (newValue) => {
</template> </template>
<style lang="scss"> <style lang="scss">
.text-right {
text-align:right !important;
}
.text-center {
text-align:center !important;
}
</style> </style>

View File

@@ -193,12 +193,6 @@ watch(changePage, (newParams) => {
</template> </template>
<style lang="scss"> <style lang="scss">
.text-right {
text-align:right !important;
}
.text-center {
text-align:center !important;
}
.is-navbar { .is-navbar {
.datatable-toolbar { .datatable-toolbar {

View File

@@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import type { iDtlSpec, iEstimate, UserData, iPbAtt } from '/@src/utils/types' import type { iDtlSpec, iEstimate, UserData, iPbAtt } from '/@src/utils/types'
import regex from "/@src/utils/regex.ts";
const props = defineProps<{ const props = defineProps<{
estimate: iEstimate estimate: iEstimate
@@ -93,7 +94,7 @@ const onPbAttDownload = (prcsNo: string, bizNo: string, fileOrd: number, logiFnm
const totPrc = computed(() => { const totPrc = computed(() => {
return estimates.value.map((item: iEstimate) => { return estimates.value.map((item: iEstimate) => {
item.amt = item.unitPrc * item.qty item.amt = item.unitPrc * item.qty
return item.amt return item.amt.toString().replace(regex.currency, ',')
}) })
}) })
@@ -113,47 +114,6 @@ watch(pbAtts.value, (newValue) => {
class="form-layout" class="form-layout"
> >
<div class="form-body"> <div class="form-body">
<!--Fieldset-->
<!-- <div class="form-fieldset">-->
<!-- <div class="form-outer">-->
<!-- <div class="fieldset-heading">-->
<!-- <h4>업체정보</h4>-->
<!-- </div>-->
<!-- <div class="columns is-multiline">-->
<!-- <div class="column is-12">-->
<!-- <VField>-->
<!-- <VLabel>회사명</VLabel>-->
<!-- <VControl>-->
<!-- <div class="content">-->
<!-- <p>{{ user.compNm }}</p>-->
<!-- </div>-->
<!-- </VControl>-->
<!-- </VField>-->
<!-- </div>-->
<!-- <div class="column is-6">-->
<!-- <VField>-->
<!-- <VLabel>사업자번호</VLabel>-->
<!-- <VControl>-->
<!-- <div class="content">-->
<!-- <p>{{ user.bizNo }}</p>-->
<!-- </div>-->
<!-- </VControl>-->
<!-- </VField>-->
<!-- </div>-->
<!-- <div class="column is-6">-->
<!-- <VField>-->
<!-- <VLabel>대표자명</VLabel>-->
<!-- <VControl>-->
<!-- <div class="content">-->
<!-- <p>{{ user.repNm }}</p>-->
<!-- </div>-->
<!-- </VControl>-->
<!-- </VField>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!--Fieldset-->
<div class="form-fieldset"> <div class="form-fieldset">
<div class="form-outer"> <div class="form-outer">
<div class="fieldset-heading"> <div class="fieldset-heading">
@@ -277,6 +237,15 @@ watch(pbAtts.value, (newValue) => {
<div class="datatable-wrapper"> <div class="datatable-wrapper">
<div class="table-container"> <div class="table-container">
<table class="table datatable-table is-fullwidth"> <table class="table datatable-table is-fullwidth">
<colgroup>
<col width="50px"/>
<col width="200px"/>
<col/>
<col width="50px"/>
<col width="80px"/>
<col width="120px"/>
<col width="100px"/>
</colgroup>
<thead> <thead>
<th>순번</th> <th>순번</th>
<th>품명</th> <th>품명</th>
@@ -288,16 +257,16 @@ watch(pbAtts.value, (newValue) => {
</thead> </thead>
<tbody v-for="(dtl, index) in props.estimate.dtlSpecs" :key="dtl.dtlSpNo"> <tbody v-for="(dtl, index) in props.estimate.dtlSpecs" :key="dtl.dtlSpNo">
<tr> <tr>
<td>{{ index + 1 }}</td> <td class="text-center">{{ index + 1 }}</td>
<td>{{ dtl.itemNm }}</td> <td>{{ dtl.itemNm }}</td>
<td>{{ dtl.spec }}</td> <td>{{ dtl.spec }}</td>
<td>{{ dtl.qty }}</td> <td class="text-center">{{ dtl.qty }}</td>
<td>{{ dtl.unit }}</td> <td class="text-center">{{ dtl.unit }}</td>
<td> <td>
<input <input
v-model="estimates[index].unitPrc" v-model="estimates[index].unitPrc"
type="number" type="number"
class="input custom-text-filter" class="input custom-text-filter text-right"
placeholder="10,000" placeholder="10,000"
> >
</td> </td>

View File

@@ -66,47 +66,6 @@ const totPrc = computed(() => {
class="form-layout" class="form-layout"
> >
<div class="form-body"> <div class="form-body">
<!--Fieldset-->
<!-- <div class="form-fieldset">-->
<!-- <div class="form-outer">-->
<!-- <div class="fieldset-heading">-->
<!-- <h4>업체정보</h4>-->
<!-- </div>-->
<!-- <div class="columns is-multiline">-->
<!-- <div class="column is-12">-->
<!-- <VField>-->
<!-- <VLabel>회사명</VLabel>-->
<!-- <VControl>-->
<!-- <div class="content">-->
<!-- <p>{{ user.compNm }}</p>-->
<!-- </div>-->
<!-- </VControl>-->
<!-- </VField>-->
<!-- </div>-->
<!-- <div class="column is-6">-->
<!-- <VField>-->
<!-- <VLabel>사업자번호</VLabel>-->
<!-- <VControl>-->
<!-- <div class="content">-->
<!-- <p>{{ user.bizNo }}</p>-->
<!-- </div>-->
<!-- </VControl>-->
<!-- </VField>-->
<!-- </div>-->
<!-- <div class="column is-6">-->
<!-- <VField>-->
<!-- <VLabel>대표자명</VLabel>-->
<!-- <VControl>-->
<!-- <div class="content">-->
<!-- <p>{{ user.repNm }}</p>-->
<!-- </div>-->
<!-- </VControl>-->
<!-- </VField>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!--Fieldset-->
<div class="form-fieldset"> <div class="form-fieldset">
<div class="form-outer"> <div class="form-outer">
<div class="fieldset-heading"> <div class="fieldset-heading">
@@ -222,6 +181,15 @@ const totPrc = computed(() => {
<div class="datatable-wrapper"> <div class="datatable-wrapper">
<div class="table-container"> <div class="table-container">
<table class="table datatable-table is-fullwidth"> <table class="table datatable-table is-fullwidth">
<colgroup>
<col width="50px"/>
<col width="200px"/>
<col/>
<col width="50px"/>
<col width="80px"/>
<col width="120px"/>
<col width="100px"/>
</colgroup>
<thead> <thead>
<th>순번</th> <th>순번</th>
<th>품명</th> <th>품명</th>
@@ -233,11 +201,11 @@ const totPrc = computed(() => {
</thead> </thead>
<tbody v-for="(dtl, index) in props.estimate.dtlSpecs" :key="dtl.dtlSpNo"> <tbody v-for="(dtl, index) in props.estimate.dtlSpecs" :key="dtl.dtlSpNo">
<tr> <tr>
<td>{{ index + 1 }}</td> <td class="text-center">{{ index + 1 }}</td>
<td>{{ dtl.itemNm }}</td> <td>{{ dtl.itemNm }}</td>
<td>{{ dtl.spec }}</td> <td>{{ dtl.spec }}</td>
<td>{{ dtl.qty }}</td> <td class="text-center">{{ dtl.qty }}</td>
<td>{{ dtl.unit }}</td> <td class="text-center">{{ dtl.unit }}</td>
<td class="text-right">{{ String(estimates[index].unitPrc).replace(regex.currency, ',') }}</td> <td class="text-right">{{ String(estimates[index].unitPrc).replace(regex.currency, ',') }}</td>
<td>{{ String(totPrc[index]).replace(regex.currency, ',') || 0 }}</td> <td>{{ String(totPrc[index]).replace(regex.currency, ',') || 0 }}</td>
</tr> </tr>

View File

@@ -1,6 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { UserData, iRePassword } from '/@src/utils/types' import type { UserData, iRePassword } from '/@src/utils/types'
import regex from '/@src/utils/regex' import regex from '/@src/utils/regex'
import rules from '/@src/utils/rules'
const userSession = useUserSession() const userSession = useUserSession()
const router = useRouter() const router = useRouter()
const notyf = useNotyf() const notyf = useNotyf()
@@ -34,13 +35,6 @@ const initRePassword = {
} }
const rePasswordValid = ref(initRePassword) const rePasswordValid = ref(initRePassword)
const rules = {
email: {
mask: /^\S*@?\S*$/,
lazy: false,
},
}
const onEmailComplete = (e) => { const onEmailComplete = (e) => {
modifyForm.value.email = e.value modifyForm.value.email = e.value
} }

View File

@@ -1,7 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import api from '/@src/utils/api.ts' import api from '/@src/utils/api.ts'
import type { UserData } from '/@src/utils/types' import type { UserData } from '/@src/utils/types'
import regex from '/@src/utils/regex.ts' import regex from '/@src/utils/regex'
import rules from '/@src/utils/rules'
type StepId = 'login' | 'forgot-password' type StepId = 'login' | 'forgot-password'
const step = ref<StepId>('login') const step = ref<StepId>('login')
@@ -24,17 +25,6 @@ const notyf = useNotyf()
const token = useUserToken() const token = useUserToken()
const userSession = useUserSession() const userSession = useUserSession()
const rules = {
bizNo: {
mask: '000-00-00000',
lazy: false,
},
email: {
mask: /^\S*@?\S*$/,
lazy: false,
},
}
const onComplete = (e: any) => { const onComplete = (e: any) => {
loginForm.value.bizNo = e.value loginForm.value.bizNo = e.value
} }

View File

@@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import regex from '/@src/utils/regex' import regex from '/@src/utils/regex'
import rules from '/@src/utils/rules'
const router = useRouter() const router = useRouter()
const notyf = useNotyf() const notyf = useNotyf()
const step = ref(0) const step = ref(0)
@@ -83,17 +84,6 @@ const handleSignup = async () => {
} }
} }
const rules = {
bizNo: {
mask: '000-00-00000',
lazy: false,
},
email: {
mask: /^\S*@?\S*$/,
lazy: false,
},
}
const onBizNoComplete = (e: any) => { const onBizNoComplete = (e: any) => {
registerForm.value.bizNo = e.value registerForm.value.bizNo = e.value
} }

View File

@@ -59,6 +59,7 @@ input {
border: 1px solid var(--fade-grey); border: 1px solid var(--fade-grey);
td { td {
word-break: break-word;
padding: 5px 10px !important; padding: 5px 10px !important;
border: 1px solid #ededed; border: 1px solid #ededed;
input { input {
@@ -162,7 +163,7 @@ a.mouse-pointer {
.estimate-file-name { .estimate-file-name {
width: 400px; width: 400px;
line-height: 40px; line-height: 40px;
color: var(--modal-text-reverse) color: var(--modal-text)
} }
.estimate-file-size { .estimate-file-size {
width: 150px; width: 150px;

22
src/utils/rules.ts Normal file
View File

@@ -0,0 +1,22 @@
/**
* Resolve after `time` has been spend.
*
* @param time Time in milliseconds to wait
*/
const rules = {
bizNo: {
mask: '000-00-00000',
lazy: false,
},
email: {
mask: /^\S*@?\S*$/,
lazy: false,
},
currency: {
mask: /(?=.*\d)^\$?(([1-9]\d{0,2}(,\d{3})*)|0)?(\.\d{1,2})?$/,
lazy: false,
},
}
export default rules

1
types/imports.d.ts vendored
View File

@@ -105,6 +105,7 @@ declare global {
const resolveComponent: typeof import('vue')['resolveComponent'] const resolveComponent: typeof import('vue')['resolveComponent']
const resolveRef: typeof import('@vueuse/core')['resolveRef'] const resolveRef: typeof import('@vueuse/core')['resolveRef']
const resolveUnref: typeof import('@vueuse/core')['resolveUnref'] const resolveUnref: typeof import('@vueuse/core')['resolveUnref']
const rules: typeof import('../src/utils/rules')['default']
const shallowReactive: typeof import('vue')['shallowReactive'] const shallowReactive: typeof import('vue')['shallowReactive']
const shallowReadonly: typeof import('vue')['shallowReadonly'] const shallowReadonly: typeof import('vue')['shallowReadonly']
const shallowRef: typeof import('vue')['shallowRef'] const shallowRef: typeof import('vue')['shallowRef']

View File

@@ -296,8 +296,6 @@ export default defineConfig(({ isSsrBuild }) => ({
// Predefine dependencies in order to prevent reloading them in the browser during development. // Predefine dependencies in order to prevent reloading them in the browser during development.
optimizeDeps: { optimizeDeps: {
include: [ include: [
'@ckeditor/ckeditor5-vue',
'@ckeditor/ckeditor5-build-classic',
'@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.min.js', '@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.min.js',
'@shikijs/rehype', '@shikijs/rehype',
'@vee-validate/zod', '@vee-validate/zod',