Merge branch 'dev'

main
jwg 4 months ago
commit 6da9b43918

@ -15,3 +15,6 @@ VUE_APP_API= '/'
# 方楠
# VUE_APP_BASE_API = 'https://2537287x0n.imdo.co'
VUE_APP_BASE_API = '/proxy-api'
#线上预览
VUE_APP_ONLINE_API = 'http://139.224.253.31:48012'

@ -14,4 +14,10 @@ VUE_APP_API= '/'
# 方楠
VUE_APP_BASE_API = 'http://139.224.253.31:8081'
# VUE_APP_BASE_API = 'http://one-h5.lyrfp.com'
# 开发环境 不要删
# VUE_APP_BASE_API = 'http://192.168.3.128:58088'
# VUE_APP_BASE_API = 'http://60.204.223.58:8080'
#线上预览
VUE_APP_ONLINE_API = 'http://139.224.253.31:48012'

@ -15,6 +15,7 @@
"crypto-js": "^4.1.1",
"dayjs": "^1.11.5",
"dingtalk-jsapi": "^2.15.2",
"echarts": "^5.5.0",
"exif-js": "^2.3.0",
"html2canvas": "^1.4.1",
"js-base64": "^3.7.5",

@ -0,0 +1,58 @@
import request from '@/plugin/axios'
// 申请单报表
export function applyReportApi(query) {
return request({
url: 'bs/expense-apply/getreport',
method: 'get',
params: query,
})
}
// 申请单报表
export function claimReportApi(query) {
return request({
url: 'bs/expense-claim/getreport',
method: 'get',
params: query,
})
}
// 报表
export function gatherMsgApi(query) {
return request({
url: 'bs/statement/gathering ',
method: 'get',
})
}
// 申请单报表
export function paymentMsgApi(query) {
return request({
url: 'bs/statement/payment',
method: 'get',
})
}
// 付款饼图
export function paymentPieApi(query) {
return request({
url: '/bs/statement/paymentPie',
method: 'get',
})
}
// 收款饼图
export function gatheringPieApi(query) {
return request({
url: '/bs/statement/gatheringPie',
method: 'get',
})
}
// 供应商柱状图
export function paymentColumnarApi(query) {
return request({
url: '/bs/statement/paymentColumnar',
method: 'get',
})
}

@ -27,10 +27,11 @@ export function deleteVendorPayment(id) {
}
// 获得对公付款
export function getVendorPayment(id) {
export function getVendorPayment(query) {
return request({
url: '/bs/vendor-payment/get?id=' + id,
method: 'get'
url: '/bs/vendor-payment/get',
method: 'get',
params: query
})
}

@ -0,0 +1,34 @@
import request from '@/plugin/axios'
// 创建银行账户信息
export function createBankInfo(data) {
return request({
url: "/system/bank-info/create",
method: "post",
data: data,
});
}
// 更新银行账户信息
export function updateBankInfo(data) {
return request({
url: "/system/bank-info/update",
method: "put",
data: data,
});
}
// 删除银行账户信息
export function deleteBankAccountInfo(id) {
return request({
url: "/system/bank-info/delete?id=" + id,
method: "delete",
});
}
// 获取银行账户信息详情
export function getDetail(id) {
return request({
url: "/system/bank-info/get?id=" + id,
method: "get",
});
}

@ -36,14 +36,21 @@ export function addUser(data) {
}
// 修改用户
export function updateUser(data) {
// export function updateUser(data) {
// return request({
// url: '/system/user/update',
// method: 'put',
// data: data
// })
// }
// 修改用户个人信息
export function updateUserProfile(data) {
return request({
url: '/system/user/update',
url: '/system/user/profile/update',
method: 'put',
data: data
})
}
// 删除用户
export function delUser(userId) {
return request({
@ -96,14 +103,14 @@ export function getUserProfile() {
})
}
// 修改用户个人信息
export function updateUserProfile(data) {
return request({
url: '/system/user/profile/update',
method: 'put',
data: data
})
}
// // 修改用户个人信息
// export function updateUserProfile(data) {
// return request({
// url: '/system/user/profile/update',
// method: 'put',
// data: data
// })
// }
// 用户密码重置
export function updateUserPwd(oldPassword, newPassword) {
@ -135,3 +142,4 @@ export function importTemplate() {
responseType: 'blob'
})
}

@ -19,9 +19,9 @@
</div>
<div class="step-info">
<!-- {{step}} -->
<div class="step-name">{{ step.assigneeUser.nickname }}</div>
<div class="step-name">{{ step.assigneeUser?.nickname }}</div>
<div class="step-status">审批时间 {{ parseTime(step.endTime) || '-' }}</div>
<div class="step-status">部门{{ step.assigneeUser.deptName }}</div>
<div class="step-status">部门{{ step.assigneeUser?.deptName }}</div>
<div class="step-status">审批意见{{ step.reason }}</div>
</div>
</div>
@ -95,6 +95,9 @@ export default {
if (this.processInstanceId) {
getProcessInstance(this.processInstanceId).then((res) => {
this.startObj = res.data || {}
console.log(
this.startObj
);
})
getTaskListByProcessInstanceId(this.processInstanceId).then(response => {
//
@ -136,6 +139,7 @@ export default {
})
});
this.$emit('onSetId', (Array.isArray(this.runningTasks) && this.runningTasks.length ? this.runningTasks[this.runningTasks.length - 1] : {}).id)
console.log(this.tasks ,'tasks');
});
}
}

