Browse Source

Merge branch 'apply' of ssh://101.201.226.163:50022/DIGITAL_MANAGEMENT/finance into apply

apply
song 4 years ago
parent
commit
0cf0257cb9
  1. 52
      apis/projectFinance.js
  2. 130
      components/BarEcharts.vue
  3. 122
      components/BonusCollection.vue
  4. 155
      components/HistoricalApplication.vue
  5. 148
      components/RingEcharts.vue
  6. 5
      nuxt.config.ts
  7. 586
      pages/Initiate-application.vue
  8. 70
      pages/applicant.vue
  9. 84
      pages/index.vue
  10. 4
      plugins/vant.js

52
apis/projectFinance.js

@ -1,23 +1,29 @@
import http from 'apis/axios';
const apiUrl = import.meta.env.VITE_API_URL;
const ptccsens = `${apiUrl}/ptccsens/v1.0`;
const projectFinance = `${ptccsens}/projectFinance`;
// 追加预算
export const addBudget = params => http.post(`${projectFinance}/addBudget`, params);
// 查看所有的费用申请
export const queryAllMoneyApply = params => http.post(`${projectFinance}/queryAllMoneyApply`, params);
// 查看项目下的财务信息
export const queryFinanceOfProject = params => http.post(`${projectFinance}/queryFinanceOfProject`, params);
// 查看自己需要审批的申请
export const queryNeedCheckByMe = params => http.post(`${projectFinance}/queryNeedCheckByMe`, params);
// 查看项目下的所有任务对应的财务信息
export const queryProjectFinance = params => http.post(`${projectFinance}/queryProjectFinance`, params);
// 修改任务或项目的预算和奖金信息
export const updateFinance = params => http.post(`${projectFinance}/updateFinance`, params);
import http from 'apis/axios';
const apiUrl = import.meta.env.VITE_API_URL;
const ptccsens = `${apiUrl}/ptccsens/v1.0`;
const projectFinance = `${ptccsens}/projectFinance`;
// 追加预算
export const addBudget = params =>
http.post(`${projectFinance}/addBudget`, params);
// 查看所有的费用申请
export const queryAllMoneyApply = params =>
http.post(`${projectFinance}/queryAllMoneyApply`, params);
// 查看项目下的财务信息
export const queryFinanceOfProject = params =>
http.post(`${projectFinance}/queryFinanceOfProject`, params);
// 查看自己需要审批的申请
export const queryNeedCheckByMe = params =>
http.post(`${projectFinance}/queryNeedCheckByMe`, params);
// 查看项目下的所有任务对应的财务信息
export const queryProjectFinance = params =>
http.post(`${projectFinance}/queryProjectFinance`, params);
// 修改任务或项目的预算和奖金信息
export const updateFinance = params =>
http.post(`${projectFinance}/updateFinance`, params);

130
components/BarEcharts.vue

@ -0,0 +1,130 @@
<template>
<div id="barEcharts" style="width:370px;height:300px"></div>
</template>
<script setup>
import{onMounted} from 'vue';
onMounted(()=>{
const myChart = echarts.init(document.getElementById('barEcharts'));
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
// Use axis to trigger tooltip
type: 'shadow', // 'shadow' as default; can also be 'line' or 'shadow'
},
},
legend: {
icon: 'circle',
orient: 'horizontal',
itemGap: 40,
itemWidth: 14,
itemHeight: 14,
textStyle: {
fontSize: 14,
color: '#858585',
fontWeight: 400,
padding: [4, 0, 0, 0],
},
data: ['A', 'B', 'P', 'E'],
},
color: ['#7E84A3', '#FF914C', '#5189F8', '#3FC7BB'],
grid: {
left: '3%',
right: '0',
bottom: '5%',
containLabel: false,
},
xAxis: {
type: 'category',
data: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
axisTick: {
show: false,
},
axisLabel: {
show: true,
},
axisLine: {
show: false,
},
},
yAxis: {
type: 'value',
splitLine: {
lineStyle: {
color: '#F3F4F5',
},
},
},
series: [
{
name: 'E',
type: 'bar',
stack: 'total',
label: {
show: true,
color: '#FFFFFF',
formatter: function (e) {
return e.value ? e.seriesName : '';
}
},
itemStyle: {
borderRadius: [0, 0, 4, 4],
},
barWidth: 20,
emphasis: {
focus: 'series',
},
data: [320, 80, 301, 334, 390, 330, 320, 390, 330, 320, 390, 390],
},
{
name: 'P',
type: 'bar',
stack: 'total',
label: {
show: true,
color: '#FFFFFF',
formatter: '{a}',
},
emphasis: {
focus: 'series',
},
data: [120, 132, 101, 134, 90, 230, 210, 302, 301, 334, 390, 330],
},
{
name: 'B',
type: 'bar',
stack: 'total',
label: {
show: true,
color: '#FFFFFF',
formatter: '{a}',
},
emphasis: {
focus: 'series',
},
data: [18, 66, 191, 234, 290, 330, 310, 182, 191, 234, 290, 330],
},
{
name: 'A',
type: 'bar',
stack: 'total',
label: {
show: true,
color: '#FFFFFF',
formatter: '{a}',
},
itemStyle: {
borderRadius: [4, 4, 0, 0],
},
emphasis: {
focus: 'series',
},
data: [150, 212, 201, 154, 190, 330, 410, 182, 191, 234, 290, 330],
},
],
};
myChart.setOption(option);
})
</script>

