|
@ -1,7 +1,7 @@ |
|
|
<template> |
|
|
<template> |
|
|
<div> |
|
|
<div> |
|
|
<!-- 导航返回上一页 --> |
|
|
<!-- 导航返回上一页 --> |
|
|
<van-nav-bar title="发起申请" left-arrow @click-left="onClickLeft" /> |
|
|
<van-nav-bar title="发起申请" left-arrow /> |
|
|
<!-- 申请发票需要输入的数据 --> |
|
|
<!-- 申请发票需要输入的数据 --> |
|
|
<div class="bg-white pb-3"> |
|
|
<div class="bg-white pb-3"> |
|
|
<div class="text-gray-500 px-4 py-3 font-semibold">发票信息</div> |
|
|
<div class="text-gray-500 px-4 py-3 font-semibold">发票信息</div> |
|
@ -22,20 +22,26 @@ |
|
|
>手动输入</van-button |
|
|
>手动输入</van-button |
|
|
> |
|
|
> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<!-- <van-overlay :show="data.showUploading"> --> |
|
|
<div |
|
|
<div |
|
|
class="text-center border-b w-52 h-24 bg-gray-100 border-dashed border-2" |
|
|
class="text-center border-b w-52 h-24 border-dashed border-2 upload-box" |
|
|
@click="uploadBill" |
|
|
|
|
|
v-show="!data.isSuccess" |
|
|
v-show="!data.isSuccess" |
|
|
> |
|
|
> |
|
|
|
|
|
<van-uploader v-model="data.fileList" multiple :max-count="1" :after-read="afterRead" class="z-50 opacity-0" /> |
|
|
|
|
|
<div class="upload-txt"> |
|
|
<p class="text-gray-400 text-xl pt-3">+</p> |
|
|
<p class="text-gray-400 text-xl pt-3">+</p> |
|
|
<p class="text-gray-400 text-xs">上传并识别凭证</p> |
|
|
<p class="text-gray-400 text-xs">上传并识别凭证</p> |
|
|
</div> |
|
|
</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" |
|
@ -47,7 +53,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" |
|
@ -80,13 +86,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> |
|
@ -98,7 +104,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 |
|
@ -112,9 +118,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 |
|
@ -133,6 +141,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="所属任务" |
|
@ -157,13 +166,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="名目" |
|
@ -174,28 +186,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"> |
|
@ -221,58 +218,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', |
|
|
}, |
|
|
}, |
|
|
], |
|
|
], |
|
@ -286,6 +287,7 @@ const data = reactive({ |
|
|
currentPage: 0, // 当前显示页数 |
|
|
currentPage: 0, // 当前显示页数 |
|
|
personalType: '个人申请', // 上传提示语隐藏 |
|
|
personalType: '个人申请', // 上传提示语隐藏 |
|
|
personalCategory: '用款', |
|
|
personalCategory: '用款', |
|
|
|
|
|
money: '', |
|
|
// 其他信息的多个选择按钮 |
|
|
// 其他信息的多个选择按钮 |
|
|
showType: false, // 申请类型的 |
|
|
showType: false, // 申请类型的 |
|
|
applyTypes: [], |
|
|
applyTypes: [], |
|
@ -304,9 +306,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) |
|
|
|
|
|
} |
|
|
|
|
|
item.value = res.data.data[key] |
|
|
|
|
|
console.log('item: ', item); |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
} |
|
|
|
|
|
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 |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 选择申请类型 |
|
|
// 选择申请类型 |
|
@ -347,15 +404,6 @@ function handleSelectChecker(id) { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 上传票据事件 |
|
|
|
|
|
function uploadBill() { |
|
|
|
|
|
//TODO:调取接口识别票据 |
|
|
|
|
|
setTimeout(() => { |
|
|
|
|
|
data.titleHidden = false; |
|
|
|
|
|
data.isSuccess = true; |
|
|
|
|
|
}, 1000); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 查询所有成员 |
|
|
* 查询所有成员 |
|
|
* @param { String } projectId |
|
|
* @param { String } projectId |
|
@ -380,7 +428,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: { |
|
@ -423,7 +470,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 = {} |
|
@ -437,7 +484,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 |
|
@ -475,18 +523,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 - 0)/100).toFixed(2) |
|
|
} |
|
|
} |
|
|
}) |
|
|
}) |
|
|
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, |
|
@ -522,4 +566,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> |
|
|