Initial commit

This commit is contained in:
fengchenchen
2023-08-22 16:30:10 +08:00
commit 9f170896a5
375 changed files with 110439 additions and 0 deletions
+72
View File
@@ -0,0 +1,72 @@
<template>
<a-config-provider :locale="locale">
<div id="app">
<router-view></router-view>
</div>
</a-config-provider>
</template>
<script>
import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN'
import enquireScreen from '@/utils/device'
window.addEventListener('message', function (event) {
// 当监听到 需要修改样式的事件时 隐藏相应的元素
if (event.data.hideDom) {
//此处执行事件
setTimeout(() => {
document.getElementsByClassName('ant-layout-sider')[0].style.display = 'none'
document.getElementsByClassName('ant-layout-header')[0].style.display = 'none'
document.getElementsByClassName('tab-layout-tabs ant-tabs ant-tabs-top')[0].style.display = 'none'
}, 1000)
}
})
document.onkeydown = keyDown
function keyDown(e) {
// 拦截backspace按钮,谷歌浏览器不需要拦截
// 拦截仍然存在的问题:当input、textarea失去焦点后,仍然会后退页面
if (e.keyCode === 8 && navigator.userAgent.indexOf('AppleWebKit') === -1 ) {
// 判断是不是在input或textarea触发backspace按钮事件
if (window.event.srcElement.tagName.toUpperCase() === 'INPUT' || window.event.srcElement.tagName.toUpperCase() === 'TEXTAREA') {
// 判断输入框中是否还有值可删除
if (window.event.srcElement.value.length === 1) {
// 拦截事件
e.keyCode=0
e.returnValue=false
}
}
}
}
export default {
data() {
return {
locale: zhCN
}
},
created() {
let that = this
enquireScreen(deviceType => {
// tablet
if (deviceType === 0) {
that.$store.commit('TOGGLE_DEVICE', 'mobile')
that.$store.dispatch('setSidebar', false)
}
// mobile
else if (deviceType === 1) {
that.$store.commit('TOGGLE_DEVICE', 'mobile')
that.$store.dispatch('setSidebar', false)
} else {
that.$store.commit('TOGGLE_DEVICE', 'desktop')
that.$store.dispatch('setSidebar', true)
}
})
}
}
</script>
<style>
#app {
height: 100%;
}
</style>
+204
View File
@@ -0,0 +1,204 @@
import { getAction, deleteAction,putAction, postAction, httpAction } from '@/api/manage'
import Vue from 'vue'
import {UI_CACHE_DB_DICT_DATA } from '@/store/mutation-types'
// idm 系统单点登录 获取用户信息
const loginIdmPlatform = (params) => postAction(`/sys/singleSignOn?code=${params.code}`)
//角色管理
const addRole = (params)=>postAction('/sys/role/add',params)
const editRole = (params)=>postAction('/sys/role/edit',params)
const checkRoleCode = (params)=>getAction('/sys/role/checkRoleCode',params)
const queryallRoles = (params)=> getAction('sys/role/treeList',params)
const queryall = (params)=>getAction('/sys/role/queryall',params)
//用户管理
const addUser = (params)=>postAction('/sys/user/add',params)
const editUser = (params)=>postAction('/sys/user/edit',params)
const queryUserRole = (params)=>getAction('/sys/user/queryUserRole',params)
const getUserList = (params)=>getAction('/sys/user/page',params)
// 获取全部用户列表
const getAllUserList = (params) => getAction('/sys/user/list', params)
const frozenBatch = (params)=>postAction('/sys/user/frozenBatch',params)
//验证用户是否存在
const checkOnlyUser = (params)=>getAction('/sys/user/checkOnlyUser',params)
//改变密码
const changePassword = (params)=>postAction('/sys/user/changePassword',params)
// 重置密码
const resetUserPassword = (params) => postAction('/sys/user/resetPassword',params)
//权限管理
const addPermission= (params)=>postAction('/sys/permission/add',params)
const editPermission= (params)=>postAction('/sys/permission/edit',params)
const getPermissionList = (params)=>getAction('/sys/permission/page',params)
const getSystemMenuList = (params)=>getAction('/sys/permission/getSystemMenuList',params)
const getSystemSubmenu = (params)=>getAction('/sys/permission/getSystemSubmenu',params)
const getSystemSubmenuBatch = (params) => getAction('/sys/permission/getSystemSubmenuBatch', params)
const queryTreeList = (params)=>getAction('/sys/permission/queryTreeList',params)
const queryTreeListForRole = (params)=>getAction('/sys/role/queryTreeList',params)
const queryListAsync = (params)=>getAction('/sys/permission/queryListAsync',params)
const queryRolePermission = (params)=>getAction('/sys/permission/queryRolePermission',params)
const saveRolePermission = (params)=>postAction('/sys/permission/saveRolePermission',params)
const queryPermissionsByUser = ()=>getAction('/sys/permission/getUserPermissionByToken')
const loadAllRoleIds = (params)=>getAction('/sys/permission/loadAllRoleIds',params)
const getPermissionRuleList = (params)=>getAction('/sys/permission/getPermRuleListByPermId',params)
const queryPermissionRule = (params)=>getAction('/sys/permission/queryPermissionRule',params)
// 部门管理
const queryDepartTreeList = (params)=>getAction('/sys/sysDepart/queryTreeList',params)
const queryIdTree = (params)=>getAction('/sys/sysDepart/queryIdTree',params)
const queryParentName = (params)=>getAction('/sys/sysDepart/queryParentName',params)
const searchByKeywords = (params)=>getAction('/sys/sysDepart/searchBy',params)
const deleteByDepartId = (params)=>getAction('/sys/sysDepart/delete',params)
//二级部门管理
const queryDepartPermission = (params)=>getAction('/sys/permission/queryDepartPermission',params)
const saveDepartPermission = (params)=>postAction('/sys/permission/saveDepartPermission',params)
const queryTreeListForDeptRole = (params)=>getAction('/sys/sysDepartPermission/queryTreeListForDeptRole',params)
const queryDeptRolePermission = (params)=>getAction('/sys/sysDepartPermission/queryDeptRolePermission',params)
const saveDeptRolePermission = (params)=>postAction('/sys/sysDepartPermission/saveDeptRolePermission',params)
const queryMyDepartTreeList = (params)=>getAction('/sys/sysDepart/queryMyDeptTreeList',params)
//日志管理
//const getLogList = (params)=>getAction("/sys/log/page",params);
const deleteLog = (params)=>deleteAction('/sys/log/delete',params)
const deleteLogList = (params)=>deleteAction('/sys/log/deleteBatch',params)
//数据字典
const addDict = (params)=>postAction('/sys/dict/add',params)
const editDict = (params)=>postAction('/sys/dict/edit',params)
const treeList = (params)=>getAction('/sys/dict/treeList',params)
const addDictItem = (params)=>postAction('/sys/dictItem/add',params)
const editDictItem = (params)=>postAction('/sys/dictItem/edit',params)
//字典标签专用(通过code获取字典数组)
export const ajaxGetDictItems = (code, params)=>getAction(`/sys/dict/getDictItems/${code}`,params)
//从缓存中获取字典配置
function getDictItemsFromCache(dictCode) {
if (Vue.ls.get(UI_CACHE_DB_DICT_DATA) && Vue.ls.get(UI_CACHE_DB_DICT_DATA)[dictCode]) {
let dictItems = Vue.ls.get(UI_CACHE_DB_DICT_DATA)[dictCode]
return dictItems
}
}
//系统通告
const doReleaseData = (params)=>getAction('/sys/annountCement/doReleaseData',params)
const doReovkeData = (params)=>getAction('/sys/annountCement/doReovkeData',params)
//获取系统访问量
const getLoginfo = (params)=>getAction('/sys/loginfo',params)
const getVisitInfo = (params)=>getAction('/sys/visitInfo',params)
// 根据部门主键查询用户信息
const queryUserByDepId = (params)=>getAction('/sys/user/queryUserByDepId',params)
// 重复校验
const duplicateCheck = (params)=>getAction('/sys/duplicate/check',params)
// 加载分类字典
const loadCategoryData = (params)=>getAction('/sys/category/loadAllData',params)
const checkRuleByCode = (params) => getAction('/sys/checkRule/checkByCode', params)
//加载我的通告信息
const getUserNoticeInfo= (params)=>getAction('/sys/sysAnnouncementSend/getMyAnnouncementSend',params)
const getTransitURL = url => `/sys/common/transitRESTful?url=${encodeURIComponent(url)}`
// 通过文件的id获取文件的相应信息
const getFileInfo = (params) => getAction('/sys/oss/file/queryById', params)
// 通过多个文件的ids 获取文件的相应信息
const getFileInfoByIds = (params) => getAction('/sys/oss/file/queryByIds', params)
// 中转HTTP请求
export const transitRESTful = {
get: (url, parameter) => getAction(getTransitURL(url), parameter),
post: (url, parameter) => postAction(getTransitURL(url), parameter),
put: (url, parameter) => putAction(getTransitURL(url), parameter),
http: (url, parameter) => httpAction(getTransitURL(url), parameter),
}
// 通过企业名称获取该企业下的联系人
const getContactsByCompany = (params) => getAction('/company/payContactsManagement/queryByCompany', params)
// 通过企业名称获取该企业下的联系人无权限接口
const getContactsByCompanyNoLimit = (params) => getAction('/company/payContactsManagement/queryByCompanyMeeting', params)
// 通过联系人id获取联系人信息
const getContactsById = (param) => getAction('/company/payContactsManagement/queryByIdMeeting', param)
// 企业管理员重置密码
const companyAdminResetPassword = (param) => postAction('/payManagerManagement/resetPassword', param)
// 企业管理员启用禁用
const companyAdminEnable= (param) => postAction('/payManagerManagement/frozenBatch', param)
// 通过企业id查询企业的相关发票信息
const queryCompanyInfoById= (param) => getAction('/company/payCompanyManagement/queryById', param)
// 加密获取key 与 iv
const getKeyIv = (param) => getAction('/sys/getEncryptedString',param)
export {
addRole,
editRole,
checkRoleCode,
addUser,
editUser,
queryUserRole,
getUserList,
getAllUserList,
queryall,
frozenBatch,
checkOnlyUser,
changePassword,
getPermissionList,
addPermission,
editPermission,
queryTreeList,
queryListAsync,
queryRolePermission,
saveRolePermission,
queryPermissionsByUser,
loadAllRoleIds,
getPermissionRuleList,
queryPermissionRule,
queryDepartTreeList,
queryIdTree,
queryParentName,
searchByKeywords,
deleteByDepartId,
deleteLog,
deleteLogList,
addDict,
editDict,
treeList,
addDictItem,
editDictItem,
doReleaseData,
doReovkeData,
getLoginfo,
getVisitInfo,
queryUserByDepId,
duplicateCheck,
queryTreeListForRole,
getSystemMenuList,
getSystemSubmenu,
getSystemSubmenuBatch,
loadCategoryData,
checkRuleByCode,
queryDepartPermission,
saveDepartPermission,
queryTreeListForDeptRole,
queryDeptRolePermission,
saveDeptRolePermission,
queryMyDepartTreeList,
getUserNoticeInfo,
getDictItemsFromCache,
resetUserPassword,
getContactsByCompany,
queryallRoles,
getContactsById,
getFileInfo,
getFileInfoByIds,
getKeyIv,
getContactsByCompanyNoLimit,
loginIdmPlatform,
companyAdminResetPassword,
companyAdminEnable,
queryCompanyInfoById
}
+26
View File
@@ -0,0 +1,26 @@
/* 合同管理 对接其他IOP系统的api */
import {getAction, postAction} from './manage'
// let apiBaseUrl = '/openApi'
// 获得 access_token
const getAccessToken = (params) => postAction(`payResearchProject/payResearchProject/getToken`,params)
// const getAccessToken = (params) => postAction(`https://openapi.catarc.ac.cn/login`,params)
// 刷新 access_token
const refreshToken = (params) => postAction('/payResearchProject/payResearchProject/refreshToken',params)
//合同台账分页查询接口
const getContractPage = (params) => postAction('/payResearchProject/payResearchProject/pageForThreeContractPage',params)
//合同台账列表查询接口
const getContractList = (params) => postAction('/payResearchProject/payResearchProject/listForThreeContract',params)
//合同台账详情接口
const getContractById = (params) => getAction(`/payResearchProject/payResearchProject/oneForThreeContract`,params)
// 通过 公司名称获取公司的相关信息
const getCompanyByName = (params) => getAction(`/company/payCompanyManagement/getCompanyByName`,params)
export {
getAccessToken,
refreshToken,
getContractPage,
getContractList,
getContractById,
getCompanyByName
}
+46
View File
@@ -0,0 +1,46 @@
import {getAction, postAction} from '@api/manage'
// 通过用户id获取用户信息
const getUserInfo = (params) => getAction('/sys/user/queryById',params)
// 通过会议id获取会议的详细信息
const getMeetInfoById = (params) => getAction('/meeting/payMeeting/queryById',params)
// 获取所有工作组项目
const getAllWorkProjects = () => getAction('/project/payWorkingGroup/listAll')
// 通过id获取参会人详细信息
const getSingUpUserInfo = (params) => getAction('/meeting/payMeetingSituation/queryById',params)
// 生成会议二维码
const createQcCode = (params) => getAction('/meeting/payMeeting/createBase64',params)
// 收入合同的新增会员项目的查询
const queryContractMemberProject = (params) => getAction('/jero/memberProject/queryListByNotCompany',params)
// 通过单位名称校验是否标协会员
const validateStandard = (params) => getAction('/meeting/internalMeetingSituation/checkMember',params)
// 国际研讨会--已经生成的随机码列表页的查询
const getGeneratedCodeList = (params) => getAction('/meeting/randomCode/link/page', params)
// 国际研讨会--生成随机码方法
const generateCode = (params) => postAction('/meeting/randomCode/generate', params)
// 国际研讨会--列表页新增一条随机码数据
const addGenerateCodeList = (params) => postAction('/meeting/randomCode/add', params)
// 国际研讨会--列表页编辑一条随机码数据
const editGenerateCodeList = (params) => postAction('/meeting/randomCode/edit', params)
// 标协会议-问题征集详情-查询标准号下拉框数据
const getStandardNumberList = (params) => getAction('/meeting/standardsMeeting/getStandardNumberList', params)
export {
getUserInfo,
getMeetInfoById,
getAllWorkProjects,
getSingUpUserInfo,
createQcCode,
queryContractMemberProject,
validateStandard,
getGeneratedCodeList,
generateCode,
addGenerateCodeList,
editGenerateCodeList,
getStandardNumberList
}
+201
View File
@@ -0,0 +1,201 @@
import { getAction, postAction } from '@api/manage'
// 通过id获取工作组详情
const getWorkingGroupById = (params) => getAction('/project/payWorkingGroup/queryById', params)
// 判断工作组成员是否设置来款通知
const getChargeNotice = (param) => getAction('/project/payWorkingGroupSubitem/getCharge', param)
// 工作组会议的发布提醒
const publishRemind = (param) => postAction('/meeting/workGroupMeeting/publishReminder', param)
// 分标委会议的发布提醒
const commitePublishRemind = (param) => postAction('/meeting/committeeMeeting/publishReminder',param)
// 理事会的发布提醒
const councilPublishRemind = (param) => postAction('/meeting/councilMeeting/publishReminder',param)
// 通过id获取收入合同信息
const getRevenueContractById = (param) => getAction('/contract/payIncomeContract/queryById', param)
// 收入合同审核
const aduitRevenueContract = (param) => postAction('/contract/payIncomeContract/audit', param)
// 收入合同关联项目
const associatedProject = (param) => postAction('/contract/payIncomeContract/associated', param)
// 收入合同获取关联项目列表
const getAssociatedProject = (param) => getAction('/contract/payIncomeContract/getAssociated', param)
// 取消关联
const cancelAssociatedProject = (param) => postAction('/contract/payIncomeContract/cancelAssociated', param)
// 收入合同提交审核
const submitAudit = (param) => postAction('/contract/payIncomeContract/submitAudit', param)
// 获取不存在成员单位的工作组信息
const getWorkingGroupListByNotCompany = (param) => getAction('/project/payWorkingGroup/queryListByNotCompany', param)
// 收入合同存档
const archiveRevenueContract = (param) => postAction('/contract/payIncomeContract/archive', param)
// 根据部门id获取用户信息
const queryUserByDepartId = (param) => getAction('/sys/user/listRoleAndDepart', param)
// 企业联系人新建重名校验
const queryContactByName = (param) => getAction('/company/payContactsManagement/queryByName', param)
// 通过id获取支出合同信息
const getExpenditureContractById = (param) => getAction('/contract/paySpendingContract/queryById', param)
// 添加来款阶段
const addPaymentPhase = (param) => postAction('/paymentRecord/payPaymentRecord/addAmountReceived', param)
// 编辑来款阶段
const editAmountPhase = (param) => postAction('/paymentRecord/payPaymentRecord/editAmountReceived', param)
// 来款列表
const amountReceivedList = (param) => postAction(`/paymentRecord/payPaymentRecord/amountReceivedList?id=${ param }`)
// 开票列表
const payBillList = (param) => postAction(`/paymentRecord/payPaymentRecord/payBillList?id=${ param }`)
// 新增开票阶段
const addPayBill = (param) => postAction(`/paymentRecord/payPaymentRecord/addPayBill`, param)
// 编辑开票阶段
const editPayBill = (param) => postAction('/paymentRecord/payPaymentRecord/editPayBill', param)
// 普通项目管理-通过项目id查询其他的信息
const queryCommonProjectById = (param) => getAction('/project/payCommonProject/queryById', param)
// 通过id查询打包企业信息
const getPackCompanyById = (param) => getAction('/pack/payPackCompany/queryById', param)
// 添加打包项目
const addPackProject = (param) => postAction('/pack/payPackCompanyProject/add', param)
// 取消打包
const removePackProject = (param) => postAction('/pack/payPackCompanyProject/remove', param)
// 批量取消打包
const batchRemovePackProject = (param) => postAction('/pack/payPackCompanyProject/removeBatch', param)
// 企业管理审核
const aduitCompany = (param) => getAction('/company/payCompanyManagement/audit', param)
// 企业管理删除确认是否有联系人
const checkContactByCompany = (param) => getAction('/company/payCompanyManagement/queryCompanyByIdFindContacts', param)
// 资料分发
const distribute = (param) => postAction('/project/payWorkingGroupDistributionRecord/add', param)
// 资料批量分发
const batchDistribute = (param) => postAction('/project/payWorkingGroupDistributionRecord/addBatch', param)
// 资料分发成员列表
const distributeMemberList = (param) => getAction('/project/payWorkingGroupDistributionRecord/list', param)
// 催款提醒
const dunningReminder = (param) => postAction('/project/payWorkingGroupSubitem/reminders', param)
// 复制工作组
const copyWorkingGroup = (param) => postAction('/project/payWorkingGroup/copy', param)
// 校验登陆人是否可以操作工作组
const checkoutWorkingGroupPrincipal = (param) => getAction('/project/payWorkingGroup/checkoutOperation', param)
// 首页统计图接口
const homePageStatistics = (param) => getAction('/statistics/principalPeople/firstPage', param)
// 首页数据统计
const homePageDataStatistics = (param) => getAction('/home/dataStatistics', param)
// 系统催款
const sysReminders = (param) => postAction('/reminders/edit', param)
// 检测企业审核是否通过
const checkCompanyAduit = (param) => getAction('/payMailContract/payMailContract/check', param)
// 获取全部部门
const getAllDepartTreeList = (param) => getAction('/sys/sysDepart/queryTreeAllList', param)
// 验证项目是否关联合同
const getIsAssociatedProject = (param) => getAction('/contract/payIncomeContract/getAssociatedProject', param)
// 支出合同审核
const aduitExpenditureContract = (param) => postAction('/contract/paySpendingContract/audit', param)
// 支出合同存档
const archiveExpenditureContract = (param) => postAction('/contract/paySpendingContract/archive', param)
// 获取全部收入合同(通过企业id查询列表)
const getAllRevenueContract = (param) => getAction('/contract/payIncomeContract/queryByCompanyId', param)
// 打印获取邮寄联系人信息接口,传票据邮寄列表id
const getPrintPostContactByMailId = (param) => getAction('/mail/payMailBill/print', param)
// 全所统计--通过部门code查所有人员
const getUserByDepartCode = (param) => getAction('/statistics/allProjectStatistics/listForUserByOrgCode', param)
// 收入合同--作废
const cancellationContract = (param) => postAction('/contract/payIncomeContract/cancellation', param)
// 支出合同--作废
const cancellationExpenditureContract = (param) => postAction('/contract/paySpendingContract/cancellation', param)
// 到账开票审核缴费凭证时获取最新一条缴费信息(普通项目、工作组项目、资料网员)
const getLastProofInfo = (param) => getAction('/paymentCheck/payPaymentCheck/getLastRecord', param)
// 到账开票审核缴费凭证时获取最新一条缴费信息(标协会员)
const getStanderMemberLastProofInfo = (param) => getAction('/paymentCheck/payPaymentCheck/getTbMemberProject', param)
// 到账开票审核缴费凭证时获取最新一条缴费信息(标协证书)
const getCertificateLastProofInfo = (param) => getAction('/paymentCheck/payPaymentCheck/getTbCertificatePayment', param)
// 通过合同邮寄表id获取邮寄详情
const queryMailDetailById = (param) => getAction('/payMailContract/payMailContract/queryById', param)
// 修改企业是否是内部企业的接口
const updateInternalEnterprise = (param) => postAction('/company/payCompanyManagement/updateInternalEnterprise', param)
// 判断当前企业是否是内部企业
const judgeInternalEnterprise = (param) => getAction('/company/payCompanyManagement/getInternalEnterprise', param)
// 更新会员系统 会员缴费的发票信息
const incomingUpdatePayment = (param) => postAction('/member/tbMemberProjectSubitem/incomingUpdatePayment', param)
// 更新会员系统 证书缴费的发票信息
const incomingUpdateCertificate = (param) => postAction('/member/tbCertificatePayment/incomingUpdateCertificate', param)
// 撤销来款
const revokeIncome = (params) => postAction(`/paymentRecord/payPaymentRecord/revoke?id=${params}`)
// 确认来款- 查询当前项目是否有来款信息
const getPayConfirmList = (param) => getAction('/payConfirmPaymentRecord/list', param)
// 新增一个确认来款信息
const addPayConfirm = (param) => postAction('/payConfirmPaymentRecord/add', param)
// 编辑一个确认来款信息
const editPayConfirm = (param) => postAction('/payConfirmPaymentRecord/edit', param)
//2023-07-13 工作组相关功能的接口
// 判断当前节点 是否可以发邮件
const judgeEmailStatus = (param) => getAction('/sys/message/sysMessageTemplate/queryByCode', param)
export {
getWorkingGroupById,
getChargeNotice,
publishRemind,
commitePublishRemind,
getRevenueContractById,
aduitRevenueContract,
associatedProject,
getAssociatedProject,
cancelAssociatedProject,
submitAudit,
getWorkingGroupListByNotCompany,
archiveRevenueContract,
queryUserByDepartId,
queryContactByName,
getExpenditureContractById,
addPaymentPhase,
editAmountPhase,
amountReceivedList,
payBillList,
addPayBill,
editPayBill,
queryCommonProjectById,
getPackCompanyById,
addPackProject,
removePackProject,
revokeIncome,
batchRemovePackProject,
aduitCompany,
checkContactByCompany,
distribute,
batchDistribute,
distributeMemberList,
dunningReminder,
copyWorkingGroup,
checkoutWorkingGroupPrincipal,
homePageStatistics,
homePageDataStatistics,
sysReminders,
checkCompanyAduit,
getAllDepartTreeList,
getIsAssociatedProject,
aduitExpenditureContract,
archiveExpenditureContract,
getAllRevenueContract,
getPrintPostContactByMailId,
getUserByDepartCode,
cancellationContract,
councilPublishRemind,
cancellationExpenditureContract,
getLastProofInfo,
getStanderMemberLastProofInfo,
getCertificateLastProofInfo,
queryMailDetailById,
updateInternalEnterprise,
judgeInternalEnterprise,
incomingUpdatePayment,
incomingUpdateCertificate,
getPayConfirmList,
addPayConfirm,
editPayConfirm,
judgeEmailStatus
}
+10
View File
@@ -0,0 +1,10 @@
const api = {
Login: '/sys/login',
Logout: '/sys/logout',
ForgePassword: '/auth/forge-password',
Register: '/auth/register',
SendSms: '/account/sms',
// get my info
UserInfo: '/user/info'
}
export default api
+89
View File
@@ -0,0 +1,89 @@
import api from './index'
import { axios } from '@/utils/request'
/**
* login func
* parameter: {
* username: '',
* password: '',
* remember_me: true,
* captcha: '12345'
* }
* @param parameter
* @returns {*}
*/
export function login(parameter) {
return axios({
url: '/sys/login',
method: 'post',
data: parameter
})
}
export function phoneLogin(parameter) {
return axios({
url: '/sys/phoneLogin',
method: 'post',
data: parameter
})
}
export function getSmsCaptcha(parameter) {
return axios({
url: api.SendSms,
method: 'post',
data: parameter
})
}
// export function getInfo() {
// return axios({
// url: '/api/user/info',
// method: 'get',
// headers: {
// 'Content-Type': 'application/json;charset=UTF-8'
// }
// })
// }
export function logout(logoutToken) {
return axios({
url: '/sys/logout',
method: 'post',
headers: {
'Content-Type': 'application/json;charset=UTF-8',
'X-Access-Token': logoutToken
}
})
}
/**
* 第三方登录
* @param token
* @param thirdType
* @returns {*}
*/
export function thirdLogin(token,thirdType) {
return axios({
url: `/sys/thirdLogin/getLoginUser/${token}/${thirdType}`,
method: 'get',
headers: {
'Content-Type': 'application/json;charset=UTF-8'
}
})
}
/**
* 获取RSA公钥
* @returns {*}
*/
export function getRSAPublicKey() {
return axios({
url: `/sys/getRSAPublicKey`,
method: 'get',
timeout: 5000,
headers: {
'Content-Type': 'application/json;charset=UTF-8'
}
})
}
+223
View File
@@ -0,0 +1,223 @@
import Vue from 'vue'
import { axios } from '@/utils/request'
const api = {
user: '/mock/api/user',
role: '/mock/api/role',
service: '/mock/api/service',
permission: '/mock/api/permission',
permissionNoPager: '/mock/api/permission/no-pager'
}
export default api
//post
export function postAction(url,parameter) {
return axios({
url: url,
method:'post' ,
data: parameter
})
}
//post method= {post | put}
export function httpAction(url,parameter,method) {
return axios({
url: url,
method:method ,
data: parameter
})
}
//put
export function putAction(url,parameter) {
return axios({
url: url,
method:'post',
data: parameter
})
}
//get
export function getAction(url,parameter) {
return axios({
url: url,
method: 'get',
params: parameter
})
}
//deleteAction
export function deleteAction(url,parameter) {
return axios({
url: url,
method: 'delete',
params: parameter
})
}
export function getUserList(parameter) {
return axios({
url: api.user,
method: 'get',
params: parameter
})
}
export function getRoleList(parameter) {
return axios({
url: api.role,
method: 'get',
params: parameter
})
}
export function getServiceList(parameter) {
return axios({
url: api.service,
method: 'get',
params: parameter
})
}
export function getPermissions(parameter) {
return axios({
url: api.permissionNoPager,
method: 'get',
params: parameter
})
}
// id == 0 add post
// id != 0 update put
export function saveService(parameter) {
return axios({
url: api.service,
method: parameter.id == 0 ? 'post' : 'put',
data: parameter
})
}
/**
* 下载文件 用于excel导出
* @param url
* @param parameter
* @returns {*}
*/
export function downFile(url,parameter){
return axios({
url: url,
params: parameter,
method:'get' ,
responseType: 'blob'
})
}
/**
* 通过A标签下载文件的通用方法
* @param data--接口返回的数据
* @param fileName --下载文件的名称
*/
export function downloadFileByA(data, fileName) {
// 当没有返回数据或者返回错误信息的时候,对数据进行解析后提示
if (!data || data.type === 'application/json') {
const reader = new FileReader()
reader.readAsText(data)
// 处理load事件。该事件在读取操作完成时触发
reader.onload = e => {
// 解析返回的值
const res = JSON.parse(e.target.result)
// 异常信息抛出
if (!res.success) {
Vue.prototype['$message'].warning(res.message || '文件下载失败')
}
}
return
}
// if (!data || data.size === 0) {
// Vue.prototype['$message'].warning('文件下载失败')
// return
// }
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(new Blob([data]), fileName)
} else {
let url = window.URL.createObjectURL(new Blob([data]))
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
document.body.removeChild(link) //下载完成移除元素
window.URL.revokeObjectURL(url) //释放掉blob对象
}
}
/**
* get请求下载文件
* @param url 文件路径
* @param fileName 文件名
* @param parameter
* @returns {*}
*/
export function downloadFile(url, fileName, parameter) {
return downFile(url, parameter).then((data) => {
// 调用a标签下载文件的方法
downloadFileByA(data, fileName)
})
}
/**
* post下载文件
* @param url 文件路径
* @param fileName 文件名
* @param parameter
* @returns {*}
*/
export function downloadPostFile(url, fileName, parameter) {
return axios({
url: url,
data: parameter,
method: 'post',
responseType: 'blob'
}).then((data) => {
// 调用a标签下载文件的方法
downloadFileByA(data, fileName)
})
}
/**
* 文件上传 用于富文本上传图片
* @param url
* @param parameter
* @returns {*}
*/
export function uploadAction(url,parameter){
return axios({
url: url,
data: parameter,
method:'post' ,
headers: {
'Content-Type': 'multipart/form-data', // 文件上传
},
})
}
/**
* 获取文件服务访问路径
* @param avatar
* @param subStr
* @returns {*}
*/
export function getFileAccessHttpUrl(avatar,subStr) {
if(!subStr) subStr = 'http'
try {
if(avatar && avatar.startsWith(subStr)){
return avatar
}else{
if(avatar && avatar.length>0 && avatar.indexOf('[')==-1){
return window._CONFIG['staticDomainURL'] + '/' + avatar
}
}
}catch(err){
return
}
}
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 690 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 801 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 943 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 949 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 851 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 546 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 687 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