122
components/BonusCollection.vue

@ -0,0 +1,122 @@
<template>
<div>
<div
v-if="data.info.list && data.info.list.length"
class="w-full overflow-x-scroll"
>
<table class="text-gray-500 mt-4 text-ms">
<tr class="bg-gray-100 text-gray-400">
<td class="name">申请人</td>
<td class="money">金额()</td>
<td class="time">时间</td>
<td class="remark">备注</td>
</tr>
<tr v-for="item in data.info.list" class="text-gray-500">
<td>{{ item.submitName }}</td>
<td>
{{ (+item.money / 100).toFixed(2) }}
</td>
<td>
{{ dayjs(item.submitTime - 0).format('YYYY/MM/DD HH:mm') }}
</td>
<td>
{{ item.remark }}
</td>
</tr>
</table>
<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="暂无数据" />
</div>
</template>
<script setup>
import dayjs from 'dayjs';
import { personalHistory } from 'apis/finance';
import { ref, reactive, onMounted, nextTick } from 'vue';
const data = reactive({
info: {},
pageNum: 1,
pageSize: 10,
pages: 0,
});
const projectId = useProjectId();
const taskDetailId = useTaskId();
const taskName = useTaskName();
/**
* 查看当前用户的费用申请历史信息奖金
* @param { Number } pageNum
* @param { Number } pageSize
* @param { String } projectId
* @param { String } name
*/
async function handlePersonalHistory() {
try {
const params = {
param: {
pageNum: data.pageNum,
pageSize: data.pageSize,
projectId: projectId.value,
taskDetailId: taskDetailId.value,
taskName: taskName.value,
type: 1,
},
};
const res = await personalHistory(params);
data.info = res;
data.pageNum = res.pageNum ? +res.pageNum : 1;
data.pageSize = res.pageSize ? +res.pageSize : 10;
data.pages = res.pages ? +res.pages : 0;
} catch (error) {
console.error('error: ', error);
}
}
function confirm() {
alert('确认放款');
}
onMounted(() => {
nextTick(() => {
handlePersonalHistory();
});
});
</script>
<style scoped lang="less">
table {
width: 500px;
td {
border: 0.5px solid #ccc;
padding: 0.85rem;
width: 5.9375rem;
}
.name {
width: 100px;
}
.money {
width: 100px;
}
.time {
width: 170px;
}
.remark {
width: 120px;
}
}
.input-box {
padding: 0 !important;
border-bottom: 1px solid #ccc;
}
</style>

155
components/HistoricalApplication.vue

@ -0,0 +1,155 @@
<template>
<div>
<div
v-if="data.info.list && data.info.list.length"
class="w-full overflow-x-scroll"
>
<table class="text-gray-500 mt-4 text-ms">
<tr class="bg-gray-100 text-gray-400">
<td class="name">申请人</td>
<td class="money">金额()</td>
<td class="time">时间</td>
<td class="status">状态</td>
</tr>
<tr v-for="item in data.info.list" class="text-gray-500">
<td>{{ item.submitName }}</td>
<td>
<!-- v-if="!item.showBudgetEdit" -->
{{ (+item.money / 100).toFixed(2) }}
<!-- <van-field
v-else
v-model="item.budget"
type="number"
class="input-box"
@change="handleUpdateFinance(item)"
@blur="item.showBudgetEdit = false"
/> -->
</td>
<td>
{{ dayjs(item.submitTime - 0).format('YYYY/MM/DD HH:mm') }}
</td>
<td>
<!-- <div v-if="!item.showBonusEdit" @click="item.showBonusEdit = true"> -->
<span v-if="item.applyType - 0 === 0" class="text-gray-500">
待审核
</span>
<span v-else-if="item.applyType - 0 === 1" class="text-gray-500">
已通过
</span>
<span v-else-if="item.applyType - 0 === 2" class="text-red-500">
已驳回
</span>
<span v-else-if="item.applyType - 0 === 3" class="text-gray-500">
待放款
</span>
<van-button
v-else-if="item.applyType - 0 === 4"
type="success"
size="mini"
class="rounded"
@click="confirm"
>
确认
</van-button>
<span v-else-if="item.applyType - 0 === 5" class="text-green-500">
已确认
</span>
</td>
</tr>
</table>
<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="暂无数据" />
</div>
</template>
<script setup>
import dayjs from 'dayjs';
import { personalHistory } from 'apis/finance';
import { ref, reactive, onMounted, nextTick } from 'vue';
const data = reactive({
info: {},
pageNum: 1,
pageSize: 10,
pages: 0,
});
const projectId = useProjectId();
const taskDetailId = useTaskId();
const taskName = useTaskName();
/**
* 查看当前用户的费用申请历史信息奖金
* @param { Number } pageNum
* @param { Number } pageSize
* @param { String } projectId
* @param { String } name
*/
async function handlePersonalHistory() {
try {
const params = {
param: {
pageNum: data.pageNum,
pageSize: data.pageSize,
projectId: projectId.value,
taskDetailId: taskDetailId.value,
taskName: taskName.value,
type: 0,
},
};
const res = await personalHistory(params);
data.info = res;
data.pageNum = res.pageNum ? +res.pageNum : 1;
data.pageSize = res.pageSize ? +res.pageSize : 10;
data.pages = res.pages ? +res.pages : 0;
} catch (error) {
console.error('error: ', error);
}
}
function confirm() {
alert('确认放款');
}
onMounted(() => {
nextTick(() => {
handlePersonalHistory();
});
});
</script>
<style scoped lang="less">
table {
width: 500px;
td {
border: 0.5px solid #ccc;
padding: 0.85rem;
width: 5.9375rem;
}
.name {
width: 100px;
}
.money {
width: 100px;
}
.time {
width: 170px;
}
.status {
width: 120px;
}
}
.input-box {
padding: 0 !important;
border-bottom: 1px solid #ccc;
}
</style>