@ -143,7 +143,7 @@ export default {
this.$loading(true, 'file')
this.uploadFiles(newList)
.then((res) => {
;(res || []).map((item) => {
(res || []).map((item) => {
this.list.push(item)
})
this.$loading(false, 'file')

@ -18,9 +18,10 @@ export default {
{ path: '/custom', name: `${pre}custom`, component: () => import('@/views/contract/custom'), meta: { cache: true, title: '客户合同审批' } },
{ path: '/pay', name: `${pre}pay`, component: () => import('@/views/contract/pay'), meta: { cache: true, title: '付款审批' } },
{ path: '/corporateReceipts', name: `${pre}corporateReceipts`, component: () => import('@/views/contract/corporateReceipts'), meta: { cache: true, title: '对公收款' } },
{ path: '/corporateReceiptsApproval', name: `${pre}corporateReceipts`, component: () => import('@/views/contract/corporateReceipts'), meta: { cache: true, title: '对公收款' } },
{ path: '/corporateReceiptsApproval', name: `${pre}corporateReceiptsApproval`, component: () => import('@/views/contract/corporateReceipts'), meta: { cache: true, title: '对公收款审批' } },
{ path: '/receipts', name: `${pre}receipts`, component: () => import('@/views/contract/receipts'), meta: { cache: true, title: '收款审批' } },
{ path: '/corporatePayment', name: `${pre}corporatePayment`, component: () => import('@/views/contract/corporatePayment'), meta: { cache: true, title: '对公付款' } },
{ path: '/corporatePaymentApproval', name: `${pre}corporatePaymentApproval`, component: () => import('@/views/contract/corporatePayment'), meta: { cache: true, title: '对公付款审批' } },
{ path: '/payment', name: `${pre}payment`, component: () => import('@/views/contract/payment'), meta: { cache: true, title: '付款审批' } },
])('contract-')
}

@ -0,0 +1,15 @@
import layoutHome from '../../layout/index.vue'
const meta = { requiresAuth: true }
export default {
path: '/reportForms',
name: 'reportForms',
meta,
redirect: { name: 'reportForms' },
component: layoutHome,
children: (pre => [
{ path: '/myReportForms', name: `${pre}myReportForms`, component: () => import('@/views/reportForms/myReportForms'), meta: { cache: true, title: '我的报表' } },
{ path: '/userInfo', name: `${pre}UserInfo`, component: () => import('@/views/reportForms/userInfo'), meta: { cache: true, title: '个人信息' } },
])('reportForms-')
}

@ -1,6 +1,7 @@
import layoutHome from '../layout/index.vue'
import company from './modules/company'
import contract from './modules/contract'
import reportForms from './modules/reportForms'
export const frameInRoutes = [
{
path: '/',
@ -13,7 +14,8 @@ export const frameInRoutes = [
])('home-')
},
company,
contract
contract,
reportForms
]
export const frameOutRoutes = [

@ -373,17 +373,28 @@
<div class="box-tp" style="margin-bottom: 1rem">
<div
class="tp-lf"
@click.stop="showRules(nitem, index, nIndex)"
>
费用 &nbsp;{{ nIndex + 1 }}
<span class="rules" style="color: #1989fa">
<span class="rules" style="color: #1989fa" @click.stop="showRules(nitem, index, nIndex)" >
<van-icon
size="18"
name="coupon-o"
color="#1989fa"
/></span
/>
</span
>
<span style="color: #1989fa; padding:5px" @click="addInvoice">
<van-icon
size="18"
name="plus"
color="#1989fa"
/>
</span>
</div>
<div
class="tp-rt"
v-if="!(item.expenseClaimDetails.length == 1)"
@ -989,6 +1000,15 @@ export default {
watch: {},
//
methods: {
//
addInvoice() {
this.$router.push({
path: '/myInvoice',
query: {
isAdd:'isAdd'
}
})
},
getTree() {
getAreaTree().then((res) => {
let tree = res.data || []

@ -1,10 +1,24 @@
<!-- -->
<template>
<div>
<iframe v-if="showFdf" :src="url" frameborder="0" :class="fullscreen?'ifarmefullscreen':'ifarme'"></iframe>
<iframe :src="previewUrl + encodeURIComponent(base64Encode(url))" frameborder="0" style="width:100%;height:80vh;"></iframe>
<iframe
v-if="showFdf"
:src="url"
frameborder="0"
:class="fullscreen ? 'ifarmefullscreen' : 'ifarme'"
></iframe>
<iframe
:src="previewUrl + encodeURIComponent(base64Encode(url))"
frameborder="0"
style="width: 100%; height: 80vh"
></iframe>
<div class="sumbit-box">
<div class="item-box" v-for="(item,index) in btnList" :key="index" @click="handleBack(item.key)">
<div
class="item-box"
v-for="(item, index) in btnList"
:key="index"
@click="handleBack(item.key)"
>
<van-icon :name="item.icon" :color="item.color" size="25" />
<div class="box-tt">
<span :style="`color:${item.color}`"> {{ item.title }}</span>
@ -16,42 +30,40 @@
<script>
export default {
name: '',
name: "",
created() {
this.handleSetFile()
this.handleSetFile();
},
data() {
return {
showFdf: false,
previewUrl: 'http://60.204.223.58:8086/onlinePreview?url=',
url: '',
btnList: [
{ title: '返回', icon: 'revoke', color: "#909399", key: 0 },
]
}
// previewUrl: 'http://60.204.223.58:8086/onlinePreview?url=',
// KKFileView
// previewUrl: 'http://139.224.253.31:48012/onlinePreview?url=',
previewUrl: process.env.VUE_APP_ONLINE_API + "/onlinePreview?url=",
url: "",
btnList: [{ title: "返回", icon: "revoke", color: "#909399", key: 0 }],
};
},
methods: {
base64Encode(url) {
if (url) {
return this.$Base64.encode(url)
return this.$Base64.encode(url);
}
},
handleBack() {
history.back()
history.back();
},
handleSetFile() {
this.url = this.$route.query.url
}
this.url = this.$route.query.url;
},
},
components: {},
computed: {},
}
};
</script>
<style scoped lang="scss">
@import '~@/assets/style/common/form.scss';
@import "~@/assets/style/common/form.scss";
</style>

@ -104,6 +104,11 @@ export default {
},
created() {
this.handleInit()
const isAdd = this.$route.query && this.$route.query.isAdd === 'isAdd'
//
if(isAdd) {
this.handleToAdd()
}
},
methods: {
handleBack() {

@ -1,39 +1,58 @@
<template>
<!-- 出差列表 -->
<div>
<HeaderFilter :listType="listType" @onListQuery="handleListQuery" :paramProp="listQuery" />
<RMList :moreLoading.sync="moreLoading" :refreshing.sync="refreshing" :finished.sync="finished" @onLoad="handleLoad" @onRefresh="handleRefresh" isMore :tableList="tableList">
<HeaderFilter
:listType="listType"
@onListQuery="handleListQuery"
:paramProp="listQuery"
/>
<RMList
:moreLoading.sync="moreLoading"
:refreshing.sync="refreshing"
:finished.sync="finished"
@onLoad="handleLoad"
@onRefresh="handleRefresh"
isMore
:tableList="tableList"
>
<div>
<MyClaimListCard v-for="(item,index) in tableList" :key="item.id" :itemData="item" :listType="listType" @onUpdataInfo="handleUpdataInfo($event, index)" @onAllRefresh="handleAllRefresh" />
<MyClaimListCard
v-for="(item, index) in tableList"
:key="item.id"
:itemData="item"
:listType="listType"
@onUpdataInfo="handleUpdataInfo($event, index)"
@onAllRefresh="handleAllRefresh"
/>
</div>
</RMList>
<div class="common-bottom-btns" style="bottom: 8rem">
<div class="common-bottom-btn" @click="handleTopPage">
<img src="@/assets/images/icons/top.png" alt="">
<img src="@/assets/images/icons/top.png" alt="" />
<span>回到顶部</span>
</div>
</div>
<div class='feedback-container'>
<div id='allBtns' class='float-btns' ref="allBtns">
<div class='help-wrap' @click="handApply(1)">
<img class='img' src="@/assets/images/tigongdan.png" />
<div class="feedback-container">
<div id="allBtns" class="float-btns" ref="allBtns">
<div class="help-wrap" @click="handApply(1)">
<img class="img" src="@/assets/images/tigongdan.png" />
<span>出差报销</span>
</div>
<div class='help-wrap' @click="handApply(2)">
<img class='img' src="@/assets/images/myworkrukou.png" />
<div class="help-wrap" @click="handApply(2)">
<img class="img" src="@/assets/images/myworkrukou.png" />
<span>日常报销</span>
</div>
</div>
</div>
<div class="common-bottom-btns" style="bottom: 10rem">
<div class="common-bottom-btn" @click="handleToAdd">
<img src="@/assets/images/icons/add.png" alt="">
<img src="@/assets/images/icons/add.png" alt="" />
<span>添加报销</span>
</div>
</div>
<div class="common-bottom-btns" style="bottom: 6rem">
<div class="common-bottom-btn" @click="handleBack">
<img src="@/assets/images/icons/home.png" alt="">
<img src="@/assets/images/icons/home.png" alt="" />
<span>返回首页</span>
</div>
</div>
@ -42,25 +61,26 @@
<script>
//
import { getScrollTop } from '@/utils'
import { getScrollTop } from "@/utils";
// import { getOrderListApi, getDataStatisticsApi, updateOrderSingleListApi } from '@/api/potentialGuest/order'
import { mapState } from 'vuex'
import { mapState } from "vuex";
import { getExpenseClaimMyPage } from "@/api/bs/expenseClaim";
export default {
props: {
listType: String // EnrollmentOrder: EnrollmentCollection: ShiftRecord: WaitPay:
listType: String, // EnrollmentOrder: EnrollmentCollection: ShiftRecord: WaitPay:
},
components: {
HeaderFilter: () => import('@/views/company/myClaim/components/HeaderFilter.vue'),
RMList: () => import('@/components/ReComponents/RMList'),
MyClaimListCard: () => import('@/components/MyClaimListCard'),
HeaderFilter: () =>
import("@/views/company/myClaim/components/HeaderFilter.vue"),
RMList: () => import("@/components/ReComponents/RMList"),
MyClaimListCard: () => import("@/components/MyClaimListCard"),
},
data() {
return {
btnshow: false,
show: false,
billType: null,
demo: ['2210', '45646', '414'],
demo: ["2210", "45646", "414"],
height: 0,
moreLoading: false,
refreshing: false,
@ -84,88 +104,94 @@ export default {
costDeptId: null,
invoiceIds: null,
},
}
};
},
computed: {
...mapState({
singlePageSize: state => state.common.setting.singlePageSize,
pageSize: state => state.common.setting.pageSize,
})
singlePageSize: (state) => state.common.setting.singlePageSize,
pageSize: (state) => state.common.setting.pageSize,
}),
},
activated() {
this.handleScrollInit()
this.handleScrollInit();
},
deactivated() {
window.removeEventListener('scroll', this.handleScroll)
window.removeEventListener("scroll", this.handleScroll);
},
created() {
this.handleInit()
this.handleInit();
},
methods: {
// type 1 2
handApply(type) {
this.$router.push({
path: '/claim',
path: "/claim",
query: {
type: 'add',
billType: type == 1 ? 'CLBX' : 'RCBX'
}
})
this.billType = type == 1 ? 'CLBX' : 'RCBX'
type: "add",
billType: type == 1 ? "CLBX" : "RCBX",
},
});
this.billType = type == 1 ? "CLBX" : "RCBX";
},
handleCloseBtns() {
this.$refs.allBtns.style.height = "0";
this.btnshow = false;
},
handleBack() {
history.back()
history.back();
},
handleSetSingle(id) {
return new Promise((resolve, reject) => {
let listQuery = {
pageNo: 1,
pageSize: this.singlePageSize,
}
getExpenseClaimMyPage(listQuery).then((res) => {
let arr = (res.data && res.data.list || []).filter(item => item.id == id)
resolve(arr)
}).catch((err) => {
reject(err)
})
};
getExpenseClaimMyPage(listQuery)
.then((res) => {
let arr = ((res.data && res.data.list) || []).filter(
(item) => item.id == id
);
resolve(arr);
})
.catch((err) => {
reject(err);
});
});
},
handleUpdataInfo(id, index) {
this.$loading(true, 'singleReset')
this.handleSetSingle(id).then(arr => {
this.$loading(true, "singleReset");
this.handleSetSingle(id)
.then((arr) => {
if (arr.length) {
this.tableList.splice(index, 1, arr[0])
this.tableList.splice(index, 1, arr[0]);
}
this.$loading(false, 'singleReset')
}).catch(() => {
this.$loading(false, 'singleReset')
this.$loading(false, "singleReset");
})
.catch(() => {
this.$loading(false, "singleReset");
});
},
handleListQuery(paramProp) {
this.listQuery = {
...paramProp,
}
this.finished = false
this.handleRefresh()
};
this.finished = false;
this.handleRefresh();
},
handleScroll() {
getScrollTop().then(height => {
this.height = height
})
getScrollTop().then((height) => {
this.height = height;
});
},
handleScrollInit() {
window.addEventListener('scroll', this.handleScroll)
window.scrollTo(0, this.height)
window.addEventListener("scroll", this.handleScroll);
window.scrollTo(0, this.height);
// this.handleInit()
},
handleScrollToTop() {
window.scrollTo(0, 0)
this.height = 0
window.scrollTo(0, 0);
this.height = 0;
},
handleToAdd() {
this.btnshow = !this.btnshow;
@ -177,58 +203,60 @@ export default {
},
handleAllRefresh() {
// this.getTableList('refresh')
this.handleRefresh()
this.handleRefresh();
},
handleInit() {
this.getTableList('init')
this.getTableList("init");
},
handleTopPage() {
window.scrollTo(0, 0)
window.scrollTo(0, 0);
this.$nextTick(() => {
this.height = 0
})
this.height = 0;
});
},
handleRefresh() {
this.listQuery.pageNo = 1
this.finished = false
this.getTableList('refresh')
this.listQuery.pageNo = 1;
this.finished = false;
this.getTableList("refresh");
},
handleLoad() {
this.listQuery.pageNo += 1
this.getTableList('more')
this.listQuery.pageNo += 1;
this.getTableList("more");
},
getTableList(val) {
// const { shellIdsLocal, collegeInfoIdLocal, startDate, endDate, keyword, type, method, targets, usePersonId, teacherIds, chargePersonIds } = this.listQuery
const query = {
...this.listQuery
}
this.moreLoading = true
this.$loading(true, 'tableLoading')
getExpenseClaimMyPage(query).then(res => {
let resList = res.data && res.data.list || []
if (['init', 'refresh'].includes(val)) {
this.tableList = resList
this.handleScrollToTop()
...this.listQuery,
};
this.moreLoading = true;
this.$loading(true, "tableLoading");
getExpenseClaimMyPage(query)
.then((res) => {
let resList = (res.data && res.data.list) || [];
if (["init", "refresh"].includes(val)) {
this.tableList = resList;
this.handleScrollToTop();
} else {
this.tableList = this.tableList.concat(resList)
this.tableList = this.tableList.concat(resList);
}
if (resList.length < this.pageSize) {
this.finished = true
this.finished = true;
}
}).finally(() => {
this.$nextTick(() => {
this.moreLoading = false
this.refreshing = false
this.$loading(false, 'tableLoading')
})
.finally(() => {
this.$nextTick(() => {
this.moreLoading = false;
this.refreshing = false;
this.$loading(false, "tableLoading");
});
// this.$loading(false, `cTableLoading_${this.listType}`)
})
});
},
}
}
},
};
</script>
<style scoped lang="scss">
@import '~@/assets/style/new.scss';
@import "~@/assets/style/new.scss";
</style>