+275
View File
@@ -0,0 +1,275 @@
.area-zoom-in-top-enter-active,
.area-zoom-in-top-leave-active {
opacity: 1;
transform: scaleY(1);
}
.area-zoom-in-top-enter,
.area-zoom-in-top-leave-active {
opacity: 0;
transform: scaleY(0);
}
.area-select {
box-sizing: border-box;
margin: 0;
padding: 0;
color: rgba(0, 0, 0, 0.65);
font-size: 14px;
font-variant: tabular-nums;
line-height: 1.5;
list-style: none;
font-feature-settings: 'tnum';
position: relative;
outline: 0;
display: block;
background-color: #fff;
border: 1px solid #d9d9d9;
border-top-width: 1.02px;
border-radius: 4px;
outline: none;
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}
.area-select-wrap .area-select {
display: inline-block;
}
.area-select * {
box-sizing: border-box;
}
.area-select:hover {
border-color: #40a9ff;
border-right-width: 1px !important;
outline: 0;
}
.area-select:active {
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
.area-select.small {
width: 126px;
}
.area-select.medium {
width: 160px;
}
.area-select.large {
width: 194px;
}
.area-select.is-disabled {
background: #eceff5;
cursor: not-allowed;
}
.area-select.is-disabled:hover {
border-color: #e1e2e6;
}
.area-select.is-disabled .area-selected-trigger {
cursor: not-allowed;
}
.area-select .area-selected-trigger {
position: relative;
display: block;
font-size: 14px;
cursor: pointer;
margin: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
height: 100%;
padding: 8px 20px 7px 12px;
}
.area-select .area-select-icon {
position: absolute;
top: 50%;
margin-top: -2px;
right: 6px;
content: "";
width: 0;
height: 0;
border: 6px solid transparent;
border-top-color: rgba(0, 0, 0, 0.25);
transition: all .3s linear;
transform-origin: center;
}
.area-select .area-select-icon.active {
margin-top: -8px;
transform: rotate(180deg);
}
.area-selectable-list-wrap {
position: absolute;
width: 100%;
max-height: 275px;
z-index: 15000;
background-color: #fff;
box-sizing: border-box;
overflow-x: auto;
margin: 2px 0;
border-radius: 4px;
outline: none;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
transition: opacity 0.15s, transform 0.3s !important;
transform-origin: center top !important;
}
.area-selectable-list {
position: relative;
margin: 0;
padding: 6px 0;
width: 100%;
font-size: 14px;
color: #565656;
list-style: none;
}
.area-selectable-list .area-select-option {
position: relative;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
cursor: pointer;
padding: 0 15px 0 10px;
height: 32px;
line-height: 32px;
}
.area-selectable-list .area-select-option.hover {
background-color: #e6f7ff;
}
// 请选择省市placeholder 为灰色
.placeholderGray .area-selected-trigger {
color: rgb(191,191,191);
}
.area-selectable-list .area-select-option.selected {
color: rgba(0, 0, 0, 0.65);
font-weight: 600;
background-color: #efefef;
}
.cascader-menu-list-wrap {
position: absolute;
white-space: nowrap;
z-index: 15000;
background-color: #fff;
box-sizing: border-box;
overflow: hidden;
font-size: 0;
margin: 2px 0;
border-radius: 4px;
outline: none;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
transition: opacity 0.15s, transform 0.3s !important;
transform-origin: center top !important;
}
.cascader-menu-list {
position: relative;
margin: 0;
font-size: 14px;
color: #565656;
padding: 6px 0;
list-style: none;
display: inline-block;
height: 204px;
overflow-x: hidden;
overflow-y: auto;
min-width: 160px;
vertical-align: top;
background-color: #fff;
border-right: 1px solid #e4e7ed;
}
.cascader-menu-list:last-child {
border-right: none;
}
.cascader-menu-list .cascader-menu-option {
position: relative;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
cursor: pointer;
padding: 0 15px 0 10px;
height: 32px;
line-height: 32px;
}
.cascader-menu-list .cascader-menu-option.hover,
.cascader-menu-list .cascader-menu-option:hover {
background-color: #e6f7ff;
}
.cascader-menu-list .cascader-menu-option.selected {
color: rgba(0, 0, 0, 0.65);
font-weight: 600;
background-color: #efefef;
}
.cascader-menu-list .cascader-menu-option.cascader-menu-extensible:after {
position: absolute;
top: 50%;
margin-top: -4px;
right: 5px;
content: "";
width: 0;
height: 0;
border: 4px solid transparent;
border-left-color: #a1a4ad;
}
.cascader-menu-list::-webkit-scrollbar,
.area-selectable-list-wrap::-webkit-scrollbar {
width: 8px;
background: transparent;
}
.area-selectable-list-wrap::-webkit-scrollbar-button:vertical:decremen,
.area-selectable-list-wrap::-webkit-scrollbar-button:vertical:end:decrement,
.area-selectable-list-wrap::-webkit-scrollbar-button:vertical:increment,
.area-selectable-list-wrap::-webkit-scrollbar-button:vertical:start:increment,
.cascader-menu-list::-webkit-scrollbar-button:vertical:decremen,
.cascader-menu-list::-webkit-scrollbar-button:vertical:end:decrement,
.cascader-menu-list::-webkit-scrollbar-button:vertical:increment,
.cascader-menu-list::-webkit-scrollbar-button:vertical:start:increment {
display: none;
}
.cascader-menu-list::-webkit-scrollbar-thumb:vertical,
.area-selectable-list-wrap::-webkit-scrollbar-thumb:vertical {
background-color: #b8b8b8;
border-radius: 4px;
}
.cascader-menu-list::-webkit-scrollbar-thumb:vertical:hover,
.area-selectable-list-wrap::-webkit-scrollbar-thumb:vertical:hover {
background-color: #777;
}
.ant-pagination-disabled i{
cursor: not-allowed!important;
}
.urge-num{
color:red;
margin-left: 4px;
}
+15
View File
@@ -0,0 +1,15 @@
/** [表格主题样式一] 表格强制列不换行 */
.j-table-force-nowrap {
td, th {
white-space: nowrap;
}
.ant-table-selection-column {
padding: 12px 22px !important;
}
/** 列自适应,弊端会导致列宽失效 */
&.ant-table-wrapper .ant-table-content {
overflow-x: auto;
}
}
+119
View File
@@ -0,0 +1,119 @@
/*列表上方操作按钮区域*/
.ant-card-body .table-operator {
margin-bottom: 8px;
}
/** Button按钮间距 */
.table-operator .ant-btn {
margin: 0 8px 8px 0;
}
.table-operator .ant-btn-group .ant-btn {
margin: 0;
}
.table-operator .ant-btn-group .ant-btn:last-child {
margin: 0 8px 8px 0;
}
/*列表td的padding设置 可以控制列表大小*/
.ant-table-tbody .ant-table-row td {
padding-top: 15px;
padding-bottom: 15px;
}
/*列表页面弹出modal*/
.ant-modal-cust-warp {
height: 100%
}
/*弹出modal Y轴滚动条*/
.ant-modal-cust-warp .ant-modal-body {
height: calc(100% - 110px) !important;
overflow-y: auto
}
/*弹出modal 先有content后有body 故滚动条控制在body上*/
.ant-modal-cust-warp .ant-modal-content {
height: 90% !important;
overflow-y: hidden
}
/*列表中有图片的加这个样式 参考用户管理*/
.anty-img-wrap {
height: 25px;
position: relative;
}
.anty-img-wrap > img {
max-height: 100%;
}
/*列表中范围查询样式*/
.query-group-cust{width: calc(50% - 10px)}
.query-group-split-cust:before{content:"~";width: 20px;display: inline-block;text-align: center}
/*erp风格子表外框padding设置*/
.ant-card-wider-padding.cust-erp-sub-tab>.ant-card-body{padding:5px 12px}
/* 内嵌子表背景颜色 */
.j-inner-table-wrapper /deep/ .ant-table-expanded-row .ant-table-wrapper .ant-table-tbody .ant-table-row {
background-color: #FFFFFF;
}
/**隐藏样式-modal确定按钮 */
.jee-hidden{display: none}
/*列表td的padding设置 可以控制列表大小*/
.ant-table-tbody .ant-table-row td .action-span-cell a + a{
padding-left: 20px;
}
.primary-color{
color: #069f99;
cursor: pointer;
}
// 标题及标题前的圆点
.part-title {
padding: 10px 0;
font-size: 16px;
font-family: PingFang SC, PingFang SC-Bold;
font-weight: 700;
text-align: left;
color: #333333;
display: flex;
align-items: center;
position: relative;
&-text {
padding-left: 20px;
}
&-text::before {
position: absolute;
content: "";
left: 0;
top: 50%;
transform: translateY(-50%);
width: 10px;
height: 10px;
background: #069f99;
border-radius: 5px;
}
}
/*重置按钮*/
.reset-button {
color: #08B6AF;
background: rgba(8,182,175,0.10);
border: 1px solid #08b6af;
}
/*表格滚动条*/
.ant-table-body {
overflow-x: auto!important;
}
/*列表自适应超出隐藏*/
.table-text {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

View File
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 567 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 664 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 846 B

+130
View File
@@ -0,0 +1,130 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br />
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener"
>vue-cli documentation</a
>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li>
<a
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel"
target="_blank"
rel="noopener"
>babel</a
>
</li>
<li>
<a
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router"
target="_blank"
rel="noopener"
>router</a
>
</li>
<li>
<a
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex"
target="_blank"
rel="noopener"
>vuex</a
>
</li>
<li>
<a
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint"
target="_blank"
rel="noopener"
>eslint</a
>
</li>
</ul>
<h3>Essential Links</h3>
<ul>
<li>
<a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a>
</li>
<li>
<a href="https://forum.vuejs.org" target="_blank" rel="noopener"
>Forum</a
>
</li>
<li>
<a href="https://chat.vuejs.org" target="_blank" rel="noopener"
>Community Chat</a
>
</li>
<li>
<a href="https://twitter.com/vuejs" target="_blank" rel="noopener"
>Twitter</a
>
</li>
<li>
<a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a>
</li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li>
<a href="https://router.vuejs.org" target="_blank" rel="noopener"
>vue-router</a
>
</li>
<li>
<a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a>
</li>
<li>
<a
href="https://github.com/vuejs/vue-devtools#vue-devtools"
target="_blank"
rel="noopener"
>vue-devtools</a
>
</li>
<li>
<a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener"
>vue-loader</a
>
</li>
<li>
<a
href="https://github.com/vuejs/awesome-vue"
target="_blank"
rel="noopener"
>awesome-vue</a
>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String,
},
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
+49
View File
@@ -0,0 +1,49 @@
<template>
<j-modal
:title="title"
:width="width"
:visible="visible"
:confirmLoading="confirmLoading"
switchFullscreen
@cancel="handleCancel"
cancelText="关闭">
<img :src="imgSrc" class="preview-img">
<template slot="footer">
<a-button @click="handleCancel">关闭</a-button>
</template>
</j-modal>
</template>
<script>
export default {
name: 'PreviewImgModal',
data() {
return {
title: '图片',
width: 800,
visible: false,
confirmLoading: false,
// 图片id
imgId: ''
}
},
computed: {
imgSrc() {
return `${ window._CONFIG['domianURL'] }/sys/common/download/${ this.imgId }`
}
},
methods: {
handleCancel() {
this.visible = false
}
}
}
</script>
<style scoped>
.preview-img {
width: 100%;
}
</style>
+99
View File
@@ -0,0 +1,99 @@
<!--进度组件-->
<template>
<div>
<!-- 三项非全0-->
<div class="progress" v-if="(data.allPayment + data.partPayment + data.notPayment) !== 0">
<!-- 将全部付款和部分付款放入一个div中-->
<div class="full-and-partial"
:style="{width: (data.allPayment + data.partPayment)/(data.allPayment + data.partPayment + data.notPayment) * 100 + '%'}">
<!-- 全部付款-->
<div :style="{width: data.allPayment/(data.allPayment + data.partPayment) * 100 + '%'}"
class="progress-item pay-in-full" v-if="data.allPayment !== 0">
{{ data.allPayment }}
</div>
<!-- 部分付款-->
<div :style="{width: data.partPayment/(data.allPayment + data.partPayment) * 100 + '%'}"
class="progress-item partial-payment" v-if="data.partPayment !== 0">
{{ data.partPayment }}
</div>
</div>
<div :style="{width: data.notPayment/(data.allPayment + data.partPayment + data.notPayment) * 100 + '%'}"
class="progress-item non-payment" v-if="data.notPayment !== 0">
{{ data.notPayment }}
</div>
</div>
<!-- 三项均为0-->
<div class="progress progress-null" v-else>0</div>
</div>
</template>
<script>
export default {
name: 'ProgressBar',
props: {
/**
* 进度字段,
* {
* allPayment: 10, // 已付全款
* partPayment: 10, // 部分付款
* notPayment: 10, // 未付款
* }
*/
data: {
type: Object,
required: false,
default: () => {
return {}
}
}
}
}
</script>
<style scoped lang="less">
.progress {
border-radius: 10px;
background: #e8e8e8;
height: 20px;
width: 100%;
display: flex;
overflow: hidden;
&-null {
justify-content: center;
}
}
.no-display {
display: none;
}
.full-and-partial {
background: linear-gradient(0deg, #0075a9 0%, #008dcc 100%);
display: flex;
border-radius: 10px;
box-sizing: border-box;
}
.progress-item {
height: 20px;
border-radius: 10px;
color: white;
line-height: 20px;
text-align: center;
box-sizing: border-box;
}
.pay-in-full {
background: linear-gradient(0deg, #069f99 0%, #07b1aa 100%);
}
.partial-payment {
background: linear-gradient(0deg, #0075a9 0%, #008dcc 100%);
}
.non-payment {
color: #57635e;
background: #e8e8e8;
}
</style>
+631
View File
@@ -0,0 +1,631 @@
<template>
<j-modal
:title="title"
:width="width"
:visible="visible"
switchFullscreen
@cancel="handleCancel"
cancelText="关闭">
<!-- 基本信息begin-->
<section class="base-info">
<h3 class="title">基本信息</h3>
<a-row :gutter="24">
<a-col :span="12" class="detail-item">
<label>项目负责人</label>
<span><j-ellipsis :value="basicInfo.principalName" :length="20"></j-ellipsis></span>
</a-col>
<a-col :span="12" class="detail-item">
<label>待确收金额</label>
<span><j-ellipsis :value="`${basicInfo.receivableAmount ? basicInfo.receivableAmount : '0.00'}元`"
:length="20"></j-ellipsis></span>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12" class="detail-item">
<label>税率</label>
<span><j-ellipsis :value="basicInfo.taxRate_dictText" :length="20"></j-ellipsis></span>
</a-col>
<a-col :span="12" class="detail-item">
<label>税额</label>
<span><j-ellipsis :value="`${basicInfo.tax ? basicInfo.tax : '0.00'}元`"
:length="20"></j-ellipsis></span>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12" class="detail-item">
<label>未税金额</label>
<span><j-ellipsis :value="`${basicInfo.noTaxAmount ? basicInfo.noTaxAmount : '0.00'}元`"
:length="20"></j-ellipsis></span>
</a-col>
<a-col :span="12" class="detail-item">
<label>是否需要发票</label>
<span>{{ basicInfo.needInvoice_dictText }}</span>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12" class="detail-item">
<label>是否打包</label>
<span>{{ basicInfo.pack_dictText }}</span>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col class="detail-item">
<label>备注</label>
<span><j-ellipsis :value="basicInfo.remarks" :length="20"></j-ellipsis></span>
</a-col>
</a-row>
<!-- 来款方式为合同的显示-->
<a-row :gutter="24" v-if="basicInfo.chargeWay === 2">
<a-col :span="12" class="detail-item">
<label>{{ createIncomeType(basicInfo.projectType) }}</label>
<span>{{ basicInfo.chargeWay_dictText }}</span>
</a-col>
<a-col :span="12" class="detail-item">
<label>合同编号</label>
<span class="contract-num" @click="toContractDetail">{{ basicInfo.contractNum }}</span>
</a-col>
</a-row>
<a-row :gutter="24" v-if="basicInfo.chargeWay === 3">
<a-col :span="12" class="detail-item">
<label>收费通知号</label>
<span><j-ellipsis :value="basicInfo.chargeNoticeNo" :length="20"></j-ellipsis></span>
</a-col>
<a-col :span="12" class="detail-item">
<label>收费通知</label>
<span><preview-file :file-id="basicInfo.chargeNoticeId"></preview-file></span>
</a-col>
</a-row>
<a-row :gutter="24" v-if="basicInfo.files">
<a-col class="detail-item">
<label>项目资料</label>
<span><preview-file :file-id="basicInfo.files"></preview-file></span>
</a-col>
</a-row>
</section>
<!-- 基本信息end-->
<!-- 企业信息begin-->
<section class="enterprise-info">
<h3 class="title">企业信息</h3>
<a-row :gutter="24">
<a-col :span="12" class="detail-item">
<label>来款企业</label>
<span><j-ellipsis :value="basicInfo.companyName" :length="20"></j-ellipsis></span>
</a-col>
<a-col :span="12" class="detail-item">
<label>信用代码</label>
<span><j-ellipsis :value="basicInfo.dutyCode" :length="20"></j-ellipsis></span>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12" class="detail-item">
<label>公司地址</label>
<span><j-ellipsis :value="basicInfo.companyAddress" :length="20"></j-ellipsis></span>
</a-col>
<a-col :span="12" class="detail-item">
<label>公司电话</label>
<span><j-ellipsis :value="basicInfo.companyPhone" :length="20"></j-ellipsis></span>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12" class="detail-item">
<label>邮编</label>
<span>{{ basicInfo.postalCodeCompany }}</span>
</a-col>
<a-col :span="12" class="detail-item">
<label>银行户名</label>
<span>{{ basicInfo.bankAccountName }}</span>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12" class="detail-item">
<label>开户行</label>
<span>{{ basicInfo.openingBank }}</span>
</a-col>
<a-col :span="12" class="detail-item">
<label>银行账号</label>
<span>{{ basicInfo.bankAccount }}</span>
</a-col>
<a-col :span="12" class="detail-item">
<label>联行号</label>
<span>{{ basicInfo.linkBankNumber || '' }}</span>
</a-col>
</a-row>
</section>
<!--企业信息end-->
<!-- 代付企业--第三方垫付 信息 只有会员缴费 和证书缴费的时候存在 begin-->
<section class="enterprise-info" v-if="(basicInfo.projectType === ProjectTypeEnums.STANDARD_MEMBER_PRO.value || basicInfo.projectType === ProjectTypeEnums.STANDARD_CERTIFICATE_PRO.value) && hasOtherCompany">
<h3 class="title">第三方垫付信息</h3>
<a-row :gutter="24">
<a-col :span="12" class="detail-item">
<label>付款单位发票抬头</label>
<span><j-ellipsis :value="otherCompanyInfo.headerName" :length="20"></j-ellipsis></span>
</a-col>
<a-col :span="12" class="detail-item">
<label>社会统一代码/税号</label>
<span><j-ellipsis :value="otherCompanyInfo.taxNumber" :length="20"></j-ellipsis></span>
</a-col>
</a-row>
<!-- 增值税发票存在的信息较多-->
<template v-if="Number(otherCompanyInfo.invoiceRequirements) === 2">
<a-row :gutter="24">
<a-col :span="12" class="detail-item">
<label>单位地址</label>
<span><j-ellipsis :value="otherCompanyInfo.invoiceAddress" :length="20"></j-ellipsis></span>
</a-col>
<a-col :span="12" class="detail-item">
<label>电话号码</label>
<span><j-ellipsis :value="otherCompanyInfo.invoicePhone" :length="20"></j-ellipsis></span>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12" class="detail-item">
<label>开户银行</label>
<span>{{ otherCompanyInfo.depositBank }}</span>
</a-col>
<a-col :span="12" class="detail-item">
<label>银行账户</label>
<span>{{ otherCompanyInfo.bankAccount }}</span>
</a-col>
<a-col :span="12" class="detail-item">
<label>联行号</label>
<span>{{ otherCompanyInfo.linkBankNumber || '' }}</span>
</a-col>
</a-row>
</template>
</section>
<!--代付企业--第三方垫付 信息end-->
<!-- 企业联系人信息start-->
<section>
<h3 class="title">企业联系人信息</h3>
<!-- 项目类型不是工作组正常显示一个企业联系人的信息-->
<template v-if="basicInfo.projectType !== 2">
<a-row :gutter="24">
<a-col :span="12">
<label>企业联系人</label>
<span>{{ basicInfo.name }}</span>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12">
<label>企业联系人性别</label>
<span>{{ basicInfo.gender_dictText }}</span>
</a-col>
<a-col :span="12" class="detail-item">
<label>企业联系人职务</label>
<span><j-ellipsis :value="basicInfo.post" :length="17"></j-ellipsis></span>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12" class="detail-item">
<label>企业联系人电话</label>
<span>{{ basicInfo.phone }}</span>
</a-col>
<a-col :span="12" class="detail-item">
<label>企业联系人邮箱</label>
<span>{{ basicInfo.email }}</span>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12" class="detail-item">
<label>企业联系人邮编</label>
<span>{{ basicInfo.postalCodeContacts }}</span>
</a-col>
<a-col :span="12" class="detail-item">
<label>企业联系人地址</label>
<span><j-ellipsis :value="basicInfo.contactAddress" :length="17"></j-ellipsis></span>
</a-col>
</a-row>
</template>
<!-- 工作组项目使用循环显示出联系人信息-->
<template v-if="basicInfo.projectType === 2 && basicInfo.payWorkingGroupSubItemContactsList && basicInfo.payWorkingGroupSubItemContactsList.length > 0">
<div v-for="(item, index) in basicInfo.payWorkingGroupSubItemContactsList" :key="index + ''">
<a-row :gutter="24">
<a-col :span="12" class="detail-item">
<label>企业联系人{{ index + 1 }}</label>
<span><j-ellipsis :value="item.contactsTemporaryName" :length="16"></j-ellipsis></span>
</a-col>
<a-col :span="12" class="detail-item">
<label>企业联系人{{ index + 1 }}备注</label>
<span><j-ellipsis :value="item.remarks" :length="16"></j-ellipsis></span>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12">
<label>企业联系人{{ index + 1 }}性别</label>
<span>{{ item.gender_dictText }}</span>
</a-col>
<a-col :span="12" class="detail-item">
<label>企业联系人{{ index + 1 }}职务</label>
<span><j-ellipsis :value="item.post" :length="16"></j-ellipsis></span>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12" class="detail-item">
<label>企业联系人{{ index + 1 }}电话</label>
<span>{{ item.phone }}</span>
</a-col>
<a-col :span="12" class="detail-item">
<label>企业联系人{{ index + 1 }}邮箱</label>
<span>{{ item.email }}</span>
</a-col>
</a-row>
<a-row :gutter="24">
<a-col :span="12" class="detail-item">
<label>企业联系人{{ index + 1 }}邮编</label>
<span>{{ item.postalCodeContacts }}</span>
</a-col>
<a-col :span="12" class="detail-item">
<label>企业联系人{{ index + 1 }}地址</label>
<span><j-ellipsis :value="item.contactAddress" :length="16"></j-ellipsis></span>
</a-col>
</a-row>
<a-divider v-if="index + 1 !== basicInfo.payWorkingGroupSubItemContactsList.length"/>
</div>
</template>
</section>
<!-- 企业联系人信息end-->
<!--到账信息begin-->
<section class="payment-info">
<h3 class="title">到账信息</h3>
<div class="payment-info-box">
<section class="payment-info-title">到账信息</section>
<template v-if="paymentInfoList && paymentInfoList.length > 0">
<div class="payment-info-content" v-for="item of paymentInfoList" :key="item.id">
{{ item.paymentDate }}到账{{ item.amountReceived }}
</div>
</template>
<a-list v-else :data-source="[]"/>
</div>
</section>
<!--到账信息end-->
<!--开票邮寄信息begin-->
<section class="logistics-info">
<h3 class="title">开票邮寄信息</h3>
<div class="wrap-table">
<a-table
ref="table"
size="middle"
rowKey="id"
:pagination="false"
:columns="columns"
:dataSource="logisticsInfoList"
class="j-table-force-nowrap"
>
<span slot="action" class="action-span-cell" slot-scope="record">
<a @click="lookLogistics(record)" v-if="record.postStatus === 1">查看物流</a>
</span>
<!-- <p slot="expandedRowRender" slot-scope="record" style="margin: 0">-->
<!-- {{ record.sendDate }}-->
<!-- </p>-->
</a-table>
</div>
</section>
<!--开票邮寄信息end-->
<template slot="footer">
<a-button @click="handleCancel">关闭</a-button>
</template>
</j-modal>
</template>
<script>
import { queryCommonProjectById, getStanderMemberLastProofInfo, getCertificateLastProofInfo } from '@api/incomePaymentsApi'
import JEllipsis from '@comp/jero/JEllipsis'
import PreviewFile from './jero/PreviewFile'
import { ProjectTypeEnums } from '@/enums/commonEnums'
// import pick from 'lodash.pick'
// import {getAction} from "@api/manage";
const columns = [
{
title: '开票人',
align: 'center',
dataIndex: 'realName'
},
{
title: '日期',
align: 'center',
dataIndex: 'billDate'
},
{
title: '金额(元)',
align: 'center',
dataIndex: 'invoiceAmount'
},
{
title: '票号',
align: 'center',
dataIndex: 'billNo'
},
{
title: '项目',
align: 'center',
dataIndex: 'projectName'
},
{
title: '邮寄人',
align: 'center',
dataIndex: 'mailName'
},
{
title: '快递',
align: 'center',
dataIndex: 'sendMethod_dictText'
},
{
title: '快递单号',
align: 'center',
dataIndex: 'postNo'
},
{
title: '操作',
align: 'center',
dataIndex: '',
scopedSlots: { customRender: 'action' }
}
]
export default {
name: 'ProjectDetailModal',
props: {
// 字段名称是否非id,适用于票据邮寄等页面id不是项目id的情况
notId: {
type: Boolean,
required: false,
default: false
},
// 是否是到账开票模块
isInvoicing: {
type: Boolean,
required: false,
default: false
}
},
data() {
return {
description: '项目详情模态框',
width: 800,
visible: false,
title: '项目信息',
// 当前项目id
currentProjectId: '',
// 基本信息
basicInfo: {},
// 企业信息
enterpriseInfo: {},
// 联系人信息
contactsInfo: {},
columns,
// 到账信息
paymentInfoList: [],
// 开票邮寄信息
logisticsInfoList: [],
// 垫付企业的信息
otherCompanyInfo: {},
ProjectTypeEnums
}
},
computed: {
// 是否是第三方代付
hasOtherCompany() {
// 去掉未审核 去判断的企业是否是标协会企业
let companyName = this.basicInfo.companyName.replaceAll('(未审核)','')
return this.isInvoicing && this.otherCompanyInfo.headerName && (this.otherCompanyInfo.headerName !== companyName)
}
},
components: {
JEllipsis,
PreviewFile
},
methods: {
open(record) {
this.visible = true
// 记录当前项目id
if (this.notId) {
this.currentProjectId = record.projectId
} else {
this.currentProjectId = record.id
}
// 通过id查询项目详情
queryCommonProjectById({ id: this.currentProjectId }).then(res => {
if (res.success) {
console.log(res.result, 'res.result')
// 项目信息
this.basicInfo = res.result
// 到账信息
this.paymentInfoList = res.result.paymentRecord
// 开票邮寄信息
this.logisticsInfoList = res.result.mailBill
} else {
console.log('未查到相应的信息')
}
})
// 到账开票模块显示请求发票信息,查看是否是第三方代付
if(this.isInvoicing) {
/* 如果当前项目是会员项目、会员证书项目 需要请求响应的 第三方付款信息*/
let projectType = Number(record.projectType)
if(projectType === ProjectTypeEnums.STANDARD_MEMBER_PRO.value) {
this.getMemberLastProofInfo(record, getStanderMemberLastProofInfo)
} else if(projectType === ProjectTypeEnums.STANDARD_CERTIFICATE_PRO.value){
this.getMemberLastProofInfo(record, getCertificateLastProofInfo)
}
}
},
getMemberLastProofInfo(record, requestFunc) {
let param = {
projectId: record.id
}
requestFunc && requestFunc(param).then(res => {
if (res.success) {
this.otherCompanyInfo = res.result || {}
}
})
},
handleCancel() {
// 清除之前的信息
this.basicInfo = {}
this.enterpriseInfo = {}
this.contactsInfo = {}
this.otherCompanyInfo = {}
this.paymentInfoList = []
this.logisticsInfoLis = []
this.visible = false
},
/*
* 生成每一个开票信息
* */
createItemInfo(item) {
let porjectItem = ''
if (item.projects.length > 0) {
item.projects.forEach((val, index) => {
if (index === item.projects.length - 1) {
porjectItem += val
} else {
porjectItem += val + '、'
}
})
}
return `${ item.person }${ item.time }开票,金额为:${ item.money }元,票号:${ item.piaoNo },项目:${ porjectItem }`
},
/*
* 查看物流
* */
lookLogistics(record) {
console.log(record)
const com = Number(record.sendMethod) === 1 && 'ems' || 'shunfeng'
// window.open(`https://www.kuaidi100.com/chaxun?com=${ com }&nu=${ record.postNo }`)
let url = ''
if (com === 'shunfeng' && record.principalPhone) {
url = `${window._CONFIG['lookExpressDomainURL']}?com=${ com }&nu=${ record.postNo }&phone=${ record.principalPhone }`
} else {
url = `${window._CONFIG['lookExpressDomainURL']}?com=${ com }&nu=${ record.postNo }`
}
window.open(url, '_blank')
},
/*
* 去合同详情 传入合同id
* */
toContractDetail() {
if (this.basicInfo.contractId) {
this.$router.push({
path: '/contractManagement/RevenueContractDetail', query: {
revenueId: this.basicInfo.contractId
}
})
} else {
this.$message.warn('该项目未与合同关联')
}
},
/*
* 每一个项目的来款方式不同
* */
createIncomeType(val) {
if (val === 1 || val === 2 || val === 4) {
return '来款方式'
} else {
return '缴费方式'
}
}
}
}
</script>
<style scoped lang="less">
.ant-row {
margin: 12px;
}
h3 {
position: relative;
}
label {
color: #666;
}
.detail-item {
display: flex;
label {
flex-shrink: 0;
}
span {
word-break: break-all;
display: block;
}
}
.contract-num {
color: #42b983;
cursor: pointer;
}
h3.title::before {
position: absolute;
top: 4px;
left: -10px;
content: "";
height: 20px;
width: 2px;
background: #069f99;
}
/* 到账信息 */
.payment-info {
margin-bottom: 14px;
&-box {
border: 1px solid #ccc;
}
&-title {
text-align: center;
font-size: 14px;
height: 35px;
line-height: 35px;
letter-spacing: 1px;
color: #fff;
background: #a2e6e4;
}
&-content {
border: 1px solid #ccc;
color: #424242;
//background: #efefef;
padding: 5px;
padding-left: 10px;
//border: 1px solid #ccc;
border-top: none;
}
}
/* 开票邮寄信息 */
.wrap-table {
border: 1px solid #ccc;
border-bottom: none;
}
/deep/ .ant-table-thead {
tr > th {
color: #fff;
background: #a2e6e4;
border: none;
}
}
/deep/ .ant-table-tbody {
tr > td {
border: none;
border-bottom: 1px solid #ccc;
}
}
.ant-divider-horizontal {
margin: 5px 0;
}
</style>
+78
View File
@@ -0,0 +1,78 @@
import { pcaa } from 'area-data'
/**
* 省市区
*/
export default class Area {
/**
* 构造器
* @param express
*/
constructor() {
const arr = []
const province = pcaa['86']
Object.keys(province).map(key => {
arr.push({ id: key, text: province[key], pid: '86' })
const city = pcaa[key]
Object.keys(city).map(key2 => {
arr.push({ id: key2, text: city[key2], pid: key })
const qu = pcaa[key2]
Object.keys(qu).map(key3 => {
arr.push({ id: key3, text: qu[key3], pid: key2 })
})
})
})
this.all = arr
}
get pca() {
return this.all
}
getCode(text) {
if (!text || text.length === 0) {
return ''
}
for (const item of this.all) {
if (item.text === text) {
return item.id
}
}
}
getText(code) {
if (!code || code.length === 0) {
return ''
}
const arr = []
this.getAreaBycode(code, arr)
return arr.join('/')
}
getRealCode(code) {
const arr = []
this.getPcode(code, arr)
return arr
}
getPcode(id, arr) {
for (const item of this.all) {
if (item.id === id) {
arr.unshift(id)
if (item.pid !== '86') {
this.getPcode(item.pid, arr)
}
}
}
}
getAreaBycode(code, arr) {
// console.log("this.all.length",this.all)
for (const item of this.all) {
if (item.id === code) {
arr.unshift(item.text)
this.getAreaBycode(item.pid, arr)
}
}
}
}
+74
View File
@@ -0,0 +1,74 @@
import pca from '../../../public/map/areaPca'
/**
* 省市区
*/
export default class Area {
/**
* 构造器
* @param express
*/
constructor() {
const arr = []
const province = pca['86']
Object.keys(province).map(key => {
arr.push({ id: key, text: province[key], pid: '86' })
const city = pca[key]
Object.keys(city).map(key2 => {
arr.push({ id: key2, text: city[key2], pid: key })
})
})
this.all = arr
}
get pca() {
return this.all
}
getCode(text) {
if (!text || text.length === 0) {
return ''
}
for (const item of this.all) {
if (item.text === text) {
return item.id
}
}
}
getText(code) {
if (!code || code.length === 0) {
return ''
}
const arr = []
this.getAreaBycode(code, arr)
return arr.join('/')
}
getRealCode(code) {
const arr = []
this.getPcode(code, arr)
return arr
}
getPcode(id, arr) {
for (const item of this.all) {
if (item.id === id) {
arr.unshift(id)
if (item.pid !== '86') {
this.getPcode(item.pid, arr)
}
}
}
}
getAreaBycode(code, arr) {
// console.log("this.all.length",this.all)
for (const item of this.all) {
if (item.id === code) {
arr.unshift(item.text)
this.getAreaBycode(item.pid, arr)
}
}
}
}
+35
View File
@@ -0,0 +1,35 @@
/**
* 获取字符串的长度ascii长度为1 中文长度为2
* @param str
* @returns {number}
*/
export const getStrFullLength = (str = '') =>
str.split('').reduce((pre, cur) => {
const charCode = cur.charCodeAt(0)
if (charCode >= 0 && charCode <= 128) {
return pre + 1
}
return pre + 2
}, 0)
/**
* 给定一个字符串和一个长度,将此字符串按指定长度截取
* @param str
* @param maxLength
* @returns {string}
*/
export const cutStrByFullLength = (str = '', maxLength) => {
let showLength = 0
return str.split('').reduce((pre, cur) => {
const charCode = cur.charCodeAt(0)
if (charCode >= 0 && charCode <= 128) {
showLength += 1
} else {
showLength += 2
}
if (showLength <= maxLength) {
return pre + cur
}
return pre
}, '')
}
+12
View File
@@ -0,0 +1,12 @@
/**
* components util
*/
/**
* 清理空值,对象
* @param children
* @returns {*[]}
*/
export function filterEmpty(children = []) {
return children.filter(c => c.tag || (c.text && c.text.trim() !== ''))
}
@@ -0,0 +1,95 @@
<template>
<div>
<a-row :gutter=10>
<a-col :span="20">
<a-input autocomplete="off" @click="chooseBusiness" :value="value[valueKey]" v-bind="$attrs"></a-input>
</a-col>
<a-col :span="4">
<a-button icon="plus" v-bind="$attrs" @click="addCompany"></a-button>
</a-col>
</a-row>
<business-select ref="businessSelect" @ok="setCompanyVal" v-bind="$attrs"></business-select>
<business-management-module ref="businessModal" @ok="setCompanyVal"></business-management-module>
</div>
</template>
<script>
import BusinessSelect from '@comp/company/BusinessSelect'
import BusinessManagementModule from '@views/businessManagement/modules/BusinessManagementModule'
export default {
name: 'AddMeetingCompany',
props: {
// 是否可以选择
isCompanyDisabled: {
type: Boolean,
required: false,
default: false
},
value: {
type: Object,
default: () => {
return {}
}
},
// 回显数据的key
valueKey: {
type: String,
default: 'companyName'
},
// 是否返回企业的全部信息,如果是 则再change方法中以第二个参数返回
fullCompanyInfo: {
type: Boolean,
required: false,
default: false
}
},
components: {
BusinessSelect,
BusinessManagementModule
},
data() {
return {
reallyValue:''
}
},
methods: {
/*
* 打开选择企业弹窗
* */
chooseBusiness() {
if (this.isCompanyDisabled) {
return
}
this.$refs.businessSelect.searchReset()
this.$refs.businessSelect.visible = true
},
/*
* 添加企业
* */
addCompany() {
this.$refs.businessModal.title='新增'
this.$refs.businessModal.add({})
},
/*
* 接受值和抛出
* */
setCompanyVal(selectedVal) {
let {id, companyName} = selectedVal
if(this.fullCompanyInfo) {
this.$emit('change', {id, companyName}, {...selectedVal})
} else {
this.$emit('change', {id, companyName})
}
}
},
model: {
prop: 'value',
event: 'change'
}
}
</script>
<style scoped>
</style>
+212
View File
@@ -0,0 +1,212 @@
<template>
<j-modal
:title="title"
:width="width"
:visible="visible"
:confirmLoading="confirmLoading"
switchFullscreen
@ok="handleOk"
@cancel="handleCancel"
cancelText="关闭">
<div class="table-page-search-wrapper">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item>
<a-input placeholder="请输入企业名称" v-model="queryParam.companyName"></a-input>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<span class="table-page-search-submitButtons">
<a-button type="primary" icon="search" @click="searchQuery">查询</a-button>
<a-button icon="reload" @click="searchReset">重置</a-button>
</span>
</a-col>
</a-row>
</a-form>
</div>
<div>
<a-table
ref="table"
size="middle"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange, type: isMultiple ? 'checkbox' : 'radio'}"
@change="handleTableChange"
class="j-table-force-nowrap">
<template slot="htmlSlot" slot-scope="text">
<div v-html="text"></div>
</template>
<template slot="imgSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
<img v-else :src="getImgView(text)" height="25px" alt=""
style="max-width:80px;font-size: 12px;font-style: italic;"/>
</template>
<template slot="fileSlot" slot-scope="text,record">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
<j-ellipsis @click.native="uploadFile(record.chargeNoticeFileId)" style="color:#219AFF;cursor: pointer"
:value="text" :length="20"/>
</template>
<template slot="text" slot-scope="text">
<j-ellipsis :value="text" :length="30"></j-ellipsis>
</template>
</a-table>
</div>
</j-modal>
</template>
<script>
import { JeroListMixin } from '@/mixins/JeroListMixin'
import { getAction } from '../../api/manage'
export default {
name: 'BusinessSelect',
mixins: [JeroListMixin],
props: {
// 理事会时需要传2,默认为0
memberNature: {
type: Number,
default: null
},
// 是否多选-默认false
isMultiple: {
type:Boolean,
required:false,
default:false
}
},
data() {
return {
title: '选择企业',
width: 800,
visible: false,
confirmLoading: false,
url: {
list: '/company/payCompanyManagement/list'
},
selectedCompany: {},
selectedRowKeys: [],
columns: [
{
title: '序号',
dataIndex: '',
key: 'rowIndex',
width: 60,
align: 'center',
customRender: function (t, r, index) {
return parseInt(index) + 1
}
}, {
title: '企业名称',
align: 'center',
dataIndex: 'companyName',
scopedSlots: { customRender: 'text' }
}
],
dataSource: [],
// 是否调用无权限接口
isLimit: false
}
},
methods: {
/**
* 重写获取数据方法,理事会需要传参
* @param arg
*/
loadData(arg) {
console.log(this.memberNature)
if (!this.url.list) {
this.$message.error('请设置url.list属性!')
return
}
//加载数据 若传入参数1则加载第一页的内容
if (arg === 1) {
this.ipagination.current = 1
}
let params = this.getQueryParams()//查询条件
// 是理事会单位则需要传参
if (this.memberNature && this.memberNature === 2) {
params.memberNature = this.memberNature
}
this.loading = true
getAction(this.url.list, params).then((res) => {
if (res.success) {
//update-begin---author:zhangyafei Date:20201118 for:适配不分页的数据列表------------
this.dataSource = res.result.records || res.result
if (res.result.total) {
this.ipagination.total = res.result.total
//清空列表选中
} else {
this.ipagination.total = 0
}
//update-end---author:zhangyafei Date:20201118 for:适配不分页的数据列表------------
}
if (res.code === 510) {
this.$message.warning(res.message)
}
this.loading = false
}).finally(() => {
this.loading = false
})
},
handleOk() {
this.$emit('ok', this.selectedCompany)
this.close()
},
handleCancel() {
this.close()
},
close() {
this.onClearSelected()
this.visible = false
this.selectedCompany = {}
if (this.isMultiple) {
this.selectedCompany = []
}
},
onSelectChange(selectedRowKeys, selectionRows) {
if(!this.isMultiple) {
this.selectedCompany = selectionRows[0]
} else {
// selectionRows只会返回当前页数据的返回,所以多选的时候需要比对各个数据是否存在,不存在的话就从当前数据中查询推入selectedCompany中
let resultArr = []
selectionRows.forEach(row => {
let ele = this.selectedCompany.find(ele => ele.id === row.id)
if(!ele) {
resultArr.push(row)
}
})
this.selectedCompany = [...this.selectedCompany, ...resultArr]
// this.selectedCompany = selectionRows
}
this.selectedRowKeys = selectedRowKeys
},
/*
* 重写一下查询 之前调用的是混入的查询
* */
searchReset() {
// 调用无权限接口
if (this.isLimit) {
this.url.list = '/company/payCompanyManagement/listMeeting'
}
this.lastQueryParam = {}
this.queryParam = {}
this.loadData(1)
}
},
created() {
if (this.isMultiple) {
this.selectedCompany = []
}
}
}
</script>
<style scoped lang="less">
@import '~@assets/less/common.less';
</style>
+152
View File
@@ -0,0 +1,152 @@
<template>
<div class="company-select">
<a-row>
<a-col :span="20">
<a-tooltip v-if="isMultiple">
<template slot="title">{{ value[valueKey] }}</template>
<a-input @click="chooseBusiness" :value="value[valueKey]" v-bind="$attrs" :readOnly="true" unselectable="on"></a-input>
</a-tooltip>
<a-input v-else @click="chooseBusiness" :value="value[valueKey]" v-bind="$attrs" :readOnly="true" unselectable="on"></a-input>
</a-col>
<a-col :span="4" class="form-btn" v-if="canAdd">
<a-button v-bind="$attrs" icon="plus" @click="addCompany"></a-button>
</a-col>
</a-row>
<business-select ref="businessSelect" @ok="handleOk" v-bind="$attrs" :is-multiple="isMultiple"></business-select>
<business-management-module ref="businessAdd" @ok="addCompanyOk"></business-management-module>
</div>
</template>
<script>
import BusinessSelect from '@comp/company/BusinessSelect'
import BusinessManagementModule from '@/views/businessManagement/modules/BusinessManagementModule'
export default {
name: 'CompanySelect',
components: { BusinessSelect, BusinessManagementModule },
props: {
// 是否可以选择
isCompanyDisabled: {
type: Boolean,
required: false,
default: false
},
value: {
type: [Object],
default: () => {
return {}
}
},
// 回显数据的key
valueKey: {
type: String,
default: 'companyName'
},
// 是否可以新增:true--可以;false--不可以(组件作为查询条件时不可新增)
canAdd: {
type: Boolean,
required: false,
default: true
},
// 是否调用无权限接口
isLimit:{
type:Boolean,
required:false,
default:false
},
// 是否多选-默认false
isMultiple: {
type:Boolean,
required:false,
default:false
}
},
methods: {
/**
* 打开选择企业的模态框,如果父级传参为true则点击不弹模态框
*/
chooseBusiness() {
if (this.isCompanyDisabled) {
return
}
// 修改参数 是否调用无权限接口
this.$refs.businessSelect.isLimit = this.isLimit
this.$refs.businessSelect.searchReset()
this.$refs.businessSelect.visible = true
if (!this.isMultiple) {
this.$refs.businessSelect.selectedRowKeys[0] = this.value.id
} else {
// 很重要 内部的删除像没有作用一样
if(this.value.id) {
this.$refs.businessSelect.selectedRowKeys = this.value.id.split(',')
this.$refs.businessSelect.selectedCompany = this.multipleData || []
} else {
this.$refs.businessSelect.selectedRowKeys = []
this.$refs.businessSelect.selectedCompany = []
}
}
},
/**
* 选中后抛出企业信息(id, companyName)
* @param value
*/
handleOk(value) {
console.log('--------value---------', 'value')
let company = {id: undefined, companyName: undefined}
// 多选的时候 全部放在一起,以逗号分隔
if (this.isMultiple) {
if(value.length > 0) {
let ids = [], nameArr = []
value.forEach(item => {
ids.push(item.id)
nameArr.push(item.companyName)
})
company.id = ids.join()
company.companyName= nameArr.join()
}
// 存储上次选中的信息,用于回显
this.multipleData = value
} else {
company.id = value.id
company.companyName= value.companyName
}
this.$emit('change', company)
},
/**
* 新增企业
*/
addCompany() {
this.$refs.businessAdd.title = '新增企业'
// 传参是否调用无权限接口
this.$refs.businessAdd.add(this.isLimit)
},
/**
* 接收回显
* @param value
*/
addCompanyOk(value) {
let { id, companyName } = value
this.$emit('change', { id, companyName })
}
},
//2.2新增 在组件内定义 指定父组件调用时候的传值属性和事件类型
model: {
prop: 'value',
event: 'change'
}
}
</script>
<style scoped>
a-input:hover {
cursor: pointer;
}
.form-btn {
padding-top: 1px;
padding-left: 8px;
margin-bottom: -1px;
}
</style>
+192
View File
@@ -0,0 +1,192 @@
<template>
<j-modal
:title="title"
:width="width"
:visible="visible"
:confirmLoading="confirmLoading"
switchFullscreen
@ok="handleOk"
@cancel="handleCancel"
cancelText="关闭">
<div class="table-page-search-wrapper">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="会议名称">
<a-input placeholder="请输入会议名称" v-model="queryParam.meetingName"></a-input>
</a-form-item>
</a-col>
<a-col :xl="10" :lg="11" :md="12" :sm="24">
<a-form-item label="会议时间">
<j-date
placeholder="请选择开始日期"
class="query-group-cust"
v-model="queryParam.meetingStartTime"
:disabled-date="disabledStartDate">
</j-date>
<span class="query-group-split-cust"></span>
<j-date
placeholder="请选择结束日期"
class="query-group-cust"
v-model="queryParam.meetingEndTime"
:disabled-date="disabledEndDate">
</j-date>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<span class="table-page-search-submitButtons">
<a-button type="primary" icon="search" @click="searchQuery">查询</a-button>
<a-button icon="reload" @click="searchReset" class="reset-button">重置</a-button>
</span>
</a-col>
</a-row>
</a-form>
</div>
<div>
<a-table
ref="table"
size="middle"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange, type: 'radio'}"
@change="handleTableChange"
class="j-table-force-nowrap">
<template slot="text" slot-scope="text">
<j-ellipsis v-if="text && text.length > 0" :value="text" :length="30"></j-ellipsis>
<span v-else></span>
</template>
</a-table>
</div>
</j-modal>
</template>
<script>
import {JeroListMixin} from '@/mixins/JeroListMixin'
import {RangeDateMixin} from '@/mixins/RangeDateMixin'
import JDate from '@comp/tools/JDate'
import JEllipsis from '@comp/jero/JEllipsis'
export default {
name: 'MeetingListModal',
components: {
JDate,
JEllipsis
},
mixins: [JeroListMixin, RangeDateMixin],
data() {
return {
title: '选择会议',
width: 1200,
visible: false,
confirmLoading: false,
url: {
list: '/meeting/payMeeting/page',
},
dateKeyObj: {
beginKey: 'meetingStartTime',
endKey: 'meetingEndTime'
},
selectedCompany: {},
selectedRowKeys: [],
columns: [
{
title: '序号',
dataIndex: '',
key: 'rowIndex',
width: 60,
align: 'center',
customRender: function (t, r, index) {
return parseInt(index) + 1
}
},
{
title: '会议名称',
align: 'center',
dataIndex: 'meetingName',
scopedSlots: {customRender: 'text'},
width: 160,
},
{
title: '会议类型',
align: 'center',
dataIndex: 'meetingType_dictText',
scopedSlots: {customRender: 'text'},
width: 100,
},
{
title: '负责人',
align: 'center',
dataIndex: 'directorName',
scopedSlots: {customRender: 'text'},
width: 160,
},
{
title: '召开时间',
align: 'center',
dataIndex: 'startTime',
width: 160,
customRender: function (text, record) {
return `${record.startTime}~${record.endTime}`
}
},
{
title: '召开地点',
align: 'center',
dataIndex: 'venue',
width: 160,
customRender: function (text, record) {
return text + '/' + record.address
}
},
{
title: '会议费用',
align: 'center',
dataIndex: 'meetingCosts',
},
{
title: '创建时间',
align: 'center',
dataIndex: 'createTime',
scopedSlots: {customRender: 'text'},
}
],
dataSource: []
}
},
methods: {
handleOk() {
this.$emit('ok', this.selectedCompany)
this.close()
},
handleCancel() {
this.close()
},
close() {
this.visible = false
},
onSelectChange(selectedRowKeys, selectionRows) {
this.selectedCompany = selectionRows[0]
this.selectedRowKeys = selectedRowKeys
},
/*
* 修改查询条件
* */
searchQuery() {
this.queryParam.meetingStartTime = this.queryParam.meetingStartTime ? this.queryParam.meetingStartTime + ' ' + '00:00:00' : undefined
this.queryParam.meetingEndTime = this.queryParam.meetingEndTime ? this.queryParam.meetingEndTime + ' ' + '23:59:59' : undefined
this.queryParam.createTime_begin = this.queryParam.createTime_begin ? this.queryParam.createTime_begin + ' ' + '00:00:00' : undefined
this.queryParam.createTime_end = this.queryParam.createTime_end ? this.queryParam.createTime_end + ' ' + '23:59:59' : undefined
this.lastQueryParam = {...this.queryParam}
this.loadData(1)
},
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>
+60
View File
@@ -0,0 +1,60 @@
<template>
<div class="company-select">
<a-input @click="chooseBusiness" autocomplete="off" :value="value[valueKey]" v-bind="$attrs" :readOnly="true"></a-input>
<meeting-list-modal ref="meetingList" @ok="handleOk" v-bind="$attrs"></meeting-list-modal>
</div>
</template>
<script>
import MeetingListModal from '@comp/company/MeetingListModal'
export default {
name: 'MeetingSelect',
components:{
MeetingListModal
},
props: {
// 是否可以选择
isCompanyDisabled: {
type: Boolean,
required: false,
default: false
},
value: {
type: [Object],
default: () => {
return {}
}
},
// 回显数据的key
valueKey: {
type: String,
default: 'meetingName'
}
},
methods:{
/**
* 打开选择会议的的模态框,如果父级传参为true则点击不弹模态框
*/
chooseBusiness() {
if (this.isCompanyDisabled) {
return
}
this.$refs.meetingList.searchReset()
this.$refs.meetingList.visible = true
},
handleOk(value) {
this.$emit('change', value)
}
},
model: {
prop: 'value',
event: 'change'
}
}
</script>
<style scoped lang="less">
a-input:hover {
cursor: pointer;
}
</style>
+215
View File
@@ -0,0 +1,215 @@
<template>
<!-- 在点击组件时获取联系人列表-->
<div>
<a-row>
<a-col :span="20">
<a-select :value="value"
v-bind="$attrs"
v-on="$listeners"
show-search
allowClear
option-filter-prop="children"
:filter-option="filterOption"
@dropdownVisibleChange="handleDropdownOpen">
<a-select-option v-for="item in contactsList" :key="item.id" :value="item.id">{{ item.name }}</a-select-option>
</a-select>
</a-col>
<a-col :span="4" class="form-btn">
<a-button icon="plus" v-bind="$attrs" @click="addContacts"></a-button>
</a-col>
</a-row>
<contact-management-module ref="contactForm"
is-company-disabled
:selected-company="selectedCompany"
@ok="addContactsOk">
</contact-management-module>
</div>
</template>
<script>
import ContactManagementModule from '@views/businessManagement/modules/ContactManagementModule'
import { getContactsByCompany, getContactsByCompanyNoLimit } from '@api/api'
export default {
name: 'SelectContacts',
components: { ContactManagementModule },
props: {
// 已选中的企业信息
selectedCompany: {
type: Object,
required: false,
default: () => {
return {}
}
},
// 编辑时回显的数据, 需要id,name两个字段
initContacts: {
type: Object,
required: false,
default: () => {
return {}
}
},
value: {
type: [String, Object],
required: false,
default: undefined
},
// 取消时将isCancel设为true,用于重置是否为第一次展开下拉
isCancel: {
type: Boolean,
required: false,
default: false
},
// value的类型
valueType: {
type: String,
required: false,
default: 'string'
},
// 是否调用无权限接口
isLimit: {
type: Boolean,
required: false,
default: false
}
},
data() {
return {
contactsList: [], // 该企业下联系人列表
isFirstOpen: true, // 编辑状态下是否为第一次打开
contactId: this.value
}
},
created() {
// this.initContacts = null
this.contactsList = []
// 编辑 第一次不回显的问题
this.getContactsList()
},
watch: {
/**
* 选中企业发生变化时重新获取数据
*/
selectedCompany: {
handler() {
this.getContactsList()
},
deep: true
},
/**
* 编辑联系人变化
*/
initContacts: {
handler() {
this.isFirstOpen = true
},
deep: true
},
isCancel(val) {
if (val) {
this.isFirstOpen = true
// 取消时重新获取联系人列表,将临时联系人信息加入列表中
this.getContactsList()
}
}
},
methods: {
/**
* 获取联系人数据
*/
getContactsList() {
this.contactsList = []
let params = {}
if (this.selectedCompany && this.selectedCompany.id) {
params.companyId = this.selectedCompany.id
} else {
params.companyId = null
}
// 是否调用无权限接口
if (this.isLimit) {
// 调用无权限接口
return new Promise(resolve => {
getContactsByCompanyNoLimit(params).then(res => {
this.contactsList = res.result
if (this.initContacts && this.initContacts.id) {
this.contactsList.push(this.initContacts)
}
resolve()
})
})
} else {
return new Promise(resolve => {
getContactsByCompany(params).then(res => {
this.contactsList = res.result || []
if (this.initContacts && this.initContacts.id) {
this.contactsList.push(this.initContacts)
}
resolve()
})
})
}
},
/**
* 新建联系人
*/
addContacts() {
if (this.selectedCompany && Object.keys(this.selectedCompany).length > 0 && this.selectedCompany.id) {
// 传入是否调用无权限接口的参数 去判断
this.$refs.contactForm.add(this.isLimit)
this.$refs.contactForm.title = '新增'
this.$refs.contactForm.disableSubmit = false
return
}
// 调用无权限的提示语修改
this.$message.warn('请先选择企业再为该企业新建联系人')
},
addContactsOk(id) {
this.getContactsList().then(() => {
if (this.valueType === 'object') {
let objContact = this.contactsList.filter(tt => tt.id === id)
objContact = objContact[0]
objContact.label = objContact.name
objContact.key = objContact.id
this.$emit('change', objContact)
} else {
this.$emit('change', id)
}
this.$emit('ok')
})
},
// 下拉框的搜索
filterOption(input, option) {
return (
option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
)
},
/**
* 第一次展开下拉,去掉和初始联系人一样的联系人
*/
handleDropdownOpen() {
// this.getContactsList()
if (this.isFirstOpen && this.initContacts && this.initContacts.id) {
let delIndex = this.contactsList.findIndex(e => {
e.id === this.initContacts.id
})
this.contactsList.splice(delIndex,1)
this.isFirstOpen = false
}
},
},
model: {
prop: 'value',
event: 'change'
}
}
</script>
<style scoped>
.form-btn {
padding-top: 1px;
padding-left: 8px;
margin-bottom: -1px;
}
</style>
@@ -0,0 +1,77 @@
<template>
<a-select :value="value"
v-bind="$attrs"
v-on="$listeners"
show-search
allowClear
option-filter-prop="children"
:filter-option="filterOption">
<a-select-option v-for="item in userList" :key="item.id" :value="item.id">
{{ `${ item.realname }(${ item.orgCodeTxt })` }}
</a-select-option>
</a-select>
</template>
<script>
import { getAllUserList } from '@api/api'
export default {
name: 'SelectPrincipal',
props: {
// 绑定值为用户id
value: {
type: String,
required: false,
default: undefined
},
index:{
type:[String,Number],
required: false
}
},
data() {
return {
userList: [] // 用户列表
}
},
created() {
this.initUserList()
},
methods: {
/**
* 获取所有用户
*/
initUserList() {
getAllUserList().then(res => {
if (res.success) {
this.userList = res.result
} else {
this.$message.warn(res.message)
}
})
},
// 下拉框的搜索
filterOption(input, option) {
console.log(option)
return (
option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
)
},
// 通过其他的信息 赋值,如 姓名、部门、员工号
setValueByOtherInfo(otherInfo) {
let ele = this.userList.find(tt => tt.realname === otherInfo.realname && tt.orgCodeTxt === otherInfo.orgCodeTxt && tt.workNo === otherInfo.workNo)
if( ele) {
this.$emit('change', ele.id)
}
}
},
model: {
prop: 'value',
event: 'change'
}
}
</script>
<style scoped>
</style>
+110
View File
@@ -0,0 +1,110 @@
<template>
<a-radio-group v-if="tagType=='radio'" @change="handleInput" :value="getValueSting" :disabled="disabled">
<a-radio v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio>
</a-radio-group>
<a-radio-group v-else-if="tagType=='radioButton'" buttonStyle="solid" @change="handleInput" :value="getValueSting" :disabled="disabled">
<a-radio-button v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio-button>
</a-radio-group>
<a-select v-else-if="tagType=='select'" :getPopupContainer = "getPopupContainer" :placeholder="placeholder" :disabled="disabled" :value="getValueSting" @change="handleInput">
<a-select-option :value="undefined">请选择</a-select-option>
<a-select-option v-for="(item, key) in dictOptions" :key="key" :value="item.value">
<span style="display: inline-block;width: 100%" :title=" item.text || item.label ">
{{ item.text || item.label }}
</span>
</a-select-option>
</a-select>
</template>
<script>
import {ajaxGetDictItems,getDictItemsFromCache} from '@/api/api'
export default {
name: 'JDictSelectTag',
props: {
dictCode: String,
placeholder: String,
triggerChange: Boolean,
disabled: Boolean,
value: [String, Number],
type: String,
getPopupContainer:{
type: Function,
default: (node) => node.parentNode
}
},
data() {
return {
dictOptions: [],
tagType:''
}
},
watch:{
dictCode:{
immediate:true,
handler() {
this.initDictData()
},
}
},
created() {
// console.log(this.dictCode);
if(!this.type || this.type==='list'){
this.tagType = 'select'
}else{
this.tagType = this.type
}
//获取字典数据
// this.initDictData();
},
computed: {
getValueSting(){
// update-begin author:wangshuai date:20200601 for: 不显示placeholder的文字 ------
// 当有null或“” placeholder不显示
return this.value != null ? this.value.toString() : undefined
// update-end author:wangshuai date:20200601 for: 不显示placeholder的文字 ------
},
},
methods: {
initDictData() {
//优先从缓存中读取字典配置
if(getDictItemsFromCache(this.dictCode)){
this.dictOptions = getDictItemsFromCache(this.dictCode)
return
}
//根据字典Code, 初始化字典数组
ajaxGetDictItems(this.dictCode, null).then((res) => {
if (res.success) {
// console.log(res.result);
this.dictOptions = res.result
}
})
},
handleInput(e) {
let val
if(this.tagType=='radio'){
val = e.target.value
}else{
val = e
}
if(this.triggerChange){
this.$emit('change', val)
}else{
this.$emit('input', val)
}
},
setCurrentDictOptions(dictOptions){
this.dictOptions = dictOptions
},
getCurrentDictOptions(){
return this.dictOptions
}
}
}
</script>
<style scoped>
</style>
+145
View File
@@ -0,0 +1,145 @@
/**
* 字典 util
* author: scott
* date: 20190109
*/
import {ajaxGetDictItems,getDictItemsFromCache} from '@/api/api'
/**
* 获取字典数组
* @param dictCode 字典Code
* @return List<Map>
*/
export async function initDictOptions(dictCode) {
if (!dictCode) {
return '字典Code不能为空!'
}
//优先从缓存中读取字典配置
if(getDictItemsFromCache(dictCode)){
let res = {}
res.result = getDictItemsFromCache(dictCode)
res.success = true
return res
}
//获取字典数组
let res = await ajaxGetDictItems(dictCode)
return res
}
/**
* 字典值替换文本通用方法
* @param dictOptions 字典数组
* @param text 字典值
* @return String
*/
export function filterDictText(dictOptions, text) {
// --update-begin----author:sunjianlei---date:20200323------for: 字典翻译 text 允许逗号分隔 ---
if (text != null && Array.isArray(dictOptions)) {
let result = []
// 允许多个逗号分隔,允许传数组对象
let splitText
if (Array.isArray(text)) {
splitText = text
} else {
splitText = text.toString().trim().split(',')
}
for (let txt of splitText) {
let dictText = txt
for (let dictItem of dictOptions) {
if (txt.toString() === dictItem.value.toString()) {
dictText = (dictItem.text || dictItem.title || dictItem.label)
break
}
}
result.push(dictText)
}
return result.join(',')
}
return text
// --update-end----author:sunjianlei---date:20200323------for: 字典翻译 text 允许逗号分隔 ---
}
/**
* 字典值替换文本通用方法(多选)
* @param dictOptions 字典数组
* @param text 字典值
* @return String
*/
export function filterMultiDictText(dictOptions, text) {
//js “!text” 认为0为空,所以做提前处理
if(text === 0 || text === '0'){
if(dictOptions){
for (let dictItem of dictOptions) {
if (text == dictItem.value) {
return dictItem.text
}
}
}
}
if(!text || text=='null' || !dictOptions || dictOptions.length==0){
return ''
}
let re = ''
text = text.toString()
let arr = text.split(',')
dictOptions.forEach(function (option) {
if(option){
for(let i=0;i<arr.length;i++){
if (arr[i] === option.value) {
re += option.text+','
break
}
}
}
})
if(re==''){
return text
}
return re.substring(0,re.length-1)
}
/**
* 翻译字段值对应的文本
* @param children
* @returns string
*/
export function filterDictTextByCache(dictCode, key) {
if(key==null ||key.length==0){
return
}
if (!dictCode) {
return '字典Code不能为空!'
}
//优先从缓存中读取字典配置
if(getDictItemsFromCache(dictCode)){
let item = getDictItemsFromCache(dictCode).filter(t => t['value'] == key)
if(item && item.length>0){
return item[0]['text']
}
}
}
/** 通过code获取字典数组 */
export async function getDictItems(dictCode, params) {
//优先从缓存中读取字典配置
if(getDictItemsFromCache(dictCode)){
let desformDictItems = getDictItemsFromCache(dictCode).map(item => ({...item, label: item.text}))
return desformDictItems
}
//缓存中没有,就请求后台
return await ajaxGetDictItems(dictCode, params).then(({success, result}) => {
if (success) {
let res = result.map(item => ({...item, label: item.text}))
console.log('------- 从DB中获取到了字典-------dictCode : ', dictCode, res)
return Promise.resolve(res)
} else {
return Promise.resolve([])
}
}).catch((res) => {
console.error('getDictItems error: ', res)
return Promise.resolve([])
})
}
+132
View File
@@ -0,0 +1,132 @@
<template>
<a-checkbox-group v-if="tagType=='checkbox'" @change="onChange" :value="arrayValue" :disabled="disabled">
<a-checkbox v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text || item.label }}</a-checkbox>
</a-checkbox-group>
<a-select
v-else-if="tagType=='select'"
:value="arrayValue"
@change="onChange"
:disabled="disabled"
mode="multiple"
:placeholder="placeholder"
:getPopupContainer="getParentContainer"
optionFilterProp="children"
:filterOption="filterOption"
allowClear>
<a-select-option
v-for="(item,index) in dictOptions"
:key="index"
:value="item.value">
<span style="display: inline-block;width: 100%" :title=" item.text || item.label ">
{{ item.text || item.label }}
</span>
</a-select-option>
</a-select>
</template>
<script>
import {ajaxGetDictItems,getDictItemsFromCache} from '@/api/api'
export default {
name: 'JMultiSelectTag',
props: {
dictCode: String,
placeholder: String,
disabled: Boolean,
value: String,
type: String,
options:Array,
spliter:{
type: String,
required: false,
default: ','
},
popContainer:{
type:String,
default:'',
required:false
},
},
data() {
return {
dictOptions: [],
tagType:'',
arrayValue:!this.value?[]:this.value.split(this.spliter)
}
},
created() {
if(!this.type || this.type==='list_multi'){
this.tagType = 'select'
}else{
this.tagType = this.type
}
//获取字典数据
//this.initDictData();
},
watch:{
options: function(val){
this.setCurrentDictOptions(val)
},
dictCode:{
immediate:true,
handler() {
this.initDictData()
},
},
value (val) {
if(!val){
this.arrayValue = []
}else{
this.arrayValue = this.value.split(this.spliter)
}
}
},
methods: {
initDictData() {
if(this.options && this.options.length>0){
this.dictOptions = [...this.options]
}else{
//优先从缓存中读取字典配置
let cacheOption = getDictItemsFromCache(this.dictCode)
if(cacheOption && cacheOption.length>0){
this.dictOptions = cacheOption
return
}
//根据字典Code, 初始化字典数组
ajaxGetDictItems(this.dictCode, null).then((res) => {
if (res.success) {
this.dictOptions = res.result
}
})
}
},
onChange (selectedValue) {
this.$emit('change', selectedValue.join(this.spliter))
},
setCurrentDictOptions(dictOptions){
this.dictOptions = dictOptions
},
getCurrentDictOptions(){
return this.dictOptions
},
getParentContainer(node){
if(!this.popContainer){
return node.parentNode
}else{
return document.querySelector(this.popContainer)
}
},
// update--begin--autor:lvdandan-----date:20201120------forLOWCOD-1086 下拉多选框,搜索时只字典code进行搜索不能通过字典text搜索
filterOption(input, option) {
return option.componentOptions.children[0].children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
// update--end--autor:lvdandan-----date:20201120------forLOWCOD-1086 下拉多选框,搜索时只字典code进行搜索不能通过字典text搜索
},
model: {
prop: 'value',
event: 'change'
}
}
</script>
+246
View File
@@ -0,0 +1,246 @@
<template>
<a-select
v-if="async"
showSearch
labelInValue
:disabled="disabled"
:getPopupContainer="getParentContainer"
@search="loadData"
:placeholder="placeholder"
v-model="selectedAsyncValue"
style="width: 100%"
:filterOption="false"
@change="handleAsyncChange"
allowClear
:notFoundContent="loading ? undefined : null"
>
<a-spin v-if="loading" slot="notFoundContent" size="small"/>
<a-select-option v-for="d in options" :key="d.value" :value="d.value">{{ d.text }}</a-select-option>
</a-select>
<a-select
v-else
:getPopupContainer="getParentContainer"
showSearch
:disabled="disabled"
:placeholder="placeholder"
optionFilterProp="children"
style="width: 100%"
@change="handleChange"
:filterOption="filterOption"
v-model="selectedValue"
allowClear
:notFoundContent="loading ? undefined : null">
<a-spin v-if="loading" slot="notFoundContent" size="small"/>
<a-select-option v-for="d in options" :key="d.value" :value="d.value">{{ d.text }}</a-select-option>
</a-select>
</template>
<script>
import { ajaxGetDictItems,getDictItemsFromCache } from '@/api/api'
import debounce from 'lodash/debounce'
import { getAction } from '../../api/manage'
export default {
name: 'JSearchSelectTag',
props:{
disabled: Boolean,
value: [String, Number],
dict: String,
dictOptions: Array,
async: Boolean,
placeholder:{
type:String,
default:'请选择',
required:false
},
popContainer:{
type:String,
default:'',
required:false
},
pageSize:{
type: Number,
default: 10,
required: false
}
},
data(){
this.loadData = debounce(this.loadData, 800)//消抖
this.lastLoad = 0
return {
loading:false,
selectedValue:[],
selectedAsyncValue:[],
options: [],
}
},
created(){
this.initDictData()
},
watch:{
'value':{
immediate:true,
handler(val){
if(!val){
if(val==0){
this.initSelectValue()
}else{
this.selectedValue=[]
this.selectedAsyncValue=[]
}
}else{
this.initSelectValue()
}
}
},
'dict':{
handler(){
this.initDictData()
}
},
'dictOptions':{
deep: true,
handler(val){
if(val && val.length>0){
this.options = [...val]
}
}
}
},
methods:{
initSelectValue(){
if(this.async){
if(!this.selectedAsyncValue || !this.selectedAsyncValue.key || this.selectedAsyncValue.key!=this.value){
console.log('这才请求后台')
getAction(`/sys/dict/loadDictItem/${this.dict}`,{key:this.value}).then(res=>{
if(res.success){
let obj = {
key:this.value,
label:res.result
}
this.selectedAsyncValue = {...obj}
}
})
}
}else{
this.selectedValue = this.value.toString()
}
},
loadData(value){
console.log('数据加载',value)
this.lastLoad +=1
const currentLoad = this.lastLoad
this.options = []
this.loading=true
// 字典code格式:table,text,code
getAction(`/sys/dict/loadDict/${this.dict}`,{keyword:value, pageSize: this.pageSize}).then(res=>{
this.loading=false
if(res.success){
if(currentLoad!=this.lastLoad){
return
}
this.options = res.result
console.log('我是第一个',res)
}else{
this.$message.warning(res.message)
}
})
},
initDictData(){
if(!this.async){
//如果字典项集合有数据
if(this.dictOptions && this.dictOptions.length>0){
this.options = [...this.dictOptions]
}else{
//根据字典Code, 初始化字典数组
let dictStr = ''
if(this.dict){
let arr = this.dict.split(',')
if(arr[0].indexOf('where')>0){
let tbInfo = arr[0].split('where')
dictStr = tbInfo[0].trim()+','+arr[1]+','+arr[2]+','+encodeURIComponent(tbInfo[1])
}else{
dictStr = this.dict
}
if (this.dict.indexOf(',') == -1) {
//优先从缓存中读取字典配置
if (getDictItemsFromCache(this.dictCode)) {
this.options = getDictItemsFromCache(this.dictCode)
return
}
}
ajaxGetDictItems(dictStr, null).then((res) => {
if (res.success) {
this.options = res.result
}
})
}
}
}else{
//异步一开始也加载一点数据
this.loading=true
getAction(`/sys/dict/loadDict/${this.dict}`,{pageSize: this.pageSize, keyword:''}).then(res=>{
this.loading=false
if(res.success){
this.options = res.result
}else{
this.$message.warning(res.message)
}
})
}
},
filterOption(input, option) {
return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
},
handleChange (selectedValue) {
console.log('selectedValue',selectedValue)
this.selectedValue = selectedValue
this.callback()
},
handleAsyncChange(selectedObj){
//update-begin-author:scott date:20201222 for:【搜索】搜索查询组件,删除条件,默认下拉还是上次的缓存数据,不好 JT-191
if(selectedObj){
this.selectedAsyncValue = selectedObj
this.selectedValue = selectedObj.key
}else{
this.selectedAsyncValue = null
this.selectedValue = null
this.options = null
this.loadData('')
}
this.callback()
//update-end-author:scott date:20201222 for:【搜索】搜索查询组件,删除条件,默认下拉还是上次的缓存数据,不好 JT-191
},
callback(){
this.$emit('change', this.selectedValue)
},
setCurrentDictOptions(dictOptions){
this.options = dictOptions
},
getCurrentDictOptions(){
return this.options
},
getParentContainer(node){
if(!this.popContainer){
return node.parentNode
}else{
return document.querySelector(this.popContainer)
}
},
},
model: {
prop: 'value',
event: 'change'
}
}
</script>
<style scoped>
</style>
+181
View File
@@ -0,0 +1,181 @@
# JDictSelectTag 组件用法
----
- 从字典表获取数据,dictCode格式说明: 字典code
```html
<j-dict-select-tag v-model="queryParam.sex" placeholder="请输入用户性别"
dictCode="sex"/>
```
v-decorator用法:
```html
<j-dict-select-tag v-decorator="['sex', {}]" :triggerChange="true" placeholder="请输入用户性别"
dictCode="sex"/>
```
- 从数据库表获取字典数据,dictCode格式说明: 表名,文本字段,取值字段
```html
<j-dict-select-tag v-model="queryParam.username" placeholder="请选择用户名称"
dictCode="sys_user,realname,id"/>
```
# JDictSelectUtil.js 列表字典函数用法
----
- 第一步: 引入依赖方法
```html
import {initDictOptions, filterDictText} from '@/components/dict/JDictSelectUtil'
```
- 第二步: 在created()初始化方法执行字典配置方法
```html
//初始化字典配置
this.initDictConfig();
```
- 第三步: 实现initDictConfig方法,加载列表所需要的字典(列表上有多个字典项,就执行多次initDictOptions方法)
```html
initDictConfig() {
//初始化字典 - 性别
initDictOptions('sex').then((res) => {
if (res.success) {
this.sexDictOptions = res.result;
}
});
},
```
- 第四步: 实现字段的customRender方法
```html
customRender: (text, record, index) => {
//字典值替换通用方法
return filterDictText(this.sexDictOptions, text);
}
```
# JMultiSelectTag 多选组件
下拉/checkbox
## 参数配置
| 参数 | 类型 | 必填 |说明|
|--------------|---------|----|---------|
| placeholder |string | | placeholder |
| disabled |Boolean | | 是否禁用 |
| type |string | | 多选类型 select/checkbox 默认是select |
| dictCode |string | | 数据字典编码或者表名,显示字段名,存储字段名拼接而成的字符串,如果提供了options参数 则此参数可不填|
| options |Array | | 多选项,如果dictCode参数未提供,可以设置此参数加载多选项 |
使用示例
----
```vue
<template>
<a-form>
<a-form-item label="下拉多选" style="width: 300px">
<j-multi-select-tag
v-model="selectValue"
:options="dictOptions"
placeholder="请做出你的选择">
</j-multi-select-tag>
{{ selectValue }}
</a-form-item>
<a-form-item label="checkbox">
<j-multi-select-tag
v-model="checkboxValue"
:options="dictOptions"
type="checkbox">
</j-multi-select-tag>
{{ checkboxValue }}
</a-form-item>
</a-form >
</template>
<script>
import JMultiSelectTag from '@/components/dict/JMultiSelectTag'
export default {
components: {JMultiSelectTag},
data() {
return {
selectValue:"",
checkboxValue:"",
dictOptions:[{
label:"选项一",
value:"1"
},{
label:"选项二",
value:"2"
},{
label:"选项三",
value:"3"
}]
}
}
}
</script>
```
# JSearchSelectTag 字典表的搜索组件
下拉搜索组件,支持异步加载,异步加载用于大数据量的字典表
## 参数配置
| 参数 | 类型 | 必填 |说明|
|--------------|---------|----|---------|
| placeholder |string | | placeholder |
| disabled |Boolean | | 是否禁用 |
| dict |string | | 表名,显示字段名,存储字段名拼接而成的字符串,如果提供了dictOptions参数 则此参数可不填|
| dictOptions |Array | | 多选项,如果dict参数未提供,可以设置此参数加载多选项 |
| async |Boolean | | 是否支持异步加载,设置成true,则通过输入的内容加载远程数据,否则在本地过滤数据,默认false|
使用示例
----
```vue
<template>
<a-form>
<a-form-item label="下拉搜索" style="width: 300px">
<j-search-select-tag
placeholder="请做出你的选择"
v-model="selectValue"
:dictOptions="dictOptions">
</j-search-select-tag>
{{ selectValue }}
</a-form-item>
<a-form-item label="异步加载" style="width: 300px">
<j-search-select-tag
placeholder="请做出你的选择"
v-model="asyncSelectValue"
dict="sys_depart,depart_name,id"
:async="true">
</j-search-select-tag>
{{ asyncSelectValue }}
</a-form-item>
</a-form >
</template>
<script>
import JSearchSelectTag from '@/components/dict/JSearchSelectTag'
export default {
components: {JSearchSelectTag},
data() {
return {
selectValue:"",
asyncSelectValue:"",
dictOptions:[{
text:"选项一",
value:"1"
},{
text:"选项二",
value:"2"
},{
text:"选项三",
value:"3"
}]
}
}
}
</script>
```
+16
View File
@@ -0,0 +1,16 @@
import JDictSelectTag from './JDictSelectTag.vue'
import JMultiSelectTag from './JMultiSelectTag.vue'
import JSearchSelectTag from './JSearchSelectTag.vue'
import { filterMultiDictText,filterDictText,initDictOptions,filterDictTextByCache } from './JDictSelectUtil'
export default {
install: function (Vue) {
Vue.component('JDictSelectTag',JDictSelectTag)
Vue.component('JMultiSelectTag',JMultiSelectTag)
Vue.component('JSearchSelectTag',JSearchSelectTag)
Vue.prototype.$initDictOptions = (dictCode) => initDictOptions(dictCode)
Vue.prototype.$filterMultiDictText = (dictOptions, text) => filterMultiDictText(dictOptions, text)
Vue.prototype.$filterDictText = (dictOptions, text) => filterDictText(dictOptions, text)
Vue.prototype.$filterDictTextByCache = (...param) => filterDictTextByCache(...param)
}
}
+204
View File
@@ -0,0 +1,204 @@
<template>
<div>
<a-form :form="form">
<a-row v-for="(item, index) in installmentList" :key="index">
<a-col :xxl="4" :xl="8" :sm="12">
<a-form-item :label="`${index + 1}阶段`" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input placeholder="请输入名称"
v-decorator="['installmentList['+index+'].phaseName',validatorRules.phaseName]"
:maxLength='50'
v-bind="$attrs"
@change="e => {e.target.value = (e.target.value + '').trim()}"></a-input>
</a-form-item>
</a-col>
<a-col :xxl="4" :xl="8" :sm="12">
<a-form-item :label="`${index + 1}阶段应${label}`" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input placeholder="请输入金额"
v-decorator="['installmentList['+index+'].accountsReceivableAmount',validatorRules.accountsReceivableAmount]"
:maxLength='50'
v-bind="$attrs"
@blur="addZero"
@change="(e) => {e.target.value = (e.target.value.replace(/[^0-9.]/g,'')).trim()}"></a-input>
</a-form-item>
</a-col>
<a-col :xxl="5" :xl="8" :sm="12">
<a-form-item :label="`${index + 1}阶段应${label}时间`" :labelCol="labelCol" :wrapperCol="wrapperCol">
<j-date :placeholder="`请选择应${label}时间`"
style="width: 100%;"
v-decorator="['installmentList['+index+'].accountsReceivableTime']"
:trigger-change="true"
v-bind="$attrs"
date-format="YYYY-MM-DD"/>
</a-form-item>
</a-col>
<a-col :xxl="4" :xl="8" :sm="12">
<a-form-item :label="`${index + 1}阶段实${label}`" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input placeholder="请输入金额"
v-decorator="['installmentList['+index+'].paidAmount',validatorRules.paidAmount]"
:maxLength='50'
v-bind="$attrs"
@blur="addZero"
@input="changePaidAmount"
@change="(e) => {e.target.value = (e.target.value.replace(/[^0-9.]/g,'')).trim()}"></a-input>
</a-form-item>
</a-col>
<a-col :xxl="5" :xl="8" :sm="12">
<a-form-item :label="`${index + 1}阶段实${label}时间`" :labelCol="labelCol" :wrapperCol="wrapperCol">
<j-date :placeholder="`请选择实${label}时间`"
style="width: 100%;"
v-decorator="['installmentList['+index+'].paidTime',validatorRules.paidTime]"
:trigger-change="true"
v-bind="$attrs"
date-format="YYYY-MM-DD"/>
</a-form-item>
</a-col>
<a-col :xxl="2" :xl="8" :sm="12" class="operator-btn">
<a-button icon="plus" @click="addInstallmentItem" v-bind="$attrs"></a-button>
<a-button icon="minus" @click="deleteInstallmentItem(index)"
v-bind="$attrs"
:disabled="installmentList.length === 1">
</a-button>
</a-col>
</a-row>
</a-form>
</div>
</template>
<script>
import JDate from '../tools/JDate'
import pick from 'lodash.pick'
import { addZero } from '../../utils/util'
import { money } from '../../utils/validate'
export default {
name: 'InstallmentForm',
components: { JDate },
props: {
label: {
type: String,
required: false,
default: '收'
}
},
data() {
return {
form: this.$form.createForm(this),
model: {},
labelCol: {
xs: { span: 24 },
sm: { span: 9 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 15 }
},
validatorRules: {
phaseName: {
rules: [{ required: true, message: '请输入名称' }],
validateTrigger: 'blur'
},
accountsReceivableAmount: {
rules: [{ required: true, validator: this.checkMoney }],
validateTrigger: 'blur'
},
paidAmount: {
rules: [{ required: false, validator: this.checkMoney }],
validateTrigger: 'blur'
}
},
index: 1,
installmentList: [],
defaultFormData: {
phaseName: null,
accountsReceivableAmount: null,
accountsReceivableTime: undefined,
paidAmount: null,
paidTime: undefined
}
}
},
methods: {
addZero,
// 修改
changePaidAmount(){
// 计算分阶段应收 款总和
let money = this.form.getFieldsValue().installmentList.reduce((total,current) => {
return total + Number(current.paidAmount)
},0)
this.$emit('editPaidAmount',money)
// console.log(this.form.getFieldsValue().installmentList,'this.form.getFieldValue()this.form.getFieldValue()')
},
/**
* 初始化分期信息列表
* @param record
*/
initInstallmentList(record) {
// 判断是否为编辑
if (record && record.length > 0) {
this.installmentList = record
} else {
this.installmentList = [this.defaultFormData]
record = [this.defaultFormData]
}
let obj = {}
obj.installmentList = record
this.model = Object.assign({}, obj)
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model, 'installmentList'))
})
},
/**
* 添加一个分期信息
*/
addInstallmentItem() {
this.installmentList.push(this.defaultFormData)
},
deleteInstallmentItem(index) {
let valArr = Object.values(this.form.getFieldValue(['installmentList']))[0]
this.installmentList.splice(index, 1)
valArr.splice(index, 1)
this.form.setFieldsValue({ installmentList: valArr })
},
handleSave() {
this.form.validateFields((err, values) => {
if (!err) {
this.$emit('ok', values)
}
})
},
/**
* 校验金额格式
* @param rules
* @param value
* @param callback
*/
checkMoney(rules, value, callback) {
console.log(value, rules.field)
if (value) {
if (money(value)) {
callback()
}
callback('请输入合法的金额数字,最多2位小数,10位整数')
}
if (rules.field.indexOf('accountsReceivableAmount') > -1) {
callback('请输入金额')
}
callback()
}
}
}
</script>
<style scoped lang="less">
.operator-btn {
height: 40px;
display: flex;
align-items: center;
.ant-btn {
margin-left: 10px;
}
}
</style>
+12
View File
@@ -0,0 +1,12 @@
/* 引入 icon class 文件 */
@import "./iconfont.css";
/* 设置使用字体的优先级 anticon 高 */
:global(.anticon) { /* :global() 是为了覆盖全局class .anticon 的样式 */
&:before {
font-family: "anticon", "anticon-jeecg" !important;
/* 默认样式是这样
font-family: "anticon" !important;
*/
}
}
+67
View File
@@ -0,0 +1,67 @@
@font-face {
font-family: "anticon-jeecg"; /* Project id 2798517 */
src: url('iconfont.woff2?t=1639559463058') format('woff2'),
url('iconfont.woff?t=1639559463058') format('woff'),
url('iconfont.ttf?t=1639559463058') format('truetype');
}
.anticon-jeecg {
font-family: "anticon-jeecg" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.anticonothermeeting:before {
content: "\e621";
}
.anticonworking:before {
content: "\e61f";
}
.anticoninternational:before {
content: "\e61e";
}
.anticondatamembers:before {
content: "\e61d";
}
.anticoncommittee:before {
content: "\e613";
}
.anticonmeeting1:before {
content: "\e60f";
}
.anticonproject:before {
content: "\e609";
}
.anticonpack:before {
content: "\e60a";
}
.anticonmember:before {
content: "\e60b";
}
.anticondata-network-disk:before {
content: "\e60c";
}
.anticonfinancial:before {
content: "\e60e";
}
.anticoncontract:before {
content: "\e608";
}
.anticoncompany:before {
content: "\e607";
}
File diff suppressed because one or more lines are too long
+100
View File
@@ -0,0 +1,100 @@
{
"id": "2798517",
"name": "zx-project",
"font_family": "anticon-jeecg",
"css_prefix_text": "anticon",
"description": "",
"glyphs": [
{
"icon_id": "26512409",
"name": "cus_othermeeting",
"font_class": "othermeeting",
"unicode": "e621",
"unicode_decimal": 58913
},
{
"icon_id": "26512248",
"name": "cus_working",
"font_class": "working",
"unicode": "e61f",
"unicode_decimal": 58911
},
{
"icon_id": "26512241",
"name": "cus_international",
"font_class": "international",
"unicode": "e61e",
"unicode_decimal": 58910
},
{
"icon_id": "26512231",
"name": "cus_datamembers",
"font_class": "datamembers",
"unicode": "e61d",
"unicode_decimal": 58909
},
{
"icon_id": "26511116",
"name": "cus_committee",
"font_class": "committee",
"unicode": "e613",
"unicode_decimal": 58899
},
{
"icon_id": "24340808",
"name": "cus_meeting",
"font_class": "meeting1",
"unicode": "e60f",
"unicode_decimal": 58895
},
{
"icon_id": "24340604",
"name": "cus_project",
"font_class": "project",
"unicode": "e609",
"unicode_decimal": 58889
},
{
"icon_id": "24340605",
"name": "cus_pack",
"font_class": "pack",
"unicode": "e60a",
"unicode_decimal": 58890
},
{
"icon_id": "24340606",
"name": "cus_member",
"font_class": "member",
"unicode": "e60b",
"unicode_decimal": 58891
},
{
"icon_id": "24340607",
"name": "cus_data-network-disk",
"font_class": "data-network-disk",
"unicode": "e60c",
"unicode_decimal": 58892
},
{
"icon_id": "24340609",
"name": "cus_financial",
"font_class": "financial",
"unicode": "e60e",
"unicode_decimal": 58894
},
{
"icon_id": "24337509",
"name": "cus_contract",
"font_class": "contract",
"unicode": "e608",
"unicode_decimal": 58888
},
{
"icon_id": "24337464",
"name": "cus_company",
"font_class": "company",
"unicode": "e607",
"unicode_decimal": 58887
}
]
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
+184
View File
@@ -0,0 +1,184 @@
<template>
<div v-if="!reloading" class="j-area-linkage">
<!--area-cascader level-0二级联动 1-三级联动-->
<area-cascader
style="border-color: red"
v-if="_type === enums.type[0]"
:value="innerValue"
:data="pca"
:style="{width}"
v-bind="$attrs"
v-on="_listeners"
@change="handleChange"
:class="{'placeholderBlack':isActive,'placeholderGray':!isActive,'has-error':hasError}"
/>
<!--area-select level-1二级联动 2-三级联动-->
<area-select
v-else-if="_type === enums.type[1]"
:value="innerValue"
:data="pca"
v-bind="$attrs"
v-on="_listeners"
@change="handleChange"
:class="{'placeholderBlack':isActive,'placeholderGray':!isActive,'has-error':hasError}"
/>
<div v-else>
<span style="color:red;"> Bad type value: {{_type}}</span>
</div>
</div>
</template>
<script>
import pca from '../../../public/map/areaPca'
import Area from '@comp/_util/AreaPca'
export default {
name: 'JAreaLinkagePca',
props: {
value: {
type: String,
required: false,
},
// 表单是否必填控制
hasError:{
type:Boolean,
required: false,
default:false
},
// 组件的类型,可选值:
// select 下拉样式
// cascader 级联样式(默认)
type: {
type: String,
default: 'cascader'
},
width: {
type: String,
default: '100%'
}
},
data() {
return {
pca,
isActive: false, // false placeholder为灰色。 true placeholder 为黑色
innerValue: [],
usedListeners: ['change'],
enums: {
type: ['cascader', 'select']
},
reloading: false,
areaData: ''
}
},
computed: {
_listeners() {
const listeners = { ...this.$listeners }
// 去掉已使用的事件,防止冲突
this.usedListeners.forEach(key => {
delete listeners[key]
})
return listeners
},
_type() {
if (this.enums.type.includes(this.type)) {
return this.type
} else {
console.error(`JAreaLinkage的type属性只能接收指定的值(${this.enums.type.join('|')}`)
return this.enums.type[0]
}
}
},
watch: {
value: {
immediate: true,
handler() {
this.loadDataByValue(this.value)
if (this.value) {
this.isActive = true // 此时value有值
}
}
}
},
created() {
this.initAreaData()
},
methods: {
/** 通过 value 反推 options */
loadDataByValue(value) {
if (!value || value.length === 0) {
this.innerValue = []
this.reloading = true
setTimeout(() => {
this.reloading = false
}, 100)
} else {
this.initAreaData()
const arr = this.areaData.getRealCode(value)
this.innerValue = arr
}
},
/** 通过地区code获取子级 */
loadDataByCode(value) {
const options = []
const data = pca[value]
if (data) {
for (const key in data) {
if (data.hasOwnProperty(key)) {
options.push({ value: key, label: data[key] })
}
}
return options
} else {
return []
}
},
/** 判断是否有子节点 */
hasChildren(options) {
options.forEach(option => {
const data = this.loadDataByCode(option.value)
option.isLeaf = data.length === 0
})
},
handleChange(values) {
const value = values[values.length - 1]
this.$emit('change', value)
},
initAreaData() {
if (!this.areaData) {
this.areaData = new Area()
}
}
},
model: { prop: 'value', event: 'change' }
}
</script>
<style lang="less" scoped>
.j-area-linkage {
height:40px;
/deep/ .area-cascader-wrap .area-select {
width: 100%;
}
/deep/ .area-select .area-selected-trigger {
line-height: 1.15;
}
}
/deep/ .area-cascader-wrap .area-select:hover {
border-color: #069f99;;
}
/deep/ .has-error .area-select {
border-color: #f5222d!important;
}
///deep/.placeholderBlack .area-cascader-wrap .area-select.active {
// color: #333 !important;
//}
///deep/.placeholderGray .area-cascader-wrap .area-select {
// color: rgb(191,191,191) !important;
//}
</style>
+65
View File
@@ -0,0 +1,65 @@
<template>
<div class="components-input-demo-presuffix">
<a-input @click="openModal" placeholder="corn表达式" v-model="cron" @change="handleOK">
<a-icon slot="prefix" type="schedule" title="corn控件"/>
<a-icon v-if="cron" slot="suffix" type="close-circle" @click="handleEmpty" title="清空"/>
</a-input>
<JCronModal ref="innerVueCron" :data="cron" @ok="handleOK"></JCronModal>
</div>
</template>
<script>
import JCronModal from './modal/JCronModal'
export default {
name: 'JCron',
components: {
JCronModal
},
props: {
value: {
required: false,
type: String,
}
},
data(){
return {
cron: this.value,
}
},
watch:{
value(val){
this.cron = val
}
},
methods:{
openModal(){
this.$refs.innerVueCron.show()
},
handleOK(val){
this.cron = val
this.$emit('change', this.cron)
//this.$emit("change", Object.assign({}, this.cron));
},
handleEmpty(){
this.handleOK('')
}
},
model: {
prop: 'value',
event: 'change'
}
}
</script>
<style scoped>
.components-input-demo-presuffix .anticon-close-circle {
cursor: pointer;
color: #ccc;
transition: color 0.3s;
font-size: 12px;
}
.components-input-demo-presuffix .anticon-close-circle:hover {
color: #f5222d;
}
.components-input-demo-presuffix .anticon-close-circle:active {
color: #666;
}
</style>
+167
View File
@@ -0,0 +1,167 @@
<template>
<div>
<!--YYYY-MM-DD HH:mm:ss-->
<a-date-picker
style="width: 100%"
v-if="showType === 'time'"
dropdownClassName="j-date-picker"
:disabled="disabled || readOnly"
:placeholder="placeholder"
@change="handleDateChange"
:value="momVal"
:showTime="showTime"
:format="dateFormat"
v-bind="$attrs"
v-on="childListeners"
:getCalendarContainer="getCalendarContainer">
</a-date-picker>
<!--YYYY-MM-DD-->
<a-date-picker
style="width: 100%"
v-if="showType === 'day'"
dropdownClassName="j-date-picker"
:disabled="disabled || readOnly"
:placeholder="placeholder"
@change="handleDateChange"
:value="momVal"
:showTime="showTime"
:format="dateFormat"
v-bind="$attrs"
v-on="childListeners"
:getCalendarContainer="getCalendarContainer">
</a-date-picker>
<!--YYYY-MM-->
<a-month-picker
style="width: 100%"
v-if="showType === 'month'"
:placeholder="placeholder"
:value="momVal"
:disabled="disabled || readOnly"
:format="dateFormat"
v-bind="$attrs"
v-on="childListeners"
@change="handleMonthChange">
</a-month-picker>
<!--YYYY-->
<a-date-picker
style="width: 100%"
v-if="showType === 'year'"
:placeholder="placeholder"
mode="year"
:format="dateFormat"
:value="year"
:disabled="disabled || readOnly"
:open="yearShowOne"
v-bind="$attrs"
v-on="childListeners"
:getCalendarContainer="getCalendarContainer"
@openChange="openChangeOne"
@panelChange="panelChangeOne">
</a-date-picker>
</div>
</template>
<script>
import moment from 'moment'
export default {
name: 'JDate',
props: {
placeholder:{
type: String,
default: '请选择',
required: false
},
value:{
type: String,
required: false
},
dateFormat:{
type: String,
default: 'YYYY-MM-DD',
required: false
},
readOnly:{
type: Boolean,
required: false,
default: false
},
disabled:{
type: Boolean,
required: false,
default: false
},
//控制选择时分秒
showType:{
type: String,
required: false,
default:'time'
},
getCalendarContainer: {
type: Function,
default: (node) => node.parentNode
},
showTime:{
type: [Boolean, Object],
default: false
}
},
data () {
let dateStr = this.value
return {
yearShowOne:false, //控制年份模态框的显示与否
year:'', // mode==“year” 专用
momVal:!dateStr?null:moment(dateStr,this.dateFormat)
}
},
computed: {
//透传给下级组件的事件,需要排除本组件使用的change事件
childListeners() {
let result = Object.assign({},
this.$listeners,
)
delete result.change
return result
}
},
watch: {
value (val) {
let fm = this.dateFormat
moment.prototype.toJSON = function(){
return moment(this).format(fm)
}
if(!val){
this.momVal = null
}else{
this.momVal = moment(val,this.dateFormat)
}
}
},
methods: {
moment,
handleDateChange(mom,dateStr){
this.$emit('change', dateStr)
},
handleMonthChange(mom,dateStr){
this.$emit('change',dateStr)
},
/**
* 弹出日历和关闭日历的回调
* status:打开或关闭的状态
* */
openChangeOne(status){
this.yearShowOne = status
},
// 得到年份选择器的值
panelChangeOne(value){
this.yearShowOne = false
let year = moment(value,this.dateFormat).year().toString() // 处理成字符串
this.year = value //组件显示的
this.$emit('change',year)
}
},
//2.2新增 在组件内定义 指定父组件调用时候的传值属性和事件类型
model: {
prop: 'value',
event: 'change'
}
}
</script>

Some files were not shown because too many files have changed in this diff Show More