148
components/RingEcharts.vue

@ -0,0 +1,148 @@
<template>
<!-- <div id="yield-chart"></div> -->
<div :id="props.id" style="width:400px;height:260px"></div>
</template>
<script setup>
import { onMounted} from 'vue';
const props = defineProps({ id: { type: Object, default: () => {} } });
onMounted(()=>{
if(props.id){
var myChart = echarts.init(document.getElementById(props.id));
}
//
const data = [
{
name: '办公费',
value: 36,
rate: 12
},
{
name: '车辆费用',
value: 20,
rate: 20
},
{
name: '差旅费',
value: 15,
rate: -40
},
{
name: '租赁费',
value: 10,
rate: -15
},
{
name: '其他',
value: 9,
rate: 12
},
];
const option = {
title: {
text: 100,
textStyle:{
fontSize:17,
color:"black"
},
textAlign:"center",
x: '24%',
y: '35%',
},
legend: {
type: 'plain',
icon: 'circle',
orient: 'vertical',
left: '55%',
top: '15%',
align: 'left',
itemGap: 15,
itemWidth: 10, //
itemHeight: 10, //
symbolKeepAspect: false,
textStyle: {
color: '#000',
rich: {
name: {
verticalAlign: 'right',
align: 'left',
width: 50,
fontSize: 12
},
value: {
align: 'left',
width: 40,
fontSize: 12
},
count: {
align: 'left',
width: 80,
fontSize: 12
},
}
},
data: data.map(item => item.name),
formatter: function(name) {
if (data && data.length) {
for (var i = 0; i < data.length; i++) {
if (name === data[i].name) {
return (
'{name| ' +
name +
'} | ' +
'{value| ' +
data[i].value +
'%}' +
'{count| ' +
data[i].value +
'} '
)
}
}
}
}
},
series: [{
name: '数量',
type: 'pie',
radius: ['40%', '55%'],
center: ['25%', '40%'],
data: data,
label: {
normal: {
show: false,
position: 'center',
formatter: '{text|{c}}\n{b}',
rich: {
text: {
align: 'center',
verticalAlign: 'middle',
padding: 8,
fontSize: 30
},
value: {
align: 'center',
verticalAlign: 'middle',
fontSize: 20
}
}
},
},
labelLine: {
normal: {
show: true
}
}
}]
};
myChart.setOption(option);
})
</script>
<style scoped>
</style>

5
nuxt.config.ts

@ -27,6 +27,9 @@ export default defineNuxtConfig({
href:"https://cdn.bootcdn.net/ajax/libs/tailwindcss/2.2.19/tailwind.min.css",
},
],
script: [{ src: 'https://cdn.bootcdn.net/ajax/libs/dayjs/1.10.7/dayjs.min.js' }],
script: [
{ src: 'https://cdn.bootcdn.net/ajax/libs/dayjs/1.10.7/dayjs.min.js' },
{src:'https://cdn.bootcdn.net/ajax/libs/echarts/5.2.2/echarts.common.js'}
],
},
});

586
pages/Initiate-application.vue

