mirror of
https://git.hmsn.ink/kospo/svcm/oa.git
synced 2026-03-20 10:53:27 +09:00
first
This commit is contained in:
509
src/pages/app/priceUpdate.vue
Normal file
509
src/pages/app/priceUpdate.vue
Normal file
@@ -0,0 +1,509 @@
|
||||
<script setup lang="ts">
|
||||
import {getDetailPrcs, updatePrice} from '/src/service/priceApi'
|
||||
import { type Person } from '/@src/utils/types'
|
||||
|
||||
const notyf = useNotyf()
|
||||
const loading = ref(false)
|
||||
const router = useRouter()
|
||||
|
||||
onBeforeMount(async ()=>{
|
||||
const result = await getDetailPrcs(history.state.key)
|
||||
getDetailList(result)
|
||||
})
|
||||
|
||||
const showTable = ref(false)
|
||||
const detailActionsOpen = ref(false)
|
||||
const apprLine = defineModel<Person[]>()
|
||||
|
||||
const generalParams = reactive({
|
||||
title: "",
|
||||
content: "",
|
||||
regSdat: "",
|
||||
regEdat: "",
|
||||
prvYn: true,
|
||||
prvRsn : "",
|
||||
prvPwd : "",
|
||||
aiYn: true,
|
||||
})
|
||||
const params = reactive({
|
||||
cateSelect: '',
|
||||
prcsNo: '',
|
||||
stCd: '', //상태코드 등록 전 : 0000
|
||||
prcsAttsColumn:[ //첨부파일 입력
|
||||
{ key: 'logiFnm', label: '구분'},
|
||||
{ key: 'data', label: '데이터'}
|
||||
],
|
||||
prcsAtts: [], //첨부파일 데이터
|
||||
felxColumn: [
|
||||
{ key: 'gubunCd', label: '구분'},
|
||||
{ key: 'deptNm', label: '부서' },
|
||||
{ key: 'sabun', label: '사번' },
|
||||
{ key: 'name', label: '이름' },
|
||||
{ key: 'attendCd', label: '비고' },
|
||||
{ key: 'apprStat', label: '결재상태'},
|
||||
{ key: 'date', label: '승인일자'},
|
||||
],
|
||||
priceData:[],
|
||||
prcsBizsColumn: [ //견적사 입력
|
||||
{ key: 'num', label: '구분', width: '10%' },
|
||||
{ key: 'email', label: '이메일', editable: true, width: '50px' },
|
||||
{ key: 'bizNo', label: '사업자번호', editable: true, width: '50px'},
|
||||
{ key: 'actions', label: '동작', width: '100px'}
|
||||
],
|
||||
prcsBizs: [], //견적사 입력 데이터
|
||||
dtlSpecsColumn: [
|
||||
{ key: 'num', label: '번호', editable: false },
|
||||
{ key: 'itemNm', label: '품명', editable: true },
|
||||
{ key: 'spec', label: '규격', editable: true },
|
||||
{ key: 'unit', label: '단위', editable: true },
|
||||
{ key: 'qty', label: '수량', editable: true },
|
||||
{ key: '', label: '단가(VAT별도)', editable: false },
|
||||
{ key: '', label: '금액(VAT별도)', editable: false },
|
||||
{ key: '', label: '삭제', editable: false },
|
||||
],
|
||||
dtlSpecs: [], //상세 규격 입력 데이터
|
||||
detailData :[
|
||||
{ cateNm: '홍길동', age: 30, email: 'hong@example.com' },
|
||||
{ name: '김철수', age: 28, email: 'kim@example.com' },
|
||||
],
|
||||
btnChangeFlag: false
|
||||
})
|
||||
|
||||
function getDetailList(arg){
|
||||
params.prcsNo = arg.prcsNo
|
||||
params.stCd = arg.stCd
|
||||
params.cateSelect = arg.cateCd
|
||||
generalParams.title = arg.title
|
||||
generalParams.content = arg.content
|
||||
params.prcsBizs = arg.prcsBizs.map(req => ({
|
||||
bizNo: req.bizNo,
|
||||
email: req.email,
|
||||
}))
|
||||
params.dtlSpecs = arg.dtlSpecs
|
||||
generalParams.regSdat = arg.regSdat
|
||||
generalParams.regEdat = arg.regEdat
|
||||
apprLine.value = arg.apprMst.apprReqs.map(req => ({
|
||||
gubunCd: req.gubunCd,
|
||||
deptCd: req.deptCd,
|
||||
deptNm: req.deptNm,
|
||||
sabun: req.sabun,
|
||||
name: req.name,
|
||||
apprNo: req.apprNo,
|
||||
apprOrd: req.apprOrd,
|
||||
apprStat: req.apprStat,
|
||||
attendCd: req.attendCd
|
||||
})) //비고 데이터 없음, 승인일자 없음 todo
|
||||
}
|
||||
|
||||
const changeButton = () => {
|
||||
//todo 상세 규격 api 테우기
|
||||
params.btnChangeFlag = true
|
||||
close()
|
||||
}
|
||||
|
||||
const validation = () => {
|
||||
notyf.dismissAll() //todo
|
||||
if(generalParams.regSdat > generalParams.regEdat){
|
||||
notyf.error("등록 종료일은 등록 시작일보다 빠를 수 없습니다.")
|
||||
return
|
||||
}
|
||||
|
||||
if(apprLine.value.length < 2){
|
||||
notyf.error("결재선은 두 명이상 입력해주세요.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const updatePriceOne = async () => {
|
||||
let res = null
|
||||
try{
|
||||
loading.value = true
|
||||
validation()
|
||||
const paramsPrice ={
|
||||
prcsNo : params.prcsNo,
|
||||
cateCd : params.cateSelect,
|
||||
title: generalParams.title,
|
||||
content: generalParams.content,
|
||||
regSdat: formatDate(generalParams.regSdat),
|
||||
regEdat: formatDate(generalParams.regEdat),
|
||||
prvYn: false,
|
||||
prvRsn : "",
|
||||
prvPwd : "",
|
||||
aiYn: false,
|
||||
prcsBizs: params.prcsBizs.map(({ num, ...rest }) => rest), //견적사 입력 데이터
|
||||
dtlSpecs: [], //todo
|
||||
// params.dtlSpecs.map(({ num, ...rest }) => rest), //상세 규격 입력 데이터
|
||||
prcsAtts: params.prcsAtts, //첨부파일 데이터
|
||||
apprReqs: apprLine.value.map(({ deptNm, ...rest }) => rest), //결재선 데이터
|
||||
}
|
||||
res = await updatePrice(paramsPrice)
|
||||
notyf.dismissAll()
|
||||
if(res.request.status == '200'){
|
||||
notyf.primary('수정 되었습니다.')
|
||||
router.push({path: '/app/priceManagement'})
|
||||
}
|
||||
}catch(e){
|
||||
notyf.error(e.message)
|
||||
}finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
const addNewEstimateRow = () => {
|
||||
const newRow = {}
|
||||
params.prcsBizsColumn.forEach(col => {
|
||||
if (col.key && col.key !== 'actions') {
|
||||
newRow[col.key] = ''
|
||||
}
|
||||
})
|
||||
params.prcsBizs.push(newRow)
|
||||
}
|
||||
|
||||
const onDelete = (index: number) => {
|
||||
|
||||
if(params.prcsBizs.length-1 !== params.prcsBizsColumn.length
|
||||
|| (params.prcsBizsColumn.length == 4 && params.prcsBizs.length-1 == params.prcsBizsColumn.length))
|
||||
{
|
||||
params.prcsBizs.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
const addNewDetailRow = () => {
|
||||
const newRow = {}
|
||||
params.dtlSpecsColumn.forEach(col => {
|
||||
if (col.key) {
|
||||
newRow[col.key] = ''
|
||||
}
|
||||
})
|
||||
params.dtlSpecs.push(newRow)
|
||||
console.log(params.dtlSpecs.length)
|
||||
}
|
||||
|
||||
const onDetailDelete = (index: number) => {
|
||||
|
||||
if(params.dtlSpecs.length-1 !== params.dtlSpecsColumn.length
|
||||
|| (params.dtlSpecsColumn.length == 8 && params.dtlSpecs.length-1 == params.dtlSpecsColumn.length))
|
||||
{
|
||||
params.dtlSpecs.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
function formatDate(dateStr) {
|
||||
if (!dateStr) return ''
|
||||
const date = new Date(dateStr)
|
||||
return date.toLocaleDateString('ko-KR', {
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
}).replace(/\./g, '-').replace(/\s/g, '').replace(/-$/,'')
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="page-content is-navbar-lg">
|
||||
<div class="datatable-wrapper">
|
||||
<div class="table-container">
|
||||
<table class="table datatable-table is-fullwidth">
|
||||
<colgroup>
|
||||
<col style="width: 10%;">
|
||||
<col style="width: 10%;">
|
||||
<col style="width: 10%;">
|
||||
<col style="width: 10%;">
|
||||
<col style="width: 10%;">
|
||||
<col style="width: 10%;">
|
||||
<col style="width: 10%;">
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>분야</td>
|
||||
<td colspan="2">
|
||||
<span class="column is-7">
|
||||
<VField class="pr-2">
|
||||
<VCodeSelect
|
||||
cd_grp=5
|
||||
v-model="params.cateSelect"/>
|
||||
</VField>
|
||||
</span>
|
||||
</td>
|
||||
<td>제목</td>
|
||||
<td colspan="3">
|
||||
<div class="column is-fullhd">
|
||||
<VField class="pr-2">
|
||||
<VControl>
|
||||
<input
|
||||
v-model="generalParams.title"
|
||||
class="input custom-text-filter"
|
||||
placeholder="제목"
|
||||
>
|
||||
</VControl>
|
||||
</VField>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>내용</td>
|
||||
<td colspan="6">
|
||||
<div class="column is-fullhd">
|
||||
<VField class="pr-2">
|
||||
<VControl>
|
||||
<textarea
|
||||
v-model="generalParams.content"
|
||||
class="input custom-text-filter"
|
||||
placeholder="내용"
|
||||
/>
|
||||
</VControl>
|
||||
</VField>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>규격입력</td>
|
||||
<td colspan="2">
|
||||
<VButton
|
||||
:color="params.btnChangeFlag? 'success':'primary'"
|
||||
icon="fas fa-plus"
|
||||
elevated
|
||||
@click="detailActionsOpen = true"
|
||||
>
|
||||
<span v-if="params.btnChangeFlag == false"> 상세 규격 입력</span>
|
||||
<span v-else-if="params.btnChangeFlag"> 상세 규격 등록 완료</span>
|
||||
</VButton>
|
||||
<VModal
|
||||
:open="detailActionsOpen"
|
||||
actions="center"
|
||||
title="상세 규격 입력"
|
||||
size="contract-big"
|
||||
@close="detailActionsOpen = false"
|
||||
>
|
||||
<template #content>
|
||||
<VButton color="success">일괄업로드</VButton>
|
||||
<ComVFlexTable
|
||||
:key="params.dtlSpecs.length"
|
||||
:data="params.dtlSpecs"
|
||||
:columns="params.dtlSpecsColumn"
|
||||
:separators="true"
|
||||
:clickable="true"
|
||||
>
|
||||
<template #body-cell="{ row, column, index, value }">
|
||||
<!-- 예: 특정 컬럼이면 input, 아니면 그냥 값 출력 -->
|
||||
<div>
|
||||
<input
|
||||
v-if="column.editable"
|
||||
v-model="row[column.key]"
|
||||
class="editable-input"
|
||||
/>
|
||||
<span v-else-if="column.key=='num'">{{index+1}}</span>
|
||||
<span v-else class="lnil lnil-close"
|
||||
@click="onDetailDelete(index)">{{ value }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</ComVFlexTable>
|
||||
<div class="mt-2">
|
||||
<VButton
|
||||
color="primary"
|
||||
icon="fas fa-plus"
|
||||
@click="addNewDetailRow"
|
||||
>
|
||||
행 추가
|
||||
</VButton>
|
||||
</div>
|
||||
</template>
|
||||
<template #action>
|
||||
<VButton color="primary" @click="changeButton">
|
||||
등록
|
||||
</VButton>
|
||||
</template>
|
||||
</VModal>
|
||||
</td>
|
||||
<td>등록기간</td>
|
||||
<td colspan="5">
|
||||
<div class="columns">
|
||||
<div class="column is-5">
|
||||
<VDatePicker
|
||||
v-model="generalParams.regSdat"
|
||||
color="green"
|
||||
trim-weeks
|
||||
>
|
||||
<template #default="{ inputValue, inputEvents }">
|
||||
<VField>
|
||||
<VControl icon="lucide:calendar">
|
||||
<input
|
||||
class="input v-input"
|
||||
type="text"
|
||||
:value="inputValue"
|
||||
v-on="inputEvents"
|
||||
placeholder="시작일"
|
||||
>
|
||||
</VControl>
|
||||
</VField>
|
||||
</template>
|
||||
</VDatePicker>
|
||||
</div>
|
||||
<div style="transform: translateY(15px)">~</div>
|
||||
<div class="column is-5">
|
||||
<VDatePicker
|
||||
v-model="generalParams.regEdat"
|
||||
color="green"
|
||||
trim-weeks
|
||||
disabledDates=""
|
||||
>
|
||||
<template #default="{ inputValue, inputEvents }">
|
||||
<VField>
|
||||
<VControl icon="lucide:calendar">
|
||||
<input
|
||||
class="input v-input"
|
||||
type="text"
|
||||
:value="inputValue"
|
||||
v-on="inputEvents"
|
||||
placeholder="종료일"
|
||||
>
|
||||
</VControl>
|
||||
</VField>
|
||||
</template>
|
||||
</VDatePicker>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>첨부파일</td>
|
||||
<td colspan="3">
|
||||
<VField class="file has-name is-right">
|
||||
<div class="file-label">
|
||||
<input
|
||||
class="file-input"
|
||||
type="file"
|
||||
name="resume">
|
||||
<span class="file-cta">
|
||||
<span class="file-icon">
|
||||
<i class="fas fa-cloud-upload-alt"/>
|
||||
</span>
|
||||
<span class="file-label">첨부파일</span>
|
||||
</span>
|
||||
<span class="file-name light-text">2022.xls</span>
|
||||
</div>
|
||||
</VField>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>견적요청</td>
|
||||
<td colspan="6">
|
||||
<VButton
|
||||
color="primary"
|
||||
icon="fas fa-plus"
|
||||
elevated
|
||||
@click="showTable = !showTable"
|
||||
>
|
||||
견적사 입력
|
||||
</VButton>
|
||||
<div v-if="showTable" class="mt-2">
|
||||
<ComVFlexTable
|
||||
:key="params.prcsBizs.length"
|
||||
:data="params.prcsBizs"
|
||||
:columns="params.prcsBizsColumn"
|
||||
:compact="true"
|
||||
:separators="true"
|
||||
:clickable="true"
|
||||
>
|
||||
<template #body-cell="{ row, column, index, value }">
|
||||
<div>
|
||||
<!-- 다른 editable 컬럼은 input -->
|
||||
<input
|
||||
v-if="column.editable"
|
||||
v-model="row[column.key]"
|
||||
class="editable-input"
|
||||
/>
|
||||
<span v-else-if="column.key=='num'">{{index + 1}}</span>
|
||||
<!-- readonly 출력 -->
|
||||
<span v-else class="lnil lnil-close"
|
||||
@click="onDelete(index)">{{ value }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</ComVFlexTable>
|
||||
<div class="mt-2">
|
||||
<VButton
|
||||
color="primary"
|
||||
icon="fas fa-plus"
|
||||
@click="addNewEstimateRow"
|
||||
>
|
||||
행 추가
|
||||
</VButton>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="column is-12">
|
||||
<VUser v-model="apprLine"/>
|
||||
</div>
|
||||
<div class="column is-12">
|
||||
<VField class="pr-2">
|
||||
<VLabel class="has-fullwidth">
|
||||
결재선
|
||||
</VLabel>
|
||||
</VField>
|
||||
<ComVFlexTable
|
||||
:data="apprLine"
|
||||
:columns="params.felxColumn"
|
||||
:separators="true"
|
||||
:clickable="true"
|
||||
:compact="true">
|
||||
<template #body-cell="{ row, column, index, value }">
|
||||
<!-- 예: 특정 컬럼이면 input, 아니면 그냥 값 출력 -->
|
||||
<div>
|
||||
<span v-if="column.key=='gubunCd'" class="column">
|
||||
<VField class="pr-1">
|
||||
<VCodeSelect
|
||||
cd_grp=7
|
||||
v-model="row.gubunCd"/>
|
||||
</VField>
|
||||
</span>
|
||||
<span v-else-if="column.key=='attendCd'" class="column">
|
||||
<VField class="pr-1">
|
||||
<VCodeSelect
|
||||
cd_grp=6
|
||||
v-model="row.attendCd"/>
|
||||
</VField>
|
||||
</span>
|
||||
<span v-else
|
||||
@click="onDetailDelete(index)">{{value}}</span>
|
||||
</div>
|
||||
</template>
|
||||
</ComVFlexTable>
|
||||
</div>
|
||||
<VButton
|
||||
color="primary"
|
||||
@click.stop="updatePriceOne"
|
||||
raised>
|
||||
수정
|
||||
</VButton>
|
||||
<VButton
|
||||
to="/app/priceManagement"
|
||||
v-if="params.stCd === '0000'"
|
||||
color="info"
|
||||
>
|
||||
닫기
|
||||
</VButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.table tbody td {
|
||||
color: var(--smoke-white);
|
||||
}
|
||||
|
||||
.datatable-table {
|
||||
padding: 12px 12px;
|
||||
|
||||
td:nth-child(1) {
|
||||
background-color: var(--primary);
|
||||
}
|
||||
td:nth-child(3) {
|
||||
background-color: var(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user