Browse Source

表格和按钮样式调整

apply^2
Min5203 4 years ago
parent
commit
d1a77ea0dc
  1. 17
      apis/finance.js
  2. 8
      apis/ocr.js
  3. 168
      components/Expenditure.vue
  4. 29
      components/FinanceExamine.vue
  5. 4
      components/FinanceManage.vue
  6. 19
      components/HistoricalApplication.vue
  7. 285
      components/RingEcharts.vue
  8. 179
      pages/Initiate-application.vue
  9. 8
      pages/applicant.vue
  10. 13
      pages/application-details.vue
  11. 276
      pages/financial-approval-details.vue
  12. 25
      pages/financial-approval.vue
  13. 128
      pages/index.vue
  14. 4
      plugins/vant.js

17
apis/finance.js

@ -11,13 +11,26 @@ export const apply = params => http.post(`${finance}/apply`, params);
export const audit = params => http.post(`${finance}/audit`, params); export const audit = params => http.post(`${finance}/audit`, params);
// 查询申请详情 // 查询申请详情
export const getApplyDetail = params => http.post(`${finance}/getApplyDetail`, params); export const getApplyDetail = params =>
http.post(`${finance}/getApplyDetail`, params);
// 通过任务id查看任务关联的财务信息 // 通过任务id查看任务关联的财务信息
export const getByTask = params => http.post(`${finance}/getByTask`, params); export const getByTask = params => http.post(`${finance}/getByTask`, params);
// 查看当前用户的费用申请历史信息(奖金) // 查看当前用户的费用申请历史信息(奖金)
export const personalHistory = params => http.post(`${finance}/personalHistory`, params); export const personalHistory = params =>
http.post(`${finance}/personalHistory`, params);
// 查询费用申请类型 // 查询费用申请类型
export const queryType = params => http.post(`${finance}/queryType`, params); export const queryType = params => http.post(`${finance}/queryType`, params);
// 任务支出统计
export const taskExpense = params =>
http.post(`${finance}/taskExpense`, params);
// 名目支出统计
export const rowExpense = params => http.post(`${finance}/rowExpense`, params);
// 成员财务统计
export const memberFinance = params =>
http.post(`${finance}/memberFinance`, params);

8
apis/ocr.js

@ -0,0 +1,8 @@
import http from 'apis/axios';
const apiUrl = import.meta.env.VITE_API_URL;
const ptccsens = `${apiUrl}/ptccsens/v1.0`;
const ocr = `${ptccsens}/ocr`;
// 发起申请
export const bill = `${ocr}/bill`;

168
components/Expenditure.vue

@ -0,0 +1,168 @@
<template>
<div v-if="data.info.length">
<div class="w-full overflow-x-scroll">
<table class="text-gray-500 mt-4 text-xs" v-if="props.id === 'taskTable'">
<tr class="bg-gray-100">
<td width="20%">任务名称</td>
<td width="16%">支出</td>
<td width="16%">占比</td>
<td width="16%">追加</td>
<td width="16%">操作</td>
</tr>
<tr v-for="item in data.info">
<td>{{ item.taskName }}</td>
<td>{{ item.money }}</td>
<td>{{ item.percentage }}%</td>
<td>
<div v-if="!item.showField" @click="item.showField = true">
{{ item.budget - 0 }}
</div>
<van-field
v-else-if="financeId - 0 !== 0 && item.showField"
v-model="item.budget"
type="number"
class="input-box"
@change="handleUpdateBudget(item)"
@blur="item.showField = false"
/>
</td>
<td>
<van-icon name="plus" @click="toApplication" />
</td>
</tr>
</table>
<table class="text-gray-500 mt-4 text-xs" v-if="props.id === 'nameTable'">
<tr class="bg-gray-100">
<td width="15%">任务名称</td>
<td width="16%">预算()</td>
<td width="16%">占比()</td>
</tr>
<tr v-for="item in data.info">
<td>{{ item.rowName }}</td>
<td>{{ item.percentage }}</td>
<td>{{ item.money }}</td>
</tr>
</table>
</div>
<div class="w-1/2 mt-4 ml-48">
<van-pagination
v-model="data.pageNum"
:items-per-page="data.pageSize"
:page-count="data.pages"
mode="simple"
/>
</div>
</div>
<van-empty v-else description="暂无数据" />
<van-dialog
v-model:show="data.show"
title="追加预算"
show-cancel-button
@confirm="handleAdd"
>
<van-field
:border="data.border"
v-model="data.appendBudget"
type="textarea"
class="appendBudget"
placeholder="追加预算"
/>
</van-dialog>
</template>
<script setup>
import { ref, reactive, onMounted, nextTick } from 'vue';
import { taskExpense, rowExpense } from 'apis/finance';
import { addBudget } from 'apis/projectFinance';
const projectId = useProjectId();
const router = useRouter();
const props = defineProps({
id: { type: Object, default: () => {} },
});
console.log('props.id: ', props.id);
const data = reactive({
info: [],
pageNum: 1,
pageSize: 10,
pages: 0,
show: false,
appendBudget: '',
auditInfo: {},
border: true,
});
//
async function handleUpdateBudget(item) {
try {
const params = {
param: {
appendBudget: item.budget - 0,
financeId: item.financeId,
projectId: projectId.value,
},
};
await addBudget(params);
} catch (error) {
console.error('error: ', error);
}
}
// ,
function toApplication() {
const routeValue = router.currentRoute.value;
const query = routeValue.query;
router.push({ path: '/Initiate-application', query });
}
// echarts()
async function getTaskExpense() {
const params = { param: { projectId: projectId.value } };
const res = await taskExpense(params);
for (let i = 0; i < res.length; i++) {
res.showField = false;
}
data.info = res;
}
// echarts()
async function getRowExpense() {
const params = { param: { projectId: projectId.value } };
const res = await rowExpense(params);
data.info = res;
}
function setData() {
if (props.id === 'taskTable') {
getTaskExpense();
} else if (props.id === 'nameTable') {
getRowExpense();
}
}
onMounted(() => {
nextTick(() => {
// handleFinanceOfProject();
setData();
});
});
</script>
<style scoped lang="less">
table {
width: 120%;
td {
border: 0.5px solid #ccc;
padding: 0.5rem;
}
}
.input-box {
padding: 0 !important;
border-bottom: 1px solid #ccc;
}
.appendBudget {
border: 1px solid #ccc;
border-radius: 4px;
margin: 5%;
width: 90%;
}
</style>

29
components/FinanceExamine.vue