@ -1,237 +1,245 @@
<template>
<div>
<!-- 导航返回上一页 -->
<van-nav-bar
title="发起申请"
left-arrow
@click-left="onClickLeft"
/>
<!-- 申请发票需要输入的数据 -->
<div class="bg-white pb-3">
<div class="text-gray-500 px-4 py-3 font-semibold">发票信息</div>
<!-- 是否上传票据 -->
<div v-show="data.isInvoice">
<div class="mx-4 pb-3 border-b">
<div class="flex pt-3 pb-2 justify-between" v-show="data.titleHidden">
<div>
<span class="text-red-500">*</span>
<span class="text-gray-500">上传票据凭证 </span>
<span class="text-gray-400 text-xs">(仅支持ipg格式)</span>
</div>
<van-button plain type="primary" size="mini" @click="data.isInvoice = false">手动输入</van-button>
</div>
<div class="text-center border-b w-52 h-24 bg-gray-100 border-dashed border-2" @click="uploadBill" v-show="!data.isSuccess">
<p class="text-gray-400 text-xl pt-3">+</p>
<p class="text-gray-400 text-xs">上传并识别凭证</p>
</div>
<!-- 上传票据成功后显示发票信息 -->
<div v-show="data.isSuccess">
<van-field
v-for="item in data.invoiceInfo"
required
v-model="item.value"
:label="item.name"
@change="cahngeInvoiceList($event, item)"
input-align="right"
/>
</div>
</div>
</div >
<!-- 手动输入信息 -->
<div v-show="!data.isInvoice">
<van-field
required
v-model="data.money"
label="申请金额"
placeholder="输入申请金额"
input-align="right"
/>
</div>
<!-- 备注信息 -->
<div class="text-gray-500 py-4 pl-5">备注</div>
<van-cell-group>
<van-field
v-model="data.remark"
rows="2"
autosize
type="textarea"
maxlength="40"
placeholder="请输入备注"
show-word-limit
class="border rounded"
/>
</van-cell-group>
</div>
<!-- 选择审核人 -->
<div class="mt-3">
<div class="flex bg-white p-4">
<div class="text-red-500">*</div>
<div class="text-gray-500 pl-1 font-semibold">审核人</div>
</div>
<div class="px-3 bg-white">
<!-- 导航返回上一页 -->
<van-nav-bar title="发起申请" left-arrow @click-left="onClickLeft" />
<!-- 申请发票需要输入的数据 -->
<div class="bg-white pb-3">
<div class="text-gray-500 px-4 py-3 font-semibold">发票信息</div>
<!-- 是否上传票据 -->
<div v-show="data.isInvoice">
<div class="mx-4 pb-3 border-b">
<div class="flex pt-3 pb-2 justify-between" v-show="data.titleHidden">
<div>
<van-button
class="button"
size="mini"
v-for="item in data.reviewerList"
:key="item.userId"
:type="data.checkerList.find(checker => checker === item.userId) ? 'primary' : 'default'"
@click="handleSelectChecker(item.userId)"
>
{{item.name}}
</van-button>
<span class="text-red-500">*</span>
<span class="text-gray-500">上传票据凭证 </span>
<span class="text-gray-400 text-xs">(仅支持ipg格式)</span>
</div>
<van-button
plain
type="primary"
size="mini"
@click="data.isInvoice = false"
>手动输入</van-button
>
</div>
</div>
<!-- 其他信息 -->
<div class="bg-white mt-3">
<div class="text-gray-500 p-4 font-semibold">其他信息</div>
<!-- 申请类型 -->
<!-- 普通票据申请 -->
<div>
<van-field
v-model="data.applyType"
is-link
readonly
label="申请类型"
placeholder="请选择申请类型"
@click="data.showType = true"
required
input-align="right"
/>
<van-popup v-model:show="data.showType" round position="bottom">
<van-picker
title="申请类型"
v-if="data.applyTypeOptions && data.applyTypeOptions.length"
:columns="data.applyTypeOptions"
@confirm="finishApplyType"
/>
<van-loading v-else type="spinner" class="text-center my-20" />
</van-popup>
<!-- 所属项目 -->
<van-field
v-model="data.projectName"
is-link
readonly
label="所属项目"
placeholder="请选择所属项目"
required
input-align="right"
disabled
/>
<van-popup v-model:show="data.projectName" round position="bottom">
<van-cascader
active-color="#1989fa"
class="p-0"
/>
</van-popup>
<!-- 所属任务的 -->
<div
class="text-center border-b w-52 h-24 bg-gray-100 border-dashed border-2"
@click="uploadBill"
v-show="!data.isSuccess"
>
<p class="text-gray-400 text-xl pt-3">+</p>
<p class="text-gray-400 text-xs">上传并识别凭证</p>
</div>
<!-- 上传票据成功后显示发票信息 -->
<div v-show="data.isSuccess">
<van-field
v-model="data.taskName"
v-show="data.isInvoice"
is-link
readonly
label="所属任务"
placeholder="请选择所属任务"
v-for="item in data.invoiceInfo"
required
v-model="item.values"
:label="item.name"
@change="cahngeInvoiceList($event, item)"
input-align="right"
disabled
/>
<van-popup v-model:show="data.taskName" round position="bottom">
<van-cascader
active-color="#1989fa"
class="p-0"
/>
</van-popup>
<!-- 类目选择 -->
<van-field
v-model="data.applyCategory"
is-link
readonly
label="类目"
placeholder="请选择类目"
required
@click="data.showCategory = true"
input-align="right"
/>
<van-popup v-model:show="data.showCategory" round position="bottom">
<van-picker
title="请选择类目"
v-if="data.applyCategoryOptions && data.applyCategoryOptions.length"
:columns="data.applyCategoryOptions"
@confirm="finishApplyCategory"
/>
<van-loading v-else type="spinner" class="text-center my-20" />
</van-popup>
<!-- 名目选择 -->
<van-field
v-model="data.applyName"
v-show="data.isInvoice"
is-link
readonly
label="名目"
placeholder="请选择名目"
required
@click="data.showName = true"
input-align="right"
/>
<van-popup v-model:show="data.showName" round position="bottom">
<van-picker
title="请选择名目"
v-if="data.applyNameOptions && data.applyNameOptions.length"
:columns="data.applyNameOptions"
@confirm="finishApplyName"
/>
<van-loading v-else type="spinner" class="text-center my-20" />
</van-popup>
</div>
</div>
</div>
<!-- 提交人信息 -->
<div class="bg-white mt-3">
<div class="text-gray-500 p-4 font-semibold">提交人信息</div>
<van-field
required
v-model="data.submitName"
label="姓名"
placeholder="请输入姓名"
input-align="right"
/>
<!-- 选择所属部门 -->
<van-field
<!-- 手动输入信息 -->
<div v-show="!data.isInvoice">
<van-field
required
v-model="data.applyMoney"
label="申请金额"
placeholder="输入申请金额"
input-align="right"
/>
</div>
<!-- 备注信息 -->
<div class="text-gray-500 py-4 pl-5">备注</div>
<van-cell-group>
<van-field
v-model="data.remark"
rows="2"
autosize
type="textarea"
maxlength="40"
placeholder="请输入备注"
show-word-limit
class="border rounded"
/>
</van-cell-group>
</div>
<!-- 选择审核人 -->
<div class="mt-3">
<div class="flex bg-white p-4">
<div class="text-red-500">*</div>
<div class="text-gray-500 pl-1 font-semibold">审核人</div>
</div>
<div class="px-3 bg-white">
<div>
<van-button
class="button"
size="mini"
v-for="item in data.reviewerList"
:key="item.userId"
:type="
data.checkerList.find(checker => checker === item.userId)
? 'primary'
: 'default'
"
@click="handleSelectChecker(item.userId)"
>
{{ item.name }}
</van-button>
</div>
</div>
</div>
<!-- 其他信息 -->
<div class="bg-white mt-3">
<div class="text-gray-500 p-4 font-semibold">其他信息</div>
<!-- 申请类型 -->
<!-- 普通票据申请 -->
<div v-show="data.isInvoice">
<van-field
v-model="data.applyType"
is-link
readonly
label="申请类型"
placeholder="请选择申请类型"
@click="data.showType = true"
required
input-align="right"
/>
<van-popup v-model:show="data.showType" round position="bottom">
<van-picker
title="申请类型"
:columns="data.applyTypeOptions"
@confirm="finishApplyType"
/>
</van-popup>
<!-- 所属项目 -->
<van-field
v-model="data.projectName"
is-link
readonly
label="所属项目"
placeholder="请选择所属项目"
required
input-align="right"
disabled
/>
<van-popup v-model:show="data.projectName" round position="bottom">
<van-cascader active-color="#1989fa" class="p-0" />
</van-popup>
<!-- 所属任务的 -->
<van-field
v-model="data.taskName"
is-link
readonly
label="所属任务"
placeholder="请选择所属任务"
required
input-align="right"
disabled
/>
<van-popup v-model:show="data.taskName" round position="bottom">
<van-cascader active-color="#1989fa" class="p-0" />
</van-popup>
<!-- 类目选择 -->
<van-field
v-model="data.applyCategory"
is-link
readonly
label="类目"
placeholder="请选择类目"
@click="data.showCategory = true"
input-align="right"
/>
<van-popup v-model:show="data.showCategory" round position="bottom">
<van-picker
title="请选择类目"
:columns="data.applyCategoryOptions"
@confirm="finishApplyCategory"
/>
</van-popup>
<!-- 名目选择 -->
<van-field
v-model="data.applyName"
is-link
readonly
label="名目"
placeholder="请选择名目"
@click="data.showName = true"
input-align="right"
/>
<van-popup v-model:show="data.showName" round position="bottom">
<van-picker
title="请选择名目"
:columns="data.applyNameOptions"
@confirm="finishApplyName"
/>
</van-popup>
</div>
<!-- 个人手动申请 -->
<div v-show="!data.isInvoice">
<div class="pl-2">
<van-cell
title="单元格"
is-link
:value="data.personalType"
required
v-model="data.department"
label="所属部门"
placeholder="请输入所属部门"
input-align="right"
/>
<van-cell
title="单元格"
is-link
:value="data.personalCategory"
required
/>
</div>
</div>
<!-- 历史申请 -->
<div class="bg-white mt-3 p-4">
<div class="text-gray-500 font-semibold">历史申请</div>
<div>
<Search />
<FinanceExamine />
</div>
</div>
<!-- 提交人信息 -->
<div class="bg-white mt-3">
<div class="text-gray-500 p-4 font-semibold">提交人信息</div>
<van-field
required
v-model="data.submitName"
label="姓名"
placeholder="请输入姓名"
input-align="right"
/>
<!-- 选择所属部门 -->
<van-field
required
v-model="data.department"
label="所属部门"
placeholder="请输入所属部门"
input-align="right"
/>
</div>
<!-- 历史申请 -->
<div class="bg-white mt-3 p-4">
<div class="text-gray-500 font-semibold">历史申请</div>
<div>
<Search />
<FinanceExamine />
</div>
<!-- 底部立即提交按钮 -->
<div class="mx-6 mt-10">
<van-button type="primary" size="small" block @click="submit">立即提交</van-button>
</div>
</div>
<!-- 底部立即提交按钮 -->
<div class="mx-6 mt-10">
<van-button type="primary" size="small" block>立即提交</van-button>
</div>
</div>
</template>
<script setup>
import {ref, reactive} from 'vue'
import { ref, reactive } from 'vue';
// import useApplication from 'hooks/useApplication';
import { queryChecker } from 'apis/member'
import { queryType, apply } from 'apis/finance'
import { Toast } from 'vant';
import { queryChecker } from 'apis/member';
import { queryType } from 'apis/finance';
// const getApplication = useApplication();
const projectName = useProjectName()
const taskName = useTaskName()
const projectId = useProjectId()
const taskDetailId = useTaskId()
const projectName = useProjectName();
const taskName = useTaskName();
const projectId = useProjectId();
const data = reactive({
isInvoice: true,
remark: '',
@ -239,34 +247,38 @@ const data = reactive({
invoiceInfo: [
{
name: '发票代码',
value:0,
label: 'invoiceCode'
values: 0,
label: 'invoiceCode',
},
{
name: '发票号码',
value:0,
label: 'invoiceNumber'
values: 1,
label: 'invoiceNumber',
},
{
name: '合计金额(元)',
value:0,
label: 'money'
values: 2,
label: 'money',
},
{
name: '税额(元)',
value:0,
label: 'taxMoney'
values: 3,
label: 'taxMoney',
},
{
name: '开票日期',
value:0,
label: 'invoiceTime'
values: 4,
label: 'invoiceTime',
},
{
name: '发票备注信息',
values: 5,
label: 'remark',
},
],
reviewerList: [], //
checkerList: [], //
isSuccess: false, //
money: '', //
submitName: '', //
department: '', //
pplyMoney: '5000', //
@ -290,73 +302,73 @@ const data = reactive({
applyNameOptions: [],
applyName: '', //
rowId: '',
})
});
//
function cahngeInvoiceList(e,item){
console.log('e: ', e.target.value,item);
function cahngeInvoiceList(e, item) {
console.log('e: ', e.target.value, item);
}
//
function finishApplyType(e){
function finishApplyType(e) {
data.showType = false;
data.applyType = e;
const type = data.applyTypes.find((option) => option.name === e);
const type = data.applyTypes.find(option => option.name === e);
data.typeId = type.id;
//
handleQueryType(data.typeId, 1)
handleQueryType(data.typeId, 1);
}
//
function finishApplyCategory(e){
function finishApplyCategory(e) {
data.showCategory = false;
data.applyCategory = e;
const category = data.applyCategories.find((option) => option.name === e);
const category = data.applyCategories.find(option => option.name === e);
data.categoryId = category.id;
//
handleQueryType(data.categoryId, 2)
handleQueryType(data.categoryId, 2);
}
//
function finishApplyName(e){
function finishApplyName(e) {
data.showName = false;
data.applyName = e;
const row = data.applyNames.find((option) => option.name === e);
const row = data.applyNames.find(option => option.name === e);
data.rowId = row.id;
}
//
function handleSelectChecker(id){
const target = data.checkerList.find(item =>item === id)
if(target){
data.checkerList = data.checkerList.filter(item =>item !== id)
}else{
data.checkerList.push(id)
function handleSelectChecker(id) {
const target = data.checkerList.find(item => item === id);
if (target) {
data.checkerList = data.checkerList.filter(item => item !== id);
} else {
data.checkerList.push(id);
}
}
//
function uploadBill(){
function uploadBill() {
//TODO:
setTimeout(() =>{
data.titleHidden = false
data.isSuccess = true
},1000)
setTimeout(() => {
data.titleHidden = false;
data.isSuccess = true;
}, 1000);
}
/**
* 查询所有成员
* @param { String } projectId
*/
async function handleQueryChecker(){
async function handleQueryChecker() {
try {
const params = {
param:{
projectId: projectId.value
}
}
const res = await queryChecker(params)
data.reviewerList = res
param: {
projectId: projectId.value,
},
};
const res = await queryChecker(params);
data.reviewerList = res;
} catch (error) {
console.error('error: ', error);
}
@ -367,49 +379,45 @@ async function handleQueryChecker(){
* @param { String } parentId 上级类型ID默认为0
* @param { Number } type 类型0申请类型 1类目 2名目
*/
async function handleQueryType(parentId, type){
async function handleQueryType(parentId, type) {
console.log('parentId: ', parentId);
try {
const params = {
param:{
param: {
parentId,
type,
}
}
const res = await queryType(params)
if(type === 0){
data.applyTypes = res
res.forEach((item) => {
data.applyTypeOptions.push(item.name)
})
},
};
const res = await queryType(params);
if (type === 0) {
data.applyTypes = res;
res.forEach(item => {
data.applyTypeOptions.push(item.name);
});
}
if(type === 1){
data.applyCategories = res
res.forEach((item) => {
data.applyCategoryOptions.push(item.name)
})
if (type === 1) {
data.applyCategories = res;
res.forEach(item => {
data.applyCategoryOptions.push(item.name);
});
}
if(type === 2){
data.applyNames = res
res.forEach((item) => {
data.applyNameOptions.push(item.name)
})
if (type === 2) {
data.applyNames = res;
res.forEach(item => {
data.applyNameOptions.push(item.name);
});
}
} catch (error) {
console.error('error: ', error);
}
}
onMounted(() =>{
onMounted(() => {
//
handleQueryChecker()
handleQueryChecker();
//
handleQueryType(0, 0)
})
function onClickLeft(){
console.log(1)
}
handleQueryType(0, 0);
});
/**
* 发起申请
@ -494,24 +502,24 @@ function setParams(){
</script>
<style lang="less" scoped>
.van-cell-group{
padding:0 1rem;
.van-cell-group {
padding: 0 1rem;
}
.van-cell{
.van-cell {
font-size: 15px;
}
.bill-name{
.bill-name {
font-weight: 600;
color: #6F6F6F;
color: #6f6f6f;
border-bottom: 1px solid #eee;
padding: 0.75rem 0px;
}
.van-button{
.van-button {
border-radius: 0.2rem;
}
.button{
.button {
border-radius: 1rem;
padding: 0 0.75rem;
margin: 0.5rem ;
margin: 0.5rem;
}
</style>

70
pages/applicant.vue

@ -1,24 +1,19 @@
<template>
<div>
<!-- 搜索框与表格部分 -->
<van-tabs v-model:active="active" shrink line-width="60px" color="#59B4FF" title-active-color="#59B4FF">
<van-tabs
v-model:active="active"
shrink
line-width="60px"
color="#59B4FF"
title-active-color="#59B4FF"
>
<van-tab title="我的申请">
<div class="mt-8 bg-white flex flex-col">
<div class="p-4 pb-0 text-gray-500 font-semibold">历史申请</div>
<Search class="px-4 pt-0"/>
<FinanceManage class="px-4 mt-0"/>
<div class="p-4 pb-0 text-gray-500 font-semibold">历史申请</div>
<Search class="px-4 pt-0" />
<HistoricalApplication class="px-4 mt-0" />
</div>
<!-- <div class="mt-8 bg-white">
<span class="p-4 pb-0 text-gray-500 font-semibold">历史申请</span>
<div v-if="isShow">
<Search />
<FinanceManage />
</div>
<div v-if="!isShow" class="no-data">
暂无历史记录
</div>
</div> -->
<!-- 底部提交按钮部分 -->
<div class="mt-20" @click="toApplication">
<van-button type="primary" block>发起申请</van-button>
@ -27,52 +22,57 @@
<van-tab title="我的奖金">
<div class="mt-8 bg-white">
<div class="p-4 pb-0 text-gray-500 font-semibold">奖金领取记录</div>
<Search class="px-4 pt-0"/>
<FinanceManage class="px-4 mt-0"/>
<div class="p-4 pb-0 text-gray-500 font-semibold">奖金领取记录</div>
<Search class="px-4 pt-0" />
<BonusCollection class="px-4 mt-0" />
</div>
<div class="my-4 bg-white">
<div class="text-gray-500 font-semibold m-4 py-3 border-b">待领取奖金</div>
<div class="text-gray-500 font-semibold m-4 py-3 border-b">
待领取奖金
</div>
<div class="text-ms text-gray-400 pl-4">可领取:</div>
<div class="w-full h-20 text-gray-400 font-semibold text-center leading-loose" v-if="!isBonus">
<div
class="w-full h-20 text-gray-400 font-semibold text-center leading-loose"
v-if="!isBonus"
>
暂无可领取的奖金
</div>
<div class="w-full h-20 text-blue-500 font-semibold text-center leading-loose text-2xl" v-if="isBonus">
<div
class="w-full h-20 text-blue-500 font-semibold text-center leading-loose text-2xl"
v-if="isBonus"
>
500
</div>
<div class="px-8">
<van-button type="primary" size="small" block :disabled="!isBonus" >立即领取</van-button>
<van-button type="primary" size="small" block :disabled="!isBonus"
>立即领取</van-button
>
</div>
</div>
</van-tab>
</van-tabs>
</van-tabs>
</div>
</template>
<script setup>
import {ref} from 'vue'
import { ref } from 'vue';
import { useRouter } from 'vue-router';
const router = useRouter();
const active = ref(0);
const isShow = ref(true);
const isBonus =ref(true)
const isBonus = ref(true);
function onClickLeft(){
console.log('返回上一页')
function onClickLeft() {
console.log('返回上一页');
}
function toApplication() {
const routeValue = router.currentRoute.value;
const query = routeValue.query
router.push({path: '/Initiate-application', query})
const query = routeValue.query;
router.push({ path: '/Initiate-application', query });
}
</script>
<style lang="less" scoped>
</style>
<style lang="less" scoped></style>

84
pages/index.vue

@ -1,6 +1,5 @@
<template>
<div class="mb-60">
<van-nav-bar title="资源管理" left-arrow @click-left="onClickLeft" />
<van-tabs
v-model:active="active"
shrink
@ -10,7 +9,7 @@
>
<van-tab title="财务管理">
<!-- 财务管理页面 -->
<div class="bg-white p-4 mt-5 flex text-gray-500 flex-col d_jump">
<div class="bg-white p-4 mt-5 text-gray-500 flex-col">
<div>
<span class="font-semibold" id="finance-manage">财务管理</span>
<span class="ml-2">对项目预算奖金进行配置</span>
@ -19,7 +18,7 @@
<FinanceManage />
</div>
<!-- 财务审批页面 -->
<div class="bg-white p-4 mt-5 flex text-gray-500 flex-col d_jump">
<div class="bg-white p-4 mt-5 text-gray-500 flex-col">
<div>
<span class="font-semibold" id="finance-audit">财务审批</span>
<span class="ml-2">对员工提交的申请进行审批</span>
@ -28,12 +27,71 @@
<FinanceExamine />
</div>
<!-- 财务统计页面 -->
<div class="bg-white p-4 mt-5 flex text-gray-500 flex-col d_jump">
<div class="bg-white p-4 mt-5 text-gray-500 flex-col">
<div>
<span class="font-semibold" id="finance-statistical">财务统计</span>
<span class="ml-2">财务明细统计查看</span>
</div>
<img src="public/statistics.png" class="w-full" />
<!-- 任务支出统计 -->
<div class="h-64 overflow-hidden">
<div class="mt-5 flex justify-between">
<div>
<span class="inline-block w-2 h-2 border-2 border-blue-400 rounded-full mr-3"></span>
<span>任务支出统计</span>
</div>
<div>
<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 v-show="taskState">
<!-- <van-empty description="暂无图表数据信息" /> -->
<RingEcharts class="w-full h-full" id="taskEcharts"/>
</div>
<!-- 任务支出统计的表格展示 -->
<div v-show="!taskState">
<FinanceExamine />
</div>
</div>
<!-- 名目支出统计 -->
<div class="h-64 overflow-hidden">
<div class="mt-5 flex justify-between">
<div>
<span class="inline-block w-2 h-2 border-2 border-blue-400 rounded-full mr-3"></span>
<span>名目支出统计</span>
</div>
<div>
<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 v-show="!nameState">
<FinanceExamine />
</div>
</div>
<!-- 成员财务图 -->
<div class="h-64 overflow-hidden">
<div>
<span class="inline-block w-2 h-2 border-2 border-blue-400 rounded-full mr-3"></span>
<span>成员财务图</span>
</div>
<RingEcharts class="w-full h-full" id="memberEcharts"/>
</div>
<!-- 时间财务图 -->
<div class="h-72 overflow-hidden">
<div>
<span class="inline-block w-2 h-2 border-2 border-blue-400 rounded-full mr-3"></span>
<span>时间财务图</span>
</div>
<BarEcharts class="w-full h-full" />
</div>
</div>
</van-tab>
<van-tab title="角色管理">角色管理</van-tab>
@ -58,6 +116,8 @@ export default {
<script setup>
import { ref, onMounted, nextTick } from 'vue';
const active = ref(0);
const taskState = ref(true);
const nameState = ref(true);
onMounted(async () => {
scrollToElementByHash();
@ -74,10 +134,6 @@ async function scrollToElementByHash() {
window.pageYOffset = scrollDom.offsetTop;
}
function onClickLeft() {
console.log('返回上一页');
}
</script>
<style lang="less">
@ -104,4 +160,14 @@ function onClickLeft() {
border-radius: 30px 0 0 30px;
margin-bottom: 15px;
}
.button{
padding: 0px;
margin:0px;
}
.van-button--mini{
padding: 0.5rem 1rem;
}
.van-button--mini+.van-button--mini{
margin-left: 0px;
}
</style>

4
plugins/vant.js

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

Loading…
Cancel
Save