@ -191,7 +191,7 @@ export default {
if (this.$route.query.id) {
this.$loading(true, 'loadingSb')
let api = getVendorPayment
api(this.$route.query.id).then((res) => {
api({id:this.$route.query.id, isApproval: true,}).then((res) => { // isApproval
this.form = {
...(res.data || {}),
responsibleId: res.data.responsibleId ? Number(res.data.responsibleId) : null,

@ -1,6 +1,7 @@
.home-box {
// height: 100vh;
height: 85vh;
// height: 85vh;
height: 100%;
background: #0088fe;
padding: 0.6rem 0.6rem 0 0.6rem;
position: relative;

@ -66,8 +66,8 @@ export default {
props: {
applyShow: {
type: Boolean,
default: false,
},
default: false
}
},
computed: {
permission_btns() {
@ -75,7 +75,7 @@ export default {
},
userInfo() {
return JSON.parse(window.localStorage.getItem('userInfo') || { dept: {} })
},
}
},
created() {
console.log(this.$route.query, 'this.$router.query')
@ -88,7 +88,7 @@ export default {
data() {
return {
roterList: [],
isDot: false,
isDot: false
}
},
@ -96,7 +96,7 @@ export default {
loginOut() {
Dialog.confirm({
title: '提示',
message: '您确定要退出吗?',
message: '您确定要退出吗?'
}).then(() => {
this.$store.dispatch('common/user/out')
})
@ -105,7 +105,7 @@ export default {
let filterArr = ['QUOTATION_SHEET']
getMyNotifyMessagePage({
pageNo: 1,
pageSize: 999,
pageSize: 999
}).then((res) => {
let resList = (res.data && res.data.list) || []
let newArr = resList.filter(
@ -120,7 +120,7 @@ export default {
},
handleToWait() {
this.$router.push({
path: '/waitToDo',
path: '/waitToDo'
})
},
handleFilterList() {
@ -138,7 +138,7 @@ export default {
route: '/myNewTrips',
title: '我的申请',
icon: 'manager-o',
show: checkPermission('bs/myExpenseApply/index'),
show: checkPermission('bs/myExpenseApply/index')
},
/* {
route: '/myTrips',
@ -156,7 +156,7 @@ export default {
route: '/myNewClaim',
title: '我的报销',
icon: 'bookmark-o',
show: checkPermission('bs/myExpenseClaim/index'),
show: checkPermission('bs/myExpenseClaim/index')
},
/* {
route: '/myClaim',
@ -168,10 +168,10 @@ export default {
route: '/myInvoice',
title: '我的发票',
icon: 'label-o',
show: checkPermission('bs/invoice/index'),
},
show: checkPermission('bs/invoice/index')
}
],
title: '报销',
title: '报销'
},
{
row: [
@ -179,26 +179,32 @@ export default {
route: '/myTrips',
title: '申请单',
icon: 'exchange',
show: checkPermission('bs/expenseApply/index'),
show: checkPermission('bs/expenseApply/index')
},
{
route: '/myClaim',
title: '报销单',
icon: 'qr-invalid',
show: checkPermission('bs/expenseClaim/index'),
show: checkPermission('bs/expenseClaim/index')
},
{
route: '/corporateReceiptsApproval', //
title: '对公收款审批',
icon: 'friends-o',
show: this.permission_btns.includes('bs:vendor-receipt:query'),
show: this.permission_btns.includes('bs:vendor-receipt:query')
},
{
route: '/corporatePaymentApproval',
title: '对公付款审批',
icon: 'friends-o',
show: this.permission_btns.includes('bs:vendor-payment:query')
}
],
title: '审批',
title: '审批'
},
{
row: [
{
/* {
route: '/mySupplier',
title: '供应商合同审批',
icon: 'friends-o',
@ -211,7 +217,7 @@ export default {
title: '客户合同审批',
icon: 'manager-o',
show: this.permission_btns.includes('bs:customer-contract:query'),
},
}, */
/* {
route: '/myBidder',
title: '中标审批',
@ -228,22 +234,44 @@ export default {
route: '/corporateReceipts',
title: '对公收款',
icon: 'friends-o',
show: this.permission_btns.includes('bs:vendor-receipt:query'),
show: this.permission_btns.includes('bs:vendor-receipt:query')
},
/* {
{
route: '/corporatePayment',
title: '对公付款',
icon: 'friends-o',
show: this.permission_btns.includes('bs:vendor-payment:query'),
}, */
show: this.permission_btns.includes('bs:vendor-payment:query')
}
],
title: '对公',
title: '对公'
},
{
row: [
{
route: '/myReportForms',
title: '我的报表',
icon: 'friends-o',
show: true
}
],
title: '报表'
},
{
row: [
{
route: '/userInfo',
title: '个人信息',
icon: 'user-o',
show: true
}
],
title: '个人信息'
}
]
this.roterList = arr.map((item) => {
return {
...item,
row: item.row.filter((n) => n.show),
row: item.row.filter((n) => n.show)
}
})
},
@ -256,19 +284,19 @@ export default {
this.$router.push({
path: route,
query: {
type: 'add',
},
type: 'add'
}
})
} else {
this.$router.push({
path: route,
path: route
})
}
} else {
this.$fm('模块正在中...')
}
},
},
}
}
}
</script>

@ -90,12 +90,12 @@ export default {
loginForm: {
loginType: '',
username: '', // admin
password: '', // admin123
password: '', // Abc123456.
captchaVerification: '',
mobile: '',
mobileCode: '',
rememberMe: false,
tenantName: '', //
tenantName: '链友融科技' //
},
systemInfo: {},
checked: false,
@ -103,20 +103,19 @@ export default {
captchaEnable: false,
isRemeber: false,
code: '',
state: '',
state: ''
}
},
components: {
// Verify
},
computed: {
...mapGetters(['devSystemList', 'devUserList']),
...mapGetters(['devSystemList', 'devUserList'])
},
created() {
//
isProhibited().then((res) => {
if (res.data) {
console.log(res.data, 'isProhibited')
if (/wxwork/i.test(navigator.userAgent)) {
//
} else {
@ -159,7 +158,7 @@ export default {
'common/user/setAuthorization',
res.data.accessToken,
{
root: true,
root: true
}
)
await setAccessToken(res.data.accessToken).then(async () => {
@ -180,7 +179,7 @@ export default {
Toast({
duration: 3000, // toast
forbidClick: false,
message: '请输入账号密码首次绑定',
message: '请输入账号密码首次绑定'
})
this.$nextTick(() => {
return
@ -197,7 +196,7 @@ export default {
// scope: 'snsapi_privateinfo',
// agentid: '1000002',
// type: 30,
redirectUri: process.env.VUE_APP_BASE_API + '/#/login',
redirectUri: process.env.VUE_APP_BASE_API + '/#/login'
}).then((res) => {
// URL
window.location.href = res.data
@ -212,7 +211,7 @@ export default {
this.loginForm = {
tenantName,
username,
password,
password
}
} else {
window.localStorage.removeItem('loginInfo')
@ -270,7 +269,7 @@ export default {
this.developLogin({
vm: this,
username: this.loginForm.username,
password: this.loginForm.password,
password: this.loginForm.password
})
.then(() => {
//
@ -278,7 +277,7 @@ export default {
let obj = {
tenantName: this.loginForm.tenantName,
username: this.loginForm.username,
password: this.loginForm.password,
password: this.loginForm.password
}
window.localStorage.setItem('loginInfo', JSON.stringify(obj))
}
@ -308,8 +307,8 @@ export default {
},
handleDevUser(val) {
this.loginForm.devUserTitle = val.title
},
},
}
}
}
</script>

@ -0,0 +1,126 @@
<template>
<div :class="className" :style="{ height: height, width: width }" />
</template>
<script>
import * as echarts from "echarts";
require("echarts/theme/macarons"); // echarts theme
// import resize from '../mixins/resize'
export default {
// mixins: [resize],
props: {
className: {
type: String,
default: "chart",
},
width: {
type: String,
default: "100%",
},
height: {
type: String,
default: "350px",
},
autoResize: {
type: Boolean,
default: true,
},
chartData: {
type: Object,
required: true,
},
},
data() {
return {
chart: null,
};
},
watch: {
chartData: {
deep: true,
handler(val) {
this.setOptions(val);
},
},
},
mounted() {
this.$nextTick(() => {
this.initChart();
});
},
beforeDestroy() {
if (!this.chart) {
return;
}
this.chart.dispose();
this.chart = null;
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, "macarons");
this.setOptions(this.chartData);
},
setOptions({ amountDataList } = {}) {
let newAmountDataList = amountDataList || [];
let xArr = [];
newAmountDataList.forEach((element) => {
xArr.push(element.date);
});
let yArr = [];
newAmountDataList.forEach((element) => {
yArr.push(element.num);
});
this.chart.setOption({
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow",
},
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true,
},
xAxis: [
{
type: "category",
data: xArr,
axisTick: {
alignWithLabel: true,
},
axisLine: {
//x
lineStyle: {
color: "#333",
},
},
},
],
yAxis: [
{
type: "value",
axisLine: {
//y
lineStyle: {
color: "#333",
},
},
},
],
series: [
{
color: "#4E98FF",
name: "CNY",
type: "bar",
barWidth: "30%",
data: yArr,
},
],
});
},
},
};
</script>

@ -0,0 +1,99 @@
<template>
<div :class="className" :style="{ height: height, width: width }" />
</template>
<script>
import * as echarts from "echarts";
require("echarts/theme/macarons"); // echarts theme
// import resize from '../mixins/resize'
export default {
// mixins: [resize],
props: {
className: {
type: String,
default: "chart",
},
width: {
type: String,
default: "100%",
},
height: {
type: String,
default: "350px",
},
autoResize: {
type: Boolean,
default: true,
},
chartData: {
type: Object,
required: true,
},
},
data() {
return {
chart: null,
};
},
watch: {
chartData: {
deep: true,
handler(val) {
this.setOptions(val);
},
},
},
mounted() {
this.$nextTick(() => {
this.initChart();
});
},
beforeDestroy() {
if (!this.chart) {
return;
}
this.chart.dispose();
this.chart = null;
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, "macarons");
this.setOptions(this.chartData);
},
setOptions({ feeTypeDataList } = {}) {
this.chart.setOption({
title: {
left: "center",
},
tooltip: {
trigger: "item",
},
legend: {
orient: "vertical",
left: "left",
},
series: [
{
label: {
formatter: "{b}{c}",
},
name: "",
type: "pie",
radius: ["50%", "70%"],
color: ["#4DB6AC", "#B3E6B5", "#5F7BAC"],
data: feeTypeDataList,
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: "rgba(0, 0, 0, 0.5)",
},
},
},
],
});
},
},
};
</script>

@ -0,0 +1,273 @@
<template>
<div class="common-list-contain">
<div class="common-form">
<van-form
ref="queryParams"
:show-error-message="false"
validate-trigger=""
:submit-on-enter="false"
label-width="8rem"
>
<div class="section"><span class="line"> </span> 查询条件</div>
<div class="trips-box">
<div class="item-box">
<RePick
v-model="bblx"
titleKey="label"
idKey="value"
label="报表类型"
:list="option1"
isRequrie
isCell
clearable
/>
<RePick
v-model="ssdlx"
titleKey="label"
idKey="value"
label="申请单类型"
:list="option2"
isRequrie
isCell
clearable
/>
<van-field
:value="queryParams.createTime"
label="日期"
placeholder="请选择"
@click="handleDateShow"
:right-icon="queryParams.createTime ? '' : 'arrow'"
input-align="right"
autosize
rows="1"
type="textarea"
>
<template v-if="queryParams.createTime" #button>
<van-icon
name="clear"
color="#C8C9CC"
size="16"
@click.stop="handleClear"
/>
</template>
</van-field>
<div style="display: flex; justify-content: center">
<van-button
style="margin-right: 30px"
@click="handleConfirm"
type="primary"
size="normal"
>搜索</van-button
>
<van-button @click="handleDateReset"></van-button>
</div>
</div>
</div>
</van-form>
</div>
<!-- 费用统计 -->
<van-cell-group style="margin-top: 20px">
<van-cell title="费用统计" />
<div class="account-box">
<div class="item-box" v-for="(item, index) in accountList" :key="index">
<div class="box-tt">
<div>
<span>{{ item.tt }}</span>
</div>
<div>
CNY <span class="fw600">{{ item.m }}</span>
</div>
<div>
单据 <span class="fw600">{{ item.num }}</span>
</div>
</div>
</div>
</div>
</van-cell-group>
<van-cell-group style="margin-top: 20px">
<van-cell title="金额按月统计" />
<LineChart :chartData="chartData" />
</van-cell-group>
<van-cell-group style="margin-top: 20px">
<van-cell title="按费用类型统计" />
<RoundChart :chartData="chartData" />
</van-cell-group>
<!--行程时间范围选择 -->
<van-calendar
ref="vanCalendar"
allow-same-day
:maxDate="maxDate"
v-model="dateShow"
:min-date="minDate"
:default-date="defaultDate"
type="range"
color="#0088FE"
@confirm="handleDateSelect"
/>
<div class="common-bottom-btns" style="bottom: 6rem">
<div class="common-bottom-btn" @click="handleBack">
<img src="@/assets/images/icons/home.png" alt="" />
<span>返回首页</span>
</div>
</div>
</div>
</template>
<script>
import dayjs from "dayjs";
import { applyReportApi, claimReportApi } from "@/api/bs/chart";
export default {
components: {
RePick: () => import("@/components/ReComponents/RePick"),
RoundChart: () => import("./components/RoundChart"),
LineChart: () => import("./components/LineChart"),
},
data() {
return {
//
option1: [
{
value: "SQ",
label: "申请单",
},
{
value: "BX",
label: "费用单",
},
],
//
option2: [
{
value: "RC",
label: "日常",
},
{
value: "CL",
label: "差旅",
},
],
//
bblx: "SQ",
ssdlx: "RC",
queryParams: {
billType: "RCSQ",
createTime: "",
startDate: null,
endDate: null,
},
minDate: new Date("2000/01/01"),
maxDate: new Date("2030/01/01"),
defaultDate: new Date(),
dateShow: false,
//
accountList: [
{
m: 747.8,
num: 2,
tt: "合计",
},
{
tt: "流程中",
m: 747.8,
num: 2,
},
],
chartData: {},
};
},
watch: {
ssdlx: {
handler(val) {
this.queryParams.billType = val + this.bblx;
},
immediate: true,
},
bblx: {
handler(val) {
this.queryParams.billType = this.ssdlx + val;
},
immediate: true,
},
},
methods: {
//
handleDateShow(obj) {
const { startTime, endTime } = obj;
this.$nextTick(() => {
this.$refs.vanCalendar && this.$refs.vanCalendar.reset();
this.dateShow = true;
if (startTime && endTime) {
this.defaultDate = [
dayjs(startTime).toDate(),
dayjs(endTime).toDate(),
];
}
});
},
//
handleClear() {
this.queryParams.startDate = "";
this.queryParams.endDate = "";
},
//
handleDateSelect(list) {
this.queryParams.startDate = dayjs(list[0]).format("YY/MM/DD");
this.queryParams.endDate = dayjs(list[1]).format("YY/MM/DD");
this.queryParams.createTime = `${dayjs(list[0]).format(
"YY/MM/DD"
)}~${dayjs(list[1]).format("YY/MM/DD")}`;
this.dateShow = false;
},
//
handleConfirm() {
let api = this.bblx == "SQ" ? applyReportApi : claimReportApi;
const { billType, startDate, endDate } = this.queryParams;
api({
billType,
startDate: startDate || null,
endDate: endDate || null,
}).then((res) => {
this.chartData = res.data || {};
this.accountList[0].m = this.chartData.totalAmount;
this.accountList[0].num = this.chartData.totalCount;
this.accountList[1].m = this.chartData.processAmount;
this.accountList[1].num = this.chartData.processCount;
});
},
//
handleDateReset() {
this.queryParams = {
billType: "RCSQ",
createTime: "",
startDate: null,
endDate: null,
};
this.handleConfirm();
},
handleBack() {
history.back();
},
},
};
</script>
<style scoped lang="scss">
@import "~@/assets/style/common/form.scss";
/* .account-box {
display: flex;
justify-content: space-between;
} */
.box-tt {
padding: 10px 30px;
display: flex;
justify-content: space-between;
.fw600 {
font-weight: 600;
}
}
</style>

@ -0,0 +1,210 @@
<template>
<div class="main">
<van-button type="info" hairline @click="handleAdd" icon="plus"
>新增</van-button
>
<van-list>
<div v-for="(item, index) in list" :key="item.id" class="card">
<p>银行卡{{ index + 1 }}</p>
<p>银行名称{{ item.bankName }}</p>
<p>开户支行{{ item.bankOfDeposit }}</p>
<p>银行账户名: {{ item.bankNumber }}</p>
<p>备注 {{ item.remark }}</p>
<div style="text-align: center">
<van-button
plain
@click="handleUpdate(item)"
type="info"
size="small"
style="margin-right: 20px"
>修改</van-button
>
<van-button
plain
type="danger"
size="small"
@click="handleDelete(item)"
>删除</van-button
>
</div>
</div>
</van-list>
<!-- 对话框(添加 / 修改) -->
<van-popup v-model="open" position="bottom" :overlay="true">
<div
style="
margin: 15px;
text-align: center;
font-size: 18px;
font-weight: 600;
"
>
{{ title }}
</div>
<van-field
v-model="form.bankName"
clearable
label="银行名称"
placeholder="请输入"
/>
<van-field
v-model="form.bankOfDeposit"
required
clearable
label="开户支行"
placeholder="请输入"
/>
<van-field
v-model="form.bankNumber"
required
clearable
label="银行账户号"
placeholder="请输入"
/>
<van-field
v-model="form.remark"
clearable
label="备注"
placeholder="请输入"
/>
<div class="btn-box">
<van-button
type="primary"
size="small"
@click="saveBankInfo"
style="margin-right: 40px"
>保存</van-button
>
<van-button type="info" size="small" @click="open = false"
>取消</van-button
>
</div>
</van-popup>
</div>
</template>
<script>
import {
createBankInfo,
updateBankInfo,
deleteBankAccountInfo,
getDetail
} from '@/api/system/bankInfo'
import { Dialog } from 'vant'
export default {
components: { Dialog },
props: {
user: {
type: Object
}
},
data() {
return {
open: false,
form: {},
title: ''
}
},
computed: {
//
list() {
return this.user.bankInfoList || []
}
},
methods: {
/** 表单重置 */
reset() {
this.form = {
id: undefined,
bankName: undefined,
bankOfDeposit: undefined,
bankNumber: undefined,
accountType: undefined,
remark: undefined,
files: undefined
}
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
this.open = true
this.title = '添加银行账户信息'
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
getDetail(row.id).then((response) => {
this.form = response.data
this.open = true
this.title = '修改银行账户信息'
})
},
//
saveBankInfo() {
if (!this.form.bankName) {
this.$fm('不可为空!')
return
}
if (!this.form.bankOfDeposit) {
this.$fm('不可为空!')
return
}
if (!this.form.bankNumber) {
this.$fm('不可为空!')
return
}
//
if (this.form.id != null) {
updateBankInfo(this.form).then((response) => {
this.$sm('修改成功')
this.open = false
this.$emit('update')
})
return
}
//
createBankInfo(this.form).then((response) => {
this.$sm('新增成功')
this.open = false
this.$emit('update')
})
},
/** 删除按钮操作 */
handleDelete(row) {
const id = row.id
Dialog.confirm({
title: `是否确认删除银行账户号为
${row.bankNumber}
的数据项?`
})
.then(() => {
return deleteBankAccountInfo(id)
.then(() => {
// this.getList()
this.$emit('update')
this.$sm('删除成功')
})
.catch(() => {})
})
.catch(() => {})
}
}
}
</script>
<style scoped lang="scss">
.main {
padding: 10px;
background-color: #f2f2f2;
}
.card {
margin: 15px 0;
padding: 10px;
background-color: #fff;
border-radius: 5px;
}
.btn-box {
margin: 10px;
text-align: center;
}
</style>

@ -0,0 +1,196 @@
<template>
<div class="common-list-contain">
<van-tabs v-model="active" @click="onChange" class="tabs">
<van-tab title="基本资料">
<van-field
v-model="user.nickname"
clearable
label="用户昵称"
placeholder="请输入用户昵称"
/>
<van-field
v-model="user.mobile"
required
clearable
label="手机号码"
placeholder="请输入手机号码"
/>
<van-field
v-model="user.email"
required
clearable
label="邮箱"
placeholder="请输入邮箱"
/>
<div class="van-cell van-field">
<div class="van-cell__title van-field__label">
<span>性别</span>
</div>
<div class="van-cell__value van-field__value">
<div class="van-field__body">
<input type="radio" name="sex" v-model="user.sex" :value="1" />
<span style="display: inline-block; width: 20px"></span>
<input type="radio" name="sex" v-model="user.sex" :value="2" />
</div>
</div>
</div>
<div class="btn-box">
<van-button
type="info"
size="small"
style="width: 30%"
@click="saveUser"
>保存</van-button
>
</div>
</van-tab>
<van-tab title="修改密码">
<van-field
v-model="password.oldPassword"
clearable
type="password"
label="旧密码"
placeholder="请输入"
/>
<van-field
v-model="password.newPassword"
required
clearable
type="password"
label="新密码"
placeholder="请输入"
/>
<van-field
v-model="password.confirmPassword"
required
clearable
type="password"
label="确认密码"
placeholder="请输入"
/>
<div class="btn-box">
<van-button
type="info"
size="small"
style="width: 30%"
@click="savePassword"
>保存</van-button
>
</div>
</van-tab>
<van-tab title="银行">
<BankInfo :user="user" @update="getUser"></BankInfo>
</van-tab>
</van-tabs>
<div class="common-bottom-btns" style="bottom: 6rem">
<div class="common-bottom-btn" @click="handleBack">
<img src="@/assets/images/icons/home.png" alt="" />
<span>返回首页</span>
</div>
</div>
</div>
</template>
<script>
import {
updateUserProfile,
getUserProfile,
updateUserPwd
} from '@/api/system/user'
import BankInfo from './bankInfo'
export default {
components: { BankInfo },
data() {
return {
active: 0,
user: {
nickname: '',
mobile: '',
email: '',
sex: null
},
password: {
oldPassword: '',
newPassword: '',
confirmPassword: ''
}
}
},
created() {
this.getUser()
},
methods: {
onChange(index, title) {
this.active = index
},
//
getUser() {
getUserProfile().then((response) => {
this.user = response.data
})
},
saveUser() {
if (!this.user.mobile) {
this.$fm('手机号不可为空!')
return
}
if (!this.user.email) {
this.$fm('邮箱不可为空!')
return
}
updateUserProfile(this.user).then((res) => {
if (res.data) this.$fm('保存成功!')
})
},
savePassword() {
if (!this.password.oldPassword) {
this.$fm('不可为空!')
return
}
if (!this.password.newPassword) {
this.$fm('不可为空!')
return
}
if (this.password.confirmPassword !== this.password.newPassword) {
this.$fm('两次输入的密码不一致')
return
}
const regex = new RegExp(
/^(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*\.])[A-Za-z\d!@#$%^&*\.]{8,16}$/
)
if (!regex.test(this.password.newPassword)) {
this.$fm('密码必须包含大写字母、数字、特殊字符, 且8-16位')
return
}
updateUserPwd(this.password.oldPassword, this.password.newPassword).then(
(response) => {
this.$fm('修改成功')
}
)
},
handleBack() {
history.back()
}
}
}
</script>
<style scoped lang="scss">
@import '~@/assets/style/common/form.scss';
.tabs {
::v-deep .van-tabs__content {
margin-top: 15px;
}
}
.my-radio {
.van-radio__icon {
display: inline;
}
}
.btn-box {
margin-top: 40px;
text-align: center;
}
</style>
Loading…
Cancel
Save