@ -1,19 +1,19 @@
<template> <template>
<div v-if="data.info.list && data.info.list.length"> <div v-if="data.info.list && data.info.list.length">
<div class="w-full overflow-x-scroll"> <div class="w-full overflow-x-scroll">
<table class="text-gray-500 mt-4 text-xs"> <table class="text-gray-500 mt-4">
<tr class="bg-gray-100"> <tr class="bg-gray-100">
<td width="15%">申请人</td> <td width="20%">申请人</td>
<td width="16%">金额()</td> <td width="25%">金额()</td>
<td width="20%">时间</td> <td width="30%">时间</td>
<td width="10%">操作</td> <td width="25%">操作</td>
</tr> </tr>
<tr v-for="item in data.info.list"> <tr v-for="item in data.info.list">
<td>{{item.submitName}}</td> <td @click="openDetails(item.applyId)">{{item.submitName}}</td>
<td>{{item.money}}</td> <td @click="openDetails(item.applyId)">{{item.money}}</td>
<td>{{dayjs(item.submitTime - 0).format('YYYY-MM-DD')}}</td> <td @click="openDetails(item.applyId)">{{dayjs(item.submitTime - 0).format('YYYY-MM-DD')}}</td>
<td> <td>
<div v-if="!item.applyType" class="flex flex-row justify-between"> <div v-if="!item.applyType" class="flex flex-row justify-around">
<van-button type="success" size="mini" class="rounded" @click="showRemark(item.financeCheckId, 1)">通过</van-button> <van-button type="success" size="mini" class="rounded" @click="showRemark(item.financeCheckId, 1)">通过</van-button>
<van-button type="danger" size="mini" class="rounded" @click="showRemark(item.financeCheckId, 2)">驳回</van-button> <van-button type="danger" size="mini" class="rounded" @click="showRemark(item.financeCheckId, 2)">驳回</van-button>
@ -40,6 +40,9 @@ import {ref, reactive, onMounted, nextTick} from'vue';
import { audit } from 'apis/finance'; import { audit } from 'apis/finance';
import { queryNeedCheckByMe } from 'apis/projectFinance'; import { queryNeedCheckByMe } from 'apis/projectFinance';
import { Toast } from 'vant'; import { Toast } from 'vant';
import { useRouter } from 'vue-router';
const router = useRouter()
const data = reactive({ const data = reactive({
info: {}, info: {},
@ -116,6 +119,14 @@ async function handleAudit(financeCheckId, checkStatus){
console.error('error: ', error); console.error('error: ', error);
} }
} }
//
function openDetails(applyId){
const routeValue = router.currentRoute.value;
const query = routeValue.query;
query.applyId = applyId;
router.push({ path: '/financial-approval-details', query });
}
</script> </script>
<style scoped lang="less"> <style scoped lang="less">

4
components/FinanceManage.vue

@ -4,8 +4,8 @@
<table class="w-full text-gray-500 mt-4 text-ms"> <table class="w-full text-gray-500 mt-4 text-ms">
<tr class="bg-gray-100"> <tr class="bg-gray-100">
<td class="name">任务名称</td> <td class="name">任务名称</td>
<td class="">预算()</td> <td>预算()</td>
<td class="">奖金()</td> <td>奖金()</td>
</tr> </tr>
<tr v-for="item in data.info.taskFinanceList.list"> <tr v-for="item in data.info.taskFinanceList.list">
<td>{{item.name}}</td> <td>{{item.name}}</td>

19
components/HistoricalApplication.vue

@ -12,8 +12,8 @@
<td class="status">状态</td> <td class="status">状态</td>
</tr> </tr>
<tr v-for="item in data.info.list" class="text-gray-500"> <tr v-for="item in data.info.list" class="text-gray-500">
<td>{{ item.submitName }}</td> <td @click="openDetails(item.applyId)">{{ item.submitName }}</td>
<td> <td @click="openDetails(item.applyId)">
<!-- v-if="!item.showBudgetEdit" --> <!-- v-if="!item.showBudgetEdit" -->
{{ (+item.money / 100).toFixed(2) }} {{ (+item.money / 100).toFixed(2) }}
<!-- <van-field <!-- <van-field
@ -25,7 +25,7 @@
@blur="item.showBudgetEdit = false" @blur="item.showBudgetEdit = false"
/> --> /> -->
</td> </td>
<td> <td @click="openDetails(item.applyId)">
{{ dayjs(item.submitTime - 0).format('YYYY/MM/DD') }} {{ dayjs(item.submitTime - 0).format('YYYY/MM/DD') }}
</td> </td>
<td> <td>
@ -74,6 +74,9 @@
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { personalHistory } from 'apis/finance'; import { personalHistory } from 'apis/finance';
import { ref, reactive, onMounted, nextTick } from 'vue'; import { ref, reactive, onMounted, nextTick } from 'vue';
import { useRouter } from 'vue-router';
const router = useRouter();
const data = reactive({ const data = reactive({
info: {}, info: {},
@ -124,6 +127,14 @@ onMounted(() => {
handlePersonalHistory(); handlePersonalHistory();
}); });
}); });
//
function openDetails(applyId){
const routeValue = router.currentRoute.value;
const query = routeValue.query;
query.applyId = applyId;
router.push({ path: '/application-details', query });
}
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
@ -141,7 +152,7 @@ table {
width: 100px; width: 100px;
} }
.time { .time {
width: 170px; width: 120px;
} }
.status { .status {
width: 120px; width: 120px;

285
components/RingEcharts.vue

@ -1,141 +1,198 @@
<template> <template>
<!-- <div id="yield-chart"></div> --> <!-- <div id="yield-chart"></div> -->
<div :id="props.id" style="width:400px;height:260px"></div> <div :id="props.id" style="width: 400px; height: 260px"></div>
</template> </template>
<script setup> <script setup>
import { onMounted} from 'vue'; import { onMounted } from 'vue';
import { taskExpense, rowExpense, memberFinance } from 'apis/finance';
const projectId = useProjectId();
const props = defineProps({ id: { type: String, default: () => {} } }); const props = defineProps({ id: { type: String, default: () => {} } });
onMounted(()=>{ let oData = [
if(props.id){ {
var myChart = echarts.init(document.getElementById(props.id)); name: '办公费',
value: 36,
rate: 12,
},
{
name: '车辆费用',
value: 20,
rate: 20,
},
{
name: '差旅费33',
value: 15,
rate: -40,
},
{
name: '租赁费',
value: 10,
rate: -15,
},
{
name: '其他',
value: 9,
rate: 12,
},
];
// echarts()
async function getTaskExpense() {
const params = { param: { projectId: projectId.value } };
const res = await taskExpense(params);
return changeData(res, 'taskName');
}
// echarts()
async function getRowExpense() {
const params = { param: { projectId: projectId.value } };
const res = await rowExpense(params);
return changeData(res, 'rowName');
}
// echarts()
async function getMemberFinance() {
const params = { param: { projectId: projectId.value } };
const res = await memberFinance(params);
return changeData(res, 'memberName');
}
// optionData
function changeData(list, name) {
let optionsData = [];
for (let i = 0; i < list.length; i++) {
const data = {
name: list[i][name],
value: list[i].money - 0,
percentage: list[i].percentage,
};
optionsData.push(data);
} }
const data = [ return optionsData;
{ }
name: '办公费', function setData() {
value: 36, if (props.id === 'taskEcharts') {
}, return getTaskExpense();
{ } else if (props.id === 'nameEcharts') {
name: '车辆费用', return getRowExpense();
value: 20, } else if (props.id === 'memberEcharts') {
}, return getMemberFinance();
{ } else {
name: '差旅费', return oData;
value: 15, }
}, }
{
name: '租赁费', function getTitleNum(list) {
value: 10, let num = 0;
}, for (let i = 0; i < list.length; i++) {
{ num += list[i].value;
name: '其他', }
value: 9, return num;
}, }
]; onMounted(async () => {
if (props.id) {
var myChart = echarts.init(document.getElementById(props.id));
}
const data = await setData();
const title = getTitleNum(data);
const option = { const option = {
title: { title: {
text: 100, text: title,
textStyle:{ textStyle: {
fontSize:17, fontSize: 17,
color:"black" color: 'black',
}, },
textAlign:"center", textAlign: 'center',
x: '24%', x: '24%',
y: '35%', y: '35%',
}, },
legend: { legend: {
type: 'plain', type: 'plain',
icon: 'circle', icon: 'circle',
orient: 'vertical', orient: 'vertical',
left: '55%', left: '55%',
top: '15%', top: '15%',
align: 'left', align: 'left',
itemGap: 15, itemGap: 15,
itemWidth: 10, // itemWidth: 10, //
itemHeight: 10, // itemHeight: 10, //
symbolKeepAspect: false, symbolKeepAspect: false,
textStyle: { textStyle: {
color: '#000', color: '#000',
rich: { rich: {
name: { name: {
verticalAlign: 'right', verticalAlign: 'right',
align: 'left', align: 'left',
width: 50, width: 50,
fontSize: 12 fontSize: 12,
}, },
value: { value: {
align: 'left', align: 'left',
width: 40, width: 40,
fontSize: 12 fontSize: 12,
}, },
count: { count: {
align: 'left', align: 'left',
width: 80, width: 80,
fontSize: 12 fontSize: 12,
}, },
}
}, },
data: data.map(item => item.name), },
formatter: function(name) { data: data.map(item => item.name),
if (data && data.length) { formatter: function (name) {
for (var i = 0; i < data.length; i++) { if (data && data.length) {
if (name === data[i].name) { for (var i = 0; i < data.length; i++) {
return ( if (name === data[i].name) {
'{name| ' + return (
name + '{name| ' +
'} | ' + name +
'{value| ' + '} | ' +
data[i].value + '{value| ' +
'%}' + data[i].percentage +
'{count| ' + '%}' +
data[i].value + '{count| ' +
'} ' data[i].value +
) '} '
} );
}
} }
}
} }
},
}, },
series: [{ series: [
{
name: '数量', name: '数量',
type: 'pie', type: 'pie',
radius: ['40%', '55%'], radius: ['40%', '55%'],
center: ['25%', '40%'], center: ['25%', '40%'],
data: data, data: data,
label: { label: {
normal: { normal: {
show: false, show: false,
position: 'center', position: 'center',
formatter: '{text|{c}}\n{b}', formatter: '{text|{c}}\n{b}',
rich: { rich: {
text: { text: {
align: 'center', align: 'center',
verticalAlign: 'middle', verticalAlign: 'middle',
padding: 8, padding: 8,
fontSize: 30 fontSize: 30,
}, },
value: { value: {
align: 'center', align: 'center',
verticalAlign: 'middle', verticalAlign: 'middle',
fontSize: 20 fontSize: 20,
} },
}
}, },
},
}, },
labelLine: { labelLine: {
normal: { normal: {
show: true show: true,
} },
} },
}] },
}; ],
myChart.setOption(option); };
myChart.setOption(option);
}) });
</script> </script>
<style scoped> <style scoped></style>
</style>

179
pages/Initiate-application.vue

@ -20,20 +20,26 @@
>手动输入</van-button >手动输入</van-button
> >
</div> </div>
<div <!-- <van-overlay :show="data.showUploading"> -->
class="text-center border-b w-52 h-24 bg-gray-100 border-dashed border-2" <div
@click="uploadBill" class="text-center border-b w-52 h-24 border-dashed border-2 upload-box"
v-show="!data.isSuccess" v-show="!data.isSuccess"
> >
<p class="text-gray-400 text-xl pt-3">+</p> <van-uploader v-model="data.fileList" multiple :max-count="1" :after-read="afterRead" class="z-50 opacity-0" />
<p class="text-gray-400 text-xs">上传并识别凭证</p> <div class="upload-txt">
</div> <p class="text-gray-400 text-xl pt-3">+</p>
<p class="text-gray-400 text-xs">上传并识别凭证</p>
</div>
<!-- <van-loading type="spinner" v-if="data.showUploading" class="upload-txt z-50" /> -->
</div>
<!-- </van-overlay> -->
<!-- 上传票据成功后显示发票信息 --> <!-- 上传票据成功后显示发票信息 -->
<div v-show="data.isSuccess"> <div v-show="data.isSuccess">
<van-field <van-field
v-for="item in data.invoiceInfo" v-for="item in data.invoiceInfo"
required required
v-model="item.values" v-model="item.value"
:label="item.name" :label="item.name"
@change="cahngeInvoiceList($event, item)" @change="cahngeInvoiceList($event, item)"
input-align="right" input-align="right"
@ -45,7 +51,7 @@
<div v-show="!data.isInvoice"> <div v-show="!data.isInvoice">
<van-field <van-field
required required
v-model="data.applyMoney" v-model="data.money"
label="申请金额" label="申请金额"
placeholder="输入申请金额" placeholder="输入申请金额"
input-align="right" input-align="right"
@ -78,13 +84,13 @@
class="button" class="button"
size="mini" size="mini"
v-for="item in data.reviewerList" v-for="item in data.reviewerList"
:key="item.userId" :key="item.memberId"
:type=" :type="
data.checkerList.find(checker => checker === item.userId) data.checkerList.find(checker => checker === item.memberId)
? 'primary' ? 'primary'
: 'default' : 'default'
" "
@click="handleSelectChecker(item.userId)" @click="handleSelectChecker(item.memberId)"
> >
{{ item.name }} {{ item.name }}
</van-button> </van-button>
@ -96,7 +102,7 @@
<div class="text-gray-500 p-4 font-semibold">其他信息</div> <div class="text-gray-500 p-4 font-semibold">其他信息</div>
<!-- 申请类型 --> <!-- 申请类型 -->
<!-- 普通票据申请 --> <!-- 普通票据申请 -->
<div v-show="data.isInvoice"> <div>
<van-field <van-field
v-model="data.applyType" v-model="data.applyType"
is-link is-link
@ -110,9 +116,11 @@
<van-popup v-model:show="data.showType" round position="bottom"> <van-popup v-model:show="data.showType" round position="bottom">
<van-picker <van-picker
title="申请类型" title="申请类型"
v-if="data.applyTypeOptions && data.applyTypeOptions.length"
:columns="data.applyTypeOptions" :columns="data.applyTypeOptions"
@confirm="finishApplyType" @confirm="finishApplyType"
/> />
<van-loading v-else class="my-20 text-center" />
</van-popup> </van-popup>
<!-- 所属项目 --> <!-- 所属项目 -->
<van-field <van-field
@ -131,6 +139,7 @@
<!-- 所属任务的 --> <!-- 所属任务的 -->
<van-field <van-field
v-model="data.taskName" v-model="data.taskName"
v-show="data.isInvoice"
is-link is-link
readonly readonly
label="所属任务" label="所属任务"
@ -155,13 +164,16 @@
<van-popup v-model:show="data.showCategory" round position="bottom"> <van-popup v-model:show="data.showCategory" round position="bottom">
<van-picker <van-picker
title="请选择类目" title="请选择类目"
v-if="data.applyCategoryOptions && data.applyCategoryOptions.length"
:columns="data.applyCategoryOptions" :columns="data.applyCategoryOptions"
@confirm="finishApplyCategory" @confirm="finishApplyCategory"
/> />
<van-loading v-else class="my-20 text-center" />
</van-popup> </van-popup>
<!-- 名目选择 --> <!-- 名目选择 -->
<van-field <van-field
v-model="data.applyName" v-model="data.applyName"
v-show="data.isInvoice"
is-link is-link
readonly readonly
label="名目" label="名目"
@ -172,28 +184,13 @@
<van-popup v-model:show="data.showName" round position="bottom"> <van-popup v-model:show="data.showName" round position="bottom">
<van-picker <van-picker
title="请选择名目" title="请选择名目"
v-if="data.applyNameOptions && data.applyNameOptions.length"
:columns="data.applyNameOptions" :columns="data.applyNameOptions"
@confirm="finishApplyName" @confirm="finishApplyName"
/> />
<van-loading v-else class="my-20 text-center" />
</van-popup> </van-popup>
</div> </div>
<!-- 个人手动申请 -->
<div v-show="!data.isInvoice">
<div class="pl-2">
<van-cell
title="单元格"
is-link
:value="data.personalType"
required
/>
<van-cell
title="单元格"
is-link
:value="data.personalCategory"
required
/>
</div>
</div>
</div> </div>
<!-- 提交人信息 --> <!-- 提交人信息 -->
<div class="bg-white mt-3"> <div class="bg-white mt-3">
@ -219,58 +216,62 @@
<div class="text-gray-500 font-semibold">历史申请</div> <div class="text-gray-500 font-semibold">历史申请</div>
<div> <div>
<Search /> <Search />
<FinanceExamine /> <HistoricalApplication />
</div> </div>
</div> </div>
<!-- 底部立即提交按钮 --> <!-- 底部立即提交按钮 -->
<div class="mx-6 mt-10"> <div class="mx-6 mt-10">
<van-button type="primary" size="small" block>立即提交</van-button> <van-button @click="submit" type="primary" size="small" block>立即提交</van-button>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import axios from 'axios';
import { ref, reactive } from 'vue'; import { ref, reactive } from 'vue';
// import useApplication from 'hooks/useApplication';
import { queryChecker } from 'apis/member'; import { queryChecker } from 'apis/member';
import { queryType } from 'apis/finance'; import { queryType, apply } from 'apis/finance';
import { bill } from 'apis/ocr';
// const getApplication = useApplication(); import { Toast } from 'vant';
const token = useToken()
const projectName = useProjectName(); const projectName = useProjectName();
const taskName = useTaskName(); const taskName = useTaskName();
const projectId = useProjectId(); const projectId = useProjectId();
const taskDetailId = useTaskId();
const data = reactive({ const data = reactive({
isInvoice: true, isInvoice: true,
fileList: [],
showUploading: false,
remark: '', remark: '',
invoiceList: [], invoiceList: [],
invoiceInfo: [ invoiceInfo: [
{ {
name: '发票代码', name: '发票代码',
values: 0, value: 0,
label: 'invoiceCode', label: 'invoiceCode',
}, },
{ {
name: '发票号码', name: '发票号码',
values: 1, value: 0,
label: 'invoiceNumber', label: 'invoiceNumber',
}, },
{ {
name: '合计金额(元)', name: '合计金额(元)',
values: 2, value: 0,
label: 'money', label: 'money',
}, },
{ {
name: '税额(元)', name: '税额(元)',
values: 3, value: 0,
label: 'taxMoney', label: 'taxMoney',
}, },
{ {
name: '开票日期', name: '开票日期',
values: 4, value: 0,
label: 'invoiceTime', label: 'invoiceTime',
}, },
{ {
name: '发票备注信息', name: '备注信息',
values: 5, value: '无',
label: 'remark', label: 'remark',
}, },
], ],
@ -284,6 +285,7 @@ const data = reactive({
currentPage: 0, // currentPage: 0, //
personalType: '个人申请', // personalType: '个人申请', //
personalCategory: '用款', personalCategory: '用款',
money: '',
// //
showType: false, // showType: false, //
applyTypes: [], applyTypes: [],
@ -302,9 +304,64 @@ const data = reactive({
rowId: '', rowId: '',
}); });
//
function upLoaderImg(file, url) { //file
//new FormData
let params = new FormData()
params.append('part', file)
let config = {
headers: { //
'Content-Type': 'multipart/form-data',
Authorization: 'Bearer ' + token.value
}
}
return new Promise((resolve, reject) => {
// uploadUrl
axios.post(`${bill}`, params, config).then(res => {
resolve(res)
}).catch(err => {
reject(err)
});
})
}
//
async function afterRead(file){
data.showUploading = true
//
upLoaderImg(file.file, 'upload').then(res => {
data.showUploading = false
if (res.data.code == 200) {
for(let key in res.data.data){
data.invoiceInfo.forEach(item => {
if(item.label === key){
if(item.label === 'money' || item.label === 'taxMoney'){
item.value = (+res.data.data[key] / 100).toFixed(2)
}else{
item.value = res.data.data[key]
}
}
})
}
console.log('data.invoiceInfo: ', data.invoiceInfo);
data.invoiceList.push(res.data.data)
data.titleHidden = false;
data.isSuccess = true;
} else {
Toast.fail(res.data.msg || '上传失败')
}
})
}
// //
function cahngeInvoiceList(e, item) { function cahngeInvoiceList(e, item) {
console.log('e: ', e.target.value, item); console.log('e: ', e.target.value, item);
data.invoiceList.forEach(invoice => {
for(let key in data.invoiceList){
if(item.label === key){
invoice[key] = item.value
}
}
})
} }
// //
@ -345,15 +402,6 @@ function handleSelectChecker(id) {
} }
} }
//
function uploadBill() {
//TODO:
setTimeout(() => {
data.titleHidden = false;
data.isSuccess = true;
}, 1000);
}
/** /**
* 查询所有成员 * 查询所有成员
* @param { String } projectId * @param { String } projectId
@ -378,7 +426,6 @@ async function handleQueryChecker() {
* @param { Number } type 类型0申请类型 1类目 2名目 * @param { Number } type 类型0申请类型 1类目 2名目
*/ */
async function handleQueryType(parentId, type) { async function handleQueryType(parentId, type) {
console.log('parentId: ', parentId);
try { try {
const params = { const params = {
param: { param: {
@ -421,7 +468,7 @@ onMounted(() => {
* 发起申请 * 发起申请
* @param { Object } params * @param { Object } params
*/ */
async function submit(params) { async function submit() {
try { try {
if(!verification()) return if(!verification()) return
const params = {} const params = {}
@ -435,7 +482,8 @@ async function submit(params) {
} }
// //
function verification(){ function verification(){
const { isSuccess, categoryId, checkerList, department, money, rowId, submitName, typeId, isInvoice } = data const { isSuccess, invoiceInfo, categoryId, checkerList, department, money, rowId, submitName, typeId, isInvoice } = data
//
if(!isSuccess && isInvoice){ if(!isSuccess && isInvoice){
Toast.fail('请上传票据凭证'); Toast.fail('请上传票据凭证');
return return
@ -473,18 +521,14 @@ function verification(){
// //
function setParams(){ function setParams(){
const { remark, money, categoryId, checkerList, department, rowId, submitName, typeId, invoiceInfo, isInvoice } = data const { remark, money, categoryId, checkerList, department, rowId, submitName, typeId, invoiceInfo, isInvoice, invoiceList } = data
let param = {} let param = {}
let invoiceList = []
let list = {url: 'https://cdn.nlark.com/yuque/0/2022/png/413990/1642482454748-931b2e93-8964-492b-b06b-b8db42733c02.png'}
let totleMoney = 0 let totleMoney = 0
invoiceInfo.forEach(item => { invoiceInfo.forEach(item => {
list[item.label] = item.value
if(item.label === 'money'){ if(item.label === 'money'){
totleMoney += item.value - 0 totleMoney += item.value
} }
}) })
invoiceList.push(list)
if(isInvoice){ if(isInvoice){
param = { param = {
money: totleMoney * 100,invoiceList, remark, checkerList, typeId, projectId: projectId.value, money: totleMoney * 100,invoiceList, remark, checkerList, typeId, projectId: projectId.value,
@ -520,4 +564,15 @@ function setParams(){
padding: 0 0.75rem; padding: 0 0.75rem;
margin: 0.5rem; margin: 0.5rem;
} }
.upload-box{
background: #f7f8fa;
position: relative;
}
.upload-txt{
position: absolute;
width: 100%;
bottom: 22px;
}
</style> </style>

8
pages/applicant.vue

@ -9,11 +9,11 @@
title-active-color="#59B4FF" title-active-color="#59B4FF"
> >
<van-tab title="我的申请"> <van-tab title="我的申请">
<div class="h-full bg-white px-4"> <div class=" bg-white px-4">
<div class="mt-4 flex flex-col h-96 overflow-hidden"> <div class="mt-4 flex flex-col overflow-hidden h-full">
<div class="py-4 pb-0 text-gray-500 font-semibold">历史申请</div> <div class="py-4 pb-0 text-gray-500 font-semibold">历史申请</div>
<Search class="px-4 pt-0" /> <Search />
<HistoricalApplication class="px-4 mt-0" /> <HistoricalApplication />
</div> </div>
<!-- 底部提交按钮部分 --> <!-- 底部提交按钮部分 -->
<div class="fixed w-11/12 box-border bottom-10 " @click="toApplication"> <div class="fixed w-11/12 box-border bottom-10 " @click="toApplication">

13
pages/application-details.vue

@ -41,11 +41,11 @@
</div> </div>
<div class="flex py-2 px-4 text-gray-400 text-base justify-between"> <div class="flex py-2 px-4 text-gray-400 text-base justify-between">
<div>合计金额()</div> <div>合计金额()</div>
<div>{{item.money}}</div> <div>{{ (+item.money / 100).toFixed(2) }}</div>
</div> </div>
<div class="flex py-2 px-4 text-gray-400 text-base justify-between"> <div class="flex py-2 px-4 text-gray-400 text-base justify-between">
<div>税额()</div> <div>税额()</div>
<div>{{item.taxMoney}}</div> <div>{{ (+item.taxMoney / 100).toFixed(2) }}</div>
</div> </div>
<div class="flex py-2 px-4 text-gray-400 text-base justify-between"> <div class="flex py-2 px-4 text-gray-400 text-base justify-between">
<div>开票日期</div> <div>开票日期</div>
@ -87,7 +87,10 @@
<script setup> <script setup>
import dayjs from "dayjs"; import dayjs from "dayjs";
import { ref, computed } from 'vue'; import { ref, computed } from 'vue';
import { getApplyDetail } from 'apis/finance' import { getApplyDetail } from 'apis/finance';
import { useRouter } from 'vue-router';
const router = useRouter();
// //
const currentRate = ref(0); const currentRate = ref(0);
const text = computed(() => currentRate.value.toFixed(0)); const text = computed(() => currentRate.value.toFixed(0));
@ -162,7 +165,9 @@ const submitter = ref([
*/ */
async function handleApplyDetail(){ async function handleApplyDetail(){
try { try {
const params = {param : { applyId: '1485797754654695424' }} const routeValue = router.currentRoute.value;
const applyId = routeValue.query.applyId;
const params = {param : { applyId }}
const res = await getApplyDetail(params) const res = await getApplyDetail(params)
// //
checkerList.value = res.checkerList checkerList.value = res.checkerList

276
pages/financial-approval-details.vue

@ -1,9 +1,39 @@
<template> <template>
<div> <div>
<!-- 发票信息 --> <!-- 发票信息 -->
<div class="bg-white px-3"> <div class="bg-white px-3" v-if="isInvoice">
<div class="text-gray-500 font-semibold px-1 py-3 mt-5">发票信息</div> <div class="text-gray-500 font-semibold px-1 py-3">发票信息</div>
<div v-for="item in billList" class="flex p-2 text-gray-400 text-base justify-between"> <div v-for="(item,invoiceIndex) in invoiceList" :key="invoiceIndex">
<div class="flex py-2 px-4 text-gray-400 text-base justify-between">
<div>发票代码</div>
<div>{{item.invoiceCode}}</div>
</div>
<div class="flex py-2 px-4 text-gray-400 text-base justify-between">
<div>发票号码</div>
<div>{{item.invoiceNumber}}</div>
</div>
<div class="flex py-2 px-4 text-gray-400 text-base justify-between">
<div>合计金额()</div>
<div>{{ (+item.money / 100).toFixed(2) }}</div>
</div>
<div class="flex py-2 px-4 text-gray-400 text-base justify-between">
<div>税额()</div>
<div>{{ (+item.taxMoney / 100).toFixed(2) }}</div>
</div>
<div class="flex py-2 px-4 text-gray-400 text-base justify-between">
<div>开票日期</div>
<div>{{dayjs(item.invoiceTime - 0).format('YYYY年MM月DD日')}}</div>
</div>
<div class="flex py-2 px-4 text-gray-400 text-base justify-between">
<div>备注</div>
<div>{{item.remark}}</div>
</div>
</div>
</div>
<!-- 金额信息 -->
<div class="bg-white px-3" v-else>
<div class="text-gray-500 font-semibold px-1 py-3">发票信息</div>
<div v-for="(item,moneyIndex) in moneyInfo" :key="moneyIndex" class="flex py-2 px-4 text-gray-400 text-base justify-between">
<div>{{item.name}}</div> <div>{{item.name}}</div>
<div>{{item.value}}</div> <div>{{item.value}}</div>
</div> </div>
@ -11,164 +41,218 @@
<!-- 其他信息 --> <!-- 其他信息 -->
<div class="bg-white px-3"> <div class="bg-white px-3">
<div class="text-gray-500 font-semibold px-1 py-3 mt-5">其他信息</div> <div class="text-gray-500 font-semibold px-1 py-3 mt-5">其他信息</div>
<div v-for="item in otherData" class="flex p-2 text-gray-400 text-base justify-between"> <div v-for="(item,otherIndex) in otherData" :key="otherIndex" class="flex py-2 px-4 text-gray-400 text-base justify-between">
<div>{{item.name}}</div> <div>{{item.name}}</div>
<div>{{item.value}}</div> <div>{{item.value}}</div>
</div> </div>
</div> </div>
<!-- 提交人信息 --> <!-- 提交人信息 -->
<div class="bg-white px-3"> <div class="bg-white px-3 mb-5">
<div class="text-gray-500 font-semibold px-1 py-3 mt-5">提交人信息</div> <div class="text-gray-500 font-semibold px-1 py-3 mt-5">提交人信息</div>
<div v-for="item in submitter" class="flex p-2 text-gray-400 text-base justify-between"> <div v-for="(item, index) in submitter" :key="index" class="flex py-2 px-4 text-gray-400 text-base justify-between">
<div>{{item.name}}</div> <div>{{item.name}}</div>
<div>{{item.value}}</div> <div>{{item.value}}</div>
</div> </div>
</div> </div>
<!-- 审核人信息 --> <!-- 审核人信息 -->
<div class="bg-white px-3"> <div class="bg-white px-3 mb-5">
<div class="text-gray-500 font-semibold px-1 py-3 mt-5">审核结果</div> <div class="text-gray-500 font-semibold px-1 py-3">审核结果</div>
<div v-for="item in checkerList" class="flex p-3 text-gray-400 text-base justify-between"> <div v-for="(item, checkerIndex) in checkerList" :key="checkerIndex" class="flex py-3 px-4 text-gray-400 text-base justify-between">
<!-- 遍历的审核人的姓名建议和时间 -->
<div> <div>
<div>{{item.name}}</div> <div>{{item.checkerName}}</div>
<div class="text-sm pt-1">{{item.advice}}</div> <div class="text-sm pt-1">{{item.remark}}</div>
<div class="text-sm pt-1">{{item.checkedTime}}</div> <div class="text-sm pt-1">{{item.time}}</div>
</div> </div>
<!--其他审核人 --> <div class="text-center">
<div class="text-center" v-show="!item.isMine"> <div v-if="item.checkStatus == '1' || item.checkStatus == '2'" :class="item.checkStatus == '1' ? 'text-green-500' : item.checkStatus == '2' ? 'text-red-500' : ''">
<div :class="item.status === '1' ? 'text-green-500' : item.status === '2' ? 'text-red-500' : ''"> {{item.checkStatus == '1' ? '已通过' : item.checkStatus == '2' ? '已驳回' : '待审批'}}
{{item.status === '1' ? '已通过' : item.status === '2' ? '已驳回' : '待审批'}}
</div> </div>
<div v-if="item.score>0" class="mt-1 text-yellow-500"> <div class="text-center" v-else>
<van-circle <van-button type="success" round size="mini" class="button ml-5" @click="showRemark(item.financeCheckId, 1)">通过</van-button>
v-model:current-rate="item.score" <van-button type="danger" round size="mini" class="button" @click="showRemark(item.financeCheckId, 2)">驳回</van-button>
:rate="item.score"
:speed="100"
:text="item.score"
color="#ff6700"
:stroke-width="100"
/>
</div>
</div>
<!-- 当前审核人已审核完毕 -->
<div class="text-center" v-show="item.isMine && item.status !== '0'">
<div :class="item.status === '1' ? 'text-green-500' : item.status === '2' ? 'text-red-500' : ''">
{{item.status === '1' ? '已通过' : item.status === '2' ? '已驳回' : '待审批'}}
</div> </div>
<div v-if="item.score>0" class="mt-1 text-yellow-500"> <div v-if="item.checkStatus == '1' || item.checkStatus == '2'" class="mt-1">
<van-circle <van-circle
v-model:current-rate="item.score" v-model:current-rate="currentRate"
:rate="item.score" :rate="100"
:speed="100" :speed="100"
:text="item.score" :text="100"
class="w-12"
color="#ff6700" color="#ff6700"
:stroke-width="100" :stroke-width="100"
/> />
</div> </div>
</div> </div>
<!-- 当前审核人未审批状态 -->
<div class="text-center" v-show="item.isMine && item.status === '0'">
<van-button type="success" round size="mini" class="button ml-5">通过</van-button>
<van-button type="danger" round size="mini" class="button">驳回</van-button>
</div>
</div> </div>
</div> </div>
<van-dialog v-model:show="data.show" title="备注" show-cancel-button @confirm="handleAudit">
<van-field :border="data.border" v-model="data.remark" type="textarea" class="remark" placeholder="请输入备注" />
</van-dialog>
</div> </div>
</template> </template>
<script setup> <script setup>
import {ref} from 'vue' import dayjs from "dayjs";
// import { ref, computed } from 'vue';
const billList = ref([ import { getApplyDetail, audit } from 'apis/finance';
{ import { useRouter } from 'vue-router';
name: "发票代码", import { Toast } from 'vant';
value: "4154153125646",
}, const router = useRouter();
{
name: "发票号码", const data = reactive({
value: "545648789", show: false,
}, remark: '',
{ auditInfo: {},
name: "合计金额(元)", border: true
value: "40", })
}, //
{ const currentRate = ref(0);
name: "税额(元)", const text = computed(() => currentRate.value.toFixed(0));
value: "2", const isInvoice = ref(false)
}, const checkerList = ref([])
//
const invoiceList = ref([])
//
const moneyInfo = ref([
{ {
name: "开票日期", name: "申请金额",
value: "2022年1月2日", value: "",
label: "money",
}, },
{ {
name: "备注", name: "备注",
value: "业务支出", value: "",
label: "remark",
}, },
]) ])
// //
const otherData = ref([ const otherData = ref([
{ {
name: "申请类型", name: "申请类型",
value: "项目申请" value: "",
label: "typeName",
}, },
{ {
name: "所属项目", name: "所属项目",
value: "PT项目" value: "",
label: "projectName",
}, },
{ {
name: "所属任务", name: "所属任务",
value: "财务条界面设计" value: "",
label: "taskDetailName",
}, },
{ {
name: "类目", name: "类目",
value: "报销" value: "",
label: "categoryName",
}, },
{ {
name: "名目", name: "名目",
value: "业务招待费" value: "",
label: "rowName",
}, },
]) ])
// //
const submitter = ref([ const submitter = ref([
{ {
name:'姓名', name:'姓名',
value:'黛西' value:'',
label: "submitName",
}, },
{ {
name:'部门', name:'部门',
value:'软件部' value:'软件部',
label: "department",
}, },
{ {
name:'提交时间', name:'提交时间',
value:'2021/12/29 13:22' value:'',
}, label: "applyTime",
]);
//
const checkerList = ref([
{
name: "冯教授",
advice: "",
checkedTime: "",
status: "0",
isMine: "1",
},
{
name: "薇薇安",
advice: "很棒!",
checkedTime: "12/18 14:55",
status: "0",
score:''
}, },
{ ])
name: "小明",
advice: "很棒!",
checkedTime: "12/18 14:55", /**
status: "1", * 查询申请详情
score:'80' * @param { Number } applyId 申请记录id
*/
async function handleApplyDetail(){
try {
const routeValue = router.currentRoute.value;
const applyId = routeValue.query.applyId;
const params = {param : { applyId }}
const res = await getApplyDetail(params)
//
checkerList.value = res.checkerList
//
isInvoice.value = res.invoiceList && res.invoiceList.length ? true : false;
invoiceList.value = res.invoiceList
for(let key in res){
moneyInfo.value.forEach(item => {
if(item.label === key){
item.value = res[key]
}
})
}
//
for(let key in res){
otherData.value.forEach(item => {
if(item.label === key){
item.value = res[key]
}
})
}
//
for(let key in res){
submitter.value.forEach(item => {
if(item.label === key){
item.value = res[key]
}
})
}
} catch (error) {
console.error('error: ', error);
} }
]); }
handleApplyDetail()
//
function showRemark(financeCheckId, checkStatus){
data.show = true
data.auditInfo = { financeCheckId, checkStatus }
}
/**
* 审批
* @param { Number } checkStatus 审核状态 1已通过 2驳回
* @param { String } financeCheckId 审核id
* @param { String } remark 备注
*/
async function handleAudit(financeCheckId, checkStatus){
try {
const { auditInfo, remark } = data
const { financeCheckId, checkStatus } = data.auditInfo
const params = {
param:{
financeCheckId,
checkStatus,
remark: data.remark
}
}
await audit(params)
Toast('审批成功');
handleFinanceOfProject()
data.remark = ''
} catch (error) {
console.error('error: ', error);
}
}
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.van-circle{ .van-circle{
width: 2.5rem !important; width: 2.5rem !important;

25
pages/financial-approval.vue

@ -1,9 +1,9 @@
<template> <template>
<div class="mb-60"> <div class="mb-60">
<!-- 财务审批页面 --> <!-- 财务审批页面 -->
<div class="bg-white p-4 flex text-gray-500 flex-col d_jump"> <div class="bg-white p-4 flex text-gray-500 flex-col">
<div> <div>
<span class="font-semibold" id="finance-audit">财务审批</span> <span class="ml-2 text-xs">对员工提交的申请进行审批</span> <span class="font-semibold" id="finance-audit">财务审批</span> <span class="ml-2">对员工提交的申请进行审批</span>
</div> </div>
<Search /> <Search />
<FinanceExamine /> <FinanceExamine />
@ -60,7 +60,7 @@
</div> </div>
<!-- 成员财务图 --> <!-- 成员财务图 -->
<div class="h-64 overflow-hidden"> <div class="h-64 overflow-hidden">
<div> <div class="mt-5">
<span class="inline-block w-2 h-2 border-2 border-blue-400 rounded-full mr-3"></span> <span class="inline-block w-2 h-2 border-2 border-blue-400 rounded-full mr-3"></span>
<span>成员财务图</span> <span>成员财务图</span>
</div> </div>
@ -73,19 +73,16 @@
<span>时间财务图</span> <span>时间财务图</span>
</div> </div>
<BarEcharts class="w-full h-full mt-5" /> <BarEcharts class="w-full h-full mt-5" />
<!-- 没有数据展示空组件 --> <!-- 没有数据展示空组件 -->
<!-- <van-empty description="暂无图表数据信息" /> --> <!-- <van-empty description="暂无图表数据信息" /> -->
</div> </div>
</div> </div>
<!-- 悬浮跳转 -->
<ul class="menu"> <ul class="menu">
<a href="#finance-audit">财务审批</a> <a href="#finance-audit">财务审批</a>
<a href="#finance-statistical">财务统计</a> <a href="#finance-statistical">财务统计</a>
</ul> </ul>
</div> </div>
</template> </template>
<script> <script>
@ -99,21 +96,7 @@ import {ref} from 'vue'
const taskState = ref(true); const taskState = ref(true);
const nameState = ref(true); const nameState = ref(true);
function onClickLeft(){
console.log('返回上一页')
}
function jump(index) {
let jump = document.querySelectorAll('.d_jump')
//
let total = jump[index].offsetTop
// Chrome
document.body.scrollTop = total
// Firefox
document.documentElement.scrollTop = total
// Safari
window.pageYOffset = total
}
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

128
pages/index.vue

@ -8,15 +8,15 @@
title-active-color="#59B4FF" title-active-color="#59B4FF"
> >
<van-tab title="财务管理"> <van-tab title="财务管理">
<div class="h-screen overflow-y-scroll w-screen mt-4"> <div class="h-screen w-full pb-60 overflow-y-scroll">
<!-- 财务管理页面 --> <!-- 财务管理页面 -->
<div class="bg-white p-4 text-gray-500 flex-col"> <div class="bg-white p-4 mt-5 text-gray-500 flex-col">
<div> <div>
<span class="font-semibold" id="finance-manage">财务管理</span> <span class="font-semibold" id="finance-manage">财务管理</span>
<span class="ml-2">对项目预算奖金进行配置</span> <span class="ml-2">对项目预算奖金进行配置</span>
</div> </div>
<Search /> <Search class="mr-5"/>
<FinanceManage /> <FinanceManage class="mr-5"/>
</div> </div>
<!-- 财务审批页面 --> <!-- 财务审批页面 -->
<div class="bg-white p-4 mt-5 text-gray-500 flex-col"> <div class="bg-white p-4 mt-5 text-gray-500 flex-col">
@ -24,80 +24,109 @@
<span class="font-semibold" id="finance-audit">财务审批</span> <span class="font-semibold" id="finance-audit">财务审批</span>
<span class="ml-2">对员工提交的申请进行审批</span> <span class="ml-2">对员工提交的申请进行审批</span>
</div> </div>
<Search /> <Search class="mr-5"/>
<FinanceExamine /> <div class="overflow-x-hidden mr-5 table-box">
<FinanceExamine />
</div>
</div> </div>
<!-- 财务统计页面 --> <!-- 财务统计页面 -->
<div class="bg-white p-4 mt-5 mb-60 text-gray-500 flex-col"> <div class="bg-white p-4 mt-5 text-gray-500 flex-col">
<div> <div>
<span class="font-semibold" id="finance-statistical">财务统计</span> <span class="font-semibold" id="finance-statistical">财务统计</span>
<span class="ml-2">财务明细统计查看</span> <span class="ml-2">财务明细统计查看</span>
</div> </div>
<!-- 任务支出统计 --> <!-- 任务支出统计 -->
<div class="h-64 overflow-hidden"> <div class="h-64 overflow-hidden">
<div class="mt-5 flex justify-between"> <div class="mt-5 flex justify-between">
<div> <div>
<span class="inline-block w-2 h-2 border-2 border-blue-400 rounded-full mr-3"></span> <span
class="inline-block w-2 h-2 border-2 border-blue-400 rounded-full mr-3"
></span>
<span>任务支出统计</span> <span>任务支出统计</span>
</div> </div>
<div> <div class="mr-5">
<van-button :type="taskState ? 'primary' : 'default'" size="mini" @click="taskState = true">图表</van-button> <van-button
<van-button :type="!taskState ? 'primary' : 'default'" size="mini" @click="taskState = false">表格</van-button> :type="taskState ? 'primary' : 'default'"
size="mini"
@click="taskState = true"
>图表</van-button
>
<van-button
:type="!taskState ? 'primary' : 'default'"
size="mini"
@click="taskState = false"
>表格</van-button
>
</div> </div>
</div> </div>
<!-- 任务支出统计的图表展示 --> <!-- 任务支出统计的图表展示 -->
<div v-show="taskState"> <div v-show="taskState">
<!-- <van-empty description="暂无图表数据信息" /> --> <!-- <van-empty description="暂无图表数据信息" /> -->
<RingEcharts class="w-full h-full" id="taskEcharts"/> <RingEcharts class="w-full h-full" id="taskEcharts" />
</div> </div>
<!-- 任务支出统计的表格展示 --> <!-- 任务支出统计的表格展示 -->
<div v-show="!taskState"> <div v-show="!taskState">
<FinanceExamine /> <Expenditure class="w-full h-full" id="taskTable" />
</div> </div>
</div> </div>
<!-- 名目支出统计 --> <!-- 名目支出统计 -->
<div class="h-64 overflow-hidden"> <div class="h-64 overflow-hidden">
<div class="mt-5 flex justify-between"> <div class="mt-5 flex justify-between">
<div> <div>
<span class="inline-block w-2 h-2 border-2 border-blue-400 rounded-full mr-3"></span> <span
<span>名目支出统计</span> class="inline-block w-2 h-2 border-2 border-blue-400 rounded-full mr-3"
</div> ></span>
<div> <span>名目支出统计</span>
<van-button :type="nameState ? 'primary' : 'default'" size="mini" @click="nameState = true">图表</van-button>
<van-button :type="!nameState ? 'primary' : 'default'" size="mini" @click="nameState = false">表格</van-button>
</div>
</div>
<!-- 名目支出统计的图表展示 -->
<div v-show="nameState">
<!-- <van-empty description="暂无图表数据信息" /> -->
<RingEcharts class="w-full h-full" id="nameEcharts"/>
</div> </div>
<!-- 名目支出统计的表格展示 --> <div class="mr-5">
<div v-show="!nameState"> <van-button
<FinanceExamine /> :type="nameState ? 'primary' : 'default'"
size="mini"
@click="nameState = true"
>图表</van-button
>
<van-button
:type="!nameState ? 'primary' : 'default'"
size="mini"
@click="nameState = false"
>表格</van-button
>
</div> </div>
</div>
<!-- 名目支出统计的图表展示 -->
<div v-show="nameState">
<!-- <van-empty description="暂无图表数据信息" /> -->
<RingEcharts class="w-full h-full" id="nameEcharts" />
</div>
<!-- 名目支出统计的表格展示 -->
<div v-show="!nameState">
<Expenditure class="w-full h-full" id="nameTable" />
</div>
</div> </div>
<!-- 成员财务图 --> <!-- 成员财务图 -->
<div class="h-64 overflow-hidden"> <div class="h-64 overflow-hidden">
<div> <div class="mt-5">
<span class="inline-block w-2 h-2 border-2 border-blue-400 rounded-full mr-3"></span> <span
class="inline-block w-2 h-2 border-2 border-blue-400 rounded-full mr-3"
></span>
<span>成员财务图</span> <span>成员财务图</span>
</div> </div>
<RingEcharts class="w-full h-full" id="memberEcharts"/> <RingEcharts class="w-full h-full" id="memberEcharts" />
</div> </div>
<!-- 时间财务图 --> <!-- 时间财务图 -->
<div class="overflow-hidden"> <div class="h-96 overflow-hidden">
<div> <div>
<span class="inline-block w-2 h-2 border-2 border-blue-400 rounded-full mr-3"></span> <span
<span>时间财务图</span> class="inline-block w-2 h-2 border-2 border-blue-400 rounded-full mr-3"
</div> ></span>
<BarEcharts class="w-full h-full mt-5" /> <span>时间财务图</span>
</div>
<!-- 没有数据展示空组件 --> <BarEcharts class="w-full h-full" />
<!-- <van-empty description="暂无图表数据信息" /> -->
</div> </div>
</div> </div>
</div> </div>
</van-tab> </van-tab>
<van-tab title="角色管理"> <div class="h-screen overflow-y-scroll w-screen mt-4">角色管理</div></van-tab> <van-tab title="角色管理"> <div class="h-screen overflow-y-scroll w-screen mt-4">角色管理</div></van-tab>
<van-tab title="任务管理"><div class="h-screen overflow-y-scroll w-screen mt-4">任务管理</div></van-tab> <van-tab title="任务管理"><div class="h-screen overflow-y-scroll w-screen mt-4">任务管理</div></van-tab>
@ -120,6 +149,7 @@ export default {
<script setup> <script setup>
import { ref, onMounted, nextTick } from 'vue'; import { ref, onMounted, nextTick } from 'vue';
const active = ref(0); const active = ref(0);
const taskState = ref(true); const taskState = ref(true);
const nameState = ref(true); const nameState = ref(true);
@ -138,7 +168,6 @@ async function scrollToElementByHash() {
document.documentElement.scrollTop = scrollDom.offsetTop; document.documentElement.scrollTop = scrollDom.offsetTop;
window.pageYOffset = scrollDom.offsetTop; window.pageYOffset = scrollDom.offsetTop;
} }
</script> </script>
<style lang="less"> <style lang="less">
@ -165,10 +194,17 @@ async function scrollToElementByHash() {
border-radius: 30px 0 0 30px; border-radius: 30px 0 0 30px;
margin-bottom: 15px; margin-bottom: 15px;
} }
.van-button--mini{ .button {
padding: 0px;
margin: 0px;
}
.van-button--mini {
padding: 0.5rem 1rem; padding: 0.5rem 1rem;
} }
.van-button--mini+.van-button--mini{ .van-button--mini + .van-button--mini {
margin-left: 0px; margin-left: 0px;
} }
.table-box{
width: 95%;
}
</style> </style>

4
plugins/vant.js

@ -25,6 +25,7 @@ import {
Dialog, Dialog,
Picker, Picker,
Loading, Loading,
Overlay
} from 'vant'; } from 'vant';
import { defineNuxtPlugin } from '#app'; import { defineNuxtPlugin } from '#app';
@ -53,5 +54,6 @@ export default defineNuxtPlugin(nuxtApp => {
.use(Popover) .use(Popover)
.use(Dialog) .use(Dialog)
.use(Picker) .use(Picker)
.use(Loading); .use(Loading)
.use(Overlay)
}); });

Loading…
Cancel
Save