mirror of
https://git.hmsn.ink/kospo/svcm/oa.git
synced 2026-03-20 03:12:27 +09:00
func : 계약관리 등록폼
- 가격조사 가져오기 활성화
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
import notyf from "/@src/plugins/notyf.ts";
|
||||||
|
|
||||||
const registerFormOpen = ref(false)
|
const registerFormOpen = ref(false)
|
||||||
const params = reactive({
|
const params = reactive({
|
||||||
@@ -22,6 +23,29 @@ const params = reactive({
|
|||||||
modalColumn: [],
|
modalColumn: [],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const completedPriceDataParams = reactive({
|
||||||
|
prcsNo:'',
|
||||||
|
cateCd:'',
|
||||||
|
cateNm:'',
|
||||||
|
bizNo:'',
|
||||||
|
compNm:'',
|
||||||
|
title:'',
|
||||||
|
content:'',
|
||||||
|
regSdat:'',
|
||||||
|
regEdat:'',
|
||||||
|
regSabun:'',
|
||||||
|
regNm:'',
|
||||||
|
regDt:'',
|
||||||
|
amt:'',
|
||||||
|
stCd:'',
|
||||||
|
stNm:'',
|
||||||
|
svyDt:'',
|
||||||
|
reason:'',
|
||||||
|
estimates: [],
|
||||||
|
page: 1,
|
||||||
|
row: 5,
|
||||||
|
})
|
||||||
|
|
||||||
params.modalColumn = [
|
params.modalColumn = [
|
||||||
{ key: 'cateNm', label: '분야' },
|
{ key: 'cateNm', label: '분야' },
|
||||||
{ key: 'title', label: '제목' },
|
{ key: 'title', label: '제목' },
|
||||||
@@ -30,11 +54,13 @@ params.modalColumn = [
|
|||||||
{ key: 'title', label: '비고' },
|
{ key: 'title', label: '비고' },
|
||||||
{ key: 'regNm', label: '선택' },
|
{ key: 'regNm', label: '선택' },
|
||||||
]
|
]
|
||||||
|
|
||||||
const selectedCode = ref()
|
const selectedCode = ref()
|
||||||
|
const priceSearchCheckBoxStatus = ref(false)
|
||||||
|
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
contractData: [],
|
contractData: [],
|
||||||
priceSearchData: [],
|
completedPriceSearchData: [],
|
||||||
})
|
})
|
||||||
|
|
||||||
const isLoading = ref(false)
|
const isLoading = ref(false)
|
||||||
@@ -44,8 +70,7 @@ watch(registerFormOpen, async (isOpen) => {
|
|||||||
// error.value = null
|
// error.value = null
|
||||||
try {
|
try {
|
||||||
const priceSearchDataRespone = await axios.get('/api/cont/prcs')
|
const priceSearchDataRespone = await axios.get('/api/cont/prcs')
|
||||||
console.log(priceSearchDataRespone.data)
|
data.completedPriceSearchData = Array.isArray(priceSearchDataRespone.data) ? priceSearchDataRespone.data : []
|
||||||
data.priceSearchData = Array.isArray(priceSearchDataRespone.data) ? priceSearchDataRespone.data : []
|
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
@@ -73,8 +98,8 @@ function getDateDiff(start, end) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const contractPeriod = computed(() => {
|
const contractPeriod = computed(() => {
|
||||||
const start = params.regSdt
|
const start = completedPriceDataParams.regSdat
|
||||||
const end = params.regEdt
|
const end = completedPriceDataParams.regEdat
|
||||||
const startStr = formatDate(start)
|
const startStr = formatDate(start)
|
||||||
const endStr = formatDate(end)
|
const endStr = formatDate(end)
|
||||||
const diff = getDateDiff(start, end)
|
const diff = getDateDiff(start, end)
|
||||||
@@ -95,6 +120,67 @@ const contractPeriod = computed(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
function handlePriceRowClick(row) {
|
||||||
|
completedPriceDataParams.prcsNo = row.prcsNo || ''
|
||||||
|
completedPriceDataParams.cateCd = row.cateCd || ''
|
||||||
|
completedPriceDataParams.cateNm = row.cateNm || ''
|
||||||
|
completedPriceDataParams.title = row.title || ''
|
||||||
|
completedPriceDataParams.content = row.content || ''
|
||||||
|
completedPriceDataParams.regSdat = row.regSdat || ''
|
||||||
|
completedPriceDataParams.regEdat = row.regEdat || ''
|
||||||
|
completedPriceDataParams.regSabun = row.regSabun || ''
|
||||||
|
completedPriceDataParams.regNm = row.regNm || ''
|
||||||
|
completedPriceDataParams.regDt = row.regDt || ''
|
||||||
|
completedPriceDataParams.stCd = row.stCd || ''
|
||||||
|
completedPriceDataParams.stNm = row.stNm || ''
|
||||||
|
completedPriceDataParams.svyDt = row.svyDt || ''
|
||||||
|
completedPriceDataParams.reason = row.reason || ''
|
||||||
|
|
||||||
|
selectedCode.value = row.cateCd || ''
|
||||||
|
completedPriceDataParams.estimates = row.estimates || []
|
||||||
|
|
||||||
|
if (row.estimates && row.estimates.length > 0) {
|
||||||
|
const minEstimate = row.estimates.reduce((min, curr) => curr.amt < min.amt ? curr : min, row.estimates[0])
|
||||||
|
completedPriceDataParams.bizNo = minEstimate.bizNo || ''
|
||||||
|
completedPriceDataParams.compNm = minEstimate.compNm || ''
|
||||||
|
completedPriceDataParams.amt = minEstimate.amt || ''
|
||||||
|
} else {
|
||||||
|
completedPriceDataParams.bizNo = ''
|
||||||
|
completedPriceDataParams.compNm = ''
|
||||||
|
completedPriceDataParams.amt = ''
|
||||||
|
notyf.error("견적서가 없습니다.")
|
||||||
|
}
|
||||||
|
|
||||||
|
registerFormOpen.value = false
|
||||||
|
priceSearchCheckBoxStatus.value = !!row
|
||||||
|
console.log(row)
|
||||||
|
console.log(completedPriceDataParams.amt)
|
||||||
|
}
|
||||||
|
|
||||||
|
const showFileInputs = ref(false)
|
||||||
|
const fileInputs = ref([
|
||||||
|
{ file: null, description: '시행 품의문' },
|
||||||
|
{ file: null, description: '소액수의계약서' },
|
||||||
|
{ file: null, description: '수의계약 체결 제한 여부 확인서' },
|
||||||
|
{ file: null, description: '퇴직자 재직여부 확인서' },
|
||||||
|
{ file: null, description: '인지세 납부확인서' },
|
||||||
|
{ file: null, description: '정부권장정책 이행 구매 검토서' },
|
||||||
|
{ file: null, description: '기타' }
|
||||||
|
])
|
||||||
|
|
||||||
|
function handleFileChange(e, idx) {
|
||||||
|
const files = e.target.files
|
||||||
|
if (files && files.length > 0) {
|
||||||
|
fileInputs.value[idx].file = files[0]
|
||||||
|
} else {
|
||||||
|
fileInputs.value[idx].file = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -116,10 +202,10 @@ const contractPeriod = computed(() => {
|
|||||||
<td>분야</td>
|
<td>분야</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="colum">
|
<span class="colum">
|
||||||
<VField class="pr-2">
|
<VField class="">
|
||||||
<VCodeSelect
|
<VCodeSelect
|
||||||
v-model="selectedCode"
|
v-model="selectedCode"
|
||||||
cd_grp="5/"
|
cd_grp="5"
|
||||||
/></VField>
|
/></VField>
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
@@ -136,28 +222,19 @@ const contractPeriod = computed(() => {
|
|||||||
title="계약관리 등록"
|
title="계약관리 등록"
|
||||||
size="contract-big"
|
size="contract-big"
|
||||||
actions="right"
|
actions="right"
|
||||||
@submit.prevent="registerFormOpen = false"
|
|
||||||
@close="registerFormOpen = false"
|
|
||||||
>
|
>
|
||||||
<template #content>
|
<template #content>
|
||||||
<div class="modal-form">
|
<div class="modal-form">
|
||||||
<ComVFlexTable
|
<ComVFlexTable
|
||||||
:data="data.priceSearchData"
|
:data="data.completedPriceSearchData"
|
||||||
:columns="params.modalColumn"
|
:columns="params.modalColumn"
|
||||||
:compact="true"
|
:compact="true"
|
||||||
:separators="true"
|
:separators="true"
|
||||||
|
@row-click="handlePriceRowClick"
|
||||||
|
clickable
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #action>
|
|
||||||
<VButton
|
|
||||||
type="submit"
|
|
||||||
color="primary"
|
|
||||||
raised
|
|
||||||
>
|
|
||||||
Save Changes
|
|
||||||
</VButton>
|
|
||||||
</template>
|
|
||||||
</VModal>
|
</VModal>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -166,6 +243,7 @@ const contractPeriod = computed(() => {
|
|||||||
<VCheckbox
|
<VCheckbox
|
||||||
label="가격조사여부"
|
label="가격조사여부"
|
||||||
color="info"
|
color="info"
|
||||||
|
v-model="priceSearchCheckBoxStatus"
|
||||||
/>
|
/>
|
||||||
</VControl>
|
</VControl>
|
||||||
</VField>
|
</VField>
|
||||||
@@ -175,7 +253,7 @@ const contractPeriod = computed(() => {
|
|||||||
<VField>
|
<VField>
|
||||||
<VControl>
|
<VControl>
|
||||||
<input
|
<input
|
||||||
v-model="params.reason"
|
v-model="completedPriceDataParams.reason"
|
||||||
class="input custom-text-filter"
|
class="input custom-text-filter"
|
||||||
placeholder="가격조사 안했을 시 예외 사유 입력(필수)"
|
placeholder="가격조사 안했을 시 예외 사유 입력(필수)"
|
||||||
>
|
>
|
||||||
@@ -190,7 +268,7 @@ const contractPeriod = computed(() => {
|
|||||||
<VField>
|
<VField>
|
||||||
<VControl>
|
<VControl>
|
||||||
<input
|
<input
|
||||||
v-model="params.title"
|
v-model="completedPriceDataParams.title"
|
||||||
class="input custom-text-filter"
|
class="input custom-text-filter"
|
||||||
placeholder="계약명"
|
placeholder="계약명"
|
||||||
>
|
>
|
||||||
@@ -204,7 +282,7 @@ const contractPeriod = computed(() => {
|
|||||||
<VField>
|
<VField>
|
||||||
<VControl>
|
<VControl>
|
||||||
<input
|
<input
|
||||||
v-model="params.regNm"
|
v-model="completedPriceDataParams.bizNo"
|
||||||
class="input custom-text-filter"
|
class="input custom-text-filter"
|
||||||
placeholder="사업자번호"
|
placeholder="사업자번호"
|
||||||
>
|
>
|
||||||
@@ -215,7 +293,7 @@ const contractPeriod = computed(() => {
|
|||||||
<VField>
|
<VField>
|
||||||
<VControl>
|
<VControl>
|
||||||
<input
|
<input
|
||||||
v-model="params.compNm"
|
v-model="completedPriceDataParams.compNm"
|
||||||
class="input custom-text-filter"
|
class="input custom-text-filter"
|
||||||
placeholder="업체명"
|
placeholder="업체명"
|
||||||
>
|
>
|
||||||
@@ -249,7 +327,7 @@ const contractPeriod = computed(() => {
|
|||||||
<VField>
|
<VField>
|
||||||
<VControl>
|
<VControl>
|
||||||
<input
|
<input
|
||||||
v-model="params.signDt"
|
:value="formatDate(completedPriceDataParams.regSdat)"
|
||||||
class="input custom-text-filter"
|
class="input custom-text-filter"
|
||||||
placeholder="계약체결일"
|
placeholder="계약체결일"
|
||||||
>
|
>
|
||||||
@@ -283,7 +361,7 @@ const contractPeriod = computed(() => {
|
|||||||
<VField>
|
<VField>
|
||||||
<VControl>
|
<VControl>
|
||||||
<input
|
<input
|
||||||
v-model="params.contAmt"
|
v-model="completedPriceDataParams.amt"
|
||||||
class="input custom-text-filter"
|
class="input custom-text-filter"
|
||||||
placeholder="금액"
|
placeholder="금액"
|
||||||
>
|
>
|
||||||
@@ -311,7 +389,7 @@ const contractPeriod = computed(() => {
|
|||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<VDatePicker
|
<VDatePicker
|
||||||
v-model="params.regSdt"
|
v-model="completedPriceDataParams.regSdat"
|
||||||
color="green"
|
color="green"
|
||||||
trim-weeks
|
trim-weeks
|
||||||
>
|
>
|
||||||
@@ -333,10 +411,10 @@ const contractPeriod = computed(() => {
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td colspan="1">
|
<td colspan="1">
|
||||||
<div class="pr-2">
|
<div class="">
|
||||||
<div>
|
<div>
|
||||||
<VDatePicker
|
<VDatePicker
|
||||||
v-model="params.regEdt"
|
v-model="completedPriceDataParams.regEdat"
|
||||||
color="green"
|
color="green"
|
||||||
trim-weeks
|
trim-weeks
|
||||||
>
|
>
|
||||||
@@ -364,20 +442,36 @@ const contractPeriod = computed(() => {
|
|||||||
<tr>
|
<tr>
|
||||||
<td>첨부파일</td>
|
<td>첨부파일</td>
|
||||||
<td colspan="1">
|
<td colspan="1">
|
||||||
<VButton color="info">
|
<VButton color="info" @click="showFileInputs = !showFileInputs">
|
||||||
등록
|
등록
|
||||||
</VButton>
|
</VButton>
|
||||||
</td>
|
</td>
|
||||||
<td colspan="5" />
|
<td colspan="5">
|
||||||
|
<!-- 첨부파일 입력영역: 등록 버튼 클릭 시 토글 -->
|
||||||
|
<div v-if="showFileInputs" class="file-upload-list" style="margin-top:10px;">
|
||||||
|
<div
|
||||||
|
v-for="(input, idx) in fileInputs"
|
||||||
|
:key="idx"
|
||||||
|
style="display: flex; align-items: center; margin-bottom: 8px;"
|
||||||
|
>
|
||||||
|
<!-- 파일선택 -->
|
||||||
|
<label class="file-label" style="margin-right: 10px;">
|
||||||
|
<input
|
||||||
|
type="file"
|
||||||
|
class="file-input"
|
||||||
|
@change="e => handleFileChange(e, idx)"
|
||||||
|
/>
|
||||||
|
<span class="file-cta">파일선택</span>
|
||||||
|
</label>
|
||||||
|
<span style="flex:1; margin-right: 10px;">{{ input.file ? input.file.name : '첨부된 파일 없음' }}</span>
|
||||||
|
<span style="flex:2; color: #666;">{{ input.description }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="bottom-button">
|
<div class="bottom-button">
|
||||||
<VButton
|
|
||||||
to="/app/DocumentManagement"
|
|
||||||
>
|
|
||||||
전 표 (임시)
|
|
||||||
</VButton>
|
|
||||||
<VButton>저 장</VButton>
|
<VButton>저 장</VButton>
|
||||||
<VButton>취 소</VButton>
|
<VButton>취 소</VButton>
|
||||||
</div>
|
</div>
|
||||||
@@ -389,11 +483,14 @@ const contractPeriod = computed(() => {
|
|||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.table tbody td {
|
.table tbody td {
|
||||||
color: var(--smoke-white);
|
color: var(--smoke-white);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.datatable-table {
|
.datatable-table {
|
||||||
padding: 12px 12px;
|
td{
|
||||||
|
font-family: var(--font),serif;
|
||||||
|
vertical-align: middle;
|
||||||
|
padding: 4px 12px;
|
||||||
|
border-bottom: 1px solid var(--fade-grey);
|
||||||
|
}
|
||||||
|
|
||||||
td:nth-child(1) {
|
td:nth-child(1) {
|
||||||
background-color: var(--primary);
|
background-color: var(--primary);
|
||||||
@@ -432,4 +529,16 @@ const contractPeriod = computed(() => {
|
|||||||
.field {
|
.field {
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.file-label {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.file-input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.file-cta {
|
||||||
|
background: #eee;
|
||||||
|
padding: 4px 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import axios from 'axios'
|
import {getContractList} from "/src/service/contract";
|
||||||
import {useRouter} from "vue-router";
|
import regex, {formatCurrency} from "/@src/utils/common/regex.ts";
|
||||||
|
|
||||||
export type MinimalTheme = 'darker' | 'light'
|
export type MinimalTheme = 'darker' | 'light'
|
||||||
|
|
||||||
@@ -21,57 +21,37 @@ const data = reactive({
|
|||||||
priceData: [],
|
priceData: [],
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(async () => {
|
onBeforeMount(async () => {
|
||||||
try {
|
await getContractListView()
|
||||||
const contractResponse = await axios.get('/api/cont/prcs')
|
|
||||||
data.contractData = Array.isArray(contractResponse.data) ? contractResponse.data : []
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(error)
|
|
||||||
data.contractData = []
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const registerFormOpen = ref(false)
|
async function getContractListView() {
|
||||||
const isLoading = ref(false)
|
const paymentParams = {
|
||||||
|
params:{
|
||||||
|
title: '',
|
||||||
|
page: '1',
|
||||||
|
row: '10'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const result = await getContractList(paymentParams)
|
||||||
|
data.contractData = result
|
||||||
|
console.log('result', result)
|
||||||
|
}
|
||||||
|
|
||||||
watch(registerFormOpen, async (isOpen) => {
|
|
||||||
if (isOpen) {
|
|
||||||
isLoading.value = true
|
|
||||||
// error.value = null
|
|
||||||
try {
|
|
||||||
const priceResponse = await axios.get('/api/prcs/page?regSdt=1970-01-01®Edt=2070-01-01&page=1&row=10')
|
|
||||||
console.log(priceResponse.data.content)
|
|
||||||
data.priceData = Array.isArray(priceResponse.data.content) ? priceResponse.data.content : []
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(error)
|
|
||||||
data.priceData = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const router = useRouter()
|
|
||||||
|
|
||||||
function handleRowClick(row) {
|
|
||||||
router.push({
|
|
||||||
name: 'DocumentManagement',
|
|
||||||
params: { id: row.contractDetailedData },
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const params = reactive({
|
const params = reactive({
|
||||||
priceData: [],
|
|
||||||
flexColumn: [
|
flexColumn: [
|
||||||
{ key: 'cateNm', label: '분야' },
|
{ key: 'cateNm', label: '분야' },
|
||||||
{ key: 'title', label: '제목' },
|
{ key: 'title', label: '계약명' },
|
||||||
|
{ key: 'compNm', label: '계약상대자' },
|
||||||
{ key: 'regNm', label: '담당자' },
|
{ key: 'regNm', label: '담당자' },
|
||||||
{ key: 'regSdat', label: '최초등록일' },
|
{ key: 'contAmt', label: '계약금액', format: formatCurrency },
|
||||||
{ key: 'stNm', label: '등록 상태' },
|
{ key: 'contNo', label: '계약번호' },
|
||||||
{ key: 'title', label: '비고' },
|
{ key: 'signDt', label: '계약체결일' },
|
||||||
|
{ key: 'contStat', label: '계약상태' },
|
||||||
],
|
],
|
||||||
prcsParams: [],
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -111,7 +91,7 @@ const params = reactive({
|
|||||||
</VLabel>
|
</VLabel>
|
||||||
<VControl>
|
<VControl>
|
||||||
<input
|
<input
|
||||||
v-model="params.title"
|
v-model="params.regNm"
|
||||||
class="input custom-text-filter"
|
class="input custom-text-filter"
|
||||||
placeholder="담당자명"
|
placeholder="담당자명"
|
||||||
>
|
>
|
||||||
@@ -202,8 +182,9 @@ const params = reactive({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<VButtons>
|
<VButtons class="is-right">
|
||||||
<VButton
|
<VButton
|
||||||
|
class=""
|
||||||
color="primary"
|
color="primary"
|
||||||
icon="fas fa-plus"
|
icon="fas fa-plus"
|
||||||
elevated
|
elevated
|
||||||
@@ -213,43 +194,5 @@ const params = reactive({
|
|||||||
등록
|
등록
|
||||||
</VButton>
|
</VButton>
|
||||||
</VButtons>
|
</VButtons>
|
||||||
|
|
||||||
<!-- 모달창 시작-->
|
|
||||||
<VModal
|
|
||||||
is="form"
|
|
||||||
:open="registerFormOpen"
|
|
||||||
title="계약관리 등록"
|
|
||||||
size="contract-big"
|
|
||||||
actions="right"
|
|
||||||
@submit.prevent="registerFormOpen = false"
|
|
||||||
@close="registerFormOpen = false"
|
|
||||||
>
|
|
||||||
<template #content>
|
|
||||||
<div class="modal-form">
|
|
||||||
<ComVFlexTable
|
|
||||||
:data="data.priceData"
|
|
||||||
:columns="{ cateNm: '분야',
|
|
||||||
title: '제목',
|
|
||||||
content: '담당자',
|
|
||||||
stNm: '등록상태',
|
|
||||||
stCd: '비고',
|
|
||||||
regSabun: '선택',
|
|
||||||
}"
|
|
||||||
:compact="true"
|
|
||||||
:separators="true"
|
|
||||||
@row-click="handleRowClick"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #action>
|
|
||||||
<VButton
|
|
||||||
type="submit"
|
|
||||||
color="primary"
|
|
||||||
raised
|
|
||||||
>
|
|
||||||
Save Changes
|
|
||||||
</VButton>
|
|
||||||
</template>
|
|
||||||
</VModal>
|
|
||||||
</div>>
|
|
||||||
</template>
|
|
||||||
|
|||||||
@@ -3,17 +3,20 @@
|
|||||||
import { getIntegratedApproval, updateIntegratedApproval } from '/src/service/integratedPayment'
|
import { getIntegratedApproval, updateIntegratedApproval } from '/src/service/integratedPayment'
|
||||||
import type { VFlexTableWrapperSortFunction, VFlexTableWrapperFilterFunction } from '/src/components/app-vuero/ComVFlexTableWrapper.vue'
|
import type { VFlexTableWrapperSortFunction, VFlexTableWrapperFilterFunction } from '/src/components/app-vuero/ComVFlexTableWrapper.vue'
|
||||||
import { users } from '/src/data/layouts/card-grid-v1'
|
import { users } from '/src/data/layouts/card-grid-v1'
|
||||||
|
import PriceDetail from "/@src/pages/app/priceDetail.vue";
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
await getIntegratedPaymentList()
|
await getIntegratedPaymentList()
|
||||||
})
|
})
|
||||||
const isModalOpen = ref(false)
|
const isModalOpen = ref(false)
|
||||||
const selectedRow = ref<any>(null)
|
const selectedRow = ref<any>(null)
|
||||||
|
const prcsNo = ref('PRCS-20250521020')
|
||||||
|
|
||||||
const masks = ref({
|
const masks = ref({
|
||||||
modelValue: 'YYYY-MM-DD',
|
modelValue: 'YYYY-MM-DD',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const params = reactive({
|
const params = reactive({
|
||||||
title: '',
|
title: '',
|
||||||
priceData: [],
|
priceData: [],
|
||||||
@@ -40,7 +43,7 @@ const params = reactive({
|
|||||||
})
|
})
|
||||||
|
|
||||||
function formatRegDt(value) {
|
function formatRegDt(value) {
|
||||||
return value ? value.substring(0, 16) : ''
|
return value ? value.toString().replace(/[^0-9]/g, '').replace(/\B(?=(\d{3})+(?!\d))/g, ',') : ''
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getIntegratedPaymentList() {
|
async function getIntegratedPaymentList() {
|
||||||
@@ -67,8 +70,8 @@ async function updateIntegratedPaymentList() {
|
|||||||
}
|
}
|
||||||
const result = await updateIntegratedApproval(paymentUpdateParams)
|
const result = await updateIntegratedApproval(paymentUpdateParams)
|
||||||
console.log(result)
|
console.log(result)
|
||||||
alert('결재승인완료')
|
notyf.error("견적서가 없습니다.")
|
||||||
window.location.reload(true)
|
router.push('/app/paymentManagement')
|
||||||
}
|
}
|
||||||
|
|
||||||
const gubunMap = {
|
const gubunMap = {
|
||||||
@@ -246,101 +249,14 @@ const onRowClick = (row: any) => {
|
|||||||
<VModal
|
<VModal
|
||||||
is="form"
|
is="form"
|
||||||
v-model:open="isModalOpen"
|
v-model:open="isModalOpen"
|
||||||
title="결재창"
|
title="결재함"
|
||||||
size="big"
|
size="contract-big"
|
||||||
actions="center"
|
actions="center"
|
||||||
@submit.prevent="isModalOpen = false"
|
@submit.prevent="isModalOpen = false"
|
||||||
@close="isModalOpen = false"
|
@close="isModalOpen = false"
|
||||||
>
|
>
|
||||||
<template #content>
|
<template #content>
|
||||||
<div class="modal-form">
|
<PriceDetail :prcsNo="prcsNo" />
|
||||||
<div class="columns is-multiline">
|
|
||||||
<div class="column is-4">
|
|
||||||
<div class="field">
|
|
||||||
<label>결재번호</label>
|
|
||||||
<div class="control">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="input"
|
|
||||||
placeholder="결재번호"
|
|
||||||
:value="selectedRow?.apprNo"
|
|
||||||
readonly
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="column is-4">
|
|
||||||
<div class="field">
|
|
||||||
<label>제목</label>
|
|
||||||
<div class="control">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="input"
|
|
||||||
placeholder="제목"
|
|
||||||
:value="selectedRow?.title"
|
|
||||||
readonly
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="column is-4">
|
|
||||||
<div class="field">
|
|
||||||
<label>작성자</label>
|
|
||||||
<div class="control">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="input"
|
|
||||||
placeholder="작성자"
|
|
||||||
:value="selectedRow?.name"
|
|
||||||
readonly
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="column is-4">
|
|
||||||
<div class="field">
|
|
||||||
<label>구분</label>
|
|
||||||
<div class="control">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="input"
|
|
||||||
placeholder="구분"
|
|
||||||
:value="selectedRow?.process"
|
|
||||||
readonly
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="column is-4">
|
|
||||||
<div class="field">
|
|
||||||
<label>결재상태</label>
|
|
||||||
<div class="control">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="input"
|
|
||||||
placeholder="결재상태"
|
|
||||||
:value="selectedRow?.apprStat"
|
|
||||||
readonly
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="column is-4">
|
|
||||||
<div class="field">
|
|
||||||
<label>등록일</label>
|
|
||||||
<div class="control">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="input"
|
|
||||||
placeholder="등록일"
|
|
||||||
:value="selectedRow?.regDt"
|
|
||||||
readonly
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
<template #action>
|
<template #action>
|
||||||
<VButton type="submit" color="info" raised>반려</VButton>
|
<VButton type="submit" color="info" raised>반려</VButton>
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 계약관리 조회(페이징)
|
||||||
|
* @property {string} params.page - 페이지
|
||||||
|
* @property {string} params.row - 아이템갯수
|
||||||
|
*
|
||||||
|
*/``
|
||||||
|
export async function getContractList(params = {}) {
|
||||||
|
try {
|
||||||
|
const result = await axios.get(`/api/cont/page`,params)
|
||||||
|
return result.data
|
||||||
|
} catch (e) {
|
||||||
|
if (e.response) {
|
||||||
|
if (e.response.status >= 500) {
|
||||||
|
throw new Error('서버 오류가 발생했습니다.')
|
||||||
|
} else if (e.response.status >= 400) {
|
||||||
|
throw new Error('잘못된 요청입니다.')
|
||||||
|
} else if (e.response._data && e.response._data.message) {
|
||||||
|
throw new Error(e.response._data.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Error(e.message || '알 수 없는 오류')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 계약관리 저장
|
||||||
|
* @param {object} params
|
||||||
|
* @property {string} params.cateNm - 분야
|
||||||
|
* @property {string} params.cateNm - 결제상태
|
||||||
|
* @property {string} params.regNm - 담당자
|
||||||
|
* @property {string} params.regSdat - 등록기간
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export async function saveContract(params = {}) {
|
||||||
|
try {
|
||||||
|
const result = await axios.post(`/api/cont`,params)
|
||||||
|
return result
|
||||||
|
} catch (e) {
|
||||||
|
const serverError = e.response?.data;
|
||||||
|
|
||||||
|
const message = typeof serverError?.body === 'string'
|
||||||
|
? serverError.body
|
||||||
|
: 'Unknown error occurred';
|
||||||
|
|
||||||
|
const error = new Error(message); // ✅ 반드시 string만 넣기! 아니면 객체가 문자열로 나옴
|
||||||
|
error.code = serverError?.code;
|
||||||
|
error.errTime = serverError?.errTime;
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,12 +17,6 @@ export async function getIntegratedApproval(params = {}) {
|
|||||||
console.log(result)
|
console.log(result)
|
||||||
if (result.status === 200) {
|
if (result.status === 200) {
|
||||||
return result.data
|
return result.data
|
||||||
} else if (result.status >= 500) {
|
|
||||||
throw new Error('서버 오류가 발생했습니다.')
|
|
||||||
} else if (result.status >= 400) {
|
|
||||||
throw new Error('잘못된 요청입니다.')
|
|
||||||
} else {
|
|
||||||
throw new Error(`예상치 못한 상태코드: ${result.status}`)
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.response) {
|
if (e.response) {
|
||||||
@@ -55,10 +49,6 @@ export async function updateIntegratedApproval(params = {}) {
|
|||||||
})
|
})
|
||||||
if (result.status === 200) {
|
if (result.status === 200) {
|
||||||
return result.data
|
return result.data
|
||||||
} else if (result.status >= 500) {
|
|
||||||
throw new Error('서버 오류가 발생했습니다.')
|
|
||||||
} else {
|
|
||||||
throw new Error(`예상치 못한 상태코드: ${result.status}`)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
|
|||||||
21
src/utils/common/regex.ts
Normal file
21
src/utils/common/regex.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* Resolve after `time` has been spend.
|
||||||
|
*
|
||||||
|
* @param time Time in milliseconds to wait
|
||||||
|
*/
|
||||||
|
|
||||||
|
const regex = {
|
||||||
|
bizNo: /^[0-9]{3}-[0-9]{2}-[0-9]{5}$/i,
|
||||||
|
email: /^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/i,
|
||||||
|
password: /^(?=.*[a-zA-Z])(?=.*[!@#$%^*+=-])(?=.*[0-9]).{8,15}$/i,
|
||||||
|
currency: /\B(?=(\d{3})+(?!\d))/g,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 천단위 콤마 포맷 함수 추가
|
||||||
|
export function formatCurrency(value) {
|
||||||
|
if (value === null || value === undefined || value === '') return ''
|
||||||
|
const num = Number(value.toString().replace(/[^0-9.]/g, ''))
|
||||||
|
return isNaN(num) ? '' : num.toLocaleString()
|
||||||
|
}
|
||||||
|
|
||||||
|
export default regex
|
||||||
Reference in New Issue
Block a user