123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445 |
- <script setup>
- import apiDataEDB from '@/api/dataEDB'
- import {ref,reactive, computed,watch} from 'vue'
- import SelectEDB from './SelectEDB.vue'
- import SelectEDBClassify from '../../components/SelectEDBClassify.vue'
- import SelectEDBUnit from '../../components/SelectEDBUnit.vue'
- import SelectEDBFrequency from '../../components/SelectEDBFrequency.vue'
- import SelectDate from '@/components/SelectDate.vue'
- import { showToast } from 'vant'
- import { useRoute, useRouter } from 'vue-router'
- const route=useRoute()
- const router=useRouter()
- const props=defineProps({
- edbInfo:{
- type:Object,
- default:null
- }
- })
- watch(
- ()=>props.edbInfo,
- ()=>{
- if(route.query.type==='edit'){
- const edbInfoData=props.edbInfo.EdbInfoDetail
- if(edbInfoData.Source===24){//累计同比拼接
- tabActive.value=2
- }else{
- tabActive.value=1
- jointDate.value=edbInfoData.CalculateFormula
- }
- const temBeforeEDBInfo=props.edbInfo.CalculateList.find(item => item.FromTag === 'A')
- const temAfterEDBInfo=props.edbInfo.CalculateList.find(item => item.FromTag === 'B')
- beforeEDBInfo.value={
- EdbName:temBeforeEDBInfo.FromEdbName,
- EdbInfoId:temBeforeEDBInfo.FromEdbInfoId,
- EndDate:temBeforeEDBInfo.EndDate,
- StartDate:temBeforeEDBInfo.StartDate
- }
- afterEBDInfo.value={
- EdbName:temAfterEDBInfo.FromEdbName,
- EdbInfoId:temAfterEDBInfo.FromEdbInfoId,
- EndDate:temAfterEDBInfo.EndDate,
- StartDate:temAfterEDBInfo.StartDate
- }
-
- baseInfo.name=edbInfoData.EdbName
- baseInfo.unit=edbInfoData.Unit
- baseInfo.classify=edbInfoData.ClassifyId
- baseInfo.frequency=edbInfoData.Frequency
- setTimeout(() => {
- selectEDBClassifyINS.value?.getSelectClassifyOpt(props.edbInfo.EdbInfoDetail.ClassifyId)//获取选择的分类目录
- }, 1000);
- }
- }
- )
- //公式说明
- const tipsConfig=new Map([
- [1,`
- 直接拼接说明:<br>
- 1、选取拼接日期<br>
- 2、在拼接日期之前的数据选择指标A<br>
- 3、拼接日期之后的数据选择指标B<br>
- 4、新指标的起始日期为A的开始日期,更新时间跟随指标B进行更新<br>
- 5、指标A和B可以是原始指标,也可以是计算指标
- `],
- [2,`
- 累计值同比拼接说明:<br>
- 1、只支持月频度的指标进行累计值同比拼接<br>
- 2、如果出现有空值运算,则返回空值<br>
- 3、选取待拼接指标A和同比值指标B<br>
- 4、搜索到指标A最后一个12月31日有值的年份,并且向前回溯12个值(12个月),分别乘以下一年同期对应的同比增长率(B),公式为【A*(1+同期增长率(B)/100)】,得到下一年每个月的绝对值,再用新得到的下一年的12个月的值再乘以再下一年同期对应的同比增长率,得到再下一年每个月的绝对值<br>
- 5、以此类推,直到运算至指标B的最新值,得到新的序列C<br>
- 6、新指标是将序列C和指标A进行直接拼接,拼接日期选取指标A中有值的年份的年末最后一天即12月31日,再与序列C的起始日期做拼接<br>
- 7、新指标跟随指标B进行更新
- `],
- ])
- const showTips=ref(false)
- const tipsContent=computed(()=>{
- return tipsConfig.get(tabActive.value)
- })
- const tabsArr=ref([{ label: '直接拼接',key: 1 },{ label: '累计同比拼接',key: 2 }])
- const tabActive=ref(1)
- function handleTabChange(){
- jointDate.value=''
- beforeEDBInfo.value=null
- afterEBDInfo.value=null
- baseInfo.name=''
- baseInfo.unit=''
- baseInfo.classify=''
- baseInfo.frequency=''
- }
- //拼接日期
- const jointDate=ref('')
- const showSelectJointDate=ref(false)
- function handleConfirmJointDate(e){
- jointDate.value=e
- }
- // 选择指标
- const selectEDBSearchParams=ref({})
- const beforeEDBInfo=ref(null)
- const afterEBDInfo=ref(null)
- const showSelectEDB=ref(false)
- let currentSelectEDBType=''//当前是选择哪个指标
- function handleShowSelectEDB(type){
- currentSelectEDBType=type
- if(tabActive.value===2&&type==='before'){//累计同比值拼接选择待拼接指标搜索指标时Frequency传月度
- selectEDBSearchParams.value={Frequency:'月度'}
- }else{
- selectEDBSearchParams.value={}
- }
- showSelectEDB.value=true
- }
- function handleConfirmSelectEDB(e){
- if(currentSelectEDBType==='before'){
- beforeEDBInfo.value=e
- }else{
- afterEBDInfo.value=e
- }
- }
- // 基础信息
- const edbNameInputFocus=ref(false)
- const baseInfo=reactive({
- name:'',
- unit:'',
- classify:'',
- frequency:''
- })
- // 选择单位
- const showSelectUnit=ref(false)
- function onConfirmSelectUnit(value){
- baseInfo.unit=value
- }
- //选择分类
- const showSelectClassify=ref(false)
- const classifyStr=ref('')
- const selectEDBClassifyINS=ref(null)
- function handleConfirmClassify({value,selectedOptions}){
- baseInfo.classify=value
- classifyStr.value=`${selectedOptions[0].ClassifyName}/${selectedOptions[1].ClassifyName}/${selectedOptions[2].ClassifyName}`
- }
- //选择频度
- const showSelectFrequency=ref(false)
- function handleConfirmFrequency(value){
- baseInfo.frequency=value
- }
- // 提交计算
- const saveBtnLoading=ref(false)
- async function handleSave(){
- if(tabActive.value===1&&!jointDate.value){
- showToast('拼接日期不能为空')
- return
- }
- if(!beforeEDBInfo.value){
- showToast(tabActive.value===1?'指标不能为空':'待拼接指标不能为空')
- return
- }
- if(!afterEBDInfo.value){
- showToast(tabActive.value===1?'指标不能为空':'指标不能为空')
- return
- }
- if(!baseInfo.name){
- showToast('指标名称不能为空')
- return
- }
- if(!baseInfo.unit){
- showToast('指标单位不能为空')
- return
- }
- if(!baseInfo.classify){
- showToast('指标目录不能为空')
- return
- }
- if(!baseInfo.frequency){
- showToast('指标频度不能为空')
- return
- }
- const baseParams={
- ClassifyId:baseInfo.classify,
- EdbName:baseInfo.name,
- Frequency:baseInfo.frequency,
- Unit:baseInfo.unit,
- }
- const params=tabActive.value===1?{
- ...baseParams,
- EdbInfoIdArr:[
- {EdbInfoId:afterEBDInfo.value.EdbInfoId}
- ],
- Formula:jointDate.value,
- FromEdbInfoId:beforeEDBInfo.value.EdbInfoId,
- Source:23
- }:{
- ...baseParams,
- EdbInfoIdArr:[
- {EdbInfoId:afterEBDInfo.value.EdbInfoId}
- ],
- FromEdbInfoId:beforeEDBInfo.value.EdbInfoId,
- Source:24
- }
- saveBtnLoading.value=true
- const res=route.query.type==='edit'?await apiDataEDB.editCalculateEDB({...params,EdbInfoId:Number(route.query.edbInfoId)}) : await apiDataEDB.addCalculateEDB(params)
- saveBtnLoading.value=false
- if(res.Ret===200){
- showToast(route.query.type==='edit'?'编辑成功':'新增成功')
- setTimeout(() => {
- router.back()
- }, 1500);
- }
- }
- </script>
- <template>
- <div class="joint-calculate-wrap">
- <van-tabs
- v-model:active="tabActive"
- sticky
- border
- title-active-color="#0052D9"
- title-inactive-color="#333"
- line-width="16px"
- @change="handleTabChange"
- v-if="$route.query.type!=='edit'"
- >
- <van-tab
- :title="tab.label"
- :name="tab.key"
- v-for="tab in tabsArr"
- :key="tab.key"
- />
- </van-tabs>
- <section class="section select-edb-box">
- <van-field
- :modelValue="jointDate"
- readonly
- label="拼接日期"
- placeholder="请选择日期"
- input-align="right"
- right-icon="arrow"
- required
- @click-input="showSelectJointDate=true"
- v-if="tabActive===1"
- />
- <van-field
- label-width="7em"
- :label="tabActive===1?'拼接日期之前':'待拼接指标'"
- required
- right-icon="arrow"
- @click-input="handleShowSelectEDB('before')"
- >
- <template #input>
- <div class="edb-info-box">
- <div class="edb-info" v-if="beforeEDBInfo">
- <span class="name">{{beforeEDBInfo.EdbName}}</span>
- <span class="time" v-if="tabActive===1">(起始日期:{{beforeEDBInfo.StartDate}})</span>
- <span class="time" v-if="tabActive===2">(截至日期:{{beforeEDBInfo.EndDate}})</span>
- </div>
- <span class="placeholder" v-else>请选择指标</span>
- </div>
- </template>
- </van-field>
- <van-field
- label-width="7em"
- :label="tabActive===1?'拼接日期之后':'同比值指标'"
- right-icon="arrow"
- required
- @click-input="handleShowSelectEDB('after')"
- >
- <template #input>
- <div class="edb-info-box">
- <div class="edb-info" v-if="afterEBDInfo">
- <span class="name">{{afterEBDInfo.EdbName}}</span>
- <span class="time" v-if="tabActive===1">(最新日期:{{afterEBDInfo.EndDate}})</span>
- </div>
- <span class="placeholder" v-else>请选择指标</span>
- </div>
- </template>
- </van-field>
- </section>
- <section class="section baseinfo-box">
- <van-field
- v-model="baseInfo.name"
- label="指标名称"
- placeholder="指标名称"
- input-align="right"
- required
- @focus="edbNameInputFocus=true"
- @blur="edbNameInputFocus=false"
- >
- <template #right-icon>
- <svg-icon class="edit-icon" name="edit" :color="edbNameInputFocus?'#0052D9':'#333333'"/>
- </template>
- </van-field>
- <van-field
- :modelValue="baseInfo.unit"
- readonly
- label="单位"
- placeholder="请选择单位"
- input-align="right"
- right-icon="arrow"
- required
- @click-input="showSelectUnit=true"
- />
- <van-field
- :modelValue="classifyStr"
- readonly
- label="指标目录"
- placeholder="请选择指标目录"
- input-align="right"
- right-icon="arrow"
- required
- @click-input="showSelectClassify=true"
- />
- <van-field
- :modelValue="baseInfo.frequency"
- readonly
- label="频度"
- placeholder="请选择指标频度"
- input-align="right"
- right-icon="arrow"
- required
- @click-input="showSelectFrequency=true"
- />
- </section>
- <div class="formula-intro-btn" @click="showTips=true">
- <svg-icon class="icon" name="warning"></svg-icon>
- <span>公式说明</span>
- </div>
- <div class="opt-btns">
- <van-button class="primary2" @click="$router.back()">取消</van-button>
- <van-button
- type="primary"
- :loading="saveBtnLoading"
- loading-text="计算中..."
- @click="handleSave"
- >保存</van-button>
- </div>
- </div>
- <!-- 选择拼接日期 -->
- <SelectDate v-model:show="showSelectJointDate" @select="handleConfirmJointDate"/>
- <!-- 选择指标 -->
- <SelectEDB v-model:show="showSelectEDB" :params="selectEDBSearchParams" @select="handleConfirmSelectEDB"/>
- <!-- 选择单位 -->
- <SelectEDBUnit v-model:show="showSelectUnit" @select="onConfirmSelectUnit"/>
- <!-- 选择分类 -->
- <SelectEDBClassify ref="selectEDBClassifyINS" :defaultId="baseInfo.classify" v-model:show="showSelectClassify" @select="handleConfirmClassify" />
- <!-- 选择频度 -->
- <SelectEDBFrequency v-model:show="showSelectFrequency" @select="handleConfirmFrequency"/>
- <!-- 公式说明 -->
- <van-dialog
- v-model:show="showTips"
- :title="$route.query.name"
- confirmButtonText='知道啦'
- >
- <div class="edb-formula-tips-html-box" v-html="tipsContent"></div>
- </van-dialog>
- </template>
- <style lang="scss" scoped>
- .joint-calculate-wrap{
- min-height: 90vh;
- background-color: $page-bg-grey;
- padding-bottom: 210px ;
- }
- .section{
- background-color: #fff;
- margin-bottom: 32px;
- }
- .select-edb-box{
- :deep(.van-cell__right-icon){
- align-self: center;
- color: #333;
- }
- .edb-info-box{
- width: 100%;
- text-align: right;
- .placeholder{
- color: var(--van-text-color-3);
- }
- .edb-info{
- display: flex;
- flex-direction: column;
- }
- .time{
- color: $font-grey_999;
- font-size: 24px;
- }
- }
- }
- .formula-intro-btn{
- width: 180px;
- height: 60px;
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 5px;
- color: $theme-color;
- line-height: 1;
- background-color: #fff;
- border-radius: 32px;
- margin-left: auto;
- margin-right: var(--van-cell-horizontal-padding);
- .icon{
- width: 24px;
- height: 24px;
- }
- }
- .opt-btns{
- position: fixed;
- left: 0;
- right: 0;
- bottom: 0;
- background-color: #fff;
- z-index: 99;
- padding: 48px;
- display: flex;
- justify-content: space-between;
- .van-button{
- width: 48%;
- }
- }
- </style>
|